From acb86e86ab61cd884054db36b6f5b029ab47c31d Mon Sep 17 00:00:00 2001 From: Joshua Koenig Date: Mon, 18 Mar 2024 14:29:25 +0100 Subject: [PATCH] [EMCAL-565, EMCAL-566]: Differentiate between run type and max time difference for loading of calib hists (#12848) - Online calibration relies on saving and loading the calibration histograms at the EOR (SOR) - However, the old objects should not be loaded if the run type (calib, physics etc.) differes, or if the time difference between the old object and the current data taking is too long - Now, the root file storing the objects is named differently, depending on the run type - The old timestamp (in hours) is stored in the file itself and then loaded at SOR and compared to the current ts - The fill Nr is stored in the file and an option is implemented to only load calibration objects if the fill is the same as for the old object - All parameters are configurable in the Calib Params Co-authored-by: jokonig --- .../EMCALCalibration/EMCALCalibParams.h | 5 +- .../EMCALCalibration/EMCALChannelCalibrator.h | 70 +++++++++++++++++-- .../testWorkflow/EMCALChannelCalibratorSpec.h | 22 ++++-- 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/Detectors/EMCAL/calibration/include/EMCALCalibration/EMCALCalibParams.h b/Detectors/EMCAL/calibration/include/EMCALCalibration/EMCALCalibParams.h index 93ddcce26a6f8..0e44e886d02f1 100644 --- a/Detectors/EMCAL/calibration/include/EMCALCalibration/EMCALCalibParams.h +++ b/Detectors/EMCAL/calibration/include/EMCALCalibration/EMCALCalibParams.h @@ -82,6 +82,9 @@ struct EMCALCalibParams : public o2::conf::ConfigurableParamHelper mCalibrator; // output @@ -249,6 +265,9 @@ bool EMCALChannelCalibrator::saveLastSlotData(TFile& fl) auto& slot = cont.at(0); DataInput* c = slot.getContainer(); + // timestamp in hours + int timeNow = static_cast(o2::ccdb::getCurrentTimestamp() / o2::ccdb::CcdbObjectInfo::HOUR); + if constexpr (std::is_same::value) { auto hist = c->getHisto(); auto histTime = c->getHistoTime(); @@ -257,20 +276,36 @@ bool EMCALChannelCalibrator::saveLastSlotData(TFile& fl) TH2F hTime = o2::utils::TH2FFromBoost(histTime, "histTime"); TH1D hNEvents("hNEvents", "hNEvents", 1, 0, 1); hNEvents.SetBinContent(1, c->getNEvents()); + TH1I hGlobalProperties("hGlobalProperties", "hGlobalProperties", 3, -0.5, 2.5); + hGlobalProperties.GetXaxis()->SetBinLabel(1, "Fill nr."); + hGlobalProperties.GetXaxis()->SetBinLabel(2, "run type"); + hGlobalProperties.GetXaxis()->SetBinLabel(2, "ts in hours"); + hGlobalProperties.SetBinContent(1, mFillNr); + hGlobalProperties.SetBinContent(2, mRunType); + hGlobalProperties.SetBinContent(3, timeNow); fl.cd(); hEnergy.Write("EnergyVsCellID"); hTime.Write("TimeVsCellID"); hNEvents.Write("NEvents"); + hGlobalProperties.Write("GlobalProperties"); } else if constexpr (std::is_same::value) { auto histTime = c->getHisto(); TH2F hTime = o2::utils::TH2FFromBoost(histTime); TH1D hNEvents("hNEvents", "hNEvents", 1, 0, 1); hNEvents.SetBinContent(1, c->getNEvents()); + TH1I hGlobalProperties("hGlobalProperties", "hGlobalProperties", 3, -0.5, 2.5); + hGlobalProperties.GetXaxis()->SetBinLabel(1, "Fill nr."); + hGlobalProperties.GetXaxis()->SetBinLabel(2, "run type"); + hGlobalProperties.GetXaxis()->SetBinLabel(2, "ts in hours"); + hGlobalProperties.SetBinContent(1, mFillNr); + hGlobalProperties.SetBinContent(2, mRunType); + hGlobalProperties.SetBinContent(3, timeNow); fl.cd(); hTime.Write("TimeVsCellID"); hNEvents.Write("NEvents"); + hGlobalProperties.Write("GlobalProperties"); } return true; @@ -296,6 +331,31 @@ bool EMCALChannelCalibrator::adoptSavedData(const o2::cal auto& slot = cont.at(0); DataInput* c = slot.getContainer(); + // check run type and fill + TH1I* hGlobalProperties = (TH1I*)fl.Get("GlobalProperties"); + if (!hGlobalProperties) { + LOG(error) << "GlobalProperties histogram not found. Will not load previous calibration histograms"; + } else { + int fillNr = hGlobalProperties->GetBinContent(1); + int runType = hGlobalProperties->GetBinContent(2); + int tsOld = hGlobalProperties->GetBinContent(3); + int tsDiff = (mStartTSCalib > 0 ? mStartTSCalib : static_cast(o2::ccdb::getCurrentTimestamp() / o2::ccdb::CcdbObjectInfo::HOUR)) - tsOld; // get current timestamp if mStartTSCalib is not set + LOG(debug) << "tsOld " << tsOld << " tsNow " << (mStartTSCalib > 0 ? mStartTSCalib : static_cast(o2::ccdb::getCurrentTimestamp() / o2::ccdb::CcdbObjectInfo::HOUR)) << " tsDiff " << tsDiff; + + if (EMCALCalibParams::Instance().requireSameRunType && runType != static_cast(mRunType)) { + LOG(info) << "adoptSavedData: Same run type required but run types differ: " << runType << " != " << static_cast(mRunType); + return false; + } + if (EMCALCalibParams::Instance().requireSameFill && fillNr != mFillNr) { + LOG(info) << "adoptSavedData: Same fill nr. required but fills differ: " << fillNr << " != " << mFillNr; + return false; + } + if (EMCALCalibParams::Instance().tsDiffMax > 0 && (EMCALCalibParams::Instance().tsDiffMax < tsDiff || tsDiff < 0)) { + LOG(info) << "adoptSavedData: Maximum difference in ts is: " << EMCALCalibParams::Instance().tsDiffMax << " but " << tsDiff << " is given"; + return false; + } + } + if constexpr (std::is_same::value) { TH2D* hEnergy = (TH2D*)fl.Get("EnergyVsCellID"); TH2D* hTime = (TH2D*)fl.Get("TimeVsCellID"); diff --git a/Detectors/EMCAL/calibration/testWorkflow/EMCALChannelCalibratorSpec.h b/Detectors/EMCAL/calibration/testWorkflow/EMCALChannelCalibratorSpec.h index a5402e9c1c913..e643baf3eb5c8 100644 --- a/Detectors/EMCAL/calibration/testWorkflow/EMCALChannelCalibratorSpec.h +++ b/Detectors/EMCAL/calibration/testWorkflow/EMCALChannelCalibratorSpec.h @@ -196,7 +196,9 @@ class EMCALChannelCalibDevice : public o2::framework::Task if (!mIsConfigured) { // configure calibrators (after calib params are loaded from the CCDB) - configureCalibrators(); + // long tsMS = o2::base::GRPGeomHelper::instance().getOrbitResetTimeMS() + pc.services().get().firstTForbit * o2::constants::lhc::LHCOrbitMUS / 1000; // this reads the ts from the data. + long tsMS = o2::ccdb::getCurrentTimestamp(); + configureCalibrators(tsMS); mIsConfigured = true; } @@ -415,14 +417,22 @@ class EMCALChannelCalibDevice : public o2::framework::Task } /// \brief Configure calibrators from the calib params - void configureCalibrators() + void configureCalibrators(long ts) { + auto currFill = o2::base::GRPGeomHelper::instance().getGRPLHCIF()->getFillNumber(); + auto runtype = o2::base::GRPGeomHelper::instance().getGRPECS()->getRunType(); + LOG(debug) << "currFill " << currFill << " runtype " << runtype; + if (mTimeCalibrator) { LOG(info) << "Configuring time calibrator"; mTimeCalibrator->setSlotLength(EMCALCalibParams::Instance().slotLength_tc); if (EMCALCalibParams::Instance().UpdateAtEndOfRunOnly_tc) { - mBadChannelCalibrator->setUpdateAtTheEndOfRunOnly(); + mTimeCalibrator->setUpdateAtTheEndOfRunOnly(); } + mTimeCalibrator->setSaveFileName("emc-time-calib-" + std::to_string(runtype) + ".root"); + mTimeCalibrator->setFillNr(currFill); + mTimeCalibrator->setRunType(runtype); + mTimeCalibrator->setCurrTSInHours(static_cast(ts / o2::ccdb::CcdbObjectInfo::HOUR)); } if (mBadChannelCalibrator) { LOG(info) << "Configuring bad channel calibrator"; @@ -431,6 +441,10 @@ class EMCALChannelCalibDevice : public o2::framework::Task mBadChannelCalibrator->setUpdateAtTheEndOfRunOnly(); } mBadChannelCalibrator->setIsTest(EMCALCalibParams::Instance().enableTestMode_bc); + mBadChannelCalibrator->setFillNr(currFill); + mBadChannelCalibrator->setRunType(runtype); + mBadChannelCalibrator->setSaveFileName("emc-channel-calib-" + std::to_string(runtype) + ".root"); + mBadChannelCalibrator->setCurrTSInHours(static_cast(ts / o2::ccdb::CcdbObjectInfo::HOUR)); } } }; // namespace calibration @@ -482,7 +496,7 @@ DataProcessorSpec getEMCALChannelCalibDeviceSpec(const std::string calibType, co auto ccdbRequest = std::make_shared(true, // orbitResetTime true, // GRPECS=true - false, // GRPLHCIF + true, // GRPLHCIF false, // GRPMagField false, // askMatLUT o2::base::GRPGeomRequest::None, // geometry