dune.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 '''
3 This module generates a DUNE connectivity graph.
4 '''
5 from collections import namedtuple
6 import numpy
7 import networkx
8 
9 # This matrix connects the:
10 #
11 # (chip row, channel column)
12 #
13 # in an FEMBwith the conductor expressed as a pair of values:
14 #
15 # (layer letter, attachement number)
16 #
17 # The layer is expressed as a letter in "uvw", the attachment number
18 # is a one-based count of the logical spot where the conductor
19 # attaches to the top of the APA looking at the face holding the
20 # conductor and ordered left to right.
21 #
22 chip_channel_layer_spot_matrix = numpy.array([
23  [('u', 19), ('u', 17), ('u', 15), ('u', 13), ('u', 11), ('v', 19),
24  ('v', 17), ('v', 15), ('v', 13), ('v', 11), ('w', 23), ('w', 21),
25  ('w', 19), ('w', 17), ('w', 15), ('w', 13)],
26  [('u', 9), ('u', 7), ('u', 5), ('u', 3), ('u', 1), ('v', 9),
27  ('v', 7), ('v', 5), ('v', 3), ('v', 1), ('w', 11), ('w', 9),
28  ('w', 7), ('w', 5), ('w', 3), ('w', 1)],
29  [('w', 14), ('w', 16), ('w', 18), ('w', 20), ('w', 22), ('w', 24),
30  ('v', 12), ('v', 14), ('v', 16), ('v', 18), ('v', 20), ('u', 12),
31  ('u', 14), ('u', 16), ('u', 18), ('u', 20)],
32  [('w', 2), ('w', 4), ('w', 6), ('w', 8), ('w', 10), ('w', 12),
33  ('v', 2), ('v', 4), ('v', 6), ('v', 8), ('v', 10), ('u', 2),
34  ('u', 4), ('u', 6), ('u', 8), ('u', 10)],
35  [('u', 29), ('u', 27), ('u', 25), ('u', 23), ('u', 21), ('v', 29),
36  ('v', 27), ('v', 25), ('v', 23), ('v', 21), ('w', 35), ('w', 33),
37  ('w', 31), ('w', 29), ('w', 27), ('w', 25)],
38  [('u', 39), ('u', 37), ('u', 35), ('u', 33), ('u', 31), ('v', 39),
39  ('v', 37), ('v', 35), ('v', 33), ('v', 31), ('w', 47), ('w', 45),
40  ('w', 43), ('w', 41), ('w', 39), ('w', 37)],
41  [('w', 26), ('w', 28), ('w', 30), ('w', 32), ('w', 34), ('w', 36),
42  ('v', 22), ('v', 24), ('v', 26), ('v', 28), ('v', 30), ('u', 22),
43  ('u', 24), ('u', 26), ('u', 28), ('u', 30)],
44  [('w', 38), ('w', 40), ('w', 42), ('w', 44), ('w', 46), ('w', 48),
45  ('v', 32), ('v', 34), ('v', 36), ('v', 38), ('v', 40), ('u', 32),
46  ('u', 34), ('u', 36), ('u', 38), ('u', 40)]], dtype=object)
47 
48 def flatten_cclsm(mat = chip_channel_layer_spot_matrix):
49  '''
50  Flatten an ASIC channel X number matrix to a dictionary keyed by
51  (plane letter, local wire attachment number (1-48 or 1-40). Value
52  is a tuple (ichip, ich) with ichip:{1-8} and ich:{1-16}
53  '''
54  ret = dict()
55  for ichip, row in enumerate(mat):
56  for ich, cell in enumerate(row):
57  cell = tuple(cell)
58  ret[cell] = (ichip+1, ich+1)
59  return ret
60 
61 
62 ApaFaceParams = namedtuple("ApaFaceParams", ["nlayers", "nboards"]);
63 ApaBoardParams = namedtuple("ApaBoardParams", ["nchips", "nchanperchip"])
64 ApaDaqParams = namedtuple("ApaDaqParams", ["nwibs", "nconnperwib"])
65 ApaParams = namedtuple("ApaParams", ["nfaces", "face", "board", "daq"])
66 
67 default_apa_params = ApaParams(
68  nfaces = 2,
69  face = ApaFaceParams(3, 10),
70  board = ApaBoardParams(8, 16),
71  daq = ApaDaqParams(5, 4)
72 )
73 
74 ApaMakers = namedtuple("ApaMakers", ["apa", "anode", "crate", "face"...]
75 
76 class ApaConnectivity(object):
77  '''
78  Provide methods to enumerate connectivity
79  '''
80  def __init__(self, params = default_apa_params):
81  self.p = params
82  self.nboards = self.p.face.nboards*self.p.nfaces
83  self.nchips = self.nboards * self.p.board.nchips
84  self.nchans = self.nchips*self.p.board.nchanperchip
85 
86  # List of indicies to boards in two ways: [face,board] and WIB
87  # [conn,slot]. A very smart layout convention adopted by the
88  # engineers let us do this so cleanly!
89  bi = numpy.array(range(self.nboards))
90  self.iboard_by_face_board = bi.reshape(self.p.nfaces, self.p.face.nboards)
91  self.iboard_by_conn_slot = bi.reshape(self.p.daq.nconnperwib, self.p.daq.nwibs)
92 
93  # List of indices to chips, accessed by [face,board_in_face,chip_on_board]
94  ci = numpy.array(range(self.nchips))
95  self.ichip_by_face_board_chip = ci.reshape(self.p.nfaces, self.p.face.nboards, self.p.board.nchips)
96 
97 
98  # List of indices to all conductors (or all channels) in an APA
99  # accessed by [face, board_in_face, chip_in_board, chan_in_chip]
100  ci = numpy.array(range(self.nchans))
101  self.iconductor_by_face_board_chip_chan = ci.reshape(self.p.nfaces, self.p.face.nboards,
102  self.p.board.nchips, self.p.board.nchanperchip)
103 
104  # Flattened chip-channel to layer-conductor map
105  self.ccls = flatten_cclsm()
106 
107  def iconductor_chip_chan(self, face, board_in_face, layer_in_face, wire_spot_in_layer):
108  '''
109  Given the paramers return information about the associated
110  conductor as a triple:
111 
112  - iconductor :: the apa-global index for the conductor
113 
114  - chip :: the board-local index for the chip
115 
116  - chan :: the chip-local index for the channel
117  '''
118  # must +1 the spot to match the matrix assumption
119  nchip,nch = self.ccls[("uvw"[layer_in_face], wire_spot_in_layer+1)]
120  # must -1 the returns to match our assumption
121  ichip,ich = nchip-1, nch-1
122  icond = self.iconductor_by_face_board_chip_chan[face, board_in_face, ichip, ich]
123  return (icond, ichip, ich)
124 
125  def iface_board(self, iboard):
126  '''
127  Given a global board index, return tuple of:
128 
129  - iface :: the apa-global face index
130  - board : the face-local board index
131  '''
132  if not iboard in range(self.nboards):
133  raise ValueError("iboard is out of range: %d" % iboard)
134  iface = iboard//self.p.face.nboards
135  board = iboard%self.p.face.nboards
136  return (iface,board)
137 
138 
139 def graph(ac, makers):
140  '''
141  Return a directed graph expressing the connectivity and
142  containment given the ApaConnectivity object.
143  '''
144  G = nx.DiGraph()
145 
146 
147 
148 # The (#layers, #columns, #rows) for DUNE "anodes" in different detectors
149 oneapa_lcr = (1,1,1)
150 protodun_lcr = (1,2,3)
151 dune_lcr = (2,25,3)
152 
def flatten_cclsm(mat=chip_channel_layer_spot_matrix)
Definition: dune.py:48
def graph(desc, maker=maker)
Definition: apa.py:294
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69