1 #include <cdc/calibration/TimeWalkCalibration.h>
2 #include <cdc/dbobjects/CDCTimeWalks.h>
3 #include <cdc/geometry/CDCGeometryPar.h>
4 #include <cdc/dataobjects/WireID.h>
9 #include <TDirectory.h>
11 #include <framework/utilities/FileSystem.h>
12 #include <framework/database/DBImportObjPtr.h>
13 #include <framework/database/DBObjPtr.h>
14 #include <framework/database/IntervalOfValidity.h>
15 #include <framework/logging/Logger.h>
21 TimeWalkCalibration::TimeWalkCalibration()
25 void TimeWalkCalibration::CreateHisto()
39 TChain* tree =
new TChain(
"tree");
40 tree->Add(m_InputRootFileName.c_str());
42 tree->SetBranchAddress(
"lay", &lay);
43 tree->SetBranchAddress(
"IWire", &IWire);
44 tree->SetBranchAddress(
"x_u", &x);
45 tree->SetBranchAddress(
"t", &t_mea);
46 tree->SetBranchAddress(
"t_fit", &t_fit);
47 tree->SetBranchAddress(
"weight", &w);
48 tree->SetBranchAddress(
"ndf", &ndf);
49 tree->SetBranchAddress(
"Pval", &Pval);
50 tree->SetBranchAddress(
"adc", &adc);
53 std::vector<TString> list_vars = {
"lay",
"IWire",
"x_u",
"t",
"t_fit",
"weight",
"Pval",
"ndf",
"adc"};
54 tree->SetBranchStatus(
"*", 0);
56 for (TString brname : list_vars) {
57 tree->SetBranchStatus(brname, 1);
63 for (
int i = 0; i < 56; ++i) {
66 halfCSize[i] = M_PI * R / nW;
68 int nEntries = tree->GetEntries();
69 B2INFO(
"Number of entry: " << nEntries);
71 for (
int i = 0; i < 300; ++i) {
72 m_h2[i] =
new TH2D(Form(
"board_%d", i), Form(
"board_%d", i), 50, 0., 500, 60, -30, 30);
76 for (
int i = 0; i < nEntries; ++i) {
78 double xmax = halfCSize[lay] - 0.12;
79 if ((fabs(x) < m_xmin) || (fabs(x) > xmax)
81 || (Pval < m_Pvalmin))
continue;
83 m_h2[cdcgeo.
getBoardID(
WireID(lay, IWire))]->Fill(adc, fabs(t_mea) - fabs(t_fit));
85 B2INFO(
"Reading data and filling histogram are done");
88 bool TimeWalkCalibration::calibrate()
94 if (m_twParamMode_old == 0)
95 fold =
new TF1(
"fold",
"[0]/sqrt(x)", 0, 500);
96 else if (m_twParamMode_old == 1)
97 fold =
new TF1(
"fold",
"[0]*exp(-1*[1]*x)", 0, 500);
99 B2FATAL(
"Mode " << m_twParamMode_new <<
" haven't implemented yet.");
101 B2INFO(
"Old time walk formular: ");
103 B2INFO(
"Time walk mode new: " << m_twParamMode_new <<
" with " << m_nTwParams_new <<
" parameters");
105 m_tw_new[0].resize(m_nTwParams_new, 0.0);
106 for (
int ib = 1; ib < 300; ++ib) {
108 B2DEBUG(199,
"Board ID:" << ib);
109 m_h2[ib]->SetDirectory(0);
112 if (m_h2[ib]->GetEntries() < 500) { m_flag[ib] = 0;
continue;}
114 m_h2[ib]->FitSlicesY(0, 1, -1, 10);
115 TString name = m_h2[ib]->GetName();
116 TString hm_name = name +
"_1";
117 m_h1[ib] = (TH1D*)gDirectory->Get(hm_name);
118 if (!m_h1[ib]) {m_flag[ib] = 0;
continue;}
119 m_h1[ib]->SetDirectory(0);
122 if (m_h1[ib]->GetEntries() < 5) {
124 B2WARNING(
"Low statistic, number of points after slice fit: " << m_h1[ib]->GetEntries());
129 for (
int p = 0; p < m_nTwParams_old; ++p) {
130 fold->SetParameter(p, m_tw_old[ib][p]);
133 if (m_twParamMode_new == 0) {
134 TF1* func =
new TF1(
"func",
"[0]+[1]/sqrt(x)", 0, 500);
135 func->SetParameters(-4, 28);
136 m_h1[ib]->Fit(
"func",
"MQ",
"", 20, 150);
138 else if (m_twParamMode_new == 1) {
139 fitToExponentialFunc(m_h1[ib]);
141 B2FATAL(
"Mode " << m_twParamMode_new <<
" is not available, please check again");
145 TF1* f1 = m_h1[ib]->GetFunction(
"func");
146 if (!f1) { m_flag[ib] = 0;
continue;}
147 m_constTerm[ib] = f1->GetParameter(0);
148 m_tw_new[ib].resize(m_nTwParams_new, 0.0);
149 for (
int i = 1; i <= m_nTwParams_new; ++i) {
150 m_tw_new[ib][i - 1] = f1->GetParameter(i);
152 B2DEBUG(199,
"Prob of fitting:" << f1->GetProb());
153 B2DEBUG(199,
"Fitting Param 0-1:" << f1->GetParameter(0) <<
" - " << f1->GetParameter(1));
157 B2INFO(
"Storing histogram");
158 TFile* fhist =
new TFile(
"tw_histo.root",
"recreate");
159 TDirectory* old = gDirectory;
160 TDirectory* h1D = old->mkdir(
"h1D");
161 TDirectory* h2D = old->mkdir(
"h2D");
163 for (
int ib = 1; ib < 300; ++ib) {
164 if (!m_h1[ib] || m_flag[ib] != 1)
continue;
165 m_h1[ib]->SetDirectory(0);
166 if (m_h1[ib]->GetEntries() < 5)
continue;
168 m_h1[ib]->SetMinimum(-5);
169 m_h1[ib]->SetMaximum(15);
172 B2DEBUG(199,
"Store 2D histogram");
174 for (
int ib = 1; ib < 300; ++ib) {
176 m_h2[ib]->SetDirectory(0);
181 B2INFO(
"All hitograms were stored");
187 void TimeWalkCalibration::Write()
189 B2INFO(
"Store calibrated time walk parameters");
195 for (
int ib = 0; ib < 300; ++ib) {
197 if (m_flag[ib] != 1) {
199 if (m_twParamMode_old == m_twParamMode_new) {
204 m_tw_new[ib].resize(m_nTwParams_new, 0.0);
216 m_lastExperiment, m_lastRun);
220 B2RESULT(
"Failure to calibrate time-walk for " << nfailure <<
" board");
221 B2RESULT(
"Time-walk coeff. table wrote to " << m_outputTWFileName.c_str());
223 void TimeWalkCalibration::updateT0()
225 B2INFO(
"Add constant term into T0 database");
227 ofstream ofs(m_outputT0FileName.c_str());
232 for (
int ilay = 0; ilay < 56; ++ilay) {
233 for (
unsigned int iwire = 0; iwire < cdcgeo.
nWiresInLayer(ilay); ++iwire) {
234 WireID wireid(ilay, iwire);
236 T0 = cdcgeo.
getT0(wireid);
237 if (m_flag[bID] == 1) {
238 ofs << ilay <<
"\t" << iwire <<
"\t" << T0 - m_constTerm[bID] << std::endl;
240 tz->
setT0(wireid, T0 - m_constTerm[bID]);
242 ofs << ilay <<
"\t" << iwire <<
"\t" << T0 << std::endl;
244 tz->
setT0(wireid, T0 - m_constTerm[bID]);
251 m_lastExperiment, m_lastRun);
254 B2RESULT(
"updated constant term of tw correction to T0 constant.");
256 void TimeWalkCalibration::fitToExponentialFunc(TH1D* h1)
259 int max = h1->GetMaximumBin();
260 double maxX = h1->GetBinCenter(max);
261 double maxY = h1->GetBinContent(max);
262 B2DEBUG(199,
"Max: id - x - y : " << max <<
" " << maxX <<
" " << maxY);
266 h1->Fit(
"pol0",
"MQE",
"", maxX + 125, 500);
267 if (h1->GetFunction(
"pol0")) {
268 p0 = h1->GetFunction(
"pol0")->GetParameter(0);
272 TH1D* hshift =
new TH1D(
"hshift",
"shift", h1->GetNbinsX(), 0, 500);
273 hshift->SetDirectory(0);
274 for (
int i = 0; i <= h1->GetNbinsX(); ++i) {
275 hshift->SetBinContent(i, h1->GetBinContent(i) - p0);
277 hshift->Fit(
"expo",
"MQE",
"", 0, 400);
278 double p1 = maxY + p0;
280 if (hshift->GetFunction(
"expo")) {
281 p1 = exp(hshift->GetFunction(
"expo")->GetParameter(0));
282 p2 = hshift->GetFunction(
"expo")->GetParameter(1);
286 TF1* func =
new TF1(
"func",
"[0]+ [1]*exp(-1*[2]*x)", 0, 500);
287 func->SetParameters(p0, p1, -1 * p2);
288 func->SetParLimits(0, -5, 5);
289 func->SetParLimits(1, -5, 500);
290 func->SetParLimits(2, -0.01, 0.1);
291 h1->Fit(
"func",
"MQE",
"", 10, 400);
293 void TimeWalkCalibration::readTW()
297 m_twParamMode_old = oldDB->getTwParamMode();
298 for (
int ib = 0; ib < 300; ++ib) {
299 m_tw_old[ib] = oldDB->getTimeWalkParams(ib);
303 std::string fileName1 =
"/data/cdc" + m_InputTWFileName;
304 std::string fileName = FileSystem::findFile(fileName1);
306 if (fileName ==
"") {
307 fileName = FileSystem::findFile(m_InputTWFileName);
309 if (fileName ==
"") {
310 B2FATAL(
"CDCGeometryPar: " << fileName1 <<
" not exist!");
312 B2INFO(
"Time Walk Calibration: open " << fileName);
313 ifs.open(fileName.c_str());
314 if (!ifs) B2FATAL(
"CDCGeometryPar: cannot open " << fileName1 <<
" !");
317 unsigned short iBoard(0);
320 ifs >> m_twParamMode_old >> m_nTwParams_old;
321 while (ifs >> iBoard) {
322 m_tw_old[iBoard].resize(m_nTwParams_old);
323 for (
int i = 0; i < m_nTwParams_old; ++i) {
325 m_tw_old[iBoard][i] = dumy;
329 if (nRead - 1 != 299) B2FATAL(
"#lines read-in (=" << nRead <<
") is not equal #boards 299 !");
331 B2INFO(
"TW from database: mode = " << m_twParamMode_old <<
" with " << m_nTwParams_old <<
" parameters");