diff --git a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx index c02b7197cd35df6f63985c46250c25dbbbe737b1..643c7e50af639f5bbaa775c3396b3cf7341d6766 100644 --- a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx +++ b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration */ #include "egammaTruthAssociationAlg.h" @@ -19,7 +19,7 @@ using PhotonLink_t = ElementLink<xAOD::PhotonContainer>; egammaTruthAssociationAlg::egammaTruthAssociationAlg(const std::string& name, ISvcLocator* pSvcLocator) - : AthAlgorithm(name, pSvcLocator) + : AthReentrantAlgorithm(name, pSvcLocator) {} egammaTruthAssociationAlg::~egammaTruthAssociationAlg() {} @@ -32,7 +32,8 @@ egammaTruthAssociationAlg::initialize() // initialize the data handles ATH_CHECK(m_truthEventContainerKey.initialize(m_doEgammaTruthContainer)); - ATH_CHECK(m_egammaTruthParticleContainerKey.initialize(m_doEgammaTruthContainer)); + ATH_CHECK( + m_egammaTruthParticleContainerKey.initialize(m_doEgammaTruthContainer)); ATH_CHECK(m_truthParticleContainerKey.initialize()); // Now the standard decoration handles @@ -73,77 +74,105 @@ egammaTruthAssociationAlg::finalize() } StatusCode -egammaTruthAssociationAlg::execute_r(const EventContext& ctx) const +egammaTruthAssociationAlg::execute(const EventContext& ctx) const { SG::WriteHandle<xAOD::TruthParticleContainer> egammaTruthContainer; if (m_doEgammaTruthContainer) { - egammaTruthContainer = - SG::WriteHandle<xAOD::TruthParticleContainer>(m_egammaTruthParticleContainerKey, ctx); - ATH_CHECK(egammaTruthContainer.record(std::make_unique<xAOD::TruthParticleContainer>(), - std::make_unique<xAOD::TruthParticleAuxContainer>())); + egammaTruthContainer = SG::WriteHandle<xAOD::TruthParticleContainer>( + m_egammaTruthParticleContainerKey, ctx); + ATH_CHECK(egammaTruthContainer.record( + std::make_unique<xAOD::TruthParticleContainer>(), + std::make_unique<xAOD::TruthParticleAuxContainer>())); // Add a copy of electrons and photons to the truth egamma container - SG::ReadHandle<xAOD::TruthEventContainer> truthEvtContainer(m_truthEventContainerKey, ctx); + SG::ReadHandle<xAOD::TruthEventContainer> truthEvtContainer( + m_truthEventContainerKey, ctx); // only for serial running. Can remove check later if (!truthEvtContainer.isValid() || truthEvtContainer->empty()) { - ATH_MSG_WARNING("Could not retrieve " << m_truthEventContainerKey.key() - << " or container empty, returning"); + ATH_MSG_WARNING("Could not retrieve " + << m_truthEventContainerKey.key() + << " or container empty, returning"); return StatusCode::SUCCESS; } - for (const auto& truthParticleLink : truthEvtContainer->front()->truthParticleLinks()) { + for (const auto& truthParticleLink : + truthEvtContainer->front()->truthParticleLinks()) { if (!truthParticleLink.isValid()) continue; const xAOD::TruthParticle* truthParticle = *truthParticleLink; if (!isPromptEgammaParticle(truthParticle)) continue; - getNewTruthParticle(*egammaTruthContainer, truthParticle, truthParticleLink.getDataPtr()); + getNewTruthParticle( + *egammaTruthContainer, truthParticle, truthParticleLink.getDataPtr()); } } // Decorate containers with truth info, including links to truth particles // Decorate the truth particles with links to the reco ones - // note that in multithreading this must be valid; can't just fail with success. - SG::ReadHandle<xAOD::TruthParticleContainer> truthParticles(m_truthParticleContainerKey, ctx); + // note that in multithreading this must be valid; can't just fail with + // success. + SG::ReadHandle<xAOD::TruthParticleContainer> truthParticles( + m_truthParticleContainerKey, ctx); // accessors - static const SG::AuxElement::Accessor<ClusterLink_t> accClusLink("recoClusterLink"); - static const SG::AuxElement::Accessor<ElectronLink_t> accElLink("recoElectronLink"); - static const SG::AuxElement::Accessor<PhotonLink_t> accPhLink("recoPhotonLink"); + static const SG::AuxElement::Accessor<ClusterLink_t> accClusLink( + "recoClusterLink"); + static const SG::AuxElement::Accessor<ElectronLink_t> accElLink( + "recoElectronLink"); + static const SG::AuxElement::Accessor<PhotonLink_t> accPhLink( + "recoPhotonLink"); if (m_matchElectrons) { ATH_MSG_DEBUG("About to match electrons"); - ATH_CHECK(match(*truthParticles, m_electronDecKeys, accElLink, egammaTruthContainer.ptr())); + ATH_CHECK(match(ctx, + *truthParticles, + m_electronDecKeys, + accElLink, + egammaTruthContainer.ptr())); } if (m_matchPhotons) { ATH_MSG_DEBUG("About to match photons"); - ATH_CHECK(match(*truthParticles, m_photonDecKeys, accPhLink, egammaTruthContainer.ptr())); + ATH_CHECK(match(ctx, + *truthParticles, + m_photonDecKeys, + accPhLink, + egammaTruthContainer.ptr())); } if (m_matchClusters) { ATH_MSG_DEBUG("About to match clusters"); - ATH_CHECK(match(*truthParticles, m_clusterDecKeys, accClusLink, egammaTruthContainer.ptr())); + ATH_CHECK(match(ctx, + *truthParticles, + m_clusterDecKeys, + accClusLink, + egammaTruthContainer.ptr())); } if (m_matchForwardElectrons) { ATH_MSG_DEBUG("About to match fwd electrons"); - ATH_CHECK(match(*truthParticles, m_fwdElectronDecKeys, accElLink, egammaTruthContainer.ptr())); + ATH_CHECK(match(ctx, + *truthParticles, + m_fwdElectronDecKeys, + accElLink, + egammaTruthContainer.ptr())); } return StatusCode::SUCCESS; } bool -egammaTruthAssociationAlg::isPromptEgammaParticle(const xAOD::TruthParticle* truth) const +egammaTruthAssociationAlg::isPromptEgammaParticle( + const xAOD::TruthParticle* truth) const { - if ((truth->pdgId() != 22 && abs(truth->pdgId()) != 11) || truth->status() == 2 || - truth->status() == 3 || truth->barcode() > m_barcodeOffset || truth->pt() < m_minPt){ + if ((truth->pdgId() != 22 && abs(truth->pdgId()) != 11) || + truth->status() == 2 || truth->status() == 3 || + truth->barcode() > m_barcodeOffset || truth->pt() < m_minPt) { return false; } @@ -185,10 +214,14 @@ egammaTruthAssociationAlg::getNewTruthParticle( truthParticle->setProdVtxLink(truth->prodVtxLink()); truthParticle->setDecayVtxLink(truth->decayVtxLink()); - static const SG::AuxElement::Accessor<ClusterLink_t> accClusLink("recoClusterLink"); - static const SG::AuxElement::Accessor<ElectronLink_t> accElLink("recoElectronLink"); - static const SG::AuxElement::Accessor<PhotonLink_t> accPhLink("recoPhotonLink"); - static const SG::AuxElement::Accessor<TruthLink_t> accTruthLink("truthParticleLink"); + static const SG::AuxElement::Accessor<ClusterLink_t> accClusLink( + "recoClusterLink"); + static const SG::AuxElement::Accessor<ElectronLink_t> accElLink( + "recoElectronLink"); + static const SG::AuxElement::Accessor<PhotonLink_t> accPhLink( + "recoPhotonLink"); + static const SG::AuxElement::Accessor<TruthLink_t> accTruthLink( + "truthParticleLink"); static const SG::AuxElement::Accessor<int> accType("truthType"); static const SG::AuxElement::Accessor<int> accOrigin("truthOrigin"); @@ -213,7 +246,7 @@ egammaTruthAssociationAlg::getEgammaTruthParticle( const xAOD::TruthParticle* truth, xAOD::TruthParticleContainer& egammaTruthContainer) const { - if (!truth){ + if (!truth) { return nullptr; } // Find the original truth particle for electrons from conversions @@ -226,7 +259,7 @@ egammaTruthAssociationAlg::getEgammaTruthParticle( } // In case truth became null in the above loop - if (!truth){ + if (!truth) { return nullptr; } for (auto egammaTruth : egammaTruthContainer) { @@ -240,8 +273,9 @@ egammaTruthAssociationAlg::getEgammaTruthParticle( //// The templated functions template<class T> StatusCode -egammaTruthAssociationAlg::initializeDecorKeys(SG::WriteDecorHandleKeyArray<T>& keys, - const std::string& name) +egammaTruthAssociationAlg::initializeDecorKeys( + SG::WriteDecorHandleKeyArray<T>& keys, + const std::string& name) { if (!keys.empty()) { ATH_MSG_FATAL("The WriteDecorHandle should not be configured directly."); @@ -258,16 +292,17 @@ egammaTruthAssociationAlg::initializeDecorKeys(SG::WriteDecorHandleKeyArray<T>& // constructor template<class T> egammaTruthAssociationAlg::writeDecorHandles<T>::writeDecorHandles( - const SG::WriteDecorHandleKeyArray<T>& hkeys) - : el(hkeys.at(0)) - , type(hkeys.at(1)) - , origin(hkeys.at(2)) + const SG::WriteDecorHandleKeyArray<T>& hkeys,const EventContext& ctx) + : el(hkeys.at(0),ctx) + , type(hkeys.at(1),ctx) + , origin(hkeys.at(2),ctx) {} template<class T> egammaTruthAssociationAlg::MCTruthInfo_t -egammaTruthAssociationAlg::particleTruthClassifier(const T* particle, - Cache* extrapolationCache) const +egammaTruthAssociationAlg::particleTruthClassifier( + const T* particle, + Cache* extrapolationCache) const { MCTruthInfo_t info; IMCTruthClassifier::Info mcinfo; @@ -283,17 +318,20 @@ egammaTruthAssociationAlg::particleTruthClassifier(const T* particle, * second pass based on the cluster to find true photons **/ template<> egammaTruthAssociationAlg::MCTruthInfo_t -egammaTruthAssociationAlg::particleTruthClassifier<xAOD::Electron>(const xAOD::Electron* electron, - Cache* extrapolationCache) const +egammaTruthAssociationAlg::particleTruthClassifier<xAOD::Electron>( + const xAOD::Electron* electron, + Cache* extrapolationCache) const { MCTruthInfo_t info; IMCTruthClassifier::Info mcinfo; mcinfo.extrapolationCache = extrapolationCache; auto ret = m_mcTruthClassifier->particleTruthClassifier(electron, &mcinfo); if (ret.first == MCTruthPartClassifier::Unknown && - !xAOD::EgammaHelpers::isFwdElectron(electron) && electron->caloCluster()) { + !xAOD::EgammaHelpers::isFwdElectron(electron) && + electron->caloCluster()) { ATH_MSG_DEBUG("Trying cluster-based truth classification for electron"); - ret = m_mcTruthClassifier->particleTruthClassifier(electron->caloCluster(), &mcinfo); + ret = m_mcTruthClassifier->particleTruthClassifier(electron->caloCluster(), + &mcinfo); } info.genPart = mcinfo.genPart; info.first = ret.first; @@ -303,13 +341,15 @@ egammaTruthAssociationAlg::particleTruthClassifier<xAOD::Electron>(const xAOD::E template<class T, class L> StatusCode -egammaTruthAssociationAlg::match(const xAOD::TruthParticleContainer& truthParticles, - const SG::WriteDecorHandleKeyArray<T>& hkeys, - const SG::AuxElement::Accessor<L>& linkAccess, - xAOD::TruthParticleContainer* egammaTruthContainer) const +egammaTruthAssociationAlg::match( + const EventContext& ctx, + const xAOD::TruthParticleContainer& truthParticles, + const SG::WriteDecorHandleKeyArray<T>& hkeys, + const SG::AuxElement::Accessor<L>& linkAccess, + xAOD::TruthParticleContainer* egammaTruthContainer) const { - writeDecorHandles<T> decoHandles(hkeys); + writeDecorHandles<T> decoHandles(hkeys,ctx); // Extrapolation Cache Cache extrapolationCache{}; @@ -320,14 +360,17 @@ egammaTruthAssociationAlg::match(const xAOD::TruthParticleContainer& truthPartic const xAOD::TruthParticle* truthParticle = info.genPart; if (truthParticle) { - ElementLink<xAOD::TruthParticleContainer> link(truthParticle, truthParticles); - ATH_MSG_DEBUG("Decorating object with link to truth, index = " << link.index()); + ElementLink<xAOD::TruthParticleContainer> link( + truthParticle, truthParticles, ctx); + ATH_MSG_DEBUG( + "Decorating object with link to truth, index = " << link.index()); decoHandles.el(*particle) = link; } else { decoHandles.el(*particle) = ElementLink<xAOD::TruthParticleContainer>(); } decoHandles.el(*particle).toPersistent(); - ATH_MSG_DEBUG("truthType = " << info.first << " truthOrigin = " << info.second); + ATH_MSG_DEBUG("truthType = " << info.first + << " truthOrigin = " << info.second); decoHandles.type(*particle) = static_cast<int>(info.first); decoHandles.origin(*particle) = static_cast<int>(info.second); @@ -337,11 +380,14 @@ egammaTruthAssociationAlg::match(const xAOD::TruthParticleContainer& truthPartic ATH_MSG_ERROR("The egammaTruthContainer needs to be valid"); return StatusCode::FAILURE; } - const xAOD::TruthParticle* truth = xAOD::TruthHelpers::getTruthParticle(*particle); + const xAOD::TruthParticle* truth = + xAOD::TruthHelpers::getTruthParticle(*particle); if (truth) { - xAOD::TruthParticle* truthEgamma = getEgammaTruthParticle(truth, *egammaTruthContainer); + xAOD::TruthParticle* truthEgamma = + getEgammaTruthParticle(truth, *egammaTruthContainer); if (truthEgamma) { - // we found a truthEgamma object we should annotate if this is the best link + // we found a truthEgamma object we should annotate if this is the + // best link bool annotateLink = true; // by default we annotate const auto link = linkAccess(*truthEgamma); // what already exists if (link.isValid()) { @@ -351,13 +397,14 @@ egammaTruthAssociationAlg::match(const xAOD::TruthParticleContainer& truthPartic std::abs(particle->e() / truthEgamma->e() - 1)) { ATH_MSG_DEBUG(truthEgamma << ": " - << " already set to a better matched particle: " << particle); + << " already set to a better matched particle: " + << particle); annotateLink = false; } } if (annotateLink) { - L link(particle, *decoHandles.readHandle()); + L link(particle, *decoHandles.readHandle(), ctx); linkAccess(*truthEgamma) = link; linkAccess(*truthEgamma).toPersistent(); } diff --git a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h index f695fba988b8a67ef664ed4abaefb0b0536bf83b..363cb365e7b30c58c257e51d94e4e81a2bd0dc89 100644 --- a/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h +++ b/Reconstruction/egamma/egammaAlgs/src/egammaTruthAssociationAlg.h @@ -5,7 +5,7 @@ #ifndef EGAMMAALGS_EGAMMATRUTHASSOCIATIONALG_H #define EGAMMAALGS_EGAMMATRUTHASSOCIATIONALG_H -#include "AthenaBaseComps/AthAlgorithm.h" +#include "AthenaBaseComps/AthReentrantAlgorithm.h" #include "GaudiKernel/EventContext.h" #include "GaudiKernel/ToolHandle.h" #include "MCTruthClassifier/IMCTruthClassifier.h" @@ -38,7 +38,7 @@ @author B. Lenzi J. Mitrevski C. Anastopoulos */ -class egammaTruthAssociationAlg : public AthAlgorithm +class egammaTruthAssociationAlg : public AthReentrantAlgorithm { public: @@ -56,13 +56,7 @@ public: virtual StatusCode finalize() override final; /** @brief execute on container */ - virtual StatusCode execute() override final - { - return execute_r(Algorithm::getContext()); - } - // This will become the normal execute when - // inheriting from AthReentrantAlgorithm - StatusCode execute_r(const EventContext& ctx) const; + virtual StatusCode execute(const EventContext& ctx) const override final; private: struct MCTruthInfo_t @@ -82,8 +76,8 @@ private: template<class T> struct writeDecorHandles { - writeDecorHandles( - const SG::WriteDecorHandleKeyArray<T>& keys); // constructor + writeDecorHandles(const SG::WriteDecorHandleKeyArray<T>& keys, + const EventContext& ctx); // constructor SG::WriteDecorHandle<T, ElementLink<xAOD::TruthParticleContainer>> el; SG::WriteDecorHandle<T, int> type; @@ -97,7 +91,8 @@ private: * info and decorate the truth particles with links to the reco ones * (reco<typeName>Link) **/ template<class T, class L> - StatusCode match(const xAOD::TruthParticleContainer& truthParticles, + StatusCode match(const EventContext& ctx, + const xAOD::TruthParticleContainer& truthParticles, const SG::WriteDecorHandleKeyArray<T>& hkeys, const SG::AuxElement::Accessor<L>& linkAccess, xAOD::TruthParticleContainer* egammaTruthContainer) const; @@ -110,9 +105,10 @@ private: /** @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(xAOD::TruthParticleContainer& egammaTruthContainer, - const xAOD::TruthParticle* truth, - const xAOD::TruthParticleContainer* oldContainer) const; + void getNewTruthParticle( + xAOD::TruthParticleContainer& egammaTruthContainer, + const xAOD::TruthParticle* truth, + const xAOD::TruthParticleContainer* oldContainer) const; /** @brief Return true if the truth particle is a prompt electron or photon * **/