1 #include <ecl/calibration/eclBhabhaTAlgorithm.h>
2 #include <ecl/dbobjects/ECLCrystalCalib.h>
3 #include <ecl/dbobjects/ECLReferenceCrystalPerCrateCalib.h>
4 #include <ecl/digitization/EclConfiguration.h>
5 #include <ecl/utility/ECLChannelMapper.h>
7 #include <framework/database/DBObjPtr.h>
8 #include <framework/database/DBStore.h>
9 #include <framework/datastore/StoreObjPtr.h>
10 #include <framework/datastore/DataStore.h>
11 #include <framework/dataobjects/EventMetaData.h>
22 eclBhabhaTAlgorithm::eclBhabhaTAlgorithm():
27 meanCleanRebinFactor(1),
28 meanCleanCutMinFactor(0),
31 savePrevCrysPayload(false),
32 readPrevCrysPayload(false),
34 debugFilenameBase(
"eclBhabhaTAlgorithm"),
35 collectorName(
"ECLBhabhaTCollector"),
36 refCrysPerCrate{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
38 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
39 -1, -1, -1, -1, -1, -1, -1}
41 setDescription(
"Calculate time offsets from bhabha events by fitting gaussian function to the (t - T0) difference.");
53 B2INFO(
"eclBhabhaTAlgorithm parameters:");
62 B2INFO(
"refCrysPerCrate = {");
63 for (
int crateTest = 0; crateTest < 52 - 1; crateTest++) {
71 auto TimevsCrysPrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibPrevCrystCalib");
72 auto TimevsCratePrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCratePrevCrateCalibPrevCrystCalib");
73 auto TimevsCrysNoCalibrations = getObjectPtr<TH2F>(
"TimevsCrysNoCalibrations");
74 auto TimevsCrysPrevCrateCalibNoCrystCalib = getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibNoCrystCalib");
75 auto TimevsCrateNoCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCrateNoCrateCalibPrevCrystCalib");
78 auto cutflow = getObjectPtr<TH1F>(
"cutflow");
83 unique_ptr<TH1F> tsNew_MINUS_tsOld__cid(
new TH1F(
"TsNew_MINUS_TsOld__cid",
84 ";cell id; ts(new|bhabha) - ts(previous iteration|merged) [ns]", 8736,
86 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld__crateID(
new TH1F(
"tcrateNew_MINUS_tcrateOld__crateID",
87 ";crate id; tcrate(new | bhabha) - tcrate(previous iteration | merged) [ns]",
89 unique_ptr<TH1F> tsNew_MINUS_tsCustomPrev__cid(
new TH1F(
"TsNew_MINUS_TsCustomPrev__cid",
90 ";cell id; ts(new|bhabha) - ts(old = 'before 1st iter'|merged) [ns]",
92 unique_ptr<TH1F> tsNew_MINUS_tsOldBhabha__cid(
new TH1F(
"TsNew_MINUS_TsOldBhabha__cid",
93 ";cell id; ts(new|bhabha) - ts(previous iteration|bhabha) [ns]", 8736,
98 unique_ptr<TH1F> tsNew_MINUS_tsOld(
new TH1F(
"TsNew_MINUS_TsOld",
99 ";ts(new | bhabha) - ts(previous iteration | merged) [ns];Number of crystals",
100 201, -10.05, 10.05));
101 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld(
new TH1F(
"tcrateNew_MINUS_tcrateOld",
102 ";tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
103 201, -10.05, 10.05));
104 unique_ptr<TH1F> tsNew_MINUS_tsCustomPrev(
new TH1F(
"TsNew_MINUS_TsCustomPrev",
105 ";ts(new | bhabha) - ts(old = 'before 1st iter' | merged) [ns];Number of crystals",
106 285, -69.5801, 69.5801));
107 unique_ptr<TH1F> tsNew_MINUS_tsOldBhabha(
new TH1F(
"TsNew_MINUS_TsOldBhabha",
108 ";ts(new | bhabha) - ts(previous iteration | bhabha) [ns];Number of crystals",
109 201, -10.05, 10.05));
114 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld_allRuns(
new TH1F(
"tcrateNew_MINUS_tcrateOld_allRuns",
115 "Crate time constant changes over all runs : tcrate(new) uncertainty < 0.1ns;tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
116 201, -10.05, 10.05));
118 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld_allRuns_allCrates(
new TH1F(
"tcrateNew_MINUS_tcrateOld_allRuns_allCrates",
119 "Crate time constant changes over all runs : all crates;tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
120 201, -10.05, 10.05));
122 unique_ptr<TH1I> num_tcrates_perRun(
new TH1I(
"num_tcrates_perRun",
123 "Number of good tcrates in each run;Run number;Number of good tcrates",
126 unique_ptr<TH2F> tcrateNew_MINUS_tcrateOld__vs__runNum(
new TH2F(
"tcrateNew_MINUS_tcrateOld__vs__runNum",
127 "Crate time constant changes vs run number : tcrate(new) uncertainty < 0.1ns;Run number;tcrate(new) - tcrate(previous iteration) [ns]",
128 6000, 0, 6000, 21, -10.5, 10.5));
134 if (!TimevsCrysNoCalibrations)
return c_Failure;
139 TFile* histExtraCrateInfofile = 0;
142 unique_ptr<TTree> tree_crystal(
new TTree(
"tree_crystal",
"Debug data from bhabha time calibration algorithm for crystals"));
144 unique_ptr<TTree> tree_crate(
new TTree(
"tree_crate",
"Debug data from bhabha time calibration algorithm for crates"));
148 vector<float> t_offsets;
150 vector<float> t_offsets_unc;
152 vector<float> t_offsets_prev;
159 int minNumEntries = 40;
160 int minNumEntriesCrateConvergence = 1000;
166 int crystalCalibSaved = 0;
170 bool minRunNumBool =
false;
171 bool maxRunNumBool =
false;
177 int expNumber = expRun.first;
178 int runNumber = expRun.second;
179 if (!minRunNumBool) {
180 minExpNum = expNumber;
181 minRunNum = runNumber;
182 minRunNumBool =
true;
184 if (!maxRunNumBool) {
185 maxExpNum = expNumber;
186 maxRunNum = runNumber;
187 maxRunNumBool =
true;
189 if (((minRunNum > runNumber) && (minExpNum >= expNumber)) ||
190 (minExpNum > expNumber)) {
191 minExpNum = expNumber;
192 minRunNum = runNumber;
194 if (((maxRunNum < runNumber) && (maxExpNum <= expNumber)) ||
195 (maxExpNum < expNumber))
198 maxExpNum = expNumber;
199 maxRunNum = runNumber;
204 string runNumsString = string(
"_") + to_string(minExpNum) +
"_" + to_string(minRunNum) + string(
"-") +
205 to_string(maxExpNum) +
"_" + to_string(maxRunNum);
207 string extraCratedebugFilename =
debugFilenameBase + string(
"_cratesAllRuns.root");
214 int eventNumberForCrates = 1;
219 evtPtr.registerInDataStore();
222 evtPtr.
construct(eventNumberForCrates, minRunNum, minExpNum);
231 B2INFO(
"Uploading payload for exp " << minExpNum <<
", run " << minRunNum <<
", event " << eventNumberForCrates);
239 B2INFO(
"Reading payloads: ECLCrystalTimeOffset and ECLCrateTimeOffset");
244 vector<float> currentValuesCrys = crystalTimeObject->getCalibVector();
245 vector<float> currentUncCrys = crystalTimeObject->getCalibUncVector();
246 vector<float> currentValuesCrate = crateTimeObject->getCalibVector();
247 vector<float> currentUncCrate = crateTimeObject->getCalibUncVector();
250 B2INFO(
"Values read from database. Write out for their values for comparison against those from tcol");
251 for (
int ic = 0; ic < 8736; ic += 500) {
252 B2INFO(
"ts: cellID " << ic + 1 <<
" " << currentValuesCrys[ic] <<
" +/- " << currentUncCrys[ic]);
253 B2INFO(
"tcrate: cellID " << ic + 1 <<
" " << currentValuesCrate[ic] <<
" +/- " << currentUncCrate[ic]);
258 vector<float> prevValuesCrys(8736);
262 prevValuesCrys = customPrevCrystalTimeObject->getCalibVector();
265 B2INFO(
"Previous values read from database. Write out for their values for comparison against those from tcol");
266 for (
int ic = 0; ic < 8736; ic += 500) {
267 B2INFO(
"ts custom previous payload: cellID " << ic + 1 <<
" " << prevValuesCrys[ic]);
273 B2INFO(
"Reading payloads: ECLCrystalTimeOffsetBhabha");
277 vector<float> currentBhabhaValuesCrys = crystalBhabhaTimeObject->getCalibVector();
278 vector<float> currentBhabhaUncCrys = crystalBhabhaTimeObject->getCalibUncVector();
281 for (
int ic = 0; ic < 8736; ic += 500) {
282 B2INFO(
"ts bhabha: cellID " << ic + 1 <<
" " << currentBhabhaValuesCrys[ic] <<
" +/- " << currentBhabhaUncCrys[ic]);
288 auto refCrysIDzeroingCrate = getObjectPtr<TH1F>(
"refCrysIDzeroingCrate");
292 B2INFO(
"Extract reference crystals from collector histogram.");
293 vector <short> crystalIDreferenceUntested;
294 for (
int bin = 1; bin <= 8736; bin++) {
295 if (refCrysIDzeroingCrate->GetBinContent(bin) > 0.5) {
296 crystalIDreferenceUntested.push_back(bin);
302 B2INFO(
"Reference crystals to define as having ts=0. Base 1 counting for both crates and crystals");
303 for (
long unsigned int crysRefCounter = 0; crysRefCounter < crystalIDreferenceUntested.size(); crysRefCounter++) {
304 int crys_id = crystalIDreferenceUntested[crysRefCounter] ;
305 int crate_id_from_crystal = crystalMapper->
getCrateID(crys_id);
306 B2INFO(
" crystal " << crys_id <<
" is a reference for crate " << crate_id_from_crystal);
312 B2INFO(
"Checking number of reference crystals");
313 B2INFO(
"Number of reference crystals = " << crystalIDreferenceUntested.size());
316 if (crystalIDreferenceUntested.size() != 52) {
317 B2FATAL(
"The number of reference crystals does not equal 52, which is one per crate");
320 B2INFO(
"Number of reference crystals is 52 as required");
326 vector <short> crateIDsNumRefCrystalsUntested(52, 0);
327 vector <short> crystalIDReferenceForZeroTs(52, 0);
329 for (
long unsigned int crysRefCounter = 0; crysRefCounter < crystalIDreferenceUntested.size(); crysRefCounter++) {
330 int crys_id = crystalIDreferenceUntested[crysRefCounter] ;
331 int crate_id_from_crystal = crystalMapper->
getCrateID(crys_id);
332 crateIDsNumRefCrystalsUntested[crate_id_from_crystal - 1]++;
333 crystalIDReferenceForZeroTs[crate_id_from_crystal - 1] = crys_id;
335 B2INFO(
"crystalIDReferenceForZeroTs = {");
336 for (
int crateTest = 0; crateTest < 52 - 1; crateTest++) {
337 B2INFO(crystalIDReferenceForZeroTs[crateTest] <<
",");
339 B2INFO(crystalIDReferenceForZeroTs[52 - 1] <<
"}");
343 for (
int crateTest = 0; crateTest < 52; crateTest++) {
344 if (crateIDsNumRefCrystalsUntested[crateTest] != 1) {
345 B2FATAL(
"Crate " << crateTest + 1 <<
" (base 1) has " << crateIDsNumRefCrystalsUntested[crateTest] <<
" reference crystals");
349 B2INFO(
"All reference crystals are reasonably mapped one crystal to one crate for all crates");
353 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.");
359 bool userSetRefCrysPerCrate = false ;
360 for (
int crateTest = 0; crateTest < 52; crateTest++) {
363 B2INFO(
"Crate " << crateTest + 1 <<
" (base 1) new reference crystal = " << crystalIDReferenceForZeroTs[crateTest]);
364 userSetRefCrysPerCrate = true ;
367 if (userSetRefCrysPerCrate) {
368 B2INFO(
"User changed reference crystals via steering script");
371 fill(crateIDsNumRefCrystalsUntested.begin(), crateIDsNumRefCrystalsUntested.end(), 0);
372 for (
long unsigned int crysRefCounter = 0; crysRefCounter < 52; crysRefCounter++) {
373 int crys_id = crystalIDReferenceForZeroTs[crysRefCounter] ;
374 int crate_id_from_crystal = crystalMapper->
getCrateID(crys_id);
375 crateIDsNumRefCrystalsUntested[crate_id_from_crystal - 1]++;
377 for (
int crateTest = 0; crateTest < 52; crateTest++) {
378 if (crateIDsNumRefCrystalsUntested[crateTest] != 1) {
379 B2FATAL(
"Crate " << crateTest + 1 <<
" (base 1) has " << crateIDsNumRefCrystalsUntested[crateTest] <<
" reference crystals");
383 B2INFO(
"All reference crystals are reasonably mapped one crystal to one crate for all crates after changes made by user steering script.");
390 B2INFO(
"Created reference crystal per crate payload: ECLReferenceCrystalPerCrateCalib");
392 B2INFO(
"User did not change reference crystals via steering script");
399 B2INFO(
"Debug output rootfile: " << debugFilename);
400 histfile =
new TFile(debugFilename.c_str(),
"recreate");
403 TimevsCrysPrevCrateCalibPrevCrystCalib ->Write();
404 TimevsCratePrevCrateCalibPrevCrystCalib->Write();
405 TimevsCrysNoCalibrations ->Write();
406 TimevsCrysPrevCrateCalibNoCrystCalib ->Write();
407 TimevsCrateNoCrateCalibPrevCrystCalib ->Write();
413 tree_crystal->Branch(
"cid", &tree_cid)->SetTitle(
"Cell ID, 1..8736");
414 tree_crystal->Branch(
"ts", &mean)->SetTitle(
"Time offset mean, ts, ns");
415 tree_crystal->Branch(
"tsUnc", &mean_unc)->SetTitle(
"Error of time ts mean, ns.");
416 tree_crystal->Branch(
"tsSigma", &sigma)->SetTitle(
"Sigma of time ts distribution, ns");
417 tree_crystal->Branch(
"crystalCalibSaved",
418 &crystalCalibSaved)->SetTitle(
"0=crystal skipped, 1=crystal calib saved (num entries based)");
419 tree_crystal->Branch(
"tsPrev", &tsPrev)->SetTitle(
"Previous crystal time offset, ts, ns");
420 tree_crystal->SetAutoSave(10);
424 double hist_tmin = TimevsCrysNoCalibrations->GetYaxis()->GetXmin();
425 double hist_tmax = TimevsCrysNoCalibrations->GetYaxis()->GetXmax();
427 double time_fit_min = hist_tmax;
428 double time_fit_max = hist_tmin;
430 B2INFO(
"hist_tmin = " << hist_tmin);
431 B2INFO(
"hist_tmax = " << hist_tmax);
439 auto databaseCounter = getObjectPtr<TH1I>(
"databaseCounter");
440 float numTimesFilled = databaseCounter->GetBinContent(1);
441 B2INFO(
"Number of times database histograms were merged = " << numTimesFilled);
444 auto TsDatabase = getObjectPtr<TH1F>(
"TsDatabase");
445 auto TsDatabaseUnc = getObjectPtr<TH1F>(
"TsDatabaseUnc");
446 for (
int i = 1; i <= 8736; i++) {
447 t_offsets.push_back(TsDatabase->GetBinContent(i) / numTimesFilled);
448 t_offsets_prev.push_back(TsDatabase->GetBinContent(i) / numTimesFilled);
450 B2INFO(
"t_offsets_prev (last iter) at crysID " << i <<
" = " << t_offsets_prev[i - 1]);
452 t_offsets_unc.push_back(TsDatabaseUnc->GetBinContent(i) / numTimesFilled);
460 TH1D* h_crysHits = TimevsCrysPrevCrateCalibNoCrystCalib->ProjectionX(
"h_crysHits");
461 h_crysHits->SetTitle(
"Hits per crystal;Crystal id");
463 histfile->WriteTObject(h_crysHits,
"h_crysHits");
471 crystalCalibSaved = 0;
473 double database_mean = 0;
474 double database_mean_unc = 0;
476 B2INFO(
"Crystal id = " << crys_id);
479 vector<bool> ts_new_was_set(8736,
false);
485 TH1D* h_time = TimevsCrysPrevCrateCalibNoCrystCalib->ProjectionY((
string(
"h_time_psi__") + to_string(crys_id)).c_str(),
487 TH1D* h_timeMask = (TH1D*)h_time->Clone();
488 TH1D* h_timeMasked = (TH1D*)h_time->Clone((
string(
"h_time_psi_masked__") + to_string(crys_id)).c_str());
489 TH1D* h_timeRebin = (TH1D*)h_time->Clone();
496 h_timeMask->Scale(0.0);
498 time_fit_min = hist_tmax;
499 time_fit_max = hist_tmin;
502 double histRebin_max = h_timeRebin->GetMaximum();
504 bool maskedOutNonZeroBin =
false;
506 for (
int bin = 1; bin <= h_timeRebin->GetNbinsX(); bin++) {
509 if (nonRebinnedBinNumber < h_time->GetNbinsX()) {
511 h_timeMask->SetBinContent(nonRebinnedBinNumber, 1);
514 double x_lower = h_timeRebin->GetXaxis()->GetBinLowEdge(bin);
515 double x_upper = h_timeRebin->GetXaxis()->GetBinUpEdge(bin);
516 if (x_lower < time_fit_min) {
517 time_fit_min = x_lower;
519 if (x_upper > time_fit_max) {
520 time_fit_max = x_upper;
524 if (h_time->GetBinContent(nonRebinnedBinNumber) > 0) {
525 B2DEBUG(22,
"Setting bin " << nonRebinnedBinNumber <<
" from " << h_timeMasked->GetBinContent(nonRebinnedBinNumber) <<
" to 0");
526 maskedOutNonZeroBin =
true;
528 h_timeMasked->SetBinContent(nonRebinnedBinNumber, 0);
533 B2INFO(
"Bins with non-zero values have been masked out: " << maskedOutNonZeroBin);
534 h_timeMasked->ResetStats();
535 h_timeMask->ResetStats();
540 double default_meanMasked = h_timeMasked->GetMean();
542 B2INFO(
"default_meanMasked = " << default_meanMasked);
546 double default_mean = h_time->GetMean();
547 double default_mean_unc = h_time->GetMeanError();
548 double default_sigma = h_time->GetStdDev();
550 B2INFO(
"Fitting crystal between " << time_fit_min <<
" and " << time_fit_max);
553 TF1* gaus =
new TF1(
"func",
"gaus(0)", time_fit_min, time_fit_max);
554 gaus->SetParNames(
"numCrystalHitsNormalization",
"mean",
"sigma");
561 double hist_max = h_time->GetMaximum();
564 double stddev = h_time->GetStdDev();
569 gaus->SetParameter(0, hist_max / 2.);
570 gaus->SetParameter(1, mean);
571 gaus->SetParameter(2, sigma);
578 h_timeMasked->Fit(gaus,
"LQR");
580 double fit_mean = gaus->GetParameter(1);
581 double fit_mean_unc = gaus->GetParError(1);
582 double fit_sigma = gaus->GetParameter(2);
584 double meanDiff = fit_mean - default_mean;
585 double meanUncDiff = fit_mean_unc - default_mean_unc;
586 double sigmaDiff = fit_sigma - default_sigma;
588 bool good_fit =
false;
590 if ((fabs(meanDiff) > 10) ||
591 (fabs(meanUncDiff) > 10) ||
592 (fabs(sigmaDiff) > 10) ||
593 (fit_mean_unc > 0.09) ||
595 (fit_mean < time_fit_min) ||
596 (fit_mean > time_fit_max)) {
597 B2INFO(
"Crystal id = " << crys_id);
598 B2INFO(
"fit mean, default mean = " << fit_mean <<
", " << default_mean);
599 B2INFO(
"fit mean unc, default mean unc = " << fit_mean_unc <<
", " << default_mean_unc);
600 B2INFO(
"fit sigma, default sigma = " << fit_sigma <<
", " << default_sigma);
602 B2INFO(
"crystal fit mean - hist mean = " << meanDiff);
603 B2INFO(
"fit mean unc. - hist mean unc. = " << meanUncDiff);
604 B2INFO(
"fit sigma - hist sigma = " << sigmaDiff);
606 B2INFO(
"fit_mean = " << fit_mean);
607 B2INFO(
"time_fit_min = " << time_fit_min);
608 B2INFO(
"time_fit_max = " << time_fit_max);
610 if (fabs(meanDiff) > 10) B2INFO(
"fit mean diff too large");
611 if (fabs(meanUncDiff) > 10) B2INFO(
"fit mean unc diff too large");
612 if (fabs(sigmaDiff) > 10) B2INFO(
"fit mean sigma diff too large");
613 if (fit_mean_unc > 0.09) B2INFO(
"fit mean unc too large");
614 if (fit_sigma < 0.1) B2INFO(
"fit sigma too small");
623 sigma = default_sigma;
626 int numEntries = h_time->GetEntries();
629 if ((numEntries >= minNumEntries) && good_fit) {
630 crystalCalibSaved = 1;
631 database_mean = fit_mean;
632 database_mean_unc = fit_mean_unc;
634 database_mean = default_mean;
635 database_mean_unc = -fabs(default_mean_unc);
638 if (numEntries < minNumEntries) B2INFO(
"Number of entries less than minimum");
639 if (numEntries == 0) B2INFO(
"Number of entries == 0");
645 t_offsets[crys_id - 1] = database_mean / TICKS_TO_NS;
646 t_offsets_unc[crys_id - 1] = database_mean_unc / TICKS_TO_NS;
649 histfile->WriteTObject(h_time, (
string(
"h_time_psi") + to_string(crys_id)).c_str());
650 histfile->WriteTObject(h_timeMasked, (
string(
"h_time_psi_masked") + to_string(crys_id)).c_str());
652 mean = database_mean;
653 mean_unc = database_mean_unc;
655 tsPrev = t_offsets_prev[crys_id - 1] * TICKS_TO_NS;
658 tree_crystal->Fill();
664 vector <double> tsRefCID ;
665 B2INFO(
"crystal times before shift");
666 for (
int crate_id = 1; crate_id <= 52; crate_id++) {
667 tsRefCID.push_back(t_offsets[ crystalIDReferenceForZeroTs[crate_id - 1] - 1 ]);
668 B2INFO(
"crystal time [crystal = " << crystalIDReferenceForZeroTs[crate_id - 1] <<
", crate = " << crate_id <<
" (base 1)] = " <<
669 t_offsets[ crystalIDReferenceForZeroTs[crate_id - 1] - 1 ] <<
" ticks");
672 B2INFO(
"crystal times after shift wrt reference crystal");
673 for (
int crys_id = 1; crys_id <= 8736; crys_id++) {
674 int crate_id_from_crystal = crystalMapper->
getCrateID(crys_id);
675 B2INFO(
"crystal time before shift [crystal = " << crys_id <<
", crate = " << crate_id_from_crystal <<
" (base 1)] = " <<
676 t_offsets[crys_id - 1] <<
" +- " << t_offsets_unc[crys_id - 1] <<
" ticks");
681 if (t_offsets[crys_id - 1] == 0 && t_offsets_unc[crys_id - 1] == 0) {
682 B2INFO(
"crystal time after shift [crystal = " << crys_id <<
", crate = " << crate_id_from_crystal <<
" (base 1)] = " <<
683 t_offsets[crys_id - 1] <<
" ticks. No change because ts=0 and ts_unc=0 (no entries).");
685 t_offsets[crys_id - 1] = t_offsets[crys_id - 1] - tsRefCID[crate_id_from_crystal - 1];
686 B2INFO(
"crystal time after shift [crystal = " << crys_id <<
", crate = " << crate_id_from_crystal <<
" (base 1)] = " <<
687 t_offsets[crys_id - 1] <<
" ticks");
692 double tsDiff_ns = (t_offsets[crys_id - 1] - t_offsets_prev[crys_id - 1]) * TICKS_TO_NS;
693 double tsDiffBhabha_ns = -999;
695 tsDiffBhabha_ns = (t_offsets[crys_id - 1] - currentBhabhaValuesCrys[crys_id - 1]) * TICKS_TO_NS;
698 B2INFO(
"Crystal " << crys_id <<
": ts new bhabha - old merged = (" <<
699 t_offsets[crys_id - 1] <<
" - " << t_offsets_prev[crys_id - 1] <<
700 ") ticks * " << TICKS_TO_NS <<
" ns/tick = " << tsDiff_ns <<
" ns");
701 B2INFO(
"Crystal " << crys_id <<
": ts new bhabha - old bhabha = (" <<
702 t_offsets[crys_id - 1] <<
" - " << currentBhabhaValuesCrys[crys_id - 1] <<
703 ") ticks * " << TICKS_TO_NS <<
" ns/tick = " << tsDiffBhabha_ns <<
" ns");
705 tsNew_MINUS_tsOld__cid->SetBinContent(crys_id, tsDiff_ns);
706 tsNew_MINUS_tsOld__cid->SetBinError(crys_id, 0);
707 tsNew_MINUS_tsOld__cid->ResetStats();
709 tsNew_MINUS_tsOld->Fill(tsDiff_ns);
712 tsNew_MINUS_tsOldBhabha__cid->SetBinContent(crys_id, tsDiffBhabha_ns);
713 tsNew_MINUS_tsOldBhabha__cid->SetBinError(crys_id, 0);
714 tsNew_MINUS_tsOldBhabha__cid->ResetStats();
716 tsNew_MINUS_tsOldBhabha->Fill(tsDiffBhabha_ns);
722 double tsDiffCustomOld_ns = -999;
724 tsDiffCustomOld_ns = (t_offsets[crys_id - 1] - prevValuesCrys[crys_id - 1]) * TICKS_TO_NS;
725 B2INFO(
"Crystal " << crys_id <<
": ts new bhabha - 'before 1st iter' merged = (" <<
726 t_offsets[crys_id - 1] <<
" - " << prevValuesCrys[crys_id - 1] <<
727 ") ticks * " << TICKS_TO_NS <<
" ns/tick = " << tsDiffCustomOld_ns <<
" ns");
729 tsNew_MINUS_tsCustomPrev__cid->SetBinContent(crys_id, tsDiffCustomOld_ns);
730 tsNew_MINUS_tsCustomPrev__cid->SetBinError(crys_id, 0);
731 tsNew_MINUS_tsCustomPrev__cid->ResetStats();
733 tsNew_MINUS_tsCustomPrev->Fill(tsDiffCustomOld_ns);
738 histfile->WriteTObject(tsNew_MINUS_tsOld__cid.get(),
"tsNew_MINUS_tsOld__cid");
739 histfile->WriteTObject(tsNew_MINUS_tsOld.get(),
"tsNew_MINUS_tsOld");
741 histfile->WriteTObject(tsNew_MINUS_tsCustomPrev__cid.get(),
"tsNew_MINUS_tsCustomPrev__cid");
742 histfile->WriteTObject(tsNew_MINUS_tsCustomPrev.get(),
"tsNew_MINUS_tsCustomPrev");
744 histfile->WriteTObject(tsNew_MINUS_tsOldBhabha__cid.get(),
"tsNew_MINUS_tsOldBhabha__cid");
745 histfile->WriteTObject(tsNew_MINUS_tsOldBhabha.get(),
"tsNew_MINUS_tsOldBhabha");
755 crysTCalib_prev->
setCalibVector(currentValuesCrys, currentUncCrys);
758 crysBhabhaTCalib_prev->
setCalibVector(currentBhabhaValuesCrys, currentBhabhaUncCrys);
764 saveCalibration(crysTCalib_prev,
"ECLCrystalTimeOffsetPreviousValues");
765 B2INFO(
"Previous overall crystal payload made");
767 saveCalibration(crysBhabhaTCalib_prev,
"ECLCrystalTimeOffsetBhabhaPreviousValues");
768 B2INFO(
"Previous bhabha crystal payload made");
781 B2DEBUG(22,
"crystal payload made");
785 B2DEBUG(22,
"end of crystal start of crate corrections .....");
791 hist_tmin = TimevsCrateNoCrateCalibPrevCrystCalib->GetYaxis()->GetXmin();
792 hist_tmax = TimevsCrateNoCrateCalibPrevCrystCalib->GetYaxis()->GetXmax();
794 B2DEBUG(22,
"Found min/max of X axis of TimevsCrateNoCrateCalibPrevCrystCalib");
798 auto TcrateDatabase = getObjectPtr<TH1F>(
"TcrateDatabase");
801 B2DEBUG(22,
"Retrieved Ts and Tcrate histograms from tcol root file");
803 double database_mean_crate = 0;
804 double database_mean_crate_unc = 0;
806 double mean_crate = 0;
807 double sigma_crate = -1;
809 vector<float> tcrate_mean_new(52, 0.0);
810 vector<float> tcrate_mean_unc_new(52, 0.0);
811 vector<float> tcrate_sigma_new(52, 0.0);
812 vector<float> tcrate_mean_prev(52, 0.0);
813 vector<float> tcrate_sigma_prev(52, 0.0);
814 vector<bool> tcrate_new_was_set(52,
false);
815 vector<bool> tcrate_new_goodQuality(52,
false);
817 B2DEBUG(22,
"crate vectors set");
823 for (
int crys_id = 1; crys_id <= 8736; crys_id++) {
824 int crate_id_from_crystal = crystalMapper->
getCrateID(crys_id);
825 tcrate_mean_prev[crate_id_from_crystal - 1] = TcrateDatabase->GetBinContent(crys_id) / numTimesFilled;
829 B2INFO(
"Print out previous crate time calibration constants to make sure they match from the two different sources.");
830 for (
int crate_id = 1; crate_id <= 52; crate_id++) {
831 B2INFO(
"tcrate_mean_prev[crate " << crate_id <<
" (base 1)] = " << tcrate_mean_prev[crate_id - 1]);
833 int thisRefCellID = crystalIDReferenceForZeroTs[crate_id - 1];
834 B2INFO(
"tcrate from payload: ref cellID " << thisRefCellID <<
" " << currentValuesCrate[thisRefCellID - 1] <<
" +/- " <<
835 currentUncCrate[thisRefCellID - 1]);
842 TFile* histExtraCrateInfofile_dummy = 0;
843 B2INFO(
"Debug output rootfile used for crate iterations: " << extraCratedebugFilename);
844 histExtraCrateInfofile_dummy =
new TFile(extraCratedebugFilename.c_str(),
"UPDATE");
848 TKey* key = histExtraCrateInfofile_dummy->FindKey(
"tcrateNew_MINUS_tcrateOld_allRuns");
850 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"tcrateNew_MINUS_tcrateOld_allRuns");
851 tcrateNew_MINUS_tcrateOld_allRuns->Add(h);
854 key = histExtraCrateInfofile_dummy->FindKey(
"tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
856 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
857 tcrateNew_MINUS_tcrateOld_allRuns_allCrates->Add(h);
860 key = histExtraCrateInfofile_dummy->FindKey(
"num_tcrates_perRun");
862 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"num_tcrates_perRun");
863 num_tcrates_perRun->Add(h);
866 key = histExtraCrateInfofile_dummy->FindKey(
"tcrateNew_MINUS_tcrateOld__vs__runNum");
868 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"tcrateNew_MINUS_tcrateOld__vs__runNum");
869 tcrateNew_MINUS_tcrateOld__vs__runNum->Add(h);
872 histExtraCrateInfofile_dummy->Close();
876 histExtraCrateInfofile =
new TFile(extraCratedebugFilename.c_str(),
"recreate");
883 B2DEBUG(22,
"Start of crate id = " << crate_id);
885 TH1D* h_time_crate = TimevsCrateNoCrateCalibPrevCrystCalib->ProjectionY(
"h_time_psi_crate", crate_id, crate_id);
886 TH1D* h_time_crate_mask = (TH1D*)h_time_crate->Clone();
887 TH1D* h_time_crate_masked = (TH1D*)h_time_crate->Clone();
888 TH1D* h_time_crate_rebin = (TH1D*)h_time_crate->Clone();
895 h_time_crate_mask->Scale(0.0);
897 time_fit_min = hist_tmax;
898 time_fit_max = hist_tmin;
901 double histRebin_max = h_time_crate_rebin->GetMaximum();
903 bool maskedOutNonZeroBin =
false;
905 for (
int bin = 1; bin <= h_time_crate_rebin->GetNbinsX(); bin++) {
908 if (nonRebinnedBinNumber < h_time_crate->GetNbinsX()) {
910 h_time_crate_mask->SetBinContent(nonRebinnedBinNumber, 1);
913 double x_lower = h_time_crate_rebin->GetXaxis()->GetBinLowEdge(bin);
914 double x_upper = h_time_crate_rebin->GetXaxis()->GetBinUpEdge(bin);
915 if (x_lower < time_fit_min) {
916 time_fit_min = x_lower;
918 if (x_upper > time_fit_max) {
919 time_fit_max = x_upper;
922 if (h_time_crate->GetBinContent(nonRebinnedBinNumber) > 0) {
923 B2DEBUG(22,
"Setting bin " << nonRebinnedBinNumber <<
" from " << h_time_crate_masked->GetBinContent(
924 nonRebinnedBinNumber) <<
" to 0");
925 maskedOutNonZeroBin =
true;
927 h_time_crate_masked->SetBinContent(nonRebinnedBinNumber, 0);
932 B2INFO(
"Bins with non-zero values have been masked out: " << maskedOutNonZeroBin);
933 h_time_crate_masked->ResetStats();
934 h_time_crate_mask->ResetStats();
940 B2DEBUG(22,
"crate loop - projected h_time_psi_crate");
943 double default_mean_crate = h_time_crate_masked->GetMean();
944 double default_mean_crate_unc = h_time_crate_masked->GetMeanError();
945 double default_sigma_crate = h_time_crate_masked->GetStdDev();
946 B2INFO(
"Fitting crate between " << time_fit_min <<
" and " << time_fit_max);
947 TF1* gaus =
new TF1(
"func",
"gaus(0)", time_fit_min, time_fit_max);
948 gaus->SetParNames(
"numCrateHisNormalization",
"mean",
"sigma");
949 double hist_max = h_time_crate->GetMaximum();
950 double stddev = h_time_crate->GetStdDev();
951 sigma_crate = stddev;
952 mean_crate = default_mean_crate;
953 gaus->SetParameter(0, hist_max / 2.);
954 gaus->SetParameter(1, mean_crate);
955 gaus->SetParameter(2, sigma_crate);
957 h_time_crate_masked->Fit(gaus,
"LQR");
959 double fit_mean_crate = gaus->GetParameter(1);
960 double fit_mean_crate_unc = gaus->GetParError(1);
961 double fit_sigma_crate = gaus->GetParameter(2);
963 double meanDiff = fit_mean_crate - default_mean_crate;
964 double meanUncDiff = fit_mean_crate_unc - default_mean_crate_unc;
965 double sigmaDiff = fit_sigma_crate - default_sigma_crate;
967 bool good_fit =
false;
969 B2DEBUG(22,
"Crate id = " << crate_id <<
" with crate mean = " << default_mean_crate <<
" +- " << fit_mean_crate_unc);
971 if ((fabs(meanDiff) > 7) ||
972 (fabs(meanUncDiff) > 7) ||
973 (fabs(sigmaDiff) > 7) ||
974 (fit_mean_crate_unc > 3) ||
975 (fit_sigma_crate < 0.1) ||
976 (fit_mean_crate < time_fit_min) ||
977 (fit_mean_crate > time_fit_max)) {
978 B2INFO(
"Crate id = " << crate_id);
979 B2INFO(
"fit mean, default mean = " << fit_mean_crate <<
", " << default_mean_crate);
980 B2INFO(
"fit sigma, default sigma = " << fit_sigma_crate <<
", " << default_sigma_crate);
982 B2INFO(
"crate fit mean - hist mean = " << meanDiff);
983 B2INFO(
"fit mean unc. - hist mean unc. = " << meanUncDiff);
984 B2INFO(
"fit sigma - hist sigma = " << sigmaDiff);
985 B2INFO(
"fit_mean_crate = " << fit_mean_crate);
986 B2INFO(
"time_fit_min = " << time_fit_min);
987 B2INFO(
"time_fit_max = " << time_fit_max);
992 int numEntries = h_time_crate->GetEntries();
993 B2INFO(
"Number entries = " << numEntries);
994 if ((numEntries >= minNumEntries) && good_fit) {
995 database_mean_crate = fit_mean_crate;
996 database_mean_crate_unc = fit_mean_crate_unc;
998 if ((numEntries >= minNumEntriesCrateConvergence) && (fit_mean_crate_unc < 0.1)) {
999 tcrate_new_goodQuality[crate_id - 1] =
true;
1002 database_mean_crate = default_mean_crate;
1003 database_mean_crate_unc = default_mean_crate_unc;
1005 if (numEntries == 0) {
1006 database_mean_crate = 0;
1007 database_mean_crate_unc = 0;
1010 tcrate_mean_new[crate_id - 1] = database_mean_crate;
1011 tcrate_mean_unc_new[crate_id - 1] = database_mean_crate_unc;
1012 tcrate_sigma_new[crate_id - 1] = fit_sigma_crate;
1013 tcrate_new_was_set[crate_id - 1] =
true;
1016 histfile->WriteTObject(h_time_crate, (
string(
"h_time_psi_crate") + to_string(crate_id)).c_str());
1017 histfile->WriteTObject(h_time_crate_masked, (
string(
"h_time_psi_crate_masked") + to_string(crate_id)).c_str());
1018 histfile->WriteTObject(h_time_crate_rebin, (
string(
"h_time_psi_crate_rebinned") + to_string(crate_id)).c_str());
1023 B2DEBUG(22,
"crate histograms made");
1028 vector<float> t_offsets_crate;
1030 vector<float> t_offsets_crate_unc;
1031 for (
int i = 1; i <= 8736; i++) {
1032 t_offsets_crate.push_back(0);
1033 t_offsets_crate_unc.push_back(0);
1037 for (
int crys_id = 1; crys_id <= 8736; crys_id++) {
1038 int crate_id_from_crystal = crystalMapper->
getCrateID(crys_id);
1039 if (tcrate_new_was_set[crate_id_from_crystal - 1]) {
1040 t_offsets_crate[crys_id - 1] = tcrate_mean_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
1041 t_offsets_crate_unc[crys_id - 1] = tcrate_mean_unc_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
1044 t_offsets_crate[crys_id - 1] = tcrate_mean_prev[crate_id_from_crystal - 1];
1045 B2INFO(
"used old crate mean but zeroed uncertainty since not saved in root file");
1054 double tCrateDiff_ns = tcrate_mean_new[crate_id - 1] - (tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS);
1055 B2INFO(
"Crate " << crate_id <<
": tcrate new - previous iteration = "
1056 << tcrate_mean_new[crate_id - 1]
1057 <<
" - " << tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS
1058 <<
" = " << tCrateDiff_ns <<
" ns");
1059 tcrateNew_MINUS_tcrateOld__crateID->SetBinContent(crate_id, tCrateDiff_ns);
1060 tcrateNew_MINUS_tcrateOld__crateID->SetBinError(crate_id, 0);
1061 tcrateNew_MINUS_tcrateOld__crateID->ResetStats();
1063 tcrateNew_MINUS_tcrateOld->Fill(tCrateDiff_ns);
1066 tcrateNew_MINUS_tcrateOld_allRuns_allCrates->Fill(tCrateDiff_ns);
1067 if (tcrate_new_goodQuality[crate_id - 1]) {
1068 tcrateNew_MINUS_tcrateOld_allRuns->Fill(tCrateDiff_ns);
1069 num_tcrates_perRun->Fill(minRunNum);
1070 tcrateNew_MINUS_tcrateOld__vs__runNum->Fill(minRunNum, tCrateDiff_ns);
1075 histfile->WriteTObject(tcrateNew_MINUS_tcrateOld__crateID.get(),
"tcrateNew_MINUS_tcrateOld__crateID");
1076 histfile->WriteTObject(tcrateNew_MINUS_tcrateOld.get(),
"tcrateNew_MINUS_tcrateOld");
1079 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld_allRuns.get(),
"tcrateNew_MINUS_tcrateOld_allRuns");
1080 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld_allRuns_allCrates.get(),
1081 "tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
1082 histExtraCrateInfofile->WriteTObject(num_tcrates_perRun.get(),
"num_tcrates_perRun");
1083 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld__vs__runNum.get(),
"tcrateNew_MINUS_tcrateOld__vs__runNum");
1088 BhabhaTCrateCalib->
setCalibVector(t_offsets_crate, t_offsets_crate_unc);
1095 B2DEBUG(22,
"crate payload made");
1097 histExtraCrateInfofile->Close();
1103 double tree_tcrate_mean;
1104 double tree_tcrate_mean_unc;
1105 double tree_tcrate_sigma;
1106 double tree_tcrate_meanPrev;
1108 tree_crate->Branch(
"runNum", &tree_runNum)->SetTitle(
"Run number, 0..infinity and beyond!");
1109 tree_crate->Branch(
"crateid", &tree_crateid)->SetTitle(
"Crate id, 1..52");
1110 tree_crate->Branch(
"tcrate", &tree_tcrate_mean)->SetTitle(
"Crate time offset mean, tcrate, ns");
1111 tree_crate->Branch(
"tcratePrev", &tree_tcrate_meanPrev)->SetTitle(
"Previous crate time offset mean, tcrate, ns");
1112 tree_crate->Branch(
"tcrate_unc", &tree_tcrate_mean_unc)->SetTitle(
"Error of time tcrate mean, ns.");
1113 tree_crate->Branch(
"tcrate_sigma", &tree_tcrate_sigma)->SetTitle(
"Sigma of time tcrate distribution, ns");
1114 tree_crate->SetAutoSave(10);
1119 B2INFO(
"run num, exp num: " << expRun.second <<
", " << expRun.first);
1120 int runNumber = expRun.second;
1122 for (
int crate_id = 1; crate_id <= 52; crate_id++) {
1123 if (tcrate_new_was_set[crate_id - 1]) {
1124 tree_runNum = runNumber;
1125 tree_crateid = crate_id;
1126 tree_tcrate_mean = tcrate_mean_new[crate_id - 1];
1127 tree_tcrate_mean_unc = tcrate_mean_unc_new[crate_id - 1];
1128 tree_tcrate_sigma = tcrate_sigma_new[crate_id - 1];
1129 tree_tcrate_meanPrev = tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS;
1135 B2DEBUG(22,
"end of crate corrections .....");
1137 tree_crystal->Write();
1138 tree_crate->Write();
1145 B2INFO(
"Finished talgorithm");