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
57{
59
60 //register EPICS PVs
61 registerEpicsPV("KLM:Eff:nEffBKLMLayers", "nEffBKLMLayers");
62 registerEpicsPV("KLM:Eff:nEffEKLMLayers", "nEffEKLMLayers");
63 registerEpicsPV("KLM:Eff:zEffThreshold", "zEffThreshold");
64 registerEpicsPV("KLM:Eff:zScoreThreshold", "zScoreThreshold");
65 registerEpicsPV("KLM:Eff:uncertaintyThreshold", "uncertaintyThreshold");
66 registerEpicsPV("KLM:Eff:minEntriesThreshold", "minEntriesThreshold");
67 registerEpicsPV("KLM:Eff:deltaEffThreshold", "deltaEffThreshold");
68 registerEpicsPV("KLM:Eff:deltaEffStopThreshold", "deltaEffStopThreshold");
69
70 gROOT->cd();
71 m_c_eff_bklm = new TCanvas((m_histogramDirectoryName + "/c_eff_bklm_plane").data());
72 m_c_eff_eklm = new TCanvas((m_histogramDirectoryName + "/c_eff_eklm_plane").data());
73 m_c_eff_bklm_sector = new TCanvas((m_histogramDirectoryName + "/c_eff_bklm_sector").data());
74 m_c_eff_eklm_sector = new TCanvas((m_histogramDirectoryName + "/c_eff_eklm_sector").data());
75
76 m_c_eff2d_bklm = new TCanvas((m_histogramDirectoryName + "/c_eff2d_bklm").data());
77 m_c_eff2d_eklm = new TCanvas((m_histogramDirectoryName + "/c_eff2d_eklm").data());
78
79 m_eff_bklm = new TH1F((m_histogramDirectoryName + "/eff_bklm_plane").data(),
80 "Plane Efficiency in BKLM",
82 m_eff_bklm->GetXaxis()->SetTitle("Layer number");
83 m_eff_bklm->SetStats(false);
84 m_eff_bklm->SetOption("HIST");
85
86 m_eff_eklm = new TH1F((m_histogramDirectoryName + "/eff_eklm_plane").data(),
87 "Plane Efficiency in EKLM",
89 m_eff_eklm->GetXaxis()->SetTitle("Plane number");
90 m_eff_eklm->SetStats(false);
91 m_eff_eklm->SetOption("HIST");
92
93 m_eff_bklm_sector = new TH1F((m_histogramDirectoryName + "/eff_bklm_sector").data(),
94 "Sector Efficiency in BKLM",
96 m_eff_bklm_sector->GetXaxis()->SetTitle("Sector number");
97 m_eff_bklm_sector->SetStats(false);
98 m_eff_bklm_sector->SetOption("HIST");
99
100 m_eff_eklm_sector = new TH1F((m_histogramDirectoryName + "/eff_eklm_sector").data(),
101 "Sector Efficiency in EKLM",
103 m_eff_eklm_sector->GetXaxis()->SetTitle("Sector number");
104 m_eff_eklm_sector->SetStats(false);
105 m_eff_eklm_sector->SetOption("HIST");
106
107 /* register plots for delta histogramming */
108 // all ext hits
109 addDeltaPar(m_histogramDirectoryName, "all_ext_hitsBKLM", HistDelta::c_Entries, m_minEntries, 1);
110 addDeltaPar(m_histogramDirectoryName, "all_ext_hitsEKLM", HistDelta::c_Entries, m_minEntries, 1);
111 addDeltaPar(m_histogramDirectoryName, "all_ext_hitsBKLMSector", HistDelta::c_Entries, m_minEntries, 1);
112 addDeltaPar(m_histogramDirectoryName, "all_ext_hitsEKLMSector", HistDelta::c_Entries, m_minEntries, 1);
113
114 // matched hits
115 addDeltaPar(m_histogramDirectoryName, "matched_hitsBKLM", HistDelta::c_Entries, m_minEntries, 1);
116 addDeltaPar(m_histogramDirectoryName, "matched_hitsEKLM", HistDelta::c_Entries, m_minEntries, 1);
117 addDeltaPar(m_histogramDirectoryName, "matched_hitsBKLMSector", HistDelta::c_Entries, m_minEntries, 1);
118 addDeltaPar(m_histogramDirectoryName, "matched_hitsEKLMSector", HistDelta::c_Entries, m_minEntries, 1);
119
120 // 2D Efficiency Histograms
121 TString eff2d_hist_bklm_title;
122 TString eff2d_hist_eklm_title;
123 if (m_ratio) {
124 eff2d_hist_bklm_title = "Plane Efficiency Ratios in BKLM";
125 eff2d_hist_eklm_title = "Plane Efficiency Ratios in EKLM";
126 } else {
127 eff2d_hist_bklm_title = "Plane Efficiency Diffs in BKLM";
128 eff2d_hist_eklm_title = "Plane Efficiency Diffs in EKLM";
129 }
130
131 // BKLM
132 m_eff2d_bklm = new TH2F((m_histogramDirectoryName + "/eff2d_bklm_sector").data(), eff2d_hist_bklm_title,
135 m_eff2d_bklm->GetXaxis()->SetTitle("Sector");
136 m_eff2d_bklm->GetYaxis()->SetTitle("Layer");
137 m_eff2d_bklm->SetStats(false);
138
139 m_err_bklm = new TH2F((m_histogramDirectoryName + "/err_bklm_sector").data(), eff2d_hist_bklm_title,
142 m_err_bklm->GetXaxis()->SetTitle("Sector");
143 m_err_bklm->GetYaxis()->SetTitle("Layer");
144 m_err_bklm->SetStats(false);
145
146 for (int sec_id = 0; sec_id < BKLMElementNumbers::getMaximalSectorNumber(); sec_id++) {
147 std::string BB_sec = "BB" + std::to_string(sec_id);
148 m_eff2d_bklm->GetXaxis()->SetBinLabel(sec_id + 1, BB_sec.c_str());
149
150 std::string BF_sec = "BF" + std::to_string(sec_id);
151 m_eff2d_bklm->GetXaxis()->SetBinLabel(BKLMElementNumbers::getMaximalSectorNumber() + sec_id + 1, BF_sec.c_str());
152 }
153
154 for (int lay_id = 0; lay_id < BKLMElementNumbers::getMaximalLayerNumber(); lay_id++) {
155 std::string B_lay = std::to_string(lay_id);
156 m_eff2d_bklm->GetYaxis()->SetBinLabel(lay_id + 1, B_lay.c_str());
157 }
158
159 // EKLM
161
162 m_eff2d_eklm = new TH2F((m_histogramDirectoryName + "/eff2d_eklm_sector").data(), eff2d_hist_eklm_title,
163 n_sectors_eklm, 0.5, n_sectors_eklm + 0.5,
165 m_eff2d_eklm->GetXaxis()->SetTitle("Layer");
166 m_eff2d_eklm->GetYaxis()->SetTitle("Sector");
167 m_eff2d_eklm->SetStats(false);
168
169 m_err_eklm = new TH2F((m_histogramDirectoryName + "/err_eklm_sector").data(), eff2d_hist_eklm_title,
170 n_sectors_eklm, 0.5, n_sectors_eklm + 0.5,
172 m_err_eklm->GetXaxis()->SetTitle("Layer");
173 m_err_eklm->GetYaxis()->SetTitle("Sector");
174 m_err_eklm->SetStats(false);
175
176 std::string name;
177 const double maximalLayer = EKLMElementNumbers::getMaximalLayerGlobalNumber();
178 for (int layerGlobal = 1; layerGlobal <= maximalLayer; ++layerGlobal) {
179 int section, layer;
180 m_EklmElementNumbers->layerNumberToElementNumbers(
181 layerGlobal, &section, &layer);
183 name = "B";
184 else
185 name = "F";
186 name += std::to_string(layer);
187 m_eff2d_eklm->GetXaxis()->SetBinLabel(layerGlobal, name.c_str());
188 }
189
190 for (int lay_id = 0; lay_id < EKLMElementNumbers::getMaximalSectorGlobalNumberKLMOrder(); lay_id++) {
191 std::string E_lay = std::to_string(lay_id);
192 m_eff2d_eklm->GetYaxis()->SetBinLabel(lay_id + 1, E_lay.c_str());
193 }
194
195}
196
197void DQMHistAnalysisKLM2Module::initialize2DRefHistogram(TH1*& hist, const std::string& histName, const std::string& title,
198 int maxLayer)
199{
200 // Get reference histogram using the base class method
202
203 if (hist) {
204 B2INFO("DQMHistAnalysisKLM2: " + histName + " histogram was found in reference");
205 hist->SetLineColor(2);
206 hist->SetOption("HIST");
207 hist->SetStats(false);
208 } else {
209 B2WARNING("DQMHistAnalysisKLM2: " + histName + " histogram not found in reference");
210 hist = new TH1F(histName.c_str(), title.c_str(), maxLayer, 0.5, 0.5 + maxLayer);
211 for (int lay_id = 0; lay_id < maxLayer; lay_id++) {
212 hist->SetBinContent(lay_id + 1, m_ratio ? 1 : 0);
213 }
214 }
215}
216
218{
219 m_IsPhysicsRun = (getRunType() == "physics");
220 m_IsNullRun = (getRunType() == "null");
221
222 // Initialize reference histograms for 2D efficiency plots
223 initialize2DRefHistogram(m_ref_efficiencies_bklm, "eff_bklm_plane", "Plane Efficiency in BKLM",
225
226 initialize2DRefHistogram(m_ref_efficiencies_eklm, "eff_eklm_plane", "Plane Efficiency in EKLM",
228
229 double unused = NAN;
230 //ratio/diff mode should only be possible if references exist
231 // default values should be initially defined in input parameters
232 requestLimitsFromEpicsPVs("zScoreThreshold", unused, m_zThreshold, unused, unused);
233 requestLimitsFromEpicsPVs("zEffThreshold", unused, m_zEffThreshold, unused, unused);
234 requestLimitsFromEpicsPVs("uncertaintyThreshold", unused, unused, m_errorThreshold, unused);
235 requestLimitsFromEpicsPVs("minEntriesThreshold", unused, m_minEntries, unused, unused);
236
237 requestLimitsFromEpicsPVs("deltaEffThreshold", m_alarmThr, m_warnThr, unused,
238 unused); // lower warn/alarm thresholds for delta efficiency
239 requestLimitsFromEpicsPVs("deltaEffStopThreshold", m_stopThr, unused, unused,
240 unused); // lower stop-alarm threshold for delta efficiency
243 requestLimitsFromEpicsPVs("nEffBKLMLayers", unused, unused, unused, m_BKLMLayerAlarm);
244 requestLimitsFromEpicsPVs("nEffEKLMLayers", unused, unused, unused, m_EKLMLayerAlarm);
245
246}
247
249{
250 std::string name;
251
252 int bklmMaxLayer = BKLMElementNumbers::getMaximalLayerNumber();//15
253 int bklmMaxSector = BKLMElementNumbers::getMaximalSectorNumber();//8
254
256 int eklmLocalMaxSector = EKLMElementNumbers::getMaximalSectorNumber();//4
257 int eklmBLayerCount = m_EklmElementNumbers->getMaximalDetectorLayerNumber(EKLMElementNumbers::c_BackwardSection);//12
258
259 // Looping over the sectors
260 for (int bin = 0; bin < m_eff_bklm_sector->GetXaxis()->GetNbins(); bin++) {
261 name = "eff_B";
262 if (bin < bklmMaxSector)
263 name += "B";
264 else
265 name += "F";
266 name += std::to_string(bin % bklmMaxSector);
267 m_monObj->setVariable(name, m_eff_bklm_sector->GetBinContent(bin + 1), m_eff_bklm_sector->GetBinError(bin + 1));
268 }
269
270 for (int bin = 0; bin < m_eff_eklm_sector->GetXaxis()->GetNbins(); bin++) {
271 name = "eff_E";
272 if (bin < eklmLocalMaxSector) //(bin < 4)
273 name += "B";
274 else
275 name += "F";
276 name += std::to_string(bin % eklmLocalMaxSector);
277 m_monObj->setVariable(name, m_eff_eklm_sector->GetBinContent(bin + 1), m_eff_eklm_sector->GetBinError(bin + 1));
278 }
279
280 // Looping over the planes
281 for (int layer = 0; layer < m_eff_bklm->GetXaxis()->GetNbins(); layer++) {
282 name = "eff_B";
283 //layer/15 < 8
284 if (layer / bklmMaxLayer < bklmMaxSector) {
285 name += "B";
286 } else {
287 name += "F";
288 }
289 name += std::to_string(int(layer / bklmMaxLayer) % bklmMaxSector) + "_layer" + std::to_string(1 + (layer % bklmMaxLayer));
290 m_monObj->setVariable(name, m_eff_bklm->GetBinContent(layer + 1), m_eff_bklm->GetBinError(layer + 1));
291 }
292 for (int layer = 0; layer < m_eff_eklm->GetXaxis()->GetNbins(); layer++) {
293 name = "eff_E";
294 if (layer / eklmGlobalMaxSector < eklmBLayerCount) //(layer/8 < 12)
295 name += "B" + std::to_string(layer / eklmGlobalMaxSector + 1);
296 else
297 name += "F" + std::to_string(layer / eklmGlobalMaxSector - eklmBLayerCount + 1);
298 name += + "_num" + std::to_string(((layer) % eklmGlobalMaxSector) + 1);
299 m_monObj->setVariable(name, m_eff_eklm->GetBinContent(layer + 1), m_eff_eklm->GetBinError(layer + 1));
300
301 }
302}
303
304void DQMHistAnalysisKLM2Module::processEfficiencyHistogram(TH1* effHist, TH1* denominator, TH1* numerator, TCanvas* canvas)
305{
306 effHist->Reset();
307 std::unique_ptr<TH1> effClone(static_cast<TH1*>
308 (effHist->Clone())); // Clone effHist, will be useful for delta plots & Smart pointer will manage memory leak
309 canvas->cd();
310 if (denominator != nullptr && numerator != nullptr) {
311 effHist->Divide(numerator, denominator, 1, 1, "B");
312 effHist->Draw();
313
314 //reference check
315 TH1* ref = findRefHist(effHist->GetName(), ERefScaling::c_RefScaleNone);
316 if (ref) {ref->Draw("hist,same");}
317
318 canvas->Modified();
319 canvas->Update();
320
321 /* delta component */
322 auto deltaDenom = getDelta("", denominator->GetName());
323 auto deltaNumer = getDelta("", numerator->GetName());
324
325 // both histograms should have the same update condition but checking both should be okay?
326 // if this condition is not satisfied, does it cause the above to not ever update?
327 // after test campaign, switch condition back to (deltaNumer != nullptr && deltaDenom != nullptr)
328 UpdateCanvas(canvas->GetName(), (effHist != nullptr));
329 if ((deltaNumer != nullptr) && (deltaDenom != nullptr)) {
330 B2INFO("DQMHistAnalysisKLM2: Eff Delta Num/Denom Entries is " << deltaNumer->GetEntries() << "/" << deltaDenom->GetEntries());
331 effClone->Divide(deltaNumer, deltaDenom, 1, 1, "B");
332 effClone->SetLineColor(kOrange);
333 effClone->DrawCopy("SAME"); // managed by ROOT, so it helps in plotting even if obj deleted by smart pointer
334 canvas->Modified();
335 canvas->Update();
336 }
337 }
338}
339
341 const std::string& histName, TH1* histogram)
342{
343 std::string name;
344 TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
345 if (canvas == NULL) {
346 B2WARNING("KLMDQM2 histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
347 return;
348 } else {
349 canvas->cd();
350 histogram->SetStats(false);
351 double histMin = gPad->GetUymin();
352 double histMax = gPad->GetUymax();
353 double histRange = histMax - histMin;
354 if (histName.find("bklm") != std::string::npos) {
355 /* First draw the vertical lines and the sector names. */
356 const int maximalLayer = BKLMElementNumbers::getMaximalLayerNumber();
357 for (int sector = 0; sector < BKLMElementNumbers::getMaximalSectorGlobalNumber(); ++sector) {
358 int bin = maximalLayer * sector + 1;
359 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
360 double xText = histogram->GetXaxis()->GetBinLowEdge(bin + maximalLayer / 2);
361 double yText = histMin + 0.98 * histRange;
362 if (sector > 0)
363 m_PlaneLine.DrawLine(xLine, histMin, xLine, histMin + histRange);
364 name = "B";
366 name += "B";
367 else
368 name += "F";
369 name += std::to_string(sector % BKLMElementNumbers::getMaximalSectorNumber());
370 m_PlaneText.DrawText(xText, yText, name.c_str());
371 }
372
373 } else {
374 /* First draw the vertical lines and the sector names. */
375 const double maximalLayer = EKLMElementNumbers::getMaximalLayerGlobalNumber();
377 for (int layerGlobal = 1; layerGlobal <= maximalLayer; ++layerGlobal) {
378 int bin = maxPlane * layerGlobal + 1;
379 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
380 double xText = histogram->GetXaxis()->GetBinLowEdge(bin - maxPlane / 2);
381 double yText = histMin + 0.98 * histRange;
382 if (layerGlobal < maximalLayer)
383 m_PlaneLine.DrawLine(xLine, histMin, xLine, histMin + histRange);
384 int section, layer;
385 m_EklmElementNumbers->layerNumberToElementNumbers(
386 layerGlobal, &section, &layer);
388 name = "B";
389 else
390 name = "F";
391 name += std::to_string(layer);
392 m_PlaneText.DrawText(xText, yText, name.c_str());
393 }
394 }
395 canvas->Modified();
396 canvas->Update();
397 }
398}
399
401 TH1* mainHist, TH1* refHist, TH2* eff2dHist, TH2* errHist, int layers, int sectors, bool ratioPlot,
402 int& pvcount, double layerLimit, TCanvas* eff2dCanv)
403{
404
405 int i = 0;
406 float mainEff;
407 float refEff;
408 float mainErr;
409 float refErr;
410 float maxVal = m_max;
411 float minVal = m_min;
412 float eff2dVal;
413 bool setAlarm = false;
414 bool setWarn = false;
415 bool setFew = false;
416 int mainEntries;
417 int layercount = 0;
418
419 errHist->Reset(); // Reset histogram
420
421 pvcount = 0; // Initialize to zero
422 mainEntries = mainHist->GetEntries();
423
424 for (int binx = 0; binx < sectors; binx++) {
425
426 for (int biny = 0; biny < layers; biny++) {
427
428 mainEff = mainHist->GetBinContent(i + 1);
429 mainErr = mainHist->GetBinError(i + 1);
430 if (refHist) {
431 refEff = refHist->GetBinContent(i + 1);
432 refErr = refHist->GetBinError(i + 1);
433 } else {
434 refEff = 0.;
435 refErr = 0.;
436 }
437
438 if ((mainEff == 0.) and (refEff == 0.)) {
439 // empty histograms, draw blank bin
440 eff2dHist->SetBinContent(binx + 1, biny + 1, 0.);
441 } else if ((refEff == 0.) and (ratioPlot)) {
442 // no reference, set maximum value
443 eff2dHist->SetBinContent(binx + 1, biny + 1, maxVal);
444 } else if (mainEff == 0.) {
445 // no data, set zero
446 eff2dHist->SetBinContent(binx + 1, biny + 1, 0.);
447 errHist->SetBinContent(binx + 1, biny + 1, 0.);
448 } else {
449 double sigmaR = 0.0;
450 double Z = 0.0;
451 double deltaR = 0.0;
452 if (ratioPlot) {
453 eff2dVal = mainEff / refEff;
454 // Calculate uncertainty on the ratio
455 sigmaR = eff2dVal * sqrt(pow(mainErr / mainEff, 2) + pow(refErr / refEff, 2));
456
457 // Z-score: how many sigma is the ratio from the threshold
458 if (sigmaR > 0) {
459 deltaR = eff2dVal - m_zEffThreshold;
460 Z = deltaR / sigmaR; // ideal-case w'd be effThr is 1, so Z = (R - 1) / sigmaR
461 }
462 } else {
463 sigmaR = pow(pow(mainErr, 2) + pow(refErr, 2), 0.5);
464 eff2dVal = (mainEff - refEff);
465 deltaR = eff2dVal;
466 Z = eff2dVal / sigmaR;
467 }
468
469 // main histogram
470 if ((eff2dVal > minVal) and (eff2dVal < maxVal)) {
471 // value within display window
472 eff2dHist->SetBinContent(binx + 1, biny + 1, eff2dVal);
473 } else if (eff2dVal > maxVal) {
474 // value above display window
475 eff2dHist->SetBinContent(binx + 1, biny + 1, maxVal);
476 } else if (eff2dVal < minVal) {
477 // value below display window
478 eff2dHist->SetBinContent(binx + 1, biny + 1, minVal);
479 }
480
481 // set alarm
482 if (mainEntries < (int)m_minEntries) {
483 setFew = true;
484 } else if (ratioPlot && sigmaR / eff2dVal > m_errorThreshold) {
485 // For ratio mode: relative uncertainty
486 setFew = true;
487 errHist->SetBinContent(binx + 1, biny + 1, sigmaR);
488 } else if (!ratioPlot && sigmaR > m_errorThreshold) {
489 // For difference mode: absolute uncertainty
490 setFew = true;
491 errHist->SetBinContent(binx + 1, biny + 1, sigmaR);
492 } else {
493 if (deltaR < m_warnThr && Z < m_zThreshold) {
494 pvcount += 1;
495 errHist->SetBinContent(binx + 1, biny + 1, sigmaR);
496 if ((deltaR <= m_alarmThr) && (deltaR >= m_stopThr)) {
497 setWarn = true;
498 layercount++; // Increment layercount when alarm condition is met
499 } else if (deltaR < m_stopThr) {
500 setAlarm = true;
501 layercount++; // Increment layercount when a stop condition is met
502 }
503 }
504 }
505
506 }
507 i++;
508 }//end of bin y
509
510 }//end of bin x
511
512 if ((pvcount - layercount) > (int) layerLimit) {
513 setWarn = true;
514 }
515 if (layercount > (int) layerLimit) {
516 setAlarm = true;
517 }
518
519 eff2dHist->SetMinimum(minVal);
520 eff2dHist->SetMaximum(maxVal);
521
522 eff2dCanv->cd();
523 eff2dHist->Draw("COLZ");
524 errHist->Draw("TEXT SAME");
525 if (setFew) {
526 colorizeCanvas(eff2dCanv, c_StatusTooFew);
527 } else if (setAlarm) {
528 colorizeCanvas(eff2dCanv, c_StatusError);
529 } else if (setWarn) {
531 } else {
532 colorizeCanvas(eff2dCanv, c_StatusGood);
533 }
534 eff2dCanv->Modified();
535 eff2dCanv->Update();
536}
537
539{
540 /* If KLM is not included, stop here and return. */
541 TH1* daqInclusion = findHist("KLM/daq_inclusion");
542 if (not(daqInclusion == NULL)) {
543 int isKlmIncluded = daqInclusion->GetBinContent(daqInclusion->GetXaxis()->FindBin("Yes"));
544 if (isKlmIncluded == 0)
545 return;
546 }
547
548
549 /* Obtain plots necessary for efficiency plots */
550 TH1F* all_ext_bklm = (TH1F*)findHist(m_histogramDirectoryName + "/all_ext_hitsBKLM");
551 TH1F* matched_hits_bklm = (TH1F*)findHist(m_histogramDirectoryName + "/matched_hitsBKLM");
552
553 TH1F* all_ext_eklm = (TH1F*)findHist(m_histogramDirectoryName + "/all_ext_hitsEKLM");
554 TH1F* matched_hits_eklm = (TH1F*)findHist(m_histogramDirectoryName + "/matched_hitsEKLM");
555
556
557 TH1F* all_ext_bklm_sector = (TH1F*)findHist(m_histogramDirectoryName + "/all_ext_hitsBKLMSector");
558 TH1F* matched_hits_bklm_sector = (TH1F*)findHist(m_histogramDirectoryName + "/matched_hitsBKLMSector");
559
560 TH1F* all_ext_eklm_sector = (TH1F*)findHist(m_histogramDirectoryName + "/all_ext_hitsEKLMSector");
561 TH1F* matched_hits_eklm_sector = (TH1F*)findHist(m_histogramDirectoryName + "/matched_hitsEKLMSector");
562
563 /* Check if efficiency histograms exist*/
564 if ((all_ext_bklm == nullptr || matched_hits_bklm == nullptr) && (m_IsPhysicsRun)) {
565 B2INFO("Histograms needed for BKLM plane efficiency computation are not found");
566 }
567
568 if ((all_ext_eklm == nullptr || matched_hits_eklm == nullptr) && (m_IsPhysicsRun)) {
569 B2INFO("Histograms needed for EKLM plane efficiency computation are not found");
570 }
571 if ((all_ext_bklm_sector == nullptr || matched_hits_bklm_sector == nullptr) && (m_IsPhysicsRun)) {
572 B2INFO("Histograms needed for BKLM sector efficiency computation are not found");
573 }
574 if ((all_ext_eklm_sector == nullptr || matched_hits_eklm_sector == nullptr) && (m_IsPhysicsRun)) {
575 B2INFO("Histograms needed for EKLM sector efficiency computation are not found");
576 }
577
578
579 /* Draw histograms onto canvases*/
580 processEfficiencyHistogram(m_eff_bklm, all_ext_bklm, matched_hits_bklm, m_c_eff_bklm);
581 processEfficiencyHistogram(m_eff_eklm, all_ext_eklm, matched_hits_eklm, m_c_eff_eklm);
582
583 processEfficiencyHistogram(m_eff_bklm_sector, all_ext_bklm_sector, matched_hits_bklm_sector, m_c_eff_bklm_sector);
584 processEfficiencyHistogram(m_eff_eklm_sector, all_ext_eklm_sector, matched_hits_eklm_sector, m_c_eff_eklm_sector);
585
586 processPlaneHistogram("eff_bklm_plane", m_eff_bklm);
587 processPlaneHistogram("eff_eklm_plane", m_eff_eklm);
588
589 /* Make Diff 2D plots */
593
598 /* Set EPICS PV Values*/
599 B2DEBUG(20, "DQMHistAnalysisKLM2: Updating EPICS PVs");
600 // only update PVs if there's enough statistics and datasize != 0
601 // Check if it's a null run, if so, don't update EPICS PVs
602 if (m_IsNullRun) {
603 B2INFO("DQMHistAnalysisKLM2: Null run detected. No PV Update.");
604 return;
605 }
606 auto* daqDataSize = findHist("DAQ/KLMDataSize");
607 double meanDAQDataSize = 0.;
608 if (daqDataSize != nullptr) {
609 meanDAQDataSize = daqDataSize->GetMean();
610 B2INFO("DAQ/KLMDataSize's mean is " << meanDAQDataSize);
611 } else
612 B2WARNING("DQMHistAnalysisKLM2: Cannot find KLMDataSize");
613 if ((daqDataSize != nullptr) and (meanDAQDataSize != 0.)) {
614 int procesedEvents = DQMHistAnalysisModule::getEventProcessed();
615 if (procesedEvents > (int)m_minEntries) {
616 if (static_cast<int>(m_eff_bklm->GetEntries()) > (int)m_minEntries) {
617 setEpicsPV("nEffBKLMLayers", m_nEffBKLMLayers);
618 }
619 if (static_cast<int>(m_eff_eklm->GetEntries()) > (int)m_minEntries) {
620 setEpicsPV("nEffEKLMLayers", m_nEffEKLMLayers);
621 }
622 }
623 } else
624 B2INFO("DQMHistAnalysisKLM2: KLM Not included. No PV Update. ");
625
626}
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
static 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).
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 addDeltaPar(const std::string &dirname, const std::string &histname, HistDelta::EDeltaType t, int p, unsigned int a=1)
Add Delta histogram parameters.
static 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 void UpdateCanvas(const std::string &name, bool updated=true)
Mark canvas as updated (or not)
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.
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.
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 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.