ATLAS Offline Software
MenuTruthThinning.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // MenuTruthThinning.cxx, (c) ATLAS Detector software
8 // Translated into xAOD by James Catmore (James.Catmore@cern.ch)
9 // from orignal D3PD code by Snyder, Marshall, Boonekamp et al:
10 // TruthD3PDAnalysis/src/TruthParticleFilterTool.cxx
11 // Provides user with a menu of options for thinning truth particles
12 // from xAOD. Tool sets up a mask which is then passed to the
13 // thinning service.
14 // DOES NOT PRESERVE GRAPH INTEGRITY
15 
20 #include "GaudiKernel/SystemOfUnits.h"
22 #include "GaudiKernel/ThreadLocalContext.h"
24 #include <vector>
25 #include <string>
26 
27 using Gaudi::Units::GeV;
28 
29 // Constructor
31  const std::string& n,
32  const IInterface* p ) :
33 base_class(t,n,p),
34 m_writeFirstN(-1),
35 m_totpart(0),
36 m_removedpart(0)
37 {
38  declareProperty ("WritePartons",
39  m_writePartons = true,
40  "Keep partons?");
41 
42  declareProperty ("WriteHadrons",
43  m_writeHadrons = false,
44  "Keep hadrons?");
45 
46  declareProperty ("WriteBHadrons",
47  m_writeBHadrons = true,
48  "Keep b-hadrons?");
49 
50  declareProperty ("WriteCHadrons",
51  m_writeCHadrons = true,
52  "Keep c-hadrons?");
53 
54  declareProperty ("WriteGeant",
55  m_writeGeant = false,
56  "Keep Geant particles?");
57 
58  declareProperty ("GeantPhotonPtThresh",
60  "Write Geant photons with Pt above this threshold. "
61  "Set to < 0 to not write any.");
62 
63  declareProperty ("WriteTauHad",
64  m_writeTauHad = false,
65  "Keep hadronic taus?");
66 
67  declareProperty ("PartonPtThresh",
68  m_partonPtThresh = -1,
69  "Write partons with Pt above this threshold.");
70 
71  declareProperty ("WriteBSM",
72  m_writeBSM = false,
73  "Keep BSM particles?");
74 
75  declareProperty ("WriteBosons",
76  m_writeBosons = false,
77  "Keep bosons?");
78 
79  declareProperty ("PhotonPtThresh",
80  m_photonPtCut = 3000.,
81  "Photon pt cut with WriteBosons");
82 
83  declareProperty ("WriteBSMProducts",
84  m_writeBSMProducts = false,
85  "Keep BSM particle decay products?");
86 
87  declareProperty ("WriteBosonProducts",
88  m_writeBosonProducts = false,
89  "Keep boson decay products?");
90 
91  declareProperty ("WriteTopAndDecays",
92  m_writeTopAndDecays = false,
93  "Keep top partons and immediate decay products?");
94 
95  declareProperty("WriteEverything",
96  m_writeEverything = false,
97  "Keep absolutely everything (overrides all other flags)");
98 
99  declareProperty("WriteAllLeptons",
100  m_writeAllLeptons = false,
101  "Keep absolutely all leptons");
102 
103  declareProperty("WriteLeptonsNotFromHadrons",
105  "Keep leptons not from hadron decays");
106 
107  declareProperty("WriteAllStable",
108  m_writeAllStable = false,
109  "Keep all stable particles");
110 
111  declareProperty("WriteNotPhysical",
112  m_writeNotPhysical = false,
113  "Save also non-physical particles");
114 
115  declareProperty("WriteFirstN",
116  m_writeFirstN = -1,
117  "Keep first N particles in record");
118 
119  declareProperty("PreserveDescendants",
120  m_preserveDescendants = false,
121  "Preserve descendants of retained particles");
122 
123  declareProperty("PreserveGeneratorDescendants",
125  "Preserve descendants of retained particles excluding Geant particles");
126 
127  declareProperty("PreserveAncestors",
128  m_preserveAncestors = false,
129  "Preserve ancestors of retained particles");
130 
131  declareProperty ("PreserveParentsSiblingsChildren",
132  m_preserveImmediate = false,
133  "Preserve the parents, siblings and children of retained particles");
134 
135  declareProperty ("PreserveHadronizationVertices",
136  m_preserveHadVtx = false,
137  "Preserve hadronization vertices with parents/children.");
138 
139  declareProperty ("WritettHFHadrons",
140  m_writettHFHadrons = false,
141  "Keep tt+HF hadrons?");
142 
143  declareProperty ("PDGIDsToKeep",
144  m_pdgIdsToKeep={},
145  "List of PDG IDs to always keep");
146 
147  declareProperty ("LongLivedPDGIDs",
149  "List of PDG IDs of long lived particles so that one can store their children");
150 }
151 
152 // Destructor
154 }
155 
156 // Athena initialize and finalize
158 {
159  if (m_preserveDescendants && m_preserveGeneratorDescendants) {
160  ATH_MSG_FATAL("You are asking to keep both all descendants, and only those from the event generator. Please check your job options.");
161  return StatusCode::FAILURE;
162  }
163  if (m_preserveImmediate && (m_preserveDescendants || m_preserveGeneratorDescendants || m_preserveAncestors)) {
164  ATH_MSG_FATAL("You are asking to preserve only parents/children/siblings of retained states, and also more distant relatives. Please check your job options.");
165  return StatusCode::FAILURE;
166  }
167  m_totpart = 0;
168  m_removedpart = 0;
169  m_eventCount = 0;
170 
171  ATH_CHECK( m_particlesKey.initialize (m_streamName) );
172  ATH_CHECK( m_verticesKey.initialize (m_streamName) );
173  return StatusCode::SUCCESS;
174 }
175 
177 {
178  ATH_MSG_VERBOSE("finalize() ...");
179  ATH_MSG_INFO("Total of " << m_totpart << " truth particles");
180  ATH_MSG_INFO("Removed "<< m_removedpart << " truth particles");
181  return StatusCode::SUCCESS;
182 }
183 
184 // The thinning itself
186 {
187  const EventContext& ctx = Gaudi::Hive::currentContext();
188 
189  // Retrieve the truth collections
191  (m_particlesKey, ctx);
192  m_totpart += importedTruthParticles->size();
193 
195  (m_verticesKey, ctx);
196 
197  // Print events
198  //if( m_eventCount < 20 ){
199  // printxAODTruth(m_eventCount, importedTruthParticles);
200  //}
201  ++m_eventCount;
202 
203  // Set up a mask with the same number of entries as the full TruthParticle collection
204  std::vector<bool> particleMask, vertexMask;
205  int nTruthParticles = importedTruthParticles->size();
206  int nTruthVertices = importedTruthVertices->size();
207  particleMask.assign(nTruthParticles,true); // default: keep all particles
208  vertexMask.assign(nTruthVertices,false); // throw all vertices: to be discussed
209 
210  // Standard particle loop
211  for (int particleCounter = 0; particleCounter < nTruthParticles; ++particleCounter) {
212  const xAOD::TruthParticle* particle = (*importedTruthParticles)[particleCounter];
213  // Keep first N particles
214  if ( (particleCounter > m_writeFirstN) && (!isAccepted(particle)) ){
215  // Particle removal - note mask is true by default
216  particleMask[particleCounter] = false;
217  ++m_removedpart;
218  }
219  }
220 
221  // If user requested preservation of descendants/ancestors:
222  // - loop over the masks and work out which particles need to be descended/ascended from
223  // - do the recursive loop
224  // - update the masks including the descendants/ancestors
225  // To ensure graph completeness, this over-rides anything set by the special treatment
226  // of taus in the section above
228  std::unordered_set<int> encounteredUniqueIDs; // For loop handling
229  if (m_preserveDescendants || m_preserveGeneratorDescendants || m_preserveAncestors) {
230  for (int i=0; i<nTruthParticles; ++i) {
231  bool toKeep = particleMask[i];
232  if (!toKeep) continue;
233  const xAOD::TruthParticle* particle = (*importedTruthParticles)[i];
234  encounteredUniqueIDs.clear();
235  if (m_preserveDescendants) decayHelper.descendants(particle,particleMask,vertexMask,encounteredUniqueIDs,true);
236  encounteredUniqueIDs.clear();
237  if (m_preserveGeneratorDescendants) decayHelper.descendants(particle,particleMask,vertexMask,encounteredUniqueIDs,false);
238  encounteredUniqueIDs.clear();
239  if (m_preserveAncestors) decayHelper.ancestors(particle,particleMask,vertexMask,encounteredUniqueIDs);
240  encounteredUniqueIDs.clear();
241  }
242  }
243  // User only wants to keep parents, siblings and children of retained states
244  // Much simpler case - no recursion so no need for uniqueIDs etc
245  if (m_preserveImmediate) {
246  // Make a copy of the particle mask to avoid changes being propagated
247  // down the chain
248  std::vector<bool> particleMaskCopy = particleMask;
249  for (int i=0; i<nTruthParticles; ++i) {
250  bool toKeep = particleMask[i]; // still loop over the orginal list, not the copy
251  if (!toKeep) continue;
252  const xAOD::TruthParticle* particle = (*importedTruthParticles)[i];
253  decayHelper.immediateRelatives(particle,particleMaskCopy,vertexMask,
254  m_preserveHadVtx); // but only update the copy
255  }
256  particleMask = particleMaskCopy; // Now update the original list in one go
257  }
258 
259  // Execute the thinning service based on the mask. Finish.
260  importedTruthParticles.keep (particleMask);
261  importedTruthVertices.keep (vertexMask);
262 
263  return StatusCode::SUCCESS;
264 }
265 
266 // Test to see if we want to keep a particle
268 {
269  bool ok = false;
270 
271  int pdg_id = p->absPdgId();
272 
273  // All explicitly requested PDG IDs of long lived particles, this is needed
274  // because their childrens uniqueIDs can be above the cut off m_geantOffset
275  if(!m_longLivedPdgIds.empty() && parentIsLongLived(p)) ok = true;
276 
277 
278  if (HepMC::is_simulation_particle(p) && !m_writeGeant && !m_writeEverything && !ok) {
279  if (!(MC::isPhoton(pdg_id) && m_geantPhotonPtThresh >= 0 && p->pt() > m_geantPhotonPtThresh) )
280  return false;
281  }
282 
283  // Do we want to save everything?
284  if (m_writeEverything) ok = true;
285 
286  // Save NotPhysical particles
287  if (m_writeNotPhysical && !MC::isPhysical(p)) ok = true;
288 
289  // OK if we select partons and are at beginning of event record
290  if( m_writePartons && !MC::isHadron(pdg_id) &&
291  (m_partonPtThresh<0 || p->pt()>m_partonPtThresh) )
292  ok = true;
293 
294  // OK if we should select hadrons and are in hadron range
295  // JRC: cut changed from PHOTOSMIN to m_geantOffset
296  if( m_writeHadrons && MC::isHadron (pdg_id) && !HepMC::is_simulation_particle(p) ) ok = true;
297 
298  // OK if we should select b hadrons and are in hadron range
299  // JRC: cut changed from PHOTOSMIN to m_geantOffset
300  if( m_writeBHadrons && !HepMC::is_simulation_particle(p) && MC::isBottomHadron (pdg_id)) ok = true;
301 
302  // OK if we should select c hadrons and are in hadron range
303  // JRC: cut changed from PHOTOSMIN to m_geantOffset
304  if( m_writeCHadrons && !HepMC::is_simulation_particle(p) && MC::isCharmHadron (pdg_id)) ok = true;
305 
306  // PHOTOS range: check whether photons come from parton range or
307  // hadron range
308  int motherPDGID = 999999999;
309  // AV: dropped the HepMC::PHOTOSMIN condition
310  if ( !HepMC::is_simulation_particle(p) && p->hasProdVtx() )
311  {
312  const xAOD::TruthVertex* vprod = p->prodVtx();
313  if (vprod->nIncomingParticles() > 0) {
314  const xAOD::TruthParticle* mother = vprod->incomingParticle(0);
315  if (mother) motherPDGID = mother->pdgId();
316  }
317  if( m_writePartons && !MC::isHadron( motherPDGID ) ) ok = true;
318  if( m_writeHadrons && MC::isHadron( motherPDGID ) ) ok = true;
319  }
320 
321  // OK if we should select G4 particles and are in G4 range
322  if( m_writeGeant && HepMC::is_simulation_particle(p) ) ok = true;
323 
324  if(isLeptonFromTau(p)) ok = true;
325 
326  if(isFsrFromLepton(p)) ok = true;
327 
328  // Hadronic tau decays
329  if(m_writeTauHad){
330  std::unordered_set<int> uniqueID_trace;
331  if (isFromTau(p, uniqueID_trace))
332  ok = true;
333  }
334 
335  // Bosons
336  if(m_writeBosons && (MC::isZ(p)||MC::isW(p)||MC::isHiggs(p) || (MC::isPhoton(p) && p->pt()>m_photonPtCut) )) ok = true;
337 
338  // BSM particles
339  if(m_writeBSM && MC::isBSM(p)) ok = true;
340 
341  // tt+HF hadrons
342  if (m_writettHFHadrons && isttHFHadron(p)) ok = true;
343 
344  // Top quarks
345  if(m_writeTopAndDecays && MC::isTop(p)) ok = true;
346 
347  // All leptons
348  if(m_writeAllLeptons && MC::isLepton(p))ok = true; // Include 4th generation...
349 
350  // All stable
351  if (m_writeAllStable && MC::isStable(p) && !HepMC::is_simulation_particle(p)) ok = true;
352 
353  // All leptons not from hadron decays
354  if(!ok && m_writeLeptonsNotFromHadrons && MC::isLepton(p) && MC::isStable(p)) {// Include 4th generation...
355  ok = !(matchHadronIncTau(p) || matchQuarkIncTau(p) || isOrphanIncTau(p));
356  }
357 
358  if ((m_writeBSMProducts || m_writeBosonProducts || m_writeTopAndDecays) && p->hasProdVtx()){ // Either way we have to go through parents
359  const xAOD::TruthVertex* prodVtx = p->prodVtx();
360  unsigned int nIncoming = prodVtx->nIncomingParticles();
361  for(unsigned int itr=0; itr<nIncoming; ++itr) {
362  const xAOD::TruthParticle* incomingParticle = prodVtx->incomingParticle(itr);
363  if (!incomingParticle) continue;
364  if ((m_writeBSMProducts && MC::isBSM(incomingParticle)) ||
365  (m_writeBosonProducts && (MC::isZ(incomingParticle)||MC::isW(incomingParticle)||MC::isHiggs(incomingParticle) || (MC::isPhoton(incomingParticle) && incomingParticle->pt()>m_photonPtCut) )) ||
366  (m_writeTopAndDecays && MC::isTop(incomingParticle)) ){
367  ok = true;
368  break;
369  }
370  }
371 
372  }
373 
374  // All explicitly requested PDG IDs
375  for (const auto id : m_pdgIdsToKeep){
376  if (pdg_id==id) ok=true;
377  } // Loop over PDG IDs
378 
379  return ok;
380 }
381 
383  //check if part descends from a hadron, possibly passing through a tau decay
384  //ported from TopFiducial
385  std::vector<int> hadrons = std::vector<int>{111};
386  std::vector<int> taus = std::vector<int>{15,-15};
387  return matchGenParticle(part, hadrons, taus, true);
388 }
389 
391  //check if part descends from a hadron, possibly passing through a tau decay
392  //ported from TopFiducial
393  std::vector<int> quarks = std::vector<int>{1,6};
394  std::vector<int> taus = std::vector<int>{15,-15};
395  return matchGenParticle(part, quarks, taus, true);
396 }
397 
399  //check if part descends from nothing, possibly passing through a tau decay
400  //(indicating a broken truth record)
401  //ported from TopFiducial
402 
403  int pdgId = part->pdgId();
404 
405  if (!part->hasProdVtx()) return true;
406 
407  const xAOD::TruthVertex* prodVtx = part->prodVtx();
408  unsigned int nIncoming = prodVtx->nIncomingParticles();
409  unsigned int itrParent = 0;
410 
411  // Simple loop catch
412  if (prodVtx==part->decayVtx()) return false;
413 
414  //0 incoming-> orphan
415  if(nIncoming == 0) return true;
416 
417  unsigned int nParents = 0;
418  while(nParents==0 && itrParent<nIncoming) {
419  const xAOD::TruthParticle* incomingParticle = prodVtx->incomingParticle(itrParent);
420 
421  // If the parent is itself migrate up the generator record
422  if(incomingParticle->pdgId() == pdgId) {
423  if(!isOrphanIncTau(incomingParticle)) nParents++;
424  }
425  else if(MC::isTau(incomingParticle)) {
426  if(!isOrphanIncTau(incomingParticle)) nParents++;
427  }
428  else {
429  nParents++;
430  }
431  ++itrParent;
432  }
433  return (nParents==0);
434 }
435 
437  std::vector<int> &intermediatePdgIds, bool targetsAreRange) const {
438  //check if part descends from a particle, possibly passing through an intermediate decay
439  //ported from TopFiducial
440 
441  int pdgId = part->pdgId();
442 
443  bool found = false;
444 
445  // Iterators for the target pdg or the intermediate pdg ids
446  std::vector<int>::const_iterator itrPdgId, itrPdgIdEnd;
447 
448  if (!part->hasProdVtx()) return false;
449 
450  // Loop over the parents
451  const xAOD::TruthVertex* prodVtx = part->prodVtx();
452  unsigned int nIncoming = prodVtx->nIncomingParticles();
453 
454  // Simple loop catch
455  if (prodVtx==part->decayVtx()) return false;
456 
457  unsigned int itrParent = 0;
458  while(!found && itrParent<nIncoming) {
459  const xAOD::TruthParticle* incomingParticle = prodVtx->incomingParticle(itrParent);
460 
461  if(!targetsAreRange) {
462 
463  // If the parent is one of the particles in the target pdg list
464  itrPdgId = targetPdgIds.begin();
465  itrPdgIdEnd = targetPdgIds.end();
466  for(;itrPdgId != itrPdgIdEnd; ++itrPdgId) {
467  if(incomingParticle->pdgId() == (*itrPdgId)) return true;
468  }
469  }
470  else {
471  int absPdgId = incomingParticle->absPdgId();
472 
473  // If the parent is within the range given in the target pdg list
474  if(targetPdgIds.size() == 1) {
475  if(absPdgId >= targetPdgIds.at(0)) return true;
476  }
477  else if(targetPdgIds.size() >= 2) {
478  if(absPdgId >= targetPdgIds.at(0) &&
479  absPdgId <= targetPdgIds.at(1)) return true;
480  }
481  }
482 
483  // If the parent is itself migrate up the generator record
484  if(incomingParticle->pdgId() == pdgId) {
485  found = matchGenParticle(incomingParticle, targetPdgIds, intermediatePdgIds, targetsAreRange);
486  }
487  else {
488  // If the parent is in the intermediatePdgIds list migrate up the generator record
489  itrPdgId = intermediatePdgIds.begin();
490  itrPdgIdEnd = intermediatePdgIds.end();
491  bool foundIntermediate = false;
492  while(!foundIntermediate && itrPdgId != itrPdgIdEnd) {
493  if(incomingParticle->pdgId() == (*itrPdgId)) foundIntermediate = true;
494  else ++itrPdgId;
495  }
496  if(foundIntermediate) {
497  found = matchGenParticle(incomingParticle, targetPdgIds, intermediatePdgIds, targetsAreRange);
498  }
499  }
500 
501  ++itrParent;
502  }
503  return found;
504 }
505 
507 
508  int pdg = part->pdgId();
509 
510  if(!MC::isSMLepton(part)) return false; // all leptons including tau.
511 
512  const xAOD::TruthVertex* prod = part->prodVtx();
513  if(!prod) return false; // no parent.
514 
515  // Simple loop catch
516  if (prod==part->decayVtx()) return false;
517 
518  // Loop over the parents of this particle.
519  unsigned int nIncoming = prod->nIncomingParticles();
520  for(unsigned int itr = 0; itr<nIncoming; ++itr){
521  int parentId = prod->incomingParticle(itr)->pdgId();
522  if( MC::isTau(parentId) ) {
523  ATH_MSG_DEBUG("Particle with pdgId = " << pdg << ", matched to tau");
524  return true; // Has tau parent
525  }
526 
527  if(parentId == pdg) { // Same particle just a different MC status
528  // Go up the generator record until a tau is found or not.
529  // Note that this requires a connected *lepton* chain, while calling
530  // isFromTau would allow leptons from hadrons from taus
531  if(isLeptonFromTau(prod->incomingParticle(itr))) {
532  return true;
533  }
534  }
535  }
536 
537  return false;
538 }
539 
541  std::unordered_set<int>& uniqueID_trace) const {
542 
543  int pdg = part->pdgId();
544 
545  const xAOD::TruthVertex* prod = part->prodVtx();
546  if(!prod) return false; // no parent.
547 
548  // Simple loop catch
549  if (prod==part->decayVtx()) return false;
550 
551  // More complex loop catch
552  std::unordered_set<int>::const_iterator foundVtx = uniqueID_trace.find( HepMC::uniqueID(prod) );
553  if( foundVtx != uniqueID_trace.end() ) {
554  ATH_MSG_DEBUG( "Found a loop (a la Sherpa sample). Backing out." );
555  return false;
556  }
557  uniqueID_trace.insert(HepMC::uniqueID(prod));
558 
559  // Loop over the parents of this particle.
560  unsigned int nIncoming = prod->nIncomingParticles();
561  for (unsigned int pitr = 0; pitr<nIncoming; ++pitr){
562  const xAOD::TruthParticle* itrParent = prod->incomingParticle(pitr);
563  if (!itrParent) continue;
564  if (pitr>2) break; // No point in trying - this vertex does not have a quantum meaning...
565 
566  if( MC::isTau(itrParent) ) {
567  // Check if one of the children of this parent was a tau - if it is, then it is
568  // photon radiation, and we already cover that under FSR
569  bool has_fsr = false;
570  if ( itrParent->hasDecayVtx() ){
571  unsigned int nChildren = itrParent->decayVtx()->nOutgoingParticles();
572  for (unsigned int citr = 0; citr<nChildren; ++citr) {
573  const xAOD::TruthParticle* itrChild = itrParent->decayVtx()->outgoingParticle(citr);
574  if (!itrChild) continue;
575  if (MC::isTau(itrChild)){
576  has_fsr = true;
577  break;
578  } // Caught FSR check
579  } // loop over immediate children
580  } // Parent has an end vertex
581  if (has_fsr) return false;
582  ATH_MSG_DEBUG("Particle with pdgId = " << pdg << ", matched to tau");
583  return true; // Has tau parent
584  }
585 
586  // Go up the generator record until a tau is found or not.
587  if(isFromTau(itrParent, uniqueID_trace)) {
588  return true;
589  }
590  }
591 
592  return false;
593 }
594 
595 
596 
598 
599  int ttHFClassification=6;
600 
601  static const SG::ConstAccessor<int> TopHadronOriginFlagAcc("TopHadronOriginFlag");
602  if (TopHadronOriginFlagAcc.isAvailable(*part)){
603  ttHFClassification = TopHadronOriginFlagAcc(*part);
604  }
605  else{
606  return false;
607  }
608 
609  if (ttHFClassification < 6 ) // useful Hadrons
610  return true;
611 
612  return false;
613 }
614 
615 
617  int pdg = part->pdgId();
618  if(!MC::isPhoton(part)) return false;
619  if(HepMC::is_simulation_particle(part) ) return false; // Geant photon
620  const xAOD::TruthVertex* prod = part->prodVtx();
621  if(!prod) return false; // no parent.
622  // Simple loop check
623  if (prod==part->decayVtx()) return false;
624  // Loop over the parents of this particle.
625  unsigned int nIncoming = prod->nIncomingParticles();
626  for(unsigned int pitr=0; pitr<nIncoming; ++pitr){
627  const xAOD::TruthParticle* itrParent = prod->incomingParticle(pitr);
628  int parentId = itrParent->pdgId();
629  if(MC::isElectron(parentId) ||
630  MC::isMuon(parentId) ||
631  MC::isTau(parentId)) {
632  ATH_MSG_DEBUG("Photon with uniqueID " << HepMC::uniqueID(part) << " matched to particle with pdgId = " << parentId );
633  return true; // Has lepton parent
634  }
635  if(parentId == pdg) { // Same particle just a different MC status
636  // Go up the generator record until a tau is found or not.
637  if(isFsrFromLepton(itrParent)) return true;
638  }
639  }
640  return false;
641 }
642 
644  //loop over the parents of the truth particle, if the parent is in the list of long lived particles
645  //store this truth particle.
646  for(size_t parent_itr = 0; parent_itr < part->nParents(); parent_itr++){
647  if(!part->parent(parent_itr)) continue;
648  const xAOD::TruthParticle* parent = part->parent(parent_itr);
649  const int parent_abs_pdgid = abs(parent->pdgId());
650  if(std::find(m_longLivedPdgIds.begin(), m_longLivedPdgIds.end(), parent_abs_pdgid) != m_longLivedPdgIds.end() ){
651  return true;
652  }
653  }
654  return false;
655 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
xAOD::TruthVertex_v1::nOutgoingParticles
size_t nOutgoingParticles() const
Get the number of outgoing particles.
DerivationFramework::MenuTruthThinning::matchGenParticle
bool matchGenParticle(const xAOD::TruthParticle *part, std::vector< int > &targetIDs, std::vector< int > &intermediateIDs, bool targetsAreRange) const
Definition: MenuTruthThinning.cxx:436
DerivationFramework::MenuTruthThinning::m_writeAllLeptons
bool m_writeAllLeptons
Parameter: Write all leptons.
Definition: MenuTruthThinning.h:105
DerivationFramework::MenuTruthThinning::m_geantPhotonPtThresh
float m_geantPhotonPtThresh
Parameter: Write Geant photons with Pt above this threshold.
Definition: MenuTruthThinning.h:77
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:18
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:79
DerivationFramework::MenuTruthThinning::m_writeBSMProducts
bool m_writeBSMProducts
Parameter: Write BSM decay products.
Definition: MenuTruthThinning.h:99
xAOD::TruthParticle_v1::absPdgId
int absPdgId() const
Absolute PDG ID code (often useful)
DerivationFramework::MenuTruthThinning::initialize
virtual StatusCode initialize() override
Definition: MenuTruthThinning.cxx:157
DerivationFramework::MenuTruthThinning::m_photonPtCut
float m_photonPtCut
Definition: MenuTruthThinning.h:87
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
python.plotting.G4DebuggerConfig.hadrons
list hadrons
Definition: G4DebuggerConfig.py:24
isBSM
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.
Definition: AtlasPID.h:836
ThinningHandle.h
Handle for requesting thinning for a data object.
DerivationFramework::MenuTruthThinning::m_writePartons
bool m_writePartons
Parameter: Keep partons?
Definition: MenuTruthThinning.h:61
MenuTruthThinning.h
DerivationFramework::MenuTruthThinning::matchQuarkIncTau
bool matchQuarkIncTau(const xAOD::TruthParticle *part) const
Definition: MenuTruthThinning.cxx:390
TruthVertexContainer.h
DerivationFramework::MenuTruthThinning::m_pdgIdsToKeep
std::vector< int > m_pdgIdsToKeep
Parameter: List of PDG IDs to always keep.
Definition: MenuTruthThinning.h:130
test_pyathena.pt
pt
Definition: test_pyathena.py:11
SG::ConstAccessor< int >
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
DerivationFramework::MenuTruthThinning::m_preserveGeneratorDescendants
bool m_preserveGeneratorDescendants
Definition: MenuTruthThinning.h:124
DerivationFramework::MenuTruthThinning::m_preserveHadVtx
bool m_preserveHadVtx
Definition: MenuTruthThinning.h:127
isBottomHadron
bool isBottomHadron(const T &p)
Definition: AtlasPID.h:901
DerivationFramework::MenuTruthThinning::matchHadronIncTau
bool matchHadronIncTau(const xAOD::TruthParticle *part) const
Definition: MenuTruthThinning.cxx:382
SG::ThinningHandle
Handle for requesting thinning for a data object.
Definition: ThinningHandle.h:84
isSMLepton
bool isSMLepton(const T &p)
APID: the fourth generation leptons are not standard model leptons.
Definition: AtlasPID.h:191
DerivationFramework::DecayGraphHelper::immediateRelatives
void immediateRelatives(const xAOD::TruthParticle *pHead, std::vector< bool > &particleMask, std::vector< bool > &vertexMask, bool keepHadVtx)
Definition: DecayGraphHelper.h:31
isHiggs
bool isHiggs(const T &p)
APID: HIGGS boson is only one particle.
Definition: AtlasPID.h:387
DerivationFramework::MenuTruthThinning::m_writeCHadrons
bool m_writeCHadrons
Parameter: Keep c-hadrons?
Definition: MenuTruthThinning.h:70
DerivationFramework::DecayGraphHelper::descendants
void descendants(const xAOD::TruthParticle *pHead, std::vector< int > &particleList, std::unordered_set< int > &encounteredUniqueIDs)
Definition: DecayGraphHelper.h:116
MC::isPhysical
bool isPhysical(const T &p)
Identify if the particle is physical, i.e. is stable or decayed.
Definition: HepMCHelpers.h:51
DerivationFramework::MenuTruthThinning::isttHFHadron
static bool isttHFHadron(const xAOD::TruthParticle *)
Definition: MenuTruthThinning.cxx:597
SG::ThinningHandleBase::keep
void keep(size_t ndx)
Mark that index ndx in the container should be kept (not thinned away).
Definition: ThinningHandleBase.cxx:75
xAOD::TruthParticle_v1::hasDecayVtx
bool hasDecayVtx() const
Check for a decay vertex on this particle.
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
HepMC::is_simulation_particle
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...
Definition: MagicNumbers.h:354
DerivationFramework::MenuTruthThinning::m_writeBHadrons
bool m_writeBHadrons
Parameter: Keep b-hadrons?
Definition: MenuTruthThinning.h:67
lumiFormat.i
int i
Definition: lumiFormat.py:85
InDetSecVtxTruthMatchUtils::isAccepted
bool isAccepted(int matchInfo)
Definition: InDetSecVtxTruthMatchTool.h:100
DerivationFramework::MenuTruthThinning::~MenuTruthThinning
virtual ~MenuTruthThinning()
Definition: MenuTruthThinning.cxx:153
DerivationFramework::MenuTruthThinning::finalize
virtual StatusCode finalize() override
Definition: MenuTruthThinning.cxx:176
beamspotman.n
n
Definition: beamspotman.py:729
DerivationFramework::MenuTruthThinning::m_writeTauHad
bool m_writeTauHad
Parameter: Keep hadronic tau decays?
Definition: MenuTruthThinning.h:80
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
DerivationFramework::MenuTruthThinning::isFromTau
bool isFromTau(const xAOD::TruthParticle *, std::unordered_set< int > &barcode_trace) const
Definition: MenuTruthThinning.cxx:540
xAOD::EgammaHelpers::isElectron
bool isElectron(const xAOD::Egamma *eg)
is the object an electron (not Fwd)
Definition: EgammaxAODHelpers.cxx:12
isZ
bool isZ(const T &p)
Definition: AtlasPID.h:376
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:37
HepMC::uniqueID
int uniqueID(const T &p)
Definition: MagicNumbers.h:116
DerivationFramework::MenuTruthThinning::m_preserveImmediate
bool m_preserveImmediate
Definition: MenuTruthThinning.h:126
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DerivationFramework::MenuTruthThinning::isLeptonFromTau
bool isLeptonFromTau(const xAOD::TruthParticle *) const
Definition: MenuTruthThinning.cxx:506
DerivationFramework::MenuTruthThinning::doThinning
virtual StatusCode doThinning() const override
Definition: MenuTruthThinning.cxx:185
DerivationFramework::MenuTruthThinning::m_preserveAncestors
bool m_preserveAncestors
Definition: MenuTruthThinning.h:125
DerivationFramework::MenuTruthThinning::m_writeLeptonsNotFromHadrons
bool m_writeLeptonsNotFromHadrons
Parameter: Write all leptons.
Definition: MenuTruthThinning.h:108
xAOD::TruthVertex_v1::incomingParticle
const TruthParticle_v1 * incomingParticle(size_t index) const
Get one of the incoming particles.
Definition: TruthVertex_v1.cxx:70
DerivationFramework::MenuTruthThinning::m_partonPtThresh
float m_partonPtThresh
Parameter: Write partons with Pt above this threshold.
Definition: MenuTruthThinning.h:90
DerivationFramework::MenuTruthThinning::m_writeNotPhysical
bool m_writeNotPhysical
Parameter: Write particles with status code 3.
Definition: MenuTruthThinning.h:114
DerivationFramework::MenuTruthThinning::MenuTruthThinning
MenuTruthThinning(const std::string &t, const std::string &n, const IInterface *p)
Definition: MenuTruthThinning.cxx:30
isTau
bool isTau(const T &p)
Definition: AtlasPID.h:205
DerivationFramework::MenuTruthThinning::m_writeEverything
bool m_writeEverything
Parameter: Write absolutely everything.
Definition: MenuTruthThinning.h:93
xAOD::TruthParticle_v1::decayVtx
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
DerivationFramework::MenuTruthThinning::m_writeTopAndDecays
bool m_writeTopAndDecays
Parameter: Write top and decay products.
Definition: MenuTruthThinning.h:102
xAOD::TruthVertex_v1
Class describing a truth vertex in the MC record.
Definition: TruthVertex_v1.h:37
errorcheck.h
Helpers for checking error return status codes and reporting errors.
DerivationFramework::DecayGraphHelper::ancestors
void ancestors(const xAOD::TruthParticle *pHead, std::vector< bool > &particleMask, std::vector< bool > &vertexMask, std::unordered_set< int > &encounteredUniqueIDs)
Definition: DecayGraphHelper.h:186
isHadron
bool isHadron(const T &p)
Definition: AtlasPID.h:348
DerivationFramework::DecayGraphHelper
Definition: DecayGraphHelper.h:26
DerivationFramework::MenuTruthThinning::m_writeBosonProducts
bool m_writeBosonProducts
Parameter: Write boson decay products.
Definition: MenuTruthThinning.h:96
runIDPVM.pdgId
pdgId
Definition: runIDPVM.py:91
DerivationFramework::MenuTruthThinning::m_writeAllStable
bool m_writeAllStable
Definition: MenuTruthThinning.h:111
checkTriggerxAOD.found
found
Definition: checkTriggerxAOD.py:328
DerivationFramework::MenuTruthThinning::m_writettHFHadrons
bool m_writettHFHadrons
Parameter: Write particles for tt+HF classification.
Definition: MenuTruthThinning.h:117
DerivationFramework::MenuTruthThinning::isFsrFromLepton
bool isFsrFromLepton(const xAOD::TruthParticle *) const
Definition: MenuTruthThinning.cxx:616
isW
bool isW(const T &p)
Definition: AtlasPID.h:379
MC::isStable
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
Definition: HepMCHelpers.h:45
DerivationFramework::MenuTruthThinning::m_writeGeant
bool m_writeGeant
Parameter: Keep geant particles?
Definition: MenuTruthThinning.h:73
isTop
bool isTop(const T &p)
Definition: AtlasPID.h:182
DerivationFramework::MenuTruthThinning::m_writeHadrons
bool m_writeHadrons
Parameter: Keep hadrons?
Definition: MenuTruthThinning.h:64
xAOD::parentId
@ parentId
Definition: TrackingPrimitives.h:517
xAOD::TruthVertex_v1::nIncomingParticles
size_t nIncomingParticles() const
Get the number of incoming particles.
xAOD::EgammaHelpers::isPhoton
bool isPhoton(const xAOD::Egamma *eg)
is the object a photon
Definition: EgammaxAODHelpers.cxx:21
isLepton
bool isLepton(const T &p)
APID: the fourth generation leptons are leptons.
Definition: AtlasPID.h:186
DerivationFramework::MenuTruthThinning::isAccepted
bool isAccepted(const xAOD::TruthParticle *) const
Definition: MenuTruthThinning.cxx:267
isCharmHadron
bool isCharmHadron(const T &p)
Definition: AtlasPID.h:900
DerivationFramework::MenuTruthThinning::m_longLivedPdgIds
std::vector< int > m_longLivedPdgIds
Parameter: List of PDG IDs of long lived particles so that one can keep their children.
Definition: MenuTruthThinning.h:133
xAOD::TruthParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TruthParticle_v1.cxx:161
DerivationFramework::MenuTruthThinning::isOrphanIncTau
bool isOrphanIncTau(const xAOD::TruthParticle *part) const
Definition: MenuTruthThinning.cxx:398
DerivationFramework::MenuTruthThinning::parentIsLongLived
bool parentIsLongLived(const xAOD::TruthParticle *) const
Definition: MenuTruthThinning.cxx:643
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
DerivationFramework::MenuTruthThinning::m_writeFirstN
int m_writeFirstN
Parameter: First N particles to write.
Definition: MenuTruthThinning.h:120
ConstAccessor.h
Helper class to provide constant type-safe access to aux data.
DerivationFramework::MenuTruthThinning::m_preserveDescendants
bool m_preserveDescendants
Parameter: preserve descendant/ancestor graph completeness.
Definition: MenuTruthThinning.h:123
xAOD::TruthParticle_v1::pdgId
int pdgId() const
PDG ID code.
DerivationFramework::MenuTruthThinning::m_writeBSM
bool m_writeBSM
Parameter: Keep BSM particles?
Definition: MenuTruthThinning.h:83
xAOD::TruthVertex_v1::outgoingParticle
const TruthParticle_v1 * outgoingParticle(size_t index) const
Get one of the outgoing particles.
Definition: TruthVertex_v1.cxx:120
DerivationFramework::MenuTruthThinning::m_writeBosons
bool m_writeBosons
Parameter: Keep bosons?
Definition: MenuTruthThinning.h:86
InDet::TrkOrigin::isFromTau
bool isFromTau(int origin)
from tau decay
Definition: InDetTrackTruthOriginDefs.h:98
HepMCHelpers.h
isMuon
bool isMuon(const T &p)
Definition: AtlasPID.h:202