Belle II Software  release-05-01-25
SoftwareTriggerHLTDQMModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2018 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Chunhua Li, Thomas Hauth, Nils Braun, Markus Prim *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #include <hlt/softwaretrigger/modules/dqm/SoftwareTriggerHLTDQMModule.h>
11 
12 #include <TDirectory.h>
13 
14 #include <hlt/softwaretrigger/core/SoftwareTriggerDBHandler.h>
15 #include <hlt/softwaretrigger/core/FinalTriggerDecisionCalculator.h>
16 
17 #include <framework/core/ModuleParam.templateDetails.h>
18 
19 #include <algorithm>
20 #include <fstream>
21 
22 using namespace Belle2;
23 using namespace SoftwareTrigger;
24 
25 REG_MODULE(SoftwareTriggerHLTDQM)
26 
28 {
29  setDescription("Monitor Physics Trigger");
30  setPropertyFlags(c_ParallelProcessingCertified);
31 
32  // Fill in the default values of the module parameters
33  m_param_variableIdentifiers = {};
34 
35  m_param_cutResultIdentifiers["filter"]["filter"] = {"total_result"};
36 
37  addParam("cutResultIdentifiers", m_param_cutResultIdentifiers,
38  "Which cuts should be reported? Please remember to include the total_result also, if wanted.",
39  m_param_cutResultIdentifiers);
40 
41  addParam("cutResultIdentifiersIgnored", m_param_cutResultIdentifiersIgnored,
42  "Which cuts should be ignored? This will display cleaner trigger lines, e.g. to clear them from bhabha contamination. "
43  "Vetoes on skims do not apply in filter plot and vice versa.",
44  m_param_cutResultIdentifiersIgnored);
45 
46  addParam("cutResultIdentifiersPerUnit", m_param_cutResultIdentifiersPerUnit,
47  "Which cuts should be reported per unit?",
48  m_param_cutResultIdentifiersPerUnit);
49 
50  addParam("variableIdentifiers", m_param_variableIdentifiers,
51  "Which variables should be reported?",
52  m_param_variableIdentifiers);
53 
54  addParam("l1Identifiers", m_param_l1Identifiers,
55  "Which l1 identifiers to report?",
56  m_param_l1Identifiers);
57 
58  addParam("createTotalResultHistograms", m_param_create_total_result_histograms,
59  "Create total result histogram?",
60  true);
61 
62  addParam("createExpRunEventHistograms", m_param_create_exp_run_event_histograms,
63  "Create exp/run/event histograms?",
64  true);
65 
66  addParam("createHLTUnitHistograms", m_param_create_hlt_unit_histograms,
67  "Create HLT unit histograms?",
68  false);
69 
70  addParam("createErrorFlagHistograms", m_param_create_error_flag_histograms,
71  "Create Error Flag histograms?",
72  false);
73 
74  addParam("histogramDirectoryName", m_param_histogramDirectoryName,
75  "SoftwareTrigger DQM histograms will be put into this directory", m_param_histogramDirectoryName);
76 }
77 
79 {
80  TDirectory* oldDirectory = nullptr;
81 
82  if (!m_param_histogramDirectoryName.empty()) {
83  oldDirectory = gDirectory;
84  TDirectory* histDir = oldDirectory->mkdir(m_param_histogramDirectoryName.c_str());
85  histDir->cd();
86  }
87 
88  for (auto const& variable : m_param_variableIdentifiers) {
89  // todo: make correct range
90  const unsigned int numberOfBins = 50;
91  const double lowerX = 0;
92  const double upperX = 50;
93  m_triggerVariablesHistograms.emplace(variable, new TH1F(variable.c_str(), variable.c_str(), numberOfBins, lowerX, upperX));
94  m_triggerVariablesHistograms[variable]->SetXTitle(("SoftwareTriggerVariable " + variable).c_str());
95  }
96 
97  for (const auto& cutIdentifier : m_param_cutResultIdentifiers) {
98 
99  const std::string& title = cutIdentifier.first;
100  const auto& mapVal = *(m_param_cutResultIdentifiers[title].begin());
101  const std::string& baseIdentifier = mapVal.first;
102  const int numberOfFlags = mapVal.second.size();
103 
104  if (title == baseIdentifier)
105  m_cutResultHistograms.emplace(title,
106  new TH1F(title.c_str(), ("Events triggered in HLT " + baseIdentifier).c_str(),
107  numberOfFlags, 0,
108  numberOfFlags));
109  else
110  m_cutResultHistograms.emplace(title,
111  new TH1F((baseIdentifier + "_" + title).c_str(), ("Events triggered in HLT " + baseIdentifier + " : " + title).c_str(),
112  numberOfFlags, 0,
113  numberOfFlags));
114  m_cutResultHistograms[title]->SetXTitle("");
115  m_cutResultHistograms[title]->SetOption("bar");
116  m_cutResultHistograms[title]->SetFillStyle(0);
117  m_cutResultHistograms[title]->SetStats(false);
118  }
119 
120  // We add one for the total result
122  m_cutResultHistograms.emplace("total_result",
123  new TH1F("total_result", "Total Result of HLT (absolute numbers)", 1, 0, 0));
124  m_cutResultHistograms["total_result"]->SetXTitle("Total Cut Result");
125  m_cutResultHistograms["total_result"]->SetOption("bar");
126  m_cutResultHistograms["total_result"]->SetFillStyle(0);
127  m_cutResultHistograms["total_result"]->SetStats(false);
128  }
129 
130  for (const std::string& trigger : m_param_l1Identifiers) {
131  m_l1Histograms.emplace(trigger, new TH1F(trigger.c_str(), ("Events triggered in L1 " + trigger).c_str(), 1, 0, 0));
132  m_l1Histograms[trigger]->SetXTitle("");
133  m_l1Histograms[trigger]->SetOption("bar");
134  m_l1Histograms[trigger]->SetFillStyle(0);
135  m_l1Histograms[trigger]->SetStats(false);
136  }
137 
138  // And also one for the total numbers
140  m_l1Histograms.emplace("l1_total_result",
141  new TH1F("l1_total_result", "Events triggered in L1 (total results)", 1, 0, 0));
142  m_l1Histograms["l1_total_result"]->SetXTitle("Total L1 Cut Result");
143  m_l1Histograms["l1_total_result"]->SetOption("bar");
144  m_l1Histograms["l1_total_result"]->SetFillStyle(0);
145  m_l1Histograms["l1_total_result"]->SetStats(false);
146  }
147 
149  m_runInfoHistograms.emplace("run_number", new TH1F("run_number", "Run Number", 100, 0, 10000));
150  m_runInfoHistograms.emplace("event_number", new TH1F("event_number", "Event Number", 100, 0, 1'000'000));
151  m_runInfoHistograms.emplace("experiment_number", new TH1F("experiment_number", "Experiment Number", 50, 0, 50));
152  }
153 
155  m_runInfoHistograms.emplace("hlt_unit_number", new TH1F("hlt_unit_number", "HLT Unit Number", HLTUnit::max_hlt_units, 0,
157 
158  for (const auto& cutIdentifierPerUnit : m_param_cutResultIdentifiersPerUnit) {
159  m_cutResultPerUnitHistograms.emplace(cutIdentifierPerUnit , new TH1F((cutIdentifierPerUnit + "_per_unit").c_str(),
160  ("Events triggered per unit in HLT : " + cutIdentifierPerUnit).c_str(), HLTUnit::max_hlt_units, 0,
162  m_cutResultPerUnitHistograms[cutIdentifierPerUnit]->SetXTitle("HLT unit number");
163  m_cutResultPerUnitHistograms[cutIdentifierPerUnit]->SetOption("bar");
164  m_cutResultPerUnitHistograms[cutIdentifierPerUnit]->SetFillStyle(0);
165  }
166 
167  }
168 
170  m_runInfoHistograms.emplace("error_flag", new TH1F("error_flag", "Error Flag", 4, 0, 4));
171  m_runInfoHistograms["error_flag"]->SetOption("bar");
172  m_runInfoHistograms["error_flag"]->SetFillStyle(0);
173  m_runInfoHistograms["error_flag"]->SetStats(false);
174  }
175 
176  if (oldDirectory) {
177  oldDirectory->cd();
178  }
179 }
180 
182 {
183  // Register histograms (calls back defineHisto)
184  REG_HISTOGRAM
185 
187  std::ifstream file;
188  file.open(HLTUnit::hlt_unit_file);
189  if (file.good()) {
190  std::string host;
191  getline(file, host);
192  m_hlt_unit = atoi(host.substr(3, 2).c_str());
193  file.close();
194  } else {
195  B2WARNING("HLT unit number not found");
196  }
197  }
198 }
199 
201 {
202  // this might be pre-scaled for performance reasons in the final configuration, therefore this structure
203  // might not be filled in every event
204  if (m_variables.isValid()) {
205  for (auto& variableNameAndTH1F : m_triggerVariablesHistograms) {
206  const std::string& variable = variableNameAndTH1F.first;
207  TH1F* histogram = variableNameAndTH1F.second;
208 
209  // try to load this variable from the computed trigger variables
210  if (not m_variables->has(variable)) {
211  B2ERROR("Variable " << variable << " configured for SoftwareTriggerDQM plotting is not available");
212  } else {
213  const double value = m_variables->getVariable(variable);
214  histogram->Fill(value);
215  }
216  }
217  }
218 
219  if (m_triggerResult.isValid()) {
220  const auto results = m_triggerResult->getResults();
221 
222  for (auto const& cutIdentifier : m_param_cutResultIdentifiers) {
223  const std::string& title = cutIdentifier.first;
224  const auto& mapVal = *(m_param_cutResultIdentifiers[title].begin());
225  const std::string& baseIdentifier = mapVal.first;
226  const auto& cuts = mapVal.second;
227 
228  // check if we want to ignore it
229  bool skip = false;
230  const auto& cutsIgnored = m_param_cutResultIdentifiersIgnored[baseIdentifier];
231 
232  for (const std::string& cutTitleIgnored : cutsIgnored) {
233  const std::string& cutNameIgnored = cutTitleIgnored.substr(0, cutTitleIgnored.find("\\"));
234  const std::string& fullCutIdentifierIgnored = SoftwareTriggerDBHandler::makeFullCutName(baseIdentifier, cutNameIgnored);
235 
236  auto const cutEntryIgnored = results.find(fullCutIdentifierIgnored);
237 
238  if (cutEntryIgnored != results.end()) {
239  if (cutEntryIgnored->second > 0) skip = true;
240  }
241  }
242 
243  for (const std::string& cutTitle : cuts) {
244  const std::string& cutName = cutTitle.substr(0, cutTitle.find("\\"));
245  const std::string& fullCutIdentifier = SoftwareTriggerDBHandler::makeFullCutName(baseIdentifier, cutName);
246 
247  // check if the cutResult is in the list, be graceful when not available
248  // Create results object instead of calling .find() on a temporary object. This will cause undefined behaviour
249  // when checking again the .end() pointer, when the .end() pointer is also created from a temporary object.
250  auto const cutEntry = results.find(fullCutIdentifier);
251 
252  if (cutEntry != results.end()) {
253  const int cutResult = cutEntry->second;
254  m_cutResultHistograms[title]->Fill(cutTitle.c_str(), cutResult > 0 and not skip);
255  }
256  }
257 
259  if (title == baseIdentifier) {
260  const std::string& totalCutIdentifier = SoftwareTriggerDBHandler::makeTotalResultName(baseIdentifier);
261  const int cutResult = static_cast<int>(m_triggerResult->getResult(totalCutIdentifier));
262 
263  m_cutResultHistograms["total_result"]->Fill(totalCutIdentifier.c_str(), cutResult > 0);
264  }
265  }
266  }
267 
270  m_cutResultHistograms["total_result"]->Fill("total_result", totalResult > 0);
271  }
272 
274  for (const std::string& cutIdentifierPerUnit : m_param_cutResultIdentifiersPerUnit) {
275  const std::string& cutName = cutIdentifierPerUnit.substr(0, cutIdentifierPerUnit.find("\\"));
276  const std::string& fullCutIdentifier = SoftwareTriggerDBHandler::makeFullCutName("filter", cutName);
277 
278  // check if the cutResult is in the list, be graceful when not available
279  auto const cutEntry = results.find(fullCutIdentifier);
280 
281  if (cutEntry != results.end()) {
282  const int cutResult = cutEntry->second;
283  m_cutResultPerUnitHistograms[cutIdentifierPerUnit]->Fill(m_hlt_unit, cutResult > 0);
284  }
285  }
286  }
287 
288  if (m_l1TriggerResult.isValid() and m_l1NameLookup.isValid()) {
289  for (const std::string& l1Trigger : m_param_l1Identifiers) {
290  const int triggerBit = m_l1NameLookup->getoutbitnum(l1Trigger.c_str());
291  if (triggerBit < 0) {
292  B2WARNING("Could not find"
293  << LogVar("L1 trigger line", l1Trigger));
294  continue;
295  }
296  const bool triggerResult = m_l1TriggerResult->testPsnm(triggerBit);
298  m_l1Histograms["l1_total_result"]->Fill(l1Trigger.c_str(), triggerResult);
299  }
300 
301  if (not triggerResult) {
302  continue;
303  }
304 
305  for (auto const& cutIdentifier : m_param_cutResultIdentifiers) {
306  const std::string& title = cutIdentifier.first;
307  const auto& mapVal = *(m_param_cutResultIdentifiers[title].begin());
308  const std::string& baseIdentifier = mapVal.first;
309  const auto& cuts = mapVal.second;
310 
311  if (title == baseIdentifier) {
312  for (const std::string& cutTitle : cuts) {
313  const std::string& cutName = cutTitle.substr(0, cutTitle.find("\\"));
314  const std::string& fullCutIdentifier = SoftwareTriggerDBHandler::makeFullCutName(baseIdentifier, cutName);
315 
316  // check if the cutResult is in the list, be graceful when not available
317  auto const cutEntry = results.find(fullCutIdentifier);
318 
319  if (cutEntry != results.end()) {
320  const int cutResult = cutEntry->second;
321  m_l1Histograms[l1Trigger]->Fill(cutTitle.c_str(), cutResult > 0);
322  }
323  }
324  }
325  }
326 
328  m_l1Histograms[l1Trigger]->Fill("hlt_result", totalResult > 0);
329  m_l1Histograms[l1Trigger]->LabelsDeflate("X");
330  }
331  }
332  }
333 
335  m_runInfoHistograms["run_number"]->Fill(m_eventMetaData->getRun());
336  m_runInfoHistograms["event_number"]->Fill(m_eventMetaData->getEvent());
337  m_runInfoHistograms["experiment_number"]->Fill(m_eventMetaData->getExperiment());
338  }
339 
341  m_runInfoHistograms["error_flag"]->Fill("B2LinkPacketCRCError",
342  (bool)(m_eventMetaData->getErrorFlag() & EventMetaData::EventErrorFlag::c_B2LinkPacketCRCError));
343  m_runInfoHistograms["error_flag"]->Fill("B2LinkEventCRCError",
344  (bool)(m_eventMetaData->getErrorFlag() & EventMetaData::EventErrorFlag::c_B2LinkEventCRCError));
345  m_runInfoHistograms["error_flag"]->Fill("HLTCrash",
346  (bool)(m_eventMetaData->getErrorFlag() & EventMetaData::EventErrorFlag::c_HLTCrash));
347  m_runInfoHistograms["error_flag"]->Fill("ReconstructionAbort",
348  (bool)(m_eventMetaData->getErrorFlag() & EventMetaData::EventErrorFlag::c_ReconstructionAbort));
349  }
350 
352  m_runInfoHistograms["hlt_unit_number"]->Fill(m_hlt_unit);
353  }
354 }
355 
357 {
358  std::for_each(m_cutResultHistograms.begin(), m_cutResultHistograms.end(),
359  [](auto & it) { it.second->Reset(); });
360  std::for_each(m_cutResultPerUnitHistograms.begin(), m_cutResultPerUnitHistograms.end(),
361  [](auto & it) { it.second->Reset(); });
362  std::for_each(m_triggerVariablesHistograms.begin(), m_triggerVariablesHistograms.end(),
363  [](auto & it) { it.second->Reset(); });
364  std::for_each(m_l1Histograms.begin(), m_l1Histograms.end(),
365  [](auto & it) { it.second->Reset(); });
366  std::for_each(m_runInfoHistograms.begin(), m_runInfoHistograms.end(),
367  [](auto & it) { it.second->Reset(); });
368 }
369 
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_cutResultPerUnitHistograms
std::map< std::string, TH1F * > m_cutResultPerUnitHistograms
histograms for the final sw trigger decisions for each base identifier per unit
Definition: SoftwareTriggerHLTDQMModule.h:104
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_cutResultHistograms
std::map< std::string, TH1F * > m_cutResultHistograms
histograms for the final sw trigger decisions for each base identifier
Definition: SoftwareTriggerHLTDQMModule.h:101
Belle2::SoftwareTrigger::SoftwareTriggerDBHandler::makeFullCutName
static std::string makeFullCutName(const std::string &baseCutIdentifier, const std::string &cutIdentifier)
Helper function to compile the full identifier from the base and the specific cut name.
Definition: SoftwareTriggerDBHandler.cc:39
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_create_hlt_unit_histograms
bool m_param_create_hlt_unit_histograms
Create HLT unit number histograms?
Definition: SoftwareTriggerHLTDQMModule.h:85
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_l1NameLookup
DBObjPtr< TRGGDLDBFTDLBits > m_l1NameLookup
Dataobjects.
Definition: SoftwareTriggerHLTDQMModule.h:129
Belle2::SoftwareTrigger::HLTUnit::max_hlt_units
static constexpr unsigned int max_hlt_units
Maximum number of HLT units used during the experiment.
Definition: SoftwareTriggerHLTDQMModule.h:135
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_histogramDirectoryName
std::string m_param_histogramDirectoryName
Directory to put the generated histograms.
Definition: SoftwareTriggerHLTDQMModule.h:94
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_variables
StoreObjPtr< SoftwareTriggerVariables > m_variables
STM cut variables.
Definition: SoftwareTriggerHLTDQMModule.h:123
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::initialize
void initialize() override
Module functions to be called from main process.
Definition: SoftwareTriggerHLTDQMModule.cc:181
Belle2::SoftwareTrigger::FinalTriggerDecisionCalculator::getFinalTriggerDecision
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...
Definition: FinalTriggerDecisionCalculator.cc:17
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_cutResultIdentifiersIgnored
std::map< std::string, std::vector< std::string > > m_param_cutResultIdentifiersIgnored
Which cuts should be ignored? This can be used to clear trigger lines from e.g. bhabha contamination.
Definition: SoftwareTriggerHLTDQMModule.h:70
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_l1Histograms
std::map< std::string, TH1F * > m_l1Histograms
histogram with the L1 information
Definition: SoftwareTriggerHLTDQMModule.h:110
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_hlt_unit
int m_hlt_unit
HLT unit number of the machine used.
Definition: SoftwareTriggerHLTDQMModule.h:97
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_triggerResult
StoreObjPtr< SoftwareTriggerResult > m_triggerResult
STM cut results.
Definition: SoftwareTriggerHLTDQMModule.h:117
Belle2::SoftwareTrigger::HLTUnit::hlt_unit_file
static constexpr char hlt_unit_file[]
Location of HLT unit number information.
Definition: SoftwareTriggerHLTDQMModule.h:138
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_variableIdentifiers
std::vector< std::string > m_param_variableIdentifiers
Which variables should be reported?
Definition: SoftwareTriggerHLTDQMModule.h:91
LogVar
Class to store variables with their name which were sent to the logging service.
Definition: LogVariableStream.h:24
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_cutResultIdentifiers
std::map< std::string, std::map< std::string, std::vector< std::string > > > m_param_cutResultIdentifiers
Which cuts should be reported? Please remember to include the total_result also, if wanted.
Definition: SoftwareTriggerHLTDQMModule.h:67
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::event
void event() override
Module functions to be called from event process.
Definition: SoftwareTriggerHLTDQMModule.cc:200
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::beginRun
void beginRun() override
Reset all histogram entries for a new run.
Definition: SoftwareTriggerHLTDQMModule.cc:356
Belle2::SoftwareTrigger::SoftwareTriggerDBHandler::makeTotalResultName
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...
Definition: SoftwareTriggerDBHandler.cc:48
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_runInfoHistograms
std::map< std::string, TH1F * > m_runInfoHistograms
histograms with the run information
Definition: SoftwareTriggerHLTDQMModule.h:113
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_create_total_result_histograms
bool m_param_create_total_result_histograms
Create total result histogram?
Definition: SoftwareTriggerHLTDQMModule.h:79
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule
Module defining the STM histograms.
Definition: SoftwareTriggerHLTDQMModule.h:47
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_create_error_flag_histograms
bool m_param_create_error_flag_histograms
Create error flag histograms?
Definition: SoftwareTriggerHLTDQMModule.h:88
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_create_exp_run_event_histograms
bool m_param_create_exp_run_event_histograms
Create exp/run/event number histograms?
Definition: SoftwareTriggerHLTDQMModule.h:82
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_eventMetaData
StoreObjPtr< EventMetaData > m_eventMetaData
Event Info.
Definition: SoftwareTriggerHLTDQMModule.h:126
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_l1Identifiers
std::vector< std::string > m_param_l1Identifiers
Which L1 cuts should be reported?
Definition: SoftwareTriggerHLTDQMModule.h:76
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_l1TriggerResult
StoreObjPtr< TRGSummary > m_l1TriggerResult
L1 cut results.
Definition: SoftwareTriggerHLTDQMModule.h:120
Belle2::HistoModule
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_triggerVariablesHistograms
std::map< std::string, TH1F * > m_triggerVariablesHistograms
histograms for the software trigger variables in all calculators (although maybe not filled)
Definition: SoftwareTriggerHLTDQMModule.h:107
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::m_param_cutResultIdentifiersPerUnit
std::vector< std::string > m_param_cutResultIdentifiersPerUnit
Which cuts should be reported per unit?
Definition: SoftwareTriggerHLTDQMModule.h:73
Belle2::SoftwareTrigger::SoftwareTriggerHLTDQMModule::defineHisto
void defineHisto() override
Histogram definition.
Definition: SoftwareTriggerHLTDQMModule.cc:78