54 if (mTrkParams[0].PerPrimaryVertexProcessing) {
55 for (
int iROF{0}; iROF < mTimeFrame->
getNrof(); ++iROF) {
56 maxNvertices = std::max(maxNvertices, (
int)mTimeFrame->
getPrimaryVertices(iROF).size());
61 for (
int iteration = 0; iteration < (
int)mTrkParams.size(); ++iteration) {
62 if (iteration == 3 && mTrkParams[0].DoUPCIteration) {
65 logger(fmt::format(
"ITS Tracking iteration {} summary:", iteration));
66 double timeTracklets{0.}, timeCells{0.}, timeNeighbours{0.}, timeRoads{0.};
67 int nTracklets{0}, nCells{0}, nNeighbours{0}, nTracks{-
static_cast<int>(mTimeFrame->
getNumberOfTracks())};
69 total += evaluateTask(&Tracker::initialiseTimeFrame,
"Timeframe initialisation", logger, iteration);
70 int nROFsIterations = mTrkParams[iteration].nROFsPerIterations > 0 ? mTimeFrame->
getNrof() / mTrkParams[iteration].nROFsPerIterations + bool(mTimeFrame->
getNrof() % mTrkParams[iteration].nROFsPerIterations) : 1;
71 int iVertex{std::min(maxNvertices, 0)};
74 for (
int iROFs{0}; iROFs < nROFsIterations; ++iROFs) {
75 timeTracklets += evaluateTask(
76 &Tracker::computeTracklets,
"Tracklet finding", [](std::string) {}, iteration, iROFs, iVertex);
78 if (!mTimeFrame->
checkMemory(mTrkParams[iteration].MaxMemory)) {
79 mTimeFrame->
printSliceInfo(iROFs, mTrkParams[iteration].nROFsPerIterations);
80 error(fmt::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.",
81 iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTimeFrame->
getArtefactsMemory() /
GB, mTrkParams[iteration].MaxMemory /
GB));
82 if (mTrkParams[iteration].DropTFUponFailure) {
88 if (trackletsPerCluster > mTrkParams[iteration].TrackletsPerClusterLimit) {
89 error(fmt::format(
"Too many tracklets per cluster ({}) in iteration {} in ROF span {}-{}:, check the detector status and/or the selections. Current limit is {}",
90 trackletsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].TrackletsPerClusterLimit));
94 timeCells += evaluateTask(
95 &Tracker::computeCells,
"Cell finding", [](std::string) {}, iteration);
97 if (!mTimeFrame->
checkMemory(mTrkParams[iteration].MaxMemory)) {
98 mTimeFrame->
printSliceInfo(iROFs, mTrkParams[iteration].nROFsPerIterations);
99 error(fmt::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.",
100 iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTimeFrame->
getArtefactsMemory() /
GB, mTrkParams[iteration].MaxMemory /
GB));
101 if (mTrkParams[iteration].DropTFUponFailure) {
107 if (cellsPerCluster > mTrkParams[iteration].CellsPerClusterLimit) {
108 error(fmt::format(
"Too many cells per cluster ({}) in iteration {} in ROF span {}-{}, check the detector status and/or the selections. Current limit is {}",
109 cellsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].CellsPerClusterLimit));
113 timeNeighbours += evaluateTask(
114 &Tracker::findCellsNeighbours,
"Neighbour finding", [](std::string) {}, iteration);
116 timeRoads += evaluateTask(
117 &Tracker::findRoads,
"Road finding", [](std::string) {}, iteration);
120 }
while (iVertex < maxNvertices && !dropTF);
121 logger(fmt::format(
" - Tracklet finding: {} tracklets found in {:.2f} ms", nTracklets, timeTracklets));
122 logger(fmt::format(
" - Cell finding: {} cells found in {:.2f} ms", nCells, timeCells));
123 logger(fmt::format(
" - Neighbours finding: {} neighbours found in {:.2f} ms", nNeighbours, timeNeighbours));
124 logger(fmt::format(
" - Track finding: {} tracks found in {:.2f} ms", nTracks + mTimeFrame->
getNumberOfTracks(), timeRoads));
125 total += timeTracklets + timeCells + timeNeighbours + timeRoads;
126 if (mTrkParams[iteration].UseTrackFollower) {
128 auto timeExtending = evaluateTask(&Tracker::extendTracks,
"Extending tracks", [](
const std::string&) {}, iteration);
129 total += timeExtending;
130 logger(fmt::format(
" - Extending Tracks: {} extended tracks using {} clusters found in {:.2f} ms", nExtendedTracks + mTimeFrame->
mNExtendedTracks, nExtendedClusters + mTimeFrame->
mNExtendedUsedClusters, timeExtending));
133 error(fmt::format(
"...Dropping Timeframe..."));
139 total += evaluateTask(&Tracker::findShortPrimaries,
"Short primaries finding", logger);
141 std::stringstream sstream;
143 sstream << std::setw(2) <<
" - "
144 <<
"Timeframe " <<
mTimeFrameCounter++ <<
" processing completed in: " << total <<
"ms using " << mTraits->
getNThreads() <<
" threads.";
146 logger(sstream.str());
149 computeTracksMClabels();
151 rectifyClusterIndices();
159 int maxNvertices{-1};
160 if (mTrkParams[0].PerPrimaryVertexProcessing) {
161 for (
int iROF{0}; iROF < mTimeFrame->
getNrof(); ++iROF) {
162 maxNvertices = std::max(maxNvertices, (
int)mTimeFrame->
getPrimaryVertices(iROF).size());
166 for (
int iteration = 0; iteration < (
int)mTrkParams.size(); ++iteration) {
167 int nROFsIterations = mTrkParams[iteration].nROFsPerIterations > 0 ? mTimeFrame->
getNrof() / mTrkParams[iteration].nROFsPerIterations + bool(mTimeFrame->
getNrof() % mTrkParams[iteration].nROFsPerIterations) : 1;
168 logger(fmt::format(
"=========== ITS Hybrid Tracking iteration {} summary ===========", iteration, nROFsIterations, maxNvertices));
169 double timeTracklets{0.}, timeCells{0.}, timeNeighbours{0.}, timeRoads{0.};
170 int nTracklets{0}, nCells{0}, nNeighbours{0}, nTracks{-
static_cast<int>(mTimeFrame->
getNumberOfTracks())};
172 total += evaluateTask(&Tracker::initialiseTimeFrameHybrid,
"Hybrid Timeframe initialisation", logger, iteration);
173 int iVertex{std::min(maxNvertices, 0)};
176 for (
int iROFs{0}; iROFs < nROFsIterations; ++iROFs) {
177 timeTracklets += evaluateTask(
178 &Tracker::computeTrackletsHybrid,
"Tracklet finding", [](std::string) {}, iteration, iROFs, iVertex);
180 if (!mTimeFrame->
checkMemory(mTrkParams[iteration].MaxMemory)) {
181 error(fmt::format(
"Too much memory used during trackleting in iteration {}, check the detector status and/or the selections.", iteration));
185 if (trackletsPerCluster > mTrkParams[iteration].TrackletsPerClusterLimit) {
186 error(fmt::format(
"Too many tracklets per cluster ({}) in iteration {}, check the detector status and/or the selections. Current limit is {}", trackletsPerCluster, iteration, mTrkParams[iteration].TrackletsPerClusterLimit));
190 timeCells += evaluateTask(
191 &Tracker::computeCellsHybrid,
"Cell finding", [](std::string) {}, iteration);
193 if (!mTimeFrame->
checkMemory(mTrkParams[iteration].MaxMemory)) {
194 error(fmt::format(
"Too much memory used during cell finding in iteration {}, check the detector status and/or the selections.", iteration));
198 if (cellsPerCluster > mTrkParams[iteration].CellsPerClusterLimit) {
199 error(fmt::format(
"Too many cells per cluster ({}) in iteration {}, check the detector status and/or the selections. Current limit is {}", cellsPerCluster, iteration, mTrkParams[iteration].CellsPerClusterLimit));
203 timeNeighbours += evaluateTask(
204 &Tracker::findCellsNeighboursHybrid,
"Neighbour finding", [](std::string) {}, iteration);
206 timeRoads += evaluateTask(
207 &Tracker::findRoads,
"Road finding", [](std::string) {}, iteration);
210 }
while (iVertex < maxNvertices);
211 logger(fmt::format(
" - Hybrid tracklet finding: {} tracklets found in {:.2f} ms", nTracklets, timeTracklets));
212 logger(fmt::format(
" - Hybrid cell finding: {} cells found in {:.2f} ms", nCells, timeCells));
213 logger(fmt::format(
" - Hybrid neighbours finding: {} neighbours found in {:.2f} ms", nNeighbours, timeNeighbours));
214 logger(fmt::format(
" - Hybrid track finding: {} tracks found in {:.2f} ms", nTracks + mTimeFrame->
getNumberOfTracks(), timeRoads));
215 total += timeTracklets + timeCells + timeNeighbours + timeRoads;
221 std::stringstream sstream;
223 sstream << std::setw(2) <<
" - "
224 <<
"Timeframe " <<
mTimeFrameCounter++ <<
" processing completed in: " << total <<
"ms using " << mTraits->
getNThreads() <<
" threads.";
226 logger(sstream.str());
229 computeTracksMClabels();
231 rectifyClusterIndices();
235void Tracker::initialiseTimeFrame(
int& iteration)
240void Tracker::computeTracklets(
int& iteration,
int& iROFslice,
int& iVertex)
245void Tracker::computeCells(
int& iteration)
250void Tracker::findCellsNeighbours(
int& iteration)
255void Tracker::findRoads(
int& iteration)
260void Tracker::initialiseTimeFrameHybrid(
int& iteration)
265void Tracker::computeTrackletsHybrid(
int& iteration,
int& iROFslice,
int& iVertex)
270void Tracker::computeCellsHybrid(
int& iteration)
275void Tracker::findCellsNeighboursHybrid(
int& iteration)
280void Tracker::findRoadsHybrid(
int& iteration)
285void Tracker::findTracksHybrid(
int& iteration)
290void Tracker::findTracks()
295void Tracker::extendTracks(
int& iteration)
300void Tracker::findShortPrimaries()
305void Tracker::computeRoadsMClabels()
314 int roadsNum{
static_cast<int>(mTimeFrame->
getRoads().size())};
316 for (
int iRoad{0}; iRoad < roadsNum; ++iRoad) {
318 Road<5>& currentRoad{mTimeFrame->
getRoads()[iRoad]};
319 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
320 bool isFakeRoad{
false};
321 bool isFirstRoadCell{
true};
323 for (
int iCell{0}; iCell < mTrkParams[0].CellsPerRoad(); ++iCell) {
324 const int currentCellIndex{currentRoad[iCell]};
327 if (isFirstRoadCell) {
334 const CellSeed& currentCell{mTimeFrame->
getCells()[iCell][currentCellIndex]};
336 if (isFirstRoadCell) {
338 const int cl0index{mTimeFrame->
getClusters()[iCell][currentCell.getFirstClusterIndex()].clusterId};
341 for (
size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
342 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
343 for (
auto&
label : cl0labs) {
344 if (
label == occurrence.first) {
352 for (
auto&
label : cl0labs) {
353 occurrences.emplace_back(
label, 1);
357 const int cl1index{mTimeFrame->
getClusters()[iCell + 1][currentCell.getSecondClusterIndex()].clusterId};
361 for (
size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
362 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
363 for (
auto&
label : cl1labs) {
364 if (
label == occurrence.first) {
372 for (
auto&
label : cl1labs) {
373 occurrences.emplace_back(
label, 1);
377 isFirstRoadCell =
false;
380 const int cl2index{mTimeFrame->
getClusters()[iCell + 2][currentCell.getThirdClusterIndex()].clusterId};
383 for (
size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
384 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
385 for (
auto&
label : cl2labs) {
386 if (
label == occurrence.first) {
394 for (
auto&
label : cl2labs) {
395 occurrences.emplace_back(
label, 1);
400 std::sort(occurrences.begin(), occurrences.end(), [](
auto e1,
auto e2) {
401 return e1.second > e2.second;
404 auto maxOccurrencesValue = occurrences[0].first;
405 mTimeFrame->
setRoadLabel(iRoad, maxOccurrencesValue.getRawValue(), isFakeRoad);
409void Tracker::computeTracksMClabels()
411 for (
int iROF{0}; iROF < mTimeFrame->
getNrof(); ++iROF) {
412 for (
auto& track : mTimeFrame->
getTracks(iROF)) {
413 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
417 const int index = track.getClusterIndex(iCluster);
423 for (
size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
424 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
425 for (
auto&
label : labels) {
426 if (
label == occurrence.first) {
434 for (
auto&
label : labels) {
435 occurrences.emplace_back(
label, 1);
439 std::sort(std::begin(occurrences), std::end(occurrences), [](
auto e1,
auto e2) {
440 return e1.second > e2.second;
443 auto maxOccurrencesValue = occurrences[0].first;
444 uint32_t
pattern = track.getPattern();
447 auto clid = track.getClusterIndex(ic);
450 for (
auto& currentLabel : labelsSpan) {
451 if (currentLabel == maxOccurrencesValue) {
459 if (occurrences[0].second < track.getNumberOfClusters()) {
460 maxOccurrencesValue.setFakeFlag();
462 mTimeFrame->
getTracksLabel(iROF).emplace_back(maxOccurrencesValue);
467void Tracker::rectifyClusterIndices()
469 for (
int iROF{0}; iROF < mTimeFrame->
getNrof(); ++iROF) {
470 for (
auto& track : mTimeFrame->
getTracks(iROF)) {
472 const int index = track.getClusterIndex(iCluster);
484 if (tc.useMatCorrTGeo) {
486 }
else if (tc.useFastMaterial) {
492 int nROFsPerIterations = tc.nROFsPerIterations > 0 ? tc.nROFsPerIterations : -1;
493 if (tc.nOrbitsPerIterations > 0) {
496 for (
auto&
params : mTrkParams) {
497 if (
params.NLayers == 7) {
498 for (
int i{0};
i < 7; ++
i) {
499 params.SystErrorY2[
i] = tc.sysErrY2[
i] > 0 ? tc.sysErrY2[
i] :
params.SystErrorY2[
i];
500 params.SystErrorZ2[
i] = tc.sysErrZ2[
i] > 0 ? tc.sysErrZ2[
i] :
params.SystErrorZ2[
i];
503 params.DeltaROF = tc.deltaRof;
504 params.DoUPCIteration = tc.doUPCIteration;
505 params.MaxChi2ClusterAttachment = tc.maxChi2ClusterAttachment > 0 ? tc.maxChi2ClusterAttachment :
params.MaxChi2ClusterAttachment;
506 params.MaxChi2NDF = tc.maxChi2NDF > 0 ? tc.maxChi2NDF :
params.MaxChi2NDF;
507 params.PhiBins = tc.LUTbinsPhi > 0 ? tc.LUTbinsPhi :
params.PhiBins;
508 params.ZBins = tc.LUTbinsZ > 0 ? tc.LUTbinsZ :
params.ZBins;
510 params.NSigmaCut *= tc.nSigmaCut > 0 ? tc.nSigmaCut : 1.f;
511 params.CellDeltaTanLambdaSigma *= tc.deltaTanLres > 0 ? tc.deltaTanLres : 1.f;
512 params.TrackletMinPt *= tc.minPt > 0 ? tc.minPt : 1.f;
513 params.nROFsPerIterations = nROFsPerIterations;
514 params.PerPrimaryVertexProcessing = tc.perPrimaryVertexProcessing;
515 params.SaveTimeBenchmarks = tc.saveTimeBenchmarks;
516 params.FataliseUponFailure = tc.fataliseUponFailure;
517 params.DropTFUponFailure = tc.dropTFUponFailure;
518 for (
int iD{0}; iD < 3; ++iD) {
519 params.Diamond[iD] = tc.diamondPos[iD];
521 params.UseDiamond = tc.useDiamond;
523 params.MaxMemory = tc.maxMemory;
525 if (tc.useTrackFollower > 0) {
526 params.UseTrackFollower =
true;
530 params.UseTrackFollowerMix = ((tc.useTrackFollower & (1 << 0)) != 0);
531 params.UseTrackFollowerTop = ((tc.useTrackFollower & (1 << 1)) != 0);
532 params.UseTrackFollowerBot = ((tc.useTrackFollower & (1 << 2)) != 0);
533 params.TrackFollowerNSigmaCutZ = tc.trackFollowerNSigmaZ;
534 params.TrackFollowerNSigmaCutPhi = tc.trackFollowerNSigmaPhi;
536 if (tc.cellsPerClusterLimit >= 0) {
537 params.CellsPerClusterLimit = tc.cellsPerClusterLimit;
539 if (tc.trackletsPerClusterLimit >= 0) {
540 params.TrackletsPerClusterLimit = tc.trackletsPerClusterLimit;
542 if (tc.findShortTracks >= 0) {
543 params.FindShortTracks = tc.findShortTracks;
Class to handle Kalman smoothing for ITS tracking. Its instance stores the state of the track to the ...
static const TrackerParamConfig & Instance()
gsl::span< const Vertex > getPrimaryVertices(int rofId) const
int mNExtendedUsedClusters
unsigned long getArtefactsMemory()
void setRoadLabel(int i, const unsigned long long &lab, bool fake)
std::vector< std::vector< CellSeed > > & getCells()
std::vector< MCCompLabel > & getTracksLabel(const int rofId)
bool hasMCinformation() const
std::vector< std::vector< Cluster > > & getClusters()
void initialiseRoadLabels()
std::vector< Road< 5 > > & getRoads()
size_t getNumberOfTracks() const
bool checkMemory(unsigned long max)
int getNumberOfNeighbours() const
int getClusterExternalIndex(int layerId, const int clId) const
const gsl::span< const MCCompLabel > getClusterLabels(int layerId, const Cluster &cl) const
void printSliceInfo(const int, const int)
static constexpr int MaxClusters
< heavy version of TrackITS, with clusters embedded
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 void computeCellsHybrid(const int iteration)
virtual int getTFNumberOfTracklets() const
virtual void findRoadsHybrid(const int iteration)
virtual void computeTrackletsHybrid(const int iteration, int, int)
virtual void findCellsNeighbours(const int iteration)
virtual void findTracksHybrid(const int iteration)
virtual int getTFNumberOfClusters() const
virtual void findShortPrimaries()
virtual void initialiseTimeFrame(const int iteration)
virtual void initialiseTimeFrameHybrid(const int iteration)
void UpdateTrackingParameters(const std::vector< TrackingParameters > &trkPars)
virtual void findCellsNeighboursHybrid(const int iteration)
void setCorrType(const o2::base::PropagatorImpl< float >::MatCorrType type)
virtual void findTracks()
virtual void computeLayerCells(const int iteration)
void adoptTimeFrame(TimeFrame &tf)
void setCorrType(const o2::base::PropagatorImpl< float >::MatCorrType type)
std::uint32_t mTimeFrameCounter
std::vector< TrackITSExt > & getTracks()
void clustersToTracksHybrid(std::function< void(std::string s)>=[](std::string s) { std::cout<< s<< std::endl;}, std::function< void(std::string s)>=[](std::string s) { std::cerr<< s<< std::endl;})
void clustersToTracks(std::function< void(std::string s)>=[](std::string s) { std::cout<< s<< std::endl;}, std::function< void(std::string s)>=[](std::string s) { std::cerr<< s<< std::endl;})
void getGlobalConfiguration()
Tracker(TrackerTraits *traits)
GLint GLint GLsizei GLint GLenum GLenum type
GLenum const GLfloat * params
GLuint GLsizei const GLchar * label
constexpr int UnusedIndex
constexpr bool DoTimeBenchmarks
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