diff --git a/Detectors/TPC/base/include/TPCBase/CDBTypes.h b/Detectors/TPC/base/include/TPCBase/CDBTypes.h index 4e084d129ac79..bca041b9c8956 100644 --- a/Detectors/TPC/base/include/TPCBase/CDBTypes.h +++ b/Detectors/TPC/base/include/TPCBase/CDBTypes.h @@ -73,6 +73,7 @@ enum class CDBType { CalCorrMapRef, ///< Cluster correction reference map (static distortions) CalCorrMapMC, ///< Cluster correction map (high IR rate distortions) for MC CalCorrDerivMapMC, ///< Cluster correction reference map (static distortions) for MC + CalCorrMapVShape, ///< Cluster correction map for V-shape distortions /// CalCorrDerivMap, ///< Cluster correction map (derivative map) /// @@ -135,6 +136,7 @@ const std::unordered_map CDBTypeMap{ // correction maps {CDBType::CalCorrMap, "TPC/Calib/CorrectionMapV2"}, {CDBType::CalCorrMapRef, "TPC/Calib/CorrectionMapRefV2"}, + {CDBType::CalCorrMapVShape, "TPC/Calib/CorrectionMapVShapeV2"}, // correction maps for MC {CDBType::CalCorrMapMC, "TPC/Calib/CorrectionMapMCV2"}, {CDBType::CalCorrDerivMapMC, "TPC/Calib/CorrectionMapDerivativeMCV2"}, diff --git a/Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx b/Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx index 4e7fadcbd288d..988035397a229 100644 --- a/Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx +++ b/Detectors/TPC/calibration/src/CorrectionMapsLoader.cxx @@ -36,6 +36,9 @@ void CorrectionMapsLoader::updateVDrift(float vdriftCorr, float vdrifRef, float if (mCorrMapRef) { o2::tpc::TPCFastTransformHelperO2::instance()->updateCalibration(*mCorrMapRef, 0, vdriftCorr, vdrifRef, driftTimeOffset); } + if (mCorrMapVShape) { + o2::tpc::TPCFastTransformHelperO2::instance()->updateCalibration(*mCorrMapVShape, 0, vdriftCorr, vdrifRef, driftTimeOffset); + } } //________________________________________________________ @@ -57,10 +60,15 @@ void CorrectionMapsLoader::extractCCDBInputs(ProcessingContext& pc) } lumiObj = lumiPrev; } - setInstLumi(mInstLumiFactor * (mCTPLumiSource == 0 ? lumiObj.getLumi() : lumiObj.getLumiAlt())); + setInstLumi(mInstLumiFactor * (mCTPLumiSource == 0 ? lumiObj.getLumi() : lumiObj.getLumiAlt()), !getUseVShapeCorrection()); } else if (getLumiScaleType() == 2 && mInstLumiOverride <= 0.) { float tpcScaler = pc.inputs().get("tpcscaler"); - setInstLumi(mInstLumiFactor * tpcScaler); + setInstLumi(mInstLumiFactor * tpcScaler, !getUseVShapeCorrection()); + } + if (getUseVShapeCorrection()) { + float vshapescaler = pc.inputs().get("vshape"); + setVShapeScaler(vshapescaler); + pc.inputs().get("tpcCorrMapVShape"); } } @@ -87,6 +95,11 @@ void CorrectionMapsLoader::requestCCDBInputs(std::vector& inputs, std addInput(inputs, {"tpcscaler", o2::header::gDataOriginTPC, "TPCSCALER", 0, Lifetime::Timeframe}); } + if (gloOpts.enableVShapeCorrection) { + addInput(inputs, {"vshape", o2::header::gDataOriginTPC, "TPCVShapeScaler", 0, Lifetime::Timeframe}); + addInput(inputs, {"tpcCorrMapVShape", o2::header::gDataOriginTPC, "CorrMapVShape", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalCorrMapVShape), {}, 0)}); // load once + } + addInput(inputs, {"tpcCorrPar", "TPC", "CorrMapParam", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CorrMapParam), {}, 0)}); // load once addOptions(options); @@ -157,6 +170,13 @@ bool CorrectionMapsLoader::accountCCDBInputs(const ConcreteDataMatcher& matcher, setUpdatedMapRef(); return true; } + if (matcher == ConcreteDataMatcher("TPC", "CorrMapVShape", 0)) { + LOGP(info, "Loading V-shape corrections from CCDB"); + setCorrMapVShape((o2::gpu::TPCFastTransform*)obj); + mCorrMapVShape->rectifyAfterReadingFromFile(); + setUpdatedMapVShape(); + return true; + } if (matcher == ConcreteDataMatcher("TPC", "CorrMapParam", 0)) { const auto& par = o2::tpc::CorrMapParam::Instance(); mMeanLumiOverride = par.lumiMean; @@ -196,6 +216,8 @@ void CorrectionMapsLoader::init(o2::framework::InitContext& ic) break; } else if (route.matcher == InputSpec{"tpcscaler", o2::header::gDataOriginTPC, "TPCSCALER", 0, Lifetime::Timeframe}) { setLumiScaleType(2); + } else if (route.matcher == InputSpec{"vshape", o2::header::gDataOriginTPC, "TPCVShapeScaler", 0, Lifetime::Timeframe}) { + enableVShapeCorrection(true); } } } @@ -211,6 +233,8 @@ void CorrectionMapsLoader::copySettings(const CorrectionMapsLoader& src) setMeanLumiRefOverride(src.getMeanLumiRefOverride()); setInstLumiOverride(src.getInstLumiOverride()); setLumiScaleMode(src.getLumiScaleMode()); + enableVShapeCorrection(src.getUseVShapeCorrection()); + setVShapeScaler(src.getVShapeScaler(), false); mInstLumiFactor = src.mInstLumiFactor; mCTPLumiSource = src.mCTPLumiSource; mLumiScaleMode = src.mLumiScaleMode; diff --git a/Detectors/TPC/calibration/src/TPCVShapeScaler.cxx b/Detectors/TPC/calibration/src/TPCVShapeScaler.cxx index 66394b5dc3ceb..434718e4fef10 100644 --- a/Detectors/TPC/calibration/src/TPCVShapeScaler.cxx +++ b/Detectors/TPC/calibration/src/TPCVShapeScaler.cxx @@ -39,17 +39,17 @@ void TPCVShapeScaler::loadFromFile(const char* inpf, const char* name) setFromTree(*tree); } -void TPCVShapeScaler::setFromTree(TTree& TPCVShapeScalerTree) +void TPCVShapeScaler::setFromTree(TTree& tpcScalerTree) { TPCVShapeScaler* scalerTmp = this; - TPCVShapeScalerTree.SetBranchAddress("TPCVShapeScaler", &scalerTmp); - const int entries = TPCVShapeScalerTree.GetEntries(); + tpcScalerTree.SetBranchAddress("TPCVShapeScaler", &scalerTmp); + const int entries = tpcScalerTree.GetEntries(); if (entries > 0) { - TPCVShapeScalerTree.GetEntry(0); + tpcScalerTree.GetEntry(0); } else { LOGP(error, "TPCVShapeScaler not found in input file"); } - TPCVShapeScalerTree.SetBranchAddress("TPCVShapeScaler", nullptr); + tpcScalerTree.SetBranchAddress("TPCVShapeScaler", nullptr); } float TPCVShapeScaler::getScaler(const double timestamp) const @@ -72,11 +72,12 @@ float TPCVShapeScaler::getScaler(const double timestamp) const const double deltaTimeLow = std::abs(mScalerA[idx - 1].first - timestamp); const double deltaTimeUp = std::abs(mScalerA[idx].first - timestamp); + // TODO if both are OK do linear interpolation // return closes value if ((deltaTimeLow < deltaTimeUp) && checkDeltaTime(deltaTimeLow)) { return mScalerA[idx - 1].second; } else if (checkDeltaTime(deltaTimeUp)) { - return mScalerA[idx - 1].second; + return mScalerA[idx].second; } } diff --git a/Detectors/TPC/workflow/src/RecoWorkflow.cxx b/Detectors/TPC/workflow/src/RecoWorkflow.cxx index fd77845ff844b..610573d609e1b 100644 --- a/Detectors/TPC/workflow/src/RecoWorkflow.cxx +++ b/Detectors/TPC/workflow/src/RecoWorkflow.cxx @@ -446,6 +446,7 @@ framework::WorkflowSpec getWorkflow(CompletionPolicyData* policyData, std::vecto cfg.runTPCTracking = true; cfg.lumiScaleType = sclOpts.lumiType; cfg.lumiScaleMode = sclOpts.lumiMode; + cfg.enableVShape = sclOpts.enableVShapeCorrection; cfg.decompressTPC = decompressTPC; cfg.decompressTPCFromROOT = decompressTPC && inputType == InputType::CompClusters; cfg.caClusterer = caClusterer; diff --git a/Detectors/TPC/workflow/src/TPCScalerSpec.cxx b/Detectors/TPC/workflow/src/TPCScalerSpec.cxx index cceafb62400b5..0dd6dc6591595 100644 --- a/Detectors/TPC/workflow/src/TPCScalerSpec.cxx +++ b/Detectors/TPC/workflow/src/TPCScalerSpec.cxx @@ -41,6 +41,7 @@ class TPCScalerSpec : public Task { o2::base::GRPGeomHelper::instance().setRequest(mCCDBRequest); mIonDriftTimeMS = ic.options().get("ion-drift-time"); + mVShapeScalingFac = ic.options().get("v-shape-scaling-factor"); } void run(ProcessingContext& pc) final @@ -70,7 +71,9 @@ class TPCScalerSpec : public Task pc.outputs().snapshot(Output{header::gDataOriginTPC, "TPCSCALER"}, meanScaler); if (mEnableVShape) { - float vshapescaler = 123; + double tsMiddleTF = timestamp + o2::base::GRPGeomHelper::instance().getNHBFPerTF() / 2 * o2::constants::lhc::LHCOrbitMUS * 0.001; + float vshapescaler = mVShapeScalingFac * mVShapeTPCScaler.getScaler(tsMiddleTF); + LOGP(info, "Publishing TPC V-shape scaler: {} for timestamp {} firstTFOrbit: {}", vshapescaler, long(timestamp), firstTFOrbit); pc.outputs().snapshot(Output{header::gDataOriginTPC, "TPCVShapeScaler"}, vshapescaler); } } @@ -95,6 +98,7 @@ class TPCScalerSpec : public Task std::shared_ptr mCCDBRequest; ///< info for CCDB request const bool mEnableVShape{}; ///< enable v shape scalers float mIonDriftTimeMS{-1}; ///< ion drift time + float mVShapeScalingFac{0}; ///< scale v-shape scalers with this value TPCScaler mTPCScaler; ///< tpc scaler TPCVShapeScaler mVShapeTPCScaler; ///< TPC V-shape scalers }; @@ -108,7 +112,7 @@ o2::framework::DataProcessorSpec getTPCScalerSpec(bool enableVShape) } auto ccdbRequest = std::make_shared(true, // orbitResetTime - false, // GRPECS=true for nHBF per TF + enableVShape, // GRPECS=true for nHBF per TF false, // GRPLHCIF false, // GRPMagField false, // askMatLUT @@ -117,6 +121,9 @@ o2::framework::DataProcessorSpec getTPCScalerSpec(bool enableVShape) std::vector outputs; outputs.emplace_back(o2::header::gDataOriginTPC, "TPCSCALER", 0, Lifetime::Timeframe); + if (enableVShape) { + outputs.emplace_back(o2::header::gDataOriginTPC, "TPCVShapeScaler", 0, Lifetime::Timeframe); + } return DataProcessorSpec{ "tpc-scaler", @@ -124,7 +131,8 @@ o2::framework::DataProcessorSpec getTPCScalerSpec(bool enableVShape) outputs, AlgorithmSpec{adaptFromTask(ccdbRequest, enableVShape)}, Options{ - {"ion-drift-time", VariantType::Float, -1.f, {"Overwrite ion drift time if a value >0 is provided"}}}}; + {"ion-drift-time", VariantType::Float, -1.f, {"Overwrite ion drift time if a value >0 is provided"}}, + {"v-shape-scaling-factor", VariantType::Float, 1.f, {"Scale V-shape scaler with this value"}}}}; } } // namespace tpc diff --git a/Detectors/TPC/workflow/src/TPCTimeSeriesSpec.cxx b/Detectors/TPC/workflow/src/TPCTimeSeriesSpec.cxx index 4dfa67a7b826b..205234770bd28 100644 --- a/Detectors/TPC/workflow/src/TPCTimeSeriesSpec.cxx +++ b/Detectors/TPC/workflow/src/TPCTimeSeriesSpec.cxx @@ -1288,14 +1288,15 @@ class TPCTimeSeries : public Task void sendOutput(ProcessingContext& pc) { + const long timeMS = o2::base::GRPGeomHelper::instance().getOrbitResetTimeMS() + processing_helpers::getFirstTForbit(pc) * o2::constants::lhc::LHCOrbitMUS / 1000; + mBufferDCA.mTSTPC.setStartTime(timeMS); + mBufferDCA.mTSITSTPC.setStartTime(timeMS); + pc.outputs().snapshot(Output{header::gDataOriginTPC, getDataDescriptionTimeSeries()}, mBufferDCA); // in case of ROOT output also store the TFinfo in the TTree if (!mDisableWriter) { o2::dataformats::TFIDInfo tfinfo; o2::base::TFIDInfoHelper::fillTFIDInfo(pc, tfinfo); - const long timeMS = o2::base::GRPGeomHelper::instance().getOrbitResetTimeMS() + processing_helpers::getFirstTForbit(pc) * o2::constants::lhc::LHCOrbitMUS / 1000; - mBufferDCA.mTSTPC.setStartTime(timeMS); - mBufferDCA.mTSITSTPC.setStartTime(timeMS); pc.outputs().snapshot(Output{header::gDataOriginTPC, getDataDescriptionTPCTimeSeriesTFId()}, tfinfo); } } diff --git a/GPU/GPUTracking/DataTypes/GPUDataTypes.h b/GPU/GPUTracking/DataTypes/GPUDataTypes.h index c00796e3fd7df..c10bb612ef7c8 100644 --- a/GPU/GPUTracking/DataTypes/GPUDataTypes.h +++ b/GPU/GPUTracking/DataTypes/GPUDataTypes.h @@ -216,6 +216,7 @@ template