Functions
wirecell.util.wires.multitpc Namespace Reference

Functions

def load (filename)
 

Detailed Description

This holds routines to load "multitpc" format wire geometry files.

Function Documentation

def wirecell.util.wires.multitpc.load (   filename)
Load a "multitpc" geometry file.

Return a list of schema.Wire objects.

Somewhere, there exists code to dump wires from larsoft in a text
format such as what made the files found in the file

protodune-wires-larsoft-v1.txt

from the wire-cell-data package.  It has columns like:

# chan tpc plane wire sx sy sz ex ey ez

And, further the order of rows of identical channel number express
progressively higher segment count.

    - channel: 0-based ID unique to one conductor in the entire
      detector

    - tpc: 0-based count of the "TPC" which is associated with one
      face of one anode.

    - plane: plane number (0 == U, 1 == V, 2 == W) in the face/tpc

    - wip: wire index in its plane

    - tail: triplet (sx,sy,sz) starting position of the wire in cm

    - head: triplet (ex,ey,ez) ending position of the wire in cm

Example lines::

    # chan tpc plane wire sx sy sz ex ey ez
    0 0 0   0 -368.926 606.670  229.881     -368.926 605.569 230.672
    0 1 0 400 -358.463 285.577  5.68434e-14 -358.463 606.509 230.672
    0 0 0 800 -368.926 286.518 -1.56319e-13 -368.926   7.61  200.467
    1 0 0   1 -368.926 606.670  229.306     -368.926 604.769 230.673
    1 1 0 401 -358.463 284.777  5.68434e-14 -358.463 605.709 230.672
    1 0 0 801 -368.926 285.718  1.7053e-13  -368.926   7.61  199.892
    ...
    800 0 1   0 -368.449 605.639  0.335  -368.449 606.335 0.835
    800 1 1 400 -358.939 605.648  0.335  -358.939 285.648 230.337
    800 0 1 800 -368.449   7.61  30.4896 -368.449 285.656 230.337
    801 0 1   1 -368.449 604.839  0.335  -368.449 606.335 1.40999
    801 1 1 401 -358.939 604.848  0.335  -358.939 284.848 230.337
    801 0 1 801 -368.449   7.61  31.0646 -368.449 284.856 230.337
    ...
    1600 0 2 0 -367.973 7.61 0.57535 -367.973 606 0.57535
    1601 0 2 1 -367.973 7.61 1.05455 -367.973 606 1.05455
    1602 0 2 2 -367.973 7.61 1.53375 -367.973 606 1.53375

As shown in the example, the first and second set of three lines
are from each the same "chan" and represent subsequent segments of
one condutor.

Also as shown, there is no sanity in segment direction.

TPC 1 are on the "front" face and TPC 0 are "back" face in the
sense that the normal to a front face pointing into the drift
region is parallel to the global X axis.

Definition at line 15 of file multitpc.py.

15 def load(filename):
16  '''
17  Load a "multitpc" geometry file.
18 
19  Return a list of schema.Wire objects.
20 
21  Somewhere, there exists code to dump wires from larsoft in a text
22  format such as what made the files found in the file
23 
24  protodune-wires-larsoft-v1.txt
25 
26  from the wire-cell-data package. It has columns like:
27 
28  # chan tpc plane wire sx sy sz ex ey ez
29 
30  And, further the order of rows of identical channel number express
31  progressively higher segment count.
32 
33  - channel: 0-based ID unique to one conductor in the entire
34  detector
35 
36  - tpc: 0-based count of the "TPC" which is associated with one
37  face of one anode.
38 
39  - plane: plane number (0 == U, 1 == V, 2 == W) in the face/tpc
40 
41  - wip: wire index in its plane
42 
43  - tail: triplet (sx,sy,sz) starting position of the wire in cm
44 
45  - head: triplet (ex,ey,ez) ending position of the wire in cm
46 
47  Example lines::
48 
49  # chan tpc plane wire sx sy sz ex ey ez
50  0 0 0 0 -368.926 606.670 229.881 -368.926 605.569 230.672
51  0 1 0 400 -358.463 285.577 5.68434e-14 -358.463 606.509 230.672
52  0 0 0 800 -368.926 286.518 -1.56319e-13 -368.926 7.61 200.467
53  1 0 0 1 -368.926 606.670 229.306 -368.926 604.769 230.673
54  1 1 0 401 -358.463 284.777 5.68434e-14 -358.463 605.709 230.672
55  1 0 0 801 -368.926 285.718 1.7053e-13 -368.926 7.61 199.892
56  ...
57  800 0 1 0 -368.449 605.639 0.335 -368.449 606.335 0.835
58  800 1 1 400 -358.939 605.648 0.335 -358.939 285.648 230.337
59  800 0 1 800 -368.449 7.61 30.4896 -368.449 285.656 230.337
60  801 0 1 1 -368.449 604.839 0.335 -368.449 606.335 1.40999
61  801 1 1 401 -358.939 604.848 0.335 -358.939 284.848 230.337
62  801 0 1 801 -368.449 7.61 31.0646 -368.449 284.856 230.337
63  ...
64  1600 0 2 0 -367.973 7.61 0.57535 -367.973 606 0.57535
65  1601 0 2 1 -367.973 7.61 1.05455 -367.973 606 1.05455
66  1602 0 2 2 -367.973 7.61 1.53375 -367.973 606 1.53375
67 
68  As shown in the example, the first and second set of three lines
69  are from each the same "chan" and represent subsequent segments of
70  one condutor.
71 
72  Also as shown, there is no sanity in segment direction.
73 
74  TPC 1 are on the "front" face and TPC 0 are "back" face in the
75  sense that the normal to a front face pointing into the drift
76  region is parallel to the global X axis.
77  '''
78 
79  store = schema.maker()
80 
81  wpids = defaultdict(list)
82  with open(filename) as fp:
83  seg = 0
84  last_chan = -1
85  for line in fp.readlines():
86  if line.startswith("#"):
87  continue
88  line = line.strip()
89  if not line:
90  continue
91  chunks = line.split()
92  chan,tpc,plane,wire = map(int, chunks[:4])
93  if chan == last_chan:
94  seg += 1
95  else:
96  seg = 0
97  last_chan = chan
98  beg = [float(x)*units.cm for x in chunks[4:7] ]
99  end = [float(x)*units.cm for x in chunks[7:10]]
100  if beg[1] > end[1]:
101  beg,end = end,beg # always point upward in Y
102 
103  face = (1+tpc)%2 # "front" face is 0.
104  apa = tpc//2 # pure conjecture
105  wid = wire # this too
106 
107  wpid = schema.wire_plane_id(plane, face, apa)
108 
109  begind = store.make("point", *beg)
110  endind = store.make("point", *end)
111 
112  wireind = store.make("wire", wid, chan, seg, begind, endind)
113  wpids[wpid].append(wireind)
114 
115  def wire_pos(ind):
116  '''
117  Return a number on which to sort wires. The z-intercept is
118  returned.
119  '''
120  wire = store.get("wire", ind)
121  p1 = store.get("point", wire.tail)
122  p2 = store.get("point", wire.head)
123  z_intercept = p1.z - p1.y * (p2.z - p1.z) / ( p2.y - p1.y ) # this will blow up with ICARUS!
124  return z_intercept
125 
126  # make and collect planes
127  by_apa_face = defaultdict(list)
128  for wpid, wire_list in sorted(wpids.items()):
129  plane,face,apa = schema.plane_face_apa(wpid)
130  wire_list.sort(key = wire_pos)
131  if face == 1: # to satisfy pitch-order and wire(x)pitch cross product
132  print ("Reversing wire order for p%d f%d a%d" %(plane,face,apa))
133  wire_list.reverse()
134  plane_index = store.make("plane", plane, wire_list)
135  by_apa_face[(apa,face)].append(plane_index)
136 
137  # make and collect faces
138  by_apa = defaultdict(list)
139  for (apa,face), plane_indices in sorted(by_apa_face.items()):
140  face_index = store.make("face", face, plane_indices)
141  by_apa[apa].append(face_index)
142 
143  for apa, face_indices in sorted(by_apa.items()):
144  store.make("anode", apa, face_indices)
145 
146  return store.schema()
147 
148 
149 
150 
int open(const char *, int)
Opens a file descriptor.