Belle II Software development
DQMHistAnalysisHLTModule.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 <dqm/analysis/modules/DQMHistAnalysisHLTModule.h>
10#include <framework/core/ModuleParam.templateDetails.h>
11#include <TROOT.h>
12
13#include <hlt/utilities/Units.h>
14
15using namespace std;
16using namespace Belle2;
17
18namespace {
19 bool hasValue(const std::string& name, TH1* histogram)
20 {
21 return histogram->GetXaxis()->FindFixBin(name.c_str()) != -1;
22 }
23
24 double getValue(const std::string& name, TH1* histogram)
25 {
26 if (not hasValue(name, histogram)) {
27 B2ERROR("This histogram does not have this value! (fallback value = -1)"
28 << LogVar("histogram", histogram->GetName())
29 << LogVar("value", name));
30 return -1;
31 }
32 auto binNumber = histogram->GetXaxis()->FindFixBin(name.c_str());
33 return histogram->GetBinContent(binNumber);
34 }
35}
36
37REG_MODULE(DQMHistAnalysisHLT);
38
40{
41 setDescription("Modify and analyze the data quality histograms of HLT");
42 addParam("pvPrefix", m_pvPrefix, "EPICS PV Name for the inst. luminosity", m_pvPrefix);
43 addParam("bhabhaName", m_bhabhaName, "Name of the bhabha trigger to do a ratio against", m_bhabhaName);
44 addParam("columnMapping", m_columnMapping, "Which columns to use for calculating ratios and cross sections", m_columnMapping);
45 addParam("l1Histograms", m_l1Histograms, "Which l1 histograms to show", m_l1Histograms);
46 addParam("retentionPerUnit", m_retentionPerUnit, "Which HLT filter lines to use for calculation retention rate per unit",
48}
49
51{
52 // this seems to be important, or strange things happen
53 gROOT->cd();
54
56 new TCanvas("HLT/Ratio"),
57 new TH1F("Ratio", "Retention of selected HLT skims", 1, 0, 0)
58 };
60 new TCanvas("HLT/RatioTotal"),
61 new TH1F("RatioTotal", "Ratio of Tags to all events", 1, 0, 0)
62 };
64 new TCanvas("HLT/CrossSection"),
65 new TH1F("CrossSection", "Cross Section of triggered Events", 1, 0, 0)
66 };
67 m_hRatios = {
68 new TCanvas("HLT/RatioToBahbha"),
69 new TH1F("RatioToBahbha", "Ratio to bhabha events", 1, 0, 0)
70 };
71
72 for (const std::string& l1Name : m_l1Histograms) {
73 m_hl1Ratios.emplace(l1Name, std::make_pair(
74 new TCanvas(("HLT/" + l1Name + "RatioToL1").c_str()),
75 // + 1 for total result
76 new TH1F((l1Name + "RatioToL1").c_str(), ("HLT Fractions for L1 " + l1Name).c_str(), 1, 0, 0)
77 ));
78 }
79
80 for (const std::string& filterLine : m_retentionPerUnit) {
81 m_hRetentionPerUnit.emplace(filterLine, std::make_pair(
82 new TCanvas(("HLT/" + filterLine + "_RetentionPerUnit").c_str()),
83 new TH1F((filterLine + "_RetentionPerUnit").c_str(), ("Retention rate per unit of: " + filterLine).c_str(),
84 HLTUnits::max_hlt_units + 1, 0,
85 HLTUnits::max_hlt_units + 1)
86 ));
87 }
88
89 for (auto& canvasAndHisto : {m_hEfficiencyTotal, m_hEfficiency, m_hCrossSection, m_hRatios}) {
90 auto* histogram = canvasAndHisto.second;
91 histogram->SetDirectory(0);
92 histogram->SetOption("bar");
93 histogram->SetFillStyle(0);
94 histogram->SetMinimum(0);
95 histogram->SetStats(false);
96 histogram->Draw("hist");
97 }
98
99 for (auto& nameAndcanvasAndHisto : m_hl1Ratios) {
100 auto* histogram = nameAndcanvasAndHisto.second.second;
101 histogram->SetDirectory(0);
102 histogram->SetOption("bar");
103 histogram->SetFillStyle(0);
104 histogram->SetStats(false);
105 histogram->Draw("hist");
106 }
107
108 for (auto& nameAndcanvasAndHisto : m_hRetentionPerUnit) {
109 auto* histogram = nameAndcanvasAndHisto.second.second;
110 histogram->SetDirectory(0);
111 histogram->SetOption("histe");
112 histogram->SetMinimum(0);
113 histogram->SetStats(false);
114 histogram->Draw();
115 }
116
117 m_hMeanTime = {
118 new TCanvas("HLT/MeanTime"),
119 new TH1F("MeanTime", "Mean processing time", 1, 0, 0)
120 };
121
123 new TCanvas("HLT/ErrorFlagFraction"),
124 new TH1D("ErrorFlagFraction", "Fraction of events with Error Flags", 1, 0, 0)
125 };
126
128 new TCanvas("HLT/FilteredFractionPerUnit"),
129 new TH1D("FilteredFractionPerUnit", "Fraction of events filtered per unit", 1, 0, 0)
130 };
131
133 new TCanvas("HLT/MeanBudgetTimePerUnit"),
134 new TH1F("MeanBudgetTimePerUnit", "Mean budget time per unit", 1, 0, 0)
135 };
136
138 new TCanvas("HLT/MeanProcessingTimePerUnit"),
139 new TH1F("MeanProcessingTimePerUnit", "Mean processing time per unit", 1, 0, 0)
140 };
141
142 m_hMeanMemory = {
143 new TCanvas("HLT/MeanMemoryChange"),
144 new TH1F("MeanMemoryChange", "Mean memory change [MB]", 1, 0, 0)
145 };
146
147#ifdef _BELLE2_EPICS
148 if (not m_pvPrefix.empty()) {
149 if (!ca_current_context()) SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
150 SEVCHK(ca_create_channel(m_pvPrefix.data(), NULL, NULL, 10, &m_epicschid), "ca_create_channel failure");
151 SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
152 }
153#endif
154}
155
156
158{
160 auto* canvas = canvasAndHisto.first;
161 canvas->Clear();
162 }
163
164 for (auto& canvasAndHisto : {m_hErrorFlagFraction, m_hFilteredFractionPerUnit}) {
165 auto* canvas = canvasAndHisto.first;
166 canvas->Clear();
167 }
168
169 for (auto& nameAndcanvasAndHisto : m_hl1Ratios) {
170 auto* canvas = nameAndcanvasAndHisto.second.first;
171 canvas->Clear();
172 }
173
174 for (auto& nameAndcanvasAndHisto : m_hRetentionPerUnit) {
175 auto* canvas = nameAndcanvasAndHisto.second.first;
176 canvas->Clear();
177 }
178}
179
181{
182 auto* filterHistogram = findHist("softwaretrigger/filter");
183 auto* skimHistogram = findHist("softwaretrigger/skim");
184 auto* totalResultHistogram = findHist("softwaretrigger/total_result");
185 auto* hltUnitNumberHistogram = findHist("softwaretrigger_before_filter/hlt_unit_number");
186 auto* processesPerUnitHistogram = findHist("timing_statistics/processesPerUnitHistogram");
187 auto* meanTimeHistogram = findHist("timing_statistics/meanTimeHistogram");
188 auto* errorFlagHistogram = findHist("softwaretrigger_before_filter/error_flag");
189 auto* hltUnitNumberHistogram_filtered = findHist("softwaretrigger/hlt_unit_number_after_filter");
190 auto* fullTimeMeanPerUnitHistogram = findHist("timing_statistics/fullTimeMeanPerUnitHistogram");
191 auto* processingTimeMeanPerUnitHistogram = findHist("timing_statistics/processingTimeMeanPerUnitHistogram");
192 auto* meanMemoryHistogram = findHist("timing_statistics/meanMemoryHistogram");
193
194 if (not filterHistogram) {
195 B2ERROR("Can not find the filter histogram!");
196 return;
197 }
198 if (not skimHistogram) {
199 B2ERROR("Can not find the skim histogram!");
200 return;
201 }
202 if (not totalResultHistogram) {
203 B2ERROR("Can not find the total result histogram!");
204 return;
205 }
206 if (not hltUnitNumberHistogram) {
207 B2ERROR("Can not find the HLT unit number histogram!");
208 return;
209 }
210 if (not processesPerUnitHistogram) {
211 B2ERROR("Can not find the processes per unit histogram!");
212 return;
213 }
214 if (not meanTimeHistogram) {
215 B2ERROR("Can not find the mean processing time histogram!");
216 return;
217 }
218 if (not errorFlagHistogram) {
219 B2ERROR("Can not find the error flag histogram!");
220 return;
221 }
222 if (not hltUnitNumberHistogram_filtered) {
223 B2ERROR("Can not find the HLT unit number after filter histogram!");
224 return;
225 }
226 if (not fullTimeMeanPerUnitHistogram) {
227 B2ERROR("Can not find the HLT budget time per unit histogram!");
228 return;
229 }
230 if (not processingTimeMeanPerUnitHistogram) {
231 B2ERROR("Can not find the HLT processing time per unit histogram!");
232 return;
233 }
234 if (not meanMemoryHistogram) {
235 B2ERROR("Can not find the mean memory change histogram!");
236 return;
237 }
238
239 m_hEfficiencyTotal.second->Reset();
240 m_hEfficiency.second->Reset();
241 m_hCrossSection.second->Reset();
242 m_hRatios.second->Reset();
243
244 double instLuminosity = 0;
245 double numberOfAcceptedHLTEvents = getValue("total_result", totalResultHistogram);
246 double numberOfBhabhaEvents = getValue(m_bhabhaName, skimHistogram);
247 double numberOfAllEvents = hltUnitNumberHistogram->GetEntries();
248 double numberOfProcesses = processesPerUnitHistogram->GetEntries();
249
250#ifdef _BELLE2_EPICS
251 if (not m_pvPrefix.empty()) {
252 SEVCHK(ca_get(DBR_DOUBLE, m_epicschid, (void*)&instLuminosity), "ca_get failure");
253 SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
254 } else {
255 instLuminosity = 0;
256 }
257#endif
258
259 m_hEfficiencyTotal.second->Fill("total_result", numberOfAcceptedHLTEvents / numberOfAllEvents);
260 if (instLuminosity != 0) {
261 m_hCrossSection.second->Fill("total_result", numberOfAcceptedHLTEvents / numberOfAllEvents * instLuminosity);
262 }
263 m_hRatios.second->Fill("total_result", numberOfAcceptedHLTEvents / numberOfBhabhaEvents);
264
265 for (const auto& columnMapping : m_columnMapping) {
266 const auto& from = columnMapping.first;
267 const auto& to = columnMapping.second;
268
269 double value = 0;
270 if (hasValue(from, filterHistogram)) {
271 value = getValue(from, filterHistogram);
272 } else if (hasValue(from, skimHistogram)) {
273 value = getValue(from, skimHistogram);
274 } else {
275 B2ERROR("Can not find value " << from << ". Will not use it!");
276 continue;
277 }
278
279 m_hEfficiency.second->Fill(to.c_str(), value / numberOfAcceptedHLTEvents);
280 m_hEfficiencyTotal.second->Fill(to.c_str(), value / numberOfAllEvents);
281 if (instLuminosity != 0) {
282 m_hCrossSection.second->Fill(to.c_str(), value / numberOfAllEvents * instLuminosity);
283 }
284 m_hRatios.second->Fill(to.c_str(), value / numberOfBhabhaEvents);
285 }
286
287 for (const std::string& l1Name : m_l1Histograms) {
288 auto* histogram = m_hl1Ratios.at(l1Name).second;
289 histogram->Reset();
290
291 auto* l1Histogram = findHist("softwaretrigger/" + l1Name);
292 auto* l1TotalResultHistogram = findHist("softwaretrigger/l1_total_result");
293
294 if (not l1Histogram or not l1TotalResultHistogram) {
295 B2ERROR("Can not find L1 histograms from softwaretrigger!");
296 continue;
297 }
298
299 for (const auto& columnMapping : m_columnMapping) {
300 const auto& from = columnMapping.first;
301 const auto& to = columnMapping.second;
302
303 if (not hasValue(from, l1Histogram)) {
304 B2ERROR("Can not find label " << from << " in l1 histogram " << l1Name);
305 continue;
306 }
307
308 if (not hasValue(l1Name, l1TotalResultHistogram)) {
309 B2ERROR("Can not find label " << l1Name << " in l1 total result histogram");
310 continue;
311 }
312
313 const double hltValueInL1Bin = getValue(from, l1Histogram);
314 const double l1TotalResult = getValue(l1Name, l1TotalResultHistogram);
315
316 histogram->Fill(to.c_str(), hltValueInL1Bin / l1TotalResult);
317 }
318
319 // and add a total result bin
320 const auto from = "hlt_result";
321 const auto to = "hlt_result";
322
323 if (not hasValue(from, l1Histogram)) {
324 B2ERROR("Can not find label " << from << " in l1 histogram " << l1Name);
325 continue;
326 }
327
328 if (not hasValue(l1Name, l1TotalResultHistogram)) {
329 B2ERROR("Can not find label " << l1Name << " in l1 total result histogram");
330 continue;
331 }
332
333 const double hltValueInL1Bin = getValue(from, l1Histogram);
334 const double l1TotalResult = getValue(l1Name, l1TotalResultHistogram);
335
336 histogram->Fill(to, hltValueInL1Bin / l1TotalResult);
337 }
338
339 for (const std::string& filterLine : m_retentionPerUnit) {
340 auto* histogram = m_hRetentionPerUnit.at(filterLine).second;
341 histogram->Reset();
342
343 auto* filterLineHistogram = findHist("softwaretrigger/" + filterLine + "_per_unit");
344
345 if (not filterLineHistogram) {
346 B2ERROR("Can not find " << filterLineHistogram << "_per_event histograms from softwaretrigger!");
347 continue;
348 }
349
350 for (unsigned int i = 1; i <= HLTUnits::max_hlt_units + 1; i++) {
351 double totalUnitValue = hltUnitNumberHistogram->GetBinContent(i);
352 if (totalUnitValue == 0) {
353 histogram->Fill(i, 0);
354 } else {
355 double filterLineUnitValue = filterLineHistogram->GetBinContent(i);
356 histogram->SetBinContent(i, filterLineUnitValue / totalUnitValue);
357 }
358 }
359 }
360
361 m_hMeanTime.second = (TH1F*) meanTimeHistogram->Clone("MeanTime");
362 m_hMeanTime.second->Scale(1 / numberOfProcesses);
363
364 m_hMeanMemory.second = (TH1F*) meanMemoryHistogram->Clone("MeanMemoryChange");
365 m_hMeanMemory.second->Scale(1 / numberOfProcesses);
366
367 m_hErrorFlagFraction.second = (TH1D*) errorFlagHistogram->Clone("ErrorFlagFraction");
368 m_hErrorFlagFraction.second->Scale(1 / numberOfAllEvents);
369 m_hErrorFlagFraction.second->SetTitle("Fraction of events with error flags");
370
371 m_hFilteredFractionPerUnit.second = (TH1D*) hltUnitNumberHistogram_filtered->Clone("FilteredFractionPerUnit");
372 m_hFilteredFractionPerUnit.second->Divide(hltUnitNumberHistogram_filtered, hltUnitNumberHistogram);
373 m_hFilteredFractionPerUnit.second->SetTitle("Fraction of events filtered per unit");
374
375 m_hMeanBudgetTimePerUnit.second = (TH1F*) fullTimeMeanPerUnitHistogram->Clone("MeanBudgetTimePerUnit");
376 m_hMeanBudgetTimePerUnit.second->Divide(fullTimeMeanPerUnitHistogram, processesPerUnitHistogram);
377
378 m_hMeanProcessingTimePerUnit.second = (TH1F*) processingTimeMeanPerUnitHistogram->Clone("MeanProcessingTimePerUnit");
379 m_hMeanProcessingTimePerUnit.second->Divide(processingTimeMeanPerUnitHistogram, processesPerUnitHistogram);
380
382 auto* canvas = canvasAndHisto.first;
383 auto* histogram = canvasAndHisto.second;
384
385 canvas->cd();
386 histogram->LabelsDeflate("X");
387 histogram->Draw("hist");
388 canvas->Modified();
389 canvas->Update();
390 }
391
392 for (auto& canvasAndHisto : {m_hErrorFlagFraction, m_hFilteredFractionPerUnit}) {
393 auto* canvas = canvasAndHisto.first;
394 auto* histogram = canvasAndHisto.second;
395
396 canvas->cd();
397 histogram->LabelsDeflate("X");
398 histogram->Draw("hist");
399 histogram->SetStats(false);
400 canvas->Modified();
401 canvas->Update();
402 }
403
404 for (auto& nameAndCanvasAndHisto : m_hl1Ratios) {
405 auto* canvas = nameAndCanvasAndHisto.second.first;
406 auto* histogram = nameAndCanvasAndHisto.second.second;
407
408 canvas->cd();
409 histogram->LabelsDeflate("X");
410 histogram->Draw("hist");
411 canvas->Modified();
412 canvas->Update();
413 }
414
415 for (auto& nameAndCanvasAndHisto : m_hRetentionPerUnit) {
416 auto* canvas = nameAndCanvasAndHisto.second.first;
417 auto* histogram = nameAndCanvasAndHisto.second.second;
418
419 canvas->cd();
420 histogram->Draw("hist");
421 canvas->Modified();
422 canvas->Update();
423 }
424}
425
427{
428#ifdef _BELLE2_EPICS
429 if (not m_pvPrefix.empty()) {
430 SEVCHK(ca_clear_channel(m_epicschid), "ca_clear_channel failure");
431 SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
432 }
433#endif
434}
void initialize() override final
Initializer.
std::string m_bhabhaName
name of the bhabha trigger
std::pair< TCanvas *, TH1F * > m_hCrossSection
Histogram with final cross sections.
std::map< std::string, std::pair< TCanvas *, TH1F * > > m_hRetentionPerUnit
Histogram with retention rate per unit of some hlt filter lines.
std::map< std::string, std::pair< TCanvas *, TH1F * > > m_hl1Ratios
Histogram with hlt&l1 ratios to l1 numbers.
std::vector< std::string > m_retentionPerUnit
Which HLT filter lines to use for calculation retention rate per unit.
std::string m_pvPrefix
prefix for EPICS PVs
void terminate() override final
This method is called at the end of the event processing.
std::pair< TCanvas *, TH1D * > m_hFilteredFractionPerUnit
Histogram with fraction of events filtered per unit.
void event() override final
This method is called for each event.
std::vector< std::string > m_l1Histograms
Which l1 triggers to show.
std::pair< TCanvas *, TH1F * > m_hMeanBudgetTimePerUnit
Histogram with mean budget time per unit per process.
std::pair< TCanvas *, TH1F * > m_hMeanProcessingTimePerUnit
Histogram with mean processing time per unit per process.
std::pair< TCanvas *, TH1F * > m_hMeanMemory
Histogram with mean memory change per process.
std::pair< TCanvas *, TH1D * > m_hErrorFlagFraction
Histogram with fraction of events with error flags.
std::pair< TCanvas *, TH1F * > m_hRatios
Histogram with final ratios to bhabha.
std::pair< TCanvas *, TH1F * > m_hEfficiency
Histogram with final efficiencies to HLT.
std::pair< TCanvas *, TH1F * > m_hEfficiencyTotal
Histogram with final efficiencies to all events.
void beginRun() override final
Called when entering a new run.
std::map< std::string, std::string > m_columnMapping
Which columns to use.
std::pair< TCanvas *, TH1F * > m_hMeanTime
Histogram with mean processing time per process.
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.
STL namespace.