9 #include <ecl/calibration/eclBhabhaTAlgorithm.h>
10 #include <ecl/dbobjects/ECLCrystalCalib.h>
11 #include <ecl/dbobjects/ECLReferenceCrystalPerCrateCalib.h>
12 #include <ecl/digitization/EclConfiguration.h>
13 #include <ecl/utility/ECLChannelMapper.h>
15 #include <framework/database/DBObjPtr.h>
16 #include <framework/database/DBStore.h>
17 #include <framework/datastore/StoreObjPtr.h>
18 #include <framework/datastore/DataStore.h>
19 #include <framework/dataobjects/EventMetaData.h>
30 eclBhabhaTAlgorithm::eclBhabhaTAlgorithm():
35 meanCleanRebinFactor(1),
36 meanCleanCutMinFactor(0),
39 savePrevCrysPayload(false),
40 readPrevCrysPayload(false),
42 debugFilenameBase(
"eclBhabhaTAlgorithm"),
43 collectorName(
"ECLBhabhaTCollector"),
44 refCrysPerCrate{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
45 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
46 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
47 -1, -1, -1, -1, -1, -1, -1}
49 setDescription(
"Calculate time offsets from bhabha events by fitting gaussian function to the (t - T0) difference.");
61 B2INFO(
"eclBhabhaTAlgorithm parameters:");
70 B2INFO(
"refCrysPerCrate = {");
71 for (
int crateTest = 0; crateTest < 52 - 1; crateTest++) {
79 auto TimevsCrysPrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibPrevCrystCalib");
80 auto TimevsCratePrevCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCratePrevCrateCalibPrevCrystCalib");
81 auto TimevsCrysNoCalibrations = getObjectPtr<TH2F>(
"TimevsCrysNoCalibrations");
82 auto TimevsCrysPrevCrateCalibNoCrystCalib = getObjectPtr<TH2F>(
"TimevsCrysPrevCrateCalibNoCrystCalib");
83 auto TimevsCrateNoCrateCalibPrevCrystCalib = getObjectPtr<TH2F>(
"TimevsCrateNoCrateCalibPrevCrystCalib");
86 auto cutflow = getObjectPtr<TH1F>(
"cutflow");
91 unique_ptr<TH1F> tsNew_MINUS_tsOld__cid(
new TH1F(
"TsNew_MINUS_TsOld__cid",
92 ";cell id; ts(new|bhabha) - ts(previous iteration|merged) [ns]", 8736,
94 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld__crateID(
new TH1F(
"tcrateNew_MINUS_tcrateOld__crateID",
95 ";crate id; tcrate(new | bhabha) - tcrate(previous iteration | merged) [ns]",
97 unique_ptr<TH1F> tsNew_MINUS_tsCustomPrev__cid(
new TH1F(
"TsNew_MINUS_TsCustomPrev__cid",
98 ";cell id; ts(new|bhabha) - ts(old = 'before 1st iter'|merged) [ns]",
100 unique_ptr<TH1F> tsNew_MINUS_tsOldBhabha__cid(
new TH1F(
"TsNew_MINUS_TsOldBhabha__cid",
101 ";cell id; ts(new|bhabha) - ts(previous iteration|bhabha) [ns]", 8736,
106 unique_ptr<TH1F> tsNew_MINUS_tsOld(
new TH1F(
"TsNew_MINUS_TsOld",
107 ";ts(new | bhabha) - ts(previous iteration | merged) [ns];Number of crystals",
108 201, -10.05, 10.05));
109 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld(
new TH1F(
"tcrateNew_MINUS_tcrateOld",
110 ";tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
111 201, -10.05, 10.05));
112 unique_ptr<TH1F> tsNew_MINUS_tsCustomPrev(
new TH1F(
"TsNew_MINUS_TsCustomPrev",
113 ";ts(new | bhabha) - ts(old = 'before 1st iter' | merged) [ns];Number of crystals",
114 285, -69.5801, 69.5801));
115 unique_ptr<TH1F> tsNew_MINUS_tsOldBhabha(
new TH1F(
"TsNew_MINUS_TsOldBhabha",
116 ";ts(new | bhabha) - ts(previous iteration | bhabha) [ns];Number of crystals",
117 201, -10.05, 10.05));
122 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld_allRuns(
new TH1F(
"tcrateNew_MINUS_tcrateOld_allRuns",
123 "Crate time constant changes over all runs : tcrate(new) uncertainty < 0.1ns;tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
124 201, -10.05, 10.05));
126 unique_ptr<TH1F> tcrateNew_MINUS_tcrateOld_allRuns_allCrates(
new TH1F(
"tcrateNew_MINUS_tcrateOld_allRuns_allCrates",
127 "Crate time constant changes over all runs : all crates;tcrate(new) - tcrate(previous iteration) [ns];Number of crates",
128 201, -10.05, 10.05));
130 unique_ptr<TH1I> num_tcrates_perRun(
new TH1I(
"num_tcrates_perRun",
131 "Number of good tcrates in each run;Run number;Number of good tcrates",
134 unique_ptr<TH2F> tcrateNew_MINUS_tcrateOld__vs__runNum(
new TH2F(
"tcrateNew_MINUS_tcrateOld__vs__runNum",
135 "Crate time constant changes vs run number : tcrate(new) uncertainty < 0.1ns;Run number;tcrate(new) - tcrate(previous iteration) [ns]",
136 6000, 0, 6000, 21, -10.5, 10.5));
142 if (!TimevsCrysNoCalibrations)
return c_Failure;
147 TFile* histExtraCrateInfofile = 0;
150 unique_ptr<TTree> tree_crystal(
new TTree(
"tree_crystal",
"Debug data from bhabha time calibration algorithm for crystals"));
152 unique_ptr<TTree> tree_crate(
new TTree(
"tree_crate",
"Debug data from bhabha time calibration algorithm for crates"));
156 vector<float> t_offsets;
158 vector<float> t_offsets_unc;
159 vector<float> t_offsets_prev;
162 int minNumEntries = 40;
163 int minNumEntriesCrateConvergence = 1000;
169 int crystalCalibSaved = 0;
173 bool minRunNumBool =
false;
174 bool maxRunNumBool =
false;
180 int expNumber = expRun.first;
181 int runNumber = expRun.second;
182 if (!minRunNumBool) {
183 minExpNum = expNumber;
184 minRunNum = runNumber;
185 minRunNumBool =
true;
187 if (!maxRunNumBool) {
188 maxExpNum = expNumber;
189 maxRunNum = runNumber;
190 maxRunNumBool =
true;
192 if (((minRunNum > runNumber) && (minExpNum >= expNumber)) ||
193 (minExpNum > expNumber)) {
194 minExpNum = expNumber;
195 minRunNum = runNumber;
197 if (((maxRunNum < runNumber) && (maxExpNum <= expNumber)) ||
198 (maxExpNum < expNumber))
201 maxExpNum = expNumber;
202 maxRunNum = runNumber;
207 string runNumsString = string(
"_") + to_string(minExpNum) +
"_" + to_string(minRunNum) + string(
"-") +
208 to_string(maxExpNum) +
"_" + to_string(maxRunNum);
210 string extraCratedebugFilename =
debugFilenameBase + string(
"_cratesAllRuns.root");
217 int eventNumberForCrates = 1;
225 evtPtr.
construct(eventNumberForCrates, minRunNum, minExpNum);
234 B2INFO(
"Uploading payload for exp " << minExpNum <<
", run " << minRunNum <<
", event " << eventNumberForCrates);
237 crystalMapper->initFromDB();
242 B2INFO(
"Reading payloads: ECLCrystalTimeOffset and ECLCrateTimeOffset");
247 vector<float> currentValuesCrys = crystalTimeObject->
getCalibVector();
249 vector<float> currentValuesCrate = crateTimeObject->
getCalibVector();
253 B2INFO(
"Values read from database. Write out for their values for comparison against those from tcol");
254 for (
int ic = 0; ic < 8736; ic += 500) {
255 B2INFO(
"ts: cellID " << ic + 1 <<
" " << currentValuesCrys[ic] <<
" +/- " << currentUncCrys[ic]);
256 B2INFO(
"tcrate: cellID " << ic + 1 <<
" " << currentValuesCrate[ic] <<
" +/- " << currentUncCrate[ic]);
261 vector<float> prevValuesCrys(8736);
268 B2INFO(
"Previous values read from database. Write out for their values for comparison against those from tcol");
269 for (
int ic = 0; ic < 8736; ic += 500) {
270 B2INFO(
"ts custom previous payload: cellID " << ic + 1 <<
" " << prevValuesCrys[ic]);
276 B2INFO(
"Reading payloads: ECLCrystalTimeOffsetBhabha");
280 vector<float> currentBhabhaValuesCrys = crystalBhabhaTimeObject->
getCalibVector();
281 vector<float> currentBhabhaUncCrys = crystalBhabhaTimeObject->
getCalibUncVector();
284 for (
int ic = 0; ic < 8736; ic += 500) {
285 B2INFO(
"ts bhabha: cellID " << ic + 1 <<
" " << currentBhabhaValuesCrys[ic] <<
" +/- " << currentBhabhaUncCrys[ic]);
291 auto refCrysIDzeroingCrate = getObjectPtr<TH1F>(
"refCrysIDzeroingCrate");
295 B2INFO(
"Extract reference crystals from collector histogram.");
296 vector <short> crystalIDreferenceUntested;
297 for (
int bin = 1; bin <= 8736; bin++) {
298 if (refCrysIDzeroingCrate->GetBinContent(bin) > 0.5) {
299 crystalIDreferenceUntested.push_back(bin);
305 B2INFO(
"Reference crystals to define as having ts=0. Base 1 counting for both crates and crystals");
306 for (
long unsigned int crysRefCounter = 0; crysRefCounter < crystalIDreferenceUntested.size(); crysRefCounter++) {
307 int crys_id = crystalIDreferenceUntested[crysRefCounter] ;
308 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
309 B2INFO(
" crystal " << crys_id <<
" is a reference for crate " << crate_id_from_crystal);
315 B2INFO(
"Checking number of reference crystals");
316 B2INFO(
"Number of reference crystals = " << crystalIDreferenceUntested.size());
319 if (crystalIDreferenceUntested.size() != 52) {
320 B2FATAL(
"The number of reference crystals does not equal 52, which is one per crate");
323 B2INFO(
"Number of reference crystals is 52 as required");
329 vector <short> crateIDsNumRefCrystalsUntested(52, 0);
330 vector <short> crystalIDReferenceForZeroTs(52, 0);
332 for (
long unsigned int crysRefCounter = 0; crysRefCounter < crystalIDreferenceUntested.size(); crysRefCounter++) {
333 int crys_id = crystalIDreferenceUntested[crysRefCounter] ;
334 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
335 crateIDsNumRefCrystalsUntested[crate_id_from_crystal - 1]++;
336 crystalIDReferenceForZeroTs[crate_id_from_crystal - 1] = crys_id;
338 B2INFO(
"crystalIDReferenceForZeroTs = {");
339 for (
int crateTest = 0; crateTest < 52 - 1; crateTest++) {
340 B2INFO(crystalIDReferenceForZeroTs[crateTest] <<
",");
342 B2INFO(crystalIDReferenceForZeroTs[52 - 1] <<
"}");
346 for (
int crateTest = 0; crateTest < 52; crateTest++) {
347 if (crateIDsNumRefCrystalsUntested[crateTest] != 1) {
348 B2FATAL(
"Crate " << crateTest + 1 <<
" (base 1) has " << crateIDsNumRefCrystalsUntested[crateTest] <<
" reference crystals");
352 B2INFO(
"All reference crystals are reasonably mapped one crystal to one crate for all crates");
356 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.");
362 bool userSetRefCrysPerCrate = false ;
363 for (
int crateTest = 0; crateTest < 52; crateTest++) {
366 B2INFO(
"Crate " << crateTest + 1 <<
" (base 1) new reference crystal = " << crystalIDReferenceForZeroTs[crateTest]);
367 userSetRefCrysPerCrate = true ;
370 if (userSetRefCrysPerCrate) {
371 B2INFO(
"User changed reference crystals via steering script");
374 fill(crateIDsNumRefCrystalsUntested.begin(), crateIDsNumRefCrystalsUntested.end(), 0);
375 for (
long unsigned int crysRefCounter = 0; crysRefCounter < 52; crysRefCounter++) {
376 int crys_id = crystalIDReferenceForZeroTs[crysRefCounter] ;
377 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
378 crateIDsNumRefCrystalsUntested[crate_id_from_crystal - 1]++;
380 for (
int crateTest = 0; crateTest < 52; crateTest++) {
381 if (crateIDsNumRefCrystalsUntested[crateTest] != 1) {
382 B2FATAL(
"Crate " << crateTest + 1 <<
" (base 1) has " << crateIDsNumRefCrystalsUntested[crateTest] <<
" reference crystals");
386 B2INFO(
"All reference crystals are reasonably mapped one crystal to one crate for all crates after changes made by user steering script.");
393 B2INFO(
"Created reference crystal per crate payload: ECLReferenceCrystalPerCrateCalib");
395 B2INFO(
"User did not change reference crystals via steering script");
402 B2INFO(
"Debug output rootfile: " << debugFilename);
403 histfile =
new TFile(debugFilename.c_str(),
"recreate");
406 TimevsCrysPrevCrateCalibPrevCrystCalib ->Write();
407 TimevsCratePrevCrateCalibPrevCrystCalib->Write();
408 TimevsCrysNoCalibrations ->Write();
409 TimevsCrysPrevCrateCalibNoCrystCalib ->Write();
410 TimevsCrateNoCrateCalibPrevCrystCalib ->Write();
416 tree_crystal->Branch(
"cid", &tree_cid)->SetTitle(
"Cell ID, 1..8736");
417 tree_crystal->Branch(
"ts", &mean)->SetTitle(
"Time offset mean, ts, ns");
418 tree_crystal->Branch(
"tsUnc", &mean_unc)->SetTitle(
"Error of time ts mean, ns.");
419 tree_crystal->Branch(
"tsSigma", &sigma)->SetTitle(
"Sigma of time ts distribution, ns");
420 tree_crystal->Branch(
"crystalCalibSaved",
421 &crystalCalibSaved)->SetTitle(
"0=crystal skipped, 1=crystal calib saved (num entries based)");
422 tree_crystal->Branch(
"tsPrev", &tsPrev)->SetTitle(
"Previous crystal time offset, ts, ns");
423 tree_crystal->SetAutoSave(10);
427 double hist_tmin = TimevsCrysNoCalibrations->GetYaxis()->GetXmin();
428 double hist_tmax = TimevsCrysNoCalibrations->GetYaxis()->GetXmax();
430 double time_fit_min = hist_tmax;
431 double time_fit_max = hist_tmin;
433 B2INFO(
"hist_tmin = " << hist_tmin);
434 B2INFO(
"hist_tmax = " << hist_tmax);
442 auto databaseCounter = getObjectPtr<TH1I>(
"databaseCounter");
443 float numTimesFilled = databaseCounter->GetBinContent(1);
444 B2INFO(
"Number of times database histograms were merged = " << numTimesFilled);
447 auto TsDatabase = getObjectPtr<TH1F>(
"TsDatabase");
448 auto TsDatabaseUnc = getObjectPtr<TH1F>(
"TsDatabaseUnc");
449 for (
int i = 1; i <= 8736; i++) {
450 t_offsets.push_back(TsDatabase->GetBinContent(i) / numTimesFilled);
451 t_offsets_prev.push_back(TsDatabase->GetBinContent(i) / numTimesFilled);
453 B2INFO(
"t_offsets_prev (last iter) at crysID " << i <<
" = " << t_offsets_prev[i - 1]);
455 t_offsets_unc.push_back(TsDatabaseUnc->GetBinContent(i) / numTimesFilled);
463 TH1D* h_crysHits = TimevsCrysPrevCrateCalibNoCrystCalib->ProjectionX(
"h_crysHits");
464 h_crysHits->SetTitle(
"Hits per crystal;Crystal id");
466 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");
804 vector<float> tcrate_mean_new(52, 0.0);
805 vector<float> tcrate_mean_unc_new(52, 0.0);
806 vector<float> tcrate_sigma_new(52, 0.0);
807 vector<float> tcrate_mean_prev(52, 0.0);
809 vector<bool> tcrate_new_was_set(52,
false);
810 vector<bool> tcrate_new_goodQuality(52,
false);
812 B2DEBUG(22,
"crate vectors set");
818 for (
int crys_id = 1; crys_id <= 8736; crys_id++) {
819 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
820 tcrate_mean_prev[crate_id_from_crystal - 1] = TcrateDatabase->GetBinContent(crys_id) / numTimesFilled;
824 B2INFO(
"Print out previous crate time calibration constants to make sure they match from the two different sources.");
825 for (
int crate_id = 1; crate_id <= 52; crate_id++) {
826 B2INFO(
"tcrate_mean_prev[crate " << crate_id <<
" (base 1)] = " << tcrate_mean_prev[crate_id - 1]);
828 int thisRefCellID = crystalIDReferenceForZeroTs[crate_id - 1];
829 B2INFO(
"tcrate from payload: ref cellID " << thisRefCellID <<
" " << currentValuesCrate[thisRefCellID - 1] <<
" +/- " <<
830 currentUncCrate[thisRefCellID - 1]);
837 TFile* histExtraCrateInfofile_dummy = 0;
838 B2INFO(
"Debug output rootfile used for crate iterations: " << extraCratedebugFilename);
839 histExtraCrateInfofile_dummy =
new TFile(extraCratedebugFilename.c_str(),
"UPDATE");
843 TKey* key = histExtraCrateInfofile_dummy->FindKey(
"tcrateNew_MINUS_tcrateOld_allRuns");
845 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"tcrateNew_MINUS_tcrateOld_allRuns");
846 tcrateNew_MINUS_tcrateOld_allRuns->Add(h);
849 key = histExtraCrateInfofile_dummy->FindKey(
"tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
851 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
852 tcrateNew_MINUS_tcrateOld_allRuns_allCrates->Add(h);
855 key = histExtraCrateInfofile_dummy->FindKey(
"num_tcrates_perRun");
857 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"num_tcrates_perRun");
858 num_tcrates_perRun->Add(h);
861 key = histExtraCrateInfofile_dummy->FindKey(
"tcrateNew_MINUS_tcrateOld__vs__runNum");
863 TH1F* h = (TH1F*)histExtraCrateInfofile_dummy->Get(
"tcrateNew_MINUS_tcrateOld__vs__runNum");
864 tcrateNew_MINUS_tcrateOld__vs__runNum->Add(h);
867 histExtraCrateInfofile_dummy->Close();
871 histExtraCrateInfofile =
new TFile(extraCratedebugFilename.c_str(),
"recreate");
878 B2DEBUG(22,
"Start of crate id = " << crate_id);
880 TH1D* h_time_crate = TimevsCrateNoCrateCalibPrevCrystCalib->ProjectionY(
"h_time_psi_crate", crate_id, crate_id);
881 TH1D* h_time_crate_mask = (TH1D*)h_time_crate->Clone();
882 TH1D* h_time_crate_masked = (TH1D*)h_time_crate->Clone();
883 TH1D* h_time_crate_rebin = (TH1D*)h_time_crate->Clone();
890 h_time_crate_mask->Scale(0.0);
892 time_fit_min = hist_tmax;
893 time_fit_max = hist_tmin;
896 double histRebin_max = h_time_crate_rebin->GetMaximum();
898 bool maskedOutNonZeroBin =
false;
900 for (
int bin = 1; bin <= h_time_crate_rebin->GetNbinsX(); bin++) {
903 if (nonRebinnedBinNumber < h_time_crate->GetNbinsX()) {
905 h_time_crate_mask->SetBinContent(nonRebinnedBinNumber, 1);
908 double x_lower = h_time_crate_rebin->GetXaxis()->GetBinLowEdge(bin);
909 double x_upper = h_time_crate_rebin->GetXaxis()->GetBinUpEdge(bin);
910 if (x_lower < time_fit_min) {
911 time_fit_min = x_lower;
913 if (x_upper > time_fit_max) {
914 time_fit_max = x_upper;
917 if (h_time_crate->GetBinContent(nonRebinnedBinNumber) > 0) {
918 B2DEBUG(22,
"Setting bin " << nonRebinnedBinNumber <<
" from " << h_time_crate_masked->GetBinContent(
919 nonRebinnedBinNumber) <<
" to 0");
920 maskedOutNonZeroBin =
true;
922 h_time_crate_masked->SetBinContent(nonRebinnedBinNumber, 0);
927 B2INFO(
"Bins with non-zero values have been masked out: " << maskedOutNonZeroBin);
928 h_time_crate_masked->ResetStats();
929 h_time_crate_mask->ResetStats();
935 B2DEBUG(22,
"crate loop - projected h_time_psi_crate");
938 double default_mean_crate = h_time_crate_masked->GetMean();
939 double default_mean_crate_unc = h_time_crate_masked->GetMeanError();
940 double default_sigma_crate = h_time_crate_masked->GetStdDev();
941 B2INFO(
"Fitting crate between " << time_fit_min <<
" and " << time_fit_max);
942 TF1* gaus =
new TF1(
"func",
"gaus(0)", time_fit_min, time_fit_max);
943 gaus->SetParNames(
"numCrateHisNormalization",
"mean",
"sigma");
944 double hist_max = h_time_crate->GetMaximum();
945 double stddev = h_time_crate->GetStdDev();
946 double sigma_crate = stddev;
947 double mean_crate = default_mean_crate;
948 gaus->SetParameter(0, hist_max / 2.);
949 gaus->SetParameter(1, mean_crate);
950 gaus->SetParameter(2, sigma_crate);
952 h_time_crate_masked->Fit(gaus,
"LQR");
954 double fit_mean_crate = gaus->GetParameter(1);
955 double fit_mean_crate_unc = gaus->GetParError(1);
956 double fit_sigma_crate = gaus->GetParameter(2);
958 double meanDiff = fit_mean_crate - default_mean_crate;
959 double meanUncDiff = fit_mean_crate_unc - default_mean_crate_unc;
960 double sigmaDiff = fit_sigma_crate - default_sigma_crate;
962 bool good_fit =
false;
964 B2DEBUG(22,
"Crate id = " << crate_id <<
" with crate mean = " << default_mean_crate <<
" +- " << fit_mean_crate_unc);
966 if ((fabs(meanDiff) > 7) ||
967 (fabs(meanUncDiff) > 7) ||
968 (fabs(sigmaDiff) > 7) ||
969 (fit_mean_crate_unc > 3) ||
970 (fit_sigma_crate < 0.1) ||
971 (fit_mean_crate < time_fit_min) ||
972 (fit_mean_crate > time_fit_max)) {
973 B2INFO(
"Crate id = " << crate_id);
974 B2INFO(
"fit mean, default mean = " << fit_mean_crate <<
", " << default_mean_crate);
975 B2INFO(
"fit sigma, default sigma = " << fit_sigma_crate <<
", " << default_sigma_crate);
977 B2INFO(
"crate fit mean - hist mean = " << meanDiff);
978 B2INFO(
"fit mean unc. - hist mean unc. = " << meanUncDiff);
979 B2INFO(
"fit sigma - hist sigma = " << sigmaDiff);
980 B2INFO(
"fit_mean_crate = " << fit_mean_crate);
981 B2INFO(
"time_fit_min = " << time_fit_min);
982 B2INFO(
"time_fit_max = " << time_fit_max);
987 int numEntries = h_time_crate->GetEntries();
988 B2INFO(
"Number entries = " << numEntries);
989 double database_mean_crate = 0;
990 double database_mean_crate_unc = 0;
991 if ((numEntries >= minNumEntries) && good_fit) {
992 database_mean_crate = fit_mean_crate;
993 database_mean_crate_unc = fit_mean_crate_unc;
995 if ((numEntries >= minNumEntriesCrateConvergence) && (fit_mean_crate_unc < 0.1)) {
996 tcrate_new_goodQuality[crate_id - 1] =
true;
999 database_mean_crate = default_mean_crate;
1000 database_mean_crate_unc = default_mean_crate_unc;
1002 if (numEntries == 0) {
1003 database_mean_crate = 0;
1004 database_mean_crate_unc = 0;
1007 tcrate_mean_new[crate_id - 1] = database_mean_crate;
1008 tcrate_mean_unc_new[crate_id - 1] = database_mean_crate_unc;
1009 tcrate_sigma_new[crate_id - 1] = fit_sigma_crate;
1010 tcrate_new_was_set[crate_id - 1] =
true;
1013 histfile->WriteTObject(h_time_crate, (
string(
"h_time_psi_crate") + to_string(crate_id)).c_str());
1014 histfile->WriteTObject(h_time_crate_masked, (
string(
"h_time_psi_crate_masked") + to_string(crate_id)).c_str());
1015 histfile->WriteTObject(h_time_crate_rebin, (
string(
"h_time_psi_crate_rebinned") + to_string(crate_id)).c_str());
1020 B2DEBUG(22,
"crate histograms made");
1025 vector<float> t_offsets_crate;
1027 vector<float> t_offsets_crate_unc;
1028 for (
int i = 1; i <= 8736; i++) {
1029 t_offsets_crate.push_back(0);
1030 t_offsets_crate_unc.push_back(0);
1034 for (
int crys_id = 1; crys_id <= 8736; crys_id++) {
1035 int crate_id_from_crystal = crystalMapper->getCrateID(crys_id);
1036 if (tcrate_new_was_set[crate_id_from_crystal - 1]) {
1037 t_offsets_crate[crys_id - 1] = tcrate_mean_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
1038 t_offsets_crate_unc[crys_id - 1] = tcrate_mean_unc_new[crate_id_from_crystal - 1] / TICKS_TO_NS;
1041 t_offsets_crate[crys_id - 1] = tcrate_mean_prev[crate_id_from_crystal - 1];
1042 B2INFO(
"used old crate mean but zeroed uncertainty since not saved in root file");
1051 double tCrateDiff_ns = tcrate_mean_new[crate_id - 1] - (tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS);
1052 B2INFO(
"Crate " << crate_id <<
": tcrate new - previous iteration = "
1053 << tcrate_mean_new[crate_id - 1]
1054 <<
" - " << tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS
1055 <<
" = " << tCrateDiff_ns <<
" ns");
1056 tcrateNew_MINUS_tcrateOld__crateID->SetBinContent(crate_id, tCrateDiff_ns);
1057 tcrateNew_MINUS_tcrateOld__crateID->SetBinError(crate_id, 0);
1058 tcrateNew_MINUS_tcrateOld__crateID->ResetStats();
1060 tcrateNew_MINUS_tcrateOld->Fill(tCrateDiff_ns);
1063 tcrateNew_MINUS_tcrateOld_allRuns_allCrates->Fill(tCrateDiff_ns);
1064 if (tcrate_new_goodQuality[crate_id - 1]) {
1065 tcrateNew_MINUS_tcrateOld_allRuns->Fill(tCrateDiff_ns);
1066 num_tcrates_perRun->Fill(minRunNum);
1067 tcrateNew_MINUS_tcrateOld__vs__runNum->Fill(minRunNum, tCrateDiff_ns);
1072 histfile->WriteTObject(tcrateNew_MINUS_tcrateOld__crateID.get(),
"tcrateNew_MINUS_tcrateOld__crateID");
1073 histfile->WriteTObject(tcrateNew_MINUS_tcrateOld.get(),
"tcrateNew_MINUS_tcrateOld");
1076 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld_allRuns.get(),
"tcrateNew_MINUS_tcrateOld_allRuns");
1077 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld_allRuns_allCrates.get(),
1078 "tcrateNew_MINUS_tcrateOld_allRuns_allCrates");
1079 histExtraCrateInfofile->WriteTObject(num_tcrates_perRun.get(),
"num_tcrates_perRun");
1080 histExtraCrateInfofile->WriteTObject(tcrateNew_MINUS_tcrateOld__vs__runNum.get(),
"tcrateNew_MINUS_tcrateOld__vs__runNum");
1085 BhabhaTCrateCalib->
setCalibVector(t_offsets_crate, t_offsets_crate_unc);
1092 B2DEBUG(22,
"crate payload made");
1094 histExtraCrateInfofile->Close();
1100 double tree_tcrate_mean;
1101 double tree_tcrate_mean_unc;
1102 double tree_tcrate_sigma;
1103 double tree_tcrate_meanPrev;
1105 tree_crate->Branch(
"runNum", &tree_runNum)->SetTitle(
"Run number, 0..infinity and beyond!");
1106 tree_crate->Branch(
"crateid", &tree_crateid)->SetTitle(
"Crate id, 1..52");
1107 tree_crate->Branch(
"tcrate", &tree_tcrate_mean)->SetTitle(
"Crate time offset mean, tcrate, ns");
1108 tree_crate->Branch(
"tcratePrev", &tree_tcrate_meanPrev)->SetTitle(
"Previous crate time offset mean, tcrate, ns");
1109 tree_crate->Branch(
"tcrate_unc", &tree_tcrate_mean_unc)->SetTitle(
"Error of time tcrate mean, ns.");
1110 tree_crate->Branch(
"tcrate_sigma", &tree_tcrate_sigma)->SetTitle(
"Sigma of time tcrate distribution, ns");
1111 tree_crate->SetAutoSave(10);
1116 B2INFO(
"run num, exp num: " << expRun.second <<
", " << expRun.first);
1117 int runNumber = expRun.second;
1119 for (
int crate_id = 1; crate_id <= 52; crate_id++) {
1120 if (tcrate_new_was_set[crate_id - 1]) {
1121 tree_runNum = runNumber;
1122 tree_crateid = crate_id;
1123 tree_tcrate_mean = tcrate_mean_new[crate_id - 1];
1124 tree_tcrate_mean_unc = tcrate_mean_unc_new[crate_id - 1];
1125 tree_tcrate_sigma = tcrate_sigma_new[crate_id - 1];
1126 tree_tcrate_meanPrev = tcrate_mean_prev[crate_id - 1] * TICKS_TO_NS;
1132 B2DEBUG(22,
"end of crate corrections .....");
1134 tree_crystal->Write();
1135 tree_crate->Write();
1139 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)
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
@ c_Failure
Failed =3 in Python.
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
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.
const std::vector< float > & getCalibUncVector() const
Get vector of uncertainties on calibration constants.
const std::vector< float > & getCalibVector() const
Get vector of calibration constants.
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 constexpr double m_rf
accelerating RF, http://ptep.oxfordjournals.org/content/2013/3/03A006.full.pdf
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.
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.
Abstract base class for different kinds of events.