Skip to content

Commit 36fcfae

Browse files
Create wcls-decode-to-sig-twofaced-dnnroi-gpu.jsonnet
tools_maker + cpu->gpu
1 parent e3ec6f9 commit 36fcfae

1 file changed

Lines changed: 392 additions & 0 deletions

File tree

Lines changed: 392 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,392 @@
1+
// This is a main entry point to configure a WC/LS job that applies
2+
// noise filtering and signal processing to existing RawDigits. The
3+
// FHiCL is expected to provide the following parameters as attributes
4+
// in the "params" structure.
5+
//
6+
// epoch: the hardware noise fix expoch: "before", "after", "dynamic" or "perfect"
7+
// reality: whether we are running on "data" or "sim"ulation.
8+
// raw_input_label: the art::Event inputTag for the input RawDigit
9+
//
10+
// see the .fcl of the same name for an example Version 2
11+
//
12+
// Manual testing, eg:
13+
//
14+
// jsonnet -V reality=data -V epoch=dynamic -V raw_input_label=daq \\
15+
// -V signal_output_form=sparse \\
16+
// -J cfg cfg/pgrapher/experiment/uboone/wcls-nf-sp.jsonnet
17+
//
18+
// jsonnet -V reality=sim -V epoch=perfect -V raw_input_label=daq \\
19+
// -V signal_output_form=sparse \\
20+
// -J cfg cfg/pgrapher/experiment/uboone/wcls-nf-sp.jsonnet
21+
22+
23+
local epoch = std.extVar('epoch'); // eg "dynamic", "after", "before", "perfect"
24+
local reality = std.extVar('reality');
25+
local sigoutform = std.extVar('signal_output_form'); // eg "sparse" or "dense"
26+
27+
local wc = import 'wirecell.jsonnet';
28+
local g = import 'pgraph.jsonnet';
29+
30+
local raw_input_label = std.extVar('raw_input_label'); // eg "daq"
31+
local volume_label = std.extVar('tpc_volume_label'); // eg "",0,1,2,3
32+
local volume = if volume_label == '' then -1 else std.parseInt(volume_label);
33+
34+
// local data_params = import 'params.jsonnet';
35+
// local simu_params = import 'simparams.jsonnet';
36+
// local params_init = if reality == 'data' then data_params else simu_params;
37+
local params_twofaced = import 'pgrapher/experiment/icarus/params_twofaced.jsonnet';
38+
39+
# Load the sim-params, overwrite the volume config for the two-faced version
40+
local base_params = import 'pgrapher/experiment/icarus/simparams.jsonnet';
41+
local base = base_params + params_twofaced;
42+
43+
// load the electronics response parameters
44+
local er_params = [
45+
{
46+
gain: std.extVar('gain0')*wc.mV/wc.fC,
47+
shaping: std.extVar('shaping0')*wc.us,
48+
},
49+
50+
{
51+
gain: std.extVar('gain1')*wc.mV/wc.fC,
52+
shaping: std.extVar('shaping1')*wc.us,
53+
},
54+
55+
{
56+
gain: std.extVar('gain2')*wc.mV/wc.fC,
57+
shaping: std.extVar('shaping2')*wc.us,
58+
},
59+
];
60+
61+
62+
local params = base {
63+
files: super.files {
64+
fields: [ std.extVar('files_fields'), ],
65+
chresp: null,
66+
},
67+
68+
rc_resp: if std.extVar('file_rcresp') != "" then
69+
{
70+
// "icarus_fnal_rc_tail.json"
71+
filename: std.extVar('file_rcresp'),
72+
postgain: 1.0,
73+
start: 0.0,
74+
tick: 0.4*wc.us,
75+
nticks: params.daq.nticks,// 4255,
76+
type: "JsonElecResponse",
77+
}
78+
else super.rc_resp,
79+
80+
elec: std.mapWithIndex(function (n, eparam)
81+
super.elec[n] + {
82+
gain: eparam.gain,
83+
shaping: eparam.shaping,
84+
}, er_params),
85+
86+
};
87+
88+
// local tools_maker = import 'pgrapher/common/tools.jsonnet';
89+
local tools_maker = import 'pgrapher/experiment/icarus/icarus_tools.jsonnet';
90+
// local tools = tools_maker(params);
91+
local default_tools = tools_maker(params);
92+
local tools = std.mergePatch(default_tools,
93+
{dft: {type: "TorchDFT", data: {device: "gpu"}}});
94+
95+
local wcls_maker = import 'pgrapher/ui/wcls/nodes.jsonnet';
96+
local wcls = wcls_maker(params, tools);
97+
98+
local sp_maker = import 'pgrapher/experiment/icarus/sp.jsonnet';
99+
100+
//local chndbm = chndb_maker(params, tools);
101+
//local chndb = if epoch == "dynamic" then chndbm.wcls_multi(name="") else chndbm.wct(epoch);
102+
103+
104+
// Collect the WC/LS input converters for use below. Make sure the
105+
// "name" argument matches what is used in the FHiCL that loads this
106+
// file. In particular if there is no ":" in the inputer then name
107+
// must be the emtpy string.
108+
local wcls_input = {
109+
adc_digits: g.pnode({
110+
type: 'wclsRawFrameSource',
111+
name: 'rfsrc%d' %volume, // to use multiple wirecell instances in a fhicl job
112+
data: {
113+
art_tag: raw_input_label,
114+
frame_tags: ['orig'], // this is a WCT designator
115+
tick: params.daq.tick,
116+
// nticks: params.daq.nticks,
117+
},
118+
}, nin=0, nout=1),
119+
120+
};
121+
122+
// Collect all the wc/ls output converters for use below. Note the
123+
// "name" MUST match what is used in theh "outputers" parameter in the
124+
// FHiCL that loads this file.
125+
126+
local this_anode = tools.anodes[volume];
127+
128+
local wcls_output = {
129+
// The noise filtered "ADC" values. These are truncated for
130+
// art::Event but left as floats for the WCT SP. Note, the tag
131+
// "raw" is somewhat historical as the output is not equivalent to
132+
// "raw data".
133+
nf_digits: g.pnode({
134+
type: 'wclsFrameSaver',
135+
name: 'nfsaver',
136+
data: {
137+
// anode: wc.tn(tools.anode),
138+
anode: wc.tn(this_anode),
139+
digitize: true, // true means save as RawDigit, else recob::Wire
140+
frame_tags: ['raw'],
141+
// nticks: params.daq.nticks,
142+
chanmaskmaps: ['bad'],
143+
plane_map: {
144+
"1": 3, // front induction: WireCell::kULayer -> geo::kH (1 -> 3)
145+
"2": 1, // middle induction: WireCell:kVLayer -> geo::kV (2 -> 1)
146+
"4": 0, // collection: WireCell::kWLayer -> geo::kU (4 -> 0)
147+
},
148+
},
149+
}, nin=1, nout=1, uses=[this_anode]),
150+
151+
152+
// The output of signal processing. Note, there are two signal
153+
// sets each created with its own filter. The "gauss" one is best
154+
// for charge reconstruction, the "wiener" is best for S/N
155+
// separation. Both are used in downstream WC code.
156+
sp_signals: g.pnode({
157+
type: 'wclsFrameSaver',
158+
name: 'spsaver%d' %volume, // to use multiple wirecell instances in a fhicl job
159+
data: {
160+
// anode: wc.tn(tools.anode),
161+
anode: wc.tn(this_anode),
162+
digitize: false, // true means save as RawDigit, else recob::Wire
163+
// frame_tags: ['gauss', 'wiener', 'looseLf','shrinkROI','extendROI'],
164+
// frame_scale: [0.1, 0.1, 0.1],
165+
// frame_tags: ['gauss','wiener','looseLf','shrinkROI','extendROI','mp3ROI','mp2ROI', 'cleanupROI'],
166+
// frame_scale: [0.009,0.009,0.009,0.009,0.009,0.009,0.009,0.009],
167+
168+
frame_tags: ['dnnsp'],
169+
frame_scale: [std.extVar('gain_ADC_per_e')],
170+
171+
// nticks: params.daq.nticks,
172+
chanmaskmaps: ['bad'],
173+
nticks: -1,
174+
plane_map: {
175+
"1": 3, // front induction: WireCell::kULayer -> geo::kH (1 -> 3)
176+
"2": 1, // middle induction: WireCell:kVLayer -> geo::kV (2 -> 1)
177+
"4": 0, // collection: WireCell::kWLayer -> geo::kU (4 -> 0)
178+
},
179+
},
180+
}, nin=1, nout=1, uses=[this_anode]),
181+
182+
h5io: g.pnode({
183+
type: 'HDF5FrameTap',
184+
name: 'hio_sp%d' % volume,
185+
data: {
186+
anode: wc.tn(this_anode),
187+
trace_tags: ['gauss'
188+
, 'wiener'
189+
, 'tightLf'
190+
, 'looseLf'
191+
, 'decon'
192+
, 'cleanupROI'
193+
, 'breakROI1'
194+
, 'breakROI2'
195+
, 'shrinkROI'
196+
, 'extendROI'
197+
, 'mp3ROI'
198+
, 'mp2ROI'
199+
, 'dnnsp'
200+
],
201+
filename: "wc-sp-%d.h5" % volume,
202+
chunk: [0, 0], // ncol, nrow
203+
gzip: 0,
204+
high_throughput: true,
205+
},
206+
}, nin=1, nout=1, uses=[this_anode]),
207+
208+
};
209+
210+
// local perfect = import 'chndb-perfect.jsonnet';
211+
local base = import 'pgrapher/experiment/icarus/chndb-base.jsonnet';
212+
local chndb = [{
213+
type: 'OmniChannelNoiseDB',
214+
name: 'ocndbperfect%d' % n,
215+
// data: perfect(params, tools.anodes[n], tools.field, n),
216+
data: base(params, tools.anodes[n], tools.field, n){dft:wc.tn(tools.dft)},
217+
uses: [tools.anodes[n], tools.field, tools.dft], // pnode extension
218+
} for n in std.range(0, std.length(tools.anodes) - 1)];
219+
220+
local nf_maker = import 'pgrapher/experiment/icarus/nf.jsonnet';
221+
local nf_pipes = [nf_maker(tools.anodes[n], chndb[n], tools, name='nf%d' % n) for n in std.range(0, std.length(tools.anodes) - 1)];
222+
223+
local sp_override = { // assume all tages sets in base sp.jsonnet
224+
sparse: sigoutform == 'sparse',
225+
use_roi_refinement: true,
226+
use_roi_debug_mode: true,
227+
save_negtive_charge: true,
228+
wiener_tag: "",
229+
// gauss_tag: "",
230+
tight_lf_tag: "",
231+
// loose_lf_tag: "",
232+
break_roi_loop1_tag: "",
233+
break_roi_loop2_tag: "",
234+
shrink_roi_tag: "",
235+
extend_roi_tag: "",
236+
// decon_charge_tag: "",
237+
cleanup_roi_tag: "",
238+
// mp2_roi_tag: "",
239+
// mp3_roi_tag: "",
240+
use_multi_plane_protection: true,
241+
mp_tick_resolution: 8,
242+
process_planes: [0, 1, 2],
243+
isWrapped: true,
244+
nwires_separate_planes: [
245+
[1056, 1056], [5600], [5600]
246+
],
247+
troi_col_th_factor: std.parseJson(std.extVar('col_threshold_factor'))*1.0, // multiply by 1 to make into float
248+
troi_ind_th_factor: std.parseJson(std.extVar('ind_threshold_factor'))*1.0
249+
};
250+
local sp = sp_maker(params, tools, sp_override);
251+
local sp_pipes = [sp.make_sigproc(a) for a in tools.anodes];
252+
253+
local util = import 'pgrapher/experiment/icarus/funcs.jsonnet';
254+
local chsel_pipes = [
255+
g.pnode({
256+
type: 'ChannelSelector',
257+
name: 'chsel%d' % n,
258+
data: {
259+
channels: util.anode_channels_twofaced(n),
260+
//tags: ['orig%d' % n], // traces tag
261+
},
262+
}, nin=1, nout=1)
263+
for n in std.range(0, std.length(tools.anodes) - 1)
264+
];
265+
266+
local magoutput = 'icarus-data-check.root';
267+
local magnify = import 'pgrapher/experiment/icarus/magnify-sinks.jsonnet';
268+
local magnifyio = magnify(tools, magoutput);
269+
270+
local dnnroi = import 'pgrapher/experiment/icarus/dnnroi.jsonnet';
271+
local ts_u = {
272+
type: "TorchService",
273+
name: "dnnroi_u",
274+
data: {
275+
model: "NNs/plane0.ts",
276+
device: "gpu",
277+
concurrency: 1,
278+
},
279+
};
280+
281+
local ts_v = {
282+
type: "TorchService",
283+
name: "dnnroi_v",
284+
data: {
285+
model: "NNs/plane1.ts",
286+
device: "gpu",
287+
concurrency: 1,
288+
},
289+
};
290+
291+
local nfsp_pipes = [
292+
g.pipeline([
293+
chsel_pipes[n],
294+
// magnifyio.orig_pipe[n],
295+
296+
nf_pipes[n],
297+
// magnifyio.raw_pipe[n],
298+
sp_pipes[n],
299+
dnnroi(tools.anodes[n], ts_u, ts_v),
300+
// magnifyio.decon_pipe[n],
301+
// magnifyio.threshold_pipe[n],
302+
// magnifyio.debug_pipe[n], // use_roi_debug_mode: true in sp.jsonnet
303+
],
304+
'nfsp_pipe_%d' % n)
305+
for n in [volume]
306+
];
307+
308+
local fanout_tag_rules = [
309+
{
310+
frame: {
311+
'.*': 'orig%d' % tools.anodes[n].data.ident,
312+
},
313+
trace: {
314+
// fake doing Nmult SP pipelines
315+
//orig: ['wiener', 'gauss'],
316+
//'.*': 'orig',
317+
},
318+
}
319+
for n in [volume]
320+
];
321+
322+
local fanin_tag_rules = [
323+
{
324+
frame: {
325+
//['number%d' % n]: ['output%d' % n, 'output'],
326+
'.*': 'framefanin',
327+
},
328+
trace: {
329+
['extend_roi%d'%ind]:'extend_roi%d'%ind,
330+
['shrink_roi%d'%ind]:'shrink_roi%d'%ind,
331+
// ['break_roi_2nd%d'%ind]:'break_roi_2nd%d'%ind,
332+
// ['break_roi_1st%d'%ind]:'break_roi_1st%d'%ind,
333+
['cleanup_roi%d'%ind]:'cleanup_roi%d'%ind,
334+
['mp2_roi%d'%ind]:'mp2_roi%d'%ind,
335+
['mp3_roi%d'%ind]:'mp3_roi%d'%ind,
336+
['gauss%d'%ind]:'gauss%d'%ind,
337+
'dnnsp\\d':'dnnsp%d'%ind,
338+
['wiener%d'%ind]:'wiener%d'%ind,
339+
// ['threshold%d'%ind]:'threshold%d'%ind,
340+
// ['tight_lf%d'%ind]:'tight_lf%d'%ind,
341+
['loose_lf%d'%ind]:'loose_lf%d'%ind,
342+
// ['decon%d'%ind]:'decon%d'%ind,
343+
},
344+
345+
}
346+
for ind in [this_anode.data.ident]
347+
];
348+
local fanpipe = util.fanpipe('FrameFanout', nfsp_pipes, 'FrameFanin', 'nfsp%d' % volume, [], fanout_tag_rules, fanin_tag_rules);
349+
350+
local retagger = g.pnode({
351+
type: 'Retagger',
352+
data: {
353+
// Note: retagger keeps tag_rules an array to be like frame fanin/fanout.
354+
tag_rules: [{
355+
// Retagger also handles "frame" and "trace" like fanin/fanout
356+
// merge separately all traces like gaussXYZ to gauss.
357+
frame: {
358+
'.*': 'retagger',
359+
},
360+
merge: {
361+
'dnnsp\\d': 'dnnsp',
362+
'gauss\\d': 'gauss',
363+
'wiener\\d': 'wiener',
364+
// 'tight_lf\\d': 'tightLf',
365+
'loose_lf\\d': 'looseLf',
366+
// 'decon\\d': 'decon',
367+
'cleanup_roi\\d': 'cleanupROI',
368+
// 'break_roi_1st\\d': 'breakROI1',
369+
// 'break_roi_2nd\\d': 'breakROI2',
370+
'shrink_roi\\d': 'shrinkROI',
371+
'extend_roi\\d': 'extendROI',
372+
'mp3_roi\\d': 'mp3ROI',
373+
'mp2_roi\\d': 'mp2ROI',
374+
},
375+
}],
376+
},
377+
}, nin=1, nout=1);
378+
379+
local sink = g.pnode({ type: 'DumpFrames' }, nin=1, nout=0);
380+
381+
// local graph = g.pipeline([wcls_input.adc_digits, chsel_pipes[volume], sp_pipes[volume], dnnroi(this_anode, ts_u, ts_v, output_scale=1), retagger, wcls_output.h5io, wcls_output.sp_signals, sink]);
382+
local graph = g.pipeline([wcls_input.adc_digits, fanpipe, retagger, wcls_output.sp_signals, sink]);
383+
384+
local app = {
385+
type: 'Pgrapher',
386+
data: {
387+
edges: g.edges(graph),
388+
},
389+
};
390+
391+
// Finally, the configuration sequence
392+
g.uses(graph) + [app]

0 commit comments

Comments
 (0)