diff --git a/PhysicsAnalysis/MCTruthClassifier/CMakeLists.txt b/PhysicsAnalysis/MCTruthClassifier/CMakeLists.txt
index 64ff08b68225bc5a091d39e50b101ea03ec991bc..a6abcb25ed965bb3f8a38464461b84617c39df84 100644
--- a/PhysicsAnalysis/MCTruthClassifier/CMakeLists.txt
+++ b/PhysicsAnalysis/MCTruthClassifier/CMakeLists.txt
@@ -17,14 +17,15 @@ elseif( XAOD_ANALYSIS )
 else()
    set( extra_deps GaudiKernel
       Reconstruction/RecoTools/ParticlesInConeTools
+      Reconstruction/RecoTools/RecoToolInterfaces
       PRIVATE
       Generators/TruthUtils
-      Reconstruction/RecoTools/RecoToolInterfaces
       Tracking/TrkEvent/TrkEventPrimitives
       Tracking/TrkEvent/TrkParametersIdentificationHelpers
+      Tracking/TrkEvent/TrkCaloExtension
       Control/AthenaKernel )
-   set( extra_libs GaudiKernel
-      PRIVATE_LINK_LIBRARIES GeneratorObjects RecoToolInterfaces
+   set( extra_libs GaudiKernel RecoToolInterfaces
+      PRIVATE_LINK_LIBRARIES GeneratorObjects 
       TrkEventPrimitives TrkParametersIdentificationHelpers )
 endif()
 
diff --git a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h
index 8ac2f28ad4a7a31d9728eaa1d033807c2fcafa84..f0b6804bbdc4dcf4b8300a5b2ca8918811cfd8eb 100644
--- a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h
+++ b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -13,7 +13,7 @@
     Interface for the PhysicsAnalysis/MCTruthClassifier/MCTruthclassifier
     @author Frederic Derue derue@lpnhe.in2p3.fr
     CREATED : 01/09/2008
-    MODIFIED :
+    MODIFIED : 
 */
 
 #include "AsgTools/IAsgTool.h"
@@ -26,15 +26,20 @@
 #include "xAODEgamma/PhotonFwd.h"
 #include "xAODTracking/TrackParticleFwd.h"
 #include "xAODCaloEvent/CaloClusterFwd.h"
+
 #include "xAODTruth/TruthParticle.h"
 #include "xAODMuon/Muon.h"
 #include "xAODJet/Jet.h"
 
+#include <memory>
+#include <unordered_map>
+
 
 #define MCTRUTHCLASSIFIER_CONST
 
 
 #ifndef XAOD_ANALYSIS
+#include "RecoToolInterfaces/IParticleCaloExtensionTool.h"
 namespace HepMC {
   class GenParticle;
 }
@@ -45,8 +50,9 @@ class IMCTruthClassifier : virtual public asg::IAsgTool {
      
   ASG_TOOL_INTERFACE(IMCTruthClassifier)
     public:
-
-
+#ifndef XAOD_ANALYSIS
+    typedef  std::unordered_map<size_t,std::unique_ptr<Trk::CaloExtension>> Cache;
+#endif
   // Additional information that can be returned by the classifier.
   // Originally, these were all held in member variables in the classifier,
   // but that prevents the classifier methods from being made const.
@@ -55,6 +61,7 @@ class IMCTruthClassifier : virtual public asg::IAsgTool {
   class Info
   {
   public:
+
     const xAOD::TruthParticle* genPart = nullptr;
 
     MCTruthPartClassifier::ParticleOutCome particleOutCome = MCTruthPartClassifier::UnknownOutCome;
@@ -75,7 +82,9 @@ class IMCTruthClassifier : virtual public asg::IAsgTool {
     const xAOD::TruthParticle* photonMother = nullptr;
 
     const xAOD::TruthParticle* bkgElecMother = nullptr;
-
+#ifndef XAOD_ANALYSIS
+    Cache *extrapolationCache = nullptr;
+#endif
     std::vector<const xAOD::TruthParticle*> egPartPtr;
     std::vector<float> egPartdR;
     std::vector<std::pair<MCTruthPartClassifier::ParticleType,MCTruthPartClassifier::ParticleOrigin> > egPartClas;
diff --git a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h
index 50a352f5006281473bf15461d0b9d90fa58c6e35..3e15deae45072ec3bc15808fefcc715ad2373c77 100644
--- a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h
+++ b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef MCTRUTHCLASSIFIER_MCTRUTHCLASSIFIER_H
@@ -17,6 +17,7 @@ Updated:
 #include "AsgTools/AsgTool.h"
 #include "MCTruthClassifier/MCTruthClassifierDefs.h"
 #include "MCTruthClassifier/IMCTruthClassifier.h"
+
 // EDM includes
 
 #include "xAODTruth/TruthParticleContainerFwd.h"
@@ -128,7 +129,7 @@ class MCTruthClassifier : virtual public IMCTruthClassifier , public asg::AsgToo
    //
    static double partCharge(const xAOD::TruthParticle*);
 #ifndef XAOD_ANALYSIS
-   bool genPartToCalo(const xAOD::CaloCluster* , const xAOD::TruthParticle* , bool, double&, bool& ) const;
+   bool genPartToCalo(const xAOD::CaloCluster* , const xAOD::TruthParticle* , bool, double&, bool&, Cache * ) const;
    const xAOD::TruthParticle* egammaClusMatch(const xAOD::CaloCluster*, bool,
                                               Info* info) const;
 #endif
diff --git a/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifier.cxx b/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifier.cxx
index 0389a6850786a8fafec3e6193b43b458b0dd8a5c..401a600c4e0502e51e1ba3dfe7b1c5d26687eb7e 100644
--- a/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifier.cxx
+++ b/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifier.cxx
@@ -152,7 +152,6 @@ MCTruthClassifier::particleTruthClassifier(const xAOD::TruthParticle  *thePart,
   ParticleOrigin partOrig = NonDefined;  
  
   if (info) {
-    *info = Info();
     info->genPart = thePart;
   }
 
@@ -330,7 +329,6 @@ MCTruthClassifier::particleTruthClassifier(const xAOD::TrackParticle *trkPtr,
 
   const xAOD::TruthParticle* genPart = getGenPart(trkPtr);
   if (info) {
-    *info = Info();
     info->genPart = genPart;
   }
   
@@ -369,7 +367,6 @@ MCTruthClassifier::particleTruthClassifier(const xAOD::Electron* elec,
   }
 
   if (info) {
-    *info = Info();
     info->genPart = genPart;
   }
 
@@ -392,8 +389,6 @@ MCTruthClassifier::particleTruthClassifier(const xAOD::Photon* phot,
   ParticleType   parttype = Unknown;
   ParticleOrigin partorig = NonDefined;
 
-  if (info)
-    *info = Info();
     
   const xAOD::CaloCluster* clus=phot->caloCluster();
   if(!clus) return std::make_pair(parttype,partorig);  
@@ -441,9 +436,6 @@ MCTruthClassifier::particleTruthClassifier(const xAOD::Muon* mu,
   //-----------------------------------------------------------------------------------------
   
   ATH_MSG_DEBUG( "Executing muon  Classifier" );
- 
-  if (info)
-   *info = Info();
 
   ParticleType   parttype = Unknown;
   ParticleOrigin partorig = NonDefined;
@@ -479,9 +471,6 @@ MCTruthClassifier::particleTruthClassifier(const xAOD::CaloCluster* clus,
   ParticleType   parttype = Unknown;
   ParticleOrigin partorig = NonDefined;
 
-  if (info){
-    *info = Info();
-  }
   if(!clus){
     return std::make_pair(parttype,partorig);  
   }
@@ -512,10 +501,6 @@ MCTruthClassifier::particleTruthClassifier(const xAOD::Jet* jet, bool DR,
 
   ATH_MSG_DEBUG( "Executing Classifier with jet Input" );
 
-  if (info){
-    *info = Info();
-  }
-
   ParticleType   parttype     = UnknownJet;
   ParticleOrigin partorig     = NonDefined;
   ParticleType   tempparttype = UnknownJet;
diff --git a/PhysicsAnalysis/MCTruthClassifier/src/MCTruthClassifierAthena.cxx b/PhysicsAnalysis/MCTruthClassifier/src/MCTruthClassifierAthena.cxx
index ea6dab830fbea78345406f41fdc7416161d84ae2..c7a727b0f9ec24ef234e0e1245a65ac88ebc4047 100644
--- a/PhysicsAnalysis/MCTruthClassifier/src/MCTruthClassifierAthena.cxx
+++ b/PhysicsAnalysis/MCTruthClassifier/src/MCTruthClassifierAthena.cxx
@@ -152,7 +152,7 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus,
 
     double dR(-999.);
     bool isNCone=false;
-    bool isExt = genPartToCalo(clus, thePart,isFwrdEle, dR, isNCone);
+    bool isExt = genPartToCalo(clus, thePart,isFwrdEle, dR, isNCone, info->extrapolationCache);
     if (!isExt) continue;
 
     theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(),thePart->barcode()%m_barcodeShift);
@@ -237,7 +237,7 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus,
     
     double dR(-999.);
     bool isNCone=false;
-    bool isExt = genPartToCalo(clus, thePart, false , dR, isNCone);
+    bool isExt = genPartToCalo(clus, thePart, false , dR, isNCone, info->extrapolationCache);
     if(!isExt) continue;
     
     theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(),thePart->barcode()%m_barcodeShift);
@@ -293,14 +293,15 @@ bool MCTruthClassifier::genPartToCalo(const xAOD::CaloCluster* clus,
 				      const xAOD::TruthParticle* thePart,
 				      bool isFwrdEle, 
 				      double& dRmatch,
-				      bool  & isNarrowCone) const {
+				      bool  & isNarrowCone,
+                                      Cache  *cache) const {
   dRmatch      = -999.;
   isNarrowCone = false;
 
   if ( thePart == 0 ) return false ;
 
-  std::unique_ptr<Trk::CaloExtension> caloExtension =m_caloExtensionTool->caloExtension(*thePart);
-  if( !caloExtension|| caloExtension->caloLayerIntersections().empty() ){
+  const Trk::CaloExtension* caloExtension =m_caloExtensionTool->caloExtension(*thePart, *cache );
+  if( caloExtension == nullptr || caloExtension->caloLayerIntersections().empty() ){
     ATH_MSG_WARNING("extrapolation of Truth Particle with eta  " << thePart->eta() 
 		    <<" and Pt " << thePart->pt() << " to calo failed");
     return false;
diff --git a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx
index 7255d0ef60c1e67ffd6a36572520970f5708ac53..6f8c1b53f3f562a4dd1cdcec994e213f932c533e 100644
--- a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx
+++ b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx
@@ -17,6 +17,9 @@
 #include "xAODTruth/TruthParticleAuxContainer.h"
 #include "xAODTruth/TruthEventContainer.h"
 
+#include "egammaInterfaces/IEMExtrapolationTools.h"
+
+
 typedef ElementLink<xAOD::TruthParticleContainer> TruthLink_t;
 typedef ElementLink<xAOD::CaloClusterContainer> ClusterLink_t;  
 typedef ElementLink<xAOD::ElectronContainer> ElectronLink_t;  
@@ -218,8 +221,13 @@ StatusCode egammaTruthAssociationAlg::match(const xAOD::TruthParticleContainer&
 
   writeDecorHandles<T> decoHandles(hkeys);
 
+  //Extrapolation Cache
+  Cache extrapolationCache{};
+
   for (auto particle : *decoHandles.readHandle()){
-    MCTruthInfo_t info = particleTruthClassifier(particle);
+
+    MCTruthInfo_t info = particleTruthClassifier(particle, &extrapolationCache);
+
     const xAOD::TruthParticle* truthParticle = info.genPart;
     if (truthParticle) {
       ElementLink<xAOD::TruthParticleContainer> link(truthParticle, truthParticles);
@@ -292,16 +300,12 @@ egammaTruthAssociationAlg::writeDecorHandles<T>::writeDecorHandles(const egammaT
 
 // ==========================================================================   
 template<class T> egammaTruthAssociationAlg::MCTruthInfo_t 
-egammaTruthAssociationAlg::particleTruthClassifier(const T* particle) {
+egammaTruthAssociationAlg::particleTruthClassifier(const T* particle, Cache *extrapolationCache) {
   MCTruthInfo_t info;
-#ifdef MCTRUTHCLASSIFIER_CONST
   IMCTruthClassifier::Info mcinfo;
+  mcinfo.extrapolationCache = extrapolationCache;
   auto ret = m_mcTruthClassifier->particleTruthClassifier(particle, &mcinfo);
   info.genPart = mcinfo.genPart;
-#else
-  auto ret = m_mcTruthClassifier->particleTruthClassifier(particle);
-  info.genPart = m_mcTruthClassifier->getGenPart();
-#endif
   info.first = ret.first;
   info.second = ret.second;
   return info;
@@ -309,28 +313,17 @@ egammaTruthAssociationAlg::particleTruthClassifier(const T* particle) {
 /** Template specialisation for electrons: 
  * second pass based on the cluster to find true photons **/
 template<> egammaTruthAssociationAlg::MCTruthInfo_t 
-egammaTruthAssociationAlg::particleTruthClassifier<xAOD::Electron>(const xAOD::Electron* electron) {
+egammaTruthAssociationAlg::particleTruthClassifier<xAOD::Electron>(const xAOD::Electron* electron, Cache *extrapolationCache) {
   MCTruthInfo_t info;
-#ifdef MCTRUTHCLASSIFIER_CONST
   IMCTruthClassifier::Info mcinfo;
+  mcinfo.extrapolationCache = extrapolationCache;
   auto ret = m_mcTruthClassifier->particleTruthClassifier(electron, &mcinfo);
-#else
-  auto ret = m_mcTruthClassifier->particleTruthClassifier(electron);
-#endif
   if (ret.first == MCTruthPartClassifier::Unknown &&
       !xAOD::EgammaHelpers::isFwdElectron(electron) && electron->caloCluster()){
     ATH_MSG_DEBUG("Trying cluster-based truth classification for electron");
-#ifdef MCTRUTHCLASSIFIER_CONST
     ret = m_mcTruthClassifier->particleTruthClassifier( electron->caloCluster(), &mcinfo);
-#else
-    ret = m_mcTruthClassifier->particleTruthClassifier( electron->caloCluster() );
-#endif
   }
-#ifdef MCTRUTHCLASSIFIER_CONST
   info.genPart = mcinfo.genPart;
-#else
-  info.genPart = m_mcTruthClassifier->getGenPart();
-#endif
   info.first = ret.first;
   info.second = ret.second;
   return info;
diff --git a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h
index 944b5eefcb42b3410ea2f10fd2cc6d76d34778bd..c56d9005e470e8f5fb34029ec0ef44389b48951a 100644
--- a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h
+++ b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h
@@ -35,7 +35,10 @@
 class egammaTruthAssociationAlg : public AthAlgorithm {
 
 public:
-  
+
+  typedef  std::unordered_map<size_t,std::unique_ptr<Trk::CaloExtension>> Cache;
+
+
   /** @brief constructor */
   egammaTruthAssociationAlg(const std::string& name, ISvcLocator* pSvcLocator);
   
@@ -55,6 +58,7 @@ private:
     MCTruthPartClassifier::ParticleType first;
     MCTruthPartClassifier::ParticleOrigin second;
     const xAOD::TruthParticle* genPart;
+    Cache *extrapolationCache;
   };
   
   /** @brief helper class to contain write docoration handle keys */
@@ -87,7 +91,7 @@ private:
 
   /** @brief return the result of MCTruthClassifier::particleTruthClassifier
     * or do a second pass for electrons based on the cluster to find true photons **/
-  template<class T> MCTruthInfo_t particleTruthClassifier(const T*) ;
+  template<class T> MCTruthInfo_t particleTruthClassifier(const T*, Cache *) ;
      
   /** @brief Create a copy a truth particle, add it to the new container and decorate it
     *  with a link to the original particle **/