Skip to content

Commit 4b20375

Browse files
committed
GPU TPC: Fix sorting of clusters in segments of looping tracks
1 parent d4af477 commit 4b20375

File tree

3 files changed

+93
-35
lines changed

3 files changed

+93
-35
lines changed

GPU/GPUTracking/Merger/GPUTPCGMMerger.cxx

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,13 +1435,14 @@ namespace // anonymous
14351435
{
14361436
struct GPUTPCGMMerger_CompareClusterIds {
14371437
const GPUTPCGMMerger::trackCluster* const mCmp;
1438-
GPUd() GPUTPCGMMerger_CompareClusterIds(const GPUTPCGMMerger::trackCluster* cmp) : mCmp(cmp) {}
1438+
const bool revert;
1439+
GPUd() GPUTPCGMMerger_CompareClusterIds(const GPUTPCGMMerger::trackCluster* cmp, bool r) : mCmp(cmp), revert(r) {}
14391440
GPUd() bool operator()(const int16_t aa, const int16_t bb)
14401441
{
14411442
const GPUTPCGMMerger::trackCluster& a = mCmp[aa];
14421443
const GPUTPCGMMerger::trackCluster& b = mCmp[bb];
14431444
if (a.row != b.row) {
1444-
return (a.row > b.row);
1445+
return (a.row > b.row) ^ revert;
14451446
}
14461447
return GPUCA_DETERMINISTIC_CODE((a.id != b.id) ? (a.id > b.id) : (aa > bb), a.id > b.id);
14471448
}
@@ -1460,6 +1461,8 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThread
14601461
GPUTPCGMSectorTrack* trbase = nullptr;
14611462
int32_t leg = 0;
14621463
int32_t lastMergedSegment = -1;
1464+
bool revertSegments = false;
1465+
bool revertInSegment = false;
14631466
while (true) {
14641467
if (trbase && !Param().rec.tpc.dropLoopers) {
14651468
int32_t jtr = trbase->NextNeighbour();
@@ -1469,7 +1472,7 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThread
14691472
trbase = nullptr;
14701473
} else {
14711474
trbase->SetPrevSegmentNeighbour(1000000001);
1472-
leg--;
1475+
leg += revertSegments ? 1 : -1;
14731476
}
14741477
} else {
14751478
trbase = nullptr;
@@ -1488,15 +1491,68 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThread
14881491
if (itr >= SectorTrackInfoLocalTotal()) {
14891492
break;
14901493
}
1491-
itr += nThreads * nBlocks;
1494+
revertSegments = false;
1495+
revertInSegment = false;
14921496
trbase->SetPrevSegmentNeighbour(1000000000);
14931497
int32_t jtr = trbase->NextNeighbour();
14941498
leg = 0;
1495-
while (jtr >= 0) {
1496-
leg++;
1497-
jtr = mSectorTrackInfos[jtr].NextNeighbour();
1499+
if (jtr >= 0) {
1500+
int32_t lasttr = itr;
1501+
while (jtr >= 0) { // --------------- count segments ---------------
1502+
if (&mSectorTrackInfos[jtr] == trbase) {
1503+
break; // Break cyclic graph
1504+
}
1505+
lasttr = jtr;
1506+
leg++;
1507+
jtr = mSectorTrackInfos[jtr].NextNeighbour();
1508+
}
1509+
1510+
float mainZT = 1e9;
1511+
revertSegments = true;
1512+
for (uint32_t k = 0; k < 2; k++) { // --------------- check if first or last segment is primary ---------------
1513+
int32_t ichk = k ? lasttr : itr;
1514+
const GPUTPCGMSectorTrack* trchk = &mSectorTrackInfos[ichk];
1515+
while (true) {
1516+
float zt = Param().par.earlyTpcTransform ? CAMath::Min(CAMath::Abs(trchk->ClusterZT0()), CAMath::Abs(trchk->ClusterZTN())) : -trchk->MinClusterZT(); // Negative time ~ smallest z, behaves the same way
1517+
if (zt < mainZT) {
1518+
if (k) {
1519+
revertSegments = false;
1520+
break;
1521+
}
1522+
mainZT = zt;
1523+
}
1524+
int32_t next = trchk->NextSegmentNeighbour();
1525+
if (next < 0 || next == ichk) {
1526+
break; // Breaks also cycles
1527+
}
1528+
trchk = &mSectorTrackInfos[next];
1529+
}
1530+
}
1531+
if (revertSegments) {
1532+
leg = 0;
1533+
}
1534+
1535+
{ // --------------- find longest sector track of main segment ---------------
1536+
int32_t length = 0;
1537+
int32_t ichk = revertSegments ? itr : lasttr;
1538+
const GPUTPCGMSectorTrack* trchk = &mSectorTrackInfos[ichk];
1539+
const GPUTPCGMSectorTrack* longest = trchk;
1540+
while (true) {
1541+
if (trchk->OrigTrack()->NHits() > length) {
1542+
longest = trchk;
1543+
length = trchk->OrigTrack()->NHits();
1544+
}
1545+
int32_t next = trchk->NextSegmentNeighbour();
1546+
if (next < 0 || next == ichk) {
1547+
break; // Breaks also cycles
1548+
}
1549+
trchk = &mSectorTrackInfos[next];
1550+
}
1551+
revertInSegment = (longest->ClusterZT0() < longest->ClusterZTN()) ^ (Param().par.earlyTpcTransform ? !longest->CSide() : false);
1552+
}
14981553
}
14991554
lastMergedSegment = -1;
1555+
itr += nThreads * nBlocks;
15001556
}
15011557

15021558
do {
@@ -1513,7 +1569,6 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThread
15131569
}
15141570
nHits += tr->NClusters();
15151571

1516-
tr->SetLeg(leg);
15171572
trackParts[nParts++] = tr;
15181573
for (int32_t i = 0; i < 2; i++) {
15191574
if (tr->ExtrapolatedTrackId(i) != -1) {
@@ -1523,8 +1578,7 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThread
15231578
if (nHits + mSectorTrackInfos[tr->ExtrapolatedTrackId(i)].NClusters() > kMaxClusters) {
15241579
break;
15251580
}
1526-
trackParts[nParts] = &mSectorTrackInfos[tr->ExtrapolatedTrackId(i)];
1527-
trackParts[nParts++]->SetLeg(leg);
1581+
trackParts[nParts++] = &mSectorTrackInfos[tr->ExtrapolatedTrackId(i)];
15281582
nHits += mSectorTrackInfos[tr->ExtrapolatedTrackId(i)].NClusters();
15291583
}
15301584
}
@@ -1538,7 +1592,7 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThread
15381592
}
15391593

15401594
// unpack and sort clusters
1541-
if (nParts > 1) {
1595+
if (nParts > 1 && (!revertInSegment ^ (leg & 1))) {
15421596
GPUCommonAlgorithm::sort(trackParts, trackParts + nParts, [](const GPUTPCGMSectorTrack* a, const GPUTPCGMSectorTrack* b) {
15431597
GPUCA_DETERMINISTIC_CODE( // clang-format off
15441598
if (a->X() != b->X()) {
@@ -1576,11 +1630,14 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThread
15761630
break;
15771631
}
15781632

1579-
bool ordered = true;
1580-
for (int32_t i = 1; i < nHits; i++) {
1581-
if (trackClusters[i].row > trackClusters[i - 1].row || trackClusters[i].id == trackClusters[i - 1].id) {
1582-
ordered = false;
1583-
break;
1633+
const bool mustReverse = revertInSegment ^ (leg & 1);
1634+
bool ordered = !mustReverse;
1635+
if (ordered) {
1636+
for (int32_t i = 1; i < nHits; i++) {
1637+
if ((trackClusters[i].row > trackClusters[i - 1].row) ^ mustReverse || trackClusters[i].id == trackClusters[i - 1].id) {
1638+
ordered = false;
1639+
break;
1640+
}
15841641
}
15851642
}
15861643
int32_t firstTrackIndex = 0;
@@ -1594,7 +1651,7 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThread
15941651
clusterIndices[i] = i;
15951652
}
15961653

1597-
GPUCommonAlgorithm::sort(clusterIndices, clusterIndices + nHits, GPUTPCGMMerger_CompareClusterIds(trackClusters));
1654+
GPUCommonAlgorithm::sort(clusterIndices, clusterIndices + nHits, GPUTPCGMMerger_CompareClusterIds(trackClusters, mustReverse));
15981655

15991656
nTmpHits = 0;
16001657
firstTrackIndex = lastTrackIndex = -1;
@@ -1659,16 +1716,24 @@ GPUd() void GPUTPCGMMerger::CollectMergedTracks(int32_t nBlocks, int32_t nThread
16591716
}
16601717

16611718
GPUTPCGMMergedTrack& mergedTrack = mMergedTracks[iOutputTrack];
1719+
GPUTPCGMTrackParam& p1 = mergedTrack.Param();
1720+
const GPUTPCGMSectorTrack& p2 = *trackParts[firstTrackIndex];
16621721
mergedTrack.SetFlags(0);
16631722
mergedTrack.SetOK(true);
1664-
mergedTrack.SetLooper(leg > 0 || lastMergedSegment >= 0);
1723+
mergedTrack.SetLeg(leg);
1724+
mergedTrack.SetLooper(leg > 0 || lastMergedSegment >= 0 || revertSegments);
16651725
mergedTrack.SetNClusters(nHits);
16661726
mergedTrack.SetFirstClusterRef(iMergedTrackFirstCluster);
1667-
GPUTPCGMTrackParam& p1 = mergedTrack.Param();
1668-
const GPUTPCGMSectorTrack& p2 = *trackParts[firstTrackIndex];
16691727
mergedTrack.SetCSide(p2.CSide());
16701728
mergedTrack.SetMergedLooperConnected(leg > 0);
1671-
mergedTrack.SetPrevSegment(lastMergedSegment);
1729+
if (revertSegments) {
1730+
mergedTrack.SetPrevSegment(-1);
1731+
if (lastMergedSegment >= 0) {
1732+
mMergedTracks[lastMergedSegment].SetPrevSegment(iOutputTrack);
1733+
}
1734+
} else {
1735+
mergedTrack.SetPrevSegment(lastMergedSegment);
1736+
}
16721737
lastMergedSegment = iOutputTrack;
16731738

16741739
GPUTPCGMBorderTrack b;

GPU/GPUTracking/Merger/GPUTPCGMSectorTrack.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ class GPUTPCGMSectorTrack
5555
GPUd() float DzDs() const { return mParam.mDzDs; }
5656
GPUd() float QPt() const { return mParam.mQPt; }
5757
GPUd() float TZOffset() const { return mTZOffset; }
58-
GPUd() uint8_t Leg() const { return mLeg; }
5958

6059
GPUd() int32_t LocalTrackId() const { return mLocalTrackId; }
6160
GPUd() void SetLocalTrackId(int32_t v) { mLocalTrackId = v; }
@@ -99,7 +98,6 @@ class GPUTPCGMSectorTrack
9998
GPUd() void SetNeighbor(int32_t v, int32_t i) { mNeighbour[i] = v; }
10099
GPUd() void SetPrevSegmentNeighbour(int32_t v) { mSegmentNeighbour[0] = v; }
101100
GPUd() void SetNextSegmentNeighbour(int32_t v) { mSegmentNeighbour[1] = v; }
102-
GPUd() void SetLeg(uint8_t v) { mLeg = v; }
103101

104102
GPUd() void CopyParamFrom(const GPUTPCGMSectorTrack& t)
105103
{
@@ -136,7 +134,6 @@ class GPUTPCGMSectorTrack
136134
int32_t mLocalTrackId; // Corrected local track id in terms of GMSectorTracks array for extrapolated tracks, UNDEFINED for local tracks!
137135
int32_t mExtrapolatedTrackIds[2]; // IDs of associated extrapolated tracks
138136
uint8_t mSector; // sector of this track segment
139-
uint8_t mLeg; // Leg of this track segment
140137

141138
ClassDefNV(GPUTPCGMSectorTrack, 1);
142139
};

GPU/GPUTracking/display/render/GPUDisplayDraw.cxx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ void GPUDisplay::DrawFinal(int32_t iSector, int32_t /*iCol*/, const GPUTPCGMProp
376376

377377
size_t startCountInner = mVertexBuffer[iSector].size();
378378
bool drawing = false;
379+
uint32_t lastSide = -1;
379380

380381
if constexpr (std::is_same_v<T, o2::tpc::TrackTPC>) {
381382
if (!mCfgH.drawTracksAndFilter && !(mCfgH.drawTPCTracks || (mCfgH.drawITSTracks && mIOPtrs->tpcLinkITS && mIOPtrs->tpcLinkITS[i] != -1) || (mCfgH.drawTRDTracks && mIOPtrs->tpcLinkTRD && mIOPtrs->tpcLinkTRD[i] != -1) || (mCfgH.drawTOFTracks && mIOPtrs->tpcLinkTOF && mIOPtrs->tpcLinkTOF[i] != -1))) {
@@ -397,6 +398,7 @@ void GPUDisplay::DrawFinal(int32_t iSector, int32_t /*iCol*/, const GPUTPCGMProp
397398
drawing = true;
398399
mVertexBuffer[iSector].emplace_back(mGlobalPosTOF[cid].x, mGlobalPosTOF[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTOF[cid].z);
399400
mGlobalPosTOF[cid].w = tTOFATTACHED;
401+
lastSide = mGlobalPosTOF[cid].z < 0;
400402
}
401403
}
402404

@@ -410,6 +412,7 @@ void GPUDisplay::DrawFinal(int32_t iSector, int32_t /*iCol*/, const GPUTPCGMProp
410412
drawing = true;
411413
mVertexBuffer[iSector].emplace_back(mGlobalPosTRD2[cid].x, mGlobalPosTRD2[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD2[cid].z);
412414
mVertexBuffer[iSector].emplace_back(mGlobalPosTRD[cid].x, mGlobalPosTRD[cid].y * mYFactor, mCfgH.projectXY ? 0 : mGlobalPosTRD[cid].z);
415+
lastSide = mGlobalPosTRD[cid].z < 0;
413416
mGlobalPosTRD[cid].w = tTRDATTACHED;
414417
}
415418
};
@@ -433,17 +436,15 @@ void GPUDisplay::DrawFinal(int32_t iSector, int32_t /*iCol*/, const GPUTPCGMProp
433436

434437
// Print TPC part of track
435438
int32_t separateExtrapolatedTracksLimit = (mCfgH.separateExtrapolatedTracks ? tEXTRAPOLATEDTRACK : TRACK_TYPE_ID_LIMIT);
436-
uint32_t lastSide = -1;
437-
int32_t prevcid = -1;
438-
int32_t leg = 0;
439439
if constexpr (std::is_same_v<T, GPUTPCGMMergedTrack>) {
440440
if (track->PrevSegment() >= 0) {
441441
const auto& prevtrk = mIOPtrs->mergedTracks[track->PrevSegment()];
442-
leg = track->Leg();
443-
for (int32_t iChk = (leg & 1) ? (prevtrk.NClusters() - 1) : 0; iChk != ((leg & 1) ? -1 : (int32_t)prevtrk.NClusters()); iChk += (leg & 1) ? -1 : 1) {
442+
for (int32_t iChk = prevtrk.NClusters() - 1; iChk >= 0; iChk--) {
444443
const auto& hit = mIOPtrs->mergedTrackHits[prevtrk.FirstClusterRef() + iChk];
445444
if (!mCfgH.hideRejectedClusters || !(hit.state & GPUTPCGMMergedTrackHit::flagReject)) {
446-
prevcid = hit.num;
445+
drawPointLinestrip(iSector, hit.num, tFINALTRACK, separateExtrapolatedTracksLimit);
446+
lastSide = mGlobalPos[hit.num].z < 0;
447+
drawing = true;
447448
break;
448449
}
449450
}
@@ -488,8 +489,6 @@ void GPUDisplay::DrawFinal(int32_t iSector, int32_t /*iCol*/, const GPUTPCGMProp
488489
lastcid = &track->getCluster(mIOPtrs->outputClusRefsTPCO2, lastCluster, *mIOPtrs->clustersNative) - mIOPtrs->clustersNative->clustersLinear;
489490
}
490491
drawPointLinestrip(iSector, lastcid, tFINALTRACK, separateExtrapolatedTracksLimit);
491-
} else if (prevcid != -1 && k == 0 && (leg & 1) == 0) {
492-
drawPointLinestrip(iSector, prevcid, tFINALTRACK, separateExtrapolatedTracksLimit);
493492
}
494493
drawPointLinestrip(iSector, cid, tFINALTRACK, separateExtrapolatedTracksLimit);
495494
}
@@ -498,9 +497,6 @@ void GPUDisplay::DrawFinal(int32_t iSector, int32_t /*iCol*/, const GPUTPCGMProp
498497
lastCluster = k;
499498
lastSide = mGlobalPos[cid].z < 0;
500499
}
501-
if (prevcid != -1 && (leg & 1) && drawing) {
502-
drawPointLinestrip(iSector, prevcid, tFINALTRACK, separateExtrapolatedTracksLimit);
503-
}
504500

505501
// Print ITS part of track
506502
if constexpr (std::is_same_v<T, o2::tpc::TrackTPC>) {

0 commit comments

Comments
 (0)