Belle II Software development
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
19namespace 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
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
TH2Poly * getPoly(int view, int min=-1111, int max=-1111)
Create the TH2Poly version of the plot.
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
TH2F * getHistogram(int view)
get a reference to 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
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.