All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GausHitFinder_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // GaussHitFinder class
4 //
5 // jaasaadi@syr.edu
6 //
7 // This algorithm is designed to find hits on wires after deconvolution.
8 // -----------------------------------
9 // This algorithm is based on the FFTHitFinder written by Brian Page,
10 // Michigan State University, for the ArgoNeuT experiment.
11 //
12 //
13 // The algorithm walks along the wire and looks for pulses above threshold
14 // The algorithm then attempts to fit n-gaussians to these pulses where n
15 // is set by the number of peaks found in the pulse
16 // If the Chi2/NDF returned is "bad" it attempts to fit n+1 gaussians to
17 // the pulse. If this is a better fit it then uses the parameters of the
18 // Gaussian fit to characterize the "hit" object
19 //
20 // To use this simply include the following in your producers:
21 // gaushit: @local::microboone_gaushitfinder
22 // gaushit: @local::argoneut_gaushitfinder
23 ////////////////////////////////////////////////////////////////////////
24 
25 // C/C++ standard library
26 #include <algorithm> // std::accumulate()
27 #include <atomic>
28 #include <memory> // std::unique_ptr()
29 #include <string>
30 #include <utility> // std::move()
31 
32 // Framework includes
33 #include "art/Framework/Core/ModuleMacros.h"
34 #include "art/Framework/Core/SharedProducer.h"
35 #include "art/Framework/Principal/Event.h"
36 #include "art/Framework/Services/Registry/ServiceHandle.h"
37 #include "art/Utilities/Globals.h"
38 #include "art/Utilities/make_tool.h"
39 #include "art_root_io/TFileService.h"
40 #include "canvas/Persistency/Common/FindOneP.h"
41 #include "fhiclcpp/ParameterSet.h"
42 
43 // LArSoft Includes
46 #include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t
50 
53 
54 // ROOT Includes
55 #include "TH1F.h"
56 #include "TMath.h"
57 
58 #include "tbb/concurrent_vector.h"
59 #include "tbb/parallel_for.h"
60 
61 namespace hit {
62  class GausHitFinder : public art::SharedProducer {
63  public:
64  explicit GausHitFinder(fhicl::ParameterSet const& pset, art::ProcessingFrame const&);
65 
66  private:
67  void produce(art::Event& evt, art::ProcessingFrame const&) override;
68  void beginJob(art::ProcessingFrame const&) override;
69 
70  std::vector<double> FillOutHitParameterVector(const std::vector<double>& input);
71 
72  const bool fFilterHits;
73  const bool fFillHists;
74 
75  const std::string fCalDataModuleLabel;
76  const std::string fAllHitsInstanceName;
77 
78  const std::vector<int> fLongMaxHitsVec; ///<Maximum number hits on a really long pulse train
79  const std::vector<int> fLongPulseWidthVec; ///<Sets width of hits used to describe long pulses
80 
81  const size_t fMaxMultiHit; ///<maximum hits for multi fit
82  const int fAreaMethod; ///<Type of area calculation
83  const std::vector<double>
84  fAreaNormsVec; ///<factors for converting area to same units as peak height
85  const double fChi2NDF; ///maximum Chisquared / NDF allowed for a hit to be saved
86 
87  const std::vector<float> fPulseHeightCuts;
88  const std::vector<float> fPulseWidthCuts;
89  const std::vector<float> fPulseRatioCuts;
90 
91  std::atomic<size_t> fEventCount{0};
92 
93  //only Standard and Morphological implementation is threadsafe.
94  std::vector<std::unique_ptr<reco_tool::ICandidateHitFinder>>
95  fHitFinderToolVec; ///< For finding candidate hits
96  // only Marqdt implementation is threadsafe.
97  std::unique_ptr<reco_tool::IPeakFitter> fPeakFitterTool; ///< Perform fit to candidate peaks
98  //HitFilterAlg implementation is threadsafe.
99  std::unique_ptr<HitFilterAlg> fHitFilterAlg; ///< algorithm used to filter out noise hits
100 
101  //only used when fFillHists is true and in single threaded mode.
102  TH1F* fFirstChi2;
103  TH1F* fChi2;
104 
105  }; // class GausHitFinder
106 
107  //-------------------------------------------------
108  //-------------------------------------------------
109  GausHitFinder::GausHitFinder(fhicl::ParameterSet const& pset, art::ProcessingFrame const&)
110  : SharedProducer{pset}
111  , fFilterHits(pset.get<bool>("FilterHits", false))
112  , fFillHists(pset.get<bool>("FillHists", false))
113  , fCalDataModuleLabel(pset.get<std::string>("CalDataModuleLabel"))
114  , fAllHitsInstanceName(pset.get<std::string>("AllHitsInstanceName", ""))
115  , fLongMaxHitsVec(pset.get<std::vector<int>>("LongMaxHits", std::vector<int>() = {25, 25, 25}))
117  pset.get<std::vector<int>>("LongPulseWidth", std::vector<int>() = {16, 16, 16}))
118  , fMaxMultiHit(pset.get<int>("MaxMultiHit"))
119  , fAreaMethod(pset.get<int>("AreaMethod"))
120  , fAreaNormsVec(FillOutHitParameterVector(pset.get<std::vector<double>>("AreaNorms")))
121  , fChi2NDF(pset.get<double>("Chi2NDF"))
123  pset.get<std::vector<float>>("PulseHeightCuts", std::vector<float>() = {3.0, 3.0, 3.0}))
124  , fPulseWidthCuts(
125  pset.get<std::vector<float>>("PulseWidthCuts", std::vector<float>() = {2.0, 1.5, 1.0}))
127  pset.get<std::vector<float>>("PulseRatioCuts", std::vector<float>() = {0.35, 0.40, 0.20}))
128  {
129  if (fFillHists && art::Globals::instance()->nthreads() > 1u) {
130  throw art::Exception(art::errors::Configuration)
131  << "Cannot fill histograms when multiple threads configured, please set fFillHists to "
132  "false or change number of threads to 1\n";
133  }
134  async<art::InEvent>();
135  if (fFilterHits) {
136  fHitFilterAlg = std::make_unique<HitFilterAlg>(pset.get<fhicl::ParameterSet>("HitFilterAlg"));
137  }
138 
139  // recover the tool to do the candidate hit finding
140  // Recover the vector of fhicl parameters for the ROI tools
141  const fhicl::ParameterSet& hitFinderTools = pset.get<fhicl::ParameterSet>("HitFinderToolVec");
142 
143  fHitFinderToolVec.resize(hitFinderTools.get_pset_names().size());
144 
145  for (const std::string& hitFinderTool : hitFinderTools.get_pset_names()) {
146  const fhicl::ParameterSet& hitFinderToolParamSet =
147  hitFinderTools.get<fhicl::ParameterSet>(hitFinderTool);
148  size_t planeIdx = hitFinderToolParamSet.get<size_t>("Plane");
149 
150  fHitFinderToolVec.at(planeIdx) =
151  art::make_tool<reco_tool::ICandidateHitFinder>(hitFinderToolParamSet);
152  }
153 
154  // Recover the peak fitting tool
155  fPeakFitterTool =
156  art::make_tool<reco_tool::IPeakFitter>(pset.get<fhicl::ParameterSet>("PeakFitter"));
157 
158  // let HitCollectionCreator declare that we are going to produce
159  // hits and associations with wires and raw digits
160  // We want the option to output two hit collections, one filtered
161  // and one with all hits. The key to doing this will be a non-null
162  // instance name for the second collection
163  // (with no particular product label)
165  producesCollector(), fAllHitsInstanceName, true, false); //fMakeRawDigitAssns);
166 
167  // and now the filtered hits...
168  if (fAllHitsInstanceName != "")
170  producesCollector(), "", true, false); //fMakeRawDigitAssns);
171 
172  return;
173  } // GausHitFinder::GausHitFinder()
174 
175  //-------------------------------------------------
176  //-------------------------------------------------
177  std::vector<double>
178  GausHitFinder::FillOutHitParameterVector(const std::vector<double>& input)
179  {
180  if (input.size() == 0)
181  throw std::runtime_error(
182  "GausHitFinder::FillOutHitParameterVector ERROR! Input config vector has zero size.");
183 
184  std::vector<double> output;
185  art::ServiceHandle<geo::Geometry const> geom;
186  const unsigned int N_PLANES = geom->Nplanes();
187 
188  if (input.size() == 1)
189  output.resize(N_PLANES, input[0]);
190  else if (input.size() == N_PLANES)
191  output = input;
192  else
193  throw std::runtime_error("GausHitFinder::FillOutHitParameterVector ERROR! Input config "
194  "vector size !=1 and !=N_PLANES.");
195  return output;
196  }
197 
198  //-------------------------------------------------
199  //-------------------------------------------------
200  void
201  GausHitFinder::beginJob(art::ProcessingFrame const&)
202  {
203  // get access to the TFile service
204  art::ServiceHandle<art::TFileService const> tfs;
205 
206  // ======================================
207  // === Hit Information for Histograms ===
208  if (fFillHists) {
209  fFirstChi2 = tfs->make<TH1F>("fFirstChi2", "#chi^{2}", 10000, 0, 5000);
210  fChi2 = tfs->make<TH1F>("fChi2", "#chi^{2}", 10000, 0, 5000);
211  }
212  }
213 
214  // This algorithm uses the fact that deconvolved signals are very smooth
215  // and looks for hits as areas between local minima that have signal above
216  // threshold.
217  //-------------------------------------------------
218  void
219  GausHitFinder::produce(art::Event& evt, art::ProcessingFrame const&)
220  {
221  unsigned int count = fEventCount.fetch_add(1);
222  //==================================================================================================
223 
224  TH1::AddDirectory(kFALSE);
225 
226  // Instantiate and Reset a stop watch
227  //TStopwatch StopWatch;
228  //StopWatch.Reset();
229 
230  // ################################
231  // ### Calling Geometry service ###
232  // ################################
233  art::ServiceHandle<geo::Geometry const> geom;
234 
235  // ###############################################
236  // ### Making a ptr vector to put on the event ###
237  // ###############################################
238  // this contains the hit collection
239  // and its associations to wires and raw digits
240  recob::HitCollectionCreator allHitCol(evt, fAllHitsInstanceName, true, false);
241 
242  // Handle the filtered hits collection...
243  recob::HitCollectionCreator hcol(evt, "", true, false);
244  recob::HitCollectionCreator* filteredHitCol = 0;
245 
246  if (fFilterHits) filteredHitCol = &hcol;
247 
248  //store in a thread safe way
249  struct hitstruct {
250  recob::Hit hit_tbb;
251  art::Ptr<recob::Wire> wire_tbb;
252  };
253 
254  tbb::concurrent_vector<hitstruct> hitstruct_vec;
255  tbb::concurrent_vector<hitstruct> filthitstruct_vec;
256 
257  // if (fAllHitsInstanceName != "") filteredHitCol = &hcol;
258 
259  // ##########################################
260  // ### Reading in the Wire List object(s) ###
261  // ##########################################
262  art::Handle<std::vector<recob::Wire>> wireVecHandle;
263  evt.getByLabel(fCalDataModuleLabel, wireVecHandle);
264 
265  //#################################################
266  //### Set the charge determination method ###
267  //### Default is to compute the normalized area ###
268  //#################################################
269  std::function<double(double, double, double, double, int, int)> chargeFunc =
270  [](double peakMean, double peakAmp, double peakWidth, double areaNorm, int low, int hi) {
271  return std::sqrt(2 * TMath::Pi()) * peakAmp * peakWidth / areaNorm;
272  };
273 
274  //##############################################
275  //### Alternative is to integrate over pulse ###
276  //##############################################
277  if (fAreaMethod == 0)
278  chargeFunc =
279  [](double peakMean, double peakAmp, double peakWidth, double areaNorm, int low, int hi) {
280  double charge(0);
281  for (int sigPos = low; sigPos < hi; sigPos++)
282  charge += peakAmp * TMath::Gaus(sigPos, peakMean, peakWidth);
283  return charge;
284  };
285 
286  //##############################
287  //### Looping over the wires ###
288  //##############################
289  //for(size_t wireIter = 0; wireIter < wireVecHandle->size(); wireIter++)
290  //{
291  tbb::parallel_for(
292  static_cast<std::size_t>(0),
293  wireVecHandle->size(),
294  [&](size_t& wireIter) {
295  // ####################################
296  // ### Getting this particular wire ###
297  // ####################################
298  art::Ptr<recob::Wire> wire(wireVecHandle, wireIter);
299 
300  // --- Setting Channel Number and Signal type ---
301 
302  raw::ChannelID_t channel = wire->Channel();
303 
304  // get the WireID for this hit
305  std::vector<geo::WireID> wids = geom->ChannelToWire(channel);
306  // for now, just take the first option returned from ChannelToWire
307  geo::WireID wid = wids[0];
308  // We need to know the plane to look up parameters
309  geo::PlaneID::PlaneID_t plane = wid.Plane;
310 
311  // ----------------------------------------------------------
312  // -- Setting the appropriate signal widths and thresholds --
313  // -- for the right plane. --
314  // ----------------------------------------------------------
315 
316  // #################################################
317  // ### Set up to loop over ROI's for this wire ###
318  // #################################################
319  const recob::Wire::RegionsOfInterest_t& signalROI = wire->SignalROI();
320 
321  // for (const auto& range : signalROI.get_ranges()) {
322  tbb::parallel_for(static_cast<std::size_t>(0),signalROI.n_ranges(),
323  [&](size_t& rangeIter){
324  const auto& range = signalROI.range(rangeIter);
325  // ROI start time
326  raw::TDCtick_t roiFirstBinTick = range.begin_index();
327 
328  // ###########################################################
329  // ### Scan the waveform and find candidate peaks + merge ###
330  // ###########################################################
331 
334 
335  fHitFinderToolVec.at(plane)->findHitCandidates(range, 0, channel, count, hitCandidateVec);
336  fHitFinderToolVec.at(plane)->MergeHitCandidates(
337  range, hitCandidateVec, mergedCandidateHitVec);
338 
339  // #######################################################
340  // ### Lets loop over the pulses we found on this wire ###
341  // #######################################################
342 
343  for (auto& mergedCands : mergedCandidateHitVec) {
344  int startT = mergedCands.front().startTick;
345  int endT = mergedCands.back().stopTick;
346 
347  // ### Putting in a protection in case things went wrong ###
348  // ### In the end, this primarily catches the case where ###
349  // ### a fake pulse is at the start of the ROI ###
350  if (endT - startT < 5) continue;
351 
352  // #######################################################
353  // ### Clearing the parameter vector for the new pulse ###
354  // #######################################################
355 
356  // === Setting the number of Gaussians to try ===
357  int nGausForFit = mergedCands.size();
358 
359  // ##################################################
360  // ### Calling the function for fitting Gaussians ###
361  // ##################################################
362  double chi2PerNDF(0.);
363  int NDF(1);
364  /*stand alone
365  reco_tool::IPeakFitter::PeakParamsVec peakParamsVec(nGausForFit);
366  */
368 
369  // #######################################################
370  // ### If # requested Gaussians is too large then punt ###
371  // #######################################################
372  if (mergedCands.size() <= fMaxMultiHit) {
373  fPeakFitterTool->findPeakParameters(
374  range.data(), mergedCands, peakParamsVec, chi2PerNDF, NDF);
375 
376  // If the chi2 is infinite then there is a real problem so we bail
377  if (!(chi2PerNDF < std::numeric_limits<double>::infinity())) {
378  chi2PerNDF = 2. * fChi2NDF;
379  NDF = 2;
380  }
381 
382  if (fFillHists) fFirstChi2->Fill(chi2PerNDF);
383  }
384 
385  // #######################################################
386  // ### If too large then force alternate solution ###
387  // ### - Make n hits from pulse train where n will ###
388  // ### depend on the fhicl parameter fLongPulseWidth ###
389  // ### Also do this if chi^2 is too large ###
390  // #######################################################
391  if (mergedCands.size() > fMaxMultiHit || nGausForFit * chi2PerNDF > fChi2NDF) {
392  int longPulseWidth = fLongPulseWidthVec.at(plane);
393  int nHitsThisPulse = (endT - startT) / longPulseWidth;
394 
395  if (nHitsThisPulse > fLongMaxHitsVec.at(plane)) {
396  nHitsThisPulse = fLongMaxHitsVec.at(plane);
397  longPulseWidth = (endT - startT) / nHitsThisPulse;
398  }
399 
400  if (nHitsThisPulse * longPulseWidth < endT - startT) nHitsThisPulse++;
401 
402  int firstTick = startT;
403  int lastTick = std::min(firstTick + longPulseWidth, endT);
404 
405  peakParamsVec.clear();
406  nGausForFit = nHitsThisPulse;
407  NDF = 1.;
408  chi2PerNDF = chi2PerNDF > fChi2NDF ? chi2PerNDF : -1.;
409 
410  for (int hitIdx = 0; hitIdx < nHitsThisPulse; hitIdx++) {
411  // This hit parameters
412  double sumADC =
413  std::accumulate(range.begin() + firstTick, range.begin() + lastTick, 0.);
414  double peakSigma = (lastTick - firstTick) / 3.; // Set the width...
415  double peakAmp = 0.3989 * sumADC / peakSigma; // Use gaussian formulation
416  double peakMean = (firstTick + lastTick) / 2.;
417 
418  // Store hit params
420 
421  peakParams.peakCenter = peakMean;
422  peakParams.peakCenterError = 0.1 * peakMean;
423  peakParams.peakSigma = peakSigma;
424  peakParams.peakSigmaError = 0.1 * peakSigma;
425  peakParams.peakAmplitude = peakAmp;
426  peakParams.peakAmplitudeError = 0.1 * peakAmp;
427 
428  peakParamsVec.push_back(peakParams);
429 
430  // set for next loop
431  firstTick = lastTick;
432  lastTick = std::min(lastTick + longPulseWidth, endT);
433  }
434  }
435 
436  // #######################################################
437  // ### Loop through returned peaks and make recob hits ###
438  // #######################################################
439 
440  int numHits(0);
441 
442  // Make a container for what will be the filtered collection
443  std::vector<recob::Hit> filteredHitVec;
444 
445  for (const auto& peakParams : peakParamsVec) {
446  // Extract values for this hit
447  float peakAmp = peakParams.peakAmplitude;
448  float peakMean = peakParams.peakCenter;
449  float peakWidth = peakParams.peakSigma;
450 
451  // Place one bit of protection here
452  if (std::isnan(peakAmp)) {
453  std::cout << "**** hit peak amplitude is a nan! Channel: " << channel
454  << ", start tick: " << startT << std::endl;
455  continue;
456  }
457 
458  // Extract errors
459  float peakAmpErr = peakParams.peakAmplitudeError;
460  float peakMeanErr = peakParams.peakCenterError;
461  float peakWidthErr = peakParams.peakSigmaError;
462 
463  // ### Charge ###
464  float charge =
465  chargeFunc(peakMean, peakAmp, peakWidth, fAreaNormsVec[plane], startT, endT);
466  ;
467  float chargeErr =
468  std::sqrt(TMath::Pi()) * (peakAmpErr * peakWidthErr + peakWidthErr * peakAmpErr);
469 
470  // ### limits for getting sums
471  std::vector<float>::const_iterator sumStartItr = range.begin() + startT;
472  std::vector<float>::const_iterator sumEndItr = range.begin() + endT;
473 
474  // ### Sum of ADC counts
475  double sumADC = std::accumulate(sumStartItr, sumEndItr, 0.);
476 
477  // ok, now create the hit
478  recob::HitCreator hitcreator(
479  *wire, // wire reference
480  wid, // wire ID
481  startT + roiFirstBinTick, // start_tick TODO check
482  endT + roiFirstBinTick, // end_tick TODO check
483  peakWidth, // rms
484  peakMean + roiFirstBinTick, // peak_time
485  peakMeanErr, // sigma_peak_time
486  peakAmp, // peak_amplitude
487  peakAmpErr, // sigma_peak_amplitude
488  charge, // hit_integral
489  chargeErr, // hit_sigma_integral
490  sumADC, // summedADC FIXME
491  nGausForFit, // multiplicity
492  numHits, // local_index TODO check that the order is correct
493  chi2PerNDF, // goodness_of_fit
494  NDF // dof
495  );
496 
497  if (filteredHitCol) filteredHitVec.push_back(hitcreator.copy());
498 
499  const recob::Hit hit(hitcreator.move());
500 
501  // This loop will store ALL hits
502  hitstruct tmp{std::move(hit), wire};
503  hitstruct_vec.push_back(std::move(tmp));
504 
505  numHits++;
506  } // <---End loop over gaussians
507 
508  // Should we filter hits?
509  if (filteredHitCol && !filteredHitVec.empty()) {
510  // #######################################################################
511  // Is all this sorting really necessary? Would it be faster to just loop
512  // through the hits and perform simple cuts on amplitude and width on a
513  // hit-by-hit basis, either here in the module (using fPulseHeightCuts and
514  // fPulseWidthCuts) or in HitFilterAlg?
515  // #######################################################################
516 
517  // Sort in ascending peak height
518  std::sort(filteredHitVec.begin(),
519  filteredHitVec.end(),
520  [](const auto& left, const auto& right) {
521  return left.PeakAmplitude() > right.PeakAmplitude();
522  });
523 
524  // Reject if the first hit fails the PH/wid cuts
525  if (filteredHitVec.front().PeakAmplitude() < fPulseHeightCuts.at(plane) ||
526  filteredHitVec.front().RMS() < fPulseWidthCuts.at(plane))
527  filteredHitVec.clear();
528 
529  // Now check other hits in the snippet
530  if (filteredHitVec.size() > 1) {
531  // The largest pulse height will now be at the front...
532  float largestPH = filteredHitVec.front().PeakAmplitude();
533 
534  // Find where the pulse heights drop below threshold
535  float threshold(fPulseRatioCuts.at(plane));
536 
537  std::vector<recob::Hit>::iterator smallHitItr = std::find_if(
538  filteredHitVec.begin(),
539  filteredHitVec.end(),
540  [largestPH, threshold](const auto& hit) {
541  return hit.PeakAmplitude() < 8. && hit.PeakAmplitude() / largestPH < threshold;
542  });
543 
544  // Shrink to fit
545  if (smallHitItr != filteredHitVec.end())
546  filteredHitVec.resize(std::distance(filteredHitVec.begin(), smallHitItr));
547 
548  // Resort in time order
549  std::sort(filteredHitVec.begin(),
550  filteredHitVec.end(),
551  [](const auto& left, const auto& right) {
552  return left.PeakTime() < right.PeakTime();
553  });
554  }
555 
556  // Copy the hits we want to keep to the filtered hit collection
557  for (const auto& filteredHit : filteredHitVec)
558  if (!fHitFilterAlg || fHitFilterAlg->IsGoodHit(filteredHit)) {
559  hitstruct tmp{std::move(filteredHit), wire};
560  filthitstruct_vec.push_back(std::move(tmp));
561  }
562 
563  if (fFillHists) fChi2->Fill(chi2PerNDF);
564  }
565  } //<---End loop over merged candidate hits
566 
567  } //<---End looping over ROI's
568  );//end tbb parallel for
569 
570  } //<---End looping over all the wires
571  ); //end tbb parallel for
572 
573  for (size_t i = 0; i < hitstruct_vec.size(); i++) {
574  allHitCol.emplace_back(hitstruct_vec[i].hit_tbb, hitstruct_vec[i].wire_tbb);
575  }
576 
577  for (size_t j = 0; j < filthitstruct_vec.size(); j++) {
578  filteredHitCol->emplace_back(filthitstruct_vec[j].hit_tbb, filthitstruct_vec[j].wire_tbb);
579  }
580 
581  //==================================================================================================
582  // End of the event -- move the hit collection and the associations into the event
583 
584  if (filteredHitCol) {
585 
586  // If we filtered hits but no instance name was
587  // specified for the "all hits" collection, then
588  // only save the filtered hits to the event
589  if (fAllHitsInstanceName == "") {
590  filteredHitCol->put_into(evt);
591 
592  // otherwise, save both
593  }
594  else {
595  filteredHitCol->put_into(evt);
596  allHitCol.put_into(evt);
597  }
598  }
599  else {
600  allHitCol.put_into(evt);
601  }
602 
603  // Keep track of events processed
604  //fEventCount++;
605 
606  } // End of produce()
607 
608  DEFINE_ART_MODULE(GausHitFinder)
609 
610 } // end of hit namespace
const datarange_t & range(size_t i) const
Returns the i-th non-void range (zero-based)
size_type n_ranges() const
Returns the internal list of non-void ranges.
recob::Hit const & copy() const
Returns the constructed wire.
Definition: HitCreator.h:361
std::unique_ptr< HitFilterAlg > fHitFilterAlg
algorithm used to filter out noise hits
fMaxMultiHit(pset.get< int >("MaxMultiHit"))
Declaration of signal hit object.
walls no right
Definition: selectors.fcl:105
void produce(art::Event &evt, art::ProcessingFrame const &) override
GausHitFinder(fhicl::ParameterSet const &pset, art::ProcessingFrame const &)
unsigned int PlaneID_t
Type for the ID number.
Definition: geo_types.h:473
fPulseHeightCuts(pset.get< std::vector< float >>("PulseHeightCuts", std::vector< float >()={3.0, 3.0, 3.0}))
fPulseRatioCuts(pset.get< std::vector< float >>("PulseRatioCuts", std::vector< float >()={0.35, 0.40, 0.20}))
const std::string instance
process_name hit
Definition: cheaterreco.fcl:51
const std::vector< int > fLongPulseWidthVec
Sets width of hits used to describe long pulses.
static void declare_products(art::ProducesCollector &collector, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Declares the hit products we are going to fill.
Definition: HitCreator.cxx:248
std::unique_ptr< reco_tool::IPeakFitter > fPeakFitterTool
Perform fit to candidate peaks.
const int fAreaMethod
Type of area calculation.
standard_dbscan3dalg useful for diagnostics hits not in a line will not be clustered on on only for track like only for track like on on the smaller the less shower like tracks low
const std::string fCalDataModuleLabel
const std::vector< float > fPulseWidthCuts
int TDCtick_t
Type representing a TDC tick.
Definition: RawTypes.h:25
Class managing the creation of a new recob::Hit object.
Definition: HitCreator.h:83
Helper functions to create a hit.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
A class handling a collection of hits and its associations.
Definition: HitCreator.h:508
std::vector< double > FillOutHitParameterVector(const std::vector< double > &input)
std::atomic< size_t > fEventCount
const size_t fMaxMultiHit
maximum hits for multi fit
const std::vector< int > fLongMaxHitsVec
Maximum number hits on a really long pulse train.
fLongPulseWidthVec(pset.get< std::vector< int >>("LongPulseWidth", std::vector< int >()={16, 16, 16}))
walls no left
Definition: selectors.fcl:105
void beginJob(art::ProcessingFrame const &) override
void emplace_back(recob::Hit &&hit, art::Ptr< recob::Wire > const &wire=art::Ptr< recob::Wire >(), art::Ptr< raw::RawDigit > const &digits=art::Ptr< raw::RawDigit >())
Adds the specified hit to the data collection.
Definition: HitCreator.cxx:290
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
void put_into(art::Event &)
Moves the data into an event.
Definition: HitCreator.h:652
fPulseWidthCuts(pset.get< std::vector< float >>("PulseWidthCuts", std::vector< float >()={2.0, 1.5, 1.0}))
BEGIN_PROLOG sequence::SlidingWindowTriggerPatternsOppositeWindows END_PROLOG simSlidingORM6O6 effSlidingORW output
const std::vector< float > fPulseRatioCuts
This provides an interface for tools which are tasked with finding candidate hits on input waveforms...
const std::vector< float > fPulseHeightCuts
maximum Chisquared / NDF allowed for a hit to be saved
Declaration of basic channel signal object.
const std::string fAllHitsInstanceName
fAreaMethod(pset.get< int >("AreaMethod"))
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
art::ServiceHandle< art::TFileService > tfs
fAreaNormsVec(FillOutHitParameterVector(pset.get< std::vector< double >>("AreaNorms")))
const std::vector< double > fAreaNormsVec
factors for converting area to same units as peak height
TCEvent evt
Definition: DataStructs.cxx:8
std::size_t count(Cont const &cont)
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
std::vector< HitCandidateVec > MergeHitCandidateVec
fChi2NDF(pset.get< double >("Chi2NDF"))
recob::Hit && move()
Prepares the constructed hit to be moved away.
Definition: HitCreator.h:343
art framework interface to geometry description
BEGIN_PROLOG could also be cout
std::vector< std::unique_ptr< reco_tool::ICandidateHitFinder > > fHitFinderToolVec
For finding candidate hits.
std::vector< HitCandidate > HitCandidateVec