diff --git a/Pr/PrVeloUT/src/PrVeloUT.cpp b/Pr/PrVeloUT/src/PrVeloUT.cpp
index 84e3d62059c5fb64367d7f39c86b68bab8723209..635cb198a83c64215a63428f2677ec9fe067495f 100644
--- a/Pr/PrVeloUT/src/PrVeloUT.cpp
+++ b/Pr/PrVeloUT/src/PrVeloUT.cpp
@@ -253,7 +253,8 @@ namespace LHCb::Pr {
   //=============================================================================
   VeloUT::VeloUT( const std::string& name, ISvcLocator* pSvcLocator )
       : Transformer( name, pSvcLocator,
-                     {KeyValue{"InputTracksName", "Rec/Track/Velo"}, KeyValue{"UTHits", UT::Info::HitLocation}},
+                     {KeyValue{"InputTracksName", "Rec/Track/Velo"}, KeyValue{"UTHits", UT::Info::HitLocation},
+                      KeyValue{"GeometryInfo", "AlgorithmSpecific-" + name + "-UTGeometryInfo"}},
                      KeyValue{"OutputTracksName", "Rec/Track/UT"} ) {}
 
   /// Initialization
@@ -267,31 +268,26 @@ namespace LHCb::Pr {
     // zMidField and distToMomentum is properly recalculated in PrUTMagnetTool when B field changes
     m_distToMomentum = m_PrUTMagnetTool->averageDist2mom();
 
-    m_magFieldSvc = svc<ILHCbMagnetSvc>( "MagneticFieldSvc", true );
-
     if ( m_doTiming ) {
       m_timerTool->increaseIndent();
       m_veloUTTime = m_timerTool->addTimer( "Internal VeloUT Tracking" );
       m_timerTool->decreaseIndent();
     }
 
-    // Get detector element.
-    m_utDet = getDet<DeUTDetector>( DeUTDetLocation::UT );
-    // Make sure we precompute z positions/sizes of the layers/sectors
-    registerCondition( m_utDet->geometry(), &VeloUT::recomputeGeometry );
-
-    return StatusCode::SUCCESS;
-  }
+    addConditionDerivation( DeUTDetLocation::UT, inputLocation<2>(), []( const DeUTDetector& utDet ) {
+      UTGeometryInfo geom;
+      UTDAQ::computeGeometry( utDet, geom.layers, geom.sectorsZ );
+      return geom;
+    } );
 
-  StatusCode VeloUT::recomputeGeometry() {
-    UTDAQ::computeGeometry( *m_utDet, m_layers, m_sectorsZ );
     return StatusCode::SUCCESS;
   }
 
   //=============================================================================
   // Main execution
   //=============================================================================
-  Upstream::Tracks VeloUT::operator()( const Velo::Tracks& inputTracks, const UT::HitHandler& hh ) const {
+  Upstream::Tracks VeloUT::operator()( const Velo::Tracks& inputTracks, const UT::HitHandler& hh,
+                                       const UTGeometryInfo& geometry ) const {
     if ( m_doTiming ) m_timerTool->start( m_veloUTTime );
 
     Upstream::Tracks outputTracks{&inputTracks};
@@ -300,7 +296,7 @@ namespace LHCb::Pr {
     const auto& fudgeFactors = m_PrUTMagnetTool->DxLayTable();
     const auto& bdlTable     = m_PrUTMagnetTool->BdlTable();
 
-    std::array<UT::Mut::Hits, 4> hitsInLayers;
+    std::array<UT::Mut::Hits, UTInfo::TotalLayers> hitsInLayers;
     for ( auto& it : hitsInLayers ) it.reserve( 8 ); // check this number!
 
     // for now only scalar, but with some adaptation it can be vectorized
@@ -311,9 +307,9 @@ namespace LHCb::Pr {
       if ( !getState<dType>( inputTracks, t, trState, outputTracks ) ) continue;
 
       for ( auto& it : hitsInLayers ) it.clear();
-      if ( !getHits( hitsInLayers, hh, fudgeFactors, trState ) ) continue;
+      if ( !getHits( hitsInLayers, hh, fudgeFactors, geometry, trState ) ) continue;
 
-      TrackHelper helper( trState, m_zKink, m_sigmaVeloSlope, m_maxPseudoChi2 );
+      TrackHelper helper( trState, c_zKink, c_sigmaVeloSlope, m_maxPseudoChi2 );
 
       if ( !formClusters( hitsInLayers, helper ) ) {
         std::reverse( hitsInLayers.begin(), hitsInLayers.end() );
@@ -379,8 +375,8 @@ namespace LHCb::Pr {
   // Find the hits
   //=============================================================================
   template <typename FudgeTable>
-  bool VeloUT::getHits( span<UT::Mut::Hits, 4> hitsInLayers, const UT::HitHandler& hh, const FudgeTable& fudgeFactors,
-                        MiniState& trState ) const {
+  bool VeloUT::getHits( span<UT::Mut::Hits, UTInfo::TotalLayers> hitsInLayers, const UT::HitHandler& hh,
+                        const FudgeTable& fudgeFactors, const UTGeometryInfo& geom, MiniState& trState ) const {
 
     // -- This is hardcoded, so faster
     // -- If you ever change the Table in the magnet tool, this will be wrong
@@ -406,18 +402,18 @@ namespace LHCb::Pr {
         if ( iStation == 1 && iLayer == 1 && nLayers < 2 ) return false;
 
         const unsigned int layerIndex  = 2 * iStation + iLayer;
-        const float        z           = m_layers[layerIndex].z;
+        const float        z           = geom.layers[layerIndex].z;
         const float        yAtZ        = trState.y + trState.ty * ( z - trState.z );
         const float        xLayer      = trState.x + trState.tx * ( z - trState.z );
-        const float        yLayer      = yAtZ + yTol * m_layers[layerIndex].dxDy;
+        const float        yLayer      = yAtZ + yTol * geom.layers[layerIndex].dxDy;
         const float        normFactNum = normFact[layerIndex];
         const float        invNormFact = 1.0f / normFactNum;
 
         UTDAQ::findSectors( layerIndex, xLayer, yLayer,
                             xTol * invNormFact - std::abs( trState.tx ) * m_intraLayerDist.value(),
-                            m_yTol + m_yTolSlope * std::abs( xTol * invNormFact ), m_layers[layerIndex], sectors );
+                            m_yTol + m_yTolSlope * std::abs( xTol * invNormFact ), geom.layers[layerIndex], sectors );
 
-        const UTDAQ::SectorsInLayerZ& sectorsZForLayer = m_sectorsZ[iStation][iLayer];
+        const UTDAQ::SectorsInLayerZ& sectorsZForLayer = geom.sectorsZ[iStation][iLayer];
         std::pair                     pp{-1, -1};
         for ( auto& p : sectors ) {
           // sectors can be duplicated in the list, but they are ordered
@@ -437,7 +433,7 @@ namespace LHCb::Pr {
   //=========================================================================
   // Form clusters
   //=========================================================================
-  bool VeloUT::formClusters( span<const UT::Mut::Hits, 4> hitsInLayers, TrackHelper& helper ) const {
+  bool VeloUT::formClusters( span<const UT::Mut::Hits, UTInfo::TotalLayers> hitsInLayers, TrackHelper& helper ) const {
 
     bool fourLayerSolution = false;
 
@@ -489,7 +485,7 @@ namespace LHCb::Pr {
 
         // -- All hits found
         if ( bestHit1 && bestHit3 ) {
-          simpleFit( std::array{&hit0, bestHit1, &hit2, bestHit3}, helper, m_zMidUT, m_zKink, m_invSigmaVeloSlope );
+          simpleFit( std::array{&hit0, bestHit1, &hit2, bestHit3}, helper, m_zMidUT, c_zKink, c_invSigmaVeloSlope );
 
           if ( !fourLayerSolution && helper.bestHits[0] ) { fourLayerSolution = true; }
           continue;
@@ -497,12 +493,12 @@ namespace LHCb::Pr {
 
         // -- Nothing found in layer 3
         if ( !fourLayerSolution && bestHit1 ) {
-          simpleFit( std::array{&hit0, bestHit1, &hit2}, helper, m_zMidUT, m_zKink, m_invSigmaVeloSlope );
+          simpleFit( std::array{&hit0, bestHit1, &hit2}, helper, m_zMidUT, c_zKink, c_invSigmaVeloSlope );
           continue;
         }
         // -- Noting found in layer 1
         if ( !fourLayerSolution && bestHit3 ) {
-          simpleFit( std::array{&hit0, bestHit3, &hit2}, helper, m_zMidUT, m_zKink, m_invSigmaVeloSlope );
+          simpleFit( std::array{&hit0, bestHit3, &hit2}, helper, m_zMidUT, c_zKink, c_invSigmaVeloSlope );
           continue;
         }
       }
@@ -515,8 +511,8 @@ namespace LHCb::Pr {
   //=========================================================================
   template <typename dType, typename BdlTable>
   void VeloUT::prepareOutputTrack( const Velo::Tracks& inputTracks, int ancestor, const TrackHelper& helper,
-                                   span<const UT::Mut::Hits, 4> hitsInLayers, Upstream::Tracks& outputTracks,
-                                   const BdlTable& bdlTable ) const {
+                                   span<const UT::Mut::Hits, UTInfo::TotalLayers> hitsInLayers,
+                                   Upstream::Tracks& outputTracks, const BdlTable& bdlTable ) const {
     using I = typename dType::int_v;
     using F = typename dType::float_v;
 
diff --git a/Pr/PrVeloUT/src/PrVeloUT.h b/Pr/PrVeloUT/src/PrVeloUT.h
index e64bba8b4dcfaae848ac13f38992c20da9599c6f..fa8031ce8498320a3456d807e5a205e7fdc8b2d8 100644
--- a/Pr/PrVeloUT/src/PrVeloUT.h
+++ b/Pr/PrVeloUT/src/PrVeloUT.h
@@ -24,18 +24,20 @@
 
 #include "PrKernel/UTHitHandler.h"
 
+#include "DetDesc/Condition.h"
+#include "DetDesc/ConditionAccessorHolder.h"
 #include "GaudiKernel/DataObject.h"
 #include "GaudiKernel/ObjectContainerBase.h"
 #include "GaudiKernel/Range.h"
 #include "Kernel/ILHCbMagnetSvc.h"
+#include "PrKernel/PrVeloUTTrack.h"
 #include "PrKernel/UTHit.h"
 #include "PrKernel/UTHitInfo.h"
 #include "PrUTMagnetTool.h"
 #include "TfKernel/IndexedHitContainer.h"
 #include "TfKernel/MultiIndexedHitContainer.h"
-
-#include "PrKernel/PrVeloUTTrack.h"
 #include "UTDAQ/UTDAQHelper.h"
+#include "UTDAQ/UTInfo.h"
 #include "vdt/log.h"
 #include "vdt/sqrt.h"
 
@@ -73,22 +75,45 @@ namespace LHCb::Pr {
       invKinkVeloDist = 1.0f / ( zKink - state.z );
     }
 
-    MiniState                          state;
-    std::array<const UT::Mut::Hit*, 4> bestHits = {nullptr, nullptr, nullptr, nullptr};
-    std::array<float, 4>               bestParams;
-    float                              wb, invKinkVeloDist, xMidField;
+    MiniState                                            state;
+    std::array<const UT::Mut::Hit*, UTInfo::TotalLayers> bestHits = {nullptr, nullptr, nullptr, nullptr};
+    std::array<float, 4>                                 bestParams;
+    float                                                wb, invKinkVeloDist, xMidField;
   };
 
-  class VeloUT : public Gaudi::Functional::Transformer<Upstream::Tracks( const Velo::Tracks&, const UT::HitHandler& )> {
+  struct UTGeometryInfo {
+    /// information about the different layers
+    std::array<UTDAQ::LayerInfo, UTInfo::TotalLayers>      layers;
+    std::array<UTDAQ::SectorsInStationZ, UTInfo::Stations> sectorsZ;
+  };
+
+  class VeloUT : public Gaudi::Functional::Transformer<Upstream::Tracks( const Velo::Tracks&, const UT::HitHandler&,
+                                                                         const UTGeometryInfo& ),
+                                                       LHCb::DetDesc::usesConditions<UTGeometryInfo>> {
   public:
     /// Standard constructor
     VeloUT( const std::string& name, ISvcLocator* pSvcLocator );
 
     StatusCode initialize() override;
 
-    Upstream::Tracks operator()( const Velo::Tracks&, const UT::HitHandler& ) const override final;
+    Upstream::Tracks operator()( const Velo::Tracks&, const UT::HitHandler&,
+                                 const UTGeometryInfo& ) const override final;
 
   private:
+    template <typename dType>
+    bool getState( const Velo::Tracks& inputTracks, int at, MiniState& trState, Upstream::Tracks& outputTracks ) const;
+
+    template <typename FudgeTable>
+    bool getHits( span<UT::Mut::Hits, UTInfo::TotalLayers> hitsInLayers, const UT::HitHandler& hh,
+                  const FudgeTable& fudgeFactors, const UTGeometryInfo&, MiniState& trState ) const;
+
+    bool formClusters( span<const UT::Mut::Hits, UTInfo::TotalLayers> hitsInLayers, TrackHelper& helper ) const;
+
+    template <typename dType, typename BdlTable>
+    void prepareOutputTrack( const Velo::Tracks& inputTracks, int ancestor, const TrackHelper& helper,
+                             span<const UT::Mut::Hits, UTInfo::TotalLayers> hitsInLayers,
+                             Upstream::Tracks& outputTracks, const BdlTable& bdlTable ) const;
+
     Gaudi::Property<float> m_minMomentum{this, "minMomentum", 1.5 * Gaudi::Units::GeV};
     Gaudi::Property<float> m_minPT{this, "minPT", 0.3 * Gaudi::Units::GeV};
     Gaudi::Property<float> m_minMomentumFinal{this, "minMomentumFinal", 2.5 * Gaudi::Units::GeV};
@@ -120,27 +145,9 @@ namespace LHCb::Pr {
     mutable Gaudi::Accumulators::SummingCounter<unsigned int> m_seedsCounter{this, "#seeds"};
     mutable Gaudi::Accumulators::SummingCounter<unsigned int> m_tracksCounter{this, "#tracks"};
 
-    StatusCode recomputeGeometry();
-
-    template <typename dType>
-    bool getState( const Velo::Tracks& inputTracks, int at, MiniState& trState, Upstream::Tracks& outputTracks ) const;
-
-    template <typename FudgeTable>
-    bool getHits( span<UT::Mut::Hits, 4> hitsInLayers, const UT::HitHandler& hh, const FudgeTable& fudgeFactors,
-                  MiniState& trState ) const;
-
-    bool formClusters( span<const UT::Mut::Hits, 4> hitsInLayers, TrackHelper& helper ) const;
-
-    template <typename dType, typename BdlTable>
-    void prepareOutputTrack( const Velo::Tracks& inputTracks, int ancestor, const TrackHelper& helper,
-                             span<const UT::Mut::Hits, 4> hitsInLayers, Upstream::Tracks& outputTracks,
-                             const BdlTable& bdlTable ) const;
-
-    DeUTDetector* m_utDet = nullptr;
-
     /// Multipupose tool for Bdl and deflection
-    ToolHandle<UTMagnetTool> m_PrUTMagnetTool{this, "PrUTMagnetTool", "PrUTMagnetTool"};
-    ILHCbMagnetSvc*          m_magFieldSvc = nullptr;
+    ToolHandle<UTMagnetTool>      m_PrUTMagnetTool{this, "PrUTMagnetTool", "PrUTMagnetTool"};
+    ServiceHandle<ILHCbMagnetSvc> m_magFieldSvc{this, "MagneticField", "MagneticFieldSvc"};
     /// timing tool
     mutable ToolHandle<ISequencerTimerTool> m_timerTool{this, "SequencerTimerTool", "SequencerTimerTool"}; // FIXME
     ///< Counter for timing tool
@@ -148,12 +155,9 @@ namespace LHCb::Pr {
 
     float m_zMidUT;
     float m_distToMomentum;
-    float m_zKink{1780.0};
-    float m_sigmaVeloSlope{0.10 * Gaudi::Units::mrad};
-    float m_invSigmaVeloSlope{10.0 / Gaudi::Units::mrad};
 
-    /// information about the different layers
-    std::array<UTDAQ::LayerInfo, 4>         m_layers;
-    std::array<UTDAQ::SectorsInStationZ, 2> m_sectorsZ;
+    constexpr static float c_zKink{1780.0};
+    constexpr static float c_sigmaVeloSlope{0.10 * Gaudi::Units::mrad};
+    constexpr static float c_invSigmaVeloSlope{10.0 / Gaudi::Units::mrad};
   };
 } // namespace LHCb::Pr