diff --git a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/MuonGeoUtilitiyTool.cxx b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/MuonGeoUtilitiyTool.cxx
index 73a4cc5ccdd1f1e1b3b9cc325dfaca2f5032d041..794623caa937563414a6d0224b2d0f01151c3f16 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/MuonGeoUtilitiyTool.cxx
+++ b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/MuonGeoUtilitiyTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
 */
 #include "MuonGeoUtilityTool.h"
 
@@ -20,8 +20,10 @@
 #include <GeoModelKernel/GeoVolumeCursor.h>
 
 #include <GeoModelHelpers/GeoShapeUtils.h>
+#include <GeoModelHelpers/printVolume.h>
 #include <GeoModelHelpers/TransformToStringConverter.h>
 
+
 #include <set>
 #include <sstream>
 #include <string>
@@ -31,9 +33,6 @@ using namespace ActsTrk;
 namespace MuonGMR4{
 
 MuonGeoUtilityTool::~MuonGeoUtilityTool() = default;
-MuonGeoUtilityTool::MuonGeoUtilityTool(const std::string &type, const std::string &name,
-                                       const IInterface *parent):
-    base_class(type,name,parent) {}
 
 const GeoShape* MuonGeoUtilityTool::extractShape(const PVConstLink& physVol) const {
     const GeoLogVol* logVol = physVol->getLogVol();
@@ -88,48 +87,7 @@ Amg::Transform3D MuonGeoUtilityTool::extractShifts(const GeoShape* inShape) cons
     return sumTrans;
 }
 std::string MuonGeoUtilityTool::dumpShape(const GeoShape* shape) const { return printGeoShape(shape); }
-std::string MuonGeoUtilityTool::dumpVolume(const PVConstLink& physVol) const {
-   return dumpVolume(physVol, "");
-}
-std::string MuonGeoUtilityTool::dumpVolume(const PVConstLink& physVol, const std::string& childDelim) const { 
-  std::stringstream sstr{};
-  if (!physVol || !physVol->getLogVol()){
-    ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" "<<__func__<<" No logical volume attached ");
-    return sstr.str();        
-  }
-  const GeoShape* shape = extractShape(physVol);
-  if (!shape) {
-      ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" "<<__func__
-                      <<" Failed to extract shape from phys volume "
-                      << physVol->getLogVol()->getName());
-      return sstr.str();
-  }
-  sstr<<"logical volume "<<physVol->getLogVol()->getName()<<", ";
-  if (physVol->isShared() || !physVol->getParent()){
-    sstr<<"shared volume, ";
-  } else {
-    const GeoVPhysVol* pv = physVol;
-    if (typeid(*pv) == typeid(GeoFullPhysVol)){
-      const Amg::Transform3D absTrans = static_cast<const GeoFullPhysVol&>(*physVol).getAbsoluteTransform();
-      sstr<<"absolute pos: "<<GeoTrf::toString(absTrans,true) << ", ";
-    } else{
-        sstr<<"relative pos: "<<GeoTrf::toString(physVol->getX(), true)<<", ";  
-    }
-  }
-  sstr<<dumpShape(shape)<<", ";
-  const Amg::Transform3D shift = extractShifts(physVol);
-  if (!Amg::isIdentity(shift)) {
-    sstr<<" shape shifted by "<<GeoTrf::toString(shift, true);
-  } 
-  sstr<<"number of children "<<physVol->getNChildVols()<<", "<<std::endl;
-  std::vector<GeoChildNodeWithTrf> children = getChildrenWithRef(physVol, false);
-  for (unsigned int child = 0; child < children.size(); ++child) {
-    sstr<<childDelim<<(child+1)<<": "<<GeoTrf::toString(children[child].transform, true)
-        <<", "<< dumpVolume(children[child].volume, childDelim + "    ");
-  }
-  return sstr.str();
-}
-
+std::string MuonGeoUtilityTool::dumpVolume(const PVConstLink& physVol) const { return printVolume(physVol); }
 const GeoAlignableTransform* MuonGeoUtilityTool::findAlignableTransform(const PVConstLink& physVol) const {
     PVConstLink parent{physVol->getParent()}, child{physVol};
     while (parent) {
@@ -148,26 +106,9 @@ const GeoAlignableTransform* MuonGeoUtilityTool::findAlignableTransform(const PV
 }
 
 std::vector<MuonGeoUtilityTool::physVolWithTrans> MuonGeoUtilityTool::findAllLeafNodesByName(const PVConstLink& physVol, const std::string& volumeName) const {
-  const std::vector<physVolWithTrans> children = getChildrenWithRef(physVol, false);
-  std::vector<physVolWithTrans> foundVols{};
-  for (const physVolWithTrans& child : children) {    
-    /// The logical volume has precisely the name for what we're searching for
-    if (child.volume->getLogVol()->getName() == volumeName || child.nodeName == volumeName) {
-        foundVols.push_back(child);
-    }
-    /// There are no grand children of this volume. We're at a leaf node
-    if (!child.volume->getNChildVols()) {
-      continue;
-    }    
-    std::vector<physVolWithTrans> grandChildren = findAllLeafNodesByName(child.volume, volumeName);
-    std::transform(std::make_move_iterator(grandChildren.begin()),
-                   std::make_move_iterator(grandChildren.end()), std::back_inserter(foundVols),
-                   [&child](physVolWithTrans&& vol){
-                      vol.transform = child.transform * vol.transform;
-                      return vol;
-                  });
-  }
-  return foundVols;
+  return getAllSubVolumes(physVol,[&volumeName](const physVolWithTrans& child){
+                                                 return child.volume->getLogVol()->getName() == volumeName || child.nodeName == volumeName;
+                                  });
 }
 std::vector<const GeoShape*> MuonGeoUtilityTool::getComponents(const GeoShape* booleanShape) const {
    return getBooleanComponents(booleanShape);
diff --git a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/MuonGeoUtilityTool.h b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/MuonGeoUtilityTool.h
index 786e0b81f0406f6ab63669899521d991057c9c4b..44f987e306af060bd463995a054c9041bb851a93 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/MuonGeoUtilityTool.h
+++ b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/MuonGeoUtilityTool.h
@@ -19,8 +19,7 @@ class MuonGeoUtilityTool final :  public extends<AthAlgTool, IMuonGeoUtilityTool
 
    public:
     // Constructor
-    MuonGeoUtilityTool(const std::string &type, const std::string &name,
-                     const IInterface *parent);
+    using base_class::base_class;
 
     // Destructor
     virtual ~MuonGeoUtilityTool() override final;
@@ -51,7 +50,6 @@ class MuonGeoUtilityTool final :  public extends<AthAlgTool, IMuonGeoUtilityTool
                                           const Amg::Transform3D& refTrf) const override;
 
    private:
-    std::string dumpVolume(const PVConstLink& physVol, const std::string& childDelim) const;
 
 };
 }  // namespace MuonGMR4
diff --git a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/RpcReadoutGeomTool.cxx b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/RpcReadoutGeomTool.cxx
index bfd1f5e24eba5e9526dbf35b545a36d775927af1..edee52ea903ab0f59829f724df71e4c7d2faa6cb 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/RpcReadoutGeomTool.cxx
+++ b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/RpcReadoutGeomTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "RpcReadoutGeomTool.h"
@@ -38,11 +38,11 @@ using defineArgs = RpcReadoutElement::defineArgs;
 
 /// Helper struct to attribute the Identifier fields with the
 /// gas gap volumes
-struct gapVolume: public physVolWithTrans {
-    gapVolume(physVolWithTrans&& physVol,
+struct gapVolume: public GeoChildNodeWithTrf {
+    gapVolume(GeoChildNodeWithTrf&& physVol,
               unsigned int gap,
               unsigned int phi):
-        physVolWithTrans{std::move(physVol)},
+              GeoChildNodeWithTrf{std::move(physVol)},
         gasGap{gap},
         doubPhi{phi} {}
     unsigned int gasGap{0};
@@ -50,18 +50,7 @@ struct gapVolume: public physVolWithTrans {
     
 };
 
-inline bool layerSorter(const physVolWithTrans&a, const physVolWithTrans & b){
-    const Amg::Vector3D cA = a.transform.translation();
-    const Amg::Vector3D cB = b.transform.translation();
-    if (std::abs(cA.x() - cB.x()) > tolerance) return (cA.x() < cB.x());
-    return (cA.y() < cB.y());
-}
-
 
-RpcReadoutGeomTool::RpcReadoutGeomTool(const std::string& type,
-                                       const std::string& name,
-                                       const IInterface* parent)
-    : base_class{type, name, parent} {}
 
 StatusCode RpcReadoutGeomTool::loadDimensions(RpcReadoutElement::defineArgs& define,
                                               FactoryCache& factoryCache) {    
@@ -95,62 +84,55 @@ StatusCode RpcReadoutGeomTool::loadDimensions(RpcReadoutElement::defineArgs& def
      *          | Strip layer  |  Strip layer |    |  Strip layer  |  Strip layer |
      *   
     */
-    std::vector<physVolWithTrans> stripLayers = m_geoUtilTool->findAllLeafNodesByName(define.physVol, "bottomStripLayer");
-    if (stripLayers.empty()) {
-        ATH_MSG_FATAL("The volume "<<m_idHelperSvc->toStringDetEl(define.detElId)<<" does not have any childern 'bottomStripLayer'"
-            <<std::endl<<m_geoUtilTool->dumpVolume(define.physVol));
-        return StatusCode::FAILURE;
-    }   
-    std::vector<physVolWithTrans> allGasGaps = m_geoUtilTool->findAllLeafNodesByName(define.physVol, "RpcGasGap");
-    if (allGasGaps.empty()) {
-        ATH_MSG_FATAL("The volume "<<m_idHelperSvc->toStringDetEl(define.detElId)<<" does not have any childern 'RpcGasGap'"
+    std::vector<GeoChildNodeWithTrf> rpcLayers = getChildrenWithRef(define.physVol, false);
+    /// Fetch all volumes with Identifiers from the tree
+    rpcLayers.erase(std::remove_if(rpcLayers.begin(), rpcLayers.end(),
+                     [](const GeoChildNodeWithTrf& subVol){ return !subVol.volumeId; }), rpcLayers.end());
+    /// Next sort them by Identifier
+    std::ranges::sort(rpcLayers, [](const GeoChildNodeWithTrf& a, const GeoChildNodeWithTrf& b){ 
+                                  return a.volumeId.value_or(0) < b.volumeId.value_or(0);});
+    
+    if (rpcLayers.empty()) {
+        ATH_MSG_FATAL("The volume "<<m_idHelperSvc->toStringDetEl(define.detElId)<<" does not have any childern with Identifiers "
             <<std::endl<<m_geoUtilTool->dumpVolume(define.physVol));
         return StatusCode::FAILURE;
     }
-    /// In the GeoModel world, the x-axis points in radial direction & y axis along the phi direction
-    std::stable_sort(allGasGaps.begin(), allGasGaps.end(), layerSorter);
-    std::stable_sort(stripLayers.begin(),stripLayers.end(), layerSorter);
-    /// The strip layers are used to express the dimensions of the strip layer. However, that's projected into the 
-    /// Center of the gasgap which may or maybe not be split into two --> Find the closest gas gap in x for each
-    /// strip layer and overwrite the x coordinate of the strip layerof that one.
-    for (physVolWithTrans& stripLayer : stripLayers){
-        /// Find the closest gas Gap
-        const Amg::Vector3D stripTrans = stripLayer.transform.translation();
-        std::vector<physVolWithTrans>::iterator closestGap =  std::min_element(allGasGaps.begin(), allGasGaps.end(), 
-                             [&stripTrans](const physVolWithTrans& a, const physVolWithTrans& b){
-                                return std::abs(stripTrans.x() - a.transform.translation().x()) <
-                                       std::abs(stripTrans.x() - b.transform.translation().x());                                
-                             });
-        stripLayer.transform.translation().x() = closestGap->transform.translation().x();
-    }
+    /// Fetch for each rpc layer the gasGaps
+    unsigned int gasGap{0};
+    const unsigned int modulePhi = m_idHelperSvc->rpcIdHelper().doubletPhi(define.detElId);
 
-    /// Now we need to associate the gasGap volumes with the gas gap number &
-    /// the doublet Phi
-    Amg::Vector3D prevGap{stripLayers[0].transform.translation()};
-    unsigned int gasGap{1}, doubletPhi{0};
-    
-    unsigned int modulePhi = m_idHelperSvc->rpcIdHelper().doubletPhi(define.detElId);
     std::vector<gapVolume> allGapsWithIdx{};
-    const bool isAside{m_idHelperSvc->stationEta(define.detElId) > 0};
-    for (physVolWithTrans& gapVol : stripLayers) {
-        Amg::Vector3D gCen = gapVol.transform.translation();
-        /// The volume points to a new gasgap
-        if (std::abs(gCen.x() - prevGap.x()) > tolerance) {
-            ++gasGap;
-            doubletPhi = 1;
-        } else ++doubletPhi;
-        ATH_MSG_DEBUG("Gas gap at "<<Amg::toString(gCen, 2)<<" is associated with gasGap: "<<gasGap<<", doubletPhi: "<<doubletPhi);
-        prevGap = std::move(gCen);
-        /// Rpc volumes with doubletZ = 3 have two gas gaps along phi but they're split into two
-        /// distnict modules with doublePhi = 1, 2. 
-        doubletPhi = std::max (doubletPhi, modulePhi);
-        allGapsWithIdx.emplace_back(std::move(gapVol), gasGap, doubletPhi);
+    for (const GeoChildNodeWithTrf& rpcSinglet : rpcLayers) {
+        auto fetchNodes = [this, &rpcSinglet] (const std::string& leafName) {
+            std::vector<GeoChildNodeWithTrf> nodes = m_geoUtilTool->findAllLeafNodesByName(rpcSinglet.volume, leafName);
+            std::ranges::for_each(nodes,[&rpcSinglet](GeoChildNodeWithTrf& node){ node.transform = rpcSinglet.transform * node.transform; });
+            return nodes;
+        };
+        std::vector<GeoChildNodeWithTrf> gasGaps = fetchNodes("RpcGasGap");
+        if (gasGaps.empty()) {
+            ATH_MSG_FATAL("The child "<<m_geoUtilTool->dumpVolume(rpcSinglet.volume)<<" has "<<gasGaps.size()<<" gasGaps. ");
+            return StatusCode::FAILURE;
+        }
+        std::vector<GeoChildNodeWithTrf> stripLayers = fetchNodes("bottomStripLayer");
+        if (stripLayers.empty()) {
+            ATH_MSG_FATAL("The child "<<m_geoUtilTool->dumpVolume(rpcSinglet.volume)<<" does not have a strip layer ");
+            return StatusCode::FAILURE;
+        }
+        ++gasGap;
+        for (GeoChildNodeWithTrf& stripPanel : stripLayers) {
+            /// Adjust the height of the strip panel to be in the centre of the gasGap
+            stripPanel.transform.translation().x() = gasGaps.front().transform.translation().x();
+            const int doubPhi = std::max(modulePhi, 1u*stripPanel.volumeId.value_or(999));
+            allGapsWithIdx.emplace_back(std::move(stripPanel), gasGap, doubPhi);
+        }
     }
+   
+    const bool isAside{m_idHelperSvc->stationEta(define.detElId) > 0};
     /// We know now whether we had 2 or 3 gasgaps and also whether there 2 or 1 panels in phi
     define.nGasGaps = gasGap;
     /// Special case for the BML4 DBZ = 3 chambers. The doubletPhi is incorporated 
     /// into the detector element but there's only one strip panel
-    define.nPanelsInPhi = modulePhi == 2 ? 1 : doubletPhi;    
+    define.nPanelsInPhi = modulePhi == 2 ? 1 : allGapsWithIdx.size () / gasGap;    
     FactoryCache::ParamBookTable::const_iterator parBookItr = factoryCache.parameterBook.find(define.chambDesign);
     if (parBookItr == factoryCache.parameterBook.end()) {
         ATH_MSG_FATAL("The chamber "<<define.chambDesign<<" is not part of the WRPC table");
diff --git a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/RpcReadoutGeomTool.h b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/RpcReadoutGeomTool.h
index a3a110131c0c5c21d6211a7d95c81a7dd5438942..1e54c0f4b1d581e517a0c53b9490aa4fbbc2524d 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/RpcReadoutGeomTool.h
+++ b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelR4/src/RpcReadoutGeomTool.h
@@ -19,8 +19,7 @@ namespace MuonGMR4 {
 class RpcReadoutGeomTool : public extends<AthAlgTool,IMuonReadoutGeomTool> {
    public:
     // Constructor
-    RpcReadoutGeomTool(const std::string &type, const std::string &name,
-                       const IInterface *parent);
+    using base_class::base_class;
 
     StatusCode buildReadOutElements(MuonDetectorManager &mgr) override final;
 
diff --git a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/python/testGeoModel.py b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/python/testGeoModel.py
index cb6b6aba13ef77076dd8e40390366af94e02122a..e3e4e024b4834ccbf2e7e4f151c4b27372c40533 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/python/testGeoModel.py
+++ b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/python/testGeoModel.py
@@ -6,7 +6,7 @@ def geoModelFileDefault(useR4Layout = False):
     # If this is changed, remember to also test with other dependent tests 
     # e.g. run ctest with ActsEventCnv
     if useR4Layout: 
-        return  "/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/MuonRecRTT/ATLAS-R4-MUONTEST.db"
+        return  "/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/MuonGeomRTT/GeoDB/ATLAS-P2-RUN4-01-00-00.db"
     return "/cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/MuonGeomRTT/GeoDB/ATLAS-R3S-2021-03-02-00.db"
 
 def SetupArgParser():
diff --git a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/util/runRpcGeoComparison.cxx b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/util/runRpcGeoComparison.cxx
index 483bfd69fab8c1c4f31f522f542eb33cf3ffe36c..99d77f351f1e1e2c41e4eaefdf8526f40c2c24e1 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/util/runRpcGeoComparison.cxx
+++ b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/util/runRpcGeoComparison.cxx
@@ -434,8 +434,8 @@ int main( int argc, char** argv ) {
             const Amg::Vector3D diffStrip{testStrip.position - refStrip.position};
             if (diffStrip.mag() > tolerance) {
                 constexpr unsigned int maxFail = 3;
-                if ( (!refStrip.measPhi && (++failedEta) <= maxFail) ||
-                      (refStrip.measPhi && (++failedPhi) <= maxFail) ) {
+                if ( (!refStrip.measPhi && ( (++failedEta) <= maxFail || refStrip.strip <= 3)) ||
+                      (refStrip.measPhi && ( (++failedPhi) <= maxFail || refStrip.strip <= 3)) ) {
                     std::cerr<<"runRpcGeoComparison() "<<__LINE__<<": "<<test<<" "
                              <<testStrip<<" should be located at "<<Amg::toString(refStrip.position, 2)
                              <<" displacement: "<<Amg::toString(diffStrip,2)<<", perp: "