12 #include <klm/eklm/calibration/EKLMTimeCalibrationAlgorithm.h>
15 #include <klm/dataobjects/eklm/EKLMElementNumbers.h>
16 #include <klm/dbobjects/eklm/EKLMTimeCalibration.h>
26 static double CrystalBall(
double* x,
double* par)
31 f = exp(-0.5 * d1 * d1 / par[2] / par[2]);
32 }
else if (*x < par[4]) {
34 f = exp(-0.5 * d1 * d1 / par[3] / par[3]);
38 t = par[5] * par[3] * par[3] / d1;
39 f = exp(-0.5 * d1 * d1 / par[3] / par[3]) *
40 pow(t / (d2 + t), par[5]);
57 int i, j1, j2, n, strip, maxStrip;
58 double s[2][3], k[2][3], dt, dl, dn, effectiveLightSpeed, tau;
59 double* averageDist, *averageTime, *averageSqrtN, *timeShift, timeShift0;
61 std::vector<struct Event>* stripEvents;
62 std::vector<struct Event>::iterator it;
70 std::shared_ptr<TTree> t;
71 TCanvas* c1 =
nullptr;
74 fcn =
new TF1(
"fcn", CrystalBall, 0, 10, 6);
75 stripEvents =
new std::vector<struct Event>[maxStrip];
76 averageDist =
new double[maxStrip];
77 averageTime =
new double[maxStrip];
78 averageSqrtN =
new double[maxStrip];
79 timeShift =
new double[maxStrip];
80 calibrateStrip =
new bool[maxStrip];
81 t = getObjectPtr<TTree>(
"calibration_data");
82 t->SetBranchAddress(
"time", &ev.
time);
83 t->SetBranchAddress(
"dist", &ev.
dist);
84 t->SetBranchAddress(
"npe", &ev.
npe);
85 t->SetBranchAddress(
"strip", &strip);
87 for (i = 0; i < n; i++) {
89 stripEvents[strip - 1].push_back(ev);
91 for (j1 = 0; j1 < 2; j1++) {
92 for (j2 = 0; j2 < 3; j2++)
115 for (i = 0; i < maxStrip; i++) {
116 n = stripEvents[i].size();
118 B2WARNING(
"Not enough calibration data collected."
119 <<
LogVar(
"Strip", i + 1));
121 delete[] stripEvents;
122 delete[] averageDist;
123 delete[] averageTime;
124 delete[] averageSqrtN;
126 delete[] calibrateStrip;
129 calibrateStrip[i] =
true;
133 for (it = stripEvents[i].begin(); it != stripEvents[i].end(); ++it) {
134 averageDist[i] = averageDist[i] + it->dist;
135 averageTime[i] = averageTime[i] + it->time;
136 averageSqrtN[i] = averageSqrtN[i] + 1.0 / sqrt(it->npe);
138 averageDist[i] = averageDist[i] / n;
139 averageTime[i] = averageTime[i] / n;
140 averageSqrtN[i] = averageSqrtN[i] / n;
141 for (j1 = 0; j1 < 2; j1++) {
142 for (j2 = 0; j2 < 3; j2++)
145 for (it = stripEvents[i].begin(); it != stripEvents[i].end(); ++it) {
146 dt = it->time - averageTime[i];
147 dl = it->dist - averageDist[i];
148 dn = 1.0 / sqrt(it->npe);
156 for (j1 = 0; j1 < 2; j1++) {
157 for (j2 = 0; j2 < 3; j2++)
158 k[j1][j2] += (n - 1) * s[j1][j2];
167 h =
new TH1F(
"h",
"", 200, -10., 10.);
168 h2 =
new TH1F(
"h2",
"", 200, -10., 10.);
169 effectiveLightSpeed = (k[0][0] * k[1][1] - k[1][0] * k[0][1]) /
170 (k[0][2] * k[1][1] - k[1][2] * k[0][1]);
171 tau = (k[0][0] * k[1][2] - k[1][0] * k[0][2]) /
172 (k[0][0] * k[1][1] - k[1][0] * k[0][1]);
173 B2INFO(
"EKLM time calibration results:"
174 <<
LogVar(
"Effective light speed, cm / ns", effectiveLightSpeed)
175 <<
LogVar(
"Amplitude time constant, ns", tau));
176 calibration->setEffectiveLightSpeed(effectiveLightSpeed);
177 calibration->setAmplitudeTimeConstant(tau);
178 for (i = 0; i < maxStrip; i++) {
179 if (!calibrateStrip[i])
181 timeShift[i] = averageTime[i] - averageDist[i] / effectiveLightSpeed -
182 averageSqrtN[i] * tau;
183 for (it = stripEvents[i].begin(); it != stripEvents[i].end(); ++it) {
184 h->Fill(it->time - (timeShift[i] + it->dist / effectiveLightSpeed +
185 tau / sqrt(it->npe)));
188 fcn->SetParameter(0, h->Integral());
189 fcn->SetParameter(1, h->GetMean());
190 fcn->SetParameter(2, h->GetRMS());
191 fcn->SetParameter(3, h->GetRMS());
192 fcn->FixParameter(4, h->GetMean() + 1.0);
193 fcn->FixParameter(5, 1.0);
198 fcn->ReleaseParameter(4);
199 fcn->ReleaseParameter(5);
204 timeShift0 = fcn->GetParameter(1);
207 c1->Print(
"corrtime.eps");
209 for (i = 0; i < maxStrip; i++) {
210 if (!calibrateStrip[i])
212 timeShift[i] = timeShift[i] + timeShift0;
214 calibration->setTimeCalibrationData(i + 1, &calibrationData);
215 for (it = stripEvents[i].begin(); it != stripEvents[i].end(); ++it) {
216 h2->Fill(it->time - (timeShift[i] + it->dist / effectiveLightSpeed +
217 tau / sqrt(it->npe)));
222 c1->Print(
"corrtime2.eps");
225 delete[] stripEvents;
226 delete[] averageDist;
227 delete[] averageTime;
228 delete[] averageSqrtN;
230 delete[] calibrateStrip;