Belle II Software  release-08-01-10
SoftwareTriggerResultPrinterModule.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/SoftwareTriggerResultPrinterModule.h>
10 #include <hlt/softwaretrigger/core/FinalTriggerDecisionCalculator.h>
11 #include <mdst/dbobjects/DBRepresentationOfSoftwareTriggerCut.h>
12 #include <framework/database/DBObjPtr.h>
13 
14 #include <TFile.h>
15 #include <TTree.h>
16 
17 #include <boost/algorithm/string/replace.hpp>
18 #include <memory>
19 
20 
21 using namespace Belle2;
22 using namespace SoftwareTrigger;
23 
24 REG_MODULE(SoftwareTriggerResultPrinter);
25 
26 
28  : Module()
29 {
30  setDescription("Write out the software trigger results in an easily accessible summary table to disk.");
31 
32  addParam("outputFileName", m_param_outputFileName, "File path and name of the ROOT "
33  "file, in which the results of the calculation are stored. Please note that already present files will be overridden. ",
35 }
36 
38 {
39  m_resultStoreObjectPointer.isRequired();
40  m_l1Result.isRequired();
41 }
42 
44 {
45 
46  auto debugOutputFile = std::unique_ptr<TFile>(TFile::Open(m_param_outputFileName.c_str(), "RECREATE"));
47  if (not debugOutputFile) {
48  B2FATAL("Could not open debug output file. Aborting.");
49  }
50  auto debugTTree = std::make_unique<TTree>("software_trigger_results", "software_trigger_results");
51  if (not debugTTree) {
52  B2FATAL("Could not create debug output tree. Aborting.");
53  }
54 
55  bool prescaled;
56  bool accepted;
57  bool cut;
58 
59  debugTTree->Branch("cut", &cut);
60  debugTTree->Branch("prescaled", &prescaled);
61  debugTTree->Branch("accept_or_reject", &accepted);
62  debugTTree->Branch("total_events", &m_numberOfEvents);
63  std::vector<double> value(m_passedEventsPerTrigger.size());
64 
65  cut = true;
66  prescaled = true;
67  accepted = true;
68  unsigned int counter = 0;
69  for (auto& cutResult : m_passedEventsPerTrigger) {
70  std::string cutName = cutResult.first;
71  boost::replace_all(cutName, "&", "_");
72  debugTTree->Branch(cutName.c_str(), &value.at(counter));
73 
74  value[counter] = static_cast<double>(cutResult.second[SoftwareTriggerCutResult::c_accept]);
75  counter++;
76  }
77  debugTTree->Fill();
78 
79  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
80  cut = true;
81  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
82  prescaled = true;
83  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
84  accepted = false;
85  counter = 0;
86  for (auto& cutResult : m_passedEventsPerTrigger) {
87  // cppcheck-suppress unreadVariable
88  value[counter] = static_cast<double>(cutResult.second[SoftwareTriggerCutResult::c_reject]);
89  counter++;
90  }
91  debugTTree->Fill();
92 
93  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
94  cut = true;
95  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
96  prescaled = false;
97  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
98  accepted = true;
99  counter = 0;
100  for (auto& cutResult : m_passedEventsPerTrigger) {
101  const auto& cutName = cutResult.first;
103  // cppcheck-suppress unreadVariable
104  value[counter] = NAN;
105  } else {
106  // cppcheck-suppress unreadVariable
107  value[counter] = static_cast<double>(m_passedEventsPerTriggerNonPrescaled[cutName][SoftwareTriggerCutResult::c_accept]);
108  }
109  counter++;
110  }
111  debugTTree->Fill();
112 
113  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
114  cut = true;
115  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
116  prescaled = false;
117  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
118  accepted = false;
119  counter = 0;
120  for (auto& cutResult : m_passedEventsPerTrigger) {
121  const auto& cutName = cutResult.first;
123  // cppcheck-suppress unreadVariable
124  value[counter] = NAN;
125  } else {
126  // cppcheck-suppress unreadVariable
127  value[counter] = static_cast<double>(m_passedEventsPerTriggerNonPrescaled[cutName][SoftwareTriggerCutResult::c_reject]);
128  }
129  counter++;
130  }
131  debugTTree->Fill();
132 
133  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
134  cut = false;
135  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
136  prescaled = false;
137  // cppcheck-suppress redundantAssignment; the variable is used in the Fill() method below
138  accepted = false;
139  counter = 0;
140  for (auto& cutResult : m_passedEventsPerTrigger) {
141  const auto& cutName = cutResult.first;
142  if (m_prescales.find(cutName) == m_prescales.end()) {
143  // cppcheck-suppress unreadVariable
144  value[counter] = NAN;
145  } else {
146  // cppcheck-suppress unreadVariable
147  value[counter] = static_cast<double>(m_prescales[cutName]);
148  }
149  counter++;
150  }
151  debugTTree->Fill();
152 
153  debugOutputFile->cd();
154  debugOutputFile->Write();
155  debugTTree.reset();
156  debugOutputFile.reset();
157 }
158 
160 {
162 
163  for (const auto& [cutName, cutResults] : m_resultStoreObjectPointer->getResultPairs()) {
164  m_passedEventsPerTrigger[cutName][static_cast<SoftwareTriggerCutResult >(cutResults.first)]++;
165 
166  // This does only make sense for non-total results (as they are prescaled)
167  if (cutName.find("total_result") == std::string::npos) {
168  m_passedEventsPerTriggerNonPrescaled[cutName][static_cast<SoftwareTriggerCutResult >(cutResults.second)]++;
169 
170  DBObjPtr<DBRepresentationOfSoftwareTriggerCut> downloadedCut(cutName);
171  if (downloadedCut) {
172  m_prescales[cutName] = downloadedCut->getPreScaleFactor();
173  }
174  }
175  }
176 
178  if (eventAccepted) {
180  } else {
182  }
183 
184  if (m_l1Result.isValid()) {
185  const bool l1Accepted = m_l1Result->test();
186  if (l1Accepted) {
188  } else {
190  }
191  } else {
192  if (m_eventMetaDataPtr)
193  B2WARNING("Uncaught exception encountered: Trying to access StoreObjPtr object 'TRGSummary' (durability: event), which was not created in exp/run/evt: "
194  << LogVar("exp", m_eventMetaDataPtr->getExperiment())
195  << LogVar("run", m_eventMetaDataPtr->getRun())
196  << LogVar("event", m_eventMetaDataPtr->getEvent()));
197  }
198 }
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
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...
StoreObjPtr< TRGSummary > m_l1Result
Store Object for reading the l1 result.
std::map< std::string, std::map< SoftwareTriggerCutResult, unsigned int > > m_passedEventsPerTriggerNonPrescaled
Internal map of summed results.
void event() override
Write out the cuts if wanted and sum them up.
std::string m_param_outputFileName
Output file name for the debug output.
void terminate() override
Store and delete the ttree if it was created. Print out the summed results.
std::map< std::string, std::map< SoftwareTriggerCutResult, unsigned int > > m_passedEventsPerTrigger
Internal map of summed results.
std::map< std::string, unsigned int > m_prescales
Internal map of prescales.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
EventMetaData is used by processEvent()/processCore().
StoreObjPtr< SoftwareTriggerResult > m_resultStoreObjectPointer
Store Object for reading the trigger decision.
unsigned int m_numberOfEvents
Internal counter for the number of seen events.
SoftwareTriggerResultPrinterModule()
Create a new module instance and set the parameters.
Class to store variables with their name which were sent to the logging service.
REG_MODULE(arichBtest)
Register the Module.
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:560
SoftwareTriggerCutResult
Enumeration with all possible results of the SoftwareTriggerCut.
@ c_accept
Accept this event.
@ c_reject
Reject this event.
Abstract base class for different kinds of events.