Project
Loading...
Searching...
No Matches
Tracker.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
15
16#include "ITStracking/Tracker.h"
17
18#include "ITStracking/Cell.h"
25
27#include <cassert>
28#include <format>
29#include <cstdlib>
30#include <string>
31#include <climits>
32
33namespace o2
34{
35namespace its
36{
38
39Tracker::Tracker(o2::its::TrackerTraits* traits) : mTraits(traits)
40{
42 mTrkParams.resize(1);
43}
44
45void Tracker::clustersToTracks(LogFunc logger, LogFunc error)
46{
47 LogFunc evalLog = [](const std::string&) {};
48
49 double total{0};
50 mTraits->UpdateTrackingParameters(mTrkParams);
51 int maxNvertices{-1};
52 if (mTrkParams[0].PerPrimaryVertexProcessing) {
53 for (int iROF{0}; iROF < mTimeFrame->getNrof(); ++iROF) {
54 maxNvertices = std::max(maxNvertices, (int)mTimeFrame->getPrimaryVertices(iROF).size());
55 }
56 }
57
58 bool dropTF = false;
59 for (int iteration = 0; iteration < (int)mTrkParams.size(); ++iteration) {
60 if (iteration == 3 && mTrkParams[0].DoUPCIteration) {
61 mTimeFrame->swapMasks();
62 }
63 double timeTracklets{0.}, timeCells{0.}, timeNeighbours{0.}, timeRoads{0.};
64 int nTracklets{0}, nCells{0}, nNeighbours{0}, nTracks{-static_cast<int>(mTimeFrame->getNumberOfTracks())};
65 int nROFsIterations = mTrkParams[iteration].nROFsPerIterations > 0 ? mTimeFrame->getNrof() / mTrkParams[iteration].nROFsPerIterations + bool(mTimeFrame->getNrof() % mTrkParams[iteration].nROFsPerIterations) : 1;
66 int iVertex{std::min(maxNvertices, 0)};
67 logger(std::format("==== ITS {} Tracking iteration {} summary ====", mTraits->getName(), iteration));
68
69 total += evaluateTask(&Tracker::initialiseTimeFrame, "Timeframe initialisation", logger, iteration);
70 do {
71 for (int iROFs{0}; iROFs < nROFsIterations; ++iROFs) {
72 timeTracklets += evaluateTask(&Tracker::computeTracklets, "Tracklet finding", evalLog, iteration, iROFs, iVertex);
73 nTracklets += mTraits->getTFNumberOfTracklets();
74 if (!mTimeFrame->checkMemory(mTrkParams[iteration].MaxMemory)) {
75 mTimeFrame->printSliceInfo(iROFs, mTrkParams[iteration].nROFsPerIterations);
76 error(std::format("Too much memory used during trackleting in iteration {} in ROF span {}-{}: {:.2f} GB. Current limit is {:.2f} GB, check the detector status and/or the selections.",
77 iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTimeFrame->getArtefactsMemory() / GB, mTrkParams[iteration].MaxMemory / GB));
78 if (mTrkParams[iteration].DropTFUponFailure) {
79 dropTF = true;
80 }
81 break;
82 }
83 float trackletsPerCluster = mTraits->getTFNumberOfClusters() > 0 ? float(mTraits->getTFNumberOfTracklets()) / mTraits->getTFNumberOfClusters() : 0.f;
84 if (trackletsPerCluster > mTrkParams[iteration].TrackletsPerClusterLimit) {
85 error(std::format("Too many tracklets per cluster ({}) in iteration {} in ROF span {}-{}:, check the detector status and/or the selections. Current limit is {}",
86 trackletsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].TrackletsPerClusterLimit));
87 break;
88 }
89
90 timeCells += evaluateTask(&Tracker::computeCells, "Cell finding", evalLog, iteration);
91 nCells += mTraits->getTFNumberOfCells();
92 if (!mTimeFrame->checkMemory(mTrkParams[iteration].MaxMemory)) {
93 mTimeFrame->printSliceInfo(iROFs, mTrkParams[iteration].nROFsPerIterations);
94 error(std::format("Too much memory used during cell finding in iteration {} in ROF span {}-{}: {:.2f} GB. Current limit is {:.2f} GB, check the detector status and/or the selections.",
95 iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTimeFrame->getArtefactsMemory() / GB, mTrkParams[iteration].MaxMemory / GB));
96 if (mTrkParams[iteration].DropTFUponFailure) {
97 dropTF = true;
98 }
99 break;
100 }
101 float cellsPerCluster = mTraits->getTFNumberOfClusters() > 0 ? float(mTraits->getTFNumberOfCells()) / mTraits->getTFNumberOfClusters() : 0.f;
102 if (cellsPerCluster > mTrkParams[iteration].CellsPerClusterLimit) {
103 error(std::format("Too many cells per cluster ({}) in iteration {} in ROF span {}-{}, check the detector status and/or the selections. Current limit is {}",
104 cellsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].CellsPerClusterLimit));
105 break;
106 }
107
108 timeNeighbours += evaluateTask(&Tracker::findCellsNeighbours, "Neighbour finding", evalLog, iteration);
109 nNeighbours += mTimeFrame->getNumberOfNeighbours();
110 timeRoads += evaluateTask(&Tracker::findRoads, "Road finding", evalLog, iteration);
111 }
112 iVertex++;
113 } while (iVertex < maxNvertices && !dropTF);
114 logger(std::format(" - Tracklet finding: {} tracklets found in {:.2f} ms", nTracklets, timeTracklets));
115 logger(std::format(" - Cell finding: {} cells found in {:.2f} ms", nCells, timeCells));
116 logger(std::format(" - Neighbours finding: {} neighbours found in {:.2f} ms", nNeighbours, timeNeighbours));
117 logger(std::format(" - Track finding: {} tracks found in {:.2f} ms", nTracks + mTimeFrame->getNumberOfTracks(), timeRoads));
118 total += timeTracklets + timeCells + timeNeighbours + timeRoads;
119 if (mTraits->supportsExtendTracks() && mTrkParams[iteration].UseTrackFollower && !dropTF) {
120 int nExtendedTracks{-mTimeFrame->mNExtendedTracks}, nExtendedClusters{-mTimeFrame->mNExtendedUsedClusters};
121 auto timeExtending = evaluateTask(&Tracker::extendTracks, "Extending tracks", [](const std::string&) {}, iteration);
122 total += timeExtending;
123 logger(std::format(" - Extending Tracks: {} extended tracks using {} clusters found in {:.2f} ms", nExtendedTracks + mTimeFrame->mNExtendedTracks, nExtendedClusters + mTimeFrame->mNExtendedUsedClusters, timeExtending));
124 }
125 if (dropTF) {
126 error("...Dropping Timeframe...");
127 mTimeFrame->dropTracks();
128 ++mNumberOfDroppedTFs;
129 return;
130 }
131 }
132
133 if (mTraits->supportsFindShortPrimaries() && mTrkParams[0].FindShortTracks) {
134 auto nTracksB = mTimeFrame->getNumberOfTracks();
135 total += evaluateTask(&Tracker::findShortPrimaries, "Short primaries finding", logger);
136 auto nTracksA = mTimeFrame->getNumberOfTracks();
137 logger(std::format(" `-> found {} additional tracks", nTracksA - nTracksB));
138 }
139
140 if constexpr (constants::DoTimeBenchmarks) {
141 logger(std::format("=== TimeFrame {} processing completed in: {:.2f} ms using {} thread(s) ===", mTimeFrameCounter, total, mTraits->getNThreads()));
142 }
143
144 if (mTimeFrame->hasMCinformation()) {
145 computeTracksMClabels();
146 }
147 rectifyClusterIndices();
148 ++mTimeFrameCounter;
149 mTotalTime += total;
150}
151
152void Tracker::initialiseTimeFrame(int& iteration)
153{
154 mTraits->initialiseTimeFrame(iteration);
155}
156
157void Tracker::computeTracklets(int& iteration, int& iROFslice, int& iVertex)
158{
159 mTraits->computeLayerTracklets(iteration, iROFslice, iVertex);
160}
161
162void Tracker::computeCells(int& iteration)
163{
164 mTraits->computeLayerCells(iteration);
165}
166
167void Tracker::findCellsNeighbours(int& iteration)
168{
169 mTraits->findCellsNeighbours(iteration);
170}
171
172void Tracker::findRoads(int& iteration)
173{
174 mTraits->findRoads(iteration);
175}
176
177void Tracker::extendTracks(int& iteration)
178{
179 mTraits->extendTracks(iteration);
180}
181
182void Tracker::findShortPrimaries()
183{
184 mTraits->findShortPrimaries();
185}
186
187void Tracker::computeRoadsMClabels()
188{
190 if (!mTimeFrame->hasMCinformation()) {
191 return;
192 }
193
194 mTimeFrame->initialiseRoadLabels();
195
196 int roadsNum{static_cast<int>(mTimeFrame->getRoads().size())};
197
198 for (int iRoad{0}; iRoad < roadsNum; ++iRoad) {
199
200 Road<5>& currentRoad{mTimeFrame->getRoads()[iRoad]};
201 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
202 bool isFakeRoad{false};
203 bool isFirstRoadCell{true};
204
205 for (int iCell{0}; iCell < mTrkParams[0].CellsPerRoad(); ++iCell) {
206 const int currentCellIndex{currentRoad[iCell]};
207
208 if (currentCellIndex == constants::its::UnusedIndex) {
209 if (isFirstRoadCell) {
210 continue;
211 } else {
212 break;
213 }
214 }
215
216 const CellSeed& currentCell{mTimeFrame->getCells()[iCell][currentCellIndex]};
217
218 if (isFirstRoadCell) {
219
220 const int cl0index{mTimeFrame->getClusters()[iCell][currentCell.getFirstClusterIndex()].clusterId};
221 auto cl0labs{mTimeFrame->getClusterLabels(iCell, cl0index)};
222 bool found{false};
223 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
224 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
225 for (auto& label : cl0labs) {
226 if (label == occurrence.first) {
227 ++occurrence.second;
228 found = true;
229 // break; // uncomment to stop to the first hit
230 }
231 }
232 }
233 if (!found) {
234 for (auto& label : cl0labs) {
235 occurrences.emplace_back(label, 1);
236 }
237 }
238
239 const int cl1index{mTimeFrame->getClusters()[iCell + 1][currentCell.getSecondClusterIndex()].clusterId};
240
241 const auto& cl1labs{mTimeFrame->getClusterLabels(iCell + 1, cl1index)};
242 found = false;
243 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
244 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
245 for (auto& label : cl1labs) {
246 if (label == occurrence.first) {
247 ++occurrence.second;
248 found = true;
249 // break; // uncomment to stop to the first hit
250 }
251 }
252 }
253 if (!found) {
254 for (auto& label : cl1labs) {
255 occurrences.emplace_back(label, 1);
256 }
257 }
258
259 isFirstRoadCell = false;
260 }
261
262 const int cl2index{mTimeFrame->getClusters()[iCell + 2][currentCell.getThirdClusterIndex()].clusterId};
263 const auto& cl2labs{mTimeFrame->getClusterLabels(iCell + 2, cl2index)};
264 bool found{false};
265 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
266 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
267 for (auto& label : cl2labs) {
268 if (label == occurrence.first) {
269 ++occurrence.second;
270 found = true;
271 // break; // uncomment to stop to the first hit
272 }
273 }
274 }
275 if (!found) {
276 for (auto& label : cl2labs) {
277 occurrences.emplace_back(label, 1);
278 }
279 }
280 }
281
282 std::sort(occurrences.begin(), occurrences.end(), [](auto e1, auto e2) {
283 return e1.second > e2.second;
284 });
285
286 auto maxOccurrencesValue = occurrences[0].first;
287 mTimeFrame->setRoadLabel(iRoad, maxOccurrencesValue.getRawValue(), isFakeRoad);
288 }
289}
290
291void Tracker::computeTracksMClabels()
292{
293 for (int iROF{0}; iROF < mTimeFrame->getNrof(); ++iROF) {
294 for (auto& track : mTimeFrame->getTracks(iROF)) {
295 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
296 occurrences.clear();
297
298 for (int iCluster = 0; iCluster < TrackITSExt::MaxClusters; ++iCluster) {
299 const int index = track.getClusterIndex(iCluster);
301 continue;
302 }
303 auto labels = mTimeFrame->getClusterLabels(iCluster, index);
304 bool found{false};
305 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
306 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
307 for (auto& label : labels) {
308 if (label == occurrence.first) {
309 ++occurrence.second;
310 found = true;
311 // break; // uncomment to stop to the first hit
312 }
313 }
314 }
315 if (!found) {
316 for (auto& label : labels) {
317 occurrences.emplace_back(label, 1);
318 }
319 }
320 }
321 std::sort(std::begin(occurrences), std::end(occurrences), [](auto e1, auto e2) {
322 return e1.second > e2.second;
323 });
324
325 auto maxOccurrencesValue = occurrences[0].first;
326 uint32_t pattern = track.getPattern();
327 // set fake clusters pattern
328 for (int ic{TrackITSExt::MaxClusters}; ic--;) {
329 auto clid = track.getClusterIndex(ic);
330 if (clid != constants::its::UnusedIndex) {
331 auto labelsSpan = mTimeFrame->getClusterLabels(ic, clid);
332 for (auto& currentLabel : labelsSpan) {
333 if (currentLabel == maxOccurrencesValue) {
334 pattern |= 0x1 << (16 + ic); // set bit if correct
335 break;
336 }
337 }
338 }
339 }
340 track.setPattern(pattern);
341 if (occurrences[0].second < track.getNumberOfClusters()) {
342 maxOccurrencesValue.setFakeFlag();
343 }
344 mTimeFrame->getTracksLabel(iROF).emplace_back(maxOccurrencesValue);
345 }
346 }
347}
348
349void Tracker::rectifyClusterIndices()
350{
351 for (int iROF{0}; iROF < mTimeFrame->getNrof(); ++iROF) {
352 for (auto& track : mTimeFrame->getTracks(iROF)) {
353 for (int iCluster = 0; iCluster < TrackITSExt::MaxClusters; ++iCluster) {
354 const int index = track.getClusterIndex(iCluster);
356 track.setExternalClusterIndex(iCluster, mTimeFrame->getClusterExternalIndex(iCluster, index));
357 }
358 }
359 }
360 }
361}
362
364{
366 if (tc.useMatCorrTGeo) {
368 } else if (tc.useFastMaterial) {
370 } else {
372 }
373 setNThreads(tc.nThreads);
374 int nROFsPerIterations = tc.nROFsPerIterations > 0 ? tc.nROFsPerIterations : -1;
375 if (tc.nOrbitsPerIterations > 0) {
377 }
378 for (auto& params : mTrkParams) {
379 if (params.NLayers == 7) {
380 for (int i{0}; i < 7; ++i) {
381 params.SystErrorY2[i] = tc.sysErrY2[i] > 0 ? tc.sysErrY2[i] : params.SystErrorY2[i];
382 params.SystErrorZ2[i] = tc.sysErrZ2[i] > 0 ? tc.sysErrZ2[i] : params.SystErrorZ2[i];
383 }
384 }
385 params.DeltaROF = tc.deltaRof;
386 params.DoUPCIteration = tc.doUPCIteration;
387 params.MaxChi2ClusterAttachment = tc.maxChi2ClusterAttachment > 0 ? tc.maxChi2ClusterAttachment : params.MaxChi2ClusterAttachment;
388 params.MaxChi2NDF = tc.maxChi2NDF > 0 ? tc.maxChi2NDF : params.MaxChi2NDF;
389 params.PhiBins = tc.LUTbinsPhi > 0 ? tc.LUTbinsPhi : params.PhiBins;
390 params.ZBins = tc.LUTbinsZ > 0 ? tc.LUTbinsZ : params.ZBins;
391 params.PVres = tc.pvRes > 0 ? tc.pvRes : params.PVres;
392 params.NSigmaCut *= tc.nSigmaCut > 0 ? tc.nSigmaCut : 1.f;
393 params.CellDeltaTanLambdaSigma *= tc.deltaTanLres > 0 ? tc.deltaTanLres : 1.f;
394 params.TrackletMinPt *= tc.minPt > 0 ? tc.minPt : 1.f;
395 params.nROFsPerIterations = nROFsPerIterations;
396 params.PerPrimaryVertexProcessing = tc.perPrimaryVertexProcessing;
397 params.SaveTimeBenchmarks = tc.saveTimeBenchmarks;
398 params.FataliseUponFailure = tc.fataliseUponFailure;
399 params.DropTFUponFailure = tc.dropTFUponFailure;
400 for (int iD{0}; iD < 3; ++iD) {
401 params.Diamond[iD] = tc.diamondPos[iD];
402 }
403 params.UseDiamond = tc.useDiamond;
404 if (tc.maxMemory) {
405 params.MaxMemory = tc.maxMemory;
406 }
407 if (tc.useTrackFollower > 0) {
408 params.UseTrackFollower = true;
409 // Bit 0: Allow for mixing of top&bot extension --> implies Bits 1&2 set
410 // Bit 1: Allow for top extension
411 // Bit 2: Allow for bot extension
412 params.UseTrackFollowerMix = ((tc.useTrackFollower & (1 << 0)) != 0);
413 params.UseTrackFollowerTop = ((tc.useTrackFollower & (1 << 1)) != 0);
414 params.UseTrackFollowerBot = ((tc.useTrackFollower & (1 << 2)) != 0);
415 params.TrackFollowerNSigmaCutZ = tc.trackFollowerNSigmaZ;
416 params.TrackFollowerNSigmaCutPhi = tc.trackFollowerNSigmaPhi;
417 }
418 if (tc.cellsPerClusterLimit >= 0) {
419 params.CellsPerClusterLimit = tc.cellsPerClusterLimit;
420 }
421 if (tc.trackletsPerClusterLimit >= 0) {
422 params.TrackletsPerClusterLimit = tc.trackletsPerClusterLimit;
423 }
424 if (tc.findShortTracks >= 0) {
425 params.FindShortTracks = tc.findShortTracks;
426 }
427 }
428}
429
431{
432 mTimeFrame = &tf;
433 mTraits->adoptTimeFrame(&tf);
434}
435
436void Tracker::setBz(float bz)
437{
438 mTraits->setBz(bz);
439}
440
445
447{
448 return mTraits->isMatLUT();
449}
450
452{
453 mTraits->setNThreads(n);
454}
455
457{
458 return mTraits->getNThreads();
459}
460
462{
463 LOGP(info, "Tracker summary: Processed {} TFs (dropped {}) in TOT={:.2f} s, AVG/TF={:.2f} s", mTimeFrameCounter, mNumberOfDroppedTFs, mTotalTime * 1.e-3, mTotalTime * 1.e-3 / ((mTimeFrameCounter > 0) ? (double)mTimeFrameCounter : -1.0));
464}
465
466} // namespace its
467} // namespace o2
Base track model for the Barrel, params only, w/o covariance.
int32_t i
#define GB
Definition Utils.h:40
Class to handle Kalman smoothing for ITS tracking. Its instance stores the state of the track to the ...
gsl::span< const Vertex > getPrimaryVertices(int rofId) const
Definition TimeFrame.h:355
unsigned long getArtefactsMemory()
void setRoadLabel(int i, const unsigned long long &lab, bool fake)
Definition TimeFrame.h:598
std::vector< std::vector< CellSeed > > & getCells()
Definition TimeFrame.h:648
std::vector< MCCompLabel > & getTracksLabel(const int rofId)
Definition TimeFrame.h:170
bool hasMCinformation() const
Definition TimeFrame.h:565
std::vector< std::vector< Cluster > > & getClusters()
Definition TimeFrame.h:638
void initialiseRoadLabels()
Definition TimeFrame.h:592
std::vector< Road< 5 > > & getRoads()
Definition TimeFrame.h:658
size_t getNumberOfTracks() const
Definition TimeFrame.h:723
bool checkMemory(unsigned long max)
Definition TimeFrame.h:183
int getNrof() const
Definition TimeFrame.h:395
int getNumberOfNeighbours() const
Definition TimeFrame.h:714
int getClusterExternalIndex(int layerId, const int clId) const
Definition TimeFrame.h:524
const gsl::span< const MCCompLabel > getClusterLabels(int layerId, const Cluster &cl) const
Definition TimeFrame.h:509
void printSliceInfo(const int, const int)
static constexpr int MaxClusters
< heavy version of TrackITS, with clusters embedded
Definition TrackITS.h:169
virtual void findRoads(const int iteration)
virtual void extendTracks(const int iteration)
virtual int getTFNumberOfCells() const
virtual void adoptTimeFrame(TimeFrame *tf)
virtual void computeLayerTracklets(const int iteration, int iROFslice, int iVertex)
virtual void setBz(float bz)
virtual bool supportsFindShortPrimaries() const noexcept
virtual int getTFNumberOfTracklets() const
virtual void findCellsNeighbours(const int iteration)
virtual int getTFNumberOfClusters() const
virtual void findShortPrimaries()
virtual void initialiseTimeFrame(const int iteration)
void UpdateTrackingParameters(const std::vector< TrackingParameters > &trkPars)
void setCorrType(const o2::base::PropagatorImpl< float >::MatCorrType type)
virtual void computeLayerCells(const int iteration)
virtual bool supportsExtendTracks() const noexcept
virtual const char * getName() const noexcept
void adoptTimeFrame(TimeFrame &tf)
Definition Tracker.cxx:430
void setCorrType(const o2::base::PropagatorImpl< float >::MatCorrType type)
Definition Tracker.cxx:441
void printSummary() const
Definition Tracker.cxx:461
bool isMatLUT() const
Definition Tracker.cxx:446
void getGlobalConfiguration()
Definition Tracker.cxx:363
Tracker(TrackerTraits *traits)
Definition Tracker.cxx:39
int getNThreads() const
Definition Tracker.cxx:456
void setBz(float)
Definition Tracker.cxx:436
void setNThreads(int n)
Definition Tracker.cxx:451
void clustersToTracks(LogFunc=[](std::string s) { std::cout<< s<< std::endl;}, LogFunc=[](std::string s) { std::cerr<< s<< std::endl;})
Definition Tracker.cxx:45
GLdouble n
Definition glcorearb.h:1982
GLuint index
Definition glcorearb.h:781
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLenum const GLfloat * params
Definition glcorearb.h:272
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
constexpr int UnusedIndex
Definition Constants.h:54
constexpr float GB
Definition Constants.h:39
constexpr bool DoTimeBenchmarks
Definition Constants.h:40
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::unique_ptr< GPUReconstructionTimeframe > tf
std::array< uint16_t, 5 > pattern