Belle II Software  release-05-01-25
DQMHistAnalysisHLTModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2019 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Nils Braun *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #include <dqm/analysis/modules/DQMHistAnalysisHLTModule.h>
11 #include <framework/core/ModuleParam.templateDetails.h>
12 #include <TROOT.h>
13 
14 #include <hlt/softwaretrigger/modules/dqm/SoftwareTriggerHLTDQMModule.h>
15 
16 using namespace std;
17 using namespace Belle2;
18 
19 namespace {
20  bool hasValue(const std::string& name, TH1* histogram)
21  {
22  return histogram->GetXaxis()->FindFixBin(name.c_str()) != -1;
23  }
24 
25  double getValue(const std::string& name, TH1* histogram)
26  {
27  B2ASSERT("This histogram does not have this value!", hasValue(name, histogram));
28  auto binNumber = histogram->GetXaxis()->FindFixBin(name.c_str());
29  return histogram->GetBinContent(binNumber);
30  }
31 }
32 
33 REG_MODULE(DQMHistAnalysisHLT)
34 
35 DQMHistAnalysisHLTModule::DQMHistAnalysisHLTModule()
36 {
37  addParam("pvPrefix", m_pvPrefix, "EPICS PV Name for the inst. luminosity", m_pvPrefix);
38  addParam("bhabhaName", m_bhabhaName, "Name of the bhabha trigger to do a ratio against", m_bhabhaName);
39  addParam("columnMapping", m_columnMapping, "Which columns to use for calculating ratios and cross sections", m_columnMapping);
40  addParam("l1Histograms", m_l1Histograms, "Which l1 histograms to show", m_l1Histograms);
41  addParam("retentionPerUnit", m_retentionPerUnit, "Which HLT filter lines to use for calculation retention rate per unit",
42  m_retentionPerUnit);
43 }
44 
45 void DQMHistAnalysisHLTModule::initialize()
46 {
47  // this seems to be important, or strange things happen
48  gROOT->cd();
49 
50  m_hEfficiency = {
51  new TCanvas("HLT/Ratio"),
52  new TH1F("Ratio", "Ratio of Tags to HLT triggered events", 1, 0, 0)
53  };
54  m_hEfficiencyTotal = {
55  new TCanvas("HLT/RatioTotal"),
56  new TH1F("Ratio", "Ratio of Tags to all events", 1, 0, 0)
57  };
58  m_hCrossSection = {
59  new TCanvas("HLT/CrossSection"),
60  new TH1F("CrossSection", "Cross Section of triggered Events", 1, 0, 0)
61  };
62  m_hRatios = {
63  new TCanvas("HLT/RatioToBahbha"),
64  new TH1F("RatioToBahbha", "Ratio to bhabha events", 1, 0, 0)
65  };
66 
67  for (const std::string& l1Name : m_l1Histograms) {
68  m_hl1Ratios.emplace(l1Name, std::make_pair(
69  new TCanvas(("HLT/" + l1Name + "RatioToL1").c_str()),
70  // + 1 for total result
71  new TH1F((l1Name + "RatioToL1").c_str(), ("HLT Fractions for L1 " + l1Name).c_str(), 1, 0, 0)
72  ));
73  }
74 
75  for (const std::string& filterLine : m_retentionPerUnit) {
76  m_hRetentionPerUnit.emplace(filterLine, std::make_pair(
77  new TCanvas(("HLT/" + filterLine + "_RetentionPerUnit").c_str()),
78  new TH1F((filterLine + "_RetentionPerUnit").c_str(), ("Retention rate per unit of: " + filterLine).c_str(),
79  SoftwareTrigger::HLTUnit::max_hlt_units, 1,
80  SoftwareTrigger::HLTUnit::max_hlt_units + 1)
81  ));
82  }
83 
84  for (auto& canvasAndHisto : {m_hEfficiencyTotal, m_hEfficiency, m_hCrossSection, m_hRatios}) {
85  auto* histogram = canvasAndHisto.second;
86  histogram->SetDirectory(0);
87  histogram->SetOption("bar");
88  histogram->SetFillStyle(0);
89  histogram->SetStats(false);
90  histogram->Draw("hist");
91  }
92 
93  for (auto& nameAndcanvasAndHisto : m_hl1Ratios) {
94  auto* histogram = nameAndcanvasAndHisto.second.second;
95  histogram->SetDirectory(0);
96  histogram->SetOption("bar");
97  histogram->SetFillStyle(0);
98  histogram->SetStats(false);
99  histogram->Draw("hist");
100  }
101 
102  for (auto& nameAndcanvasAndHisto : m_hRetentionPerUnit) {
103  auto* histogram = nameAndcanvasAndHisto.second.second;
104  histogram->SetDirectory(0);
105  histogram->SetOption("bar");
106  histogram->SetFillStyle(0);
107  histogram->SetStats(false);
108  histogram->Draw("hist");
109  }
110 
111 #ifdef _BELLE2_EPICS
112  if (not m_pvPrefix.empty()) {
113  SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
114  SEVCHK(ca_create_channel(m_pvPrefix.data(), NULL, NULL, 10, &m_epicschid), "ca_create_channel failure");
115  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
116  }
117 #endif
118 }
119 
120 
121 void DQMHistAnalysisHLTModule::beginRun()
122 {
123  for (auto& canvasAndHisto : {m_hEfficiencyTotal, m_hEfficiency, m_hCrossSection, m_hRatios}) {
124  auto* canvas = canvasAndHisto.first;
125  canvas->Clear();
126  }
127 
128  for (auto& nameAndcanvasAndHisto : m_hl1Ratios) {
129  auto* canvas = nameAndcanvasAndHisto.second.first;
130  canvas->Clear();
131  }
132 
133  for (auto& nameAndcanvasAndHisto : m_hRetentionPerUnit) {
134  auto* canvas = nameAndcanvasAndHisto.second.first;
135  canvas->Clear();
136  }
137 }
138 
139 void DQMHistAnalysisHLTModule::event()
140 {
141  auto* filterHistogram = findHist("softwaretrigger/filter");
142  auto* skimHistogram = findHist("softwaretrigger/skim");
143  auto* totalResultHistogram = findHist("softwaretrigger/total_result");
144  auto* hltUnitNumberHistogram = findHist("softwaretrigger_before_filter/hlt_unit_number");
145 
146  if (not filterHistogram) {
147  B2ERROR("Can not find the filter histogram!");
148  return;
149  }
150  if (not skimHistogram) {
151  B2ERROR("Can not find the skim histogram!");
152  return;
153  }
154  if (not totalResultHistogram) {
155  B2ERROR("Can not find the total result histogram!");
156  return;
157  }
158  if (not hltUnitNumberHistogram) {
159  B2ERROR("Can not find the HLT unit number histogram!");
160  return;
161  }
162 
163  m_hEfficiencyTotal.second->Reset();
164  m_hEfficiency.second->Reset();
165  m_hCrossSection.second->Reset();
166  m_hRatios.second->Reset();
167 
168  double instLuminosity = 0;
169  double numberOfAcceptedHLTEvents = getValue("total_result", totalResultHistogram);
170  double numberOfBhabhaEvents = getValue(m_bhabhaName, skimHistogram);
171  double numberOfAllEvents = hltUnitNumberHistogram->GetEntries();
172 
173 #ifdef _BELLE2_EPICS
174  if (not m_pvPrefix.empty()) {
175  if (!ca_current_context()) SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
176  SEVCHK(ca_get(DBR_DOUBLE, m_epicschid, (void*)&instLuminosity), "ca_get failure");
177  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
178  } else {
179  instLuminosity = 0;
180  }
181 #endif
182 
183  m_hEfficiencyTotal.second->Fill("total_result", numberOfAcceptedHLTEvents / numberOfAllEvents);
184  if (instLuminosity != 0) {
185  m_hCrossSection.second->Fill("total_result", numberOfAcceptedHLTEvents / numberOfAllEvents * instLuminosity);
186  }
187  m_hRatios.second->Fill("total_result", numberOfAcceptedHLTEvents / numberOfBhabhaEvents);
188 
189  for (const auto& columnMapping : m_columnMapping) {
190  const auto& from = columnMapping.first;
191  const auto& to = columnMapping.second;
192 
193  double value = 0;
194  if (hasValue(from, filterHistogram)) {
195  value = getValue(from, filterHistogram);
196  } else if (hasValue(from, skimHistogram)) {
197  value = getValue(from, skimHistogram);
198  } else {
199  B2ERROR("Can not find value " << from << ". Will not use it!");
200  continue;
201  }
202 
203  m_hEfficiency.second->Fill(to.c_str(), value / numberOfAcceptedHLTEvents);
204  m_hEfficiencyTotal.second->Fill(to.c_str(), value / numberOfAllEvents);
205  if (instLuminosity != 0) {
206  m_hCrossSection.second->Fill(to.c_str(), value / numberOfAllEvents * instLuminosity);
207  }
208  m_hRatios.second->Fill(to.c_str(), value / numberOfBhabhaEvents);
209  }
210 
211  for (const std::string& l1Name : m_l1Histograms) {
212  auto* histogram = m_hl1Ratios.at(l1Name).second;
213  histogram->Reset();
214 
215  auto* l1Histogram = findHist("softwaretrigger/" + l1Name);
216  auto* l1TotalResultHistogram = findHist("softwaretrigger/l1_total_result");
217 
218  if (not l1Histogram or not l1TotalResultHistogram) {
219  B2ERROR("Can not find L1 histograms from softwaretrigger!");
220  continue;
221  }
222 
223  for (const auto& columnMapping : m_columnMapping) {
224  const auto& from = columnMapping.first;
225  const auto& to = columnMapping.second;
226 
227  if (not hasValue(from, l1Histogram)) {
228  B2ERROR("Can not find label " << from << " in l1 histogram " << l1Name);
229  continue;
230  }
231 
232  if (not hasValue(l1Name, l1TotalResultHistogram)) {
233  B2ERROR("Can not find label " << l1Name << " in l1 total result histogram");
234  continue;
235  }
236 
237  const double hltValueInL1Bin = getValue(from, l1Histogram);
238  const double l1TotalResult = getValue(l1Name, l1TotalResultHistogram);
239 
240  histogram->Fill(to.c_str(), hltValueInL1Bin / l1TotalResult);
241  }
242 
243  // and add a total result bin
244  const auto from = "hlt_result";
245  const auto to = "hlt_result";
246 
247  if (not hasValue(from, l1Histogram)) {
248  B2ERROR("Can not find label " << from << " in l1 histogram " << l1Name);
249  continue;
250  }
251 
252  if (not hasValue(l1Name, l1TotalResultHistogram)) {
253  B2ERROR("Can not find label " << l1Name << " in l1 total result histogram");
254  continue;
255  }
256 
257  const double hltValueInL1Bin = getValue(from, l1Histogram);
258  const double l1TotalResult = getValue(l1Name, l1TotalResultHistogram);
259 
260  histogram->Fill(to, hltValueInL1Bin / l1TotalResult);
261  }
262 
263  for (const std::string& filterLine : m_retentionPerUnit) {
264  auto* histogram = m_hRetentionPerUnit.at(filterLine).second;
265  histogram->Reset();
266 
267  auto* filterLineHistogram = findHist("softwaretrigger/" + filterLine + "_per_unit");
268 
269  if (not filterLineHistogram) {
270  B2ERROR("Can not find " << filterLineHistogram << "_per_event histograms from softwaretrigger!");
271  continue;
272  }
273 
274  for (unsigned int i = 1; i <= SoftwareTrigger::HLTUnit::max_hlt_units; i++) {
275  double totalUnitValue = hltUnitNumberHistogram->GetBinContent(i);
276  if (totalUnitValue == 0) {
277  histogram->Fill(i, 0);
278  } else {
279  double filterLineUnitValue = filterLineHistogram->GetBinContent(i);
280  histogram->Fill(i, filterLineUnitValue / totalUnitValue);
281  }
282  }
283  }
284 
285  for (auto& canvasAndHisto : {m_hEfficiencyTotal, m_hEfficiency, m_hCrossSection, m_hRatios}) {
286  auto* canvas = canvasAndHisto.first;
287  auto* histogram = canvasAndHisto.second;
288 
289  canvas->cd();
290  histogram->LabelsDeflate("X");
291  histogram->Draw("hist");
292  canvas->Modified();
293  canvas->Update();
294  }
295 
296  for (auto& nameAndCanvasAndHisto : m_hl1Ratios) {
297  auto* canvas = nameAndCanvasAndHisto.second.first;
298  auto* histogram = nameAndCanvasAndHisto.second.second;
299 
300  canvas->cd();
301  histogram->LabelsDeflate("X");
302  histogram->Draw("hist");
303  canvas->Modified();
304  canvas->Update();
305  }
306 
307  for (auto& nameAndCanvasAndHisto : m_hRetentionPerUnit) {
308  auto* canvas = nameAndCanvasAndHisto.second.first;
309  auto* histogram = nameAndCanvasAndHisto.second.second;
310 
311  canvas->cd();
312  histogram->Draw("hist");
313  canvas->Modified();
314  canvas->Update();
315  }
316 }
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19