Skip to content

Commit 40d6440

Browse files
Merge branch 'develop' into bugfix/wirecellgrouped
2 parents a6da52b + 945728f commit 40d6440

17 files changed

Lines changed: 1841 additions & 89 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"

sbndcode/OpDetReco/OpDeconvolution/Alg/OpDeconvolutionAlgWienerData_tool.cc

Lines changed: 26 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
#include "sbndcode/OpDetReco/OpDeconvolution/Alg/OpDeconvolutionAlg.hh"
2929

30+
#include "sbndcode/Calibration/PDSDatabaseInterface/PMTCalibrationDatabase.h"
31+
#include "sbndcode/Calibration/PDSDatabaseInterface/IPMTCalibrationDatabaseService.h"
3032

3133
namespace opdet {
3234
class OpDeconvolutionAlgWiener;
@@ -37,7 +39,7 @@ class opdet::OpDeconvolutionAlgWiener : opdet::OpDeconvolutionAlg {
3739
public:
3840
explicit OpDeconvolutionAlgWiener(fhicl::ParameterSet const& p);
3941

40-
~OpDeconvolutionAlgWiener() {}
42+
~OpDeconvolutionAlgWiener() {delete fFilterTF1;}
4143

4244
// Required functions.
4345
std::vector<raw::OpDetWaveform> RunDeconvolution(std::vector<raw::OpDetWaveform> const& wfHandle) override;
@@ -65,7 +67,6 @@ class opdet::OpDeconvolutionAlgWiener : opdet::OpDeconvolutionAlg {
6567
double fPMTChargeToADC;
6668
double fDecoWaveformPrecision;
6769
short unsigned int fBaselineSample;
68-
std::string fOpDetDataFile;
6970
std::string fFilter;
7071
std::string fElectronics;
7172
bool fScaleHypoSignal;
@@ -80,6 +81,7 @@ class opdet::OpDeconvolutionAlgWiener : opdet::OpDeconvolutionAlg {
8081
unsigned int NDecoWf;
8182

8283
TF1 *fFilterTF1;
84+
8385
std::vector<double> fSignalHypothesis;
8486
std::vector<double> fNoiseHypothesis;
8587

@@ -88,6 +90,8 @@ class opdet::OpDeconvolutionAlgWiener : opdet::OpDeconvolutionAlg {
8890
short unsigned int fBaseSampleBins;
8991
double fBaseVarCut;
9092

93+
sbndDB::PMTCalibrationDatabase const* fPMTCalibrationDatabaseService;
94+
9195
// Declare member functions
9296
void ApplyExpoAvSmoothing(std::vector<double>& wf);
9397
void ApplyUnAvSmoothing(std::vector<double>& wf);
@@ -125,7 +129,6 @@ opdet::OpDeconvolutionAlgWiener::OpDeconvolutionAlgWiener(fhicl::ParameterSet co
125129
fPMTChargeToADC = p.get< double >("PMTChargeToADC");
126130
fDecoWaveformPrecision = p.get< double >("DecoWaveformPrecision");
127131
fBaselineSample = p.get< short unsigned int >("BaselineSample");
128-
fOpDetDataFile = p.get< std::string >("OpDetDataFile");
129132
fSkipChannelList = p.get< std::vector<int>>("SkipChannelList");
130133
fFilter = p.get< std::string >("Filter");
131134
fElectronics = p.get< std::string >("Electronics");
@@ -138,6 +141,8 @@ opdet::OpDeconvolutionAlgWiener::OpDeconvolutionAlgWiener(fhicl::ParameterSet co
138141
fBaseVarCut = p.get< double >("BaseVarCut");
139142
fFilterParams = p.get< std::vector<double> >("FilterParams");
140143

144+
fFilterTF1 = new TF1("FilterTemplate", fFilter.c_str());
145+
141146
fNormUnAvSmooth=1./(2*fUnAvNeighbours+1);
142147
NDecoWf=0;
143148
MaxBinsFFT=std::pow(2, fMaxFFTSizePow);
@@ -147,38 +152,10 @@ opdet::OpDeconvolutionAlgWiener::OpDeconvolutionAlgWiener(fhicl::ParameterSet co
147152
if (fElectronics=="Daphne") fSamplingFreq=fDaphne_Freq/1000.;//in GHz
148153
auto const* lar_prop = lar::providerFrom<detinfo::LArPropertiesService>();
149154

150-
//Load SER
151-
std::string fname;
152-
cet::search_path sp("FW_SEARCH_PATH");
153-
sp.find_file(fOpDetDataFile, fname);
154-
TFile* file = TFile::Open(fname.c_str(), "READ");
155-
std::vector<std::vector<double>>* SinglePEVec_p;
156-
std::vector<int>* fSinglePEChannels_p;
157-
std::vector<double>* fPeakAmplitude_p;
158-
std::vector<std::vector<double>> * fFilterParamVector_p;
159-
160-
file->GetObject("SERChannels", fSinglePEChannels_p);
161-
file->GetObject("SinglePEVec", SinglePEVec_p);
162-
file->GetObject("PeakAmplitude", fPeakAmplitude_p);
163-
file->GetObject("FilterParams", fFilterParamVector_p);
164-
165-
if (fElectronics=="Daphne") file->GetObject("SinglePEVec_40ftCable_Daphne", SinglePEVec_p);
166-
fSinglePEWaveVector = *SinglePEVec_p;
167-
fSinglePEChannels = *fSinglePEChannels_p;
168-
fPeakAmplitude = *fPeakAmplitude_p;
169-
fFilterParamVector = *fFilterParamVector_p;
170-
171-
mf::LogInfo("OpDeconvolutionAlg")<<"Loaded SER from "<<fOpDetDataFile<<"... size="<<fSinglePEWave.size()<<std::endl;
172-
file->Close();
173-
174-
if(fUseParamFilter && !fUseParamFilterInidividualChannel){
175-
//If use param filter but not one for each channel, build it here
176-
fFilterTF1 = new TF1("FilterTemplate", fFilter.c_str());
177-
for(size_t k=0; k<fFilterParams.size(); k++)
178-
fFilterTF1->SetParameter(k, fFilterParams[k]);
179-
mf::LogInfo("OpDeconvolutionAlg")<<"Creating parametrized filter... TF1:"<<fFilter<<std::endl;
180-
}
181-
else if (!fUseParamFilter){
155+
//Load PMT Calibration Database
156+
fPMTCalibrationDatabaseService = lar::providerFrom<sbndDB::IPMTCalibrationDatabaseService const>();
157+
158+
if (!fUseParamFilter){
182159
//Create light signal hypothesis for "on-fly" Wiener filter
183160
fSignalHypothesis.resize(MaxBinsFFT, 0);
184161
if(fFilter=="Wiener")
@@ -200,38 +177,26 @@ std::vector<raw::OpDetWaveform> opdet::OpDeconvolutionAlgWiener::RunDeconvolutio
200177
{
201178
int channelNumber = wf.ChannelNumber();
202179
auto it = std::find(fSkipChannelList.begin(), fSkipChannelList.end(), channelNumber);
203-
bool AnalyseChannel = false;
204180
if (it == fSkipChannelList.end()) {
205-
//If it's not try to find its SER in the file
206-
for(size_t i=0; i<fSinglePEChannels.size(); i++)
181+
fSinglePEWave = fPMTCalibrationDatabaseService->getSER(channelNumber);
182+
double SPEAmplitude = fPMTCalibrationDatabaseService->getSPEAmplitude(channelNumber);
183+
double SPEPeakValue = *std::max_element(fSinglePEWave.begin(), fSinglePEWave.end(), [](double a, double b) {return std::abs(a) < std::abs(b);});
184+
double SinglePENormalization = std::abs(SPEAmplitude/SPEPeakValue);
185+
std::transform(fSinglePEWave.begin(), fSinglePEWave.end(), fSinglePEWave.begin(), [SinglePENormalization](double val) {return val * SinglePENormalization;});
186+
fSinglePEWave.resize(MaxBinsFFT, 0);
187+
// If use channel dependent param filter
188+
if(fUseParamFilter)
207189
{
208-
if(fSinglePEChannels[i]==channelNumber)
190+
double GaussFilterPower = fPMTCalibrationDatabaseService->getGaussFilterPower(channelNumber);
191+
double GaussFilterWC = fPMTCalibrationDatabaseService->getGaussFilterWC(channelNumber);
192+
fFilterParamChannel = {GaussFilterWC, GaussFilterPower};
193+
for(size_t k=0; k<fFilterParamChannel.size(); k++)
209194
{
210-
fSinglePEWave = fSinglePEWaveVector[i];
211-
double SPEPeakValue = *std::max_element(fSinglePEWave.begin(), fSinglePEWave.end(), [](double a, double b) {return std::abs(a) < std::abs(b);});
212-
double SinglePENormalization = std::abs(fPeakAmplitude[i]/SPEPeakValue);
213-
std::transform(fSinglePEWave.begin(), fSinglePEWave.end(), fSinglePEWave.begin(), [SinglePENormalization](double val) {return val * SinglePENormalization;});
214-
fSinglePEWave.resize(MaxBinsFFT, 0);
215-
AnalyseChannel = true;
216-
// If use channel dependent param filter
217-
if(fUseParamFilterInidividualChannel)
218-
{
219-
fFilterParamChannel = fFilterParamVector[i];
220-
fFilterTF1 = new TF1("FilterTemplate", fFilter.c_str());
221-
for(size_t k=0; k<fFilterParamChannel.size(); k++)
222-
{
223-
fFilterTF1->SetParameter(k, fFilterParamChannel[k]);
224-
}
225-
226-
227-
mf::LogInfo("OpDeconvolutionAlg")<<"Creating parametrized filter... TF1:"<<fFilter << " for channel " << channelNumber <<std::endl;
228-
}
229-
break;
195+
fFilterTF1->SetParameter(k, fFilterParamChannel[k]);
230196
}
197+
mf::LogInfo("OpDeconvolutionAlg")<<"Creating parametrized filter... TF1:"<<fFilter << " for channel " << channelNumber <<std::endl;
231198
}
232-
if(AnalyseChannel == false) mf::LogError("OpDeconvolutionAlg") << " SER for channel " << channelNumber <<" not found in the file \n";
233199
}
234-
if(!AnalyseChannel) continue;
235200
//Read waveform
236201
size_t wfsize=wf.Waveform().size();
237202
if(wfsize>MaxBinsFFT){
@@ -537,15 +502,13 @@ std::vector<TComplex> opdet::OpDeconvolutionAlgWiener::DeconvolutionKernel(size_
537502
}
538503
}
539504

540-
541505
if(fDebug){
542506
std::string name="h_wienerfilter_"+std::to_string(NDecoWf);
543507
TH1F * hs_wiener = tfs->make< TH1F >
544508
(name.c_str(),"Wiener Filter;Frequency Bin;Magnitude",size/2, 0, size/2);
545509
for(size_t k=0; k<size/2; k++)
546510
hs_wiener->SetBinContent(k, TComplex::Abs( kernel[k]*serfft[k] ) );
547511
}
548-
if(fUseParamFilter && fUseParamFilterInidividualChannel) delete fFilterTF1;
549512
return kernel;
550513
}
551514

sbndcode/OpDetReco/OpDeconvolution/Alg/opdeconvolution_alg_data.fcl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ OpDeconvolutionAlgData:
66
tool_type: "OpDeconvolutionAlgWienerData"
77
Debug: false
88
MaxFFTSizePow: 16
9-
OpDetDataFile: "./OpDetSim/digi_pmt_sbnd_data_OV6.root"
109
BaseSampleBins: 30
1110
BaseVarCut: 50
1211
SkipChannelList: []
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)])

0 commit comments

Comments
 (0)