All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ROIFinderStandard_tool.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file ROIFinder.cc
3 /// \author T. Usher
4 ////////////////////////////////////////////////////////////////////////
5 
6 #include <cmath>
8 #include "art/Utilities/ToolMacros.h"
9 #include "art_root_io/TFileService.h"
10 #include "messagefacility/MessageLogger/MessageLogger.h"
11 #include "cetlib_except/exception.h"
14 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
16 
17 #include "TH1D.h"
18 
19 #include <fstream>
20 #include <numeric> // std::accumulate
21 
22 namespace icarus_tool
23 {
24 
26 {
27 public:
28  explicit ROIFinderStandard(const fhicl::ParameterSet& pset);
29 
31 
32  void configure(const fhicl::ParameterSet& pset) override;
33  void initializeHistograms(art::TFileDirectory&) const override;
34  size_t plane() const override {return fPlane;}
35 
36  void FindROIs(const Waveform&, size_t, size_t, double, CandidateROIVec&) const override;
37 
38 private:
39  // Member variables from the fhicl file
40  size_t fPlane;
41  unsigned short fNumBinsHalf; ///< Determines # bins in ROI running sum
42  std::vector<unsigned short> fThreshold; ///< abs(threshold) ADC counts for ROI
43  std::vector<int> fNumSigma; ///< "# sigma" rms noise for ROI threshold
44  std::vector<unsigned short> fPreROIPad; ///< ROI padding
45  std::vector<unsigned short> fPostROIPad; ///< ROI padding
46 
47  // Services
48  const geo::GeometryCore* fGeometry = lar::providerFrom<geo::Geometry>();
49  art::ServiceHandle<icarusutil::SignalShapingICARUSService> fSignalShaping;
50 };
51 
52 //----------------------------------------------------------------------
53 // Constructor.
54 ROIFinderStandard::ROIFinderStandard(const fhicl::ParameterSet& pset)
55 {
56  configure(pset);
57 }
58 
60 {
61 }
62 
63 void ROIFinderStandard::configure(const fhicl::ParameterSet& pset)
64 {
65  // Start by recovering the parameters
66  std::vector<unsigned short> uin;
67  std::vector<unsigned short> vin;
68  std::vector<unsigned short> zin;
69 
70  fNumBinsHalf = pset.get< unsigned short > ("NumBinsHalf", 3);
71  fThreshold = pset.get< std::vector<unsigned short> >("Threshold" );
72  fNumSigma = pset.get< std::vector<int> > ("NumSigma" );
73  uin = pset.get< std::vector<unsigned short> >("uPlaneROIPad" );
74  vin = pset.get< std::vector<unsigned short> >("vPlaneROIPad" );
75  zin = pset.get< std::vector<unsigned short> >("zPlaneROIPad" );
76 
77  if(uin.size() != 2 || vin.size() != 2 || zin.size() != 2) {
78  throw art::Exception(art::errors::Configuration)
79  << "u/v/z plane ROI pad size != 2";
80  }
81 
82  fPreROIPad.resize(3);
83  fPostROIPad.resize(3);
84 
85  // put the ROI pad sizes into more convenient vectors
86  fPreROIPad[0] = uin[0];
87  fPostROIPad[0] = uin[1];
88  fPreROIPad[1] = vin[0];
89  fPostROIPad[1] = vin[1];
90  fPreROIPad[2] = zin[0];
91  fPostROIPad[2] = zin[1];
92 
93  fSignalShaping = art::ServiceHandle<icarusutil::SignalShapingICARUSService>();
94 
95  return;
96 }
97 
98 void ROIFinderStandard::FindROIs(const Waveform& waveform, size_t channel, size_t cnt, double rmsNoise, CandidateROIVec& roiVec) const
99 {
100  // First up, translate the channel to plane
101  std::vector<geo::WireID> wids = fGeometry->ChannelToWire(channel);
102  const geo::PlaneID& planeID = wids[0].planeID();
103 
104  size_t numBins(2 * fNumBinsHalf + 1);
105  size_t startBin(0);
106  size_t stopBin(numBins);
107  float elecNoise = fSignalShaping->GetRawNoise(channel);
108  float rawNoise = std::max(rmsNoise, double(elecNoise));
109 
110  float startThreshold = sqrt(float(numBins)) * (fNumSigma[planeID.Plane] * rawNoise + fThreshold[planeID.Plane]);
111  float stopThreshold = startThreshold;
112 
113  // Setup
114  float runningSum = std::accumulate(waveform.begin(),waveform.begin()+numBins, 0.);
115 
116  size_t roiStartBin(0);
117  bool roiCandStart(false);
118 
119  // search for ROIs - follow prescription from Bruce B using a running sum to make faster
120  // Note that we start in the middle of the running sum... if we find an ROI padding will extend
121  // past this to take care of ends of the waveform
122  for(size_t bin = fNumBinsHalf + 1; bin < waveform.size() - fNumBinsHalf; bin++)
123  {
124  // handle the running sum
125  // Case, we are at start of waveform
126  runningSum -= waveform[startBin++];
127 
128  // Case, we are at end of waveform
129  runningSum += waveform[stopBin++];
130 
131  // We have already started a candidate ROI
132  if (roiCandStart)
133  {
134  if (fabs(runningSum) < stopThreshold)
135  {
136  if (bin - roiStartBin > 2) roiVec.push_back(CandidateROI(roiStartBin, bin));
137 
138  roiCandStart = false;
139  }
140  }
141  // Not yet started a candidate ROI
142  else
143  {
144  if (fabs(runningSum) > startThreshold)
145  {
146  roiStartBin = bin;
147  roiCandStart = true;
148  }
149  }
150  } // bin
151 
152  // add the last ROI if existed
153  if (roiCandStart) roiVec.push_back(CandidateROI(roiStartBin, waveform.size() - 1));
154 
155  // pad the ROIs
156  for(auto& roi : roiVec)
157  {
158  // low ROI end
159  roi.first = std::max(int(roi.first - fPreROIPad[planeID.Plane]),0);
160  // high ROI end
161  roi.second = std::min(roi.second + fPostROIPad[planeID.Plane], waveform.size() - 1);
162  }
163 
164  // merge overlapping (or touching) ROI's
165  if(roiVec.size() > 1)
166  {
167  // temporary vector for merged ROIs
168  CandidateROIVec tempRoiVec;
169 
170  // Loop through candidate roi's
171  size_t startRoi = roiVec.front().first;
172  size_t stopRoi = startRoi;
173 
174  for(auto& roi : roiVec)
175  {
176  if (roi.first <= stopRoi) stopRoi = roi.second;
177  else
178  {
179  tempRoiVec.push_back(CandidateROI(startRoi,stopRoi));
180 
181  startRoi = roi.first;
182  stopRoi = roi.second;
183  }
184  }
185 
186  // Make sure to get the last one
187  tempRoiVec.push_back(CandidateROI(startRoi,stopRoi));
188 
189  roiVec = tempRoiVec;
190  }
191 
192  return;
193 }
194 
195 void ROIFinderStandard::initializeHistograms(art::TFileDirectory& histDir) const
196 {
197  // It is assumed that the input TFileDirectory has been set up to group histograms into a common
198  // folder at the calling routine's level. Here we create one more level of indirection to keep
199  // histograms made by this tool separate.
200 /*
201  std::string dirName = "ROIFinderPlane_" + std::to_string(fPlane);
202 
203  art::TFileDirectory dir = histDir.mkdir(dirName.c_str());
204 
205  auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
206  double samplingRate = detprop->SamplingRate();
207  double numBins = fROIFinderVec.size();
208  double maxFreq = 500. / samplingRate;
209  std::string histName = "ROIFinderPlane_" + std::to_string(fPlane);
210 
211  TH1D* hist = dir.make<TH1D>(histName.c_str(), "ROIFinder;Frequency(MHz)", numBins, 0., maxFreq);
212 
213  for(int bin = 0; bin < numBins; bin++)
214  {
215  double freq = maxFreq * double(bin + 0.5) / double(numBins);
216 
217  hist->Fill(freq, fROIFinderVec.at(bin).Re());
218  }
219 */
220 
221  return;
222 }
223 
224 DEFINE_ART_CLASS_TOOL(ROIFinderStandard)
225 }
std::vector< int > fNumSigma
&quot;# sigma&quot; rms noise for ROI threshold
void FindROIs(const Waveform &, size_t, size_t, double, CandidateROIVec &) const override
Utilities related to art service access.
std::vector< unsigned short > fPostROIPad
ROI padding.
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
void initializeHistograms(art::TFileDirectory &) const override
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
ROIFinderStandard(const fhicl::ParameterSet &pset)
void configure(const fhicl::ParameterSet &pset) override
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
std::vector< unsigned short > fPreROIPad
ROI padding.
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
Description of geometry of one entire detector.
unsigned short fNumBinsHalf
Determines # bins in ROI running sum.
art::ServiceHandle< icarusutil::SignalShapingICARUSService > fSignalShaping
const geo::GeometryCore * fGeometry
std::vector< unsigned short > fThreshold
abs(threshold) ADC counts for ROI
art framework interface to geometry description