diff --git a/Phys/FunctorCore/include/Functors/TrackLike.h b/Phys/FunctorCore/include/Functors/TrackLike.h
index 4fafed823457ccb11a3e8224e8bff9989525d750..6195e53eba407de14ab76c65e4cfcdf856f749b4 100644
--- a/Phys/FunctorCore/include/Functors/TrackLike.h
+++ b/Phys/FunctorCore/include/Functors/TrackLike.h
@@ -13,9 +13,14 @@
 #include "DetDesc/DetectorElement.h"
 #include "DetDesc/GenericConditionAccessorHolder.h"
 #include "Event/Bremsstrahlung.h"
+#include "Event/ChiSquare.h"
+#include "Event/ITrackFitResult.h"
+#include "Event/KalmanFitResult.h"
+#include "Event/PrKalmanFitResult.h"
 #include "Event/ProtoParticle.h"
 #include "Event/StateParameters.h"
 #include "Event/TrackEnums.h"
+#include "Event/TrackFitResult.h"
 #include "Event/Track_v1.h"
 #include "Event/Track_v3.h"
 #include "Functors/Function.h"
@@ -215,12 +220,56 @@ namespace Functors::Track {
   constexpr auto LHCbIDs =
       GenericFunctor{ "LHCbIDs", []( auto const& d ) -> decltype( d.lhcbIDs() ) { return d.lhcbIDs(); } };
 
+  namespace detail {
+    template <size_t N>
+    constexpr auto make_nFTHits_functor( const char ( &name )[N], bool ( LHCb::Detector::FTChannelID::*fun )() const ) {
+      return chain( TrivialFunctor{ name,
+                                    [=]( std::span<const LHCb::LHCbID> ids ) {
+                                      return std::count_if( ids.begin(), ids.end(), [=]( auto id ) {
+                                        return id.isFT() && ( id.ftID().*fun )();
+                                      } );
+                                    } },
+                    LHCbIDs );
+    }
+  } // namespace detail
+
+  constexpr auto nFTHitsRight = detail::make_nFTHits_functor( "nFTHitsRight", &LHCb::Detector::FTChannelID::isRight );
+  constexpr auto nFTHitsLeft  = detail::make_nFTHits_functor( "nFTHitsLeft", &LHCb::Detector::FTChannelID::isLeft );
+  constexpr auto nFTHitsTop   = detail::make_nFTHits_functor( "nFTHitsTop", &LHCb::Detector::FTChannelID::isTop );
+  constexpr auto nFTHitsBottom =
+      detail::make_nFTHits_functor( "nFTHitsBottom", &LHCb::Detector::FTChannelID::isBottom );
+
+  /**
+   * @brief Check if track has hits in different sensors of same VELO module (i.e. track in sensor overlap region)
+   *
+   */
+
+  constexpr auto hasVPSensorOverlap = chain(
+      TrivialPredicate{ "hasVPSensorOverlap",
+                        []( std::span<const LHCb::LHCbID> ids ) {
+                          auto vpids = std::ranges::filter_view( ids, []( auto i ) { return i.isVP(); } );
+                          return vpids.end() != std::ranges::adjacent_find(
+                                                    vpids,
+                                                    []( LHCb::Detector::VPChannelID i, LHCb::Detector::VPChannelID j ) {
+                                                      return i.module() == j.module() && i.sensor() != j.sensor();
+                                                    },
+                                                    []( LHCb::LHCbID id ) { return id.vpID(); } );
+                        } },
+      LHCbIDs );
+
   /**
    * @brief Access HitPattern of LHCbIDs.
    *
    */
   constexpr auto HitPattern = TrivialFunctor{ "HitPattern", []( auto const& d ) { return LHCb::HitPattern( d ); } };
 
+  /**
+   * @brief Access number of VP layers on HitPattern.
+   *
+   */
+  constexpr auto nVPLayers =
+      chain( Functors::TrivialFunctor{ "HitPattern::numVelo", &LHCb::HitPattern::numVelo }, HitPattern, LHCbIDs );
+
   /**
    * @brief Access number of A-side VP hits on HitPattern.
    *
@@ -229,20 +278,146 @@ namespace Functors::Track {
       chain( Functors::TrivialFunctor{ "HitPattern::numVeloA", &LHCb::HitPattern::numVeloA }, HitPattern, LHCbIDs );
 
   /**
-   * @brief Access number of c-side VP hits on HitPattern.
+   * @brief Access number of C-side VP hits on HitPattern.
    *
    */
   constexpr auto nVPHitsC =
       chain( Functors::TrivialFunctor{ "HitPattern::numVeloC", &LHCb::HitPattern::numVeloC }, HitPattern, LHCbIDs );
 
   /**
-   * @brief Acces number of overlap VP hits on HitPattern.
+   * @brief Access number of overlap VP hits on HitPattern.
    *
    */
   constexpr auto nVPOverlap = chain(
       Functors::TrivialFunctor{ "HitPattern::numVeloStationsOverlap", &LHCb::HitPattern::numVeloStationsOverlap },
       HitPattern, LHCbIDs );
 
+  /**
+   * @brief Access number of VP holes of track from HitPattern.
+   *
+   */
+  constexpr auto nVPHoles = chain(
+      Functors::TrivialFunctor{ "HitPattern::numVeloHoles", &LHCb::HitPattern::numVeloHoles }, HitPattern, LHCbIDs );
+
+  /**
+   * @brief Access number of FT holes of trackk from HitPattern.
+   *
+   */
+  constexpr auto nFTHoles =
+      chain( Functors::TrivialFunctor{ "HitPattern::numFTHoles", &LHCb::HitPattern::numFTHoles }, HitPattern, LHCbIDs );
+
+  /**
+   * @brief Access fitResult of track.
+   *
+   */
+  constexpr auto FitResult =
+      GenericFunctor{ "FitResult", []( auto const& t ) -> decltype( t.fitResult() ) { return t.fitResult(); } };
+
+  /**
+   * @brief Access VELO ChiSquare of fit result.
+   *
+   */
+  constexpr auto FitResultChi2Velo =
+      GenericFunctor{ "FitResultChi2Velo", []( auto const& f ) -> decltype( f.chi2Velo() ) { return f.chi2Velo(); },
+                      []( LHCb::ITrackFitResult const& ifr ) {
+                        return dispatch<LHCb::TrackFitResult, LHCb::PrKalmanFitResult, LHCb::KalmanFitResult>(
+                            ifr, []( auto const& r ) -> LHCb::ChiSquare { return r.chi2Velo(); } );
+                      }
+
+      };
+
+  /**
+   * @brief Get chi2 of fitted VELO track segment
+   *
+   */
+  constexpr auto VeloChi2 =
+      chain( Functors::TrivialFunctor{ "ChiSquare::chi2", &LHCb::ChiSquare::chi2 }, FitResultChi2Velo, FitResult );
+
+  /**
+   * @brief Get chi2/ndof of fitted VELO track segment
+   *
+   */
+  constexpr auto VeloChi2DoF = chain( Functors::TrivialFunctor{ "ChiSquare::chi2PerDoF", &LHCb::ChiSquare::chi2PerDoF },
+                                      FitResultChi2Velo, FitResult );
+
+  /**
+   * @brief Access Upstream ChiSquare of fit result.
+   *
+   */
+  constexpr auto FitResultChi2Upstream = GenericFunctor{
+      "FitResultChi2Upstream", []( auto const& f ) -> decltype( f.chi2Velo() ) { return f.chi2Upstream(); },
+      []( LHCb::ITrackFitResult const& ifr ) {
+        return dispatch<LHCb::TrackFitResult, LHCb::PrKalmanFitResult, LHCb::KalmanFitResult>(
+            ifr, []( auto const& r ) -> LHCb::ChiSquare { return r.chi2Upstream(); } );
+      } };
+
+  /**
+   * @brief Get chi2 of fitted upstream track segment
+   *
+   */
+  constexpr auto UpstreamChi2 =
+      chain( Functors::TrivialFunctor{ "ChiSquare::chi2", &LHCb::ChiSquare::chi2 }, FitResultChi2Upstream, FitResult );
+
+  /**
+   * @brief Get chi2/ndof of fitted upstream track segment
+   *
+   */
+  constexpr auto UpstreamChi2DoF =
+      chain( Functors::TrivialFunctor{ "ChiSquare::chi2PerDoF", &LHCb::ChiSquare::chi2PerDoF }, FitResultChi2Upstream,
+             FitResult );
+
+  /**
+   * @brief Access Downstream ChiSquare of fit result.
+   *
+   */
+  constexpr auto FitResultChi2Downstream = GenericFunctor{
+      "FitResultChi2Downstream", []( auto const& f ) -> decltype( f.chi2Velo() ) { return f.chi2Downstream(); },
+      []( LHCb::ITrackFitResult const& ifr ) {
+        return dispatch<LHCb::TrackFitResult, LHCb::PrKalmanFitResult, LHCb::KalmanFitResult>(
+            ifr, []( auto const& r ) -> LHCb::ChiSquare { return r.chi2Downstream(); } );
+      } };
+
+  /**
+   * @brief Get chi2 of fitted downstream track segment
+   *
+   */
+  constexpr auto DownstreamChi2 = chain( Functors::TrivialFunctor{ "ChiSquare::chi2", &LHCb::ChiSquare::chi2 },
+                                         FitResultChi2Downstream, FitResult );
+
+  /**
+   * @brief Get chi2/ndof of fitted downstream track segment
+   *
+   */
+  constexpr auto DownstreamChi2DoF =
+      chain( Functors::TrivialFunctor{ "ChiSquare::chi2PerDoF", &LHCb::ChiSquare::chi2PerDoF }, FitResultChi2Downstream,
+             FitResult );
+
+  /**
+   * @brief Access Match ChiSquare of fit result.
+   *
+   */
+  constexpr auto FitResultChi2Match =
+      GenericFunctor{ "FitResultChi2Match", []( auto const& f ) -> decltype( f.chi2Velo() ) { return f.chi2Match(); },
+                      []( LHCb::ITrackFitResult const& ifr ) {
+                        return dispatch<LHCb::TrackFitResult, LHCb::PrKalmanFitResult, LHCb::KalmanFitResult>(
+                            ifr, []( auto const& r ) -> LHCb::ChiSquare { return r.chi2Match(); } );
+                      } };
+
+  /**
+   * @brief Get chi2 of upstream-downstream match
+   *
+   */
+  constexpr auto MatchChi2 =
+      chain( Functors::TrivialFunctor{ "ChiSquare::chi2", &LHCb::ChiSquare::chi2 }, FitResultChi2Match, FitResult );
+
+  /**
+   * @brief Get chi2/ndof of upstream-downstream match
+   *
+   */
+  constexpr auto MatchChi2DoF =
+      chain( Functors::TrivialFunctor{ "ChiSquare::chi2PerDoF", &LHCb::ChiSquare::chi2PerDoF }, FitResultChi2Match,
+             FitResult );
+
   /**
    * @brief referencePoint, as defined by the referencePoint() accessor.
    * @note referencePoint is the position at which the object has its threeMomentum
diff --git a/Phys/FunctorCore/python/Functors/__init__.py b/Phys/FunctorCore/python/Functors/__init__.py
index 922b102bce3e40cb49e0de5c93704e1a7c3df606..f20a5753c80cf7b1ba38f0089c5010975f1539e8 100644
--- a/Phys/FunctorCore/python/Functors/__init__.py
+++ b/Phys/FunctorCore/python/Functors/__init__.py
@@ -195,6 +195,16 @@ LHCBIDS = Functor("LHCBIDS", "Track::LHCbIDs", "Get LHCbIDs from track-like obje
 
 HIT_PATTERN = Functor("HIT_PATTERN", "Track::HitPattern", "Get HitPattern from LHCbIDs")
 
+NVPLAYERS = Functor(
+    "NVLAYERS",
+    "Track::nVPLayers",
+    """
+    Return number of VELO layers of track as defined by HitPattern
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
 NVPHITSA = Functor(
     "NVPHITSA",
     "Track::nVPHitsA",
@@ -219,12 +229,177 @@ NVPOVERLAP = Functor(
     "NVPOVERLAP",
     "Track::nVPOverlap",
     """
-    Return number of overlap hits in VELO
+    Return number of station overlaps in VELO as defined by HitPattern of a track
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+NVPHOLES = Functor(
+    "NVPHOLES",
+    "Track::nVPHoles",
+    """
+    Return number of holes in VELO of track as defined by HitPattern
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+HASVPSENSOROVERLAP = Functor(
+    "HASVPSENSOROVERLAP",
+    "Track::hasVPSensorOverlap",
+    """
+    Check if track has hits in different sensors of same VELO module
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+NFTHOLES = Functor(
+    "NFTHOLES",
+    "Track::nFTHoles",
+    """
+    Return number of holes in SciFi of track as defined by HitPattern
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+NFTHITSLEFT = Functor(
+    "NFTHITSLEFT",
+    "Track::nFTHitsLeft",
+    """
+    Return number of hits in left SciFi half (quarters Q1 and Q3) of track
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+NFTHITSRIGHT = Functor(
+    "NFTHITSRIGHT",
+    "Track::nFTHitsRight",
+    """
+    Return number of hits in right SciFi half (quarters Q0 and Q2) of track
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+NFTHITSTOP = Functor(
+    "NFTHITSTOP",
+    "Track::nFTHitsTop",
+    """
+    Return number of hits in top SciFi half (quarters Q2 and Q3) of track
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+NFTHITSBOTTOM = Functor(
+    "NFTHITSBOTTOM",
+    "Track::nFTHitsBottom",
+    """
+    Return number of hits in bottom SciFi half (quarters Q0 and Q1) of track
 
     Functor's call operator expects a track-like object.
     """,
 )
 
+VELOCHI2 = Functor(
+    "VELOCHI2",
+    "Track::VeloChi2",
+    """
+    Return chi2 of fitted VELO segment
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+VELOCHI2DOF = Functor(
+    "VELOCHI2DOF",
+    "Track::VeloChi2DoF",
+    """
+    Return chi2/ndof of fitted VELO segment
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+UPSTREAMCHI2 = Functor(
+    "UPSTREAMCHI2",
+    "Track::UpstreamChi2",
+    """
+    Return chi2 of fitted upstream track segment
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+UPSTREAMCHI2DOF = Functor(
+    "UPSTREAMCHI2DOF",
+    "Track::UpstreamChi2DoF",
+    """
+    Return chi2/ndof of fitted upstream track segment
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+DOWNSTREAMCHI2 = Functor(
+    "DOWNSTREAMMCHI2",
+    "Track::DownstreamChi2",
+    """
+    Return chi2 of fitted downstream track segment
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+DOWNSTREAMCHI2DOF = Functor(
+    "DOWNSTREAMCHI2DOF",
+    "Track::DownstreamChi2DoF",
+    """
+    Return chi2/ndof of fitted downstream track segment
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+MATCHCHI2 = Functor(
+    "MATCHMCHI2",
+    "Track::MatchChi2",
+    """
+    Return chi2 of upstream-downstream match of fitted track
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
+MATCHCHI2DOF = Functor(
+    "MATCHCHI2DOF",
+    "Track::MatchChi2DoF",
+    """
+    Return chi2/ndof of upstream-downstream match of fitted track
+
+    Functor's call operator expects a track-like object.
+    """,
+)
+
+
 EXTRAPOLATE_TRACK = Functor(
     "EXTRAPOLATE_TRACK",
     "Track::Extrapolate",
diff --git a/Phys/FunctorCore/tests/src/TestFunctors.cpp b/Phys/FunctorCore/tests/src/TestFunctors.cpp
index 46c47d25e70ad01d00bc40d5c65d4800dfc441d6..15a38561d2b9b7512900f7c6e1b8c4131b6a4d42 100644
--- a/Phys/FunctorCore/tests/src/TestFunctors.cpp
+++ b/Phys/FunctorCore/tests/src/TestFunctors.cpp
@@ -114,6 +114,14 @@ struct DummyState {
   }
 };
 
+// dummy fit result
+struct DummyFitResult {
+  LHCb::ChiSquare chi2Velo() const { return LHCb::ChiSquare{ 3.9, 3 }; };
+  LHCb::ChiSquare chi2Upstream() const { return LHCb::ChiSquare{ 5.5, 5 }; };
+  LHCb::ChiSquare chi2Downstream() const { return LHCb::ChiSquare{ 6., 4 }; };
+  LHCb::ChiSquare chi2Match() const { return LHCb::ChiSquare{ 4.2, 2 }; };
+};
+
 // dummy track type
 struct DummyTrack {
   float                          m_pt{ 0.f }, m_eta{ 0.f };
@@ -151,10 +159,45 @@ struct DummyTrack {
   bool checkFlag( LHCb::Event::Enum::Track::Flag flag ) const { return static_cast<int>( flag ) == 0; }
   const std::vector<DummyState*>& states() const { return m_states; }
   void                            addToStates( DummyState* state ) { m_states.push_back( state ); };
-  // VELO LHCbIDs: two C-side, one A-side
+  auto                            fitResult() const { return DummyFitResult{}; };
+
+  using FTChannelID = LHCb::Detector::FTChannelID;
+  using FTStationID = FTChannelID::StationID;
+  using FTLayerID   = FTChannelID::LayerID;
+  using FTQuarterID = FTChannelID::QuarterID;
+  using FTModuleID  = FTChannelID::ModuleID;
+  using FTMatID     = FTChannelID::MatID;
+  using VPChannelID = LHCb::Detector::VPChannelID;
+  using VPSensorID  = VPChannelID::SensorID;
+  using VPChipID    = VPChannelID::ChipID;
+  using VPColumnID  = VPChannelID::ColumnID;
+  using VPRowID     = VPChannelID::RowID;
+
+  // VELO LHCbIDs: three C-side, one A-side with sensor overlap in C-side
+  // FT LHCbIDs: 3 in quarter 0, 4 in quarter 3
   std::vector<LHCb::LHCbID> lhcbIDs() const {
-    std::vector<LHCb::LHCbID> tmp_ids{ LHCb::LHCbID{ 604130029 }, LHCb::LHCbID{ 605211373 },
-                                       LHCb::LHCbID{ 606223851 } };
+    std::vector<LHCb::LHCbID> tmp_ids{
+        LHCb::LHCbID{ VPChannelID{ VPSensorID{ 0 }, VPChipID{ 2 }, VPColumnID{ 74 }, VPRowID{ 237 } } },
+        LHCb::LHCbID{ VPChannelID{ VPSensorID{ 4 }, VPChipID{ 2 }, VPColumnID{ 202 }, VPRowID{ 237 } } },
+        LHCb::LHCbID{ VPChannelID{ VPSensorID{ 8 }, VPChipID{ 2 }, VPColumnID{ 61 }, VPRowID{ 235 } } },
+        LHCb::LHCbID{ VPChannelID{ VPSensorID{ 154 }, VPChipID{ 2 }, VPColumnID{ 104 }, VPRowID{ 3 } } },
+        LHCb::LHCbID{ VPChannelID{ VPSensorID{ 155 }, VPChipID{ 0 }, VPColumnID{ 154 }, VPRowID{ 254 } } },
+
+        LHCb::LHCbID{ FTChannelID{ FTStationID{ 1 }, FTLayerID{ 0 }, FTQuarterID{ 0 }, FTModuleID{ 0 }, FTMatID{ 3 }, 1,
+                                   81 } }, // channel =81 sipm =1
+        LHCb::LHCbID{ FTChannelID{ FTStationID{ 1 }, FTLayerID{ 1 }, FTQuarterID{ 0 }, FTModuleID{ 0 }, FTMatID{ 0 }, 2,
+                                   4 } }, // channel =4 sipm =2
+        LHCb::LHCbID{ FTChannelID{ FTStationID{ 1 }, FTLayerID{ 3 }, FTQuarterID{ 0 }, FTModuleID{ 0 }, FTMatID{ 0 }, 2,
+                                   56 } }, // channel =56 sipm =2
+        LHCb::LHCbID{ FTChannelID{ FTStationID{ 2 }, FTLayerID{ 0 }, FTQuarterID{ 3 }, FTModuleID{ 1 }, FTMatID{ 1 }, 3,
+                                   38 } }, // channel =38 sipm =3
+        LHCb::LHCbID{ FTChannelID{ FTStationID{ 2 }, FTLayerID{ 1 }, FTQuarterID{ 3 }, FTModuleID{ 1 }, FTMatID{ 1 }, 3,
+                                   106 } }, // channel =106 sipm =3
+        LHCb::LHCbID{ FTChannelID{ FTStationID{ 2 }, FTLayerID{ 2 }, FTQuarterID{ 3 }, FTModuleID{ 1 }, FTMatID{ 1 }, 0,
+                                   114 } }, // channel =114 sipm =0
+        LHCb::LHCbID{ FTChannelID{ FTStationID{ 2 }, FTLayerID{ 3 }, FTQuarterID{ 3 }, FTModuleID{ 1 }, FTMatID{ 2 }, 2,
+                                   50 } }, // channel =50 sipm =2
+    };
     return tmp_ids;
   }
 
@@ -201,6 +244,7 @@ struct DummyTrack {
   DummyTrack( float pt, float eta, bool inacceptance, bool ismuon, float ebrem = 0.f )
       : m_pt( pt ), m_eta( eta ), m_inacceptance( inacceptance ), m_ismuon( ismuon ), m_ebrem( ebrem ) {}
 };
+
 struct DummyReconstructedObject {
   DummyReconstructedObject( const int charge, const DummyTrack* track ) : m_charge( charge ), m_track( track ) {}
   const DummyTrack* track() const { return m_track; }
@@ -456,33 +500,50 @@ BOOST_AUTO_TEST_CASE( test_1trackmva_functor ) {
 
 BOOST_AUTO_TEST_CASE( test_general_track_functor ) {
 
-  auto const TYPE             = Functors::Track::Type;
-  auto const HAST             = Functors::Track::HasT;
-  auto const HASUT            = Functors::Track::HasUT;
-  auto const HASVELO          = Functors::Track::HasVelo;
-  auto const HISTORY          = Functors::Track::History;
-  auto const NFTHITS          = Functors::Track::nFTHits;
-  auto const NUTHITS          = Functors::Track::nUTHits;
-  auto const NVPHITS          = Functors::Track::nVPHits;
-  auto const NHITS            = Functors::Track::nHits;
-  auto const NDOF             = Functors::Track::nDoF;
-  auto const CHI2             = Functors::Track::Chi2;
-  auto const MC_RECONSTRUCTED = Functors::Track::MC_Reconstructed;
-  auto const STATES           = Functors::Track::States;
-  auto const GETTRACK         = Functors::Particle::GetTrack;
-  auto const REFERENCEPOINT   = Functors::Track::ReferencePoint;
-  auto const ISTTRACK         = trivial_prepare( Functors::Track::IsTtrack );
-  auto const ISDOWNSTREAM     = trivial_prepare( Functors::Track::IsDownstream );
-  auto const ISUPSTREAM       = trivial_prepare( Functors::Track::IsUpstream );
-  auto const ISLONG           = trivial_prepare( Functors::Track::IsLong );
-  auto const ISVELO           = trivial_prepare( Functors::Track::IsVelo );
-  auto const ISVELOBACKWARD   = trivial_prepare( Functors::Track::IsVeloBackward );
-  auto const ISINVALID        = Functors::Track::IsInvalid;
-  auto const ISSELECTED       = Functors::Track::IsSelected;
-  auto const ISCLONE          = Functors::Track::IsClone;
-  auto const NVPHITSA         = trivial_prepare( Functors::Track::nVPHitsA );
-  auto const NVPHITSC         = trivial_prepare( Functors::Track::nVPHitsC );
-  auto const NVPOVERLAP       = trivial_prepare( Functors::Track::nVPOverlap );
+  auto const TYPE                = Functors::Track::Type;
+  auto const HAST                = Functors::Track::HasT;
+  auto const HASUT               = Functors::Track::HasUT;
+  auto const HASVELO             = Functors::Track::HasVelo;
+  auto const HISTORY             = Functors::Track::History;
+  auto const NFTHITS             = Functors::Track::nFTHits;
+  auto const NUTHITS             = Functors::Track::nUTHits;
+  auto const NVPHITS             = Functors::Track::nVPHits;
+  auto const NHITS               = Functors::Track::nHits;
+  auto const NDOF                = Functors::Track::nDoF;
+  auto const CHI2                = Functors::Track::Chi2;
+  auto const MC_RECONSTRUCTED    = Functors::Track::MC_Reconstructed;
+  auto const STATES              = Functors::Track::States;
+  auto const GETTRACK            = Functors::Particle::GetTrack;
+  auto const REFERENCEPOINT      = Functors::Track::ReferencePoint;
+  auto const ISTTRACK            = trivial_prepare( Functors::Track::IsTtrack );
+  auto const ISDOWNSTREAM        = trivial_prepare( Functors::Track::IsDownstream );
+  auto const ISUPSTREAM          = trivial_prepare( Functors::Track::IsUpstream );
+  auto const ISLONG              = trivial_prepare( Functors::Track::IsLong );
+  auto const ISVELO              = trivial_prepare( Functors::Track::IsVelo );
+  auto const ISVELOBACKWARD      = trivial_prepare( Functors::Track::IsVeloBackward );
+  auto const ISINVALID           = Functors::Track::IsInvalid;
+  auto const ISSELECTED          = Functors::Track::IsSelected;
+  auto const ISCLONE             = Functors::Track::IsClone;
+  auto const NVPLAYERS           = trivial_prepare( Functors::Track::nVPLayers );
+  auto const NVPHITSA            = trivial_prepare( Functors::Track::nVPHitsA );
+  auto const NVPHITSC            = trivial_prepare( Functors::Track::nVPHitsC );
+  auto const NVPOVERLAP          = trivial_prepare( Functors::Track::nVPOverlap );
+  auto const HASVPSSENSOROVERLAP = trivial_prepare( Functors::Track::hasVPSensorOverlap );
+  auto const NVPHOLES            = trivial_prepare( Functors::Track::nVPHoles );
+
+  auto const VELOCHI2          = trivial_prepare( Functors::Track::VeloChi2 );
+  auto const VELOCHI2DOF       = trivial_prepare( Functors::Track::VeloChi2DoF );
+  auto const UPSTREAMCHI2      = trivial_prepare( Functors::Track::UpstreamChi2 );
+  auto const UPSTREAMCHI2DOF   = trivial_prepare( Functors::Track::UpstreamChi2DoF );
+  auto const DOWNSTREAMCHI2    = trivial_prepare( Functors::Track::DownstreamChi2 );
+  auto const DOWNSTREAMCHI2DOF = trivial_prepare( Functors::Track::DownstreamChi2DoF );
+  auto const MATCHCHI2         = trivial_prepare( Functors::Track::MatchChi2 );
+  auto const MATCHCHI2DOF      = trivial_prepare( Functors::Track::MatchChi2DoF );
+  auto const NFTHITSRIGHT      = trivial_prepare( Functors::Track::nFTHitsRight );
+  auto const NFTHITSLEFT       = trivial_prepare( Functors::Track::nFTHitsLeft );
+  auto const NFTHITSBOTTOM     = trivial_prepare( Functors::Track::nFTHitsBottom );
+  auto const NFTHITSTOP        = trivial_prepare( Functors::Track::nFTHitsTop );
+  auto const NFTHOLES          = trivial_prepare( Functors::Track::nFTHoles );
 
   auto const CAST_TO_INT = Functors::Functional::CastTo<int>;
   BOOST_CHECK_EQUAL( CAST_TO_INT( true ), 1 );
@@ -509,9 +570,27 @@ BOOST_AUTO_TEST_CASE( test_general_track_functor ) {
   BOOST_CHECK_EQUAL( NHITS( track ), 12 );
   BOOST_CHECK_EQUAL( NDOF( track ), 1 );
   BOOST_CHECK_EQUAL( CHI2( track ), 1.f );
+  BOOST_CHECK_EQUAL( NVPLAYERS( track ), 4 );
   BOOST_CHECK_EQUAL( NVPHITSA( track ), 1 );
-  BOOST_CHECK_EQUAL( NVPHITSC( track ), 2 );
+  BOOST_CHECK_EQUAL( NVPHITSC( track ), 3 );
   BOOST_CHECK_EQUAL( NVPOVERLAP( track ), 1 );
+  BOOST_CHECK_EQUAL( NVPHOLES( track ), 17 );
+  BOOST_CHECK_EQUAL( HASVPSSENSOROVERLAP( track ), true );
+
+  BOOST_CHECK_EQUAL( VELOCHI2( track ), 3.9 );
+  BOOST_CHECK_EQUAL( VELOCHI2DOF( track ), 1.3 );
+  BOOST_CHECK_EQUAL( UPSTREAMCHI2( track ), 5.5 );
+  BOOST_CHECK_EQUAL( UPSTREAMCHI2DOF( track ), 1.1 );
+  BOOST_CHECK_EQUAL( DOWNSTREAMCHI2( track ), 6. );
+  BOOST_CHECK_EQUAL( DOWNSTREAMCHI2DOF( track ), 1.5 );
+  BOOST_CHECK_EQUAL( MATCHCHI2( track ), 4.2 );
+  BOOST_CHECK_EQUAL( MATCHCHI2DOF( track ), 2.1 );
+
+  BOOST_CHECK_EQUAL( NFTHITSBOTTOM( track ), 3 );
+  BOOST_CHECK_EQUAL( NFTHITSTOP( track ), 4 );
+  BOOST_CHECK_EQUAL( NFTHITSLEFT( track ), 4 );
+  BOOST_CHECK_EQUAL( NFTHITSRIGHT( track ), 3 );
+  BOOST_CHECK_EQUAL( NFTHOLES( track ), 1 );
 
   DummyReconstructedObject rec{ 1, &track };
   BOOST_CHECK_EQUAL( MC_RECONSTRUCTED( rec ), 1 );
diff --git a/Tr/TrackFitEvent/include/Event/Measurement.h b/Tr/TrackFitEvent/include/Event/Measurement.h
index d2c08ff75a87fdfd8533dd8cd279a5edb92dabb9..217c9e82042c1338c0631eac1b1c9c1f83fb2508 100644
--- a/Tr/TrackFitEvent/include/Event/Measurement.h
+++ b/Tr/TrackFitEvent/include/Event/Measurement.h
@@ -71,19 +71,19 @@ namespace LHCb {
       return idx;
     }
 
+    // Scaffolding for visit overloading with another variant
+    template <typename T>
+    struct is_variant_ : std::false_type {};
+    template <typename... Ts>
+    struct is_variant_<std::variant<Ts...>> : std::true_type {};
+    template <typename T>
+    constexpr bool is_variant_v = is_variant_<std::decay_t<T>>::value;
+
   } // namespace details::Measurement
 
   using Point =
       typename ROOT::Math::PositionVector3D<ROOT::Math::Cartesian3D<double>, ROOT::Math::DefaultCoordinateSystemTag>;
 
-  // Scaffolding for visit overloading with another variant
-  template <typename T>
-  struct is_variant_ : std::false_type {};
-  template <typename... Ts>
-  struct is_variant_<std::variant<Ts...>> : std::true_type {};
-  template <typename T>
-  constexpr bool is_variant_v = is_variant_<std::decay_t<T>>::value;
-
   class Measurement final {
   public:
     struct FT {
@@ -219,7 +219,7 @@ namespace LHCb {
     // Same as above, but allow for an additional variant as first argument of visit
     template <typename F, typename... Fs>
     decltype( auto ) visit( F&& f, Fs&&... fs ) const {
-      if constexpr ( is_variant_v<F> ) {
+      if constexpr ( details::Measurement::is_variant_v<F> ) {
         return std::visit( Gaudi::overload( std::forward<Fs>( fs )... ), m_sub, std::forward<F>( f ) );
       } else {
         return std::visit( Gaudi::overload( std::forward<F>( f ), std::forward<Fs>( fs )... ), m_sub );