All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
opdet::ICARUSOpHitFinder Class Reference

Extracts PMT activity as optical hits (recob::OpHit). More...

Inheritance diagram for opdet::ICARUSOpHitFinder:

Classes

struct  Config
 

Public Types

using Parameters = art::ReplicatedProducer::Table< Config >
 

Public Member Functions

 ICARUSOpHitFinder (Parameters const &config, art::ProcessingFrame const &frame)
 
virtual void produce (art::Event &, art::ProcessingFrame const &) override
 

Private Types

using FWInterfacedPedAlgo = opdet::factory::FWInterfacedIF< pmtana::PMTPedestalBase, ArtTraits >
 

Private Member Functions

std::vector< sim::BeamGateInfo
const * > 
fetchBeamGates (art::Event const &event) const
 Optionally reads the beam gates from fBeamGateTag, empty if none. More...
 
std::vector< raw::OpDetWaveformselectWaveforms (std::vector< raw::OpDetWaveform > const &waveforms) const
 Returns a vector with copies of only the waveforms not in masked channels. More...
 

Private Attributes

art::InputTag const fWaveformTags
 Input PMT waveform data product tags. More...
 
art::InputTag const fBeamGateTag
 
std::vector< unsigned int > const fChannelMasks
 Sorted list of channels to skip. More...
 
float const fHitThreshold
 Hit finding threshold. More...
 
bool const fUseStartTime
 Whether to store start instead of peak time. More...
 
std::unique_ptr
< calib::IPhotonCalibrator
fMyCalib
 Storage for our own calibration algorithm, if any. More...
 
unsigned int const fMaxOpChannel
 Number of channels in the detector. More...
 
calib::IPhotonCalibrator const * fCalib = nullptr
 The calibration algorithm to be used (not owned). More...
 
pmtana::PulseRecoManager fPulseRecoMgr
 
std::unique_ptr
< pmtana::PMTPulseRecoBase >
const 
fThreshAlg
 
std::unique_ptr
< FWInterfacedPedAlgo > const 
fPedAlg
 

Detailed Description

Extracts PMT activity as optical hits (recob::OpHit).

This module runs hit-finding algorithms, and is tailored to allow for an update of the hit finding parameters event by event.

Motivation

This module is a branch of the standard LArSoft opdet::OpHitFinder by Gleb Sinev, Ben Jones and others. That module itself is an interface to the hit finding mini-framework also in larana, authored by Kazuhiro Terao.

That framework independently analyzes each waveform and performs hit finding using general timing and geometry information (from detinfo::DetectorClocks and geo::GeometryCore service providers), a threshold parameter and configurable algorithms for baseline evaluation, hit finding and calibration.

It is believed that the baseline of ICARUS PMT is remarkably stable in the short time, and it is conceivable to use a single steady value for many waveforms on each channel. Unfortunately the existing module is not suitable for a baseline that may change event by event or in time: the mini-framework does not explicitly allow this, and the module is not equipped with the necessary workarounds.

This module is a replica of LArSoft's, with the additional workarounds needed to allow for a baseline learnt from an external source and changing event by event.

Configuration parameters

The configuration parameters are intentionally left the same as in opdet::OpHitFinder, with a few exceptions and additions where needed.

Noticeable differences with LArSoft's opdet::OpHitFinder configuration:

Multithreading

In order to support the algorithms that require an event-specific configuration, the module is not shared. While the algorithms could be written to keep track of different event configurations, at the time the algorithms are executed on a waveform they have no mean to know which event the waveforms belong to. Rather than writing complex workarounds on this problem, the module is replicated so that there are multiple algorithms (and multiple managers) but each of them sees an event at a time, in a way that the module (replica) can predict.

Definition at line 202 of file ICARUSOpHitFinder_module.cc.

Member Typedef Documentation

Definition at line 312 of file ICARUSOpHitFinder_module.cc.

using opdet::ICARUSOpHitFinder::Parameters = art::ReplicatedProducer::Table<Config>

Definition at line 280 of file ICARUSOpHitFinder_module.cc.

Constructor & Destructor Documentation

opdet::ICARUSOpHitFinder::ICARUSOpHitFinder ( Parameters const &  config,
art::ProcessingFrame const &  frame 
)
explicit

Definition at line 484 of file ICARUSOpHitFinder_module.cc.

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  //
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()
unsigned int const fMaxOpChannel
Number of channels in the detector.
bool const fUseStartTime
Whether to store start instead of peak time.
pmtana::PulseRecoManager fPulseRecoMgr
std::unique_ptr< calib::IPhotonCalibrator > fMyCalib
Storage for our own calibration algorithm, if any.
void AddRecoAlgo(pmtana::PMTPulseRecoBase *algo, PMTPedestalBase *ped_algo=nullptr)
A method to set pulse reconstruction algorithm.
calib::IPhotonCalibrator const * fCalib
The calibration algorithm to be used (not owned).
float const fHitThreshold
Hit finding threshold.
The geometry of one entire detector, as served by art.
Definition: Geometry.h:181
void SetDefaultPedAlgo(pmtana::PMTPedestalBase *algo)
A method to set a choice of pedestal estimation method.
std::vector< unsigned int > const fChannelMasks
Sorted list of channels to skip.
art::InputTag const fWaveformTags
Input PMT waveform data product tags.
std::unique_ptr< pmtana::PMTPulseRecoBase > const fThreshAlg
std::unique_ptr< FWInterfacedPedAlgo > const fPedAlg
fDetProps &fDetProps fDetProps &fDetProps consumesCollector())

Member Function Documentation

std::vector< sim::BeamGateInfo const * > opdet::ICARUSOpHitFinder::fetchBeamGates ( art::Event const &  event) const
private

Optionally reads the beam gates from fBeamGateTag, empty if none.

Definition at line 637 of file ICARUSOpHitFinder_module.cc.

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()
EResult err(const char *call)
void opdet::ICARUSOpHitFinder::produce ( art::Event &  event,
art::ProcessingFrame const &  frame 
)
overridevirtual

Definition at line 567 of file ICARUSOpHitFinder_module.cc.

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,
613  geom,
615  clockData,
616  *fCalib,
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()
bool const fUseStartTime
Whether to store start instead of peak time.
pmtana::PulseRecoManager fPulseRecoMgr
calib::IPhotonCalibrator const * fCalib
The calibration algorithm to be used (not owned).
float const fHitThreshold
Hit finding threshold.
The geometry of one entire detector, as served by art.
Definition: Geometry.h:181
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
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.
art::InputTag const fWaveformTags
Input PMT waveform data product tags.
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::unique_ptr< pmtana::PMTPulseRecoBase > const fThreshAlg
std::unique_ptr< FWInterfacedPedAlgo > const fPedAlg
std::vector< raw::OpDetWaveform > opdet::ICARUSOpHitFinder::selectWaveforms ( std::vector< raw::OpDetWaveform > const &  waveforms) const
private

Returns a vector with copies of only the waveforms not in masked channels.

Definition at line 653 of file ICARUSOpHitFinder_module.cc.

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()
std::vector< unsigned int > const fChannelMasks
Sorted list of channels to skip.

Member Data Documentation

art::InputTag const opdet::ICARUSOpHitFinder::fBeamGateTag
private

Data product with beam gates.

Definition at line 291 of file ICARUSOpHitFinder_module.cc.

calib::IPhotonCalibrator const* opdet::ICARUSOpHitFinder::fCalib = nullptr
private

The calibration algorithm to be used (not owned).

Definition at line 305 of file ICARUSOpHitFinder_module.cc.

std::vector<unsigned int> const opdet::ICARUSOpHitFinder::fChannelMasks
private

Sorted list of channels to skip.

Definition at line 293 of file ICARUSOpHitFinder_module.cc.

float const opdet::ICARUSOpHitFinder::fHitThreshold
private

Hit finding threshold.

Definition at line 294 of file ICARUSOpHitFinder_module.cc.

unsigned int const opdet::ICARUSOpHitFinder::fMaxOpChannel
private

Number of channels in the detector.

Definition at line 302 of file ICARUSOpHitFinder_module.cc.

std::unique_ptr<calib::IPhotonCalibrator> opdet::ICARUSOpHitFinder::fMyCalib
private

Storage for our own calibration algorithm, if any.

Definition at line 300 of file ICARUSOpHitFinder_module.cc.

std::unique_ptr<FWInterfacedPedAlgo> const opdet::ICARUSOpHitFinder::fPedAlg
private

Definition at line 316 of file ICARUSOpHitFinder_module.cc.

pmtana::PulseRecoManager opdet::ICARUSOpHitFinder::fPulseRecoMgr
private

Definition at line 314 of file ICARUSOpHitFinder_module.cc.

std::unique_ptr<pmtana::PMTPulseRecoBase> const opdet::ICARUSOpHitFinder::fThreshAlg
private

Definition at line 315 of file ICARUSOpHitFinder_module.cc.

bool const opdet::ICARUSOpHitFinder::fUseStartTime
private

Whether to store start instead of peak time.

Definition at line 295 of file ICARUSOpHitFinder_module.cc.

art::InputTag const opdet::ICARUSOpHitFinder::fWaveformTags
private

Input PMT waveform data product tags.

Definition at line 290 of file ICARUSOpHitFinder_module.cc.


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