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"
25
27#include <cassert>
28#include <format>
29#include <cstdlib>
30#include <string>
31#include <climits>
32
33namespace o2::its
34{
36
37Tracker::Tracker(TrackerTraits7* traits) : mTraits(traits)
38{
40 mTrkParams.resize(1);
41 if (traits->isGPU()) {
42 ITSGpuTrackingParamConfig::Instance().printKeyValues(true, true);
43 }
44}
45
46void Tracker::clustersToTracks(const LogFunc& logger, const LogFunc& error)
47{
48 LogFunc evalLog = [](const std::string&) {};
49
50 double total{0};
51 mTraits->updateTrackingParameters(mTrkParams);
52 int maxNvertices{-1};
53 if (mTrkParams[0].PerPrimaryVertexProcessing) {
54 for (int iROF{0}; iROF < mTimeFrame->getNrof(); ++iROF) {
55 maxNvertices = std::max(maxNvertices, (int)mTimeFrame->getPrimaryVertices(iROF).size());
56 }
57 }
58
59 int iteration{0}, iROFs{0}, iVertex{0};
60 auto handleException = [&](const auto& err) {
61 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.",
62 StateNames[mCurState], iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, iVertex,
63 (double)mTimeFrame->getArtefactsMemory() / GB, (double)mTrkParams[iteration].MaxMemory / GB);
64 LOGP(error, "Exception: {}", err.what());
65 if (mTrkParams[iteration].DropTFUponFailure) {
66 mTimeFrame->wipe();
67 mMemoryPool->print();
68 ++mNumberOfDroppedTFs;
69 error("...Dropping Timeframe...");
70 } else {
71 throw err;
72 }
73 };
74
75 try {
76 for (iteration = 0; iteration < (int)mTrkParams.size(); ++iteration) {
77 mMemoryPool->setMaxMemory(mTrkParams[iteration].MaxMemory);
78 if (iteration == 3 && mTrkParams[0].DoUPCIteration) {
79 mTimeFrame->swapMasks();
80 }
81 double timeTracklets{0.}, timeCells{0.}, timeNeighbours{0.}, timeRoads{0.};
82 int nTracklets{0}, nCells{0}, nNeighbours{0}, nTracks{-static_cast<int>(mTimeFrame->getNumberOfTracks())};
83 int nROFsIterations = mTrkParams[iteration].nROFsPerIterations > 0 ? mTimeFrame->getNrof() / mTrkParams[iteration].nROFsPerIterations + bool(mTimeFrame->getNrof() % mTrkParams[iteration].nROFsPerIterations) : 1;
84 iVertex = std::min(maxNvertices, 0);
85 logger(std::format("==== ITS {} Tracking iteration {} summary ====", mTraits->getName(), iteration));
86
87 total += evaluateTask(&Tracker::initialiseTimeFrame, StateNames[mCurState = TFInit], iteration, logger, iteration);
88 do {
89 for (iROFs = 0; iROFs < nROFsIterations; ++iROFs) {
90 timeTracklets += evaluateTask(&Tracker::computeTracklets, StateNames[mCurState = Trackleting], iteration, evalLog, iteration, iROFs, iVertex);
91 nTracklets += mTraits->getTFNumberOfTracklets();
92 float trackletsPerCluster = mTraits->getTFNumberOfClusters() > 0 ? float(mTraits->getTFNumberOfTracklets()) / float(mTraits->getTFNumberOfClusters()) : 0.f;
93 if (trackletsPerCluster > mTrkParams[iteration].TrackletsPerClusterLimit) {
94 error(std::format("Too many tracklets per cluster ({}) in iteration {} in ROF span {}-{}:, check the detector status and/or the selections. Current limit is {}",
95 trackletsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].TrackletsPerClusterLimit));
96 break;
97 }
98 timeCells += evaluateTask(&Tracker::computeCells, StateNames[mCurState = Celling], iteration, evalLog, iteration);
99 nCells += mTraits->getTFNumberOfCells();
100 float cellsPerCluster = mTraits->getTFNumberOfClusters() > 0 ? float(mTraits->getTFNumberOfCells()) / float(mTraits->getTFNumberOfClusters()) : 0.f;
101 if (cellsPerCluster > mTrkParams[iteration].CellsPerClusterLimit) {
102 error(std::format("Too many cells per cluster ({}) in iteration {} in ROF span {}-{}, check the detector status and/or the selections. Current limit is {}",
103 cellsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].CellsPerClusterLimit));
104 break;
105 }
106 timeNeighbours += evaluateTask(&Tracker::findCellsNeighbours, StateNames[mCurState = Neighbouring], iteration, evalLog, iteration);
107 nNeighbours += mTimeFrame->getNumberOfNeighbours();
108 timeRoads += evaluateTask(&Tracker::findRoads, StateNames[mCurState = Roading], iteration, evalLog, iteration);
109 }
110 } while (++iVertex < maxNvertices);
111 logger(std::format(" - Tracklet finding: {} tracklets found in {:.2f} ms", nTracklets, timeTracklets));
112 logger(std::format(" - Cell finding: {} cells found in {:.2f} ms", nCells, timeCells));
113 logger(std::format(" - Neighbours finding: {} neighbours found in {:.2f} ms", nNeighbours, timeNeighbours));
114 logger(std::format(" - Track finding: {} tracks found in {:.2f} ms", nTracks + mTimeFrame->getNumberOfTracks(), timeRoads));
115 total += timeTracklets + timeCells + timeNeighbours + timeRoads;
116 if (mTraits->supportsExtendTracks() && mTrkParams[iteration].UseTrackFollower) {
117 int nExtendedTracks{-mTimeFrame->mNExtendedTracks}, nExtendedClusters{-mTimeFrame->mNExtendedUsedClusters};
118 auto timeExtending = evaluateTask(&Tracker::extendTracks, "Extending tracks", iteration, evalLog, iteration);
119 total += timeExtending;
120 logger(std::format(" - Extending Tracks: {} extended tracks using {} clusters found in {:.2f} ms", nExtendedTracks + mTimeFrame->mNExtendedTracks, nExtendedClusters + mTimeFrame->mNExtendedUsedClusters, timeExtending));
121 }
122 if (mTrkParams[iteration].PrintMemory) {
123 mMemoryPool->print();
124 }
125 }
126 if (mTraits->supportsFindShortPrimaries() && mTrkParams[0].FindShortTracks) {
127 auto nTracksB = mTimeFrame->getNumberOfTracks();
128 total += evaluateTask(&Tracker::findShortPrimaries, "Short primaries finding", 0, logger);
129 auto nTracksA = mTimeFrame->getNumberOfTracks();
130 logger(std::format(" `-> found {} additional tracks", nTracksA - nTracksB));
131 }
132 if constexpr (constants::DoTimeBenchmarks) {
133 logger(std::format("=== TimeFrame {} processing completed in: {:.2f} ms using {} thread(s) ===", mTimeFrameCounter, total, mTraits->getNThreads()));
134 }
135 } catch (const BoundedMemoryResource::MemoryLimitExceeded& err) {
136 handleException(err);
137 return;
138 } catch (const std::bad_alloc& err) {
139 handleException(err);
140 return;
141 } catch (...) {
142 error("Uncaught exception, all bets are off...");
143 }
144
145 if (mTrkParams[0].PrintMemory) {
146 mTimeFrame->printArtefactsMemory();
147 mMemoryPool->print();
148 }
149
150 if (mTimeFrame->hasMCinformation()) {
151 computeTracksMClabels();
152 }
153 rectifyClusterIndices();
154 ++mTimeFrameCounter;
155 mTotalTime += total;
156}
157
158void Tracker::computeRoadsMClabels()
159{
161 if (!mTimeFrame->hasMCinformation()) {
162 return;
163 }
164
165 mTimeFrame->initialiseRoadLabels();
166
167 int roadsNum{static_cast<int>(mTimeFrame->getRoads().size())};
168
169 for (int iRoad{0}; iRoad < roadsNum; ++iRoad) {
170
171 Road<5>& currentRoad{mTimeFrame->getRoads()[iRoad]};
172 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
173 bool isFakeRoad{false};
174 bool isFirstRoadCell{true};
175
176 for (int iCell{0}; iCell < mTrkParams[0].CellsPerRoad(); ++iCell) {
177 const int currentCellIndex{currentRoad[iCell]};
178
179 if (currentCellIndex == constants::UnusedIndex) {
180 if (isFirstRoadCell) {
181 continue;
182 } else {
183 break;
184 }
185 }
186
187 const CellSeed& currentCell{mTimeFrame->getCells()[iCell][currentCellIndex]};
188
189 if (isFirstRoadCell) {
190
191 const int cl0index{mTimeFrame->getClusters()[iCell][currentCell.getFirstClusterIndex()].clusterId};
192 auto cl0labs{mTimeFrame->getClusterLabels(iCell, cl0index)};
193 bool found{false};
194 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
195 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
196 for (const auto& label : cl0labs) {
197 if (label == occurrence.first) {
198 ++occurrence.second;
199 found = true;
200 // break; // uncomment to stop to the first hit
201 }
202 }
203 }
204 if (!found) {
205 for (const auto& label : cl0labs) {
206 occurrences.emplace_back(label, 1);
207 }
208 }
209
210 const int cl1index{mTimeFrame->getClusters()[iCell + 1][currentCell.getSecondClusterIndex()].clusterId};
211
212 const auto& cl1labs{mTimeFrame->getClusterLabels(iCell + 1, cl1index)};
213 found = false;
214 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
215 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
216 for (auto& label : cl1labs) {
217 if (label == occurrence.first) {
218 ++occurrence.second;
219 found = true;
220 // break; // uncomment to stop to the first hit
221 }
222 }
223 }
224 if (!found) {
225 for (auto& label : cl1labs) {
226 occurrences.emplace_back(label, 1);
227 }
228 }
229
230 isFirstRoadCell = false;
231 }
232
233 const int cl2index{mTimeFrame->getClusters()[iCell + 2][currentCell.getThirdClusterIndex()].clusterId};
234 const auto& cl2labs{mTimeFrame->getClusterLabels(iCell + 2, cl2index)};
235 bool found{false};
236 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
237 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
238 for (auto& label : cl2labs) {
239 if (label == occurrence.first) {
240 ++occurrence.second;
241 found = true;
242 // break; // uncomment to stop to the first hit
243 }
244 }
245 }
246 if (!found) {
247 for (auto& label : cl2labs) {
248 occurrences.emplace_back(label, 1);
249 }
250 }
251 }
252
253 std::sort(occurrences.begin(), occurrences.end(), [](auto e1, auto e2) {
254 return e1.second > e2.second;
255 });
256
257 auto maxOccurrencesValue = occurrences[0].first;
258 mTimeFrame->setRoadLabel(iRoad, maxOccurrencesValue.getRawValue(), isFakeRoad);
259 }
260}
261
262void Tracker::computeTracksMClabels()
263{
264 for (int iROF{0}; iROF < mTimeFrame->getNrof(); ++iROF) {
265 for (auto& track : mTimeFrame->getTracks(iROF)) {
266 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
267 occurrences.clear();
268
269 for (int iCluster = 0; iCluster < TrackITSExt::MaxClusters; ++iCluster) {
270 const int index = track.getClusterIndex(iCluster);
272 continue;
273 }
274 auto labels = mTimeFrame->getClusterLabels(iCluster, index);
275 bool found{false};
276 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
277 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
278 for (const auto& label : labels) {
279 if (label == occurrence.first) {
280 ++occurrence.second;
281 found = true;
282 // break; // uncomment to stop to the first hit
283 }
284 }
285 }
286 if (!found) {
287 for (const auto& label : labels) {
288 occurrences.emplace_back(label, 1);
289 }
290 }
291 }
292 std::sort(std::begin(occurrences), std::end(occurrences), [](auto e1, auto e2) {
293 return e1.second > e2.second;
294 });
295
296 auto maxOccurrencesValue = occurrences[0].first;
297 uint32_t pattern = track.getPattern();
298 // set fake clusters pattern
299 for (int ic{TrackITSExt::MaxClusters}; ic--;) {
300 auto clid = track.getClusterIndex(ic);
301 if (clid != constants::UnusedIndex) {
302 auto labelsSpan = mTimeFrame->getClusterLabels(ic, clid);
303 for (const auto& currentLabel : labelsSpan) {
304 if (currentLabel == maxOccurrencesValue) {
305 pattern |= 0x1 << (16 + ic); // set bit if correct
306 break;
307 }
308 }
309 }
310 }
311 track.setPattern(pattern);
312 if (occurrences[0].second < track.getNumberOfClusters()) {
313 maxOccurrencesValue.setFakeFlag();
314 }
315 mTimeFrame->getTracksLabel(iROF).emplace_back(maxOccurrencesValue);
316 }
317 }
318}
319
320void Tracker::rectifyClusterIndices()
321{
322 for (int iROF{0}; iROF < mTimeFrame->getNrof(); ++iROF) {
323 for (auto& track : mTimeFrame->getTracks(iROF)) {
324 for (int iCluster = 0; iCluster < TrackITSExt::MaxClusters; ++iCluster) {
325 const int index = track.getClusterIndex(iCluster);
327 track.setExternalClusterIndex(iCluster, mTimeFrame->getClusterExternalIndex(iCluster, index));
328 }
329 }
330 }
331 }
332}
333
335{
336 mTimeFrame = &tf;
337 mTraits->adoptTimeFrame(&tf);
338}
339
341{
342 auto avgTF = mTotalTime * 1.e-3 / ((mTimeFrameCounter > 0) ? (double)mTimeFrameCounter : -1.0);
343 auto avgTFwithDropped = mTotalTime * 1.e-3 / (((mTimeFrameCounter + mNumberOfDroppedTFs) > 0) ? (double)(mTimeFrameCounter + mNumberOfDroppedTFs) : -1.0);
344 LOGP(info, "Tracker summary: Processed {} TFs (dropped {}) in TOT={:.2f} s, AVG/TF={:.2f} ({:.2f}) s", mTimeFrameCounter, mNumberOfDroppedTFs, mTotalTime * 1.e-3, avgTF, avgTFwithDropped);
345}
346
347} // namespace o2::its
Base track model for the Barrel, params only, w/o covariance.
#define GB
Definition Utils.h:40
static constexpr int MaxClusters
< heavy version of TrackITS, with clusters embedded
Definition TrackITS.h:169
virtual int getTFNumberOfTracklets() const
virtual bool isGPU() const noexcept
virtual int getTFNumberOfClusters() const
void updateTrackingParameters(const std::vector< TrackingParameters > &trkPars)
virtual void adoptTimeFrame(TimeFrame< nLayers > *tf)
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:340
void clustersToTracks(const LogFunc &=[](const std::string &s) { std::cout<< s<< '\n';}, const LogFunc &=[](const std::string &s) { std::cerr<< s<< '\n';})
Definition Tracker.cxx:46
void adoptTimeFrame(TimeFrame< NLayers > &tf)
Definition Tracker.cxx:334
Tracker(TrackerTraits< NLayers > *traits)
Definition Tracker.cxx:37
GLuint index
Definition glcorearb.h:781
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
constexpr int UnusedIndex
Definition Constants.h:30
constexpr float GB
Definition Constants.h:24
constexpr bool DoTimeBenchmarks
Definition Constants.h:25
std::unique_ptr< GPUReconstructionTimeframe > tf
int getNrof() const
Definition TimeFrame.h:104
bool hasMCinformation() const
Definition TimeFrame.h:150
size_t getNumberOfTracks() const
Definition TimeFrame.h:675
int getClusterExternalIndex(int layerId, const int clId) const
Definition TimeFrame.h:143
gsl::span< const Vertex > getPrimaryVertices(int rofId) const
Definition TimeFrame.h:358
void initialiseRoadLabels()
Definition TimeFrame.h:560
auto & getClusters()
Definition TimeFrame.h:166
gsl::span< const MCCompLabel > getClusterLabels(int layerId, const Cluster &cl) const
Definition TimeFrame.h:141
unsigned long getArtefactsMemory() const
virtual int getNumberOfNeighbours() const
Definition TimeFrame.h:665
void printArtefactsMemory() const
auto & getTracksLabel(const int rofId)
Definition TimeFrame.h:176
void setRoadLabel(int i, const unsigned long long &lab, bool fake)
Definition TimeFrame.h:567
std::array< uint16_t, 5 > pattern