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"
21
22#include <cassert>
23#include <format>
24#include <cstdlib>
25#include <string>
26
27namespace o2::its
28{
30
31template <int NLayers>
33{
34}
35
36template <int NLayers>
37float Tracker<NLayers>::clustersToTracks(const LogFunc& logger, const LogFunc& error)
38{
39 LogFunc evalLog = [](const std::string&) {};
40
41 float total{0};
42 mTraits->updateTrackingParameters(mTrkParams);
43
44 int maxNvertices{-1};
45 if (mTrkParams[0].PerPrimaryVertexProcessing) {
46 maxNvertices = mTimeFrame->getROFVertexLookupTableView().getMaxVerticesPerROF();
47 }
48
49 int iteration{0}, iVertex{0};
50 auto handleException = [&](const auto& err) {
51 LOGP(error, "Too much memory in {} in iteration {} iVtx={}: {:.2f} GB. Current limit is {:.2f} GB, check the detector status and/or the selections.",
52 StateNames[mCurStep], iteration, iVertex,
53 (double)mTimeFrame->getArtefactsMemory() / GB,
54 (double)mTrkParams[iteration].MaxMemory / GB);
55 if (typeid(err) != typeid(std::bad_alloc)) { // only print if the exceptions is different from what is expected
56 LOGP(error, "Exception: {}", err.what());
57 }
58 if (mTrkParams[iteration].DropTFUponFailure) {
59 mMemoryPool->print();
60 mTimeFrame->wipe();
61 ++mNumberOfDroppedTFs;
62 error(std::format("...Dropping TimeSlice {} (out of {} dropped {})...", mTimeSlice, mTimeFrameCounter, mNumberOfDroppedTFs));
63 } else {
64 throw err;
65 }
66 };
67
68 try {
69 for (iteration = 0; iteration < (int)mTrkParams.size(); ++iteration) {
70 mMemoryPool->setMaxMemory(mTrkParams[iteration].MaxMemory);
71 if (iteration == 3 && mTrkParams[0].DoUPCIteration) {
72 mTimeFrame->useUPCMask();
73 }
74 float timeFrame{0.}, timeTracklets{0.}, timeCells{0.}, timeNeighbours{0.}, timeRoads{0.};
75 size_t nTracklets{0}, nCells{0}, nNeighbours{0};
76 int nTracks{-static_cast<int>(mTimeFrame->getNumberOfTracks())};
77 iVertex = std::min(maxNvertices, 0);
78 logger(std::format("==== ITS {} Tracking iteration {} summary ====", mTraits->getName(), iteration));
79 total += timeFrame = evaluateTask(&Tracker::initialiseTimeFrame, StateNames[mCurStep = TFInit], iteration, evalLog, iteration);
80 logger(std::format(" - TimeFrame initialisation completed in {:.2f} ms", timeFrame));
81 do {
82 timeTracklets += evaluateTask(&Tracker::computeTracklets, StateNames[mCurStep = Trackleting], iteration, evalLog, iteration, iVertex);
83 nTracklets += mTraits->getTFNumberOfTracklets();
84 timeCells += evaluateTask(&Tracker::computeCells, StateNames[mCurStep = Celling], iteration, evalLog, iteration);
85 nCells += mTraits->getTFNumberOfCells();
86 timeNeighbours += evaluateTask(&Tracker::findCellsNeighbours, StateNames[mCurStep = Neighbouring], iteration, evalLog, iteration);
87 nNeighbours += mTimeFrame->getNumberOfNeighbours();
88 timeRoads += evaluateTask(&Tracker::findRoads, StateNames[mCurStep = Roading], iteration, evalLog, iteration);
89 } while (++iVertex < maxNvertices);
90 logger(std::format(" - Tracklet finding: {} tracklets found in {:.2f} ms", nTracklets, timeTracklets));
91 logger(std::format(" - Cell finding: {} cells found in {:.2f} ms", nCells, timeCells));
92 logger(std::format(" - Neighbours finding: {} neighbours found in {:.2f} ms", nNeighbours, timeNeighbours));
93 logger(std::format(" - Track finding: {} tracks found in {:.2f} ms", nTracks + mTimeFrame->getNumberOfTracks(), timeRoads));
94 total += timeTracklets + timeCells + timeNeighbours + timeRoads;
95 }
97 handleException(err);
98 return -1.f;
99 } catch (const std::bad_alloc& err) {
100 handleException(err);
101 return -1.f;
102 } catch (const std::exception& err) {
103 error(std::format("Uncaught exception, all bets are off... {}", err.what()));
104 // clear tracks explicitly since if not fatalising on exception this may contain partial output
105 mTimeFrame->getTracks().clear();
106 return -1.f;
107 }
108
109 if (mTimeFrame->hasMCinformation()) {
110 computeTracksMClabels();
111 }
112 rectifyClusterIndices();
113 sortTracks();
114
115 ++mTimeFrameCounter;
116 mTotalTime += total;
117
118 return total;
119}
120
121template <int NLayers>
123{
124 for (auto& track : mTimeFrame->getTracks()) {
125 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
126 occurrences.clear();
127
128 for (int iCluster = 0; iCluster < TrackITSExt::MaxClusters; ++iCluster) {
129 const int index = track.getClusterIndex(iCluster);
131 continue;
132 }
133 auto labels = mTimeFrame->getClusterLabels(iCluster, index);
134 bool found{false};
135 for (size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
136 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
137 for (const auto& label : labels) {
138 if (label == occurrence.first) {
139 ++occurrence.second;
140 found = true;
141 // break; // uncomment to stop to the first hit
142 }
143 }
144 }
145 if (!found) {
146 for (const auto& label : labels) {
147 occurrences.emplace_back(label, 1);
148 }
149 }
150 }
151 std::sort(std::begin(occurrences), std::end(occurrences), [](auto e1, auto e2) {
152 return e1.second > e2.second;
153 });
154
155 auto maxOccurrencesValue = occurrences[0].first;
156 uint32_t pattern = track.getPattern();
157 // set fake clusters pattern
158 for (int ic{TrackITSExt::MaxClusters}; ic--;) {
159 auto clid = track.getClusterIndex(ic);
160 if (clid != constants::UnusedIndex) {
161 auto labelsSpan = mTimeFrame->getClusterLabels(ic, clid);
162 for (const auto& currentLabel : labelsSpan) {
163 if (currentLabel == maxOccurrencesValue) {
164 pattern |= 0x1 << (16 + ic); // set bit if correct
165 break;
166 }
167 }
168 }
169 }
170 track.setPattern(pattern);
171 if (occurrences[0].second < track.getNumberOfClusters()) {
172 maxOccurrencesValue.setFakeFlag();
173 }
174 mTimeFrame->getTracksLabel().emplace_back(maxOccurrencesValue);
175 }
176}
177
178template <int NLayers>
180{
181 for (auto& track : mTimeFrame->getTracks()) {
182 for (int iCluster = 0; iCluster < TrackITSExt::MaxClusters; ++iCluster) {
183 const int index = track.getClusterIndex(iCluster);
185 track.setExternalClusterIndex(iCluster, mTimeFrame->getClusterExternalIndex(iCluster, index));
186 }
187 }
188 }
189}
190
191template <int NLayers>
192void Tracker<NLayers>::sortTracks()
193{
194 auto& trks = mTimeFrame->getTracks();
195 bounded_vector<size_t> indices(trks.size(), mMemoryPool.get());
196 std::iota(indices.begin(), indices.end(), 0);
197 std::sort(indices.begin(), indices.end(), [&trks](size_t i, size_t j) {
198 // provide tracks sorted by lower-bound
199 const auto& a = trks[i];
200 const auto& b = trks[j];
201 const auto aLower = a.getTimeStamp().getTimeStamp() - a.getTimeStamp().getTimeStampError();
202 const auto bLower = b.getTimeStamp().getTimeStamp() - b.getTimeStamp().getTimeStampError();
203 if (aLower != bLower) {
204 return aLower < bLower;
205 }
206 return a.isBetter(b, 1e9); // then sort tracks in quality
207 });
208 bounded_vector<TrackITSExt> sortedTrks(mMemoryPool.get());
209 sortedTrks.reserve(trks.size());
210 for (size_t idx : indices) {
211 sortedTrks.push_back(trks[idx]);
212 }
213 trks.swap(sortedTrks);
214 if (mTimeFrame->hasMCinformation()) {
215 auto& trksLabels = mTimeFrame->getTracksLabel();
216 bounded_vector<MCCompLabel> sortedLabels(mMemoryPool.get());
217 sortedLabels.reserve(trksLabels.size());
218 for (size_t idx : indices) {
219 sortedLabels.push_back(trksLabels[idx]);
220 }
221 trksLabels.swap(sortedLabels);
222 }
223}
224
225template <int NLayers>
227{
228 mTimeFrame = &tf;
229 mTraits->adoptTimeFrame(&tf);
230}
231
232template <int NLayers>
233void Tracker<NLayers>::addTimingStatCurStep(int iteration, double timeMs)
234{
235 if (iteration < 0) {
236 return;
237 }
238 if (mTimingStats.size() < (iteration + 1)) {
239 mTimingStats.resize(iteration + 1);
240 }
241 mTimingStats[iteration][mCurStep].add(timeMs);
242}
243
244template <int NLayers>
246{
247 auto avgTF = mTotalTime * 1.e-3 / ((mTimeFrameCounter > 0) ? (double)mTimeFrameCounter : -1.0);
248 auto avgTFwithDropped = mTotalTime * 1.e-3 / (((mTimeFrameCounter + mNumberOfDroppedTFs) > 0) ? (double)(mTimeFrameCounter + mNumberOfDroppedTFs) : -1.0);
249 LOGP(info, "Tracker summary: Processed {} TFs (dropped {}) in TOT={:.2f} s, AVG/TF={:.2f} ({:.2f}) s", mTimeFrameCounter, mNumberOfDroppedTFs, mTotalTime * 1.e-3, avgTF, avgTFwithDropped);
250 for (size_t iteration = 0; iteration < mTimingStats.size(); ++iteration) {
251 for (size_t state = 0; state < NSteps; ++state) {
252 const auto& stats = mTimingStats[iteration][state];
253 if (!stats.calls) {
254 continue;
255 }
256 LOGP(info, " - iter {} {}: calls={} total={:.2f} ms avg={:.2f} ms", iteration, StateNames[state], stats.calls, stats.totalTimeMs, stats.averageTimeMs());
257 }
258 }
259}
260
261template class Tracker<7>;
262// ALICE3 upgrade
263#ifdef ENABLE_UPGRADES
264template class Tracker<11>;
265#endif
266
267} // namespace o2::its
std::vector< std::string > labels
benchmark::State & state
int32_t i
#define GB
Definition Utils.h:40
uint32_t j
Definition RawData.h:0
static constexpr int MaxClusters
< heavy version of TrackITS, with clusters embedded
Definition TrackITS.h:171
Tracker(TrackerTraits< NLayers > *traits)
Definition Tracker.cxx:32
void adoptTimeFrame(TimeFrame< NLayers > &tf)
Definition Tracker.cxx:226
void computeTracksMClabels()
Definition Tracker.cxx:122
float clustersToTracks(const LogFunc &=[](const std::string &s) { std::cout<< s<< '\n';}, const LogFunc &=[](const std::string &s) { std::cerr<< s<< '\n';})
Definition Tracker.cxx:37
GLuint index
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLsizei GLenum const void * indices
Definition glcorearb.h:400
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
constexpr int UnusedIndex
Definition Constants.h:32
constexpr float GB
Definition Constants.h:27
std::unique_ptr< GPUReconstructionTimeframe > tf
std::array< uint16_t, 5 > pattern