From ced1dfec49e0fc6bcf4c2e342595a04bbb572726 Mon Sep 17 00:00:00 2001
From: Gerhard Raven <gerhard.raven@nikhef.nl>
Date: Mon, 31 Dec 2018 00:47:09 +0100
Subject: [PATCH 1/2] add forward compatible TrackFunctors

---
 Tr/TrackKernel/TrackKernel/TrackFunctors.h | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 Tr/TrackKernel/TrackKernel/TrackFunctors.h

diff --git a/Tr/TrackKernel/TrackKernel/TrackFunctors.h b/Tr/TrackKernel/TrackKernel/TrackFunctors.h
new file mode 100644
index 00000000000..819ae7b5078
--- /dev/null
+++ b/Tr/TrackKernel/TrackKernel/TrackFunctors.h
@@ -0,0 +1,42 @@
+/*****************************************************************************\
+* (c) Copyright 2018 CERN for the benefit of the LHCb Collaboration           *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+#pragma once
+
+#include "Event/Track.h"
+
+namespace LHCb::Event::v1 {
+
+inline const TrackFitResult* fitResult( const Track& t ) {
+    return t.fitResult();
+}
+
+inline TrackFitResult* fitResult( Track& t ) {
+    return t.fitResult();
+}
+
+inline auto measurements( const Track& t ) {
+    return t.measurements();
+}
+
+inline auto nodes( const Track& t ) {
+    return t.nodes();
+}
+
+inline auto nMeasurements( const Track& t ) {
+    return t.nMeasurements();
+}
+
+inline auto nMeasurementsRemoved( const Track& t ) {
+    return t.nMeasurementsRemoved();
+}
+
+}
+
-- 
GitLab


From f8006799a1b63feaad294170c46e1b2270fde858 Mon Sep 17 00:00:00 2001
From: Gerhard Raven <gerhard.raven@nikhef.nl>
Date: Tue, 8 Jan 2019 19:46:17 +0100
Subject: [PATCH 2/2] Add closestState to v1 TrackFunctors

... and use it in VeloExpectation, MuonTrackAlignMonitor,
TrackCaloMatchMonitor, Track2Calo, Track2CaloFuture, TrackExtrapolator,
UTHitExpectation, VPExpectation, THitExpectation, TTHitExpectation,
TrackBuildCloneTable, CaloTrackTool and CaloFutureTrackTool
---
 Calo/CaloPIDs/CMakeLists.txt                  |   5 +-
 Calo/CaloPIDs/src/CaloTrackTool.h             |  21 +--
 Calo/CaloTools/CMakeLists.txt                 |   5 +-
 Calo/CaloTools/src/Track2Calo.cpp             |  30 ++--
 CaloFuture/CaloFuturePIDs/CMakeLists.txt      |   5 +-
 .../src/CaloFutureTrackTool.cpp               |   3 +-
 CaloFuture/CaloFutureTools/CMakeLists.txt     |   5 +-
 .../CaloFutureTools/src/Track2CaloFuture.cpp  |  31 +++--
 Muon/MuonTrackMonitor/CMakeLists.txt          |   5 +-
 .../src/MuonTrackAligMonitor.cpp              | 131 +++++++++---------
 Tr/TrackExtrapolators/CMakeLists.txt          |   2 +-
 .../src/TrackExtrapolator.cpp                 |   9 +-
 Tr/TrackKernel/TrackKernel/TrackFunctors.h    |  28 ++++
 Tr/TrackMonitors/CMakeLists.txt               |   2 +-
 .../src/TrackCaloMatchMonitor.cpp             |   5 +-
 Tr/TrackTools/src/THitExpectation.cpp         |   5 +-
 Tr/TrackTools/src/TTHitExpectation.cpp        |   9 +-
 Tr/TrackTools/src/UTHitExpectation.cpp        |   9 +-
 Tr/TrackTools/src/VPExpectation.cpp           |   5 +-
 Tr/TrackTools/src/VeloExpectation.cpp         |   3 +-
 Tr/TrackUtils/src/TrackBuildCloneTable.cpp    |   3 +-
 21 files changed, 192 insertions(+), 129 deletions(-)

diff --git a/Calo/CaloPIDs/CMakeLists.txt b/Calo/CaloPIDs/CMakeLists.txt
index 14c76f512ce..d71c0a85b5c 100644
--- a/Calo/CaloPIDs/CMakeLists.txt
+++ b/Calo/CaloPIDs/CMakeLists.txt
@@ -19,6 +19,7 @@ gaudi_depends_on_subdirs(Calo/CaloInterfaces
                          Kernel/LHCbKernel
                          Kernel/LHCbMath
                          Kernel/Relations
+                         Tr/TrackKernel
                          Tr/TrackInterfaces)
 
 find_package(AIDA)
@@ -30,8 +31,8 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS})
 
 gaudi_add_module(CaloPIDs
                  src/*.cpp
-                 INCLUDE_DIRS AIDA Tr/TrackInterfaces
-                 LINK_LIBRARIES CaloUtils GaudiAlgLib LHCbKernel LHCbMathLib RelationsLib)
+                 INCLUDE_DIRS AIDA Tr/TrackInterfaces Tr/TrackKernel
+                 LINK_LIBRARIES CaloUtils GaudiAlgLib TrackKernel LHCbKernel LHCbMathLib RelationsLib)
 
 gaudi_install_python_modules()
 
diff --git a/Calo/CaloPIDs/src/CaloTrackTool.h b/Calo/CaloPIDs/src/CaloTrackTool.h
index 86047f40c24..f15732a4120 100644
--- a/Calo/CaloPIDs/src/CaloTrackTool.h
+++ b/Calo/CaloPIDs/src/CaloTrackTool.h
@@ -26,6 +26,7 @@
 #include "CaloInterfaces/ICaloDigits4Track.h"
 #include "TrackInterfaces/ITrackExtrapolator.h"
 #include "CaloDet/DeCalorimeter.h"
+#include "TrackKernel/TrackFunctors.h"
 
 //==============================================================================
 
@@ -113,7 +114,7 @@ namespace Calo
     inline MsgStream& print
     ( MsgStream&         stream ,
       const LHCb::Track* track  ) const ;
-    
+
     /// print the short infomration about track flags
     inline MsgStream& print
     ( const LHCb::Track* track             ,
@@ -134,25 +135,25 @@ namespace Calo
       {"TrackLinearExtrapolator/Linear"};
 
     Gaudi::Property<float> m_fastZ
-      {this, "zForFastExtrapolator", 
-      10.0 * Gaudi::Units::meter, 
+      {this, "zForFastExtrapolator",
+      10.0 * Gaudi::Units::meter,
       "z-position of 'linear' extrapolation"};
 
     Gaudi::Property<float> m_tolerance
-      {this, "Tolerance", 
-      2.0 * Gaudi::Units::mm, 
+      {this, "Tolerance",
+      2.0 * Gaudi::Units::mm,
       "plane extrapolation tolerance"};
 
     Gaudi::Property<float> m_cosTolerance
-      {this, "CosTolerance", 
-      ::cos( 0.1 * Gaudi::Units::mrad ), 
+      {this, "CosTolerance",
+      ::cos( 0.1 * Gaudi::Units::mrad ),
       "plane extrapolation angular tolerance"};
 
     Gaudi::Property<unsigned int> m_maxIter
-      {this, "MaxPlaneIterations", 5, 
+      {this, "MaxPlaneIterations", 5,
       "maximal number of iterations"};
 
-    Gaudi::Property<std::string> m_detectorName 
+    Gaudi::Property<std::string> m_detectorName
       {this, "Calorimeter"};
 
     // detector element
@@ -191,7 +192,7 @@ Calo::CaloTrackTool::propagate
   LHCb::State&            state ,
   const LHCb::Tr::PID pid   ) const
 {
-  state = track.closestState ( plane ) ;
+  state = closestState(track, plane ) ;
   if ( ::fabs( plane.Distance ( state.position() ) ) < tolerance() )
   { return StatusCode::SUCCESS ; }
   return propagate ( state , plane , pid ) ;
diff --git a/Calo/CaloTools/CMakeLists.txt b/Calo/CaloTools/CMakeLists.txt
index 6298a6ca858..de5eb007df0 100644
--- a/Calo/CaloTools/CMakeLists.txt
+++ b/Calo/CaloTools/CMakeLists.txt
@@ -23,6 +23,7 @@ gaudi_depends_on_subdirs(Calo/CaloInterfaces
                          Kernel/LHCbKernel
                          Kernel/LHCbMath
                          Kernel/Relations
+                         Tr/TrackKernel
                          Tr/TrackInterfaces)
 
 find_package(Boost)
@@ -32,5 +33,5 @@ include_directories(SYSTEM ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
 
 gaudi_add_module(CaloTools
                  src/*.cpp
-                 INCLUDE_DIRS Tr/TrackInterfaces XGBoost
-                 LINK_LIBRARIES CaloUtils CaloDetLib LinkerEvent RecEvent TrackEvent GaudiAlgLib LHCbKernel LHCbMathLib RelationsLib XGBoost)
+                 INCLUDE_DIRS Tr/TrackInterfaces Tr/TrackKernel XGBoost
+                 LINK_LIBRARIES CaloUtils CaloDetLib LinkerEvent RecEvent TrackEvent GaudiAlgLib TrackKernel LHCbKernel LHCbMathLib RelationsLib XGBoost)
diff --git a/Calo/CaloTools/src/Track2Calo.cpp b/Calo/CaloTools/src/Track2Calo.cpp
index bdcff10099f..e2e4efb050a 100644
--- a/Calo/CaloTools/src/Track2Calo.cpp
+++ b/Calo/CaloTools/src/Track2Calo.cpp
@@ -8,7 +8,7 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files 
+// Include files
 
 // LHCb
 #include "GaudiKernel/Point3DTypes.h"
@@ -19,9 +19,17 @@
 #include "Event/CaloCluster.h"
 #include "Event/CaloHypo.h"
 #include "TrackInterfaces/ITrackExtrapolator.h"
+#include "TrackKernel/TrackFunctors.h"
 // local
 #include "Track2Calo.h"
 
+namespace {
+
+// fix name clash with Track2Calo::closestState
+auto closest_state( const LHCb::Track& t, const Gaudi::Plane3D& p)
+{ return closestState(t,p); }
+
+}
 //-----------------------------------------------------------------------------
 // Implementation file for class : Track2Calo
 //
@@ -50,7 +58,7 @@ StatusCode Track2Calo::initialize(){
   StatusCode sc = GaudiTool::initialize();
   if (sc.isFailure()) return Error("Failed to initialize", sc);
   m_extrapolator = tool<ITrackExtrapolator>( m_extrapolatorType,"Extrapolator",this );
-  return StatusCode::SUCCESS;  
+  return StatusCode::SUCCESS;
 }
 //=============================================================================
 bool Track2Calo::match(const LHCb::Track* track, std::string det,CaloPlane::Plane plane , double delta, const LHCb::Tr::PID pid ){
@@ -60,7 +68,7 @@ bool Track2Calo::match(const LHCb::Track* track, std::string det,CaloPlane::Plan
   m_state  = caloState(plane, delta, pid);
   m_cell   = m_calo->Cell( m_state.position() );
   m_valid  = m_calo->valid( m_cell );
-  if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) 
+  if( UNLIKELY( msgLevel(MSG::DEBUG) ) )
     debug() << " Track2Calo setting [" << *track <<","<< det<<"] status : " <<m_status << endmsg;
   return m_status;
 }
@@ -69,16 +77,16 @@ LHCb::State Track2Calo::caloState(CaloPlane::Plane plane , double delta, const L
 
   LHCb::State state; // empty state
   if( !m_status ) return state;
-  
+
   // get caloPlane
-  ROOT::Math::Plane3D refPlane = m_calo->plane( plane );
+  Gaudi::Plane3D refPlane = m_calo->plane( plane );
   // propagate state to refPlane
-  LHCb::State calostate( m_track->closestState( refPlane ) );
+  LHCb::State calostate = closest_state( *m_track, refPlane );
   StatusCode sc = m_extrapolator->propagate ( calostate, refPlane , m_tolerance , pid  );
-  if(sc.isFailure())return state;  
+  if(sc.isFailure())return state;
+
+  if( 0. == delta)return calostate;
 
-  if( 0. == delta)return calostate; 
-  
   Gaudi::XYZVector dir (calostate.tx(), calostate.ty(), 1.);
   Gaudi::XYZPoint  point = calostate.position() + delta * dir/dir.R();
   // extrapolate to the new point
@@ -89,7 +97,7 @@ LHCb::State Track2Calo::caloState(CaloPlane::Plane plane , double delta, const L
 //=============================================================================
 bool Track2Calo::setting(const LHCb::Track* track){
   m_track   = track;
-  return ( NULL == m_track) ? false : true;
+  return m_track!=nullptr;
 }
 
 
@@ -119,7 +127,7 @@ LHCb::State Track2Calo::closestState(LHCb::CaloCellID cellID,const LHCb::Tr::PID
 LHCb::State Track2Calo::closestState(double x, double y,const LHCb::Tr::PID pid){
   LHCb::State state; // empty state
   if( !m_status ) return state;
-  
+
   // get state on Front of Ecal
   LHCb::State calostate = caloState( CaloPlane::Front);
   if(calostate.z() == 0 ) return state;
diff --git a/CaloFuture/CaloFuturePIDs/CMakeLists.txt b/CaloFuture/CaloFuturePIDs/CMakeLists.txt
index 69a1f9b7440..2f895327bd7 100644
--- a/CaloFuture/CaloFuturePIDs/CMakeLists.txt
+++ b/CaloFuture/CaloFuturePIDs/CMakeLists.txt
@@ -19,6 +19,7 @@ gaudi_depends_on_subdirs(CaloFuture/CaloFutureInterfaces
                          Kernel/LHCbKernel
                          Kernel/LHCbMath
                          Kernel/Relations
+                         Tr/TrackKernel
                          Tr/TrackInterfaces)
 
 find_package(AIDA)
@@ -30,8 +31,8 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS})
 
 gaudi_add_module(CaloFuturePIDs
                  src/*.cpp
-                 INCLUDE_DIRS AIDA Tr/TrackInterfaces
-                 LINK_LIBRARIES CaloFutureUtils GaudiAlgLib LHCbKernel LHCbMathLib RelationsLib)
+                 INCLUDE_DIRS AIDA Tr/TrackInterfaces Tr/TrackKernel
+                 LINK_LIBRARIES CaloFutureUtils GaudiAlgLib LHCbKernel TrackKernel LHCbMathLib RelationsLib)
 
 gaudi_install_python_modules()
 
diff --git a/CaloFuture/CaloFuturePIDs/src/CaloFutureTrackTool.cpp b/CaloFuture/CaloFuturePIDs/src/CaloFutureTrackTool.cpp
index a5a75681f2c..14f5eb275bb 100644
--- a/CaloFuture/CaloFuturePIDs/src/CaloFutureTrackTool.cpp
+++ b/CaloFuture/CaloFuturePIDs/src/CaloFutureTrackTool.cpp
@@ -10,6 +10,7 @@
 \*****************************************************************************/
 // Include files
 #include "CaloFutureTrackTool.h"
+#include "TrackKernel/TrackFunctors.h"
 
 // ============================================================================
 /** @file
@@ -62,7 +63,7 @@ void CaloFuture::CaloFutureTrackTool::_setProperty(const std::string &p,
 
 StatusCode CaloFuture::CaloFutureTrackTool::propagate(const LHCb::Track& track, const Gaudi::Plane3D& plane, LHCb::State& state, const LHCb::Tr::PID pid) const
 {
-  state = track.closestState( plane );
+  state = closestState( track, plane );
   if ( std::abs( plane.Distance ( state.position() ) ) < tolerance() )
   { return StatusCode::SUCCESS ; }
   return propagate ( state , plane , pid ) ;
diff --git a/CaloFuture/CaloFutureTools/CMakeLists.txt b/CaloFuture/CaloFutureTools/CMakeLists.txt
index bd942cba5ba..da0eeb5c455 100644
--- a/CaloFuture/CaloFutureTools/CMakeLists.txt
+++ b/CaloFuture/CaloFutureTools/CMakeLists.txt
@@ -24,6 +24,7 @@ gaudi_depends_on_subdirs(CaloFuture/CaloFutureInterfaces
                          Kernel/LHCbKernel
                          Kernel/LHCbMath
                          Kernel/Relations
+                         Tr/TrackKernel
                          Tr/TrackInterfaces)
 
 find_package(Boost)
@@ -33,5 +34,5 @@ include_directories(SYSTEM ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
 
 gaudi_add_module(CaloFutureTools
                  src/*.cpp
-                 INCLUDE_DIRS Tr/TrackInterfaces XGBoost
-                 LINK_LIBRARIES CaloFutureUtils CaloDetLib LinkerEvent RecEvent TrackEvent GaudiAlgLib LHCbKernel LHCbMathLib RelationsLib XGBoost)
+                 INCLUDE_DIRS Tr/TrackInterfaces Tr/TrackKernel XGBoost
+                 LINK_LIBRARIES CaloFutureUtils CaloDetLib LinkerEvent RecEvent TrackEvent GaudiAlgLib TrackKernel LHCbKernel LHCbMathLib RelationsLib XGBoost)
diff --git a/CaloFuture/CaloFutureTools/src/Track2CaloFuture.cpp b/CaloFuture/CaloFutureTools/src/Track2CaloFuture.cpp
index 2728d286931..614534911ad 100644
--- a/CaloFuture/CaloFutureTools/src/Track2CaloFuture.cpp
+++ b/CaloFuture/CaloFutureTools/src/Track2CaloFuture.cpp
@@ -8,7 +8,7 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files 
+// Include files
 
 // LHCb
 #include "GaudiKernel/Point3DTypes.h"
@@ -19,9 +19,20 @@
 #include "Event/CaloCluster.h"
 #include "Event/CaloHypo.h"
 #include "TrackInterfaces/ITrackExtrapolator.h"
+#include "TrackKernel/TrackFunctors.h"
+
 // local
 #include "Track2CaloFuture.h"
 
+namespace {
+
+// fix name clash with Track2Calo::closestState
+auto closest_state( const LHCb::Track& t, const Gaudi::Plane3D& p)
+{ return closestState(t,p); }
+
+}
+
+
 //-----------------------------------------------------------------------------
 // Implementation file for class : Track2CaloFuture
 //
@@ -50,7 +61,7 @@ StatusCode Track2CaloFuture::initialize(){
   StatusCode sc = GaudiTool::initialize();
   if (sc.isFailure()) return Error("Failed to initialize", sc);
   m_extrapolator = tool<ITrackExtrapolator>( m_extrapolatorType,"Extrapolator",this );
-  return StatusCode::SUCCESS;  
+  return StatusCode::SUCCESS;
 }
 //=============================================================================
 bool Track2CaloFuture::match(const LHCb::Track* track, std::string det,CaloPlane::Plane plane , double delta, const LHCb::Tr::PID pid ){
@@ -60,7 +71,7 @@ bool Track2CaloFuture::match(const LHCb::Track* track, std::string det,CaloPlane
   m_state  = caloState(plane, delta, pid);
   m_cell   = m_calo->Cell( m_state.position() );
   m_valid  = m_calo->valid( m_cell );
-  if( UNLIKELY( msgLevel(MSG::DEBUG) ) ) 
+  if( UNLIKELY( msgLevel(MSG::DEBUG) ) )
     debug() << " Track2CaloFuture setting [" << *track <<","<< det<<"] status : " <<m_status << endmsg;
   return m_status;
 }
@@ -69,16 +80,16 @@ LHCb::State Track2CaloFuture::caloState(CaloPlane::Plane plane , double delta, c
 
   LHCb::State state; // empty state
   if( !m_status ) return state;
-  
+
   // get caloPlane
   ROOT::Math::Plane3D refPlane = m_calo->plane( plane );
   // propagate state to refPlane
-  LHCb::State calostate( m_track->closestState( refPlane ) );
+  LHCb::State calostate( closest_state(*m_track, refPlane ) );
   StatusCode sc = m_extrapolator->propagate ( calostate, refPlane , m_tolerance , pid  );
-  if(sc.isFailure())return state;  
+  if(sc.isFailure())return state;
+
+  if( 0. == delta)return calostate;
 
-  if( 0. == delta)return calostate; 
-  
   Gaudi::XYZVector dir (calostate.tx(), calostate.ty(), 1.);
   Gaudi::XYZPoint  point = calostate.position() + delta * dir/dir.R();
   // extrapolate to the new point
@@ -89,7 +100,7 @@ LHCb::State Track2CaloFuture::caloState(CaloPlane::Plane plane , double delta, c
 //=============================================================================
 bool Track2CaloFuture::setting(const LHCb::Track* track){
   m_track   = track;
-  return ( NULL == m_track) ? false : true;
+  return m_track!=nullptr;
 }
 
 
@@ -119,7 +130,7 @@ LHCb::State Track2CaloFuture::closestState(LHCb::CaloCellID cellID,const LHCb::T
 LHCb::State Track2CaloFuture::closestState(double x, double y,const LHCb::Tr::PID pid){
   LHCb::State state; // empty state
   if( !m_status ) return state;
-  
+
   // get state on Front of Ecal
   LHCb::State calostate = caloState( CaloPlane::Front);
   if(calostate.z() == 0 ) return state;
diff --git a/Muon/MuonTrackMonitor/CMakeLists.txt b/Muon/MuonTrackMonitor/CMakeLists.txt
index 57c274526f1..73c17d1b7e3 100644
--- a/Muon/MuonTrackMonitor/CMakeLists.txt
+++ b/Muon/MuonTrackMonitor/CMakeLists.txt
@@ -20,6 +20,7 @@ gaudi_depends_on_subdirs(Det/MuonDet
                          Event/RecEvent
                          Event/TrackEvent
                          Tr/TrackInterfaces
+                         Tr/TrackKernel
                          GaudiAlg
                          Tf/TrackSys
                          Tr/TrackFitter
@@ -33,8 +34,8 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS})
 
 gaudi_add_module(MuonTrackMonitor
                  src/*.cpp
-                 INCLUDE_DIRS AIDA Tr/TrackInterfaces
-                 LINK_LIBRARIES MuonDetLib HltEvent LinkerEvent MCEvent RecEvent TrackEvent GaudiAlgLib)
+                 INCLUDE_DIRS AIDA Tr/TrackInterfaces Tr/TrackKernel
+                 LINK_LIBRARIES MuonDetLib HltEvent LinkerEvent MCEvent RecEvent TrackEvent TrackKernel GaudiAlgLib)
 
 gaudi_install_python_modules()
 
diff --git a/Muon/MuonTrackMonitor/src/MuonTrackAligMonitor.cpp b/Muon/MuonTrackMonitor/src/MuonTrackAligMonitor.cpp
index cc3eabb1b73..fe5dc789b4b 100644
--- a/Muon/MuonTrackMonitor/src/MuonTrackAligMonitor.cpp
+++ b/Muon/MuonTrackMonitor/src/MuonTrackAligMonitor.cpp
@@ -8,7 +8,7 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
-// Include files 
+// Include files
 
 // local
 #include "MuonTrackAligMonitor.h"
@@ -20,6 +20,7 @@
 #include "AIDA/IProfile2D.h"
 
 #include "MuonDet/DeMuonDetector.h"
+#include "TrackKernel/TrackFunctors.h"
 
 #include <boost/lexical_cast.hpp>
 
@@ -28,36 +29,36 @@ using namespace Gaudi::Units;
 //-----------------------------------------------------------------------------
 // Implementation file for class : MuonTrackAligMonitor
 //
-// 2009-02-25 
-//                                                                              
-//                                                        .--. ::/.             
-//    a.k.a. "ciupeta"                                 -//:::::////.            
-//                                                    :/:::::::/++o/            
-//    a Ferrara speciality                        ..-//::::::/++oo:             
-//                                              ://::::::///+/:-.               
-//                                        -://::::---::://+o                    
-//                                   .-::/::::::://:///++++:                    
-//       ...                .---::///:::/+++/:::::/+/o+/:-                      
-//   .-///////:--.-:///::--///:::/+/++ooo++++////::/:                           
-//  :o++//::::::++/::::::/+////+o++++/://////+++/////                           
-//   /ooo++/:/:++/////::/+++/o+++/++//::::////++++++o-                          
-//     .---:/oooo++++++/+oo++o++++++//://oo+/:-::::/+/                          
-//           :osssssooooosooossoo+//////::::::::::::///::-.-::--.               
-//              ....   .://:-.+o+////::///////:::::::/::::/::////:              
-//                            .o+//://////++++////////:-///////:--:-::::--.     
-//                            -+//::///+++oooooooo++++//++++++/--:::::::////:   
-//                          .//+/////++oosssssysssssosooooooo++/++/////+o+/::/  
-//                      .-://::/++o++oossso/:::/+oso: .-/++:../sssoooooooo+++o  
-//                     /+//////::+osssss/.                      :+sso:.  .---.  
-//                    :/::://++++oo///:                                         
-//                  .:/::--:/+ooo/.                                             
-//                :+////////++..                                                
-//              /+++////+++oo.                                                  
-//            .//+ooooooosso.                                                   
-//            ++/::/+o/::-.                                                     
-//           .sooso+/                                                           
-//            /oo+:.                                                            
-//                                                                              
+// 2009-02-25
+//
+//                                                        .--. ::/.
+//    a.k.a. "ciupeta"                                 -//:::::////.
+//                                                    :/:::::::/++o/
+//    a Ferrara speciality                        ..-//::::::/++oo:
+//                                              ://::::::///+/:-.
+//                                        -://::::---::://+o
+//                                   .-::/::::::://:///++++:
+//       ...                .---::///:::/+++/:::::/+/o+/:-
+//   .-///////:--.-:///::--///:::/+/++ooo++++////::/:
+//  :o++//::::::++/::::::/+////+o++++/://////+++/////
+//   /ooo++/:/:++/////::/+++/o+++/++//::::////++++++o-
+//     .---:/oooo++++++/+oo++o++++++//://oo+/:-::::/+/
+//           :osssssooooosooossoo+//////::::::::::::///::-.-::--.
+//              ....   .://:-.+o+////::///////:::::::/::::/::////:
+//                            .o+//://////++++////////:-///////:--:-::::--.
+//                            -+//::///+++oooooooo++++//++++++/--:::::::////:
+//                          .//+/////++oosssssysssssosooooooo++/++/////+o+/::/
+//                      .-://::/++o++oossso/:::/+oso: .-/++:../sssoooooooo+++o
+//                     /+//////::+osssss/.                      :+sso:.  .---.
+//                    :/::://++++oo///:
+//                  .:/::--:/+ooo/.
+//                :+////////++..
+//              /+++////+++oo.
+//            .//+ooooooosso.
+//            ++/::/+o/::-.
+//           .sooso+/
+//            /oo+:.
+//
 //-----------------------------------------------------------------------------
 
 // Declaration of the Algorithm Factory
@@ -66,7 +67,7 @@ DECLARE_COMPONENT( MuonTrackAligMonitor )
 MuonTrackAligMonitor::MuonTrackAligMonitor(const std::string &name,
                                            ISvcLocator *pSvcLocator)
 : Consumer(name, pSvcLocator, {KeyValue{"Input", LHCb::MuonPIDLocation::Default},
-                               KeyValue{"TrackInput", "/Event/Rec/Track/MuonFit"}}) 
+                               KeyValue{"TrackInput", "/Event/Rec/Track/MuonFit"}})
 {
   declareProperty("Extrapolator", m_extrapolator);
   declareProperty( "Chi2Calculator" , m_chi2Calculator  );
@@ -84,11 +85,11 @@ StatusCode MuonTrackAligMonitor::initialize() {
   if(!Consumer::initialize())
     return StatusCode::FAILURE;
 
-  m_muonDet = getDet<DeMuonDetector>(DeMuonLocation::Default); 
+  m_muonDet = getDet<DeMuonDetector>(DeMuonLocation::Default);
   if(!m_muonDet){
     err()<<"error retrieving the Muon detector element "<<endmsg;
     return StatusCode::FAILURE;
-  }  
+  }
 
   GaudiAlg::HistoID name;
   std::string title;
@@ -102,11 +103,11 @@ StatusCode MuonTrackAligMonitor::initialize() {
   if(m_notOnline) {
     name = "p";
     m_h_p = book1D( name, name, 0, 100, 100);
-    
+
     if(m_expertMode) {
       name = "x_vs_y";
       m_h_xy = book2D( name, name, -4000, 4000, 80, -4000, 4000, 80);
-      
+
       name = "tx_vs_ty";
       m_h_txty = book2D( name, name, ulow, uhigh, 100, ulow, uhigh, 100);
     }
@@ -121,26 +122,26 @@ StatusCode MuonTrackAligMonitor::initialize() {
     // x coord
     name = "prof_resx_x";
     m_p_resxx = bookProfile1D( name, "profile res. x vs x", -4000, 4000, 80);
-    
+
     name = "prof_resx_y";
     m_p_resxy = bookProfile1D( name, "profile res. x vs y", -4000, 4000, 80);
-    
+
     if(m_notOnline) {
       name = "prof_resx_tx";
       m_p_resxtx = bookProfile1D( name, "profile res. x vs tx", ulow, uhigh, 60);
-      
+
       name = "prof_resx_ty";
       m_p_resxty = bookProfile1D( name, "profile res. x vs ty", ulow, uhigh, 60);
-      
+
       name = "prof_restx_x";
       m_p_restxx = bookProfile1D( name, "profile res. tx vs x", -4000, 4000, 80);
-      
+
       name = "prof_restx_y";
       m_p_restxy = bookProfile1D( name, "profile res. tx vs y", -4000, 4000, 80);
-      
+
       name = "prof_restx_tx";
       m_p_restxtx = bookProfile1D( name, "profile res. tx vs tx", ulow, uhigh, 60);
-      
+
       name = "prof_restx_ty";
       m_p_restxty = bookProfile1D( name, "profile res. tx vs ty", ulow, uhigh, 60);
     }
@@ -155,31 +156,31 @@ StatusCode MuonTrackAligMonitor::initialize() {
     if(m_notOnline) {
       name = "prof_resy_tx";
       m_p_resytx = bookProfile1D( name, "profile res. y vs tx", ulow, uhigh, 60);
-      
+
       name = "prof_resy_ty";
       m_p_resyty = bookProfile1D( name, "profile res. y vs ty", ulow, uhigh, 60);
-      
+
       name = "prof_resty_x";
       m_p_restyx = bookProfile1D( name, "profile res. ty vs x", -4000, 4000, 80);
-      
+
       name = "prof_resty_y";
       m_p_restyy = bookProfile1D( name, "profile res. ty vs y", -4000, 4000, 80);
-      
+
       name = "prof_resty_tx";
       m_p_restytx = bookProfile1D( name, "profile res. ty vs tx", ulow, uhigh, 60);
-      
+
       name = "prof_resty_ty";
       m_p_restyty = bookProfile1D( name, "profile res. ty vs ty", ulow, uhigh, 60);
     }
   }
-  
+
   if(m_notOnline) {
     for(int i = 0; i < m_muonDet->stations(); i++){
       name = "residxL_aSide_station_$" + boost::lexical_cast<std::string>(i);
       title = "X resid from Long tracks A side M" + boost::lexical_cast<std::string>(i+1);
       m_h_resxL_a.push_back( book1D( name, title.c_str(), -500, 500, 100 ));
       name = "residyL_aSide_station_$" + boost::lexical_cast<std::string>(i);
-      title = "Y resid from Long tracks A side M" + boost::lexical_cast<std::string>(i+1);      
+      title = "Y resid from Long tracks A side M" + boost::lexical_cast<std::string>(i+1);
       m_h_resyL_a.push_back( book1D( name, title.c_str(), -500, 500, 100 ));
       name = "residxL_cSide_station_$" + boost::lexical_cast<std::string>(i);
       title = "X resid from Long tracks C side M" + boost::lexical_cast<std::string>(i+1);
@@ -254,8 +255,8 @@ void MuonTrackAligMonitor::operator()(const LHCb::MuonPIDs& pMuids, const LHCb::
         muTrack->chi2PerDoF() < m_chi2nCut && muTrack->nDoF() > 3)) {
       continue;
     }
-    LHCb::State muState = muTrack->closestState(m_zM1);
-    LHCb::State longState = longTrack->closestState(muState.z());
+    LHCb::State muState = closestState(*muTrack,m_zM1);
+    LHCb::State longState = closestState(*longTrack,muState.z());
 
     StatusCode sc = m_extrapolator->propagate(longState, m_zM1, LHCb::Tr::PID::Muon());
     if (sc.isFailure()) {
@@ -313,32 +314,32 @@ void MuonTrackAligMonitor::operator()(const LHCb::MuonPIDs& pMuids, const LHCb::
     double dummy,z;
 
     if (m_LongToMuonMatch) {
-      m_p_resxx->fill( x, resx ); 
+      m_p_resxx->fill( x, resx );
       m_p_resxy->fill( y, resx );
 
       if (m_notOnline) {
-        m_p_resxtx->fill( tx, resx ); 
+        m_p_resxtx->fill( tx, resx );
         m_p_resxty->fill( ty, resx );
-        m_p_restxx->fill( x, restx ); 
-        m_p_restxy->fill( y, restx );          
-        m_p_restxtx->fill( tx, restx ); 
+        m_p_restxx->fill( x, restx );
+        m_p_restxy->fill( y, restx );
+        m_p_restxtx->fill( tx, restx );
         m_p_restxty->fill( ty, restx );
       }
 
-      m_p_resyx->fill( x, resy ); 
+      m_p_resyx->fill( x, resy );
       m_p_resyy->fill( y, resy );
 
       if (m_notOnline) {
-        m_p_resytx->fill( tx, resy ); 
+        m_p_resytx->fill( tx, resy );
         m_p_resyty->fill( ty, resy );
-        m_p_restyx->fill( x, resty ); 
+        m_p_restyx->fill( x, resty );
         m_p_restyy->fill( y, resty );
-        m_p_restytx->fill( tx, resty ); 
+        m_p_restytx->fill( tx, resty );
         m_p_restyty->fill( ty, resty );
         m_h_chi2->fill(chi2);
       }
     }
-      
+
     for(const auto& tile0: muTrack->lhcbIDs()) {
       // Skip if it's not muon
       if(tile0.isMuon())
@@ -372,9 +373,9 @@ void MuonTrackAligMonitor::operator()(const LHCb::MuonPIDs& pMuids, const LHCb::
             tempy = x > 0 ? m_h_resyL_a[ tile.station() ] : m_h_resyL_c[ tile.station() ];
           } else {
             tempx = x > 0 ? m_h_resxM_a[ tile.station() ] : m_h_resxM_c[ tile.station() ];
-            tempy = x > 0 ? m_h_resyM_a[ tile.station() ] : m_h_resyM_c[ tile.station() ];        
-          }            
-          
+            tempy = x > 0 ? m_h_resyM_a[ tile.station() ] : m_h_resyM_c[ tile.station() ];
+          }
+
           tempx->fill( rx );
           tempy->fill( ry );
         }
diff --git a/Tr/TrackExtrapolators/CMakeLists.txt b/Tr/TrackExtrapolators/CMakeLists.txt
index 323a5a976c0..f0d448fb32e 100644
--- a/Tr/TrackExtrapolators/CMakeLists.txt
+++ b/Tr/TrackExtrapolators/CMakeLists.txt
@@ -29,5 +29,5 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} ${EIGEN_IN
 
 gaudi_add_module(TrackExtrapolators
                  src/*.cpp
-                 INCLUDE_DIRS GSL Eigen Tr/TrackInterfaces
+                 INCLUDE_DIRS GSL Eigen Tr/TrackInterfaces Tr/TrackKernel
                  LINK_LIBRARIES GSL DetDescLib TrackEvent GaudiAlgLib TrackKernel PartPropLib)
diff --git a/Tr/TrackExtrapolators/src/TrackExtrapolator.cpp b/Tr/TrackExtrapolators/src/TrackExtrapolator.cpp
index 4f76d5ea97d..616de63e5cd 100644
--- a/Tr/TrackExtrapolators/src/TrackExtrapolator.cpp
+++ b/Tr/TrackExtrapolators/src/TrackExtrapolator.cpp
@@ -13,6 +13,7 @@
 // local
 #include "TrackExtrapolator.h"
 #include "Event/TrackParameters.h"
+#include "TrackKernel/TrackFunctors.h"
 
 #include <math.h>
 
@@ -57,7 +58,7 @@ StatusCode TrackExtrapolator::propagate( const Track& track,
                                          const LHCb::Tr::PID pid ) const
 {
   // get state closest to z
-  state = track.closestState( z );
+  state = closestState( track, z );
 
   // propagate the closest state
   return propagate( state, z, pid );
@@ -73,7 +74,7 @@ StatusCode TrackExtrapolator::propagate( const Track& track,
                                          const LHCb::Tr::PID pid ) const
 {
   // get state closest to z
-  const State& closest = track.closestState( z );
+  const State& closest = closestState( track, z );
   state = LHCb::StateVector( closest.stateVector(), closest.z()) ;
 
   // propagate the closest state
@@ -117,7 +118,7 @@ StatusCode TrackExtrapolator::propagate( const Track& track,
                                          const LHCb::Tr::PID pid ) const
 {
   // get state closest to z of point
-  state = track.closestState( point.z() );
+  state = closestState(track, point.z() );
 
   // propagate the closest state
   return propagate( state, point.z(), pid );
@@ -150,7 +151,7 @@ StatusCode TrackExtrapolator::propagate( const Track& track,
                                          const LHCb::Tr::PID pid ) const
 {
   // get state closest to the plane
-  state = track.closestState( plane );
+  state = closestState( track, plane );
 
   // propagate the closest state
   return propagate( state, plane, tolerance, pid );
diff --git a/Tr/TrackKernel/TrackKernel/TrackFunctors.h b/Tr/TrackKernel/TrackKernel/TrackFunctors.h
index 819ae7b5078..cf74092f0e2 100644
--- a/Tr/TrackKernel/TrackKernel/TrackFunctors.h
+++ b/Tr/TrackKernel/TrackKernel/TrackFunctors.h
@@ -11,6 +11,7 @@
 #pragma once
 
 #include "Event/Track.h"
+#include "Event/TrackFunctor.h"
 
 namespace LHCb::Event::v1 {
 
@@ -38,5 +39,32 @@ inline auto nMeasurementsRemoved( const Track& t ) {
     return t.nMeasurementsRemoved();
 }
 
+inline const LHCb::State& closestState( const Track& trk, double z ) {
+  const auto* fr = fitResult(trk);
+  if ( fr && !fr->nodes().empty() ) {
+      auto iter = std::min_element( fr->nodes().begin(),fr->nodes().end(),
+                                    TrackFunctor::distanceAlongZ(z) );
+      if ( iter == fr->nodes().end() )
+          throw GaudiException( "No state closest to z",__func__,
+                                StatusCode::FAILURE );
+      return (*iter)->state();
+  } else {
+      return trk.closestState(z);
+  }
+}
+
+inline const LHCb::State& closestState( const Track& trk, const Gaudi::Plane3D& plane ) {
+  const auto* fr = fitResult(trk);
+  if ( fr && !fr->nodes().empty() ) {
+    auto iter = std::min_element( fr->nodes().begin(),fr->nodes().end(),
+                                  TrackFunctor::distanceToPlane(plane) );
+    if ( iter == fr->nodes().end() )
+      throw GaudiException( "No state closest to z",__func__,
+                            StatusCode::FAILURE );
+    return (*iter)->state();
+  } else {
+      return trk.closestState(plane);
+  }
+}
 }
 
diff --git a/Tr/TrackMonitors/CMakeLists.txt b/Tr/TrackMonitors/CMakeLists.txt
index 160ac7f9f20..b44b62b12b2 100644
--- a/Tr/TrackMonitors/CMakeLists.txt
+++ b/Tr/TrackMonitors/CMakeLists.txt
@@ -40,7 +40,7 @@ include_directories(SYSTEM ${Boost_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS})
 
 gaudi_add_module(TrackMonitors
                  src/*.cpp
-                 INCLUDE_DIRS GSL AIDA Tr/TrackInterfaces Tf/PatKernel
+                 INCLUDE_DIRS GSL AIDA Tr/TrackInterfaces Tr/TrackKernel Tf/PatKernel
                  LINK_LIBRARIES GSL CaloDetLib MCEvent GenEvent PhysEvent RecEvent TrackEvent HltEvent GaudiAlgLib GaudiUtilsLib PartPropLib LinkerEvent STKernelLib STTELL1Event TrackFitEvent TrackKernel)
 
 gaudi_install_python_modules()
diff --git a/Tr/TrackMonitors/src/TrackCaloMatchMonitor.cpp b/Tr/TrackMonitors/src/TrackCaloMatchMonitor.cpp
index f2045e9b8e0..96a6e794bba 100644
--- a/Tr/TrackMonitors/src/TrackCaloMatchMonitor.cpp
+++ b/Tr/TrackMonitors/src/TrackCaloMatchMonitor.cpp
@@ -18,6 +18,7 @@
 #include "Event/CaloCluster.h"
 #include "Event/CaloPosition.h"
 #include "TrackInterfaces/ITrackExtrapolator.h"
+#include "TrackKernel/TrackFunctors.h"
 #include "CaloDet/DeCalorimeter.h"
 #include "TrackVectorFit/Types.h"
 #include <optional>
@@ -226,7 +227,7 @@ StatusCode TrackCaloMatchMonitor::execute()
   LHCb::Track::Range trackcontainer = get<LHCb::Track::Range>( m_trackLocation.value() ) ;
   for( const LHCb::Track* track: trackcontainer)
     if( !m_requireTHits || track->hasT() ) {
-      const LHCb::State& closest = track->closestState( m_geometricZ  );
+      const LHCb::State& closest = closestState( *track, m_geometricZ  );
       LHCb::StateVector state = { closest.stateVector(), closest.z() };
       m_extrapolator->propagate( state, m_geometricZ ) ;
 
@@ -240,7 +241,7 @@ StatusCode TrackCaloMatchMonitor::execute()
       }
 
       for( const MyCaloPosition& cluster: calopositions) {
-        //state = &(track->closestState(pos.z())) ;
+        //state = &(closestState(*track,pos.z())) ;
         double dz = cluster.pos.z() + m_clusterZCorrection.value() - state.z() ;
         double xtrack = state.x() + state.tx() * dz ;
         double ytrack = state.y() + state.ty() * dz ;
diff --git a/Tr/TrackTools/src/THitExpectation.cpp b/Tr/TrackTools/src/THitExpectation.cpp
index 5cd1a2e2c35..7dccb189197 100644
--- a/Tr/TrackTools/src/THitExpectation.cpp
+++ b/Tr/TrackTools/src/THitExpectation.cpp
@@ -25,6 +25,7 @@
 #include "LHCbMath/GeomFun.h"
 
 #include "TrackInterfaces/ITrackExtrapolator.h"
+#include "TrackKernel/TrackFunctors.h"
 
 #include "THitExpectation.h"
 
@@ -49,7 +50,7 @@ StatusCode THitExpectation::initialize()
 Tf::Tsa::Parabola THitExpectation::xParabola(const LHCb::Track& aTrack, const double z) const{
 
   // find the closest state
-  const LHCb::State& aState = aTrack.closestState(z);
+  const LHCb::State& aState = closestState(aTrack,z);
   LHCb::StateVector stateVector(aState.position(),aState.slopes());
   m_extrapolator->propagate(stateVector,StateParameters::ZMidT);
 
@@ -78,7 +79,7 @@ double THitExpectation::curvature(const LHCb::State& aState) const{
 Tf::Tsa::Line THitExpectation::yLine(const LHCb::Track& aTrack, const double z)const{
 
   // find the closest state
-  LHCb::State aState = aTrack.closestState(z);
+  LHCb::State aState = closestState(aTrack,z);
   LHCb::StateVector stateVector(aState.position(),aState.slopes());
   m_extrapolator->propagate(stateVector,StateParameters::ZMidT);
 
diff --git a/Tr/TrackTools/src/TTHitExpectation.cpp b/Tr/TrackTools/src/TTHitExpectation.cpp
index 4d141f99071..544250d5fc2 100644
--- a/Tr/TrackTools/src/TTHitExpectation.cpp
+++ b/Tr/TrackTools/src/TTHitExpectation.cpp
@@ -21,6 +21,7 @@
 #include "STDet/DeSTSensor.h"
 #include "TrackInterfaces/ITrackExtrapolator.h"
 #include "Event/StateParameters.h"
+#include "TrackKernel/TrackFunctors.h"
 
 #include "TTHitExpectation.h"
 #include <algorithm>
@@ -73,10 +74,10 @@ IHitExpectation::Info TTHitExpectation::expectation(const LHCb::Track& aTrack) c
 unsigned int TTHitExpectation::nExpected(const LHCb::Track& aTrack) const{
 
   // make a line at TTa and TTb
-  const State& TTaState = aTrack.closestState(m_zTTa);
+  const State& TTaState = closestState(aTrack,m_zTTa);
   StateVector stateVectorTTa(TTaState.position(), TTaState.slopes());
 
-  const State& TTbState = aTrack.closestState(m_zTTb);
+  const State& TTbState = closestState(aTrack,m_zTTb);
   StateVector stateVectorTTb(TTbState.position(), TTbState.slopes());
 
   // determine which modules should be hit
@@ -91,10 +92,10 @@ unsigned int TTHitExpectation::nExpected(const LHCb::Track& aTrack) const{
 void TTHitExpectation::collect(const LHCb::Track& aTrack, std::vector<LHCb::LHCbID>& ids) const{
 
   // make a line at TTa and TTb
-  const State& TTaState = aTrack.closestState(m_zTTa);
+  const State& TTaState = closestState(aTrack,m_zTTa);
   StateVector stateVectorTTa(TTaState.position(), TTaState.slopes());
 
-  const State& TTbState = aTrack.closestState(m_zTTb);
+  const State& TTbState = closestState(aTrack,m_zTTb);
   StateVector stateVectorTTb(TTbState.position(), TTbState.slopes());
 
   // determine which modules should be hit
diff --git a/Tr/TrackTools/src/UTHitExpectation.cpp b/Tr/TrackTools/src/UTHitExpectation.cpp
index e17f138ac05..98a7576cea7 100644
--- a/Tr/TrackTools/src/UTHitExpectation.cpp
+++ b/Tr/TrackTools/src/UTHitExpectation.cpp
@@ -19,6 +19,7 @@
 #include "LHCbMath/GeomFun.h"
 #include "UTDet/DeUTDetector.h"
 #include "UTDet/DeUTSensor.h"
+#include "TrackKernel/TrackFunctors.h"
 #include "TrackInterfaces/ITrackExtrapolator.h"
 #include "Event/StateParameters.h"
 
@@ -74,10 +75,10 @@ IHitExpectation::Info UTHitExpectation::expectation(const LHCb::Track& aTrack) c
 unsigned int UTHitExpectation::nExpected(const LHCb::Track& aTrack) const{
 
   // make a line at UTa and UTb
-  const State& UTaState = aTrack.closestState(m_zUTa);
+  const State& UTaState = closestState(aTrack,m_zUTa);
   StateVector stateVectorUTa(UTaState.position(), UTaState.slopes());
 
-  const State& UTbState = aTrack.closestState(m_zUTb);
+  const State& UTbState = closestState(aTrack,m_zUTb);
   StateVector stateVectorUTb(UTbState.position(), UTbState.slopes());
 
   // determine which modules should be hit
@@ -92,10 +93,10 @@ unsigned int UTHitExpectation::nExpected(const LHCb::Track& aTrack) const{
 void UTHitExpectation::collect(const LHCb::Track& aTrack, std::vector<LHCb::LHCbID>& ids) const{
 
   // make a line at UTa and UTb
-  const State& UTaState = aTrack.closestState(m_zUTa);
+  const State& UTaState = closestState(aTrack,m_zUTa);
   StateVector stateVectorUTa(UTaState.position(), UTaState.slopes());
 
-  const State& UTbState = aTrack.closestState(m_zUTb);
+  const State& UTbState = closestState(aTrack,m_zUTb);
   StateVector stateVectorUTb(UTbState.position(), UTbState.slopes());
 
   // determine which modules should be hit
diff --git a/Tr/TrackTools/src/VPExpectation.cpp b/Tr/TrackTools/src/VPExpectation.cpp
index c34f55c4845..ac1fc74f633 100644
--- a/Tr/TrackTools/src/VPExpectation.cpp
+++ b/Tr/TrackTools/src/VPExpectation.cpp
@@ -18,6 +18,7 @@
 // Rec
 // Tf/TsaKernel
 #include "TsaKernel/Line.h"
+#include "TrackKernel/TrackFunctors.h"
 
 // Local
 #include "VPExpectation.h"
@@ -155,7 +156,7 @@ IVPExpectation::Info VPExpectation::scan(const LHCb::Track &track,
     // Skip sensors outside the range.
     const double z = sensor->z();
     if (z < zStart || z > zStop) continue;
-    auto state = track.closestState(z);
+    auto state = closestState(track,z);
     Tf::Tsa::Line xLine(state.tx(), state.x(), state.z());
     Tf::Tsa::Line yLine(state.ty(), state.y(), state.z());
     const double x = xLine.value(z);
@@ -244,7 +245,7 @@ int VPExpectation::nFound(const Track &track, const double zStart,
 //=============================================================================
 double VPExpectation::zBeamLine(const Track &track) const {
 
-  const State &state = track.closestState(0.);
+  const State &state = closestState(track,0.);
   double z = state.z();
   if (state.checkLocation(State::Location::ClosestToBeam)) return z;
   const Gaudi::TrackVector &vec = state.stateVector();
diff --git a/Tr/TrackTools/src/VeloExpectation.cpp b/Tr/TrackTools/src/VeloExpectation.cpp
index 92a20ad8f03..5429ad9d13e 100644
--- a/Tr/TrackTools/src/VeloExpectation.cpp
+++ b/Tr/TrackTools/src/VeloExpectation.cpp
@@ -34,6 +34,7 @@
 #include "Event/State.h"
 
 #include "Event/TrackParameters.h"
+#include "TrackKernel/TrackFunctors.h"
 
 using namespace LHCb;
 using namespace Gaudi;
@@ -280,7 +281,7 @@ int VeloExpectation::nFound(const Track& aTrack,
 void VeloExpectation::param(const LHCb::Track& aTrack, const double z,
                             Tf::Tsa::Line& xLine, Tf::Tsa::Line& yLine) const{
 
-  const LHCb::State& state = aTrack.closestState(z);
+  const LHCb::State& state = closestState(aTrack,z);
   xLine = Tf::Tsa::Line(state.tx(), state.x(), state.z());
   yLine = Tf::Tsa::Line(state.ty(), state.y(), state.z());
 }
diff --git a/Tr/TrackUtils/src/TrackBuildCloneTable.cpp b/Tr/TrackUtils/src/TrackBuildCloneTable.cpp
index 81adcfb8ff0..e0dce3a5a90 100644
--- a/Tr/TrackUtils/src/TrackBuildCloneTable.cpp
+++ b/Tr/TrackUtils/src/TrackBuildCloneTable.cpp
@@ -16,6 +16,7 @@
 #include "Event/State.h"
 #include "Event/Track.h"
 #include "LHCbMath/Similarity.h"
+#include "TrackKernel/TrackFunctors.h"
 
 // from Event/LinkerEvent
 #include "Linker/LinkerWithKey.h"
@@ -158,7 +159,7 @@ StatusCode TrackBuildCloneTable::execute()
       // Loop over all z positions
       for ( auto z : m_zStates ) {
         // get state closest to reference z pos
-        const State & cState = track->closestState(z);
+        const State & cState = closestState(*track,z);
 
         // only take ones that are close in z
         if ( fabs( cState.z() - z ) > m_maxDz ) continue ;
-- 
GitLab