diff --git a/Control/PileUpComps/src/DigitizationAlg.cxx b/Control/PileUpComps/src/DigitizationAlg.cxx
index 1db3686d0aada63ed1abf3c1584aa1fc08475d50..961d8553efec9733aafa6c11586c6e42694345fb 100644
--- a/Control/PileUpComps/src/DigitizationAlg.cxx
+++ b/Control/PileUpComps/src/DigitizationAlg.cxx
@@ -30,7 +30,7 @@ StatusCode DigitizationAlg::execute()
     {
       // Reset the filter first
       puToolHandle->resetFilter();
-      ATH_CHECK(puToolHandle->processAllSubEvents());
+      ATH_CHECK(puToolHandle->processAllSubEvents(Gaudi::Hive::currentContext()));
       // Check if the event was filtered out by the current PileUpTool.
       if (!puToolHandle->filterPassed())
         {
diff --git a/Control/PileUpComps/src/PileUpToolsAlg.cxx b/Control/PileUpComps/src/PileUpToolsAlg.cxx
index fa564d5637bb144cbe1f0bf13ead64bee89ee057..8517c60abdf1be67679e934708473a7fd2cbcb42 100644
--- a/Control/PileUpComps/src/PileUpToolsAlg.cxx
+++ b/Control/PileUpComps/src/PileUpToolsAlg.cxx
@@ -79,7 +79,7 @@ StatusCode PileUpToolsAlg::execute()
       // Reset the filters
       puToolHandle->resetFilter();
       ATH_MSG_VERBOSE ( puToolHandle->name() << " will get " << eventsToProcessByTool[&(*puToolHandle)] << " subevents to process." );
-      ATH_CHECK(puToolHandle->prepareEvent(eventsToProcessByTool[&(*puToolHandle)]));
+      ATH_CHECK(puToolHandle->prepareEvent(Gaudi::Hive::currentContext(), eventsToProcessByTool[&(*puToolHandle)]));
     }
 
   // Loop over bunch-crossings and call processBunchXing for each
@@ -108,7 +108,7 @@ StatusCode PileUpToolsAlg::execute()
   // call mergeEvent for all PileUpTools
   for(auto& puToolHandle : m_puTools)
     {
-      ATH_CHECK(puToolHandle->mergeEvent());
+      ATH_CHECK(puToolHandle->mergeEvent(Gaudi::Hive::currentContext()));
       // Check if the event was filtered out by the current PileUpTool.
       if (!puToolHandle->filterPassed())
         {
diff --git a/Control/PileUpComps/src/TestPileUpTool.cxx b/Control/PileUpComps/src/TestPileUpTool.cxx
index dbe66d7c8877a4f8b93ac1e06e8d704b37838e7e..51be205e1c905e91a2083912144f73fb76dea4f9 100644
--- a/Control/PileUpComps/src/TestPileUpTool.cxx
+++ b/Control/PileUpComps/src/TestPileUpTool.cxx
@@ -13,13 +13,13 @@ TestPileUpTool::TestPileUpTool(const std::string& type,
 {
 }
 
-StatusCode TestPileUpTool::prepareEvent(unsigned int nInputEvents)
+StatusCode TestPileUpTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents)
 {
   ATH_MSG_INFO( "prepareEvent: expect to process " << nInputEvents << " events this time." );
   return StatusCode::SUCCESS;
 }
 
-StatusCode TestPileUpTool::mergeEvent()
+StatusCode TestPileUpTool::mergeEvent(const EventContext& /*ctx*/)
 {
   for (const auto& bc : m_seen)
     {
diff --git a/Control/PileUpComps/src/TestPileUpTool.h b/Control/PileUpComps/src/TestPileUpTool.h
index bf9a35adfe8488fd81776679880ff99d1ef6a4d0..b7fed896f74811cebd9ed4c76b343cfe1e21a080 100644
--- a/Control/PileUpComps/src/TestPileUpTool.h
+++ b/Control/PileUpComps/src/TestPileUpTool.h
@@ -27,10 +27,10 @@ public:
   /// \name IPileUpTool methods
   //@{
   ///called before the bunchXing loop
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+    virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode
diff --git a/Control/PileUpTools/PileUpTools/IPileUpTool.h b/Control/PileUpTools/PileUpTools/IPileUpTool.h
index 5926310c8199b2d8a7c9b8cdc33b8a94c05a8b5d..39e265554a7f5d8bbbf4a9062ff42fcca4c63d94 100644
--- a/Control/PileUpTools/PileUpTools/IPileUpTool.h
+++ b/Control/PileUpTools/PileUpTools/IPileUpTool.h
@@ -24,7 +24,7 @@ typedef std::vector<xAOD::EventInfo::SubEvent>::const_iterator SubEventIterator;
 class IPileUpTool : virtual public IAlgTool{
 public:
   ///called before the bunchXing loop
-  virtual StatusCode prepareEvent(unsigned int /*nInputEvents*/) { return StatusCode::SUCCESS; }
+  virtual StatusCode prepareEvent(const EventContext& /*ctx*/, unsigned int /*nInputEvents*/) { return StatusCode::SUCCESS; }
   ///called for each active bunch-crossing (time in ns)
   virtual StatusCode processBunchXing(int bunchXing,
                                       SubEventIterator bSubEvents,
@@ -33,10 +33,10 @@ public:
   /// implemented by default in PileUpToolBase as FirstXing<=bunchXing<=LastXing
   virtual bool toProcess(int bunchXing) const =0;
   ///called at the end of the bunchXing loop
-  virtual StatusCode mergeEvent() { return StatusCode::SUCCESS; }
+  virtual StatusCode mergeEvent(const EventContext& /*ctx*/) { return StatusCode::SUCCESS; }
   ///alternative interface which uses the PileUpMergeSvc to obtain all
   ///the required SubEvents.
-  virtual StatusCode processAllSubEvents() = 0;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) = 0;
   ///flags whether the event should be removed or not
   virtual bool filterPassed() const =0;
   ///reset the filter
@@ -45,4 +45,5 @@ public:
   /// Creates the InterfaceID and interfaceID() method
   DeclareInterfaceID(IPileUpTool, 1, 0 );
 };
+
 #endif // PILEUPTOOLS_IPILEUPTOOL_H
diff --git a/Control/PileUpTools/PileUpTools/PileUpToolBase.h b/Control/PileUpTools/PileUpTools/PileUpToolBase.h
index 4778e8b58b964abe2de448166c7fcd5ed9988f2a..a3449db1e7703b0369ad0a7726af49bdc8059298 100644
--- a/Control/PileUpTools/PileUpTools/PileUpToolBase.h
+++ b/Control/PileUpTools/PileUpTools/PileUpToolBase.h
@@ -37,7 +37,8 @@ public:
   }
   ///dummy implementation to allow compilation while all Digitization
   ///packages are migrated to use this new interface.
-  virtual StatusCode processAllSubEvents() override {
+  using IPileUpTool::processAllSubEvents;
+  virtual StatusCode processAllSubEvents(const EventContext&) override {
     return StatusCode::SUCCESS;
   }
   virtual StatusCode
diff --git a/DataQuality/DataQualityTools/CMakeLists.txt b/DataQuality/DataQualityTools/CMakeLists.txt
index ab6551efdb1663e60f1775a4f099b9c671d93b75..766347768658e94a41d2f9e5cab7867e4b2d345f 100644
--- a/DataQuality/DataQualityTools/CMakeLists.txt
+++ b/DataQuality/DataQualityTools/CMakeLists.txt
@@ -47,6 +47,8 @@ atlas_depends_on_subdirs(
                           Trigger/TrigEvent/TrigParticle
                           Trigger/TrigT1/TrigT1Result 
                           PhysicsAnalysis/MuonID/MuonSelectorTools
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions
 )
 
 # External dependencies:
@@ -60,7 +62,7 @@ atlas_add_component( DataQualityTools
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} CaloGeoHelpers AthenaBaseComps AthenaMonitoringLib StoreGateLib SGtests xAODCaloEvent xAODEventInfo xAODJet xAODMissingET xAODMuon xAODTracking LUCID_RawEvent ZdcEvent ZdcIdentifier GaudiKernel InDetIdentifier InDetRawData InDetReadoutGeometry InDetPrepRawData LArRawEvent LArRecEvent MagFieldInterfaces MuonCalibITools MuonIdHelpersLib MuonRDO MuonRecHelperToolsLib TagEvent RecBackgroundEvent RecoToolInterfaces TileEvent LWHists TrkParameters TrkExInterfaces TrkVertexAnalysisUtilsLib TrigDecisionToolLib TrigCaloEvent TrigMuonEvent TrigParticle TrigT1Result MuonSelectorToolsLib )
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} CaloGeoHelpers AthenaBaseComps AthenaMonitoringLib StoreGateLib SGtests xAODCaloEvent xAODEventInfo xAODJet xAODMissingET xAODMuon xAODTracking LUCID_RawEvent ZdcEvent ZdcIdentifier GaudiKernel InDetIdentifier InDetRawData InDetReadoutGeometry InDetPrepRawData LArRawEvent LArRecEvent MagFieldInterfaces MuonCalibITools MuonIdHelpersLib MuonRDO MuonRecHelperToolsLib TagEvent RecBackgroundEvent RecoToolInterfaces TileEvent LWHists TrkParameters TrkExInterfaces TrkVertexAnalysisUtilsLib TrigDecisionToolLib TrigCaloEvent TrigMuonEvent TrigParticle TrigT1Result MuonSelectorToolsLib MagFieldElements MagFieldConditions)
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py )
diff --git a/DataQuality/DataQualityTools/DataQualityTools/DQTDetSynchMonAlg.h b/DataQuality/DataQualityTools/DataQualityTools/DQTDetSynchMonAlg.h
index bacd75e4f6435d1c198496ae1b6686d93bc0092b..d1dcfdad28821e39f531394ae8530fc0057f43c3 100644
--- a/DataQuality/DataQualityTools/DataQualityTools/DQTDetSynchMonAlg.h
+++ b/DataQuality/DataQualityTools/DataQualityTools/DQTDetSynchMonAlg.h
@@ -30,6 +30,11 @@
 #include "MuonRDO/RpcPadContainer.h"
 
 #include "AthenaMonitoring/AthMonitorAlgorithm.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 namespace Trk {
    class IMagFieldSvc;
@@ -78,6 +83,10 @@ private:
     { "TileDigitsFlt" };
   SG::ReadHandleKey<RpcPadContainer> m_RpcPadContainerKey
     { "RPCPAD" };
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                       "Name of the Magnetic Field conditions object key"};
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 };
 
 #endif
diff --git a/DataQuality/DataQualityTools/DataQualityTools/DQTDetSynchMonTool.h b/DataQuality/DataQualityTools/DataQualityTools/DQTDetSynchMonTool.h
index b1eb3b2b7cb7cc937514d8c10b3e11d899a8aeaa..4fcc7609eab53ac77b40fe0af1ffae8ea5a455b3 100644
--- a/DataQuality/DataQualityTools/DataQualityTools/DQTDetSynchMonTool.h
+++ b/DataQuality/DataQualityTools/DataQualityTools/DQTDetSynchMonTool.h
@@ -28,6 +28,12 @@
 #include "TileEvent/TileDigitsContainer.h"
 #include "LArRawEvent/LArFebHeaderContainer.h"
 #include "MuonRDO/RpcPadContainer.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 
 namespace Trk {
    //REL18 class IMagneticFieldTool; 
@@ -50,7 +56,7 @@ class DQTDetSynchMonTool: public DataQualityFatherMonTool
     
   StatusCode bookHistograms( );
   //StatusCode bookHistograms( bool isNewEventsBlock, bool isNewLumiBlock, bool isNewRun );
-  StatusCode fillHistograms();
+  StatusCode fillHistograms( );
   StatusCode procHistograms( );
   //StatusCode procHistograms( bool isEndOfEventsBlock, bool isEndOfLumiBlock, bool isEndOfRun );
   StatusCode checkHists(bool fromFinalize);
@@ -276,6 +282,11 @@ private:
     { "TileDigitsFlt" };
   SG::ReadHandleKey<RpcPadContainer> m_RpcPadContainerKey
     { "RPCPAD" };
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                       "Name of the Magnetic Field conditions object key"};
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 };
 
 #endif
diff --git a/DataQuality/DataQualityTools/src/DQTDetSynchMonAlg.cxx b/DataQuality/DataQualityTools/src/DQTDetSynchMonAlg.cxx
index 382b17b4fb63c589f0ba96ca791d820b7ee8f856..73fb2a17bf24be595a5540f2a2f15ef768e86aca 100644
--- a/DataQuality/DataQualityTools/src/DQTDetSynchMonAlg.cxx
+++ b/DataQuality/DataQualityTools/src/DQTDetSynchMonAlg.cxx
@@ -64,6 +64,10 @@ StatusCode DQTDetSynchMonAlg::initialize() {
   ATH_CHECK( m_TileDigitsContainerKey.initialize() );
   ATH_CHECK( m_RpcPadContainerKey.initialize() );
   ATH_CHECK( m_field.retrieve() );
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
   return AthMonitorAlgorithm::initialize();
 }
 
@@ -390,15 +394,33 @@ StatusCode DQTDetSynchMonAlg::fillHistograms( const EventContext& ctx ) const
 	tile_l1id16, rpcl1id, pixell1id, diffx, diffy);
 
 
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
    // B field
    Amg::Vector3D f; 
    Amg::Vector3D gP1(m_solenoidPositionX, m_solenoidPositionY, m_solenoidPositionZ);
-   m_field->getField(&gP1,&f);
+   MagField::AtlasFieldCache    fieldCache;
+   SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+   const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+
+   if (fieldCondObj == nullptr) {
+       ATH_MSG_ERROR("DQTDetSynchMonAlg: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+       return StatusCode::FAILURE;
+   }
+   fieldCondObj->getInitializedCache (fieldCache);
+
+   // MT version uses cache, temporarily keep old version
+   if (fieldCache.useNewBfieldCache()) fieldCache.getField(gP1.data(),f.data());
+   else                                 m_field->getField(&gP1,&f);
+
    // field is in kilotesla (!)
    auto solenoid_bz = Monitored::Scalar("solenoid_bz", f[2]*1000.);
 
    Amg::Vector3D  gP2(m_toroidPositionX, m_toroidPositionY, m_toroidPositionZ);
-   m_field->getField(&gP2,&f);
+
+   // MT version uses cache, temporarily keep old version
+   if (fieldCache.useNewBfieldCache()) fieldCache.getField(gP2.data(),f.data());
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+
    auto toroid_bx = Monitored::Scalar("toroid_bx", f[0]*1000.);
 
    fill("bfield", solenoid_bz, toroid_bx, lb);
diff --git a/DataQuality/DataQualityTools/src/DQTDetSynchMonTool.cxx b/DataQuality/DataQualityTools/src/DQTDetSynchMonTool.cxx
index 1de8a26c87697b103108a42b82c241d766366d36..52a02adc5053fd507dbe6b9961e96e20c01bdda7 100644
--- a/DataQuality/DataQualityTools/src/DQTDetSynchMonTool.cxx
+++ b/DataQuality/DataQualityTools/src/DQTDetSynchMonTool.cxx
@@ -208,6 +208,9 @@ StatusCode DQTDetSynchMonTool::initialize() {
   ATH_CHECK( m_LArFebHeaderContainerKey.initialize() );
   ATH_CHECK( m_TileDigitsContainerKey.initialize() );
   ATH_CHECK( m_RpcPadContainerKey.initialize() );
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
   return DataQualityFatherMonTool::initialize();
 }
 
@@ -1154,7 +1157,24 @@ StatusCode DQTDetSynchMonTool::fillHistograms()
    Amg::Vector3D gP1(m_solenoidPositionX, m_solenoidPositionY, m_solenoidPositionZ);
    //REL18 Trk::GlobalPosition gP1(m_solenoidPositionX, m_solenoidPositionY, m_solenoidPositionZ);
    //REL19 
-   m_field->getField(&gP1,&f);
+//   m_field->getField(&gP1,&f);
+////////////////////////////////////////////////////////////////////////////////////////////////////
+   MagField::AtlasFieldCache    fieldCache;
+
+   SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, Gaudi::Hive::currentContext()};
+   const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+
+   if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("DQTDetSynchMonAlg: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return StatusCode::FAILURE;
+   }
+
+   fieldCondObj->getInitializedCache (fieldCache);
+
+   // MT version uses cache, temporarily keep old version
+   if (fieldCache.useNewBfieldCache()) fieldCache.getField  (gP1.data(),f.data());
+   else                                m_field->getField    (&gP1,&f);
+
    //REL18 m_field->getMagneticFieldKiloGauss(gP1,f);
    float solenoid_bz = f[2];
    //REL19: field is in kilotesla (!)
@@ -1167,7 +1187,12 @@ StatusCode DQTDetSynchMonTool::fillHistograms()
    Amg::Vector3D  gP2(m_toroidPositionX, m_toroidPositionY, m_toroidPositionZ);
    //REL18 Trk::GlobalPosition gP2(m_toroidPositionX, m_toroidPositionY, m_toroidPositionZ);
    //REL19 
-   m_field->getField(&gP2,&f);
+
+   // MT version uses cache, temporarily keep old version
+   if (fieldCache.useNewBfieldCache()) fieldCache.getField (gP2.data(),f.data());
+   else                                m_field->getField   (&gP2,&f);
+
+
    //REL18 m_field->getMagneticFieldKiloGauss(gP2,f);
    float toroid_bx = f[0];
    //REL19: field is in kilotesla (!)
@@ -1274,6 +1299,5 @@ float DQTDetSynchMonTool::findfrac(std::multiset<uint32_t>& mset, uint16_t ctpid
   else
     frac = 1.0; //set frac = 1 if totalCounter counts zero
 
-  //std::cout << "Returning frac: " << nonctpIdCounter << "/" << totalCounter << "=" << frac << std::endl;
   return frac;
 }
diff --git a/ForwardDetectors/AFP/AFP_Digitization/AFP_Digitization/AFP_PileUpTool.h b/ForwardDetectors/AFP/AFP_Digitization/AFP_Digitization/AFP_PileUpTool.h
index ebf8d8dc979b3fbb368d088947e3c7768c7d95b7..766d84bf2696b3f350313321947032366a4a4ef0 100644
--- a/ForwardDetectors/AFP/AFP_Digitization/AFP_Digitization/AFP_PileUpTool.h
+++ b/ForwardDetectors/AFP/AFP_Digitization/AFP_Digitization/AFP_PileUpTool.h
@@ -49,7 +49,7 @@ class AFP_PileUpTool: public PileUpToolBase {
   virtual StatusCode finalize() override final;
 
   /// called before the subevts loop. Not (necessarily) able to access SubEvents
-  virtual StatusCode prepareEvent(const unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, const unsigned int nInputEvents) override final;
   
   /// called for each active bunch-crossing to process current SubEvents bunchXing is in ns
   virtual StatusCode processBunchXing(
@@ -62,9 +62,9 @@ class AFP_PileUpTool: public PileUpToolBase {
   //  virtual bool toProcess(int bunchXing) const;
 
   /// called at the end of the subevts loop. Not (necessarily) able to access SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
  private:
   
diff --git a/ForwardDetectors/AFP/AFP_Digitization/src/AFP_DigiTop.cxx b/ForwardDetectors/AFP/AFP_Digitization/src/AFP_DigiTop.cxx
index 9e090fb15edc36a6c6a5d730fadf976d49e5fb55..e38954dee067f1a915a81dd55380a701251287a6 100644
--- a/ForwardDetectors/AFP/AFP_Digitization/src/AFP_DigiTop.cxx
+++ b/ForwardDetectors/AFP/AFP_Digitization/src/AFP_DigiTop.cxx
@@ -21,5 +21,5 @@ StatusCode AFP_DigiTop::initialize()
 StatusCode AFP_DigiTop::execute()
 {
   ATH_MSG_DEBUG ( "AFP_DigiTop::execute" );
-  return m_digTool->processAllSubEvents();
+  return m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/ForwardDetectors/AFP/AFP_Digitization/src/AFP_PileUpTool.cxx b/ForwardDetectors/AFP/AFP_Digitization/src/AFP_PileUpTool.cxx
index 82754b30510a2dace74239dfd13de77be4da9d43..a96f9826539f3006b83f6b82517607ae97a165d3 100644
--- a/ForwardDetectors/AFP/AFP_Digitization/src/AFP_PileUpTool.cxx
+++ b/ForwardDetectors/AFP/AFP_Digitization/src/AFP_PileUpTool.cxx
@@ -131,7 +131,7 @@ StatusCode AFP_PileUpTool::initialize() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode AFP_PileUpTool::processAllSubEvents() {
+StatusCode AFP_PileUpTool::processAllSubEvents(const EventContext& /*ctx*/) {
 
   ATH_MSG_DEBUG ( "AFP_PileUpTool::processAllSubEvents()" );
  
@@ -231,7 +231,7 @@ StatusCode AFP_PileUpTool::processAllSubEvents() {
 }
 
 
-StatusCode AFP_PileUpTool::prepareEvent(const unsigned int nInputEvents){
+StatusCode AFP_PileUpTool::prepareEvent(const EventContext& /*ctx*/, const unsigned int nInputEvents){
 
   ATH_MSG_DEBUG ( "AFP_PileUpTool::prepareEvent() called for " << nInputEvents << " input events" );
  
@@ -254,8 +254,8 @@ StatusCode AFP_PileUpTool::prepareEvent(const unsigned int nInputEvents){
 }
 
 StatusCode AFP_PileUpTool::processBunchXing(int bunchXing,
-                                                 SubEventIterator bSubEvents,
-                                                 SubEventIterator eSubEvents) {
+                                            SubEventIterator bSubEvents,
+                                            SubEventIterator eSubEvents) {
 
   ATH_MSG_DEBUG ( "AFP_PileUpTool::processBunchXing() " << bunchXing );
   SubEventIterator iEvt = bSubEvents;
@@ -310,7 +310,7 @@ StatusCode AFP_PileUpTool::processBunchXing(int bunchXing,
   return StatusCode::SUCCESS;
 }
 
-StatusCode AFP_PileUpTool::mergeEvent(){
+StatusCode AFP_PileUpTool::mergeEvent(const EventContext& /*ctx*/){
  
   fillTDDigiCollection(m_mergedTDSimHitList, m_rndEngine);
   fillSiDigiCollection(m_mergedSIDSimHitList);
diff --git a/ForwardDetectors/ALFA/ALFA_Digitization/ALFA_Digitization/ALFA_PileUpTool.h b/ForwardDetectors/ALFA/ALFA_Digitization/ALFA_Digitization/ALFA_PileUpTool.h
index 21e3913a3c6ae912a03b6bbbb48a9219017a082b..197b3f6f513ff7826eb63ff823d3a3297e51fbe6 100644
--- a/ForwardDetectors/ALFA/ALFA_Digitization/ALFA_Digitization/ALFA_PileUpTool.h
+++ b/ForwardDetectors/ALFA/ALFA_Digitization/ALFA_Digitization/ALFA_PileUpTool.h
@@ -44,7 +44,7 @@ class ALFA_PileUpTool: public PileUpToolBase {
   
   /// code taken from ZDC; author (highly) probably John Chapman
   /// called before the subevts loop. Not (necessarily) able to access SubEvents
-  virtual StatusCode prepareEvent(const unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, const unsigned int nInputEvents) override final;
   
   /// called for each active bunch-crossing to process current SubEvents bunchXing is in ns
   virtual  StatusCode processBunchXing(
@@ -57,9 +57,9 @@ class ALFA_PileUpTool: public PileUpToolBase {
   //  virtual bool toProcess(int bunchXing) const;
 
   /// called at the end of the subevts loop. Not (necessarily) able to access SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
  private:
   
diff --git a/ForwardDetectors/ALFA/ALFA_Digitization/src/ALFA_DigiAlg.cxx b/ForwardDetectors/ALFA/ALFA_Digitization/src/ALFA_DigiAlg.cxx
index 389a4ec2914614102e4ce98d350aa98578582a53..b98f37eefbde492f0ccf48dfc2978e3f233ef0d1 100644
--- a/ForwardDetectors/ALFA/ALFA_Digitization/src/ALFA_DigiAlg.cxx
+++ b/ForwardDetectors/ALFA/ALFA_Digitization/src/ALFA_DigiAlg.cxx
@@ -27,7 +27,7 @@ StatusCode ALFA_DigiAlg::execute()
 {
   ATH_MSG_DEBUG ( "ALFA_DigiAlg::execute" );
   
-  return m_digiTool->processAllSubEvents();
+  return m_digiTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
 
 StatusCode ALFA_DigiAlg::finalize() 
diff --git a/ForwardDetectors/ALFA/ALFA_Digitization/src/ALFA_PileUpTool.cxx b/ForwardDetectors/ALFA/ALFA_Digitization/src/ALFA_PileUpTool.cxx
index a4cce2f2d08a7c80e8935a4a8416ef91950e9d6b..730b51b0e3bc996309acda4fbe1cc94ff19bc52d 100644
--- a/ForwardDetectors/ALFA/ALFA_Digitization/src/ALFA_PileUpTool.cxx
+++ b/ForwardDetectors/ALFA/ALFA_Digitization/src/ALFA_PileUpTool.cxx
@@ -125,7 +125,7 @@ StatusCode ALFA_PileUpTool::initialize(){
 
 // *********************************************************************************
 
-StatusCode ALFA_PileUpTool::processAllSubEvents() {
+StatusCode ALFA_PileUpTool::processAllSubEvents(const EventContext& /*ctx*/) {
 
   ATH_MSG_DEBUG ("ALFA_PileUpTool::processAllSubEvents()");
 
@@ -240,7 +240,7 @@ StatusCode ALFA_PileUpTool::processAllSubEvents() {
 
 
 
-StatusCode ALFA_PileUpTool::prepareEvent(const unsigned int nInputEvents){
+StatusCode ALFA_PileUpTool::prepareEvent(const EventContext& /*ctx*/, const unsigned int nInputEvents){
 
   ATH_MSG_DEBUG ( "ALFA_PileUpTool::prepareEvent() called for " << nInputEvents << " input events" );
  
@@ -318,7 +318,7 @@ StatusCode ALFA_PileUpTool::processBunchXing(int bunchXing,
 
 
 
-StatusCode ALFA_PileUpTool::mergeEvent(){
+StatusCode ALFA_PileUpTool::mergeEvent(const EventContext& /*ctx*/){
 
 
   ALFA_MD_info(m_mergedALFA_HitList);
diff --git a/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_Digitization.cxx b/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_Digitization.cxx
index 14a196684ee2b0ba4a3e3394b4ccbfc7ba35cc65..4f6b2c6ec370cfbfd0ace0d623b45f5587bb92a9 100644
--- a/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_Digitization.cxx
+++ b/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_Digitization.cxx
@@ -22,5 +22,5 @@ StatusCode LUCID_DigiTop::initialize() {
 
 StatusCode LUCID_DigiTop::execute() {
   ATH_MSG_DEBUG("execute()");
-  return m_mergeTool->processAllSubEvents();
+  return m_mergeTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_PileUpTool.cxx b/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_PileUpTool.cxx
index f3602be83292f13a12e18fe61b98d9622ca191a4..f2407ca941e3919bcaea752e833cd3e1ddd335de 100644
--- a/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_PileUpTool.cxx
+++ b/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_PileUpTool.cxx
@@ -120,7 +120,7 @@ StatusCode LUCID_PileUpTool::initialize()
 }
 
 /// ----------------------------------------------------------------------------------------------------
-StatusCode LUCID_PileUpTool::prepareEvent(const unsigned int nInputEvents)
+StatusCode LUCID_PileUpTool::prepareEvent(const EventContext& /*ctx*/, const unsigned int nInputEvents)
 {
   ATH_MSG_DEBUG ( "prepareEvent() called for " << nInputEvents << " input events" );
 
@@ -175,7 +175,7 @@ StatusCode LUCID_PileUpTool::processBunchXing(int bunchXing,
 }
 
 /// ----------------------------------------------------------------------------------------------------
-StatusCode LUCID_PileUpTool::mergeEvent()
+StatusCode LUCID_PileUpTool::mergeEvent(const EventContext& /*ctx*/)
 {
   CHECK(m_digitToolBox->fillDigitContainer(m_mergedhitList, m_rndEngine));
   ATH_MSG_DEBUG ( " LUCID_DigitContainer successfully registered in StoreGate " );
@@ -184,7 +184,7 @@ StatusCode LUCID_PileUpTool::mergeEvent()
 }
 
 /// ----------------------------------------------------------------------------------------------------
-StatusCode LUCID_PileUpTool::processAllSubEvents()
+StatusCode LUCID_PileUpTool::processAllSubEvents(const EventContext& /*ctx*/)
 {
   ATH_MSG_VERBOSE ( "processAllSubEvents()" );
   if(!m_mergeSvc)
diff --git a/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_PileUpTool.h b/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_PileUpTool.h
index c012d728fcf189bf8ee08a705712e156812fc6e0..57696b81e7e6f810836e30473f7b275d2c063ad7 100644
--- a/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_PileUpTool.h
+++ b/ForwardDetectors/LUCID/LUCID_Digitization/src/LUCID_PileUpTool.h
@@ -40,7 +40,7 @@ public:
   virtual StatusCode finalize() override final;
 
   /// called before the subevts loop. Not (necessarily) able to access SubEvents
-  virtual StatusCode prepareEvent(const unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, const unsigned int nInputEvents) override final;
 
   /// called for each active bunch-crossing to process current SubEvents bunchXing is in ns
   virtual StatusCode processBunchXing(int bunchXing,
@@ -51,10 +51,10 @@ public:
   //  virtual bool toProcess(int bunchXing) const override final;
 
   /// called at the end of the subevts loop. Not (necessarily) able to access SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
   /// perform the digitization - used by LUCID_DigiTop::execute
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
 private:
 
diff --git a/ForwardDetectors/ZDC/ZDC_SimuDigitization/ZDC_SimuDigitization/ZDC_PileUpTool.h b/ForwardDetectors/ZDC/ZDC_SimuDigitization/ZDC_SimuDigitization/ZDC_PileUpTool.h
index 2220c72b2e7c9ec8cd800dad5c6c10c0faf62e47..c36fc37aa67e1ffef4dac2c55f00911c557d78b8 100644
--- a/ForwardDetectors/ZDC/ZDC_SimuDigitization/ZDC_SimuDigitization/ZDC_PileUpTool.h
+++ b/ForwardDetectors/ZDC/ZDC_SimuDigitization/ZDC_SimuDigitization/ZDC_PileUpTool.h
@@ -37,10 +37,10 @@ class ZDC_PileUpTool: public PileUpToolBase {
   virtual StatusCode finalize() override final;
 
   /// called before the subevts loop. Not (necessarily) able to access SubEvents
-  virtual StatusCode prepareEvent(const unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx,const unsigned int nInputEvents) override final;
 
   /// called for each active bunch-crossing to process current SubEvents bunchXing is in ns
-    virtual StatusCode processBunchXing(
+  virtual StatusCode processBunchXing(
                                         int bunchXing,
                                         SubEventIterator bSubEvents,
                                         SubEventIterator eSubEvents
@@ -50,9 +50,9 @@ class ZDC_PileUpTool: public PileUpToolBase {
   //  virtual bool toProcess(int bunchXing) const;
 
   /// called at the end of the subevts loop. Not (necessarily) able to access SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
  private:
 
diff --git a/ForwardDetectors/ZDC/ZDC_SimuDigitization/src/ZDC_DigiTop.cxx b/ForwardDetectors/ZDC/ZDC_SimuDigitization/src/ZDC_DigiTop.cxx
index 8663df9a3dd5e67bdde38d596afaef70238bd6f6..9c2b96857f404142759c3503ef3c01cb6f584d06 100644
--- a/ForwardDetectors/ZDC/ZDC_SimuDigitization/src/ZDC_DigiTop.cxx
+++ b/ForwardDetectors/ZDC/ZDC_SimuDigitization/src/ZDC_DigiTop.cxx
@@ -21,5 +21,5 @@ StatusCode ZDC_DigiTop::execute()
 {
   ATH_MSG_DEBUG ( "ZDC_DigiTop::execute" );
 
-  return m_digTool->processAllSubEvents();
+  return m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/ForwardDetectors/ZDC/ZDC_SimuDigitization/src/ZDC_PileUpTool.cxx b/ForwardDetectors/ZDC/ZDC_SimuDigitization/src/ZDC_PileUpTool.cxx
index 0cfb17a0ca212dc528371024641c650602c8a9d4..88328727d8eb9b952ffe1e11cbbbc96bc200abc5 100644
--- a/ForwardDetectors/ZDC/ZDC_SimuDigitization/src/ZDC_PileUpTool.cxx
+++ b/ForwardDetectors/ZDC/ZDC_SimuDigitization/src/ZDC_PileUpTool.cxx
@@ -57,7 +57,7 @@ StatusCode ZDC_PileUpTool::initialize() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode ZDC_PileUpTool::processAllSubEvents() {
+StatusCode ZDC_PileUpTool::processAllSubEvents(const EventContext& /*ctx*/) {
 
   ATH_MSG_DEBUG ( "ZDC_PileUpTool::processAllSubEvents()" );
 
@@ -128,7 +128,7 @@ StatusCode ZDC_PileUpTool::processAllSubEvents() {
   
   return StatusCode::SUCCESS;
 }
-StatusCode ZDC_PileUpTool::prepareEvent(const unsigned int nInputEvents){
+StatusCode ZDC_PileUpTool::prepareEvent(const EventContext& /*ctx*/, const unsigned int nInputEvents){
 
   ATH_MSG_DEBUG ( "ZDC_PileUpTool::prepareEvent() called for " << nInputEvents << " input events" );
  
@@ -196,7 +196,7 @@ StatusCode ZDC_PileUpTool::processBunchXing(int bunchXing,
   return StatusCode::SUCCESS;
 }
 
-StatusCode ZDC_PileUpTool::mergeEvent(){
+StatusCode ZDC_PileUpTool::mergeEvent(const EventContext& /*ctx*/){
  
   fillStripDigitContainer(m_mergedStripHitList, m_rndEngine);
   fillPixelDigitContainer(m_mergedPixelHitList, m_rndEngine);
diff --git a/InnerDetector/InDetConditions/InDetCondTools/InDetCondTools/ISiLorentzAngleTool.h b/InnerDetector/InDetConditions/InDetCondTools/InDetCondTools/ISiLorentzAngleTool.h
index 1eb0058c3167cadc2e36322b8a76da7cdfcb8d79..d62f2c9e940e260ddcf08e6b032224a196e27dab 100644
--- a/InnerDetector/InDetConditions/InDetCondTools/InDetCondTools/ISiLorentzAngleTool.h
+++ b/InnerDetector/InDetConditions/InDetCondTools/InDetCondTools/ISiLorentzAngleTool.h
@@ -11,6 +11,8 @@
 
 //Gaudi Includes
 #include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
+#include "GaudiKernel/ThreadLocalContext.h"
 // Amg
 #include "GeoPrimitives/GeoPrimitives.h"
 
diff --git a/InnerDetector/InDetConditions/SiLorentzAngleTool/CMakeLists.txt b/InnerDetector/InDetConditions/SiLorentzAngleTool/CMakeLists.txt
index 0f3000a5e012af26cc45444511df25ad43d559da..514fc4722099eb4da2a8eaa177e7bd958456571d 100644
--- a/InnerDetector/InDetConditions/SiLorentzAngleTool/CMakeLists.txt
+++ b/InnerDetector/InDetConditions/SiLorentzAngleTool/CMakeLists.txt
@@ -24,7 +24,10 @@ atlas_depends_on_subdirs( PUBLIC
                           InnerDetector/InDetConditions/InDetConditionsSummaryService
                           InnerDetector/InDetDetDescr/InDetIdentifier
                           InnerDetector/InDetDetDescr/InDetReadoutGeometry
-			  InnerDetector/InDetDetDescr/PixelReadoutGeometry )
+			  InnerDetector/InDetDetDescr/PixelReadoutGeometry
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions
+			  )
 
 # External dependencies:
 find_package( Eigen )
@@ -34,7 +37,7 @@ atlas_add_component( SiLorentzAngleTool
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${EIGEN_LIBRARIES} AthenaBaseComps AthenaKernel StoreGateLib SGtests GeoPrimitives GaudiKernel SiPropertiesToolLib MagFieldInterfaces AthenaPoolUtilities Identifier InDetIdentifier InDetReadoutGeometry PixelReadoutGeometry)
+                     LINK_LIBRARIES ${EIGEN_LIBRARIES} AthenaBaseComps AthenaKernel StoreGateLib SGtests GeoPrimitives GaudiKernel SiPropertiesToolLib MagFieldInterfaces AthenaPoolUtilities Identifier InDetIdentifier InDetReadoutGeometry PixelReadoutGeometry MagFieldElements MagFieldConditions)
 
 # Run tests:
 atlas_add_test( TestSCTLorentzAngle
diff --git a/InnerDetector/InDetConditions/SiLorentzAngleTool/src/PixelSiLorentzAngleCondAlg.cxx b/InnerDetector/InDetConditions/SiLorentzAngleTool/src/PixelSiLorentzAngleCondAlg.cxx
index aae1d57a51ae6e2cd1abcae0a18dfed8896b5ae5..2ef72d9dadf56af32c267791ee33b9ced09b2095 100644
--- a/InnerDetector/InDetConditions/SiLorentzAngleTool/src/PixelSiLorentzAngleCondAlg.cxx
+++ b/InnerDetector/InDetConditions/SiLorentzAngleTool/src/PixelSiLorentzAngleCondAlg.cxx
@@ -4,7 +4,6 @@
 
 #include "PixelSiLorentzAngleCondAlg.h"
 
-#include "GaudiKernel/SystemOfUnits.h"
 #include "GaudiKernel/PhysicalConstants.h"
 
 #include "MagFieldInterfaces/IMagFieldSvc.h"
@@ -13,22 +12,21 @@
 #include "SiPropertiesTool/SiliconProperties.h"
 
 PixelSiLorentzAngleCondAlg::PixelSiLorentzAngleCondAlg(const std::string& name, ISvcLocator* pSvcLocator):
-  ::AthAlgorithm(name, pSvcLocator),
+  ::AthReentrantAlgorithm(name, pSvcLocator),
   m_pixid(nullptr),
   m_condSvc("CondSvc", name),
   m_magFieldSvc("AtlasFieldSvc", name)
 {
   declareProperty("MagFieldSvc", m_magFieldSvc);
-  declareProperty("NominalField", m_nominalField = 2.0834*Gaudi::Units::tesla);
-  declareProperty("UseMagFieldSvc", m_useMagFieldSvc = true);
-  declareProperty("UseMagFieldDcs", m_useMagFieldDcs = true);
-  declareProperty("CorrectionFactor", m_correctionFactor = 0.9);
 }
 
 StatusCode PixelSiLorentzAngleCondAlg::initialize() {
   ATH_MSG_DEBUG("PixelSiLorentzAngleCondAlg::initialize()");
 
-  ATH_CHECK(detStore()->retrieve(m_pixid,"PixelID"));
+  const PixelID* idHelper{nullptr};
+  ATH_CHECK(detStore()->retrieve(idHelper,"PixelID"));
+  m_maxHash = idHelper->wafer_hash_max();
+
   ATH_CHECK(m_condSvc.retrieve());
 
   ATH_CHECK(m_readKeyTemp.initialize());
@@ -42,6 +40,9 @@ StatusCode PixelSiLorentzAngleCondAlg::initialize() {
   ATH_CHECK(m_siPropertiesTool.retrieve());
 
   if (m_useMagFieldSvc) {
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     ATH_CHECK(m_magFieldSvc.retrieve());
     if (m_useMagFieldDcs) {
       ATH_CHECK(m_readKeyBFieldSensor.initialize());
@@ -56,11 +57,14 @@ StatusCode PixelSiLorentzAngleCondAlg::initialize() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode 
-PixelSiLorentzAngleCondAlg::execute() {
+////////////////////////////////////////////////////////////////////////////////////////////////
+StatusCode
+PixelSiLorentzAngleCondAlg::execute(const EventContext& ctx) const {
+////////////////////////////////////////////////////////////////////////////////////////////////
+
   ATH_MSG_DEBUG("PixelSiLorentzAngleCondAlg::execute()");
 
-  SG::WriteCondHandle<SiLorentzAngleCondData> writeHandle{m_writeKey};
+  SG::WriteCondHandle<SiLorentzAngleCondData> writeHandle{m_writeKey, ctx};
   if (writeHandle.isValid()) {
     ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid." << " In theory this should not be called, but may happen" << " if multiple concurrent events are being processed out of order.");
     return StatusCode::SUCCESS;
@@ -76,7 +80,7 @@ PixelSiLorentzAngleCondAlg::execute() {
   EventIDRange rangeBField{eidStart, eidStop};
 
   // Read Cond Handle (temperature)
-  SG::ReadCondHandle<PixelDCSTempData> readHandleTemp(m_readKeyTemp);
+  SG::ReadCondHandle<PixelDCSTempData> readHandleTemp(m_readKeyTemp, ctx);
   const PixelDCSTempData* readCdoTemp(*readHandleTemp);
   if (readCdoTemp==nullptr) {
     ATH_MSG_FATAL("Null pointer to the read conditions object");
@@ -91,7 +95,7 @@ PixelSiLorentzAngleCondAlg::execute() {
   ATH_MSG_DEBUG("Input is " << readHandleTemp.fullKey() << " with the range of " << rangeTemp);
 
   // Read Cond Handle (HV)
-  SG::ReadCondHandle<PixelDCSHVData> readHandleHV(m_readKeyHV);
+  SG::ReadCondHandle<PixelDCSHVData> readHandleHV(m_readKeyHV, ctx);
   const PixelDCSHVData* readCdoHV(*readHandleHV);
   if (readCdoHV==nullptr) {
     ATH_MSG_FATAL("Null pointer to the read conditions object");
@@ -111,10 +115,24 @@ PixelSiLorentzAngleCondAlg::execute() {
     return StatusCode::FAILURE;
   }
 
+  // Field cache object for field calculations
+  MagField::AtlasFieldCache    fieldCache;
   if (m_useMagFieldSvc) {
+////////////////////////////////////////////////////////////////////////////////////////////////////
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+
+    if (fieldCondObj == nullptr) {
+        ATH_MSG_ERROR("PixelSiLorentzAngleCondAlg: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+        return StatusCode::FAILURE;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
     if (m_useMagFieldDcs) {
       // Read Cond Handle (B field sensor)
-      SG::ReadCondHandle<CondAttrListCollection> readHandleBFieldSensor(m_readKeyBFieldSensor);
+      SG::ReadCondHandle<CondAttrListCollection> readHandleBFieldSensor(m_readKeyBFieldSensor, ctx);
       const CondAttrListCollection* readCdoBFieldSensor(*readHandleBFieldSensor);
       if (readCdoBFieldSensor==nullptr) {
         ATH_MSG_FATAL("Null pointer to the read conditions object");
@@ -148,7 +166,7 @@ PixelSiLorentzAngleCondAlg::execute() {
   }
 
   // Get PixelDetectorElementCollection
-  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEle(m_pixelDetEleCollKey);
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEle(m_pixelDetEleCollKey, ctx);
   const InDetDD::SiDetectorElementCollection* elements(pixelDetEle.retrieve());
   if (elements==nullptr) {
     ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
@@ -162,9 +180,9 @@ PixelSiLorentzAngleCondAlg::execute() {
 
   // Construct the output Cond Object and fill it in
   std::unique_ptr<SiLorentzAngleCondData> writeCdo{std::make_unique<SiLorentzAngleCondData>()};
-  const PixelID::size_type wafer_hash_max = m_pixid->wafer_hash_max();
+  const PixelID::size_type wafer_hash_max = m_maxHash;
   writeCdo->resize(wafer_hash_max);
-  for (PixelID::size_type hash=0; hash<wafer_hash_max; hash++) {
+  for (PixelID::size_type hash = 0; hash < wafer_hash_max; hash++) {
     const IdentifierHash elementHash = static_cast<IdentifierHash::value_type>(hash);
 
     double temperature = readCdoTemp->getTemperature(elementHash)+273.15;
@@ -192,8 +210,10 @@ PixelSiLorentzAngleCondAlg::execute() {
     const InDet::SiliconProperties &siProperties = m_siPropertiesTool->getSiProperties(elementHash);
     double mobility = siProperties.signedHallMobility(element->carrierType());
 
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // Get magnetic field. This first checks that field cache is valid.
-    Amg::Vector3D magneticField = getMagneticField(element);
+    Amg::Vector3D magneticField = getMagneticField(fieldCache,element);
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
     // The angles are in the hit frame. This is because that is what is needed by the digization and also
     // gives a more physical sign of the angle (ie dosen't flip sign when the detector is flipped).
@@ -243,16 +263,21 @@ StatusCode PixelSiLorentzAngleCondAlg::finalize() {
   return StatusCode::SUCCESS;
 }
 
-Amg::Vector3D PixelSiLorentzAngleCondAlg::getMagneticField(const InDetDD::SiDetectorElement* element) const {
+Amg::Vector3D PixelSiLorentzAngleCondAlg::getMagneticField(MagField::AtlasFieldCache& fieldCache, const InDetDD::SiDetectorElement* element) const {
   if (m_useMagFieldSvc) {
     Amg::Vector3D pointvec = element->center();
-    ATH_MSG_VERBOSE("Getting magnetic field from magnetic field service.");
+
+    ATH_MSG_VERBOSE("Getting magnetic field from MT magnetic field service.");
     double point[3];
     point[0] = pointvec[0];
     point[1] = pointvec[1];
     point[2] = pointvec[2];
     double field[3];
-    m_magFieldSvc->getField(point, field);
+
+    // MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getField      (point, field);
+    else                                m_magFieldSvc->getField  (point, field);
+
     return Amg::Vector3D(field[0], field[1], field[2]);
   } 
   else {
diff --git a/InnerDetector/InDetConditions/SiLorentzAngleTool/src/PixelSiLorentzAngleCondAlg.h b/InnerDetector/InDetConditions/SiLorentzAngleTool/src/PixelSiLorentzAngleCondAlg.h
index 63e9def527f93a285d05af5f0a6208442d513295..f117aa35297beb7a6cabe0ee9412c99352d1bb51 100644
--- a/InnerDetector/InDetConditions/SiLorentzAngleTool/src/PixelSiLorentzAngleCondAlg.h
+++ b/InnerDetector/InDetConditions/SiLorentzAngleTool/src/PixelSiLorentzAngleCondAlg.h
@@ -11,7 +11,7 @@
 #ifndef PIXELSILORENTZANGLECONDALG
 #define PIXELSILORENTZANGLECONDALG
 
-#include "AthenaBaseComps/AthAlgorithm.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
 
 #include "StoreGate/ReadCondHandleKey.h"
 #include "StoreGate/WriteCondHandleKey.h"
@@ -21,22 +21,29 @@
 #include "PixelConditionsData/PixelDCSHVData.h"
 #include "PixelConditionsData/PixelDCSTempData.h"
 #include "GaudiKernel/ICondSvc.h"
+#include "GaudiKernel/SystemOfUnits.h"
 #include "SiPropertiesTool/ISiPropertiesTool.h"
 
 #include "SiLorentzAngleTool/SiLorentzAngleCondData.h"
 #include "InDetIdentifier/PixelID.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 // forward declarations
 namespace MagField {
   class IMagFieldSvc;
 }
 
-class PixelSiLorentzAngleCondAlg: public AthAlgorithm {
+class PixelSiLorentzAngleCondAlg: public AthReentrantAlgorithm {
   public:
     PixelSiLorentzAngleCondAlg(const std::string& name, ISvcLocator* pSvcLocator);
     virtual ~PixelSiLorentzAngleCondAlg() = default;
     virtual StatusCode initialize() override;
-    virtual StatusCode execute() override;
+    virtual StatusCode execute(const EventContext& ctx) const override;
     virtual StatusCode finalize() override;
 
   private:
@@ -64,12 +71,20 @@ class PixelSiLorentzAngleCondAlg: public AthAlgorithm {
     {this, "SiPropertiesTool", "SiPropertiesTool", "Tool to retrieve SiProperties"};
 
     // Properties
-    double                   m_nominalField;
-    bool                     m_useMagFieldSvc;
-    bool                     m_useMagFieldDcs;
-    double                   m_correctionFactor;
-
-    Amg::Vector3D getMagneticField(const InDetDD::SiDetectorElement* element) const;
+    DoubleProperty           m_nominalField  {this, "NominalField", 2.0834*Gaudi::Units::tesla, "Default nominal field"};
+    BooleanProperty          m_useMagFieldSvc{this, "UseMagFieldSvc", true};
+    BooleanProperty          m_useMagFieldDcs{this, "UseMagFieldDcs", true};
+    DoubleProperty           m_correctionFactor{this, "CorrectionFactor", 0.9, "Lorentz angle correction factor"};
+    unsigned int             m_maxHash;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//    Amg::Vector3D getMagneticField(const InDetDD::SiDetectorElement* element) const;
+    Amg::Vector3D getMagneticField(MagField::AtlasFieldCache& m_fieldCache,
+                                   const InDetDD::SiDetectorElement* element) const;
+    // Read handle for conditions object to get the field cache
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                       "Name of the Magnetic Field conditions object key"};
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 };
 
 #endif
diff --git a/InnerDetector/InDetConditions/SiLorentzAngleTool/src/SCTSiLorentzAngleCondAlg.cxx b/InnerDetector/InDetConditions/SiLorentzAngleTool/src/SCTSiLorentzAngleCondAlg.cxx
index 0d48a5992d264e69c3ee805f4c8f0a08bb16a943..046502edc81bc12d1690e55323bf6ff9acc90ec9 100644
--- a/InnerDetector/InDetConditions/SiLorentzAngleTool/src/SCTSiLorentzAngleCondAlg.cxx
+++ b/InnerDetector/InDetConditions/SiLorentzAngleTool/src/SCTSiLorentzAngleCondAlg.cxx
@@ -49,6 +49,9 @@ StatusCode SCTSiLorentzAngleCondAlg::initialize()
   if (m_useMagFieldSvc.value()) {
     // MagFieldSvc
     ATH_CHECK(m_magFieldSvc.retrieve());
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // Read Cond handle
     if (m_useMagFieldDcs.value()) {
       ATH_CHECK(m_readKeyBFieldSensor.initialize());
@@ -150,7 +153,20 @@ StatusCode SCTSiLorentzAngleCondAlg::execute(const EventContext& ctx) const
   }
 
   bool validBField{false};
+  MagField::AtlasFieldCache    fieldCache;
   if (m_useMagFieldSvc.value()) {
+////////////////////////////////////////////////////////////////////////////////////////////////////
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+
+    if (fieldCondObj == nullptr) {
+        ATH_MSG_ERROR("SCTSiLorentzAngleCondAlg : Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+        return StatusCode::FAILURE;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
     if (m_useMagFieldDcs.value()) {
       // Read Cond Handle (B field sensor)
       SG::ReadCondHandle<CondAttrListCollection> readHandleBFieldSensor{m_readKeyBFieldSensor, ctx};
@@ -238,7 +254,9 @@ StatusCode SCTSiLorentzAngleCondAlg::execute(const EventContext& ctx) const
     double mobility{siProperties.signedHallMobility(element->carrierType())};
 
     // Get magnetic field. This first checks that field cache is valid.
-    Amg::Vector3D magneticField{getMagneticField(element)};
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    Amg::Vector3D magneticField{getMagneticField(fieldCache, element)};
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
     // The angles are in the hit frame. This is because that is what is needed by the digization and also
     // gives a more physical sign of the angle (ie dosen't flip sign when the detector is flipped).
@@ -291,16 +309,24 @@ StatusCode SCTSiLorentzAngleCondAlg::finalize()
   return StatusCode::SUCCESS;
 }
 
-Amg::Vector3D SCTSiLorentzAngleCondAlg::getMagneticField(const InDetDD::SiDetectorElement* element) const {
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+Amg::Vector3D SCTSiLorentzAngleCondAlg::getMagneticField(MagField::AtlasFieldCache& fieldCache, const InDetDD::SiDetectorElement* element) const {
+
   if (m_useMagFieldSvc.value()) {
     Amg::Vector3D pointvec{element->center()};
-    ATH_MSG_VERBOSE("Getting magnetic field from magnetic field service.");
+
+    ATH_MSG_VERBOSE("Getting magnetic field from MT magnetic field service.");
+
     double point[3];
     point[0] = pointvec[0];
     point[1] = pointvec[1];
     point[2] = pointvec[2];
     double field[3];
-    m_magFieldSvc->getField(point, field);
+
+     // MT version uses cache, temporarily keep old version
+     if (fieldCache.useNewBfieldCache()) fieldCache.getField      (point, field);
+     else                                m_magFieldSvc->getField  (point, field);
+
     return Amg::Vector3D(field[0], field[1], field[2]);
   } else {
     ATH_MSG_VERBOSE("Using Nominal Field");
diff --git a/InnerDetector/InDetConditions/SiLorentzAngleTool/src/SCTSiLorentzAngleCondAlg.h b/InnerDetector/InDetConditions/SiLorentzAngleTool/src/SCTSiLorentzAngleCondAlg.h
index 2ce6a0f7d7991f9ca76d250186be619536177b26..0a9dc513839d2e6f02baf2a28a49ad701b018e23 100644
--- a/InnerDetector/InDetConditions/SiLorentzAngleTool/src/SCTSiLorentzAngleCondAlg.h
+++ b/InnerDetector/InDetConditions/SiLorentzAngleTool/src/SCTSiLorentzAngleCondAlg.h
@@ -27,6 +27,13 @@
 #include "GaudiKernel/SystemOfUnits.h"
 #include "GaudiKernel/ToolHandle.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
 // forward declarations
 namespace MagField {
   class IMagFieldSvc;
@@ -76,7 +83,13 @@ class SCTSiLorentzAngleCondAlg: public AthReentrantAlgorithm
   BooleanProperty          m_useGeoModel{this, "UseGeoModel", false};
   unsigned int             m_maxHash;
 
-  Amg::Vector3D getMagneticField(const InDetDD::SiDetectorElement* element) const;
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  Amg::Vector3D getMagneticField(MagField::AtlasFieldCache& fieldCache, const InDetDD::SiDetectorElement* element) const;
+
+  // Read handle for conditions object to get the field cache
+  SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                        "Name of the Magnetic Field conditions object key"};
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 };
 
 #endif // SCTSiLorentzAngleCondAlg_h
diff --git a/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_Digitization.cxx b/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_Digitization.cxx
index b46cb48c3348d5d3f7c9661dffd820824c270c2f..ef9ffba4bd5f36c1105a2dd694736957037df248 100644
--- a/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_Digitization.cxx
+++ b/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_Digitization.cxx
@@ -32,5 +32,5 @@ StatusCode BCM_Digitization::initialize()
 StatusCode BCM_Digitization::execute()
 {
   ATH_MSG_DEBUG ( "execute()" );
-  return m_digTool->processAllSubEvents();
+  return m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.cxx b/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.cxx
index 4c4197e6d11384b61fea78d095524b2c7a39b138..b13a9f87abbf1387be89f2dc615321cda64fabae 100644
--- a/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.cxx
@@ -67,10 +67,10 @@ StatusCode BCM_DigitizationTool::initialize()
 //----------------------------------------------------------------------
 // createOutpuContainers method:
 //----------------------------------------------------------------------
-StatusCode BCM_DigitizationTool::createOutputContainers()
+StatusCode BCM_DigitizationTool::createOutputContainers(const EventContext& ctx)
 {
   // Creating output RDO container
-  SG::WriteHandle<BCM_RDO_Container> outputContainer(m_outputKey);
+  SG::WriteHandle<BCM_RDO_Container> outputContainer(m_outputKey, ctx);
   ATH_CHECK(outputContainer.record(std::make_unique<BCM_RDO_Container>()));
   if (!outputContainer.isValid()) {
     ATH_MSG_ERROR("Could not record output BCM RDO container " << outputContainer.name() << " to store " << outputContainer.store());
@@ -81,7 +81,7 @@ StatusCode BCM_DigitizationTool::createOutputContainers()
   m_rdoContainer = outputContainer.ptr();
 
   // Creating output SDO collection container
-  SG::WriteHandle<InDetSimDataCollection> outputSDOContainer(m_outputSDOKey);
+  SG::WriteHandle<InDetSimDataCollection> outputSDOContainer(m_outputSDOKey, ctx);
   ATH_CHECK(outputSDOContainer.record(std::make_unique<InDetSimDataCollection>()));
   if (!outputSDOContainer.isValid()) {
     ATH_MSG_ERROR("Could not record output BCM SDO container " << outputSDOContainer.name() << " to store " << outputSDOContainer.store());
@@ -126,17 +126,17 @@ void BCM_DigitizationTool::processSiHit(const SiHit &currentHit, double eventTim
 //----------------------------------------------------------------------
 // createRDOs method:
 //----------------------------------------------------------------------
-void BCM_DigitizationTool::createRDOsAndSDOs()
+void BCM_DigitizationTool::createRDOsAndSDOs(const EventContext& ctx)
 {
   // Set the RNG to use for this event.
   ATHRNG::RNGWrapper* rngWrapper = m_rndmGenSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
+  rngWrapper->setSeed( name(), ctx );
 
   // Digitize hit info and create RDO for each module
   for (int iMod=0; iMod<8; ++iMod) {
     if (m_depositVect[iMod].size()) m_simDataCollMap->insert(std::make_pair(Identifier(iMod), InDetSimData(m_depositVect[iMod])));
     std::vector<float> analog = createAnalog(iMod,m_enerVect[iMod],m_timeVect[iMod]);
-    addNoise(iMod,analog, *rngWrapper);
+    addNoise(iMod,analog, rngWrapper->getEngine(ctx));
     for (int iGain=0; iGain<2; ++iGain) {
       std::bitset<64> digital = applyThreshold(iGain*8+iMod,analog);
       int p1x,p1w,p2x,p2w;
@@ -151,11 +151,11 @@ void BCM_DigitizationTool::createRDOsAndSDOs()
 //----------------------------------------------------------------------
 // PrepareEvent method:
 //----------------------------------------------------------------------
-StatusCode BCM_DigitizationTool::prepareEvent(unsigned int nInputEvents)
+StatusCode BCM_DigitizationTool::prepareEvent(const EventContext& ctx, unsigned int nInputEvents)
 {
   ATH_MSG_DEBUG ( "prepareEvent() called for " << nInputEvents << " input events" );
 
-  CHECK(createOutputContainers());
+  CHECK(createOutputContainers(ctx));
 
   return StatusCode::SUCCESS;
 }
@@ -163,15 +163,15 @@ StatusCode BCM_DigitizationTool::prepareEvent(unsigned int nInputEvents)
 //----------------------------------------------------------------------//
 // Digitize method:                                                     //
 //----------------------------------------------------------------------//
-StatusCode BCM_DigitizationTool::processAllSubEvents()
+StatusCode BCM_DigitizationTool::processAllSubEvents(const EventContext& ctx)
 {
   ATH_MSG_DEBUG ( "processAllSubEvents()" );
 
-  ATH_CHECK(createOutputContainers());
+  ATH_CHECK(createOutputContainers(ctx));
 
   // Fetch SiHitCollections for this bunch crossing
   if (!m_onlyUseContainerName) {
-    SG::ReadHandle<SiHitCollection> hitCollection(m_hitsContainerKey);
+    SG::ReadHandle<SiHitCollection> hitCollection(m_hitsContainerKey, ctx);
     if (!hitCollection.isValid()) {
       ATH_MSG_ERROR("Could not get BCM SiHitCollection container " << hitCollection.name() <<
                     " from store " << hitCollection.store());
@@ -211,7 +211,7 @@ StatusCode BCM_DigitizationTool::processAllSubEvents()
     }
   }
 
-  createRDOsAndSDOs();
+  createRDOsAndSDOs(ctx);
 
   return StatusCode::SUCCESS;
 }
@@ -251,11 +251,11 @@ StatusCode BCM_DigitizationTool::processBunchXing(int bunchXing,
 //----------------------------------------------------------------------
 // MergeEvent method:
 //----------------------------------------------------------------------
-StatusCode BCM_DigitizationTool::mergeEvent()
+StatusCode BCM_DigitizationTool::mergeEvent(const EventContext& ctx)
 {
   ATH_MSG_DEBUG ( "mergeEvent()" );
 
-  createRDOsAndSDOs();
+  createRDOsAndSDOs(ctx);
 
   return StatusCode::SUCCESS;
 }
diff --git a/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.h b/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.h
index 904f71c0fdd24657d551e6ea65ffc33c1b18daea..04377849143ea1def54ea00829cabb0424788706 100644
--- a/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.h
+++ b/InnerDetector/InDetDigitization/BCM_Digitization/src/BCM_DigitizationTool.h
@@ -41,19 +41,19 @@ class BCM_DigitizationTool : public PileUpToolBase {
   virtual StatusCode initialize() override final;
   /** alternative interface which uses the PileUpMergeSvc to obtain
   all the required SubEvents. */
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
   /** PileUpToolBase methods */
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int) override final;
   virtual StatusCode processBunchXing(int bunchXing,
                                       SubEventIterator bSubEvents,
                                       SubEventIterator eSubEvents) override final;
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
  private:
   /** Create the RDO and SDO containers */
-  StatusCode createOutputContainers();
+  StatusCode createOutputContainers(const EventContext& ctx);
   void processSiHit(const SiHit &currentHit, double eventTime, unsigned int evtIndex);
-  void createRDOsAndSDOs();
+  void createRDOsAndSDOs(const EventContext& ctx);
 
   /** Compute energy deposit depending on hit position */
   float computeEnergy(float simEner, HepGeom::Point3D<double> startPos, HepGeom::Point3D<double> endPos);
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/IPixelFastDigitizationTool.h b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/IPixelFastDigitizationTool.h
index f10d1705e769c541f9ca0c7bbe5f4e1dacabfc3c..589fa66ee3dbb3504be6b36b27583d01f18813c9 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/IPixelFastDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/IPixelFastDigitizationTool.h
@@ -7,6 +7,7 @@
 
 #include "GaudiKernel/IAlgTool.h"
 #include "GaudiKernel/StatusCode.h"
+#include "GaudiKernel/EventContext.h"
 
 static const InterfaceID IID_IPixelFastDigitizationTool ("IPixelFastDigitizationTool",1,0);
 
@@ -19,7 +20,7 @@ class IPixelFastDigitizationTool : virtual public IAlgTool
 
      ///alternative interface which uses the PileUpMergeSvc to obtain all
      ///the required SubEvents.
-     virtual StatusCode processAllSubEvents() = 0;
+     virtual StatusCode processAllSubEvents(const EventContext& ctx) = 0;
 
 };
 
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ISCT_FastDigitizationTool.h b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ISCT_FastDigitizationTool.h
index a31aa670e9752144d8cee0dde904fbc32fde3ffd..fb6d06e30fd7fbafd5fc887dc0c9e89cc60a1470 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ISCT_FastDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ISCT_FastDigitizationTool.h
@@ -7,6 +7,7 @@
 
 #include "GaudiKernel/IAlgTool.h"
 #include "GaudiKernel/StatusCode.h"
+#include "GaudiKernel/EventContext.h"
 
 static const InterfaceID IID_ISCT_FastDigitizationTool ("ISCT_FastDigitizationTool",1,0);
 
@@ -19,7 +20,7 @@ class ISCT_FastDigitizationTool : virtual public IAlgTool
 
      ///alternative interface which uses the PileUpMergeSvc to obtain all
      ///the required SubEvents.
-     virtual StatusCode processAllSubEvents() = 0;
+     virtual StatusCode processAllSubEvents(const EventContext& ctx) = 0;
 
 };
 
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ISiSmearedDigitizationTool.h b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ISiSmearedDigitizationTool.h
index 8acae7fa5a356e1449c8375da106677dba5008ec..390a8a564245cdac79dc6671f032802a96e17781 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ISiSmearedDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/ISiSmearedDigitizationTool.h
@@ -7,6 +7,7 @@
 
 #include "GaudiKernel/IAlgTool.h"
 #include "GaudiKernel/StatusCode.h"
+#include "GaudiKernel/EventContext.h"
 
 static const InterfaceID IID_ISiSmearedDigitizationTool ("ISiSmearedDigitizationTool",1,0);
 
@@ -19,7 +20,7 @@ class ISiSmearedDigitizationTool : virtual public IAlgTool
 
      ///alternative interface which uses the PileUpMergeSvc to obtain all
      ///the required SubEvents.
-     virtual StatusCode processAllSubEvents() = 0;
+     virtual StatusCode processAllSubEvents(const EventContext& ctx) = 0;
 
 };
 
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/PixelFastDigitizationTool.h b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/PixelFastDigitizationTool.h
index b37ddacf99c975e46db1170b2e94ce1bbc2f2ba3..1e1dadec8f3e7bb96bc3543cd5c972a2725b55a7 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/PixelFastDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/PixelFastDigitizationTool.h
@@ -73,14 +73,14 @@ public:
   ~PixelFastDigitizationTool();
 
   StatusCode initialize();
-  StatusCode prepareEvent(unsigned int);
+  StatusCode prepareEvent(const EventContext& ctx, unsigned int);
   StatusCode processBunchXing( int bunchXing,
                                SubEventIterator bSubEvents,
                                SubEventIterator eSubEvents );
-  StatusCode processAllSubEvents();
-  StatusCode mergeEvent();
-  StatusCode digitize();
-  StatusCode createAndStoreRIOs();
+  StatusCode processAllSubEvents(const EventContext& ctx);
+  StatusCode mergeEvent(const EventContext& ctx);
+  StatusCode digitize(const EventContext& ctx);
+  StatusCode createAndStoreRIOs(const EventContext& ctx);
 
 
 
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SCT_FastDigitizationTool.h b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SCT_FastDigitizationTool.h
index dd296cce45d43797f8d6594b23b941dde8e2de5f..7cc312d1bcb2c4d3378ced8c75e60ffa45e338ee 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SCT_FastDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SCT_FastDigitizationTool.h
@@ -97,17 +97,17 @@ public:
      @brief Called before processing physics events
   */
   virtual StatusCode initialize();
-  StatusCode prepareEvent( unsigned int );
+  StatusCode prepareEvent(const EventContext& ctx, unsigned int );
   StatusCode processBunchXing( int bunchXing,
                                SubEventIterator bSubEvents,
                                SubEventIterator eSubEvents );
-  StatusCode mergeEvent();
-  StatusCode processAllSubEvents();
-  StatusCode createAndStoreRIOs();
+  StatusCode mergeEvent(const EventContext& ctx);
+  StatusCode processAllSubEvents(const EventContext& ctx);
+  StatusCode createAndStoreRIOs(const EventContext& ctx);
 
 private:
 
-  StatusCode digitize();
+  StatusCode digitize(const EventContext& ctx);
   StatusCode createOutputContainers();
   bool NeighbouringClusters(const std::vector<Identifier>& potentialClusterRDOList,  const InDet::SCT_Cluster *existingCluster) const;
   void Diffuse(HepGeom::Point3D<double>& localEntry, HepGeom::Point3D<double>& localExit, double shiftX, double shiftY ) const;
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SiSmearedDigitizationTool.h b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SiSmearedDigitizationTool.h
index a24a8a3ca4da4aa98cd31cef7ce578fafc77f8bf..0b5c240b262d701dbd6504c3bca883ec324a0ca0 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SiSmearedDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/FastSiDigitization/SiSmearedDigitizationTool.h
@@ -84,12 +84,12 @@ public:
 
 
   StatusCode initialize();
-  StatusCode prepareEvent(unsigned int);
+  StatusCode prepareEvent(const EventContext& ctx, unsigned int);
   StatusCode processBunchXing( int bunchXing,
                                SubEventIterator bSubEvents,
                                SubEventIterator eSubEvents );
-  StatusCode processAllSubEvents();
-  StatusCode mergeEvent();
+  StatusCode processAllSubEvents(const EventContext& ctx);
+  StatusCode mergeEvent(const EventContext& ctx);
 
   typedef std::multimap<IdentifierHash, InDet::PixelCluster*> Pixel_detElement_RIO_map;
   typedef std::multimap<IdentifierHash, iFatras::PlanarCluster*> Planar_detElement_RIO_map;
@@ -98,8 +98,8 @@ public:
   StatusCode mergeClusters(Planar_detElement_RIO_map * cluster_map);
   StatusCode mergeClusters(SCT_detElement_RIO_map * cluster_map);
 
-  StatusCode digitize();
-  StatusCode createAndStoreRIOs();
+  StatusCode digitize(const EventContext& ctx);
+  StatusCode createAndStoreRIOs(const EventContext& ctx);
   StatusCode retrieveTruth();
   StatusCode finalize();
 
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitization.cxx b/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitization.cxx
index 02f5d963d75d37e897b560f691c7dbbe9e9d9e4f..770f8ada212b74ae67a7a372024462de6a798fbe 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitization.cxx
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitization.cxx
@@ -37,7 +37,7 @@ StatusCode PixelFastDigitization::execute() {
 
   ATH_MSG_VERBOSE ( " PixelFastDigitization : execute()" );
 
-  StatusCode sc =  m_digTool->processAllSubEvents();
+  StatusCode sc =  m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 
   ATH_MSG_VERBOSE ( " PixelFastDigitization : m_digTool->processAllSubEvents()" );
 
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitizationTool.cxx b/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitizationTool.cxx
index 745a4e0f9aeda1751f9d42f23ccbd68df17efed2..b7b0b87df9b66d54236d1922c4c2f6a1bb09408e 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/src/PixelFastDigitizationTool.cxx
@@ -224,7 +224,7 @@ StatusCode PixelFastDigitizationTool::initialize()
 
 
 
-StatusCode PixelFastDigitizationTool::prepareEvent(unsigned int)
+StatusCode PixelFastDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
 {
 
   m_siHitCollList.clear();
@@ -275,7 +275,7 @@ StatusCode PixelFastDigitizationTool::processBunchXing(int bunchXing,
 }
 
 
-StatusCode PixelFastDigitizationTool::processAllSubEvents() {
+StatusCode PixelFastDigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
   m_pixelClusterContainer = new InDet::PixelClusterContainer(m_pixel_ID->wafer_hash_max());
 
@@ -357,12 +357,12 @@ StatusCode PixelFastDigitizationTool::processAllSubEvents() {
   m_thpcsi = &thpcsi;
 
   // Process the Hits straw by straw: get the iterator pairs for given straw
-  if(this->digitize().isFailure()) {
+  if(this->digitize(ctx).isFailure()) {
     ATH_MSG_FATAL ( "digitize method failed!" );
     return StatusCode::FAILURE;
   }
 
-  if (createAndStoreRIOs().isFailure()) {
+  if (createAndStoreRIOs(ctx).isFailure()) {
     ATH_MSG_FATAL ( "createAndStoreRIOs() failed!" );
     return StatusCode::FAILURE;
   }
@@ -392,7 +392,7 @@ StatusCode PixelFastDigitizationTool::processAllSubEvents() {
 
 
 
-StatusCode PixelFastDigitizationTool::mergeEvent()
+StatusCode PixelFastDigitizationTool::mergeEvent(const EventContext& ctx)
 {
 
   m_pixelClusterContainer = new InDet::PixelClusterContainer(m_pixel_ID->wafer_hash_max());
@@ -438,7 +438,7 @@ StatusCode PixelFastDigitizationTool::mergeEvent()
   m_ambiguitiesMap =new PixelGangedClusterAmbiguities();
 
   if (m_thpcsi != 0) {
-    if(digitize().isFailure()) {
+    if(digitize(ctx).isFailure()) {
       ATH_MSG_FATAL ( "Pixel digitize method failed!" );
       return StatusCode::FAILURE;
     }
@@ -455,7 +455,7 @@ StatusCode PixelFastDigitizationTool::mergeEvent()
   m_siHitCollList.clear();
 
 
-  if (createAndStoreRIOs().isFailure()) {
+  if (createAndStoreRIOs(ctx).isFailure()) {
     ATH_MSG_FATAL ( "createAndStoreRIOs() failed!" );
     return StatusCode::FAILURE;
   }
@@ -481,9 +481,9 @@ StatusCode PixelFastDigitizationTool::mergeEvent()
 }
 
 
-StatusCode PixelFastDigitizationTool::digitize()
+StatusCode PixelFastDigitizationTool::digitize(const EventContext& ctx)
 {
-  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEleHandle(m_pixelDetEleCollKey);
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEleHandle(m_pixelDetEleCollKey, ctx);
   const InDetDD::SiDetectorElementCollection* elements(*pixelDetEleHandle);
   if (not pixelDetEleHandle.isValid() or elements==nullptr) {
     ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
@@ -495,7 +495,7 @@ StatusCode PixelFastDigitizationTool::digitize()
   if(!m_pixelClusterMap) { m_pixelClusterMap = new Pixel_detElement_RIO_map; }
   else { m_pixelClusterMap->clear(); }
 
-  SG::ReadCondHandle<PixelChargeCalibCondData> calibData(m_chargeDataKey);
+  SG::ReadCondHandle<PixelChargeCalibCondData> calibData(m_chargeDataKey, ctx);
 
   while (m_thpcsi->nextDetectorElement(i, e)) {
 
@@ -885,9 +885,9 @@ StatusCode PixelFastDigitizationTool::digitize()
   return StatusCode::SUCCESS;
 }
 
-StatusCode PixelFastDigitizationTool::createAndStoreRIOs()
+StatusCode PixelFastDigitizationTool::createAndStoreRIOs(const EventContext& ctx)
 {
-  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEleHandle(m_pixelDetEleCollKey);
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEleHandle(m_pixelDetEleCollKey, ctx);
   const InDetDD::SiDetectorElementCollection* elements(*pixelDetEleHandle);
   if (not pixelDetEleHandle.isValid() or elements==nullptr) {
     ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitization.cxx b/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitization.cxx
index 49ed8deb26466f59fdd58580fa1b15509029feb9..28a55496d6557fcfb7cf33d067f73a631ba7b536 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitization.cxx
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitization.cxx
@@ -37,7 +37,7 @@ StatusCode SCT_FastDigitization::execute() {
 
   ATH_MSG_VERBOSE ( " SCT_FastDigitization : execute()" );
 
-  StatusCode sc =  m_digTool->processAllSubEvents();
+  StatusCode sc =  m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 
   ATH_MSG_VERBOSE ( " SCT_FastDigitization : m_digTool->processAllSubEvents()" );
 
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitizationTool.cxx b/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitizationTool.cxx
index a521f1f4ad86dfecd01c1d521ab798c1bd741dcd..706125523db95d4ce23a83bf7fef5a8dc9721175 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/src/SCT_FastDigitizationTool.cxx
@@ -150,7 +150,7 @@ StatusCode SCT_FastDigitizationTool::initialize()
   return StatusCode::SUCCESS ;
 }
 
-StatusCode SCT_FastDigitizationTool::prepareEvent(unsigned int)
+StatusCode SCT_FastDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
 {
 
   m_siHitCollList.clear();
@@ -235,7 +235,7 @@ StatusCode SCT_FastDigitizationTool::createOutputContainers()
   return StatusCode::SUCCESS;
 }
 
-StatusCode SCT_FastDigitizationTool::processAllSubEvents() {
+StatusCode SCT_FastDigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
   CHECK(this->createOutputContainers());
 
@@ -278,9 +278,9 @@ StatusCode SCT_FastDigitizationTool::processAllSubEvents() {
   m_thpcsi = &thpcsi;
 
   // Process the Hits
-  CHECK(this->digitize());
+  CHECK(this->digitize(ctx));
 
-  CHECK(this->createAndStoreRIOs());
+  CHECK(this->createAndStoreRIOs(ctx));
   ATH_MSG_DEBUG ( "createAndStoreRIOs() succeeded" );
 
   return StatusCode::SUCCESS;
@@ -288,13 +288,13 @@ StatusCode SCT_FastDigitizationTool::processAllSubEvents() {
 
 
 
-StatusCode SCT_FastDigitizationTool::mergeEvent()
+StatusCode SCT_FastDigitizationTool::mergeEvent(const EventContext& ctx)
 {
   CHECK(this->createOutputContainers());
 
   if (m_thpcsi != 0)
     {
-      CHECK(this->digitize());
+      CHECK(this->digitize(ctx));
     }
 
   //-----------------------------------------------------------------------
@@ -310,17 +310,17 @@ StatusCode SCT_FastDigitizationTool::mergeEvent()
   m_siHitCollList.clear();
   //-----------------------------------------------------------------------
 
-  CHECK(this->createAndStoreRIOs());
+  CHECK(this->createAndStoreRIOs(ctx));
   ATH_MSG_DEBUG ( "createAndStoreRIOs() succeeded" );
 
   return StatusCode::SUCCESS;
 }
 
 
-StatusCode SCT_FastDigitizationTool::digitize()
+StatusCode SCT_FastDigitizationTool::digitize(const EventContext& ctx)
 {
   // Get SCT_DetectorElementCollection
-  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey);
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx);
   const InDetDD::SiDetectorElementCollection* elements(sctDetEle.retrieve());
   if (elements==nullptr) {
     ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
@@ -958,10 +958,10 @@ StatusCode SCT_FastDigitizationTool::digitize()
 }
 
 
-StatusCode SCT_FastDigitizationTool::createAndStoreRIOs()
+StatusCode SCT_FastDigitizationTool::createAndStoreRIOs(const EventContext& ctx)
 {
   // Get SCT_DetectorElementCollection
-  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey);
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx);
   const InDetDD::SiDetectorElementCollection* elements(sctDetEle.retrieve());
   if (elements==nullptr) {
     ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitization.cxx b/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitization.cxx
index 425bd3389edb6432b351f3bb7053af1313c6504d..8d061160b98cca454b6dc8b42b995556cef89a57 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitization.cxx
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitization.cxx
@@ -40,7 +40,7 @@ StatusCode SiSmearedDigitization::execute() {
 
   ATH_MSG_INFO ( " SiSmearedDigitization : execute()" );
 
-  StatusCode sc =  m_smearTool->processAllSubEvents();
+  StatusCode sc =  m_smearTool->processAllSubEvents(Gaudi::Hive::currentContext());
   
   ATH_MSG_INFO ( " SiSmearedDigitization : m_smearTool->processAllSubEvents()" );
   
diff --git a/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitizationTool.cxx b/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitizationTool.cxx
index 29f6b70ce3d910bfb1af3735d30f69b9fa646f38..c0f277ddf86f92544aaefa212952deaf83f5c08d 100644
--- a/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/FastSiDigitization/src/SiSmearedDigitizationTool.cxx
@@ -301,7 +301,7 @@ StatusCode SiSmearedDigitizationTool::finalize()
 
 }
 
-StatusCode SiSmearedDigitizationTool::prepareEvent(unsigned int)
+StatusCode SiSmearedDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
 {
 
   ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in pixel prepareEvent() ---" );
@@ -356,7 +356,7 @@ StatusCode SiSmearedDigitizationTool::processBunchXing(int bunchXing,
 }
 
 
-StatusCode SiSmearedDigitizationTool::processAllSubEvents() {
+StatusCode SiSmearedDigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
   ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in pixel processAllSubEvents() ---" );
 
@@ -493,18 +493,18 @@ StatusCode SiSmearedDigitizationTool::processAllSubEvents() {
   m_thpcsi = &thpcsi;
 
   // Process the Hits straw by straw: get the iterator pairs for given straw
-  if(this->digitize().isFailure()) {
+  if(this->digitize(ctx).isFailure()) {
     ATH_MSG_FATAL ( "digitize method failed!" );
     return StatusCode::FAILURE;
   }
 
   if (m_merge)
-    if(this->mergeEvent().isFailure()) {
+    if(this->mergeEvent(ctx).isFailure()) {
       ATH_MSG_FATAL ( "merge method failed!" );
       return StatusCode::FAILURE;
     }
 
-  if (createAndStoreRIOs().isFailure()) {
+  if (createAndStoreRIOs(ctx).isFailure()) {
     ATH_MSG_FATAL ( "createAndStoreRIOs() failed!" );
     return StatusCode::FAILURE;
   }
@@ -588,7 +588,7 @@ StatusCode SiSmearedDigitizationTool::FillTruthMap(PRD_MultiTruthCollection * ma
   return StatusCode::SUCCESS;
 }
 
-StatusCode SiSmearedDigitizationTool::mergeEvent(){
+StatusCode SiSmearedDigitizationTool::mergeEvent(const EventContext& /*ctx*/){
 
   if (m_useCustomGeometry)
     return mergeClusters(m_planarClusterMap);
@@ -889,7 +889,7 @@ StatusCode SiSmearedDigitizationTool::mergeClusters(Planar_detElement_RIO_map *
   return StatusCode::SUCCESS;
 }
 
-StatusCode SiSmearedDigitizationTool::digitize()
+StatusCode SiSmearedDigitizationTool::digitize(const EventContext& ctx)
 {
   ATH_MSG_DEBUG( "--- SiSmearedDigitizationTool: in SiSmearedDigizationTool::digitize() ---" );
 
@@ -914,7 +914,7 @@ StatusCode SiSmearedDigitizationTool::digitize()
   // Get PixelDetectorElementCollection
   const InDetDD::SiDetectorElementCollection* elementsPixel = nullptr;
   if ((not m_useCustomGeometry) and m_SmearPixel) {
-    SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEle(m_pixelDetEleCollKey);
+    SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEle(m_pixelDetEleCollKey, ctx);
     elementsPixel = pixelDetEle.retrieve();
     if (elementsPixel==nullptr) {
       ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
@@ -924,7 +924,7 @@ StatusCode SiSmearedDigitizationTool::digitize()
   // Get SCT_DetectorElementCollection
   const InDetDD::SiDetectorElementCollection* elementsSCT = nullptr;
   if ((not m_useCustomGeometry) and (not m_SmearPixel)) {
-    SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey);
+    SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx);
     elementsSCT = sctDetEle.retrieve();
     if (elementsSCT==nullptr) {
       ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
@@ -1619,12 +1619,12 @@ StatusCode SiSmearedDigitizationTool::digitize()
 }
 
 
-StatusCode SiSmearedDigitizationTool::createAndStoreRIOs()
+StatusCode SiSmearedDigitizationTool::createAndStoreRIOs(const EventContext& ctx)
 {
   // Get PixelDetectorElementCollection
   const InDetDD::SiDetectorElementCollection* elementsPixel = nullptr;
   if ((not m_useCustomGeometry) and m_SmearPixel) {
-    SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEle(m_pixelDetEleCollKey);
+    SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEle(m_pixelDetEleCollKey, ctx);
     elementsPixel = pixelDetEle.retrieve();
     if (elementsPixel==nullptr) {
       ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
@@ -1634,7 +1634,7 @@ StatusCode SiSmearedDigitizationTool::createAndStoreRIOs()
   // Get SCT_DetectorElementCollection
   const InDetDD::SiDetectorElementCollection* elementsSCT = nullptr;
   if ((not m_useCustomGeometry) and (not m_SmearPixel)) {
-    SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey);
+    SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx);
     elementsSCT = sctDetEle.retrieve();
     if (elementsSCT==nullptr) {
       ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
diff --git a/InnerDetector/InDetDigitization/FastTRT_Digitization/FastTRT_Digitization/ITRTFastDigitizationTool.h b/InnerDetector/InDetDigitization/FastTRT_Digitization/FastTRT_Digitization/ITRTFastDigitizationTool.h
index 95c941098909b6b769ce1ea8bf297820cbeab263..a2328a91ad15f991f5b49f1cc8e4e6564ad27909 100644
--- a/InnerDetector/InDetDigitization/FastTRT_Digitization/FastTRT_Digitization/ITRTFastDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastTRT_Digitization/FastTRT_Digitization/ITRTFastDigitizationTool.h
@@ -7,6 +7,7 @@
 
 #include "GaudiKernel/IAlgTool.h"
 #include "GaudiKernel/StatusCode.h"
+#include "GaudiKernel/EventContext.h"
 
 static const InterfaceID IID_ITRTFastDigitizationTool ("ITRTFastDigitizationTool",1,0);
 
@@ -19,7 +20,7 @@ class ITRTFastDigitizationTool : virtual public IAlgTool
 
      ///alternative interface which uses the PileUpMergeSvc to obtain all
      ///the required SubEvents.
-     virtual StatusCode processAllSubEvents() = 0;
+     virtual StatusCode processAllSubEvents(const EventContext& ctx) = 0;
 
 };
 
diff --git a/InnerDetector/InDetDigitization/FastTRT_Digitization/FastTRT_Digitization/TRTFastDigitizationTool.h b/InnerDetector/InDetDigitization/FastTRT_Digitization/FastTRT_Digitization/TRTFastDigitizationTool.h
index 729ecf2b041c590fd5929cc36f705c44db4d549b..4aa3e2e89b5c1ad3775804f39ad12db178ea6402 100644
--- a/InnerDetector/InDetDigitization/FastTRT_Digitization/FastTRT_Digitization/TRTFastDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/FastTRT_Digitization/FastTRT_Digitization/TRTFastDigitizationTool.h
@@ -66,7 +66,7 @@ public:
 
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  StatusCode mergeEvent();
+  StatusCode mergeEvent(const EventContext& ctx);
 
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
@@ -78,11 +78,11 @@ public:
   /// implemented by default in PileUpToolBase as FirstXing<=bunchXing<=LastXing
   //  virtual bool toProcess(int bunchXing) const;
 
-  StatusCode prepareEvent( const unsigned int /*nInputEvents*/ );
+  StatusCode prepareEvent(const EventContext& ctx, const unsigned int /*nInputEvents*/ );
 
   ///alternative interface which uses the PileUpMergeSvc to obtain all
   ///the required SubEvents.
-  StatusCode processAllSubEvents();
+  StatusCode processAllSubEvents(const EventContext& ctx);
 
   /** Initialize */
   virtual StatusCode initialize();
@@ -95,7 +95,7 @@ private:
   StatusCode initializeNumericalConstants();    // once per run 
   StatusCode setNumericalConstants();    // once per event (pileup-dependent constants) 
 
-  StatusCode produceDriftCircles();
+  StatusCode produceDriftCircles(const EventContext& ctx);
   StatusCode createOutputContainers();
 
   Identifier getIdentifier( int hitID, IdentifierHash &hash, Identifier &layer_id, bool &status ) const;
diff --git a/InnerDetector/InDetDigitization/FastTRT_Digitization/src/TRTFastDigitization.cxx b/InnerDetector/InDetDigitization/FastTRT_Digitization/src/TRTFastDigitization.cxx
index e12be8e8b993d839b37921e8e7a61fa1fbe57d39..a5660d3a66397d6e83e8d8fb6da3e702bf7dd980 100644
--- a/InnerDetector/InDetDigitization/FastTRT_Digitization/src/TRTFastDigitization.cxx
+++ b/InnerDetector/InDetDigitization/FastTRT_Digitization/src/TRTFastDigitization.cxx
@@ -37,7 +37,7 @@ StatusCode TRTFastDigitization::execute() {
 
   ATH_MSG_VERBOSE ( "execute()" );
 
-  StatusCode sc =  m_digTool->processAllSubEvents();
+  StatusCode sc =  m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 
   ATH_MSG_DEBUG ( "m_digTool->processAllSubEvents()" );
 
diff --git a/InnerDetector/InDetDigitization/FastTRT_Digitization/src/TRTFastDigitizationTool.cxx b/InnerDetector/InDetDigitization/FastTRT_Digitization/src/TRTFastDigitizationTool.cxx
index 5b4c726176f2da354c0c0ed10d0c2921eb95b519..6592963af482cc71c64f3967f14bfc511c5bdf19 100644
--- a/InnerDetector/InDetDigitization/FastTRT_Digitization/src/TRTFastDigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/FastTRT_Digitization/src/TRTFastDigitizationTool.cxx
@@ -145,7 +145,7 @@ StatusCode TRTFastDigitizationTool::initialize()
 }
 
 
-StatusCode TRTFastDigitizationTool::prepareEvent( unsigned int )
+StatusCode TRTFastDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int )
 {
   m_trtHitCollList.clear();
   m_thpctrt = new TimedHitCollection< TRTUncompressedHit >();
@@ -292,11 +292,11 @@ StatusCode TRTFastDigitizationTool::setNumericalConstants() {
    return StatusCode::SUCCESS;
 }
 
-StatusCode TRTFastDigitizationTool::produceDriftCircles() {
+StatusCode TRTFastDigitizationTool::produceDriftCircles(const EventContext& ctx) {
   
   if(m_useEventInfo){
 
-     SG::ReadHandle<EventInfo> eventInfoContainer(m_EventInfoKey);
+     SG::ReadHandle<EventInfo> eventInfoContainer(m_EventInfoKey, ctx);
      if(eventInfoContainer.isValid()){
        m_NCollPerEvent = (float) eventInfoContainer->averageInteractionsPerCrossing();
      }
@@ -445,7 +445,7 @@ StatusCode TRTFastDigitizationTool::produceDriftCircles() {
 }
 
 
-StatusCode TRTFastDigitizationTool::processAllSubEvents() {
+StatusCode TRTFastDigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
   ATH_MSG_DEBUG( "TRTFastDigitizationTool::processAllSubEvents()" );
 
@@ -475,7 +475,7 @@ StatusCode TRTFastDigitizationTool::processAllSubEvents() {
   m_thpctrt = &timedHitCollection;
 
   // Process the Hits straw by straw: get the iterator pairs for given straw
-  CHECK( this->produceDriftCircles() );
+  CHECK( this->produceDriftCircles(ctx) );
 
   CHECK( this->createAndStoreRIOs() );
   ATH_MSG_DEBUG ( "createAndStoreRIOs() succeeded" );
@@ -512,7 +512,7 @@ StatusCode TRTFastDigitizationTool::createOutputContainers() {
 }
 
 
-StatusCode TRTFastDigitizationTool::mergeEvent() {
+StatusCode TRTFastDigitizationTool::mergeEvent(const EventContext& ctx) {
 
   ATH_MSG_DEBUG( "TRTFastDigitizationTool::mergeEvent()" );
 
@@ -520,7 +520,7 @@ StatusCode TRTFastDigitizationTool::mergeEvent() {
 
   // Process the Hits straw by straw: get the iterator pairs for given straw
   if ( m_thpctrt != 0 ) {
-    CHECK( this->produceDriftCircles() );
+    CHECK( this->produceDriftCircles(ctx) );
   }
 
   // Clean up temporary containers
diff --git a/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitization.cxx b/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitization.cxx
index e0c62b4e4a8d27329486c85022d598cc05afe713..23c2201eb789c090b3eae4c9b63951e7ddac993d 100644
--- a/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitization.cxx
+++ b/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitization.cxx
@@ -22,5 +22,5 @@ StatusCode PixelDigitization::initialize() {
 // Execute method:
 StatusCode PixelDigitization::execute() {
   ATH_MSG_DEBUG ( "execute()" );
-  return m_pixelDigitizationTool->processAllSubEvents();
+  return m_pixelDigitizationTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitizationTool.cxx b/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitizationTool.cxx
index 84d2494a5731107cc37ac2c193dd0531a016cfa8..35e1214bf5c79fd5825def3447d68f1146da6b7d 100644
--- a/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitizationTool.cxx
@@ -60,17 +60,17 @@ StatusCode PixelDigitizationTool::finalize() {
 //=======================================
 // P R O C E S S   S U B E V E N T S
 //=======================================
-StatusCode PixelDigitizationTool::processAllSubEvents() {
+StatusCode PixelDigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
   // Prepare event
   ATH_MSG_DEBUG("Prepare event");
-  ATH_CHECK(prepareEvent(0));
+  ATH_CHECK(prepareEvent(ctx, 0));
 
   // Get the container(s)
   typedef PileUpMergeSvc::TimedList<SiHitCollection>::type TimedHitCollList;
   // In case of single hits container just load the collection using read handles
   if (!m_onlyUseContainerName) {
-    SG::ReadHandle<SiHitCollection> hitCollection(m_hitsContainerKey);
+    SG::ReadHandle<SiHitCollection> hitCollection(m_hitsContainerKey, ctx);
     if (!hitCollection.isValid()) {
       ATH_MSG_ERROR("Could not get Pixel SiHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
       return StatusCode::FAILURE;
@@ -98,7 +98,7 @@ StatusCode PixelDigitizationTool::processAllSubEvents() {
     }
   }
   // Digitize hits
-  ATH_CHECK(digitizeEvent());
+  ATH_CHECK(digitizeEvent(ctx));
 
   ATH_MSG_DEBUG("Digitize success!");
   return StatusCode::SUCCESS;
@@ -107,10 +107,10 @@ StatusCode PixelDigitizationTool::processAllSubEvents() {
 //=======================================
 // D I G I T I Z E   E V E N T (main)
 //=======================================
-StatusCode PixelDigitizationTool::digitizeEvent() {
+StatusCode PixelDigitizationTool::digitizeEvent(const EventContext& ctx) {
   ATH_MSG_VERBOSE("PixelDigitizationTool::digitizeEvent()");
 
-  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEleHandle(m_pixelDetEleCollKey);
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEleHandle(m_pixelDetEleCollKey, ctx);
   const InDetDD::SiDetectorElementCollection* elements(*pixelDetEleHandle);
   if (not pixelDetEleHandle.isValid() or elements==nullptr) {
     ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
@@ -126,8 +126,8 @@ StatusCode PixelDigitizationTool::digitizeEvent() {
 
   // Set the RNG to use for this event.
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
-  CLHEP::HepRandomEngine *rndmEngine = *rngWrapper;
+  rngWrapper->setSeed( name(), ctx );
+  CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
 
   TimedHitCollection<SiHit>::const_iterator firstHit, lastHit;
   
@@ -298,15 +298,15 @@ void PixelDigitizationTool::addSDO(SiChargedDiodeCollection* collection) {
 //=======================================
 // P R E P A R E   E V E N T
 //=======================================
-StatusCode PixelDigitizationTool::prepareEvent(unsigned int) {
+StatusCode PixelDigitizationTool::prepareEvent(const EventContext& ctx, unsigned int) {
   ATH_MSG_VERBOSE("PixelDigitizationTool::prepareEvent()");
 
   // Prepare event
-  m_rdoContainer = SG::makeHandle(m_rdoContainerKey);
+  m_rdoContainer = SG::makeHandle(m_rdoContainerKey, ctx);
   ATH_CHECK(m_rdoContainer.record(std::make_unique<PixelRDO_Container>(m_detID->wafer_hash_max())));
   ATH_MSG_DEBUG("PixelRDO_Container " << m_rdoContainer.name() << " registered in StoreGate");
 
-  m_simDataColl = SG::makeHandle(m_simDataCollKey);
+  m_simDataColl = SG::makeHandle(m_simDataCollKey, ctx);
   ATH_CHECK(m_simDataColl.record(std::make_unique<InDetSimDataCollection>()));
   ATH_MSG_DEBUG("InDetSimDataCollection " << m_simDataColl.name() << " registered in StoreGate");
 
@@ -321,11 +321,11 @@ StatusCode PixelDigitizationTool::prepareEvent(unsigned int) {
 //=======================================
 // M E R G E   E V E N T
 //=======================================
-StatusCode PixelDigitizationTool::mergeEvent() {
+StatusCode PixelDigitizationTool::mergeEvent(const EventContext& ctx) {
   ATH_MSG_VERBOSE("PixelDigitizationTool::mergeEvent()");
 
   // Digitize hits
-  ATH_CHECK(digitizeEvent());
+  ATH_CHECK(digitizeEvent(ctx));
 
   for (std::vector<SiHitCollection*>::iterator it = m_hitCollPtrs.begin();it!=m_hitCollPtrs.end();it++) {
     (*it)->Clear();
diff --git a/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitizationTool.h b/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitizationTool.h
index 99eb901a5700f05b3132da548634dfa054ed6406..c1da6db1a38b1e73eea7bb4b5abf129f2ceee79a 100644
--- a/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/PixelDigitization/src/PixelDigitizationTool.h
@@ -40,12 +40,12 @@ class PixelDigitizationTool : public PileUpToolBase {
     PixelDigitizationTool(const std::string &type, const std::string &name, const IInterface *pIID);
 
     virtual StatusCode initialize() override;
-    virtual StatusCode processAllSubEvents() override;
+    virtual StatusCode processAllSubEvents(const EventContext& ctx) override;
     virtual StatusCode finalize() override;
 
-    virtual StatusCode prepareEvent(unsigned int) override;
-    StatusCode digitizeEvent();
-    virtual StatusCode mergeEvent() override;
+    virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int) override;
+    StatusCode digitizeEvent(const EventContext& ctx);
+    virtual StatusCode mergeEvent(const EventContext& ctx) override;
     virtual StatusCode processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents) override final;
 
   protected:
diff --git a/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_Digitization.cxx b/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_Digitization.cxx
index f30bbd62b14fd201ca98a739de49894bafe9c6bc..df7a822d4c893e4f049961a742d2dfe2f6fbef24 100644
--- a/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_Digitization.cxx
+++ b/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_Digitization.cxx
@@ -27,5 +27,5 @@ StatusCode SCT_Digitization::initialize() {
 
 StatusCode SCT_Digitization::execute() {
   ATH_MSG_DEBUG("execute()");
-  return m_sctDigitizationTool->processAllSubEvents();
+  return m_sctDigitizationTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.cxx b/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.cxx
index 9d645308771a97e2787f4ad9c6a19c7a8e90c94f..ab9a2aa71dd13aa7a7492ece11d98f58d8b0356d 100644
--- a/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.cxx
@@ -187,18 +187,18 @@ StatusCode SCT_DigitizationTool::initDisabledCells() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode SCT_DigitizationTool::processAllSubEvents() {
-  if (prepareEvent(0).isFailure()) {
+StatusCode SCT_DigitizationTool::processAllSubEvents(const EventContext& ctx) {
+  if (prepareEvent(ctx, 0).isFailure()) {
     return StatusCode::FAILURE;
   }
   // Set the RNG to use for this event.
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
-  CLHEP::HepRandomEngine *rndmEngine = *rngWrapper;
+  rngWrapper->setSeed( name(), ctx );
+  CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
 
   ATH_MSG_VERBOSE("Begin digitizeAllHits");
-  if (m_enableHits and (not getNextEvent().isFailure())) {
-    digitizeAllHits(&m_rdoContainer, &m_simDataCollMap, &m_processedElements, m_thpcsi, rndmEngine);
+  if (m_enableHits and (not getNextEvent(ctx).isFailure())) {
+    digitizeAllHits(ctx, &m_rdoContainer, &m_simDataCollMap, &m_processedElements, m_thpcsi, rndmEngine);
   } else {
     ATH_MSG_DEBUG("no hits found in event!");
   }
@@ -206,7 +206,7 @@ StatusCode SCT_DigitizationTool::processAllSubEvents() {
 
   // loop over elements without hits
   if (not m_onlyHitElements) {
-    digitizeNonHits(&m_rdoContainer, &m_simDataCollMap, &m_processedElements, rndmEngine);
+    digitizeNonHits(ctx, &m_rdoContainer, &m_simDataCollMap, &m_processedElements, rndmEngine);
     ATH_MSG_DEBUG("Digitized Elements without Hits");
   }
 
@@ -220,15 +220,15 @@ StatusCode SCT_DigitizationTool::processAllSubEvents() {
 // ======================================================================
 // prepareEvent
 // ======================================================================
-StatusCode SCT_DigitizationTool::prepareEvent(unsigned int /*index*/) {
+StatusCode SCT_DigitizationTool::prepareEvent(const EventContext& ctx, unsigned int /*index*/) {
   ATH_MSG_VERBOSE("SCT_DigitizationTool::prepareEvent()");
   // Create the IdentifiableContainer to contain the digit collections Create
   // a new RDO container
-  m_rdoContainer = SG::makeHandle(m_rdoContainerKey);
+  m_rdoContainer = SG::makeHandle(m_rdoContainerKey, ctx);
   ATH_CHECK(m_rdoContainer.record(std::make_unique<SCT_RDO_Container>(m_detID->wafer_hash_max())));
 
   // Create a map for the SDO and register it into StoreGate
-  m_simDataCollMap = SG::makeHandle(m_simDataCollMapKey);
+  m_simDataCollMap = SG::makeHandle(m_simDataCollMapKey, ctx);
   ATH_CHECK(m_simDataCollMap.record(std::make_unique<InDetSimDataCollection>()));
 
   m_processedElements.clear();
@@ -242,20 +242,20 @@ StatusCode SCT_DigitizationTool::prepareEvent(unsigned int /*index*/) {
 // =========================================================================
 // mergeEvent
 // =========================================================================
-StatusCode SCT_DigitizationTool::mergeEvent() {
+StatusCode SCT_DigitizationTool::mergeEvent(const EventContext& ctx) {
   ATH_MSG_VERBOSE("SCT_DigitizationTool::mergeEvent()");
 
   // Set the RNG to use for this event.
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
-  CLHEP::HepRandomEngine *rndmEngine = *rngWrapper;
+  rngWrapper->setSeed( name(), ctx );
+  CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
 
   if (m_enableHits) {
-    digitizeAllHits(&m_rdoContainer, &m_simDataCollMap, &m_processedElements, m_thpcsi, rndmEngine);
+    digitizeAllHits(ctx, &m_rdoContainer, &m_simDataCollMap, &m_processedElements, m_thpcsi, rndmEngine);
   }
 
   if (not m_onlyHitElements) {
-    digitizeNonHits(&m_rdoContainer, &m_simDataCollMap, &m_processedElements, rndmEngine);
+    digitizeNonHits(ctx, &m_rdoContainer, &m_simDataCollMap, &m_processedElements, rndmEngine);
   }
 
   for (SiHitCollection* hit: m_hitCollPtrs) {
@@ -271,7 +271,7 @@ StatusCode SCT_DigitizationTool::mergeEvent() {
   return StatusCode::SUCCESS;
 }
 
-void SCT_DigitizationTool::digitizeAllHits(SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, std::vector<bool>* processedElements, TimedHitCollection<SiHit>* thpcsi, CLHEP::HepRandomEngine * rndmEngine) const {
+void SCT_DigitizationTool::digitizeAllHits(const EventContext& ctx, SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, std::vector<bool>* processedElements, TimedHitCollection<SiHit>* thpcsi, CLHEP::HepRandomEngine * rndmEngine) const {
   /////////////////////////////////////////////////
   //
   // In order to process all element rather than just those with hits we
@@ -284,7 +284,7 @@ void SCT_DigitizationTool::digitizeAllHits(SG::WriteHandle<SCT_RDO_Container>* r
 
   SiChargedDiodeCollection chargedDiodes;
 
-  while (digitizeElement(&chargedDiodes, thpcsi, rndmEngine)) {
+  while (digitizeElement(ctx, &chargedDiodes, thpcsi, rndmEngine)) {
     ATH_MSG_DEBUG("Hit collection ID=" << m_detID->show_to_string(chargedDiodes.identify()));
 
     hitcount++;  // Hitcount will be a number in the hit collection minus
@@ -322,9 +322,9 @@ void SCT_DigitizationTool::digitizeAllHits(SG::WriteHandle<SCT_RDO_Container>* r
 }
 
 // digitize elements without hits
-void SCT_DigitizationTool::digitizeNonHits(SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, const std::vector<bool>* processedElements, CLHEP::HepRandomEngine * rndmEngine) const {
+void SCT_DigitizationTool::digitizeNonHits(const EventContext& ctx, SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, const std::vector<bool>* processedElements, CLHEP::HepRandomEngine * rndmEngine) const {
   // Get SCT_DetectorElementCollection
-  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey);
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx);
   const InDetDD::SiDetectorElementCollection* elements{sctDetEle.retrieve()};
   if (elements==nullptr) {
     ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
@@ -371,7 +371,7 @@ void SCT_DigitizationTool::digitizeNonHits(SG::WriteHandle<SCT_RDO_Container>* r
   return;
 }
 
-bool SCT_DigitizationTool::digitizeElement(SiChargedDiodeCollection* chargedDiodes, TimedHitCollection<SiHit>*& thpcsi, CLHEP::HepRandomEngine * rndmEngine) const {
+bool SCT_DigitizationTool::digitizeElement(const EventContext& ctx, SiChargedDiodeCollection* chargedDiodes, TimedHitCollection<SiHit>*& thpcsi, CLHEP::HepRandomEngine * rndmEngine) const {
   if (nullptr == thpcsi) {
     ATH_MSG_ERROR("thpcsi should not be nullptr!");
 
@@ -397,7 +397,7 @@ bool SCT_DigitizationTool::digitizeElement(SiChargedDiodeCollection* chargedDiod
   IdentifierHash waferHash{m_detID->wafer_hash(id)};
 
   // Get SCT_DetectorElementCollection
-  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey);
+  SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> sctDetEle(m_SCTDetEleCollKey, ctx);
   const InDetDD::SiDetectorElementCollection* elements(sctDetEle.retrieve());
   if (elements==nullptr) {
     ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
@@ -715,15 +715,15 @@ SCT_RDO_Collection* SCT_DigitizationTool::createRDO(SiChargedDiodeCollection* co
 // ------------------------------------------------------------
 // Get next event and extract collection of hit collections:
 // ------------------------------------------------------------
-StatusCode SCT_DigitizationTool::getNextEvent() {
-  ATH_MSG_DEBUG("SCT_DigitizationTool::getNextEvent()");
+StatusCode SCT_DigitizationTool::getNextEvent(const EventContext& ctx) {
+  ATH_MSG_DEBUG("SCT_DigitizationTool::getNextEvent");
   //  get the container(s)
   typedef PileUpMergeSvc::TimedList<SiHitCollection>::type TimedHitCollList;
   // this is a list<pair<time_t, DataLink<SiHitCollection> >
 
   // In case of single hits container just load the collection using read handles
   if (!m_onlyUseContainerName) {
-    SG::ReadHandle<SiHitCollection> hitCollection(m_hitsContainerKey);
+    SG::ReadHandle<SiHitCollection> hitCollection(m_hitsContainerKey, ctx);
     if (!hitCollection.isValid()) {
       ATH_MSG_ERROR("Could not get SCT SiHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
       return StatusCode::FAILURE;
diff --git a/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.h b/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.h
index 4b4067b83c7a053c7d356066e877d12a06616575..b229b45faba60317309863eb561d2abb5c806d56 100644
--- a/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.h
+++ b/InnerDetector/InDetDigitization/SCT_Digitization/src/SCT_DigitizationTool.h
@@ -60,18 +60,18 @@ public:
   /**
      @brief Called before processing physics events
   */
-  virtual StatusCode prepareEvent(unsigned int) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int) override final;
   virtual StatusCode processBunchXing(int bunchXing,
                                       SubEventIterator bSubEvents,
                                       SubEventIterator eSubEvents) override final;
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
   virtual StatusCode initialize() override final;
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
 protected:
 
-  bool digitizeElement(SiChargedDiodeCollection* chargedDiodes, TimedHitCollection<SiHit>*& thpcsi, CLHEP::HepRandomEngine * rndmEngine) const ; //!
+  bool digitizeElement(const EventContext& ctx, SiChargedDiodeCollection* chargedDiodes, TimedHitCollection<SiHit>*& thpcsi, CLHEP::HepRandomEngine * rndmEngine) const ; //!
   void applyProcessorTools(SiChargedDiodeCollection* chargedDiodes, CLHEP::HepRandomEngine * rndmEngine) const; //!
   void addSDO(SiChargedDiodeCollection* collection, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap) const;
 
@@ -108,9 +108,9 @@ private:
   */
   SCT_RDO_Collection* createRDO(SiChargedDiodeCollection* collection) const;
 
-  StatusCode getNextEvent();
-  void       digitizeAllHits(SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, std::vector<bool>* processedElements, TimedHitCollection<SiHit>* thpcsi, CLHEP::HepRandomEngine * rndmEngine) const; //!< digitize all hits
-  void       digitizeNonHits(SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, const std::vector<bool>* processedElements, CLHEP::HepRandomEngine * rndmEngine) const;     //!< digitize SCT without hits
+  StatusCode getNextEvent(const EventContext& ctx);
+  void       digitizeAllHits(const EventContext& ctx, SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, std::vector<bool>* processedElements, TimedHitCollection<SiHit>* thpcsi, CLHEP::HepRandomEngine * rndmEngine) const; //!< digitize all hits
+  void       digitizeNonHits(const EventContext& ctx, SG::WriteHandle<SCT_RDO_Container>* rdoContainer, SG::WriteHandle<InDetSimDataCollection>* simDataCollMap, const std::vector<bool>* processedElements, CLHEP::HepRandomEngine * rndmEngine) const;     //!< digitize SCT without hits
 
   /**
      @brief Called when m_WriteSCT1_RawData is altered. Does nothing, but required by Gaudi.
diff --git a/InnerDetector/InDetDigitization/TRT_Digitization/CMakeLists.txt b/InnerDetector/InDetDigitization/TRT_Digitization/CMakeLists.txt
index 5bedd953f193b4622e53102fdc7b640d0537945e..4c6340a28227d399e04b87250b4c38a8456b4883 100644
--- a/InnerDetector/InDetDigitization/TRT_Digitization/CMakeLists.txt
+++ b/InnerDetector/InDetDigitization/TRT_Digitization/CMakeLists.txt
@@ -30,7 +30,9 @@ atlas_depends_on_subdirs( PUBLIC
                           InnerDetector/InDetSimEvent
                           InnerDetector/InDetSimUtils/TRT_PAI_Process
                           MagneticField/MagFieldInterfaces
-                          Simulation/HitManagement )
+                          Simulation/HitManagement
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions )
 
 # External dependencies:
 find_package( CLHEP )
@@ -43,7 +45,7 @@ atlas_add_component( TRT_Digitization
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${HEPPDT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${HEPPDT_LIBRARIES} ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} GaudiKernel AthenaBaseComps AthenaKernel PileUpToolsLib AthenaPoolUtilities GeoModelUtilities GeoPrimitives Identifier EventInfo GeneratorObjects TRT_ConditionsData TRT_ConditionsServicesLib InDetIdentifier InDetReadoutGeometry TRT_ReadoutGeometry InDetRawData InDetSimData InDetSimEvent MagFieldInterfaces HitManagement )
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${HEPPDT_LIBRARIES} ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} GaudiKernel AthenaBaseComps AthenaKernel PileUpToolsLib AthenaPoolUtilities GeoModelUtilities GeoPrimitives Identifier EventInfo GeneratorObjects TRT_ConditionsData TRT_ConditionsServicesLib InDetIdentifier InDetReadoutGeometry TRT_ReadoutGeometry InDetRawData InDetSimData InDetSimEvent MagFieldInterfaces HitManagement MagFieldElements MagFieldConditions)
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py )
diff --git a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitization.cxx b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitization.cxx
index ab621fc394113eda4acb2a1701a5c51e31dba136..4baeb5dd31c7d4c14b5defd5845faeca20895f65 100644
--- a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitization.cxx
+++ b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitization.cxx
@@ -27,5 +27,5 @@ StatusCode TRTDigitization::initialize() {
 //----------------------------------------------------------------------
 StatusCode TRTDigitization::execute() {
   ATH_MSG_DEBUG ( "execute()" );
-  return m_digTool->processAllSubEvents();
+  return m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitizationTool.cxx b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitizationTool.cxx
index 7835d99dfe6e360e2abcb6b61b0355fe1ad5de0f..2a2f37804a7d19f0c6ea05032ccaaa2125342af2 100644
--- a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitizationTool.cxx
+++ b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitizationTool.cxx
@@ -46,6 +46,8 @@
 
 // Gaudi includes
 #include "GaudiKernel/SmartDataPtr.h"
+#include "GaudiKernel/EventContext.h"
+#include "GaudiKernel/ThreadLocalContext.h"
 
 
 //CondDB
@@ -183,11 +185,15 @@ StatusCode TRTDigitizationTool::initialize()
     }
   }
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
   return StatusCode::SUCCESS;
 }
 
 //_____________________________________________________________________________
-StatusCode TRTDigitizationTool::prepareEvent(unsigned int)
+StatusCode TRTDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
 {
   m_vDigits.clear();
   m_trtHitCollList.clear();
@@ -242,14 +248,14 @@ StatusCode TRTDigitizationTool::processBunchXing(int bunchXing,
 }
 
 //_____________________________________________________________________________
-StatusCode TRTDigitizationTool::lateInitialize() {
+StatusCode TRTDigitizationTool::lateInitialize(const EventContext& ctx) {
 
   // setup the RNGs which are only used in the first event
-  CLHEP::HepRandomEngine *fakeCondRndmEngine = getRandomEngine("TRT_FakeConditions", m_randomSeedOffset);
-  CLHEP::HepRandomEngine *noiseInitRndmEngine = getRandomEngine("TRT_Noise", m_randomSeedOffset);
-  CLHEP::HepRandomEngine *noiseElecRndmEngine = getRandomEngine("TRT_Noise_Electronics", m_randomSeedOffset);
-  CLHEP::HepRandomEngine *noiseThreshRndmEngine = getRandomEngine("TRT_Noise_ThresholdFluctuations", m_randomSeedOffset);
-  CLHEP::HepRandomEngine *noiseElecResetRndmEngine = getRandomEngine("TRT_ElectronicsNoiseReset", m_randomSeedOffset);
+  CLHEP::HepRandomEngine *fakeCondRndmEngine = getRandomEngine("TRT_FakeConditions", m_randomSeedOffset, ctx);
+  CLHEP::HepRandomEngine *noiseInitRndmEngine = getRandomEngine("TRT_Noise", m_randomSeedOffset, ctx);
+  CLHEP::HepRandomEngine *noiseElecRndmEngine = getRandomEngine("TRT_Noise_Electronics", m_randomSeedOffset, ctx);
+  CLHEP::HepRandomEngine *noiseThreshRndmEngine = getRandomEngine("TRT_Noise_ThresholdFluctuations", m_randomSeedOffset, ctx);
+  CLHEP::HepRandomEngine *noiseElecResetRndmEngine = getRandomEngine("TRT_ElectronicsNoiseReset", m_randomSeedOffset, ctx);
   m_first_event=false;
 
   if (m_condDBdigverfoldersexists) {
@@ -338,7 +344,8 @@ StatusCode TRTDigitizationTool::lateInitialize() {
 }
 
 //_____________________________________________________________________________
-StatusCode TRTDigitizationTool::processStraws(const TimedHitCollection<TRTUncompressedHit>& thpctrt,
+StatusCode TRTDigitizationTool::processStraws(const EventContext& ctx,
+                                              const TimedHitCollection<TRTUncompressedHit>& thpctrt,
                                               std::set<int>& sim_hitids, std::set<Identifier>& simhitsIdentifiers,
                                               CLHEP::HepRandomEngine *rndmEngine,
                                               CLHEP::HepRandomEngine *strawRndmEngine,
@@ -347,8 +354,26 @@ StatusCode TRTDigitizationTool::processStraws(const TimedHitCollection<TRTUncomp
                                               CLHEP::HepRandomEngine *paiRndmEngine) {
 
   // Create a map for the SDO
-  SG::WriteHandle<InDetSimDataCollection> simDataMap(m_outputSDOCollName);
+  SG::WriteHandle<InDetSimDataCollection> simDataMap(m_outputSDOCollName, ctx);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+  MagField::AtlasFieldCache    fieldCache;
+  if (m_settings->useMagneticFieldMap()) {
+      
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+
+    if (fieldCondObj == nullptr) {
+        ATH_MSG_ERROR("SCTSiLorentzAngleCondAlg : Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+        return StatusCode::FAILURE;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+  }
+  
+////////////////////////////////////////////////////////////////////////////////////////////////////
 
+  
   ATH_CHECK(simDataMap.record(std::make_unique<InDetSimDataCollection>() ));
 
   // Register the map into StoreGate
@@ -441,7 +466,7 @@ StatusCode TRTDigitizationTool::processStraws(const TimedHitCollection<TRTUncomp
     bool emulateArFlag = m_sumTool->getStatusHT(idStraw) == 6;
     bool emulateKrFlag = m_sumTool->getStatusHT(idStraw) == 7;
     const int statusHT = m_sumTool->getStatusHT(idStraw);
-    m_pProcessingOfStraw->ProcessStraw(i, e, digit_straw,
+    m_pProcessingOfStraw->ProcessStraw(fieldCache, i, e, digit_straw,
                                        m_alreadyPrintedPDGcodeWarning,
                                        m_cosmicEventPhase, //m_ComTime,
                                        TRTDigiHelper::StrawGasType(statusHT,m_UseGasMix, &msg()),
@@ -471,18 +496,18 @@ StatusCode TRTDigitizationTool::processStraws(const TimedHitCollection<TRTUncomp
 }
 
 //_____________________________________________________________________________
-StatusCode TRTDigitizationTool::processAllSubEvents() {
+StatusCode TRTDigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
   // Set the RNGs to use for this event.
-  CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("");
-  CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise");
-  CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool");
-  CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw");
-  CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations");
-  CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI");
+  CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
+  CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
+  CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
+  CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
+  CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
+  CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
 
   if (m_first_event) {
-    if(this->lateInitialize().isFailure()) {
+    if(this->lateInitialize(ctx).isFailure()) {
       ATH_MSG_FATAL ( "lateInitialize method failed!" );
       return StatusCode::FAILURE;
     }
@@ -490,9 +515,9 @@ StatusCode TRTDigitizationTool::processAllSubEvents() {
 
   m_alreadyPrintedPDGcodeWarning = false;
 
-  ATH_MSG_DEBUG ( "TRTDigitization::execute()" );
+  ATH_MSG_DEBUG ( "TRTDigitizationTool::processAllSubEvents()" );
 
-  m_trtrdo_container = SG::makeHandle(m_outputRDOCollName);
+  m_trtrdo_container = SG::makeHandle(m_outputRDOCollName, ctx);
   ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
   ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
 
@@ -510,7 +535,7 @@ StatusCode TRTDigitizationTool::processAllSubEvents() {
   TimedHitCollection<TRTUncompressedHit> thpctrt;
   // In case of single hits container just load the collection using read handles
   if (!m_onlyUseContainerName) {
-    SG::ReadHandle<TRTUncompressedHitCollection> hitCollection(m_hitsContainerKey);
+    SG::ReadHandle<TRTUncompressedHitCollection> hitCollection(m_hitsContainerKey, ctx);
     if (!hitCollection.isValid()) {
       ATH_MSG_ERROR("Could not get TRTUncompressedHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
       return StatusCode::FAILURE;
@@ -558,7 +583,7 @@ StatusCode TRTDigitizationTool::processAllSubEvents() {
   std::set<Identifier> simhitsIdentifiers;
 
   // Process the Hits straw by straw: get the iterator pairs for given straw
-  ATH_CHECK(this->processStraws(thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
+  ATH_CHECK(this->processStraws(ctx, thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
 
   // no more hits
 
@@ -593,25 +618,26 @@ StatusCode TRTDigitizationTool::processAllSubEvents() {
   return StatusCode::SUCCESS;
 }
 
-CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName) const
+CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName,
+                                                             const EventContext& ctx) const
 {
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
   std::string rngName = name()+streamName;
-  rngWrapper->setSeed( rngName, Gaudi::Hive::currentContext() );
-  return *rngWrapper;
+  rngWrapper->setSeed( rngName, ctx );
+  return rngWrapper->getEngine(ctx);
 }
 
 //_____________________________________________________________________________
-CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName, unsigned long int randomSeedOffset) const
+CLHEP::HepRandomEngine* TRTDigitizationTool::getRandomEngine(const std::string& streamName, unsigned long int randomSeedOffset,
+                                                             const EventContext& ctx) const
 {
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
-  const EventContext& ctx = Gaudi::Hive::currentContext();
   rngWrapper->setSeed( streamName, ctx.slot(), randomSeedOffset, ctx.eventID().run_number() );
-  return *rngWrapper;
+  return rngWrapper->getEngine(ctx);
 }
 
 //_____________________________________________________________________________
-StatusCode TRTDigitizationTool::mergeEvent() {
+StatusCode TRTDigitizationTool::mergeEvent(const EventContext& ctx) {
   std::vector<std::pair<unsigned int, int> >::iterator ii(m_seen.begin());
   std::vector<std::pair<unsigned int, int> >::iterator ee(m_seen.end());
   while (ii != ee) {
@@ -620,15 +646,15 @@ StatusCode TRTDigitizationTool::mergeEvent() {
   }
 
   // Set the RNGs to use for this event.
-  CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("");
-  CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise");
-  CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool");
-  CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw");
-  CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations");
-  CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI");
+  CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
+  CLHEP::HepRandomEngine *elecNoiseRndmEngine = getRandomEngine("TRT_ElectronicsNoise", ctx);
+  CLHEP::HepRandomEngine *noiseRndmEngine = getRandomEngine("TRT_NoiseDigitPool", ctx);
+  CLHEP::HepRandomEngine *strawRndmEngine = getRandomEngine("TRT_ProcessStraw", ctx);
+  CLHEP::HepRandomEngine *elecProcRndmEngine = getRandomEngine("TRT_ThresholdFluctuations", ctx);
+  CLHEP::HepRandomEngine *paiRndmEngine = getRandomEngine("TRT_PAI", ctx);
 
   if (m_first_event) {
-    if(this->lateInitialize().isFailure()) {
+    if(this->lateInitialize(ctx).isFailure()) {
       ATH_MSG_FATAL ( "lateInitialize method failed!" );
       return StatusCode::FAILURE;
     }
@@ -638,7 +664,7 @@ StatusCode TRTDigitizationTool::mergeEvent() {
 
   ATH_MSG_DEBUG ( "TRTDigitization::execute()"  );
 
-  m_trtrdo_container = SG::makeHandle(m_outputRDOCollName);
+  m_trtrdo_container = SG::makeHandle(m_outputRDOCollName, ctx);
   ATH_CHECK(m_trtrdo_container.record(std::make_unique<TRT_RDO_Container>(m_trt_id->straw_layer_hash_max())));
   ATH_MSG_DEBUG ( " TRT_RDO_Container created " );
   if (not m_trtrdo_container.isValid()) {
@@ -654,7 +680,7 @@ StatusCode TRTDigitizationTool::mergeEvent() {
 
   // Process the Hits straw by straw:
   //   get the iterator pairs for given straw
-  ATH_CHECK(this->processStraws(*m_thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
+  ATH_CHECK(this->processStraws(ctx, *m_thpctrt, sim_hitids, simhitsIdentifiers, rndmEngine, strawRndmEngine, elecProcRndmEngine, elecNoiseRndmEngine,paiRndmEngine));
 
   delete m_thpctrt;
   std::list<TRTUncompressedHitCollection*>::iterator trtHitColl(m_trtHitCollList.begin());
diff --git a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitizationTool.h b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitizationTool.h
index 0c6d4b06c7dcf2b0416a52aa0283e94663932405..d4f4f520a5878b6b4107623ff27574fb7fc1985a 100644
--- a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitizationTool.h
+++ b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTDigitizationTool.h
@@ -28,6 +28,7 @@
 
 // For magneticfield
 #include "MagFieldInterfaces/IMagFieldSvc.h"
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
 
 #include "StoreGate/ReadHandleKey.h"
 #include "StoreGate/WriteHandleKey.h"
@@ -75,7 +76,7 @@ public:
   virtual StatusCode finalize() override final;
 
   ///called at the end of the subevts loop. Not (necessarily) able to access SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
   ///called for each active bunch-crossing to process current SubEvents bunchXing is in ns
   virtual StatusCode processBunchXing( int bunchXing,
@@ -85,7 +86,7 @@ public:
   /// implemented by default in PileUpToolBase as FirstXing<=bunchXing<=LastXing
   //  virtual bool toProcess(int bunchXing) const;
 
-  virtual StatusCode prepareEvent( const unsigned int /*nInputEvents*/ ) override final;
+  virtual StatusCode prepareEvent( const EventContext& ctx, const unsigned int nInputEvents ) override final;
 
   /**
    * Perform digitization:
@@ -94,11 +95,11 @@ public:
    * - Add noise
    * - Create RDO collection
    */
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
 private:
-  CLHEP::HepRandomEngine* getRandomEngine(const std::string& streamName) const;
-  CLHEP::HepRandomEngine* getRandomEngine(const std::string& streamName, unsigned long int randomSeedOffset) const;
+  CLHEP::HepRandomEngine* getRandomEngine(const std::string& streamName, const EventContext& ctx) const;
+  CLHEP::HepRandomEngine* getRandomEngine(const std::string& streamName, unsigned long int randomSeedOffset, const EventContext& ctx) const;
 
   Identifier getIdentifier( int hitID,
                             IdentifierHash& hashId,
@@ -108,8 +109,11 @@ private:
   StatusCode update( IOVSVC_CALLBACK_ARGS );        // Update of database entries.
   StatusCode ConditionsDependingInitialization();
 
-  StatusCode lateInitialize();
-  StatusCode processStraws(const TimedHitCollection<TRTUncompressedHit>& thpctrt, std::set<int>& sim_hitids, std::set<Identifier>& simhitsIdentifiers,
+  StatusCode lateInitialize(const EventContext& ctx);
+  StatusCode processStraws(const EventContext& ctx,
+                           const TimedHitCollection<TRTUncompressedHit>& thpctrt,
+                           std::set<int>& sim_hitids,
+                           std::set<Identifier>& simhitsIdentifiers,
                            CLHEP::HepRandomEngine *rndmEngine,
                            CLHEP::HepRandomEngine *strawRndmEngine,
                            CLHEP::HepRandomEngine *elecProcRndmEngine,
@@ -130,7 +134,9 @@ private:
   ServiceHandle<IAthRNGSvc> m_rndmSvc{this, "RndmSvc", "AthRNGSvc", ""};  //!< Random number service
   ServiceHandle<ITRT_StrawNeighbourSvc> m_TRTStrawNeighbourSvc{this, "TRT_StrawNeighbourSvc", "TRT_StrawNeighbourSvc", ""};
   ServiceHandle < MagField::IMagFieldSvc > m_magneticfieldsvc{this, "MagFieldSvc", "AtlasFieldSvc", "MagFieldSvc used by TRTProcessingOfStraw"};
-
+  // Read handle for conditions object to get the field cache
+  SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                        "Name of the Magnetic Field conditions object key"};
   Gaudi::Property<bool> m_onlyUseContainerName{this, "OnlyUseContainerName", true, "Don't use the ReadHandleKey directly. Just extract the container name from it."};
   SG::ReadHandleKey<TRTUncompressedHitCollection> m_hitsContainerKey{this, "DataObjectName", "TRTUncompressedHits", "Data Object Name"};
   std::string m_dataObjectName{""};
diff --git a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTProcessingOfStraw.cxx b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTProcessingOfStraw.cxx
index 4f1f17d365e93c25880e1da53630d4cee13ab58f..0747a150eefee9626cdc12eb8e657d5a0311c2b6 100644
--- a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTProcessingOfStraw.cxx
+++ b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTProcessingOfStraw.cxx
@@ -207,6 +207,7 @@ void TRTProcessingOfStraw::Initialize(const ITRT_CalDbTool* calDbTool)
         }
     }
 
+
   ATH_MSG_VERBOSE ( "Initialization done" );
 
   return;
@@ -260,7 +261,8 @@ void TRTProcessingOfStraw::addClustersFromStep ( const double& scaledKineticEner
 }
 
 //________________________________________________________________________________
-void TRTProcessingOfStraw::ProcessStraw ( hitCollConstIter i,
+void TRTProcessingOfStraw::ProcessStraw ( MagField::AtlasFieldCache& fieldCache,
+                                          hitCollConstIter i,
                                           hitCollConstIter e,
                                           TRTDigit& outdigit,
                                           bool & alreadyPrintedPDGcodeWarning,
@@ -520,8 +522,9 @@ void TRTProcessingOfStraw::ProcessStraw ( hitCollConstIter i,
   //////////////////////////////////////////////////////////
 
   m_depositList.clear();
-  // ClustersToDeposits( hitID, m_clusterlist, m_depositList, TRThitGlobalPos, m_ComTime, strawGasType );
-  ClustersToDeposits( hitID, m_clusterlist, m_depositList, TRThitGlobalPos, cosmicEventPhase, strawGasType, rndmEngine );
+
+  ClustersToDeposits(fieldCache, hitID, m_clusterlist, m_depositList, TRThitGlobalPos, cosmicEventPhase, strawGasType, rndmEngine );
+
 
   //////////////////////////////////////////////////////////
   //======================================================//
@@ -557,11 +560,11 @@ void TRTProcessingOfStraw::ProcessStraw ( hitCollConstIter i,
 }
 
 //________________________________________________________________________________
-void TRTProcessingOfStraw::ClustersToDeposits (const int& hitID,
-                                               const std::vector<cluster>& clusters,
-                                               std::vector<TRTElectronicsProcessing::Deposit>& deposits,
-                                               Amg::Vector3D TRThitGlobalPos,
-                                               double cosmicEventPhase, // was const ComTime* m_ComTime,
+void TRTProcessingOfStraw::ClustersToDeposits (MagField::AtlasFieldCache& fieldCache, const int& hitID,
+					       const std::vector<cluster>& clusters,
+					       std::vector<TRTElectronicsProcessing::Deposit>& deposits,
+					       Amg::Vector3D TRThitGlobalPos,
+					       double cosmicEventPhase, // was const ComTime* m_ComTime,
                                                int strawGasType,
                                                CLHEP::HepRandomEngine* rndmEngine)
 {
@@ -605,7 +608,13 @@ void TRTProcessingOfStraw::ClustersToDeposits (const int& hitID,
       globalPosition[0]=TRThitGlobalPos[0]*CLHEP::mm;
       globalPosition[1]=TRThitGlobalPos[1]*CLHEP::mm;
       globalPosition[2]=TRThitGlobalPos[2]*CLHEP::mm;
-      m_magneticfieldsvc->getField(&globalPosition, &mField);
+
+    // MT Field cache is stored in cache
+
+    // MT version uses cache, temporarily keep old version
+      if (fieldCache.useNewBfieldCache()) fieldCache.getField         (globalPosition.data(), mField.data());
+      else                                m_magneticfieldsvc->getField(&globalPosition, &mField);
+
       map_x2 = mField.x()*mField.x(); // would be zero for a uniform field
       map_y2 = mField.y()*mField.y(); // would be zero for a uniform field
       map_z2 = mField.z()*mField.z(); // would be m_solenoidfieldstrength^2 for uniform field
diff --git a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTProcessingOfStraw.h b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTProcessingOfStraw.h
index 3f44e18342643be4123775d768a49f8ee2e0f379..9f860212f343df8c3fd42486056484318d12484d 100644
--- a/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTProcessingOfStraw.h
+++ b/InnerDetector/InDetDigitization/TRT_Digitization/src/TRTProcessingOfStraw.h
@@ -24,6 +24,12 @@
 #include "TRT_ConditionsServices/ITRT_StrawStatusSummaryTool.h"
 #include "TRT_ConditionsServices/ITRT_CalDbTool.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
 class TRTDigit;
 class TRTTimeCorrection;
 class TRTNoise;
@@ -85,11 +91,12 @@ public:
    * @param outdigit: The 27 bit digit
    * (bits: 8 low + 1 high + 8 low + 1 high + 8 low + 1 high)
    */
-  void ProcessStraw (hitCollConstIter i,
-                     hitCollConstIter e,
-                     TRTDigit& outdigit,
-                     bool & m_alreadyPrintedPDGcodeWarning,
-                     double m_cosmicEventPhase, //const ComTime* m_ComTime,
+  void ProcessStraw (MagField::AtlasFieldCache& fieldCache,
+                     hitCollConstIter i,
+		     hitCollConstIter e,
+		     TRTDigit& outdigit,
+		     bool & m_alreadyPrintedPDGcodeWarning,
+		     double m_cosmicEventPhase, //const ComTime* m_ComTime,
                      int strawGasType,
                      bool emulationArflag,
                      bool emulationKrflag,
@@ -214,10 +221,10 @@ private:
    * @param clusters: ionisation clusters along particle trajectory
    * @param deposits: energy deposits on wire
    */
-  void ClustersToDeposits (const int& hitID,
-                           const std::vector<cluster>& clusters,
-                           std::vector<TRTElectronicsProcessing::Deposit>& deposits,
-                           Amg::Vector3D TRThitGlobalPos,
+  void ClustersToDeposits (MagField::AtlasFieldCache& fieldCache, const int& hitID,
+			   const std::vector<cluster>& clusters,
+			   std::vector<TRTElectronicsProcessing::Deposit>& deposits,
+			   Amg::Vector3D TRThitGlobalPos,
                            double m_cosmicEventPhase, // const ComTime* m_ComTime
                            int strawGasType,
                            CLHEP::HepRandomEngine* rndmEngine);
diff --git a/InnerDetector/InDetExample/InDetDetDescrExample/src/ReadSiDetectorElements.cxx b/InnerDetector/InDetExample/InDetDetDescrExample/src/ReadSiDetectorElements.cxx
index 6832c895d65b037343e21a65153dd5604e3dceb6..63ecf0fd82431e3e00d47bb544c5edb8b272935a 100755
--- a/InnerDetector/InDetExample/InDetDetDescrExample/src/ReadSiDetectorElements.cxx
+++ b/InnerDetector/InDetExample/InDetDetDescrExample/src/ReadSiDetectorElements.cxx
@@ -660,11 +660,10 @@ ReadSiDetectorElements::testElement(const Identifier & id,
 
 std::string 
 ReadSiDetectorElements::printElementId(const SiDetectorElement * element) const{
-  static const std::string noElementString("NONE");
   if (element) {
     return element->getIdHelper()->show_to_string(element->identify());
   } else {
-    return noElementString;
+    return "NONE";
   }
 }
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
diff --git a/InnerDetector/InDetExample/InDetRecExample/share/InDetRecLoadTools.py b/InnerDetector/InDetExample/InDetRecExample/share/InDetRecLoadTools.py
index a826109ac606f7fb201466dd07131b18d1922b68..98b9dcc51d4244dc63002c903ba5e0b50cff21a4 100755
--- a/InnerDetector/InDetExample/InDetRecExample/share/InDetRecLoadTools.py
+++ b/InnerDetector/InDetExample/InDetRecExample/share/InDetRecLoadTools.py
@@ -339,7 +339,8 @@ if InDetFlags.doPattern():
     # Igors propagator needed by Igors tools
     #
     from TrkExRungeKuttaPropagator.TrkExRungeKuttaPropagatorConf import Trk__RungeKuttaPropagator as Propagator
-    InDetPatternPropagator = Propagator(name = 'InDetPatternPropagator')
+    InDetPatternPropagator = Propagator(name = 'InDetPatternPropagator',
+                                        UseCondObj = False)
     ToolSvc += InDetPatternPropagator
     if (InDetFlags.doPrintConfigurables()):
       printfunc (     InDetPatternPropagator)
diff --git a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/CMakeLists.txt b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/CMakeLists.txt
index 1c9830a20766cead5a80e0e0cd44291e8789659c..182e35d964e22475524d89fc90ccceed1282c55c 100644
--- a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/CMakeLists.txt
+++ b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/CMakeLists.txt
@@ -24,7 +24,8 @@ atlas_depends_on_subdirs( PUBLIC
                           Event/xAOD/xAODEventInfo
                           InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData
                           Tracking/TrkEvent/TrkPatternParameters
-                          Tracking/TrkEvent/TrkRIO_OnTrack )
+                          Tracking/TrkEvent/TrkRIO_OnTrack
+			  )
 
 # Component(s) in the package:
 atlas_add_component( SiSPSeededTrackFinder
diff --git a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/src/SiSPSeededTrackFinder.cxx b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/src/SiSPSeededTrackFinder.cxx
index 585f21adce34a807fb6c3031649238fc89542386..ecb5f351240d460a8ca07cb95abb9264e16a6a1d 100644
--- a/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/src/SiSPSeededTrackFinder.cxx
+++ b/InnerDetector/InDetRecAlgs/SiSPSeededTrackFinder/src/SiSPSeededTrackFinder.cxx
@@ -137,19 +137,19 @@ StatusCode InDet::SiSPSeededTrackFinder::oldStrategy(const EventContext& ctx) co
   SiSpacePointsSeedMakerEventData seedEventData;
   bool ZVE = false;
   if (m_useZvertexTool) {
-    std::list<Trk::Vertex> vertices = m_zvertexmaker->newEvent(seedEventData);
+    std::list<Trk::Vertex> vertices = m_zvertexmaker->newEvent(ctx, seedEventData);
     if (not vertices.empty()) ZVE = true;
-    m_seedsmaker->find3Sp(seedEventData, vertices);
+    m_seedsmaker->find3Sp(ctx, seedEventData, vertices);
   } else {
-    m_seedsmaker->newEvent(seedEventData, -1);
+    m_seedsmaker->newEvent(ctx, seedEventData, -1);
     std::list<Trk::Vertex> VZ;
-    m_seedsmaker->find3Sp(seedEventData, VZ);
+    m_seedsmaker->find3Sp(ctx, seedEventData, VZ);
   }
 
   const bool PIX = true;
   const bool SCT = true;
   InDet::ExtendedSiTrackMakerEventData_xk trackEventData(m_prdToTrackMap);
-  m_trackmaker->newEvent(trackEventData, PIX, SCT);
+  m_trackmaker->newEvent(ctx, trackEventData, PIX, SCT);
 
   bool ERR = false;
   Counter_t counter{};
@@ -157,9 +157,9 @@ StatusCode InDet::SiSPSeededTrackFinder::oldStrategy(const EventContext& ctx) co
   std::multimap<double, Trk::Track*> qualityTrack;
   // Loop through all seed and reconsrtucted tracks collection preparation
   //
-  while ((seed = m_seedsmaker->next(seedEventData))) {
+  while ((seed = m_seedsmaker->next(ctx, seedEventData))) {
     ++counter[kNSeeds];
-    std::list<Trk::Track*> trackList = m_trackmaker->getTracks(trackEventData, seed->spacePoints());
+    std::list<Trk::Track*> trackList = m_trackmaker->getTracks(ctx, trackEventData, seed->spacePoints());
     for (Trk::Track* t: trackList) {
       qualityTrack.insert(std::make_pair(-trackQuality(t), t));
     }
@@ -228,14 +228,14 @@ StatusCode InDet::SiSPSeededTrackFinder::newStrategy(const EventContext& ctx) co
 
   SiSpacePointsSeedMakerEventData seedEventData;
  
-  m_seedsmaker->newEvent(seedEventData, 0);
+  m_seedsmaker->newEvent(ctx, seedEventData, 0);
   std::list<Trk::Vertex> VZ;
-  m_seedsmaker->find3Sp(seedEventData, VZ);
+  m_seedsmaker->find3Sp(ctx, seedEventData, VZ);
 
   const bool PIX = true ;
   const bool SCT = true ;
   InDet::ExtendedSiTrackMakerEventData_xk trackEventData(m_prdToTrackMap);
-  m_trackmaker->newEvent(trackEventData, PIX, SCT);
+  m_trackmaker->newEvent(ctx, trackEventData, PIX, SCT);
 
   std::vector<int> nhistogram(m_histsize, 0);
   std::vector<double> zhistogram(m_histsize, 0.);
@@ -247,10 +247,10 @@ StatusCode InDet::SiSPSeededTrackFinder::newStrategy(const EventContext& ctx) co
   std::multimap<double, Trk::Track*> qualityTrack;
   // Loop through all seed and reconsrtucted tracks collection preparation
   //
-  while ((seed = m_seedsmaker->next(seedEventData))) {
+  while ((seed = m_seedsmaker->next(ctx, seedEventData))) {
     ++counter[kNSeeds];
     bool firstTrack{true};
-    std::list<Trk::Track*> trackList = m_trackmaker->getTracks(trackEventData, seed->spacePoints());
+    std::list<Trk::Track*> trackList = m_trackmaker->getTracks(ctx, trackEventData, seed->spacePoints());
     for (Trk::Track* t: trackList) {
       qualityTrack.insert(std::make_pair(-trackQuality(t), t));
 
@@ -266,21 +266,21 @@ StatusCode InDet::SiSPSeededTrackFinder::newStrategy(const EventContext& ctx) co
     }
   }
 
-  m_seedsmaker->newEvent(seedEventData, 1);
+  m_seedsmaker->newEvent(ctx, seedEventData, 1);
 
   double ZB[2];
   if (not m_ITKGeometry) {
     findZvertex(VZ, ZB, nhistogram, zhistogram, phistogram);
-    m_seedsmaker->find3Sp(seedEventData, VZ, ZB);
+    m_seedsmaker->find3Sp(ctx, seedEventData, VZ, ZB);
   } else {
-    m_seedsmaker->find3Sp(seedEventData, VZ);
+    m_seedsmaker->find3Sp(ctx, seedEventData, VZ);
   }
 
   // Loop through all seed and reconsrtucted tracks collection preparation
   //
-  while ((seed = m_seedsmaker->next(seedEventData))) {
+  while ((seed = m_seedsmaker->next(ctx, seedEventData))) {
     ++counter[kNSeeds];
-    for (Trk::Track* t: m_trackmaker->getTracks(trackEventData, seed->spacePoints())) {
+    for (Trk::Track* t: m_trackmaker->getTracks(ctx, trackEventData, seed->spacePoints())) {
       qualityTrack.insert(std::make_pair(-trackQuality(t), t));
     }
     if (counter[kNSeeds] >= m_maxNumberSeeds) {
diff --git a/InnerDetector/InDetRecAlgs/TRT_SeededTrackFinder/TRT_SeededTrackFinder/TRT_SeededTrackFinder.h b/InnerDetector/InDetRecAlgs/TRT_SeededTrackFinder/TRT_SeededTrackFinder/TRT_SeededTrackFinder.h
index 37742738f21a990b4cc0ec77281d5f922657c99e..073e6bf096cdadaf9b63f9cf1fb51dba29e513e9 100755
--- a/InnerDetector/InDetRecAlgs/TRT_SeededTrackFinder/TRT_SeededTrackFinder/TRT_SeededTrackFinder.h
+++ b/InnerDetector/InDetRecAlgs/TRT_SeededTrackFinder/TRT_SeededTrackFinder/TRT_SeededTrackFinder.h
@@ -159,7 +159,7 @@ namespace InDet {
       Trk::Track*                   mergeExtension(const Trk::Track&,std::vector<const Trk::MeasurementBase*>&) const;
 
       /** Transform a TRT track segment into a track  */
-      Trk::Track*                   segToTrack(const Trk::TrackSegment&) const;
+        Trk::Track*                 segToTrack(const EventContext&, const Trk::TrackSegment&) const;
 
       /** Do some statistics analysis at the end of each event */
       void                 Analyze(TrackCollection*) const;
diff --git a/InnerDetector/InDetRecAlgs/TRT_SeededTrackFinder/src/TRT_SeededTrackFinder.cxx b/InnerDetector/InDetRecAlgs/TRT_SeededTrackFinder/src/TRT_SeededTrackFinder.cxx
index 929878d03a99aa95320410760f91b73a598cb649..f2f020033a2eb2859209b3b8d37229919fc8a087 100644
--- a/InnerDetector/InDetRecAlgs/TRT_SeededTrackFinder/src/TRT_SeededTrackFinder.cxx
+++ b/InnerDetector/InDetRecAlgs/TRT_SeededTrackFinder/src/TRT_SeededTrackFinder.cxx
@@ -173,8 +173,8 @@ StatusCode InDet::TRT_SeededTrackFinder::execute_r (const EventContext& ctx) con
   InDet::ExtendedSiCombinatorialTrackFinderData_xk combinatorialData(m_prdToTrackMap);
 
   // Initialize the TRT seeded track tool's new event
-  std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData> event_data_p( m_trackmaker  ->newEvent(combinatorialData));
-  std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> ext_event_data_p( m_trtExtension->newEvent() );
+  std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData> event_data_p( m_trackmaker->newEvent(ctx, combinatorialData));
+  std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> ext_event_data_p( m_trtExtension->newEvent(ctx) );
 
 //  TrackCollection* outTracks  = new TrackCollection;           //Tracks to be finally output
   std::unique_ptr<TrackCollection> outTracks = std::make_unique<TrackCollection>();
@@ -221,7 +221,7 @@ StatusCode InDet::TRT_SeededTrackFinder::execute_r (const EventContext& ctx) con
         ev_stat.m_counter[Stat_t::Stat_t::kNTrtSegGood]++;
 
 	// ok, call track maker and get list of possible track candidates
-        std::list<Trk::Track*> trackSi = m_trackmaker->getTrack(*event_data_p, *trackTRT); //Get the possible Si extensions
+        std::list<Trk::Track*> trackSi = m_trackmaker->getTrack(ctx, *event_data_p, *trackTRT); //Get the possible Si extensions
 
         if (trackSi.size()==0) {
           ATH_MSG_DEBUG ("No Si track candidates associated to the TRT track ");
@@ -232,7 +232,7 @@ StatusCode InDet::TRT_SeededTrackFinder::execute_r (const EventContext& ctx) con
 	  // obsolete backup of TRT only
           if(m_saveTRT && trackTRT->numberOfMeasurementBases() > m_minTRTonly){
             ///Transform the original TRT segment into a track
-            Trk::Track* trtSeg = 0;trtSeg = segToTrack(*trackTRT);
+            Trk::Track* trtSeg = 0;trtSeg = segToTrack(ctx, *trackTRT);
             if(!trtSeg) {
 	      ATH_MSG_DEBUG ("Failed to make a track out of the TRT segment!");
 	      continue;
@@ -356,7 +356,7 @@ StatusCode InDet::TRT_SeededTrackFinder::execute_r (const EventContext& ctx) con
 	      ev_stat.m_counter[Stat_t::Stat_t::kNTrtExtCalls]++;
 
 	      // call extension tool
-              std::vector<const Trk::MeasurementBase*>& tn = m_trtExtension->extendTrack(*(*itt), *ext_event_data_p);
+              std::vector<const Trk::MeasurementBase*>& tn = m_trtExtension->extendTrack(ctx, *(*itt), *ext_event_data_p);
 
               if(!tn.size()) {
 
@@ -419,7 +419,7 @@ StatusCode InDet::TRT_SeededTrackFinder::execute_r (const EventContext& ctx) con
               ATH_MSG_DEBUG ("Failed to merge TRT+Si track segment !");
 
 	      if(m_saveTRT && trackTRT->numberOfMeasurementBases() > m_minTRTonly) {
-                Trk::Track* trtSeg = 0;trtSeg = segToTrack(*trackTRT);
+                Trk::Track* trtSeg = 0;trtSeg = segToTrack(ctx, *trackTRT);
                 if(!trtSeg){
 		  ATH_MSG_DEBUG ("Failed to make a track out of the  TRT segment!");
 		  continue;
@@ -649,7 +649,7 @@ Trk::Track* InDet::TRT_SeededTrackFinder::mergeSegments(const Trk::Track& tT, co
 // Transform a TRT segment to track
 ///////////////////////////////////////////////////////////////////
 
-Trk::Track* InDet::TRT_SeededTrackFinder::segToTrack(const Trk::TrackSegment& tS) const {
+Trk::Track* InDet::TRT_SeededTrackFinder::segToTrack(const EventContext&, const Trk::TrackSegment& tS) const {
 	ATH_MSG_DEBUG ("Transforming the TRT segment into a track...");
 
 	//Get the track segment information and build the initial track parameters
diff --git a/InnerDetector/InDetRecAlgs/TRT_StandaloneTrackFinder/src/TRT_StandaloneTrackFinder.cxx b/InnerDetector/InDetRecAlgs/TRT_StandaloneTrackFinder/src/TRT_StandaloneTrackFinder.cxx
index 70048911568c57269c254e82f9d7c6131ac1eb94..d217a7bf11d56c2becd758813924293469a84988 100644
--- a/InnerDetector/InDetRecAlgs/TRT_StandaloneTrackFinder/src/TRT_StandaloneTrackFinder.cxx
+++ b/InnerDetector/InDetRecAlgs/TRT_StandaloneTrackFinder/src/TRT_StandaloneTrackFinder.cxx
@@ -164,7 +164,7 @@ StatusCode InDet::TRT_StandaloneTrackFinder::execute(const EventContext& ctx) co
 	ATH_MSG_DEBUG ("Segment considered for further processing, enter into list");
 
 	// Transform the original TRT segment into a track
-	Trk::Track* trtSeg = m_segToTrackTool->segToTrack(*trackTRT);
+	Trk::Track* trtSeg = m_segToTrackTool->segToTrack(ctx, *trackTRT);
 	if(!trtSeg){
 	  // Statistics...
 	  counter[kNSegFailed]++;
diff --git a/InnerDetector/InDetRecAlgs/TRT_TrackExtensionAlg/src/TRT_TrackExtensionAlg.cxx b/InnerDetector/InDetRecAlgs/TRT_TrackExtensionAlg/src/TRT_TrackExtensionAlg.cxx
index 0e82e202ccb580ebfe0e377b2a5d42a2bd98cfc6..c2da6d7be406d128899694c67438a2677751bf48 100755
--- a/InnerDetector/InDetRecAlgs/TRT_TrackExtensionAlg/src/TRT_TrackExtensionAlg.cxx
+++ b/InnerDetector/InDetRecAlgs/TRT_TrackExtensionAlg/src/TRT_TrackExtensionAlg.cxx
@@ -53,7 +53,7 @@ StatusCode InDet::TRT_TrackExtensionAlg::execute_r(const EventContext& ctx) cons
 	}
 
         std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData>
-           event_data_p( m_trtExtension->newEvent() );
+           event_data_p( m_trtExtension->newEvent(ctx) );
 
 	// Loop through all input track and output tracks collection production
 	SG::WriteHandle<TrackExtensionMap> outputTracks(m_outputTracksKey,ctx);
@@ -64,7 +64,7 @@ StatusCode InDet::TRT_TrackExtensionAlg::execute_r(const EventContext& ctx) cons
 		if ( !(*trk) ) continue;
 		++counter.m_nTracks;
 
-		std::vector<const Trk::MeasurementBase*>& trkExt = m_trtExtension->extendTrack(*(*trk), *event_data_p);
+		std::vector<const Trk::MeasurementBase*>& trkExt = m_trtExtension->extendTrack(ctx, *(*trk), *event_data_p);
 		if( !trkExt.size() ) continue;
 
 		outputTracks->insert( std::make_pair((*trk), trkExt) ); 
diff --git a/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/CMakeLists.txt b/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/CMakeLists.txt
index 8162e745964c1f1d736890f9741b629d6898e070..4b545bf1a408ca111c9383fa5e89203e3bc437db 100644
--- a/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/CMakeLists.txt
+++ b/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/CMakeLists.txt
@@ -14,13 +14,15 @@ atlas_depends_on_subdirs( PUBLIC
                           InnerDetector/InDetDetDescr/InDetReadoutGeometry
 			  InnerDetector/InDetDetDescr/TRT_ReadoutGeometry
                           Tracking/TrkEvent/TrkCaloClusterROI
-                          Tracking/TrkEvent/TrkSegment )
+                          Tracking/TrkEvent/TrkSegment
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions)
 
 # Component(s) in the package:
 atlas_add_component( TRT_TrackSegmentsFinder
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetRecToolInterfaces InDetReadoutGeometry TRT_ReadoutGeometry TrkCaloClusterROI TrkSegment )
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetRecToolInterfaces InDetReadoutGeometry TRT_ReadoutGeometry TrkCaloClusterROI TrkSegment MagFieldElements MagFieldConditions )
 
 # Install files from the package:
 atlas_install_headers( TRT_TrackSegmentsFinder )
diff --git a/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/TRT_TrackSegmentsFinder/TRT_TrackSegmentsFinder.h b/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/TRT_TrackSegmentsFinder/TRT_TrackSegmentsFinder.h
index b49546ed5fc76f90bda6f97de261503759da426d..a735d8e59707d2afa7c38f2d7014bd17a17932da 100755
--- a/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/TRT_TrackSegmentsFinder/TRT_TrackSegmentsFinder.h
+++ b/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/TRT_TrackSegmentsFinder/TRT_TrackSegmentsFinder.h
@@ -16,6 +16,9 @@
 #include "StoreGate/ReadHandleKey.h"
 #include "TrkSegment/SegmentCollection.h"
 #include "TrkCaloClusterROI/CaloClusterROI_Collection.h"
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
 namespace InDet {
 
 
@@ -61,6 +64,8 @@ namespace InDet {
       ToolHandle<ITRT_DetElementsRoadMaker>         m_roadtool
        {this, "RoadTool", "InDet::TRT_DetElementsRoadMaker_xk", "Tool to build roads in the TRT."};
 
+      SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
+        
       mutable std::atomic<int>                      m_nsegmentsTotal {}  ; // statistics about number of segments
 
     };
diff --git a/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/src/TRT_TrackSegmentsFinder.cxx b/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/src/TRT_TrackSegmentsFinder.cxx
index 10becab3c743e766766215b49bba7f109a825a45..594d3957065fd852c3070c9e2824e54aa9a8c06a 100644
--- a/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/src/TRT_TrackSegmentsFinder.cxx
+++ b/InnerDetector/InDetRecAlgs/TRT_TrackSegmentsFinder/src/TRT_TrackSegmentsFinder.cxx
@@ -38,6 +38,10 @@ StatusCode InDet::TRT_TrackSegmentsFinder::initialize()
   ATH_CHECK( m_caloKey.initialize(m_useCaloSeeds) );
   ATH_CHECK( m_foundSegmentsKey.initialize() );
 
+  ////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize());
+  ////////////////////////////////////////////////////////////////////////////////
+  
   // Get output print level
   //
   if (msgLvl(MSG::DEBUG)) {
@@ -61,8 +65,8 @@ StatusCode InDet::TRT_TrackSegmentsFinder::execute(const EventContext &ctx) cons
   std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> event_data_p;
   if(!m_useCaloSeeds) {
 
-    event_data_p = m_segmentsMakerTool->newEvent();
-    m_segmentsMakerTool->find    (*event_data_p);
+    event_data_p = m_segmentsMakerTool->newEvent(ctx);
+    m_segmentsMakerTool->find    (ctx, *event_data_p);
 
     // Loop through all segments and reconsrtucted segments collection preparation
     //
@@ -97,9 +101,20 @@ StatusCode InDet::TRT_TrackSegmentsFinder::execute(const EventContext &ctx) cons
         std::unique_ptr<const Trk::TrackParameters>
            par(PS.createTrackParameters(0.,0.,atan2(y,x), atan2(1.,z/sqrt(x*x+y*y)),0.,0));
 
+        // Get AtlasFieldCache
+        MagField::AtlasFieldCache fieldCache;
+
+        SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+        const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+        if (fieldCondObj == nullptr) {
+            ATH_MSG_ERROR("InDet::TRT_TrackExtensionTool_xk::findSegment: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+            return StatusCode::FAILURE;
+        }
+        fieldCondObj->getInitializedCache (fieldCache);
+  
 	// TRT detector elements road builder
 	//
-	m_roadtool->detElementsRoad(*par,Trk::alongMomentum,DE);
+	m_roadtool->detElementsRoad(ctx, fieldCache, *par, Trk::alongMomentum, DE);
         }
 	if(int(DE.size()) < m_minNumberDCs) continue;
 
@@ -109,8 +124,8 @@ StatusCode InDet::TRT_TrackSegmentsFinder::execute(const EventContext &ctx) cons
            vTR.push_back(d->identifyHash());
         }
 
-	event_data_p = m_segmentsMakerTool->newRegion(vTR);
-	m_segmentsMakerTool->find(*event_data_p);
+	event_data_p = m_segmentsMakerTool->newRegion(ctx, vTR);
+	m_segmentsMakerTool->find(ctx, *event_data_p);
 
 	// Loop through all segments and reconsrtucted segments collection preparation
 	//
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/CMakeLists.txt b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/CMakeLists.txt
index 6a6e664b9796bd9668f62eb43f8feac475799e87..612e32801cf41ada5a897a3c0082a4725201699b 100644
--- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/CMakeLists.txt
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/CMakeLists.txt
@@ -26,12 +26,13 @@ atlas_depends_on_subdirs( PUBLIC
                           Tracking/TrkEvent/TrkMaterialOnTrack
                           Tracking/TrkEvent/TrkPrepRawData
                           Tracking/TrkEvent/TrkRIO_OnTrack
-                          Tracking/TrkEvent/TrkSpacePoint )
+                          Tracking/TrkEvent/TrkSpacePoint
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions )
 
 # Component(s) in the package:
 atlas_add_library( SiSPSeededTrackFinderData
                    src/*.cxx
                    PUBLIC_HEADERS SiSPSeededTrackFinderData
-                   LINK_LIBRARIES InDetPrepRawData InDetReadoutGeometry MagFieldInterfaces TrkEventPrimitives TrkExInterfaces TrkGeometry TrkPatternParameters TrkTrack TrkToolInterfaces TrkEventUtils
-                   PRIVATE_LINK_LIBRARIES GaudiKernel InDetRIO_OnTrack SiSpacePointsSeed TrkSurfaces TrkMaterialOnTrack TrkPrepRawData TrkRIO_OnTrack TrkSpacePoint )
-
+                   LINK_LIBRARIES InDetPrepRawData InDetReadoutGeometry MagFieldInterfaces TrkEventPrimitives TrkExInterfaces TrkGeometry TrkPatternParameters TrkTrack TrkToolInterfaces TrkEventUtils MagFieldElements MagFieldConditions
+                   PRIVATE_LINK_LIBRARIES GaudiKernel InDetRIO_OnTrack SiSpacePointsSeed TrkSurfaces TrkMaterialOnTrack TrkPrepRawData TrkRIO_OnTrack TrkSpacePoint)
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiCombinatorialTrackFinderData_xk.h b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiCombinatorialTrackFinderData_xk.h
index 93a933c64e1b3adae6d8d59729ffe1bd483e513d..be7888a8e7903390d39fefebcc1deeb328b7aec8 100644
--- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiCombinatorialTrackFinderData_xk.h
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiCombinatorialTrackFinderData_xk.h
@@ -55,6 +55,12 @@ namespace InDet {
                   const IInDetConditionsTool* sctCondTool,
                   const Trk::MagneticFieldProperties* fieldProp);
 
+      
+    /**
+     * Set magnetif field cache
+     */
+    void setFieldCondObj(const  AtlasFieldCacheCondObj* fieldCondObj);
+      
     /**
      * Set cached pointer to Pixel cluster collection in StoreGate
      */
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTools_xk.h b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTools_xk.h
index 954a9c0ca9ea0f873aabebf4b2394cb3407c1a09..206bb38cb4ee4d1a954904d30a1971d8045de851 100644
--- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTools_xk.h
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTools_xk.h
@@ -17,6 +17,7 @@
 
 #include "InDetConditionsSummaryService/IInDetConditionsTool.h"
 #include "MagFieldInterfaces/IMagFieldSvc.h"
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
 #include "TrkExInterfaces/IPatternParametersPropagator.h"
 #include "TrkGeometry/MagneticFieldProperties.h"
 #include "TrkToolInterfaces/IPatternParametersUpdator.h"
@@ -44,9 +45,10 @@ namespace InDet{
       
       const Trk::MagneticFieldProperties& fieldTool  () const {return *m_fieldtool  ;}
 
-      const Trk::IPatternParametersPropagator*  propTool   () const {return m_proptool   ;}
-      const Trk::IPatternParametersUpdator*     updatorTool() const {return m_updatortool;}
-      const MagField::IMagFieldSvc*             magfield   () const {return m_fieldService;}  
+      const Trk::IPatternParametersPropagator*  propTool      () const {return m_proptool   ;}
+      const Trk::IPatternParametersUpdator*     updatorTool   () const {return m_updatortool;}
+      const MagField::IMagFieldSvc*             magfield      () const {return m_fieldService;}  
+      const AtlasFieldCacheCondObj*             fieldCondObj  () const {return m_fieldCondObj;}
 
       const Trk::IRIO_OnTrackCreator*           rioTool    () const {return m_riotool    ;}
       const IInDetConditionsTool*               pixcond    () const {return m_pixcond    ;}
@@ -72,7 +74,9 @@ namespace InDet{
 	 const Trk::IRIO_OnTrackCreator*          , 
 	 MagField::IMagFieldSvc* 
 	 );  
-      
+
+      void setFieldCondObj(const AtlasFieldCacheCondObj* fieldCondObj);
+        
       void setPRDtoTrackMap(const Trk::PRDtoTrackMap* prd_to_track_map) {
         m_prdToTrackMap = prd_to_track_map;
         if (!m_prdToTrackMap) m_useassoTool=false;
@@ -96,7 +100,10 @@ namespace InDet{
       ///////////////////////////////////////////////////////////////////
 
       const Trk::MagneticFieldProperties* m_fieldtool; // Magnetic field properties
-      MagField::IMagFieldSvc*        m_fieldService;  // Magnetic field service 
+      MagField::IMagFieldSvc*        m_fieldService;  // Magnetic field service
+      const AtlasFieldCacheCondObj*  m_fieldCondObj;  // Magnetic field conditions object to access cache
+
+
       const Trk::IPatternParametersPropagator* m_proptool; // Propagator tool
       const Trk::IPatternParametersUpdator* m_updatortool; // Updator    tool
       const Trk::IRIO_OnTrackCreator* m_riotool    ;  // RIOonTrack creator
@@ -166,6 +173,11 @@ namespace InDet{
       m_fieldService= MS;   
     }
 
+  inline void SiTools_xk::setFieldCondObj(const AtlasFieldCacheCondObj* fieldCondObj) 
+    {
+      m_fieldCondObj   = fieldCondObj;
+    }
+    
   inline void SiTools_xk::setTools
     (const Trk::MagneticFieldProperties* MF)
     {
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTrajectoryElement_xk.h b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTrajectoryElement_xk.h
index 9892c82fefb99937fee5e10bbdf851a418744b3c..962ac7205d58baa863dd77c7cd158efae3cdc1ea 100644
--- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTrajectoryElement_xk.h
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTrajectoryElement_xk.h
@@ -25,6 +25,8 @@
 #include "TrkPatternParameters/NoiseOnSurface.h"
 #include "TrkTrack/TrackStateOnSurface.h"
 #include "TrkEventUtils/PRDtoTrackMap.h"
+// MagField cache
+#include "MagFieldElements/AtlasFieldCache.h"
 
 #include <any>
 
@@ -412,6 +414,7 @@ namespace InDet{
       Trk::NoiseOnSurface                         m_noise       ; 
       const InDet::SiTools_xk*                    m_tools       ; 
       const MagField::IMagFieldSvc*               m_fieldService;
+      MagField::AtlasFieldCache                   m_fieldCache;
       const Trk::IPatternParametersUpdator*       m_updatorTool ;
       const Trk::IPatternParametersPropagator*    m_proptool    ;
       const Trk::IRIO_OnTrackCreator*             m_riotool     ;
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiCombinatorialTrackFinderData_xk.cxx b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiCombinatorialTrackFinderData_xk.cxx
index 6467d253cb67c98b9215fda2933068027648d9b7..24da1e53d305678a71a6a23f0f53504d5f4be0b1 100644
--- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiCombinatorialTrackFinderData_xk.cxx
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiCombinatorialTrackFinderData_xk.cxx
@@ -38,6 +38,11 @@ namespace InDet {
     m_initialized = true;
   }
 
+  void SiCombinatorialTrackFinderData_xk::setFieldCondObj(const  AtlasFieldCacheCondObj* fieldCondObj) 
+  {
+    m_tools.setFieldCondObj(fieldCondObj);
+  }
+    
   void SiCombinatorialTrackFinderData_xk::setPixContainer(const InDet::PixelClusterContainer* pixcont) {
     m_pixcontainer = pixcont;
   }
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiTrajectoryElement_xk.cxx b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiTrajectoryElement_xk.cxx
index f439baf14f075545ed186252b827cdc06efeb28a..d3fd125778c13da5928f7b10b097e040a7748d94 100644
--- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiTrajectoryElement_xk.cxx
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiTrajectoryElement_xk.cxx
@@ -14,6 +14,8 @@
 #include "InDetRIO_OnTrack/PixelClusterOnTrack.h"
 #include "InDetRIO_OnTrack/SCT_ClusterOnTrack.h"
 
+#include "StoreGate/ReadCondHandle.h"
+
 #include <stdexcept>
 #include <math.h>//for sincos function
 
@@ -30,7 +32,8 @@ void InDet::SiTrajectoryElement_xk::setTools(const InDet::SiTools_xk* t)
   m_updatorTool  = m_tools->updatorTool ();
   m_proptool     = m_tools->propTool    ();
   m_riotool      = m_tools->rioTool     ();
-} 
+  m_tools->fieldCondObj()->getInitializedCache (m_fieldCache);
+}
 
 void InDet::SiTrajectoryElement_xk::setParameters()
 {
@@ -1145,10 +1148,15 @@ bool  InDet::SiTrajectoryElement_xk::rungeKuttaToPlane
   else  if( (Pa*S0) > .3) {
     S > 0. ? S = .3/Pa : S=-.3/Pa;
   }
-  
-  bool   ste   = false; 
 
-  double f0[3],f[3]; m_fieldService->getFieldZR(R,f0); 
+  bool   ste   = false;
+
+  double f0[3],f[3];
+
+  // MT version uses cache, temporarily keep old version
+  if (m_fieldCache.useNewBfieldCache()) m_fieldCache.getFieldZR    (R,f0);
+  else                                  m_fieldService->getFieldZR (R,f0);
+
 
   while(true) {
 
@@ -1172,7 +1180,13 @@ bool  InDet::SiTrajectoryElement_xk::rungeKuttaToPlane
     //
     if(!Helix) {
       double gP[3]={R[0]+A1*S4, R[1]+B1*S4, R[2]+C1*S4};
-      m_fieldService->getFieldZR(gP,f);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+      // MT version uses cache, temporarily keep old version
+      if (m_fieldCache.useNewBfieldCache()) m_fieldCache.getFieldZR  (gP,f);
+      else                                  m_fieldService->getFieldZR(gP,f);
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
     }
     else       {f[0]=f0[0]; f[1]=f0[1]; f[2]=f0[2];}
 
@@ -1190,8 +1204,14 @@ bool  InDet::SiTrajectoryElement_xk::rungeKuttaToPlane
     // Last point
     //
     if(!Helix) {
-      double gP[3]={R[0]+S*A4, R[1]+S*B4, R[2]+S*C4};    
-      m_fieldService->getFieldZR(gP,f);
+      double gP[3]={R[0]+S*A4, R[1]+S*B4, R[2]+S*C4};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+      // MT version uses cache, temporarily keep old version
+      if (m_fieldCache.useNewBfieldCache()) m_fieldCache.getFieldZR    (gP,f);
+      else                                  m_fieldService->getFieldZR (gP,f);
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
     }
     else       {f[0]=f0[0]; f[1]=f0[1]; f[2]=f0[2];} 
     
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiCombinatorialTrackFinder.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiCombinatorialTrackFinder.h
index d889591b9b446762b256bfecd11736ea7125890f..211b7c0a4e166a8c2e002672ac90a101a1e5a9f9 100644
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiCombinatorialTrackFinder.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiCombinatorialTrackFinder.h
@@ -17,6 +17,7 @@
 #include "TrkTrack/Track.h"
 
 #include "GaudiKernel/AlgTool.h"
+#include "GaudiKernel/EventContext.h"
 
 #include <list>
 #include <map>
@@ -89,9 +90,9 @@ namespace InDet {
 	 std::multimap<const Trk::PrepRawData*, const Trk::Track*>&,
 	 bool) const =0;
 
-      virtual void newEvent(SiCombinatorialTrackFinderData_xk& data) const =0;
+      virtual void newEvent(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data) const =0;
 
-      virtual void newEvent(SiCombinatorialTrackFinderData_xk& data,
+      virtual void newEvent(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data,
                             Trk::TrackInfo, const TrackQualityCuts&) const =0;
 
       virtual void endEvent(SiCombinatorialTrackFinderData_xk& data) const =0;
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiDetElementsRoadMaker.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiDetElementsRoadMaker.h
index 96d2b5075bdca722fa52ce68359ba03af8b653c7..2b5984c2feab4415be87f3b8db12ad3ba3631aa1 100644
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiDetElementsRoadMaker.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiDetElementsRoadMaker.h
@@ -17,6 +17,8 @@
 #include "TrkSpacePoint/SpacePoint.h"
 
 #include "GaudiKernel/AlgTool.h"
+#include "GaudiKernel/EventContext.h"
+#include "MagFieldElements/AtlasFieldCache.h"
 
 #include <list>
 
@@ -57,8 +59,10 @@ namespace InDet {
          bool test) const=0;
 
       virtual void detElementsRoad
-	(const Trk::TrackParameters&,Trk::PropDirection,
-	 std::list<const InDetDD::SiDetectorElement*>&) const=0;
+      (const EventContext& ctx,
+       MagField::AtlasFieldCache& fieldCache,
+       const Trk::TrackParameters&,Trk::PropDirection,
+       std::list<const InDetDD::SiDetectorElement*>&) const=0;
       //@} 
 
       ///////////////////////////////////////////////////////////////////
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiSpacePointsSeedMaker.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiSpacePointsSeedMaker.h
index 4df7fa4cf16661895c84486dd7a4f5dae266c7cd..e51088b9ea70576153422552b04365fde8c5bb68 100644
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiSpacePointsSeedMaker.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiSpacePointsSeedMaker.h
@@ -20,6 +20,7 @@
 #include "IRegionSelector/IRoiDescriptor.h"
 #include "SiSpacePointsSeed/SiSpacePointsSeed.h"
 #include "VxVertex/Vertex.h"
+#include "GaudiKernel/EventContext.h"
 
 #include <set>
 
@@ -87,10 +88,10 @@ namespace InDet {
       /// @name Methods to initialize tool for new event or region
       ///////////////////////////////////////////////////////////////////
       //@{
-      virtual void newEvent(SiSpacePointsSeedMakerEventData& data, int iteration=-1) const =0;
-      virtual void newRegion(SiSpacePointsSeedMakerEventData& data,
+      virtual void newEvent(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data, int iteration=-1) const =0;
+      virtual void newRegion(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
                              const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const =0;
-      virtual void newRegion(SiSpacePointsSeedMakerEventData& data,
+      virtual void newRegion(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
                              const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
                              const IRoiDescriptor& iRD) const =0;
       //@}
@@ -104,17 +105,17 @@ namespace InDet {
                            const std::list<Trk::Vertex>& lv) const =0;
 
       /// with three space points with or without vertex constraint
-      virtual void find3Sp(SiSpacePointsSeedMakerEventData& data,
+      virtual void find3Sp(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
                            const std::list<Trk::Vertex>& lv) const =0;
 
       /// with three space points with or without vertex constraint
       /// with information about min and max Z of the  vertex
-      virtual void find3Sp(SiSpacePointsSeedMakerEventData& data,
+      virtual void find3Sp(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
                            const std::list<Trk::Vertex>& lv, const double* zVertex) const =0;
 
       /// with variable number space points with or without vertex constraint
       /// Variable means (2,3,4,....) any number space points
-      virtual void findVSp(SiSpacePointsSeedMakerEventData& data,
+      virtual void findVSp(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
                            const std::list<Trk::Vertex>& lv) const =0;
       //@}
       
@@ -123,7 +124,7 @@ namespace InDet {
       /// produced accordingly methods find
       ///////////////////////////////////////////////////////////////////
       //@{
-      virtual const SiSpacePointsSeed* next(SiSpacePointsSeedMakerEventData& data) const =0;
+      virtual const SiSpacePointsSeed* next(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data) const =0;
       //@}
       
       ///////////////////////////////////////////////////////////////////
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiTrackMaker.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiTrackMaker.h
index 6f135c6a2e781218e75ea7ecc47a14db865389fa..81ca75a8f0cf1f86d613e60d4a146ef55abba1db 100644
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiTrackMaker.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiTrackMaker.h
@@ -18,6 +18,7 @@
 #include "TrkTrack/Track.h"
 
 #include "GaudiKernel/AlgTool.h"
+#include "GaudiKernel/EventContext.h"
 
 #include <list>
 
@@ -63,15 +64,14 @@ namespace InDet {
       ///////////////////////////////////////////////////////////////////
       //@{
       virtual std::list<Trk::Track*>
-	getTracks(SiTrackMakerEventData_xk& data, const std::list<const Trk::SpacePoint*>&) const =0;
-
+        getTracks(const EventContext& ctx, SiTrackMakerEventData_xk& data, const std::list<const Trk::SpacePoint*>&) const =0;
       virtual std::list<Trk::Track*>
-	getTracks(SiTrackMakerEventData_xk& data, const Trk::TrackParameters&, const std::list<Amg::Vector3D>&) const =0;
-      
-      virtual void newEvent(SiTrackMakerEventData_xk& data, bool, bool) const =0;
+	getTracks(const EventContext& ctx, SiTrackMakerEventData_xk& data, const Trk::TrackParameters&, const std::list<Amg::Vector3D>&) const =0;
+
+      virtual void newEvent(const EventContext& ctx, SiTrackMakerEventData_xk& data, bool, bool) const =0;
+
+      virtual void newTrigEvent(const EventContext& ctx, SiTrackMakerEventData_xk& data, bool, bool) const =0;
 
-      virtual void newTrigEvent(SiTrackMakerEventData_xk& data, bool, bool) const =0;
-      
       virtual void endEvent(SiTrackMakerEventData_xk& data) const =0;
       //@}
 
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiZvertexMaker.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiZvertexMaker.h
index 258de747392cebc75d8c1bc4eb7002e0c542fb89..628ace7d9c028d44c4d8cdd7d682d5d451ca9b3e 100644
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiZvertexMaker.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiZvertexMaker.h
@@ -18,6 +18,7 @@
 #include "Identifier/IdentifierHash.h"
 #include "IRegionSelector/IRoiDescriptor.h"
 #include "VxVertex/Vertex.h"
+#include "GaudiKernel/EventContext.h"
 
 class MsgStream;
 
@@ -66,13 +67,13 @@ namespace InDet{
       /// @name Methods to initialize tool for new event or region and return vertex list
       ///////////////////////////////////////////////////////////////////
       //@{
-      virtual std::list<Trk::Vertex> newEvent(SiSpacePointsSeedMakerEventData& data) const =0;
+      virtual std::list<Trk::Vertex> newEvent(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data) const =0;
 
-      virtual std::list<Trk::Vertex> newRegion(SiSpacePointsSeedMakerEventData& data,
+      virtual std::list<Trk::Vertex> newRegion(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
                                                const std::vector<IdentifierHash>&,
                                                const std::vector<IdentifierHash>&) const =0;
 
-      virtual std::list<Trk::Vertex> newRegion(SiSpacePointsSeedMakerEventData& data,
+      virtual std::list<Trk::Vertex> newRegion(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
                                                const std::vector<IdentifierHash>&,
                                                const std::vector<IdentifierHash>&,
                                                const IRoiDescriptor&) const =0;
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_DetElementsRoadMaker.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_DetElementsRoadMaker.h
index 84f9cdeb39aee73b908ff54aeac482fe13d1861f..df3c74e18ff8e564ed141565f9d52591176daa98 100755
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_DetElementsRoadMaker.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_DetElementsRoadMaker.h
@@ -18,11 +18,16 @@
 
 #include <list>
 #include "GaudiKernel/AlgTool.h"
+#include "GaudiKernel/EventContext.h"
 #include "TrkEventPrimitives/PropDirection.h"
 #include "TrkParameters/TrackParameters.h"
 
 class MsgStream;
 
+namespace MagField {
+    class AtlasFieldCache;
+}
+
 namespace InDetDD {
   class TRT_BaseElement;
 }
@@ -52,15 +57,19 @@ namespace InDet {
       ///////////////////////////////////////////////////////////////////
       // Main methods for road builder
       ///////////////////////////////////////////////////////////////////
-      
+
       virtual void detElementsRoad
-	(const Trk::TrackParameters&,Trk::PropDirection, 
-	 std::vector<const InDetDD::TRT_BaseElement*>&) const =0;
+	(const EventContext& ctx,
+         MagField::AtlasFieldCache& fieldCache,
+         const Trk::TrackParameters&,Trk::PropDirection,
+	 std::vector<const InDetDD::TRT_BaseElement*>&) const = 0;
 
       virtual void detElementsRoad
-	(const Trk::TrackParameters&,Trk::PropDirection, 
-	 std::vector<std::pair<const InDetDD::TRT_BaseElement*,const Trk::TrackParameters*> >&) const=0;
-      
+	(const EventContext& ctx,
+         MagField::AtlasFieldCache& fieldCache,
+         const Trk::TrackParameters&,Trk::PropDirection,
+	 std::vector<std::pair<const InDetDD::TRT_BaseElement*,const Trk::TrackParameters*> >&) const =0;
+
       ///////////////////////////////////////////////////////////////////
       // Print internal tool parameters and status
       ///////////////////////////////////////////////////////////////////
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SeededSpacePointFinder.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SeededSpacePointFinder.h
index 9e0ad4d788f5c684cdc715caa05af880d5a348fc..6addc61bc1dce7a034ec21a10758cb8fcfe16365 100755
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SeededSpacePointFinder.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SeededSpacePointFinder.h
@@ -75,7 +75,8 @@ namespace InDet {
       ///////////////////////////////////////////////////////////////////
 
       virtual std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> >
-      find2Sp (const Trk::TrackParameters& tP,
+      find2Sp (const EventContext& ctx,
+               const Trk::TrackParameters& tP,
                ITRT_SeededSpacePointFinder::IEventData &event_data) const=0;
 
       ///////////////////////////////////////////////////////////////////
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SeededTrackFinder.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SeededTrackFinder.h
index e18ba042c18b88f8507f3fbab25b793d9dc68a07..be84aa688fcc1e06d8bda34d12e0698d59862d6a 100755
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SeededTrackFinder.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SeededTrackFinder.h
@@ -19,6 +19,7 @@
 #include "GaudiKernel/AlgTool.h"
 #include "TrkTrack/Track.h"
 #include "TrkSegment/TrackSegment.h"
+#include "GaudiKernel/EventContext.h"
 
 class MsgStream;
 
@@ -56,13 +57,14 @@ namespace InDet {
       ///////////////////////////////////////////////////////////////////
 
       virtual std::list<Trk::Track*> getTrack
-         (InDet::ITRT_SeededTrackFinder::IEventData &,
+         (const EventContext& ctx,
+          InDet::ITRT_SeededTrackFinder::IEventData &,
           const Trk::TrackSegment&) const = 0;
       virtual std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData>
-      newEvent(SiCombinatorialTrackFinderData_xk& combinatorialData) const =0;
+      newEvent(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& combinatorialData) const =0;
 
       virtual std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData>
-      newRegion(SiCombinatorialTrackFinderData_xk& combinatorialData,
+      newRegion(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& combinatorialData,
                 const std::vector<IdentifierHash>&,const std::vector<IdentifierHash>&) const =0;
       virtual void endEvent(InDet::ITRT_SeededTrackFinder::IEventData &event_data) const =0;
 
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SegmentToTrackTool.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SegmentToTrackTool.h
index 4fca277596718c4cad4a0610d69b8aa76f79acee..a5ccca3dc51490ae10342252b93c37b296795425 100755
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SegmentToTrackTool.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_SegmentToTrackTool.h
@@ -25,6 +25,7 @@
 #include "TrkSegment/TrackSegment.h"
 #include "TrkTrack/TrackCollection.h"
 #include "TrkEventPrimitives/TrackScore.h"
+#include "GaudiKernel/EventContext.h"
 #include <utility>
 
 class MsgStream;
@@ -55,7 +56,7 @@ namespace InDet {
        std::array<int,kNCounter>  m_counter {};
     };
 
-    virtual Trk::Track* segToTrack(const Trk::TrackSegment&) const = 0;
+    virtual Trk::Track* segToTrack(const EventContext&, const Trk::TrackSegment&) const = 0;
 
     /** Check if the TRT segment has already been assigned a Si extension  */
     virtual bool segIsUsed(const Trk::TrackSegment&,
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_TrackExtensionTool.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_TrackExtensionTool.h
index 21b21feaa5c1ac2cf361107eb9a9f02a1ad92ac0..af86dd584637c4971c917b693689dc63439b57a1 100755
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_TrackExtensionTool.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_TrackExtensionTool.h
@@ -17,6 +17,7 @@
 
 #include <list>
 #include "GaudiKernel/AlgTool.h"
+#include "GaudiKernel/EventContext.h"
 #include "TrkTrack/Track.h"
 #include "TrkMeasurementBase/MeasurementBase.h"
 #include "TrkSegment/TrackSegment.h"
@@ -58,15 +59,18 @@ namespace InDet {
       ///////////////////////////////////////////////////////////////////
 
       virtual std::vector<const Trk::MeasurementBase*>& extendTrack
-        (const Trk::Track&,
+        (const EventContext& ctx,
+         const Trk::Track&,
          InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const = 0;
 
       virtual std::vector<const Trk::MeasurementBase*>& extendTrack
-        (const Trk::TrackParameters&,
+        (const EventContext& ctx,
+         const Trk::TrackParameters&,
          InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const = 0;
 
       virtual Trk::Track* newTrack
-        (const Trk::Track&,
+        (const EventContext& ctx,
+         const Trk::Track&,
          InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const = 0;
 
       ///////////////////////////////////////////////////////////////////
@@ -74,14 +78,15 @@ namespace InDet {
       ///////////////////////////////////////////////////////////////////
 
       virtual Trk::TrackSegment* findSegment
-        (const Trk::TrackParameters&,
+        (const EventContext& ctx,
+         const Trk::TrackParameters&,
          InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const = 0;
 
       ///////////////////////////////////////////////////////////////////
       //  Tool initialisation  for new eevent
       ///////////////////////////////////////////////////////////////////
 
-      virtual std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> newEvent() const = 0;
+      virtual std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> newEvent(const EventContext& ctx) const = 0;
 
       ///////////////////////////////////////////////////////////////////
       // Print internal tool parameters and status
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_TrackSegmentsMaker.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_TrackSegmentsMaker.h
index b6394fc8c8986a0153034e48e67ba31e72ad349c..1a38df1ee2285696bcc54244632eaded351e7634 100755
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_TrackSegmentsMaker.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ITRT_TrackSegmentsMaker.h
@@ -30,6 +30,7 @@
 #define ITRT_TrackSegmentsMaker_H
 
 #include "GaudiKernel/AlgTool.h"
+#include "GaudiKernel/EventContext.h"
 #include "Identifier/IdentifierHash.h"
 #include "TrkSegment/TrackSegment.h"
 #include "VxVertex/Vertex.h"
@@ -65,15 +66,15 @@ namespace InDet {
       // Methods to initialize tool for new event or region
       ///////////////////////////////////////////////////////////////////
 
-      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newEvent () const =0;
-      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newRegion(const std::vector<IdentifierHash>&) const =0;
+      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newEvent (const EventContext& ctx) const =0;
+      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newRegion(const EventContext& ctx, const std::vector<IdentifierHash>&) const =0;
       virtual void endEvent (InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const =0;
 
       ///////////////////////////////////////////////////////////////////
       // Methods of seeds production without vertex constraint
       ///////////////////////////////////////////////////////////////////
 
-      virtual void find(InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const =0;
+      virtual void find(const EventContext& ctx, InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const =0;
 
       ///////////////////////////////////////////////////////////////////
       // Iterator through track segments pseudo collection produced 
diff --git a/InnerDetector/InDetRecTools/InDetTrackSummaryHelperTool/src/InDetTrackSummaryHelperTool.cxx b/InnerDetector/InDetRecTools/InDetTrackSummaryHelperTool/src/InDetTrackSummaryHelperTool.cxx
index d9ab69b5e92b2e7bcefa0fe4941caefbbc42abd5..f4f09fc00ddf922b57359b3e8b95124548065469 100755
--- a/InnerDetector/InDetRecTools/InDetTrackSummaryHelperTool/src/InDetTrackSummaryHelperTool.cxx
+++ b/InnerDetector/InDetRecTools/InDetTrackSummaryHelperTool/src/InDetTrackSummaryHelperTool.cxx
@@ -76,11 +76,11 @@ StatusCode InDet::InDetTrackSummaryHelperTool::initialize()
   }
 
   if (not m_testBLayerTool.empty() and m_testBLayerTool.retrieve().isFailure() ) {
-    ATH_MSG_ERROR("Failed to retrieve Test B Layer tool " << m_pixeldedxtool);
+    ATH_MSG_ERROR("Failed to retrieve Test B Layer tool " << m_testBLayerTool);
     ATH_MSG_ERROR("configure as 'None' to avoid its loading.");
     return StatusCode::FAILURE;
   } else {
-    if (not m_testBLayerTool.empty()) ATH_MSG_INFO("Retrieved tool " << m_pixeldedxtool);
+    if (not m_testBLayerTool.empty()) ATH_MSG_INFO("Retrieved tool " << m_testBLayerTool);
   }
 
   if (m_useTRT and not m_TRTStrawSummaryTool.empty() and m_TRTStrawSummaryTool.retrieve().isFailure()) {
diff --git a/InnerDetector/InDetRecTools/SiClusterizationTool/SiClusterizationTool/ClusterMakerTool.h b/InnerDetector/InDetRecTools/SiClusterizationTool/SiClusterizationTool/ClusterMakerTool.h
index 8e9786cf991a617c0303155ba1bd18cd09afae03..28e8514b8c07756dd5550076753ada6f61453844 100644
--- a/InnerDetector/InDetRecTools/SiClusterizationTool/SiClusterizationTool/ClusterMakerTool.h
+++ b/InnerDetector/InDetRecTools/SiClusterizationTool/SiClusterizationTool/ClusterMakerTool.h
@@ -59,8 +59,8 @@ class ClusterMakerTool : public AthAlgTool {
 public:
 
   ClusterMakerTool(const std::string &type,
-		   const std::string &name,
-		   const IInterface *parent);
+                   const std::string &name,
+                   const IInterface *parent);
   ~ClusterMakerTool() = default;
   
   static const InterfaceID& interfaceID() { return IID_ClusterMakerTool; };
@@ -91,33 +91,33 @@ public:
   //     Omegay: similar definition with columns rather than rows ]
 
   PixelCluster* pixelCluster(const Identifier& clusterID,
-			     const Amg::Vector2D& localPos,
-			     const std::vector<Identifier>& rdoList,
-			     const int lvl1a,
-			     const std::vector<int>& totList,
-			     const SiWidth& width,
-			     const InDetDD::SiDetectorElement* element, 
-			     bool ganged,
-			     int errorStrategy,
-			     const float omegax,
-			     const float omegay,
-			     bool split = false,
-                 double splitProb1 = 0.,
-                 double splitProb2 = 0.) const;
+                             const Amg::Vector2D& localPos,
+                             const std::vector<Identifier>& rdoList,
+                             const int lvl1a,
+                             const std::vector<int>& totList,
+                             const SiWidth& width,
+                             const InDetDD::SiDetectorElement* element, 
+                             bool ganged,
+                             int errorStrategy,
+                             const float omegax,
+                             const float omegay,
+                             bool split = false,
+                             double splitProb1 = 0.,
+                             double splitProb2 = 0.) const;
 
   PixelCluster* pixelCluster(const Identifier& clusterID,
-			     const Amg::Vector2D& localPos,
-			     const std::vector<Identifier>& rdoList,
-			     const int lvl1a,
-			     const std::vector<int>& totList,
-			     const SiWidth& width,
-			     const InDetDD::SiDetectorElement* element, 
-			     bool ganged,
-			     int errorStrategy,
-			     const PixelID& pixelID,
- 			     bool split = false,
-                 double splitProb1 = 0.,
-                 double splitProb2 = 0.) const;
+                             const Amg::Vector2D& localPos,
+                             const std::vector<Identifier>& rdoList,
+                             const int lvl1a,
+                             const std::vector<int>& totList,
+                             const SiWidth& width,
+                             const InDetDD::SiDetectorElement* element, 
+                             bool ganged,
+                             int errorStrategy,
+                             const PixelID& pixelID,
+                             bool split = false,
+                             double splitProb1 = 0.,
+                             double splitProb2 = 0.) const;
 
 
 
@@ -135,7 +135,7 @@ public:
   //    1: Set to a different values for one and two-strip clusters (def.)
 
   SCT_Cluster* sctCluster(const Identifier& clusterID,
-			 const Amg::Vector2D& localPos,
+                         const Amg::Vector2D& localPos,
                          const std::vector<Identifier>& rdoList,
                          const SiWidth& width,
                          const InDetDD::SiDetectorElement* element,
diff --git a/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/SiCombinatorialTrackFinderTool_xk/SiCombinatorialTrackFinder_xk.h b/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/SiCombinatorialTrackFinderTool_xk/SiCombinatorialTrackFinder_xk.h
index 4764f22fbec034efc54c9f94b8023cb41039ea7e..4ab79ae39ed958d8d5458e5fe997ac2de34edc81 100644
--- a/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/SiCombinatorialTrackFinderTool_xk/SiCombinatorialTrackFinder_xk.h
+++ b/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/SiCombinatorialTrackFinderTool_xk/SiCombinatorialTrackFinder_xk.h
@@ -30,6 +30,11 @@
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 #include <list>
 #include <map>
 #include <vector>
@@ -107,8 +112,8 @@ namespace InDet {
 	 std::multimap<const Trk::PrepRawData*, const Trk::Track*>&,
 	 bool) const override;
    
-      virtual void newEvent(SiCombinatorialTrackFinderData_xk& data) const override;
-      virtual void newEvent(SiCombinatorialTrackFinderData_xk& data,
+      virtual void newEvent(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data) const override;
+      virtual void newEvent(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data,
                             Trk::TrackInfo, const TrackQualityCuts&) const override;
 
       virtual void endEvent(SiCombinatorialTrackFinderData_xk& data) const override;
@@ -156,6 +161,7 @@ namespace InDet {
       // For P->T converter of SCT_Clusters
       SG::ReadCondHandleKey<InDetDD::SiDetectorElementCollection> m_SCTDetEleCollKey{this, "SCTDetEleCollKey",
           "SCT_DetectorElementCollection", "Key of SiDetectorElementCollection for SCT"};
+      SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
       //@}
 
       /// @name Properties
@@ -202,7 +208,7 @@ namespace InDet {
       MsgStream& dumpconditions(MsgStream& out) const;
       MsgStream& dumpevent(SiCombinatorialTrackFinderData_xk& data, MsgStream& out) const;
 
-      void initializeCombinatorialData(SiCombinatorialTrackFinderData_xk& data) const;
+      void initializeCombinatorialData(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data) const;
 
     };
 
diff --git a/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/src/SiCombinatorialTrackFinder_xk.cxx b/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/src/SiCombinatorialTrackFinder_xk.cxx
index a9e6c23e469eb3d5b838014508e194baab24221a..52d1a5bfb02f291623762a36f4345418b3923fc9 100644
--- a/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/src/SiCombinatorialTrackFinder_xk.cxx
+++ b/InnerDetector/InDetRecTools/SiCombinatorialTrackFinderTool_xk/src/SiCombinatorialTrackFinder_xk.cxx
@@ -26,6 +26,7 @@
 #include <iomanip>
 #include <iostream>
 #include <utility>
+#include <stdexcept>
 
 ///////////////////////////////////////////////////////////////////
 // Constructor
@@ -116,6 +117,10 @@ StatusCode InDet::SiCombinatorialTrackFinder_xk::initialize ATLAS_NOT_THREAD_SAF
     ATH_CHECK( m_SCTDetEleCollKey.initialize() );
   }
 
+  // initialize conditions object key for field cache
+  //
+  ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+  
   return StatusCode::SUCCESS;
 }
 
@@ -134,7 +139,7 @@ StatusCode InDet::SiCombinatorialTrackFinder_xk::finalize()
 
 MsgStream&  InDet::SiCombinatorialTrackFinder_xk::dump(SiCombinatorialTrackFinderData_xk& data, MsgStream& out) const
 {
-  if (not data.isInitialized()) initializeCombinatorialData(data);
+  if (not data.isInitialized()) initializeCombinatorialData(Gaudi::Hive::currentContext(), data);
 
   out<<std::endl;
   if (data.nprint()) return dumpevent(data, out);
@@ -250,9 +255,9 @@ MsgStream& InDet::SiCombinatorialTrackFinder_xk::dumpevent(SiCombinatorialTrackF
 // Initiate track finding tool 
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiCombinatorialTrackFinder_xk::newEvent(SiCombinatorialTrackFinderData_xk& data) const
+void InDet::SiCombinatorialTrackFinder_xk::newEvent(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data) const
 {
-  if (not data.isInitialized()) initializeCombinatorialData(data);
+  if (not data.isInitialized()) initializeCombinatorialData(ctx, data);
 
   // Erase statistic information
   //
@@ -266,6 +271,16 @@ void InDet::SiCombinatorialTrackFinder_xk::newEvent(SiCombinatorialTrackFinderDa
   //
   data.trackinfo().setPatternRecognitionInfo(Trk::TrackInfo::SiSPSeededFinder);
   data.cosmicTrack() = 0;
+
+  // Add conditions object to SiCombinatorialTrackFinderData to be able to access the field cache for each new event
+  // Get conditions object for field cache 
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+      std::string msg = "InDet::SiCombinatorialTrackFinder_xk::newEvent: Failed to retrieve AtlasFieldCacheCondObj with key " + m_fieldCondObjInputKey.key();
+      throw(std::runtime_error(msg));
+  }
+  data.setFieldCondObj(fieldCondObj);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -273,11 +288,11 @@ void InDet::SiCombinatorialTrackFinder_xk::newEvent(SiCombinatorialTrackFinderDa
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiCombinatorialTrackFinder_xk::newEvent
-(SiCombinatorialTrackFinderData_xk& data, Trk::TrackInfo info, const TrackQualityCuts& Cuts) const
+(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data, Trk::TrackInfo info, const TrackQualityCuts& Cuts) const
 {
-  if (not data.isInitialized()) initializeCombinatorialData(data);
+  if (not data.isInitialized()) initializeCombinatorialData(ctx, data);
 
-  newEvent(data);
+  newEvent(ctx, data);
   data.trackinfo() = info;
   
   // Get track qulaity cuts information
@@ -301,7 +316,7 @@ void InDet::SiCombinatorialTrackFinder_xk::newEvent
 
 void InDet::SiCombinatorialTrackFinder_xk::endEvent(SiCombinatorialTrackFinderData_xk& data) const
 {
-  if (not data.isInitialized()) initializeCombinatorialData(data);
+  if (not data.isInitialized()) initializeCombinatorialData(Gaudi::Hive::currentContext(), data);
 
   // Print event information 
   //
@@ -323,7 +338,7 @@ const std::list<Trk::Track*>&  InDet::SiCombinatorialTrackFinder_xk::getTracks
  std::list<const InDetDD::SiDetectorElement*>& DE,
  const TrackQualityCuts& Cuts) const
 {
-  if (not data.isInitialized()) initializeCombinatorialData(data);
+  if (not data.isInitialized()) initializeCombinatorialData(Gaudi::Hive::currentContext(), data);
 
   data.tools().setBremNoise(false, false);
   data.tracks().erase(data.tracks().begin(), data.tracks().end());
@@ -368,7 +383,7 @@ const std::list<Trk::Track*>& InDet::SiCombinatorialTrackFinder_xk::getTracks
  std::list<const InDetDD::SiDetectorElement*>& DE,
  std::multimap<const Trk::PrepRawData*, const Trk::Track*>& PT) const
 {
-  if (not data.isInitialized()) initializeCombinatorialData(data);
+  if (not data.isInitialized()) initializeCombinatorialData(Gaudi::Hive::currentContext(), data);
 
   data.tools().setBremNoise(false, false);
   data.tracks().erase(data.tracks().begin(), data.tracks().end());
@@ -414,7 +429,7 @@ const std::list<Trk::Track*>&  InDet::SiCombinatorialTrackFinder_xk::getTracksWi
  std::multimap<const Trk::PrepRawData*, const Trk::Track*>& PT,
  bool isCaloCompatible) const
 {
-  if (not data.isInitialized()) initializeCombinatorialData(data);
+  if (not data.isInitialized()) initializeCombinatorialData(Gaudi::Hive::currentContext(), data);
 
   // Old information
   //
@@ -497,7 +512,7 @@ bool InDet::SiCombinatorialTrackFinder_xk::findTrack
  std::list<const InDetDD::SiDetectorElement*>& DE,
  std::multimap<const Trk::PrepRawData*,const Trk::Track*>& PT) const
 {
-  if (not data.isInitialized()) initializeCombinatorialData(data);
+  if (not data.isInitialized()) initializeCombinatorialData(Gaudi::Hive::currentContext(), data);
 
   // List detector element links preparation
   //
@@ -770,7 +785,19 @@ void  InDet::SiCombinatorialTrackFinder_xk::getTrackQualityCuts
   data.trajectory().setParameters();
 }
 
-void InDet::SiCombinatorialTrackFinder_xk::initializeCombinatorialData(SiCombinatorialTrackFinderData_xk& data) const {
+void InDet::SiCombinatorialTrackFinder_xk::initializeCombinatorialData(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data) const {
+
+  // Add conditions object to SiCombinatorialTrackFinderData to be able to access the field cache for each new event
+  // Get conditions object for field cache 
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+      std::string msg = "InDet::SiCombinatorialTrackFinder_xk::initializeCombinatorialData: Failed to retrieve AtlasFieldCacheCondObj with key " + m_fieldCondObjInputKey.key();
+      throw(std::runtime_error(msg));
+  }
+  data.setFieldCondObj(fieldCondObj);
+
+  // Must have set fieldCondObj BEFORE calling setTools because fieldCondObj is used there
   data.setTools(&*m_proptool,
                 &*m_updatortool,
                 &*m_riocreator,
@@ -778,4 +805,5 @@ void InDet::SiCombinatorialTrackFinder_xk::initializeCombinatorialData(SiCombina
                 (m_usePIX ? &*m_pixelCondSummaryTool : nullptr),
                 (m_useSCT ? &*m_sctCondSummaryTool : nullptr),
                 &m_fieldprop);
+  
 }
diff --git a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/CMakeLists.txt b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/CMakeLists.txt
index fb750bcdc1a23e549a45fb66423d5c8be9f56e9d..5364d8c1ce0ef3c3392e125a9f7207c8f9b6619f 100644
--- a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/CMakeLists.txt
@@ -21,13 +21,15 @@ atlas_depends_on_subdirs( PUBLIC
                           Database/AthenaPOOL/AthenaPoolUtilities
                           Event/EventInfo
                           Tracking/TrkEvent/TrkPrepRawData
-                          Tracking/TrkExtrapolation/TrkExInterfaces )
+                          Tracking/TrkExtrapolation/TrkExInterfaces
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions )
 
 # Component(s) in the package:
 atlas_add_component( SiDetElementsRoadTool_xk
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps AthenaKernel GaudiKernel InDetReadoutGeometry PixelReadoutGeometry SCT_ReadoutGeometry InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkSurfaces AthenaPoolUtilities EventInfo TrkPrepRawData TrkExInterfaces )
+                     LINK_LIBRARIES AthenaBaseComps AthenaKernel GaudiKernel InDetReadoutGeometry PixelReadoutGeometry SCT_ReadoutGeometry InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkSurfaces AthenaPoolUtilities EventInfo TrkPrepRawData TrkExInterfaces MagFieldElements MagFieldConditions )
 
 # Install files from the package:
 atlas_install_headers( SiDetElementsRoadTool_xk )
diff --git a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsRoadMaker_xk.h b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsRoadMaker_xk.h
index d03bd39188bbd8dd13743f7269903d73a0433937..9c9f7b517773fb40827e98fbe215bd54d8c78718 100644
--- a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsRoadMaker_xk.h
+++ b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsRoadMaker_xk.h
@@ -30,6 +30,9 @@
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
 
+// MagField cache
+#include "MagFieldElements/AtlasFieldCache.h"
+
 #include <atomic>
 #include <iosfwd>
 #include <list>
@@ -80,7 +83,9 @@ namespace InDet{
        bool test) const override;
 
     virtual void detElementsRoad
-      (const Trk::TrackParameters&,
+      (const EventContext& ctx,
+       MagField::AtlasFieldCache& fieldCache,
+       const Trk::TrackParameters&,
        Trk::PropDirection,
        std::list<const InDetDD::SiDetectorElement*>&) const override;
     //@}
@@ -139,7 +144,8 @@ namespace InDet{
     float stepToDetElement(const InDetDD::SiDetectorElement*&,
                            Amg::Vector3D&, Amg::Vector3D&) const;
 
-    Trk::CylinderBounds getBound(const Trk::TrackParameters&) const;
+    Trk::CylinderBounds getBound(MagField::AtlasFieldCache& fieldCache,
+                                 const Trk::TrackParameters&) const;
 
     MsgStream& dumpConditions(MsgStream& out) const;
 
diff --git a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsRoadMaker_xk.cxx b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsRoadMaker_xk.cxx
index c1c415bfc585f5016bdc06931c76a7c0c52df02a..a5d4124152f670c56759a28cc101f409fbfc2598 100644
--- a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsRoadMaker_xk.cxx
+++ b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsRoadMaker_xk.cxx
@@ -19,6 +19,7 @@
 #include "PixelReadoutGeometry/PixelDetectorManager.h"
 #include "SiDetElementsRoadTool_xk/SiDetElementsComparison.h"
 #include "SiDetElementsRoadUtils_xk.h"
+#include "StoreGate/ReadCondHandle.h"
 #include "TrkPrepRawData/PrepRawData.h"
 
 #include <ostream>
@@ -446,8 +447,11 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
 // Main methods for road builder using track parameters and direction
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiDetElementsRoadMaker_xk::detElementsRoad 
-(const Trk::TrackParameters& Tp, Trk::PropDirection D,
+void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
+(const EventContext& ctx,
+ MagField::AtlasFieldCache& fieldCache,
+ const Trk::TrackParameters& Tp,
+ Trk::PropDirection D,
  std::list<const InDetDD::SiDetectorElement*>& R) const
 {
   if (!m_usePIX && !m_useSCT) return;
@@ -467,8 +471,10 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
   if (!m_fieldServiceHandle->solenoidOn()) fieldModeEnum = Trk::NoField;
   Trk::MagneticFieldProperties fieldprop(fieldModeEnum);
 
+  // Note: could also give fieldCache directly to propagator if it would be more efficient - would
+  // need to add interface RDS 2020/03
   std::list<Amg::Vector3D> G;
-  m_proptool->globalPositions(G, Tp, fieldprop,getBound(Tp), S, Trk::pion);
+  m_proptool->globalPositions(ctx, G, Tp, fieldprop,getBound(fieldCache, Tp), S, Trk::pion);
   if (G.size()<2) return;
 
   if (D > 0) {
@@ -666,7 +672,8 @@ float InDet::SiDetElementsRoadMaker_xk::stepToDetElement
 ///////////////////////////////////////////////////////////////////
 
 Trk::CylinderBounds InDet::SiDetElementsRoadMaker_xk::getBound
-(const Trk::TrackParameters& Tp) const
+(MagField::AtlasFieldCache& fieldCache,
+ const Trk::TrackParameters& Tp) const
 {
   const double cor = 1.;
 
@@ -674,7 +681,11 @@ Trk::CylinderBounds InDet::SiDetElementsRoadMaker_xk::getBound
   if (m_fieldModeEnum!=Trk::NoField && m_fieldServiceHandle->solenoidOn()) {
     const Amg::Vector3D& pos = Tp.position();
     double f[3], p[3] = {pos[Amg::x], pos[Amg::y], pos[Amg::z]};
-    m_fieldServiceHandle->getFieldZR(p, f);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (p, f);
+    else                                m_fieldServiceHandle->getFieldZR(p, f);
+
     zfield = 299.7925*f[2];
   }
 
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/CMakeLists.txt b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/CMakeLists.txt
index 8b9cce7b072535b9a6c09ca728adf0b0a70cabfd..676db91126ff7f29a3f9c9bf605cac000c962a82 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/CMakeLists.txt
@@ -19,13 +19,15 @@ atlas_depends_on_subdirs( PUBLIC
                           Tracking/TrkDetDescr/TrkSurfaces
                           Tracking/TrkEvent/TrkSpacePoint
                           PRIVATE
-                          Tracking/TrkTools/TrkToolInterfaces )
+                          Tracking/TrkTools/TrkToolInterfaces
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions)
 
 # Component(s) in the package:
 atlas_add_component( SiSpacePointsSeedTool_xk
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetReadoutGeometry InDetPrepRawData SiSpacePointsSeed SiSPSeededTrackFinderData InDetRecToolInterfaces MagFieldInterfaces TrkSurfaces TrkSpacePoint TrkToolInterfaces )
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetReadoutGeometry InDetPrepRawData SiSpacePointsSeed SiSPSeededTrackFinderData InDetRecToolInterfaces MagFieldInterfaces TrkSurfaces TrkSpacePoint TrkToolInterfaces MagFieldElements MagFieldConditions)
 
 # Install files from the package:
 atlas_install_headers( SiSpacePointsSeedTool_xk )
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h
index d21659f86ebbd3158af1ca1844dcb79cb6977437..e7fbc4cfd6498a12cb55fb75b0854c2b14f2251d 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h
@@ -26,6 +26,13 @@
 
 #include "GaudiKernel/ServiceHandle.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
 #include <iosfwd>
 #include <list>
 #include <vector>
@@ -70,10 +77,10 @@ namespace InDet {
     /// @name Methods to initialize tool for new event or region
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual void newEvent(EventData& data, int iteration) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newEvent (const EventContext& ctx, EventData& data, int iteration) const override;
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newRegion(const EventContext& ctx,SiSpacePointsSeedMakerEventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
                            const IRoiDescriptor& iRD) const override;
     //@}
@@ -87,15 +94,15 @@ namespace InDet {
     virtual void find2Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
     /// with information about min and max Z of the vertex
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
 
     /// with variable number space points with or without vertex constraint
     /// Variable means (2,3,4,....) any number space points
-    virtual void findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void findVSp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -103,7 +110,7 @@ namespace InDet {
     /// produced accordingly methods find    
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual const SiSpacePointsSeed* next(EventData& data) const override;
+    virtual const SiSpacePointsSeed* next(const EventContext& ctx, EventData& data) const override;
     //@}
       
     ///////////////////////////////////////////////////////////////////
@@ -140,6 +147,9 @@ namespace InDet {
     SG::ReadHandleKey<SpacePointOverlapCollection> m_spacepointsOverlap{this, "SpacePointsOverlapName", "OverlapSpacePoints"};
     SG::ReadHandleKey<Trk::PRDtoTrackMap> m_prdToTrackMap{this,"PRDtoTrackMap","","option PRD-to-track association"};
     SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey{this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot"};
+    // Read handle for conditions object to get the field cache
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                          "Name of the Magnetic Field conditions object key"};
     //@}
 
     /// @name Properties, which will not be changed after construction
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_BeamGas.h b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_BeamGas.h
index 60bd6f9d3a5a82810a28f1ba687427d6269f5441..93cc7e9a656b17404fb9f9ee6bfc4444802f954f 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_BeamGas.h
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_BeamGas.h
@@ -29,6 +29,11 @@
 #include <iosfwd>
 #include <list>
 #include <vector>
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 class MsgStream;
 
@@ -71,10 +76,10 @@ namespace InDet {
     /// @name Methods to initialize tool for new event or region
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual void newEvent(EventData& data, int iteration) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newEvent (const EventContext& ctx, EventData& data, int iteration) const override;
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
                            const IRoiDescriptor& iRD) const override;
     //@}
@@ -88,15 +93,15 @@ namespace InDet {
     virtual void find2Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
     /// with information about min and max Z of the vertex
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
 
     /// with variable number space points with or without vertex constraint
     /// Variable means (2,3,4,....) any number space points
-    virtual void findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void findVSp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
     //@}
       
     ///////////////////////////////////////////////////////////////////
@@ -104,7 +109,7 @@ namespace InDet {
     /// produced accordingly methods find    
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual const SiSpacePointsSeed* next(EventData& data) const override;
+    virtual const SiSpacePointsSeed* next(const EventContext& ctx, EventData& data) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -139,6 +144,11 @@ namespace InDet {
     SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey{this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot"};
     //@}
 
+    /// @name Read handle for conditions object to get the field cache
+    //@{
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                               "Name of the Magnetic Field conditions object key"};
+
     /// @name Properties, which will not be changed after construction
     //@{
     BooleanProperty m_pixel{this, "usePixel", true};
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_Cosmic.h b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_Cosmic.h
index bdd72daad207aa8b9136cc57cbf71dbee4c2b2d2..e24346080b317e878fd7812209cbd40a5e78d1e7 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_Cosmic.h
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_Cosmic.h
@@ -28,6 +28,11 @@
 #include <iosfwd>
 #include <list>
 #include <vector>
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 class MsgStream;
 
@@ -70,10 +75,10 @@ namespace InDet {
     /// @name Methods to initialize tool for new event or region
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual void newEvent(EventData& data, int iteration) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newEvent (const EventContext& ctx, EventData& data, int iteration) const override;
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
                            const IRoiDescriptor& iRD) const override;
     //@}
@@ -87,15 +92,15 @@ namespace InDet {
     virtual void find2Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
     /// with information about min and max Z of the vertex
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
 
     /// with variable number space points with or without vertex constraint
     /// Variable means (2,3,4,....) any number space points
-    virtual void findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void findVSp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -103,7 +108,7 @@ namespace InDet {
     /// produced accordingly methods find    
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual const SiSpacePointsSeed* next(EventData& data) const override;
+    virtual const SiSpacePointsSeed* next(const EventContext& ctx, EventData& data) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -135,6 +140,9 @@ namespace InDet {
     SG::ReadHandleKey<SpacePointContainer> m_spacepointsPixel{this, "SpacePointsPixelName", "PixelSpacePoints"};
     SG::ReadHandleKey<SpacePointOverlapCollection> m_spacepointsOverlap{this, "SpacePointsOverlapName", "OverlapSpacePoints"};
     SG::ReadHandleKey<Trk::PRDtoTrackMap>m_prdToTrackMap{this,"PRDtoTrackMap","","option PRD-to-track association"};
+    // Read handle for conditions object to get the field cache
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                           "Name of the Magnetic Field conditions object key"};
     //@}
 
     /// @name Properties, which will not be changed after construction
@@ -213,7 +221,7 @@ namespace InDet {
     void fillLists(EventData& data) const;
     void erase(EventData& data) const;
     void production2Sp(EventData& data) const;
-    void production3Sp(EventData& data) const;
+    void production3Sp(const EventContext& ctx, EventData& data) const;
     void production3Sp
     (EventData& data,
      std::vector<InDet::SiSpacePointForSeed*>::iterator*,
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_HeavyIon.h b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_HeavyIon.h
index f9f8caaf894a9131c8bfc74da568b3d2e10b723a..8cb3444ab4a2ce2ad4315b79c3476d75f4fde8e5 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_HeavyIon.h
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_HeavyIon.h
@@ -26,6 +26,12 @@
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 #include <iosfwd>
 #include <list>
 #include <vector>
@@ -71,10 +77,10 @@ namespace InDet {
     /// @name Methods to initialize tool for new event or region
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual void newEvent(EventData& data, int iteration) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newEvent (const EventContext& ctx, EventData& data, int iteration) const override;
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>&vSCT) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>&vSCT,
                            const IRoiDescriptor& iRD) const override;
     //@}
@@ -88,15 +94,15 @@ namespace InDet {
     virtual void find2Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
     /// with information about min and max Z of the vertex
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
 
     // with variable number space points with or without vertex constraint
     // Variable means (2,3,4,....) any number space points
-    virtual void findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void findVSp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -104,7 +110,7 @@ namespace InDet {
     /// produced accordingly methods find    
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual const SiSpacePointsSeed* next(EventData& data) const override;
+    virtual const SiSpacePointsSeed* next(const EventContext& ctx, EventData& data) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -140,6 +146,9 @@ namespace InDet {
     SG::ReadHandleKey<SpacePointContainer> m_spacepointsPixel{this, "SpacePointsPixelName", "PixelSpacePoints", "Pixel space points container"};
     SG::ReadHandleKey<SpacePointOverlapCollection> m_spacepointsOverlap{this, "SpacePointsOverlapName", "OverlapSpacePoints"};
     SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey{this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot"};
+    // Read handle for conditions object to get the field cache
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                          "Name of the Magnetic Field conditions object key"};
     //@}
 
     /// @name Properties, which will not be changed after construction
@@ -229,7 +238,7 @@ namespace InDet {
     MsgStream& dumpEvent(EventData& data, MsgStream& out) const;
 
     void buildFrameWork();
-    void buildBeamFrameWork(EventData& data) const;
+    void buildBeamFrameWork(const EventContext& ctx, EventData& data) const;
 
     SiSpacePointForSeed* newSpacePoint
     (EventData& data, const Trk::SpacePoint*const&) const;
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ITK.h b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ITK.h
index d6dbc2cbd68f31859d912955651c62e6f27efb8b..a1c6baabd221c3101eeefeebd86025f60cd24d25 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ITK.h
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ITK.h
@@ -26,6 +26,12 @@
 
 #include "GaudiKernel/ServiceHandle.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 #include <iosfwd>
 #include <list>
 #include <vector>
@@ -72,10 +78,10 @@ namespace InDet {
     /// @name Methods to initialize tool for new event or region
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual void newEvent(EventData& data, int iteration) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newEvent (const EventContext& ctx, EventData& data, int iteration) const override;
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
                            const IRoiDescriptor& iRD) const override;
     //@}
@@ -89,15 +95,15 @@ namespace InDet {
     virtual void find2Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
     /// with information about min and max Z of the vertex
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
 
     /// with variable number space points with or without vertex constraint
     /// Variable means (2,3,4,....) any number space points
-    virtual void findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void findVSp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
     //@}
       
     ///////////////////////////////////////////////////////////////////
@@ -105,7 +111,7 @@ namespace InDet {
     /// produced accordingly methods find    
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual const SiSpacePointsSeed* next(EventData& data) const override;
+    virtual const SiSpacePointsSeed* next(const EventContext& ctx, EventData& data) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -142,6 +148,8 @@ namespace InDet {
     SG::ReadHandleKey<SpacePointOverlapCollection> m_spacepointsOverlap{this, "SpacePointsOverlapName", "OverlapSpacePoints"};
     SG::ReadHandleKey<Trk::PRDtoTrackMap> m_prdToTrackMap{this,"PRDtoTrackMap","","option PRD-to-track association"};
     SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey{this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot"};
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                           "Name of the Magnetic Field conditions object key"};
     //@}
 
     /// @name Properties, which will not be changed after construction
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_LowMomentum.h b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_LowMomentum.h
index 389c59575cef7306ed273c055e9afaee4c491a66..27721ab94f4787bb5e55461c69c1b2c8ef7baf2d 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_LowMomentum.h
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_LowMomentum.h
@@ -25,6 +25,11 @@
 #include "TrkEventUtils/PRDtoTrackMap.h"
 
 #include "GaudiKernel/ServiceHandle.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 #include <list>
 #include <vector>
@@ -70,10 +75,10 @@ namespace InDet {
     /// @name Methods to initialize tool for new event or region
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual void newEvent(EventData& data, int iteration) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newEvent (const EventContext& ctx, EventData& data, int iteration) const override;
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
                            const IRoiDescriptor& iRD) const override;
     //@}
@@ -87,15 +92,15 @@ namespace InDet {
     virtual void find2Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
     /// with information about min and max Z of the vertex
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
 
     /// with variable number space points with or without vertex constraint
     /// Variable means (2,3,4,....) any number space points
-    virtual void findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void findVSp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
     //@}
       
     ///////////////////////////////////////////////////////////////////
@@ -103,7 +108,7 @@ namespace InDet {
     /// produced accordingly methods find    
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual const SiSpacePointsSeed* next(EventData& data) const override;
+    virtual const SiSpacePointsSeed* next(const EventContext& ctx, EventData& data) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -136,6 +141,9 @@ namespace InDet {
     SG::ReadHandleKey<SpacePointOverlapCollection> m_spacepointsOverlap{this, "SpacePointsOverlapName", "OverlapSpacePoints"};
     SG::ReadHandleKey<Trk::PRDtoTrackMap> m_prdToTrackMap{this,"PRDtoTrackMap","","option PRD-to-track association"};
     SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey { this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot" };
+    // Read handle for conditions object to get the field cache
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                           "Name of the Magnetic Field conditions object key"};
     //@}
 
     /// @name Properties, which will not be changed after construction
@@ -228,7 +236,7 @@ namespace InDet {
     void fillLists(EventData& data) const;
     void erase(EventData& data) const;
     void production2Sp(EventData& data) const;
-    void production3Sp(EventData& data) const;
+    void production3Sp(const EventContext& ctx, EventData& data) const;
     void production3Sp
     (EventData& data,
      std::vector<InDet::SiSpacePointForSeed*>::iterator*,
@@ -238,7 +246,7 @@ namespace InDet {
      int,int,int&,float) const;
      
     bool newVertices(EventData& data, const std::list<Trk::Vertex>&) const;
-    void findNext(EventData& data) const;
+    void findNext(const EventContext& ctx, EventData& data) const;
     bool isZCompatible(EventData& data, float&,float&,float&) const;
     void convertToBeamFrameWork(EventData& data, const Trk::SpacePoint*const&,float*) const;
     bool isUsed(const Trk::SpacePoint*, const Trk::PRDtoTrackMap &prd_to_track_map) const;
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_Trigger.h b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_Trigger.h
index 2021956750323031d1315dda8650bd207cc40b95..c423216060c036def0de868533838b8be9cd744c 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_Trigger.h
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_Trigger.h
@@ -26,6 +26,12 @@
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 #include <list>
 #include <vector>
 
@@ -69,10 +75,10 @@ namespace InDet {
     /// @name Methods to initialize tool for new event or region
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual void newEvent(EventData& data, int iteration) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newEvent (const EventContext& ctx, EventData& data, int iteration) const override;
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const override;
-    virtual void newRegion(EventData& data,
+    virtual void newRegion(const EventContext& ctx, EventData& data,
                            const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
                            const IRoiDescriptor& iRD) const override;
     //@}
@@ -86,15 +92,15 @@ namespace InDet {
     virtual void find2Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
 
     /// with three space points with or without vertex constraint
     /// with information about min and max Z of the vertex
-    virtual void find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
+    virtual void find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double* zVertex) const override;
 
     /// with variable number space points with or without vertex constraint
     /// Variable means (2,3,4,....) any number space points
-    virtual void findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const override;
+    virtual void findVSp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const override;
     //@}
       
     ///////////////////////////////////////////////////////////////////
@@ -102,7 +108,7 @@ namespace InDet {
     /// produced accordingly methods find    
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual const SiSpacePointsSeed* next(EventData& data) const override;
+    virtual const SiSpacePointsSeed* next(const EventContext& ctx, EventData& data) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -138,6 +144,9 @@ namespace InDet {
     SG::ReadHandleKey<SpacePointContainer> m_spacepointsPixel{this, "SpacePointsPixelName", "PixelSpacePoints", "Pixel space points container"};
     SG::ReadHandleKey<SpacePointOverlapCollection> m_spacepointsOverlap{this, "SpacePointsOverlapName", "OverlapSpacePoints"};
     SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey{this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot"};
+    // Read handle for conditions object to get the field cache
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                          "Name of the Magnetic Field conditions object key"};
     //@}
 
     /// @name Properties, which will not be changed after construction
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx
index 15de74b182027d6eac2af69e8dde928860b9cac9..93a1e073aee1883f41e3baa20a1a309e49d38cd3 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx
@@ -55,6 +55,10 @@ StatusCode InDet::SiSpacePointsSeedMaker_ATLxk::initialize()
   }    
   ATH_MSG_DEBUG("Retrieved " << m_fieldServiceHandle );
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
   // PRD-to-track association (optional)
   ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty()));
   
@@ -85,7 +89,7 @@ StatusCode InDet::SiSpacePointsSeedMaker_ATLxk::finalize()
 // Initialize tool for new event 
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(EventData& data, int iteration) const
+void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(const EventContext& ctx, EventData& data, int iteration) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -105,7 +109,21 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(EventData& data, int iteratio
 
     double f[3], gP[3] ={10.,10.,0.};
     if (m_fieldServiceHandle->solenoidOn()) {
-      m_fieldServiceHandle->getFieldZR(gP,f);
+
+      MagField::AtlasFieldCache    fieldCache;
+      // Get field cache object
+      SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+      const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+      if (fieldCondObj == nullptr) {
+          ATH_MSG_ERROR("SiSpacePointsSeedMaker_ATLxk: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+          return;
+      }
+      fieldCondObj->getInitializedCache (fieldCache);
+
+      //    MT version uses cache, temporarily keep old version
+      if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP,f);
+      else                                m_fieldServiceHandle->getFieldZR(gP,f);
+
       data.K = 2./(300.*f[2]);
     } else {
       data.K = 2./(300.* 5. );
@@ -136,7 +154,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(EventData& data, int iteratio
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -148,7 +166,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(EventData& data, int iteratio
   //
   if (!m_dbm && m_pixel) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsPixel) {
@@ -182,7 +200,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(EventData& data, int iteratio
   //
   if (!m_dbm && m_sct) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsSCT) {
@@ -207,7 +225,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(EventData& data, int iteratio
     //
     if (m_useOverlap && !data.checketa) {
 
-      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap};
+      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap, ctx};
       if (spacepointsOverlap.isValid()) {
   
         for (const Trk::SpacePoint* sp: *spacepointsOverlap) {
@@ -232,7 +250,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(EventData& data, int iteratio
   //
   if (m_dbm) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsPixel) {
@@ -268,7 +286,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newEvent(EventData& data, int iteratio
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
 {
   if (not data.initialized) initializeEventData(data);
@@ -289,7 +307,22 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
   double f[3], gP[3] ={10.,10.,0.};
 
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP,f);
+
+    MagField::AtlasFieldCache    fieldCache;
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+
+    if (fieldCondObj == nullptr) {
+        ATH_MSG_ERROR("SiSpacePointsSeedMaker_ATLxk: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+        return;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP,f);
+    else                                m_fieldServiceHandle->getFieldZR(gP,f);
+
     data.K = 2./(300.*f[2]);
   } else {
     data.K = 2./(300.* 5. );
@@ -318,7 +351,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
   //
   if (m_pixel && !vPixel.empty()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if ( spacepointsPixel.isValid() ) {
       SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
@@ -346,7 +379,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
   //
   if (m_sct && !vSCT.empty()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
@@ -377,7 +410,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
  const IRoiDescriptor& IRD) const
 {
@@ -385,7 +418,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newRegion
 
   if (not data.initialized) initializeEventData(data);
 
-  newRegion(data, vPixel, vSCT);
+  newRegion(ctx, data, vPixel, vSCT);
   data.trigger = true;
 
   double dzdrmin = 1./tan(2.*atan(exp(-IRD.etaMinus())));
@@ -444,7 +477,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::find2Sp(EventData& data, const std::li
 // with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -481,7 +514,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(EventData& data, const std::li
 // with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double* ZVertex) const
+void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv, const double* ZVertex) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -520,7 +553,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::find3Sp(EventData& data, const std::li
 // Variable means (2,3,4,....) any number space points
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_ATLxk::findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_ATLxk::findVSp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -1766,7 +1799,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::fillSeeds(EventData& data) const
   }
 }
 
-const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_ATLxk::next(EventData& data) const
+const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_ATLxk::next(const EventContext&, EventData& data) const
 {
   if (not data.initialized) initializeEventData(data);
 
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_BeamGas.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_BeamGas.cxx
index eb2f0c470a7f3cd636973a4d3084e373c125db40..1efb6bd8252c1a23d0ee406c09268d2cea6c3bf6 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_BeamGas.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_BeamGas.cxx
@@ -52,6 +52,10 @@ StatusCode InDet::SiSpacePointsSeedMaker_BeamGas::initialize()
   }    
   ATH_MSG_DEBUG("Retrieved " << m_fieldServiceHandle );
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
   // PRD-to-track association (optional)
   ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty()));
 
@@ -87,7 +91,7 @@ StatusCode InDet::SiSpacePointsSeedMaker_BeamGas::finalize()
 // Initialize tool for new event 
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_BeamGas::newEvent(EventData& data, int) const
+void InDet::SiSpacePointsSeedMaker_BeamGas::newEvent(const EventContext& ctx, EventData& data, int) const
 {
   if (!m_pixel && !m_sct) return;
 
@@ -99,7 +103,21 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newEvent(EventData& data, int) const
   double f[3], gP[3] ={10.,10.,0.};
 
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP,f);
+
+    MagField::AtlasFieldCache    fieldCache;
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+        ATH_MSG_ERROR("SiSpacePointsSeedMaker_BeamGas: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+        return;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //    MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP,f);
+    else                                m_fieldServiceHandle->getFieldZR(gP,f);
+
     data.K = 2./(300.*f[2]);
   } else {
     data.K = 2./(300.* 5. );
@@ -113,7 +131,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newEvent(EventData& data, int) const
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -124,7 +142,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newEvent(EventData& data, int) const
   //
   if (m_pixel) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsPixel) {
@@ -148,7 +166,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newEvent(EventData& data, int) const
   //
   if (m_sct) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsSCT) {
@@ -171,7 +189,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newEvent(EventData& data, int) const
     //
     if (m_useOverlap) {
 
-      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap};
+      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap, ctx};
       if (spacepointsOverlap.isValid()) {
 
         for (const Trk::SpacePoint* sp: *spacepointsOverlap) {
@@ -198,7 +216,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newEvent(EventData& data, int) const
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_BeamGas::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
 {
   if (!m_pixel && !m_sct) return;
@@ -211,7 +229,21 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newRegion
   double f[3], gP[3] ={10.,10.,0.};
 
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP,f);
+
+    MagField::AtlasFieldCache    fieldCache;
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+        ATH_MSG_ERROR("SiSpacePointsSeedMaker_BeamGas: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+        return;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //    MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP,f);
+    else                                m_fieldServiceHandle->getFieldZR(gP,f);
+
     data.K = 2./(300.*f[2]);
   } else {
     data.K = 2./(300.* 5. );
@@ -224,7 +256,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newRegion
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -235,7 +267,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newRegion
   //
   if (m_pixel && vPixel.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
@@ -263,7 +295,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newRegion
   //
   if (m_sct && vSCT.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
@@ -295,10 +327,10 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newRegion
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_BeamGas::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT, const IRoiDescriptor&) const
 {
-  newRegion(data, vPixel, vSCT);
+  newRegion(ctx, data, vPixel, vSCT);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -337,7 +369,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::find2Sp(EventData& data, const std::
 // with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_BeamGas::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_BeamGas::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -362,9 +394,9 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::find3Sp(EventData& data, const std::
     dump(data, msg(MSG::DEBUG));
   }
 }
-void InDet::SiSpacePointsSeedMaker_BeamGas::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
+void InDet::SiSpacePointsSeedMaker_BeamGas::find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
 {
-  find3Sp(data, lv);
+  find3Sp(ctx, data, lv);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -373,7 +405,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::find3Sp(EventData& data, const std::
 // Variable means (2,3,4,....) any number space points
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_BeamGas::findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_BeamGas::findVSp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -1088,7 +1120,7 @@ void InDet::SiSpacePointsSeedMaker_BeamGas::newOneSeed
   }
 }
 
-const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_BeamGas::next(EventData& data) const
+const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_BeamGas::next(const EventContext&, EventData& data) const
 {
   if (not data.initialized) initializeEventData(data);
 
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Cosmic.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Cosmic.cxx
index a5fc8822972a2dfa60f9e9045e3b0077f2116360..1943684a50bdaf6b24787af7c1548c88b9a404c8 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Cosmic.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Cosmic.cxx
@@ -47,6 +47,10 @@ StatusCode InDet::SiSpacePointsSeedMaker_Cosmic::initialize()
   }    
   ATH_MSG_DEBUG("Retrieved " << m_fieldServiceHandle );
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	ATH_CHECK( m_fieldCondObjInputKey.initialize() );
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
   // PRD-to-track association (optional)
   ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty()));
 
@@ -83,7 +87,7 @@ StatusCode InDet::SiSpacePointsSeedMaker_Cosmic::finalize()
 // Initialize tool for new event 
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_Cosmic::newEvent(EventData& data, int) const
+void InDet::SiSpacePointsSeedMaker_Cosmic::newEvent(const EventContext& ctx, EventData& data, int) const
 {
   if (!m_pixel && !m_sct) return;
 
@@ -98,7 +102,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newEvent(EventData& data, int) const
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -109,7 +113,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newEvent(EventData& data, int) const
   //
   if (m_pixel) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsPixel) {
@@ -134,7 +138,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newEvent(EventData& data, int) const
   //
   if (m_sct) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsSCT) {
@@ -158,7 +162,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newEvent(EventData& data, int) const
     //
     if (m_useOverlap) {
 
-      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap};
+      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap, ctx};
       if (spacepointsOverlap.isValid()) {
 	
         for (const Trk::SpacePoint* sp: *spacepointsOverlap) {
@@ -185,7 +189,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newEvent(EventData& data, int) const
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_Cosmic::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
 {
   if (not data.initialized) initializeEventData(data);
@@ -200,7 +204,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newRegion
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -211,7 +215,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newRegion
   //
   if (m_pixel && vPixel.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
@@ -240,7 +244,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newRegion
   //
   if (m_sct && vSCT.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
@@ -272,10 +276,10 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::newRegion
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_Cosmic::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT, const IRoiDescriptor&) const
 {
-  newRegion(data, vPixel, vSCT);
+  newRegion(ctx, data, vPixel, vSCT);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -319,7 +323,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::find2Sp(EventData& data, const std::l
 // with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_Cosmic::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_Cosmic::find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -338,7 +342,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::find3Sp(EventData& data, const std::l
     data.endlist = true            ;
     data.fNmin   = 0               ;
     data.zMin    = 0               ;
-    production3Sp(data);
+    production3Sp(ctx, data);
   }
 
   data.i_seed_map  = data.l_seeds_map.begin();
@@ -350,9 +354,9 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::find3Sp(EventData& data, const std::l
   }
 }
 
-void InDet::SiSpacePointsSeedMaker_Cosmic::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
+void InDet::SiSpacePointsSeedMaker_Cosmic::find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
 {
-  find3Sp(data, lv);
+  find3Sp(ctx, data, lv);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -361,7 +365,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::find3Sp(EventData& data, const std::l
 // Variable means (2,3,4,....) any number space points
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_Cosmic::findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_Cosmic::findVSp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -377,7 +381,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::findVSp(EventData& data, const std::l
     data.endlist = true            ;
     data.fNmin   = 0               ;
     data.zMin    = 0               ;
-    production3Sp(data);
+    production3Sp(ctx, data);
   }
 
   data.i_seed_map  = data.l_seeds_map.begin();
@@ -675,8 +679,8 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::production2Sp(EventData& data) const
 // Production 3 space points seeds 
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_Cosmic::production3Sp(EventData& data) const
-{ 
+void InDet::SiSpacePointsSeedMaker_Cosmic::production3Sp(const EventContext& ctx, EventData& data) const
+{
   if (data.nsaz<3) return;
 
   float K   = 0.;
@@ -684,7 +688,21 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::production3Sp(EventData& data) const
   double f[3], gP[3] ={10.,10.,0.};
 
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP,f);
+
+    MagField::AtlasFieldCache    fieldCache;
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+        ATH_MSG_ERROR("SiSpacePointsSeedMaker_Cosmic: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+        return;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //    MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP,f);
+    else                                m_fieldServiceHandle->getFieldZR(gP,f);
+
     K = 2./(300.*f[2]);
   }
   if (!K) return production3SpWithoutField(data);
@@ -1024,7 +1042,7 @@ void InDet::SiSpacePointsSeedMaker_Cosmic::production3SpWithoutField
 // Test is space point used
 ///////////////////////////////////////////////////////////////////
 
-const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_Cosmic::next(EventData& data) const
+const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_Cosmic::next(const EventContext&, EventData& data) const
 {
   if (not data.initialized) initializeEventData(data);
 
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_HeavyIon.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_HeavyIon.cxx
index abb9d6a54c7480d656d723a64a1f51b4833907c0..b75eef500eddeb2e10b8b4b601ee43e8bcb05d20 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_HeavyIon.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_HeavyIon.cxx
@@ -50,6 +50,9 @@ StatusCode InDet::SiSpacePointsSeedMaker_HeavyIon::initialize()
     return StatusCode::FAILURE;
   }    
   ATH_MSG_DEBUG("Retrieved " << m_fieldServiceHandle );
+////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize());
+////////////////////////////////////////////////////////////////////////////////
 
   // Build framework
   //
@@ -83,19 +86,34 @@ StatusCode InDet::SiSpacePointsSeedMaker_HeavyIon::finalize()
 // Initialize tool for new event 
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_HeavyIon::newEvent(EventData& data, int) const
+void InDet::SiSpacePointsSeedMaker_HeavyIon::newEvent(const EventContext& ctx, EventData& data, int) const
 {
   if (not data.initialized) initializeEventData(data);
 
   data.trigger = false;
   if (!m_pixel && !m_sct) return;
   erase(data);
-  buildBeamFrameWork(data);
+  buildBeamFrameWork(ctx, data);
 
   double f[3], gP[3] ={10.,10.,0.};
 
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP,f);
+
+    MagField::AtlasFieldCache    fieldCache;
+
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("SiSpacePointsSeedMaker_HeavyIon: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP,f);
+    else                                m_fieldServiceHandle->getFieldZR(gP,f);
+
     data.K = 2./(300.*f[2]);
   } else {
     data.K = 2./(300.* 5. );
@@ -110,7 +128,7 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newEvent(EventData& data, int) cons
   //
   if (m_pixel) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsPixel) {
@@ -133,7 +151,7 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newEvent(EventData& data, int) cons
   //
   if (m_sct) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsSCT) {
@@ -159,7 +177,7 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newEvent(EventData& data, int) cons
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_HeavyIon::newRegion
-(EventData& data, 
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
 {
   if (not data.initialized) initializeEventData(data);
@@ -168,12 +186,27 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newRegion
   if (!m_pixel && !m_sct) return;
   erase(data);
 
-  buildBeamFrameWork(data);
+  buildBeamFrameWork(ctx, data);
 
   double f[3], gP[3] ={10.,10.,0.};
 
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP,f);
+
+    MagField::AtlasFieldCache    fieldCache;
+
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("SiSpacePointsSeedMaker_HeavyIon: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP, f);
+    else                                m_fieldServiceHandle->getFieldZR(gP, f);
+
     data.K = 2./(300.*f[2]);
   } else {
     data.K = 2./(300.* 5.);
@@ -188,7 +221,7 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newRegion
   //
   if (m_pixel && vPixel.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
@@ -216,7 +249,7 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newRegion
   //
   if (m_sct && vSCT.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
@@ -247,11 +280,11 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newRegion
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_HeavyIon::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
  const IRoiDescriptor&) const
 {
-  newRegion(data, vPixel, vSCT);
+  newRegion(ctx, data, vPixel, vSCT);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -295,7 +328,7 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::find2Sp(EventData& data, const std:
 // with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_HeavyIon::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_HeavyIon::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -326,9 +359,9 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::find3Sp(EventData& data, const std:
   }
 }
 
-void InDet::SiSpacePointsSeedMaker_HeavyIon::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
+void InDet::SiSpacePointsSeedMaker_HeavyIon::find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
 {
-  find3Sp(data, lv);
+  find3Sp(ctx, data, lv);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -337,7 +370,7 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::find3Sp(EventData& data, const std:
 // Variable means (2,3,4,....) any number space points
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_HeavyIon::findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_HeavyIon::findVSp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -717,9 +750,9 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::buildFrameWork()
 // Initiate beam frame work for seed generator
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_HeavyIon::buildBeamFrameWork(EventData& data) const
-{ 
-  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle{m_beamSpotKey};
+void InDet::SiSpacePointsSeedMaker_HeavyIon::buildBeamFrameWork(const EventContext& ctx, EventData& data) const
+{
+  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle{m_beamSpotKey, ctx};
 
   const Amg::Vector3D& cb = beamSpotHandle->beamPos();
   double tx = tan(beamSpotHandle->beamTilt(0));
@@ -1594,7 +1627,7 @@ void InDet::SiSpacePointsSeedMaker_HeavyIon::newOneSeed
   }
 }
 
-const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_HeavyIon::next(EventData& data) const
+const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_HeavyIon::next(const EventContext&, EventData& data) const
 {
   if (not data.initialized) initializeEventData(data);
 
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ITK.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ITK.cxx
index d8770d314c4336d2b0901c348cb01bd986d0c9ab..7ec051bdf9f4b91d4d8010a1213fb46c0f8a7758 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ITK.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ITK.cxx
@@ -52,6 +52,9 @@ StatusCode InDet::SiSpacePointsSeedMaker_ITK::initialize()
     return StatusCode::FAILURE;
   }    
   ATH_MSG_DEBUG("Retrieved " << m_fieldServiceHandle );
+  ////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize());
+  ////////////////////////////////////////////////////////////////////////////////
 
   // PRD-to-track association (optional)
   ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty()));
@@ -91,7 +94,7 @@ StatusCode InDet::SiSpacePointsSeedMaker_ITK::finalize()
 // Initialize tool for new event 
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_ITK::newEvent(EventData& data, int iteration) const
+void InDet::SiSpacePointsSeedMaker_ITK::newEvent(const EventContext& ctx, EventData& data, int iteration) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -109,7 +112,22 @@ void InDet::SiSpacePointsSeedMaker_ITK::newEvent(EventData& data, int iteration)
 
     double f[3], gP[3] ={10.,10.,0.};
     if (m_fieldServiceHandle->solenoidOn()) {
-      m_fieldServiceHandle->getFieldZR(gP, f);
+
+      MagField::AtlasFieldCache    fieldCache;
+
+      // Get field cache object
+      SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+      const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+      if (fieldCondObj == nullptr) {
+        ATH_MSG_ERROR("SiSpacePointsSeedMaker_ITK: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+        return;
+      }
+      fieldCondObj->getInitializedCache (fieldCache);
+
+      //   MT version uses cache, temporarily keep old version
+      if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP, f);
+      else                                m_fieldServiceHandle->getFieldZR(gP, f);
+
       data.K = 2./(300.*f[2]);
     } else {
       data.K = 2./(300.* 5. );
@@ -139,7 +157,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::newEvent(EventData& data, int iteration)
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -151,7 +169,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::newEvent(EventData& data, int iteration)
   data.r_first = 0;
   if (m_pixel) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsPixel) {
@@ -179,7 +197,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::newEvent(EventData& data, int iteration)
   //
   if (m_sct) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsSCT) {
@@ -204,7 +222,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::newEvent(EventData& data, int iteration)
     //
     if (m_useOverlap) {
 
-      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap};
+      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap, ctx};
       if (spacepointsOverlap.isValid()) {
 	
         for (const Trk::SpacePoint* sp: *spacepointsOverlap) {
@@ -234,7 +252,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::newEvent(EventData& data, int iteration)
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ITK::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
 {
   if (not data.initialized) initializeEventData(data);
@@ -252,7 +270,22 @@ void InDet::SiSpacePointsSeedMaker_ITK::newRegion
   double f[3], gP[3] ={10.,10.,0.};
 
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP, f);
+
+    MagField::AtlasFieldCache    fieldCache;
+
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("SiSpacePointsSeedMaker_ITK: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP, f);
+    else                                m_fieldServiceHandle->getFieldZR(gP, f);
+
     data.K = 2./(300.*f[2]);
   } else {
     data.K = 2./(300.* 5. );
@@ -281,7 +314,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::newRegion
   //
   if (m_pixel && vPixel.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
@@ -309,7 +342,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::newRegion
   //
   if (m_sct && vSCT.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
@@ -340,12 +373,12 @@ void InDet::SiSpacePointsSeedMaker_ITK::newRegion
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_ITK::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT, const IRoiDescriptor& IRD) const
 {
   if (not data.initialized) initializeEventData(data);
 
-  newRegion(data, vPixel, vSCT);
+  newRegion(ctx, data, vPixel, vSCT);
   data.trigger = true;
 
   double dzdrmin = 1./tan(2.*atan(exp(-IRD.etaMinus())));
@@ -404,7 +437,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::find2Sp(EventData& data, const std::list
 // with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_ITK::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_ITK::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -441,7 +474,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::find3Sp(EventData& data, const std::list
 // with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_ITK::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double* ZVertex) const
+void InDet::SiSpacePointsSeedMaker_ITK::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv, const double* ZVertex) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -481,7 +514,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::find3Sp(EventData& data, const std::list
 // Variable means (2,3,4,....) any number space points
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_ITK::findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_ITK::findVSp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -1959,7 +1992,7 @@ void InDet::SiSpacePointsSeedMaker_ITK::fillSeeds(EventData& data) const
   }
 }
 
-const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_ITK::next(EventData& data) const
+const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_ITK::next(const EventContext&, EventData& data) const
 {
   if (not data.initialized) initializeEventData(data);
 
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_LowMomentum.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_LowMomentum.cxx
index b651565345cde615dbab7b89ac57ea676d2e57a3..40d3b6fcad1bbc4b99cfe8398c5511013e932245 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_LowMomentum.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_LowMomentum.cxx
@@ -52,6 +52,10 @@ StatusCode InDet::SiSpacePointsSeedMaker_LowMomentum::initialize()
   }    
   ATH_MSG_DEBUG("Retrieved " << m_fieldServiceHandle );
 
+  ////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize());
+  ////////////////////////////////////////////////////////////////////////////////
+
   // PRD-to-track association (optional)
   ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty()));
 
@@ -87,7 +91,7 @@ StatusCode InDet::SiSpacePointsSeedMaker_LowMomentum::finalize()
 // Initialize tool for new event 
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_LowMomentum::newEvent(EventData& data, int) const
+void InDet::SiSpacePointsSeedMaker_LowMomentum::newEvent(const EventContext& ctx, EventData& data, int) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -103,7 +107,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newEvent(EventData& data, int) c
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -114,7 +118,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newEvent(EventData& data, int) c
   //
   if (m_pixel) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsPixel) {
@@ -141,7 +145,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newEvent(EventData& data, int) c
   //
   if (m_sct) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsSCT) {
@@ -171,7 +175,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newEvent(EventData& data, int) c
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_LowMomentum::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const{
   if (not data.initialized) initializeEventData(data);
 
@@ -187,7 +191,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newRegion
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap  *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -198,7 +202,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newRegion
   //
   if (m_pixel && vPixel.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
@@ -229,7 +233,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newRegion
   //
   if (m_sct && vSCT.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
 
       SpacePointContainer::const_iterator spce = spacepointsSCT->end();
@@ -262,11 +266,11 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newRegion
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_LowMomentum::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
  const IRoiDescriptor&) const
 {
-  newRegion(data, vPixel, vSCT);
+  newRegion(ctx, data, vPixel, vSCT);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -306,7 +310,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::find2Sp(EventData& data, const s
 // with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_LowMomentum::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_LowMomentum::find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -323,7 +327,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::find3Sp(EventData& data, const s
     data.endlist = true;
     data.fNmin   = 0;
     data.zMin    = 0;
-    production3Sp(data);
+    production3Sp(ctx, data);
   }
   data.i_seed = data.l_seeds.begin();
 
@@ -333,9 +337,9 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::find3Sp(EventData& data, const s
   }
 }
 
-void InDet::SiSpacePointsSeedMaker_LowMomentum::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
+void InDet::SiSpacePointsSeedMaker_LowMomentum::find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
 {
-  find3Sp(data, lv);
+  find3Sp(ctx, data, lv);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -344,7 +348,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::find3Sp(EventData& data, const s
 // Variable means (2,3,4,....) any number space points
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_LowMomentum::findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_LowMomentum::findVSp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -361,7 +365,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::findVSp(EventData& data, const s
     data.endlist = true;
     data.fNmin   = 0;
     data.zMin    = 0;
-    production3Sp(data);
+    production3Sp(ctx, data);
   }
   data.i_seed = data.l_seeds.begin();
 
@@ -537,7 +541,7 @@ MsgStream& InDet::SiSpacePointsSeedMaker_LowMomentum::dumpEvent(EventData& data,
 // Find next set space points
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_LowMomentum::findNext(EventData& data) const
+void InDet::SiSpacePointsSeedMaker_LowMomentum::findNext(const EventContext& ctx, EventData& data) const
 {
   if (data.endlist) return;
   
@@ -545,9 +549,9 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::findNext(EventData& data) const
   if (data.mode==0 || data.mode==1) {
     production2Sp(data);
   } else if (data.mode==2 || data.mode==3) {
-    production3Sp(data);
+    production3Sp(ctx, data);
   } else if (data.mode==5 || data.mode==6) {
-    production3Sp(data);
+    production3Sp(ctx, data);
   }
 
   data.i_seed = data.l_seeds.begin();
@@ -796,7 +800,7 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::production2Sp(EventData& data) c
 // Production 3 space points seeds (new version)
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_LowMomentum::production3Sp(EventData& data) const
+void InDet::SiSpacePointsSeedMaker_LowMomentum::production3Sp(const EventContext& ctx, EventData& data) const
 {
   if (data.nsaz<3) return;
 
@@ -804,7 +808,22 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::production3Sp(EventData& data) c
   double f[3], gP[3] ={10.,10.,0.};
 
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP,f);
+
+    MagField::AtlasFieldCache    fieldCache;
+
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("SiSpacePointsSeedMaker_LowMomentum: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP, f);
+    else                                m_fieldServiceHandle->getFieldZR(gP, f);
+
     K = 2./(300.*f[2]);
   } else {
     K = 2./(300.* 5. );
@@ -1058,12 +1077,12 @@ void InDet::SiSpacePointsSeedMaker_LowMomentum::newOneSeed
   }
 }
 
-const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_LowMomentum::next(EventData& data) const
+const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_LowMomentum::next(const EventContext& ctx, EventData& data) const
 {
   if (not data.initialized) initializeEventData(data);
 
   if (data.i_seed==data.i_seede) {
-    findNext(data);
+    findNext(ctx, data);
     if (data.i_seed==data.i_seede) return nullptr;
   } 
   return &(*data.i_seed++);
diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Trigger.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Trigger.cxx
index b07fc210cc467d21201daf5f5218aac9d9c45bc1..a30e81f5aa473a00dcd7df56583b7fb978c589ff 100644
--- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Trigger.cxx
+++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_Trigger.cxx
@@ -50,6 +50,9 @@ StatusCode InDet::SiSpacePointsSeedMaker_Trigger::initialize()
     return StatusCode::FAILURE;
   }    
   ATH_MSG_DEBUG("Retrieved " << m_fieldServiceHandle );
+  ////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize());
+  ////////////////////////////////////////////////////////////////////////////////
 
   // Build framework
   //
@@ -83,7 +86,7 @@ StatusCode InDet::SiSpacePointsSeedMaker_Trigger::finalize()
 // Initialize tool for new event 
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_Trigger::newEvent(EventData& data, int) const
+void InDet::SiSpacePointsSeedMaker_Trigger::newEvent(const EventContext& ctx, EventData& data, int) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -95,7 +98,22 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newEvent(EventData& data, int) const
   double f[3], gP[3] ={10.,10.,0.};
 
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP,f);
+
+    MagField::AtlasFieldCache    fieldCache;
+
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("SiSpacePointsSeedMaker_Trigger: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return; 
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP, f);
+    else                                m_fieldServiceHandle->getFieldZR(gP, f);
+
     data.K = 2./(300.*f[2]);
   } else {
     data.K = 2./(300.* 5.);
@@ -110,7 +128,7 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newEvent(EventData& data, int) const
   //
   if (m_pixel) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsPixel) {
@@ -136,7 +154,7 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newEvent(EventData& data, int) const
   //
   if (m_sct) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
 
       for (const SpacePointCollection* spc: *spacepointsSCT) {
@@ -161,7 +179,7 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newEvent(EventData& data, int) const
     //
     if (m_useOverlap) {
 
-      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap};
+      SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap{m_spacepointsOverlap, ctx};
       if (spacepointsOverlap.isValid()) {
  
         for (const Trk::SpacePoint* sp: *spacepointsOverlap) {
@@ -189,7 +207,7 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newEvent(EventData& data, int) const
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_Trigger::newRegion
-(EventData& data, const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
+(const EventContext& ctx, EventData& data, const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -201,7 +219,22 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newRegion
 
   double f[3], gP[3] ={10.,10.,0.};
   if (m_fieldServiceHandle->solenoidOn()) {
-    m_fieldServiceHandle->getFieldZR(gP, f);
+
+    MagField::AtlasFieldCache    fieldCache;
+
+    // Get field cache object
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("SiSpacePointsSeedMaker_Trigger: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return;
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP, f);
+    else                                m_fieldServiceHandle->getFieldZR(gP, f);
+
     data.K = 2./(300.*f[2]);
   } else {
     data.K = 2./(300.* 5.);
@@ -216,7 +249,7 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newRegion
   //
   if (m_pixel && vPixel.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel};
+    SG::ReadHandle<SpacePointContainer> spacepointsPixel{m_spacepointsPixel, ctx};
     if (spacepointsPixel.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsPixel->end();
 
@@ -244,7 +277,7 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newRegion
   //
   if (m_sct && vSCT.size()) {
 
-    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT};
+    SG::ReadHandle<SpacePointContainer> spacepointsSCT{m_spacepointsSCT, ctx};
     if (spacepointsSCT.isValid()) {
       SpacePointContainer::const_iterator spce = spacepointsSCT->end();
 
@@ -275,13 +308,13 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newRegion
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiSpacePointsSeedMaker_Trigger::newRegion
-(EventData& data,
+(const EventContext& ctx, EventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
  const IRoiDescriptor& IRD) const
 {
   if (not data.initialized) initializeEventData(data);
 
-  newRegion(data, vPixel, vSCT);
+  newRegion(ctx, data, vPixel, vSCT);
 
   data.trigger = true;
 
@@ -338,7 +371,7 @@ void InDet::SiSpacePointsSeedMaker_Trigger::find2Sp(EventData& data, const std::
 // with three space points with or without vertex constraint
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_Trigger::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_Trigger::find3Sp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -369,9 +402,9 @@ void InDet::SiSpacePointsSeedMaker_Trigger::find3Sp(EventData& data, const std::
   }
 }
 
-void InDet::SiSpacePointsSeedMaker_Trigger::find3Sp(EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
+void InDet::SiSpacePointsSeedMaker_Trigger::find3Sp(const EventContext& ctx, EventData& data, const std::list<Trk::Vertex>& lv, const double*) const
 {
-  find3Sp(data, lv);
+  find3Sp(ctx, data, lv);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -380,7 +413,7 @@ void InDet::SiSpacePointsSeedMaker_Trigger::find3Sp(EventData& data, const std::
 // Variable means (2,3,4,....) any number space points
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiSpacePointsSeedMaker_Trigger::findVSp(EventData& data, const std::list<Trk::Vertex>& lv) const
+void InDet::SiSpacePointsSeedMaker_Trigger::findVSp(const EventContext&, EventData& data, const std::list<Trk::Vertex>& lv) const
 {
   if (not data.initialized) initializeEventData(data);
 
@@ -1520,7 +1553,7 @@ void InDet::SiSpacePointsSeedMaker_Trigger::newOneSeed
   }
 }
 
-const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_Trigger::next(EventData& data) const
+const InDet::SiSpacePointsSeed* InDet::SiSpacePointsSeedMaker_Trigger::next(const EventContext&, EventData& data) const
 {
   if (not data.initialized) initializeEventData(data);
 
diff --git a/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/CMakeLists.txt b/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/CMakeLists.txt
index 190630f65bb34bb3c1f799f6cf6df0894ff77828..0d5efe37ffcd640e586ca3046eb811c794253582 100644
--- a/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/CMakeLists.txt
@@ -18,13 +18,15 @@ atlas_depends_on_subdirs( PUBLIC
                           Database/AthenaPOOL/AthenaPoolUtilities
                           InnerDetector/InDetRecEvent/InDetPrepRawData
                           InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData
-                          Tracking/TrkEvent/TrkRIO_OnTrack )
+                          Tracking/TrkEvent/TrkRIO_OnTrack
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions)
 
 # Component(s) in the package:
 atlas_add_component( SiTrackMakerTool_xk
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkCaloClusterROI AthenaPoolUtilities InDetPrepRawData SiSPSeededTrackFinderData TrkRIO_OnTrack)
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkCaloClusterROI AthenaPoolUtilities InDetPrepRawData SiSPSeededTrackFinderData TrkRIO_OnTrack MagFieldElements MagFieldConditions)
 
 # Install files from the package:
 atlas_install_headers( SiTrackMakerTool_xk )
diff --git a/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/SiTrackMakerTool_xk/SiTrackMaker_xk.h b/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/SiTrackMakerTool_xk/SiTrackMaker_xk.h
index fc49c73dcf0f783ad2da9d0a9219025da6b1d4e4..8d3e788daf509eb3624fae2a95f76dc554dc35d1 100644
--- a/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/SiTrackMakerTool_xk/SiTrackMaker_xk.h
+++ b/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/SiTrackMakerTool_xk/SiTrackMaker_xk.h
@@ -27,6 +27,12 @@
 #include "GaudiKernel/ServiceHandle.h"
 #include "GaudiKernel/ToolHandle.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 #include <array>
 #include <iosfwd>
 #include <list>
@@ -79,13 +85,13 @@ namespace InDet{
       ///////////////////////////////////////////////////////////////////
       //@{
       virtual std::list<Trk::Track*>
-      getTracks(SiTrackMakerEventData_xk& data, const std::list<const Trk::SpacePoint*>& Sp) const override;
+      getTracks(const EventContext& ctx, SiTrackMakerEventData_xk& data, const std::list<const Trk::SpacePoint*>& Sp) const override;
 
       virtual std::list<Trk::Track*>
-      getTracks(SiTrackMakerEventData_xk& data, const Trk::TrackParameters& Tp, const std::list<Amg::Vector3D>& Gp) const override;
+      getTracks(const EventContext& ctx, SiTrackMakerEventData_xk& data, const Trk::TrackParameters& Tp, const std::list<Amg::Vector3D>& Gp) const override;
 
-      virtual void newEvent(SiTrackMakerEventData_xk& data, bool PIX, bool SCT) const override;
-      virtual void newTrigEvent(SiTrackMakerEventData_xk& data, bool PIX, bool SCT) const override;
+      virtual void newEvent(const EventContext& ctx, SiTrackMakerEventData_xk& data, bool PIX, bool SCT) const override;
+      virtual void newTrigEvent(const EventContext& ctx, SiTrackMakerEventData_xk& data, bool PIX, bool SCT) const override;
 
       virtual void endEvent(SiTrackMakerEventData_xk& data) const override;
       //@}
@@ -121,6 +127,7 @@ namespace InDet{
       /// @name Data handles
       //@{
       SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey{this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot"};
+      SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
       SG::ReadHandleKey<CaloClusterROI_Collection> m_caloCluster{this, "InputClusterContainerName", "InDetCaloClusterROIs"};
       SG::ReadHandleKey<CaloClusterROI_Collection> m_caloHad{this, "InputHadClusterContainerName", "InDetHadCaloClusterROIs"};
       //@}
@@ -169,10 +176,10 @@ namespace InDet{
       // Methods 
       ///////////////////////////////////////////////////////////////////
 
-      const Trk::TrackParameters* getAtaPlane(SiTrackMakerEventData_xk& data,
+      const Trk::TrackParameters* getAtaPlane(MagField::AtlasFieldCache& fieldCache, SiTrackMakerEventData_xk& data,
                                               bool sss,
                                               const std::list<const Trk::SpacePoint*>& SP) const;
-      const Trk::TrackParameters* getAtaPlaneDBM(SiTrackMakerEventData_xk& data,
+      const Trk::TrackParameters* getAtaPlaneDBM(MagField::AtlasFieldCache& fieldCache, SiTrackMakerEventData_xk& data,
                                                  const std::list<const Trk::SpacePoint*>& SP) const;
 
       bool globalPositions(const Trk::SpacePoint* s0,
diff --git a/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx b/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx
index 208322cb0d34b05aaa8a4717452783fa83c124fc..ff91802562732da468ecaf0365111236de4b3e54 100644
--- a/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx
+++ b/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx
@@ -117,6 +117,10 @@ StatusCode InDet::SiTrackMaker_xk::initialize()
   ATH_CHECK(m_caloHad.initialize( !m_useSSSfilter && m_useHClusSeed) );
 
   if (m_pTmin < 20.) m_pTmin = 20.;
+
+  ////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize());
+  ////////////////////////////////////////////////////////////////////////////////
   return StatusCode::SUCCESS;
 }
 
@@ -225,12 +229,12 @@ MsgStream& InDet::SiTrackMaker_xk::dumpevent(SiTrackMakerEventData_xk& data, Msg
 // Initiate track finding tool for new event
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiTrackMaker_xk::newEvent(SiTrackMakerEventData_xk& data, bool PIX, bool SCT) const
+void InDet::SiTrackMaker_xk::newEvent(const EventContext& ctx, SiTrackMakerEventData_xk& data, bool PIX, bool SCT) const
 {
   data.xybeam()[0] = 0.;
   data.xybeam()[1] = 0.;
   if (not m_beamSpotKey.empty()) {
-    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey };
+    SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey, ctx };
     if (beamSpotHandle.isValid()) {
       data.xybeam()[0] = beamSpotHandle->beamPos()[0];
       data.xybeam()[1] = beamSpotHandle->beamPos()[1];
@@ -245,7 +249,7 @@ void InDet::SiTrackMaker_xk::newEvent(SiTrackMakerEventData_xk& data, bool PIX,
 
   // New event for track finder tool
   //
-  m_tracksfinder->newEvent(data.combinatorialData(), m_trackinfo, trackquality);
+  m_tracksfinder->newEvent(ctx, data.combinatorialData(), m_trackinfo, trackquality);
 
   // Erase cluster to track association
   //
@@ -266,7 +270,7 @@ void InDet::SiTrackMaker_xk::newEvent(SiTrackMakerEventData_xk& data, bool PIX,
     data.caloZ().clear();
 
     if (!m_caloCluster.key().empty()) {
-      SG::ReadHandle<CaloClusterROI_Collection> calo_cluster(m_caloCluster);
+      SG::ReadHandle<CaloClusterROI_Collection> calo_cluster(m_caloCluster, ctx);
       if (calo_cluster.isValid()) {
         for (const Trk::CaloClusterROI *c : * calo_cluster) {
           data.caloF().push_back( c->globalPosition().phi ());
@@ -283,7 +287,7 @@ void InDet::SiTrackMaker_xk::newEvent(SiTrackMakerEventData_xk& data, bool PIX,
     data.hadZ().clear();
 
     if (!m_caloHad.key().empty()) {
-      SG::ReadHandle<CaloClusterROI_Collection> calo_had(m_caloHad);
+      SG::ReadHandle<CaloClusterROI_Collection> calo_had(m_caloHad, ctx);
       if (calo_had.isValid()) {
         for (const Trk::CaloClusterROI *c : * calo_had) {
           data.hadF().push_back( c->globalPosition().phi ());
@@ -300,7 +304,7 @@ void InDet::SiTrackMaker_xk::newEvent(SiTrackMakerEventData_xk& data, bool PIX,
 // Initiate track finding tool for new event
 ///////////////////////////////////////////////////////////////////
 
-void InDet::SiTrackMaker_xk::newTrigEvent(SiTrackMakerEventData_xk& data, bool PIX, bool SCT) const
+void InDet::SiTrackMaker_xk::newTrigEvent(const EventContext& ctx, SiTrackMakerEventData_xk& data, bool PIX, bool SCT) const
 {
   data.pix()        = PIX && m_usePix;
   data.sct()        = SCT && m_useSct;
@@ -310,7 +314,7 @@ void InDet::SiTrackMaker_xk::newTrigEvent(SiTrackMakerEventData_xk& data, bool P
 
   // New event for track finder tool
   //
-  m_tracksfinder->newEvent(data.combinatorialData(), m_trackinfo, trackquality);
+  m_tracksfinder->newEvent(ctx, data.combinatorialData(), m_trackinfo, trackquality);
 
   // Erase cluster to track association
   //
@@ -352,7 +356,7 @@ void InDet::SiTrackMaker_xk::endEvent(SiTrackMakerEventData_xk& data) const
 ///////////////////////////////////////////////////////////////////
 
 std::list<Trk::Track*> InDet::SiTrackMaker_xk::getTracks
-(SiTrackMakerEventData_xk& data, const std::list<const Trk::SpacePoint*>& Sp) const
+(const EventContext& ctx, SiTrackMakerEventData_xk& data, const std::list<const Trk::SpacePoint*>& Sp) const
 {
   ++data.inputseeds();
   std::list<Trk::Track*> tracks;
@@ -365,20 +369,31 @@ std::list<Trk::Track*> InDet::SiTrackMaker_xk::getTracks
 
   data.dbm() = isDBMSeeds(*Sp.begin());
 
+  // Get AtlasFieldCache
+  MagField::AtlasFieldCache fieldCache;
+
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("InDet::SiTrackMaker_xk::getTracks: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return tracks;
+  }
+  fieldCondObj->getInitializedCache (fieldCache);
+  
   // Get initial parameters estimation
   //
   bool sss = false;
   const Trk::TrackParameters* Tp = nullptr;
-  if (data.dbm()) Tp = getAtaPlaneDBM(data, Sp);
-  else Tp = getAtaPlane(data, sss && m_useHClusSeed, Sp);
+  if (data.dbm()) Tp = getAtaPlaneDBM(fieldCache, data, Sp);
+  else Tp = getAtaPlane(fieldCache, data, sss && m_useHClusSeed, Sp);
   if (!Tp) return tracks;
   ++data.goodseeds();
 
   // Get detector elements road
   //
   std::list<const InDetDD::SiDetectorElement*> DE;
-  if (!m_cosmicTrack) m_roadmaker->detElementsRoad(*Tp,Trk::alongMomentum,   DE);
-  else                m_roadmaker->detElementsRoad(*Tp,Trk::oppositeMomentum,DE);
+  if (!m_cosmicTrack) m_roadmaker->detElementsRoad(ctx, fieldCache, *Tp,Trk::alongMomentum,   DE);
+  else                m_roadmaker->detElementsRoad(ctx, fieldCache, *Tp,Trk::oppositeMomentum,DE);
 
   if (!data.pix() || !data.sct() || data.dbm()) detectorElementsSelection(data, DE);
 
@@ -427,7 +442,7 @@ std::list<Trk::Track*> InDet::SiTrackMaker_xk::getTracks
 ///////////////////////////////////////////////////////////////////
 
 std::list<Trk::Track*> InDet::SiTrackMaker_xk::getTracks
-(SiTrackMakerEventData_xk& data, const Trk::TrackParameters& Tp, const std::list<Amg::Vector3D>& Gp) const
+(const EventContext& ctx, SiTrackMakerEventData_xk& data, const Trk::TrackParameters& Tp, const std::list<Amg::Vector3D>& Gp) const
 {
   ++data.inputseeds();
   std::list<Trk::Track*> tracks;
@@ -435,11 +450,22 @@ std::list<Trk::Track*> InDet::SiTrackMaker_xk::getTracks
 
   ++data.goodseeds();
 
+  // Get AtlasFieldCache
+  MagField::AtlasFieldCache fieldCache;
+
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("InDet::SiTrackMaker_xk::getTracks: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return tracks;
+  }
+  fieldCondObj->getInitializedCache (fieldCache);
+  
   // Get detector elements road
   //
   std::list<const InDetDD::SiDetectorElement*> DE;
-  if (!m_cosmicTrack) m_roadmaker->detElementsRoad(Tp,Trk::alongMomentum,   DE);
-  else                m_roadmaker->detElementsRoad(Tp,Trk::oppositeMomentum,DE);
+  if (!m_cosmicTrack) m_roadmaker->detElementsRoad(ctx, fieldCache, Tp,Trk::alongMomentum,   DE);
+  else                m_roadmaker->detElementsRoad(ctx, fieldCache, Tp,Trk::oppositeMomentum,DE);
 
   if (!data.pix() || !data.sct()) detectorElementsSelection(data, DE);
 
@@ -479,7 +505,10 @@ std::list<Trk::Track*> InDet::SiTrackMaker_xk::getTracks
 ///////////////////////////////////////////////////////////////////
 
 const Trk::TrackParameters* InDet::SiTrackMaker_xk::getAtaPlane
-(SiTrackMakerEventData_xk& data, bool sss, const std::list<const Trk::SpacePoint*>& SP) const
+(MagField::AtlasFieldCache& fieldCache,
+ SiTrackMakerEventData_xk& data,
+ bool sss,
+ const std::list<const Trk::SpacePoint*>& SP) const
 {
   std::list<const Trk::SpacePoint*>::const_iterator is=SP.begin(),ise=SP.end(),is0,is1,is2;  
   if (is==ise) return nullptr;
@@ -535,7 +564,10 @@ const Trk::TrackParameters* InDet::SiTrackMaker_xk::getAtaPlane
   Trk::MagneticFieldProperties fieldprop(fieldModeEnum);
   if (fieldprop.magneticFieldMode() > 0) {
 
-    double H[3],gP[3] ={x0,y0,z0}; m_fieldServiceHandle->getFieldZR(gP,H);
+    double H[3],gP[3] ={x0,y0,z0};
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP, H);
+    else                                m_fieldServiceHandle->getFieldZR(gP, H);
 
     if (fabs(H[2])>.0001) {
       data.par()[2] = atan2(b+a*A,a-b*A);
@@ -570,7 +602,9 @@ const Trk::TrackParameters* InDet::SiTrackMaker_xk::getAtaPlane
 ///////////////////////////////////////////////////////////////////
 
 const Trk::TrackParameters* InDet::SiTrackMaker_xk::getAtaPlaneDBM
-(SiTrackMakerEventData_xk& data, const std::list<const Trk::SpacePoint*>& SP) const
+(MagField::AtlasFieldCache& fieldCache,
+ SiTrackMakerEventData_xk& data,
+ const std::list<const Trk::SpacePoint*>& SP) const
 {
   std::list<const Trk::SpacePoint*>::const_iterator is=SP.begin(),ise=SP.end(),is0,is1,is2;  
   if (is==ise) return nullptr;
@@ -623,7 +657,10 @@ const Trk::TrackParameters* InDet::SiTrackMaker_xk::getAtaPlaneDBM
   Trk::MagneticFieldProperties fieldprop(fieldModeEnum);
   if (fieldprop.magneticFieldMode() > 0) {
     double H[3],gP[3] ={p0[0],p0[1],p0[2]};
-    m_fieldServiceHandle->getFieldZR(gP,H);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR           (gP, H);
+    else                                m_fieldServiceHandle->getFieldZR(gP,H);
 
     if (fabs(H[2])>.0001) {
       data.par()[2] = atan2(b+a*A,a-b*A);
diff --git a/InnerDetector/InDetRecTools/SiZvertexTool_xk/SiZvertexTool_xk/SiZvertexMaker_xk.h b/InnerDetector/InDetRecTools/SiZvertexTool_xk/SiZvertexTool_xk/SiZvertexMaker_xk.h
index 401e8324117820e87a6e213c864891ccbcd5f8fc..ad4d772d20143df951740243b3dfb87a83db88bd 100644
--- a/InnerDetector/InDetRecTools/SiZvertexTool_xk/SiZvertexTool_xk/SiZvertexMaker_xk.h
+++ b/InnerDetector/InDetRecTools/SiZvertexTool_xk/SiZvertexTool_xk/SiZvertexMaker_xk.h
@@ -70,11 +70,11 @@ namespace InDet {
     /// @name Methods to initialize tool for new event or region
     ///////////////////////////////////////////////////////////////////
     //@{
-    virtual std::list<Trk::Vertex> newEvent(SiSpacePointsSeedMakerEventData& data) const override;
-    virtual std::list<Trk::Vertex> newRegion(SiSpacePointsSeedMakerEventData& data,
+    virtual std::list<Trk::Vertex> newEvent(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data) const override;
+    virtual std::list<Trk::Vertex> newRegion(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
                                              const std::vector<IdentifierHash>&,
                                              const std::vector<IdentifierHash>&) const override;
-    virtual std::list<Trk::Vertex> newRegion(SiSpacePointsSeedMakerEventData& data,
+    virtual std::list<Trk::Vertex> newRegion(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
                                              const std::vector<IdentifierHash>&,
                                              const std::vector<IdentifierHash>&,
                                              const IRoiDescriptor&) const override;
@@ -113,7 +113,7 @@ namespace InDet {
     // Protected methods
     ///////////////////////////////////////////////////////////////////
 
-    std::list<Trk::Vertex> production(SiSpacePointsSeedMakerEventData& data) const;
+    std::list<Trk::Vertex> production(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data) const;
     MsgStream& dumpConditions(MsgStream& out) const;
   };
 }
diff --git a/InnerDetector/InDetRecTools/SiZvertexTool_xk/src/SiZvertexMaker_xk.cxx b/InnerDetector/InDetRecTools/SiZvertexTool_xk/src/SiZvertexMaker_xk.cxx
index 26c3ba490166f2748fa1d048d9a50ba101f1bcd3..89a273a0d44cfd0cd5e46f608771784ea661d77a 100644
--- a/InnerDetector/InDetRecTools/SiZvertexTool_xk/src/SiZvertexMaker_xk.cxx
+++ b/InnerDetector/InDetRecTools/SiZvertexTool_xk/src/SiZvertexMaker_xk.cxx
@@ -58,10 +58,10 @@ StatusCode InDet::SiZvertexMaker_xk::finalize()
 // Initialize tool for new event 
 ///////////////////////////////////////////////////////////////////
 
-std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::newEvent(SiSpacePointsSeedMakerEventData& data) const
+std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::newEvent(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data) const
 {
-  m_seedsgenerator->newEvent(data);
-  return production(data);
+  m_seedsgenerator->newEvent(ctx, data);
+  return production(ctx, data);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -69,11 +69,11 @@ std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::newEvent(SiSpacePointsSeedMaker
 ///////////////////////////////////////////////////////////////////
 
 std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::newRegion
-(SiSpacePointsSeedMakerEventData& data,
+(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT) const
 {
-  m_seedsgenerator->newRegion(data, vPixel, vSCT);
-  return production(data);
+  m_seedsgenerator->newRegion(ctx, data, vPixel, vSCT);
+  return production(ctx, data);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -81,19 +81,20 @@ std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::newRegion
 ///////////////////////////////////////////////////////////////////
 
 std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::newRegion
-(SiSpacePointsSeedMakerEventData& data,
+(const EventContext& ctx, SiSpacePointsSeedMakerEventData& data,
  const std::vector<IdentifierHash>& vPixel, const std::vector<IdentifierHash>& vSCT,
  const IRoiDescriptor& PhEt) const
 {
-  m_seedsgenerator->newRegion(data, vPixel, vSCT, PhEt);
-  return production(data);
+  m_seedsgenerator->newRegion(ctx, data, vPixel, vSCT, PhEt);
+  return production(ctx, data);
 }
 
 ///////////////////////////////////////////////////////////////////
 // Get list vertices Z-coordinates
 ///////////////////////////////////////////////////////////////////
 
-std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::production(SiSpacePointsSeedMakerEventData& data) const
+std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::production(const EventContext& ctx,
+                                                            SiSpacePointsSeedMakerEventData& data) const
 {
   std::list<Trk::Vertex> vertices;
 
@@ -109,8 +110,8 @@ std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::production(SiSpacePointsSeedMak
   std::list<Trk::Vertex> lv;  
   
   if      (m_nspoint==2) m_seedsgenerator->find2Sp(data, lv);
-  else if (m_nspoint==3) m_seedsgenerator->find3Sp(data, lv);
-  else                   m_seedsgenerator->findVSp(data, lv);
+  else if (m_nspoint==3) m_seedsgenerator->find3Sp(ctx, data, lv);
+  else                   m_seedsgenerator->findVSp(ctx, data, lv);
 
   const InDet::SiSpacePointsSeed* seed = nullptr;
   std::multimap<int,double> ver;
@@ -119,7 +120,7 @@ std::list<Trk::Vertex> InDet::SiZvertexMaker_xk::production(SiSpacePointsSeedMak
   int    Hmax = 0 ;
   double zmax = 0.;
 
-  while ((seed = m_seedsgenerator->next(data))) {
+  while ((seed = m_seedsgenerator->next(ctx, data))) {
 
     std::list<const Trk::SpacePoint*>::const_iterator 
       s = seed->spacePoints().begin();
diff --git a/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/CMakeLists.txt b/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/CMakeLists.txt
index aa39883005140f93812bcdcc19ceb025cde4d92f..258ea53b34eff2fb7ec5d3f66e303982bed03cbe 100644
--- a/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/CMakeLists.txt
@@ -18,13 +18,15 @@ atlas_depends_on_subdirs( PUBLIC
                           Tracking/TrkDetDescr/TrkSurfaces
                           PRIVATE
                           Database/AthenaPOOL/AthenaPoolUtilities
-                          Tracking/TrkExtrapolation/TrkExInterfaces )
-
+                          Tracking/TrkExtrapolation/TrkExInterfaces
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions)
+                          
 # Component(s) in the package:
 atlas_add_component( TRT_DetElementsRoadTool_xk
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetReadoutGeometry TRT_ReadoutGeometry InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkSurfaces AthenaPoolUtilities TrkExInterfaces )
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetReadoutGeometry TRT_ReadoutGeometry InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkSurfaces AthenaPoolUtilities TrkExInterfaces MagFieldElements MagFieldConditions)
 
 # Install files from the package:
 atlas_install_headers( TRT_DetElementsRoadTool_xk )
diff --git a/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/TRT_DetElementsRoadTool_xk/TRT_DetElementsRoadMaker_xk.h b/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/TRT_DetElementsRoadTool_xk/TRT_DetElementsRoadMaker_xk.h
index 0599c5dfb004ffe0062d24be4889d9d34520fe16..1d627a9be0e638c1b8b09d809c3110905b10f823 100755
--- a/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/TRT_DetElementsRoadTool_xk/TRT_DetElementsRoadMaker_xk.h
+++ b/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/TRT_DetElementsRoadTool_xk/TRT_DetElementsRoadMaker_xk.h
@@ -38,11 +38,16 @@
 #include "TRT_DetElementsRoadTool_xk/TRT_DetElementsLayer_xk.h"
 #include "TRT_DetElementsRoadTool_xk/TRT_DetElementsRoadData_xk.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 #include <atomic>
+#include <mutex>
 #include <list>
 #include <vector>
 #include <iosfwd>
-#include <mutex>
 
 class MsgStream;
 
@@ -86,11 +91,15 @@ namespace InDet {
       ///////////////////////////////////////////////////////////////////
       
       virtual void detElementsRoad
-	(const Trk::TrackParameters&,Trk::PropDirection, 
+	(const EventContext& ctx,
+         MagField::AtlasFieldCache& fieldCache,
+         const Trk::TrackParameters&,Trk::PropDirection,
 	 std::vector<const InDetDD::TRT_BaseElement*>&) const;
 
       virtual void detElementsRoad
-	(const Trk::TrackParameters&,Trk::PropDirection, 
+	(const EventContext& ctx,
+         MagField::AtlasFieldCache& fieldCache,
+         const Trk::TrackParameters&,Trk::PropDirection,
 	 std::vector<std::pair<const InDetDD::TRT_BaseElement*,const Trk::TrackParameters*> >&) const;
 
       ///////////////////////////////////////////////////////////////////
@@ -100,11 +109,8 @@ namespace InDet {
       MsgStream&    dump(MsgStream&    out) const;
       std::ostream& dump(std::ostream& out) const;
 
-    private:
-      
-      ///////////////////////////////////////////////////////////////////
-      // Protected Data
-      ///////////////////////////////////////////////////////////////////
+
+    private :
 
       SG::ReadCondHandleKey<TRT_DetElementsRoadData_xk> m_roadDataKey{this, "RoadDataKey",                       
         "TRT_DetElementsRoadData_xk", "Key of TRT_DetElementsRoadData_xk"}; 
@@ -131,7 +137,7 @@ namespace InDet {
       double stepToDetElement
 	(const InDetDD::TRT_BaseElement*&,Amg::Vector3D&,Amg::Vector3D&) const;
 
-      Trk::CylinderBounds getBound(const Trk::TrackParameters&) const;
+      Trk::CylinderBounds getBound(MagField::AtlasFieldCache& fieldCache, const Trk::TrackParameters&) const;
 
       MsgStream&    dumpConditions(MsgStream   & out) const;
 
diff --git a/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/src/TRT_DetElementsRoadMaker_xk.cxx b/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/src/TRT_DetElementsRoadMaker_xk.cxx
index 1ddafbac5807b3596d51c483488fc9ddb21f97ea..8d07b0435c15da2e272ce4d9fd34e4355f5c36ee 100755
--- a/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/src/TRT_DetElementsRoadMaker_xk.cxx
+++ b/InnerDetector/InDetRecTools/TRT_DetElementsRoadTool_xk/src/TRT_DetElementsRoadMaker_xk.cxx
@@ -290,14 +290,16 @@ std::ostream& InDet::TRT_DetElementsRoadMaker_xk::dump( std::ostream& out ) cons
 ///////////////////////////////////////////////////////////////////
 
 void InDet::TRT_DetElementsRoadMaker_xk::detElementsRoad
-(const Trk::TrackParameters& Tp,Trk::PropDirection D, 
+(const EventContext& ctx,
+ MagField::AtlasFieldCache& fieldCache,
+ const Trk::TrackParameters& Tp,Trk::PropDirection D,
  std::vector<const InDetDD::TRT_BaseElement*>& R) const
 {
 
   double qp   = fabs(500.*Tp.parameters()[4]) ; if( qp < 1.e-10  ) qp = 1.e-10; 
   double S    = m_step/qp                     ; if( S  > 200.    ) S  = 200.  ; if(D<0) S=-S; 
 
-  Trk::CylinderBounds CB = getBound(Tp);
+  Trk::CylinderBounds CB = getBound(fieldCache, Tp);
 
   double rminTRT = getTRTMinR();
 
@@ -307,7 +309,7 @@ void InDet::TRT_DetElementsRoadMaker_xk::detElementsRoad
     Trk::MagneticFieldProperties fieldprop(fieldModeEnum);
 
     std::list<Amg::Vector3D> G;
-    m_proptool->globalPositions(G,Tp,fieldprop,CB,S,Trk::pion);
+    m_proptool->globalPositions(ctx, G,Tp,fieldprop,CB,S,Trk::pion);
 
     if(G.size() > 1 ) {
       detElementsRoadATL(G,R);
@@ -326,10 +328,14 @@ void InDet::TRT_DetElementsRoadMaker_xk::detElementsRoad
 ///////////////////////////////////////////////////////////////////
 
 void InDet::TRT_DetElementsRoadMaker_xk::detElementsRoad
-(const Trk::TrackParameters& Tp,Trk::PropDirection D, 
+(const EventContext& ctx,
+ MagField::AtlasFieldCache& fieldCache,
+ const Trk::TrackParameters& Tp,
+ Trk::PropDirection D,
  std::vector<std::pair<const InDetDD::TRT_BaseElement*,const Trk::TrackParameters*> >& R) const
 {
- std::vector<const InDetDD::TRT_BaseElement*> RE;  detElementsRoad(Tp,D,RE);
+ std::vector<const InDetDD::TRT_BaseElement*> RE;
+ detElementsRoad(ctx, fieldCache, Tp,D,RE);
 
  if (msgLvl(MSG::VERBOSE)) {
     dumpEvent(msg(MSG::VERBOSE), R.size());
@@ -345,7 +351,7 @@ void InDet::TRT_DetElementsRoadMaker_xk::detElementsRoad
  Trk::MagneticFieldProperties fieldprop(fieldModeEnum);
 
  const Trk::TrackParameters* tp0 = 
-   m_proptool->propagate(Tp,(*r)->surface(),D,false,fieldprop,Trk::pion);
+   m_proptool->propagate(ctx, Tp,(*r)->surface(),D,false,fieldprop,Trk::pion);
  if(!tp0) return;
 
  std::pair<const InDetDD::TRT_BaseElement*,const Trk::TrackParameters*> EP0((*r),tp0);
@@ -354,7 +360,7 @@ void InDet::TRT_DetElementsRoadMaker_xk::detElementsRoad
  for(++r; r!=re; ++r) {
    
    const Trk::TrackParameters* tp = 
-     m_proptool->propagate((*tp0),(*r)->surface(),D,false,fieldprop,Trk::pion);
+     m_proptool->propagate(ctx, (*tp0),(*r)->surface(),D,false,fieldprop,Trk::pion);
    if(!tp) return;
 
    std::pair<const InDetDD::TRT_BaseElement*,const Trk::TrackParameters*> EP((*r),tp);
@@ -597,7 +603,7 @@ double InDet::TRT_DetElementsRoadMaker_xk::stepToDetElement
 ///////////////////////////////////////////////////////////////////
 
 Trk::CylinderBounds InDet::TRT_DetElementsRoadMaker_xk::getBound
-(const Trk::TrackParameters& Tp) const
+(MagField::AtlasFieldCache& fieldCache, const Trk::TrackParameters& Tp) const
 {
   const double cor = 0.8;
 
@@ -605,7 +611,11 @@ Trk::CylinderBounds InDet::TRT_DetElementsRoadMaker_xk::getBound
   if(m_fieldModeEnum!=Trk::NoField && m_fieldService->solenoidOn()) {
     const Amg::Vector3D& pos = Tp.position();
     double f[3], p[3] ={pos[Amg::x],pos[Amg::y],pos[Amg::z]};
-    m_fieldService->getFieldZR(p,f);
+
+    //   MT version uses cache, temporarily keep old version
+    if (fieldCache.useNewBfieldCache()) fieldCache.getFieldZR  (p, f);
+    else                                m_fieldService->getFieldZR(p,f);
+
     zfield =  299.7925*f[2];
   }
 
diff --git a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/CMakeLists.txt b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/CMakeLists.txt
index 51950c5738f000bfbde9b3695e12143607c15cb5..8f8c97138fe5751313403c656a4c7c59980a17cc 100644
--- a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/CMakeLists.txt
@@ -22,7 +22,10 @@ atlas_depends_on_subdirs( PUBLIC
                           InnerDetector/InDetDetDescr/InDetIdentifier
                           InnerDetector/InDetRecEvent/InDetPrepRawData
                           Tracking/TrkDetDescr/TrkSurfaces
-                          Tracking/TrkTools/TrkToolInterfaces )
+                          Tracking/TrkTools/TrkToolInterfaces
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions
+			  )
 
 # External dependencies:
 find_package( CLHEP )
@@ -32,7 +35,7 @@ atlas_add_component( TRT_SeededSpacePointFinderTool
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${CLHEP_LIBRARIES} AthenaBaseComps IRegionSelector GaudiKernel SiSpacePointsSeed InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkSpacePoint RoiDescriptor InDetIdentifier InDetPrepRawData TrkSurfaces TrkToolInterfaces TrkEventUtils)
+                     LINK_LIBRARIES ${CLHEP_LIBRARIES} AthenaBaseComps IRegionSelector GaudiKernel SiSpacePointsSeed InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkSpacePoint RoiDescriptor InDetIdentifier InDetPrepRawData TrkSurfaces TrkToolInterfaces TrkEventUtils MagFieldElements MagFieldConditions)
 
 # Install files from the package:
 atlas_install_headers( TRT_SeededSpacePointFinderTool )
diff --git a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinderTool/SimpleTRT_SeededSpacePointFinder_ATL.h b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinderTool/SimpleTRT_SeededSpacePointFinder_ATL.h
index 088f5d5bcf3a38a690e2cc0c8d3d8585af0f2026..400fd153c4b1bdfb0df6462406a16e16e1f4c2e2 100755
--- a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinderTool/SimpleTRT_SeededSpacePointFinder_ATL.h
+++ b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinderTool/SimpleTRT_SeededSpacePointFinder_ATL.h
@@ -69,7 +69,8 @@ namespace InDet{
       /** main method, calls the private methods and returns a pointer to
           the list of SpacePointpairs. The list itself is a private member of this
           class */
-      std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> > find2Sp (const Trk::TrackParameters&,
+      std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> > find2Sp (const EventContext& ctx,
+                                                                                    const Trk::TrackParameters&,
                                                                                     InDet::ITRT_SeededSpacePointFinder::IEventData &event_data) const override;
       
       ///////////////////////////////////////////////////////////////////
@@ -138,7 +139,11 @@ namespace InDet{
        void getSearchRange(double& deltaPhi, double& deltaEta) const;
 
        /** retrieves SP Collections of modules in the ROI and sorts them by SCT layer */
-       void getSpacePointsInROI(std::set<IdentifierHash>& setOfSCT_Hashes, int modulTRT,  std::multimap<int,const Trk::SpacePoint*>& relevantSpacePoints) const;
+       void getSpacePointsInROI(const EventContext& ctx,
+                                std::set<IdentifierHash>& setOfSCT_Hashes,
+                                int modulTRT,
+                                std::multimap<int,
+                                const Trk::SpacePoint*>& relevantSpacePoints) const;
 
        /** obtains the hashes of modules in the ROI */ 
        void getHashesInROI(const Trk::TrackParameters& directionTRT, std::set<IdentifierHash>& setOfSCT_Hashes) const;
diff --git a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinder_ATL.h b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinder_ATL.h
index a5b1878c23188ae4f8ca6fc50698a958e55ba9f7..04b9b2241a52aedf8dc1c003397cd8c967cc6f74 100755
--- a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinder_ATL.h
+++ b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinderTool/TRT_SeededSpacePointFinder_ATL.h
@@ -31,6 +31,11 @@
 #include "MagFieldInterfaces/IMagFieldSvc.h"
 
 #include "TrkEventUtils/PRDtoTrackMap.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 #include <list>
 #include <vector>
@@ -92,7 +97,8 @@ namespace InDet{
       /** Main method of seed production                               */
       ///////////////////////////////////////////////////////////////////
 
-      std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> > find2Sp (const Trk::TrackParameters&,
+      std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> > find2Sp (const EventContext& ctx,
+                                                                                    const Trk::TrackParameters&,
                                                                                     ITRT_SeededSpacePointFinder::IEventData &event_data) const;
 
       ///////////////////////////////////////////////////////////////////
@@ -196,6 +202,11 @@ namespace InDet{
       SG::ReadHandleKey<Trk::PRDtoTrackMap>          m_prdToTrackMap
          {this,"PRDtoTrackMap",""};
 
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+      // Read handle for conditions object to get the field cache
+      SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                            "Name of the Magnetic Field conditions object key"};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       ///////////////////////////////////////////////////////////////////
       /** Protected methods                                            */
       ///////////////////////////////////////////////////////////////////
@@ -212,7 +223,7 @@ namespace InDet{
       /** Form possible space point combinations within allowed radial and pseudorapidity ranges */
 
       // // // // // // // // // // // // // // // // //
-      void production2Spb (const Trk::TrackParameters&,
+      void production2Spb (const EventContext& ctx, const Trk::TrackParameters&,
                            int,
                            std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> > &outputListBuffer,
                            InDet::TRT_SeededSpacePointFinder_ATL::EventData &event_data) const;
diff --git a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/src/SimpleTRT_SeededSpacePointFinder_ATL.cxx b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/src/SimpleTRT_SeededSpacePointFinder_ATL.cxx
index 78b04a0d00efa8d7613748eded28d34ba8523fa2..a18b2f4fd4fac731aac06fea503b703cf13f3afa 100755
--- a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/src/SimpleTRT_SeededSpacePointFinder_ATL.cxx
+++ b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/src/SimpleTRT_SeededSpacePointFinder_ATL.cxx
@@ -130,7 +130,9 @@ std::unique_ptr<InDet::ITRT_SeededSpacePointFinder::IEventData> InDet::SimpleTRT
 }
 
 std::list<std::pair<const Trk::SpacePoint*, const Trk::SpacePoint*> >
-InDet::SimpleTRT_SeededSpacePointFinder_ATL::find2Sp(const Trk::TrackParameters& directionTRT, InDet::ITRT_SeededSpacePointFinder::IEventData &) const
+InDet::SimpleTRT_SeededSpacePointFinder_ATL::find2Sp(const EventContext& ctx,
+                                                     const Trk::TrackParameters& directionTRT,
+                                                     InDet::ITRT_SeededSpacePointFinder::IEventData &) const
 {
   /** The main method. This method is called from outside to form pairs of SCT SpacePoints which could seed
       Si tracks linked to the TRT TrackParameter given as input. iModus is a dummy variable to satisfy the 
@@ -176,7 +178,7 @@ InDet::SimpleTRT_SeededSpacePointFinder_ATL::find2Sp(const Trk::TrackParameters&
 
       // fill the map of relevant SP as defined by hashes from ROI
       int modulTRT = TRT_Module(directionTRT);
-      getSpacePointsInROI(setOfSCT_Hashes, modulTRT, relevantSpacePoints);
+      getSpacePointsInROI(ctx, setOfSCT_Hashes, modulTRT, relevantSpacePoints);
 
       msg(MSG::VERBOSE) << "Retrieved " << relevantSpacePoints.size() << " potentially interesting SpacePoints" << endmsg;
 
@@ -252,7 +254,10 @@ void InDet::SimpleTRT_SeededSpacePointFinder_ATL::getHashesInROI(const Trk::Trac
 
 //=====================================================================================================
 
-void InDet::SimpleTRT_SeededSpacePointFinder_ATL::getSpacePointsInROI(std::set<IdentifierHash>& setOfSCT_Hashes, int modulTRT, std::multimap<int,const Trk::SpacePoint*>& relevantSpacePoints) const
+void InDet::SimpleTRT_SeededSpacePointFinder_ATL::getSpacePointsInROI(const EventContext& ctx,
+                                                                      std::set<IdentifierHash>& setOfSCT_Hashes,
+                                                                      int modulTRT, std::multimap<int,
+                                                                      const Trk::SpacePoint*>& relevantSpacePoints) const
 {
   /** This method retrieves the SpacePoints in a given region of interest. The region of interest is defined by the hashes in the first argument of the method.
 
@@ -276,7 +281,7 @@ void InDet::SimpleTRT_SeededSpacePointFinder_ATL::getSpacePointsInROI(std::set<I
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -284,7 +289,7 @@ void InDet::SimpleTRT_SeededSpacePointFinder_ATL::getSpacePointsInROI(std::set<I
   }
 
   // retrieve SP Container
-  SG::ReadHandle<SpacePointContainer> spacepointsSCT(m_spacepointsSCTname);
+  SG::ReadHandle<SpacePointContainer> spacepointsSCT(m_spacepointsSCTname, ctx);
   if(spacepointsSCT.isValid()) 
     {
       // loop over SP collections in SP container
@@ -361,7 +366,7 @@ void InDet::SimpleTRT_SeededSpacePointFinder_ATL::getSpacePointsInROI(std::set<I
     }
 
   // retrieve the overlap collection
-  SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap(m_spacepointsOverlapname);
+  SG::ReadHandle<SpacePointOverlapCollection> spacepointsOverlap(m_spacepointsOverlapname, ctx);
   if(spacepointsOverlap.isValid()) 
     {
 
diff --git a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/src/TRT_SeededSpacePointFinder_ATL.cxx b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/src/TRT_SeededSpacePointFinder_ATL.cxx
index fa87308381a62fa4e3b89229132bc33d416cac82..88bdb9da11bf66dd8205d7a1f76fa528d1ad8629 100755
--- a/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/src/TRT_SeededSpacePointFinder_ATL.cxx
+++ b/InnerDetector/InDetRecTools/TRT_SeededSpacePointFinderTool/src/TRT_SeededSpacePointFinder_ATL.cxx
@@ -114,6 +114,9 @@ StatusCode InDet::TRT_SeededSpacePointFinder_ATL::initialize()
   // PRD-to-track association (optional)
   ATH_CHECK( m_prdToTrackMap.initialize( !m_prdToTrackMap.key().empty()));
 
+  ////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize());
+  ////////////////////////////////////////////////////////////////////////////////
   StatusCode sc = detStore()->retrieve(m_sctId, "SCT_ID");
   if (sc.isFailure()){
     msg(MSG::FATAL) << "Could not get SCT_ID helper !" << endmsg;
@@ -360,7 +363,8 @@ std::unique_ptr<InDet::ITRT_SeededSpacePointFinder::IEventData> InDet::TRT_Seede
 ///////////////////////////////////////////////////////////////////
 
 std::list<std::pair<const Trk::SpacePoint*, const Trk::SpacePoint*> >
-InDet::TRT_SeededSpacePointFinder_ATL::find2Sp(const Trk::TrackParameters& tP,
+InDet::TRT_SeededSpacePointFinder_ATL::find2Sp(const EventContext& ctx,
+                                               const Trk::TrackParameters& tP,
                                                ITRT_SeededSpacePointFinder::IEventData &virt_event_data) const
 {
   InDet::TRT_SeededSpacePointFinder_ATL::EventData &event_data = EventData::getPrivateEventData(virt_event_data);
@@ -381,7 +385,7 @@ InDet::TRT_SeededSpacePointFinder_ATL::find2Sp(const Trk::TrackParameters& tP,
     f -= event_data.m_fNmax;
 
 
-  production2Spb (tP,f, outputListBuffer,event_data); //Get a list of SP pairs.
+  production2Spb (ctx, tP,f, outputListBuffer,event_data); //Get a list of SP pairs.
 
   if(msgLvl(MSG::DEBUG)) {
      dumpEvent( msg(MSG::DEBUG), event_data);
@@ -693,7 +697,8 @@ rotrating(double y, double x) {
 }
 
 void
-InDet::TRT_SeededSpacePointFinder_ATL::production2Spb(const Trk::TrackParameters& tP,
+InDet::TRT_SeededSpacePointFinder_ATL::production2Spb(const EventContext& ctx,
+                                                      const Trk::TrackParameters& tP,
                                                       int phi,
                                                       std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> > &outputListBuffer,
                                                       InDet::TRT_SeededSpacePointFinder_ATL::EventData &event_data) const
@@ -739,8 +744,22 @@ InDet::TRT_SeededSpacePointFinder_ATL::production2Spb(const Trk::TrackParameters
   double x0=tP.position().x()  ; 
   double y0=tP.position().y()  ;
   double z0=tP.position().z()  ;
-  double H[3]; double gP[3] = {x0,y0,z0}; 
-  m_fieldService->getField(gP,H);
+  double H[3]; double gP[3] = {x0,y0,z0};
+
+  MagField::AtlasFieldCache    fieldCache;
+
+  // Get field cache object
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+    ATH_MSG_ERROR("production2Spb: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+    return;
+  }
+  fieldCondObj->getInitializedCache (fieldCache);
+
+  //   MT version uses cache, temporarily keep old version
+  if (fieldCache.useNewBfieldCache()) fieldCache.getField     (gP, H);
+  else                                m_fieldService->getField(gP, H);
 
   //need conversion kilotesla -> kilogauss - Previously used getMagneticFiledKiloGauss, whereas new function returns value in kiloTesla...
   H[0] *= 10000;
diff --git a/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/TRT_SeededTrackFinderTool/TRT_SeededTrackFinder_ATL.h b/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/TRT_SeededTrackFinderTool/TRT_SeededTrackFinder_ATL.h
index 2e12169cf55bcaa624926c7f09660fa78250c612..4fa11a5e309b0bea8a53b46a1f604dfcc7e5b09c 100755
--- a/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/TRT_SeededTrackFinderTool/TRT_SeededTrackFinder_ATL.h
+++ b/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/TRT_SeededTrackFinderTool/TRT_SeededTrackFinder_ATL.h
@@ -37,6 +37,12 @@
 #include "TrkGeometry/MagneticFieldProperties.h"
 #include "MagFieldInterfaces/IMagFieldSvc.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 //Si Tools
 //
 #include "TRT_SeededTrackFinderTool/SiNoise_bt.h"
@@ -99,14 +105,14 @@ namespace InDet{
       ///////////////////////////////////////////////////////////////////
 
       /** Main method. Calls private methods and returns a list of Si tracks */
-      virtual std::list<Trk::Track*> getTrack (InDet::ITRT_SeededTrackFinder::IEventData &event_data,
+      virtual std::list<Trk::Track*> getTrack (const EventContext& ctx, InDet::ITRT_SeededTrackFinder::IEventData &event_data,
                                                const Trk::TrackSegment&) const override;
       /** New event initialization */
       virtual std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData>
-         newEvent(SiCombinatorialTrackFinderData_xk& combinatorialData) const override;
+         newEvent(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& combinatorialData) const override;
       /** New region intialization */
       virtual std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData>
-         newRegion(SiCombinatorialTrackFinderData_xk& combinatorialData,
+         newRegion(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& combinatorialData,
                    const std::vector<IdentifierHash>&,const std::vector<IdentifierHash>&) const override;
       /** End of event tasks       */
       virtual void endEvent(InDet::ITRT_SeededTrackFinder::IEventData &event_data) const override;
@@ -171,6 +177,7 @@ namespace InDet{
       ToolHandle<Trk::IUpdator>                      m_updatorTool;  /** Updator tool        */
       ToolHandle<InDet::ISiCombinatorialTrackFinder> m_tracksfinder; /** Combinatorial track finder tool */
 
+      SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
 
       /**ID TRT helper*/
       const TRT_ID* m_trtId;
@@ -207,7 +214,8 @@ namespace InDet{
                                                                     InDet::TRT_SeededTrackFinder_ATL::EventData &event_data) const;
 
       /** Find the corresponding list of Si tracks  */
-      std::list<Trk::Track*>                                 findTrack(InDet::TRT_SeededTrackFinder_ATL::EventData &event_data,
+      std::list<Trk::Track*>                                 findTrack(const EventContext& ctx,
+                                                                       InDet::TRT_SeededTrackFinder_ATL::EventData &event_data,
                                                                        const Trk::TrackParameters*,const Trk::TrackSegment&) const;
 
       /** Add material effects   */
diff --git a/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/src/TRT_SeededTrackFinder_ATL.cxx b/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/src/TRT_SeededTrackFinder_ATL.cxx
index 70a24ccc172ca4d14e7f2f932e5dd304bcd9c0c0..426710907a9c519d48dc017af3c789e91d876027 100755
--- a/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/src/TRT_SeededTrackFinder_ATL.cxx
+++ b/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/src/TRT_SeededTrackFinder_ATL.cxx
@@ -168,6 +168,11 @@ StatusCode InDet::TRT_SeededTrackFinder_ATL::initialize()
   
   magneticFieldInit();
 
+  ////////////////////////////////////////////////////////////////////////////////
+  ATH_CHECK( m_fieldCondObjInputKey.initialize());
+  ////////////////////////////////////////////////////////////////////////////////
+
+  
   // Get propagator tool
   //
   if(m_proptool.retrieve().isFailure()) {
@@ -328,7 +333,7 @@ std::ostream& InDet::TRT_SeededTrackFinder_ATL::dump( std::ostream& out ) const
 ///////////////////////////////////////////////////////////////////
 
 std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData>
-InDet::TRT_SeededTrackFinder_ATL::newEvent(SiCombinatorialTrackFinderData_xk& combinatorialData) const
+InDet::TRT_SeededTrackFinder_ATL::newEvent(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& combinatorialData) const
 {
 
   ///Get the seeds
@@ -337,7 +342,7 @@ InDet::TRT_SeededTrackFinder_ATL::newEvent(SiCombinatorialTrackFinderData_xk& co
                                                                                   m_seedmaker->newEvent());
   // New event for track finder tool
   //
-  m_tracksfinder->newEvent(event_data_p->combinatorialData());
+  m_tracksfinder->newEvent(ctx, event_data_p->combinatorialData());
 
 
   // Print event information 
@@ -351,7 +356,7 @@ InDet::TRT_SeededTrackFinder_ATL::newEvent(SiCombinatorialTrackFinderData_xk& co
   if(m_searchInCaloROI ) {
 
 
-    SG::ReadHandle<CaloClusterROI_Collection> calo(m_inputClusterContainerName);
+    SG::ReadHandle<CaloClusterROI_Collection> calo(m_inputClusterContainerName, ctx);
 
     if (calo.isValid()) {
        event_data_p->caloF().reserve( calo->size());
@@ -373,7 +378,7 @@ InDet::TRT_SeededTrackFinder_ATL::newEvent(SiCombinatorialTrackFinderData_xk& co
 
 ///////////////////////////////////////////////////////////////////////
 std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData>
-InDet::TRT_SeededTrackFinder_ATL::newRegion(SiCombinatorialTrackFinderData_xk& combinatorialData,
+InDet::TRT_SeededTrackFinder_ATL::newRegion(const EventContext& ctx, SiCombinatorialTrackFinderData_xk& combinatorialData,
                                             const std::vector<IdentifierHash>& listOfPixIds,
                                             const std::vector<IdentifierHash>& listOfSCTIds) const
 {
@@ -383,7 +388,7 @@ InDet::TRT_SeededTrackFinder_ATL::newRegion(SiCombinatorialTrackFinderData_xk& c
 
   // New event for track finder tool
   //
-  m_tracksfinder->newEvent(event_data_p->combinatorialData());
+  m_tracksfinder->newEvent(ctx, event_data_p->combinatorialData());
 
 
   // Print event information
@@ -413,7 +418,8 @@ void InDet::TRT_SeededTrackFinder_ATL::endEvent(InDet::ITRT_SeededTrackFinder::I
 // starting from an intial track segment
 ///////////////////////////////////////////////////////////////////
 
-std::list<Trk::Track*> InDet::TRT_SeededTrackFinder_ATL::getTrack(InDet::ITRT_SeededTrackFinder::IEventData &virt_event_data,
+std::list<Trk::Track*> InDet::TRT_SeededTrackFinder_ATL::getTrack(const EventContext& ctx,
+                                                                  InDet::ITRT_SeededTrackFinder::IEventData &virt_event_data,
                                                                   const Trk::TrackSegment& tS) const
 {
   InDet::TRT_SeededTrackFinder_ATL::EventData &event_data = EventData::getPrivateEventData(virt_event_data);
@@ -463,7 +469,7 @@ std::list<Trk::Track*> InDet::TRT_SeededTrackFinder_ATL::getTrack(InDet::ITRT_Se
   }
 
 
-  aSiTrack = findTrack(event_data, newPerPar.get(), tS);
+  aSiTrack = findTrack(ctx, event_data, newPerPar.get(), tS);
   if((aSiTrack.size()==0)&&(m_bremCorrect)){
     if(msgLvl(MSG::DEBUG)) {
       msg(MSG::DEBUG) << "==============================================================" << endmsg;
@@ -474,7 +480,7 @@ std::list<Trk::Track*> InDet::TRT_SeededTrackFinder_ATL::getTrack(InDet::ITRT_Se
       msg(MSG::VERBOSE) << "Modified TRT Track Parameters for brem. " << endmsg;
       msg(MSG::VERBOSE) << (*modTP) << endmsg;
     }
-    aSiTrack = findTrack(event_data, modTP, tS);
+    aSiTrack = findTrack(ctx, event_data, modTP, tS);
     delete modTP;
     if(aSiTrack.size()==0){
       if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG)<<"Could not create track states on surface for this track after all!"<<endmsg;
@@ -493,8 +499,10 @@ std::list<Trk::Track*> InDet::TRT_SeededTrackFinder_ATL::getTrack(InDet::ITRT_Se
 ///////////////////////////////////////////////////////////////////
 
 std::list<Trk::Track*> InDet::TRT_SeededTrackFinder_ATL::findTrack
-(InDet::TRT_SeededTrackFinder_ATL::EventData &event_data,
- const Trk::TrackParameters* initTP,const Trk::TrackSegment& tS) const
+(const EventContext& ctx,
+ InDet::TRT_SeededTrackFinder_ATL::EventData &event_data,
+ const Trk::TrackParameters* initTP,
+ const Trk::TrackSegment& tS) const
 {
   SiCombinatorialTrackFinderData_xk& combinatorialData=event_data.combinatorialData();
   //Return list copied by value (fix!!) 
@@ -503,11 +511,23 @@ std::list<Trk::Track*> InDet::TRT_SeededTrackFinder_ATL::findTrack
   
   //Get the seeds
   std::list<std::pair<const Trk::SpacePoint*,const Trk::SpacePoint*> >
-     SpE = m_seedmaker->find2Sp(*initTP,event_data.spacePointFinderEventData());                //Get a list of SP pairs
+      SpE = m_seedmaker->find2Sp(ctx, *initTP,event_data.spacePointFinderEventData());                //Get a list of SP pairs
 
   if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "---------------> SP SEED LIST SIZE " << SpE.size() << endmsg;
   if(SpE.size()==0){return associatedSiTrack;}
 
+  // Get AtlasFieldCache
+  MagField::AtlasFieldCache fieldCache;
+
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("InDet::SiTrackMaker_xk::getTracks: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return associatedSiTrack;
+  }
+  fieldCondObj->getInitializedCache (fieldCache);
+  
+  
   //
   // --------------- loop over the found seeds
   //
@@ -677,7 +697,7 @@ std::list<Trk::Track*> InDet::TRT_SeededTrackFinder_ATL::findTrack
 
     //Get list of InDet Elements
     std::list<const InDetDD::SiDetectorElement*> DE;
-    m_roadmaker->detElementsRoad(*per,Trk::alongMomentum,DE);
+    m_roadmaker->detElementsRoad(ctx, fieldCache, *per,Trk::alongMomentum,DE);
     delete per;
     if( int(DE.size()) < m_nclusmin){ //Not enough detector elements to satisfy the minimum number of clusters requirement. Stop
       if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Too few detector elements, not expected" << endmsg;
diff --git a/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/CMakeLists.txt b/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/CMakeLists.txt
index 7d8884c32b73244ff819f97fea6e880ef15bc855..0a359dbd9b2033b2130895d9646a67eb3d314f0e 100644
--- a/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/CMakeLists.txt
@@ -19,13 +19,16 @@ atlas_depends_on_subdirs( PUBLIC
                           Tracking/TrkExtrapolation/TrkExInterfaces
                           Tracking/TrkFitter/TrkFitterInterfaces
                           Tracking/TrkTools/TrkToolInterfaces
-			  Tracking/TrkDetDescr/TrkSurfaces)
+			  Tracking/TrkDetDescr/TrkSurfaces
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions
+			  )
 
 # Component(s) in the package:
 atlas_add_component( TRT_SegmentToTrackTool
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetRecToolInterfaces TrkEventPrimitives InDetIdentifier InDetRIO_OnTrack MagFieldInterfaces TrkPseudoMeasurementOnTrack TrkExInterfaces TrkFitterInterfaces TrkToolInterfaces )
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetRecToolInterfaces TrkEventPrimitives InDetIdentifier InDetRIO_OnTrack MagFieldInterfaces TrkPseudoMeasurementOnTrack TrkExInterfaces TrkFitterInterfaces TrkToolInterfaces MagFieldElements MagFieldConditions)
 
 # Install files from the package:
 atlas_install_headers( TRT_SegmentToTrackTool )
diff --git a/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/TRT_SegmentToTrackTool/TRT_SegmentToTrackTool.h b/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/TRT_SegmentToTrackTool/TRT_SegmentToTrackTool.h
index c539ed8d3489ec9eb52600f85d436e66b4cd5ca9..37374984bd1edd067e376e5c6031dccd7d83897d 100644
--- a/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/TRT_SegmentToTrackTool/TRT_SegmentToTrackTool.h
+++ b/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/TRT_SegmentToTrackTool/TRT_SegmentToTrackTool.h
@@ -27,8 +27,15 @@
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "InDetRecToolInterfaces/ITRT_SegmentToTrackTool.h"
 #include "TrkToolInterfaces/IPRDtoTrackMapTool.h"
+#include "TrkEventPrimitives/TrackScore.h"
 #include "TrkToolInterfaces/IExtendedTrackSummaryTool.h"
 
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 #include <string>
 
 class MsgStream;
@@ -73,7 +80,7 @@ namespace InDet {
       virtual StatusCode initialize() override;
       virtual StatusCode finalize() override;
 
-      virtual Trk::Track* segToTrack(const Trk::TrackSegment&) const override;
+      virtual Trk::Track* segToTrack(const EventContext& ctx, const Trk::TrackSegment&) const override;
       /** Check if the TRT segment has already been assigned a Si extension  */
       virtual bool segIsUsed(const Trk::TrackSegment&,
                              const Trk::PRDtoTrackMap *prd_to_track_map) const override;
@@ -106,6 +113,13 @@ namespace InDet {
       ToolHandle<Trk::ITrackScoringTool>     m_scoringTool   ;  //!< Track scoring tool
       ServiceHandle<MagField::IMagFieldSvc>  m_magFieldSvc  ;  //!< Magnetic field service
 
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+      // Read handle for conditions object to get the field cache
+      SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj",
+                                                                           "Name of the Magnetic Field conditions object key"};
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
       /**ID TRT helper*/
       const TRT_ID* m_trtId;
 
diff --git a/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/src/TRT_SegmentToTrackTool.cxx b/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/src/TRT_SegmentToTrackTool.cxx
index 97d81a875c42ec06c08b63367f8f9a64a5f5954b..77d6dadc382105e9247ea0e2ded06c17ee0ec2a0 100644
--- a/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/src/TRT_SegmentToTrackTool.cxx
+++ b/InnerDetector/InDetRecTools/TRT_SegmentToTrackTool/src/TRT_SegmentToTrackTool.cxx
@@ -85,6 +85,9 @@ namespace InDet {
     ATH_CHECK( m_magFieldSvc.retrieve() );
 
     ATH_CHECK( detStore()->retrieve(m_trtId, "TRT_ID") );
+    ////////////////////////////////////////////////////////////////////////////////
+    ATH_CHECK( m_fieldCondObjInputKey.initialize());
+    ////////////////////////////////////////////////////////////////////////////////
 
     // Get output print level
     //
@@ -151,7 +154,7 @@ namespace InDet {
   }
 
 
-  Trk::Track* TRT_SegmentToTrackTool::segToTrack(const Trk::TrackSegment& tS) const {
+  Trk::Track* TRT_SegmentToTrackTool::segToTrack(const EventContext& ctx, const Trk::TrackSegment& tS) const {
 
 
     ATH_MSG_DEBUG ("Transforming the TRT segment into a track...");
@@ -292,7 +295,6 @@ namespace InDet {
 	  }
 	  // remember oldphi
 	  oldphi=tmpphi;
-	  //std::cout << "oldphi: " << oldphi << " tmpphi: " << tmpphi << std::endl;
 	
 	  // copy the points
 	  points.push_back(std::make_pair(tS.measurement(it)->associatedSurface().center().z(),tmpphi));
@@ -404,7 +406,6 @@ namespace InDet {
 	d             = (points.size()*sxx-sx*sx);
 	double dphidz = ((points.size()*sxy-sy*sx)/d);
 	myqoverp      = (fabs(pseudotheta)>1e-6) ? -dphidz/(0.6*tan(pseudotheta)) : 1000.;
-	// std::cout << "pt: " << sin(pseudotheta)/myqoverp << std::endl;    
 
 	// some geometry stuff to estimate further paramters...
 	double halfz  = 200.;
@@ -423,7 +424,6 @@ namespace InDet {
 	// ME: this is hardcoding, not nice and should be fixed
 	if (fabs(lastsurf->center().z())<2650*mm) {
 	  pos2 = lastsurf->center()+halfz2*strawdir2;
-	  //std::cout << "pos2: " << pos2 << std::endl;
 	  if (nbarrel==0){
 	    double dr = fabs(tan(pseudotheta)*(lastsurf->center().z()-firstsurf->center().z()));
 	    pos1      = firstsurf->center()+(halfz-dr)*strawdir1; 
@@ -458,7 +458,22 @@ namespace InDet {
 	}
 
 	Amg::Vector3D field1;
-	m_magFieldSvc->getField(Amg::Vector3D(.5*(pos1+pos2)).data(),field1.data());
+
+        MagField::AtlasFieldCache    fieldCache;
+
+        // Get field cache object
+        SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+        const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+        if (fieldCondObj == nullptr) {
+            ATH_MSG_ERROR("segToTrack: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+            return 0;
+        }
+        fieldCondObj->getInitializedCache (fieldCache);
+
+        //   MT version uses cache, temporarily keep old version
+        if (fieldCache.useNewBfieldCache()) fieldCache.getField    (Amg::Vector3D(.5*(pos1+pos2)).data(),field1.data());
+        else                                m_magFieldSvc->getField(Amg::Vector3D(.5*(pos1+pos2)).data(),field1.data());
+
 	field1 *= m_fieldUnitConversion; // field in Tesla
 
 	double phideflection = -.3*(pos2-pos1).perp()*field1.z()*myqoverp/sin(pseudotheta);
@@ -478,7 +493,6 @@ namespace InDet {
 	Trk::AtaStraightLine ataline(((nbarrel==0) ? pos1 : pos2),precisephi,precisetheta,myqoverp,*surfforpar);
 	Trk::PerigeeSurface persurf;
 	const Trk::TrackParameters *extrappar=m_extrapolator->extrapolateDirectly(ataline,persurf);
-	//std::cout << "ataline: " << ataline << " extrap par: " << *extrappar << std::endl;
 
 	// now get parameters
 	if (extrappar){
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/CMakeLists.txt b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/CMakeLists.txt
index a73a907f6f59f2cf885932898266cd751df8c087..d0219a51dd68d54d6d206e2735c2ad3bc6999fa8 100644
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/CMakeLists.txt
@@ -24,13 +24,16 @@ atlas_depends_on_subdirs( PUBLIC
                           Tracking/TrkEvent/TrkMeasurementBase
                           Tracking/TrkEvent/TrkTrack
                           Tracking/TrkExtrapolation/TrkExInterfaces
-                          Tracking/TrkTools/TrkToolInterfaces )
+                          Tracking/TrkTools/TrkToolInterfaces
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions
+			  )
 
 # Component(s) in the package:
 atlas_add_component( TRT_TrackExtensionTool_DAF
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetPrepRawData InDetRecToolInterfaces TrkGeometry TrkParameters StoreGateLib SGtests InDetIdentifier InDetReadoutGeometry TRT_ReadoutGeometry MagFieldInterfaces TrkMeasurementBase TrkTrack TrkExInterfaces TrkToolInterfaces )
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetPrepRawData InDetRecToolInterfaces TrkGeometry TrkParameters StoreGateLib SGtests InDetIdentifier InDetReadoutGeometry TRT_ReadoutGeometry MagFieldInterfaces TrkMeasurementBase TrkTrack TrkExInterfaces TrkToolInterfaces MagFieldElements MagFieldConditions )
 
 # Install files from the package:
 atlas_install_headers( TRT_TrackExtensionTool_DAF )
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/TRT_TrackExtensionTool_DAF/TRT_TrackExtensionTool_DAF.h b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/TRT_TrackExtensionTool_DAF/TRT_TrackExtensionTool_DAF.h
index 3cd8a96ca4fc31998b1b348ae277e29570719bd8..43fff203a7791caf8554bf519be295223c542e7a 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/TRT_TrackExtensionTool_DAF/TRT_TrackExtensionTool_DAF.h
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/TRT_TrackExtensionTool_DAF/TRT_TrackExtensionTool_DAF.h
@@ -28,6 +28,10 @@
 #include "TrkEventUtils/EventDataBase.h"
 #include "TrkGeometry/MagneticFieldProperties.h"
 
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+
 class MsgStream;
 class TRT_ID;
 
@@ -76,23 +80,27 @@ public:
     ///////////////////////////////////////////////////////////////////
 
     virtual std::vector<const Trk::MeasurementBase*>&
-       extendTrack(const Trk::Track&,
+       extendTrack(const EventContext& ctx,
+                   const Trk::Track&,
                    InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
 
     virtual std::vector<const Trk::MeasurementBase*>&
-       extendTrack(const Trk::TrackParameters&,
+       extendTrack(const EventContext& ctx,
+                   const Trk::TrackParameters&,
                    InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
 
     virtual Trk::Track*
-       newTrack(const Trk::Track&,
+       newTrack(const EventContext& ctx,
+                const Trk::Track&,
                 InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
 
-    virtual std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> newEvent() const override;
+    virtual std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> newEvent(const EventContext& ctx) const override;
     ///////////////////////////////////////////////////////////////////
     // TRT seed extension to TRT  
     ///////////////////////////////////////////////////////////////////
 
-    virtual Trk::TrackSegment* findSegment(const Trk::TrackParameters&,
+    virtual Trk::TrackSegment* findSegment(const EventContext& ctx,
+                                           const Trk::TrackParameters&,
                                            InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
 
     ///////////////////////////////////////////////////////////////////
@@ -145,7 +153,10 @@ protected:
 
     ToolHandle< Trk::IPropagator >                                  m_propagator;           //!<  the Propagator tool
 
-    ServiceHandle<MagField::IMagFieldSvc>  m_fieldServiceHandle; 
+    ServiceHandle<MagField::IMagFieldSvc>                           m_fieldServiceHandle; 
+
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj>                   m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
+        
 
     std::string                                                     m_fieldmode;          //!< jobOption: Magnetic field mode
     Trk::MagneticFieldProperties                                    m_fieldprop;            //!< Magnetic field properties
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/src/TRT_TrackExtensionTool_DAF.cxx b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/src/TRT_TrackExtensionTool_DAF.cxx
index 85fcb5924d68ce0bfe4c66fee2d57a99680759d9..c7fa745fdcd02877344b53cfea0d0446c34bd0d1 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/src/TRT_TrackExtensionTool_DAF.cxx
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_DAF/src/TRT_TrackExtensionTool_DAF.cxx
@@ -146,6 +146,10 @@ StatusCode InDet::TRT_TrackExtensionTool_DAF::initialize() {
 
     ATH_CHECK( m_jo_trtcontainername.initialize());
 
+    ////////////////////////////////////////////////////////////////////////////////
+    ATH_CHECK( m_fieldCondObjInputKey.initialize());
+    ////////////////////////////////////////////////////////////////////////////////
+
     return StatusCode::SUCCESS;
 }
 
@@ -272,10 +276,10 @@ std::ostream& InDet::TRT_TrackExtensionTool_DAF::dump( std::ostream& out ) const
 // Track extension init for a new event
 ///////////////////////////////////////////////////////////////////
 std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData>
-InDet::TRT_TrackExtensionTool_DAF::newEvent() const {
+InDet::TRT_TrackExtensionTool_DAF::newEvent(const EventContext& ctx) const {
     // -----------
     // get the container with TRT RIOs
-   SG::ReadHandle<TRT_DriftCircleContainer> trtcontainer(m_jo_trtcontainername);
+   SG::ReadHandle<TRT_DriftCircleContainer> trtcontainer(m_jo_trtcontainername, ctx);
 
    if((not trtcontainer.isValid())) {
       std::stringstream msg;
@@ -294,7 +298,8 @@ InDet::TRT_TrackExtensionTool_DAF::newEvent() const {
 // Main methods for track extension to TRT
 ///////////////////////////////////////////////////////////////////
 std::vector<const Trk::MeasurementBase*>&
-InDet::TRT_TrackExtensionTool_DAF::extendTrack(const Trk::Track& track,
+InDet::TRT_TrackExtensionTool_DAF::extendTrack(const EventContext& ctx,
+                                               const Trk::Track& track,
                                                InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const
 {
   InDet::TRT_TrackExtensionTool_DAF::EventData &
@@ -316,12 +321,13 @@ InDet::TRT_TrackExtensionTool_DAF::extendTrack(const Trk::Track& track,
         }
     }
     // call main function
-    return extendTrack(*trackPar,event_data);
+    return extendTrack(ctx, *trackPar,event_data);
 }
 
 
 std::vector<const Trk::MeasurementBase*>&
-InDet::TRT_TrackExtensionTool_DAF::extendTrack(const Trk::TrackParameters& trackPar,
+InDet::TRT_TrackExtensionTool_DAF::extendTrack(const EventContext& ctx,
+                                               const Trk::TrackParameters& trackPar,
                                                InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const
 {
    InDet::TRT_TrackExtensionTool_DAF::EventData &
@@ -351,10 +357,24 @@ InDet::TRT_TrackExtensionTool_DAF::extendTrack(const Trk::TrackParameters& track
     event_data.m_siliconTrkParams = &trackPar;
 
     ATH_MSG_DEBUG("starting TRT detector elements road maker with initial TrackParemeters: "<< *event_data.m_siliconTrkParams );
+
+
+    // Get AtlasFieldCache
+    MagField::AtlasFieldCache fieldCache;
+
+    SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+    const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+    if (fieldCondObj == nullptr) {
+        ATH_MSG_ERROR("InDet::TRT_TrackExtensionTool_xk::findSegment: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+    }
+    fieldCondObj->getInitializedCache (fieldCache);
+
+    
+
     // ----------------------------------
     // start the TRT detector elements road maker to get a list of possibly interesting detector elements
     std::vector<const InDetDD::TRT_BaseElement*> detElements;
-    m_roadtool->detElementsRoad(*event_data.m_siliconTrkParams, Trk::alongMomentum, detElements);
+    m_roadtool->detElementsRoad(ctx, fieldCache, *event_data.m_siliconTrkParams, Trk::alongMomentum, detElements);
 
     ATH_MSG_DEBUG("TRT detector elements road maker found "<< detElements.size()<< " detElements" );
 
@@ -900,7 +920,8 @@ InDet::TRT_TrackExtensionTool_DAF::groupedBarrelExtension(int beginIndex,
 // Main methods for segment finding in TRT
 ///////////////////////////////////////////////////////////////////
 Trk::TrackSegment*
-InDet::TRT_TrackExtensionTool_DAF::findSegment(const Trk::TrackParameters&,
+InDet::TRT_TrackExtensionTool_DAF::findSegment(const EventContext& /*ctx*/,
+                                               const Trk::TrackParameters&,
                                                InDet::ITRT_TrackExtensionTool::IEventData &) const
 {
     return 0;
@@ -911,7 +932,8 @@ InDet::TRT_TrackExtensionTool_DAF::findSegment(const Trk::TrackParameters&,
 ///////////////////////////////////////////////////////////////////
 
 Trk::Track*
-InDet::TRT_TrackExtensionTool_DAF::newTrack(const Trk::Track&,
+InDet::TRT_TrackExtensionTool_DAF::newTrack(const EventContext& /*ctx*/,
+                                            const Trk::Track&,
                                             InDet::ITRT_TrackExtensionTool::IEventData &) const
 {
   return 0;
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/CMakeLists.txt b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/CMakeLists.txt
index 9f33791a8900ae6c1762e73bfb3ac1e911924d56..6f0286702031aaa6c3564a1094fa29921f64eb60 100644
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/CMakeLists.txt
@@ -28,13 +28,15 @@ atlas_depends_on_subdirs( PUBLIC
                           InnerDetector/InDetRecEvent/InDetRIO_OnTrack
                           Tracking/TrkDetDescr/TrkSurfaces
                           Tracking/TrkEvent/TrkRIO_OnTrack
-                          Tracking/TrkEvent/TrkTrack )
+                          Tracking/TrkEvent/TrkTrack
+                          MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions)
 
 # Component(s) in the package:
 atlas_add_component( TRT_TrackExtensionTool_xk
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetReadoutGeometry TRT_ReadoutGeometry InDetPrepRawData InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkEventPrimitives TrkPatternParameters TrkPseudoMeasurementOnTrack TrkSegment TrkExInterfaces TrkToolInterfaces AthenaPoolUtilities InDetRIO_OnTrack TrkSurfaces TrkRIO_OnTrack TrkTrack )
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel InDetReadoutGeometry TRT_ReadoutGeometry InDetPrepRawData InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkEventPrimitives TrkPatternParameters TrkPseudoMeasurementOnTrack TrkSegment TrkExInterfaces TrkToolInterfaces AthenaPoolUtilities InDetRIO_OnTrack TrkSurfaces TrkRIO_OnTrack TrkTrack MagFieldElements MagFieldConditions)
 
 # Install files from the package:
 atlas_install_headers( TRT_TrackExtensionTool_xk )
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrackExtensionToolCosmics.h b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrackExtensionToolCosmics.h
index b5213ba19ca07c28c515bc73190a62652140f214..c5e03a4be1c34637ee5d55cd91cfdd08f7551ee8 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrackExtensionToolCosmics.h
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrackExtensionToolCosmics.h
@@ -72,22 +72,26 @@ namespace InDet {
       ///////////////////////////////////////////////////////////////////
 
       virtual std::vector<const Trk::MeasurementBase*>& extendTrack
-         (const Trk::Track&,
+         (const EventContext& ctx,
+          const Trk::Track&,
           InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
 
       virtual std::vector<const Trk::MeasurementBase*>& extendTrack
-         (const Trk::TrackParameters&,
+         (const EventContext& ctx,
+          const Trk::TrackParameters&,
           InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
 
       virtual Trk::TrackSegment* findSegment
-	 (const Trk::TrackParameters&,
+	 (const EventContext& ctx,
+          const Trk::TrackParameters&,
           InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
 
       virtual Trk::Track* newTrack
-         (const Trk::Track&,
+         (const EventContext& ctx,
+          const Trk::Track&,
           InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
 
-      virtual std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> newEvent() const override;
+      virtual std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> newEvent(const EventContext& ctx) const override;
 
       ///////////////////////////////////////////////////////////////////
       // Print internal tool parameters and status
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk.h b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk.h
index 784a9afb5334b8d9de075d461c11153e0e97cef3..06db25aea0d98d76ff0811ef71310be9ed2e1d02 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk.h
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk.h
@@ -29,6 +29,10 @@
 #include <iosfwd>
 #include <vector>
 
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+
 class MsgStream;
 class TRT_ID;
 
@@ -70,14 +74,14 @@ namespace InDet{
       ///////////////////////////////////////////////////////////////////
       
       virtual std::vector<const Trk::MeasurementBase*>& extendTrack
-        (const Trk::Track&,InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
+        (const EventContext& ctx, const Trk::Track&,InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
       virtual std::vector<const Trk::MeasurementBase*>& extendTrack
-        (const Trk::TrackParameters&,InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
+        (const EventContext& ctx, const Trk::TrackParameters&,InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
       virtual Trk::TrackSegment* findSegment
-        (const Trk::TrackParameters&, InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
+        (const EventContext& ctx, const Trk::TrackParameters&, InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
       virtual Trk::Track* newTrack
-        (const Trk::Track&, InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
-      virtual std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> newEvent() const override;
+        (const EventContext& ctx, const Trk::Track&, InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const override;
+      virtual std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> newEvent(const EventContext& ctx) const override;
 
       ///////////////////////////////////////////////////////////////////
       // Print internal tool parameters and status
@@ -107,7 +111,8 @@ namespace InDet{
 
 
       std::vector<const Trk::MeasurementBase*>& extendTrackFromParameters
-      (const Trk::TrackParameters&,
+      (const EventContext& ctx,
+       const Trk::TrackParameters&,
        InDet::TRT_TrackExtensionTool_xk::EventData &event_data) const;
 
       ///////////////////////////////////////////////////////////////////
@@ -123,6 +128,9 @@ namespace InDet{
       ToolHandle<Trk::IRIO_OnTrackCreator>          m_riontrackD ; //
       ToolHandle<Trk::IRIO_OnTrackCreator>          m_riontrackN ; //
 
+      SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
+        
+        
       int                              m_segmentFindMode; // Method of segment find
       int                              m_outputlevel    ; // Print level
       int                              m_nprint         ; // Kind of print
@@ -148,7 +156,9 @@ namespace InDet{
 
       void       magneticFieldInit();
       StatusCode magneticFieldInit(IOVSVC_CALLBACK_ARGS);
-      bool isGoodExtension(const Trk::TrackParameters&, InDet::TRT_TrackExtensionTool_xk::EventData &event_data) const;
+      bool isGoodExtension(const EventContext& ctx,
+                           const Trk::TrackParameters&,
+                           InDet::TRT_TrackExtensionTool_xk::EventData &event_data) const;
       bool numberPIXandSCTclustersCut(const Trk::Track&) const;
 
       MsgStream&    dumpConditions(MsgStream   & out) const;
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrajectoryElement_xk.h b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrajectoryElement_xk.h
index f9983eae40625f8b6e4b6bf3b1ed4cd8087c6c3d..989f761123436c7e9b6b790452b553a75e922d4a 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrajectoryElement_xk.h
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_TrajectoryElement_xk.h
@@ -24,6 +24,9 @@
 #include "TrkToolInterfaces/IPatternParametersUpdator.h"
 #include "TrkExInterfaces/IPatternParametersPropagator.h"
 #include "TRT_TrackExtensionTool_xk/TRT_ExtensionDriftCircleLink_xk.h"
+// MagField cache
+#include "MagFieldElements/AtlasFieldCache.h"
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
 
 class TRT_ID;
 
@@ -68,7 +71,7 @@ namespace InDet{
          double                             );
 
       void set
-	(const Trk::MagneticFieldProperties&,const MagField::IMagFieldSvc*);
+      (const Trk::MagneticFieldProperties&,const MagField::IMagFieldSvc*, const AtlasFieldCacheCondObj* );
 
       bool initiateForPrecisionSeed     (bool,const InDetDD::TRT_BaseElement*&,
 					 InDet::TRT_DriftCircleCollection::const_iterator&,
@@ -145,6 +148,7 @@ namespace InDet{
       const Trk::IRIO_OnTrackCreator       *             m_riomakerN  ; 
       Trk::MagneticFieldProperties                       m_fieldprop  ;
       const MagField::IMagFieldSvc*                      m_fieldService;
+      MagField::AtlasFieldCache                          m_fieldCache;
 
       ///////////////////////////////////////////////////////////////////
       // Comments
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_Trajectory_xk.h b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_Trajectory_xk.h
index de29a145be1f5e0e860c9369d7f5bfe120bc8a07..ad95a509ecf617b7cc93019e2dd4a58dd78c1510 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_Trajectory_xk.h
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/TRT_TrackExtensionTool_xk/TRT_Trajectory_xk.h
@@ -19,6 +19,8 @@
 #include "TrkSegment/TrackSegment.h"
 #include "TrkPseudoMeasurementOnTrack/PseudoMeasurementOnTrack.h"
 #include "TRT_TrackExtensionTool_xk/TRT_TrajectoryElement_xk.h"
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
 
 namespace Trk {
   class Track;
@@ -71,7 +73,7 @@ namespace InDet{
 	       double,
                double);
 
-      void set(Trk::MagneticFieldProperties&,const MagField::IMagFieldSvc *);
+      void set(Trk::MagneticFieldProperties&,const MagField::IMagFieldSvc *, const AtlasFieldCacheCondObj*);
 
       void initiateForPrecisionSeed
 	(std::list< std::pair<Amg::Vector3D,double> >&,
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrackExtensionToolCosmics.cxx b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrackExtensionToolCosmics.cxx
index 802d2c4bb34817e95b5ceff393e92f28cf04a53b..d747cd18aca5461e244fa81c77b0ded7bb4e2dc2 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrackExtensionToolCosmics.cxx
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrackExtensionToolCosmics.cxx
@@ -204,11 +204,11 @@ std::ostream& InDet::operator <<
 ///////////////////////////////////////////////////////////////////
 
 std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData>
-InDet::TRT_TrackExtensionToolCosmics::newEvent() const
+InDet::TRT_TrackExtensionToolCosmics::newEvent(const EventContext& ctx) const
 {
   //create the boundary surfaces
   //
-  SG::ReadHandle<TRT_DriftCircleContainer> trtcontainer(m_trtname);
+  SG::ReadHandle<TRT_DriftCircleContainer> trtcontainer(m_trtname, ctx);
   if(not trtcontainer.isValid() && m_outputlevel<=0) {
     std::stringstream msg;
     msg << "Missing TRT_DriftCircleContainer " << m_trtname.key();
@@ -236,7 +236,8 @@ InDet::TRT_TrackExtensionToolCosmics::newEvent() const
 ///////////////////////////////////////////////////////////////////
 
 std::vector<const Trk::MeasurementBase*>& 
-InDet::TRT_TrackExtensionToolCosmics::extendTrack(const Trk::Track& Tr,
+InDet::TRT_TrackExtensionToolCosmics::extendTrack(const EventContext& ctx,
+                                                  const Trk::Track& Tr,
                                                   InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const
 { 
   InDet::TRT_TrackExtensionToolCosmics::EventData &
@@ -263,7 +264,7 @@ InDet::TRT_TrackExtensionToolCosmics::extendTrack(const Trk::Track& Tr,
   }
 
   if(Tr.perigeeParameters()) {
-     return extendTrack(*Tr.perigeeParameters(),event_data);
+    return extendTrack(ctx, *Tr.perigeeParameters(),event_data);
   }
   event_data.m_measurement.clear();
   return event_data.m_measurement;
@@ -395,7 +396,8 @@ class tp_sort_cosmics{
 ///////////////////////////////////////////////////////////////////
 
 std::vector<const Trk::MeasurementBase*>&
-InDet::TRT_TrackExtensionToolCosmics::extendTrack(const Trk::TrackParameters& par,
+InDet::TRT_TrackExtensionToolCosmics::extendTrack(const EventContext& /*ctx*/,
+                                                  const Trk::TrackParameters& par,
                                                   InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const
 {
   InDet::TRT_TrackExtensionToolCosmics::EventData &
@@ -410,19 +412,19 @@ InDet::TRT_TrackExtensionToolCosmics::extendTrack(const Trk::TrackParameters& pa
 
   std::vector<const Trk::TrackParameters* >* tpars_down=0;
   std::vector<const Trk::TrackParameters* >* tpars_up=0;
-const Trk::Perigee *per=dynamic_cast<const Trk::Perigee *>(&par);
+  const Trk::Perigee *per=dynamic_cast<const Trk::Perigee *>(&par);
   if (!per) {
     msg(MSG::FATAL)<<"Track perigee not found!"<<endmsg;
     return event_data.m_measurement;
   }
 
- if (!event_data.m_trtcontainer) {
+  if (!event_data.m_trtcontainer) {
     return event_data.m_measurement;
   }
 
-InDet::TRT_DriftCircleContainer::const_iterator
-   w = event_data.m_trtcontainer->begin(),we = event_data.m_trtcontainer->end();
-   for(; w!=we; ++w) {
+  InDet::TRT_DriftCircleContainer::const_iterator
+      w = event_data.m_trtcontainer->begin(),we = event_data.m_trtcontainer->end();
+  for(; w!=we; ++w) {
      if ((**w).empty()) continue; 
      const Trk::Surface &surf=(**(**w).begin()).detectorElement()->surface();
      Amg::Vector3D pos=intersect(&surf,per);
@@ -489,7 +491,8 @@ InDet::TRT_DriftCircleContainer::const_iterator
 ///////////////////////////////////////////////////////////////////
 
 Trk::TrackSegment* 
-InDet::TRT_TrackExtensionToolCosmics::findSegment(const Trk::TrackParameters&,
+InDet::TRT_TrackExtensionToolCosmics::findSegment(const EventContext& /*ctx*/,
+                                                  const Trk::TrackParameters&,
                                                   InDet::ITRT_TrackExtensionTool::IEventData &) const
 {
   return NULL;
@@ -579,7 +582,8 @@ Amg::Vector3D InDet::TRT_TrackExtensionToolCosmics::intersect(const Trk::Surface
 ///////////////////////////////////////////////////////////////////
 
 Trk::Track* 
-InDet::TRT_TrackExtensionToolCosmics::newTrack(const Trk::Track&,
+InDet::TRT_TrackExtensionToolCosmics::newTrack(const EventContext& /*ctx*/,
+                                               const Trk::Track&,
                                                InDet::ITRT_TrackExtensionTool::IEventData &) const
 { 
   return 0;
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrackExtensionTool_xk.cxx b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrackExtensionTool_xk.cxx
index 3e22684ef0de7525a58581d765d91e807f88b1d0..1602715d330a5ade1aed85d007fc22fc44e16197 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrackExtensionTool_xk.cxx
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrackExtensionTool_xk.cxx
@@ -107,6 +107,11 @@ StatusCode InDet::TRT_TrackExtensionTool_xk::initialize()
       return StatusCode::FAILURE;
     }    
     ATH_MSG_DEBUG("Retrieved " << m_fieldServiceHandle );
+
+    ////////////////////////////////////////////////////////////////////////////////
+    ATH_CHECK( m_fieldCondObjInputKey.initialize());
+    ////////////////////////////////////////////////////////////////////////////////
+    
   }
 
   if     (m_fieldmode == "NoField"    ) m_fieldprop = Trk::MagneticFieldProperties(Trk::NoField  );
@@ -315,9 +320,9 @@ std::ostream& InDet::operator <<
 ///////////////////////////////////////////////////////////////////
 
 std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData>
-InDet::TRT_TrackExtensionTool_xk::newEvent() const
+InDet::TRT_TrackExtensionTool_xk::newEvent(const EventContext& ctx) const
 {
-  SG::ReadHandle<TRT_DriftCircleContainer> trtcontainer(m_trtname);
+  SG::ReadHandle<TRT_DriftCircleContainer> trtcontainer(m_trtname, ctx);
 
   if((not trtcontainer.isValid()) && m_outputlevel<=0) {
     std::stringstream msg;
@@ -329,8 +334,15 @@ InDet::TRT_TrackExtensionTool_xk::newEvent() const
                                                   ? m_fieldprop
                                                   : Trk::MagneticFieldProperties(Trk::NoField  ));
 
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("InDet::TRT_TrackExtensionTool_xk::findSegment: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return 0;
+  }
+
   std::unique_ptr<EventData> event_data(new EventData(trtcontainer.cptr(), m_maxslope));
-  event_data->m_trajectory.set(fieldprop,&(*m_fieldServiceHandle));
+  event_data->m_trajectory.set(fieldprop, &(*m_fieldServiceHandle), fieldCondObj);
   event_data->m_trajectory.set (m_trtid,
                                 &(*m_proptool),
                                 &(*m_updatortool),
@@ -350,7 +362,8 @@ InDet::TRT_TrackExtensionTool_xk::newEvent() const
 ///////////////////////////////////////////////////////////////////
 
 std::vector<const Trk::MeasurementBase*>& 
-InDet::TRT_TrackExtensionTool_xk::extendTrack(const Trk::Track& Tr,
+InDet::TRT_TrackExtensionTool_xk::extendTrack(const EventContext& ctx,
+                                              const Trk::Track& Tr,
                                               InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const
 {
   InDet::TRT_TrackExtensionTool_xk::EventData &
@@ -373,7 +386,7 @@ InDet::TRT_TrackExtensionTool_xk::extendTrack(const Trk::Track& Tr,
     const Amg::Vector3D& g2 = parb->position();
     if((g2.x()*g2.x()+g2.y()*g2.y()) > (g1.x()*g1.x()+g1.y()*g1.y())) par=parb;
   }
-  return extendTrackFromParameters(*par,event_data);
+  return extendTrackFromParameters(ctx, *par, event_data);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -381,21 +394,23 @@ InDet::TRT_TrackExtensionTool_xk::extendTrack(const Trk::Track& Tr,
 ///////////////////////////////////////////////////////////////////
 
 std::vector<const Trk::MeasurementBase*>&
-InDet::TRT_TrackExtensionTool_xk::extendTrack(const Trk::TrackParameters& par,
+InDet::TRT_TrackExtensionTool_xk::extendTrack(const EventContext& ctx,
+                                              const Trk::TrackParameters& par,
                                               InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const
 {
   InDet::TRT_TrackExtensionTool_xk::EventData &
      event_data=InDet::TRT_TrackExtensionTool_xk::EventData::getPrivateEventData(virt_event_data);
-  return extendTrackFromParameters(par,event_data);
+  return extendTrackFromParameters(ctx, par, event_data);
 }
 
 
 std::vector<const Trk::MeasurementBase*>&
-InDet::TRT_TrackExtensionTool_xk::extendTrackFromParameters(const Trk::TrackParameters& par,
+InDet::TRT_TrackExtensionTool_xk::extendTrackFromParameters(const EventContext& ctx,
+                                                            const Trk::TrackParameters& par,
                                                             InDet::TRT_TrackExtensionTool_xk::EventData &event_data) const
 {
   event_data.m_measurement.clear();
-  if(isGoodExtension(par,event_data)) event_data.m_trajectory.convert(event_data.m_measurement);
+  if(isGoodExtension(ctx, par,event_data)) event_data.m_trajectory.convert(event_data.m_measurement);
   return event_data.m_measurement;
 }
 
@@ -404,7 +419,8 @@ InDet::TRT_TrackExtensionTool_xk::extendTrackFromParameters(const Trk::TrackPara
 ///////////////////////////////////////////////////////////////////
 
 Trk::TrackSegment* 
-InDet::TRT_TrackExtensionTool_xk::findSegment(const Trk::TrackParameters& par,
+InDet::TRT_TrackExtensionTool_xk::findSegment(const EventContext& ctx,
+                                              const Trk::TrackParameters& par,
                                               InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const
 {
   InDet::TRT_TrackExtensionTool_xk::EventData &
@@ -413,10 +429,23 @@ InDet::TRT_TrackExtensionTool_xk::findSegment(const Trk::TrackParameters& par,
   int nCut = m_minNumberDCs;
   if(m_parameterization) {nCut = m_selectortool->minNumberDCs(&par); if(nCut<m_minNumberDCs) nCut=m_minNumberDCs;}
 
+
+  // Get AtlasFieldCache
+  MagField::AtlasFieldCache fieldCache;
+
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("InDet::TRT_TrackExtensionTool_xk::findSegment: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return 0;
+  }
+  fieldCondObj->getInitializedCache (fieldCache);
+  
+
   // TRT detector elements road builder
   //
   std::vector<const InDetDD::TRT_BaseElement*> DE;
-  m_roadtool->detElementsRoad(par,Trk::alongMomentum,DE);
+  m_roadtool->detElementsRoad(ctx, fieldCache, par, Trk::alongMomentum,DE);
 
   if(int(DE.size())< nCut) return 0;
   
@@ -433,7 +462,7 @@ InDet::TRT_TrackExtensionTool_xk::findSegment(const Trk::TrackParameters& par,
   // 
   Trk::PatternTrackParameters Tp; if(!Tp.production(&par)) return 0;
   std::list< std::pair<Amg::Vector3D,double> > gpos;
-  m_proptool->globalPositions(Tp,surfaces,gpos,m_fieldprop);
+  m_proptool->globalPositions(ctx, Tp, surfaces, gpos, m_fieldprop);
 
   // Initiate trajectory
   //
@@ -499,13 +528,27 @@ InDet::TRT_TrackExtensionTool_xk::findSegment(const Trk::TrackParameters& par,
 // Test possiblity extend track to TRT for pixles+sct tracks
 ///////////////////////////////////////////////////////////////////
 
-bool InDet::TRT_TrackExtensionTool_xk::isGoodExtension(const Trk::TrackParameters& par,
+bool InDet::TRT_TrackExtensionTool_xk::isGoodExtension(const EventContext& ctx,
+                                                       const Trk::TrackParameters& par,
                                                        InDet::TRT_TrackExtensionTool_xk::EventData &event_data) const
-{ 
+{
+    
+  // Get AtlasFieldCache
+  MagField::AtlasFieldCache fieldCache;
+
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("InDet::TRT_TrackExtensionTool_xk::findSegment: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+      return 0;
+  }
+  fieldCondObj->getInitializedCache (fieldCache);
+
+    
   // TRT detector elements road builder
   //
   std::vector<const InDetDD::TRT_BaseElement*> DE;
-  m_roadtool->detElementsRoad(par,Trk::alongMomentum,DE);
+  m_roadtool->detElementsRoad(ctx, fieldCache, par,Trk::alongMomentum,DE);
   if(int(DE.size()) < m_minNumberDCs) return false;
   
   // Array pointers to surface preparation
@@ -521,7 +564,7 @@ bool InDet::TRT_TrackExtensionTool_xk::isGoodExtension(const Trk::TrackParameter
   // 
   Trk::PatternTrackParameters Tp; if(!Tp.production(&par)) return false;
   std::list< std::pair<Amg::Vector3D,double> > gpos;
-  m_proptool->globalPositions(Tp,surfaces,gpos,m_fieldprop);
+  m_proptool->globalPositions(ctx, Tp,surfaces,gpos,m_fieldprop);
 
   // Initiate trajectory
   //
@@ -549,7 +592,8 @@ bool InDet::TRT_TrackExtensionTool_xk::isGoodExtension(const Trk::TrackParameter
 // and new track production
 ///////////////////////////////////////////////////////////////////
 
-Trk::Track* InDet::TRT_TrackExtensionTool_xk::newTrack(const Trk::Track& Tr,
+Trk::Track* InDet::TRT_TrackExtensionTool_xk::newTrack(const EventContext& ctx,
+                                                       const Trk::Track& Tr,
                                                        InDet::ITRT_TrackExtensionTool::IEventData &virt_event_data) const
 {
   InDet::TRT_TrackExtensionTool_xk::EventData &
@@ -571,7 +615,7 @@ Trk::Track* InDet::TRT_TrackExtensionTool_xk::newTrack(const Trk::Track& Tr,
 
   // Test possibility extend track and new track production
   //
-  if(isGoodExtension(*pe,event_data)) return event_data.m_trajectory.convert(Tr);
+  if(isGoodExtension(ctx, *pe,event_data)) return event_data.m_trajectory.convert(Tr);
   return 0;
 }
 
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrajectoryElement_xk.cxx b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrajectoryElement_xk.cxx
index fc62b21c69eb9d31fc4fbd0bfa65c2231d5e5a71..a43616d70ea79b44a49e014403d94716cef1388e 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrajectoryElement_xk.cxx
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_TrajectoryElement_xk.cxx
@@ -28,10 +28,11 @@ void InDet::TRT_TrajectoryElement_xk::set
 }
 
 void InDet::TRT_TrajectoryElement_xk::set
-(const Trk::MagneticFieldProperties &  mf,const MagField::IMagFieldSvc*ms)
+(const Trk::MagneticFieldProperties &  mf, const MagField::IMagFieldSvc* ms, const AtlasFieldCacheCondObj* fieldCondObj)
 {
   m_fieldprop    = mf;
   m_fieldService = ms;
+  fieldCondObj->getInitializedCache (m_fieldCache);
 }
 
 ///////////////////////////////////////////////////////////////////
@@ -682,9 +683,22 @@ bool  InDet::TRT_TrajectoryElement_xk::trackParametersEstimation
   double pos0[3]; pos0[0]=Gp[0][0]; pos0[1]=Gp[0][1]; pos0[2]=Gp[0][2];
   double pos1[3]; pos1[0]=Gp[1][0]; pos1[1]=Gp[1][1]; pos1[2]=Gp[1][2];
   double pos2[3]; pos2[0]=Gp[2][0]; pos2[1]=Gp[2][1]; pos2[2]=Gp[2][2];
-  double H0  [3]; m_fieldService->getFieldZR(pos0,H0);
-  double H1  [3]; m_fieldService->getFieldZR(pos1,H1);
-  double H2  [3]; m_fieldService->getFieldZR(pos2,H2);
+  double H0  [3]; 
+  double H1  [3]; 
+  double H2  [3]; 
+  // MT version uses cache, temporarily keep old version
+  if (m_fieldCache.useNewBfieldCache()) {
+      m_fieldCache.getFieldZR    (pos0,H0);
+      m_fieldCache.getFieldZR    (pos1,H1);
+      m_fieldCache.getFieldZR    (pos2,H2);
+  }
+  else {
+      m_fieldService->getFieldZR (pos0,H0);
+      m_fieldService->getFieldZR (pos1,H1);
+      m_fieldService->getFieldZR (pos2,H2);      
+  }
+  
+  
   double Hz = .333333*(H0[2]+H1[2]+H2[2]);
 
   // If magnetic field exist
@@ -765,9 +779,21 @@ bool  InDet::TRT_TrajectoryElement_xk::trackParametersEstimation
   double pos0[3]; pos0[0]=Gp[0][0]; pos0[1]=Gp[0][1]; pos0[2]=Gp[0][2];
   double pos1[3]; pos1[0]=Gp[1][0]; pos1[1]=Gp[1][1]; pos1[2]=Gp[1][2];
   double pos2[3]; pos2[0]=Gp[2][0]; pos2[1]=Gp[2][1]; pos2[2]=Gp[2][2];
-  double H0  [3]; m_fieldService->getFieldZR(pos0,H0);
-  double H1  [3]; m_fieldService->getFieldZR(pos1,H1);
-  double H2  [3]; m_fieldService->getFieldZR(pos2,H2);
+  double H0  [3]; 
+  double H1  [3]; 
+  double H2  [3]; 
+  // MT version uses cache, temporarily keep old version
+  if (m_fieldCache.useNewBfieldCache()) {
+      m_fieldCache.getFieldZR    (pos0,H0);
+      m_fieldCache.getFieldZR    (pos1,H1);
+      m_fieldCache.getFieldZR    (pos2,H2);
+  }
+  else {
+      m_fieldService->getFieldZR (pos0,H0);
+      m_fieldService->getFieldZR (pos1,H1);
+      m_fieldService->getFieldZR (pos2,H2);      
+  }
+  
   double Hz = .333333*(H0[2]+H1[2]+H2[2]);
 
   // If magnetic field exist
diff --git a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_Trajectory_xk.cxx b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_Trajectory_xk.cxx
index 1f0e311b5ad044c9ef5868261ce106fc887e0068..abf8bf56d31f052fd5721f4e3468b17f4e38f2a4 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_Trajectory_xk.cxx
+++ b/InnerDetector/InDetRecTools/TRT_TrackExtensionTool_xk/src/TRT_Trajectory_xk.cxx
@@ -36,11 +36,11 @@ void  InDet::TRT_Trajectory_xk::set
 }
 
 void  InDet::TRT_Trajectory_xk::set
-(Trk::MagneticFieldProperties& mp,const MagField::IMagFieldSvc* ms )
+(Trk::MagneticFieldProperties& mp,const MagField::IMagFieldSvc* ms, const AtlasFieldCacheCondObj* condObj )
 
 {
   m_fieldprop    = mp;
-  for(int i=0; i!=400; ++i) m_elements[i].set(mp,ms);  
+  for(int i=0; i!=400; ++i) m_elements[i].set(mp, ms, condObj);  
 }
 
 ///////////////////////////////////////////////////////////////////
diff --git a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_ATLxk.h b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_ATLxk.h
index d66c27c8d131d31660782ce167f3c7722d0a9b31..3bcdaffc91678c3cd4c2142b2fc33bded703fb69 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_ATLxk.h
+++ b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_ATLxk.h
@@ -69,15 +69,15 @@ namespace InDet{
       // Methods to initialize tool for new event or region
       ///////////////////////////////////////////////////////////////////
 
-      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newEvent () const override;
-      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newRegion(const std::vector<IdentifierHash>&) const override;
+      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newEvent (const EventContext& ctx) const override;
+        virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newRegion(const EventContext& ctx, const std::vector<IdentifierHash>&) const override;
       void endEvent(InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
       
       ///////////////////////////////////////////////////////////////////
       // Methods of seeds production without vertex constraint
       ///////////////////////////////////////////////////////////////////
 
-      virtual void find(InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
+      virtual void find(const EventContext& ctx, InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
 
       ///////////////////////////////////////////////////////////////////
       // Iterator through seeds pseudo collection produced accordingly
@@ -185,7 +185,8 @@ namespace InDet{
       void analyseHistogramm(unsigned char&,unsigned int&,float,int,TRT_TrackSegmentsMaker_ATLxk::EventData &event_data) const;
       unsigned int localMaximum(unsigned int, TRT_TrackSegmentsMaker_ATLxk::EventData &event_data) const;
 
-      void findLocaly(unsigned int,
+      void findLocaly(const EventContext &ctx,
+                      unsigned int,
                       const Trk::PRDtoTrackMap *prd_to_track_map,
                       TRT_TrackSegmentsMaker_ATLxk::EventData &event_data) const;
 
diff --git a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_BarrelCosmics.h b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_BarrelCosmics.h
index 9d65263448866947020c86d840203530dca170cc..760bad65c82a82780acf59666c3528af0c5fad7b 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_BarrelCosmics.h
+++ b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_BarrelCosmics.h
@@ -58,11 +58,11 @@ namespace InDet{
 //      StatusCode magneticFieldInit(IOVSVC_CALLBACK_ARGS);
       virtual StatusCode               finalize  () override;
 
-      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newEvent() const override;
-      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newRegion(const std::vector<IdentifierHash>&) const override;
+      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newEvent(const EventContext& ctx) const override;
+      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newRegion(const EventContext& ctx, const std::vector<IdentifierHash>&) const override;
       void endEvent(InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
 
-      virtual void find(InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
+      virtual void find(const EventContext& ctx, InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
       virtual Trk::TrackSegment *next(InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
 
       virtual MsgStream&    dump          (MsgStream   & out) const override
diff --git a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_ECcosmics.h b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_ECcosmics.h
index 768c432908b6a8c75fceeddda6eb4c38ba6e4509..6901feb7248a8870516b5ed963f89baa499446be 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_ECcosmics.h
+++ b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsTool_xk/TRT_TrackSegmentsMaker_ECcosmics.h
@@ -86,15 +86,15 @@ namespace InDet{
       // Methods to initialize tool for new event or region
       ///////////////////////////////////////////////////////////////////
 
-      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newEvent() const override;
-      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newRegion(const std::vector<IdentifierHash>&) const override;
+      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newEvent(const EventContext& ctx) const override;
+      virtual std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> newRegion(const EventContext& ctx, const std::vector<IdentifierHash>&) const override;
       void endEvent(InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
 
       ///////////////////////////////////////////////////////////////////
       // Methods of seeds production without vertex constraint
       ///////////////////////////////////////////////////////////////////
 
-      virtual void find(InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
+      virtual void find(const EventContext& ctx, InDet::ITRT_TrackSegmentsMaker::IEventData &event_data) const override;
 
       ///////////////////////////////////////////////////////////////////
       // Iterator through seeds pseudo collection produced accordingly
diff --git a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ATLxk.cxx b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ATLxk.cxx
index d26386459cd381890ef4033a1601116a87353754..22fa30885a8d473018cd7a97e2830ee645798ac5 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ATLxk.cxx
+++ b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ATLxk.cxx
@@ -145,7 +145,7 @@ StatusCode InDet::TRT_TrackSegmentsMaker_ATLxk::finalize()
 ///////////////////////////////////////////////////////////////////
 
 std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>
-InDet::TRT_TrackSegmentsMaker_ATLxk::newEvent() const
+InDet::TRT_TrackSegmentsMaker_ATLxk::newEvent(const EventContext &ctx) const
 {
 
   const float pi2 = 2.*M_PI;
@@ -154,7 +154,7 @@ InDet::TRT_TrackSegmentsMaker_ATLxk::newEvent() const
 
   // Get drift circles collection
   //
-  SG::ReadHandle<InDet::TRT_DriftCircleContainer> trtcontainer(m_trtname);
+  SG::ReadHandle<InDet::TRT_DriftCircleContainer> trtcontainer(m_trtname, ctx);
   if(not trtcontainer.isValid()) {
     std::stringstream msg;
     msg << name() << " Missing TRT_DriftCircleContainer " << m_trtname.key();
@@ -164,7 +164,7 @@ InDet::TRT_TrackSegmentsMaker_ATLxk::newEvent() const
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -177,7 +177,7 @@ InDet::TRT_TrackSegmentsMaker_ATLxk::newEvent() const
 
   // Initiate extension tool
   //
-  event_data->m_extEventData = m_extensionTool->newEvent();
+  event_data->m_extEventData = m_extensionTool->newEvent(ctx);
 
   InDet::TRT_DriftCircleContainer::const_iterator
     w = trtcontainer->begin(),we = trtcontainer->end();
@@ -234,7 +234,7 @@ InDet::TRT_TrackSegmentsMaker_ATLxk::newEvent() const
 
 std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>
 InDet::TRT_TrackSegmentsMaker_ATLxk::newRegion
-(const std::vector<IdentifierHash>& vTRT) const
+(const EventContext& ctx, const std::vector<IdentifierHash>& vTRT) const
 {
   const float pi2 = 2.*M_PI;
 
@@ -242,7 +242,7 @@ InDet::TRT_TrackSegmentsMaker_ATLxk::newRegion
 
   // Get drift cilrcles collection
   //
-  SG::ReadHandle<InDet::TRT_DriftCircleContainer> trtcontainer(m_trtname);
+  SG::ReadHandle<InDet::TRT_DriftCircleContainer> trtcontainer(m_trtname, ctx);
   if(not trtcontainer.isValid() && msgLvl(MSG::DEBUG)) {
     msg(MSG::DEBUG)<<"Could not get TRT_DriftCircleContainer"<<endmsg;
   }
@@ -250,7 +250,7 @@ InDet::TRT_TrackSegmentsMaker_ATLxk::newRegion
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -263,7 +263,7 @@ InDet::TRT_TrackSegmentsMaker_ATLxk::newRegion
   if(trtcontainer.isValid()) {
   // Initiate extension tool
   //
-  event_data->m_extEventData = m_extensionTool->newEvent();
+  event_data->m_extEventData = m_extensionTool->newEvent(ctx);
 
   InDet::TRT_DriftCircleContainer::const_iterator we = trtcontainer->end();
 
@@ -333,7 +333,8 @@ void InDet::TRT_TrackSegmentsMaker_ATLxk::endEvent (InDet::ITRT_TrackSegmentsMak
 ///////////////////////////////////////////////////////////////////
 // Methods for seeds production without vertex constraint
 ///////////////////////////////////////////////////////////////////
-void InDet::TRT_TrackSegmentsMaker_ATLxk::find(InDet::ITRT_TrackSegmentsMaker::IEventData &virt_event_data) const
+void InDet::TRT_TrackSegmentsMaker_ATLxk::find(const EventContext &ctx,
+                                               InDet::ITRT_TrackSegmentsMaker::IEventData &virt_event_data) const
 {
    TRT_TrackSegmentsMaker_ATLxk::EventData &
       event_data = TRT_TrackSegmentsMaker_ATLxk::EventData::getPrivateEventData(virt_event_data);
@@ -390,7 +391,7 @@ void InDet::TRT_TrackSegmentsMaker_ATLxk::find(InDet::ITRT_TrackSegmentsMaker::I
   SG::ReadHandle<Trk::PRDtoTrackMap>  prd_to_track_map;
   const Trk::PRDtoTrackMap  *prd_to_track_map_cptr = nullptr;
   if (!m_prdToTrackMap.key().empty()) {
-    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap);
+    prd_to_track_map=SG::ReadHandle<Trk::PRDtoTrackMap>(m_prdToTrackMap, ctx);
     if (!prd_to_track_map.isValid()) {
       ATH_MSG_ERROR("Failed to read PRD to track association map: " << m_prdToTrackMap.key());
     }
@@ -402,7 +403,7 @@ void InDet::TRT_TrackSegmentsMaker_ATLxk::find(InDet::ITRT_TrackSegmentsMaker::I
   while(event_data.m_sizebin_iterator!=event_data.m_sizebin.rend()) {
 
     unsigned int bin =(*event_data.m_sizebin_iterator++).second;
-    findLocaly(bin,prd_to_track_map_cptr, event_data);
+    findLocaly(ctx, bin,prd_to_track_map_cptr, event_data);
   }
 
   // Final segments preparation
@@ -629,7 +630,8 @@ void InDet::TRT_TrackSegmentsMaker_ATLxk::analyseHistogramm
 // TRT seeds production
 ///////////////////////////////////////////////////////////////////
 
-void InDet::TRT_TrackSegmentsMaker_ATLxk::findLocaly(unsigned int bin,
+void InDet::TRT_TrackSegmentsMaker_ATLxk::findLocaly(const EventContext &ctx,
+                                                     unsigned int bin,
                                                      const Trk::PRDtoTrackMap *prd_to_track_map,
                                                      TRT_TrackSegmentsMaker_ATLxk::EventData &event_data) const
 {
@@ -696,7 +698,7 @@ void InDet::TRT_TrackSegmentsMaker_ATLxk::findLocaly(unsigned int bin,
   const Trk::TrackParameters* Tp = PS.createTrackParameters(0.,0.,fm,atan2(1.,condData.m_dzdr[ndzdr]),pin,0);
     ++event_data.m_nlocal;
 
-  Trk::TrackSegment* seg = m_extensionTool->findSegment(*Tp, *(event_data.m_extEventData) );
+  Trk::TrackSegment* seg = m_extensionTool->findSegment(ctx, *Tp, *(event_data.m_extEventData) );
   delete Tp;
   if(!seg) return;
 
diff --git a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_BarrelCosmics.cxx b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_BarrelCosmics.cxx
index a212c54be20f2583788d11c9394a02ec20b1a5a1..c2b69630a5e66024d91bf13681772ab1fdbe196a 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_BarrelCosmics.cxx
+++ b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_BarrelCosmics.cxx
@@ -103,12 +103,12 @@ StatusCode InDet::TRT_TrackSegmentsMaker_BarrelCosmics::finalize() {
 //   other methods inherited from ITRT_TrackSegmentsMaker: newEvent, newRegion, endEvent
 //////////////////////////////////////////////////////////////////////////////////////////
 
-std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> InDet::TRT_TrackSegmentsMaker_BarrelCosmics::newEvent() const {
+std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> InDet::TRT_TrackSegmentsMaker_BarrelCosmics::newEvent(const EventContext& ctx) const {
 
   ATH_MSG_DEBUG( "InDet::TRT_TrackSegmentsMaker_BarrelCosmics::newEvent()");
 
 
-  SG::ReadHandle<InDet::TRT_DriftCircleContainer> trtcontainer(m_driftCirclesName); // get TRT_DriftCircle list from StoreGate containers
+  SG::ReadHandle<InDet::TRT_DriftCircleContainer> trtcontainer(m_driftCirclesName, ctx); // get TRT_DriftCircle list from StoreGate containers
 
   if (not trtcontainer.isValid()) {
      msg(MSG::ERROR) << "Could not find TRT_DriftCircles collection!" << endmsg;
@@ -154,11 +154,11 @@ std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData> InDet::TRT_TrackSegm
 }
 
 std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>
-InDet::TRT_TrackSegmentsMaker_BarrelCosmics::newRegion(const std::vector<IdentifierHash> &vTRT) const {
+InDet::TRT_TrackSegmentsMaker_BarrelCosmics::newRegion(const EventContext& ctx, const std::vector<IdentifierHash> &vTRT) const {
 
   ATH_MSG_DEBUG("InDet::TRT_TrackSegmentsMaker_BarrelCosmics::newRegion()" );
 
-  SG::ReadHandle<InDet::TRT_DriftCircleContainer> trtcontainer(m_driftCirclesName);
+  SG::ReadHandle<InDet::TRT_DriftCircleContainer> trtcontainer(m_driftCirclesName, ctx);
   if (not trtcontainer.isValid()) {
     msg(MSG::ERROR) << "m_trtcontainer is empty!!!" << endmsg;
      std::stringstream msg;
@@ -219,7 +219,8 @@ void InDet::TRT_TrackSegmentsMaker_BarrelCosmics::endEvent (InDet::ITRT_TrackSeg
 //   segment finding algorithm function: find, calls findSeed 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-void InDet::TRT_TrackSegmentsMaker_BarrelCosmics::find(InDet::ITRT_TrackSegmentsMaker::IEventData &virt_event_data) const {
+void InDet::TRT_TrackSegmentsMaker_BarrelCosmics::find(const EventContext &/*ctx*/,
+                                                       InDet::ITRT_TrackSegmentsMaker::IEventData &virt_event_data) const {
   TRT_TrackSegmentsMaker_BarrelCosmics::EventData &
      event_data  = TRT_TrackSegmentsMaker_BarrelCosmics::EventData::getPrivateEventData(virt_event_data);
 
diff --git a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ECcosmics.cxx b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ECcosmics.cxx
index 01857d4ab0bc44319bd8b0ebd78f25a1aa6527f8..067d922b969a50cddf685d0c4f6493f7f4331bdc 100755
--- a/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ECcosmics.cxx
+++ b/InnerDetector/InDetRecTools/TRT_TrackSegmentsTool_xk/src/TRT_TrackSegmentsMaker_ECcosmics.cxx
@@ -194,7 +194,7 @@ StatusCode InDet::TRT_TrackSegmentsMaker_ECcosmics::finalize()
 ///////////////////////////////////////////////////////////////////
 
 std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>
-InDet::TRT_TrackSegmentsMaker_ECcosmics::newEvent () const
+InDet::TRT_TrackSegmentsMaker_ECcosmics::newEvent (const EventContext& /*ctx*/) const
 {
 
   std::unique_ptr<TRT_TrackSegmentsMaker_ECcosmics::EventData>
@@ -241,7 +241,7 @@ InDet::TRT_TrackSegmentsMaker_ECcosmics::newEvent () const
 
 std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>
 InDet::TRT_TrackSegmentsMaker_ECcosmics::newRegion
-(const std::vector<IdentifierHash>& vTRT) const
+(const EventContext& /*ctx*/, const std::vector<IdentifierHash>& vTRT) const
 {
   (void) vTRT;
   std::unique_ptr<TRT_TrackSegmentsMaker_ECcosmics::EventData>
@@ -340,7 +340,7 @@ namespace InDet{
 // Methods of TRT segment reconstruction in one event
 ///////////////////////////////////////////////////////////////////
 
-void InDet::TRT_TrackSegmentsMaker_ECcosmics::find(InDet::ITRT_TrackSegmentsMaker::IEventData &virt_event_data) const
+void InDet::TRT_TrackSegmentsMaker_ECcosmics::find(const EventContext & /*ctx*/, InDet::ITRT_TrackSegmentsMaker::IEventData &virt_event_data) const
 {
   TRT_TrackSegmentsMaker_ECcosmics::EventData &
      event_data  = TRT_TrackSegmentsMaker_ECcosmics::EventData::getPrivateEventData(virt_event_data);
diff --git a/InnerDetector/InDetTrigRecAlgs/SiTrigSPSeededTrackFinder/src/SiTrigSPSeededTrackFinder.cxx b/InnerDetector/InDetTrigRecAlgs/SiTrigSPSeededTrackFinder/src/SiTrigSPSeededTrackFinder.cxx
index 213f0b7f0fb43b490c3b9693f999e22b51cd86a1..fa675b32a7ae7660bf049c2a117287a22aa5dbf1 100755
--- a/InnerDetector/InDetTrigRecAlgs/SiTrigSPSeededTrackFinder/src/SiTrigSPSeededTrackFinder.cxx
+++ b/InnerDetector/InDetTrigRecAlgs/SiTrigSPSeededTrackFinder/src/SiTrigSPSeededTrackFinder.cxx
@@ -39,6 +39,7 @@
 #include "GeoPrimitives/GeoPrimitives.h"
 
 #include "TrigNavigation/NavigationCore.icc"
+#include "GaudiKernel/ThreadLocalContext.h"
 
 ///////////////////////////////////////////////////////////////////
 // Constructor
@@ -293,21 +294,21 @@ HLT::ErrorCode InDet::SiTrigSPSeededTrackFinder::hltExecute(const HLT::TriggerEl
       
       if(!m_doFullScan){
 	if (m_fastTracking){
-	  vertices = m_zvertexmaker->newRegion(seedEventData, listOfPixIds, listOfSCTIds, *roi);
+          vertices = m_zvertexmaker->newRegion(Gaudi::Hive::currentContext(), seedEventData, listOfPixIds, listOfSCTIds, *roi);
 	}
 	else {
-	  vertices = m_zvertexmaker->newRegion(seedEventData, listOfPixIds, listOfSCTIds);
+	  vertices = m_zvertexmaker->newRegion(Gaudi::Hive::currentContext(), seedEventData, listOfPixIds, listOfSCTIds);
 	}
       }
       else{
-	vertices = m_zvertexmaker->newEvent(seedEventData);
+	vertices = m_zvertexmaker->newEvent(Gaudi::Hive::currentContext(), seedEventData);
       }
       
       if(doTiming()) m_timerZVertexTool->stop();
       
       if(doTiming()) m_timerSeedsMaker->start();
       
-      m_seedsmaker->find3Sp(seedEventData, vertices);
+      m_seedsmaker->find3Sp(Gaudi::Hive::currentContext(), seedEventData, vertices);
       
       if(doTiming()) m_timerSeedsMaker->stop();
       
@@ -320,18 +321,18 @@ HLT::ErrorCode InDet::SiTrigSPSeededTrackFinder::hltExecute(const HLT::TriggerEl
       if(doTiming()) m_timerSeedsMaker->start();
       if(!m_doFullScan){
 	if (m_fastTracking){
-	  m_seedsmaker->newRegion(seedEventData, listOfPixIds, listOfSCTIds, *roi);
+	  m_seedsmaker->newRegion(Gaudi::Hive::currentContext(), seedEventData, listOfPixIds, listOfSCTIds, *roi);
 	} else {
-	  m_seedsmaker->newRegion(seedEventData, listOfPixIds, listOfSCTIds);
+	  m_seedsmaker->newRegion(Gaudi::Hive::currentContext(), seedEventData, listOfPixIds, listOfSCTIds);
 	}
 
       }
       else{
-	m_seedsmaker->newEvent(seedEventData);
+	m_seedsmaker->newEvent(Gaudi::Hive::currentContext(), seedEventData);
       }
       
       std::list<Trk::Vertex> VZ;
-      m_seedsmaker->find3Sp(seedEventData, VZ);
+      m_seedsmaker->find3Sp(Gaudi::Hive::currentContext(), seedEventData, VZ);
       if(doTiming()) m_timerSeedsMaker->stop();
     }
   }
@@ -343,10 +344,10 @@ HLT::ErrorCode InDet::SiTrigSPSeededTrackFinder::hltExecute(const HLT::TriggerEl
   InDet::ExtendedSiTrackMakerEventData_xk trackEventData(*this, outputTE, m_prdToTrackMap);
   if(doTiming()) m_timerTrackMaker->start();
   if (m_fastTracking){
-    m_trackmaker->newTrigEvent(trackEventData, PIX, SCT);
+    m_trackmaker->newTrigEvent(Gaudi::Hive::currentContext(), trackEventData, PIX, SCT);
     //m_trackmaker->newEvent(trackEventData, PIX, SCT);
   } else {
-    m_trackmaker->newEvent(trackEventData, PIX, SCT);
+    m_trackmaker->newEvent(Gaudi::Hive::currentContext(), trackEventData, PIX, SCT);
   }
 
   // Loop through all seeds and reconsrtucted tracks collection preparation
@@ -377,7 +378,7 @@ HLT::ErrorCode InDet::SiTrigSPSeededTrackFinder::hltExecute(const HLT::TriggerEl
     int nseedwithtrack(0);
     ///////////////////////////////////////
     
-    while((seed = m_seedsmaker->next(seedEventData))) {
+    while((seed = m_seedsmaker->next(Gaudi::Hive::currentContext(), seedEventData))) {
       if (m_doTimeOutChecks && Athena::Timeout::instance().reached() ) {
 	      ATH_MSG_WARNING( "Timeout reached. Aborting sequence." );
 	      delete foundTracks;
@@ -385,7 +386,7 @@ HLT::ErrorCode InDet::SiTrigSPSeededTrackFinder::hltExecute(const HLT::TriggerEl
       }
       if(doTiming()) m_timerSeedProcessing->start();
       ++m_nseeds;
-      std::list<Trk::Track*> T = m_trackmaker->getTracks(trackEventData, seed->spacePoints());
+      std::list<Trk::Track*> T = m_trackmaker->getTracks(Gaudi::Hive::currentContext(), trackEventData, seed->spacePoints());
       
       if (m_fastTracking){
 	      for(std::list<Trk::Track*>::const_iterator t=T.begin(); t!=T.end(); ++t) {
@@ -573,7 +574,7 @@ HLT::ErrorCode InDet::SiTrigSPSeededTrackFinder::hltExecute(const HLT::TriggerEl
       }
       
 	  
-      std::list<Trk::Track*> T = m_trackmaker->getTracks(trackEventData, *perig, gpList);//dummyp); //
+      std::list<Trk::Track*> T = m_trackmaker->getTracks(Gaudi::Hive::currentContext(), trackEventData, *perig, gpList);//dummyp); //
 	  
 	  
 	if(doTiming()){
diff --git a/InnerDetector/InDetTrigRecAlgs/TRT_TrigSeededTrackFinder/src/TRT_TrigSeededTrackFinder.cxx b/InnerDetector/InDetTrigRecAlgs/TRT_TrigSeededTrackFinder/src/TRT_TrigSeededTrackFinder.cxx
index dda0d50b7f0bc3a3d2ccbd8a756374055989c640..23c9070448ccd1eba8cc415d09e832428d485c8f 100755
--- a/InnerDetector/InDetTrigRecAlgs/TRT_TrigSeededTrackFinder/src/TRT_TrigSeededTrackFinder.cxx
+++ b/InnerDetector/InDetTrigRecAlgs/TRT_TrigSeededTrackFinder/src/TRT_TrigSeededTrackFinder.cxx
@@ -27,6 +27,7 @@
 #include "SiSPSeededTrackFinderData/SiCombinatorialTrackFinderData_xk.h"
 
 #include "TrigNavigation/NavigationCore.icc"
+#include "GaudiKernel/ThreadLocalContext.h"
 using namespace std;
 
 ///////////////////////////////////////////////////////////////////
@@ -239,12 +240,12 @@ HLT::ErrorCode InDet::TRT_TrigSeededTrackFinder::hltExecute(const HLT::TriggerEl
 
   ///Initialize the TRT seeded track tool's new event
   std::unique_ptr<InDet::ITRT_SeededTrackFinder::IEventData> event_data_p;
-  std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> ext_event_data_p (m_trtExtension->newEvent());
+  std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData> ext_event_data_p (m_trtExtension->newEvent(Gaudi::Hive::currentContext()));
   if(!m_doFullScan){
-    event_data_p = m_trackmaker->newRegion(combinatorialData, listOfPixIds, listOfSCTIds); //RoI-based reconstruction
+    event_data_p = m_trackmaker->newRegion(Gaudi::Hive::currentContext(), combinatorialData, listOfPixIds, listOfSCTIds); //RoI-based reconstruction
   }
   else{
-    event_data_p = m_trackmaker->newEvent(combinatorialData); // FullScan mode
+    event_data_p = m_trackmaker->newEvent(Gaudi::Hive::currentContext(), combinatorialData); // FullScan mode
   }
 
   if(outputLevel <= MSG::DEBUG) msg() << MSG::DEBUG << "Begin looping over all TRT segments in the event" << endmsg;
@@ -268,7 +269,7 @@ HLT::ErrorCode InDet::TRT_TrigSeededTrackFinder::hltExecute(const HLT::TriggerEl
       if(outputLevel <= MSG::DEBUG) msg() << MSG::DEBUG << "Number Of ROTs " << (trackTRT->numberOfMeasurementBases()) << endmsg;
       if(trackTRT->numberOfMeasurementBases()>9){  //Ask for at least 10 TRT hits in order to process
         m_nTrtSegGood++;
-        std::list<Trk::Track*> trackSi = m_trackmaker->getTrack(*event_data_p, *trackTRT); //Get the possible Si extensions
+        std::list<Trk::Track*> trackSi = m_trackmaker->getTrack(Gaudi::Hive::currentContext(), *event_data_p, *trackTRT); //Get the possible Si extensions
 
 	if(trackSi.size()==0){
 	  if(outputLevel <= MSG::DEBUG) msg() << MSG::DEBUG << "No Si track candidates associated to the TRT track " << endmsg;
@@ -299,7 +300,7 @@ HLT::ErrorCode InDet::TRT_TrigSeededTrackFinder::hltExecute(const HLT::TriggerEl
 	    Trk::Track* globalTrackNew = 0;
 
 	    if(int(temptsos->size())>=4 && m_doExtension){
-               std::vector<const Trk::MeasurementBase*>& tn = m_trtExtension->extendTrack(*(*itt),*ext_event_data_p);
+               std::vector<const Trk::MeasurementBase*>& tn = m_trtExtension->extendTrack(Gaudi::Hive::currentContext(), *(*itt),*ext_event_data_p);
 
 	      if(tn.size()) {
 
diff --git a/InnerDetector/InDetTrigRecAlgs/TRT_TrigStandaloneTrackFinder/src/TRT_TrigStandaloneTrackFinder.cxx b/InnerDetector/InDetTrigRecAlgs/TRT_TrigStandaloneTrackFinder/src/TRT_TrigStandaloneTrackFinder.cxx
index 896df9d9901e104a7abeee547e7f8d2106fbd3a7..970a45bacbd13915a92cd45f051efceecb466687 100644
--- a/InnerDetector/InDetTrigRecAlgs/TRT_TrigStandaloneTrackFinder/src/TRT_TrigStandaloneTrackFinder.cxx
+++ b/InnerDetector/InDetTrigRecAlgs/TRT_TrigStandaloneTrackFinder/src/TRT_TrigStandaloneTrackFinder.cxx
@@ -19,6 +19,7 @@
 #include "InDetIdentifier/TRT_ID.h"
 #include "TrkTrack/Track.h"
 #include "TrkTrack/TrackInfo.h"
+#include "GaudiKernel/ThreadLocalContext.h"
 
 //Eigen
 #include "EventPrimitives/EventPrimitives.h"
@@ -159,7 +160,7 @@ HLT::ErrorCode InDet::TRT_TrigStandaloneTrackFinder::hltExecute(const HLT::Trigg
         m_nTrtSegGood++;
 
 	///Transform the original TRT segment into a track
-	Trk::Track* trtSeg = 0;trtSeg = m_segToTrackTool->segToTrack(*trackTRT);
+	Trk::Track* trtSeg = 0;trtSeg = m_segToTrackTool->segToTrack(Gaudi::Hive::currentContext(), *trackTRT);
 	if(!trtSeg){
 	  if(outputLevel <= MSG::DEBUG)
 	    msg() << MSG::DEBUG << "Failed to make a track out of the TRT segment!" << endmsg;
diff --git a/InnerDetector/InDetTrigRecAlgs/TRT_TrigTrackExtensionAlg/src/TRT_TrigTrackExtensionAlg.cxx b/InnerDetector/InDetTrigRecAlgs/TRT_TrigTrackExtensionAlg/src/TRT_TrigTrackExtensionAlg.cxx
index 6be851d47d74cf3f510c21d9510a435819f7afaf..c0ad99f0a90e798c4e33d3ac2057efcf0b00834a 100755
--- a/InnerDetector/InDetTrigRecAlgs/TRT_TrigTrackExtensionAlg/src/TRT_TrigTrackExtensionAlg.cxx
+++ b/InnerDetector/InDetTrigRecAlgs/TRT_TrigTrackExtensionAlg/src/TRT_TrigTrackExtensionAlg.cxx
@@ -8,6 +8,7 @@
 #include "TrkTrack/TrackCollection.h"
 #include "TRT_TrigTrackExtensionAlg/TRT_TrigTrackExtensionAlg.h"
 #include "InDetRecToolInterfaces/ITRT_TrackExtensionTool.h"
+#include "GaudiKernel/ThreadLocalContext.h"
 
 
 ///////////////////////////////////////////////////////////////////
@@ -93,7 +94,7 @@ HLT::ErrorCode InDet::TRT_TrigTrackExtensionAlg::hltExecute(const HLT::TriggerEl
   }
 
   std::unique_ptr<InDet::ITRT_TrackExtensionTool::IEventData>
-     event_data = m_trtExtension->newEvent();
+     event_data = m_trtExtension->newEvent(Gaudi::Hive::currentContext());
 
   // Loop through all input track and output tracks collection production
   //
@@ -109,7 +110,7 @@ HLT::ErrorCode InDet::TRT_TrigTrackExtensionAlg::hltExecute(const HLT::TriggerEl
     ++m_nTracks;
          
     std::vector<const Trk::MeasurementBase*>& tn = 
-      m_trtExtension->extendTrack(*(*t), *event_data);
+      m_trtExtension->extendTrack(Gaudi::Hive::currentContext(), *(*t), *event_data);
 
     if(!tn.size())
       continue;
diff --git a/InnerDetector/InDetTrigRecAlgs/TRT_TrigTrackSegmentsFinder/src/TRT_TrigTrackSegmentsFinder.cxx b/InnerDetector/InDetTrigRecAlgs/TRT_TrigTrackSegmentsFinder/src/TRT_TrigTrackSegmentsFinder.cxx
index ce20cdaae3d5d6a7293ff8efb37a44902511b39c..c106ba7b5f4ec23d6c5a53b264857340394ab6aa 100755
--- a/InnerDetector/InDetTrigRecAlgs/TRT_TrigTrackSegmentsFinder/src/TRT_TrigTrackSegmentsFinder.cxx
+++ b/InnerDetector/InDetTrigRecAlgs/TRT_TrigTrackSegmentsFinder/src/TRT_TrigTrackSegmentsFinder.cxx
@@ -17,6 +17,7 @@
 #include "TRT_TrigTrackSegmentsFinder/TRT_TrigTrackSegmentsFinder.h"
 #include "TrkSegment/SegmentCollection.h"
 #include "TrigTimeAlgs/TrigTimerSvc.h"
+#include "GaudiKernel/ThreadLocalContext.h"
 
 //Trigger stuff
 #include "TrigSteeringEvent/TrigRoiDescriptor.h"
@@ -136,17 +137,17 @@ HLT::ErrorCode InDet::TRT_TrigTrackSegmentsFinder::hltExecute(const HLT::Trigger
     if(doTiming()) m_timerRegSel->stop();
 
     if(doTiming()) m_timerSegMaker->resume();
-    event_data = m_segmentsMakerTool->newRegion(listOfTRTIds);
+    event_data = m_segmentsMakerTool->newRegion(Gaudi::Hive::currentContext(), listOfTRTIds);
     if(doTiming()) m_timerSegMaker->stop();
   } 
   else{
     if(doTiming()) m_timerSegMaker->resume();
-    event_data = m_segmentsMakerTool->newEvent();
+    event_data = m_segmentsMakerTool->newEvent(Gaudi::Hive::currentContext());
     if(doTiming()) m_timerSegMaker->stop();
   }
 
   if(doTiming()) m_timerFind->resume();
-  m_segmentsMakerTool->find    (*event_data);
+  m_segmentsMakerTool->find    (Gaudi::Hive::currentContext(), *event_data);
   if(doTiming()) m_timerFind->stop();
 
   if(doTiming()) m_timerMainLoop->resume();
diff --git a/LArCalorimeter/LArDigitization/LArDigitization/LArPileUpTool.h b/LArCalorimeter/LArDigitization/LArDigitization/LArPileUpTool.h
index 6af2613a800c99eb7d5f939dde2178837a442186..15a592542362452cfe6abd2f87ab50ed89033dc5 100755
--- a/LArCalorimeter/LArDigitization/LArDigitization/LArPileUpTool.h
+++ b/LArCalorimeter/LArDigitization/LArDigitization/LArPileUpTool.h
@@ -79,15 +79,15 @@ class LArPileUpTool : virtual public ILArPileUpTool, public PileUpToolBase
 
   virtual StatusCode initialize() override final;
 
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
 
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
   virtual StatusCode processBunchXing(int bunchXing,
                                       SubEventIterator bSubEvents,
                                       SubEventIterator eSubEvents) override final;
 
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
   virtual StatusCode fillMapFromHit(StoreGateSvc* seStore,float tbunch,bool isSignal) override final;
 
@@ -104,14 +104,14 @@ class LArPileUpTool : virtual public ILArPileUpTool, public PileUpToolBase
   StatusCode AddHit(const Identifier cellId, const float energy, const float time, const bool iSignal);
 
 
-  StatusCode MakeDigit(const Identifier & cellId,
+  StatusCode MakeDigit(const EventContext& ctx, const Identifier & cellId,
 		       HWIdentifier & ch_id,
 		       const std::vector<std::pair<float,float> >* TimeE,
 		       const LArDigit * rndm_digit, CLHEP::HepRandomEngine * engine,
 		       const std::vector<std::pair<float,float> >* TimeE_DigiHSTruth = nullptr);
 
 
-  StatusCode ConvertHits2Samples(const Identifier & cellId, HWIdentifier ch_id,
+  StatusCode ConvertHits2Samples(const EventContext& ctx, const Identifier & cellId, HWIdentifier ch_id,
                    CaloGain::CaloGain igain,
                    //const std::vector<std::pair<float,float> >  *TimeE);
                    const std::vector<std::pair<float,float> >  *TimeE,  std::vector<double> &sampleList);
diff --git a/LArCalorimeter/LArDigitization/src/LArDigitMaker.cxx b/LArCalorimeter/LArDigitization/src/LArDigitMaker.cxx
index faafbbfd862485affe48d2dd2067b8f58ff8ec2b..276320f2ae875058dcd5e9eb346afcd07b7da2e1 100755
--- a/LArCalorimeter/LArDigitization/src/LArDigitMaker.cxx
+++ b/LArCalorimeter/LArDigitization/src/LArDigitMaker.cxx
@@ -54,7 +54,7 @@ StatusCode LArDigitMaker::initialize()
 StatusCode LArDigitMaker::execute()
 {
 
-  if (m_LArPileUpTool->processAllSubEvents().isFailure()) {
+  if (m_LArPileUpTool->processAllSubEvents(Gaudi::Hive::currentContext()).isFailure()) {
        ATH_MSG_ERROR(" error in LArPileupTool::processAllSubEvents");
        return StatusCode::FAILURE;
   }
diff --git a/LArCalorimeter/LArDigitization/src/LArPileUpTool.cxx b/LArCalorimeter/LArDigitization/src/LArPileUpTool.cxx
index 7978d2c679d26defac19695b5b29746433a9a871..a5bc95bd138af61e82c4e68295c9d105e3200abf 100755
--- a/LArCalorimeter/LArDigitization/src/LArPileUpTool.cxx
+++ b/LArCalorimeter/LArDigitization/src/LArPileUpTool.cxx
@@ -244,17 +244,17 @@ StatusCode LArPileUpTool::initialize()
 
 // ----------------------------------------------------------------------------------------------------------------------------------
 
-StatusCode LArPileUpTool::prepareEvent(unsigned int /*nInputEvents */)
+StatusCode LArPileUpTool::prepareEvent(const EventContext& ctx, unsigned int /*nInputEvents */)
 {
 
-  SG::ReadCondHandle<LArOnOffIdMapping> cablingHdl{m_cablingKey};
+  SG::ReadCondHandle<LArOnOffIdMapping> cablingHdl{m_cablingKey, ctx};
   m_cabling=*cablingHdl;
   if(!m_cabling) {
      ATH_MSG_ERROR("Failed to retrieve LAr Cabling map with key " << m_cablingKey.key() );
      return StatusCode::FAILURE;
   }
 
-  m_hitmap=SG::makeHandle(m_hitMapKey);
+  m_hitmap=SG::makeHandle(m_hitMapKey, ctx);
   auto hitMapPtr=std::make_unique<LArHitEMap>(m_cabling,m_calocell_id,m_caloDDMgr,m_RndmEvtOverlay);
   ATH_CHECK(m_hitmap.record(std::move(hitMapPtr)));
   ATH_MSG_DEBUG(" Number of created  cells in Map " << m_hitmap->GetNbCells());
@@ -263,7 +263,7 @@ StatusCode LArPileUpTool::prepareEvent(unsigned int /*nInputEvents */)
 
   
   if (m_doDigiTruth) {
-    m_hitmap_DigiHSTruth=SG::makeHandle(m_hitMapKey_DigiHSTruth);
+    m_hitmap_DigiHSTruth=SG::makeHandle(m_hitMapKey_DigiHSTruth, ctx);
     auto hitMapPtr=std::make_unique<LArHitEMap>(m_cabling,m_calocell_id,m_caloDDMgr,m_RndmEvtOverlay);
     ATH_CHECK(m_hitmap_DigiHSTruth.record(std::move(hitMapPtr)));
     if (!m_useMBTime) m_energySum_DigiHSTruth.assign(m_hitmap_DigiHSTruth->GetNbCells(),0.);
@@ -278,11 +278,11 @@ StatusCode LArPileUpTool::prepareEvent(unsigned int /*nInputEvents */)
   }
 
   ATHRNG::RNGWrapper* rngWrapper = m_rndmGenSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
+  rngWrapper->setSeed( name(), ctx );
 
   // add random phase (i.e subtract it from trigtime)
   if (m_addPhase) {
-    m_trigtime = m_trigtime - (m_phaseMin + (m_phaseMax-m_phaseMin)*RandFlat::shoot(*rngWrapper)  );
+    m_trigtime = m_trigtime - (m_phaseMin + (m_phaseMax-m_phaseMin)*RandFlat::shoot(rngWrapper->getEngine(ctx))  );
   }
 
   if (m_Windows) {
@@ -299,11 +299,11 @@ StatusCode LArPileUpTool::prepareEvent(unsigned int /*nInputEvents */)
   // ....... create the LAr Digit Container
   //
   
-  m_DigitContainer = SG::makeHandle(m_DigitContainerName);//new LArDigitContainer();
+  m_DigitContainer = SG::makeHandle(m_DigitContainerName, ctx);//new LArDigitContainer();
   ATH_CHECK(m_DigitContainer.record(std::make_unique<LArDigitContainer>()));
 
   if (m_doDigiTruth) {
-    m_DigitContainer_DigiHSTruth = SG::makeHandle(m_DigitContainerName_DigiHSTruth);//new LArDigitContainer();
+    m_DigitContainer_DigiHSTruth = SG::makeHandle(m_DigitContainerName_DigiHSTruth, ctx);//new LArDigitContainer();
     ATH_CHECK(m_DigitContainer_DigiHSTruth.record(std::make_unique<LArDigitContainer>()));
   }
 
@@ -371,16 +371,16 @@ StatusCode LArPileUpTool::processBunchXing(int bunchXing,
 
 // ---------------------------------------------------------------------------------------------------------------------------------
 
-StatusCode LArPileUpTool::processAllSubEvents()
+StatusCode LArPileUpTool::processAllSubEvents(const EventContext& ctx)
 {
 
-  if (this->prepareEvent(0).isFailure()) {
+  if (this->prepareEvent(ctx, 0).isFailure()) {
      ATH_MSG_ERROR("error in prepareEvent");
      return StatusCode::FAILURE;
   }
 
   if(!m_onlyUseContainerName && m_RndmEvtOverlay) {
-    auto hitVectorHandles = m_hitContainerKeys.makeHandles();
+    auto hitVectorHandles = m_hitContainerKeys.makeHandles(ctx);
     for (auto & inputHits : hitVectorHandles) {
       if (!inputHits.isValid()) {
         ATH_MSG_ERROR("BAD HANDLE"); //FIXME improve error here
@@ -555,7 +555,7 @@ StatusCode LArPileUpTool::processAllSubEvents()
     {
       if (!m_onlyUseContainerName)
       {
-        SG::ReadHandle<LArDigitContainer> digitCollection(m_inputDigitContainerKey);
+        SG::ReadHandle<LArDigitContainer> digitCollection(m_inputDigitContainerKey, ctx);
         if (!digitCollection.isValid()) {
           ATH_MSG_ERROR("Could not get LArDigitContainer container " << digitCollection.name() << " from store " << digitCollection.store());
           return StatusCode::FAILURE;
@@ -602,7 +602,7 @@ StatusCode LArPileUpTool::processAllSubEvents()
 
   }  // if pileup
 
-  if (this->mergeEvent().isFailure()) {
+  if (this->mergeEvent(ctx).isFailure()) {
     ATH_MSG_ERROR("error in mergeEvent");
     return StatusCode::FAILURE;
   }
@@ -614,9 +614,9 @@ StatusCode LArPileUpTool::processAllSubEvents()
 // ---------------------------------------------------------------------------------------------------------------------------------
 
 
-StatusCode LArPileUpTool::mergeEvent()
+StatusCode LArPileUpTool::mergeEvent(const EventContext& ctx)
 {
-   SG::ReadCondHandle<LArBadFebCont> badFebHdl(m_badFebKey);
+   SG::ReadCondHandle<LArBadFebCont> badFebHdl(m_badFebKey, ctx);
    const LArBadFebCont* badFebs=*badFebHdl;
 
    int it,it_end;
@@ -628,7 +628,7 @@ StatusCode LArPileUpTool::mergeEvent()
    const std::vector<std::pair<float,float> >* TimeE_DigiHSTruth = nullptr;
 
    ATHRNG::RNGWrapper* rngWrapper = m_rndmGenSvc->getEngine(this);
-   CLHEP::HepRandomEngine * engine = *rngWrapper;
+   CLHEP::HepRandomEngine * engine = rngWrapper->getEngine(ctx);
 
    for( ; it!=it_end;++it) // now loop on cells
    {
@@ -652,7 +652,7 @@ StatusCode LArPileUpTool::mergeEvent()
 	    // MakeDigit called if in no overlay mode or
 	    // if in overlay mode and random digit exists
 	    if( (!m_RndmEvtOverlay) || (m_RndmEvtOverlay && digit) ) {
-	      if ( this->MakeDigit(cellID, ch_id,TimeE, digit, engine, TimeE_DigiHSTruth)
+              if ( this->MakeDigit(ctx,cellID, ch_id,TimeE, digit, engine, TimeE_DigiHSTruth)
 		   == StatusCode::FAILURE ) return StatusCode::FAILURE;
 	    }
 	  }
@@ -1590,7 +1590,7 @@ void LArPileUpTool::cross_talk(const IdentifierHash& hashId,
 // ----------------------------------------------------------------------------------------------------------------------------------
 
 
-StatusCode LArPileUpTool::MakeDigit(const Identifier & cellId,
+StatusCode LArPileUpTool::MakeDigit(const EventContext& ctx, const Identifier & cellId,
                                     HWIdentifier & ch_id,
                                     const std::vector<std::pair<float,float> >* TimeE,
                                     const LArDigit * rndmEvtDigit, CLHEP::HepRandomEngine * engine,
@@ -1614,24 +1614,24 @@ StatusCode LArPileUpTool::MakeDigit(const Identifier & cellId,
   std::vector<float> rndm_energy_samples(m_NSamples) ;
 
 
-  SG::ReadCondHandle<LArADC2MeV> adc2mevHdl(m_adc2mevKey);
+  SG::ReadCondHandle<LArADC2MeV> adc2mevHdl(m_adc2mevKey, ctx);
   const LArADC2MeV* adc2MeVs=*adc2mevHdl;
 
-  SG::ReadCondHandle<ILArfSampl> fSamplHdl(m_fSamplKey);
+  SG::ReadCondHandle<ILArfSampl> fSamplHdl(m_fSamplKey, ctx);
   const ILArfSampl* fSampl=*fSamplHdl;
 
-  SG::ReadCondHandle<ILArPedestal> pedHdl(m_pedestalKey);
+  SG::ReadCondHandle<ILArPedestal> pedHdl(m_pedestalKey, ctx);
   const ILArPedestal* pedestal=*pedHdl;
 
   const ILArNoise* noise=nullptr;  
   if ( !m_RndmEvtOverlay && !m_pedestalNoise && m_NoiseOnOff ){
-    SG::ReadCondHandle<ILArNoise> noiseHdl(m_noiseKey);
+    SG::ReadCondHandle<ILArNoise> noiseHdl(m_noiseKey, ctx);
     noise=*noiseHdl;
   }
 
   const LArAutoCorrNoise* autoCorrNoise=nullptr;
   if ( !m_RndmEvtOverlay  &&  m_NoiseOnOff) {
-    SG::ReadCondHandle<LArAutoCorrNoise>  autoCorrNoiseHdl(m_autoCorrNoiseKey);
+    SG::ReadCondHandle<LArAutoCorrNoise>  autoCorrNoiseHdl(m_autoCorrNoiseKey, ctx);
     autoCorrNoise=*autoCorrNoiseHdl;
   }
 
@@ -1690,9 +1690,9 @@ StatusCode LArPileUpTool::MakeDigit(const Identifier & cellId,
   if (m_useBad) isDead = m_maskingTool->cellShouldBeMasked(ch_id);
 
   if (!isDead) {
-    if( this->ConvertHits2Samples(cellId,ch_id,initialGain,TimeE, m_Samples).isFailure() ) return StatusCode::SUCCESS;
+    if( this->ConvertHits2Samples(ctx, cellId,ch_id,initialGain,TimeE, m_Samples).isFailure() ) return StatusCode::SUCCESS;
     if(m_doDigiTruth){
-      if( this->ConvertHits2Samples(cellId,ch_id,initialGain,TimeE_DigiHSTruth, m_Samples_DigiHSTruth).isFailure() ) return StatusCode::SUCCESS;
+      if( this->ConvertHits2Samples(ctx, cellId,ch_id,initialGain,TimeE_DigiHSTruth, m_Samples_DigiHSTruth).isFailure() ) return StatusCode::SUCCESS;
     }
   }
 
@@ -1719,7 +1719,7 @@ StatusCode LArPileUpTool::MakeDigit(const Identifier & cellId,
 //   this requires to take into account the sum of the optimal filter coefficients, as they don't compute with ADC shift
      float adc0=0.;
      if (!m_isMcOverlay && rndmEvtDigit->gain()>0) {
-        SG::ReadCondHandle<ILArOFC> larOFC(m_OFCKey);
+        SG::ReadCondHandle<ILArOFC> larOFC(m_OFCKey, ctx);
         if (larOFC.cptr() != nullptr) {
           ILArOFC::OFCRef_t ofc_a = larOFC->OFC_a(ch_id,rndmEvtDigit->gain(),0);
           float sumOfc=0.;
@@ -1809,9 +1809,9 @@ StatusCode LArPileUpTool::MakeDigit(const Identifier & cellId,
      }
 
      if (!isDead) {
-       if( this->ConvertHits2Samples(cellId,ch_id,igain,TimeE, m_Samples) == StatusCode::FAILURE ) return StatusCode::SUCCESS;
+       if( this->ConvertHits2Samples(ctx, cellId,ch_id,igain,TimeE, m_Samples) == StatusCode::FAILURE ) return StatusCode::SUCCESS;
        if(m_doDigiTruth){
-         if( this->ConvertHits2Samples(cellId,ch_id,igain,TimeE_DigiHSTruth, m_Samples_DigiHSTruth) == StatusCode::FAILURE ) return StatusCode::SUCCESS;
+         if( this->ConvertHits2Samples(ctx, cellId,ch_id,igain,TimeE_DigiHSTruth, m_Samples_DigiHSTruth) == StatusCode::FAILURE ) return StatusCode::SUCCESS;
        }
      }
 
@@ -1877,7 +1877,7 @@ StatusCode LArPileUpTool::MakeDigit(const Identifier & cellId,
 //   this requires to take into account the sum of the optimal filter coefficients, as they don't compute with ADC shift
   if(!m_isMcOverlay && m_RndmEvtOverlay  && igain>0)
   {
-    SG::ReadCondHandle<ILArOFC> larOFC(m_OFCKey);
+    SG::ReadCondHandle<ILArOFC> larOFC(m_OFCKey, ctx);
     if (larOFC.cptr() != nullptr) {
       float sumOfc=0.;
       ILArOFC::OFCRef_t ofc_a = larOFC->OFC_a(ch_id,igain,0);
@@ -1965,7 +1965,8 @@ StatusCode LArPileUpTool::MakeDigit(const Identifier & cellId,
 
 // ----------------------------------------------------------------------------------------------------------------------------------
 
-StatusCode LArPileUpTool::ConvertHits2Samples(const Identifier & cellId, const HWIdentifier ch_id, CaloGain::CaloGain igain,
+StatusCode LArPileUpTool::ConvertHits2Samples(const EventContext& ctx,
+                                              const Identifier & cellId, const HWIdentifier ch_id, CaloGain::CaloGain igain,
 					      //const std::vector<std::pair<float,float> >  *TimeE)
 					      const std::vector<std::pair<float,float> >  *TimeE, std::vector<double> &sampleList)
 
@@ -1979,7 +1980,7 @@ StatusCode LArPileUpTool::ConvertHits2Samples(const Identifier & cellId, const H
    float energy ;
    float time ;
 
-   SG::ReadCondHandle<ILArShape> shapeHdl(m_shapeKey);
+   SG::ReadCondHandle<ILArShape> shapeHdl(m_shapeKey, ctx);
    const ILArShape* shape=*shapeHdl;
 
 
diff --git a/MagneticField/MagFieldConditions/CMakeLists.txt b/MagneticField/MagFieldConditions/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1a0c270a9d278cba049e4e26b37b0e4a888e5cbb
--- /dev/null
+++ b/MagneticField/MagFieldConditions/CMakeLists.txt
@@ -0,0 +1,28 @@
+################################################################################
+# Package: MagFieldConditions
+################################################################################
+
+# Declare the package name:
+atlas_subdir( MagFieldConditions )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs( PUBLIC
+                          Control/StoreGate
+                          MagneticField/MagFieldInterfaces
+			  GaudiKernel
+                          PRIVATE
+                          MagneticField/MagFieldElements
+                          )
+
+# External dependencies:
+find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
+
+# Component(s) in the package:
+atlas_add_library( MagFieldConditions
+                   src/*.cxx
+                   PUBLIC_HEADERS MagFieldConditions
+                   PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+                   LINK_LIBRARIES SGTools GaudiKernel StoreGateLib
+                   PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} MagFieldElements)
+
+
diff --git a/MagneticField/MagFieldConditions/MagFieldConditions/ATLAS_CHECK_THREAD_SAFETY b/MagneticField/MagFieldConditions/MagFieldConditions/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..eacd609fa9ee5f3dbef77414bf94058d341c1284
--- /dev/null
+++ b/MagneticField/MagFieldConditions/MagFieldConditions/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+MagneticField/MagFieldConditions
diff --git a/MagneticField/MagFieldConditions/MagFieldConditions/AtlasFieldCacheCondObj.h b/MagneticField/MagFieldConditions/MagFieldConditions/AtlasFieldCacheCondObj.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c9238116fadda7693ec4e4c1dea2a6ef8d34c05
--- /dev/null
+++ b/MagneticField/MagFieldConditions/MagFieldConditions/AtlasFieldCacheCondObj.h
@@ -0,0 +1,70 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MAGFIELDCONDITIONS_ATLASMTFIELDCONDOBJ
+#define MAGFIELDCONDITIONS_ATLASMTFIELDCONDOBJ
+
+// MagField includes
+#include "AthenaKernel/CondCont.h" 
+#include "GaudiKernel/ServiceHandle.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+
+// forward declarations
+namespace MagField {
+    class AtlasFieldMap;
+}
+
+
+class AtlasFieldCacheCondObj {
+
+public:
+    AtlasFieldCacheCondObj();
+
+    ~AtlasFieldCacheCondObj();
+
+    /// Temporary flag for switching between 'old' and 'new' magField usage
+    bool useNewBfieldCache() { return m_useNewBfieldCache; }
+
+    /** get B field cache for evaluation as a function of 2-d (solenoid) or 3-d (toroid) position. 
+        Resets cache to an initialized state */
+    inline void getInitializedCache (MagField::AtlasFieldCache& cache) const;
+
+    /** access to solenoid field scale factor */
+    double solenoidFieldScaleFactor() const { return m_solFieldScale; } ;
+
+    /** access to toroid field scale factor */
+    double toriodFieldScaleFactor() const { return m_torFieldScale; } ;
+
+    /** set values for field scale and service to be able to build the cache **/
+    bool initialize(double solFieldScale, double torFieldScale, 
+                    const MagField::AtlasFieldMap* fieldMap,
+                    bool useNewBfieldCache);
+
+private:
+    /// Temporary flag for switching between 'old' and 'new' magField usage
+    bool                             m_useNewBfieldCache{false};
+    double                           m_solFieldScale{1};
+    double                           m_torFieldScale{1};
+    const MagField::AtlasFieldMap*   m_fieldMap{nullptr};
+};
+
+// inline function(s)
+
+void
+AtlasFieldCacheCondObj::getInitializedCache (MagField::AtlasFieldCache& cache) const
+{
+
+    // setup with field scale and magnetic field service for first access to field */
+    cache = MagField::AtlasFieldCache(m_solFieldScale, m_torFieldScale, m_fieldMap, m_useNewBfieldCache);
+}
+
+
+#include "AthenaKernel/CLASS_DEF.h"
+CLASS_DEF( AtlasFieldCacheCondObj, 258146572, 1)
+#include "AthenaKernel/CondCont.h"
+CONDCONT_DEF (AtlasFieldCacheCondObj, 3622068);
+
+
+#endif // MAGFIELDCONDITIONS_ATLASMTFIELDCONDOBJ
+
diff --git a/MagneticField/MagFieldConditions/MagFieldConditions/AtlasFieldMapCondObj.h b/MagneticField/MagFieldConditions/MagFieldConditions/AtlasFieldMapCondObj.h
new file mode 100644
index 0000000000000000000000000000000000000000..3f197a6bffc96a2303f60fdfc0dd4e9f6153c65b
--- /dev/null
+++ b/MagneticField/MagFieldConditions/MagFieldConditions/AtlasFieldMapCondObj.h
@@ -0,0 +1,38 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MAGFIELDCONDITIONS_ATLASMTFIELDMAPCONDOBJ
+#define MAGFIELDCONDITIONS_ATLASMTFIELDMAPCONDOBJ
+
+// MagField includes
+#include "AthenaKernel/CondCont.h" 
+#include "MagFieldElements/AtlasFieldMap.h"
+
+class AtlasFieldMapCondObj {
+
+public:
+    AtlasFieldMapCondObj();
+
+    ~AtlasFieldMapCondObj();
+
+    // access to field map 
+    const MagField::AtlasFieldMap* fieldMap () const;
+
+    // setter
+    void setFieldMap(std::unique_ptr<MagField::AtlasFieldMap> fieldMap);
+    
+private:
+    // field map 
+    std::unique_ptr<MagField::AtlasFieldMap> m_fieldMap;
+};
+
+
+#include "AthenaKernel/CLASS_DEF.h"
+CLASS_DEF( AtlasFieldMapCondObj, 122915602, 1)
+#include "AthenaKernel/CondCont.h"
+CONDCONT_DEF (AtlasFieldMapCondObj, 249359246);
+
+
+#endif // MAGFIELDCONDITIONS_ATLASMTFIELDMAPCONDOBJ
+
diff --git a/MagneticField/MagFieldConditions/src/AtlasFieldCacheCondObj.cxx b/MagneticField/MagFieldConditions/src/AtlasFieldCacheCondObj.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4423ac75c0ee2f2ad1a9eb9f06ec3f019727debf
--- /dev/null
+++ b/MagneticField/MagFieldConditions/src/AtlasFieldCacheCondObj.cxx
@@ -0,0 +1,25 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+
+AtlasFieldCacheCondObj::AtlasFieldCacheCondObj()
+{}
+
+AtlasFieldCacheCondObj::~AtlasFieldCacheCondObj() {}
+
+
+bool
+AtlasFieldCacheCondObj::initialize(double solFieldScale,
+                                   double torFieldScale,
+                                   const MagField::AtlasFieldMap* fieldMap,
+                                   bool useNewBfieldCache)
+{
+    // temporary flag
+    m_useNewBfieldCache = useNewBfieldCache;
+    m_solFieldScale = solFieldScale;
+    m_torFieldScale = torFieldScale;
+    m_fieldMap      = fieldMap;
+    return (m_fieldMap) != nullptr; // return false if cast failed
+}
+
diff --git a/MagneticField/MagFieldConditions/src/AtlasFieldMapCondObj.cxx b/MagneticField/MagFieldConditions/src/AtlasFieldMapCondObj.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6214d3d6cd68dd7515f5ef5845b46c3658d121b2
--- /dev/null
+++ b/MagneticField/MagFieldConditions/src/AtlasFieldMapCondObj.cxx
@@ -0,0 +1,23 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+#include "MagFieldConditions/AtlasFieldMapCondObj.h"
+
+AtlasFieldMapCondObj::AtlasFieldMapCondObj() {}
+
+AtlasFieldMapCondObj::~AtlasFieldMapCondObj() {}
+
+// access to field map 
+const MagField::AtlasFieldMap*
+AtlasFieldMapCondObj::fieldMap () const
+{
+    return m_fieldMap.get();
+}
+
+// setter
+void
+AtlasFieldMapCondObj::setFieldMap(std::unique_ptr<MagField::AtlasFieldMap> fieldMap)
+{
+    m_fieldMap = std::move(fieldMap);
+}
+
diff --git a/MagneticField/MagFieldElements/CMakeLists.txt b/MagneticField/MagFieldElements/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c04fc6894dabb297e4356d68d2f74318ba72f1c8
--- /dev/null
+++ b/MagneticField/MagFieldElements/CMakeLists.txt
@@ -0,0 +1,36 @@
+################################################################################
+# Package: MagFieldElements
+################################################################################
+
+# Declare the package name:
+atlas_subdir( MagFieldElements )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs( PUBLIC
+                          Control/AthenaBaseComps
+                          MagneticField/MagFieldInterfaces
+                          MagneticField/MagFieldConditions
+			  Control/CxxUtils
+                          PRIVATE
+                          MagneticField/MagFieldElements
+                          Control/StoreGate
+                          Database/AthenaPOOL/AthenaPoolUtilities
+                          GaudiKernel
+                          Tools/PathResolver )
+
+# External dependencies:
+find_package( CLHEP )
+find_package( Eigen )
+find_package( ROOT COMPONENTS Core Tree MathCore Hist RIO pthread )
+
+# Component(s) in the package:
+atlas_add_library( MagFieldElements
+                   src/*.cxx
+                   PUBLIC_HEADERS MagFieldElements
+                   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS}
+		   LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES}  ${EIGEN_LIBRARIES} AthenaBaseComps GaudiKernel CxxUtils)
+
+# Install files from the package:
+atlas_install_headers( MagFieldElements )
+
+
diff --git a/MagneticField/MagFieldElements/MagFieldElements/ATLAS_CHECK_THREAD_SAFETY b/MagneticField/MagFieldElements/MagFieldElements/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..4f7c45a0c80ff2ed3733bb4f188a61eaf79e98df
--- /dev/null
+++ b/MagneticField/MagFieldElements/MagFieldElements/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+MagneticField/MagFieldElements
diff --git a/MagneticField/MagFieldElements/MagFieldElements/AtlasFieldCache.h b/MagneticField/MagFieldElements/MagFieldElements/AtlasFieldCache.h
new file mode 100644
index 0000000000000000000000000000000000000000..c61d4e776d509657ea10b8417cc04e3c5aaccd80
--- /dev/null
+++ b/MagneticField/MagFieldElements/MagFieldElements/AtlasFieldCache.h
@@ -0,0 +1,217 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @author R.D.Schaffer -at- cern.ch
+ * @date July 2019
+ * @brief Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
+ */
+
+#ifndef MAGFIELDCONDITIONS_ATLASMTFIELDCACHE_H
+#define MAGFIELDCONDITIONS_ATLASMTFIELDCACHE_H 1
+
+// MagField includes
+#include "MagFieldElements/AtlasFieldMap.h"
+#include "MagFieldElements/BFieldCache.h"
+#include "MagFieldElements/BFieldCacheZR.h"
+#include "MagFieldElements/BFieldCond.h"
+#include "MagFieldElements/BFieldZone.h"
+#include "MagFieldElements/BFieldMeshZR.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "CxxUtils/restrict.h"
+// CLHEP
+#include "CLHEP/Units/SystemOfUnits.h"
+#include<iostream>
+#include <memory>
+namespace MagField {
+
+    
+/** @class AtlasFieldCache
+ *
+ *  @brief Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
+ *
+ *  @author R.D.Schaffer -at- cern.ch
+ */
+    class AtlasFieldCache
+    // : public ::AthMessaging
+    {
+    public:
+        AtlasFieldCache();
+        // ** constructor to setup with field scale and magnetic field service for first access to field */
+        AtlasFieldCache(double solFieldScale,
+                        double torFieldScale,
+                        const AtlasFieldMap* fieldMap,
+                        bool useNewBfieldCache);
+        AtlasFieldCache& operator= (AtlasFieldCache&& other)      = default;
+        ~AtlasFieldCache() = default; 
+ 
+        /// Temporary flag for switching between 'old' and 'new' magField usage
+        bool useNewBfieldCache() { return m_useNewBfieldCache; }
+
+        /** get B field value at given position */
+        /** xyz[3] is in mm, bxyz[3] is in kT */
+        /** if deriv[9] is given, field derivatives are returned in kT/mm */
+        inline void getField  (const double* ATH_RESTRICT xyz, 
+                               double* ATH_RESTRICT bxyz, 
+                               double* ATH_RESTRICT deriv = nullptr);
+        inline void getFieldZR(const double* ATH_RESTRICT xyz, 
+                               double* ATH_RESTRICT bxyz, 
+                               double* ATH_RESTRICT deriv = nullptr);
+    
+    private:
+    
+        AtlasFieldCache(const AtlasFieldCache& other)             = delete;
+        AtlasFieldCache& operator= (const AtlasFieldCache& other) = delete;
+        AtlasFieldCache(AtlasFieldCache&& other)                  = delete;
+
+        inline bool fillFieldCache(double z, double r, double phi);
+        inline bool fillFieldCacheZR(double z, double r);
+
+        /// Temporary flag for switching between 'old' and 'new' magField usage
+        bool m_useNewBfieldCache{false};
+
+        /// magnetic field scales from currents
+        double m_solScale{1};
+        double m_torScale{1};
+        double m_scaleToUse{1};
+        // Solenoid zone ID number - needed to set solScale. Assumes only one Solenoid zone!
+        int    m_solZoneId{-1}; 
+
+        /// handle to the magnetic field service - not owner
+        const AtlasFieldMap* m_fieldMap;
+
+        /// Pointer to the conductors in the current field zone (to compute Biot-Savart component)
+        /// Owned by AtlasFieldMap. 
+        const std::vector<BFieldCond>* m_cond{nullptr};
+
+        /// Full 3d field
+        BFieldCache   m_cache3d;
+
+        /// Fast 2d field
+        BFieldCacheZR m_cacheZR;
+
+        // fast 2d map (made of one zone)
+        /// Owned by AtlasFieldMap.
+        const BFieldMeshZR* m_meshZR{nullptr};
+        
+    };
+
+}  // namespace MagField
+
+
+/** fill given magnetic field zone */
+bool
+MagField::AtlasFieldCache::fillFieldCache(double z, double r, double phi) 
+{
+    // search for the zone
+    const BFieldZone* zone = m_fieldMap->findBFieldZone( z, r, phi );
+    if ( zone == nullptr ) {
+        // outsize all zones
+        return false;
+    }
+
+    // set scale for field
+    if (zone->id() == m_solZoneId) {
+        m_scaleToUse = m_solScale;
+    }
+    else {
+        m_scaleToUse = m_torScale;
+    }
+
+    // fill the cache, pass in current scale factor
+    zone->getCache( z, r, phi, m_cache3d, m_scaleToUse );
+
+    // save pointer to the conductors in the zone
+    m_cond = zone->condVector();
+
+    return true;
+}
+
+/** fill Z-R cache for solenoid */
+bool
+MagField::AtlasFieldCache::fillFieldCacheZR(double z, double r) 
+{
+    // is it inside the solenoid zone?
+    if ( m_meshZR && m_meshZR->inside( z, r ) ) {
+
+        // fill the cache, pass in current scale factor
+        m_meshZR->getCache( z, r, m_cacheZR, m_solScale );
+
+    } else {
+        // outside solenoid
+        return false;
+    }
+    return true;
+}
+
+
+void
+MagField::AtlasFieldCache::getField(const double* ATH_RESTRICT xyz, 
+                                    double* ATH_RESTRICT bxyz, 
+                                    double* ATH_RESTRICT deriv) 
+{
+    const double &x(xyz[0]);
+    const double &y(xyz[1]);
+    const double &z(xyz[2]);
+    double r = std::sqrt(x * x + y * y);
+    double phi = std::atan2(y, x);
+
+    // test if initialised and the cache is valid
+    if ( !m_cache3d.inside(z, r, phi) ) {
+        // cache is invalid -> refresh cache
+        if (!fillFieldCache(z, r, phi)) {
+            // caching failed -> outside the valid map volume
+            // return default field (0.1 gauss)
+            const double defaultB(0.1*CLHEP::gauss);
+            bxyz[0] = bxyz[1] = bxyz[2] = defaultB;
+            // return zero gradient if requested
+            if ( deriv ) {
+                for ( int i = 0; i < 9; i++ ) {
+                    deriv[i] = 0.;
+                }
+            }
+            return;
+        }
+    }
+
+    // do interpolation (cache3d has correct scale factor)
+    m_cache3d.getB(xyz, r, phi, bxyz, deriv);
+    // add biot savart component - must add in scale factor to avoid changing conductor SF since the
+    // conductor is part of the static magnetic field model
+    if (m_cond) {
+        const size_t condSize = m_cond->size();
+        for (size_t i = 0; i < condSize; i++) {
+            (*m_cond)[i].addBiotSavart(m_scaleToUse, xyz, bxyz, deriv); 
+        }
+    }
+} 
+
+void
+MagField::AtlasFieldCache::getFieldZR(const double* ATH_RESTRICT xyz, 
+                                      double* ATH_RESTRICT bxyz, 
+                                      double* ATH_RESTRICT deriv) 
+{
+    const double &x(xyz[0]);
+    const double &y(xyz[1]);
+    const double &z(xyz[2]);
+    double r = sqrt(x * x + y * y);
+
+    // test if the cache was initialized and the ZR cache is valid for current position
+    if ( !m_cacheZR.inside(z, r) ) {
+
+        // cache is invalid -> refresh cache
+        if (!fillFieldCacheZR(z, r)) {
+
+            // caching failed -> outside the valid z-r map volume
+            // call the full version of getField()
+            getField(xyz, bxyz, deriv);
+            return;
+
+        }
+    }
+    // do interpolation
+    m_cacheZR.getB(xyz, r, bxyz, deriv);
+}
+
+#endif  // MAGFIELDCONDITIONS_ATLASMTFIELDCACHE_H
diff --git a/MagneticField/MagFieldElements/MagFieldElements/AtlasFieldMap.h b/MagneticField/MagFieldElements/MagFieldElements/AtlasFieldMap.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b69428c738610d7fa966c2cebff13932442c720
--- /dev/null
+++ b/MagneticField/MagFieldElements/MagFieldElements/AtlasFieldMap.h
@@ -0,0 +1,117 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @author R.D.Schaffer -at- cern.ch
+ * @date end 2019
+ * @brief Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
+ */
+
+#ifndef MAGFIELDCONDITIONS_ATLASFIELDMAP_H
+#define MAGFIELDCONDITIONS_ATLASFIELDMAP_H 1
+
+// MagField includes
+#include "MagFieldElements/BFieldCache.h"
+#include "MagFieldElements/BFieldCacheZR.h"
+#include "MagFieldElements/BFieldCond.h"
+#include "MagFieldElements/BFieldZone.h"
+#include "MagFieldElements/BFieldMeshZR.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "CxxUtils/restrict.h"
+// CLHEP
+#include "CLHEP/Units/SystemOfUnits.h"
+#include<iostream>
+#include <memory>
+
+// forward declarations
+class TFile;
+
+namespace MagField {
+
+    
+/** @class AtlasFieldMap
+ *
+ *  @brief Map for magnetic field 
+ *
+ *  @author R.D.Schaffer -at- cern.ch
+ */
+    class AtlasFieldMap
+    {
+    public:
+        AtlasFieldMap();
+        ~AtlasFieldMap(); 
+
+        // initialize map from root file
+        bool initializeMap( TFile* rootfile, float solenoidCurrent, float toroidCurrent);
+
+        // Functions used by getField[ZR] in AtlasFieldCache
+        // search for a "zone" to which the point (z,r,phi) belongs
+        const BFieldZone* findBFieldZone( double z, double r, double phi ) const;
+
+        // fast 2d map (made of one zone)
+        const BFieldMeshZR* getBFieldMesh() const;
+
+        /** status of the magnets */
+        bool solenoidOn() const { return solenoidCurrent() > 0.0; }
+        bool toroidOn() const   { return toroidCurrent()   > 0.0; }
+        // magnet currents read with map - needed for scaling
+        float solenoidCurrent() const { return m_solenoidCurrent; }
+        float toroidCurrent() const   { return m_toroidCurrent;   }
+        int   solenoidZoneId() const  { return m_solenoidZoneId;  }
+    private:
+    
+        AtlasFieldMap& operator= (AtlasFieldMap&& other)      = delete;
+        AtlasFieldMap(const AtlasFieldMap& other)             = delete;
+        AtlasFieldMap& operator= (const AtlasFieldMap& other) = delete;
+        AtlasFieldMap(AtlasFieldMap&& other)                  = delete;
+
+        // slow zone search is used during initialization to build the LUT
+        BFieldZone* findZoneSlow( double z, double r, double phi );
+
+        // utility functions used by readMap
+        int read_packed_data( std::istream& input, std::vector<int>& data ) const;
+        int read_packed_int( std::istream& input, int &n ) const;
+        void buildLUT();
+        void buildZR();
+
+        /** approximate memory footprint in bytes */
+        int memSize() const;
+
+        /** Data Members **/
+
+        // field map name
+        std::string m_filename; 
+
+        // currents read in with map
+        float m_solenoidCurrent{0}; // solenoid current in ampere
+        float m_toroidCurrent{0};   // toroid current in ampere
+        int   m_solenoidZoneId{-1}; // solenoid zone id
+
+        // full 3d map (made of multiple zones)
+        std::vector<BFieldZone>        m_zone;
+
+        // fast 2d map (made of one zone)
+        BFieldMeshZR*                  m_meshZR{nullptr};
+
+        // data members used in zone-finding
+        std::vector<double>            m_edge[3];    // zone boundaries in z, r, phi
+        std::vector<int>               m_edgeLUT[3]; // look-up table for zone edges
+        double                         m_invq[3];    // 1/stepsize in m_edgeLUT
+        std::vector<const BFieldZone*> m_zoneLUT; // look-up table for zones
+        // more data members to speed up zone-finding
+        double                         m_zmin{0};   // minimum z
+        double                         m_zmax{0};   // maximum z
+        int                            m_nz  {0};   // number of z bins in zoneLUT
+        double                         m_rmax{0};   // maximum r
+        int                            m_nr  {0};   // number of r bins in zoneLUT
+        int                            m_nphi{0};   // number of phi bins in zoneLUT
+        bool                           m_mapIsInitialized{false};
+        
+    };
+
+}  // namespace MagField
+
+
+
+#endif  // MAGFIELDCONDITIONS_ATLASFIELDMAP_H
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldCache.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldCache.h
similarity index 86%
rename from MagneticField/MagFieldServices/MagFieldServices/BFieldCache.h
rename to MagneticField/MagFieldElements/MagFieldElements/BFieldCache.h
index f97aeaa6a6b020db4f2129b306af2e2cfe7759ed..ff0d19a0c192f517e405326465aea0b4f204baf8 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/BFieldCache.h
+++ b/MagneticField/MagFieldElements/MagFieldElements/BFieldCache.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -15,7 +15,7 @@
 
 #include <iostream>
 #include <cmath>
-#include "MagFieldServices/BFieldVector.h"
+#include "MagFieldElements/BFieldVector.h"
 
 class BFieldCache {
 public:
@@ -27,17 +27,21 @@ public:
     void setRange( double zmin, double zmax, double rmin, double rmax, double phimin, double phimax )
     { m_zmin = zmin; m_zmax = zmax; m_rmin = rmin; m_rmax = rmax; m_phimin = phimin; m_phimax = phimax;
       m_invz = 1.0/(zmax-zmin); m_invr = 1.0/(rmax-rmin); m_invphi = 1.0/(phimax-phimin); }
-    // set the field values at each corner
-    void setField( int i, const BFieldVector<double> &field ) { for(int j=0; j<3; j++) m_field[j][i] = field[j]; }
-    void setField( int i, const BFieldVector<short> &field ) { for(int j=0; j<3; j++) m_field[j][i] = field[j]; }    // set the multiplicative factor for the field vectors
+    // set the field values at each corner (rescale for current scale factor)
+    void setField( int i, const BFieldVector<double> &field, double scaleFactor = 1.0 )
+        { for(int j=0; j<3; j++) m_field[j][i] = scaleFactor * field[j]; }
+    void setField( int i, const BFieldVector<short> &field, double scaleFactor = 1.0 )
+        { for(int j=0; j<3; j++) m_field[j][i] = scaleFactor * field[j]; }
+    // set the multiplicative factor for the field vectors
     void setBscale( double bscale ) { m_scale = bscale; }
+    float bscale() { return m_scale; }
     // test if (z, r, phi) is inside this bin
     bool inside( double z, double r, double phi ) const
     { if ( phi < m_phimin ) phi += 2.0*M_PI;
       return ( phi >= m_phimin && phi <= m_phimax && z >= m_zmin && z <= m_zmax && r >= m_rmin && r <= m_rmax ); }
     // interpolate the field and return B[3].
     // also compute field derivatives if deriv[9] is given.
-    inline void getB( const double *xyz, double r, double phi, double *B, double *deriv=0 ) const;
+    inline void getB( const double *xyz, double r, double phi, double *B, double *deriv=nullptr ) const;
 private:
     double m_zmin, m_zmax; // bin range in z
     double m_rmin, m_rmax; // bin range in r
@@ -52,9 +56,12 @@ private:
 void
 BFieldCache::getB( const double *xyz, double r, double phi, double *B, double *deriv ) const
 {
+
+    
     const double &x(xyz[0]);
     const double &y(xyz[1]);
     const double &z(xyz[2]);
+
     // make sure phi is inside [m_phimin,m_phimax]
     if ( phi < m_phimin ) phi += 2*M_PI;
     // fractional position inside this bin
@@ -74,7 +81,11 @@ BFieldCache::getB( const double *xyz, double r, double phi, double *B, double *d
                                    fr*( gphi*field[6] + fphi*field[7] ) ) );
     }
     // convert (Bz,Br,Bphi) to (Bx,By,Bz)
-    float invr, c, s;
+    float invr;
+
+    float c;
+
+    float s;
     if ( r > 0.0 ) {
         invr = 1.0/r;
         c = x*invr;
@@ -93,7 +104,11 @@ BFieldCache::getB( const double *xyz, double r, double phi, double *B, double *d
         float sz = m_scale*m_invz;
         float sr = m_scale*m_invr;
         float sphi = m_scale*m_invphi;
-        float dBdz[3], dBdr[3], dBdphi[3];
+        float dBdz[3];
+
+        float dBdr[3];
+
+        float dBdphi[3];
         for ( int j = 0; j < 3; j++ ) { // Bz, Br, Bphi components
             const float *field = m_field[j];
             dBdz[j]   = sz*( gr*( gphi*(field[4]-field[0]) + fphi*(field[5]-field[1]) ) +
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldCacheZR.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldCacheZR.h
similarity index 87%
rename from MagneticField/MagFieldServices/MagFieldServices/BFieldCacheZR.h
rename to MagneticField/MagFieldElements/MagFieldElements/BFieldCacheZR.h
index 867a964eb5402b50a32d354041940d9fa10a2da2..77addc177c7a6d54bff209a227d1b9e7013db8c3 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/BFieldCacheZR.h
+++ b/MagneticField/MagFieldElements/MagFieldElements/BFieldCacheZR.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -13,30 +13,30 @@
 #ifndef BFIELDCACHEZR_H
 #define BFIELDCACHEZR_H
 
-#include "MagFieldServices/BFieldVectorZR.h"
+#include "MagFieldElements/BFieldVectorZR.h"
 #include <iostream>
 #include <cmath>
 
 class BFieldCacheZR {
 public:
     // default constructor sets unphysical boundaries, so that inside() will fail
-    BFieldCacheZR() : m_zmin(0.0), m_zmax(-1.0), m_rmin(0.0), m_rmax(-1.0) {;}
+    BFieldCacheZR() : m_zmin(0.0), m_zmax(-1.0), m_rmin(0.0), m_rmax(-1.0) {}
     // invalidate this cache, so that inside() will fail
     void invalidate() { m_rmin = 0.0; m_rmax = -1.0; }
     // set the z, r range that defines the bin
     void setRange( double zmin, double zmax, double rmin, double rmax )
     { m_zmin = zmin; m_zmax = zmax; m_rmin = rmin; m_rmax = rmax;
       m_invz = 1.0/(zmax-zmin); m_invr = 1.0/(rmax-rmin); }
-    // set the field values at each corner
-    void setField( int i, const BFieldVectorZR &field )
-    { m_field[0][i] = field[0]; m_field[1][i] = field[1]; }
+    // set the field values at each corner (rescale for current scale factor)
+    void setField( int i, const BFieldVectorZR &field, double scaleFactor = 1.0 )
+    { m_field[0][i] = scaleFactor * field[0]; m_field[1][i] = scaleFactor * field[1]; }
     // set the multiplicative factor for the field vectors
     // test if (z, r) is inside this bin
     bool inside( double z, double r ) const
     { return ( z >= m_zmin && z <= m_zmax && r >= m_rmin && r <= m_rmax ); }
     // interpolate the field and return B[3].
     // also compute field derivatives if deriv[9] is given.
-    inline void getB( const double *xyz, double r, double *B, double *deriv=0 ) const;
+    inline void getB( const double *xyz, double r, double *B, double *deriv=nullptr ) const;
 private:
     double m_zmin, m_zmax; // bin range in z
     double m_rmin, m_rmax; // bin range in r
@@ -78,7 +78,9 @@ BFieldCacheZR::getB( const double *xyz, double r, double *B, double *deriv ) con
 
     // compute field derivatives if requested
     if ( deriv ) {
-        float dBdz[2], dBdr[2];
+        float dBdz[2];
+
+        float dBdr[2];
         for ( int j = 0; j < 2; j++ ) { // Bz, Br components
             const float *field = m_field[j];
             dBdz[j]   = m_invz*( gr*(field[2]-field[0]) + fr*(field[3]-field[1]) );
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldCond.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldCond.h
similarity index 77%
rename from MagneticField/MagFieldServices/MagFieldServices/BFieldCond.h
rename to MagneticField/MagFieldElements/MagFieldElements/BFieldCond.h
index 9857ef4a0bc6c993f1d7e0e0eeb47ffd85ecbe26..63909d5057b2066cb99e034701accb79b8d946e6 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/BFieldCond.h
+++ b/MagneticField/MagFieldElements/MagFieldElements/BFieldCond.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -30,7 +30,7 @@ public:
     {}
 
     // compute magnetic field, plus derivatives if requested, and add
-    inline void addBiotSavart( const double *xyz, double *B, double *deriv=0 ) const;
+    inline void addBiotSavart( double scaleFactor, const double *xyz, double *B, double *deriv=nullptr ) const;
     // scale the current wrt the nominal current
     void scaleCurrent( double factor ) { m_curr = factor*m_nomCurr; }
     // accessors
@@ -55,9 +55,14 @@ private:
 // Compute the Biot-Savart field due to this conductor
 // If deriv[9] is passed, also computes the field derivatives
 // The results are _added_ to B[] and deriv[].
+// The current scale factor can enter in one of two ways:
+//   1) the whole model is scaled using scaleCurrent
+//   2) each call is scaled with scaleFactor
+//   The former is the pre-multithreading way where the whole model is rebuilts for each changing current.
+//   The latter is the newer multithreading way where the model remains constant and there is 'per-thread' rescaling
 //
 void
-BFieldCond::addBiotSavart( const double *xyz, double *B_in, double *deriv ) const
+BFieldCond::addBiotSavart( double scaleFactor, const double *xyz, double *B_in, double *deriv ) const
 {
     static const double mu04pi = 1.0e-7;  // mu_0/4pi
     static const double minvsq = 10.*10.; // (1 cm)^2
@@ -70,10 +75,14 @@ BFieldCond::addBiotSavart( const double *xyz, double *B_in, double *deriv ) cons
     const Eigen::Vector3d v = m_u.cross(r1);
     const double vsq = std::max(v.squaredNorm(), minvsq);
 
-    const double r1u = r1.dot(m_u), r2u = r2.dot(m_u);
-    const double r1n = r1.norm(), r2n = r2.norm();
+    const double r1u = r1.dot(m_u);
 
-    const double f0 = mu04pi * m_curr / vsq;
+    const double r2u = r2.dot(m_u);
+    const double r1n = r1.norm();
+
+    const double r2n = r2.norm();
+
+    const double f0 = mu04pi * m_curr * scaleFactor / vsq;
     const double f1 = f0 * (m_finite ? r1u / r1n - r2u / r2n : 2.0);
     const double f2 = 2.0 * f1 / vsq;
 
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldMesh.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.h
similarity index 91%
rename from MagneticField/MagFieldServices/MagFieldServices/BFieldMesh.h
rename to MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.h
index de2ff9f1124b88e366928a8ccacf816414240d35..dfa7063a9cab0099962347b151ece755119b963a 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/BFieldMesh.h
+++ b/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -16,8 +16,8 @@
 #include <iostream>
 #include <vector>
 #include <cmath>
-#include "MagFieldServices/BFieldVector.h"
-#include "MagFieldServices/BFieldCache.h"
+#include "MagFieldElements/BFieldVector.h"
+#include "MagFieldElements/BFieldCache.h"
 
 template <class T>
 class BFieldMesh {
@@ -46,9 +46,9 @@ public:
     // test if a point is inside this zone
     inline bool inside( double z, double r, double phi ) const;
     // find the bin
-    inline void getCache( double z, double r, double phi, BFieldCache & cache ) const;
+    inline void getCache( double z, double r, double phi, BFieldCache & cache, double scaleFactor = 1.0 ) const;
     // get the B field
-    void getB( const double *xyz, double *B, double* deriv=0 ) const;
+    void getB( const double *xyz, double *B, double* deriv=nullptr ) const;
     // accessors
     double min( int i ) const { return m_min[i]; }
     double max( int i ) const { return m_max[i]; }
@@ -111,7 +111,7 @@ bool BFieldMesh<T>::inside( double z, double r, double phi ) const
 // Find and return the cache of the bin containing (z,r,phi)
 //
 template <class T>
-void BFieldMesh<T>::getCache( double z, double r, double phi, BFieldCache & cache ) const
+void BFieldMesh<T>::getCache( double z, double r, double phi, BFieldCache & cache, double scaleFactor ) const
 {
     // make sure phi is inside this zone
     if ( phi < phimin() ) phi += 2.0*M_PI;
@@ -135,17 +135,16 @@ void BFieldMesh<T>::getCache( double z, double r, double phi, BFieldCache & cach
     cache.setRange( mz[iz], mz[iz+1], mr[ir], mr[ir+1], mphi[iphi], mphi[iphi+1] );
     // store the B field at the 8 corners
     int im0 = iz*m_zoff+ir*m_roff+iphi; // index of the first corner
-    cache.setField( 0, m_field[im0              ] );
-    cache.setField( 1, m_field[im0            +1] );
-    cache.setField( 2, m_field[im0      +m_roff  ] );
-    cache.setField( 3, m_field[im0      +m_roff+1] );
-    cache.setField( 4, m_field[im0+m_zoff        ] );
-    cache.setField( 5, m_field[im0+m_zoff      +1] );
-    cache.setField( 6, m_field[im0+m_zoff+m_roff  ] );
-    cache.setField( 7, m_field[im0+m_zoff+m_roff+1] );
+    cache.setField( 0, m_field[im0              ],   scaleFactor );
+    cache.setField( 1, m_field[im0            +1],   scaleFactor );
+    cache.setField( 2, m_field[im0      +m_roff  ],  scaleFactor );
+    cache.setField( 3, m_field[im0      +m_roff+1],  scaleFactor );
+    cache.setField( 4, m_field[im0+m_zoff        ],  scaleFactor );
+    cache.setField( 5, m_field[im0+m_zoff      +1],  scaleFactor );
+    cache.setField( 6, m_field[im0+m_zoff+m_roff  ], scaleFactor );
+    cache.setField( 7, m_field[im0+m_zoff+m_roff+1], scaleFactor );
     // store the B scale
     cache.setBscale( m_scale );
-    return;
 }
 
 //
@@ -221,7 +220,11 @@ void BFieldMesh<T>::getB( const double *xyz, double *B, double* deriv ) const
         double sz = m_scale/(mz[iz+1]-mz[iz]);
         double sr = m_scale/(mr[ir+1]-mr[ir]);
         double sphi = m_scale/(mphi[iphi+1]-mphi[iphi]);
-        double dBdz[3], dBdr[3], dBdphi[3];
+        double dBdz[3];
+
+        double dBdr[3];
+
+        double dBdphi[3];
         for ( int j = 0; j < 3; j++ ) { // Bz, Br, Bphi components
             dBdz[j]   = sz*( gr*( gphi*(field[4][j]-field[0][j]) + fphi*(field[5][j]-field[1][j]) ) +
                              fr*( gphi*(field[6][j]-field[2][j]) + fphi*(field[7][j]-field[3][j]) ) );
@@ -244,8 +247,7 @@ void BFieldMesh<T>::getB( const double *xyz, double *B, double* deriv ) const
         deriv[7] = s*dBdr[1] + c*dBdphi[0]/r;
         deriv[8] = dBdz[0];
     }
-    return;
-}
+    }
 
 //
 // Construct the look-up table to accelerate bin-finding.
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldMeshZR.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldMeshZR.h
similarity index 85%
rename from MagneticField/MagFieldServices/MagFieldServices/BFieldMeshZR.h
rename to MagneticField/MagFieldElements/MagFieldElements/BFieldMeshZR.h
index defab56c610d1e0fd201342169b9d17b32d19e81..9cf3a688399136cacd97d3a980ed8900cd502b6e 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/BFieldMeshZR.h
+++ b/MagneticField/MagFieldElements/MagFieldElements/BFieldMeshZR.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -14,8 +14,8 @@
 
 #include <vector>
 #include <cmath>
-#include "MagFieldServices/BFieldVectorZR.h"
-#include "MagFieldServices/BFieldCacheZR.h"
+#include "MagFieldElements/BFieldVectorZR.h"
+#include "MagFieldElements/BFieldCacheZR.h"
 
 class BFieldMeshZR {
 public:
@@ -34,7 +34,7 @@ public:
     inline bool inside( double z, double r ) const
         { return ( z >= zmin() && z <= zmax() && r >= rmin() && r <= rmax() ); }
     // find the bin
-    inline void getCache( double z, double r, BFieldCacheZR & cache ) const;
+    inline void getCache( double z, double r, BFieldCacheZR & cache, double scaleFactor = 1.0 ) const;
     // accessors
     double min( int i ) const { return m_min[i]; }
     double max( int i ) const { return m_max[i]; }
@@ -61,7 +61,7 @@ private:
 // Find and return the cache of the bin containing (z,r)
 //
 inline void
-BFieldMeshZR::getCache( double z, double r, BFieldCacheZR & cache ) const
+BFieldMeshZR::getCache( double z, double r, BFieldCacheZR & cache, double scaleFactor ) const
 {
     // find the mesh, and relative location in the mesh
     // z
@@ -78,11 +78,10 @@ BFieldMeshZR::getCache( double z, double r, BFieldCacheZR & cache ) const
     cache.setRange( mz[iz], mz[iz+1], mr[ir], mr[ir+1] );
     // store the B field at the 8 corners
     int im0 = iz*m_zoff+ir; // index of the first corner
-    cache.setField( 0, m_field[im0         ] );
-    cache.setField( 1, m_field[im0       +1] );
-    cache.setField( 2, m_field[im0+m_zoff  ] );
-    cache.setField( 3, m_field[im0+m_zoff+1] );
-    return;
+    cache.setField( 0, m_field[im0         ], scaleFactor );
+    cache.setField( 1, m_field[im0       +1], scaleFactor );
+    cache.setField( 2, m_field[im0+m_zoff  ], scaleFactor );
+    cache.setField( 3, m_field[im0+m_zoff+1], scaleFactor );
 }
 
 #endif
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldVector.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldVector.h
similarity index 100%
rename from MagneticField/MagFieldServices/MagFieldServices/BFieldVector.h
rename to MagneticField/MagFieldElements/MagFieldElements/BFieldVector.h
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldVectorZR.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldVectorZR.h
similarity index 100%
rename from MagneticField/MagFieldServices/MagFieldServices/BFieldVectorZR.h
rename to MagneticField/MagFieldElements/MagFieldElements/BFieldVectorZR.h
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldZone.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldZone.h
similarity index 84%
rename from MagneticField/MagFieldServices/MagFieldServices/BFieldZone.h
rename to MagneticField/MagFieldElements/MagFieldElements/BFieldZone.h
index 531257cc3f8355d16f92d9542b7e5bdd8df2c9a1..a03e6b1fa657e63bf5ab38b65607f5f959285b7e 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/BFieldZone.h
+++ b/MagneticField/MagFieldElements/MagFieldElements/BFieldZone.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -13,8 +13,8 @@
 #define BFIELDZONE_H
 
 #include <vector>
-#include "MagFieldServices/BFieldMesh.h"
-#include "MagFieldServices/BFieldCond.h"
+#include "MagFieldElements/BFieldMesh.h"
+#include "MagFieldElements/BFieldCond.h"
 
 class BFieldZone : public BFieldMesh<short> {
 public:
@@ -25,8 +25,8 @@ public:
     // add elements to vectors
     void appendCond( const BFieldCond& cond ) { m_cond.push_back(cond); }
     // compute Biot-Savart magnetic field and add to B[3]
-    inline void addBiotSavart( const double *xyz, double *B, double *deriv=0 ) const;
-    // scale B field by a multiplicative factor
+    inline void addBiotSavart( const double *xyz, double *B, double *deriv=nullptr ) const;
+    // scale B field by a multiplicative factor: RDS 2019/09 - no longer used. Scaling is done in cachec
     void scaleField( double factor )
     { scaleBscale(factor); for (unsigned i=0; i<ncond(); i++) { m_cond[i].scaleCurrent(factor); } }
     // accessors
@@ -53,7 +53,7 @@ void
 BFieldZone::addBiotSavart( const double *xyz, double *B, double *deriv ) const
 {
     for ( unsigned i = 0; i < m_cond.size(); i++ ) {
-        m_cond[i].addBiotSavart( xyz, B, deriv );
+        m_cond[i].addBiotSavart( 1, xyz, B, deriv );
     }
 }
 
diff --git a/MagneticField/MagFieldElements/src/AtlasFieldCache.cxx b/MagneticField/MagFieldElements/src/AtlasFieldCache.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..febf00b28bc2b9bc025a0422823e0f48333728f5
--- /dev/null
+++ b/MagneticField/MagFieldElements/src/AtlasFieldCache.cxx
@@ -0,0 +1,38 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//
+// AtlasFieldCache.cxx
+//
+// Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
+//
+// R.D.Schaffer -at- cern.ch
+//
+#include "MagFieldElements/AtlasFieldCache.h"
+
+/// Constructor
+MagField::AtlasFieldCache::AtlasFieldCache()
+{}
+
+MagField::AtlasFieldCache::AtlasFieldCache(double solFieldScale,
+                                           double torFieldScale, 
+                                           const AtlasFieldMap* fieldMap, 
+                                           bool useNewBfieldCache)
+    :
+    // temporary flag
+    m_useNewBfieldCache(useNewBfieldCache),
+    m_solScale(solFieldScale),
+    m_torScale(torFieldScale),
+    // Get solenoid zone id from field service
+    m_solZoneId(fieldMap->solenoidZoneId()),
+    // set field service
+    m_fieldMap(fieldMap)
+
+{
+    // save ZR bfield
+    m_meshZR = m_fieldMap->getBFieldMesh();
+}
+    
+
+
diff --git a/MagneticField/MagFieldElements/src/AtlasFieldMap.cxx b/MagneticField/MagFieldElements/src/AtlasFieldMap.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..dc379cf2589c8a3dfd9d5822cd1a5013435839b9
--- /dev/null
+++ b/MagneticField/MagFieldElements/src/AtlasFieldMap.cxx
@@ -0,0 +1,460 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// AtlasMTFieldSvc.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+// ISF_Services include
+#include "MagFieldElements/AtlasFieldMap.h"
+
+// PathResolver
+#include "PathResolver/PathResolver.h"
+
+// CLHEP
+#include "CLHEP/Units/SystemOfUnits.h"
+
+// ROOT
+#include "TFile.h"
+#include "TTree.h"
+
+/** Constructor **/
+MagField::AtlasFieldMap::AtlasFieldMap() 
+{}
+
+
+MagField::AtlasFieldMap::~AtlasFieldMap()
+{
+    delete m_meshZR;
+}
+
+
+
+const BFieldZone*
+MagField::AtlasFieldMap::findBFieldZone( double z, double r, double phi ) const
+{
+
+    // make sure it's inside the largest zone
+    // NB: the sign of the logic is chosen in order to return 0 on NaN inputs
+    if ( z >= m_zmin && z <= m_zmax && r <= m_rmax ) {
+        // find the edges of the zone
+        // z
+        const std::vector<double>& edgez(m_edge[0]);
+        int iz = int(m_invq[0]*(z-m_zmin)); // index to LUT
+        iz = m_edgeLUT[0][iz]; // tentative index from LUT
+        if ( z > edgez[iz+1] ) iz++;
+        // r
+        const std::vector<double>& edger(m_edge[1]);
+        int ir = int(m_invq[1]*r); // index to LUT - note minimum r is always 0
+        ir = m_edgeLUT[1][ir]; // tentative index from LUT
+        if ( r > edger[ir+1] ) ir++;
+        // phi
+        const std::vector<double>& edgephi(m_edge[2]);
+        int iphi = int(m_invq[2]*(phi+M_PI)); // index to LUT - minimum phi is -pi
+        iphi = m_edgeLUT[2][iphi]; // tentative index from LUT
+        if ( phi > edgephi[iphi+1] ) iphi++;
+        // use LUT to get the zone
+        return m_zoneLUT[(iz*m_nr+ir)*m_nphi+iphi];
+    } else {
+        return nullptr;
+    }
+}
+
+// fast 2d map (made of one zone)
+const BFieldMeshZR*
+MagField::AtlasFieldMap::getBFieldMesh() const 
+{
+    return m_meshZR;
+}
+
+
+
+//
+// read the map from a ROOT file.
+// returns 0 if successful.
+//
+bool
+MagField::AtlasFieldMap::initializeMap( TFile* rootfile, float solenoidCurrent, float toroidCurrent)
+{
+    // save currents
+    m_solenoidCurrent = solenoidCurrent;
+    m_toroidCurrent   = toroidCurrent;
+    
+    // open the tree
+    TTree* tree = (TTree*)rootfile->Get("BFieldMap");
+    // if ( tree == 0 ) {
+    //     // no tree
+    //     ATH_MSG_ERROR("readMap(): TTree 'BFieldMap' does not exist in ROOT field map");
+    //     return StatusCode::FAILURE;
+    // }
+    int id;
+    double zmin;
+
+    double zmax;
+
+    double rmin;
+
+    double rmax;
+
+    double phimin;
+
+    double phimax;
+    double bscale;
+    int ncond;
+    bool *finite;
+    double *p1x;
+
+    double *p1y;
+
+    double *p1z;
+
+    double *p2x;
+
+    double *p2y;
+
+    double *p2z;
+    double *curr;
+    int nmeshz;
+
+    int nmeshr;
+
+    int nmeshphi;
+    double *meshz;
+
+    double *meshr;
+
+    double *meshphi;
+    int nfield;
+    short *fieldz;
+
+    short *fieldr;
+
+    short *fieldphi;
+    // define the fixed-sized branches first
+    tree->SetBranchAddress( "id", &id );
+    tree->SetBranchAddress( "zmin", &zmin );
+    tree->SetBranchAddress( "zmax", &zmax );
+    tree->SetBranchAddress( "rmin", &rmin );
+    tree->SetBranchAddress( "rmax", &rmax );
+    tree->SetBranchAddress( "phimin", &phimin );
+    tree->SetBranchAddress( "phimax", &phimax );
+    tree->SetBranchAddress( "bscale", &bscale );
+    tree->SetBranchAddress( "ncond", &ncond );
+    tree->SetBranchAddress( "nmeshz", &nmeshz );
+    tree->SetBranchAddress( "nmeshr", &nmeshr );
+    tree->SetBranchAddress( "nmeshphi", &nmeshphi );
+    tree->SetBranchAddress( "nfield", &nfield );
+    // prepare arrays - need to know the maximum sizes
+    // open the tree of buffer sizes (may not exist in old maps)
+    unsigned maxcond(0);
+
+    unsigned maxmeshz(0);
+
+    unsigned maxmeshr(0);
+
+    unsigned maxmeshphi(0);
+
+    unsigned maxfield(0);
+    TTree* tmax = (TTree*)rootfile->Get("BFieldMapSize");
+    if ( tmax != nullptr ) {
+        tmax->SetBranchAddress( "maxcond", &maxcond );
+        tmax->SetBranchAddress( "maxmeshz", &maxmeshz );
+        tmax->SetBranchAddress( "maxmeshr", &maxmeshr );
+        tmax->SetBranchAddress( "maxmeshphi", &maxmeshphi );
+        tmax->SetBranchAddress( "maxfield", &maxfield );
+        tmax->GetEntry(0);
+    } else { // "BFieldMapSize" tree does not exist
+        for ( int i = 0; i < tree->GetEntries(); i++ ) {
+            tree->GetEntry(i);
+            maxcond = std::max( maxcond, (unsigned)ncond );
+            maxmeshz = std::max( maxmeshz, (unsigned)nmeshz );
+            maxmeshr = std::max( maxmeshr, (unsigned)nmeshr );
+            maxmeshphi = std::max( maxmeshphi, (unsigned)nmeshphi );
+            maxfield = std::max( maxfield, (unsigned)nfield );
+        }
+    }
+    finite = new bool[maxcond];
+    p1x = new double[maxcond];
+    p1y = new double[maxcond];
+    p1z = new double[maxcond];
+    p2x = new double[maxcond];
+    p2y = new double[maxcond];
+    p2z = new double[maxcond];
+    curr = new double[maxcond];
+    meshz = new double[maxmeshz];
+    meshr = new double[maxmeshr];
+    meshphi = new double[maxmeshphi];
+    fieldz = new short[maxfield];
+    fieldr = new short[maxfield];
+    fieldphi = new short[maxfield];
+    // define the variable length branches
+    tree->SetBranchAddress( "finite", finite );
+    tree->SetBranchAddress( "p1x", p1x );
+    tree->SetBranchAddress( "p1y", p1y );
+    tree->SetBranchAddress( "p1z", p1z );
+    tree->SetBranchAddress( "p2x", p2x );
+    tree->SetBranchAddress( "p2y", p2y );
+    tree->SetBranchAddress( "p2z", p2z );
+    tree->SetBranchAddress( "curr", curr );
+    tree->SetBranchAddress( "meshz", meshz );
+    tree->SetBranchAddress( "meshr", meshr );
+    tree->SetBranchAddress( "meshphi", meshphi );
+    tree->SetBranchAddress( "fieldz", fieldz );
+    tree->SetBranchAddress( "fieldr", fieldr );
+    tree->SetBranchAddress( "fieldphi", fieldphi );
+
+    // reserve the space for m_zone so that it won't move as the vector grows
+    m_zone.reserve( tree->GetEntries() );
+    // read all tree and store
+    for ( int i = 0; i < tree->GetEntries(); i++ ) {
+        tree->GetEntry(i);
+        BFieldZone z( id, zmin, zmax, rmin, rmax, phimin, phimax, bscale );
+        m_zone.push_back(z);
+        m_zone.back().reserve( nmeshz, nmeshr, nmeshphi );
+        for ( int j = 0; j < ncond; j++ ) {
+            double p1[3];
+
+            double p2[3];
+            p1[0] = p1x[j];
+            p1[1] = p1y[j];
+            p1[2] = p1z[j];
+            p2[0] = p2x[j];
+            p2[1] = p2y[j];
+            p2[2] = p2z[j];
+            BFieldCond cond( finite[j], p1, p2, curr[j] );
+            m_zone.back().appendCond(cond);
+        }
+        for ( int j = 0; j < nmeshz; j++ ) {
+            m_zone.back().appendMesh( 0, meshz[j] );
+        }
+        for ( int j = 0; j < nmeshr; j++ ) {
+            m_zone.back().appendMesh( 1, meshr[j] );
+        }
+        for ( int j = 0; j < nmeshphi; j++ ) {
+            m_zone.back().appendMesh( 2, meshphi[j] );
+        }
+        for ( int j = 0; j < nfield; j++ ) {
+            BFieldVector<short> field( fieldz[j], fieldr[j], fieldphi[j] );
+            m_zone.back().appendField( field );
+        }
+    }
+    // clean up
+    tree->Delete();
+    delete[] finite;
+    delete[] p1x;
+    delete[] p1y;
+    delete[] p1z;
+    delete[] p2x;
+    delete[] p2y;
+    delete[] p2z;
+    delete[] curr;
+    delete[] meshz;
+    delete[] meshr;
+    delete[] meshphi;
+    delete[] fieldz;
+    delete[] fieldr;
+    delete[] fieldphi;
+    // build the LUTs
+    buildLUT();
+    buildZR();
+
+    // setup id for solenoid bfield zone
+    BFieldZone* solezone = findZoneSlow( 0.0, 0.0, 0.0 );
+    if (solezone) m_solenoidZoneId = solezone->id();
+    
+    return true;
+}
+
+//
+// Search for the zone that contains a point (z, r, phi)
+// This is a linear-search version, used only to construct the LUT.
+//
+BFieldZone* MagField::AtlasFieldMap::findZoneSlow( double z, double r, double phi )
+{
+    for ( int j = m_zone.size()-1; j >= 0; --j ) {
+        if ( m_zone[j].inside( z, r, phi ) ) return &m_zone[j];
+    }
+    return nullptr;
+}
+
+//
+// Build the look-up table used by FindZone().
+// Called by readMap()
+// It also calls buildLUT() for all zones.
+//
+void MagField::AtlasFieldMap::buildLUT()
+{
+
+    // make lists of (z,r,phi) edges of all zones
+    for ( int j = 0; j < 3; j++ ) { // z, r, phi
+        for ( unsigned i = 0; i < m_zone.size(); i++ ) {
+            double e[2];
+            e[0] = m_zone[i].min(j);
+            e[1] = m_zone[i].max(j);
+            for ( int k = 0; k < 2; k++ ) {
+                // for the phi edge, fit into [-pi,pi]
+                if ( j==2 && e[k] > M_PI ) e[k] -= 2.0*M_PI;
+                m_edge[j].push_back(e[k]);
+            }
+        }
+        // add -pi and +pi to phi, just in case
+        m_edge[2].push_back(-M_PI);
+        m_edge[2].push_back(M_PI);
+        // sort
+        sort( m_edge[j].begin(), m_edge[j].end() );
+        // remove duplicates
+        // must do this by hand to allow small differences due to rounding in phi
+        int i = 0;
+        for ( unsigned k = 1; k < m_edge[j].size(); k++ ) {
+            if ( fabs(m_edge[j][i] - m_edge[j][k]) < 1.0e-6 ) continue;
+            m_edge[j][++i] = m_edge[j][k];
+        }
+        m_edge[j].resize( i+1 );
+        // because of the small differences allowed in the comparison above,
+        // m_edge[][] values do not exactly match the m_zone[] boundaries.
+        // we have to fix this up in order to avoid invalid field values
+        // very close to the zone boundaries.
+        for ( unsigned i = 0; i < m_zone.size(); i++ ) {
+            for ( unsigned k = 0; k < m_edge[j].size(); k++ ) {
+                if ( fabs(m_zone[i].min(j) - m_edge[j][k]) < 1.0e-6 ) {
+                    m_zone[i].adjustMin(j,m_edge[j][k]);
+                }
+                if ( fabs(m_zone[i].max(j) - m_edge[j][k]) < 1.0e-6 ) {
+                    m_zone[i].adjustMax(j,m_edge[j][k]);
+                }
+            }
+        }
+    }
+    // build LUT for edge finding
+    for ( int j = 0; j < 3; j++ ) { // z, r, phi
+        // find the size of the smallest interval
+        double width = m_edge[j].back() - m_edge[j].front();
+        double q(width);
+        for ( unsigned i = 0; i < m_edge[j].size()-1; i++ ) {
+            q = std::min( q, m_edge[j][i+1] - m_edge[j][i] );
+        }
+        // find the number of cells in the LUT
+        int n = int(width/q) + 1;
+        q = width/(n+0.5);
+        m_invq[j] = 1.0/q;
+        n++;
+        // fill the LUT
+        int m = 0;
+        for ( int i = 0; i < n; i++ ) { // index of LUT
+            if ( q*i+m_edge[j].front() > m_edge[j][m+1] ) m++;
+            m_edgeLUT[j].push_back(m);
+        }
+    }
+    // store min/max for speedup
+    m_zmin=m_edge[0].front();
+    m_zmax=m_edge[0].back();
+    m_rmax=m_edge[1].back();
+    // build LUT for zone finding
+    m_nz = m_edge[0].size() - 1;
+    m_nr = m_edge[1].size() - 1;
+    m_nphi = m_edge[2].size() - 1;
+    m_zoneLUT.reserve( m_nz*m_nr*m_nphi );
+    for ( int iz = 0; iz < m_nz; iz++ ) {
+        double z = 0.5*(m_edge[0][iz]+m_edge[0][iz+1]);
+        for ( int ir = 0; ir < m_nr; ir++ ) {
+            double r = 0.5*(m_edge[1][ir]+m_edge[1][ir+1]);
+            for ( int iphi = 0; iphi < m_nphi; iphi++ ) {
+                double phi = 0.5*(m_edge[2][iphi]+m_edge[2][iphi+1]);
+                const BFieldZone* zone = findZoneSlow( z, r, phi );
+                m_zoneLUT.push_back( zone );
+            }
+        }
+    }
+    // build LUT in each zone
+    for ( unsigned i = 0; i < m_zone.size(); i++ ) {
+        m_zone[i].buildLUT();
+    }
+}
+
+//
+// Build the z-r 2d map for fast solenoid field
+//
+void MagField::AtlasFieldMap::buildZR()
+{
+    // delete if previously allocated
+    delete m_meshZR;
+
+    // find the solenoid zone
+    // solenoid zone always covers 100 < R < 1000, but not necessarily R < 100
+    // so we search for the zone that contains a point at R = 200, Z = 0
+    const BFieldZone *solezone = findBFieldZone( 0.0, 200.0, 0.0 );
+
+    // instantiate the new ZR map with the same external coverage as the solenoid zone
+    // make sure R = 0 is covered
+    m_meshZR = new BFieldMeshZR( solezone->zmin(), solezone->zmax(), 0.0, solezone->rmax() );
+
+    // reserve the right amount of memroy
+    unsigned nmeshz = solezone->nmesh(0);
+    unsigned nmeshr = solezone->nmesh(1);
+    if ( solezone->rmin() > 0.0 ) nmeshr++;
+    m_meshZR->reserve( nmeshz, nmeshr );
+
+    // copy the mesh structure in z/r
+    // take care of R = 0 first
+    if ( solezone->rmin() > 0.0 ) {
+        m_meshZR->appendMesh( 1, 0.0 );
+    }
+    // copy the rest
+    for ( int i = 0; i < 2; i++ ) { // z, r
+        for ( unsigned j = 0; j < solezone->nmesh(i); j++ ) { // loop over mesh points
+            m_meshZR->appendMesh( i, solezone->mesh( i, j ) );
+        }
+    }
+
+    // loop through the mesh and compute the phi-averaged field
+    for ( unsigned iz = 0; iz < m_meshZR->nmesh(0); iz++ ) { // loop over z
+        double z = m_meshZR->mesh( 0, iz );
+        for ( unsigned ir = 0; ir < m_meshZR->nmesh(1); ir++ ) { // loop over r
+            double r = m_meshZR->mesh( 1, ir );
+            const int nphi(200); // number of phi slices to average
+            double Br = 0.0;
+            double Bz = 0.0;
+            for ( int iphi = 0; iphi < nphi; iphi++ ) {
+                double phi = double(iphi)/double(nphi)*2.*M_PI;
+                double xyz[3];
+                xyz[0] = r*cos(phi);
+                xyz[1] = r*sin(phi);
+                xyz[2] = z;
+                double B[3];
+                solezone->getB( xyz, B, nullptr );
+                Br += B[0]*cos(phi) + B[1]*sin(phi);
+                Bz += B[2];
+            }
+            Br *= 1.0/double(nphi);
+            Bz *= 1.0/double(nphi);
+            m_meshZR->appendField( BFieldVectorZR( Bz, Br ) );
+        }
+    }
+
+    // build the internal LUT
+    m_meshZR->buildLUT();
+}
+
+//
+// Approximate memory footprint
+//
+int MagField::AtlasFieldMap::memSize() const
+{
+    int size = 0;
+    size += sizeof(BFieldCache);
+    size += sizeof(BFieldCacheZR);
+    for ( unsigned i = 0; i < m_zone.size(); i++ ) {
+        size += m_zone[i].memSize();
+    }
+    for ( int i = 0; i < 3; i++ ) {
+        size += sizeof(double)*m_edge[i].capacity();
+        size += sizeof(int)*m_edgeLUT[i].capacity();
+    }
+    size += sizeof(BFieldZone*)*m_zoneLUT.capacity();
+    if ( m_meshZR ) {
+        size += m_meshZR->memSize();
+    }
+    return size;
+}
+
diff --git a/MagneticField/MagFieldServices/src/BFieldMeshZR.cxx b/MagneticField/MagFieldElements/src/BFieldMeshZR.cxx
similarity index 97%
rename from MagneticField/MagFieldServices/src/BFieldMeshZR.cxx
rename to MagneticField/MagFieldElements/src/BFieldMeshZR.cxx
index 1647c746b8740a223946d6bd7c8c77e74ead6b9a..a95c9872718b4f7a9ac2f559b97adf9f818df822 100644
--- a/MagneticField/MagFieldServices/src/BFieldMeshZR.cxx
+++ b/MagneticField/MagFieldElements/src/BFieldMeshZR.cxx
@@ -9,7 +9,7 @@
 //
 // Masahiro Morii, Harvard University
 //
-#include "MagFieldServices/BFieldMeshZR.h"
+#include "MagFieldElements/BFieldMeshZR.h"
 
 //
 // Construct the look-up table to accelerate bin-finding.
diff --git a/MagneticField/MagFieldServices/CMakeLists.txt b/MagneticField/MagFieldServices/CMakeLists.txt
index 70c82b59f61d53fbac9ef9f424d42729bf2ac133..cbcc972cab216cd83ee575ed1592cc03a2e8db58 100644
--- a/MagneticField/MagFieldServices/CMakeLists.txt
+++ b/MagneticField/MagFieldServices/CMakeLists.txt
@@ -9,7 +9,10 @@ atlas_subdir( MagFieldServices )
 atlas_depends_on_subdirs( PUBLIC
                           Control/AthenaBaseComps
                           MagneticField/MagFieldInterfaces
+                          MagneticField/MagFieldConditions
+			  Control/CxxUtils
                           PRIVATE
+                          MagneticField/MagFieldElements
                           Control/StoreGate
                           Database/AthenaPOOL/AthenaPoolUtilities
                           GaudiKernel
@@ -24,7 +27,8 @@ atlas_add_component( MagFieldServices
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} AthenaBaseComps MagFieldInterfaces StoreGateLib SGtests AthenaPoolUtilities GaudiKernel PathResolver )
+		     LINK_LIBRARIES ${ROOT_LIBRARIES} ${CLHEP_LIBRARIES} MagFieldElements MagFieldConditions CxxUtils 
+		     AthenaBaseComps MagFieldInterfaces StoreGateLib SGtests AthenaPoolUtilities GaudiKernel PathResolver )
 
 # Install files from the package:
 atlas_install_headers( MagFieldServices )
diff --git a/MagneticField/MagFieldServices/MagFieldServices/ATLAS_CHECK_THREAD_SAFETY b/MagneticField/MagFieldServices/MagFieldServices/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..2118e8f88f6d8c4fd4c4f32d4a83c79eb4f2324a
--- /dev/null
+++ b/MagneticField/MagFieldServices/MagFieldServices/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+MagneticField/MagFieldServices
diff --git a/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldCacheCondAlg.h b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldCacheCondAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..00b5097d9610600125b26a22fd8ee678b595aa05
--- /dev/null
+++ b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldCacheCondAlg.h
@@ -0,0 +1,96 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+///////////////////////////////////////////////////////////////////
+// AtlasFieldCacheCondAlg.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef MAGFIELDSERVICES_ATLASFIELDCACHECONDALG_H
+#define MAGFIELDSERVICES_ATLASFIELDCACHECONDALG_H 
+
+// FrameWork includes
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "StoreGate/ReadCondHandleKey.h"
+#include "StoreGate/WriteCondHandleKey.h"
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+#include "GaudiKernel/ICondSvc.h"
+
+// #include "MagFieldInterfaces/IMTMagFieldSvc.h"
+
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldConditions/AtlasFieldMapCondObj.h"
+
+namespace MagField {
+
+    class AtlasFieldCacheCondAlg : public AthReentrantAlgorithm 
+    {
+    public:
+        AtlasFieldCacheCondAlg(const std::string& name,ISvcLocator* pSvcLocator);
+        virtual ~AtlasFieldCacheCondAlg();
+
+        StatusCode initialize() override final;
+        StatusCode execute(const EventContext& ctx) const override final;
+        StatusCode finalize() override final;  
+
+    private:
+
+        /*
+         *  Cache of the variables to be updated before we write the conditions object
+         */
+        struct Cache{
+            float  m_solenoidCurrent{0};   // solenoid current in ampere
+            float  m_toroidCurrent{0};     // toroid current in ampere
+            double m_solScaleFactor{1};    // solenoid current scale factor
+            double m_torScaleFactor{1};    // toroid current scale factor
+            
+            //"infinite in case we do not update from DCS" - full run/event range
+            EventIDRange m_condObjOutputRange {EventIDRange(EventIDBase(0,0), EventIDBase(EventIDBase::UNDEFNUM-1, EventIDBase::UNDEFEVT-1))}; 
+        }; 
+        StatusCode updateCurrentFromConditions(const EventContext& ctx, Cache& cache) const;
+        StatusCode updateCurrentFromParameters(Cache& cache) const;
+        void       scaleField(Cache& cache, const MagField::AtlasFieldMap* fieldMap) const;
+
+        /// Temporary flag for switching between 'old' and 'new' magField usage
+        Gaudi::Property<bool> m_useNewBfieldCache {this, 
+                                                   "UseNewBfieldCache", true, "Temporary flag for switching between 'old' and 'new' magField usage. Default = true"};
+
+        // threshold below which currents are considered zero
+        Gaudi::Property<double> m_soleMinCurrent {this, 
+                                                  "SoleMinCurrent", 1.0, "Minimum solenoid current (A) for which solenoid is considered ON"};
+        Gaudi::Property<double> m_toroMinCurrent {this, 
+                                                  "ToroMinCurrent", 1.0, "Minimum toroid current (A) for which toroid is considered ON"};
+
+        // flag to use magnet current from DCS in COOL
+        Gaudi::Property<bool> m_useDCS {this, 
+                                        "UseDCS", false, "Get magnet currents from DCS through ConditionsSvc"};
+
+        // COOL folder name containing current information
+        // current input key
+        SG::ReadCondHandleKey<CondAttrListCollection> m_currInputKey
+        {this, 
+         "COOLCurrentsFolderName", "/EXT/DCS/MAGNETS/SENSORDATA", "Name of the COOL folder containing magnet currents"};
+
+        // AtlasFieldMapCondObj - read handle to access magnet field conditions object containing the map file names
+        SG::ReadCondHandleKey<AtlasFieldMapCondObj> m_mapCondObjInputKey
+        {this, 
+         "AtlasFieldMapCondObj", "fieldMapCondObj", "Name of key for the Magnetic Field conditions object with the map file names"};
+
+        // AtlasFieldCacheCondObj - magnet field conditions object containing the current scale factors
+        SG::WriteCondHandleKey<AtlasFieldCacheCondObj> m_condObjOutputKey
+        {this, 
+         "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the key for the Magnetic Field conditions object with currents for scaling"};
+
+        // actual current if DCS is not in use
+        Gaudi::Property<double> m_useSoleCurrent {this, 
+                                                  "UseSoleCurrent", 7730.,  "Set actual solenoid current (A)"};
+        Gaudi::Property<double> m_useToroCurrent {this, 
+                                                  "UseToroCurrent", 20400., "Set actual toroid current (A)"};
+        ServiceHandle<ICondSvc> m_condSvc { this, 
+                                            "CondSvc", "CondSvc", "conditions service" };
+
+    };
+}
+
+#endif //> !MAGFIELDSERVICES_ATLASFIELDCACHECONDALG_H
diff --git a/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldMapCondAlg.h b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldMapCondAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..f4fe5d6f0b76875b42f67dd38ac94efe99d4f8bd
--- /dev/null
+++ b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldMapCondAlg.h
@@ -0,0 +1,98 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+///////////////////////////////////////////////////////////////////
+// AtlasFieldMapCondAlg.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef MAGFIELDSERVICES_ATLASFIELDMAPCONDALG_H
+#define MAGFIELDSERVICES_ATLASFIELDMAPCONDALG_H 
+
+// FrameWork includes
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "StoreGate/ReadCondHandleKey.h"
+#include "StoreGate/WriteCondHandleKey.h"
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+#include "GaudiKernel/ICondSvc.h"
+
+// #include "MagFieldInterfaces/IMTMagFieldSvc.h"
+
+#include "MagFieldConditions/AtlasFieldMapCondObj.h"
+
+namespace MagField {
+
+    class AtlasFieldMapCondAlg : public AthReentrantAlgorithm 
+    {
+    public:
+        AtlasFieldMapCondAlg(const std::string& name,ISvcLocator* pSvcLocator);
+        virtual ~AtlasFieldMapCondAlg();
+
+        StatusCode initialize() override final;
+        StatusCode execute(const EventContext& ctx) const override final;
+        StatusCode finalize() override final;  
+
+    private:
+
+        /*
+         *  Cache of the variables to be updated before we write the conditions object
+         */
+        struct Cache{
+            bool solenoidOn() { return (m_mapSoleCurrent > 0.0); }
+            bool toroidOn()   { return (m_mapToroCurrent > 0.0); }
+            // current associated with the map
+            double m_mapSoleCurrent {7730.};
+            double m_mapToroCurrent {20400.};
+            // field map names
+            std::string m_fullMapFilename{"MagneticFieldMaps/bfieldmap_7730_20400_14m.root"}; // all magnets on
+            std::string m_soleMapFilename{"MagneticFieldMaps/bfieldmap_7730_0_14m.root"};     // solenoid on / toroid off
+            std::string m_toroMapFilename{"MagneticFieldMaps/bfieldmap_0_20400_14m.root"};    // toroid on / solenoid off
+            // field map - pointer and event id range
+            std::unique_ptr<MagField::AtlasFieldMap> m_fieldMap;
+            
+            //"infinite in case we do not update from COOL" 
+            EventIDRange m_mapCondObjOutputRange {EventIDRange()}; // default range covers everything (run/event and timestamp)
+        }; 
+
+        StatusCode updateFieldMap(const EventContext& ctx, Cache& cache) const;
+
+        /// map file names - if not read from cool
+        Gaudi::Property<std::string> m_fullMapFilename {this,
+                                                        "FullMapFile", "MagneticFieldMaps/bfieldmap_7730_20400_14m.root",
+                                                        "File storing the full magnetic field map"};
+        Gaudi::Property<std::string> m_soleMapFilename {this,
+                                                        "SoleMapFile", "MagneticFieldMaps/bfieldmap_7730_0_14m.root",
+                                                        "File storing the solenoid-only magnetic field map"};
+        Gaudi::Property<std::string> m_toroMapFilename {this,
+                                                        "ToroMapFile", "MagneticFieldMaps/bfieldmap_0_20400_14m.root",
+                                                        "File storing the toroid-only magnetic field map"};
+        /// nominal current for the maps
+        Gaudi::Property<double>      m_mapSoleCurrent  {this,
+                                                        "MapSoleCurrent", 7730., "Nominal solenoid current (A)"};
+        Gaudi::Property<double>      m_mapToroCurrent  {this,
+                                                        "MapToroCurrent", 20400., "Nominal toroid current (A)"};
+
+
+        // flag to read magnet map filenames from COOL
+        Gaudi::Property<bool> m_useMapsFromCOOL {this,
+                                                 "UseMapsFromCOOL", true , "Get magnetic field map filenames from COOL"};
+
+        // COOL folder name containing field maps
+        // map input key
+        SG::ReadCondHandleKey<CondAttrListCollection> m_mapsInputKey
+        {this,
+         "COOLMapsFolderName", "/GLOBAL/BField/Maps", "Name of the COOL folder containing field maps"};
+
+        // AtlasFieldMapCondObj - magnet field conditions object containing the map file names
+        SG::WriteCondHandleKey<AtlasFieldMapCondObj> m_mapCondObjOutputKey
+        {this, 
+         "AtlasFieldMapCondObj", "fieldMapCondObj", "Name of key for the Magnetic Field conditions object with the map file names"};
+
+        ServiceHandle<ICondSvc> m_condSvc { this, 
+                                            "CondSvc", "CondSvc", "conditions service" };
+
+    };
+}
+
+#endif //> !MAGFIELDSERVICES_ATLASFIELDMAPCONDALG_H
diff --git a/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvc.h b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvc.h
index 8d57bf92d7631bb21b11e582f6ed72e7b7680e1f..529398741971db19801ce924c1aca473573ffcc7 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvc.h
+++ b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvc.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -17,17 +17,18 @@
 // MagField includes
 #include "MagFieldInterfaces/IMagFieldSvc.h"
 #include "MagFieldServices/AtlasFieldSvcTLS.h"
-#include "MagFieldServices/BFieldCache.h"
-#include "MagFieldServices/BFieldCacheZR.h"
-#include "MagFieldServices/BFieldCond.h"
-#include "MagFieldServices/BFieldZone.h"
-#include "MagFieldServices/BFieldMeshZR.h"
-// #include "MagFieldInterfaces/IMagFieldManipulator.h"
+#include "MagFieldElements/BFieldCache.h"
+#include "MagFieldElements/BFieldCacheZR.h"
+#include "MagFieldElements/BFieldCond.h"
+#include "MagFieldElements/BFieldZone.h"
+#include "MagFieldElements/BFieldMeshZR.h"
 
 // STL includes
 #include <vector>
 #include <iostream>
 
+#include "CxxUtils/checker_macros.h"
+
 // forward declarations
 class CondAttrListCollection;
 class BFieldZone;
@@ -44,23 +45,23 @@ namespace MagField {
     public:
 
       //** Constructor with parameters */
-      AtlasFieldSvc( const std::string& name, ISvcLocator* pSvcLocator );
+      AtlasFieldSvc( const std::string& name, ISvcLocator* pSvcLocator )  ATLAS_CTORDTOR_NOT_THREAD_SAFE;
 
       /** Destructor */
-      virtual ~AtlasFieldSvc();
+      virtual ~AtlasFieldSvc()  ATLAS_CTORDTOR_NOT_THREAD_SAFE ;
 
       /** Athena algorithm's interface methods */
-      virtual StatusCode  initialize() override;
+      virtual StatusCode  initialize  ATLAS_NOT_THREAD_SAFE () override;
       virtual StatusCode  finalize() override;
 
       /** Read **/
       virtual void handle(const Incident& runIncident) override;
 
       /** Call back for possible magnet current update **/
-      StatusCode updateCurrent(IOVSVC_CALLBACK_ARGS);
+      StatusCode updateCurrent ATLAS_NOT_THREAD_SAFE (IOVSVC_CALLBACK_ARGS);
 
       /** Call back for possible magnet filename update **/
-      StatusCode updateMapFilenames(IOVSVC_CALLBACK_ARGS);
+      StatusCode updateMapFilenames ATLAS_NOT_THREAD_SAFE (IOVSVC_CALLBACK_ARGS);
 
       /** get B field value at given position */
       /** xyz[3] is in mm, bxyz[3] is in kT */
@@ -215,7 +216,7 @@ MagField::AtlasFieldSvc::findZone( double z, double r, double phi ) const
     // use LUT to get the zone
     return m_zoneLUT[(iz*m_nr+ir)*m_nphi+iphi];
   } else {
-    return 0;
+    return nullptr;
   }
 }
 
@@ -225,7 +226,7 @@ MagField::AtlasFieldSvc::fillFieldCache(double z, double r, double phi, AtlasFie
 {
   // search for the zone
   const BFieldZone* zone = findZone( z, r, phi );
-  if ( zone == 0 ) {
+  if ( zone == nullptr ) {
       // outsize all zones
       return false;
   }
diff --git a/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvcTLS.h b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvcTLS.h
index 314b6de9a1e88270860d10be6f98e44c2c5412d9..1b9784384edf5fb44bcac7e24044cc43e0e627c3 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvcTLS.h
+++ b/MagneticField/MagFieldServices/MagFieldServices/AtlasFieldSvcTLS.h
@@ -13,9 +13,9 @@
 #define MAGFIELDSERVICES_ATLASFIELDSVCTLS_H 1
 
 // MagField includes
-#include "BFieldCond.h"
-#include "BFieldZone.h"
-#include "BFieldMeshZR.h"
+#include "MagFieldElements/BFieldCond.h"
+#include "MagFieldElements/BFieldZone.h"
+#include "MagFieldElements/BFieldMeshZR.h"
 
 namespace MagField {
 
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldH8Grid.h b/MagneticField/MagFieldServices/MagFieldServices/BFieldH8Grid.h
index 112a5983184f9d111a2131e53388fadb5076b513..71ba9d62b548d68f912016ee76368c96461e606d 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/BFieldH8Grid.h
+++ b/MagneticField/MagFieldServices/MagFieldServices/BFieldH8Grid.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -22,7 +22,7 @@ public:
     // read map data from a text file
     void readMap( std::istream& input );
     // compute magnetic field + derivatives
-    void getB( const double *xyz, double *B, double *deriv=0 ) const;
+    void getB( const double *xyz, double *B, double *deriv=nullptr ) const;
     // true if the grid has been defined
     bool defined() const { return ( m_n[0] > 0 ); }
     // true if xyz[3] is inside this grid
@@ -39,8 +39,7 @@ public:
         out_max[i] = m_max[i];
         out_d[i] = m_d[i];
       }
-      return;
-    }
+         }
 private:
     int    m_n[3];              // number of grid points
     double m_min[3], m_max[3];  // range in x,y,z (mm)
diff --git a/MagneticField/MagFieldServices/MagFieldServices/BFieldSolenoid.h b/MagneticField/MagFieldServices/MagFieldServices/BFieldSolenoid.h
index 208b104afcdea9d8a9e82dba16d58186bf407a8b..f9034fe883d0034b0b99868941fa6f9bacbaa49f 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/BFieldSolenoid.h
+++ b/MagneticField/MagFieldServices/MagFieldServices/BFieldSolenoid.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -15,12 +15,14 @@
 #include <vector>
 #include <iostream>
 #include "TFile.h"
-#include "MagFieldServices/BFieldZone.h"
+#include "MagFieldElements/BFieldZone.h"
+#include "CxxUtils/checker_macros.h"
 
-class BFieldSolenoid {
+
+class ATLAS_NOT_THREAD_SAFE BFieldSolenoid {
 public:
     // constructor
-    BFieldSolenoid() : m_orig(0), m_tilt(0) {;}
+    BFieldSolenoid() : m_orig(nullptr), m_tilt(nullptr) {;}
     // destructor
     ~BFieldSolenoid() { delete m_orig; if (m_orig!=m_tilt) delete m_tilt; }
     // read/write map from/to file
@@ -30,7 +32,7 @@ public:
     // move and tilt the map
     void moveMap( double dx, double dy, double dz, double ax, double ay );
     // compute magnetic field
-    void getB( const double *xyz, double *B, double *deriv=0 ) const;
+    void getB( const double *xyz, double *B, double *deriv=nullptr ) const;
     // accessor
     const BFieldMesh<double> *tiltedMap() const { return m_tilt; }
 private:
diff --git a/MagneticField/MagFieldServices/MagFieldServices/H8FieldSvc.h b/MagneticField/MagFieldServices/MagFieldServices/H8FieldSvc.h
index dd525f5fee94c7e42bf37eec5e976223ddfc75cd..47ebecd374085bee1dfe9b2af92d19d5bbf1e219 100644
--- a/MagneticField/MagFieldServices/MagFieldServices/H8FieldSvc.h
+++ b/MagneticField/MagFieldServices/MagFieldServices/H8FieldSvc.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -53,7 +53,7 @@ namespace MagField {
       // initialize map
       StatusCode initializeMap();
       // read the field map
-      StatusCode readMap( const std::string mapFile );
+      StatusCode readMap( const std::string& mapFile );
 
       /** Data members **/
 
diff --git a/MagneticField/MagFieldServices/python/MagFieldServicesConfig.py b/MagneticField/MagFieldServices/python/MagFieldServicesConfig.py
index 5a426d637ccf3b0d55178a7c60221283b222c399..0f25b709f666fbbe741f9266742c1cdfd527f02b 100644
--- a/MagneticField/MagFieldServices/python/MagFieldServicesConfig.py
+++ b/MagneticField/MagFieldServices/python/MagFieldServicesConfig.py
@@ -1,13 +1,91 @@
 # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 
-# JobOption fragment to set up the AtlasFieldSvc
+# JobOption fragment to set up the AtlasFieldSvc and conditions algorithms
 # Valerio Ippolito - Harvard University
 
 # inspired by https://svnweb.cern.ch/trac/atlasoff/browser/MuonSpectrometer/MuonCnv/MuonCnvExample/trunk/python/MuonCalibConfig.py
 
+from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
+from AthenaCommon.GlobalFlags import GlobalFlags
+from AthenaCommon import CfgMgr
 from AthenaConfiguration.ComponentFactory import CompFactory
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from MagFieldServices.MagFieldServicesConf import MagField__AtlasFieldCacheCondAlg
+from MagFieldServices.MagFieldServicesConf import MagField__AtlasFieldMapCondAlg
 
+MagField__AtlasFieldSvc=CompFactory.MagField__AtlasFieldSvc
+
+#--------------------------------------------------------------
+
+def AtlasFieldSvc(name="AtlasFieldSvc",**kwargs):
+  if athenaCommonFlags.isOnline():
+    kwargs.setdefault( "UseDCS", False )
+    kwargs.setdefault( "UseSoleCurrent", 7730 )
+    kwargs.setdefault( "UseToroCurrent", 20400 )
+  else:
+    kwargs.setdefault( "UseDCS", True )
+    # kwargs.setdefault( "UseDCS", False )
+    # kwargs.setdefault( "UseSoleCurrent", 7730 )
+    # kwargs.setdefault( "UseToroCurrent", 20400 )
+
+    # kwargs.setdefault( "UseDCS", False )
+    # kwargs.setdefault( "UseSoleCurrent", 12000 )
+    # kwargs.setdefault( "UseToroCurrent", 20400 )
+
+    
+  return CfgMgr.MagField__AtlasFieldSvc(name,**kwargs)
+
+def AtlasMTFieldSvc(name="AtlasMTFieldSvc",**kwargs):
+  # if athenaCommonFlags.isOnline():
+  #   kwargs.setdefault( "UseSoleCurrent", 7730 )
+  #   kwargs.setdefault( "UseToroCurrent", 20400 )
+  return CfgMgr.MagField__AtlasMTFieldSvc(name,**kwargs)
+
+def AtlasFieldCacheCondAlg(name="AtlasFieldCacheCondAlg",**kwargs):
+  if athenaCommonFlags.isOnline():
+    kwargs.setdefault( "UseDCS", False )
+    # currents for scaling wrt to map currents
+    kwargs.setdefault( "UseSoleCurrent", 7730 )
+    kwargs.setdefault( "UseToroCurrent", 20400 )
+  else:
+    kwargs.setdefault( "UseDCS", True )
+    kwargs.setdefault( "UseNewBfieldCache", True )
+    # kwargs.setdefault( "UseNewBfieldCache", False )
+    # kwargs.setdefault( "UseDCS", False )
+    # kwargs.setdefault( "UseSoleCurrent", 12000 )
+    # kwargs.setdefault( "UseToroCurrent", 20400 )
+  return CfgMgr.MagField__AtlasFieldCacheCondAlg(name,**kwargs)
+
+def AtlasFieldMapCondAlg(name="AtlasFieldMapCondAlg",**kwargs):
+  if athenaCommonFlags.isOnline():
+    # The following are the defaults - added here to be clear
+    kwargs.setdefault( "UseMapsFromCOOL", True )
+    # kwargs.setdefault( "MapSoleCurrent", 7730 )
+    # kwargs.setdefault( "MapToroCurrent", 20400 )
+  else:
+    # The following are the defaults - added here to be clear
+    kwargs.setdefault( "UseMapsFromCOOL", True )
+    # kwargs.setdefault( "MapSoleCurrent", 7730 )
+    # kwargs.setdefault( "MapToroCurrent", 20400 )
+  return CfgMgr.MagField__AtlasFieldMapCondAlg(name,**kwargs)
+
+    
+
+def H8FieldSvc(name="H8FieldSvc",**kwargs):
+  return CfgMgr.MagField__H8FieldSvc(name,**kwargs)
+
+def GetFieldSvc(name="AtlasFieldSvc",**kwargs):
+  if GlobalFlags.DetGeo == 'ctbh8':
+    return H8FieldSvc(name, **kwargs)
+  else:
+    return AtlasFieldSvc(name, **kwargs)
+    
+def GetFieldCacheCondAlg(name="AtlasFieldCacheCondAlg",**kwargs):
+    return AtlasFieldCacheCondAlg(name, **kwargs)
+    
+def GetFieldMapCondAlg(name="AtlasFieldMapCondAlg",**kwargs):
+    return AtlasFieldMapCondAlg(name, **kwargs)
+    
 # The magneticfields is going to need a big update for MT, so this is all temporary. Ed
 def MagneticFieldSvcCfg(flags, **kwargs):
     result=ComponentAccumulator()
@@ -23,21 +101,47 @@ def MagneticFieldSvcCfg(flags, **kwargs):
     else:
         db='GLOBAL'
         
-    result.merge(addFolders(flags,['/GLOBAL/BField/Maps <noover/>'],detDb=db) )
+    result.merge(addFolders(flags,['/GLOBAL/BField/Maps <noover/>'], detDb=db, className="CondAttrListCollection") )
         
     if not flags.Common.isOnline:
         result.merge(addFolders(flags, ['/EXT/DCS/MAGNETS/SENSORDATA'], detDb='DCS_OFL', className="CondAttrListCollection") )
             
+
+    # AtlasFieldSvc - old one
+    afsArgs = {
+      "name": "AtlasFieldSvc",
+    }
     if flags.Common.isOnline:
-      kwargs.setdefault( "UseDCS", False )
-      kwargs.setdefault( "UseSoleCurrent", 7730 )
-      kwargs.setdefault( "UseToroCurrent", 20400 )
+      afsArgs.update( UseDCS = False )
+      afsArgs.update( UseSoleCurrent = 7730 )
+      afsArgs.update( UseToroCurrent = 20400 )
     else:
-      kwargs.setdefault( "UseDCS", True )
+      afsArgs.update( UseDCS = True )
+    mag_field_svc = MagField__AtlasFieldSvc(**afsArgs)  
+    result.addService(mag_field_svc, primary=True)
 
-
-    mag_field_svc = CompFactory.MagField__AtlasFieldSvc("AtlasFieldSvc",**kwargs)  
-    result.addService(mag_field_svc,primary=True)
+    # AtlasFieldMapCondAlg - for reading in map
+    afmArgs = {
+      "name": "AtlasFieldMapCondAlg",
+    }
+    afmArgs.update( UseMapsFromCOOL = True )
+    mag_field_map_cond_alg = MagField__AtlasFieldMapCondAlg(**afmArgs) 
+    result.addCondAlgo(mag_field_map_cond_alg)
+    
+    # AtlasFieldCacheCondAlg - for reading in current
+    afcArgs = {
+      "name": "AtlasFieldCacheCondAlg",
+    }
+    if flags.Common.isOnline:
+      afcArgs.update( UseDCS = False )
+      afcArgs.update( UseSoleCurrent = 7730 )
+      afcArgs.update( UseToroCurrent = 20400 )
+    else:
+      afcArgs.update( UseDCS = True )
+      afcArgs.update( UseNewBfieldCache = True )
+    mag_field_cache_cond_alg = MagField__AtlasFieldCacheCondAlg(**afcArgs) 
+    result.addCondAlgo(mag_field_cache_cond_alg)
+    
     return result 
     
 if __name__=="__main__":
diff --git a/MagneticField/MagFieldServices/python/MagFieldServicesConfigDb.py b/MagneticField/MagFieldServices/python/MagFieldServicesConfigDb.py
index 5b8323b4e3c28e743fa018b8897bde6c71638a71..a03abf9256d4f749f43bcf1dda04574ef74b28cb 100644
--- a/MagneticField/MagFieldServices/python/MagFieldServicesConfigDb.py
+++ b/MagneticField/MagFieldServices/python/MagFieldServicesConfigDb.py
@@ -2,6 +2,8 @@
 
 # database entries for https://twiki.cern.ch/twiki/bin/view/AtlasComputing/ConfiguredFactory#Factory_functions_vs_derived_cla
 # Valerio Ippolito - Harvard University
-from AthenaCommon.CfgGetter import addService
+from AthenaCommon.CfgGetter import addService,addAlgorithm  
 
-addService('MagFieldServices.MagFieldServicesSetup.GetFieldSvc', 'AtlasFieldSvc')
+addService('MagFieldServices.MagFieldServicesConfig.GetFieldSvc', 'AtlasFieldSvc')
+addAlgorithm('MagFieldServices.MagFieldServicesConfig.GetFieldMapCondAlg', 'AtlasFieldMapCondAlg')
+addAlgorithm('MagFieldServices.MagFieldServicesConfig.GetFieldCacheCondAlg', 'AtlasFieldCacheCondAlg')
diff --git a/MagneticField/MagFieldServices/python/SetupField.py b/MagneticField/MagFieldServices/python/SetupField.py
index 49d2c3c3d37fdfd021ecc067be0293362903e0b7..0806fe6e2ed75ad59a13fa2ab4a755c7b958e973 100755
--- a/MagneticField/MagFieldServices/python/SetupField.py
+++ b/MagneticField/MagFieldServices/python/SetupField.py
@@ -11,11 +11,17 @@ from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
 
 # initialise required conditions DB folders
 from IOVDbSvc.CondDB import conddb
-conddb.addFolderSplitMC('GLOBAL','/GLOBAL/BField/Maps <noover/>','/GLOBAL/BField/Maps <noover/>')
+conddb.addFolderSplitMC('GLOBAL','/GLOBAL/BField/Maps <noover/>','/GLOBAL/BField/Maps <noover/>', className="CondAttrListCollection")
 if not athenaCommonFlags.isOnline():
     conddb.addFolder('DCS_OFL','/EXT/DCS/MAGNETS/SENSORDATA', className="CondAttrListCollection")
     
-# import the field service
+# import the field service and conditions algs (service is 'to be removed')
 # (it is MagFieldServices.MagFieldServicesConfig which takes care of configuration)
-from AthenaCommon.CfgGetter import getService
+from AthenaCommon.CfgGetter import getService,getAlgorithm
 getService('AtlasFieldSvc')
+
+from AthenaCommon.AlgSequence import AthSequencer             
+condSequence = AthSequencer("AthCondSeq")             
+condSequence += getAlgorithm( "AtlasFieldMapCondAlg" )
+condSequence += getAlgorithm( "AtlasFieldCacheCondAlg" )
+
diff --git a/MagneticField/MagFieldServices/src/AtlasFieldCacheCondAlg.cxx b/MagneticField/MagFieldServices/src/AtlasFieldCacheCondAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e4b39448093321cae5d6ada942184ec4bdec03a6
--- /dev/null
+++ b/MagneticField/MagFieldServices/src/AtlasFieldCacheCondAlg.cxx
@@ -0,0 +1,290 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+   @class AtlasFieldCacheCondAlg
+   @authors RD Schaffer <r.d.schaffer -at- cern.ch>, C Anastopoulos
+   @brief create a MagField object for tracking clients
+
+   Purpose: for each event, create a MagField object for tracking clients and store in conditions
+   Store
+
+**/
+
+// ISF_Services include
+#include "MagFieldServices/AtlasFieldCacheCondAlg.h"
+
+// Concurrency
+#include "GaudiKernel/ConcurrencyFlags.h"
+
+// PathResolver
+#include "PathResolver/PathResolver.h"
+
+// ROOT
+#include "TFile.h"
+#include "TTree.h"
+
+MagField::AtlasFieldCacheCondAlg::AtlasFieldCacheCondAlg(const std::string& name, 
+                                                   ISvcLocator* pSvcLocator)
+    :AthReentrantAlgorithm(name, pSvcLocator){ 
+}
+
+MagField::AtlasFieldCacheCondAlg::~AtlasFieldCacheCondAlg(){ }
+
+StatusCode
+MagField::AtlasFieldCacheCondAlg::initialize() {
+
+    ATH_MSG_INFO ("Initialize");
+    // CondSvc
+    ATH_CHECK( m_condSvc.retrieve() );
+
+    // Read Handle for the current
+    ATH_CHECK( m_currInputKey.initialize() );
+
+    // Read handle for the field map cond object
+    ATH_CHECK( m_mapCondObjInputKey.initialize() );
+
+    // Output handle for scale factors/cache
+    ATH_CHECK( m_condObjOutputKey.initialize() );
+
+    // Register write handle for scale factors/cache
+    if (m_condSvc->regHandle(this, m_condObjOutputKey).isFailure()) {
+        ATH_MSG_ERROR("Unable to register WriteCondHandle " << m_condObjOutputKey.fullKey() << " with CondSvc");
+        return StatusCode::FAILURE;
+    }
+
+    ATH_MSG_INFO ( "Initialize: Key " << m_condObjOutputKey.fullKey() << " has been succesfully registered " );
+    if (m_useDCS) {
+        ATH_MSG_INFO ( "Initialize: Will update current from conditions"); // 
+    }
+    else {
+        ATH_MSG_INFO ( "Initialize: Will update current from parameters");
+    }
+
+    ATH_MSG_INFO ( "Initialize: useDCS, useSoleCurrent, useToroCurrent. " << (int)m_useDCS << ", "
+                   << m_useSoleCurrent << ", " << m_useToroCurrent);
+
+    
+    return StatusCode::SUCCESS;
+}
+
+StatusCode
+MagField::AtlasFieldCacheCondAlg::execute(const EventContext& ctx) const {
+
+    ATH_MSG_INFO ( "execute: entering");
+
+    // Check if output conditions object with field cache object is still valid, if not replace it
+    // with new current scale factors
+    SG::WriteCondHandle<AtlasFieldCacheCondObj> writeHandle{m_condObjOutputKey, ctx};
+    if (writeHandle.isValid()) {
+        ATH_MSG_DEBUG("execute: CondHandle " << writeHandle.fullKey() 
+                      << " is already valid. " 
+                      <<" May happen if multiple concurrent events are being processed out of order.");
+        return StatusCode::SUCCESS;
+    }  
+
+    //This will need to be filled before we construct the condition object 
+    Cache cache{};
+
+    // set current scale factor from either conditions or from jobOption parameters
+    if (m_useDCS) {
+        ATH_CHECK( updateCurrentFromConditions(ctx, cache) );
+    }
+    else {
+        ATH_CHECK( updateCurrentFromParameters(cache) );
+    }
+
+    // Must read map cond object to get previously created map
+    SG::ReadCondHandle<AtlasFieldMapCondObj> mapReadHandle{m_mapCondObjInputKey, ctx};
+    const AtlasFieldMapCondObj* mapCondObj{*mapReadHandle};
+    if (mapCondObj == nullptr) {
+        ATH_MSG_ERROR("execute: Could not access conditions map for key: " << m_mapCondObjInputKey.fullKey());
+        return StatusCode::FAILURE;
+    }
+
+    // simple pointer to the map, to be give to the AtlasFieldCacheCondObj, used for the cache field map access
+    const MagField::AtlasFieldMap* fieldMap =  mapCondObj->fieldMap();
+
+    // calculate the scale factors
+    scaleField(cache, fieldMap);
+
+    // save current scale factor in conditions object
+    auto fieldCondObj = std::make_unique<AtlasFieldCacheCondObj>();
+
+    // initialize cond obj with current scale factors and the field svc (needed to setup cache)
+    if (!fieldCondObj->initialize(cache.m_solScaleFactor, 
+                                  cache.m_torScaleFactor, 
+                                  fieldMap, 
+                                  m_useNewBfieldCache)) {
+        ATH_MSG_ERROR("execute: Could not initialize conditions field object with solenoid/toroid currents "
+                      << cache.m_solScaleFactor << "," << cache.m_torScaleFactor);
+        return StatusCode::FAILURE;
+    }
+
+    // Record in conditions store the conditions object with scale factors and map pointer for cache
+    if(writeHandle.record(cache.m_condObjOutputRange, std::move(fieldCondObj)).isFailure()) {
+        ATH_MSG_ERROR("execute: Could not record AtlasFieldCacheCondObj object with " 
+                      << writeHandle.key() << " with EventRange " << cache.m_condObjOutputRange
+                      << " into Conditions Store");
+        return StatusCode::FAILURE;
+    }
+
+    ATH_MSG_INFO ( "execute: initialized AtlasFieldCacheCondObj and cache with SFs - sol/tor "
+                   << cache.m_solScaleFactor << "/" << cache.m_torScaleFactor );
+    ATH_MSG_INFO ( "execute: solenoid zone id  " << fieldMap->solenoidZoneId());
+    ATH_MSG_INFO ( "execute: useNewBfieldCache " << m_useNewBfieldCache);
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode
+MagField::AtlasFieldCacheCondAlg::updateCurrentFromConditions(const EventContext& ctx, Cache& cache) const
+{
+    ATH_MSG_INFO ( "UpdateCurrentFromConditions  " );
+
+    // readin current value
+    SG::ReadCondHandle<CondAttrListCollection> readHandle {m_currInputKey, ctx};
+    const CondAttrListCollection* attrListColl{*readHandle};
+    if (attrListColl == nullptr) {
+        ATH_MSG_ERROR("updateCurrentFromConditions: Failed to retrieve CondAttributeListCollection with key " << m_currInputKey.key());
+        return StatusCode::FAILURE;
+    }
+
+
+    // Get the validitiy range
+    EventIDRange rangeW;
+    if (!readHandle.range(rangeW)) {
+        ATH_MSG_FATAL("updateCurrentFromConditions: Failed to retrieve validity range for " << readHandle.key());
+        return StatusCode::FAILURE;
+    }
+    cache.m_condObjOutputRange = rangeW;
+    ATH_MSG_INFO("UpdateCurrentFromConditions: Range of input/output is " <<  cache.m_condObjOutputRange);
+
+    // get magnet currents from DCS
+    double solcur{0.};
+    double torcur{0.};
+    bool gotsol{false};
+    bool gottor{false};
+
+    /*
+     * due to inconsistencies between CONDBR2 and OFLP200/COMP200 (the former includes channel names
+     * in the /EXT/DCS/MAGNETS/SENSORDATA folder, the latter don't), we try to read currents in
+     * both ways
+     */
+    bool hasChanNames{false};
+    ATH_MSG_INFO( "UpdateCurrentFromConditions: Attempt 1 at reading currents from DCS (using channel name)" );
+    for ( CondAttrListCollection::const_iterator itr = attrListColl->begin(); itr != attrListColl->end(); ++itr ) {
+        const std::string& name = attrListColl->chanName(itr->first);
+        ATH_MSG_INFO( "UpdateCurrentFromConditions: Trying to read from DCS: [channel name, index, value] "
+                      << name << " , " << itr->first << " , " << itr->second["value"].data<float>() );
+        if (name.compare("") != 0) {
+            hasChanNames = true;
+        }
+        if ( name.compare("CentralSol_Current") == 0 ) {
+            // channel 1 is solenoid current
+            solcur = itr->second["value"].data<float>();
+            gotsol = true;
+        } else if ( name.compare("Toroids_Current") == 0 ) {
+            // channel 3 is toroid current
+            torcur = itr->second["value"].data<float>();
+            gottor = true;
+        }
+    }
+    if ( !hasChanNames ) {
+        ATH_MSG_INFO( "UpdateCurrentFromConditions: Attempt 2 at reading currents from DCS (using channel index)" );
+        // in no channel is named, try again using channel index instead
+        for ( CondAttrListCollection::const_iterator itr = attrListColl->begin(); itr != attrListColl->end(); ++itr ) {
+
+            if ( itr->first == 1 ) {
+                // channel 1 is solenoid current
+                solcur = itr->second["value"].data<float>();
+                gotsol = true;
+            } else if ( itr->first == 3 ) {
+                // channel 3 is toroid current
+                torcur = itr->second["value"].data<float>();
+                gottor = true;
+            }
+        }
+    }
+    if ( !gotsol || !gottor ) {
+        if ( !gotsol ) ATH_MSG_ERROR( "UpdateCurrentFromConditions: Missing solenoid current in DCS information" );
+        if ( !gottor ) ATH_MSG_ERROR( "UpdateCurrentFromConditions: Missing toroid current in DCS information" );
+        return StatusCode::FAILURE;
+    }
+
+    ATH_MSG_INFO( "UpdateCurrentFromConditions: Currents read from DCS - solenoid " << solcur << " toroid " << torcur );
+
+    // round to zero if close to zero
+    if ( solcur < m_soleMinCurrent) {
+        solcur = 0.0;
+        ATH_MSG_INFO( "UpdateCurrentFromConditions: Solenoid is off" );
+    }
+    if ( torcur < m_toroMinCurrent) {
+        torcur = 0.0;
+        ATH_MSG_INFO( "UpdateCurrentFromConditions: Toroids are off" );
+    }
+    cache.m_solenoidCurrent = solcur;
+    cache.m_toroidCurrent   = torcur;
+
+    return StatusCode::SUCCESS;
+}
+
+
+StatusCode
+MagField::AtlasFieldCacheCondAlg::updateCurrentFromParameters(Cache& cache) const
+{
+
+    ATH_MSG_INFO( "updateCurrentFromParameters" );
+    // take the current values from JobOptions
+    double solcur{m_useSoleCurrent};
+    double torcur{m_useToroCurrent};
+    if ( solcur < m_soleMinCurrent ) {
+        solcur = 0.0;
+        ATH_MSG_INFO( "updateCurrentFromParameters: Solenoid is off" );
+    }
+    if ( torcur < m_toroMinCurrent) {
+        torcur = 0.0;
+        ATH_MSG_INFO( "updateCurrentFromParameters: Toroids are off" );
+    }
+    cache.m_solenoidCurrent = solcur;
+    cache.m_toroidCurrent   = torcur;
+    ATH_MSG_INFO("updateCurrentFromParameters: Update from job options: Range of input/output is " <<  cache.m_condObjOutputRange);
+    ATH_MSG_INFO("updateCurrentFromParameters: Currents taken for jobOption parameters " );
+    return StatusCode::SUCCESS;
+}
+
+
+void
+MagField::AtlasFieldCacheCondAlg::scaleField(Cache& cache, const MagField::AtlasFieldMap* fieldMap) const
+{
+    //
+    if ( cache.m_solenoidCurrent > 0.0 ) {
+        if ( fieldMap->solenoidCurrent() > 0.0 &&
+             std::abs( cache.m_solenoidCurrent/fieldMap->solenoidCurrent() - 1.0 ) > 0.001 ){
+            cache.m_solScaleFactor = cache.m_solenoidCurrent/fieldMap->solenoidCurrent(); 
+        }
+        ATH_MSG_INFO( "scaleField: Solenoid field scale factor " << cache.m_solScaleFactor << ". Solenoid and map currents: "
+                      << cache.m_solenoidCurrent << "," << fieldMap->solenoidCurrent());
+    }
+    //
+    if (cache.m_toroidCurrent ) {
+        if ( fieldMap->toroidCurrent() > 0.0 &&
+             std::abs(cache.m_toroidCurrent/fieldMap->toroidCurrent() - 1.0 ) > 0.001 ) {
+            // scale the field in all zones except for the solenoid zone
+            cache.m_torScaleFactor = cache.m_toroidCurrent/fieldMap->toroidCurrent();
+        }
+        ATH_MSG_INFO( "scaleField: Toroid field scale factor " << cache.m_torScaleFactor << ". Toroid and map currents: "
+                      << cache.m_toroidCurrent << "," << fieldMap->toroidCurrent());
+    }
+}
+
+
+
+    
+
+StatusCode
+MagField::AtlasFieldCacheCondAlg::finalize() {
+    ATH_MSG_INFO ( " in finalize " );
+    return StatusCode::SUCCESS; 
+}
diff --git a/MagneticField/MagFieldServices/src/AtlasFieldMapCondAlg.cxx b/MagneticField/MagFieldServices/src/AtlasFieldMapCondAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3677b5654ba9782503dc0ce145960a7db28fdab5
--- /dev/null
+++ b/MagneticField/MagFieldServices/src/AtlasFieldMapCondAlg.cxx
@@ -0,0 +1,259 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+   @class AtlasFieldMapCondAlg
+   @authors RD Schaffer <r.d.schaffer -at- cern.ch>, C Anastopoulos
+   @brief create a MagField object for tracking clients
+
+   Purpose: create a MagField map object, filling from a file whose name is taken normally from
+   COOL, and save the map in a conditions object for the AtlasFieldCacheCondAlg
+
+**/
+
+// ISF_Services include
+#include "MagFieldServices/AtlasFieldMapCondAlg.h"
+
+// Concurrency
+#include "GaudiKernel/ConcurrencyFlags.h"
+
+// PathResolver
+#include "PathResolver/PathResolver.h"
+
+// ROOT
+#include "TFile.h"
+#include "TTree.h"
+
+MagField::AtlasFieldMapCondAlg::AtlasFieldMapCondAlg(const std::string& name, 
+                                                   ISvcLocator* pSvcLocator)
+    :AthReentrantAlgorithm(name, pSvcLocator){ 
+}
+
+MagField::AtlasFieldMapCondAlg::~AtlasFieldMapCondAlg(){ }
+
+StatusCode
+MagField::AtlasFieldMapCondAlg::initialize() {
+
+    ATH_MSG_INFO ("Initialize");
+    // CondSvc
+    ATH_CHECK( m_condSvc.retrieve() );
+
+    // Read Handle for the map
+    ATH_CHECK( m_mapsInputKey.initialize() );
+
+    // Output handle for the field map
+    ATH_CHECK( m_mapCondObjOutputKey.initialize() );
+
+    // Register write handles for scale factors/cache and the field map
+    if (m_condSvc->regHandle(this, m_mapCondObjOutputKey).isFailure()) {
+        ATH_MSG_ERROR("Unable to register WriteCondHandle " << m_mapCondObjOutputKey.fullKey() << " with CondSvc");
+        return StatusCode::FAILURE;
+    }
+    
+    ATH_MSG_INFO ( "Initialize: Key " << m_mapCondObjOutputKey.fullKey() << " has been succesfully registered " );
+    if (m_useMapsFromCOOL) {
+        ATH_MSG_INFO ( "Initialize: Will update the field map from conditions"); // 
+    }
+    else {
+        ATH_MSG_INFO ( "Initialize: Will update the field map from jobOpt file name");
+    }
+    return StatusCode::SUCCESS;
+}
+
+StatusCode
+MagField::AtlasFieldMapCondAlg::execute(const EventContext& ctx) const {
+
+    ATH_MSG_INFO ( "execute: entering  ");
+
+    // Check if output conditions object with field map object is still valid, if not replace it
+    // with new map
+    SG::WriteCondHandle<AtlasFieldMapCondObj> mapWriteHandle{m_mapCondObjOutputKey, ctx};
+    if (mapWriteHandle.isValid()) {
+        ATH_MSG_DEBUG("execute: CondHandle " << mapWriteHandle.fullKey() 
+                      << " is still valid. ");
+        return StatusCode::SUCCESS;
+    }  
+
+    //This will need to be filled before we construct the condition object 
+    Cache cache{};
+
+    ATH_CHECK( updateFieldMap(ctx, cache) );
+
+
+    ATH_MSG_INFO ( "execute: solenoid zone id  " << cache.m_fieldMap->solenoidZoneId());
+    
+    
+    // Save newly created map in conditions object, and record it in the conditions store, with its
+    // own range
+    auto fieldMapCondObj = std::make_unique<AtlasFieldMapCondObj>();
+    // move ownership of the field map to the fieldMapCondObj
+    fieldMapCondObj->setFieldMap(std::move(cache.m_fieldMap));
+    if(mapWriteHandle.record(cache.m_mapCondObjOutputRange, std::move(fieldMapCondObj)).isFailure()) {
+        ATH_MSG_ERROR("execute: Could not record AtlasFieldMapCondObj object with " 
+                      << mapWriteHandle.key() 
+                      << " with EventRange " << cache.m_mapCondObjOutputRange
+                      << " into Conditions Store");
+        return StatusCode::FAILURE;
+    }
+    ATH_MSG_INFO ( "execute: recored AtlasFieldMapCondObj with field map");
+
+    return StatusCode::SUCCESS;
+}
+
+StatusCode
+MagField::AtlasFieldMapCondAlg::updateFieldMap(const EventContext& ctx, Cache& cache) const 
+{
+    // We get here only for the first creation of the field map, or if the AtlasFieldMapCondObj
+    // object, where the map is stored, is no longer valid, i.e. the IOV is out of range
+
+    // Update the map either with the file names from cool or from alg properties, according to m_useMapsFromCOOL
+
+    // Get file names from COOL, or use local ones:
+    std::string fullMapFilename;
+    std::string soleMapFilename;
+    std::string toroMapFilename;
+
+    if (m_useMapsFromCOOL) {
+
+        ATH_MSG_INFO("updateFieldMap: Update map from conditions");
+        
+        // readin map file name from cool
+        SG::ReadCondHandle<CondAttrListCollection> readHandle {m_mapsInputKey, ctx};
+        const CondAttrListCollection* attrListColl{*readHandle};
+        if (attrListColl == nullptr) {
+            ATH_MSG_ERROR("updateFieldMap: Failed to retrieve CondAttributeListCollection with key " << readHandle.key());
+            return StatusCode::FAILURE;
+        }
+
+        // // handle for COOL field map filenames
+        // const DataHandle<CondAttrListCollection> mapHandle;
+        
+
+        // Get the validitiy range
+        EventIDRange rangeW;
+        if (!readHandle.range(rangeW)) {
+            ATH_MSG_FATAL("updateFieldMap: Failed to retrieve validity range for " << readHandle.key());
+            return StatusCode::FAILURE;
+        }
+        cache.m_mapCondObjOutputRange = rangeW;
+        ATH_MSG_INFO("updateFieldMap: Update map from conditions: Range of input/output is "
+                     << cache.m_mapCondObjOutputRange);
+
+        ATH_MSG_INFO( "updateFieldMap: reading magnetic field map filenames from COOL" );
+
+        for (CondAttrListCollection::const_iterator itr = attrListColl->begin(); itr != attrListColl->end(); ++itr) {
+            const coral::AttributeList &attr = itr->second;
+            const std::string &mapType = attr["FieldType"].data<std::string>();
+            const std::string &mapFile = attr["MapFileName"].data<std::string>();
+            const float soleCur = attr["SolenoidCurrent"].data<float>();
+            const float toroCur = attr["ToroidCurrent"].data<float>();
+        
+            ATH_MSG_INFO("updateFieldMap: found map of type " << mapType << " with soleCur=" << soleCur << " toroCur=" << toroCur << " (path " << mapFile << ")");
+
+            // first 5 letters are reserved (like "file:")
+            const std::string mapFile_decoded = mapFile.substr(5);
+            if (mapType == "GlobalMap") {
+                fullMapFilename = mapFile_decoded;
+                cache.m_mapSoleCurrent = soleCur;
+                cache.m_mapToroCurrent = toroCur;
+            }
+            else if (mapType == "SolenoidMap") {
+                soleMapFilename = mapFile_decoded;
+            }
+            else if (mapType == "ToroidMap") {
+                toroMapFilename = mapFile_decoded;
+            }
+            // note: the idea is that the folder contains exactly three maps
+            // (if it contains more than 3 maps, then this logic doesn't work perfectly)
+            // nominal currents are read from the global map
+        }
+    }
+    
+    else {
+        // not m_useMapsFromCOOL - set values from job options
+        fullMapFilename = m_fullMapFilename;
+        soleMapFilename = m_soleMapFilename;
+        toroMapFilename = m_toroMapFilename;
+        cache.m_mapSoleCurrent = m_mapSoleCurrent;
+        cache.m_mapToroCurrent = m_mapToroCurrent;
+    }
+        
+        
+    // Select map file according to the value of the currents which indicate which map is 'on'
+
+    // determine the map to load
+    std::string mapFile;
+    if ( cache.solenoidOn() && cache.toroidOn() ) mapFile = fullMapFilename;
+    else if ( cache.solenoidOn() )                mapFile = soleMapFilename;
+    else if ( cache.toroidOn() )                  mapFile = toroMapFilename;
+    else {
+        // all magnets OFF. no need to read map
+        return StatusCode::SUCCESS;
+    }
+        
+    ATH_MSG_INFO ( "updateFieldMap: Set map currents from FieldSvc: solenoid/toroid " 
+                   << cache.m_mapSoleCurrent << "," << cache.m_mapToroCurrent);
+    ATH_MSG_INFO ( "updateFieldMap: Use map file " << mapFile);
+
+        
+    // find the path to the map file
+    std::string resolvedMapFile = PathResolver::find_file( mapFile.c_str(), "DATAPATH" );
+    if ( resolvedMapFile.empty() ) {
+        ATH_MSG_ERROR( "updateFieldMap: Field map file " << mapFile << " not found" );
+        return StatusCode::FAILURE;
+    }
+    // Do checks and extract root file to initialize the map
+    if ( resolvedMapFile.find(".root") == std::string::npos ) {
+        ATH_MSG_ERROR("updateFieldMap: input file name '" << resolvedMapFile << "' does not end with .root");
+        return StatusCode::FAILURE;
+    } 
+    TFile* rootfile = new TFile(resolvedMapFile.c_str(), "OLD");
+    if ( ! rootfile ) {
+        ATH_MSG_ERROR("updateFieldMap: failed to open " << resolvedMapFile);
+        return StatusCode::FAILURE;
+    }
+    if ( !rootfile->cd() ) {
+        // could not make it current directory
+        ATH_MSG_ERROR("updateFieldMap: unable to cd() into the ROOT field map TFile");
+        rootfile->Close();
+        delete rootfile;
+        return StatusCode::FAILURE; 
+    }
+    // open the tree
+    TTree* tree = (TTree*)rootfile->Get("BFieldMap");
+    if ( tree == nullptr ) {
+        // no tree
+        ATH_MSG_ERROR("updateFieldMap: TTree 'BFieldMap' does not exist in ROOT field map");
+        rootfile->Close();
+        delete rootfile;
+        return StatusCode::FAILURE;
+    }
+
+    // create map
+    cache.m_fieldMap = std::make_unique<MagField::AtlasFieldMap>();
+
+    // initialize map
+    if (!cache.m_fieldMap->initializeMap( rootfile, cache.m_mapSoleCurrent, cache.m_mapToroCurrent )) {
+        // failed to initialize the map
+        ATH_MSG_ERROR("updateFieldMap: unable to initialize the map for AtlasFieldMap for file " << resolvedMapFile);
+        rootfile->Close();
+        delete rootfile;
+        return StatusCode::FAILURE;
+    }
+    
+    rootfile->Close();
+    delete rootfile;
+    
+
+    ATH_MSG_INFO( "updateFieldMap: Initialized the field map from " << resolvedMapFile );
+
+    return StatusCode::SUCCESS;
+}
+    
+
+StatusCode
+MagField::AtlasFieldMapCondAlg::finalize() {
+    ATH_MSG_INFO ( " in finalize " );
+    return StatusCode::SUCCESS; 
+}
diff --git a/MagneticField/MagFieldServices/src/AtlasFieldSvc.cxx b/MagneticField/MagFieldServices/src/AtlasFieldSvc.cxx
index 144bb934d7cef021f0a47af839d56d1d8954a30d..bf4e68028b9a5603237bdd21c6f3f0e715cf53f5 100644
--- a/MagneticField/MagFieldServices/src/AtlasFieldSvc.cxx
+++ b/MagneticField/MagFieldServices/src/AtlasFieldSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -90,7 +90,7 @@ MagField::AtlasFieldSvc::~AtlasFieldSvc()
 }
 
 /** framework methods */
-StatusCode MagField::AtlasFieldSvc::initialize()
+StatusCode MagField::AtlasFieldSvc::initialize ATLAS_NOT_THREAD_SAFE ( )
 {
     ATH_MSG_INFO( "initialize() ..." );
 
@@ -211,7 +211,7 @@ StatusCode MagField::AtlasFieldSvc::importCurrents(AtlasFieldSvcTLS &tls)
 }
 
 /** callback for possible magnet current update **/
-StatusCode MagField::AtlasFieldSvc::updateCurrent(IOVSVC_CALLBACK_ARGS)
+StatusCode MagField::AtlasFieldSvc::updateCurrent ATLAS_NOT_THREAD_SAFE (IOVSVC_CALLBACK_ARGS)
 {
     // get magnet currents from DCS
     double solcur(0.);
@@ -304,7 +304,7 @@ StatusCode MagField::AtlasFieldSvc::updateCurrent(IOVSVC_CALLBACK_ARGS)
 }
 
 /** callback for possible field map filenames update **/
-StatusCode MagField::AtlasFieldSvc::updateMapFilenames(IOVSVC_CALLBACK_ARGS)
+StatusCode MagField::AtlasFieldSvc::updateMapFilenames ATLAS_NOT_THREAD_SAFE (IOVSVC_CALLBACK_ARGS)
 {
     ATH_MSG_INFO( "reading magnetic field map filenames from COOL" );
 
@@ -337,7 +337,7 @@ StatusCode MagField::AtlasFieldSvc::updateMapFilenames(IOVSVC_CALLBACK_ARGS)
 	// nominal currents are read from the global map
     }
 
-    if (fullMapFilename == "" || soleMapFilename == "" || toroMapFilename == "") {
+    if (fullMapFilename.empty() || soleMapFilename.empty() || toroMapFilename.empty()) {
       ATH_MSG_ERROR("unexpected content in COOL field map folder");
       return StatusCode::FAILURE;
     }
@@ -387,7 +387,7 @@ StatusCode MagField::AtlasFieldSvc::initializeMap(AtlasFieldSvcTLS &tls)
     }
     // find the path to the map file
     std::string resolvedMapFile = PathResolver::find_file( mapFile.c_str(), "DATAPATH" );
-    if ( resolvedMapFile == "" ) {
+    if ( resolvedMapFile.empty() ) {
         ATH_MSG_ERROR( "Field map file " << mapFile << " not found" );
         return StatusCode::FAILURE;
     }
@@ -408,7 +408,7 @@ StatusCode MagField::AtlasFieldSvc::initializeMap(AtlasFieldSvcTLS &tls)
 
 void MagField::AtlasFieldSvc::scaleField()
 {
-    BFieldZone *solezone(0);
+    BFieldZone *solezone(nullptr);
     //
     if ( solenoidOn() ) {
         solezone = findZoneSlow( 0.0, 0.0, 0.0 );
@@ -421,6 +421,7 @@ void MagField::AtlasFieldSvc::scaleField()
             buildZR();
             ATH_MSG_INFO( "Scaled the solenoid field by a factor " << factor );
         }
+        ATH_MSG_INFO( "Solenoid zone id " << solezone->id() );
     }
     //
     if ( toroidOn() ) {
@@ -435,6 +436,9 @@ void MagField::AtlasFieldSvc::scaleField()
             }
             ATH_MSG_INFO( "Scaled the toroid field by a factor " << factor );
         }
+        // for ( unsigned i = 0; i < m_zone.size(); i++ ) {
+        //     ATH_MSG_INFO( "zone i,id " << i << ": " << m_zone[i].id() );
+        // }
     }
 }
 
@@ -487,7 +491,7 @@ void MagField::AtlasFieldSvc::getField(const double *xyz, double *bxyz, double *
   if (tls.cond) {
     const size_t condSize = tls.cond->size();
     for (size_t i = 0; i < condSize; i++) {
-      (*tls.cond)[i].addBiotSavart(xyz, bxyz, deriv);
+      (*tls.cond)[i].addBiotSavart(1, xyz, bxyz, deriv); // added scale factor of 1 for compatibility with multi-threaded model
     }
   }
 } 
@@ -540,12 +544,14 @@ void MagField::AtlasFieldSvc::getFieldZR(const double *xyz, double *bxyz, double
       // caching failed -> outside the valid z-r map volume
       // call the full version of getField()
       getField(xyz, bxyz, deriv);
+
       return;
     }
   }
 
   // do interpolation
   cacheZR.getB(xyz, r, bxyz, deriv);
+
 }
 
 //
@@ -580,7 +586,7 @@ void MagField::AtlasFieldSvc::clearMap(AtlasFieldSvcTLS &tls)
 //
 StatusCode MagField::AtlasFieldSvc::readMap( const char* filename )
 {
-    if ( strstr(filename, ".root") == 0 ) {
+    if ( strstr(filename, ".root") == nullptr ) {
         ATH_MSG_ERROR("input file name '" << filename << "' does not end with .root");
         return StatusCode::FAILURE;
     } 
@@ -654,23 +660,59 @@ StatusCode MagField::AtlasFieldSvc::readMap( std::istream& input )
         ATH_MSG_ERROR( myname << ": found '" << word << "' instead of 'ZONES'" );
         return StatusCode::FAILURE;
     }
-    std::vector<int> jz(nzone), nz(nzone);
-    std::vector<int> jr(nzone), nr(nzone);
-    std::vector<int> jphi(nzone), nphi(nzone);
-    std::vector<int> jbs(nzone), nbs(nzone);
-    std::vector<int> jcoil(nzone), ncoil(nzone);
-    std::vector<int> jfield(nzone), nfield(nzone);
-    std::vector<int> jaux(nzone), naux(nzone);
+    std::vector<int> jz(nzone);
+
+    std::vector<int> nz(nzone);
+    std::vector<int> jr(nzone);
+
+    std::vector<int> nr(nzone);
+    std::vector<int> jphi(nzone);
+
+    std::vector<int> nphi(nzone);
+    std::vector<int> jbs(nzone);
+
+    std::vector<int> nbs(nzone);
+    std::vector<int> jcoil(nzone);
+
+    std::vector<int> ncoil(nzone);
+    std::vector<int> jfield(nzone);
+
+    std::vector<int> nfield(nzone);
+    std::vector<int> jaux(nzone);
+
+    std::vector<int> naux(nzone);
 
     for ( int i = 0; i < nzone; i++ )
     {
         int id;
-        int nrep, map; // unused
-        double z1, z2, r1, r2, phi1, phi2;
+        int nrep;
+
+        int map; // unused
+        double z1;
+
+        double z2;
+
+        double r1;
+
+        double r2;
+
+        double phi1;
+
+        double phi2;
         int nzrphi0; // unused
         double tol; // unused
-        int mzn, mxsym, mrefl, mback; // unused
-        double qz, qr, qphi; // unused
+        int mzn;
+
+        int mxsym;
+
+        int mrefl;
+
+        int mback; // unused
+        double qz;
+
+        double qr;
+
+        double qphi; // unused
         double bscale;
         input >> id >> nrep;
 	if ( version == 6 ) input >> map;
@@ -711,7 +753,9 @@ StatusCode MagField::AtlasFieldSvc::readMap( std::istream& input )
     for ( int i = 0; i < nbiot; i++ ) {
         char dummy; // unused
         char cfinite;
-        double xyz1[3], xyz2[3];
+        double xyz1[3];
+
+        double xyz2[3];
         double phirot; // unused
         double curr;
         input >> dummy >> cfinite
@@ -789,8 +833,12 @@ StatusCode MagField::AtlasFieldSvc::readMap( std::istream& input )
     }
 
     // read field values
-    int nf, nzlist;
-    std::string ftype, bytype;
+    int nf;
+
+    int nzlist;
+    std::string ftype;
+
+    std::string bytype;
     input >> word >> nf >> nzlist >> ftype >> bytype;
     if ( word != "FIELD" ) {
         ATH_MSG_ERROR( myname << ": found '" << word << "' instead of 'FIELD'" );
@@ -806,7 +854,11 @@ StatusCode MagField::AtlasFieldSvc::readMap( std::istream& input )
     }
     // read zone by zone
     for ( int i = 0; i < nzlist; i++ ) {
-        int izone, idzone, nfzone;
+        int izone;
+
+        int idzone;
+
+        int nfzone;
         input >> izone >> idzone >> nfzone;
         izone--; // fortran -> C++
         if ( idzone != m_zone[izone].id() ) {
@@ -853,25 +905,65 @@ StatusCode MagField::AtlasFieldSvc::readMap( std::istream& input )
 //
 void MagField::AtlasFieldSvc::writeMap( TFile* rootfile ) const
 {
-    if ( rootfile == 0 ) return; // no file
-    if ( rootfile->cd() == false ) return; // could not make it current directory
+    if ( rootfile == nullptr ) return; // no file
+    if ( !rootfile->cd() ) return; // could not make it current directory
     // define the tree
     TTree* tree = new TTree( "BFieldMap", "BFieldMap version 5" );
     TTree* tmax = new TTree( "BFieldMapSize", "Buffer size information" );
     int id;
-    double zmin, zmax, rmin, rmax, phimin, phimax;
+    double zmin;
+
+    double zmax;
+
+    double rmin;
+
+    double rmax;
+
+    double phimin;
+
+    double phimax;
     double bscale;
     int ncond;
     bool *finite;
-    double *p1x, *p1y, *p1z, *p2x, *p2y, *p2z;
+    double *p1x;
+
+    double *p1y;
+
+    double *p1z;
+
+    double *p2x;
+
+    double *p2y;
+
+    double *p2z;
     double *curr;
-    int nmeshz, nmeshr, nmeshphi;
-    double *meshz, *meshr, *meshphi;
+    int nmeshz;
+
+    int nmeshr;
+
+    int nmeshphi;
+    double *meshz;
+
+    double *meshr;
+
+    double *meshphi;
     int nfield;
-    short *fieldz, *fieldr, *fieldphi;
+    short *fieldz;
+
+    short *fieldr;
+
+    short *fieldphi;
 
     // prepare arrays - need to know the maximum sizes
-    unsigned maxcond(0), maxmeshz(0), maxmeshr(0), maxmeshphi(0), maxfield(0);
+    unsigned maxcond(0);
+
+    unsigned maxmeshz(0);
+
+    unsigned maxmeshr(0);
+
+    unsigned maxmeshphi(0);
+
+    unsigned maxfield(0);
     for ( unsigned i = 0; i < m_zone.size(); i++ ) {
         maxcond = std::max( maxcond, m_zone[i].ncond() );
         maxmeshz = std::max( maxmeshz, m_zone[i].nmesh(0) );
@@ -939,7 +1031,7 @@ void MagField::AtlasFieldSvc::writeMap( TFile* rootfile ) const
         bscale = z.bscale();
         ncond = z.ncond();
         for ( int j = 0; j < ncond; j++ ) {
-            const BFieldCond c = z.cond(j);
+            const BFieldCond& c = z.cond(j);
             finite[j] = c.finite();
             p1x[j] = c.p1(0);
             p1y[j] = c.p1(1);
@@ -994,34 +1086,66 @@ void MagField::AtlasFieldSvc::writeMap( TFile* rootfile ) const
 //
 StatusCode MagField::AtlasFieldSvc::readMap( TFile* rootfile )
 {
-    if ( rootfile == 0 ) {
+    if ( rootfile == nullptr ) {
       // no file
       ATH_MSG_ERROR("readMap(): unable to read field map, no TFile given");
       return StatusCode::FAILURE;
     }
-    if ( rootfile->cd() == false ) {
+    if ( !rootfile->cd() ) {
       // could not make it current directory
       ATH_MSG_ERROR("readMap(): unable to cd() into the ROOT field map TFile");
       return StatusCode::FAILURE; 
     }
     // open the tree
     TTree* tree = (TTree*)rootfile->Get("BFieldMap");
-    if ( tree == 0 ) {
+    if ( tree == nullptr ) {
       // no tree
       ATH_MSG_ERROR("readMap(): TTree 'BFieldMap' does not exist in ROOT field map");
       return StatusCode::FAILURE;
     }
     int id;
-    double zmin, zmax, rmin, rmax, phimin, phimax;
+    double zmin;
+
+    double zmax;
+
+    double rmin;
+
+    double rmax;
+
+    double phimin;
+
+    double phimax;
     double bscale;
     int ncond;
     bool *finite;
-    double *p1x, *p1y, *p1z, *p2x, *p2y, *p2z;
+    double *p1x;
+
+    double *p1y;
+
+    double *p1z;
+
+    double *p2x;
+
+    double *p2y;
+
+    double *p2z;
     double *curr;
-    int nmeshz, nmeshr, nmeshphi;
-    double *meshz, *meshr, *meshphi;
+    int nmeshz;
+
+    int nmeshr;
+
+    int nmeshphi;
+    double *meshz;
+
+    double *meshr;
+
+    double *meshphi;
     int nfield;
-    short *fieldz, *fieldr, *fieldphi;
+    short *fieldz;
+
+    short *fieldr;
+
+    short *fieldphi;
     // define the fixed-sized branches first
     tree->SetBranchAddress( "id", &id );
     tree->SetBranchAddress( "zmin", &zmin );
@@ -1038,9 +1162,17 @@ StatusCode MagField::AtlasFieldSvc::readMap( TFile* rootfile )
     tree->SetBranchAddress( "nfield", &nfield );
     // prepare arrays - need to know the maximum sizes
     // open the tree of buffer sizes (may not exist in old maps)
-    unsigned maxcond(0), maxmeshz(0), maxmeshr(0), maxmeshphi(0), maxfield(0);
+    unsigned maxcond(0);
+
+    unsigned maxmeshz(0);
+
+    unsigned maxmeshr(0);
+
+    unsigned maxmeshphi(0);
+
+    unsigned maxfield(0);
     TTree* tmax = (TTree*)rootfile->Get("BFieldMapSize");
-    if ( tmax != 0 ) {
+    if ( tmax != nullptr ) {
         tmax->SetBranchAddress( "maxcond", &maxcond );
         tmax->SetBranchAddress( "maxmeshz", &maxmeshz );
         tmax->SetBranchAddress( "maxmeshr", &maxmeshr );
@@ -1096,7 +1228,9 @@ StatusCode MagField::AtlasFieldSvc::readMap( TFile* rootfile )
         m_zone.push_back(z);
         m_zone.back().reserve( nmeshz, nmeshr, nmeshphi );
         for ( int j = 0; j < ncond; j++ ) {
-            double p1[3], p2[3];
+            double p1[3];
+
+            double p2[3];
             p1[0] = p1x[j];
             p1[1] = p1y[j];
             p1[2] = p1z[j];
@@ -1251,7 +1385,7 @@ BFieldZone* MagField::AtlasFieldSvc::findZoneSlow( double z, double r, double ph
     for ( int j = m_zone.size()-1; j >= 0; --j ) {
         if ( m_zone[j].inside( z, r, phi ) ) return &m_zone[j];
     }
-    return 0;
+    return nullptr;
 }
 
 //
@@ -1397,7 +1531,7 @@ void MagField::AtlasFieldSvc::buildZR()
                 xyz[1] = r*sin(phi);
                 xyz[2] = z;
                 double B[3];
-                solezone->getB( xyz, B, 0 );
+                solezone->getB( xyz, B, nullptr );
                 Br += B[0]*cos(phi) + B[1]*sin(phi);
                 Bz += B[2];
             }
diff --git a/MagneticField/MagFieldServices/src/BFieldH8Grid.cxx b/MagneticField/MagFieldServices/src/BFieldH8Grid.cxx
index f68cc8dbd701e58ee1665838c70ee68ef3ff2a17..d53c169f997cba734f12c1455e4a46bf64f9adf7 100644
--- a/MagneticField/MagFieldServices/src/BFieldH8Grid.cxx
+++ b/MagneticField/MagFieldServices/src/BFieldH8Grid.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -78,7 +78,7 @@ BFieldH8Grid::getB( const double *xyz, double *B, double *deriv ) const
 {
     if ( !defined() || !inside( xyz ) ) {
         B[0] = B[1] = B[2] = 0.0;
-        if ( deriv != 0 ) {
+        if ( deriv != nullptr ) {
             for ( int j = 0; j < 9; j++ ) deriv[j] = 0.0;
         }
         return;
@@ -112,7 +112,7 @@ BFieldH8Grid::getB( const double *xyz, double *B, double *deriv ) const
                       f[1]*( g[0]*m_B[i][ixyz[6]] + f[0]*m_B[i][ixyz[7]] ) );
     }
     // derivatives
-    if ( deriv != 0 ) {
+    if ( deriv != nullptr ) {
         for ( int i=0; i<3; i++ ) { // Bx, By, Bz
             deriv[i*3  ] = ( g[2]*( g[1]*(m_B[i][ixyz[1]] - m_B[i][ixyz[0]] ) +
                                     f[1]*(m_B[i][ixyz[3]] - m_B[i][ixyz[2]] ) ) +
diff --git a/MagneticField/MagFieldServices/src/BFieldSolenoid.cxx b/MagneticField/MagFieldServices/src/BFieldSolenoid.cxx
index 0c5de32ca7186cbd6401ae9d1f699fc4f6347bfe..c6e9194d8308ad87599b6c888624da449528840b 100644
--- a/MagneticField/MagFieldServices/src/BFieldSolenoid.cxx
+++ b/MagneticField/MagFieldServices/src/BFieldSolenoid.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -33,7 +33,11 @@ BFieldSolenoid::readMap( istream& input )
         return 1;
     }
     // second line contains number of bins
-    int nz, nr, nphi;
+    int nz;
+
+    int nr;
+
+    int nphi;
     double unused;
     input >> nz >> nr >> nphi >> unused >> unused >> unused;
     m_orig->reserve( nz, nr, nphi+1 ); // extra phi at 2pi
@@ -55,7 +59,11 @@ BFieldSolenoid::readMap( istream& input )
     // read field values
     // the index order is opposite to the toroid - have to reorder
     // also convert from gauss to Tesla here.
-    vector<double> Bz, Br, Bphi;
+    vector<double> Bz;
+
+    vector<double> Br;
+
+    vector<double> Bphi;
     double b;
     for ( int k = 0; k < nphi; k++ ) {
         for ( int j = 0; j < nr; j++ ) {
@@ -96,9 +104,9 @@ void
 BFieldSolenoid::writeMap( TFile* rootfile, bool tilted )
 {
     BFieldMesh<double> *map = tilted ? m_tilt : m_orig;
-    if ( map == 0 ) return; // no map to write
-    if ( rootfile == 0 ) return; // no file
-    if ( rootfile->cd() == false ) return; // could not make it current directory
+    if ( map == nullptr ) return; // no map to write
+    if ( rootfile == nullptr ) return; // no file
+    if ( !rootfile->cd() ) return; // could not make it current directory
     // define the tree
     TTree* tree = new TTree( "BFieldSolenoid", "BFieldSolenoid version 4" );
     double zmin = map->zmin();
@@ -110,9 +118,17 @@ BFieldSolenoid::writeMap( TFile* rootfile, bool tilted )
     int nmeshz = map->nmesh(0);
     int nmeshr = map->nmesh(1);
     int nmeshphi = map->nmesh(2);
-    double *meshz, *meshr, *meshphi;
+    double *meshz;
+
+    double *meshr;
+
+    double *meshphi;
     int nfield = nmeshz*nmeshr*nmeshphi;
-    double *fieldz, *fieldr, *fieldphi;
+    double *fieldz;
+
+    double *fieldr;
+
+    double *fieldphi;
     meshz = new double[nmeshz];
     meshr = new double[nmeshr];
     meshphi = new double[nmeshphi];
@@ -171,19 +187,41 @@ BFieldSolenoid::writeMap( TFile* rootfile, bool tilted )
 int
 BFieldSolenoid::readMap( TFile* rootfile )
 {
-    if ( rootfile == 0 ) return 1; // no file
-    if ( rootfile->cd() == false ) return 2; // could not make it current directory
+    if ( rootfile == nullptr ) return 1; // no file
+    if ( !rootfile->cd() ) return 2; // could not make it current directory
     if ( m_orig == m_tilt ) delete m_orig;
     else { delete m_orig; delete m_tilt; }
     m_orig = m_tilt = new BFieldMesh<double>;
     // open the tree
     TTree* tree = (TTree*)rootfile->Get("BFieldSolenoid");
-    if ( tree == 0 ) return 3; // no tree
-    double zmin, zmax, rmin, rmax, phimin, phimax;
-    int nmeshz, nmeshr, nmeshphi;
-    double *meshz, *meshr, *meshphi;
+    if ( tree == nullptr ) return 3; // no tree
+    double zmin;
+
+    double zmax;
+
+    double rmin;
+
+    double rmax;
+
+    double phimin;
+
+    double phimax;
+    int nmeshz;
+
+    int nmeshr;
+
+    int nmeshphi;
+    double *meshz;
+
+    double *meshr;
+
+    double *meshphi;
     int nfield;
-    double *fieldz, *fieldr, *fieldphi;
+    double *fieldz;
+
+    double *fieldr;
+
+    double *fieldphi;
     //unsigned char *fbyte;
     // define the fixed-sized branches first
     tree->SetBranchAddress( "zmin", &zmin );
@@ -266,7 +304,7 @@ BFieldSolenoid::getB( const double *xyz, double *B, double *deriv ) const
 void
 BFieldSolenoid::moveMap( double dx, double dy, double dz, double ax, double ay )
 {
-    if ( m_orig==0 ) {
+    if ( m_orig==nullptr ) {
         cerr << "BFieldSolenoid::moveMap() : original map has not been read" << endl;
         return;
     }
diff --git a/MagneticField/MagFieldServices/src/H8FieldSvc.cxx b/MagneticField/MagFieldServices/src/H8FieldSvc.cxx
index cb8700a180bf8e08ef9c96678f49d16a154a8992..cf847e22a85faad0fd217aca90eca3c714894708 100644
--- a/MagneticField/MagFieldServices/src/H8FieldSvc.cxx
+++ b/MagneticField/MagFieldServices/src/H8FieldSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 //
@@ -69,11 +69,11 @@ StatusCode MagField::H8FieldSvc::finalize()
     return StatusCode::SUCCESS;
 }
 
-StatusCode MagField::H8FieldSvc::readMap( const std::string mapFile )
+StatusCode MagField::H8FieldSvc::readMap( const std::string& mapFile )
 {
     // find the path to the map file
     std::string resolvedMapFile = PathResolver::find_file( mapFile.c_str(), "DATAPATH" );
-    if ( resolvedMapFile == "" ) {
+    if ( resolvedMapFile.empty() ) {
         ATH_MSG_ERROR( "Field map file " << mapFile << " not found" );
         return StatusCode::FAILURE;
     }
@@ -145,14 +145,12 @@ void MagField::H8FieldSvc::getField( const double *xyz, double *B, double *deriv
     }
     // xyz is outside all grids
     B[0] = B[1] = B[2] = 0.0;
-    if ( deriv != 0 ) {
+    if ( deriv != nullptr ) {
         for ( int j = 0; j < 9; j++ ) deriv[j] = 0.0;
     }
-    return;
-}
+    }
 
 void MagField::H8FieldSvc::getFieldZR( const double *xyz, double *B, double *deriv ) const
 {
     getField( xyz, B, deriv );
-    return;
 }
diff --git a/MagneticField/MagFieldServices/src/components/MagFieldServices_entries.cxx b/MagneticField/MagFieldServices/src/components/MagFieldServices_entries.cxx
index 4b16a448307e522847e02fa5f8af884097b89811..00ceb76cc36579c0a0b39c24f72b8932cd3557d1 100644
--- a/MagneticField/MagFieldServices/src/components/MagFieldServices_entries.cxx
+++ b/MagneticField/MagFieldServices/src/components/MagFieldServices_entries.cxx
@@ -1,6 +1,10 @@
 #include "MagFieldServices/AtlasFieldSvc.h"
+#include "MagFieldServices/AtlasFieldMapCondAlg.h"
+#include "MagFieldServices/AtlasFieldCacheCondAlg.h"
 #include "MagFieldServices/H8FieldSvc.h"
 
 DECLARE_COMPONENT( MagField::AtlasFieldSvc )
+DECLARE_COMPONENT( MagField::AtlasFieldMapCondAlg )
+DECLARE_COMPONENT( MagField::AtlasFieldCacheCondAlg )
 DECLARE_COMPONENT( MagField::H8FieldSvc )
 
diff --git a/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/MuonByteStreamCnvTest/MuonRdoToMuonDigitTool.h b/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/MuonByteStreamCnvTest/MuonRdoToMuonDigitTool.h
index 25c75ae35b650f8011398c791ec48147d2bc4651..533a47637af96881cb6e2275da162a13573ee012 100644
--- a/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/MuonByteStreamCnvTest/MuonRdoToMuonDigitTool.h
+++ b/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/MuonByteStreamCnvTest/MuonRdoToMuonDigitTool.h
@@ -73,28 +73,28 @@ class MuonRdoToMuonDigitTool : virtual public IMuonDigitizationTool, public AthA
   ~MuonRdoToMuonDigitTool();
     
   virtual StatusCode initialize() override;
-  virtual StatusCode digitize()   override;
+  virtual StatusCode digitize(const EventContext& ctx)   override;
 
  private:
 
   // private method for the decoding RDO --> digits
-  StatusCode decodeMdtRDO(MdtDigitContainer*);
+  StatusCode decodeMdtRDO(const EventContext& ctx, MdtDigitContainer*); 
   StatusCode decodeMdt(MdtDigitContainer*, const MdtCsm *, MdtDigitCollection*&, Identifier& );
 
-  StatusCode decodeCscRDO(CscDigitContainer*);
+  StatusCode decodeCscRDO(const EventContext& ctx, CscDigitContainer*);
   //  StatusCode decodeCsc( const CscRawDataCollection *, CscDigitCollection*, Identifier&, CscRDO_Decoder& decoder );
   StatusCode decodeCsc(CscDigitContainer*, const CscRawDataCollection *, CscDigitCollection*&, Identifier&);
 
-  StatusCode decodeRpcRDO(RpcDigitContainer*);
+  StatusCode decodeRpcRDO(const EventContext& ctx, RpcDigitContainer*);
   StatusCode decodeRpc(RpcDigitContainer*, const RpcPad *, RpcDigitCollection*& );
  
-  StatusCode decodeTgcRDO(TgcDigitContainer*);
+  StatusCode decodeTgcRDO(const EventContext& ctx, TgcDigitContainer*);
   StatusCode decodeTgc(TgcDigitContainer*, const TgcRdo *, Identifier&);
 
-  StatusCode decodeSTGC_RDO(sTgcDigitContainer*);
+  StatusCode decodeSTGC_RDO(const EventContext& ctx, sTgcDigitContainer*);
   StatusCode decodeSTGC(sTgcDigitContainer*, const Muon::STGC_RawDataCollection *, sTgcDigitCollection*&, Identifier&);
 
-  StatusCode decodeMM_RDO(MmDigitContainer*);
+  StatusCode decodeMM_RDO(const EventContext& ctx, MmDigitContainer*);
   StatusCode decodeMM(MmDigitContainer*, const Muon::MM_RawDataCollection *, MmDigitCollection*&, Identifier&);
 
   StatusCode getTgcCabling();
diff --git a/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/CscDigitToCscRDO.cxx b/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/CscDigitToCscRDO.cxx
index 6e031d709e61dc538da7c0345c9b319ca129118f..84fd15d3a9ff469a2903369265b04163c9d0607a 100644
--- a/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/CscDigitToCscRDO.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/CscDigitToCscRDO.cxx
@@ -30,7 +30,7 @@ StatusCode CscDigitToCscRDO::initialize()
 StatusCode CscDigitToCscRDO::execute()
 {
   ATH_MSG_DEBUG( "in execute()"  );
-  return m_digTool->digitize();
+  return m_digTool->digitize(Gaudi::Hive::currentContext());
 }
 
 StatusCode CscDigitToCscRDO::finalize()
diff --git a/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/MuonRdoToMuonDigit.cxx b/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/MuonRdoToMuonDigit.cxx
index b4156c8c513fe444ace1ec358d2402c2dfef70a8..6ef2bff255f6fa915e045e1073ae2350483fc9e5 100644
--- a/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/MuonRdoToMuonDigit.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/MuonRdoToMuonDigit.cxx
@@ -26,7 +26,7 @@ StatusCode MuonRdoToMuonDigit::initialize()
 StatusCode MuonRdoToMuonDigit::execute()
 {
   ATH_MSG_DEBUG( "in execute()"  );
-  return m_digTool->digitize();
+  return m_digTool->digitize(Gaudi::Hive::currentContext());
 }
 
 
diff --git a/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/MuonRdoToMuonDigitTool.cxx b/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/MuonRdoToMuonDigitTool.cxx
index 40536b4e8e2ad1c60e01a9cde77197d6d590552c..772686b372acc1128a5edebbba9e2f37ecd548a9 100644
--- a/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/MuonRdoToMuonDigitTool.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonByteStreamCnvTest/src/MuonRdoToMuonDigitTool.cxx
@@ -146,7 +146,7 @@ StatusCode MuonRdoToMuonDigitTool::initialize() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode MuonRdoToMuonDigitTool::digitize() {
+StatusCode MuonRdoToMuonDigitTool::digitize(const EventContext& ctx) {
 
   ATH_MSG_DEBUG( " *************** in MuonRdoToMuonDigitTool::digitize()"  );
   ATH_MSG_DEBUG( "in digitize()"  );
@@ -154,40 +154,40 @@ StatusCode MuonRdoToMuonDigitTool::digitize() {
   // create digit containers and decode
 
   if (m_decodeMdtRDO){
-    SG::WriteHandle<MdtDigitContainer> wh_mdtDigit(m_mdtDigitKey);
+    SG::WriteHandle<MdtDigitContainer> wh_mdtDigit(m_mdtDigitKey, ctx);
     ATH_CHECK(wh_mdtDigit.record(std::make_unique<MdtDigitContainer>(m_muonIdHelperTool->mdtIdHelper().module_hash_max())));
-    ATH_CHECK( decodeMdtRDO(wh_mdtDigit.ptr()) );
+    ATH_CHECK( decodeMdtRDO(ctx, wh_mdtDigit.ptr()) );
   }
 
   if (m_decodeCscRDO){
-    SG::WriteHandle<CscDigitContainer> wh_cscDigit(m_cscDigitKey);
+    SG::WriteHandle<CscDigitContainer> wh_cscDigit(m_cscDigitKey, ctx);
     ATH_CHECK(wh_cscDigit.record(std::make_unique<CscDigitContainer> (m_muonIdHelperTool->cscIdHelper().module_hash_max())));
-    ATH_CHECK( decodeCscRDO(wh_cscDigit.ptr()) );
+    ATH_CHECK( decodeCscRDO(ctx, wh_cscDigit.ptr()) );
   }
 
   if (m_decodeRpcRDO ){
-    SG::WriteHandle<RpcDigitContainer> wh_rpcDigit(m_rpcDigitKey);
+    SG::WriteHandle<RpcDigitContainer> wh_rpcDigit(m_rpcDigitKey, ctx);
     ATH_CHECK(wh_rpcDigit.record(std::make_unique<RpcDigitContainer> (m_muonIdHelperTool->rpcIdHelper().module_hash_max())));
-    ATH_CHECK( decodeRpcRDO(wh_rpcDigit.ptr()) );
+    ATH_CHECK( decodeRpcRDO(ctx, wh_rpcDigit.ptr()) );
   }
 
   if(!m_tgcCabling && getTgcCabling().isFailure()) return StatusCode::FAILURE;
   if (m_decodeTgcRDO && m_tgcCabling){
-    SG::WriteHandle<TgcDigitContainer> wh_tgcDigit(m_tgcDigitKey);
+    SG::WriteHandle<TgcDigitContainer> wh_tgcDigit(m_tgcDigitKey, ctx);
     ATH_CHECK(wh_tgcDigit.record(std::make_unique<TgcDigitContainer> (m_muonIdHelperTool->tgcIdHelper().module_hash_max())));
-    ATH_CHECK( decodeTgcRDO(wh_tgcDigit.ptr()) );
+    ATH_CHECK( decodeTgcRDO(ctx, wh_tgcDigit.ptr()) );
   }
 
   if (m_decodesTgcRDO){
-    SG::WriteHandle<sTgcDigitContainer> wh_stgcDigit(m_stgcDigitKey);
+    SG::WriteHandle<sTgcDigitContainer> wh_stgcDigit(m_stgcDigitKey, ctx);
     ATH_CHECK(wh_stgcDigit.record(std::make_unique<sTgcDigitContainer> (m_muonIdHelperTool->stgcIdHelper().module_hash_max())));
-    ATH_CHECK( decodeSTGC_RDO(wh_stgcDigit.ptr()) );
+    ATH_CHECK( decodeSTGC_RDO(ctx, wh_stgcDigit.ptr()) );
   }
 
   if (m_decodeMmRDO){
-    SG::WriteHandle<MmDigitContainer> wh_mmDigit(m_mmDigitKey);
+    SG::WriteHandle<MmDigitContainer> wh_mmDigit(m_mmDigitKey, ctx);
     ATH_CHECK(wh_mmDigit.record(std::make_unique<MmDigitContainer> (m_muonIdHelperTool->mmIdHelper().module_hash_max())));
-    ATH_CHECK( decodeMM_RDO(wh_mmDigit.ptr()) );
+    ATH_CHECK( decodeMM_RDO(ctx, wh_mmDigit.ptr()) );
   }
 
 
@@ -195,7 +195,7 @@ StatusCode MuonRdoToMuonDigitTool::digitize() {
 }
 
 
-StatusCode MuonRdoToMuonDigitTool::decodeMdtRDO(MdtDigitContainer *mdtContainer) {
+StatusCode MuonRdoToMuonDigitTool::decodeMdtRDO(const EventContext& ctx, MdtDigitContainer *mdtContainer) {
 
   ATH_MSG_DEBUG( "Decoding MDT RDO into MDT Digit"  );
 
@@ -203,7 +203,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeMdtRDO(MdtDigitContainer *mdtContainer)
   Identifier oldId;
   MdtDigitCollection * collection = 0;
 
-  SG::ReadHandle<MdtCsmContainer> rdoRH(m_mdtRdoKey);
+  SG::ReadHandle<MdtCsmContainer> rdoRH(m_mdtRdoKey, ctx);
   if (!rdoRH.isValid()) {
     ATH_MSG_WARNING( "No MDT RDO container found!"  );
     return StatusCode::SUCCESS;
@@ -223,7 +223,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeMdtRDO(MdtDigitContainer *mdtContainer)
   return StatusCode::SUCCESS;
 }
 
-StatusCode MuonRdoToMuonDigitTool::decodeCscRDO(CscDigitContainer* cscContainer) {
+StatusCode MuonRdoToMuonDigitTool::decodeCscRDO(const EventContext& ctx, CscDigitContainer* cscContainer) {
 
   ATH_MSG_DEBUG( "Decoding CSC RDO into CSC Digit"  );
 
@@ -233,7 +233,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeCscRDO(CscDigitContainer* cscContainer)
   CscDigitCollection * collection = 0;
 
   // retrieve the collection of RDO
-  SG::ReadHandle<CscRawDataContainer> rdoRH(m_cscRdoKey);
+  SG::ReadHandle<CscRawDataContainer> rdoRH(m_cscRdoKey, ctx);
   if (!rdoRH.isValid()) {
     ATH_MSG_WARNING( "No CSC RDO container found!"  );
     return StatusCode::SUCCESS;
@@ -253,7 +253,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeCscRDO(CscDigitContainer* cscContainer)
   return StatusCode::SUCCESS;
 }
 
-StatusCode MuonRdoToMuonDigitTool::decodeRpcRDO(RpcDigitContainer *rpcContainer) {
+StatusCode MuonRdoToMuonDigitTool::decodeRpcRDO(const EventContext& ctx, RpcDigitContainer *rpcContainer) {
 
     ATH_MSG_DEBUG( "Decoding RPC RDO into RPC Digit"  );
 
@@ -261,7 +261,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeRpcRDO(RpcDigitContainer *rpcContainer)
     const RpcPadContainer* rdoContainer;
 
     // retrieve the collection of RDO
-    SG::ReadHandle<RpcPadContainer> rdoRH(m_rpcRdoKey);
+    SG::ReadHandle<RpcPadContainer> rdoRH(m_rpcRdoKey, ctx);
     if (!rdoRH.isValid()) {
       ATH_MSG_WARNING( "No RPC RDO container found!"  );
       return StatusCode::SUCCESS;
@@ -282,7 +282,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeRpcRDO(RpcDigitContainer *rpcContainer)
     return StatusCode::SUCCESS;
 }
 
-StatusCode MuonRdoToMuonDigitTool::decodeTgcRDO(TgcDigitContainer *tgcContainer) {
+StatusCode MuonRdoToMuonDigitTool::decodeTgcRDO(const EventContext& ctx, TgcDigitContainer *tgcContainer) {
 
   ATH_MSG_DEBUG( "Decoding TGC RDO into TGC Digit"  );
 
@@ -291,7 +291,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeTgcRDO(TgcDigitContainer *tgcContainer)
   Identifier oldElementId;
 
   // retrieve the collection of RDO
-  SG::ReadHandle<TgcRdoContainer> rdoRH(m_tgcRdoKey);
+  SG::ReadHandle<TgcRdoContainer> rdoRH(m_tgcRdoKey, ctx);
   if (!rdoRH.isValid()) {
     ATH_MSG_WARNING( "No TGC RDO container found!"  );
     return StatusCode::SUCCESS;
@@ -313,7 +313,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeTgcRDO(TgcDigitContainer *tgcContainer)
   return StatusCode::SUCCESS;
 }
 
-StatusCode MuonRdoToMuonDigitTool::decodeSTGC_RDO(sTgcDigitContainer* stgcContainer) {
+StatusCode MuonRdoToMuonDigitTool::decodeSTGC_RDO(const EventContext& ctx, sTgcDigitContainer* stgcContainer) {
 
   ATH_MSG_DEBUG( "Decoding sTGC RDO into sTGC Digit"  );
 
@@ -323,7 +323,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeSTGC_RDO(sTgcDigitContainer* stgcContai
   Identifier oldId;
   sTgcDigitCollection * collection = 0;
 
-  SG::ReadHandle<Muon::STGC_RawDataContainer> rdoRH(m_stgcRdoKey);
+  SG::ReadHandle<Muon::STGC_RawDataContainer> rdoRH(m_stgcRdoKey, ctx);
   if (!rdoRH.isValid()) {
     ATH_MSG_WARNING( "No sTGC RDO container found!" );
     return StatusCode::SUCCESS;
@@ -341,7 +341,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeSTGC_RDO(sTgcDigitContainer* stgcContai
   return StatusCode::SUCCESS;
 }
 
-StatusCode MuonRdoToMuonDigitTool::decodeMM_RDO(MmDigitContainer *mmContainer) {
+StatusCode MuonRdoToMuonDigitTool::decodeMM_RDO(const EventContext& ctx, MmDigitContainer *mmContainer) {
 
   ATH_MSG_DEBUG( "Decoding MM RDO into MM Digit"  );
 
@@ -350,7 +350,7 @@ StatusCode MuonRdoToMuonDigitTool::decodeMM_RDO(MmDigitContainer *mmContainer) {
   Identifier oldId;
   MmDigitCollection * collection = 0;
 
-  SG::ReadHandle<Muon::MM_RawDataContainer> rdoRH(m_mmRdoKey);
+  SG::ReadHandle<Muon::MM_RawDataContainer> rdoRH(m_mmRdoKey, ctx);
   if (!rdoRH.isValid()) {
     ATH_MSG_WARNING( "No MM RDO container found!" );
     return StatusCode::SUCCESS;
diff --git a/MuonSpectrometer/MuonCnv/MuonCSC_CnvTools/src/CscDigitToCscRDOTool.cxx b/MuonSpectrometer/MuonCnv/MuonCSC_CnvTools/src/CscDigitToCscRDOTool.cxx
index fccd6c131bff9408f7bc457a3c69928719a02e8b..f6e5d12ee996fdaf427f3f85b2ec2e47b7bc663e 100644
--- a/MuonSpectrometer/MuonCnv/MuonCSC_CnvTools/src/CscDigitToCscRDOTool.cxx
+++ b/MuonSpectrometer/MuonCnv/MuonCSC_CnvTools/src/CscDigitToCscRDOTool.cxx
@@ -70,7 +70,7 @@ StatusCode CscDigitToCscRDOTool::initialize()
   return StatusCode::SUCCESS;
 }
  
-StatusCode CscDigitToCscRDOTool::digitize()
+StatusCode CscDigitToCscRDOTool::digitize(const EventContext& /*ctx*/)
 {
   ATH_MSG_DEBUG ( "in execute()" );
 
diff --git a/MuonSpectrometer/MuonCnv/MuonCSC_CnvTools/src/CscDigitToCscRDOTool.h b/MuonSpectrometer/MuonCnv/MuonCSC_CnvTools/src/CscDigitToCscRDOTool.h
index 5a554dfe2aa22578d659859c67a6ef9f2021104e..62613cc3ac789e0d35167bdf637db0fbab545ede 100644
--- a/MuonSpectrometer/MuonCnv/MuonCSC_CnvTools/src/CscDigitToCscRDOTool.h
+++ b/MuonSpectrometer/MuonCnv/MuonCSC_CnvTools/src/CscDigitToCscRDOTool.h
@@ -37,7 +37,7 @@ class CscDigitToCscRDOTool final : public extends<AthAlgTool, IMuonDigitizationT
   virtual ~CscDigitToCscRDOTool() = default;
 
   virtual StatusCode initialize() override;
-  virtual StatusCode digitize() override;
+  virtual StatusCode digitize(const EventContext& ctx) override;
 
  private:
 
diff --git a/MuonSpectrometer/MuonDigitization/CSC_Digitization/CSC_Digitization/CscDigitizationTool.h b/MuonSpectrometer/MuonDigitization/CSC_Digitization/CSC_Digitization/CscDigitizationTool.h
index 2de2b90ef3cfe62adb9d067a200d24a6f5459749..bf1250237555e600a866a90f7ef860c364955488 100644
--- a/MuonSpectrometer/MuonDigitization/CSC_Digitization/CSC_Digitization/CscDigitizationTool.h
+++ b/MuonSpectrometer/MuonDigitization/CSC_Digitization/CSC_Digitization/CscDigitizationTool.h
@@ -52,7 +52,7 @@ public:
 
   // PileUpTool methods...
   ///called at the end of the subevts loop. Not (necessarily) able to access subEvents
-  virtual StatusCode mergeEvent()  override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx)  override final;
 
   ///called for each active bunch-crossing to process current subEvents. bunchXing is in ns
   virtual  StatusCode processBunchXing(
@@ -64,11 +64,11 @@ public:
   /// return false if not interested in  certain xing times (in ns)
   /// implemented by default in PileUpToolBase as FirstXing<=bunchXing<=LastXing
   //  virtual bool toProcess(int bunchXing) const;
-  virtual StatusCode prepareEvent(unsigned int /*nInputEvents*/)  override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int /*nInputEvents*/)  override final;
 
   /// alternative interface which uses the PileUpMergeSvc to obtain
   /// all the required SubEvents.
-  virtual StatusCode processAllSubEvents()  override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx)  override final;
 
 public: //possibly these should be private?
   StatusCode FillCollectionWithNewDigitEDM(csc_newmap& data_SampleMap, //csc_newmap& data_SampleMapOddPhase,
@@ -79,7 +79,7 @@ public: //possibly these should be private?
   StatusCode CoreDigitization(CscDigitContainer* cscDigits,CscSimDataCollection* cscSimData, CLHEP::HepRandomEngine* rndmEngine);
 
   // Get next event and extract collection of hit collections:
-  StatusCode getNextEvent();
+  StatusCode getNextEvent(const EventContext& ctx);
 
 private:
 
diff --git a/MuonSpectrometer/MuonDigitization/CSC_Digitization/src/CscDigitBuilder.cxx b/MuonSpectrometer/MuonDigitization/CSC_Digitization/src/CscDigitBuilder.cxx
index 4cf98725ceefe2fd91e002bc80fbef478bc770f7..ea7c847a2d178450f2c31d16b582638463f15093 100644
--- a/MuonSpectrometer/MuonDigitization/CSC_Digitization/src/CscDigitBuilder.cxx
+++ b/MuonSpectrometer/MuonDigitization/CSC_Digitization/src/CscDigitBuilder.cxx
@@ -24,5 +24,5 @@ StatusCode CscDigitBuilder::initialize() {
 
 StatusCode CscDigitBuilder::execute() {
   ATH_MSG_DEBUG ( "in execute()" );
-  return m_digTool->processAllSubEvents();
+  return m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/MuonSpectrometer/MuonDigitization/CSC_Digitization/src/CscDigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/CSC_Digitization/src/CscDigitizationTool.cxx
index 2ff5574f266a085bd91fad5b1a13ec3df0918683..5ba699e2e3688ec6362ee6b1218d6a25adee314f 100644
--- a/MuonSpectrometer/MuonDigitization/CSC_Digitization/src/CscDigitizationTool.cxx
+++ b/MuonSpectrometer/MuonDigitization/CSC_Digitization/src/CscDigitizationTool.cxx
@@ -113,7 +113,7 @@ StatusCode CscDigitizationTool::initialize() {
 }
 
 // Inherited from PileUpTools
-StatusCode CscDigitizationTool::prepareEvent(unsigned int /*nInputEvents*/) {
+StatusCode CscDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int /*nInputEvents*/) {
 
   if (0 == m_thpcCSC)
     m_thpcCSC = new TimedHitCollection<CSCSimHit>();
@@ -124,25 +124,25 @@ StatusCode CscDigitizationTool::prepareEvent(unsigned int /*nInputEvents*/) {
 }
 ///////////////////////////////
 
-StatusCode CscDigitizationTool::processAllSubEvents() {
+StatusCode CscDigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
   ATH_MSG_DEBUG ( "in processAllSubEvents()" );
 
   //create and record CscDigitContainer in SG
-  SG::WriteHandle<CscDigitContainer> cscDigits(m_cscDigitContainerKey);
+  SG::WriteHandle<CscDigitContainer> cscDigits(m_cscDigitContainerKey, ctx);
   ATH_CHECK(cscDigits.record(std::make_unique<CscDigitContainer>(m_muonIdHelperTool->cscIdHelper().module_hash_max())));
   ATH_MSG_DEBUG("recorded CscDigitContainer with name "<<cscDigits.key());
 
   if (m_isPileUp) return StatusCode::SUCCESS;
 
   // create and record the SDO container in StoreGate
-  SG::WriteHandle<CscSimDataCollection> cscSimData(m_cscSimDataCollectionWriteHandleKey);
+  SG::WriteHandle<CscSimDataCollection> cscSimData(m_cscSimDataCollectionWriteHandleKey, ctx);
   ATH_CHECK(cscSimData.record(std::make_unique<CscSimDataCollection>()));
 
   //merging of the hit collection in getNextEvent method
 
   if (0 == m_thpcCSC ) {
-    StatusCode sc = getNextEvent();
+    StatusCode sc = getNextEvent(ctx);
     if (StatusCode::FAILURE == sc) {
       ATH_MSG_INFO ( "There are no CSC hits in this event" );
       return sc; // there are no hits in this event
@@ -150,8 +150,8 @@ StatusCode CscDigitizationTool::processAllSubEvents() {
   }
 
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
-  return CoreDigitization(cscDigits.ptr(),cscSimData.ptr(), *rngWrapper);
+  rngWrapper->setSeed( name(), ctx );
+  return CoreDigitization(cscDigits.ptr(),cscSimData.ptr(), rngWrapper->getEngine(ctx));
 
 }
 
@@ -518,7 +518,7 @@ FillCollectionWithOldDigitEDM(csc_map& data_map, std::map<IdentifierHash,deposit
 
 
 // Get next event and extract collection of hit collections:
-StatusCode CscDigitizationTool::getNextEvent() // This is applicable to non-PileUp Event...
+StatusCode CscDigitizationTool::getNextEvent(const EventContext& ctx) // This is applicable to non-PileUp Event...
 {
 
   //  get the container(s)
@@ -526,7 +526,7 @@ StatusCode CscDigitizationTool::getNextEvent() // This is applicable to non-Pile
 
   // In case of single hits container just load the collection using read handles
   if (!m_onlyUseContainerName) {
-    SG::ReadHandle<CSCSimHitCollection> hitCollection(m_hitsContainerKey);
+    SG::ReadHandle<CSCSimHitCollection> hitCollection(m_hitsContainerKey, ctx);
     if (!hitCollection.isValid()) {
       ATH_MSG_ERROR("Could not get CSCSimHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
       return StatusCode::FAILURE;
@@ -618,22 +618,22 @@ StatusCode CscDigitizationTool::processBunchXing(int bunchXing,
 }
 
 //////////////////////////
-StatusCode CscDigitizationTool::mergeEvent() {
+StatusCode CscDigitizationTool::mergeEvent(const EventContext& ctx) {
 
   ATH_MSG_DEBUG ( "in mergeEvent()" );
 
   //create and record CscDigitContainer in SG
-  SG::WriteHandle<CscDigitContainer> cscDigits(m_cscDigitContainerKey);
+  SG::WriteHandle<CscDigitContainer> cscDigits(m_cscDigitContainerKey, ctx);
   ATH_CHECK(cscDigits.record(std::make_unique<CscDigitContainer>(m_muonIdHelperTool->cscIdHelper().module_hash_max())));
   ATH_MSG_DEBUG("recorded CscDigitContainer with name "<<cscDigits.key());
 
   // create and record the SDO container in StoreGate
-  SG::WriteHandle<CscSimDataCollection> cscSimData(m_cscSimDataCollectionWriteHandleKey);
+  SG::WriteHandle<CscSimDataCollection> cscSimData(m_cscSimDataCollectionWriteHandleKey, ctx);
   ATH_CHECK(cscSimData.record(std::make_unique<CscSimDataCollection>()));
 
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
-  ATH_CHECK(CoreDigitization(cscDigits.ptr(),cscSimData.ptr(), *rngWrapper));
+  rngWrapper->setSeed( name(), ctx );
+  ATH_CHECK(CoreDigitization(cscDigits.ptr(),cscSimData.ptr(), rngWrapper->getEngine(ctx)));
 
   // remove cloned one in processBunchXing......
   std::list<CSCSimHitCollection*>::iterator cscHitColl = m_cscHitCollList.begin();
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/MdtDigitizationTool.h b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/MdtDigitizationTool.h
index a2c7eaaef0009ada814ac1e96bd5840066a3a9a5..e6ab702e4a23f24538113c03174e7b86c3596b00 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/MdtDigitizationTool.h
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/MDT_Digitization/MdtDigitizationTool.h
@@ -108,7 +108,7 @@ class MdtDigitizationTool : public PileUpToolBase {
   virtual StatusCode initialize() override final;
 
   /** When being run from PileUpToolsAlgs, this method is called at the start of the subevts loop. Not able to access SubEvents */
-  StatusCode prepareEvent(const unsigned int /*nInputEvents*/) override final;
+  StatusCode prepareEvent(const EventContext& ctx, const unsigned int /*nInputEvents*/) override final;
 
   /** When being run from PileUpToolsAlgs, this method is called for each active bunch-crossing to process current SubEvents bunchXing is in ns */
    virtual StatusCode processBunchXing(
@@ -117,11 +117,11 @@ class MdtDigitizationTool : public PileUpToolBase {
                                 SubEventIterator eSubEvents
                                 ) override final;
   /** When being run from PileUpToolsAlgs, this method is called at the end of the subevts loop. Not (necessarily) able to access SubEvents */
-  StatusCode mergeEvent() override final;
+  StatusCode mergeEvent(const EventContext& ctx) override final;
 
   /** alternative interface which uses the PileUpMergeSvc to obtain
   all the required SubEvents. */
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
   struct GeoCorOut {
   GeoCorOut( double sSag, double sTrack, Amg::Vector3D lp, double lSag ) : sagSign(sSag), trackingSign(sTrack), localPosition(lp), localSag(lSag) {}
@@ -132,7 +132,7 @@ class MdtDigitizationTool : public PileUpToolBase {
   };
 
  private:
-  CLHEP::HepRandomEngine*   getRandomEngine(const std::string& streamName) const;
+  CLHEP::HepRandomEngine*   getRandomEngine(const std::string& streamName, const EventContext& ctx) const;
   int                       digitizeTime(double time, bool isHPTDC, CLHEP::HepRandomEngine *rndmEngine) const;
   double                    minimumTof(Identifier DigitId) const;
 
@@ -236,8 +236,8 @@ class MdtDigitizationTool : public PileUpToolBase {
   // Access to the event methods:
   ///////////////////////////////////////////////////////////////////
   // Get next event and extract collection of hit collections:
-  StatusCode                getNextEvent();
-  StatusCode doDigitization(MdtDigitContainer* digitContainer, MuonSimDataCollection* sdoContainer);
+  StatusCode                getNextEvent(const EventContext& ctx);
+  StatusCode doDigitization(const EventContext& ctx, MdtDigitContainer* digitContainer, MuonSimDataCollection* sdoContainer);
   MdtDigitCollection*       getDigitCollection(Identifier elementId, MdtDigitContainer* digitContainer);
   void                fillMaps(const MDTSimHit * mdtHit, const Identifier digitId,
                                const double driftR);
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MDT_Digitizer.cxx b/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MDT_Digitizer.cxx
index fc6a555f7969d1d5e88151dcd1d468e8bc5e8c23..1b71f5c433fe45194b70c3be84167ca0140dfc7a 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MDT_Digitizer.cxx
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MDT_Digitizer.cxx
@@ -21,5 +21,5 @@ StatusCode MDT_Digitizer::initialize() {
 
 StatusCode MDT_Digitizer::execute() {
   ATH_MSG_DEBUG("in execute()");
-  return m_digTool->processAllSubEvents();
+  return m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MdtDigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MdtDigitizationTool.cxx
index 607faaa3918aafd0b7abdeb189a3877f4ec74973..4dc72ed32fdc2fb02cfea217fd89c967a3f2c9de 100644
--- a/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MdtDigitizationTool.cxx
+++ b/MuonSpectrometer/MuonDigitization/MDT_Digitization/src/MdtDigitizationTool.cxx
@@ -184,7 +184,7 @@ StatusCode MdtDigitizationTool::initialize() {
 }
 
 
-StatusCode MdtDigitizationTool::prepareEvent(unsigned int nInputEvents) {
+StatusCode MdtDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents) {
   
   ATH_MSG_DEBUG("MdtDigitizationTool::prepareEvent() called for " << nInputEvents << " input events" );
 
@@ -237,7 +237,7 @@ StatusCode MdtDigitizationTool::processBunchXing(int bunchXing,
 }
 
 
-StatusCode MdtDigitizationTool::getNextEvent()
+StatusCode MdtDigitizationTool::getNextEvent(const EventContext& ctx)
 {
   
   ATH_MSG_DEBUG ( "MdtDigitizationTool::getNextEvent()" );
@@ -250,7 +250,7 @@ StatusCode MdtDigitizationTool::getNextEvent()
   
   // In case of single hits container just load the collection using read handles
   if (!m_onlyUseContainerName) {
-    SG::ReadHandle<MDTSimHitCollection> hitCollection(m_hitsContainerKey);
+    SG::ReadHandle<MDTSimHitCollection> hitCollection(m_hitsContainerKey, ctx);
     if (!hitCollection.isValid()) {
       ATH_MSG_ERROR("Could not get MDTSimHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
       return StatusCode::FAILURE;
@@ -294,29 +294,29 @@ StatusCode MdtDigitizationTool::getNextEvent()
   return StatusCode::SUCCESS;
 }
 
-CLHEP::HepRandomEngine* MdtDigitizationTool::getRandomEngine(const std::string& streamName) const
+CLHEP::HepRandomEngine* MdtDigitizationTool::getRandomEngine(const std::string& streamName, const EventContext& ctx) const
 {
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, streamName);
   std::string rngName = name()+streamName;
-  rngWrapper->setSeed( rngName, Gaudi::Hive::currentContext() );
-  return *rngWrapper;
+  rngWrapper->setSeed( rngName, ctx );
+  return rngWrapper->getEngine(ctx);
 }
 
-StatusCode MdtDigitizationTool::mergeEvent() {
+StatusCode MdtDigitizationTool::mergeEvent(const EventContext& ctx) {
 
   ATH_MSG_DEBUG ( "MdtDigitizationTool::in mergeEvent()" );
 
   // create and record the Digit container in StoreGate
-  SG::WriteHandle<MdtDigitContainer> digitContainer(m_outputObjectKey);
+  SG::WriteHandle<MdtDigitContainer> digitContainer(m_outputObjectKey, ctx);
   ATH_CHECK(digitContainer.record(std::make_unique<MdtDigitContainer>(m_idHelper->module_hash_max())));
   ATH_MSG_DEBUG("Recorded MdtDigitContainer called " << digitContainer.name() << " in store " << digitContainer.store());
 
   // create and record the SDO container in StoreGate
-  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDOKey);
+  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDOKey, ctx);
   ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
   ATH_MSG_DEBUG("Recorded MuonSimDataCollection called " << sdoContainer.name() << " in store " << sdoContainer.store());
 
-  StatusCode status = doDigitization(digitContainer.ptr(), sdoContainer.ptr());
+  StatusCode status = doDigitization(ctx, digitContainer.ptr(), sdoContainer.ptr());
   if (status.isFailure())  {
     ATH_MSG_ERROR ( "doDigitization Failed" );
   }
@@ -334,45 +334,45 @@ StatusCode MdtDigitizationTool::mergeEvent() {
 }
 
 
-StatusCode MdtDigitizationTool::processAllSubEvents() {
+StatusCode MdtDigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
   ATH_MSG_DEBUG ( "MdtDigitizationTool::processAllSubEvents()" );
 
   // create and record the Digit container in StoreGate
-  SG::WriteHandle<MdtDigitContainer> digitContainer(m_outputObjectKey);
+  SG::WriteHandle<MdtDigitContainer> digitContainer(m_outputObjectKey, ctx);
   ATH_CHECK(digitContainer.record(std::make_unique<MdtDigitContainer>(m_idHelper->module_hash_max())));
   ATH_MSG_DEBUG("Recorded MdtDigitContainer called " << digitContainer.name() << " in store " << digitContainer.store());
 
   // create and record the SDO container in StoreGate
-  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDOKey);
+  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDOKey, ctx);
   ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
   ATH_MSG_DEBUG("Recorded MuonSimDataCollection called " << sdoContainer.name() << " in store " << sdoContainer.store());
 
   StatusCode status = StatusCode::SUCCESS;
   if (0 == m_thpcMDT ) {
-    status = getNextEvent();
+    status = getNextEvent(ctx);
     if (StatusCode::FAILURE == status) {
       ATH_MSG_INFO ( "There are no MDT hits in this event" );
       return status;
     }
   }
 
-  ATH_CHECK(doDigitization(digitContainer.ptr(), sdoContainer.ptr()));
+  ATH_CHECK(doDigitization(ctx, digitContainer.ptr(), sdoContainer.ptr()));
 
   return status;
 }
 
 
-StatusCode MdtDigitizationTool::doDigitization(MdtDigitContainer* digitContainer, MuonSimDataCollection* sdoContainer) {
+StatusCode MdtDigitizationTool::doDigitization(const EventContext& ctx, MdtDigitContainer* digitContainer, MuonSimDataCollection* sdoContainer) {
   // Set the RNGs to use for this event.
-  CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("");
-  CLHEP::HepRandomEngine *twinRndmEngine = getRandomEngine("Twin");
-  CLHEP::HepRandomEngine *toolRndmEngine = getRandomEngine(m_digiTool->name());
+  CLHEP::HepRandomEngine *rndmEngine = getRandomEngine("", ctx);
+  CLHEP::HepRandomEngine *twinRndmEngine = getRandomEngine("Twin", ctx);
+  CLHEP::HepRandomEngine *toolRndmEngine = getRandomEngine(m_digiTool->name(), ctx);
 
 
   //Get the list of dead/missing chambers and cache it
   if ( m_UseDeadChamberSvc ) { 
-    SG::ReadCondHandle<MdtCondDbData> readHandle{m_readKey};
+    SG::ReadCondHandle<MdtCondDbData> readHandle{m_readKey, ctx};
     const MdtCondDbData* readCdo{*readHandle};
     m_IdentifiersToMask.clear();
     int size_id = readCdo->getDeadStationsId().size();
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_DigitizationTool.h b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_DigitizationTool.h
index 86e87dda4326f95106391c39f48f540d6cc476cf..424f0861670b78506d0a942e1e5debd8f9d30731 100644
--- a/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_DigitizationTool.h
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/MM_Digitization/MM_DigitizationTool.h
@@ -99,7 +99,7 @@ class MM_DigitizationTool : virtual public IMuonDigitizationTool, public PileUpT
 		virtual StatusCode initialize() override final;
 
 		/** When being run from PileUpToolsAlgs, this method is called at the start of the subevts loop. Not able to access SubEvents */
-		StatusCode prepareEvent(const unsigned int /*nInputEvents*/) override final;
+                StatusCode prepareEvent(const EventContext& ctx, const unsigned int /*nInputEvents*/) override final;
 
 		/** When being run from PileUpToolsAlgs, this method is called for each active bunch-crossing to process current SubEvents bunchXing is in ns */
 		StatusCode  processBunchXing(int bunchXing,
@@ -107,17 +107,17 @@ class MM_DigitizationTool : virtual public IMuonDigitizationTool, public PileUpT
 									SubEventIterator eSubEvents) override final;
 
 		/** When being run from PileUpToolsAlgs, this method is called at the end of the subevts loop. Not (necessarily) able to access SubEvents */
-		StatusCode mergeEvent() override final;
+		StatusCode mergeEvent(const EventContext& ctx) override final;
 
 		/** When being run from MM_Digitizer, this method is called during the event loop */
 
 		/** alternative interface which uses the PileUpMergeSvc to obtain
 		all the required SubEvents. */
-		virtual StatusCode processAllSubEvents() override;
+		virtual StatusCode processAllSubEvents(const EventContext& ctx) override;
 
 		/** Just calls processAllSubEvents - leaving for back-compatibility
 		(IMuonDigitizationTool) */
-		StatusCode digitize() override;
+		StatusCode digitize(const EventContext& ctx) override;
 
 		/** Finalize */
 		StatusCode finalize() override final;
@@ -132,7 +132,7 @@ class MM_DigitizationTool : virtual public IMuonDigitizationTool, public PileUpT
 
 		/** Record MmDigitContainer and MuonSimDataCollection */
 		StatusCode getNextEvent();
-		StatusCode doDigitization();
+		StatusCode doDigitization(const EventContext& ctx);
 
 		bool  checkMMSimHit(const MMSimHit& /* hit */ ) const;
 		MM_ElectronicsToolInput combinedStripResponseAllHits(const std::vector< MM_ElectronicsToolInput > & v_stripDigitOutput);
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_DigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_DigitizationTool.cxx
index 205b74ae1513129d40f2ec353778c715f1280f2e..ed25ec4b99d92cd3a38d98c20c055d92a3213e34 100644
--- a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_DigitizationTool.cxx
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_DigitizationTool.cxx
@@ -361,7 +361,7 @@ StatusCode MM_DigitizationTool::initialize() {
 //----------------------------------------------------------------------
 // PrepareEvent method:
 //----------------------------------------------------------------------
-StatusCode MM_DigitizationTool::prepareEvent(unsigned int nInputEvents) {
+StatusCode MM_DigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents) {
 
 	ATH_MSG_DEBUG("MM_DigitizationTool::prepareEvent() called for " << nInputEvents << " input events" );
 
@@ -469,11 +469,11 @@ StatusCode MM_DigitizationTool::getNextEvent() {
 
 }
 /*******************************************************************************/
-StatusCode MM_DigitizationTool::mergeEvent() {
+StatusCode MM_DigitizationTool::mergeEvent(const EventContext& ctx) {
 
 	ATH_MSG_VERBOSE ( "MM_DigitizationTool::in mergeEvent()" );
 
-	ATH_CHECK( doDigitization() );
+	ATH_CHECK( doDigitization(ctx) );
 
 	// reset the pointer (delete null pointer should be safe)
 	if (m_timedHitCollection_MM){
@@ -492,11 +492,11 @@ StatusCode MM_DigitizationTool::mergeEvent() {
 	return StatusCode::SUCCESS;
 }
 /*******************************************************************************/
-StatusCode MM_DigitizationTool::digitize() {
-	return this->processAllSubEvents();
+StatusCode MM_DigitizationTool::digitize(const EventContext& ctx) {
+	return this->processAllSubEvents(ctx);
 }
 /*******************************************************************************/
-StatusCode MM_DigitizationTool::processAllSubEvents() {
+StatusCode MM_DigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
 	ATH_MSG_DEBUG ("MM_DigitizationTool::processAllSubEvents()");
 
@@ -504,7 +504,7 @@ StatusCode MM_DigitizationTool::processAllSubEvents() {
 
 	if (m_timedHitCollection_MM == nullptr) ATH_CHECK( getNextEvent() );
 
-	ATH_CHECK( doDigitization() );
+	ATH_CHECK( doDigitization(ctx) );
 
 	// reset the pointer (delete null pointer should be safe)
 	if (m_timedHitCollection_MM){
@@ -531,15 +531,15 @@ StatusCode MM_DigitizationTool::finalize() {
 	return StatusCode::SUCCESS;
 }
 /*******************************************************************************/
-StatusCode MM_DigitizationTool::doDigitization() {
+StatusCode MM_DigitizationTool::doDigitization(const EventContext& ctx) {
 
   // create and record the Digit container in StoreGate
-  SG::WriteHandle<MmDigitContainer> digitContainer(m_outputDigitCollectionKey);
+  SG::WriteHandle<MmDigitContainer> digitContainer(m_outputDigitCollectionKey, ctx);
   ATH_CHECK(digitContainer.record(std::make_unique<MmDigitContainer>(m_idHelper->detectorElement_hash_max())));
   ATH_MSG_DEBUG ( "MmDigitContainer recorded in StoreGate." );
 
   // Create and record the SDO container in StoreGate
-  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey);
+  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey, ctx);
   ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
   ATH_MSG_DEBUG ( "MmSDOCollection recorded in StoreGate." );
 
diff --git a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Digitizer.cxx b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Digitizer.cxx
index b06b9679ab1adfd45193e63256843ed7b2d86194..5dd158d4b001ac4876d5f8484ab9f0884f2fb09f 100644
--- a/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Digitizer.cxx
+++ b/MuonSpectrometer/MuonDigitization/MM_Digitization/src/MM_Digitizer.cxx
@@ -28,7 +28,7 @@ StatusCode MM_Digitizer::initialize() {
 /*******************************************************************************/
 StatusCode MM_Digitizer::execute() {
   ATH_MSG_DEBUG ("MM_Digitizer::in execute()");
-  return m_digTool->digitize();
+  return m_digTool->digitize(Gaudi::Hive::currentContext());
 }
 /*******************************************************************************/
 StatusCode MM_Digitizer::finalize() {
diff --git a/MuonSpectrometer/MuonDigitization/MuonDigToolInterfaces/MuonDigToolInterfaces/IMuonDigitizationTool.h b/MuonSpectrometer/MuonDigitization/MuonDigToolInterfaces/MuonDigToolInterfaces/IMuonDigitizationTool.h
index 9748d713a621238d884b8f21ffad5d26f0266410..2a680c9eedb49e60eae76de1927dcb7426bbf98e 100644
--- a/MuonSpectrometer/MuonDigitization/MuonDigToolInterfaces/MuonDigToolInterfaces/IMuonDigitizationTool.h
+++ b/MuonSpectrometer/MuonDigitization/MuonDigToolInterfaces/MuonDigToolInterfaces/IMuonDigitizationTool.h
@@ -6,6 +6,7 @@
 #define IMUONDIGITIZATIONTOOL_H
 
 #include "GaudiKernel/IAlgTool.h" 
+#include "GaudiKernel/EventContext.h"
 #include "GaudiKernel/StatusCode.h"
 
 static const InterfaceID IID_IMuonDigitizationTool ("IMuonDigitizationTool",1,0);
@@ -19,7 +20,7 @@ class IMuonDigitizationTool : virtual public IAlgTool
 
      /**  @brief do the digitization
      */
-     virtual StatusCode digitize() = 0;
+     virtual StatusCode digitize(const EventContext& ctx) = 0;
 };
 
 inline const InterfaceID& IMuonDigitizationTool::interfaceID()
diff --git a/MuonSpectrometer/MuonDigitization/RPC_Digitization/RPC_Digitization/RpcDigitizationTool.h b/MuonSpectrometer/MuonDigitization/RPC_Digitization/RPC_Digitization/RpcDigitizationTool.h
index eaabb2e27cf153f34f451520aea9263fe17e4778..ef3348c714d7682b6423a2c37f61517ad9cb2119 100644
--- a/MuonSpectrometer/MuonDigitization/RPC_Digitization/RPC_Digitization/RpcDigitizationTool.h
+++ b/MuonSpectrometer/MuonDigitization/RPC_Digitization/RPC_Digitization/RpcDigitizationTool.h
@@ -84,7 +84,7 @@ public:
 
   /** When being run from PileUpToolsAlgs, this method is called at the start of
       the subevts loop. Not able to access SubEvents */
-  virtual StatusCode prepareEvent(const unsigned int /*nInputEvents*/) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, const unsigned int /*nInputEvents*/) override final;
 
   /** When being run from PileUpToolsAlgs, this method is called for each active
       bunch-crossing to process current SubEvents bunchXing is in ns */
@@ -98,18 +98,18 @@ public:
 
   /** When being run from PileUpToolsAlgs, this method is called at the end of
       the subevts loop. Not (necessarily) able to access SubEvents */
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
   /** alternative interface which uses the PileUpMergeSvc to obtain
       all the required SubEvents. */
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
 private:
 
   /** Get next event and extract collection of hit collections: */
-  StatusCode getNextEvent();
+  StatusCode getNextEvent(const EventContext& ctx);
   /** Digitization functionality shared with RPC_PileUpTool */
-  StatusCode doDigitization(RpcDigitContainer* digitContainer, MuonSimDataCollection* sdoContainer);
+  StatusCode doDigitization(const EventContext& ctx, RpcDigitContainer* digitContainer, MuonSimDataCollection* sdoContainer);
   /** */
   StatusCode fillTagInfo()    const;
   /** */
@@ -124,7 +124,7 @@ private:
   /** Cluster simulation: first step.
       The impact point of the particle across the strip is used
       to decide whether the cluster size should be 1 or 2 */
-  std::vector<int> PhysicalClusterSize(const Identifier* id, const RPCSimHit* theHit, CLHEP::HepRandomEngine* rndmEngine);
+  std::vector<int> PhysicalClusterSize(const EventContext& ctx, const Identifier* id, const RPCSimHit* theHit, CLHEP::HepRandomEngine* rndmEngine);
   /** Cluster simulation: second step.
       Additional strips are turned on in order to reproduce the
       observed cluster size distribution */
@@ -157,12 +157,12 @@ private:
   /** Average calibration methods and parameters */
   StatusCode  PrintCalibrationVector();
   /** Evaluate detection efficiency */
-  StatusCode DetectionEfficiency(const Identifier* ideta, const Identifier* idphi, bool& undefinedPhiStripStatus, CLHEP::HepRandomEngine* rndmEngine, const RPCSimHit& thehit);
+  StatusCode DetectionEfficiency(const EventContext& ctx, const Identifier* ideta, const Identifier* idphi, bool& undefinedPhiStripStatus, CLHEP::HepRandomEngine* rndmEngine, const RPCSimHit& thehit);
   double FCPEfficiency(const HepMC::GenParticle* genParticle);
   /** */
-  int ClusterSizeEvaluation(const Identifier* id, float xstripnorm, CLHEP::HepRandomEngine* rndmEngine);
+  int ClusterSizeEvaluation(const EventContext& ctx, const Identifier* id, float xstripnorm, CLHEP::HepRandomEngine* rndmEngine);
   /** CoolDB */
-  StatusCode DumpRPCCalibFromCoolDB();
+  StatusCode DumpRPCCalibFromCoolDB(const EventContext& ctx);
 
   const MuonGM::MuonDetectorManager*  m_GMmgr{};
   const RpcIdHelper*          m_idHelper{};
diff --git a/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RPC_Digitizer.cxx b/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RPC_Digitizer.cxx
index af17d922a16ca7c0029d1b3fdc99b079b67ad05f..60a8b1b941a757d04868c9aa62605726e979af24 100644
--- a/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RPC_Digitizer.cxx
+++ b/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RPC_Digitizer.cxx
@@ -21,5 +21,5 @@ StatusCode RPC_Digitizer::initialize() {
 
 StatusCode RPC_Digitizer::execute() {
   ATH_MSG_DEBUG("in execute()");
-  return m_digTool->processAllSubEvents();
+  return m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RpcDigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RpcDigitizationTool.cxx
index 80c702c685d7a8e6e7316a23124c8d61c4b9fe49..3638e89d1289a0cafef95fc0463b2df84e15080c 100644
--- a/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RpcDigitizationTool.cxx
+++ b/MuonSpectrometer/MuonDigitization/RPC_Digitization/src/RpcDigitizationTool.cxx
@@ -278,7 +278,7 @@ StatusCode RpcDigitizationTool::initialize() {
 }
 
 //--------------------------------------------
-StatusCode RpcDigitizationTool::prepareEvent(unsigned int) {
+StatusCode RpcDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int) {
 
   ATH_MSG_DEBUG ( "RpcDigitizationTool::in prepareEvent()" );
 
@@ -336,7 +336,7 @@ StatusCode RpcDigitizationTool::processBunchXing(int bunchXing,
 
 //--------------------------------------------
 // Get next event and extract collection of hit collections:
-StatusCode RpcDigitizationTool::getNextEvent()
+StatusCode RpcDigitizationTool::getNextEvent(const EventContext& ctx)
 {
 
   ATH_MSG_DEBUG ( "RpcDigitizationTool::getNextEvent()" );
@@ -349,7 +349,7 @@ StatusCode RpcDigitizationTool::getNextEvent()
 
   // In case of single hits container just load the collection using read handles
   if (!m_onlyUseContainerName) {
-    SG::ReadHandle<RPCSimHitCollection> hitCollection(m_hitsContainerKey);
+      SG::ReadHandle<RPCSimHitCollection> hitCollection(m_hitsContainerKey, ctx);
     if (!hitCollection.isValid()) {
       ATH_MSG_ERROR("Could not get RPCSimHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
       return StatusCode::FAILURE;
@@ -394,25 +394,25 @@ StatusCode RpcDigitizationTool::getNextEvent()
 }
 
 //--------------------------------------------
-StatusCode RpcDigitizationTool::mergeEvent() {
+StatusCode RpcDigitizationTool::mergeEvent(const EventContext& ctx) {
 
   StatusCode status = StatusCode::SUCCESS;
 
   ATH_MSG_DEBUG ( "RpcDigitizationTool::in mergeEvent()" );
 
   if(m_DumpFromDbFirst && m_RPCInfoFromDb){
-    status = DumpRPCCalibFromCoolDB() ;
+    status = DumpRPCCalibFromCoolDB(ctx) ;
     if (status == StatusCode::FAILURE) return status ;
     m_DumpFromDbFirst = false ;
   }
 
   // create and record the Digit container in StoreGate
-  SG::WriteHandle<RpcDigitContainer> digitContainer(m_outputDigitCollectionKey);
+  SG::WriteHandle<RpcDigitContainer> digitContainer(m_outputDigitCollectionKey, ctx);
   ATH_CHECK(digitContainer.record(std::make_unique<RpcDigitContainer>(m_idHelper->module_hash_max())));
   ATH_MSG_DEBUG ( "RpcDigitContainer recorded in StoreGate." );
 
   // Create and record the SDO container in StoreGate
-  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey);
+  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey, ctx);
   ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
   ATH_MSG_DEBUG ( "RpcSDOCollection recorded in StoreGate." );
 
@@ -420,7 +420,7 @@ StatusCode RpcDigitizationTool::mergeEvent() {
   m_sdo_tmp_map.clear();
   /////////////////////////
 
-  status = doDigitization(digitContainer.ptr(), sdoContainer.ptr());
+  status = doDigitization(ctx, digitContainer.ptr(), sdoContainer.ptr());
   if (status.isFailure())  {
     ATH_MSG_ERROR ( "doDigitization Failed" );
   }
@@ -439,7 +439,7 @@ StatusCode RpcDigitizationTool::mergeEvent() {
 }
 
 //--------------------------------------------
-StatusCode RpcDigitizationTool::processAllSubEvents() {
+StatusCode RpcDigitizationTool::processAllSubEvents(const EventContext& ctx) {
 
   StatusCode status = StatusCode::SUCCESS;
 
@@ -448,18 +448,18 @@ StatusCode RpcDigitizationTool::processAllSubEvents() {
   ATH_MSG_DEBUG ( "RpcDigitizationTool::in digitize()" );
 
   if(m_DumpFromDbFirst && m_RPCInfoFromDb){
-    status = DumpRPCCalibFromCoolDB() ;
+    status = DumpRPCCalibFromCoolDB(ctx) ;
     if (status == StatusCode::FAILURE) return status ;
     m_DumpFromDbFirst = false ;
   }
 
   // create and record the Digit container in StoreGate
-  SG::WriteHandle<RpcDigitContainer> digitContainer(m_outputDigitCollectionKey);
+  SG::WriteHandle<RpcDigitContainer> digitContainer(m_outputDigitCollectionKey, ctx);
   ATH_CHECK(digitContainer.record(std::make_unique<RpcDigitContainer>(m_idHelper->module_hash_max())));
   ATH_MSG_DEBUG ( "RpcDigitContainer recorded in StoreGate." );
 
   // Create and record the SDO container in StoreGate
-  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey);
+  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey, ctx);
   ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
   ATH_MSG_DEBUG ( "RpcSDOCollection recorded in StoreGate." );
 
@@ -468,24 +468,24 @@ StatusCode RpcDigitizationTool::processAllSubEvents() {
   /////////////////////////
 
   if (0 == m_thpcRPC ) {
-    status = getNextEvent();
+    status = getNextEvent(ctx);
     if (StatusCode::FAILURE == status) {
       ATH_MSG_INFO ( "There are no RPC hits in this event" );
       return status; // there are no hits in this event
     }
   }
 
-  ATH_CHECK(doDigitization(digitContainer.ptr(), sdoContainer.ptr()));
+  ATH_CHECK(doDigitization(ctx, digitContainer.ptr(), sdoContainer.ptr()));
 
   return status;
 }
 
 //--------------------------------------------
-StatusCode RpcDigitizationTool::doDigitization(RpcDigitContainer* digitContainer, MuonSimDataCollection* sdoContainer) {
+StatusCode RpcDigitizationTool::doDigitization(const EventContext& ctx, RpcDigitContainer* digitContainer, MuonSimDataCollection* sdoContainer) {
 
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
-  CLHEP::HepRandomEngine *rndmEngine = *rngWrapper;
+  rngWrapper->setSeed( name(), ctx );
+  CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
 
   //StatusCode status = StatusCode::SUCCESS;
   //status.ignore();
@@ -592,9 +592,9 @@ StatusCode RpcDigitizationTool::doDigitization(RpcDigitContainer* digitContainer
       // measured panel eff. will be used in that case and no phi strip killing will happen
       bool undefPhiStripStat = false;
 
-      std::vector<int> pcseta    = PhysicalClusterSize(&idpaneleta, &hit, rndmEngine); //set to one for new algorithms
+      std::vector<int> pcseta    = PhysicalClusterSize(ctx, &idpaneleta, &hit, rndmEngine); //set to one for new algorithms
       ATH_MSG_DEBUG ( "Simulated cluster on eta panel: size/first/last= "<<pcseta[0]   <<"/"<<pcseta[1]   <<"/"<<pcseta[2] );
-      std::vector<int> pcsphi = PhysicalClusterSize(&idpanelphi, &hit, rndmEngine); //set to one for new algorithms
+      std::vector<int> pcsphi = PhysicalClusterSize(ctx, &idpanelphi, &hit, rndmEngine); //set to one for new algorithms
       ATH_MSG_DEBUG ( "Simulated cluster on phi panel: size/first/last= "<<pcsphi[0]<<"/"<<pcsphi[1]<<"/"<<pcsphi[2] );
 
       // create Identifiers
@@ -605,7 +605,7 @@ StatusCode RpcDigitizationTool::doDigitization(RpcDigitContainer* digitContainer
 
       const RpcReadoutElement* ele= m_GMmgr->getRpcReadoutElement(atlasRpcIdeta);// first add time jitter to the time:
 
-      if (DetectionEfficiency(&atlasRpcIdeta,&atlasRpcIdphi, undefPhiStripStat, rndmEngine, hit).isFailure()) return StatusCode::FAILURE ;
+      if (DetectionEfficiency(ctx, &atlasRpcIdeta,&atlasRpcIdphi, undefPhiStripStat, rndmEngine, hit).isFailure()) return StatusCode::FAILURE ;
       ATH_MSG_DEBUG ( "SetPhiOn " << m_SetPhiOn << " SetEtaOn " <<  m_SetEtaOn );
 
       for( int imeasphi=0 ;  imeasphi!=2;  ++imeasphi){
@@ -700,8 +700,8 @@ StatusCode RpcDigitizationTool::doDigitization(RpcDigitContainer* digitContainer
 									 stationPhi,doubletR), doubletZ, doubletPhi,gasGap, imeasphi, clus);
 	  // here count and maybe kill dead strips if using COOL input for the detector status 
 	  if (m_Efficiency_fromCOOL) {
-        SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey};
-        const RpcCondDbData* readCdo{*readHandle};
+            SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey, ctx};
+            const RpcCondDbData* readCdo{*readHandle};
 	    if ( !(undefPhiStripStat && imeasphi==1) )
 	      {
 		if(readCdo->getDeadStripIntMap().find( newId )  != readCdo->getDeadStripIntMap().end()) 
@@ -926,7 +926,7 @@ StatusCode RpcDigitizationTool::doDigitization(RpcDigitContainer* digitContainer
 }
 
 //--------------------------------------------
-std::vector<int> RpcDigitizationTool::PhysicalClusterSize(const Identifier* id, const RPCSimHit* theHit, CLHEP::HepRandomEngine* rndmEngine)
+std::vector<int> RpcDigitizationTool::PhysicalClusterSize(const EventContext& ctx, const Identifier* id, const RPCSimHit* theHit, CLHEP::HepRandomEngine* rndmEngine)
 {
 
   // ME unused: int stationName = m_idHelper->stationName(*id);
@@ -1089,7 +1089,7 @@ std::vector<int> RpcDigitizationTool::PhysicalClusterSize(const Identifier* id,
   else{
 
     float xstripnorm=xstrip/30.;
-    result[0] = ClusterSizeEvaluation(id, xstripnorm, rndmEngine );
+    result[0] = ClusterSizeEvaluation(ctx, id, xstripnorm, rndmEngine );
 
     int nstrips = ele->Nstrips(measuresPhi);
     //
@@ -1690,7 +1690,7 @@ StatusCode RpcDigitizationTool::readParameters(){
 }
 
 //--------------------------------------------
-StatusCode RpcDigitizationTool::DetectionEfficiency(const Identifier* IdEtaRpcStrip, const Identifier* IdPhiRpcStrip, bool& undefinedPhiStripStatus, CLHEP::HepRandomEngine* rndmEngine, const RPCSimHit& thehit) {
+StatusCode RpcDigitizationTool::DetectionEfficiency(const EventContext& ctx, const Identifier* IdEtaRpcStrip, const Identifier* IdPhiRpcStrip, bool& undefinedPhiStripStatus, CLHEP::HepRandomEngine* rndmEngine, const RPCSimHit& thehit) {
 
   ATH_MSG_DEBUG ( "RpcDigitizationTool::in DetectionEfficiency" );
 
@@ -1763,7 +1763,7 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const Identifier* IdEtaRpcSt
   }
   else{
 
-    SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey};
+    SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey, ctx};
     const RpcCondDbData* readCdo{*readHandle};
 
     ATH_MSG_DEBUG("Efficiencies and cluster size + dead strips will be extracted from COOL");
@@ -2100,7 +2100,7 @@ StatusCode RpcDigitizationTool::DetectionEfficiency(const Identifier* IdEtaRpcSt
 }
 
 //--------------------------------------------
-int RpcDigitizationTool::ClusterSizeEvaluation(const Identifier* IdRpcStrip, float xstripnorm, CLHEP::HepRandomEngine* rndmEngine) {
+int RpcDigitizationTool::ClusterSizeEvaluation(const EventContext& ctx, const Identifier* IdRpcStrip, float xstripnorm, CLHEP::HepRandomEngine* rndmEngine) {
 
   ATH_MSG_DEBUG ( "RpcDigitizationTool::in ClusterSizeEvaluation" );
 
@@ -2157,7 +2157,7 @@ int RpcDigitizationTool::ClusterSizeEvaluation(const Identifier* IdRpcStrip, flo
     }
   }
   else{
-    SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey};
+    SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey, ctx};
     const RpcCondDbData* readCdo{*readHandle};
 
     Identifier Id  = m_idHelper->panelID(*IdRpcStrip);
@@ -2342,11 +2342,11 @@ StatusCode RpcDigitizationTool::PrintCalibrationVector() {
 }
 
 //--------------------------------------------
-StatusCode RpcDigitizationTool::DumpRPCCalibFromCoolDB() {
+StatusCode RpcDigitizationTool::DumpRPCCalibFromCoolDB(const EventContext& ctx) {
 
   ATH_MSG_DEBUG ( "RpcDigitizationTool::in DumpRPCCalibFromCoolDB" );
 
-  SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey};
+  SG::ReadCondHandle<RpcCondDbData> readHandle{m_readKey, ctx};
   const RpcCondDbData* readCdo{*readHandle};
 
   StatusCode sc = StatusCode::SUCCESS;
diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TGCDigitizer.cxx b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TGCDigitizer.cxx
index 26cd90d476aaac157ad5bbb9a2b5c0b387d46b4e..7239f346ee54361d3c19948c208235971b06d70a 100644
--- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TGCDigitizer.cxx
+++ b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TGCDigitizer.cxx
@@ -21,5 +21,5 @@ StatusCode TGCDigitizer::initialize() {
 
 StatusCode TGCDigitizer::execute() {
   ATH_MSG_DEBUG("in execute()");
-  return m_digTool->processAllSubEvents();
+  return m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.cxx
index a476cdbdc6dce4898e66da56094892d10af2cf3d..3dacd198f7ada4aef58bfea230adcbfc04a485c0 100644
--- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.cxx
+++ b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.cxx
@@ -111,7 +111,7 @@ StatusCode TgcDigitizationTool::initialize()
 }
 
 //--------------------------------------------
-StatusCode TgcDigitizationTool::prepareEvent(unsigned int)
+StatusCode TgcDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int)
 {
   m_TGCHitCollList.clear();
   m_thpcTGC = new TimedHitCollection<TGCSimHit>();
@@ -162,10 +162,10 @@ StatusCode TgcDigitizationTool::processBunchXing(int bunchXing,
 }
 
 //--------------------------------------------
-StatusCode TgcDigitizationTool::mergeEvent() {
+StatusCode TgcDigitizationTool::mergeEvent(const EventContext& ctx) {
   ATH_MSG_DEBUG("TgcDigitizationTool::mergeEvent()");
 
-  ATH_CHECK(digitizeCore());
+  ATH_CHECK(digitizeCore(ctx));
   // reset the pointer (delete null pointer should be safe)
   delete m_thpcTGC;
   m_thpcTGC = 0;
@@ -182,13 +182,13 @@ StatusCode TgcDigitizationTool::mergeEvent() {
 }
 
 //_____________________________________________________________________________
-StatusCode TgcDigitizationTool::processAllSubEvents() {
+StatusCode TgcDigitizationTool::processAllSubEvents(const EventContext& ctx) {
   ATH_MSG_DEBUG("TgcDigitizationTool::processAllSubEvents()");
   //merging of the hit collection in getNextEvent method
   if(!m_thpcTGC) {
-    ATH_CHECK(getNextEvent());
+    ATH_CHECK(getNextEvent(ctx));
   }
-  ATH_CHECK(digitizeCore());
+  ATH_CHECK(digitizeCore(ctx));
   // reset the pointer (delete null pointer should be safe)
   delete m_thpcTGC;
   m_thpcTGC = 0;
@@ -207,7 +207,7 @@ StatusCode TgcDigitizationTool::finalize() {
 
 //_____________________________________________________________________________
 // Get next event and extract collection of hit collections:
-StatusCode TgcDigitizationTool::getNextEvent()
+StatusCode TgcDigitizationTool::getNextEvent(const EventContext& ctx)
 {
   // initialize pointer
   m_thpcTGC = nullptr;
@@ -217,7 +217,7 @@ StatusCode TgcDigitizationTool::getNextEvent()
   
   // In case of single hits container just load the collection using read handles
   if (!m_onlyUseContainerName) {
-    SG::ReadHandle<TGCSimHitCollection> hitCollection(m_hitsContainerKey);
+    SG::ReadHandle<TGCSimHitCollection> hitCollection(m_hitsContainerKey, ctx);
     if (!hitCollection.isValid()) {
       ATH_MSG_ERROR("Could not get TGCSimHitCollection container " << hitCollection.name() << " from store " << hitCollection.store());
       return StatusCode::FAILURE;
@@ -263,19 +263,19 @@ StatusCode TgcDigitizationTool::getNextEvent()
   return StatusCode::SUCCESS;
 }
 
-StatusCode TgcDigitizationTool::digitizeCore() const {
+StatusCode TgcDigitizationTool::digitizeCore(const EventContext& ctx) const {
 
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
-  CLHEP::HepRandomEngine *rndmEngine = *rngWrapper;
+  rngWrapper->setSeed( name(), ctx );
+  CLHEP::HepRandomEngine *rndmEngine = rngWrapper->getEngine(ctx);
 
   // create and record the Digit container in StoreGate
-  SG::WriteHandle<TgcDigitContainer> digitContainer(m_outputDigitCollectionKey);
+  SG::WriteHandle<TgcDigitContainer> digitContainer(m_outputDigitCollectionKey, ctx);
   ATH_CHECK(digitContainer.record(std::make_unique<TgcDigitContainer>(m_idHelper->module_hash_max())));
   ATH_MSG_DEBUG ( "TgcDigitContainer recorded in StoreGate." );
 
   // Create and record the SDO container in StoreGate
-  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey);
+  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey, ctx);
   ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
   ATH_MSG_DEBUG ( "TgcSDOCollection recorded in StoreGate." );
 
diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.h b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.h
index bcb610382ac48cf3a9228a3124a59fe569784772..e6bcba20f43106a78a5e303c021d0160d541199d 100644
--- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.h
+++ b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.h
@@ -42,9 +42,9 @@ public:
                       const std::string& name,
                       const IInterface* parent);
   /** Initialize */
-    virtual StatusCode initialize() override final;
+  virtual StatusCode initialize() override final;
 
-  virtual StatusCode prepareEvent(unsigned int /*nInputEvents*/) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int /*nInputEvents*/) override final;
 
   /** called for each active bunch-crossing to process current SubEvents
       bunchXing is in ns */
@@ -56,7 +56,7 @@ public:
 
   /** called at the end of the subevts loop. Not (necessarily) able to access
       SubEvents (IPileUpTool) */
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
 
   /** alternative interface which uses the PileUpMergeSvc to obtain
   all the required SubEvents.  Reads GEANT4 hits from StoreGate in
@@ -65,16 +65,16 @@ public:
   double has two. This method calls TgcDigitMaker::executeDigi, which
   digitizes every hit, for every readout element, i.e., a sensitive
   volume of a chamber. */
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
   /** Finalize */
   virtual StatusCode finalize() override final;
 
 private:
   /** Get next event and extract collection of hit collections */
-  StatusCode getNextEvent();
+  StatusCode getNextEvent(const EventContext& ctx);
   /** Core part of digitization used by processAllSubEvents and mergeEvent */
-  StatusCode digitizeCore() const;
+  StatusCode digitizeCore(const EventContext& ctx) const;
 
 protected:
   ServiceHandle<PileUpMergeSvc> m_mergeSvc{this, "PileUpMergeSvc", "PileUpMergeSvc", ""}; // Pile up service
diff --git a/MuonSpectrometer/MuonDigitization/sTGC_Digitization/sTGC_Digitization/sTgcDigitizationTool.h b/MuonSpectrometer/MuonDigitization/sTGC_Digitization/sTGC_Digitization/sTgcDigitizationTool.h
index 4cb088d883ca5f1e426cfdd2027cf4bbc5258366..4e201dc0bc1693acd8aea92eff919266ef973b7e 100644
--- a/MuonSpectrometer/MuonDigitization/sTGC_Digitization/sTGC_Digitization/sTgcDigitizationTool.h
+++ b/MuonSpectrometer/MuonDigitization/sTGC_Digitization/sTGC_Digitization/sTgcDigitizationTool.h
@@ -70,7 +70,7 @@ public:
 
   // /** When being run from PileUpToolsAlgs, this method is called at the start of
   //       the subevts loop. Not able to access SubEvents */
-  StatusCode prepareEvent(const unsigned int /*nInputEvents*/);
+  StatusCode prepareEvent(const EventContext& ctx, const unsigned int /*nInputEvents*/);
   //
   //   /** When being run from PileUpToolsAlgs, this method is called for each active
   //       bunch-crossing to process current SubEvents bunchXing is in ns */
@@ -80,10 +80,10 @@ public:
 
   //   /** When being run from PileUpToolsAlgs, this method is called at the end of
   //       the subevts loop. Not (necessarily) able to access SubEvents */
-  StatusCode mergeEvent();
+  StatusCode mergeEvent(const EventContext& ctx);
   /** alternative interface which uses the PileUpMergeSvc to obtain
       all the required SubEvents. */
-  virtual StatusCode processAllSubEvents();
+  virtual StatusCode processAllSubEvents(const EventContext& ctx);
 
   /** Just calls processAllSubEvents - leaving for back-compatibility
       (IMuonDigitizationTool) */
@@ -97,7 +97,7 @@ public:
      every readout element, i.e., a sensitive volume of a
      chamber. (IMuonDigitizationTool)
   */
-  StatusCode digitize();
+  StatusCode digitize(const EventContext& ctx);
 
   /** Finalize */
   StatusCode finalize();
@@ -112,7 +112,7 @@ private:
   /** Record sTgcDigitContainer and MuonSimDataCollection */
   StatusCode recordDigitAndSdoContainers();
   /** Core part of digitization use by mergeEvent (IPileUpTool) and digitize (IMuonDigitizationTool) */
-  StatusCode doDigitization();
+  StatusCode doDigitization(const EventContext& ctx);
 
 protected:
   PileUpMergeSvc *m_mergeSvc; // Pile up service
diff --git a/MuonSpectrometer/MuonDigitization/sTGC_Digitization/src/sTGC_Digitizer.cxx b/MuonSpectrometer/MuonDigitization/sTGC_Digitization/src/sTGC_Digitizer.cxx
index f735623e477bfff003ff52021cf2f684d9ce9fd6..27b924cfddf9d462160d0dd8fe783f66bb0ec8dc 100644
--- a/MuonSpectrometer/MuonDigitization/sTGC_Digitization/src/sTGC_Digitizer.cxx
+++ b/MuonSpectrometer/MuonDigitization/sTGC_Digitization/src/sTGC_Digitizer.cxx
@@ -28,7 +28,7 @@ StatusCode sTGC_Digitizer::initialize() {
 /*******************************************************************************/
 StatusCode sTGC_Digitizer::execute() {   
   ATH_MSG_DEBUG ("sTGC_Digitizer::in execute()"); 
-  return m_digTool->digitize();
+  return m_digTool->digitize(Gaudi::Hive::currentContext());
 }
 /*******************************************************************************/
 StatusCode sTGC_Digitizer::finalize() { 
diff --git a/MuonSpectrometer/MuonDigitization/sTGC_Digitization/src/sTgcDigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/sTGC_Digitization/src/sTgcDigitizationTool.cxx
index 23e1d5fdc18d689a2e513b05841ed56a555ab5c8..10365959560d0a8a81c95f07890cdc5d00460880 100644
--- a/MuonSpectrometer/MuonDigitization/sTGC_Digitization/src/sTgcDigitizationTool.cxx
+++ b/MuonSpectrometer/MuonDigitization/sTGC_Digitization/src/sTgcDigitizationTool.cxx
@@ -222,7 +222,7 @@ StatusCode sTgcDigitizationTool::initialize() {
   return status;
 }
 /*******************************************************************************/ 
-StatusCode sTgcDigitizationTool::prepareEvent(unsigned int nInputEvents) {
+StatusCode sTgcDigitizationTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents) {
 
   ATH_MSG_DEBUG("sTgcDigitizationTool::prepareEvent() called for " << nInputEvents << " input events" );
   m_STGCHitCollList.clear();
@@ -327,13 +327,13 @@ StatusCode sTgcDigitizationTool::getNextEvent() {
   return StatusCode::SUCCESS;
 }
 /*******************************************************************************/
-StatusCode sTgcDigitizationTool::mergeEvent() {
+StatusCode sTgcDigitizationTool::mergeEvent(const EventContext& ctx) {
 
   StatusCode status = StatusCode::SUCCESS;
 
   ATH_MSG_DEBUG ( "sTgcDigitizationTool::in mergeEvent()" );
 
-  status = doDigitization();
+  status = doDigitization(ctx);
   if (status.isFailure())  {
     ATH_MSG_ERROR ( "doDigitization Failed" );
   }
@@ -354,11 +354,11 @@ StatusCode sTgcDigitizationTool::mergeEvent() {
   return status;
 }
 /*******************************************************************************/
-StatusCode sTgcDigitizationTool::digitize() {
-  return this->processAllSubEvents(); 
+StatusCode sTgcDigitizationTool::digitize(const EventContext& ctx) {
+  return this->processAllSubEvents(ctx); 
 } 
 /*******************************************************************************/
-StatusCode sTgcDigitizationTool::processAllSubEvents() {
+StatusCode sTgcDigitizationTool::processAllSubEvents(const EventContext& ctx) {
   StatusCode status = StatusCode::SUCCESS;
   ATH_MSG_DEBUG (" sTgcDigitizationTool::processAllSubEvents()" );
 
@@ -370,7 +370,7 @@ StatusCode sTgcDigitizationTool::processAllSubEvents() {
       return status;
     }
   }
-  status = doDigitization();
+  status = doDigitization(ctx);
   if (status.isFailure())  {
     ATH_MSG_ERROR ( "doDigitization() Failed" );
   }   
@@ -390,17 +390,17 @@ StatusCode sTgcDigitizationTool::finalize() {
   return StatusCode::SUCCESS;
 }
 /*******************************************************************************/
-StatusCode sTgcDigitizationTool::doDigitization() {
+StatusCode sTgcDigitizationTool::doDigitization(const EventContext& ctx) {
   
   ATH_MSG_DEBUG ("sTgcDigitizationTool::doDigitization()" );
 
   // create and record the Digit container in StoreGate
-  SG::WriteHandle<sTgcDigitContainer> digitContainer(m_outputDigitCollectionKey);
+  SG::WriteHandle<sTgcDigitContainer> digitContainer(m_outputDigitCollectionKey, ctx);
   ATH_CHECK(digitContainer.record(std::make_unique<sTgcDigitContainer>(m_idHelper->detectorElement_hash_max())));
   ATH_MSG_DEBUG ( "sTgcDigitContainer recorded in StoreGate." );
 
   // Create and record the SDO container in StoreGate
-  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey);
+  SG::WriteHandle<MuonSimDataCollection> sdoContainer(m_outputSDO_CollectionKey, ctx);
   ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
   ATH_MSG_DEBUG ( "sTgcSDOCollection recorded in StoreGate." );
     
diff --git a/Projects/AthSimulation/package_filters.txt b/Projects/AthSimulation/package_filters.txt
index d03fde2fd87387d75089b4acc20b6f58ccc0d57b..48b8bcc63b66d4a0d0f0f83fb21d521687aa8b07 100644
--- a/Projects/AthSimulation/package_filters.txt
+++ b/Projects/AthSimulation/package_filters.txt
@@ -237,6 +237,8 @@
 + MagneticField/MagFieldInterfaces
 + MagneticField/MagFieldServices
 + MagneticField/MagFieldUtils
++ MagneticField/MagFieldConditions
++ MagneticField/MagFieldElements
 + MuonSpectrometer/MuonAlignment/MuonAlignmentData
 + MuonSpectrometer/MuonCnv/MuonIdCnv
 + MuonSpectrometer/MuonCnv/MuonSimEventAthenaPool
diff --git a/Reconstruction/RecoTools/TrackToCalo/CMakeLists.txt b/Reconstruction/RecoTools/TrackToCalo/CMakeLists.txt
index 700f25f68d359f20cefb3101a25880beb06fab05..fe374b6bc281616e8fe7142bf80357958c6b2d8b 100644
--- a/Reconstruction/RecoTools/TrackToCalo/CMakeLists.txt
+++ b/Reconstruction/RecoTools/TrackToCalo/CMakeLists.txt
@@ -19,6 +19,7 @@ atlas_depends_on_subdirs( PUBLIC
                           Reconstruction/RecoTools/ITrackToVertex
                           Tracking/TrkEvent/TrkCaloExtension
                           Tracking/TrkEvent/TrkParametersIdentificationHelpers
+			  Tracking/TrkExtrapolation/TrkExUtils
 			  InnerDetector/InDetDetDescr/InDetReadoutGeometry
                           InnerDetector/InDetDetDescr/TRT_ReadoutGeometry
 			  PRIVATE
@@ -43,7 +44,7 @@ atlas_depends_on_subdirs( PUBLIC
                           Tracking/TrkEvent/TrkTrack
                           Tracking/TrkEvent/VxVertex
                           Tracking/TrkExtrapolation/TrkExInterfaces
-                          Tracking/TrkTools/TrkToolInterfaces 
+                          Tracking/TrkTools/TrkToolInterfaces
 			  Control/CxxUtils )
 
 # External dependencies:
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHits.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHits.cxx
index fa2ad7e3ce18717edf916d46c080ca02114a3beb..60e54abe5ee5219c269f846a07223a25e6176c86 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHits.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHits.cxx
@@ -21,5 +21,5 @@ StatusCode MergeCalibHits::initialize() {
 
 StatusCode MergeCalibHits::execute() {
   ATH_MSG_DEBUG("execute()");
-  return m_mergeTool->processAllSubEvents();
+  return m_mergeTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHitsTool.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHitsTool.cxx
index 02183448c469058e1178e10e06b839a0192d7955..34e7f1a067f462e26f2f8097832b1aa2dc6204de 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHitsTool.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHitsTool.cxx
@@ -42,7 +42,7 @@ StatusCode MergeCalibHitsTool::initialize() {
 }
 
 
-StatusCode MergeCalibHitsTool::prepareEvent(unsigned int nInputEvents) {
+StatusCode MergeCalibHitsTool::prepareEvent(const EventContext& /*ctx*/,unsigned int nInputEvents) {
   ATH_MSG_VERBOSE ( "Calling prepareEvent(): " << name() << " - package version " << PACKAGE_VERSION );
   ATH_MSG_VERBOSE( "prepareEvent: there are " << nInputEvents << " subevents in this event.");
   m_firstSubEvent = true;
@@ -110,7 +110,7 @@ StatusCode MergeCalibHitsTool::processBunchXing(int bunchXing,
 
   return StatusCode::SUCCESS;
 }
-StatusCode MergeCalibHitsTool::mergeEvent() {
+StatusCode MergeCalibHitsTool::mergeEvent(const EventContext& /*ctx*/) {
   for (unsigned int iHitContainer=0;iHitContainer<m_CalibrationHitContainer.size();++iHitContainer) {
     if ( m_outputContainers[iHitContainer]==0 ) { continue; } //don't bother recording unused containers!
     if (!(evtStore()->record(m_outputContainers[iHitContainer],m_CalibrationHitContainer[iHitContainer]).isSuccess())) {
@@ -121,7 +121,7 @@ StatusCode MergeCalibHitsTool::mergeEvent() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeCalibHitsTool::processAllSubEvents() {
+StatusCode MergeCalibHitsTool::processAllSubEvents(const EventContext& /*ctx*/) {
   ATH_MSG_VERBOSE ( "processAllSubEvents()" );
 
   // loop over containers
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHitsTool.h b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHitsTool.h
index 01b28e8c52bea0193bf3935ae2da456cb32116ff..c0798e3fa3e1636d3e9c188e2334174abf621f47 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHitsTool.h
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeCalibHitsTool.h
@@ -31,10 +31,10 @@ public:
   virtual StatusCode initialize() override final;
   ///called before the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode processBunchXing(int bunchXing,
@@ -47,7 +47,7 @@ public:
   /**  @brief Propagate the Calib Hit Containers to the output
        StoreGate
   */
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
 private:
   Gaudi::Property<bool> m_oldFormat{this, "OldFormat", false, ""};
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitColl.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitColl.cxx
index b2fce6ab5df2c855de156c856010cc4c59241d10..53c95d4e33024461c2e760c4544e274e84a079cb 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitColl.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitColl.cxx
@@ -22,5 +22,5 @@ StatusCode MergeGenericMuonSimHitColl::initialize() {
 
 StatusCode MergeGenericMuonSimHitColl::execute() {
   ATH_MSG_DEBUG("execute()");
-  return m_mergeTool->processAllSubEvents();
+  return m_mergeTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitCollTool.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitCollTool.cxx
index 5d5f68225a1d267460be474eb4485111ed46cf27..8f9a530b2ee2fb7d9fe54390dc27a4f5fd318a30 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitCollTool.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitCollTool.cxx
@@ -31,7 +31,7 @@ StatusCode MergeGenericMuonSimHitCollTool::initialize() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeGenericMuonSimHitCollTool::prepareEvent(unsigned int nInputEvents) {
+StatusCode MergeGenericMuonSimHitCollTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents) {
   ATH_MSG_DEBUG ( "Calling prepareEvent(): " << name() << " - package version " << PACKAGE_VERSION );
   ATH_MSG_DEBUG( "prepareEvent: there are " << nInputEvents << " subevents in this event.");
   m_firstSubEvent = true;
@@ -74,7 +74,7 @@ StatusCode MergeGenericMuonSimHitCollTool::processBunchXing(int bunchXing,
   return sc;
 }
 
-StatusCode MergeGenericMuonSimHitCollTool::mergeEvent() {
+StatusCode MergeGenericMuonSimHitCollTool::mergeEvent(const EventContext& /*ctx*/) {
   for (unsigned int iHitContainer=0;iHitContainer<m_SimHitContainerNames.size();++iHitContainer) {
     if ( m_outputContainers[iHitContainer]==0 ) { continue; } //don't bother recording unused containers!
     if (!(evtStore()->record(m_outputContainers[iHitContainer],m_SimHitContainerNames[iHitContainer]).isSuccess())) {
@@ -85,7 +85,7 @@ StatusCode MergeGenericMuonSimHitCollTool::mergeEvent() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeGenericMuonSimHitCollTool::processAllSubEvents()
+StatusCode MergeGenericMuonSimHitCollTool::processAllSubEvents(const EventContext& /*ctx*/)
 {
   ATH_MSG_VERBOSE ( "processAllSubEvents()" );
   if(!m_pMergeSvc) {
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitCollTool.h b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitCollTool.h
index 40499a5eeab61c349556472ef7e468141ae8fc04..fa469a37abf3f2115d8a4142c2f19dc048922a56 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitCollTool.h
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeGenericMuonSimHitCollTool.h
@@ -31,10 +31,10 @@ public:
   virtual StatusCode initialize() override final;
   ///called before the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode processBunchXing(int bunchXing,
@@ -44,7 +44,7 @@ public:
   /// implemented by default in PileUpToolBase as FirstXing<=bunchXing<=LastXing
   // virtual bool toProcess(int bunchXing) const;
   /// Merge the GenericMuonSimHitColl
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 private:
   /// share code between two approaches
   virtual void processGenericMuonSimHitColl(const GenericMuonSimHitCollection *inputCollection, GenericMuonSimHitCollection *outputCollection, const double& timeOfBCID);
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingPars.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingPars.cxx
index 3f56d02153960f5c2f501a20ec90476f73bfda9c..cfade2a8900d0d4336447b54ec72aae3fde19323 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingPars.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingPars.cxx
@@ -20,5 +20,5 @@ StatusCode MergeHijingPars::initialize() {
 
 StatusCode MergeHijingPars::execute() {
   ATH_MSG_DEBUG("execute()");
-  return m_mergeTool->processAllSubEvents();
+  return m_mergeTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingParsTool.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingParsTool.cxx
index 61d4a327624eda809a70c74a09e974c82eac5322..ce6f37a3b752dd0bf86800e09013ac1b5609fe09 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingParsTool.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingParsTool.cxx
@@ -17,11 +17,11 @@ StatusCode MergeHijingParsTool::initialize() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeHijingParsTool::prepareEvent(unsigned int nInputEvents) {
+StatusCode MergeHijingParsTool::prepareEvent(const EventContext& ctx, unsigned int nInputEvents) {
   ATH_MSG_VERBOSE ( "Calling prepareEvent(): " << name() << " - package version " << PACKAGE_VERSION );
   ATH_MSG_DEBUG( "prepareEvent: there are " << nInputEvents << " subevents in this event.");
   m_firstSubEvent=true;
-  m_outputObject = SG::makeHandle(m_outputObjectKey);
+  m_outputObject = SG::makeHandle(m_outputObjectKey, ctx);
   return StatusCode::SUCCESS;
 }
 
@@ -72,7 +72,7 @@ StatusCode MergeHijingParsTool::processBunchXing(int bunchXing,
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeHijingParsTool::mergeEvent()
+StatusCode MergeHijingParsTool::mergeEvent(const EventContext& /*ctx*/)
 {
   //Double check that something was found.
   if(!m_outputObject.isValid()) {
@@ -88,9 +88,9 @@ bool MergeHijingParsTool::toProcess(int bunchXing) const {
   return (bunchXing==0);
 }
 
-StatusCode MergeHijingParsTool::processAllSubEvents() {
+StatusCode MergeHijingParsTool::processAllSubEvents(const EventContext& ctx) {
   ATH_MSG_VERBOSE ( "processAllSubEvents()" );
-  m_outputObject = SG::makeHandle(m_outputObjectKey);
+  m_outputObject = SG::makeHandle(m_outputObjectKey, ctx);
   typedef PileUpMergeSvc::TimedList<HijingEventParams>::type TimedHijingParamsList;
   TimedHijingParamsList HijingList;
   const HijingEventParams *hijing_pars(nullptr);
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingParsTool.h b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingParsTool.h
index 8a1c5008e4079b024c2b42e2cc2c1f127983e6b3..064e4135f3e1212d2b4fb32faf237efc72b0f844 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingParsTool.h
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeHijingParsTool.h
@@ -31,10 +31,10 @@ public:
   virtual StatusCode initialize() override final;
   ///called before the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode processBunchXing(int bunchXing,
@@ -46,7 +46,7 @@ public:
      /**  @brief Propagate the HijingParsections to the output
           StoreGate
      */
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 private:
   ServiceHandle<PileUpMergeSvc> m_pMergeSvc{this, "PileUpMergeSvc", "PileUpMergeSvc", ""};
   SG::WriteHandleKey<HijingEventParams> m_outputObjectKey{this, "HijingParamsKey", "Hijing_event_params", ""};
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollTool.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollTool.cxx
index a647cd5ee05eef1f9f5b4f431963bdb9d4be2083..13e817d788dee03c18cc4f1e3906eb25d1172696 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollTool.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollTool.cxx
@@ -149,7 +149,7 @@ StatusCode MergeMcEventCollTool::initialize() {
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeMcEventCollTool::prepareEvent(unsigned int nInputEvents) {
+StatusCode MergeMcEventCollTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents) {
   //clear the background classification map
   m_backgroundClassificationMap.clear();
   m_newevent=true;
@@ -168,7 +168,7 @@ StatusCode MergeMcEventCollTool::prepareEvent(unsigned int nInputEvents) {
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeMcEventCollTool::processAllSubEvents() {
+StatusCode MergeMcEventCollTool::processAllSubEvents(const EventContext& /*ctx*/) {
   ATH_MSG_VERBOSE ( "processAllSubEvents()" );
   if(!m_pMergeSvc) {
     if (!(m_pMergeSvc.retrieve()).isSuccess()) {
@@ -267,7 +267,7 @@ StatusCode MergeMcEventCollTool::processBunchXing(int bunchXing,
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeMcEventCollTool::mergeEvent() {
+StatusCode MergeMcEventCollTool::mergeEvent(const EventContext& /*ctx*/) {
   ATH_MSG_DEBUG( "mergeEvent" );
   if(m_nBkgEventsReadSoFar+1<m_nInputMcEventColls) {
     ATH_MSG_WARNING( "mergeEvent: Expected " << m_nInputMcEventColls << " subevents, but only saw " << m_nBkgEventsReadSoFar+1 << "! The job will probably crash now..." );
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollTool.h b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollTool.h
index a114a1cbfda33dd233ad6915e7c2d0d7070f6c6e..bc2a7cb24d0f1c33eb34fd65cf56e6fe1cc5f652 100755
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollTool.h
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollTool.h
@@ -34,10 +34,10 @@ public:
   virtual StatusCode initialize() override final;
   ///called before the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode processBunchXing(int bunchXing,
@@ -48,7 +48,7 @@ public:
   /// implemented by default in PileUpToolBase as FirstXing<=bunchXing<=LastXing
   //  virtual bool toProcess(int bunchXing) const;
 
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
 private:
   //** The types used to classify the events. NOPUTYPE is used both as the number of types, and to flag a reject (no type)
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollection.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollection.cxx
index 6d0dae45b187f1b78dbc69694d90a3c0ab0264dc..7c93f13230b9a915827afcd76f91ac1611e72368 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollection.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeMcEventCollection.cxx
@@ -22,5 +22,5 @@ StatusCode MergeMcEventCollection::initialize()
 StatusCode MergeMcEventCollection::execute()
 {
   ATH_MSG_DEBUG("execute()");
-  return m_mergeTool->processAllSubEvents();
+  return m_mergeTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObj.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObj.cxx
index b6ab191cadb6b1e0b52f89e35e9e683ea3a150da..cfb9b6f522918e0a09f0d3a70378fb21d398c3ba 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObj.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObj.cxx
@@ -22,5 +22,5 @@ StatusCode MergeRecoTimingObj::initialize() {
 
 StatusCode MergeRecoTimingObj::execute() {
   ATH_MSG_DEBUG("execute()");
-  return m_mergeTool->processAllSubEvents();
+  return m_mergeTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObjTool.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObjTool.cxx
index 6deea353f9a4340c7d58fc50bfb679c6401f9443..eaba7c0cee72a029dbe4a4d430180d6138576b23 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObjTool.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObjTool.cxx
@@ -20,7 +20,7 @@ StatusCode MergeRecoTimingObjTool::initialize()
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeRecoTimingObjTool::prepareEvent(unsigned int nInputEvents)
+StatusCode MergeRecoTimingObjTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents)
 {
   ATH_MSG_DEBUG ( "Calling prepareEvent(): " << name() << " - package version " << PACKAGE_VERSION );
   ATH_MSG_DEBUG( "prepareEvent: there are " << nInputEvents << " subevents in this event.");
@@ -52,7 +52,7 @@ StatusCode MergeRecoTimingObjTool::processBunchXing(int bunchXing,
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeRecoTimingObjTool::mergeEvent()
+StatusCode MergeRecoTimingObjTool::mergeEvent(const EventContext& /*ctx*/)
 {
   //Nothing to do here;
   return StatusCode::SUCCESS;
@@ -65,7 +65,7 @@ bool MergeRecoTimingObjTool::toProcess(int bunchXing) const
   return (bunchXing==0);
 }
 
-StatusCode MergeRecoTimingObjTool::processAllSubEvents()
+StatusCode MergeRecoTimingObjTool::processAllSubEvents(const EventContext& /*ctx*/)
 {
   ATH_MSG_VERBOSE ( "processAllSubEvents()" );
   const RecoTimingObj *oldColl(nullptr);
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObjTool.h b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObjTool.h
index dcabdac2760d04b9655a968be043cfae67c76b3c..036f05839cdb94b23a72d38d24f1bf23677802b3 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObjTool.h
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeRecoTimingObjTool.h
@@ -30,10 +30,10 @@ public:
   virtual StatusCode initialize() override final;
   ///called before the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode processBunchXing(int bunchXing,
@@ -43,7 +43,7 @@ public:
   /// implemented by default in PileUpToolBase as FirstXing<=bunchXing<=LastXing
   virtual bool toProcess(int bunchXing) const override final;
   /// Merge the RecoTimingObj
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 private:
   /// share code between two approaches
   virtual StatusCode processRecoTimingObj(const RecoTimingObj *inputObj);
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollTool.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollTool.cxx
index aa73862288da6c89d3344bddac97f20004ac7170..1722ae9c8ea85ac49e2f61aed8f34da17f74c053 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollTool.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollTool.cxx
@@ -21,7 +21,7 @@ StatusCode MergeTrackRecordCollTool::initialize()
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeTrackRecordCollTool::prepareEvent(unsigned int nInputEvents)
+StatusCode MergeTrackRecordCollTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents)
 {
   ATH_MSG_DEBUG ( "Calling prepareEvent(): " << name() << " - package version " << PACKAGE_VERSION );
   ATH_MSG_DEBUG( "prepareEvent: there are " << nInputEvents << " subevents in this event.");
@@ -65,7 +65,7 @@ StatusCode MergeTrackRecordCollTool::processBunchXing(int bunchXing,
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeTrackRecordCollTool::mergeEvent()
+StatusCode MergeTrackRecordCollTool::mergeEvent(const EventContext& /*ctx*/)
 {
   //Nothing to do here;
   return StatusCode::SUCCESS;
@@ -78,7 +78,7 @@ bool MergeTrackRecordCollTool::toProcess(int bunchXing) const
   return (bunchXing==0);
 }
 
-StatusCode MergeTrackRecordCollTool::processAllSubEvents()
+StatusCode MergeTrackRecordCollTool::processAllSubEvents(const EventContext& ctx)
 {
   ATH_MSG_VERBOSE ( "processAllSubEvents()" );
 
@@ -89,7 +89,7 @@ StatusCode MergeTrackRecordCollTool::processAllSubEvents()
       //FIXME we are forced to do a deep copy
       const TrackRecordCollection &oldColl=*(truthList.begin())->second;
 
-      SG::WriteHandle<TrackRecordCollection> outputCollection(m_outputKey);
+      SG::WriteHandle<TrackRecordCollection> outputCollection(m_outputKey, ctx);
       ATH_CHECK(outputCollection.record(std::make_unique<TrackRecordCollection>()));
       if (!outputCollection.isValid()) {
         ATH_MSG_ERROR("Could not record output TrackRecordCollection " << outputCollection.name() << " to store " << outputCollection.store());
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollTool.h b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollTool.h
index 65f80d321c510ff972524b55acbc41a183461625..f7f438309a4b396c1385573fa3a52ae3eb6b6dcb 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollTool.h
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollTool.h
@@ -30,10 +30,10 @@ public:
   virtual StatusCode initialize() override final;
   ///called before the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode processBunchXing(int bunchXing,
@@ -45,7 +45,7 @@ public:
      /**  @brief Propagate the TrackRecordCollections to the output
           StoreGate
      */
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 private:
   ServiceHandle<PileUpMergeSvc> m_pMergeSvc{this, "PileUpMergeSvc", "PileUpMergeSvc", ""};
   StringProperty m_trRecCollKey{this, "TrackRecordCollKey", "MuonEntryLayer", ""};
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollection.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollection.cxx
index 0fa0e31a9b59f78c35b1dbe23d4a07c20742f8d4..270b04a92a84b40ae6cca077535d9d0045eb758a 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollection.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTrackRecordCollection.cxx
@@ -22,5 +22,5 @@ StatusCode MergeTrackRecordCollection::initialize() {
 
 StatusCode MergeTrackRecordCollection::execute() {
   ATH_MSG_DEBUG("execute()");
-  return m_mergeTool->processAllSubEvents();
+  return m_mergeTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJets.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJets.cxx
index a3567fa217b5cbae0785babc61ec41094754c37b..eb2324e27887babd096ba39ae0d77e67f1ee73a0 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJets.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJets.cxx
@@ -21,5 +21,5 @@ StatusCode MergeTruthJets::initialize() {
 
 StatusCode MergeTruthJets::execute() {
   ATH_MSG_DEBUG("execute()");
-  return m_mergeTool->processAllSubEvents();
+  return m_mergeTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJetsTool.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJetsTool.cxx
index 8218d7c17b97f17d7354317e183dbacb3d8ed89a..2e263f5b29bf19b77c36f2b33a3aca6167e5906c 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJetsTool.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJetsTool.cxx
@@ -23,7 +23,7 @@ StatusCode MergeTruthJetsTool::initialize()
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeTruthJetsTool::prepareEvent(unsigned int nInputEvents)
+StatusCode MergeTruthJetsTool::prepareEvent(const EventContext& /*ctx*/, unsigned int nInputEvents)
 {
   ATH_MSG_VERBOSE ( "prepareEvent()" );
   ATH_MSG_DEBUG ( "prepareEvent: there are " << nInputEvents << " subevents in this event." );
@@ -86,7 +86,7 @@ StatusCode MergeTruthJetsTool::processBunchXing(int bunchXing,
   return StatusCode::SUCCESS;
 }
 
-StatusCode MergeTruthJetsTool::mergeEvent()
+StatusCode MergeTruthJetsTool::mergeEvent(const EventContext& /*ctx*/)
 {
   ATH_MSG_VERBOSE ( "mergeEvent" );
 
@@ -141,7 +141,7 @@ StatusCode MergeTruthJetsTool::record(const xAOD::JetContainer* pjets, std::stri
 }
 
 
-StatusCode MergeTruthJetsTool::processAllSubEvents()
+StatusCode MergeTruthJetsTool::processAllSubEvents(const EventContext& /*ctx*/)
 {
   ATH_MSG_VERBOSE ( "processAllSubEvents()" );
 
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJetsTool.h b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJetsTool.h
index d0aece1ff4582128cdc387039ca265c40428bed3..177c6dd0d8838ec3c7020800d030a13557c6a752 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJetsTool.h
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/MergeTruthJetsTool.h
@@ -29,17 +29,17 @@ public:
   StatusCode initialize() override final;
   ///called before the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode processBunchXing(int bunchXing,
                                       SubEventIterator bSubEvents,
                                       SubEventIterator eSubEvents) override final;
   ///Merge the Truth JetContainers using the PileUpMergeSvc
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
   // ///implementation of passing filter
   // virtual bool filterPassed() const override final { return (!m_vetoOnInTime || m_filterPassed); }
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/NewMergeMcEventCollTool.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/NewMergeMcEventCollTool.cxx
index 6a3cbc09102802577e33973c1b1cf54ee1bb7fe1..5a4d85728666caf4f2fb73ddff2844b0a92e487c 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/NewMergeMcEventCollTool.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/NewMergeMcEventCollTool.cxx
@@ -23,7 +23,7 @@ StatusCode NewMergeMcEventCollTool::initialize()
 }
 
 /// PileUpTools Approach
-StatusCode NewMergeMcEventCollTool::prepareEvent(unsigned int nInputEvents)
+StatusCode NewMergeMcEventCollTool::prepareEvent(const EventContext& ctx, unsigned int nInputEvents)
 {
   ATH_MSG_VERBOSE( this->name()<<"::prepareEvent()" );
 
@@ -40,7 +40,7 @@ StatusCode NewMergeMcEventCollTool::prepareEvent(unsigned int nInputEvents)
     // variable, but this is the only way to allow multiple function
     // calls to add information to the version of the
     // McEventCollection in the output StoreGate
-    m_outputMcEventCollection = SG::makeHandle(m_truthCollOutputKey);
+    m_outputMcEventCollection = SG::makeHandle(m_truthCollOutputKey, ctx);
     ATH_CHECK(m_outputMcEventCollection.record(std::make_unique<McEventCollection>()));
   }
   else {
@@ -70,7 +70,7 @@ StatusCode NewMergeMcEventCollTool::processBunchXing(int /*bunchXing*/,
   return StatusCode::SUCCESS;
 }
 
-StatusCode NewMergeMcEventCollTool::mergeEvent()
+StatusCode NewMergeMcEventCollTool::mergeEvent(const EventContext& /*ctx*/)
 {
   ATH_MSG_VERBOSE(  this->name()<<"::mergeEvent()" );
   if(msgLvl(MSG::VERBOSE)) { this->printDetailsOfMergedMcEventCollection(m_outputMcEventCollection.ptr()); }
@@ -78,10 +78,10 @@ StatusCode NewMergeMcEventCollTool::mergeEvent()
 }
 
 /// Algorithm Approach
-StatusCode NewMergeMcEventCollTool::processAllSubEvents()
+StatusCode NewMergeMcEventCollTool::processAllSubEvents(const EventContext& ctx)
 {
   ATH_MSG_VERBOSE ( this->name()<<"::processAllSubEvents()" );
-  SG::WriteHandle<McEventCollection> outputMcEventCollection(m_truthCollOutputKey);
+  SG::WriteHandle<McEventCollection> outputMcEventCollection(m_truthCollOutputKey, ctx);
   ATH_CHECK(outputMcEventCollection.record(std::make_unique<McEventCollection>()));
 
   //first get the list of McEventCollections
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/NewMergeMcEventCollTool.h b/Simulation/G4Utilities/MCTruthSimAlgs/src/NewMergeMcEventCollTool.h
index 5054b130bedf74733638ae354d45dcbc51007825..07c14ad2440b0961366feab1e522ddee8886c73c 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/NewMergeMcEventCollTool.h
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/NewMergeMcEventCollTool.h
@@ -29,10 +29,10 @@ public:
   virtual StatusCode initialize() override final;
   ///called before the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode
@@ -40,7 +40,7 @@ public:
                      SubEventIterator bSubEvents,
                      SubEventIterator eSubEvents) override final;
 
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
 private:
   //** Add the required information from the current GenEvent to the output McEventCollection
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/SimpleMergeMcEventCollTool.cxx b/Simulation/G4Utilities/MCTruthSimAlgs/src/SimpleMergeMcEventCollTool.cxx
index f90ff2380098be0c6395fc02455d04b3ce0ab5ae..285388c01cc904ef0b9f6eee9ff2bea1904b7537 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/SimpleMergeMcEventCollTool.cxx
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/SimpleMergeMcEventCollTool.cxx
@@ -25,7 +25,7 @@ StatusCode SimpleMergeMcEventCollTool::initialize()
 }
 
 /// PileUpTools Approach
-StatusCode SimpleMergeMcEventCollTool::prepareEvent(unsigned int nInputEvents)
+StatusCode SimpleMergeMcEventCollTool::prepareEvent(const EventContext& ctx, unsigned int nInputEvents)
 {
   ATH_MSG_VERBOSE ( "prepareEvent()" );
   m_nBkgEventsReadSoFar=0;
@@ -45,7 +45,7 @@ StatusCode SimpleMergeMcEventCollTool::prepareEvent(unsigned int nInputEvents)
     // variable, but this is the only way to allow multiple function
     // calls to add information to the version of the
     // McEventCollection in the output StoreGate
-    m_outputMcEventCollection = SG::makeHandle(m_truthCollOutputKey);
+    m_outputMcEventCollection = SG::makeHandle(m_truthCollOutputKey, ctx);
     ATH_CHECK(m_outputMcEventCollection.record(std::make_unique<McEventCollection>()));
   }
   else {
@@ -74,7 +74,7 @@ StatusCode SimpleMergeMcEventCollTool::processBunchXing(int /*bunchXing*/,
   return StatusCode::SUCCESS;
 }
 
-StatusCode SimpleMergeMcEventCollTool::mergeEvent()
+StatusCode SimpleMergeMcEventCollTool::mergeEvent(const EventContext& /*ctx*/)
 {
   ATH_MSG_DEBUG( "mergeEvent()" );
   if(m_nBkgEventsReadSoFar+1<m_nInputMcEventColls)
@@ -87,10 +87,10 @@ StatusCode SimpleMergeMcEventCollTool::mergeEvent()
 }
 
 /// Algorithm Approach
-StatusCode SimpleMergeMcEventCollTool::processAllSubEvents()
+StatusCode SimpleMergeMcEventCollTool::processAllSubEvents(const EventContext& ctx)
 {
   ATH_MSG_VERBOSE ( "processAllSubEvents()" );
-  SG::WriteHandle<McEventCollection> outputMcEventCollection(m_truthCollOutputKey);
+  SG::WriteHandle<McEventCollection> outputMcEventCollection(m_truthCollOutputKey, ctx);
   ATH_CHECK(outputMcEventCollection.record(std::make_unique<McEventCollection>()));
 
   //first get the list of McEventCollections
diff --git a/Simulation/G4Utilities/MCTruthSimAlgs/src/SimpleMergeMcEventCollTool.h b/Simulation/G4Utilities/MCTruthSimAlgs/src/SimpleMergeMcEventCollTool.h
index d5a9c5791b3ef6fb2b491140e4c3f3cf8b7ce134..e9b5745e5aa6d2d477fd1e055852600aa478b733 100644
--- a/Simulation/G4Utilities/MCTruthSimAlgs/src/SimpleMergeMcEventCollTool.h
+++ b/Simulation/G4Utilities/MCTruthSimAlgs/src/SimpleMergeMcEventCollTool.h
@@ -33,10 +33,10 @@ public:
   virtual StatusCode initialize() override final;
   ///called before the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode prepareEvent(unsigned int nInputEvents) override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int nInputEvents) override final;
   ///called at the end of the subevts loop. Not (necessarily) able to access
   ///SubEvents
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   ///called for each active bunch-crossing to process current SubEvents
   /// bunchXing is in ns
   virtual StatusCode
@@ -47,7 +47,7 @@ public:
   /// implemented by default in PileUpToolBase as FirstXing<=bunchXing<=LastXing
   //  virtual bool toProcess(int bunchXing) const;
 
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
 
 private:
   //** Add the required information from the current GenEvent to the output McEventCollection
diff --git a/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileHitVecToCntTool.h b/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileHitVecToCntTool.h
index 1bece1d6e9750f5b299172275cfb476a5105d37d..68c935cfaba23b36ba139654c6020a9ea2de9154 100644
--- a/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileHitVecToCntTool.h
+++ b/TileCalorimeter/TileSimAlgs/TileSimAlgs/TileHitVecToCntTool.h
@@ -84,12 +84,12 @@ class TileHitVecToCntTool: public PileUpToolBase {
 public:
   TileHitVecToCntTool(const std::string& type, const std::string& name, const IInterface* parent); //!< Constructor
   StatusCode initialize() override final;
-  virtual StatusCode prepareEvent(unsigned int /*nInputEvents*/) override final;
-  virtual StatusCode mergeEvent() override final;
+  virtual StatusCode prepareEvent(const EventContext& ctx, unsigned int /*nInputEvents*/) override final;
+  virtual StatusCode mergeEvent(const EventContext& ctx) override final;
   virtual StatusCode processBunchXing(int bunchXing,
                                       SubEventIterator bSubEvents,
                                       SubEventIterator eSubEvents) override final;
-  virtual StatusCode processAllSubEvents() override final;
+  virtual StatusCode processAllSubEvents(const EventContext& ctx) override final;
   StatusCode finalize() override final;
 
 private:
diff --git a/TileCalorimeter/TileSimAlgs/src/TileHitVecToCnt.cxx b/TileCalorimeter/TileSimAlgs/src/TileHitVecToCnt.cxx
index 003fec0dd7e211ff6df007735488f8a45a45eecb..e4cead810e296678227fd56b69c934a6611adb4d 100644
--- a/TileCalorimeter/TileSimAlgs/src/TileHitVecToCnt.cxx
+++ b/TileCalorimeter/TileSimAlgs/src/TileHitVecToCnt.cxx
@@ -41,5 +41,5 @@ StatusCode TileHitVecToCnt::initialize() {
 //----------------------------------------------------------------------
 StatusCode TileHitVecToCnt::execute() {
   ATH_MSG_DEBUG ( "execute()" );
-  return m_digTool->processAllSubEvents();
+  return m_digTool->processAllSubEvents(Gaudi::Hive::currentContext());
 }
diff --git a/TileCalorimeter/TileSimAlgs/src/TileHitVecToCntTool.cxx b/TileCalorimeter/TileSimAlgs/src/TileHitVecToCntTool.cxx
index 0dae6a810a5b0c7901a4f7ec8452c5185ffe0931..c19087fae63c14a8f642da2f7e5fd16b24231179 100644
--- a/TileCalorimeter/TileSimAlgs/src/TileHitVecToCntTool.cxx
+++ b/TileCalorimeter/TileSimAlgs/src/TileHitVecToCntTool.cxx
@@ -318,7 +318,7 @@ StatusCode TileHitVecToCntTool::createContainers() {
 
 }
 
-StatusCode TileHitVecToCntTool::prepareEvent(unsigned int /*nInputEvents*/) {
+StatusCode TileHitVecToCntTool::prepareEvent(const EventContext& ctx, unsigned int /*nInputEvents*/) {
 
   ATH_MSG_DEBUG("TileHitVecToCntTool prepareEvent initialization started");
 
@@ -327,7 +327,7 @@ StatusCode TileHitVecToCntTool::prepareEvent(unsigned int /*nInputEvents*/) {
   ATH_MSG_DEBUG("TileHitVecToCntTool prepareEvent finished");
 
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
+  rngWrapper->setSeed( name(), ctx );
 
   return StatusCode::SUCCESS;
 }
@@ -713,7 +713,7 @@ StatusCode TileHitVecToCntTool::processBunchXing(int bunchXing
   //  setFilterPassed(true);
 
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  CLHEP::HepRandomEngine * engine = *rngWrapper;
+  CLHEP::HepRandomEngine * engine = rngWrapper->getEngine(Gaudi::Hive::currentContext());
 
   SubEventIterator iEvt(bSubEvents);
   if (m_rndmEvtOverlay && bunchXing != 0) iEvt = eSubEvents; // in overlay skip all events except BC=0
@@ -775,7 +775,7 @@ StatusCode TileHitVecToCntTool::processBunchXing(int bunchXing
   return StatusCode::SUCCESS;
 }
 
-StatusCode TileHitVecToCntTool::processAllSubEvents() {
+StatusCode TileHitVecToCntTool::processAllSubEvents(const EventContext& ctx) {
 
   ATH_MSG_DEBUG("TileHitVecToCntTool processAllSubEvents started");
   typedef PileUpMergeSvc::TimedList<TileHitVector>::type TimedHitContList;
@@ -787,11 +787,11 @@ StatusCode TileHitVecToCntTool::processAllSubEvents() {
   double eHitTot(0.0);
 
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  rngWrapper->setSeed( name(), Gaudi::Hive::currentContext() );
-  CLHEP::HepRandomEngine * engine = *rngWrapper;
+  rngWrapper->setSeed( name(), ctx );
+  CLHEP::HepRandomEngine * engine = rngWrapper->getEngine(ctx);
 
   if(!m_onlyUseContainerName && m_rndmEvtOverlay) {
-    auto hitVectorHandles = m_hitVectorKeys.makeHandles();
+    auto hitVectorHandles = m_hitVectorKeys.makeHandles(ctx);
     for (auto & inputHits : hitVectorHandles) {
       if (!inputHits.isValid()) {
         ATH_MSG_ERROR("BAD HANDLE"); //FIXME improve error here
@@ -803,7 +803,7 @@ StatusCode TileHitVecToCntTool::processAllSubEvents() {
       this->processHitVectorForOverlay(inputHits.cptr(), nHit, eHitTot);
       if(m_doDigiTruth) this->processHitVectorWithoutPileUp(inputHits.cptr(), nHit, eHitTot, m_hits_DigiHSTruth, engine);
     }
-    ATH_CHECK(this->mergeEvent());
+    ATH_CHECK(this->mergeEvent(ctx));
     return StatusCode::SUCCESS;
   }
 
@@ -864,12 +864,12 @@ StatusCode TileHitVecToCntTool::processAllSubEvents() {
 
   } // end of the loop over different input hitVectorNames (normal hits and MBTS hits)
 
-  ATH_CHECK(this->mergeEvent());
+  ATH_CHECK(this->mergeEvent(ctx));
 
   return StatusCode::SUCCESS;
 }
 
-StatusCode TileHitVecToCntTool::mergeEvent() {
+StatusCode TileHitVecToCntTool::mergeEvent(const EventContext& ctx) {
 
   ATH_MSG_DEBUG("Entering mergeEvent in TileHitVecToCntTool");
 
@@ -934,7 +934,7 @@ StatusCode TileHitVecToCntTool::mergeEvent() {
   //std::vector<std::string>::const_iterator hitVecNamesEnd = m_hitVectorNames.end();
 
   ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
-  CLHEP::HepRandomEngine * engine = *rngWrapper;
+  CLHEP::HepRandomEngine * engine = rngWrapper->getEngine(ctx);
   
   TileHitNonConstContainer::iterator collIt_DigiHSTruth; 
   TileHitNonConstContainer::iterator endColl_DigiHSTruth;
@@ -995,7 +995,7 @@ StatusCode TileHitVecToCntTool::mergeEvent() {
     CHECK(hits->addCollection (coll.release(), hashId++));
   }
 
-  SG::WriteHandle<TileHitContainer> hitContainer(m_hitContainerKey);
+  SG::WriteHandle<TileHitContainer> hitContainer(m_hitContainerKey, ctx);
   ATH_CHECK( hitContainer.record(std::move(hits)) );
 
   ATH_MSG_DEBUG("TileHit container registered to the TES with name" << m_hitContainerKey.key());
@@ -1013,7 +1013,7 @@ StatusCode TileHitVecToCntTool::mergeEvent() {
       ATH_CHECK(hits_DigiHSTruth->addCollection (coll.release(), hashId_DigiHSTruth++));
     }
 
-    SG::WriteHandle<TileHitContainer> hitContainer_DigiHSTruth(m_hitContainer_DigiHSTruthKey);
+    SG::WriteHandle<TileHitContainer> hitContainer_DigiHSTruth(m_hitContainer_DigiHSTruthKey, ctx);
     ATH_CHECK( hitContainer_DigiHSTruth.record(std::move(hits_DigiHSTruth)) );
   }
 
diff --git a/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IExtrapolator.h b/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IExtrapolator.h
index 6f7525f16287cb15c54117a7e12c5e3766350994..2a38729db8b995dbfd1e123a912bde4a9c69f6f5 100755
--- a/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IExtrapolator.h
+++ b/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IExtrapolator.h
@@ -55,7 +55,7 @@ namespace Trk {
   class TrackStateOnSurface;      
   class Layer;
   class Volume;
-
+    
   class IExtrapolator : virtual public IAlgTool {
      public:
      
@@ -75,7 +75,7 @@ namespace Trk {
 
 
 
-       /** xAOD 0) neutral xAOD particle */
+        /** xAOD 0) xAOD track particle */
         virtual const TrackParameters* extrapolate(const xAOD::TrackParticle& particleBase,
                                                    const Surface& sf,
                                                    PropDirection dir=anyDirection,
@@ -160,22 +160,20 @@ namespace Trk {
          - extrapolation to the next active layer, based on the extrapolation to the next layer
            and layer identification
         */          
-        virtual std::pair<const TrackParameters*,const Layer*> extrapolateToNextActiveLayer(
-                                                                                       const IPropagator& prop,
-											                                           const TrackParameters& parm,
-											                                           PropDirection dir,
-											                                           const BoundaryCheck& bcheck,
-											                                           ParticleHypothesis particle=pion,
-											                                           MaterialUpdateMode matupmode=addNoise) const=0;
-
-        virtual std::pair<const TrackParameters*,const Layer*> extrapolateToNextActiveLayerM(
-                                                                                       const IPropagator& prop,
-											                                           const TrackParameters& parm,
-											                                           PropDirection dir,
-											                                           const BoundaryCheck& bcheck,
-											                                           std::vector<const Trk::TrackStateOnSurface*>& material,
-											                                           ParticleHypothesis particle=pion,
-											                                           MaterialUpdateMode matupmode=addNoise) const=0;
+        virtual std::pair<const TrackParameters*,const Layer*> extrapolateToNextActiveLayer(const IPropagator& prop,
+                                                                                            const TrackParameters& parm,
+											    PropDirection dir,
+                                                                                            const BoundaryCheck& bcheck,
+											    ParticleHypothesis particle=pion,
+											    MaterialUpdateMode matupmode=addNoise) const=0;
+
+        virtual std::pair<const TrackParameters*,const Layer*> extrapolateToNextActiveLayerM(const IPropagator& prop,
+											     const TrackParameters& parm,
+											     PropDirection dir,
+                                                                                             const BoundaryCheck& bcheck,
+											     std::vector<const Trk::TrackStateOnSurface*>& material,
+											     ParticleHypothesis particle=pion,
+											     MaterialUpdateMode matupmode=addNoise) const=0;
               
         /** S 8) <b>Strategy Pattern extrapolation method</b>:
          - Extrapolation using specific intermediate surfaces and energy loss effects to be accounted for at
diff --git a/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IPatternParametersPropagator.h b/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IPatternParametersPropagator.h
index 420f7b04d8094f0af17b4c8d9ae4c33bea5d2a01..0c204d101b23f46e749ca3d8536fffec5cb4b082 100644
--- a/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IPatternParametersPropagator.h
+++ b/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IPatternParametersPropagator.h
@@ -16,6 +16,7 @@
 
 #include "GeoPrimitives/GeoPrimitives.h"
 #include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
 #include "TrkEventPrimitives/PropDirection.h"
 #include "TrkEventPrimitives/ParticleHypothesis.h"
 
@@ -46,9 +47,12 @@ namespace Trk {
     //! framework method providing the abstract interface
     static const InterfaceID& interfaceID( ) ;
 
+    /** Interfaces WITH EventContext (new) */
+      
     /** Main propagation method */
     virtual bool propagate
-      (PatternTrackParameters         &,
+      (const ::EventContext&          ctx,
+       PatternTrackParameters         &,
        const Surface                  &,
        PatternTrackParameters         &,
        PropDirection                   ,
@@ -57,7 +61,8 @@ namespace Trk {
 
     /** Main propagation method with step to surface calculation*/
     virtual bool propagate
-      (PatternTrackParameters         &,
+      (const ::EventContext&          ctx,
+       PatternTrackParameters         &,
        const Surface                  &,
        PatternTrackParameters         &,
        PropDirection                   ,
@@ -67,7 +72,8 @@ namespace Trk {
       
       /** Main propagation method for parameters only */
     virtual bool propagateParameters
-      (PatternTrackParameters         &,
+      (const ::EventContext&          ctx,
+       PatternTrackParameters         &,
        const Surface                  &,
        PatternTrackParameters         &,
        PropDirection                   ,
@@ -76,7 +82,8 @@ namespace Trk {
       
       /** Main propagation method for parameters only with step to surface calculation*/
     virtual bool propagateParameters
-      (PatternTrackParameters         &,
+      (const ::EventContext&          ctx,
+       PatternTrackParameters         &,
        const Surface                  &,
        PatternTrackParameters         &,
        PropDirection                   ,
@@ -86,7 +93,8 @@ namespace Trk {
 
       /** GlobalPositions list interface */
     virtual void globalPositions
-      (std::list<Amg::Vector3D>       &,
+      (const ::EventContext&          ctx,
+       std::list<Amg::Vector3D>       &,
        const PatternTrackParameters   &,
        const MagneticFieldProperties  &,
        const CylinderBounds           &,
@@ -95,12 +103,71 @@ namespace Trk {
 
       /** GlobalPostions and steps for set surfaces */
     virtual void globalPositions
-      (const PatternTrackParameters                 &,
+      (const ::EventContext&          ctx,
+       const PatternTrackParameters                 &,
        std::list<const Surface*>                    &,
        std::list< std::pair<Amg::Vector3D,double> > &,
        const MagneticFieldProperties                &,
        ParticleHypothesis particle=pion              ) const = 0;
       
+
+    /** Interfaces WITHOUT EventContext (old) */
+
+    /** Main propagation method */
+    virtual bool propagate
+      (PatternTrackParameters         &,
+       const Surface                  &,
+       PatternTrackParameters         &,
+       PropDirection                   ,
+       const MagneticFieldProperties  &, 
+       ParticleHypothesis particle=pion) const;
+
+    /** Main propagation method with step to surface calculation*/
+    virtual bool propagate
+      (PatternTrackParameters         &,
+       const Surface                  &,
+       PatternTrackParameters         &,
+       PropDirection                   ,
+       const MagneticFieldProperties  &,
+       double                         &,
+       ParticleHypothesis particle=pion) const;
+      
+      /** Main propagation method for parameters only */
+    virtual bool propagateParameters
+      (PatternTrackParameters         &,
+       const Surface                  &,
+       PatternTrackParameters         &,
+       PropDirection                   ,
+       const MagneticFieldProperties  &,
+       ParticleHypothesis particle=pion) const;
+      
+      /** Main propagation method for parameters only with step to surface calculation*/
+    virtual bool propagateParameters
+      (PatternTrackParameters         &,
+       const Surface                  &,
+       PatternTrackParameters         &,
+       PropDirection                   ,
+       const MagneticFieldProperties  &,
+       double                         &,
+       ParticleHypothesis particle=pion) const;
+
+      /** GlobalPositions list interface */
+    virtual void globalPositions
+      (std::list<Amg::Vector3D>       &,
+       const PatternTrackParameters   &,
+       const MagneticFieldProperties  &,
+       const CylinderBounds           &,
+       double                          ,
+       ParticleHypothesis particle=pion) const;
+
+      /** GlobalPostions and steps for set surfaces */
+    virtual void globalPositions
+      (const PatternTrackParameters                 &,
+       std::list<const Surface*>                    &,
+       std::list< std::pair<Amg::Vector3D,double> > &,
+       const MagneticFieldProperties                &,
+       ParticleHypothesis particle=pion              ) const;
+      
   };
 } // end namespace
 
@@ -109,4 +176,84 @@ inline const InterfaceID& Trk::IPatternParametersPropagator::interfaceID()
         return IID_IPatternParametersPropagator;
 }
 
+/** temporarily default to old interfaces, taking the EventContext from GaudiHive */
+
+
+    /** Main propagation method */
+inline bool Trk::IPatternParametersPropagator::propagate
+      (Trk::PatternTrackParameters         &ptp1,
+       const Trk::Surface                  &surf,
+       Trk::PatternTrackParameters         &ptp2,
+       Trk::PropDirection                   pd,
+       const Trk::MagneticFieldProperties  &mf, 
+       Trk::ParticleHypothesis             particle) const
+{
+    return propagate(Gaudi::Hive::currentContext(), ptp1, surf, ptp2, pd, mf, particle);
+}
+
+
+    /** Main propagation method with step to surface calculation*/
+inline bool Trk::IPatternParametersPropagator::propagate
+      (Trk::PatternTrackParameters         &ptp1,
+       const Trk::Surface                  &surf,
+       Trk::PatternTrackParameters         &ptp2,
+       Trk::PropDirection                   pd,
+       const Trk::MagneticFieldProperties  &mf,
+       double                              &step,
+       Trk::ParticleHypothesis              particle) const
+{
+    return propagate(Gaudi::Hive::currentContext(), ptp1, surf, ptp2, pd, mf, step, particle);
+}
+
+      /** Main propagation method for parameters only */
+inline bool Trk::IPatternParametersPropagator::propagateParameters
+      (Trk::PatternTrackParameters         &ptp1,
+       const Trk::Surface                  &surf,
+       Trk::PatternTrackParameters         &ptp2,
+       Trk::PropDirection                   pd,
+       const Trk::MagneticFieldProperties  &mf,
+       Trk::ParticleHypothesis              particle) const
+{
+    return propagateParameters(Gaudi::Hive::currentContext(), ptp1, surf, ptp2, pd, mf, particle);
+}
+
+      
+      /** Main propagation method for parameters only with step to surface calculation*/
+inline bool Trk::IPatternParametersPropagator::propagateParameters
+      (Trk::PatternTrackParameters         &ptp1,
+       const Trk::Surface                  &surf,
+       Trk::PatternTrackParameters         &ptp2,
+       Trk::PropDirection                   pd,  
+       const Trk::MagneticFieldProperties  &mf,  
+       double                              &step,
+       Trk::ParticleHypothesis             particle) const
+{
+    return propagateParameters(Gaudi::Hive::currentContext(), ptp1, surf, ptp2, pd, mf, step, particle);
+}
+
+
+      /** GlobalPositions list interface */
+inline void Trk::IPatternParametersPropagator::globalPositions
+      (std::list<Amg::Vector3D>            &gp, 
+       const Trk::PatternTrackParameters   &ptp,
+       const Trk::MagneticFieldProperties  &mf,
+       const Trk::CylinderBounds           &cb,
+       double                               step,
+       Trk::ParticleHypothesis              particle) const
+{
+    return globalPositions(Gaudi::Hive::currentContext(), gp, ptp, mf, cb, step, particle);
+}
+
+      /** GlobalPostions and steps for set surfaces */
+inline void Trk::IPatternParametersPropagator::globalPositions
+      (const Trk::PatternTrackParameters                 &ptp,  
+       std::list<const Trk::Surface*>                    &surfs,
+       std::list< std::pair<Amg::Vector3D,double> >      &gp,
+       const Trk::MagneticFieldProperties                &mf,
+       Trk::ParticleHypothesis                           particle) const
+{
+    return globalPositions(Gaudi::Hive::currentContext(), ptp, surfs, gp, mf, particle);
+}
+
+
 #endif // TRK_IPATTERNPARAMETERSPROPAGATOR_H
diff --git a/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IPropagator.h b/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IPropagator.h
index 616fd0e09834dbc665cd83ccf58c6f328debcdb1..d55c9dffc15b736caac180e6af23091ad4091e72 100755
--- a/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IPropagator.h
+++ b/Tracking/TrkExtrapolation/TrkExInterfaces/TrkExInterfaces/IPropagator.h
@@ -11,6 +11,9 @@
 
 // Gaudi
 #include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
+#include "GaudiKernel/ThreadLocalContext.h"
+
 // Trk
 #include "TrkEventPrimitives/PropDirection.h"
 #include "TrkEventPrimitives/ParticleHypothesis.h"
@@ -57,7 +60,7 @@ namespace Trk {
        
        /** AlgTool and IAlgTool interface methods */
        static const InterfaceID& interfaceID() { return IID_IPropagator; }
-       
+
        /** [NeutralParameters] ------------------------------------------------------------- */
 
        /** N 0) <b>Neutral parameters method </b> 
@@ -87,20 +90,21 @@ namespace Trk {
           if (tVol) return nullptr;
         }
 
-       /** [TrackParameters] --------------------------------------------------------- */
+       /** [TrackParameters] new interfaces WITH EventContext ------------------------------------------ */
 
        /** Propagation interface:
          The propagation method called by the TrkExtrapolator. The extrapolator
          is responsible for the underlying logic of which surface to go to.
          */
-       virtual TrackParameters*  propagate( const TrackParameters& parm,
-                                             const Surface& sf,
-                                             PropDirection dir,
-                                             const BoundaryCheck& bcheck,
+       virtual TrackParameters*  propagate(  const EventContext&            ctx,
+                                             const TrackParameters&         parm,
+                                             const Surface&                 sf,
+                                             PropDirection                  dir,
+                                             const BoundaryCheck&           bcheck,
                                              const MagneticFieldProperties& mprop,
-                                             ParticleHypothesis particle=pion,
-                                             bool returnCurv = false,
-                                             const TrackingVolume* tVol=nullptr) const = 0;
+                                             ParticleHypothesis             particle   = pion,
+                                             bool                           returnCurv = false,
+                                             const TrackingVolume*          tVol       = nullptr) const = 0;
        
 
        /** Propagation interface:
@@ -108,54 +112,251 @@ namespace Trk {
          The propagation method called by the TrkExtrapolator. The propagator
          finds the closest surface.
          */
-       virtual  TrackParameters* propagate( const TrackParameters& parm,
-                                            std::vector<DestSurf>& sfs,
-                                            PropDirection dir,
+       virtual  TrackParameters* propagate( const EventContext&            ctx,
+                                            const TrackParameters&         parm,
+                                            std::vector<DestSurf>&         sfs,
+                                            PropDirection                  dir,
                                             const MagneticFieldProperties& mprop,
-                                            ParticleHypothesis particle,
-                                            std::vector<unsigned int>& solutions,
-                                            double& path,
-                                            bool usePathLim = false,
-                                            bool returnCurv = false,
-                                            const TrackingVolume* tVol=nullptr) const = 0;
+                                            ParticleHypothesis             particle,
+                                            std::vector<unsigned int>&     solutions,
+                                            double&                        path,
+                                            bool                           usePathLim = false,
+                                            bool                           returnCurv = false,
+                                            const TrackingVolume*          tVol       = nullptr) const = 0;
        
        /** Propagation interface:
          
          The propagation method called by the TrkExtrapolator. The propagator
          finds the closest surface. Timing included.
          */
-       virtual TrackParameters* propagateT( const TrackParameters& parm,
-						  std::vector<DestSurf>& sfs,
-						  PropDirection dir,
-              const MagneticFieldProperties& mprop,
-						  ParticleHypothesis particle,
-						  std::vector<unsigned int>& solutions,
-						  PathLimit& pathLim, TimeLimit& timeLim,
-						  bool returnCurv ,
-						  const TrackingVolume* tVol,
-						  std::vector<Trk::HitInfo>*& hitVector) const;
+       virtual TrackParameters* propagateT( const EventContext&            ctx,
+                                            const TrackParameters&         parm,
+                                            std::vector<DestSurf>&         sfs,
+                                            PropDirection                  dir,
+                                            const MagneticFieldProperties& mprop,
+                                            ParticleHypothesis             particle,
+                                            std::vector<unsigned int>&     solutions,
+                                            PathLimit&                     pathLim, TimeLimit& timeLim,
+                                            bool                           returnCurv ,
+                                            const TrackingVolume*          tVol,
+                                            std::vector<Trk::HitInfo>*&    hitVector) const;
          
        /** Propagation interface:
          
          The propagation method called by the TrkExtrapolator. The propagator
          finds the closest surface. Timing included.
          */
-       virtual TrackParameters* propagateT( const TrackParameters& parm,
-						  TargetSurfaces& sfs,
-						  PropDirection dir,
-              const MagneticFieldProperties& mprop,
-						  ParticleHypothesis particle,
-						  TargetSurfaceVector& solutions,
-						  PathLimit& pathLim, TimeLimit& timeLim,
-						  bool returnCurv ,
-						  std::vector<Trk::HitInfo>*& hitVector) const;
+       virtual TrackParameters* propagateT( const EventContext&            ctx,
+                                            const TrackParameters&         parm,
+                                            TargetSurfaces&                sfs,
+                                            PropDirection                  dir,
+                                            const MagneticFieldProperties& mprop,
+                                            ParticleHypothesis             particle,
+                                            TargetSurfaceVector&           solutions,
+                                            PathLimit&                     pathLim, TimeLimit& timeLim,
+                                            bool                           returnCurv ,
+                                            std::vector<Trk::HitInfo>*&    hitVector) const;
          
 
        /** Propagation interface:
          
          The propagation method called by the TrkExEngine. All options included.
          */
-       virtual Trk::ExtrapolationCode propagate( Trk::ExCellCharged& eCell,
+      virtual Trk::ExtrapolationCode propagate( const EventContext&       ctx,
+                                                Trk::ExCellCharged&       eCell,
+                                                Trk::TargetSurfaces&      sfs,
+                                                Trk::TargetSurfaceVector& solutions) const;         
+       /** Propagation interface:
+         
+         The propagation method with internal material collection. The propagator
+         finds the closest surface. 
+         */
+      virtual  TrackParameters* propagateM( const EventContext&                                        ctx,
+                                            const TrackParameters&                                     parm,
+                                            std::vector<DestSurf>&                                     sfs,
+                                            PropDirection                                              dir,
+                                            const MagneticFieldProperties&                             mprop,
+                                            ParticleHypothesis                                         particle,
+                                            std::vector<unsigned int>&                                 solutions,
+                                            std::vector<const Trk::TrackStateOnSurface*>*&             matstates,
+                                            std::vector<std::pair<const Trk::TrackParameters*,int> >*& intersections, 
+                                            double&                                                    path,
+                                            bool                                                       usePathLim = false,
+                                            bool                                                       returnCurv = false,
+                                            const TrackingVolume*                                      tVol       = nullptr,
+                                            Trk::ExtrapolationCache*                                   cache      = nullptr) const;
+         
+
+       /** Propagation interface:
+         
+         The propagation method including the return of the TransportJacobian matrix.
+
+         */
+       virtual TrackParameters*      propagate( const EventContext&            ctx,
+                                                const TrackParameters&         parm,
+                                                const Surface&                 sf,
+                                                PropDirection                  dir,
+                                                const BoundaryCheck&           bcheck,
+                                                const MagneticFieldProperties& mprop,
+                                                TransportJacobian*&            jacob,
+                                                double&                        pathLength,
+                                                ParticleHypothesis             particle   = pion,
+                                                bool                           returnCurv = false,
+                                                const TrackingVolume*          tVol       = 0) const = 0;
+       
+
+       /** Propagation interface without Covariance matrix propagation
+         the pathlength has to be returned for eventual following propagateCovariance
+         */
+
+       virtual TrackParameters*      propagateParameters( const EventContext&            ctx,
+                                                          const TrackParameters&         parm,
+                                                          const Surface&                 sf,
+                                                          PropDirection                  dir,
+                                                          const BoundaryCheck&           bcheck,
+                                                          const MagneticFieldProperties& mprop,
+                                                          ParticleHypothesis             particle=pion,
+                                                          bool                           returnCurv = false,
+                                                          const TrackingVolume*          tVol=0) const = 0;
+       
+       virtual TrackParameters*      propagateParameters( const EventContext&            ctx,
+                                                          const TrackParameters&         parm,
+                                                          const Surface&                 sf,
+                                                          PropDirection                  dir,
+                                                          const BoundaryCheck&           bcheck,
+                                                          const MagneticFieldProperties& mprop,
+                                                          TransportJacobian*&            jacob,
+                                                          ParticleHypothesis             particle=pion,
+                                                          bool                           returnCurv = false,
+                                                          const TrackingVolume*          tVol=0) const = 0;
+       
+
+       /** Intersection interface:
+         
+          The intersection interface might be used by the material service as well to estimate
+          the surfaces (sensitive and nonesensitive) while propagation
+         */
+       virtual const IntersectionSolution* intersect( const EventContext&            ctx,
+                                                      const TrackParameters&         parm,
+                                                      const Surface&                 sf,
+                                                      const MagneticFieldProperties& mprop,
+                                                      ParticleHypothesis             particle=pion,
+                                                      const TrackingVolume*          tVol=0) const = 0;
+
+      /** Intersection and Intersector interface: 
+        */
+
+      virtual const TrackSurfaceIntersection* intersectSurface(const EventContext&             ctx,
+                                                               const Surface&                  surface,
+                                                               const TrackSurfaceIntersection* trackIntersection,
+                                                               const double                    qOverP,
+                                                               const MagneticFieldProperties&  mft,
+                                                               ParticleHypothesis              particle) const = 0;                        
+ 
+
+      /** GlobalPositions list interface:
+         This is used mostly in pattern recognition in the road finder, the propagation direction is intrinsically given
+         by the sign of the stepSize.
+         
+         To avoid memory fragmentation in multiple use of pattern recognition processes and respecting the possible iterative
+         filling of the positions list, the list of GlobalPositions is given by reference through the signature and a void 
+         method has been chosen.
+         */
+       virtual void globalPositions(const EventContext&            ctx,
+                                    std::list<Amg::Vector3D>&      positionslist, 
+                                    const TrackParameters&         parm,
+                                    const MagneticFieldProperties& mprop,
+                                    const CylinderBounds&          cylbo,
+                                    double                         stepSize,
+                                    ParticleHypothesis             particle=pion,
+                                    const TrackingVolume*          tVol=0) const = 0;
+
+     /** a very simple propagation along a given path length */
+     virtual void propagateStep(const EventContext&            ctx,
+                                const Amg::Vector3D&           inputPosition, 
+                                const Amg::Vector3D&           inputMomentum, 
+                                double                         charge, 
+                                double                         step,
+                                Amg::Vector3D&                 outputPosition, 
+                                Amg::Vector3D&                 outputMomentum,
+                                const MagneticFieldProperties& mprop) const;
+
+
+     /** Validation Action:
+       Can be implemented optionally, outside access to internal validation steps */
+     virtual void validationAction() const {}
+
+
+       /** [TrackParameters] old interfaces WITHOUT EventContext ------------------------------------------ */
+
+       /** Propagation interface:
+         The propagation method called by the TrkExtrapolator. The extrapolator
+         is responsible for the underlying logic of which surface to go to.
+         */
+       virtual TrackParameters*  propagate( const TrackParameters&         parm,
+                                            const Surface&                 sf,
+                                            PropDirection                  dir,
+                                            const BoundaryCheck&           bcheck,
+                                            const MagneticFieldProperties& mprop,
+                                            ParticleHypothesis             particle   = pion,
+                                            bool                           returnCurv = false,
+                                            const TrackingVolume*          tVol       = 0) const;
+       
+
+       /** Propagation interface:
+         
+         The propagation method called by the TrkExtrapolator. The propagator
+         finds the closest surface.
+         */
+       virtual  TrackParameters* propagate( const TrackParameters&         parm,
+                                            std::vector<DestSurf>&         sfs,
+                                            PropDirection                  dir,
+                                            const MagneticFieldProperties& mprop,
+                                            ParticleHypothesis             particle,
+                                            std::vector<unsigned int>&     solutions,
+                                            double&                        path,
+                                            bool                           usePathLim = false,
+                                            bool                           returnCurv = false,
+                                            const TrackingVolume*          tVol       = nullptr) const;
+       
+       /** Propagation interface:
+         
+         The propagation method called by the TrkExtrapolator. The propagator
+         finds the closest surface. Timing included.
+         */
+       virtual TrackParameters* propagateT( const TrackParameters&         parm,
+                                            std::vector<DestSurf>&         sfs,
+                                            PropDirection                  dir,
+                                            const MagneticFieldProperties& mprop,
+                                            ParticleHypothesis             particle,
+                                            std::vector<unsigned int>&     solutions,
+                                            PathLimit&                     pathLim, TimeLimit& timeLim,
+                                            bool                           returnCurv ,
+                                            const TrackingVolume*          tVol,
+                                            std::vector<Trk::HitInfo>*& hitVector) const;
+         
+       /** Propagation interface:
+         
+         The propagation method called by the TrkExtrapolator. The propagator
+         finds the closest surface. Timing included.
+
+         */
+       virtual TrackParameters* propagateT( const TrackParameters&         parm,
+                                            TargetSurfaces&                sfs,
+                                            PropDirection                  dir,
+                                            const MagneticFieldProperties& mprop,
+                                            ParticleHypothesis             particle,
+                                            TargetSurfaceVector&           solutions,
+                                            PathLimit&                     pathLim, TimeLimit& timeLim,
+                                            bool                           returnCurv ,
+                                            std::vector<Trk::HitInfo>*& hitVector) const;
+         
+
+       /** Propagation interface:
+         
+         The propagation method called by the TrkExEngine. All options included.
+         */
+       virtual Trk::ExtrapolationCode propagate( Trk::ExCellCharged&  eCell,
                                                  Trk::TargetSurfaces& sfs,
                                                  Trk::TargetSurfaceVector& solutions) const;         
        /** Propagation interface:
@@ -163,19 +364,19 @@ namespace Trk {
          The propagation method with internal material collection. The propagator
          finds the closest surface. 
          */
-       virtual  TrackParameters* propagateM( const TrackParameters& parm,
-						  std::vector<DestSurf>& sfs,
-						  PropDirection dir,
-              const MagneticFieldProperties& mprop,
-						  ParticleHypothesis particle,
-						  std::vector<unsigned int>& solutions,
-						  std::vector<const Trk::TrackStateOnSurface*>*& matstates,
-						  std::vector<std::pair<const Trk::TrackParameters*,int> >*& intersections, 
-						  double& path,
-						  bool usePathLim = false,
-						  bool returnCurv = false,
-						  const TrackingVolume* tVol = nullptr,
-                                                  Trk::ExtrapolationCache* cache = nullptr) const;
+       virtual  TrackParameters* propagateM( const TrackParameters&                         parm,
+                                             std::vector<DestSurf>&                         sfs,
+                                             PropDirection                                  dir,
+                                             const MagneticFieldProperties&                 mprop,
+                                             ParticleHypothesis                             particle,
+                                             std::vector<unsigned int>&                     solutions,
+                                             std::vector<const Trk::TrackStateOnSurface*>*& matstates,
+                                             std::vector<std::pair<const Trk::TrackParameters*,int> >*& intersections, 
+                                             double&                                        path,
+                                             bool                                           usePathLim = false,
+                                             bool                                           returnCurv = false,
+                                             const TrackingVolume*                          tVol       = nullptr,
+                                             Trk::ExtrapolationCache*                       cache      = nullptr) const;
          
 
        /** Propagation interface:
@@ -183,40 +384,40 @@ namespace Trk {
          The propagation method including the return of the TransportJacobian matrix.
 
          */
-       virtual TrackParameters*      propagate( const TrackParameters& parm,
-                                                const Surface& sf,
-                                                PropDirection dir,
-                                                const BoundaryCheck& bcheck,
+       virtual TrackParameters*      propagate( const TrackParameters&         parm,
+                                                const Surface&                 sf,
+                                                PropDirection                  dir,
+                                                const BoundaryCheck&           bcheck,
                                                 const MagneticFieldProperties& mprop,
                                                 TransportJacobian*&,
-                                                double& pathLength,
-                                                ParticleHypothesis particle=pion,
-                                                bool returnCurv = false,
-                                                const TrackingVolume* tVol=nullptr) const = 0;
+                                                double&                        pathLength,
+                                                ParticleHypothesis             particle   = pion,
+                                                bool                           returnCurv = false,
+                                                const TrackingVolume*          tVol       = nullptr) const;
        
 
        /** Propagation interface without Covariance matrix propagation
          the pathlength has to be returned for eventual following propagateCovariance
          */
 
-       virtual TrackParameters*      propagateParameters( const TrackParameters& parm,
-                                                          const Surface& sf,
-                                                          PropDirection dir,
-                                                          const BoundaryCheck& bcheck,
+       virtual TrackParameters*      propagateParameters( const TrackParameters&         parm,
+                                                          const Surface&                 sf,
+                                                          PropDirection                  dir,
+                                                          const BoundaryCheck&           bcheck,
                                                           const MagneticFieldProperties& mprop,
-                                                          ParticleHypothesis particle=pion,
-                                                          bool returnCurv = false,
-                                                          const TrackingVolume* tVol=nullptr) const = 0;
+                                                          ParticleHypothesis             particle   = pion,
+                                                          bool                           returnCurv = false,
+                                                          const TrackingVolume*          tVol=nullptr) const;
        
-       virtual TrackParameters*      propagateParameters( const TrackParameters& parm,
-                                                          const Surface& sf,
-                                                          PropDirection dir,
-                                                          const BoundaryCheck& bcheck,
+       virtual TrackParameters*      propagateParameters( const TrackParameters&         parm,
+                                                          const Surface&                 sf,
+                                                          PropDirection                  dir,
+                                                          const BoundaryCheck&           bcheck,
                                                           const MagneticFieldProperties& mprop,
                                                           TransportJacobian*&,
-                                                          ParticleHypothesis particle=pion,
-                                                          bool returnCurv = false,
-                                                          const TrackingVolume* tVol=nullptr) const = 0;
+                                                          ParticleHypothesis             particle   = pion,
+                                                          bool                           returnCurv = false,
+                                                          const TrackingVolume*          tVol       = nullptr) const;
        
 
        /** Intersection interface:
@@ -224,20 +425,20 @@ namespace Trk {
           The intersection interface might be used by the material service as well to estimate
           the surfaces (sensitive and nonesensitive) while propagation
          */
-       virtual IntersectionSolution* intersect( const TrackParameters& parm,
-                                                const Surface& sf,
-                                                const MagneticFieldProperties& mprop,
-                                                ParticleHypothesis particle=pion,
-                                                const TrackingVolume* tVol=nullptr) const = 0;
+       virtual const IntersectionSolution* intersect( const TrackParameters&         parm,
+                                                      const Surface&                 sf,
+                                                      const MagneticFieldProperties& mprop,
+                                                      ParticleHypothesis             particle = pion,
+                                                      const TrackingVolume*          tVol     = nullptr) const;
 
       /** Intersection and Intersector interface: 
         */
 
-       virtual TrackSurfaceIntersection* intersectSurface(const Surface&         surface,
-                                                          const TrackSurfaceIntersection*    trackIntersection,
-                                                          const double               qOverP,
-                                                          const MagneticFieldProperties& mft,
-                                                          ParticleHypothesis       particle) const = 0;                        
+       virtual const TrackSurfaceIntersection* intersectSurface(const Surface&                  surface,
+                                                                const TrackSurfaceIntersection* trackIntersection,
+                                                                const double                    qOverP,
+                                                                const MagneticFieldProperties&  mft,
+                                                                ParticleHypothesis              particle) const;                        
  
 
       /** GlobalPositions list interface:
@@ -248,97 +449,102 @@ namespace Trk {
          filling of the positions list, the list of GlobalPositions is given by reference through the signature and a void 
          method has been chosen.
          */
-       virtual void globalPositions(std::list<Amg::Vector3D>& positionslist, 
-                                    const TrackParameters& parm,
+       virtual void globalPositions(std::list<Amg::Vector3D>&      positionslist, 
+                                    const TrackParameters&         parm,
                                     const MagneticFieldProperties& mprop,
-                                    const CylinderBounds& cylbo,
-                                    double stepSize,
-                                    ParticleHypothesis particle=pion,
-				                    const TrackingVolume* tVol=nullptr) const = 0;
+                                    const CylinderBounds&          cylbo,
+                                    double                         stepSize,
+                                    ParticleHypothesis             particle = pion,
+                                    const TrackingVolume*          tVol     = nullptr) const;
 
      /** a very simple propagation along a given path length */
      virtual void propagateStep(const Amg::Vector3D& inputPosition, 
                                 const Amg::Vector3D& inputMomentum, 
-                                double charge, 
-                                double step,
-                                Amg::Vector3D& outputPosition, 
-                                Amg::Vector3D& outputMomentum,
+                                double               charge, 
+                                double               step,
+                                Amg::Vector3D&       outputPosition, 
+                                Amg::Vector3D&       outputMomentum,
                                 const MagneticFieldProperties& mprop) const;
 
 
-     /** Validation Action:
-       Can be implemented optionally, outside access to internal validation steps */
-     virtual void validationAction() const {}
-
- };
+  };
 
 } // end of namespace
 
-inline  Trk::TrackParameters* Trk::IPropagator::propagate( const TrackParameters&,
-								std::vector<DestSurf>&,
-								PropDirection ,
-								const MagneticFieldProperties&,
-								ParticleHypothesis,
-								std::vector<unsigned int>&,
-								double&,
-								bool,
-								bool,
-								const Trk::TrackingVolume*) const
+// default methods for some methods which will not always be implemented
+
+inline  Trk::TrackParameters* Trk::IPropagator::propagate( const EventContext&,
+                                                           const TrackParameters&,
+                                                           std::vector<DestSurf>&,
+                                                           PropDirection ,
+                                                           const MagneticFieldProperties&,
+                                                           ParticleHypothesis,
+                                                           std::vector<unsigned int>&,
+                                                           double&,
+                                                           bool,
+                                                           bool,
+                                                           const Trk::TrackingVolume*) const
 {                  
-  return nullptr;
+    return nullptr;
 }
 
-inline Trk::TrackParameters* Trk::IPropagator::propagateT( const TrackParameters&,
-								 std::vector<DestSurf>&,
-								 PropDirection ,
-								 const MagneticFieldProperties&,
-								 ParticleHypothesis,
-								 std::vector<unsigned int>&,
-								 PathLimit&, TimeLimit&,
-								 bool,const Trk::TrackingVolume*,
-								 std::vector<Trk::HitInfo>*&) const
+inline Trk::TrackParameters* Trk::IPropagator::propagateT( const EventContext&,
+                                                           const TrackParameters&,
+                                                           std::vector<DestSurf>&,
+                                                           PropDirection ,
+                                                           const MagneticFieldProperties&,
+                                                           ParticleHypothesis,
+                                                           std::vector<unsigned int>&,
+                                                           PathLimit&, TimeLimit&,
+                                                           bool,const Trk::TrackingVolume*,
+                                                           std::vector<Trk::HitInfo>*&) const
 {                  
   return nullptr;
 }
 
-inline  Trk::TrackParameters* Trk::IPropagator::propagateT( const TrackParameters& ,
-								 Trk::TargetSurfaces& ,
-								 PropDirection ,
-								 const MagneticFieldProperties& ,
-								 ParticleHypothesis ,
-								 Trk::TargetSurfaceVector& ,
-								 PathLimit& , TimeLimit& ,
-								 bool,std::vector<Trk::HitInfo>*& ) const
+inline  Trk::TrackParameters* Trk::IPropagator::propagateT( const EventContext&,
+                                                            const TrackParameters& ,
+                                                            Trk::TargetSurfaces& ,
+                                                            PropDirection ,
+                                                            const MagneticFieldProperties& ,
+                                                            ParticleHypothesis ,
+                                                            Trk::TargetSurfaceVector& ,
+                                                            PathLimit& , TimeLimit& ,
+                                                            bool,std::vector<Trk::HitInfo>*& ) const
 {
-  return nullptr;
+    return nullptr;
 }
 
-inline Trk::ExtrapolationCode Trk::IPropagator::propagate( Trk::ExCellCharged& ,
-							   Trk::TargetSurfaces&,
-							   Trk::TargetSurfaceVector& ) const
+inline Trk::ExtrapolationCode Trk::IPropagator::propagate( const EventContext&,
+                                                           Trk::ExCellCharged& ,
+                                                           Trk::TargetSurfaces&,
+                                                           Trk::TargetSurfaceVector& ) const
 {
-  return Trk::ExtrapolationCode::FailureConfiguration;
+    return Trk::ExtrapolationCode::FailureConfiguration;
 }         
 
-inline  Trk::TrackParameters* Trk::IPropagator::propagateM( const TrackParameters&,
-								 std::vector<DestSurf>&,
-								 PropDirection ,
-								 const MagneticFieldProperties&,
-								 ParticleHypothesis,
-								 std::vector<unsigned int>&,
-								 std::vector<const Trk::TrackStateOnSurface*>*&,
-								 std::vector<std::pair<const Trk::TrackParameters*,int> >*& , 
-								 double&,
-								 bool,
-								 bool,
-								 const Trk::TrackingVolume*,							      
-								 Trk::ExtrapolationCache*) const
+inline  Trk::TrackParameters* Trk::IPropagator::propagateM( const EventContext&,
+                                                            const TrackParameters&,
+                                                            std::vector<DestSurf>&,
+                                                            PropDirection ,
+                                                            const MagneticFieldProperties&,
+                                                            ParticleHypothesis,
+                                                            std::vector<unsigned int>&,
+                                                            std::vector<const Trk::TrackStateOnSurface*>*&,
+                                                            std::vector<std::pair<const Trk::TrackParameters*,int> >*& , 
+                                                            double&,
+                                                            bool,
+                                                            bool,
+                                                            const Trk::TrackingVolume*,                                                          
+                                                            Trk::ExtrapolationCache*) const
 {                  
-  return nullptr;
+    return nullptr;
 }
 
+
 /** a very simple propagation along a given path length */
-inline void Trk::IPropagator::propagateStep(const Amg::Vector3D&, 
+inline void Trk::IPropagator::propagateStep(const EventContext&,
+                                            const Amg::Vector3D&, 
                                             const Amg::Vector3D&, 
                                             double, 
                                             double, 
@@ -347,6 +553,356 @@ inline void Trk::IPropagator::propagateStep(const Amg::Vector3D&,
                                             const MagneticFieldProperties&) const {}
 
 
+
+/** [TrackParameters] new interfaces WITH EventContext ------------------------------------------ */
+/** temporarily default to old interfaces, taking the EventContext from GaudiHive */
+
+//  Propagation interface:
+//    The propagation method called by the TrkExtrapolator. The extrapolator
+//    is responsible for the underlying logic of which surface to go to.
+
+inline Trk::TrackParameters*
+Trk::IPropagator::propagate(  const Trk::TrackParameters&         parm,
+                              const Trk::Surface&                 sf,
+                              Trk::PropDirection                  dir,
+                              const BoundaryCheck&                bcheck,
+                              const Trk::MagneticFieldProperties& mprop,
+                              Trk::ParticleHypothesis             particle,
+                              bool                                returnCurv,
+                              const Trk::TrackingVolume*          tVol) const
+{
+    return propagate( Gaudi::Hive::currentContext(),
+                      parm,
+                      sf,
+                      dir,
+                      bcheck,
+                      mprop,
+                      particle,
+                      returnCurv,
+                      tVol);
+}
+
+        
+
+/** Propagation interface:
+         
+    The propagation method called by the TrkExtrapolator. The propagator
+    finds the closest surface.
+*/
+inline  Trk::TrackParameters*
+Trk::IPropagator::propagate( const Trk::TrackParameters&         parm,
+                             std::vector<Trk::DestSurf>&         sfs,
+                             Trk::PropDirection                  dir,
+                             const Trk::MagneticFieldProperties& mprop,
+                             Trk::ParticleHypothesis             particle,
+                             std::vector<unsigned int>&          solutions,
+                             double&                             path,
+                             bool                                usePathLim,
+                             bool                                returnCurv,
+                             const Trk::TrackingVolume*          tVol) const
+{
+    
+    return propagate( Gaudi::Hive::currentContext(),
+                      parm,
+                      sfs,
+                      dir,
+                      mprop,
+                      particle,
+                      solutions,
+                      path,
+                      usePathLim,
+                      returnCurv,
+                      tVol);
+}
+
+
+/** Propagation interface:
+         
+    The propagation method called by the TrkExtrapolator. The propagator
+    finds the closest surface. Timing included.
+*/
+inline Trk::TrackParameters*
+Trk::IPropagator::propagateT( const Trk::TrackParameters&         parm,
+                              std::vector<Trk::DestSurf>&         sfs,
+                              Trk::PropDirection                  dir,
+                              const Trk::MagneticFieldProperties& mprop,
+                              Trk::ParticleHypothesis             particle,
+                              std::vector<unsigned int>&          solutions,
+                              PathLimit&                          pathLim, TimeLimit& timeLim,
+                              bool                                returnCurv ,
+                              const Trk::TrackingVolume*          tVol,
+                              std::vector<Trk::HitInfo>*&         hitVector) const
+{
+    
+    return  propagateT( Gaudi::Hive::currentContext(),
+                        parm,
+                        sfs,
+                        dir,
+                        mprop,
+                        particle,
+                        solutions,
+                        pathLim, timeLim,
+                        returnCurv ,
+                        tVol,
+                        hitVector);
+}
+
+
+/** Propagation interface:
+         
+    The propagation method called by the TrkExtrapolator. The propagator
+    finds the closest surface. Timing included.
+*/
+inline Trk::TrackParameters*
+Trk::IPropagator::propagateT( const Trk::TrackParameters&         parm,
+                              Trk::TargetSurfaces&                sfs,
+                              Trk::PropDirection                  dir,
+                              const Trk::MagneticFieldProperties& mprop,
+                              Trk::ParticleHypothesis             particle,
+                              TargetSurfaceVector&                solutions,
+                              PathLimit&                          pathLim, TimeLimit& timeLim,
+                              bool                                returnCurv ,
+                              std::vector<Trk::HitInfo>*&         hitVector) const
+{
+    return propagateT( Gaudi::Hive::currentContext(),
+                       parm,
+                       sfs,
+                       dir,
+                       mprop,
+                       particle,
+                       solutions,
+                       pathLim, timeLim,
+                       returnCurv ,
+                       hitVector);
+}
+
+/** Propagation interface:
+         
+    The propagation method called by the TrkExEngine. All options included.
+*/
+inline Trk::ExtrapolationCode
+Trk::IPropagator::propagate( Trk::ExCellCharged&  eCell,
+                             Trk::TargetSurfaces& sfs,
+                             Trk::TargetSurfaceVector& solutions) const
+{
+    return  propagate( Gaudi::Hive::currentContext(),
+                       eCell,
+                       sfs,
+                       solutions);         
+}
+
+/** Propagation interface:
+         
+    The propagation method with internal material collection. The propagator
+    finds the closest surface. 
+*/
+inline  Trk::TrackParameters*
+Trk::IPropagator::propagateM( const Trk::TrackParameters&         parm,
+                              std::vector<Trk::DestSurf>&         sfs,
+                              Trk::PropDirection                  dir,
+                              const Trk::MagneticFieldProperties& mprop,
+                              Trk::ParticleHypothesis             particle,
+                              std::vector<unsigned int>&          solutions,
+                              std::vector<const Trk::TrackStateOnSurface*>*& matstates,
+                              std::vector<std::pair<const Trk::TrackParameters*,int> >*& intersections, 
+                              double&                             path,
+                              bool                                usePathLim,
+                              bool                                returnCurv,
+                              const Trk::TrackingVolume*          tVol,
+                              Trk::ExtrapolationCache*            cache) const
+{
+    return propagateM( Gaudi::Hive::currentContext(),
+                       parm,
+                       sfs,
+                       dir,
+                       mprop,
+                       particle,
+                       solutions,
+                       matstates,
+                       intersections, 
+                       path,
+                       usePathLim,
+                       returnCurv,
+                       tVol,
+                       cache);
+}
+
+         
+
+/** Propagation interface:
+         
+    The propagation method including the return of the TransportJacobian matrix.
+
+*/
+inline Trk::TrackParameters*
+Trk::IPropagator::propagate( const Trk::TrackParameters&         parm,
+                             const Trk::Surface&                 sf,
+                             Trk::PropDirection                  dir,
+                             const BoundaryCheck&                bcheck,
+                             const Trk::MagneticFieldProperties& mprop,
+                             TransportJacobian*&                 jacob,
+                             double&                             pathLength,
+                             Trk::ParticleHypothesis             particle,
+                             bool                                returnCurv,
+                             const Trk::TrackingVolume*          tVol) const
+{
+    return propagate( Gaudi::Hive::currentContext(),
+                      parm,
+                      sf,
+                      dir,
+                      bcheck,
+                      mprop,
+                      jacob,
+                      pathLength,
+                      particle,
+                      returnCurv,
+                      tVol);
+}
+
+       
+
+/** Propagation interface without Covariance matrix propagation
+    the pathlength has to be returned for eventual following propagateCovariance
+*/
+
+inline Trk::TrackParameters*
+Trk::IPropagator::propagateParameters( const Trk::TrackParameters&         parm,
+                                       const Trk::Surface&                 sf,
+                                       Trk::PropDirection                  dir,
+                                       const BoundaryCheck&                bcheck,
+                                       const Trk::MagneticFieldProperties& mprop,
+                                       Trk::ParticleHypothesis             particle,
+                                       bool                                returnCurv,
+                                       const Trk::TrackingVolume*          tVol) const
+{
+    return propagateParameters( Gaudi::Hive::currentContext(),
+                                parm,
+                                sf,
+                                dir,
+                                bcheck,
+                                mprop,
+                                particle=pion,
+                                returnCurv,
+                                tVol);
+}
+
+       
+inline Trk::TrackParameters*
+Trk::IPropagator::propagateParameters( const Trk::TrackParameters&         parm,
+                                       const Trk::Surface&                 sf,
+                                       Trk::PropDirection                  dir,
+                                       const BoundaryCheck&                bcheck,
+                                       const Trk::MagneticFieldProperties& mprop,
+                                       TransportJacobian*&                 jacob,
+                                       Trk::ParticleHypothesis             particle,
+                                       bool                                returnCurv,
+                                       const Trk::TrackingVolume*          tVol) const
+{
+    return propagateParameters( Gaudi::Hive::currentContext(),
+                                parm,
+                                sf,
+                                dir,
+                                bcheck,
+                                mprop,
+                                jacob,
+                                particle=pion,
+                                returnCurv,
+                                tVol);
+}
+
+       
+
+/** Intersection interface:
+         
+    The intersection interface might be used by the material service as well to estimate
+    the surfaces (sensitive and nonesensitive) while propagation
+*/
+inline const Trk::IntersectionSolution*
+Trk::IPropagator::intersect( const Trk::TrackParameters&         parm,
+                             const Trk::Surface&                 sf,
+                             const Trk::MagneticFieldProperties& mprop,
+                             Trk::ParticleHypothesis             particle,
+                             const Trk::TrackingVolume*          tVol) const
+{
+    return intersect( Gaudi::Hive::currentContext(),
+                      parm,
+                      sf,
+                      mprop,
+                      particle=pion,
+                      tVol);
+}
+
+
+/** Intersection and Intersector interface: 
+ */
+
+inline const Trk::TrackSurfaceIntersection*
+Trk::IPropagator::intersectSurface(const Trk::Surface&                 surface,
+                                   const TrackSurfaceIntersection*     trackIntersection,
+                                   const double                        qOverP,
+                                   const Trk::MagneticFieldProperties& mft,
+                                   Trk::ParticleHypothesis             particle) const
+{
+    return intersectSurface(Gaudi::Hive::currentContext(),
+                            surface,
+                            trackIntersection,
+                            qOverP,
+                            mft,
+                            particle);
+}
+
+ 
+
+/** GlobalPositions list interface:
+    This is used mostly in pattern recognition in the road finder, the propagation direction is intrinsically given
+    by the sign of the stepSize.
+         
+    To avoid memory fragmentation in multiple use of pattern recognition processes and respecting the possible iterative
+    filling of the positions list, the list of GlobalPositions is given by reference through the signature and a void 
+    method has been chosen.
+*/
+inline void
+Trk::IPropagator::globalPositions(std::list<Amg::Vector3D>&           positionslist, 
+                                  const Trk::TrackParameters&         parm,
+                                  const Trk::MagneticFieldProperties& mprop,
+                                  const CylinderBounds&               cylbo,
+                                  double                              stepSize,
+                                  Trk::ParticleHypothesis             particle,
+                                  const Trk::TrackingVolume*          tVol) const
+{
+    globalPositions(Gaudi::Hive::currentContext(),
+                    positionslist, 
+                    parm,
+                    mprop,
+                    cylbo,
+                    stepSize,
+                    particle=pion,
+                    tVol);
+}
+
+
+/** a very simple propagation along a given path length */
+inline void
+Trk::IPropagator::propagateStep(const Amg::Vector3D& inputPosition, 
+                                const Amg::Vector3D& inputMomentum, 
+                                double               charge, 
+                                double               step,
+                                Amg::Vector3D&       outputPosition, 
+                                Amg::Vector3D&       outputMomentum,
+                                const Trk::MagneticFieldProperties& mprop) const
+{
+    propagateStep(Gaudi::Hive::currentContext(),
+                  inputPosition, 
+                  inputMomentum, 
+                  charge, 
+                  step,
+                  outputPosition, 
+                  outputMomentum,
+                  mprop);
+}
+
+
+
 #endif // TRKEXINTERFACES_PROPAGATOR_H
 
 
diff --git a/Tracking/TrkExtrapolation/TrkExRungeKuttaIntersector/TrkExRungeKuttaIntersector/IntersectorWrapper.h b/Tracking/TrkExtrapolation/TrkExRungeKuttaIntersector/TrkExRungeKuttaIntersector/IntersectorWrapper.h
index f8329fd9fda632262b22467fe1e280f181d9460d..21d49044c66425ebb94244d638c8cbb49c77167f 100755
--- a/Tracking/TrkExtrapolation/TrkExRungeKuttaIntersector/TrkExRungeKuttaIntersector/IntersectorWrapper.h
+++ b/Tracking/TrkExtrapolation/TrkExRungeKuttaIntersector/TrkExRungeKuttaIntersector/IntersectorWrapper.h
@@ -21,7 +21,7 @@ namespace Trk
 class IIntersector;
 class TrackSurfaceIntersection;
 
-class IntersectorWrapper: public AthAlgTool,
+class IntersectorWrapper final: public AthAlgTool,
   virtual public IPropagator
   {
 
@@ -57,14 +57,15 @@ class IntersectorWrapper: public AthAlgTool,
       is responsible for the underlying logic of which surface to go to.
       */
     /// implemented
-    virtual  TrackParameters*      propagate( const TrackParameters& parm,
-                                              const Surface& sf,
-                                              PropDirection dir,
-                                              const BoundaryCheck&  bcheck,
+    virtual  TrackParameters*      propagate( const EventContext&     ctx,
+                                              const TrackParameters&  parm,
+                                              const Surface&          sf,
+                                              PropDirection           dir,
+                                              const BoundaryCheck&    bcheck,
                                               const MagneticFieldProperties& mprop,
-                                              ParticleHypothesis particle,
-                                              bool returnCurv,
-                                              const TrackingVolume*) const override;
+                                              ParticleHypothesis             particle,
+                                              bool                           returnCurv,
+                                              const TrackingVolume*) const   override final;
 
 
     /** Propagation interface:
@@ -72,32 +73,34 @@ class IntersectorWrapper: public AthAlgTool,
       The propagation method called by the TrkExtrapolator. The propagator
       finds the closest surface.
       */
-    virtual TrackParameters* propagate( const TrackParameters&,
-                                      std::vector<DestSurf>&,
-                                      PropDirection,
-                                      const MagneticFieldProperties&,
-                                      ParticleHypothesis,
-                                      std::vector<unsigned int>&,
-                                      double&,
-                                      bool,
-                                      bool,
-                                      const TrackingVolume*) const override{ return nullptr; }
+    virtual TrackParameters* propagate( const EventContext&,
+                                        const TrackParameters&,
+                                        std::vector<DestSurf>&,
+                                        PropDirection,
+                                        const MagneticFieldProperties&,
+                                        ParticleHypothesis,
+                                        std::vector<unsigned int>&,
+                                        double&,
+                                        bool,
+                                        bool,
+                                        const TrackingVolume*) const override{ return 0; }
 
     /** Propagation interface:
 
       The propagation method called by the TrkExtrapolator. The propagator
       finds the closest surface. Timing included.
       */
-    virtual  TrackParameters* propagateT( const TrackParameters&,
-                                       std::vector<DestSurf>&,
-                                       PropDirection,
-                                       const MagneticFieldProperties&,
-                                       ParticleHypothesis,
-                                       std::vector<unsigned int>&,
-                                       PathLimit&, TimeLimit&,
-                                       bool,
-                                       const TrackingVolume*,
-                                       std::vector<Trk::HitInfo>*&) const override{ return nullptr; }
+    virtual  TrackParameters* propagateT( const EventContext&,
+                                          const TrackParameters&,
+                                          std::vector<DestSurf>&,
+                                          PropDirection,
+                                          const MagneticFieldProperties&,
+                                          ParticleHypothesis,
+                                          std::vector<unsigned int>&,
+                                          PathLimit&, TimeLimit&,
+                                          bool,
+                                          const TrackingVolume*,
+                                          std::vector<Trk::HitInfo>*&) const override{ return 0; }
 
 
     /** Propagation interface:
@@ -106,41 +109,44 @@ class IntersectorWrapper: public AthAlgTool,
 
 */
     /// implemented
-    virtual  TrackParameters*      propagate( const TrackParameters&,
-                                           const Surface&,
-                                           PropDirection,
-                                           const BoundaryCheck& ,
-                                           const MagneticFieldProperties&,
-                                           TransportJacobian*&,
-                                           double&,
-                                           ParticleHypothesis,
-                                           bool,
-                                           const TrackingVolume*) const override;
-
+    virtual  TrackParameters*      propagate( const EventContext&          ctx,
+                                              const TrackParameters&,
+                                              const Surface&,
+                                              PropDirection,
+                                              const BoundaryCheck& ,
+                                              const MagneticFieldProperties&,
+                                              TransportJacobian*&,
+                                              double&,
+                                              ParticleHypothesis,
+                                              bool,
+                                              const TrackingVolume*) const override;
 
     /** Propagation interface without Covariance matrix propagation
       the pathlength has to be returned for eventual following propagateCovariance
       */
     /// implemented
-    virtual  TrackParameters*      propagateParameters( const TrackParameters& parm,
-                                                     const Surface& sf,
-                                                     PropDirection dir,
-                                                     const BoundaryCheck&  bcheck,
-                                                     const MagneticFieldProperties& mprop,
-                                                     ParticleHypothesis particle=pion,
-                                                     bool returnCurv = false,
-                                                     const TrackingVolume* tVol=nullptr) const override;
+    using Trk::IPropagator::propagateParameters;
+    virtual  TrackParameters*      propagateParameters( const EventContext&            ctx,
+                                                        const TrackParameters&         parm,
+                                                        const Surface&                 sf,
+                                                        PropDirection                  dir,
+                                                        const BoundaryCheck&           bcheck,
+                                                        const MagneticFieldProperties& mprop,
+                                                        ParticleHypothesis             particle   = pion,
+                                                        bool                           returnCurv = false,
+                                                        const TrackingVolume*          tVol       = nullptr) const override;
 
     /// implemented
-    virtual  TrackParameters*      propagateParameters( const TrackParameters& parm,
-                                                     const Surface& sf,
-                                                     PropDirection dir,
-                                                     const BoundaryCheck&  bcheck,
-                                                     const MagneticFieldProperties& mprop,
-                                                     TransportJacobian*&,
-                                                     ParticleHypothesis particle=pion,
-                                                     bool returnCurv = false,
-                                                     const TrackingVolume* tVol=nullptr) const override;
+    virtual  TrackParameters*      propagateParameters( const EventContext&            ctx,
+                                                        const TrackParameters&         parm,
+                                                        const Surface&                 sf,
+                                                        PropDirection                  dir,
+                                                        const BoundaryCheck&           bcheck,
+                                                        const MagneticFieldProperties& mprop,
+                                                        TransportJacobian*&,
+                                                        ParticleHypothesis             particle   = pion,
+                                                        bool                           returnCurv = false,
+                                                        const TrackingVolume*          tVol       = nullptr) const override;
 
 
     /** Intersection interface:
@@ -148,11 +154,13 @@ class IntersectorWrapper: public AthAlgTool,
       The intersection interface might be used by the material service as well to estimate
       the surfaces (sensitive and nonesensitive) while propagation
       */
-    virtual IntersectionSolution* intersect( const TrackParameters& parm,
-                                             const Surface& sf,
-                                             const MagneticFieldProperties& mprop,
-                                             ParticleHypothesis particle=pion,
-                                             const TrackingVolume* tVol=nullptr) const override;
+    using Trk::IPropagator::intersect;
+    virtual const IntersectionSolution* intersect( const EventContext&            ctx,
+                                                   const TrackParameters&         parm,
+                                                   const Surface&                 sf,
+                                                   const MagneticFieldProperties& mprop,
+                                                   ParticleHypothesis             particle = pion,
+                                                   const TrackingVolume*          tVol     = nullptr) const override;
 
     /** GlobalPositions list interface:
       This is used mostly in pattern recognition in the road finder, the propagation direction is intrinsically given
@@ -162,20 +170,24 @@ class IntersectorWrapper: public AthAlgTool,
       filling of the positions list, the list of GlobalPositions is given by reference through the signature and a void
       method has been chosen.
       */
-    virtual void globalPositions(std::list<Amg::Vector3D>& positionslist, 
-                         const TrackParameters& parm,
-                         const MagneticFieldProperties& mprop,
-                         const CylinderBounds& cylbo,
-                         double stepSize,
-                         ParticleHypothesis particle=pion,
-                         const TrackingVolume* tVol=nullptr) const override;
+    using Trk::IPropagator::globalPositions;
+    virtual void globalPositions(const EventContext&            ctx,
+                                 std::list<Amg::Vector3D>&      positionslist, 
+                                 const TrackParameters&         parm,
+                                 const MagneticFieldProperties& mprop,
+                                 const CylinderBounds&          cylbo,
+                                 double                         stepSize,
+                                 ParticleHypothesis             particle = pion,
+                                 const TrackingVolume*          tVol     = nullptr) const override;
 
     //placeholder for compatibility with new interface                                                                                                                        
-    virtual TrackSurfaceIntersection* intersectSurface(const Surface&,
-                                                       const TrackSurfaceIntersection*,
-                                                       const double,
-                                                       const MagneticFieldProperties&,
-                                                       ParticleHypothesis) const override{return nullptr;}
+    using Trk::IPropagator::intersectSurface;
+    virtual const TrackSurfaceIntersection* intersectSurface(const EventContext&,
+                                                             const Surface&,
+                                                             const TrackSurfaceIntersection*,
+                                                             const double,
+                                                             const MagneticFieldProperties&,
+                                                             ParticleHypothesis) const override{return nullptr;}
 
     /** Validation Action:
       Can be implemented optionally, outside access to internal validation steps */
diff --git a/Tracking/TrkExtrapolation/TrkExRungeKuttaIntersector/src/IntersectorWrapper.cxx b/Tracking/TrkExtrapolation/TrkExRungeKuttaIntersector/src/IntersectorWrapper.cxx
index d9c6aed068b3daa2aaefc6ec182d7a828b832cb8..4eb06a0473907dbe8336c6f06612e82e75c35244 100755
--- a/Tracking/TrkExtrapolation/TrkExRungeKuttaIntersector/src/IntersectorWrapper.cxx
+++ b/Tracking/TrkExtrapolation/TrkExRungeKuttaIntersector/src/IntersectorWrapper.cxx
@@ -78,7 +78,8 @@ IntersectorWrapper::propagate (const NeutralParameters&		parameters,
 }
 
 TrackParameters*
-IntersectorWrapper::propagate (const TrackParameters&		parameters,
+IntersectorWrapper::propagate (const EventContext&              /*ctx*/,
+                               const TrackParameters&		parameters,
                                const Surface&			surface,
                                PropDirection			dir,
                                const BoundaryCheck& 			boundsCheck,
@@ -94,7 +95,8 @@ IntersectorWrapper::propagate (const TrackParameters&		parameters,
 }
 
 TrackParameters*
-IntersectorWrapper::propagate (const TrackParameters&		parameters,
+IntersectorWrapper::propagate (const EventContext&              /*ctx*/,
+                               const TrackParameters&		parameters,
                                const Surface&			surface,
                                PropDirection			dir,
                                const BoundaryCheck& 			boundsCheck,
@@ -112,7 +114,8 @@ IntersectorWrapper::propagate (const TrackParameters&		parameters,
 }
 
 TrackParameters*
-IntersectorWrapper::propagateParameters (const TrackParameters&		parameters,
+IntersectorWrapper::propagateParameters (const EventContext&              /*ctx*/,
+                                         const TrackParameters&		parameters,
                                          const Surface&			surface,
                                          PropDirection			dir,
                                          const BoundaryCheck& 			boundsCheck,
@@ -129,7 +132,8 @@ IntersectorWrapper::propagateParameters (const TrackParameters&		parameters,
 }
 
 TrackParameters*
-IntersectorWrapper::propagateParameters (const TrackParameters&		parameters,
+IntersectorWrapper::propagateParameters (const EventContext&              /*ctx*/,
+                                         const TrackParameters&		parameters,
                                          const Surface&			surface,
                                          PropDirection			dir,
                                          const BoundaryCheck& 			boundsCheck,
@@ -145,8 +149,9 @@ IntersectorWrapper::propagateParameters (const TrackParameters&		parameters,
   return cache.m_parameters;
 }
 
-IntersectionSolution*
-IntersectorWrapper::intersect (const TrackParameters&		parameters,
+const IntersectionSolution*
+IntersectorWrapper::intersect (const EventContext&              /*ctx*/,
+                               const TrackParameters&		parameters,
                                const Surface&			surface,
                                const MagneticFieldProperties&	/*magProperties*/,
                                ParticleHypothesis		/*particle*/,
@@ -162,7 +167,8 @@ IntersectorWrapper::intersect (const TrackParameters&		parameters,
 }
 
 void
-IntersectorWrapper::globalPositions (std::list<Amg::Vector3D>&,
+IntersectorWrapper::globalPositions (const EventContext&              /*ctx*/,
+                                     std::list<Amg::Vector3D>&,
                                      const TrackParameters&,
                                      const MagneticFieldProperties&,
                                      const CylinderBounds&,
diff --git a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/CMakeLists.txt b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/CMakeLists.txt
index c18d93e7f8560747081b57e46cd241acd1547550..436c705e19e5f35cd5d867923726be5b6a590b0d 100644
--- a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/CMakeLists.txt
+++ b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/CMakeLists.txt
@@ -18,13 +18,16 @@ atlas_depends_on_subdirs( PUBLIC
                           Tracking/TrkDetDescr/TrkGeometry
                           Tracking/TrkDetDescr/TrkSurfaces
                           Tracking/TrkEvent/TrkPatternParameters
-                          Tracking/TrkExtrapolation/TrkExUtils )
+                          Tracking/TrkExtrapolation/TrkExUtils 
+			  MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions
+)
 
 # Component(s) in the package:
 atlas_add_component( TrkExRungeKuttaPropagator
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps GaudiKernel MagFieldInterfaces TrkEventPrimitives TrkNeutralParameters TrkParameters TrkExInterfaces TrkGeometry TrkSurfaces TrkPatternParameters TrkExUtils )
+                     LINK_LIBRARIES AthenaBaseComps GaudiKernel MagFieldInterfaces TrkEventPrimitives TrkNeutralParameters TrkParameters TrkExInterfaces TrkGeometry TrkSurfaces TrkPatternParameters TrkExUtils MagFieldElements MagFieldConditions)
 
 # Install files from the package:
 atlas_install_headers( TrkExRungeKuttaPropagator )
diff --git a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/TrkExRungeKuttaPropagator/RungeKuttaPropagator.h b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/TrkExRungeKuttaPropagator/RungeKuttaPropagator.h
index 15fc975c6d7a8afe56da84eb1c6e91703099045b..252dbb9cdc2b2b66bc34dd1a4b62254f5fab0e22 100755
--- a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/TrkExRungeKuttaPropagator/RungeKuttaPropagator.h
+++ b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/TrkExRungeKuttaPropagator/RungeKuttaPropagator.h
@@ -20,463 +20,517 @@
 #include "TrkParameters/TrackParameters.h"
 #include "TrkNeutralParameters/NeutralParameters.h"
 
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
+
 namespace Trk {
 
-class Surface                  ;
-class MagneticFieldProperties  ;
-class CylinderBounds           ;
-class CylinderSurface          ;
-class PatternTrackParameters   ;
+    class Surface                  ;
+    class MagneticFieldProperties  ;
+    class CylinderBounds           ;
+    class CylinderSurface          ;
+    class PatternTrackParameters   ;
 
 /**
-  @class RungeKuttaPropagator
-
-  Trk::RungeKuttaPropagator is algorithm for track parameters propagation through
-  magnetic field with or without jacobian of transformation. This algorithm
-  contains three steps.
-
-  1.The first step of the algorithm is track parameters transformation from
-  local presentation for given start surface to global Runge Kutta coordinates.
-
-  2.The second step is propagation through magnetic field with or without jacobian.
-
-  3.Third step is transformation from global Runge Kutta presentation to local
-  presentation of given output surface.
-
-
-  AtaPlane    AtaStraightLine      AtaDisc       AtaCylinder      Perigee
-  |               |               |               |              |
-  |               |               |               |              |
-  V               V               V               V              V 
-  ----------------------------------------------------------------- 
-  |              Local->Global transformation
-  V
-  Global position (Runge Kutta presentation)
-  |
-  |
-  Propagation to next surface with or without jacobian
-  using Nystroem algorithm 
-  (See Handbook Net. Bur. of Standards, procedure 25.5.20)
-  |
-  V              Global->Local transformation
-  ----------------------------------------------------------------
-  |               |               |               |              |
-  |               |               |               |              |
-  V               V               V               V              V
-  PlaneSurface StraightLineSurface DiscSurface CylinderSurface PerigeeSurface 
-
-  For propagation using Runge Kutta method we use global coordinate, direction,
-  inverse momentum and Jacobian of transformation. All this parameters we save 
-  in array P[42].
-  /dL0    /dL1    /dPhi   /dThe   /dCM
-  X  ->P[0]  dX /   P[ 7]   P[14]   P[21]   P[28]   P[35]  
-  Y  ->P[1]  dY /   P[ 8]   P[15]   P[22]   P[29]   P[36]  
-  Z  ->P[2]  dZ /   P[ 9]   P[16]   P[23]   P[30]   P[37]   
-  Ax ->P[3]  dAx/   P[10]   P[17]   P[24]   P[31]   P[38]  
-  Ay ->P[4]  dAy/   P[11]   P[18]   P[25]   P[32]   P[39]  
-  Az ->P[5]  dAz/   P[12]   P[19]   P[26]   P[33]   P[40]  
-  CM ->P[6]  dCM/   P[13]   P[20]   P[27]   P[34]   P[41] 
-
-  where 
-  in case local presentation 
-
-  L0  - first  local coordinate  (surface dependent)
-  L1  - second local coordinate  (surface dependent)
-  Phi - Azimuthal angle
-  The - Polar     angle
-  CM  - charge/momentum
-
-  in case global presentation
-
-  X   - global x-coordinate        = surface dependent
-  Y   - global y-coordinate        = surface dependent
-  Z   - global z-coordinate        = sutface dependent
-  Ax  - direction cosine to x-axis = Sin(The)*Cos(Phi)
-  Ay  - direction cosine to y-axis = Sin(The)*Sin(Phi)
-  Az  - direction cosine to z-axis = Cos(The)
-  CM  - charge/momentum            = local CM
-
-Comment: 
-if pointer to const *  = 0 algorithm will propagate track 
-parameters and jacobian of transformation according straight line model
-
-
-@author Igor.Gavrilenko@cern.ch     
-  */
-
-  class RungeKuttaPropagator final: public AthAlgTool, virtual public IPropagator,
-  virtual public IPatternParametersPropagator
-{
-  /////////////////////////////////////////////////////////////////////////////////
-  // Public methods:
-  /////////////////////////////////////////////////////////////////////////////////
-
-public:
-
-  RungeKuttaPropagator(const std::string&,const std::string&,const IInterface*);
-
-  virtual ~RungeKuttaPropagator ();
-
-  /** AlgTool initailize method.*/
-  virtual StatusCode initialize() override final;
-
-  /** AlgTool finalize method */
-  virtual StatusCode finalize() override final;
-
-  /** Main propagation mehtod NeutralParameters */
-
- virtual NeutralParameters* propagate
-    (const NeutralParameters        &,
-     const Surface                  &,
-     PropDirection                   ,
-     const BoundaryCheck            &,
-     bool                            ) const override final;
-
-  /** Main propagation mehtod without transport jacobian production*/
-
-  virtual  TrackParameters*           propagate
-    (const TrackParameters          &,
-     const Surface                  &,
-     const PropDirection             ,
-     const BoundaryCheck            &,
-     const MagneticFieldProperties  &, 
-     ParticleHypothesis              ,
-     bool                            ,
-     const TrackingVolume*           ) const override final;
-
-  /** Main propagation mehtod with transport jacobian production*/
-
-  virtual  TrackParameters*           propagate
-    (const TrackParameters          &,
-     const Surface                  &,
-     const PropDirection             ,
-     const BoundaryCheck            &,
-     const MagneticFieldProperties  &, 
-     TransportJacobian             *&,
-     double                         &,
-     ParticleHypothesis              ,
-     bool                            ,
-     const TrackingVolume*            ) const override final;
-
-  /** The propagation method finds the closest surface */
-
-  virtual TrackParameters*           propagate
-    (const TrackParameters         &,
-     std::vector<DestSurf>         &,
-     PropDirection                  ,
-     const MagneticFieldProperties &,
-     ParticleHypothesis             ,
-     std::vector<unsigned int>     &,
-     double                        &,
-     bool                           ,
-     bool                           ,
-     const TrackingVolume*          ) const override final;
-
-  /** Main propagation mehtod for parameters only without transport jacobian productio*/
-
-  virtual  TrackParameters*           propagateParameters
-    (const TrackParameters          &,
-     const Surface                  &,
-     const PropDirection             ,
-     const BoundaryCheck            &,
-     const MagneticFieldProperties  &, 
-     ParticleHypothesis              ,
-     bool                            ,
-     const TrackingVolume*          ) const override final;
-
-
-  /** Main propagation mehtod for parameters only with transport jacobian productio*/
-
-  virtual  TrackParameters*           propagateParameters
-    (const TrackParameters          &,
-     const Surface                  &,
-     const PropDirection             ,
-     const BoundaryCheck            &,
-     const MagneticFieldProperties  &, 
-     TransportJacobian             *&,
-     ParticleHypothesis              ,
-     bool                            ,
-     const TrackingVolume*           ) const override final;
-
-  /** Global position together with direction of the trajectory on the surface */
-
-  virtual IntersectionSolution*      intersect
-    (const TrackParameters          &,
-     const Surface                  &,
-     const MagneticFieldProperties  &, 
-     ParticleHypothesis particle=pion, 
-     const TrackingVolume*   tvol=nullptr  ) const override final;
-
-  /** GlobalPositions list interface:*/
-
-  virtual void globalPositions
-    (std::list<Amg::Vector3D>       &,
-     const TrackParameters          &,
-     const MagneticFieldProperties  &,
-     const CylinderBounds&           ,
-     double                          ,
-     ParticleHypothesis particle=pion,
-     const TrackingVolume* tvol=nullptr    ) const override final;
-
- /////////////////////////////////////////////////////////////////////////////////
-  // Public methods for Trk::PatternTrackParameters (from IPattern'Propagator)
-  /////////////////////////////////////////////////////////////////////////////////
-
-  /** Main propagation method */
-
-  using IPropagator::propagate;
-  virtual bool propagate
-    (PatternTrackParameters         &,
-     const Surface                  &,
-     PatternTrackParameters         &,
-     PropDirection                   ,
-     const MagneticFieldProperties  &, 
-     ParticleHypothesis particle=pion) const  override final;
-
-  /** Main propagation mehtod with step to surface calculation*/
-
-  virtual bool propagate
-    (PatternTrackParameters         &,
-     const Surface                  &,
-     PatternTrackParameters         &,
-     PropDirection                   ,
-     const MagneticFieldProperties  &,
-     double                         &,
-     ParticleHypothesis particle=pion) const  override final;
-
-  /** Main propagation mehtod for parameters only */
-
-  virtual bool propagateParameters
-    (PatternTrackParameters         &,
-     const Surface                  &,
-     PatternTrackParameters         &,
-     PropDirection                   ,
-     const MagneticFieldProperties  &,
-     ParticleHypothesis particle=pion) const  override final;
-
-  /** Main propagation mehtod for parameters only with step to surface calculation*/
-
-  virtual bool propagateParameters
-    (PatternTrackParameters         &,
-     const Surface                  &,
-     PatternTrackParameters         &,
-     PropDirection                   ,
-     const MagneticFieldProperties  &,
-     double                         &,
-     ParticleHypothesis particle=pion) const  override final;
-
-  /** GlobalPositions list interface:*/
-
-  virtual void globalPositions
-    (std::list<Amg::Vector3D>       &,
-     const PatternTrackParameters   &,
-     const MagneticFieldProperties  &,
-     const CylinderBounds           &,
-     double                          ,
-     ParticleHypothesis particle=pion) const  override final;
-
-  /** GlobalPostions and steps for set surfaces */
-
-  virtual void globalPositions
-    (const PatternTrackParameters                 &,
-     std::list<const Surface*>                    &,
-     std::list< std::pair<Amg::Vector3D,double> > &,
-     const MagneticFieldProperties                &,
-     ParticleHypothesis particle=pion              ) const  override final;
-
-  /** a very simple propagation along a given path length */
-
-  virtual void propagateStep(const Amg::Vector3D& inputPosition, 
-                             const Amg::Vector3D& inputMomentum, 
-                             double charge, 
-                             double step,
-                             Amg::Vector3D& outputPosition, 
-                             Amg::Vector3D& outputMomentum,
-                             const MagneticFieldProperties& mprop) const override final;
-
-private:
-
-  struct Cache{
-    double  m_direction                                ;
-    double  m_step                                     ;
-    double  m_maxPath                            =10000;
-    double  m_field[3]                                 ;
-    bool    m_maxPathLimit                       =false;
-    bool    m_mcondition                         =false;
-    bool    m_solenoid                            =true;
-    bool    m_needgradient                       =false;  
-    bool    m_newfield                            =true;
-  };
-
-  /////////////////////////////////////////////////////////////////////////////////
-  // Private methods:
-  /////////////////////////////////////////////////////////////////////////////////
-
-  /** Test quality Jacobian calculation */
-
-  void JacobianTest
-    (const TrackParameters        &,
-     const Surface                &,
-     const MagneticFieldProperties&) const;
+<<<<<<< HEAD
+   @class RungeKuttaPropagator
+
+   Trk::RungeKuttaPropagator is algorithm for track parameters propagation through
+   magnetic field with or without jacobian of transformation. This algorithm
+   contains three steps.
+
+   1.The first step of the algorithm is track parameters transformation from
+   local presentation for given start surface to global Runge Kutta coordinates.
+
+   2.The second step is propagation through magnetic field with or without jacobian.
+
+   3.Third step is transformation from global Runge Kutta presentation to local
+   presentation of given output surface.
+
+
+   AtaPlane    AtaStraightLine      AtaDisc       AtaCylinder      Perigee
+   |               |               |               |              |
+   |               |               |               |              |
+   V               V               V               V              V 
+   ----------------------------------------------------------------- 
+   |              Local->Global transformation
+   V
+   Global position (Runge Kutta presentation)
+   |
+   |
+   Propagation to next surface with or without jacobian
+   using Nystroem algorithm 
+   (See Handbook Net. Bur. of Standards, procedure 25.5.20)
+   |
+   V              Global->Local transformation
+   ----------------------------------------------------------------
+   |               |               |               |              |
+   |               |               |               |              |
+   V               V               V               V              V
+   PlaneSurface StraightLineSurface DiscSurface CylinderSurface PerigeeSurface 
+
+   For propagation using Runge Kutta method we use global coordinate, direction,
+   inverse momentum and Jacobian of transformation. All this parameters we save 
+   in array P[42].
+   /dL0    /dL1    /dPhi   /dThe   /dCM
+   X  ->P[0]  dX /   P[ 7]   P[14]   P[21]   P[28]   P[35]  
+   Y  ->P[1]  dY /   P[ 8]   P[15]   P[22]   P[29]   P[36]  
+   Z  ->P[2]  dZ /   P[ 9]   P[16]   P[23]   P[30]   P[37]   
+   Ax ->P[3]  dAx/   P[10]   P[17]   P[24]   P[31]   P[38]  
+   Ay ->P[4]  dAy/   P[11]   P[18]   P[25]   P[32]   P[39]  
+   Az ->P[5]  dAz/   P[12]   P[19]   P[26]   P[33]   P[40]  
+   CM ->P[6]  dCM/   P[13]   P[20]   P[27]   P[34]   P[41] 
+
+   where 
+   in case local presentation 
+
+   L0  - first  local coordinate  (surface dependent)
+   L1  - second local coordinate  (surface dependent)
+   Phi - Azimuthal angle
+   The - Polar     angle
+   CM  - charge/momentum
+
+   in case global presentation
+
+   X   - global x-coordinate        = surface dependent
+   Y   - global y-coordinate        = surface dependent
+   Z   - global z-coordinate        = sutface dependent
+   Ax  - direction cosine to x-axis = Sin(The)*Cos(Phi)
+   Ay  - direction cosine to y-axis = Sin(The)*Sin(Phi)
+   Az  - direction cosine to z-axis = Cos(The)
+   CM  - charge/momentum            = local CM
+
+   Comment: 
+   if pointer to const *  = 0 algorithm will propagate track 
+   parameters and jacobian of transformation according straight line model
+
+
+   @author Igor.Gavrilenko@cern.ch     
+*/
+
+    class RungeKuttaPropagator final: public AthAlgTool, virtual public IPropagator,
+                                      virtual public IPatternParametersPropagator
+    {
+        /////////////////////////////////////////////////////////////////////////////////
+        // Public methods:
+        /////////////////////////////////////////////////////////////////////////////////
+
+    public:
+        using IPropagator::intersect;
+        using IPropagator::propagate;
+        using IPropagator::propagateParameters;
+        using IPropagator::globalPositions;
+        using IPropagator::propagateStep;
+        using IPropagator::intersectSurface;
+        using IPatternParametersPropagator::propagate;
+        using IPatternParametersPropagator::propagateParameters;
+        using IPatternParametersPropagator::globalPositions;
+
+        RungeKuttaPropagator(const std::string&,const std::string&,const IInterface*);
+
+        virtual ~RungeKuttaPropagator ();
+
+        /** AlgTool initailize method.*/
+        virtual StatusCode initialize() override final;
+
+        /** AlgTool finalize method */
+        virtual StatusCode finalize() override final;
+
+        /** Main propagation mehtod NeutralParameters */
+
+        virtual NeutralParameters* propagate
+        (const NeutralParameters        &,
+         const Surface                  &,
+         PropDirection                   ,
+         const BoundaryCheck            &,
+         bool                            ) const override final;
+
+        /** Main propagation mehtod without transport jacobian production*/
+
+        virtual  TrackParameters*           propagate
+        (const EventContext&          ctx,
+         const TrackParameters          &,
+         const Surface                  &,
+         const PropDirection             ,
+         const BoundaryCheck            &,
+         const MagneticFieldProperties  &, 
+         ParticleHypothesis              ,
+         bool                            ,
+         const TrackingVolume*           ) const override final;
+
+        /** Main propagation mehtod with transport jacobian production*/
+
+        virtual  TrackParameters*           propagate
+        (const EventContext&          ctx,
+         const TrackParameters          &,
+         const Surface                  &,
+         const PropDirection             ,
+         const BoundaryCheck            &,
+         const MagneticFieldProperties  &, 
+         TransportJacobian             *&,
+         double                         &,
+         ParticleHypothesis              ,
+         bool                            ,
+         const TrackingVolume*            ) const override final;
+
+        /** The propagation method finds the closest surface */
+
+        virtual TrackParameters*           propagate
+        (const EventContext&          ctx,
+         const TrackParameters         &,
+         std::vector<DestSurf>         &,
+         PropDirection                  ,
+         const MagneticFieldProperties &,
+         ParticleHypothesis             ,
+         std::vector<unsigned int>     &,
+         double                        &,
+         bool                           ,
+         bool                           ,
+         const TrackingVolume*          ) const override final;
+
+        /** Main propagation mehtod for parameters only without transport jacobian productio*/
+
+        virtual  TrackParameters*           propagateParameters
+        (const EventContext&          ctx,
+         const TrackParameters          &,
+         const Surface                  &,
+         const PropDirection             ,
+         const BoundaryCheck            &,
+         const MagneticFieldProperties  &, 
+         ParticleHypothesis              ,
+         bool                            ,
+         const TrackingVolume*          ) const override final;
+
+
+        /** Main propagation mehtod for parameters only with transport jacobian productio*/
+
+        virtual  TrackParameters*           propagateParameters
+        (const EventContext&          ctx,
+         const TrackParameters          &,
+         const Surface                  &,
+         const PropDirection             ,
+         const BoundaryCheck            &,
+         const MagneticFieldProperties  &, 
+         TransportJacobian             *&,
+         ParticleHypothesis              ,
+         bool                            ,
+         const TrackingVolume*           ) const override final;
+
+        /** Global position together with direction of the trajectory on the surface */
+
+        virtual const IntersectionSolution*      intersect
+        (const EventContext&          ctx,
+         const TrackParameters          &,
+         const Surface                  &,
+         const MagneticFieldProperties  &, 
+         ParticleHypothesis particle=pion, 
+         const TrackingVolume*   tvol=nullptr  ) const override final;
+
+        /** GlobalPositions list interface:*/
+
+        virtual void globalPositions
+        (const EventContext&          ctx,
+         std::list<Amg::Vector3D>       &,
+         const TrackParameters          &,
+         const MagneticFieldProperties  &,
+         const CylinderBounds&           ,
+         double                          ,
+         ParticleHypothesis particle=pion,
+         const TrackingVolume* tvol=nullptr    ) const override final;
+
+        /////////////////////////////////////////////////////////////////////////////////
+        // Public methods for Trk::PatternTrackParameters (from IPattern'Propagator)
+        /////////////////////////////////////////////////////////////////////////////////
+
+        /** Main propagation method */
+
+        virtual bool propagate
+        (const EventContext&          ctx,
+         PatternTrackParameters         &,
+         const Surface                  &,
+         PatternTrackParameters         &,
+         PropDirection                   ,
+         const MagneticFieldProperties  &, 
+         ParticleHypothesis particle=pion) const  override final;
+
+        /** Main propagation mehtod with step to surface calculation*/
+
+        virtual bool propagate
+        (const EventContext&          ctx,
+         PatternTrackParameters         &,
+         const Surface                  &,
+         PatternTrackParameters         &,
+         PropDirection                   ,
+         const MagneticFieldProperties  &,
+         double                         &,
+         ParticleHypothesis particle=pion) const  override final;
+
+        /** Main propagation mehtod for parameters only */
+
+        virtual bool propagateParameters
+        (const EventContext&          ctx,
+         PatternTrackParameters         &,
+         const Surface                  &,
+         PatternTrackParameters         &,
+         PropDirection                   ,
+         const MagneticFieldProperties  &,
+         ParticleHypothesis particle=pion) const  override final;
+
+        /** Main propagation mehtod for parameters only with step to surface calculation*/
+        virtual bool propagateParameters
+        (const EventContext&          ctx,
+         PatternTrackParameters         &,
+         const Surface                  &,
+         PatternTrackParameters         &,
+         PropDirection                   ,
+         const MagneticFieldProperties  &,
+         double                         &,
+         ParticleHypothesis particle=pion) const  override final;
+
+        /** GlobalPositions list interface:*/
+
+        virtual void globalPositions
+        (const EventContext&          ctx,
+         std::list<Amg::Vector3D>       &,
+         const PatternTrackParameters   &,
+         const MagneticFieldProperties  &,
+         const CylinderBounds           &,
+         double                          ,
+         ParticleHypothesis particle=pion) const  override final;
+
+        /** GlobalPostions and steps for set surfaces */
+
+        virtual void globalPositions
+        (const EventContext&          ctx,
+         const PatternTrackParameters                 &,
+         std::list<const Surface*>                    &,
+         std::list< std::pair<Amg::Vector3D,double> > &,
+         const MagneticFieldProperties                &,
+         ParticleHypothesis particle=pion              ) const  override final;
+
+        /** a very simple propagation along a given path length */
+
+        virtual void propagateStep(const EventContext&          ctx,
+                                   const Amg::Vector3D& inputPosition, 
+                                   const Amg::Vector3D& inputMomentum, 
+                                   double charge, 
+                                   double step,
+                                   Amg::Vector3D& outputPosition, 
+                                   Amg::Vector3D& outputMomentum,
+                                   const MagneticFieldProperties& mprop) const override final;
+
+    private:
+
+        struct Cache{
+            double  m_direction;
+            double  m_step;
+            double  m_maxPath                            = 10000;
+            double  m_field[3];
+            bool    m_maxPathLimit                       = false;
+            bool    m_mcondition                         = false;
+            bool    m_solenoid                           = true;
+            bool    m_needgradient                       = false;  
+            bool    m_newfield                           = true;
+
+            MagField::AtlasFieldCache    m_fieldCache;
+        };
+
+
+        /////////////////////////////////////////////////////////////////////////////////
+        // Private methods:
+        /////////////////////////////////////////////////////////////////////////////////
+
+        /** Test quality Jacobian calculation */
+
+        void JacobianTest
+        (const TrackParameters        &,
+         const Surface                &,
+         const MagneticFieldProperties&) const;
 
  
-  /** Internal RungeKutta propagation method for charge track parameters*/   
-
-    TrackParameters*      propagateRungeKutta
-    (Cache& cache                  ,
-     bool                          ,
-     const TrackParameters        &,
-     const Surface                &,
-     const PropDirection           ,
-     const BoundaryCheck&                 ,
-     const MagneticFieldProperties&,
-     double                       *,
-     bool                returnCurv) const;
-
-  /** Internal RungeKutta propagation method for neutral track parameters*/   
-
-   NeutralParameters*    propagateStraightLine
-    (Cache& cache                  ,
-     bool                          ,
-     const NeutralParameters      &,
-     const Surface                &,
-     const PropDirection           ,
-     const BoundaryCheck&                 ,
-     double                       *,
-     bool                returnCurv) const;
-
-  /** Internal RungeKutta propagation method */
-
-  bool propagateRungeKutta
-    (Cache& cache                  ,
-     bool                          ,
-     PatternTrackParameters       &,
-     const Surface                &,
-     PatternTrackParameters       &,
-     PropDirection                 ,
-     const MagneticFieldProperties&,
-     double                       &) const;
-
-  /** Internal RungeKutta propagation method for propation with jacobian*/     
-
-  bool propagateWithJacobian
-    (Cache& cache                  , 
-     bool                          ,
-     int                           ,
-     double                       *,
-     double                       *,
-     double                       &) const;
-
-  /** Propagation methods runge kutta step*/
-
-  double rungeKuttaStep  
-    (Cache& cache,
-     bool                          ,
-     double                        ,
-     double                       *,
-     bool                         &) const;
-
-  /** Propagation methods runge kutta step*/
-
-  double rungeKuttaStepWithGradient  
-    (Cache& cache                  ,
-     double                        ,
-     double                       *,
-     bool                         &) const;
-
-  /** Propagation methods straight line step*/
-
-  double straightLineStep
-    (bool   ,     
-     double ,
-     double*) const;
-
-  /** Test new propagation to cylinder boundary */
-
-  bool newCrossPoint
-    (const CylinderSurface&,
-     const double         *,
-     const double         *) const;
-
-  /** Step estimator with directions correction */
-
-  double stepEstimatorWithCurvature(Cache& cache,int,double*,const double*,bool&) const;
-
-  /** Step reduction */
-  double stepReduction(const double*) const;
-
-  /** Build new track parameters without propagation */
-
-  TrackParameters*  buildTrackParametersWithoutPropagation
-    (const TrackParameters &,double*) const;
-
-  NeutralParameters*  buildTrackParametersWithoutPropagation
-    (const NeutralParameters&,double*) const;
-
-  void globalOneSidePositions
-    (Cache& cache                   ,
-     std::list<Amg::Vector3D>       &,
-     const double                   *,
-     const MagneticFieldProperties  &,
-     const CylinderBounds           &,
-     double                          ,
-     ParticleHypothesis particle=pion) const;
-
-  void globalTwoSidePositions
-    (Cache& cache                   ,
-     std::list<Amg::Vector3D>       &,
-     const double                   *,
-     const MagneticFieldProperties  &,
-     const CylinderBounds           &,
-     double                          ,
-     ParticleHypothesis particle=pion) const;
-
-  Trk::TrackParameters* crossPoint
-    (const TrackParameters    &,
-     std::vector<DestSurf>    &,
-     std::vector<unsigned int>&,
-     double                   *,
-     std::pair<double,int>    &) const;
-
-  void getField        (Cache& cache, double*,double*        ) const;
-  void getFieldGradient(Cache& cache, double*,double*,double*) const;
-
-  //placeholder for compatibility with new interface
-  virtual
-  TrackSurfaceIntersection* intersectSurface(const Surface&,
-                                             const TrackSurfaceIntersection*,
-                                             const double,
-                                             const MagneticFieldProperties&,
-                                             ParticleHypothesis) const override
-  {return nullptr;}
-
-  /////////////////////////////////////////////////////////////////////////////////
-  // Private data members: 
-  /////////////////////////////////////////////////////////////////////////////////
-
-  double m_dlt                                               ;  // accuracy parameter
-  double m_helixStep                                         ;  // max step whith helix model
-  double m_straightStep                                      ;  // max step whith srtaight line model
-  bool   m_usegradient                                       ;  // use magnetif field gradient
-  ServiceHandle<MagField::IMagFieldSvc>  m_fieldServiceHandle;
-  MagField::IMagFieldSvc*                m_fieldService      ;
-};
+        /** Internal RungeKutta propagation method for charge track parameters*/   
+
+        TrackParameters*      propagateRungeKutta
+        (Cache& cache                  ,
+         bool                          ,
+         const TrackParameters        &,
+         const Surface                &,
+         const PropDirection           ,
+         const BoundaryCheck&          ,
+         const MagneticFieldProperties&,
+         double                       *,
+         bool                returnCurv) const;
+
+        /** Internal RungeKutta propagation method for neutral track parameters*/   
+
+        NeutralParameters*    propagateStraightLine
+        (Cache& cache                  ,
+         bool                          ,
+         const NeutralParameters      &,
+         const Surface                &,
+         const PropDirection           ,
+         const BoundaryCheck&          ,
+         double                       *,
+         bool                returnCurv) const;
+
+        /** Internal RungeKutta propagation method */
+
+        bool propagateRungeKutta
+        (Cache& cache                  ,
+         bool                          ,
+         PatternTrackParameters       &,
+         const Surface                &,
+         PatternTrackParameters       &,
+         PropDirection                 ,
+         const MagneticFieldProperties&,
+         double                       &) const;
+
+        /** Internal RungeKutta propagation method for propation with jacobian*/     
+
+        bool propagateWithJacobian
+        (Cache& cache                  , 
+         bool                          ,
+         int                           ,
+         double                       *,
+         double                       *,
+         double                       &) const;
+
+        /** Propagation methods runge kutta step*/
+
+        double rungeKuttaStep  
+        (Cache& cache,
+         bool                          ,
+         double                        ,
+         double                       *,
+         bool                         &) const;
+
+        /** Propagation methods runge kutta step*/
+
+        double rungeKuttaStepWithGradient  
+        (Cache& cache                  ,
+         double                        ,
+         double                       *,
+         bool                         &) const;
+
+        /** Propagation methods straight line step*/
+
+        double straightLineStep
+        (bool   ,     
+         double ,
+         double*) const;
+
+        /** Test new propagation to cylinder boundary */
+
+        bool newCrossPoint
+        (const CylinderSurface&,
+         const double         *,
+         const double         *) const;
+
+        /** Step estimator with directions correction */
+
+        double stepEstimatorWithCurvature(Cache& cache,int,double*,const double*,bool&) const;
+
+        /** Step reduction */
+        double stepReduction(const double*) const;
+
+        /** Build new track parameters without propagation */
+
+        TrackParameters*  buildTrackParametersWithoutPropagation
+        (const TrackParameters &,double*) const;
+
+        NeutralParameters*  buildTrackParametersWithoutPropagation
+        (const NeutralParameters&,double*) const;
+
+        void globalOneSidePositions
+        (Cache& cache                   ,
+         std::list<Amg::Vector3D>       &,
+         const double                   *,
+         const MagneticFieldProperties  &,
+         const CylinderBounds           &,
+         double                          ,
+         ParticleHypothesis particle=pion) const;
+
+        void globalTwoSidePositions
+        (Cache& cache                   ,
+         std::list<Amg::Vector3D>       &,
+         const double                   *,
+         const MagneticFieldProperties  &,
+         const CylinderBounds           &,
+         double                          ,
+         ParticleHypothesis particle=pion) const;
+
+        Trk::TrackParameters* crossPoint
+        (const TrackParameters    &,
+         std::vector<DestSurf>    &,
+         std::vector<unsigned int>&,
+         double                   *,
+         std::pair<double,int>    &) const;
+
+        void getField        (Cache& cache, double*,double*        ) const;
+        void getFieldGradient(Cache& cache, double*,double*,double*) const;
+
+        //placeholder for compatibility with new interface
+        virtual
+        const TrackSurfaceIntersection* intersectSurface(const EventContext&,
+                                                         const Surface&,
+                                                         const TrackSurfaceIntersection*,
+                                                         const double,
+                                                         const MagneticFieldProperties&,
+                                                         ParticleHypothesis) const override
+            {return nullptr;}
+ 
+        /////////////////////////////////////////////////////////////////////////////////
+        // Private data members: 
+        /////////////////////////////////////////////////////////////////////////////////
+
+        double m_dlt                                               ;  // accuracy parameter
+        double m_helixStep                                         ;  // max step whith helix model
+        double m_straightStep                                      ;  // max step whith srtaight line model
+        bool   m_usegradient                                       ;  // use magnetif field gradient
+        ServiceHandle<MagField::IMagFieldSvc>  m_fieldServiceHandle;
+        MagField::IMagFieldSvc*                m_fieldService      ;
+
+        // temporary flag to be able to avoid the use of the AtlasFieldCacheCondObj
+        Gaudi::Property<bool> m_useCondObj {this, "UseCondObj", true, "Use the conditions object to fetch the field cache"};
+
+        // Read handle for conditions object to get the field cache
+        SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
+        void getFieldCacheObject(Cache& cache, const EventContext& ctx) const;      
+
+    };
 
 /////////////////////////////////////////////////////////////////////////////////
 // Inline methods for magnetic field information
 /////////////////////////////////////////////////////////////////////////////////
 
-inline void RungeKuttaPropagator::getField(Cache& cache,double* R,double* H) const
-{
-  if(cache.m_solenoid) return m_fieldService->getFieldZR(R,H);
-  return                m_fieldService->getField  (R,H);
-}
-
-inline void RungeKuttaPropagator::getFieldGradient(Cache& cache,double* R,double* H,double* dH) const
-{
-  if(cache.m_solenoid) return m_fieldService->getFieldZR(R,H,dH);
-  return                m_fieldService->getField  (R,H,dH);
-}
+    inline void RungeKuttaPropagator::getField(Cache& cache,double* R,double* H) const {	 
+
+        // MT version uses cache, temporarily keep old version
+        if (cache.m_fieldCache.useNewBfieldCache()) {
+            if(cache.m_solenoid) cache.m_fieldCache.getFieldZR(R, H);
+            else                 cache.m_fieldCache.getField  (R, H);
+        }
+        else {
+            if(cache.m_solenoid) m_fieldService->getFieldZR(R, H);
+            else                 m_fieldService->getField  (R, H);
+        }
+    
+    }
+
+    inline void RungeKuttaPropagator::getFieldGradient(Cache& cache,double* R,double* H,double* dH) const { 
+
+        // MT version uses cache, temporarily keep old version
+        if (cache.m_fieldCache.useNewBfieldCache()) {
+            if(cache.m_solenoid) cache.m_fieldCache.getFieldZR(R, H, dH);
+            else                 cache.m_fieldCache.getField  (R, H, dH);
+        }
+        else {
+            if(cache.m_solenoid) m_fieldService->getFieldZR(R, H, dH);
+            else                 m_fieldService->getField  (R, H, dH);
+        }
+    
+    }
 }
 
 #endif // RungeKuttaPropagator_H
diff --git a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/src/RungeKuttaPropagator.cxx b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/src/RungeKuttaPropagator.cxx
index 82fea9ce06f7615b7debeab9bde350d0eecb7303..864f5681c4bb3d295a7c1fee8b2e8327e89ca401 100755
--- a/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/src/RungeKuttaPropagator.cxx
+++ b/Tracking/TrkExtrapolation/TrkExRungeKuttaPropagator/src/RungeKuttaPropagator.cxx
@@ -49,6 +49,17 @@ Trk::RungeKuttaPropagator::RungeKuttaPropagator
 
 StatusCode Trk::RungeKuttaPropagator::initialize()
 {
+  ATH_MSG_VERBOSE(" RungeKutta_Propagator initialize() successful" );
+
+  // temporarily protect the use of the field cond object/field cache for clients with IOV callbacks
+      
+  // Read handle for AtlasFieldCacheCondObj
+  ATH_CHECK( m_fieldCondObjInputKey.initialize(m_useCondObj) );
+  if (m_useCondObj) ATH_MSG_INFO("initialize() init key: " << m_fieldCondObjInputKey.key());
+  else              ATH_MSG_INFO("initialize() DID NOT init key: " << m_fieldCondObjInputKey.key());
+  
+
+  
   if( !m_fieldServiceHandle.retrieve() ){
     ATH_MSG_FATAL("Failed to retrieve " << m_fieldServiceHandle );
     return StatusCode::FAILURE;
@@ -56,7 +67,7 @@ StatusCode Trk::RungeKuttaPropagator::initialize()
   ATH_MSG_DEBUG("Retrieved " << m_fieldServiceHandle );
   m_fieldService = &*m_fieldServiceHandle;
 
-  msg(MSG::INFO) << name() <<" initialize() successful" << endmsg;
+//  msg(MSG::INFO) << name() <<" initialize() successful" << endmsg;
   return StatusCode::SUCCESS;
 }
 
@@ -66,7 +77,7 @@ StatusCode Trk::RungeKuttaPropagator::initialize()
 
 StatusCode  Trk::RungeKuttaPropagator::finalize()
 {
-  msg(MSG::INFO) << name() <<" finalize() successful" << endmsg;
+  ATH_MSG_INFO(name() <<" finalize() successful");
   return StatusCode::SUCCESS;
 }
 
@@ -98,7 +109,8 @@ Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagate
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
-(const Trk::TrackParameters  & Tp,
+(const ::EventContext&               ctx,
+ const Trk::TrackParameters  & Tp,
  const Trk::Surface          & Su,
  Trk::PropDirection             D,
  const Trk::BoundaryCheck    &  B,
@@ -109,6 +121,10 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
 {
   double J[25];
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_maxPath = 10000.;
   return propagateRungeKutta(cache,true,Tp,Su,D,B,M,J,returnCurv);
 }
@@ -119,7 +135,8 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
-(const Trk::TrackParameters   & Tp ,
+(const ::EventContext&               ctx,
+ const Trk::TrackParameters   & Tp ,
  const Trk::Surface&            Su ,
  Trk::PropDirection             D  ,
  const Trk::BoundaryCheck     & B  ,
@@ -132,6 +149,10 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
 {
   double J[25];
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   pathLength < 0. ?  cache.m_maxPath = 10000. : cache.m_maxPath = pathLength; 
   Trk::TrackParameters* Tpn = propagateRungeKutta(cache,true,Tp,Su,D,B,M,J,returnCurv);
   pathLength = cache.m_step;  
@@ -149,7 +170,8 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
-(const TrackParameters        & Tp  ,
+(const ::EventContext&               ctx,
+ const TrackParameters        & Tp  ,
  std::vector<DestSurf>        & DS  ,
  PropDirection                  D   ,
  const MagneticFieldProperties& M   ,
@@ -162,6 +184,10 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
 {
  
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   Sol.erase(Sol.begin(),Sol.end()); Path = 0.; if(DS.empty()) return nullptr;
   cache.m_direction               = D; 
 
@@ -171,9 +197,9 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
 
   // Magnetic field information preparation
   //
-  M.magneticFieldMode()==2  ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  M.magneticFieldMode() == Trk::FastField  ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
   (useJac && m_usegradient) ? cache.m_needgradient = true : cache.m_needgradient = false; 
-  M.magneticFieldMode()!=0  ? cache.m_mcondition   = true : cache.m_mcondition   = false;
+  M.magneticFieldMode() != Trk::NoField    ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   // Transform to global presentation
   //
@@ -293,7 +319,8 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagate
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateParameters
-(const Trk::TrackParameters  & Tp,
+(const ::EventContext&               ctx,
+ const Trk::TrackParameters  & Tp,
  const Trk::Surface          & Su, 
  Trk::PropDirection             D,
  const Trk::BoundaryCheck    &  B,
@@ -304,6 +331,10 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateParameters
 {
   double J[25];
   Cache cache;
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_maxPath = 10000.;
   return propagateRungeKutta(cache,false,Tp,Su,D,B,M,J,returnCurv);
 }
@@ -314,7 +345,8 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateParameters
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateParameters
-(const Trk::TrackParameters    & Tp ,
+(const ::EventContext&               ctx,
+ const Trk::TrackParameters    & Tp ,
  const Trk::Surface            & Su , 
  Trk::PropDirection              D  ,
  const Trk::BoundaryCheck      & B  ,
@@ -326,6 +358,9 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateParameters
 {
   double J[25];
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
   cache.m_maxPath = 10000.;
   Trk::TrackParameters* Tpn = propagateRungeKutta   (cache,true,Tp,Su,D,B,M,J,returnCurv);
   
@@ -343,10 +378,10 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateParameters
 Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagateStraightLine
 (Cache&                         cache ,
  bool                           useJac,
- const Trk::NeutralParameters & Tp    ,
- const Trk::Surface           & Su    ,
+ const Trk::NeutralParameters&  Tp    ,
+ const Trk::Surface&            Su    ,
  Trk::PropDirection             D     ,
- const Trk::BoundaryCheck&             B     ,
+ const Trk::BoundaryCheck&      B     ,
  double                       * Jac   ,
  bool                       returnCurv) const 
 {
@@ -472,10 +507,10 @@ Trk::NeutralParameters* Trk::RungeKuttaPropagator::propagateStraightLine
 Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateRungeKutta
 (Cache&                         cache ,
  bool                           useJac,
- const Trk::TrackParameters   & Tp    ,
- const Trk::Surface           & Su    ,
+ const Trk::TrackParameters&    Tp    ,
+ const Trk::Surface&            Su    ,
  Trk::PropDirection             D     ,
- const Trk::BoundaryCheck&             B     ,
+ const Trk::BoundaryCheck&      B     ,
  const MagneticFieldProperties& M     ,
  double                       * Jac   ,
  bool                       returnCurv) const 
@@ -484,9 +519,9 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateRungeKutta
 
   cache.m_direction               = D ; 
 
-  M.magneticFieldMode()==2 ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  M.magneticFieldMode() == Trk::FastField ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
   (useJac && m_usegradient)? cache.m_needgradient = true : cache.m_needgradient = false; 
-  M.magneticFieldMode()!=0 ? cache.m_mcondition   = true : cache.m_mcondition   = false;
+  M.magneticFieldMode() != Trk::NoField   ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   if(su == &Tp.associatedSurface()) return buildTrackParametersWithoutPropagation(Tp,Jac);
 
@@ -601,7 +636,8 @@ Trk::TrackParameters* Trk::RungeKuttaPropagator::propagateRungeKutta
 /////////////////////////////////////////////////////////////////////////////////
 
 void Trk::RungeKuttaPropagator::globalPositions 
-(std::list<Amg::Vector3D>      & GP,
+(const ::EventContext&               ctx,
+ std::list<Amg::Vector3D>      & GP,
  const TrackParameters         & Tp,
  const MagneticFieldProperties & M ,
  const CylinderBounds          & CB,
@@ -612,6 +648,10 @@ void Trk::RungeKuttaPropagator::globalPositions
   Trk::RungeKuttaUtils utils;
   double P[45]; if(!utils.transformLocalToGlobal(false,Tp,P)) return;
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_direction = fabs(mS);
   if(mS > 0.) globalOneSidePositions(cache,GP,P,M,CB, mS);
   else        globalTwoSidePositions(cache,GP,P,M,CB,-mS);
@@ -621,8 +661,9 @@ void Trk::RungeKuttaPropagator::globalPositions
 //  Global position together with direction of the trajectory on the surface
 /////////////////////////////////////////////////////////////////////////////////
 
-Trk::IntersectionSolution* Trk::RungeKuttaPropagator::intersect
-( const Trk::TrackParameters   & Tp,
+const Trk::IntersectionSolution* Trk::RungeKuttaPropagator::intersect
+( const ::EventContext&               ctx,
+  const Trk::TrackParameters   & Tp,
   const Trk::Surface           & Su,
   const MagneticFieldProperties& M ,
   ParticleHypothesis               ,
@@ -631,11 +672,15 @@ Trk::IntersectionSolution* Trk::RungeKuttaPropagator::intersect
   bool nJ = false;
   const Trk::Surface* su = &Su;
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+ 
   cache.m_direction            = 0. ;
 
   cache.m_needgradient = false; 
-  M.magneticFieldMode()==2 ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
-  M.magneticFieldMode()!=0 ? cache.m_mcondition   = true : cache.m_mcondition   = false;
+  M.magneticFieldMode() == Trk::FastField ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  M.magneticFieldMode() != Trk::NoField   ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   Trk::RungeKuttaUtils utils;
 
@@ -1240,7 +1285,8 @@ double Trk::RungeKuttaPropagator::straightLineStep
 /////////////////////////////////////////////////////////////////////////////////
 
 bool Trk::RungeKuttaPropagator::propagate
-(Trk::PatternTrackParameters  & Ta,
+(const ::EventContext&               ctx,
+ Trk::PatternTrackParameters  & Ta,
  const Trk::Surface           & Su,
  Trk::PatternTrackParameters  & Tb,
  Trk::PropDirection             D ,
@@ -1249,6 +1295,10 @@ bool Trk::RungeKuttaPropagator::propagate
 {
   double S;
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+ 
   cache.m_maxPath = 10000.;
   return propagateRungeKutta(cache,true,Ta,Su,Tb,D,M,S);
 }
@@ -1259,7 +1309,8 @@ bool Trk::RungeKuttaPropagator::propagate
 /////////////////////////////////////////////////////////////////////////////////
 
 bool Trk::RungeKuttaPropagator::propagate
-(Trk::PatternTrackParameters  & Ta,
+(const ::EventContext&               ctx,
+ Trk::PatternTrackParameters  & Ta,
  const Trk::Surface           & Su,
  Trk::PatternTrackParameters  & Tb,
  Trk::PropDirection             D ,
@@ -1268,6 +1319,10 @@ bool Trk::RungeKuttaPropagator::propagate
  ParticleHypothesis               ) const 
 {
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_maxPath = 10000.; 
   return propagateRungeKutta(cache,true,Ta,Su,Tb,D,M,S);
 }
@@ -1278,7 +1333,8 @@ bool Trk::RungeKuttaPropagator::propagate
 /////////////////////////////////////////////////////////////////////////////////
 
 bool Trk::RungeKuttaPropagator::propagateParameters
-(Trk::PatternTrackParameters  & Ta,
+(const ::EventContext&               ctx,
+ Trk::PatternTrackParameters  & Ta,
  const Trk::Surface           & Su,
  Trk::PatternTrackParameters  & Tb, 
  Trk::PropDirection             D ,
@@ -1287,6 +1343,10 @@ bool Trk::RungeKuttaPropagator::propagateParameters
 {
   double S;
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_maxPath = 10000.; 
   return propagateRungeKutta(cache,false,Ta,Su,Tb,D,M,S);
 }
@@ -1297,7 +1357,8 @@ bool Trk::RungeKuttaPropagator::propagateParameters
 /////////////////////////////////////////////////////////////////////////////////
 
 bool Trk::RungeKuttaPropagator::propagateParameters
-(Trk::PatternTrackParameters  & Ta,
+(const ::EventContext&               ctx,
+Trk::PatternTrackParameters  & Ta,
  const Trk::Surface           & Su,
  Trk::PatternTrackParameters  & Tb, 
  Trk::PropDirection             D ,
@@ -1306,6 +1367,10 @@ bool Trk::RungeKuttaPropagator::propagateParameters
  ParticleHypothesis               ) const 
 {
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+ 
   cache.m_maxPath = 10000.;
   return propagateRungeKutta(cache,false,Ta,Su,Tb,D,M,S);
 }
@@ -1317,7 +1382,8 @@ bool Trk::RungeKuttaPropagator::propagateParameters
 /////////////////////////////////////////////////////////////////////////////////
 
 void Trk::RungeKuttaPropagator::globalPositions 
-(std::list<Amg::Vector3D>         & GP,
+(const ::EventContext&               ctx,
+ std::list<Amg::Vector3D>         & GP,
  const Trk::PatternTrackParameters& Tp,
  const MagneticFieldProperties    & M,
  const CylinderBounds             & CB,
@@ -1328,6 +1394,10 @@ void Trk::RungeKuttaPropagator::globalPositions
   double P[45]; if(!utils.transformLocalToGlobal(false,Tp,P)) return;
 
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+ 
   cache.m_direction = fabs(mS);
   if(mS > 0.) globalOneSidePositions(cache,GP,P,M,CB, mS);
   else        globalTwoSidePositions(cache,GP,P,M,CB,-mS);
@@ -1339,6 +1409,7 @@ void Trk::RungeKuttaPropagator::globalPositions
 
 void Trk::RungeKuttaPropagator::globalPositions
 (
+ const ::EventContext&               ctx,
  const PatternTrackParameters                 & Tp,
  std::list<const Trk::Surface*>               & SU,
  std::list< std::pair<Amg::Vector3D,double> > & GP,
@@ -1346,12 +1417,16 @@ void Trk::RungeKuttaPropagator::globalPositions
  ParticleHypothesis                               ) const
 {
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx); 
+
   cache.m_direction               = 0.    ;
   cache.m_mcondition              = false ;
   cache.m_maxPath                 = 10000.;
   cache.m_needgradient = false;
-  M.magneticFieldMode()==2 ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
-  M.magneticFieldMode()!=0 ? cache.m_mcondition   = true : cache.m_mcondition   = false;
+  M.magneticFieldMode() == Trk::FastField ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  M.magneticFieldMode() != Trk::NoField   ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   Trk::RungeKuttaUtils utils;
 
@@ -1446,9 +1521,9 @@ bool Trk::RungeKuttaPropagator::propagateRungeKutta
 
   if(useJac && !Ta.iscovariance()) useJac = false;
 
-  M.magneticFieldMode()==2  ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  M.magneticFieldMode() == Trk::FastField  ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
   (useJac && m_usegradient) ? cache.m_needgradient = true : cache.m_needgradient = false; 
-  M.magneticFieldMode()!=0  ? cache.m_mcondition   = true : cache.m_mcondition   = false;
+  M.magneticFieldMode() != Trk::NoField    ? cache.m_mcondition   = true : cache.m_mcondition   = false;
 
   Trk::RungeKuttaUtils utils;
 
@@ -1632,8 +1707,8 @@ void Trk::RungeKuttaPropagator::globalOneSidePositions
  double                          mS,
  ParticleHypothesis                ) const
 {
-  M.magneticFieldMode()==2 ? cache.m_solenoid   = true : cache.m_solenoid  = false;  
-  M.magneticFieldMode()!=0 ? cache.m_mcondition = true : cache.m_mcondition = false;
+  M.magneticFieldMode() == Trk::FastField ? cache.m_solenoid   = true : cache.m_solenoid  = false;  
+  M.magneticFieldMode() != Trk::NoField   ? cache.m_mcondition = true : cache.m_mcondition = false;
 
   double Pm[45]; for(int i=0; i!=7; ++i) Pm[i]=P[i];
 
@@ -1751,8 +1826,8 @@ void Trk::RungeKuttaPropagator::globalTwoSidePositions
  double                          mS,
  ParticleHypothesis                ) const
 {
-  M.magneticFieldMode()==2 ? cache.m_solenoid   = true : cache.m_solenoid   = false;  
-  M.magneticFieldMode()!=0 ? cache.m_mcondition = true : cache.m_mcondition = false;
+  M.magneticFieldMode() == Trk::FastField ? cache.m_solenoid   = true : cache.m_solenoid   = false;  
+  M.magneticFieldMode() != Trk::NoField   ? cache.m_mcondition = true : cache.m_mcondition = false;
 
   double       W     = 0.                 ; // way
   double       R2max = CB.r()*CB.r()      ; // max. radius**2 of region
@@ -1884,17 +1959,22 @@ double Trk::RungeKuttaPropagator::stepReduction(const double* E) const
 // Ro and Po - output  coordinate and momentum after propagation
 /////////////////////////////////////////////////////////////////////////////////
 
-void Trk::RungeKuttaPropagator::propagateStep( const Amg::Vector3D& Ri,const  Amg::Vector3D& Pi,
-                                               double Charge,double Step,
-                                               Amg::Vector3D& Ro, Amg::Vector3D& Po, 
-                                               const MagneticFieldProperties& Mag) const
+void Trk::RungeKuttaPropagator::propagateStep(const EventContext& ctx,
+                                              const Amg::Vector3D& Ri,const  Amg::Vector3D& Pi,
+                                              double Charge,double Step,
+                                              Amg::Vector3D& Ro, Amg::Vector3D& Po, 
+                                              const MagneticFieldProperties& Mag) const
 {
 
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   // Magnetic field information preparation
   //
-  Mag.magneticFieldMode()==2 ? cache.m_solenoid   = true : cache.m_solenoid   = false;  
-  Mag.magneticFieldMode()!=0 ? cache.m_mcondition = true : cache.m_mcondition = false;
+  Mag.magneticFieldMode() == Trk::FastField ? cache.m_solenoid   = true : cache.m_solenoid   = false;  
+  Mag.magneticFieldMode() != Trk::NoField   ? cache.m_mcondition = true : cache.m_mcondition = false;
 
   double M  = sqrt(Pi[0]*Pi[0]+Pi[1]*Pi[1]+Pi[2]*Pi[2]); if(M < .00001) {Ro = Ri; Po = Pi; return;}
   double Mi = 1./M;
@@ -1925,3 +2005,26 @@ void Trk::RungeKuttaPropagator::propagateStep( const Amg::Vector3D& Ri,const  Am
   Ro[0] =   P[0];  Ro[1] =   P[1];  Ro[2] =   P[2];
   Po[0] = M*P[3];  Po[1] = M*P[4];  Po[2] = M*P[5];
 }
+
+
+void Trk::RungeKuttaPropagator::getFieldCacheObject( Cache& cache,const EventContext& ctx) const
+{
+
+    if (m_useCondObj) {
+
+        SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx};
+        const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+        if (fieldCondObj == nullptr) {
+
+            // temporarily protect for when cache a cannot be retrieved in an IOV callback
+            ATH_MSG_ERROR("extrapolate: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key()
+                          << ". Skipping use of field cache!");
+
+            // ATH_MSG_ERROR("extrapolate: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
+            // return;
+        }
+        fieldCondObj->getInitializedCache (cache.m_fieldCache);
+    }
+
+}
+
diff --git a/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/CMakeLists.txt b/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/CMakeLists.txt
index b072a81e90c3bcffd60ec578b7a2774428d5b43a..616bffbe5365cd3acea1aeda296d06acbea42b12 100644
--- a/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/CMakeLists.txt
+++ b/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/CMakeLists.txt
@@ -22,7 +22,10 @@ atlas_depends_on_subdirs( PUBLIC
                           GaudiKernel
                           Tracking/TrkDetDescr/TrkDetDescrUtils
                           Tracking/TrkDetDescr/TrkSurfaces
-                          Tracking/TrkEvent/TrkTrack )
+                          Tracking/TrkEvent/TrkTrack
+			  MagneticField/MagFieldElements
+                          MagneticField/MagFieldConditions
+			  )
 
 # External dependencies:
 find_package( CLHEP )
@@ -33,7 +36,7 @@ atlas_add_component( TrkExSTEP_Propagator
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${EIGEN_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} AthenaBaseComps AthenaKernel GeoPrimitives EventPrimitives MagFieldInterfaces TrkGeometry TrkEventPrimitives TrkMaterialOnTrack TrkParameters TrkExInterfaces TrkExUtils GaudiKernel TrkDetDescrUtils TrkSurfaces TrkTrack )
+                     LINK_LIBRARIES ${CLHEP_LIBRARIES} ${EIGEN_LIBRARIES} AthenaBaseComps AthenaKernel GeoPrimitives EventPrimitives MagFieldInterfaces TrkGeometry TrkEventPrimitives TrkMaterialOnTrack TrkParameters TrkExInterfaces TrkExUtils GaudiKernel TrkDetDescrUtils TrkSurfaces TrkTrack MagFieldElements MagFieldConditions )
 
 # Install files from the package:
 atlas_install_headers( TrkExSTEP_Propagator )
diff --git a/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/TrkExSTEP_Propagator/STEP_Propagator.h b/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/TrkExSTEP_Propagator/STEP_Propagator.h
index 39a0063508cbafdc153ff9866f345642d0ed0255..c364c9c4bc0f98b82d891b870178130db430fb71 100755
--- a/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/TrkExSTEP_Propagator/STEP_Propagator.h
+++ b/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/TrkExSTEP_Propagator/STEP_Propagator.h
@@ -23,7 +23,9 @@
 #include "AthenaKernel/IAtRndmGenSvc.h"
 #include "GaudiKernel/ToolHandle.h"
 #include "TrkExInterfaces/IPropagator.h"
+
 #include "MagFieldInterfaces/IMagFieldSvc.h"
+
 #include "TrkEventPrimitives/PropDirection.h"
 #include "TrkEventPrimitives/ParticleHypothesis.h"
 #include "TrkParameters/TrackParameters.h" //TrackParameters typedef
@@ -35,6 +37,9 @@
 // Amg
 #include "GeoPrimitives/GeoPrimitives.h"
 #include "EventPrimitives/EventPrimitives.h"
+// MagField cache
+#include "MagFieldConditions/AtlasFieldCacheCondObj.h"
+#include "MagFieldElements/AtlasFieldCache.h"
 
 namespace Trk {
   class Surface;
@@ -150,7 +155,7 @@ namespace Trk {
     /** AlgTool finalize method */
     virtual StatusCode finalize() override final;
 
-
+      
     /** Main propagation method for ParametersBase. Use StraightLinePropagator for neutrals */
     /*
       const Trk::ParametersBase*
@@ -175,31 +180,34 @@ namespace Trk {
 
     /** Propagate parameters and covariance without returning the Jacobian */
     virtual Trk::TrackParameters*
-      propagate (const Trk::TrackParameters&         trackParameters,
-                 const Trk::Surface&                 targetSurface,
-                 Trk::PropDirection                  propagationDirection,
-                 const Trk::BoundaryCheck&           boundaryCheck,
-                 const      MagneticFieldProperties& magneticFieldProperties,
-                 ParticleHypothesis            particle,
-                 bool                          returnCurv = false,
-                 const Trk::TrackingVolume*          tVol = nullptr) const override final;
+   propagate (const EventContext&                 ctx,
+               const Trk::TrackParameters&         trackParameters,
+               const Trk::Surface&                 targetSurface,
+               Trk::PropDirection                  propagationDirection,
+               const Trk::BoundaryCheck&           boundaryCheck,
+               const      MagneticFieldProperties& magneticFieldProperties,
+               ParticleHypothesis                  particle,
+               bool                                returnCurv = false,
+               const Trk::TrackingVolume*          tVol       = nullptr) const override final;
 
     /** Propagate parameters and covariance with search of closest surface */
     virtual  Trk::TrackParameters*    
-      propagate  (const Trk::TrackParameters&        trackParameters,
-                  std::vector<Trk::DestSurf>&        targetSurfaces,
-                  Trk::PropDirection                 propagationDirection,
-                  const MagneticFieldProperties&     magneticFieldProperties,
-                  ParticleHypothesis                 particle,
-                  std::vector<unsigned int>&         solutions,
-                  double&                            path,
-                  bool                               usePathLimit = false,
-                  bool                               returnCurv = false,
-                  const Trk::TrackingVolume*          tVol = nullptr) const override final;       
+    propagate  (const EventContext&                ctx,
+                const Trk::TrackParameters&        trackParameters,
+                std::vector<Trk::DestSurf>&        targetSurfaces,
+                Trk::PropDirection                 propagationDirection,
+                const MagneticFieldProperties&     magneticFieldProperties,
+                ParticleHypothesis                 particle,
+                std::vector<unsigned int>&         solutions,
+                double&                            path,
+                bool                               usePathLimit = false,
+                bool                               returnCurv = false,
+                const Trk::TrackingVolume*         tVol = nullptr) const override final;       
 
     /** Propagate parameters and covariance with search of closest surface */
     virtual  Trk::TrackParameters*    
-      propagateT  (const Trk::TrackParameters&        trackParameters,
+      propagateT  (const EventContext&                ctx,
+                   const Trk::TrackParameters&        trackParameters,
                    std::vector<Trk::DestSurf>&        targetSurfaces,
                    Trk::PropDirection                 propagationDirection,
                    const MagneticFieldProperties&     magneticFieldProperties,
@@ -212,8 +220,10 @@ namespace Trk {
                    std::vector<Trk::HitInfo>*& hitVector) const override final;
 
     /** Propagate parameters and covariance with search of closest surface and material collection */
+    using Trk::IPropagator::propagateM;
     virtual Trk::TrackParameters*    
-      propagateM  (const Trk::TrackParameters&        trackParameters,
+      propagateM  (const EventContext&                ctx,
+                   const Trk::TrackParameters&        trackParameters,
                    std::vector<Trk::DestSurf>&        targetSurfaces,
                    Trk::PropDirection                 propagationDirection,
                    const MagneticFieldProperties&     magneticFieldProperties,
@@ -229,7 +239,8 @@ namespace Trk {
 
     /** Propagate parameters and covariance, and return the Jacobian. WARNING: Multiple Scattering is not included in the Jacobian! */
     virtual  Trk::TrackParameters*
-      propagate (const Trk::TrackParameters&         trackParameters,
+      propagate (const EventContext&                 ctx,
+                 const Trk::TrackParameters&         trackParameters,
                  const Trk::Surface&                 targetSurface,
                  Trk::PropDirection                  propagationDirection,
                  const Trk::BoundaryCheck&           boundaryCheck,
@@ -242,8 +253,10 @@ namespace Trk {
 
 
     /** Propagate parameters only */
+    using Trk::IPropagator::propagateParameters;
     virtual Trk::TrackParameters*
-      propagateParameters (const Trk::TrackParameters&         trackParameters,
+      propagateParameters (const EventContext&                 ctx,
+                           const Trk::TrackParameters&         trackParameters,
                            const Trk::Surface&                 targetSurface,
                            Trk::PropDirection                  propagationDirection,
                            const Trk::BoundaryCheck&           boundaryCheck,
@@ -255,7 +268,8 @@ namespace Trk {
 
     /** Propagate parameters and return Jacobian. WARNING: Multiple Scattering is not included in the Jacobian! */
     virtual Trk::TrackParameters*
-      propagateParameters (const Trk::TrackParameters&         trackParameters,
+      propagateParameters (const EventContext&                 ctx,
+                           const Trk::TrackParameters&         trackParameters,
                            const Trk::Surface&                 targetSurface,
                            Trk::PropDirection                  propagationDirection,
                            const Trk::BoundaryCheck&           boundaryCheck,
@@ -267,8 +281,10 @@ namespace Trk {
 
 
     /** Propagate parameters and return path (Similar to propagateParameters */
-    virtual IntersectionSolution*
-      intersect (const Trk::TrackParameters&         trackParameters,
+    using Trk::IPropagator::intersect;
+    virtual const IntersectionSolution*
+      intersect (const EventContext&                 ctx,
+                 const Trk::TrackParameters&         trackParameters,
                  const Trk::Surface&                 targetSurface,
                  const Trk::MagneticFieldProperties& magneticFieldProperties,
                  ParticleHypothesis                  particle,
@@ -276,22 +292,25 @@ namespace Trk {
 
     /** Intersection and propagation:
      */
-
-    virtual TrackSurfaceIntersection* intersectSurface(const Surface&         surface,
-                                                       const TrackSurfaceIntersection*    trackIntersection,
-                                                       const double               qOverP,
-                                                       const MagneticFieldProperties& mft,
-                                                       ParticleHypothesis       particle) const override final; 
+    using Trk::IPropagator::intersectSurface;
+    virtual const TrackSurfaceIntersection* intersectSurface(const EventContext&              ctx,
+                                                             const Surface&                   surface,
+                                                             const TrackSurfaceIntersection*  trackIntersection,
+                                                             const double                     qOverP,
+                                                             const MagneticFieldProperties&   mft,
+                                                             ParticleHypothesis               particle) const override final; 
 
     /** Return a list of positions along the track */
+    using Trk::IPropagator::globalPositions;
     virtual void
-      globalPositions (std::list<Amg::Vector3D>&  positionsList,
-                       const TrackParameters&           trackParameters,
-                       const MagneticFieldProperties&   magneticFieldProperties,
-                       const CylinderBounds&            cylinderBounds,
-                       double                           maxStepSize,
-                       ParticleHypothesis               particle,
-                       const Trk::TrackingVolume*       tVol = nullptr) const override final;       
+    globalPositions (const EventContext&            ctx,
+                     std::list<Amg::Vector3D>&      positionsList,
+                     const TrackParameters&         trackParameters,
+                     const MagneticFieldProperties& magneticFieldProperties,
+                     const CylinderBounds&          cylinderBounds,
+                     double                         maxStepSize,
+                     ParticleHypothesis             particle,
+                     const Trk::TrackingVolume*     tVol = 0) const override final;       
 
 
     /////////////////////////////////////////////////////////////////////////////////
@@ -349,6 +368,7 @@ namespace Trk {
       Trk::EnergyLoss                m_combinedEloss;
       Trk::MaterialInteraction       m_matInt;
       std::vector<std::pair<int,std::pair<double,double> > > m_currentDist;
+      MagField::AtlasFieldCache    m_fieldCache;
 
       Cache(){
         m_currentDist.reserve(100);
@@ -432,9 +452,10 @@ namespace Trk {
     // Output: BG, which contains Bx, By, Bz, dBx/dx, dBx/dy, dBx/dz, dBy/dx, dBy/dy, dBy/dz, dBz/dx, dBz/dy, dBz/dz
     /////////////////////////////////////////////////////////////////////////////////
     void
-      getMagneticField(const Amg::Vector3D&  position,
-                       bool            getGradients,
-                       float*          BG) const;
+    getMagneticField(Cache& cache,
+                     const Amg::Vector3D&  position,
+                     bool            getGradients,
+                     float*          BG) const;
 
 
     /////////////////////////////////////////////////////////////////////////////////
@@ -523,8 +544,8 @@ namespace Trk {
                                                   bool                     usePathLimit,
                                                   bool                     returnCurv=false) const;
 
-    void getField        (double*,double*        ) const;
-    void getFieldGradient(double*,double*,double*) const;
+    void getField        (Cache& cache, double*,double*        ) const;
+    void getFieldGradient(Cache& cache, double*,double*,double*) const;
 
 
     double                         m_tolerance;         //!< Error tolerance. Low tolerance gives high accuracy
@@ -555,23 +576,37 @@ namespace Trk {
     ServiceHandle<MagField::IMagFieldSvc>  m_fieldServiceHandle;
     MagField::IMagFieldSvc*                m_fieldService;
 
-
+      // Read handle for conditions object to get the field cache
+    SG::ReadCondHandleKey<AtlasFieldCacheCondObj> m_fieldCacheCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};
+    void getFieldCacheObject(Cache& cache, const EventContext& ctx) const;      
   };
   /////////////////////////////////////////////////////////////////////////////////
   // Inline methods for magnetic field information
   /////////////////////////////////////////////////////////////////////////////////
 
-  inline void STEP_Propagator::getField(double* R,double* H) const
+  inline void STEP_Propagator::getField        (Cache& cache, double* R, double* H) const
   {
-    //if(m_solenoid) return m_fieldService->getFieldZR(R,H);
-    return    m_fieldService->getField  (R,H);
+
+      // getFieldZR has been turned off for Step: if(m_solenoid) return m_fieldService->getFieldZR(R,H);
+
+      // MT version uses cache, temporarily keep old version
+      if (cache.m_fieldCache.useNewBfieldCache()) cache.m_fieldCache.getField  (R, H);
+      else                                        m_fieldService->getField  (R, H);
   }
 
-  inline void STEP_Propagator::getFieldGradient(double* R,double* H,double* dH) const
+  inline void STEP_Propagator::getFieldGradient(Cache& cache, double* R, double* H, double* dH) const
   {
-    //if(m_solenoid) return m_fieldService->getFieldZR(R,H,dH);
-    return    m_fieldService->getField  (R,H,dH);
+
+      // getFieldZR has been turned off for Step: if(m_solenoid) return m_fieldService->getFieldZR(R,H,dH);
+      
+      // MT version uses cache, temporarily keep old version
+      if (cache.m_fieldCache.useNewBfieldCache()) cache.m_fieldCache.getField  (R, H, dH);
+      else                                        m_fieldService->getField  (R, H, dH);
+
+      
   }
 }
 
+
+
 #endif // STEP_Propagator_H
diff --git a/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/src/STEP_Propagator.cxx b/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/src/STEP_Propagator.cxx
index 79f3bb046ac5f57c12d8141457a08254b5ca26ab..6b6b38fd6e743d65d6b7d9d5e12ced5524f8ccbd 100755
--- a/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/src/STEP_Propagator.cxx
+++ b/Tracking/TrkExtrapolation/TrkExSTEP_Propagator/src/STEP_Propagator.cxx
@@ -108,6 +108,9 @@ StatusCode Trk::STEP_Propagator::initialize()
 {
   ATH_MSG_VERBOSE(" STEP_Propagator initialize() successful" );
 
+  // Read handle for AtlasFieldCacheCondObj
+  ATH_CHECK( m_fieldCacheCondObjInputKey.initialize() );
+    
   if (!m_materialEffects) { //override all material interactions
     m_multipleScattering = false;
     m_energyLoss = false;
@@ -154,6 +157,7 @@ StatusCode Trk::STEP_Propagator::finalize()
   return StatusCode::SUCCESS;
 }
 
+
 /** Main propagation method NeutralParameters. Use StraightLinePropagator for neutrals*/
 Trk::NeutralParameters*
 Trk::STEP_Propagator::propagate (const Trk::NeutralParameters&,
@@ -173,17 +177,25 @@ Trk::STEP_Propagator::propagate (const Trk::NeutralParameters&,
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters*
-Trk::STEP_Propagator::propagate (const Trk::TrackParameters&         trackParameters,
-                                 const Trk::Surface&                 targetSurface,
-                                 Trk::PropDirection                  propagationDirection,
+Trk::STEP_Propagator::propagate (const EventContext&            ctx,
+                                 const Trk::TrackParameters&    trackParameters,
+                                 const Trk::Surface&            targetSurface,
+                                 Trk::PropDirection             propagationDirection,
                                  const Trk::BoundaryCheck&           boundaryCheck,
-                                 const MagneticFieldProperties&      magneticFieldProperties,
-                                 ParticleHypothesis       particle,
-                                 bool                     returnCurv,
-                                 const Trk::TrackingVolume*          tVol) const
+                                 const MagneticFieldProperties& magneticFieldProperties,
+                                 ParticleHypothesis             particle,
+                                 bool                           returnCurv,
+                                 const Trk::TrackingVolume*     tVol) const
 {
+
+    // ATH_MSG_WARNING( "[STEP_Propagator] enter 1");
+
   double Jacobian[25];
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_detailedElossFlag=m_detailedEloss;
   clearCache(cache); 
 
@@ -212,18 +224,26 @@ Trk::STEP_Propagator::propagate (const Trk::TrackParameters&         trackParame
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters*
-Trk::STEP_Propagator::propagate (const Trk::TrackParameters&         trackParameters,
-                                 std::vector<DestSurf>&        targetSurfaces,
-                                 Trk::PropDirection            propagationDirection,
+Trk::STEP_Propagator::propagate (const EventContext&                 ctx,
+                                 const Trk::TrackParameters&         trackParameters,
+                                 std::vector<DestSurf>&              targetSurfaces,
+                                 Trk::PropDirection                  propagationDirection,
                                  const Trk::MagneticFieldProperties& magneticFieldProperties,
-                                 ParticleHypothesis       particle,
-                                 std::vector<unsigned int>&    solutions,
-                                 double&                  path,
-                                 bool                     usePathLimit,
-                                 bool                     returnCurv,
+                                 ParticleHypothesis                  particle,
+                                 std::vector<unsigned int>&          solutions,
+                                 double&                             path,
+                                 bool                                usePathLimit,
+                                 bool                                returnCurv,
                                  const Trk::TrackingVolume*          tVol) const
 {
+
+    // ATH_MSG_WARNING( "[STEP_Propagator] enter 2");
+
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_detailedElossFlag=m_detailedEloss;
   clearCache(cache); 
 
@@ -266,19 +286,27 @@ Trk::STEP_Propagator::propagate (const Trk::TrackParameters&         trackParame
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters*
-Trk::STEP_Propagator::propagateT (const Trk::TrackParameters&         trackParameters,
-                                  std::vector<DestSurf>&        targetSurfaces,
-                                  Trk::PropDirection            propagationDirection,
+Trk::STEP_Propagator::propagateT (const EventContext&                 ctx,
+                                  const Trk::TrackParameters&         trackParameters,
+                                  std::vector<DestSurf>&              targetSurfaces,
+                                  Trk::PropDirection                  propagationDirection,
                                   const Trk::MagneticFieldProperties& magneticFieldProperties,
-                                  ParticleHypothesis       particle,
-                                  std::vector<unsigned int>&    solutions,
-                                  PathLimit&               pathLim,
-                                  TimeLimit&               timeLim,
-                                  bool                     returnCurv,
+                                  ParticleHypothesis                  particle,
+                                  std::vector<unsigned int>&          solutions,
+                                  PathLimit&                          pathLim,
+                                  TimeLimit&                          timeLim,
+                                  bool                                returnCurv,
                                   const Trk::TrackingVolume*          tVol,
                                   std::vector<Trk::HitInfo>*&         hitVector) const
 {
+
+    // ATH_MSG_WARNING( "[STEP_Propagator] enter 3");
+
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_detailedElossFlag=m_detailedEloss;
   clearCache(cache); 
 
@@ -355,21 +383,29 @@ Trk::STEP_Propagator::propagateT (const Trk::TrackParameters&         trackParam
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters*
-Trk::STEP_Propagator::propagateM (const Trk::TrackParameters&         trackParameters,
-                                  std::vector<DestSurf>&        targetSurfaces,
-                                  Trk::PropDirection            propagationDirection,
-                                  const Trk::MagneticFieldProperties& magneticFieldProperties,
-                                  ParticleHypothesis       particle,
-                                  std::vector<unsigned int>&    solutions,
-                                  std::vector<const Trk::TrackStateOnSurface*>*& matstates,
+Trk::STEP_Propagator::propagateM (const EventContext&                                        ctx,
+                                  const Trk::TrackParameters&                                trackParameters,
+                                  std::vector<DestSurf>&                                     targetSurfaces,
+                                  Trk::PropDirection                                         propagationDirection,
+                                  const Trk::MagneticFieldProperties&                        magneticFieldProperties,
+                                  ParticleHypothesis                                         particle,
+                                  std::vector<unsigned int>&                                 solutions,
+                                  std::vector<const Trk::TrackStateOnSurface*>*&             matstates,
                                   std::vector<std::pair<const Trk::TrackParameters*,int> >*& intersections,
-                                  double&                  path,
-                                  bool                     usePathLimit,
-                                  bool                     returnCurv,
-                                  const Trk::TrackingVolume*          tVol,
+                                  double&                                                    path,
+                                  bool                                                       usePathLimit,
+                                  bool                                                       returnCurv,
+                                  const Trk::TrackingVolume*                                 tVol,
                                   Trk::ExtrapolationCache*  extrapCache) const
 {
+
+    // ATH_MSG_WARNING( "[STEP_Propagator] enter 4");
+
   Cache cache{};
+
+    // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_detailedElossFlag=m_detailedEloss;
   clearCache(cache); 
 
@@ -416,7 +452,8 @@ Trk::STEP_Propagator::propagateM (const Trk::TrackParameters&         trackParam
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters*
-Trk::STEP_Propagator::propagate (const Trk::TrackParameters&         trackParameters,
+Trk::STEP_Propagator::propagate (const EventContext&                 ctx,
+                                 const Trk::TrackParameters&         trackParameters,
                                  const Trk::Surface&                 targetSurface,
                                  Trk::PropDirection                  propagationDirection,
                                  const Trk::BoundaryCheck&           boundaryCheck,
@@ -427,8 +464,15 @@ Trk::STEP_Propagator::propagate (const Trk::TrackParameters&         trackParame
                                  bool                                returnCurv,
                                  const Trk::TrackingVolume*          tVol) const
 {
+
+    // ATH_MSG_WARNING( "[STEP_Propagator] enter 5");
+
   double Jacobian[25];
   Cache cache{};
+
+    // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_detailedElossFlag=m_detailedEloss;
   clearCache(cache); 
 
@@ -467,17 +511,25 @@ Trk::STEP_Propagator::propagate (const Trk::TrackParameters&         trackParame
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters*
-Trk::STEP_Propagator::propagateParameters (const Trk::TrackParameters&         trackParameters,
+Trk::STEP_Propagator::propagateParameters (const EventContext&                 ctx,
+                                           const Trk::TrackParameters&         trackParameters,
                                            const Trk::Surface&                 targetSurface,
                                            Trk::PropDirection                  propagationDirection,
                                            const Trk::BoundaryCheck&           boundaryCheck,
                                            const Trk::MagneticFieldProperties& magneticFieldProperties,
-                                           ParticleHypothesis       particle,
-                                           bool                     returnCurv,
+                                           ParticleHypothesis                  particle,
+                                           bool                                returnCurv,
                                            const Trk::TrackingVolume*          tVol) const
 {
+
+    // ATH_MSG_WARNING( "[STEP_Propagator] enter 6");
+
   double Jacobian[25];
   Cache cache{};
+
+    // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_detailedElossFlag=m_detailedEloss;
   clearCache(cache); 
 
@@ -504,7 +556,8 @@ Trk::STEP_Propagator::propagateParameters (const Trk::TrackParameters&         t
 /////////////////////////////////////////////////////////////////////////////////
 
 Trk::TrackParameters*
-Trk::STEP_Propagator::propagateParameters (const Trk::TrackParameters&         trackParameters,
+Trk::STEP_Propagator::propagateParameters (const EventContext&                 ctx,
+                                           const Trk::TrackParameters&         trackParameters,
                                            const Trk::Surface&                 targetSurface,
                                            Trk::PropDirection                  propagationDirection,
                                            const Trk::BoundaryCheck&           boundaryCheck,
@@ -514,9 +567,16 @@ Trk::STEP_Propagator::propagateParameters (const Trk::TrackParameters&         t
                                            bool                                returnCurv,
                                            const Trk::TrackingVolume*          tVol) const
 {
-  double Jacobian[25];
+
+    // ATH_MSG_WARNING( "[STEP_Propagator] enter 7");
+ 
+ double Jacobian[25];
 
   Cache cache{};
+
+    // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_detailedElossFlag=m_detailedEloss;
   clearCache(cache); 
 
@@ -550,15 +610,20 @@ Trk::STEP_Propagator::propagateParameters (const Trk::TrackParameters&         t
 // Function for finding the intersection point with a surface
 /////////////////////////////////////////////////////////////////////////////////
 
-Trk::IntersectionSolution*
-Trk::STEP_Propagator::intersect (const Trk::TrackParameters&         trackParameters,
+const Trk::IntersectionSolution*
+Trk::STEP_Propagator::intersect (const EventContext&                 ctx,
+                                 const Trk::TrackParameters&         trackParameters,
                                  const Trk::Surface&                 targetSurface,
                                  const Trk::MagneticFieldProperties& mft,
-                                 ParticleHypothesis       particle,
+                                 ParticleHypothesis                  particle,
                                  const Trk::TrackingVolume*          tVol) const
 {
 
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_detailedElossFlag=m_detailedEloss;
   clearCache(cache); 
 
@@ -577,7 +642,7 @@ Trk::STEP_Propagator::intersect (const Trk::TrackParameters&         trackParame
   cache.m_hitVector = nullptr;
 
   // Bfield mode
-  mft.magneticFieldMode()==2 ? cache.m_solenoid = true : cache.m_solenoid = false;  
+  mft.magneticFieldMode() == Trk::FastField ? cache.m_solenoid = true : cache.m_solenoid = false;  
 
   //Check inputvalues
   if (m_tolerance <= 0.) return nullptr;
@@ -654,12 +719,14 @@ Trk::STEP_Propagator::intersect (const Trk::TrackParameters&         trackParame
   return intersectionSolution;
 }
 
-Trk::TrackSurfaceIntersection* Trk::STEP_Propagator::intersectSurface(const Trk::Surface&         surface,
-                                                                      const Trk::TrackSurfaceIntersection*    
-                                                                      trackIntersection,
-                                                                      const double               qOverP,
-                                                                      const Trk::MagneticFieldProperties& mft,
-                                                                      ParticleHypothesis       particle) const 
+const Trk::TrackSurfaceIntersection*
+Trk::STEP_Propagator::intersectSurface(const EventContext&             ctx,
+                                       const Trk::Surface&         surface,
+                                       const Trk::TrackSurfaceIntersection*    
+                                       trackIntersection,
+                                       const double               qOverP,
+                                       const Trk::MagneticFieldProperties& mft,
+                                       ParticleHypothesis       particle) const 
 {
 
   Amg::Vector3D origin = trackIntersection->position();
@@ -670,7 +737,8 @@ Trk::TrackSurfaceIntersection* Trk::STEP_Propagator::intersectSurface(const Trk:
                                                                                       direction.phi(),
                                                                                       direction.theta(),qOverP,nullptr);
 
-  const Trk::IntersectionSolution* solution = qOverP==0? intersect(*trackParameters,surface,
+  const Trk::IntersectionSolution* solution = qOverP==0? intersect(ctx,
+                                                                   *trackParameters,surface,
                                                                    Trk::MagneticFieldProperties(Trk::NoField),
                                                                    particle):intersect(*trackParameters,surface,
                                                                                        mft,particle,nullptr);
@@ -695,15 +763,20 @@ Trk::TrackSurfaceIntersection* Trk::STEP_Propagator::intersectSurface(const Trk:
 /////////////////////////////////////////////////////////////////////////////////
 
 void
-Trk::STEP_Propagator::globalPositions ( std::list<Amg::Vector3D>& positionsList,
-                                        const Trk::TrackParameters&           trackParameters,
-                                        const Trk::MagneticFieldProperties&   mft,
-                                        const Trk::CylinderBounds&            cylinderBounds,
-                                        double                     maxStepSize,
-                                        ParticleHypothesis         particle,
-                                        const Trk::TrackingVolume*       tVol) const
+Trk::STEP_Propagator::globalPositions ( const EventContext&                 ctx,
+                                        std::list<Amg::Vector3D>&           positionsList,
+                                        const Trk::TrackParameters&         trackParameters,
+                                        const Trk::MagneticFieldProperties& mft,
+                                        const Trk::CylinderBounds&          cylinderBounds,
+                                        double                              maxStepSize,
+                                        ParticleHypothesis                  particle,
+                                        const Trk::TrackingVolume*          tVol) const
 {
   Cache cache{};
+
+  // Get field cache object
+  getFieldCacheObject(cache, ctx);
+
   cache.m_detailedElossFlag=m_detailedEloss;
   clearCache(cache); 
 
@@ -721,7 +794,7 @@ Trk::STEP_Propagator::globalPositions ( std::list<Amg::Vector3D>& positionsList,
     cache.m_matPropOK = false;
   }
 
-  mft.magneticFieldMode()==2 ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  mft.magneticFieldMode() == Trk::FastField ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
 
   //Check inputvalues
   if (m_tolerance <= 0.) return;
@@ -827,7 +900,7 @@ Trk::STEP_Propagator::propagateRungeKutta (Cache&                              c
   const Trk::TrackParameters* trackParameters = nullptr;
 
   // Bfield mode
-  mft.magneticFieldMode()==2 ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  mft.magneticFieldMode() == Trk::FastField ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
 
   //Check inputvalues
   if (m_tolerance <= 0.) return nullptr;
@@ -1028,7 +1101,7 @@ Trk::STEP_Propagator::propagateRungeKutta ( Cache&
   const Trk::TrackParameters* trackParameters = nullptr;
 
   // Bfield mode
-  mft.magneticFieldMode()==2 ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
+  mft.magneticFieldMode() == Trk::FastField ? cache.m_solenoid     = true : cache.m_solenoid     = false;  
 
   //Check inputvalues
   if (m_tolerance <= 0.) return nullptr;
@@ -1948,7 +2021,8 @@ Trk::STEP_Propagator::rungeKuttaStep( Cache& cache,
   dir1 = dir;
   if (firstStep) {	       // Poll BG1 if this is the first step, else use recycled BG4
     firstStep = false;
-    getMagneticField( pos, errorPropagation, BG1); //Get the gradients needed for the error propagation if errorPropagation=true
+    // MT Field cache is stored in cache
+    getMagneticField( cache, pos, errorPropagation, BG1); //Get the gradients needed for the error propagation if errorPropagation=true
   }
   // Lorentz force, d2r/ds2 = lambda * (dir x B)
   Amg::Vector3D k1( dir.y()*BG1[2] - dir.z()*BG1[1], dir.z()*BG1[0] - dir.x()*BG1[2], dir.x()*BG1[1] - dir.y()*BG1[0]);
@@ -1970,7 +2044,9 @@ Trk::STEP_Propagator::rungeKuttaStep( Cache& cache,
     pos = initialPos + (h/2.)*initialDir + (h*h/8.)*k1;
     dir = initialDir + (h/2.)*k1;
     dir2 = dir;
-    getMagneticField( pos, errorPropagation, BG23);
+
+    // MT Field cache is stored in cache
+    getMagneticField( cache, pos, errorPropagation, BG23);
     Amg::Vector3D k2( dir.y()*BG23[2] - dir.z()*BG23[1], dir.z()*BG23[0] - dir.x()*BG23[2],
                       dir.x()*BG23[1] - dir.y()*BG23[0]);
     k2 = sol * lambda2 * k2;
@@ -2006,7 +2082,9 @@ Trk::STEP_Propagator::rungeKuttaStep( Cache& cache,
     pos = initialPos + h*initialDir + (h*h/2.)*k3;
     dir = initialDir + h*k3;
     dir4 = dir;
-    getMagneticField( pos, errorPropagation, BG4);
+
+    // MT Field cache is stored in cache
+    getMagneticField( cache, pos, errorPropagation, BG4);
     Amg::Vector3D k4( dir.y()*BG4[2] - dir.z()*BG4[1], dir.z()*BG4[0] - dir.x()*BG4[2], dir.x()*BG4[1] - dir.y()*BG4[0]);
     k4 = sol * lambda4 * k4;
 
@@ -2200,7 +2278,8 @@ Trk::STEP_Propagator::rungeKuttaStep( Cache& cache,
 /////////////////////////////////////////////////////////////////////////////////
 
 void
-Trk::STEP_Propagator::getMagneticField( const Amg::Vector3D&  position,
+Trk::STEP_Propagator::getMagneticField( Cache& cache,
+                                        const Amg::Vector3D&  position,
                                         bool            getGradients,
                                         float*          BG) const
 {
@@ -2218,7 +2297,8 @@ Trk::STEP_Propagator::getMagneticField( const Amg::Vector3D&  position,
 
   if (getGradients && m_includeBgradients) {   // field gradients needed and available
 
-    getFieldGradient(R,H,dH);
+    // MT Field cache is stored in cache
+    getFieldGradient(cache, R,H,dH);
 
     BG[0]=H[0]*magScale;    
     BG[1]=H[1]*magScale;    
@@ -2236,7 +2316,8 @@ Trk::STEP_Propagator::getMagneticField( const Amg::Vector3D&  position,
   }
   else {  //Homogenous field or no gradients needed, only retrieve the field strength.
 
-    getField(R,H); 
+    // MT Field cache is stored in cache
+    getField(cache, R,H); 
 
     BG[0]=H[0]*magScale;
     BG[1]=H[1]*magScale;    
@@ -2710,3 +2791,15 @@ void Trk::STEP_Propagator::clearCache(Cache& cache) const
   cache.m_sigmaIoni=0.;
   cache.m_sigmaRad=0.;
 }
+
+void Trk::STEP_Propagator::getFieldCacheObject( Cache& cache,const EventContext& ctx) const
+{
+  SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCacheCondObjInputKey, ctx};
+  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
+  if (fieldCondObj == nullptr) {
+      ATH_MSG_ERROR("extrapolate: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
+      return;
+  }
+  fieldCondObj->getInitializedCache (cache.m_fieldCache);
+}
+
diff --git a/Tracking/TrkExtrapolation/TrkExTools/TrkExTools/Extrapolator.h b/Tracking/TrkExtrapolation/TrkExTools/TrkExTools/Extrapolator.h
index 6cd5a45aa89211f8b58b470cacc0ddad6cf9f7bc..3d34bceba3f89491faf40327fda451c146381b59 100755
--- a/Tracking/TrkExtrapolation/TrkExTools/TrkExTools/Extrapolator.h
+++ b/Tracking/TrkExtrapolation/TrkExTools/TrkExTools/Extrapolator.h
@@ -9,9 +9,12 @@
 #ifndef TRKEXTOOLS_EXTRAPOLATOR_H
 #define TRKEXTOOLS_EXTRAPOLATOR_H
 
-// Gaudi
+// Gaudi/StoreGate
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/EventContext.h"
+#include "StoreGate/ReadCondHandleKey.h"
+
 // Trk
 #include "TrkExInterfaces/IExtrapolator.h"
 #include "TrkExInterfaces/INavigator.h"
@@ -50,6 +53,7 @@ class Layer;
 class Volume;
 class DetachedTrackingVolume;
 class TrackingGeometry;
+class TrackParticleBase;
 class IPropagator;
 class IDynamicLayerCreator;
 class INavigator;
@@ -863,8 +867,9 @@ VERBOSE : Method call sequence with values
     unsigned int                    m_maxNavigVol;
     bool                            m_dumpCache;
     //------------ Magnetic field properties
-    bool                            m_fastField; 
-    Trk::MagneticFieldProperties    m_fieldProperties;
+    bool                                       m_fastField; 
+    Trk::MagneticFieldProperties               m_fieldProperties;
+    
     //------------Reference surface --------------
     
     Surface*                        m_referenceSurface;
diff --git a/Tracking/TrkExtrapolation/TrkExTools/src/Extrapolator.cxx b/Tracking/TrkExtrapolation/TrkExTools/src/Extrapolator.cxx
index fa2a78101d1e9fc1d496fc0638ba488e164d5f3a..7f7c1e1c02312aa873bef852a0dfab6e82c982e8 100755
--- a/Tracking/TrkExtrapolation/TrkExTools/src/Extrapolator.cxx
+++ b/Tracking/TrkExtrapolation/TrkExTools/src/Extrapolator.cxx
@@ -7,6 +7,7 @@
 ///////////////////////////////////////////////////////////////////
 
 #include "GaudiKernel/MsgStream.h"
+// #include "GaudiKernel/EventContext.h"
 // Trk inlcude
 #include "TrkExTools/ObjContainer.h"
 #include "TrkParameters/TrackParameters.h"
@@ -215,6 +216,7 @@ Trk::Extrapolator::~Extrapolator() {
 // initialize
 StatusCode
 Trk::Extrapolator::initialize() {
+
   m_referenceSurface = new Trk::PlaneSurface(new Amg::Transform3D(Trk::s_idTransform), 0., 0.);
   m_referenceSurface->setOwner(Trk::TGOwn);
 
@@ -4544,6 +4546,7 @@ Trk::Extrapolator::extrapolateWithPathLimit(
      }
   }
   Cache cache{};
+
   // reset the path
   cache.m_path = 0.;
   ++cache.m_methodSequence;
diff --git a/Tracking/TrkTools/TrkParticleCreator/TrkParticleCreator/TrackParticleCreatorTool.h b/Tracking/TrkTools/TrkParticleCreator/TrkParticleCreator/TrackParticleCreatorTool.h
index 9662d21169623b3f3bb1bd53182df38ab3057f0c..2bce75cb68760e7bda6d6cb34e2f3bdf79aeb81b 100644
--- a/Tracking/TrkTools/TrkParticleCreator/TrkParticleCreator/TrackParticleCreatorTool.h
+++ b/Tracking/TrkTools/TrkParticleCreator/TrkParticleCreator/TrackParticleCreatorTool.h
@@ -148,7 +148,7 @@ class TrackParticleCreatorTool : public extends<AthAlgTool, ITrackParticleCreato
   
   /** Get the name used for the decoration of the track particle with the number of used hits for TRT dE/dx computation.*/
   static const std::string & trtdEdxUsedHitsAuxName() { return s_trtdEdxUsedHitsDecorationName; }
-  virtual const InDet::BeamSpotData* CacheBeamSpotData(const EventContext &ctx) const override;
+  virtual const InDet::BeamSpotData* CacheBeamSpotData(const ::EventContext &ctx) const override;
 
 private:
 
diff --git a/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx b/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx
index f2c574050717e0624c711472554536f9aa256df7..73e76dc784245a30efe6a25d57b79e6d9d98e937 100644
--- a/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx
+++ b/Tracking/TrkTools/TrkParticleCreator/src/TrackParticleCreatorTool.cxx
@@ -1086,7 +1086,7 @@ namespace Trk
     }
   }
 
-  const InDet::BeamSpotData* TrackParticleCreatorTool::CacheBeamSpotData(const EventContext &ctx) const {
+  const InDet::BeamSpotData* TrackParticleCreatorTool::CacheBeamSpotData(const ::EventContext &ctx) const {
     // if (ctx.evt() == m_lastEvent) return m_lastBeamSpot;
     return m_trackToVertex->GetBeamSpotData(ctx);
     // m_lastEvent = ctx.evt();
diff --git a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackParticleCreatorTool.h b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackParticleCreatorTool.h
index 43b524f7e4982d5f3c7835224b662d8342c99860..85625d849ff1c146cf25652ca8a7f651af1b4674 100755
--- a/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackParticleCreatorTool.h
+++ b/Tracking/TrkTools/TrkToolInterfaces/TrkToolInterfaces/ITrackParticleCreatorTool.h
@@ -9,6 +9,7 @@
 #define ITRKTRACKPARTICLECREATORTOOL_H
 
 #include "GaudiKernel/IAlgTool.h"
+#include "GaudiKernel/EventContext.h"
 #include "TrkParticleBase/TrackParticleBase.h" // to know TrackParticleOrigin enum
 #include "TrkTrack/TrackCollection.h"
 #include "AthLinks/ElementLink.h"
@@ -98,7 +99,7 @@ namespace Trk
                                                  xAOD::TrackParticleContainer* container = nullptr ) const = 0;
 
     /** Convenience method to retrieve Beamspot Data object -- cache this once per event for optimal performance */
-    virtual const InDet::BeamSpotData* CacheBeamSpotData(const EventContext &ctx) const =0;
+    virtual const InDet::BeamSpotData* CacheBeamSpotData(const ::EventContext &ctx) const =0;
 
   };
 
diff --git a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx
index 0f8d653631c67dcaf11e4623cd35cf84ea5ff02d..c8b7e19f5390a80ccf498e4feda3e30192e8a91e 100644
--- a/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx
+++ b/Trigger/TrigAlgorithms/TrigFastTrackFinder/src/TrigFastTrackFinder.cxx
@@ -70,6 +70,7 @@
 #include "TrigNavigation/NavigationCore.icc"
 
 #include "AthenaMonitoringKernel/Monitored.h"
+#include "GaudiKernel/ThreadLocalContext.h"
 
 TrigFastTrackFinder::TrigFastTrackFinder(const std::string& name, ISvcLocator* pSvcLocator) : 
 
@@ -540,7 +541,7 @@ StatusCode TrigFastTrackFinder::findTracks(InDet::SiTrackMakerEventData_xk &trac
 
   bool PIX = true;
   bool SCT = true;
-  m_trackMaker->newTrigEvent(trackEventData, PIX, SCT);
+  m_trackMaker->newTrigEvent(Gaudi::Hive::currentContext(), trackEventData, PIX, SCT);
 
   for(unsigned int tripletIdx=0;tripletIdx!=triplets.size();tripletIdx++) {
 
@@ -565,7 +566,7 @@ StatusCode TrigFastTrackFinder::findTracks(InDet::SiTrackMakerEventData_xk &trac
 
     ++mnt_roi_nSeeds;
 
-    std::list<Trk::Track*> tracks = m_trackMaker->getTracks(trackEventData, spList);
+    std::list<Trk::Track*> tracks = m_trackMaker->getTracks(Gaudi::Hive::currentContext(), trackEventData, spList);
 
     for(std::list<Trk::Track*>::const_iterator t=tracks.begin(); t!=tracks.end(); ++t) {
       if((*t)) {
diff --git a/Trigger/TrigAlgorithms/TrigL2TRTSegFinder/src/TrigTRTSegFinder.cxx b/Trigger/TrigAlgorithms/TrigL2TRTSegFinder/src/TrigTRTSegFinder.cxx
index 9d3a6b8747d88fae7b16ab3110fa12f72386f7c3..0977a9d87866380ac3ceeb899617bfdc9a5c5cde 100755
--- a/Trigger/TrigAlgorithms/TrigL2TRTSegFinder/src/TrigTRTSegFinder.cxx
+++ b/Trigger/TrigAlgorithms/TrigL2TRTSegFinder/src/TrigTRTSegFinder.cxx
@@ -8,6 +8,7 @@
 #include "GaudiKernel/DataSvc.h"
 #include "GaudiKernel/SmartDataPtr.h"
 #include "GaudiKernel/ListItem.h"
+#include "GaudiKernel/ThreadLocalContext.h"
 
 #include "TrigL2TRTSegFinder/TrigTRTSegFinder.h"
 #include "InDetRIO_OnTrack/TRT_DriftCircleOnTrack.h"
@@ -236,8 +237,8 @@ HLT::ErrorCode TrigTRTSegFinder::hltExecute(const HLT::TriggerElement* inputTE,
   }
 
   std::unique_ptr<InDet::ITRT_TrackSegmentsMaker::IEventData>
-     event_data = m_segmentsmaker->newRegion(listTrtIds);
-  m_segmentsmaker->find(*event_data);
+     event_data = m_segmentsmaker->newRegion(Gaudi::Hive::currentContext(), listTrtIds);
+  m_segmentsmaker->find(Gaudi::Hive::currentContext(), *event_data);
 
   Trk::Segment* segment = 0;
   m_nsegments           = 0;