Skip to content

Commit 8ac8efe

Browse files
Merge branch 'develop' into feature/acastill_deconvolution_database
2 parents c1cd4d5 + aa043fb commit 8ac8efe

15 files changed

Lines changed: 1815 additions & 25 deletions

sbndcode/JobConfigurations/base/cafmakerjob_sbnd_data_base.fcl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,11 @@ physics:
125125
# change tools in sbn to have 2D TPC sim/sp input
126126
physics.producers.pandoraShowerRazzle.SimChannelLabel: "sptpc2d:gauss"
127127
physics.producers.pandoraTrackDazzle.SimChannelLabel: "sptpc2d:gauss"
128-
129128
physics.producers.cnnid.WireLabel: "sptpc2d:gauss"
129+
# uncomment below lines to use DNN ROI SP for Razzle/Dazzle/CNNID
130+
#physics.producers.pandoraShowerRazzle.SimChannelLabel: "sptpc2d:dnnsp"
131+
#physics.producers.pandoraTrackDazzle.SimChannelLabel: "sptpc2d:dnnsp"
132+
#physics.producers.cnnid.WireLabel: "sptpc2d:dnnsp"
130133

131134
### Calorimetry for data
132135
physics.producers.cnnid.PointIdAlg.CalorimetryAlg: @local::sbnd_calorimetryalgdata

sbndcode/JobConfigurations/standard/caf/cafmakerjob_sbnd.fcl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ physics:
127127
physics.producers.pandoraShowerRazzle.SimChannelLabel: "simtpc2d:simpleSC"
128128
physics.producers.pandoraTrackDazzle.SimChannelLabel: "simtpc2d:simpleSC"
129129
physics.producers.cnnid.WireLabel: "simtpc2d:gauss"
130+
# uncomment below line for to use DNN ROI SP for CNNID scores
131+
#physics.producers.cnnid.WireLabel: "simtpc2d:dnnsp"
130132

131133
physics.producers.vertexCharge.CaloAlg: @local::sbnd_calorimetryalgmc
132134
physics.producers.vertexStub.CaloAlg: @local::sbnd_calorimetryalgmc

sbndcode/JobConfigurations/standard/reco/reco1_data.fcl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,12 @@ physics.ana: [superadata]
3535
outputs.out1.SelectEvents: [ "reco1" ]
3636

3737
physics.producers.gaushit.CalDataModuleLabel: "sptpc2d:gauss"
38+
39+
# uncomment below 4 lines to run DNN ROI finding SP
40+
#physics.producers.sptpc2d.wcls_main.outputers: ["wclsFrameSaver:spsaver" , "wclsFrameSaver:dnnsaver"]
41+
#physics.producers.sptpc2d.wcls_main.structs.use_dnnroi: true
42+
#physics.producers.sptpc2d.wcls_main.structs.nchunks: 2 # should match training config
43+
#physics.producers.sptpc2d.wcls_main.structs.tick_per_slice: 4 # should match training config
44+
45+
# uncomment below line to run DNN ROI finding SP for reco
46+
#physics.producers.gaushit.CalDataModuleLabel: "sptpc2d:dnnsp"

sbndcode/JobConfigurations/standard/standard_detsim_sbnd.fcl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,9 @@ outputs:
9292
]
9393
}
9494
}
95+
96+
# uncomment below 4 lines to run DNN ROI finding SP
97+
# physics.producers.simtpc2d.wcls_main.outputers: ["wclsDepoFluxWriter:postdrift", "wclsFrameSaver:spsaver", "wclsFrameSaver:dnnsaver"] # "wclsFrameSaver:simdigits" <- by default, do not save RawDigits. Uncomment this line to save RawDigits and set
98+
# physics.producers.simtpc2d.wcls_main.structs.use_dnnroi: true
99+
# physics.producers.simtpc2d.wcls_main.structs.nchunks: 2 # should match training config
100+
# physics.producers.simtpc2d.wcls_main.structs.tick_per_slice: 4 # should match training config

sbndcode/JobConfigurations/standard/standard_reco1_sbnd.fcl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,6 @@ physics.end_paths: [ @sequence::physics.end_paths, ana ]
3535
#outputs table overrides
3636
outputs.out1.dataTier: "reconstructed"
3737
outputs.out1.outputCommands: [@sequence::outputs.out1.outputCommands, @sequence::sbnd_reco1_drops]
38+
39+
# uncomment below line to run DNN ROI finding SP for reco -- must have run DNN ROI finding in detsim stage
40+
#physics.producers.gaushit.CalDataModuleLabel: "simtpc2d:dnnsp"
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// This produces a function to configure DNN-ROI for one APA given
2+
// anode and torch service (ts) objects.
3+
//
4+
// The prefix is prepended to all internal node names if uniqueness
5+
// beyond anode ID is needed. The output_scale allows for an ad-hoc
6+
// scaling of dnnroi output. The U and W planes will go through
7+
// dnnroi while hte W plane will be shunted. What comes out will be a
8+
// unified frame with frame tag "dnnspN" where "N" is the anode ID.
9+
10+
local wc = import "wirecell.jsonnet";
11+
local pg = import "pgraph.jsonnet";
12+
13+
14+
function (anode, ts_p0, ts_p1, prefix="dnnroi", output_scale=1.0, nticks=3428, tick_per_slice=4, nchunks=1)
15+
local apaid = anode.data.ident;
16+
local prename = prefix + std.toString(apaid);
17+
local intags = ['loose_lf%d'%apaid, 'mp2_roi%d'%apaid,
18+
'mp3_roi%d'%apaid];
19+
20+
local dnnroi_u = pg.pnode({
21+
type: "DNNROIFinding",
22+
name: prename+"u",
23+
data: {
24+
anode: wc.tn(anode),
25+
plane: 0,
26+
intags: intags,
27+
decon_charge_tag: "decon_charge%d" %apaid,
28+
outtag: "dnnsp%du"%apaid,
29+
input_scale: 0.00025, // 1/4000
30+
output_scale: output_scale,
31+
forward: wc.tn(ts_p0),
32+
tick_per_slice: tick_per_slice,
33+
nticks: nticks,
34+
nchunks: nchunks
35+
}
36+
}, nin=1, nout=1, uses=[ts_p0, anode]);
37+
local dnnroi_v = pg.pnode({
38+
type: "DNNROIFinding",
39+
name: prename+"v",
40+
data: {
41+
anode: wc.tn(anode),
42+
plane: 1,
43+
intags: intags,
44+
decon_charge_tag: "decon_charge%d" %apaid,
45+
outtag: "dnnsp%dv"%apaid,
46+
input_scale: 0.00025, // 1/4000
47+
output_scale: output_scale,
48+
forward: wc.tn(ts_p1),
49+
tick_per_slice: tick_per_slice,
50+
nticks: nticks,
51+
nchunks: nchunks
52+
}
53+
}, nin=1, nout=1, uses=[ts_p1, anode]);
54+
local dnnroi_w = pg.pnode({
55+
type: "PlaneSelector",
56+
name: prename+"w",
57+
data: {
58+
anode: wc.tn(anode),
59+
plane: 2,
60+
tags: ["gauss%d"%apaid],
61+
tag_rules: [{
62+
frame: {".*":"DNNROIFinding"},
63+
trace: {["gauss%d"%apaid]:"dnnsp%dw"%apaid},
64+
}],
65+
}
66+
}, nin=1, nout=1, uses=[anode]);
67+
68+
local dnnpipes = [dnnroi_u, dnnroi_v, dnnroi_w];
69+
local dnnfanout = pg.pnode({
70+
type: "FrameFanout",
71+
name: prename,
72+
data: {
73+
multiplicity: 3
74+
}
75+
}, nin=1, nout=3);
76+
77+
local dnnfanin = pg.pnode({
78+
type: "FrameFanin",
79+
name: prename,
80+
data: {
81+
multiplicity: 3,
82+
tag_rules: [{
83+
frame: {".*": "dnnsp%d%s" % [apaid,plane]},
84+
trace: {".*": "dnnsp%d%s" % [apaid,plane]},
85+
} for plane in ["u", "v", "w"]]
86+
},
87+
}, nin=3, nout=1);
88+
89+
local retagger = pg.pnode({
90+
type: "Retagger",
91+
name: 'dnnroi%d' % apaid,
92+
data: {
93+
// Note: retagger keeps tag_rules an array to be like frame fanin/fanout.
94+
tag_rules: [{
95+
// Retagger also handles "frame" and "trace" like fanin/fanout
96+
// merge separately all traces like gaussN to gauss.
97+
frame: {
98+
".*": "dnnsp%d" % apaid
99+
},
100+
merge: {
101+
".*": "dnnsp%d" % apaid
102+
},
103+
}],
104+
},
105+
}, nin=1, nout=1);
106+
107+
pg.intern(innodes=[dnnfanout],
108+
outnodes=[retagger],
109+
centernodes=dnnpipes+[dnnfanin],
110+
edges=[pg.edge(dnnfanout, dnnpipes[ind], ind, 0) for ind in [0,1,2]] +
111+
[pg.edge(dnnpipes[ind], dnnfanin, 0, ind) for ind in [0,1,2]] +
112+
[pg.edge(dnnfanin, retagger, 0, 0)])

sbndcode/WireCell/cfg/pgrapher/experiment/sbnd/wcls-nf-sp-data.jsonnet

Lines changed: 173 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
local sigoutform = std.extVar('signal_output_form'); // eg "sparse" or "dense"
2525
local raw_input_label = std.extVar('raw_input_label'); // eg "daq"
2626
local use_paramresp = std.extVar('use_paramresp'); // eg "true" or "false"
27+
local use_dnnroi = std.extVar('use_dnnroi');
28+
local nchunks = std.extVar('nchunks');
29+
local tick_per_slice = std.extVar('tick_per_slice');
30+
local dnnroi_model_p0 = std.extVar('dnnroi_model_p0');
31+
local dnnroi_model_p1 = std.extVar('dnnroi_model_p1');
2732

2833
local g = import 'pgraph.jsonnet';
2934
local f = import 'pgrapher/experiment/sbnd/funcs.jsonnet';
@@ -124,6 +129,22 @@ local wcls_output = {
124129
chanmaskmaps: ['bad'],
125130
},
126131
}, nin=1, nout=1, uses=[mega_anode]),
132+
133+
dnnsp_signals: g.pnode({
134+
type: 'wclsFrameSaver',
135+
name: 'dnnsaver',
136+
data: {
137+
anode: wc.tn(mega_anode),
138+
digitize: false, // true means save as RawDigit, else recob::Wire
139+
frame_tags: ['dnnsp'],
140+
141+
// this may be needed to convert the decon charge [units:e-] to be consistent with the LArSoft default ?unit? e.g. decon charge * 0.005 --> "charge value" to GaussHitFinder
142+
frame_scale: [0.02, 0.02, 0.02],
143+
nticks: params.daq.nticks,
144+
145+
chanmaskmaps: ['dnnspbad'],
146+
},
147+
}, nin=1, nout=1, uses=[mega_anode]),
127148
};
128149

129150
local base = import 'pgrapher/experiment/sbnd/chndb-base.jsonnet';
@@ -151,14 +172,85 @@ local nf_maker = import 'pgrapher/experiment/sbnd/nf-data.jsonnet'; //added Ewer
151172
local nf_pipes = [nf_maker(params, tools.anodes[n], chndb[n], n, name='nf%d' % n) for n in std.range(0, std.length(tools.anodes) - 1)];
152173

153174
local sp_maker = import 'pgrapher/experiment/sbnd/sp.jsonnet';
154-
local sp = sp_maker(params, tools, { sparse: sigoutform == 'sparse' });
175+
local sp_override = if use_dnnroi then {
176+
sparse: true,
177+
use_roi_debug_mode: true,
178+
save_negtive_charge: true, // TODO: no negative charge in gauss, default is false
179+
use_multi_plane_protection: true,
180+
mp_tick_resolution: 4,
181+
tight_lf_tag: "",
182+
// loose_lf_tag: "",
183+
cleanup_roi_tag: "",
184+
break_roi_loop1_tag: "",
185+
break_roi_loop2_tag: "",
186+
shrink_roi_tag: "",
187+
extend_roi_tag: "",
188+
// m_decon_charge_tag: "",
189+
} else {
190+
sparse: true,
191+
};
192+
//local sp = sp_maker(params, tools, { sparse: sigoutform == 'sparse' });
193+
local sp = sp_maker(params, tools, sp_override);
155194
local sp_pipes = [sp.make_sigproc(a) for a in tools.anodes];
195+
local dnnroi = import 'dnnroi.jsonnet';
196+
local ts_p0 = {
197+
type: "TorchService",
198+
name: "dnnroi_p0",
199+
tick_per_slice: tick_per_slice,
200+
data: {
201+
model: dnnroi_model_p0,
202+
device: "cpu",
203+
concurrency: 1,
204+
},
205+
};
206+
207+
local ts_p1 = {
208+
type: "TorchService",
209+
name: "dnnroi_p1",
210+
tick_per_slice: tick_per_slice,
211+
data: {
212+
model: dnnroi_model_p1,
213+
device: "cpu",
214+
concurrency: 1,
215+
},
216+
};
156217

157218
local magoutput = 'sbnd-data-check.root';
158219
local magnify = import 'pgrapher/experiment/sbnd/magnify-sinks.jsonnet';
159220
local sinks = magnify(tools, magoutput);
160221

161-
local nfsp_pipes = [
222+
local fanout = function (name, multiplicity=2)
223+
g.pnode({
224+
type: 'FrameFanout',
225+
name: name,
226+
data: {
227+
multiplicity: multiplicity
228+
},
229+
}, nin=1, nout=multiplicity);
230+
231+
local sp_fans = [fanout("sp_fan_%d" % n) for n in std.range(0, std.length(tools.anodes) - 1)];
232+
local dnnroi_pipes = [ dnnroi(tools.anodes[n], ts_p0, ts_p1, output_scale=1, nchunks=nchunks) for n in std.range(0, std.length(tools.anodes) - 1) ];
233+
local nfsp_pipes = if use_dnnroi then
234+
[
235+
g.intern(
236+
innodes=[chsel_pipes[n]],
237+
outnodes=[dnnroi_pipes[n],sinks.decon_pipe[n]],
238+
centernodes=[nf_pipes[n], sp_pipes[n], sp_fans[n], sinks.decon_pipe[n]],
239+
edges=[
240+
g.edge(chsel_pipes[n], nf_pipes[n], 0, 0),
241+
g.edge(nf_pipes[n], sp_pipes[n], 0, 0),
242+
g.edge(sp_pipes[n], sp_fans[n], 0, 0),
243+
g.edge(sp_fans[n], dnnroi_pipes[n], 0, 0),
244+
g.edge(sp_fans[n], sinks.decon_pipe[n], 1, 0),
245+
],
246+
iports=chsel_pipes[n].iports,
247+
oports=dnnroi_pipes[n].oports+sinks.decon_pipe[n].oports,
248+
name='nfsp_pipe_%d' % n,
249+
)
250+
for n in std.range(0, std.length(tools.anodes) - 1)
251+
]
252+
else
253+
[
162254
g.pipeline([
163255
chsel_pipes[n],
164256
//sinks.orig_pipe[n],
@@ -177,8 +269,9 @@ local nfsp_pipes = [
177269

178270
local fanpipe = f.fanpipe('FrameFanout', nfsp_pipes, 'FrameFanin', 'sn_mag_nf');
179271

180-
local retagger = g.pnode({
272+
local retagger = function(name) g.pnode({
181273
type: 'Retagger',
274+
name: name,
182275
data: {
183276
// Note: retagger keeps tag_rules an array to be like frame fanin/fanout.
184277
tag_rules: [{
@@ -190,16 +283,89 @@ local retagger = g.pnode({
190283
merge: {
191284
'gauss\\d': 'gauss',
192285
'wiener\\d': 'wiener',
286+
'dnnsp\\d': 'dnnsp',
193287
},
194288
}],
195289
},
196290
}, nin=1, nout=1);
197291

198-
local sink = g.pnode({ type: 'DumpFrames' }, nin=1, nout=0);
292+
local retag_dnnroi = retagger("retag_dnnroi");
293+
local retag_sp = retagger("retag_sp");
199294

200295

201-
// local graph = g.pipeline([wcls_input.adc_digits, rootfile_creation_frames, fanpipe, retagger, wcls_output.sp_signals, sink]);
202-
local graph = g.pipeline([wcls_input.adc_digits, fanpipe, retagger, wcls_output.sp_signals, sink]);
296+
local sink = function(name) g.pnode({ type: 'DumpFrames', name: name }, nin=1, nout=0);
297+
local sink_dnnroi = sink("sink_dnnroi");
298+
local sink_sp = sink("sink_sp");
299+
300+
local fanout_apa = g.pnode({
301+
type: 'FrameFanout',
302+
name: 'fanout_apa',
303+
data: {
304+
multiplicity: std.length(tools.anodes),
305+
"tag_rules": [
306+
{
307+
"frame": {
308+
".*": "orig%d" % n
309+
},
310+
"trace": { }
311+
}
312+
for n in std.range(0, std.length(tools.anodes) - 1)
313+
]
314+
}},
315+
nin=1, nout=std.length(tools.anodes));
316+
local framefanin = function(name) g.pnode({
317+
type: 'FrameFanin',
318+
name: name,
319+
data: {
320+
multiplicity: std.length(tools.anodes),
321+
322+
"tag_rules": [
323+
{
324+
"frame": {
325+
".*": "framefanin"
326+
},
327+
trace: {
328+
['dnnsp%d' % n]: ['dnnsp%d' % n],
329+
['gauss%d' % n]: ['gauss%d' % n],
330+
['wiener%d' % n]: ['wiener%d' % n],
331+
['threshold%d' % n]: ['threshold%d' % n],
332+
},
333+
}
334+
for n in std.range(0, std.length(tools.anodes) - 1)
335+
],
336+
"tags": [ ]
337+
},
338+
}, nin=std.length(tools.anodes), nout=1);
339+
local fanin_apa_dnnroi = framefanin('fanin_apa_dnnroi');
340+
local fanin_apa_sp = framefanin('fanin_apa_sp');
341+
342+
local graph = if use_dnnroi then
343+
g.intern(
344+
innodes=[wcls_input.adc_digits],
345+
outnodes=[],
346+
centernodes=nfsp_pipes+[fanout_apa, retag_dnnroi, retag_sp, fanin_apa_dnnroi, fanin_apa_sp, wcls_output.sp_signals, wcls_output.dnnsp_signals, sink_dnnroi, sink_sp],
347+
edges=[
348+
g.edge(wcls_input.adc_digits, fanout_apa, 0, 0),
349+
g.edge(fanout_apa, nfsp_pipes[0], 0, 0),
350+
g.edge(fanout_apa, nfsp_pipes[1], 1, 0),
351+
g.edge(nfsp_pipes[0], fanin_apa_dnnroi, 0, 0),
352+
g.edge(nfsp_pipes[1], fanin_apa_dnnroi, 0, 1),
353+
g.edge(fanin_apa_dnnroi, retag_dnnroi, 0, 0),
354+
g.edge(retag_dnnroi, wcls_output.dnnsp_signals, 0, 0),
355+
g.edge(wcls_output.dnnsp_signals, sink_dnnroi, 0, 0),
356+
g.edge(nfsp_pipes[0], fanin_apa_sp, 1, 0),
357+
g.edge(nfsp_pipes[1], fanin_apa_sp, 1, 1),
358+
g.edge(fanin_apa_sp, retag_sp, 0, 0),
359+
g.edge(retag_sp, wcls_output.sp_signals, 0, 0),
360+
g.edge(wcls_output.sp_signals, sink_sp, 0, 0),
361+
]
362+
)
363+
else
364+
g.pipeline([wcls_input.adc_digits,
365+
fanpipe,
366+
retag_sp,
367+
wcls_output.sp_signals,
368+
sink_sp]);
203369

204370
local app = {
205371
type: 'TbbFlow',
@@ -210,3 +376,4 @@ local app = {
210376

211377
// Finally, the configuration sequence
212378
g.uses(graph) + [app]
379+

0 commit comments

Comments
 (0)