Belle II Software  release-08-02-06
SVDSummaryPlots.h
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 #pragma once
10 #include <vxd/dataobjects/VxdID.h>
11 #include <string>
12 #include <regex>
13 #include <TH2F.h>
14 #include <TProfile.h>
15 
16 #include <TH2Poly.h>
17 #include <TMath.h>
18 
19 namespace Belle2 {
26  class SVDSummaryPlots: public TObject {
27 
28  public:
31  SVDSummaryPlots("", "") {};
37  SVDSummaryPlots(TString name, TString title)
38  {
39  m_defaultHistogram = new TH2F(name.Data(), title.Data(),
40  16, 0.5, 16.5,
41  19, 0, 19);
42 
43  for (int view = VIndex ; view < UIndex + 1; view++) {
44  std::string hname = name.Data();
45  bool isU = (view == UIndex);
46  customizeString(hname, isU);
47  m_histos[view] = new TH2F(hname.c_str(), title.Data(),
48  16, 0.5, 16.5,
49  19, 0, 19);
50  customize(*m_histos[view], view);
51  m_Title[view] = m_histos[view]->GetTitle();
52  }
53  }
54 
55 
58 
61  enum E_side { VIndex = 0, UIndex = 1 };
62 
66  TH2F* getHistogram(int view)
67  {
68  TH2F* returnValue = m_defaultHistogram;
69  try {
70  returnValue = m_histos[view];
71  } catch (...) {
72  B2WARNING("Unexpected view: " << view);
73 
74  returnValue = m_defaultHistogram;
75  }
76 
77  return returnValue;
78  }
79 
81  float getValue(const VxdID& vxdID, int view)
82  {
83  int layer = vxdID.getLayerNumber();
84  int ladder = vxdID.getLadderNumber();
85  int sensor = vxdID.getSensorNumber();
86 
87  return getValue(layer, ladder, sensor, view);
88  }
89 
96  float getValue(int layer, int ladder, int sensor, int view)
97  {
98  int bin = m_histos[view]->FindBin(ladder, findBinY(layer, sensor));
99  return getHistogram(view)->GetBinContent(bin);
100  }
101 
109  void fill(int layer, int ladder, int sensor, int view, float value)
110  {
111  getHistogram(view)->Fill(ladder, findBinY(layer, sensor), value);
112  }
113 
117  void fill(const VxdID& vxdID, int view, float value)
118  {
119  int layer = vxdID.getLayerNumber();
120  int ladder = vxdID.getLadderNumber();
121  int sensor = vxdID.getSensorNumber();
122 
123  fill(layer, ladder, sensor, view, value);
124  }
125 
129  void setRunID(const TString& runID)
130  {
131  for (int view = VIndex ; view < UIndex + 1; view++) {
132  // add blank if needed before adding runID
133  if (!m_Title[view].EndsWith(" "))
134  m_Title[view].Append(" ");
135 
136  getHistogram(view)->SetTitle(m_Title[view] + runID);
137  }
138  }
139 
142  void reset()
143  {
144  for (int view = VIndex ; view < UIndex + 1; view++)
145  getHistogram(view)->Reset();
146  }
147 
151  void setStats(bool stats = true)
152  {
153  for (int view = VIndex ; view < UIndex + 1; view++)
154  getHistogram(view)->SetStats(stats);
155  }
156 
158  void fill(const VxdID& vxdID, bool isU, float value)
159  {
160  int view = isU ? UIndex : VIndex;
161 
162  int layer = vxdID.getLayerNumber();
163  int ladder = vxdID.getLadderNumber();
164  int sensor = vxdID.getSensorNumber();
165 
166  fill(layer, ladder, sensor, view, value);
167  }
168 
170  void customizeString(std::string& base, bool isU)
171  {
172  std::string view = isU ? "U" : "V" ;
173  base = std::regex_replace(base, std::regex("[@]view"), view);
174  std::string side = isU ? "P" : "N" ;
175  base = std::regex_replace(base, std::regex("[@]side"), side);
176  }
177 
181  void setMinimum(Int_t value = 0)
182  {
183  for (int view = VIndex ; view < UIndex + 1; view++)
184  getHistogram(view)->SetMinimum(value);
185  }
186 
190  void setMaximum(Int_t value = 0)
191  {
192  for (int view = VIndex ; view < UIndex + 1; view++)
193  getHistogram(view)->SetMaximum(value);
194  }
195 
198  TH2Poly* getPoly(int view, int min = -1111, int max = -1111) //-1111 set the minimum depending on the content
199  {
200  TH2F* histogram = getHistogram(view);
201  TString name = histogram->GetName();
202  TString title = histogram->GetTitle();
203 
204  double xLow = -210.;
205  double xHigh = 210.;
206  double yLow = -210.;
207  double yHigh = 210.;
208 
209  if (m_polyHistos[view] == NULL) {
210  m_polyHistos[view] = new TH2Poly(name + "_poly", title, xLow, xHigh, yLow, yHigh);
212  m_polyHistos[view]->GetXaxis()->SetTitle("x");
213  m_polyHistos[view]->GetXaxis()->SetLabelSize(0);
214  m_polyHistos[view]->GetXaxis()->SetTickLength(0);
215  m_polyHistos[view]->GetXaxis()->SetTitleOffset(0.5);
216 
217  m_polyHistos[view]->GetYaxis()->SetTitle("y");
218  m_polyHistos[view]->GetYaxis()->SetLabelSize(0);
219  m_polyHistos[view]->GetYaxis()->SetTickLength(0);
220  m_polyHistos[view]->GetYaxis()->SetTitleOffset(0.5);
221  }
222 
223  m_polyHistos[view]->SetName(name + "poly");
224  m_polyHistos[view]->SetTitle(title);
225 
226  m_polyHistos[view]->SetMinimum(min);
227  m_polyHistos[view]->SetMaximum(max);
228 
229  const double nLadders[4] = {7, 10, 12, 16}; // per layer
230  const double nSensors[4] = {2, 3, 4, 5}; // per ladder
231 
232  for (int layer = 0; layer < 4; layer++) {
233  for (int ladder = 1; ladder < nLadders[layer] + 1; ladder++) {
234  for (int sensor = 1; sensor < nSensors[layer] + 1; sensor++) {
235  double value = getValue(layer + 3, ladder, sensor, view);
236  int bin = findBinPoly(layer + 3, ladder, sensor);
237  m_polyHistos[view]->SetBinContent(bin, value);
238  }
239  }
240  }
241 
242  return m_polyHistos[view];
243  }
244 
246  void clean()
247  {
248  delete m_histos[0];
249  delete m_histos[1];
250  delete m_defaultHistogram;
251  }
252 
253  private:
254 
256  Int_t findBinY(Int_t layer, Int_t sensor)
257  {
258 
259  if (layer == 3)
260  return sensor; //2
261  if (layer == 4)
262  return 2 + 1 + sensor; //6
263  if (layer == 5)
264  return 6 + 1 + sensor; // 11
265  if (layer == 6)
266  return 11 + 1 + sensor; // 17
267  else
268  return -1;
269  }
270 
271  TH2F* m_histos[2];
273  TH2Poly* m_polyHistos[2] = {nullptr};
275  TH2F* m_defaultHistogram = nullptr;
277  TString m_Title[2];
280  void customize(TH2F& histogram, int view)
281  {
282 
283  const int nY = 19;
284  TString Ylabels[nY] = {"", "L3.x.1", "L3.x.2",
285  " ", "L4.x.1", "L4.x.2", "L4.x.3",
286  " ", "L5.x.1", "L5.x.2", "L5.x.3", "L5.x.4",
287  " ", "L6.x.1", "L6.x.2", "L6.x.3", "L6.x.4", "L6.x.5", " "
288  };
289 
290  histogram.SetMarkerSize(1.1);
291  histogram.GetXaxis()->SetTitle("ladder number");
292  histogram.GetXaxis()->SetLabelSize(0.04);
293  for (unsigned short i = 0; i < nY; i++)
294  histogram.GetYaxis()->SetBinLabel(i + 1, Ylabels[i].Data());
295 
296  bool isU = view == UIndex;
297  std::string title = histogram.GetTitle();
298  customizeString(title, isU);
299  histogram.SetTitle(title.c_str());
300 
301  std::string xAxis = histogram.GetXaxis()->GetTitle();
302  customizeString(xAxis, isU);
303  histogram.SetXTitle(xAxis.c_str());
304 
305  std::string yAxis = histogram.GetYaxis()->GetTitle();
306  customizeString(yAxis, isU);
307  histogram.SetYTitle(yAxis.c_str());
308 
309  std::string zAxis = histogram.GetZaxis()->GetTitle();
310  customizeString(zAxis, isU);
311  histogram.SetZTitle(zAxis.c_str());
312 
313  }
314 
316  void generateHistogramBins(TH2Poly* histogram)
317  {
318  // parameters
319  const double rLayer[4] = {40, 70, 110, 160}; // arbitrary units. True radii are {39, 80, 104, 135}; // mm
320  const double nLadders[4] = {7, 10, 12, 16}; // per layer
321  const double nSensors[4] = {2, 3, 4, 5}; // per ladder
322  const double inclination[4] = {-17, -5, -13, -12}; // de.g. Layer inclination with respect to the x-axis
323  const double delta[4] = {9, 8, 8, 8}; // arbitrary units. Width of the bins for each sensor
324 
325  double pi = TMath::Pi();
326 
327  for (int layer = 0; layer < 4; layer ++) {
328  for (int ladder = 1; ladder <= nLadders[layer]; ladder++) {
329  for (int sensor = 1; sensor <= nSensors[layer]; sensor++) {
330  double r = rLayer[layer] + (delta[layer]) * (sensor - 1); //position of the layer + position of the sensor
331  double phi = 2 * pi / nLadders[layer]; // angle for each sensor (step)
332  double dphiThisPoint = (ladder - 1) * phi - phi / 2 + inclination[layer] * pi /
333  180.; // position of the edge of the sensor (ladder-1 to start from zero)
334  double dphiNextPoint = dphiThisPoint + phi; // position of the next edge of the sensor
335  // bin coordinates
336  double xr0 = r * TMath::Cos(dphiThisPoint);
337  double xr1 = (r + delta[layer]) * TMath::Cos(dphiThisPoint);
338  double xr2 = (r + delta[layer]) * TMath::Cos(dphiNextPoint);
339  double xr3 = r * TMath::Cos(dphiNextPoint);
340  double yr0 = r * TMath::Sin(dphiThisPoint);
341  double yr1 = (r + delta[layer]) * TMath::Sin(dphiThisPoint);
342  double yr2 = (r + delta[layer]) * TMath::Sin(dphiNextPoint);
343  double yr3 = r * TMath::Sin(dphiNextPoint);
344  // add bin to the histogram
345  double xbin[4] = {xr0, xr1, xr2, xr3};
346  double ybin[4] = {yr0, yr1, yr2, yr3};
347  histogram->AddBin(4, xbin, ybin);
348  // resetting bin coordinates
349  for (int k = 0; k < 4; k++) {
350  xbin[k] = 0.;
351  ybin[k] = 0.;
352  }
353  }
354  }
355  }
356  }
357 
359  Int_t findBinPoly(Int_t layer, Int_t ladder, Int_t sensor)
360  {
361  const int initBinPerLayer[4] = {1, 15, 45, 93};
362 
363  const double nLadders[4] = {7, 10, 12, 16}; // per layer
364  const double nSensors[4] = {2, 3, 4, 5}; // per ladder
365 
366  int bin = initBinPerLayer[layer - 3];
367 
368  for (int ld = 1; ld <= nLadders[layer - 3]; ld++) {
369  bool binFound = false;
370  for (int s = 1; s <= nSensors[layer - 3]; s++) {
371  if (ld == ladder && s == sensor) binFound = true;
372  if (binFound) break;
373  bin += 1;
374  }
375  if (binFound) break;
376  }
377  return bin;
378  }
379 
381  };
382 
383 
385 }
class to summarize SVD quantities per sensor and side
TH2Poly * getPoly(int view, int min=-1111, int max=-1111)
Create the TH2Poly version of the plot.
ClassDef(SVDSummaryPlots, 3)
needed by root
TH2F * m_histos[2]
vector containing the U and V histograms
void fill(const VxdID &vxdID, int view, float value)
fill the histogram for
~SVDSummaryPlots()
clean everything in the destructor
void clean()
delete pointers
Int_t findBinY(Int_t layer, Int_t sensor)
find the Y bin given the layer and sensor number
TH2Poly * m_polyHistos[2]
vector containing the U and V poly-histograms
void generateHistogramBins(TH2Poly *histogram)
generate histogram bins
void setStats(bool stats=true)
set histograms stat
void customizeString(std::string &base, bool isU)
replaces layer ladder sensor view and apv with the current numbers
SVDSummaryPlots(TString name, TString title)
this is the default constructor
float getValue(const VxdID &vxdID, int view)
get the value contained in the corresponding bin, given VxdID and view
void fill(int layer, int ladder, int sensor, int view, float value)
fill the histogram for
void setMinimum(Int_t value=0)
set histogram minimum
void fill(const VxdID &vxdID, bool isU, float value)
fill the histogram for
TH2F * getHistogram(int view)
get a reference to the histogram for
TString m_Title[2]
Base title.
SVDSummaryPlots()
Default constructor.
float getValue(int layer, int ladder, int sensor, int view)
get the value contained in the corresponding bin, given
Int_t findBinPoly(Int_t layer, Int_t ladder, Int_t sensor)
find the poly-bin given the layer, ladder and sensor number
void customize(TH2F &histogram, int view)
customize the histogram with the sensor, view
TH2F * m_defaultHistogram
default histograms
void setRunID(const TString &runID)
set run ids in title
void reset()
Reset histograms.
E_side
This enumeration assure the same semantic of the isU methods defined by Peter Kv.
void setMaximum(Int_t value=0)
set histogram maximum
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
Abstract base class for different kinds of events.