29 #include "art/Framework/Services/Registry/ServiceHandle.h"
30 #include "art/Framework/Core/EDProducer.h"
31 #include "art/Framework/Core/ModuleMacros.h"
32 #include "art/Framework/Principal/Event.h"
33 #include "art/Framework/Principal/Handle.h"
34 #include "canvas/Utilities/InputTag.h"
35 #include "canvas/Utilities/Exception.h"
36 #include "messagefacility/MessageLogger/MessageLogger.h"
37 #include "fhiclcpp/types/OptionalAtom.h"
38 #include "fhiclcpp/types/Atom.h"
39 #include "fhiclcpp/types/Sequence.h"
40 #include "cetlib_except/exception.h"
55 namespace icarus::trigger {
class LVDSgates; }
192 Name(
"TriggerGatesTag"),
193 Comment(
"label of trigger gate extraction module (no instance name)")
199 (
"thresholds to consider (full tag or instance name of TriggerGatesTag)")
203 Name(
"ChannelPairing"),
205 (
"grouping of optical detector channels (e.g.: [ [ 0, 2 ], [ 4, 6 ], [ 8 ], ... ])")
209 Name(
"IgnoreChannels"),
211 (
"optical detector channels to ignore (e.g.: [ 54, 58, 67, 76, ... ])")
215 Name(
"CombinationMode"),
220 Name(
"ProduceWaveformAssns"),
222 (
"also produce gate/waveform associations together with gate/metadata"),
228 Comment(
"name of the category used for the output"),
239 throw art::Exception(art::errors::Configuration)
240 <<
"Invalid value for 'CombinationMode' parameter: '" << e.
label()
241 <<
"'; valid options: "
268 virtual void produce(art::Event& event)
override;
313 std::string
const& thresholdStr,
324 std::vector<std::vector<raw::Channel_t>> channelPairing,
325 std::vector<raw::Channel_t>
const& ignoreChannels
332 std::vector<TrackedTriggerGate_t>
const&,
333 std::vector<raw::Channel_t>
const& pairing
338 std::vector<TrackedTriggerGate_t>
const&,
339 std::vector<raw::Channel_t>
const& pairing, std::size_t chosenIndex
343 template <
typename Op>
345 std::vector<TrackedTriggerGate_t>
const& gates,
346 std::vector<raw::Channel_t>
const& pairing,
352 std::vector<TrackedTriggerGate_t>
const& gates,
353 std::vector<raw::Channel_t>
const& pairing,
366 void checkInput(std::vector<TrackedTriggerGate_t>
const& gates)
const;
374 art::Assns<TriggerGateData_t, sbn::OpDetWaveformMeta>
const& assns
379 art::Event
const& event, art::InputTag
const& dataTag,
385 (std::string
const& thresholdStr, std::string
const& defModule);
389 (art::InputTag
const& inputTag, std::string
const& defModule);
400 : art::EDProducer(config)
411 std::string
const discrModuleLabel = config().TriggerGatesTag().value_or(
"");
412 for (std::string
const& thresholdStr: config().
Thresholds()) {
413 art::InputTag
const inputTag =
makeTag(thresholdStr, discrModuleLabel);
428 log << nConfiguredChannels
429 <<
" optical channels configured to be combined into "
432 log <<
"\nConfigured " <<
fADCthresholds.size() <<
" thresholds (ADC):";
434 log <<
"\n * " << threshold
435 <<
" (from '" << srcInfo.inputTag.encode() <<
"')";
446 consumes<std::vector<OpticalTriggerGateData_t>>(inputTag);
447 consumes<art::Assns<OpticalTriggerGateData_t, sbn::OpDetWaveformMeta>>
456 produces<std::vector<OpticalTriggerGateData_t>>(outName);
457 produces<art::Assns<OpticalTriggerGateData_t, raw::OpDetWaveform>>(outName);
459 produces<art::Assns<OpticalTriggerGateData_t, sbn::OpDetWaveformMeta>>
488 std::string
const& thresholdStr,
492 auto const& [ dataTag, outputInstanceName ] = srcInfo;
495 <<
"Processing threshold " << thresholdStr
496 <<
" from '" << dataTag.encode() <<
"'";
500 std::vector<TrackedTriggerGate_t>
const& gates
505 std::vector<TrackedTriggerGate_t> combinedGates;
507 std::vector<std::vector<raw::Channel_t>>
const cleanedChannels
510 for (std::vector<raw::Channel_t>
const& pairing: cleanedChannels) {
511 if (pairing.empty())
continue;
518 art::PtrMaker<OpticalTriggerGateData_t>
const makeGatePtr
519 (event, outputInstanceName);
520 auto [ outputGates, outputAssns ]
522 (std::move(combinedGates), makeGatePtr, waveformMap);
525 <<
"Threshold " << thresholdStr <<
" ('" << dataTag.encode() <<
"'): "
526 << gates.size() <<
" input channels, "
527 << outputGates.size() <<
" output channels (+"
528 << outputAssns.size() <<
" associations to waveforms) into '"
529 << moduleDescription().moduleLabel() <<
":" << outputInstanceName <<
"'"
538 art::Assns<OpticalTriggerGateData_t, raw::OpDetWaveform> outputWaveAssns;
539 for (
auto const [ gatePtr, metaPtr ]: outputAssns)
540 outputWaveAssns.addSingle(gatePtr, waveformMetaMatcher(metaPtr));
543 std::make_unique<art::Assns<OpticalTriggerGateData_t, raw::OpDetWaveform>>
544 (std::move(outputWaveAssns)),
551 std::make_unique<std::vector<OpticalTriggerGateData_t>>
552 (std::move(outputGates)),
556 std::make_unique<art::Assns<OpticalTriggerGateData_t, sbn::OpDetWaveformMeta>>
557 (std::move(outputAssns)),
566 std::vector<TrackedTriggerGate_t>
const& gates,
567 std::vector<raw::Channel_t>
const& pairing,
571 namespace GateOps = icarus::trigger::GateOps;
585 throw art::Exception(art::errors::LogicError)
586 <<
"Unexpected combination mode (#" <<
static_cast<int>(comboMode)
594 std::vector<std::vector<raw::Channel_t>> channelPairing,
595 std::vector<raw::Channel_t>
const& ignoreChannels
598 for (std::vector<raw::Channel_t>& channels: channelPairing) {
599 for (
unsigned int j = channels.size(); j-- > 0; ) {
600 std::vector<raw::Channel_t>::const_iterator
const it
601 = find(ignoreChannels.begin(), ignoreChannels.end(), channels[j]);
603 channels.erase(channels.begin() + j);
608 return channelPairing;
615 std::vector<TrackedTriggerGate_t>
const& gates,
616 std::vector<raw::Channel_t>
const& pairing
620 for (
auto const& srcGate: gates) gate.
tracking().
add(srcGate.tracking());
627 std::vector<TrackedTriggerGate_t>
const& gates,
628 std::vector<raw::Channel_t>
const& pairing,
629 std::size_t chosenIndex
635 gate.gate().addChannel(channel);
637 mf::LogTrace(
fLogCategory) <<
"Output: " << gate.gate();
638 for (
auto const& srcGate: gates) gate.tracking().add(srcGate.tracking());
644 template <
typename Op>
646 std::vector<TrackedTriggerGate_t>
const& gates,
647 std::vector<raw::Channel_t>
const& pairing,
655 {
return gates[index]; };
670 auto iChannel = pairing.begin();
671 auto cend = pairing.end();
677 while (++iChannel !=
cend) {
679 mf::LogTrace(
fLogCategory) <<
"Input: " << gates[*iChannel].gate();
683 mf::LogTrace(
fLogCategory) <<
"Output: " << gate.gate();
696 auto const& geom = *(lar::providerFrom<geo::Geometry>());
700 unsigned int nEmptyGroups = 0U;
701 std::set<raw::Channel_t> configuredChannels, duplicateChannels;
703 if (pairing.empty()) {
708 if (!configuredChannels.insert(channel).second)
709 duplicateChannels.insert(channel);
714 std::vector<raw::Channel_t> invalidChannels;
716 if (!geom.IsValidOpChannel(channel)) invalidChannels.push_back(channel);
720 auto const endChannel = geom.MaxOpChannel() + 1U;
721 std::vector<raw::Channel_t> missingChannels;
722 for (
auto channel: util::counter<raw::Channel_t>(endChannel)) {
723 if (!geom.IsValidOpChannel(channel))
continue;
724 if (configuredChannels.count(channel) > 0U)
continue;
725 missingChannels.push_back(channel);
729 if (invalidChannels.empty()
730 && missingChannels.empty()
731 && duplicateChannels.empty()
732 && (nEmptyGroups == 0U)
734 return configuredChannels.size();
738 art::Exception
e(art::errors::Configuration);
739 e <<
"The pairing configuration of " << configuredChannels.size()
740 <<
" optical channels in `ChannelPairing` presents the following errors.\n";
741 if (!invalidChannels.empty()) {
742 auto iChannel = invalidChannels.cbegin();
743 auto const cend = invalidChannels.cend();
745 << invalidChannels.size()
746 <<
" channel numbers do not represent valid channels: " << *iChannel;
747 while (++iChannel !=
cend) e <<
", " << *iChannel;
751 if (!missingChannels.empty()) {
752 auto iChannel = missingChannels.cbegin();
753 auto const cend = missingChannels.cend();
755 << missingChannels.size()
756 <<
" channels do not appear in the configuration: " << *iChannel;
757 while (++iChannel !=
cend) e <<
", " << *iChannel;
761 if (!duplicateChannels.empty()) {
762 auto iChannel = duplicateChannels.cbegin();
763 auto const cend = duplicateChannels.cend();
765 << duplicateChannels.size()
766 <<
" channels are specified more than once: " << *iChannel;
767 while (++iChannel !=
cend) e <<
", " << *iChannel;
771 if (nEmptyGroups > 0U) {
772 e << nEmptyGroups <<
" channel groups are empty.";
781 (std::vector<TrackedTriggerGate_t>
const& gates)
const
796 if (gate.nChannels() != 1U) {
797 cet::exception
e(
"LVDSgates");
798 e <<
"Requirement failure: gate #" << iGate <<
" includes ";
799 if (!gate.hasChannels())
802 auto const& channels = gate.channels();
803 auto iChannel = channels.begin();
804 auto const cend = channels.end();
805 e << gate.nChannels() <<
" channels (" << *iChannel;
806 while (++iChannel !=
cend) e <<
", " << *iChannel;
809 e <<
" should have exactly one channel (" << expectedChannel <<
").\n";
813 if (gate.channel() != expectedChannel) {
814 throw cet::exception(
"LVDSgates")
815 <<
"Requirement failure: gate #" << iGate <<
" gate covers channel "
816 << gate.channel() <<
", should cover " << expectedChannel
823 <<
"LVDSgates[" << moduleDescription().moduleLabel() <<
"]: input checked.";
831 art::Assns<TriggerGateData_t, sbn::OpDetWaveformMeta>
const& assns
834 for (art::Ptr<sbn::OpDetWaveformMeta>
const& wave: util::get_elements<1U>(assns))
835 map.emplace(wave.get(), wave);
842 art::Event
const& event,
843 art::InputTag
const& dataTag,
845 ) -> std::vector<TrackedTriggerGate_t> {
849 event.getProduct<art::Assns<OpticalTriggerGateData_t, sbn::OpDetWaveformMeta>>
855 (event.getProduct<std::vector<OpticalTriggerGateData_t>>(dataTag), assns);
862 (std::string
const& thresholdStr, std::string
const& defModule)
864 return (thresholdStr.find(
':') != std::string::npos)
865 ? art::InputTag{ thresholdStr }
867 ?
throw (art::Exception(art::errors::Configuration)
868 <<
"No default module label (`TriggerGatesTag`) specified"
869 ", and it's needed for threshold '"
870 << thresholdStr <<
"'.\n")
871 : art::InputTag{ defModule, thresholdStr }
878 (art::InputTag
const& inputTag, std::string
const& defModule)
880 return (inputTag.label() == defModule)
881 ? inputTag.instance()
882 : inputTag.instance().empty()
883 ? inputTag.label(): inputTag.label() + inputTag.instance()
BEGIN_PROLOG BeamGateDuration pmtthr physics producers trigtilewindowORS Thresholds
Request for unknown option.
art::EDProducer::Table< Config > Parameters
Utilities related to art service access.
fhicl::Sequence< std::string > Thresholds
Utilities for the conversion of trigger gate data formats.
fhicl::Atom< bool > ProduceWaveformAssns
Helper to select an string option among a set of allowed choices.
Definition of util::get_elements() and util::get_const_elements().
static art::InputTag makeTag(std::string const &thresholdStr, std::string const &defModule)
Converts a threshold string into an input tag.
TrackedTriggerGate_t binaryCombineChannel(std::vector< TrackedTriggerGate_t > const &gates, std::vector< raw::Channel_t > const &pairing, Op combine) const
Combination function for the AND and OR modes; op is from GateOps.
A wrapper to trigger gate objects tracking the input of operations.
util::MultipleChoiceSelection< ComboMode > const CombinationModeSelector
Selector for CombinationMode parameter.
fhicl::Sequence< fhicl::Sequence< raw::Channel_t > > ChannelPairing
Option_t const & parse(std::string const &label) const
Returns the option matching the specified label.
auto gatesIn(TrackingGateColl &trackingGates)
void produceThreshold(art::Event &event, icarus::trigger::OpDetWaveformMetaDataProductMap_t &waveformMap, std::string const &thresholdStr, SourceInfo_t const &srcInfo) const
Completely processes the data for the specified threshold.
std::vector< icarus::trigger::OpticalTriggerGateData_t > transformIntoOpticalTriggerGate(Gates &&gates)
Returns the trigger gates in serializable format.
decltype(auto) const_values(Coll &&coll)
Range-for loop helper iterating across the constant values of the specified collection.
TrackedTriggerGate_t discardChannels(std::vector< TrackedTriggerGate_t > const &, std::vector< raw::Channel_t > const &pairing) const
Combination function for the disable mode.
std::string optionListString(std::string const &sep=", ") const
Returns a string with the (main) name of all options.
fhicl::Sequence< raw::Channel_t > IgnoreChannels
void add(TrackedType tracked)
Add an object to the list of tracked objects, if it's not present yet.
auto cend(FixedBins< T, C > const &) noexcept
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
static std::string makeOutputInstanceName(art::InputTag const &inputTag, std::string const &defModule)
Converts an input tag into an instance name for the corresponding output.
auto OpGateColl(Op op, GateColl const &gates)
Computes the result of an operation on all gates from collection.
ComboMode
Available operations for the combination of channels.
TrackedTriggerGate_t combineChannels(std::vector< TrackedTriggerGate_t > const &gates, std::vector< raw::Channel_t > const &pairing, ComboMode comboMode) const
Performs the combination of a group of channels.
virtual void produce(art::Event &event) override
Fills the plots. Also extracts the information to fill them with.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Access the description of detector geometry.
TrackingInfo const & tracking() const
Returns the tracking information.
ComboMode getCombinationMode() const
void checkInput(std::vector< TrackedTriggerGate_t > const &gates) const
Input requirement check. Throws if requirements fail.
LVDSgates & operator=(LVDSgates const &)=delete
Logical multi-level gate associated to one or more readout channels.
static std::vector< TrackedTriggerGate_t > ReadTriggerGates(art::Event const &event, art::InputTag const &dataTag, icarus::trigger::OpDetWaveformMetaDataProductMap_t &waveformMap)
Assembles trigger gates from dataTag data products in event.
bool fProduceWaveformAssns
Whether to produce gate/waveform associations.
auto make_transformed_span(BIter begin, EIter end, Op &&op)
Simple type definitions for trigger algorithms.
std::string outputInstanceName
A trigger gate data object for optical detector electronics.
icarus::trigger::ReadoutTriggerGate< TriggerGateTick_t, TriggerGateTicks_t, raw::Channel_t > OpticalTriggerGateData_t
Type of trigger gate data serialized into art data products.
Utilities for the conversion of trigger gate data formats.
BEGIN_PROLOG vertical distance to the surface Name
AGate OpGates(Op op, AGate A, BGate const &B, OGates const &...others)
Applies an operation to two gates.
fhicl::Atom< std::string > LogCategory
TriggerGate_t const & gate() const &
Returns the enclosed gate.
Information for each source.
Logical multi-level gate associated to one or more waveforms.
Functions pulling in STL customization if available.
std::string const & label() const
fhicl::Atom< std::string > CombinationMode
A simple alias for a most commonly used TrackedTriggerGate type.
std::vector< icarus::trigger::TrackedOpticalTriggerGate< OpDetInfo > > FillTriggerGates(std::vector< icarus::trigger::OpticalTriggerGateData_t > const &gates, art::Assns< icarus::trigger::OpticalTriggerGateData_t, OpDetInfo > const &gateToWaveformInfo)
Creates a gate object out of trigger gate data products.
std::map< std::string, SourceInfo_t > fADCthresholds
ADC thresholds to read, and the input tag connected to their data.
Combines discriminated PMT outputs into V1730 LVDS gates.
std::string fLogCategory
Message facility stream category for output.
std::vector< std::vector< raw::Channel_t > > removeChannels(std::vector< std::vector< raw::Channel_t >> channelPairing, std::vector< raw::Channel_t > const &ignoreChannels) const
Removes all the channel in ignoreChannels from channelPairing.
LVDSgates(Parameters const &config)
Definition of util::values() and util::const_values().
fhicl::OptionalAtom< std::string > TriggerGatesTag
std::vector< std::vector< raw::Channel_t > > fChannelPairing
Pairing of optical detector channels.
static void UpdateWaveformMap(icarus::trigger::OpDetWaveformMetaDataProductMap_t &map, art::Assns< TriggerGateData_t, sbn::OpDetWaveformMeta > const &assns)
Adds the associated waveforms into the map.
TrackedTriggerGate_t selectChannel(std::vector< TrackedTriggerGate_t > const &, std::vector< raw::Channel_t > const &pairing, std::size_t chosenIndex) const
Combination function for the input1 and input2 modes.
util::DataProductPointerMap_t< sbn::OpDetWaveformMeta > OpDetWaveformMetaDataProductMap_t
Map util::DataProductPointerMap_t for sbn::OpDetWaveformMeta objects.
OpticalTriggerGateData_t GateData_t
Type for gate data access.
ComboMode fComboMode
The operation used to combinate channels.
art framework interface to geometry description
OpticalTriggerGate &(OpticalTriggerGate::*)(OpticalTriggerGate const &) BinaryCombinationFunc_t
Type of member function to combine the current gate with another one.
unsigned int checkPairings() const
std::vector< raw::Channel_t > fIgnoreChannels