Belle II Software  release-08-01-10
SVDLocalCalibrationsCheckModule.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 #include <svd/modules/svdCalibration/SVDLocalCalibrationsCheckModule.h>
10 #include <vxd/geometry/GeoCache.h>
11 #include <svd/geometry/SensorInfo.h>
12 
13 #include <TCanvas.h>
14 #include <TLine.h>
15 #include <TPaveText.h>
16 #include <TStyle.h>
17 #include <TText.h>
18 
19 using namespace Belle2;
20 
21 //-----------------------------------------------------------------
22 // Register the Module
23 //-----------------------------------------------------------------
24 REG_MODULE(SVDLocalCalibrationsCheck);
25 
26 //-----------------------------------------------------------------
27 // Implementation
28 //-----------------------------------------------------------------
29 
31 {
32  // Set module properties
33  setDescription("Module to produce a list of histograms showing the uploaded calibration constants");
34 
35  // Parameter definitions
36  addParam("outputPdfName", m_outputPdfName, "output pdf filename", std::string("SVDLocalCalibrationsCheck.pdf"));
37  addParam("referenceID", m_idFileNameREF, "ID of REFERENCE xml file.",
38  std::string("refID"));
39  addParam("checkID", m_idFileNameCHECK, "ID of CHECK xml file.",
40  std::string("checkID"));
41  addParam("reference_root", m_rootFileNameREF, "Name of REFERENCE root file.",
42  std::string("SVDLocalCalibrationsMonitor_ref.root"));
43  addParam("check_root", m_rootFileNameCHECK, "Name of CHECK root file.",
44  std::string("SVDLocalCalibrationsMonitor_check.root"));
45  addParam("plotGoodAPVs", m_plotGoodAPVs, "If true draw 1D plots also for good APVs", bool(false));
46 
47  addParam("cutN_outliers", m_cutN_out, "Max number of outliers allowed", int(5));
48  addParam("cutNoise_average", m_cutNoise_ave, "Max deviation of average noise per APV, in ADC", float(0.1));
49  addParam("cutNoise_outliers", m_cutNoise_out, "Max deviation of single strip, in ADC", float(2));
50  addParam("cutCalPeakADC_average", m_cutCalpeakADC_ave, "Max deviation of average CalPeakADC per APV, in ADC", float(4));
51  addParam("cutCalPeakADC_outliers", m_cutCalpeakADC_out, "Max deviation of single strip, in ADC", float(10));
52  addParam("cutPedestal_average", m_cutPedestal_ave, "Max deviation of average pedestal per APV, in ADC", float(4));
53  addParam("cutPedestal_outliers", m_cutPedestal_out, "Max deviation of single strip, in ADC", float(10));
54 
55 }
56 
58 {
59  B2INFO("SVD Local Calibration Check Configuration");
60  B2INFO("-----------------------------------------");
61  B2INFO("");
62  B2INFO("- input files:");
63  B2INFO(" reference: " << m_idFileNameREF);
64  B2INFO(" check: " << m_idFileNameCHECK);
65  B2INFO("- output file:");
66  B2INFO(" output pdf: " << m_outputPdfName);
67  B2INFO("");
68  B2INFO("- analysis parameters:");
69  B2INFO(" outliers (Noise, Pedestal, CalPeakADC)");
70  B2INFO(" max allowed outliers = " << m_cutN_out);
71  B2INFO(" Noise");
72  B2INFO(" max difference on the APV averages = " << m_cutNoise_ave << " ADC");
73  B2INFO(" max to mark a strip as outlier = " << m_cutNoise_out << " ADC");
74  B2INFO(" CalPeakADC");
75  B2INFO(" max difference on the APV averages = " << m_cutCalpeakADC_ave << " ADC");
76  B2INFO(" max to mark a strip as outlier = " << m_cutCalpeakADC_out << " ADC");
77  B2INFO(" Pedestal");
78  B2INFO(" max difference on the APV averages = " << m_cutPedestal_ave << " ADC");
79  B2INFO(" max to mark a strip as outlier = " << m_cutPedestal_out << " ADC");
80  B2INFO("--------------------------------------------------------------");
81  B2INFO("");
82 }
83 
85 {
86 
88 
89  gStyle->SetOptStat(0);
90  gStyle->SetLegendBorderSize(0);
91  gStyle->SetTextFont(42);
92 
93  // read REFERENCE root file
94  m_rootFilePtrREF = new TFile(m_rootFileNameREF.c_str(), "READ");
95 
96  // m_rootFilePtrREF->Print();
97 
98  //REF tree initialization
99  m_treeREF = (TTree*)m_rootFilePtrREF->Get("calibLocalDetailed");
100  m_treeREF->SetBranchAddress("run", &m_runREF, &b_runREF);
101  m_treeREF->SetBranchAddress("layer", &m_layerREF, &b_layerREF);
102  m_treeREF->SetBranchAddress("ladder", &m_ladderREF, &b_ladderREF);
103  m_treeREF->SetBranchAddress("sensor", &m_sensorREF, &b_sensorREF);
104  m_treeREF->SetBranchAddress("side", &m_sideREF, &b_sideREF);
105  m_treeREF->SetBranchAddress("strip", &m_stripREF, &b_stripREF);
106  m_treeREF->SetBranchAddress("mask", &m_maskREF, &b_maskREF);
107  m_treeREF->SetBranchAddress("noise", &m_noiseREF, &b_noiseREF);
108  m_treeREF->SetBranchAddress("noiseEl", &m_noiseElREF, &b_noiseElREF);
109  m_treeREF->SetBranchAddress("gain", &m_gainREF, &b_gainREF);
110  m_treeREF->SetBranchAddress("pedestal", &m_pedestalREF, &b_pedestalREF);
111  m_treeREF->SetBranchAddress("calPeakADC", &m_calPeakADCREF, &b_calPeakADCREF);
112  m_treeREF->SetBranchAddress("calPeakTime", &m_calPeakTimeREF, &b_calPeakTimeREF);
113  m_treeREF->SetBranchAddress("pulseWidth", &m_pulseWidthREF, &b_pulseWidthREF);
114 
115  // read CHECK root file
116  m_rootFilePtrCHECK = new TFile(m_rootFileNameCHECK.c_str(), "READ");
117  // m_rootFilePtrCHECK->Print();
118 
119  //CHECK tree initialization
120  m_treeCHECK = (TTree*)m_rootFilePtrCHECK->Get("calibLocalDetailed");
121  m_treeCHECK->SetBranchAddress("run", &m_runCHECK, &b_runCHECK);
122  m_treeCHECK->SetBranchAddress("layer", &m_layerCHECK, &b_layerCHECK);
123  m_treeCHECK->SetBranchAddress("ladder", &m_ladderCHECK, &b_ladderCHECK);
124  m_treeCHECK->SetBranchAddress("sensor", &m_sensorCHECK, &b_sensorCHECK);
125  m_treeCHECK->SetBranchAddress("side", &m_sideCHECK, &b_sideCHECK);
126  m_treeCHECK->SetBranchAddress("strip", &m_stripCHECK, &b_stripCHECK);
127  m_treeCHECK->SetBranchAddress("mask", &m_maskCHECK, &b_maskCHECK);
128  m_treeCHECK->SetBranchAddress("noise", &m_noiseCHECK, &b_noiseCHECK);
129  m_treeCHECK->SetBranchAddress("noiseEl", &m_noiseElCHECK, &b_noiseElCHECK);
130  m_treeCHECK->SetBranchAddress("gain", &m_gainCHECK, &b_gainCHECK);
131  m_treeCHECK->SetBranchAddress("pedestal", &m_pedestalCHECK, &b_pedestalCHECK);
132  m_treeCHECK->SetBranchAddress("calPeakTime", &m_calPeakTimeCHECK, &b_calPeakTimeCHECK);
133  m_treeCHECK->SetBranchAddress("calPeakADC", &m_calPeakADCCHECK, &b_calPeakADCCHECK);
134  m_treeCHECK->SetBranchAddress("pulseWidth", &m_pulseWidthCHECK, &b_pulseWidthCHECK);
135 
136 
138  m_h2NoiseREF = (SVDHistograms<TH2F>*)m_rootFilePtrREF->Get("expert/h2Noise");
139  m_h2NoiseCHECK = (SVDHistograms<TH2F>*)m_rootFilePtrCHECK->Get("expert/h2Noise");
140 
141  TH1F template_noise("noiseDIFF_L@layerL@ladderS@sensor@view@apv",
142  "Noise Deviation Distribution in @layer.@ladder.@sensor @view/@side",
143  // 200, -1, 1);
144  200, -5, 5);
145  // template_noise.GetXaxis()->SetTitle("( ref - check ) / ref");
146  template_noise.GetXaxis()->SetTitle("ref - check (ADC)");
147  m_hNoiseDIFF = new SVDAPVHistograms<TH1F>(template_noise);
149  m_hNoiseSummary = new SVDSummaryPlots("noiseSummary@view", "Number of problematic APV chips due to Noise for @view/@side Side");
150 
151 
152 
153 
155  m_h2CalpeakTimeREF = (SVDHistograms<TH2F>*)m_rootFilePtrREF->Get("expert/h2CalPeakTime");
156  m_h2CalpeakTimeCHECK = (SVDHistograms<TH2F>*)m_rootFilePtrCHECK->Get("expert/h2CalPeakTime");
157 
158  TH1F template_calpeakTime("calpeakTimeDIFF_L@layerL@ladderS@sensor@view@apv",
159  // "CalpeakTime Deviation Distribution in @layer.@ladder.@sensor @view/@side APV @apv",
160  "CalPeakTime Deviation Distribution in @layer.@ladder.@sensor @view/@side",
161  500, -0.5, 0.5);
162  template_calpeakTime.GetXaxis()->SetTitle("( ref - check ) / ref");
163  m_hCalpeakTimeDIFF = new SVDAPVHistograms<TH1F>(template_calpeakTime);
165  m_hCalpeakTimeSummary = new SVDSummaryPlots("calPeakTimeSummary@view",
166  "Number of problematic APV chips due to CalPeakTime for @view/@side Side for @view/@side Side");
167 
169  m_h2CalpeakADCREF = (SVDHistograms<TH2F>*)m_rootFilePtrREF->Get("expert/h2CalPeakADC");
170  m_h2CalpeakADCCHECK = (SVDHistograms<TH2F>*)m_rootFilePtrCHECK->Get("expert/h2CalPeakADC");
171 
172  TH1F template_calpeakADC("calpeakADCDIFF_L@layerL@ladderS@sensor@view@apv",
173  // "CalpeakADC Deviation Distribution in @layer.@ladder.@sensor @view/@side APV @apv",
174  "CalPeakADC Deviation Distribution in @layer.@ladder.@sensor @view/@side",
175  400, -20, 20);
176  template_calpeakADC.GetXaxis()->SetTitle("ref - check (ADC)");
177  m_hCalpeakADCDIFF = new SVDAPVHistograms<TH1F>(template_calpeakADC);
179  m_hCalpeakADCSummary = new SVDSummaryPlots("calPeakADCSummary@view",
180  "Number of problematic APV chips due to CalPeakADC for @view/@side Side");
181 
182 
184  m_h2PedestalREF = (SVDHistograms<TH2F>*)m_rootFilePtrREF->Get("expert/h2Pedestal");
185  m_h2PedestalCHECK = (SVDHistograms<TH2F>*)m_rootFilePtrCHECK->Get("expert/h2Pedestal");
186 
187  TH1F template_pedestal("pedestalDIFF_L@layerL@ladderS@sensor@view@apv",
188  "Pedestal Deviation Distribution in @layer.@ladder.@sensor @view/@side",
189  // 100, -0.5, 0.5);
190  100, -15, 15);
191  // template_pedestal.GetXaxis()->SetTitle("( ref - check ) / ref");
192  template_pedestal.GetXaxis()->SetTitle("( ref - check) (ADC)");
193  m_hPedestalDIFF = new SVDAPVHistograms<TH1F>(template_pedestal);
195  m_hPedestalSummary = new SVDSummaryPlots("pedestalSummary@view",
196  "Number of problematic APV chips due to Pedestal for @view/@side Side");
197 
198  createLegends();
199 }
200 
202 {
203  printFirstPage();
204 
205  Long64_t nentries = m_treeREF->GetEntriesFast();
206 
207  for (Long64_t jentry = 0; jentry < nentries; jentry++) {
208  m_treeREF->GetEntry(jentry);
209  m_treeCHECK->GetEntry(jentry);
211  float diff = 0;
212 
213 
214  diff = (m_noiseREF - m_noiseCHECK);// / m_noiseREF;
215  m_hNoiseDIFF->fill(theVxdID, (int)m_sideREF, (int)m_stripREF / 128, diff);
216 
218  m_hCalpeakTimeDIFF->fill(theVxdID, (int)m_sideREF, (int)m_stripREF / 128, diff);
219 
220  diff = (m_calPeakADCREF - m_calPeakADCCHECK);// / m_calPeakADCREF;
221  m_hCalpeakADCDIFF->fill(theVxdID, (int)m_sideREF, (int)m_stripREF / 128, diff);
222 
223  diff = (m_pedestalREF - m_pedestalCHECK);// / m_pedestalREF;
224  m_hPedestalDIFF->fill(theVxdID, (int)m_sideREF, (int)m_stripREF / 128, diff);
225  }
226 
227 
228  //call for a geometry instance
230  std::set<Belle2::VxdID> svdLayers = aGeometry.getLayers(VXD::SensorInfoBase::SVD);
231  std::set<Belle2::VxdID>::iterator itSvdLayers = svdLayers.begin();
232 
233  while ((itSvdLayers != svdLayers.end()) && (itSvdLayers->getLayerNumber() != 7)) { //loop on Layers
234 
235  bool isL3 = false;
236 
237  int layer = itSvdLayers->getLayerNumber();
238  printLayerPage(layer);
239 
240  if (layer == 3)
241  isL3 = true;
242 
243  std::set<Belle2::VxdID> svdLadders = aGeometry.getLadders(*itSvdLayers);
244  std::set<Belle2::VxdID>::iterator itSvdLadders = svdLadders.begin();
245 
246  while (itSvdLadders != svdLadders.end()) { //loop on Ladders
247 
248  std::set<Belle2::VxdID> svdSensors = aGeometry.getSensors(*itSvdLadders);
249  std::set<Belle2::VxdID>::iterator itSvdSensors = svdSensors.begin();
250 
251  while (itSvdSensors != svdSensors.end()) { //loop on sensors
252  B2DEBUG(1, " svd sensor info " << *itSvdSensors);
253 
254 
255  int ladder = itSvdSensors->getLadderNumber();
256  int sensor = itSvdSensors->getSensorNumber();
257  Belle2::VxdID theVxdID(layer, ladder, sensor);
258  const SVD::SensorInfo* currentSensorInfo = dynamic_cast<const SVD::SensorInfo*>(&VXD::GeoCache::get(theVxdID));
259 
260  TList* listEmpty = new TList;
261 
262  //noise
263  TList* listNoiseUBAD = new TList;
264  TList* listNoiseUGOOD = new TList;
265  TList* listNoiseVBAD = new TList;
266  TList* listNoiseVGOOD = new TList;
267 
268 
269  //calpeak
270  TList* listCalpeakADCUBAD = new TList;
271  TList* listCalpeakADCUGOOD = new TList;
272  TList* listCalpeakADCVBAD = new TList;
273  TList* listCalpeakADCVGOOD = new TList;
274 
275  //calpeak
276  TList* listCalpeakTimeUGOOD = new TList;
277  TList* listCalpeakTimeVGOOD = new TList;
278 
279  //pedestal
280  TList* listPedestalUBAD = new TList;
281  TList* listPedestalUGOOD = new TList;
282  TList* listPedestalVBAD = new TList;
283  TList* listPedestalVGOOD = new TList;
284 
285  bool needPlot = false;
286  for (int side = 0; side < 2; side++) {
287 
288  int Ncells = currentSensorInfo->getUCells();
289  if (side == 0)
290  Ncells = currentSensorInfo->getVCells();
291 
292  int Napv = Ncells / 128;
293 
294  for (int m_APV = 0; m_APV < Napv; m_APV++) {
295 
296  int problem = 0;
297 
298  //noise analysis
299  TH1F* hNoise = m_hNoiseDIFF->getHistogram(theVxdID, side, m_APV);
300  problem = hasAnyProblem(hNoise, m_cutNoise_ave, m_cutNoise_out);
301  if (problem) {
302  needPlot = true;
303  B2INFO("WARNING, ONE APV has Noise problems in: L" << layer << "L" << ladder << "S" << sensor << " side = " << side <<
304  ", APV number = " << m_APV << ", problem ID = " << problem);
305  m_hNoiseSummary->fill(theVxdID, side, 1);
306  if (side == 0)
307  listNoiseVBAD->Add(hNoise);
308  else
309  listNoiseUBAD->Add(hNoise);
310  } else {
311  if (side == 0)
312  listNoiseVGOOD->Add(hNoise);
313  else
314  listNoiseUGOOD->Add(hNoise);
315  }
316 
317 
318 
319  //calpeak analysis
320  TH1F* hCalpeakADC = m_hCalpeakADCDIFF->getHistogram(theVxdID, side, m_APV);
321  problem = hasAnyProblem(hCalpeakADC, m_cutCalpeakADC_ave, m_cutCalpeakADC_out);
322  if (problem) {
323  needPlot = true;
324  B2INFO("WARNING, ONE APV has CalpeakADC problems in: L" << layer << "L" << ladder << "S" << sensor << " side = " << side <<
325  ", APV number = " << m_APV << " problem ID = " << problem);
326  m_hCalpeakADCSummary->fill(theVxdID, side, 1);
327  if (side == 0)
328  listCalpeakADCVBAD->Add(hCalpeakADC);
329  else
330  listCalpeakADCUBAD->Add(hCalpeakADC);
331  } else {
332  if (side == 0)
333  listCalpeakADCVGOOD->Add(hCalpeakADC);
334  else
335  listCalpeakADCUGOOD->Add(hCalpeakADC);
336  }
337 
338  //calpeak plot
339  TH1F* hCalpeakTime = m_hCalpeakTimeDIFF->getHistogram(theVxdID, side, m_APV);
340  if (side == 0)
341  listCalpeakTimeVGOOD->Add(hCalpeakTime);
342  else
343  listCalpeakTimeUGOOD->Add(hCalpeakTime);
344 
345 
346  //pedestal analysis
347  TH1F* hPedestal = m_hPedestalDIFF->getHistogram(theVxdID, side, m_APV);
348  problem = hasAnyProblem(hPedestal, m_cutPedestal_ave, m_cutPedestal_out);
349  if (problem) {
350  needPlot = true;
351  B2INFO("WARNING, ONE APV has Pedestal problems in: L" << layer << "L" << ladder << "S" << sensor << " side = " << side <<
352  ", APV number = " << m_APV << " problem ID = " << problem);
353  m_hPedestalSummary->fill(theVxdID, side, 1);
354  if (side == 0)
355  listPedestalVBAD->Add(hPedestal);
356  else
357  listPedestalUBAD->Add(hPedestal);
358  } else {
359  if (side == 0)
360  listPedestalVGOOD->Add(hPedestal);
361  else
362  listPedestalUGOOD->Add(hPedestal);
363  }
364 
365 
366 
367  }
368  }
369  if (needPlot) {
370  printPage(theVxdID, listNoiseUBAD, listNoiseVBAD, listNoiseUGOOD, listNoiseVGOOD, "Noise", isL3);
371  printPage(theVxdID, listCalpeakADCUBAD, listCalpeakADCVBAD, listCalpeakADCUGOOD, listCalpeakADCVGOOD, "CalpeakADC", isL3);
372  printPage(theVxdID, listEmpty, listEmpty, listCalpeakTimeUGOOD, listCalpeakTimeVGOOD, "CalpeakTime", isL3);
373  printPage(theVxdID, listPedestalUBAD, listPedestalVBAD, listPedestalUGOOD, listPedestalVGOOD, "Pedestal", isL3);
374  }
375  ++itSvdSensors;
376  }
377  ++itSvdLadders;
378  }
379  ++itSvdLayers;
380  }
381 
383  printLastPage();
384 
385 }
386 
388 {
389 
390  TCanvas* empty = new TCanvas();
391  TString pdf_open = TString(m_outputPdfName) + "[";
392  empty->Print(pdf_open);
393 
394  TCanvas* first = new TCanvas("open_pag1", "test first page");
395  first->cd();
396  TPaveText* pt_title = new TPaveText(.05, .9, .95, 1, "blNDC");
397  char name[50];
398  sprintf(name, "Local Calibration Check Results");
399  pt_title->AddText(name);
400  pt_title->SetTextFont(42);
401  pt_title->SetTextColor(kBlack);
402  pt_title->SetShadowColor(0);
403  pt_title->SetFillColor(10);
404  pt_title->SetBorderSize(0);
405  pt_title->SetTextSize(0.08);
406  pt_title->Draw();
407 
408  TPaveText* pt_input_title = new TPaveText(.05, .8, .95, .85);
409  TPaveText* pt_input = new TPaveText(.05, .72, .8, .8);
410  char input[150];
411  sprintf(input, "%s", "input files");
412  pt_input_title->AddText(input);
413  pt_input_title->SetShadowColor(0);
414  pt_input_title->SetBorderSize(0);
415  pt_input_title->SetTextSize(0.03);
416  if (m_idFileNameREF == "refID")
417  sprintf(input, "reference rootfile = %s", m_rootFileNameREF.c_str());
418  else
419  sprintf(input, " reference ID = %s", m_idFileNameREF.c_str());
420  pt_input->AddText(input);
421  ((TText*)pt_input->GetListOfLines()->Last())->SetTextColor(kRed);
422  if (m_idFileNameCHECK == "checkID")
423  sprintf(input, "calibration rootfile = %s", m_rootFileNameCHECK.c_str());
424  else
425  sprintf(input, "calibration ID = %s", m_idFileNameCHECK.c_str());
426  pt_input->AddText(input);
427  ((TText*)pt_input->GetListOfLines()->Last())->SetTextColor(kBlue);
428  pt_input->SetTextSize(0.02);
429  pt_input->SetTextAlign(12);
430  pt_input->SetShadowColor(0);
431  pt_input->SetBorderSize(0);
432  pt_input->SetFillColor(10);
433 
434  pt_input_title->Draw();
435  pt_input->Draw();
436 
437  TPaveText* pt_cuts_title = new TPaveText(.05, .65, .95, .7);
438  TPaveText* pt_cuts = new TPaveText(.05, .15, .8, .60);
439  char cuts[512];
440  sprintf(cuts, "%s", "selection criteria");
441  pt_cuts_title->AddText(cuts);
442  pt_cuts_title->SetShadowColor(0);
443  pt_cuts_title->SetBorderSize(0);
444  pt_cuts_title->SetTextSize(0.03);
445  sprintf(cuts, " An APV chip is selected as problematic if passes the criteria on Noise or CalPeakADC or Pedestal");
446  pt_cuts->AddText(cuts);
447  // NOISE
448  sprintf(cuts, " Noise: an APV is problematic if 1. or 2. or 3.");
449  pt_cuts->AddText(cuts);
450  sprintf(cuts, " 1. abs(ref_ave - check_ave) > %1.2f ADC", m_cutNoise_ave);
451  pt_cuts->AddText(cuts);
452  sprintf(cuts, " 2. more than %d strips with a value %1.2f ADC higher than the value of the ref calibration", m_cutN_out,
454  pt_cuts->AddText(cuts);
455  sprintf(cuts, " 3. more than %d strips with a value %1.2f ADC lower than the value of the ref calibration", m_cutN_out,
457  pt_cuts->AddText(cuts);
458  // CALPEAK ADC
459  sprintf(cuts, " CalPeakADC: an APV is problematic if 1. or 2. or 3.");
460  pt_cuts->AddText(cuts);
461  sprintf(cuts, " 1. abs(ref_ave - check_ave) > %1.2f ADC", m_cutCalpeakADC_ave);
462  pt_cuts->AddText(cuts);
463  sprintf(cuts, " 2. more than %d strips with a value %1.1f ADC higher than the value of the ref calibration", m_cutN_out,
465  pt_cuts->AddText(cuts);
466  sprintf(cuts, " 3. more than %d strips with a value %1.1f ADC lower than the value of the ref calibration", m_cutN_out,
468  pt_cuts->AddText(cuts);
469  // PEDESTAL
470  sprintf(cuts, " Pedestal: an APV is problematic if 1. or 2. or 3.");
471  pt_cuts->AddText(cuts);
472  sprintf(cuts, " 1. abs(ref_ave - check_ave) > %1.1f ADC", m_cutPedestal_ave);
473  pt_cuts->AddText(cuts);
474  sprintf(cuts, " 2. more than %d strips with a value %1.1f ADC higher than the value of the ref calibration", m_cutN_out,
476  pt_cuts->AddText(cuts);
477  sprintf(cuts, " 3. more than %d strips with a value %1.1f ADC lower than the value of the ref calibration", m_cutN_out,
479  pt_cuts->AddText(cuts);
480  sprintf(cuts,
481  " where:");
482  pt_cuts->AddText(cuts);
483  sprintf(cuts,
484  " - {ref,check}_ave is the variable averaged on one APV chip of the reference or the check calibration");
485  pt_cuts->AddText(cuts);
486  sprintf(cuts,
487  " - 1 2 and 3 are the problem ID printed on screen while running the python script");
488  pt_cuts->AddText(cuts);
489  pt_cuts->SetTextSize(0.02);
490  pt_cuts->SetShadowColor(0);
491  pt_cuts->SetBorderSize(0);
492  pt_cuts->SetFillColor(10);
493  pt_cuts->SetTextAlign(12);
494 
495  pt_cuts_title->Draw();
496  pt_cuts->Draw();
497 
498  TPaveText* pt_tag_title = new TPaveText(.05, .03, .95, .07);
499  char tag[100];
500  sprintf(tag, "analysis algorithm ID 1.0");
501  pt_tag_title->AddText(tag);
502  // pt_tag_title->SetTextFont(62);
503  pt_tag_title->SetShadowColor(0);
504  pt_tag_title->SetFillColor(18);
505  pt_tag_title->SetBorderSize(0);
506  pt_tag_title->SetTextSize(0.02);
507  pt_tag_title->Draw();
508  first->Print(m_outputPdfName.c_str());
509 }
510 
512 {
513 
514  TCanvas* cLayer = new TCanvas();
515  cLayer->cd();
516  TPaveText* pt_title = new TPaveText(.05, .4, .95, 0.6, "blNDC");
517  char name[50];
518  sprintf(name, "Layer %d", layer);
519  pt_title->AddText(name);
520  pt_title->SetTextFont(42);
521  pt_title->SetTextColor(kBlack);
522  pt_title->SetShadowColor(0);
523  pt_title->SetFillColor(10);
524  pt_title->SetBorderSize(0);
525  pt_title->SetTextSize(0.08);
526  pt_title->Draw();
527  cLayer->Print(m_outputPdfName.c_str());
528 
529 }
530 
531 void SVDLocalCalibrationsCheckModule::printPage(VxdID theVxdID, TList* listUBAD, TList* listVBAD, TList* listUGOOD,
532  TList* listVGOOD, TString variable, bool isL3)
533 {
534 
535  TH2F* refU = nullptr;
536  TH2F* refV = nullptr;
537  TH2F* checkU = nullptr;
538  TH2F* checkV = nullptr;
539 
540  Int_t minY = 0;
541  Int_t maxY = 0;
542 
543  Float_t leftLine = 0;
544  Float_t rightLine = 0;
545  Float_t topLine = 0;
546 
547  if (variable == "Noise") {
548  refU = m_h2NoiseREF->getHistogram(theVxdID, 1);
549  refV = m_h2NoiseREF->getHistogram(theVxdID, 0);
550  checkU = m_h2NoiseCHECK->getHistogram(theVxdID, 1);
551  checkV = m_h2NoiseCHECK->getHistogram(theVxdID, 0);
552  // minY = refU->GetYaxis()->GetXmin();
553  // maxY = refU->GetYaxis()->GetXmax();
554  minY = 0;
555  maxY = 6;
556  leftLine = -m_cutNoise_out;
557  rightLine = m_cutNoise_out;
558  topLine = 5;
559  } else if (variable == "CalpeakADC") {
560  refU = m_h2CalpeakADCREF->getHistogram(theVxdID, 1);
561  refV = m_h2CalpeakADCREF->getHistogram(theVxdID, 0);
562  checkU = m_h2CalpeakADCCHECK->getHistogram(theVxdID, 1);
563  checkV = m_h2CalpeakADCCHECK->getHistogram(theVxdID, 0);
564  minY = refU->GetYaxis()->GetXmin();
565  maxY = refU->GetYaxis()->GetXmax();
566  leftLine = -m_cutCalpeakADC_out;
567  rightLine = m_cutCalpeakADC_out;
568  topLine = 15;
569  } else if (variable == "CalpeakTime") {
570  refU = m_h2CalpeakTimeREF->getHistogram(theVxdID, 1);
571  refV = m_h2CalpeakTimeREF->getHistogram(theVxdID, 0);
572  checkU = m_h2CalpeakTimeCHECK->getHistogram(theVxdID, 1);
573  checkV = m_h2CalpeakTimeCHECK->getHistogram(theVxdID, 0);
574  minY = refU->GetYaxis()->GetXmin();
575  maxY = refU->GetYaxis()->GetXmax();
576  } else if (variable == "Pedestal") {
577  refU = m_h2PedestalREF->getHistogram(theVxdID, 1);
578  refV = m_h2PedestalREF->getHistogram(theVxdID, 0);
579  checkU = m_h2PedestalCHECK->getHistogram(theVxdID, 1);
580  checkV = m_h2PedestalCHECK->getHistogram(theVxdID, 0);
581  // minY = refU->GetYaxis()->GetXmin();
582  // maxY = refU->GetYaxis()->GetXmax();
583  minY = 250;
584  maxY = 500;
585  leftLine = -m_cutPedestal_out;
586  rightLine = m_cutPedestal_out;
587  topLine = 25;
588  }
589  refU->GetYaxis()->SetRangeUser(minY, maxY);
590  refV->GetYaxis()->SetRangeUser(minY, maxY);
591  checkU->GetYaxis()->SetRangeUser(minY, maxY);
592  checkV->GetYaxis()->SetRangeUser(minY, maxY);
593 
594  refU->SetMarkerColor(kRed);
595  refV->SetMarkerColor(kRed);
596  checkU->SetMarkerColor(kBlue);
597  checkV->SetMarkerColor(kBlue);
598 
599  float min = minY;
600  float max = maxY;
601 
602  //create outliers lines
603  TLine lLeft(leftLine, 0, leftLine, topLine);
604  TLine lRight(rightLine, 0, rightLine, topLine);
605  lLeft.SetLineColor(15);
606  lRight.SetLineColor(15);
607  lLeft.SetLineStyle(kDashed);
608  lRight.SetLineStyle(kDashed);
609 
610  //create APVlines
611  TLine l1(128, min, 128, max);
612  TLine l2(128 * 2, min, 128 * 2, max);
613  TLine l3(128 * 3, min, 128 * 3, max);
614  TLine l4(128 * 4, min, 128 * 4, max);
615  TLine l5(128 * 5, min, 128 * 5, max);
616  l1.SetLineColor(15);
617  l2.SetLineColor(15);
618  l3.SetLineColor(15);
619  l4.SetLineColor(15);
620  l5.SetLineColor(15);
621  TCanvas* c = new TCanvas();
622  TPaveText* pt_sensorID = new TPaveText(.495, 0.485, .505, 0.505, "blNDC");
623  char name[50];
624  sprintf(name, "%d.%d.%.d", theVxdID.getLayerNumber(), theVxdID.getLadderNumber(), theVxdID.getSensorNumber());
625  pt_sensorID->AddText(name);
626  pt_sensorID->SetTextFont(82);
627  pt_sensorID->SetTextColor(kBlack);
628  pt_sensorID->SetShadowColor(0);
629  pt_sensorID->SetFillColor(10);
630  pt_sensorID->SetBorderSize(0);
631  pt_sensorID->SetTextSize(0.08);
632 
633 
634  c->Divide(2, 2);
635  c->cd(1);
636  refU->Draw();
637  l1.Draw("same");
638  l2.Draw("same");
639  l3.Draw("same");
640  l4.Draw("same");
641  l5.Draw("same");
642  refU->Draw("same");
643  checkU->Draw("same");
644  m_leg2D->Draw("same");
645 
646  c->cd(2);
647  TH1F* objDiff;
648  int count = 0;
649  if (m_plotGoodAPVs) {
650  TIter nextH_uGood(listUGOOD);
651  while ((objDiff = (TH1F*)nextH_uGood())) {
652  objDiff->SetFillStyle(3004);
653  if (count == 0)
654  objDiff->Draw();
655  else
656  objDiff->Draw("same");
657  count++;
658  }
659  }
660  TIter nextH_uBad(listUBAD);
661  while ((objDiff = (TH1F*)nextH_uBad())) {
662  objDiff->SetFillStyle(0);
663  if (count == 0)
664  objDiff->Draw();
665  else
666  objDiff->Draw("same");
667  count++;
668  }
669  if (count > 0) {
670  lLeft.Draw("same");
671  lRight.Draw("same");
672  m_legU->Draw("same");
673  }
674 
675  c->cd(3);
676  refV->Draw();
677  l1.Draw("same");
678  l2.Draw("same");
679  l3.Draw("same");
680  if (isL3) {
681  l4.Draw("same");
682  l5.Draw("same");
683  }
684 
685  refV->Draw("same");
686  checkV->Draw("same");
687  m_leg2D->Draw("same");
688 
689  c->cd(4);
690  TIter nextH_vBad(listVBAD);
691  count = 0;
692  if (m_plotGoodAPVs) {
693  TIter nextH_vGood(listVGOOD);
694  while ((objDiff = (TH1F*)nextH_vGood())) {
695  objDiff->SetFillStyle(3004);
696  if (count == 0)
697  objDiff->Draw();
698  else
699  objDiff->Draw("same");
700  count++;
701  }
702  }
703  while ((objDiff = (TH1F*)nextH_vBad())) {
704  objDiff->SetFillStyle(0);
705  if (count == 0)
706  objDiff->Draw();
707  else
708  objDiff->Draw("same");
709  count++;
710  }
711  if (count > 0) {
712  lLeft.Draw("same");
713  lRight.Draw("same");
714  if (isL3)
715  m_legU->Draw("same");
716  else
717  m_legV->Draw("same");
718  }
719  c->cd();
720  if (variable == "Noise")
721  pt_sensorID->Draw("same");
722  c->Print(m_outputPdfName.c_str());
723 
724 }
725 
726 int SVDLocalCalibrationsCheckModule::hasAnyProblem(TH1F* h, float cutAve, float cutCOUNT)
727 {
728 
729  float average = h->GetMean();
730  if (std::fabs(average) > cutAve)
731  return 1;
732 
733  TAxis* xaxis = h->GetXaxis();
734  Int_t bin1 = xaxis->FindBin(-cutCOUNT);
735  Int_t bin2 = xaxis->FindBin(cutCOUNT);
736  if (bin1 > bin2) {
737  int tmp = bin1;
738  bin1 = bin2;
739  bin2 = tmp;
740  }
741 
742  B2DEBUG(1, bin1 << " -> " << bin2 << " with " << xaxis->GetNbins() << " bins");
743 
744  if (h->Integral(1, bin1) > m_cutN_out - 1) return 2;
745 
746  if (h->Integral(bin2, xaxis->GetNbins()) > m_cutN_out - 1) return 3;
747 
748  return 0;
749 }
750 
751 
753 {
754 
756  std::set<Belle2::VxdID> svdLayers = aGeometry.getLayers(VXD::SensorInfoBase::SVD);
757  std::set<Belle2::VxdID>::iterator itSvdLayers = svdLayers.begin();
758 
759  while ((itSvdLayers != svdLayers.end()) && (itSvdLayers->getLayerNumber() != 7)) { //loop on Layers
760 
761  std::set<Belle2::VxdID> svdLadders = aGeometry.getLadders(*itSvdLayers);
762  std::set<Belle2::VxdID>::iterator itSvdLadders = svdLadders.begin();
763 
764  while (itSvdLadders != svdLadders.end()) { //loop on Ladders
765 
766  std::set<Belle2::VxdID> svdSensors = aGeometry.getSensors(*itSvdLadders);
767  std::set<Belle2::VxdID>::iterator itSvdSensors = svdSensors.begin();
768 
769  while (itSvdSensors != svdSensors.end()) { //loop on sensors
770 
771  int layer = itSvdSensors->getLayerNumber();
772  int ladder = itSvdSensors->getLadderNumber();
773  int sensor = itSvdSensors->getSensorNumber();
774  Belle2::VxdID theVxdID(layer, ladder, sensor);
775  const SVD::SensorInfo* currentSensorInfo = dynamic_cast<const SVD::SensorInfo*>(&VXD::GeoCache::get(theVxdID));
776 
777  for (int side = 0; side < 2; side++) {
778 
779  int Ncells = currentSensorInfo->getUCells();
780  if (side == 0)
781  Ncells = currentSensorInfo->getVCells();
782 
783  int Napv = Ncells / 128;
784 
785  for (int m_APV = 0; m_APV < Napv; m_APV++) {
786 
787  TH1F* h = m_APVhistos->getHistogram(theVxdID, side, m_APV);
788 
789  h->SetFillColor(m_apvColors[m_APV]);
790  h->SetLineColor(m_apvColors[m_APV]);
791  h->SetMarkerColor(m_apvColors[m_APV]);
792  }
793  }
794 
795  ++itSvdSensors;
796  }
797  ++itSvdLadders;
798  }
799  ++itSvdLayers;
800  }
801 
802 
803 }
804 
805 
807 {
808 
809  TPaveText* pt_cuts_title = new TPaveText(.05, .6, .95, .65);
810  TPaveText* pt_cuts = new TPaveText(.15, .5, .85, .55);
811  char cuts[512];
812  sprintf(cuts, "%s", "SUMMARY");
813  pt_cuts_title->SetShadowColor(0);
814  pt_cuts_title->SetBorderSize(0);
815  pt_cuts_title->SetTextSize(0.03);
816  pt_cuts_title->AddText(cuts);
817  sprintf(cuts, "each bin of the plots in the next pages contains the number of problematic APV chips of the sensor");
818  pt_cuts->AddText(cuts);
819  sprintf(cuts, "corresponding to the combination of column (ladder number) and row (layer and sensor number)");
820  pt_cuts->AddText(cuts);
821  pt_cuts->SetTextSize(0.02);
822  pt_cuts->SetShadowColor(0);
823  pt_cuts->SetBorderSize(0);
824  pt_cuts->SetFillColor(10);
825  pt_cuts->SetTextAlign(12);
826 
827  TCanvas* explain = new TCanvas();
828  pt_cuts_title->Draw();
829  pt_cuts->Draw();
830  explain->Print(m_outputPdfName.c_str());
831 
832  TCanvas* noise = new TCanvas();
833  noise->SetGridx();
834  noise->Divide(2, 2);
835  noise->cd(1);
836  m_hNoiseSummary->getHistogram(1)->Draw("colztext");
837  noise->cd(3);
838  m_hNoiseSummary->getHistogram(0)->Draw("colztext");
839  noise->Print(m_outputPdfName.c_str());
840 
841  TCanvas* calpeakADC = new TCanvas();
842  calpeakADC->Divide(2, 2);
843  calpeakADC->cd(1);
844  m_hCalpeakADCSummary->getHistogram(1)->Draw("colztext");
845  calpeakADC->cd(3);
846  m_hCalpeakADCSummary->getHistogram(0)->Draw("colztext");
847  calpeakADC->Print(m_outputPdfName.c_str());
848 
849 
850 
851  TCanvas* pedestal = new TCanvas();
852  pedestal->Divide(2, 2);
853  pedestal->cd(1);
854  m_hPedestalSummary->getHistogram(1)->Draw("colztext");
855  pedestal->cd(3);
856  m_hPedestalSummary->getHistogram(0)->Draw("colztext");
857  pedestal->Print(m_outputPdfName.c_str());
858 
859 
860 }
861 
863 {
864 
865  TCanvas* empty = new TCanvas();
866  TString pdf_close = TString(m_outputPdfName) + "]";
867  empty->Print(pdf_close);
868 
869 
870 }
871 
872 
874 {
875 
876 
877  m_legU = new TLegend(0.75, 0.55, 0.89, 0.89);
878  m_legV = new TLegend(0.75, 0.65, 0.89, 0.89);
879  m_legU->SetFillStyle(0);
880  m_legV->SetFillStyle(0);
881 
882 
883  TH1F* hAPV1 = new TH1F("apv1", "apv 1", 1, 0, 1);
884  hAPV1->SetLineColor(m_apvColors[0]);
885  m_legU->AddEntry(hAPV1, "apv 1", "l");
886  m_legV->AddEntry(hAPV1, "apv 1", "l");
887  TH1F* hAPV2 = new TH1F("apv2", "apv 2", 2, 0, 2);
888  hAPV2->SetLineColor(m_apvColors[1]);
889  hAPV2->SetMarkerColor(m_apvColors[1]);
890  hAPV2->SetMarkerStyle(21);
891  hAPV2->SetMarkerSize(0.5);
892  m_legU->AddEntry(hAPV2, "apv 2", "l");
893  m_legV->AddEntry(hAPV2, "apv 2", "l");
894  TH1F* hAPV3 = new TH1F("apv3", "apv 3", 3, 0, 3);
895  hAPV3->SetLineColor(m_apvColors[2]);
896  m_legU->AddEntry(hAPV3, "apv 3", "l");
897  m_legV->AddEntry(hAPV3, "apv 3", "l");
898  TH1F* hAPV4 = new TH1F("apv4", "apv 4", 4, 0, 4);
899  hAPV4->SetLineColor(m_apvColors[3]);
900  hAPV4->SetMarkerColor(m_apvColors[3]);
901  hAPV4->SetMarkerStyle(21);
902  hAPV4->SetMarkerSize(0.5);
903  m_legU->AddEntry(hAPV4, "apv 4", "l");
904  m_legV->AddEntry(hAPV4, "apv 4", "l");
905  TH1F* hAPV5 = new TH1F("apv5", "apv 5", 5, 0, 5);
906  hAPV5->SetLineColor(m_apvColors[4]);
907  m_legU->AddEntry(hAPV5, "apv 5", "l");
908  TH1F* hAPV6 = new TH1F("apv6", "apv 6", 6, 0, 6);
909  hAPV6->SetLineColor(m_apvColors[5]);
910  m_legU->AddEntry(hAPV6, "apv 6", "l");
911 
912  m_leg2D = new TLegend(0.78, 0.75, 0.89, 0.89);
913  m_leg2D->AddEntry(hAPV2, "ref", "pl");
914  m_leg2D->AddEntry(hAPV4, "check", "pl");
915  m_leg2D->SetFillStyle(0);
916 }
917 
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
H * getHistogram(const VxdID &vxdID, int view, int apv)
get a reference to the histogram for
void fill(const VxdID &vxdID, int view, int apv, Types ... args)
fill the histogram for
H * getHistogram(const VxdID &vxdID, int view)
get a reference to the histogram for
Definition: SVDHistograms.h:56
SVDHistograms< TH2F > * m_h2CalpeakADCREF
CALPEAKS ADC.
void printSummaryPages()
summary page with 2D summary plot
SVDSummaryPlots * m_hCalpeakADCSummary
calpeakADC summary histo
TFile * m_rootFilePtrCHECK
pointer at the CHECK root file
SVDHistograms< TH2F > * m_h2CalpeakTimeCHECK
calpeakTime VS strip 2D histo
void printPage(VxdID theVxdID, TList *listUBAD, TList *listVBAD, TList *listUGOOD, TList *listVGOOD, TString variable, bool isL3)
print the page relative to a sensor with problematic APVs
int m_cutN_out
maximum number of allowed outliers
SVDAPVHistograms< TH1F > * m_hCalpeakTimeDIFF
calpeakTime histo
SVDLocalCalibrationsCheckModule()
Constructor: Sets the description, the properties and the parameters of the module.
TBranch * b_calPeakADCCHECK
strip calPeakADC (ADC of max pulse)
SVDHistograms< TH2F > * m_h2CalpeakADCCHECK
calpeakADC VS strip 2D histo
virtual void event() override
perform analysis and Draw pdf Canvas
TBranch * b_calPeakADCREF
strip calPeakADC (ADC of max pulse)
float m_cutPedestal_ave
maximum relative deviation APV-average (pedestal)
TFile * m_rootFilePtrREF
pointer at the REFERENCE root file
float m_cutCalpeakADC_ave
maximum relative deviation APV-average (calpeakADC)
void printLayerPage(int layer)
print layer-number page
SVDSummaryPlots * m_hCalpeakTimeSummary
calpeakTime summary histo
float m_cutCalpeakADC_out
maximum relative deviation strip (calpeakADC)
std::string m_idFileNameCHECK
ID of the xml file name CHECK.
SVDHistograms< TH2F > * m_h2NoiseCHECK
noise VS strip 2D histo
SVDAPVHistograms< TH1F > * m_hPedestalDIFF
pedestal histo
bool m_plotGoodAPVs
if true also the good APVs are plotted on the DIFF canvas
float m_cutNoise_ave
maximum relative deviation APV-average (noise)
TBranch * b_calPeakTimeCHECK
strip calPeakTime (time of max pulse)
virtual void beginRun() override
initialize the TTrees and create SVDHistograms and SVDAPVHistograms
float m_cutNoise_out
maximum relative deviation strip (noise)
void printConfiguration()
print the configuration of the check of the calibration VS a reference calibration
int hasAnyProblem(TH1F *h, float cutAve, float cutCOUNT)
return True if the APV has a problem, given a variable
std::string m_rootFileNameREF
root file name REFERENCE
std::string m_idFileNameREF
ID of the xml file name REFERENCE.
SVDAPVHistograms< TH1F > * m_hCalpeakADCDIFF
calpeakADC histo
SVDHistograms< TH2F > * m_h2PedestalCHECK
pedestal VS strip 2D histo
TBranch * b_calPeakTimeREF
strip calPeakTime (time of max pulse)
void printFirstPage()
print the first page of the output pdf
void createLegends()
create the TLegends for the plot
SVDAPVHistograms< TH1F > * m_hNoiseDIFF
noise histo
SVDSummaryPlots * m_hPedestalSummary
pedestal summary histo
SVDSummaryPlots * m_hNoiseSummary
noise summary histo
void setAPVHistoStyles(SVDAPVHistograms< TH1F > *m_APVhistos)
set style of APV histograms
SVDHistograms< TH2F > * m_h2CalpeakTimeREF
CALPEAKS TIME.
float m_cutPedestal_out
maximum relative deviation strip (pedestal)
class to summarize SVD quantities per sensor and side
void fill(int layer, int ladder, int sensor, int view, float value)
fill the histogram for
TH2F * getHistogram(int view)
get a reference to the histogram for
Specific implementation of SensorInfo for SVD Sensors which provides additional sensor specific infor...
Definition: SensorInfo.h:25
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
const std::set< Belle2::VxdID > getLayers(SensorInfoBase::SensorType sensortype=SensorInfoBase::VXD)
Return a set of all known Layers.
Definition: GeoCache.cc:176
const std::set< Belle2::VxdID > & getSensors(Belle2::VxdID ladder) const
Return a set of all sensor IDs belonging to a given ladder.
Definition: GeoCache.cc:204
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition: GeoCache.cc:214
static const SensorInfoBase & get(Belle2::VxdID id)
Return a reference to the SensorInfo of a given SensorID.
Definition: GeoCache.h:139
const std::set< Belle2::VxdID > & getLadders(Belle2::VxdID layer) const
Return a set of all ladder IDs belonging to a given layer.
Definition: GeoCache.cc:193
int getVCells() const
Return number of pixel/strips in v direction.
int getUCells() const
Return number of pixel/strips in u direction.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
baseType getSensorNumber() const
Get the sensor id.
Definition: VxdID.h:100
baseType getLadderNumber() const
Get the ladder id.
Definition: VxdID.h:98
baseType getLayerNumber() const
Get the layer id.
Definition: VxdID.h:96
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
Abstract base class for different kinds of events.