From 1b5cb65564633b5d5438021188f17ba00803b6f9 Mon Sep 17 00:00:00 2001
From: Christos Anastopoulos <christos.anastopoulos@cern.ch>
Date: Mon, 2 Oct 2023 16:23:07 +0200
Subject: [PATCH] Introduce ParametersCommon to factorize the relation between
 PatternTrackParameters and ParametersBase

Introduce ParametersCommon to factorize the relation between PatternTrackParameters and ParametersBase
---
 .../TrkParametersBase/ParametersBase.h        | 137 ++-----
 .../TrkParametersBase/ParametersBase.icc      | 348 ++++++------------
 .../TrkParametersBase/ParametersCommon.h      | 170 +++++++++
 .../TrkParametersBase/ParametersCommon.icc    | 117 ++++++
 .../PatternTrackParameters.h                  |  22 +-
 .../PatternTrackParameters.icc                |   2 +-
 6 files changed, 437 insertions(+), 359 deletions(-)
 create mode 100644 Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersCommon.h
 create mode 100644 Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersCommon.icc

diff --git a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersBase.h b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersBase.h
index baadcdb6fae..2581b9bed9f 100644
--- a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersBase.h
+++ b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersBase.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -9,17 +9,11 @@
 #ifndef TRKPARAMETERSBASE_PARAMETERSBASE_H
 #define TRKPARAMETERSBASE_PARAMETERSBASE_H
 //
-#include "TrkParametersBase/Charged.h"
-#include "TrkParametersBase/Neutral.h"
-// Amg
-#include "EventPrimitives/EventPrimitives.h"
-#include "GeoPrimitives/GeoPrimitives.h"
-#include "TrkEventPrimitives/SurfaceTypes.h"
+#include "TrkParametersBase/ParametersCommon.h"
 //system
 #include <memory>
 #include <type_traits>
 #include <optional>
-#include <limits>
 #include <iosfwd>
 
 class MsgStream;
@@ -35,22 +29,7 @@ namespace Trk {
 class Surface;
 class MaterialEffectsEngine;
 
-/**
-   @enum ParametersType
-   Enum to avoid dynamic cast for different parameter types.
-*/
-enum ParametersType
-{
-  AtaSurface = 0,
-  Curvilinear = 1,
-  Pattern = 2
-};
 
-namespace InvalidParam {
-constexpr double INVALID = std::numeric_limits<double>::quiet_NaN();
-constexpr double INVALID_P(10e9);
-constexpr double INVALID_QOP(10e-9);
-}
 /**
    @class ParametersBase
 
@@ -72,106 +51,54 @@ constexpr double INVALID_QOP(10e-9);
 */
 
 template<int DIM, class T>
-class ParametersBase
+class ParametersBase : public ParametersCommon<DIM,T>
 {
 public:
-  static_assert((std::is_same<T, Trk::Charged>::value ||
-                 std::is_same<T, Trk::Neutral>::value),
-                "Parameters must be Charged or Neutral");
-  static constexpr int dim = DIM;
   /** virtual Destructor */
   virtual ~ParametersBase() = default;
 
-  /** Access methods for the parameters */
-  const AmgVector(DIM) & parameters() const;
-  AmgVector(DIM) & parameters();
-
-  /** Access method for the covariance matrix - returns nullptr if no covariance
-   * matrix is given */
-  const AmgSymMatrix(DIM) * covariance() const;
-  AmgSymMatrix(DIM) * covariance();
-
-  /** Access method for transverse momentum */
-  double pT() const;
-
-  /** Access method for pseudorapidity - from momentum */
-  double eta() const;
-
-  /** Returns true if Charged or false if Neutral
-   */
-  constexpr bool isCharged() const;
-  /** Access method for the local coordinates, \f$(loc1,loc2)\f$
-      local parameter definitions differ for each surface type. */
-  Amg::Vector2D localPosition() const;
-
-  /** set parameters*/
-  void setParameters(const AmgVector(DIM) & param);
-
-  /** set covariance */
-  void setCovariance(const AmgSymMatrix(DIM) & cov);
-
-  /** Update parameters  and covariance , passing covariance by ref. A
-   * covariance is created if one does not exist.  Otherwise in place update
-   * occurs via assignment.
-   *
-   * Derived classes override the
-   * implementation via updateParametersHelper
-   * as this could possibly lead to updating
-   * other data members
-   */
-  void updateParameters(const AmgVector(DIM) &, const AmgSymMatrix(DIM) &);
-
-  /** Update parameters.
-   * Derived classes override the
-   * implementation via updateParametersHelper
-   * as this could possibly lead to updating
-   * other data members
-   */
-  void updateParameters(const AmgVector(DIM)&);
-
-
   /** Returns the charge */
-  virtual double charge() const = 0;
+  virtual double charge() const override = 0;
 
   /** Access method for the position */
-  virtual Amg::Vector3D position() const = 0;
+  virtual Amg::Vector3D position() const override = 0;
 
   /** Access method for the momentum */
-  virtual Amg::Vector3D momentum() const = 0;
+  virtual Amg::Vector3D momentum() const override =0 ;
 
   //** equality operator */
   virtual bool operator==(const ParametersBase<DIM, T>&) const;
 
   /** Test to see if there's a not null surface ptr. */
-  virtual bool hasSurface() const = 0;
+  virtual bool hasSurface() const override = 0;
 
   /** Access to the Surface associated to the Parameters*/
-  virtual const Surface& associatedSurface() const = 0;
+  virtual const Surface& associatedSurface() const override = 0;
 
   /** Return the measurement frame - this is needed for alignment, in
      particular for StraightLine and Perigee Surface
       - the default implementation is the RotationMatrix3D of the
      transform */
-  virtual Amg::RotationMatrix3D measurementFrame() const = 0;
+  virtual Amg::RotationMatrix3D measurementFrame() const override = 0;
 
   /** clone method for polymorphic deep copy
        @return new object copied from the concrete type of this object.*/
-  virtual ParametersBase<DIM, T>* clone() const = 0;
-  
+  virtual ParametersBase<DIM, T>* clone() const override = 0;
+
   /** clone method for polymorphic deep copy returning unique_ptr; it is not overriden,
        but uses the existing clone method.
        @return new object copied from the concrete type of this object.*/
   std::unique_ptr<ParametersBase<DIM, T>> uniqueClone() const{
     return std::unique_ptr<ParametersBase<DIM, T>>(this->clone());
   }
-  
-  
+
+
   /** Return the ParametersType enum */
-  virtual ParametersType type() const = 0;
+  virtual ParametersType type() const override = 0;
 
   /** Returns the Surface Type enum for the surface used
    * to define the derived class*/
-  virtual SurfaceType surfaceType() const = 0;
+  virtual SurfaceType surfaceType() const override = 0;
 
   /** Dumps relevant information about the track parameters into the ostream */
   virtual MsgStream& dump(MsgStream& out) const;
@@ -182,8 +109,11 @@ protected:
    * This is an abstract class and we can not instantiate objects directly.
    * In the other hand derived classed can use ctors
    */
-
   ParametersBase() = default;
+  ParametersBase(ParametersBase&&) noexcept = default;
+  ParametersBase& operator=(ParametersBase&&) noexcept  = default;
+  ParametersBase(const ParametersBase&) = default;
+  ParametersBase& operator=(const ParametersBase&) = default;
 
   /* Helper ctors for derived classes*/
   ParametersBase(const AmgVector(DIM) parameters,
@@ -195,32 +125,13 @@ protected:
   ParametersBase(const AmgVector(DIM) & parameters,
                  std::optional<AmgSymMatrix(DIM)>&& covariance = std::nullopt);
 
+  virtual void updateParametersHelper(const AmgVector(DIM) &) override = 0;
   /*
-   * Default Move ctor/assignment, private can be used
-   * only by derived classes.
+   * Add dependent names into scope
    */
-  ParametersBase(ParametersBase&&) noexcept = default;
-  ParametersBase& operator=(ParametersBase&&) noexcept  = default;
-  /*
-   * Default copy ctor/assignment
-   * Deleted due unique_ptr.
-   *
-   * Derived classes can implement them explicitly.
-   * Polymorphic deep copy can happen via the clone
-   * method
-   */
-  ParametersBase(const ParametersBase&) = default;
-  ParametersBase& operator=(const ParametersBase&) = default;
-
-  /* Helper implementing the specific per derived class logic for
-   * the update of parameters*/
-  virtual void updateParametersHelper(const AmgVector(DIM) &) = 0;
-
-  AmgVector(DIM) m_parameters; //!< contains the n parameters
-  //!< contains the n x n covariance matrix
-  std::optional<AmgSymMatrix(DIM)> m_covariance = std::nullopt;
-  T m_chargeDef; //!< charge definition for this track
-
+  using ParametersCommon<DIM, T>::m_parameters;
+  using ParametersCommon<DIM, T>::m_covariance;
+  using ParametersCommon<DIM, T>::m_chargeDef;
 };
 
 /**Overload of << operator for both, MsgStream and std::ostream for debug
diff --git a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersBase.icc b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersBase.icc
index df3f9dfabc8..2e582de5876 100644
--- a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersBase.icc
+++ b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersBase.icc
@@ -6,253 +6,133 @@
 // ParametersBase.icc, (c) ATLAS Detector software
 ///////////////////////////////////////////////////////////////////
 
-
 // Gaudi
 #include "GaudiKernel/MsgStream.h"
 // Trk
 #include "TrkEventPrimitives/ParamDefs.h"
 // STD
+#include <iomanip>
 #include <ostream>
-#include <utility>
 #include <sstream>
-#include <iomanip>
+#include <utility>
 
 namespace Trk {
 
-  namespace {
-    template<typename T>
-    int
-    sgn(const T& val)
-    {
-      return (val > 0) - (val < 0);
-    }
-  }
+namespace {
+template <typename T>
+int sgn(const T& val) {
+  return (val > 0) - (val < 0);
+}
+}  // namespace
 
-  // Helper protected ctor*/
-  template<int DIM, class T>
-  inline ParametersBase<DIM, T>::ParametersBase(
+// Helper protected ctor*/
+template <int DIM, class T>
+inline ParametersBase<DIM, T>::ParametersBase(
     const AmgVector(DIM) parameters,
-    std::optional<AmgSymMatrix(DIM)>&& covariance,
-    const T chargeDef)
-    : m_parameters(parameters)
-    , m_covariance(std::move(covariance))
-    , m_chargeDef(chargeDef)
-  {}
+    std::optional<AmgSymMatrix(DIM)>&& covariance, const T chargeDef)
+    : ParametersCommon<DIM, T>(parameters, std::move(covariance), chargeDef) {}
 
-  // Helper protected ctor
-  template<int DIM, class T>
-  inline ParametersBase<DIM, T>::ParametersBase(
+// Helper protected ctor
+template <int DIM, class T>
+inline ParametersBase<DIM, T>::ParametersBase(
     std::optional<AmgSymMatrix(DIM)>&& covariance)
-    : m_parameters()
-    , m_covariance(std::move(covariance))
-    , m_chargeDef{}
-  {}
-  // Protected Constructor with local arguments - persistency only
-  template<int DIM, class T>
-  inline ParametersBase<DIM, T>::ParametersBase(
+    : ParametersCommon<DIM, T>(std::move(covariance)) {}
+
+// Protected Constructor with local arguments - persistency only
+template <int DIM, class T>
+inline ParametersBase<DIM, T>::ParametersBase(
     const AmgVector(DIM) & parameters,
     std::optional<AmgSymMatrix(DIM)>&& covariance)
-    : m_parameters(parameters)
-    , m_covariance(std::move(covariance))
-    , m_chargeDef{}
-  {}
-
-  template<int DIM, class T>
-  inline const AmgVector(DIM)& 
-  ParametersBase<DIM, T>::parameters() const
-  {
-    return m_parameters;
-  }
-
-  template<int DIM, class T>
-  inline AmgVector(DIM)& 
-  ParametersBase<DIM, T>::parameters()
-  {
-    return m_parameters;
-  }
-
-  template<int DIM, class T>
-  inline const AmgSymMatrix(DIM)* 
-  ParametersBase<DIM, T>::covariance() const
-  {
-    if (m_covariance) {
-      return &(*m_covariance);
-    } else {
-      return nullptr;
-    }
-  }
-
-  template<int DIM, class T>
-  inline AmgSymMatrix(DIM)* 
-  ParametersBase<DIM, T>::covariance()
-  {
-    if (m_covariance) {
-      return &(*m_covariance);
-    } else {
-      return nullptr;
-    }
-  }
-
-  template<int DIM, class T>
-  inline double
-  ParametersBase<DIM, T>::pT() const
-  {
-    return momentum().perp();
-  }
-
-  template<int DIM, class T>
-  inline double
-  ParametersBase<DIM, T>::eta() const
-  {
-    return momentum().eta();
-  }
-
-  template<int DIM, class T>
-  inline constexpr bool
-  ParametersBase<DIM, T>::isCharged() const
-  {
-    if constexpr (std::is_same<T, Trk::Neutral>::value) {
-      return false;
-    } else {
-      return true;
-    }
-  }
-
-  template<int DIM, class T>
-  inline Amg::Vector2D
-  ParametersBase<DIM, T>::localPosition() const
-  {
-    return Amg::Vector2D(m_parameters[Trk::loc1], m_parameters[Trk::loc2]);
-  }
-
-  template<int DIM, class T>
-  inline void
-  ParametersBase<DIM, T>::setParameters(const AmgVector(DIM) & param)
-  {
-    m_parameters = param;
-  }
-
-  template<int DIM, class T>
-  inline void
-  ParametersBase<DIM, T>::setCovariance(const AmgSymMatrix(DIM) & cov)
-  {
-    m_covariance = cov;
-  }
-
-  template<int DIM, class T>
-  inline void
-  ParametersBase<DIM, T>::updateParameters(const AmgVector(DIM) &
-                                             updatedParameters)
-  {
-    this->updateParametersHelper(updatedParameters);
-  }
-
-  template<int DIM, class T>
-  inline void
-  ParametersBase<DIM, T>::updateParameters(const AmgVector(DIM) &
-                                             updatedParameters,
-                                           const AmgSymMatrix(DIM) &
-                                             updatedCovariance)
-  {
-    m_covariance = updatedCovariance;
-    this->updateParametersHelper(updatedParameters);
-  }
-
-  /** equality operator */
-  template<int DIM, class T>
-  bool
-  ParametersBase<DIM, T>::operator==(const ParametersBase<DIM, T>& rhs) const
-  {
-    // tolerance for comparisons
-    constexpr double tolerance = 1e-8;
-
-    // compare parameters
-    if (!this->parameters().isApprox(rhs.parameters(), tolerance)) {
-      return false;
-    }
-
-    // compare covariance
-    if (((this->covariance() != nullptr) && (rhs.covariance() != nullptr) &&
-         !this->covariance()->isApprox(*rhs.covariance(), tolerance)) ||
-        (!this->covariance() != !rhs.covariance())) { // <-- this is: covariance()
-                                                      // XOR pCast->covariance()
-      return false;
-    }
-
-    // compare position
-    if (!this->position().isApprox(rhs.position(), tolerance)) {
-      return false;
-    }
-
-    // compare momentum
-    if (!this->momentum().isApprox(rhs.momentum(), tolerance)) {
-      return false;
-    }
-
-    // compare charge definition
-    if (m_chargeDef != rhs.m_chargeDef) {
-      return false;
-    }
-
-    return true;
-  }
-
-  template<int DIM, class T>
-  MsgStream&
-  ParametersBase<DIM, T>::dump(MsgStream& sl) const
-  {
-    std::ostringstream output{};
-    dump(output);
-    sl<<output.str();
-    return sl;
-  }
-
-  template<int DIM, class T>
-  std::ostream&
-  ParametersBase<DIM, T>::dump(std::ostream& sl) const
-  {
-    const std::string nl{"\n"};
-    sl << std::setiosflags(std::ios::fixed);
-    sl << std::setprecision(7);
-    sl << " * TrackParameters on Surface" << nl;
-    sl << " * loc1  : " << parameters()[Trk::loc1] << nl;
-    sl << " * loc2  : " << parameters()[Trk::loc2] << nl;
-    sl << " * phi   : " << parameters()[Trk::phi] << nl;
-    sl << " * Theta : " << parameters()[Trk::theta] << nl;
-    sl << " * q/p   : " << parameters()[Trk::qOverP] << nl;
-    if (parameters().rows() > 5) {
-      sl << " * mass  : " << parameters()[Trk::trkMass]
-         << " (extended parameters)" << nl;
-    }
-    sl << " * charge: " << charge() << nl;
-    sl << " * covariance matrix = " << covariance() << nl;
-    sl << " * corresponding global parameters:" << nl;
-    sl << " *    position  (x,  y,  z ) = (" << position().x() << ", "
-       << position().y() << ", " << position().z() << ")" << nl;
-    sl << " *    momentum  (px, py, pz) = (" << momentum().x() << ", "
-       << momentum().y() << ", " << momentum().z() << ")" << nl;
-    sl << std::setprecision(-1);
-    if (hasSurface()){
-      sl << "associated surface:" << nl;
-      sl << associatedSurface() << std::endl;
-    } else {
-      sl<< "no associated surface"<< std::endl;
-    }
-    
-    return sl;
-  }
-
-  template<int DIM, class T>
-  MsgStream&
-  operator<<(MsgStream& sl, const Trk::ParametersBase<DIM, T>& p)
-  {
-    return p.dump(sl);
-  }
-
-  template<int DIM, class T>
-  std::ostream&
-  operator<<(std::ostream& sl, const Trk::ParametersBase<DIM, T>& p)
-  {
-    return p.dump(sl);
-  }
-} // end of namespace Trk
+    : ParametersCommon<DIM, T>(parameters, std::move(covariance)) {}
+
+/** equality operator */
+template <int DIM, class T>
+bool ParametersBase<DIM, T>::operator==(
+    const ParametersBase<DIM, T>& rhs) const {
+  // tolerance for comparisons
+  constexpr double tolerance = 1e-8;
+
+  // compare parameters
+  if (!this->parameters().isApprox(rhs.parameters(), tolerance)) {
+    return false;
+  }
+
+  // compare covariance
+  if (((this->covariance() != nullptr) && (rhs.covariance() != nullptr) &&
+       !this->covariance()->isApprox(*rhs.covariance(), tolerance)) ||
+      (!this->covariance() !=
+       !rhs.covariance())) {  // <-- this is: covariance()
+                              // XOR pCast->covariance()
+    return false;
+  }
+
+  // compare position
+  if (!this->position().isApprox(rhs.position(), tolerance)) {
+    return false;
+  }
+
+  // compare momentum
+  if (!this->momentum().isApprox(rhs.momentum(), tolerance)) {
+    return false;
+  }
+
+  // compare charge definition
+  if (m_chargeDef != rhs.m_chargeDef) {
+    return false;
+  }
+
+  return true;
+}
+
+template <int DIM, class T>
+MsgStream& ParametersBase<DIM, T>::dump(MsgStream& sl) const {
+  std::ostringstream output{};
+  dump(output);
+  sl << output.str();
+  return sl;
+}
+
+template <int DIM, class T>
+std::ostream& ParametersBase<DIM, T>::dump(std::ostream& sl) const {
+  const std::string nl{"\n"};
+  sl << std::setiosflags(std::ios::fixed);
+  sl << std::setprecision(7);
+  sl << " * TrackParameters on Surface" << nl;
+  sl << " * loc1  : " << this->parameters()[Trk::loc1] << nl;
+  sl << " * loc2  : " << this->parameters()[Trk::loc2] << nl;
+  sl << " * phi   : " << this->parameters()[Trk::phi] << nl;
+  sl << " * Theta : " << this->parameters()[Trk::theta] << nl;
+  sl << " * q/p   : " << this->parameters()[Trk::qOverP] << nl;
+  if (this->parameters().rows() > 5) {
+    sl << " * mass  : " << this->parameters()[Trk::trkMass]
+       << " (extended parameters)" << nl;
+  }
+  sl << " * charge: " << this->charge() << nl;
+  sl << " * covariance matrix = " << this->covariance() << nl;
+  sl << " * corresponding global parameters:" << nl;
+  sl << " *    position  (x,  y,  z ) = (" << this->position().x() << ", "
+     << this->position().y() << ", " << this->position().z() << ")" << nl;
+  sl << " *    momentum  (px, py, pz) = (" << this->momentum().x() << ", "
+     << this->momentum().y() << ", " << this->momentum().z() << ")" << nl;
+  sl << std::setprecision(-1);
+  if (this->hasSurface()) {
+    sl << "associated surface:" << nl;
+    sl << this->associatedSurface() << std::endl;
+  } else {
+    sl << "no associated surface" << std::endl;
+  }
+
+  return sl;
+}
+
+template <int DIM, class T>
+MsgStream& operator<<(MsgStream& sl, const Trk::ParametersBase<DIM, T>& p) {
+  return p.dump(sl);
+}
+
+template <int DIM, class T>
+std::ostream& operator<<(std::ostream& sl,
+                         const Trk::ParametersBase<DIM, T>& p) {
+  return p.dump(sl);
+}
+}  // end of namespace Trk
diff --git a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersCommon.h b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersCommon.h
new file mode 100644
index 00000000000..4e9e8b3c87c
--- /dev/null
+++ b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersCommon.h
@@ -0,0 +1,170 @@
+/*
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+*/
+
+/* @brief ParametersCommon common base class
+ * for  ParametersT, CurvilinearParameters and PatternTrackParameters
+ */
+
+#ifndef TRKPARAMETERSCOMMON_PARAMETERSCOMMON_H
+#define TRKPARAMETERSCOMMON_PARAMETERSCOMMON_H
+//
+#include "TrkParametersBase/Charged.h"
+#include "TrkParametersBase/Neutral.h"
+// Amg
+#include "EventPrimitives/EventPrimitives.h"
+#include "GeoPrimitives/GeoPrimitives.h"
+#include "TrkEventPrimitives/SurfaceTypes.h"
+//
+#include <optional>
+#include <limits>
+
+namespace Trk {
+class Surface;
+
+/**
+   @enum ParametersType
+   Enum to avoid dynamic cast for different parameter types.
+*/
+enum ParametersType { AtaSurface = 0, Curvilinear = 1, Pattern = 2 };
+
+namespace InvalidParam {
+constexpr double INVALID = std::numeric_limits<double>::quiet_NaN();
+constexpr double INVALID_P(10e9);
+constexpr double INVALID_QOP(10e-9);
+}
+
+/**
+   @class ParametersCommon
+   Common class for neutral, charged and Pattern Track
+   Parameters
+   @author Christos Anastopoulos
+*/
+
+template <int DIM, class T>
+class ParametersCommon {
+ public:
+  static_assert((std::is_same<T, Trk::Charged>::value ||
+                 std::is_same<T, Trk::Neutral>::value),
+                "Parameters must be Charged or Neutral");
+  static constexpr int dim = DIM;
+
+  /** Access methods for the parameters */
+  const AmgVector(DIM) & parameters() const;
+  AmgVector(DIM) & parameters();
+
+  /** Access method for the covariance matrix - returns nullptr if no covariance
+   * matrix is given */
+  const AmgSymMatrix(DIM) * covariance() const;
+  AmgSymMatrix(DIM) * covariance();
+
+  /** Access method for transverse momentum */
+  double pT() const;
+
+  /** Access method for pseudorapidity - from momentum */
+  double eta() const;
+
+  /** Returns true if Charged or false if Neutral
+   */
+  constexpr bool isCharged() const;
+  /** Access method for the local coordinates, \f$(loc1,loc2)\f$
+      local parameter definitions differ for each surface type. */
+  Amg::Vector2D localPosition() const;
+
+  /** set parameters*/
+  void setParameters(const AmgVector(DIM) & param);
+
+  /** set covariance */
+  void setCovariance(const AmgSymMatrix(DIM) & cov);
+
+  /** Update parameters  and covariance , passing covariance by ref. A
+   * covariance is created if one does not exist.  Otherwise in place update
+   * occurs via assignment.
+   *
+   * Derived classes override the
+   * implementation via updateParametersHelper
+   * as this could possibly lead to updating
+   * other data members
+   */
+  void updateParameters(const AmgVector(DIM) &, const AmgSymMatrix(DIM) &);
+
+  /** Update parameters.
+   * Derived classes override the
+   * implementation via updateParametersHelper
+   * as this could possibly lead to updating
+   * other data members
+   */
+  void updateParameters(const AmgVector(DIM) &);
+
+  /** Returns the charge */
+  virtual double charge() const = 0;
+
+  /** Access method for the position */
+  virtual Amg::Vector3D position() const = 0;
+
+  /** Access method for the momentum */
+  virtual Amg::Vector3D momentum() const = 0;
+
+  /** Test to see if there's a not null surface ptr. */
+  virtual bool hasSurface() const = 0;
+
+  /** Access to the Surface associated to the Parameters*/
+  virtual const Surface& associatedSurface() const = 0;
+
+  /** Return the measurement frame - this is needed for alignment, in
+     particular for StraightLine and Perigee Surface
+      - the default implementation is the RotationMatrix3D of the
+     transform */
+  virtual Amg::RotationMatrix3D measurementFrame() const = 0;
+
+  /** clone method for polymorphic deep copy
+       @return new object copied from the concrete type of this object.*/
+  virtual ParametersCommon<DIM, T>* clone() const = 0;
+
+  /** Return the ParametersType enum */
+  virtual ParametersType type() const = 0;
+
+  /** Returns the Surface Type enum for the surface used
+   * to define the derived class*/
+  virtual SurfaceType surfaceType() const = 0;
+
+  /** virtual Destructor */
+  virtual ~ParametersCommon() = default;
+
+ protected:
+  /*
+   * This is an abstract class and we can not instantiate objects directly.
+   * In the other hand derived classed can use ctors
+   */
+  ParametersCommon() = default;
+  ParametersCommon(ParametersCommon&&) noexcept = default;
+  ParametersCommon& operator=(ParametersCommon&&) noexcept = default;
+  ParametersCommon(const ParametersCommon&) = default;
+  ParametersCommon& operator=(const ParametersCommon&) = default;
+  /* Helper ctors for derived classes*/
+  ParametersCommon(const AmgVector(DIM) parameters,
+                 std::optional<AmgSymMatrix(DIM)>&& covariance,
+                 const T chargeDef);
+
+  ParametersCommon(std::optional<AmgSymMatrix(DIM)>&& covariance);
+
+  ParametersCommon(const AmgVector(DIM) & parameters,
+                 std::optional<AmgSymMatrix(DIM)>&& covariance = std::nullopt);
+
+
+  /* Helper implementing the specific per derived class logic for
+   * the update of parameters*/
+  virtual void updateParametersHelper(const AmgVector(DIM) &) = 0;
+
+  //!< contains the n parameters
+  AmgVector(DIM) m_parameters;
+  //!< contains the n x n covariance matrix
+  std::optional<AmgSymMatrix(DIM)> m_covariance = std::nullopt;
+  //!< charge definition for this track
+  T m_chargeDef{};  //!< charge definition for this track
+};
+}  // end of namespace Trk
+
+#include "TrkParametersBase/ParametersCommon.icc"
+
+#endif
diff --git a/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersCommon.icc b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersCommon.icc
new file mode 100644
index 00000000000..63b62b6e1d9
--- /dev/null
+++ b/Tracking/TrkEvent/TrkParametersBase/TrkParametersBase/ParametersCommon.icc
@@ -0,0 +1,117 @@
+/*
+  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
+*/
+
+// Trk
+#include "TrkEventPrimitives/ParamDefs.h"
+// STD
+#include <utility>
+
+namespace Trk {
+// Helper protected ctor
+template <int DIM, class T>
+inline ParametersCommon<DIM, T>::ParametersCommon(
+    const AmgVector(DIM) parameters,
+    std::optional<AmgSymMatrix(DIM)>&& covariance, const T chargeDef)
+    : m_parameters(parameters),
+      m_covariance(std::move(covariance)),
+      m_chargeDef(chargeDef) {}
+
+// Helper protected ctor
+template <int DIM, class T>
+inline ParametersCommon<DIM, T>::ParametersCommon(
+    std::optional<AmgSymMatrix(DIM)>&& covariance)
+    : m_parameters(),
+    m_covariance(std::move(covariance)),
+    m_chargeDef{} {}
+
+
+// Protected Constructor with local arguments
+template <int DIM, class T>
+inline ParametersCommon<DIM, T>::ParametersCommon(
+    const AmgVector(DIM) & parameters,
+    std::optional<AmgSymMatrix(DIM)>&& covariance)
+    : m_parameters(parameters),
+      m_covariance(std::move(covariance)),
+      m_chargeDef{} {}
+
+template <int DIM, class T>
+inline const AmgVector(DIM) & ParametersCommon<DIM, T>::parameters() const {
+  return m_parameters;
+}
+
+template <int DIM, class T>
+inline AmgVector(DIM) & ParametersCommon<DIM, T>::parameters() {
+  return m_parameters;
+}
+
+template <int DIM, class T>
+inline const AmgSymMatrix(DIM) *ParametersCommon<DIM, T>::covariance() const {
+  if (m_covariance) {
+    return &(*m_covariance);
+  } else {
+    return nullptr;
+  }
+}
+
+template <int DIM, class T>
+inline AmgSymMatrix(DIM) * ParametersCommon<DIM, T>::covariance() {
+  if (m_covariance) {
+    return &(*m_covariance);
+  } else {
+    return nullptr;
+  }
+}
+
+template <int DIM, class T>
+inline double ParametersCommon<DIM, T>::pT() const {
+  return momentum().perp();
+}
+
+template <int DIM, class T>
+inline double ParametersCommon<DIM, T>::eta() const {
+  return momentum().eta();
+}
+
+template <int DIM, class T>
+inline constexpr bool ParametersCommon<DIM, T>::isCharged() const {
+  if constexpr (std::is_same<T, Trk::Neutral>::value) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+template <int DIM, class T>
+inline Amg::Vector2D ParametersCommon<DIM, T>::localPosition() const {
+  return Amg::Vector2D(m_parameters[Trk::loc1], m_parameters[Trk::loc2]);
+}
+
+template <int DIM, class T>
+inline void ParametersCommon<DIM, T>::setParameters(
+  const AmgVector(DIM) & param) {
+  m_parameters = param;
+}
+
+template <int DIM, class T>
+inline void ParametersCommon<DIM, T>::setCovariance(
+  const AmgSymMatrix(DIM) & cov) {
+  m_covariance = cov;
+}
+
+template <int DIM, class T>
+inline void ParametersCommon<DIM, T>::updateParameters(
+  const AmgVector(DIM)& updatedParameters) {
+  this->updateParametersHelper(updatedParameters);
+}
+
+template <int DIM, class T>
+inline void ParametersCommon<DIM, T>::updateParameters(
+  const AmgVector(DIM) &updatedParameters,
+  const AmgSymMatrix(DIM) & updatedCovariance) {
+  m_covariance = updatedCovariance;
+  this->updateParametersHelper(updatedParameters);
+}
+
+}  // end of namespace Trk
+
diff --git a/Tracking/TrkEvent/TrkPatternParameters/TrkPatternParameters/PatternTrackParameters.h b/Tracking/TrkEvent/TrkPatternParameters/TrkPatternParameters/PatternTrackParameters.h
index 5f65a2dc404..3f412160c48 100755
--- a/Tracking/TrkEvent/TrkPatternParameters/TrkPatternParameters/PatternTrackParameters.h
+++ b/Tracking/TrkEvent/TrkPatternParameters/TrkPatternParameters/PatternTrackParameters.h
@@ -15,7 +15,7 @@
 #ifndef PatternTrackParameters_H
 #define PatternTrackParameters_H
 
-#include "TrkParametersBase/ParametersBase.h"
+#include "TrkParametersBase/ParametersCommon.h"
 #include "TrkParametersBase/Charged.h"
 #include "TrkEventPrimitives/PropDirection.h"
 #include "TrkSurfaces/Surface.h"
@@ -28,14 +28,14 @@ class MsgStream;
 
 namespace Trk {
 
-  class PlaneSurface       ;  
+  class PlaneSurface       ;
   class StraightLineSurface;
   class DiscSurface        ;
   class CylinderSurface    ;
   class PerigeeSurface     ;
   class ConeSurface        ;
 
-  class PatternTrackParameters final : public ParametersBase<5, Trk::Charged>{
+  class PatternTrackParameters final : public ParametersCommon<5, Trk::Charged>{
     public:
       PatternTrackParameters();
       PatternTrackParameters(const PatternTrackParameters&);
@@ -54,7 +54,7 @@ namespace Trk {
       void             changeDirection   ()          ;
       double           transverseMomentum()     const;
 
-      // Methods from ParametersBase
+      // Methods from ParametersCommon
       virtual const Surface&  associatedSurface ()  const override final;
       virtual Amg::Vector3D position() const override final;
       virtual Amg::Vector3D momentum() const override final;
@@ -81,18 +81,18 @@ namespace Trk {
       bool initiate (PatternTrackParameters&, const Amg::Vector2D&,const Amg::MatrixX&);
 
       // Add or remove noise
-      void addNoise   (const NoiseOnSurface&,PropDirection); 
-      void removeNoise(const NoiseOnSurface&,PropDirection); 
+      void addNoise   (const NoiseOnSurface&,PropDirection);
+      void removeNoise(const NoiseOnSurface&,PropDirection);
 
       // Covariance matrix production using jacobian CovNEW = J*CovOLD*Jt
       static AmgSymMatrix(5) newCovarianceMatrix(const AmgSymMatrix(5) &, const double *);
 
       // Print
-      virtual std::ostream& dump(std::ostream&) const override;
-      virtual MsgStream&    dump(MsgStream&   ) const override;
+      std::ostream& dump(std::ostream&) const;
+      MsgStream&    dump(MsgStream&   ) const;
 
     protected:
-      
+
       // Protected data
       SurfaceUniquePtrT<const Surface> m_surface;
 
@@ -128,9 +128,9 @@ namespace Trk {
   // Overload operator
   /////////////////////////////////////////////////////////////////////////////////
 
-  std::ostream& operator << (std::ostream&,const PatternTrackParameters&); 
+  std::ostream& operator << (std::ostream&,const PatternTrackParameters&);
   MsgStream& operator    << (MsgStream&, const PatternTrackParameters& );
- 
+
 } // end of name space Trk
 
 #include "TrkPatternParameters/PatternTrackParameters.icc"
diff --git a/Tracking/TrkEvent/TrkPatternParameters/TrkPatternParameters/PatternTrackParameters.icc b/Tracking/TrkEvent/TrkPatternParameters/TrkPatternParameters/PatternTrackParameters.icc
index fb574ebcda4..1be9002ab4d 100644
--- a/Tracking/TrkEvent/TrkPatternParameters/TrkPatternParameters/PatternTrackParameters.icc
+++ b/Tracking/TrkEvent/TrkPatternParameters/TrkPatternParameters/PatternTrackParameters.icc
@@ -5,7 +5,7 @@
 namespace Trk {
 
 inline PatternTrackParameters::PatternTrackParameters()
-    : ParametersBase<5, Trk::Charged>() {
+    : ParametersCommon<5, Trk::Charged>() {
   m_parameters.setZero();
 }
 
-- 
GitLab