10#include <ecl/calibration/eclBhabhaTAlgorithm.h>
13#include <ecl/dataobjects/ECLElementNumbers.h>
14#include <ecl/dbobjects/ECLCrystalCalib.h>
15#include <ecl/dbobjects/ECLReferenceCrystalPerCrateCalib.h>
16#include <ecl/digitization/EclConfiguration.h>
17#include <ecl/mapper/ECLChannelMapper.h>
20#include <framework/database/DBObjPtr.h>
21#include <framework/database/DBStore.h>
22#include <framework/dataobjects/EventMetaData.h>
23#include <framework/datastore/DataStore.h>
24#include <framework/datastore/StoreObjPtr.h>
40 cellIDHi(ECLElementNumbers::c_NCrystals),
41 meanCleanRebinFactor(1),
42 meanCleanCutMinFactor(0),
45 savePrevCrysPayload(false),
46 readPrevCrysPayload(false),
48 debugFilenameBase(
"eclBhabhaTAlgorithm"),
49 collectorName(
"ECLBhabhaTCollector"),
50 refCrysPerCrate{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
51 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
52 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
53 -1, -1, -1, -1, -1, -1, -1}
55 setDescription(
"Calculate time offsets from bhabha events by fitting gaussian function to the (t - T0) difference.");
67 B2INFO(
"eclBhabhaTAlgorithm parameters:");
76 B2INFO(
"refCrysPerCrate = {");
77 for (
int crateTest = 0; crateTest < 52 - 1; crateTest++) {
85 auto TimevsCrysPrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibPrevCrystCalib");
86 auto TimevsCratePrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCratePrevCrateCalibPrevCrystCalib");
87 auto TimevsCrysNoCalibrations = getObjectPtr<TH2F>(
"TimevsCrysNoCalibrations");
88 auto TimevsCrysPrevCrateCalibNoCrystCalib = getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibNoCrystCalib");
89 auto TimevsCrateNoCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCrateNoCrateCalibPrevCrystCalib");
92 auto cutflow = getObjectPtr<TH1F>(
"cutflow");
93 auto svdEventT0 = getObjectPtr<TH1D>(
"svdEventT0");
98 unique_ptr<TH1F> tsNew_MINUS_tsOld__cid(
new TH1F(
"TsNew_MINUS_TsOld__cid",
101 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld__crateID(
new TH1F(
"tcrateNew_MINUS_tcrateOld__crateID",
102 ";crate id; tcrate(new | bhabha) - tcrate(previous iteration | merged) [ns]",
104 unique_ptr<TH1F> tsNew_MINUS_tsCustomPrev__cid(
new TH1F(
"TsNew_MINUS_TsCustomPrev__cid",
105 ";cell id; ts(new|bhabha) - ts(old = 'before 1st iter'|merged) [ns]",
107 unique_ptr<TH1F> tsNew_MINUS_tsOldBhabha__cid(
new TH1F(
"TsNew_MINUS_TsOldBhabha__cid",
113 unique_ptr<TH1F> tsNew_MINUS_tsOld(
new TH1F(
"TsNew_MINUS_TsOld",
114 ";ts(new | bhabha) - ts(previous iteration | merged) [ns];Number of crystals",
115 201, -10.05, 10.05));
116 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld(
new TH1F(
"tcrateNew_MINUS_tcrateOld",
117 ";tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
118 201, -10.05, 10.05));
119 unique_ptr<TH1F> tsNew_MINUS_tsCustomPrev(
new TH1F(
"TsNew_MINUS_TsCustomPrev",
120 ";ts(new | bhabha) - ts(old = 'before 1st iter' | merged) [ns];Number of crystals",
121 285, -69.5801, 69.5801));
122 unique_ptr<TH1F> tsNew_MINUS_tsOldBhabha(
new TH1F(
"TsNew_MINUS_TsOldBhabha",
123 ";ts(new | bhabha) - ts(previous iteration | bhabha) [ns];Number of crystals",
124 201, -10.05, 10.05));
129 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld_allRuns(
new TH1F(
"tcrateNew_MINUS_tcrateOld_allRuns",
130 "Crate time constant changes over all runs : tcrate(new) uncertainty < 0.1ns;tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
131 201, -10.05, 10.05));
133 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld_allRuns_allCrates(
new TH1F(
"tcrateNew_MINUS_tcrateOld_allRuns_allCrates",
134 "Crate time constant changes over all runs : all crates;tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
135 201, -10.05, 10.05));
137 unique_ptr<TH1I> num_tcrates_perRun(
new TH1I(
"num_tcrates_perRun",
138 "Number of good tcrates in each run;Run number;Number of good tcrates",
141 unique_ptr<TH2F> tcrateNew_MINUS_tcrateOld__vs__runNum(
new TH2F(
"tcrateNew_MINUS_tcrateOld__vs__runNum",
142 "Crate time constant changes vs run number : tcrate(new) uncertainty < 0.1ns;Run number;tcrate(new) - tcrate(previous iteration) [ns]",
143 6000, 0, 6000, 21, -10.5, 10.5));
149 if (!TimevsCrysNoCalibrations)
return c_Failure;
154 TFile* histExtraCrateInfofile = 0;
157 unique_ptr<TTree> tree_crystal(
new TTree(
"tree_crystal",
"Debug data from bhabha time calibration algorithm for crystals"));
159 unique_ptr<TTree> tree_crate(
new TTree(
"tree_crate",
"Debug data from bhabha time calibration algorithm for crates"));
163 vector<float> t_offsets;
165 vector<float> t_offsets_unc;
166 vector<float> t_offsets_prev;
169 int minNumEntries = 40;
170 int minNumEntriesCrateConvergence = 1000;
176 int crystalCalibSaved = 0;
180 bool minRunNumBool =
false;
181 bool maxRunNumBool =
false;
187 int expNumber = expRun.first;
188 int runNumber = expRun.second;
189 if (!minRunNumBool) {
190 minExpNum = expNumber;
191 minRunNum = runNumber;
192 minRunNumBool =
true;
194 if (!maxRunNumBool) {
195 maxExpNum = expNumber;
196 maxRunNum = runNumber;
197 maxRunNumBool =
true;
199 if (((minRunNum > runNumber) && (minExpNum >= expNumber)) ||
200 (minExpNum > expNumber)) {
201 minExpNum = expNumber;
202 minRunNum = runNumber;
204 if (((maxRunNum < runNumber) && (maxExpNum <= expNumber)) ||
205 (maxExpNum < expNumber))
208 maxExpNum = expNumber;
209 maxRunNum = runNumber;
214 string runNumsString = string(
"_") + to_string(minExpNum) +
"_" + to_string(minRunNum) + string(
"-") +
215 to_string(maxExpNum) +
"_" + to_string(maxRunNum);
217 string extraCratedebugFilename =
debugFilenameBase + string(
"_cratesAllRuns.root");
224 int eventNumberForCrates = 1;
232 evtPtr.
construct(eventNumberForCrates, minRunNum, minExpNum);
241 B2INFO(
"Uploading payload for exp " << minExpNum <<
", run " << minRunNum <<
", event " << eventNumberForCrates);
244 crystalMapper->initFromDB();
249 B2INFO(
"Reading payloads: ECLCrystalTimeOffset and ECLCrateTimeOffset");
254 vector<float> currentValuesCrys = crystalTimeObject->getCalibVector();
255 vector<float> currentUncCrys = crystalTimeObject->getCalibUncVector();
256 vector<float> currentValuesCrate = crateTimeObject->getCalibVector();
257 vector<float> currentUncCrate = crateTimeObject->getCalibUncVector();
260 B2INFO(
"Values read from database. Write out for their values for comparison against those from tcol");
262 B2INFO(
"ts: cellID " << ic + 1 <<
" " << currentValuesCrys[ic] <<
" +/- " << currentUncCrys[ic]);
263 B2INFO(
"tcrate: cellID " << ic + 1 <<
" " << currentValuesCrate[ic] <<
" +/- " << currentUncCrate[ic]);
272 prevValuesCrys = customPrevCrystalTimeObject->getCalibVector();
275 B2INFO(
"Previous values read from database. Write out for their values for comparison against those from tcol");
277 B2INFO(
"ts custom previous payload: cellID " << ic + 1 <<
" " << prevValuesCrys[ic]);
283 B2INFO(
"Reading payloads: ECLCrystalTimeOffsetBhabha");
287 vector<float> currentBhabhaValuesCrys = crystalBhabhaTimeObject->getCalibVector();
288 vector<float> currentBhabhaUncCrys = crystalBhabhaTimeObject->getCalibUncVector();
292 B2INFO(
"ts bhabha: cellID " << ic + 1 <<
" " << currentBhabhaValuesCrys[ic] <<
" +/- " << currentBhabhaUncCrys[ic]);
298 auto refCrysIDzeroingCrate = getObjectPtr<TH1F>(
"refCrysIDzeroingCrate");
302 B2INFO(
"Extract reference crystals from collector histogram.");
303 vector <short> crystalIDreferenceUntested;
305 if (refCrysIDzeroingCrate->GetBinContent(bin) > 0.5) {
306 crystalIDreferenceUntested.push_back(bin);
312 B2INFO(
"Reference crystals to define as having ts=0. Base 1 counting for both crates and crystals");
313 for (
long unsigned int crysRefCounter = 0; crysRefCounter < crystalIDreferenceUntested.size(); crysRefCounter++) {
314 int crys_id = crystalIDreferenceUntested[crysRefCounter] ;
315 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
316 B2INFO(
" crystal " << crys_id <<
" is a reference for crate " << crate_id_from_crystal);
322 B2INFO(
"Checking number of reference crystals");
323 B2INFO(
"Number of reference crystals = " << crystalIDreferenceUntested.size());
326 if (crystalIDreferenceUntested.size() != 52) {
327 B2FATAL(
"The number of reference crystals does not equal 52, which is one per crate");
330 B2INFO(
"Number of reference crystals is 52 as required");
336 vector <short> crateIDsNumRefCrystalsUntested(52, 0);
337 vector <short> crystalIDReferenceForZeroTs(52, 0);
339 for (
long unsigned int crysRefCounter = 0; crysRefCounter < crystalIDreferenceUntested.size(); crysRefCounter++) {
340 int crys_id = crystalIDreferenceUntested[crysRefCounter] ;
341 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
342 crateIDsNumRefCrystalsUntested[crate_id_from_crystal - 1]++;
343 crystalIDReferenceForZeroTs[crate_id_from_crystal - 1] = crys_id;
345 B2INFO(
"crystalIDReferenceForZeroTs = {");
346 for (
int crateTest = 0; crateTest < 52 - 1; crateTest++) {
347 B2INFO(crystalIDReferenceForZeroTs[crateTest] <<
",");
349 B2INFO(crystalIDReferenceForZeroTs[52 - 1] <<
"}");
353 for (
int crateTest = 0; crateTest < 52; crateTest++) {
354 if (crateIDsNumRefCrystalsUntested[crateTest] != 1) {
355 B2FATAL(
"Crate " << crateTest + 1 <<
" (base 1) has " << crateIDsNumRefCrystalsUntested[crateTest] <<
" reference crystals");
359 B2INFO(
"All reference crystals are reasonably mapped one crystal to one crate for all crates");
363 B2INFO(
"Extract reference crystals from algorithm steering script if provided. If user inputs custom values via steering script for this algorithm, they are only applied after all the tests are performed on the values from the histogram and override the histogram valuees. User can adjust just a single crystal if desired. Use -1 to indicate that a crystal is not to be modified. Position of crystal in list determines the crate to which the crystal is meant to be associated.");
369 bool userSetRefCrysPerCrate = false ;
370 for (
int crateTest = 0; crateTest < 52; crateTest++) {
373 B2INFO(
"Crate " << crateTest + 1 <<
" (base 1) new reference crystal = " << crystalIDReferenceForZeroTs[crateTest]);
374 userSetRefCrysPerCrate = true ;
377 if (userSetRefCrysPerCrate) {
378 B2INFO(
"User changed reference crystals via steering script");
381 fill(crateIDsNumRefCrystalsUntested.begin(), crateIDsNumRefCrystalsUntested.end(), 0);
382 for (
long unsigned int crysRefCounter = 0; crysRefCounter < 52; crysRefCounter++) {
383 int crys_id = crystalIDReferenceForZeroTs[crysRefCounter] ;
384 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
385 crateIDsNumRefCrystalsUntested[crate_id_from_crystal - 1]++;
387 for (
int crateTest = 0; crateTest < 52; crateTest++) {
388 if (crateIDsNumRefCrystalsUntested[crateTest] != 1) {
389 B2FATAL(
"Crate " << crateTest + 1 <<
" (base 1) has " << crateIDsNumRefCrystalsUntested[crateTest] <<
" reference crystals");
393 B2INFO(
"All reference crystals are reasonably mapped one crystal to one crate for all crates after changes made by user steering script.");
400 B2INFO(
"Created reference crystal per crate payload: ECLReferenceCrystalPerCrateCalib");
402 B2INFO(
"User did not change reference crystals via steering script");
409 B2INFO(
"Debug output rootfile: " << debugFilename);
410 histfile =
new TFile(debugFilename.c_str(),
"recreate");
413 TimevsCrysPrevCrateCalibPrevCrystCalib ->Write();
414 TimevsCratePrevCrateCalibPrevCrystCalib->Write();
415 TimevsCrysNoCalibrations ->Write();
416 TimevsCrysPrevCrateCalibNoCrystCalib ->Write();
417 TimevsCrateNoCrateCalibPrevCrystCalib ->Write();
424 tree_crystal->Branch(
"cid", &tree_cid)->SetTitle(
"Cell ID, 1..8736");
425 tree_crystal->Branch(
"ts", &mean)->SetTitle(
"Time offset mean, ts, ns");
426 tree_crystal->Branch(
"tsUnc", &mean_unc)->SetTitle(
"Error of time ts mean, ns.");
427 tree_crystal->Branch(
"tsSigma", &sigma)->SetTitle(
"Sigma of time ts distribution, ns");
428 tree_crystal->Branch(
"crystalCalibSaved",
429 &crystalCalibSaved)->SetTitle(
"0=crystal skipped, 1=crystal calib saved (num entries based)");
430 tree_crystal->Branch(
"tsPrev", &tsPrev)->SetTitle(
"Previous crystal time offset, ts, ns");
431 tree_crystal->SetAutoSave(10);
435 double hist_tmin = TimevsCrysNoCalibrations->GetYaxis()->GetXmin();
436 double hist_tmax = TimevsCrysNoCalibrations->GetYaxis()->GetXmax();
438 double time_fit_min = hist_tmax;
439 double time_fit_max = hist_tmin;
441 B2INFO(
"hist_tmin = " << hist_tmin);
442 B2INFO(
"hist_tmax = " << hist_tmax);
450 auto databaseCounter = getObjectPtr<TH1I>(
"databaseCounter");
451 float numTimesFilled = databaseCounter->GetBinContent(1);
452 B2INFO(
"Number of times database histograms were merged = " << numTimesFilled);
455 auto TsDatabase = getObjectPtr<TH1F>(
"TsDatabase");
456 auto TsDatabaseUnc = getObjectPtr<TH1F>(
"TsDatabaseUnc");
458 t_offsets.push_back(TsDatabase->GetBinContent(i) / numTimesFilled);
459 t_offsets_prev.push_back(TsDatabase->GetBinContent(i) / numTimesFilled);
461 B2INFO(
"t_offsets_prev (last iter) at crysID " << i <<
" = " << t_offsets_prev[i - 1]);
463 t_offsets_unc.push_back(TsDatabaseUnc->GetBinContent(i) / numTimesFilled);
471 TH1D* h_crysHits = TimevsCrysPrevCrateCalibNoCrystCalib->ProjectionX(
"h_crysHits");
472 h_crysHits->SetTitle(
"Hits per crystal;Crystal id");
474 histfile->WriteTObject(h_crysHits,
"h_crysHits");
479 crystalCalibSaved = 0;
481 double database_mean = 0;
482 double database_mean_unc = 0;
484 B2INFO(
"Crystal id = " << crys_id);
493 TH1D* h_time = TimevsCrysPrevCrateCalibNoCrystCalib->ProjectionY((
string(
"h_time_psi__") + to_string(crys_id)).c_str(),
495 TH1D* h_timeMask = (TH1D*)h_time->Clone();
496 TH1D* h_timeMasked = (TH1D*)h_time->Clone((
string(
"h_time_psi_masked__") + to_string(crys_id)).c_str());
497 TH1D* h_timeRebin = (TH1D*)h_time->Clone();
504 h_timeMask->Scale(0.0);
506 time_fit_min = hist_tmax;
507 time_fit_max = hist_tmin;
510 double histRebin_max = h_timeRebin->GetMaximum();
512 bool maskedOutNonZeroBin =
false;
514 for (
int bin = 1; bin <= h_timeRebin->GetNbinsX(); bin++) {
517 if (nonRebinnedBinNumber < h_time->GetNbinsX()) {
519 h_timeMask->SetBinContent(nonRebinnedBinNumber, 1);
522 double x_lower = h_timeRebin->GetXaxis()->GetBinLowEdge(bin);
523 double x_upper = h_timeRebin->GetXaxis()->GetBinUpEdge(bin);
524 if (x_lower < time_fit_min) {
525 time_fit_min = x_lower;
527 if (x_upper > time_fit_max) {
528 time_fit_max = x_upper;
532 if (h_time->GetBinContent(nonRebinnedBinNumber) > 0) {
533 B2DEBUG(22,
"Setting bin " << nonRebinnedBinNumber <<
" from " << h_timeMasked->GetBinContent(nonRebinnedBinNumber) <<
" to 0");
534 maskedOutNonZeroBin =
true;
536 h_timeMasked->SetBinContent(nonRebinnedBinNumber, 0);
541 B2INFO(
"Bins with non-zero values have been masked out: " << maskedOutNonZeroBin);
542 h_timeMasked->ResetStats();
543 h_timeMask->ResetStats();
548 double default_meanMasked = h_timeMasked->GetMean();
550 B2INFO(
"default_meanMasked = " << default_meanMasked);
554 double default_mean = h_time->GetMean();
555 double default_mean_unc = h_time->GetMeanError();
556 double default_sigma = h_time->GetStdDev();
558 B2INFO(
"Fitting crystal between " << time_fit_min <<
" and " << time_fit_max);
561 TF1* gaus =
new TF1(
"func",
"gaus(0)", time_fit_min, time_fit_max);
562 gaus->SetParNames(
"numCrystalHitsNormalization",
"mean",
"sigma");
569 double hist_max = h_time->GetMaximum();
572 double stddev = h_time->GetStdDev();
577 gaus->SetParameter(0, hist_max / 2.);
578 gaus->SetParameter(1, mean);
579 gaus->SetParameter(2, sigma);
586 h_timeMasked->Fit(gaus,
"LQR");
588 double fit_mean = gaus->GetParameter(1);
589 double fit_mean_unc = gaus->GetParError(1);
590 double fit_sigma = gaus->GetParameter(2);
592 double meanDiff = fit_mean - default_mean;
593 double meanUncDiff = fit_mean_unc - default_mean_unc;
594 double sigmaDiff = fit_sigma - default_sigma;
596 bool good_fit =
false;
598 if ((fabs(meanDiff) > 10) ||
599 (fabs(meanUncDiff) > 10) ||
600 (fabs(sigmaDiff) > 10) ||
601 (fit_mean_unc > 0.09) ||
603 (fit_mean < time_fit_min) ||
604 (fit_mean > time_fit_max)) {
605 B2INFO(
"Crystal id = " << crys_id);
606 B2INFO(
"fit mean, default mean = " << fit_mean <<
", " << default_mean);
607 B2INFO(
"fit mean unc, default mean unc = " << fit_mean_unc <<
", " << default_mean_unc);
608 B2INFO(
"fit sigma, default sigma = " << fit_sigma <<
", " << default_sigma);
610 B2INFO(
"crystal fit mean - hist mean = " << meanDiff);
611 B2INFO(
"fit mean unc. - hist mean unc. = " << meanUncDiff);
612 B2INFO(
"fit sigma - hist sigma = " << sigmaDiff);
614 B2INFO(
"fit_mean = " << fit_mean);
615 B2INFO(
"time_fit_min = " << time_fit_min);
616 B2INFO(
"time_fit_max = " << time_fit_max);
618 if (fabs(meanDiff) > 10) B2INFO(
"fit mean diff too large");
619 if (fabs(meanUncDiff) > 10) B2INFO(
"fit mean unc diff too large");
620 if (fabs(sigmaDiff) > 10) B2INFO(
"fit mean sigma diff too large");
621 if (fit_mean_unc > 0.09) B2INFO(
"fit mean unc too large");
622 if (fit_sigma < 0.1) B2INFO(
"fit sigma too small");
631 sigma = default_sigma;
634 int numEntries = h_time->GetEntries();
637 if ((numEntries >= minNumEntries) && good_fit) {
638 crystalCalibSaved = 1;
639 database_mean = fit_mean;
640 database_mean_unc = fit_mean_unc;
642 database_mean = default_mean;
643 database_mean_unc = -fabs(default_mean_unc);
646 if (numEntries < minNumEntries) B2INFO(
"Number of entries less than minimum");
647 if (numEntries == 0) B2INFO(
"Number of entries == 0");
653 t_offsets[crys_id - 1] = database_mean / TICKS_TO_NS;
654 t_offsets_unc[crys_id - 1] = database_mean_unc / TICKS_TO_NS;
657 histfile->WriteTObject(h_time, (
string(
"h_time_psi") + to_string(crys_id)).c_str());
658 histfile->WriteTObject(h_timeMasked, (
string(
"h_time_psi_masked") + to_string(crys_id)).c_str());
660 mean = database_mean;
661 mean_unc = database_mean_unc;
663 tsPrev = t_offsets_prev[crys_id - 1] * TICKS_TO_NS;
666 tree_crystal->Fill();
672 vector <double> tsRefCID ;
673 B2INFO(
"crystal times before shift");
674 for (
int crate_id = 1; crate_id <= 52; crate_id++) {
675 tsRefCID.push_back(t_offsets[ crystalIDReferenceForZeroTs[crate_id - 1] - 1 ]);
676 B2INFO(
"crystal time [crystal = " << crystalIDReferenceForZeroTs[crate_id - 1] <<
", crate = " << crate_id <<
" (base 1)] = " <<
677 t_offsets[ crystalIDReferenceForZeroTs[crate_id - 1] - 1 ] <<
" ticks");
680 B2INFO(
"crystal times after shift wrt reference crystal");
682 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
683 B2INFO(
"crystal time before shift [crystal = " << crys_id <<
", crate = " << crate_id_from_crystal <<
" (base 1)] = " <<
684 t_offsets[crys_id - 1] <<
" +- " << t_offsets_unc[crys_id - 1] <<
" ticks");
689 if (t_offsets[crys_id - 1] == 0 && t_offsets_unc[crys_id - 1] == 0) {
690 B2INFO(
"crystal time after shift [crystal = " << crys_id <<
", crate = " << crate_id_from_crystal <<
" (base 1)] = " <<
691 t_offsets[crys_id - 1] <<
" ticks. No change because ts=0 and ts_unc=0 (no entries).");
693 t_offsets[crys_id - 1] = t_offsets[crys_id - 1] - tsRefCID[crate_id_from_crystal - 1];
694 B2INFO(
"crystal time after shift [crystal = " << crys_id <<
", crate = " << crate_id_from_crystal <<
" (base 1)] = " <<
695 t_offsets[crys_id - 1] <<
" ticks");
700 double tsDiff_ns = (t_offsets[crys_id - 1] - t_offsets_prev[crys_id - 1]) * TICKS_TO_NS;
701 double tsDiffBhabha_ns = -999;
703 tsDiffBhabha_ns = (t_offsets[crys_id - 1] - currentBhabhaValuesCrys[crys_id - 1]) * TICKS_TO_NS;
706 B2INFO(
"Crystal " << crys_id <<
": ts new bhabha - old merged = (" <<
707 t_offsets[crys_id - 1] <<
" - " << t_offsets_prev[crys_id - 1] <<
708 ") ticks * " << TICKS_TO_NS <<
" ns/tick = " << tsDiff_ns <<
" ns");
709 B2INFO(
"Crystal " << crys_id <<
": ts new bhabha - old bhabha = (" <<
710 t_offsets[crys_id - 1] <<
" - " << currentBhabhaValuesCrys[crys_id - 1] <<
711 ") ticks * " << TICKS_TO_NS <<
" ns/tick = " << tsDiffBhabha_ns <<
" ns");
713 tsNew_MINUS_tsOld__cid->SetBinContent(crys_id, tsDiff_ns);
714 tsNew_MINUS_tsOld__cid->SetBinError(crys_id, 0);
715 tsNew_MINUS_tsOld__cid->ResetStats();
717 tsNew_MINUS_tsOld->Fill(tsDiff_ns);
720 tsNew_MINUS_tsOldBhabha__cid->SetBinContent(crys_id, tsDiffBhabha_ns);
721 tsNew_MINUS_tsOldBhabha__cid->SetBinError(crys_id, 0);
722 tsNew_MINUS_tsOldBhabha__cid->ResetStats();
724 tsNew_MINUS_tsOldBhabha->Fill(tsDiffBhabha_ns);
730 double tsDiffCustomOld_ns = -999;
732 tsDiffCustomOld_ns = (t_offsets[crys_id - 1] - prevValuesCrys[crys_id - 1]) * TICKS_TO_NS;
733 B2INFO(
"Crystal " << crys_id <<
": ts new bhabha - 'before 1st iter' merged = (" <<
734 t_offsets[crys_id - 1] <<
" - " << prevValuesCrys[crys_id - 1] <<
735 ") ticks * " << TICKS_TO_NS <<
" ns/tick = " << tsDiffCustomOld_ns <<
" ns");
737 tsNew_MINUS_tsCustomPrev__cid->SetBinContent(crys_id, tsDiffCustomOld_ns);
738 tsNew_MINUS_tsCustomPrev__cid->SetBinError(crys_id, 0);
739 tsNew_MINUS_tsCustomPrev__cid->ResetStats();
741 tsNew_MINUS_tsCustomPrev->Fill(tsDiffCustomOld_ns);
746 histfile->WriteTObject(tsNew_MINUS_tsOld__cid.get(),
"tsNew_MINUS_tsOld__cid");
747 histfile->WriteTObject(tsNew_MINUS_tsOld.get(),
"tsNew_MINUS_tsOld");
749 histfile->WriteTObject(tsNew_MINUS_tsCustomPrev__cid.get(),
"tsNew_MINUS_tsCustomPrev__cid");
750 histfile->WriteTObject(tsNew_MINUS_tsCustomPrev.get(),
"tsNew_MINUS_tsCustomPrev");
752 histfile->WriteTObject(tsNew_MINUS_tsOldBhabha__cid.get(),
"tsNew_MINUS_tsOldBhabha__cid");
753 histfile->WriteTObject(tsNew_MINUS_tsOldBhabha.get(),
"tsNew_MINUS_tsOldBhabha");
763 crysTCalib_prev->
setCalibVector(currentValuesCrys, currentUncCrys);
766 crysBhabhaTCalib_prev->
setCalibVector(currentBhabhaValuesCrys, currentBhabhaUncCrys);
772 saveCalibration(crysTCalib_prev,
"ECLCrystalTimeOffsetPreviousValues");
773 B2INFO(
"Previous overall crystal payload made");
775 saveCalibration(crysBhabhaTCalib_prev,
"ECLCrystalTimeOffsetBhabhaPreviousValues");
776 B2INFO(
"Previous bhabha crystal payload made");
789 B2DEBUG(22,
"crystal payload made");
793 B2DEBUG(22,
"end of crystal start of crate corrections .....");
799 hist_tmin = TimevsCrateNoCrateCalibPrevCrystCalib->GetYaxis()->GetXmin();
800 hist_tmax = TimevsCrateNoCrateCalibPrevCrystCalib->GetYaxis()->GetXmax();
802 B2DEBUG(22,
"Found min/max of X axis of TimevsCrateNoCrateCalibPrevCrystCalib");
806 auto TcrateDatabase = getObjectPtr<TH1F>(
"TcrateDatabase");
809 B2DEBUG(22,
"Retrieved Ts and Tcrate histograms from tcol root file");
812 vector<float> tcrate_mean_new(52, 0.0);
813 vector<float> tcrate_mean_unc_new(52, 0.0);
814 vector<float> tcrate_sigma_new(52, 0.0);
815 vector<float> tcrate_mean_prev(52, 0.0);
817 vector<bool> tcrate_new_was_set(52,
false);
818 vector<bool> tcrate_new_goodQuality(52,
false);
820 B2DEBUG(22,
"crate vectors set");
827 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
828 tcrate_mean_prev[crate_id_from_crystal - 1] = TcrateDatabase->GetBinContent(crys_id) / numTimesFilled;
832 B2INFO(
"Print out previous crate time calibration constants to make sure they match from the two different sources.");
833 for (
int crate_id = 1; crate_id <= 52; crate_id++) {
834 B2INFO(
"tcrate_mean_prev[crate " << crate_id <<
" (base 1)] = " << tcrate_mean_prev[crate_id - 1]);
836 int thisRefCellID = crystalIDReferenceForZeroTs[crate_id - 1];
837 B2INFO(
"tcrate from payload: ref cellID " << thisRefCellID <<
" " << currentValuesCrate[thisRefCellID - 1] <<
" +/- " <<
838 currentUncCrate[thisRefCellID - 1]);
845 TFile* histExtraCrateInfofile_dummy = 0;
846 B2INFO(
"Debug output rootfile used for crate iterations: " << extraCratedebugFilename);
847 histExtraCrateInfofile_dummy =
new TFile(extraCratedebugFilename.c_str(),
"UPDATE");
851 TKey* key = histExtraCrateInfofile_dummy->FindKey(
"tcrateNew_MINUS_tcrateOld_allRuns");
853 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"tcrateNew_MINUS_tcrateOld_allRuns");
854 tcrateNew_MINUS_tcrateOld_allRuns->Add(h);
857 key = histExtraCrateInfofile_dummy->FindKey(
"tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
859 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
860 tcrateNew_MINUS_tcrateOld_allRuns_allCrates->Add(h);
863 key = histExtraCrateInfofile_dummy->FindKey(
"num_tcrates_perRun");
865 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"num_tcrates_perRun");
866 num_tcrates_perRun->Add(h);
869 key = histExtraCrateInfofile_dummy->FindKey(
"tcrateNew_MINUS_tcrateOld__vs__runNum");
871 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"tcrateNew_MINUS_tcrateOld__vs__runNum");
872 tcrateNew_MINUS_tcrateOld__vs__runNum->Add(h);
875 histExtraCrateInfofile_dummy->Close();
879 histExtraCrateInfofile =
new TFile(extraCratedebugFilename.c_str(),
"recreate");
886 B2DEBUG(22,
"Start of crate id = " << crate_id);
888 TH1D* h_time_crate = TimevsCrateNoCrateCalibPrevCrystCalib->ProjectionY(
"h_time_psi_crate", crate_id, crate_id);
889 TH1D* h_time_crate_mask = (TH1D*)h_time_crate->Clone();
890 TH1D* h_time_crate_masked = (TH1D*)h_time_crate->Clone();
891 TH1D* h_time_crate_rebin = (TH1D*)h_time_crate->Clone();
898 h_time_crate_mask->Scale(0.0);
900 time_fit_min = hist_tmax;
901 time_fit_max = hist_tmin;
904 double histRebin_max = h_time_crate_rebin->GetMaximum();
906 bool maskedOutNonZeroBin =
false;
908 for (
int bin = 1; bin <= h_time_crate_rebin->GetNbinsX(); bin++) {
911 if (nonRebinnedBinNumber < h_time_crate->GetNbinsX()) {
913 h_time_crate_mask->SetBinContent(nonRebinnedBinNumber, 1);
916 double x_lower = h_time_crate_rebin->GetXaxis()->GetBinLowEdge(bin);
917 double x_upper = h_time_crate_rebin->GetXaxis()->GetBinUpEdge(bin);
918 if (x_lower < time_fit_min) {
919 time_fit_min = x_lower;
921 if (x_upper > time_fit_max) {
922 time_fit_max = x_upper;
925 if (h_time_crate->GetBinContent(nonRebinnedBinNumber) > 0) {
926 B2DEBUG(22,
"Setting bin " << nonRebinnedBinNumber <<
" from " << h_time_crate_masked->GetBinContent(
927 nonRebinnedBinNumber) <<
" to 0");
928 maskedOutNonZeroBin =
true;
930 h_time_crate_masked->SetBinContent(nonRebinnedBinNumber, 0);
935 B2INFO(
"Bins with non-zero values have been masked out: " << maskedOutNonZeroBin);
936 h_time_crate_masked->ResetStats();
937 h_time_crate_mask->ResetStats();
943 B2DEBUG(22,
"crate loop - projected h_time_psi_crate");
946 double default_mean_crate = h_time_crate_masked->GetMean();
947 double default_mean_crate_unc = h_time_crate_masked->GetMeanError();
948 double default_sigma_crate = h_time_crate_masked->GetStdDev();
949 B2INFO(
"Fitting crate between " << time_fit_min <<
" and " << time_fit_max);
950 TF1* gaus =
new TF1(
"func",
"gaus(0)", time_fit_min, time_fit_max);
951 gaus->SetParNames(
"numCrateHisNormalization",
"mean",
"sigma");
952 double hist_max = h_time_crate->GetMaximum();
953 double stddev = h_time_crate->GetStdDev();
954 double sigma_crate = stddev;
955 double mean_crate = default_mean_crate;
956 gaus->SetParameter(0, hist_max / 2.);
957 gaus->SetParameter(1, mean_crate);
958 gaus->SetParameter(2, sigma_crate);
960 h_time_crate_masked->Fit(gaus,
"LQR");
962 double fit_mean_crate = gaus->GetParameter(1);
963 double fit_mean_crate_unc = gaus->GetParError(1);
964 double fit_sigma_crate = gaus->GetParameter(2);
966 double meanDiff = fit_mean_crate - default_mean_crate;
967 double meanUncDiff = fit_mean_crate_unc - default_mean_crate_unc;
968 double sigmaDiff = fit_sigma_crate - default_sigma_crate;
970 bool good_fit =
false;
972 B2DEBUG(22,
"Crate id = " << crate_id <<
" with crate mean = " << default_mean_crate <<
" +- " << fit_mean_crate_unc);
974 if ((fabs(meanDiff) > 7) ||
975 (fabs(meanUncDiff) > 7) ||
976 (fabs(sigmaDiff) > 7) ||
977 (fit_mean_crate_unc > 3) ||
978 (fit_sigma_crate < 0.1) ||
979 (fit_mean_crate < time_fit_min) ||
980 (fit_mean_crate > time_fit_max)) {
981 B2INFO(
"Crate id = " << crate_id);
982 B2INFO(
"fit mean, default mean = " << fit_mean_crate <<
", " << default_mean_crate);
983 B2INFO(
"fit sigma, default sigma = " << fit_sigma_crate <<
", " << default_sigma_crate);
985 B2INFO(
"crate fit mean - hist mean = " << meanDiff);
986 B2INFO(
"fit mean unc. - hist mean unc. = " << meanUncDiff);
987 B2INFO(
"fit sigma - hist sigma = " << sigmaDiff);
988 B2INFO(
"fit_mean_crate = " << fit_mean_crate);
989 B2INFO(
"time_fit_min = " << time_fit_min);
990 B2INFO(
"time_fit_max = " << time_fit_max);
995 int numEntries = h_time_crate->GetEntries();
996 B2INFO(
"Number entries = " << numEntries);
997 double database_mean_crate = 0;
998 double database_mean_crate_unc = 0;
999 if ((numEntries >= minNumEntries) && good_fit) {
1000 database_mean_crate = fit_mean_crate;
1001 database_mean_crate_unc = fit_mean_crate_unc;
1003 if ((numEntries >= minNumEntriesCrateConvergence) && (fit_mean_crate_unc < 0.1)) {
1004 tcrate_new_goodQuality[crate_id - 1] =
true;
1007 database_mean_crate = default_mean_crate;
1008 database_mean_crate_unc = default_mean_crate_unc;
1010 if (numEntries == 0) {
1011 database_mean_crate = 0;
1012 database_mean_crate_unc = 0;
1015 tcrate_mean_new[crate_id - 1] = database_mean_crate;
1016 tcrate_mean_unc_new[crate_id - 1] = database_mean_crate_unc;
1017 tcrate_sigma_new[crate_id - 1] = fit_sigma_crate;
1018 tcrate_new_was_set[crate_id - 1] =
true;
1021 histfile->WriteTObject(h_time_crate, (
string(
"h_time_psi_crate") + to_string(crate_id)).c_str());
1022 histfile->WriteTObject(h_time_crate_masked, (
string(
"h_time_psi_crate_masked") + to_string(crate_id)).c_str());
1023 histfile->WriteTObject(h_time_crate_rebin, (
string(
"h_time_psi_crate_rebinned") + to_string(crate_id)).c_str());
1028 B2DEBUG(22,
"crate histograms made");
1033 vector<float> t_offsets_crate;
1035 vector<float> t_offsets_crate_unc;
1037 t_offsets_crate.push_back(0);
1038 t_offsets_crate_unc.push_back(0);
1043 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
1044 if (tcrate_new_was_set[crate_id_from_crystal - 1]) {
1045 t_offsets_crate[crys_id - 1] = tcrate_mean_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
1046 t_offsets_crate_unc[crys_id - 1] = tcrate_mean_unc_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
1049 t_offsets_crate[crys_id - 1] = tcrate_mean_prev[crate_id_from_crystal - 1];
1050 B2INFO(
"used old crate mean but zeroed uncertainty since not saved in root file");
1059 double tCrateDiff_ns = tcrate_mean_new[crate_id - 1] - (tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS);
1060 B2INFO(
"Crate " << crate_id <<
": tcrate new - previous iteration = "
1061 << tcrate_mean_new[crate_id - 1]
1062 <<
" - " << tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS
1063 <<
" = " << tCrateDiff_ns <<
" ns");
1064 tcrateNew_MINUS_tcrateOld__crateID->SetBinContent(crate_id, tCrateDiff_ns);
1065 tcrateNew_MINUS_tcrateOld__crateID->SetBinError(crate_id, 0);
1066 tcrateNew_MINUS_tcrateOld__crateID->ResetStats();
1068 tcrateNew_MINUS_tcrateOld->Fill(tCrateDiff_ns);
1071 tcrateNew_MINUS_tcrateOld_allRuns_allCrates->Fill(tCrateDiff_ns);
1072 if (tcrate_new_goodQuality[crate_id - 1]) {
1073 tcrateNew_MINUS_tcrateOld_allRuns->Fill(tCrateDiff_ns);
1074 num_tcrates_perRun->Fill(minRunNum);
1075 tcrateNew_MINUS_tcrateOld__vs__runNum->Fill(minRunNum, tCrateDiff_ns);
1080 histfile->WriteTObject(tcrateNew_MINUS_tcrateOld__crateID.get(),
"tcrateNew_MINUS_tcrateOld__crateID");
1081 histfile->WriteTObject(tcrateNew_MINUS_tcrateOld.get(),
"tcrateNew_MINUS_tcrateOld");
1084 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld_allRuns.get(),
"tcrateNew_MINUS_tcrateOld_allRuns");
1085 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld_allRuns_allCrates.get(),
1086 "tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
1087 histExtraCrateInfofile->WriteTObject(num_tcrates_perRun.get(),
"num_tcrates_perRun");
1088 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld__vs__runNum.get(),
"tcrateNew_MINUS_tcrateOld__vs__runNum");
1093 BhabhaTCrateCalib->
setCalibVector(t_offsets_crate, t_offsets_crate_unc);
1100 B2DEBUG(22,
"crate payload made");
1102 histExtraCrateInfofile->Close();
1108 double tree_tcrate_mean;
1109 double tree_tcrate_mean_unc;
1110 double tree_tcrate_sigma;
1111 double tree_tcrate_meanPrev;
1113 tree_crate->Branch(
"runNum", &tree_runNum)->SetTitle(
"Run number, 0..infinity and beyond!");
1114 tree_crate->Branch(
"crateid", &tree_crateid)->SetTitle(
"Crate id, 1..52");
1115 tree_crate->Branch(
"tcrate", &tree_tcrate_mean)->SetTitle(
"Crate time offset mean, tcrate, ns");
1116 tree_crate->Branch(
"tcratePrev", &tree_tcrate_meanPrev)->SetTitle(
"Previous crate time offset mean, tcrate, ns");
1117 tree_crate->Branch(
"tcrate_unc", &tree_tcrate_mean_unc)->SetTitle(
"Error of time tcrate mean, ns.");
1118 tree_crate->Branch(
"tcrate_sigma", &tree_tcrate_sigma)->SetTitle(
"Sigma of time tcrate distribution, ns");
1119 tree_crate->SetAutoSave(10);
1124 B2INFO(
"run num, exp num: " << expRun.second <<
", " << expRun.first);
1125 int runNumber = expRun.second;
1127 for (
int crate_id = 1; crate_id <= 52; crate_id++) {
1128 if (tcrate_new_was_set[crate_id - 1]) {
1129 tree_runNum = runNumber;
1130 tree_crateid = crate_id;
1131 tree_tcrate_mean = tcrate_mean_new[crate_id - 1];
1132 tree_tcrate_mean_unc = tcrate_mean_unc_new[crate_id - 1];
1133 tree_tcrate_sigma = tcrate_sigma_new[crate_id - 1];
1134 tree_tcrate_meanPrev = tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS;
1140 B2DEBUG(22,
"end of crate corrections .....");
1142 tree_crystal->Write();
1143 tree_crate->Write();
1147 B2INFO(
"Finished talgorithm");
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void updateDBObjPtrs(const unsigned int event, const int run, const int experiment)
Updates any DBObjPtrs by calling update(event) for DBStore.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
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 successfully =0 in Python.
@ c_Failure
Failed =3 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.
General DB object to store one calibration number per ECL crystal.
void setCalibVector(const std::vector< float > &CalibConst, const std::vector< float > &CalibConstUnc)
Set vector of constants with uncertainties.
General DB object to store one reference crystal per per ECL crate for calibration purposes.
void setCalibVector(const std::vector< short > &refCrystals)
Set vector of constants with uncertainties.
This class provides access to ECL channel map that is either a) Loaded from the database (see ecl/dbo...
static double getRF()
See m_rf.
int crateIDHi
Fit crates with crateID0 in the inclusive range [crateIDLo,crateIDHi].
int cellIDHi
Fit crystals with cellID0 in the inclusive range [cellIDLo,cellIDHi].
int cellIDLo
Fit crystals with cellID0 in the inclusive range [cellIDLo,cellIDHi].
bool debugOutput
Save every histogram and fitted function to debugFilename.
double meanCleanRebinFactor
Rebinning factor for mean calculation.
eclBhabhaTAlgorithm()
..Constructor
int crateIDLo
Fit crates with crateID0 in the inclusive range [crateIDLo,crateIDHi].
double meanCleanCutMinFactor
After rebinning, create a mask for bins that have values less than meanCleanCutMinFactor times the ma...
bool savePrevCrysPayload
Save the previous crystal payload values for comparison.
bool readPrevCrysPayload
Read the previous crystal payload values for comparison.
EResult calibrate() override
..Run algorithm on events
int refCrysPerCrate[52]
List of crystals, one per crate, used as reference time for crystal time calibration.
std::string debugFilenameBase
Name of file with debug output, eclBhabhaTAlgorithm.root by default.
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 construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
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.
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.