Skip to content

Commit 4e0cba4

Browse files
Merge pull request #845 from SBNSoftware/trj_digital_noise_event_filter_oct9_2025
Digital Noise Event Filter
2 parents 42821aa + a208af3 commit 4e0cba4

4 files changed

Lines changed: 171 additions & 2 deletions

File tree

sbndcode/Utilities/CMakeLists.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,15 @@ cet_build_plugin( SignalShapingServiceSBND art::service SOURCE SignalShapingSer
2828
)
2929

3030
cet_build_plugin( DigitalNoiseChannelStatus art::service SOURCE DigitalNoiseChannelStatus_service.cc LIBRARIES
31-
${sbnd_util_lib_list}
31+
${sbnd_util_lib_list}
3232
)
33-
33+
34+
cet_build_plugin( DigitalNoiseEventFilter art::module SOURCE DigitalNoiseEventFilter_module.cc LIBRARIES
35+
${sbnd_util_lib_list}
36+
sbnobj::Common_Analysis
37+
larevt::CalibrationDBI_Providers
38+
)
39+
3440
cet_build_plugin ( SBNDGeoHelper art::module
3541
larcorealg::Geometry
3642
larcore::Geometry_Geometry_service
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
BEGIN_PROLOG
2+
3+
digital_noise_event_filter: {
4+
5+
module_type: "DigitalNoiseEventFilter"
6+
TPCChannelInfoDataLabel: "daq"
7+
EvenFractionHighCut: 0.6
8+
EvenFractionLowCut: 0.4
9+
EvenFractionNumChannelCut: 10
10+
RMSCut: 1100.0
11+
RMSNumChannelCut: 50
12+
KeepIfNoChannelInfo: true
13+
UseBadChanStatus: true
14+
}
15+
16+
END_PROLOG
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
////////////////////////////////////////////////////////////////////////
2+
// Class: DigitalNoiseEventFilter
3+
// Plugin Type: filter (Unknown Unknown)
4+
// File: DigitalNoiseEventFilter_module.cc
5+
//
6+
// Generated at Tue Oct 7 14:28:27 2025 by Thomas Junk 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+
#include "sbnobj/Common/Analysis/TPCChannelInfo.hh"
20+
#include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h"
21+
#include "larevt/CalibrationDBI/Interface/ChannelStatusService.h"
22+
23+
#include <memory>
24+
25+
class DigitalNoiseEventFilter;
26+
27+
28+
class DigitalNoiseEventFilter : public art::EDFilter {
29+
public:
30+
explicit DigitalNoiseEventFilter(fhicl::ParameterSet const& p);
31+
// The compiler-generated destructor is fine for non-base
32+
// classes without bare pointers or other resource use.
33+
34+
// Plugins should not be copied or assigned.
35+
DigitalNoiseEventFilter(DigitalNoiseEventFilter const&) = delete;
36+
DigitalNoiseEventFilter(DigitalNoiseEventFilter&&) = delete;
37+
DigitalNoiseEventFilter& operator=(DigitalNoiseEventFilter const&) = delete;
38+
DigitalNoiseEventFilter& operator=(DigitalNoiseEventFilter&&) = delete;
39+
40+
// Required functions.
41+
bool filter(art::Event& e) override;
42+
43+
private:
44+
45+
std::string fTag; // input tag for reading TPCChannelInfo data
46+
float fEvenFractionHighCut; // upper cut on the fraction of ADC samples that are even
47+
float fEvenFractionLowCut; // lower cut on the fraction of ADC samples that are even
48+
int fEvenFractionNumChannelCut; // max # of channels with suspect even fractions to keep event. Otherwise suspect CE noise
49+
float fRMSCut; // how noisy a channel has to be before we think it might have CE noise
50+
int fRMSNumChannelCut; // keep event if this many channels or fewer have RMS>fRMSCut. Otherwise suspect CE noise
51+
bool fKeepIfNoChannelInfo; // If we do not find TPCChannelInfo, do we keep or reject the event?
52+
bool fUseBadChanStatus; // true if we skip over bad channels in calculating numbers of suspect CE noise channels
53+
54+
};
55+
56+
57+
DigitalNoiseEventFilter::DigitalNoiseEventFilter(fhicl::ParameterSet const& p)
58+
: EDFilter{p} // ,
59+
// More initializers here.
60+
{
61+
fTag = p.get<std::string>("TPCChannelInfoDataLabel","daq");
62+
fEvenFractionHighCut = p.get<float>("EvenFractionHighCut",0.6);
63+
fEvenFractionLowCut = p.get<float>("EvenFractionLowCut",0.4);
64+
fEvenFractionNumChannelCut = p.get<int>("EvenFractionNumChannelCut",10);
65+
fRMSCut = p.get<float>("RMSCut",1100.0);
66+
fRMSNumChannelCut = p.get<int>("RMSNumChannelCut",50);
67+
fKeepIfNoChannelInfo = p.get<bool>("KeepIfNoChannelInfo",true);
68+
fUseBadChanStatus = p.get<bool>("UseBadChanStatus",true);
69+
70+
consumes<std::vector<anab::TPCChannelInfo>>(fTag);
71+
}
72+
73+
bool DigitalNoiseEventFilter::filter(art::Event& e)
74+
{
75+
lariov::ChannelStatusProvider const& channelStatus(art::ServiceHandle<lariov::ChannelStatusService const>()->GetProvider());
76+
77+
auto channelinfos = e.getHandle<std::vector<anab::TPCChannelInfo>>(fTag);
78+
if (!channelinfos || channelinfos->empty()) return fKeepIfNoChannelInfo;
79+
80+
int neven_suspect = 0;
81+
int nrms_suspect = 0;
82+
double fevdiff = (fEvenFractionHighCut - fEvenFractionLowCut)/2.0;
83+
for (const auto &ci : *channelinfos) {
84+
if (fUseBadChanStatus && channelStatus.IsBad(ci.channel)) continue;
85+
if (ci.even_fraction > fEvenFractionHighCut || ci.even_fraction < fEvenFractionLowCut) ++neven_suspect;
86+
if (ci.rms > fRMSCut) {
87+
++nrms_suspect;
88+
}
89+
else { // try a diagonal cut in case a waveform is noisy and then becomes stuck partway through
90+
if (fRMSCut > 0 && fevdiff > 0) {
91+
if ( (ci.rms/fRMSCut + std::abs(ci.even_fraction - 0.5)/fevdiff) > 1) ++nrms_suspect;
92+
}
93+
}
94+
}
95+
return (neven_suspect <= fEvenFractionNumChannelCut && nrms_suspect <= fRMSNumChannelCut);
96+
}
97+
98+
DEFINE_ART_MODULE(DigitalNoiseEventFilter)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include "DigitalNoiseEventFilter.fcl"
2+
#include "services_sbnd.fcl"
3+
#include "simulationservices_sbnd.fcl"
4+
5+
process_name: DigitalNoiseEventFilter
6+
7+
source:
8+
{
9+
module_type: RootInput
10+
maxEvents: -1 # Number of events to create
11+
}
12+
13+
outputs:
14+
{
15+
out1:
16+
{
17+
module_type: RootOutput
18+
fileName: "digitalnoisefiltered.root"
19+
dataTier: "digitalnoisefiltered"
20+
}
21+
}
22+
23+
services:
24+
{
25+
AuxDetGeometry: @local::sbnd_auxdetgeo
26+
WireReadout: @local::sbnd_wire_readout
27+
GeometryConfigurationWriter: {}
28+
Geometry: @local::sbnd_geo
29+
AuxDetGeometry: @local::sbnd_auxdetgeo
30+
ChannelStatusService: @local::sbnd_channelstatus
31+
}
32+
33+
physics:
34+
{
35+
producers: {}
36+
filters:
37+
{
38+
digitalnoisefilter: @local::digital_noise_event_filter
39+
}
40+
analyzers:{}
41+
42+
reco: [digitalnoisefilter]
43+
stream1: [out1]
44+
trigger_paths: [reco]
45+
end_paths: [stream1]
46+
}
47+
48+
outputs.out1.SelectEvents: [ "reco" ]
49+

0 commit comments

Comments
 (0)