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"
90 template <
typename Algo>
98 , Decl<FWIFPedAlgo<pmtana::PedAlgoEdges >>{
"Edges" }
99 , Decl<FWIFPedAlgo<pmtana::PedAlgoRollingMean>>{
"RollingMean"}
100 , Decl<FWIFPedAlgo<pmtana::PedAlgoUB >>{
"UB" }
101 , Decl<FWIFPedAlgo<pmtana::PedAlgoFixed >>{
"Fixed" }
114 namespace opdet {
class ICARUSOpHitFinder; }
210 Name{
"InputModule" },
211 Comment{
"Data product with the optical waveforms to process" }
216 Comment{
"Data product with the beam gates" }
220 Name{
"ChannelMasks" },
221 Comment{
"List of channels to skip [none by default]" },
222 std::vector<raw::Channel_t>{}
226 Name{
"HitThreshold" },
227 Comment{
"Hit reconstruction threshold [ADC#]" }
231 Name{
"UseStartTime" },
232 Comment{
"Store the start time instead of the peak time" },
237 Name{
"HitAlgoPset" },
239 "parameters of the hit finding algorithm."
240 " The parameters must include the algorithm \"Name\", one of: "
241 + HitAlgoFactory.names(
", ") +
"."
246 Name{
"PedAlgoPset" },
248 "parameters of the pedestal extraction algorithm."
249 " The parameters must include the algorithm \"Name\", one of: "
250 + PedAlgoFactory.names(
", ") +
"."
255 Name{
"UseCalibrator" },
256 Comment{
"Use the photon calibration service configured in the job" },
262 Comment{
"Whether the `SPEArea` parameter refers to area or amplitude" },
268 Comment{
"area or amplitude of PMT response to single photoelectron" },
274 Comment{
"shift on the single photoelectron response" },
283 (
Parameters const& config, art::ProcessingFrame
const& frame);
285 virtual void produce(art::Event&, art::ProcessingFrame
const&)
override;
300 std::unique_ptr<calib::IPhotonCalibrator>
fMyCalib;
316 std::unique_ptr<FWInterfacedPedAlgo>
const fPedAlg;
322 (art::Event
const& event)
const;
326 (std::vector<raw::OpDetWaveform>
const& waveforms)
const;
342 <pmtana::PedAlgoFixed, pmtana::PMTPedestalBase, ArtTraits>
357 module.template consumes<std::vector<raw::OpDetWaveform>>
359 module.template consumes<std::vector<icarus::WaveformBaseline>>
361 module.template consumes<std::vector<icarus::WaveformRMS>>
373 auto const& waveforms
374 =
event.template getProduct<std::vector<raw::OpDetWaveform>>
377 =
event.template getProduct<std::vector<icarus::WaveformBaseline>>
380 =
event.template getProduct<std::vector<icarus::WaveformRMS>>
382 assert(waveforms.size() == pedSrc.size());
383 assert(waveforms.size() == rmsSrc.size());
392 inputSet.
waveforms.reserve(waveforms.size());
394 waveforms.begin(), waveforms.end(), back_inserter(inputSet.waveforms),
395 [](
auto& obj){
return &obj; }
398 inputSet.pedestals.reserve(pedSrc.size());
400 pedSrc.begin(), pedSrc.end(), back_inserter(inputSet.pedestals),
404 inputSet.RMSs.reserve(rmsSrc.size());
406 rmsSrc.begin(), rmsSrc.end(), back_inserter(inputSet.RMSs),
416 { IFBase_t::getAlgo()->clearParameters(); }
426 template <
typename T>
427 std::vector<T>& sortVector(std::vector<T>& v)
428 { std::sort(v.begin(), v.end());
return v; }
431 template <
typename T>
432 std::vector<T> sortedVector(std::vector<T> v)
433 { sortVector(v);
return v; }
448 template <
typename T>
449 class MaybeOwnerPtr {
451 using element_type = T;
455 MaybeOwnerPtr(pointer ptr) noexcept: fStorage{ ptr } {}
458 MaybeOwnerPtr(element_type&& data): fStorage{ std::move(data) } {}
460 pointer
get()
const {
return std::visit(PointerGetter{}, fStorage); }
462 pointer operator->()
const {
return get(); }
463 auto&
operator*()
const {
return *(
get()); }
467 struct PointerGetter {
468 pointer operator() (pointer ptr)
const noexcept {
return ptr; }
469 pointer operator() (element_type& item)
const noexcept {
return &item; }
472 using store_t = std::variant<element_type, pointer>;
484 (
Parameters const& params, art::ProcessingFrame
const& frame)
485 : art::ReplicatedProducer{ params, frame }
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() }
493 , fMaxOpChannel{ frame.serviceHandle<
geo::Geometry>()->MaxOpChannel() }
497 { HitAlgoFactory.create(params().HitAlgoPset.get<fhicl::ParameterSet>()) }
499 { PedAlgoFactory.create(params().PedAlgoPset.get<fhicl::ParameterSet>()) }
505 consumes<std::vector<raw::OpDetWaveform>>(fWaveformTags);
506 if (!fBeamGateTag.empty())
507 mayConsume<std::vector<sim::BeamGateInfo>>(fBeamGateTag);
512 if (params().UseCalibrator()) {
516 fMyCalib = std::make_unique<calib::PhotonCalibratorStandard>(
519 , params().SPEShift()
521 fCalib = fMyCalib.get();
527 fPulseRecoMgr.AddRecoAlgo(fThreshAlg.get());
528 fPulseRecoMgr.SetDefaultPedAlgo(&(fPedAlg->algo()));
531 if (!fChannelMasks.empty() && (fPedAlg->algo().Name() ==
"Fixed")) {
551 throw art::Exception{ art::errors::Configuration }
552 <<
"Pedestal algorithm \"Fixed\" will not work"
553 " since a channel mask list is specified.\n";
560 produces<std::vector<recob::OpHit>>();
567 (art::Event& event, art::ProcessingFrame
const& frame)
573 auto const& allWaveforms
574 =
event.getProduct<std::vector<raw::OpDetWaveform>>(fWaveformTags);
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) }
585 if (fChannelMasks.empty() && (&allWaveforms != &*waveforms)) {
587 throw art::Exception{ art::errors::LogicError }
588 <<
"Bug in MaybeOwnerPtr!\n";
590 assert(fChannelMasks.empty() || (&allWaveforms == &*waveforms));
597 fPedAlg->beginEvent(event);
599 std::vector<sim::BeamGateInfo const*>
const beamGateArray
600 = fetchBeamGates(event);
602 auto const& geom = *(frame.serviceHandle<
geo::Geometry>()->provider());
608 std::vector<recob::OpHit> opHits;
612 fPulseRecoMgr, *fThreshAlg,
620 mf::LogInfo{
"ICARUSOpHitFinder" }
621 <<
"Found " << opHits.size() <<
" hits from " << waveforms->size()
625 fPedAlg->endEvent(event);
630 event.put(std::make_unique<std::vector<recob::OpHit>>(std::move(opHits)));
637 (art::Event
const& event)
const
639 std::vector<const sim::BeamGateInfo*> beamGateArray;
640 if (fBeamGateTag.empty())
return beamGateArray;
642 event.getView(fBeamGateTag, beamGateArray);
644 catch (art::Exception
const&
err) {
645 if (err.categoryCode() != art::errors::ProductNotFound)
throw;
647 return beamGateArray;
653 (std::vector<raw::OpDetWaveform>
const& waveforms)
const
655 std::vector<raw::OpDetWaveform> selected;
659 return !std::binary_search
660 (fChannelMasks.begin(), fChannelMasks.end(), waveform.ChannelNumber());
664 (waveforms.begin(), waveforms.end(), back_inserter(selected), isNotMasked);
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.
EResult err(const char *call)
Pedestal "algorithm" reading the pedestals from somewhere else.
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 "safety").
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
typename ArtTraits::Module_t Module_t
fhicl::Sequence< raw::Channel_t > ChannelMasks
Utility and boilerplate for optical algorithms.
FWInterfaced(fhicl::ParameterSet const &pset)
Pedestal "algorithm" reading the pedestals from somewhere else.
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.
fhicl::Atom< bool > UseCalibrator
typename ArtTraits::Event_t Event_t
ICARUSOpHitFinder(Parameters const &config, art::ProcessingFrame const &frame)
std::string const & pedestalSourceName() const
Returns the name of the configured pedestal source.
art::InputTag const fBeamGateTag
fhicl::Atom< float > HitThreshold
An algorithm factory class.
Class definition file of AlgoFixedWindow.
std::string const & waveformSourceName() const
Returns the name of the configured waveform source.
fhicl::Atom< bool > AreaToPE
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)
fhicl::DelegatedParameter PedAlgoPset
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.
std::unique_ptr< pmtana::PMTPulseRecoBase > const fThreshAlg
QuadExpr operator*(double v, const QuadExpr &e)
fhicl::DelegatedParameter HitAlgoPset
art framework interface to geometry description
std::unique_ptr< FWInterfacedPedAlgo > const fPedAlg
Class definition file of PulseRecoManager.
fhicl::Atom< float > SPEArea
fhicl::Atom< bool > UseStartTime
fhicl::Atom< float > SPEShift