From e0045d993703f30c5bb905a02fa598a2230f6942 Mon Sep 17 00:00:00 2001 From: jdkio Date: Wed, 19 Aug 2026 15:03:38 -0400 Subject: [PATCH] Prevent track matcher index underflow loops --- CHANGELOG.md | 1 + src/TMS_Reco.cpp | 35 ++++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 524b1d62..b23c5195 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Geometry releases will be tagged as `Descriptive_tag_v_X.Y.Z`. ## [MAIN] - Unreleased - Changed MergeTracks default to True. - Hits trailing the end of a Hough Track can now be added to the track they 'should' correspond to. ON by default, switchable in config. +- Prevent 3D track matching from looping indefinitely when the last hit in a required view lies outside the detector bounds. ## [Version 0.2] - 2023-12-13 - Areal density calculation fixed, affected Muon KE reconstruction diff --git a/src/TMS_Reco.cpp b/src/TMS_Reco.cpp index d691167a..5769ef9f 100644 --- a/src/TMS_Reco.cpp +++ b/src/TMS_Reco.cpp @@ -1320,21 +1320,32 @@ std::vector TMS_TrackFinder::TrackMatching3D() { // if (Xrun) std::cout <<"itX:"< 4000.0 || UTracks[itU].GetZ() < 11000 || UTracks[itU].GetZ() > 20000) { - --itU; + if (itU == 0) view_exhausted = true; + else --itU; hit_outside = true; } if (std::abs(VTracks[itV].GetNotZ()) > 4000.0 || VTracks[itV].GetZ() < 11000 || VTracks[itV].GetZ() > 20000) { - --itV; + if (itV == 0) view_exhausted = true; + else --itV; hit_outside = true; } if (Xrun && Xback_match && Xfront_match) { if (XTracks[itX].GetNotZ() > 400. || XTracks[itX].GetNotZ() < -4000. || XTracks[itX].GetZ() < 11000 || XTracks[itX].GetZ() > 20000) { - --itX; + if (itX == 0) view_exhausted = true; + else --itX; hit_outside = true; } } - if (hit_outside) continue; + // There is no valid hit left in at least one required view. Continuing + // would decrement its index below zero and read outside the vector. + if (view_exhausted) break; + if (hit_outside) { + sane = (itU > 0 || itV > 0); + if (Xrun && Xback_match && Xfront_match) sane = sane || itX > 0; + continue; + } // Stereo check bool stereo_view = true; @@ -2137,17 +2148,27 @@ std::vector TMS_TrackFinder::TrackMatching3D_XY() { // std::cout <<"itX:"< 500.0 || XTracks[itX].GetNotZ() == 0. || XTracks[itX].GetNotZ() < -4000.0 || XTracks[itX].GetZ() < 11000 || XTracks[itX].GetZ() > 20000) { - --itX; + if (itX == 0) view_exhausted = true; + else --itX; hit_outside = true; } if (std::abs(YTracks[itY].GetNotZ()) > 4000.0 or YTracks[itY].GetNotZ() == 0. || YTracks[itY].GetZ() < 11000 || YTracks[itY].GetZ() > 20000) { - --itY; + if (itY == 0) view_exhausted = true; + else --itY; hit_outside = true; } - if (hit_outside) continue; + // There is no valid hit left in at least one required view. + // Continuing would decrement its index below zero, skip the + // loop-condition update, and repeatedly read outside the vector. + if (view_exhausted) break; + if (hit_outside) { + sane = (itX > 0 || itY > 0); + continue; + } // Stereo check bool stereo_view = true;