Belle II Software release-09-00-00
DQMHistAnalysisKLM.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/DQMHistAnalysisKLM.h>
11
12/* Basf2 headers. */
13#include <klm/dataobjects/KLMChannelIndex.h>
14
15/* ROOT headers. */
16#include <TClass.h>
17#include <TROOT.h>
18#include <TStyle.h>
19
20/* C++ headers. */
21#include <algorithm>
22
23using namespace Belle2;
24
25REG_MODULE(DQMHistAnalysisKLM);
26
29 m_ProcessedEvents{0},
30 m_IsNullRun{false},
31 m_ChannelArrayIndex{&(KLMChannelArrayIndex::Instance())},
32 m_SectorArrayIndex{&(KLMSectorArrayIndex::Instance())},
33 m_ElementNumbers{&(KLMElementNumbers::Instance())},
34 m_EklmElementNumbers{&(EKLMElementNumbers::Instance())}
35{
36 setDescription("Module used to analyze KLM DQM histograms.");
37 addParam("ThresholdForMasked", m_ThresholdForMasked,
38 "Threshold X for masked channels: if a channel has an occupancy X times larger than the average, it will be masked.", 100);
39 addParam("ThresholdForHot", m_ThresholdForHot,
40 "Threshold Y for hot channels: if a channel has an occupancy Y times larger than the average, it will be marked as hot (but not masked).",
41 10);
42 addParam("ThresholdForLog", m_ThresholdForLog,
43 "Threshold Z for log scale view: if a channel has an occupancy Z times larger than the average, canvas shifts to log scale.",
44 20);
45 addParam("MinHitsForFlagging", m_MinHitsForFlagging, "Minimal number of hits in a channel required to flag it as 'Masked' or 'Hot'",
46 50);
47 addParam("MinProcessedEventsForMessages", m_MinProcessedEventsForMessagesInput,
48 "Minimal number of processed events required to print error messages", 10000.);
49 addParam("MinEntries", m_minEntries,
50 "Minimal number for delta histogram updates", 50000.);
51 addParam("MessageThreshold", m_MessageThreshold,
52 "Max number of messages to show up in channel occupancy plots", 12);
53 addParam("HistogramDirectoryName", m_histogramDirectoryName, "Name of histogram directory", std::string("KLM"));
54 addParam("RefHistogramDirectoryPrefix", m_refHistogramDirectoryPrefix, "Prefix to account for reference file", std::string("ref/"));
55 addParam("RefHistoFile", m_refFileName, "Reference histogram file name", std::string("KLM_DQM_REF_BEAM.root"));
56
58 m_2DHitsLine.SetLineColor(kRed);
59 m_2DHitsLine.SetLineWidth(3);
60 m_2DHitsLine.SetLineStyle(2); // dashed
61 m_PlaneLine.SetLineColor(kMagenta);
62 m_PlaneLine.SetLineWidth(1);
63 m_PlaneLine.SetLineStyle(2); // dashed
64 m_PlaneText.SetTextAlign(22); // centered, middle
65 m_PlaneText.SetTextColor(kMagenta);
66 m_PlaneText.SetTextFont(42); // Helvetica regular
67 m_PlaneText.SetTextSize(0.02); // 2% of TPad's full height
68}
69
70
72{
74
76 B2FATAL("The threshold used for hot channels is larger than the one for masked channels."
77 << LogVar("Threshold for hot channels", m_ThresholdForHot)
78 << LogVar("Threshold for masked channels", m_ThresholdForMasked));
79
80 if (m_refFileName != "") {
81 m_refFile = TFile::Open(m_refFileName.data(), "READ");
82 }
83
84 // register plots for delta histogramming
85 addDeltaPar(m_histogramDirectoryName, "time_rpc", HistDelta::c_Entries, m_minEntries, 1);
86 addDeltaPar(m_histogramDirectoryName, "time_scintillator_bklm", HistDelta::c_Entries, m_minEntries, 1);
87 addDeltaPar(m_histogramDirectoryName, "time_scintillator_eklm", HistDelta::c_Entries, m_minEntries, 1);
88
89 //register EPICS PVs
90 registerEpicsPV("KLM:MaskedChannels", "MaskedChannels");
91 registerEpicsPV("KLM:DeadBarrelModules", "DeadBarrelModules");
92 registerEpicsPV("KLM:DeadEndcapModules", "DeadEndcapModules");
93
94 gROOT->cd();
95
96 std::string str;
98 for (KLMChannelIndex& klmSector : klmIndex) {
99 int nHistograms;
100 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
101 nHistograms = 2;
102 else
103 nHistograms = 3;
104 for (int j = 0; j < nHistograms; j++) {
105 str = "strip_hits_subdetector_" +
106 std::to_string(klmSector.getSubdetector()) +
107 "_section_" + std::to_string(klmSector.getSection()) +
108 "_sector_" + std::to_string(klmSector.getSector()) +
109 "_" + std::to_string(j);
110 addDeltaPar(m_histogramDirectoryName, str, HistDelta::c_Entries, m_minEntries, 1);
111
112 }
113 }
114
115
116 //search for reference
117 if (m_refFile && m_refFile->IsOpen()) {
118 B2INFO("DQMHistAnalysisKLM: reference root file (" << m_refFileName << ") FOUND, able to read ref histograms");
119
120 } else
121 B2WARNING("DQMHistAnalysisKLM: reference root file (" << m_refFileName << ") not found, or closed");
122}
123
125{
126 if (m_refFile) {
127 m_refFile->Close();
128 delete m_refFile;
129 }
130}
131
133{
134 if (!m_ElectronicsMap.isValid())
135 B2FATAL("No KLM electronics map.");
138 m_DeadBarrelModules.clear();
139 m_DeadEndcapModules.clear();
140 m_MaskedChannels.clear();
141
142 m_IsNullRun = (getRunType() == "null");
143}
144
146{
147 int hist_max_bin; double max_position;
148 TH1* time_rpc = findHist(m_histogramDirectoryName + "/time_rpc");
149 if (time_rpc) {
150 hist_max_bin = time_rpc->GetMaximumBin();
151 max_position = time_rpc->GetXaxis()->GetBinCenter(hist_max_bin);
152 m_monObj->setVariable("RPC_Time_Peak", max_position);
153 }
154
155 TH1* time_scint_bklm = findHist(m_histogramDirectoryName + "/time_scintillator_bklm");
156 if (time_scint_bklm) {
157 hist_max_bin = time_scint_bklm->GetMaximumBin();
158 max_position = time_scint_bklm->GetXaxis()->GetBinCenter(hist_max_bin);
159 m_monObj->setVariable("BKLM_Scint_Time_Peak", max_position);
160 }
161
162 TH1* time_scint_eklm = findHist(m_histogramDirectoryName + "/time_scintillator_eklm");
163 if (time_scint_eklm) {
164 hist_max_bin = time_scint_eklm->GetMaximumBin();
165 max_position = time_scint_eklm->GetXaxis()->GetBinCenter(hist_max_bin);
166 m_monObj->setVariable("EKLM_Scint_Time_Peak", max_position);
167 }
168}
169
171{
173 B2WARNING("Either DAQ/Nevent is not found or Nevent = 0.");
174 /* Set the minimal number of processed events to 0 if we can't determine the processed events. */
176 }
178}
179
180void DQMHistAnalysisKLMModule::deltaDrawer(TH1* delta, TH1* histogram, TCanvas* canvas)
181{
182 if (delta != nullptr) {
183 Double_t scale = (Double_t) histogram->Integral(); //want delta and histo to have same norm
184
185 // delta != nullptr should take care of whether update condition is met.
186 delta->SetLineColor(kBlackBody); //random choice of not green or blue
187 delta->SetLineStyle(4);
188 delta->DrawNormalized("SAME", scale); //normalize delta to histo
189 canvas->Modified();
190 canvas->Update();
191 }
192}
193
195 int subdetector, int section, int sector, int index,
196 TH1* histogram, TH1* delta, TCanvas* canvas, TLatex& latex)
197{
198 double x = 0.15;
199 double y = 0.85;
200 int i, n;
201 std::map<KLMModuleNumber, double> moduleHitMap;
202 std::map<KLMModuleNumber, double>::iterator it;
203 double average = 0;
204 int channelSubdetector, channelSection, channelSector;
205 int layer, plane, strip;
206 std::string str;
207 canvas->Clear();
208 canvas->cd();
209 histogram->SetStats(false);
210 canvas->SetLogy(0); //initialize to start without logscale
211 histogram->Draw();
212 deltaDrawer(delta, histogram, canvas); //draw normalized delta on top
213 n = histogram->GetXaxis()->GetNbins();
214
215 /* call reference histograms */
216 TH1* ref_histogram = nullptr;
217 float ref_average = 0;
218 if (m_refFile && m_refFile->IsOpen()) {
219 ref_histogram = (TH1*)m_refFile->Get((m_refHistogramDirectoryPrefix + histogram->GetName()).data());
220 if (!ref_histogram) {
221 B2WARNING("Unable to find " << m_refHistogramDirectoryPrefix << histogram->GetName() << " in reference file.");
222 }
223 }
224
225 if (ref_histogram != nullptr) {
226 for (i = 1; i <= n; i++) {
227 double nHitsPerModuleRef = ref_histogram->GetBinContent(i);
228 ref_average = ref_average + nHitsPerModuleRef;
229 }
230 }
231
232 for (i = 1; i <= n; i++) {
233 KLMChannelNumber channelIndex = std::round(histogram->GetBinCenter(i));
234 KLMChannelNumber channelNumber =
235 m_ChannelArrayIndex->getNumber(channelIndex);
236 double nHitsPerModule = histogram->GetBinContent(i);
237 average = average + nHitsPerModule;
239 channelNumber, &channelSubdetector, &channelSection, &channelSector,
240 &layer, &plane, &strip);
241 if ((channelSubdetector != subdetector) ||
242 (channelSection != section) ||
243 (channelSector != sector))
244 B2FATAL("Inconsistent element numbers.");
246 subdetector, section, sector, layer);
247 it = moduleHitMap.find(module);
248 if (it == moduleHitMap.end()) {
249 moduleHitMap.insert(std::pair<KLMModuleNumber, double>(
250 module, nHitsPerModule));
251 } else {
252 it->second += nHitsPerModule;
253 }
254 }
255 unsigned int activeModuleChannels = 0;
256 int message_counter = 0;
257 for (it = moduleHitMap.begin(); it != moduleHitMap.end(); ++it) {
258 KLMModuleNumber moduleNumber = it->first;
259 if (it->second != 0) {
260 activeModuleChannels += m_ElementNumbers->getNChannelsModule(moduleNumber);
261 continue;
262 }
264 moduleNumber, &channelSubdetector, &channelSection, &channelSector, &layer);
265 /* Channel with plane = 1, strip = 1 exists for any BKLM or EKLM module. */
266 KLMChannelNumber channel =
268 channelSubdetector, channelSection, channelSector, layer, 1, 1);
269 const KLMElectronicsChannel* electronicsChannel =
270 m_ElectronicsMap->getElectronicsChannel(channel);
271 if (electronicsChannel == nullptr)
272 B2FATAL("Incomplete KLM electronics map.");
273 str = "No data from lane " + std::to_string(electronicsChannel->getLane());
274 latex.DrawLatexNDC(x, y, str.c_str());
275 y -= 0.05;
276 message_counter++;
277 /* Store the module number, used later in processPlaneHistogram
278 * to color the canvas with red and to raise up an alarm. */
279 if (channelSubdetector == KLMElementNumbers::c_BKLM) {
280 std::vector<KLMModuleNumber>::iterator ite =
281 std::find(m_DeadBarrelModules.begin(),
283 moduleNumber);
284 if (ite == m_DeadBarrelModules.end())
285 m_DeadBarrelModules.push_back(moduleNumber);
286 } else {
287 std::vector<KLMModuleNumber>::iterator ite = std::find(m_DeadEndcapModules.begin(),
289 moduleNumber);
290 if (ite == m_DeadEndcapModules.end())
291 m_DeadEndcapModules.push_back(moduleNumber);
292 }
293 }
294 if (activeModuleChannels == 0)
295 return;
296 average /= activeModuleChannels;
297 ref_average /= activeModuleChannels;
298
299 for (i = 1; i <= n; ++i) {
300 KLMChannelNumber channelIndex = std::round(histogram->GetBinCenter(i));
301 KLMChannelNumber channelNumber =
302 m_ChannelArrayIndex->getNumber(channelIndex);
303 double nHits = histogram->GetBinContent(i);
305 channelNumber, &channelSubdetector, &channelSection, &channelSector,
306 &layer, &plane, &strip);
307 std::string channelStatus = "Normal";
308 if ((nHits > average * m_ThresholdForMasked) && (nHits > m_MinHitsForFlagging)) {
309 channelStatus = "Masked";
310 std::vector<KLMModuleNumber>::iterator ite =
311 std::find(m_MaskedChannels.begin(),
312 m_MaskedChannels.end(),
313 channelNumber);
314 if (ite == m_MaskedChannels.end())
315 m_MaskedChannels.push_back(channelNumber);
316 B2DEBUG(20, "KLM@MaskMe " << channelNumber);
317 } else if ((nHits > average * m_ThresholdForHot) && (nHits > m_MinHitsForFlagging)) {
318 channelStatus = "Hot";
319 }
320 if (channelStatus != "Normal") {
321 const KLMElectronicsChannel* electronicsChannel =
322 m_ElectronicsMap->getElectronicsChannel(channelNumber);
323 if (electronicsChannel == nullptr)
324 B2FATAL("Incomplete BKLM electronics map.");
325 if (channelStatus == "Masked") {
326 histogram->SetBinContent(i, 0);
327 if (delta != nullptr)
328 delta->SetBinContent(i, 0);
329 }
330 str = channelStatus + " channel: ";
331 // lane, axis, channel
332 str += ("L" + std::to_string(electronicsChannel->getLane()) +
333 " A" + std::to_string(electronicsChannel->getAxis()) +
334 " Ch" + std::to_string(electronicsChannel->getChannel()));
335 message_counter++;
336 if (message_counter <= m_MessageThreshold) {
337 latex.DrawLatexNDC(x, y, str.c_str());
338 y -= 0.05;
339 }
340 }
341 }
342 if (message_counter > m_MessageThreshold) {
343 std::string verbose_message = " more messages";
344 verbose_message = std::to_string(message_counter - m_MessageThreshold) + verbose_message;
345 latex.DrawLatexNDC(x, y, verbose_message.c_str());
346 }
347
348
349 // for hot/masked channels, log scale plots (reference and main)
350 if (histogram->GetMaximum()*n > histogram->Integral()*m_ThresholdForLog && average * activeModuleChannels > m_MinHitsForFlagging) {
351 histogram->SetMinimum(1);
352 canvas->SetLogy();
353 } else if (ref_histogram != nullptr) {
354 if (ref_histogram->GetMaximum()*n > ref_histogram->Integral()*m_ThresholdForLog
355 && ref_average * activeModuleChannels > m_MinHitsForFlagging) {
356 histogram->SetMinimum(1);
357 canvas->SetLogy();
358 } else
359 canvas->SetLogy(0);
360 } else
361 canvas->SetLogy(0);
362
363 canvas->Modified();
364 canvas->Update();
365
366 /* Drawing dividing lines */
367 int divisions;
368 int bin = 1;
369 double xLine;
370 // drawing lines for BKLM sectors
371 if (subdetector == 1) {
372 int shift;
373 if (index == 0) {
374 divisions = 7;
375 shift = 1;
376 } else {
379 }
380 for (int k = 0; k < divisions; k++) {
381 xLine = (histogram->GetXaxis()->GetBinLowEdge(bin) - canvas->GetX1()) / (canvas->GetX2() - canvas->GetX1());
382 m_PlaneLine.DrawLineNDC(xLine, 0.1, xLine, 0.9);
383 bin += BKLMElementNumbers::getNStrips(section, sector, k + shift, 0)
384 + BKLMElementNumbers::getNStrips(section, sector, k + shift, 1);
385 }
386 } else { // drawing lines for EKLM sectors
387 if ((section == 2) && (index == 0 || index == 1))
388 divisions = 5;
389 else
390 divisions = 4;
391 for (int k = 0; k < divisions; k++) {
392 xLine = (histogram->GetXaxis()->GetBinLowEdge(bin) - canvas->GetX1()) / (canvas->GetX2() - canvas->GetX1());
393 m_PlaneLine.DrawLineNDC(xLine, 0.1, xLine, 0.9);
395 }
396 }
397 canvas->Modified();
398 canvas->Update();
399
400}
401
403 KLMSectionNumber section, TH2F* histogram, TCanvas* canvas)
404{
405 canvas->Clear();
406 canvas->cd();
407 histogram->SetStats(false);
408 histogram->Draw("COLZ");
409 /* Draw the lines only for the backward layers. */
411 m_2DHitsLine.DrawLine(-110, 80, -110, 190);
412 m_2DHitsLine.DrawLine(-110, 190, 110, 190);
413 m_2DHitsLine.DrawLine(110, 80, 110, 190);
414 m_2DHitsLine.DrawLine(-110, 80, 110, 80);
415 }
416 canvas->Modified();
417 canvas->Update();
418}
419
421 const std::string& histName)
422{
423 TH1* histogram = findHist(m_histogramDirectoryName + "/" + histName);
424 if (histogram == nullptr) {
425 B2WARNING("KLM DQM histogram " + m_histogramDirectoryName + "/" << histName << " is not found.");
426 return;
427 }
428
429 TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
430 if (canvas == nullptr) {
431 B2WARNING("KLM DQM histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
432 return;
433 }
434
435 else {
436 canvas->Clear();
437 canvas->cd();
438 histogram->Draw();
439 /* calling on delta histogram*/
440 TH1* delta = getDelta(m_histogramDirectoryName, histName);
441 UpdateCanvas(canvas->GetName(), delta != nullptr); //keeping this for testing purposes
442 if (delta != nullptr) {
443 B2INFO("DQMHistAnalysisKLM: Time Delta Entries is " << delta->GetEntries());
444 deltaDrawer(delta, histogram, canvas);
445 }
446 }
447}
448
450 const std::string& histName)
451{
452 TH1* histogram = findHist(m_histogramDirectoryName + "/" + histName);
453 if (histogram == nullptr) {
454 B2WARNING("KLM DQM histogram " + m_histogramDirectoryName + "/" << histName << " is not found.");
455 return;
456 }
457 TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
458 if (canvas == nullptr) {
459 B2WARNING("KLM DQM histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
460 return;
461 }
462
463 histogram->Clear();
464 canvas->Clear();
465 canvas->cd();
466 if (m_MaskedChannels.size() > 0) {
467 int channelSubdetector, channelSection, channelSector;
468 int layer, plane, strip;
469 for (KLMChannelNumber channel : m_MaskedChannels) {
471 channel, &channelSubdetector, &channelSection, &channelSector,
472 &layer, &plane, &strip);
473 KLMSectorNumber sectorNumber;
474 if (channelSubdetector == KLMElementNumbers::c_BKLM)
475 sectorNumber = m_ElementNumbers->sectorNumberBKLM(channelSection, channelSector);
476 else
477 sectorNumber = m_ElementNumbers->sectorNumberEKLM(channelSection, channelSector);
478 KLMSectorNumber sectorIndex = m_SectorArrayIndex->getIndex(sectorNumber);
479 histogram->Fill(sectorIndex);
480 }
481 }
482 histogram->SetStats(false);
483 histogram->Draw();
484 canvas->Modified();
485 canvas->Update();
486}
487
489 const std::string& histName, TLatex& latex)
490{
491
492 TH1* histogram = findHist(m_histogramDirectoryName + "/" + histName);
493 if (histogram == nullptr) {
494 B2WARNING("KLM DQM histogram " + m_histogramDirectoryName + "/" << histName << " is not found.");
495 return;
496 }
497 TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
498 if (canvas == nullptr) {
499 B2WARNING("KLM DQM histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
500 return;
501 } else {
502 std::string name, alarm;
503 int moduleSubdetector, moduleSection, moduleSector, moduleLayer;
504 double xAlarm = 0.15;
505 double yAlarm = 0.8;
506 canvas->Clear();
507 canvas->cd();
508 histogram->SetStats(false);
509 histogram->Draw();
510
511 int message_counter = 0;
512 if (histName.find("bklm") != std::string::npos) {
513 /* First draw the vertical lines and the sector names. */
514 const int maximalLayer = BKLMElementNumbers::getMaximalLayerNumber();
515 for (int sector = 0; sector < BKLMElementNumbers::getMaximalSectorGlobalNumber(); ++sector) {
516 int bin = maximalLayer * sector + 1;
517 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
518 double xText = histogram->GetXaxis()->GetBinLowEdge(bin + maximalLayer / 2);
519 double yText = gPad->GetUymin() + 0.98 * (gPad->GetUymax() - gPad->GetUymin());
520 if (sector > 0)
521 m_PlaneLine.DrawLine(xLine, gPad->GetUymin(), xLine, gPad->GetUymax());
522 name = "B";
524 name += "B";
525 else
526 name += "F";
527 name += std::to_string(sector % BKLMElementNumbers::getMaximalSectorNumber());
528 m_PlaneText.DrawText(xText, yText, name.c_str());
529 }
530 /* Then, color the canvas with red if there is a dead module
531 * and write an error message. */
532 if (m_DeadBarrelModules.size() == 0) {
535 for (KLMModuleNumber module : m_DeadBarrelModules) {
537 module, &moduleSubdetector, &moduleSection, &moduleSector, &moduleLayer);
538 alarm = "No data from " + m_ElementNumbers->getSectorDAQName(moduleSubdetector, moduleSection, moduleSector);
539 alarm += ", layer " + std::to_string(moduleLayer);
540 message_counter++;
541 if (message_counter <= m_MessageThreshold) {
542 latex.DrawLatexNDC(xAlarm, yAlarm, alarm.c_str());
543 yAlarm -= 0.05;
544 }
545 }
546 if (m_IsNullRun == false) {
548 }
549 } //end of enough statistics condition
550 else {
552 }
553 } else {
554 /* First draw the vertical lines and the sector names. */
555 const double maximalLayer = EKLMElementNumbers::getMaximalLayerGlobalNumber();
557 for (int layerGlobal = 1; layerGlobal <= maximalLayer; ++layerGlobal) {
558 int bin = maxPlane * layerGlobal + 1;
559 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
560 double xText = histogram->GetXaxis()->GetBinLowEdge(bin - maxPlane / 2);
561 double yText = gPad->GetUymin() + 0.98 * (gPad->GetUymax() - gPad->GetUymin());
562 if (layerGlobal < maximalLayer)
563 m_PlaneLine.DrawLine(xLine, gPad->GetUymin(), xLine, gPad->GetUymax());
564 int section, layer;
566 layerGlobal, &section, &layer);
568 name = "B";
569 else
570 name = "F";
571 name += std::to_string(layer);
572 m_PlaneText.DrawText(xText, yText, name.c_str());
573 }
574 /* Then, color the canvas with red if there is a dead module
575 * and write an error message. */
576 if (m_DeadEndcapModules.size() == 0) {
579 for (KLMModuleNumber module : m_DeadEndcapModules) {
581 module, &moduleSubdetector, &moduleSection, &moduleSector, &moduleLayer);
582 alarm = "No data from " + m_ElementNumbers->getSectorDAQName(moduleSubdetector, moduleSection, moduleSector);
583 alarm += ", layer " + std::to_string(moduleLayer);
584 message_counter++;
585 if (message_counter <= m_MessageThreshold) {
586 latex.DrawLatexNDC(xAlarm, yAlarm, alarm.c_str());
587 yAlarm -= 0.05;
588 }
589 }
590 if (m_IsNullRun == false) {
592 }
593 } //end of high statistics condition
594 else {
596 }
597 }
598 if (message_counter > m_MessageThreshold) {
599 std::string verbose_string = " more messages";
600 verbose_string = std::to_string(message_counter - m_MessageThreshold) + verbose_string;
601 latex.DrawLatexNDC(xAlarm, yAlarm, verbose_string.c_str());
602 }
603 canvas->Modified();
604 canvas->Update();
605 }
606}
607
609{
610 /* If KLM is not included, stop here and return. */
611 TH1* daqInclusion = findHist(m_histogramDirectoryName + "/daq_inclusion");
612 if (not(daqInclusion == nullptr)) {
613 int isKlmIncluded = daqInclusion->GetBinContent(daqInclusion->GetXaxis()->FindBin("Yes"));
614 if (isKlmIncluded == 0)
615 return;
616 }
617 /* Make sure that the vectors are cleared at each DQM refresh. */
618 m_DeadBarrelModules.clear();
619 m_DeadEndcapModules.clear();
620 m_MaskedChannels.clear();
622 std::string str, histogramName, canvasName;
623 TLatex latex;
624 latex.SetTextColor(kRed);
625 latex.SetTextAlign(11);
627 // gathering relevant info for analyseChannelHitHistogram
628 for (KLMChannelIndex& klmSector : klmIndex) {
629 int nHistograms;
630 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
631 nHistograms = 2;
632 else
633 nHistograms = 3;
634 for (int j = 0; j < nHistograms; j++) {
635 str = "strip_hits_subdetector_" +
636 std::to_string(klmSector.getSubdetector()) +
637 "_section_" + std::to_string(klmSector.getSection()) +
638 "_sector_" + std::to_string(klmSector.getSector()) +
639 "_" + std::to_string(j);
640 histogramName = m_histogramDirectoryName + "/" + str;
641 canvasName = m_histogramDirectoryName + "/c_" + str;
642 TH1* histogram = findHist(histogramName);
643 //get delta histogram (should we work with a clone instead?)
644 auto delta = getDelta("", histogramName);
645
646 if (histogram == nullptr) {
647 B2WARNING("KLM DQM histogram " << histogramName << " is not found.");
648 continue;
649 }
650 TCanvas* canvas = findCanvas(canvasName);
651 if (canvas == nullptr) {
652 B2WARNING("KLM DQM histogram canvas " << canvasName << " is not found.");
653 continue;
654 }
655 // Add this canvas that it is time to update
656 // not sure if this is interfering with the generation of some features
657 // after testing, switch condition back to delta != nullptr || histogram != nullptr
658 UpdateCanvas(canvas->GetName(), true);
660 klmSector.getSubdetector(), klmSector.getSection(),
661 klmSector.getSector(), j, histogram, delta, canvas, latex);
662
663 }
664 }
665 /* Temporary change the color palette. */
666 gStyle->SetPalette(kLightTemperature);
668 for (KLMChannelIndex& klmSection : klmIndex) {
669 KLMSubdetectorNumber subdetector = klmSection.getSubdetector();
670 if (subdetector == KLMElementNumbers::c_EKLM) {
671 KLMSubdetectorNumber section = klmSection.getSection();
672 int maximalLayerNumber = m_EklmElementNumbers->getMaximalDetectorLayerNumber(section);
673 for (int j = 1; j <= maximalLayerNumber; ++j) {
674 str = "spatial_2d_hits_subdetector_" + std::to_string(subdetector) +
675 "_section_" + std::to_string(section) +
676 "_layer_" + std::to_string(j);
677 histogramName = m_histogramDirectoryName + "/" + str;
678 canvasName = m_histogramDirectoryName + "/c_" + str;
679 TH2F* histogram = static_cast<TH2F*>(findHist(histogramName));
680 if (histogram == nullptr) {
681 B2ERROR("KLM DQM histogram " << histogramName << " is not found.");
682 continue;
683 }
684 TCanvas* canvas = findCanvas(canvasName);
685 if (canvas == nullptr) {
686 B2ERROR("KLM DQM histogram canvas " << canvasName << " is not found.");
687 continue;
688 }
689 processSpatial2DHitEndcapHistogram(section, histogram, canvas);
690 }
691 }
692 }
693 /* Reset the color palette to the default one. */
694 gStyle->SetPalette(kBird);
695 fillMaskedChannelsHistogram("masked_channels");
696 latex.SetTextColor(kBlue);
697 processPlaneHistogram("plane_bklm_phi", latex);
698 processPlaneHistogram("plane_bklm_z", latex);
699 processPlaneHistogram("plane_eklm", latex);
700
701 processTimeHistogram("time_rpc");
702 processTimeHistogram("time_scintillator_bklm");
703 processTimeHistogram("time_scintillator_eklm");
704
705 B2DEBUG(20, "Updating EPICS PVs for DQMHistAnalysisKLM");
706 // only update PVs if there's enough statistics and datasize != 0
707 // Check if it's a null run, if so, don't update EPICS PVs
708 if (m_IsNullRun) {
709 B2INFO("DQMHistAnalysisKLM: Null run detected. No PV Update.");
710 return;
711 }
712 auto* daqDataSize = findHist("DAQ/KLMDataSize");
713 double meanDAQDataSize = 0.;
714 if (daqDataSize != nullptr) {
715 meanDAQDataSize = daqDataSize->GetMean();
716 } else
717 B2WARNING("DQMHistAnalysisKLM: Cannot find KLMDataSize");
718 if ((daqDataSize != nullptr) and (meanDAQDataSize != 0.)) {
720 setEpicsPV("MaskedChannels", (double)m_MaskedChannels.size());
721 setEpicsPV("DeadBarrelModules", (double)m_DeadBarrelModules.size());
722 setEpicsPV("DeadEndcapModules", (double)m_DeadEndcapModules.size());
723 B2DEBUG(20, "DQMHistAnalysisKLM: MaskedChannels " << m_MaskedChannels.size());
724 B2DEBUG(20, "DQMHistAnalysisKLM: DeadBarrelModules " << m_DeadBarrelModules.size());
725 B2DEBUG(20, "DQMHistAnalysisKLM: DeadEndcapModules " << m_DeadEndcapModules.size());
726 }
727 } else
728 B2INFO("DQMHistAnalysisKLM: KLM Not included. No PV Update. ");
729
730
731}
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.
static int getNStrips(int section, int sector, int layer, int plane)
Get number of strips.
std::string m_refFileName
Reference Histogram Root file name.
TLine m_PlaneLine
TLine for boundary in plane histograms.
double m_ProcessedEvents
Number of processed events.
void initialize() override final
Initializer.
int m_MessageThreshold
Message Threshold for expert pots.
int m_ThresholdForLog
Threshold for log scale.
double m_minEntries
Minimal number of entries for delta histogram update.
int m_MinHitsForFlagging
Minimal number of hits for flagging.
const KLMElementNumbers * m_ElementNumbers
KLM element numbers.
const EKLMElementNumbers * m_EklmElementNumbers
EKLM element numbers.
void processSpatial2DHitEndcapHistogram(uint16_t section, TH2F *histogram, TCanvas *canvas)
Process spatial 2D hits histograms for endcap.
MonitoringObject * m_monObj
Monitoring object.
void deltaDrawer(TH1 *delta, TH1 *histogram, TCanvas *canvas)
Scales and draws desired delta histogram for current canvas.
void processTimeHistogram(const std::string &histName)
Process histogram containing the hit times.
std::vector< uint16_t > m_MaskedChannels
Vector of masked channels.
void terminate() override final
This method is called at the end of the event processing.
void event() override final
This method is called for each event.
int m_ThresholdForHot
Threshold for hot channels.
std::vector< uint16_t > m_DeadBarrelModules
Vector of dead barrel modules.
std::string m_histogramDirectoryName
Name of histogram directory.
double m_MinProcessedEventsForMessagesInput
Input parameter for minimal number of processed events for error messages.
std::string m_refHistogramDirectoryPrefix
Prefix to account for reference file.
TText m_PlaneText
TText for names in plane histograms.
DBObjPtr< KLMElectronicsMap > m_ElectronicsMap
Electronics map.
void endRun() override final
This method is called if the current run ends.
void processPlaneHistogram(const std::string &histName, TLatex &latex)
Process histogram containing the number of hits in plane.
int m_ThresholdForMasked
Threshold for masked channels.
const KLMSectorArrayIndex * m_SectorArrayIndex
KLM sector array index.
void beginRun() override final
Called when entering a new run.
double m_MinProcessedEventsForMessages
Minimal number of processed events for error messages.
std::vector< uint16_t > m_DeadEndcapModules
Vector of dead endcap modules.
double getProcessedEvents()
Get number of processed events.
TLine m_2DHitsLine
TLine for background region in 2d hits histograms.
const KLMChannelArrayIndex * m_ChannelArrayIndex
KLM channel array index.
bool m_IsNullRun
Run type flag for null runs.
void analyseChannelHitHistogram(int subdetector, int section, int sector, int index, TH1 *histogram, TH1 *delta, TCanvas *canvas, TLatex &latex)
Analyse channel hit histogram.
void fillMaskedChannelsHistogram(const std::string &histName)
Fill histogram containing masked channels per sector.
TFile * m_refFile
The pointer to the reference file.
The base class for the histogram analysis module.
TCanvas * findCanvas(TString cname)
Find canvas by name.
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 Run Type.
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.
@ c_StatusTooFew
Not enough entries/event to judge.
@ c_StatusError
Analysis result: Severe issue found.
@ 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)
EKLM element numbers.
static constexpr int getNStripsSector()
Get number of strips in a sector.
static constexpr int getMaximalLayerGlobalNumber()
Get maximal detector layer global number.
int getMaximalDetectorLayerNumber(int section) const
Get maximal detector layer number.
void layerNumberToElementNumbers(int layerGlobal, int *section, int *layer) const
Get element numbers by detector layer global number.
static constexpr int getMaximalSectorNumber()
Get maximal sector number.
static constexpr int getMaximalPlaneNumber()
Get maximal plane number.
KLM channel array index.
KLM channel index.
void setIndexLevel(enum IndexLevel indexLevel)
Set index level.
BKLM electronics channel.
int getChannel() const
Get channel.
uint16_t getNumber(uint16_t index) const
Get element number.
uint16_t getIndex(uint16_t number) const
Get element index.
KLM element numbers.
KLMSectorNumber sectorNumberEKLM(int section, int sector) const
Get sector number for EKLM.
KLMChannelNumber channelNumber(int subdetector, int section, int sector, int layer, int plane, int strip) const
Get channel number.
void channelNumberToElementNumbers(KLMChannelNumber channel, int *subdetector, int *section, int *sector, int *layer, int *plane, int *strip) const
Get element numbers by channel number.
unsigned int getNChannelsModule(KLMModuleNumber module) const
Get number of channels in module.
void moduleNumberToElementNumbers(KLMModuleNumber module, int *subdetector, int *section, int *sector, int *layer) const
Get element numbers by module number.
KLMModuleNumber moduleNumber(int subdetector, int section, int sector, int layer) const
Get module number.
KLMSectorNumber sectorNumberBKLM(int section, int sector) const
Get sector number for BKLM.
std::string getSectorDAQName(int subdetector, int section, int sector) const
Get DAQ name for a given sector.
KLM sector array index.
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setVariable(const std::string &var, float val, float upErr=-1., float dwErr=-1)
set value to float variable (new variable is made if not yet existing)
Class to store variables with their name which were sent to the logging service.
TH2 * moduleHitMap(TH1 *hitMap, int moduleID)
Make hit map in HAPD view (12*12 channels).
Definition: hitMapMaker.cc:38
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
uint16_t KLMSectorNumber
Sector number.
uint16_t KLMChannelNumber
Channel number.
uint16_t KLMSubdetectorNumber
Subdetector number.
uint16_t KLMModuleNumber
Module number.
uint16_t KLMSectionNumber
Section number.
Abstract base class for different kinds of events.