Belle II Software  release-08-01-10
CDCDedx1DCellAlgorithm.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 <algorithm>
10 #include <iostream>
11 
12 #include <TCanvas.h>
13 #include <TH1D.h>
14 #include <TLine.h>
15 #include <TTree.h>
16 #include <TMath.h>
17 
18 #include <reconstruction/calibration/CDCDedx1DCellAlgorithm.h>
19 
20 using namespace Belle2;
21 
22 
23 //-----------------------------------------------------------------
24 // Implementation
25 //-----------------------------------------------------------------
26 
28  CalibrationAlgorithm("CDCDedxElectronCollector"),
29  fnEntaBinG(128),
30  fnEntaBinL(64),
31  feaLE(-TMath::Pi() / 2),
32  feaUE(+TMath::Pi() / 2),
33  fSetPrefix("_it0"),
34  IsLocalBin(true),
35  IsMakePlots(false),
36  IsRS(true)
37 {
38  // Set module properties
39  setDescription("A calibration algorithm for the CDC dE/dx entrance angle cleanup correction");
40 }
41 
42 //-----------------------------------------------------------------
43 // Run the calibration
44 //-----------------------------------------------------------------
45 
47 {
48 
49  //reading electron collector TREE
50  auto ttree = getObjectPtr<TTree>("tree");
51  if (ttree->GetEntries() < 100)return c_NotEnoughData;
52 
53  std::vector<double>* dedxhit = 0, *enta = 0;
54  std::vector<int>* layer = 0;
55 
56  ttree->SetBranchAddress("dedxhit", &dedxhit);
57  ttree->SetBranchAddress("layer", &layer);
58  ttree->SetBranchAddress("entaRS", &enta);
59 
60  // Setting up bins for entra angle
61  feaBS = (feaUE - feaLE) / fnEntaBinG;
62 
63  std::vector<int> globalbins;
64  for (int ibin = 0; ibin < fnEntaBinG; ibin++)globalbins.push_back(ibin);
65 
66  if (!IsLocalBin) {
67  fEntaBinNums = globalbins;
69  } else {
71  fnEntaBinL = fEntaBinNums.at(fEntaBinNums.size() - 1) + 1;
72  }
73 
74  //enta dedx distributions for inner and outer layer
75  std::vector<TH1D*> hILdEdxhitInEntaBin(fnEntaBinL, 0);
76  std::vector<TH1D*> hOLdEdxhitInEntaBin(fnEntaBinL, 0);
77 
78  Double_t ifeaLE = 0, ifeaUE = 0;
79 
80  for (int iea = 0; iea < fnEntaBinL; iea++) {
81 
82  if (IsLocalBin) {
83  ifeaLE = fEntaBinValues.at(iea);
84  ifeaUE = fEntaBinValues.at(iea + 1);
85  } else {
86  ifeaLE = iea * feaBS - feaUE; //- because of -ive range shifting
87  ifeaUE = ifeaLE + feaBS;
88  }
89 
90  hILdEdxhitInEntaBin[iea] = new TH1D(Form("hILdEdxhitInEntaBin%d", iea), "bla-bla", 250, 0., 5.);
91  hILdEdxhitInEntaBin[iea]->SetTitle(Form("IL: dedxhit in EntA = (%0.03f to %0.03f)", ifeaLE, ifeaUE));
92  hILdEdxhitInEntaBin[iea]->GetXaxis()->SetTitle("dedxhits in Inner Layer");
93  hILdEdxhitInEntaBin[iea]->GetYaxis()->SetTitle("Entries");
94 
95  hOLdEdxhitInEntaBin[iea] = new TH1D(Form("hOLdEdxhitInEntaBin%d", iea), "bla-bla", 250, 0., 5.);
96  hOLdEdxhitInEntaBin[iea]->SetTitle(Form("OL: dedxhit in EntA = (%0.03f to %0.03f)", ifeaLE, ifeaUE));
97  hOLdEdxhitInEntaBin[iea]->GetXaxis()->SetTitle("dedxhits in Outer Layer");
98  hOLdEdxhitInEntaBin[iea]->GetYaxis()->SetTitle("Entries");
99  }
100 
101  // Enta stats
102  TH1D* hILEntaG = new TH1D("hILEntaG", "EntA: Inner Layer", fnEntaBinG, feaLE, feaUE);
103  hILEntaG->GetXaxis()->SetTitle("Entrance angle (#theta)");
104  hILEntaG->GetYaxis()->SetTitle("Entries");
105 
106  TH1D* hOLEntaG = new TH1D("hOLEntaG", "EntA: Outer Layer", fnEntaBinG, feaLE, feaUE);
107  hOLEntaG->GetXaxis()->SetTitle("Entrance angle (#theta)");
108  hOLEntaG->GetYaxis()->SetTitle("Entries");
109 
110  //rebinned histogram
111  Double_t* RmapEntaValue = &fEntaBinValues[0];
112 
113  TH1D* hILEntaL = new TH1D("hILEntaL", "EntA: Inner Layer (assym bin)", fnEntaBinL, RmapEntaValue);
114  hILEntaL->GetXaxis()->SetTitle("Entrance angle (#theta)");
115  hILEntaL->GetYaxis()->SetTitle("Entries");
116 
117  TH1D* hOLEntaL = new TH1D("hOLEntaL", "EntA: Outer Layer (assym bin)", fnEntaBinL, RmapEntaValue);
118  hOLEntaL->GetYaxis()->SetTitle("Entries");
119  hOLEntaL->GetXaxis()->SetTitle("Entrance angle (#theta)");
120 
121  TH1D* hILdEdx_all = new TH1D("hILdEdx_all", "", 250, 0., 5.);
122  TH1D* hOLdEdx_all = new TH1D("hOLdEdx_all", "", 250, 0., 5.);
123 
124  Int_t ibinEA = 0;
125  for (int i = 0; i < ttree->GetEntries(); ++i) {
126 
127  ttree->GetEvent(i);
128 
129  for (unsigned int j = 0; j < dedxhit->size(); ++j) {
130 
131  if (dedxhit->at(j) == 0) continue;
132 
133  Double_t ieaHit = enta->at(j);
134  if (ieaHit < -TMath::Pi() / 2.0) ieaHit += TMath::Pi() / 2.0;
135  else if (ieaHit > TMath::Pi() / 2.0) ieaHit -= TMath::Pi() / 2.0;
136  if (abs(ieaHit) > TMath::Pi() / 2.0) continue;
137 
138  //Bin corresponds to enta
139  ibinEA = (ieaHit - feaLE) / feaBS ; //from 0
140  if (ibinEA >= fnEntaBinG) continue; //bin stats from 0
141 
142  if (IsLocalBin) ibinEA = fEntaBinNums.at(ibinEA);
143 
144  if (layer->at(j) < 8) {
145  hILEntaG->Fill(ieaHit);
146  if (IsLocalBin)hILEntaL->Fill(ieaHit);
147  hILdEdx_all->Fill(dedxhit->at(j));
148  hILdEdxhitInEntaBin[ibinEA]->Fill(dedxhit->at(j));
149  } else {
150  hOLEntaG->Fill(ieaHit);
151  if (IsLocalBin)hOLEntaL->Fill(ieaHit);
152  hOLdEdx_all->Fill(dedxhit->at(j));
153  hOLdEdxhitInEntaBin[ibinEA]->Fill(dedxhit->at(j));
154  }
155  }
156  }
157 
158  if (IsMakePlots) {
159  TCanvas* ctmpde = new TCanvas("hEntaDist", "Enta distributions", 400, 400);
160  if (IsLocalBin) {
161  ctmpde->SetCanvasSize(800, 400);
162  ctmpde->Divide(2, 1);
163  ctmpde->cd(1); gPad->SetLogy(); hOLEntaG->SetMarkerColor(kBlue); hOLEntaG->Draw(""); hILEntaG->Draw("same");
164  ctmpde->cd(2); gPad->SetLogy(); hOLEntaL->SetMarkerColor(kBlue); hOLEntaL->Draw(""); hILEntaL->Draw("same");
165  } else {
166  hOLEntaG->Draw(""); hILEntaG->Draw("same");
167  }
168  ctmpde->SaveAs(Form("hEntaDistributions_%s.pdf", fSetPrefix.data()));
169 
170  }
171 
172  double InsumPer5 = 0.0, InsumPer75 = 0.0;
173  double OutsumPer5 = 0.0, OutsumPer75 = 0.0;
174  double InLayInt = hILdEdx_all->Integral();
175  double OutLayInt = hOLdEdx_all->Integral();
176 
177  Int_t lBinInLayer = 1, hBinInLayer = 1;
178  Int_t lBinOutLayer = 1, hBinOutLayer = 1;
179 
180  for (int ibin = 1; ibin <= hILdEdx_all->GetNbinsX(); ibin++) {
181 
182  if (InsumPer5 <= 0.05 * InLayInt) {
183  InsumPer5 += hILdEdx_all->GetBinContent(ibin);
184  lBinInLayer = ibin;
185  }
186 
187  if (InsumPer75 <= 0.75 * InLayInt) {
188  InsumPer75 += hILdEdx_all->GetBinContent(ibin);
189  hBinInLayer = ibin;
190  }
191 
192  if (OutsumPer5 <= 0.05 * OutLayInt) {
193  OutsumPer5 += hOLdEdx_all->GetBinContent(ibin);
194  lBinOutLayer = ibin;
195  }
196 
197  if (OutsumPer75 <= 0.75 * OutLayInt) {
198  OutsumPer75 += hOLdEdx_all->GetBinContent(ibin);
199  hBinOutLayer = ibin;
200  }
201  }
202 
203  if (IsMakePlots) {
204 
205  TCanvas* ctem = new TCanvas("Layerhisto", "Inner and Outer Histo", 1200, 600);
206  ctem->Divide(2, 1);
207  ctem->cd(1);
208  hILdEdx_all->SetMarkerColor(kBlue);
209  hILdEdx_all->Draw("histo");
210 
211  TLine* tlInF = new TLine();
212  tlInF->SetLineColor(kBlue);
213  tlInF->SetX1(InsumPer5); tlInF->SetX2(InsumPer5);
214  tlInF->SetY1(0); tlInF->SetY2(hILdEdx_all->GetMaximum());
215  tlInF->DrawClone("same");
216 
217  TLine* tlInL = new TLine();
218  tlInL->SetLineColor(kBlue);
219  tlInL->SetX1(InsumPer75); tlInL->SetX2(InsumPer75);
220  tlInL->SetY1(0); tlInL->SetY2(hILdEdx_all->GetMaximum());
221  tlInL->DrawClone("same");
222 
223  ctem->cd(2);
224  hOLdEdx_all->Draw("histo");
225  hOLdEdx_all->SetMarkerColor(kRed);
226 
227  TLine* tlOutF = new TLine();
228  tlOutF->SetLineColor(kBlue);
229  tlOutF->SetX1(OutsumPer5); tlOutF->SetX2(OutsumPer5);
230  tlOutF->SetY1(0); tlOutF->SetY2(hOLdEdx_all->GetMaximum());
231  tlOutF->DrawClone("same");
232 
233  TLine* tlOutL = new TLine();
234  tlOutL->SetLineColor(kBlue);
235  tlOutL->SetX1(OutsumPer75); tlOutL->SetX2(OutsumPer75);
236  tlOutL->SetY1(0); tlOutL->SetY2(hOLdEdx_all->GetMaximum());
237  tlOutL->DrawClone("same");
238  ctem->SaveAs(Form("Layerhistodedxhit_OneDCorr_%s.pdf", fSetPrefix.data()));
239  }
240 
241  //short version = 0;
242  TCanvas* ctmp = new TCanvas("tmp", "tmp", 1200, 1200);
243  ctmp->Divide(4, 4);
244  std::stringstream psname; psname << Form("dedx_1dcell_%s.pdf[", fSetPrefix.data());
245  TLine* tl = new TLine();
246  tl->SetLineColor(kRed);
247 
248  TBox* tb = new TBox();
249 
250  if (IsMakePlots) {
251  ctmp->Print(psname.str().c_str());
252  psname.str(""); psname << Form("dedx_1dcell_%s.pdf", fSetPrefix.data());
253  }
254 
255  TH1D* htemp = 0x0;
256  std::vector<std::vector<double>> onedcors; // prev->std::vector<std::vector<double>> ones;
257  std::vector<double> onedcorIorOL, onedcorIorOLtemp;
258 
259  TH1D* hILEntaConst = new TH1D("hILEntaConst", "EntA: Outer Layer", fnEntaBinG, feaLE, feaUE);
260  hILEntaConst->GetXaxis()->SetTitle("Entrance angle (#theta)");
261  hILEntaConst->GetYaxis()->SetTitle("Constant");
262 
263  TH1D* hOLEntaConst = new TH1D("hOLEntaConst", "EntA: Outer Layer", fnEntaBinG, feaLE, feaUE);
264  hOLEntaConst->GetXaxis()->SetTitle("Entrance angle (#theta)");
265  hOLEntaConst->GetYaxis()->SetTitle("Constant");
266 
267  for (int iIOLayer = 0; iIOLayer <= 1; iIOLayer++) {
268 
269  int startfrom = 1, endat = 1;
270 
271  if (iIOLayer == 0) {
272  startfrom = lBinInLayer; endat = hBinInLayer;
273  } else if (iIOLayer == 1) {
274  startfrom = lBinOutLayer; endat = hBinOutLayer;
275  } else continue;
276 
277  for (int iea = 1; iea <= fnEntaBinL; iea++) {
278 
279  Int_t ieaprime = iea; //rotation symmtery for 1<->3 and 4<->2
280 
281  if (IsRS)ieaprime = GetRotationSymmericBin(fnEntaBinL, iea);
282 
283  if (iIOLayer == 0)htemp = (TH1D*)hILdEdxhitInEntaBin[ieaprime - 1]->Clone(Form("hL%d_Ea%d", iIOLayer, iea));
284  else if (iIOLayer == 1)htemp = (TH1D*)hOLdEdxhitInEntaBin[ieaprime - 1]->Clone(Form("hL%d_Ea%d", iIOLayer, iea));
285  else continue;
286 
287  double truncMean = 1.0;
288  if (htemp->Integral() < 250) truncMean = 1.0; //low stats
289  else {
290  double binweights = 0.0;
291  int sumofbc = 0;
292  for (int ibin = startfrom; ibin <= endat; ibin++) {
293 
294  if (htemp->GetBinContent(ibin) > 0) {
295  binweights += (htemp->GetBinContent(ibin) * htemp->GetBinCenter(ibin));
296  sumofbc += htemp->GetBinContent(ibin);
297  }
298  }
299  if (sumofbc > 0)truncMean = (double)(binweights / sumofbc);
300  else truncMean = 1.0;
301  }
302 
303  if (truncMean <= 0)truncMean = 1.0; //protection only
304  onedcorIorOLtemp.push_back(truncMean);
305 
306  if (IsMakePlots) {
307  ctmp->cd(((iea - 1) % 16) + 1);
308  htemp->SetFillColorAlpha(kGreen, 0.30);
309  htemp->SetTitle(Form("%s, #mean = %0.2f", htemp->GetTitle(), truncMean));
310  if (truncMean >= 1.02 || truncMean <= 0.98)htemp->SetFillColor(kYellow);
311  if (truncMean >= 1.05 || truncMean <= 0.95)htemp->SetFillColor(kOrange);
312  if (truncMean >= 1.10 || truncMean <= 0.90)htemp->SetFillColor(kRed);
313  htemp->DrawClone("hist"); //clone is nessesory for pointer survival
314  tl->SetLineColor(kRed);
315  tl->SetX1(truncMean); tl->SetX2(truncMean);
316  tl->SetY1(0); tl->SetY2(htemp->GetMaximum());
317  tl->DrawClone("same");
318 
319  tb->SetLineColor(kPink);
320  tb->SetLineStyle(6);
321  tb->SetFillColorAlpha(kPink, 0.15);
322  tb->SetX1(htemp->GetBinLowEdge(startfrom));
323  tb->SetY1(0);
324  tb->SetX2(htemp->GetBinLowEdge(endat));
325  tb->SetY2(htemp->GetMaximum());
326  tb->DrawClone("same");
327  if (iea % 16 == 0)ctmp->Print(psname.str().c_str());
328  }
329 
330  htemp->Reset();
331  }
332 
333  for (int iea = 0; iea < fnEntaBinG; iea++) {
334  ibinEA = iea;
335  if (IsLocalBin)ibinEA = fEntaBinNums.at(iea);
336  onedcorIorOL.push_back(onedcorIorOLtemp.at(ibinEA));
337  if (iIOLayer == 0)hILEntaConst->SetBinContent(iea + 1, onedcorIorOLtemp.at(ibinEA));
338  else if (iIOLayer == 1)hOLEntaConst->SetBinContent(iea + 1, onedcorIorOLtemp.at(ibinEA));
339  }
340 
341  onedcors.push_back(onedcorIorOL);
342  onedcorIorOL.clear();
343  onedcorIorOLtemp.clear();
344  }
345 
346 
347  if (IsMakePlots) {
348  psname.str(""); psname << Form("dedx_1dcell_%s.pdf]", fSetPrefix.data());
349  ctmp->Print(psname.str().c_str());
350 
351  // //Drawing final constants
352  TCanvas* cconst = new TCanvas("FinalConstantHistoMap", "Inner and Outer Histo", 800, 400);
353  cconst->Divide(2, 1);
354  cconst->cd(1); hILEntaConst->Draw();
355  cconst->cd(2); hOLEntaConst->Draw();
356  cconst->SaveAs(Form("FinalOneDConstantMap_%s.pdf", fSetPrefix.data()));
357  }
358 
359  B2INFO("dE/dx Calibration done for 1D cleanup correction");
360  CDCDedx1DCell* gain = new CDCDedx1DCell(0, onedcors);
361  saveCalibration(gain, "CDCDedx1DCell");
362 
363  delete htemp;
364  delete ctmp;
365  delete tl;
366  delete tb;
367  return c_OK;
368 
369 }
CDCDedx1DCellAlgorithm()
Constructor: Sets the description, the properties and the parameters of the algorithm.
bool IsRS
if rotation symmtery requested
bool IsLocalBin
if local variable bins requested
std::vector< double > fEntaBinValues
Vector for doca asym bin values.
Double_t feaBS
Binwidth edge of enta angle.
std::vector< int > fEntaBinNums
Vector for enta asym bin values.
int fnEntaBinL
etna angle bins, Local
std::string fSetPrefix
suffix to filename
int GetRotationSymmericBin(int nbin, int ibin)
funtion to set rotation symmetry
bool IsMakePlots
produce plots for status
virtual EResult calibrate() override
1D cell algorithm
int fnEntaBinG
Save arithmetic and truncated mean for the 'dedx' values.
Double_t feaLE
Lower edge of enta angle.
void GetVariableBin(int nbin, std::vector< int > &nBinEnta0to100Per)
funtion to set variable bins
Double_t feaUE
Upper edge of enta angle.
dE/dx wire gain calibration constants
Definition: CDCDedx1DCell.h:27
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
Abstract base class for different kinds of events.