All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
icarus::trigger::TriggerEfficiencyPlots Class Reference

Produces plots about trigger simulation and trigger efficiency. More...

Inheritance diagram for icarus::trigger::TriggerEfficiencyPlots:

Classes

struct  Config
 

Public Types

using Parameters = art::EDAnalyzer::Table< Config >
 

Public Member Functions

 TriggerEfficiencyPlots (Parameters const &config)
 
 TriggerEfficiencyPlots (TriggerEfficiencyPlots const &)=delete
 
 TriggerEfficiencyPlots (TriggerEfficiencyPlots &&)=delete
 
TriggerEfficiencyPlotsoperator= (TriggerEfficiencyPlots const &)=delete
 
TriggerEfficiencyPlotsoperator= (TriggerEfficiencyPlots &&)=delete
 
virtual void analyze (art::Event const &event) override
 Fills the plots. Also extracts the information to fill them with. More...
 
virtual void endJob () override
 Prints end-of-job summaries. More...
 

Private Types

using microseconds = util::quantities::intervals::microseconds
 
using nanoseconds = util::quantities::intervals::nanoseconds
 
using TrackedTriggerGate_t = icarus::trigger::TrackedOpticalTriggerGate< sbn::OpDetWaveformMeta >
 Reconstituted trigger gate type internally used. More...
 
using TriggerGateData_t = icarus::trigger::OpticalTriggerGateData_t::GateData_t
 Type of gate data without channel information. More...
 
using PlotSandbox = icarus::trigger::PlotSandbox
 Import type. More...
 
using PlotSandboxRefs_t = std::vector< std::reference_wrapper< PlotSandbox const >>
 List of references to plot sandboxes. More...
 

Private Member Functions

void initializePlots (detinfo::DetectorClocksData const &clockData, PlotCategories_t const &categories)
 Initializes all the plot sets, one per threshold. More...
 
void initializePlotSet (detinfo::DetectorClocksData const &clockData, PlotSandbox &plots) const
 Initializes full set of plots for (ADC threshold + category) into plots. More...
 
void initializeEfficiencyPerTriggerPlots (detinfo::DetectorClocksData const &clockData, PlotSandbox &plots) const
 Initializes set of plots per complete trigger definition into plots. More...
 
void initializeEventPlots (PlotSandbox &plots) const
 Initializes a single, trigger-independent plot set into plots. More...
 
bool shouldPlotEvent (EventInfo_t const &eventInfo) const
 
std::vector< std::string > selectPlotCategories (EventInfo_t const &info, PlotCategories_t const &categories) const
 Returns the names of the plot categories event qualifies for. More...
 
EventInfo_t extractEventInfo (art::Event const &event, detinfo::DetectorClocksData const &clockData) const
 Extracts from event the relevant information on the physics event. More...
 
geo::TPCGeo const * pointInTPC (geo::Point_t const &point) const
 Returns the TPC point is within, nullptr if none. More...
 
geo::TPCGeo const * pointInActiveTPC (geo::Point_t const &point) const
 
std::vector< TriggerGateData_tcombineTriggerPrimitives (art::Event const &event, icarus::trigger::ADCCounts_t const threshold, art::InputTag const &dataTag) const
 Computes the trigger response from primitives with the given threshold. More...
 
void plotResponses (std::size_t iThr, icarus::trigger::ADCCounts_t const threshold, detinfo::DetectorTimings const &detTimings, PlotSandboxRefs_t const &plots, EventInfo_t const &info, std::vector< TriggerGateData_t > const &primitiveCounts) const
 Adds all the responses (one per threshold) to the plots. More...
 
std::vector< std::vector
< TrackedTriggerGate_t > > 
ReadTriggerGates (art::Event const &event, art::InputTag const &dataTag) const
 Reads a set of input gates from the event. More...
 

Static Private Member Functions

static std::string thrAndCatName (std::string const &boxName, std::string const &category)
 
static std::string thrAndCatName (PlotSandbox const &box, std::string const &category)
 
template<typename TrigGateColl >
static auto computeMaxGate (TrigGateColl const &gates)
 Returns a gate that is Max() of all the specified gates. More...
 

Private Attributes

std::vector< art::InputTag > fGeneratorTags
 Generator data product tags. More...
 
art::InputTag fDetectorParticleTag
 
std::vector< art::InputTag > fEnergyDepositTags
 Energy deposition data product tags. More...
 
std::map
< icarus::trigger::ADCCounts_t,
art::InputTag > 
fADCthresholds
 ADC thresholds to read, and the input tag connected to their data. More...
 
microseconds fBeamGateDuration
 Duration of the gate during with global optical triggers are accepted. More...
 
std::vector< unsigned int > fMinimumPrimitives
 Minimum number of trigger primitives for a trigger to happen. More...
 
nanoseconds fTriggerTimeResolution
 Trigger resolution in time. More...
 
bool fPlotOnlyActiveVolume
 Plot only events in active volume. More...
 
std::string const fLogCategory
 Message facility stream category for output. More...
 
std::string fLogEventDetails
 Steam where to print event info. More...
 
geo::GeometryCore const & fGeom
 
art::TFileDirectory fOutputDir
 ROOT directory where all the plots are written. More...
 
std::pair
< detinfo::timescales::optical_tick,
detinfo::timescales::optical_tick >
const 
fBeamGateOpt
 Beam gate start and stop tick in optical detector scale. More...
 
std::pair
< detinfo::timescales::simulation_time,
detinfo::timescales::simulation_time >
const 
fBeamGateSim
 Beam gate start and stop time in simulation scale. More...
 
std::vector< PlotSandboxfThresholdPlots
 All plots, one set per ADC threshold. More...
 
std::unique_ptr< EventIDTreefIDTree
 Handler of ROOT tree output. More...
 
std::unique_ptr< PlotInfoTreefPlotTree
 Handler of ROOT tree output. More...
 
std::unique_ptr< EventInfoTreefEventTree
 Handler of ROOT tree output. More...
 
std::unique_ptr< ResponseTreefResponseTree
 Handler of ROOT tree output. More...
 
std::atomic< unsigned int > nEvents { 0U }
 Count of seen events. More...
 
std::atomic< unsigned int > nPlottedEvents { 0U }
 Count of plotted events. More...
 

Detailed Description

Produces plots about trigger simulation and trigger efficiency.

Deprecated:
This module is deprecated for the ones derived from icarus::trigger::TriggerEfficiencyPlotsBase (e.g. SlidingWindowTriggerEfficiencyPlots).

This module produces sets of plots based on trigger primitives given in input.

The following documentation mainly deals with the most standard configuration and operations in ICARUS. This module and the ones upstream of it have quite some knobs that can be manipulated to test unorthodox configurations.

Overview of trigger simulation steps

This simulation only trigger primitives derived from the optical detector via hardware (V1730B boards). The trigger simulation branches from the standard simulation of optical detector waveforms (icarus::SimPMTIcarus module). From there, multiple steps are needed.

  1. Produce single-PMT-channel discriminated waveforms: the discrimination threshold can be chosen ("ADC threshold" or just "threshold" in the following), and the result is one binary discriminated waveform that has value 0 when the waveform is under threshold and 1 when it's above threshold, with the same time discretization as the PMT waveform. Each discriminated waveform spans the whole event readout time and therefore it may merge information from multiple readout waveforms (raw::OpDetWaveform), but all from the same optical detector channel. This step can be performed with the module icarus::trigger::DiscriminatePMTwaveforms.
  2. Combine the discriminated waveforms in pairs, in the same fashion as the V1730B readout board does to produce LVDS output. The output of this step is roughly half as many discriminated outputs as there were from the previous step (some channels are not paired). This output will be called trigger primitives because it is what the trigger logics is based on. We say that a trigger primitive is "on" when its level is 1. This step can be performed with the module icarus::trigger::LVDSgates.
  3. Simulate the trigger logic based on the trigger primitives _(see below)_. This usually includes the requirement of coincidence with the beam gate.

Trigger logic may be complex, being implemented in a FPGA. Many options are available, including:

This module (icarus::trigger::TriggerEfficiencyPlots) is designed for implementing a trigger logic based on coincidence of trigger primitives, and to plot trigger efficiency and related information based on a requirement of a minimum number of trigger primitives, in that enabling the simulation in the fashion of the first option above. More details on the steps performed by this module are documented later.

For the implementation of sliding window, different logic needs to be implemented, possibly keeping track of the location of each primitive, and different plots are needed as well. This module may provide a template for such implementation, but it hasn't been designed with enough flexibility to accommodate that directly.

Data objects for discriminated waveforms

See the documentation of icarus::trigger::TriggerEfficiencyPlotsBase.

On the terminology

In this documentation, the "discriminated waveforms" are sometimes called "trigger gates" and sometimes "trigger primitives". Although these concepts are, strictly, different, usually the difference does not affect the meaning and they end up being exchanged carelessly.

Trigger logic algorithm

This section describes the trigger logic algorithm used in icarus::trigger::TriggerEfficiencyPlots and its assumptions.

The algorithm treats all the trigger primitives equally, whether they originate from one or from two channels (or 10 or 30), and wherever their channels are in the detector. The trigger primitives are combined in a multi-level gate by adding them, so that the level of the resulting gate describes at any time matches how many trigger primitives are on at that time.

This multi-level gate is set in coincidence with the beam gate by multiplying the multi-level and the beam gates. The beam gate opens at a time configured in DetectorClocks service provider (detinfo::DetectorClocks::BeamGateTime()) and has a duration configured in this module (BeamGateDuration).

At this point, the trigger gate is a multi-level gate suppressed everywhere except than during the beam gate. The algorithm handles multiple trigger definitions, or requirements. Each requirement is simply how many trigger primitives must be open at the same time for the trigger to fire. The values of these requirements are set in the configuration (MinimumPrimitives). To determine whether a trigger with a given requirement, i.e. with a required minimum number of trigger primitives open at the same time, has fired, the gate is scanned to find the first tick where the level of the gate reaches or passes this minimum required number. If such tick exists, the trigger is considered to have fired, and at that time.

As a consequence, there are for each event as many different trigger responses as how many different requirements are configured in MinimumPrimitives, times how many ADC thresholds are provided in input, configured in Thresholds.

While there is a parameter describing the time resolution of the trigger (TriggerTimeResolution), this is currently only used for aesthetic purposes to choose the binning of some plots: the resolution is not superimposed to the gates (yet).

This algorithm is currently implemented in detinfo::trigger::TriggerEfficiencyPlots::plotResponses().

Event categories

Each event is assigned to a set of categories, and its information contributes to the plots of all those categories. The categories are defined in the PlotCategories list (hard-coded).

Module usage

Input data products

This module uses the following data products as input:

Output plots

The module produces a standard set of plots for each configured ADC threshold and for each event category. The plots are saved via art service TFileService in a ROOT file and they are organized in nested ROOT directories under the module label directory which is assigned by art:

Each of the inner ROOT directories contains a full set of plots, whose name is the standard plot name followed by its event category and threshold (e.g. Eff_NuCC_Thr15 for the trigger efficiency plot on neutrino charged current events with 15 ADC counts as PMT threshold).

Each set of plots, defined in icarus::trigger::TriggerEfficiencyPlots::initializePlotSet() (and, within, initializeEventPlots() and initializeEfficiencyPerTriggerPlots()), is contributed only by the events in the set category.

There are different "types" of plots. Some do not depend on triggering at all, like the deposited energy distribution. Others cross different trigger definitions, like the trigger efficiency as function of trigger requirement. Others still assume a single trigger definition: this is the case of trigger efficiency plots versus energy. Finally, there are plots that depend on a specific trigger definition and outcome: this is the case of all the plots including only triggering or non-triggering events.

A list of plots follows for each plot type. All the plots are always relative to a specific optical detector channel threshold (ADC) and a broad event category.

Plots independent of the triggers (selection plots)

These plots are stored directly in a threshold/category folder:

Note
In fact, these plots usually do not even depend on the ADC threshold of the optical detector channels. Nevertheless, they are stored in the folders under specific thresholds, and they are duplicate.

Plots including different trigger requirements

These plots collect information from scenarios with different trigger requirements, but still with the same underlying optical detector channel ADC threshold. They are also stored in the threshold/category folder:

Plots depending on a specific trigger definition

The following plots depend on the full definition of the trigger, including PMT thresholds and other requirements. They are hosted each in a subfolder of the threshold/category folder, with a name encoding the requirement: ReqXX for trigger with minimum required primitives XX.

The parameters are defined in the same way as in the selection plots, unless stated otherwise.

Plots depending on a specific trigger definition and response

These plots depend on the trigger definition, as the ones in the previous type, and on the actual trigger response. They are hosted each in a subfolder of the threshold/category/requirement folder, with a name encoding the response: triggering for triggering events, nontriggering for the others.

Their event pool is filtered to include only the events in the current category which also pass, or do not pass, the trigger requirement.

The plots are:

Configuration parameters

A terse description of the parameters is printed by running lar --print-description TriggerEfficiencyPlots.

An example job configuration is provided as maketriggerplots_icarus.fcl.

Technical description of the module

This module reads trigger gate data products from different ADC thresholds, and for each threahold it combines the data into a trigger response depending on a ADC threshold. It then applies different requirement levels and for each one it fills plots.

All the input sets (each with its own ADC treshold) are treated independently from each other.

We can separate the plots in two categories: the ones which depend on the trigger response, and the ones which do not. The latter include event-wide information like the total energy deposited in the detector by one event. They also include plots that depend on the ADC threshold, e.g. the largest number of trigger primitives available at any time during the event. Therefore there are more precisely three plot categories:

  1. plots which do not depend on the trigger primitives at all;
  2. plots which depend on the ADC threshold of the trigger primitives, but not on the trigger response;
  3. plots which depend on the trigger response (and therefore also on the ADC threshold of the trigger primitives).

In addition, each event is assigned to event categories. These categories do not depend on trigger primitives. For example, a electron neutrino neutral current interaction event would be assigned to the neutral current neutrino interaction category, to the electron neutrino category, and so on. A set of plot is produced at once for each of the event categories.

This module is designed as follows:

Note that the plots depending on the response may require multiple fillings. For example, the trigger efficiency plot is a single plot in the plot set which requires a filling for every requirement level. In a similar fashion, the plot of trigger time requires one filling for each requirement level that is met.

Organization of the plots

Plots are written on disk via the standard art service TFileService, which puts them in a ROOT subdirectory named as the instance of this module being run.

As described above, there are two "dimensions" for the plot sets: there is one plot set for each ADC threshold and for each event category, the total number of plot sets being the product of the options in the two dimensions.

The code is structured to work by threshold by threshold, because the trigger response depends on the threshold but not by the event category: the response is computed once per threshold, then all the plots related to that response (including all the event categories) are filled.

The structure in the file reflects this logic, and there are two levels of ROOT directories inside the one assigned by art to this module:

In each inner directory, a complete set of plots is contained. The name of each plot is a base name for that plot (e.g. Eff for the efficiency plot) with the event category tag and the threshold tag appended (separated by an underscore character, "_"). The title of the plot is also modified to include the description of the plot category (as defined in PlotCategory::description()) and the ADC threshold. Therefore, within the same module directory, all plot names are different.

Adding a plot

When adding a plot, two actions are necessary:

  1. initialize the new plot
  2. fill the new plot

The initialization happens in icarus::trigger::TriggerEfficiencyPlots::initializePlotSet() method. A request must be issued to the plot sandbox to "make" the plot. In general it can be expected that all the arguments args in a call plots.make<PlotType>(args) are forwarded to the constructor of PlotType, so that to make a new PlotType object one has to consult only the constructor of that class. Be aware though that the library expects the first argument to be the ROOT name of the new object and the second to be its ROOT title. It is possible to work around this requirement with additional coding.

The method performing the plotting is plotResponses(). The plots should be filled inside loops going through all plot sets. The existing code already does that in two loops, one for the plots depending on the trigger response requirement, and the other for the plots not depending on it.

About plot sandboxes

For the sake of this module, a plot sandbox is an object similar to a ROOT TDirectory, which can mangle the objects it contains to change ("process") their name and title, and that interacts properly with art::TFileDirectory so make TFileService happy. The processing of the name and title is used to add the category and threshold tags to the plot ROOT name and the corresponding annotations to the plot title, as described above.

Adding an event category

Event categories are listed in PlotCategories: each one is described by a simple object PlotCategory which contains a name (used in ROOT directories, plot name tags and to univocally identify the category), a description (used in plot titles) and a condition for the event to fulfill in order to qualify for the category. The condition is a function object that accepts an EventInfo_t object with the relevant event information, and returns its decision (true if the event belongs to this category).

To add a category, it is enough to append an entry at the end of the PlotCategories list, taking the existing ones as example.

The condition function adjudicates based on the information in EventInfo_t. It is likely though that if a new category is needed, the information currently available in EventInfo_t is not enough to decide the response. In that case, EventInfo_t must be extended to hold the newly required information. In addition, the method extractEventInfo() must be modified to set the new information. The documentation of that method expands on this topic.

Changing the trigger logic

The trigger logic is hard-coded in analyze(), but it effectively has a follow up in the plotting code. In fact, in analyze() the primitives are combined into a single object, but it is in plotResponses() that this object is interpreted to decide whether the trigger fired according to a requirement.

To implement a radically different trigger logic, several components need to be coordinated:

  1. configuration of trigger logic parameters
  2. combination of trigger primitives;
  3. the data structure the combination is stored in;
  4. interpretation of that data structure in terms of trigger firing;
  5. configuration of the trigger logic from user parameters.

Because of the design of this module, the first and the third elements are in different places (causing the necessity of the shared data structure that is the second element) and changing one typically imply changing the other.

This module simulates a trigger counting the number of primitives that are "on" and imposing a required minimum on that number for the trigger to fire. This is how this implementation includes those elements:

  1. combination of trigger primitives: primitives are summed into a single multilevel gate (with beam gate on top);
  2. the data structure the combination is stored in: a trigger gate object;
  3. interpretation of that data structure in terms of trigger firing: the logic requires a minimum number of primitives being on at the same time; the interpretation uses the level of the combined trigger gate as the number of primitives on at every time, and decides that the first time this number meets the requirement, the trigger fires;
  4. configuration of the trigger logic from user parameters: it's a parameter of the module itself (MinimumPrimitives).

An example of how a different trigger logic could be implemented following a similar model. Let's assume we want a trigger based on two sliding windows. A window is a group of LVDS signals from neighboring channels. We can split the whole optical detector channels into many windows, and we can make the windows overlap: for example, a window includes the first 30 channels behind one anode plane, the second window includes 30 channels starting from the fifteenth, the third window includes 30 channels starting from the thirtieth, and so on. In ICARUS, 30 channels are served in 16 LVDS discriminated waveforms, i.e. 16 trigger primitives. We may require as a loose trigger that any window contains at least 10 primitives on at the same time (that is about 20 PMT channels beyond ADC threshold), and as a tighter trigger that there is a window with at least 8 trigger primitives on, and the corresponding window in the opposite TPC has at least 6 primitives on at the same time. Note that a splitting 7/7 won't do: one of the two windows must have 8 or more primitives on. The input primitives from the point of view of the module now become the "sliding window" combination of the LVDS trigger primitives, as produced e.g. by icarus::trigger::SlidingWindowTrigger module. How this can be implemented following the pattern of this module:

  1. combination of trigger primitives: we prepare two primitives: one describes the maximum level among all the windows, and the other describes the level of the window opposite to the maximum (the way to achieve this is quite complicate);
  2. the data structure the combination is stored in: two trigger gate objects;
  3. interpretation of that data structure in terms of trigger firing: for the loose trigger, we look for the first time the maximum window level reaches the designated threshold; for the tighter trigger, some additional logic is required, discriminating the maximum window level primitive to the higher threshold, the opposite window level on the lower threshold, and setting them in coincidence; then the time the resulting gate opens, if any, is the trigger time;
  4. configuration of trigger logic parameters: the two requirements (single window, double window with their minimum number of LVDS primitives) are read from the module FHiCL configuration; for computing efficiency, either in the constructor or in a beginJob() method we may also prepare the associations (pairing) between opposite windows or just channels;
Todo:
add ability to discriminate a trigger gate object? discrimination on level N (>=N -> 1, <N -> 0) can be obtained with adding a _-N_ uniform level, flooring on level 0 and (if needed) maxing on level 1.

Code style: quantities with units

To avoid issues with missing or wrong conversions, this code often uses LArSoft quantities library. A variable with a Quantity type is represented with a specific unit (e.g. microseconds) and can undergo only limited manipulation. The allowed manipulation should guarantee that the unit of the quantity is correctly preserved. For example, it is not possible to add to a microseconds interval a pure number (e.g. 9.0), but rather it is only possible to add time quantities (e.g. another microseconds variable, or a nanoseconds variable, or a literal value with unit, like 9.0_ns), and those quantities are properly converted, with the caveat that rounding errors may happen that a more careful explicit handling could avoid. Also, there are two types of variables that can feature the same unit, intervals and points. A point can't be scaled (e.g. you can't "double" the time the beam gate opens, while you can double the beam gate duration) and it can't be added to another point (the difference between two points is an interval).

To avoid mistakes in the conversion between different time scales, the LArSoft utility library detinfo::DetectorTimings is used, which is a wrapper of DetectorClocks service provider that makes the interface to convert times easier and uniform. Here we use it to convert time points from the simulation (which are expressed in nanoseconds and are starting at trigger time) into optical detector readout ticks, and vice versa. The values returned by this library have encoded in them which time scale they belong to, and in which unit they are measured.

Definition at line 1217 of file TriggerEfficiencyPlots_module.cc.

Member Typedef Documentation

Definition at line 1219 of file TriggerEfficiencyPlots_module.cc.

Definition at line 1220 of file TriggerEfficiencyPlots_module.cc.

Definition at line 1299 of file TriggerEfficiencyPlots_module.cc.

Import type.

Definition at line 1336 of file TriggerEfficiencyPlots_module.cc.

using icarus::trigger::TriggerEfficiencyPlots::PlotSandboxRefs_t = std::vector<std::reference_wrapper<PlotSandbox const>>
private

List of references to plot sandboxes.

Definition at line 1340 of file TriggerEfficiencyPlots_module.cc.

Reconstituted trigger gate type internally used.

Definition at line 1330 of file TriggerEfficiencyPlots_module.cc.

Type of gate data without channel information.

Definition at line 1334 of file TriggerEfficiencyPlots_module.cc.

Constructor & Destructor Documentation

icarus::trigger::TriggerEfficiencyPlots::TriggerEfficiencyPlots ( Parameters const &  config)
explicit

Definition at line 1508 of file TriggerEfficiencyPlots_module.cc.

1509  : art::EDAnalyzer(config)
1510  // configuration
1511  , fGeneratorTags (config().GeneratorTags())
1512  , fDetectorParticleTag (config().DetectorParticleTag())
1513  , fEnergyDepositTags (config().EnergyDepositTags())
1514  , fBeamGateDuration (config().BeamGateDuration())
1515  , fMinimumPrimitives (config().MinimumPrimitives())
1516  , fTriggerTimeResolution(config().TriggerTimeResolution())
1517  , fPlotOnlyActiveVolume (config().PlotOnlyActiveVolume())
1518  , fLogCategory (config().LogCategory())
1519  // services
1520  , fGeom (*lar::providerFrom<geo::Geometry>())
1521  , fOutputDir (*art::ServiceHandle<art::TFileService>())
1522  // cached
1523 {
1524  //
1525  // more complex parameter parsing
1526  //
1527  if (config().EventDetailsLogCategory(fLogEventDetails)) {
1528  // the parameter is somehow set, so fLogEventDetails won't be empty;
1529  // but if the parameter value is specified empty, we set it to fLogCategory
1531  } // if EventDetailsLogCategory is specified
1532 
1533  std::string const discrModuleLabel = config().TriggerGatesTag();
1534  for (raw::ADC_Count_t threshold: config().Thresholds()) {
1536  = art::InputTag{ discrModuleLabel, util::to_string(threshold) };
1537  }
1538 
1539  if (config().EventTreeName.hasValue()) {
1540  std::string treeName;
1541  config().EventTreeName(treeName);
1542 
1543  fIDTree = std::make_unique<EventIDTree>
1544  (*(fOutputDir.make<TTree>(treeName.c_str(), "Event information")));
1545  fEventTree = std::make_unique<EventInfoTree>(fIDTree->tree());
1546  fPlotTree = std::make_unique<PlotInfoTree>(fIDTree->tree());
1547  fResponseTree = std::make_unique<ResponseTree>(
1548  fIDTree->tree(),
1549  util::get_elements<0U>(fADCthresholds), fMinimumPrimitives
1550  );
1551 
1552  } // if make tree
1553 
1554  //
1555  // input data declaration
1556  //
1557  using icarus::trigger::OpticalTriggerGateData_t; // for convenience
1558 
1559  // event information
1560  for (art::InputTag const& inputTag: fGeneratorTags)
1561  consumes<std::vector<simb::MCTruth>>(inputTag);
1562  for (art::InputTag const& inputTag: fEnergyDepositTags)
1563  consumes<std::vector<sim::SimEnergyDeposit>>(inputTag);
1564 // consumes<std::vector<simb::MCParticle>>(fDetectorParticleTag);
1565 
1566  // trigger primitives
1567  for (art::InputTag const& inputDataTag: util::const_values(fADCthresholds)) {
1568  icarus::trigger::TriggerGateReader{ inputDataTag }
1570  } // for
1571 
1572  //
1573  // initialization of plots and plot categories
1574  //
1575  auto const clockData
1576  = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
1577 
1578  initializePlots(clockData, ::PlotCategories);
1579  {
1580  mf::LogInfo log(fLogCategory);
1581  log << "\nConfigured " << fADCthresholds.size() << " thresholds:";
1582  for (auto const& [ threshold, dataTag ]: fADCthresholds)
1583  log << "\n * " << threshold << " ADC (from '" << dataTag.encode() << "')";
1584 
1585  auto const beamGate = icarus::trigger::makeBeamGateStruct
1587  log << "\nBeam gate used for plot ranges: " << beamGate.asSimulationRange();
1588  } // local block
1589 
1590 } // icarus::trigger::TriggerEfficiencyPlots::TriggerEfficiencyPlots()
BEGIN_PROLOG BeamGateDuration pmtthr physics producers trigtilewindowORS Thresholds
std::string fLogEventDetails
Steam where to print event info.
nanoseconds fTriggerTimeResolution
Trigger resolution in time.
std::vector< unsigned int > fMinimumPrimitives
Minimum number of trigger primitives for a trigger to happen.
decltype(auto) const_values(Coll &&coll)
Range-for loop helper iterating across the constant values of the specified collection.
void declareConsumes(ConsumesCollector &collector) const
Declares to the collector the data products that are going to be read.
art::TFileDirectory fOutputDir
ROOT directory where all the plots are written.
Assembles and returns trigger gates from serialized data.
std::unique_ptr< ResponseTree > fResponseTree
Handler of ROOT tree output.
PlotCategories_t const PlotCategories
List of event categories.
std::vector< art::InputTag > fGeneratorTags
Generator data product tags.
void initializePlots(detinfo::DetectorClocksData const &clockData, PlotCategories_t const &categories)
Initializes all the plot sets, one per threshold.
microseconds fBeamGateDuration
Duration of the gate during with global optical triggers are accepted.
TimeRange< simulation_time > const & asSimulationRange() const
Returns the gate as start/stop pair in simulation time scale.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
A value measured in the specified unit.
Definition: quantities.h:566
icarus::trigger::ReadoutTriggerGate< TriggerGateTick_t, TriggerGateTicks_t, raw::Channel_t > OpticalTriggerGateData_t
Type of trigger gate data serialized into art data products.
std::unique_ptr< PlotInfoTree > fPlotTree
Handler of ROOT tree output.
std::string const fLogCategory
Message facility stream category for output.
std::unique_ptr< EventInfoTree > fEventTree
Handler of ROOT tree output.
std::map< icarus::trigger::ADCCounts_t, art::InputTag > fADCthresholds
ADC thresholds to read, and the input tag connected to their data.
std::vector< art::InputTag > fEnergyDepositTags
Energy deposition data product tags.
bool fPlotOnlyActiveVolume
Plot only events in active volume.
BeamGateStruct makeBeamGateStruct(detinfo::DetectorTimings const &detTimings, util::quantities::intervals::microseconds duration, util::quantities::intervals::microseconds delay=util::quantities::intervals::microseconds{0.0})
Creates a BeamGateStruct object of specified duration and start.
A class exposing an upgraded interface of detinfo::DetectorClocksData.
std::unique_ptr< EventIDTree > fIDTree
Handler of ROOT tree output.
fDetProps &fDetProps fDetProps &fDetProps consumesCollector())
icarus::trigger::TriggerEfficiencyPlots::TriggerEfficiencyPlots ( TriggerEfficiencyPlots const &  )
delete
icarus::trigger::TriggerEfficiencyPlots::TriggerEfficiencyPlots ( TriggerEfficiencyPlots &&  )
delete

Member Function Documentation

void icarus::trigger::TriggerEfficiencyPlots::analyze ( art::Event const &  event)
overridevirtual

Fills the plots. Also extracts the information to fill them with.

Gate representing the time we expect light from beam interactions.

Definition at line 1594 of file TriggerEfficiencyPlots_module.cc.

1594  {
1595 
1596  /*
1597  * 1. find out the features of the event and the categories it belongs to
1598  * 2. for each threshold:
1599  * 1. read the trigger primitives
1600  * 2. apply the beam gate on the primitives
1601  * 3. (optional) combine the trigger primitives
1602  * 4. generate the trigger response
1603  * 5. pick the plots to be filled
1604  * 6. add the response to all the plots
1605  *
1606  */
1607 
1608  ++nEvents;
1609 
1610  //
1611  // 1. find out the features of the event and the categories it belongs to
1612  //
1613  auto const clockData
1614  = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(event);
1615  detinfo::DetectorTimings const detTimings{clockData};
1616  EventInfo_t const eventInfo = extractEventInfo(event, clockData);
1617 
1618  bool const bPlot = shouldPlotEvent(eventInfo);
1619  if (bPlot) ++nPlottedEvents;
1620 
1621  if (fIDTree) fIDTree->assignEvent(event);
1622  if (fPlotTree) fPlotTree->assign(bPlot);
1623  if (fEventTree) fEventTree->assignEvent(eventInfo);
1624 
1625  std::vector<std::string> selectedPlotCategories
1626  = selectPlotCategories(eventInfo, ::PlotCategories);
1627  {
1628  mf::LogTrace log(fLogCategory);
1629  log
1630  << "Event " << event.id() << " falls in " << selectedPlotCategories.size()
1631  << " categories:"
1632  ;
1633  for (std::string const& name: selectedPlotCategories)
1634  log << " \"" << name << "\"";
1635  // print the information on the event
1636  } // local block
1637  if (!fLogEventDetails.empty()) {
1638  mf::LogTrace(fLogEventDetails)
1639  << "Event " << event.id() << ": " << eventInfo;
1640  }
1641 
1642  //
1643  // 2. for each threshold:
1644  //
1645  /// Gate representing the time we expect light from beam interactions.
1646  auto const beam_gate = icarus::trigger::BeamGateMaker{clockData}(fBeamGateDuration);
1647 
1648  for (auto&& [ iThr, thrPair, thrPlots ]
1650  ) {
1651 
1652  auto const& [ threshold, dataTag ] = thrPair;
1653 
1654  //
1655  // 1.1. read the trigger primitives
1656  // 1.2. (optional) combine the trigger primitives
1657  // 1.3. apply the beam gate on the primitives
1658  // 1.4. generate the trigger response
1659  //
1660 
1661  std::vector<TriggerGateData_t> primitiveCounts;
1662  std::vector<TriggerGateData_t> combinedTriggerPrimitives
1663  = combineTriggerPrimitives(event, threshold, dataTag);
1664 
1665  for (TriggerGateData_t combinedPrimitive: combinedTriggerPrimitives) {
1666  TriggerGateData_t const primitiveCount
1667  = combinedPrimitive.Mul(beam_gate);
1668 
1669  primitiveCounts.push_back(primitiveCount);
1670  }
1671 
1672  //
1673  // 1.5. pick the plots to be filled
1674  //
1675  PlotSandboxRefs_t selectedPlots;
1676 
1677  if (bPlot) {
1678  for (std::string const& name: selectedPlotCategories)
1679  selectedPlots.emplace_back(*(thrPlots.findSandbox(name)));
1680  }
1681 
1682  // 1.6. add the response to the appropriate plots
1683  plotResponses(iThr, threshold, detTimings, selectedPlots, eventInfo, primitiveCounts);
1684 
1685  } // for thresholds
1686 
1687 
1688  //
1689  // store information in output tree if any
1690  //
1691  if (fIDTree) fIDTree->tree().Fill();
1692 
1693 } // icarus::trigger::TriggerEfficiencyPlots::analyze()
std::string fLogEventDetails
Steam where to print event info.
std::vector< std::string > selectPlotCategories(EventInfo_t const &info, PlotCategories_t const &categories) const
Returns the names of the plot categories event qualifies for.
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
PlotCategories_t const PlotCategories
List of event categories.
Information about the event.
triggergatedata_t & Mul(triggergatedata_t const &other)
Combines with a gate, keeping the product of openings of the two.
EventInfo_t extractEventInfo(art::Event const &event, detinfo::DetectorClocksData const &clockData) const
Extracts from event the relevant information on the physics event.
microseconds fBeamGateDuration
Duration of the gate during with global optical triggers are accepted.
std::vector< PlotSandbox > fThresholdPlots
All plots, one set per ADC threshold.
std::atomic< unsigned int > nEvents
Count of seen events.
std::atomic< unsigned int > nPlottedEvents
Count of plotted events.
bool shouldPlotEvent(EventInfo_t const &eventInfo) const
std::unique_ptr< PlotInfoTree > fPlotTree
Handler of ROOT tree output.
void plotResponses(std::size_t iThr, icarus::trigger::ADCCounts_t const threshold, detinfo::DetectorTimings const &detTimings, PlotSandboxRefs_t const &plots, EventInfo_t const &info, std::vector< TriggerGateData_t > const &primitiveCounts) const
Adds all the responses (one per threshold) to the plots.
std::string const fLogCategory
Message facility stream category for output.
std::unique_ptr< EventInfoTree > fEventTree
Handler of ROOT tree output.
std::map< icarus::trigger::ADCCounts_t, art::InputTag > fADCthresholds
ADC thresholds to read, and the input tag connected to their data.
A class exposing an upgraded interface of detinfo::DetectorClocksData.
Simple utility to generate gates around beam time.
Definition: BeamGateMaker.h:49
std::vector< TriggerGateData_t > combineTriggerPrimitives(art::Event const &event, icarus::trigger::ADCCounts_t const threshold, art::InputTag const &dataTag) const
Computes the trigger response from primitives with the given threshold.
then echo fcl name
icarus::trigger::OpticalTriggerGateData_t::GateData_t TriggerGateData_t
Type of gate data without channel information.
fDetProps &fDetProps fDetProps &fDetProps detTimings
std::vector< std::reference_wrapper< PlotSandbox const >> PlotSandboxRefs_t
List of references to plot sandboxes.
std::unique_ptr< EventIDTree > fIDTree
Handler of ROOT tree output.
auto icarus::trigger::TriggerEfficiencyPlots::combineTriggerPrimitives ( art::Event const &  event,
icarus::trigger::ADCCounts_t const  threshold,
art::InputTag const &  dataTag 
) const
private

Computes the trigger response from primitives with the given threshold.

Definition at line 2181 of file TriggerEfficiencyPlots_module.cc.

2185  {
2186 
2187  //
2188  // simple count
2189  //
2190 
2191  std::vector<std::vector<TrackedTriggerGate_t>> const& cryoGates
2192  = ReadTriggerGates(event, dataTag);
2193 
2194  std::vector<TriggerGateData_t> cryoCombinedGate;
2195 
2196  for (auto const& gates: (cryoGates)) {
2197  mf::LogTrace(fLogCategory)
2198  << "Simulating trigger response with ADC threshold " << threshold
2199  << " from '" << dataTag.encode() << "' (" << gates.size() << " primitives)";
2200 
2201  if (gates.empty()) { // this is unexpected...
2202  mf::LogWarning(fLogCategory)
2203  << " No trigger primitive found for threshold " << threshold
2204  << " ('" << dataTag.encode() << "')";
2205  return {};
2206  } // if no gates
2207 
2208  TrackedTriggerGate_t combinedGate = icarus::trigger::sumGates(gates);
2209 
2210  cryoCombinedGate.push_back(std::move(combinedGate).gate()) ;
2211  }
2212 
2213  return cryoCombinedGate;
2214 } // icarus::trigger::TriggerEfficiencyPlots::combineTriggerPrimitives()
std::vector< std::vector< TrackedTriggerGate_t > > ReadTriggerGates(art::Event const &event, art::InputTag const &dataTag) const
Reads a set of input gates from the event.
std::string const fLogCategory
Message facility stream category for output.
auto sumGates(GateColl const &gates)
Sums all the gates in a collection.
icarus::trigger::TrackedOpticalTriggerGate< sbn::OpDetWaveformMeta > TrackedTriggerGate_t
Reconstituted trigger gate type internally used.
template<typename TrigGateColl >
auto icarus::trigger::TriggerEfficiencyPlots::computeMaxGate ( TrigGateColl const &  gates)
staticprivate

Returns a gate that is Max() of all the specified gates.

Definition at line 2221 of file TriggerEfficiencyPlots_module.cc.

2222 {
2223 
2224  // if `gates` is empty return a default-constructed gate of the contained type
2225  if (empty(gates)) return decltype(*begin(gates)){};
2226 
2227  auto iGate = cbegin(gates);
2228  auto const gend = cend(gates);
2229  auto maxGate = *iGate;
2230  while (++iGate != gend) maxGate.Max(*iGate);
2231 
2232  return maxGate;
2233 } // icarus::trigger::TriggerEfficiencyPlots::computeMaxGate()
auto cbegin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:567
auto cend(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:579
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
bool empty(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:555
void icarus::trigger::TriggerEfficiencyPlots::endJob ( )
overridevirtual

Prints end-of-job summaries.

Definition at line 1697 of file TriggerEfficiencyPlots_module.cc.

1697  {
1698 
1699  mf::LogInfo(fLogCategory)
1700  << nPlottedEvents << "/" << nEvents << " events plotted."
1701  ;
1702 
1703 } // icarus::trigger::TriggerEfficiencyPlots::endJob()
std::atomic< unsigned int > nEvents
Count of seen events.
std::atomic< unsigned int > nPlottedEvents
Count of plotted events.
std::string const fLogCategory
Message facility stream category for output.
auto icarus::trigger::TriggerEfficiencyPlots::extractEventInfo ( art::Event const &  event,
detinfo::DetectorClocksData const &  clockData 
) const
private

Extracts from event the relevant information on the physics event.

This returns a EventInfo_t object filled as completely as possible. The result is used in the context of assigning the `event` to categories.

This method can read any data product in the event, and has access to the module configuration. If information is needed from a data product that is not read yet, the following actions are needed:

  1. decide the input tag of the data product(s) to be read; this is usually delegated to the user via module configuration (see Config structure);
  2. the required input tags need to be stored into TriggerEfficiencyPlots object;
  3. art needs to be informed of the intention of reading the data products via consumes() or equivalent calls, in TriggerEfficiencyPlots constructor;
  4. the data product can be read with the usual means in this method.

For an example of this procedure, see how the configuration parameter DetectorParticleTag is treated: read by Config::DetectorParticleTag, stored in fDetectorParticleTag, declared as "consumed" in TriggerEfficiencyPlots constructor. Likewise a known list of data products can be used: see GeneratorTags parameter, read by the sequence Config::GeneratorTags, stored in the class field fGeneratorTags, declared as "consumed" in a loop in TriggerEfficiencyPlots constructor, and read in extractEventInfo() to be used within it.

Definition at line 2047 of file TriggerEfficiencyPlots_module.cc.

2048 {
2049 
2050  EventInfo_t info;
2051 
2052  //
2053  // generator information
2054  //
2055  for (art::InputTag const& inputTag: fGeneratorTags) {
2056 
2057  auto const& truthRecords
2058  = *(event.getValidHandle<std::vector<simb::MCTruth>>(inputTag));
2059 
2060  for (simb::MCTruth const& truth: truthRecords) {
2061 
2062  if (truth.NeutrinoSet()) {
2063  //
2064  // interaction flavor (nu_mu, nu_e)
2065  // interaction type (CC, NC)
2066  //
2067 
2068  simb::MCParticle const& nu = truth.GetNeutrino().Nu();
2069  info.SetNeutrinoPDG(nu.PdgCode());
2070  info.SetInteractionType(truth.GetNeutrino().InteractionType());
2071 
2072  info.SetNeutrinoEnergy(GeV{ nu.E() });
2073  info.SetLeptonEnergy(GeV{ truth.GetNeutrino().Lepton().E() });
2074  //info.SetNucleonEnergy(truth.GetNeutrino().HitNuc().E());
2075 
2076  switch (nu.PdgCode()) {
2077  case 14:
2078  case -14:
2079  info.SetNu_mu(true);
2080  break;
2081  case 12:
2082  case -12:
2083  info.SetNu_e(true);
2084  break;
2085  }
2086 
2087  switch (truth.GetNeutrino().CCNC()) {
2088  case simb::kCC: info.AddWeakChargedCurrentInteractions(); break;
2089  case simb::kNC: info.AddWeakNeutralCurrentInteractions(); break;
2090  default:
2091  mf::LogWarning(fLogCategory)
2092  << "Event " << event.id() << " has unexpected NC/CC flag ("
2093  << truth.GetNeutrino().CCNC() << ")";
2094  } // switch
2095 
2096  // we do not trust the vertex (`GvX()`) of the neutrino particle,
2097  // since GenieHelper does not translate the vertex
2098  // of some of the particles from GENIE to detector frame;
2099  // trajectory is always translated:
2100  geo::Point_t const vertex { nu.EndX(), nu.EndY(), nu.EndZ() };
2101  info.AddVertex(vertex);
2102 
2103  geo::TPCGeo const* tpc = pointInActiveTPC(vertex);
2104  if (tpc) info.SetInActiveVolume();
2105 
2106  } // if neutrino event
2107 
2108  } // for truth records
2109 
2110  } // for generators
2111 
2112  //
2113  // propagation in the detector
2114  //
2115  GeV totalEnergy { 0.0 }, inSpillEnergy { 0.0 };
2116  GeV activeEnergy { 0.0 }, inSpillActiveEnergy { 0.0 };
2117 
2118  detinfo::DetectorTimings const detTimings{clockData};
2119  auto const beam_gate_opt = std::make_pair(detTimings.toOpticalTick(detTimings.BeamGateTime()),
2120  detTimings.toOpticalTick(detTimings.BeamGateTime() + fBeamGateDuration));
2121  auto const beam_gate_sim = std::make_pair(detTimings.toSimulationTime(beam_gate_opt.first),
2122  detTimings.toSimulationTime(beam_gate_opt.second));
2123  for (art::InputTag const& edepTag: fEnergyDepositTags) {
2124 
2125  auto const& energyDeposits
2126  = *(event.getValidHandle<std::vector<sim::SimEnergyDeposit>>(edepTag));
2127  mf::LogTrace(fLogCategory)
2128  << "Event " << event.id() << " has " << energyDeposits.size()
2129  << " energy deposits recorded in '" << edepTag.encode() << "'";
2130 
2131  for (sim::SimEnergyDeposit const& edep: energyDeposits) {
2132 
2133  MeV const e { edep.Energy() }; // assuming it's stored in MeV
2134 
2135  detinfo::timescales::simulation_time const t { edep.Time() };
2136  bool const inSpill
2137  = (t >= beam_gate_sim.first) && (t <= beam_gate_sim.second);
2138 
2139  totalEnergy += e;
2140  if (inSpill) inSpillEnergy += e;
2141 
2142  if (pointInActiveTPC(edep.MidPoint())) {
2143  activeEnergy += e;
2144  if (inSpill) inSpillActiveEnergy += e;
2145  }
2146 
2147  } // for all energy deposits in the data product
2148 
2149  } // for all energy deposit tags
2150 
2151  info.SetDepositedEnergy(totalEnergy);
2152  info.SetDepositedEnergyInSpill(inSpillEnergy);
2153  info.SetDepositedEnergyInActiveVolume(activeEnergy);
2154  info.SetDepositedEnergyInActiveVolumeInSpill(inSpillActiveEnergy);
2155 
2156  mf::LogTrace(fLogCategory) << "Event " << event.id() << ": " << info;
2157 
2158  return info;
2159 } // icarus::trigger::TriggerEfficiencyPlots::extractEventInfo()
process_name vertex
Definition: cheaterreco.fcl:51
void SetInteractionType(int type)
void AddWeakNeutralCurrentInteractions(unsigned int n=1U)
Marks this event as including n more weak neutral current interactions.
void SetNu_mu(bool numu)
Marks the neutrino flavor.
Geometry information for a single TPC.
Definition: TPCGeo.h:38
Information about the event.
void SetNeutrinoPDG(int NU)
Marks this event&#39;s neutrino type.
Charged-current interactions.
Definition: IPrediction.h:38
std::vector< art::InputTag > fGeneratorTags
Generator data product tags.
microseconds fBeamGateDuration
Duration of the gate during with global optical triggers are accepted.
geo::TPCGeo const * pointInActiveTPC(geo::Point_t const &point) const
timescale_traits< SimulationTimeCategory >::time_point_t simulation_time
A point in time on the simulation time scale.
A value measured in the specified unit.
Definition: quantities.h:566
void SetInActiveVolume(bool active=true)
Set whether the event has relevant activity in the active volume.
std::string const fLogCategory
Message facility stream category for output.
void AddWeakChargedCurrentInteractions(unsigned int n=1U)
Marks this event as including n more weak charged current interactions.
std::vector< art::InputTag > fEnergyDepositTags
Energy deposition data product tags.
void AddVertex(geo::Point_t const &vertex)
Adds a point to the list of interaction vertices in the event.
A class exposing an upgraded interface of detinfo::DetectorClocksData.
Energy deposition in the active material.
do i e
Neutral-current interactions.
Definition: IPrediction.h:39
void SetDepositedEnergyInActiveVolumeInSpill(GeV e)
void SetDepositedEnergy(GeV e)
Sets the total deposited energy of the event [GeV].
void SetDepositedEnergyInActiveVolume(GeV e)
Sets the total deposited energy of the event in active volume [GeV].
fDetProps &fDetProps fDetProps &fDetProps detTimings
void SetDepositedEnergyInSpill(GeV e)
Sets the energy of the event deposited during beam gate [GeV].
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
BEGIN_PROLOG SN nu
void icarus::trigger::TriggerEfficiencyPlots::initializeEfficiencyPerTriggerPlots ( detinfo::DetectorClocksData const &  clockData,
PlotSandbox plots 
) const
private

Initializes set of plots per complete trigger definition into plots.

Definition at line 1887 of file TriggerEfficiencyPlots_module.cc.

1888 {
1889  detinfo::DetectorTimings const detTimings{clockData};
1890  detinfo::timescales::optical_time_ticks const triggerResolutionTicks
1891  { detTimings.toOpticalTicks(fTriggerTimeResolution) };
1892 
1893  auto const beam_gate_opt = std::make_pair(detTimings.toOpticalTick(detTimings.BeamGateTime()),
1894  detTimings.toOpticalTick(detTimings.BeamGateTime() + fBeamGateDuration));
1895  //
1896  // Triggering efficiency vs. something else
1897  //
1898  plots.make<TEfficiency>(
1899  "EffVsEnergyInSpill",
1900  "Efficiency of triggering vs. energy deposited in spill"
1901  ";energy deposited in spill [ GeV ]"
1902  ";trigger efficiency [ / 50 GeV ]",
1903  120, 0.0, 6.0 // 6 GeV should be enough for a MIP crossing 20 m of detector
1904  );
1905 
1906  plots.make<TEfficiency>(
1907  "EffVsEnergyInSpillActive",
1908  "Efficiency of triggering vs. energy deposited in active volume"
1909  ";energy deposited in active volume in spill [ GeV ]"
1910  ";trigger efficiency [ / 50 GeV ]",
1911  120, 0.0, 6.0 // 6 GeV should be enough for a MIP crossing 20 m of detector
1912  );
1913 
1914  plots.make<TEfficiency>(
1915  "EffVsNeutrinoEnergy",
1916  "Efficiency of triggering vs. neutrino energy"
1917  ";neutrino true energy [ GeV ]"
1918  ";trigger efficiency [ / 50 GeV ]",
1919  120, 0.0, 6.0 // 6 GeV is not that much for NuMI, but we should be ok
1920  );
1921 
1922  plots.make<TEfficiency>(
1923  "EffVsLeptonEnergy",
1924  "Efficiency of triggering vs. outgoing lepton energy"
1925  ";final state lepton true energy [ GeV ]"
1926  ";trigger efficiency [ / 50 GeV ]",
1927  120, 0.0, 6.0
1928  );
1929 
1930  plots.make<TH1F>(
1931  "TriggerTick",
1932  "Trigger time tick"
1933  ";optical time tick [ /" + util::to_string(triggerResolutionTicks) + " ]",
1934  (beam_gate_opt.second - beam_gate_opt.first) / triggerResolutionTicks,
1935  beam_gate_opt.first.value(), beam_gate_opt.second.value()
1936  );
1937 
1938 } // initializeEfficiencyPerTriggerPlots()
nanoseconds fTriggerTimeResolution
Trigger resolution in time.
timescale_traits< OpticalTimeCategory >::tick_interval_t optical_time_ticks
microseconds fBeamGateDuration
Duration of the gate during with global optical triggers are accepted.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
std::vector< PlotDef > plots
Definition: demo.h:54
A class exposing an upgraded interface of detinfo::DetectorClocksData.
fDetProps &fDetProps fDetProps &fDetProps detTimings
void icarus::trigger::TriggerEfficiencyPlots::initializeEventPlots ( PlotSandbox plots) const
private

Initializes a single, trigger-independent plot set into plots.

Definition at line 1943 of file TriggerEfficiencyPlots_module.cc.

1944 {
1945 
1946  // a variable binning for the required number of trigger primitives
1947  auto [ minimumPrimBinning, minimumPrimBinningLabels ]
1949  assert(minimumPrimBinning.size() == minimumPrimBinningLabels.size() + 1U);
1950 
1951  {
1952  mf::LogTrace log(fLogCategory);
1953  log << "TriggerEfficiencyPlots (plots '"
1954  << plots.name() << "') variable binning including the "
1955  << fMinimumPrimitives.size() << " points {";
1956  for (auto value: fMinimumPrimitives) log << " " << value;
1957  log << " } => " << minimumPrimBinningLabels.size() << " bins: ";
1958  for (auto const& [ value, label ]
1959  : util::zip<1U>(minimumPrimBinning, minimumPrimBinningLabels))
1960  {
1961  log << " " << value << " (\"" << label << "\") =>";
1962  } // for
1963  log << " " << minimumPrimBinning.back();
1964  } // debug output block
1965 
1966  //
1967  // Selection-related plots
1968  //
1969  plots.make<TH1F>(
1970  "NeutrinoEnergy",
1971  "True Neutrino Energy"
1972  ";neutrino energy [GeV]"
1973  ";events",
1974  120, 0.0, 6.0 // GeV
1975  );
1976  plots.make<TH1F>(
1977  "EnergyInSpill",
1978  "Energy deposited during the beam gate opening"
1979  ";energy deposited in spill [ GeV ]"
1980  ";events [ / 50 MeV ]",
1981  120, 0.0, 6.0 // 6 GeV should be enough for a MIP crossing 20 m of detector
1982  );
1983  plots.make<TH1F>(
1984  "EnergyInSpillActive",
1985  "Energy deposited during the beam gate opening in active volume"
1986  ";energy deposited in active volume in spill [ GeV ]"
1987  ";events [ / 50 MeV ]",
1988  120, 0.0, 6.0 // 6 GeV should be enough for a MIP crossing 20 m of detector
1989  );
1990  plots.make<TH1I>(
1991  "InteractionType",
1992  "Interaction type"
1993  ";Interaction Type"
1994  ";events",
1995  200, 999.5, 1199.5
1996  );
1997  plots.make<TH1F>(
1998  "LeptonEnergy",
1999  "Energy of outgoing lepton"
2000  ";deposited energy [ GeV ]"
2001  ";events [ / 50 MeV ]",
2002  120, 0.0, 6.0
2003  );
2004  plots.make<TH2F>(
2005  "InteractionVertexYZ",
2006  "Vertex of triggered interaction"
2007  ";Z [ / 20 cm ]"
2008  ";Y [ / 5 cm ]",
2009  120, -1200., +1200.,
2010  100, -250., +250.
2011  );
2012 
2013 } // icarus::trigger::TriggerEfficiencyPlots::initializeEventPlots()
std::pair< std::vector< double >, std::vector< std::string > > makeVariableBinningAndLabels(Coll const &centralPoints)
Returns a variable size binning for the points.
std::vector< unsigned int > fMinimumPrimitives
Minimum number of trigger primitives for a trigger to happen.
std::vector< PlotDef > plots
Definition: demo.h:54
std::string const fLogCategory
Message facility stream category for output.
temporary value
void icarus::trigger::TriggerEfficiencyPlots::initializePlots ( detinfo::DetectorClocksData const &  clockData,
PlotCategories_t const &  categories 
)
private

Initializes all the plot sets, one per threshold.

Definition at line 1708 of file TriggerEfficiencyPlots_module.cc.

1709 {
1710  using namespace std::string_literals;
1711 
1712  for (icarus::trigger::ADCCounts_t const threshold
1713  : util::get_elements<0U>(fADCthresholds))
1714  {
1715  // create a plot sandbox inside `fOutputDir` with a name/prefix `Thr###`
1716  auto const thr = threshold.value();
1718  "Thr"s + util::to_string(thr), "(thr: "s + util::to_string(thr) + ")"s };
1719 
1720  // create a subbox for each plot category
1721  for (PlotCategory const& category: categories) {
1722  PlotSandbox& plots = thrPlots.addSubSandbox(
1723  category.name(),
1724  category.description()
1725  );
1726 
1727  initializePlotSet(clockData, plots);
1728  }
1729  fThresholdPlots.push_back(std::move(thrPlots));
1730  } // for thresholds
1731 
1732  mf::LogTrace log(fLogCategory);
1733  log << "Created " << fThresholdPlots.size() << " plot boxes:\n";
1734  for (auto const& box: fThresholdPlots) {
1735  box.dump(log, " ");
1736  } // for
1737 
1738 } // icarus::trigger::TriggerEfficiencyPlots::initializePlots()
art::TFileDirectory fOutputDir
ROOT directory where all the plots are written.
std::vector< PlotSandbox > fThresholdPlots
All plots, one set per ADC threshold.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
A value measured in the specified unit.
Definition: quantities.h:566
void initializePlotSet(detinfo::DetectorClocksData const &clockData, PlotSandbox &plots) const
Initializes full set of plots for (ADC threshold + category) into plots.
std::vector< PlotDef > plots
Definition: demo.h:54
icarus::trigger::PlotSandbox PlotSandbox
Import type.
std::string const fLogCategory
Message facility stream category for output.
std::map< icarus::trigger::ADCCounts_t, art::InputTag > fADCthresholds
ADC thresholds to read, and the input tag connected to their data.
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
A helper to manage ROOT objects with consistent naming.
Definition: PlotSandbox.h:95
void icarus::trigger::TriggerEfficiencyPlots::initializePlotSet ( detinfo::DetectorClocksData const &  clockData,
PlotSandbox plots 
) const
private

Initializes full set of plots for (ADC threshold + category) into plots.

Definition at line 1743 of file TriggerEfficiencyPlots_module.cc.

1744 {
1745 
1746  // a variable binning for the required number of trigger primitives
1747  auto [ minimumPrimBinning, minimumPrimBinningLabels ]
1749  assert(minimumPrimBinning.size() == minimumPrimBinningLabels.size() + 1U);
1750 
1751  {
1752  mf::LogTrace log(fLogCategory);
1753  log << "TriggerEfficiencyPlots (plots '"
1754  << plots.name() << "') variable binning including the "
1755  << fMinimumPrimitives.size() << " points {";
1756  for (auto value: fMinimumPrimitives) log << " " << value;
1757  log << " } => " << minimumPrimBinningLabels.size() << " bins: ";
1758  for (auto const& [ value, label ]
1759  : util::zip<1U>(minimumPrimBinning, minimumPrimBinningLabels))
1760  {
1761  log << " " << value << " (\"" << label << "\") =>";
1762  } // for
1763  log << " " << minimumPrimBinning.back();
1764  } // debug output block
1765 
1766  //
1767  // Triggering efficiency vs. threshold.
1768  //
1769  detinfo::DetectorTimings const detTimings{clockData};
1770  detinfo::timescales::optical_time_ticks const triggerResolutionTicks
1771  { detTimings.toOpticalTicks(fTriggerTimeResolution) };
1772  auto const beam_gate_opt = std::make_pair(detTimings.toOpticalTick(detTimings.BeamGateTime()),
1773  detTimings.toOpticalTick(detTimings.BeamGateTime() + fBeamGateDuration));
1774  auto* TrigTime = plots.make<TH2F>(
1775  "TriggerTick",
1776  "Trigger time tick"
1777  ";minimum requested number of trigger primitives"
1778  ";optical time tick [ /" + util::to_string(triggerResolutionTicks) + " ]",
1779  minimumPrimBinning.size() - 1U, minimumPrimBinning.data(),
1780 // fMinimumPrimitives.back(), 0, fMinimumPrimitives.back() + 1
1781  (beam_gate_opt.second - beam_gate_opt.first) / triggerResolutionTicks,
1782  beam_gate_opt.first.value(), beam_gate_opt.second.value()
1783  );
1784 
1785  util::ROOT::applyAxisLabels(TrigTime->GetXaxis(), minimumPrimBinningLabels);
1786 
1787  auto* Eff = plots.make<TEfficiency>(
1788  "Eff",
1789  "Efficiency of triggering"
1790  ";minimum requested number of trigger primitives"
1791  ";trigger efficiency",
1792  minimumPrimBinning.size() - 1U, minimumPrimBinning.data()
1793 // fMinimumPrimitives.back(), 0, fMinimumPrimitives.back() + 1
1794  );
1795 
1796  // people are said to have earned hell for things like this;
1797  // but TEfficiency really does not expose the interface to assign labels to
1798  // its axes, which supposedly could be done had we chosen to create it by
1799  // histograms instead of directly as recommended.
1801  const_cast<TH1*>(Eff->GetTotalHistogram())->GetXaxis(),
1802  minimumPrimBinningLabels
1803  );
1804 
1805  //
1806  // plots independent of the trigger primitive requirements
1807  //
1808  plots.make<TH1F>(
1809  "NPrimitives",
1810  "Number of trigger primitives (\"channels firing at once\")"
1811  ";maximum trigger primitives at the same time"
1812  ";events",
1813  192, 0.0, 192.0 // large number, zoom in presentations!
1814  );
1815 
1816  //
1817  // Selection-related plots
1818  //
1820 
1821 
1822  //
1823  // Plots per trigger setting, split in triggering and not triggering events;
1824  // the plot set is the same as the "global" one.
1825  //
1826  using SS_t = std::pair<std::string, std::string>;
1827  std::array<SS_t, 2U> const classes {
1828  SS_t{ "triggering", "triggering events" },
1829  SS_t{ "nontriggering", "non-triggering events" }
1830  };
1831  for (auto minCount: fMinimumPrimitives) {
1832 
1833  std::string const minCountStr = std::to_string(minCount);
1834 
1835  // this defines a specific trigger, with its thresholds and settings
1836  PlotSandbox& reqBox = plots.addSubSandbox
1837  ("Req" + minCountStr, minCountStr + " channels required");
1838 
1839  initializeEfficiencyPerTriggerPlots(clockData, reqBox);
1840 
1841  for (auto const& [ name, desc ]: classes) {
1842 
1843  PlotSandbox& box = reqBox.addSubSandbox(name, desc);
1844 
1845  initializeEventPlots(box);
1846 
1847  } // for triggering requirement
1848  } // for triggering classes
1849 
1850  //
1851  // No trigger related plots
1852  //
1853  plots.make<TH1F>(
1854  "NeutrinoEnergy_NoTrig",
1855  "True Neutrino Energy of Non-Triggered Event"
1856  ";neutrino energy [GeV]"
1857  ";events",
1858  120,0.0,6.0 // GeV
1859  );
1860  plots.make<TH1F>(
1861  "EnergyInSpill_NoTrig",
1862  "Energy eposited during the beam gate opening of Non-Triggered Event"
1863  ";deposited energy [ GeV ]"
1864  ";events [ / 50 MeV ]",
1865  120, 0.0, 6.0 // 6 GeV should be enough for a MIP crossing 20 m of detector
1866  );
1867  plots.make<TH1I>(
1868  "InteractionType_NoTrig",
1869  "Interaction type of Non-Triggered Event"
1870  ";Interaction Type"
1871  ";events [ / 50 MeV ]",
1872  200, 999.5, 1199.5
1873  );
1874  plots.make<TH1F>(
1875  "LeptonEnergy_NoTrig",
1876  "Energy of outgoing lepton of Non-Triggered Event"
1877  ";lepton generated energy [ GeV ]"
1878  ";events [ / 50 MeV ]",
1879  120, 0.0, 6.0
1880  );
1881 
1882 } // icarus::trigger::TriggerEfficiencyPlots::initializePlotSet()
void initializeEventPlots(PlotSandbox &plots) const
Initializes a single, trigger-independent plot set into plots.
nanoseconds fTriggerTimeResolution
Trigger resolution in time.
std::pair< std::vector< double >, std::vector< std::string > > makeVariableBinningAndLabels(Coll const &centralPoints)
Returns a variable size binning for the points.
std::vector< unsigned int > fMinimumPrimitives
Minimum number of trigger primitives for a trigger to happen.
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).
Definition: ROOTutils.h:175
timescale_traits< OpticalTimeCategory >::tick_interval_t optical_time_ticks
void initializeEfficiencyPerTriggerPlots(detinfo::DetectorClocksData const &clockData, PlotSandbox &plots) const
Initializes set of plots per complete trigger definition into plots.
microseconds fBeamGateDuration
Duration of the gate during with global optical triggers are accepted.
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
std::vector< PlotDef > plots
Definition: demo.h:54
icarus::trigger::PlotSandbox PlotSandbox
Import type.
std::string const fLogCategory
Message facility stream category for output.
std::string to_string(WindowPattern const &pattern)
A class exposing an upgraded interface of detinfo::DetectorClocksData.
SandboxType & addSubSandbox(std::string const &name, std::string const &desc, Args &&...args)
Creates a new sandbox contained in this one.
Definition: PlotSandbox.h:723
then echo fcl name
temporary value
fDetProps &fDetProps fDetProps &fDetProps detTimings
TriggerEfficiencyPlots& icarus::trigger::TriggerEfficiencyPlots::operator= ( TriggerEfficiencyPlots const &  )
delete
TriggerEfficiencyPlots& icarus::trigger::TriggerEfficiencyPlots::operator= ( TriggerEfficiencyPlots &&  )
delete
void icarus::trigger::TriggerEfficiencyPlots::plotResponses ( std::size_t  iThr,
icarus::trigger::ADCCounts_t const  threshold,
detinfo::DetectorTimings const &  detTimings,
PlotSandboxRefs_t const &  plots,
EventInfo_t const &  info,
std::vector< TriggerGateData_t > const &  primitiveCounts 
) const
private

Adds all the responses (one per threshold) to the plots.

Definition at line 2237 of file TriggerEfficiencyPlots_module.cc.

2244  {
2245 
2246  /*
2247  * This function plots according to the configured minimum number of trigger
2248  * primitives: for each requirement of minimum number of primitives, the
2249  * earliest time where that requirement is met is found, and that is
2250  * considered as the trigger time.
2251  *
2252  * The following quantities are drawn per ADC threshold and per plot category:
2253  *
2254  * * per minimum number of primitives:
2255  * * trigger efficiency (i.e. whether there was _any time_ a number of
2256  * primitives fulfilling the requirement)
2257  * * trigger time in ticks (distribution as 2D histogram)
2258  * * maximum number of trigger primitives present at any time
2259  * * deposited energy during beam spill
2260  *
2261  */
2262  using namespace std::string_literals;
2263 
2264  using ClockTick_t = TriggerGateData_t::ClockTick_t;
2265  using OpeningCount_t = TriggerGateData_t::OpeningCount_t;
2266 
2267  using PrimitiveCount_t = std::pair<ClockTick_t, OpeningCount_t>;
2268 
2269  // largest number of trigger primitives at any time
2270  assert(!primitiveCounts.empty());
2271  auto const primitiveCount = computeMaxGate(primitiveCounts);
2272 
2273  auto const maxPrimitiveTime { primitiveCount.findMaxOpen() };
2274  PrimitiveCount_t const maxPrimitives
2275  { maxPrimitiveTime, primitiveCount.openingCount(maxPrimitiveTime) };
2276 
2277  mf::LogTrace(fLogCategory)
2278  << "Max primitive count in " << threshold << ": "
2279  << maxPrimitives.second << " at tick " << maxPrimitives.first << " ("
2280  << detTimings.toElectronicsTime
2281  (detinfo::DetectorTimings::optical_tick{ maxPrimitives.first })
2282  << ")"
2283  ;
2284 
2285  /*
2286  * Fill all the histograms for all the minimum primitive requirements
2287  * (filling the information whether or not the trigger fired),
2288  * for all the qualifying categories.
2289  * Note that in this type of plots each event appears in all bins
2290  * (may be with "fired" or "not fired" on each bin)
2291  */
2292  PrimitiveCount_t lastMinCount { TriggerGateData_t::MinTick, 0 };
2293  bool fired = true; // the final trigger response (changes with requirement)
2294 
2295  class HistGetter { // helper, since this seems "popular"
2296  PlotSandbox const& plots;
2297 
2298  public:
2299  HistGetter(PlotSandbox const& plots): plots(plots) {}
2300 
2301  PlotSandbox const& box() const { return plots; }
2302 
2303  TH1& Hist(std::string const& name) const { return plots.demand<TH1>(name); }
2304  TH2& Hist2D(std::string const& name) const { return plots.demand<TH2>(name); }
2305  TEfficiency& Eff(std::string const& name) const
2306  { return plots.demand<TEfficiency>(name); }
2307 
2308  }; // class HistGetter
2309 
2310 
2311  for (auto [ iReq, minCount ]: util::enumerate(fMinimumPrimitives)) {
2312 
2313  if (fired && (lastMinCount.second < minCount)) {
2314  // if we haven't passed this minimum yet
2315  ClockTick_t const time = primitiveCount.findOpen(minCount);
2316  if (time == TriggerGateData_t::MaxTick) {
2317  mf::LogTrace(fLogCategory)
2318  << "Never got at " << minCount << " primitives or above.";
2319  fired = false;
2320  }
2321  else {
2322  lastMinCount = { time, primitiveCount.openingCount(time) };
2323  mf::LogTrace(fLogCategory)
2324  << "Reached " << minCount << " primitives or above ("
2325  << lastMinCount.second << ") at " << lastMinCount.first << ".";
2326  }
2327  } // if
2328 
2329  // at this point we know we have minCount or more trigger primitives,
2330  // and the time of this one is in lastMinCount.first (just in case)
2331 
2332  if (fResponseTree) fResponseTree->assignResponse(iThr, iReq, fired);
2333 
2334  std::string const minCountStr { "Req" + std::to_string(minCount) };
2335 
2336  // go through all the plot categories this event qualifies for
2337  for (icarus::trigger::PlotSandbox const& plotSet: plotSets) {
2338 
2339  HistGetter const get { plotSet };
2340 
2341  // simple efficiency
2342  get.Eff("Eff"s).Fill(fired, minCount);
2343 
2344  // trigger time (if any)
2345  if (fired) {
2346  get.Hist2D("TriggerTick"s).Fill(minCount, lastMinCount.first);
2347  if (minCount == 1) {
2348  for (auto point : eventInfo.fVertices) {
2349  get.Hist2D("InteractionVertexYZ"s).Fill(point.Z(), point.Y());
2350  }
2351  }
2352  }
2353 
2354  //
2355  // plotting specific to this trigger definition
2356  //
2357 
2358  HistGetter const getTrigEff { plotSet.demandSandbox(minCountStr) };
2359 
2360  // efficiency plots
2361  getTrigEff.Eff("EffVsEnergyInSpill").Fill
2362  (fired, double(eventInfo.DepositedEnergyInSpill()));
2363  getTrigEff.Eff("EffVsEnergyInSpillActive").Fill
2364  (fired, double(eventInfo.DepositedEnergyInSpillInActiveVolume()));
2365  getTrigEff.Eff("EffVsNeutrinoEnergy").Fill
2366  (fired, double(eventInfo.NeutrinoEnergy()));
2367  getTrigEff.Eff("EffVsLeptonEnergy").Fill
2368  (fired, double(eventInfo.LeptonEnergy()));
2369  if (fired) {
2370  getTrigEff.Hist("TriggerTick"s).Fill(lastMinCount.first);
2371  }
2372 
2373 
2374  //
2375  // plotting split for triggering/not triggering events
2376  //
2377 
2378  HistGetter const getTrig
2379  { getTrigEff.box().demandSandbox(fired? "triggering": "nontriggering") };
2380 
2381  getTrig.Hist("EnergyInSpill"s).Fill(double(eventInfo.DepositedEnergyInSpill()));
2382  getTrig.Hist("EnergyInSpillActive"s).Fill(double(eventInfo.DepositedEnergyInSpillInActiveVolume()));
2383  if (eventInfo.isNeutrino()) {
2384  getTrig.Hist("NeutrinoEnergy"s).Fill(double(eventInfo.NeutrinoEnergy()));
2385  getTrig.Hist("InteractionType"s).Fill(eventInfo.InteractionType());
2386  getTrig.Hist("LeptonEnergy"s).Fill(double(eventInfo.LeptonEnergy()));
2387  } // if neutrino event
2388  TH2& vertexHist = getTrig.Hist2D("InteractionVertexYZ"s);
2389  for (auto const& point: eventInfo.fVertices)
2390  vertexHist.Fill(point.Z(), point.Y());
2391 
2392 
2393  //
2394  // non triggered events
2395  //
2396  if (!fired && minCount == 1 ) { // I only am interested in events that aren't triggered when there is a low multiplicity requirement
2397  get.Hist("EnergyInSpill_NoTrig"s).Fill(double(eventInfo.DepositedEnergyInSpill()));
2398  get.Hist("NeutrinoEnergy_NoTrig"s).Fill(double(eventInfo.NeutrinoEnergy()));
2399  get.Hist("InteractionType_NoTrig"s).Fill(eventInfo.InteractionType());
2400  get.Hist("LeptonEnergy_NoTrig"s).Fill(double(eventInfo.LeptonEnergy()));
2401  //getHist("NucleonEnergy_NoTrig"s)->Fill(double(eventInfo.NucleonEnergy()));
2402  }
2403 
2404  } // for all qualifying plot categories
2405 
2406  } // for all thresholds
2407 
2408  /*
2409  * Now fill the plots independent of the trigger response:
2410  * the same value is plotted in all plot sets.
2411  *
2412  */
2413  for (PlotSandbox const& plotSet: plotSets) {
2414 
2415  HistGetter const get(plotSet);
2416 
2417  // number of primitives
2418  get.Hist("NPrimitives"s).Fill(maxPrimitives.second);
2419 
2420  // selection-related plots:
2421  get.Hist("EnergyInSpill"s).Fill(double(eventInfo.DepositedEnergyInSpill()));
2422  get.Hist("EnergyInSpillActive"s).Fill(double(eventInfo.DepositedEnergyInSpillInActiveVolume()));
2423 
2424  if (eventInfo.isNeutrino()) {
2425  get.Hist("NeutrinoEnergy"s).Fill(double(eventInfo.NeutrinoEnergy()));
2426  get.Hist("InteractionType"s).Fill(eventInfo.InteractionType());
2427  get.Hist("LeptonEnergy"s).Fill(double(eventInfo.LeptonEnergy()));
2428  } // if neutrino event
2429  TH2& vertexHist = get.Hist2D("InteractionVertexYZ"s);
2430  for (auto const& point: eventInfo.fVertices)
2431  vertexHist.Fill(point.Z(), point.Y());
2432 
2433  } // for
2434 
2435 } // icarus::trigger::TriggerEfficiencyPlots::plotResponses()
static constexpr ClockTick_t MaxTick
An unbearably large tick number.
std::vector< unsigned int > fMinimumPrimitives
Minimum number of trigger primitives for a trigger to happen.
static constexpr ClockTick_t MinTick
An unbearably small tick number.
static auto computeMaxGate(TrigGateColl const &gates)
Returns a gate that is Max() of all the specified gates.
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:69
std::unique_ptr< ResponseTree > fResponseTree
Handler of ROOT tree output.
std::vector< PlotDef > plots
Definition: demo.h:54
icarus::trigger::PlotSandbox PlotSandbox
Import type.
std::string const fLogCategory
Message facility stream category for output.
unsigned int OpeningCount_t
Type of count of number of open channels.
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
Definition: file_to_url.sh:60
then echo fcl name
fDetProps &fDetProps fDetProps &fDetProps detTimings
Tick ClockTick_t
Type of a point in time, measured in ticks.
detinfo::timescales::optical_tick optical_tick
A helper to manage ROOT objects with consistent naming.
Definition: PlotSandbox.h:95
geo::TPCGeo const * icarus::trigger::TriggerEfficiencyPlots::pointInActiveTPC ( geo::Point_t const &  point) const
private

Returns in which TPC point is within the active volume of; nullptr if none.

Definition at line 2172 of file TriggerEfficiencyPlots_module.cc.

2173 {
2174  geo::TPCGeo const* tpc = pointInTPC(point);
2175  return
2176  (tpc && tpc->ActiveBoundingBox().ContainsPosition(point))? tpc: nullptr;
2177 } // icarus::trigger::TriggerEfficiencyPlots::pointInActiveTPC()
Geometry information for a single TPC.
Definition: TPCGeo.h:38
geo::BoxBoundedGeo const & ActiveBoundingBox() const
Returns the box of the active volume of this TPC.
Definition: TPCGeo.h:320
geo::TPCGeo const * pointInTPC(geo::Point_t const &point) const
Returns the TPC point is within, nullptr if none.
bool ContainsPosition(geo::Point_t const &point, double wiggle=1.0) const
Returns whether this volume contains the specified point.
geo::TPCGeo const * icarus::trigger::TriggerEfficiencyPlots::pointInTPC ( geo::Point_t const &  point) const
private

Returns the TPC point is within, nullptr if none.

Definition at line 2164 of file TriggerEfficiencyPlots_module.cc.

2165 {
2166  return fGeom.PositionToTPCptr(point);
2167 } // icarus::trigger::TriggerEfficiencyPlots::pointInTPC()
geo::TPCGeo const * PositionToTPCptr(geo::Point_t const &point) const
Returns the TPC at specified location.
auto icarus::trigger::TriggerEfficiencyPlots::ReadTriggerGates ( art::Event const &  event,
art::InputTag const &  dataTag 
) const
private

Reads a set of input gates from the event.

Definition at line 2440 of file TriggerEfficiencyPlots_module.cc.

2442 {
2443 
2444  std::vector<TrackedTriggerGate_t> allGates
2445  = icarus::trigger::ReadTriggerGates(event, dataTag);
2446 
2447  std::vector<geo::CryostatID> fChannelCryostat;
2448 
2449  fChannelCryostat.reserve(fGeom.NOpChannels());
2450  for (auto const opChannel: util::counter(fGeom.NOpChannels())) {
2451  if (!fGeom.IsValidOpChannel(opChannel)) continue;
2452  fChannelCryostat[opChannel] = fGeom.OpDetGeoFromOpChannel(opChannel).ID();
2453  } // for all channels
2454 
2455  std::vector<std::vector<TrackedTriggerGate_t>> gatesPerCryostat
2456  { fGeom.Ncryostats() };
2457  for (auto& gate: allGates) {
2458  assert(gate.gate().hasChannels());
2459  gatesPerCryostat[fChannelCryostat[gate.channels().front()].Cryostat]
2460  .push_back(std::move(gate));
2461  }
2462  return gatesPerCryostat;
2463 
2464 } // icarus::trigger::TriggerEfficiencyPlots::ReadTriggerGates()
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
unsigned int NOpChannels() const
Number of electronics channels for all the optical detectors.
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:285
geo::OpDetID const & ID() const
Returns the geometry ID of this optical detector.
Definition: OpDetGeo.h:72
std::vector< icarus::trigger::TrackedOpticalTriggerGate< OpDetInfo > > ReadTriggerGates(Event const &event, art::InputTag const &dataTag)
Assembles and returns trigger gates from serialized data.
OpDetGeo const & OpDetGeoFromOpChannel(unsigned int OpChannel) const
Returns the geo::OpDetGeo object for the given channel number.
bool IsValidOpChannel(int opChannel) const
Is this a valid OpChannel number?
std::vector< std::string > icarus::trigger::TriggerEfficiencyPlots::selectPlotCategories ( EventInfo_t const &  info,
PlotCategories_t const &  categories 
) const
private

Returns the names of the plot categories event qualifies for.

Definition at line 2033 of file TriggerEfficiencyPlots_module.cc.

2034 {
2035  std::vector<std::string> selected;
2036 
2037  for (auto const& category: categories)
2038  if (category(info)) selected.push_back(category);
2039 
2040  return selected;
2041 
2042 } // icarus::trigger::TriggerEfficiencyPlots::selectPlotCategories()
bool icarus::trigger::TriggerEfficiencyPlots::shouldPlotEvent ( EventInfo_t const &  eventInfo) const
private

Returns whether an event with the specified information should be included in the plots at all (it's a filter).

Definition at line 2018 of file TriggerEfficiencyPlots_module.cc.

2019 {
2021  && eventInfo.hasVertex() && !eventInfo.isInActiveVolume())
2022  {
2023  return false;
2024  }
2025 
2026  return true;
2027 } // icarus::trigger::TriggerEfficiencyPlots::shouldPlotEvent()
bool fPlotOnlyActiveVolume
Plot only events in active volume.
static std::string icarus::trigger::TriggerEfficiencyPlots::thrAndCatName ( std::string const &  boxName,
std::string const &  category 
)
inlinestaticprivate

Definition at line 1488 of file TriggerEfficiencyPlots_module.cc.

1489  { return boxName + "_" + category; }
static std::string icarus::trigger::TriggerEfficiencyPlots::thrAndCatName ( PlotSandbox const &  box,
std::string const &  category 
)
inlinestaticprivate

Definition at line 1491 of file TriggerEfficiencyPlots_module.cc.

1492  { return thrAndCatName(box.name(), category); }
static std::string thrAndCatName(std::string const &boxName, std::string const &category)

Member Data Documentation

std::map<icarus::trigger::ADCCounts_t, art::InputTag> icarus::trigger::TriggerEfficiencyPlots::fADCthresholds
private

ADC thresholds to read, and the input tag connected to their data.

Definition at line 1351 of file TriggerEfficiencyPlots_module.cc.

microseconds icarus::trigger::TriggerEfficiencyPlots::fBeamGateDuration
private

Duration of the gate during with global optical triggers are accepted.

Definition at line 1354 of file TriggerEfficiencyPlots_module.cc.

std::pair<detinfo::timescales::optical_tick, detinfo::timescales::optical_tick> const icarus::trigger::TriggerEfficiencyPlots::fBeamGateOpt
private

Beam gate start and stop tick in optical detector scale.

Definition at line 1386 of file TriggerEfficiencyPlots_module.cc.

std::pair<detinfo::timescales::simulation_time, detinfo::timescales::simulation_time> const icarus::trigger::TriggerEfficiencyPlots::fBeamGateSim
private

Beam gate start and stop time in simulation scale.

Definition at line 1391 of file TriggerEfficiencyPlots_module.cc.

art::InputTag icarus::trigger::TriggerEfficiencyPlots::fDetectorParticleTag
private

Input simulated particles.

Definition at line 1346 of file TriggerEfficiencyPlots_module.cc.

std::vector<art::InputTag> icarus::trigger::TriggerEfficiencyPlots::fEnergyDepositTags
private

Energy deposition data product tags.

Definition at line 1348 of file TriggerEfficiencyPlots_module.cc.

std::unique_ptr<EventInfoTree> icarus::trigger::TriggerEfficiencyPlots::fEventTree
private

Handler of ROOT tree output.

Definition at line 1398 of file TriggerEfficiencyPlots_module.cc.

std::vector<art::InputTag> icarus::trigger::TriggerEfficiencyPlots::fGeneratorTags
private

Generator data product tags.

Definition at line 1345 of file TriggerEfficiencyPlots_module.cc.

geo::GeometryCore const& icarus::trigger::TriggerEfficiencyPlots::fGeom
private

Definition at line 1373 of file TriggerEfficiencyPlots_module.cc.

std::unique_ptr<EventIDTree> icarus::trigger::TriggerEfficiencyPlots::fIDTree
private

Handler of ROOT tree output.

Definition at line 1396 of file TriggerEfficiencyPlots_module.cc.

std::string const icarus::trigger::TriggerEfficiencyPlots::fLogCategory
private

Message facility stream category for output.

Definition at line 1364 of file TriggerEfficiencyPlots_module.cc.

std::string icarus::trigger::TriggerEfficiencyPlots::fLogEventDetails
private

Steam where to print event info.

Definition at line 1366 of file TriggerEfficiencyPlots_module.cc.

std::vector<unsigned int> icarus::trigger::TriggerEfficiencyPlots::fMinimumPrimitives
private

Minimum number of trigger primitives for a trigger to happen.

Definition at line 1357 of file TriggerEfficiencyPlots_module.cc.

art::TFileDirectory icarus::trigger::TriggerEfficiencyPlots::fOutputDir
private

ROOT directory where all the plots are written.

Definition at line 1376 of file TriggerEfficiencyPlots_module.cc.

bool icarus::trigger::TriggerEfficiencyPlots::fPlotOnlyActiveVolume
private

Plot only events in active volume.

Definition at line 1361 of file TriggerEfficiencyPlots_module.cc.

std::unique_ptr<PlotInfoTree> icarus::trigger::TriggerEfficiencyPlots::fPlotTree
private

Handler of ROOT tree output.

Definition at line 1397 of file TriggerEfficiencyPlots_module.cc.

std::unique_ptr<ResponseTree> icarus::trigger::TriggerEfficiencyPlots::fResponseTree
private

Handler of ROOT tree output.

Definition at line 1399 of file TriggerEfficiencyPlots_module.cc.

std::vector<PlotSandbox> icarus::trigger::TriggerEfficiencyPlots::fThresholdPlots
private

All plots, one set per ADC threshold.

Definition at line 1394 of file TriggerEfficiencyPlots_module.cc.

nanoseconds icarus::trigger::TriggerEfficiencyPlots::fTriggerTimeResolution
private

Trigger resolution in time.

Definition at line 1359 of file TriggerEfficiencyPlots_module.cc.

std::atomic<unsigned int> icarus::trigger::TriggerEfficiencyPlots::nEvents { 0U }
private

Count of seen events.

Definition at line 1401 of file TriggerEfficiencyPlots_module.cc.

std::atomic<unsigned int> icarus::trigger::TriggerEfficiencyPlots::nPlottedEvents { 0U }
private

Count of plotted events.

Definition at line 1402 of file TriggerEfficiencyPlots_module.cc.


The documentation for this class was generated from the following file: