From 256277c2fac0857c4704733e8a27fc16bb26db8e Mon Sep 17 00:00:00 2001
From: christos <christos@cern.ch>
Date: Thu, 7 Jan 2021 03:35:07 +0100
Subject: [PATCH] MCTruthClassifier : Pass the EventContext down the call chain

---
 .../MCTruthClassifier/IMCTruthClassifier.h    | 113 ++++++++-----
 .../MCTruthClassifier/MCTruthClassifier.h     |  12 +-
 .../MCTruthClassifier/Root/MCRecoToTruth.cxx  |   8 +-
 .../Root/MCTruthClassifierGen.cxx             |  48 ++++--
 .../src/MCTruthClassifierAthena.cxx           | 159 ++++++++++++------
 .../src/egammaTruthAssociationAlg.cxx         |  25 +--
 .../src/egammaTruthAssociationAlg.h           |   5 +-
 7 files changed, 241 insertions(+), 129 deletions(-)

diff --git a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h
index e9f6e0413a0e..3d240699e3b7 100644
--- a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h
+++ b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h
@@ -16,6 +16,7 @@
     MODIFIED :
 */
 
+#include "AsgTools/CurrentContext.h"
 #include "AsgTools/IAsgTool.h"
 #include "MCTruthClassifier/MCTruthClassifierDefs.h"
 #include "xAODTruth/TruthParticle.h"
@@ -39,7 +40,8 @@
 #include <AtlasHepMC/GenParticle.h>
 #endif
 
-#if !defined(XAOD_ANALYSIS) && !defined(GENERATIONBASE) // Can only be used in Athena
+#if !defined(XAOD_ANALYSIS) &&                                                 \
+  !defined(GENERATIONBASE) // Can only be used in Athena
 #include "RecoToolInterfaces/IParticleCaloExtensionTool.h"
 #endif
 
@@ -48,7 +50,8 @@ class IMCTruthClassifier : virtual public asg::IAsgTool
 
   ASG_TOOL_INTERFACE(IMCTruthClassifier)
 public:
-#if !defined(XAOD_ANALYSIS) && !defined(GENERATIONBASE) // Can only be used in Athena
+#if !defined(XAOD_ANALYSIS) &&                                                 \
+  !defined(GENERATIONBASE) // Can only be used in Athena
   typedef Trk::IParticleCaloExtensionTool::Cache Cache;
 #endif
   // Additional information that can be returned by the classifier.
@@ -59,15 +62,26 @@ public:
   class Info
   {
   public:
+    Info()
+      : eventContext(Gaudi::Hive::currentContext())
+    {}
+    Info(const EventContext& ctx)
+      : eventContext(ctx)
+    {}
+
+    ~Info() = default;
+
+    const EventContext& eventContext;
     const xAOD::TruthParticle* genPart = nullptr;
 
-    MCTruthPartClassifier::ParticleOutCome particleOutCome = MCTruthPartClassifier::UnknownOutCome;
+    MCTruthPartClassifier::ParticleOutCome particleOutCome =
+      MCTruthPartClassifier::UnknownOutCome;
 
     const xAOD::TruthParticle* mother = nullptr;
     long motherBarcode = 0;
     int motherPDG = 0;
 
-    int photonMotherBarcode = 0;
+    long photonMotherBarcode = 0;
     long photonMotherStatus = 0;
     int photonMotherPDG = 0;
     const xAOD::TruthParticle* photonMother = nullptr;
@@ -84,7 +98,9 @@ public:
 
     std::vector<const xAOD::TruthParticle*> egPartPtr;
     std::vector<float> egPartdR;
-    std::vector<std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin>> egPartClas;
+    std::vector<std::pair<MCTruthPartClassifier::ParticleType,
+                          MCTruthPartClassifier::ParticleOrigin>>
+      egPartClas;
 
     std::vector<const xAOD::TrackParticle*> cnvPhotTrkPtr;
     std::vector<const xAOD::TruthParticle*> cnvPhotTrkToTruthPart;
@@ -92,7 +108,8 @@ public:
     std::vector<MCTruthPartClassifier::ParticleOrigin> cnvPhotPartOrig;
 #endif
 
-#if !defined(XAOD_ANALYSIS) && !defined(GENERATIONBASE) /*Can only be used in Athena*/
+#if !defined(XAOD_ANALYSIS) &&                                                 \
+  !defined(GENERATIONBASE) /*Can only be used in Athena*/
     Cache* extrapolationCache = nullptr;
 #endif
   };
@@ -101,49 +118,67 @@ public:
   virtual ~IMCTruthClassifier(){};
 
   /* All get to see these*/
-  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> particleTruthClassifier(
-    const xAOD::TruthParticle*,
-    Info* info = nullptr) const = 0;
-  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> checkOrigOfBkgElec(
-    const xAOD::TruthParticle*,
-    Info* info = nullptr) const = 0;
+  virtual std::pair<MCTruthPartClassifier::ParticleType,
+                    MCTruthPartClassifier::ParticleOrigin>
+  particleTruthClassifier(const xAOD::TruthParticle*,
+                          Info* info = nullptr) const = 0;
 
-  virtual const xAOD::TruthParticle* isHadronFromB(const xAOD::TruthParticle*) const = 0;
+  virtual std::pair<MCTruthPartClassifier::ParticleType,
+                    MCTruthPartClassifier::ParticleOrigin>
+  checkOrigOfBkgElec(const xAOD::TruthParticle*,
+                     Info* info = nullptr) const = 0;
 
-  /// \brief main function used in \ref MCTruthClassifier returning the value from defOrigofParticle to \ref TruthClassificationDecorator
-  virtual unsigned int classify(const xAOD::TruthParticle *) const = 0;
+  virtual const xAOD::TruthParticle* isHadronFromB(
+    const xAOD::TruthParticle*) const = 0;
 
-  /// \brief function used in \ref MCTruthClassifier classifying truth particles with HepMC status 1 & 2
-  virtual unsigned int defOrigOfParticle(const xAOD::TruthParticle*) const = 0;    
+  /// \brief main function used in \ref MCTruthClassifier returning the value
+  /// from defOrigofParticle to \ref TruthClassificationDecorator
+  virtual unsigned int classify(const xAOD::TruthParticle*) const = 0;
 
+  /// \brief function used in \ref MCTruthClassifier classifying truth particles
+  /// with HepMC status 1 & 2
+  virtual unsigned int defOrigOfParticle(const xAOD::TruthParticle*) const = 0;
 
 #ifndef XAOD_ANALYSIS /*This can not run in Analysis Base*/
-  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> particleTruthClassifier(
-    HepMC::ConstGenParticlePtr,
-    Info* info = nullptr) const = 0;
+  virtual std::pair<MCTruthPartClassifier::ParticleType,
+                    MCTruthPartClassifier::ParticleOrigin>
+  particleTruthClassifier(HepMC::ConstGenParticlePtr,
+                          Info* info = nullptr) const = 0;
 
 #endif
   //
 #ifndef GENERATIONBASE /*These can not run in Generation only release*/
-  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> particleTruthClassifier(
-    const xAOD::TrackParticle*,
-    Info* info = nullptr) const = 0;
-  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> particleTruthClassifier(
-    const xAOD::Electron*,
-    Info* info = nullptr) const = 0;
-  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> particleTruthClassifier(
-    const xAOD::Photon*,
-    Info* info = nullptr) const = 0;
-  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> particleTruthClassifier(
-    const xAOD::Muon*,
-    Info* info = nullptr) const = 0;
-  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> particleTruthClassifier(
-    const xAOD::CaloCluster*,
-    Info* info = nullptr) const = 0;
-  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin>
-  particleTruthClassifier(const xAOD::Jet*, bool DR, Info* info = nullptr) const = 0;
-
-  virtual const xAOD::TruthParticle* getGenPart(const xAOD::TrackParticle*, Info* info = nullptr) const = 0;
+  virtual std::pair<MCTruthPartClassifier::ParticleType,
+                    MCTruthPartClassifier::ParticleOrigin>
+  particleTruthClassifier(const xAOD::TrackParticle*,
+                          Info* info = nullptr) const = 0;
+
+  virtual std::pair<MCTruthPartClassifier::ParticleType,
+                    MCTruthPartClassifier::ParticleOrigin>
+  particleTruthClassifier(const xAOD::Electron*,
+                          Info* info = nullptr) const = 0;
+
+  virtual std::pair<MCTruthPartClassifier::ParticleType,
+                    MCTruthPartClassifier::ParticleOrigin>
+  particleTruthClassifier(const xAOD::Photon*, Info* info = nullptr) const = 0;
+
+  virtual std::pair<MCTruthPartClassifier::ParticleType,
+                    MCTruthPartClassifier::ParticleOrigin>
+  particleTruthClassifier(const xAOD::Muon*, Info* info = nullptr) const = 0;
+
+  virtual std::pair<MCTruthPartClassifier::ParticleType,
+                    MCTruthPartClassifier::ParticleOrigin>
+  particleTruthClassifier(const xAOD::CaloCluster*,
+                          Info* info = nullptr) const = 0;
+
+  virtual std::pair<MCTruthPartClassifier::ParticleType,
+                    MCTruthPartClassifier::ParticleOrigin>
+  particleTruthClassifier(const xAOD::Jet*,
+                          bool DR,
+                          Info* info = nullptr) const = 0;
+
+  virtual const xAOD::TruthParticle* getGenPart(const xAOD::TrackParticle*,
+                                                Info* info = nullptr) const = 0;
 
 #endif
 };
diff --git a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h
index 81d0f257f64c..aadcdc136d88 100644
--- a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h
+++ b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h
@@ -193,8 +193,16 @@ private:
 
   /* Private functions */
 #if !defined(XAOD_ANALYSIS) && !defined(GENERATIONBASE) /*Athena Only*/
-  bool genPartToCalo(const xAOD::CaloCluster*, const xAOD::TruthParticle*, bool, double&, bool&, Cache* cache) const;
-  const xAOD::TruthParticle* egammaClusMatch(const xAOD::CaloCluster*, bool, Info* info) const;
+  bool genPartToCalo(const EventContext& ctx,
+                     const xAOD::CaloCluster*,
+                     const xAOD::TruthParticle*,
+                     bool,
+                     double&,
+                     bool&,
+                     Cache* cache) const;
+  const xAOD::TruthParticle* egammaClusMatch(const xAOD::CaloCluster*,
+                                             bool,
+                                             Info* info) const;
 #endif
 
 #ifndef GENERATIONBASE /*Disable when no recostruction packages are expected*/
diff --git a/PhysicsAnalysis/MCTruthClassifier/Root/MCRecoToTruth.cxx b/PhysicsAnalysis/MCTruthClassifier/Root/MCRecoToTruth.cxx
index 3f24f71d9770..5d236d50f4f4 100644
--- a/PhysicsAnalysis/MCTruthClassifier/Root/MCRecoToTruth.cxx
+++ b/PhysicsAnalysis/MCTruthClassifier/Root/MCRecoToTruth.cxx
@@ -416,7 +416,7 @@ MCTruthClassifier::findJetConstituents(const xAOD::Jet* jet,
                                                           << " has valid ReadHandle ");
 
     // find the matching truth particles
-    for (const auto thePart : *truthParticleContainerReadHandle) {
+    for (const auto *const thePart : *truthParticleContainerReadHandle) {
       // match truth particles to the jet
       if (thePart->status() == 1 && deltaR((*thePart), (*jet)) < m_jetPartDRMatch) {
         constituents.insert(thePart);
@@ -425,7 +425,7 @@ MCTruthClassifier::findJetConstituents(const xAOD::Jet* jet,
   } // end if DR
   else {
     xAOD::JetConstituentVector vec = jet->getConstituents();
-    for (auto particle0 : vec) {
+    for (const auto *particle0 : vec) {
       const xAOD::TruthParticle* thePart = dynamic_cast<const xAOD::TruthParticle*>(particle0->rawConstituent());
       if (thePart->status() == 1) {
         constituents.insert(thePart);
@@ -465,10 +465,10 @@ MCTruthClassifier::fracParticleInJet(const xAOD::TruthParticle* thePart,
     frac = 1.0 * intersect.size() / daughters.size();
   } else {
     double tot = 0;
-    for (auto daughter : daughters) {
+    for (const auto *daughter : daughters) {
       tot += 1.0 * daughter->pt();
     }
-    for (auto particle : intersect) {
+    for (const auto *particle : intersect) {
       frac += 1.0 * particle->pt() / tot;
     }
   }
diff --git a/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifierGen.cxx b/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifierGen.cxx
index aef379a04271..3c3841da32ff 100644
--- a/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifierGen.cxx
+++ b/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifierGen.cxx
@@ -24,15 +24,21 @@ MCTruthClassifier::particleTruthClassifier(HepMC::ConstGenParticlePtr thePart, I
     return std::make_pair(partType, partOrig);
 
   // Retrieve the links between HepMC and xAOD::TruthParticle
-  SG::ReadHandle<xAODTruthParticleLinkVector> truthParticleLinkVecReadHandle(m_truthLinkVecReadHandleKey);
+  const EventContext& ctx =
+    info ? info->eventContext : Gaudi::Hive::currentContext();
+
+  SG::ReadHandle<xAODTruthParticleLinkVector> truthParticleLinkVecReadHandle(
+    m_truthLinkVecReadHandleKey, ctx);
   if (!truthParticleLinkVecReadHandle.isValid()) {
     ATH_MSG_WARNING(
-      " Invalid ReadHandle for xAODTruthParticleLinkVector with key: " << truthParticleLinkVecReadHandle.key());
+      " Invalid ReadHandle for xAODTruthParticleLinkVector with key: "
+      << truthParticleLinkVecReadHandle.key());
     return std::make_pair(partType, partOrig);
   }
 
   for (const auto& entry : *truthParticleLinkVecReadHandle) {
-    if (entry->first.isValid() && entry->second.isValid() && HepMC::barcode(entry->first.cptr()) == HepMC::barcode(thePart)) {
+    if (entry->first.isValid() && entry->second.isValid() &&
+        HepMC::barcode(entry->first.cptr()) == HepMC::barcode(thePart)) {
       const xAOD::TruthParticle* truthParticle = *entry->second;
       if (!compareTruthParticles(thePart, truthParticle)) {
         // if the barcode/pdg id / status of the pair does not match
@@ -79,19 +85,25 @@ MCTruthClassifier::particleTruthClassifier(const xAOD::TruthParticle* thePart, I
   }
 
   // retrieve collection and get a pointer
-  if (!thePart)
+  if (!thePart){
     return std::make_pair(partType, partOrig);
+  }
+  const EventContext& ctx =
+    info ? info->eventContext : Gaudi::Hive::currentContext();
 
-  SG::ReadHandle<xAOD::TruthParticleContainer> truthParticleContainerReadHandle(m_truthParticleContainerKey);
+  SG::ReadHandle<xAOD::TruthParticleContainer> truthParticleContainerReadHandle(
+    m_truthParticleContainerKey,ctx);
 
   if (!truthParticleContainerReadHandle.isValid()) {
     ATH_MSG_WARNING(
-      " Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.key());
+      " Invalid ReadHandle for xAOD::TruthParticleContainer with key: "
+      << truthParticleContainerReadHandle.key());
     return std::make_pair(partType, partOrig);
   }
 
-  ATH_MSG_DEBUG("xAODTruthParticleContainer with key  " << truthParticleContainerReadHandle.key()
-                                                        << " has valid ReadHandle ");
+  ATH_MSG_DEBUG("xAODTruthParticleContainer with key  "
+                << truthParticleContainerReadHandle.key()
+                << " has valid ReadHandle ");
 
   int iParticlePDG = thePart->pdgId();
   // status=10902 in Pythia?
@@ -318,7 +330,7 @@ unsigned int MCTruthClassifier::classify(const xAOD::TruthParticle  *thePart) co
 //--------------------------------------------------------------------------------------
 
   ATH_MSG_DEBUG( "Executing classify" );
-  
+
   if(!thePart){ATH_MSG_WARNING( "Passed a nullptr" ); return 0;}
 
   return defOrigOfParticle(thePart);
@@ -326,7 +338,7 @@ unsigned int MCTruthClassifier::classify(const xAOD::TruthParticle  *thePart) co
 
 //-------------------------------------------------------------------------------
 unsigned int MCTruthClassifier::defOrigOfParticle(const xAOD::TruthParticle  *thePart) const {
-//-------------------------------------------------------------------------------  
+//-------------------------------------------------------------------------------
 
   ATH_MSG_DEBUG( "Executing DefOrigOfParticle " );
 
@@ -341,8 +353,8 @@ unsigned int MCTruthClassifier::defOrigOfParticle(const xAOD::TruthParticle  *th
     isStable = 1;
   }
   if(isStable == 1){
-    const xAOD::TruthVertex* partOriVert=thePart->hasProdVtx() ? thePart->prodVtx():0;
-    if( partOriVert!=0 ) {
+    const xAOD::TruthVertex* partOriVert=thePart->hasProdVtx() ? thePart->prodVtx():nullptr;
+    if( partOriVert!=nullptr ) {
       for (unsigned int ipIn=0; ipIn<partOriVert->nIncomingParticles(); ++ipIn) {
         const xAOD::TruthParticle* theMother=partOriVert->incomingParticle(ipIn);
         if(!theMother) continue;
@@ -355,8 +367,8 @@ unsigned int MCTruthClassifier::defOrigOfParticle(const xAOD::TruthParticle  *th
         }
 
         while (mybeam==0){
-          const xAOD::TruthVertex* partOriVert=thePart->hasProdVtx() ? thePart->prodVtx():0;
-          if( partOriVert!=0 ) {
+          const xAOD::TruthVertex* partOriVert=thePart->hasProdVtx() ? thePart->prodVtx():nullptr;
+          if( partOriVert!=nullptr ) {
             const xAOD::TruthParticle* theMother=partOriVert->incomingParticle(0);
             if(!theMother) continue;
 
@@ -366,7 +378,7 @@ unsigned int MCTruthClassifier::defOrigOfParticle(const xAOD::TruthParticle  *th
             if(MC::PID::isTau(theMother->pdgId()) && theMother->status() == 2 ){
               fromTau = 1; isHadTau =0;
             }
-            if(isHadron(theMother) == true && theMother->status() == 2 ) {
+            if(isHadron(theMother) && theMother->status() == 2 ) {
               fromhad = 1;
               if(fromTau == 1){
                 isHadTau = 1;
@@ -407,7 +419,7 @@ unsigned int MCTruthClassifier::defOrigOfParticle(const xAOD::TruthParticle  *th
 
   return outputvalue;
 }
-      
+
 //-------------------------------------------------------------------------------
 ParticleType
 MCTruthClassifier::defTypeOfElectron(ParticleOrigin EleOrig, bool isPrompt) const
@@ -2951,7 +2963,7 @@ MCTruthClassifier::findFinalStatePart(const xAOD::TruthVertex* EndVert) const
       if (pVert != nullptr) {
         vecPart = findFinalStatePart(pVert);
         if (!vecPart.empty())
-          for (auto i : vecPart)
+          for (const auto *i : vecPart)
             finalStatePart.push_back(i);
       }
     }
@@ -3101,7 +3113,7 @@ MCTruthClassifier::barcode_to_particle(const xAOD::TruthParticleContainer* Truth
   // temporary solution?
   const xAOD::TruthParticle* ptrPart = nullptr;
 
-  for (const auto truthParticle : *TruthTES) {
+  for (const auto *const truthParticle : *TruthTES) {
     if (truthParticle->barcode() == bc) {
       ptrPart = truthParticle;
       break;
diff --git a/PhysicsAnalysis/MCTruthClassifier/src/MCTruthClassifierAthena.cxx b/PhysicsAnalysis/MCTruthClassifier/src/MCTruthClassifierAthena.cxx
index 14a120489628..20b6195bc9d0 100644
--- a/PhysicsAnalysis/MCTruthClassifier/src/MCTruthClassifierAthena.cxx
+++ b/PhysicsAnalysis/MCTruthClassifier/src/MCTruthClassifierAthena.cxx
@@ -47,7 +47,7 @@ EtaPhiCaloHelper(const Trk::CaloExtension* caloExtension,
     Trk::TrackParametersIdHelper parsIdHelper;
 
     // loop over calo layers
-    for (auto cur : caloExtension->caloLayerIntersections()) {
+    for (const auto *cur : caloExtension->caloLayerIntersections()) {
 
       // only use entry layer
       if (!parsIdHelper.isEntryToVolume(cur->cIdentifier())) {
@@ -82,18 +82,25 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus, bool isFwrdEle
   ATH_MSG_DEBUG("Executing egammaClusMatch ");
 
   const xAOD::TruthParticle* theMatchPart = nullptr;
+  Trk::IParticleCaloExtensionTool::Cache* cache =
+    info ? info->extrapolationCache : nullptr;
+  const EventContext& ctx =
+    info ? info->eventContext : Gaudi::Hive::currentContext();
 
   // retrieve collection and get a pointer
-  SG::ReadHandle<xAOD::TruthParticleContainer> truthParticleContainerReadHandle(m_truthParticleContainerKey);
+  SG::ReadHandle<xAOD::TruthParticleContainer> truthParticleContainerReadHandle(
+    m_truthParticleContainerKey, ctx);
 
   if (!truthParticleContainerReadHandle.isValid()) {
     ATH_MSG_WARNING(
-      " Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.key());
+      " Invalid ReadHandle for xAOD::TruthParticleContainer with key: "
+      << truthParticleContainerReadHandle.key());
     return theMatchPart;
   }
 
-  ATH_MSG_DEBUG("xAODTruthParticleContainer with key  " << truthParticleContainerReadHandle.key()
-                                                        << " has valid ReadHandle ");
+  ATH_MSG_DEBUG("xAODTruthParticleContainer with key  "
+                << truthParticleContainerReadHandle.key()
+                << " has valid ReadHandle ");
 
   const xAOD::TruthParticle* theEgamma(nullptr);
   const xAOD::TruthParticle* theLeadingPartInCone(nullptr);
@@ -110,10 +117,12 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus, bool isFwrdEle
 
   double etaClus = clus->etaBE(2);
   double phiClus = clus->phiBE(2);
-  if (etaClus < -900)
+  if (etaClus < -900){
     etaClus = clus->eta();
-  if (phiClus < -900)
+  }
+  if (phiClus < -900){
     phiClus = clus->phi();
+  }
 
   std::vector<const xAOD::TruthParticle*> tps;
   if (!m_truthInConeTool->particlesInCone(etaClus, phiClus, 0.5, tps)) {
@@ -121,50 +130,67 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus, bool isFwrdEle
     return theMatchPart;
   }
 
-  for (const auto thePart : tps) {
+  for (const auto *const thePart : tps) {
     // loop over the stable particle
-    if (thePart->status() != 1)
+    if (thePart->status() != 1){
       continue;
+    }
     // excluding G4 particle
-    if (thePart->barcode() >= m_barcodeG4Shift)
+    if (thePart->barcode() >= m_barcodeG4Shift){
       continue;
+    }
     long iParticlePDG = thePart->pdgId();
     // excluding neutrino
-    if (abs(iParticlePDG) == 12 || abs(iParticlePDG) == 14 || abs(iParticlePDG) == 16)
+    if (abs(iParticlePDG) == 12 || abs(iParticlePDG) == 14 ||
+        abs(iParticlePDG) == 16) {
       continue;
+    }
 
     double pt = thePart->pt() / GeV;
     double q = partCharge(thePart);
     // exclude charged particles with pT<1 GeV
-    if (q != 0 && pt < m_pTChargePartCut)
+    if (q != 0 && pt < m_pTChargePartCut) {
       continue;
-    if (q == 0 && pt < m_pTNeutralPartCut)
+    }
+    if (q == 0 && pt < m_pTNeutralPartCut) {
       continue;
+    }
 
     // eleptical cone  for extrapolations m_partExtrConePhi X m_partExtrConeEta
     if (!isFwrdEle && m_ROICone &&
         std::pow((detPhi(phiClus, thePart->phi()) / m_partExtrConePhi), 2) +
             std::pow((detEta(etaClus, thePart->eta()) / m_partExtrConeEta), 2) >
-          1.0)
+          1.0) {
       continue;
+    }
 
-    // Also check if the clus and true have different sign , i they need both to be <0 or >0
-    if (isFwrdEle &&                                 // It is forward and
-        (((etaClus < 0) - (thePart->eta() < 0) != 0) // The truth eta has different sign wrt to the fwd electron
-         || (std::fabs(thePart->eta()) < m_FwdElectronTruthExtrEtaCut) // or the truth is less than 2.4 (default cut)
+    // Also check if the clus and true have different sign , i they need both to
+    // be <0 or >0
+    if (isFwrdEle && // It is forward and
+        (((etaClus < 0) - (thePart->eta() < 0) !=
+          0) // The truth eta has different sign wrt to the fwd electron
+         || (std::fabs(thePart->eta()) <
+             m_FwdElectronTruthExtrEtaCut) // or the truth is less than 2.4
+                                           // (default cut)
          || (std::fabs(thePart->eta() - etaClus) >
-             m_FwdElectronTruthExtrEtaWindowCut) // or if the delta Eta between el and truth is  > 0.15
-         )                                       // then do no extrapolate this truth Particle for this fwd electron
-    )
+             m_FwdElectronTruthExtrEtaWindowCut) // or if the delta Eta between
+                                                 // el and truth is  > 0.15
+         ) // then do no extrapolate this truth Particle for this fwd electron
+    ) {
       continue;
+    }
 
     double dR(-999.);
     bool isNCone = false;
-    bool isExt = genPartToCalo(clus, thePart, isFwrdEle, dR, isNCone, info->extrapolationCache);
-    if (!isExt)
+
+    bool isExt =
+      genPartToCalo(ctx, clus, thePart, isFwrdEle, dR, isNCone, cache);
+    if (!isExt) {
       continue;
+    }
 
-    theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(), thePart->barcode() % m_barcodeShift);
+    theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(),
+                                       thePart->barcode() % m_barcodeShift);
 
     if (info) {
       info->egPartPtr.push_back(thePart);
@@ -175,20 +201,24 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus, bool isFwrdEle
     // Gen particles
     // Not forward
     if (!isFwrdEle) {
-      // the leading photon or electron  inside narrow eleptical cone m_phtClasConePhi  X m_phtClasConeEta
-      if ((iParticlePDG == 22 || abs(iParticlePDG) == 11) && isNCone && pt > LeadingPhtPT) {
+      // the leading photon or electron  inside narrow eleptical cone
+      // m_phtClasConePhi  X m_phtClasConeEta
+      if ((iParticlePDG == 22 || abs(iParticlePDG) == 11) && isNCone &&
+          pt > LeadingPhtPT) {
         theEgamma = thePart;
         LeadingPhtPT = pt;
         LeadingPhtdR = dR;
       }
-      // leading particle (excluding photon and electron) inside narrow eleptic cone m_phtClasConePhi  X
-      // m_phtClasConeEta
-      if ((iParticlePDG != 22 && abs(iParticlePDG) != 11) && isNCone && pt > LeadingPartPT) {
+      // leading particle (excluding photon and electron) inside narrow eleptic
+      // cone m_phtClasConePhi  X m_phtClasConeEta
+      if ((iParticlePDG != 22 && abs(iParticlePDG) != 11) && isNCone &&
+          pt > LeadingPartPT) {
         theLeadingPartInCone = thePart;
         LeadingPartPT = pt;
         LeadingPartdR = dR;
       };
-      // the best dR matched particle outside  narrow eleptic cone cone m_phtClasConePhi  X m_phtClasConeEta
+      // the best dR matched particle outside  narrow eleptic cone cone
+      // m_phtClasConePhi  X m_phtClasConeEta
       if (!isNCone && dR < BestPartdR) {
         theBestPartOutCone = thePart;
         BestPartdR = dR;
@@ -202,24 +232,32 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus, bool isFwrdEle
   } // end cycle for Gen particle
 
   if (theEgamma != nullptr) {
-    theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(), theEgamma->barcode() % m_barcodeShift);
-    if (info)
+    theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(),
+                                       theEgamma->barcode() % m_barcodeShift);
+    if (info) {
       info->deltaRMatch = LeadingPhtdR;
+    }
   } else if (theLeadingPartInCone != nullptr) {
     theMatchPart =
-      barcode_to_particle(truthParticleContainerReadHandle.ptr(), theLeadingPartInCone->barcode() % m_barcodeShift);
-    if (info)
+      barcode_to_particle(truthParticleContainerReadHandle.ptr(),
+                          theLeadingPartInCone->barcode() % m_barcodeShift);
+    if (info) {
       info->deltaRMatch = LeadingPartdR;
+    }
   } else if (theBestPartOutCone != nullptr) {
     theMatchPart =
-      barcode_to_particle(truthParticleContainerReadHandle.ptr(), theBestPartOutCone->barcode() % m_barcodeShift);
-    if (info)
+      barcode_to_particle(truthParticleContainerReadHandle.ptr(),
+                          theBestPartOutCone->barcode() % m_barcodeShift);
+    if (info) {
       info->deltaRMatch = BestPartdR;
+    }
   } else if (isFwrdEle && theBestPartdR != nullptr) {
     theMatchPart =
-      barcode_to_particle(truthParticleContainerReadHandle.ptr(), theBestPartdR->barcode() % m_barcodeShift);
-    if (info)
+      barcode_to_particle(truthParticleContainerReadHandle.ptr(),
+                          theBestPartdR->barcode() % m_barcodeShift);
+    if (info) {
       info->deltaRMatch = BestPartdR;
+    }
   } else {
     theMatchPart = nullptr;
   }
@@ -228,7 +266,7 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus, bool isFwrdEle
   }
 
   // additional loop over G4 particles,
-  for (const auto thePart : tps) {
+  for (const auto *const thePart : tps) {
     // loop over the stable particle
     if (thePart->status() != 1)
       continue;
@@ -251,18 +289,23 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus, bool isFwrdEle
     double pt = thePart->pt() / GeV;
     double q = partCharge(thePart);
     // exclude charged particles with pT<1 GeV
-    if (q != 0 && pt < m_pTChargePartCut)
+    if (q != 0 && pt < m_pTChargePartCut){
       continue;
-    if (q == 0 && pt < m_pTNeutralPartCut)
+    }
+    if (q == 0 && pt < m_pTNeutralPartCut){
       continue;
+    }
 
     double dR(-999.);
     bool isNCone = false;
-    bool isExt = genPartToCalo(clus, thePart, isFwrdEle, dR, isNCone, info->extrapolationCache);
-    if (!isExt)
+    bool isExt =
+      genPartToCalo(ctx, clus, thePart, isFwrdEle, dR, isNCone, cache);
+    if (!isExt){
       continue;
+    }
 
-    theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(), thePart->barcode() % m_barcodeShift);
+    theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(),
+                                       thePart->barcode() % m_barcodeShift);
 
     if (info) {
       info->egPartPtr.push_back(thePart);
@@ -291,19 +334,25 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus, bool isFwrdEle
   } // end cycle for G4 particle
 
   if (theEgamma != nullptr) {
-    theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(), theEgamma->barcode() % m_barcodeShift);
-    if (info)
+    theMatchPart = barcode_to_particle(truthParticleContainerReadHandle.ptr(),
+                                       theEgamma->barcode() % m_barcodeShift);
+    if (info) {
       info->deltaRMatch = LeadingPhtdR;
+    }
   } else if (theLeadingPartInCone != nullptr) {
     theMatchPart =
-      barcode_to_particle(truthParticleContainerReadHandle.ptr(), theLeadingPartInCone->barcode() % m_barcodeShift);
-    if (info)
+      barcode_to_particle(truthParticleContainerReadHandle.ptr(),
+                          theLeadingPartInCone->barcode() % m_barcodeShift);
+    if (info) {
       info->deltaRMatch = LeadingPartdR;
+    }
   } else if (theBestPartOutCone != nullptr) {
     theMatchPart =
-      barcode_to_particle(truthParticleContainerReadHandle.ptr(), theBestPartOutCone->barcode() % m_barcodeShift);
-    if (info)
+      barcode_to_particle(truthParticleContainerReadHandle.ptr(),
+                          theBestPartOutCone->barcode() % m_barcodeShift);
+    if (info) {
       info->deltaRMatch = BestPartdR;
+    }
   } else {
     theMatchPart = nullptr;
   }
@@ -314,7 +363,8 @@ MCTruthClassifier::egammaClusMatch(const xAOD::CaloCluster* clus, bool isFwrdEle
 
 //--------------------------------------------------------------
 bool
-MCTruthClassifier::genPartToCalo(const xAOD::CaloCluster* clus,
+MCTruthClassifier::genPartToCalo(const EventContext& ctx,
+                                 const xAOD::CaloCluster* clus,
                                  const xAOD::TruthParticle* thePart,
                                  bool isFwrdEle,
                                  double& dRmatch,
@@ -344,17 +394,18 @@ MCTruthClassifier::genPartToCalo(const xAOD::CaloCluster* clus,
     // FCAL
     sample = CaloSampling::FCAL2;
 
-  } else
+  } else {
     return false;
+  }
 
   double etaCalo = -99;
   double phiCalo = -99;
   bool extensionOK = false;
   if (cache) {
-    const Trk::CaloExtension* caloExtension = m_caloExtensionTool->caloExtension(*thePart, *cache);
+    const Trk::CaloExtension* caloExtension = m_caloExtensionTool->caloExtension(ctx,*thePart, *cache);
     extensionOK = EtaPhiCaloHelper(caloExtension, sample, etaCalo, phiCalo);
   } else {
-    std::unique_ptr<Trk::CaloExtension> caloExtension = m_caloExtensionTool->caloExtension(*thePart);
+    std::unique_ptr<Trk::CaloExtension> caloExtension = m_caloExtensionTool->caloExtension(ctx,*thePart);
     extensionOK = EtaPhiCaloHelper(caloExtension.get(), sample, etaCalo, phiCalo);
   }
   if (!extensionOK) {
diff --git a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx
index 643c7e50af63..6f4c9891f93e 100644
--- a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx
+++ b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx
@@ -106,8 +106,10 @@ egammaTruthAssociationAlg::execute(const EventContext& ctx) const
       const xAOD::TruthParticle* truthParticle = *truthParticleLink;
       if (!isPromptEgammaParticle(truthParticle))
         continue;
-      getNewTruthParticle(
-        *egammaTruthContainer, truthParticle, truthParticleLink.getDataPtr());
+      getNewTruthParticle(ctx,
+                          *egammaTruthContainer,
+                          truthParticle,
+                          truthParticleLink.getDataPtr());
     }
   }
   // Decorate containers with truth info, including links to truth particles
@@ -196,11 +198,11 @@ egammaTruthAssociationAlg::isPromptEgammaParticle(
 
 void
 egammaTruthAssociationAlg::getNewTruthParticle(
+  const EventContext& ctx,
   xAOD::TruthParticleContainer& egammaTruthContainer,
   const xAOD::TruthParticle* truth,
   const xAOD::TruthParticleContainer* oldContainer) const
 {
-  ATH_MSG_DEBUG("In getNewTruthParticle");
   xAOD::TruthParticle* truthParticle = new xAOD::TruthParticle();
   egammaTruthContainer.push_back(truthParticle);
   truthParticle->setPdgId(truth->pdgId());
@@ -230,15 +232,13 @@ egammaTruthAssociationAlg::getNewTruthParticle(
   }
   accElLink(*truthParticle) = ElectronLink_t();
   accPhLink(*truthParticle) = PhotonLink_t();
-  accTruthLink(*truthParticle) = TruthLink_t(truth, *oldContainer);
+  accTruthLink(*truthParticle) = TruthLink_t(truth, *oldContainer,ctx);
   accTruthLink(*truthParticle).toPersistent();
-  ATH_MSG_DEBUG("Decorating truth particle with link to old truth, index = "
-                << accTruthLink(*truthParticle).index());
   // MCTruthClassifier info
-  auto info = m_mcTruthClassifier->particleTruthClassifier(truth);
+  IMCTruthClassifier::Info mcinfo(ctx);
+  auto info = m_mcTruthClassifier->particleTruthClassifier(truth,&mcinfo);
   accType(*truthParticle) = static_cast<int>(info.first);
   accOrigin(*truthParticle) = static_cast<int>(info.second);
-  ATH_MSG_DEBUG("Exiting getNewTruthParticle");
 }
 
 xAOD::TruthParticle*
@@ -301,11 +301,12 @@ egammaTruthAssociationAlg::writeDecorHandles<T>::writeDecorHandles(
 template<class T>
 egammaTruthAssociationAlg::MCTruthInfo_t
 egammaTruthAssociationAlg::particleTruthClassifier(
+  const EventContext& ctx,
   const T* particle,
   Cache* extrapolationCache) const
 {
   MCTruthInfo_t info;
-  IMCTruthClassifier::Info mcinfo;
+  IMCTruthClassifier::Info mcinfo(ctx);
   mcinfo.extrapolationCache = extrapolationCache;
   auto ret = m_mcTruthClassifier->particleTruthClassifier(particle, &mcinfo);
   info.genPart = mcinfo.genPart;
@@ -319,11 +320,12 @@ egammaTruthAssociationAlg::particleTruthClassifier(
 template<>
 egammaTruthAssociationAlg::MCTruthInfo_t
 egammaTruthAssociationAlg::particleTruthClassifier<xAOD::Electron>(
+  const EventContext& ctx,
   const xAOD::Electron* electron,
   Cache* extrapolationCache) const
 {
   MCTruthInfo_t info;
-  IMCTruthClassifier::Info mcinfo;
+  IMCTruthClassifier::Info mcinfo(ctx);
   mcinfo.extrapolationCache = extrapolationCache;
   auto ret = m_mcTruthClassifier->particleTruthClassifier(electron, &mcinfo);
   if (ret.first == MCTruthPartClassifier::Unknown &&
@@ -356,7 +358,8 @@ egammaTruthAssociationAlg::match(
 
   for (auto particle : *decoHandles.readHandle()) {
 
-    MCTruthInfo_t info = particleTruthClassifier(particle, &extrapolationCache);
+    MCTruthInfo_t info =
+      particleTruthClassifier(ctx, particle, &extrapolationCache);
 
     const xAOD::TruthParticle* truthParticle = info.genPart;
     if (truthParticle) {
diff --git a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h
index 363cb365e7b3..988d4c835ddf 100644
--- a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h
+++ b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h
@@ -101,11 +101,14 @@ private:
    * or do a second pass for electrons based on the cluster to find true photons
    * **/
   template<class T>
-  MCTruthInfo_t particleTruthClassifier(const T*, Cache*) const;
+  MCTruthInfo_t particleTruthClassifier(const EventContext& ctx,
+                                        const T*,
+                                        Cache*) const;
 
   /** @brief Create a copy a truth particle, add it to the new container and
    * decorate it with a link to the original particle **/
   void getNewTruthParticle(
+    const EventContext& ctx,
     xAOD::TruthParticleContainer& egammaTruthContainer,
     const xAOD::TruthParticle* truth,
     const xAOD::TruthParticleContainer* oldContainer) const;
-- 
GitLab