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