Skip to content

Commit 5785e38

Browse files
Merge pull request #565 from SBNSoftware/feature/lynnt_pmtmetricsana
Add Analyzer and Filter for PMT Flash Metrics from PMT Software Trigger
2 parents 232f0c9 + f159fe1 commit 5785e38

6 files changed

Lines changed: 337 additions & 0 deletions

File tree

sbndcode/Trigger/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set(
2424
sbndcode_CRTUtils
2525
sbnobj::Common_CRT
2626
sbnobj::SBND_CRT
27+
sbnobj::SBND_Timing
2728
sbndcode_CRTUtils
2829
sbndcode_GeoWrappers
2930
art::Framework_Services_Optional_RandomNumberGenerator_service
@@ -41,6 +42,8 @@ add_subdirectory(PMT)
4142

4243
cet_build_plugin(ArtdaqFragmentProducer art::module SOURCE ArtdaqFragmentProducer_module.cc LIBRARIES ${MODULE_LIBRARIES})
4344
cet_build_plugin(MetricProducer art::module SOURCE MetricProducer_module.cc LIBRARIES ${MODULE_LIBRARIES})
45+
cet_build_plugin(MetricAnalyzer art::module SOURCE MetricAnalyzer_module.cc LIBRARIES ${MODULE_LIBRARIES})
46+
cet_build_plugin(MetricFilter art::module SOURCE MetricFilter_module.cc LIBRARIES ${MODULE_LIBRARIES})
4447

4548
install_headers()
4649
install_fhicl()
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
////////////////////////////////////////////////////////////////////////
2+
// Class: MetricAnalyzer
3+
// Plugin Type: analyzer (Unknown Unknown)
4+
// File: MetricAnalyzer_module.cc
5+
//
6+
// Generated at Fri Nov 22 12:06:48 2024 by Lynn Tung using cetskelgen
7+
// from cetlib version 3.18.02.
8+
////////////////////////////////////////////////////////////////////////
9+
10+
#include "art/Framework/Core/EDAnalyzer.h"
11+
#include "art/Framework/Core/ModuleMacros.h"
12+
#include "art/Framework/Principal/Event.h"
13+
#include "art/Framework/Principal/Handle.h"
14+
#include "art/Framework/Principal/Run.h"
15+
#include "art/Framework/Principal/SubRun.h"
16+
#include "canvas/Utilities/InputTag.h"
17+
#include "fhiclcpp/ParameterSet.h"
18+
#include "messagefacility/MessageLogger/MessageLogger.h"
19+
20+
#include "sbndaq-artdaq-core/Obj/SBND/pmtSoftwareTrigger.hh"
21+
#include "sbnobj/SBND/Timing/DAQTimestamp.hh"
22+
23+
#include "art_root_io/TFileService.h"
24+
#include "TFile.h"
25+
#include "TTree.h"
26+
27+
namespace sbndaq {
28+
class MetricAnalyzer;
29+
}
30+
31+
32+
class sbndaq::MetricAnalyzer : public art::EDAnalyzer {
33+
public:
34+
explicit MetricAnalyzer(fhicl::ParameterSet const& p);
35+
// The compiler-generated destructor is fine for non-base
36+
// classes without bare pointers or other resource use.
37+
38+
// Plugins should not be copied or assigned.
39+
MetricAnalyzer(MetricAnalyzer const&) = delete;
40+
MetricAnalyzer(MetricAnalyzer&&) = delete;
41+
MetricAnalyzer& operator=(MetricAnalyzer const&) = delete;
42+
MetricAnalyzer& operator=(MetricAnalyzer&&) = delete;
43+
44+
// Required functions.
45+
void analyze(art::Event const& e) override;
46+
47+
private:
48+
std::string fmetric_instance_name;
49+
std::string fmetric_module_label;
50+
51+
std::string fspectdc_module_label;
52+
uint32_t fspectdc_etrig_ch;
53+
54+
TTree* tree;
55+
int _run, _subrun, _event;
56+
float _flash_peakpe;
57+
float _flash_peaktime; // us
58+
float _trigger_dt; // us
59+
int _timing_type;
60+
int _tdc_etrig;
61+
int _tdc_bes;
62+
};
63+
64+
65+
sbndaq::MetricAnalyzer::MetricAnalyzer(fhicl::ParameterSet const& p)
66+
: EDAnalyzer{p} // ,
67+
// More initializers here.
68+
{
69+
fmetric_module_label = p.get<std::string>("metric_module_label","pmtmetricproducer");
70+
fmetric_instance_name = p.get<std::string>("metric_instance_name","");
71+
fspectdc_module_label = p.get<std::string>("spectdc_module_name","tdcdecoder");
72+
fspectdc_etrig_ch = p.get<uint32_t>("spectdc_etrig_ch",4);
73+
74+
art::ServiceHandle<art::TFileService> fs;
75+
tree = fs->make<TTree>("tree","metrictree");
76+
tree->Branch("run",&_run,"run/I");
77+
tree->Branch("subrun",&_subrun,"subrun/I");
78+
tree->Branch("event",&_event,"event/I");
79+
tree->Branch("flash_peakpe",&_flash_peakpe,"flash_peakpe/F");
80+
tree->Branch("flash_peaktime",&_flash_peaktime,"flash_peaktime/F");
81+
tree->Branch("trigger_dt",&_trigger_dt,"trigger_dt/F");
82+
tree->Branch("timing_type",&_timing_type,"timing_type/I");
83+
tree->Branch("tdc_etrig",&_tdc_etrig,"tdc_etrig/I");
84+
tree->Branch("tdc_bes",&_tdc_bes,"tdc_bes/I");
85+
}
86+
87+
void sbndaq::MetricAnalyzer::analyze(art::Event const& e)
88+
{
89+
_run = e.id().run();
90+
_subrun = e.id().subRun();
91+
_event = e.id().event();
92+
93+
// initialize tree variables
94+
_flash_peakpe = -999999999;
95+
_flash_peaktime = -999999999;
96+
_trigger_dt = -999999999;
97+
_timing_type = -1;
98+
_tdc_etrig = -999999999;
99+
_tdc_bes = -999999999;
100+
101+
art::Handle<std::vector<sbnd::trigger::pmtSoftwareTrigger>> metricHandle;
102+
if (fmetric_instance_name.empty()) e.getByLabel(fmetric_module_label,metricHandle);
103+
else e.getByLabel(fmetric_module_label,fmetric_instance_name,metricHandle);
104+
if (!metricHandle.isValid() || metricHandle->size() == 0){
105+
std::cout << "No Metrics found" << std::endl;
106+
tree->Fill();
107+
return;
108+
}
109+
else{
110+
const std::vector<sbnd::trigger::pmtSoftwareTrigger> metric_v(*metricHandle);
111+
auto metric = metric_v[0];
112+
_trigger_dt = float(metric.trig_ts)/1e3;
113+
_flash_peakpe = metric.peakPE;
114+
_flash_peaktime = metric.peaktime;
115+
}
116+
117+
// see if etrig exists
118+
art::Handle<std::vector<sbnd::timing::DAQTimestamp>> tdcHandle;
119+
e.getByLabel(fspectdc_module_label,tdcHandle);
120+
bool found_ett = false;
121+
122+
if (!tdcHandle.isValid() || tdcHandle->size() == 0)
123+
std::cout << "No SPECTDC products found." << std::endl;
124+
else{
125+
const std::vector<sbnd::timing::DAQTimestamp> tdc_v(*tdcHandle);
126+
for (size_t i=0; i<tdc_v.size(); i++){
127+
auto tdc = tdc_v[i];
128+
const uint32_t ch = tdc.Channel();
129+
if (ch==fspectdc_etrig_ch) found_ett = true;
130+
if (ch==fspectdc_etrig_ch) _tdc_etrig = tdc.Timestamp()%uint64_t(1e9);
131+
if (ch==1) _tdc_bes = tdc.Timestamp()%uint64_t(1e9);
132+
}
133+
}
134+
if (found_ett) _timing_type = 0;
135+
else _timing_type = 1;
136+
137+
tree->Fill();
138+
}
139+
140+
DEFINE_ART_MODULE(sbndaq::MetricAnalyzer)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
////////////////////////////////////////////////////////////////////////
2+
// Class: MetricFilter
3+
// Plugin Type: filter (Unknown Unknown)
4+
// File: MetricFilter_module.cc
5+
//
6+
// Generated at Fri Dec 13 06:19:04 2024 by Lynn Tung using cetskelgen
7+
// from cetlib version 3.18.02.
8+
////////////////////////////////////////////////////////////////////////
9+
10+
#include "art/Framework/Core/EDFilter.h"
11+
#include "art/Framework/Core/ModuleMacros.h"
12+
#include "art/Framework/Principal/Event.h"
13+
#include "art/Framework/Principal/Handle.h"
14+
#include "art/Framework/Principal/Run.h"
15+
#include "art/Framework/Principal/SubRun.h"
16+
#include "canvas/Utilities/InputTag.h"
17+
#include "fhiclcpp/ParameterSet.h"
18+
#include "messagefacility/MessageLogger/MessageLogger.h"
19+
20+
#include "sbndaq-artdaq-core/Obj/SBND/pmtSoftwareTrigger.hh"
21+
22+
#include <memory>
23+
24+
namespace sbndaq {
25+
class MetricFilter;
26+
}
27+
28+
29+
class sbndaq::MetricFilter : public art::EDFilter {
30+
public:
31+
explicit MetricFilter(fhicl::ParameterSet const& p);
32+
// The compiler-generated destructor is fine for non-base
33+
// classes without bare pointers or other resource use.
34+
35+
// Plugins should not be copied or assigned.
36+
MetricFilter(MetricFilter const&) = delete;
37+
MetricFilter(MetricFilter&&) = delete;
38+
MetricFilter& operator=(MetricFilter const&) = delete;
39+
MetricFilter& operator=(MetricFilter&&) = delete;
40+
41+
// Required functions.
42+
bool filter(art::Event& e) override;
43+
44+
private:
45+
std::string fmetric_instance_name;
46+
std::string fmetric_module_label;
47+
48+
float ftime_min; // us
49+
float ftime_max; // us
50+
float fpe_thresh;
51+
52+
// Declare member data here.
53+
54+
};
55+
56+
57+
sbndaq::MetricFilter::MetricFilter(fhicl::ParameterSet const& p)
58+
: EDFilter{p} // ,
59+
// More initializers here.
60+
{
61+
fmetric_module_label = p.get<std::string>("metric_module_label","pmtmetricproducer");
62+
fmetric_instance_name = p.get<std::string>("metric_instance_name","");
63+
ftime_min = p.get<float>("time_min",0);
64+
ftime_max = p.get<float>("time_max",3);
65+
fpe_thresh = p.get<float>("pe_thresh",50);
66+
}
67+
68+
bool sbndaq::MetricFilter::filter(art::Event& e)
69+
{
70+
// Implementation of required member function here.
71+
art::Handle<std::vector<sbnd::trigger::pmtSoftwareTrigger>> metricHandle;
72+
if (fmetric_instance_name.empty()) e.getByLabel(fmetric_module_label,metricHandle);
73+
else e.getByLabel(fmetric_module_label,fmetric_instance_name,metricHandle);
74+
if (!metricHandle.isValid() || metricHandle->size() == 0){
75+
return false;
76+
}
77+
else{
78+
const std::vector<sbnd::trigger::pmtSoftwareTrigger> metric_v(*metricHandle);
79+
auto metric = metric_v[0];
80+
auto flash_peakpe = metric.peakPE;
81+
auto flash_peaktime = metric.peaktime; // us
82+
83+
bool pass_timing = (flash_peaktime > ftime_min) && (flash_peaktime < ftime_max);
84+
bool pass_pe = flash_peakpe > fpe_thresh;
85+
return pass_timing && pass_pe;
86+
}
87+
88+
}
89+
90+
DEFINE_ART_MODULE(sbndaq::MetricFilter)

sbndcode/Trigger/metricfilter.fcl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
BEGIN_PROLOG
2+
3+
metricfilter_sbnd:
4+
{
5+
module_type: "MetricFilter"
6+
metric_module_label: "pmtmetricproducer"
7+
time_min: 0
8+
time_max: 3
9+
pe_thresh: 50
10+
}
11+
12+
END_PROLOG

sbndcode/Trigger/run_metricana.fcl

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "spectdc_decoder_sbnd.fcl"
2+
3+
process_name: MetricAna
4+
5+
services: {
6+
TFileService : {fileName: "metricana.root"}
7+
}
8+
9+
source:
10+
{
11+
module_type: RootInput
12+
maxEvents: -1 # Number of events to create
13+
}
14+
15+
outputs:
16+
{
17+
out1:
18+
{
19+
module_type: RootOutput
20+
fileName: "metricana-art.root"
21+
}
22+
}
23+
24+
physics:
25+
{
26+
27+
producers:{
28+
tdcdecoder: @local::spec_tdc_decoder_sbnd
29+
}
30+
31+
filters:{}
32+
33+
analyzers:{
34+
metricana: {
35+
module_type: MetricAnalyzer
36+
}
37+
}
38+
39+
40+
reco: [tdcdecoder]
41+
42+
# define the output stream, there could be more than one if using filters
43+
stream1: [metricana]
44+
45+
# trigger_paths is a keyword and contains the paths that modify the art::event,
46+
# ie filters and producers
47+
trigger_paths: [reco]
48+
49+
# end_paths is a keyword and contains the paths that do not modify the art::Event,
50+
# ie analyzers and output streams. these all run simultaneously
51+
end_paths: [stream1]
52+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "metricfilter.fcl"
2+
3+
process_name: MetricFilter
4+
5+
source:
6+
{
7+
module_type: RootInput
8+
maxEvents: -1 # Number of events to create
9+
}
10+
11+
outputs:
12+
{
13+
out1:
14+
{
15+
module_type: RootOutput
16+
fileName: "metricfiltered-art.root"
17+
}
18+
}
19+
20+
physics:
21+
{
22+
producers: {}
23+
filters:
24+
{
25+
metricfilter: @local::metricfilter_sbnd
26+
}
27+
analyzers:{}
28+
29+
reco: [metricfilter]
30+
stream1: [out1]
31+
trigger_paths: [reco]
32+
end_paths: [stream1]
33+
}
34+
35+
outputs.out1.SelectEvents: [ "reco" ]
36+
37+
# beam window as of run17998
38+
physics.filters.metricfilter.time_min: 0.7
39+
physics.filters.metricfilter.time_max: 2.3
40+
physics.filters.metricfilter.pe_thresh: 50

0 commit comments

Comments
 (0)