1111
1212//
1313// Task to add a table of track parameters propagated to the primary vertex
14+ // V2: GRPMagField and MeanVertexObject migrated to declarative CCDB columns.
1415//
1516
1617#include " Common/Core/TableHelper.h"
1920#include " Common/Tools/TrackTuner.h"
2021
2122#include < CCDB/BasicCCDBManager.h>
22- #include < CommonConstants/GeomConstants.h>
2323#include < DataFormatsCalibration/MeanVertexObject.h>
2424#include < DataFormatsParameters/GRPMagField.h>
2525#include < DetectorsBase/MatLayerCylSet.h>
4848#include < cmath>
4949#include < string>
5050
51- // The Run 3 AO2D stores the tracks at the point of innermost update. For a track with ITS this is the innermost (or second innermost)
52- // ITS layer. For a track without ITS, this is the TPC inner wall or for loopers in the TPC even a radius beyond that.
53- // In order to use the track parameters, the tracks have to be propagated to the collision vertex which is done by this task.
54- // The task consumes the TracksIU and TracksCovIU tables and produces Tracks and TracksCov to which then the user analysis can subscribe.
55- //
56- // This task is not needed for Run 2 converted data.
57- // There are two versions of the task (see process flags), one producing also the covariance matrix and the other only the tracks table.
51+ // Declarative CCDB columns for GRPMagField and MeanVertexObject.
52+ // MatLayerCylSet is intentionally excluded: it requires
53+ // MatLayerCylSet::rectifyPtrFromFile() after deserialisation, a type-specific
54+ // fixup the CCDB column mechanism does not perform. It continues to be fetched
55+ // via Service<BasicCCDBManager> below.
56+ namespace o2 ::aod
57+ {
58+ namespace trackpropv2
59+ {
60+ DECLARE_SOA_CCDB_COLUMN (GRPMagField, grpMagField, o2::parameters::GRPMagField, " GLO/Config/GRPMagField" ); // !
61+ DECLARE_SOA_CCDB_COLUMN (MeanVertex, meanVertex, o2::dataformats::MeanVertexObject, " GLO/Calib/MeanVertex" ); // !
62+ } // namespace trackpropv2
63+
64+ DECLARE_SOA_TIMESTAMPED_TABLE (TrackPropV2CCDBObjects, aod::Timestamps, o2::aod::timestamp::Timestamp, 1 , " TRKPROPV2CC" , // !
65+ trackpropv2::GRPMagField, trackpropv2::MeanVertex);
66+ } // namespace o2::aod
5867
5968using namespace o2 ;
6069using namespace o2 ::framework;
61- // using namespace o2::framework::expressions;
6270
63- struct TrackPropagation {
71+ struct TrackPropagationV2 {
6472 Produces<aod::StoredTracks> tracksParPropagated;
6573 Produces<aod::TracksExtension> tracksParExtensionPropagated;
6674
@@ -72,25 +80,28 @@ struct TrackPropagation {
7280
7381 Produces<aod::TrackTunerTable> tunertable;
7482
83+ // MatLUT still fetched via BasicCCDBManager (requires rectifyPtrFromFile).
84+ // GRPMagField and MeanVertex are now sourced from CCDB columns on the BC.
7585 Service<o2::ccdb::BasicCCDBManager> ccdb;
7686
7787 bool fillTracksDCA = false ;
7888 bool fillTracksDCACov = false ;
79- int runNumber = -1 ;
89+ int runNumber = -1 ; // tracks current run for per-run B-field re-initialisation
8090
8191 o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT;
8292
83- const o2::dataformats::MeanVertexObject* mMeanVtx = nullptr ;
84- o2::parameters::GRPMagField* grpmag = nullptr ;
8593 o2::base::MatLayerCylSet* lut = nullptr ;
8694 TrackTuner trackTunerObj;
8795
96+ // MatLUT path: still fetched manually (see note above)
8897 Configurable<std::string> ccdburl{" ccdb-url" , " http://alice-ccdb.cern.ch" , " url of the ccdb repository" };
8998 Configurable<std::string> lutPath{" lutPath" , " GLO/Param/MatLUT" , " Path of the Lut parametrization" };
9099 Configurable<std::string> geoPath{" geoPath" , " GLO/Config/GeometryAligned" , " Path of the geometry file" };
91- Configurable<std::string> grpmagPath{" grpmagPath" , " GLO/Config/GRPMagField" , " CCDB path of the GRPMagField object" };
92- Configurable<std::string> mVtxPath {" mVtxPath" , " GLO/Calib/MeanVertex" , " Path of the mean vertex file" };
93- Configurable<float > minPropagationRadius{" minPropagationDistance" , o2::constants::geom::XTPCInnerRef + 0.1 , " Only tracks which are at a smaller radius will be propagated, defaults to TPC inner wall" };
100+ // Declarative CCDB path overrides — replace the old grpmagPath / mVtxPath Configurables.
101+ // Option names: "ccdb:fGRPMagField" and "ccdb:fMeanVertex" respectively.
102+ ConfigurableCCDBPath<trackpropv2::GRPMagField> grpmagPath;
103+ ConfigurableCCDBPath<trackpropv2::MeanVertex> mVtxPath ;
104+
94105 // for TrackTuner only (MC smearing)
95106 Configurable<bool > useTrackTuner{" useTrackTuner" , false , " Apply track tuner corrections to MC" };
96107 Configurable<bool > fillTrackTunerTable{" fillTrackTunerTable" , false , " flag to fill track tuner table" };
@@ -99,10 +110,8 @@ struct TrackPropagation {
99110 ConfigurableAxis axisPtQA{" axisPtQA" , {VARIABLE_WIDTH, 0 .0f , 0 .1f , 0 .2f , 0 .3f , 0 .4f , 0 .5f , 0 .6f , 0 .7f , 0 .8f , 0 .9f , 1 .0f , 1 .1f , 1 .2f , 1 .3f , 1 .4f , 1 .5f , 1 .6f , 1 .7f , 1 .8f , 1 .9f , 2 .0f , 2 .2f , 2 .4f , 2 .6f , 2 .8f , 3 .0f , 3 .2f , 3 .4f , 3 .6f , 3 .8f , 4 .0f , 4 .4f , 4 .8f , 5 .2f , 5 .6f , 6 .0f , 6 .5f , 7 .0f , 7 .5f , 8 .0f , 9 .0f , 10 .0f , 11 .0f , 12 .0f , 13 .0f , 14 .0f , 15 .0f , 17 .0f , 19 .0f , 21 .0f , 23 .0f , 25 .0f , 30 .0f , 35 .0f , 40 .0f , 50 .0f }, " pt axis for QA histograms" };
100111 OutputObj<TH1D> trackTunedTracks{TH1D (" trackTunedTracks" , " " , 1 , 0.5 , 1.5 ), OutputObjHandlingPolicy::AnalysisObject};
101112
102- // OutputObj<TH2F> hDCAxyVsPtRec{TH2F("hDCAxyVsPtRec", ";DCAxy;PtRec", 600, -0.15, 0.15, axisPtQA)};
103- // OutputObj<TH2F> hDCAxyVsPtMC{TH2F("hDCAxyVsPtMC", ";DCAxy;PtMC", 600, -0.15, 0.15, axisPtQA)};
104-
105113 using TracksIUWithMc = soa::Join<aod::StoredTracksIU, aod::McTrackLabels, aod::TracksCovIU>;
114+ using MyBCs = soa::Join<aod::BCsWithTimestamps, aod::TrackPropV2CCDBObjects>;
106115
107116 HistogramRegistry registry{" registry" };
108117
@@ -117,12 +126,10 @@ struct TrackPropagation {
117126 LOG (info) << " Enabling processCovarianceMc" ;
118127 nEnabledProcesses++;
119128 }
120-
121129 if (doprocessCovariance) {
122130 LOG (info) << " Enabling processCovariance" ;
123131 nEnabledProcesses++;
124132 }
125-
126133 if (doprocessStandardWithPID) {
127134 LOG (info) << " Enabling processStandardWithPID" ;
128135 nEnabledProcesses++;
@@ -138,6 +145,7 @@ struct TrackPropagation {
138145 fillTracksDCA = o2::common::core::isTableRequiredInWorkflow (initContext, " TracksDCA" );
139146 fillTracksDCACov = o2::common::core::isTableRequiredInWorkflow (initContext, " TracksDCACov" );
140147
148+ // Only needed for the MatLUT fetch; GRPMagField and MeanVertex use CCDB columns
141149 ccdb->setURL (ccdburl);
142150 ccdb->setCaching (true );
143151 ccdb->setLocalObjectValidityChecking ();
@@ -159,37 +167,33 @@ struct TrackPropagation {
159167 case aod::track_tuner::Configurables:
160168 outputStringParams = trackTunerObj.configParams ();
161169 break ;
162-
163170 default :
164171 LOG (fatal) << " TrackTuner configuration source not defined. Fix it! (Supported options: input string (1); Configurables (2))" ;
165172 break ;
166173 }
167-
168174 trackTunerObj.getDcaGraphs ();
169175 trackTunedTracks->SetTitle (outputStringParams.c_str ());
170176 trackTunedTracks->GetXaxis ()->SetBinLabel (1 , " all tracks" );
171177 }
172178 }
173179
174- void initCCDB (aod::BCsWithTimestamps::iterator const & bc)
180+ // Initialises the MatLUT (once per job) and the B-field (once per run).
181+ // GRPMagField is now read directly from the CCDB column on the BC row;
182+ // only the MatLUT still requires a manual fetch + rectifyPtrFromFile.
183+ template <typename TBC>
184+ void initCCDB (TBC const & bc)
175185 {
176- if (runNumber == bc.runNumber ()) {
177- return ;
178- }
179-
180- // load matLUT for this timestamp
181186 if (!lut) {
182187 LOG (info) << " Loading material look-up table for timestamp: " << bc.timestamp ();
183188 lut = o2::base::MatLayerCylSet::rectifyPtrFromFile (ccdb->getForTimeStamp <o2::base::MatLayerCylSet>(lutPath, bc.timestamp ()));
184- } else {
185- LOG (info) << " Material look-up table already in place. Not reloading." ;
189+ o2::base::Propagator::Instance ()->setMatLUT (lut);
186190 }
187-
188- grpmag = ccdb-> getForTimeStamp <o2::parameters::GRPMagField>(grpmagPath, bc. timestamp ()) ;
189- LOG (info) << " Setting magnetic field to current " << grpmag-> getL3Current () << " A for run " << bc. runNumber () << " from its GRPMagField CCDB object " ;
190- o2::base::Propagator::initFieldFromGRP ( grpmag);
191- o2::base::Propagator::Instance ()-> setMatLUT (lut) ;
192- mMeanVtx = ccdb-> getForTimeStamp < o2::dataformats::MeanVertexObject>( mVtxPath , bc. timestamp () );
191+ if (runNumber == bc. runNumber ()) {
192+ return ;
193+ }
194+ const auto & grpmag = bc. grpMagField (); // from declarative CCDB column
195+ LOG (info) << " Setting magnetic field to current " << grpmag. getL3Current () << " A for run " << bc. runNumber () << " from its GRPMagField CCDB column " ;
196+ o2::base::Propagator::initFieldFromGRP (&grpmag );
193197 runNumber = bc.runNumber ();
194198 }
195199
@@ -200,16 +204,20 @@ struct TrackPropagation {
200204 o2::track::TrackParametrization<float > mTrackPar ;
201205 o2::track::TrackParametrizationWithError<float > mTrackParCov ;
202206
207+ Configurable<float > minPropagationRadius{" minPropagationDistance" , o2::constants::geom::XTPCInnerRef + 0.1 , " Only tracks which are at a smaller radius will be propagated, defaults to TPC inner wall" };
208+
203209 template <typename TTrack, typename TParticle, bool isMc, bool fillCovMat = false , bool useTrkPid = false >
204210 void fillTrackTables (TTrack const & tracks,
205211 TParticle const &,
206212 aod::Collisions const &,
207- aod::BCsWithTimestamps const & bcs)
213+ MyBCs const & bcs)
208214 {
209215 if (bcs.size () == 0 ) {
210216 return ;
211217 }
212- initCCDB (bcs.begin ());
218+ auto bc0 = bcs.begin ();
219+ initCCDB (bc0);
220+ const auto & meanVertex = bc0.meanVertex (); // from declarative CCDB column
213221
214222 if constexpr (fillCovMat) {
215223 tracksParCovPropagated.reserve (tracks.size ());
@@ -244,15 +252,11 @@ struct TrackPropagation {
244252 mTrackPar .setPID (track.pidForTracking ());
245253 }
246254 }
247- // auto trackParCov = getTrackParCov(track);
248255 aod::track::TrackTypeEnum trackType = (aod::track::TrackTypeEnum)track.trackType ();
249- // std::array<float, 3> trackPxPyPz;
250- // std::array<float, 3> trackPxPyPzTuned = {0.0, 0.0, 0.0};
251256 double q2OverPtNew = -9999 .;
252257 // Only propagate tracks which have passed the innermost wall of the TPC (e.g. skipping loopers etc). Others fill unpropagated.
253258 if (track.trackType () == aod::track::TrackIU && track.x () < minPropagationRadius) {
254259 if constexpr (isMc && fillCovMat) { // checking MC and fillCovMat block begins
255- // bool hasMcParticle = track.has_mcParticle();
256260 if (useTrackTuner) {
257261 trackTunedTracks->Fill (1 ); // all tracks
258262 bool hasMcParticle = track.has_mcParticle ();
@@ -276,11 +280,11 @@ struct TrackPropagation {
276280 }
277281 } else {
278282 if constexpr (fillCovMat) {
279- mVtx .setPos ({mMeanVtx -> getX (), mMeanVtx -> getY (), mMeanVtx -> getZ ()});
280- mVtx .setCov (mMeanVtx -> getSigmaX () * mMeanVtx -> getSigmaX (), 0 .0f , mMeanVtx -> getSigmaY () * mMeanVtx -> getSigmaY (), 0 .0f , 0 .0f , mMeanVtx -> getSigmaZ () * mMeanVtx -> getSigmaZ ());
283+ mVtx .setPos ({meanVertex. getX (), meanVertex. getY (), meanVertex. getZ ()});
284+ mVtx .setCov (meanVertex. getSigmaX () * meanVertex. getSigmaX (), 0 .0f , meanVertex. getSigmaY () * meanVertex. getSigmaY (), 0 .0f , 0 .0f , meanVertex. getSigmaZ () * meanVertex. getSigmaZ ());
281285 isPropagationOK = o2::base::Propagator::Instance ()->propagateToDCABxByBz (mVtx , mTrackParCov , 2 .f , matCorr, &mDcaInfoCov );
282286 } else {
283- isPropagationOK = o2::base::Propagator::Instance ()->propagateToDCABxByBz ({mMeanVtx -> getX (), mMeanVtx -> getY (), mMeanVtx -> getZ ()}, mTrackPar , 2 .f , matCorr, &mDcaInfo );
287+ isPropagationOK = o2::base::Propagator::Instance ()->propagateToDCABxByBz ({meanVertex. getX (), meanVertex. getY (), meanVertex. getZ ()}, mTrackPar , 2 .f , matCorr, &mDcaInfo );
284288 }
285289 }
286290 if (isPropagationOK) {
@@ -290,7 +294,6 @@ struct TrackPropagation {
290294 if constexpr (isMc && fillCovMat) { // checking MC and fillCovMat block begins
291295 if (track.has_mcParticle () && isPropagationOK) {
292296 auto mcParticle1 = track.mcParticle ();
293- // && abs(mcParticle1.pdgCode())==211
294297 if (mcParticle1.isPhysicalPrimary ()) {
295298 registry.fill (HIST (" hDCAxyVsPtRec" ), mDcaInfoCov .getY (), mTrackParCov .getPt ());
296299 registry.fill (HIST (" hDCAxyVsPtMC" ), mDcaInfoCov .getY (), mcParticle1.pt ());
@@ -304,7 +307,6 @@ struct TrackPropagation {
304307 if (useTrackTuner && fillTrackTunerTable) {
305308 tunertable (q2OverPtNew);
306309 }
307- // LOG(info) << " trackPropagation (this value filled in tuner table)--> " << q2OverPtNew;
308310 if constexpr (fillCovMat) {
309311 tracksParPropagated (track.collisionId (), trackType, mTrackParCov .getX (), mTrackParCov .getAlpha (), mTrackParCov .getY (), mTrackParCov .getZ (), mTrackParCov .getSnp (), mTrackParCov .getTgl (), mTrackParCov .getQ2Pt ());
310312 tracksParExtensionPropagated (mTrackParCov .getPt (), mTrackParCov .getP (), mTrackParCov .getEta (), mTrackParCov .getPhi ());
@@ -331,38 +333,35 @@ struct TrackPropagation {
331333 }
332334 }
333335
334- void processStandard (aod::StoredTracksIU const & tracks, aod::Collisions const & collisions, aod::BCsWithTimestamps const & bcs)
336+ void processStandard (aod::StoredTracksIU const & tracks, aod::Collisions const & collisions, MyBCs const & bcs)
335337 {
336338 fillTrackTables</* TTrack*/ aod::StoredTracksIU, /* Particle*/ aod::StoredTracksIU, /* isMc = */ false , /* fillCovMat =*/ false , /* useTrkPid =*/ false >(tracks, tracks, collisions, bcs);
337339 }
338- PROCESS_SWITCH (TrackPropagation , processStandard, " Process without covariance" , true );
340+ PROCESS_SWITCH (TrackPropagationV2 , processStandard, " Process without covariance" , true );
339341
340- void processStandardWithPID (soa::Join<aod::StoredTracksIU, aod::TracksExtra> const & tracks, aod::Collisions const & collisions, aod::BCsWithTimestamps const & bcs)
342+ void processStandardWithPID (soa::Join<aod::StoredTracksIU, aod::TracksExtra> const & tracks, aod::Collisions const & collisions, MyBCs const & bcs)
341343 {
342344 fillTrackTables</* TTrack*/ soa::Join<aod::StoredTracksIU, aod::TracksExtra>, /* Particle*/ soa::Join<aod::StoredTracksIU, aod::TracksExtra>, /* isMc = */ false , /* fillCovMat =*/ false , /* useTrkPid =*/ true >(tracks, tracks, collisions, bcs);
343345 }
344- PROCESS_SWITCH (TrackPropagation , processStandardWithPID, " Process without covariance and with PID in tracking" , false );
346+ PROCESS_SWITCH (TrackPropagationV2 , processStandardWithPID, " Process without covariance and with PID in tracking" , false );
345347
346- // -----------------------
347- void processCovarianceMc (TracksIUWithMc const & tracks, aod::McParticles const & mcParticles, aod::Collisions const & collisions, aod::BCsWithTimestamps const & bcs)
348+ void processCovarianceMc (TracksIUWithMc const & tracks, aod::McParticles const & mcParticles, aod::Collisions const & collisions, MyBCs const & bcs)
348349 {
349- // auto table_extension = soa::Extend<TracksIUWithMc, aod::extension::MomX>(tracks);
350350 fillTrackTables</* TTrack*/ TracksIUWithMc, /* Particle*/ aod::McParticles, /* isMc = */ true , /* fillCovMat =*/ true , /* useTrkPid =*/ false >(tracks, mcParticles, collisions, bcs);
351351 }
352- PROCESS_SWITCH (TrackPropagation , processCovarianceMc, " Process with covariance on MC" , false );
352+ PROCESS_SWITCH (TrackPropagationV2 , processCovarianceMc, " Process with covariance on MC" , false );
353353
354- void processCovariance (soa::Join<aod::StoredTracksIU, aod::TracksCovIU> const & tracks, aod::Collisions const & collisions, aod::BCsWithTimestamps const & bcs)
354+ void processCovariance (soa::Join<aod::StoredTracksIU, aod::TracksCovIU> const & tracks, aod::Collisions const & collisions, MyBCs const & bcs)
355355 {
356356 fillTrackTables</* TTrack*/ soa::Join<aod::StoredTracksIU, aod::TracksCovIU>, /* Particle*/ soa::Join<aod::StoredTracksIU, aod::TracksCovIU>, /* isMc = */ false , /* fillCovMat =*/ true , /* useTrkPid =*/ false >(tracks, tracks, collisions, bcs);
357357 }
358- PROCESS_SWITCH (TrackPropagation, processCovariance, " Process with covariance" , false );
359- // ------------------------
358+ PROCESS_SWITCH (TrackPropagationV2, processCovariance, " Process with covariance" , false );
360359
361- void processCovarianceWithPID (soa::Join<aod::StoredTracksIU, aod::TracksCovIU, aod::TracksExtra> const & tracks, aod::Collisions const & collisions, aod::BCsWithTimestamps const & bcs)
360+ void processCovarianceWithPID (soa::Join<aod::StoredTracksIU, aod::TracksCovIU, aod::TracksExtra> const & tracks, aod::Collisions const & collisions, MyBCs const & bcs)
362361 {
363362 fillTrackTables</* TTrack*/ soa::Join<aod::StoredTracksIU, aod::TracksCovIU, aod::TracksExtra>, /* Particle*/ soa::Join<aod::StoredTracksIU, aod::TracksCovIU, aod::TracksExtra>, /* isMc = */ false , /* fillCovMat =*/ true , /* useTrkPid =*/ false >(tracks, tracks, collisions, bcs);
364363 }
365- PROCESS_SWITCH (TrackPropagation , processCovarianceWithPID, " Process with covariance and with PID in tracking" , false );
364+ PROCESS_SWITCH (TrackPropagationV2 , processCovarianceWithPID, " Process with covariance and with PID in tracking" , false );
366365};
367366
368367// ****************************************************************************************
@@ -372,6 +371,6 @@ struct TrackPropagation {
372371// ****************************************************************************************
373372WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
374373{
375- WorkflowSpec workflow{adaptAnalysisTask<TrackPropagation >(cfgc)};
374+ WorkflowSpec workflow{adaptAnalysisTask<TrackPropagationV2 >(cfgc)};
376375 return workflow;
377376}
0 commit comments