Belle II Software  release-06-01-15
DQMHistAnalysisSVDEfficiency.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 // File : DQMHistAnalysisSVDEfficiency.cc
10 // Description : module for DQM histogram analysis of SVD sensors efficiencies
11 //-
12 
13 
14 #include <dqm/analysis/modules/DQMHistAnalysisSVDEfficiency.h>
15 #include <vxd/geometry/GeoCache.h>
16 
17 #include <TROOT.h>
18 #include <TStyle.h>
19 #include <TString.h>
20 
21 using namespace std;
22 using namespace Belle2;
23 
24 //-----------------------------------------------------------------
25 // Register the Module
26 //-----------------------------------------------------------------
27 REG_MODULE(DQMHistAnalysisSVDEfficiency)
28 
29 //-----------------------------------------------------------------
30 // Implementation
31 //-----------------------------------------------------------------
32 
35  m_effUstatus(good),
36  m_effVstatus(good)
37 {
38  //Parameter definition
39  B2DEBUG(10, "DQMHistAnalysisSVDEfficiency: Constructor done.");
40 
41  setDescription("DQM Analysis Module that computes the average SVD sensor efficiency.");
42 
43  addParam("RefHistoFile", m_refFileName, "Reference histogram file name", std::string("SVDrefHisto.root"));
44  addParam("effLevel_Error", m_effError, "Efficiency error (%) level (red)", float(0.9));
45  addParam("effLevel_Warning", m_effWarning, "Efficiency WARNING (%) level (orange)", float(0.94));
46  addParam("statThreshold", m_statThreshold, "minimal number of tracks per sensor to set green/red alert", float(100));
47 }
48 
49 DQMHistAnalysisSVDEfficiencyModule::~DQMHistAnalysisSVDEfficiencyModule() { }
50 
51 void DQMHistAnalysisSVDEfficiencyModule::initialize()
52 {
53  B2DEBUG(10, "DQMHistAnalysisSVDEfficiency: initialized.");
54  B2DEBUG(10, " black = " << kBlack);
55  B2DEBUG(10, " green = " << kGreen);
56  B2DEBUG(10, " orange = " << kOrange);
57  B2DEBUG(10, " Red = " << kRed);
58 
59  m_refFile = NULL;
60  if (m_refFileName != "") {
61  m_refFile = new TFile(m_refFileName.data(), "READ");
62  }
63 
64  //search for reference
65  if (m_refFile && m_refFile->IsOpen()) {
66  B2INFO("SVD DQMHistAnalysis: reference root file (" << m_refFileName << ") FOUND, reading ref histograms");
67 
68  TH1F* ref_eff = (TH1F*)m_refFile->Get("refEfficiency");
69  if (!ref_eff)
70  B2WARNING("SVD DQMHistAnalysis: Efficiency Level Reference not found! using module parameters");
71  else {
72  m_effWarning = ref_eff->GetBinContent(2);
73  m_effError = ref_eff->GetBinContent(3);
74  }
75 
76  } else
77  B2WARNING("SVD DQMHistAnalysis: reference root file (" << m_refFileName << ") not found, or closed, using module parameters");
78 
79  B2INFO(" SVD efficiency thresholds:");
80  B2INFO(" EFFICIENCY: normal < " << m_effWarning << " < warning < " << m_effError << " < error");
81 
82 
83  //build the legend
84  m_legProblem = new TPaveText(11, findBinY(4, 3) - 3, 16, findBinY(4, 3));
85  m_legProblem->AddText("ERROR!");
86  m_legProblem->AddText("at least one sensor with:");
87  m_legProblem->AddText(Form("efficiency < %1.0f%%", m_effError * 100));
88  m_legProblem->SetFillColor(kRed);
89  m_legWarning = new TPaveText(11, findBinY(4, 3) - 3, 16, findBinY(4, 3));
90  m_legWarning->AddText("WARNING!");
91  m_legWarning->AddText("at least one sensor with:");
92  m_legWarning->AddText(Form("%1.0f%% < efficiency < %1.0f%%", m_effError * 100, m_effWarning * 100));
93  m_legWarning->SetFillColor(kOrange);
94  m_legNormal = new TPaveText(11, findBinY(4, 3) - 3, 16, findBinY(4, 3));
95  m_legNormal->AddText("EFFICIENCY WITHIN LIMITS");
96  m_legNormal->AddText(Form("efficiency > %1.0f%%", m_effWarning * 100));
97  m_legNormal->SetFillColor(kGreen);
98  m_legNormal->SetBorderSize(0.);
99  m_legNormal->SetLineColor(kBlack);
100  m_legEmpty = new TPaveText(11, findBinY(4, 3) - 2, 16, findBinY(4, 3));
101  m_legEmpty->AddText("Not enough statistics,");
102  m_legEmpty->AddText("check again in a few minutes");
103  m_legEmpty->SetFillColor(kBlack);
104  m_legEmpty->SetTextColor(kWhite);
105  m_legEmpty->SetBorderSize(0.);
106  m_legEmpty->SetLineColor(kBlack);
107 
108 
109  const VXD::GeoCache& geo = VXD::GeoCache::getInstance();
110 
111  //collect the list of all SVD Modules in the geometry here
112  std::vector<VxdID> sensors = geo.getListOfSensors();
113  for (VxdID& aVxdID : sensors) {
114  VXD::SensorInfoBase info = geo.getSensorInfo(aVxdID);
115  // B2INFO("VXD " << aVxdID);
116  if (info.getType() != VXD::SensorInfoBase::SVD) continue;
117  m_SVDModules.push_back(aVxdID); // reorder, sort would be better
118  }
119  std::sort(m_SVDModules.begin(), m_SVDModules.end()); // back to natural order
120 
121  gROOT->cd();
122  m_cEfficiencyU = new TCanvas("SVDAnalysis/c_SVDEfficiencyU");
123  m_cEfficiencyV = new TCanvas("SVDAnalysis/c_SVDEfficiencyV");
124  m_cEfficiencyErrU = new TCanvas("SVDAnalysis/c_SVDEfficiencyErrU");
125  m_cEfficiencyErrV = new TCanvas("SVDAnalysis/c_SVDEfficiencyErrV");
126 
127  m_hEfficiency = new SVDSummaryPlots("SVDEfficiency@view", "Summary of SVD efficiencies (%), @view/@side Side");
128  m_hEfficiencyErr = new SVDSummaryPlots("SVDEfficiencyErr@view", "Summary of SVD efficiencies errors (%), @view/@side Side");
129 }
130 
131 void DQMHistAnalysisSVDEfficiencyModule::beginRun()
132 {
133  B2DEBUG(10, "DQMHistAnalysisSVDEfficiency: beginRun called.");
134  m_cEfficiencyU->Clear();
135  m_cEfficiencyV->Clear();
136  m_cEfficiencyErrU->Clear();
137  m_cEfficiencyErrV->Clear();
138 }
139 
140 void DQMHistAnalysisSVDEfficiencyModule::event()
141 {
142  B2DEBUG(10, "DQMHistAnalysisSVDEfficiency: event called.");
143 
144  //SETUP gSTYLE - all plots
145  // gStyle->SetOptStat(0);
146  // gStyle->SetTitleY(.97);
147 
148  //set dedicate gStyle
149  // const Int_t colNum = 4;
150  // Int_t palette[colNum] {kBlack, kGreen, kOrange, kRed};
151  // gStyle->SetPalette(colNum, palette);
152  gStyle->SetOptStat(0);
153  gStyle->SetPaintTextFormat("2.1f");
154 
155  m_hEfficiency->getHistogram(0)->Reset();
156  m_hEfficiency->getHistogram(1)->Reset();
157  m_hEfficiencyErr->getHistogram(0)->Reset();
158  m_hEfficiencyErr->getHistogram(1)->Reset();
159 
160  Float_t effU = -1;
161  Float_t effV = -1;
162  Float_t erreffU = -1;
163  Float_t erreffV = -1;
164 
165  // Efficiency for the U side
166  TH2F* found_tracksU = (TH2F*)findHist("SVDEfficiency/TrackHitsU");
167  TH2F* matched_clusU = (TH2F*)findHist("SVDEfficiency/MatchedHitsU");
168 
169  if (matched_clusU == NULL || found_tracksU == NULL) {
170  B2INFO("Histograms needed for Efficiency computation are not found");
171  m_cEfficiencyU->SetFillColor(kRed);
172  } else {
173  B2INFO("U-side Before loop on sensors, size :" << m_SVDModules.size());
174  m_effUstatus = good;
175  for (unsigned int i = 0; i < m_SVDModules.size(); i++) {
176  B2DEBUG(10, "module " << i << "," << m_SVDModules[i]);
177  int bin = found_tracksU->FindBin(m_SVDModules[i].getLadderNumber(), findBinY(m_SVDModules[i].getLayerNumber(),
178  m_SVDModules[i].getSensorNumber()));
179  float numU = matched_clusU->GetBinContent(bin);
180  float denU = found_tracksU->GetBinContent(bin);
181  if (denU > 0)
182  effU = numU / denU;
183  else
184  effU = -1;
185  B2DEBUG(10, "effU = " << numU << "/" << denU << " = " << effU);
186  m_hEfficiency->fill(m_SVDModules[i], 1, effU * 100);
187  if (effU == -1)
188  erreffU = -1;
189  else
190  erreffU = std::sqrt(effU * (1 - effU) / denU);
191  m_hEfficiencyErr->fill(m_SVDModules[i], 1, erreffU * 100);
192 
193  if (denU < m_statThreshold) {
194  m_effUstatus = std::max(lowStat, m_effUstatus);
195  } else if (effU > m_effWarning) {
196  m_effUstatus = std::max(good, m_effUstatus);
197  } else if ((effU <= m_effWarning) && (effU > m_effError)) {
198  m_effUstatus = std::max(warning, m_effUstatus);
199  } else if ((effU <= m_effError)) {
200  m_effUstatus = std::max(error, m_effUstatus);
201  }
202  B2DEBUG(10, "Status is " << m_effUstatus);
203  }
204  }
205 
206  //Efficiency for the V side
207  TH2F* found_tracksV = (TH2F*)findHist("SVDEfficiency/TrackHitsV");
208  TH2F* matched_clusV = (TH2F*)findHist("SVDEfficiency/MatchedHitsV");
209 
210  if (matched_clusV == NULL || found_tracksV == NULL) {
211  B2INFO("Histograms needed for Efficiency computation are not found");
212  m_cEfficiencyV->SetFillColor(kRed);
213  } else {
214  B2INFO("V-side Before loop on sensors, size :" << m_SVDModules.size());
215  m_effVstatus = good;
216  for (unsigned int i = 0; i < m_SVDModules.size(); i++) {
217  B2DEBUG(10, "module " << i << "," << m_SVDModules[i]);
218  int bin = found_tracksV->FindBin(m_SVDModules[i].getLadderNumber(), findBinY(m_SVDModules[i].getLayerNumber(),
219  m_SVDModules[i].getSensorNumber()));
220  float numV = matched_clusV->GetBinContent(bin);
221  float denV = found_tracksV->GetBinContent(bin);
222  if (denV > 0)
223  effV = numV / denV;
224  else
225  effV = -1;
226 
227  B2DEBUG(10, "effV = " << numV << "/" << denV << " = " << effV);
228  m_hEfficiency->fill(m_SVDModules[i], 0, effV * 100);
229  if (effV == -1)
230  erreffV = -1;
231  else
232  erreffV = std::sqrt(effV * (1 - effV) / denV);
233 
234  m_hEfficiencyErr->fill(m_SVDModules[i], 0, erreffV * 100);
235 
236  if (denV < m_statThreshold) {
237  m_effVstatus = std::max(lowStat, m_effVstatus);
238  } else if (effV > m_effWarning) {
239  m_effVstatus = std::max(good, m_effVstatus);
240  } else if ((effV <= m_effWarning) && (effV > m_effError)) {
241  m_effVstatus = std::max(warning, m_effVstatus);
242  } else if ((effV <= m_effError)) {
243  m_effVstatus = std::max(error, m_effVstatus);
244  }
245  B2DEBUG(10, "Status is " << m_effVstatus);
246  }
247  }
248 
249  // update summary for U side
250  m_cEfficiencyU->cd();
251  m_hEfficiency->getHistogram(1)->Draw("text");
252 
253  switch (m_effUstatus) {
254  case good: {
255  m_cEfficiencyU->SetFillColor(kGreen);
256  m_cEfficiencyU->SetFrameFillColor(10);
257  m_legNormal->Draw("same");
258  break;
259  }
260  case error: {
261  m_cEfficiencyU->SetFillColor(kRed);
262  m_cEfficiencyU->SetFrameFillColor(10);
263  m_legProblem->Draw("same");
264  break;
265  }
266  case warning: {
267  m_cEfficiencyU->SetFillColor(kOrange);
268  m_cEfficiencyU->SetFrameFillColor(10);
269  m_legWarning->Draw("same");
270  break;
271  }
272  case lowStat: {
273  m_cEfficiencyU->SetFillColor(kGray);
274  m_cEfficiencyU->SetFrameFillColor(10);
275  m_legEmpty->Draw("same");
276  break;
277  }
278  default: {
279  B2INFO("effUstatus not set properly: " << m_effUstatus);
280  break;
281  }
282  }
283 
284  m_cEfficiencyU->Draw("text");
285  m_cEfficiencyU->Update();
286  m_cEfficiencyU->Modified();
287  m_cEfficiencyU->Update();
288 
289  // update summary for V side
290  m_cEfficiencyV->cd();
291  m_hEfficiency->getHistogram(0)->Draw("text");
292 
293  switch (m_effVstatus) {
294  case good: {
295  m_cEfficiencyV->SetFillColor(kGreen);
296  m_cEfficiencyV->SetFrameFillColor(10);
297  m_legNormal->Draw("same");
298  break;
299  }
300  case error: {
301  m_cEfficiencyV->SetFillColor(kRed);
302  m_cEfficiencyV->SetFrameFillColor(10);
303  m_legProblem->Draw("same");
304  break;
305  }
306  case warning: {
307  m_cEfficiencyV->SetFillColor(kOrange);
308  m_cEfficiencyV->SetFrameFillColor(10);
309  m_legWarning->Draw("same");
310  break;
311  }
312  case lowStat: {
313  m_cEfficiencyV->SetFillColor(kGray);
314  m_cEfficiencyV->SetFrameFillColor(10);
315  m_legEmpty->Draw("same");
316  break;
317  }
318  default: {
319  B2INFO("effVstatus not set properly: " << m_effVstatus);
320  break;
321  }
322  }
323 
324  m_cEfficiencyV->Draw();
325  m_cEfficiencyV->Update();
326  m_cEfficiencyV->Modified();
327  m_cEfficiencyV->Update();
328 
329  m_cEfficiencyErrU->cd();
330  m_hEfficiencyErr->getHistogram(1)->Draw("colztext");
331  m_cEfficiencyErrU->Draw();
332  m_cEfficiencyErrU->Update();
333  m_cEfficiencyErrU->Modified();
334  m_cEfficiencyErrU->Update();
335 
336  m_cEfficiencyErrV->cd();
337  m_hEfficiencyErr->getHistogram(0)->Draw("colztext");
338  m_cEfficiencyErrV->Draw();
339  m_cEfficiencyErrV->Update();
340  m_cEfficiencyErrV->Modified();
341  m_cEfficiencyErrV->Update();
342 }
343 
344 void DQMHistAnalysisSVDEfficiencyModule::endRun()
345 {
346  B2DEBUG(10, "DQMHistAnalysisSVDEfficiency: endRun called");
347 }
348 
349 void DQMHistAnalysisSVDEfficiencyModule::terminate()
350 {
351  B2DEBUG(10, "DQMHistAnalysisSVDEfficiency: terminate called");
352 
353  delete m_refFile;
354  delete m_legProblem;
355  delete m_legWarning;
356  delete m_legNormal;
357  delete m_legEmpty;
358  delete m_hEfficiency;
359  delete m_cEfficiencyU;
360  delete m_cEfficiencyV;
361  delete m_hEfficiencyErr;
362  delete m_cEfficiencyErrU;
363  delete m_cEfficiencyErrV;
364 }
365 
366 // return y coordinate in TH2F histogram for specified sensor
367 Int_t DQMHistAnalysisSVDEfficiencyModule::findBinY(Int_t layer, Int_t sensor)
368 {
369  if (layer == 3)
370  return sensor; //2 -> 1,2
371  if (layer == 4)
372  return 2 + 1 + sensor; //6 -> 4,5,6
373  if (layer == 5)
374  return 6 + 1 + sensor; // 11 -> 8, 9, 10, 11
375  if (layer == 6)
376  return 11 + 1 + sensor; // 17 -> 13, 14, 15, 16, 17
377  else
378  return -1;
379 }
380 
The base class for the histogram analysis module.
Class definition for the output module of Sequential ROOT I/O.
class to summarize SVD quantities per sensor and side
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
const std::vector< VxdID > getListOfSensors() const
Get list of all sensors.
Definition: GeoCache.cc:58
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:66
Base class to provide Sensor Information for PXD and SVD.
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.