Belle II Software  release-08-01-10
T0Correction.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 #include <cdc/calibration/T0Correction.h>
9 #include <cdc/dbobjects/CDCTimeZeros.h>
10 #include <cdc/geometry/CDCGeometryPar.h>
11 #include <cdc/dataobjects/WireID.h>
12 
13 #include <TError.h>
14 #include <TROOT.h>
15 #include <TGraphErrors.h>
16 #include <TF1.h>
17 #include <TFile.h>
18 #include <TChain.h>
19 
20 #include <framework/database/IntervalOfValidity.h>
21 #include <framework/database/DBImportObjPtr.h>
22 #include <framework/logging/Logger.h>
23 
24 using namespace std;
25 using namespace Belle2;
26 using namespace CDC;
27 
29  m_firstExperiment(0), m_firstRun(0),
30  m_lastExperiment(-1), m_lastRun(-1)
31 {
32  /*
33  setDescription(
34  " -------------------------- Test Calibration Algoritm -------------------------\n"
35  " \n"
36  " Testing algorithm which just gets mean of a test histogram collected by \n"
37  " CaTest module and provides a DB object with another histogram with one \n"
38  " entry at calibrated value. \n"
39  " ------------------------------------------------------------------------------\n"
40  );
41  */
42 }
43 
45 {
46 
47  B2INFO("CreateHisto");
48  double x;
49  double t_mea;
50  double w;
51  double t_fit;
52  double ndf;
53  double Pval;
54  int IWire;
55  int lay;
56 
57  // auto& tree = getObject<TTree>("cdcCalib");
58  TChain* tree = new TChain("tree");
59  tree->Add(m_inputRootFileName.c_str());
60  tree->SetBranchAddress("lay", &lay);
61  tree->SetBranchAddress("IWire", &IWire);
62  tree->SetBranchAddress("x_u", &x);
63  tree->SetBranchAddress("t", &t_mea);
64  tree->SetBranchAddress("t_fit", &t_fit);
65  tree->SetBranchAddress("weight", &w);
66  tree->SetBranchAddress("ndf", &ndf);
67  tree->SetBranchAddress("Pval", &Pval);
68 
69  /* Disable unused branch */
70  std::vector<TString> list_vars = {"lay", "IWire", "x_u", "t", "t_fit", "weight", "Pval", "ndf"};
71  tree->SetBranchStatus("*", 0);
72 
73  for (TString brname : list_vars) {
74  tree->SetBranchStatus(brname, 1);
75  }
76 
77 
78  double halfCSize[56];
79  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
80  for (int i = 0; i < 56; ++i) {
81  double R = cdcgeo.senseWireR(i);
82  double nW = cdcgeo.nWiresInLayer(i);
83  halfCSize[i] = M_PI * R / nW;
84  }
85 
86  m_hTotal = new TH1F("hTotal", "hTotal", 30, -15, 15);
87  //for each channel
88  for (int il = 0; il < 56; il++) {
89  const int nW = cdcgeo.nWiresInLayer(il);
90  for (int ic = 0; ic < nW; ++ic) {
91  m_h1[il][ic] = new TH1F(Form("h1%d@%d", il, ic), Form("L%d_cell%d", il, ic), 30, -15, 15);
92  }
93  }
94  //for each board
95  for (int ib = 0; ib < 300; ++ib) {
96  m_hT0b[ib] = new TH1F(Form("hT0b%d", ib), Form("boardID_%d", ib), 100, -20, 20);
97  }
98  //read data
99  const int nEntries = tree->GetEntries();
100  B2INFO("Number of entries: " << nEntries);
101  for (int i = 0; i < nEntries; ++i) {
102  tree->GetEntry(i);
103  double xmax = halfCSize[lay] - 0.1;
104  if ((fabs(x) < m_xmin) || (fabs(x) > xmax)
105  || (ndf < m_ndfmin)
106  || (Pval < m_Pvalmin)) continue; /*select good region*/
107  //each channel
108  m_hTotal->Fill(t_mea - t_fit);
109  m_h1[lay][IWire]->Fill(t_mea - t_fit);
110  //each board
111  m_hT0b[cdcgeo.getBoardID(WireID(lay, IWire))]->Fill(t_mea - t_fit);
112  }
113  B2INFO("Finish making histogram for all channels");
114 }
115 
117 {
118  B2INFO("Start calibration");
119 
120  gROOT->SetBatch(1);
121  gErrorIgnoreLevel = 3001;
122 
123  CreateHisto();
124  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
125 
126  TF1* g1 = new TF1("g1", "gaus", -100, 100);
127  vector<double> b, db, Sb, dSb;
128  vector<double> c[56];
129  vector<double> dc[56];
130  vector<double> s[56];
131  vector<double> ds[56];
132 
133  B2INFO("Gaus fitting for whole channel");
134  double par[3];
135  m_hTotal->SetDirectory(0);
136  double mean = m_hTotal->GetMean();
137  m_hTotal->Fit("g1", "Q", "", mean - 15, mean + 15);
138  g1->GetParameters(par);
139 
140  B2INFO("Gaus fitting for each board");
141  for (int ib = 1; ib < 300; ++ib) {
142  if (m_hT0b[ib]->GetEntries() < 10) continue;
143  mean = m_hT0b[ib]->GetMean();
144  m_hT0b[ib]->SetDirectory(0);
145  m_hT0b[ib]->Fit("g1", "Q", "", mean - 15, mean + 15);
146  g1->GetParameters(par);
147  b.push_back(ib);
148  db.push_back(0.0);
149  Sb.push_back(par[1]);
150  dSb.push_back(g1->GetParError(1));
151  dtb[ib] = par[1];
152  err_dtb[ib] = g1->GetParError(1);
153  }
154  B2INFO("Gaus fitting for each cell");
155  for (int ilay = 0; ilay < 56; ++ilay) {
156  for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
157  const int n = m_h1[ilay][iwire]->GetEntries();
158  B2DEBUG(99, "layer " << ilay << " wire " << iwire << " entries " << n);
159  if (n < 10) continue;
160  mean = m_h1[ilay][iwire]->GetMean();
161  m_h1[ilay][iwire]->SetDirectory(0);
162  m_h1[ilay][iwire]->Fit("g1", "Q", "", mean - 15, mean + 15);
163  g1->GetParameters(par);
164  c[ilay].push_back(iwire);
165  dc[ilay].push_back(0.0);
166  s[ilay].push_back(par[1]);
167  ds[ilay].push_back(g1->GetParError(1));
168 
169  dt[ilay][iwire] = par[1];
170  err_dt[ilay][iwire] = g1->GetParError(1);
171  }
172  }
173 
174 
175  if (m_storeHisto) {
176  B2INFO("Store histo");
177  TFile* fout = new TFile("Correct_T0.root", "RECREATE");
178  fout->cd();
179  TGraphErrors* gr[56];
180  TDirectory* top = gDirectory;
181  m_hTotal->Write();
182  TDirectory* subDir[56];
183  for (int ilay = 0; ilay < 56; ++ilay) {
184  subDir[ilay] = top ->mkdir(Form("lay_%d", ilay));
185  subDir[ilay]->cd();
186  for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
187  m_h1[ilay][iwire]->Write();
188  }
189  }
190  top->cd();
191  TDirectory* corrT0 = top->mkdir("DeltaT0");
192  corrT0->cd();
193 
194  if (b.size() > 2) {
195  TGraphErrors* grb = new TGraphErrors(b.size(), &b.at(0), &Sb.at(0), &db.at(0), &dSb.at(0));
196  grb->SetMarkerColor(2);
197  grb->SetMarkerSize(1.0);
198  grb->SetTitle("#DeltaT0;BoardID;#DeltaT0[ns]");
199  grb->SetMaximum(10);
200  grb->SetMinimum(-10);
201  grb->SetName("Board");
202  grb->Write();
203  }
204  for (int sl = 0; sl < 56; ++sl) {
205  if (c[sl].size() < 2) continue;
206  gr[sl] = new TGraphErrors(c[sl].size(), &c[sl].at(0), &s[sl].at(0), &dc[sl].at(0), &ds[sl].at(0));
207  gr[sl]->SetMarkerColor(2);
208  gr[sl]->SetMarkerSize(1.0);
209  gr[sl]->SetTitle(Form("Layer_%d;IWire;#LT t_{mea}-t_{fit} #GT [ns]", sl));
210  gr[sl]->SetMaximum(10);
211  gr[sl]->SetMinimum(-10);
212  gr[sl]->SetName(Form("lay%d", sl));
213  gr[sl]->Write();
214  }
215  fout->Close();
216  }
217  B2INFO("Write constants");
218  Write();
219  return true;
220 }
222 {
223  static CDCGeometryPar& cdcgeo = CDCGeometryPar::Instance();
224  ofstream ofs(m_outputT0FileName.c_str());
226  tz.construct();
227 
228  double T0;
229  TH1F* T0B[300];
230  for (int ib = 0; ib < 300; ++ib) {
231  T0B[ib] = new TH1F(Form("T0B%d", ib), Form("boardID_%d", ib), 9000, 0, 9000);
232  }
233  //for calculate T0 mean of each board
234  for (int ilay = 0; ilay < 56; ++ilay) {
235  for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
236  WireID wireid(ilay, iwire);
237  T0 = cdcgeo.getT0(wireid);
238  T0B[cdcgeo.getBoardID(wireid)]->Fill(T0);
239  }
240  }
241 
242  //correct T0 and write
243  for (int ilay = 0; ilay < 56; ++ilay) {
244  for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
245  WireID wireid(ilay, iwire);
246  int bID = cdcgeo.getBoardID(wireid);
247  if (abs(err_dt[ilay][iwire]) > 2 || abs(dt[ilay][iwire]) > 1.e3) {
248  // if (abs(err_dt[ilay][iwire]) > 2) {
249  T0 = T0B[bID]->GetMean();
250  dt[ilay][iwire] = dtb[bID];
251  } else {
252  T0 = cdcgeo.getT0(wireid);
253  }
254  ofs << ilay << "\t" << iwire << "\t" << T0 - dt[ilay][iwire] << std::endl;
255  if (m_useDB) {
256  tz->setT0(wireid, T0 - dt[ilay][iwire]);
257  }
258  }
259  }
260  ofs.close();
261  if (m_useDB) {
262  IntervalOfValidity iov(m_firstExperiment, m_firstRun,
263  m_lastExperiment, m_lastRun);
264  tz.import(iov);
265  B2RESULT("T0 was calibrated and imported to database.");
266  }
267 
268 }
double R
typedef autogenerated by FFTW
The Class for CDC Geometry Parameters.
unsigned short getBoardID(const WireID &wID) const
Returns frontend board id. corresponding to the wire id.
float getT0(const WireID &wireID) const
Returns t0 parameter of the specified sense wire.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
double senseWireR(int layerId) const
Returns radius of sense wire in each layer.
T0Correction()
Constructor.
Definition: T0Correction.cc:28
virtual void Write()
write outut or store db
virtual bool calibrate()
Run algo on data.
virtual void CreateHisto()
create histo for each channel
Definition: T0Correction.cc:44
bool import(const IntervalOfValidity &iov)
Import the object to database.
Definition: DBImportBase.cc:36
Class for importing a single object to the database.
void construct(Args &&... params)
Construct an object of type T in this DBImportObjPtr using the provided constructor arguments.
A class that describes the interval of experiments/runs for which an object in the database is valid.
Class to identify a wire inside the CDC.
Definition: WireID.h:34
Abstract base class for different kinds of events.