ATLAS Offline Software
Loading...
Searching...
No Matches
ParticleLevelOverlapRemovalAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
8
13#include <TLorentzVector.h>
14
15#include <optional>
16#include <utility>
17#include <vector>
18
19namespace CP {
20
22
23 if (m_doJetElectronOR.value() == m_electronsKey.empty()) {
24 ANA_MSG_ERROR("doJetElectronOR is " << (m_doJetElectronOR.value() ? "true" : "false")
25 << " but the input container is "
26 << (m_electronsKey.empty() ? "empty" : "set"));
27 return StatusCode::FAILURE;
28 }
29 if (m_doJetMuonOR.value() == m_muonsKey.empty()) {
30 ANA_MSG_ERROR("doJetMuonOR is " << (m_doJetMuonOR.value() ? "true" : "false")
31 << " but the input container is "
32 << (m_muonsKey.empty() ? "empty" : "set"));
33 return StatusCode::FAILURE;
34 }
35 if (m_doJetPhotonOR.value() == m_photonsKey.empty()) {
36 ANA_MSG_ERROR("doJetPhotonOR is " << (m_doJetPhotonOR.value() ? "true" : "false")
37 << " but the input container is "
38 << (m_photonsKey.empty() ? "empty" : "set"));
39 return StatusCode::FAILURE;
40 }
41
42 ANA_CHECK(m_jetsKey.initialize());
46
50 ANA_CHECK(m_decORjet.initialize());
51
56
61
62 if (!m_jetSelection.empty())
63 ANA_CHECK(m_jetSelection.initialize());
64 if (!m_electronSelection.empty())
65 ANA_CHECK(m_electronSelection.initialize());
66 if (!m_muonSelection.empty())
67 ANA_CHECK(m_muonSelection.initialize());
68 if (!m_photonSelection.empty())
69 ANA_CHECK(m_photonSelection.initialize());
70
71 return StatusCode::SUCCESS;
72}
73
75 double rapidityOrEta,
76 double phi) const {
77 if (m_useRapidity)
78 return xAOD::P4Helpers::deltaR(jet->rapidity(), jet->phi(), rapidityOrEta,
79 phi);
80 else
81 return xAOD::P4Helpers::deltaR(jet->eta(), jet->phi(), rapidityOrEta, phi);
82}
83
84StatusCode ParticleLevelOverlapRemovalAlg::execute(const EventContext &ctx) const {
85 SG::ReadHandle<xAOD::TruthParticleContainer> electrons, muons, photons;
87 electrons = SG::makeHandle(m_electronsKey, ctx);
88 if (m_doJetMuonOR)
89 muons = SG::makeHandle(m_muonsKey, ctx);
91 photons = SG::makeHandle(m_photonsKey, ctx);
93
94 // the lepton/photon decoration handles only exist if the respective OR is
95 // enabled (their keys are empty otherwise)
96 std::optional<SG::WriteDecorHandle<xAOD::TruthParticleContainer, char>>
97 dec_electrons_OR, dec_muons_OR, dec_photons_OR;
99 dec_electrons_OR.emplace(m_decORelectron, ctx);
100 if (m_doJetMuonOR)
101 dec_muons_OR.emplace(m_decORmuon, ctx);
102 if (m_doJetPhotonOR)
103 dec_photons_OR.emplace(m_decORphoton, ctx);
105
106 // accessors for the dressed lepton kinematics (only bound when needed)
107 std::optional<SG::ReadDecorHandle<xAOD::TruthParticleContainer, float>>
108 acc_pt_dressed_e, acc_eta_dressed_e, acc_phi_dressed_e, acc_e_dressed_e;
110 acc_pt_dressed_e.emplace(m_ptDressedElectronKey, ctx);
111 acc_eta_dressed_e.emplace(m_etaDressedElectronKey, ctx);
112 acc_phi_dressed_e.emplace(m_phiDressedElectronKey, ctx);
113 acc_e_dressed_e.emplace(m_eDressedElectronKey, ctx);
114 }
115 std::optional<SG::ReadDecorHandle<xAOD::TruthParticleContainer, float>>
116 acc_pt_dressed_m, acc_eta_dressed_m, acc_phi_dressed_m, acc_e_dressed_m;
118 acc_pt_dressed_m.emplace(m_ptDressedMuonKey, ctx);
119 acc_eta_dressed_m.emplace(m_etaDressedMuonKey, ctx);
120 acc_phi_dressed_m.emplace(m_phiDressedMuonKey, ctx);
121 acc_e_dressed_m.emplace(m_eDressedMuonKey, ctx);
122 }
123
124 // dressed (rapidity or eta, phi) of a lepton, used for the DeltaR
125 auto dressedRapidityOrEtaPhi =
126 [&](const xAOD::TruthParticle& lepton,
131 TLorentzVector dressed;
132 dressed.SetPtEtaPhiE(acc_pt(lepton), acc_eta(lepton), acc_phi(lepton),
133 acc_e(lepton));
134 return std::pair<double, double>{
135 m_useRapidity ? dressed.Rapidity() : dressed.Eta(), dressed.Phi()};
136 };
137 // per-lepton dressed kinematics, indexed by position in the container
138 // (only filled for selected leptons when using dressed properties)
139 std::vector<std::pair<double, double>> dressed_electrons, dressed_muons;
140
141 // Default decorations: all objects pass!
142 for (const auto* jet : *jets) {
143 if (m_jetSelection)
144 dec_jets_OR(*jet) = m_jetSelection.getBool(*jet);
145 else
146 dec_jets_OR(*jet) = true;
147 }
148 if (m_doJetElectronOR) {
149 dressed_electrons.resize(electrons->size());
150 for (std::size_t i = 0; i < electrons->size(); ++i) {
151 const auto* electron = (*electrons)[i];
153 (*dec_electrons_OR)(*electron) = m_electronSelection.getBool(*electron);
154 else
155 (*dec_electrons_OR)(*electron) = true;
156 if (m_useDressedProperties && (*dec_electrons_OR)(*electron))
157 dressed_electrons[i] = dressedRapidityOrEtaPhi(
158 *electron, *acc_pt_dressed_e, *acc_eta_dressed_e,
159 *acc_phi_dressed_e, *acc_e_dressed_e);
160 }
161 }
162 if (m_doJetMuonOR) {
163 dressed_muons.resize(muons->size());
164 for (std::size_t i = 0; i < muons->size(); ++i) {
165 const auto* muon = (*muons)[i];
166 if (m_muonSelection)
167 (*dec_muons_OR)(*muon) = m_muonSelection.getBool(*muon);
168 else
169 (*dec_muons_OR)(*muon) = true;
170 if (m_useDressedProperties && (*dec_muons_OR)(*muon))
171 dressed_muons[i] = dressedRapidityOrEtaPhi(
172 *muon, *acc_pt_dressed_m, *acc_eta_dressed_m, *acc_phi_dressed_m,
173 *acc_e_dressed_m);
174 }
175 }
176 if (m_doJetPhotonOR) {
177 for (const auto* photon : *photons) {
179 (*dec_photons_OR)(*photon) = m_photonSelection.getBool(*photon);
180 else
181 (*dec_photons_OR)(*photon) = true;
182 }
183 }
184
185 // ----------------------
186 // OVERLAP REMOVAL
187 // ----------------------
188 // Removal Steps:
189 // 1. Jets & Muons:
190 // Remove Muons with dR < 0.4
191 // 2. Jets & Electrons:
192 // Remove Electrons with dR < 0.4
193 // 3. Photons & Jets:
194 // Remove Jets with dR < 0.4
195 // The steps are interleaved per jet (not run sequentially over all jets),
196 // and the lepton removal uses all selected jets, regardless of whether
197 // the jet itself is removed by the photon-jet overlap removal.
198
199 for (const auto* jet : *jets) {
200 if (m_jetSelection && !m_jetSelection.getBool(*jet))
201 continue;
202 if (m_doJetMuonOR) {
203 for (std::size_t i = 0; i < muons->size(); ++i) {
204 const auto* muon = (*muons)[i];
205 if ((*dec_muons_OR)(*muon)) {
207 const auto& [rapidityOrEta, phi] = dressed_muons[i];
208 if (dressedDeltaR(jet, rapidityOrEta, phi) < 0.4)
209 (*dec_muons_OR)(*muon) = false;
210 } else {
212 (*dec_muons_OR)(*muon) = false;
213 }
214 }
215 }
216 }
217 if (m_doJetElectronOR) {
218 for (std::size_t i = 0; i < electrons->size(); ++i) {
219 const auto* electron = (*electrons)[i];
220 if ((*dec_electrons_OR)(*electron)) {
222 const auto& [rapidityOrEta, phi] = dressed_electrons[i];
223 if (dressedDeltaR(jet, rapidityOrEta, phi) < 0.4)
224 (*dec_electrons_OR)(*electron) = false;
225 } else {
227 (*dec_electrons_OR)(*electron) = false;
228 }
229 }
230 }
231 }
232 if (m_doJetPhotonOR) {
233 for (const auto* photon : *photons) {
234 if ((*dec_photons_OR)(*photon)) {
236 dec_jets_OR(*jet) = false;
237 break;
238 }
239 }
240 }
241 }
242 }
243
244 return StatusCode::SUCCESS;
245}
246
247} // namespace CP
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
#define ANA_MSG_ERROR(xmsg,...)
Macro printing error messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_phiDressedMuonKey
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_photonsKey
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_decORmuon
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_muonsKey
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_eDressedElectronKey
SG::ReadHandleKey< xAOD::JetContainer > m_jetsKey
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_decORphoton
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_ptDressedElectronKey
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_ptDressedMuonKey
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_decORelectron
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_etaDressedMuonKey
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_phiDressedElectronKey
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_eDressedMuonKey
virtual StatusCode execute(const EventContext &ctx) const final
SG::WriteDecorHandleKey< xAOD::JetContainer > m_decORjet
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_electronsKey
float dressedDeltaR(const xAOD::Jet *jet, double rapidityOrEta, double phi) const
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_etaDressedElectronKey
Handle class for reading a decoration on an object.
Handle class for adding a decoration to an object.
Select isolated Photons, Electrons and Muons.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
Jet_v1 Jet
Definition of the current "jet version".
TruthParticle_v1 TruthParticle
Typedef to implementation.