Classes | Functions | Variables
wirecell.util.wires.generator Namespace Reference

Classes

class  Point
 
class  Ray
 
class  Rectangle
 

Functions

def wrap_one (start_ray, rect)
 
def wrapped_from_top (offset, angle, pitch, rect)
 
def wrapped_from_top_oneside (offset, angle, pitch, rect)
 
def onesided_wrapped (params=protodune_params)
 
def celltree_geometry ()
 

Variables

 microboone_params
 
 protodune_params
 

Detailed Description

Wires and Channels

Function Documentation

def wirecell.util.wires.generator.celltree_geometry ( )
Spit out contents of a file like:

https://github.com/BNLIF/wire-cell-celltree/blob/master/geometry/ChannelWireGeometry_v2.txt

columns of:
# channel plane wire sx sy sz ex ey ez

Definition at line 411 of file generator.py.

412  '''
413  Spit out contents of a file like:
414 
415  https://github.com/BNLIF/wire-cell-celltree/blob/master/geometry/ChannelWireGeometry_v2.txt
416 
417  columns of:
418  # channel plane wire sx sy sz ex ey ez
419  '''
420 
421 
422  #Wire = namedtuple("Wire", "index Chan w1 h1 w2 h2")
423  # wire: (along_pitch, side, channel, seg, p1, p2)
424  aps = set()
425  sides = set()
426  channels = set()
427  for iplane, letter in enumerate("uvw"):
428  rect, wires = protodune_plane_one_side(letter)
429  print (letter, len(wires))
430  for wire in wires:
431  ap, side, channel, seg, p1, p2 = wire
432  print (wire)
433  aps.add(ap)
434  sides.add(side)
435  channels.add(channel)
436  print (len(aps),len(sides),len(channels))
437 
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
def wirecell.util.wires.generator.onesided_wrapped (   params = protodune_params)
Generate a schema.store of wires for a onesided but wrapped face.

This does not populate electronics.

Definition at line 341 of file generator.py.

341 def onesided_wrapped(params = protodune_params):
342  '''
343  Generate a schema.store of wires for a onesided but wrapped face.
344 
345  This does not populate electronics.
346  '''
347  rect = Rectangle(params['width'], params['height'])
348 
349  store = schema.maker()
350 
351  apa = 0
352 
353  # temporary per-plane lists of wires to allow sorting before tuplizing.
354  planes = [list(), list(), list()]
355  iface = 0
356 
357  planex = params['planex']
358 
359  mcpp = params['maxchanperplane']
360 
361  for iplane in range(3):
362  wires = wrapped_from_top(params['offsets'][iplane],
363  params['angles'][iplane],
364  params['pitches'][iplane],
365  rect)
366 
367  # a common X because each face has its own coordinate system
368  x = planex[iplane]
369 
370  # (along_pitch, side, channel, seg, p1, p2)
371  for iwire,wire in enumerate(wires):
372  ap, side, wan, seg, p1, p2 = wire
373 
374  z1, y1 = p1
375  z2, y2 = p2
376 
377  # side is +/-1, if back side, mirror due to wrapping. Fixme: this
378  # is very sensitive to offsets and will likely result in a shift as
379  # one goes from a unwrapped wire to its wrapped neighbor.
380  z1 *= side
381  z2 *= side
382 
383  chplane = iplane+1
384  if side < 0:
385  chplane += 3
386  ch = chplane*mcpp + wan
387 
388  wid = mcpp*10*(iplane+1) + (iwire+1)
389 
390  begind = store.make("point", x, y1, z1)
391  endind = store.make("point", x, y2, z2)
392  wireind = store.make("wire", wid, ch, seg, begind, endind)
393  planes[iplane].append(wireind)
394 
395  wire_plane_indices = list()
396  for iplane, wire_list in enumerate(planes):
397  if iplane == 0:
398  wire_list.sort(key = lambda w: -1*store.wire_ypos(w))
399  elif iplane == 1:
400  wire_list.sort(key = store.wire_ypos)
401  else:
402  wire_list.sort(key = store.wire_zpos)
403  wpid = schema.wire_plane_id(iplane, iface, apa)
404  index = store.make("plane", wpid, wire_list)
405  wire_plane_indices.append(index)
406  face_index = store.make("face", iface, wire_plane_indices)
407  store.make("anode", apa, [face_index])
408  return store.schema()
409 
410 
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
def wrapped_from_top(offset, angle, pitch, rect)
Definition: generator.py:188
def onesided_wrapped(params=protodune_params)
Definition: generator.py:341
def wirecell.util.wires.generator.wrap_one (   start_ray,
  rect 
)
Return wire end points by wrapping around a rectangle.

Definition at line 166 of file generator.py.

166 def wrap_one(start_ray, rect):
167  '''
168  Return wire end points by wrapping around a rectangle.
169  '''
170  p = rect.relative(start_ray.tail)
171  d = start_ray.unit
172  ret = [p]
173  while True:
174  #print "loop: p:%s d:%s" %(p,d)
175  jump = rect.toedge(p, d)
176  p = p + jump
177  ret.append(p)
178  if p.y <= -0.5*rect.height:
179  break
180  d.x = -1.0*d.x # swap direction
181  return ret
182 
183 
184 
185 
186 
187 
def wrap_one(start_ray, rect)
Definition: generator.py:166
def wirecell.util.wires.generator.wrapped_from_top (   offset,
  angle,
  pitch,
  rect 
)
Wrap a rectangle with a plane of wires starting along the top of
the given rectangle and starting at given offset from upper-left
corner of the rectangle and with angle measured from the vertical
to the wire direction.  Positive angle means the wire starts going
down-left from the top of the rectangle.

Return list of "wires" (wire segments) as tuple:

    - return :: (along_pitch, side, channel, seg, p1, p2)

    - channel :: counts the attachment point at the top of the
      rectangle from left to right starting from 0

    - side :: identify which side the wire is on, (this value is
      redundant with "seg").

    - seg :: the segment number, ie, how many times the wire's
      conductor has wrapped around the rectangle.

    - p1 and p2 :: end points of wire assuming the original
      rectangle is centered on the origin.

Definition at line 188 of file generator.py.

188 def wrapped_from_top(offset, angle, pitch, rect):
189  '''
190  Wrap a rectangle with a plane of wires starting along the top of
191  the given rectangle and starting at given offset from upper-left
192  corner of the rectangle and with angle measured from the vertical
193  to the wire direction. Positive angle means the wire starts going
194  down-left from the top of the rectangle.
195 
196  Return list of "wires" (wire segments) as tuple:
197 
198  - return :: (along_pitch, side, channel, seg, p1, p2)
199 
200  - channel :: counts the attachment point at the top of the
201  rectangle from left to right starting from 0
202 
203  - side :: identify which side the wire is on, (this value is
204  redundant with "seg").
205 
206  - seg :: the segment number, ie, how many times the wire's
207  conductor has wrapped around the rectangle.
208 
209  - p1 and p2 :: end points of wire assuming the original
210  rectangle is centered on the origin.
211  '''
212 
213  cang = math.cos(angle)
214  sang = math.sin(angle)
215  direc = Point(-sang, -cang)
216  pitchv = Point(cang, -sang)
217 
218  start = Point(-0.5*rect.width + offset, 0.5*rect.height) + rect.center
219 
220  step = pitch / cang
221  stop = rect.center.x + 0.5*rect.width
222 
223  #print -0.5*rect.width, start.x, step, stop
224 
225  wires = list()
226 
227  channel = 0
228  while True:
229  points = wrap_one(Ray(start, start+direc), rect)
230  side = 1
231  for seg, (p1, p2) in enumerate(zip(points[:-1], points[1:])):
232  wcenter = (p1+p2)*0.5 - rect.center
233  along_pitch = pitchv.dot(wcenter)
234  w = (along_pitch, side, channel, seg, p1, p2)
235  wires.append(w)
236  side *= -1
237  start.x += step
238  if start.x >= stop:
239  break
240  channel += 1
241  return wires
242 
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
def wrapped_from_top(offset, angle, pitch, rect)
Definition: generator.py:188
def wrap_one(start_ray, rect)
Definition: generator.py:166
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.
Definition: zip.h:295
def wirecell.util.wires.generator.wrapped_from_top_oneside (   offset,
  angle,
  pitch,
  rect 
)
Wrap a rectangle with a plane of wires starting along the top of
the given rectangle and starting at given offset from upper-left
corner of the rectangle and with angle measured from the vertical
to the wire direction.  Positive angle means the wire starts going
down-left from the top of the rectangle.

Return list of "wires" (wire segments) as tuple:

    - return :: (along_pitch, side, channel, seg, p1, p2)

    - channel :: counts the attachment point at the top of the
      rectangle from left to right starting from 0

    - side :: identify which side the wire is on, (this value is
      redundant with "seg").

    - seg :: the segment number, ie, how many times the wire's
      conductor has wrapped around the rectangle.

    - p1 and p2 :: end points of wire assuming the original
      rectangle is centered on the origin.

Definition at line 243 of file generator.py.

243 def wrapped_from_top_oneside(offset, angle, pitch, rect):
244  '''
245  Wrap a rectangle with a plane of wires starting along the top of
246  the given rectangle and starting at given offset from upper-left
247  corner of the rectangle and with angle measured from the vertical
248  to the wire direction. Positive angle means the wire starts going
249  down-left from the top of the rectangle.
250 
251  Return list of "wires" (wire segments) as tuple:
252 
253  - return :: (along_pitch, side, channel, seg, p1, p2)
254 
255  - channel :: counts the attachment point at the top of the
256  rectangle from left to right starting from 0
257 
258  - side :: identify which side the wire is on, (this value is
259  redundant with "seg").
260 
261  - seg :: the segment number, ie, how many times the wire's
262  conductor has wrapped around the rectangle.
263 
264  - p1 and p2 :: end points of wire assuming the original
265  rectangle is centered on the origin.
266  '''
267 
268  cang = math.cos(angle)
269  sang = math.sin(angle)
270  direc = Point(-sang, -cang)
271  pitchv = Point(cang, -sang)
272 
273  start = Point(-0.5*rect.width + offset, 0.5*rect.height) + rect.center
274 
275  step = pitch / cang
276  stop = rect.center.x + 0.5*rect.width
277 
278  #print -0.5*rect.width, start.x, step, stop
279 
280  def swapx(p):
281  return Point(2*rect.center.x - p.x, p.y)
282 
283  wires = list()
284 
285  channel = 0
286  while True:
287  points = wrap_one(Ray(start, start+direc), rect)
288  side = 1
289  for seg, (p1, p2) in enumerate(zip(points[:-1], points[1:])):
290  if side < 0:
291  p1 = swapx(p1)
292  p2 = swapx(p2)
293  wcenter = (p1+p2)*0.5 - rect.center
294  along_pitch = pitchv.dot(wcenter)
295 
296  # The same wire can serve both both faces if the
297  # coordinate system of each face is related by a rotation
298  # of the plane along the x axis.
299  w = (along_pitch, side, channel, seg, p1, p2)
300 
301  wires.append(w)
302 
303  side *= -1 # for next time
304  start.x += step
305  if start.x >= stop:
306  break
307  channel += 1
308  return wires
309 
310 
311 
312 # https://www-microboone.fnal.gov/publications/TDRCD3.pdf
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
def wrap_one(start_ray, rect)
Definition: generator.py:166
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.
Definition: zip.h:295
def wrapped_from_top_oneside(offset, angle, pitch, rect)
Definition: generator.py:243

Variable Documentation

wirecell.util.wires.generator.microboone_params
Initial value:
1 = dict(
2  # drift is 2.5604*units.meter
3  width = 10.368*units.meter, # in Z
4  height = 2.325*units.meter, # in Y
5  pitches = [3*units.mm, 3*units.mm, 3*units.mm ],
6  # guess at left/right ambiguity
7  angles = [+60*units.deg, -60*units.deg, 0.0],
8  #
9  offsets = [0.0*units.mm, 0.0*units.mm, 0.0*units.mm],
10  # fixme: this is surely wrong
11  planex = [9*units.mm, 6*units.mm, 3*units.mm],
12  maxchanperplane = 3000,
13 )

Definition at line 313 of file generator.py.

wirecell.util.wires.generator.protodune_params
Initial value:
1 = dict(
2  width = 2295*units.mm,
3  height = 5920*units.mm,
4  pitches = [4.669*units.mm, 4.669*units.mm, 4.790*units.mm ],
5  # guess at left/right ambiguity
6  angles = [+35.707*units.deg, -35.707*units.deg, 0.0],
7  # guess based on symmetry and above numbers
8  offsets = [0.3923*units.mm, 0.3923*units.mm, 0.295*units.mm],
9  # fixme: this is surely wrong
10  planex = [15*units.mm, 10*units.mm, 5*units.mm],
11  maxchanperplane = 1000,
12  )

Definition at line 327 of file generator.py.