diff --git a/PhysicsAnalysis/AnalysisCommon/IsolationSelection/IsolationSelection/Defs.h b/PhysicsAnalysis/AnalysisCommon/IsolationSelection/IsolationSelection/Defs.h index db4e1d81907ea391f102f15e9dd5b1a182070200..160f6ce2dd8c91427c36d8ba170acf6b9060e95c 100644 --- a/PhysicsAnalysis/AnalysisCommon/IsolationSelection/IsolationSelection/Defs.h +++ b/PhysicsAnalysis/AnalysisCommon/IsolationSelection/IsolationSelection/Defs.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration */ #ifndef ISOLATIONSELECTION_DEFS_H @@ -13,6 +13,7 @@ #include <xAODTracking/TrackParticle.h> #include <set> +#include <unordered_set> namespace CP { using CharAccessor = SG::AuxElement::ConstAccessor<char>; @@ -72,6 +73,8 @@ namespace CP { using TrackSet = std::set<TrackPtr>; using ClusterSet = std::set<CaloClusterPtr>; using PflowSet = std::set<FlowElementPtr>; + + using UnorderedClusterSet = std::unordered_set<const xAOD::CaloCluster*>; } // namespace CP #endif diff --git a/PhysicsAnalysis/AnalysisCommon/IsolationSelection/IsolationSelection/IsolationCloseByCorrectionTool.h b/PhysicsAnalysis/AnalysisCommon/IsolationSelection/IsolationSelection/IsolationCloseByCorrectionTool.h index b190090dfbcad0f69515dce63264c58d018dd3c8..befbf596df86ac25ea3c6534a1b0bdd7728d8876 100644 --- a/PhysicsAnalysis/AnalysisCommon/IsolationSelection/IsolationSelection/IsolationCloseByCorrectionTool.h +++ b/PhysicsAnalysis/AnalysisCommon/IsolationSelection/IsolationSelection/IsolationCloseByCorrectionTool.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration */ #ifndef IsolationSelection_IsolationCloseByCorrectionTool_H @@ -90,6 +90,7 @@ namespace CP { TrackSet tracks{}; ClusterSet clusters{}; PflowSet flows{}; + UnorderedClusterSet eg_associated_clusters{}; }; private: @@ -113,13 +114,13 @@ namespace CP { const IsoVector& getIsolationTypes(const xAOD::IParticle* particle) const; // Functions to perfrom the isolation correction directly - CorrectionCode subtractCloseByContribution(const EventContext& ctx, const xAOD::IParticle* P, const ObjectCache& cache) const; + CorrectionCode subtractCloseByContribution(const EventContext& ctx, const xAOD::IParticle* P, ObjectCache& cache) const; // Remove close-by tracks from the track isolation variables CorrectionCode getCloseByCorrectionTrackIso(const xAOD::IParticle* primary, const IsoType type, const ObjectCache& cache, float& isoValue) const; // Remove close-by calo clusters from the topo et isolation variables CorrectionCode getCloseByCorrectionTopoIso(const EventContext& ctx, const xAOD::IParticle* primary, const IsoType type, - const ObjectCache& cache, float& isoValue) const; + ObjectCache& cache, float& isoValue) const; // Remove close-by flow elements from the neflow isolation variables CorrectionCode getCloseByCorrectionPflowIso(const EventContext& ctx, const xAOD::IParticle* primary, const IsoType type, const ObjectCache& cache, float& isoValue) const; @@ -128,7 +129,8 @@ namespace CP { /// Loads the topo clusters associated with the primary IParticle - ClusterSet getAssociatedClusters(const EventContext& ctx, const xAOD::IParticle* particle) const; + ClusterSet getAssociatedClusters(const EventContext& ctx, const xAOD::IParticle* particle, + ObjectCache& cache) const; /// Loads the pflow elements associated with the primary IParticle PflowSet getAssocFlowElements(const EventContext& ctx, const xAOD::IParticle* particle) const; diff --git a/PhysicsAnalysis/AnalysisCommon/IsolationSelection/Root/IsolationCloseByCorrectionTool.cxx b/PhysicsAnalysis/AnalysisCommon/IsolationSelection/Root/IsolationCloseByCorrectionTool.cxx index 1d3c77ae84a1d424d9c02d5c48ac4bde2047526a..cd479af275c2c188799b39a5f517b128688c235c 100644 --- a/PhysicsAnalysis/AnalysisCommon/IsolationSelection/Root/IsolationCloseByCorrectionTool.cxx +++ b/PhysicsAnalysis/AnalysisCommon/IsolationSelection/Root/IsolationCloseByCorrectionTool.cxx @@ -171,7 +171,7 @@ namespace CP { const TrackSet tracks = getAssociatedTracks(prim, cache.prim_vtx); cache.tracks.insert(tracks.begin(), tracks.end()); } - const ClusterSet clusters = getAssociatedClusters(ctx, prim); + const ClusterSet clusters = getAssociatedClusters(ctx, prim, cache); cache.clusters.insert(clusters.begin(), clusters.end()); } getAssocFlowElements(ctx, cache); @@ -330,7 +330,7 @@ namespace CP { CorrectionCode IsolationCloseByCorrectionTool::subtractCloseByContribution(const EventContext& ctx, const xAOD::IParticle* par, - const ObjectCache& cache) const { + ObjectCache& cache) const { const IsoVector& types = getIsolationTypes(par); if (types.empty()) { ATH_MSG_WARNING("No isolation types are defiend for " << particleName(par)); @@ -485,10 +485,10 @@ namespace CP { // - for electrons and photons, collect the associated clusters // - for muons, use associated cluster, if it exists, to get topocluster, otherwise, extrapolate the InDet trackParticle to calo // and look for topoclusters matching in dR the core muon cone - ClusterSet IsolationCloseByCorrectionTool::getAssociatedClusters(const EventContext& ctx, const xAOD::IParticle* P) const { - // Use accessor to mark topoclusters which are associated to an egamma object, electron or photon - // This will be used to avoid associating the same object to a muon during getCloseByCorrectionPflowIso or getCloseByCorrectionTopoIso - static const CharDecorator acc_isAssociatedToEG{"isAssociatedToEG"}; + ClusterSet IsolationCloseByCorrectionTool::getAssociatedClusters(const EventContext& ctx,const xAOD::IParticle* P, + ObjectCache& cache) const { + // Remember topoclusters which are associated to an egamma object, electron or photon + // This will be used to avoid associating the same object to a muon ClusterSet clusters; if (isEgamma(P)) { const xAOD::Egamma* egamm = static_cast<const xAOD::Egamma*>(P); @@ -498,11 +498,10 @@ namespace CP { std::vector<const xAOD::CaloCluster*> constituents = xAOD::EgammaHelpers::getAssociatedTopoClusters(clust); for (const xAOD::CaloCluster* cluster : constituents) { if (cluster && std::abs(cluster->eta()) < 7. && cluster->e() > MinClusterEnergy) { - clusters.emplace(cluster); - acc_isAssociatedToEG(*cluster) = true; // set flag that this cluster is associate to an electron or photon + clusters.emplace(cluster); + cache.eg_associated_clusters.insert(cluster); // set flag that this cluster is associated to an electron or photon ATH_MSG_VERBOSE("getAssociatedClusters: " << P->type() << " has topo cluster with pt: " << cluster->pt() * MeVtoGeV << " GeV, eta: " - << cluster->eta() << ", phi: " << cluster->phi() - << ", isAssociatedToEG: " << (int)acc_isAssociatedToEG(*cluster)); + << cluster->eta() << ", phi: " << cluster->phi()); } } } @@ -523,7 +522,7 @@ namespace CP { for (const xAOD::CaloCluster* cluster : constituents) { if (cluster && std::abs(cluster->eta()) < 7. && cluster->e() > MinClusterEnergy) { // skip association if this cluster is already associated with an electron or photon - priority is given to egamma reco - if (!acc_isAssociatedToEG.isAvailable(*cluster) || !acc_isAssociatedToEG(*cluster)) { + if (!cache.eg_associated_clusters.contains(cluster)) { clusters.emplace(cluster); foundMuonTopo = true; ATH_MSG_VERBOSE("getAssociatedClusters: muon has topo cluster with pt: " << cluster->pt() * MeVtoGeV << " GeV, eta: " @@ -681,7 +680,7 @@ namespace CP { } CorrectionCode IsolationCloseByCorrectionTool::getCloseByCorrectionTopoIso(const EventContext& ctx, const xAOD::IParticle* primary, - const IsoType type, const ObjectCache& cache, + const IsoType type, ObjectCache& cache, float& isoValue) const { // check if the isolation can be loaded if (!isTopoEtIso(type)) { @@ -707,7 +706,7 @@ namespace CP { ATH_MSG_VERBOSE("getCloseByCorrectionTopoIso: " << toString(type) << " of " << particleName(primary) << " with pt: " << primary->pt() * MeVtoGeV << " GeV, eta: " << primary->eta() << ", phi: " << primary->phi() << " before correction: " << isoValue * MeVtoGeV << " GeV. "); - ClusterSet assoc = getAssociatedClusters(ctx, primary); + ClusterSet assoc = getAssociatedClusters(ctx, primary, cache); for (const CaloClusterPtr& calo : cache.clusters) { const float dR = xAOD::P4Helpers::deltaR(ref_eta, ref_phi, calo->eta(), calo->phi()); ATH_MSG_VERBOSE("getCloseByCorrectionTopoIso: Loop over cluster: " << calo->pt() * MeVtoGeV << " GeV, eta: " << calo->eta() << " phi: " << calo->phi() << " dR: " << dR);