diff --git a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtTubeLayer.h b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtTubeLayer.h
index b12665bd35159041b8652c75050c8393d3ae6ef9..d3b6f2948796cc5371c690fd053b3fc10f144e78 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtTubeLayer.h
+++ b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtTubeLayer.h
@@ -7,6 +7,7 @@
 #include <MuonReadoutGeometryR4/MuonDetectorDefs.h>
 #include <GeoModelKernel/GeoVPhysVol.h>
 #include <GeoModelKernel/GeoTransform.h>
+#include <GeoModelKernel/GeoVolumeCursor.h>
 #include <GeoModelUtilities/TransientConstSharedPtr.h>
 
 #include <set>
@@ -40,6 +41,8 @@ namespace MuonGMR4{
         unsigned int nTubes() const;
         ///@brief: Returns the transformation from the layer to the muon station
         const Amg::Transform3D& layerTransform() const;
+        ///@brief Return a cursor object over the tubes in the layer.
+        GeoVolumeCursor tubeCursor() const;
         ///@brief Returns the transformation of the tube to the muon station
         ///       Index counting [0 - nTubes()-1]
         const Amg::Transform3D tubeTransform(const unsigned int tube) const;
@@ -55,4 +58,4 @@ namespace MuonGMR4{
     };
 
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtReadoutElement.cxx b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtReadoutElement.cxx
index 9fa10513a9b83d9e20c0b6929155ba73c90ee068..a8d172e2f1ed89ab962be557b0a4ce950d2d11e8 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtReadoutElement.cxx
+++ b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtReadoutElement.cxx
@@ -70,7 +70,11 @@ StatusCode MdtReadoutElement::initElement() {
 #endif
     /// Cache the transformations to the tube layers
     std::optional<Amg::Vector3D> prevTubePos{std::nullopt};
-    for (unsigned int tube = 1; tube <= numTubesInLay(); ++ tube) {
+    MdtTubeLayer& layer = *m_pars.tubeLayers[lay-1];
+    GeoVolumeCursor tubeCursor = layer.tubeCursor();
+    GeoTrf::Transform3D layerTransform = layer.layerTransform();
+    for (unsigned int tube = 1; tube <= numTubesInLay(); ++ tube, tubeCursor.next()) {
+      assert (!tubeCursor.atEnd());
       const IdentifierHash idHash = measurementHash(lay,tube);
       if (m_pars.removedTubes.count(idHash)) {
          prevTubePos = std::nullopt;
@@ -81,15 +85,16 @@ StatusCode MdtReadoutElement::initElement() {
       ATH_CHECK(strawSurfaceFactory(idHash, m_pars.tubeBounds->make_bounds(innerTubeRadius(), 0.5*tubeLength(idHash))));
 #endif
       ///Ensure that all linear transformations are rotations
-      const AmgSymMatrix(3) tubeRot = toTubeFrame(idHash).linear();
+      GeoTrf::Transform3D tubeFrame = layerTransform*tubeCursor.getDefTransform();
+      const AmgSymMatrix(3) tubeRot = tubeFrame.linear();
       if (std::abs(tubeRot.determinant()- 1.) > std::numeric_limits<float>::epsilon()){
          ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<" Transformation matrix is not a pure rotation for "<<
                        idHelperSvc()->toStringDetEl(identify())<<" in layer: "<<lay<<", tube: "<<tube
-                       <<Amg::toString(toTubeFrame(idHash)));
+                       <<Amg::toString(tubeFrame));
          return StatusCode::FAILURE;
       }
       /// Ensure that all tubes have the same pitch
-      const Amg::Vector3D tubePos = toTubeFrame(idHash).translation();
+      const Amg::Vector3D tubePos = tubeFrame.translation();
       
       constexpr double pitchTolerance = 20. * Gaudi::Units::micrometer;
       if (prevTubePos) {
@@ -112,6 +117,8 @@ StatusCode MdtReadoutElement::initElement() {
                           <<dR<<" tube position: "<<Amg::toString(tubePos,2)
                           <<" previous:"<<Amg::toString((*prevLayPos), 2));
          }
+      }
+      if (tube == 1) {
          prevLayPos = std::make_optional<Amg::Vector3D>(tubePos);
       }
       prevTubePos = std::make_optional<Amg::Vector3D>(tubePos);
diff --git a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtTubeLayer.cxx b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtTubeLayer.cxx
index 1b7f205314dbf7189d8b052a2e456f9d4b27ae36..a0daaef44f2d78bfa2c4919668ddfe6c04d0630e 100644
--- a/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtTubeLayer.cxx
+++ b/MuonSpectrometer/MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtTubeLayer.cxx
@@ -56,6 +56,9 @@ const Amg::Transform3D MdtTubeLayer::tubeTransform(const unsigned int tube) cons
     m_layerNode->exec(&volAcc);
     return layerTransform() * volAcc.getDefTransform();
 }
+GeoVolumeCursor MdtTubeLayer::tubeCursor() const {
+  return GeoVolumeCursor(m_layerNode);
+}
 const Amg::Vector3D MdtTubeLayer::tubePosInLayer(const unsigned int tube) const {
     return  layerTransform().inverse() * tubeTransform(tube).translation();
 }