From ee558ae622df6696882cdd7a83bba96ee1001ff0 Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Wed, 22 Jan 2025 21:32:03 +0000
Subject: [PATCH 01/14] computeSharedHits in TrackFindingAlg

---
 .../src/TrackFindingAlg.cxx                   | 74 ++++++++++++++++++-
 .../src/TrackFindingAlg.h                     |  5 ++
 2 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
index 680b57ea0857..6aaa2a9445c4 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
@@ -361,6 +361,8 @@ namespace ActsTrk
 
     ATH_MSG_DEBUG("    \\__ Created " << tracksContainer.size() << " tracks");
 
+    computeSharedHits(tracksContainer, measurements, event_stat);
+
     mon_nTracks = tracksContainer.size();
 
     copyStats(event_stat);
@@ -1008,6 +1010,72 @@ namespace ActsTrk
     return {enoughMeasurements, tooManyHoles, tooManyOutliers};
   }
 
+  // TODO we should make a common implementation in Acts Core at some point
+  void TrackFindingAlg::computeSharedHits(ActsTrk::MutableTrackContainer &tracks,
+                                          const detail::TrackFindingMeasurements &measurements,
+                                          EventStats &event_stat) const {
+    // Find shared hits in all the reconstructed tracks and update SharedHitFlag
+    // hit index -> list of multi traj indexes [traj, meas]
+
+    const auto measurementContainerOffsets = measurements.measurementContainerOffsets();
+    const std::size_t nMeasurements = measurements.nMeasurements();
+
+    auto containerOffset = [&measurementContainerOffsets](const auto *container) -> std::size_t {
+      for (const auto &[c, offset] : measurementContainerOffsets) {
+        if (c == container)
+          return offset;
+      }
+      return measurementContainerOffsets.size();  // skip this measurement
+    };
+
+    std::vector<std::size_t> firstTrackOnTheHit(nMeasurements, std::numeric_limits<std::size_t>::max());
+    std::vector<std::size_t> firstStateOnTheHit(nMeasurements, std::numeric_limits<std::size_t>::max());
+    std::size_t totShared = 0;
+
+    for (auto track : tracks) {
+      for (auto state : track.trackStatesReversed()) {
+        if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag))
+          continue;
+
+        if (!state.hasUncalibratedSourceLink())
+          continue;
+
+        auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
+        const xAOD::UncalibratedMeasurement &hit = getUncalibratedMeasurement(sl);
+        std::size_t hitIndex = hit.index() + containerOffset(hit.container());
+        if (!(hitIndex < nMeasurements)) {
+          ATH_MSG_WARNING("computeSharedHits: track measurement with index " << hit.index() << " not found in input");
+          continue;
+        }
+
+        // Check if hit not already used
+        if (firstTrackOnTheHit.at(hitIndex) == std::numeric_limits<std::size_t>::max()) {
+          firstTrackOnTheHit.at(hitIndex) = track.index();
+          firstStateOnTheHit.at(hitIndex) = state.index();
+          continue;
+        }
+
+        // if already used, control if first track state has been marked as shared
+        int indexFirstTrack = firstTrackOnTheHit.at(hitIndex);
+        int indexFirstState = firstStateOnTheHit.at(hitIndex);
+
+        auto firstState = tracks.getTrack(indexFirstTrack).container().trackStateContainer().getTrackState(indexFirstState);
+        if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
+          firstState.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
+        }
+
+        // Decorate this track state
+        state.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
+
+        double eta = -std::log(std::tan(0.5 * track.theta()));
+        std::size_t category_i = getStatCategory(0, eta);  // not useful (or easy) to separate by seed type, so use first one
+        ++event_stat[category_i][kNTotalSharedHits];
+        ++totShared;
+      }
+    }
+    ATH_MSG_DEBUG("found " << totShared << " shared hits among" << tracks.size() << "  tracks");
+  }
+
   // === Statistics printout =================================================
 
   void TrackFindingAlg::initStatTables()
@@ -1065,7 +1133,8 @@ namespace ActsTrk
                                           std::make_pair(kMultipleBranches, "Seeds with more than one branch"),
                                           std::make_pair(kNoSecond, "Tracks failing second CKF"),
                                           std::make_pair(kNStoppedTracksMinPt, "Stopped tracks below pT cut"),
-                                          std::make_pair(kNStoppedTracksMaxEta, "Stopped tracks above max eta")
+                                          std::make_pair(kNStoppedTracksMaxEta, "Stopped tracks above max eta"),
+                                          std::make_pair(kNTotalSharedHits, "Total shared hits")
                                       });
       assert(stat_labels.size() == kNStat);
       std::vector<std::string> categories;
@@ -1158,7 +1227,8 @@ namespace ActsTrk
                                                       TableUtils::defineSimpleRatio("selected / CKF tracks", kNSelectedTracks, kNOutputTracks),
                                                       TableUtils::defineSimpleRatio("selected tracks / used seeds", kNSelectedTracks, kNUsedSeeds),
                                                       TableUtils::defineSimpleRatio("branched tracks / used seeds", kMultipleBranches, kNUsedSeeds),
-                                                      TableUtils::defineSimpleRatio("no 2nd CKF / CKF tracks", kNoSecond, kNOutputTracks)});
+                                                      TableUtils::defineSimpleRatio("no 2nd CKF / CKF tracks", kNoSecond, kNOutputTracks),
+                                                      TableUtils::defineSimpleRatio("shared hits / CKF tracks", kNTotalSharedHits, kNOutputTracks)});
 
       std::vector<float> ratio = TableUtils::computeRatios(ratio_def,
                                                            nSeedCollections() + 1,
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
index 346e72cd727c..64c390941dee 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
@@ -172,6 +172,7 @@ namespace ActsTrk
       kNoSecond,
       kNStoppedTracksMinPt,
       kNStoppedTracksMaxEta,
+      kNTotalSharedHits,
       kNStat
     };
     using EventStats = std::vector<std::array<unsigned int, kNStat>>;
@@ -209,6 +210,10 @@ namespace ActsTrk
                        const detail::RecoTrackContainerProxy &track,
                        detail::DuplicateSeedDetector &duplicateSeedDetector) const;
 
+    void computeSharedHits(ActsTrk::MutableTrackContainer &tracks,
+                           const detail::TrackFindingMeasurements &measurements,
+                           EventStats &event_stat) const;
+
     // Access Acts::CombinatorialKalmanFilter etc using "pointer to implementation"
     // so we don't have to instantiate the heavily templated classes in the header.
     // To maintain const-correctness, only use this via the accessor functions.
-- 
GitLab


From 82c1804b7b708075b907e0a9562e79d5ac4d3741 Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Wed, 22 Jan 2025 21:47:36 +0000
Subject: [PATCH 02/14] fix comments

---
 .../src/TrackFindingAlg.cxx                       |  2 +-
 .../ActsTrackReconstruction/src/TrackFindingAlg.h | 15 ++++++++++-----
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
index 6aaa2a9445c4..39dd3731aca8 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
@@ -396,7 +396,7 @@ namespace ActsTrk
                               const ActsTrk::SeedContainer &seeds,
                               const InDetDD::SiDetectorElementCollection& detElements,
                               ActsTrk::MutableTrackContainer &tracksContainer,
-                              size_t typeIndex,
+                              std::size_t typeIndex,
                               const char *seedType,
                               EventStats &event_stat) const
   {
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
index 64c390941dee..7bc7ad928cba 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
@@ -184,12 +184,16 @@ namespace ActsTrk
      * @brief invoke track finding procedure
      *
      * @param ctx - event context
+     * @param trackingGeometry - Acts tracking geometry
+     * @param detectorElementToGeoId - map Trk detector element to Acts Geometry id
      * @param measurements - measurements container
+     * @param duplicateSeedDetector - duplicate seed detector
      * @param seeds - spacepoint triplet seeds
+     * @param detElements - Trk detector elements
      * @param tracksContainer - output tracks
-     * @param tracksCollection - auxiliary output for downstream tools compatibility (to be removed in the future)
-     * @param seedCollectionIndex - index of seeds in measurements
-     * @param seedType name of type of seeds (strip or pixel) - only used for messages
+     * @param seedCollectionIndex - index of this collection of seeds
+     * @param seedType - name of type of seeds (strip or pixel) - only used for messages
+     * @param event_stat - stats, just for this event
      */
     StatusCode
     findTracks(const EventContext &ctx,
@@ -200,16 +204,17 @@ namespace ActsTrk
                const ActsTrk::SeedContainer &seeds,
                const InDetDD::SiDetectorElementCollection& detElements,
                ActsTrk::MutableTrackContainer &tracksContainer,
-               size_t seedCollectionIndex,
+               std::size_t seedCollectionIndex,
                const char *seedType,
                EventStats &event_stat) const;
 
     // Create tracks from one seed's CKF result, appending to tracksContainer
-
     void storeSeedInfo(const detail::RecoTrackContainer &tracksContainer,
                        const detail::RecoTrackContainerProxy &track,
                        detail::DuplicateSeedDetector &duplicateSeedDetector) const;
 
+
+    // add shared hit flags to output tracks
     void computeSharedHits(ActsTrk::MutableTrackContainer &tracks,
                            const detail::TrackFindingMeasurements &measurements,
                            EventStats &event_stat) const;
-- 
GitLab


From f25f56c47970a7e32985cd126399e73ef8ffb963 Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Thu, 23 Jan 2025 16:21:54 +0000
Subject: [PATCH 03/14] MR comments

---
 .../ActsTrackReconstruction/src/TrackFindingAlg.cxx | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
index 39dd3731aca8..6af1354aa70f 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
@@ -1010,12 +1010,11 @@ namespace ActsTrk
     return {enoughMeasurements, tooManyHoles, tooManyOutliers};
   }
 
-  // TODO we should make a common implementation in Acts Core at some point
   void TrackFindingAlg::computeSharedHits(ActsTrk::MutableTrackContainer &tracks,
                                           const detail::TrackFindingMeasurements &measurements,
                                           EventStats &event_stat) const {
     // Find shared hits in all the reconstructed tracks and update SharedHitFlag
-    // hit index -> list of multi traj indexes [traj, meas]
+    // hit index -> list of track indexes [track, state]
 
     const auto measurementContainerOffsets = measurements.measurementContainerOffsets();
     const std::size_t nMeasurements = measurements.nMeasurements();
@@ -1049,15 +1048,15 @@ namespace ActsTrk
         }
 
         // Check if hit not already used
-        if (firstTrackOnTheHit.at(hitIndex) == std::numeric_limits<std::size_t>::max()) {
-          firstTrackOnTheHit.at(hitIndex) = track.index();
-          firstStateOnTheHit.at(hitIndex) = state.index();
+        if (firstTrackOnTheHit[hitIndex] == std::numeric_limits<std::size_t>::max()) {
+          firstTrackOnTheHit[hitIndex] = track.index();
+          firstStateOnTheHit[hitIndex] = state.index();
           continue;
         }
 
         // if already used, control if first track state has been marked as shared
-        int indexFirstTrack = firstTrackOnTheHit.at(hitIndex);
-        int indexFirstState = firstStateOnTheHit.at(hitIndex);
+        int indexFirstTrack = firstTrackOnTheHit[hitIndex];
+        int indexFirstState = firstStateOnTheHit[hitIndex];
 
         auto firstState = tracks.getTrack(indexFirstTrack).container().trackStateContainer().getTrackState(indexFirstState);
         if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
-- 
GitLab


From a2dea921bf88a93fc9a88a2573cda14bd549ec38 Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Thu, 23 Jan 2025 20:28:59 +0000
Subject: [PATCH 04/14] Added measurements.measurementIndex(measurement), which
 should now work with cache

---
 .../src/TrackExtensionAlg.cxx                 |  2 +-
 .../src/TrackFindingAlg.cxx                   | 28 +++++--------
 .../src/TrackFindingAlg.h                     |  4 +-
 .../src/TrackStatePrinterTool.cxx             |  4 +-
 .../src/TrackStatePrinterTool.h               | 10 +++--
 .../src/TrackStatePrinterTool.icc             | 26 +++++--------
 .../src/detail/TrackFindingMeasurements.cxx   | 39 +++++++------------
 .../src/detail/TrackFindingMeasurements.h     |  9 +++--
 .../src/detail/TrackFindingMeasurements.icc   | 39 ++++++++++++++++---
 .../test/TrackFindingMeasurementsTest.cxx     | 34 +++++++---------
 10 files changed, 100 insertions(+), 95 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
index 41b6595d709d..03246ba42379 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
@@ -208,7 +208,7 @@ namespace ActsTrk{
         ATH_MSG_DEBUG("Reco MTJ size " << trackStateBackend.size() );
         for ( size_t stateIndex=0; stateIndex < trackStateBackend.size(); ++stateIndex) {
           auto state = trackStateBackend.getTrackState(stateIndex);
-          if (m_trackStatePrinter.isSet()) m_trackStatePrinter->printTrackState(tgContext, state, measurements.measurementContainerOffsets(), false);
+          if (m_trackStatePrinter.isSet()) m_trackStatePrinter->printTrackState(tgContext, state, measurements, false);
         }
         ATH_MSG_DEBUG("Track has: " << tempTrackProxy.nMeasurements() << " measurements ");
         ATH_MSG_DEBUG("track: eta: " <<  -1 * log(tan( tempTrackProxy.theta() * 0.5)) << " phi: " << tempTrackProxy.phi() << " pt:" << abs(1./tempTrackProxy.qOverP() * sin(protoTrack.parameters->theta())));
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
index 6af1354aa70f..11fa57d2810e 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
@@ -38,6 +38,7 @@
 #include "ActsInterop/TableUtils.h"
 #include "src/detail/AtlasMeasurementSelector.h"
 #include "src/detail/OnTrackCalibrator.h"
+#include "src/detail/TrackFindingMeasurements.h"
 
 // STL
 #include <sstream>
@@ -483,7 +484,6 @@ namespace ActsTrk
     };
 
     std::size_t category_i = 0;
-    const auto measurementContainerOffsets = measurements.measurementContainerOffsets();
 
     using BranchStopperResult = Acts::CombinatorialKalmanFilterBranchStopperResult;
     auto stopBranch = [&](const detail::RecoTrackContainer::TrackProxy &track,
@@ -495,7 +495,7 @@ namespace ActsTrk
       }
 
       if (!m_trackStatePrinter.empty()) {
-        m_trackStatePrinter->printTrackState(tgContext, trackState, measurementContainerOffsets, true);
+        m_trackStatePrinter->printTrackState(tgContext, trackState, measurements, true);
       }
 
       if (!m_doBranchStopper)
@@ -589,7 +589,7 @@ namespace ActsTrk
       {
         ATH_MSG_INFO("CKF results for " << seeds.size() << ' ' << seedType << " seeds:");
       }
-      m_trackStatePrinter->printSeed(tgContext, *seeds[iseed], seedParameters, measurementContainerOffsets, iseed, isKF);
+      m_trackStatePrinter->printSeed(tgContext, *seeds[iseed], seedParameters, measurements, iseed, isKF);
     };
 
     // Loop over the track finding results for all initial parameters
@@ -745,7 +745,7 @@ namespace ActsTrk
         }
 
         if (!m_trackStatePrinter.empty()) {
-          m_trackStatePrinter->printTrack(tgContext, tracksContainerTemp, track, measurementContainerOffsets);
+          m_trackStatePrinter->printTrack(tgContext, tracksContainerTemp, track, measurements);
         }
 
         ++ntracks;
@@ -1016,19 +1016,11 @@ namespace ActsTrk
     // Find shared hits in all the reconstructed tracks and update SharedHitFlag
     // hit index -> list of track indexes [track, state]
 
-    const auto measurementContainerOffsets = measurements.measurementContainerOffsets();
-    const std::size_t nMeasurements = measurements.nMeasurements();
+    const std::size_t measurementIndexSize = measurements.measurementIndexSize();
+    ATH_MSG_DEBUG("measurementIndexSize = " << measurementIndexSize);
 
-    auto containerOffset = [&measurementContainerOffsets](const auto *container) -> std::size_t {
-      for (const auto &[c, offset] : measurementContainerOffsets) {
-        if (c == container)
-          return offset;
-      }
-      return measurementContainerOffsets.size();  // skip this measurement
-    };
-
-    std::vector<std::size_t> firstTrackOnTheHit(nMeasurements, std::numeric_limits<std::size_t>::max());
-    std::vector<std::size_t> firstStateOnTheHit(nMeasurements, std::numeric_limits<std::size_t>::max());
+    std::vector<std::size_t> firstTrackOnTheHit(measurementIndexSize, std::numeric_limits<std::size_t>::max());
+    std::vector<std::size_t> firstStateOnTheHit(measurementIndexSize, std::numeric_limits<std::size_t>::max());
     std::size_t totShared = 0;
 
     for (auto track : tracks) {
@@ -1041,8 +1033,8 @@ namespace ActsTrk
 
         auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
         const xAOD::UncalibratedMeasurement &hit = getUncalibratedMeasurement(sl);
-        std::size_t hitIndex = hit.index() + containerOffset(hit.container());
-        if (!(hitIndex < nMeasurements)) {
+        std::size_t hitIndex = measurements.measurementIndex(hit);
+        if (!(hitIndex < measurementIndexSize)) {
           ATH_MSG_WARNING("computeSharedHits: track measurement with index " << hit.index() << " not found in input");
           continue;
         }
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
index 7bc7ad928cba..1d177fd01323 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
@@ -55,10 +55,12 @@
 #include "ActsEvent/TrackContainerHandlesHelper.h"
 #include "src/detail/Definitions.h"
 #include "src/detail/DuplicateSeedDetector.h"
-#include "src/detail/TrackFindingMeasurements.h"
 
 namespace ActsTrk
 {
+  namespace detail {
+    class TrackFindingMeasurements;
+  }
 
   class TrackFindingAlg : public AthReentrantAlgorithm
   {
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx
index dd099da1aeb3..dd7e516e9aab 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx
@@ -450,7 +450,7 @@ namespace ActsTrk
   TrackStatePrinterTool::printSeed(const Acts::GeometryContext &tgContext,
 				   const ActsTrk::Seed &seed,
 				   const Acts::BoundTrackParameters &initialParameters,
-				   const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &offset,
+				   const detail::TrackFindingMeasurements &measurements,
 				   size_t iseed,
 				   bool isKF) const
   {
@@ -470,7 +470,7 @@ namespace ActsTrk
           os << ',';
         ++nos;
         ++nom;
-        os << el->index() + containerOffset(el->container(), offset);
+        os << measurements.measurementIndex(*el);
       }
     }
 
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
index 4f074883d91b..6040248c6eee 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
@@ -21,13 +21,13 @@
 #include "Acts/EventData/TrackStateType.hpp"
 
 // PACKAGE
+#include "src/detail/TrackFindingMeasurements.h"
 #include "ActsGeometry/ATLASSourceLink.h"
 #include "ActsEvent/Seed.h"
 #include "ActsEvent/TrackContainer.h"
 #include "ActsGeometryInterfaces/ActsGeometryContext.h"
 #include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
 #include "xAODInDetMeasurement/SpacePointContainer.h"
-
 #include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
 
 // Other
@@ -64,7 +64,7 @@ namespace ActsTrk
     printSeed(const Acts::GeometryContext &tgContext,
               const ActsTrk::Seed &seed,
               const Acts::BoundTrackParameters &initialParameters,
-              const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &offset,
+              const detail::TrackFindingMeasurements &measurements,
               size_t iseed,
               bool isKF) const;
 
@@ -73,13 +73,13 @@ namespace ActsTrk
     printTrack(const Acts::GeometryContext &tgContext,
                const track_container_t &tracks,
                const typename track_container_t::TrackProxy &track,
-               const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &offset) const;
+               const detail::TrackFindingMeasurements &measurements) const;
 
     template <typename track_state_proxy_t>
     bool
     printTrackState(const Acts::GeometryContext &tgContext,
                     const track_state_proxy_t &state,
-                    const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offset,
+                    const detail::TrackFindingMeasurements &measurements,
                     bool useFiltered = false,
                     bool newLine = true) const;
 
@@ -125,6 +125,8 @@ namespace ActsTrk
 
 } // namespace
 
+#ifndef ACTSTRACKRECONSTRUCTION_TRACKSTATEPRINTERTOOL_ICC
 #include "src/TrackStatePrinterTool.icc"
+#endif
 
 #endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
index 2d99609e4ec0..e3ecd43b55ea 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
@@ -2,6 +2,11 @@
   Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
+#ifndef ACTSTRACKRECONSTRUCTION_TRACKSTATEPRINTERTOOL_ICC
+#define ACTSTRACKRECONSTRUCTION_TRACKSTATEPRINTERTOOL_ICC
+
+#include "src/TrackStatePrinterTool.h"
+
 // ATHENA
 #include "xAODMeasurementBase/UncalibratedMeasurementContainer.h"
 #include "ActsGeometry/ATLASSourceLink.h"
@@ -26,24 +31,12 @@ namespace ActsTrk
     return os.str();
   }
 
-  template <typename measurement_container_t>
-  static std::size_t
-  containerOffset(const measurement_container_t *container,
-                  const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offsets)
-  {
-    for (const auto &[c, offset] : container_offsets)
-    {
-      if (c == container) return offset;
-    }
-    return 0;
-  }
-
   template <typename track_container_t>
   void
   TrackStatePrinterTool::printTrack(const Acts::GeometryContext &tgContext,
 				    const track_container_t &tracks,
 				    const typename track_container_t::TrackProxy &track,
-				    const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offset) const
+				    const detail::TrackFindingMeasurements &measurements) const
   {
     const auto lastMeasurementIndex = track.tipIndex();
     // to print track states from inside outward, we need to reverse the order of visitBackwards().
@@ -91,7 +84,7 @@ namespace ActsTrk
 
     for (auto i = states.size(); i > 0;)
     {
-      printTrackState(tgContext, states[--i], container_offset);
+      printTrackState(tgContext, states[--i], measurements);
     }
   }
 
@@ -99,7 +92,7 @@ namespace ActsTrk
   bool
   TrackStatePrinterTool::printTrackState(const Acts::GeometryContext &tgContext,
                                          const track_state_proxy_t &state,
-                                         const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offsets,
+                                         const detail::TrackFindingMeasurements &measurements,
                                          bool useFiltered,
                                          bool newLine) const
   {
@@ -112,7 +105,7 @@ namespace ActsTrk
     {
       ATLASUncalibSourceLink sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
       const xAOD::UncalibratedMeasurement &umeas = getUncalibratedMeasurement(sl);
-      index = umeas.index() + containerOffset(umeas.container(), container_offsets);
+      index = measurements.measurementIndex(umeas);
     }
 
     std::cout << std::setw(5) << state.index() << ' ';
@@ -160,3 +153,4 @@ namespace ActsTrk
 
 }  // namespace ActsTrk
 
+#endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
index eece7af053a3..3c76ac7b5c98 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
@@ -3,12 +3,15 @@
 */
 
 #include "src/detail/TrackFindingMeasurements.h"
+#include <algorithm>
 
 namespace ActsTrk::detail {
 
   TrackFindingMeasurements::TrackFindingMeasurements(std::size_t nMeasurementContainerMax)
     : m_measurementOffsets(nMeasurementContainerMax, 0ul)
-  {}
+  {
+    m_measurementContainerOffsets.reserve(nMeasurementContainerMax);
+  }
   
   // NB. all addDetectorElements() must have been done before calling first addMeasurements().
   void TrackFindingMeasurements::addMeasurements(std::size_t typeIndex,
@@ -36,6 +39,15 @@ namespace ActsTrk::detail {
     std::size_t sl_idx = 0;
     for( ; sl_idx < n_elements; ++sl_idx) {
       const auto *measurement  = clusterContainer[sl_idx];
+
+      auto container = measurement->container();  // owning container, which might be different from &clusterContainer
+      if (std::none_of(m_measurementContainerOffsets.begin(),
+                       m_measurementContainerOffsets.end(),
+                       [container](const auto &c) { return c.first == container; })) {
+        m_measurementContainerOffsets.emplace_back(container, m_measurementIndexSize);
+        m_measurementIndexSize += container->size_v();
+      }
+
       if (measurement->identifierHash() != lastIdHash or
 	  measurement->type() != lastMeasurementType)
         {
@@ -77,29 +89,6 @@ namespace ActsTrk::detail {
     
     m_measurementsTotal += clusterContainer.size();
   }
-  
-  std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, std::size_t>>
-  TrackFindingMeasurements::measurementContainerOffsets() const
-  {
-    std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, std::size_t>> offsets;
-    if (m_measurementRanges.numContainers() == 0) return offsets;
-    offsets.reserve(m_measurementRanges.numContainers() - 1); // first one usually 0
-    
-    for (std::size_t typeIndex = 0; typeIndex < m_measurementRanges.numContainers(); ++typeIndex)
-      {
-        const xAOD::UncalibratedMeasurementContainer *theContainer
-	  = std::visit( [] (const auto &a) -> const xAOD::UncalibratedMeasurementContainer *
-	  { return a.containerPtr(); },
-	    m_measurementRanges.container(typeIndex));
-	
-        if (measurementOffset(typeIndex) > 0 and theContainer != nullptr)
-	  {
-	    offsets.emplace_back(theContainer, measurementOffset(typeIndex));
-	  }
-      }
-    
-    return offsets;
-  }
-  
+
 } // namespace ActsTrk::detail
 
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
index 01c23811155b..88d69408c2f9 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
@@ -28,16 +28,17 @@ namespace ActsTrk::detail {
                          const xAOD::UncalibratedMeasurementContainer &clusterContainer,
                          const DetectorElementToActsGeometryIdMap &detectorElementToGeoid);
 
-    std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, std::size_t>> measurementContainerOffsets() const;
+    inline std::size_t measurementIndex(const xAOD::UncalibratedMeasurement &hit) const;
+    inline std::size_t measurementIndexSize() const;
 
-
-    inline std::size_t measurementOffset(std::size_t typeIndex) const;    
     inline const std::vector<std::size_t>& measurementOffsets() const;
     inline const ActsTrk::detail::MeasurementRangeList& measurementRanges() const;
     inline std::size_t nMeasurements() const;
     
   private:
     std::vector<std::size_t> m_measurementOffsets{};
+    std::vector<std::pair<const SG::AuxVectorData *, std::size_t>> m_measurementContainerOffsets{};
+    std::size_t m_measurementIndexSize{0ul};
     // ActsTrk::detail::MeasurementRangeList is an std::unordered_map;
     ActsTrk::detail::MeasurementRangeList m_measurementRanges{};
     std::size_t m_measurementsTotal{0ul};
@@ -45,6 +46,8 @@ namespace ActsTrk::detail {
 
 } // namespace ActsTrk::detail
 
+#ifndef ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_ICC
 #include "src/detail/TrackFindingMeasurements.icc"
+#endif
 
 #endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
index fcc03bd10b94..a39757f91c66 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
@@ -1,11 +1,15 @@
 /*
   Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
+#ifndef ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_ICC
+#define ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_ICC
+
+#include "src/detail/TrackFindingMeasurements.h"
+#include <algorithm>
 
 namespace ActsTrk::detail {
-  
-  inline std::size_t TrackFindingMeasurements::measurementOffset(std::size_t typeIndex) const
-  { return typeIndex < m_measurementOffsets.size() ? m_measurementOffsets[typeIndex] : 0ul; }
+  inline std::size_t TrackFindingMeasurements::nMeasurements() const
+  { return m_measurementsTotal; }
   
   inline const std::vector<std::size_t>& TrackFindingMeasurements::measurementOffsets() const
   { return m_measurementOffsets; }
@@ -13,8 +17,31 @@ namespace ActsTrk::detail {
   inline const ActsTrk::detail::MeasurementRangeList& TrackFindingMeasurements::measurementRanges() const
   { return m_measurementRanges; }
   
-  inline std::size_t TrackFindingMeasurements::nMeasurements() const
-  { return m_measurementsTotal; }
-  
+  inline std::size_t TrackFindingMeasurements::measurementIndex(const xAOD::UncalibratedMeasurement& hit) const {
+    const auto* container = hit.container();
+    auto it =
+        std::find_if(m_measurementContainerOffsets.begin(),
+                     m_measurementContainerOffsets.end(),
+                     [container](const auto& c) {
+                       return c.first == container;
+                     });
+    if (it == m_measurementContainerOffsets.end())
+      return m_measurementIndexSize;
+    std::size_t offset = it->second;
+
+    // check our local index is less than the saved size of the container
+    ++it;
+    std::size_t nextOffset = (it != m_measurementContainerOffsets.end()) ? it->second : m_measurementIndexSize;
+    if (!(hit.index() < (nextOffset - offset)))
+      return m_measurementIndexSize;
+
+    return offset + hit.index();
+  }
+
+  inline std::size_t TrackFindingMeasurements::measurementIndexSize() const
+  { return m_measurementIndexSize; }
+
+
 } // namespace ActsTrk::detail
 
+#endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
index f3008ad60bd0..5dce807eb868 100644
--- a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
@@ -27,13 +27,13 @@ void checkList(const ActsTrk::detail::TrackFindingMeasurements& measurements,
 	       bool isFilled) {
   std::size_t cumulativeOffset = 0ul;
   for (std::size_t i(0); i<N; ++i) {
-    std::cout << "Checking measurementOffset " << i << " : " << measurements.measurementOffset(i) << " with expected " << cumulativeOffset << std::endl;
-    assert( measurements.measurementOffset(i) == cumulativeOffset );
+    std::cout << "Checking measurementOffset " << i << " : " << measurements.measurementOffsets().at(i) << " with expected " << cumulativeOffset << std::endl;
+    assert( measurements.measurementOffsets().at(i) == cumulativeOffset );
     cumulativeOffset += entries.at(i);
   }
   // always 0ul if index too high
-  std::cout << "Checking measurementOffset " << N << " : " << measurements.measurementOffset(N) << " with expected " << 0ul << " (too big)" << std::endl;
-  assert( measurements.measurementOffset(N) == 0ul );
+  std::cout << "Checking measurementOffset " << N << " : " << measurements.measurementOffsets().at(N) << " with expected " << 0ul << " (too big)" << std::endl;
+  assert( measurements.measurementOffsets().at(N) == 0ul );
   
   const std::vector<std::size_t>& offsets = measurements.measurementOffsets();
   std::cout << "Checking offsets size: " << offsets.size() << " with expected " <<	N << std::endl;
@@ -139,20 +139,16 @@ int main() {
   entries = { nPixelClusters, nStripClusters, nHgtdClusters };
   checkList<N>(measurements, entries, true);
 
-  std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, std::size_t>> containerOffsets = measurements.measurementContainerOffsets();
-  std::cout << "Checking measurementContainerOffsets size: " << containerOffsets.size() << " with expected " << N - 1 << std::endl;
-  assert( containerOffsets.size() == N - 1 );
   //  collections
-  auto [container, offset] = containerOffsets.at(0);
-  std::cout << "Checking container : " << container << " with expected " << &stripContainer << std::endl;
-  assert( container == &stripContainer );
-  std::cout << "Checking offset value : " << pixelContainer.size() << " with expected " << offset << std::endl;
-  assert( pixelContainer.size() == offset );
-
-  //
-  auto [container2, offset2] = containerOffsets.at(1);
-  std::cout << "Checking container : " << container2 << " with expected " << &hgtdContainer << std::endl;
-  assert( container2 == &hgtdContainer );
-  std::cout << "Checking offset value : " << pixelContainer.size() + stripContainer.size() << " with expected " << offset2 << std::endl;
-  assert( pixelContainer.size() + stripContainer.size() == offset2 );
+  std::size_t index = measurements.measurementIndex(*pixelContainer[0]);
+  std::cout << "Checking index value : " << index << " with expected " << 0ul << std::endl;
+  assert( index == 0ul );
+
+  std::size_t index2 = measurements.measurementIndex(*stripContainer[0]);
+  std::cout << "Checking index value : " << index2 << " with expected " << pixelContainer.size() << std::endl;
+  assert( index == pixelContainer.size() );
+
+  std::size_t index3 = measurements.measurementIndex(*hgtdContainer[0]);
+  std::cout << "Checking index value : " << index3 << " with expected " << pixelContainer.size() + stripContainer.size() << std::endl;
+  assert( index == pixelContainer.size() + stripContainer.size() );
 }
-- 
GitLab


From 9326304d8087fa68f110dceaedefaec03ab4a59b Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Fri, 24 Jan 2025 18:11:00 +0000
Subject: [PATCH 05/14] separate out measurementIndex etc into new class,
 SharedHitCounter (it doesn't yet count shared hits)

---
 .../src/TrackExtensionAlg.cxx                 | 16 +++--
 .../src/TrackExtensionAlg.h                   |  2 +-
 .../src/TrackFindingAlg.cxx                   | 36 ++++++----
 .../src/TrackFindingAlg.h                     |  4 +-
 .../src/TrackStatePrinterTool.cxx             |  4 +-
 .../src/TrackStatePrinterTool.h               |  8 +--
 .../src/TrackStatePrinterTool.icc             |  8 +--
 .../src/detail/SharedHitCounter.h             | 43 ++++++++++++
 .../src/detail/SharedHitCounter.icc           | 68 +++++++++++++++++++
 .../src/detail/TrackFindingMeasurements.cxx   | 21 ------
 .../src/detail/TrackFindingMeasurements.h     | 17 ++---
 .../src/detail/TrackFindingMeasurements.icc   | 28 --------
 .../test/TrackFindingMeasurementsTest.cxx     | 31 +++++----
 13 files changed, 180 insertions(+), 106 deletions(-)
 create mode 100644 Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
 create mode 100644 Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
index 03246ba42379..f2baf7bac5a4 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
@@ -37,6 +37,8 @@
 #include "ActsInterop/TableUtils.h"
 #include "src/detail/AtlasMeasurementSelector.h"
 #include "src/detail/OnTrackCalibrator.h"
+#include "src/detail/TrackFindingMeasurements.h"
+#include "src/detail/SharedHitCounter.h"
 #include "ActsGeometry/SurfaceOfMeasurementUtil.h"
 
 // STL
@@ -135,7 +137,8 @@ namespace ActsTrk{
        acts_tracking_geometry = m_trackingGeometryTool->trackingGeometry().get();
     ATH_CHECK( acts_tracking_geometry != nullptr);
 
-    detail::TrackFindingMeasurements measurements = collectMeasurements(context, **detectorElementToGeometryIdMap);
+    const auto ms = collectMeasurements(context, **detectorElementToGeometryIdMap);
+    const auto& [measurements, sharedHits] = ms;
 
     ActsTrk::detail::UncalibSourceLinkAccessor slAccessor(measurements.measurementRanges());
     Acts::SourceLinkAccessorDelegate<ActsTrk::detail::UncalibSourceLinkAccessor::Iterator> slAccessorDelegate;
@@ -208,7 +211,7 @@ namespace ActsTrk{
         ATH_MSG_DEBUG("Reco MTJ size " << trackStateBackend.size() );
         for ( size_t stateIndex=0; stateIndex < trackStateBackend.size(); ++stateIndex) {
           auto state = trackStateBackend.getTrackState(stateIndex);
-          if (m_trackStatePrinter.isSet()) m_trackStatePrinter->printTrackState(tgContext, state, measurements, false);
+          if (m_trackStatePrinter.isSet()) m_trackStatePrinter->printTrackState(tgContext, state, sharedHits, false);
         }
         ATH_MSG_DEBUG("Track has: " << tempTrackProxy.nMeasurements() << " measurements ");
         ATH_MSG_DEBUG("track: eta: " <<  -1 * log(tan( tempTrackProxy.theta() * 0.5)) << " phi: " << tempTrackProxy.phi() << " pt:" << abs(1./tempTrackProxy.qOverP() * sin(protoTrack.parameters->theta())));
@@ -229,15 +232,18 @@ namespace ActsTrk{
   }
 
 
-  detail::TrackFindingMeasurements TrackExtensionAlg::collectMeasurements(
+  std::pair<detail::TrackFindingMeasurements, detail::SharedHitCounter> TrackExtensionAlg::collectMeasurements(
        const EventContext& context,
        const ActsTrk::DetectorElementToActsGeometryIdMap &detectorElementToGeometryIdMap) const {
     SG::ReadHandle<xAOD::PixelClusterContainer> pixelClustersHandle(m_pixelClusters, context);
 
-    detail::TrackFindingMeasurements measurements(1u /* only one measurement collection: pixel clusters*/);
+    // setup to return both objects with RVO
+    std::pair<detail::TrackFindingMeasurements, detail::SharedHitCounter> res{{}, {1u /* only one measurement collection: pixel clusters*/}};
+    auto [measurements, sharedHits] = res;
     ATH_MSG_DEBUG("Measurements (pixels only) size: " << pixelClustersHandle->size());
     // potential TODO: filtering only certain layers
     measurements.addMeasurements(0, *pixelClustersHandle, detectorElementToGeometryIdMap);
-    return measurements;
+    sharedHits.addMeasurements(0, *pixelClustersHandle);
+    return res;
   }
 } // EOF namespace
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.h
index 5c308cb60a3c..cdb82284f9c0 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.h
@@ -97,7 +97,7 @@ class TrackExtensionAlg : public AthReentrantAlgorithm {
   std::unique_ptr<detail::CKF_config> m_ckfConfig;
   std::unique_ptr<const Acts::Logger> m_logger;
 
-  detail::TrackFindingMeasurements collectMeasurements(
+  std::pair<detail::TrackFindingMeasurements, detail::SharedHitCounter> collectMeasurements(
       const EventContext& context,
       const ActsTrk::DetectorElementToActsGeometryIdMap&
           detectorElementToGeometryIdMap) const;
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
index 11fa57d2810e..3ba7b878b238 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
@@ -39,6 +39,7 @@
 #include "src/detail/AtlasMeasurementSelector.h"
 #include "src/detail/OnTrackCalibrator.h"
 #include "src/detail/TrackFindingMeasurements.h"
+#include "src/detail/SharedHitCounter.h"
 
 // STL
 #include <sstream>
@@ -307,7 +308,8 @@ namespace ActsTrk
       duplicateSeedDetector.addSeeds(icontainer, *seedContainers[icontainer]);
     }
 
-    detail::TrackFindingMeasurements measurements(uncalibratedMeasurementContainers.size() /* number of measurement containers*/);
+    detail::TrackFindingMeasurements measurements;
+    detail::SharedHitCounter sharedHits(uncalibratedMeasurementContainers.size() /* number of measurement containers*/);
     const Acts::TrackingGeometry *
        acts_tracking_geometry = m_trackingGeometryTool->trackingGeometry().get();
     ATH_CHECK(acts_tracking_geometry != nullptr);
@@ -317,10 +319,12 @@ namespace ActsTrk
       measurements.addMeasurements(icontainer,
                                    *uncalibratedMeasurementContainers[icontainer],
                                    **detectorElementToGeometryIdMap);
+      sharedHits.addMeasurements(icontainer,
+                                 *uncalibratedMeasurementContainers[icontainer]);
     }
 
-    if (!m_trackStatePrinter.empty()) {
-      m_trackStatePrinter->printMeasurements(ctx, uncalibratedMeasurementContainers, **detectorElementToGeometryIdMap, measurements.measurementOffsets());
+    if (m_trackStatePrinter.isSet()) {
+      m_trackStatePrinter->printMeasurements(ctx, uncalibratedMeasurementContainers, **detectorElementToGeometryIdMap, sharedHits.measurementOffsets());
     }
 
     // ================================================== //
@@ -351,6 +355,7 @@ namespace ActsTrk
                            *acts_tracking_geometry,
                            **detectorElementToGeometryIdMap,
                            measurements,
+                           sharedHits,
                            duplicateSeedDetector,
                            *seedContainers.at(icontainer),
                            *detElementsCollections.at(icontainer),
@@ -362,7 +367,7 @@ namespace ActsTrk
 
     ATH_MSG_DEBUG("    \\__ Created " << tracksContainer.size() << " tracks");
 
-    computeSharedHits(tracksContainer, measurements, event_stat);
+    computeSharedHits(tracksContainer, sharedHits, event_stat);
 
     mon_nTracks = tracksContainer.size();
 
@@ -393,6 +398,7 @@ namespace ActsTrk
                               const Acts::TrackingGeometry &trackingGeometry,
                               const ActsTrk::DetectorElementToActsGeometryIdMap &detectorElementToGeoId,
                               const detail::TrackFindingMeasurements &measurements,
+                              const detail::SharedHitCounter &sharedHits,
                               detail::DuplicateSeedDetector &duplicateSeedDetector,
                               const ActsTrk::SeedContainer &seeds,
                               const InDetDD::SiDetectorElementCollection& detElements,
@@ -494,8 +500,8 @@ namespace ActsTrk
         checkPixelStripCounts(track);
       }
 
-      if (!m_trackStatePrinter.empty()) {
-        m_trackStatePrinter->printTrackState(tgContext, trackState, measurements, true);
+      if (m_trackStatePrinter.isSet()) {
+        m_trackStatePrinter->printTrackState(tgContext, trackState, sharedHits, true);
       }
 
       if (!m_doBranchStopper)
@@ -583,13 +589,13 @@ namespace ActsTrk
     std::size_t nPrinted = 0;
     auto printSeed = [&](std::size_t iseed, const Acts::BoundTrackParameters &seedParameters, bool isKF = false)
     {
-      if (m_trackStatePrinter.empty())
+      if (!m_trackStatePrinter.isSet())
         return;
       if (!nPrinted++)
       {
         ATH_MSG_INFO("CKF results for " << seeds.size() << ' ' << seedType << " seeds:");
       }
-      m_trackStatePrinter->printSeed(tgContext, *seeds[iseed], seedParameters, measurements, iseed, isKF);
+      m_trackStatePrinter->printSeed(tgContext, *seeds[iseed], seedParameters, sharedHits, iseed, isKF);
     };
 
     // Loop over the track finding results for all initial parameters
@@ -615,7 +621,7 @@ namespace ActsTrk
         category_i = getSeedCategory(typeIndex, *seeds[iseed]);
         ++event_stat[category_i][kNTotalSeeds];
         ++event_stat[category_i][kNDuplicateSeeds];
-        if (m_trackStatePrinter.empty()) continue;  // delay continue to estimate track parms for TrackStatePrinter?
+        if (!m_trackStatePrinter.isSet()) continue;  // delay continue to estimate track parms for TrackStatePrinter?
       }
 
       plainOptions.direction = reverseSearch ? Acts::Direction::Backward : Acts::Direction::Forward;
@@ -744,8 +750,8 @@ namespace ActsTrk
           checkPixelStripCounts(track);
         }
 
-        if (!m_trackStatePrinter.empty()) {
-          m_trackStatePrinter->printTrack(tgContext, tracksContainerTemp, track, measurements);
+        if (m_trackStatePrinter.isSet()) {
+          m_trackStatePrinter->printTrack(tgContext, tracksContainerTemp, track, sharedHits);
         }
 
         ++ntracks;
@@ -862,7 +868,7 @@ namespace ActsTrk
       } else if (ntracks >= 2) {
         ++event_stat[category_i][kMultipleBranches];
       }
-      if (!m_trackStatePrinter.empty())
+      if (m_trackStatePrinter.isSet())
         std::cout << std::flush;
     }
 
@@ -1011,12 +1017,12 @@ namespace ActsTrk
   }
 
   void TrackFindingAlg::computeSharedHits(ActsTrk::MutableTrackContainer &tracks,
-                                          const detail::TrackFindingMeasurements &measurements,
+                                          const detail::SharedHitCounter &sharedHits,
                                           EventStats &event_stat) const {
     // Find shared hits in all the reconstructed tracks and update SharedHitFlag
     // hit index -> list of track indexes [track, state]
 
-    const std::size_t measurementIndexSize = measurements.measurementIndexSize();
+    const std::size_t measurementIndexSize = sharedHits.measurementIndexSize();
     ATH_MSG_DEBUG("measurementIndexSize = " << measurementIndexSize);
 
     std::vector<std::size_t> firstTrackOnTheHit(measurementIndexSize, std::numeric_limits<std::size_t>::max());
@@ -1033,7 +1039,7 @@ namespace ActsTrk
 
         auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
         const xAOD::UncalibratedMeasurement &hit = getUncalibratedMeasurement(sl);
-        std::size_t hitIndex = measurements.measurementIndex(hit);
+        std::size_t hitIndex = sharedHits.measurementIndex(hit);
         if (!(hitIndex < measurementIndexSize)) {
           ATH_MSG_WARNING("computeSharedHits: track measurement with index " << hit.index() << " not found in input");
           continue;
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
index 1d177fd01323..0c8a13f19509 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
@@ -60,6 +60,7 @@ namespace ActsTrk
 {
   namespace detail {
     class TrackFindingMeasurements;
+    class SharedHitCounter;
   }
 
   class TrackFindingAlg : public AthReentrantAlgorithm
@@ -202,6 +203,7 @@ namespace ActsTrk
                const Acts::TrackingGeometry &trackingGeometry,
                const ActsTrk::DetectorElementToActsGeometryIdMap &detectorElementToGeoId,
                const detail::TrackFindingMeasurements &measurements,
+               const detail::SharedHitCounter &sharedHits,
                detail::DuplicateSeedDetector &duplicateSeedDetector,
                const ActsTrk::SeedContainer &seeds,
                const InDetDD::SiDetectorElementCollection& detElements,
@@ -218,7 +220,7 @@ namespace ActsTrk
 
     // add shared hit flags to output tracks
     void computeSharedHits(ActsTrk::MutableTrackContainer &tracks,
-                           const detail::TrackFindingMeasurements &measurements,
+                           const detail::SharedHitCounter &sharedHits,
                            EventStats &event_stat) const;
 
     // Access Acts::CombinatorialKalmanFilter etc using "pointer to implementation"
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx
index dd7e516e9aab..04410ef19b0b 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx
@@ -450,7 +450,7 @@ namespace ActsTrk
   TrackStatePrinterTool::printSeed(const Acts::GeometryContext &tgContext,
 				   const ActsTrk::Seed &seed,
 				   const Acts::BoundTrackParameters &initialParameters,
-				   const detail::TrackFindingMeasurements &measurements,
+				   const detail::SharedHitCounter &sharedHits,
 				   size_t iseed,
 				   bool isKF) const
   {
@@ -470,7 +470,7 @@ namespace ActsTrk
           os << ',';
         ++nos;
         ++nom;
-        os << measurements.measurementIndex(*el);
+        os << sharedHits.measurementIndex(*el);
       }
     }
 
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
index 6040248c6eee..5b8004997fca 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
@@ -21,7 +21,7 @@
 #include "Acts/EventData/TrackStateType.hpp"
 
 // PACKAGE
-#include "src/detail/TrackFindingMeasurements.h"
+#include "src/detail/SharedHitCounter.h"
 #include "ActsGeometry/ATLASSourceLink.h"
 #include "ActsEvent/Seed.h"
 #include "ActsEvent/TrackContainer.h"
@@ -64,7 +64,7 @@ namespace ActsTrk
     printSeed(const Acts::GeometryContext &tgContext,
               const ActsTrk::Seed &seed,
               const Acts::BoundTrackParameters &initialParameters,
-              const detail::TrackFindingMeasurements &measurements,
+              const detail::SharedHitCounter &sharedHits,
               size_t iseed,
               bool isKF) const;
 
@@ -73,13 +73,13 @@ namespace ActsTrk
     printTrack(const Acts::GeometryContext &tgContext,
                const track_container_t &tracks,
                const typename track_container_t::TrackProxy &track,
-               const detail::TrackFindingMeasurements &measurements) const;
+               const detail::SharedHitCounter &sharedHits) const;
 
     template <typename track_state_proxy_t>
     bool
     printTrackState(const Acts::GeometryContext &tgContext,
                     const track_state_proxy_t &state,
-                    const detail::TrackFindingMeasurements &measurements,
+                    const detail::SharedHitCounter &sharedHits,
                     bool useFiltered = false,
                     bool newLine = true) const;
 
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
index e3ecd43b55ea..600fd10640a7 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
@@ -36,7 +36,7 @@ namespace ActsTrk
   TrackStatePrinterTool::printTrack(const Acts::GeometryContext &tgContext,
 				    const track_container_t &tracks,
 				    const typename track_container_t::TrackProxy &track,
-				    const detail::TrackFindingMeasurements &measurements) const
+				    const detail::SharedHitCounter &sharedHits) const
   {
     const auto lastMeasurementIndex = track.tipIndex();
     // to print track states from inside outward, we need to reverse the order of visitBackwards().
@@ -84,7 +84,7 @@ namespace ActsTrk
 
     for (auto i = states.size(); i > 0;)
     {
-      printTrackState(tgContext, states[--i], measurements);
+      printTrackState(tgContext, states[--i], sharedHits);
     }
   }
 
@@ -92,7 +92,7 @@ namespace ActsTrk
   bool
   TrackStatePrinterTool::printTrackState(const Acts::GeometryContext &tgContext,
                                          const track_state_proxy_t &state,
-                                         const detail::TrackFindingMeasurements &measurements,
+                                         const detail::SharedHitCounter &sharedHits,
                                          bool useFiltered,
                                          bool newLine) const
   {
@@ -105,7 +105,7 @@ namespace ActsTrk
     {
       ATLASUncalibSourceLink sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
       const xAOD::UncalibratedMeasurement &umeas = getUncalibratedMeasurement(sl);
-      index = measurements.measurementIndex(umeas);
+      index = sharedHits.measurementIndex(umeas);
     }
 
     std::cout << std::setw(5) << state.index() << ' ';
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
new file mode 100644
index 000000000000..9ca0d300383f
--- /dev/null
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_H
+#define ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_H
+
+#include "src/detail/AtlasUncalibSourceLinkAccessor.h"
+
+namespace ActsTrk::detail {
+
+  // Helper class to keep track of measurement indices, used for shared hits and debug printing
+  class SharedHitCounter {
+  public:
+    inline SharedHitCounter(std::size_t nMeasurementContainerMax);
+    SharedHitCounter(const SharedHitCounter &) = default;
+    SharedHitCounter& operator=(const SharedHitCounter &) = delete;
+    SharedHitCounter(SharedHitCounter&&) noexcept = delete;
+    SharedHitCounter& operator=(SharedHitCounter&&) noexcept = delete;
+    ~SharedHitCounter() = default;
+    
+    inline void addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer &clusterContainer);
+
+    inline std::size_t measurementIndex(const xAOD::UncalibratedMeasurement &hit) const;
+    inline std::size_t measurementIndexSize() const;
+
+    inline const std::vector<std::size_t>& measurementOffsets() const;
+    inline std::size_t nMeasurements() const;
+    
+  private:
+    std::vector<std::size_t> m_measurementOffsets{};
+    std::vector<std::pair<const SG::AuxVectorData *, std::size_t>> m_measurementContainerOffsets{};
+    std::size_t m_measurementIndexSize{0ul};
+    std::size_t m_measurementsTotal{0ul};
+  };
+
+} // namespace ActsTrk::detail
+
+#ifndef ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
+#include "src/detail/SharedHitCounter.icc"
+#endif
+
+#endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
new file mode 100644
index 000000000000..dfd0f59dee13
--- /dev/null
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
@@ -0,0 +1,68 @@
+/*
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
+*/
+#ifndef ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
+#define ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
+
+#include "src/detail/SharedHitCounter.h"
+#include <algorithm>
+
+namespace ActsTrk::detail {
+
+inline SharedHitCounter::SharedHitCounter(std::size_t nMeasurementContainerMax)
+    : m_measurementOffsets(nMeasurementContainerMax, 0ul) {
+  m_measurementContainerOffsets.reserve(nMeasurementContainerMax);
+}
+
+inline void SharedHitCounter::addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer& clusterContainer) {
+  if (typeIndex < m_measurementOffsets.size())
+    m_measurementOffsets[typeIndex] = m_measurementsTotal;
+
+  for (const auto* measurement : clusterContainer) {
+    auto container = measurement->container();  // owning container, which might be different from clusterContainer
+    if (std::none_of(m_measurementContainerOffsets.begin(),
+                     m_measurementContainerOffsets.end(),
+                     [container](const auto& c) { return c.first == container; })) {
+      m_measurementContainerOffsets.emplace_back(container, m_measurementIndexSize);
+      m_measurementIndexSize += container->size_v();
+    }
+  }
+  m_measurementsTotal += clusterContainer.size();
+}
+
+inline std::size_t SharedHitCounter::measurementIndex(const xAOD::UncalibratedMeasurement& hit) const {
+  const auto* container = hit.container();
+  auto it =
+      std::find_if(m_measurementContainerOffsets.begin(),
+                   m_measurementContainerOffsets.end(),
+                   [container](const auto& c) {
+                     return c.first == container;
+                   });
+  if (it == m_measurementContainerOffsets.end())
+    return m_measurementIndexSize;
+  std::size_t offset = it->second;
+
+  // check our local index is less than the saved size of the container
+  ++it;
+  std::size_t nextOffset = (it != m_measurementContainerOffsets.end()) ? it->second : m_measurementIndexSize;
+  if (!(hit.index() < (nextOffset - offset)))
+    return m_measurementIndexSize;
+
+  return offset + hit.index();
+}
+
+inline std::size_t SharedHitCounter::nMeasurements() const {
+  return m_measurementsTotal;
+}
+
+inline const std::vector<std::size_t>& SharedHitCounter::measurementOffsets() const {
+  return m_measurementOffsets;
+}
+
+inline std::size_t SharedHitCounter::measurementIndexSize() const {
+  return m_measurementIndexSize;
+}
+
+}  // namespace ActsTrk::detail
+
+#endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
index 3c76ac7b5c98..42aa24c6c8ad 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
@@ -7,22 +7,10 @@
 
 namespace ActsTrk::detail {
 
-  TrackFindingMeasurements::TrackFindingMeasurements(std::size_t nMeasurementContainerMax)
-    : m_measurementOffsets(nMeasurementContainerMax, 0ul)
-  {
-    m_measurementContainerOffsets.reserve(nMeasurementContainerMax);
-  }
-  
-  // NB. all addDetectorElements() must have been done before calling first addMeasurements().
   void TrackFindingMeasurements::addMeasurements(std::size_t typeIndex,
 						 const xAOD::UncalibratedMeasurementContainer &clusterContainer,
 						 const DetectorElementToActsGeometryIdMap &detectorElementToGeoid)
   {
-    if (typeIndex >= m_measurementOffsets.size()) {
-      throw std::runtime_error("Adding collection with too big a typeIndex");
-    }    
-    m_measurementOffsets[typeIndex] = m_measurementsTotal;
-    
     if (m_measurementRanges.empty()) {
       // try to reserve needed space,
       // this however will reserve more than necessary not just the space needed for the surfaces of
@@ -40,14 +28,6 @@ namespace ActsTrk::detail {
     for( ; sl_idx < n_elements; ++sl_idx) {
       const auto *measurement  = clusterContainer[sl_idx];
 
-      auto container = measurement->container();  // owning container, which might be different from &clusterContainer
-      if (std::none_of(m_measurementContainerOffsets.begin(),
-                       m_measurementContainerOffsets.end(),
-                       [container](const auto &c) { return c.first == container; })) {
-        m_measurementContainerOffsets.emplace_back(container, m_measurementIndexSize);
-        m_measurementIndexSize += container->size_v();
-      }
-
       if (measurement->identifierHash() != lastIdHash or
 	  measurement->type() != lastMeasurementType)
         {
@@ -91,4 +71,3 @@ namespace ActsTrk::detail {
   }
 
 } // namespace ActsTrk::detail
-
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
index 88d69408c2f9..cc2dc59ee186 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
@@ -7,7 +7,6 @@
 
 #include "ActsGeometry/SurfaceOfMeasurementUtil.h"
 #include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
-
 #include "src/detail/AtlasUncalibSourceLinkAccessor.h"
 
 namespace ActsTrk::detail {
@@ -16,29 +15,21 @@ namespace ActsTrk::detail {
   // Helper class to convert MeasurementContainer specializations to UncalibSourceLinkMultiset.
   class TrackFindingMeasurements {
   public:
-    TrackFindingMeasurements(std::size_t nMeasurementContainerMax);
+    TrackFindingMeasurements() = default;
     TrackFindingMeasurements(const TrackFindingMeasurements &) = default;
-    TrackFindingMeasurements& operator=(const TrackFindingMeasurements &) = default;
-    TrackFindingMeasurements(TrackFindingMeasurements&&) noexcept = default;
-    TrackFindingMeasurements& operator=(TrackFindingMeasurements&&) noexcept = default;
+    TrackFindingMeasurements& operator=(const TrackFindingMeasurements &) = delete;
+    TrackFindingMeasurements(TrackFindingMeasurements&&) noexcept = delete;
+    TrackFindingMeasurements& operator=(TrackFindingMeasurements&&) noexcept = delete;
     ~TrackFindingMeasurements() = default;
     
-    // NB. all addDetectorElements() must have been done before calling first addMeasurements().
     void addMeasurements(std::size_t typeIndex,
                          const xAOD::UncalibratedMeasurementContainer &clusterContainer,
                          const DetectorElementToActsGeometryIdMap &detectorElementToGeoid);
 
-    inline std::size_t measurementIndex(const xAOD::UncalibratedMeasurement &hit) const;
-    inline std::size_t measurementIndexSize() const;
-
-    inline const std::vector<std::size_t>& measurementOffsets() const;
     inline const ActsTrk::detail::MeasurementRangeList& measurementRanges() const;
     inline std::size_t nMeasurements() const;
     
   private:
-    std::vector<std::size_t> m_measurementOffsets{};
-    std::vector<std::pair<const SG::AuxVectorData *, std::size_t>> m_measurementContainerOffsets{};
-    std::size_t m_measurementIndexSize{0ul};
     // ActsTrk::detail::MeasurementRangeList is an std::unordered_map;
     ActsTrk::detail::MeasurementRangeList m_measurementRanges{};
     std::size_t m_measurementsTotal{0ul};
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
index a39757f91c66..c14be5258e68 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
@@ -11,37 +11,9 @@ namespace ActsTrk::detail {
   inline std::size_t TrackFindingMeasurements::nMeasurements() const
   { return m_measurementsTotal; }
   
-  inline const std::vector<std::size_t>& TrackFindingMeasurements::measurementOffsets() const
-  { return m_measurementOffsets; }
-  
   inline const ActsTrk::detail::MeasurementRangeList& TrackFindingMeasurements::measurementRanges() const
   { return m_measurementRanges; }
   
-  inline std::size_t TrackFindingMeasurements::measurementIndex(const xAOD::UncalibratedMeasurement& hit) const {
-    const auto* container = hit.container();
-    auto it =
-        std::find_if(m_measurementContainerOffsets.begin(),
-                     m_measurementContainerOffsets.end(),
-                     [container](const auto& c) {
-                       return c.first == container;
-                     });
-    if (it == m_measurementContainerOffsets.end())
-      return m_measurementIndexSize;
-    std::size_t offset = it->second;
-
-    // check our local index is less than the saved size of the container
-    ++it;
-    std::size_t nextOffset = (it != m_measurementContainerOffsets.end()) ? it->second : m_measurementIndexSize;
-    if (!(hit.index() < (nextOffset - offset)))
-      return m_measurementIndexSize;
-
-    return offset + hit.index();
-  }
-
-  inline std::size_t TrackFindingMeasurements::measurementIndexSize() const
-  { return m_measurementIndexSize; }
-
-
 } // namespace ActsTrk::detail
 
 #endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
index 5dce807eb868..8ec3ec124161 100644
--- a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
@@ -16,6 +16,7 @@
 #include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
 
 #include "src/detail/TrackFindingMeasurements.h"
+#include "src/detail/SharedHitCounter.h"
 
 #include "Acts/Geometry/GeometryIdentifier.hpp"
 
@@ -23,19 +24,20 @@
 
 template <typename std::size_t N>
 void checkList(const ActsTrk::detail::TrackFindingMeasurements& measurements,
+               const ActsTrk::detail::SharedHitCounter& sharedHits,
 	       const std::array<std::size_t, N>& entries,
 	       bool isFilled) {
   std::size_t cumulativeOffset = 0ul;
   for (std::size_t i(0); i<N; ++i) {
-    std::cout << "Checking measurementOffset " << i << " : " << measurements.measurementOffsets().at(i) << " with expected " << cumulativeOffset << std::endl;
-    assert( measurements.measurementOffsets().at(i) == cumulativeOffset );
+    std::cout << "Checking measurementOffset " << i << " : " << sharedHits.measurementOffsets().at(i) << " with expected " << cumulativeOffset << std::endl;
+    assert( sharedHits.measurementOffsets().at(i) == cumulativeOffset );
     cumulativeOffset += entries.at(i);
   }
   // always 0ul if index too high
-  std::cout << "Checking measurementOffset " << N << " : " << measurements.measurementOffsets().at(N) << " with expected " << 0ul << " (too big)" << std::endl;
-  assert( measurements.measurementOffsets().at(N) == 0ul );
+  std::cout << "Checking measurementOffset " << N << " : " << sharedHits.measurementOffsets().at(N) << " with expected " << 0ul << " (too big)" << std::endl;
+  assert( sharedHits.measurementOffsets().at(N) == 0ul );
   
-  const std::vector<std::size_t>& offsets = measurements.measurementOffsets();
+  const std::vector<std::size_t>& offsets = sharedHits.measurementOffsets();
   std::cout << "Checking offsets size: " << offsets.size() << " with expected " <<	N << std::endl;
   assert( offsets.size() == N );
 
@@ -106,12 +108,13 @@ int main() {
   // checks pre-fill
   std::cout << "----------------------------------------------" << std::endl;
   std::cout << "Checking tests pre-fill ..." << std::endl;
-  ActsTrk::detail::TrackFindingMeasurements measurements(N);
+  ActsTrk::detail::TrackFindingMeasurements measurements;
+  ActsTrk::detail::SharedHitCounter sharedHits(N);
   std::cout << "Checking nMeasurements: " << measurements.nMeasurements() << " with the expected " << 0ul << std::endl;
   assert( measurements.nMeasurements() == 0ul );
 
   std::array<std::size_t, N> entries {};
-  checkList<N>(measurements, entries, false);
+  checkList<N>(measurements, sharedHits, entries, false);
 
   // fill
   std::cout << "----------------------------------------------" << std::endl;
@@ -131,24 +134,28 @@ int main() {
   measurements.addMeasurements(0, pixelContainer, geometryIdMap);
   measurements.addMeasurements(1, stripContainer, geometryIdMap);
   measurements.addMeasurements(2, hgtdContainer, geometryIdMap);
-   
+
+  sharedHits.addMeasurements(0, pixelContainer);
+  sharedHits.addMeasurements(1, stripContainer);
+  sharedHits.addMeasurements(2, hgtdContainer);
+
   // check post-fill
   std::cout << "----------------------------------------------" << std::endl;
   std::cout << "Checking tests post-fill ..." << std::endl;
   std::cout << "Checking nMeasurements: " << measurements.nMeasurements() << " with the expected " << nPixelClusters + nStripClusters + nHgtdClusters << std::endl;
   entries = { nPixelClusters, nStripClusters, nHgtdClusters };
-  checkList<N>(measurements, entries, true);
+  checkList<N>(measurements, sharedHits, entries, true);
 
   //  collections
-  std::size_t index = measurements.measurementIndex(*pixelContainer[0]);
+  std::size_t index = sharedHits.measurementIndex(*pixelContainer[0]);
   std::cout << "Checking index value : " << index << " with expected " << 0ul << std::endl;
   assert( index == 0ul );
 
-  std::size_t index2 = measurements.measurementIndex(*stripContainer[0]);
+  std::size_t index2 = sharedHits.measurementIndex(*stripContainer[0]);
   std::cout << "Checking index value : " << index2 << " with expected " << pixelContainer.size() << std::endl;
   assert( index == pixelContainer.size() );
 
-  std::size_t index3 = measurements.measurementIndex(*hgtdContainer[0]);
+  std::size_t index3 = sharedHits.measurementIndex(*hgtdContainer[0]);
   std::cout << "Checking index value : " << index3 << " with expected " << pixelContainer.size() + stripContainer.size() << std::endl;
   assert( index == pixelContainer.size() + stripContainer.size() );
 }
-- 
GitLab


From 0cf81da139288a05a2e8fbcd2a4f1e0914c4e445 Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Fri, 24 Jan 2025 18:23:10 +0000
Subject: [PATCH 06/14] tidy

---
 .../Acts/ActsTrackReconstruction/src/TrackFindingAlg.h     | 3 ++-
 .../src/detail/TrackFindingMeasurements.cxx                | 2 --
 .../src/detail/TrackFindingMeasurements.h                  | 1 +
 .../src/detail/TrackFindingMeasurements.icc                | 7 ++++---
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
index 0c8a13f19509..d24ff9eb7bd6 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
@@ -189,7 +189,8 @@ namespace ActsTrk
      * @param ctx - event context
      * @param trackingGeometry - Acts tracking geometry
      * @param detectorElementToGeoId - map Trk detector element to Acts Geometry id
-     * @param measurements - measurements container
+     * @param measurements - measurements container used in MeasurementSelector
+     * @param sharedHits - measurements container used for shared hit counting
      * @param duplicateSeedDetector - duplicate seed detector
      * @param seeds - spacepoint triplet seeds
      * @param detElements - Trk detector elements
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
index 42aa24c6c8ad..869fdbca5804 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
@@ -3,7 +3,6 @@
 */
 
 #include "src/detail/TrackFindingMeasurements.h"
-#include <algorithm>
 
 namespace ActsTrk::detail {
 
@@ -27,7 +26,6 @@ namespace ActsTrk::detail {
     std::size_t sl_idx = 0;
     for( ; sl_idx < n_elements; ++sl_idx) {
       const auto *measurement  = clusterContainer[sl_idx];
-
       if (measurement->identifierHash() != lastIdHash or
 	  measurement->type() != lastMeasurementType)
         {
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
index cc2dc59ee186..2a0a50a3fd8c 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
@@ -7,6 +7,7 @@
 
 #include "ActsGeometry/SurfaceOfMeasurementUtil.h"
 #include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
+
 #include "src/detail/AtlasUncalibSourceLinkAccessor.h"
 
 namespace ActsTrk::detail {
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
index c14be5258e68..1c3662e06167 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
@@ -8,12 +8,13 @@
 #include <algorithm>
 
 namespace ActsTrk::detail {
-  inline std::size_t TrackFindingMeasurements::nMeasurements() const
-  { return m_measurementsTotal; }
-  
+
   inline const ActsTrk::detail::MeasurementRangeList& TrackFindingMeasurements::measurementRanges() const
   { return m_measurementRanges; }
   
+  inline std::size_t TrackFindingMeasurements::nMeasurements() const
+  { return m_measurementsTotal; }
+
 } // namespace ActsTrk::detail
 
 #endif
-- 
GitLab


From f1428fd254647d2bca05e16a31f65060e5d6985b Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Mon, 27 Jan 2025 13:24:18 +0000
Subject: [PATCH 07/14] move computeSharedHits into SharedHitCounter

---
 .../src/TrackFindingAlg.cxx                   | 63 ++---------------
 .../src/TrackFindingAlg.h                     |  5 --
 .../src/detail/SharedHitCounter.h             |  2 +
 .../src/detail/SharedHitCounter.icc           | 67 ++++++++++++++++---
 4 files changed, 66 insertions(+), 71 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
index 3ba7b878b238..50fddae85a49 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
@@ -367,7 +367,11 @@ namespace ActsTrk
 
     ATH_MSG_DEBUG("    \\__ Created " << tracksContainer.size() << " tracks");
 
-    computeSharedHits(tracksContainer, sharedHits, event_stat);
+    std::size_t totShared = sharedHits.computeSharedHits(tracksContainer);
+    ATH_MSG_DEBUG("found " << totShared << " shared hits among" << tracksContainer.size() << "  tracks");
+    // double eta = -std::log(std::tan(0.5 * track.theta()));
+    // std::size_t category_i = getStatCategory(0, eta);  // not useful (or easy) to separate by seed type, so use first one
+    // event_stat[category_i][kNTotalSharedHits] += totShared;
 
     mon_nTracks = tracksContainer.size();
 
@@ -1016,63 +1020,6 @@ namespace ActsTrk
     return {enoughMeasurements, tooManyHoles, tooManyOutliers};
   }
 
-  void TrackFindingAlg::computeSharedHits(ActsTrk::MutableTrackContainer &tracks,
-                                          const detail::SharedHitCounter &sharedHits,
-                                          EventStats &event_stat) const {
-    // Find shared hits in all the reconstructed tracks and update SharedHitFlag
-    // hit index -> list of track indexes [track, state]
-
-    const std::size_t measurementIndexSize = sharedHits.measurementIndexSize();
-    ATH_MSG_DEBUG("measurementIndexSize = " << measurementIndexSize);
-
-    std::vector<std::size_t> firstTrackOnTheHit(measurementIndexSize, std::numeric_limits<std::size_t>::max());
-    std::vector<std::size_t> firstStateOnTheHit(measurementIndexSize, std::numeric_limits<std::size_t>::max());
-    std::size_t totShared = 0;
-
-    for (auto track : tracks) {
-      for (auto state : track.trackStatesReversed()) {
-        if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag))
-          continue;
-
-        if (!state.hasUncalibratedSourceLink())
-          continue;
-
-        auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
-        const xAOD::UncalibratedMeasurement &hit = getUncalibratedMeasurement(sl);
-        std::size_t hitIndex = sharedHits.measurementIndex(hit);
-        if (!(hitIndex < measurementIndexSize)) {
-          ATH_MSG_WARNING("computeSharedHits: track measurement with index " << hit.index() << " not found in input");
-          continue;
-        }
-
-        // Check if hit not already used
-        if (firstTrackOnTheHit[hitIndex] == std::numeric_limits<std::size_t>::max()) {
-          firstTrackOnTheHit[hitIndex] = track.index();
-          firstStateOnTheHit[hitIndex] = state.index();
-          continue;
-        }
-
-        // if already used, control if first track state has been marked as shared
-        int indexFirstTrack = firstTrackOnTheHit[hitIndex];
-        int indexFirstState = firstStateOnTheHit[hitIndex];
-
-        auto firstState = tracks.getTrack(indexFirstTrack).container().trackStateContainer().getTrackState(indexFirstState);
-        if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
-          firstState.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
-        }
-
-        // Decorate this track state
-        state.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
-
-        double eta = -std::log(std::tan(0.5 * track.theta()));
-        std::size_t category_i = getStatCategory(0, eta);  // not useful (or easy) to separate by seed type, so use first one
-        ++event_stat[category_i][kNTotalSharedHits];
-        ++totShared;
-      }
-    }
-    ATH_MSG_DEBUG("found " << totShared << " shared hits among" << tracks.size() << "  tracks");
-  }
-
   // === Statistics printout =================================================
 
   void TrackFindingAlg::initStatTables()
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
index d24ff9eb7bd6..bafcf6c2d7de 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
@@ -219,11 +219,6 @@ namespace ActsTrk
                        detail::DuplicateSeedDetector &duplicateSeedDetector) const;
 
 
-    // add shared hit flags to output tracks
-    void computeSharedHits(ActsTrk::MutableTrackContainer &tracks,
-                           const detail::SharedHitCounter &sharedHits,
-                           EventStats &event_stat) const;
-
     // Access Acts::CombinatorialKalmanFilter etc using "pointer to implementation"
     // so we don't have to instantiate the heavily templated classes in the header.
     // To maintain const-correctness, only use this via the accessor functions.
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
index 9ca0d300383f..b1517bc0cf3b 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
@@ -6,6 +6,7 @@
 #define ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_H
 
 #include "src/detail/AtlasUncalibSourceLinkAccessor.h"
+#include "ActsEvent/TrackContainer.h"
 
 namespace ActsTrk::detail {
 
@@ -20,6 +21,7 @@ namespace ActsTrk::detail {
     ~SharedHitCounter() = default;
     
     inline void addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer &clusterContainer);
+    inline std::size_t computeSharedHits(ActsTrk::MutableTrackContainer& tracks) const;
 
     inline std::size_t measurementIndex(const xAOD::UncalibratedMeasurement &hit) const;
     inline std::size_t measurementIndexSize() const;
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
index dfd0f59dee13..785ea574e907 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
@@ -14,6 +14,18 @@ inline SharedHitCounter::SharedHitCounter(std::size_t nMeasurementContainerMax)
   m_measurementContainerOffsets.reserve(nMeasurementContainerMax);
 }
 
+inline std::size_t SharedHitCounter::nMeasurements() const {
+  return m_measurementsTotal;
+}
+
+inline const std::vector<std::size_t>& SharedHitCounter::measurementOffsets() const {
+  return m_measurementOffsets;
+}
+
+inline std::size_t SharedHitCounter::measurementIndexSize() const {
+  return m_measurementIndexSize;
+}
+
 inline void SharedHitCounter::addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer& clusterContainer) {
   if (typeIndex < m_measurementOffsets.size())
     m_measurementOffsets[typeIndex] = m_measurementsTotal;
@@ -51,16 +63,55 @@ inline std::size_t SharedHitCounter::measurementIndex(const xAOD::UncalibratedMe
   return offset + hit.index();
 }
 
-inline std::size_t SharedHitCounter::nMeasurements() const {
-  return m_measurementsTotal;
-}
+inline std::size_t SharedHitCounter::computeSharedHits(ActsTrk::MutableTrackContainer& tracks) const {
+  // Find shared hits in all the reconstructed tracks and update SharedHitFlag
+  // hit index -> list of track indexes [track, state]
 
-inline const std::vector<std::size_t>& SharedHitCounter::measurementOffsets() const {
-  return m_measurementOffsets;
-}
+  // ATH_MSG_DEBUG("measurementIndexSize = " << m_measurementIndexSize);
 
-inline std::size_t SharedHitCounter::measurementIndexSize() const {
-  return m_measurementIndexSize;
+  std::vector<std::size_t> firstTrackOnTheHit(m_measurementIndexSize, std::numeric_limits<std::size_t>::max());
+  std::vector<std::size_t> firstStateOnTheHit(m_measurementIndexSize, std::numeric_limits<std::size_t>::max());
+  std::size_t totShared = 0;
+
+  for (auto track : tracks) {
+    for (auto state : track.trackStatesReversed()) {
+      if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag))
+        continue;
+
+      if (!state.hasUncalibratedSourceLink())
+        continue;
+
+      auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
+      const xAOD::UncalibratedMeasurement& hit = getUncalibratedMeasurement(sl);
+      std::size_t hitIndex = measurementIndex(hit);
+      if (!(hitIndex < m_measurementIndexSize)) {
+        // ATH_MSG_WARNING("computeSharedHits: track measurement with index " << hit.index() << " not found in input");
+        continue;
+      }
+
+      // Check if hit not already used
+      if (firstTrackOnTheHit[hitIndex] == std::numeric_limits<std::size_t>::max()) {
+        firstTrackOnTheHit[hitIndex] = track.index();
+        firstStateOnTheHit[hitIndex] = state.index();
+        continue;
+      }
+
+      // if already used, control if first track state has been marked as shared
+      int indexFirstTrack = firstTrackOnTheHit[hitIndex];
+      int indexFirstState = firstStateOnTheHit[hitIndex];
+
+      auto firstState = tracks.getTrack(indexFirstTrack).container().trackStateContainer().getTrackState(indexFirstState);
+      if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
+        firstState.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
+      }
+
+      // Decorate this track state
+      state.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
+
+      ++totShared;
+    }
+  }
+  return totShared;
 }
 
 }  // namespace ActsTrk::detail
-- 
GitLab


From 9ee09ead0746ba8297dc9b619844056c44f95a88 Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Mon, 27 Jan 2025 14:16:21 +0000
Subject: [PATCH 08/14] computeSharedHits called for each new track immediately
 after selection

---
 .../src/TrackFindingAlg.cxx                   | 17 ++--
 .../src/TrackFindingAlg.h                     |  2 +-
 .../src/detail/SharedHitCounter.h             |  9 +-
 .../src/detail/SharedHitCounter.icc           | 83 ++++++++++---------
 4 files changed, 59 insertions(+), 52 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
index 50fddae85a49..27b9119cf1da 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
@@ -367,12 +367,6 @@ namespace ActsTrk
 
     ATH_MSG_DEBUG("    \\__ Created " << tracksContainer.size() << " tracks");
 
-    std::size_t totShared = sharedHits.computeSharedHits(tracksContainer);
-    ATH_MSG_DEBUG("found " << totShared << " shared hits among" << tracksContainer.size() << "  tracks");
-    // double eta = -std::log(std::tan(0.5 * track.theta()));
-    // std::size_t category_i = getStatCategory(0, eta);  // not useful (or easy) to separate by seed type, so use first one
-    // event_stat[category_i][kNTotalSharedHits] += totShared;
-
     mon_nTracks = tracksContainer.size();
 
     copyStats(event_stat);
@@ -402,7 +396,7 @@ namespace ActsTrk
                               const Acts::TrackingGeometry &trackingGeometry,
                               const ActsTrk::DetectorElementToActsGeometryIdMap &detectorElementToGeoId,
                               const detail::TrackFindingMeasurements &measurements,
-                              const detail::SharedHitCounter &sharedHits,
+                              detail::SharedHitCounter &sharedHits,
                               detail::DuplicateSeedDetector &duplicateSeedDetector,
                               const ActsTrk::SeedContainer &seeds,
                               const InDetDD::SiDetectorElementCollection& detElements,
@@ -770,6 +764,15 @@ namespace ActsTrk
         };
         if (trackFinder().trackSelector.isValidTrack(track) &&
             selectPixelStripCountsFinal(track)) {
+
+          auto [nShared, badTrackMeasurement] = sharedHits.computeSharedHits(track, tracksContainer);
+          if (badTrackMeasurement > 0)
+            ATH_MSG_WARNING("computeSharedHits: " << badTrackMeasurement << " track measurements not found in input for " << seedType << " seed " << iseed);
+          ATH_MSG_DEBUG("found " << nShared << " shared hits among"
+                                 << tracksContainer.size()
+                                 << " tracks (measurementIndexSize = " << sharedHits.measurementIndexSize() << ")");
+          event_stat[category_i][kNTotalSharedHits] += nShared;
+
           auto destProxy = tracksContainer.getTrack(tracksContainer.addTrack());
           destProxy.copyFrom(track, true);  // make sure we copy track states!
           ++event_stat[category_i][kNSelectedTracks];
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
index bafcf6c2d7de..3b02392cc794 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
@@ -204,7 +204,7 @@ namespace ActsTrk
                const Acts::TrackingGeometry &trackingGeometry,
                const ActsTrk::DetectorElementToActsGeometryIdMap &detectorElementToGeoId,
                const detail::TrackFindingMeasurements &measurements,
-               const detail::SharedHitCounter &sharedHits,
+               detail::SharedHitCounter &sharedHits,
                detail::DuplicateSeedDetector &duplicateSeedDetector,
                const ActsTrk::SeedContainer &seeds,
                const InDetDD::SiDetectorElementCollection& detElements,
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
index b1517bc0cf3b..b089a0633d27 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
@@ -7,6 +7,7 @@
 
 #include "src/detail/AtlasUncalibSourceLinkAccessor.h"
 #include "ActsEvent/TrackContainer.h"
+#include "src/detail/Definitions.h"
 
 namespace ActsTrk::detail {
 
@@ -21,7 +22,7 @@ namespace ActsTrk::detail {
     ~SharedHitCounter() = default;
     
     inline void addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer &clusterContainer);
-    inline std::size_t computeSharedHits(ActsTrk::MutableTrackContainer& tracks) const;
+    inline std::pair<std::size_t,std::size_t> computeSharedHits(detail::RecoTrackContainerProxy &track, ActsTrk::MutableTrackContainer& tracks);
 
     inline std::size_t measurementIndex(const xAOD::UncalibratedMeasurement &hit) const;
     inline std::size_t measurementIndexSize() const;
@@ -30,10 +31,12 @@ namespace ActsTrk::detail {
     inline std::size_t nMeasurements() const;
     
   private:
-    std::vector<std::size_t> m_measurementOffsets{};
-    std::vector<std::pair<const SG::AuxVectorData *, std::size_t>> m_measurementContainerOffsets{};
+    std::vector<std::size_t> m_measurementOffsets;
+    std::vector<std::pair<const SG::AuxVectorData *, std::size_t>> m_measurementContainerOffsets;
     std::size_t m_measurementIndexSize{0ul};
     std::size_t m_measurementsTotal{0ul};
+    std::vector<std::size_t> firstTrackOnTheHit;
+    std::vector<std::size_t> firstStateOnTheHit;
   };
 
 } // namespace ActsTrk::detail
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
index 785ea574e907..973dce5ae5eb 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
@@ -4,9 +4,10 @@
 #ifndef ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
 #define ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
 
-#include "src/detail/SharedHitCounter.h"
 #include <algorithm>
 
+#include "src/detail/SharedHitCounter.h"
+
 namespace ActsTrk::detail {
 
 inline SharedHitCounter::SharedHitCounter(std::size_t nMeasurementContainerMax)
@@ -63,55 +64,55 @@ inline std::size_t SharedHitCounter::measurementIndex(const xAOD::UncalibratedMe
   return offset + hit.index();
 }
 
-inline std::size_t SharedHitCounter::computeSharedHits(ActsTrk::MutableTrackContainer& tracks) const {
+inline std::pair<std::size_t,std::size_t> SharedHitCounter::computeSharedHits(detail::RecoTrackContainerProxy& track,
+                                                       MutableTrackContainer& tracks) {
   // Find shared hits in all the reconstructed tracks and update SharedHitFlag
   // hit index -> list of track indexes [track, state]
 
-  // ATH_MSG_DEBUG("measurementIndexSize = " << m_measurementIndexSize);
-
-  std::vector<std::size_t> firstTrackOnTheHit(m_measurementIndexSize, std::numeric_limits<std::size_t>::max());
-  std::vector<std::size_t> firstStateOnTheHit(m_measurementIndexSize, std::numeric_limits<std::size_t>::max());
-  std::size_t totShared = 0;
-
-  for (auto track : tracks) {
-    for (auto state : track.trackStatesReversed()) {
-      if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag))
-        continue;
-
-      if (!state.hasUncalibratedSourceLink())
-        continue;
-
-      auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
-      const xAOD::UncalibratedMeasurement& hit = getUncalibratedMeasurement(sl);
-      std::size_t hitIndex = measurementIndex(hit);
-      if (!(hitIndex < m_measurementIndexSize)) {
-        // ATH_MSG_WARNING("computeSharedHits: track measurement with index " << hit.index() << " not found in input");
-        continue;
-      }
-
-      // Check if hit not already used
-      if (firstTrackOnTheHit[hitIndex] == std::numeric_limits<std::size_t>::max()) {
-        firstTrackOnTheHit[hitIndex] = track.index();
-        firstStateOnTheHit[hitIndex] = state.index();
-        continue;
-      }
+  if (m_measurementIndexSize < firstTrackOnTheHit.size()) {
+    firstTrackOnTheHit.resize(m_measurementIndexSize, std::numeric_limits<std::size_t>::max());
+    firstStateOnTheHit.resize(m_measurementIndexSize, std::numeric_limits<std::size_t>::max());
+  }
 
-      // if already used, control if first track state has been marked as shared
-      int indexFirstTrack = firstTrackOnTheHit[hitIndex];
-      int indexFirstState = firstStateOnTheHit[hitIndex];
+  std::size_t nShared = 0;
+  std::size_t badTrackMeasurement = 0;
+  for (auto state : track.trackStatesReversed()) {
+    if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag))
+      continue;
+
+    if (!state.hasUncalibratedSourceLink())
+      continue;
+
+    auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
+    const xAOD::UncalibratedMeasurement& hit = getUncalibratedMeasurement(sl);
+    std::size_t hitIndex = measurementIndex(hit);
+    if (!(hitIndex < m_measurementIndexSize)) {
+      ++badTrackMeasurement;
+      continue;
+    }
 
-      auto firstState = tracks.getTrack(indexFirstTrack).container().trackStateContainer().getTrackState(indexFirstState);
-      if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
-        firstState.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
-      }
+    // Check if hit not already used
+    if (firstTrackOnTheHit[hitIndex] == std::numeric_limits<std::size_t>::max()) {
+      firstTrackOnTheHit[hitIndex] = track.index();
+      firstStateOnTheHit[hitIndex] = state.index();
+      continue;
+    }
 
-      // Decorate this track state
-      state.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
+    // if already used, control if first track state has been marked as shared
+    int indexFirstTrack = firstTrackOnTheHit[hitIndex];
+    int indexFirstState = firstStateOnTheHit[hitIndex];
 
-      ++totShared;
+    auto firstState = tracks.getTrack(indexFirstTrack).container().trackStateContainer().getTrackState(indexFirstState);
+    if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
+      firstState.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
+      ++nShared;
     }
+
+    // Decorate this track state
+    state.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
+    ++nShared;
   }
-  return totShared;
+  return {nShared, badTrackMeasurement};
 }
 
 }  // namespace ActsTrk::detail
-- 
GitLab


From f6b0c9a5eeb481f3e8c4ca9d0fee13a5dec7418a Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Mon, 27 Jan 2025 14:49:52 +0000
Subject: [PATCH 09/14] fix init test. 2 vectors -> vector<TrackStateIndex>

---
 .../src/detail/SharedHitCounter.h             |  9 ++++--
 .../src/detail/SharedHitCounter.icc           | 28 +++++++++----------
 2 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
index b089a0633d27..afa6dbc3f630 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
@@ -22,7 +22,7 @@ namespace ActsTrk::detail {
     ~SharedHitCounter() = default;
     
     inline void addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer &clusterContainer);
-    inline std::pair<std::size_t,std::size_t> computeSharedHits(detail::RecoTrackContainerProxy &track, ActsTrk::MutableTrackContainer& tracks);
+    inline std::pair<std::size_t, std::size_t> computeSharedHits(detail::RecoTrackContainerProxy &track, ActsTrk::MutableTrackContainer &tracks);
 
     inline std::size_t measurementIndex(const xAOD::UncalibratedMeasurement &hit) const;
     inline std::size_t measurementIndexSize() const;
@@ -31,12 +31,15 @@ namespace ActsTrk::detail {
     inline std::size_t nMeasurements() const;
     
   private:
+    struct TrackStateIndex {
+      std::size_t trackIndex;
+      std::size_t stateIndex;
+    };
     std::vector<std::size_t> m_measurementOffsets;
     std::vector<std::pair<const SG::AuxVectorData *, std::size_t>> m_measurementContainerOffsets;
     std::size_t m_measurementIndexSize{0ul};
     std::size_t m_measurementsTotal{0ul};
-    std::vector<std::size_t> firstTrackOnTheHit;
-    std::vector<std::size_t> firstStateOnTheHit;
+    std::vector<TrackStateIndex> firstTrackStateOnTheHit;
   };
 
 } // namespace ActsTrk::detail
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
index 973dce5ae5eb..957d4b3b7fad 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
@@ -4,9 +4,9 @@
 #ifndef ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
 #define ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
 
-#include <algorithm>
-
 #include "src/detail/SharedHitCounter.h"
+#include <algorithm>
+#include <utility>
 
 namespace ActsTrk::detail {
 
@@ -64,15 +64,15 @@ inline std::size_t SharedHitCounter::measurementIndex(const xAOD::UncalibratedMe
   return offset + hit.index();
 }
 
-inline std::pair<std::size_t,std::size_t> SharedHitCounter::computeSharedHits(detail::RecoTrackContainerProxy& track,
-                                                       MutableTrackContainer& tracks) {
-  // Find shared hits in all the reconstructed tracks and update SharedHitFlag
+inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(detail::RecoTrackContainerProxy& track,
+                                                                               MutableTrackContainer& tracks) {
+  // Find shared hits in the reconstructed track and update SharedHitFlag in both tracks
   // hit index -> list of track indexes [track, state]
 
-  if (m_measurementIndexSize < firstTrackOnTheHit.size()) {
-    firstTrackOnTheHit.resize(m_measurementIndexSize, std::numeric_limits<std::size_t>::max());
-    firstStateOnTheHit.resize(m_measurementIndexSize, std::numeric_limits<std::size_t>::max());
-  }
+  constexpr TrackStateIndex noTrackState{std::numeric_limits<std::size_t>::max(), std::numeric_limits<std::size_t>::max()};
+
+  if (firstTrackStateOnTheHit.size() < m_measurementIndexSize)
+    firstTrackStateOnTheHit.resize(m_measurementIndexSize, noTrackState);
 
   std::size_t nShared = 0;
   std::size_t badTrackMeasurement = 0;
@@ -92,17 +92,15 @@ inline std::pair<std::size_t,std::size_t> SharedHitCounter::computeSharedHits(de
     }
 
     // Check if hit not already used
-    if (firstTrackOnTheHit[hitIndex] == std::numeric_limits<std::size_t>::max()) {
-      firstTrackOnTheHit[hitIndex] = track.index();
-      firstStateOnTheHit[hitIndex] = state.index();
+    if (firstTrackStateOnTheHit[hitIndex].trackIndex == noTrackState.trackIndex) {
+      firstTrackStateOnTheHit[hitIndex] = {track.index(), state.index()};
       continue;
     }
 
     // if already used, control if first track state has been marked as shared
-    int indexFirstTrack = firstTrackOnTheHit[hitIndex];
-    int indexFirstState = firstStateOnTheHit[hitIndex];
+    const TrackStateIndex& indexFirstTrackState = firstTrackStateOnTheHit[hitIndex];
 
-    auto firstState = tracks.getTrack(indexFirstTrack).container().trackStateContainer().getTrackState(indexFirstState);
+    auto firstState = tracks.getTrack(indexFirstTrackState.trackIndex).container().trackStateContainer().getTrackState(indexFirstTrackState.stateIndex);
     if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
       firstState.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
       ++nShared;
-- 
GitLab


From 5cbd446a4cda94586c31c54fdd32ba566335149c Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Mon, 27 Jan 2025 17:03:10 +0000
Subject: [PATCH 10/14] tidy up and fix unit test

---
 .../src/TrackExtensionAlg.cxx                 |  4 +--
 .../src/TrackFindingAlg.h                     |  1 -
 .../src/TrackStatePrinterTool.h               |  2 --
 .../src/TrackStatePrinterTool.icc             |  7 -----
 .../src/detail/SharedHitCounter.h             | 26 +++++++++++--------
 .../src/detail/SharedHitCounter.icc           | 10 +++----
 .../src/detail/TrackFindingMeasurements.cxx   |  3 +++
 .../src/detail/TrackFindingMeasurements.h     | 26 +++++++++----------
 .../src/detail/TrackFindingMeasurements.icc   | 19 +++++---------
 .../test/TrackFindingMeasurementsTest.cxx     |  9 +++----
 10 files changed, 45 insertions(+), 62 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
index f2baf7bac5a4..79f6273b2c04 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
@@ -237,9 +237,9 @@ namespace ActsTrk{
        const ActsTrk::DetectorElementToActsGeometryIdMap &detectorElementToGeometryIdMap) const {
     SG::ReadHandle<xAOD::PixelClusterContainer> pixelClustersHandle(m_pixelClusters, context);
 
-    // setup to return both objects with RVO
+    // setup to return both objects with RVO. Note that SharedHitCounter is only used to get hit offsets needed by TrackStatePrinter.
     std::pair<detail::TrackFindingMeasurements, detail::SharedHitCounter> res{{}, {1u /* only one measurement collection: pixel clusters*/}};
-    auto [measurements, sharedHits] = res;
+    auto& [measurements, sharedHits] = res;
     ATH_MSG_DEBUG("Measurements (pixels only) size: " << pixelClustersHandle->size());
     // potential TODO: filtering only certain layers
     measurements.addMeasurements(0, *pixelClustersHandle, detectorElementToGeometryIdMap);
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
index 3b02392cc794..0b8a671d98eb 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
@@ -218,7 +218,6 @@ namespace ActsTrk
                        const detail::RecoTrackContainerProxy &track,
                        detail::DuplicateSeedDetector &duplicateSeedDetector) const;
 
-
     // Access Acts::CombinatorialKalmanFilter etc using "pointer to implementation"
     // so we don't have to instantiate the heavily templated classes in the header.
     // To maintain const-correctness, only use this via the accessor functions.
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
index 5b8004997fca..4e91480fd98b 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
@@ -125,8 +125,6 @@ namespace ActsTrk
 
 } // namespace
 
-#ifndef ACTSTRACKRECONSTRUCTION_TRACKSTATEPRINTERTOOL_ICC
 #include "src/TrackStatePrinterTool.icc"
-#endif
 
 #endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
index 600fd10640a7..848960ca70ce 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
@@ -2,11 +2,6 @@
   Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
-#ifndef ACTSTRACKRECONSTRUCTION_TRACKSTATEPRINTERTOOL_ICC
-#define ACTSTRACKRECONSTRUCTION_TRACKSTATEPRINTERTOOL_ICC
-
-#include "src/TrackStatePrinterTool.h"
-
 // ATHENA
 #include "xAODMeasurementBase/UncalibratedMeasurementContainer.h"
 #include "ActsGeometry/ATLASSourceLink.h"
@@ -152,5 +147,3 @@ namespace ActsTrk
   }
 
 }  // namespace ActsTrk
-
-#endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
index afa6dbc3f630..c05a58b83b81 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
@@ -6,9 +6,15 @@
 #define ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_H
 
 #include "src/detail/AtlasUncalibSourceLinkAccessor.h"
-#include "ActsEvent/TrackContainer.h"
 #include "src/detail/Definitions.h"
 
+#include <utility>
+#include <vector>
+
+namespace ActsTrk {
+ class MutableTrackContainer;
+}
+
 namespace ActsTrk::detail {
 
   // Helper class to keep track of measurement indices, used for shared hits and debug printing
@@ -16,20 +22,20 @@ namespace ActsTrk::detail {
   public:
     inline SharedHitCounter(std::size_t nMeasurementContainerMax);
     SharedHitCounter(const SharedHitCounter &) = default;
-    SharedHitCounter& operator=(const SharedHitCounter &) = delete;
-    SharedHitCounter(SharedHitCounter&&) noexcept = delete;
-    SharedHitCounter& operator=(SharedHitCounter&&) noexcept = delete;
+    SharedHitCounter &operator=(const SharedHitCounter &) = default;
+    SharedHitCounter(SharedHitCounter &&) noexcept = default;
+    SharedHitCounter &operator=(SharedHitCounter &&) noexcept = default;
     ~SharedHitCounter() = default;
-    
+
     inline void addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer &clusterContainer);
-    inline std::pair<std::size_t, std::size_t> computeSharedHits(detail::RecoTrackContainerProxy &track, ActsTrk::MutableTrackContainer &tracks);
+    inline std::pair<std::size_t, std::size_t> computeSharedHits(RecoTrackContainerProxy &track, ActsTrk::MutableTrackContainer &tracks);
 
     inline std::size_t measurementIndex(const xAOD::UncalibratedMeasurement &hit) const;
     inline std::size_t measurementIndexSize() const;
 
-    inline const std::vector<std::size_t>& measurementOffsets() const;
+    inline const std::vector<std::size_t> &measurementOffsets() const;
     inline std::size_t nMeasurements() const;
-    
+
   private:
     struct TrackStateIndex {
       std::size_t trackIndex;
@@ -42,10 +48,8 @@ namespace ActsTrk::detail {
     std::vector<TrackStateIndex> firstTrackStateOnTheHit;
   };
 
-} // namespace ActsTrk::detail
+}  // namespace ActsTrk::detail
 
-#ifndef ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
 #include "src/detail/SharedHitCounter.icc"
-#endif
 
 #endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
index 957d4b3b7fad..04a077f0cbff 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
@@ -1,12 +1,10 @@
 /*
   Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
 */
-#ifndef ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
-#define ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_ICC
 
-#include "src/detail/SharedHitCounter.h"
+#include "ActsEvent/TrackContainer.h"
+
 #include <algorithm>
-#include <utility>
 
 namespace ActsTrk::detail {
 
@@ -64,7 +62,7 @@ inline std::size_t SharedHitCounter::measurementIndex(const xAOD::UncalibratedMe
   return offset + hit.index();
 }
 
-inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(detail::RecoTrackContainerProxy& track,
+inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(RecoTrackContainerProxy& track,
                                                                                MutableTrackContainer& tracks) {
   // Find shared hits in the reconstructed track and update SharedHitFlag in both tracks
   // hit index -> list of track indexes [track, state]
@@ -114,5 +112,3 @@ inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(d
 }
 
 }  // namespace ActsTrk::detail
-
-#endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
index 869fdbca5804..cf5082b1be86 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
@@ -4,6 +4,9 @@
 
 #include "src/detail/TrackFindingMeasurements.h"
 
+#include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
+#include "ActsGeometry/SurfaceOfMeasurementUtil.h"
+
 namespace ActsTrk::detail {
 
   void TrackFindingMeasurements::addMeasurements(std::size_t typeIndex,
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
index 2a0a50a3fd8c..13701fba2872 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
@@ -5,41 +5,39 @@
 #ifndef ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_H
 #define ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_H
 
-#include "ActsGeometry/SurfaceOfMeasurementUtil.h"
-#include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
-
 #include "src/detail/AtlasUncalibSourceLinkAccessor.h"
 
+namespace ActsTrk {
+  class DetectorElementToActsGeometryIdMap;
+}
+
 namespace ActsTrk::detail {
 
-  // === TrackFindingMeasurements ============================================
-  // Helper class to convert MeasurementContainer specializations to UncalibSourceLinkMultiset.
+  // Helper class to convert and store MeasurementContainer specializations to MeasurementRangeList
   class TrackFindingMeasurements {
   public:
     TrackFindingMeasurements() = default;
     TrackFindingMeasurements(const TrackFindingMeasurements &) = default;
-    TrackFindingMeasurements& operator=(const TrackFindingMeasurements &) = delete;
-    TrackFindingMeasurements(TrackFindingMeasurements&&) noexcept = delete;
-    TrackFindingMeasurements& operator=(TrackFindingMeasurements&&) noexcept = delete;
+    TrackFindingMeasurements &operator=(const TrackFindingMeasurements &) = default;
+    TrackFindingMeasurements(TrackFindingMeasurements &&) noexcept = default;
+    TrackFindingMeasurements &operator=(TrackFindingMeasurements &&) noexcept = default;
     ~TrackFindingMeasurements() = default;
-    
+
     void addMeasurements(std::size_t typeIndex,
                          const xAOD::UncalibratedMeasurementContainer &clusterContainer,
                          const DetectorElementToActsGeometryIdMap &detectorElementToGeoid);
 
-    inline const ActsTrk::detail::MeasurementRangeList& measurementRanges() const;
+    inline const ActsTrk::detail::MeasurementRangeList &measurementRanges() const;
     inline std::size_t nMeasurements() const;
-    
+
   private:
     // ActsTrk::detail::MeasurementRangeList is an std::unordered_map;
     ActsTrk::detail::MeasurementRangeList m_measurementRanges{};
     std::size_t m_measurementsTotal{0ul};
   };
 
-} // namespace ActsTrk::detail
+}  // namespace ActsTrk::detail
 
-#ifndef ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_ICC
 #include "src/detail/TrackFindingMeasurements.icc"
-#endif
 
 #endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
index 1c3662e06167..ea60fe67121a 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
@@ -1,20 +1,15 @@
 /*
   Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
-#ifndef ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_ICC
-#define ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_ICC
-
-#include "src/detail/TrackFindingMeasurements.h"
-#include <algorithm>
 
 namespace ActsTrk::detail {
 
-  inline const ActsTrk::detail::MeasurementRangeList& TrackFindingMeasurements::measurementRanges() const
-  { return m_measurementRanges; }
-  
-  inline std::size_t TrackFindingMeasurements::nMeasurements() const
-  { return m_measurementsTotal; }
+  inline const ActsTrk::detail::MeasurementRangeList& TrackFindingMeasurements::measurementRanges() const {
+    return m_measurementRanges;
+  }
 
-} // namespace ActsTrk::detail
+  inline std::size_t TrackFindingMeasurements::nMeasurements() const {
+    return m_measurementsTotal;
+  }
 
-#endif
+}  // namespace ActsTrk::detail
diff --git a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
index 8ec3ec124161..901ce7ba0526 100644
--- a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
@@ -27,17 +27,14 @@ void checkList(const ActsTrk::detail::TrackFindingMeasurements& measurements,
                const ActsTrk::detail::SharedHitCounter& sharedHits,
 	       const std::array<std::size_t, N>& entries,
 	       bool isFilled) {
+  const std::vector<std::size_t>& offsets = sharedHits.measurementOffsets();
   std::size_t cumulativeOffset = 0ul;
   for (std::size_t i(0); i<N; ++i) {
-    std::cout << "Checking measurementOffset " << i << " : " << sharedHits.measurementOffsets().at(i) << " with expected " << cumulativeOffset << std::endl;
-    assert( sharedHits.measurementOffsets().at(i) == cumulativeOffset );
+    std::cout << "Checking measurementOffset " << i << " : " << offsets.at(i) << " with expected " << cumulativeOffset << std::endl;
+    assert( offsets.at(i) == cumulativeOffset );
     cumulativeOffset += entries.at(i);
   }
-  // always 0ul if index too high
-  std::cout << "Checking measurementOffset " << N << " : " << sharedHits.measurementOffsets().at(N) << " with expected " << 0ul << " (too big)" << std::endl;
-  assert( sharedHits.measurementOffsets().at(N) == 0ul );
   
-  const std::vector<std::size_t>& offsets = sharedHits.measurementOffsets();
   std::cout << "Checking offsets size: " << offsets.size() << " with expected " <<	N << std::endl;
   assert( offsets.size() == N );
 
-- 
GitLab


From e67354a7e38c4dbd78759eb6a7bb358f0029ce91 Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Mon, 27 Jan 2025 17:29:21 +0000
Subject: [PATCH 11/14] update refs

---
 Tracking/Acts/ActsConfig/share/ActsCheckObjectCounts.ref  | 8 ++++++++
 .../Acts/ActsConfig/share/ActsCheckObjectCountsCached.ref | 8 ++++++++
 .../Acts/ActsConfig/share/ActsCheckObjectCountsHgtd.ref   | 8 ++++++++
 3 files changed, 24 insertions(+)

diff --git a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCounts.ref b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCounts.ref
index 6b5656695797..ffd407d7abbf 100644
--- a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCounts.ref
+++ b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCounts.ref
@@ -47,6 +47,7 @@ ActsTrackFindingAlg                                               INFO statistic
 | Tracks failing second CKF         |         11 |        186 |        197 |
 | Stopped tracks below pT cut       |       2414 |        494 |       2908 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |      55958 |      12629 |      68587 |
 |-----------------------------------|------------|------------|------------|
 ActsTrackFindingAlg                                               INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -59,6 +60,7 @@ ActsTrackFindingAlg                                               INFO Ratios
 | selected tracks / used seeds             |   0.171359 |  0.0516492 |   0.151384 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  | 0.000742942 |  0.0492976 |  0.0106034 |
+| shared hits / CKF tracks                 |    3.77941 |     3.3472 |    3.69164 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.890205 |    0.11658 |   0.709443 |
 |                                 0.5- 1.0 |   0.913255 |   0.252874 |   0.737646 |
@@ -119,6 +121,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO statistic
 | Tracks failing second CKF         |         30 |         30 |
 | Stopped tracks below pT cut       |       1886 |       1886 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |        582 |        582 |
 |-----------------------------------|------------|------------|
 ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 |------------------------------------------|------------|------------|
@@ -131,6 +134,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 | selected tracks / used seeds             |  0.0129692 |  0.0129692 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |  0.0320513 |  0.0320513 |
+| shared hits / CKF tracks                 |   0.621795 |   0.621795 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.169014 |   0.169014 |
 |                                 0.5- 1.0 |   0.214286 |   0.214286 |
@@ -186,6 +190,7 @@ ActsConversionTrackFindingAlg                                     INFO statistic
 | Tracks failing second CKF         |          0 |          0 |
 | Stopped tracks below pT cut       |          8 |          8 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |          0 |          0 |
 |-----------------------------------|------------|------------|
 ActsConversionTrackFindingAlg                                     INFO Ratios
 |------------------------------------------|------------|------------|
@@ -198,6 +203,7 @@ ActsConversionTrackFindingAlg                                     INFO Ratios
 | selected tracks / used seeds             |          0 |          0 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |          0 |
+| shared hits / CKF tracks                 |          0 |          0 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |          0 |          0 |
 |                                 0.5- 1.0 |          0 |          0 |
@@ -268,6 +274,7 @@ ActsLowPtTrackFindingAlg                                          INFO statistic
 | Tracks failing second CKF         |          0 |         71 |         71 |
 | Stopped tracks below pT cut       |        442 |         42 |        484 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |       2538 |        257 |       2795 |
 |-----------------------------------|------------|------------|------------|
 ActsLowPtTrackFindingAlg                                          INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -280,6 +287,7 @@ ActsLowPtTrackFindingAlg                                          INFO Ratios
 | selected tracks / used seeds             |  0.0134633 | 0.00498076 |   0.012098 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |  0.0413753 |  0.0249123 |
+| shared hits / CKF tracks                 |     2.2381 |   0.149767 |   0.980702 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.833333 |          0 |       0.36 |
 |                                 0.5- 1.0 |   0.965909 |  0.0215827 |   0.387665 |
diff --git a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsCached.ref b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsCached.ref
index 52c475733549..f91569185751 100644
--- a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsCached.ref
+++ b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsCached.ref
@@ -72,6 +72,7 @@ ActsTrackFindingAlg                                               INFO statistic
 | Tracks failing second CKF         |         11 |        186 |        197 |
 | Stopped tracks below pT cut       |       2414 |        494 |       2908 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |      55958 |      12649 |      68607 |
 |-----------------------------------|------------|------------|------------|
 ActsTrackFindingAlg                                               INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -84,6 +85,7 @@ ActsTrackFindingAlg                                               INFO Ratios
 | selected tracks / used seeds             |   0.171359 |  0.0517098 |   0.151393 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  | 0.000742942 |  0.0492846 |  0.0106028 |
+| shared hits / CKF tracks                 |    3.77941 |    3.35162 |    3.69252 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.890205 |    0.11658 |   0.709443 |
 |                                 0.5- 1.0 |   0.913255 |   0.252874 |   0.737646 |
@@ -160,6 +162,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO statistic
 | Tracks failing second CKF         |         30 |         30 |
 | Stopped tracks below pT cut       |       1886 |       1886 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |        582 |        582 |
 |-----------------------------------|------------|------------|
 ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 |------------------------------------------|------------|------------|
@@ -172,6 +175,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 | selected tracks / used seeds             |  0.0129692 |  0.0129692 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |  0.0320513 |  0.0320513 |
+| shared hits / CKF tracks                 |   0.621795 |   0.621795 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.169014 |   0.169014 |
 |                                 0.5- 1.0 |   0.214286 |   0.214286 |
@@ -243,6 +247,7 @@ ActsConversionTrackFindingAlg                                     INFO statistic
 | Tracks failing second CKF         |          0 |          0 |
 | Stopped tracks below pT cut       |          8 |          8 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |          0 |          0 |
 |-----------------------------------|------------|------------|
 ActsConversionTrackFindingAlg                                     INFO Ratios
 |------------------------------------------|------------|------------|
@@ -255,6 +260,7 @@ ActsConversionTrackFindingAlg                                     INFO Ratios
 | selected tracks / used seeds             |          0 |          0 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |          0 |
+| shared hits / CKF tracks                 |          0 |          0 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |          0 |          0 |
 |                                 0.5- 1.0 |          0 |          0 |
@@ -346,6 +352,7 @@ ActsLowPtTrackFindingAlg                                          INFO statistic
 | Tracks failing second CKF         |          0 |         71 |         71 |
 | Stopped tracks below pT cut       |        442 |         42 |        484 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |       2538 |        257 |       2795 |
 |-----------------------------------|------------|------------|------------|
 ActsLowPtTrackFindingAlg                                          INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -358,6 +365,7 @@ ActsLowPtTrackFindingAlg                                          INFO Ratios
 | selected tracks / used seeds             |  0.0134633 | 0.00498076 |   0.012098 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |  0.0413753 |  0.0249123 |
+| shared hits / CKF tracks                 |     2.2381 |   0.149767 |   0.980702 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.833333 |          0 |       0.36 |
 |                                 0.5- 1.0 |   0.965909 |  0.0215827 |   0.387665 |
diff --git a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsHgtd.ref b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsHgtd.ref
index e27d95f67f10..1de5e210ef24 100644
--- a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsHgtd.ref
+++ b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsHgtd.ref
@@ -52,6 +52,7 @@ ActsTrackFindingAlg                                               INFO statistic
 | Tracks failing second CKF         |         11 |        186 |        197 |
 | Stopped tracks below pT cut       |       2414 |        495 |       2909 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |      55972 |      12625 |      68597 |
 |-----------------------------------|------------|------------|------------|
 ActsTrackFindingAlg                                               INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -64,6 +65,7 @@ ActsTrackFindingAlg                                               INFO Ratios
 | selected tracks / used seeds             |   0.171455 |  0.0516492 |   0.151462 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  | 0.00074194 |  0.0491803 |  0.0105868 |
+| shared hits / CKF tracks                 |    3.77526 |    3.33818 |    3.68643 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.890205 |    0.11658 |   0.709443 |
 |                                 0.5- 1.0 |   0.913255 |   0.252874 |   0.737646 |
@@ -129,6 +131,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO statistic
 | Tracks failing second CKF         |         30 |         30 |
 | Stopped tracks below pT cut       |       1885 |       1885 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |        582 |        582 |
 |-----------------------------------|------------|------------|
 ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 |------------------------------------------|------------|------------|
@@ -141,6 +144,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 | selected tracks / used seeds             |  0.0129706 |  0.0129706 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |  0.0317797 |  0.0317797 |
+| shared hits / CKF tracks                 |   0.616525 |   0.616525 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.169014 |   0.169014 |
 |                                 0.5- 1.0 |   0.214286 |   0.214286 |
@@ -201,6 +205,7 @@ ActsConversionTrackFindingAlg                                     INFO statistic
 | Tracks failing second CKF         |          0 |          0 |
 | Stopped tracks below pT cut       |          8 |          8 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |          0 |          0 |
 |-----------------------------------|------------|------------|
 ActsConversionTrackFindingAlg                                     INFO Ratios
 |------------------------------------------|------------|------------|
@@ -213,6 +218,7 @@ ActsConversionTrackFindingAlg                                     INFO Ratios
 | selected tracks / used seeds             |          0 |          0 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |          0 |
+| shared hits / CKF tracks                 |          0 |          0 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |          0 |          0 |
 |                                 0.5- 1.0 |          0 |          0 |
@@ -288,6 +294,7 @@ ActsLowPtTrackFindingAlg                                          INFO statistic
 | Tracks failing second CKF         |          0 |         71 |         71 |
 | Stopped tracks below pT cut       |        441 |         43 |        484 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |       2538 |        257 |       2795 |
 |-----------------------------------|------------|------------|------------|
 ActsLowPtTrackFindingAlg                                          INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -300,6 +307,7 @@ ActsLowPtTrackFindingAlg                                          INFO Ratios
 | selected tracks / used seeds             |  0.0134677 | 0.00498132 |  0.0121016 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |  0.0411833 |  0.0247214 |
+| shared hits / CKF tracks                 |     2.2108 |   0.149072 |   0.973189 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.833333 |          0 |       0.36 |
 |                                 0.5- 1.0 |   0.965909 |  0.0215827 |   0.387665 |
-- 
GitLab


From 32f45b2078ef176b7c3c7af8a85d1f44f768969e Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Mon, 27 Jan 2025 18:20:34 +0000
Subject: [PATCH 12/14] rename variable, and improve comments

---
 .../ActsTrackReconstruction/src/TrackFindingAlg.cxx  |  6 +++---
 .../src/detail/SharedHitCounter.icc                  | 12 +++++++-----
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
index 27b9119cf1da..69890a52f21a 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
@@ -765,9 +765,9 @@ namespace ActsTrk
         if (trackFinder().trackSelector.isValidTrack(track) &&
             selectPixelStripCountsFinal(track)) {
 
-          auto [nShared, badTrackMeasurement] = sharedHits.computeSharedHits(track, tracksContainer);
-          if (badTrackMeasurement > 0)
-            ATH_MSG_WARNING("computeSharedHits: " << badTrackMeasurement << " track measurements not found in input for " << seedType << " seed " << iseed);
+          auto [nShared, nBadTrackMeasurements] = sharedHits.computeSharedHits(track, tracksContainer);
+          if (nBadTrackMeasurements > 0)
+            ATH_MSG_WARNING("computeSharedHits: " << nBadTrackMeasurements << " track measurements not found in input for " << seedType << " seed " << iseed);
           ATH_MSG_DEBUG("found " << nShared << " shared hits among"
                                  << tracksContainer.size()
                                  << " tracks (measurementIndexSize = " << sharedHits.measurementIndexSize() << ")");
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
index 04a077f0cbff..8b4a8bafc2c6 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
@@ -64,8 +64,10 @@ inline std::size_t SharedHitCounter::measurementIndex(const xAOD::UncalibratedMe
 
 inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(RecoTrackContainerProxy& track,
                                                                                MutableTrackContainer& tracks) {
-  // Find shared hits in the reconstructed track and update SharedHitFlag in both tracks
-  // hit index -> list of track indexes [track, state]
+  // Based on ActsExamples::TrackFindingAlgorithm::computeSharedHits().
+  // Finds shared hits in the reconstructed track and updates SharedHitFlag in both tracks.
+  // Uses measurementIndex() to convert hit to hitIndex, and then firstTrackStateOnTheHit[] to convert hitIndex -> TrackStateIndex
+  // Returns stats: nShared and nBadTrackMeasurements
 
   constexpr TrackStateIndex noTrackState{std::numeric_limits<std::size_t>::max(), std::numeric_limits<std::size_t>::max()};
 
@@ -73,7 +75,7 @@ inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(R
     firstTrackStateOnTheHit.resize(m_measurementIndexSize, noTrackState);
 
   std::size_t nShared = 0;
-  std::size_t badTrackMeasurement = 0;
+  std::size_t nBadTrackMeasurements = 0;
   for (auto state : track.trackStatesReversed()) {
     if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag))
       continue;
@@ -85,7 +87,7 @@ inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(R
     const xAOD::UncalibratedMeasurement& hit = getUncalibratedMeasurement(sl);
     std::size_t hitIndex = measurementIndex(hit);
     if (!(hitIndex < m_measurementIndexSize)) {
-      ++badTrackMeasurement;
+      ++nBadTrackMeasurements;
       continue;
     }
 
@@ -108,7 +110,7 @@ inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(R
     state.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
     ++nShared;
   }
-  return {nShared, badTrackMeasurement};
+  return {nShared, nBadTrackMeasurements};
 }
 
 }  // namespace ActsTrk::detail
-- 
GitLab


From aac7f179d5cbfb7c1a25f2937db1394d487b16c2 Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Mon, 27 Jan 2025 22:46:07 +0000
Subject: [PATCH 13/14] fix unit test

---
 .../test/TrackFindingMeasurementsTest.cxx                     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
index 901ce7ba0526..4586cc29cd5b 100644
--- a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
@@ -150,9 +150,9 @@ int main() {
 
   std::size_t index2 = sharedHits.measurementIndex(*stripContainer[0]);
   std::cout << "Checking index value : " << index2 << " with expected " << pixelContainer.size() << std::endl;
-  assert( index == pixelContainer.size() );
+  assert( index2 == pixelContainer.size() );
 
   std::size_t index3 = sharedHits.measurementIndex(*hgtdContainer[0]);
   std::cout << "Checking index value : " << index3 << " with expected " << pixelContainer.size() + stripContainer.size() << std::endl;
-  assert( index == pixelContainer.size() + stripContainer.size() );
+  assert( index3 == pixelContainer.size() + stripContainer.size() );
 }
-- 
GitLab


From e88434b2091a1fceb5669c004b5059986905a971 Mon Sep 17 00:00:00 2001
From: Tim Adye <Tim.Adye@cern.ch>
Date: Mon, 27 Jan 2025 23:04:15 +0000
Subject: [PATCH 14/14] fix ATLAS coding standards warning

---
 .../src/detail/SharedHitCounter.h                    |  2 +-
 .../src/detail/SharedHitCounter.icc                  | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
index c05a58b83b81..9ae813ba6144 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
@@ -45,7 +45,7 @@ namespace ActsTrk::detail {
     std::vector<std::pair<const SG::AuxVectorData *, std::size_t>> m_measurementContainerOffsets;
     std::size_t m_measurementIndexSize{0ul};
     std::size_t m_measurementsTotal{0ul};
-    std::vector<TrackStateIndex> firstTrackStateOnTheHit;
+    std::vector<TrackStateIndex> m_firstTrackStateOnTheHit;
   };
 
 }  // namespace ActsTrk::detail
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
index 8b4a8bafc2c6..65b5dc80d493 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
@@ -66,13 +66,13 @@ inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(R
                                                                                MutableTrackContainer& tracks) {
   // Based on ActsExamples::TrackFindingAlgorithm::computeSharedHits().
   // Finds shared hits in the reconstructed track and updates SharedHitFlag in both tracks.
-  // Uses measurementIndex() to convert hit to hitIndex, and then firstTrackStateOnTheHit[] to convert hitIndex -> TrackStateIndex
+  // Uses measurementIndex() to convert hit to hitIndex, and then m_firstTrackStateOnTheHit[] to convert hitIndex -> TrackStateIndex
   // Returns stats: nShared and nBadTrackMeasurements
 
   constexpr TrackStateIndex noTrackState{std::numeric_limits<std::size_t>::max(), std::numeric_limits<std::size_t>::max()};
 
-  if (firstTrackStateOnTheHit.size() < m_measurementIndexSize)
-    firstTrackStateOnTheHit.resize(m_measurementIndexSize, noTrackState);
+  if (m_firstTrackStateOnTheHit.size() < m_measurementIndexSize)
+    m_firstTrackStateOnTheHit.resize(m_measurementIndexSize, noTrackState);
 
   std::size_t nShared = 0;
   std::size_t nBadTrackMeasurements = 0;
@@ -92,13 +92,13 @@ inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(R
     }
 
     // Check if hit not already used
-    if (firstTrackStateOnTheHit[hitIndex].trackIndex == noTrackState.trackIndex) {
-      firstTrackStateOnTheHit[hitIndex] = {track.index(), state.index()};
+    if (m_firstTrackStateOnTheHit[hitIndex].trackIndex == noTrackState.trackIndex) {
+      m_firstTrackStateOnTheHit[hitIndex] = {track.index(), state.index()};
       continue;
     }
 
     // if already used, control if first track state has been marked as shared
-    const TrackStateIndex& indexFirstTrackState = firstTrackStateOnTheHit[hitIndex];
+    const TrackStateIndex& indexFirstTrackState = m_firstTrackStateOnTheHit[hitIndex];
 
     auto firstState = tracks.getTrack(indexFirstTrackState.trackIndex).container().trackStateContainer().getTrackState(indexFirstTrackState.stateIndex);
     if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
-- 
GitLab