diff --git a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/python/ThinGeantTruth.py b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/python/ThinGeantTruth.py
index f58f8441155c8cce24b869aa7bfc1e3ced5c6b46..411b5271edeb3d47fde267bbd337da04ba2a75fc 100644
--- a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/python/ThinGeantTruth.py
+++ b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/python/ThinGeantTruth.py
@@ -14,7 +14,6 @@ class ThinGeantTruth(Configured):
             from ThinningUtils.ThinningUtilsConf import ThinGeantTruthAlg
             theGeantTruthThinner = ThinGeantTruthAlg(
                 "ThinGeantTruthAlg",
-                ThinGeantTruth = True,
                 StreamName = 'StreamAOD'
             )
             print (theGeantTruthThinner)
diff --git a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ReducePileUpEventInfoAlg.cxx b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ReducePileUpEventInfoAlg.cxx
index f0a93ad31b25644a133be46dc874eaa4bfc070e7..81bfd620dfc3025ac6bf8087a22a198ef696c9da 100644
--- a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ReducePileUpEventInfoAlg.cxx
+++ b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ReducePileUpEventInfoAlg.cxx
@@ -82,7 +82,7 @@ StatusCode ReducePileUpEventInfoAlg::execute()
   if ( evtStore()->contains< PileUpEventInfo >( "" ) )
     {
       // Get the EventInfo object
-      const PileUpEventInfo* oldEventInfo(NULL);
+      const PileUpEventInfo* oldEventInfo(nullptr);
       ATH_CHECK( evtStore()->retrieve( oldEventInfo ) );
 
       // Create a new EventInfo object and register it into StoreGate
diff --git a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinGeantTruthAlg.cxx b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinGeantTruthAlg.cxx
index c893c4860e6368dd93502d91bb55e55226d97c22..af6339e8ee9ee8a41fcace75e6ceed84017fc692 100644
--- a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinGeantTruthAlg.cxx
+++ b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinGeantTruthAlg.cxx
@@ -11,9 +11,9 @@
 // can't be dropped earlier in the simulation chain.
 // Not intended for use in derivations!
 // - Keep all truth particles with barcode <200 000
-// - Keep all truth particles associated with reco photons, electrons 
+// - Keep all truth particles associated with reco photons, electrons
 //   and muons, and their ancestors.
-// - Drop any vertices that, after the above thinning, have neither 
+// - Drop any vertices that, after the above thinning, have neither
 // incoming nor outgoing particles
 // Unlike other algs in this package, no tool is used to select the
 // objects for thinning - everything is done in this one class.
@@ -22,166 +22,145 @@
 
 // EventUtils includes
 #include "ThinGeantTruthAlg.h"
-#include "xAODTruth/xAODTruthHelpers.h"
 #include "MCTruthClassifier/MCTruthClassifierDefs.h"
+#include "xAODTruth/xAODTruthHelpers.h"
 // STL includes
-#include <algorithm> 
+#include <algorithm>
 
 // FrameWork includes
-#include "StoreGate/ThinningHandle.h"
 #include "Gaudi/Property.h"
+#include "StoreGate/ThinningHandle.h"
 
-//Standard includes
+// Standard includes
 #include <cstdlib>
 
-///////////////////////////////////////////////////////////////////
-// Public methods:
-///////////////////////////////////////////////////////////////////
-
-// Constructors
-////////////////
-ThinGeantTruthAlg::ThinGeantTruthAlg( const std::string& name,
-                                             ISvcLocator* pSvcLocator ) :
-::AthAlgorithm( name, pSvcLocator ),
-m_doThinning(true),
-m_geantOffset(200000),
-m_longlived{310,3122,3222,3112,3322,3312},
-m_nEventsProcessed{0},
-m_nParticlesProcessed{0},
-m_nVerticesProcessed{0},
-m_nParticlesThinned{0},
-m_nVerticesThinned{0}
-{
-   
-    declareProperty("ThinGeantTruth", m_doThinning,
-                    "Should the Geant truth thinning be run?");
-    declareProperty("GeantBarcodeOffset", m_geantOffset,
-                    "Barcode offset for Geant particles");
-    declareProperty("LongLivedParticleList", m_longlived,
-                    "List of long lifetime particles which are likely to be decayed by Geant but whose children must be kept");
-
-}
-
-// Destructor
-///////////////
-ThinGeantTruthAlg::~ThinGeantTruthAlg()
-{}
-
-// Athena Algorithm's Hooks
-////////////////////////////
-StatusCode ThinGeantTruthAlg::initialize()
+StatusCode
+ThinGeantTruthAlg::initialize()
 {
-    ATH_MSG_DEBUG ("Initializing " << name() << "...");
-    
-    // Print out the used configuration
-    ATH_MSG_DEBUG ( " using = " << m_streamName );
-
-    // Is truth thinning required?
-    if (!m_doThinning) {
-        ATH_MSG_INFO("Geant truth thinning not required");
-    } else {
-        ATH_MSG_INFO("Geant truth will be thinned");
-    }
-
-    if (m_doThinning && m_streamName.empty()) {
-      ATH_MSG_ERROR ("StreamName property was not initialized.");
-      return StatusCode::FAILURE;
-    }
-
-    ATH_CHECK(m_truthParticlesKey.initialize(m_streamName, m_doThinning));
-    ATH_CHECK(m_truthVerticesKey.initialize(m_streamName, m_doThinning));
-    ATH_CHECK(m_electronsKey.initialize(m_doThinning));
-    ATH_CHECK(m_photonsKey.initialize(m_doThinning));
-    ATH_CHECK(m_muonsKey.initialize(m_doThinning));
-    ATH_CHECK(m_egammaTruthKey.initialize(m_doThinning));
- 
-    // Initialize the counters to zero
-   ATH_MSG_DEBUG ( "==> done with initialize " << name() << "..." );
-    return StatusCode::SUCCESS;
+  if (m_streamName.empty()) {
+    ATH_MSG_ERROR("StreamName property was not initialized.");
+    return StatusCode::FAILURE;
+  }
+
+  ATH_CHECK(m_truthParticlesKey.initialize(m_streamName));
+  ATH_CHECK(m_truthVerticesKey.initialize(m_streamName));
+  ATH_CHECK(m_electronsKey.initialize(m_keepEGamma));
+  ATH_CHECK(m_photonsKey.initialize(m_keepEGamma));
+  ATH_CHECK(m_muonsKey.initialize(m_keepMuons));
+  ATH_CHECK(m_egammaTruthKey.initialize(m_keepEGamma));
+
+  return StatusCode::SUCCESS;
 }
 
-
-StatusCode ThinGeantTruthAlg::finalize()
+StatusCode
+ThinGeantTruthAlg::finalize()
 {
-    ATH_MSG_DEBUG ("Finalizing " << name() << "...");
-    ATH_MSG_INFO("Processed " << m_nEventsProcessed << " events containing " << m_nParticlesProcessed 
-                 << " truth particles and " << m_nVerticesProcessed << " truth vertices ");     
-    ATH_MSG_INFO("Removed " << m_nParticlesThinned << " Geant truth particles and " 
-                 << m_nVerticesThinned << " corresponding truth vertices ");
-    return StatusCode::SUCCESS;
+  ATH_MSG_INFO("Processed " << m_nEventsProcessed << " events containing "
+                            << m_nParticlesProcessed << " truth particles and "
+                            << m_nVerticesProcessed << " truth vertices ");
+  ATH_MSG_INFO("Removed " << m_nParticlesThinned
+                          << " Geant truth particles and " << m_nVerticesThinned
+                          << " corresponding truth vertices ");
+  return StatusCode::SUCCESS;
 }
 
-StatusCode ThinGeantTruthAlg::execute()
+StatusCode
+ThinGeantTruthAlg::execute(const EventContext& ctx) const
 {
-    // Increase the event counter
-    ++m_nEventsProcessed;
-    
-    // Is truth thinning required?
-    if (!m_doThinning) {
-        return StatusCode::SUCCESS;
-    } 
-   
-    // Retrieve truth and vertex containers
-    SG::ThinningHandle<xAOD::TruthParticleContainer> truthParticles(m_truthParticlesKey);
-    SG::ThinningHandle<xAOD::TruthVertexContainer> truthVertices(m_truthVerticesKey);
-    if(!truthParticles.isValid()){
-        ATH_MSG_FATAL("No TruthParticleContainer with key "+m_truthParticlesKey.key()+" found.");
-        return StatusCode::FAILURE;
-    }
-    if(!truthVertices.isValid()){
-        ATH_MSG_FATAL("No TruthVertexContainer with key "+m_truthVerticesKey.key()+" found.");
-        return StatusCode::FAILURE;
-    }
-
-    SG::ReadHandle<xAOD::MuonContainer> muons(m_muonsKey);
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Retrieve truth and vertex containers
+  SG::ThinningHandle<xAOD::TruthParticleContainer> truthParticles(
+    m_truthParticlesKey, ctx);
+  SG::ThinningHandle<xAOD::TruthVertexContainer> truthVertices(
+    m_truthVerticesKey, ctx);
+  if (!truthParticles.isValid()) {
+    ATH_MSG_FATAL("No TruthParticleContainer with key " +
+                  m_truthParticlesKey.key() + " found.");
+    return StatusCode::FAILURE;
+  }
+  if (!truthVertices.isValid()) {
+    ATH_MSG_FATAL("No TruthVertexContainer with key " +
+                  m_truthVerticesKey.key() + " found.");
+    return StatusCode::FAILURE;
+  }
+
+  // Loop over photons, electrons and muons and get the associated truth
+  // particles Retain the associated index number
+  std::vector<int> recoParticleTruthIndices;
+  std::vector<int> egammaTruthIndices{};
+
+  // Muons
+  if (m_keepMuons) {
+    SG::ReadHandle<xAOD::MuonContainer> muons(m_muonsKey, ctx);
     // Retrieve muons, electrons and photons
-    if(!muons.isValid()){
-        ATH_MSG_WARNING("No muon container with key "+m_muonsKey.key()+" found.");
-    }
-    SG::ReadHandle<xAOD::ElectronContainer> electrons(m_electronsKey);   
-    if(!electrons.isValid()){
-        ATH_MSG_WARNING("No electron container with key "+m_electronsKey.key()+" found.");
-    }
-    SG::ReadHandle<xAOD::PhotonContainer> photons(m_photonsKey);   
-    if(!photons.isValid()){
-        ATH_MSG_WARNING("No photon container with key "+m_photonsKey.key()+" found.");
+    if (!muons.isValid()) {
+      ATH_MSG_WARNING("No muon container with key " + m_muonsKey.key() +
+                      " found.");
     }
-   
-    // Loop over photons, electrons and muons and get the associated truth particles
-    // Retain the associated index number
-    std::vector<int> recoParticleTruthIndices;
     for (const xAOD::Muon* muon : *muons) {
-      const xAOD::TruthParticle* truthMuon = xAOD::TruthHelpers::getTruthParticle(*muon); 
-      if (truthMuon) {recoParticleTruthIndices.push_back(truthMuon->index());}
+      const xAOD::TruthParticle* truthMuon =
+        xAOD::TruthHelpers::getTruthParticle(*muon);
+      if (truthMuon) {
+        recoParticleTruthIndices.push_back(truthMuon->index());
+      }
+    }
+  }
+
+  // Electrons and photons
+  if (m_keepEGamma) {
+
+    // Electrons
+    SG::ReadHandle<xAOD::ElectronContainer> electrons(m_electronsKey, ctx);
+    if (!electrons.isValid()) {
+      ATH_MSG_WARNING("No electron container with key " + m_electronsKey.key() +
+                      " found.");
     }
     for (const xAOD::Electron* electron : *electrons) {
-      const xAOD::TruthParticle* truthElectron = xAOD::TruthHelpers::getTruthParticle(*electron);
-      if (truthElectron) {recoParticleTruthIndices.push_back(truthElectron->index());}
+      const xAOD::TruthParticle* truthElectron =
+        xAOD::TruthHelpers::getTruthParticle(*electron);
+      if (truthElectron) {
+        recoParticleTruthIndices.push_back(truthElectron->index());
+      }
+    }
+
+    // Photons
+    SG::ReadHandle<xAOD::PhotonContainer> photons(m_photonsKey, ctx);
+    if (!photons.isValid()) {
+      ATH_MSG_WARNING("No photon container with key " + m_photonsKey.key() +
+                      " found.");
     }
+
     for (const xAOD::Photon* photon : *photons) {
-      const xAOD::TruthParticle* truthPhoton = xAOD::TruthHelpers::getTruthParticle(*photon);
-      if (truthPhoton) {recoParticleTruthIndices.push_back(truthPhoton->index());}
-    } 
-
-    //Set up the indices for the egamma Truth Particles to keep
-    SG::ReadHandle<xAOD::TruthParticleContainer> egammaTruthParticles(m_egammaTruthKey);   
-    if(!egammaTruthParticles.isValid()){
-      ATH_MSG_WARNING("No e-gamma truth container with key "+m_egammaTruthKey.key()+" found.");
+      const xAOD::TruthParticle* truthPhoton =
+        xAOD::TruthHelpers::getTruthParticle(*photon);
+      if (truthPhoton) {
+        recoParticleTruthIndices.push_back(truthPhoton->index());
+      }
+    }
+
+    // egamma Truth Particles
+    SG::ReadHandle<xAOD::TruthParticleContainer> egammaTruthParticles(
+      m_egammaTruthKey, ctx);
+    if (!egammaTruthParticles.isValid()) {
+      ATH_MSG_WARNING("No e-gamma truth container with key " +
+                      m_egammaTruthKey.key() + " found.");
     }
 
-    std::vector<int> egammaTruthIndices{};
     for (const xAOD::TruthParticle* egTruthParticle : *egammaTruthParticles) {
 
       static const SG::AuxElement::ConstAccessor<int> accType("truthType");
 
-      if(!accType.isAvailable(*egTruthParticle) || 
-         accType(*egTruthParticle)!=MCTruthPartClassifier::IsoElectron || 
-         std::abs(egTruthParticle->eta()) > 2.525){
+      if (!accType.isAvailable(*egTruthParticle) ||
+          accType(*egTruthParticle) != MCTruthPartClassifier::IsoElectron ||
+          std::abs(egTruthParticle->eta()) > 2.525) {
         continue;
-        }
-      //Only central isolated true electrons	
-      typedef ElementLink<xAOD::TruthParticleContainer> TruthLink_t;
-      static const SG::AuxElement::ConstAccessor<TruthLink_t> linkToTruth("truthParticleLink");
+      }
+      // Only central isolated true electrons
+      using TruthLink_t = ElementLink<xAOD::TruthParticleContainer>;
+      static const SG::AuxElement::ConstAccessor<TruthLink_t> linkToTruth(
+        "truthParticleLink");
       if (!linkToTruth.isAvailable(*egTruthParticle)) {
         continue;
       }
@@ -189,193 +168,223 @@ StatusCode ThinGeantTruthAlg::execute()
       const TruthLink_t& truthegamma = linkToTruth(*egTruthParticle);
       if (!truthegamma.isValid()) {
         continue;
-      } 
-      egammaTruthIndices.push_back( (*truthegamma)->index());
+      }
+      egammaTruthIndices.push_back((*truthegamma)->index());
     }
-    // Set up masks
-    
-    std::vector<bool> particleMask, vertexMask;
-    int nTruthParticles = truthParticles->size();
-    int nTruthVertices = truthVertices->size();
-    m_nParticlesProcessed += nTruthParticles;
-    m_nVerticesProcessed += nTruthVertices;
-    particleMask.assign(nTruthParticles,false);
-    vertexMask.assign(nTruthVertices,false);
-    
-    // Vector of pairs keeping track of how many incoming/outgoing particles each vertex has
-    std::vector<std::pair<int, int> > vertexLinksCounts;
-    for (auto vertex : *truthVertices) {
-        std::pair<int , int> tmpPair;
-        tmpPair.first = vertex->nIncomingParticles();
-        tmpPair.second = vertex->nOutgoingParticles();
-        vertexLinksCounts.push_back(tmpPair);
+  }
+
+  // Set up masks
+
+  std::vector<bool> particleMask, vertexMask;
+  int nTruthParticles = truthParticles->size();
+  int nTruthVertices = truthVertices->size();
+  m_nParticlesProcessed += nTruthParticles;
+  m_nVerticesProcessed += nTruthVertices;
+  particleMask.assign(nTruthParticles, false);
+  vertexMask.assign(nTruthVertices, false);
+
+  // Vector of pairs keeping track of how many incoming/outgoing particles each
+  // vertex has
+  std::vector<std::pair<int, int>> vertexLinksCounts;
+  for (const auto *vertex : *truthVertices) {
+    std::pair<int, int> tmpPair;
+    tmpPair.first = vertex->nIncomingParticles();
+    tmpPair.second = vertex->nOutgoingParticles();
+    vertexLinksCounts.push_back(tmpPair);
+  }
+
+  // Loop over truth particles and update mask
+  std::unordered_set<int> encounteredBarcodes; // for loop protection
+  for (int i = 0; i < nTruthParticles; ++i) {
+    encounteredBarcodes.clear();
+    const xAOD::TruthParticle* particle = (*truthParticles)[i];
+    // Retain status 1 BSM particles and descendants
+    if (isStatus1BSMParticle(particle)) {
+      descendants(particle, particleMask, encounteredBarcodes);
+      encounteredBarcodes.clear();
     }
-    
-    // Loop over truth particles and update mask
-    std::unordered_set<int> encounteredBarcodes; // for loop protection
-    for (int i=0; i<nTruthParticles; ++i) {
-        encounteredBarcodes.clear();
-        const xAOD::TruthParticle* particle = (*truthParticles)[i];
-        // Retain status 1 BSM particles and descendants
-        if (isStatus1BSMParticle(particle)) {
-            descendants(particle,particleMask,encounteredBarcodes);
-            encounteredBarcodes.clear();
+    // Retain children of longer-lived generator particles
+    if (particle->status() == 1) {
+      int pdgId = abs(particle->pdgId());
+      if (std::find(m_longlived.begin(), m_longlived.end(), pdgId) !=
+          m_longlived.end()) {
+        const xAOD::TruthVertex* decayVtx(nullptr);
+        if (particle->hasDecayVtx()) {
+          decayVtx = particle->decayVtx();
         }
-        // Retain children of longer-lived generator particles
-        if (particle->status()==1) { 
-            int pdgId = abs(particle->pdgId());
-            if ( std::find(m_longlived.begin(), m_longlived.end(), pdgId) != m_longlived.end() ) {
-                const xAOD::TruthVertex* decayVtx(0);
-                if (particle->hasDecayVtx()) {decayVtx = particle->decayVtx();}
-                int nChildren = 0;
-                if (decayVtx) nChildren = decayVtx->nOutgoingParticles();
-                for (int i=0; i<nChildren; ++i) {
-                    particleMask[decayVtx->outgoingParticle(i)->index()] = true;    
-                }        
-            }
-        }  
-
-        // Retain particles and their descendants/ancestors associated with the reconstructed objects
-        if ( std::find(recoParticleTruthIndices.begin(), recoParticleTruthIndices.end(), i) != recoParticleTruthIndices.end() ) { 
-            if (abs(particle->barcode()) > m_geantOffset) { // only need to do this for Geant particles since non-Geant are kept anyway 
-                ancestors(particle,particleMask,encounteredBarcodes);
-                encounteredBarcodes.clear();
-                descendants(particle,particleMask,encounteredBarcodes);
-                encounteredBarcodes.clear();
-            }
-        }
-
-        // Retain particles and their descendants  associated with the egamma Truth Particles
-        if ( std::find(egammaTruthIndices.begin(), egammaTruthIndices.end(), i) != egammaTruthIndices.end() ) { 
-          descendants(particle,particleMask,encounteredBarcodes);
-          encounteredBarcodes.clear();
+        int nChildren = 0;
+        if (decayVtx)
+          nChildren = decayVtx->nOutgoingParticles();
+        for (int i = 0; i < nChildren; ++i) {
+          particleMask[decayVtx->outgoingParticle(i)->index()] = true;
         }
+      }
+    }
 
-        if (abs(particle->barcode()) < m_geantOffset) {
-            particleMask[i] = true;
-        }         
+    // Retain particles and their descendants/ancestors associated with the
+    // reconstructed objects
+    if (std::find(recoParticleTruthIndices.begin(),
+                  recoParticleTruthIndices.end(),
+                  i) != recoParticleTruthIndices.end()) {
+      if (abs(particle->barcode()) >
+          m_geantOffset) { // only need to do this for Geant particles since
+                           // non-Geant are kept anyway
+        ancestors(particle, particleMask, encounteredBarcodes);
+        encounteredBarcodes.clear();
+        descendants(particle, particleMask, encounteredBarcodes);
+        encounteredBarcodes.clear();
+      }
     }
 
-    // Loop over the mask and update vertex association counters
-    for (int i=0; i<nTruthParticles; ++i) {
-        if (particleMask[i] == false) {
-            ++m_nParticlesThinned;
-            const xAOD::TruthParticle* particle = (*truthParticles)[i];
-            if (particle->hasProdVtx()) {
-                auto prodVertex = particle->prodVtx();
-                --vertexLinksCounts[prodVertex->index()].second;
-            }
-            if (particle->hasDecayVtx()) {
-                auto decayVertex = particle->decayVtx();
-                --vertexLinksCounts[decayVertex->index()].first;
-            }             
-        }
-    } 
-
-    // Loop over truth vertices and update mask
-    // Those for which all incoming and outgoing particles are to be thinned, will be thinned as well
-    for (int i=0; i<nTruthVertices; ++i) {
-        if (vertexLinksCounts[i].first!=0 || vertexLinksCounts[i].second!=0) {
-            vertexMask[i] = true;
-        } else {++m_nVerticesThinned;}
+    // Retain particles and their descendants  associated with the egamma Truth
+    // Particles
+    if (std::find(egammaTruthIndices.begin(), egammaTruthIndices.end(), i) !=
+        egammaTruthIndices.end()) {
+      descendants(particle, particleMask, encounteredBarcodes);
+      encounteredBarcodes.clear();
     }
-    // Apply masks to thinning
-    truthParticles.keep (particleMask);
-    truthVertices.keep (vertexMask);
-    
-    return StatusCode::SUCCESS;
-}
 
+    if (abs(particle->barcode()) < m_geantOffset) {
+      particleMask[i] = true;
+    }
+  }
+
+  // Loop over the mask and update vertex association counters
+  for (int i = 0; i < nTruthParticles; ++i) {
+    if (!particleMask[i]) {
+      ++m_nParticlesThinned;
+      const xAOD::TruthParticle* particle = (*truthParticles)[i];
+      if (particle->hasProdVtx()) {
+        const auto *prodVertex = particle->prodVtx();
+        --vertexLinksCounts[prodVertex->index()].second;
+      }
+      if (particle->hasDecayVtx()) {
+        const auto *decayVertex = particle->decayVtx();
+        --vertexLinksCounts[decayVertex->index()].first;
+      }
+    }
+  }
+
+  // Loop over truth vertices and update mask
+  // Those for which all incoming and outgoing particles are to be thinned, will
+  // be thinned as well
+  for (int i = 0; i < nTruthVertices; ++i) {
+    if (vertexLinksCounts[i].first != 0 || vertexLinksCounts[i].second != 0) {
+      vertexMask[i] = true;
+    } else {
+      ++m_nVerticesThinned;
+    }
+  }
+  // Apply masks to thinning
+  truthParticles.keep(particleMask);
+  truthVertices.keep(vertexMask);
 
+  return StatusCode::SUCCESS;
+}
 
 // Inline methods
 //
 // ==============================
-// ancestors 
+// ancestors
 // ==============================
 // Updates particle mask such that particle and all ancestors are retained
-void ThinGeantTruthAlg::ancestors(const xAOD::TruthParticle* pHead,
-                                  std::vector<bool> &particleMask,
-                                  std::unordered_set<int> &encounteredBarcodes ) {
-           
-    // Check that this barcode hasn't been seen before (e.g. we are in a loop)
-    std::unordered_set<int>::const_iterator found = encounteredBarcodes.find(pHead->barcode());
-    if (found!=encounteredBarcodes.end()) return;
-    encounteredBarcodes.insert(pHead->barcode());
-   
-    // Save particle position in the mask
-    int headIndex = pHead->index();
-    particleMask[headIndex] = true;
-   
-    // Get the production vertex
-    const xAOD::TruthVertex* prodVtx(0);
-    if (pHead->hasProdVtx()) {prodVtx = pHead->prodVtx();}
-    else {return;}
-   
-    // Get children particles and self-call
-    int nParents = prodVtx->nIncomingParticles();
-    for (int i=0; i<nParents; ++i) ancestors(prodVtx->incomingParticle(i),particleMask,encounteredBarcodes);
+void
+ThinGeantTruthAlg::ancestors(const xAOD::TruthParticle* pHead,
+                             std::vector<bool>& particleMask,
+                             std::unordered_set<int>& encounteredBarcodes) const
+{
+
+  // Check that this barcode hasn't been seen before (e.g. we are in a loop)
+  std::unordered_set<int>::const_iterator found =
+    encounteredBarcodes.find(pHead->barcode());
+  if (found != encounteredBarcodes.end())
     return;
-}
+  encounteredBarcodes.insert(pHead->barcode());
 
+  // Save particle position in the mask
+  int headIndex = pHead->index();
+  particleMask[headIndex] = true;
+
+  // Get the production vertex
+  const xAOD::TruthVertex* prodVtx(nullptr);
+  if (pHead->hasProdVtx()) {
+    prodVtx = pHead->prodVtx();
+  } else {
+    return;
+  }
+
+  // Get children particles and self-call
+  int nParents = prodVtx->nIncomingParticles();
+  for (int i = 0; i < nParents; ++i)
+    ancestors(prodVtx->incomingParticle(i), particleMask, encounteredBarcodes);
+}
 
 // ==============================
-// descendants 
+// descendants
 // ==============================
 // Updates particle mask such that particle and all descendants are retained
-void ThinGeantTruthAlg::descendants(const xAOD::TruthParticle* pHead,
-                                    std::vector<bool> &particleMask,
-                                    std::unordered_set<int> &encounteredBarcodes ) {
-    // Check that this barcode hasn't been seen before (e.g. we are in a loop)
-    std::unordered_set<int>::const_iterator found = encounteredBarcodes.find(pHead->barcode());
-    if (found!=encounteredBarcodes.end()) return;
-    encounteredBarcodes.insert(pHead->barcode());
-    
-    // Save the particle position in the mask
-    int headIndex = pHead->index();
-    particleMask[headIndex] = true;
-    
-    // Get the decay vertex
-    const xAOD::TruthVertex* decayVtx(0);
-    if (pHead->hasDecayVtx()) {decayVtx = pHead->decayVtx();}
-    else {return;}
-    
-    // Get children particles and self-call
-    int  nChildren = decayVtx->nOutgoingParticles();
-    for (int i=0; i<nChildren; ++i) {
-        descendants(decayVtx->outgoingParticle(i),particleMask,encounteredBarcodes);
-    }
- 
+void
+ThinGeantTruthAlg::descendants(
+  const xAOD::TruthParticle* pHead,
+  std::vector<bool>& particleMask,
+  std::unordered_set<int>& encounteredBarcodes) const
+{
+  // Check that this barcode hasn't been seen before (e.g. we are in a loop)
+  std::unordered_set<int>::const_iterator found =
+    encounteredBarcodes.find(pHead->barcode());
+  if (found != encounteredBarcodes.end())
     return;
-}
+  encounteredBarcodes.insert(pHead->barcode());
+
+  // Save the particle position in the mask
+  int headIndex = pHead->index();
+  particleMask[headIndex] = true;
+
+  // Get the decay vertex
+  const xAOD::TruthVertex* decayVtx(nullptr);
+  if (pHead->hasDecayVtx()) {
+    decayVtx = pHead->decayVtx();
+  } else {
+    return;
+  }
+
+  // Get children particles and self-call
+  int nChildren = decayVtx->nOutgoingParticles();
+  for (int i = 0; i < nChildren; ++i) {
+    descendants(
+      decayVtx->outgoingParticle(i), particleMask, encounteredBarcodes);
+  }
+
+  }
 
 // ==============================
-// isStatus1BSMParticle 
+// isStatus1BSMParticle
 // ==============================
 // Returns true if a particle is BSM and stable
+bool
+ThinGeantTruthAlg::isStatus1BSMParticle(const xAOD::TruthParticle* part) 
+{
 
-bool ThinGeantTruthAlg::isStatus1BSMParticle(const xAOD::TruthParticle* part) const{
-   
-    int pdg = part->pdgId();
-    bool status1 = (part->status()==1);
-    bool isBSM(false);   
-
-    if ( (31<abs(pdg) && abs(pdg)<38) || // BSM Higgs / W' / Z' / etc
-        abs(pdg)==39 ||
-        abs(pdg)==41 ||
-        abs(pdg)==42 ||
-        abs(pdg)== 7 || // 4th gen beauty
-        abs(pdg)== 8 || // 4th gen top
-        (600 < abs(pdg) && abs(pdg) < 607) || // scalar leptoquarks
-        (1000000<abs(pdg) && abs(pdg)<2000000) || // left-handed SUSY (including R-Hadrons)
-        (2000000<abs(pdg) && abs(pdg)<3000000) || // right-handed SUSY (including R-Hadrons)
-        abs(pdg)==6000005 || // X5/3
-        abs(pdg)==6000006 || // T2/3
-        abs(pdg)==6000007 || // B-1/3
-        abs(pdg)==6000008 || // Y-4/3
-        ( (abs(pdg)>=10000100) && (abs(pdg)<=10001000) ) // multi-charged
-    ) isBSM = true;
-
-    if (status1 && isBSM) {return true;} else {return false;}        
-
+  int pdg = part->pdgId();
+  bool status1 = (part->status() == 1);
+  bool isBSM(false);
+
+  if ((31 < abs(pdg) && abs(pdg) < 38) || // BSM Higgs / W' / Z' / etc
+      abs(pdg) == 39 || abs(pdg) == 41 || abs(pdg) == 42 ||
+      abs(pdg) == 7 ||                      // 4th gen beauty
+      abs(pdg) == 8 ||                      // 4th gen top
+      (600 < abs(pdg) && abs(pdg) < 607) || // scalar leptoquarks
+      (1000000 < abs(pdg) &&
+       abs(pdg) < 2000000) || // left-handed SUSY (including R-Hadrons)
+      (2000000 < abs(pdg) &&
+       abs(pdg) < 3000000) || // right-handed SUSY (including R-Hadrons)
+      abs(pdg) == 6000005 ||  // X5/3
+      abs(pdg) == 6000006 ||  // T2/3
+      abs(pdg) == 6000007 ||  // B-1/3
+      abs(pdg) == 6000008 ||  // Y-4/3
+      ((abs(pdg) >= 10000100) && (abs(pdg) <= 10001000)) // multi-charged
+  )
+    isBSM = true;
+
+  return status1 && isBSM;
 }
diff --git a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinGeantTruthAlg.h b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinGeantTruthAlg.h
index 3bcfeb52738fa94979e2558472bd0435d8e5a211..7a29fb73ea691efad6fb0e20ee251ffe88e73200 100644
--- a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinGeantTruthAlg.h
+++ b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinGeantTruthAlg.h
@@ -4,7 +4,6 @@
   Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
-
 #ifndef THINNINGUTILS_ThinGeantTruthAlg_H
 #define THINNINGUTILS_ThinGeantTruthAlg_H 1
 
@@ -12,107 +11,103 @@
  @class ThinGeantTruthAlg
 */
 
-
 // STL includes
+#include <atomic>
 #include <string>
 
 // FrameWork includes
-#include "GaudiKernel/ToolHandle.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
 #include "GaudiKernel/ServiceHandle.h"
-#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
 #include "StoreGate/ThinningHandleKey.h"
-#include "xAODTruth/TruthParticleContainer.h"
-#include "xAODTruth/TruthVertexContainer.h"
-#include "xAODMuon/MuonContainer.h"
 #include "xAODEgamma/ElectronContainer.h"
 #include "xAODEgamma/PhotonContainer.h"
-#include "xAODEgamma/PhotonContainer.h"
-#
+#include "xAODMuon/MuonContainer.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthVertexContainer.h"
 
-class ThinGeantTruthAlg
-  : public ::AthAlgorithm
+class ThinGeantTruthAlg : public AthReentrantAlgorithm
 {
 public:
-  
-    /// Constructor with parameters:
-    ThinGeantTruthAlg( const std::string& name, ISvcLocator* pSvcLocator );
-    
-    /// Destructor:
-    virtual ~ThinGeantTruthAlg();
-    
-    /// Athena algorithm's initalize hook
-    virtual StatusCode  initialize();
-    
-    /// Athena algorithm's execute hook
-    virtual StatusCode  execute();
-    
-    /// Athena algorithm's finalize hook
-    virtual StatusCode  finalize();
-    
-    /// Inline method
-    void ancestors(const xAOD::TruthParticle*,
-                   std::vector<bool> &,
-                   std::unordered_set<int> & );
-    void descendants(const xAOD::TruthParticle*,
-                     std::vector<bool> &,
-                     std::unordered_set<int> & );   
-    bool isStatus1BSMParticle(const xAOD::TruthParticle*) const;
-
- 
-private:
-
-    /// Should the thinning run?
-    bool m_doThinning;
-   
-    /// Geant barcode
-    int m_geantOffset; 
- 
-    /// Geant-decayed longer lived particles
-    std::vector<int> m_longlived;
-
-    StringProperty m_streamName
-    { this, "StreamName", "", "Stream for which thinning is to be done." };
-
-    SG::ThinningHandleKey<xAOD::TruthParticleContainer>  m_truthParticlesKey {this, 
-        "TruthParticlesKey", 
-        "TruthParticles", 
-        "Name of the input Truth Particle container"};
-
-
-    SG::ThinningHandleKey<xAOD::TruthVertexContainer> m_truthVerticesKey{this, 
-        "TruthVerticesKey", 
-        "TruthVertices", 
-        "Name of the input Truth Vertices container"};
-
-
-    SG::ReadHandleKey<xAOD::ElectronContainer> m_electronsKey {this, 
-        "ElectronsKey", 
-        "Electrons", 
-        "Name of the input electron container"};
-
-    SG::ReadHandleKey<xAOD::PhotonContainer> m_photonsKey {this, 
-        "PhotonsKey", 
-        "Photons", 
-        "Name of the input photon container"};
-
-    SG::ReadHandleKey<xAOD::MuonContainer> m_muonsKey {this, 
-        "MuonsKey", 
-        "Muons", 
-        "Name of the input muon container"};
-
-    SG::ReadHandleKey<xAOD::TruthParticleContainer> m_egammaTruthKey {this, 
-        "EGammaTruthKey", 
-        "egammaTruthParticles", 
-        "Name of the input egammaTruth container"};
-    
-    /// Counters
-    unsigned long m_nEventsProcessed;
-    unsigned long m_nParticlesProcessed;
-    unsigned long m_nVerticesProcessed;
-    unsigned long m_nParticlesThinned;
-    unsigned long m_nVerticesThinned;
+  using AthReentrantAlgorithm::AthReentrantAlgorithm;
+  virtual StatusCode initialize() override;
+  virtual StatusCode finalize() override;
+  virtual StatusCode execute(const EventContext& ctx) const override final;
+
+  /// Inline method
+  void ancestors(const xAOD::TruthParticle*,
+                 std::vector<bool>&,
+                 std::unordered_set<int>&) const;
+  void descendants(const xAOD::TruthParticle*,
+                   std::vector<bool>&,
+                   std::unordered_set<int>&) const;
+  static bool isStatus1BSMParticle(const xAOD::TruthParticle*) ;
 
+private:
+  StringProperty m_streamName{ this,
+                               "StreamName",
+                               "",
+                               "Stream for which thinning is to be done." };
+
+  Gaudi::Property<int> m_geantOffset{ this,
+                                      "GeantBarcodeOffset",
+                                      200000,
+                                      "Barcode offset for Geant particles" };
+  Gaudi::Property<bool> m_keepMuons{ this, "keepMuons", true };
+  Gaudi::Property<bool> m_keepEGamma{ this, "keepEGamma", true };
+
+  Gaudi::Property<std::vector<int>> m_longlived{
+    this,
+    "LongLivedParticleList",
+    { 310, 3122, 3222, 3112, 3322, 3312 },
+    "List of long lifetime particles which are likely to be decayed by "
+    "Geant but whose children must be kept"
+  };
+
+  SG::ThinningHandleKey<xAOD::TruthParticleContainer> m_truthParticlesKey{
+    this,
+    "TruthParticlesKey",
+    "TruthParticles",
+    "Name of the input Truth Particle container"
+  };
+
+  SG::ThinningHandleKey<xAOD::TruthVertexContainer> m_truthVerticesKey{
+    this,
+    "TruthVerticesKey",
+    "TruthVertices",
+    "Name of the input Truth Vertices container"
+  };
+
+  SG::ReadHandleKey<xAOD::ElectronContainer> m_electronsKey{
+    this,
+    "ElectronsKey",
+    "Electrons",
+    "Name of the input electron container"
+  };
+
+  SG::ReadHandleKey<xAOD::PhotonContainer> m_photonsKey{
+    this,
+    "PhotonsKey",
+    "Photons",
+    "Name of the input photon container"
+  };
+
+  SG::ReadHandleKey<xAOD::MuonContainer>
+    m_muonsKey{ this, "MuonsKey", "Muons", "Name of the input muon container" };
+
+  SG::ReadHandleKey<xAOD::TruthParticleContainer> m_egammaTruthKey{
+    this,
+    "EGammaTruthKey",
+    "egammaTruthParticles",
+    "Name of the input egammaTruth container"
+  };
+
+  /// Counters
+  mutable std::atomic<unsigned long> m_nEventsProcessed{};
+  mutable std::atomic<unsigned long> m_nParticlesProcessed{};
+  mutable std::atomic<unsigned long> m_nVerticesProcessed{};
+  mutable std::atomic<unsigned long> m_nParticlesThinned{};
+  mutable std::atomic<unsigned long> m_nVerticesThinned{};
 };
 
-
 #endif //> !THINNINGUTILS_ThinGeantTruthAlg_H
diff --git a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinInDetForwardTrackParticlesAlg.cxx b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinInDetForwardTrackParticlesAlg.cxx
index 91fbbd3694b9c9138cf02001b56ed681d04559b7..a42450c25af05928dd007803f01a46ec7634f997 100644
--- a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinInDetForwardTrackParticlesAlg.cxx
+++ b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinInDetForwardTrackParticlesAlg.cxx
@@ -125,7 +125,7 @@ StatusCode ThinInDetForwardTrackParticlesAlg::execute()
     // Loop over the muons. Identify which are SiliconAssociatedForwardMuon. 
     // Get their associated inner detector track. Find that track in the InDetForwardTrackParticles.
     // Set the mask element.
-    for (auto muon : *muons) {
+    for (const auto *muon : *muons) {
       if (muon->muonType()==xAOD::Muon::SiliconAssociatedForwardMuon) {
         ++m_nSiFwdMuons;
         const xAOD::TrackParticle* muTrk(nullptr);
@@ -139,7 +139,7 @@ StatusCode ThinInDetForwardTrackParticlesAlg::execute()
 
     // Increment counters
     for (unsigned int i=0; i<nTracks; ++i) {
-        if (trackMask[i]==false) ++m_nTracksThinned;  
+        if (!trackMask[i]) ++m_nTracksThinned;  
     }
 
     // Apply masks to thinning service
diff --git a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinInDetForwardTrackParticlesAlg.h b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinInDetForwardTrackParticlesAlg.h
index 798a148a3e281baa5bef2afa288e346992eddea5..d2c8893283e5dda5a3b80fb3a3523de90c097892 100644
--- a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinInDetForwardTrackParticlesAlg.h
+++ b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinInDetForwardTrackParticlesAlg.h
@@ -64,9 +64,9 @@ private:
     unsigned long m_nEventsProcessed;
     unsigned long m_nTracksProcessed;
     unsigned long m_nTracksThinned;
-    unsigned long m_nMuons;
-    unsigned long m_nSiFwdMuons;
-    unsigned long m_nSiFwdAssoc;
+    unsigned long m_nMuons = 0UL;
+    unsigned long m_nSiFwdMuons = 0UL;
+    unsigned long m_nSiFwdAssoc = 0UL;
 };
 
 
diff --git a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinTrkTrackAlg.cxx b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinTrkTrackAlg.cxx
index f9837b499e8d6f850aad040a76b1012fac086112..0cc645cf22ed0505def3a8214145b956e8c9dae2 100644
--- a/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinTrkTrackAlg.cxx
+++ b/PhysicsAnalysis/AnalysisCommon/ThinningUtils/src/ThinTrkTrackAlg.cxx
@@ -89,7 +89,7 @@ ThinTrkTrackAlg::doEGamma(const EventContext& ctx) const
     SG::ReadHandle<xAOD::ElectronContainer> electrons(m_electronsKey, ctx);
 
     // Loop over electrons
-    for (auto el : *electrons) {
+    for (const auto *el : *electrons) {
       if (el->pt() < m_minptElectrons) {
         continue;
       }
@@ -114,7 +114,7 @@ ThinTrkTrackAlg::doEGamma(const EventContext& ctx) const
     SG::ReadHandle<xAOD::PhotonContainer> photons(m_photonsKey, ctx);
 
     // Loop over photons
-    for (auto ph : *photons) {
+    for (const auto *ph : *photons) {
       if (ph->pt() < m_minptPhotons) {
         continue;
       }
@@ -164,7 +164,7 @@ ThinTrkTrackAlg::doMuons(const EventContext& ctx) const
 
   // Loop over muons
   size_t kept(0);
-  for (auto mu : *muons) {
+  for (const auto *mu : *muons) {
     if (mu->pt() < m_minptMuons) {
       continue;
     }