Belle II Software  release-05-01-25
TimeWalkCalibrationAlgorithm.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Makoto Uchida *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <cdc/calibration/TimeWalkCalibrationAlgorithm.h>
12 #include <cdc/dbobjects/CDCTimeWalks.h>
13 #include <cdc/geometry/CDCGeometryPar.h>
14 #include <cdc/dataobjects/WireID.h>
15 
16 #include <TF1.h>
17 #include <TFile.h>
18 #include <TDirectory.h>
19 #include <TROOT.h>
20 #include <TTree.h>
21 #include <framework/database/DBObjPtr.h>
22 #include <framework/database/IntervalOfValidity.h>
23 #include <framework/logging/Logger.h>
24 
25 using namespace std;
26 using namespace Belle2;
27 using namespace CDC;
28 
29 TimeWalkCalibrationAlgorithm::TimeWalkCalibrationAlgorithm() : CalibrationAlgorithm("CDCCalibrationCollector")
30 {
32  " -------------------------- Time Walk Calibration Algorithm -------------------------\n"
33  );
34 }
35 
37 {
38  B2INFO("Creating and filling histograms");
39 
41 
42  double halfCSize[56];
43  for (int i = 0; i < 56; ++i) {
44  double R = cdcgeo.senseWireR(i);
45  double nW = cdcgeo.nWiresInLayer(i);
46  halfCSize[i] = M_PI * R / nW;
47  }
48 
49  // Histogram for each board
50  for (int i = 0; i < 300; ++i) {
51  m_h2[i] = new TH2D(Form("board_%d", i), Form("board_%d", i), 50, 0., 500, 60, -30, 30);
52  }
53 
54  // Read data
55 
56  auto tree = getObjectPtr<TTree>("tree");
57 
58  Float_t x;
59  Float_t t_mea;
60  Float_t t_fit;
61  Float_t ndf;
62  Float_t Pval;
63  UShort_t adc;
64  UShort_t IWire;
65  UChar_t lay;
66 
67  tree->SetBranchAddress("lay", &lay);
68  tree->SetBranchAddress("IWire", &IWire);
69  tree->SetBranchAddress("x_u", &x);
70  tree->SetBranchAddress("t", &t_mea);
71  tree->SetBranchAddress("t_fit", &t_fit);
72  tree->SetBranchAddress("ndf", &ndf);
73  tree->SetBranchAddress("Pval", &Pval);
74  tree->SetBranchAddress("adc", &adc);
75 
76  /* Disable unused branch */
77  std::vector<TString> list_vars = {"lay", "IWire", "x_u", "t", "t_fit", "Pval", "ndf", "adc"};
78  tree->SetBranchStatus("*", 0);
79 
80  for (TString brname : list_vars) {
81  tree->SetBranchStatus(brname, 1);
82  }
83 
84  const Long64_t nEntries = tree->GetEntries();
85  B2INFO("Number of entries: " << nEntries);
86  for (Long64_t i = 0; i < nEntries; ++i) {
87  tree->GetEntry(i);
88  const double xmax = halfCSize[lay] - 0.12;
89  if ((fabs(x) < m_xmin) || (fabs(x) > xmax)
90  || (ndf < m_minNdf)
91  || (Pval < m_minPval)) continue; /*select good region*/
92 
93  m_h2[cdcgeo.getBoardID(WireID(lay, IWire))]->Fill(adc, fabs(t_mea) - fabs(t_fit));
94  }
95  B2INFO("Finish making histogram for all channels");
96 }
97 
99 {
100  B2INFO("Start calibration");
101  gROOT->SetBatch(1);
102 
103  const auto exprun = getRunList()[0];
104  B2INFO("ExpRun used for DB Geometry : " << exprun.first << " " << exprun.second);
105  updateDBObjPtrs(1, exprun.second, exprun.first);
106  B2INFO("Creating CDCGeometryPar object");
108 
109  prepare();
110  createHisto();
111 
112  TF1* fold = nullptr;
113  if (m_twParamMode == 0)
114  fold = new TF1("fold", "[0]/sqrt(x)", 0, 500);
115  else if (m_twParamMode == 1)
116  fold = new TF1("fold", "[0]*exp(-1*[1]*x)", 0, 500);
117 
118  if (fold == nullptr) {
119  B2FATAL("Old fitting function is not defined.");
120  }
121 
122 
123  B2INFO("time walk formular: ");
124  [](TF1 * f) { auto title = f->GetTitle(); B2INFO("Expression : " << title);}(fold);
125  // B2INFO("New time walk mode : " << m_twParamMode_new << " with " << m_nTwParams_new << " parameters");
126 
127  for (int ib = 1; ib < 300; ++ib) {
128  m_flag[ib] = 1;
129  B2DEBUG(21, "Board ID:" << ib);
130  m_h2[ib]->SetDirectory(0);
131 
132  // Ignore if histogram has low stat. (<500 entries)
133  if (m_h2[ib]->GetEntries() < 500) {
134  m_flag[ib] = 0;
135  continue;
136  }
137  m_h2[ib]->FitSlicesY(0, 1, -1, 10);
138  TString name = m_h2[ib]->GetName();
139  TString hm_name = name + "_1";
140  m_h1[ib] = (TH1D*)gDirectory->Get(hm_name);
141  if (!m_h1[ib]) {m_flag[ib] = 0; continue;}
142  m_h1[ib]->SetDirectory(0);
143  if (m_h1[ib]->GetEntries() < 5) {
144  m_flag[ib] = 0;
145  B2WARNING("Low statistic, number of points after slice fit: " << m_h1[ib]->GetEntries());
146  continue;
147  }
148 
149  // Add previous correction to this
150  for (int p = 0; p < m_nTwParams; ++p) {
151  fold->SetParameter(p, m_tw_old[ib][p]);
152  }
153 
154 
155  if (m_twParamMode == 0) {
156  TF1* func = new TF1("func", "[0]+[1]/sqrt(x)", 0, 500);
157  func->SetParameters(-4, 28);
158  m_h1[ib]->Fit("func", "MQ", "", 20, 150);
159  } else if (m_twParamMode == 1) {
160  m_h1[ib]->Add(fold);
162  } else {
163  B2FATAL("Mode " << m_twParamMode << " is not available, please check again");
164  }
165 
166  // Read fitted parameters
167  TF1* f1 = m_h1[ib]->GetFunction("func");
168  if (!f1) { m_flag[ib] = 0; continue;}
169  m_constTerm[ib] = f1->GetParameter(0);
170  for (int i = 1; i <= m_nTwParams; ++i) {
171  m_tw_new[ib][i - 1] = f1->GetParameter(i);
172  }
173 
174 
175  B2DEBUG(21, "Prob of fitting:" << f1->GetProb());
176  B2DEBUG(21, "Fitting Param 0-1:" << f1->GetParameter(0) << " - " << f1->GetParameter(1));
177 
178  }
179 
180  //Write histogram to file
181  if (m_storeHisto) {
182  storeHist();
183  }
184 
185  write();
186  updateT0();
187 
188  return checkConvergence();
189 }
190 
192 {
193  B2INFO("Storing histogram");
194  B2DEBUG(21, "Store 1D histogram");
195  TFile* fhist = new TFile(m_histName.c_str(), "RECREATE");
196  auto hNDF = getObjectPtr<TH1F>("hNDF");
197  auto hPval = getObjectPtr<TH1F>("hPval");
198  auto hEvtT0 = getObjectPtr<TH1F>("hEventT0");
199  //store NDF, P-val. EventT0 histogram for monitoring during calibration
200  if (hNDF && hPval && hEvtT0) {
201  hEvtT0->Write();
202  hPval->Write();
203  hNDF->Write();
204  }
205 
206  TDirectory* old = gDirectory;
207  TDirectory* h1D = old->mkdir("h1D");
208  TDirectory* h2D = old->mkdir("h2D");
209  h1D->cd();
210  for (int ib = 1; ib < 300; ++ib) {
211  if (!m_h1[ib] || m_flag[ib] != 1) continue;
212  if (m_h1[ib]->GetEntries() < 5) continue;
213  m_h1[ib]->SetMinimum(-5);
214  m_h1[ib]->SetMaximum(15);
215  m_h1[ib]->Write();
216  }
217 
218  B2DEBUG(21, "Store 2D histogram");
219  h2D->cd();
220  for (int ib = 1; ib < 300; ++ib) {
221  if (m_h2[ib] == nullptr) continue;
222  if (m_h2[ib]->GetEntries() < 5) continue;
223  m_h2[ib]->Write();
224 
225  }
226 
227  fhist->Close();
228  B2INFO("Hitograms were stored");
229 }
230 
232 {
233  TH1F* hDtw = new TH1F("hDtw", "", 100, -1, 1);
234  for (int ib = 0; ib < 300; ++ib) {
235  float dtw = (m_tw_new[ib][0] - m_tw_old[ib][0]) / m_tw_old[ib][0];
236  if (std::isnan(dtw) == 0) {
237  hDtw->Fill(dtw);
238  }
239  }
240 
241  B2INFO(hDtw->GetRMS());
242 
243  if (hDtw->GetRMS() < 0.02) {
244  return c_OK;
245  } else {
246  return c_Iterate;
247  }
248  delete hDtw;
249 }
250 
252 {
253  B2INFO("Save to the local DB");
254  CDCTimeWalks* dbTw = new CDCTimeWalks();
255  int nfailure = 0;
256 
258  for (int ib = 0; ib < 300; ++ib) {
259  if (m_flag[ib] != 1) {
260  nfailure += 1;
261  }
262  if (m_twParamMode == 0) {
263  const int num = static_cast<int>(m_tw_old[ib].size());
264  for (int i = 0; i < num; ++i) {
265  m_tw_new[ib][i] += m_tw_old[ib][i];
266  }
267  }
268 
269  dbTw->setTimeWalkParams(ib, m_tw_new[ib]);
270  }
271 
272  if (m_textOutput == true) {
274  B2RESULT("Time-walk coeff. table has been written to " << m_outputTWFileName.c_str());
275  }
276 
277  saveCalibration(dbTw, "CDCTimeWalks");
278  B2RESULT("Failure to calibrate time-walk for " << nfailure << " board");
279 
280 }
281 
283 {
284  B2INFO("Prepare calibration");
285 
287  m_twParamMode = dbTw->getTwParamMode();
288 
289  if (!(m_twParamMode == 0 || m_twParamMode == 1)) {
290  B2FATAL("Mode " << m_twParamMode << " haven't implemented yet.");
291  }
292 
293  B2INFO("tw param mode " << m_twParamMode);
294  const int nEntries = dbTw->getEntries();
295  for (int ib = 0; ib < nEntries; ++ib) {
296  m_tw_old[ib] = dbTw->getTimeWalkParams(ib);
297  m_tw_new[ib].resize(m_nTwParams, 0.0);
298  }
299 }
300 
302 {
303  B2INFO("Add constant term into T0 database");
305  CDCTimeZeros* tz = new CDCTimeZeros();
306  double T0;
307  for (int ilay = 0; ilay < 56; ++ilay) {
308  for (unsigned int iwire = 0; iwire < cdcgeo.nWiresInLayer(ilay); ++iwire) {
309  WireID wireid(ilay, iwire);
310  int bID = cdcgeo.getBoardID(wireid);
311  if (m_flag[bID] == 1) {
312  T0 = cdcgeo.getT0(wireid);
313  tz->setT0(wireid, T0 - m_constTerm[bID]);
314  }
315  }
316  }
317  if (m_textOutput == true) {
319  }
320  saveCalibration(tz, "CDCTimeZeros");
321 }
322 
324 {
325  h1->SetDirectory(0);
326  int max = h1->GetMaximumBin();
327  double maxX = h1->GetBinCenter(max);
328  double maxY = h1->GetBinContent(max);
329  B2DEBUG(21, "Max: id - x - y : " << max << " " << maxX << " " << maxY);
330 
331  //search for p0
332  double p0 = -1;
333  h1->Fit("pol0", "MQE", "", maxX + 125, 500);
334  if (h1->GetFunction("pol0")) {
335  p0 = h1->GetFunction("pol0")->GetParameter(0);
336  }
337  //create histo = old-p0;
338  // fit with expo function to find intial parameters
339  TH1D* hshift = new TH1D("hshift", "shift", h1->GetNbinsX(), 0, 500);
340  hshift->SetDirectory(0);
341  for (int i = 0; i <= h1->GetNbinsX(); ++i) {
342  hshift->SetBinContent(i, h1->GetBinContent(i) - p0);
343  }
344  hshift->Fit("expo", "MQE", "", 0, 400);
345  double p1 = maxY + p0;
346  double p2 = -0.04;
347  if (hshift->GetFunction("expo")) {
348  p1 = exp(hshift->GetFunction("expo")->GetParameter(0));
349  p2 = hshift->GetFunction("expo")->GetParameter(1);
350  }
351 
352  // fit with function
353  TF1* func = new TF1("func", "[0]+ [1]*exp(-1*[2]*x)", 0, 500);
354  func->SetParameters(p0, p1, -1 * p2);
355  func->SetParLimits(0, -5, 5);
356  func->SetParLimits(1, -5, 500);
357  func->SetParLimits(2, -0.01, 0.1);
358  h1->Fit("func", "MQE", "", 10, 400);
359 }
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_outputT0FileName
std::string m_outputT0FileName
t0 file name after calibration.
Definition: TimeWalkCalibrationAlgorithm.h:121
Belle2::WireID
Class to identify a wire inside the CDC.
Definition: WireID.h:44
Belle2::CDC::TimeWalkCalibrationAlgorithm::prepare
void prepare()
prepare calibration.
Definition: TimeWalkCalibrationAlgorithm.cc:282
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_constTerm
double m_constTerm[300]
const term in fitting, it will be added to T0 instead tw
Definition: TimeWalkCalibrationAlgorithm.h:113
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_cdcGeo
DBObjPtr< CDCGeometry > m_cdcGeo
Geometry of CDC.
Definition: TimeWalkCalibrationAlgorithm.h:127
Belle2::CalibrationAlgorithm::saveCalibration
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
Definition: CalibrationAlgorithm.cc:290
Belle2::CDC::TimeWalkCalibrationAlgorithm::checkConvergence
EResult checkConvergence()
check convergence.
Definition: TimeWalkCalibrationAlgorithm.cc:231
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_h1
TH1D * m_h1[300]
Mean of residual as function of ADC of each board.
Definition: TimeWalkCalibrationAlgorithm.h:107
Belle2::CDCTimeWalks
Database object for time-walk.
Definition: CDCTimeWalks.h:35
Belle2::CDCTimeZeros::setT0
void setT0(unsigned short iCLayer, unsigned short iWire, float t0)
Set t0 in the list.
Definition: CDCTimeZeros.h:50
Belle2::CDC::TimeWalkCalibrationAlgorithm::calibrate
EResult calibrate() override
Run algo on data.
Definition: TimeWalkCalibrationAlgorithm.cc:98
Belle2::CalibrationAlgorithm::c_Iterate
@ c_Iterate
Needs iteration =1 in Python.
Definition: CalibrationAlgorithm.h:52
Belle2::CDCTimeZeros::outputToFile
void outputToFile(std::string fileName) const
Output the contents in text file format.
Definition: CDCTimeZeros.h:133
Belle2::CalibrationAlgorithm::c_OK
@ c_OK
Finished successfuly =0 in Python.
Definition: CalibrationAlgorithm.h:51
Belle2::CalibrationAlgorithm::setDescription
void setDescription(const std::string &description)
Set algorithm description (in constructor)
Definition: CalibrationAlgorithm.h:331
Belle2::CalibrationAlgorithm::updateDBObjPtrs
void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
Definition: CalibrationAlgorithm.cc:398
Belle2::CDC::TimeWalkCalibrationAlgorithm::updateT0
void updateT0()
update constant term to t0 database.
Definition: TimeWalkCalibrationAlgorithm.cc:301
Belle2::CDC::TimeWalkCalibrationAlgorithm::fitToExponentialFunc
void fitToExponentialFunc(TH1D *h1)
fit tw histogram
Definition: TimeWalkCalibrationAlgorithm.cc:323
Belle2::DBObjPtr
Class for accessing objects in the database.
Definition: DBObjPtr.h:31
Belle2::CDC::CDCGeometryPar
The Class for CDC Geometry Parameters.
Definition: CDCGeometryPar.h:75
Belle2::CDC::CDCGeometryPar::senseWireR
double senseWireR(int layerId) const
Returns radius of sense wire in each layer.
Definition: CDCGeometryPar.h:1231
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_minNdf
double m_minNdf
minimum number of degree of freedom required for track.
Definition: TimeWalkCalibrationAlgorithm.h:111
Belle2::CDCTimeWalks::setTimeWalkParams
void setTimeWalkParams(unsigned short boardID, const std::vector< float > &params)
Set the time-walk coefficients in the list.
Definition: CDCTimeWalks.h:58
Belle2::CDC::CDCGeometryPar::Instance
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
Definition: CDCGeometryPar.cc:41
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_twParamMode
unsigned short m_twParamMode
=0 for P0/Sqrt(ADC); =1 for P0*Exp(-P1*ADC).
Definition: TimeWalkCalibrationAlgorithm.h:125
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_nTwParams
unsigned short m_nTwParams
No.
Definition: TimeWalkCalibrationAlgorithm.h:126
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_textOutput
bool m_textOutput
output text file if true
Definition: TimeWalkCalibrationAlgorithm.h:124
Belle2::CDCTimeZeros
Database object for timing offset (t0).
Definition: CDCTimeZeros.h:36
Belle2::CDC::CDCGeometryPar::getBoardID
unsigned short getBoardID(const WireID &wID) const
Returns frontend board id. corresponding to the wire id.
Definition: CDCGeometryPar.h:576
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_outputTWFileName
std::string m_outputTWFileName
tw file name after calibration.
Definition: TimeWalkCalibrationAlgorithm.h:120
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_storeHisto
bool m_storeHisto
Store all Histogram or not.
Definition: TimeWalkCalibrationAlgorithm.h:117
Belle2::CalibrationAlgorithm::EResult
EResult
The result of calibration.
Definition: CalibrationAlgorithm.h:50
Belle2::CalibrationAlgorithm::getRunList
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
Definition: CalibrationAlgorithm.h:276
Belle2::CDC::CDCGeometryPar::getT0
float getT0(const WireID &wireID) const
Returns t0 parameter of the specified sense wire.
Definition: CDCGeometryPar.h:565
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_h2
TH2D * m_h2[300]
2D histogram of residual vs ADC for each board.
Definition: TimeWalkCalibrationAlgorithm.h:108
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_histName
std::string m_histName
root file name
Definition: TimeWalkCalibrationAlgorithm.h:122
Belle2::CDC::CDCGeometryPar::nWiresInLayer
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
Definition: CDCGeometryPar.h:1211
Belle2::CDCTimeWalks::setTwParamMode
void setTwParamMode(unsigned short mode)
Set tw parameterization mode mode=0: tw (in ns) = p0/sqrt(FADCsum); mode=1: tw( in ns) = p0*exp(-p1*F...
Definition: CDCTimeWalks.h:48
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_tw_old
std::vector< float > m_tw_old[300]
tw list before calibration.
Definition: TimeWalkCalibrationAlgorithm.h:115
Belle2::CalibrationAlgorithm
Base class for calibration algorithms.
Definition: CalibrationAlgorithm.h:47
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_minPval
double m_minPval
minimum number of Prob(chi2) of fitted track.
Definition: TimeWalkCalibrationAlgorithm.h:112
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_xmin
double m_xmin
minimum value cut of drift length.
Definition: TimeWalkCalibrationAlgorithm.h:110
Belle2::CDC::TimeWalkCalibrationAlgorithm::createHisto
void createHisto()
Create histo for calibrate.
Definition: TimeWalkCalibrationAlgorithm.cc:36
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_flag
unsigned short m_flag[300]
flag for fit status
Definition: TimeWalkCalibrationAlgorithm.h:114
Belle2::CDCTimeWalks::outputToFile
void outputToFile(std::string fileName) const
Output the contents in text file format.
Definition: CDCTimeWalks.h:144
Belle2::CDC::TimeWalkCalibrationAlgorithm::m_tw_new
std::vector< float > m_tw_new[300]
tw list after calibration.
Definition: TimeWalkCalibrationAlgorithm.h:116
Belle2::CDC::TimeWalkCalibrationAlgorithm::storeHist
void storeHist()
Store histograms.
Definition: TimeWalkCalibrationAlgorithm.cc:191
Belle2::CDC::TimeWalkCalibrationAlgorithm::write
void write()
save calibration.
Definition: TimeWalkCalibrationAlgorithm.cc:251