4 from wirecell
import units
10 Wire Cell Toolkit Utility Commands 13 @cli.command(
"convert-oneside-wires")
14 @click.argument(
"input-file")
15 @click.argument(
"output-file")
19 Convert a a "onesided" wires description file into one suitable for WCT. 23 https://github.com/BNLIF/wire-cell-celltree/blob/master/geometry/ChannelWireGeometry_v2.txt 26 # channel plane wire sx sy sz ex ey ez 28 The output file is JSON and if it has .gz or .bz2 it will be compressed. 31 store = onesided.load(input_file)
32 persist.dump(output_file, store)
35 @cli.command(
"convert-multitpc-wires")
36 @click.argument(
"input-file")
37 @click.argument(
"output-file")
41 Convert a "multitpc" wire description file into one suitable for 44 Here "TPC" refers to on anode face. That is, one APA is made up 45 of two TPCs. An example file is protodune-wires-larsoft-v1.txt 46 from wire-cell-data. It has columns like: 48 # chan tpc plane wire sx sy sz ex ey ez 50 And, further the order of rows of identical channel number express 51 progressively higher segment count. 54 store = multitpc.load(input_file)
55 persist.dump(output_file, store)
59 @cli.command(
"convert-uboone-wire-regions")
60 @click.argument(
"wire-json-file")
61 @click.argument(
"csvfile")
62 @click.argument(
"region-json-file")
66 Convert CSV file to WCT format for wire regions. Example is one 67 as saved from MicroBooNE_ShortedWireList.xlsx. Use ,-separated 72 store = wpersist.load(wire_json_file)
73 ubs = reg.uboone_shorted(store, csvfile)
74 wpersist.dump(region_json_file, ubs)
76 @cli.command(
"plot-wire-regions")
77 @click.argument(
"wire-json-file")
78 @click.argument(
"region-json-file")
79 @click.argument(
"pdf-file")
84 from matplotlib.backends.backend_pdf
import PdfPages
85 import matplotlib.pyplot
as plt
86 from matplotlib.patches
import Polygon
87 from matplotlib.collections
import PatchCollection
89 store = wpersist.load(wire_json_file)
90 regions = wpersist.load(region_json_file)
94 'Point id to xy tuple' 95 ptobj = store.points[pt]
96 return (ptobj.z, ptobj.y)
98 'wire objects to polygon' 99 return numpy.asarray([pt2xy(wo1.tail),pt2xy(wo1.head),
100 pt2xy(wo2.head),pt2xy(wo2.tail)])
102 colors=[
'red',
'green',
'blue']
104 def get_polygons(shorted, triples):
109 pl,wip1,wip2 = one[
"plane"],one[
"wire1"],one[
"wire2"]
114 plobj = store.planes[pl]
115 wobj1 = store.wires[plobj.wires[wip1]]
116 wobj2 = store.wires[plobj.wires[wip2]]
118 assert wobj1.channel == one[
'ch1']
119 assert wobj2.channel == one[
'ch2']
121 verts = wo2pg(wobj1,wobj2)
123 pg = Polygon(verts, closed=
True, facecolor=colors[pl],
124 alpha=0.3, fill=
True, linewidth=.1, edgecolor=
'black')
128 pgs = [get_polygons(
int(s), t)
for s,t
in regions.items()]
129 pgs2 = [get_polygons(
int(s), t)
for s,t
in regions.items()]
130 pgs.append(pgs2[0] + pgs2[1])
132 zlimits = [ (0,4100), (6900,7500), (0, 7500) ]
134 with PdfPages(pdf_file)
as pdf:
136 for pgl,zlim
in zip(pgs,zlimits):
137 fig, ax = plt.subplots(nrows=1, ncols=1)
142 ax.set_ylim(-1500,1500)
143 ax.set_title(
'Dead wires')
144 ax.set_xlabel(
'Z [mm]')
145 ax.set_ylabel(
'Y [mm]')
151 @cli.command(
"wires-info")
152 @click.argument(
"json-file")
156 Print information about a wires file (.json or .json.bz2) 160 wires = wpersist.load(json_file)
161 dat = winfo.summary(wires)
162 print (
'\n'.join(dat))
165 @cli.command(
"wires-volumes")
166 @click.option(
'-a',
'--anode', default=1.0,
167 help=
'Distance from collection plane to "anode" (cutoff) plane (cm)')
168 @click.option(
'-r',
'--response', default=10.0,
169 help=
'Distance from collection plane to "respones" plane, should probably match Garfield (cm)')
170 @click.option(
'-c',
'--cathode', default=1.0,
171 help=
'Distance from colleciton plane to "cathode" plane (cm)')
172 @click.argument(
"json-file")
176 Print a parms.det.volumes JSON fragment for the given wires file. 178 You very likely want to carefully supply ALL command line options. 182 wires = wpersist.load(json_file)
183 jv = winfo.jsonnet_volumes(wires, anode*units.cm, response*units.cm, cathode*units.cm)
188 @cli.command(
"plot-wires")
189 @click.argument(
"json-file")
190 @click.argument(
"pdf-file")
194 Plot wires from a WCT JSON(.bz2) wire file 198 wires = wpersist.load(json_file)
199 wplot.allplanes(wires, pdf_file)
202 @cli.command(
"plot-select-channels")
203 @click.option(
'--labels/--no-labels', default=
True,
204 help=
"Use labels or not")
205 @click.argument(
"json-file")
206 @click.argument(
"pdf-file")
207 @click.argument(
"channels", nargs=-1, type=int)
211 Plot wires for select channels from a WCT JSON(.bz2) wire file 215 wires = wpersist.load(json_file)
216 wplot.select_channels(wires, pdf_file, channels, labels=labels)
219 @cli.command(
"gen-plot-wires")
220 @click.argument(
"output-file")
224 Generate wires and plot them. 228 s = wgen.onesided_wrapped()
229 fig,ax = wplot.oneplane(s, 0)
232 fig.savefig(output_file)
234 @cli.command(
"make-wires")
235 @click.option(
'-d',
'--detector',
237 type=click.Choice([
'apa']),
238 help=
"Set the target detector")
242 @click.argument(
"output-file")
246 Generate a WCT "wires" file giving geometry and connectivity of 247 conductor wire segments and channel identifiers. 249 if detector ==
"apa":
251 desc = apa.Description();
252 G,P = apa.graph(desc)
253 store = graph.to_schema(G, P, apa.channel_ident)
254 persist.dump(output_file, store)
256 click.echo(
'Unknown detector type: "%s"' % detector)
259 @cli.command(
"make-map")
260 @click.option(
'-d',
'--detector',
262 type=click.Choice([
'apa']),
263 help=
"Set the target detector")
264 @click.argument(
"output-file")
268 Generate a WCT channel map file giving numpy arrays. 270 schema = output_file[output_file.rfind(
".")+1:]
271 click.echo(
'writing schema: "%s"' % schema)
273 if detector ==
"apa":
276 click.echo(
'generating Numpy file "%s"' % output_file)
277 numpy.savez(output_file, **dict(
278 chip_channel_spot = apa.chip_channel_spot,
279 chip_channel_layer = apa.chip_channel_layer,
280 connector_slot_board = numpy.asarray(range(10),dtype=numpy.int32).reshape(2,5)+1,
281 face_board_femb = numpy.asarray(range(20),dtype=numpy.int32).reshape(2,10)+1))
284 click.echo(
'generating LaTeX fragment file "%s"' % output_file)
285 with
open(output_file,
"w")
as fp:
286 color = dict(u=
"red", v=
"blue", w=
"black")
288 mat = numpy.asarray([
r"\textcolor{%s}{%s%02d}" % (color[p], p, w) \
289 for p,w
in apa.chip_channel_layer_spot_matrix.reshape(8*16,2)])\
292 cells = [
"ch%02d" % chn]
295 lines.append(
" & " .join(cells))
297 body = end.join(lines)
298 top =
"&".join([
"ASIC:"] + [
str(n+1)
for n
in range(8)]) +
r"\\" 300 tabular = [
r"\begin{center}",
r"\begin{tabular}{%s}"%form,
r"\hline", top,
301 r"\hline", body+
r"\\",
r"\hline",
r"\end{tabular}",
r"\end{center}",
""]
302 fp.write(
"\n".join(tabular))
304 layers = dict(u=[
""]*40, v=[
""]*40, w=[
""]*48)
305 for chipn, chip
in enumerate(apa.chip_channel_layer_spot_matrix):
306 for chn, (plane,wire)
in enumerate(chip):
307 layers[plane][wire-1] = (chipn,chn)
310 for letter, layer
in sorted(layers.items()):
313 form =
"|" +
"C{3.5mm}|"*nhalf
317 r"\begin{tabular}{%s}"%form,
321 r"\multicolumn{%d}{c}{%s layer, first half: conductor / chip / chan} \\" % (nhalf, letter.upper()),
323 wires =
"&".join([
"%2s"%ww
for ww
in range(1,nhalf+1)]) +
r"\\";
324 chips =
"&".join([
"%2s"%(cc[0]+1,)
for cc
in layer[:nhalf]]) +
r"\\";
325 chans =
"&".join([
"%2s"%cc[1]
for cc
in layer[:nhalf]]) +
r"\\";
326 lines += [wires,
r"\hline", chips, chans];
329 r"\multicolumn{%d}{c}{%s layer, second half: conductor / chip / chan} \\" % (nhalf, letter.upper()),
331 wires =
"&".join([
"%2s"%ww
for ww
in range(nhalf+1,nchans+1)]) +
r"\\";
332 chips =
"&".join([
"%2s"%(cc[0]+1,)
for cc
in layer[nhalf:]]) +
r"\\";
333 chans =
"&".join([
"%2s"%cc[1]
for cc
in layer[nhalf:]]) +
r"\\";
334 lines += [wires,
r"\hline", chips, chans];
336 lines += [
r"\hline",
r"\end{tabular}"]
337 lines += [
r"\end{center}"]
338 fp.write(
"\n".join(lines))
344 click.echo(
'Unknown detector type: "%s"' % detector)
348 @cli.command(
"gravio")
349 @click.argument(
"dotfile")
353 Make a dot file using gravio of the connectivity. 356 from gravio
import gen, dotify
358 click.echo(
'You need to install the "gravio" package')
359 click.echo(
'See https://github.com/brettviren/gravio')
362 desc = apa.Description();
363 G,P = apa.graph(desc)
366 node_colors = dict(wib=
'orange', chip=
'red', face=
'blue', plane=
'purple', board=
'green', channel=
'pink')
368 skip_types = [
'point',
'wire',
'conductor']
369 nt = G.nodes[n][
'type']
370 return nt
in skip_types
372 gr = gen.Graph(
"dune",
"graph")
373 gr.node(shape=
'point')
375 for name, params
in G.nodes.items():
378 nt = G.nodes[name][
'type']
379 gr.node(name, shape=
'point', color=node_colors.get(nt,
'black'))
383 link_colors = dict(trace=
'pink', spot=
'red', side=
'blue', plane=
'purple', address=
'yellow', cable=
'brown', chanel=
'orange')
385 for (n1,n2), params
in G.edges.items():
386 if skip_node(n1)
or skip_node(n2):
388 if (n1,n2)
in seen_edges
or (n2,n1)
in seen_edges:
390 seen_edges.add((n1,n2))
391 link = params[
'link']
392 gr.edge(n1,n2, color=link_colors.get(link,
'black'))
395 d = dotify.Dotify(gr)
399 @cli.command(
"make-wires-onesided")
400 @click.argument(
"output-file")
404 Generate a WCT wires file. 408 s = wgen.onesided_wrapped()
409 wpersist.dump(output_file, s)
411 @cli.command(
"wire-channel-map")
412 @click.argument(
"input-file")
416 Debug command, generate a WCT channel map wires file. 418 from collections
import defaultdict
420 s = wpersist.load(input_file)
422 channel_map = defaultdict(list)
424 for anode
in s.anodes:
425 for iface
in anode.faces:
426 face = s.faces[iface]
427 for iplane
in face.planes:
428 plane = s.planes[iplane]
429 for iwire
in plane.wires:
430 wire = s.wires[iwire]
432 channel_map[(plane.ident,wire.channel)].append(iwire)
434 for c,wires
in sorted(channel_map.items()):
435 if c[1]
in range(4210, 4235):
437 click.echo(
"%s\t%s" %(c,wires))
443 if '__main__' == __name__:
def make_wires(ctx, detector, output_file)
int open(const char *, int)
Opens a file descriptor.
def make_map(ctx, detector, output_file)
def plot_wires(ctx, json_file, pdf_file)
size_t write(int, const char *, size_t)
Writes count bytes from buf to the filedescriptor fd.
def plot_select_channels(ctx, labels, json_file, pdf_file, channels)
def wires_info(ctx, json_file)
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
def convert_uboon_wire_regions(ctx, wire_json_file, csvfile, region_json_file)
def gen_plot_wires(ctx, output_file)
def make_wires_onesided(ctx, output_file)
def convert_multitpc_wires(ctx, input_file, output_file)
def wire_channel_map(ctx, input_file)
auto zip(Iterables &&...iterables)
Range-for loop helper iterating across many collections at the same time.
def convert_oneside_wires(ctx, input_file, output_file)
def wires_volumes(ctx, anode, response, cathode, json_file)
def plot_wire_regions(ctx, wire_json_file, region_json_file, pdf_file)