17 #include "art/Framework/Core/SharedProducer.h"
18 #include "art/Framework/Core/ModuleMacros.h"
19 #include "art/Framework/Principal/Event.h"
20 #include "canvas/Utilities/InputTag.h"
21 #include "messagefacility/MessageLogger/MessageLogger.h"
22 #include "fhiclcpp/types/TableAs.h"
23 #include "fhiclcpp/types/OptionalTable.h"
24 #include "fhiclcpp/types/OptionalAtom.h"
25 #include "fhiclcpp/types/Sequence.h"
26 #include "fhiclcpp/types/Atom.h"
36 namespace icarus::trigger {
class FixBeamGateInfo; }
113 template <
typename P,
typename I =
typename P::
interval_t>
125 std::optional<ChangeRecipe_t<simulation_time>>
const start;
128 std::optional<ChangeRecipe_t<simulation_time::interval_t>>
const width;
166 template <
typename P,
typename I =
typename P::
interval_t>
170 Comment{
"set to the specified time, regardless of the previous one" }
172 fhicl::OptionalAtom<I>
Add {
174 Comment{
"add the specified time to the existing one" }
181 fhicl::Sequence<std::string>
Types {
184 "gate type to apply the changes on: "
187 std::vector<std::string>
199 {
"apply these settings only to gates satisfying these criteria" }
202 fhicl::OptionalTable<ChangeConfig<simulation_time>>
Start {
204 Comment{
"changes to the start of the beam gate" }
207 fhicl::OptionalTable<ChangeConfig<microseconds>>
Width {
209 Comment{
"changes to the width of the beam gate" }
214 template <
typename P,
typename I>
215 static std::optional<BeamChangeRecipe::ChangeRecipe_t<P, I>>
convert
216 (std::optional<ChangeConfig<P, I>>
const& config);
220 (SelectGateConfig
const& config);
226 Name{
"BeamGateTag" },
227 Comment{
"beam gate data product to operate on" }
231 fhicl::Sequence<fhicl::TableAs<BeamChangeRecipe, ChangeGate>>
Changes {
233 Comment{
"sets of changes to apply to the beam gate" }
238 Name{
"KeepInstanceName" },
240 {
"output data product has the same instance name as in BeamGateTag" },
245 Name{
"OutputInstanceName" },
246 Comment{
"instance name for the output data product" },
251 Name{
"LogCategory" },
252 Comment{
"name of the category used for the output" },
265 (fhicl::Sequence<std::string>
const&
type);
277 (
Parameters const& config, art::ProcessingFrame
const&);
284 virtual void produce(art::Event& event, art::ProcessingFrame
const&)
override;
318 template <
typename T,
typename P,
typename I>
332 namespace icarus::trigger {
342 , indent(
std::move(indent)), firstIndent(
std::move(firstIndent))
346 std::string
const&
indent =
""
353 std::ostream&
operator<< (std::ostream& out, dumpRecipe
const& dr);
359 namespace icarus::trigger {
363 FixBeamGateInfo::BeamChangeRecipe
convert
384 template <
typename Coll,
typename T>
385 bool contains(Coll
const& coll, T
const&
value) {
387 auto const b =
begin(coll);
auto const e =
end(coll);
388 return std::find(b,
e, value) !=
e;
393 namespace icarus::trigger {
398 { BeamType_t::kUnknown,
"unknown" }
409 : art::SharedProducer(config)
411 , fBeamGateTag{ config().BeamGateTag() }
412 , fChanges{ config().Changes() }
414 config().KeepInstanceName()
415 ? fBeamGateTag.instance(): config().OutputInstanceName()
419 using namespace util::quantities::time_literals;
424 if (config().KeepInstanceName() && !config().OutputInstanceName().
empty()) {
425 throw art::Exception{ art::errors::Configuration }
426 <<
"Can't set both '" << config().KeepInstanceName.name()
427 <<
" (" << std::boolalpha << config().KeepInstanceName() <<
")"
428 <<
"' and '" << config().OutputInstanceName.name() <<
"' ('"
429 << config().OutputInstanceName() <<
"') at the same time.\n";
433 if (change.valid())
continue;
434 throw art::Exception{ art::errors::Configuration }
435 <<
"Incompatible requests for '" << config().Changes.name()
436 <<
"' item [" << iChange <<
"] " << dumpRecipe(change,
" ",
"")
443 consumes<std::vector<sim::BeamGateInfo>>(fBeamGateTag);
448 produces<std::vector<sim::BeamGateInfo>>(fInstanceName);
450 async<art::InEvent>();
457 log <<
"New beam gates based on '" << fBeamGateTag.encode()
458 <<
"' following " << fChanges.size() <<
" rules:";
460 log <<
"\n[" << iChange <<
"] " << dumpRecipe(change,
" ",
"");
469 (art::Event& event, art::ProcessingFrame
const&)
475 auto const& beamGates
476 =
event.getProduct<std::vector<sim::BeamGateInfo>>(fBeamGateTag);
481 std::vector<sim::BeamGateInfo> fixedBeamGates;
482 fixedBeamGates.reserve(beamGates.size());
484 fixedBeamGates.push_back(fixBeamGate(beamGate));
490 std::make_unique<std::vector<sim::BeamGateInfo>>
491 (std::move(fixedBeamGates)),
510 if (!acceptGate(beamGate, change.selectGates))
continue;
511 applyRecipe(start, change.start);
512 applyRecipe(width, change.width);
536 template <
typename T,
typename P,
typename I>
541 if (recipe->setValue) target = *recipe->setValue;
542 if (recipe->addValue) target += *recipe->addValue;
550 (fhicl::Atom<std::string>
const&
type)
554 (BeamTypeSelector.parse(
type()).value());
558 throw art::Exception(art::errors::Configuration)
559 <<
"Invalid value for '" << type.name()
560 <<
"' parameter: '" << e.
label() <<
"'; valid options: "
561 << BeamTypeSelector.optionListString() <<
".\n";
568 (fhicl::Sequence<std::string>
const&
types) -> std::vector<sim::BeamType_t>
570 std::vector<sim::BeamType_t> beamTypes;
571 beamTypes.reserve(types.size());
572 for (std::string
const& type:
types()) {
575 (static_cast<sim::BeamType_t>(BeamTypeSelector.parse(type).value()));
579 throw art::Exception(art::errors::Configuration)
580 <<
"Invalid value for '" << types.name()
581 <<
"' parameter: '" << e.
label() <<
"'; valid options: "
582 << BeamTypeSelector.optionListString() <<
".\n";
590 template <
typename P,
typename I>
593 -> std::optional<BeamChangeRecipe::ChangeRecipe_t<P, I>>
597 config->SetTo(), config->Add()
614 std::ostream& icarus::trigger::operator<<
617 using namespace util::quantities::time_literals;
619 auto printChangeRecipe = [&out, &indent=dr.indent]
620 (std::string
const&
name,
auto const& recipe)
622 if (!recipe || recipe->empty())
return;
623 out <<
"\n" << indent <<
"- " <<
name <<
":";
624 if (recipe->setValue) out <<
" set to " << (*recipe->setValue);
625 if (recipe->addValue) {
626 if (*recipe->addValue < 0_ns) out <<
" remove " << (-*recipe->addValue);
627 else out <<
" add " << (*recipe->addValue);
632 if (dr.recipe.empty()) {
633 out <<
"(no action)";
636 out << dr.firstIndent;
637 if (dr.recipe.selectGates.empty()) out <<
"(always)";
639 out <<
"(only on gates of type:";
643 .
get(static_cast<FixBeamGateInfo::Config::BeamType_t>(gate)).
name();
648 printChangeRecipe(
"start", dr.recipe.start);
649 printChangeRecipe(
"width", dr.recipe.width);
Request for unknown option.
Rewrites a set collection of beam gates into each event.
art::SharedProducer::Table< Config > Parameters
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
std::vector< sim::BeamType_t > beamTypes
Match these beam types.
fhicl::OptionalAtom< I > Add
DiscriminatePMTwaveformsByChannel::ChannelInfo_t convert(DiscriminatePMTwaveformsByChannel::ChannelConfig const &config)
std::optional< I > addValue
Value to add.
std::string const fInstanceName
Instance name for the output product.
fhicl::Atom< art::InputTag > BeamGateTag
Helper to select an string option among a set of allowed choices.
icarus::trigger::FixBeamGateInfo::BeamChangeRecipe const & recipe
Definition of util::enumerate().
FixBeamGateInfo(Parameters const &config, art::ProcessingFrame const &)
microseconds_as<> microseconds
Type of time interval stored in microseconds, in double precision.
std::ostream & operator<<(std::ostream &out, icarus::trigger::ApplyBeamGateClass const &gate)
virtual void produce(art::Event &event, art::ProcessingFrame const &) override
static bool acceptGate(sim::BeamGateInfo const &gate, BeamChangeRecipe::GateSelector_t const &selection)
Returns whether gate passes the specified selection.
sim::BeamGateInfo fixBeamGate(sim::BeamGateInfo const &beamGate) const
Returns a "fixed" beam gate based on the input beamGate one.
All directions to change a beam gate.
std::optional< ChangeRecipe_t< simulation_time::interval_t > > const width
Instructions on how to change the gate width.
fhicl::Atom< std::string > OutputInstanceName
std::string optionListString(std::string const &sep=", ") const
Returns a string with the (main) name of all options.
static util::MultipleChoiceSelection< BeamType_t > const BeamTypeSelector
Selector for Type parameter.
Configuration to select a gate to be changed.
constexpr value_t value() const
Returns the value of the quantity.
std::string const fLogCategory
Message facility stream category for output.
std::optional< ChangeRecipe_t< simulation_time > > const start
Instructions on how to change the gate start.
std::vector< BeamChangeRecipe > const fChanges
Changes on beam gate.
fhicl::OptionalTable< ChangeConfig< microseconds > > Width
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
dumpRecipe(icarus::trigger::FixBeamGateInfo::BeamChangeRecipe const &recipe, std::string indent, std::string firstIndent)
dumpRecipe(icarus::trigger::FixBeamGateInfo::BeamChangeRecipe const &recipe, std::string const &indent="")
microsecond_as<> microsecond
Type of time point stored in microseconds, in double precision.
Option_t const & get(Choices_t value) const
Returns the specified option.
timescale_traits< SimulationTimeCategory >::time_point_t simulation_time
A point in time on the simulation time scale.
std::vector< SelDef > types
auto end(FixedBins< T, C > const &) noexcept
static T & applyRecipe(T &target, std::optional< BeamChangeRecipe::ChangeRecipe_t< P, I >> const &recipe)
Applies the changes in recipe on the target value.
BEGIN_PROLOG vertical distance to the surface Name
static std::vector< sim::BeamType_t > getBeamTypes(fhicl::Sequence< std::string > const &type)
Converts a FHiCL sequence into a vector of beam types.
GateSelector_t selectGates
Which gates to apply this recipe on.
fhicl::OptionalTable< ChangeConfig< simulation_time > > Start
An interval (duration, length, distance) between two quantity points.
std::string name() const
Returns the name of the option (i.e. the main label).
nanoseconds_as<> nanoseconds
Type of time interval stored in nanoseconds, in double precision.
auto begin(FixedBins< T, C > const &) noexcept
static std::optional< BeamChangeRecipe::ChangeRecipe_t< P, I > > convert(std::optional< ChangeConfig< P, I >> const &config)
Converts a configuration table into a ChangeRecipe_t.
std::vector< sim::BeamType_t > getBeamTypes() const
Utilities to read interval and point quantity FHiCL configuration.
fhicl::Sequence< std::string > Types
fhicl::OptionalAtom< P > SetTo
fhicl::Atom< std::string > LogCategory
Dimensioned variables representing space or time quantities.
Data types for detinfo::DetectorTimings.
nanosecond_as<> nanosecond
Type of time stored in nanoseconds, in double precision.
std::string const & label() const
nanosecond_as<> nanosecond
Type of time point stored in nanoseconds, in double precision.
fhicl::Sequence< fhicl::TableAs< BeamChangeRecipe, ChangeGate > > Changes
fhicl::Table< SelectGateConfig > Select
detinfo::timescales::simulation_time simulation_time
fhicl::Atom< bool > KeepInstanceName
art::InputTag const fBeamGateTag
Input beam gate data product.
BeamType_t BeamType() const
bool empty(FixedBins< T, C > const &) noexcept
BeamType_t
Defines category of beams to be stored in sim::BeamGateInfo.
Settings to change a gate.
friend BeamChangeRecipe convert(Config::ChangeGate const &config)
static sim::BeamType_t getBeamType(fhicl::Atom< std::string > const &type)
Converts a FHiCL atom into a beam type.
TimeTrackTreeStorage::TriggerInputSpec_t convert(TimeTrackTreeStorage::Config::TriggerSpecConfig const &config)
Set of instructions for a change.
std::optional< P > setValue
Value to set.
nanosecond nanoseconds
Alias for common language habits.