From 1d089f7120d1ae623c07898cf03f5e5136f5bbf5 Mon Sep 17 00:00:00 2001 From: Sandro Wenzel Date: Tue, 22 Sep 2026 22:26:13 +0200 Subject: [PATCH] Fix out-of-range BC slice for ambiguous tracks past the last BC This fixes a problem in the AOD producer's BC slice assignment for ambiguous tracks. - BunchCrossings::lower_bound returns {size(), 0} when no BC is at or after the requested one, and fillBCSlice used that pair unchecked. - A track whose time window starts after the last BC of the timeframe therefore got fIndexSliceBCs[0] equal to the number of BCs, one past the end of the BC table. - The same pair sets the time reference, where 0 - mStartIR.toLong() underflows in unsigned arithmetic, so fTrackTime was written as about -4.6e20 ns. - The binary-search implementation that the accelerated lookup replaced clamped this case to the last BC; fillBCSlice now does the same. - Seen in LHC26a5a_gp_2025_v10 (Pb-Pb apass1 anchored MC), where 51 of 736770 ambiguous tracks were affected and later crashed the AnalysisQC event selection QA task. Co-Authored-By: Claude Opus 5 --- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 385a9930d8f66..06f2cfb0301e5 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -3367,6 +3367,13 @@ std::uint64_t AODProducerWorkflowDPL::fillBCSlice(int (&slice)[2], double tmin, // the time becomes larger than bcMax. // (if this is not the case we could determine it with a similar call to mBCLookup) auto& bcvector = mBCLookup.getBCTimeVector(); + // lower_bound reports {size(), 0} when no BC is at or after bcMin, i.e. the track time + // window starts past the last BC of the timeframe. Clamp to the last BC, as the binary + // search above does, so that the slice stays in range and the time reference stays valid. + if (p.first >= bcvector.size()) { + p.first = bcvector.size() - 1; + p.second = bcvector[p.first]; + } auto upperindex = p.first; while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) { upperindex++;