1 #include <ecl/calibration/eclBhabhaTAlgorithm.h>
2 #include <ecl/dbobjects/ECLCrystalCalib.h>
3 #include <ecl/digitization/EclConfiguration.h>
4 #include <framework/dataobjects/EventMetaData.h>
5 #include <ecl/utility/ECLChannelMapper.h>
16 eclBhabhaTAlgorithm::eclBhabhaTAlgorithm():
21 meanCleanRebinFactor(1),
22 meanCleanCutMinFactor(0),
26 debugFilenameBase(
"eclBhabhaTAlgorithm"),
27 collectorName(
"ECLBhabhaTCollector")
31 setDescription(
"Calculate time offsets from bhabha events by fitting gaussian function to the (t - T0) difference.");
43 B2INFO(
"eclBhabhaTAlgorithm parameters:");
54 auto TimevsCrysPrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibPrevCrystCalib");
55 auto TimevsCratePrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCratePrevCrateCalibPrevCrystCalib");
56 auto TimevsCrysNoCalibrations = getObjectPtr<TH2F>(
"TimevsCrysNoCalibrations");
57 auto TimevsCrysPrevCrateCalibNoCrystCalib = getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibNoCrystCalib");
58 auto TimevsCrateNoCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCrateNoCrateCalibPrevCrystCalib");
61 auto cutflow = getObjectPtr<TH1F>(
"cutflow");
64 if (!TimevsCrysNoCalibrations)
return c_Failure;
71 int expNumberForCrates = -1;
72 int runNumberForCrates = -1;
73 int eventNumberForCrates = 1;
75 expNumberForCrates = expRun.first;
76 runNumberForCrates = expRun.second;
78 updateDBObjPtrs(eventNumberForCrates, runNumberForCrates, expNumberForCrates);
84 unique_ptr<TTree> tree_crystal(
new TTree(
"tree_crystal",
"Debug data from bhabha time calibration algorithm for crystals"));
86 unique_ptr<TTree> tree_crate(
new TTree(
"tree_crate",
"Debug data from bhabha time calibration algorithm for crates"));
90 vector<float> t_offsets;
92 vector<float> t_offsets_unc;
94 vector<float> t_offsets_prev;
97 vector<float> t_offsets_temp;
98 vector<float> t_offsets_unc_temp;
101 int minNumEntries = 40;
107 int crystalCalibSaved = 0;
111 bool minRunNumBool =
false;
112 bool maxRunNumBool =
false;
118 int expNumber = expRun.first;
119 int runNumber = expRun.second;
120 if (!minRunNumBool) {
121 minExpNum = expNumber;
122 minRunNum = runNumber;
123 minRunNumBool =
true;
125 if (!maxRunNumBool) {
126 maxExpNum = expNumber;
127 maxRunNum = runNumber;
128 maxRunNumBool =
true;
130 if (((minRunNum > runNumber) && (minExpNum >= expNumber)) ||
131 (minExpNum > expNumber)) {
132 minExpNum = expNumber;
133 minRunNum = runNumber;
135 if (((maxRunNum < runNumber) && (maxExpNum <= expNumber)) ||
136 (maxExpNum < expNumber))
139 maxExpNum = expNumber;
140 maxRunNum = runNumber;
145 string runNumsString = string(
"_") + to_string(minExpNum) +
"_" + to_string(minRunNum) + string(
"-") + to_string(
146 maxExpNum) +
"_" + to_string(maxRunNum);
150 B2INFO(
"Debug output rootfile: " << debugFilename);
151 histfile =
new TFile(debugFilename.c_str(),
"recreate");
154 TimevsCrysPrevCrateCalibPrevCrystCalib ->Write();
155 TimevsCratePrevCrateCalibPrevCrystCalib->Write();
156 TimevsCrysNoCalibrations ->Write();
157 TimevsCrysPrevCrateCalibNoCrystCalib ->Write();
158 TimevsCrateNoCrateCalibPrevCrystCalib ->Write();
164 tree_crystal->Branch(
"cid", &tree_cid)->SetTitle(
"Cell ID, 1..8736");
165 tree_crystal->Branch(
"ts", &mean)->SetTitle(
"Time offset mean, ts, ns");
166 tree_crystal->Branch(
"tsUnc", &mean_unc)->SetTitle(
"Error of time ts mean, ns.");
167 tree_crystal->Branch(
"tsSigma", &sigma)->SetTitle(
"Sigma of time ts distribution, ns");
168 tree_crystal->Branch(
"crystalCalibSaved",
169 &crystalCalibSaved)->SetTitle(
"0=crystal skipped, 1=crystal calib saved (num entries based)");
170 tree_crystal->Branch(
"tsPrev", &tsPrev)->SetTitle(
"Previous crystal time offset, ts, ns");
171 tree_crystal->SetAutoSave(10);
175 double hist_tmin = TimevsCrysNoCalibrations->GetYaxis()->GetXmin();
176 double hist_tmax = TimevsCrysNoCalibrations->GetYaxis()->GetXmax();
178 double time_fit_min = hist_tmax;
179 double time_fit_max = hist_tmin;
181 B2INFO(
"hist_tmin = " << hist_tmin);
182 B2INFO(
"hist_tmax = " << hist_tmax);
190 auto databaseCounter = getObjectPtr<TH1F>(
"databaseCounter");
191 float numTimesFilled = databaseCounter->GetBinContent(1);
192 B2INFO(
"Number of times database histograms were merged = " << numTimesFilled);
195 auto TsDatabase = getObjectPtr<TH1F>(
"TsDatabase");
196 auto TsDatabaseUnc = getObjectPtr<TH1F>(
"TsDatabaseUnc");
197 for (
int i = 1; i <= 8736; i++) {
198 t_offsets.push_back(TsDatabase->GetBinContent(i - 1) / numTimesFilled);
199 t_offsets_prev.push_back(TsDatabase->GetBinContent(i) / numTimesFilled);
201 B2INFO(
" TsDatabase->GetBinContent(i) = " << TsDatabase->GetBinContent(i));
202 B2INFO(
"t_offsets_prev = " << t_offsets_prev[i - 1]);
205 t_offsets_unc.push_back(TsDatabaseUnc->GetBinContent(i - 1) / numTimesFilled);
213 crystalCalibSaved = 0;
215 double database_mean = 0;
216 double database_mean_unc = 0;
218 B2INFO(
"Crystal id = " << crys_id);
221 vector<bool> ts_new_was_set(8736,
false);
227 TH1D* h_time = TimevsCrysPrevCrateCalibNoCrystCalib->ProjectionY(
"h_time_psi", crys_id, crys_id);
228 TH1D* h_timeMask = (TH1D*)h_time->Clone();
229 TH1D* h_timeMasked = (TH1D*)h_time->Clone();
230 TH1D* h_timeRebin = (TH1D*)h_time->Clone();
237 h_timeMask->Scale(0.0);
239 time_fit_min = hist_tmax;
240 time_fit_max = hist_tmin;
243 double histRebin_max = h_timeRebin->GetMaximum();
245 bool maskedOutNonZeroBin =
false;
247 for (
int bin = 1; bin <= h_timeRebin->GetNbinsX(); bin++) {
250 if (nonRebinnedBinNumber < h_time->GetNbinsX()) {
252 h_timeMask->SetBinContent(nonRebinnedBinNumber, 1);
255 double x_lower = h_timeRebin->GetXaxis()->GetBinLowEdge(bin);
256 double x_upper = h_timeRebin->GetXaxis()->GetBinUpEdge(bin);
257 if (x_lower < time_fit_min) {
258 time_fit_min = x_lower;
260 if (x_upper > time_fit_max) {
261 time_fit_max = x_upper;
265 if (h_time->GetBinContent(nonRebinnedBinNumber) > 0) {
266 B2INFO(
"Setting bin " << nonRebinnedBinNumber <<
" from " << h_timeMasked->GetBinContent(nonRebinnedBinNumber) <<
" to 0");
267 maskedOutNonZeroBin =
true;
269 h_timeMasked->SetBinContent(nonRebinnedBinNumber, 0);
274 B2INFO(
"Bins with non-zero values have been masked out: " << maskedOutNonZeroBin);
275 h_timeMasked->ResetStats();
276 h_timeMask->ResetStats();
281 double default_meanMasked = h_timeMasked->GetMean();
283 B2INFO(
"default_meanMasked = " << default_meanMasked);
287 double default_mean = h_time->GetMean();
288 double default_mean_unc = h_time->GetMeanError();
289 double default_sigma = h_time->GetStdDev();
291 B2INFO(
"Fitting crystal between " << time_fit_min <<
" and " << time_fit_max);
294 TF1* gaus =
new TF1(
"func",
"gaus(0)", time_fit_min, time_fit_max);
295 gaus->SetParNames(
"numCrystalHitsNormalization",
"mean",
"sigma");
302 double hist_max = h_time->GetMaximum();
305 double stddev = h_time->GetStdDev();
310 gaus->SetParameter(0, hist_max / 2.);
311 gaus->SetParameter(1, mean);
312 gaus->SetParameter(2, sigma);
319 h_timeMasked->Fit(gaus,
"LQR");
321 double fit_mean = gaus->GetParameter(1);
322 double fit_mean_unc = gaus->GetParError(1);
323 double fit_sigma = gaus->GetParameter(2);
325 double meanDiff = fit_mean - default_mean;
326 double meanUncDiff = fit_mean_unc - default_mean_unc;
327 double sigmaDiff = fit_sigma - default_sigma;
329 bool good_fit =
false;
331 if ((fabs(meanDiff) > 10) ||
332 (fabs(meanUncDiff) > 10) ||
333 (fabs(sigmaDiff) > 10) ||
334 (fit_mean_unc > 3) ||
336 (fit_mean < time_fit_min) ||
337 (fit_mean > time_fit_max)) {
338 B2INFO(
"Crystal id = " << crys_id);
339 B2INFO(
"fit mean, default mean = " << fit_mean <<
", " << default_mean);
340 B2INFO(
"fit mean unc, default mean unc = " << fit_mean_unc <<
", " << default_mean_unc);
341 B2INFO(
"fit sigma, default sigma = " << fit_sigma <<
", " << default_sigma);
343 B2INFO(
"crystal fit mean - hist mean = " << meanDiff);
344 B2INFO(
"fit mean unc. - hist mean unc. = " << meanUncDiff);
345 B2INFO(
"fit sigma - hist sigma = " << sigmaDiff);
347 B2INFO(
"fit_mean = " << fit_mean);
348 B2INFO(
"time_fit_min = " << time_fit_min);
349 B2INFO(
"time_fit_max = " << time_fit_max);
351 if (fabs(meanDiff) > 10) B2INFO(
"fit mean diff too large");
352 if (fabs(meanUncDiff) > 10) B2INFO(
"fit mean unc diff too large");
353 if (fabs(sigmaDiff) > 10) B2INFO(
"fit mean sigma diff too large");
354 if (fit_mean_unc > 3) B2INFO(
"fit mean unc too large");
355 if (fit_sigma < 0.1) B2INFO(
"fit sigma too small");
364 sigma = default_sigma;
367 int numEntries = h_time->GetEntries();
370 if ((numEntries >= minNumEntries) && good_fit) {
371 crystalCalibSaved = 1;
372 database_mean = fit_mean;
373 database_mean_unc = fit_mean_unc;
375 database_mean = default_mean;
376 database_mean_unc = default_mean_unc;
379 if (numEntries < minNumEntries) B2INFO(
"Number of entries less than minimum");
380 if (numEntries == 0) B2INFO(
"Number of entries == 0");
386 t_offsets[crys_id - 1] = database_mean / TICKS_TO_NS;
387 t_offsets_unc[crys_id - 1] = database_mean_unc / TICKS_TO_NS;
390 histfile->WriteTObject(h_time, (std::string(
"h_time_psi") + std::to_string(crys_id)).c_str());
391 histfile->WriteTObject(h_timeMasked, (std::string(
"h_time_psi_masked") + std::to_string(crys_id)).c_str());
393 mean = database_mean;
394 mean_unc = database_mean_unc;
396 tsPrev = t_offsets_prev[crys_id - 1] * TICKS_TO_NS;
399 tree_crystal->Fill();
410 B2DEBUG(30,
"crystal payload made");
414 B2DEBUG(30,
"end of crystal start of crate corrections .....");
419 hist_tmin = TimevsCrateNoCrateCalibPrevCrystCalib->GetYaxis()->GetXmin();
420 hist_tmax = TimevsCrateNoCrateCalibPrevCrystCalib->GetYaxis()->GetXmax();
422 B2DEBUG(30,
"Found min/max of X axis of TimevsCrateNoCrateCalibPrevCrystCalib");
426 auto TcrateDatabase = getObjectPtr<TH1F>(
"TcrateDatabase");
429 B2DEBUG(30,
"Retrieved Ts and Tcrate histograms from tcol root file");
431 double database_mean_crate = 0;
432 double database_mean_crate_unc = 0;
434 double mean_crate = 0;
435 double sigma_crate = -1;
437 vector<float> tcrate_mean_new(52, 0.0);
438 vector<float> tcrate_mean_unc_new(52, 0.0);
439 vector<float> tcrate_sigma_new(52, 0.0);
440 vector<float> tcrate_mean_prev(52, 0.0);
441 vector<float> tcrate_sigma_prev(52, 0.0);
442 vector<bool> tcrate_new_was_set(52,
false);
444 B2DEBUG(30,
"crate vectors set");
450 for (
int crys_id = 1; crys_id <= 8736; crys_id++) {
451 int crate_id_from_crystal = crystalMapper->
getCrateID(crys_id);
452 tcrate_mean_prev[crate_id_from_crystal - 1] = TcrateDatabase->GetBinContent(crys_id) / numTimesFilled;
457 B2DEBUG(30,
"Start of crate id = " << crate_id);
459 TH1D* h_time_crate = TimevsCrateNoCrateCalibPrevCrystCalib->ProjectionY(
"h_time_psi_crate", crate_id, crate_id);
460 TH1D* h_time_crate_mask = (TH1D*)h_time_crate->Clone();
461 TH1D* h_time_crate_masked = (TH1D*)h_time_crate->Clone();
462 TH1D* h_time_crate_rebin = (TH1D*)h_time_crate->Clone();
470 h_time_crate_mask->Scale(0.0);
472 time_fit_min = hist_tmax;
473 time_fit_max = hist_tmin;
476 double histRebin_max = h_time_crate_rebin->GetMaximum();
478 bool maskedOutNonZeroBin =
false;
480 for (
int bin = 1; bin <= h_time_crate_rebin->GetNbinsX(); bin++) {
483 if (nonRebinnedBinNumber < h_time_crate->GetNbinsX()) {
485 h_time_crate_mask->SetBinContent(nonRebinnedBinNumber, 1);
488 double x_lower = h_time_crate_rebin->GetXaxis()->GetBinLowEdge(bin);
489 double x_upper = h_time_crate_rebin->GetXaxis()->GetBinUpEdge(bin);
490 if (x_lower < time_fit_min) {
491 time_fit_min = x_lower;
493 if (x_upper > time_fit_max) {
494 time_fit_max = x_upper;
497 if (h_time_crate->GetBinContent(nonRebinnedBinNumber) > 0) {
498 B2INFO(
"Setting bin " << nonRebinnedBinNumber <<
" from " << h_time_crate_masked->GetBinContent(nonRebinnedBinNumber) <<
" to 0");
499 maskedOutNonZeroBin =
true;
501 h_time_crate_masked->SetBinContent(nonRebinnedBinNumber, 0);
506 B2INFO(
"Bins with non-zero values have been masked out: " << maskedOutNonZeroBin);
507 h_time_crate_masked->ResetStats();
508 h_time_crate_mask->ResetStats();
514 B2DEBUG(30,
"crate loop - projected h_time_psi_crate");
517 double default_mean_crate = h_time_crate_masked->GetMean();
518 double default_mean_crate_unc = h_time_crate_masked->GetMeanError();
519 double default_sigma_crate = h_time_crate_masked->GetStdDev();
520 B2INFO(
"Fitting crate between " << time_fit_min <<
" and " << time_fit_max);
521 TF1* gaus =
new TF1(
"func",
"gaus(0)", time_fit_min, time_fit_max);
522 gaus->SetParNames(
"numCrateHisNormalization",
"mean",
"sigma");
523 double hist_max = h_time_crate->GetMaximum();
524 double stddev = h_time_crate->GetStdDev();
525 sigma_crate = stddev;
526 mean_crate = default_mean_crate;
527 gaus->SetParameter(0, hist_max / 2.);
528 gaus->SetParameter(1, mean_crate);
529 gaus->SetParameter(2, sigma_crate);
531 h_time_crate_masked->Fit(gaus,
"LQR");
533 double fit_mean_crate = gaus->GetParameter(1);
534 double fit_mean_crate_unc = gaus->GetParError(1);
535 double fit_sigma_crate = gaus->GetParameter(2);
537 double meanDiff = fit_mean_crate - default_mean_crate;
538 double meanUncDiff = fit_mean_crate_unc - default_mean_crate_unc;
539 double sigmaDiff = fit_sigma_crate - default_sigma_crate;
541 bool good_fit =
false;
543 B2DEBUG(30,
"Crate id = " << crate_id <<
" with crate mean = " << default_mean_crate <<
" +- " << fit_mean_crate_unc);
545 if ((fabs(meanDiff) > 7) ||
546 (fabs(meanUncDiff) > 7) ||
547 (fabs(sigmaDiff) > 7) ||
548 (fit_mean_crate_unc > 3) ||
549 (fit_sigma_crate < 0.1) ||
550 (fit_mean_crate < time_fit_min) ||
551 (fit_mean_crate > time_fit_max)) {
552 B2INFO(
"Crate id = " << crate_id);
553 B2INFO(
"fit mean, default mean = " << fit_mean_crate <<
", " << default_mean_crate);
554 B2INFO(
"fit sigma, default sigma = " << fit_sigma_crate <<
", " << default_sigma_crate);
556 B2INFO(
"crate fit mean - hist mean = " << meanDiff);
557 B2INFO(
"fit mean unc. - hist mean unc. = " << meanUncDiff);
558 B2INFO(
"fit sigma - hist sigma = " << sigmaDiff);
559 B2INFO(
"fit_mean_crate = " << fit_mean_crate);
560 B2INFO(
"time_fit_min = " << time_fit_min);
561 B2INFO(
"time_fit_max = " << time_fit_max);
566 int numEntries = h_time_crate->GetEntries();
567 B2INFO(
"Number entries = " << numEntries);
568 if ((numEntries >= minNumEntries) && good_fit) {
570 database_mean_crate = fit_mean_crate;
571 database_mean_crate_unc = fit_mean_crate_unc;
574 database_mean_crate = default_mean_crate;
575 database_mean_crate_unc = default_mean_crate_unc;
577 if (numEntries == 0) {
578 database_mean_crate = 0;
579 database_mean_crate_unc = 0;
582 tcrate_mean_new[crate_id - 1] = database_mean_crate;
583 tcrate_mean_unc_new[crate_id - 1] = database_mean_crate_unc;
584 tcrate_sigma_new[crate_id - 1] = fit_sigma_crate;
585 tcrate_new_was_set[crate_id - 1] =
true;
588 histfile->WriteTObject(h_time_crate, (std::string(
"h_time_psi_crate") + std::to_string(crate_id)).c_str());
589 histfile->WriteTObject(h_time_crate_masked, (std::string(
"h_time_psi_crate_masked") + std::to_string(crate_id)).c_str());
590 histfile->WriteTObject(h_time_crate_rebin, (std::string(
"h_time_psi_crate_rebinned") + std::to_string(crate_id)).c_str());
595 B2DEBUG(30,
"crate histograms made");
600 vector<float> t_offsets_crate;
602 vector<float> t_offsets_crate_unc;
603 for (
int i = 1; i <= 8736; i++) {
604 t_offsets_crate.push_back(0);
605 t_offsets_crate_unc.push_back(0);
609 for (
int crys_id = 1; crys_id <= 8736; crys_id++) {
611 int crate_id_from_crystal = crystalMapper->
getCrateID(crys_id);
612 if (tcrate_new_was_set[crate_id_from_crystal - 1]) {
613 t_offsets_crate[crys_id - 1] = tcrate_mean_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
614 t_offsets_crate_unc[crys_id - 1] = tcrate_mean_unc_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
617 t_offsets_crate[crys_id - 1] = tcrate_mean_prev[crate_id_from_crystal - 1];
618 B2INFO(
"used old crate mean but zeroed uncertainty since not saved in root file");
624 BhabhaTCrateCalib->
setCalibVector(t_offsets_crate, t_offsets_crate_unc);
631 B2DEBUG(30,
"crate payload made");
637 double tree_tcrate_mean;
638 double tree_tcrate_mean_unc;
639 double tree_tcrate_sigma;
640 double tree_tcrate_meanPrev;
642 tree_crate->Branch(
"runNum", &tree_runNum)->SetTitle(
"Run number, 0..infinity and beyond!");
643 tree_crate->Branch(
"crateid", &tree_crateid)->SetTitle(
"Crate id, 1..52");
644 tree_crate->Branch(
"tcrate", &tree_tcrate_mean)->SetTitle(
"Crate time offset mean, tcrate, ns");
645 tree_crate->Branch(
"tcratePrev", &tree_tcrate_meanPrev)->SetTitle(
"Previous crate time offset mean, tcrate, ns");
646 tree_crate->Branch(
"tcrate_unc", &tree_tcrate_mean_unc)->SetTitle(
"Error of time tcrate mean, ns.");
647 tree_crate->Branch(
"tcrate_sigma", &tree_tcrate_sigma)->SetTitle(
"Sigma of time tcrate distribution, ns");
648 tree_crate->SetAutoSave(10);
653 B2INFO(
"run num, exp num: " << expRun.second <<
", " << expRun.first);
654 int runNumber = expRun.second;
656 for (
int crate_id = 1; crate_id <= 52; crate_id++) {
657 if (tcrate_new_was_set[crate_id - 1]) {
658 tree_runNum = runNumber;
659 tree_crateid = crate_id;
660 tree_tcrate_mean = tcrate_mean_new[crate_id - 1];
661 tree_tcrate_mean_unc = tcrate_mean_unc_new[crate_id - 1];
662 tree_tcrate_sigma = tcrate_sigma_new[crate_id - 1];
663 tree_tcrate_meanPrev = tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS;
669 B2DEBUG(30,
"end of crate corrections .....");
671 tree_crystal->Write();
679 B2INFO(
"Finished talgorithm");