Belle II Software development
TriggerSkimModule.cc
1
2/**************************************************************************
3 * basf2 (Belle II Analysis Software Framework) *
4 * Author: The Belle II Collaboration *
5 * *
6 * See git log for contributors and copyright holders. *
7 * This file is licensed under LGPL-3.0, see LICENSE.md. *
8 **************************************************************************/
9
10#include <calibration/modules/TriggerSkim/TriggerSkimModule.h>
11#include <hlt/softwaretrigger/core/utilities.h>
12#include <framework/core/ModuleParam.templateDetails.h>
13#include <framework/utilities/Utils.h>
14
15#include <stdexcept>
16
17using namespace Belle2;
18
19REG_MODULE(TriggerSkim);
20
22{
23 // Set module properties
24 setDescription(R"DOC(Trigger Skim Module
25
26Module will return an overall result (True/False) based on whether or not ANY or
27ALL (depending on ``logicMode``) of the specified triggers returned the given
28value (``expectedResult``) from the SoftwareTriggerResult.
29
30Optionally it can apply prescales on each trigger line. In that case ``logicMode='and'``
31might not be very meaningful as the return value will only be true if all trigger
32lines were accepted after their own prescale.
33)DOC");
35
36 // Parameter definitions
37 addParam("triggerLines", m_triggerLines,
38 "Trigger lines to skim on. This can either be just a list of names or "
39 "each item can also optionally be a tuple with name and prescale factor. "
40 "So either ``['hadron', 'cosmic']`` or ``[('hadron', 1), ('cosmic', 20)]`` "
41 "or a mix of both");
42 addParam("expectedResult", m_expectedResult,
43 "The SoftwareTriggerResult value that each trigger line in the ``triggerLines`` "
44 "parameter will be tested for.", int(1));
45 addParam("logicMode", m_logicMode,
46 "Each trigger line in ``triggerLines`` will be tested against the ``expectedResult`` parameter. "
47 "The logic mode controls whether we test using 'and' or 'or' logic to get a return value. "
48 "'and' means that all trigger lines must have ``results == expectedResult``, 'or' means that only "
49 "one of the trigger lines must match the expectedResult value.", m_logicMode);
50 addParam("useRandomNumbersForPreScale", m_useRandomNumbersForPreScale, "Flag to use random numbers (True) "
51 "or a counter (False) for applying the prescale. In the latter case, the module will retain exactly "
52 "one event every N processed, where N (the counter value) is set for each line via the "
53 "``triggerLines`` option. By default, random numbers are used.", m_useRandomNumbersForPreScale);
54 addParam("resultOnMissing", m_resultOnMissing, "Value to return if hlt trigger result is not available or incomplete. "
55 "If this is set to None a FATAL error will be raised if the results are missing. Otherwise the value "
56 "given will be set as return value of the module", m_resultOnMissing);
57 addParam("skipFirstEvent", m_firstEvent, "Boolean to skip the first event or not. "
58 "If the module is used inside the hbasf2, like HLT storage, the first event need to be skipped.", m_firstEvent);
59}
60
62{
64 m_trigResults.isRequired();
65 } else {
66 m_trigResults.isOptional();
67 }
68 if (m_logicMode != "and" and m_logicMode != "or") {
69 B2FATAL("You have entered an invalid parameter for logicMode. "
70 "Valid strings are any of ['or', 'and']");
71 }
72 if(m_expectedResult < -1 or m_expectedResult > 1) {
73 B2FATAL("Expected trigger result needs to be -1, 0 or 1");
74 }
75
76 // check if and how many prescales we have
77 int havePrescales{0};
78 for(const auto& triggerLine: m_triggerLines){
79 boost::apply_visitor(Utils::VisitOverload{
80 [&havePrescales](const std::tuple<std::string, unsigned int>& line) {
81 const auto& [name, prescale] = line;
82 if(prescale < 1) {
83 B2ERROR("Prescale is not positive, needs to be at least 1"
84 << LogVar("trigger line", name) << LogVar("prescale", prescale));
85 }
86 ++havePrescales;
87 B2DEBUG(20, "Prescale of " << prescale << " to be applied to " << name);
88 },
89 [](const std::string& name) {
90 // nothing to do without prescales
91 B2DEBUG(20, "No prescales to be applied to " << name);
92 },
93 }, triggerLine);
94 }
95 // and reserve counters if we need them
96 if(havePrescales > 0 and not m_useRandomNumbersForPreScale) {
97 m_prescaleCounters.clear();
98 m_prescaleCounters.assign(havePrescales, 0);
99 }
100}
101
102bool TriggerSkimModule::checkTrigger(const std::string& name, unsigned int prescale, uint32_t* counter) const {
103 try {
104 bool accepted = m_trigResults->getResult(name) == static_cast<SoftwareTriggerCutResult>(m_expectedResult);
105 if(accepted and prescale != 1) {
106 accepted &= SoftwareTrigger::makePreScale(prescale, counter);
107 }
108 return accepted;
109 } catch(std::out_of_range &e) {
110 // typo? change in lines? In any case we nope out of here but let's try to give a helpful message
111 std::string available_lines = "";
112 // cppcheck-suppress unassignedVariable
113 for(auto&& [line, result]: m_trigResults->getResults()) {
114 available_lines += line + "(" + std::to_string((int)result) + ") ";
115 }
117 B2WARNING("Software trigger line not found" << LogVar("requested", name)
118 << LogVar("available", available_lines)
119 << LogVar("errorFlag", m_eventMetaDataPtr->getErrorFlag())
120 << LogVar("experiment", m_eventMetaDataPtr->getExperiment())
121 << LogVar("run", m_eventMetaDataPtr->getRun())
122 << LogVar("event", m_eventMetaDataPtr->getEvent()));
123 return *m_resultOnMissing;
124 }
125 else {
126 B2FATAL("Software trigger line not found (if this is expected, please use the `resultOnMissing` parameter)"
127 << LogVar("requested", name)
128 << LogVar("available", available_lines)
129 << LogVar("errorFlag", m_eventMetaDataPtr->getErrorFlag())
130 << LogVar("experiment", m_eventMetaDataPtr->getExperiment())
131 << LogVar("run", m_eventMetaDataPtr->getRun())
132 << LogVar("event", m_eventMetaDataPtr->getEvent()));
133 return false;
134 }
135 }
136}
137
139{
140 if(m_firstEvent) {
141 m_firstEvent = false;
142 setReturnValue(true);
143 return;
144 }
145 if(!m_trigResults) {
148 return;
149 }
150 B2FATAL("No HLT Trigger result available (if this is expected to be possible "
151 "please use the `resultOnMissing` parameter");
152 }
153 // count accepted triggers
154 size_t numAccepted(0);
155 // Now check all lines, index is the prescale counter if needed
156 size_t counterIndex{0};
157 for(const auto& triggerLine: m_triggerLines) {
158 const bool accept = boost::apply_visitor(Utils::VisitOverload{
159 // check in prescale case
160 [this, &counterIndex](const std::tuple<std::string, unsigned int>& line) {
161 const auto& [name, prescale] = line;
162 uint32_t* prescaleCounter = m_useRandomNumbersForPreScale ? nullptr : &m_prescaleCounters[counterIndex++];
163 return checkTrigger(name, prescale, prescaleCounter);
164 },
165 // check without prescale
166 [this](const std::string& name) {
167 return checkTrigger(name);
168 },
169 }, triggerLine);
170 if(accept)
171 ++numAccepted;
172 }
173
174 // Apply our logic on the test results
175 if (m_logicMode == "and") {
176 setReturnValue(numAccepted == m_triggerLines.size());
177 }
178 if (m_logicMode == "or") {
179 setReturnValue(numAccepted > 0);
180 }
181}
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
void setReturnValue(int value)
Sets the return value for this module as integer.
Definition: Module.cc:220
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
bool m_firstEvent
Check event is the first event for hbasf2 usage, especiaaly for HLT storage.
std::string m_logicMode
do we want each or any trigger line?
virtual void initialize() override
Initialize.
std::optional< int > m_resultOnMissing
value to return if there's no SoftwareTriggerResult
virtual void event() override
Event function.
int m_expectedResult
Result we want for each or any trigger line.
std::vector< boost::variant< std::string, std::tuple< std::string, unsigned int > > > m_triggerLines
List of triggerlines we're interested in.
std::vector< uint32_t > m_prescaleCounters
if we don't use random prescale we need counters
bool m_useRandomNumbersForPreScale
and do we want random prescale or counters ?
StoreObjPtr< SoftwareTriggerResult > m_trigResults
Required input for trigger results.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
EventMetaData is used to report warning/error messages.
bool checkTrigger(const std::string &name, unsigned int prescale=1, uint32_t *counter=nullptr) const
Check a single trigger line for the expected result.
TriggerSkimModule()
Constructor: Sets the description, the properties and the parameters of the module.
Class to store variables with their name which were sent to the logging service.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:649
SoftwareTriggerCutResult
Enumeration with all possible results of the SoftwareTriggerCut.
Abstract base class for different kinds of events.
Helper struct for the C++17 std::visit overload pattern to allow simple use of variants.
Definition: Utils.h:26