diff --git a/Tr/TrackKernel/TrackKernel/LinearStateZTraj.h b/Tr/TrackKernel/TrackKernel/LinearStateZTraj.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a83e26204d9336ca2092f5e4dfb93f76f95ee28
--- /dev/null
+++ b/Tr/TrackKernel/TrackKernel/LinearStateZTraj.h
@@ -0,0 +1,82 @@
+#ifndef LINEARSTATEZTRAJ_H
+#define LINEARSTATEZTRAJ_H
+
+#include "TrackKernel/ZTrajectory.h"
+
+
+
+
+namespace LHCb
+{
+  // ==========================================================================
+  /** @class LinearStateZTraj
+   * 
+   *  ZTrajectory class for a simple line parametrized by a State. The
+   *  difference with StateZTraj is that this one cannot account for
+   *  bending in a field. However, it does provide a correct covariance
+   *  matrix in the call to 'state(z)', which unfortunately doesn't.
+   *
+   *  @author Wouter Hulsbergen
+   *  @date 2018-05-25
+   */
+  class LinearStateZTraj : public ZTrajectory
+  {
+  private:
+    const LHCb::State m_state ; /// state on which trajectory is based
+  public:
+    /// Constructor from a state
+    LinearStateZTraj( const LHCb::State& state ) : m_state{state} {}
+    /// Clone
+    std::unique_ptr<LHCb::Trajectory> clone() const override final {
+      return std::unique_ptr<LHCb::Trajectory>{new LinearStateZTraj{*this}}; }
+    /// Return the cached state
+    const LHCb::State& state() const { return m_state ; }
+    /// Position at location z
+    Point position( double z ) const override final {
+      return Point{m_state.x() + (z-m_state.z())*m_state.tx(),m_state.y() + (z-m_state.z())*m_state.ty(),1.0} ; }
+    /// First derivative of position to z
+    Vector direction( double /*z*/ ) const override final { return Vector{m_state.tx(),m_state.ty(),1.0} ; }
+    /// Second derivative of position to z
+    Vector curvature( double /*z*/ ) const override final { return Vector{0,0,0} ; }
+    /// Distance in z until the deviation from the linear
+    /// approximation differs from this trajectory by a given tolerance.
+    double distTo1stError( double /*z*/, double /*tolerance*/, int /*pathDirection*/ ) const override final { return 10*Gaudi::Units::km ; }
+    /// Distance in z until the deviation from the quadratic
+    /// approximation differs from this trajectory by a given tolerance.
+    double distTo2ndError( double /*z*/, double /*tolerance*/, int /*pathDirection*/ ) const override final { return 10*Gaudi::Units::km ; }
+    /// Create a parabolic approximation to the trajectory
+    void expansion(  double z, Gaudi::XYZPoint& p, Gaudi::XYZVector& dp, Gaudi::XYZVector& ddp  ) const override final
+    {
+      p  = position(z) ;
+      dp = direction(z) ;
+      ddp = curvature(z) ;
+    }
+    /// Arclength of total trajectory
+    using ZTrajectory::arclength;
+    /// Arclength between 2 z -locations
+    double arclength(double z1, double z2) const override final { return (z2-z1)*direction(z1).R() ; }
+    /// Estimate for expansion parameter 'z' closest to point
+    double muEstimate(const Point& p) const override final { return p.z() ; }
+    /// return a state at position z
+    virtual LHCb::State state( double z ) const override final
+    {
+      LHCb::State rc = m_state ;
+      rc.linearTransportTo( z ) ;
+      return rc ;
+    }
+    /// return a state vector at position z
+    virtual LHCb::StateVector stateVector( double z ) const override final
+    {
+      const double dz = z - m_state.z() ;
+      return LHCb::StateVector{Gaudi::TrackVector{m_state.x()+dz*m_state.tx(),
+	    m_state.y()+dz*m_state.ty(),
+	    m_state.tx(),m_state.ty(),m_state.qOverP()},z} ;
+    }
+    /// return the set of reference statevectors for this parameterization (if any)
+    virtual std::vector<StateVector> refStateVectors() const override final {
+      return std::vector<StateVector>{StateVector{m_state.stateVector(),m_state.z()}}; }
+  } ;
+}
+
+
+#endif