Belle II Software prerelease-11-00-00a
SoftwareTriggerModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <hlt/softwaretrigger/modules/basics/SoftwareTriggerModule.h>
10#include <hlt/softwaretrigger/core/utilities.h>
11#include <hlt/softwaretrigger/calculations/PrefilterCalculator.h>
12#include <hlt/softwaretrigger/calculations/FilterCalculator.h>
13#include <hlt/softwaretrigger/calculations/SkimSampleCalculator.h>
14#include <hlt/softwaretrigger/core/FinalTriggerDecisionCalculator.h>
15#include <TFile.h>
16
17using namespace Belle2;
18using namespace SoftwareTrigger;
19
20REG_MODULE(SoftwareTrigger);
21
22
25{
26 setDescription("Module to perform cuts on various variables in the event. The cuts can be defined\n"
27 "by elements loaded from the database. Each cut is executed and its result stored.\n"
28 "The return value of this module is a bool, which is either true (accept the event) or false (reject it).\n"
29 "It is defined from the results of the cuts in the given trigger menu, which are all evaluated\n"
30 "and the trigger mode (accept mode or not).\n"
31 "if not in accept mode (= reject mode):\n"
32 "* 1: if one of the accept cuts has a true result and none of the reject cuts is false ( = accepted)\n"
33 "* 0: if neither one of the accept cuts is true nor one of the reject cuts false ( = don't know) or\n"
34 "* if one of the reject cuts is false ( = rejected)\n"
35 "In short: event accepted <=> (#true accept cuts > 0) && (#false reject cuts == 0)\n"
36 "Please note that the reject cuts override the accept cuts decision in this case!\n"
37 "if in accept mode\n"
38 "* 1: if one of the accept cuts has a true result. ( = accepted) or\n"
39 "* if neither one of the accept cuts is true nor one of the reject cuts false ( = don't know)\n"
40 "* 0: if one of the reject cuts is false and none of the accept cuts is true ( = rejected)\n"
41 "Please note that the accept cuts override the reject cuts decision in this case!\n"
42 "In short: event accepted <=> (#true accept cuts > 0) || (#false reject cuts == 0)");
43
45
46 addParam("baseIdentifier", m_param_baseIdentifier, "Base identifier for all cuts downloaded from database. "
47 "The full db name of the cuts will be <base_identifier>/<cut_identifier>. You can only choose one identifier "
48 "to make clear that all chosen cuts belong together (and should be calculated together).",
50
51 addParam("resultStoreArrayName", m_param_resultStoreArrayName, "Store Object Pointer name for storing the "
52 "trigger decision.", m_param_resultStoreArrayName);
53
54 addParam("storeDebugOutputToROOTFile", m_param_storeDebugOutputToROOTFile, "Flag to save the results of the calculations leading "
55 "to the trigger decisions into a ROOT file. The file path and name of this file can be handled by the "
56 "debugOutputFileName parameter. Not supported during parallel processing.", m_param_storeDebugOutputToROOTFile);
57
58 addParam("preScaleStoreDebugOutputToDataStore", m_param_preScaleStoreDebugOutputToDataStore,
59 "Prescale with which to save the results of the calculations leading "
60 "to the trigger decisions into the DataStore. Leave to zero, to not store them at all.",
62
63 addParam("debugOutputFileName", m_param_debugOutputFileName, "File path and name of the ROOT "
64 "file, in which the results of the calculation are stored, if storeDebugOutput is "
65 "turned on. Please note that already present files will be overridden. "
66 "ATTENTION: This file debugging mode does not work in parallel processing.", m_param_debugOutputFileName);
67 addParam("useRandomNumbersForPreScale", m_param_useRandomNumbersForPreScale, "Flag to use random numbers (True) "
68 "or a counter (False) for applying the prescale.", m_param_useRandomNumbersForPreScale);
69}
70
72{
73 // Check if the SoftwareTriggerResult is already present in the datastore:
74 // if so, warn the user that the SoftwareTriggerResult will be recalculated and overwritten
75 // Let's not warn the user if we are skimming, since the module is called twice and we might throw a false warning
77 B2WARNING("The object "
78 << (m_param_resultStoreArrayName == "" ? SoftwareTriggerResult::Class_Name() : m_param_resultStoreArrayName)
79 << " is already present in the DataStore: the module SoftwareTrigger will overwrite the filter answer from HLT.");
80 }
81
84
87}
88
90{
91 m_dbHandler->checkForChangedDBEntries();
92 // Initialize always the internal counters at the beginning of each run.
95 }
96}
97
99{
100 if (m_debugTTree) {
101 m_debugOutputFile->cd();
102 m_debugOutputFile->Write();
103 m_debugTTree.reset();
104 m_debugOutputFile.reset();
105 }
106}
107
110{
111 if (not m_resultStoreObjectPointer.isValid()) {
112 m_resultStoreObjectPointer.construct();
113 }
114
116 m_debugOutputStoreObject.construct();
117 }
118
119 B2DEBUG(20, "Doing the calculation...");
120 const SoftwareTriggerObject& prefilledObject = m_calculation->fillInCalculations();
121 B2DEBUG(20, "Successfully finished the calculation.");
122
123 makeCut(prefilledObject);
125}
126
128{
129 if (m_param_baseIdentifier == "prefilter") {
131 } else if (m_param_baseIdentifier == "filter") {
132 m_calculation.reset(new FilterCalculator());
133 } else if (m_param_baseIdentifier == "skim") {
135 } else {
136 B2FATAL("You gave an invalid base identifier " << m_param_baseIdentifier << ".");
137 }
138
139 m_calculation->requireStoreArrays();
140}
141
143{
145 m_debugOutputFile.reset(TFile::Open(m_param_debugOutputFileName.c_str(), "RECREATE"));
146 if (not m_debugOutputFile) {
147 B2FATAL("Could not open debug output file. Aborting.");
148 }
149 m_debugTTree.reset(new TTree("software_trigger_results", "software_trigger_results"));
150 if (not m_debugTTree) {
151 B2FATAL("Could not create debug output tree. Aborting.");
152 }
153 }
154
157 }
158}
159
161{
162 // Clear the vector of counters...
163 m_counters.clear();
164 // ... and then initialize it with "numberOfCuts" 0s.
165 size_t numberOfCuts = (m_dbHandler->getCutsWithNames()).size();
166 m_counters.assign(numberOfCuts, 0);
167}
168
169void SoftwareTriggerModule::makeCut(const SoftwareTriggerObject& prefilledObject)
170{
171 // Define the pointer to the counter and the index of each counter in m_counters.
172 uint32_t* counter{nullptr};
173 size_t counterIndex{0};
174 // Check all cuts with the prefilled object and write them back into the data store.
175 for (const auto& cutWithName : m_dbHandler->getCutsWithNames()) {
176 const std::string& cutIdentifier = cutWithName.first;
177 const auto& cut = cutWithName.second;
178 B2DEBUG(20, "Next processing cut " << cutIdentifier << " (" << cut->decompile() << ")");
180 counter = &m_counters.at(counterIndex++);
181 }
182 const auto& [prescaledCutResult, nonPrescaledCutResult] = cut->check(prefilledObject, counter);
183 m_resultStoreObjectPointer->addResult(cutIdentifier, prescaledCutResult, nonPrescaledCutResult);
184 }
185
186 // Also add the module result ( = the result of all cuts with this basename) for later reference.
187 const SoftwareTriggerCutResult& moduleResult =
189 m_dbHandler->getAcceptOverridesReject());
190 const std::string& moduleResultIdentifier = SoftwareTriggerDBHandler::makeTotalResultName(m_param_baseIdentifier);
191 m_resultStoreObjectPointer->addResult(moduleResultIdentifier, moduleResult);
192
193 // Return the trigger decision up to here
195 const std::string& totalResultIdentifier = SoftwareTriggerDBHandler::makeTotalResultName();
196 if (totalResult) {
197 m_resultStoreObjectPointer->addResult(totalResultIdentifier, SoftwareTriggerCutResult::c_accept);
198 } else {
199 m_resultStoreObjectPointer->addResult(totalResultIdentifier, SoftwareTriggerCutResult::c_reject);
200 }
201 setReturnValue(totalResult);
202}
203
205{
207 B2DEBUG(20, "Storing debug output to file as requested.");
208 m_calculation->writeDebugOutput(m_debugTTree);
209 B2DEBUG(20, "Finished storing the debug output to file.");
210 }
211
213 B2DEBUG(20, "Storing debug output to DataStore as requested.");
215 }
216}
In the store you can park objects that have to be accessed by various modules.
Definition DataStore.h:51
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
Module()
Constructor.
Definition Module.cc:30
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
Implementation of a calculator used in the SoftwareTriggerModule to fill a SoftwareTriggerObject for ...
static SoftwareTriggerCutResult getModuleResult(const SoftwareTriggerResult &result, const std::string &baseIdentifier, bool acceptOverridesReject)
Calculate the "total_result" for a given base identifier by looping through all results with the give...
static bool getFinalTriggerDecision(const SoftwareTriggerResult &result, bool forgetTotalResult=false)
Calculate the final cut decision using all "total_results" of all sub triggers in the software trigge...
Implementation of a calculator used in the SoftwareTriggerModule to fill a SoftwareTriggerObject for ...
Implementation of a calculator used in the SoftwareTriggerModule to fill a SoftwareTriggerObject for ...
Helper class for performing up- and downloads of SoftwareTriggerCuts from the database.
static std::string makeTotalResultName(const std::string &baseIdentifier="all")
Handy function to create the name related to the total result of a specific trigger stage (either fil...
bool m_param_useRandomNumbersForPreScale
Flag to use random numbers or a counter for applying a prescale.
unsigned int m_param_preScaleStoreDebugOutputToDataStore
Prescale with which to save the results of the calculations into the DataStore.
std::string m_param_baseIdentifier
Base identifier for all cuts downloaded from database.
std::unique_ptr< SoftwareTriggerDBHandler > m_dbHandler
Internal handler object for the DB interface.
void initializeDebugOutput()
Helper function to initialize debug output creation by creating a TTree and an object in the data sto...
std::string m_param_resultStoreArrayName
Store Object Pointer name for storing the trigger decision.
void initialize() override
Initialize/Require the DB object pointers and any needed store arrays.
std::string m_param_debugOutputStoreObjName
Output store object name for the debug output. Is only used if debug is turned on.
void makeCut(const SoftwareTriggerObject &prefilledObject)
Helper function to perform the actual cut on the prefilled object and set the return value of the mod...
void event() override
Run over all cuts and check them. If one of the cuts yields true, give a positive return value of the...
void terminate() override
Store and delete the ttree if it was created.
std::unique_ptr< SoftwareTriggerCalculation > m_calculation
Internal handler for the Calculations (will be set in initialize to the correct one).
void beginRun() override
Check if the cut representations in the database have changed and download newer ones if needed.
std::vector< uint32_t > m_counters
Vector of the internal counters used to apply a prescale.
void initializeCalculation()
Helper function to initialize the calculation by creating a new calculation object and requiring all ...
bool m_param_storeDebugOutputToROOTFile
Flag to also store the result of the calculations into a root file.
SoftwareTriggerModule()
Create a new module instance and set the parameters.
void makeDebugOutput()
Helper function to store the calculated variables from the calculation either in the TTree or in the ...
std::string m_param_debugOutputFileName
Output file name for the debug output. Is only used if debug is turned on.
void initializeCounters()
Helper function to initialize the internal counters used for each cut identifier.
StoreObjPtr< SoftwareTriggerResult > m_resultStoreObjectPointer
Store Object for storing the trigger decision.
std::unique_ptr< TFile > m_debugOutputFile
TFile to store the debug TTree (or a nullptr if we do not save the debug output).
std::unique_ptr< TTree > m_debugTTree
TTree to store the debug output (or a nullptr if we do not save the debug output).
StoreObjPtr< SoftwareTriggerVariables > m_debugOutputStoreObject
TTree living in the datastore for debug reasons.
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.