Skip to content

Commit 26d73c3

Browse files
committed
Add forward compatibility with the new propagation-service-v2
1 parent b968bd4 commit 26d73c3

4 files changed

Lines changed: 143 additions & 33 deletions

File tree

Common/Core/TPCVDriftManager.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,27 @@ class TPCVDriftManager
6363
LOGP(info, "Updated VDrift for timestamp {} with vdrift={:.7f} (cm/ns)", mVD->creationTime, mTPCVDriftNS);
6464
}
6565

66+
// Adopts a drift correction obtained elsewhere, typically straight from the
67+
// aod::TpcCalibCCDBObjects column, so no CCDB manager is involved at all.
68+
void update(const o2::tpc::VDriftCorrFact& vd) noexcept
69+
{
70+
if (mVD == &vd) { // same object as last time, nothing to recompute
71+
return;
72+
}
73+
if (vd.firstTime < 0 || vd.lastTime < 0) {
74+
LOGP(error, "Got invalid VDriftCorrFact created at {}", vd.creationTime);
75+
mValid = false;
76+
return;
77+
}
78+
mVD = &vd;
79+
80+
// TODO account for laser calib
81+
82+
mTPCVDriftNS = mVD->refVDrift * mVD->corrFact * 1e-3;
83+
mValid = true;
84+
LOGP(info, "Updated VDrift for timestamp {} with vdrift={:.7f} (cm/ns)", mVD->creationTime, mTPCVDriftNS);
85+
}
86+
6687
template <typename BCs, typename Collisions, typename Collision, typename TrackExtra, typename Track>
6788
[[nodiscard]] bool moveTPCTrack(const Collision& col, const TrackExtra& trackExtra, Track& track) noexcept
6889
{

Common/Tools/TrackPropagationModule.h

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "Common/Tools/TrackTuner.h"
2323

2424
#include <CommonConstants/GeomConstants.h>
25+
#include <DataFormatsCalibration/MeanVertexObject.h>
2526
#include <DetectorsBase/Propagator.h>
2627
#include <Framework/AnalysisDataModel.h>
2728
#include <Framework/AnalysisHelpers.h>
@@ -31,13 +32,13 @@
3132
#include <Framework/HistogramRegistry.h>
3233
#include <Framework/HistogramSpec.h>
3334
#include <Framework/Logger.h>
34-
#include <Framework/RunningWorkflowInfo.h>
3535
#include <ReconstructionDataFormats/DCA.h>
3636
#include <ReconstructionDataFormats/TrackParametrization.h>
3737
#include <ReconstructionDataFormats/TrackParametrizationWithError.h>
3838

3939
#include <TH1.h>
4040
#include <TH2.h>
41+
#include <TList.h>
4142

4243
#include <array>
4344
#include <cmath>
@@ -109,7 +110,9 @@ class TrackPropagationModule
109110
bool autoDetectDcaCalib = false; // track tuner setting
110111

111112
template <typename TConfigurableGroup, typename TInitContext, typename THistoRegistry>
112-
void init(TConfigurableGroup const& cGroup, TrackTuner& trackTunerObj, THistoRegistry& registry, TInitContext& initContext)
113+
/// \param calibFromCCDBColumns the task supplies the TrackTuner calibrations from the
114+
/// aod::TrackTunerCCDBObjects columns, so nothing is fetched from CCDB here.
115+
void init(TConfigurableGroup const& cGroup, TrackTuner& trackTunerObj, THistoRegistry& registry, TInitContext& initContext, bool calibFromCCDBColumns = false)
113116
{
114117
// Checking if the tables are requested in the workflow and enabling them
115118
fillTracks = o2::common::core::isTableRequiredInWorkflow(initContext, "Tracks");
@@ -176,23 +179,31 @@ class TrackPropagationModule
176179
/// read the track tuner instance configurations,
177180
/// to understand whether the TrackTuner::getDcaGraphs function can be called here (input path from string/configurables)
178181
/// or inside the process function, to "auto-detect" the input file based on the run number
179-
const auto& workflows = initContext.services().template get<o2::framework::RunningWorkflowInfo const>();
180-
for (o2::framework::DeviceSpec const& device : workflows.devices) { /// loop over devices
181-
if (device.name == "propagation-service") {
182-
// loop over the options
183-
// to find the value of TrackTuner::autoDetectDcaCalib
184-
for (const auto& option : device.options) { /// loop over options
185-
if (option.name == "trackTuner.autoDetectDcaCalib") {
186-
// found it!
187-
autoDetectDcaCalib = option.defaultValue.get<bool>();
188-
break;
189-
}
190-
} /// end loop over options
182+
// Read the option off the device we are actually running in. This used to search
183+
// the workflow for a device literally named "propagation-service", which silently
184+
// matched nothing in any other task (propagation-service-v2, -run2, ...), leaving
185+
// autoDetectDcaCalib at its default no matter how the task was configured.
186+
o2::framework::DeviceSpec const& device = initContext.services().template get<o2::framework::DeviceSpec const>();
187+
for (const auto& option : device.options) { /// loop over options
188+
if (option.name == "trackTuner.autoDetectDcaCalib") {
189+
// found it!
190+
autoDetectDcaCalib = option.defaultValue.get<bool>();
191191
break;
192192
}
193-
} /// end loop over devices
193+
} /// end loop over options
194194
LOG(info) << "[TrackPropagationModule] trackTuner.autoDetectDcaCalib it's equal to " << autoDetectDcaCalib;
195-
if (!autoDetectDcaCalib) {
195+
if (calibFromCCDBColumns && trackTunerObj.isInputFileFromCCDB) {
196+
// The column is the single source of truth for the path: its default carries the
197+
// per-period mapping and it is overridden through "ccdb:fTrackTunerDca". Silently
198+
// preferring one of two path settings is how calibrations diverge unnoticed, so a
199+
// leftover trackTuner.pathInputFile is an error rather than a shadowed value.
200+
if (!trackTunerObj.pathInputFile.empty()) {
201+
LOG(fatal) << "[TrackPropagationModule] trackTuner.pathInputFile is set to '" << trackTunerObj.pathInputFile
202+
<< "' while the TrackTuner calibrations are taken from the aod::TrackTunerCCDBObjects columns. "
203+
<< "Set the path through the \"ccdb:fTrackTunerDca\" option instead, or unset trackTuner.pathInputFile.";
204+
}
205+
LOG(info) << "[TrackPropagationModule] TrackTuner calibrations come from CCDB columns; graphs retrieved in the process function";
206+
} else if (!autoDetectDcaCalib) {
196207
LOG(info) << "[TrackPropagationModule] retrieve the graphs already (we are in propagationService::Init() function)";
197208
trackTunerObj.getDcaGraphs();
198209
} else {
@@ -215,24 +226,50 @@ class TrackPropagationModule
215226
registry.template get<TH1>(HIST("hPropagation"))->GetXaxis()->SetBinLabel(3, "Propagation OK");
216227
}
217228

229+
/// Legacy overload for callers still holding a StandardCCDBLoader; forwards the two
230+
/// run-scoped values actually used. Prefer the overload below, which lets the caller
231+
/// source them from CCDB columns instead of a CCDB query.
218232
template <bool isMc, typename TConfigurableGroup, typename TCCDBLoader, typename TCollisions, typename TTracks, typename TOutputGroup, typename THistoRegistry>
219233
void fillTrackTables(TConfigurableGroup const& cGroup, TrackTuner& trackTunerObj, TCCDBLoader const& ccdbLoader, TCollisions const& collisions, TTracks const& tracks, TOutputGroup& cursors, THistoRegistry& registry)
234+
{
235+
fillTrackTables<isMc>(cGroup, trackTunerObj, ccdbLoader.runNumber, ccdbLoader.mMeanVtx, collisions, tracks, cursors, registry);
236+
}
237+
238+
/// Takes the run-scoped conditions it actually needs (run number for the TrackTuner
239+
/// path, mean vertex for the DCA reference) rather than a CCDB loader object, so that
240+
/// callers are free to source them from CCDB columns instead of a CCDB query.
241+
template <bool isMc, typename TConfigurableGroup, typename TCollisions, typename TTracks, typename TOutputGroup, typename THistoRegistry>
242+
void fillTrackTables(TConfigurableGroup const& cGroup, TrackTuner& trackTunerObj, int currentRunNumber, o2::dataformats::MeanVertexObject const* meanVtx, TCollisions const& collisions, TTracks const& tracks, TOutputGroup& cursors, THistoRegistry& registry)
243+
{
244+
fillTrackTables<isMc>(cGroup, trackTunerObj, currentRunNumber, meanVtx, nullptr, nullptr, collisions, tracks, cursors, registry);
245+
}
246+
247+
/// As above, plus the TrackTuner calibration lists taken from the
248+
/// aod::TrackTunerCCDBObjects columns. When they are given, the run-range table that
249+
/// getPathInputFileAutomaticFromCCDB() would have walked has already been applied by
250+
/// the CCDB fetcher, so no CCDB query happens here at all.
251+
template <bool isMc, typename TConfigurableGroup, typename TCollisions, typename TTracks, typename TOutputGroup, typename THistoRegistry>
252+
void fillTrackTables(TConfigurableGroup const& cGroup, TrackTuner& trackTunerObj, int currentRunNumber, o2::dataformats::MeanVertexObject const* meanVtx, TList* dcaCalib, TList* qOverPtCalib, TCollisions const& collisions, TTracks const& tracks, TOutputGroup& cursors, THistoRegistry& registry)
220253
{
221254

222255
/// retrieve the TrackTuner calibration graphs *if not done yet*
223256
/// i.e. if autodetect is required
224-
if (cGroup.useTrackTuner.value && autoDetectDcaCalib && !trackTunerObj.areGraphsConfigured) {
257+
if (cGroup.useTrackTuner.value && !trackTunerObj.areGraphsConfigured && (autoDetectDcaCalib || dcaCalib != nullptr)) {
225258

226-
/// get the run number from the ccdb loader, already initialized
227-
const int runNumber = ccdbLoader.runNumber;
228-
trackTunerObj.setRunNumber(runNumber);
259+
trackTunerObj.setRunNumber(currentRunNumber);
229260

230-
/// setup the "auto-detected" path based on the run number
231-
trackTunerObj.getPathInputFileAutomaticFromCCDB();
232-
trackTunedTracks->SetTitle(trackTunerObj.outputString.c_str());
261+
if (dcaCalib != nullptr) {
262+
/// the path was resolved by the CCDB fetcher from the column's run-range mapping
263+
trackTunedTracks->SetTitle(trackTunerObj.outputString.c_str());
264+
trackTunerObj.getDcaGraphs(dcaCalib, qOverPtCalib);
265+
} else {
266+
/// setup the "auto-detected" path based on the run number
267+
trackTunerObj.getPathInputFileAutomaticFromCCDB();
268+
trackTunedTracks->SetTitle(trackTunerObj.outputString.c_str());
233269

234-
/// now that the path is ok, retrieve the graphs
235-
trackTunerObj.getDcaGraphs();
270+
/// now that the path is ok, retrieve the graphs
271+
trackTunerObj.getDcaGraphs();
272+
}
236273
}
237274

238275
if (!fillTracks) {
@@ -314,11 +351,11 @@ class TrackPropagationModule
314351
}
315352
} else {
316353
if (fillTracksCov) {
317-
mVtx.setPos({ccdbLoader.mMeanVtx->getX(), ccdbLoader.mMeanVtx->getY(), ccdbLoader.mMeanVtx->getZ()});
318-
mVtx.setCov(ccdbLoader.mMeanVtx->getSigmaX() * ccdbLoader.mMeanVtx->getSigmaX(), 0.0f, ccdbLoader.mMeanVtx->getSigmaY() * ccdbLoader.mMeanVtx->getSigmaY(), 0.0f, 0.0f, ccdbLoader.mMeanVtx->getSigmaZ() * ccdbLoader.mMeanVtx->getSigmaZ());
354+
mVtx.setPos({meanVtx->getX(), meanVtx->getY(), meanVtx->getZ()});
355+
mVtx.setCov(meanVtx->getSigmaX() * meanVtx->getSigmaX(), 0.0f, meanVtx->getSigmaY() * meanVtx->getSigmaY(), 0.0f, 0.0f, meanVtx->getSigmaZ() * meanVtx->getSigmaZ());
319356
isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, mTrackParCov, 2.f, matCorr, &mDcaInfoCov);
320357
} else {
321-
isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz({ccdbLoader.mMeanVtx->getX(), ccdbLoader.mMeanVtx->getY(), ccdbLoader.mMeanVtx->getZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo);
358+
isPropagationOK = o2::base::Propagator::Instance()->propagateToDCABxByBz({meanVtx->getX(), meanVtx->getY(), meanVtx->getZ()}, mTrackPar, 2.f, matCorr, &mDcaInfo);
322359
}
323360
}
324361
if (isPropagationOK) {

Common/Tools/TrackTuner.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#define COMMON_TOOLS_TRACKTUNER_H_
2020

2121
#include <CCDB/BasicCCDBManager.h>
22-
#include <CCDB/CcdbApi.h>
2322
#include <CommonConstants/MathConstants.h>
2423
#include <DetectorsBase/Propagator.h>
2524
#include <Framework/AnalysisDataModel.h>
@@ -630,6 +629,20 @@ struct TrackTuner : o2::framework::ConfigurableGroup {
630629
ccdb_object_qoverpt = dynamic_cast<TList*>(inputFileQoverPt->Get("ccdb_object"));
631630
}
632631

632+
getDcaGraphs(ccdb_object_dca, ccdb_object_qoverpt);
633+
}
634+
635+
/// \brief Builds the correction graphs from lists obtained elsewhere, typically straight
636+
/// from the aod::TrackTunerCCDBObjects columns, so no CCDB client is involved.
637+
void getDcaGraphs(TList* ccdb_object_dca, TList* ccdb_object_qoverpt)
638+
{
639+
/// abort if the graphs were already loaded
640+
if (areGraphsConfigured) {
641+
LOG(fatal) << "[TrackTuner::getDcaGraphs()] Function already called, i.e. the calibrations are already loaded. This further call should never happen. Aborting...";
642+
}
643+
std::string grOneOverPtPionNameMC = "sigmaVsPtMc";
644+
std::string grOneOverPtPionNameData = "sigmaVsPtData";
645+
633646
// choose wheter to use corrections w/ PV refit or w/o it, and retrieve the proper TList
634647
std::string dir = "woPvRefit";
635648
if (usePvRefitCorrections) {

PWGLF/Utils/strangenessBuilderModule.h

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
#include <array>
5151
#include <cmath>
52+
#include <cstddef>
5253
#include <cstdint>
5354
#include <cstdlib>
5455
#include <numeric>
@@ -844,6 +845,30 @@ class BuilderModule
844845
return idx;
845846
}
846847

848+
// Feed the V-drift manager from the aod::TpcCalibCCDBObjects column when the BC table
849+
// carries it, else fall back to a CCDB query. Lets migrated and un-migrated tasks share
850+
// this module unchanged.
851+
template <typename TBCs, typename TCollision>
852+
void updateVDrift(TCollision const& collision)
853+
{
854+
auto const& bc = collision.template bc_as<TBCs>();
855+
if constexpr (requires { bc.vdriftTgl(); }) {
856+
mVDriftMgr.update(bc.vdriftTgl());
857+
} else {
858+
mVDriftMgr.update(bc.timestamp());
859+
}
860+
}
861+
862+
// Overload for tasks whose BC table carries the V-drift CCDB column: nothing in here
863+
// needs a CCDB manager any more, so they need not own one.
864+
template <typename TCollisions, typename TBCs>
865+
bool initCCDB(TBCs const& bcs, TCollisions const& collisions)
866+
{
867+
static_assert(requires(typename TBCs::iterator bc) { bc.vdriftTgl(); }, "initCCDB without a CCDB manager needs a BC table joined with aod::TpcCalibCCDBObjects");
868+
std::nullptr_t noCCDB{};
869+
return initCCDB<TCollisions>(noCCDB, bcs, collisions);
870+
}
871+
847872
template <typename TCollisions, typename TCCDB, typename TBCs>
848873
bool initCCDB(TCCDB& ccdb, TBCs const& bcs, TCollisions const& collisions)
849874
{
@@ -872,8 +897,12 @@ class BuilderModule
872897

873898
if (v0BuilderOpts.generatePhotonCandidates.value && v0BuilderOpts.moveTPCOnlyTracks.value) {
874899
// initialize only if needed, avoid unnecessary CCDB calls
875-
mVDriftMgr.init(&ccdb->instance());
876-
mVDriftMgr.update(timestamp);
900+
if constexpr (requires { bc.vdriftTgl(); }) {
901+
mVDriftMgr.update(bc.vdriftTgl());
902+
} else {
903+
mVDriftMgr.init(&ccdb->instance());
904+
mVDriftMgr.update(timestamp);
905+
}
877906
}
878907

879908
return true;
@@ -1021,7 +1050,7 @@ class BuilderModule
10211050
// handle TPC-only tracks properly (photon conversions)
10221051
if (v0BuilderOpts.moveTPCOnlyTracks) {
10231052
if (collision.has_bc()) {
1024-
mVDriftMgr.update(collision.template bc_as<aod::BCsWithTimestamps>().timestamp());
1053+
updateVDrift<TBCs>(collision);
10251054
}
10261055
if (isPosTPCOnly) {
10271056
// Nota bene: positive is TPC-only -> this entire V0 merits treatment as photon candidate
@@ -1498,7 +1527,7 @@ class BuilderModule
14981527
continue;
14991528
}
15001529
if (v0BuilderOpts.generatePhotonCandidates && v0BuilderOpts.moveTPCOnlyTracks && collision.has_bc()) {
1501-
mVDriftMgr.update(collision.template bc_as<aod::BCsWithTimestamps>().timestamp());
1530+
updateVDrift<TBCs>(collision);
15021531
}
15031532
}
15041533
auto const& posTrack = tracks.rawIteratorAt(v0.posTrackId);
@@ -2757,6 +2786,16 @@ class BuilderModule
27572786
return returnValue;
27582787
}
27592788

2789+
//__________________________________________________
2790+
// Overload for tasks sourcing every conditions object from CCDB columns; see initCCDB above.
2791+
template <typename THistoRegistry, typename TCollisions, typename TMCCollisions, typename TV0s, typename TCascades, typename TTrackedCascades, typename TTracks, typename TBCs, typename TMCParticles, typename TProducts>
2792+
void dataProcess(THistoRegistry& histos, TCollisions const& collisions, TMCCollisions const& mccollisions, TV0s const& v0s, TCascades const& cascades, TTrackedCascades const& trackedCascades, TTracks const& tracks, TBCs const& bcs, TMCParticles const& mcParticles, TProducts& products)
2793+
{
2794+
static_assert(requires(typename TBCs::iterator bc) { bc.vdriftTgl(); }, "dataProcess without a CCDB manager needs a BC table joined with aod::TpcCalibCCDBObjects");
2795+
std::nullptr_t noCCDB{};
2796+
dataProcess(noCCDB, histos, collisions, mccollisions, v0s, cascades, trackedCascades, tracks, bcs, mcParticles, products);
2797+
}
2798+
27602799
//__________________________________________________
27612800
template <typename TCCDB, typename THistoRegistry, typename TCollisions, typename TMCCollisions, typename TV0s, typename TCascades, typename TTrackedCascades, typename TTracks, typename TBCs, typename TMCParticles, typename TProducts>
27622801
void dataProcess(TCCDB& ccdb, THistoRegistry& histos, TCollisions const& collisions, TMCCollisions const& mccollisions, TV0s const& v0s, TCascades const& cascades, TTrackedCascades const& trackedCascades, TTracks const& tracks, TBCs const& bcs, TMCParticles const& mcParticles, TProducts& products)

0 commit comments

Comments
 (0)