All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
icarus_tool::ROIFinderMorphological Class Reference
Inheritance diagram for icarus_tool::ROIFinderMorphological:
icarus_tool::IROIFinder

Public Member Functions

 ROIFinderMorphological (const fhicl::ParameterSet &pset)
 
 ~ROIFinderMorphological ()
 
void configure (const fhicl::ParameterSet &pset) override
 
void initializeHistograms (art::TFileDirectory &) const override
 
size_t plane () const override
 
void FindROIs (const Waveform &, size_t, size_t, double, CandidateROIVec &) const override
 
- Public Member Functions inherited from icarus_tool::IROIFinder
virtual ~IROIFinder () noexcept=default
 

Private Types

enum  HistogramType : int { ROIHISTOGRAM = icarus_tool::LASTELEMENT + 1, TRUNCMEANHIST, TRUNCRMSHIST, WAVEFORMHIST }
 

Private Member Functions

void findROICandidatesDifference (const Waveform &, const Waveform &, const Waveform &, int, int, float, CandidateROIVec &) const
 
void findROICandidatesDilation (const Waveform &, const Waveform &, const Waveform &, int, int, float, CandidateROIVec &) const
 
void smoothInputWaveform (const Waveform &, Waveform &) const
 
icarus_tool::HistogramMap initializeHistograms (size_t, size_t, size_t) const
 

Private Attributes

size_t fPlane
 Tool can be plane dependent. More...
 
bool fUseDifference
 If true use differences, else dilation. More...
 
float fNumSigma
 "# sigma" rms noise for ROI threshold More...
 
int fNumBinsToAve
 Controls the smoothing. More...
 
int fMax2MinDistance
 Minimum allow peak to peak distance. More...
 
float fMax2MinHeight
 Minimum peak to peak height (box cut) More...
 
int fMaxLengthCut
 Minimum length of the maximum. More...
 
int fStructuringElement
 The window size. More...
 
unsigned short fPreROIPad
 ROI padding. More...
 
unsigned short fPostROIPad
 ROI padding. More...
 
unsigned short fMaxPadLen
 Don't let padding be larger than this. More...
 
bool fOutputHistograms
 Output histograms? More...
 
bool fOutputWaveforms
 Output waveforms? More...
 
std::vector< float > fAveWeightVec
 Weight vector for smoothing. More...
 
float fWeightSum
 sum of weights for smoothing More...
 
art::TFileDirectory * fHistDirectory
 
TH1F * fDiffMeanHist
 
TH1F * fDiffRmsHist
 
TH1F * fDiffFullRmsHist
 
TH1F * fDTruncBinsHist
 
TH1F * fDiffMaxHist
 
TH1F * fNumSigmaHist
 
TH1F * fThresholdHist
 
TH1F * fNumSigNextHist
 
TH1F * fMaxDiffLength
 
TH1F * fDeltaTicksHist
 
TH2F * fDTixVDLenHist
 
TH2F * fDTixVDiffHist
 
TH2F * fDiffVDilHist
 
icarus_signal_processing::WaveformTools
< float > 
fWaveformTool
 
const geo::GeometryCorefGeometry = lar::providerFrom<geo::Geometry>()
 

Additional Inherited Members

- Public Types inherited from icarus_tool::IROIFinder
using Waveform = std::vector< float >
 
using CandidateROI = std::pair< size_t, size_t >
 
using CandidateROIVec = std::vector< CandidateROI >
 

Detailed Description

Definition at line 27 of file ROIFinderMorphological_tool.cc.

Member Enumeration Documentation

Constructor & Destructor Documentation

icarus_tool::ROIFinderMorphological::ROIFinderMorphological ( const fhicl::ParameterSet &  pset)
explicit

Definition at line 116 of file ROIFinderMorphological_tool.cc.

117 {
118  configure(pset);
119 }
void configure(const fhicl::ParameterSet &pset) override
icarus_tool::ROIFinderMorphological::~ROIFinderMorphological ( )

Definition at line 121 of file ROIFinderMorphological_tool.cc.

122 {
123 }

Member Function Documentation

void icarus_tool::ROIFinderMorphological::configure ( const fhicl::ParameterSet &  pset)
overridevirtual

Implements icarus_tool::IROIFinder.

Definition at line 125 of file ROIFinderMorphological_tool.cc.

126 {
127  // Start by recovering the parameters
128  std::vector<unsigned short> zin;
129 
130  fPlane = pset.get< size_t >("Plane" );
131  fUseDifference = pset.get< bool >("UseDifference", true);
132  fNumSigma = pset.get< float >("NumSigma" );
133  fNumBinsToAve = pset.get< int >("NumBinsToAve" );
134  fMax2MinDistance = pset.get< int >("Max2MinDistance" );
135  fMax2MinHeight = pset.get< int >("Max2MinHeight" );
136  fMaxLengthCut = pset.get< int >("MaxLengthCut" );
137  fStructuringElement = pset.get< int >("StructuringElement" );
138  zin = pset.get< std::vector<unsigned short>>("roiLeadTrailPad" );
139  fMaxPadLen = pset.get< unsigned short >("MaxPadLen", 200);
140  fOutputHistograms = pset.get< bool >("OutputHistograms", false);
141  fOutputWaveforms = pset.get< bool >("OutputWaveforms", false);
142 
143  if(zin.size() != 2) {
144  throw art::Exception(art::errors::Configuration)
145  << "Plane ROI pad size != 2";
146  }
147 
148  // put the ROI pad sizes into more variables
149  fPreROIPad = zin[0];
150  fPostROIPad = zin[1];
151 
152  // If asked, define the global histograms
153  if (fOutputHistograms)
154  {
155  // Access ART's TFileService, which will handle creating and writing
156  // histograms and n-tuples for us.
157  art::ServiceHandle<art::TFileService> tfs;
158 
159  fHistDirectory = tfs.get();
160 
161  // Make a directory for these histograms
162  art::TFileDirectory dir = fHistDirectory->mkdir(Form("ROIPlane_%1zu",fPlane));
163 
164  fDiffMeanHist = dir.make<TH1F>("DiffMean", ";Diff Mean;", 100, -20., 20.);
165  fDiffRmsHist = dir.make<TH1F>("DiffRms", ";Diff RMS;", 200, 0., 10.);
166  fDiffFullRmsHist = dir.make<TH1F>("DiffFRms", ";Diff RMS;", 200, 0., 10.);
167  fDTruncBinsHist = dir.make<TH1F>("DTruncBn", "D trunc B", 500, 0., 1000.);
168  fDiffMaxHist = dir.make<TH1F>("DiffMax", ";Diff Max;", 200, 0., 200.);
169  fNumSigmaHist = dir.make<TH1F>("NSigma", ";#sigma;", 200, 0., 40.);
170  fThresholdHist = dir.make<TH1F>("Threshold", ";Threshold;", 200, 0., 40.);
171  fNumSigNextHist = dir.make<TH1F>("NSigNext", ";#sigma;", 200, 0., 50.);
172  fMaxDiffLength = dir.make<TH1F>("MaxLength", ";Delta t", 200, 0., 200.);
173  fDeltaTicksHist = dir.make<TH1F>("DeltaTix", ";Delta t", 200, 0., 200.);
174 
175  fDTixVDLenHist = dir.make<TH2F>("DTixVDLen", ";Delta t;DLength", 100, 0., 100., 100, 0., 100.);
176  fDTixVDiffHist = dir.make<TH2F>("DTixVDiff", ";Delta t;Max Diff", 100, 0., 100., 100, 0., 100.);
177  fDiffVDilHist = dir.make<TH2F>("DiffVDil", ";Max Diff;Max Dilation", 100, 0., 200., 100, 0., 200.);
178  }
179 
180  // precalculate the weight vector to use in the smoothing
182 
183  if (fNumBinsToAve > 1)
184  {
185  for(int idx = 0; idx < fNumBinsToAve/2; idx++)
186  {
187  float weight = idx + 1;
188 
189  fAveWeightVec.at(idx) = weight;
190  fAveWeightVec.at(fNumBinsToAve - idx - 1) = weight;
191  }
192 
193  // Watch for case of fNumBinsToAve being odd
194  if (fNumBinsToAve % 2 > 0) fAveWeightVec.at(fNumBinsToAve/2) = fNumBinsToAve/2 + 1;
195  }
196  else fAveWeightVec.at(0) = 1.;
197 
198  fWeightSum = std::accumulate(fAveWeightVec.begin(),fAveWeightVec.end(), 0.);
199 
200  return;
201 }
float fMax2MinHeight
Minimum peak to peak height (box cut)
int fMaxLengthCut
Minimum length of the maximum.
float fWeightSum
sum of weights for smoothing
unsigned short fMaxPadLen
Don&#39;t let padding be larger than this.
int fMax2MinDistance
Minimum allow peak to peak distance.
tuple dir
Definition: dropbox.py:28
float fNumSigma
&quot;# sigma&quot; rms noise for ROI threshold
bool fUseDifference
If true use differences, else dilation.
std::vector< float > fAveWeightVec
Weight vector for smoothing.
art::ServiceHandle< art::TFileService > tfs
size_t fPlane
Tool can be plane dependent.
void icarus_tool::ROIFinderMorphological::findROICandidatesDifference ( const Waveform differenceVec,
const Waveform erosionVec,
const Waveform dilationVec,
int  startTick,
int  stopTick,
float  threshold,
CandidateROIVec roiCandidateVec 
) const
private

Definition at line 397 of file ROIFinderMorphological_tool.cc.

404 {
405  int roiLength = stopTick - startTick;
406 
407  if (roiLength > 0)
408  {
409  // The idea here is to find the difference and use that as the seed for searching the
410  // erosion and dilation vectors for the end points
411  Waveform::const_iterator maxItr = std::max_element(differenceVec.begin()+startTick,differenceVec.begin()+stopTick);
412 
413  int maxTick = std::distance(differenceVec.begin(),maxItr);
414  float maxDifference = *maxItr;
415 
416  // Accomodate a special case of slowly rising waveforms where the difference will be under threshold but we
417  // do have a definite region of interest
418  float dilationVal = dilationVec[maxTick];
419 
420  // No point continuing if not over threshold
421  if (maxDifference > threshold || dilationVal > threshold)
422  {
423  // move forward to find the length of the top
424  while(*maxItr == maxDifference) maxItr++;
425 
426  int deltaTicks = std::distance(differenceVec.begin(),maxItr) - maxTick;
427 
428  // Start by finding maximum range of the erosion vector at this extremum
429  int maxCandRoiTick = maxTick;
430 
431  // The test on the erosion vector takes care of special case of slowly rising pulses which are characteristic of
432  // tracks running into the wire plane
433  while(++maxCandRoiTick < stopTick)
434  {
435  float difference = differenceVec.at(maxCandRoiTick);
436  float erosion = erosionVec.at(maxCandRoiTick);
437 
438  if (difference < threshold && erosion < 0.5 * threshold) break;
439  }
440 
441  maxCandRoiTick = std::min(maxCandRoiTick,stopTick);
442 
443  // Now do the dilation vector
444  int minCandRoiTick = maxTick;
445 
446  while(--minCandRoiTick >= startTick)
447  {
448  float difference = differenceVec.at(minCandRoiTick);
449  float erosion = erosionVec.at(minCandRoiTick);
450 
451  if (difference < threshold && erosion < 0.5 * threshold) break;
452  }
453 
454  // make sure we have not gone under
455  minCandRoiTick = std::max(minCandRoiTick, startTick);
456 
457  int max2MinDiff = maxCandRoiTick - minCandRoiTick;
458 
459  if (fOutputHistograms && !(startTick > 0 || stopTick < int(differenceVec.size())))
460  {
461  float maxDilation = *std::max_element(dilationVec.begin() + minCandRoiTick, dilationVec.begin() + maxCandRoiTick);
462 
463  fMaxDiffLength->Fill(std::min(deltaTicks,199), 1.);
464  fDeltaTicksHist->Fill(max2MinDiff, 1.);
465  fDTixVDLenHist->Fill(max2MinDiff, deltaTicks, 1.);
466  fDTixVDiffHist->Fill(max2MinDiff, maxDifference, 1.);
467  fDiffVDilHist->Fill(maxDifference, maxDilation, 1.);
468  }
469 
470  // Make sure we have a legitimate candidate
471  if ((max2MinDiff > fMax2MinDistance || maxDifference > fMax2MinHeight) && deltaTicks > fMaxLengthCut)
472  {
473  // Before saving this ROI, look for candidates preceeding this one
474  // Note that preceeding snippet will reference to the current roiStartTick
475  findROICandidatesDifference(differenceVec, erosionVec, dilationVec, startTick, minCandRoiTick, threshold, roiCandidateVec);
476 
477  // Save this ROI
478  roiCandidateVec.push_back(CandidateROI(minCandRoiTick, maxCandRoiTick));
479 
480  // Now look for candidate ROI's downstream of this one
481  findROICandidatesDifference(differenceVec, erosionVec, dilationVec, maxCandRoiTick+1, stopTick, threshold, roiCandidateVec);
482  }
483  }
484  }
485 
486  return;
487 }
float fMax2MinHeight
Minimum peak to peak height (box cut)
int fMaxLengthCut
Minimum length of the maximum.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
int fMax2MinDistance
Minimum allow peak to peak distance.
void findROICandidatesDifference(const Waveform &, const Waveform &, const Waveform &, int, int, float, CandidateROIVec &) const
void icarus_tool::ROIFinderMorphological::findROICandidatesDilation ( const Waveform differenceVec,
const Waveform erosionVec,
const Waveform dilationVec,
int  startTick,
int  stopTick,
float  threshold,
CandidateROIVec roiCandidateVec 
) const
private

Definition at line 490 of file ROIFinderMorphological_tool.cc.

497 {
498  int roiLength = stopTick - startTick;
499 
500  if (roiLength > 0)
501  {
502  // The idea here is to find the difference and use that as the seed for searching the
503  // erosion and dilation vectors for the end points
504  //Waveform::const_iterator maxItr = std::max_element(differenceVec.begin()+startTick,differenceVec.begin()+stopTick,[](const auto& left, const auto& right){return std::fabs(left) < std::fabs(right);});
505  Waveform::const_iterator maxItr = std::max_element(dilationVec.begin()+startTick,dilationVec.begin()+stopTick);
506 
507  int maxTick = std::distance(dilationVec.begin(),maxItr);
508  float maxDilation = *maxItr;
509 
510  // move forward to find the length of the top
511  while(*maxItr == maxDilation) maxItr++;
512 
513  int deltaTicks = std::distance(dilationVec.begin(),maxItr) - maxTick;
514 
515  // No point continuing if not over threshold
516  if (maxDilation > threshold)
517  {
518  // Start by finding maximum range of the erosion vector at this extremum
519  int maxCandRoiTick = std::distance(dilationVec.begin(),maxItr);
520 
521  // The test on the erosion vector takes care of special case of slowly rising pulses which are characteristic of
522  // tracks running into the wire plane
523  while(++maxCandRoiTick < stopTick)
524  {
525  float dilation = dilationVec.at(maxCandRoiTick);
526  float erosion = erosionVec.at(maxCandRoiTick);
527 
528  if (dilation < threshold && erosion < 0.5 * threshold) break;
529  }
530 
531  maxCandRoiTick = std::min(maxCandRoiTick,stopTick);
532 
533  // Now do the dilation vector
534  int minCandRoiTick = maxTick;
535 
536  while(--minCandRoiTick >= startTick)
537  {
538  float dilation = dilationVec.at(minCandRoiTick);
539  float erosion = erosionVec.at(minCandRoiTick);
540 
541  if (dilation < threshold && erosion < 0.5 * threshold) break;
542  }
543 
544  // make sure we have not gone under
545  minCandRoiTick = std::max(minCandRoiTick, startTick);
546 
547  int max2MinDiff = maxCandRoiTick - minCandRoiTick;
548 
549  if (fOutputHistograms && !(startTick > 0 || stopTick < int(dilationVec.size())))
550  {
551  float maxDifference = *std::max_element(differenceVec.begin() + minCandRoiTick, differenceVec.begin() + maxCandRoiTick);
552 
553  fMaxDiffLength->Fill(std::min(deltaTicks,199), 1.);
554  fDeltaTicksHist->Fill(max2MinDiff, 1.);
555  fDTixVDLenHist->Fill(max2MinDiff, deltaTicks, 1.);
556  fDTixVDiffHist->Fill(max2MinDiff, maxDilation, 1.);
557  fDiffVDilHist->Fill(maxDifference, maxDilation, 1.);
558  }
559 
560  // Make sure we have a legitimate candidate
561  if ((max2MinDiff > fMax2MinDistance || maxDilation > fMax2MinHeight) && deltaTicks > fMaxLengthCut)
562  {
563  // Before saving this ROI, look for candidates preceeding this one
564  // Note that preceeding snippet will reference to the current roiStartTick
565  findROICandidatesDilation(differenceVec, erosionVec, dilationVec, startTick, minCandRoiTick, threshold, roiCandidateVec);
566 
567  // Save this ROI
568  roiCandidateVec.push_back(CandidateROI(minCandRoiTick, maxCandRoiTick));
569 
570  // Now look for candidate ROI's downstream of this one
571  findROICandidatesDilation(differenceVec, erosionVec, dilationVec, maxCandRoiTick+1, stopTick, threshold, roiCandidateVec);
572  }
573  }
574  }
575 
576  return;
577 }
float fMax2MinHeight
Minimum peak to peak height (box cut)
int fMaxLengthCut
Minimum length of the maximum.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
int fMax2MinDistance
Minimum allow peak to peak distance.
void findROICandidatesDilation(const Waveform &, const Waveform &, const Waveform &, int, int, float, CandidateROIVec &) const
void icarus_tool::ROIFinderMorphological::FindROIs ( const Waveform waveform,
size_t  channel,
size_t  cnt,
double  rmsNoise,
CandidateROIVec roiVec 
) const
overridevirtual

Implements icarus_tool::IROIFinder.

Definition at line 203 of file ROIFinderMorphological_tool.cc.

204 {
205  // The idea here is to consider the input waveform - if an induction plane then it is already in differential form,
206  // if a collection plane then we form the differential - then smooth and look for ROIs. The technique for actually
207  // finding ROI's will be to compute the erosion and dilation vectors, get their average/difference and then use these to determine
208  // candidate ROI's
209 
210  // Smooth the input waveform
211  Waveform smoothWaveform;
212 
213  smoothInputWaveform(waveform, smoothWaveform);
214 
215  // We make lots of vectors... erosion, dilation, average and difference
216  Waveform erosionVec;
217  Waveform dilationVec;
218  Waveform averageVec;
219  Waveform differenceVec;
220 
221  // Compute the morphological filter vectors
222  fWaveformTool.getErosionDilationAverageDifference(smoothWaveform, fStructuringElement, erosionVec, dilationVec, averageVec, differenceVec);
223 
224  // Use the average vector to find ROI's
225  float fullRMS;
226  float truncRMS;
227  float truncMean;
228  float nSig(2.5);
229  int nTrunc;
230  int range;
231 
232  if (fUseDifference)
233  {
234  Waveform zeroSuppressed(differenceVec.size());
235 
236  fWaveformTool.getTruncatedMean(differenceVec, truncMean, nTrunc, range);
237 
238  std::transform(differenceVec.begin(),differenceVec.end(),zeroSuppressed.begin(),[truncMean](auto& val){return val - truncMean;});
239 
240  fWaveformTool.getTruncatedRMS(zeroSuppressed, nSig, fullRMS, truncRMS, nTrunc);
241  }
242  else
243  {
244  Waveform zeroSuppressed(dilationVec.size());
245 
246  fWaveformTool.getTruncatedMean(dilationVec, truncMean, nTrunc, range);
247 
248  std::transform(dilationVec.begin(),dilationVec.end(),zeroSuppressed.begin(),[truncMean](auto& val){return val - truncMean;});
249 
250  fWaveformTool.getTruncatedRMS(zeroSuppressed, nSig, fullRMS, truncRMS, nTrunc);
251  }
252 
253  // Calculate a threshold to use based on the truncated mand and rms...
254  float threshold = truncMean + fNumSigma * std::max(float(0.02),truncRMS);
255 
256  // Define the histogram map which will be referenced later
257  icarus_tool::HistogramMap histogramMap;
258 
259  if (fOutputWaveforms)
260  {
261  // Define histograms for this particular channel?
262  histogramMap = initializeHistograms(channel, cnt, waveform.size());
263 
264  for(size_t curBin = 0; curBin < waveform.size(); curBin++)
265  {
266  histogramMap.at(WAVEFORMHIST)->Fill( curBin, waveform[curBin], 1.);
267  histogramMap.at(WAVEFORM)->Fill( curBin, smoothWaveform[curBin], 1.);
268  histogramMap.at(EROSION)->Fill( curBin, erosionVec[curBin], 1.);
269  histogramMap.at(DILATION)->Fill( curBin, dilationVec[curBin], 1.);
270  histogramMap.at(AVERAGE)->Fill( curBin, averageVec[curBin], 1.);
271  histogramMap.at(DIFFERENCE)->Fill( curBin, differenceVec[curBin], 1.);
272  histogramMap.at(TRUNCMEANHIST)->Fill(curBin, truncMean, 1.);
273  histogramMap.at(TRUNCRMSHIST)->Fill( curBin, threshold, 1.);
274  }
275  }
276 
277  // If histogramming, do the global hists here
278  if (fOutputHistograms)
279  {
280  Waveform::iterator maxItr;
281 
282  if (fUseDifference) maxItr = std::max_element(differenceVec.begin(),differenceVec.end());
283  else maxItr = std::max_element(dilationVec.begin(),dilationVec.end());
284 
285  float maxDiff = *maxItr;
286  float nSigma = (maxDiff - truncMean) / std::max(float(0.5),truncRMS);
287  int dTruncBins = int(differenceVec.size()) - nTrunc;
288 
289  fDiffMeanHist->Fill(truncMean, 1.);
290  fDiffRmsHist->Fill(truncRMS, 1.);
291  fDiffFullRmsHist->Fill(fullRMS, 1.);
292  fDTruncBinsHist->Fill(std::min(dTruncBins,999), 1.);
293  fDiffMaxHist->Fill(maxDiff, 1.);
294  fNumSigmaHist->Fill(std::min(nSigma,float(39.9)), 1.);
295  fThresholdHist->Fill(std::min(threshold,float(39.9)), 1.);
296 
297  if (fUseDifference)
298  {
299  if (std::distance(differenceVec.begin(),maxItr) > 4 * fStructuringElement)
300  {
301  maxDiff = *std::max_element(differenceVec.begin(),maxItr-4*fStructuringElement);
302  nSigma = (maxDiff - truncMean) / std::max(float(0.5),truncRMS);
303 
304  fNumSigNextHist->Fill(nSigma, 1.);
305  }
306 
307  if (std::distance(maxItr, differenceVec.end()) > 4 * fStructuringElement)
308  {
309  maxDiff = *std::max_element(maxItr+4*fStructuringElement,differenceVec.end());
310  nSigma = (maxDiff - truncMean) / std::max(float(0.5),truncRMS);
311 
312  fNumSigNextHist->Fill(nSigma, 1.);
313  }
314  }
315  else
316  {
317  if (std::distance(dilationVec.begin(),maxItr) > 4 * fStructuringElement)
318  {
319  maxDiff = *std::max_element(dilationVec.begin(),maxItr-4*fStructuringElement);
320  nSigma = (maxDiff - truncMean) / std::max(float(0.5),truncRMS);
321 
322  fNumSigNextHist->Fill(nSigma, 1.);
323  }
324 
325  if (std::distance(maxItr, dilationVec.end()) > 4 * fStructuringElement)
326  {
327  maxDiff = *std::max_element(maxItr+4*fStructuringElement,dilationVec.end());
328  nSigma = (maxDiff - truncMean) / std::max(float(0.5),truncRMS);
329 
330  fNumSigNextHist->Fill(nSigma, 1.);
331  }
332  }
333  }
334 
335  if (fUseDifference) findROICandidatesDifference(differenceVec, erosionVec, dilationVec, 0, averageVec.size(), threshold, roiVec);
336  else findROICandidatesDilation( differenceVec, erosionVec, dilationVec, 0, averageVec.size(), threshold, roiVec);
337 
338  if (roiVec.empty()) return;
339 
340  // pad the ROIs
341  for(auto& roi : roiVec)
342  {
343  if (!histogramMap.empty())
344  {
345  histogramMap.at(ROIHISTOGRAM)->Fill(int(roi.first), std::max(5.*truncRMS,1.));
346  histogramMap.at(ROIHISTOGRAM)->Fill(int(roi.second), std::max(5.*truncRMS,1.));
347  }
348 
349  // For longer than normal pulse trains we could use a bit extra padding
350  unsigned short halfROILen = (roi.second - roi.first) / 2;
351  unsigned short preROIPad = std::min(std::max(fPreROIPad,halfROILen),fMaxPadLen);
352  unsigned short postROIPad = std::min(std::max(fPostROIPad,halfROILen),fMaxPadLen);
353 
354  // low ROI end
355  roi.first = std::max(int(roi.first - preROIPad),0);
356  // high ROI end
357  roi.second = std::min(roi.second + postROIPad, waveform.size() - 1);
358  }
359 
360  // merge overlapping (or touching) ROI's
361  if(roiVec.size() > 1)
362  {
363  // temporary vector for merged ROIs
364  CandidateROIVec tempRoiVec;
365 
366  // Loop through candidate roi's
367  size_t startRoi = roiVec.front().first;
368  size_t stopRoi = startRoi;
369 
370  for(auto& roi : roiVec)
371  {
372  // Should we merge roi's?
373  if (roi.first <= stopRoi + 50)
374  {
375  // Make sure the merge gets the right start/end times
376  startRoi = std::min(startRoi,roi.first);
377  stopRoi = std::max(stopRoi,roi.second);
378  }
379  else
380  {
381  tempRoiVec.push_back(CandidateROI(startRoi,stopRoi));
382 
383  startRoi = roi.first;
384  stopRoi = roi.second;
385  }
386  }
387 
388  // Make sure to get the last one
389  tempRoiVec.push_back(CandidateROI(startRoi,stopRoi));
390 
391  roiVec = tempRoiVec;
392  }
393 
394  return;
395 }
static constexpr Sample_t transform(Sample_t sample)
void initializeHistograms(art::TFileDirectory &) const override
unsigned short fMaxPadLen
Don&#39;t let padding be larger than this.
icarus_signal_processing::WaveformTools< float > fWaveformTool
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
float fNumSigma
&quot;# sigma&quot; rms noise for ROI threshold
void findROICandidatesDifference(const Waveform &, const Waveform &, const Waveform &, int, int, float, CandidateROIVec &) const
void smoothInputWaveform(const Waveform &, Waveform &) const
void findROICandidatesDilation(const Waveform &, const Waveform &, const Waveform &, int, int, float, CandidateROIVec &) const
bool fUseDifference
If true use differences, else dilation.
void icarus_tool::ROIFinderMorphological::initializeHistograms ( art::TFileDirectory &  histDir) const
overridevirtual

Implements icarus_tool::IROIFinder.

Definition at line 615 of file ROIFinderMorphological_tool.cc.

616 {
617  // It is assumed that the input TFileDirectory has been set up to group histograms into a common
618  // folder at the calling routine's level. Here we create one more level of indirection to keep
619  // histograms made by this tool separate.
620 /*
621  std::string dirName = "ROIFinderPlane_" + std::to_string(fPlane);
622 
623  art::TFileDirectory dir = histDir.mkdir(dirName.c_str());
624 
625  auto const* detprop = lar::providerFrom<detinfo::DetectorPropertiesService>();
626  double samplingRate = detprop->SamplingRate();
627  double numBins = fROIFinderVec.size();
628  double maxFreq = 500. / samplingRate;
629  std::string histName = "ROIFinderPlane_" + std::to_string(fPlane);
630 
631  TH1D* hist = dir.make<TH1D>(histName.c_str(), "ROIFinder;Frequency(MHz)", numBins, 0., maxFreq);
632 
633  for(int bin = 0; bin < numBins; bin++)
634  {
635  double freq = maxFreq * double(bin + 0.5) / double(numBins);
636 
637  hist->Fill(freq, fROIFinderVec.at(bin).Re());
638  }
639 */
640 
641  return;
642 }
icarus_tool::HistogramMap icarus_tool::ROIFinderMorphological::initializeHistograms ( size_t  channel,
size_t  cnt,
size_t  waveformSize 
) const
private

Definition at line 644 of file ROIFinderMorphological_tool.cc.

645 {
646  icarus_tool::HistogramMap histogramMap;
647 
648  if (fOutputWaveforms)
649  {
650  // Try to limit to the wire number (since we are already segregated by plane)
651  std::vector<geo::WireID> wids = fGeometry->ChannelToWire(channel);
652  size_t cryo = wids[0].Cryostat;
653  size_t tpc = wids[0].TPC;
654 // size_t plane = wids[0].Plane;
655  size_t wire = wids[0].Wire;
656 
657  // Make a directory for these histograms
658  art::TFileDirectory dir = fHistDirectory->mkdir(Form("Event_%03zu/C%1zuT%1zuP%1zu/Wire_%05zu",cnt,cryo,tpc,fPlane,wire));
659 
660  // We keep track of four histograms:
661  try
662  {
663  histogramMap[icarus_tool::WAVEFORM] =
664  dir.make<TProfile>("SmoothWaveform", "Waveform", waveformSize, 0, waveformSize, -500., 500.);
665  histogramMap[icarus_tool::EROSION] =
666  dir.make<TProfile>("Erosion", "Erosion", waveformSize, 0, waveformSize, -500., 500.);
667  histogramMap[icarus_tool::DILATION] =
668  dir.make<TProfile>("Dilation", "Dilation", waveformSize, 0, waveformSize, -500., 500.);
669  histogramMap[icarus_tool::AVERAGE] =
670  dir.make<TProfile>("Average", "Average", waveformSize, 0, waveformSize, -500., 500.);
671  histogramMap[icarus_tool::DIFFERENCE] =
672  dir.make<TProfile>("Difference", "Difference", waveformSize, 0, waveformSize, -500., 500.);
673 
674  // This is a kludge so that the ROI histogram ends up in the same diretory as the waveforms
675  histogramMap[ROIHISTOGRAM] =
676  dir.make<TProfile>("ROI", "ROI", waveformSize, 0, waveformSize, -500., 500.);
677 
678  // Keep kludging so we can see the truncated mean and threshold that gets applied
679  histogramMap[TRUNCMEANHIST] =
680  dir.make<TProfile>("TruncatedMean", "Truncated Mean", waveformSize, 0, waveformSize, -500., 500.);
681  histogramMap[TRUNCRMSHIST] =
682  dir.make<TProfile>("TruncatedRMS", "Truncated rms", waveformSize, 0, waveformSize, -500., 500.);
683 
684  // Also, if smoothing then we would like to keep track of the original waveform too
685  histogramMap[WAVEFORMHIST] =
686  dir.make<TProfile>("InputWaveform", "Waveform", waveformSize, 0, waveformSize, -500., 500.);
687  } catch(...)
688  {
689  std::cout << "Caught exception trying to make new hists, tpc,plane,cnt,wire: " << tpc << ", " << fPlane << ", " << cnt << ", " << wire << std::endl;
690  }
691  }
692 
693  return histogramMap;
694 }
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
tuple dir
Definition: dropbox.py:28
size_t fPlane
Tool can be plane dependent.
BEGIN_PROLOG could also be cout
size_t icarus_tool::ROIFinderMorphological::plane ( ) const
inlineoverridevirtual

Implements icarus_tool::IROIFinder.

Definition at line 36 of file ROIFinderMorphological_tool.cc.

36 {return fPlane;}
size_t fPlane
Tool can be plane dependent.
void icarus_tool::ROIFinderMorphological::smoothInputWaveform ( const Waveform inputWaveform,
Waveform outputWaveform 
) const
private

Definition at line 579 of file ROIFinderMorphological_tool.cc.

580 {
581  // Vector smoothing - take the 10 bin average
582  int halfBins = fNumBinsToAve / 2;
583 
584  outputWaveform.resize(inputWaveform.size());
585 
586  // Make sure smoothing makes sense
587  if (halfBins > 0)
588  {
589  // To facilitate handling the bins at the ends of the input waveform we embed in a slightly larger
590  // vector which has zeroes on the ends
591  Waveform tempWaveform(inputWaveform.size()+fNumBinsToAve);
592 
593  // Set the edge bins which can't be smoothed to zero
594  std::fill(tempWaveform.begin(),tempWaveform.begin()+halfBins,0.);
595  std::fill(tempWaveform.end()-halfBins,tempWaveform.end(),0.);
596 
597  // Copy in the input waveform
598  std::copy(inputWaveform.begin(),inputWaveform.end(),tempWaveform.begin()+halfBins);
599 
600  // Now do the smoothing
601  for(size_t idx = 0; idx < inputWaveform.size(); idx++)
602  {
603  float weightedSum(0.);
604 
605  for(int wIdx = 0; wIdx < fNumBinsToAve; wIdx++) weightedSum += fAveWeightVec.at(wIdx) * tempWaveform.at(idx + wIdx);
606 
607  outputWaveform.at(idx) = weightedSum / fWeightSum;
608  }
609  }
610  else std::copy(inputWaveform.begin(),inputWaveform.end(),outputWaveform.begin());
611 
612  return;
613 }
float fWeightSum
sum of weights for smoothing
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
T copy(T const &v)
std::vector< float > fAveWeightVec
Weight vector for smoothing.

Member Data Documentation

std::vector<float> icarus_tool::ROIFinderMorphological::fAveWeightVec
private

Weight vector for smoothing.

Definition at line 88 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fDeltaTicksHist
private

Definition at line 103 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fDiffFullRmsHist
private

Definition at line 96 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fDiffMaxHist
private

Definition at line 98 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fDiffMeanHist
private

Definition at line 94 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fDiffRmsHist
private

Definition at line 95 of file ROIFinderMorphological_tool.cc.

TH2F* icarus_tool::ROIFinderMorphological::fDiffVDilHist
private

Definition at line 106 of file ROIFinderMorphological_tool.cc.

TH2F* icarus_tool::ROIFinderMorphological::fDTixVDiffHist
private

Definition at line 105 of file ROIFinderMorphological_tool.cc.

TH2F* icarus_tool::ROIFinderMorphological::fDTixVDLenHist
private

Definition at line 104 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fDTruncBinsHist
private

Definition at line 97 of file ROIFinderMorphological_tool.cc.

const geo::GeometryCore* icarus_tool::ROIFinderMorphological::fGeometry = lar::providerFrom<geo::Geometry>()
private

Definition at line 111 of file ROIFinderMorphological_tool.cc.

art::TFileDirectory* icarus_tool::ROIFinderMorphological::fHistDirectory
private

Definition at line 91 of file ROIFinderMorphological_tool.cc.

int icarus_tool::ROIFinderMorphological::fMax2MinDistance
private

Minimum allow peak to peak distance.

Definition at line 78 of file ROIFinderMorphological_tool.cc.

float icarus_tool::ROIFinderMorphological::fMax2MinHeight
private

Minimum peak to peak height (box cut)

Definition at line 79 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fMaxDiffLength
private

Definition at line 102 of file ROIFinderMorphological_tool.cc.

int icarus_tool::ROIFinderMorphological::fMaxLengthCut
private

Minimum length of the maximum.

Definition at line 80 of file ROIFinderMorphological_tool.cc.

unsigned short icarus_tool::ROIFinderMorphological::fMaxPadLen
private

Don't let padding be larger than this.

Definition at line 84 of file ROIFinderMorphological_tool.cc.

int icarus_tool::ROIFinderMorphological::fNumBinsToAve
private

Controls the smoothing.

Definition at line 77 of file ROIFinderMorphological_tool.cc.

float icarus_tool::ROIFinderMorphological::fNumSigma
private

"# sigma" rms noise for ROI threshold

Definition at line 76 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fNumSigmaHist
private

Definition at line 99 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fNumSigNextHist
private

Definition at line 101 of file ROIFinderMorphological_tool.cc.

bool icarus_tool::ROIFinderMorphological::fOutputHistograms
private

Output histograms?

Definition at line 85 of file ROIFinderMorphological_tool.cc.

bool icarus_tool::ROIFinderMorphological::fOutputWaveforms
private

Output waveforms?

Definition at line 86 of file ROIFinderMorphological_tool.cc.

size_t icarus_tool::ROIFinderMorphological::fPlane
private

Tool can be plane dependent.

Definition at line 74 of file ROIFinderMorphological_tool.cc.

unsigned short icarus_tool::ROIFinderMorphological::fPostROIPad
private

ROI padding.

Definition at line 83 of file ROIFinderMorphological_tool.cc.

unsigned short icarus_tool::ROIFinderMorphological::fPreROIPad
private

ROI padding.

Definition at line 82 of file ROIFinderMorphological_tool.cc.

int icarus_tool::ROIFinderMorphological::fStructuringElement
private

The window size.

Definition at line 81 of file ROIFinderMorphological_tool.cc.

TH1F* icarus_tool::ROIFinderMorphological::fThresholdHist
private

Definition at line 100 of file ROIFinderMorphological_tool.cc.

bool icarus_tool::ROIFinderMorphological::fUseDifference
private

If true use differences, else dilation.

Definition at line 75 of file ROIFinderMorphological_tool.cc.

icarus_signal_processing::WaveformTools<float> icarus_tool::ROIFinderMorphological::fWaveformTool
private

Definition at line 108 of file ROIFinderMorphological_tool.cc.

float icarus_tool::ROIFinderMorphological::fWeightSum
private

sum of weights for smoothing

Definition at line 89 of file ROIFinderMorphological_tool.cc.


The documentation for this class was generated from the following file: