11 #include <cdc/calibration/TimeWalkCalibrationAlgorithm.h>
12 #include <cdc/dbobjects/CDCTimeWalks.h>
13 #include <cdc/geometry/CDCGeometryPar.h>
14 #include <cdc/dataobjects/WireID.h>
18 #include <TDirectory.h>
21 #include <framework/database/DBObjPtr.h>
22 #include <framework/database/IntervalOfValidity.h>
23 #include <framework/logging/Logger.h>
29 TimeWalkCalibrationAlgorithm::TimeWalkCalibrationAlgorithm() :
CalibrationAlgorithm(
"CDCCalibrationCollector")
32 " -------------------------- Time Walk Calibration Algorithm -------------------------\n"
38 B2INFO(
"Creating and filling histograms");
43 for (
int i = 0; i < 56; ++i) {
46 halfCSize[i] = M_PI * R / nW;
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);
56 auto tree = getObjectPtr<TTree>(
"tree");
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);
77 std::vector<TString> list_vars = {
"lay",
"IWire",
"x_u",
"t",
"t_fit",
"Pval",
"ndf",
"adc"};
78 tree->SetBranchStatus(
"*", 0);
80 for (TString brname : list_vars) {
81 tree->SetBranchStatus(brname, 1);
84 const Long64_t nEntries = tree->GetEntries();
85 B2INFO(
"Number of entries: " << nEntries);
86 for (Long64_t i = 0; i < nEntries; ++i) {
88 const double xmax = halfCSize[lay] - 0.12;
89 if ((fabs(x) <
m_xmin) || (fabs(x) > xmax)
95 B2INFO(
"Finish making histogram for all channels");
100 B2INFO(
"Start calibration");
104 B2INFO(
"ExpRun used for DB Geometry : " << exprun.first <<
" " << exprun.second);
106 B2INFO(
"Creating CDCGeometryPar object");
114 fold =
new TF1(
"fold",
"[0]/sqrt(x)", 0, 500);
116 fold =
new TF1(
"fold",
"[0]*exp(-1*[1]*x)", 0, 500);
118 if (fold ==
nullptr) {
119 B2FATAL(
"Old fitting function is not defined.");
123 B2INFO(
"time walk formular: ");
124 [](TF1 * f) {
auto title = f->GetTitle(); B2INFO(
"Expression : " << title);}(fold);
127 for (
int ib = 1; ib < 300; ++ib) {
129 B2DEBUG(21,
"Board ID:" << ib);
130 m_h2[ib]->SetDirectory(0);
133 if (
m_h2[ib]->GetEntries() < 500) {
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);
142 m_h1[ib]->SetDirectory(0);
143 if (
m_h1[ib]->GetEntries() < 5) {
145 B2WARNING(
"Low statistic, number of points after slice fit: " <<
m_h1[ib]->GetEntries());
151 fold->SetParameter(p,
m_tw_old[ib][p]);
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);
163 B2FATAL(
"Mode " <<
m_twParamMode <<
" is not available, please check again");
167 TF1* f1 =
m_h1[ib]->GetFunction(
"func");
168 if (!f1) {
m_flag[ib] = 0;
continue;}
171 m_tw_new[ib][i - 1] = f1->GetParameter(i);
175 B2DEBUG(21,
"Prob of fitting:" << f1->GetProb());
176 B2DEBUG(21,
"Fitting Param 0-1:" << f1->GetParameter(0) <<
" - " << f1->GetParameter(1));
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");
200 if (hNDF && hPval && hEvtT0) {
206 TDirectory* old = gDirectory;
207 TDirectory* h1D = old->mkdir(
"h1D");
208 TDirectory* h2D = old->mkdir(
"h2D");
210 for (
int ib = 1; ib < 300; ++ib) {
212 if (
m_h1[ib]->GetEntries() < 5)
continue;
213 m_h1[ib]->SetMinimum(-5);
214 m_h1[ib]->SetMaximum(15);
218 B2DEBUG(21,
"Store 2D histogram");
220 for (
int ib = 1; ib < 300; ++ib) {
221 if (
m_h2[ib] ==
nullptr)
continue;
222 if (
m_h2[ib]->GetEntries() < 5)
continue;
228 B2INFO(
"Hitograms were stored");
233 TH1F* hDtw =
new TH1F(
"hDtw",
"", 100, -1, 1);
234 for (
int ib = 0; ib < 300; ++ib) {
236 if (std::isnan(dtw) == 0) {
241 B2INFO(hDtw->GetRMS());
243 if (hDtw->GetRMS() < 0.02) {
253 B2INFO(
"Save to the local DB");
258 for (
int ib = 0; ib < 300; ++ib) {
263 const int num =
static_cast<int>(
m_tw_old[ib].size());
264 for (
int i = 0; i < num; ++i) {
274 B2RESULT(
"Time-walk coeff. table has been written to " <<
m_outputTWFileName.c_str());
278 B2RESULT(
"Failure to calibrate time-walk for " << nfailure <<
" board");
284 B2INFO(
"Prepare calibration");
290 B2FATAL(
"Mode " <<
m_twParamMode <<
" haven't implemented yet.");
294 const int nEntries = dbTw->getEntries();
295 for (
int ib = 0; ib < nEntries; ++ib) {
296 m_tw_old[ib] = dbTw->getTimeWalkParams(ib);
303 B2INFO(
"Add constant term into T0 database");
307 for (
int ilay = 0; ilay < 56; ++ilay) {
308 for (
unsigned int iwire = 0; iwire < cdcgeo.
nWiresInLayer(ilay); ++iwire) {
309 WireID wireid(ilay, iwire);
312 T0 = cdcgeo.
getT0(wireid);
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);
333 h1->Fit(
"pol0",
"MQE",
"", maxX + 125, 500);
334 if (h1->GetFunction(
"pol0")) {
335 p0 = h1->GetFunction(
"pol0")->GetParameter(0);
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);
344 hshift->Fit(
"expo",
"MQE",
"", 0, 400);
345 double p1 = maxY + p0;
347 if (hshift->GetFunction(
"expo")) {
348 p1 = exp(hshift->GetFunction(
"expo")->GetParameter(0));
349 p2 = hshift->GetFunction(
"expo")->GetParameter(1);
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);