10#include <klm/calibration/KLMTimeAlgorithm.h>
13#include <klm/dataobjects/bklm/BKLMElementNumbers.h>
16#include <framework/database/Database.h>
17#include <framework/database/DBObjPtr.h>
18#include <framework/database/DBStore.h>
19#include <framework/dataobjects/EventMetaData.h>
20#include <framework/gearbox/Const.h>
21#include <framework/logging/Logger.h>
24#include <Math/MinimizerOptions.h>
25#include <Math/Vector3D.h>
27#include <TFitResult.h>
38using namespace ROOT::Math;
41const int c_NBinsTime = 100;
44const int c_NBinsDistance = 100;
47static double s_BinnedData[c_NBinsTime][c_NBinsDistance];
50static double s_LowerTimeBoundary = 0;
53static double s_UpperTimeBoundary = 0;
56static double s_StripLength = 0;
58static bool compareEventNumber(
const std::pair<KLMChannelNumber, unsigned int>& pair1,
59 const std::pair<KLMChannelNumber, unsigned int>& pair2)
61 return pair1.second < pair2.second;
64static double timeDensity(
const double x[2],
const double* par)
66 double polynomial, t0, gauss;
68 t0 = par[2] + par[4] * x[1];
69 gauss = par[1] / (
sqrt(2.0 * M_PI) * par[3]) *
70 exp(-0.5 * pow((x[0] - t0) / par[3], 2));
71 return fabs(polynomial + gauss);
74static void fcn(
int& npar,
double* grad,
double& fval,
double* par,
int iflag)
81 for (
int i = 0; i < c_NBinsTime; ++i) {
82 x[0] = s_LowerTimeBoundary +
83 (s_UpperTimeBoundary - s_LowerTimeBoundary) *
84 (
double(i) + 0.5) / c_NBinsTime;
85 for (
int j = 0; j < c_NBinsDistance; ++j) {
86 x[1] = s_StripLength * (double(j) + 0.5) / c_NBinsDistance;
87 double f = timeDensity(x, par);
88 if (s_BinnedData[i][j] == 0)
89 fval = fval + 2.0 * f;
91 fval = fval + 2.0 * (f - s_BinnedData[i][j] *
92 (1.0 - log(s_BinnedData[i][j] / f)));
110 const std::vector<Calibration::ExpRun>& runs =
getRunList();
111 int firstExperiment = runs[0].first;
112 int lastExperiment = runs[runs.size() - 1].first;
113 if (firstExperiment != lastExperiment) {
114 B2FATAL(
"Runs from different experiments are used "
115 "for KLM time calibration (single algorithm run).");
124 if (eventMetaData->getExperiment() != firstExperiment) {
125 B2FATAL(
"Runs from different experiments are used "
126 "for KLM time calibration (consecutive algorithm runs).");
128 eventMetaData->setExperiment(firstExperiment);
129 eventMetaData->setRun(runs[0].second);
131 eventMetaData.
construct(1, runs[0].second, firstExperiment);
148 B2INFO(
"Read tree entries (initial data check only).");
149 std::shared_ptr<TTree> timeCalibrationData;
150 timeCalibrationData = getObjectPtr<TTree>(
"time_calibration_data");
152 int n = timeCalibrationData->GetEntries();
153 B2INFO(
LogVar(
"Total number of digits:", n));
163 B2INFO(
"Counting events per channel (lightweight scan)...");
165 std::shared_ptr<TTree> timeCalibrationData;
166 timeCalibrationData = getObjectPtr<TTree>(
"time_calibration_data");
167 timeCalibrationData->SetBranchAddress(
"channelId", &event.channelId);
171 int n = timeCalibrationData->GetEntries();
172 for (
int i = 0; i < n; ++i) {
173 timeCalibrationData->GetEntry(i);
174 eventCounts[
event.channelId]++;
177 B2INFO(
"Event counting complete." <<
LogVar(
"Total events", n) <<
LogVar(
"Unique channels", eventCounts.size()));
181 const std::vector<std::pair<KLMChannelNumber, unsigned int>>& channelsBKLM,
182 const std::vector<std::pair<KLMChannelNumber, unsigned int>>& channelsEKLM)
184 B2INFO(
"Loading data for 2D fit (top 1000 channels from BKLM and EKLM)...");
186 std::shared_ptr<TTree> timeCalibrationData;
187 timeCalibrationData = getObjectPtr<TTree>(
"time_calibration_data");
188 timeCalibrationData->SetBranchAddress(
"t0", &event.t0);
189 timeCalibrationData->SetBranchAddress(
"flyTime", &event.flyTime);
190 timeCalibrationData->SetBranchAddress(
"recTime", &event.recTime);
191 timeCalibrationData->SetBranchAddress(
"dist", &event.dist);
192 timeCalibrationData->SetBranchAddress(
"diffDistX", &event.diffDistX);
193 timeCalibrationData->SetBranchAddress(
"diffDistY", &event.diffDistY);
194 timeCalibrationData->SetBranchAddress(
"diffDistZ", &event.diffDistZ);
195 timeCalibrationData->SetBranchAddress(
"eDep", &event.eDep);
196 timeCalibrationData->SetBranchAddress(
"nPE", &event.nPE);
197 timeCalibrationData->SetBranchAddress(
"channelId", &event.channelId);
198 timeCalibrationData->SetBranchAddress(
"inRPC", &event.inRPC);
199 timeCalibrationData->SetBranchAddress(
"isFlipped", &event.isFlipped);
204 std::set<KLMChannelNumber> neededChannels;
205 int maxChannels = 1000;
207 for (
size_t i = 0; i < channelsBKLM.size() && i <
static_cast<size_t>(maxChannels); ++i) {
208 neededChannels.insert(channelsBKLM[i].first);
210 for (
size_t i = 0; i < channelsEKLM.size() && i <
static_cast<size_t>(maxChannels); ++i) {
211 neededChannels.insert(channelsEKLM[i].first);
214 int n = timeCalibrationData->GetEntries();
215 int loadedEvents = 0;
217 for (
int i = 0; i < n; ++i) {
218 timeCalibrationData->GetEntry(i);
220 if (neededChannels.find(event.channelId) != neededChannels.end()) {
221 m_evts[
event.channelId].push_back(event);
226 B2INFO(
"2D fit data loaded." <<
LogVar(
"Events", loadedEvents) <<
LogVar(
"Channels",
m_evts.size()));
231 B2INFO(
"Loading calibration data batch...");
233 std::shared_ptr<TTree> timeCalibrationData;
234 timeCalibrationData = getObjectPtr<TTree>(
"time_calibration_data");
235 timeCalibrationData->SetBranchAddress(
"t0", &event.t0);
236 timeCalibrationData->SetBranchAddress(
"flyTime", &event.flyTime);
237 timeCalibrationData->SetBranchAddress(
"recTime", &event.recTime);
238 timeCalibrationData->SetBranchAddress(
"dist", &event.dist);
239 timeCalibrationData->SetBranchAddress(
"diffDistX", &event.diffDistX);
240 timeCalibrationData->SetBranchAddress(
"diffDistY", &event.diffDistY);
241 timeCalibrationData->SetBranchAddress(
"diffDistZ", &event.diffDistZ);
242 timeCalibrationData->SetBranchAddress(
"eDep", &event.eDep);
243 timeCalibrationData->SetBranchAddress(
"nPE", &event.nPE);
244 timeCalibrationData->SetBranchAddress(
"channelId", &event.channelId);
245 timeCalibrationData->SetBranchAddress(
"inRPC", &event.inRPC);
246 timeCalibrationData->SetBranchAddress(
"isFlipped", &event.isFlipped);
250 int n = timeCalibrationData->GetEntries();
251 int loadedEvents = 0;
253 for (
int i = 0; i < n; ++i) {
254 timeCalibrationData->GetEntry(i);
257 int subdetector, section, sector, layer, plane, strip;
259 event.channelId, &subdetector, §ion, §or, &layer, &plane, &strip);
260 KLMChannelIndex klmChannel(subdetector, section, sector, layer, plane, strip);
262 if (channelFilter(klmChannel)) {
263 m_evts[
event.channelId].push_back(event);
268 B2INFO(
"Batch loaded." <<
LogVar(
"Events", loadedEvents) <<
LogVar(
"Channels",
m_evts.size()));
292 TString iFstring[2] = {
"Backward",
"Forward"};
293 TString iPstring[2] = {
"ZReadout",
"PhiReadout"};
296 h_diff =
new TH1F(
"h_diff",
"Position difference between bklmHit2d and extHit;position difference", 100, 0, 10);
297 h_calibrated =
new TH1I(
"h_calibrated_summary",
"h_calibrated_summary;calibrated or not", 3, 0, 3);
298 hc_calibrated =
new TH1I(
"hc_calibrated_summary",
"hc_calibrated_summary;calibrated or not", 3, 0, 3);
316 double maximalPhiStripLengthBKLM =
318 double maximalZStripLengthBKLM =
320 double maximalStripLengthEKLM =
324 "Time over propagation length for RPCs (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
327 "Time over propagation length for RPCs (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
330 "Time over propagation length for scintillators (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
331 50, 0.0, maximalPhiStripLengthBKLM);
333 "Time over propagation length for scintillators (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
334 50, 0.0, maximalZStripLengthBKLM);
336 "Time over propagation length for scintillators (plane1, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
337 50, 0.0, maximalStripLengthEKLM);
339 "Time over propagation length for scintillators (plane2, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
340 50, 0.0, maximalStripLengthEKLM);
343 "Time over propagation length for RPCs (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
346 "Time over propagation length for RPCs (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]", 50, 0.0,
349 "Time over propagation length for scintillators (Phi_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
350 50, 0.0, maximalPhiStripLengthBKLM);
352 "Time over propagation length for scintillators (Z_Readout); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
353 50, 0.0, maximalZStripLengthBKLM);
355 "Time over propagation length for scintillators (plane1, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
356 50, 0.0, maximalStripLengthEKLM);
358 "Time over propagation length for scintillators (plane2, Endcap); propagation distance[cm]; T_rec-T_0-T_fly-'T_calibration'[ns]",
359 50, 0.0, maximalStripLengthEKLM);
362 h_time_scint_tc =
new TH1F(
"h_time_scint_tc",
"time distribution for Scintillator", nBin_scint,
364 h_time_scint_tc_end =
new TH1F(
"h_time_scint_tc_end",
"time distribution for Scintillator (Endcap)", nBin_scint,
371 h_time_scint =
new TH1F(
"h_time_scint",
"time distribution for Scintillator; T_rec-T_0-T_fly-T_propagation[ns]", nBin_scint,
373 h_time_scint_end =
new TH1F(
"h_time_scint_end",
"time distribution for Scintillator (Endcap); T_rec-T_0-T_fly-T_propagation[ns]",
376 hc_time_rpc =
new TH1F(
"hc_time_rpc",
"Calibrated time distribution for RPC; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
379 "Calibrated time distribution for Scintillator; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", nBin_scint,
383 "Calibrated time distribution for Scintillator (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", nBin_scint,
387 B2INFO(
"Skipping debug histogram allocation (m_saveAllPlots = false)");
391 for (
int iF = 0; iF < 2; ++iF) {
392 hn = Form(
"h_timeF%d_rpc", iF);
393 ht = Form(
"Time distribution for RPC of %s; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
395 hn = Form(
"h_timeF%d_scint", iF);
396 ht = Form(
"Time distribution for Scintillator of %s; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
399 hn = Form(
"h_timeF%d_scint_end", iF);
400 ht = Form(
"Time distribution for Scintillator of %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
404 hn = Form(
"h2_timeF%d_rpc", iF);
405 ht = Form(
"Time distribution for RPC of %s; Sector Index; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
407 hn = Form(
"h2_timeF%d_scint", iF);
408 ht = Form(
"Time distribution for Scintillator of %s; Sector Index; T_rec-T_0-T_fly-T_propagation[ns]", iFstring[iF].Data());
411 hn = Form(
"h2_timeF%d_scint_end", iF);
412 ht = Form(
"Time distribution for Scintillator of %s (Endcap); Sector Index; T_rec-T_0-T_fly-T_propagation[ns]",
413 iFstring[iF].Data());
417 hn = Form(
"hc_timeF%d_rpc", iF);
418 ht = Form(
"Calibrated time distribution for RPC of %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iFstring[iF].Data());
420 hn = Form(
"hc_timeF%d_scint", iF);
421 ht = Form(
"Calibrated time distribution for Scintillator of %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
422 iFstring[iF].Data());
425 hn = Form(
"hc_timeF%d_scint_end", iF);
426 ht = Form(
"Calibrated time distribution for Scintillator of %s (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
427 iFstring[iF].Data());
431 hn = Form(
"h2c_timeF%d_rpc", iF);
432 ht = Form(
"Calibrated time distribution for RPC of %s; Sector Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
433 iFstring[iF].Data());
436 hn = Form(
"h2c_timeF%d_scint", iF);
437 ht = Form(
"Calibrated time distribution for Scintillator of %s; Sector Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
438 iFstring[iF].Data());
441 hn = Form(
"h2c_timeF%d_scint_end", iF);
442 ht = Form(
"Calibrated time distribution for Scintillator of %s (Endcap) ; Sector Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
443 iFstring[iF].Data());
447 for (
int iS = 0; iS < 8; ++iS) {
449 hn = Form(
"h_timeF%d_S%d_scint", iF, iS);
450 ht = Form(
"Time distribution for Scintillator of Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
453 hn = Form(
"h_timeF%d_S%d_rpc", iF, iS);
454 ht = Form(
"Time distribution for RPC of Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
456 hn = Form(
"h2_timeF%d_S%d", iF, iS);
457 ht = Form(
"Time distribution of Sector%d, %s; Layer Index; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
461 hn = Form(
"hc_timeF%d_S%d_scint", iF, iS);
462 ht = Form(
"Calibrated time distribution for Scintillator of Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iS,
463 iFstring[iF].Data());
466 hn = Form(
"hc_timeF%d_S%d_rpc", iF, iS);
467 ht = Form(
"Calibrated time distribution for RPC of Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iS,
468 iFstring[iF].Data());
471 hn = Form(
"h2c_timeF%d_S%d", iF, iS);
472 ht = Form(
"Calibrated time distribution of Sector%d, %s; Layer Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iS,
473 iFstring[iF].Data());
478 for (
int iL = 0; iL < 2; ++iL) {
479 hn = Form(
"h_timeF%d_S%d_L%d", iF, iS, iL);
480 ht = Form(
"Time distribution for Scintillator of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iL, iS,
481 iFstring[iF].Data());
484 hn = Form(
"hc_timeF%d_S%d_L%d", iF, iS, iL);
485 ht = Form(
"Calibrated time distribution for Scintillator of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
486 iL, iS, iFstring[iF].Data());
490 for (
int iP = 0; iP < 2; ++iP) {
491 hn = Form(
"h_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
492 ht = Form(
"Time distribution for Scintillator of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]",
493 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
496 hn = Form(
"h2_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
497 ht = Form(
"Time distribution for Scintillator of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation[ns]",
498 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
502 hn = Form(
"hc_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
503 ht = Form(
"Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
504 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
507 hn = Form(
"h2c_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
508 ht = Form(
"Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
509 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
515 for (
int iL = 2; iL < 15; ++iL) {
516 hn = Form(
"h_timeF%d_S%d_L%d", iF, iS, iL);
517 ht = Form(
"time distribution for RPC of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iL, iS, iFstring[iF].Data());
520 hn = Form(
"hc_timeF%d_S%d_L%d", iF, iS, iL);
521 ht = Form(
"Calibrated time distribution for RPC of Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]", iL, iS,
522 iFstring[iF].Data());
525 for (
int iP = 0; iP < 2; ++iP) {
526 hn = Form(
"h_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
527 ht = Form(
"time distribution for RPC of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation[ns]", iPstring[iP].Data(), iL, iS,
528 iFstring[iF].Data());
531 hn = Form(
"h2_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
532 ht = Form(
"time distribution for RPC of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation[ns]",
533 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
536 hn = Form(
"hc_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
537 ht = Form(
"Calibrated time distribution for RPC of %s, Layer%d, Sector%d, %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
538 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
542 hn = Form(
"h2c_timeF%d_S%d_L%d_P%d", iF, iS, iL, iP);
543 ht = Form(
"Calibrated time distribution for RPC of %s, Layer%d, Sector%d, %s; Channel Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
544 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
551 int maxLay = 12 + 2 * iF;
552 for (
int iS = 0; iS < 4; ++iS) {
553 hn = Form(
"h_timeF%d_S%d_scint_end", iF, iS);
554 ht = Form(
"Time distribution for Scintillator of Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]", iS,
555 iFstring[iF].Data());
558 hn = Form(
"h2_timeF%d_S%d_end", iF, iS);
559 ht = Form(
"Time distribution of Sector%d, %s (Endcap); Layer Index; T_rec-T_0-T_fly-T_propagation[ns]", iS, iFstring[iF].Data());
562 hn = Form(
"hc_timeF%d_S%d_scint_end", iF, iS);
563 ht = Form(
"Calibrated time distribution for Scintillator of Sector%d (Endcap), %s; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
564 iS, iFstring[iF].Data());
567 hn = Form(
"h2c_timeF%d_S%d_end", iF, iS);
568 ht = Form(
"Calibrated time distribution of Sector%d, %s (Endcap); Layer Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
569 iS, iFstring[iF].Data());
570 h2c_timeFS_end[iF][iS] =
new TH2F(hn.Data(), ht.Data(), maxLay, 0, maxLay, nBin_scint,
574 for (
int iL = 0; iL < maxLay; ++iL) {
575 hn = Form(
"h_timeF%d_S%d_L%d_end", iF, iS, iL);
576 ht = Form(
"Time distribution for Scintillator of Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]", iL, iS,
577 iFstring[iF].Data());
580 hn = Form(
"hc_timeF%d_S%d_L%d_end", iF, iS, iL);
581 ht = Form(
"Calibrated time distribution for Scintillator of Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
582 iL, iS, iFstring[iF].Data());
586 for (
int iP = 0; iP < 2; ++iP) {
587 hn = Form(
"h_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
588 ht = Form(
"Time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation[ns]",
589 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
593 hn = Form(
"h2_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
594 ht = Form(
"Time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); Channel Index; T_rec-T_0-T_fly-T_propagation[ns]",
595 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
599 hn = Form(
"hc_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
600 ht = Form(
"Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
601 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
605 hn = Form(
"h2c_timeF%d_S%d_L%d_P%d_end", iF, iS, iL, iP);
606 ht = Form(
"Calibrated time distribution for Scintillator of %s, Layer%d, Sector%d, %s (Endcap); Channel Index; T_rec-T_0-T_fly-T_propagation-T_calibration[ns]",
607 iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
608 h2c_timeFSLP_end[iF][iS][iL][iP] =
new TH2F(hn.Data(), ht.Data(), 75, 0, 75, nBin_scint,
618 TProfile* profileRpcPhi, TProfile* profileRpcZ,
619 TProfile* profileBKLMScintillatorPhi, TProfile* profileBKLMScintillatorZ,
620 TProfile* profileEKLMScintillatorPlane1,
621 TProfile* profileEKLMScintillatorPlane2,
bool fill2dHistograms)
623 B2INFO(
"Filling time-distance profiles" << (fill2dHistograms ?
" with 2D histograms" :
"") <<
" (batched processing)...");
625 TString iFstring[2] = {
"Backward",
"Forward"};
626 TString iPstring[2] = {
"ZReadout",
"PhiReadout"};
663 std::vector<std::pair<std::string, std::function<bool(
const KLMChannelIndex&)>>> batches = {
664 {
"RPC Backward", isRPCBackward},
665 {
"RPC Forward", isRPCForward},
666 {
"BKLM Scintillator Backward", isBKLMScintillatorBackward},
667 {
"BKLM Scintillator Forward", isBKLMScintillatorForward},
668 {
"EKLM Scintillator Backward", isEKLMScintillatorBackward},
669 {
"EKLM Scintillator Forward", isEKLMScintillatorForward}
673 for (
const auto& batch : batches) {
674 B2INFO(
"Processing batch for profiles: " << batch.first);
678 std::map<KLMChannelNumber, TH2F*> tempHistBKLM;
679 std::map<KLMChannelNumber, TH2F*> tempHistEKLM;
685 if (!batch.second(klmChannel))
688 if (
m_cFlag[channel] == ChannelCalibrationStatus::c_NotEnoughData)
694 std::vector<struct Event> eventsChannel =
m_evts[channel];
695 int iSub = klmChannel.getSubdetector();
698 TH2F* hist2d =
nullptr;
699 if (fill2dHistograms) {
701 int iF = klmChannel.getSection();
702 int iS = klmChannel.getSector() - 1;
703 int iL = klmChannel.getLayer() - 1;
704 int iP = klmChannel.getPlane();
705 int iC = klmChannel.getStrip() - 1;
709 TString hn = Form(
"time_length_bklm_F%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
710 double stripLength = 200;
711 hist2d =
new TH2F(hn.Data(),
712 "Time versus propagation length; "
713 "propagation distance[cm]; "
714 "T_rec-T_0-T_fly-'T_calibration'[ns]",
715 50, 0.0, stripLength,
718 tempHistBKLM[channel] = hist2d;
721 int iF = klmChannel.getSection() - 1;
722 int iS = klmChannel.getSector() - 1;
723 int iL = klmChannel.getLayer() - 1;
724 int iP = klmChannel.getPlane() - 1;
725 int iC = klmChannel.getStrip() - 1;
727 TString hn = Form(
"time_length_eklm_F%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
729 hist2d =
new TH2F(hn.Data(),
730 "Time versus propagation length; "
731 "propagation distance[cm]; "
732 "T_rec-T_0-T_fly-'T_calibration'[ns]",
733 50, 0.0, stripLength,
736 tempHistEKLM[channel] = hist2d;
741 for (
const Event& event : eventsChannel) {
742 double timeHit =
event.time() -
m_timeShift[channel];
744 timeHit = timeHit -
event.t0;
745 double distHit =
event.dist;
747 if (timeHit <= -400e3)
751 int iL = klmChannel.getLayer() - 1;
752 int iP = klmChannel.getPlane();
757 profileRpcPhi->Fill(distHit, timeHit);
759 profileRpcZ->Fill(distHit, timeHit);
764 hist2d->Fill(distHit, timeHit);
767 profileBKLMScintillatorPhi->Fill(distHit, timeHit);
769 profileBKLMScintillatorZ->Fill(distHit, timeHit);
773 int iP = klmChannel.getPlane() - 1;
776 hist2d->Fill(distHit, timeHit);
779 profileEKLMScintillatorPlane1->Fill(distHit, timeHit);
781 profileEKLMScintillatorPlane2->Fill(distHit, timeHit);
788 if (fill2dHistograms) {
789 for (
auto& pair : tempHistBKLM) {
792 for (
auto& pair : tempHistEKLM) {
798 B2INFO(
"Batch processed and cleared: " << batch.first);
801 B2INFO(
"Time-distance profile filling complete.");
805 const std::vector< std::pair<KLMChannelNumber, unsigned int> >& channels,
806 double& delay,
double& delayError)
808 std::vector<struct Event> eventsChannel;
810 int nConvergedFits = 0;
813 if (nFits > (
int)channels.size())
814 nFits = channels.size();
815 for (
int i = 0; i < nFits; ++i) {
816 int subdetector, section, sector, layer, plane, strip;
818 channels[i].first, &subdetector, §ion, §or, &layer, &plane,
825 s_StripLength = module->getStripLength(plane, strip);
832 for (
int j = 0; j < c_NBinsTime; ++j) {
833 for (
int k = 0; k < c_NBinsDistance; ++k)
834 s_BinnedData[j][k] = 0;
836 eventsChannel =
m_evts[channels[i].first];
837 double averageTime = 0;
838 for (
const Event& event : eventsChannel) {
839 double timeHit =
event.time();
841 timeHit = timeHit -
event.t0;
843 if (timeHit <= -400e3) {
847 averageTime = averageTime + timeHit;
848 int timeBin = std::floor((timeHit - s_LowerTimeBoundary) * c_NBinsTime /
849 (s_UpperTimeBoundary - s_LowerTimeBoundary));
850 if (timeBin < 0 || timeBin >= c_NBinsTime)
852 int distanceBin = std::floor(event.dist * c_NBinsDistance / s_StripLength);
853 if (distanceBin < 0 || distanceBin >= c_NBinsDistance) {
854 B2ERROR(
"The distance to SiPM is greater than the strip length.");
857 s_BinnedData[timeBin][distanceBin] += 1;
859 averageTime = averageTime / eventsChannel.size();
861 minuit.SetPrintLevel(-1);
863 minuit.mnparm(0,
"P0", 1, 0.001, 0, 0, minuitResult);
864 minuit.mnparm(1,
"N", 10, 0.001, 0, 0, minuitResult);
865 minuit.mnparm(2,
"T0", averageTime, 0.001, 0, 0, minuitResult);
866 minuit.mnparm(3,
"SIGMA", 10, 0.001, 0, 0, minuitResult);
867 minuit.mnparm(4,
"DELAY", 0.0, 0.001, 0, 0, minuitResult);
869 minuit.mncomd(
"FIX 2 3 4 5", minuitResult);
870 minuit.mncomd(
"MIGRAD 10000", minuitResult);
871 minuit.mncomd(
"RELEASE 2", minuitResult);
872 minuit.mncomd(
"MIGRAD 10000", minuitResult);
873 minuit.mncomd(
"RELEASE 3", minuitResult);
874 minuit.mncomd(
"MIGRAD 10000", minuitResult);
875 minuit.mncomd(
"RELEASE 4", minuitResult);
876 minuit.mncomd(
"MIGRAD 10000", minuitResult);
877 minuit.mncomd(
"RELEASE 5", minuitResult);
878 minuit.mncomd(
"MIGRAD 10000", minuitResult);
880 if (minuit.fISW[1] != 3)
883 double channelDelay, channelDelayError;
884 minuit.GetParameter(4, channelDelay, channelDelayError);
885 delay = delay + channelDelay;
886 delayError = delayError + channelDelayError * channelDelayError;
888 delay = delay / nConvergedFits;
889 delayError =
sqrt(delayError) / (nConvergedFits - 1);
915 gROOT->SetBatch(kTRUE);
921 fcn_gaus =
new TF1(
"fcn_gaus",
"gaus");
922 fcn_land =
new TF1(
"fcn_land",
"landau");
923 fcn_pol1 =
new TF1(
"fcn_pol1",
"pol1");
924 fcn_const =
new TF1(
"fcn_const",
"pol0");
932 std::string name =
"time_calibration.root";
936 if (stat(name.c_str(), &buffer) != 0)
938 name =
"time_calibration_" + std::to_string(i) +
".root";
943 m_outFile =
new TFile(name.c_str(),
"recreate");
946 std::vector<struct Event> eventsChannel;
947 eventsChannel.clear();
954 B2INFO(
"Counting events per channel...");
955 std::map<KLMChannelNumber, unsigned int> eventCounts;
959 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsBKLM;
960 std::vector< std::pair<KLMChannelNumber, unsigned int> > channelsEKLM;
965 m_cFlag[channel] = ChannelCalibrationStatus::c_NotEnoughData;
967 if (eventCounts.find(channel) == eventCounts.end())
970 int nEvents = eventCounts[channel];
972 B2WARNING(
"Not enough calibration data collected."
973 <<
LogVar(
"channel", channel)
974 <<
LogVar(
"number of digit", nEvents));
978 m_cFlag[channel] = ChannelCalibrationStatus::c_FailedFit;
982 channelsBKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
985 channelsEKLM.push_back(std::pair<KLMChannelNumber, unsigned int>(channel, nEvents));
989 std::sort(channelsBKLM.begin(), channelsBKLM.end(), compareEventNumber);
990 std::sort(channelsEKLM.begin(), channelsEKLM.end(), compareEventNumber);
995 double delayBKLM, delayBKLMError;
996 double delayEKLM, delayEKLMError;
1004 B2INFO(
"2D fits complete, data cleared.");
1043 std::vector<std::pair<std::string, std::function<bool(
const KLMChannelIndex&)>>> batches = {
1044 {
"RPC Backward", isRPCBackward},
1045 {
"RPC Forward", isRPCForward},
1046 {
"BKLM Scintillator Backward", isBKLMScintillatorBackward},
1047 {
"BKLM Scintillator Forward", isBKLMScintillatorForward},
1048 {
"EKLM Scintillator Backward", isEKLMScintillatorBackward},
1049 {
"EKLM Scintillator Forward", isEKLMScintillatorForward}
1056 B2INFO(
"First loop: Computing global statistics (batched processing)...");
1058 TString iFstring[2] = {
"Backward",
"Forward"};
1059 TString iPstring[2] = {
"ZReadout",
"PhiReadout"};
1061 int nBin_scint = 80;
1063 for (
const auto& batch : batches) {
1064 B2INFO(
"Processing batch for global stats: " << batch.first);
1068 channelId = klmChannel.getKLMChannelNumber();
1070 if (!batch.second(klmChannel))
1073 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1079 eventsChannel =
m_evts[channelId];
1080 int iSub = klmChannel.getSubdetector();
1084 for (
const Event& event : eventsChannel) {
1085 XYZVector diffD = XYZVector(event.diffDistX, event.diffDistY, event.diffDistZ);
1088 double timeHit =
event.time();
1090 timeHit = timeHit -
event.t0;
1092 if (timeHit <= -400e3)
1108 B2INFO(
"Batch processed and cleared: " << batch.first);
1117 B2INFO(
"Global Mean for Raw." <<
LogVar(
"RPC", tmpMean_rpc_global)
1118 <<
LogVar(
"Scint BKLM", tmpMean_scint_global)
1119 <<
LogVar(
"Scint EKLM", tmpMean_scint_global_end));
1125 B2INFO(
"Second pass: Computing per-channel time shifts (batched processing)...");
1127 for (
const auto& batch : batches) {
1128 B2INFO(
"Processing batch for time shifts: " << batch.first);
1132 channelId = klmChannel.getKLMChannelNumber();
1134 if (!batch.second(klmChannel))
1137 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1143 eventsChannel =
m_evts[channelId];
1144 int iSub = klmChannel.getSubdetector();
1145 int iF, iS, iL, iP, iC;
1148 iF = klmChannel.getSection();
1149 iS = klmChannel.getSector() - 1;
1150 iL = klmChannel.getLayer() - 1;
1151 iP = klmChannel.getPlane();
1152 iC = klmChannel.getStrip() - 1;
1154 iF = klmChannel.getSection() - 1;
1155 iS = klmChannel.getSector() - 1;
1156 iL = klmChannel.getLayer() - 1;
1157 iP = klmChannel.getPlane() - 1;
1158 iC = klmChannel.getStrip() - 1;
1163 TH1F* h_temp_tc =
nullptr;
1167 hn = Form(
"h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1168 ht = Form(
"Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1169 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1172 hn = Form(
"h_timeF%d_S%d_L%d_P%d_C%d_tc", iF, iS, iL, iP, iC);
1173 ht = Form(
"time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1174 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1179 hn = Form(
"h_timeF%d_S%d_L%d_P%d_C%d_tc_end", iF, iS, iL, iP, iC);
1180 ht = Form(
"Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1181 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1186 for (
const Event& event : eventsChannel) {
1187 double timeHit =
event.time();
1189 timeHit = timeHit -
event.t0;
1190 if (timeHit <= -400e3)
1192 h_temp_tc->Fill(timeHit);
1196 double tmpMean_channel =
fcn_gaus->GetParameter(1);
1200 m_timeShift[channelId] = tmpMean_channel - tmpMean_rpc_global;
1202 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global;
1205 m_timeShift[channelId] = tmpMean_channel - tmpMean_scint_global_end;
1212 B2INFO(
"Batch processed and cleared: " << batch.first);
1218 B2INFO(
"Effective Light m_timeShift obtained.");
1226 B2INFO(
"Effective light speed fitting.");
1228 double delayRPCPhi =
fcn_pol1->GetParameter(1);
1229 double e_slope_rpc_phi =
fcn_pol1->GetParError(1);
1232 double delayRPCZ =
fcn_pol1->GetParameter(1);
1233 double e_slope_rpc_z =
fcn_pol1->GetParError(1);
1236 double slope_scint_phi =
fcn_pol1->GetParameter(1);
1237 double e_slope_scint_phi =
fcn_pol1->GetParError(1);
1240 double slope_scint_z =
fcn_pol1->GetParameter(1);
1241 double e_slope_scint_z =
fcn_pol1->GetParError(1);
1244 double slope_scint_plane1_end =
fcn_pol1->GetParameter(1);
1245 double e_slope_scint_plane1_end =
fcn_pol1->GetParError(1);
1248 double slope_scint_plane2_end =
fcn_pol1->GetParameter(1);
1249 double e_slope_scint_plane2_end =
fcn_pol1->GetParError(1);
1251 TString logStr_phi, logStr_z;
1252 logStr_phi = Form(
"%.4f +/- %.4f ns/cm", delayRPCPhi, e_slope_rpc_phi);
1253 logStr_z = Form(
"%.4f +/- %.4f ns/cm", delayRPCZ, e_slope_rpc_z);
1254 B2INFO(
"Delay in RPCs:"
1255 <<
LogVar(
"Fitted Value (phi readout) ", logStr_phi.Data())
1256 <<
LogVar(
"Fitted Value (z readout) ", logStr_z.Data()));
1257 logStr_phi = Form(
"%.4f +/- %.4f ns/cm", slope_scint_phi, e_slope_scint_phi);
1258 logStr_z = Form(
"%.4f +/- %.4f ns/cm", slope_scint_z, e_slope_scint_z);
1259 B2INFO(
"Delay in BKLM scintillators:"
1260 <<
LogVar(
"Fitted Value (phi readout) ", logStr_phi.Data())
1261 <<
LogVar(
"Fitted Value (z readout) ", logStr_z.Data()));
1262 logStr_phi = Form(
"%.4f +/- %.4f ns/cm", slope_scint_plane1_end,
1263 e_slope_scint_plane1_end);
1264 logStr_z = Form(
"%.4f +/- %.4f ns/cm", slope_scint_plane2_end,
1265 e_slope_scint_plane2_end);
1266 B2INFO(
"Delay in EKLM scintillators:"
1267 <<
LogVar(
"Fitted Value (plane1 readout) ", logStr_phi.Data())
1268 <<
LogVar(
"Fitted Value (plane2 readout) ", logStr_z.Data()));
1270 logStr_z = Form(
"%.4f +/- %.4f ns/cm", delayBKLM, delayBKLMError);
1271 B2INFO(
"Delay in BKLM scintillators:"
1272 <<
LogVar(
"Fitted Value (2d fit) ", logStr_z.Data()));
1273 logStr_z = Form(
"%.4f +/- %.4f ns/cm", delayEKLM, delayEKLMError);
1274 B2INFO(
"Delay in EKLM scintillators:"
1275 <<
LogVar(
"Fitted Value (2d fit) ", logStr_z.Data()));
1286 B2INFO(
"Third loop: Time distribution filling (batched processing)...");
1288 for (
const auto& batch : batches) {
1289 B2INFO(
"Processing batch: " << batch.first);
1293 channelId = klmChannel.getKLMChannelNumber();
1295 if (!batch.second(klmChannel))
1298 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData)
1304 eventsChannel =
m_evts[channelId];
1305 int iSub = klmChannel.getSubdetector();
1306 int iF, iS, iL, iP, iC;
1309 iF = klmChannel.getSection();
1310 iS = klmChannel.getSector() - 1;
1311 iL = klmChannel.getLayer() - 1;
1312 iP = klmChannel.getPlane();
1313 iC = klmChannel.getStrip() - 1;
1315 iF = klmChannel.getSection() - 1;
1316 iS = klmChannel.getSector() - 1;
1317 iL = klmChannel.getLayer() - 1;
1318 iP = klmChannel.getPlane() - 1;
1319 iC = klmChannel.getStrip() - 1;
1324 TH1F* h_temp =
nullptr;
1328 hn = Form(
"h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1329 ht = Form(
"Time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1330 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1333 hn = Form(
"h_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1334 ht = Form(
"time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1335 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1340 hn = Form(
"h_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1341 ht = Form(
"Time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1342 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1348 for (
const Event& event : eventsChannel) {
1349 double timeHit =
event.time();
1351 timeHit = timeHit -
event.t0;
1352 if (timeHit <= -400e3)
1359 propgationT =
event.dist * delayRPCZ;
1361 propgationT =
event.dist * delayRPCPhi;
1362 double time = timeHit - propgationT;
1377 double propgationT =
event.dist * delayBKLM;
1378 double time = timeHit - propgationT;
1394 double propgationT =
event.dist * delayEKLM;
1395 double time = timeHit - propgationT;
1412 TFitResultPtr r = h_temp->Fit(
fcn_gaus,
"LESQ");
1414 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1423 B2INFO(
"Batch processed and cleared: " << batch.first);
1426 B2INFO(
"Original filling done.");
1429 int iChannel_rpc = 0;
1431 int iChannel_end = 0;
1433 channelId = klmChannel.getKLMChannelNumber();
1434 if (
m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1437 int iSub = klmChannel.getSubdetector();
1439 int iL = klmChannel.getLayer() - 1;
1468 B2INFO(
"Channel's time distribution fitting done.");
1473 B2INFO(
"Calibrated channel's time distribution filling begins.");
1477 channelId = klmChannel.getKLMChannelNumber();
1487 channelId = klmChannel.getKLMChannelNumber();
1492 B2DEBUG(20,
"Uncalibrated Estimation " <<
LogVar(
"Channel", channelId) <<
LogVar(
"Estimated value",
m_timeShift[channelId]));
1499 channelId = klmChannel.getKLMChannelNumber();
1501 B2ERROR(
"!!! Not All Channels Calibration Constant Set. Error Happened on " <<
LogVar(
"Channel", channelId));
1504 int iSub = klmChannel.getSubdetector();
1506 int iL = klmChannel.getLayer();
1530 B2INFO(
"Fourth loop: Calibrated time distribution filling (batched processing)...");
1532 for (
const auto& batch : batches) {
1533 B2INFO(
"Processing batch: " << batch.first);
1537 channelId = klmChannel.getKLMChannelNumber();
1539 if (!batch.second(klmChannel))
1545 eventsChannel =
m_evts[channelId];
1546 int iSub = klmChannel.getSubdetector();
1547 int iF, iS, iL, iP, iC;
1550 iF = klmChannel.getSection();
1551 iS = klmChannel.getSector() - 1;
1552 iL = klmChannel.getLayer() - 1;
1553 iP = klmChannel.getPlane();
1554 iC = klmChannel.getStrip() - 1;
1556 iF = klmChannel.getSection() - 1;
1557 iS = klmChannel.getSector() - 1;
1558 iL = klmChannel.getLayer() - 1;
1559 iP = klmChannel.getPlane() - 1;
1560 iC = klmChannel.getStrip() - 1;
1564 TH1F* hc_temp =
nullptr;
1568 hn = Form(
"hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1569 ht = Form(
"Calibrated time distribution for RPC of Channel%d, %s, Layer%d, Sector%d, %s",
1570 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1574 hn = Form(
"hc_timeF%d_S%d_L%d_P%d_C%d", iF, iS, iL, iP, iC);
1575 ht = Form(
"Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s",
1576 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1581 hn = Form(
"hc_timeF%d_S%d_L%d_P%d_C%d_end", iF, iS, iL, iP, iC);
1582 ht = Form(
"Calibrated time distribution for Scintillator of Channel%d, %s, Layer%d, Sector%d, %s (Endcap)",
1583 iC, iPstring[iP].Data(), iL, iS, iFstring[iF].Data());
1588 for (
const Event& event : eventsChannel) {
1589 double timeHit =
event.time();
1591 timeHit = timeHit -
event.t0;
1592 if (timeHit <= -400e3)
1599 propgationT =
event.dist * delayRPCZ;
1601 propgationT =
event.dist * delayRPCPhi;
1602 double time = timeHit - propgationT -
m_timeShift[channelId];
1605 hc_temp->Fill(time);
1617 double propgationT =
event.dist * delayBKLM;
1618 double time = timeHit - propgationT -
m_timeShift[channelId];
1621 hc_temp->Fill(time);
1634 double propgationT =
event.dist * delayEKLM;
1635 double time = timeHit - propgationT -
m_timeShift[channelId];
1638 hc_temp->Fill(time);
1652 if (
m_cFlag[channelId] == ChannelCalibrationStatus::c_NotEnoughData) {
1657 TFitResultPtr rc = hc_temp->Fit(
fcn_gaus,
"LESQ");
1659 m_cFlag[channelId] = ChannelCalibrationStatus::c_SuccessfulCalibration;
1668 B2INFO(
"Batch processed and cleared: " << batch.first);
1672 int icChannel_rpc = 0;
1674 int icChannel_end = 0;
1676 channelId = klmChannel.getKLMChannelNumber();
1677 if (
m_cFlag[channelId] != ChannelCalibrationStatus::c_SuccessfulCalibration)
1680 int iSub = klmChannel.getSubdetector();
1682 int iL = klmChannel.getLayer() - 1;
1711 B2INFO(
"Channel's time distribution fitting done.");
1716 B2INFO(
"Calibrated channel's time distribution filling begins.");
1720 channelId = klmChannel.getKLMChannelNumber();
1730 channelId = klmChannel.getKLMChannelNumber();
1735 B2DEBUG(20,
"Calibrated Estimation " <<
LogVar(
"Channel", channelId) <<
LogVar(
"Estimated value",
m_timeRes[channelId]));
1742 channelId = klmChannel.getKLMChannelNumber();
1744 B2ERROR(
"!!! Not All Channels Calibration Constant Set. Error Happened on " <<
LogVar(
"Channel", channelId));
1747 int iSub = klmChannel.getSubdetector();
1749 int iL = klmChannel.getLayer();
1780 B2INFO(
"Save Histograms into Files.");
1785 TDirectory* dir_monitor =
m_outFile->mkdir(
"monitor_Hists",
"",
true);
1789 h_diff->SetDirectory(dir_monitor);
1792 TDirectory* dir_effC =
m_outFile->mkdir(
"effC_Hists",
"",
true);
1808 TDirectory* dir_time =
m_outFile->mkdir(
"time",
"",
true);
1833 B2INFO(
"Top file setup Done.");
1839 B2INFO(
"Skipping debug histogram directory creation (m_saveAllPlots = false)");
1843 B2INFO(
"File Write and Close. Done.");
1847 TDirectory* dir_time_F[2];
1848 TDirectory* dir_time_FS[2][8];
1849 TDirectory* dir_time_FSL[2][8][15];
1850 TDirectory* dir_time_FSLP[2][8][15][2];
1851 TDirectory* dir_time_F_end[2];
1852 TDirectory* dir_time_FS_end[2][4];
1853 TDirectory* dir_time_FSL_end[2][4][14];
1854 TDirectory* dir_time_FSLP_end[2][4][14][2];
1856 B2INFO(
"Sub files declare Done.");
1857 for (
int iF = 0; iF < 2; ++iF) {
1876 sprintf(dirname,
"isForward_%d", iF);
1877 dir_time_F[iF] = dir_time->mkdir(dirname,
"",
true);
1878 dir_time_F[iF]->cd();
1880 for (
int iS = 0; iS < 8; ++iS) {
1887 h2_timeFS[iF][iS]->SetDirectory(dir_time_F[iF]);
1888 h2c_timeFS[iF][iS]->SetDirectory(dir_time_F[iF]);
1890 sprintf(dirname,
"Sector_%d", iS + 1);
1891 dir_time_FS[iF][iS] = dir_time_F[iF]->mkdir(dirname,
"",
true);
1892 dir_time_FS[iF][iS]->cd();
1894 for (
int iL = 0; iL < 15; ++iL) {
1895 h_timeFSL[iF][iS][iL]->SetDirectory(dir_time_FS[iF][iS]);
1896 hc_timeFSL[iF][iS][iL]->SetDirectory(dir_time_FS[iF][iS]);
1898 sprintf(dirname,
"Layer_%d", iL + 1);
1899 dir_time_FSL[iF][iS][iL] = dir_time_FS[iF][iS]->mkdir(dirname,
"",
true);
1900 dir_time_FSL[iF][iS][iL]->cd();
1901 for (
int iP = 0; iP < 2; ++iP) {
1902 h_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
1903 hc_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
1904 h2_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
1905 h2c_timeFSLP[iF][iS][iL][iP]->SetDirectory(dir_time_FSL[iF][iS][iL]);
1907 sprintf(dirname,
"Plane_%d", iP);
1908 dir_time_FSLP[iF][iS][iL][iP] = dir_time_FSL[iF][iS][iL]->mkdir(dirname,
"",
true);
1909 dir_time_FSLP[iF][iS][iL][iP]->cd();
1915 sprintf(dirname,
"isForward_%d_end", iF + 1);
1916 dir_time_F_end[iF] = dir_time->mkdir(dirname,
"",
true);
1917 dir_time_F_end[iF]->cd();
1918 int maxLayer = 12 + 2 * iF;
1919 for (
int iS = 0; iS < 4; ++iS) {
1926 sprintf(dirname,
"Sector_%d_end", iS + 1);
1927 dir_time_FS_end[iF][iS] = dir_time_F_end[iF]->mkdir(dirname,
"",
true);
1928 dir_time_FS_end[iF][iS]->cd();
1929 for (
int iL = 0; iL < maxLayer; ++iL) {
1930 h_timeFSL_end[iF][iS][iL]->SetDirectory(dir_time_FS_end[iF][iS]);
1931 hc_timeFSL_end[iF][iS][iL]->SetDirectory(dir_time_FS_end[iF][iS]);
1933 sprintf(dirname,
"Layer_%d_end", iL + 1);
1934 dir_time_FSL_end[iF][iS][iL] = dir_time_FS_end[iF][iS]->mkdir(dirname,
"",
true);
1935 dir_time_FSL_end[iF][iS][iL]->cd();
1936 for (
int iP = 0; iP < 2; ++iP) {
1937 h_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
1938 hc_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
1939 h2_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
1940 h2c_timeFSLP_end[iF][iS][iL][iP]->SetDirectory(dir_time_FSL_end[iF][iS][iL]);
1942 sprintf(dirname,
"plane_%d_end", iP);
1943 dir_time_FSLP_end[iF][iS][iL][iP] = dir_time_FSL_end[iF][iS][iL]->mkdir(dirname,
"",
true);
1944 dir_time_FSLP_end[iF][iS][iL][iP]->cd();
1953 B2INFO(
"File Write and Close. Done.");
1971 }
else if (iC == totNStrips) {
1977 std::pair<int, double> tS_upper =
tS_upperStrip(kCIndex_upper);
1978 std::pair<int, double> tS_lower =
tS_lowerStrip(kCIndex_lower);
1979 unsigned int td_upper = tS_upper.first - iC;
1980 unsigned int td_lower = iC - tS_lower.first;
1981 unsigned int td = tS_upper.first - tS_lower.first;
1982 tS = (double(td_upper) * tS_lower.second + double(td_lower) * tS_upper.second) /
double(td);
1989 std::pair<int, double> tS;
2003 }
else if (iC == totNStrips) {
2015 std::pair<int, double> tS;
2026 }
else if (iC == 1) {
2051 }
else if (iC == totNStrips) {
2057 std::pair<int, double> tR_upper =
tR_upperStrip(kCIndex_upper);
2058 std::pair<int, double> tR_lower =
tR_lowerStrip(kCIndex_lower);
2059 unsigned int tr_upper = tR_upper.first - iC;
2060 unsigned int tr_lower = iC - tR_lower.first;
2061 unsigned int tr = tR_upper.first - tR_lower.first;
2062 tR = (double(tr_upper) * tR_lower.second + double(tr_lower) * tR_upper.second) /
double(tr);
2069 std::pair<int, double> tR;
2083 }
else if (iC == totNStrips) {
2095 std::pair<int, double> tR;
2106 }
else if (iC == 1) {
@ c_FirstRPCLayer
First RPC layer.
@ c_ForwardSection
Forward.
@ c_BackwardSection
Backward.
static int getNStrips(int section, int sector, int layer, int plane)
Get number of strips.
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
Class for accessing objects in the database.
Singleton class to cache database objects.
static DataStore & Instance()
Instance of singleton Store.
void setInitializeActive(bool active)
Setter for m_initializeActive.
static constexpr int getMaximalStripNumber()
Get maximal strip number.
@ c_ForwardSection
Forward.
@ c_BackwardSection
Backward.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
double getStripLength(int strip) const
Get strip length.
double getMaximalStripLength() const
Get maximal strip length.
int getSubdetector() const
Get subdetector.
int getLayer() const
Get layer.
KLMChannelIndex begin()
First channel.
int getSection() const
Get section.
int getPlane() const
Get plane.
int getStrip() const
Get strip.
int getSector() const
Get sector.
KLMChannelNumber getKLMChannelNumber() const
Get KLM channel number.
KLMChannelIndex & end()
Last channel.
static const KLMElementNumbers & Instance()
Instantiation.
void channelNumberToElementNumbers(KLMChannelNumber channel, int *subdetector, int *section, int *sector, int *layer, int *plane, int *strip) const
Get element numbers by channel number.
TProfile * m_Profile2EKLMScintillatorPlane2
For EKLM scintillator plane2.
double mc_etime_channelAvg_rpc
Calibrated central value error of the global time distribution (BKLM RPC part).
TH2F * h2c_timeF_scint_end[2]
EKLM part.
KLMTimeResolution * m_timeResolution
DBObject of time resolution.
TH1F * h_time_scint_tc_end
EKLM part.
void createHistograms()
Create histograms.
TGraphErrors * gre_time_channel_scint
BKLM Scintillator.
TH1F * h_timeFSL[2][8][15]
BKLM part.
TH1F * hc_timeFSL_end[2][4][14]
EKLM part.
TH1F * h_timeFSLP_end[2][4][14][2]
EKLM part.
TGraph * gr_timeRes_channel_rpc
BKLM RPC.
TH1F * hc_timeFSLP_end[2][4][14][2]
EKLM part.
TH1F * h_timeFSLP[2][8][15][2]
BKLM part.
TH1F * hc_timeF_scint_end[2]
EKLM part.
std::map< KLMChannelNumber, double > m_timeShift
Shift values of each channel.
TH1F * h_time_scint
BKLM scintillator part.
double m_time_channelAvg_scint
Central value of the global time distribution (BKLM scintillator part).
TH1F * hc_timeFS_scint_end[2][4]
EKLM part.
double esti_timeRes(const KLMChannelIndex &klmChannel)
Estimate value of calibration constant for calibrated channels.
double m_UpperTimeBoundaryCalibratedRPC
Upper time boundary for RPC (calibrated data).
double m_ctime_channelAvg_rpc
Calibrated central value of the global time distribution (BKLM RPC part).
KLMTimeConstants * m_timeConstants
DBObject of time cost on some parts of the detector.
void setupDatabase()
Setup the database.
TH1F * hc_timeFS_scint[2][8]
BKLM scintillator part.
std::map< KLMChannelNumber, double > m_time_channel
Time distribution central value of each channel.
double m_ctime_channelAvg_scint_end
Calibrated central value of the global time distribution (EKLM scintillator part).
CalibrationAlgorithm::EResult readCalibrationData()
Read calibration data.
TGraph * gr_timeShift_channel_scint_end
EKLM.
TGraph * gr_timeRes_channel_scint
BKLM scintillator.
TH1F * hc_timeF_scint[2]
BKLM scintillator part.
TH1F * h_timeFS_scint[2][8]
BKLM scintillator part.
bool m_saveChannelHists
Write per-channel temporary histograms (tc/raw/hc) in minimal mode.
double m_UpperTimeBoundaryScintillatorsBKLM
Upper time boundary for BKLM scintillators.
const KLMElementNumbers * m_ElementNumbers
Element numbers.
std::pair< int, double > tR_upperStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with increasing strip number.
TH1F * hc_timeF_rpc[2]
BKLM RPC part.
TH2F * h2c_timeFS_end[2][4]
EKLM part.
const EKLM::GeometryData * m_EKLMGeometry
EKLM geometry data.
TGraphErrors * gre_ctime_channel_scint_end
EKLM.
TProfile * m_Profile2BKLMScintillatorPhi
For BKLM scintillator phi plane.
TH1F * hc_time_scint_end
EKLM part.
TGraphErrors * gre_time_channel_scint_end
EKLM.
TH2F * h2_timeFSLP[2][8][15][2]
BKLM part.
double m_UpperTimeBoundaryCalibratedScintillatorsEKLM
Upper time boundary for BKLM scintillators (calibrated data).
TGraph * gr_timeShift_channel_scint
BKLM scintillator.
double m_time_channelAvg_scint_end
Central value of the global time distribution (EKLM scintillator part).
TProfile * m_Profile2EKLMScintillatorPlane1
For EKLM scintillator plane1.
TH1F * hc_timeFS_rpc[2][8]
BKLM RPC part.
double m_UpperTimeBoundaryScintillatorsEKLM
Upper time boundary for BKLM scintillators.
void fillTimeDistanceProfiles(TProfile *profileRpcPhi, TProfile *profileRpcZ, TProfile *profileBKLMScintillatorPhi, TProfile *profileBKLMScintillatorZ, TProfile *profileEKLMScintillatorPlane1, TProfile *profileEKLMScintillatorPlane2, bool fill2dHistograms)
Fill profiles of time versus distance.
TFile * m_outFile
Output file.
double esti_timeShift(const KLMChannelIndex &klmChannel)
Estimate value of calibration constant for uncalibrated channels.
std::pair< int, double > tS_upperStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with increasing strip number.
double m_LowerTimeBoundaryCalibratedScintillatorsEKLM
Lower time boundary for EKLM scintillators (calibrated data).
TH1F * hc_timeFSLP[2][8][15][2]
BKLM part.
TGraphErrors * gre_ctime_channel_rpc
BKLM RPC.
void saveHist()
Save histograms to file.
const bklm::GeometryPar * m_BKLMGeometry
BKLM geometry data.
bool m_saveAllPlots
Default minimal unless you set true in your header script.
TH2F * h2c_timeFSLP[2][8][15][2]
BKLM part.
double m_ctime_channelAvg_scint
Calibrated central value of the global time distribution (BKLM scintillator part).
TF1 * fcn_const
Const function.
double m_UpperTimeBoundaryCalibratedScintillatorsBKLM
Upper time boundary for BKLM scintillators (calibrated data).
TProfile * m_Profile2RpcZ
For BKLM RPC z plane.
~KLMTimeAlgorithm()
Destructor.
TH2F * h2_timeFSLP_end[2][4][14][2]
EKLM part.
TH1I * hc_calibrated
Calibration statistics for each channel.
void timeDistance2dFit(const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channels, double &delay, double &delayError)
Two-dimensional fit for individual channels.
TGraph * gr_timeRes_channel_scint_end
EKLM.
TH1I * h_calibrated
Calibration statistics for each channel.
TProfile * m_ProfileBKLMScintillatorZ
For BKLM scintillator z plane.
double m_LowerTimeBoundaryScintillatorsBKLM
Lower time boundary for BKLM scintillators.
TH1F * h_time_rpc_tc
BKLM RPC part.
TH1F * h_time_scint_end
EKLM part.
TH2F * h2c_timeF_scint[2]
BKLM scintillator part.
TF1 * fcn_pol1
Pol1 function.
double m_etime_channelAvg_scint_end
Central value error of the global time distribution (EKLM scintillator part).
TH1F * hc_time_rpc
BKLM RPC part.
double mc_etime_channelAvg_scint
Calibrated central value error of the global time distribution (BKLM scintillator part).
TH2F * h2c_timeFSLP_end[2][4][14][2]
EKLM part.
double mc_etime_channelAvg_scint_end
Calibrated central value error of the global time distribution (EKLM scintillator part).
void writeThenDelete_(TH1 *h, bool write)
Optionally write a histogram, then delete it to free memory.
TH2F * h2_timeF_scint_end[2]
EKLM part.
TF1 * fcn_gaus
Gaussian function.
double m_LowerTimeBoundaryCalibratedScintillatorsBKLM
Lower time boundary for BKLM scintillators (calibrated data).
TH1F * h_timeF_rpc[2]
BKLM RPC part.
TProfile * m_ProfileBKLMScintillatorPhi
For BKLM scintillator phi plane.
TH1F * hc_time_scint
BKLM scintillator part.
TH2F * h2_timeFS[2][8]
BKLM part.
double m_etime_channelAvg_scint
Central value error of the global time distribution (BKLM scintillator part).
TH1F * h_timeF_scint_end[2]
EKLM part.
TProfile * m_ProfileRpcPhi
For BKLM RPC phi plane.
TGraphErrors * gre_ctime_channel_scint
BKLM Scintillator.
TProfile * m_ProfileEKLMScintillatorPlane2
For EKLM scintillator plane2.
TH1F * h_time_rpc
BKLM RPC part.
TH1F * h_timeFSL_end[2][4][14]
EKLM part.
TProfile * m_Profile2RpcPhi
For BKLM RPC phi plane.
TH1F * h_timeF_scint[2]
BKLM scintillator part.
TH1F * hc_timeFSL[2][8][15]
BKLM part.
TProfile * m_Profile2BKLMScintillatorZ
For BKLM scintillator z plane.
TH1F * h_timeFS_rpc[2][8]
BKLM RPC part.
KLMChannelIndex m_klmChannels
KLM ChannelIndex object.
TGraph * gr_timeShift_channel_rpc
BKLM RPC.
std::map< KLMChannelNumber, double > m_timeRes
Resolution values of each channel.
TH1F * h_diff
Distance between global and local position.
TH2F * h2_timeF_scint[2]
BKLM scintillator part.
TH1F * h_time_scint_tc
BKLM scintillator part.
double m_LowerTimeBoundaryRPC
Lower time boundary for RPC.
virtual EResult calibrate() override
Run algorithm on data.
std::map< KLMChannelNumber, double > m_ctime_channel
Calibrated time distribution central value of each channel.
double m_LowerTimeBoundaryCalibratedRPC
Lower time boundary for RPC (calibrated data).
bool m_useEventT0
Whether to use event T0 from CDC.
int m_MinimalDigitNumber
Minimal digit number (total).
TProfile * m_ProfileEKLMScintillatorPlane1
For EKLM scintillator plane1.
double m_UpperTimeBoundaryRPC
Upper time boundary for RPC.
TH2F * h2c_timeF_rpc[2]
BKLM RPC part.
TF1 * fcn_land
Landau function.
KLMTimeCableDelay * m_timeCableDelay
DBObject of the calibration constant of each channel due to cable decay.
std::pair< int, double > tS_lowerStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with decreasing strip number.
TProfile * m_ProfileRpcZ
For BKLM RPC z plane.
std::map< KLMChannelNumber, double > mc_etime_channel
Calibrated time distribution central value Error of each channel.
std::pair< int, double > tR_lowerStrip(const KLMChannelIndex &klmChannel)
Tracing available channels with decreasing strip number.
void readCalibrationDataBatch(std::function< bool(const KLMChannelIndex &)> channelFilter)
Load calibration data for a specific batch of channels.
ROOT::Math::MinimizerOptions m_minimizerOptions
Minimization options.
std::map< KLMChannelNumber, int > m_cFlag
Calibration flag if the channel has enough hits collected and fitted OK.
TGraphErrors * gre_time_channel_rpc
BKLM RPC.
TH2F * h2_timeFS_end[2][4]
EKLM part.
TH2F * h2_timeF_rpc[2]
BKLM RPC part.
std::map< KLMChannelNumber, std::vector< struct Event > > m_evts
Container of hit information.
TH1F * h_timeFS_scint_end[2][4]
EKLM part.
double m_time_channelAvg_rpc
Central value of the global time distribution (BKLM RPC part).
TH2F * h2c_timeFS[2][8]
BKLM part.
double m_etime_channelAvg_rpc
Central value error of the global time distribution (BKLM RPC part).
double m_LowerTimeBoundaryScintillatorsEKLM
Lower time boundary for EKLM scintillators.
KLMTimeAlgorithm()
Constructor.
void readCalibrationDataCounts(std::map< KLMChannelNumber, unsigned int > &eventCounts)
Count events per channel (lightweight scan without loading full data).
std::map< KLMChannelNumber, double > m_etime_channel
Time distribution central value Error of each channel.
int m_lower_limit_counts
Lower limit of hits collected for on single channel.
void readCalibrationDataFor2DFit(const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsBKLM, const std::vector< std::pair< KLMChannelNumber, unsigned int > > &channelsEKLM)
Load calibration data only for channels needed for 2D fit.
Class to store BKLM delay time coused by cable in the database.
void setTimeDelay(KLMChannelNumber channel, float timeDelay)
Set the time calibration constant.
Class to store KLM constants related to time.
@ c_BKLM
BKLM scintillator.
@ c_EKLM
EKLM scintillator.
void setDelay(float delay, int cType)
Set effective light speed of scintillators.
Class to store KLM time resolution in the database.
void setTimeResolution(KLMChannelNumber channel, float resolution)
Set time resolution.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
bool construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
static const double cm
Standard units with the value = 1.
const Module * findModule(int section, int sector, int layer) const
Get the pointer to the definition of a module.
double getMaximalZStripLength() const
Get maximal Z strip length (for scintillators).
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
double getMaximalPhiStripLength() const
Get maximal phi strip length (for scintillators).
Define the geometry of a BKLM module Each sector [octant] contains Modules.
Class to store variables with their name which were sent to the logging service.
static DBStore & Instance()
Instance of a singleton DBStore.
void updateEvent()
Updates all intra-run dependent objects.
void update()
Updates all objects that are outside their interval of validity.
double sqrt(double a)
sqrt for double
uint16_t KLMChannelNumber
Channel number.
Abstract base class for different kinds of events.