92{
93
95
96
99 if (!truthParticles.isValid()) {
101 return StatusCode::FAILURE;
102 }
103 if (!truthVertices.isValid()) {
105 return StatusCode::FAILURE;
106 }
107
108
109
110 std::vector<int> recoParticleTruthIndices;
111 std::vector<int> egammaTruthIndices{};
112
113
119 if (truthMuon) {
121 if (truthMuon) {
122 recoParticleTruthIndices.push_back(
truthMuon->index());
123 }
124 }
125 }
126
127
130 if (lrtMuons) {
133 if (truthMuon) {
135 if (truthMuon) {
136 recoParticleTruthIndices.push_back(
truthMuon->index());
137 }
138 }
139 }
140 }
141 }
142
143
145
146
149
153 if (truthElectron) {
154 recoParticleTruthIndices.push_back(truthElectron->index());
155 }
156 }
157
158
161 if (fwdElectrons) {
162
166 if (truthElectron) {
167 recoParticleTruthIndices.push_back(truthElectron->index());
168 }
169 }
170 }
171
172
175 if (lrtElectrons) {
179 if (truthElectron) {
180 recoParticleTruthIndices.push_back(truthElectron->index());
181 }
182 }
183 }
184
185
191 if (truthPhoton) {
192 recoParticleTruthIndices.push_back(truthPhoton->index());
193 }
194 }
195
196
199
201
202 static const SG::ConstAccessor<int> accType("truthType");
203
204 if (!accType.isAvailable(*egTruthParticle) ||
207 continue;
208 }
209
210 using TruthLink_t = ElementLink<xAOD::TruthParticleContainer>;
212 "truthParticleLink");
213 if (!linkToTruth.isAvailable(*egTruthParticle)) {
214 continue;
215 }
216
217 const TruthLink_t& truthegamma = linkToTruth(*egTruthParticle);
219 continue;
220 }
221 egammaTruthIndices.push_back((*truthegamma)->index());
222 }
223 }
224
225
226 std::vector<bool> particleMask, vertexMask;
227 int nTruthParticles = truthParticles->size();
228 int nTruthVertices = truthVertices->size();
231 particleMask.assign(nTruthParticles, false);
232 vertexMask.assign(nTruthVertices, false);
233
234
235
236 std::vector<std::pair<int, int>> vertexLinksCounts;
237 for (const auto *vertex : *truthVertices) {
238 std::pair<int, int> tmpPair;
239 tmpPair.first =
vertex->nIncomingParticles();
240 tmpPair.second =
vertex->nOutgoingParticles();
241 vertexLinksCounts.push_back(tmpPair);
242 }
243
244
245 std::unordered_set<int> encounteredUniqueIDs;
246 for (
int i = 0;
i < nTruthParticles; ++
i) {
247 encounteredUniqueIDs.clear();
249
251 descendants(particle, particleMask, encounteredUniqueIDs);
252 encounteredUniqueIDs.clear();
253 }
254
255
257 descendants(particle, particleMask, encounteredUniqueIDs);
258 encounteredUniqueIDs.clear();
259 }
260
261
269 }
270 int nChildren = 0;
271 if (decayVtx)
272 nChildren = decayVtx->nOutgoingParticles();
273 for (
int i = 0;
i < nChildren; ++
i) {
274 particleMask[decayVtx->outgoingParticle(i)->index()] = true;
275 }
276 }
277 }
278
279
280
281 if (std::find(recoParticleTruthIndices.begin(),
282 recoParticleTruthIndices.end(),
283 i) != recoParticleTruthIndices.end()) {
285
286 ancestors(particle, particleMask, encounteredUniqueIDs);
287 encounteredUniqueIDs.clear();
288 descendants(particle, particleMask, encounteredUniqueIDs);
289 encounteredUniqueIDs.clear();
290 }
291 }
292
293
294
295 if (std::find(egammaTruthIndices.begin(), egammaTruthIndices.end(), i) !=
296 egammaTruthIndices.end()) {
297 descendants(particle, particleMask, encounteredUniqueIDs);
298 encounteredUniqueIDs.clear();
299 }
300
302 particleMask[
i] =
true;
303 }
304 else {
305
306
312
313
314
315 particleMask[
i] =
true;
316 break;
317 }
318 }
319 }
320 }
321 }
322
323
324 for (
int i = 0;
i < nTruthParticles; ++
i) {
325 if (!particleMask[i]) {
329 const auto *prodVertex =
particle->prodVtx();
330 --vertexLinksCounts[prodVertex->index()].second;
331 }
333 const auto *decayVertex =
particle->decayVtx();
334 --vertexLinksCounts[decayVertex->index()].first;
335 }
336 }
337 }
338
339
340
341
342 unsigned int nVerticesThinned = 0;
343 for (
int i = 0;
i < nTruthVertices; ++
i) {
344 if (vertexLinksCounts[i].first != 0 || vertexLinksCounts[i].second != 0) {
345 vertexMask[
i] =
true;
346 } else {
347 ++nVerticesThinned;
348 }
349 }
351
352 truthParticles.
keep(particleMask);
353 truthVertices.keep(vertexMask);
354
355 return StatusCode::SUCCESS;
356}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x,...)
ElementLink< xAOD::TruthParticleContainer > TruthLink_t
bool isValid() const
Check if the element can be found.
void keep(size_t ndx)
Mark that index ndx in the container should be kept (not thinned away).
SG::ReadHandleKey< xAOD::MuonContainer > m_muonsKey
std::atomic< unsigned long > m_nParticlesThinned
SG::ReadHandleKey< xAOD::MuonContainer > m_lrtMuonsKey
std::atomic< unsigned long > m_nVerticesProcessed
std::atomic< unsigned long > m_nVerticesThinned
SG::ReadHandleKey< xAOD::PhotonContainer > m_photonsKey
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_egammaTruthKey
SG::ThinningHandleKey< xAOD::TruthVertexContainer > m_truthVerticesKey
Gaudi::Property< std::vector< int > > m_longlived
SG::ReadHandleKey< xAOD::ElectronContainer > m_electronsKey
std::atomic< unsigned long > m_nEventsProcessed
Counters.
SG::ReadHandleKey< xAOD::ElectronContainer > m_lrtElectronsKey
Gaudi::Property< bool > m_keepMuons
Gaudi::Property< bool > m_keepEGamma
std::atomic< unsigned long > m_nParticlesProcessed
SG::ThinningHandleKey< xAOD::TruthParticleContainer > m_truthParticlesKey
Gaudi::Property< float > m_etaMaxEgTruth
SG::ReadHandleKey< xAOD::ElectronContainer > m_fwdElectronsKey
const TruthParticle_v1 * incomingParticle(size_t index) const
Get one of the incoming particles.
size_t nIncomingParticles() const
Get the number of incoming particles.
bool is_simulation_particle(const T &p)
Method to establish if a particle (or barcode) was created during the simulation (TODO update to be s...
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
bool isDecayed(const T &p)
Identify if the particle decayed.
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.
SG::ConstAccessor< T, ALLOC > ConstAccessor
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
const xAOD::TruthParticle * getTruthParticle(const xAOD::IParticle &p)
Return the truthParticle associated to the given IParticle (if any).
PhotonContainer_v1 PhotonContainer
Definition of the current "photon container version".
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
TruthParticle_v1 TruthParticle
Typedef to implementation.
Muon_v1 Muon
Reference the current persistent version:
Photon_v1 Photon
Definition of the current "egamma version".
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.
Electron_v1 Electron
Definition of the current "egamma version".