Belle II Software development
DQMHistAnalysisKLM2.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/* Own header. */
10#include <dqm/analysis/modules/DQMHistAnalysisKLM2.h>
11
12/* Basf2 headers. */
13#include <klm/dataobjects/KLMChannelIndex.h>
14
15/* ROOT headers. */
16#include <TROOT.h>
17#include <TStyle.h>
18#include <TColor.h>
19
20/* Standard Library*/
21#include <algorithm>
22
23using namespace Belle2;
24
25REG_MODULE(DQMHistAnalysisKLM2);
26
29 m_IsNullRun{false},
31{
32 setDescription("Module used to analyze KLM Efficiency DQM histograms (depends on tracking variables).");
33 addParam("HistogramDirectoryName", m_histogramDirectoryName, "Name of histogram directory", std::string("KLMEfficiencyDQM"));
34 addParam("RefHistogramDirectoryName", m_refHistogramDirectoryName, "Name of ref histogram directory",
35 std::string("KLMEfficiencyDQM"));
36 addParam("deltaEffStopThreshold", m_stopThr, "Set stop threshold", -0.50);
37 addParam("deltaEffAlarmThreshold", m_alarmThr, "Set alarm threshold", -0.15);
38 addParam("deltaEffWarnThreshold", m_warnThr, "Set warn threshold", -0.05);
39 addParam("zEffThreshold", m_zEffThreshold, "Set efficiency threshold for z-score calculation", 0.90);
40 addParam("ZThreshold", m_zThreshold, "Set Z-score threshold for inefficient layers ", -1.5);
41 addParam("ErrorThreshold", m_errorThreshold, "Set uncertainty threshold for low statistics", 0.05);
42 addParam("Min2DEff", m_min, "2D efficiency min", float(0.5));
43 addParam("Max2DEff", m_max, "2D efficiency max", float(2));
44 addParam("RatioPlot", m_ratio, "2D efficiency ratio or difference plot ", bool(true));
45 addParam("MinEntries", m_minEntries, "Minimum entries for delta histogram update", 35000.);
46
47 m_PlaneLine.SetLineColor(kMagenta);
48 m_PlaneLine.SetLineWidth(1);
49 m_PlaneLine.SetLineStyle(2); // dashed
50 m_PlaneText.SetTextAlign(22); // centered, middle
51 m_PlaneText.SetTextColor(kMagenta);
52 m_PlaneText.SetTextFont(42); // Helvetica regular
53 m_PlaneText.SetTextSize(0.02); // 2% of TPad's full height
54}
55
56
57
59{
61
62 //register EPICS PVs
63 registerEpicsPV("KLM:Eff:nEffBKLMLayers", "nEffBKLMLayers");
64 registerEpicsPV("KLM:Eff:nEffEKLMLayers", "nEffEKLMLayers");
65 registerEpicsPV("KLM:Eff:zEffThreshold", "zEffThreshold");
66 registerEpicsPV("KLM:Eff:zScoreThreshold", "zScoreThreshold");
67 registerEpicsPV("KLM:Eff:uncertaintyThreshold", "uncertaintyThreshold");
68 registerEpicsPV("KLM:Eff:minEntriesThreshold", "minEntriesThreshold");
69 registerEpicsPV("KLM:Eff:deltaEffThreshold", "deltaEffThreshold");
70 registerEpicsPV("KLM:EFF:deltaEffStopThreshold", "deltaEffStopThreshold");
71
72 gROOT->cd();
73 m_c_eff_bklm = new TCanvas((m_histogramDirectoryName + "/c_eff_bklm_plane").data());
74 m_c_eff_eklm = new TCanvas((m_histogramDirectoryName + "/c_eff_eklm_plane").data());
75 m_c_eff_bklm_sector = new TCanvas((m_histogramDirectoryName + "/c_eff_bklm_sector").data());
76 m_c_eff_eklm_sector = new TCanvas((m_histogramDirectoryName + "/c_eff_eklm_sector").data());
77
78 m_c_eff2d_bklm = new TCanvas((m_histogramDirectoryName + "/c_eff2d_bklm").data());
79 m_c_eff2d_eklm = new TCanvas((m_histogramDirectoryName + "/c_eff2d_eklm").data());
80
81 m_eff_bklm = new TH1F((m_histogramDirectoryName + "/eff_bklm_plane").data(),
82 "Plane Efficiency in BKLM",
84 m_eff_bklm->GetXaxis()->SetTitle("Layer number");
85 m_eff_bklm->SetStats(false);
86 m_eff_bklm->SetOption("HIST");
87
88 m_eff_eklm = new TH1F((m_histogramDirectoryName + "/eff_eklm_plane").data(),
89 "Plane Efficiency in EKLM",
91 m_eff_eklm->GetXaxis()->SetTitle("Plane number");
92 m_eff_eklm->SetStats(false);
93 m_eff_eklm->SetOption("HIST");
94
95 m_eff_bklm_sector = new TH1F((m_histogramDirectoryName + "/eff_bklm_sector").data(),
96 "Sector Efficiency in BKLM",
98 m_eff_bklm_sector->GetXaxis()->SetTitle("Sector number");
99 m_eff_bklm_sector->SetStats(false);
100 m_eff_bklm_sector->SetOption("HIST");
101
102 m_eff_eklm_sector = new TH1F((m_histogramDirectoryName + "/eff_eklm_sector").data(),
103 "Sector Efficiency in EKLM",
105 m_eff_eklm_sector->GetXaxis()->SetTitle("Sector number");
106 m_eff_eklm_sector->SetStats(false);
107 m_eff_eklm_sector->SetOption("HIST");
108
109 /* register plots for delta histogramming */
110 // all ext hits
111 addDeltaPar(m_histogramDirectoryName, "all_ext_hitsBKLM", HistDelta::c_Entries, m_minEntries, 1);
112 addDeltaPar(m_histogramDirectoryName, "all_ext_hitsEKLM", HistDelta::c_Entries, m_minEntries, 1);
113 addDeltaPar(m_histogramDirectoryName, "all_ext_hitsBKLMSector", HistDelta::c_Entries, m_minEntries, 1);
114 addDeltaPar(m_histogramDirectoryName, "all_ext_hitsEKLMSector", HistDelta::c_Entries, m_minEntries, 1);
115
116 // matched hits
117 addDeltaPar(m_histogramDirectoryName, "matched_hitsBKLM", HistDelta::c_Entries, m_minEntries, 1);
118 addDeltaPar(m_histogramDirectoryName, "matched_hitsEKLM", HistDelta::c_Entries, m_minEntries, 1);
119 addDeltaPar(m_histogramDirectoryName, "matched_hitsBKLMSector", HistDelta::c_Entries, m_minEntries, 1);
120 addDeltaPar(m_histogramDirectoryName, "matched_hitsEKLMSector", HistDelta::c_Entries, m_minEntries, 1);
121
122 // 2D Efficiency Histograms
123 TString eff2d_hist_bklm_title;
124 TString eff2d_hist_eklm_title;
125 if (m_ratio) {
126 eff2d_hist_bklm_title = "Plane Efficiency Ratios in BKLM";
127 eff2d_hist_eklm_title = "Plane Efficiency Ratios in EKLM";
128 } else {
129 eff2d_hist_bklm_title = "Plane Efficiency Diffs in BKLM";
130 eff2d_hist_eklm_title = "Plane Efficiency Diffs in EKLM";
131 }
132
133 // BKLM
134 m_eff2d_bklm = new TH2F((m_histogramDirectoryName + "/eff2d_bklm_sector").data(), eff2d_hist_bklm_title,
137 m_eff2d_bklm->GetXaxis()->SetTitle("Sector");
138 m_eff2d_bklm->GetYaxis()->SetTitle("Layer");
139 m_eff2d_bklm->SetStats(false);
140
141 m_err_bklm = new TH2F((m_histogramDirectoryName + "/err_bklm_sector").data(), eff2d_hist_bklm_title,
144 m_err_bklm->GetXaxis()->SetTitle("Sector");
145 m_err_bklm->GetYaxis()->SetTitle("Layer");
146 m_err_bklm->SetStats(false);
147
148 for (int sec_id = 0; sec_id < BKLMElementNumbers::getMaximalSectorNumber(); sec_id++) {
149 std::string BB_sec = "BB" + std::to_string(sec_id);
150 m_eff2d_bklm->GetXaxis()->SetBinLabel(sec_id + 1, BB_sec.c_str());
151
152 std::string BF_sec = "BF" + std::to_string(sec_id);
153 m_eff2d_bklm->GetXaxis()->SetBinLabel(BKLMElementNumbers::getMaximalSectorNumber() + sec_id + 1, BF_sec.c_str());
154 }
155
156 for (int lay_id = 0; lay_id < BKLMElementNumbers::getMaximalLayerNumber(); lay_id++) {
157 std::string B_lay = std::to_string(lay_id);
158 m_eff2d_bklm->GetYaxis()->SetBinLabel(lay_id + 1, B_lay.c_str());
159 }
160
161 // EKLM
163
164 m_eff2d_eklm = new TH2F((m_histogramDirectoryName + "/eff2d_eklm_sector").data(), eff2d_hist_eklm_title,
165 n_sectors_eklm, 0.5, n_sectors_eklm + 0.5,
167 m_eff2d_eklm->GetXaxis()->SetTitle("Layer");
168 m_eff2d_eklm->GetYaxis()->SetTitle("Sector");
169 m_eff2d_eklm->SetStats(false);
170
171 m_err_eklm = new TH2F((m_histogramDirectoryName + "/err_eklm_sector").data(), eff2d_hist_eklm_title,
172 n_sectors_eklm, 0.5, n_sectors_eklm + 0.5,
174 m_err_eklm->GetXaxis()->SetTitle("Layer");
175 m_err_eklm->GetYaxis()->SetTitle("Sector");
176 m_err_eklm->SetStats(false);
177
178 std::string name;
179 const double maximalLayer = EKLMElementNumbers::getMaximalLayerGlobalNumber();
180 for (int layerGlobal = 1; layerGlobal <= maximalLayer; ++layerGlobal) {
181 int section, layer;
182 m_EklmElementNumbers->layerNumberToElementNumbers(
183 layerGlobal, &section, &layer);
185 name = "B";
186 else
187 name = "F";
188 name += std::to_string(layer);
189 m_eff2d_eklm->GetXaxis()->SetBinLabel(layerGlobal, name.c_str());
190 }
191
192 for (int lay_id = 0; lay_id < EKLMElementNumbers::getMaximalSectorGlobalNumberKLMOrder(); lay_id++) {
193 std::string E_lay = std::to_string(lay_id);
194 m_eff2d_eklm->GetYaxis()->SetBinLabel(lay_id + 1, E_lay.c_str());
195 }
196
197
198}
199
200void DQMHistAnalysisKLM2Module::initialize2DRefHistogram(TH1*& hist, const std::string& histName, const std::string& title,
201 int maxLayer)
202{
203 // Get reference histogram using the base class method
205
206 if (hist) {
207 B2INFO("DQMHistAnalysisKLM2: " + histName + " histogram was found in reference");
208 hist->SetLineColor(2);
209 hist->SetOption("HIST");
210 hist->SetStats(false);
211 } else {
212 B2WARNING("DQMHistAnalysisKLM2: " + histName + " histogram not found in reference");
213 hist = new TH1F(histName.c_str(), title.c_str(), maxLayer, 0.5, 0.5 + maxLayer);
214 for (int lay_id = 0; lay_id < maxLayer; lay_id++) {
215 hist->SetBinContent(lay_id + 1, m_ratio ? 1 : 0);
216 }
217 }
218}
219
221{
222 m_IsPhysicsRun = (getRunType() == "physics");
223 m_IsNullRun = (getRunType() == "null");
224
225 // Initialize reference histograms for 2D efficiency plots
226 initialize2DRefHistogram(m_ref_efficiencies_bklm, "eff_bklm_plane", "Plane Efficiency in BKLM",
228
229 initialize2DRefHistogram(m_ref_efficiencies_eklm, "eff_eklm_plane", "Plane Efficiency in EKLM",
231
232 double unused = NAN;
233 //ratio/diff mode should only be possible if references exist
234 // default values should be initially defined in input parameters
235 requestLimitsFromEpicsPVs("zScoreThreshold", unused, m_zThreshold, unused, unused);
236 requestLimitsFromEpicsPVs("zEffThreshold", unused, m_zEffThreshold, unused, unused);
237 requestLimitsFromEpicsPVs("uncertaintyThreshold", unused, unused, m_errorThreshold, unused);
238 requestLimitsFromEpicsPVs("minEntriesThreshold", unused, m_minEntries, unused, unused);
239
240 requestLimitsFromEpicsPVs("deltaEffThreshold", m_alarmThr, m_warnThr, unused,
241 unused); // lower warn/alarm thresholds for delta efficiency
242 requestLimitsFromEpicsPVs("deltaEffStopThreshold", m_stopThr, unused, unused,
243 unused); // lower stop-alarm threshold for delta efficiency
246 requestLimitsFromEpicsPVs("nEffBKLMLayers", unused, unused, unused, m_BKLMLayerAlarm);
247 requestLimitsFromEpicsPVs("nEffEKLMLayers", unused, unused, unused, m_EKLMLayerAlarm);
248
249}
250
252{
253 std::string name;
254
255 int bklmMaxLayer = BKLMElementNumbers::getMaximalLayerNumber();//15
256 int bklmMaxSector = BKLMElementNumbers::getMaximalSectorNumber();//8
257
259 int eklmLocalMaxSector = EKLMElementNumbers::getMaximalSectorNumber();//4
260 int eklmBLayerCount = m_EklmElementNumbers->getMaximalDetectorLayerNumber(EKLMElementNumbers::c_BackwardSection);//12
261
262 // Looping over the sectors
263 for (int bin = 0; bin < m_eff_bklm_sector->GetXaxis()->GetNbins(); bin++) {
264 name = "eff_B";
265 if (bin < bklmMaxSector)
266 name += "B";
267 else
268 name += "F";
269 name += std::to_string(bin % bklmMaxSector);
270 m_monObj->setVariable(name, m_eff_bklm_sector->GetBinContent(bin + 1));
271 }
272
273 for (int bin = 0; bin < m_eff_eklm_sector->GetXaxis()->GetNbins(); bin++) {
274 name = "eff_E";
275 if (bin < eklmLocalMaxSector) //(bin < 4)
276 name += "B";
277 else
278 name += "F";
279 name += std::to_string(bin % eklmLocalMaxSector);
280 m_monObj->setVariable(name, m_eff_eklm_sector->GetBinContent(bin + 1));
281 }
282
283 // Looping over the planes
284 for (int layer = 0; layer < m_eff_bklm->GetXaxis()->GetNbins(); layer++) {
285 name = "eff_B";
286 //layer/15 < 8
287 if (layer / bklmMaxLayer < bklmMaxSector) {
288 name += "B";
289 } else {
290 name += "F";
291 }
292 name += std::to_string(int(layer / bklmMaxLayer) % bklmMaxSector) + "_layer" + std::to_string(1 + (layer % bklmMaxLayer));
293 m_monObj->setVariable(name, m_eff_bklm->GetBinContent(layer + 1));
294 }
295 for (int layer = 0; layer < m_eff_eklm->GetXaxis()->GetNbins(); layer++) {
296 name = "eff_E";
297 if (layer / eklmGlobalMaxSector < eklmBLayerCount) //(layer/8 < 12)
298 name += "B" + std::to_string(layer / eklmGlobalMaxSector + 1);
299 else
300 name += "F" + std::to_string(layer / eklmGlobalMaxSector - eklmBLayerCount + 1);
301 name += + "_num" + std::to_string(((layer) % eklmGlobalMaxSector) + 1);
302 m_monObj->setVariable(name, m_eff_eklm->GetBinContent(layer + 1));
303
304 }
305}
306
307void DQMHistAnalysisKLM2Module::processEfficiencyHistogram(TH1* effHist, TH1* denominator, TH1* numerator, TCanvas* canvas)
308{
309 effHist->Reset();
310 std::unique_ptr<TH1> effClone(static_cast<TH1*>
311 (effHist->Clone())); // Clone effHist, will be useful for delta plots & Smart pointer will manage memory leak
312 canvas->cd();
313 if (denominator != nullptr && numerator != nullptr) {
314 effHist->Divide(numerator, denominator, 1, 1, "B");
315 effHist->Draw();
316
317 //reference check
318 TH1* ref = findRefHist(effHist->GetName(), ERefScaling::c_RefScaleNone);
319 if (ref) {ref->Draw("hist,same");}
320
321 canvas->Modified();
322 canvas->Update();
323
324 /* delta component */
325 auto deltaDenom = getDelta("", denominator->GetName());
326 auto deltaNumer = getDelta("", numerator->GetName());
327
328 // both histograms should have the same update condition but checking both should be okay?
329 // if this condition is not satisfied, does it cause the above to not ever update?
330 // after test campaign, switch condition back to (deltaNumer != nullptr && deltaDenom != nullptr)
331 UpdateCanvas(canvas->GetName(), (effHist != nullptr));
332 if ((deltaNumer != nullptr) && (deltaDenom != nullptr)) {
333 B2INFO("DQMHistAnalysisKLM2: Eff Delta Num/Denom Entries is " << deltaNumer->GetEntries() << "/" << deltaDenom->GetEntries());
334 effClone->Divide(deltaNumer, deltaDenom, 1, 1, "B");
335 effClone->SetLineColor(kOrange);
336 effClone->DrawCopy("SAME"); // managed by ROOT, so it helps in plotting even if obj deleted by smart pointer
337 canvas->Modified();
338 canvas->Update();
339 }
340 }
341}
342
344 const std::string& histName, TH1* histogram)
345{
346 std::string name;
347 TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
348 if (canvas == NULL) {
349 B2WARNING("KLMDQM2 histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
350 return;
351 } else {
352 canvas->cd();
353 histogram->SetStats(false);
354 double histMin = gPad->GetUymin();
355 double histMax = gPad->GetUymax();
356 double histRange = histMax - histMin;
357 if (histName.find("bklm") != std::string::npos) {
358 /* First draw the vertical lines and the sector names. */
359 const int maximalLayer = BKLMElementNumbers::getMaximalLayerNumber();
360 for (int sector = 0; sector < BKLMElementNumbers::getMaximalSectorGlobalNumber(); ++sector) {
361 int bin = maximalLayer * sector + 1;
362 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
363 double xText = histogram->GetXaxis()->GetBinLowEdge(bin + maximalLayer / 2);
364 double yText = histMin + 0.98 * histRange;
365 if (sector > 0)
366 m_PlaneLine.DrawLine(xLine, histMin, xLine, histMin + histRange);
367 name = "B";
369 name += "B";
370 else
371 name += "F";
372 name += std::to_string(sector % BKLMElementNumbers::getMaximalSectorNumber());
373 m_PlaneText.DrawText(xText, yText, name.c_str());
374 }
375
376 } else {
377 /* First draw the vertical lines and the sector names. */
378 const double maximalLayer = EKLMElementNumbers::getMaximalLayerGlobalNumber();
380 for (int layerGlobal = 1; layerGlobal <= maximalLayer; ++layerGlobal) {
381 int bin = maxPlane * layerGlobal + 1;
382 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
383 double xText = histogram->GetXaxis()->GetBinLowEdge(bin - maxPlane / 2);
384 double yText = histMin + 0.98 * histRange;
385 if (layerGlobal < maximalLayer)
386 m_PlaneLine.DrawLine(xLine, histMin, xLine, histMin + histRange);
387 int section, layer;
388 m_EklmElementNumbers->layerNumberToElementNumbers(
389 layerGlobal, &section, &layer);
391 name = "B";
392 else
393 name = "F";
394 name += std::to_string(layer);
395 m_PlaneText.DrawText(xText, yText, name.c_str());
396 }
397 }
398 canvas->Modified();
399 canvas->Update();
400 }
401}
402
404 TH1* mainHist, TH1* refHist, TH2* eff2dHist, TH2* errHist, int layers, int sectors, bool ratioPlot,
405 int& pvcount, double layerLimit, TCanvas* eff2dCanv)
406{
407
408 int i = 0;
409 float mainEff;
410 float refEff;
411 float mainErr;
412 float refErr;
413 float maxVal = m_max;
414 float minVal = m_min;
415 float eff2dVal;
416 bool setAlarm = false;
417 bool setWarn = false;
418 bool setFew = false;
419 int mainEntries;
420 int layercount = 0;
421
422 errHist->Reset(); // Reset histogram
423
424 pvcount = 0; // Initialize to zero
425 mainEntries = mainHist->GetEntries();
426
427 for (int binx = 0; binx < sectors; binx++) {
428
429 for (int biny = 0; biny < layers; biny++) {
430
431 mainEff = mainHist->GetBinContent(i + 1);
432 mainErr = mainHist->GetBinError(i + 1);
433 if (refHist) {
434 refEff = refHist->GetBinContent(i + 1);
435 refErr = refHist->GetBinError(i + 1);
436 } else {
437 refEff = 0.;
438 refErr = 0.;
439 }
440
441 if ((mainEff == 0.) and (refEff == 0.)) {
442 // empty histograms, draw blank bin
443 eff2dHist->SetBinContent(binx + 1, biny + 1, 0.);
444 } else if ((refEff == 0.) and (ratioPlot)) {
445 // no reference, set maximum value
446 eff2dHist->SetBinContent(binx + 1, biny + 1, maxVal);
447 } else if (mainEff == 0.) {
448 // no data, set zero
449 eff2dHist->SetBinContent(binx + 1, biny + 1, 0.);
450 errHist->SetBinContent(binx + 1, biny + 1, 0.);
451 } else {
452 double sigmaR = 0.0;
453 double Z = 0.0;
454 double deltaR = 0.0;
455 if (ratioPlot) {
456 eff2dVal = mainEff / refEff;
457 // Calculate uncertainty on the ratio
458 sigmaR = eff2dVal * sqrt(pow(mainErr / mainEff, 2) + pow(refErr / refEff, 2));
459
460 // Z-score: how many sigma is the ratio from the threshold
461 if (sigmaR > 0) {
462 deltaR = eff2dVal - m_zEffThreshold;
463 Z = deltaR / sigmaR; // ideal-case w'd be effThr is 1, so Z = (R - 1) / sigmaR
464 }
465 } else {
466 sigmaR = pow(pow(mainErr, 2) + pow(refErr, 2), 0.5);
467 eff2dVal = (mainEff - refEff);
468 deltaR = eff2dVal;
469 Z = eff2dVal / sigmaR;
470 }
471
472 // main histogram
473 if ((eff2dVal > minVal) and (eff2dVal < maxVal)) {
474 // value within display window
475 eff2dHist->SetBinContent(binx + 1, biny + 1, eff2dVal);
476 } else if (eff2dVal > maxVal) {
477 // value above display window
478 eff2dHist->SetBinContent(binx + 1, biny + 1, maxVal);
479 } else if (eff2dVal < minVal) {
480 // value below display window
481 eff2dHist->SetBinContent(binx + 1, biny + 1, minVal);
482 }
483
484 // set alarm
485 if (mainEntries < (int)m_minEntries) {
486 setFew = true;
487 } else if (ratioPlot && sigmaR / eff2dVal > m_errorThreshold) {
488 // For ratio mode: relative uncertainty
489 setFew = true;
490 errHist->SetBinContent(binx + 1, biny + 1, sigmaR);
491 } else if (!ratioPlot && sigmaR > m_errorThreshold) {
492 // For difference mode: absolute uncertainty
493 setFew = true;
494 errHist->SetBinContent(binx + 1, biny + 1, sigmaR);
495 } else {
496 if (deltaR < m_warnThr && Z < m_zThreshold) {
497 pvcount += 1;
498 errHist->SetBinContent(binx + 1, biny + 1, sigmaR);
499 if ((deltaR <= m_alarmThr) && (deltaR >= m_stopThr)) {
500 setWarn = true;
501 layercount++; // Increment layercount when alarm condition is met
502 } else if (deltaR < m_stopThr) {
503 setAlarm = true;
504 layercount++; // Increment layercount when a stop condition is met
505 }
506 }
507 }
508
509 }
510 i++;
511 }//end of bin y
512
513 }//end of bin x
514
515 if ((pvcount - layercount) > (int) layerLimit) {
516 setWarn = true;
517 }
518 if (layercount > (int) layerLimit) {
519 setAlarm = true;
520 }
521
522 eff2dHist->SetMinimum(minVal);
523 eff2dHist->SetMaximum(maxVal);
524
525 eff2dCanv->cd();
526 eff2dHist->Draw("COLZ");
527 errHist->Draw("TEXT SAME");
528 if (setFew) {
529 colorizeCanvas(eff2dCanv, c_StatusTooFew);
530 } else if (setAlarm) {
531 colorizeCanvas(eff2dCanv, c_StatusError);
532 } else if (setWarn) {
534 } else {
535 colorizeCanvas(eff2dCanv, c_StatusGood);
536 }
537 eff2dCanv->Modified();
538 eff2dCanv->Update();
539}
540
542{
543 /* If KLM is not included, stop here and return. */
544 TH1* daqInclusion = findHist("KLM/daq_inclusion");
545 if (not(daqInclusion == NULL)) {
546 int isKlmIncluded = daqInclusion->GetBinContent(daqInclusion->GetXaxis()->FindBin("Yes"));
547 if (isKlmIncluded == 0)
548 return;
549 }
550
551
552 /* Obtain plots necessary for efficiency plots */
553 TH1F* all_ext_bklm = (TH1F*)findHist(m_histogramDirectoryName + "/all_ext_hitsBKLM");
554 TH1F* matched_hits_bklm = (TH1F*)findHist(m_histogramDirectoryName + "/matched_hitsBKLM");
555
556 TH1F* all_ext_eklm = (TH1F*)findHist(m_histogramDirectoryName + "/all_ext_hitsEKLM");
557 TH1F* matched_hits_eklm = (TH1F*)findHist(m_histogramDirectoryName + "/matched_hitsEKLM");
558
559
560 TH1F* all_ext_bklm_sector = (TH1F*)findHist(m_histogramDirectoryName + "/all_ext_hitsBKLMSector");
561 TH1F* matched_hits_bklm_sector = (TH1F*)findHist(m_histogramDirectoryName + "/matched_hitsBKLMSector");
562
563 TH1F* all_ext_eklm_sector = (TH1F*)findHist(m_histogramDirectoryName + "/all_ext_hitsEKLMSector");
564 TH1F* matched_hits_eklm_sector = (TH1F*)findHist(m_histogramDirectoryName + "/matched_hitsEKLMSector");
565
566 /* Check if efficiency histograms exist*/
567 if ((all_ext_bklm == nullptr || matched_hits_bklm == nullptr) && (m_IsPhysicsRun)) {
568 B2INFO("Histograms needed for BKLM plane efficiency computation are not found");
569 }
570
571 if ((all_ext_eklm == nullptr || matched_hits_eklm == nullptr) && (m_IsPhysicsRun)) {
572 B2INFO("Histograms needed for EKLM plane efficiency computation are not found");
573 }
574 if ((all_ext_bklm_sector == nullptr || matched_hits_bklm_sector == nullptr) && (m_IsPhysicsRun)) {
575 B2INFO("Histograms needed for BKLM sector efficiency computation are not found");
576 }
577 if ((all_ext_eklm_sector == nullptr || matched_hits_eklm_sector == nullptr) && (m_IsPhysicsRun)) {
578 B2INFO("Histograms needed for EKLM sector efficiency computation are not found");
579 }
580
581
582 /* Draw histograms onto canvases*/
583 processEfficiencyHistogram(m_eff_bklm, all_ext_bklm, matched_hits_bklm, m_c_eff_bklm);
584 processEfficiencyHistogram(m_eff_eklm, all_ext_eklm, matched_hits_eklm, m_c_eff_eklm);
585
586 processEfficiencyHistogram(m_eff_bklm_sector, all_ext_bklm_sector, matched_hits_bklm_sector, m_c_eff_bklm_sector);
587 processEfficiencyHistogram(m_eff_eklm_sector, all_ext_eklm_sector, matched_hits_eklm_sector, m_c_eff_eklm_sector);
588
589 processPlaneHistogram("eff_bklm_plane", m_eff_bklm);
590 processPlaneHistogram("eff_eklm_plane", m_eff_eklm);
591
592 /* Make Diff 2D plots */
596
601 /* Set EPICS PV Values*/
602 B2DEBUG(20, "DQMHistAnalysisKLM2: Updating EPICS PVs");
603 // only update PVs if there's enough statistics and datasize != 0
604 // Check if it's a null run, if so, don't update EPICS PVs
605 if (m_IsNullRun) {
606 B2INFO("DQMHistAnalysisKLM2: Null run detected. No PV Update.");
607 return;
608 }
609 auto* daqDataSize = findHist("DAQ/KLMDataSize");
610 double meanDAQDataSize = 0.;
611 if (daqDataSize != nullptr) {
612 meanDAQDataSize = daqDataSize->GetMean();
613 B2INFO("DAQ/KLMDataSize's mean is " << meanDAQDataSize);
614 } else
615 B2WARNING("DQMHistAnalysisKLM2: Cannot find KLMDataSize");
616 if ((daqDataSize != nullptr) and (meanDAQDataSize != 0.)) {
617 int procesedEvents = DQMHistAnalysisModule::getEventProcessed();
618 if (procesedEvents > (int)m_minEntries) {
619 if (static_cast<int>(m_eff_bklm->GetEntries()) > (int)m_minEntries) {
620 setEpicsPV("nEffBKLMLayers", m_nEffBKLMLayers);
621 }
622 if (static_cast<int>(m_eff_eklm->GetEntries()) > (int)m_minEntries) {
623 setEpicsPV("nEffEKLMLayers", m_nEffEKLMLayers);
624 }
625 }
626 } else
627 B2INFO("DQMHistAnalysisKLM2: KLM Not included. No PV Update. ");
628
629}
static constexpr int getMaximalLayerGlobalNumber()
Get maximal layer global number.
static constexpr int getMaximalLayerNumber()
Get maximal layer number (1-based).
static constexpr int getMaximalSectorNumber()
Get maximal sector number (1-based).
static constexpr int getMaximalSectorGlobalNumber()
Get maximal sector global number.
TH1 * m_ref_efficiencies_bklm
BKLM efficiencies reference histogram.
TLine m_PlaneLine
TLine for boundary in plane histograms.
int m_nEffEKLMLayers
Number of inefficient EKLM Layers.
void initialize() override final
Initializer.
double m_stopThr
efficiency ratio (run-)stop threshold
TCanvas * m_c_eff2d_bklm
BKLM efficiencies ratio canvas.
std::string m_refHistogramDirectoryName
Name of histogram directory for reference file.
TCanvas * m_c_eff2d_eklm
EKLM efficiencies ratio canvas.
TH1 * m_eff_bklm_sector
Histogram for BKLM sector efficiency.
void processPlaneHistogram(const std::string &histName, TH1 *histogram)
Process histogram containing the number of hits in plane.
bool m_IsPhysicsRun
Run type flag for null runs.
double m_minEntries
Minimal number of entries for delta histogram and PV update.
double m_alarmThr
efficiency ratio alarm threshold
double m_zEffThreshold
efficiency threshold for z-score calculation
TH1 * m_eff_eklm
Histogram for EKLM plane efficiency.
void processEfficiencyHistogram(TH1 *effHist, TH1 *denominator, TH1 *numerator, TCanvas *canvas)
Process histogram containing the efficiencies.
TCanvas * m_c_eff_eklm_sector
Histogram for EKLM sector efficiency.
const EKLMElementNumbers * m_EklmElementNumbers
EKLM element numbers.
TH1 * m_eff_eklm_sector
Histogram for EKLM sector efficiency.
float m_max
efficiency ratio max z scale
MonitoringObject * m_monObj
Monitoring object.
TH1 * m_ref_efficiencies_eklm
ELM efficiencies reference histogram.
double m_errorThreshold
uncertainty threshold for low statistics
void event() override final
This method is called for each event.
void process2DEffHistogram(TH1 *mainHist, TH1 *refHist, TH2 *planeHist, TH2 *errHist, int layers, int sectors, bool ratioPlot, int &pvcount, double layerLimit, TCanvas *eff2dCanv)
Process 2D efficiency histograms.
TCanvas * m_c_eff_bklm_sector
Histogram for BKLM sector efficiency.
std::string m_histogramDirectoryName
Name of histogram directory.
TH2 * m_err_bklm
BKLM efficiencies error histogram.
float m_min
efficiency ratio min z scale
TH2 * m_eff2d_bklm
BKLM efficiencies 2dim histogram.
TH1 * m_eff_bklm
Histogram for BKLM plane efficiency.
TCanvas * m_c_eff_bklm
BKLM plane efficiency canvas.
TText m_PlaneText
TText for names in plane histograms.
TCanvas * m_c_eff_eklm
EKLM plane efficiency canvas.
void endRun() override final
This method is called if the current run ends.
double m_BKLMLayerAlarm
alarm limits from inefficient BKLM layers PV
void beginRun() override final
Called when entering a new run.
void initialize2DRefHistogram(TH1 *&hist, const std::string &histName, const std::string &title, int maxLayer)
Initialize a histogram by either finding a reference histogram or creating a new one.
double m_zThreshold
z-score threshold for inefficient layers
bool m_ratio
show efficiency ratio or difference
double m_EKLMLayerAlarm
alarm limits from inefficient EKLM layers PV
TH2 * m_err_eklm
EKLM efficiencies error histogram.
bool m_IsNullRun
Run type flag for null runs.
TH2 * m_eff2d_eklm
EKLM efficiencies 2dim histogram.
int m_nEffBKLMLayers
Number of inefficient BKLM layers.
double m_warnThr
efficiency ratio warning threshold
TCanvas * findCanvas(TString cname)
Find canvas by name.
static TH1 * findRefHist(const std::string &histname, ERefScaling scaling=ERefScaling::c_RefScaleNone, const TH1 *hist=nullptr)
Get referencehistogram from list (no other search).
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
void addDeltaPar(const std::string &dirname, const std::string &histname, HistDelta::EDeltaType t, int p, unsigned int a=1)
Add Delta histogram parameters.
void colorizeCanvas(TCanvas *canvas, EStatus status)
Helper function for Canvas colorization.
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
static const std::string & getRunType(void)
Get the list of the reference histograms.
TH1 * getDelta(const std::string &fullname, int n=0, bool onlyIfUpdated=true)
Get Delta histogram.
void setEpicsPV(std::string keyname, double value)
Write value to a EPICS PV.
DQMHistAnalysisModule()
Constructor / Destructor.
@ c_StatusTooFew
Not enough entries/event to judge.
@ c_StatusError
Analysis result: Severe issue found.
@ c_StatusWarning
Analysis result: Warning, there may be minor issues.
@ c_StatusGood
Analysis result: Good.
static int getEventProcessed(void)
Get the number of processed events.
int registerEpicsPV(std::string pvname, std::string keyname="")
EPICS related Functions.
void UpdateCanvas(std::string name, bool updated=true)
Mark canvas as updated (or not)
bool requestLimitsFromEpicsPVs(chid id, double &lowerAlarm, double &lowerWarn, double &upperWarn, double &upperAlarm)
Get Alarm Limits from EPICS PV.
static constexpr int getMaximalLayerGlobalNumber()
Get maximal detector layer global number.
static constexpr int getMaximalPlaneGlobalNumber()
Get maximal plane global number.
static constexpr int getMaximalSectorNumber()
Get maximal sector number.
static constexpr int getMaximalPlaneNumber()
Get maximal plane number.
static constexpr int getMaximalSectorGlobalNumberKLMOrder()
Get maximal sector global number with KLM ordering (section, sector).
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
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
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
Abstract base class for different kinds of events.