From 16f729487bdc405d5c4de8ce42d13b74b87092e2 Mon Sep 17 00:00:00 2001
From: Goetz Gaycken <goetz.gaycken@cern.ch>
Date: Tue, 14 May 2024 12:45:03 +0200
Subject: [PATCH] Use bare pointer in ATLASUncalibSourceLink rather than
 element links.

Since the sourcelinks are very frequently dereferenced this leads to
a significant improvement in the track finding time.
---
 .../src/CoreStripSpacePointFormationTool.cxx  | 14 +++---
 .../src/ActsToTrkConvertorAlg.cxx             |  2 +-
 .../ActsGeometry/ATLASSourceLink.h            | 45 +++++++++++++++----
 .../ATLASSourceLinkSurfaceAccessor.h          |  7 +--
 .../src/AmbiguityResolutionAlg.cxx            | 11 +++--
 .../src/HitSummaryDataUtils.cxx               |  2 +-
 .../src/KalmanFitter.cxx                      |  6 +--
 .../src/OnTrackCalibrator.icc                 | 10 ++---
 .../src/RandomProtoTrackCreator.cxx           |  9 ++--
 .../src/TrackFindingData.h                    | 14 ++----
 .../src/TrackStatePrinter.icc                 |  5 ++-
 .../src/TruthGuidedProtoTrackCreator.cxx      |  7 ++-
 .../src/TrackToTruthAssociationAlg.cxx        |  2 +-
 13 files changed, 82 insertions(+), 52 deletions(-)

diff --git a/Tracking/Acts/ActsDataPreparation/src/CoreStripSpacePointFormationTool.cxx b/Tracking/Acts/ActsDataPreparation/src/CoreStripSpacePointFormationTool.cxx
index b59a763b644f..bb67047d205a 100644
--- a/Tracking/Acts/ActsDataPreparation/src/CoreStripSpacePointFormationTool.cxx
+++ b/Tracking/Acts/ActsDataPreparation/src/CoreStripSpacePointFormationTool.cxx
@@ -125,7 +125,7 @@ namespace ActsTrk
       size_t idx = 0;
       for (const auto& slink : slinks){
 	const auto& atlasSourceLink = slink.get<ATLASUncalibSourceLink>();
-	const xAOD::UncalibratedMeasurement *hit = *atlasSourceLink;
+	const xAOD::UncalibratedMeasurement *hit = &getUncalibratedMeasurement(atlasSourceLink);
 
 	// Check if the cluster is in the cluster container
 	const auto it = std::find(clusterContainer.begin(), clusterContainer.end(), dynamic_cast<const xAOD::StripCluster*>(hit));
@@ -206,7 +206,7 @@ namespace ActsTrk
             if ((*start)->identifierHash() != thisElement->identifyHash()) {
                throw std::logic_error("Identifier mismatch.");
             }
-	    auto slink = ATLASUncalibSourceLink(clusterContainer, (*start)->index());
+	    auto slink = makeATLASUncalibSourceLink(&clusterContainer, (*start)->index());
 	    neighbourSourceLinks[0].emplace_back(std::make_pair(slink, position));
 	  }
 	}
@@ -252,7 +252,7 @@ namespace ActsTrk
               if ((*start)->identifierHash() != otherElement->identifyHash()) {
                  throw std::logic_error("Identifier mismatch.");
               }
-              auto slink = ATLASUncalibSourceLink(clusterContainer, (*start)->index());
+              auto slink = makeATLASUncalibSourceLink(&clusterContainer, (*start)->index());
 	      neighbourSourceLinks[neigbourIndices[n]].emplace_back(std::make_pair(slink, position));
 	    }
 	  }
@@ -539,8 +539,7 @@ namespace ActsTrk
     ends2_acts.second = ends2.second;
     auto paramCovAccessor = [&](const Acts::SourceLink &slink) {
       const auto &atlasSLink = slink.get<ATLASUncalibSourceLink>();
-      assert( atlasSLink.isValid());
-      const xAOD::UncalibratedMeasurement *measurement = *atlasSLink;
+      const xAOD::UncalibratedMeasurement *measurement = &getUncalibratedMeasurement(atlasSLink);
       Acts::BoundVector loc = Acts::BoundVector::Zero();
       Acts::BoundSquareMatrix cov = Acts::BoundMatrix::Zero();
       switch (measurement->type()) {
@@ -666,9 +665,8 @@ double CoreStripSpacePointFormationTool::computeOffset(const InDetDD::SiDetector
 						 const InDetDD::SiDetectorElement *element,
 						 size_t &stripIndex) const
   {
-    assert( sourceLink.isValid());
-    const xAOD::UncalibratedMeasurement *measurement = *sourceLink;
-    auto cluster = dynamic_cast<const xAOD::StripCluster *>(measurement);
+    const xAOD::UncalibratedMeasurement &measurement = getUncalibratedMeasurement(sourceLink);
+    auto cluster = dynamic_cast<const xAOD::StripCluster *>(&measurement);
     if(!cluster){
       ATH_MSG_FATAL("Could not cast UncalibratedMeasurement as StripCluster");
       return {};
diff --git a/Tracking/Acts/ActsEventCnv/src/ActsToTrkConvertorAlg.cxx b/Tracking/Acts/ActsEventCnv/src/ActsToTrkConvertorAlg.cxx
index c2a9328d434b..a2c5649b3e2e 100644
--- a/Tracking/Acts/ActsEventCnv/src/ActsToTrkConvertorAlg.cxx
+++ b/Tracking/Acts/ActsEventCnv/src/ActsToTrkConvertorAlg.cxx
@@ -166,7 +166,7 @@ namespace ActsTrk
               try {
                 auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
                 assert( sl.isValid() && *sl != nullptr);
-                const xAOD::UncalibratedMeasurement &uncalibMeas = **sl;
+                const xAOD::UncalibratedMeasurement &uncalibMeas = getUncalibratedMeasurement(sl);
                 measState = makeRIO_OnTrack(uncalibMeas, *parm);
                 ATH_MSG_DEBUG("Successfully used ATLASUncalibratedSourceLink");
               } catch ( const std::bad_any_cast& ){
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ATLASSourceLink.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ATLASSourceLink.h
index c5f4b03e08a3..d2c17c3142ca 100644
--- a/Tracking/Acts/ActsGeometry/ActsGeometry/ATLASSourceLink.h
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ATLASSourceLink.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef ACTSGEOMETRY_ATLASOURCELINK_H
@@ -22,19 +22,48 @@
 
 namespace ActsTrk {
    using ATLASSourceLink = const Trk::MeasurementBase *;
-   using ATLASUncalibSourceLink = ElementLink<xAOD::UncalibratedMeasurementContainer>;
+   using ATLASUncalibSourceLink = const xAOD::UncalibratedMeasurement *;
 
+   inline const xAOD::UncalibratedMeasurement &getUncalibratedMeasurement(const ATLASUncalibSourceLink &source_link) {
+      assert(source_link);
+      return *source_link;
+   }
+   inline ATLASUncalibSourceLink makeATLASUncalibSourceLink(const xAOD::UncalibratedMeasurementContainer *container,
+                                                            std::size_t index,
+                                                            [[maybe_unused]] const EventContext& ctx) {
+      assert(container && index < container->size());
+      return container->at(index);
+   }
+   inline ATLASUncalibSourceLink makeATLASUncalibSourceLink([[maybe_unused]] const xAOD::UncalibratedMeasurementContainer *container,
+                                                            const xAOD::UncalibratedMeasurement *measurement,
+                                                            [[maybe_unused]] const EventContext& ctx) {
+      assert( container == measurement->container());
+      assert( container && measurement->index() < container->size() );
+      return measurement;
+   }
+   inline ATLASUncalibSourceLink makeATLASUncalibSourceLink(const xAOD::UncalibratedMeasurementContainer *container,
+                                                            std::size_t index) {
+      assert(container && index < container->size());
+      return container->at(index);
+   }
+   // *dynamic_cast<const xAOD::UncalibratedMeasurementContainer*>(umeas->container()), umeas->index()
+   inline ATLASUncalibSourceLink makeATLASUncalibSourceLink(const xAOD::UncalibratedMeasurement *measurement) {
+      assert(measurement && measurement->container() && measurement->index() < measurement->container()->size_v());
+      return measurement;
+   }
    inline float localXFromSourceLink(const ATLASUncalibSourceLink &source_link) {
-      assert( source_link.isValid());
-      return (*source_link)->type() == xAOD::UncalibMeasType::PixelClusterType
-         ? (*source_link)->localPosition<2>()[Trk::locX]
-         : (*source_link)->localPosition<1>()[Trk::locX];
+      const xAOD::UncalibratedMeasurement &uncalib_meas = getUncalibratedMeasurement(source_link);
+      return uncalib_meas.type() == xAOD::UncalibMeasType::PixelClusterType
+         ? uncalib_meas.localPosition<2>()[Trk::locX]
+         : uncalib_meas.localPosition<1>()[Trk::locX];
    }
 
    inline float localYFromSourceLink(const ATLASUncalibSourceLink &source_link) {
-      assert( source_link.isValid() && (*source_link)->type() == xAOD::UncalibMeasType::PixelClusterType );
-      return (*source_link)->localPosition<2>()[Trk::locY];
+      const xAOD::UncalibratedMeasurement &uncalib_meas = getUncalibratedMeasurement(source_link);
+      assert(uncalib_meas.type() == xAOD::UncalibMeasType::PixelClusterType );
+      return uncalib_meas.localPosition<2>()[Trk::locY];
    }
+
 }
 
 #endif
diff --git a/Tracking/Acts/ActsGeometry/ActsGeometry/ATLASSourceLinkSurfaceAccessor.h b/Tracking/Acts/ActsGeometry/ActsGeometry/ATLASSourceLinkSurfaceAccessor.h
index f9c4bb02bfc0..8cccddde818b 100644
--- a/Tracking/Acts/ActsGeometry/ActsGeometry/ATLASSourceLinkSurfaceAccessor.h
+++ b/Tracking/Acts/ActsGeometry/ActsGeometry/ATLASSourceLinkSurfaceAccessor.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
   */
 #ifndef ATLASSOURCELINKSURFACEACCESSOR_H
 #define ATLASSOURCELINKSURFACEACCESSOR_H
@@ -35,8 +35,9 @@ namespace ActsTrk {
 // surface accessor implementation for ATLASUncalibSourceLink i.e. xAOD::UncalibratedMeasurement
 inline const Acts::Surface* ATLASUncalibSourceLinkSurfaceAccessor::operator()(const Acts::SourceLink& sourceLink) const {
    const auto atlas_uncalib_source_link = sourceLink.get<ATLASUncalibSourceLink>();
-   assert(atlas_uncalib_source_link.isValid() && *atlas_uncalib_source_link );
-   return &this->m_converterTool->trkSurfaceToActsSurface(m_surfaceHelper->associatedSurface( **atlas_uncalib_source_link ) );
+   const xAOD::UncalibratedMeasurement &uncalibMeas = getUncalibratedMeasurement(atlas_uncalib_source_link);
+
+   return &this->m_converterTool->trkSurfaceToActsSurface(m_surfaceHelper->associatedSurface( uncalibMeas ));
 }
 
 // surface accessor implementation for ATLASSourceLink i.e. Trk::MeasurementBase
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/AmbiguityResolutionAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/AmbiguityResolutionAlg.cxx
index c5327e269c44..7c1aa8019fcd 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/AmbiguityResolutionAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/AmbiguityResolutionAlg.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "AmbiguityResolutionAlg.h"
@@ -22,12 +22,15 @@
 namespace {
    std::size_t sourceLinkHash(const Acts::SourceLink& slink) {
       const ActsTrk::ATLASUncalibSourceLink &atlasSourceLink = slink.get<ActsTrk::ATLASUncalibSourceLink>();
-      return (*atlasSourceLink)->identifierHash();
+      const xAOD::UncalibratedMeasurement &uncalibMeas = ActsTrk::getUncalibratedMeasurement(atlasSourceLink);
+      return uncalibMeas.identifierHash();
    }
 
    bool sourceLinkEquality(const Acts::SourceLink& a, const Acts::SourceLink& b) {
-      return    (*a.get<ActsTrk::ATLASUncalibSourceLink>())->identifierHash()
-             == (*b.get<ActsTrk::ATLASUncalibSourceLink>())->identifierHash();
+      const xAOD::UncalibratedMeasurement &uncalibMeas_a = ActsTrk::getUncalibratedMeasurement(a.get<ActsTrk::ATLASUncalibSourceLink>());
+      const xAOD::UncalibratedMeasurement &uncalibMeas_b = ActsTrk::getUncalibratedMeasurement(b.get<ActsTrk::ATLASUncalibSourceLink>());
+
+      return uncalibMeas_a.identifierHash() == uncalibMeas_b.identifierHash();
    }
 }
 
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/HitSummaryDataUtils.cxx b/Tracking/Acts/ActsTrackReconstruction/src/HitSummaryDataUtils.cxx
index 1843453c1f32..2c1ebe4fd3ae 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/HitSummaryDataUtils.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/HitSummaryDataUtils.cxx
@@ -91,7 +91,7 @@ namespace ActsTrk {
              if (state.hasUncalibratedSourceLink()) {
                 auto sl = state.getUncalibratedSourceLink().template get<ActsTrk::ATLASUncalibSourceLink>();
                 assert( sl.isValid() && *sl);
-                const xAOD::UncalibratedMeasurement &uncalibMeas = **sl;
+                const xAOD::UncalibratedMeasurement &uncalibMeas = getUncalibratedMeasurement(sl);
                 if (measurement_to_summary_type.at(to_underlying(uncalibMeas.type())) <  xAOD::numberOfTrackSummaryTypes ) {
                    if (static_cast<unsigned int>(to_underlying(uncalibMeas.type())) < siDetEleColl.size()) {
                       hit_info_out.addHit(siDetEleColl[to_underlying(uncalibMeas.type())],
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/KalmanFitter.cxx b/Tracking/Acts/ActsTrackReconstruction/src/KalmanFitter.cxx
index db0e12f9db38..c2d1e47fbec0 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/KalmanFitter.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/KalmanFitter.cxx
@@ -462,7 +462,7 @@ KalmanFitter::fit(const EventContext& ,
    
   for (const ActsTrk::ATLASUncalibSourceLink& el : clusterList) {
     sourceLinks.emplace_back( el );
-    surfaces.push_back(&tracking_surface_helper.associatedActsSurface(**el));
+    surfaces.push_back(&tracking_surface_helper.associatedActsSurface( getUncalibratedMeasurement(el) ));
   }
  
   Acts::KalmanFitterExtensions<ActsTrk::MutableTrackStateBackend> kfExtensions = m_kfExtensions;
@@ -889,9 +889,9 @@ KalmanFitter::fit(const EventContext& ctx,
   for (const xAOD::SpacePoint* sp : sps) {
     const auto& measurements = sp->measurements();
     for (const xAOD::UncalibratedMeasurement *umeas : measurements) {
-      ActsTrk::ATLASUncalibSourceLink el(*dynamic_cast<const xAOD::UncalibratedMeasurementContainer*>(umeas->container()), umeas->index());
+      ActsTrk::ATLASUncalibSourceLink el(makeATLASUncalibSourceLink(umeas));
       sourceLinks.emplace_back( el );
-      surfaces.push_back(&tracking_surface_helper.associatedActsSurface(**el));
+      surfaces.push_back(&tracking_surface_helper.associatedActsSurface(*umeas));
     }
   }
   return fit(ctx, sourceLinks, initialParams, tgContext, mfContext, calContext, tracking_surface_helper, surfaces.front()); 
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.icc b/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.icc
index 91be5e703b3e..c49d6332b8e1 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/OnTrackCalibrator.icc
@@ -48,16 +48,16 @@ void OnTrackCalibrator<traj_t>::calibrate(
     state.setUncalibratedSourceLink(link);
     ATLASUncalibSourceLink sourceLink = link.template get<ATLASUncalibSourceLink>();
     assert(sourceLink.isValid() && *sourceLink);
-    const xAOD::UncalibratedMeasurement *measurement = *sourceLink;
-    const Acts::Surface &surface = m_surfaceHelper->associatedActsSurface(*measurement);
+    const xAOD::UncalibratedMeasurement &measurement = getUncalibratedMeasurement(sourceLink);
+    const Acts::Surface &surface = m_surfaceHelper->associatedActsSurface(measurement);
 
-    switch (measurement->type()) {
+    switch (measurement.type()) {
     case xAOD::UncalibMeasType::PixelClusterType: {
 	assert(pixel_calibrator.connected());
 	auto [pos, cov] = pixel_calibrator(
 	    geoctx,
 	    cctx,
-	    *dynamic_cast<const xAOD::PixelCluster*>(measurement),
+	    *dynamic_cast<const xAOD::PixelCluster*>(&measurement),
 	    state);
 	setState<2>(
 	    xAOD::UncalibMeasType::PixelClusterType,
@@ -72,7 +72,7 @@ void OnTrackCalibrator<traj_t>::calibrate(
 	auto [pos, cov] = strip_calibrator(
 	    geoctx,
 	    cctx,
-	    *dynamic_cast<const xAOD::StripCluster*>(measurement),
+	    *dynamic_cast<const xAOD::StripCluster*>(&measurement),
 	    state);
 	setState<1>(
 	    xAOD::UncalibMeasType::StripClusterType,
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/RandomProtoTrackCreator.cxx b/Tracking/Acts/ActsTrackReconstruction/src/RandomProtoTrackCreator.cxx
index 900ff71be776..0f1c01a4faf7 100755
--- a/Tracking/Acts/ActsTrackReconstruction/src/RandomProtoTrackCreator.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/RandomProtoTrackCreator.cxx
@@ -1,3 +1,6 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+  */
 #include "RandomProtoTrackCreator.h"
 #include "TrkEventPrimitives/ParticleHypothesis.h"
 #include "Acts/Surfaces/PerigeeSurface.hpp"
@@ -17,13 +20,13 @@ StatusCode ActsTrk::RandomProtoTrackCreator::findProtoTracks(const EventContext&
     size_t nStrip = 7; 
     for (size_t k = 0; k < nPix; ++k){
         auto index = rand() % pixelContainer.size();
-        dummyPoints.push_back(ATLASUncalibSourceLink(pixelContainer.at(index),pixelContainer,ctx)); 
+        dummyPoints.push_back(makeATLASUncalibSourceLink(&pixelContainer, index, ctx));
     }
 
 
     for (size_t k = 0; k < nStrip; ++k){
         auto index = rand() % stripContainer.size();
-        dummyPoints.push_back(ATLASUncalibSourceLink(stripContainer.at(index),stripContainer,ctx)); 
+        dummyPoints.push_back(makeATLASUncalibSourceLink(&stripContainer, index, ctx));
     }
 
     ATH_MSG_DEBUG("Made a proto-track with " <<dummyPoints.size()<<" random clusters");
@@ -50,7 +53,7 @@ Amg::Vector3D ActsTrk::RandomProtoTrackCreator::getMeasurementPos(const xAOD::Un
 
 std::unique_ptr<Acts::BoundTrackParameters> ActsTrk::RandomProtoTrackCreator::makeDummyParams (const ActsTrk::ATLASUncalibSourceLink & firstPRD) const{
 
-  const xAOD::UncalibratedMeasurement* measurement = *firstPRD; 
+  const xAOD::UncalibratedMeasurement* measurement = &getUncalibratedMeasurement(firstPRD);
   using namespace Acts::UnitLiterals;
   std::shared_ptr<const Acts::Surface> actsSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
         Acts::Vector3(0., 0., 0.));
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingData.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingData.h
index 729ba3667c8d..db2efbfe9970 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingData.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingData.h
@@ -139,7 +139,7 @@ namespace
     class BaseIterator
     {
     public:
-      BaseIterator(const EventContext &ctx,
+      BaseIterator([[maybe_unused]] const EventContext &ctx,
                    const xAOD::UncalibratedMeasurementContainer *container,
                    unsigned int element_index,
                    const Acts::GeometryIdentifier &geometry_id)
@@ -148,13 +148,6 @@ namespace
             m_geometryId(geometry_id)
 
       {
-        if (container != nullptr) {
-          m_refElementLink.toIndexedElement (*container, 0, ctx);
-        }
-        if (m_refElementLink.isValid() && !container->empty())
-        {
-          m_refElementLink.getStorableObjectPointer();
-        }
       }
       BaseIterator &operator++()
       {
@@ -166,7 +159,7 @@ namespace
       Acts::SourceLink operator*() const
       {
         assert(m_container && m_index < m_container->size());
-        return Acts::SourceLink(ActsTrk::ATLASUncalibSourceLink(m_refElementLink, m_index));
+        return Acts::SourceLink(ActsTrk::ATLASUncalibSourceLink(m_container->at(m_index)));
       }
       using value_type = unsigned int;
       using difference_type = unsigned int;
@@ -177,7 +170,6 @@ namespace
     private:
       const xAOD::UncalibratedMeasurementContainer *m_container;
       unsigned int m_index;
-      ActsTrk::ATLASUncalibSourceLink m_refElementLink;
       Acts::GeometryIdentifier m_geometryId;
     };
 
@@ -299,7 +291,7 @@ namespace
     {
       if (m_disabled || m_nextSeed == m_nUsedMeasurements.size())
         return;
-      for (auto [iiseed, eiseed] = m_seedIndex.equal_range(&(**sl)); iiseed != eiseed; ++iiseed)
+      for (auto [iiseed, eiseed] = m_seedIndex.equal_range(&(ActsTrk::getUncalibratedMeasurement(sl))); iiseed != eiseed; ++iiseed)
       {
         size_t iseed = iiseed->second;
         assert(iseed < m_nUsedMeasurements.size());
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinter.icc b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinter.icc
index fd10f19ebdbb..c59f3d07e2b7 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinter.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinter.icc
@@ -101,10 +101,11 @@ namespace ActsTrk
     if (state.hasUncalibratedSourceLink())
     {
       ATLASUncalibSourceLink sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
-      index = (*sl)->index();
+      const xAOD::UncalibratedMeasurement &umeas = getUncalibratedMeasurement(sl);
+      index = umeas.index();
       for (const auto &[container, offset] : container_offset)
       {
-        if ((*sl)->container() == container)
+        if (umeas.container() == container)
         {
           index += offset;
           break;
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TruthGuidedProtoTrackCreator.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TruthGuidedProtoTrackCreator.cxx
index c0feec22ff66..aad5e94053c3 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TruthGuidedProtoTrackCreator.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TruthGuidedProtoTrackCreator.cxx
@@ -1,3 +1,6 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+  */
 #include "TruthGuidedProtoTrackCreator.h"
 #include "TrkEventPrimitives/ParticleHypothesis.h"
 #include "Acts/Surfaces/PerigeeSurface.hpp"
@@ -81,7 +84,7 @@ StatusCode ActsTrk::TruthGuidedProtoTrackCreator::findProtoTracks(const EventCon
             if(identToHepMCMap.find(id) != identToHepMCMap.end())
             {
                 auto truthParticle = identToHepMCMap.at(id);
-                trackCollections[truthParticle].emplace_back(ATLASUncalibSourceLink(cluster, pixelContainer, ctx));
+                trackCollections[truthParticle].emplace_back(makeATLASUncalibSourceLink(&pixelContainer, cluster, ctx));
             }
         }
     }
@@ -98,7 +101,7 @@ StatusCode ActsTrk::TruthGuidedProtoTrackCreator::findProtoTracks(const EventCon
             if(identToHepMCMap.find(id) != identToHepMCMap.end())
             {
                 auto truthParticle = identToHepMCMap.at(id);
-                trackCollections[truthParticle].emplace_back(ATLASUncalibSourceLink(cluster, stripContainer, ctx));
+                trackCollections[truthParticle].emplace_back(makeATLASUncalibSourceLink(&stripContainer, cluster, ctx));
             }
         }
     }
diff --git a/Tracking/Acts/ActsTruth/src/TrackToTruthAssociationAlg.cxx b/Tracking/Acts/ActsTruth/src/TrackToTruthAssociationAlg.cxx
index a1719d1c2822..2703e4560454 100644
--- a/Tracking/Acts/ActsTruth/src/TrackToTruthAssociationAlg.cxx
+++ b/Tracking/Acts/ActsTruth/src/TrackToTruthAssociationAlg.cxx
@@ -164,7 +164,7 @@ namespace ActsTrk
             if (!state.typeFlags().test(Acts::TrackStateFlag::OutlierFlag) && state.hasUncalibratedSourceLink()) {
               auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
               assert( sl.isValid() && *sl);
-              const xAOD::UncalibratedMeasurement &uncalibMeas = **sl;
+              const xAOD::UncalibratedMeasurement &uncalibMeas = getUncalibratedMeasurement(sl);
 
 
               const ActsTrk::MeasurementToTruthParticleAssociation *association_map = measurement_to_truth_association_maps.at(to_underlying(uncalibMeas.type()));
-- 
GitLab