Belle II Software development
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
56 m_2DHitsLine.SetLineColor(kRed);
57 m_2DHitsLine.SetLineWidth(3);
58 m_2DHitsLine.SetLineStyle(2); // dashed
59 m_PlaneLine.SetLineColor(kMagenta);
60 m_PlaneLine.SetLineWidth(1);
61 m_PlaneLine.SetLineStyle(2); // dashed
62 m_PlaneText.SetTextAlign(22); // centered, middle
63 m_PlaneText.SetTextColor(kMagenta);
64 m_PlaneText.SetTextFont(42); // Helvetica regular
65 m_PlaneText.SetTextSize(0.02); // 2% of TPad's full height
66}
67
68
70{
72
74 B2FATAL("The threshold used for hot channels is larger than the one for masked channels."
75 << LogVar("Threshold for hot channels", m_ThresholdForHot)
76 << LogVar("Threshold for masked channels", m_ThresholdForMasked));
77
78 // register plots for delta histogramming
79 addDeltaPar(m_histogramDirectoryName, "time_rpc", HistDelta::c_Entries, m_minEntries, 1);
80 addDeltaPar(m_histogramDirectoryName, "time_scintillator_bklm", HistDelta::c_Entries, m_minEntries, 1);
81 addDeltaPar(m_histogramDirectoryName, "time_scintillator_eklm", HistDelta::c_Entries, m_minEntries, 1);
82
83 //register EPICS PVs
84 registerEpicsPV("KLM:MaskedChannels", "MaskedChannels");
85 registerEpicsPV("KLM:DeadBarrelModules", "DeadBarrelModules");
86 registerEpicsPV("KLM:DeadEndcapModules", "DeadEndcapModules");
87
88 gROOT->cd();
89
90 std::string str;
92 for (KLMChannelIndex& klmSector : klmIndex) {
93 int nHistograms;
94 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
95 nHistograms = 2;
96 else
97 nHistograms = 3;
98 for (int j = 0; j < nHistograms; j++) {
99 str = "strip_hits_subdetector_" +
100 std::to_string(klmSector.getSubdetector()) +
101 "_section_" + std::to_string(klmSector.getSection()) +
102 "_sector_" + std::to_string(klmSector.getSector()) +
103 "_" + std::to_string(j);
104 addDeltaPar(m_histogramDirectoryName, str, HistDelta::c_Entries, m_minEntries, 1);
105
106 }
107 }
108
109}
110
112{
113}
114
116{
117 if (!m_ElectronicsMap.isValid())
118 B2FATAL("No KLM electronics map.");
121 m_DeadBarrelModules.clear();
122 m_DeadEndcapModules.clear();
123 m_MaskedChannels.clear();
124
125 m_IsNullRun = (getRunType() == "null");
126}
127
129{
130 int hist_max_bin; double max_position;
131 TH1* time_rpc = findHist(m_histogramDirectoryName + "/time_rpc");
132 if (time_rpc) {
133 hist_max_bin = time_rpc->GetMaximumBin();
134 max_position = time_rpc->GetXaxis()->GetBinCenter(hist_max_bin);
135 m_monObj->setVariable("RPC_Time_Peak", max_position);
136 }
137
138 TH1* time_scint_bklm = findHist(m_histogramDirectoryName + "/time_scintillator_bklm");
139 if (time_scint_bklm) {
140 hist_max_bin = time_scint_bklm->GetMaximumBin();
141 max_position = time_scint_bklm->GetXaxis()->GetBinCenter(hist_max_bin);
142 m_monObj->setVariable("BKLM_Scint_Time_Peak", max_position);
143 }
144
145 TH1* time_scint_eklm = findHist(m_histogramDirectoryName + "/time_scintillator_eklm");
146 if (time_scint_eklm) {
147 hist_max_bin = time_scint_eklm->GetMaximumBin();
148 max_position = time_scint_eklm->GetXaxis()->GetBinCenter(hist_max_bin);
149 m_monObj->setVariable("EKLM_Scint_Time_Peak", max_position);
150 }
151}
152
154{
156 B2WARNING("Either DAQ/Nevent is not found or Nevent = 0.");
157 /* Set the minimal number of processed events to 0 if we can't determine the processed events. */
159 }
161}
162
163void DQMHistAnalysisKLMModule::deltaDrawer(TH1* delta, TH1* histogram, TCanvas* canvas)
164{
165 if (delta != nullptr) {
166 Double_t scale = (Double_t) histogram->Integral(); //want delta and histo to have same norm
167
168 // delta != nullptr should take care of whether update condition is met.
169 delta->SetLineColor(kBlackBody); //random choice of not green or blue
170 delta->SetLineStyle(4);
171 delta->DrawNormalized("SAME", scale); //normalize delta to histo
172 canvas->Modified();
173 canvas->Update();
174 }
175}
176
178 int subdetector, int section, int sector, int index,
179 TH1* histogram, TH1* delta, TCanvas* canvas, TLatex& latex)
180{
181 double x = 0.15;
182 double y = 0.85;
183 int i, n;
184 std::map<KLMModuleNumber, double> moduleHitMap;
185 std::map<KLMModuleNumber, double>::iterator it;
186 double average = 0;
187 int channelSubdetector, channelSection, channelSector;
188 int layer, plane, strip;
189 std::string str;
190 canvas->Clear();
191 canvas->cd();
192 histogram->SetStats(false);
193 canvas->SetLogy(0); //initialize to start without logscale
194 histogram->Draw();
195 deltaDrawer(delta, histogram, canvas); //draw normalized delta on top
196 n = histogram->GetXaxis()->GetNbins();
197
198 /* call reference histograms from base class*/
199 TH1* ref_histogram = findRefHist(histogram->GetName(), ERefScaling::c_RefScaleEntries, histogram);
200 if (ref_histogram) {ref_histogram->Draw("hist,same");}
201 float ref_average = 0;
202
203 if (ref_histogram != nullptr) {
204 for (i = 1; i <= n; i++) {
205 double nHitsPerModuleRef = ref_histogram->GetBinContent(i);
206 ref_average = ref_average + nHitsPerModuleRef;
207 }
208 }
209
210 for (i = 1; i <= n; i++) {
211 KLMChannelNumber channelIndex = std::round(histogram->GetBinCenter(i));
212 KLMChannelNumber channelNumber =
213 m_ChannelArrayIndex->getNumber(channelIndex);
214 double nHitsPerModule = histogram->GetBinContent(i);
215 average = average + nHitsPerModule;
217 channelNumber, &channelSubdetector, &channelSection, &channelSector,
218 &layer, &plane, &strip);
219 if ((channelSubdetector != subdetector) ||
220 (channelSection != section) ||
221 (channelSector != sector))
222 B2FATAL("Inconsistent element numbers.");
224 subdetector, section, sector, layer);
225 it = moduleHitMap.find(module);
226 if (it == moduleHitMap.end()) {
227 moduleHitMap.insert(std::pair<KLMModuleNumber, double>(
228 module, nHitsPerModule));
229 } else {
230 it->second += nHitsPerModule;
231 }
232 }
233 unsigned int activeModuleChannels = 0;
234 int message_counter = 0;
235 for (it = moduleHitMap.begin(); it != moduleHitMap.end(); ++it) {
236 KLMModuleNumber moduleNumber = it->first;
237 if (it->second != 0) {
238 activeModuleChannels += m_ElementNumbers->getNChannelsModule(moduleNumber);
239 continue;
240 }
242 moduleNumber, &channelSubdetector, &channelSection, &channelSector, &layer);
243 /* Channel with plane = 1, strip = 1 exists for any BKLM or EKLM module. */
244 KLMChannelNumber channel =
246 channelSubdetector, channelSection, channelSector, layer, 1, 1);
247 const KLMElectronicsChannel* electronicsChannel =
248 m_ElectronicsMap->getElectronicsChannel(channel);
249 if (electronicsChannel == nullptr)
250 B2FATAL("Incomplete KLM electronics map.");
251 str = "No data from lane " + std::to_string(electronicsChannel->getLane());
252 latex.DrawLatexNDC(x, y, str.c_str());
253 y -= 0.05;
254 message_counter++;
255 /* Store the module number, used later in processPlaneHistogram
256 * to color the canvas with red and to raise up an alarm. */
257 if (channelSubdetector == KLMElementNumbers::c_BKLM) {
258 std::vector<KLMModuleNumber>::iterator ite =
259 std::find(m_DeadBarrelModules.begin(),
261 moduleNumber);
262 if (ite == m_DeadBarrelModules.end())
263 m_DeadBarrelModules.push_back(moduleNumber);
264 } else {
265 std::vector<KLMModuleNumber>::iterator ite = std::find(m_DeadEndcapModules.begin(),
267 moduleNumber);
268 if (ite == m_DeadEndcapModules.end())
269 m_DeadEndcapModules.push_back(moduleNumber);
270 }
271 }
272 if (activeModuleChannels == 0)
273 return;
274 average /= activeModuleChannels;
275 ref_average /= activeModuleChannels;
276
277 for (i = 1; i <= n; ++i) {
278 KLMChannelNumber channelIndex = std::round(histogram->GetBinCenter(i));
279 KLMChannelNumber channelNumber =
280 m_ChannelArrayIndex->getNumber(channelIndex);
281 double nHits = histogram->GetBinContent(i);
283 channelNumber, &channelSubdetector, &channelSection, &channelSector,
284 &layer, &plane, &strip);
285 std::string channelStatus = "Normal";
286 if ((nHits > average * m_ThresholdForMasked) && (nHits > m_MinHitsForFlagging)) {
287 channelStatus = "Masked";
288 std::vector<KLMModuleNumber>::iterator ite =
289 std::find(m_MaskedChannels.begin(),
290 m_MaskedChannels.end(),
291 channelNumber);
292 if (ite == m_MaskedChannels.end())
293 m_MaskedChannels.push_back(channelNumber);
294 B2DEBUG(20, "KLM@MaskMe " << channelNumber);
295 } else if ((nHits > average * m_ThresholdForHot) && (nHits > m_MinHitsForFlagging)) {
296 channelStatus = "Hot";
297 }
298 if (channelStatus != "Normal") {
299 const KLMElectronicsChannel* electronicsChannel =
300 m_ElectronicsMap->getElectronicsChannel(channelNumber);
301 if (electronicsChannel == nullptr)
302 B2FATAL("Incomplete BKLM electronics map.");
303 if (channelStatus == "Masked") {
304 histogram->SetBinContent(i, 0);
305 if (delta != nullptr)
306 delta->SetBinContent(i, 0);
307 }
308 str = channelStatus + " channel: ";
309 // lane, axis, channel
310 str += ("L" + std::to_string(electronicsChannel->getLane()) +
311 " A" + std::to_string(electronicsChannel->getAxis()) +
312 " Ch" + std::to_string(electronicsChannel->getChannel()));
313 message_counter++;
314 if (message_counter <= m_MessageThreshold) {
315 latex.DrawLatexNDC(x, y, str.c_str());
316 y -= 0.05;
317 }
318 }
319 }
320 if (message_counter > m_MessageThreshold) {
321 std::string verbose_message = " more messages";
322 verbose_message = std::to_string(message_counter - m_MessageThreshold) + verbose_message;
323 latex.DrawLatexNDC(x, y, verbose_message.c_str());
324 }
325
326
327 // for hot/masked channels, log scale plots (reference and main)
328 if (histogram->GetMaximum()*n > histogram->Integral()*m_ThresholdForLog && average * activeModuleChannels > m_MinHitsForFlagging) {
329 histogram->SetMinimum(1);
330 canvas->SetLogy();
331 } else if (ref_histogram != nullptr) {
332 if (ref_histogram->GetMaximum()*n > ref_histogram->Integral()*m_ThresholdForLog
333 && ref_average * activeModuleChannels > m_MinHitsForFlagging) {
334 histogram->SetMinimum(1);
335 canvas->SetLogy();
336 } else
337 canvas->SetLogy(0);
338 } else
339 canvas->SetLogy(0);
340
341 canvas->Modified();
342 canvas->Update();
343
344 /* Drawing dividing lines */
345 int divisions;
346 int bin = 1;
347 double xLine;
348 // drawing lines for BKLM sectors
349 if (subdetector == 1) {
350 int shift;
351 if (index == 0) {
352 divisions = 7;
353 shift = 1;
354 } else {
357 }
358 for (int k = 0; k < divisions; k++) {
359 xLine = (histogram->GetXaxis()->GetBinLowEdge(bin) - canvas->GetX1()) / (canvas->GetX2() - canvas->GetX1());
360 m_PlaneLine.DrawLineNDC(xLine, 0.1, xLine, 0.9);
361 bin += BKLMElementNumbers::getNStrips(section, sector, k + shift, 0)
362 + BKLMElementNumbers::getNStrips(section, sector, k + shift, 1);
363 }
364 } else { // drawing lines for EKLM sectors
365 if ((section == 2) && (index == 0 || index == 1))
366 divisions = 5;
367 else
368 divisions = 4;
369 for (int k = 0; k < divisions; k++) {
370 xLine = (histogram->GetXaxis()->GetBinLowEdge(bin) - canvas->GetX1()) / (canvas->GetX2() - canvas->GetX1());
371 m_PlaneLine.DrawLineNDC(xLine, 0.1, xLine, 0.9);
373 }
374 }
375 canvas->Modified();
376 canvas->Update();
377
378}
379
381 KLMSectionNumber section, TH2F* histogram, TCanvas* canvas)
382{
383 canvas->Clear();
384 canvas->cd();
385 histogram->SetStats(false);
386 histogram->Draw("COLZ");
387 /* Draw the lines only for the backward layers. */
389 m_2DHitsLine.DrawLine(-110, 80, -110, 190);
390 m_2DHitsLine.DrawLine(-110, 190, 110, 190);
391 m_2DHitsLine.DrawLine(110, 80, 110, 190);
392 m_2DHitsLine.DrawLine(-110, 80, 110, 80);
393 }
394 canvas->Modified();
395 canvas->Update();
396}
397
399 const std::string& histName)
400{
401 TH1* histogram = findHist(m_histogramDirectoryName + "/" + histName);
402 if (histogram == nullptr) {
403 B2WARNING("KLM DQM histogram " + m_histogramDirectoryName + "/" << histName << " is not found.");
404 return;
405 }
406
407 TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
408 if (canvas == nullptr) {
409 B2WARNING("KLM DQM histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
410 return;
411 }
412
413 else {
414 canvas->Clear();
415 canvas->cd();
416 histogram->Draw();
417 /* calling on delta histogram*/
418 TH1* delta = getDelta(m_histogramDirectoryName, histName);
419 UpdateCanvas(canvas->GetName(), delta != nullptr); //keeping this for testing purposes
420 if (delta != nullptr) {
421 B2INFO("DQMHistAnalysisKLM: Time Delta Entries is " << delta->GetEntries());
422 deltaDrawer(delta, histogram, canvas);
423 }
424 //reference check
425 TH1* ref = findRefHist(histogram->GetName(), ERefScaling::c_RefScaleEntries, histogram);
426 if (ref) {ref->Draw("hist,same");}
427 }
428}
429
431 const std::string& histName)
432{
433 TH1* histogram = findHist(m_histogramDirectoryName + "/" + histName);
434 if (histogram == nullptr) {
435 B2WARNING("KLM DQM histogram " + m_histogramDirectoryName + "/" << histName << " is not found.");
436 return;
437 }
438 TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
439 if (canvas == nullptr) {
440 B2WARNING("KLM DQM histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
441 return;
442 }
443
444 histogram->Clear();
445 canvas->Clear();
446 canvas->cd();
447 if (m_MaskedChannels.size() > 0) {
448 int channelSubdetector, channelSection, channelSector;
449 int layer, plane, strip;
450 for (KLMChannelNumber channel : m_MaskedChannels) {
452 channel, &channelSubdetector, &channelSection, &channelSector,
453 &layer, &plane, &strip);
454 KLMSectorNumber sectorNumber;
455 if (channelSubdetector == KLMElementNumbers::c_BKLM)
456 sectorNumber = m_ElementNumbers->sectorNumberBKLM(channelSection, channelSector);
457 else
458 sectorNumber = m_ElementNumbers->sectorNumberEKLM(channelSection, channelSector);
459 KLMSectorNumber sectorIndex = m_SectorArrayIndex->getIndex(sectorNumber);
460 histogram->Fill(sectorIndex);
461 }
462 }
463 histogram->SetStats(false);
464 histogram->Draw();
465 canvas->Modified();
466 canvas->Update();
467}
468
470 const std::string& histName, TLatex& latex)
471{
472
473 TH1* histogram = findHist(m_histogramDirectoryName + "/" + histName);
474 if (histogram == nullptr) {
475 B2WARNING("KLM DQM histogram " + m_histogramDirectoryName + "/" << histName << " is not found.");
476 return;
477 }
478 TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
479 if (canvas == nullptr) {
480 B2WARNING("KLM DQM histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
481 return;
482 } else {
483 std::string name, alarm;
484 int moduleSubdetector, moduleSection, moduleSector, moduleLayer;
485 double xAlarm = 0.15;
486 double yAlarm = 0.8;
487 canvas->Clear();
488 canvas->cd();
489 histogram->SetStats(false);
490 histogram->Draw();
491 //reference check
492 TH1* ref = findRefHist(histogram->GetName(), ERefScaling::c_RefScaleEntries, histogram);
493 if (ref) {ref->Draw("hist,same");}
494
495 int message_counter = 0;
496 if (histName.find("bklm") != std::string::npos) {
497 /* First draw the vertical lines and the sector names. */
498 const int maximalLayer = BKLMElementNumbers::getMaximalLayerNumber();
499 for (int sector = 0; sector < BKLMElementNumbers::getMaximalSectorGlobalNumber(); ++sector) {
500 int bin = maximalLayer * sector + 1;
501 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
502 double xText = histogram->GetXaxis()->GetBinLowEdge(bin + maximalLayer / 2);
503 double yText = gPad->GetUymin() + 0.98 * (gPad->GetUymax() - gPad->GetUymin());
504 if (sector > 0)
505 m_PlaneLine.DrawLine(xLine, gPad->GetUymin(), xLine, gPad->GetUymax());
506 name = "B";
508 name += "B";
509 else
510 name += "F";
511 name += std::to_string(sector % BKLMElementNumbers::getMaximalSectorNumber());
512 m_PlaneText.DrawText(xText, yText, name.c_str());
513 }
514 /* Then, color the canvas with red if there is a dead module
515 * and write an error message. */
516 if (m_DeadBarrelModules.size() == 0) {
519 for (KLMModuleNumber module : m_DeadBarrelModules) {
521 module, &moduleSubdetector, &moduleSection, &moduleSector, &moduleLayer);
522 alarm = "No data from " + m_ElementNumbers->getSectorDAQName(moduleSubdetector, moduleSection, moduleSector);
523 alarm += ", layer " + std::to_string(moduleLayer);
524 message_counter++;
525 if (message_counter <= m_MessageThreshold) {
526 latex.DrawLatexNDC(xAlarm, yAlarm, alarm.c_str());
527 yAlarm -= 0.05;
528 }
529 }
530 if (m_IsNullRun == false) {
532 }
533 } //end of enough statistics condition
534 else {
536 }
537 } else {
538 /* First draw the vertical lines and the sector names. */
539 const double maximalLayer = EKLMElementNumbers::getMaximalLayerGlobalNumber();
541 for (int layerGlobal = 1; layerGlobal <= maximalLayer; ++layerGlobal) {
542 int bin = maxPlane * layerGlobal + 1;
543 double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
544 double xText = histogram->GetXaxis()->GetBinLowEdge(bin - maxPlane / 2);
545 double yText = gPad->GetUymin() + 0.98 * (gPad->GetUymax() - gPad->GetUymin());
546 if (layerGlobal < maximalLayer)
547 m_PlaneLine.DrawLine(xLine, gPad->GetUymin(), xLine, gPad->GetUymax());
548 int section, layer;
550 layerGlobal, &section, &layer);
552 name = "B";
553 else
554 name = "F";
555 name += std::to_string(layer);
556 m_PlaneText.DrawText(xText, yText, name.c_str());
557 }
558 /* Then, color the canvas with red if there is a dead module
559 * and write an error message. */
560 if (m_DeadEndcapModules.size() == 0) {
563 for (KLMModuleNumber module : m_DeadEndcapModules) {
565 module, &moduleSubdetector, &moduleSection, &moduleSector, &moduleLayer);
566 alarm = "No data from " + m_ElementNumbers->getSectorDAQName(moduleSubdetector, moduleSection, moduleSector);
567 alarm += ", layer " + std::to_string(moduleLayer);
568 message_counter++;
569 if (message_counter <= m_MessageThreshold) {
570 latex.DrawLatexNDC(xAlarm, yAlarm, alarm.c_str());
571 yAlarm -= 0.05;
572 }
573 }
574 if (m_IsNullRun == false) {
576 }
577 } //end of high statistics condition
578 else {
580 }
581 }
582 if (message_counter > m_MessageThreshold) {
583 std::string verbose_string = " more messages";
584 verbose_string = std::to_string(message_counter - m_MessageThreshold) + verbose_string;
585 latex.DrawLatexNDC(xAlarm, yAlarm, verbose_string.c_str());
586 }
587 canvas->Modified();
588 canvas->Update();
589 }
590}
591
593{
594 /* If KLM is not included, stop here and return. */
595 TH1* daqInclusion = findHist(m_histogramDirectoryName + "/daq_inclusion");
596 if (not(daqInclusion == nullptr)) {
597 int isKlmIncluded = daqInclusion->GetBinContent(daqInclusion->GetXaxis()->FindBin("Yes"));
598 if (isKlmIncluded == 0)
599 return;
600 }
601 /* Make sure that the vectors are cleared at each DQM refresh. */
602 m_DeadBarrelModules.clear();
603 m_DeadEndcapModules.clear();
604 m_MaskedChannels.clear();
606 std::string str, histogramName, canvasName;
607 TLatex latex;
608 latex.SetTextColor(kRed);
609 latex.SetTextAlign(11);
611 // gathering relevant info for analyseChannelHitHistogram
612 for (KLMChannelIndex& klmSector : klmIndex) {
613 int nHistograms;
614 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
615 nHistograms = 2;
616 else
617 nHistograms = 3;
618 for (int j = 0; j < nHistograms; j++) {
619 str = "strip_hits_subdetector_" +
620 std::to_string(klmSector.getSubdetector()) +
621 "_section_" + std::to_string(klmSector.getSection()) +
622 "_sector_" + std::to_string(klmSector.getSector()) +
623 "_" + std::to_string(j);
624 histogramName = m_histogramDirectoryName + "/" + str;
625 canvasName = m_histogramDirectoryName + "/c_" + str;
626 TH1* histogram = findHist(histogramName);
627 //get delta histogram (should we work with a clone instead?)
628 auto delta = getDelta("", histogramName);
629
630 if (histogram == nullptr) {
631 B2WARNING("KLM DQM histogram " << histogramName << " is not found.");
632 continue;
633 }
634 TCanvas* canvas = findCanvas(canvasName);
635 if (canvas == nullptr) {
636 B2WARNING("KLM DQM histogram canvas " << canvasName << " is not found.");
637 continue;
638 }
639 // Add this canvas that it is time to update
640 // not sure if this is interfering with the generation of some features
641 // after testing, switch condition back to delta != nullptr || histogram != nullptr
642 UpdateCanvas(canvas->GetName(), true);
644 klmSector.getSubdetector(), klmSector.getSection(),
645 klmSector.getSector(), j, histogram, delta, canvas, latex);
646
647 }
648 }
649 /* Temporary change the color palette. */
650 gStyle->SetPalette(kLightTemperature);
652 for (KLMChannelIndex& klmSection : klmIndex) {
653 KLMSubdetectorNumber subdetector = klmSection.getSubdetector();
654 if (subdetector == KLMElementNumbers::c_EKLM) {
655 KLMSubdetectorNumber section = klmSection.getSection();
656 int maximalLayerNumber = m_EklmElementNumbers->getMaximalDetectorLayerNumber(section);
657 for (int j = 1; j <= maximalLayerNumber; ++j) {
658 str = "spatial_2d_hits_subdetector_" + std::to_string(subdetector) +
659 "_section_" + std::to_string(section) +
660 "_layer_" + std::to_string(j);
661 histogramName = m_histogramDirectoryName + "/" + str;
662 canvasName = m_histogramDirectoryName + "/c_" + str;
663 TH2F* histogram = static_cast<TH2F*>(findHist(histogramName));
664 if (histogram == nullptr) {
665 B2ERROR("KLM DQM histogram " << histogramName << " is not found.");
666 continue;
667 }
668 TCanvas* canvas = findCanvas(canvasName);
669 if (canvas == nullptr) {
670 B2ERROR("KLM DQM histogram canvas " << canvasName << " is not found.");
671 continue;
672 }
673 processSpatial2DHitEndcapHistogram(section, histogram, canvas);
674 }
675 }
676 }
677 /* Reset the color palette to the default one. */
678 gStyle->SetPalette(kBird);
679 fillMaskedChannelsHistogram("masked_channels");
680 latex.SetTextColor(kBlue);
681 processPlaneHistogram("plane_bklm_phi", latex);
682 processPlaneHistogram("plane_bklm_z", latex);
683 processPlaneHistogram("plane_eklm", latex);
684
685 processTimeHistogram("time_rpc");
686 processTimeHistogram("time_scintillator_bklm");
687 processTimeHistogram("time_scintillator_eklm");
688
689 B2DEBUG(20, "Updating EPICS PVs for DQMHistAnalysisKLM");
690 // only update PVs if there's enough statistics and datasize != 0
691 // Check if it's a null run, if so, don't update EPICS PVs
692 if (m_IsNullRun) {
693 B2INFO("DQMHistAnalysisKLM: Null run detected. No PV Update.");
694 return;
695 }
696 auto* daqDataSize = findHist("DAQ/KLMDataSize");
697 double meanDAQDataSize = 0.;
698 if (daqDataSize != nullptr) {
699 meanDAQDataSize = daqDataSize->GetMean();
700 } else
701 B2WARNING("DQMHistAnalysisKLM: Cannot find KLMDataSize");
702 if ((daqDataSize != nullptr) and (meanDAQDataSize != 0.)) {
704 setEpicsPV("MaskedChannels", (double)m_MaskedChannels.size());
705 setEpicsPV("DeadBarrelModules", (double)m_DeadBarrelModules.size());
706 setEpicsPV("DeadEndcapModules", (double)m_DeadEndcapModules.size());
707 B2DEBUG(20, "DQMHistAnalysisKLM: MaskedChannels " << m_MaskedChannels.size());
708 B2DEBUG(20, "DQMHistAnalysisKLM: DeadBarrelModules " << m_DeadBarrelModules.size());
709 B2DEBUG(20, "DQMHistAnalysisKLM: DeadEndcapModules " << m_DeadEndcapModules.size());
710 }
711 } else
712 B2INFO("DQMHistAnalysisKLM: KLM Not included. No PV Update. ");
713
714
715}
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.
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.
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.
The base class for the histogram analysis module.
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 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.
@ c_RefScaleEntries
to number of entries (integral)
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.