1818#include " Framework/runDataProcessing.h"
1919#include " Common/Core/TrackSelection.h"
2020#include " Common/DataModel/TrackSelectionTables.h"
21+ #include " Common/DataModel/Multiplicity.h"
2122#include " Common/Core/trackUtilities.h"
2223#include " ReconstructionDataFormats/DCA.h"
2324#include " DetectorsBase/Propagator.h"
2425#include " DetectorsBase/GeometryManager.h"
2526#include " DetectorsCommonDataFormats/NameConf.h"
27+ #include " DataFormatsParameters/GRPObject.h"
28+ #include < CCDB/BasicCCDBManager.h>
2629
2730using namespace o2 ;
2831using namespace o2 ::framework;
@@ -35,44 +38,112 @@ using namespace o2::framework::expressions;
3538 * FIXME: computing overhead and errors in calculations
3639 */
3740// ****************************************************************************************
38- struct TrackExtensionTask {
39- Configurable<int > cfgDcaMethod{" dcamethod" , 1 , " Method to estimate the track DCA: 0 = crude, 1 = minimum, 2 = rigorous. Default minimum" };
41+ namespace o2
42+ {
43+ namespace analysis
44+ {
45+ namespace trackextension
46+ {
47+ constexpr long run3lut_timestamp = (1665695116725 + 1634159124442 ) / 2 ;
48+ constexpr long run3grp_timestamp = (1619781650000 + 1619781529000 ) / 2 ;
49+ const char * ccdbpath_lut = " GLO/Param/MatLUT" ;
50+ const char * ccdbpath_grp = " Users/v/victor/GRP/GRP" ;
51+ const char * ccdburl = " http://alice-ccdb.cern.ch:8080" ; /* production "https://alice-ccdb.cern.ch"; */
52+ } // namespace trackextension
53+ } // namespace analysis
54+ } // namespace o2
4055
56+ struct TrackExtensionTask {
4157 Produces<aod::TracksExtended> extendedTrackQuantities;
58+ Service<o2::ccdb::BasicCCDBManager> ccdb;
4259
43- void process (aod::FullTracks const & tracks, aod::Collisions const &)
60+ int mRunNumber ;
61+
62+ void init (InitContext& context)
4463 {
45- o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT;
46- if ((cfgDcaMethod == 1 ) or (cfgDcaMethod == 2 )) {
47- if (!o2::base::GeometryManager::isGeometryLoaded ()) {
48- o2::base::GeometryManager::loadGeometry ();
49- o2::base::Propagator::initFieldFromGRP ();
50- auto matLUTFile = o2::base::NameConf::getMatLUTFileName ();
51- if (o2::utils::Str::pathExists (matLUTFile)) {
52- auto * lut = o2::base::MatLayerCylSet::loadFromFile (matLUTFile);
53- o2::base::Propagator::Instance ()->setMatLUT (lut);
64+ using namespace analysis ::trackextension;
65+
66+ ccdb->setURL (ccdburl);
67+ ccdb->setCaching (true );
68+ ccdb->setLocalObjectValidityChecking ();
69+
70+ auto lut = o2::base::MatLayerCylSet::rectifyPtrFromFile (ccdb->getForTimeStamp <o2::base::MatLayerCylSet>(ccdbpath_lut, run3lut_timestamp));
71+
72+ if (!o2::base::GeometryManager::isGeometryLoaded ()) {
73+ o2::base::GeometryManager::loadGeometry ();
74+ /* it seems this is needed at this level for the material LUT to work properly */
75+ /* but what happens if the run changes while doing the processing? */
76+ o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp <o2::parameters::GRPObject>(ccdbpath_grp, analysis::trackextension::run3grp_timestamp);
77+ o2::base::Propagator::initFieldFromGRP (grpo);
78+ o2::base::Propagator::Instance ()->setMatLUT (lut);
79+ }
80+ mRunNumber = 0 ;
81+ }
82+
83+ void processRun2 (aod::FullTracks const & tracks, aod::Collisions const &, aod::BCsWithTimestamps const &)
84+ {
85+ using namespace analysis ::trackextension;
86+
87+ int lastCollId = -1 ;
88+ for (auto & track : tracks) {
89+ std::array<float , 2 > dca{1e10f, 1e10f};
90+ float magField = 0.0 ;
91+ if (track.has_collision ()) {
92+ if (track.trackType () == o2::aod::track::TrackTypeEnum::Run2Track && track.itsChi2NCl () != 0 .f && track.tpcChi2NCl () != 0 .f && std::abs (track.x ()) < 10 .f ) {
93+ if (lastCollId != track.collisionId ()) {
94+ auto bc = track.collision_as <aod::Collisions>().bc_as <aod::BCsWithTimestamps>();
95+ if (mRunNumber != bc.runNumber ()) {
96+ o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp <o2::parameters::GRPObject>(ccdbpath_grp, bc.timestamp ());
97+ if (grpo != nullptr ) {
98+ /* TODO: magnetic field intensity from L3 current */
99+ if (grpo->getL3Current () > 0 ) {
100+ magField = 5.0 ;
101+ } else {
102+ magField = -5.0 ;
103+ }
104+ } else {
105+ LOGF (fatal, " GRP object is not available in CCDB for run=%d at timestamp=%llu" , bc.runNumber (), bc.timestamp ());
106+ }
107+ mRunNumber = bc.runNumber ();
108+ }
109+ lastCollId = track.collisionId ();
110+ }
111+ auto trackPar = getTrackPar (track);
112+ auto const & collision = track.collision ();
113+ trackPar.propagateParamToDCA ({collision.posX (), collision.posY (), collision.posZ ()}, magField, &dca);
54114 }
55115 }
116+ extendedTrackQuantities (dca[0 ], dca[1 ]);
117+
118+ // TODO: add realtive pt resolution sigma(pt)/pt \approx pt * sigma(1/pt)
119+ // TODO: add geometrical length / fiducial volume
56120 }
57- for (auto & track : tracks) {
121+ }
122+ PROCESS_SWITCH (TrackExtensionTask, processRun2, " Process Run2 track extension task" , true );
123+
124+ void processRun3 (aod::FullTracks const & tracks, aod::Collisions const &)
125+ {
126+ using namespace analysis ::trackextension;
58127
128+ /* it is not clear yet if we will the GRP object per run number */
129+ /* if that is the case something similar to what has been */
130+ /* done for Run2 needs to be implemented */
131+ /* but incorporating here only the GRP object makes appear */
132+ /* the double peak in the DCAxy distribution again */
133+ /* so probaly the whole initalization sequence is needed */
134+ /* when a new run (Run3) is processed */
135+ o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT;
136+
137+ for (auto & track : tracks) {
59138 std::array<float , 2 > dca{1e10f, 1e10f};
60139 if (track.has_collision ()) {
61- if ((track.trackType () == o2::aod::track::TrackTypeEnum::Track) ||
62- (track.trackType () == o2::aod::track::TrackTypeEnum::Run2Track && track.itsChi2NCl () != 0 .f && track.tpcChi2NCl () != 0 .f && std::abs (track.x ()) < 10 .f )) {
140+ if (track.trackType () == o2::aod::track::TrackTypeEnum::Track) {
63141 auto trackPar = getTrackPar (track);
64142 auto const & collision = track.collision ();
65- if (cfgDcaMethod == 1 ) {
66- trackPar.propagateParamToDCA ({collision.posX (), collision.posY (), collision.posZ ()}, o2::base::Propagator::Instance ()->getNominalBz (), &dca);
67- } else if (cfgDcaMethod == 2 ) {
68- gpu::gpustd::array<float , 2 > dcaInfo;
69- if (o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, trackPar, 2 .f , matCorr, &dcaInfo)) {
70- dca[0 ] = dcaInfo[0 ];
71- dca[1 ] = dcaInfo[1 ];
72- }
73- } else {
74- float magField = 5.0 ; // in kG (FIXME: get this from CCDB)
75- trackPar.propagateParamToDCA ({collision.posX (), collision.posY (), collision.posZ ()}, magField, &dca);
143+ gpu::gpustd::array<float , 2 > dcaInfo;
144+ if (o2::base::Propagator::Instance ()->propagateToDCABxByBz ({collision.posX (), collision.posY (), collision.posZ ()}, trackPar, 2 .f , matCorr, &dcaInfo)) {
145+ dca[0 ] = dcaInfo[0 ];
146+ dca[1 ] = dcaInfo[1 ];
76147 }
77148 }
78149 }
@@ -82,6 +153,7 @@ struct TrackExtensionTask {
82153 // TODO: add geometrical length / fiducial volume
83154 }
84155 }
156+ PROCESS_SWITCH (TrackExtensionTask, processRun3, " Process Run3 track extension task" , false );
85157};
86158
87159// ****************************************************************************************
@@ -91,6 +163,6 @@ struct TrackExtensionTask {
91163// ****************************************************************************************
92164WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
93165{
94- WorkflowSpec workflow{adaptAnalysisTask<TrackExtensionTask>(cfgc, TaskName{ " track-extension " } )};
166+ WorkflowSpec workflow{adaptAnalysisTask<TrackExtensionTask>(cfgc)};
95167 return workflow;
96168}
0 commit comments