26 #include "art/Framework/Core/EDAnalyzer.h"
27 #include "art/Framework/Core/ModuleMacros.h"
28 #include "art/Framework/Principal/Event.h"
29 #include "canvas/Utilities/Exception.h"
30 #include "messagefacility/MessageLogger/MessageLogger.h"
31 #include "fhiclcpp/types/Sequence.h"
73 template <
typename Thresholds,
typename Requirements>
75 (TTree&
tree,
Thresholds const& thresholds, Requirements
const& minReqs);
78 void assignResponse(std::size_t iThr, std::size_t iReq,
bool resp);
87 namespace icarus::trigger {
class MajorityTriggerEfficiencyPlots; }
279 :
public art::EDAnalyzer
292 Name(
"MinimumPrimitives"),
293 Comment(
"minimum required number of trigger primitives for a trigger")
320 virtual void analyze(art::Event
const& event)
override;
323 virtual void endJob()
override;
388 std::size_t
const thresholdIndex,
433 std::size_t iThr, std::string
const& threshold,
436 std::vector<WorkingTriggerGate_t>
const& combinedCounts,
437 std::vector<ChannelID_t>
const& channelList
457 std::string
const& threshold
469 template <
typename Thresholds,
typename Requirements>
471 (TTree& tree,
Thresholds const& thresholds, Requirements
const& minReqs)
474 , RespTxxRxx{ std::make_unique<bool[]>(
indices.size()) }
481 std::string
const branchName
485 (branchName.c_str(), &(RespTxxRxx[
indices(iThr, iReq)]));
496 (std::size_t iThr, std::size_t iReq,
bool resp)
498 RespTxxRxx[
indices(iThr, iReq)] = resp;
507 : art::EDAnalyzer (config)
510 , fMinimumPrimitives(config().MinimumPrimitives())
512 std::sort(fMinimumPrimitives.begin(), fMinimumPrimitives.end());
517 if (helper().eventTree()) {
519 fResponseTree = std::make_unique<ResponseTree>
520 (*(helper().eventTree()), helper().ADCthresholds(), fMinimumPrimitives);
524 if (fMinimumPrimitives.empty()) {
525 throw art::Exception(art::errors::Configuration)
526 <<
"At least one 'MinimumPrimitives' requirement... required.";
529 std::size_t iPattern [[maybe_unused]] = 0U;
530 for (
auto const& req: fMinimumPrimitives) {
531 std::size_t
const index [[maybe_unused]]
533 assert(index == iPattern++);
537 mf::LogInfo log(helper().logCategory());
539 <<
"Requirement of minimum trigger primitives ("
540 << fMinimumPrimitives.size() <<
"):";
541 for (
auto const& req: fMinimumPrimitives) log <<
" " << req;
555 std::vector<SettingsInfo_t> settings;
558 settings.emplace_back(
561 minCountStr +
" channels required"
574 (art::Event
const& event)
580 helper().process(event);
589 helper().printSummary();
604 helper().TriggerEfficiencyPlotsBase::initializePlotSet(plots, settings);
611 auto [ minimumPrimBinning, minimumPrimBinningLabels ]
613 assert(minimumPrimBinning.size() == minimumPrimBinningLabels.size() + 1U);
616 mf::LogTrace log(helper().logCategory());
617 log <<
"MajorityTriggerEfficiencyPlots (plots '"
618 << plots.
name() <<
"') variable binning including the "
619 << fMinimumPrimitives.size() <<
" points {";
620 for (
auto value: fMinimumPrimitives) log <<
" " <<
value;
621 log <<
" } => " << minimumPrimBinningLabels.size() <<
" bins: ";
622 for (
auto const& [ value, label ]
623 : util::zip<1U>(minimumPrimBinning, minimumPrimBinningLabels))
625 log <<
" " << value <<
" (\"" << label <<
"\") =>";
627 log <<
" " << minimumPrimBinning.back();
634 auto const [
detTimings, beamGate, preSpillWindow ] = makeGatePack();
637 {
detTimings.toOpticalTicks(helper().triggerTimeResolution()) };
639 auto const& beamGateOpt = beamGate.asOptTickRange();
641 auto* TrigTime = plots.
make<TH2F>(
644 ";minimum requested number of trigger primitives"
645 ";optical time tick [ /" +
util::to_string(triggerResolutionTicks) +
" ]",
646 minimumPrimBinning.size() - 1U, minimumPrimBinning.data(),
648 beamGateOpt.duration() / triggerResolutionTicks,
649 beamGateOpt.first.value(), beamGateOpt.second.value()
654 auto* Eff = plots.
make<TEfficiency>(
656 "Efficiency of triggering"
657 ";minimum requested number of trigger primitives"
658 ";trigger efficiency",
659 minimumPrimBinning.size() - 1U, minimumPrimBinning.data()
668 const_cast<TH1*>(Eff->GetTotalHistogram())->GetXaxis(),
669 minimumPrimBinningLabels
677 "Number of trigger primitives (\"channels firing at once\")"
678 ";maximum trigger primitives at the same time on a single cryostat"
688 std::size_t
const thresholdIndex,
695 auto const threshold = helper().ADCthresholdTag(thresholdIndex);
697 auto const& beamGate = helper().makeMyBeamGate(clockData);
706 thresholdIndex, threshold, selectedPlots, eventInfo,
708 beamGate.applyToAll(combineTriggerPrimitives(gates, threshold)),
709 helper().extractActiveChannels(gates)
718 std::string
const& threshold,
722 std::vector<WorkingTriggerGate_t>
const& combinedCounts,
723 std::vector<ChannelID_t>
const& channelList
742 using namespace std::string_literals;
744 using ClockTick_t = WorkingTriggerGate_t::TriggerGate_t::ClockTick_t;
745 using OpeningCount_t = WorkingTriggerGate_t::TriggerGate_t::OpeningCount_t;
747 using PrimitiveCount_t = std::pair<ClockTick_t, OpeningCount_t>;
749 PrimitiveCount_t maxPrimitives { ClockTick_t{ 0 } , 0U };
750 for (
auto const& [ iCryo, combinedCount ]
753 auto const maxPrimitiveTime { combinedCount.findMaxOpen() };
754 PrimitiveCount_t
const maxPrimitivesInCryo
755 { maxPrimitiveTime, combinedCount.openingCount(maxPrimitiveTime) };
756 if (maxPrimitivesInCryo.second > maxPrimitives.second)
757 maxPrimitives = maxPrimitivesInCryo;
759 mf::LogTrace log { helper().logCategory() };
760 log <<
"Max primitive count in " << threshold <<
" for C:" << iCryo <<
": "
761 << maxPrimitivesInCryo.second;
762 if (maxPrimitivesInCryo.second > 0) {
763 log <<
" at tick " << maxPrimitivesInCryo.first <<
" ("
771 PMTInfo_t const PMTinfo { threshold, channelList };
789 for (
auto const& [ iCryo, cryoGate ]:
util::enumerate(combinedCounts)) {
792 {
gateIn(cryoGate), minCount };
793 extractOpeningInfo.setLocation(iCryo);
794 while (extractOpeningInfo) {
795 auto info = extractOpeningInfo();
800 fired = triggerInfo.
fired();
804 mf::LogTrace log(helper().logCategory());
806 <<
" => fired (>" << minCount <<
") at " << triggerInfo.
atTick()
807 <<
" (level " << triggerInfo.
level() <<
") from"
810 else log <<
" unknown location";
811 log <<
", " << triggerInfo.
nTriggers() <<
" triggers total:";
813 log <<
" [" << iTrigger <<
"] at " <<
info.tick;
814 if (
info.hasLocation()) log <<
" of C:" <<
info.locationID;
815 else log <<
" [unknown location]";
816 log <<
" (level=" <<
info.level <<
")";
821 mf::LogTrace(helper().logCategory())
822 <<
" => not fired (>" << minCount <<
")";
828 if (fResponseTree) fResponseTree->assignResponse(iThr, iReq, fired);
830 registerTriggerResult(iThr, iReq, fired);
832 std::string
const minCountStr {
"Req" +
std::to_string(minCount) };
845 get.
Eff(
"Eff"s).Fill(fired, minCount);
849 get.Hist2D(
"TriggerTick"s).Fill(minCount, triggerInfo.
atTick().value());
859 helper().fillAllEfficiencyPlots
860 (eventInfo, PMTinfo, triggerInfo, plotSet.demandSandbox(minCountStr));
880 fillEventPlots(eventInfo, plotSet);
886 fillPMTplots(PMTinfo, plotSet);
894 get.
Hist(
"NPrimitives"s).Fill(maxPrimitives.second);
904 std::string
const& threshold
905 )
const -> std::vector<WorkingTriggerGate_t> {
910 std::vector<WorkingTriggerGate_t> cryoCombinedGate;
911 cryoCombinedGate.reserve(cryoGates.size());
916 mf::LogTrace(helper().logCategory())
917 <<
"Simulating trigger response with ADC threshold " << threshold
918 <<
" for " << cryoID <<
" (" << gates.size() <<
" primitives)";
926 return cryoCombinedGate;
BEGIN_PROLOG BeamGateDuration pmtthr physics producers trigtilewindowORS Thresholds
bool fired() const
Returns whether the trigger fired.
Obj * make(std::string const &name, std::string const &title, Args &&...args)
Creates a new ROOT object with the specified name and title.
Definition of util::zip().
Helper class to produce plots about trigger simulation and trigger efficiency.
std::vector< OpeningInfo_t > const & all() const
std::vector< unsigned int > fMinimumPrimitives
Minimum number of trigger primitives for a trigger to happen.
virtual void initializePlotSet(PlotSandbox &plots, std::vector< SettingsInfo_t > const &settings) const override
Initializes full set of plots for (ADC threshold + category).
std::pair< std::vector< double >, std::vector< std::string > > makeVariableBinningAndLabels(Coll const ¢ralPoints)
Returns a variable size binning for the points.
void sortOpenings()
Sorts all openings by time.
Definition of util::enumerate().
A wrapper to trigger gate objects tracking the input of operations.
virtual void endJob() override
Prints end-of-job summaries.
virtual void beginJob() override
Initializes the plots.
LocationID_t location() const
Returns the ID of the location of the trigger (undefined if !fired()).
Class managing the serialization of trigger responses in a simple ROOT tree.
ResponseTree(TTree &tree, Thresholds const &thresholds, Requirements const &minReqs)
Constructor: accommodates that many thresholds and requirements.
void assignResponse(std::size_t iThr, std::size_t iReq, bool resp)
Assigns the response for the specified trigger.
auto gatesIn(TrackingGateColl &trackingGates)
std::size_t size(FixedBins< T, C > const &) noexcept
void applyAxisLabels(TAxis *pAxis, std::vector< std::string > const &labels, int first=1)
Sets all the labels starting with the bin first (1 by default).
TEfficiency & Eff(std::string const &name) const
fhicl::Sequence< unsigned int > MinimumPrimitives
std::unique_ptr< ResponseTree > fResponseTree
Handler of ROOT tree output.
TensorIndices class to flatten multi-dimension indices into linear.
bool hasLocation() const
Returns if the location of the trigger is set (undefined if !fired()).
std::string const & name() const
Returns the sandbox name.
std::unique_ptr< bool[]> RespTxxRxx
TH1 & Hist(std::string const &name) const
Helper data structure to store transient trigger result.
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
timescale_traits< OpticalTimeCategory >::tick_interval_t optical_time_ticks
icarus::trigger::TrackedOpticalTriggerGate< sbn::OpDetWaveformMeta > InputTriggerGate_t
Type of trigger gate extracted from the input event.
std::vector< WorkingTriggerGate_t > combineTriggerPrimitives(TriggerGatesPerCryostat_t const &cryoGates, std::string const &threshold) const
Computes the trigger response from primitives with the given threshold.
MajorityTriggerEfficiencyPlots(Parameters const &config)
Information about the event.
Converts a tensor element specification into a linear index.
electronics_time toElectronicsTime(FromTime time) const
Converts a time point into electronics time scale.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
void plotResponses(std::size_t iThr, std::string const &threshold, PlotSandboxRefs_t const &plotSets, EventInfo_t const &eventInfo, detinfo::DetectorClocksData const &clockData, std::vector< WorkingTriggerGate_t > const &combinedCounts, std::vector< ChannelID_t > const &channelList)
Completes the event trigger simulation and fills the plots.
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
A bunch of diverse utilities and futilities related to ROOT.
virtual void simulateAndPlot(std::size_t const thresholdIndex, TriggerGatesPerCryostat_t const &gates, EventInfo_t const &eventInfo, detinfo::DetectorClocksData const &clockData, PlotSandboxRefs_t const &selectedPlots) override
Simulates all trigger minimum requirements plots the results.
MajorityTriggerEfficiencyPlots & helper()
std::vector< PlotDef > plots
Utilities for the conversion of trigger gate data formats.
BEGIN_PROLOG vertical distance to the surface Name
Helper data structure to store PMT activity information in the event.
Simple class holding a tree.
auto sumGates(GateColl const &gates)
Sums all the gates in a collection.
Base class for _art_modules plotting trigger efficiencies.
util::MatrixIndices indices
virtual void analyze(art::Event const &event) override
Fills the plots. Also extracts the information to fill them with.
MajorityTriggerEfficiencyPlots const & helper() const
Access to the helper.
A wrapper to trigger gate objects tracking the contributions.
art::EDAnalyzer::Table< Config > Parameters
optical_tick atTick() const
Returns the time of the trigger (undefined if !fired()).
Contains all timing reference information for the detector.
std::string to_string(WindowPattern const &pattern)
then echo File list $list not found else cat $list while read file do echo $file sed s
A class exposing an upgraded interface of detinfo::DetectorClocksData.
Data types for detinfo::DetectorTimings.
Functions pulling in STL customization if available.
Selected information about the event.
std::vector< std::reference_wrapper< PlotSandbox const >> PlotSandboxRefs_t
List of references to plot sandboxes.
Opening_t level() const
Returns the opening level of the trigger (undefined if !fired()).
virtual void initializePlots(PlotCategories_t categories, std::vector< SettingsInfo_t > const &settings)
Initializes all the plot sets, one per PMT threshold.
std::vector< TriggerGates_t > TriggerGatesPerCryostat_t
Type of lists of gates, one list per cryostat (outer index: cryostat no).
MajorityTriggerEfficiencyPlots & operator=(MajorityTriggerEfficiencyPlots const &)=delete
detinfo::timescales::optical_tick optical_tick
void add(OpeningInfo_t info)
A helper to manage ROOT objects in a art::TFileDirectory.
std::size_t nTriggers() const
Returns the number of registered triggers.
The data type to uniquely identify a cryostat.
A helper to manage ROOT objects with consistent naming.
decltype(auto) gateIn(Gate &&gate)
Returns the trigger gate (a ReadoutTriggerGate) from the specified gate.
Produces plots about trigger simulation and trigger efficiency.