diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt b/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt
index fcae79acc8299bfd740f93630427bf644195dd7a..03917148f91e02b349214be570fbac7c0f23663c 100644
--- a/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/CMakeLists.txt
@@ -16,6 +16,7 @@ atlas_depends_on_subdirs(
    Tracking/TrkDetDescr/TrkGeometry
    InnerDetector/InDetDetDescr/InDetReadoutGeometry
    PRIVATE
+   Tracking/TrkDetDescr/TrkDetDescrSvc
     )
 
 find_package( Eigen )
@@ -33,6 +34,7 @@ atlas_add_component( TrackingGeometryCondAlg
    TrkDetDescrUtils
    TrkGeometry
    InDetReadoutGeometry
+   TrkDetDescrSvcLib
     )
 
 # Install files from the package:
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h b/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
index b450935f4c7e44746af3f27e33d0e07c9a53355b..8cb72f154db3824f218f5fa15d68fa6e109e3e0b 100644
--- a/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/TrackingGeometryCondAlg/TrackingGeometryCondAlg.h
@@ -15,6 +15,7 @@
 #include "TrkDetDescrInterfaces/IGeometryBuilderCond.h"
 #include "TrkDetDescrInterfaces/IGeometryProcessor.h"
 #include "InDetReadoutGeometry/SiDetectorElementCollection.h"
+#include "TrkDetDescrInterfaces/ITrackingGeometrySvc.h"
 
 #include "GaudiKernel/ICondSvc.h"
 #include "GaudiKernel/ToolHandle.h"
@@ -40,6 +41,7 @@ private:
   ServiceHandle<ICondSvc> m_condSvc{this, "CondSvc", "CondSvc"};
   ToolHandle<Trk::IGeometryBuilderCond>           m_trackingGeometryBuilder {this, "GeometryBuilder", ""};
   ToolHandleArray<Trk::IGeometryProcessor>    m_geometryProcessors ;
+  ServiceHandle<ITrackingGeometrySvc>         m_trackingGeometrySvc {this,"TrackingGeometrySvc",""};
 };
 }
 #endif //TRACKINGGEOMETRYCONDALG_H
diff --git a/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx
index 1a2dad69db835621f76880f59a5dc47ee9484210..7eb5799f3ca3ce16052970cfcd15725bf5025ca7 100644
--- a/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx
+++ b/Tracking/TrkConditions/TrackingGeometryCondAlg/src/TrackingGeometryCondAlg.cxx
@@ -6,13 +6,14 @@
 // Trk includes
 #include "TrkGeometry/TrackingGeometry.h"
 #include "AthenaKernel/IOVSvcDefs.h"
+#include "TrkDetDescrSvc/TrackingGeometrySvc.h"
 
 #include "TrackingGeometryCondAlg/TrackingGeometryCondAlg.h"
-
+#include "TrkDetDescrSvc/TrackingGeometryMirror.h"
 
 Trk::TrackingGeometryCondAlg::TrackingGeometryCondAlg(const std::string& name, ISvcLocator* pSvcLocator)
   : AthReentrantAlgorithm(name, pSvcLocator),
-    m_geometryProcessors(this) 
+    m_geometryProcessors(this)
 {
   declareProperty("GeometryProcessors", m_geometryProcessors);
 }
@@ -33,6 +34,9 @@ StatusCode Trk::TrackingGeometryCondAlg::initialize()
     ATH_MSG_FATAL( "Could not retrieve " << m_geometryProcessors );
     return StatusCode::FAILURE;
   }
+  if (!m_trackingGeometrySvc.name().empty()) {
+     ATH_CHECK( m_trackingGeometrySvc.retrieve() );
+  }
 
   return StatusCode::SUCCESS;
 }
@@ -66,5 +70,18 @@ StatusCode Trk::TrackingGeometryCondAlg::execute(const EventContext& ctx) const{
       }
   }
   ATH_CHECK(writeHandle.record(trackingGeometryPair.first,trackingGeometry));
+  if (msgLvl(MSG::VERBOSE)) {
+     Trk::TrackingGeometryMirror dumper(trackingGeometry);
+     dumper.dump(msg(MSG::VERBOSE), name() + " TrackingGeometry dump " );
+  }
+  if (!m_trackingGeometrySvc.name().empty()) {
+     Trk::TrackingGeometrySvc *the_service = dynamic_cast<Trk::TrackingGeometrySvc *>(&(*m_trackingGeometrySvc));
+     if (!the_service) {
+        ATH_MSG_FATAL("Expected a special TrackingGeometrySvc implementation derived from Trk::TrackingGeometrySvc but got " << typeid(the_service).name() );
+     }
+     ATH_MSG_DEBUG("Set TrackingGeometry " << static_cast<const void *>(trackingGeometry) << " in svc " << m_trackingGeometrySvc.name() );
+     the_service->setTrackingGeometry(trackingGeometry);
+  }
+
   return StatusCode::SUCCESS;
 }
diff --git a/Tracking/TrkDetDescr/TrkDetDescrSvc/TrkDetDescrSvc/TrackingGeometryMirror.h b/Tracking/TrkDetDescr/TrkDetDescrSvc/TrkDetDescrSvc/TrackingGeometryMirror.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ae68a04577a62abfed94f84d486a51858e85ca6
--- /dev/null
+++ b/Tracking/TrkDetDescr/TrkDetDescrSvc/TrkDetDescrSvc/TrackingGeometryMirror.h
@@ -0,0 +1,88 @@
+#ifndef _Trk_TrackingGeometryMirror_h_
+#define _Trk_TrackingGeometryMirror_h_
+namespace Trk {
+   class TrackingGeometryMirror;
+}
+#include "TrkGeometry/TrackingGeometry.h"
+#include "AthenaKernel/CLASS_DEF.h"
+
+#include "TrkGeometry/Layer.h"
+#include "TrkVolumes/VolumeBounds.h"
+#include "TrkGeometry/TrackingVolume.h"
+#include "TrkDetDescrUtils/BinnedArray.h"
+#include <iostream>
+
+namespace Trk {
+
+   /// Helper class to provide the same objects as an existing TrackingGeometry without claiming ownership over these objects.
+   /// The class is solely meant to allow using the TrackingGeometry conditions data and the TrackingGeometrySvc at the same time.
+   class TrackingGeometryMirror : public Trk::TrackingGeometry {
+   public:
+      TrackingGeometryMirror(TrackingGeometry *src) : TrackingGeometry(nullptr,src->m_navigationLevel) {
+         update(src);
+      }
+
+      ~TrackingGeometryMirror() {
+         cleanup();
+      }
+
+      void update(TrackingGeometry *src) {
+         m_world = src->m_world;
+         m_beam = src->m_beam;
+         /** The unique boundary Layers */
+         m_boundaryLayers = src->m_boundaryLayers;
+         /** The Volumes in a map for later finding */
+         m_trackingVolumes = src->m_trackingVolumes;
+      }
+
+      void cleanup() {
+         m_world=nullptr;
+         m_beam=nullptr;
+         m_boundaryLayers.clear();
+         m_trackingVolumes.clear();
+      }
+
+      template <class T_Ostream>
+      void dump(T_Ostream &out, const std::string &head) const {
+         for(const std::pair<const Layer*,int> &bound_layers : m_boundaryLayers) {
+            out << head << " [" << bound_layers.second  << "] ";
+            dumpLayer(out, "",bound_layers.first);
+         }
+         int counter=0;
+         for (const std::pair<const std::string, const TrackingVolume*> &volume : m_trackingVolumes) {
+            out << head << " [" << counter++  << "] " << volume.first << " volumeBound=" << volume.second->volumeBounds() << std::endl;
+            if (volume.second->confinedArbitraryLayers()) {
+               int j=0;
+               for(const Layer* confined_layer :  *volume.second->confinedArbitraryLayers()) {
+                  out << head << " [" << counter++  << "] " << volume.first << " confinedArbitrary layer " << j++ << " ";
+                  dumpLayer(out, "",confined_layer);
+               }
+            }
+            if (volume.second->confinedLayers()) {
+               int j=0;
+               for(const Layer* confined_layer :  volume.second->confinedLayers()->arrayObjects()) {
+                  out << head << " [" << counter++  << "] " << volume.first << " confined layer" << j++ << " ";
+                  dumpLayer(out,"",confined_layer);
+               }
+            }
+         }
+      }
+
+   protected:
+      template <class T_Ostream>
+      static void dumpLayer(T_Ostream &out, const std::string &head, const Layer *layer) {
+         if (layer) {
+            out << head
+                << layer->layerIndex().value() << " [t=" << layer->layerType() << "] d=" << layer->thickness();
+            if (layer->representingVolume()) {
+               out << " vol=" << layer->representingVolume()->volumeBounds();
+            }
+            out << layer->surfaceRepresentation();
+         }
+         out << std::endl;
+
+      }
+   };
+}
+
+#endif
diff --git a/Tracking/TrkDetDescr/TrkDetDescrSvc/TrkDetDescrSvc/TrackingGeometrySvc.h b/Tracking/TrkDetDescr/TrkDetDescrSvc/TrkDetDescrSvc/TrackingGeometrySvc.h
index 22f57382df0e485cf182f9649b9e362544af49ae..2a7bf6788b1028fe721b43e0ef8c5cc46c69b056 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrSvc/TrkDetDescrSvc/TrackingGeometrySvc.h
+++ b/Tracking/TrkDetDescr/TrkDetDescrSvc/TrkDetDescrSvc/TrackingGeometrySvc.h
@@ -21,7 +21,7 @@
 
 #ifdef TRKDETDESCR_MEMUSAGE   
 #include "TrkDetDescrUtils/MemoryLogger.h"
-#endif    
+#endif
 
 
 class StoreGateSvc;
@@ -76,8 +76,10 @@ namespace Trk {
       //!< Standard Destructor
       virtual ~TrackingGeometrySvc();
   
-    
+      void setTrackingGeometry(const Trk::TrackingGeometry *ptr);
+
     private:
+      void trackingGeometryNotSet() const;
       //!< cached pointers:
       ISvcLocator*                                m_pSvcLocator {nullptr};
       StoreGateSvc*                               m_pDetStore   {nullptr};
@@ -85,6 +87,7 @@ namespace Trk {
       ToolHandle<Trk::IGeometryBuilder>           m_trackingGeometryBuilder {this, "GeometryBuilder", ""};
       //!< the actual building tool
       mutable const Trk::TrackingGeometry*        m_trackingGeometry     {nullptr};
+
       //!< the cached TrackingGeometry
       Gaudi::Property<std::string>                m_trackingGeometryName {this, "TrackingGeometryName", "AtlasTrackingGeometry"};
       //!< the name of the TrackingGeometry
@@ -103,13 +106,13 @@ namespace Trk {
       Gaudi::Property<bool>                       m_rerunOnCallback {this, "RerunOnCallback", false};
       //!< enables the callback
       Gaudi::Property<bool>                       m_buildGeometryFromTagInfo {this, "BuildGeometryFromTagInfo", true};
-  
-          
+      Gaudi::Property<bool>                       m_useConditionsData {this, "UseExternalConditionsData", false};
   };
 }
 
 inline const Trk::TrackingGeometry* Trk::TrackingGeometrySvc::trackingGeometry() const
-  { return m_trackingGeometry; }
+{  if (!m_trackingGeometry) { trackingGeometryNotSet(); }
+   return m_trackingGeometry; }
 
 inline const std::string& Trk::TrackingGeometrySvc::trackingGeometryName() const
   { return m_trackingGeometryName; }
diff --git a/Tracking/TrkDetDescr/TrkDetDescrSvc/src/TrackingGeometrySvc.cxx b/Tracking/TrkDetDescr/TrkDetDescrSvc/src/TrackingGeometrySvc.cxx
index 1b1899bda7a8d3b89f3c51c172aea2167652ebd0..f4444202dba6feb6f0d8c813fd20bb303298f912 100755
--- a/Tracking/TrkDetDescr/TrkDetDescrSvc/src/TrackingGeometrySvc.cxx
+++ b/Tracking/TrkDetDescr/TrkDetDescrSvc/src/TrackingGeometrySvc.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
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -7,6 +7,7 @@
 ///////////////////////////////////////////////////////////////////
 
 // Trk
+#include "TrkDetDescrSvc/TrackingGeometryMirror.h"
 #include "TrkGeometry/TrackingGeometry.h"
 #include "TrkGeometry/TrackingVolume.h"
 #include "TrkGeometry/Layer.h"
@@ -44,18 +45,23 @@ Trk::TrackingGeometrySvc::~TrackingGeometrySvc()
 /** Initialize Service */
 StatusCode Trk::TrackingGeometrySvc::initialize()
 {
+  // get the DetectorStore
+  ATH_CHECK( service("DetectorStore", m_pDetStore ) );
+
+  // alternative mode which only uses an externally provided TrackingGeometry rather than building its own
+  if (m_useConditionsData) {
+     for (auto &handle : m_geometryProcessors ) {
+         handle.disable();
+     }
+     m_trackingGeometryBuilder.disable();
+     return StatusCode::SUCCESS;
+  }
+
   if (m_geometryProcessors.retrieve().isFailure()){
       ATH_MSG_FATAL( "Could not retrieve " << m_geometryProcessors );
       return StatusCode::FAILURE;
   }
 
-  // get the DetectorStore
-  if (service("DetectorStore", m_pDetStore ).isFailure()) 
-  {
-    ATH_MSG_FATAL( "DetectorStore service not found!" );
-    return StatusCode::FAILURE;
-  }
-
   // get the key -- from StoreGate (DetectorStore)
   std::vector< std::string > tagInfoKeys = m_pDetStore->keys<TagInfo> ();
   std::string tagInfoKey = "";
@@ -93,6 +99,9 @@ StatusCode Trk::TrackingGeometrySvc::initialize()
 
 StatusCode Trk::TrackingGeometrySvc::trackingGeometryInit(IOVSVC_CALLBACK_ARGS_P(I,keys))
 {
+    if (m_useConditionsData) {
+       ATH_MSG_FATAL("Logic error: TrackingGeometry init callback called despite being configured to use external TrackingGeometries provided by a conditions algorithm.");
+    }
     // Retrieve the tracking geometry builder tool   ----------------------------------------------------    
     if (!m_trackingGeometryBuilder.empty() && m_trackingGeometryBuilder.retrieve().isFailure()) {
         ATH_MSG_FATAL( "Failed to retrieve tool '" << m_trackingGeometryBuilder << "'. Aborting." );
@@ -125,7 +134,7 @@ StatusCode Trk::TrackingGeometrySvc::trackingGeometryInit(IOVSVC_CALLBACK_ARGS_P
     if (needsInit || !m_callbackStringCheck) {
         // cleanup the geometry if you have one 
         // (will delete what is in detector store, because new one will overwrite old one)
-        delete m_trackingGeometry; m_trackingGeometry = 0;
+        m_trackingGeometry = nullptr;
     
 #ifdef TRKDETDESCR_MEMUSAGE           
         // memory monitoring    
@@ -179,7 +188,12 @@ StatusCode Trk::TrackingGeometrySvc::trackingGeometryInit(IOVSVC_CALLBACK_ARGS_P
 #endif            
           }
       }
-    
+
+      if (msgLvl(MSG::VERBOSE)) {
+         Trk::TrackingGeometryMirror mirror(atlasTrackingGeometry);
+         mirror.dump(msg(MSG::VERBOSE), name()+" TrackingGeometry dump ");
+         mirror.cleanup();
+      }
       // record the resulting TrackingGeometry 
       if (m_pDetStore->record(atlasTrackingGeometry, m_trackingGeometryName, false).isFailure() ){
          ATH_MSG_WARNING( "Couldn't write TrackingGeometry to DetectorStore." );
@@ -189,6 +203,41 @@ StatusCode Trk::TrackingGeometrySvc::trackingGeometryInit(IOVSVC_CALLBACK_ARGS_P
     return StatusCode::SUCCESS;
 }
 
+void Trk::TrackingGeometrySvc::setTrackingGeometry(const Trk::TrackingGeometry *ptr) {
+   if (!m_useConditionsData) {
+      ATH_MSG_FATAL("Logic error:  external TrackingGeometry provided despite being configured to build an internal one.");
+   }
+   if (m_pDetStore->contains<Trk::TrackingGeometry>(m_trackingGeometryName)) {
+      const TrackingGeometry *mirror;
+      if (m_pDetStore->retrieve(mirror, m_trackingGeometryName).isFailure()) {
+         ATH_MSG_FATAL("TrackingGeometry " << m_trackingGeometryName << " exists, but cannot be retrieved.");
+      }
+      TrackingGeometry *non_const_mirror ATLAS_NOT_THREAD_SAFE = const_cast<TrackingGeometry *>(mirror);
+      static_cast<Trk::TrackingGeometryMirror *>(non_const_mirror)->update(const_cast<TrackingGeometry *>(ptr));
+      if (msgLvl(MSG::VERBOSE)) {
+         ATH_MSG_VERBOSE( "Setting TrackingGeometry from cond alg ptr="  << static_cast<const void *>(ptr));
+         static_cast<const Trk::TrackingGeometryMirror *>(mirror)->dump(msg(MSG::VERBOSE), "external TrackingGeometry dump ");
+      }
+   }
+   else {
+      std::unique_ptr<Trk::TrackingGeometryMirror> mirror=std::make_unique<Trk::TrackingGeometryMirror>(const_cast<TrackingGeometry *>(ptr));
+      if (msgLvl(MSG::VERBOSE)) {
+         ATH_MSG_VERBOSE( "Setting TrackingGeometry from cond alg ptr="  << static_cast<const void *>(ptr));
+         mirror->dump(msg(MSG::VERBOSE), "external TrackingGeometry dump ");
+      }
+
+      // record the resulting TrackingGeometry
+      if (m_pDetStore->record(static_cast<TrackingGeometry *>(mirror.release()), m_trackingGeometryName, false).isFailure() ){
+         ATH_MSG_WARNING( "Couldn't write TrackingGeometry to DetectorStore." );
+      } else {
+         ATH_MSG_DEBUG( "initialize() successful: TrackingGeometry '" << m_trackingGeometryName << "' built and written to DetectorStore." );
+      }
+   }
+   m_trackingGeometry=ptr;
+}
+void Trk::TrackingGeometrySvc::trackingGeometryNotSet() const {
+   ATH_MSG_WARNING( "TrackingGeometry not set  ptr="  << static_cast<const void *>(m_trackingGeometry));
+}
 
 /** Finalize Service */
 StatusCode Trk::TrackingGeometrySvc::finalize()
@@ -201,6 +250,17 @@ StatusCode Trk::TrackingGeometrySvc::finalize()
     ATH_MSG_INFO( "[ memory usage ] ---------------------------------------------------------"  );
 #endif
 
+    if (m_useConditionsData) {
+       const TrackingGeometry *clone=nullptr;
+       if (m_pDetStore->retrieve(clone, m_trackingGeometryName).isFailure() ){
+          ATH_MSG_WARNING( "Failed to retrieve TrackingGeometry " << m_trackingGeometryName << " from DetectorStore." );
+       }
+       if (clone) {
+          static_cast<Trk::TrackingGeometryMirror *>(const_cast<TrackingGeometry *>(clone))->cleanup();
+          ATH_MSG_WARNING( "Cleaned TrackingGeometryMirror " << m_trackingGeometryName << "." );
+       }
+    }
+
     ATH_MSG_INFO( "finalize() successful." );
     return StatusCode::SUCCESS;
 }
@@ -217,4 +277,3 @@ StatusCode Trk::TrackingGeometrySvc::queryInterface(const InterfaceID& riid, voi
   addRef();
   return StatusCode::SUCCESS;
 }
-
diff --git a/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h b/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h
index 48d2fea91fc7ec0bd4970c86ba8278fcc74a50fc..0527ad54dfce94eeb493e75abf3e14862882a006 100755
--- a/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h
+++ b/Tracking/TrkDetDescr/TrkGeometry/TrkGeometry/TrackingGeometry.h
@@ -63,13 +63,19 @@ namespace Trk {
     
     friend class GeometryBuilderCond;
     friend class IGeometryBuilderCond;
-  
+
+    // give access to private members to allow the  class below to mirror a TrackingGeometry.
+    // This is needed for a temporary workaround to allow using the TrackingGeometryCondAlg and
+    // TrackingGeometrySvc at the same time.
+    // @TODO revert once the TrackingGeometrySvc is completly replaced
+    friend class TrackingGeometryMirror;
+
     public :
       /** Constructor */
       TrackingGeometry(const TrackingVolume* highestVolume, NavigationLevel navlevel=globalSearch);
       
       /** Destructor */
-      ~TrackingGeometry();
+      virtual ~TrackingGeometry();
       
       /** return the world */
       const TrackingVolume* highestTrackingVolume() const;