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
19#include "ITStracking/Cell.h"
26
28#include <cassert>
29#include <format>
30#include <cstdlib>
31#include <string>
32#include <climits>
33
34namespace o2::its
35{
37
38Tracker::Tracker(TrackerTraits7* traits) : mTraits(traits)
39{
41 mTrkParams.resize(1);
42}
43
44void Tracker::clustersToTracks(LogFunc logger, LogFunc error)
45{
46 LogFunc evalLog = [](const std::string&) {};
47
48 double total{0};
49 mTraits->updateTrackingParameters(mTrkParams);
50 int maxNvertices{-1};
51 if (mTrkParams[0].PerPrimaryVertexProcessing) {
52 for (int iROF{0}; iROF < mTimeFrame->getNrof(); ++iROF) {
53 maxNvertices = std::max(maxNvertices, (int)mTimeFrame->getPrimaryVertices(iROF).size());
54 }
55 }
56
57 int iteration{0}, iROFs{0}, iVertex{0};
58 auto handleException = [&](const auto& err) {
59 LOGP(error, "Too much memory used during {} in iteration {} in ROF span {}-{} iVtx={}: {:.2f} GB. Current limit is {:.2f} GB, check the detector status and/or the selections.",
60 StateNames[mCurState], iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, iVertex,
61 (double)mTimeFrame->getArtefactsMemory() / GB, (double)mTrkParams[iteration].MaxMemory / GB);
62 LOGP(error, "Exception: {}", err.what());
63 if (mTrkParams[iteration].DropTFUponFailure) {
64 mTimeFrame->wipe();
65 mMemoryPool->print();
66 ++mNumberOfDroppedTFs;
67 error("...Dropping Timeframe...");
68 } else {
69 throw err;
70 }
71 };
72
73 try {
74 for (iteration = 0; iteration < (int)mTrkParams.size(); ++iteration) {
75 mMemoryPool->setMaxMemory(mTrkParams[iteration].MaxMemory);
76 if (iteration == 3 && mTrkParams[0].DoUPCIteration) {
77 mTimeFrame->swapMasks();
78 }
79 double timeTracklets{0.}, timeCells{0.}, timeNeighbours{0.}, timeRoads{0.};
80 int nTracklets{0}, nCells{0}, nNeighbours{0}, nTracks{-static_cast<int>(mTimeFrame->getNumberOfTracks())};
81 int nROFsIterations = mTrkParams[iteration].nROFsPerIterations > 0 ? mTimeFrame->getNrof() / mTrkParams[iteration].nROFsPerIterations + bool(mTimeFrame->getNrof() % mTrkParams[iteration].nROFsPerIterations) : 1;
82 int iVertex{std::min(maxNvertices, 0)};
83 logger(std::format("==== ITS {} Tracking iteration {} summary ====", mTraits->getName(), iteration));
84
85 total += evaluateTask(&Tracker::initialiseTimeFrame, StateNames[mCurState = TFInit], iteration, logger, iteration);
86 do {
87 for (iROFs = 0; iROFs < nROFsIterations; ++iROFs) {
88 timeTracklets += evaluateTask(&Tracker::computeTracklets, StateNames[mCurState = Trackleting], iteration, evalLog, iteration, iROFs, iVertex);
89 nTracklets += mTraits->getTFNumberOfTracklets();
90 float trackletsPerCluster = mTraits->getTFNumberOfClusters() > 0 ? float(mTraits->getTFNumberOfTracklets()) / float(mTraits->getTFNumberOfClusters()) : 0.f;
91 if (trackletsPerCluster > mTrkParams[iteration].TrackletsPerClusterLimit) {
92 error(std::format("Too many tracklets per cluster ({}) in iteration {} in ROF span {}-{}:, check the detector status and/or the selections. Current limit is {}",
93 trackletsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].TrackletsPerClusterLimit));
94 break;
95 }
96 timeCells += evaluateTask(&Tracker::computeCells, StateNames[mCurState = Celling], iteration, evalLog, iteration);
97 nCells += mTraits->getTFNumberOfCells();
98 float cellsPerCluster = mTraits->getTFNumberOfClusters() > 0 ? float(mTraits->getTFNumberOfCells()) / float(mTraits->getTFNumberOfClusters()) : 0.f;
99 if (cellsPerCluster > mTrkParams[iteration].CellsPerClusterLimit) {
100 error(std::format("Too many cells per cluster ({}) in iteration {} in ROF span {}-{}, check the detector status and/or the selections. Current limit is {}",
101 cellsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].CellsPerClusterLimit));
102 break;
103 }
104 timeNeighbours += evaluateTask(&Tracker::findCellsNeighbours, StateNames[mCurState = Neighbouring], iteration, evalLog, iteration);
105 nNeighbours += mTimeFrame->getNumberOfNeighbours();
106 timeRoads += evaluateTask(&Tracker::findRoads, StateNames[mCurState = Roading], iteration, evalLog, iteration);
107 }
108 iVertex++;
109 } while (iVertex < maxNvertices);
110 logger(std::format(" - Tracklet finding: {} tracklets found in {:.2f} ms", nTracklets, timeTracklets));
111 logger(std::format(" - Cell finding: {} cells found in {:.2f} ms", nCells, timeCells));
112 logger(std::format(" - Neighbours finding: {} neighbours found in {:.2f} ms", nNeighbours, timeNeighbours));
113 logger(std::format(" - Track finding: {} tracks found in {:.2f} ms", nTracks + mTimeFrame->getNumberOfTracks(), timeRoads));
114 total += timeTracklets + timeCells + timeNeighbours + timeRoads;
115 if (mTraits->supportsExtendTracks() && mTrkParams[iteration].UseTrackFollower) {
116 int nExtendedTracks{-mTimeFrame->mNExtendedTracks}, nExtendedClusters{-mTimeFrame->mNExtendedUsedClusters};
117 auto timeExtending = evaluateTask(&Tracker::extendTracks, "Extending tracks", iteration, evalLog, iteration);
118 total += timeExtending;
119 logger(std::format(" - Extending Tracks: {} extended tracks using {} clusters found in {:.2f} ms", nExtendedTracks + mTimeFrame->mNExtendedTracks, nExtendedClusters + mTimeFrame->mNExtendedUsedClusters, timeExtending));
120 }
121 if (mTrkParams[iteration].PrintMemory) {
122 mMemoryPool->print();
123 }
124 }
125 if (mTraits->supportsFindShortPrimaries() && mTrkParams[0].FindShortTracks) {
126 auto nTracksB = mTimeFrame->getNumberOfTracks();
127 total += evaluateTask(&Tracker::findShortPrimaries, "Short primaries finding", 0, logger);
128 auto nTracksA = mTimeFrame->getNumberOfTracks();
129 logger(std::format(" `-> found {} additional tracks", nTracksA - nTracksB));
130 }
131 if (mTrkParams[iteration].PrintMemory) {
132 mMemoryPool->print();
133 }
134 if constexpr (constants::DoTimeBenchmarks) {
135 logger(std::format("=== TimeFrame {} processing completed in: {:.2f} ms using {} thread(s) ===", mTimeFrameCounter, total, mTraits->getNThreads()));
136 }
137 } catch (const BoundedMemoryResource::MemoryLimitExceeded& err) {
138 handleException(err);
139 return;
140 } catch (const std::bad_alloc& err) {
141 handleException(err);
142 return;
143 } catch (...) {
144 error("Uncaught exception, all bets are off...");
145 }
146
147 if (mTrkParams[0].PrintMemory) {
148 mTimeFrame->printArtefactsMemory();
149 mMemoryPool->print();
150 }
151
152 if (mTimeFrame->hasMCinformation()) {
153 computeTracksMClabels();
154 }
155 rectifyClusterIndices();
156 ++mTimeFrameCounter;
157 mTotalTime += total;
158}
159
160void Tracker::computeRoadsMClabels()
161{
163 if (!mTimeFrame->hasMCinformation()) {
164 return;
165 }
166
167 mTimeFrame->initialiseRoadLabels();
168
169 int roadsNum{static_cast<int>(mTimeFrame->getRoads().size())};
170
171 for (int iRoad{0}; iRoad < roadsNum; ++iRoad) {
172
173 Road<5>& currentRoad{mTimeFrame->getRoads()[iRoad]};
174 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
175 bool isFakeRoad{false};
176 bool isFirstRoadCell{true};
177
178 for (int iCell{0}; iCell < mTrkParams[0].CellsPerRoad(); ++iCell) {
179 const int currentCellIndex{currentRoad[iCell]};
180
181 if (currentCellIndex == constants::its::UnusedIndex) {
182 if (isFirstRoadCell) {
183 continue;
184 } else {
185 break;
186 }
187 }
188
189 const CellSeed& currentCell{mTimeFrame->getCells()[iCell][currentCellIndex]};
190
191 if (isFirstRoadCell) {
192
193 const int cl0index{mTimeFrame->getClusters()[iCell][currentCell.getFirstClusterIndex()].clusterId};
194 auto cl0labs{mTimeFrame->getClusterLabels(iCell, cl0index)};
195 bool found{false};
196 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
197 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
198 for (auto& label : cl0labs) {
199 if (label == occurrence.first) {
200 ++occurrence.second;
201 found = true;
202 // break; // uncomment to stop to the first hit
203 }
204 }
205 }
206 if (!found) {
207 for (auto& label : cl0labs) {
208 occurrences.emplace_back(label, 1);
209 }
210 }
211
212 const int cl1index{mTimeFrame->getClusters()[iCell + 1][currentCell.getSecondClusterIndex()].clusterId};
213
214 const auto& cl1labs{mTimeFrame->getClusterLabels(iCell + 1, cl1index)};
215 found = false;
216 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
217 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
218 for (auto& label : cl1labs) {
219 if (label == occurrence.first) {
220 ++occurrence.second;
221 found = true;
222 // break; // uncomment to stop to the first hit
223 }
224 }
225 }
226 if (!found) {
227 for (auto& label : cl1labs) {
228 occurrences.emplace_back(label, 1);
229 }
230 }
231
232 isFirstRoadCell = false;
233 }
234
235 const int cl2index{mTimeFrame->getClusters()[iCell + 2][currentCell.getThirdClusterIndex()].clusterId};
236 const auto& cl2labs{mTimeFrame->getClusterLabels(iCell + 2, cl2index)};
237 bool found{false};
238 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
239 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
240 for (auto& label : cl2labs) {
241 if (label == occurrence.first) {
242 ++occurrence.second;
243 found = true;
244 // break; // uncomment to stop to the first hit
245 }
246 }
247 }
248 if (!found) {
249 for (auto& label : cl2labs) {
250 occurrences.emplace_back(label, 1);
251 }
252 }
253 }
254
255 std::sort(occurrences.begin(), occurrences.end(), [](auto e1, auto e2) {
256 return e1.second > e2.second;
257 });
258
259 auto maxOccurrencesValue = occurrences[0].first;
260 mTimeFrame->setRoadLabel(iRoad, maxOccurrencesValue.getRawValue(), isFakeRoad);
261 }
262}
263
264void Tracker::computeTracksMClabels()
265{
266 for (int iROF{0}; iROF < mTimeFrame->getNrof(); ++iROF) {
267 for (auto& track : mTimeFrame->getTracks(iROF)) {
268 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
269 occurrences.clear();
270
271 for (int iCluster = 0; iCluster < TrackITSExt::MaxClusters; ++iCluster) {
272 const int index = track.getClusterIndex(iCluster);
274 continue;
275 }
276 auto labels = mTimeFrame->getClusterLabels(iCluster, index);
277 bool found{false};
278 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
279 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
280 for (auto& label : labels) {
281 if (label == occurrence.first) {
282 ++occurrence.second;
283 found = true;
284 // break; // uncomment to stop to the first hit
285 }
286 }
287 }
288 if (!found) {
289 for (auto& label : labels) {
290 occurrences.emplace_back(label, 1);
291 }
292 }
293 }
294 std::sort(std::begin(occurrences), std::end(occurrences), [](auto e1, auto e2) {
295 return e1.second > e2.second;
296 });
297
298 auto maxOccurrencesValue = occurrences[0].first;
299 uint32_t pattern = track.getPattern();
300 // set fake clusters pattern
301 for (int ic{TrackITSExt::MaxClusters}; ic--;) {
302 auto clid = track.getClusterIndex(ic);
303 if (clid != constants::its::UnusedIndex) {
304 auto labelsSpan = mTimeFrame->getClusterLabels(ic, clid);
305 for (auto& currentLabel : labelsSpan) {
306 if (currentLabel == maxOccurrencesValue) {
307 pattern |= 0x1 << (16 + ic); // set bit if correct
308 break;
309 }
310 }
311 }
312 }
313 track.setPattern(pattern);
314 if (occurrences[0].second < track.getNumberOfClusters()) {
315 maxOccurrencesValue.setFakeFlag();
316 }
317 mTimeFrame->getTracksLabel(iROF).emplace_back(maxOccurrencesValue);
318 }
319 }
320}
321
322void Tracker::rectifyClusterIndices()
323{
324 for (int iROF{0}; iROF < mTimeFrame->getNrof(); ++iROF) {
325 for (auto& track : mTimeFrame->getTracks(iROF)) {
326 for (int iCluster = 0; iCluster < TrackITSExt::MaxClusters; ++iCluster) {
327 const int index = track.getClusterIndex(iCluster);
329 track.setExternalClusterIndex(iCluster, mTimeFrame->getClusterExternalIndex(iCluster, index));
330 }
331 }
332 }
333 }
334}
335
337{
339 if (tc.useMatCorrTGeo) {
341 } else if (tc.useFastMaterial) {
343 } else {
345 }
346 setNThreads(tc.nThreads);
347 int nROFsPerIterations = tc.nROFsPerIterations > 0 ? tc.nROFsPerIterations : -1;
348 if (tc.nOrbitsPerIterations > 0) {
350 }
351 for (auto& params : mTrkParams) {
352 if (params.NLayers == 7) {
353 for (int i{0}; i < 7; ++i) {
354 params.SystErrorY2[i] = tc.sysErrY2[i] > 0 ? tc.sysErrY2[i] : params.SystErrorY2[i];
355 params.SystErrorZ2[i] = tc.sysErrZ2[i] > 0 ? tc.sysErrZ2[i] : params.SystErrorZ2[i];
356 }
357 }
358 params.DeltaROF = tc.deltaRof;
359 params.DoUPCIteration = tc.doUPCIteration;
360 params.MaxChi2ClusterAttachment = tc.maxChi2ClusterAttachment > 0 ? tc.maxChi2ClusterAttachment : params.MaxChi2ClusterAttachment;
361 params.MaxChi2NDF = tc.maxChi2NDF > 0 ? tc.maxChi2NDF : params.MaxChi2NDF;
362 params.PhiBins = tc.LUTbinsPhi > 0 ? tc.LUTbinsPhi : params.PhiBins;
363 params.ZBins = tc.LUTbinsZ > 0 ? tc.LUTbinsZ : params.ZBins;
364 params.PVres = tc.pvRes > 0 ? tc.pvRes : params.PVres;
365 params.NSigmaCut *= tc.nSigmaCut > 0 ? tc.nSigmaCut : 1.f;
366 params.CellDeltaTanLambdaSigma *= tc.deltaTanLres > 0 ? tc.deltaTanLres : 1.f;
367 params.TrackletMinPt *= tc.minPt > 0 ? tc.minPt : 1.f;
368 params.nROFsPerIterations = nROFsPerIterations;
369 params.PerPrimaryVertexProcessing = tc.perPrimaryVertexProcessing;
370 params.SaveTimeBenchmarks = tc.saveTimeBenchmarks;
371 params.FataliseUponFailure = tc.fataliseUponFailure;
372 params.DropTFUponFailure = tc.dropTFUponFailure;
373 for (int iD{0}; iD < 3; ++iD) {
374 params.Diamond[iD] = tc.diamondPos[iD];
375 }
376 params.UseDiamond = tc.useDiamond;
377 if (tc.maxMemory) {
378 params.MaxMemory = tc.maxMemory;
379 }
380 if (tc.useTrackFollower > 0) {
381 params.UseTrackFollower = true;
382 // Bit 0: Allow for mixing of top&bot extension --> implies Bits 1&2 set
383 // Bit 1: Allow for top extension
384 // Bit 2: Allow for bot extension
385 params.UseTrackFollowerMix = ((tc.useTrackFollower & (1 << 0)) != 0);
386 params.UseTrackFollowerTop = ((tc.useTrackFollower & (1 << 1)) != 0);
387 params.UseTrackFollowerBot = ((tc.useTrackFollower & (1 << 2)) != 0);
388 params.TrackFollowerNSigmaCutZ = tc.trackFollowerNSigmaZ;
389 params.TrackFollowerNSigmaCutPhi = tc.trackFollowerNSigmaPhi;
390 }
391 if (tc.cellsPerClusterLimit >= 0) {
392 params.CellsPerClusterLimit = tc.cellsPerClusterLimit;
393 }
394 if (tc.trackletsPerClusterLimit >= 0) {
395 params.TrackletsPerClusterLimit = tc.trackletsPerClusterLimit;
396 }
397 if (tc.findShortTracks >= 0) {
398 params.FindShortTracks = tc.findShortTracks;
399 }
400 }
401}
402
404{
405 mTimeFrame = &tf;
406 mTraits->adoptTimeFrame(&tf);
407}
408
410{
411 auto avgTF = mTotalTime * 1.e-3 / ((mTimeFrameCounter > 0) ? (double)mTimeFrameCounter : -1.0);
412 auto avgTFwithDropped = mTotalTime * 1.e-3 / (((mTimeFrameCounter + mNumberOfDroppedTFs) > 0) ? (double)(mTimeFrameCounter + mNumberOfDroppedTFs) : -1.0);
413 LOGP(info, "Tracker summary: Processed {} TFs (dropped {}) in TOT={:.2f} s, AVG/TF={:.2f} ({:.2f}) s", mTimeFrameCounter, mNumberOfDroppedTFs, mTotalTime * 1.e-3, avgTF, avgTFwithDropped);
414}
415
416} // namespace o2::its
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 ...
static constexpr int MaxClusters
< heavy version of TrackITS, with clusters embedded
Definition TrackITS.h:169
virtual int getTFNumberOfTracklets() const
virtual int getTFNumberOfClusters() const
void updateTrackingParameters(const std::vector< TrackingParameters > &trkPars)
virtual void adoptTimeFrame(TimeFrame< nLayers > *tf)
void setCorrType(const o2::base::PropagatorImpl< float >::MatCorrType type)
virtual bool supportsFindShortPrimaries() const noexcept
virtual bool supportsExtendTracks() const noexcept
virtual const char * getName() const noexcept
virtual int getTFNumberOfCells() const
void printSummary() const
Definition Tracker.cxx:409
void getGlobalConfiguration()
Definition Tracker.cxx:336
void adoptTimeFrame(TimeFrame< NLayers > &tf)
Definition Tracker.cxx:403
Tracker(TrackerTraits< NLayers > *traits)
Definition Tracker.cxx:38
void clustersToTracks(LogFunc=[](const std::string &s) { std::cout<< s<< '\n';}, LogFunc=[](const std::string &s) { std::cerr<< s<< '\n';})
Definition Tracker.cxx:44
void setNThreads(int n)
Definition Tracker.h:76
GLuint index
Definition glcorearb.h:781
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
std::unique_ptr< GPUReconstructionTimeframe > tf
int getNrof() const
Definition TimeFrame.h:100
bool hasMCinformation() const
Definition TimeFrame.h:146
size_t getNumberOfTracks() const
Definition TimeFrame.h:651
int getClusterExternalIndex(int layerId, const int clId) const
Definition TimeFrame.h:139
gsl::span< const Vertex > getPrimaryVertices(int rofId) const
Definition TimeFrame.h:350
void initialiseRoadLabels()
Definition TimeFrame.h:536
auto & getClusters()
Definition TimeFrame.h:162
gsl::span< const MCCompLabel > getClusterLabels(int layerId, const Cluster &cl) const
Definition TimeFrame.h:137
unsigned long getArtefactsMemory() const
int getNumberOfNeighbours() const
Definition TimeFrame.h:641
void printArtefactsMemory() const
auto & getTracksLabel(const int rofId)
Definition TimeFrame.h:172
void setRoadLabel(int i, const unsigned long long &lab, bool fake)
Definition TimeFrame.h:543
std::array< uint16_t, 5 > pattern