diff --git a/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignablePlaneSurface.cxx b/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignablePlaneSurface.cxx
index 749984da7c0fa21ee729b8670bf2cb8dc668e05e..6082ab6a6e0e356022b2ddc8596456bf5f90b7e2 100644
--- a/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignablePlaneSurface.cxx
+++ b/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignablePlaneSurface.cxx
@@ -22,18 +22,10 @@ Trk::AlignablePlaneSurface::AlignablePlaneSurface(const Trk::PlaneSurface& psf,
   , m_nominalSurface(&psf)
 {
   if (htrans) {
-    Surface::m_transform = std::unique_ptr<Amg::Transform3D>(htrans);
-    Trk::Surface::m_center =
-      std::make_unique<Amg::Vector3D>(Trk::Surface::m_transform->translation());
-    Trk::Surface::m_normal = std::make_unique<Amg::Vector3D>(
-      Trk::Surface::m_transform->rotation().col(2));
+    Trk::Surface::m_transforms = std::make_unique<Transforms>(*htrans);
   } else {
-    Surface::m_transform =
-      std::make_unique<Amg::Transform3D>(m_nominalSurface->transform());
-    Trk::Surface::m_center =
-      std::make_unique<Amg::Vector3D>(Trk::Surface::m_transform->translation());
-    Trk::Surface::m_normal = std::make_unique<Amg::Vector3D>(
-      Trk::Surface::m_transform->rotation().col(2));
+    Trk::Surface::m_transforms =
+      std::make_unique<Transforms>(m_nominalSurface->transform());
   }
 }
 
@@ -71,23 +63,19 @@ Trk::AlignablePlaneSurface::operator==(const Trk::Surface& sf) const
 void
 Trk::AlignablePlaneSurface::addAlignmentCorrection(Amg::Transform3D& corr)
 {
-  Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>((*Trk::Surface::m_transform) * corr);
-  Trk::Surface::m_center = std::make_unique<Amg::Vector3D>(Trk::Surface::m_transform->translation());
-  Trk::Surface::m_normal = std::make_unique<Amg::Vector3D>(Trk::Surface::m_transform->rotation().col(2));
+  Trk::Surface::m_transforms =
+    std::make_unique<Transforms>(Trk::Surface::m_transforms->transform * corr);
 }
 
 void
 Trk::AlignablePlaneSurface::setAlignmentCorrection(Amg::Transform3D& corr)
 {
-  Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>((m_nominalSurface->transform()) * corr);
-  Trk::Surface::m_center = std::make_unique<Amg::Vector3D>(Trk::Surface::m_transform->translation());
-  Trk::Surface::m_normal = std::make_unique<Amg::Vector3D>(Trk::Surface::m_transform->rotation().col(2));
+  Trk::Surface::m_transforms =
+    std::make_unique<Transforms>(m_nominalSurface->transform() * corr);
 }
 
 void
 Trk::AlignablePlaneSurface::setAlignableTransform(Amg::Transform3D& trans)
 {
-  Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>(trans);
-  Trk::Surface::m_center = std::make_unique<Amg::Vector3D>(Trk::Surface::m_transform->translation());
-  Trk::Surface::m_normal = std::make_unique<Amg::Vector3D>(Trk::Surface::m_transform->rotation().col(2));
+  Trk::Surface::m_transforms = std::make_unique<Transforms>(trans);
 }
diff --git a/Tracking/TrkDetDescr/TrkGeometry/src/ConeLayer.cxx b/Tracking/TrkDetDescr/TrkGeometry/src/ConeLayer.cxx
index a9d5d9c9b0f3db68fa47c18fc41987aee0749ca7..bfd195bcb2c5919de73bb37f857db0524e164a00 100644
--- a/Tracking/TrkDetDescr/TrkGeometry/src/ConeLayer.cxx
+++ b/Tracking/TrkDetDescr/TrkGeometry/src/ConeLayer.cxx
@@ -107,8 +107,5 @@ double Trk::ConeLayer::postUpdateMaterialFactor(const Trk::TrackParameters& parm
 }
 
 void Trk::ConeLayer::moveLayer(Amg::Transform3D& shift)  {
-  Amg::Transform3D transf = shift * (*m_transform);
-  Trk::ConeSurface::m_transform=std::make_unique<Amg::Transform3D>(transf) ;
-  Trk::ConeSurface::m_center=std::make_unique<Amg::Vector3D>(m_transform->translation());
-  Trk::ConeSurface::m_normal=std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+  Trk::ConeSurface::m_transforms = std::make_unique<Transforms>(shift * m_transforms->transform);
 }
diff --git a/Tracking/TrkDetDescr/TrkGeometry/src/CylinderLayer.cxx b/Tracking/TrkDetDescr/TrkGeometry/src/CylinderLayer.cxx
index 0c32376771a5b431f400bf45e8328975f298d603..a41d61cd3a142b0540576f0acd0ea90a73dc4239 100755
--- a/Tracking/TrkDetDescr/TrkGeometry/src/CylinderLayer.cxx
+++ b/Tracking/TrkDetDescr/TrkGeometry/src/CylinderLayer.cxx
@@ -188,11 +188,7 @@ double Trk::CylinderLayer::postUpdateMaterialFactor(const Trk::TrackParameters&
 
 
 void Trk::CylinderLayer::moveLayer(Amg::Transform3D& shift) {
-       Amg::Transform3D transf = shift * (*m_transform);
-       Trk::CylinderSurface::m_transform= std::make_unique<Amg::Transform3D>(transf);
-       m_center = std::make_unique<Amg::Vector3D>(m_transform->translation());
-       m_normal =
-         std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+       Trk::CylinderSurface::m_transforms = std::make_unique<Transforms>(shift * (m_transforms->transform));
 
        if (m_approachDescriptor &&  m_approachDescriptor->rebuild()){
            // build the new approach descriptor - deletes the current one
@@ -286,7 +282,8 @@ void Trk::CylinderLayer::buildApproachDescriptor(){
     // delete the surfaces
     auto  aSurfaces = std::make_unique<Trk::ApproachSurfaces>();
     // create new surfaces
-    Amg::Transform3D* asTransform = m_transform ? new Amg::Transform3D(*m_transform) : nullptr;
+    Amg::Transform3D* asTransform =
+      m_transforms ? new Amg::Transform3D(m_transforms->transform) : nullptr;
     // create the new surfaces
     aSurfaces->push_back(new Trk::CylinderSurface(asTransform, m_bounds->r()-0.5*thickness(), m_bounds->halflengthZ() ));
     aSurfaces->push_back(new Trk::CylinderSurface(asTransform, m_bounds->r()+0.5*thickness(), m_bounds->halflengthZ() ));
@@ -303,15 +300,12 @@ void Trk::CylinderLayer::resizeAndRepositionLayer(const VolumeBounds& vBounds, c
     // resize first of all
     resizeLayer(vBounds,envelope);
     // now reposition to the potentially center if necessary, do not change layers with no transform
-    if ( Trk::CylinderSurface::m_transform || center().isApprox(vCenter) ) {
+    if ( Trk::CylinderSurface::m_transforms || center().isApprox(vCenter) ) {
       return;
     }
-
-    Trk::CylinderSurface::m_transform=std::make_unique<Amg::Transform3D>(vCenter);
-    // delete derived and the cache
-    Trk::CylinderSurface::m_center = std::make_unique<Amg::Vector3D>(vCenter);
-    Trk::CylinderSurface::m_normal =
-      std::make_unique<Amg::Vector3D>(Trk::CylinderSurface::m_transform->rotation().col(2));
+    Amg::Transform3D transf(vCenter);
+    Trk::CylinderSurface::m_transforms =
+      std::make_unique<Transforms>(Amg::Transform3D(vCenter), vCenter);
     // rebuild approaching layers if needed
     if (m_approachDescriptor &&  m_approachDescriptor->rebuild())
         buildApproachDescriptor();
diff --git a/Tracking/TrkDetDescr/TrkGeometry/src/DiscLayer.cxx b/Tracking/TrkDetDescr/TrkGeometry/src/DiscLayer.cxx
index 84dc2b9564d9d07dd2f9f3b37c511de1c34e4dac..d1492ce1712016bb037b506143efaa82126b8cbc 100755
--- a/Tracking/TrkDetDescr/TrkGeometry/src/DiscLayer.cxx
+++ b/Tracking/TrkDetDescr/TrkGeometry/src/DiscLayer.cxx
@@ -140,14 +140,13 @@ double Trk::DiscLayer::postUpdateMaterialFactor(const Trk::TrackParameters& parm
 
 void Trk::DiscLayer::moveLayer(Amg::Transform3D& shift)  {
 
-       Amg::Transform3D transf = shift * (*m_transform);
-       m_transform=std::make_unique<Amg::Transform3D>(transf);
-       m_center=std::make_unique<Amg::Vector3D>(m_transform->translation());
-       m_normal=std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
-       // rebuild that - deletes the current one
-       if (m_approachDescriptor &&  m_approachDescriptor->rebuild()) {
-         buildApproachDescriptor();
-       }
+  Amg::Transform3D transf = shift * m_transforms->transform;
+  m_transforms = std::make_unique<Transforms>(
+    transf, transf.translation(), transf.rotation().col(2));
+  // rebuild that - deletes the current one
+  if (m_approachDescriptor && m_approachDescriptor->rebuild()) {
+    buildApproachDescriptor();
+  }
 }
 
 void Trk::DiscLayer::resizeLayer(const VolumeBounds& bounds, double envelope)  {
@@ -268,10 +267,9 @@ void Trk::DiscLayer::resizeAndRepositionLayer(const VolumeBounds& vBounds, const
                                                          Amg::Vector3D( vCenter + Amg::Vector3D(0.,0.,hLengthZ-0.5*thickness()) );
         if (center().isApprox(nDiscCenter)) return;
         // else set to the new volume center
-        Trk::DiscSurface::m_transform=std::make_unique<Amg::Transform3D> (Amg::Translation3D(nDiscCenter));
-        // delete derived and the cache
-        Trk::DiscSurface::m_center= std::make_unique<Amg::Vector3D>(nDiscCenter);
-        Trk::DiscSurface::m_normal= std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+        Amg::Transform3D transf((Amg::Translation3D(nDiscCenter)));
+        Amg::Vector3D center(nDiscCenter);
+        m_transforms = std::make_unique<Transforms>(transf, center);
     }
     // rebuild the approaching layer
     if (m_approachDescriptor &&  m_approachDescriptor->rebuild())
diff --git a/Tracking/TrkDetDescr/TrkGeometry/src/PlaneLayer.cxx b/Tracking/TrkDetDescr/TrkGeometry/src/PlaneLayer.cxx
index 418900c33538722c9f547dd56592fc29419ab4f9..a62f3c14e39c59b339309847af495091e014f0a0 100755
--- a/Tracking/TrkDetDescr/TrkGeometry/src/PlaneLayer.cxx
+++ b/Tracking/TrkDetDescr/TrkGeometry/src/PlaneLayer.cxx
@@ -182,10 +182,6 @@ double Trk::PlaneLayer::postUpdateMaterialFactor(const Trk::TrackParameters& par
 }
 
 void Trk::PlaneLayer::moveLayer(Amg::Transform3D& shift)  {
-       Amg::Transform3D transf = shift * (*m_transform);
-       m_transform = std::make_unique<Amg::Transform3D>(transf);
-       m_center = std::make_unique<Amg::Vector3D>(m_transform->translation());
-       m_normal =
-         std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+  m_transforms = std::make_unique<Transforms>(shift * (m_transforms->transform));
 }
 
diff --git a/Tracking/TrkDetDescr/TrkGeometry/src/SubtractedCylinderLayer.cxx b/Tracking/TrkDetDescr/TrkGeometry/src/SubtractedCylinderLayer.cxx
index 1007f8b8d2de8f4396ec46cc41218c56f478b4a0..252d21cd333b2edb176f7847d646bb1d3cb87fca 100755
--- a/Tracking/TrkDetDescr/TrkGeometry/src/SubtractedCylinderLayer.cxx
+++ b/Tracking/TrkDetDescr/TrkGeometry/src/SubtractedCylinderLayer.cxx
@@ -71,13 +71,9 @@ double Trk::SubtractedCylinderLayer::postUpdateMaterialFactor(const Trk::TrackPa
     Amg::Vector3D pastStep(parmPos + dir*parm.momentum().normalized());
     if (pastStep.perp() > parm.position().perp())
       return Trk::Layer::m_layerMaterialProperties->alongPostFactor();
-    return   Trk::Layer::m_layerMaterialProperties->oppositePostFactor();
+    return   Trk::Layer::m_layerMaterialProperties->oppositePostFactor();
 }
 
 void Trk::SubtractedCylinderLayer::moveLayer(Amg::Transform3D& shift)  {
-      Amg::Transform3D transf = shift * (*m_transform);
-      m_transform = std::make_unique<Amg::Transform3D>(transf);
-      m_center = std::make_unique<Amg::Vector3D>(m_transform->translation());
-      m_normal =
-        std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+      m_transforms = std::make_unique<Transforms>(shift * (m_transforms->transform));
 }
diff --git a/Tracking/TrkDetDescr/TrkGeometry/src/SubtractedPlaneLayer.cxx b/Tracking/TrkDetDescr/TrkGeometry/src/SubtractedPlaneLayer.cxx
index 91759e7652bcd4aea0923be50088fa82143a3383..85d2943408921d5119b3968137079f0d684ca7a1 100755
--- a/Tracking/TrkDetDescr/TrkGeometry/src/SubtractedPlaneLayer.cxx
+++ b/Tracking/TrkDetDescr/TrkGeometry/src/SubtractedPlaneLayer.cxx
@@ -68,9 +68,5 @@ double Trk::SubtractedPlaneLayer::postUpdateMaterialFactor(const Trk::TrackParam
 }
 
 void Trk::SubtractedPlaneLayer::moveLayer(Amg::Transform3D& shift)  {
-      Amg::Transform3D transf = shift * (*m_transform);
-      m_transform = std::make_unique<Amg::Transform3D>(transf);
-      m_center = std::make_unique<Amg::Vector3D>(m_transform->translation());
-      m_normal =
-        std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+      m_transforms = std::make_unique<Transforms>(shift * (m_transforms->transform));
 }
diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingCylinderSurface.cxx b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingCylinderSurface.cxx
index 5928e503af788fcd9045a2440871e8a60b1116f3..30cefd4822826fcf6ec0a1bd5806e1a1a97548c9 100644
--- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingCylinderSurface.cxx
+++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingCylinderSurface.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -128,7 +128,7 @@ Trk::SlidingCylinderSurface::globalToLocal(const Amg::Vector3D& glopos,
   Amg::Vector3D loc3D0 = m_align ? (m_align->inverse() * glopos) : glopos;
   float offset = (*m_depth)[m_etaBin->bin(loc3D0)];
   // do the transformation or not
-  if (Trk::Surface::m_transform) {
+  if (Trk::Surface::m_transforms) {
     const Amg::Transform3D& surfaceTrans = transform();
     Amg::Transform3D inverseTrans(surfaceTrans.inverse());
     Amg::Vector3D loc3Dframe(inverseTrans * glopos);
@@ -149,7 +149,7 @@ Trk::SlidingCylinderSurface::isOnSurface(const Amg::Vector3D& glopo,
                                          double tol2) const
 {
   Amg::Vector3D loc3D0 = m_align ? m_align->inverse() * glopo : glopo;
-  Amg::Vector3D loc3Dframe = m_transform ? (transform().inverse()) * glopo : glopo;
+  Amg::Vector3D loc3Dframe = m_transforms ? (transform().inverse()) * glopo : glopo;
   float offset = (*m_depth)[m_etaBin->bin(loc3D0)];
   // recalculate r to match bounds
   Amg::Vector3D loc3Dbase((loc3Dframe.perp() - offset) * cos(loc3Dframe.phi()),
diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PerigeeSurface.icc b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PerigeeSurface.icc
index aef32c2c4d574f9005c03ac5c66d2a2ab9a7ae9b..c7fe5c8ea00f50effe17f70d3827d6a658745c1c 100644
--- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PerigeeSurface.icc
+++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PerigeeSurface.icc
@@ -193,8 +193,7 @@ PerigeeSurface::lineDirection() const
     return *(m_lineDirection.ptr());
   }
 
-  if (Surface::m_transform) {
-
+  if (Surface::m_transforms) {
     if (!m_lineDirection.isValid()) {
       m_lineDirection.set(transform().rotation().col(2));
       return *(m_lineDirection.ptr());
diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h
index acddadc7bc39ddb2fb69d002fe8563dae246ed77..5dde363bd243596b7befb2658a7d6943e91ca752 100644
--- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h
+++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h
@@ -97,6 +97,48 @@ public:
     Other = 7
   };
 
+  /*
+   * struct holding the transform, center, normal,
+   * needed when by surfaces when not delegating
+   * to a detector element
+   */
+  struct Transforms
+  {
+    //constructor with just a Amg::Transform3D input
+    inline Transforms(const Amg::Transform3D& _transform)
+      : transform(_transform)
+      , center(transform.translation())
+      , normal(transform.rotation().col(2))
+    {}
+
+    //constructor with  Amg::Transform3D and center input
+    inline Transforms(const Amg::Transform3D& _transform,
+                      const Amg::Vector3D& _center)
+      : transform(_transform)
+      , center(_center)
+      , normal(transform.rotation().col(2))
+    {}
+
+    // constructor with  Amg::Transform3D , center and normal input
+    inline Transforms(const Amg::Transform3D& _transform,
+                      const Amg::Vector3D& _center,
+                      const Amg::Vector3D& _normal)
+      : transform(_transform)
+      , center(_center)
+      , normal(_normal)
+    {}
+    Transforms(const Transforms&) = default;
+    Transforms(Transforms&&) = default;
+    Transforms& operator=(const Transforms&) = default;
+    Transforms& operator=(Transforms&&) = default;
+    ~Transforms() = default;
+    //!< Transform3D to orient surface w.r.t to global frame
+    Amg::Transform3D transform;
+    //!< center position of the surface
+    Amg::Vector3D center;
+    //!< normal vector of the surface
+    Amg::Vector3D normal;
+  };
   /** Unique ptr types**/
   using ChargedTrackParametersUniquePtr = std::unique_ptr<ParametersBase<5, Trk::Charged>>;
   using NeutralTrackParametersUniquePtr = std::unique_ptr<ParametersBase<5, Trk::Neutral>>;
@@ -459,29 +501,22 @@ protected:
   /** Private members are in principle implemented as pointers to
    * objects for easy checks if they are already declared or not */
 
-  //!< Transform3D to orient surface w.r.t to global frame
-  std::unique_ptr<Amg::Transform3D> m_transform;
-  //!< center position of the surface
-  std::unique_ptr<Amg::Vector3D> m_center;
-  //!< normal vector of the surface
-  std::unique_ptr<Amg::Vector3D> m_normal;
+  //!< Pointer to the Transforms struct*/
+  std::unique_ptr<Transforms> m_transforms = nullptr;
 
-  /** Pointers to the a TrkDetElementBase  (not owning)*/
-  const TrkDetElementBase* m_associatedDetElement;
+  /** Pointers to the TrkDetElementBase  (not owning)*/
+  const TrkDetElementBase* m_associatedDetElement = nullptr;
   Identifier m_associatedDetElementId;
-
   /**The associated layer Trk::Layer
    - layer in which the Surface is be embedded
    (not owning)
    */
-  const Layer* m_associatedLayer;
-
+  const Layer* m_associatedLayer = nullptr;
   /** Possibility to attach a material descrption
   - potentially given as the associated material layer
     (not owning)
   */
-  const Layer* m_materialLayer;
-
+  const Layer* m_materialLayer = nullptr;
   /** enum for surface owner : 0  free surface */
   SurfaceOwner m_owner;
 
diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.icc b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.icc
index ecf85d970a1eef0720265e428f1cea04222c30d1..6258cb9f90b9db6eb7154b5a3edcd240c34b8965 100644
--- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.icc
+++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.icc
@@ -13,14 +13,14 @@ Surface::operator!=(const Surface& sf) const
 inline const Amg::Transform3D*
 Surface::cachedTransform() const
 {
-  return m_transform.get();
+  return ((m_transforms) ? &(m_transforms->transform) : nullptr);
 }
 
 inline const Amg::Transform3D&
 Surface::transform() const
 {
-  if (m_transform){
-    return (*m_transform);
+  if (m_transforms){
+    return m_transforms->transform;
   }
   if (m_associatedDetElement && m_associatedDetElementId.is_valid()){
     return m_associatedDetElement->transform(m_associatedDetElementId);
@@ -34,8 +34,8 @@ Surface::transform() const
 inline const Amg::Vector3D&
 Surface::center() const
 {
-  if (m_center){
-    return (*m_center);
+  if (m_transforms){
+    return m_transforms->center;
   }
   if (m_associatedDetElement && m_associatedDetElementId.is_valid()){
     return m_associatedDetElement->center(m_associatedDetElementId);
@@ -49,8 +49,8 @@ Surface::center() const
 inline const Amg::Vector3D&
 Surface::normal() const
 {
-  if (m_normal){
-    return (*m_normal);
+  if (m_transforms){
+    return m_transforms->normal;
   }
   if (m_associatedDetElement && m_associatedDetElementId.is_valid()){
     return m_associatedDetElement->normal(m_associatedDetElementId);
@@ -256,9 +256,7 @@ Surface::isFree() const
 inline void
 Surface::setTransform(const Amg::Transform3D& trans)
 {
-  m_transform = std::make_unique<Amg::Transform3D>(trans);
-  m_center = std::make_unique<Amg::Vector3D>(m_transform->translation());
-  m_normal = std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+  m_transforms = std::make_unique<Transforms>(trans);
 }
 
 inline void Surface::setOwner
diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderSurface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderSurface.cxx
index bc05750c3379512046ee1425b1929eb35ba6fc77..e51c463c3c15a5dee8f3f8804b673bfa263e015c 100644
--- a/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderSurface.cxx
+++ b/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderSurface.cxx
@@ -187,7 +187,7 @@ Trk::CylinderSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vect
   double phi = locpos[Trk::locRPhi] / r;
   glopos = Amg::Vector3D(r * cos(phi), r * sin(phi), locpos[Trk::locZ]);
   // transform it to the globalframe: CylinderSurfaces are allowed to have 0 pointer transform
-  if (Trk::Surface::m_transform)
+  if (Trk::Surface::m_transforms)
     glopos = transform() * glopos;
 }
 
@@ -201,7 +201,7 @@ Trk::CylinderSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vect
   if (inttol < 0.01)
     inttol = 0.01;
   // do the transformation or not
-  if (Trk::Surface::m_transform) {
+  if (Trk::Surface::m_transforms) {
     const Amg::Transform3D& surfaceTrans = transform();
     Amg::Transform3D inverseTrans(surfaceTrans.inverse());
     Amg::Vector3D loc3Dframe(inverseTrans * glopos);
@@ -218,8 +218,12 @@ Trk::CylinderSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vect
 bool
 Trk::CylinderSurface::isOnSurface(const Amg::Vector3D& glopo, Trk::BoundaryCheck bchk, double tol1, double tol2) const
 {
-  Amg::Vector3D loc3Dframe = Trk::Surface::m_transform ? (transform().inverse()) * glopo : glopo;
-  return (bchk ? bounds().inside3D(loc3Dframe, tol1 + s_onSurfaceTolerance, tol2 + s_onSurfaceTolerance) : true);
+  Amg::Vector3D loc3Dframe =
+    Trk::Surface::m_transforms ? (transform().inverse()) * glopo : glopo;
+  return (bchk ? bounds().inside3D(loc3Dframe,
+                                   tol1 + s_onSurfaceTolerance,
+                                   tol2 + s_onSurfaceTolerance)
+               : true);
 }
 
 Trk::Intersection
@@ -228,7 +232,7 @@ Trk::CylinderSurface::straightLineIntersection(const Amg::Vector3D& pos,
                                                bool forceDir,
                                                Trk::BoundaryCheck bchk) const
 {
-  bool needsTransform = m_transform || m_associatedDetElement;
+  bool needsTransform = m_transforms || m_associatedDetElement;
   // create the hep points
   Amg::Vector3D point1 = pos;
   Amg::Vector3D direction = dir;
diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/PerigeeSurface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/PerigeeSurface.cxx
index e720e6ef9fe260f664e9c49e1b0564173dd63b7c..fc788df51ff69d1c4882773f642899892bd09a60 100644
--- a/Tracking/TrkDetDescr/TrkSurfaces/src/PerigeeSurface.cxx
+++ b/Tracking/TrkDetDescr/TrkSurfaces/src/PerigeeSurface.cxx
@@ -27,19 +27,17 @@ Trk::PerigeeSurface::PerigeeSurface(const Amg::Vector3D& gp)
   : Surface()
   , m_lineDirection{}
 {
-  Surface::m_center = std::make_unique<Amg::Vector3D>(gp);
-  Surface::m_transform = std::make_unique<Amg::Transform3D>(
-    Amg::Translation3D(gp.x(), gp.y(), gp.z()));
+  Amg::Transform3D transform (Amg::Translation3D(gp.x(), gp.y(), gp.z()));
+  Surface::m_transforms = std::make_unique<Transforms>(transform, gp, s_xAxis);
 }
 
 Trk::PerigeeSurface::PerigeeSurface(Amg::Transform3D* tTransform)
   : Surface()
   , m_lineDirection{}
 {
-  Surface::m_transform = std::unique_ptr<Amg::Transform3D>(tTransform);
-  if(tTransform){
-    Surface::m_center =
-      std::make_unique<Amg::Vector3D>(tTransform->translation());
+  if (tTransform) {
+    Surface::m_transforms = std::make_unique<Transforms>(
+      *tTransform, tTransform->translation(), s_xAxis);
   }
 }
 
@@ -60,11 +58,9 @@ Trk::PerigeeSurface::PerigeeSurface(const PerigeeSurface& pesf)
   : Surface(pesf)
   , m_lineDirection{}
 {
-  if (pesf.m_center){
-    Surface::m_center = std::make_unique<Amg::Vector3D>(*pesf.m_center);
-  }
-  if (pesf.m_transform){
-    Surface::m_transform = std::make_unique<Amg::Transform3D>(*pesf.m_transform);
+  if (pesf.m_transforms) {
+    Surface::m_transforms = std::make_unique<Transforms>(
+      pesf.m_transforms->transform, pesf.m_transforms->center, s_xAxis);
   }
 }
 
@@ -72,11 +68,11 @@ Trk::PerigeeSurface::PerigeeSurface(const PerigeeSurface& pesf, const Amg::Trans
   : Surface()
   , m_lineDirection{}
 {
-  if (pesf.m_center){
-    Surface::m_center = std::make_unique<Amg::Vector3D>(shift * (*pesf.m_center));
-  }
-  if (pesf.m_transform){
-    Surface::m_transform = std::make_unique<Amg::Transform3D>(shift * (*pesf.m_transform));
+  if (pesf.m_transforms) {
+    Surface::m_transforms =
+      std::make_unique<Transforms>(shift * pesf.m_transforms->transform,
+                                   shift * pesf.m_transforms->center,
+                                   s_xAxis);
   }
 }
 
@@ -133,7 +129,7 @@ Trk::PerigeeSurface::localToGlobal(const Amg::Vector2D& locpos,
                                    Amg::Vector3D& glopos) const
 {
   // this is for a tilted perigee surface
-  if (Surface::m_transform) {
+  if (Surface::m_transforms) {
     // get the vector perpendicular to the momentum and the straw axis
     Amg::Vector3D radiusAxisGlobal(lineDirection().cross(glomom));
     Amg::Vector3D locZinGlobal = transform() * Amg::Vector3D(0., 0., locpos[Trk::locZ]);
@@ -152,7 +148,7 @@ Trk::PerigeeSurface::localToGlobal(const Amg::Vector2D& locpos,
 const Amg::Vector3D*
 Trk::PerigeeSurface::localToGlobal(const Trk::LocalParameters& locpars, const Amg::Vector3D& glomom) const
 {
-  if (Surface::m_transform) {
+  if (Surface::m_transforms) {
     Amg::Vector3D* glopos = new Amg::Vector3D(0., 0., 0.);
     localToGlobal(Amg::Vector2D(locpars[Trk::d0], locpars[Trk::z0]), glomom, *glopos);
     return glopos;
diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/PlaneSurface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/PlaneSurface.cxx
index dff9a96c61b36d693c43919d8b9518b6ba6cc91e..6f97cd7c914613b00b6069612bb98e1a9dfeb909 100644
--- a/Tracking/TrkDetDescr/TrkSurfaces/src/PlaneSurface.cxx
+++ b/Tracking/TrkDetDescr/TrkSurfaces/src/PlaneSurface.cxx
@@ -62,11 +62,10 @@ Trk::PlaneSurface::PlaneSurface(const Amg::Vector3D& position, const Curvilinear
   curvilinearRotation.col(1) = curvUVT.curvV();
   curvilinearRotation.col(2) = curvUVT.curvT();
   // curvilinear surfaces are boundless
-  Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>();
-  (*Trk::Surface::m_transform) = curvilinearRotation;
-  Trk::Surface::m_transform->pretranslate(position);
-  Trk::Surface::m_center = std::make_unique<Amg::Vector3D>(m_transform->translation());
-  Trk::Surface::m_normal = std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+  Amg::Transform3D transform{};
+  transform = curvilinearRotation;
+  transform.pretranslate(position);
+  Trk::Surface::m_transforms = std::make_unique<Transforms>(transform);
 }
 
 // construct form TrkDetElementBase
@@ -74,12 +73,8 @@ Trk::PlaneSurface::PlaneSurface(const Trk::TrkDetElementBase& detelement, Amg::T
   : Trk::Surface(detelement)
   , m_bounds()
 {
-  m_transform=std::unique_ptr<Amg::Transform3D>(transf);
-  if (m_transform) {
-    Trk::Surface::m_center =
-      std::make_unique<Amg::Vector3D>(m_transform->translation());
-    Trk::Surface::m_normal =
-      std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+  if(transf){
+    Trk::Surface::m_transforms = std::make_unique<Transforms>(*transf);
   }
 }
 
@@ -90,13 +85,10 @@ Trk::PlaneSurface::PlaneSurface(const Trk::TrkDetElementBase& detelement,
   : Trk::Surface(detelement, id)
   , m_bounds()
 {
-  m_transform=std::unique_ptr<Amg::Transform3D>(transf);
-  if (m_transform) {
-    Trk::Surface::m_center =
-      std::make_unique<Amg::Vector3D>(m_transform->translation());
-    Trk::Surface::m_normal =
-      std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+  if(transf){
+    Trk::Surface::m_transforms = std::make_unique<Transforms>(*transf);
   }
+
 }
 
 // construct planar surface without bounds
diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/Surface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/Surface.cxx
index 520e9ada1e49b8887e2d5543c3a739a5756a79e2..378e5d676c228beb1211cc23766ddf5e4d586d83 100644
--- a/Tracking/TrkDetDescr/TrkSurfaces/src/Surface.cxx
+++ b/Tracking/TrkDetDescr/TrkSurfaces/src/Surface.cxx
@@ -24,9 +24,7 @@ std::atomic<unsigned int> Trk::Surface::s_numberOfFreeInstantiations{ 0 };
 #endif
 
 Trk::Surface::Surface()
-  : m_transform(nullptr)
-  , m_center(nullptr)
-  , m_normal(nullptr)
+  : m_transforms(nullptr)
   , m_associatedDetElement(nullptr)
   , m_associatedDetElementId()
   , m_associatedLayer(nullptr)
@@ -49,19 +47,15 @@ Trk::Surface::Surface()
 __attribute__ ((flatten))
 #endif
 Trk::Surface::Surface(Amg::Transform3D* tform)
-  : m_transform(nullptr)
-  , m_center(nullptr)
-  , m_normal(nullptr)
+  : m_transforms(nullptr)
   , m_associatedDetElement(nullptr)
   , m_associatedDetElementId()
   , m_associatedLayer(nullptr)
   , m_materialLayer(nullptr)
   , m_owner(Trk::noOwn)
 {
-  m_transform = std::unique_ptr<Amg::Transform3D>(tform);
   if (tform) {
-    m_center = std::make_unique<Amg::Vector3D>(tform->translation());
-    m_normal = std::make_unique<Amg::Vector3D>(tform->rotation().col(2));
+    m_transforms = std::make_unique<Transforms>(*tform);
   }
 #ifndef NDEBUG
   s_numberOfInstantiations++; // EDM Monitor - increment one instance
@@ -76,9 +70,7 @@ Trk::Surface::Surface(std::unique_ptr<Amg::Transform3D> tform)
 }
 
 Trk::Surface::Surface(const Trk::TrkDetElementBase& detelement)
-  : m_transform(nullptr)
-  , m_center(nullptr)
-  , m_normal(nullptr)
+  : m_transforms(nullptr)
   , m_associatedDetElement(&detelement)
   , m_associatedDetElementId()
   , m_associatedLayer(nullptr)
@@ -91,9 +83,7 @@ Trk::Surface::Surface(const Trk::TrkDetElementBase& detelement)
 }
 
 Trk::Surface::Surface(const Trk::TrkDetElementBase& detelement, const Identifier& id)
-  : m_transform(nullptr)
-  , m_center(nullptr)
-  , m_normal(nullptr)
+  : m_transforms(nullptr)
   , m_associatedDetElement(&detelement)
   , m_associatedDetElementId(id)
   , m_associatedLayer(nullptr)
@@ -115,19 +105,14 @@ __attribute__ ((flatten))
 #endif
 // copy constructor - Attention! sets the associatedDetElement to 0 and the identifier to invalid
 Trk::Surface::Surface(const Surface& sf)
-  : m_transform(nullptr)
-  , m_center(nullptr)
-  , m_normal(nullptr)
+  : m_transforms(nullptr)
   , m_associatedDetElement(nullptr)
   , m_associatedDetElementId()
   , m_associatedLayer(sf.m_associatedLayer)
   , m_materialLayer(sf.m_materialLayer)
   , m_owner(Trk::noOwn)
 {
-
-  m_transform = std::make_unique<Amg::Transform3D>(sf.transform());
-  m_center = std::make_unique<Amg::Vector3D>(m_transform->translation());
-  m_normal = std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+  m_transforms = std::make_unique<Transforms>(sf.transform());
 #ifndef NDEBUG
   s_numberOfInstantiations++; // EDM Monitor - increment one instance
   // this is by definition a free surface since a copy is not allowed to point to the det element
@@ -141,25 +126,25 @@ Trk::Surface::Surface(const Surface& sf)
 // to out-of-line Eigen code that is linked from other DSOs; in that case,
 // it would not be optimized.  Avoid this by forcing all Eigen code
 // to be inlined here if possible.
-__attribute__ ((flatten))
+__attribute__((flatten))
 #endif
-// copy constructor with shift - Attention! sets the associatedDetElement to 0 and the identifier to invalid
-// also invalidates the material layer
+// copy constructor with shift - Attention! sets the associatedDetElement to 0
+// and the identifier to invalid also invalidates the material layer
 Trk::Surface::Surface(const Surface& sf, const Amg::Transform3D& shift)
-  : m_transform(sf.m_transform ? std::make_unique<Amg::Transform3D>(shift * (*(sf.m_transform)))
-                               : std::make_unique<Amg::Transform3D>(shift))
-  , m_center((sf.m_center) ? std::make_unique<Amg::Vector3D>(shift * (*(sf.m_center))) : nullptr)
-  , m_normal(nullptr)
+  : m_transforms(nullptr)
   , m_associatedDetElement(nullptr)
   , m_associatedDetElementId()
   , m_associatedLayer(nullptr)
   , m_materialLayer(nullptr)
   , m_owner(Trk::noOwn)
 {
-  if (!m_center) {
-    m_center = std::make_unique<Amg::Vector3D>(m_transform->translation());
+
+  if (sf.m_transforms) {
+    m_transforms = std::make_unique<Transforms>(
+      shift * sf.m_transforms->transform, shift * sf.m_transforms->center);
+  } else {
+    m_transforms = std::make_unique<Transforms>(Amg::Transform3D(shift));
   }
-  m_normal = std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
 #ifndef NDEBUG
   s_numberOfInstantiations++; // EDM Monitor - increment one instance
   // this is by definition a free surface since a copy is not allowed to point to the det element
@@ -184,9 +169,7 @@ Trk::Surface&
 Trk::Surface::operator=(const Trk::Surface& sf)
 {
   if (this != &sf) {
-    m_transform = std::make_unique<Amg::Transform3D>(sf.transform());
-    m_center = std::make_unique<Amg::Vector3D>(m_transform->translation());
-    m_normal = std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2));
+    m_transforms = std::make_unique<Transforms>(sf.transform());
     m_associatedDetElement = nullptr;
     m_associatedDetElementId = Identifier();
     m_associatedLayer = sf.m_associatedLayer;