All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ICARUSOpHitFinder_module.cc
Go to the documentation of this file.
1 /**
2  * @file icaruscode/PMT/ICARUSOpHitFinder_module.cc
3  * @brief LArSoft module for PMT hit finding.
4  * @date May 6, 2022
5  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
6  *
7  * Offers `opdet::ICARUSOpHitFinder` (see in its documentation why).
8  */
9 
10 // ICARUS libraries
15 // LArSoft libraries
27 #include "larana/OpticalDetector/OpHitFinder/OpticalRecoTypes.h" // pmtana::Waveform_t
37 
38 // framework libraries
39 #include "art/Framework/Core/ReplicatedProducer.h"
40 #include "art/Framework/Core/ProcessingFrame.h"
41 #include "art/Framework/Core/ModuleMacros.h"
42 #include "art/Framework/Principal/Event.h"
43 #include "art/Framework/Principal/Handle.h"
44 #include "canvas/Utilities/Exception.h"
45 #include "messagefacility/MessageLogger/MessageLogger.h"
46 #include "fhiclcpp/types/Sequence.h"
47 #include "fhiclcpp/types/OptionalAtom.h"
48 #include "fhiclcpp/types/Atom.h"
49 #include "fhiclcpp/types/DelegatedParameter.h"
50 #include "fhiclcpp/ParameterSet.h"
51 
52 // C++ standard libraries
53 #include <algorithm> // std::copy_if(), std::binary_search()
54 #include <vector>
55 #include <variant>
56 #include <memory> // std::unique_ptr
57 #include <string>
58 #include <functional> // std::mem_fn()
59 #include <utility> // std::move()
60 #include <cassert>
61 
62 
63 // -----------------------------------------------------------------------------
64 namespace {
65 
67 
68  /// Types of _art_ interface.
69  using ArtTraits
71 
72  // ===========================================================================
73  // BEGIN === DECLARE NEW ALGORITHMS HERE
74  // ===========================================================================
75  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
76  // optical hit algorithm factory
78  HitAlgoFactory {
79  "Name" // find the name of the algorithm under "Name" in its configuration
85  };
86 
87 
88  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
89  // pedestal algorithm factory
90  template <typename Algo>
91  using FWIFPedAlgo
93 
96  PedAlgoFactory {
97  "Name" // find the name of the algorithm under "Name" in its configuration
98  , Decl<FWIFPedAlgo<pmtana::PedAlgoEdges >>{"Edges" }
99  , Decl<FWIFPedAlgo<pmtana::PedAlgoRollingMean>>{"RollingMean"}
100  , Decl<FWIFPedAlgo<pmtana::PedAlgoUB >>{"UB" }
101  , Decl<FWIFPedAlgo<pmtana::PedAlgoFixed >>{"Fixed" }
102  };
103 
104  // ===========================================================================
105  // END ===== DECLARE NEW ALGORITHMS HERE
106  // ===========================================================================
107 
108  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
109 
110 } // local namespace
111 
112 
113 // -----------------------------------------------------------------------------
114 namespace opdet { class ICARUSOpHitFinder; }
115 /**
116  * @class opdet::ICARUSOpHitFinder
117  * @brief Extracts PMT activity as optical hits (`recob::OpHit`).
118  *
119  * This module runs hit-finding algorithms, and is tailored to allow for an
120  * update of the hit finding parameters event by event.
121  *
122  *
123  * Motivation
124  * -----------
125  *
126  * This module is a branch of the standard LArSoft `opdet::OpHitFinder` by
127  * Gleb Sinev, Ben Jones and others.
128  * That module itself is an interface to the hit finding mini-framework also
129  * in `larana`, authored by Kazuhiro Terao.
130  *
131  * That framework independently analyzes each waveform and performs hit finding
132  * using general timing and geometry information (from `detinfo::DetectorClocks`
133  * and `geo::GeometryCore` service providers), a threshold parameter and
134  * configurable algorithms for baseline evaluation, hit finding and calibration.
135  *
136  * It is believed that the baseline of ICARUS PMT is remarkably stable in the
137  * short time, and it is conceivable to use a single steady value for many
138  * waveforms on each channel. Unfortunately the existing module is not suitable
139  * for a baseline that may change event by event or in time: the mini-framework
140  * does not explicitly allow this, and the module is not equipped with the
141  * necessary workarounds.
142  *
143  * This module is a replica of LArSoft's, with the additional workarounds needed
144  * to allow for a baseline learnt from an external source and changing event by
145  * event.
146  *
147  *
148  * Configuration parameters
149  * -------------------------
150  *
151  * The configuration parameters are intentionally left the same as in
152  * `opdet::OpHitFinder`, with a few exceptions and additions where needed.
153  *
154  * * `InputModule` (input tag): data product with the optical waveforms to
155  * analyze.
156  * * `GenModule` (input tag, mandatory): data product with the beam gate (either
157  * generated or from trigger information).
158  * * `UseStartTime` (flag, default: `false`): store the start time in the hit
159  * instead of the peak time.
160  * * `ChannelMasks` (list of channel numbers, default: empty): skip waveforms
161  * on the channels specified in this list.
162  * * `HitAlgoPset` (table, mandatory): configuration of the hit finding
163  * algorithm; its content depends on the algorithm itself, but the following
164  * elements are nonetheless mandatory:
165  * * `Name` (text): algorithm name; the supported algorithms are hard-coded
166  * by name.
167  * * `PedAlgoPset` (table, mandatory): configuration of the pedestal
168  * algorithm; its content depends on the algorithm itself, but the following
169  * elements are nonetheless mandatory:
170  * * `Name` (text): algorithm name; the supported algorithms are hard-coded
171  * by name.
172  *
173  * * `HitThreshold` (real): hit threshold [ADC counts]
174  * * `UseCalibrator` (flag, default: `false`): if set, use the calibration
175  * service configured in the job; otherwise, use the simpler calibration
176  * configured in this module (see the following parameters).
177  * * `AreaToPE` (flag): whether the conversion factor goes from hit area (total
178  * ADC) or from amplitude (ADC), to photoelectrons.
179  * * `SPEArea` (real): area or amplitude (depending on `AreaToPE`) of the
180  * response signal to a single photoelectron.
181  * * `SPEShift` (real, default: `0`)
182  *
183  * Noticeable differences with LArSoft's `opdet::OpHitFinder` configuration:
184  *
185  * * multiple input collections are not supported, so the `InputModule` is a
186  * complete input tag and no list of instance names can be specified.
187  *
188  *
189  * Multithreading
190  * ---------------
191  *
192  * In order to support the algorithms that require an event-specific
193  * configuration, the module is not shared. While the algorithms could be
194  * written to keep track of different event configurations, at the time the
195  * algorithms are executed on a waveform they have no mean to know which event
196  * the waveforms belong to. Rather than writing complex workarounds on this
197  * problem, the module is replicated so that there are multiple algorithms
198  * (and multiple managers) but each of them sees an event at a time, in a way
199  * that the module (replica) can predict.
200  *
201  */
202 class opdet::ICARUSOpHitFinder: public art::ReplicatedProducer {
203  public:
204 
205  struct Config {
206  using Name = fhicl::Name;
207  using Comment = fhicl::Comment;
208 
209  fhicl::Atom<art::InputTag> InputModule {
210  Name{ "InputModule" },
211  Comment{ "Data product with the optical waveforms to process" }
212  };
213 
214  fhicl::OptionalAtom<art::InputTag> GenModule {
215  Name{ "GenModule" },
216  Comment{ "Data product with the beam gates" }
217  };
218 
219  fhicl::Sequence<raw::Channel_t> ChannelMasks {
220  Name{ "ChannelMasks" },
221  Comment{ "List of channels to skip [none by default]" },
222  std::vector<raw::Channel_t>{}
223  };
224 
225  fhicl::Atom<float> HitThreshold {
226  Name{ "HitThreshold" },
227  Comment{ "Hit reconstruction threshold [ADC#]" }
228  };
229 
230  fhicl::Atom<bool> UseStartTime {
231  Name{ "UseStartTime" },
232  Comment{ "Store the start time instead of the peak time" },
233  false
234  };
235 
236  fhicl::DelegatedParameter HitAlgoPset {
237  Name{ "HitAlgoPset" },
238  Comment{
239  "parameters of the hit finding algorithm."
240  " The parameters must include the algorithm \"Name\", one of: "
241  + HitAlgoFactory.names(", ") + "."
242  }
243  };
244 
245  fhicl::DelegatedParameter PedAlgoPset {
246  Name{ "PedAlgoPset" },
247  Comment{
248  "parameters of the pedestal extraction algorithm."
249  " The parameters must include the algorithm \"Name\", one of: "
250  + PedAlgoFactory.names(", ") + "."
251  }
252  };
253 
254  fhicl::Atom<bool> UseCalibrator {
255  Name{ "UseCalibrator" },
256  Comment{ "Use the photon calibration service configured in the job" },
257  false
258  };
259 
260  fhicl::Atom<bool> AreaToPE {
261  Name{ "AreaToPE" },
262  Comment{ "Whether the `SPEArea` parameter refers to area or amplitude" },
263  [this](){ return !UseCalibrator(); }
264  };
265 
266  fhicl::Atom<float> SPEArea {
267  Name{ "SPEArea" },
268  Comment{ "area or amplitude of PMT response to single photoelectron" },
269  [this](){ return !UseCalibrator(); }
270  };
271 
272  fhicl::Atom<float> SPEShift {
273  Name{ "SPEShift" },
274  Comment{ "shift on the single photoelectron response" },
275  [this](){ return !UseCalibrator(); }
276  };
277 
278  }; // Config
279 
280  using Parameters = art::ReplicatedProducer::Table<Config>;
281 
282  explicit ICARUSOpHitFinder
283  (Parameters const& config, art::ProcessingFrame const& frame);
284 
285  virtual void produce(art::Event&, art::ProcessingFrame const&) override;
286 
287  private:
288 
289  // --- BEGIN -- Configuration parameters -------------------------------------
290  art::InputTag const fWaveformTags; ///< Input PMT waveform data product tags.
291  art::InputTag const fBeamGateTag; ///< Data product with beam gates.
292  /// Sorted list of channels to skip.
293  std::vector<unsigned int> const fChannelMasks;
294  float const fHitThreshold; ///< Hit finding threshold.
295  bool const fUseStartTime; ///< Whether to store start instead of peak time.
296  // --- END ---- Configuration parameters -------------------------------------
297 
298  // --- BEGIN -- Cached service values ----------------------------------------
299  /// Storage for our own calibration algorithm, if any.
300  std::unique_ptr<calib::IPhotonCalibrator> fMyCalib;
301 
302  unsigned int const fMaxOpChannel; ///< Number of channels in the detector.
303 
304  /// The calibration algorithm to be used (not owned).
306 
307  // --- END ---- Cached service values ----------------------------------------
308 
309 
310  // --- BEGIN -- Algorithms ---------------------------------------------------
311  using FWInterfacedPedAlgo
313 
315  std::unique_ptr<pmtana::PMTPulseRecoBase> const fThreshAlg;
316  std::unique_ptr<FWInterfacedPedAlgo> const fPedAlg;
317 
318  // --- END ---- Algorithms ---------------------------------------------------
319 
320  /// Optionally reads the beam gates from `fBeamGateTag`, empty if none.
321  std::vector<sim::BeamGateInfo const*> fetchBeamGates
322  (art::Event const& event) const;
323 
324  /// Returns a vector with copies of only the waveforms not in masked channels.
325  std::vector<raw::OpDetWaveform> selectWaveforms
326  (std::vector<raw::OpDetWaveform> const& waveforms) const;
327 
328 
329 }; // opdet::ICARUSOpHitFinder
330 
331 
332 // -----------------------------------------------------------------------------
333 // --- Implementation
334 // -----------------------------------------------------------------------------
335 // --- specializations
336 // -----------------------------------------------------------------------------
337 /// Framework interface to `pmtana::PedAlgoFixed`.
338 template <>
340  <pmtana::PedAlgoFixed, pmtana::PMTPedestalBase, ArtTraits>
342  <pmtana::PedAlgoFixed, pmtana::PMTPedestalBase, ArtTraits>
343 {
346 
347  public:
348  FWInterfaced(fhicl::ParameterSet const& pset): IFBase_t{ pset } {}
349 
350 
351  private:
352 
353  /// Declares the consumables.
354  virtual void doInitialize(typename IFBase_t::Module_t& module)
355  {
356  pmtana::PedAlgoFixed const& algo = *(IFBase_t::getAlgo());
357  module.template consumes<std::vector<raw::OpDetWaveform>>
358  (art::InputTag{ algo.waveformSourceName() });
359  module.template consumes<std::vector<icarus::WaveformBaseline>>
360  (art::InputTag{ algo.pedestalSourceName() });
361  module.template consumes<std::vector<icarus::WaveformRMS>>
362  (art::InputTag{ algo.pedestalRMSName() });
363  }
364 
365  /// Reads and reports to the algorithm the pedestals for this event.
366  virtual void doBeginEvent(typename IFBase_t::Event_t const& event)
367  {
368  pmtana::PedAlgoFixed& algo = *(IFBase_t::getAlgo());
369 
370  //
371  // collect the data
372  //
373  auto const& waveforms
374  = event.template getProduct<std::vector<raw::OpDetWaveform>>
375  (art::InputTag{ algo.waveformSourceName() });
376  auto const& pedSrc
377  = event.template getProduct<std::vector<icarus::WaveformBaseline>>
378  (art::InputTag{ algo.pedestalSourceName() });
379  auto const& rmsSrc
380  = event.template getProduct<std::vector<icarus::WaveformRMS>>
381  (art::InputTag{ algo.pedestalRMSName() });
382  assert(waveforms.size() == pedSrc.size());
383  assert(waveforms.size() == rmsSrc.size());
384 
385  //
386  // translate and store
387  //
388 
389  // event number as ID:
390  pmtana::PedAlgoFixed::InputSet_t inputSet { event.event() };
391 
392  inputSet.waveforms.reserve(waveforms.size());
394  waveforms.begin(), waveforms.end(), back_inserter(inputSet.waveforms),
395  [](auto& obj){ return &obj; }
396  );
397 
398  inputSet.pedestals.reserve(pedSrc.size());
400  pedSrc.begin(), pedSrc.end(), back_inserter(inputSet.pedestals),
402  );
403 
404  inputSet.RMSs.reserve(rmsSrc.size());
406  rmsSrc.begin(), rmsSrc.end(), back_inserter(inputSet.RMSs),
407  std::mem_fn(&icarus::WaveformRMS::RMS)
408  );
409 
410  algo.setParameters(std::move(inputSet));
411 
412  } // doBeginEvent()
413 
414  /// Clear the event information (just "safety").
415  virtual void doEndEvent(typename IFBase_t::Event_t const&)
416  { IFBase_t::getAlgo()->clearParameters(); }
417 
418 
419 }; // FWInterfaced<pmtana::PedAlgoFixed, pmtana::PMTPedestalBase>
420 
421 
422 // -----------------------------------------------------------------------------
423 namespace {
424 
425  /// Sorts in place and returns a vector.
426  template <typename T>
427  std::vector<T>& sortVector(std::vector<T>& v)
428  { std::sort(v.begin(), v.end()); return v; }
429 
430  /// Sorts and returns a copy of the vector.
431  template <typename T>
432  std::vector<T> sortedVector(std::vector<T> v)
433  { sortVector(v); return v; }
434 
435 
436  /**
437  * @brief A "smart" pointer that may or may not own its data.
438  * @tparam T type of the data to point to
439  *
440  * This pointer can be used when depending on a run-time condition a data set
441  * may come from an immutable, owning source (like `art::Event`) or from a
442  * local processing (e.g. a selection of the above).
443  *
444  * If initialized with a pointer to the data, this pointer will refer to it
445  * without owning; if initialized with a r-value (reference) to data, the data
446  * is stolen and owned from now on.
447  */
448  template <typename T>
449  class MaybeOwnerPtr {
450  public:
451  using element_type = T;
452  using pointer = T*;
453 
454  /// Points to the given pointer without owning it.
455  MaybeOwnerPtr(pointer ptr) noexcept: fStorage{ ptr } {}
456 
457  /// Steals the data and owns it.
458  MaybeOwnerPtr(element_type&& data): fStorage{ std::move(data) } {}
459 
460  pointer get() const { return std::visit(PointerGetter{}, fStorage); }
461 
462  pointer operator->() const { return get(); }
463  auto& operator*() const { return *(get()); }
464 
465  private:
466 
467  struct PointerGetter {
468  pointer operator() (pointer ptr) const noexcept { return ptr; }
469  pointer operator() (element_type& item) const noexcept { return &item; }
470  }; // PointerGetter
471 
472  using store_t = std::variant<element_type, pointer>;
473 
474  store_t fStorage; ///< Contains the data or pointer to it.
475 
476  }; // MaybeOwnerPtr
477 
478 
479 } // local namespace
480 
481 
482 // -----------------------------------------------------------------------------
484  (Parameters const& params, art::ProcessingFrame const& frame)
485  : art::ReplicatedProducer{ params, frame }
486  // configuration
487  , fWaveformTags{ params().InputModule() }
488  , fBeamGateTag{ params().GenModule().value_or(art::InputTag{}) }
489  , fChannelMasks{ sortedVector(params().ChannelMasks()) }
490  , fHitThreshold{ params().HitThreshold() }
491  , fUseStartTime{ params().UseStartTime() }
492  // caches
493  , fMaxOpChannel{ frame.serviceHandle<geo::Geometry>()->MaxOpChannel() }
494  // algorithms
495  , fPulseRecoMgr{}
496  , fThreshAlg
497  { HitAlgoFactory.create(params().HitAlgoPset.get<fhicl::ParameterSet>()) }
498  , fPedAlg
499  { PedAlgoFactory.create(params().PedAlgoPset.get<fhicl::ParameterSet>()) }
500 {
501 
502  //
503  // declaration of input
504  //
505  consumes<std::vector<raw::OpDetWaveform>>(fWaveformTags);
506  if (!fBeamGateTag.empty())
507  mayConsume<std::vector<sim::BeamGateInfo>>(fBeamGateTag);
508 
509  //
510  // calibration initialization
511  //
512  if (params().UseCalibrator()) {
513  fCalib = frame.serviceHandle<calib::IPhotonCalibratorService>()->provider();
514  }
515  else {
516  fMyCalib = std::make_unique<calib::PhotonCalibratorStandard>(
517  params().AreaToPE()
518  , params().SPEArea()
519  , params().SPEShift()
520  );
521  fCalib = fMyCalib.get();
522  } // if ... else
523 
524  //
525  // register the algorithms in the manager
526  //
527  fPulseRecoMgr.AddRecoAlgo(fThreshAlg.get());
528  fPulseRecoMgr.SetDefaultPedAlgo(&(fPedAlg->algo()));
529 
530  // framework hooks to the algorithms
531  if (!fChannelMasks.empty() && (fPedAlg->algo().Name() == "Fixed")) {
532  /* TODO
533  * The reason why this is not working is complicate.
534  * The interface of ophit mini-framework is quite minimal and tight,
535  * it accepts only `std::vector<short>` input and nothing more.
536  * The whole reason of this module is to overcome that limitation;
537  * since there is no channel information, we have to guess which channel
538  * this is the data of, and the way we do it is by address of the data;
539  * `raw::OpDetWaveform` derives from `std::vector<short>`, so when we use
540  * the original data product, the waveform data `std::vector<short>` is
541  * actually the same object and we can compare with the address of the data
542  * product, which we have because of the framework hooks here introduced;
543  * but if the `ChannelMasks` is not empty, we are forced to copy the
544  * original data in a new location (excluding the masked channels) and the
545  * new data has a different address. In principle we could still try to
546  * look for which `raw::OpDetWaveform` data product has the same content as
547  * the `std::vector<short>` we were given, which may be a bit tedious
548  * (thousand of vector comparisons to do, although all except the target one
549  * will be short because the noise pattern are different).
550  */
551  throw art::Exception{ art::errors::Configuration }
552  << "Pedestal algorithm \"Fixed\" will not work"
553  " since a channel mask list is specified.\n";
554  }
555  fPedAlg->initialize(consumesCollector());
556 
557  //
558  // declare output products
559  //
560  produces<std::vector<recob::OpHit>>();
561 
562 } // opdet::ICARUSOpHitFinder::ICARUSOpHitFinder()
563 
564 
565 //----------------------------------------------------------------------------
567  (art::Event& event, art::ProcessingFrame const& frame)
568 {
569 
570  //
571  // read and select the waveforms
572  //
573  auto const& allWaveforms
574  = event.getProduct<std::vector<raw::OpDetWaveform>>(fWaveformTags);
575 
576  // this pointer owns the waveforms only if they come from `selectWaveforms()`
577 // MaybeOwnerPtr<std::vector<raw::OpDetWaveform> const> waveforms
578 // = fChannelMasks.empty()? &allWaveforms: selectWaveforms(allWaveforms);
579  using WaveformsPtr_t = MaybeOwnerPtr<std::vector<raw::OpDetWaveform> const>;
580  WaveformsPtr_t waveforms = fChannelMasks.empty()
581  ? WaveformsPtr_t{ &allWaveforms }
582  : WaveformsPtr_t{ selectWaveforms(allWaveforms) }
583  ;
584 
585  if (fChannelMasks.empty() && (&allWaveforms != &*waveforms)) {
586  // if this happens, contact the author
587  throw art::Exception{ art::errors::LogicError }
588  << "Bug in MaybeOwnerPtr!\n";
589  }
590  assert(fChannelMasks.empty() || (&allWaveforms == &*waveforms));
591 
592  //
593  // run the algorithm
594  //
595 
596  // framework hooks to the algorithms
597  fPedAlg->beginEvent(event);
598 
599  std::vector<sim::BeamGateInfo const*> const beamGateArray
600  = fetchBeamGates(event);
601 
602  auto const& geom = *(frame.serviceHandle<geo::Geometry>()->provider());
603  auto const clockData
604  = frame.serviceHandle<detinfo::DetectorClocksService const>()
605  ->DataFor(event)
606  ;
607 
608  std::vector<recob::OpHit> opHits;
609 
610  RunHitFinder(
611  *waveforms, opHits,
612  fPulseRecoMgr, *fThreshAlg,
613  geom,
614  fHitThreshold,
615  clockData,
616  *fCalib,
617  fUseStartTime
618  );
619 
620  mf::LogInfo{ "ICARUSOpHitFinder" }
621  << "Found " << opHits.size() << " hits from " << waveforms->size()
622  << " waveforms.";
623 
624  // framework hooks to the algorithms
625  fPedAlg->endEvent(event);
626 
627  //
628  // store results into the event
629  //
630  event.put(std::make_unique<std::vector<recob::OpHit>>(std::move(opHits)));
631 
632 } // opdet::ICARUSOpHitFinder::produce()
633 
634 
635 //------------------------------------------------------------------------------
636 std::vector<sim::BeamGateInfo const*> opdet::ICARUSOpHitFinder::fetchBeamGates
637  (art::Event const& event) const
638 {
639  std::vector<const sim::BeamGateInfo*> beamGateArray;
640  if (fBeamGateTag.empty()) return beamGateArray;
641  try {
642  event.getView(fBeamGateTag, beamGateArray);
643  }
644  catch (art::Exception const& err) {
645  if (err.categoryCode() != art::errors::ProductNotFound) throw;
646  }
647  return beamGateArray;
648 } // opdet::ICARUSOpHitFinder::fetchBeamGates()
649 
650 
651 //----------------------------------------------------------------------------
652 std::vector<raw::OpDetWaveform> opdet::ICARUSOpHitFinder::selectWaveforms
653  (std::vector<raw::OpDetWaveform> const& waveforms) const
654 {
655  std::vector<raw::OpDetWaveform> selected;
656 
657  auto const isNotMasked = [this](raw::OpDetWaveform const& waveform)
658  {
659  return !std::binary_search
660  (fChannelMasks.begin(), fChannelMasks.end(), waveform.ChannelNumber());
661  };
662 
663  std::copy_if
664  (waveforms.begin(), waveforms.end(), back_inserter(selected), isNotMasked);
665 
666  return selected;
667 } // selectWaveforms()
668 
669 
670 // -----------------------------------------------------------------------------
671 DEFINE_ART_MODULE(opdet::ICARUSOpHitFinder)
672 
673 // -----------------------------------------------------------------------------
Algo_t & algo() const
Access to the algorithm.
unsigned int const fMaxOpChannel
Number of channels in the detector.
Token to register an algorithm, used in AlgorithmFactory.
bool const fUseStartTime
Whether to store start instead of peak time.
void setParameters(InputSet_t inputSet)
Records the current pedestals and RMS per channel.
Extracts PMT activity as optical hits (recob::OpHit).
Template type for the third parameter of FWInterfacedIF objects.
static constexpr Sample_t transform(Sample_t sample)
A baseline RMS for a waveform.
EResult err(const char *call)
Pedestal &quot;algorithm&quot; reading the pedestals from somewhere else.
Definition: PedAlgoFixed.h:64
BaselineRMS_t RMS() const
Definition: WaveformRMS.h:79
pmtana::PulseRecoManager fPulseRecoMgr
fhicl::OptionalAtom< art::InputTag > GenModule
std::unique_ptr< calib::IPhotonCalibrator > fMyCalib
Storage for our own calibration algorithm, if any.
virtual void doEndEvent(typename IFBase_t::Event_t const &)
Clear the event information (just &quot;safety&quot;).
virtual void doInitialize(typename IFBase_t::Module_t &module)
Declares the consumables.
calib::IPhotonCalibrator const * fCalib
The calibration algorithm to be used (not owned).
fhicl::Atom< art::InputTag > InputModule
fhicl::Sequence< raw::Channel_t > ChannelMasks
Utility and boilerplate for optical algorithms.
Pedestal &quot;algorithm&quot; reading the pedestals from somewhere else.
std::vector< pmtana::Waveform_t const * > waveforms
All the waveforms that are going to process.
Definition: PedAlgoFixed.h:73
Class definition file of PedAlgoRollingMean.
Class definition file of AlgoCFD.
Class definition file of PedAlgoUB.
art::ReplicatedProducer::Table< Config > Parameters
BEGIN_PROLOG vertical distance to the surface Name
float const fHitThreshold
Hit finding threshold.
The geometry of one entire detector, as served by art.
Definition: Geometry.h:181
ICARUSOpHitFinder(Parameters const &config, art::ProcessingFrame const &frame)
std::string const & pedestalSourceName() const
Returns the name of the configured pedestal source.
Definition: PedAlgoFixed.h:119
An algorithm factory class.
Class definition file of AlgoFixedWindow.
std::string const & waveformSourceName() const
Returns the name of the configured waveform source.
Definition: PedAlgoFixed.h:116
void RunHitFinder(std::vector< raw::OpDetWaveform > const &opDetWaveformVector, std::vector< recob::OpHit > &hitVector, pmtana::PulseRecoManager const &pulseRecoMgr, pmtana::PMTPulseRecoBase const &threshAlg, geo::GeometryCore const &geometry, float hitThreshold, detinfo::DetectorClocksData const &clocksData, calib::IPhotonCalibrator const &calibrator, bool use_start_time)
Definition: OpHitAlg.cxx:30
Class definition file of AlgoSlidingWindow.
Class definition file of AlgoThreshold.
Base class for specialization.
virtual void produce(art::Event &, art::ProcessingFrame const &) override
std::vector< unsigned int > const fChannelMasks
Sorted list of channels to skip.
std::vector< sim::BeamGateInfo const * > fetchBeamGates(art::Event const &event) const
Optionally reads the beam gates from fBeamGateTag, empty if none.
virtual void doBeginEvent(typename IFBase_t::Event_t const &event)
Reads and reports to the algorithm the pedestals for this event.
art::InputTag const fWaveformTags
Input PMT waveform data product tags.
Class definition file of PMTPulseRecoBase.
Class definition file of PedAlgoEdges.
std::vector< raw::OpDetWaveform > selectWaveforms(std::vector< raw::OpDetWaveform > const &waveforms) const
Returns a vector with copies of only the waveforms not in masked channels.
std::string const & pedestalRMSName() const
Returns the name of the configured RMS source.
Definition: PedAlgoFixed.h:122
std::unique_ptr< pmtana::PMTPulseRecoBase > const fThreshAlg
QuadExpr operator*(double v, const QuadExpr &e)
Definition: QuadExpr.h:39
art framework interface to geometry description
std::unique_ptr< FWInterfacedPedAlgo > const fPedAlg
fDetProps &fDetProps fDetProps &fDetProps consumesCollector())
Baseline_t baseline() const
Class definition file of PulseRecoManager.