Belle II Software development
DQMHistAnalysisPXDEff.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// File : DQMHistAnalysisPXDEff.cc
10// Description : DQM module, which gives histograms showing the efficiency of PXD sensors
11//-
12
13#include <dqm/analysis/modules/DQMHistAnalysisPXDEff.h>
14#include <TROOT.h>
15#include <TLatex.h>
16#include <TGraphAsymmErrors.h>
17#include <vxd/geometry/GeoCache.h>
18
19using namespace std;
20using namespace Belle2;
21
22//-----------------------------------------------------------------
23// Register the Module
24//-----------------------------------------------------------------
25REG_MODULE(DQMHistAnalysisPXDEff);
26
27//-----------------------------------------------------------------
28// Implementation
29//-----------------------------------------------------------------
30
32{
33 // This module CAN NOT be run in parallel!
34 setDescription("DQM Analysis for PXD Efficiency");
35
36 // Parameter definition
37
38 // Would be much more elegant to get bin numbers from the saved histograms, but would need to retrieve at least one of them before the initialize function for this
39 // Or get one and clone it
40 addParam("binsU", m_u_bins, "histogram bins in u direction, needs to be the same as in PXDDQMEfficiency", int(16));
41 addParam("binsV", m_v_bins, "histogram bins in v direction, needs to be the same as in PXDDQMEfficiency", int(48));
42 addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of the directory where histograms were placed",
43 std::string("PXDEFF"));
44 addParam("ConfidenceLevel", m_confidence, "Confidence Level for error bars and alarms", 0.99);
45 addParam("WarnLevel", m_warnlevel, "Efficiency Warn Level for alarms", 0.92);
46 addParam("ErrorLevel", m_errorlevel, "Efficiency Level for alarms", 0.90);
47 addParam("perModuleAlarm", m_perModuleAlarm, "Alarm level per module", true);
48 addParam("alarmAdhoc", m_alarmAdhoc, "Generate Alarm from adhoc values", true);
49 addParam("minEntries", m_minEntries, "minimum number of new entries for last time slot", 1000);
50 addParam("excluded", m_excluded, "the list of excluded modules, indices from 0 to 39", std::vector<int>());
51 B2DEBUG(1, "DQMHistAnalysisPXDEff: Constructor done.");
52}
53
55{
56 B2DEBUG(99, "DQMHistAnalysisPXDEffModule: initialized.");
57
60
61 // collect the list of all PXD Modules in the geometry here
62 std::vector<VxdID> sensors = geo.getListOfSensors();
63 for (const auto& aVxdID : sensors) {
64 VXD::SensorInfoBase info = geo.getSensorInfo(aVxdID);
65 if (info.getType() != VXD::SensorInfoBase::PXD) continue;
66 m_PXDModules.push_back(aVxdID); // reorder, sort would be better
67 }
68 std::sort(m_PXDModules.begin(), m_PXDModules.end()); // back to natural order
69
70 gROOT->cd(); // this seems to be important, or strange things happen
71
72 int nu = 1;//If this does not get overwritten, the histograms will anyway never contain anything useful
73 int nv = 1;
74 if (m_PXDModules.size() == 0) {
75 // This could as well be a B2FATAL, the module won't do anything useful if this happens
76 B2WARNING("No PXDModules in Geometry found! Use hard-coded setup.");
77 std::vector <string> mod = {
78 "1.1.1", "1.1.2", "1.2.1", "1.2.2", "1.3.1", "1.3.2", "1.4.1", "1.4.2",
79 "1.5.1", "1.5.2", "1.6.1", "1.6.2", "1.7.1", "1.7.2", "1.8.1", "1.8.2",
80 "2.1.1", "2.1.2", "2.2.1", "2.2.2", "2.3.1", "2.3.2", "2.4.1", "2.4.2",
81 "2.5.1", "2.5.2", "2.6.1", "2.6.2", "2.7.1", "2.7.2", "2.8.1", "2.8.2",
82 "2.9.1", "2.9.2", "2.10.1", "2.10.2", "2.11.1", "2.11.2", "2.12.1", "2.12.2"
83 };
84 for (const auto& it : mod) m_PXDModules.push_back(VxdID(it));
85 // set some default size to nu, nv?
86 } else {
87 // Have been promised that all modules have the same number of pixels, so just take from the first one
89 nu = cellGetInfo.getUCells();
90 nv = cellGetInfo.getVCells();
91 }
92
93 for (const auto& aPXDModule : m_PXDModules) {
94 auto buff = (std::string)aPXDModule;
95 replace(buff.begin(), buff.end(), '.', '_');
96 registerEpicsPV("PXD:Eff:" + buff, (std::string)aPXDModule);
97
98 TString histTitle = "PXD Hit Efficiency on Module " + (std::string)aPXDModule + ";Pixel in U;Pixel in V";
99 m_cEffModules[aPXDModule] = new TCanvas((m_histogramDirectoryName + "/c_Eff_" + buff).c_str());
100 m_eEffModules[aPXDModule] = new TEfficiency(("ePXDHitEff_" + buff).c_str(), histTitle,
101 m_u_bins, -0.5, nu - 0.5, m_v_bins, -0.5, nv - 0.5);
102 }
103
104 m_cInnerMap = new TCanvas((m_histogramDirectoryName + "/c_InnerMap").data());
105 m_cOuterMap = new TCanvas((m_histogramDirectoryName + "/c_OuterMap").data());
106 m_hInnerMap = new TH2F("hEffInnerMap", "hEffInnerMap", m_u_bins * 8, 0, m_u_bins * 8, m_v_bins * 2, 0, m_v_bins * 2);
107 m_hOuterMap = new TH2F("hEffOuterMap", "hEffOuterMap", m_u_bins * 12, 0, m_u_bins * 12, m_v_bins * 2, 0, m_v_bins * 2);
108
109 m_nrxbins = m_PXDModules.size() + 3; // Modules + L1 + L2 + All
110 m_hErrorLine = new TH1F("hPXDErrorlimit", "Error Limit", m_nrxbins, 0, m_nrxbins);
111 m_hWarnLine = new TH1F("hPXDWarnlimit", "Warn Limit", m_nrxbins, 0, m_nrxbins);
112 for (int i = 0; i < (int)m_nrxbins; i++) {
113 m_hErrorLine->SetBinContent(i + 1, m_errorlevel);
114 m_hWarnLine->SetBinContent(i + 1, m_warnlevel);
115 }
116 m_hWarnLine->SetLineColor(kOrange - 3);
117 m_hWarnLine->SetLineWidth(3);
118 m_hWarnLine->SetLineStyle(4);
119 m_hErrorLine->SetLineColor(kRed + 3);
120 m_hErrorLine->SetLineWidth(3);
121 m_hErrorLine->SetLineStyle(7);
122
123 //One bin for each module in the geometry, one histogram for each layer
124 m_cEffAll = new TCanvas((m_histogramDirectoryName + "/c_EffAll").data());
125 m_eEffAll = new TEfficiency("ePXDHitEffAll", "PXD Integrated Efficiency of each module;PXD Module;", m_nrxbins, 0, m_nrxbins);
126 m_eEffAll->SetConfidenceLevel(m_confidence);
127 m_eEffAll->Paint("AP");
128 m_hEffAllLastTotal = m_eEffAll->GetCopyTotalHisto();
129 m_hEffAllLastPassed = m_eEffAll->GetCopyPassedHisto();
130
131 setLabels(m_eEffAll->GetPaintedGraph());
132
133 m_cEffAllUpdate = new TCanvas((m_histogramDirectoryName + "/c_EffAllUp").data());
134 m_eEffAllUpdate = new TEfficiency("ePXDHitEffAllUpdate", "PXD Integral and last-updated Efficiency per module;PXD Module;",
135 m_nrxbins, 0, m_nrxbins);
136 m_eEffAllUpdate->SetConfidenceLevel(m_confidence);
137
138 m_eEffAllUpdate->Paint("AP");
139 setLabels(m_eEffAllUpdate->GetPaintedGraph());
140
141 m_monObj->addCanvas(m_cEffAll);
142 m_monObj->addCanvas(m_cEffAllUpdate);
143
144 registerEpicsPV("PXD:Eff:Status", "Status");
145 registerEpicsPV("PXD:Eff:Overall", "All");
146 registerEpicsPV("PXD:Eff:L1", "L1");
147 registerEpicsPV("PXD:Eff:L2", "L2");
148 B2DEBUG(1, "DQMHistAnalysisPXDEff: initialized.");
149}
150
151
153{
154 B2DEBUG(1, "DQMHistAnalysisPXDEff: beginRun called.");
155
156 // Clear all used canvases
157 m_cEffAll->Clear();
158 m_cEffAllUpdate->Clear();
159 m_cInnerMap->Clear();
160 m_cOuterMap->Clear();
161 for (auto single_cmap : m_cEffModules) {
162 if (single_cmap.second) single_cmap.second->Clear();
163 }
164
165 // The 2d Efficiency maps (m_eEffModules[]) per module are not cleared, but re-created each update
166 // also they are only drawn to Canvas on update, thus no clear is needed here
167
168 // Reset TEfficiency and get (new) alarm limits from PVs
169 // no way to reset TEfficiency, do it bin by bin
170 for (int i = 0; i < m_nrxbins; i++) {
171 int bin = i + 1;
172 m_eEffAll->SetPassedEvents(bin, 0); // order, otherwise it might happen that SetTotalEvents is NOT filling the value!
173 m_eEffAll->SetTotalEvents(bin, 0);
174 m_eEffAllUpdate->SetPassedEvents(bin, 0); // otherwise it might happen that SetTotalEvents is NOT filling the value!
175 m_eEffAllUpdate->SetTotalEvents(bin, 0);
176
177 if (i < int(m_PXDModules.size())) { // only for modules
180
181 // get warn and error limit
182 // as the same array as above, we assume chid exists
183 double dummy, loerr = 0, lowarn = 0;
184 if (requestLimitsFromEpicsPVs((std::string)m_PXDModules[i], loerr, lowarn, dummy, dummy)) {
185 m_hErrorLine->SetBinContent(bin, loerr);
187 m_hWarnLine->SetBinContent(bin, lowarn);
189 }
190 }
191 }
192 {
193 double dummy, loerr = 0, lowarn = 0;
196 if (requestLimitsFromEpicsPVs("L1", loerr, lowarn, dummy, dummy)) {
197 m_hErrorLine->SetBinContent(m_PXDModules.size() + 1, loerr);
198 if (m_perModuleAlarm) m_errorlevelmod["L1"] = loerr;
199 m_hWarnLine->SetBinContent(m_PXDModules.size() + 1, lowarn);
200 if (m_perModuleAlarm) m_warnlevelmod["L1"] = lowarn;
201 }
204 if (requestLimitsFromEpicsPVs("L2", loerr, lowarn, dummy, dummy)) {
205 m_hErrorLine->SetBinContent(m_PXDModules.size() + 2, loerr);
206 if (m_perModuleAlarm) m_errorlevelmod["L2"] = loerr;
207 m_hWarnLine->SetBinContent(m_PXDModules.size() + 2, lowarn);
208 if (m_perModuleAlarm) m_warnlevelmod["L2"] = lowarn;
209 }
212 if (requestLimitsFromEpicsPVs("All", loerr, lowarn, dummy, dummy)) {
213 m_hErrorLine->SetBinContent(m_PXDModules.size() + 3, loerr);
214 if (m_perModuleAlarm) m_errorlevelmod["All"] = loerr;
215 m_hWarnLine->SetBinContent(m_PXDModules.size() + 3, lowarn);
216 if (m_perModuleAlarm) m_warnlevelmod["All"] = lowarn;
217 }
218 }
219
220 // Clear all remaining Histograms (e.g. for our private delta histogramming)
221 m_hEffAllLastTotal->Reset();
222 m_hEffAllLastPassed->Reset();
223 m_hInnerMap->Reset();
224 m_hOuterMap->Reset();
225}
226
227bool DQMHistAnalysisPXDEffModule::updateEffBins(int bin, int nhit, int nmatch, int minentries)
228{
229 m_eEffAll->SetPassedEvents(bin, 0); // otherwise it might happen that SetTotalEvents is NOT filling the value!
230 m_eEffAll->SetTotalEvents(bin, nhit);
231 m_eEffAll->SetPassedEvents(bin, nmatch);
232
233 if (nhit < minentries) {
234 // update the first entries directly (short runs)
235 m_eEffAllUpdate->SetPassedEvents(bin, 0); // otherwise it might happen that SetTotalEvents is NOT filling the value!
236 m_eEffAllUpdate->SetTotalEvents(bin, nhit);
237 m_eEffAllUpdate->SetPassedEvents(bin, nmatch);
238 m_hEffAllLastTotal->SetBinContent(bin, nhit);
239 m_hEffAllLastPassed->SetBinContent(bin, nmatch);
240 return true;
241 } else if (nhit - m_hEffAllLastTotal->GetBinContent(bin) > minentries) {
242 m_eEffAllUpdate->SetPassedEvents(bin, 0); // otherwise it might happen that SetTotalEvents is NOT filling the value!
243 m_eEffAllUpdate->SetTotalEvents(bin, nhit - m_hEffAllLastTotal->GetBinContent(bin));
244 m_eEffAllUpdate->SetPassedEvents(bin, nmatch - m_hEffAllLastPassed->GetBinContent(bin));
245 m_hEffAllLastTotal->SetBinContent(bin, nhit);
246 m_hEffAllLastPassed->SetBinContent(bin, nmatch);
247 return true;
248 }// else
249 return false;
250}
251
252bool DQMHistAnalysisPXDEffModule::check_warn_level(int bin, const std::string& name)
253{
254 bool warn_flag = (m_eEffAll->GetEfficiency(bin) + m_eEffAll->GetEfficiencyErrorUp(bin) <
255 m_warnlevelmod[name]); // (and not only the actual eff value)
256 if (m_alarmAdhoc) {
257 warn_flag |= (m_eEffAllUpdate->GetEfficiency(bin) + m_eEffAllUpdate->GetEfficiencyErrorUp(bin) <
258 m_warnlevelmod[name]); // (and not only the actual eff value)
259 }
260 return warn_flag;
261}
262
263bool DQMHistAnalysisPXDEffModule::check_error_level(int bin, const std::string& name)
264{
265 bool error_flag = (m_eEffAll->GetEfficiency(bin) + m_eEffAll->GetEfficiencyErrorUp(bin) <
266 m_errorlevelmod[name]); // error if upper error value is below limit
267 if (m_alarmAdhoc) {
268 error_flag |= (m_eEffAllUpdate->GetEfficiency(bin) + m_eEffAllUpdate->GetEfficiencyErrorUp(bin) <
269 m_errorlevelmod[name]); // error if upper error value is below limit
270 }
271 return error_flag;
272}
273
274void DQMHistAnalysisPXDEffModule::setLabels(TGraphAsymmErrors* gr)
275{
276 if (gr) {
277 auto ax = gr->GetXaxis();
278 if (ax) {
279 ax->Set(m_nrxbins, 0, m_nrxbins);
280 for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
281 TString ModuleName = (std::string)m_PXDModules[i];
282 ax->SetBinLabel(i + 1, ModuleName);
283 }
284 ax->SetBinLabel(m_PXDModules.size() + 1, "L1");
285 ax->SetBinLabel(m_PXDModules.size() + 2, "L2");
286 ax->SetBinLabel(m_PXDModules.size() + 3, "All");
287 }
288 }
289}
290
292{
293 {
294 // First create some 2d overview of efficiency for all modules
295 // This is not taken into account for efficiency calculation as
296 // there may be update glitches dues to separate histograms
297 // The histograms
298 bool updateinner = false, updateouter = false;
299 for (const auto& aPXDModule : m_PXDModules) {
300 auto buff = (std::string)aPXDModule;
301 replace(buff.begin(), buff.end(), '.', '_');
302
303 std::string locationHits = "track_hits_" + buff;
304 std::string locationMatches = "matched_cluster_" + buff;
305
306 auto Hits = findHist(m_histogramDirectoryName, locationHits, true);// check if updated
307 auto Matches = findHist(m_histogramDirectoryName, locationMatches, true);// check if updated
308
309 if (Hits == nullptr && Matches == nullptr) continue; // none updated
310
311 if (Hits == nullptr) Hits = findHist(m_histogramDirectoryName, locationHits); // actually, this should not happen ...
312 if (Matches == nullptr) Matches = findHist(m_histogramDirectoryName, locationMatches); // ... as updates should coincide
313
314 // Finding only one of them should only happen in very strange situations... still better check
315 if (Hits && Matches) {
316 if (m_cEffModules[aPXDModule] && m_eEffModules[aPXDModule]) {// this check creates them with a nullptr ..bad
317 m_eEffModules[aPXDModule]->SetTotalHistogram(*Hits, "f");
318 m_eEffModules[aPXDModule]->SetPassedHistogram(*Matches, "f");
319
320 m_cEffModules[aPXDModule]->cd();
321 m_eEffModules[aPXDModule]->Paint("colz"); // not Draw, enforce to create GetPaintedHistogram?
322 m_eEffModules[aPXDModule]->Draw("colz"); // but Draw needed to export Canvas!
323 m_cEffModules[aPXDModule]->Modified();
324 m_cEffModules[aPXDModule]->Update();
325 UpdateCanvas(m_cEffModules[aPXDModule]);
326
327 auto h = m_eEffModules[aPXDModule]->GetPaintedHistogram();
328 int s = (2 - aPXDModule.getSensorNumber()) * m_v_bins;
329 int l = (aPXDModule.getLadderNumber() - 1) * m_u_bins;
330 if (m_hInnerMap && aPXDModule.getLayerNumber() == 1) {
331 updateinner = true;
332 for (int u = 0; u < m_u_bins; u++) {
333 for (int v = 0; v < m_v_bins; v++) {
334 auto b = h->GetBin(u + 1, v + 1);
335 m_hInnerMap->Fill(u + l, v + s, h->GetBinContent(b));
336 }
337 }
338 }
339 if (m_hOuterMap && aPXDModule.getLayerNumber() == 2) {
340 updateouter = true;
341 for (int u = 0; u < m_u_bins; u++) {
342 for (int v = 0; v < m_v_bins; v++) {
343 auto b = h->GetBin(u + 1, v + 1);
344 m_hOuterMap->Fill(u + l, v + s, h->GetBinContent(b));
345 }
346 }
347 }
348 }
349 } else {
350 B2WARNING("only one plot upd " << aPXDModule);
351 }
352 }
353 // Single-Module histos + 2d overview finished. now draw overviews
354 if (updateinner) {
355 m_cInnerMap->cd();
356 if (m_hInnerMap) m_hInnerMap->Draw("colz");
357 m_cInnerMap->Modified();
358 m_cInnerMap->Update();
360 }
361 if (updateouter) {
362 m_cOuterMap->cd();
363 if (m_hOuterMap) m_hOuterMap->Draw("colz");
364 m_cOuterMap->Modified();
365 m_cOuterMap->Update();
367 }
368 // 3d overview done
369 }
370
371
372// Now, calculate and update efficiency.
373// Only histogram is used for numerator AND denominatorto to have an atomic update.
374// (avoid possible update glitches from daq/dqm framework side)
375// The bins per module are read out and filled into an TEfficiency as total and passed events into bin
376// Summaries for L1, L2, Overall are added, too
377 auto Combined = findHist(m_histogramDirectoryName, "PXD_Eff_combined", true);// only if updated
378
379 if (Combined) {
380 // only if histogram was changed
381
382 EStatus stat_data = c_StatusTooFew;
383 bool error_flag = false;
384 bool warn_flag = false;
385 double all = 0.0;
386
387 double imatch = 0.0, ihit = 0.0;
388 double imatchL1 = 0.0, ihitL1 = 0.0;
389 double imatchL2 = 0.0, ihitL2 = 0.0;
390 int ieff = 0; // count number of modules with useful stytistics
391
392 std::map <VxdID, bool> updated{}; // init to false, keep track of updated histograms
393 for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
394 // workaround for excluded module
395 if (std::find(m_excluded.begin(), m_excluded.end(), i) != m_excluded.end()) continue;
396 // excluded modules are not counted at all!
397 int bin = i + 1; // bin nr is index +1
398
399 const VxdID& aModule = m_PXDModules[i];
400 double nmatch = Combined->GetBinContent(i * 2 + 2);
401 double nhit = Combined->GetBinContent(i * 2 + 1);
402
403 imatch += nmatch;
404 ihit += nhit;
405 // check layer
406 if (i >= 16) {
407 imatchL2 += nmatch;
408 ihitL2 += nhit;
409 } else {
410 imatchL1 += nmatch;
411 ihitL1 += nhit;
412 }
413
414 if (nhit >= m_minEntries) { // dont update if there is nothing to calculate
415 ieff++; // only count in modules with significant stat
416 double var_e = nmatch / nhit; // can never be zero
417 m_monObj->setVariable(Form("efficiency_%d_%d_%d", aModule.getLayerNumber(), aModule.getLadderNumber(), aModule.getSensorNumber()),
418 var_e);
419 }
420
422 all += nhit;
423
424 updated[aModule] = updateEffBins(bin, nhit, nmatch, m_minEntries);
425
426 // workaround for excluded module
427 if (std::find(m_excluded.begin(), m_excluded.end(), i) != m_excluded.end()) continue;
428
429 // get the errors and check for limits for each bin separately ...
430
431 if (nhit >= m_minEntries) {
432 error_flag |= check_error_level(bin, aModule);
433 warn_flag |= check_warn_level(bin, aModule);
434 }
435 }
436
437 updateEffBins(m_PXDModules.size() + 1, ihitL1, imatchL1, m_minEntries * 8);
438 if (ihitL1 >= m_minEntries) {
439 error_flag |= check_error_level(m_PXDModules.size() + 1, "L1");
440 warn_flag |= check_warn_level(m_PXDModules.size() + 1, "L1");
441 }
442 updateEffBins(m_PXDModules.size() + 2, ihitL2, imatchL2, m_minEntries * 12);
443 if (ihitL2 >= m_minEntries) {
444 error_flag |= check_error_level(m_PXDModules.size() + 2, "L2");
445 warn_flag |= check_warn_level(m_PXDModules.size() + 2, "L2");
446 }
447 updateEffBins(m_PXDModules.size() + 3, ihit, imatch, m_minEntries * 20);
448 if (ihit >= m_minEntries) {
449 error_flag |= check_error_level(m_PXDModules.size() + 3, "All");
450 warn_flag |= check_warn_level(m_PXDModules.size() + 3, "All");
451 }
452
453 {
454 m_cEffAll->cd();
455 m_cEffAll->cd(0);
456 m_eEffAll->Paint("AP");
457 m_cEffAll->Clear();
458 m_cEffAll->cd(0);
459
460 auto gr = m_eEffAll->GetPaintedGraph();
461 if (gr) {
462 double scale_min = 1.0;
463 for (int i = 0; i < gr->GetN(); i++) {
464 gr->SetPointEXhigh(i, 0.);
465 gr->SetPointEXlow(i, 0.);
466 // this has to be done first, as it will recalc Min/Max and destroy axis
467 Double_t x, y;
468 gr->GetPoint(i, x, y);
469 gr->SetPoint(i, x - 0.01, y); // workaround for jsroot bug (fixed upstream)
470 auto val = y - gr->GetErrorYlow(i); // Error is relative to value
471 if (std::find(m_excluded.begin(), m_excluded.end(), i) == m_excluded.end()) {
472 // scale update only for included module
473 if (scale_min > val) scale_min = val;
474 }
475 }
476 if (scale_min == 1.0) scale_min = 0.0;
477 if (scale_min > 0.9) scale_min = 0.9;
478 auto ay = gr->GetYaxis();
479 if (ay) ay->SetRangeUser(scale_min, 1.0);
480 setLabels(gr);
481
482 gr->SetLineColor(4);
483 gr->SetLineWidth(2);
484 gr->SetMarkerStyle(8);
485
486 gr->Draw("AP");
487
488 for (const auto& it : m_excluded) {
489 static std::map <int, TLatex*> ltmap;
490 auto tt = ltmap[it];
491 if (!tt) {
492 tt = new TLatex(it + 0.5, scale_min, (" " + std::string(m_PXDModules[it]) + " Module is excluded, please ignore").c_str());
493 tt->SetTextSize(0.035);
494 tt->SetTextAngle(90);// Rotated
495 tt->SetTextAlign(12);// Centered
496 ltmap[it] = tt;
497 } else {
498 tt->SetY(scale_min);
499 }
500 tt->Draw();
501 }
502
503
504 EStatus all_stat = makeStatus(all >= m_minEntries, warn_flag, error_flag);
505 colorizeCanvas(m_cEffAll, all_stat);
506
507 m_hWarnLine->Draw("same,hist");
508 m_hErrorLine->Draw("same,hist");
509 }
510
511 UpdateCanvas(m_cEffAll->GetName());
512 m_cEffAll->Modified();
513 m_cEffAll->Update();
514 }
515
516 {
517 m_cEffAllUpdate->cd();
518 m_eEffAllUpdate->Paint("AP");
519 m_cEffAllUpdate->Clear();
520 m_cEffAllUpdate->cd(0);
521
522 auto gr = m_eEffAllUpdate->GetPaintedGraph();
523 // A clone in next line would create a memory leak unless taken care of as member. No clone results in acceptable minor displayement of points
524 auto gr3 = dynamic_cast<TGraphAsymmErrors*>(m_eEffAll->GetPaintedGraph()); // ->Clone();
525 if (gr3) {
526 for (int i = 0; i < gr3->GetN(); i++) {
527 Double_t x, y;
528 gr3->GetPoint(i, x, y);
529 gr3->SetPoint(i, x + 0.2, y);
530 }
531 }
532
533 double scale_min = 1.0;
534 if (gr) {
535 for (int i = 0; i < gr->GetN(); i++) {
536 gr->SetPointEXhigh(i, 0.);
537 gr->SetPointEXlow(i, 0.);
538 // this has to be done first, as it will recalc Min/Max and destroy axis
539 Double_t x, y;
540 gr->GetPoint(i, x, y);
541 gr->SetPoint(i, x - 0.2, y); // shift a bit if in same plot
542 auto val = y - gr->GetErrorYlow(i); // Error is relative to value
543 if (std::find(m_excluded.begin(), m_excluded.end(), i) == m_excluded.end()) {
544 // skip scale update only for included modules
545 if (scale_min > val) scale_min = val;
546 }
547 }
548 if (scale_min == 1.0) scale_min = 0.0;
549 if (scale_min > 0.9) scale_min = 0.9;
550 auto ay = gr->GetYaxis();
551 if (ay) ay->SetRangeUser(scale_min, 1.0);
552 setLabels(gr);
553
554 for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
555 if (updated[m_PXDModules[i]]) {
556 // we should only write if it was updated!
557 Double_t x, y;// we assume that double and Double_t are same!
558 gr->GetPoint(i, x, y);
559 setEpicsPV((std::string)m_PXDModules[i], y);
560 }
561 }
562
563 gr->SetLineColor(kBlack);
564 gr->SetLineWidth(3);
565 gr->SetMarkerStyle(33);
566 gr->Draw("AP");
567 } else scale_min = 0.0;
568 if (gr3) gr3->Draw("P"); // both in one plot
569
570 for (const auto& it : m_excluded) {
571 static std::map <int, TLatex*> ltmap;
572 auto tt = ltmap[it];
573 if (!tt) {
574 tt = new TLatex(it + 0.5, scale_min, (" " + std::string(m_PXDModules[it]) + " Module is excluded, please ignore").c_str());
575 tt->SetTextSize(0.035);
576 tt->SetTextAngle(90);// Rotated
577 tt->SetTextAlign(12);// Centered
578 ltmap[it] = tt;
579 } else {
580 tt->SetY(scale_min);
581 }
582 tt->Draw();
583 }
584
585 stat_data = makeStatus(all >= m_minEntries, warn_flag, error_flag);
587
588 m_hWarnLine->Draw("same,hist");
589 m_hErrorLine->Draw("same,hist");
590 }
591 UpdateCanvas(m_cEffAllUpdate->GetName());
592 m_cEffAllUpdate->Modified();
593 m_cEffAllUpdate->Update();
594
595 double var_efficiency = ihit > 0 ? imatch / ihit : 0.0;
596 double var_efficiencyL1 = ihitL1 > 0 ? imatchL1 / ihitL1 : 0.0;
597 double var_efficiencyL2 = ihitL2 > 0 ? imatchL2 / ihitL2 : 0.0;
598
599 m_monObj->setVariable("efficiency", var_efficiency);
600 m_monObj->setVariable("efficiencyL1", var_efficiencyL1);
601 m_monObj->setVariable("efficiencyL2", var_efficiencyL2);
602 m_monObj->setVariable("nmodules", ieff);
603
604 setEpicsPV("Status", stat_data);
605 // only update if statistics is reasonable, we dont want "0" drops between runs!
606 if (stat_data != c_StatusTooFew) {
607 setEpicsPV("All", var_efficiency);
608 setEpicsPV("L1", var_efficiencyL1);
609 setEpicsPV("L2", var_efficiencyL2);
610 }
611 }
612}
613
615{
616 B2DEBUG(1, "DQMHistAnalysisPXDEff: terminate called");
617
618 for (const auto& aPXDModule : m_PXDModules) {
619 if (m_cEffModules[aPXDModule]) delete m_cEffModules[aPXDModule];
620 if (m_eEffModules[aPXDModule]) delete m_eEffModules[aPXDModule];
621 }
622
625
626 if (m_cInnerMap) delete m_cInnerMap;
627 if (m_cOuterMap) delete m_cOuterMap;
628 if (m_hInnerMap) delete m_hInnerMap;
629 if (m_hOuterMap) delete m_hOuterMap;
630
631 if (m_hErrorLine) delete m_hErrorLine;
632 if (m_hWarnLine) delete m_hWarnLine;
633
634 if (m_cEffAll) delete m_cEffAll;
635 if (m_eEffAll) delete m_eEffAll;
636
639}
640
int registerEpicsPV(const std::string &pvname, const std::string &keyname="")
EPICS related Functions.
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
static void colorizeCanvas(TCanvas *canvas, EStatus status)
Helper function for Canvas colorization.
static void UpdateCanvas(const std::string &name, bool updated=true)
Mark canvas as updated (or not)
DQMHistAnalysisModule()
Constructor / Destructor.
EStatus
Status flag of histogram/canvas.
@ c_StatusTooFew
Not enough entries/event to judge.
static EStatus makeStatus(bool enough, bool warn_flag, bool error_flag)
Helper function to judge the status for coloring and EPICS.
bool requestLimitsFromEpicsPVs(chid id, double &lowerAlarm, double &lowerWarn, double &upperWarn, double &upperAlarm)
Get Alarm Limits from EPICS PV.
void setEpicsPV(const std::string &keyname, double value)
Write value to a EPICS PV.
static TH1 * findHist(const std::string &dirname, const std::string &histname="", bool onlyIfUpdated=false)
Find histogram.
TCanvas * m_cOuterMap
Full Eff Map Outer Layer.
TCanvas * m_cInnerMap
Full Eff Map Inner Layer.
void terminate(void) override final
This method is called at the end of the event processing.
std::map< VxdID, TEfficiency * > m_eEffModules
Individual efficiency for each module, 2d histogram.
bool m_perModuleAlarm
use alarm level per module
std::map< VxdID, TCanvas * > m_cEffModules
Individual efficiency for each module, canvas.
void initialize(void) override final
Initializer.
int m_nrxbins
Number of bins in efficiency plot, all modules plus layer and summary.
TH1 * m_hEffAllLastTotal
TH1, last state, total.
TH1 * m_hEffAllLastPassed
TH1, last state, passed.
TH2F * m_hOuterMap
Full Eff Map Outer Layer.
bool check_warn_level(int bin, const std::string &name)
Check bin/name for warn condition.
void setLabels(TGraphAsymmErrors *gr)
Set module labels for TGraphAsymmErrors.
TEfficiency * m_eEffAll
One bin for each module in the geometry.
MonitoringObject * m_monObj
Monitoring Object.
bool check_error_level(int bin, const std::string &name)
Check bin/name for error condition.
std::vector< VxdID > m_PXDModules
IDs of all PXD Modules to iterate over.
std::string m_histogramDirectoryName
name of histogram directory
TCanvas * m_cEffAllUpdate
Final Canvas for Update.
TH2F * m_hInnerMap
Full Eff Map Inner Layer.
double m_confidence
confidence level for error bars
std::map< std::string, double > m_warnlevelmod
warn level for alarm per module
TEfficiency * m_eEffAllUpdate
Efficiency, last state, updated.
TH1F * m_hWarnLine
TLine object for warning limit.
double m_errorlevel
error level for alarm
std::map< std::string, double > m_errorlevelmod
error level for alarm per module
TH1F * m_hErrorLine
TLine object for error error.
std::vector< int > m_excluded
Indizes of excluded PXD Modules.
bool m_alarmAdhoc
generate alarm from adhoc values
bool updateEffBins(int bin, int nhit, int nmatch, int minentries)
Update bin in efficiency plots with condition on nhits.
void beginRun(void) override final
Called when entering a new run.
void event(void) override final
This method is called for each event.
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Class to facilitate easy access to sensor information of the VXD like coordinate transformations or p...
Definition GeoCache.h:38
const std::vector< VxdID > getListOfSensors() const
Get list of all sensors.
Definition GeoCache.cc:59
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a reference to the SensorInfo of a given SensorID.
Definition GeoCache.cc:67
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition GeoCache.cc:214
Base class to provide Sensor Information for PXD and SVD.
int getVCells() const
Return number of pixel/strips in v direction.
int getUCells() const
Return number of pixel/strips in u direction.
Class to uniquely identify a any structure of the PXD and SVD.
Definition VxdID.h:32
baseType getSensorNumber() const
Get the sensor id.
Definition VxdID.h:99
baseType getLadderNumber() const
Get the ladder id.
Definition VxdID.h:97
baseType getLayerNumber() const
Get the layer id.
Definition VxdID.h:95
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
Abstract base class for different kinds of events.
STL namespace.