diff --git a/MuonSpectrometer/MuonPhaseII/MuonPatternRecognition/MuonTruthAlgsR4/python/MuonTruthAlgsConfig.py b/MuonSpectrometer/MuonPhaseII/MuonPatternRecognition/MuonTruthAlgsR4/python/MuonTruthAlgsConfig.py
index 94aa98d122f58952acf5a781f23987a889941ecb..2dfee864ff8874e42d47093303ce396ab566db65 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonPatternRecognition/MuonTruthAlgsR4/python/MuonTruthAlgsConfig.py
+++ b/MuonSpectrometer/MuonPhaseII/MuonPatternRecognition/MuonTruthAlgsR4/python/MuonTruthAlgsConfig.py
@@ -17,6 +17,12 @@ def TruthSegmentMakerCfg(flags, name = "TruthSegmentMakerAlg", **kwargs):
     if flags.Detector.EnableMM: containerNames+=["xMmSimHits"]
     if flags.Detector.EnablesTGC: containerNames+=["xStgcSimHits"] 
     kwargs.setdefault("SimHitKeys", containerNames)
+    PrdLinkInputs = []
+    if flags.Detector.EnableMDT: PrdLinkInputs+=[( 'xAOD::UncalibratedMeasurementContainer' , 'StoreGateSvc+xAODMdtCircles.simHitLink' )]       
+    if flags.Detector.EnableRPC: PrdLinkInputs+=[ ( 'xAOD::UncalibratedMeasurementContainer' , 'StoreGateSvc+xRpcMeasurements.simHitLink' )]
+    if flags.Detector.EnableTGC: PrdLinkInputs+=[('xAOD::UncalibratedMeasurementContainer' , 'StoreGateSvc+xTgcStrips.simHitLink' )] 
+
+    kwargs.setdefault("ExtraInputs", PrdLinkInputs)
     the_alg = CompFactory.MuonR4.TruthSegmentMaker(name, **kwargs)
     result.addEventAlgo(the_alg, primary = True)
     return result
diff --git a/MuonSpectrometer/MuonPhaseII/MuonValidation/MuonPatternRecognitionTest/src/MuonHoughTransformTester.cxx b/MuonSpectrometer/MuonPhaseII/MuonValidation/MuonPatternRecognitionTest/src/MuonHoughTransformTester.cxx
index df4ea07d2abcea06a8177216a2c7248030fc52dc..490bc7df5194dba0f13a624ab5a531f1ced92ecd 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonValidation/MuonPatternRecognitionTest/src/MuonHoughTransformTester.cxx
+++ b/MuonSpectrometer/MuonPhaseII/MuonValidation/MuonPatternRecognitionTest/src/MuonHoughTransformTester.cxx
@@ -22,6 +22,8 @@ namespace MuonValR4 {
         ATH_CHECK(m_inSimHitKeys.initialize());
         ATH_CHECK(m_spacePointKey.initialize());
         ATH_CHECK(m_inHoughSegmentSeedKey.initialize());
+        ATH_CHECK(m_truthSegmentKey.initialize());
+        ATH_CHECK(m_rh_truthSegmentSimHitLink.initialize());
         ATH_CHECK(m_inSegmentKey.initialize(!m_inSegmentKey.empty()));
         m_tree.addBranch(std::make_shared<MuonVal::EventInfoBranch>(m_tree,0));
         m_out_SP = std::make_shared<MuonValR4::SpacePointTesterModule>(m_tree, m_spacePointKey.key()); 
@@ -64,30 +66,33 @@ namespace MuonValR4 {
     }
 
    
-    void MuonHoughTransformTester::matchSeedToTruth(const MuonR4::SegmentSeed* seed, 
+    void MuonHoughTransformTester::matchSeedToTruth(const EventContext & ctx, const MuonR4::SegmentSeed* seed, 
                                                     chamberLevelObjects & objs ) const{
         double bestTruthFrac{0.}; 
-        HepMC::ConstGenParticlePtr bestMatch = nullptr; 
-        for (auto & [ genParticle, truthQuantities] : objs.truthMatching) {
+        const xAOD::MuonSegment* bestMatch = nullptr; 
+        SG::ReadDecorHandle<xAOD::MuonSegmentContainer,SimHitLinkVec> simHitsFromTruth(m_rh_truthSegmentSimHitLink, ctx);
+        SG::ConstAccessor<ElementLink<xAOD::MuonSimHitContainer>> simHitAcc("simHitLink"); 
+
+        for (auto & [ truthsegment, truthQuantities] : objs.truthMatching) {
             unsigned int nRecFound{0}; 
+            const SimHitLinkVec & simHitsForSegment = simHitsFromTruth(*truthsegment); 
+
             for (const MuonR4::HoughHitType& spacePoint : seed->getHitsInMax()) {
-                for (const xAOD::MuonSimHit* simHit : truthQuantities.detectorHits) {
-                    if(m_idHelperSvc->isMdt(simHit->identify()) &&
-                        spacePoint->identify() == simHit->identify()){
-                        ++nRecFound;
-                        break;
-                    } 
-                    //// Sim hits are expressed w.r.t to the gas gap Id. Check whether
-                    ///  the hit is in the same gas gap
-                    else if (m_idHelperSvc->gasGapId(spacePoint->identify()) == simHit->identify()) {
-                        ++nRecFound;
-                        // break; // should we... ? 
-                    }
+                if (!simHitAcc.isAvailable(*spacePoint->primaryMeasurement())) continue; 
+                auto simHitMatch = simHitAcc(*spacePoint->primaryMeasurement()); 
+                if (!simHitMatch.isValid() || *simHitMatch == nullptr){
+                    continue;
+                }
+                auto found = std::ranges::find_if( simHitsForSegment, [&simHitMatch](const ElementLink<xAOD::MuonSimHitContainer> & el){
+                    return (el == simHitMatch);
+                });
+                if (found != simHitsForSegment.end()){
+                    ++nRecFound; 
                 }
             }
             double truthFraction = (1.*nRecFound) / (1.*seed->getHitsInMax().size()); 
             if (truthFraction > bestTruthFrac) {
-                bestMatch = genParticle;
+                bestMatch = truthsegment;
                 bestTruthFrac = truthFraction; 
             }
         }
@@ -95,14 +100,14 @@ namespace MuonValR4 {
         /** Map the seed to the truth particle */
         chamberLevelObjects::SeedMatchQuantites& seedMatch = objs.seedMatching[seed];
         seedMatch.matchProb = bestTruthFrac;
-        seedMatch.truthParticle = bestMatch;
+        seedMatch.truthsegment = bestMatch;
         /** Back mapping of the best truth -> seed */
         objs.truthMatching[bestMatch].assocSeeds.push_back(seed);
     }
   
-    void MuonHoughTransformTester::matchSeedsToTruth(chamberLevelObjects & objs) const {        
+    void MuonHoughTransformTester::matchSeedsToTruth(const EventContext & ctx,chamberLevelObjects & objs) const {        
         for (auto & [ seed, matchObj] : objs.seedMatching) {
-            matchSeedToTruth(seed, objs);
+            matchSeedToTruth(ctx, seed, objs);
             ATH_MSG_VERBOSE("Truth matching probability "<<matchObj.matchProb);           
         }
     }
@@ -112,37 +117,42 @@ namespace MuonValR4 {
         m_out_stationEta = chamber->stationEta();
         m_out_stationPhi = chamber->stationPhi();
     }                
-    void MuonHoughTransformTester::fillTruthInfo(const HepMC::ConstGenParticlePtr genParticlePtr, const std::vector<const xAOD::MuonSimHit*> & hits,const ActsGeometryContext & gctx){
-        if (!genParticlePtr) return; 
+    void MuonHoughTransformTester::fillTruthInfo(const EventContext & ctx, const xAOD::MuonSegment* segment,const ActsGeometryContext & gctx){
+        if (!segment) return; 
         m_out_hasTruth = true; 
-        m_out_gen_Eta   = genParticlePtr->momentum().eta();
-        m_out_gen_Phi= genParticlePtr->momentum().phi();
-        m_out_gen_Pt= genParticlePtr->momentum().perp();
-        
-        const xAOD::MuonSimHit* simHit = hits.front(); 
-        const Identifier ID = simHit->identify();
-                
-        const Amg::Transform3D toChamber{toChamberTrf(gctx, ID)};
-        const Amg::Vector3D localPos{toChamber * xAOD::toEigen(simHit->localPosition())};
-        Amg::Vector3D chamberDir = toChamber.linear() * xAOD::toEigen(simHit->localDirection());
+        Amg::Vector3D segPos{
+            segment->x(),
+            segment->y(),
+            segment->z(),
+        }; 
+        Amg::Vector3D segDir{
+            segment->px(),
+            segment->py(),
+            segment->pz(),
+        };
+        // eta is interpreted as the eta-location 
+        m_out_gen_Eta   = segDir.eta();
+        m_out_gen_Phi= segDir.phi();
+        m_out_gen_Pt= segDir.perp();
+
+        SG::ReadDecorHandle<xAOD::MuonSegmentContainer,SimHitLinkVec> simHitsFromTruth(m_rh_truthSegmentSimHitLink, ctx);
+        const SimHitLinkVec & simHits = simHitsFromTruth(*segment);         
+        const xAOD::MuonSimHit* firstSimHit = *(simHits.front()); 
+        const Identifier ID = firstSimHit->identify();
+        const MuonGMR4::MuonReadoutElement* reElement = m_r4DetMgr->getReadoutElement(ID); 
+        //transform from local (w.r.t tube's frame) to global (ATLAS frame) and then to chamber's frame
+        const MuonGMR4::MuonChamber* muonChamber = reElement->getChamber();
+        auto toChamber = muonChamber->globalToLocalTrans(gctx);
+        const Amg::Vector3D chamberPos{toChamber * segPos};
+        Amg::Vector3D chamberDir = toChamber.linear() * segDir;
         
-        /// Express the simulated hit in the center of the chamber
-        const std::optional<double> lambda = Amg::intersect<3>(localPos, chamberDir, Amg::Vector3D::UnitZ(), 0.);
-        Amg::Vector3D chamberPos = localPos + (*lambda)*chamberDir;
-        m_out_gen_nHits = hits.size(); 
-        unsigned int nMdt{0}, nRpc{0}, nTgc{0}, nMm{0}, nsTgc{0}; 
-        for (const xAOD::MuonSimHit* hit : hits){
-            nMdt += m_idHelperSvc->isMdt(hit->identify()); 
-            nRpc += m_idHelperSvc->isRpc(hit->identify()); 
-            nTgc += m_idHelperSvc->isTgc(hit->identify()); 
-            nMm  += m_idHelperSvc->isMM(hit->identify());
-            nsTgc += m_idHelperSvc->issTgc(hit->identify());
-        }
-        m_out_gen_nRPCHits = nRpc; 
-        m_out_gen_nMDTHits = nMdt; 
-        m_out_gen_nTGCHits = nTgc;
-        m_out_gen_nMMits = nMm;
-        m_out_gen_nsTGCHits = nsTgc;
+        m_out_gen_nHits = segment->nPrecisionHits()+segment->nPhiLayers() + segment->nTrigEtaLayers(); 
+       
+        m_out_gen_nMDTHits = (segment->technology() == Muon::MuonStationIndex::MDT ? segment->nPrecisionHits() : 0); 
+        m_out_gen_nNswHits = (segment->technology() != Muon::MuonStationIndex::MDT ? segment->nPrecisionHits() : 0); 
+        m_out_gen_nTGCHits = (segment->chamberIndex() > Muon::MuonStationIndex::ChIndex::BEE ? segment->nPhiLayers() + segment->nTrigEtaLayers() : 0);
+        m_out_gen_nRPCHits = (segment->chamberIndex() <= Muon::MuonStationIndex::ChIndex::BEE ? segment->nPhiLayers() + segment->nTrigEtaLayers() : 0);
+
 
         m_out_gen_tantheta = (std::abs(chamberDir.z()) > 1.e-8 ? chamberDir.y()/chamberDir.z() : 1.e10); 
         m_out_gen_tanphi = (std::abs(chamberDir.z()) > 1.e-8 ? chamberDir.x()/chamberDir.z() : 1.e10); 
@@ -239,6 +249,11 @@ namespace MuonValR4 {
         
         const MuonR4::SegmentContainer* readMuonSegments{nullptr};
         ATH_CHECK(retrieveContainer(ctx, m_inSegmentKey, readMuonSegments));
+        
+        const xAOD::MuonSegmentContainer* readTruthSegments{nullptr};
+        ATH_CHECK(retrieveContainer(ctx, m_truthSegmentKey, readTruthSegments));
+        
+        SG::ReadDecorHandle<xAOD::MuonSegmentContainer, SimHitLinkVec> readSimHits{m_rh_truthSegmentSimHitLink, ctx}; 
 
         ATH_MSG_DEBUG("Succesfully retrieved input collections");
 
@@ -246,26 +261,18 @@ namespace MuonValR4 {
         // The fast digi should only generate one circle per tube. 
         std::map<const MuonGMR4::MuonChamber*, chamberLevelObjects> allObjectsPerChamber; 
 
-        for (const SG::ReadHandleKey<xAOD::MuonSimHitContainer>& key : m_inSimHitKeys){
-            const xAOD::MuonSimHitContainer* collection{nullptr};
-            ATH_CHECK(retrieveContainer(ctx, key, collection));
-            for (const xAOD::MuonSimHit* simHit : *collection) {
-                const MuonGMR4::MuonReadoutElement* reElement = m_r4DetMgr->getReadoutElement(simHit->identify()); 
-                const MuonGMR4::MuonChamber* id{reElement->getChamber()};
-                chamberLevelObjects & theObjects  = allObjectsPerChamber[id];
-                auto genLink = simHit->genParticleLink();
-                HepMC::ConstGenParticlePtr genParticle = nullptr; 
-                if (genLink.isValid()){
-                    genParticle = genLink.cptr(); 
-                }
-                /// skip empty truth matches for now
-                if (!genParticle) continue;
-                theObjects.truthMatching[genParticle].detectorHits.push_back(simHit); 
-            }
+        for (const xAOD::MuonSegment* truthSegment : *readTruthSegments){
+            const SimHitLinkVec & simHits = readSimHits(*truthSegment); 
+            const Identifier simHitId = (*simHits.front())->identify();
+            const MuonGMR4::MuonReadoutElement* reElement = m_r4DetMgr->getReadoutElement(simHitId); 
+            const MuonGMR4::MuonChamber* id{reElement->getChamber()};
+            chamberLevelObjects & theObjects  = allObjectsPerChamber[id];
+            theObjects.truthMatching[truthSegment].truthsegment = truthSegment; 
         }
 
         // Populate the seeds first
         for (const MuonR4::SegmentSeed* max : *readSegmentSeeds) {
+            // use adventurous minion syntax to add a key with a default value
             allObjectsPerChamber[max->chamber()].seedMatching[max];
         }
         if (readMuonSegments) {
@@ -277,18 +284,18 @@ namespace MuonValR4 {
         }
 
         for (auto & [chamber, chamberLevelObjects] : allObjectsPerChamber){
-            matchSeedsToTruth(chamberLevelObjects);            
+            matchSeedsToTruth(ctx, chamberLevelObjects);            
             /// Step 1: Fill the matched pairs 
-            for (auto & [genParticlePtr, assocInfo] : chamberLevelObjects.truthMatching) {                
+            for (auto & [truthSegment, assocInfo] : chamberLevelObjects.truthMatching) {                
                 if (assocInfo.assocSeeds.empty()) {
                     fillChamberInfo(chamber); 
-                    fillTruthInfo(genParticlePtr, assocInfo.detectorHits, gctx);
+                    fillTruthInfo(ctx, truthSegment, gctx);
                     if (!m_tree.fill(ctx)) return StatusCode::FAILURE;
                     continue;
                 }
                 for (const MuonR4::SegmentSeed* seed : assocInfo.assocSeeds) {
                     fillChamberInfo(chamber); 
-                    fillTruthInfo(genParticlePtr, assocInfo.detectorHits, gctx);
+                    fillTruthInfo(ctx, truthSegment, gctx);
                     auto& seedMatch = chamberLevelObjects.seedMatching[seed];
                     m_out_SP->push_back(*seed->parentBucket());
                     fillSeedInfo(seed, seedMatch.matchProb);
@@ -300,7 +307,7 @@ namespace MuonValR4 {
             }
             // also fill the reco not matched to any truth 
             for (auto & [ seed, assocInfo ] : chamberLevelObjects.seedMatching) {
-                if (assocInfo.truthParticle) continue;
+                if (assocInfo.truthsegment) continue;
                 fillChamberInfo(chamber);
                 m_out_SP->push_back(*seed->parentBucket());
                 fillSeedInfo(seed, 0.); 
diff --git a/MuonSpectrometer/MuonPhaseII/MuonValidation/MuonPatternRecognitionTest/src/MuonHoughTransformTester.h b/MuonSpectrometer/MuonPhaseII/MuonValidation/MuonPatternRecognitionTest/src/MuonHoughTransformTester.h
index 69109b96a1a3ad3cafa0a3f30f9df39ab4d9712b..103ff3490b1f13cf98fbeaa04306544f8ac9b326 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonValidation/MuonPatternRecognitionTest/src/MuonHoughTransformTester.h
+++ b/MuonSpectrometer/MuonPhaseII/MuonValidation/MuonPatternRecognitionTest/src/MuonHoughTransformTester.h
@@ -8,11 +8,13 @@
 // Framework includes
 #include "AthenaBaseComps/AthHistogramAlgorithm.h"
 #include "StoreGate/ReadHandleKey.h"
+#include "StoreGate/ReadDecorHandle.h"
 #include "StoreGate/ReadHandleKeyArray.h"
 #include "StoreGate/ReadCondHandleKey.h"
 
 // EDM includes 
 #include "xAODMuonSimHit/MuonSimHitContainer.h"
+#include "xAODMuon/MuonSegmentContainer.h"
 
 #include <MuonPatternEvent/MuonPatternContainer.h>
 
@@ -60,7 +62,7 @@ namespace MuonValR4{
     struct chamberLevelObjects { 
         struct SeedMatchQuantites {
             /** @brief Best matched truth particle */
-            HepMC::ConstGenParticlePtr truthParticle{};
+            const xAOD::MuonSegment* truthsegment{nullptr};
             /** @brief Probability of which the segment is matched to it */
             double matchProb{0.};
             /** @brief Associated segment */
@@ -71,25 +73,25 @@ namespace MuonValR4{
 
         /** @brief Collection of the truth particle trajectory */
         struct TruthMatchQuantities{
-            std::vector<const xAOD::MuonSimHit*> detectorHits{};
+            const xAOD::MuonSegment* truthsegment{nullptr};
             std::vector<const MuonR4::SegmentSeed*> assocSeeds{};
         };
 
-        std::map<HepMC::ConstGenParticlePtr, TruthMatchQuantities> truthMatching{}; 
+        std::map<const xAOD::MuonSegment*, TruthMatchQuantities> truthMatching{}; 
     };
 
-    void matchSeedToTruth(const MuonR4::SegmentSeed* seed, chamberLevelObjects & objs ) const;                          
-    std::pair<HepMC::ConstGenParticlePtr, double> matchSegmentToTruth(const MuonR4::Segment* seed, chamberLevelObjects & objs ) const;                          
-    void matchSeedsToTruth(chamberLevelObjects & objs) const;          
-    void matchSegmentsToTruth(chamberLevelObjects & objs) const;          
+    void matchSeedToTruth(const EventContext & ctx, const MuonR4::SegmentSeed* seed, chamberLevelObjects & objs ) const;                          
+    std::pair<const xAOD::MuonSegment*, double> matchSegmentToTruth(const MuonR4::Segment* seed, chamberLevelObjects & objs ) const;                          
+    void matchSeedsToTruth(const EventContext & ctx,chamberLevelObjects & objs) const;          
     void fillChamberInfo(const MuonGMR4::MuonChamber* chamber);                
-    void fillTruthInfo(const HepMC::ConstGenParticlePtr genParticlePtr, const std::vector<const xAOD::MuonSimHit*> & simHits, const ActsGeometryContext & gctx);     
+    void fillTruthInfo(const EventContext & ctx, const xAOD::MuonSegment* truthSegment,  const ActsGeometryContext & gctx);     
     void fillSeedInfo(const MuonR4::SegmentSeed* segmentSeed, double matchProb);            
     void fillSegmentInfo(const ActsGeometryContext& gctx,
                          const MuonR4::Segment* segment, double matchProb);            
     
     // MDT sim hits in xAOD format 
     SG::ReadHandleKeyArray<xAOD::MuonSimHitContainer> m_inSimHitKeys {this, "SimHitKeys",{}, "xAOD  SimHit collections"};
+    SG::ReadHandleKey<xAOD::MuonSegmentContainer> m_truthSegmentKey {this, "TruthSegmentKey","TruthSegmentsR4", "truth segment container"};
                                                           
     SG::ReadHandleKey<MuonR4::SegmentSeedContainer> m_inHoughSegmentSeedKey{this, "SegmentSeedKey", "MuonHoughStationSegmentSeeds"};
     SG::ReadHandleKey<MuonR4::SegmentContainer> m_inSegmentKey{this, "SegmentKey", "R4MuonSegments"};
@@ -97,6 +99,10 @@ namespace MuonValR4{
     
     SG::ReadHandleKey<ActsGeometryContext> m_geoCtxKey{this, "AlignmentKey", "ActsAlignment", "cond handle key"};
 
+    using SimHitLinkVec = std::vector<ElementLink<xAOD::MuonSimHitContainer>>; 
+
+    SG::ReadDecorHandleKey<xAOD::MuonSegmentContainer> m_rh_truthSegmentSimHitLink{this, "TruthSegmentSimHitLink", m_truthSegmentKey, "simHitLinks"};  
+
     ServiceHandle<Muon::IMuonIdHelperSvc> m_idHelperSvc{this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};
     const MuonGMR4::MuonDetectorManager* m_r4DetMgr{nullptr};
 
@@ -123,7 +129,7 @@ namespace MuonValR4{
     MuonVal::ScalarBranch<unsigned int>&   m_out_gen_nMDTHits{m_tree.newScalar<unsigned int>("genNMdtHits",0)};
     MuonVal::ScalarBranch<unsigned int>&   m_out_gen_nTGCHits{m_tree.newScalar<unsigned int>("genNTgcHits",0)};
     MuonVal::ScalarBranch<unsigned int>&   m_out_gen_nsTGCHits{m_tree.newScalar<unsigned int>("genNsTgcHits",0)};
-    MuonVal::ScalarBranch<unsigned int>&   m_out_gen_nMMits{m_tree.newScalar<unsigned int>("genNMmHits",0)};
+    MuonVal::ScalarBranch<unsigned int>&   m_out_gen_nNswHits{m_tree.newScalar<unsigned int>("genNNswHits",0)};
     MuonVal::ScalarBranch<bool>&  m_out_hasMax {m_tree.newScalar<bool>("hasMax", false)}; 
     MuonVal::ScalarBranch<bool>&  m_out_max_hasPhiExtension {m_tree.newScalar<bool>("maxHasPhiExtension", false)}; 
     MuonVal::ScalarBranch<float>&  m_out_max_matchFraction {m_tree.newScalar<float>("maxMatchFraction", false)};