Belle II Software  release-08-01-10
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 
23 using namespace Belle2;
24 
25 REG_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", 500000.);
51  addParam("HistogramDirectoryName", m_histogramDirectoryName, "Name of histogram directory", std::string("KLM"));
52  addParam("RefHistoFile", m_refFileName, "Reference histogram file name", std::string("KLM_DQM_REF_BEAM.root"));
53 
55  m_2DHitsLine.SetLineColor(kRed);
56  m_2DHitsLine.SetLineWidth(3);
57  m_2DHitsLine.SetLineStyle(2); // dashed
58  m_PlaneLine.SetLineColor(kMagenta);
59  m_PlaneLine.SetLineWidth(1);
60  m_PlaneLine.SetLineStyle(2); // dashed
61  m_PlaneText.SetTextAlign(22); // centered, middle
62  m_PlaneText.SetTextColor(kMagenta);
63  m_PlaneText.SetTextFont(42); // Helvetica regular
64  m_PlaneText.SetTextSize(0.02); // 2% of TPad's full height
65 }
66 
67 
69 {
71 
73  B2FATAL("The threshold used for hot channels is larger than the one for masked channels."
74  << LogVar("Threshold for hot channels", m_ThresholdForHot)
75  << LogVar("Threshold for masked channels", m_ThresholdForMasked));
76 
77  if (m_refFileName != "") {
78  m_refFile = TFile::Open(m_refFileName.data(), "READ");
79  }
80 
81  // register plots for delta histogramming
82  addDeltaPar(m_histogramDirectoryName, "time_rpc", HistDelta::c_Entries, m_minEntries, 1);
83  addDeltaPar(m_histogramDirectoryName, "time_scintillator_bklm", HistDelta::c_Entries, m_minEntries, 1);
84  addDeltaPar(m_histogramDirectoryName, "time_scintillator_eklm", HistDelta::c_Entries, m_minEntries, 1);
85 
86  //register EPICS PVs
87  registerEpicsPV("KLM:MaskedChannels", "MaskedChannels");
88  registerEpicsPV("KLM:DeadBarrelModules", "DeadBarrelModules");
89  registerEpicsPV("KLM:DeadEndcapModules", "DeadEndcapModules");
90  updateEpicsPVs(5.0);
91 
92  gROOT->cd();
93 
94  std::string str;
96  for (KLMChannelIndex& klmSector : klmIndex) {
97  int nHistograms;
98  if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
99  nHistograms = 2;
100  else
101  nHistograms = 3;
102  for (int j = 0; j < nHistograms; j++) {
103  str = "strip_hits_subdetector_" +
104  std::to_string(klmSector.getSubdetector()) +
105  "_section_" + std::to_string(klmSector.getSection()) +
106  "_sector_" + std::to_string(klmSector.getSector()) +
107  "_" + std::to_string(j);
108  addDeltaPar(m_histogramDirectoryName, str, HistDelta::c_Entries, m_minEntries, 1);
109 
110  }
111  }
112 
113 
114  //search for reference
115  if (m_refFile && m_refFile->IsOpen()) {
116  B2INFO("KLM DQMHistAnalysis: reference root file (" << m_refFileName << ") FOUND, able to read ref histograms");
117 
118  } else
119  B2WARNING("KLM DQMHistAnalysis: reference root file (" << m_refFileName << ") not found, or closed");
120 }
121 
123 {
124  if (m_refFile) {
125  m_refFile->Close();
126  delete m_refFile;
127  }
128 }
129 
131 {
132  if (!m_ElectronicsMap.isValid())
133  B2FATAL("No KLM electronics map.");
135  m_ProcessedEvents = 0.;
136  m_DeadBarrelModules.clear();
137  m_DeadEndcapModules.clear();
138  m_MaskedChannels.clear();
139 
140  m_IsNullRun = (getRunType() == "null");
141 }
142 
144 {
145  int hist_max_bin; double max_position;
146  TH1* time_rpc = findHist(m_histogramDirectoryName + "/time_rpc");
147  if (time_rpc) {
148  hist_max_bin = time_rpc->GetMaximumBin();
149  max_position = time_rpc->GetXaxis()->GetBinCenter(hist_max_bin);
150  m_monObj->setVariable("RPC_Time_Peak", max_position);
151  }
152 
153  TH1* time_scint_bklm = findHist(m_histogramDirectoryName + "/time_scintillator_bklm");
154  if (time_scint_bklm) {
155  hist_max_bin = time_scint_bklm->GetMaximumBin();
156  max_position = time_scint_bklm->GetXaxis()->GetBinCenter(hist_max_bin);
157  m_monObj->setVariable("BKLM_Scint_Time_Peak", max_position);
158  }
159 
160  TH1* time_scint_eklm = findHist(m_histogramDirectoryName + "/time_scintillator_bklm");
161  if (time_scint_eklm) {
162  hist_max_bin = time_scint_eklm->GetMaximumBin();
163  max_position = time_scint_eklm->GetXaxis()->GetBinCenter(hist_max_bin);
164  m_monObj->setVariable("EKLM_Scint_Time_Peak", max_position);
165  }
166 }
167 
169 {
171  B2WARNING("Either DAQ/Nevent is not found or Nevent = 0.");
172  /* Set the minimal number of processed events to 0 if we can't determine the processed events. */
174  }
176 }
177 
178 void DQMHistAnalysisKLMModule::deltaDrawer(TH1* delta, TH1* histogram, TCanvas* canvas)
179 {
180  if (delta != nullptr) {
181  auto scale = delta->Integral();
182  if (scale > 0. && histogram->Integral() > 0) scale = histogram->Integral() / delta->Integral();
183  else scale = 1.0;
184 
185  // delta != nullptr should take care of whether update condition is met.
186  delta->DrawNormalized("SAME", scale);
187  canvas->Modified();
188  canvas->Update();
189  }
190 }
191 
193  int subdetector, int section, int sector, int index,
194  TH1* histogram, TH1* delta, TCanvas* canvas, TLatex& latex)
195 {
196  double x = 0.15;
197  double y = 0.85;
198  int i, n;
199  std::map<KLMModuleNumber, double> moduleHitMap;
200  std::map<KLMModuleNumber, double>::iterator it;
201  double average = 0;
202  int channelSubdetector, channelSection, channelSector;
203  int layer, plane, strip;
204  std::string str;
205  canvas->Clear();
206  canvas->cd();
207  histogram->SetStats(false);
208  canvas->SetLogy(0); //initialize to start without logscale
209  histogram->Draw();
210  deltaDrawer(delta, histogram, canvas); //draw normalized delta on top
211  n = histogram->GetXaxis()->GetNbins();
212 
213  /* call reference histograms */
214  TH1* ref_histogram = nullptr;
215  float ref_average = 0;
216  if (m_refFile && m_refFile->IsOpen()) {
217  ref_histogram = (TH1*)m_refFile->Get(histogram->GetName());
218  if (!ref_histogram) {
219  B2WARNING("Unable to find " << histogram->GetName() << "in reference file.");
220  }
221  }
222 
223  if (ref_histogram != nullptr) {
224  for (i = 1; i <= n; i++) {
225  double nHitsPerModuleRef = ref_histogram->GetBinContent(i);
226  ref_average = ref_average + nHitsPerModuleRef;
227  }
228  }
229 
230  for (i = 1; i <= n; i++) {
231  KLMChannelNumber channelIndex = std::round(histogram->GetBinCenter(i));
232  KLMChannelNumber channelNumber =
233  m_ChannelArrayIndex->getNumber(channelIndex);
234  double nHitsPerModule = histogram->GetBinContent(i);
235  average = average + nHitsPerModule;
237  channelNumber, &channelSubdetector, &channelSection, &channelSector,
238  &layer, &plane, &strip);
239  if ((channelSubdetector != subdetector) ||
240  (channelSection != section) ||
241  (channelSector != sector))
242  B2FATAL("Inconsistent element numbers.");
244  subdetector, section, sector, layer);
245  it = moduleHitMap.find(module);
246  if (it == moduleHitMap.end()) {
247  moduleHitMap.insert(std::pair<KLMModuleNumber, double>(
248  module, nHitsPerModule));
249  } else {
250  it->second += nHitsPerModule;
251  }
252  }
253  unsigned int activeModuleChannels = 0;
254  for (it = moduleHitMap.begin(); it != moduleHitMap.end(); ++it) {
255  KLMModuleNumber moduleNumber = it->first;
256  if (it->second != 0) {
257  activeModuleChannels += m_ElementNumbers->getNChannelsModule(moduleNumber);
258  continue;
259  }
261  moduleNumber, &channelSubdetector, &channelSection, &channelSector, &layer);
262  /* Channel with plane = 1, strip = 1 exists for any BKLM or EKLM module. */
263  KLMChannelNumber channel =
265  channelSubdetector, channelSection, channelSector, layer, 1, 1);
266  const KLMElectronicsChannel* electronicsChannel =
267  m_ElectronicsMap->getElectronicsChannel(channel);
268  if (electronicsChannel == nullptr)
269  B2FATAL("Incomplete KLM electronics map.");
270  str = "No data from lane " + std::to_string(electronicsChannel->getLane());
271  latex.DrawLatexNDC(x, y, str.c_str());
272  y -= 0.05;
273  /* Store the module number, used later in processPlaneHistogram
274  * to color the canvas with red and to raise up an alarm. */
275  if (channelSubdetector == KLMElementNumbers::c_BKLM) {
276  std::vector<KLMModuleNumber>::iterator ite =
277  std::find(m_DeadBarrelModules.begin(),
278  m_DeadBarrelModules.end(),
279  moduleNumber);
280  if (ite == m_DeadBarrelModules.end())
281  m_DeadBarrelModules.push_back(moduleNumber);
282  } else {
283  std::vector<KLMModuleNumber>::iterator ite = std::find(m_DeadEndcapModules.begin(),
284  m_DeadEndcapModules.end(),
285  moduleNumber);
286  if (ite == m_DeadEndcapModules.end())
287  m_DeadEndcapModules.push_back(moduleNumber);
288  }
289  }
290  if (activeModuleChannels == 0)
291  return;
292  average /= activeModuleChannels;
293  ref_average /= activeModuleChannels;
294  for (i = 1; i <= n; ++i) {
295  KLMChannelNumber channelIndex = std::round(histogram->GetBinCenter(i));
296  KLMChannelNumber channelNumber =
297  m_ChannelArrayIndex->getNumber(channelIndex);
298  double nHits = histogram->GetBinContent(i);
300  channelNumber, &channelSubdetector, &channelSection, &channelSector,
301  &layer, &plane, &strip);
302  std::string channelStatus = "Normal";
303  if ((nHits > average * m_ThresholdForMasked) && (nHits > m_MinHitsForFlagging)) {
304  channelStatus = "Masked";
305  std::vector<KLMModuleNumber>::iterator ite =
306  std::find(m_MaskedChannels.begin(),
307  m_MaskedChannels.end(),
308  channelNumber);
309  if (ite == m_MaskedChannels.end())
310  m_MaskedChannels.push_back(channelNumber);
311  B2DEBUG(20, "KLM@MaskMe " << channelNumber);
312  } else if ((nHits > average * m_ThresholdForHot) && (nHits > m_MinHitsForFlagging)) {
313  channelStatus = "Hot";
314  }
315  if (channelStatus != "Normal") {
316  const KLMElectronicsChannel* electronicsChannel =
317  m_ElectronicsMap->getElectronicsChannel(channelNumber);
318  if (electronicsChannel == nullptr)
319  B2FATAL("Incomplete BKLM electronics map.");
320  if (channelStatus == "Masked") {
321  histogram->SetBinContent(i, 0);
322  if (delta != nullptr)
323  delta->SetBinContent(i, 0);
324  }
325  str = channelStatus + " channel: ";
326  // lane, axis, channel
327  str += ("L" + std::to_string(electronicsChannel->getLane()) +
328  " A" + std::to_string(electronicsChannel->getAxis()) +
329  " Ch" + std::to_string(electronicsChannel->getChannel()));
330  latex.DrawLatexNDC(x, y, str.c_str());
331  y -= 0.05;
332  }
333  }
334 
335  if (histogram->GetMaximum()*n > histogram->Integral()*m_ThresholdForLog && average * activeModuleChannels > m_MinHitsForFlagging) {
336  histogram->SetMinimum(1);
337  canvas->SetLogy();
338  } else if (ref_histogram != nullptr) {
339  if (ref_histogram->GetMaximum()*n > ref_histogram->Integral()*m_ThresholdForLog
340  && ref_average * activeModuleChannels > m_MinHitsForFlagging) {
341  histogram->SetMinimum(1);
342  canvas->SetLogy();
343  } else
344  canvas->SetLogy(0);
345  } else
346  canvas->SetLogy(0);
347 
348  canvas->Modified();
349  canvas->Update();
350 
351  /* Drawing dividing lines */
352  int divisions;
353  int bin = 1;
354  double xLine;
355  if (subdetector == 1) {
356  int shift;
357  if (index == 0) {
358  divisions = 7;
359  shift = 1;
360  } else {
361  divisions = 8;
362  shift = 8;
363  }
364  for (int k = 0; k < divisions; k++) {
365  xLine = (histogram->GetXaxis()->GetBinLowEdge(bin) - canvas->GetX1()) / (canvas->GetX2() - canvas->GetX1());
366  m_PlaneLine.DrawLineNDC(xLine, 0.1, xLine, 0.9);
367  bin += BKLMElementNumbers::getNStrips(section, sector, k + shift, 0)
368  + BKLMElementNumbers::getNStrips(section, sector, k + shift, 1);
369  }
370  } else {
371  if ((section == 2) && (index == 0 || index == 1))
372  divisions = 5;
373  else
374  divisions = 4;
375  for (int k = 0; k < divisions; k++) {
376  xLine = (histogram->GetXaxis()->GetBinLowEdge(bin) - canvas->GetX1()) / (canvas->GetX2() - canvas->GetX1());
377  m_PlaneLine.DrawLineNDC(xLine, 0.1, xLine, 0.9);
379  }
380  }
381  canvas->Modified();
382  canvas->Update();
383 
384 }
385 
387  KLMSectionNumber section, TH2F* histogram, TCanvas* canvas)
388 {
389  canvas->Clear();
390  canvas->cd();
391  histogram->SetStats(false);
392  histogram->Draw("COLZ");
393  /* Draw the lines only for the backward layers. */
394  if (section == EKLMElementNumbers::c_ForwardSection) {
395  m_2DHitsLine.DrawLine(-110, 80, -110, 190);
396  m_2DHitsLine.DrawLine(-110, 190, 110, 190);
397  m_2DHitsLine.DrawLine(110, 80, 110, 190);
398  m_2DHitsLine.DrawLine(-110, 80, 110, 80);
399  }
400  canvas->Modified();
401 }
402 
404  const std::string& histName)
405 {
406  TH1* histogram = findHist(m_histogramDirectoryName + "/" + histName);
407  if (histogram == nullptr) {
408  B2WARNING("KLM DQM histogram " + m_histogramDirectoryName + "/" << histName << " is not found.");
409  return;
410  }
411 
412  TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
413  if (canvas == nullptr) {
414  B2WARNING("KLM DQM histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
415  return;
416  }
417 
418  else {
419  /* calling on delta histogram*/
420  TH1* delta = getDelta(m_histogramDirectoryName, histName);
421  UpdateCanvas(canvas->GetName(), delta != nullptr);
422  if (delta != nullptr) {
423  canvas->Clear();
424  canvas->cd();
425  delta->Draw("hist");
426  }
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 }
467 
469  const std::string& histName, TLatex& latex)
470 {
471 
472  TH1* histogram = findHist(m_histogramDirectoryName + "/" + histName);
473  if (histogram == nullptr) {
474  B2WARNING("KLM DQM histogram " + m_histogramDirectoryName + "/" << histName << " is not found.");
475  return;
476  }
477  TCanvas* canvas = findCanvas(m_histogramDirectoryName + "/c_" + histName);
478  if (canvas == nullptr) {
479  B2WARNING("KLM DQM histogram canvas " + m_histogramDirectoryName + "/c_" << histName << " is not found.");
480  return;
481  } else {
482  std::string name, alarm;
483  int moduleSubdetector, moduleSection, moduleSector, moduleLayer;
484  double xAlarm = 0.15;
485  double yAlarm = 0.8;
486  canvas->Clear();
487  canvas->cd();
488  histogram->SetStats(false);
489  histogram->Draw();
490  if (histName.find("bklm") != std::string::npos) {
491  /* First draw the vertical lines and the sector names. */
492  const int maximalLayer = BKLMElementNumbers::getMaximalLayerNumber();
493  for (int sector = 0; sector < BKLMElementNumbers::getMaximalSectorGlobalNumber(); ++sector) {
494  int bin = maximalLayer * sector + 1;
495  double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
496  double xText = histogram->GetXaxis()->GetBinLowEdge(bin + maximalLayer / 2);
497  double yText = gPad->GetUymin() + 0.98 * (gPad->GetUymax() - gPad->GetUymin());
498  if (sector > 0)
499  m_PlaneLine.DrawLine(xLine, gPad->GetUymin(), xLine, gPad->GetUymax());
500  name = "B";
501  if (sector < 8)
502  name += "B";
503  else
504  name += "F";
505  name += std::to_string(sector % 8);
506  m_PlaneText.DrawText(xText, yText, name.c_str());
507  }
508  /* Then, color the canvas with red if there is a dead module
509  * and write an error message. */
510  if (m_DeadBarrelModules.size() == 0) {
511  canvas->Pad()->SetFillColor(kWhite);
513  for (KLMModuleNumber module : m_DeadBarrelModules) {
515  module, &moduleSubdetector, &moduleSection, &moduleSector, &moduleLayer);
516  alarm = "No data from " + m_ElementNumbers->getSectorDAQName(moduleSubdetector, moduleSection, moduleSector);
517  alarm += ", layer " + std::to_string(moduleLayer);
518  latex.DrawLatexNDC(xAlarm, yAlarm, alarm.c_str());
519  yAlarm -= 0.05;
520  }
521  if (m_IsNullRun == false) {
522  alarm = "Call the KLM experts immediately!";
523  latex.DrawLatexNDC(xAlarm, yAlarm, alarm.c_str());
524  canvas->Pad()->SetFillColor(kRed);
525  }
526  }
527  } else {
528  /* First draw the vertical lines and the sector names. */
529  const double maximalLayer = EKLMElementNumbers::getMaximalLayerGlobalNumber();
531  for (int layerGlobal = 1; layerGlobal <= maximalLayer; ++layerGlobal) {
532  int bin = maxPlane * layerGlobal + 1;
533  double xLine = histogram->GetXaxis()->GetBinLowEdge(bin);
534  double xText = histogram->GetXaxis()->GetBinLowEdge(bin - maxPlane / 2);
535  double yText = gPad->GetUymin() + 0.98 * (gPad->GetUymax() - gPad->GetUymin());
536  if (layerGlobal < maximalLayer)
537  m_PlaneLine.DrawLine(xLine, gPad->GetUymin(), xLine, gPad->GetUymax());
538  int section, layer;
540  layerGlobal, &section, &layer);
542  name = "B";
543  else
544  name = "F";
545  name += std::to_string(layer);
546  m_PlaneText.DrawText(xText, yText, name.c_str());
547  }
548  /* Then, color the canvas with red if there is a dead module
549  * and write an error message. */
550  if (m_DeadEndcapModules.size() == 0) {
551  canvas->Pad()->SetFillColor(kWhite);
553  for (KLMModuleNumber module : m_DeadEndcapModules) {
555  module, &moduleSubdetector, &moduleSection, &moduleSector, &moduleLayer);
556  alarm = "No data from " + m_ElementNumbers->getSectorDAQName(moduleSubdetector, moduleSection, moduleSector);
557  alarm += ", layer " + std::to_string(moduleLayer);
558  latex.DrawLatexNDC(xAlarm, yAlarm, alarm.c_str());
559  yAlarm -= 0.05;
560  }
561  if (m_IsNullRun == false) {
562  alarm = "Call the KLM experts immediately!";
563  latex.DrawLatexNDC(xAlarm, yAlarm, alarm.c_str());
564  canvas->Pad()->SetFillColor(kRed);
565  }
566  }
567  }
568  canvas->Modified();
569  canvas->Update();
570  }
571 }
572 
574 {
575  /* If KLM is not included, stop here and return. */
576  TH1* daqInclusion = findHist(m_histogramDirectoryName + "/daq_inclusion");
577  if (not(daqInclusion == nullptr)) {
578  int isKlmIncluded = daqInclusion->GetBinContent(daqInclusion->GetXaxis()->FindBin("Yes"));
579  if (isKlmIncluded == 0)
580  return;
581  }
582  /* Make sure that the vectors are cleared at each DQM refresh. */
583  m_DeadBarrelModules.clear();
584  m_DeadEndcapModules.clear();
585  m_MaskedChannels.clear();
587  std::string str, histogramName, canvasName;
588  TLatex latex;
589  latex.SetTextColor(kRed);
590  latex.SetTextAlign(11);
592  for (KLMChannelIndex& klmSector : klmIndex) {
593  int nHistograms;
594  if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
595  nHistograms = 2;
596  else
597  nHistograms = 3;
598  for (int j = 0; j < nHistograms; j++) {
599  str = "strip_hits_subdetector_" +
600  std::to_string(klmSector.getSubdetector()) +
601  "_section_" + std::to_string(klmSector.getSection()) +
602  "_sector_" + std::to_string(klmSector.getSector()) +
603  "_" + std::to_string(j);
604  histogramName = m_histogramDirectoryName + "/" + str;
605  canvasName = m_histogramDirectoryName + "/c_" + str;
606  TH1* histogram = findHist(histogramName);
607  //get delta histogram (should we work with a clone instead?)
608  auto delta = getDelta("", histogramName);
609 
610  if (histogram == nullptr) {
611  B2WARNING("KLM DQM histogram " << histogramName << " is not found.");
612  continue;
613  }
614  TCanvas* canvas = findCanvas(canvasName);
615  if (canvas == nullptr) {
616  B2WARNING("KLM DQM histogram canvas " << canvasName << " is not found.");
617  continue;
618  }
619  UpdateCanvas(canvas->GetName(), delta != nullptr || histogram != nullptr);
621  klmSector.getSubdetector(), klmSector.getSection(),
622  klmSector.getSector(), j, histogram, delta, canvas, latex);
623 
624  }
625  }
626  /* Temporary change the color palette. */
627  gStyle->SetPalette(kLightTemperature);
629  for (KLMChannelIndex& klmSection : klmIndex) {
630  KLMSubdetectorNumber subdetector = klmSection.getSubdetector();
631  if (subdetector == KLMElementNumbers::c_EKLM) {
632  KLMSubdetectorNumber section = klmSection.getSection();
633  int maximalLayerNumber = m_EklmElementNumbers->getMaximalDetectorLayerNumber(section);
634  for (int j = 1; j <= maximalLayerNumber; ++j) {
635  str = "spatial_2d_hits_subdetector_" + std::to_string(subdetector) +
636  "_section_" + std::to_string(section) +
637  "_layer_" + std::to_string(j);
638  histogramName = m_histogramDirectoryName + "/" + str;
639  canvasName = m_histogramDirectoryName + "/c_" + str;
640  TH2F* histogram = static_cast<TH2F*>(findHist(histogramName));
641  if (histogram == nullptr) {
642  B2ERROR("KLM DQM histogram " << histogramName << " is not found.");
643  continue;
644  }
645  TCanvas* canvas = findCanvas(canvasName);
646  if (canvas == nullptr) {
647  B2ERROR("KLM DQM histogram canvas " << canvasName << " is not found.");
648  continue;
649  }
650  processSpatial2DHitEndcapHistogram(section, histogram, canvas);
651  }
652  }
653  }
654  /* Reset the color palette to the default one. */
655  gStyle->SetPalette(kBird);
656  fillMaskedChannelsHistogram("masked_channels");
657  latex.SetTextColor(kBlue);
658  processPlaneHistogram("plane_bklm_phi", latex);
659  processPlaneHistogram("plane_bklm_z", latex);
660  processPlaneHistogram("plane_eklm", latex);
661 
662  processTimeHistogram("time_rpc");
663  processTimeHistogram("time_scintillator_bklm");
664  processTimeHistogram("time_scintillator_eklm");
665 
666  B2DEBUG(20, "Updating EPICS PVs for DQMHistAnalysisKLM");
667  setEpicsPV("MaskedChannels", (double)m_MaskedChannels.size());
668  setEpicsPV("DeadBarrelModules", (double)m_DeadBarrelModules.size());
669  setEpicsPV("DeadEndcapModules", (double)m_DeadEndcapModules.size());
670  B2DEBUG(20, "DQMHistAnalysisKLM: MaskedChannels " << m_MaskedChannels.size());
671  B2DEBUG(20, "DQMHistAnalysisKLM: DeadBarrelModules " << m_DeadBarrelModules.size());
672  B2DEBUG(20, "DQMHistAnalysisKLM: DeadEndcapModules " << m_DeadEndcapModules.size());
673  updateEpicsPVs(5.0);
674 }
static constexpr int getMaximalLayerNumber()
Get maximal layer 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_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.
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.
int registerEpicsPV(std::string pvname, std::string keyname="", bool update_pvs=true)
EPICS related Functions.
void addDeltaPar(const std::string &dirname, const std::string &histname, HistDelta::EDeltaType t, int p, unsigned int a=1)
Add Delta histogram parameters.
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
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.
static const std::string & getRunType(void)
Get the Run Type.
static int getEventProcessed(void)
Get the number of processed events.
void UpdateCanvas(std::string name, bool updated=true)
Mark canvas as updated (or not)
static MonitoringObject * getMonitoringObject(const std::string &histname)
Get MonitoringObject with given name (new object is created if non-existing)
int updateEpicsPVs(float timeout)
Update all EPICS PV (flush to network)
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
REG_MODULE(arichBtest)
Register the Module.
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
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.