diff --git a/CMakeLists.txt b/CMakeLists.txt index 542265963..7bcca8fe0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ find_package(ifdhc REQUIRED ) find_package(ifdh_art REQUIRED ) find_package(Range-v3 REQUIRED ) find_package(sbnobj REQUIRED ) +find_package(sbnalg REQUIRED ) find_package(icarus_signal_processing REQUIRED ) find_package(icarusalg REQUIRED ) find_package(icarusutil REQUIRED ) diff --git a/icaruscode/PMT/Trigger/LVDSgates_module.cc b/icaruscode/PMT/Trigger/LVDSgates_module.cc index fd447d73f..04ca63185 100644 --- a/icaruscode/PMT/Trigger/LVDSgates_module.cc +++ b/icaruscode/PMT/Trigger/LVDSgates_module.cc @@ -192,9 +192,9 @@ class icarus::trigger::LVDSgates: public art::EDProducer { { ComboMode::OR, "OR" } }; - fhicl::OptionalAtom TriggerGatesTag { + fhicl::OptionalAtom TriggerGatesTag { Name("TriggerGatesTag"), - Comment("label of trigger gate extraction module (no instance name)") + Comment("tag of trigger gate extraction module (no instance name)") }; fhicl::Sequence Thresholds { @@ -386,11 +386,11 @@ class icarus::trigger::LVDSgates: public art::EDProducer { /// Converts a threshold string into an input tag. static art::InputTag makeTag - (std::string const& thresholdStr, std::string const& defModule); + (std::string const& thresholdStr, art::InputTag const& defModule); /// Converts an input tag into an instance name for the corresponding output. static std::string makeOutputInstanceName - (art::InputTag const& inputTag, std::string const& defModule); + (art::InputTag const& inputTag, art::InputTag const& defModule); }; // class icarus::trigger::LVDSgates @@ -412,11 +412,11 @@ icarus::trigger::LVDSgates::LVDSgates // // more complex parameter parsing // - std::string const discrModuleLabel = config().TriggerGatesTag().value_or(""); + art::InputTag const discrModuleTag = config().TriggerGatesTag().value_or(""); for (std::string const& thresholdStr: config().Thresholds()) { - art::InputTag const inputTag = makeTag(thresholdStr, discrModuleLabel); + art::InputTag const inputTag = makeTag(thresholdStr, discrModuleTag); fADCthresholds[thresholdStr] - = { inputTag, makeOutputInstanceName(inputTag, discrModuleLabel) }; + = { inputTag, makeOutputInstanceName(inputTag, discrModuleTag) }; } // for all thresholds // @@ -863,34 +863,38 @@ auto icarus::trigger::LVDSgates::ReadTriggerGates( //------------------------------------------------------------------------------ art::InputTag icarus::trigger::LVDSgates::makeTag - (std::string const& thresholdStr, std::string const& defModule) + (std::string const& thresholdStr, art::InputTag const& defModule) { auto const isNumber = [pattern=std::regex{ "[+-]?[0-9]+" }] (std::string const& s) -> bool { return std::regex_match(s, pattern); }; - return + if (!thresholdStr.empty() && !defModule.instance().empty()) { + throw art::Exception(art::errors::Configuration) + << "Both the input gate module tag instance name (`TriggerGatesTag`: '" + << defModule.encode() << "') and the threshold '" << thresholdStr + << "' are set. One of them must be empty.\n"; + } + return ((thresholdStr.find(':') != std::string::npos) || !isNumber(thresholdStr)) ? art::InputTag{ thresholdStr } - : defModule.empty() + : defModule.label().empty() ? throw (art::Exception(art::errors::Configuration) << "No default module label (`TriggerGatesTag`) specified" - ", and it's needed for threshold '" - << thresholdStr << "'.\n") - : art::InputTag{ defModule, thresholdStr } + ", and it's needed for threshold '" << thresholdStr << "'.\n") + : art::InputTag{ defModule.label(), thresholdStr, defModule.process() } ; } // icarus::trigger::LVDSgates::makeTag() //------------------------------------------------------------------------------ std::string icarus::trigger::LVDSgates::makeOutputInstanceName - (art::InputTag const& inputTag, std::string const& defModule) + (art::InputTag const& inputTag, art::InputTag const& defModule) { - return (inputTag.label() == defModule) + return (inputTag.label() == defModule.label()) ? inputTag.instance() - : inputTag.instance().empty() - ? inputTag.label(): inputTag.label() + inputTag.instance() + : inputTag.label() + inputTag.instance() ; -} // icarus::trigger::LVDSgates::makeTag() +} // icarus::trigger::LVDSgates::makeOutputInstanceName() //------------------------------------------------------------------------------ diff --git a/icaruscode/PMT/Trigger/MajorityTriggerSimulation_module.cc b/icaruscode/PMT/Trigger/MajorityTriggerSimulation_module.cc index aae0c544d..fb43c4435 100644 --- a/icaruscode/PMT/Trigger/MajorityTriggerSimulation_module.cc +++ b/icaruscode/PMT/Trigger/MajorityTriggerSimulation_module.cc @@ -359,9 +359,9 @@ class icarus::trigger::MajorityTriggerSimulation using Name = fhicl::Name; using Comment = fhicl::Comment; - fhicl::Atom TriggerGatesTag { + fhicl::Atom TriggerGatesTag { Name("TriggerGatesTag"), - Comment("label of the input trigger gate data product (no instance name)") + Comment("tag of the input trigger gate data product") }; fhicl::Sequence Thresholds { @@ -597,6 +597,11 @@ class icarus::trigger::MajorityTriggerSimulation //@} + /// Returns `defModule` with instance name replaced by `thresholdStr`. + static art::InputTag makeTag + (art::InputTag const& defModule, std::string const& thresholdStr); + + }; // icarus::trigger::MajorityTriggerSimulation @@ -629,10 +634,10 @@ icarus::trigger::MajorityTriggerSimulation::MajorityTriggerSimulation // // more complex parameter parsing // - std::string const discrModuleLabel = config().TriggerGatesTag(); + art::InputTag const& discrModuleTag = config().TriggerGatesTag(); for (raw::ADC_Count_t threshold: config().Thresholds()) { fADCthresholds[icarus::trigger::ADCCounts_t{threshold}] - = art::InputTag{ discrModuleLabel, util::to_string(threshold) }; + = makeTag(discrModuleTag, util::to_string(threshold)); } // initialization of a vector of atomic is not as trivial as it sounds... @@ -943,6 +948,20 @@ icarus::trigger::MajorityTriggerSimulation::triggerInfoToTriggerData } // icarus::trigger::MajorityTriggerSimulation::triggerInfoToTriggerData() +//------------------------------------------------------------------------------ +art::InputTag icarus::trigger::MajorityTriggerSimulation::makeTag + (art::InputTag const& defModule, std::string const& thresholdStr) +{ + if (!thresholdStr.empty() && !defModule.instance().empty()) { + throw art::Exception(art::errors::Configuration) + << "Module tag instance name (`TriggerGatesTag`: '" + << defModule.encode() << "') and the threshold '" << thresholdStr + << "' are both set. One of them must be empty.\n"; + } + return { defModule.label(), thresholdStr, defModule.process() }; +} // icarus::trigger::MajorityTriggerSimulation::makeTag() + + //------------------------------------------------------------------------------ DEFINE_ART_MODULE(icarus::trigger::MajorityTriggerSimulation) diff --git a/icaruscode/PMT/Trigger/SlidingWindowTriggerSimulation_module.cc b/icaruscode/PMT/Trigger/SlidingWindowTriggerSimulation_module.cc index f95638ca3..f356090f7 100644 --- a/icaruscode/PMT/Trigger/SlidingWindowTriggerSimulation_module.cc +++ b/icaruscode/PMT/Trigger/SlidingWindowTriggerSimulation_module.cc @@ -285,9 +285,9 @@ class icarus::trigger::SlidingWindowTriggerSimulation using Name = fhicl::Name; using Comment = fhicl::Comment; - fhicl::Atom TriggerGatesTag { + fhicl::Atom TriggerGatesTag { Name("TriggerGatesTag"), - Comment("label of the input trigger gate data product (no instance name)") + Comment("tag of the input trigger gate data product (no instance name)") }; fhicl::Sequence Thresholds { @@ -573,7 +573,12 @@ class icarus::trigger::SlidingWindowTriggerSimulation static double eventTimestampInSeconds(art::Timestamp const& time); static double eventTimestampInSeconds(art::Event const& event); //@} - + + + /// Returns `defModule` with instance name replaced by `thresholdStr`. + static art::InputTag makeTag + (art::InputTag const& defModule, std::string const& thresholdStr); + }; // icarus::trigger::SlidingWindowTriggerSimulation @@ -622,9 +627,9 @@ icarus::trigger::SlidingWindowTriggerSimulation::SlidingWindowTriggerSimulation // // more complex parameter parsing // - std::string const& discrModuleLabel = config().TriggerGatesTag(); + art::InputTag const& discrModuleTag = config().TriggerGatesTag(); for (std::string const& threshold: config().Thresholds()) - fADCthresholds[threshold] = art::InputTag{ discrModuleLabel, threshold }; + fADCthresholds[threshold] = makeTag(discrModuleTag, threshold); // initialization of a vector of atomic is not as trivial as it sounds... fTriggerCount = std::vector>(fADCthresholds.size()); @@ -1204,6 +1209,20 @@ double icarus::trigger::SlidingWindowTriggerSimulation::eventTimestampInSeconds { return eventTimestampInSeconds(event.time()); } +//------------------------------------------------------------------------------ +art::InputTag icarus::trigger::SlidingWindowTriggerSimulation::makeTag + (art::InputTag const& defModule, std::string const& thresholdStr) +{ + if (!thresholdStr.empty() && !defModule.instance().empty()) { + throw art::Exception(art::errors::Configuration) + << "Module tag instance name (`TriggerGatesTag`: '" + << defModule.encode() << "') and the threshold '" << thresholdStr + << "' are both set. One of them must be empty.\n"; + } + return { defModule.label(), thresholdStr, defModule.process() }; +} // icarus::trigger::SlidingWindowTriggerSimulation::makeTag() + + //------------------------------------------------------------------------------ DEFINE_ART_MODULE(icarus::trigger::SlidingWindowTriggerSimulation) diff --git a/icaruscode/PMT/Trigger/SlidingWindowTrigger_module.cc b/icaruscode/PMT/Trigger/SlidingWindowTrigger_module.cc index ad4e36dd4..4c19ff057 100644 --- a/icaruscode/PMT/Trigger/SlidingWindowTrigger_module.cc +++ b/icaruscode/PMT/Trigger/SlidingWindowTrigger_module.cc @@ -226,9 +226,9 @@ class icarus::trigger::SlidingWindowTrigger: public art::EDProducer { using Comment = fhicl::Comment; - fhicl::Atom TriggerGatesTag { + fhicl::Atom TriggerGatesTag { Name("TriggerGatesTag"), - Comment("label of the input trigger gate data product (no instance name)") + Comment("tag of the input trigger gate data product (no instance name)") }; fhicl::Sequence Thresholds { @@ -385,6 +385,9 @@ class icarus::trigger::SlidingWindowTrigger: public art::EDProducer { art::Assns const& assns ); + static art::InputTag makeTag + (art::InputTag const& defModule, std::string const& thresholdStr); + }; // class icarus::trigger::SlidingWindowTrigger @@ -435,9 +438,9 @@ icarus::trigger::SlidingWindowTrigger::SlidingWindowTrigger // // more complex parameter parsing // - std::string const discrModuleLabel = config().TriggerGatesTag(); + art::InputTag const& discrModuleTag = config().TriggerGatesTag(); for (std::string const& threshold: config().Thresholds()) - fADCthresholds[threshold] = art::InputTag{ discrModuleLabel, threshold }; + fADCthresholds[threshold] = makeTag(discrModuleTag, threshold); // // configuration report (short) @@ -668,6 +671,21 @@ auto icarus::trigger::SlidingWindowTrigger::ReadTriggerGates( } // icarus::trigger::SlidingWindowTrigger::ReadTriggerGates() + +//------------------------------------------------------------------------------ +art::InputTag icarus::trigger::SlidingWindowTrigger::makeTag + (art::InputTag const& defModule, std::string const& thresholdStr) +{ + if (!thresholdStr.empty() && !defModule.instance().empty()) { + throw art::Exception(art::errors::Configuration) + << "Module tag instance name (`TriggerGatesTag`: '" + << defModule.encode() << "') and the threshold '" << thresholdStr + << "' are both set. One of them must be empty.\n"; + } + return { defModule.label(), thresholdStr, defModule.process() }; +} // icarus::trigger::SlidingWindowTrigger::makeTag() + + //------------------------------------------------------------------------------ DEFINE_ART_MODULE(icarus::trigger::SlidingWindowTrigger) diff --git a/icaruscode/PMT/Trigger/TriggerEfficiencyPlotsBase.cxx b/icaruscode/PMT/Trigger/TriggerEfficiencyPlotsBase.cxx index b423ecc66..f769f0c6b 100644 --- a/icaruscode/PMT/Trigger/TriggerEfficiencyPlotsBase.cxx +++ b/icaruscode/PMT/Trigger/TriggerEfficiencyPlotsBase.cxx @@ -531,9 +531,9 @@ icarus::trigger::TriggerEfficiencyPlotsBase::TriggerEfficiencyPlotsBase if (fLogEventDetails.empty()) fLogEventDetails = fLogCategory; } // if EventDetailsLogCategory is specified - std::string const discrModuleLabel = config.TriggerGatesTag(); + art::InputTag const& discrModuleTag = config.TriggerGatesTag(); for (std::string const& threshold: config.Thresholds()) - fADCthresholds[threshold] = art::InputTag{ discrModuleLabel, threshold }; + fADCthresholds[threshold] = makeInputTag(discrModuleTag, threshold); if (config.EventTreeName.hasValue()) { @@ -1497,4 +1497,18 @@ icarus::trigger::TriggerEfficiencyPlotsBase::makeEdepTag( } // icarus::trigger::MakeTriggerSimulationTree::makeEdepTag() +//------------------------------------------------------------------------------ +art::InputTag icarus::trigger::TriggerEfficiencyPlotsBase::makeInputTag + (art::InputTag const& defModule, std::string const& thresholdStr) +{ + if (!thresholdStr.empty() && !defModule.instance().empty()) { + throw art::Exception(art::errors::Configuration) + << "Module tag instance name (`TriggerGatesTag`: '" + << defModule.encode() << "') and the threshold '" << thresholdStr + << "' are both set. One of them must be empty.\n"; + } + return { defModule.label(), thresholdStr, defModule.process() }; +} // icarus::trigger::TriggerEfficiencyPlotsBase::makeInputTag() + + //------------------------------------------------------------------------------ diff --git a/icaruscode/PMT/Trigger/TriggerEfficiencyPlotsBase.h b/icaruscode/PMT/Trigger/TriggerEfficiencyPlotsBase.h index 7741cd726..69b1913a8 100644 --- a/icaruscode/PMT/Trigger/TriggerEfficiencyPlotsBase.h +++ b/icaruscode/PMT/Trigger/TriggerEfficiencyPlotsBase.h @@ -222,7 +222,7 @@ class icarus::trigger::details::TriggerPassCounters { /// Registers a new pattern in the index and returns its index (unchecked). std::size_t registerPattern(std::string const& name); - + }; // icarus::trigger::details::TriggerPassCounters @@ -1010,9 +1010,9 @@ class icarus::trigger::TriggerEfficiencyPlotsBase { Comment("label of energy deposition summary data product") }; - fhicl::Atom TriggerGatesTag { + fhicl::Atom TriggerGatesTag { Name("TriggerGatesTag"), - Comment("label of the input trigger gate data product (no instance name)") + Comment("tag of the input trigger gate data product (no instance name)") }; fhicl::Sequence Thresholds { @@ -1565,6 +1565,10 @@ class icarus::trigger::TriggerEfficiencyPlotsBase { fhicl::OptionalAtom const& EnergyDepositSummaryTag ); + /// Returns `defModule` with instance name replaced by `thresholdStr`. + static art::InputTag makeInputTag + (art::InputTag const& defModule, std::string const& thresholdStr); + }; // icarus::trigger::TriggerEfficiencyPlotsBase diff --git a/icaruscode/PMT/Trigger/TriggerEfficiencyPlots_module.cc b/icaruscode/PMT/Trigger/TriggerEfficiencyPlots_module.cc index 6c47661b9..970dc31b8 100644 --- a/icaruscode/PMT/Trigger/TriggerEfficiencyPlots_module.cc +++ b/icaruscode/PMT/Trigger/TriggerEfficiencyPlots_module.cc @@ -1246,9 +1246,9 @@ class icarus::trigger::TriggerEfficiencyPlots: public art::EDAnalyzer { std::vector{ "largeant:TPCActive" } }; - fhicl::Atom TriggerGatesTag { + fhicl::Atom TriggerGatesTag { Name("TriggerGatesTag"), - Comment("label of the input trigger gate data product (no instance name)") + Comment("tag of the input trigger gate data product (no instance name)") }; fhicl::Sequence Thresholds { @@ -1496,6 +1496,11 @@ class icarus::trigger::TriggerEfficiencyPlots: public art::EDAnalyzer { /// Returns a gate that is `Max()` of all the specified `gates`. template static auto computeMaxGate(TrigGateColl const& gates); + + + /// Returns `defModule` with instance name replaced by `thresholdStr`. + static art::InputTag makeTag + (art::InputTag const& defModule, std::string const& thresholdStr); }; // icarus::trigger::TriggerEfficiencyPlots @@ -1533,10 +1538,10 @@ icarus::trigger::TriggerEfficiencyPlots::TriggerEfficiencyPlots if (fLogEventDetails.empty()) fLogEventDetails = fLogCategory; } // if EventDetailsLogCategory is specified - std::string const discrModuleLabel = config().TriggerGatesTag(); + art::InputTag const& discrModuleTag = config().TriggerGatesTag(); for (raw::ADC_Count_t threshold: config().Thresholds()) { fADCthresholds[icarus::trigger::ADCCounts_t{threshold}] - = art::InputTag{ discrModuleLabel, util::to_string(threshold) }; + = makeTag(discrModuleTag, util::to_string(threshold)); } if (config().EventTreeName.hasValue()) { @@ -2467,6 +2472,20 @@ auto icarus::trigger::TriggerEfficiencyPlots::ReadTriggerGates } // icarus::trigger::TriggerEfficiencyPlots::ReadTriggerGates() +//------------------------------------------------------------------------------ +art::InputTag icarus::trigger::TriggerEfficiencyPlots::makeTag + (art::InputTag const& defModule, std::string const& thresholdStr) +{ + if (!thresholdStr.empty() && !defModule.instance().empty()) { + throw art::Exception(art::errors::Configuration) + << "Module tag instance name (`TriggerGatesTag`: '" + << defModule.encode() << "') and the threshold '" << thresholdStr + << "' are both set. One of them must be empty.\n"; + } + return { defModule.label(), thresholdStr, defModule.process() }; +} // icarus::trigger::TriggerEfficiencyPlots::makeTag() + + //------------------------------------------------------------------------------ //--- EventIDTree //------------------------------------------------------------------------------ diff --git a/icaruscode/PMT/Trigger/TriggerSimulationOnGates_module.cc b/icaruscode/PMT/Trigger/TriggerSimulationOnGates_module.cc index eee5c986a..6c9885eed 100644 --- a/icaruscode/PMT/Trigger/TriggerSimulationOnGates_module.cc +++ b/icaruscode/PMT/Trigger/TriggerSimulationOnGates_module.cc @@ -406,9 +406,9 @@ class icarus::trigger::TriggerSimulationOnGates using Name = fhicl::Name; using Comment = fhicl::Comment; - fhicl::Atom TriggerGatesTag { + fhicl::Atom TriggerGatesTag { Name("TriggerGatesTag"), - Comment("label of the input trigger gate data product (no instance name)") + Comment("tag of the input trigger gate data product (no instance name)") }; fhicl::Sequence Thresholds { @@ -776,6 +776,10 @@ class icarus::trigger::TriggerSimulationOnGates (icarus::trigger::WindowChannelMap::WindowInfo_t const& winfo) { return winfo.composition.cryoid; } + /// Returns `defModule` with instance name replaced by `thresholdStr`. + static art::InputTag makeTag + (art::InputTag const& defModule, std::string const& thresholdStr); + }; // icarus::trigger::TriggerSimulationOnGates @@ -878,9 +882,9 @@ icarus::trigger::TriggerSimulationOnGates::TriggerSimulationOnGates // // more complex parameter parsing // - std::string const& discrModuleLabel = config().TriggerGatesTag(); + art::InputTag const& discrModuleTag = config().TriggerGatesTag(); for (std::string const& threshold: config().Thresholds()) - fADCthresholds[threshold] = art::InputTag{ discrModuleLabel, threshold }; + fADCthresholds[threshold] = makeTag(discrModuleTag, threshold); // initialization of a vector of atomic is not as trivial as it sounds... fTriggerCount = std::vector>(fADCthresholds.size()); @@ -929,19 +933,12 @@ icarus::trigger::TriggerSimulationOnGates::TriggerSimulationOnGates log << "\nConfigured " << fADCthresholds.size() << " thresholds (ADC):"; for (auto const& [ thresholdTag, dataTag ]: fADCthresholds) log << "\n * " << thresholdTag << " (from '" << dataTag.encode() << "')"; -#if 0 // TODO restore after adoption of https://github.com/LArSoft/lardataalg/pull/44 + log << "\nOther parameters:" << "\n * trigger time resolution: " << fTriggerTimeResolution << "\n * input beam gate reference time: " << util::StandardSelectorFor{} .get(fBeamGateReference).name() -#else - util::StandardSelectorFor const timeScaleSelector; - log << "\nOther parameters:" - << "\n * trigger time resolution: " << fTriggerTimeResolution - << "\n * input beam gate reference time: " - << timeScaleSelector.get(fBeamGateReference).name() -#endif ; if (fDeadTime == std::numeric_limits::max()) log << "\n * only one trigger per beam gate (infinite dead time)"; @@ -1775,6 +1772,20 @@ double icarus::trigger::TriggerSimulationOnGates::eventTimestampInSeconds { return eventTimestampInSeconds(event.time()); } +//------------------------------------------------------------------------------ +art::InputTag icarus::trigger::TriggerSimulationOnGates::makeTag + (art::InputTag const& defModule, std::string const& thresholdStr) +{ + if (!thresholdStr.empty() && !defModule.instance().empty()) { + throw art::Exception(art::errors::Configuration) + << "Module tag instance name (`TriggerGatesTag`: '" + << defModule.encode() << "') and the threshold '" << thresholdStr + << "' are both set. One of them must be empty.\n"; + } + return { defModule.label(), thresholdStr, defModule.process() }; +} // icarus::trigger::TriggerSimulationOnGates::makeTag() + + //------------------------------------------------------------------------------ DEFINE_ART_MODULE(icarus::trigger::TriggerSimulationOnGates)