Skip to content

Commit 291eded

Browse files
ddobrigkalibuild
andauthored
[Common] track propagation test with modular approach (#11343)
Co-authored-by: ALICE Builder <alibuild@users.noreply.github.com>
1 parent 25541ee commit 291eded

File tree

3 files changed

+401
-277
lines changed

3 files changed

+401
-277
lines changed

Common/TableProducer/trackPropagationTester.cxx

Lines changed: 35 additions & 277 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,19 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12+
/// \file trackPropagationTester.cxx
13+
/// \brief testing ground for track propagation
14+
/// \author ALICE
15+
16+
//===============================================================
17+
//
18+
// Experimental version of the track propagation task
19+
// this utilizes an analysis task module that can be employed elsewhere
20+
// and allows for the re-utilization of a material LUT
1221
//
13-
// Task to add a table of track parameters propagated to the primary vertex
22+
// candidate approach for core service approach
1423
//
15-
// FIXME: THIS IS AN EXPERIMENTAL TASK, MEANT ONLY FOR EXPLORATORY PURPOSES.
16-
// FIXME: PLEASE ONLY USE IT WITH EXTREME CARE. IF IN DOUBT, STICK WITH THE DEFAULT
17-
// FIXME: TRACKPROPAGATION
24+
//===============================================================
1825

1926
#include "Framework/AnalysisDataModel.h"
2027
#include "Framework/AnalysisTask.h"
@@ -30,10 +37,10 @@
3037
#include "DataFormatsParameters/GRPMagField.h"
3138
#include "CCDB/BasicCCDBManager.h"
3239
#include "Framework/HistogramRegistry.h"
33-
#include "Framework/runDataProcessing.h"
3440
#include "DataFormatsCalibration/MeanVertexObject.h"
3541
#include "CommonConstants/GeomConstants.h"
36-
#include "trackSelectionRequest.h"
42+
#include "Common/Tools/TrackPropagationModule.h"
43+
#include "Common/Tools/StandardCCDBLoader.h"
3744

3845
// 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)
3946
// ITS layer. For a track without ITS, this is the TPC inner wall or for loopers in the TPC even a radius beyond that.
@@ -48,294 +55,45 @@ using namespace o2::framework;
4855
// using namespace o2::framework::expressions;
4956

5057
struct TrackPropagationTester {
51-
Produces<aod::StoredTracks> tracksParPropagated;
52-
Produces<aod::TracksExtension> tracksParExtensionPropagated;
53-
54-
Produces<aod::StoredTracksCov> tracksParCovPropagated;
55-
Produces<aod::TracksCovExtension> tracksParCovExtensionPropagated;
56-
57-
Produces<aod::TracksDCA> tracksDCA;
58+
o2::common::StandardCCDBLoaderConfigurables standardCCDBLoaderConfigurables;
59+
o2::common::TrackPropagationProducts trackPropagationProducts;
60+
o2::common::TrackPropagationConfigurables trackPropagationConfigurables;
5861

62+
// CCDB boilerplate declarations
63+
o2::framework::Configurable<std::string> ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
5964
Service<o2::ccdb::BasicCCDBManager> ccdb;
6065

61-
HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject};
62-
63-
bool fillTracksDCA = false;
64-
int runNumber = -1;
65-
66-
o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT;
67-
68-
const o2::dataformats::MeanVertexObject* mVtx = nullptr;
69-
o2::parameters::GRPMagField* grpmag = nullptr;
70-
o2::base::MatLayerCylSet* lut = nullptr;
66+
o2::common::StandardCCDBLoader ccdbLoader;
67+
o2::common::TrackPropagationModule trackPropagation;
7168

72-
// Track selection object in this scope: not necessarily a configurable
73-
trackSelectionRequest trackSels;
74-
// Configurable based on a struct
75-
// Configurable<trackSelectionRequest> trackSels{"trackSels", {}, "track selections"};
76-
77-
Configurable<std::string> ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
78-
Configurable<std::string> lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"};
79-
Configurable<std::string> geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"};
80-
Configurable<std::string> grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"};
81-
Configurable<std::string> mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"};
82-
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"};
83-
84-
// Configurables regarding what to propagate
85-
// FIXME: This is dangerous and error prone for general purpose use. It is meant ONLY for testing.
86-
Configurable<bool> propagateUnassociated{"propagateUnassociated", false, "propagate tracks with no collision assoc"};
87-
Configurable<bool> propagateTPConly{"propagateTPConly", false, "propagate tracks with only TPC (no ITS, TRD, TOF)"};
88-
Configurable<int> minTPCClusters{"minTPCClusters", 70, "min number of TPC clusters to propagate"};
89-
Configurable<float> maxPropagStep{"maxPropagStep", 2.0, "max propag step"}; // to be checked systematically
90-
// use auto-detect configuration
91-
Configurable<bool> d_UseAutodetectMode{"d_UseAutodetectMode", false, "Autodetect requested track criteria"};
92-
93-
bool hasEnding(std::string const& fullString, std::string const& ending)
94-
{
95-
if (fullString.length() >= ending.length()) {
96-
return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
97-
} else {
98-
return false;
99-
}
100-
}
69+
HistogramRegistry registry{"registry"};
10170

10271
void init(o2::framework::InitContext& initContext)
10372
{
104-
const AxisSpec axisX{(int)4, 0.0f, +4.0f, "Track counter"};
105-
histos.add("hTrackCounter", "hTrackCounter", kTH1F, {axisX});
106-
107-
if (doprocessCovariance == true && doprocessStandard == true) {
108-
LOGF(fatal, "Cannot enable processStandard and processCovariance at the same time. Please choose one.");
109-
}
110-
111-
// Checking if the tables are requested in the workflow and enabling them
112-
auto& workflows = initContext.services().get<RunningWorkflowInfo const>();
113-
for (DeviceSpec const& device : workflows.devices) {
114-
for (auto const& input : device.inputs) {
115-
if (input.matcher.binding == "TracksDCA") {
116-
fillTracksDCA = true;
117-
}
118-
}
119-
}
120-
121-
ccdb->setURL(ccdburl);
73+
// CCDB boilerplate init
12274
ccdb->setCaching(true);
12375
ccdb->setLocalObjectValidityChecking();
76+
ccdb->setURL(ccdburl.value);
12477

125-
lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get<o2::base::MatLayerCylSet>(lutPath));
126-
127-
if (d_UseAutodetectMode) {
128-
LOGF(info, "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*");
129-
LOGF(info, " Track propagator self-configuration");
130-
LOGF(info, "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*");
131-
trackSels.SetTightSelections(); // Only loosen from this point forward
132-
for (DeviceSpec const& device : workflows.devices) {
133-
// Loop over options to find track selection
134-
for (auto const& option : device.options) {
135-
if (hasEnding(option.name, ".requireTPC")) {
136-
bool lVal = option.defaultValue.get<bool>();
137-
LOGF(info, "Device %s, request TPC: %i", device.name, lVal);
138-
if (trackSels.getRequireTPC() == false)
139-
trackSels.setRequireTPC(lVal);
140-
}
141-
if (hasEnding(option.name, ".minTPCclusters")) {
142-
int lVal = option.defaultValue.get<int>();
143-
LOGF(info, "Device %s, min TPC clusters: %i", device.name, lVal);
144-
if (trackSels.getMinTPCClusters() > lVal)
145-
trackSels.setMinTPCClusters(lVal);
146-
}
147-
if (hasEnding(option.name, ".minTPCcrossedrows")) {
148-
int lVal = option.defaultValue.get<int>();
149-
LOGF(info, "Device %s, min TPC crossed rows: %i", device.name, lVal);
150-
if (trackSels.getMinTPCCrossedRows() > lVal)
151-
trackSels.setMinTPCCrossedRows(lVal);
152-
}
153-
if (hasEnding(option.name, ".minTPCcrossedrowsoverfindable")) {
154-
float lVal = option.defaultValue.get<float>();
155-
LOGF(info, "Device %s, min TPC crossed rows over findable: %.3f", device.name, lVal);
156-
if (trackSels.getMinTPCCrossedRowsOverFindable() > lVal)
157-
trackSels.setMinTPCCrossedRowsOverFindable(lVal);
158-
}
159-
if (hasEnding(option.name, ".requireITS")) {
160-
bool lVal = option.defaultValue.get<bool>();
161-
LOGF(info, "Device %s, request ITS: %i", device.name, lVal);
162-
if (trackSels.getRequireITS() == false)
163-
trackSels.setRequireITS(lVal);
164-
}
165-
if (hasEnding(option.name, ".minITSclusters")) {
166-
int lVal = option.defaultValue.get<int>();
167-
LOGF(info, "Device %s, minimum ITS clusters: %i", device.name, lVal);
168-
if (trackSels.getMinITSClusters() > lVal)
169-
trackSels.setMinITSClusters(lVal);
170-
}
171-
if (hasEnding(option.name, ".maxITSChi2percluster")) {
172-
float lVal = option.defaultValue.get<float>();
173-
LOGF(info, "Device %s, max ITS chi2/clu: %.3f", device.name, lVal);
174-
if (trackSels.getMaxITSChi2PerCluster() < lVal)
175-
trackSels.setMaxITSChi2PerCluster(lVal);
176-
}
177-
}
178-
}
179-
LOGF(info, "-+*> Automatic self-config ended. Final settings:");
180-
trackSels.PrintSelections();
181-
}
182-
}
183-
184-
void initCCDB(aod::BCsWithTimestamps::iterator const& bc)
185-
{
186-
if (runNumber == bc.runNumber()) {
187-
return;
188-
}
189-
grpmag = ccdb->getForTimeStamp<o2::parameters::GRPMagField>(grpmagPath, bc.timestamp());
190-
LOG(info) << "Setting magnetic field to current " << grpmag->getL3Current() << " A for run " << bc.runNumber() << " from its GRPMagField CCDB object";
191-
o2::base::Propagator::initFieldFromGRP(grpmag);
192-
o2::base::Propagator::Instance()->setMatLUT(lut);
193-
if (propagateUnassociated)
194-
mVtx = ccdb->getForTimeStamp<o2::dataformats::MeanVertexObject>(mVtxPath, bc.timestamp());
195-
runNumber = bc.runNumber();
78+
// task-specific
79+
trackPropagation.init(trackPropagationConfigurables, registry, initContext);
19680
}
19781

198-
template <typename TTrack, typename TTrackPar>
199-
void FillTracksPar(TTrack& track, aod::track::TrackTypeEnum trackType, TTrackPar& trackPar)
82+
void processReal(soa::Join<aod::StoredTracksIU, aod::TracksCovIU, aod::TracksExtra> const& tracks, aod::Collisions const&, aod::BCs const& bcs)
20083
{
201-
tracksParPropagated(track.collisionId(), trackType, trackPar.getX(), trackPar.getAlpha(), trackPar.getY(), trackPar.getZ(), trackPar.getSnp(), trackPar.getTgl(), trackPar.getQ2Pt());
202-
tracksParExtensionPropagated(trackPar.getPt(), trackPar.getP(), trackPar.getEta(), trackPar.getPhi());
84+
// task-specific
85+
ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs);
86+
trackPropagation.fillTrackTables<false>(trackPropagationConfigurables, ccdbLoader, tracks, trackPropagationProducts, registry);
20387
}
88+
PROCESS_SWITCH(TrackPropagationTester, processReal, "Process Real Data", true);
20489

205-
void processStandard(soa::Join<aod::TracksIU, aod::TracksExtra> const& tracks, aod::Collisions const&, aod::BCsWithTimestamps const& bcs)
90+
// -----------------------
91+
void processMc(soa::Join<aod::StoredTracksIU, aod::McTrackLabels, aod::TracksCovIU, aod::TracksExtra> const& tracks, aod::McParticles const&, aod::Collisions const&, aod::BCs const& bcs)
20692
{
207-
if (bcs.size() == 0) {
208-
return;
209-
}
210-
initCCDB(bcs.begin());
211-
212-
std::array<float, 2> dcaInfo;
213-
214-
int lNAll = 0;
215-
int lNaccTPC = 0;
216-
int lNaccNotTPCOnly = 0;
217-
int lNPropagated = 0;
218-
bool passTPCclu = kFALSE;
219-
bool passNotTPCOnly = kFALSE;
220-
221-
for (auto& track : tracks) {
222-
// Selection criteria
223-
passTPCclu = kFALSE;
224-
passNotTPCOnly = kFALSE;
225-
lNAll++;
226-
if (track.tpcNClsFound() >= minTPCClusters) {
227-
passTPCclu = kTRUE;
228-
lNaccTPC++;
229-
}
230-
if ((track.hasTPC() && !track.hasITS() && !track.hasTRD() && !track.hasTOF()) || propagateTPConly) {
231-
passNotTPCOnly = kTRUE;
232-
lNaccNotTPCOnly++;
233-
}
234-
235-
dcaInfo[0] = 999;
236-
dcaInfo[1] = 999;
237-
aod::track::TrackTypeEnum trackType = (aod::track::TrackTypeEnum)track.trackType();
238-
auto trackPar = getTrackPar(track);
239-
// Only propagate tracks which have passed the innermost wall of the TPC (e.g. skipping loopers etc). Others fill unpropagated.
240-
if (track.trackType() == aod::track::TrackIU && track.x() < minPropagationRadius && passTPCclu && passNotTPCOnly) {
241-
if (track.has_collision()) {
242-
auto const& collision = track.collision();
243-
o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackPar, maxPropagStep, matCorr, &dcaInfo);
244-
trackType = aod::track::Track;
245-
lNPropagated++;
246-
} else {
247-
if (propagateUnassociated) {
248-
o2::base::Propagator::Instance()->propagateToDCABxByBz({mVtx->getX(), mVtx->getY(), mVtx->getZ()}, trackPar, maxPropagStep, matCorr, &dcaInfo);
249-
trackType = aod::track::Track;
250-
lNPropagated++;
251-
}
252-
}
253-
}
254-
FillTracksPar(track, trackType, trackPar);
255-
if (fillTracksDCA) {
256-
tracksDCA(dcaInfo[0], dcaInfo[1]);
257-
}
258-
}
259-
// Fill only per table (not per track). ROOT FindBin is slow
260-
histos.fill(HIST("hTrackCounter"), 0.5, lNAll);
261-
histos.fill(HIST("hTrackCounter"), 1.5, lNaccTPC);
262-
histos.fill(HIST("hTrackCounter"), 2.5, lNaccNotTPCOnly);
263-
histos.fill(HIST("hTrackCounter"), 3.5, lNPropagated);
264-
}
265-
PROCESS_SWITCH(TrackPropagationTester, processStandard, "Process without covariance", true);
266-
267-
void processCovariance(soa::Join<aod::TracksIU, aod::TracksCovIU, aod::TracksExtra> const& tracks, aod::Collisions const&, aod::BCsWithTimestamps const& bcs)
268-
{
269-
if (bcs.size() == 0) {
270-
return;
271-
}
272-
initCCDB(bcs.begin());
273-
274-
o2::dataformats::DCA dcaInfoCov;
275-
o2::dataformats::VertexBase vtx;
276-
277-
int lNAll = 0;
278-
int lNaccTPC = 0;
279-
int lNaccNotTPCOnly = 0;
280-
int lNPropagated = 0;
281-
bool passTPCclu = kFALSE;
282-
bool passNotTPCOnly = kFALSE;
283-
284-
for (auto& track : tracks) {
285-
// Selection criteria
286-
passTPCclu = kFALSE;
287-
passNotTPCOnly = kFALSE;
288-
lNAll++;
289-
if (track.tpcNClsFound() >= minTPCClusters) {
290-
passTPCclu = kTRUE;
291-
lNaccTPC++;
292-
}
293-
if ((track.hasTPC() && !track.hasITS() && !track.hasTRD() && !track.hasTOF()) || propagateTPConly) {
294-
passNotTPCOnly = kTRUE;
295-
lNaccNotTPCOnly++;
296-
}
297-
298-
dcaInfoCov.set(999, 999, 999, 999, 999);
299-
auto trackParCov = getTrackParCov(track);
300-
aod::track::TrackTypeEnum trackType = (aod::track::TrackTypeEnum)track.trackType();
301-
// Only propagate tracks which have passed the innermost wall of the TPC (e.g. skipping loopers etc). Others fill unpropagated.
302-
if (track.trackType() == aod::track::TrackIU && track.x() < minPropagationRadius && passTPCclu && passNotTPCOnly) {
303-
if (track.has_collision()) {
304-
auto const& collision = track.collision();
305-
vtx.setPos({collision.posX(), collision.posY(), collision.posZ()});
306-
vtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ());
307-
o2::base::Propagator::Instance()->propagateToDCABxByBz(vtx, trackParCov, maxPropagStep, matCorr, &dcaInfoCov);
308-
trackType = aod::track::Track;
309-
lNPropagated++;
310-
} else {
311-
if (propagateUnassociated) {
312-
vtx.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()});
313-
vtx.setCov(mVtx->getSigmaX() * mVtx->getSigmaX(), 0.0f, mVtx->getSigmaY() * mVtx->getSigmaY(), 0.0f, 0.0f, mVtx->getSigmaZ() * mVtx->getSigmaZ());
314-
o2::base::Propagator::Instance()->propagateToDCABxByBz(vtx, trackParCov, maxPropagStep, matCorr, &dcaInfoCov);
315-
trackType = aod::track::Track;
316-
lNPropagated++;
317-
}
318-
}
319-
}
320-
FillTracksPar(track, trackType, trackParCov);
321-
if (fillTracksDCA) {
322-
tracksDCA(dcaInfoCov.getY(), dcaInfoCov.getZ());
323-
}
324-
// TODO do we keep the rho as 0? Also the sigma's are duplicated information
325-
tracksParCovPropagated(std::sqrt(trackParCov.getSigmaY2()), std::sqrt(trackParCov.getSigmaZ2()), std::sqrt(trackParCov.getSigmaSnp2()),
326-
std::sqrt(trackParCov.getSigmaTgl2()), std::sqrt(trackParCov.getSigma1Pt2()), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
327-
tracksParCovExtensionPropagated(trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), trackParCov.getSigmaSnpY(),
328-
trackParCov.getSigmaSnpZ(), trackParCov.getSigmaSnp2(), trackParCov.getSigmaTglY(), trackParCov.getSigmaTglZ(), trackParCov.getSigmaTglSnp(),
329-
trackParCov.getSigmaTgl2(), trackParCov.getSigma1PtY(), trackParCov.getSigma1PtZ(), trackParCov.getSigma1PtSnp(), trackParCov.getSigma1PtTgl(),
330-
trackParCov.getSigma1Pt2());
331-
}
332-
// Fill only per table (not per track). ROOT FindBin is slow
333-
histos.fill(HIST("hTrackCounter"), 0.5, lNAll);
334-
histos.fill(HIST("hTrackCounter"), 1.5, lNaccTPC);
335-
histos.fill(HIST("hTrackCounter"), 2.5, lNaccNotTPCOnly);
336-
histos.fill(HIST("hTrackCounter"), 3.5, lNPropagated);
93+
ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs);
94+
trackPropagation.fillTrackTables<false>(trackPropagationConfigurables, ccdbLoader, tracks, trackPropagationProducts, registry);
33795
}
338-
PROCESS_SWITCH(TrackPropagationTester, processCovariance, "Process with covariance", false);
96+
PROCESS_SWITCH(TrackPropagationTester, processMc, "Process Monte Carlo", false);
33997
};
34098

34199
//****************************************************************************************

0 commit comments

Comments
 (0)