6 from wirecell
import units
9 from collections
import namedtuple
21 return "Point(%s)" % s
47 return self._coords.__iter__()
50 return Point(*[
abs(a)
for a
in self])
54 return Point(*[(a-b)
for a,b
in zip(self, other)])
56 return Point(*[(a-other)
for a
in self])
60 return Point(*[(a+b)
for a,b
in zip(self, other)])
62 return Point(*[(a+other)
for a
in self])
66 return Point(*[(a*b)
for a,b
in zip(self, other)])
68 return Point(*[(a*other)
for a
in self])
72 return Point(*[(a/b)
for a,b
in zip(self, other)])
74 return Point(*[(a/other)
for a
in self])
78 return sum([a*b
for a,b
in zip(self, other)])
82 return math.sqrt(self.
dot(self))
95 return "%s -> %s" % (self.
tail, self.
head)
106 return self.vector.unit
110 def __init__(self, width, height, center = Point(0.0, 0.0)):
118 self.center.y - 0.5*self.
height);
121 return point - self.
center 129 Return a vector that takes point along direction to the nearest edge. 138 xdir = d1.dot((1.0, 0.0))
142 xsign = xdir/
abs(xdir)
143 dx = xsign*corn.x - p1.x
146 ydir = d1.dot((0.0, 1.0))
150 ysign = ydir/
abs(ydir)
151 dy = ysign*corn.y - p1.y
168 Return wire end points by wrapping around a rectangle. 170 p = rect.relative(start_ray.tail)
175 jump = rect.toedge(p, d)
178 if p.y <= -0.5*rect.height:
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. 196 Return list of "wires" (wire segments) as tuple: 198 - return :: (along_pitch, side, channel, seg, p1, p2) 200 - channel :: counts the attachment point at the top of the 201 rectangle from left to right starting from 0 203 - side :: identify which side the wire is on, (this value is 204 redundant with "seg"). 206 - seg :: the segment number, ie, how many times the wire's 207 conductor has wrapped around the rectangle. 209 - p1 and p2 :: end points of wire assuming the original 210 rectangle is centered on the origin. 213 cang = math.cos(angle)
214 sang = math.sin(angle)
215 direc =
Point(-sang, -cang)
216 pitchv =
Point(cang, -sang)
218 start =
Point(-0.5*rect.width + offset, 0.5*rect.height) + rect.center
221 stop = rect.center.x + 0.5*rect.width
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)
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. 251 Return list of "wires" (wire segments) as tuple: 253 - return :: (along_pitch, side, channel, seg, p1, p2) 255 - channel :: counts the attachment point at the top of the 256 rectangle from left to right starting from 0 258 - side :: identify which side the wire is on, (this value is 259 redundant with "seg"). 261 - seg :: the segment number, ie, how many times the wire's 262 conductor has wrapped around the rectangle. 264 - p1 and p2 :: end points of wire assuming the original 265 rectangle is centered on the origin. 268 cang = math.cos(angle)
269 sang = math.sin(angle)
270 direc =
Point(-sang, -cang)
271 pitchv =
Point(cang, -sang)
273 start =
Point(-0.5*rect.width + offset, 0.5*rect.height) + rect.center
276 stop = rect.center.x + 0.5*rect.width
281 return Point(2*rect.center.x - p.x, p.y)
289 for seg, (p1, p2)
in enumerate(
zip(points[:-1], points[1:])):
293 wcenter = (p1+p2)*0.5 - rect.center
294 along_pitch = pitchv.dot(wcenter)
299 w = (along_pitch, side, channel, seg, p1, p2)
313 microboone_params = dict(
315 width = 10.368*units.meter,
316 height = 2.325*units.meter,
317 pitches = [3*units.mm, 3*units.mm, 3*units.mm ],
319 angles = [+60*units.deg, -60*units.deg, 0.0],
321 offsets = [0.0*units.mm, 0.0*units.mm, 0.0*units.mm],
323 planex = [9*units.mm, 6*units.mm, 3*units.mm],
324 maxchanperplane = 3000,
327 protodune_params = dict(
328 width = 2295*units.mm,
329 height = 5920*units.mm,
330 pitches = [4.669*units.mm, 4.669*units.mm, 4.790*units.mm ],
332 angles = [+35.707*units.deg, -35.707*units.deg, 0.0],
334 offsets = [0.3923*units.mm, 0.3923*units.mm, 0.295*units.mm],
336 planex = [15*units.mm, 10*units.mm, 5*units.mm],
337 maxchanperplane = 1000,
343 Generate a schema.store of wires for a onesided but wrapped face. 345 This does not populate electronics. 347 rect =
Rectangle(params[
'width'], params[
'height'])
349 store = schema.maker()
354 planes = [list(), list(), list()]
357 planex = params[
'planex']
359 mcpp = params[
'maxchanperplane']
361 for iplane
in range(3):
363 params[
'angles'][iplane],
364 params[
'pitches'][iplane],
372 ap, side, wan, seg, p1, p2 = wire
386 ch = chplane*mcpp + wan
388 wid = mcpp*10*(iplane+1) + (iwire+1)
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)
395 wire_plane_indices = list()
396 for iplane, wire_list
in enumerate(planes):
398 wire_list.sort(key =
lambda w: -1*store.wire_ypos(w))
400 wire_list.sort(key = store.wire_ypos)
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()
413 Spit out contents of a file like: 415 https://github.com/BNLIF/wire-cell-celltree/blob/master/geometry/ChannelWireGeometry_v2.txt 418 # channel plane wire sx sy sz ex ey ez 428 rect, wires = protodune_plane_one_side(letter)
429 print (letter, len(wires))
431 ap, side, channel, seg, p1, p2 = wire
435 channels.add(channel)
436 print (len(aps),len(sides),len(channels))
def __init__(self, coords)
def __getitem__(self, key)
def relative(self, point)
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
def wrapped_from_top(offset, angle, pitch, rect)
def __setitem__(self, key, val)
def wrap_one(start_ray, rect)
def onesided_wrapped(params=protodune_params)
def __init__(self, width, height, center=Point(0.0, 0.0))
def toedge(self, point, direction)
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.
def wrapped_from_top_oneside(offset, angle, pitch, rect)
def __init__(self, tail, head)