From 53637b4d3c51be53087024c839e9ca480fed30be Mon Sep 17 00:00:00 2001
From: Carlo Varni <carlo.varni@cern.ch>
Date: Tue, 18 Mar 2025 16:56:02 +0000
Subject: [PATCH] Reorganize classes inside the ActsObjectDecoration package

from MeasurementToTrackParticleDecoration to MeasurementToTrackParticleDecorationAlg and analysis flag
---
 .../python/ITkActsParticleCreationConfig.py   |  13 ++
 .../python/InDetPrepRawDataToxAODConfig.py    |   6 +-
 .../ActsConfig/python/ActsAnalysisConfig.py   |  21 +-
 .../Acts/ActsConfig/python/ActsConfigFlags.py |   1 +
 .../python/ActsObjectDecorationConfig.py      |  44 ++--
 .../python/ActsTrackFindingConfig.py          |   7 -
 .../Acts/ActsConfig/test/ActsConfiguration.sh |   3 +-
 .../src/ITkAlignMonResidualsAlg.cxx           | 220 ++++++++++--------
 .../src/ITkAlignMonResidualsAlg.h             |  18 +-
 ...asurementToTrackParticleDecorationAlg.cxx} |  50 +++-
 ...MeasurementToTrackParticleDecorationAlg.h} |  66 +++---
 .../src/PixelClusterTruthDecorator.cxx        | 128 ----------
 .../src/PixelClusterTruthDecorator.h          |  62 -----
 .../src/PixelClusterTruthDecoratorAlg.cxx     | 129 ++++++++++
 .../src/PixelClusterTruthDecoratorAlg.h       |  60 +++++
 .../src/StripClusterTruthDecorator.cxx        | 139 -----------
 .../src/StripClusterTruthDecoratorAlg.cxx     | 121 ++++++++++
 ...ator.h => StripClusterTruthDecoratorAlg.h} |  33 ++-
 .../ActsObjectDecoration_entries.cxx          |  12 +-
 19 files changed, 584 insertions(+), 549 deletions(-)
 rename Tracking/Acts/ActsObjectDecoration/src/{MeasurementToTrackParticleDecoration.cxx => MeasurementToTrackParticleDecorationAlg.cxx} (88%)
 rename Tracking/Acts/ActsObjectDecoration/src/{MeasurementToTrackParticleDecoration.h => MeasurementToTrackParticleDecorationAlg.h} (68%)
 delete mode 100644 Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecorator.cxx
 delete mode 100644 Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecorator.h
 create mode 100644 Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecoratorAlg.cxx
 create mode 100644 Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecoratorAlg.h
 delete mode 100644 Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecorator.cxx
 create mode 100644 Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecoratorAlg.cxx
 rename Tracking/Acts/ActsObjectDecoration/src/{StripClusterTruthDecorator.h => StripClusterTruthDecoratorAlg.h} (54%)

diff --git a/InnerDetector/InDetConfig/python/ITkActsParticleCreationConfig.py b/InnerDetector/InDetConfig/python/ITkActsParticleCreationConfig.py
index e3972668245..3d011fa09e8 100644
--- a/InnerDetector/InDetConfig/python/ITkActsParticleCreationConfig.py
+++ b/InnerDetector/InDetConfig/python/ITkActsParticleCreationConfig.py
@@ -53,6 +53,19 @@ def ITkActsTrackParticleCreationCfg(flags,
                                                              OutputLevel = WARNING              if len(TrackContainers)==1 else INFO,
                                                              ComputeTrackRecoEfficiency = False if len(TrackContainers)==1 else True))
 
+    # Additional decorations
+    if flags.Acts.storeTrackStateInfo:
+        from ActsConfig.ActsObjectDecorationConfig import ActsMeasurementToTrackParticleDecorationAlgCfg
+        acc.merge(ActsMeasurementToTrackParticleDecorationAlgCfg(flags,
+                                                                 name = f"ActsMeasurementTo{TrackParticleContainer}DecorationAlg",
+                                                                 TrackParticleKey = TrackParticleContainer))
+        
+        if flags.Acts.Particles.doAnalysis:
+            from ActsConfig.ActsAnalysisConfig import ActsResidualAnalysisAlgCfg
+            acc.merge(ActsResidualAnalysisAlgCfg(flags,
+                                                 name = f"Acts{TrackParticleContainer}ResidualAnalysisAlg",
+                                                 TrackParticles = TrackParticleContainer))
+            
     # Persistification
     # By default this is always happening, but in the case the perigee strategy is set
     # to Vertex we need to create a temporary track particle collection wrt the BeamLine
diff --git a/InnerDetector/InDetConfig/python/InDetPrepRawDataToxAODConfig.py b/InnerDetector/InDetConfig/python/InDetPrepRawDataToxAODConfig.py
index 50ec551bb19..e561b3a1cf2 100644
--- a/InnerDetector/InDetConfig/python/InDetPrepRawDataToxAODConfig.py
+++ b/InnerDetector/InDetConfig/python/InDetPrepRawDataToxAODConfig.py
@@ -51,9 +51,9 @@ def ITkActsPrepDataToxAODCfg(flags) -> ComponentAccumulator:
     if flags.Input.isMC:        
         acc.merge( TruthParticleIndexDecoratorAlgCfg(flags) )
 
-        from ActsConfig.ActsObjectDecorationConfig import ActsPixelClusterTruthDecorator,ActsStripClusterTruthDecorator
-        acc.merge(ActsPixelClusterTruthDecorator(flags))
-        acc.merge(ActsStripClusterTruthDecorator(flags))
+        from ActsConfig.ActsObjectDecorationConfig import ActsPixelClusterTruthDecoratorAlgCfg,ActsStripClusterTruthDecoratorAlgCfg
+        acc.merge(ActsPixelClusterTruthDecoratorAlgCfg(flags))
+        acc.merge(ActsStripClusterTruthDecoratorAlgCfg(flags))
 
     return acc
 
diff --git a/Tracking/Acts/ActsConfig/python/ActsAnalysisConfig.py b/Tracking/Acts/ActsConfig/python/ActsAnalysisConfig.py
index 7e02f7ab09e..8226fb8351f 100644
--- a/Tracking/Acts/ActsConfig/python/ActsAnalysisConfig.py
+++ b/Tracking/Acts/ActsConfig/python/ActsAnalysisConfig.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
 
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
@@ -735,24 +735,25 @@ def ActsResidualAnalysisAlgCfg(flags,
 
     acc = ComponentAccumulator()
     
-    kwargs.setdefault('InDetTrackParticles', 'InDetTrackParticles')
-    kwargs.setdefault("MonGroupName", kwargs['InDetTrackParticles'])
+    kwargs.setdefault('TrackParticles', 'InDetTrackParticles')
+    kwargs.setdefault("MonGroupName", kwargs['TrackParticles'])
 
     from AthenaMonitoring import AthMonitorCfgHelper
-    helper = AthMonitorCfgHelper(flags, kwargs['InDetTrackParticles'] + 'AnalysisAlgCfg')
+    helper = AthMonitorCfgHelper(flags, kwargs['TrackParticles'] + 'AnalysisAlgCfg')
 
     ResidualMonitoringAlgorithm = helper.addAlgorithm(CompFactory.ActsTrk.ITkAlignMonResidualsAlg, name, **kwargs)
     
     layersPix = ['0', '1', '2', '3', '4']
 
-    residualXArray = helper.addArray([len(layersPix)], ResidualMonitoringAlgorithm, 'PixResidualX', topPath = '/ActsAnalysis/Residuals')
-    residualYArray = helper.addArray([len(layersPix)], ResidualMonitoringAlgorithm, 'PixResidualY', topPath = '/ActsAnalysis/Residuals')
-    pullXArray = helper.addArray([len(layersPix)], ResidualMonitoringAlgorithm, 'PixPullX', topPath = '/ActsAnalysis/Residuals')
-    pullYArray = helper.addArray([len(layersPix)], ResidualMonitoringAlgorithm, 'PixPullY', topPath = '/ActsAnalysis/Residuals')
+    path = f'/ActsAnalysis/{kwargs["TrackParticles"]}/Residuals'
+    residualXArray = helper.addArray([len(layersPix)], ResidualMonitoringAlgorithm, 'PixResidualX', topPath = path)
+    residualYArray = helper.addArray([len(layersPix)], ResidualMonitoringAlgorithm, 'PixResidualY', topPath = path)
+    pullXArray = helper.addArray([len(layersPix)], ResidualMonitoringAlgorithm, 'PixPullX', topPath = path)
+    pullYArray = helper.addArray([len(layersPix)], ResidualMonitoringAlgorithm, 'PixPullY', topPath = path)
 
     layersStrip = ['0','1','2','3','4','5','6','7','8']
-    stripResidualXArray  = helper.addArray([len(layersStrip)], ResidualMonitoringAlgorithm, 'StripResidualX', topPath = '/ActsAnalysis/Residuals')
-    stripPullXArray  = helper.addArray([len(layersStrip)], ResidualMonitoringAlgorithm, 'StripPullX', topPath = '/ActsAnalysis/Residuals')
+    stripResidualXArray  = helper.addArray([len(layersStrip)], ResidualMonitoringAlgorithm, 'StripResidualX', topPath = path)
+    stripPullXArray  = helper.addArray([len(layersStrip)], ResidualMonitoringAlgorithm, 'StripPullX', topPath = path)
     
     
     xminX  = -100
diff --git a/Tracking/Acts/ActsConfig/python/ActsConfigFlags.py b/Tracking/Acts/ActsConfig/python/ActsConfigFlags.py
index 1286e4b3561..61a6be894f1 100644
--- a/Tracking/Acts/ActsConfig/python/ActsConfigFlags.py
+++ b/Tracking/Acts/ActsConfig/python/ActsConfigFlags.py
@@ -77,6 +77,7 @@ def createActsConfigFlags():
     actscf.addFlag('Acts.SpacePoints.doAnalysis', lambda pcf: pcf.Acts.doAnalysis)
     actscf.addFlag('Acts.Seeds.doAnalysis', lambda pcf: pcf.Acts.doAnalysis)
     actscf.addFlag('Acts.Tracks.doAnalysis', lambda pcf: pcf.Acts.doAnalysis)
+    actscf.addFlag('Acts.Particles.doAnalysis', lambda pcf: pcf.Acts.doAnalysis)
     actscf.addFlag('Acts.storeTrackStateInfo', False)
 
     # SpacePoint
diff --git a/Tracking/Acts/ActsConfig/python/ActsObjectDecorationConfig.py b/Tracking/Acts/ActsConfig/python/ActsObjectDecorationConfig.py
index efbbbaeaa56..5dd88fe6540 100644
--- a/Tracking/Acts/ActsConfig/python/ActsObjectDecorationConfig.py
+++ b/Tracking/Acts/ActsConfig/python/ActsObjectDecorationConfig.py
@@ -3,9 +3,9 @@
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
 
-def ActsMeasurementToTrackParticleDecorationCfg(flags,
-                                                name: str = "ActsMeasurementToTrackParticleDecoration",
-                                                **kwargs) -> ComponentAccumulator:
+def ActsMeasurementToTrackParticleDecorationAlgCfg(flags,
+                                                   name: str = "ActsMeasurementToTrackParticleDecorationAlg",
+                                                   **kwargs) -> ComponentAccumulator:
     acc = ComponentAccumulator()
     kwargs.setdefault("TrackParticleKey", "InDetTrackParticles")
 
@@ -19,21 +19,19 @@ def ActsMeasurementToTrackParticleDecorationCfg(flags,
             acc.popToolsAndMerge(ActsTrackingGeometryToolCfg(flags)),
         )
     
-
-    acc.addEventAlgo(CompFactory.ActsTrk.MeasurementToTrackParticleDecoration(name, **kwargs))
+    acc.addEventAlgo(CompFactory.ActsTrk.MeasurementToTrackParticleDecorationAlg(name, **kwargs))
     return acc
 
 
-def ActsPixelClusterTruthDecorator(flags,
-                                   name: str = "ActsPixelClusterTruthDecorator",
-                                   **kwargs) -> ComponentAccumulator:
+def ActsPixelClusterTruthDecoratorAlgCfg(flags,
+                                         name: str = "ActsPixelClusterTruthDecoratorAlg",
+                                         **kwargs) -> ComponentAccumulator:
     acc = ComponentAccumulator()
-    kwargs.setdefault("SiClusterContainer","ITkPixelClusters")
+    kwargs.setdefault("ClusterContainer","ITkPixelClusters")
     kwargs.setdefault("AssociationMapOut","ITkPixelClustersToTruthParticles")
-
-    #Using the same name of the xAOD::SiCluster causes bunch of warnings
-    kwargs.setdefault("OutputClusterContainer","ITkPixelMeasurements")
-    acc.addEventAlgo(CompFactory.ActsTrk.PixelClusterTruthDecorator(name,**kwargs))
+    kwargs.setdefault("MeasurementContainer","ITkPixelMeasurements")
+    kwargs.setdefault("UseTruthInfo", flags.Tracking.doTruth)
+    acc.addEventAlgo(CompFactory.ActsTrk.PixelClusterTruthDecoratorAlg(name,**kwargs))
 
     # add SDO and SiHit info
     if flags.Acts.decoratePRD.sdoSiHit:
@@ -42,8 +40,8 @@ def ActsPixelClusterTruthDecorator(flags,
     # Persistification
     if flags.Tracking.writeExtendedSi_PRDInfo:
         toAOD = [
-            f'xAOD::TrackMeasurementValidationContainer#{kwargs["OutputClusterContainer"]}',
-            f'xAOD::TrackMeasurementValidationAuxContainer#{kwargs["OutputClusterContainer"]}Aux.'
+            f'xAOD::TrackMeasurementValidationContainer#{kwargs["MeasurementContainer"]}',
+            f'xAOD::TrackMeasurementValidationAuxContainer#{kwargs["MeasurementContainer"]}Aux.'
         ]        
         from OutputStreamAthenaPool.OutputStreamConfig import addToAOD
         acc.merge(addToAOD(flags, toAOD))
@@ -51,14 +49,14 @@ def ActsPixelClusterTruthDecorator(flags,
     return acc
 
 
-def ActsStripClusterTruthDecorator(flags,
-                                   name: str = "ActsStripClusterTruthDecorator",
-                                   **kwargs) -> ComponentAccumulator:
+def ActsStripClusterTruthDecoratorAlgCfg(flags,
+                                         name: str = "ActsStripClusterTruthDecoratorAlg",
+                                         **kwargs) -> ComponentAccumulator:
     acc = ComponentAccumulator()
-    kwargs.setdefault("SiClusterContainer","ITkStripClusters")
+    kwargs.setdefault("ClusterContainer","ITkStripClusters")
     kwargs.setdefault("AssociationMapOut","ITkStripClustersToTruthParticles")
-    kwargs.setdefault("OutputClusterContainer","ITkStripMeasurements")
-    acc.addEventAlgo(CompFactory.ActsTrk.StripClusterTruthDecorator(name,**kwargs))
+    kwargs.setdefault("MeasurementContainer","ITkStripMeasurements")
+    acc.addEventAlgo(CompFactory.ActsTrk.StripClusterTruthDecoratorAlg(name,**kwargs))
 
     if flags.Acts.decoratePRD.sdoSiHit:
         acc.merge(ActsStripClusterSiHitDecoratorAlgCfg(flags))
@@ -66,8 +64,8 @@ def ActsStripClusterTruthDecorator(flags,
     # Persistification
     if flags.Tracking.writeExtendedSi_PRDInfo:
         toAOD = [
-            f'xAOD::TrackMeasurementValidationContainer#{kwargs["OutputClusterContainer"]}',
-            f'xAOD::TrackMeasurementValidationAuxContainer#{kwargs["OutputClusterContainer"]}Aux.'
+            f'xAOD::TrackMeasurementValidationContainer#{kwargs["MeasurementContainer"]}',
+            f'xAOD::TrackMeasurementValidationAuxContainer#{kwargs["MeasurementContainer"]}Aux.'
         ]        
         from OutputStreamAthenaPool.OutputStreamConfig import addToAOD
         acc.merge(addToAOD(flags, toAOD))
diff --git a/Tracking/Acts/ActsConfig/python/ActsTrackFindingConfig.py b/Tracking/Acts/ActsConfig/python/ActsTrackFindingConfig.py
index 35ccddc2ed0..cf8f1fc86c5 100644
--- a/Tracking/Acts/ActsConfig/python/ActsTrackFindingConfig.py
+++ b/Tracking/Acts/ActsConfig/python/ActsTrackFindingConfig.py
@@ -428,13 +428,6 @@ def ActsTrackToTrackParticleCnvAlgCfg(flags,
     acc.addEventAlgo(
         CompFactory.ActsTrk.TrackToTrackParticleCnvAlg(name, **kwargs))
 
-    if flags.Acts.storeTrackStateInfo:
-        from ActsConfig.ActsObjectDecorationConfig import ActsMeasurementToTrackParticleDecorationCfg
-        acc.merge(ActsMeasurementToTrackParticleDecorationCfg(flags))
-
-        from ActsConfig.ActsAnalysisConfig import ActsResidualAnalysisAlgCfg
-        acc.merge(ActsResidualAnalysisAlgCfg(flags))
-
     return acc
 
 
diff --git a/Tracking/Acts/ActsConfig/test/ActsConfiguration.sh b/Tracking/Acts/ActsConfig/test/ActsConfiguration.sh
index 22c13925787..0e071ee07a7 100755
--- a/Tracking/Acts/ActsConfig/test/ActsConfiguration.sh
+++ b/Tracking/Acts/ActsConfig/test/ActsConfiguration.sh
@@ -68,8 +68,9 @@ activate_all_flags="flags.Acts.doITkConversion=True; \
         	    flags.Acts.EDM.PersistifySpacePoints=True; \
 		    flags.Detector.EnableCalo=True; \
 		    flags.Tracking.writeExtendedSi_PRDInfo=True; \
+		    flags.Acts.storeTrackStateInfo=True; \
 		    flags.Tracking.doTruth=True;"
-
+		   
 activate_all_collections="\"InDet\" \
         \"InDetActs\" \
         \"InDetActsConversion\" \
diff --git a/Tracking/Acts/ActsMonitoring/src/ITkAlignMonResidualsAlg.cxx b/Tracking/Acts/ActsMonitoring/src/ITkAlignMonResidualsAlg.cxx
index 6a04303eb37..c79b4239fe3 100644
--- a/Tracking/Acts/ActsMonitoring/src/ITkAlignMonResidualsAlg.cxx
+++ b/Tracking/Acts/ActsMonitoring/src/ITkAlignMonResidualsAlg.cxx
@@ -9,20 +9,43 @@
 
 namespace ActsTrk {
 
-  ITkAlignMonResidualsAlg::ITkAlignMonResidualsAlg(const std::string& name, ISvcLocator* pSvcLocator)
+  ITkAlignMonResidualsAlg::ITkAlignMonResidualsAlg(const std::string& name,
+						   ISvcLocator* pSvcLocator)
     : AthMonitorAlgorithm(name, pSvcLocator)
   {}
   
   StatusCode ITkAlignMonResidualsAlg::initialize() {
     ATH_MSG_DEBUG("Initializing " << name() << " ...");
-    ATH_MSG_DEBUG("Properties:");
-    ATH_MSG_DEBUG(m_trackParticlesKey);
-    ATH_CHECK(m_trackParticlesKey.initialize());
+    
     ATH_MSG_DEBUG("Monitoring settings ...");
     ATH_MSG_DEBUG(m_monGroupName);
+
+    ATH_CHECK(m_trackParticlesKey.initialize());
+
+    // Decorators
+    m_measurement_det = m_trackParticlesKey.key() + "." + m_measurement_det.key();
+    m_measurement_region = m_trackParticlesKey.key() + "." + m_measurement_region.key();    
+    m_measurement_type = m_trackParticlesKey.key() + "." + m_measurement_type.key();
+    m_measurement_layer = m_trackParticlesKey.key() + "." + m_measurement_layer.key();
+    m_hitResiduals_residualLocX = m_trackParticlesKey.key() + "." + m_hitResiduals_residualLocX.key();
+    m_hitResiduals_pullLocX = m_trackParticlesKey.key() + "." + m_hitResiduals_pullLocX.key();
+    m_hitResiduals_residualLocY = m_trackParticlesKey.key() + "." + m_hitResiduals_residualLocY.key();
+    m_hitResiduals_pullLocY = m_trackParticlesKey.key() + "." + m_hitResiduals_pullLocY.key();
+    m_hitResiduals_phiWidth = m_trackParticlesKey.key() + "." + m_hitResiduals_phiWidth.key();
+    m_hitResiduals_etaWidth = m_trackParticlesKey.key() + "." + m_hitResiduals_etaWidth.key();    
+
+    ATH_CHECK(m_measurement_det.initialize());
+    ATH_CHECK(m_measurement_region.initialize());
+    ATH_CHECK(m_measurement_type.initialize());
+    ATH_CHECK(m_measurement_layer.initialize());
+    ATH_CHECK(m_hitResiduals_residualLocX.initialize());
+    ATH_CHECK(m_hitResiduals_pullLocX.initialize());
+    ATH_CHECK(m_hitResiduals_residualLocY.initialize());
+    ATH_CHECK(m_hitResiduals_pullLocY.initialize());
+    ATH_CHECK(m_hitResiduals_phiWidth.initialize());
+    ATH_CHECK(m_hitResiduals_etaWidth.initialize());
     
-    ATH_CHECK(m_acc_measurement_regionAcc.initialize());
-    
+    // Monitoring tools
     m_pixResidualX = Monitored::buildToolMap<int>(m_tools, "PixResidualX", m_nSiBlayers);
     m_pixResidualY = Monitored::buildToolMap<int>(m_tools, "PixResidualY", m_nSiBlayers);
     m_pixPullX     = Monitored::buildToolMap<int>(m_tools, "PixPullX",     m_nSiBlayers);
@@ -42,109 +65,100 @@ namespace ActsTrk {
     SG::ReadHandle<xAOD::TrackParticleContainer> trackParticlesHandle = SG::makeHandle(m_trackParticlesKey, ctx);
     ATH_CHECK(trackParticlesHandle.isValid());
     const xAOD::TrackParticleContainer *trackparticles = trackParticlesHandle.cptr();
-        
-    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<int>> acc_measurement_regionAcc{m_acc_measurement_regionAcc, ctx};
 
-    for (auto trkprt : *trackparticles) {
-      auto trk = *trkprt;
-      static const SG::ConstAccessor<std::vector<int> >
-	measurement_regionAcc("measurement_region");
-      const static bool hitDetailsAvailable = measurement_regionAcc.isAvailable(trk);
-      
-      if (!hitDetailsAvailable) {
-	ATH_MSG_WARNING("The hit res plots dont see any data");
-	
-	auto measurement_region = acc_measurement_regionAcc(trk);
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<int>> decorator_measurement_det( m_measurement_det, ctx );
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<int>> decorator_measurement_region( m_measurement_region, ctx );
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<int>> decorator_measurement_type( m_measurement_type, ctx );
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<int>> decorator_measurement_iLayer( m_measurement_layer, ctx );
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<float>> decorator_hitResiduals_residualLocX( m_hitResiduals_residualLocX, ctx );
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<float>> decorator_hitResiduals_pullLocX( m_hitResiduals_pullLocX, ctx );
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<float>> decorator_hitResiduals_residualLocY( m_hitResiduals_residualLocY, ctx );
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<float>> decorator_hitResiduals_pullLocY( m_hitResiduals_pullLocY, ctx );
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<int>> decorator_hitResiduals_phiWidth( m_hitResiduals_phiWidth, ctx );
+    SG::ReadDecorHandle<xAOD::TrackParticleContainer, std::vector<int>> decorator_hitResiduals_etaWidth( m_hitResiduals_etaWidth, ctx );
 
+    ATH_CHECK(decorator_measurement_det.initialize());
+    ATH_CHECK(decorator_measurement_region.isValid());
+    ATH_CHECK(decorator_measurement_type.isValid());
+    ATH_CHECK(decorator_measurement_iLayer.isValid());
+    ATH_CHECK(decorator_hitResiduals_residualLocX.isValid());
+    ATH_CHECK(decorator_hitResiduals_pullLocX.isValid());
+    ATH_CHECK(decorator_hitResiduals_residualLocY.isValid());
+    ATH_CHECK(decorator_hitResiduals_pullLocY.isValid());
+    ATH_CHECK(decorator_hitResiduals_phiWidth.isValid());
+    ATH_CHECK(decorator_hitResiduals_etaWidth.isValid());
+    
+    for (const xAOD::TrackParticle* track : *trackparticles) {
+      const std::vector<int>& result_det = decorator_measurement_det(*track);
+      if (result_det.empty()) continue;
+      
+      const std::vector<int>&   result_region = decorator_measurement_region(*track);
+      const std::vector<int>&   result_measureType = decorator_measurement_type(*track);
+      const std::vector<int>&   result_layer  = decorator_measurement_iLayer(*track);
+      const std::vector<float>& result_residualLocX = decorator_hitResiduals_residualLocX(*track);
+      const std::vector<float>& result_pullLocX = decorator_hitResiduals_pullLocX(*track);
+      const std::vector<float>& result_residualLocY = decorator_hitResiduals_residualLocY(*track);
+      const std::vector<float>& result_pullLocY = decorator_hitResiduals_pullLocY(*track);
+      // const std::vector<int>&   result_phiWidth = decorator_hitResiduals_phiWidth(*track);
+      // const std::vector<int>&   result_etaWidth = decorator_hitResiduals_etaWidth(*track);
+      // const float eta = track->eta();
+      
+      // NP: this should be fine... resiudal filled with -1 if not hit
+      if (result_det.size() != result_residualLocX.size()) {
+	ATH_MSG_WARNING("Vectors of results are not matched in size!");
       }
-      else {
+      
+      const auto resultSize = result_region.size();
+      for (unsigned int idx = 0; idx < resultSize; ++idx) {
 	
-	static const SG::ConstAccessor< std::vector<int> > measurement_detAcc("measurement_det");
-	const std::vector<int>& result_det = measurement_detAcc(trk);
-
-	// Read all the other decorators
-	if (!result_det.empty()) {
-	  
-	  static const SG::ConstAccessor< std::vector<int> > measurement_typeAcc("measurement_type");
-	  static const SG::ConstAccessor< std::vector<int> > measurement_regionAcc("measurement_region");
-	  static const SG::ConstAccessor< std::vector<int> > measurement_layerAcc("measurement_iLayer");
-	  static const SG::ConstAccessor< std::vector<float> > hitResiduals_residualLocXAcc("hitResiduals_residualLocX");
-	  static const SG::ConstAccessor< std::vector<float> > hitResiduals_pullLocXAcc("hitResiduals_pullLocX");
-	  static const SG::ConstAccessor< std::vector<float> > hitResiduals_residualLocYAcc("hitResiduals_residualLocY");
-	  static const SG::ConstAccessor< std::vector<float> > hitResiduals_pullLocYAcc("hitResiduals_pullLocY");
-	  static const SG::ConstAccessor< std::vector<int> > hitResiduals_phiWidthAcc("hitResiduals_phiWidth");
-	  static const SG::ConstAccessor< std::vector<int> > hitResiduals_etaWidthAcc("hitResiduals_etaWidth");
+	const int measureType = result_measureType.at(idx);
+	const int det = result_det.at(idx);
+	const int layer = result_layer.at(idx);
+	const int region = result_region.at(idx);
+	//const int width = result_phiWidth.at(idx);
+	//const int etaWidth = result_etaWidth.at(idx);
+	const float residualX = result_residualLocX.at(idx);
+	const float pullLocX = result_pullLocX.at(idx);
+	const float residualY = result_residualLocY.at(idx);
+	const float pullLocY = result_pullLocY.at(idx);
+	
+	if (det == -1) continue;
+	if (region == -1) continue;
+	
+	// Unbiased residuals only for the moment
+	if (measureType == 4) {
 	  
-	  const std::vector<int>&   result_measureType = measurement_typeAcc(trk);
-	  const std::vector<int>&   result_region = measurement_regionAcc(trk);
-	  const std::vector<int>&   result_layer  = measurement_layerAcc(trk);
-	  const std::vector<float>& result_residualLocX = hitResiduals_residualLocXAcc(trk);
-	  const std::vector<float>& result_pullLocX = hitResiduals_pullLocXAcc(trk);
-	  const std::vector<float>& result_residualLocY = hitResiduals_residualLocYAcc(trk);
-	  const std::vector<float>& result_pullLocY = hitResiduals_pullLocYAcc(trk);
-	  //const std::vector<int>&   result_phiWidth = hitResiduals_phiWidthAcc(trk);
-	  //const std::vector<int>&   result_etaWidth = hitResiduals_etaWidthAcc(trk);
-
-	  //const float eta = trk.eta();
+	  //1 PIXEL, 2 STRIP
+	  if (det == 1 || det == 0 )  {// PIXEL or PIXEL LY 0
+	    if (region == 0) { // BARREL
+	      //std::cout<<"Filling pixel layer "<<layer<<std::endl;
+	      auto pix_b_residualsx_m = Monitored::Scalar<float>("m_pix_residualsx", residualX);
+	      auto pix_b_residualsy_m = Monitored::Scalar<float>("m_pix_residualsy", residualY);
+	      auto pix_b_pullsx_m     = Monitored::Scalar<float>("m_pix_pullsx",     pullLocX);
+	      auto pix_b_pullsy_m     = Monitored::Scalar<float>("m_pix_pullsy",     pullLocY);
+	      
+	      fill(m_tools[m_pixResidualX[layer]], pix_b_residualsx_m);
+	      fill(m_tools[m_pixResidualY[layer]], pix_b_residualsy_m);
+	      fill(m_tools[m_pixPullX[layer]], pix_b_pullsx_m);
+	      fill(m_tools[m_pixPullY[layer]], pix_b_pullsy_m);
+	      
+	    } //Barrel
+	  } // Pixel
 	  
-	  // NP: this should be fine... resiudal filled with -1 if not hit
-	  if (result_det.size() != result_residualLocX.size()) {
-	    ATH_MSG_WARNING("Vectors of results are not matched in size!");
-	  }
-	  const auto resultSize = result_region.size();
-	  for (unsigned int idx = 0; idx < resultSize; ++idx) {
-	    
-	    const int measureType = result_measureType[idx];
-	    const int det = result_det[idx];
-	    const int layer = result_layer[idx];
-	    const int region = result_region[idx];
-	    //const int width = result_phiWidth[idx];
-	    //const int etaWidth = result_etaWidth[idx];
-	    const float residualX = result_residualLocX[idx];
-	    const float pullLocX = result_pullLocX[idx];
-	    const float residualY = result_residualLocY[idx];
-	    const float pullLocY = result_pullLocY[idx];
-	    if ((det == -1) or (region == -1)) {
-	      continue;
+	  else if (det == 2) { // Strips
+	    if (region == 0) { // BARREL		
+	      auto strip_b_residualsx_m = Monitored::Scalar<float>("m_strip_residualsx", residualX);
+	      auto strip_b_pullsx_m     = Monitored::Scalar<float>("m_strip_pullsx",     pullLocX);
+	      fill(m_tools[m_stripResidualX[layer]], strip_b_residualsx_m);
+	      fill(m_tools[m_stripPullX[layer]], strip_b_pullsx_m);
 	    }
-	    
-	    // Unbiased residuals only for the moment
-
-	    if (measureType == 4) {
-
-	      //1 PIXEL, 2 STRIP
-	      if (det == 1 || det == 0 )  {// PIXEL or PIXEL LY 0
-		if (region == 0) { // BARREL
-		  //std::cout<<"Filling pixel layer "<<layer<<std::endl;
-		  auto pix_b_residualsx_m = Monitored::Scalar<float>("m_pix_residualsx", residualX);
-		  auto pix_b_residualsy_m = Monitored::Scalar<float>("m_pix_residualsy", residualY);
-		  auto pix_b_pullsx_m     = Monitored::Scalar<float>("m_pix_pullsx",     pullLocX);
-		  auto pix_b_pullsy_m     = Monitored::Scalar<float>("m_pix_pullsy",     pullLocY);
-		  
-		  fill(m_tools[m_pixResidualX[layer]], pix_b_residualsx_m);
-		  fill(m_tools[m_pixResidualY[layer]], pix_b_residualsy_m);
-		  fill(m_tools[m_pixPullX[layer]], pix_b_pullsx_m);
-		  fill(m_tools[m_pixPullY[layer]], pix_b_pullsy_m);
-		  
-		} //Barrel
-	      } // Pixel
-	      
-	      else if (det == 2) { // Strips
-		if (region == 0) { // BARREL
-		  
-		  auto strip_b_residualsx_m = Monitored::Scalar<float>("m_strip_residualsx", residualX);
-		  auto strip_b_pullsx_m     = Monitored::Scalar<float>("m_strip_pullsx",     pullLocX);
-		  fill(m_tools[m_stripResidualX[layer]], strip_b_residualsx_m);
-		  fill(m_tools[m_stripPullX[layer]], strip_b_pullsx_m);
-		}
-	      }
-	    } //unbiased residuals
-	  }//resultSize
-	}//result det not empty
-      } //hit Detail available
-    }//trk loop
-
+	  }
+	} // measure type
+      } // resultSize
+    } // loop on track
+    
     return StatusCode::SUCCESS;
     
-  }//fill histograms
-}//name space ActsTrk
+  } // fill histograms
+
+} //name space ActsTrk
diff --git a/Tracking/Acts/ActsMonitoring/src/ITkAlignMonResidualsAlg.h b/Tracking/Acts/ActsMonitoring/src/ITkAlignMonResidualsAlg.h
index 38c693f81ee..ab2f4020c4f 100644
--- a/Tracking/Acts/ActsMonitoring/src/ITkAlignMonResidualsAlg.h
+++ b/Tracking/Acts/ActsMonitoring/src/ITkAlignMonResidualsAlg.h
@@ -20,12 +20,20 @@ namespace ActsTrk {
     virtual StatusCode fillHistograms(const EventContext& ctx) const override;
 
   private:
-    
-    SG::ReadHandleKey<ActsTrk::TrackContainer> m_tracksKey{this, "ActsTracks","","Input Acts::Track Collection"};
-    SG::ReadHandleKey<xAOD::TrackParticleContainer> m_trackParticlesKey{this, "InDetTrackParticles","InDetTrackParticles","Input xAOD::TrackParticles"};
+    SG::ReadHandleKey<xAOD::TrackParticleContainer> m_trackParticlesKey{this, "TrackParticles", "", "Input xAOD::TrackParticles"};
+
+    // Decorators
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_measurement_det {this, "measurement_det", "measurement_det"};
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_measurement_region {this, "measurement_region", "measurement_region"};
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_measurement_type {this, "measurement_type", "measurement_type"};
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_measurement_layer {this, "measurement_iLayer", "measurement_iLayer"};
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_hitResiduals_residualLocX {this, "hitResiduals_residualLocX", "hitResiduals_residualLocX"};
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_hitResiduals_pullLocX {this, "hitResiduals_pullLocX", "hitResiduals_pullLocX"};
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_hitResiduals_residualLocY {this, "hitResiduals_residualLocY", "hitResiduals_residualLocY"};
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_hitResiduals_pullLocY {this, "hitResiduals_pullLocY", "hitResiduals_pullLocY"};
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_hitResiduals_phiWidth {this, "hitResiduals_phiWidth", "hitResiduals_phiWidth"};
+    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_hitResiduals_etaWidth {this, "hitResiduals_etaWidth", "hitResiduals_etaWidth"};
 
-    SG::ReadDecorHandleKey<xAOD::TrackParticleContainer> m_acc_measurement_regionAcc {this, "measurement_region", m_trackParticlesKey, "measurement_region"};
-    
     Gaudi::Property< std::string > m_monGroupName
       {this, "MonGroupName", "ActsResAnalysisAlg"};
 
diff --git a/Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecoration.cxx b/Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecorationAlg.cxx
similarity index 88%
rename from Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecoration.cxx
rename to Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecorationAlg.cxx
index 73f5c6c08a5..d56f1ba1dc5 100644
--- a/Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecoration.cxx
+++ b/Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecorationAlg.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
 */
 
-#include "MeasurementToTrackParticleDecoration.h"
+#include "src/MeasurementToTrackParticleDecorationAlg.h"
 #include "ActsGeometry/ActsDetectorElement.h"
 #include "ActsGeometry/ATLASSourceLink.h"
 #include "xAODMeasurementBase/MeasurementDefs.h"
@@ -18,14 +18,42 @@ using namespace Acts::UnitLiterals;
 
 namespace ActsTrk {
 
-    MeasurementToTrackParticleDecoration::MeasurementToTrackParticleDecoration(const std::string &name, ISvcLocator *pSvcLocator) :
+    MeasurementToTrackParticleDecorationAlg::MeasurementToTrackParticleDecorationAlg(const std::string &name,
+										     ISvcLocator *pSvcLocator) :
       AthReentrantAlgorithm(name,pSvcLocator)
     {}
 
-    StatusCode MeasurementToTrackParticleDecoration::initialize()
+    StatusCode MeasurementToTrackParticleDecorationAlg::initialize()
     {
+        ATH_MSG_DEBUG("Initializing " << name() << " ...");
+	
         ATH_CHECK(m_trackParticlesKey.initialize());
-        ATH_CHECK(m_measurementRegionKey.initialize());
+
+	m_measurementRegionKey = m_trackParticlesKey.key() + "." + m_measurementRegionKey.key();
+	m_measurementDetectorKey = m_trackParticlesKey.key() + "." + m_measurementDetectorKey.key();
+	m_measurementLayerKey = m_trackParticlesKey.key() + "." + m_measurementLayerKey.key();
+	m_chi2HitPredictedKey = m_trackParticlesKey.key() + "." + m_chi2HitPredictedKey.key();
+	m_chi2HitFilteredKey = m_trackParticlesKey.key() + "." + m_chi2HitFilteredKey.key();
+	m_measurementTypeKey = m_trackParticlesKey.key() + "." + m_measurementTypeKey.key();
+	m_measurementPhiWidthKey = m_trackParticlesKey.key() + "." + m_measurementPhiWidthKey.key();
+	m_measurementEtaWidthKey = m_trackParticlesKey.key() + "." + m_measurementEtaWidthKey.key();
+
+	m_residualLocXkey = m_trackParticlesKey.key() + "." + m_residualLocXkey.key();
+	m_pullLocXkey = m_trackParticlesKey.key() + "." + m_pullLocXkey.key();
+	m_measurementLocXkey = m_trackParticlesKey.key() + "." + m_measurementLocXkey.key();
+	m_trackParameterLocXkey = m_trackParticlesKey.key() + "." + m_trackParameterLocXkey.key();
+	m_measurementLocCovXkey = m_trackParticlesKey.key() + "." + m_measurementLocCovXkey.key();
+	m_trackParameterLocCovXkey = m_trackParticlesKey.key() + "." + m_trackParameterLocCovXkey.key();
+
+	m_residualLocYkey = m_trackParticlesKey.key() + "." + m_residualLocYkey.key();
+	m_pullLocYkey = m_trackParticlesKey.key() + "." + m_pullLocYkey.key();
+	m_measurementLocYkey = m_trackParticlesKey.key() + "." + m_measurementLocYkey.key();
+	m_trackParameterLocYkey = m_trackParticlesKey.key() + "." + m_trackParameterLocYkey.key();
+	m_measurementLocCovYkey = m_trackParticlesKey.key() + "." + m_measurementLocCovYkey.key();
+	m_trackParameterLocCovYkey = m_trackParticlesKey.key() + "." + m_trackParameterLocCovYkey.key();
+	
+	// Decorations
+	ATH_CHECK(m_measurementRegionKey.initialize());
 	ATH_CHECK(m_measurementDetectorKey.initialize());
         ATH_CHECK(m_measurementLayerKey.initialize());
 	ATH_CHECK(m_chi2HitPredictedKey.initialize());
@@ -51,9 +79,9 @@ namespace ActsTrk {
         return StatusCode::SUCCESS;
     }
 
-  StatusCode MeasurementToTrackParticleDecoration::execute(const EventContext& ctx) const
+  StatusCode MeasurementToTrackParticleDecorationAlg::execute(const EventContext& ctx) const
     {
-        ATH_MSG_DEBUG("Executing MeasurementToTrackParticleDecoration...");
+        ATH_MSG_DEBUG("Executing " << name() << " ...");
 
 	auto tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
 
@@ -367,7 +395,7 @@ namespace ActsTrk {
         return StatusCode::SUCCESS;
     }
   
-  float MeasurementToTrackParticleDecoration::getChi2Contribution(const typename ActsTrk::TrackStateBackend::ConstTrackStateProxy &state) const {
+  float MeasurementToTrackParticleDecorationAlg::getChi2Contribution(const typename ActsTrk::TrackStateBackend::ConstTrackStateProxy &state) const {
     
     auto pred  = state.predicted();
     auto predC = state.predictedCovariance();
@@ -395,10 +423,10 @@ namespace ActsTrk {
   }
 
   
-  float MeasurementToTrackParticleDecoration::evaluatePull(const float residual,
-							   const float measurementCovariance,
-							   const float trackParameterCovariance,
-							   const bool evaluateUnbiased) const {
+  float MeasurementToTrackParticleDecorationAlg::evaluatePull(const float residual,
+							      const float measurementCovariance,
+							      const float trackParameterCovariance,
+							      const bool evaluateUnbiased) const {
     float correlation = evaluateUnbiased ? 1. : -1.;
     float residualCovariance = measurementCovariance + correlation*trackParameterCovariance;
     if (residualCovariance<=0.) {
diff --git a/Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecoration.h b/Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecorationAlg.h
similarity index 68%
rename from Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecoration.h
rename to Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecorationAlg.h
index a64554e6fd4..66d1b6ab207 100644
--- a/Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecoration.h
+++ b/Tracking/Acts/ActsObjectDecoration/src/MeasurementToTrackParticleDecorationAlg.h
@@ -11,8 +11,8 @@
 //
 ///////////////////////////////////////////////////////////////////
 
-#ifndef MEASUREMENTTOTRACKPARTICLEDECORATION_H
-#define MEASUREMENTTOTRACKPARTICLEDECORATION_H
+#ifndef MEASUREMENTTOTRACKPARTICLEDECORATIONALG_H
+#define MEASUREMENTTOTRACKPARTICLEDECORATIONALG_H
 
 #include "AthenaBaseComps/AthReentrantAlgorithm.h"
 #include "GaudiKernel/ServiceHandle.h"
@@ -27,22 +27,18 @@
 #include "ActsEvent/TrackContainer.h"
 #include "Acts/EventData/TrackStateProxy.hpp"
 
-using EffectiveCalibrated =
-  typename Acts::detail_lt::DynamicSizeTypes<>::CoefficientsMap;
-using EffectiveCalibratedCovariance =
-  typename Acts::detail_lt::DynamicSizeTypes<>::CovarianceMap;
 
 namespace ActsTrk {
 
-    class MeasurementToTrackParticleDecoration : public AthReentrantAlgorithm  {
+    class MeasurementToTrackParticleDecorationAlg : public AthReentrantAlgorithm  {
     public:
-        MeasurementToTrackParticleDecoration(const std::string &name,ISvcLocator *pSvcLocator);
-        virtual ~MeasurementToTrackParticleDecoration() = default;
+        MeasurementToTrackParticleDecorationAlg(const std::string &name,ISvcLocator *pSvcLocator);
+        virtual ~MeasurementToTrackParticleDecorationAlg() = default;
 
         virtual StatusCode initialize() override;
         virtual StatusCode execute(const EventContext& ctx) const override;
-        virtual StatusCode finalize() override { return StatusCode::SUCCESS;};
 
+    private:      
         enum Subdetector {
             INVALID_DETECTOR=-1, INNERMOST_PIXEL, PIXEL, STRIP, N_SUBDETECTORS
         };
@@ -53,8 +49,9 @@ namespace ActsTrk {
 	    INVALID_MEASUREMENT=-1, HIT, OUTLIER, HOLE, BIASED, UNBIASED
         };
 
-      float getChi2Contribution(const typename ActsTrk::TrackStateBackend::ConstTrackStateProxy &state) const ;
-      std::pair<Acts::BoundVector, Acts::BoundMatrix> getUnbiasedTrackParameters(const typename ActsTrk::TrackStateBackend::ConstTrackStateProxy &state, bool useSmoothed=true) const;
+      float getChi2Contribution(const typename ActsTrk::TrackStateBackend::ConstTrackStateProxy &state) const;
+      std::pair<Acts::BoundVector, Acts::BoundMatrix> getUnbiasedTrackParameters(const typename ActsTrk::TrackStateBackend::ConstTrackStateProxy &state,
+										 bool useSmoothed = true) const;
 
       float evaluatePull(const float residual,
 			 const float measurementCovariance,
@@ -66,73 +63,74 @@ namespace ActsTrk {
       ToolHandle<IActsTrackingGeometryTool> m_trackingGeometryTool{this, "TrackingGeometryTool", ""};
       
       SG::ReadHandleKey<xAOD::TrackParticleContainer> m_trackParticlesKey {
-	this, "TrackParticleKey", "InDetTrackParticles", "Input track particle collection"};
+	this, "TrackParticleKey", "", "Input track particle collection"};
       
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementRegionKey{
-	this, "MeasurementRegionKey", m_trackParticlesKey,"measurement_region",
+	this, "MeasurementRegionKey", "measurement_region",
 	"Decorate track particle with region of the measurement (barrel, ec)"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementDetectorKey{
-	this, "MeasurementDetectorKey", m_trackParticlesKey,"measurement_det",
+	this, "MeasurementDetectorKey", "measurement_det",
 	"Decorate track particle with measurement detector id (innermost pix, pix, strip)"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementLayerKey{
-	this, "MeasurementLayerKey", m_trackParticlesKey,"measurement_iLayer",
+	this, "MeasurementLayerKey", "measurement_iLayer",
 	"Decorate track particle with measurement layer"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_chi2HitPredictedKey{
-	this, "Chi2HitPredictedKey", m_trackParticlesKey,"chi2_hit_predicted",
+	this, "Chi2HitPredictedKey", "chi2_hit_predicted",
 	"Predicted Chi2 contribution for each hit"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_chi2HitFilteredKey{
-	this, "Chi2HitFilteredKey", m_trackParticlesKey,"chi2_hit_filtered",
+	this, "Chi2HitFilteredKey", "chi2_hit_filtered",
 	"Filtered Chi2 contribution for each hit"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementTypeKey{
-	this, "MeasurementTypeKey", m_trackParticlesKey,"measurement_type",
+	this, "MeasurementTypeKey", "measurement_type",
 	"Decorate track particle with type of track state (outlier,hole, biased/unbiased)"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementPhiWidthKey{
-	this, "MeasurementPhiWidthKey", m_trackParticlesKey,"hitResiduals_phiWidth",
+	this, "MeasurementPhiWidthKey", "hitResiduals_phiWidth",
 	"Decorate track particle with measurement cluster size (in r-phi)"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementEtaWidthKey{
-	this, "MeasurementEtaWidthKey", m_trackParticlesKey,"hitResiduals_etaWidth",
+	this, "MeasurementEtaWidthKey", "hitResiduals_etaWidth",
 	"Decorate track particle with measurement cluster size (in eta)"};
       
       
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_residualLocXkey{
-	this, "ResidualLocXkey", m_trackParticlesKey,"hitResiduals_residualLocX",
+	this, "ResidualLocXkey", "hitResiduals_residualLocX",
 	"Decorate track particle with unbiased residual in local x"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_pullLocXkey{
-	this, "PullLocXkey", m_trackParticlesKey,"hitResiduals_pullLocX",
+	this, "PullLocXkey", "hitResiduals_pullLocX",
 	"Decorate track particle with unbiased pull in local x"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementLocXkey{
-	this, "MeasurementLocXkey", m_trackParticlesKey,"measurementLocX",
+	this, "MeasurementLocXkey", "measurementLocX",
 	"Decorate track particle with measurement local x"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_trackParameterLocXkey{
-	this, "TrackParameterLocXkey", m_trackParticlesKey,"trackParamLocX",
+	this, "TrackParameterLocXkey", "trackParamLocX",
 	"Decorate track particle with unbiased prediction in local x"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementLocCovXkey{
-	this, "MeasurementLocCovXkey", m_trackParticlesKey,"measurementLocCovX",
+	this, "MeasurementLocCovXkey", "measurementLocCovX",
 	"Decorate track particle with local x measurement covariance"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_trackParameterLocCovXkey{
-	this, "TrackParameterLocCovXkey", m_trackParticlesKey,"trackParameterLocCovX",
+	this, "TrackParameterLocCovXkey", "trackParameterLocCovX",
 	"Decorate track particle with unbiased local x prediction covariance"};
       
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_residualLocYkey{
-	this, "ResidualLocYkey", m_trackParticlesKey,"hitResiduals_residualLocY",
+	this, "ResidualLocYkey", "hitResiduals_residualLocY",
 	"Decorate track particle with unbiased residual in local y"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_pullLocYkey{
-	this, "PullLocYkey", m_trackParticlesKey,"hitResiduals_pullLocY",
+	this, "PullLocYkey", "hitResiduals_pullLocY",
 	"Decorate track particle with unbiased pull in local y"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementLocYkey{
-	this, "MeasurementLocYkey", m_trackParticlesKey,"measurementLocY",
+	this, "MeasurementLocYkey", "measurementLocY",
 	"Decorate track particle with measurement local y"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_trackParameterLocYkey{
-	this, "TrackParameterLocYkey", m_trackParticlesKey,"trackParamLocY",
+	this, "TrackParameterLocYkey", "trackParamLocY",
 	"Decorate track particle with unbiased prediction in local y"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_measurementLocCovYkey{
-	this, "MeasurementLocCovYkey", m_trackParticlesKey,"measurementLocCovY",
+	this, "MeasurementLocCovYkey", "measurementLocCovY",
 	"Decorate track particle with local y measurement covariance"};
       SG::WriteDecorHandleKey<xAOD::TrackParticleContainer> m_trackParameterLocCovYkey{
-	this, "TrackParameterLocCovYkey", m_trackParticlesKey,"trackParameterLocCovY",
+	this, "TrackParameterLocCovYkey", "trackParameterLocCovY",
 	"Decorate track particle with unbiased local y prediction covariance"};
     };
 }
 
-#endif // MEASUREMENTTOTRACKPARTICLEDECORATION_H
+#endif
+
 
diff --git a/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecorator.cxx b/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecorator.cxx
deleted file mode 100644
index db271e24f22..00000000000
--- a/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecorator.cxx
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
-  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
-*/
-#include "PixelClusterTruthDecorator.h"
-
-//output
-#include "xAODTracking/TrackMeasurementValidation.h"
-#include "xAODTracking/TrackMeasurementValidationContainer.h"
-#include "xAODTracking/TrackMeasurementValidationAuxContainer.h"
-#include "TruthUtils/HepMCHelpers.h"
-
-#define AUXDATA(OBJ, TYP, NAME) \
-  static const SG::AuxElement::Accessor<TYP> acc_##NAME (#NAME);  acc_##NAME(*(OBJ))
-
-namespace ActsTrk {
-
-  PixelClusterTruthDecorator::PixelClusterTruthDecorator(const std::string& name, ISvcLocator *pSvcLocator) :
-    AthReentrantAlgorithm(name, pSvcLocator)
-  {}
-
-  StatusCode PixelClusterTruthDecorator::initialize() {
-    
-    // Read keys
-    ATH_CHECK(m_clustercontainer_key.initialize());
-    ATH_CHECK(m_associationMap_key.initialize());
-    
-    // Write keys
-    ATH_CHECK(m_write_xaod_key.initialize());
-    //ATH_CHECK(m_write_offsets.initialize()); 
-
-    return StatusCode::SUCCESS;
-  }
-  
-StatusCode PixelClusterTruthDecorator::execute(const EventContext& ctx) const {
-
-  //Mandatory. Require if the algorithm is scheduled.
-  SG::ReadHandle<xAOD::PixelClusterContainer> PixelClusterContainer(m_clustercontainer_key,ctx);
-
-  // Get the truth association map
-  const MeasurementToTruthParticleAssociation* measToTruth(nullptr);
-  if (m_useTruthInfo) {
-    SG::ReadHandle<MeasurementToTruthParticleAssociation> measToTruthHandle(m_associationMap_key,ctx);
-    
-    if (measToTruthHandle.isValid()) {
-      measToTruth = &*measToTruthHandle;
-    } else {
-      ATH_MSG_ERROR("MeasurementToTruthParticlesAssociation "<<m_associationMap_key.key()<<" not found!");
-    }
-  }
-
-  // Setup outputs
-  // Create the xAOD container and its auxiliary store:
-  SG::WriteHandle<xAOD::TrackMeasurementValidationContainer> xaod(m_write_xaod_key,ctx);
-  ATH_CHECK(xaod.record(std::make_unique<xAOD::TrackMeasurementValidationContainer>(),
-                        std::make_unique<xAOD::TrackMeasurementValidationAuxContainer>()));
-  
-
-  // loop over collection and convert to xAOD::TrackMeasurementValidation
-  for( const auto* prd : *PixelClusterContainer ){
-
-    //This needs to be taken care of
-    Identifier clusterId = Identifier((int)prd->identifier());
-    if ( !clusterId.is_valid() ) {
-      ATH_MSG_WARNING("Pixel cluster identifier is not valid");
-    }
-
-    xAOD::TrackMeasurementValidation* xprd = new xAOD::TrackMeasurementValidation();
-    //unsigned int cluster_idx = xaod->size();
-    xaod->push_back(xprd);
-    //Set Identifier
-    xprd->setIdentifier( clusterId.get_compact() );
-
-    //Set Global Position
-    auto gpos = prd->globalPosition();
-    xprd->setGlobalPosition(gpos.x(),gpos.y(),gpos.z());
-
-    auto locpos = prd->localPosition<2>();
-    // Set local error matrix
-    xprd->setLocalPosition(locpos[0],  locpos[1]); 
-
-    auto localCov = prd->localCovariance<2>();
-    if(localCov.size() == 1){
-      xprd->setLocalPositionError( localCov(0,0), 0., 0. ); 
-    } else if(localCov.size() == 4){
-      xprd->setLocalPositionError( localCov(0,0), localCov(1,1), localCov(0,1) );     
-    } else {
-      xprd->setLocalPositionError(0.,0.,0.);
-    }
-    
-    // Use the MultiTruth Collection 
-    // to get a list of all true particle contributing to the cluster
-    if (measToTruth) {
-      
-      if (prd->index() >= (*measToTruth).size()) {
-	ATH_MSG_ERROR("PRD index "<< prd->index()<<" not present in the measurement to truth vector with size "<<(*measToTruth).size());
-	continue;
-      }
-      auto tps = (*measToTruth)[prd->index()];
-      
-      
-      std::vector<unsigned int> tp_indices;
-      std::vector<unsigned int> tp_barcodes;
-      for (auto tp : tps) {
-	tp_indices.push_back(tp->index());
-	tp_barcodes.push_back(HepMC::barcode(tp));
-      }
-
-      //TODO change how to decorate
-      AUXDATA(xprd,std::vector<unsigned int>, truth_index) = tp_indices;
-      AUXDATA(xprd,std::vector<unsigned int>, truth_barcode) = tp_barcodes;
-      
-      
-    }// association map exists
-  
-  }// close loop on clusters
-
-  ATH_MSG_DEBUG( " recorded PixelPrepData objects: size " << xaod->size() );
-
-  return StatusCode::SUCCESS;
-}
-
-  StatusCode PixelClusterTruthDecorator::finalize(){
-    
-    return StatusCode::SUCCESS;
-  }
-}
-
-
diff --git a/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecorator.h b/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecorator.h
deleted file mode 100644
index b913cac7888..00000000000
--- a/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecorator.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
-*/
-
-///////////////////////////////////////////////////////////////////
-// Header file for class PixelClusterTruthDecorator
-//
-// The algorithm extends xAOD::PixelClusterContainer
-// with additional decorations associated to truth information
-// And stores the results in a TrackMeasurementValidationContainer
-// for compatibility with monitoring tools
-///////////////////////////////////////////////////////////////////
-
-#ifndef PIXELCLUSTERTRUTHDECORATOR_H
-#define PIXELCLUSTERTRUTHDECORATOR_H
-
-#include "AthenaBaseComps/AthReentrantAlgorithm.h"
-#include "GaudiKernel/ServiceHandle.h"
-#include "StoreGate/ReadHandleKey.h"
-
-#include "StoreGate/WriteDecorHandleKey.h"
-#include "StoreGate/WriteDecorHandle.h"
-
-#include "xAODInDetMeasurement/PixelClusterContainer.h"
-#include "xAODTracking/TrackMeasurementValidationContainer.h"
-
-#include "Identifier/Identifier.h"
-
-#include "ActsEvent/MeasurementToTruthParticleAssociation.h"
-
-
-namespace ActsTrk {
-  
-  class PixelClusterTruthDecorator : public AthReentrantAlgorithm {
-  public:
-    PixelClusterTruthDecorator(const std::string &name,ISvcLocator *pSvcLocator);
-    virtual ~PixelClusterTruthDecorator() = default;
-    
-    virtual StatusCode initialize() override;
-    virtual StatusCode execute(const EventContext& ctx) const override;
-    virtual StatusCode finalize() override;
-    
-    SG::ReadHandleKey<xAOD::PixelClusterContainer> m_clustercontainer_key{this,"SiClusterContainer",
-      "PixelClusters","Input Pixel Cluster container"};
-    SG::ReadHandleKey<MeasurementToTruthParticleAssociation> m_associationMap_key{this,"AssociationMapOut","",
-      "Association map between measurements and truth particles"};
-    
-    SG::WriteHandleKey<xAOD::TrackMeasurementValidationContainer> m_write_xaod_key{this,"OutputClusterContainer","ITkPixelClusters",
-      "Output Pixel Validation Clusters"};
-    
-    
-  private:
-    bool m_useTruthInfo{true};
-    
-  };
-
-  
-  
-}
-
-
-#endif
diff --git a/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecoratorAlg.cxx b/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecoratorAlg.cxx
new file mode 100644
index 00000000000..565207235ea
--- /dev/null
+++ b/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecoratorAlg.cxx
@@ -0,0 +1,129 @@
+/*
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "src/PixelClusterTruthDecoratorAlg.h"
+#include "TruthUtils/HepMCHelpers.h"
+
+namespace ActsTrk {
+  
+  PixelClusterTruthDecoratorAlg::PixelClusterTruthDecoratorAlg(const std::string& name,
+							       ISvcLocator *pSvcLocator) :
+    AthReentrantAlgorithm(name, pSvcLocator)
+  {}
+
+  StatusCode PixelClusterTruthDecoratorAlg::initialize() {
+    ATH_MSG_DEBUG("Initialize " << name() << " ...");
+    
+    // Read keys
+    ATH_CHECK(m_clustercontainer_key.initialize());
+    ATH_CHECK(m_associationMap_key.initialize(m_useTruthInfo));
+    
+    // Write keys
+    ATH_CHECK(m_write_xaod_key.initialize());
+
+    // Decorators
+    m_measurement_truth_indices = m_write_xaod_key.key() + "." + m_measurement_truth_indices.key();
+    m_measurement_truth_barcodes = m_write_xaod_key.key() + "." + m_measurement_truth_barcodes.key();
+
+    ATH_CHECK(m_measurement_truth_indices.initialize(m_useTruthInfo));
+    ATH_CHECK(m_measurement_truth_barcodes.initialize(m_useTruthInfo));
+
+    return StatusCode::SUCCESS;
+  }
+  
+  StatusCode PixelClusterTruthDecoratorAlg::execute(const EventContext& ctx) const {
+
+  //Mandatory. Require if the algorithm is scheduled.
+  SG::ReadHandle<xAOD::PixelClusterContainer> PixelClusterContainer = SG::makeHandle(m_clustercontainer_key,ctx);
+  ATH_CHECK(PixelClusterContainer.isValid());
+  
+  // Get the truth association map
+  const MeasurementToTruthParticleAssociation* measToTruth(nullptr);
+  if (m_useTruthInfo) {
+    SG::ReadHandle<MeasurementToTruthParticleAssociation> measToTruthHandle = SG::makeHandle(m_associationMap_key,ctx);
+    ATH_CHECK(measToTruthHandle.isValid());
+    measToTruth = measToTruthHandle.cptr();
+  }
+
+  // Setup outputs
+  // Create the xAOD container and its auxiliary store:
+  SG::WriteHandle<xAOD::TrackMeasurementValidationContainer> xaod = SG::makeHandle(m_write_xaod_key,ctx);
+  ATH_CHECK(xaod.record(std::make_unique<xAOD::TrackMeasurementValidationContainer>(),
+                        std::make_unique<xAOD::TrackMeasurementValidationAuxContainer>()));
+  
+  // Create output collection
+  xAOD::TrackMeasurementValidationContainer *measurements = xaod.ptr();
+  std::vector<xAOD::TrackMeasurementValidation*> toAdd(PixelClusterContainer->size(), nullptr);
+  for (std::size_t i(0); i<toAdd.size(); ++i) {
+    toAdd[i] = new xAOD::TrackMeasurementValidation();
+  }
+  measurements->insert(measurements->end(), toAdd.begin(), toAdd.end());
+
+  
+  // loop over collection and convert to xAOD::TrackMeasurementValidation
+  for (std::size_t i(0); i<PixelClusterContainer->size(); ++i) {
+    const xAOD::PixelCluster* cluster = PixelClusterContainer->at(i);
+    xAOD::TrackMeasurementValidation* measurement = measurements->at(i);
+    
+    //This needs to be taken care of
+    Identifier clusterId = Identifier(static_cast<int>(cluster->identifier()));
+    if ( !clusterId.is_valid() ) {
+      ATH_MSG_ERROR("Pixel cluster identifier is not valid");
+      return StatusCode::FAILURE;
+    }
+    
+    //Set Identifier
+    measurement->setIdentifier( clusterId.get_compact() );
+
+    //Set Global Position
+    auto gpos = cluster->globalPosition();
+    measurement->setGlobalPosition(gpos.x(), gpos.y(), gpos.z());
+
+    // Set local position and error matrix
+    auto locpos = cluster->localPosition<2>();
+    measurement->setLocalPosition(locpos[0],  locpos[1]); 
+
+    auto localCov = cluster->localCovariance<2>();
+    measurement->setLocalPositionError( localCov(0,0), localCov(1,1), localCov(0,1) );
+  }
+
+  // handle the truth
+  if (m_useTruthInfo) {
+    SG::WriteDecorHandle<xAOD::TrackMeasurementValidationContainer, std::vector<unsigned int>> decor_truth_indices( m_measurement_truth_indices, ctx );
+    SG::WriteDecorHandle<xAOD::TrackMeasurementValidationContainer, std::vector<unsigned int>> decor_truth_barcode( m_measurement_truth_barcodes, ctx );
+  
+    for (std::size_t i(0); i<PixelClusterContainer->size(); ++i) {
+      const xAOD::PixelCluster* cluster = PixelClusterContainer->at(i);
+      xAOD::TrackMeasurementValidation* measurement = measurements->at(i);
+
+      // Use the MultiTruth Collection 
+      // to get a list of all true particle contributing to the cluster      
+      if (cluster->index() >= measToTruth->size()) {
+	ATH_MSG_ERROR( "PRD index "<< cluster->index() << " not present in the measurement to truth vector with size " << measToTruth->size() );
+	return StatusCode::FAILURE;
+      }
+
+      auto tps = measToTruth->at(cluster->index());
+
+      std::vector<unsigned int> tp_indices;
+      std::vector<unsigned int> tp_barcodes;
+      for (const auto& tp : tps) {
+        tp_indices.push_back(tp->index());
+        tp_barcodes.push_back(HepMC::barcode(tp));
+      }
+      
+      // decorate
+      decor_truth_indices(*measurement) = std::move(tp_indices);
+      decor_truth_barcode(*measurement) = std::move(tp_barcodes);
+      
+    } // loop on clusters/measurements
+  } // if do truth
+
+  ATH_MSG_DEBUG( " recorded PixelPrepData objects: size " << measurements->size() );
+  return StatusCode::SUCCESS;
+}
+
+}
+
+
diff --git a/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecoratorAlg.h b/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecoratorAlg.h
new file mode 100644
index 00000000000..15ff0cf2238
--- /dev/null
+++ b/Tracking/Acts/ActsObjectDecoration/src/PixelClusterTruthDecoratorAlg.h
@@ -0,0 +1,60 @@
+/*
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// Header file for class PixelClusterTruthDecoratorAlg
+//
+// The algorithm extends xAOD::PixelClusterContainer
+// with additional decorations associated to truth information
+// And stores the results in a TrackMeasurementValidationContainer
+// for compatibility with monitoring tools
+///////////////////////////////////////////////////////////////////
+
+#ifndef PIXELCLUSTERTRUTHDECORATORALG_H
+#define PIXELCLUSTERTRUTHDECORATORALG_H
+
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "StoreGate/ReadHandleKey.h"
+
+#include "StoreGate/WriteDecorHandleKey.h"
+#include "StoreGate/WriteDecorHandle.h"
+
+#include "xAODInDetMeasurement/PixelClusterContainer.h"
+#include "xAODTracking/TrackMeasurementValidationContainer.h"
+#include "xAODTracking/TrackMeasurementValidationAuxContainer.h"
+
+#include "Identifier/Identifier.h"
+
+#include "ActsEvent/MeasurementToTruthParticleAssociation.h"
+
+
+namespace ActsTrk {
+  
+  class PixelClusterTruthDecoratorAlg
+    : public AthReentrantAlgorithm {
+  public:
+    PixelClusterTruthDecoratorAlg(const std::string &name,
+				  ISvcLocator *pSvcLocator);
+    virtual ~PixelClusterTruthDecoratorAlg() = default;
+    
+    virtual StatusCode initialize() override;
+    virtual StatusCode execute(const EventContext& ctx) const override;
+    
+  private:
+    SG::ReadHandleKey<xAOD::PixelClusterContainer> m_clustercontainer_key {this,"ClusterContainer", "","Input Pixel Cluster container"};
+    SG::ReadHandleKey<ActsTrk::MeasurementToTruthParticleAssociation> m_associationMap_key {this,"AssociationMapOut","", "Association map between measurements and truth particles"};
+    
+    SG::WriteHandleKey<xAOD::TrackMeasurementValidationContainer> m_write_xaod_key{this,"MeasurementContainer","", "Output Pixel Validation Clusters"};
+
+    // Decorations
+    SG::WriteDecorHandleKey<xAOD::TrackMeasurementValidationContainer> m_measurement_truth_indices {this, "MeasurementTruthIndices", "truth_index"};
+    SG::WriteDecorHandleKey<xAOD::TrackMeasurementValidationContainer> m_measurement_truth_barcodes {this, "MeasurementTruthBarcode", "truth_barcode"};
+
+    Gaudi::Property<bool> m_useTruthInfo {this, "UseTruthInfo", true};
+  };
+  
+}
+
+#endif
diff --git a/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecorator.cxx b/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecorator.cxx
deleted file mode 100644
index ae25e9398aa..00000000000
--- a/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecorator.cxx
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
-*/
-#include "PixelClusterTruthDecorator.h"
-#include "StripClusterTruthDecorator.h"
-
-//output
-#include "xAODTracking/TrackMeasurementValidation.h"
-#include "xAODTracking/TrackMeasurementValidationContainer.h"
-#include "xAODTracking/TrackMeasurementValidationAuxContainer.h"
-#include "TruthUtils/HepMCHelpers.h"
-
-#define AUXDATA(OBJ, TYP, NAME) \
-  static const SG::AuxElement::Accessor<TYP> acc_##NAME (#NAME);  acc_##NAME(*(OBJ))
-
-
-
-namespace ActsTrk {
-
-  StripClusterTruthDecorator::StripClusterTruthDecorator(const std::string& name,
-							 ISvcLocator *pSvcLocator) :
-    AthReentrantAlgorithm(name, pSvcLocator)
-  {}
-
-  
-  StatusCode StripClusterTruthDecorator::initialize() {
-    
-    // Read keys
-    ATH_CHECK(m_clustercontainer_key.initialize());
-    ATH_CHECK(m_associationMap_key.initialize());
-        
-    // Write keys
-    ATH_CHECK(m_write_xaod_key.initialize());
-    
-    return StatusCode::SUCCESS;
-  }
-  
-  StatusCode StripClusterTruthDecorator::execute(const EventContext& ctx)  const {
-    
-    SG::ReadHandle<xAOD::StripClusterContainer> StripClusterContainer(m_clustercontainer_key,ctx);
-
-    if (!StripClusterContainer.isValid()) {
-      ATH_MSG_ERROR("Failed Getting the strip cluster container "<<m_clustercontainer_key);
-      return StatusCode::FAILURE;
-    }
-      
-
-    const MeasurementToTruthParticleAssociation* measToTruth(nullptr);
-    if (m_useTruthInfo) {
-      SG::ReadHandle<MeasurementToTruthParticleAssociation> measToTruthHandle(m_associationMap_key,ctx);
-      
-      if (measToTruthHandle.isValid()) {
-	measToTruth = &*measToTruthHandle;
-      } else {
-	ATH_MSG_ERROR("Measurement to Truth association map "<<m_associationMap_key.key()<<" not found!");
-      }
-    }
-
-    // Setup outputs
-    // Create the xAOD container and its auxiliary store:
-    SG::WriteHandle<xAOD::TrackMeasurementValidationContainer> xaod(m_write_xaod_key,ctx);
-    ATH_CHECK(xaod.record(std::make_unique<xAOD::TrackMeasurementValidationContainer>(),
-			  std::make_unique<xAOD::TrackMeasurementValidationAuxContainer>()));
-    
-    
-    // loop over collection and convert to xAOD::TrackMeasurementValidation
-    for( const auto* prd : *StripClusterContainer ){
-      
-      //This needs to be taken care of
-      Identifier clusterId = Identifier((int)prd->identifier());
-      if ( !clusterId.is_valid() ) {
-	ATH_MSG_WARNING("Strip cluster identifier is not valid");
-      }
-
-      xAOD::TrackMeasurementValidation* xprd = new xAOD::TrackMeasurementValidation();
-      
-      //unsigned int cluster_idx = xaod->size();
-      xaod->push_back(xprd);
-      //Set Identifier
-      xprd->setIdentifier( clusterId.get_compact() );
-      
-      //Set Global Position
-      auto gpos = prd->globalPosition();
-      xprd->setGlobalPosition(gpos.x(),gpos.y(),gpos.z());
-      
-      auto locpos = prd->localPosition<1>();
-      // Set local error matrix
-      xprd->setLocalPosition(locpos[0],  locpos[1]); 
-      
-      
-      auto localCov = prd->localCovariance<1>();
-      
-      if(localCov.size() == 1){
-	xprd->setLocalPositionError( localCov(0,0), 0., 0. ); 
-      } else if(localCov.size() == 4){
-	xprd->setLocalPositionError( localCov(0,0), localCov(1,1), localCov(0,1) );     
-      } else {
-	xprd->setLocalPositionError(0.,0.,0.);
-      }
-      
-      // Get a list of all true particle contributing to the cluster
-
-      if (measToTruth) {
-
-	if (prd->index() >= (*measToTruth).size()) {
-	  ATH_MSG_ERROR("PRD index "<< prd->index()<<" not present in the measurement to truth vector with size "<<(*measToTruth).size());
-	  continue;
-	}
-	
-	auto tps = (*measToTruth)[prd->index()];
-	
-	//TODO:: reserve / resize?
-	std::vector<unsigned int> tp_indices;
-	std::vector<unsigned int> tp_barcodes;
-	for (auto tp : tps) {
-	  tp_indices.push_back(tp->index());
-	  tp_barcodes.push_back(HepMC::barcode(tp));
-	}
-	
-	//TODO move vectors
-	AUXDATA(xprd,std::vector<unsigned int>, truth_index) = tp_indices;
-	AUXDATA(xprd,std::vector<unsigned int>, truth_barcode) = tp_barcodes;
-	
-      }// association map exists
-  
-    }// close loop on clusters
-    
-    ATH_MSG_DEBUG( " recorded StripPrepData objects: size " << xaod->size() );
-    
-    return StatusCode::SUCCESS;
-  }
-
-
-  StatusCode StripClusterTruthDecorator::finalize(){
-    
-    return StatusCode::SUCCESS;
-  }
-  
-} // ActsTrk
diff --git a/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecoratorAlg.cxx b/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecoratorAlg.cxx
new file mode 100644
index 00000000000..5bb41645758
--- /dev/null
+++ b/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecoratorAlg.cxx
@@ -0,0 +1,121 @@
+/*
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "src/StripClusterTruthDecoratorAlg.h"
+#include "TruthUtils/HepMCHelpers.h"
+
+namespace ActsTrk {
+
+  StripClusterTruthDecoratorAlg::StripClusterTruthDecoratorAlg(const std::string& name,
+							       ISvcLocator *pSvcLocator) :
+    AthReentrantAlgorithm(name, pSvcLocator)
+  {}
+
+  
+  StatusCode StripClusterTruthDecoratorAlg::initialize() {
+    ATH_MSG_DEBUG("Initialize " << name() << " ...");
+    
+    // Read keys
+    ATH_CHECK(m_clustercontainer_key.initialize());
+    ATH_CHECK(m_associationMap_key.initialize(m_useTruthInfo));
+        
+    // Write keys
+    ATH_CHECK(m_write_xaod_key.initialize());
+
+    // Decorator
+    m_measurement_truth_indices = m_write_xaod_key.key() + "." + m_measurement_truth_indices.key();
+    m_measurement_truth_barcodes = m_write_xaod_key.key() + "." + m_measurement_truth_barcodes.key();
+    ATH_CHECK(m_measurement_truth_indices.initialize(m_useTruthInfo));
+    ATH_CHECK(m_measurement_truth_barcodes.initialize(m_useTruthInfo));
+    
+    return StatusCode::SUCCESS;
+  }
+  
+  StatusCode StripClusterTruthDecoratorAlg::execute(const EventContext& ctx)  const {
+    
+    SG::ReadHandle<xAOD::StripClusterContainer> StripClusterContainer = SG::makeHandle(m_clustercontainer_key,ctx);
+    ATH_CHECK(StripClusterContainer.isValid());
+    const xAOD::StripClusterContainer *stripClusters = StripClusterContainer.cptr();
+
+    const ActsTrk::MeasurementToTruthParticleAssociation* measToTruth(nullptr);
+    if (m_useTruthInfo) {
+      SG::ReadHandle<ActsTrk::MeasurementToTruthParticleAssociation> measToTruthHandle = SG::makeHandle(m_associationMap_key,ctx);
+      ATH_CHECK( measToTruthHandle.isValid());
+      measToTruth = measToTruthHandle.ptr();
+    }
+
+    // Setup outputs
+    // Create the xAOD container and its auxiliary store:
+    SG::WriteHandle<xAOD::TrackMeasurementValidationContainer> xaod = SG::makeHandle( m_write_xaod_key,ctx );
+    ATH_CHECK(xaod.record(std::make_unique<xAOD::TrackMeasurementValidationContainer>(),
+			  std::make_unique<xAOD::TrackMeasurementValidationAuxContainer>()));
+    xAOD::TrackMeasurementValidationContainer* measurements = xaod.ptr();
+
+    std::vector<xAOD::TrackMeasurementValidation*> toAdd(stripClusters->size(), nullptr);
+    for (std::size_t i(0); i<toAdd.size(); ++i) {
+      toAdd[i] = new xAOD::TrackMeasurementValidation();
+    }
+    measurements->insert(measurements->end(), toAdd.begin(), toAdd.end());
+    
+    // loop over collection and convert to xAOD::TrackMeasurementValidation
+    for (std::size_t i(0); i<stripClusters->size(); ++i) {
+      const xAOD::StripCluster* cluster = stripClusters->at(i);
+      xAOD::TrackMeasurementValidation *measurement = measurements->at(i);
+
+      //This needs to be taken care of
+      Identifier clusterId = Identifier(static_cast<int>(cluster->identifier()));
+      if ( !clusterId.is_valid() ) {
+	ATH_MSG_ERROR("Strip cluster identifier is not valid");
+	return StatusCode::FAILURE;
+      }
+
+      //Set Identifier
+      measurement->setIdentifier( clusterId.get_compact() );
+      
+      //Set Global Position
+      auto gpos = cluster->globalPosition();
+      measurement->setGlobalPosition(gpos.x(), gpos.y(), gpos.z());
+
+      // Set local position and error matrix
+      auto locpos = cluster->localPosition<1>();
+      measurement->setLocalPosition(locpos[0],  locpos[1]); 
+            
+      auto localCov = cluster->localCovariance<1>();
+      measurement->setLocalPositionError( localCov(0,0), 0., 0. ); 
+    }
+
+      
+    // Get a list of all true particle contributing to the cluster
+    if (m_useTruthInfo) {
+      SG::WriteDecorHandle<xAOD::TrackMeasurementValidationContainer, std::vector<unsigned int>> decor_truth_indices( m_measurement_truth_indices, ctx );
+      SG::WriteDecorHandle<xAOD::TrackMeasurementValidationContainer, std::vector<unsigned int>> decor_truth_barcode( m_measurement_truth_barcodes, ctx );
+    
+      for (std::size_t i(0); i<stripClusters->size(); ++i) {
+	const xAOD::StripCluster* cluster = stripClusters->at(i);
+	xAOD::TrackMeasurementValidation *measurement = measurements->at(i);
+	
+	if (cluster->index() >= measToTruth->size()) {
+	  ATH_MSG_ERROR("PRD index "<< cluster->index() << " not present in the measurement to truth vector with size " << measToTruth->size());
+	  return StatusCode::FAILURE;
+	}
+	
+	auto tps = measToTruth->at(cluster->index());
+
+	std::vector<unsigned int> tp_indices;
+	std::vector<unsigned int> tp_barcodes;
+	for (auto tp : tps) {
+	  tp_indices.push_back(tp->index());
+	  tp_barcodes.push_back(HepMC::barcode(tp));
+	}
+	
+	decor_truth_indices(*measurement) = std::move(tp_indices);
+	decor_truth_barcode(*measurement) = std::move(tp_barcodes);
+      } // loop on clusters
+    }
+    
+    ATH_MSG_DEBUG( " recorded StripPrepData objects: size " << measurements->size() );    
+    return StatusCode::SUCCESS;
+  }
+  
+} // ActsTrk
diff --git a/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecorator.h b/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecoratorAlg.h
similarity index 54%
rename from Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecorator.h
rename to Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecoratorAlg.h
index 72fb41afde5..ecea507f1ef 100644
--- a/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecorator.h
+++ b/Tracking/Acts/ActsObjectDecoration/src/StripClusterTruthDecoratorAlg.h
@@ -3,7 +3,7 @@
 */
 
 ///////////////////////////////////////////////////////////////////
-// Header file for class StipClusterTruthDecorator
+// Header file for class StipClusterTruthDecoratorAlg
 //
 // The algorithm extends xAOD::StripClusterContainer
 // with additional decorations associated to truth information
@@ -11,8 +11,8 @@
 // for compatibility with monitoring tools
 ///////////////////////////////////////////////////////////////////
 
-#ifndef STRIPCLUSTERTRUTHDECORATOR_H
-#define STRIPCLUSTERTRUTHDECORATOR_H
+#ifndef STRIPCLUSTERTRUTHDECORATORALG_H
+#define STRIPCLUSTERTRUTHDECORATORALG_H
 
 #include "AthenaBaseComps/AthReentrantAlgorithm.h"
 #include "GaudiKernel/ServiceHandle.h"
@@ -23,6 +23,7 @@
 
 #include "xAODInDetMeasurement/StripClusterContainer.h"
 #include "xAODTracking/TrackMeasurementValidationContainer.h"
+#include "xAODTracking/TrackMeasurementValidationAuxContainer.h"
 
 #include "Identifier/Identifier.h"
 
@@ -30,26 +31,24 @@
 
 namespace ActsTrk {
   
-  class StripClusterTruthDecorator : public AthReentrantAlgorithm {
+  class StripClusterTruthDecoratorAlg : public AthReentrantAlgorithm {
   public:
-    StripClusterTruthDecorator(const std::string &name,ISvcLocator *pSvcLocator);
-    virtual ~StripClusterTruthDecorator() = default;
+    StripClusterTruthDecoratorAlg(const std::string &name,ISvcLocator *pSvcLocator);
+    virtual ~StripClusterTruthDecoratorAlg() = default;
     
     virtual StatusCode initialize() override;
     virtual StatusCode execute(const EventContext& ctx) const override;
-    virtual StatusCode finalize() override;
-    
-    SG::ReadHandleKey<xAOD::StripClusterContainer> m_clustercontainer_key{this,"SiClusterContainer",
-      "StripClusters","Input Strip Cluster container"};
-    
-    SG::ReadHandleKey<MeasurementToTruthParticleAssociation> m_associationMap_key{this,"AssociationMapOut","",
-    "Association map between measurements and truth particles"};
-    SG::WriteHandleKey<xAOD::TrackMeasurementValidationContainer> m_write_xaod_key{this,"OutputClusterContainer","ITkStripClusters",
-    "Output Strip Validation Clusters"};
-    
+
   private:
+    SG::ReadHandleKey<xAOD::StripClusterContainer> m_clustercontainer_key{this,"ClusterContainer", "", "Input Strip Cluster container"};
+    SG::ReadHandleKey<MeasurementToTruthParticleAssociation> m_associationMap_key{this,"AssociationMapOut", "", "Association map between measurements and truth particles"};
+
+    SG::WriteHandleKey<xAOD::TrackMeasurementValidationContainer> m_write_xaod_key{this,"MeasurementContainer","", "Output Strip Validation Clusters"};
 
-    bool m_useTruthInfo{true};
+    SG::WriteDecorHandleKey<xAOD::TrackMeasurementValidationContainer> m_measurement_truth_indices {this, "MeasurementTruthIndices", "truth_index"};
+    SG::WriteDecorHandleKey<xAOD::TrackMeasurementValidationContainer> m_measurement_truth_barcodes {this, "MeasurementTruthBarcode", "truth_barcode"};
+    
+    Gaudi::Property<bool> m_useTruthInfo {this, "UseTruthInfo", true};
   };
 }
 
diff --git a/Tracking/Acts/ActsObjectDecoration/src/components/ActsObjectDecoration_entries.cxx b/Tracking/Acts/ActsObjectDecoration/src/components/ActsObjectDecoration_entries.cxx
index 2d5f03d2212..eeed5dfc4a4 100644
--- a/Tracking/Acts/ActsObjectDecoration/src/components/ActsObjectDecoration_entries.cxx
+++ b/Tracking/Acts/ActsObjectDecoration/src/components/ActsObjectDecoration_entries.cxx
@@ -2,14 +2,14 @@
   Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
-#include "src/MeasurementToTrackParticleDecoration.h"
-#include "src/PixelClusterTruthDecorator.h"
-#include "src/StripClusterTruthDecorator.h"
+#include "src/MeasurementToTrackParticleDecorationAlg.h"
+#include "src/PixelClusterTruthDecoratorAlg.h"
+#include "src/StripClusterTruthDecoratorAlg.h"
 #include "src/PixelClusterSiHitDecoratorAlg.h"
 #include "src/StripClusterSiHitDecoratorAlg.h"
 
-DECLARE_COMPONENT(ActsTrk::MeasurementToTrackParticleDecoration)
-DECLARE_COMPONENT(ActsTrk::PixelClusterTruthDecorator)
-DECLARE_COMPONENT(ActsTrk::StripClusterTruthDecorator)
+DECLARE_COMPONENT(ActsTrk::MeasurementToTrackParticleDecorationAlg)
+DECLARE_COMPONENT(ActsTrk::PixelClusterTruthDecoratorAlg)
+DECLARE_COMPONENT(ActsTrk::StripClusterTruthDecoratorAlg)
 DECLARE_COMPONENT(ActsTrk::PixelClusterSiHitDecoratorAlg)
 DECLARE_COMPONENT(ActsTrk::StripClusterSiHitDecoratorAlg)
-- 
GitLab