From bde133396b6941d5d16148c19ea74f77f4ec48f9 Mon Sep 17 00:00:00 2001 From: shahoian Date: Tue, 1 Jul 2025 16:53:39 +0200 Subject: [PATCH] Add/use in TPCFastTransform mean IDC data member on top of Lumi Nominally both IDC (setIDC(val)) and Lumi (setLumi(val)) info of the map should be filled at the creation time. Depending what is used for the corrections (accoding to --lumi-type value: 1 for CTP lumi or 2 for IDC scaler) the getLumi or getIDC will be used. For the old maps, where the mIDC is absent (i.e. default value -1 returned by getIDC()) but the Lumi was used to stored the IDC mean value, we check if getLumi() is below the threshold TPCCorrMap.CTP2IDCFallBackThreshold (by default set to 30). If this is a case, the getLumi() value will be used as IDC scale, otherwise a Fatal will be thrown. Note that the inverse check is not done: if CTP Lumi scaling is requested for the old map where getLumi returns IDC, a wrong scale will be accepted. --- .../include/TPCCalibration/CorrMapParam.h | 1 + .../TPCCalibration/CorrectionMapsLoader.h | 1 + .../src/CorrectdEdxDistortions.cxx | 4 +- .../calibration/src/CorrectionMapsLoader.cxx | 44 ++++++++++++++++--- .../TPCFastTransform.cxx | 35 ++++++++++++++- GPU/TPCFastTransformation/TPCFastTransform.h | 25 ++++++++++- 6 files changed, 98 insertions(+), 12 deletions(-) diff --git a/Detectors/TPC/calibration/include/TPCCalibration/CorrMapParam.h b/Detectors/TPC/calibration/include/TPCCalibration/CorrMapParam.h index 147e5587accbb..4ce0e642f4ea3 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/CorrMapParam.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/CorrMapParam.h @@ -29,6 +29,7 @@ struct CorrMapParam : public o2::conf::ConfigurableParamHelper { float lumiMean = 0.; // override TPC corr.map mean lumi (if > 0), disable corrections if < 0 float lumiMeanRef = 0.; // override TPC corr.mapRef mean lumi (if > 0)" float lumiInstFactor = 1.; // scaling to apply to instantaneous lumi from CTP (but not to IDC scaler) + float CTP2IDCFallBackThreshold = 30.; // if needed, interpret map->getLumi() as map->getIDC(), provided map->getLumi() is below this threshold int ctpLumiSource = 0; // CTP lumi source: 0 = LumiInfo.getLumi(), 1 = LumiInfo.getLumiAlt() O2ParamDef(CorrMapParam, "TPCCorrMap"); diff --git a/Detectors/TPC/calibration/include/TPCCalibration/CorrectionMapsLoader.h b/Detectors/TPC/calibration/include/TPCCalibration/CorrectionMapsLoader.h index 90dc84e618cec..41e3ed6d3dcd5 100644 --- a/Detectors/TPC/calibration/include/TPCCalibration/CorrectionMapsLoader.h +++ b/Detectors/TPC/calibration/include/TPCCalibration/CorrectionMapsLoader.h @@ -63,6 +63,7 @@ class CorrectionMapsLoader : public o2::gpu::CorrectionMapsHelper void init(o2::framework::InitContext& ic); void copySettings(const CorrectionMapsLoader& src); void updateInverse(); /// recalculate inverse correction + float getMapMeanRate(const o2::gpu::TPCFastTransform* mp, bool lumiOverridden) const; static void requestCCDBInputs(std::vector& inputs, std::vector& options, const CorrectionMapsLoaderGloOpts& gloOpts); static void addGlobalOptions(std::vector& options); diff --git a/Detectors/TPC/calibration/src/CorrectdEdxDistortions.cxx b/Detectors/TPC/calibration/src/CorrectdEdxDistortions.cxx index e5d1f32ad5661..73599e744483c 100644 --- a/Detectors/TPC/calibration/src/CorrectdEdxDistortions.cxx +++ b/Detectors/TPC/calibration/src/CorrectdEdxDistortions.cxx @@ -70,8 +70,8 @@ void o2::tpc::CorrectdEdxDistortions::setLumi(float lumi) LOGP(warn, "Nullptr detected in accessing the correction maps"); return; } - const float lumiAvg = mCorrAvg->getLumi(); - const float lumiDer = mCorrDer->getLumi(); + const float lumiAvg = mCorrAvg->getIDC(); + const float lumiDer = mCorrDer->getIDC(); mScaleDer = (lumi - lumiAvg) / lumiDer; LOGP(info, "Setting mScaleDer: {} for inst lumi: {} avg lumi: {} deriv. lumi: {}", mScaleDer, lumi, lumiAvg, lumiDer); } diff --git a/Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx b/Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx index e13f887cbdc21..d1e1f60d4b801 100644 --- a/Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx +++ b/Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx @@ -176,20 +176,52 @@ bool CorrectionMapsLoader::accountCCDBInputs(const ConcreteDataMatcher& matcher, if (matcher == ConcreteDataMatcher("TPC", "CorrMap", 0)) { setCorrMap((o2::gpu::TPCFastTransform*)obj); mCorrMap->rectifyAfterReadingFromFile(); - if (getMeanLumiOverride() == 0 && mCorrMap->getLumi() > 0.) { - setMeanLumi(mCorrMap->getLumi(), false); + mCorrMap->setCTP2IDCFallBackThreshold(o2::tpc::CorrMapParam::Instance().CTP2IDCFallBackThreshold); + if (getMeanLumiOverride() != 0) { + if (getLumiScaleType() == 1) { + mCorrMap->setLumi(getMeanLumiOverride()); + LOGP(info, "CorrMap mean lumi rate is overridden to {}", mCorrMap->getLumi()); + } else if (getLumiScaleType() == 2) { + mCorrMap->setIDC(getMeanLumiOverride()); + LOGP(info, "CorrMap mean IDC rate is overridden to {}", mCorrMap->getIDC()); + } + } + float mapMeanRate = 0; + if (getLumiScaleType() == 1) { + mapMeanRate = mCorrMap->getLumi(); + } else if (getLumiScaleType() == 2) { + mapMeanRate = mCorrMap->getIDC(); + } + if (getMeanLumiOverride() == 0 && mapMeanRate > 0.) { + setMeanLumi(mapMeanRate, false); } - LOGP(debug, "MeanLumiOverride={} MeanLumiMap={} -> meanLumi = {}", getMeanLumiOverride(), mCorrMap->getLumi(), getMeanLumi()); + LOGP(debug, "MeanLumiOverride={} MeanLumiMap={} -> meanLumi = {}", getMeanLumiOverride(), mapMeanRate, getMeanLumi()); setUpdatedMap(); return true; } if (matcher == ConcreteDataMatcher("TPC", "CorrMapRef", 0)) { setCorrMapRef((o2::gpu::TPCFastTransform*)obj); mCorrMapRef->rectifyAfterReadingFromFile(); + mCorrMapRef->setCTP2IDCFallBackThreshold(o2::tpc::CorrMapParam::Instance().CTP2IDCFallBackThreshold); + if (getMeanLumiRefOverride() != 0) { + if (getLumiScaleType() == 1) { + mCorrMapRef->setLumi(getMeanLumiRefOverride()); + LOGP(info, "CorrMapRef mean lumi rate is overridden to {}", mCorrMapRef->getLumi()); + } else if (getLumiScaleType() == 2) { + mCorrMapRef->setIDC(getMeanLumiRefOverride()); + LOGP(info, "CorrMapRef mean IDC rate is overridden to {}", mCorrMapRef->getIDC()); + } + } + float mapRefMeanRate = 0; + if (getLumiScaleType() == 1) { + mapRefMeanRate = mCorrMapRef->getLumi(); + } else if (getLumiScaleType() == 2) { + mapRefMeanRate = mCorrMapRef->getIDC(); + } if (getMeanLumiRefOverride() == 0) { - setMeanLumiRef(mCorrMapRef->getLumi()); + setMeanLumiRef(mapRefMeanRate); } - LOGP(debug, "MeanLumiRefOverride={} MeanLumiMap={} -> meanLumi = {}", getMeanLumiRefOverride(), mCorrMapRef->getLumi(), getMeanLumiRef()); + LOGP(debug, "MeanLumiRefOverride={} MeanLumiMap={} -> meanLumi = {}", getMeanLumiRefOverride(), mapRefMeanRate, getMeanLumiRef()); setUpdatedMapRef(); return true; } @@ -217,7 +249,7 @@ bool CorrectionMapsLoader::accountCCDBInputs(const ConcreteDataMatcher& matcher, int scaleType = getLumiScaleType(); const std::array lumiS{"OFF", "CTP", "TPC scaler"}; if (scaleType >= lumiS.size()) { - LOGP(fatal, "Wrong lumi-scale-type provided!"); + LOGP(fatal, "Wrong corrmap-lumi-mode provided!"); } LOGP(info, "TPC correction map params updated: SP corrections: {} (corr.map scaling type={}, override values: lumiMean={} lumiRefMean={} lumiScaleMode={}), CTP Lumi: source={} lumiInstOverride={} , LumiInst scale={} ", diff --git a/GPU/TPCFastTransformation/TPCFastTransform.cxx b/GPU/TPCFastTransformation/TPCFastTransform.cxx index aea6589761403..bd29a760615ad 100644 --- a/GPU/TPCFastTransformation/TPCFastTransform.cxx +++ b/GPU/TPCFastTransformation/TPCFastTransform.cxx @@ -37,7 +37,7 @@ using namespace o2::gpu; TPCFastTransform::TPCFastTransform() - : FlatObject(), mTimeStamp(0), mCorrection(), mApplyCorrection(1), mT0(0.f), mVdrift(0.f), mVdriftCorrY(0.f), mLdriftCorr(0.f), mTOFcorr(0.f), mPrimVtxZ(0.f), mLumi(0.f), mLumiError(0.f), mLumiScaleFactor(1.0f) + : FlatObject(), mTimeStamp(0), mCorrection(), mApplyCorrection(1), mT0(0.f), mVdrift(0.f), mVdriftCorrY(0.f), mLdriftCorr(0.f), mTOFcorr(0.f), mPrimVtxZ(0.f), mLumi(TPCFastTransform::DEFLUMI), mLumiError(0.f), mLumiScaleFactor(1.0f), mIDC(TPCFastTransform::DEFIDC), mIDCError(0.f), mCTP2IDCFallBackThreshold(30.f) { // Default Constructor: creates an empty uninitialized object } @@ -60,6 +60,9 @@ void TPCFastTransform::cloneFromObject(const TPCFastTransform& obj, char* newFla mPrimVtxZ = obj.mPrimVtxZ; mLumi = obj.mLumi; mLumiError = obj.mLumiError; + mIDC = obj.mIDC; + mIDCError = obj.mIDCError; + mCTP2IDCFallBackThreshold = obj.mCTP2IDCFallBackThreshold; mLumiScaleFactor = obj.mLumiScaleFactor; // variable-size data @@ -108,8 +111,11 @@ void TPCFastTransform::startConstruction(const TPCFastSpaceChargeCorrection& cor mLdriftCorr = 0.f; mTOFcorr = 0.f; mPrimVtxZ = 0.f; - mLumi = 0.f; + mLumi = DEFLUMI; mLumiError = 0.f; + mIDC = DEFIDC; + mIDCError = 0.f; + mCTP2IDCFallBackThreshold = 30.f; mLumiScaleFactor = 1.f; // variable-size data @@ -160,6 +166,9 @@ void TPCFastTransform::print() const LOG(info) << "mPrimVtxZ = " << mPrimVtxZ; LOG(info) << "mLumi = " << mLumi; LOG(info) << "mLumiError = " << mLumiError; + LOG(info) << "mIDC = " << mIDC; + LOG(info) << "mIDCError = " << mIDCError; + LOG(info) << "mCTP2IDCFallBackThreshold = " << mCTP2IDCFallBackThreshold; LOG(info) << "mLumiScaleFactor = " << mLumiScaleFactor; mCorrection.print(); #endif @@ -251,3 +260,25 @@ void TPCFastTransform::setSlowTPCSCCorrection(TFile& inpf) mCorrectionSlow->mCorr->setGlobalCorrectionsFromFile(inpf, o2::tpc::Side::C); } #endif + +float TPCFastTransform::getIDC() const +{ + auto val = mIDC; + if (!isIDCSet()) { + if (mLumi < mCTP2IDCFallBackThreshold) { +#if !defined(GPUCA_GPUCODE) + bool static report = true; + if (report) { + report = false; + LOG(warn) << "IDC scaling is requested but map IDC record is empty. Since map Lumi " << mLumi << " is less than fall-back threshold " << mCTP2IDCFallBackThreshold << ", interpret Lumi record as IDC"; + } +#endif + val = mLumi; + } else { +#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) + LOG(fatal) << "IDC scaling is requested but map IDC record is empty. The map Lumi " << mLumi << " exceeds Lumi->IDC fall-back threshold " << mCTP2IDCFallBackThreshold; +#endif + } + } + return val; +} diff --git a/GPU/TPCFastTransformation/TPCFastTransform.h b/GPU/TPCFastTransformation/TPCFastTransform.h index 4e0403422ee06..14cd892b2554a 100644 --- a/GPU/TPCFastTransformation/TPCFastTransform.h +++ b/GPU/TPCFastTransformation/TPCFastTransform.h @@ -96,6 +96,9 @@ struct TPCSlowSpaceChargeCorrection { class TPCFastTransform : public FlatObject { public: + static constexpr float DEFLUMI = -1e6f; // default value to check if member was set + static constexpr float DEFIDC = -1e6f; // default value to check if member was set + /// _____________ Constructors / destructors __________________________ /// Default constructor: creates an empty uninitialized object @@ -162,7 +165,9 @@ class TPCFastTransform : public FlatObject void setLumi(float l) { mLumi = l; } void setLumiError(float e) { mLumiError = e; } void setLumiScaleFactor(float s) { mLumiScaleFactor = s; } - + void setIDC(float l) { mIDC = l; } + void setIDCError(float e) { mIDCError = e; } + void setCTP2IDCFallBackThreshold(float v) { mCTP2IDCFallBackThreshold = v; } /// Sets the time stamp of the current calibaration void setTimeStamp(int64_t v) { mTimeStamp = v; } @@ -251,9 +256,21 @@ class TPCFastTransform : public FlatObject /// Return map lumi GPUd() float getLumi() const { return mLumi; } + GPUd() float isLumiSet() const { return mLumi != DEFLUMI; } + /// Return map lumi error GPUd() float getLumiError() const { return mLumiError; } + /// Return map lumi + GPUd() float getIDC() const; + + GPUd() bool isIDCSet() const { return mIDC != DEFIDC; } + + /// Return map lumi error + GPUd() float getIDCError() const { return mIDCError; } + + GPUd() float getCTP2IDCFallBackThreshold() const { return mCTP2IDCFallBackThreshold; } + /// Return map user defined lumi scale factor GPUd() float getLumiScaleFactor() const { return mLumiScaleFactor; } @@ -334,12 +351,16 @@ class TPCFastTransform : public FlatObject float mLumiError; ///< error on luminosity float mLumiScaleFactor; ///< user correction factor for lumi (e.g. normalization, efficiency correction etc.) + float mIDC; ///< IDC estimator + float mIDCError; ///< error on IDC + float mCTP2IDCFallBackThreshold; ///< if IDC is not set but requested, use Lumi if it does not exceed this threshold + /// Correction of (x,u,v) with tricubic interpolator on a regular grid TPCSlowSpaceChargeCorrection* mCorrectionSlow{nullptr}; ///< reference space charge corrections GPUd() void TransformInternal(int32_t slice, int32_t row, float& u, float& v, float& x, const TPCFastTransform* ref, const TPCFastTransform* ref2, float scale, float scale2, int32_t scaleMode) const; - ClassDefNV(TPCFastTransform, 3); + ClassDefNV(TPCFastTransform, 4); }; // =======================================================================