Skip to content

Commit d482315

Browse files
sawenzelclaude
andauthored
Write tracked V0s, cascades and 3-bodies in collision order (#15838)
* Write tracked V0s, cascades and 3-bodies in collision order This fixes the row order of the tracked strangeness tables written by the AOD producer. - The tracked V0, cascade and 3-body rows were written in strangeness-tracker order, which is not always collision order. - Analyses slicing them by collision then abort with "TraCascIndices index fIndexCollisions is not sorted". - The rows are now written in the per-collision order already built in prepareStrangenessTracking. - The track index of a row no longer comes from a running counter, so a skipped strange track cannot shift the rows after it. https://its.cern.ch/jira/browse/O2-7197 * Keep strange tracks in decay order also with one vertexer thread This makes the order of the tracked strangeness tables within a collision the same in MC as in data. - SVertexer sorted the strange tracks by decay only when running with more than one thread; MC reconstruction runs it with one. - The strange tracks are now sorted by decay in all cases. - The AOD producer groups them by collision with a stable sort, so the decay order within a collision is kept. https://its.cern.ch/jira/browse/O2-7197 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent cd59f17 commit d482315

2 files changed

Lines changed: 10 additions & 8 deletions

File tree

‎Detectors/AOD/src/AODProducerWorkflowSpec.cxx‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,7 @@ void AODProducerWorkflowDPL::prepareStrangenessTracking(const o2::globaltracking
15271527
std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
15281528

15291529
// sort by collision ID
1530-
std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](const auto& a, const auto& b) { return a.first < b.first; });
1530+
std::stable_sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](const auto& a, const auto& b) { return a.first < b.first; });
15311531
mStrTrkIndices.clear();
15321532
mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
15331533
}
@@ -1536,7 +1536,6 @@ template <typename V0C, typename CC, typename D3BC>
15361536
void AODProducerWorkflowDPL::fillStrangenessTrackingTables(const o2::globaltracking::RecoContainer& recoData, V0C& v0Curs, CC& cascCurs, D3BC& d3BodyCurs)
15371537
{
15381538
int itsTableIdx = -1;
1539-
int sTrkID = 0;
15401539
int nV0 = 0;
15411540
int nCasc = 0;
15421541
int nD3Body = 0;
@@ -1555,7 +1554,10 @@ void AODProducerWorkflowDPL::fillStrangenessTrackingTables(const o2::globaltrack
15551554
cascCurs.reserve(nCasc);
15561555
d3BodyCurs.reserve(nD3Body);
15571556

1558-
for (const auto& sTrk : recoData.getStrangeTracks()) {
1557+
// Write the rows grouped by collision, the order analyses slice these tables in
1558+
auto sTracks = recoData.getStrangeTracks();
1559+
for (const auto& collStrTrk : mCollisionStrTrk) {
1560+
const auto& sTrk = sTracks[collStrTrk.second];
15591561
auto ITSIndex = GIndex{sTrk.mITSRef, GIndex::ITS};
15601562
auto item = mGIDToTableID.find(ITSIndex);
15611563
if (item != mGIDToTableID.end()) {
@@ -1565,7 +1567,7 @@ void AODProducerWorkflowDPL::fillStrangenessTrackingTables(const o2::globaltrack
15651567
continue;
15661568
}
15671569
if (sTrk.mPartType == dataformats::kStrkV0) {
1568-
v0Curs(mStrTrkIndices[sTrkID++],
1570+
v0Curs(mStrTrkIndices[collStrTrk.second],
15691571
itsTableIdx,
15701572
sTrk.mDecayRef,
15711573
sTrk.mDecayVtx[0],
@@ -1577,7 +1579,7 @@ void AODProducerWorkflowDPL::fillStrangenessTrackingTables(const o2::globaltrack
15771579
sTrk.mTopoChi2,
15781580
sTrk.getAverageClusterSize());
15791581
} else if (sTrk.mPartType == dataformats::kStrkCascade) {
1580-
cascCurs(mStrTrkIndices[sTrkID++],
1582+
cascCurs(mStrTrkIndices[collStrTrk.second],
15811583
itsTableIdx,
15821584
sTrk.mDecayRef,
15831585
sTrk.mDecayVtx[0],
@@ -1589,7 +1591,7 @@ void AODProducerWorkflowDPL::fillStrangenessTrackingTables(const o2::globaltrack
15891591
sTrk.mTopoChi2,
15901592
sTrk.getAverageClusterSize());
15911593
} else {
1592-
d3BodyCurs(mStrTrkIndices[sTrkID++],
1594+
d3BodyCurs(mStrTrkIndices[collStrTrk.second],
15931595
itsTableIdx,
15941596
sTrk.mDecayRef,
15951597
sTrk.mDecayVtx[0],

‎Detectors/Vertexing/src/SVertexer.cxx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ void SVertexer::produceOutput(o2::framework::ProcessingContext& pc)
225225

226226
std::vector<int> sortIdx(strTracksTmp.size());
227227
std::iota(sortIdx.begin(), sortIdx.end(), 0);
228-
// if mNTreads > 1 we need to sort tracks, clus and MCLabs by their mDecayRef
229-
if (mNThreads > 1 && mNStrangeTracks > 1) {
228+
// sort tracks, clus and MCLabs by their mDecayRef, also with one thread, so that they follow the vertex order
229+
if (mNStrangeTracks > 1) {
230230
std::sort(sortIdx.begin(), sortIdx.end(), [&strTracksTmp](int i1, int i2) { return strTracksTmp[i1].mDecayRef < strTracksTmp[i2].mDecayRef; });
231231
}
232232

0 commit comments

Comments
 (0)