ATLAS Offline Software
Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
MCTruthClassifier Class Referenceabstract

#include <MCTruthClassifier.h>

Inheritance diagram for MCTruthClassifier:
Collaboration diagram for MCTruthClassifier:

Public Member Functions

 MCTruthClassifier (const std::string &type)
 
virtual ~MCTruthClassifier ()=default
 
virtual StatusCode initialize () override
 Dummy implementation of the initialisation function. More...
 
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOriginparticleTruthClassifier (const xAOD::TruthParticle *, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOriginparticleHepMCTruthClassifier (const HepMcParticleLink &theLink, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOriginparticleHepMCTruthClassifier (HepMC::ConstGenParticlePtr, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual const xAOD::TruthParticlegetGenPart (const xAOD::TrackParticle *, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual const xAOD::TruthParticleegammaClusMatch (const xAOD::CaloCluster *, bool, MCTruthPartClassifier::Info *info) const override final
 
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOriginparticleTruthClassifier (const xAOD::TrackParticle *, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOriginparticleTruthClassifier (const xAOD::Electron *, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOriginparticleTruthClassifier (const xAOD::Photon *, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOriginparticleTruthClassifier (const xAOD::Muon *, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOriginparticleTruthClassifier (const xAOD::CaloCluster *, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOriginparticleTruthClassifier (const xAOD::Jet *, bool DR, MCTruthPartClassifier::Info *info=nullptr) const override final
 
virtual void print () const =0
 Print the state of the tool. More...
 
virtual void print () const
 Print the state of the tool. More...
 
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc. More...
 
const ServiceHandle< StoreGateSvc > & evtStore () const
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc. More...
 
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc. More...
 
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm. More...
 
virtual StatusCode sysStart () override
 Handle START transition. More...
 
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles. More...
 
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles. More...
 
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, SG::VarHandleKey &hndl, const std::string &doc, const SG::VarHandleKeyType &)
 Declare a new Gaudi property. More...
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, SG::VarHandleBase &hndl, const std::string &doc, const SG::VarHandleType &)
 Declare a new Gaudi property. More...
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, SG::VarHandleKeyArray &hndArr, const std::string &doc, const SG::VarHandleKeyArrayType &)
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, T &property, const std::string &doc, const SG::NotHandleType &)
 Declare a new Gaudi property. More...
 
Gaudi::Details::PropertyBase * declareProperty (const std::string &name, T &property, const std::string &doc="none")
 Declare a new Gaudi property. More...
 
void updateVHKA (Gaudi::Details::PropertyBase &)
 
MsgStream & msg () const
 
MsgStream & msg (const MSG::Level lvl) const
 
bool msgLvl (const MSG::Level lvl) const
 

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution More...
 
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
 
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed. More...
 

Private Types

typedef ServiceHandle< StoreGateSvcStoreGateSvc_t
 

Private Member Functions

double detEta (double x, double y) const
 
double detPhi (double x, double y) const
 
bool TruthLoopDetectionMethod1 (const xAOD::TruthVertex *childOrigVtx, const xAOD::TruthParticle *parent) const
 
bool TruthLoopDetectionMethod2 (const xAOD::TruthParticle *child, const xAOD::TruthParticle *parent) const
 
bool TruthLoopDetectionMethod3 (const xAOD::TruthVertex *childOrigVtx, const xAOD::TruthParticle *parent) const
 
MCTruthPartClassifier::ParticleOrigin defOrigOfElectron (const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
 
MCTruthPartClassifier::ParticleOrigin defOrigOfMuon (const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
 
MCTruthPartClassifier::ParticleOrigin defOrigOfTau (const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, int motherPDG, MCTruthPartClassifier::Info &info) const
 
MCTruthPartClassifier::ParticleOrigin defOrigOfPhoton (const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
 
MCTruthPartClassifier::ParticleOrigin defOrigOfNeutrino (const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
 
bool genPartToCalo (const EventContext &ctx, const xAOD::CaloCluster *clus, const xAOD::TruthParticle *thePart, bool isFwrdEle, double &dRmatch, bool &isNarrowCone, const CaloDetDescrManager &caloDDMgr) const
 
double fracParticleInJet (const xAOD::TruthParticle *, const xAOD::Jet *, bool DR, bool nparts) const
 
void findJetConstituents (const xAOD::Jet *, std::set< const xAOD::TruthParticle * > &constituents, bool DR) const
 
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey> More...
 
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyArrayType &)
 specialization for handling Gaudi::Property<SG::VarHandleKeyArray> More...
 
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleType &)
 specialization for handling Gaudi::Property<SG::VarHandleBase> More...
 
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &t, const SG::NotHandleType &)
 specialization for handling everything that's not a Gaudi::Property<SG::VarHandleKey> or a <SG::VarHandleKeyArray> More...
 

Private Attributes

SG::ReadHandleKey< xAOD::TruthParticleContainerm_truthParticleContainerKey {this,"xAODTruthParticleContainerName","TruthParticles","ReadHandleKey for xAOD::TruthParticleContainer"}
 
ToolHandle< Trk::IParticleCaloExtensionToolm_caloExtensionTool {this,"ParticleCaloExtensionTool",""}
 
SG::ReadCondHandleKey< CaloDetDescrManagerm_caloMgrKey {this,"CaloDetDescrManager",""}
 
ToolHandle< xAOD::ITruthParticlesInConeToolm_truthInConeTool {this,"TruthInConeTool","xAOD::TruthParticlesInConeTool/TruthParticlesInConeTool"}
 
bool m_FwdElectronUseG4Sel
 
float m_FwdElectronTruthExtrEtaCut
 
float m_FwdElectronTruthExtrEtaWindowCut
 
float m_partExtrConeEta
 
float m_partExtrConePhi
 
bool m_useCaching
 
float m_phtClasConePhi
 
float m_phtClasConeEta
 
float m_phtdRtoTrCut
 
float m_fwrdEledRtoTrCut
 
bool m_ROICone
 
float m_pTChargePartCut
 
float m_pTNeutralPartCut
 
bool m_inclG4part
 
SG::ReadHandleKey< xAODTruthParticleLinkVectorm_truthLinkVecReadHandleKey {this,"xAODTruthLinkVector","xAODTruthLinks", "ReadHandleKey for xAODTruthParticleLinkVector"}
 
float m_deltaRMatchCut
 
float m_deltaPhiMatchCut
 
int m_NumOfSiHitsCut
 
float m_jetPartDRMatch
 
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default) More...
 
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default) More...
 
std::vector< SG::VarHandleKeyArray * > m_vhka
 
bool m_varHandleArraysDeclared
 

Detailed Description

Definition at line 55 of file MCTruthClassifier.h.

Member Typedef Documentation

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ MCTruthClassifier()

MCTruthClassifier::MCTruthClassifier ( const std::string &  type)
inline

Definition at line 65 of file MCTruthClassifier.h.

96  {
97  ATH_MSG_INFO(" Initializing MCTruthClassifier");

◆ ~MCTruthClassifier()

virtual MCTruthClassifier::~MCTruthClassifier ( )
virtualdefault

Member Function Documentation

◆ declareGaudiProperty() [1/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  hndl,
const SG::VarHandleKeyArrayType  
)
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKeyArray>

Definition at line 170 of file AthCommonDataStore.h.

172  {
173  return *AthCommonDataStore<PBASE>::declareProperty(hndl.name(),
174  hndl.value(),
175  hndl.documentation());
176 
177  }

◆ declareGaudiProperty() [2/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  hndl,
const SG::VarHandleKeyType  
)
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158  {
159  return *AthCommonDataStore<PBASE>::declareProperty(hndl.name(),
160  hndl.value(),
161  hndl.documentation());
162 
163  }

◆ declareGaudiProperty() [3/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  hndl,
const SG::VarHandleType  
)
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleBase>

Definition at line 184 of file AthCommonDataStore.h.

186  {
187  return *AthCommonDataStore<PBASE>::declareProperty(hndl.name(),
188  hndl.value(),
189  hndl.documentation());
190  }

◆ declareGaudiProperty() [4/4]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > &  t,
const SG::NotHandleType  
)
inlineprivateinherited

specialization for handling everything that's not a Gaudi::Property<SG::VarHandleKey> or a <SG::VarHandleKeyArray>

Definition at line 199 of file AthCommonDataStore.h.

200  {
201  return PBASE::declareProperty(t);
202  }

◆ declareProperty() [1/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
SG::VarHandleBase hndl,
const std::string &  doc,
const SG::VarHandleType  
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
hndlObject holding the property value.
docDocumentation string for the property.

This is the version for types that derive from SG::VarHandleBase. The property value object is put on the input and output lists as appropriate; then we forward to the base class.

Definition at line 245 of file AthCommonDataStore.h.

249  {
250  this->declare(hndl.vhKey());
251  hndl.vhKey().setOwner(this);
252 
253  return PBASE::declareProperty(name,hndl,doc);
254  }

◆ declareProperty() [2/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
SG::VarHandleKey hndl,
const std::string &  doc,
const SG::VarHandleKeyType  
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
hndlObject holding the property value.
docDocumentation string for the property.

This is the version for types that derive from SG::VarHandleKey. The property value object is put on the input and output lists as appropriate; then we forward to the base class.

Definition at line 221 of file AthCommonDataStore.h.

225  {
226  this->declare(hndl);
227  hndl.setOwner(this);
228 
229  return PBASE::declareProperty(name,hndl,doc);
230  }

◆ declareProperty() [3/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
SG::VarHandleKeyArray hndArr,
const std::string &  doc,
const SG::VarHandleKeyArrayType  
)
inlineinherited

Definition at line 259 of file AthCommonDataStore.h.

263  {
264 
265  // std::ostringstream ost;
266  // ost << Algorithm::name() << " VHKA declareProp: " << name
267  // << " size: " << hndArr.keys().size()
268  // << " mode: " << hndArr.mode()
269  // << " vhka size: " << m_vhka.size()
270  // << "\n";
271  // debug() << ost.str() << endmsg;
272 
273  hndArr.setOwner(this);
274  m_vhka.push_back(&hndArr);
275 
276  Gaudi::Details::PropertyBase* p = PBASE::declareProperty(name, hndArr, doc);
277  if (p != 0) {
278  p->declareUpdateHandler(&AthCommonDataStore<PBASE>::updateVHKA, this);
279  } else {
280  ATH_MSG_ERROR("unable to call declareProperty on VarHandleKeyArray "
281  << name);
282  }
283 
284  return p;
285 
286  }

◆ declareProperty() [4/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
T &  property,
const std::string &  doc,
const SG::NotHandleType  
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
propertyObject holding the property value.
docDocumentation string for the property.

This is the generic version, for types that do not derive from SG::VarHandleKey. It just forwards to the base class version of declareProperty.

Definition at line 333 of file AthCommonDataStore.h.

337  {
338  return PBASE::declareProperty(name, property, doc);
339  }

◆ declareProperty() [5/6]

Gaudi::Details::PropertyBase* AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( const std::string &  name,
T &  property,
const std::string &  doc = "none" 
)
inlineinherited

Declare a new Gaudi property.

Parameters
nameName of the property.
propertyObject holding the property value.
docDocumentation string for the property.

This dispatches to either the generic declareProperty or the one for VarHandle/Key/KeyArray.

Definition at line 352 of file AthCommonDataStore.h.

355  {
356  typedef typename SG::HandleClassifier<T>::type htype;
357  return declareProperty (name, property, doc, htype());
358  }

◆ declareProperty() [6/6]

Gaudi::Details::PropertyBase& AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > &  t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145  {
146  typedef typename SG::HandleClassifier<T>::type htype;
148  }

◆ defOrigOfElectron()

ParticleOrigin MCTruthClassifier::defOrigOfElectron ( const xAOD::TruthParticleContainer xTruthParticleContainer,
const xAOD::TruthParticle thePart,
bool &  isPrompt,
MCTruthPartClassifier::Info info 
) const
private

Definition at line 280 of file MCTruthClassifierGen.cxx.

284 {
285  ATH_MSG_DEBUG("Executing DefOrigOfElectron ");
286 
287  // Find the first copy of this particle stored in the xAOD::TruthParticleContainer (i.e. the particle prior to any interactions)
288  const xAOD::TruthParticle* thePriPart = MC::findMatching(xTruthParticleContainer, thePart);
289  if (!thePriPart) return NonDefined;
290  if (!MC::isElectron(thePriPart)) return NonDefined;
291 
292  //-- to define electron outcome status
293  info.particleOutCome = defOutComeOfElectron(thePriPart);
294 
295  const xAOD::TruthVertex* partProdVtx = thePriPart->hasProdVtx() ? thePriPart->prodVtx() : nullptr;
296  if (!partProdVtx) return NonDefined;
297 
298  if (partProdVtx->nIncomingParticles() > 1) ATH_MSG_DEBUG("DefOrigOfElectron:: electron has more than one parent.");
299 
300  const xAOD::TruthParticle* ancestor = MC::findMother(thePriPart);
301  info.setMotherProperties(ancestor);
302  if (!ancestor) { return NonDefined; } // After this point "ancestor" cannot be nullptr
303 
304  // Start of method 1 of protecting against loops
305  bool samePart = TruthLoopDetectionMethod1(partProdVtx, ancestor);
306  // to resolve Sherpa loop
307  // End of method 1 of protecting against loops
308 
309  if ((MC::isMuon(ancestor) || MC::isTau(ancestor) || MC::isW(ancestor)) && ancestor->hasProdVtx() && !samePart) {
310  int pPDG(0);
311  const xAOD::TruthParticle* ancestorParent{};
312  do {
313  pPDG = 0; // reset pPDG
314  ancestorParent = MC::findMother(ancestor);
315  // Start of method 2 of protecting against loops
316  // to prevent Sherpa loop
317  if (ancestor == ancestorParent) { break; }
318  if (TruthLoopDetectionMethod2(ancestor,ancestorParent)) {
319  ancestorParent = ancestor;
320  break;
321  }
322  // End of method 2 of protecting against loops
323  // FIXME why are slightly different criteria used in method 1 and method 2???
324  if (ancestorParent) {
325  pPDG = ancestorParent->pdgId(); // Only set pPDG in the case that we aren't in a loop.
326  if (MC::isMuon(pPDG) || MC::isTau(pPDG) || MC::isW(pPDG)) { // There will be another iteration so set ancestor to ancestorParent
327  ancestor = ancestorParent; // ancestorParent is not nullptr here
328  }
329  }
330  } while ((MC::isMuon(pPDG) || MC::isTau(pPDG) || MC::isW(pPDG)));
331 
332  if (MC::isMuon(pPDG) || MC::isTau(pPDG) || MC::isW(pPDG) || MC::isZ(pPDG) || MC::isHiggs(pPDG) ||
333  MC::isMSSMHiggs(pPDG) || MC::isHeavyBoson(pPDG) || MC::isTop(pPDG) || // MSSM Higgs bosons, Heavy bosons( Z', Z'', W'+)
334  std::abs(pPDG) == MC::WBOSON_LRSM || MC::isNeutrinoRH(pPDG) || // Left-right symmetric model WBoson || Right-handed neutrino (Pythia-specific)
335  MC::isSUSY(pPDG)) {
336  ancestor = ancestorParent; // ancestorParent is not nullptr here
337  }
338  }
339 
340  info.setMotherProperties(ancestor);
341  const int ancestorPDG = ancestor->pdgId();
342  const xAOD::TruthVertex* ancestorProdVtx = ancestor->hasProdVtx() ? ancestor->prodVtx() : nullptr;
343  partProdVtx = ancestor->decayVtx();
344  const int numOfParents = partProdVtx->nIncomingParticles();
345  const int numberOfChildren = partProdVtx->nOutgoingParticles();
346 
347  // Determine decay products
348  auto DP = DecayProducts(partProdVtx);
349  const int NumOfPhot = DP.pd(MC::PHOTON);
350  const int NumOfEl = DP.pd(MC::ELECTRON);
351  const int NumOfPos = DP.pd(MC::POSITRON);
352  const int NumOfquark = DP.apd({MC::DQUARK,MC::UQUARK,MC::SQUARK,MC::CQUARK,MC::BQUARK,MC::TQUARK});
353  const int NumOfgluon = DP.apd(MC::GLUON);
354  const int NumOfElNeut = DP.apd(MC::NU_E);
355  const int NumOfLQ = DP.apd(MC::LEPTOQUARK);
356  const int NumOfMuPl = DP.pd(-MC::MUON);
357  const int NumOfMuMin = DP.pd(MC::MUON);
358  const int NumOfMuNeut = DP.apd(MC::NU_MU);
359  const int NumOfTau = DP.apd(MC::TAU);
360  const int NumOfTauNeut = DP.apd(MC::NU_TAU);
361 
362  samePart = false;
363  int NumOfNucFr(0);
364  const bool possibleNuclearFragment = (numOfParents == 1 && (MC::isPhoton(ancestorPDG) || MC::isElectron(ancestorPDG) || MC::isMuon(ancestorPDG) || std::abs(ancestorPDG) == MC::PIPLUS));
365  for (const auto& aChild: partProdVtx->particles_out()) {
366  if (!aChild) continue;
367  const int childPDG = aChild->pdgId();
368  if (std::abs(childPDG) == std::abs(ancestorPDG) && HepMC::is_same_generator_particle(aChild, ancestor )) samePart = true;
369  if (possibleNuclearFragment &&
370  (MC::isNucleus(childPDG) || childPDG == 0 || childPDG == MC::PROTON || childPDG == MC::NEUTRON || // FIXME Do we really expect particles with PDG_ID = 0 in the truth record?
371  std::abs(childPDG) == MC::PIPLUS || std::abs(childPDG) == MC::PI0))
372  NumOfNucFr++;
373  }
374  // End of section determining decay products
375 
376  if (MC::isPhoton(ancestorPDG) && ancestorProdVtx) {
377  if (ancestorProdVtx->nIncomingParticles() > 1) { ATH_MSG_DEBUG("DefOrigOfElectron:: photon has more than one parent."); }
378  for (const auto& photonParent: ancestorProdVtx->particles_in()) {
379  if (!photonParent) continue;
380  info.photonMother = photonParent; // FIXME Just taking the first valid particle...
381  }
382  }
383 
384  if ((MC::isPhoton(ancestorPDG) && numberOfChildren == 2 && NumOfEl == 1 && NumOfPos == 1) || (MC::isPhoton(ancestorPDG) && numberOfChildren == 1 && (NumOfEl == 1 || NumOfPos == 1))) return PhotonConv;
385 
386  // e,gamma,pi+Nuclear->NuclearFragments+nuclons+e
387  if ((numOfParents == 1 && (MC::isPhoton(ancestorPDG) || MC::isElectron(ancestorPDG) || MC::isTau(ancestorPDG))) && numberOfChildren > 1 && NumOfNucFr != 0) return ElMagProc;
388 
389  if (numOfParents == 1 && std::abs(ancestorPDG) == MC::PIPLUS && numberOfChildren > 2 && NumOfNucFr != 0) return ElMagProc;
390 
391  // nuclear photo fission
392  if (MC::isPhoton(ancestorPDG) && numberOfChildren > 4 && NumOfNucFr != 0) return ElMagProc;
393 
394  // unknown process el(pos)->el+pos??
395  if (MC::isElectron(ancestorPDG) && numberOfChildren == 2 && NumOfEl == 1 && NumOfPos == 1) return ElMagProc;
396 
397  // unknown process el->el+el??
398  if (ancestorPDG == MC::ELECTRON && numberOfChildren == 2 && NumOfEl == 2 && NumOfPos == 0) return ElMagProc;
399 
400  // unknown process pos->pos+pos??
401  if (ancestorPDG == MC::POSITRON && numberOfChildren == 2 && NumOfEl == 0 && NumOfPos == 2) return ElMagProc;
402 
403  // unknown process pos/el->pos/el??
404  if (MC::isElectron(ancestorPDG) && !MC::isDecayed(ancestor) && ancestorPDG == thePriPart->pdgId() && numberOfChildren == 1 && !samePart) return ElMagProc;
405 
406  // pi->pi+e+/e-; mu->mu+e+/e- ;
407  // gamma+ atom->gamma(the same) + e (compton scattering)
408  if (numberOfChildren == 2 && (NumOfEl == 1 || NumOfPos == 1) && !MC::isElectron(ancestorPDG) && samePart) return ElMagProc;
409 
410  if ((ancestorPDG == MC::PI0 && numberOfChildren == 3 && NumOfPhot == 1 && NumOfEl == 1 && NumOfPos == 1) ||
411  (ancestorPDG == MC::PI0 && numberOfChildren == 4 && NumOfPhot == 0 && NumOfEl == 2 && NumOfPos == 2))
412  return DalitzDec;
413 
414  // Quark weak decay
415  if (MC::isSMQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && NumOfElNeut == 1) return QuarkWeakDec;
416 
417  if (MC::isMuon(ancestorPDG) && NumOfNucFr != 0) return ElMagProc;
418 
419  if (MC::isTop(ancestorPDG)) return top;
420 
421  if (MC::isW(ancestorPDG) && ancestorProdVtx && ancestorProdVtx->nIncomingParticles() != 0) {
422 
423  const xAOD::TruthVertex* prodVert = ancestorProdVtx;
424  const xAOD::TruthParticle* ptrPart{};
425  do {
426  ptrPart = prodVert->incomingParticle(0); // FIXME just taking the first one
427  prodVert = ptrPart->hasProdVtx() ? ptrPart->prodVtx() : nullptr;
428  } while (MC::isW(ptrPart) && prodVert);
429 
430  if (prodVert && prodVert->nIncomingParticles() == 1) {
431  if (std::abs(ptrPart->pdgId()) == MC::RH_NU_E) return NuREle; // Right-handed NU_E (Pythia-specific)
432  if (std::abs(ptrPart->pdgId()) == MC::RH_NU_MU) return NuRMu; // Right-handed NU_MU (Pythia-specific)
433  if (std::abs(ptrPart->pdgId()) == MC::RH_NU_TAU) return NuRTau; // Right-handed NU_TAU (Pythia-specific)
434  }
435  return WBoson;
436  }
437  if (MC::isW(ancestorPDG)) return WBoson;
438  if (MC::isZ(ancestorPDG)) return ZBoson;
439 
440  // MadGraphPythia ZWW*->lllnulnu
441  if (numOfParents == 1 && numberOfChildren > 4 && (MC::isSMQuark(ancestorPDG) || MC::isGluon(ancestorPDG))) {
442 
443  const xAOD::TruthParticle* thePartToCheck = thePriPart;
444  const xAOD::TruthParticle* theParent = thePriPart->hasProdVtx() ? thePriPart->prodVtx()->incomingParticle(0) : nullptr; // FIXME just taking the first one
445  if (theParent && MC::isElectron(theParent) && MC::isDecayed(theParent)) { thePartToCheck = theParent; }
446 
447  bool isZboson = false;
448  bool isWboson = false;
449  bool skipnext = false;
450 
451  for (unsigned int ipOut = 0; ipOut + 1 < partProdVtx->nOutgoingParticles(); ++ipOut) {
452  const xAOD::TruthParticle* aChild = partProdVtx->outgoingParticle(ipOut);
453  if (!aChild) continue;
454  const xAOD::TruthParticle* theNextChild = nullptr;
455  for (unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->nOutgoingParticles(); ipOut1++) {
456  theNextChild = partProdVtx->outgoingParticle(ipOut1);
457  if (theNextChild) break;
458  }
459  if (!theNextChild) continue;
460  if (skipnext) {
461  skipnext = false;
462  continue;
463  }
464 
465  if (MC::isElectron(aChild) && MC::isElectron(theNextChild)) {
466  // Zboson
467  if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
468  isZboson = true;
469  break;
470  }
471  skipnext = true;
472  } else if (MC::isElectron(aChild) && std::abs(theNextChild->pdgId()) == MC::NU_E) {
473  // WBoson
474  if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
475  isWboson = true;
476  break;
477  }
478  skipnext = true;
479  }
480  }
481  if (isWboson) return WBoson;
482  if (isZboson) return ZBoson;
483  }
484  if (numOfParents == 2) {
485  //--Sherpa Z->ee
486  if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfEl == 1 && NumOfPos == 1) return ZBoson;
487 
488  //--Sherpa W->enu ??
489  if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfElNeut == 1) return WBoson;
490 
491  const int pdg1 = partProdVtx->incomingParticle(0)->pdgId();
492  const int pdg2 = partProdVtx->incomingParticle(1)->pdgId();
493  //--Sherpa ZZ,ZW
494  if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
495  (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
496  (MC::isQuark(pdg1)||MC::isGluon(pdg1)) && (MC::isQuark(pdg2)||MC::isGluon(pdg2))) return DiBoson;
497 
498  //--Sherpa VVV -- Note, have to allow for prompt photon radiation or these get lost
499  if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
500  (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
501  (MC::isQuark(pdg1)||MC::isGluon(pdg1)) && (MC::isQuark(pdg2)||MC::isGluon(pdg2))) return MultiBoson;
502  }
503 
504  // New Sherpa Z->ee
505  if (partProdVtx == ancestorProdVtx) {
506  int NumOfEleLoop = 0;
507  int NumOfLepLoop = 0;
508  int NumOfEleNeuLoop = 0;
509  for (const auto *const pout: partProdVtx->particles_out()) {
510  if (!pout) continue;
511  for (const auto *const pin: partProdVtx->particles_in()) {
512  if (!pin) continue;
513  if (!HepMC::is_same_particle(pout,pin)) continue;
514  if (MC::isElectron(pout)) NumOfEleLoop++;
515  if (std::abs(pout->pdgId()) == MC::NU_E) NumOfEleNeuLoop++;
516  if (MC::isSMLepton(pout)) NumOfLepLoop++;
517  break; // break out of inner loop after having found two matching particles
518  }
519  }
520  if (NumOfEleLoop == 2 && NumOfEleNeuLoop == 0) return ZBoson;
521  if (NumOfEleLoop == 1 && NumOfEleNeuLoop == 1) return WBoson;
522  if ((NumOfEleLoop == 4 && NumOfEleNeuLoop == 0) || (NumOfEleLoop == 3 && NumOfEleNeuLoop == 1) ||
523  (NumOfEleLoop == 2 && NumOfEleNeuLoop == 2)) return DiBoson;
524  if (NumOfLepLoop == 4) return DiBoson;
525  }
526 
527  //-- McAtNLo
528 
529  if (MC::isHiggs(ancestorPDG)) return Higgs;
530 
531  if (MC::isMSSMHiggs(ancestorPDG)) return HiggsMSSM; // MSSM Higgs bosons
532 
533  if (MC::isHeavyBoson(ancestorPDG)) return HeavyBoson; // Heavy bosons( Z', Z'', W'+)
534 
535  if (MC::isMuon(ancestorPDG)) return Mu;
536  if (MC::isTau(ancestorPDG)) {
537  const ParticleOrigin tauOrig = defOrigOfTau(xTruthParticleContainer, ancestor, ancestorPDG, info);
538  const ParticleType tautype = defTypeOfTau(tauOrig);
539  return (tautype == IsoTau)?tauOrig:TauLep;
540  }
541 
542  if (std::abs(ancestorPDG) == MC::WBOSON_LRSM) return WBosonLRSM; // Left-right symmetric model WBoson (Pythia-specific)
543  if (std::abs(ancestorPDG) == MC::RH_NU_E) return NuREle; // Right-handed NU_E (Pythia-specific)
544  if (std::abs(ancestorPDG) == MC::RH_NU_MU) return NuRMu; // Right-handed NU_MU (Pythia-specific)
545  if (std::abs(ancestorPDG) == MC::RH_NU_TAU) return NuRTau; // Right-handed NU_TAU (Pythia-specific)
546  if (MC::isLeptoQuark(ancestorPDG) || NumOfLQ != 0) return LQ;
547  if (MC::isSUSY(ancestorPDG)) return SUSY;
548  if (MC::isBSM(ancestorPDG)) return OtherBSM;
549 
550  const ParticleType pType = defTypeOfHadron(ancestorPDG);
551  if ((pType == BBbarMesonPart || pType == CCbarMesonPart) && ancestorProdVtx && MC::isHardScatteringVertex(ancestorProdVtx)) isPrompt = true;
552  return convHadronTypeToOrig(pType, ancestorPDG);
553 }

◆ defOrigOfMuon()

ParticleOrigin MCTruthClassifier::defOrigOfMuon ( const xAOD::TruthParticleContainer xTruthParticleContainer,
const xAOD::TruthParticle thePart,
bool &  isPrompt,
MCTruthPartClassifier::Info info 
) const
private

Definition at line 556 of file MCTruthClassifierGen.cxx.

560 {
561  ATH_MSG_DEBUG("Executing DefOrigOfMuon ");
562 
563  // Find the first copy of this particle stored in the xAOD::TruthParticleContainer (i.e. the particle prior to any interactions)
564  const xAOD::TruthParticle* thePriPart = MC::findMatching(xTruthParticleContainer, thePart);
565  if (!thePriPart) return NonDefined;
566  if (!MC::isMuon(thePriPart)) return NonDefined;
567 
568  //-- to define muon outcome status
569  info.particleOutCome = defOutComeOfMuon(thePriPart);
570 
571  const xAOD::TruthVertex* partProdVtx = thePriPart->hasProdVtx() ? thePriPart->prodVtx() : nullptr;
572  if (!partProdVtx) return NonDefined;
573 
574  if (partProdVtx->nIncomingParticles() > 1) ATH_MSG_DEBUG("DefOrigOfMuon:: muon has more than one parent.");
575 
576  const xAOD::TruthParticle* ancestor = MC::findMother(thePriPart);
577  info.setMotherProperties(ancestor);
578  if (!ancestor) { return NonDefined; } // ancestor is not a nullptr beyond this point
579 
580  // "method 1" for finding Sherpa loops from defOrigOfElectron not used here. Why?
581 
582  if ((MC::isTau(ancestor)|| MC::isW(ancestor)) && ancestor->hasProdVtx()) {
583  int pPDG(0);
584  const xAOD::TruthParticle* ancestorParent{};
585  do {
586  pPDG = 0;
587  ancestorParent = MC::findMother(ancestor);
588  // Start of method 2 of protecting against loops
589  // to prevent Sherpa loop
590  if (ancestor == ancestorParent) { break; }
591  if (TruthLoopDetectionMethod2(ancestor,ancestorParent)) {
592  ancestorParent = ancestor;
593  break;
594  }
595  // End of method 2 of protecting against loops
596 
597  if (ancestorParent) {
598  pPDG = ancestorParent->pdgId();// Only set pPDG in the case that we aren't in a loop.
599  if (MC::isMuon(pPDG) || MC::isTau(pPDG) || MC::isW(pPDG)) { // FIXME should this be (MC::isTau(pPDG) || MC::isW(pPDG)) ???
600  // There will be another iteration so set ancestor to ancestorParent
601  ancestor = ancestorParent; // ancestorParent is not nullptr here
602  }
603  }
604  } while ((MC::isMuon(pPDG) || MC::isTau(pPDG) || MC::isW(pPDG))); // FIXME should this be (MC::isTau(pPDG) || MC::isW(pPDG)) ???
605 
606  if (MC::isTau(pPDG) || MC::isW(pPDG) || MC::isZ(pPDG) || MC::isHiggs(pPDG) ||
607  MC::isMSSMHiggs(pPDG) || MC::isHeavyBoson(pPDG) || MC::isTop(pPDG) || // MSSM Higgs bosons, Heavy bosons( Z', Z'', W'+)
608  std::abs(pPDG) == MC::WBOSON_LRSM || MC::isNeutrinoRH(pPDG) || // Left-right symmetric model WBoson || Right-handed neutrino (Pythia-specific)
609  MC::isSUSY(pPDG)) {
610  ancestor = ancestorParent; // ancestorParent is not nullptr here
611  }
612  }
613 
614  info.setMotherProperties(ancestor);
615  const int ancestorPDG = ancestor->pdgId();
616  const xAOD::TruthVertex* ancestorProdVtx = ancestor->hasProdVtx() ? ancestor->prodVtx() : nullptr;
617  partProdVtx = ancestor->decayVtx();
618  const int numOfParents = partProdVtx->nIncomingParticles();
619  const int numberOfChildren = partProdVtx->nOutgoingParticles();
620 
621  // Determine decay products
622  auto DP = DecayProducts(partProdVtx);
623  const int NumOfPhot = DP.pd(MC::PHOTON);
624  const int NumOfEl = DP.pd(MC::ELECTRON);
625  const int NumOfPos = DP.pd(MC::POSITRON);
626  const int NumOfElNeut = DP.apd(MC::NU_E);
627  const int NumOfMuNeut = DP.apd(MC::NU_MU);
628  const int NumOfLQ = DP.apd(MC::LEPTOQUARK);
629  const int NumOfquark = DP.apd({MC::DQUARK,MC::UQUARK,MC::SQUARK,MC::CQUARK,MC::BQUARK,MC::TQUARK});
630  const int NumOfgluon = DP.apd(MC::GLUON);
631  const int NumOfMuPl = DP.pd(-MC::MUON);
632  const int NumOfMuMin = DP.pd(MC::MUON);
633  const int NumOfTau = DP.apd(MC::TAU);
634  const int NumOfTauNeut = DP.apd(MC::NU_TAU);
635  // End of section determining decay products
636 
637  if (std::abs(ancestorPDG) == MC::PIPLUS && numberOfChildren == 2 && NumOfMuNeut == 1) return PionDecay;
638  if (std::abs(ancestorPDG) == MC::KPLUS && numberOfChildren == 2 && NumOfMuNeut == 1) return KaonDecay;
639  if (MC::isTau(ancestorPDG)) {
640  const ParticleOrigin tauOrig = defOrigOfTau(xTruthParticleContainer, ancestor, ancestorPDG, info);
641  const ParticleType tautype = defTypeOfTau(tauOrig);
642  return (tautype == IsoTau)?tauOrig:TauLep;
643  }
644 
645  if (MC::isTop(ancestorPDG)) return top;
646  // Quark weak decay
647  if (MC::isSMQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && NumOfMuNeut == 1) return QuarkWeakDec;
648 
649  if (MC::isW(ancestorPDG) && ancestorProdVtx && ancestorProdVtx->nIncomingParticles() != 0) {
650  const xAOD::TruthVertex* prodVert = ancestorProdVtx;
651  const xAOD::TruthParticle* itrP;
652  do {
653  itrP = prodVert->incomingParticle(0); // FIXME just taking the first one
654  prodVert = itrP->hasProdVtx() ? itrP->prodVtx() : nullptr;
655  } while (MC::isW(itrP) && prodVert);
656 
657  if (prodVert && prodVert->nIncomingParticles() == 1) {
658  if (std::abs(itrP->pdgId()) == MC::RH_NU_E) return NuREle; // Right-handed NU_E (Pythia-specific)
659  if (std::abs(itrP->pdgId()) == MC::RH_NU_MU) return NuRMu; // Right-handed NU_MU (Pythia-specific)
660  if (std::abs(itrP->pdgId()) == MC::RH_NU_TAU) return NuRTau; // Right-handed NU_TAU (Pythia-specific)
661  }
662  return WBoson;
663  }
664  if (MC::isW(ancestorPDG)) return WBoson;
665  if (MC::isZ(ancestorPDG)) return ZBoson;
666  if (MC::isPhoton(ancestorPDG) && numberOfChildren == 2 && NumOfMuMin == 1 && NumOfMuPl == 1) return PhotonConv;
667  //-- Exotics
668 
669  // MadGraphPythia ZWW*->lllnulnu
670  if (numOfParents == 1 && numberOfChildren > 4 && (MC::isSMQuark(ancestorPDG) || MC::isGluon(ancestorPDG))) {
671  bool isZboson = false;
672  bool isWboson = false;
673  bool skipnext = false;
674  for (unsigned int ipOut = 0; ipOut + 1 < partProdVtx->nOutgoingParticles(); ipOut++) {
675  if (skipnext) {
676  skipnext = false;
677  continue;
678  }
679  const xAOD::TruthParticle* aChild = partProdVtx->outgoingParticle(ipOut);
680  if (!aChild) continue;
681  const xAOD::TruthParticle* theNextChild{};
682  for (unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->nOutgoingParticles(); ipOut1++) {
683  theNextChild = partProdVtx->outgoingParticle(ipOut1);
684  if (theNextChild) break;
685  }
686  if (!theNextChild) continue;
687  if (MC::isMuon(aChild) && MC::isMuon(theNextChild)) {
688  // Zboson
689  if (thePriPart == aChild || thePriPart == theNextChild) {
690  isZboson = true;
691  break;
692  }
693  skipnext = true;
694  } else if (MC::isMuon(aChild) && std::abs(theNextChild->pdgId()) == MC::NU_MU) {
695  // WBoson
696  if (thePriPart == aChild || thePriPart == theNextChild) {
697  isWboson = true;
698  break;
699  }
700  skipnext = true;
701  }
702  }
703  if (isWboson) return WBoson;
704  if (isZboson) return ZBoson;
705  }
706  if (numOfParents == 2 ) {
707  //--Sherpa Z->mumu
708  if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfMuPl == 1 && NumOfMuMin == 1) return ZBoson;
709 
710  //--Sherpa W->munu ??
711  // if(numOfParents==2&&(numberOfChildren-NumOfquark-NumOfgluon)==2&&(NumOfEl==1||NumOfPos==1)&&NumOfElNeut==1) return WBoson;
712  if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfMuPl == 1 || NumOfMuMin == 1) && NumOfMuNeut == 1) return WBoson;
713 
714  const int pdg1 = partProdVtx->incomingParticle(0)->pdgId();
715  const int pdg2 = partProdVtx->incomingParticle(1)->pdgId();
716  //--Sherpa ZZ,ZW
717  if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
718  (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
719  (MC::isQuark(pdg1)||MC::isGluon(pdg1)) && (MC::isQuark(pdg2)||MC::isGluon(pdg2))) return DiBoson;
720 
721  //--Sherpa VVV -- Note, have to allow for prompt photon radiation or these get lost
722  if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
723  (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
724  (MC::isQuark(pdg1)||MC::isGluon(pdg1)) && (MC::isQuark(pdg2)||MC::isGluon(pdg2))) return MultiBoson;
725  }
726 
727  //--New Sherpa Z->mumu
728  if (partProdVtx == ancestorProdVtx) {
729  int NumOfMuLoop = 0;
730  int NumOfMuNeuLoop = 0;
731  int NumOfLepLoop = 0;
732  for (const auto & pout: partProdVtx->particles_out()) {
733  if (!pout) continue;
734  for (const auto & pin: partProdVtx->particles_in()) {
735  if (!pin) continue;
736  if (HepMC::is_same_particle(pout,pin)) {
737  if (MC::isMuon(pout)) NumOfMuLoop++;
738  if (std::abs(pout->pdg_id()) == MC::NU_MU) NumOfMuNeuLoop++;
739  if (MC::isSMLepton(pout)) NumOfLepLoop++;
740  break; // break out of inner loop after having found two matching particles
741  }
742  }
743  }
744  if (NumOfMuLoop == 2 && NumOfMuNeuLoop == 0) return ZBoson;
745  if (NumOfMuLoop == 1 && NumOfMuNeuLoop == 1) return WBoson;
746  if ((NumOfMuLoop == 4 && NumOfMuNeuLoop == 0) || (NumOfMuLoop == 3 && NumOfMuNeuLoop == 1) ||
747  (NumOfMuLoop == 2 && NumOfMuNeuLoop == 2)) return DiBoson;
748  if (NumOfLepLoop == 4) return DiBoson;
749  }
750 
751  //-- McAtNLo
752 
753  if (MC::isHiggs(ancestorPDG)) return Higgs;
754 
755  if (MC::isMSSMHiggs(ancestorPDG)) return HiggsMSSM; // MSSM Higgs bosons
756 
757  if (MC::isHeavyBoson(ancestorPDG)) return HeavyBoson; // Heavy bosons( Z', Z'', W'+)
758 
759  if (std::abs(ancestorPDG) == MC::WBOSON_LRSM) return WBosonLRSM; // Left-right symmetric model WBoson (Pythia-specific)
760  if (std::abs(ancestorPDG) == MC::RH_NU_E) return NuREle; // Right-handed NU_E (Pythia-specific)
761  if (std::abs(ancestorPDG) == MC::RH_NU_MU) return NuRMu; // Right-handed NU_MU (Pythia-specific)
762  if (std::abs(ancestorPDG) == MC::RH_NU_TAU) return NuRTau; // Right-handed NU_TAU (Pythia-specific)
763  if (MC::isLeptoQuark(ancestorPDG) || NumOfLQ != 0) return LQ;
764  if (MC::isSUSY(ancestorPDG)) return SUSY;
765  if (MC::isBSM(ancestorPDG)) return OtherBSM;
766 
767  const ParticleType pType = defTypeOfHadron(ancestorPDG);
768  if ((pType == BBbarMesonPart || pType == CCbarMesonPart) && ancestorProdVtx && MC::isHardScatteringVertex(ancestorProdVtx)) isPrompt = true;
769 
770  return convHadronTypeToOrig(pType, ancestorPDG);
771 }

◆ defOrigOfNeutrino()

ParticleOrigin MCTruthClassifier::defOrigOfNeutrino ( const xAOD::TruthParticleContainer xTruthParticleContainer,
const xAOD::TruthParticle thePart,
bool &  isPrompt,
MCTruthPartClassifier::Info info 
) const
private

Definition at line 1210 of file MCTruthClassifierGen.cxx.

1214 {
1215  ATH_MSG_DEBUG("Executing DefOrigOfNeutrino ");
1216 
1217  const int nuFlav = std::abs(thePart->pdgId());
1218  // Find the first copy of this particle stored in the xAOD::TruthParticleContainer (i.e. the particle prior to any interactions)
1219  const xAOD::TruthParticle* thePriPart = MC::findMatching(xTruthParticleContainer, thePart);
1220  if (!thePriPart) return NonDefined;
1221  if (std::abs(thePriPart->pdgId()) != nuFlav) return NonDefined; // FIXME should this be if (!MC::isSMNeutrino(thePriPart) || abs(thePriPart->pdgId()) != nuFlav) return NonDefined; // (Use MC::isNeutrino if 4th generation neutrinos OK)
1222 
1223  //-- to define neutrino outcome status
1224  info.particleOutCome = NonInteract;
1225 
1226  const xAOD::TruthVertex* partProdVtx = thePriPart->hasProdVtx() ? thePriPart->prodVtx() : nullptr;
1227  if (!partProdVtx) return NonDefined;
1228 
1229  if (partProdVtx->nIncomingParticles() > 1) ATH_MSG_DEBUG("DefOrigOfNeutrino:: neutrino has more than one parent.");
1230 
1231  const xAOD::TruthParticle* ancestor = MC::findMother(thePriPart);
1232  info.setMotherProperties(ancestor);
1233  if (!ancestor) { return NonDefined; } // ancestor is not a nullptr beyond this point
1234 
1235  // Start of method 3 of protecting against loops
1236  // to resolve Sherpa loop
1237  bool samePart = TruthLoopDetectionMethod1(partProdVtx, ancestor);
1238  // End of method 3 of protecting against loops
1239 
1240  if ((std::abs(ancestor->pdgId()) == nuFlav || MC::isTau(ancestor) || MC::isW(ancestor)) && ancestor->hasProdVtx() && !samePart) {
1241  int pPDG(0);
1242  const xAOD::TruthParticle* ancestorParent{};
1243  do {
1244  pPDG = 0;
1245  ancestorParent = MC::findMother(ancestor);
1246  // Start of method 2 of protecting against loops
1247  // to prevent Sherpa loop
1248  if (TruthLoopDetectionMethod2(ancestor,ancestorParent)) {
1249  ancestorParent = ancestor;
1250  break;
1251  }
1252  //
1253  if (ancestorParent) {
1254  pPDG = ancestorParent->pdgId(); // FIXME difference in behaviour compared to defOrigOfElectron/Muon pPDG set even if we are in a loop
1255  }
1256  // to prevent Sherpa loop
1257  if (ancestor == ancestorParent) { break; }
1258  // End of method 2 of protecting against Sherpa loops
1259  if (std::abs(pPDG) == nuFlav || MC::isTau(pPDG) || MC::isW(pPDG) ) {
1260  // There will be another iteration so set ancestor to ancestorParent
1261  ancestor = ancestorParent; // ancestorParent is not a nullptr
1262  info.setMotherProperties(ancestor); // FIXME difference in behaviour compared to MCTruthClassifier::defOrigOfElectron/Muon
1263  }
1264 
1265  } while ((std::abs(pPDG) == nuFlav || MC::isTau(pPDG) || MC::isW(pPDG)));
1266 
1267  if (std::abs(pPDG) == nuFlav || MC::isTau(pPDG) || MC::isW(pPDG) || MC::isZ(pPDG) || MC::isHiggs(pPDG) ||
1268  MC::isMSSMHiggs(pPDG) || MC::isHeavyBoson(pPDG) || MC::isTop(pPDG) || // MSSM Higgs bosons, Heavy bosons( Z', Z'', W'+)
1269  std::abs(pPDG) == MC::WBOSON_LRSM || MC::isNeutrinoRH(pPDG) || // Left-right symmetric model WBoson || Right-handed neutrino (Pythia-specific)
1270  MC::isSUSY(pPDG)) {
1271  ancestor = ancestorParent; // ancestorParent is not nullptr here
1272  info.setMotherProperties(ancestor);
1273  }
1274  }
1275  //if ancestor is still nullptr, we have a problem
1276  if (!ancestor) return NonDefined; // FIXME it should not be possible for ancestor to be nullptr at this point???
1277 
1278  info.setMotherProperties(ancestor);
1279  const int ancestorPDG = ancestor->pdgId();
1280  partProdVtx = ancestor->decayVtx();
1281  const xAOD::TruthVertex* ancestorProdVtx = ancestor->hasProdVtx() ? ancestor->prodVtx() : nullptr;
1282  const int numOfParents = partProdVtx->nIncomingParticles();
1283  const int numberOfChildren = partProdVtx->nOutgoingParticles();
1284 
1285  // Determine decay products
1286  auto DP = DecayProducts(partProdVtx);
1287  const int NumOfPhot = DP.pd(MC::PHOTON);
1288  const int NumOfquark = DP.apd({MC::DQUARK,MC::UQUARK,MC::SQUARK,MC::CQUARK,MC::BQUARK,MC::TQUARK});
1289  const int NumOfgluon = DP.apd(MC::GLUON);
1290  const int NumOfLQ = DP.apd(MC::LEPTOQUARK);
1291  const int NumOfElNeut = DP.apd(MC::NU_E);
1292  const int NumOfMuNeut = DP.apd(MC::NU_MU);
1293  const int NumOfTauNeut = DP.apd(MC::NU_TAU);
1294  const int NumOfEl = DP.apd(MC::ELECTRON);
1295  const int NumOfMu = DP.apd(MC::MUON);
1296  const int NumOfTau = DP.apd(MC::TAU);
1297 
1298  samePart = false;
1299  for (const auto& aChild: partProdVtx->particles_out()) {
1300  if (!aChild) continue;
1301  if (aChild->pdgId() == ancestorPDG && HepMC::is_same_generator_particle(aChild,ancestor)) {
1302  samePart = true;
1303  break;
1304  }
1305  }
1306  // End of section determining decay products
1307 
1308  // Quark weak decay
1309  if (MC::isQuark(ancestorPDG) && numOfParents == 1 && numberOfChildren == 3 && NumOfquark == 1 && (NumOfEl == 1 || NumOfMu == 1 || NumOfTau == 1)) return QuarkWeakDec;
1310  if (MC::isTop(ancestorPDG)) return top;
1311 
1312  if (MC::isW(ancestorPDG) && ancestorProdVtx && ancestorProdVtx->nIncomingParticles() != 0) {
1313  const xAOD::TruthVertex* prodVert = ancestorProdVtx;
1314  const xAOD::TruthParticle* ptrPart;
1315  do {
1316  ptrPart = prodVert->incomingParticle(0); // FIXME just taking the first one
1317  prodVert = ptrPart->hasProdVtx() ? ptrPart->prodVtx() : nullptr;
1318  } while (MC::isW(ptrPart) && prodVert);
1319 
1320  if (prodVert && prodVert->nIncomingParticles() == 1) {
1321  if (std::abs(ptrPart->pdgId()) == MC::RH_NU_E) return NuREle; // Right-handed NU_E (Pythia-specific)
1322  if (std::abs(ptrPart->pdgId()) == MC::RH_NU_MU) return NuRMu; // Right-handed NU_MU (Pythia-specific)
1323  if (std::abs(ptrPart->pdgId()) == MC::RH_NU_TAU) return NuRTau; // Right-handed NU_TAU (Pythia-specific)
1324  }
1325  return WBoson;
1326  }
1327  if (MC::isW(ancestorPDG)) return WBoson;
1328  if (MC::isZ(ancestorPDG)) return ZBoson;
1329 
1330  //-- Exotics
1331 
1332  // MadGraphPythia ZWW*->lllnulnu or ZWW*->nunulnulnu (don't even know if the latter is generated)
1333  if (numOfParents == 1 && numberOfChildren > 4 && (MC::isSMQuark(ancestorPDG) || MC::isGluon(ancestorPDG))) {
1334 
1335  const xAOD::TruthParticle* thePartToCheck = thePriPart;
1336  const xAOD::TruthParticle* theParent = thePriPart->hasProdVtx() ? thePriPart->prodVtx()->incomingParticle(0) : nullptr; // FIXME just taking the first one
1337 
1338  if (MC::isElectron(theParent) && MC::isDecayed(theParent)) { thePartToCheck = theParent; }
1339  bool isZboson = false;
1340  bool isWboson = false;
1341  bool skipnext = false;
1342 
1343  for (unsigned int ipOut = 0; ipOut + 1 < partProdVtx->nOutgoingParticles(); ++ipOut) {
1344  const xAOD::TruthParticle* aChild = partProdVtx->outgoingParticle(ipOut);
1345  if (!aChild) continue;
1346  const xAOD::TruthParticle* theNextChild{};
1347  for (unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->nOutgoingParticles(); ipOut1++) {
1348  theNextChild = partProdVtx->outgoingParticle(ipOut1);
1349  if (theNextChild) break;
1350  }
1351  if (!theNextChild) continue;
1352 
1353  if (skipnext) {
1354  skipnext = false;
1355  continue;
1356  }
1357 
1358  const int apdgID1 = std::abs(aChild->pdgId());
1359  const int apdgID2 = std::abs(theNextChild->pdgId());
1360  if (apdgID1 == apdgID2 && MC::isSMNeutrino(apdgID1)) {
1361  // Zboson
1362  if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
1363  isZboson = true;
1364  break;
1365  }
1366  skipnext = true;
1367  } else if ((apdgID1 == MC::ELECTRON && apdgID2 == MC::NU_E) ||
1368  (apdgID1 == MC::NU_E && apdgID2 == MC::ELECTRON) ||
1369  (apdgID1 == MC::MUON && apdgID2 == MC::NU_MU) ||
1370  (apdgID1 == MC::NU_MU && apdgID2 == MC::MUON) ||
1371  (apdgID1 == MC::TAU && apdgID2 == MC::NU_TAU) ||
1372  (apdgID1 == MC::NU_TAU && apdgID2 == MC::TAU)
1373  ) {
1374  // WBoson
1375  if (thePartToCheck == aChild || thePartToCheck == theNextChild) {
1376  isWboson = true;
1377  break;
1378  }
1379  skipnext = true;
1380  }
1381  }
1382  if (isWboson) return WBoson;
1383  if (isZboson) return ZBoson;
1384  }
1385 
1386  if (numOfParents == 2) {
1387  //--Sherpa Z->nunu
1388  if ( (numberOfChildren - NumOfquark - NumOfgluon) == 2 && (NumOfElNeut == 2 || NumOfMuNeut == 2 || NumOfTauNeut == 2)) return ZBoson;
1389 
1390  //--Sherpa W->enu ??
1391  if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && ((NumOfEl == 1 && NumOfElNeut == 1) || (NumOfMu == 1 && NumOfMuNeut == 1) || (NumOfTau == 1 && NumOfTauNeut == 1))) return WBoson;
1392 
1393  const int pdg1 = partProdVtx->incomingParticle(0)->pdgId();
1394  const int pdg2 = partProdVtx->incomingParticle(1)->pdgId();
1395  //--Sherpa ZZ,ZW
1396  if ( (numberOfChildren - NumOfquark - NumOfgluon) == 4 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
1397  (MC::isQuark(pdg1)||MC::isGluon(pdg1)) && (MC::isQuark(pdg2)||MC::isGluon(pdg2))) return DiBoson;
1398 
1399  //--Sherpa VVV -- Note, have to allow for prompt photon radiation or these get lost
1400  if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 && (NumOfEl + NumOfMu + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
1401  (MC::isQuark(pdg1)||MC::isGluon(pdg1)) && (MC::isQuark(pdg2)||MC::isGluon(pdg2))) return MultiBoson;
1402  }
1403 
1404  // New Sherpa Z->nunu
1405  if (partProdVtx == ancestorProdVtx) {
1406  int NumOfLepLoop = 0;
1407  int NumOfNeuLoop = 0;
1408  for (const auto *const pout: partProdVtx->particles_out()) {
1409  if (!pout) continue;
1410  for (const auto *const pin: partProdVtx->particles_in()) {
1411  if (!pin) continue;
1412  if (HepMC::is_same_particle(pin,pout)) continue;
1413  const int apdgid = std::abs(pout->pdgId());
1414  if (MC::isSMLepton(apdgid)) {
1415  if (MC::isSMNeutrino(apdgid)) { NumOfNeuLoop++; }
1416  else { NumOfLepLoop++; }
1417  }
1418  break; // break out of inner loop after having found two matching particles
1419  }
1420  }
1421  if (NumOfNeuLoop == 2 && NumOfLepLoop == 0) return ZBoson;
1422  if (NumOfNeuLoop == 1 && NumOfLepLoop == 1) return WBoson;
1423  if (NumOfNeuLoop + NumOfLepLoop == 4) return DiBoson;
1424  }
1425 
1426  //-- McAtNLo
1427 
1428  if (MC::isHiggs(ancestorPDG)) return Higgs;
1429  if (MC::isMSSMHiggs(ancestorPDG)) return HiggsMSSM; // MSSM Higgs bosons
1430  if (MC::isHeavyBoson(ancestorPDG)) return HeavyBoson; // Heavy bosons( Z', Z'', W'+)
1431 
1432  if (MC::isTau(ancestorPDG)) {
1433  const ParticleOrigin tauOrig = defOrigOfTau(xTruthParticleContainer, ancestor, ancestorPDG, info);
1434  const ParticleType tautype = defTypeOfTau(tauOrig);
1435  return (tautype == IsoTau)?tauOrig:TauLep;
1436  }
1437 
1438  if (std::abs(ancestorPDG) == MC::WBOSON_LRSM) return WBosonLRSM; // Left-right symmetric model WBoson (Pythia-specific)
1439  if (std::abs(ancestorPDG) == MC::RH_NU_E) return NuREle; // Right-handed NU_E (Pythia-specific)
1440  if (std::abs(ancestorPDG) == MC::RH_NU_MU) return NuRMu; // Right-handed NU_MU (Pythia-specific)
1441  if (std::abs(ancestorPDG) == MC::RH_NU_TAU) return NuRTau; // Right-handed NU_TAU (Pythia-specific)
1442  if (MC::isLeptoQuark(ancestorPDG) || NumOfLQ != 0) return LQ;
1443  if (MC::isSUSY(ancestorPDG)) return SUSY;
1444  if (MC::isBSM(ancestorPDG)) return OtherBSM;
1445 
1446  const ParticleType pType = defTypeOfHadron(ancestorPDG);
1447  if ((pType == BBbarMesonPart || pType == CCbarMesonPart) && ancestorProdVtx && MC::isHardScatteringVertex(ancestorProdVtx)) isPrompt = true;
1448 
1449  return convHadronTypeToOrig(pType, ancestorPDG);
1450 }

◆ defOrigOfPhoton()

ParticleOrigin MCTruthClassifier::defOrigOfPhoton ( const xAOD::TruthParticleContainer xTruthParticleContainer,
const xAOD::TruthParticle thePart,
bool &  isPrompt,
MCTruthPartClassifier::Info info 
) const
private

Definition at line 947 of file MCTruthClassifierGen.cxx.

951 {
952  if (!thePart) return NonDefined; // FIXME Why is this extra protection needed for this function and not the others?
953  ATH_MSG_DEBUG("Executing DefOrigOfPhoton ");
954 
955  info.resetMotherProperties();
956  info.photonMother = nullptr;
957 
958  // Find the first copy of this particle stored in the xAOD::TruthParticleContainer (i.e. the particle prior to any interactions)
959  const xAOD::TruthParticle* thePriPart = MC::findMatching(xTruthParticleContainer, thePart);
960  if (!thePriPart) return NonDefined;
961  if (!MC::isPhoton(thePriPart)) return NonDefined;
962 
963  const xAOD::TruthVertex* partProdVtx = thePriPart->hasProdVtx() ? thePriPart->prodVtx() : nullptr;
964 
965  //-- to define photon outcome status
966  info.particleOutCome = defOutComeOfPhoton(thePriPart);
967 
968  if (!partProdVtx) return NonDefined;
969 
970  int numOfParents = partProdVtx->nIncomingParticles();
971  if (partProdVtx->nIncomingParticles() > 1) ATH_MSG_DEBUG("DefOrigOfPhoton:: photon has more than one parent.");
972 
973  const xAOD::TruthParticle* ancestor = MC::findMother(thePriPart);
974  info.setMotherProperties(ancestor);
975  if (!ancestor) { return NonDefined; } // ancestor is not a nullptr beyond this point
976 
977  int ancestorPDG = ancestor->pdgId();
978  // "method 1" for finding Sherpa loops from defOrigOfElectron not used here. Why?
979  const xAOD::TruthVertex* ancestorProdVtx = ancestor->hasProdVtx() ? ancestor->prodVtx() : nullptr;
980 
981  partProdVtx = ancestor->decayVtx(); // FIXME how often does this line actually change the pointer???
982  numOfParents = partProdVtx->nIncomingParticles();
983 
984  const int numberOfChildren = partProdVtx->nOutgoingParticles();
985 
986  // Determine decay products
987  auto DP = DecayProducts(partProdVtx);
988  const int NumOfEl = DP.pd(MC::ELECTRON);
989  const int NumOfPos = DP.pd(MC::POSITRON);
990  const int NumOfMu = DP.apd(MC::MUON);
991  const int NumOfTau = DP.apd(MC::TAU);
992  const int NumOfLQ = DP.apd(MC::LEPTOQUARK);
993  const int NumOfLep = NumOfEl + NumOfPos + NumOfMu + NumOfTau;
994  const int NumOfNeut = DP.apd({MC::NU_E,MC::NU_MU,MC::NU_TAU});
995  const int NumOfPht = DP.pd(MC::PHOTON);
996 
997  int childPDG(0);
998  int NumOfPartons(0);
999  int NumOfNucFr(0);
1000  const bool possibleNuclearFragment = (numOfParents == 1 && (MC::isPhoton(ancestorPDG) || MC::isElectron(ancestorPDG) || std::abs(ancestorPDG) == MC::PIPLUS));
1001  const xAOD::TruthParticle* child{};
1002  for (const auto& pout: partProdVtx->particles_out()) {
1003  if (!pout) continue;
1004  childPDG = pout->pdg_id();
1005  if (possibleNuclearFragment &&
1006  (MC::isNucleus(childPDG) || childPDG == 0 || childPDG == MC::PROTON || childPDG == MC::NEUTRON)) { // FIXME Do we really expect particles with PDG_ID = 0 in the truth record?
1007  NumOfNucFr++;
1008  }
1009  if (std::abs(childPDG) < MC::ELECTRON ||
1010  (std::abs(childPDG) > MC::NU_TAU && std::abs(childPDG) < 43 && !MC::isPhoton(childPDG))) {
1011  // FIXME Too loose? This definition picks up 4th generation quarks and leptons as well as all gauge bosons and leptoquarks.
1012  // Suggest MC::isSMQuark(childPDG) || (MC::isBoson(childPDG) && !MC::isPhoton(childPDG))
1013  // or maybe even MC::isSMQuark(childPDG) || MC::isGluon(childPDG)
1014  // AKA const int NumOfPartons = DP.apd({MC::DQUARK,MC::UQUARK,MC::SQUARK,MC::CQUARK,MC::BQUARK,MC::TQUARK,MC::GLUON});
1015  NumOfPartons++;
1016  }
1017  if (childPDG == ancestorPDG) {
1018  child = pout;
1019  }
1020  }
1021  // End of section determining decay products
1022 
1023  bool foundISR = false;
1024  bool foundFSR = false;
1025  if (numOfParents == 1 && numberOfChildren == 2 && child && HepMC::is_same_generator_particle(child, ancestor)) return BremPhot;
1026  if (numOfParents == 1 && numberOfChildren == 2 && MC::isElectron(ancestorPDG) && NumOfPht == 2) return ElMagProc;
1027 
1028  // decay of W,Z and Higgs to lepton with FSR generated by Pythia
1029  if (numOfParents == 1 && numberOfChildren == 2 && (MC::isElectron(ancestorPDG) || MC::isMuon(ancestorPDG) || MC::isTau(ancestorPDG)) &&
1030  !(child && HepMC::is_same_generator_particle(child, ancestor)) && ancestorProdVtx &&
1031  ancestorProdVtx->nIncomingParticles() == 1) {
1032  int itr = 0;
1033  int PartPDG = 0;
1034  const xAOD::TruthVertex* prodVert = ancestorProdVtx;
1035  const xAOD::TruthVertex* Vert{};
1036  do {
1037  Vert = prodVert;
1038  for (const auto & pin: Vert->particles_in()) {
1039  if (!pin) continue;
1040  PartPDG = std::abs(pin->pdgId());
1041  prodVert = pin->prodVtx();
1042  if (MC::isZ(PartPDG) || MC::isW(PartPDG) || MC::isHiggs(PartPDG)) foundFSR = true;
1043  }
1044  itr++;
1045  if (itr > 100) { // FIXME Improve loop detection here?
1046  ATH_MSG_WARNING("DefOrigOfPhoton:: infinite while");
1047  break;
1048  }
1049  } while (prodVert && std::abs(ancestorPDG) == PartPDG);
1050 
1051  if (foundFSR) return FSRPhot;
1052  }
1053 
1054  // Nucl reaction
1055  // gamma+Nuclear=>gamma+Nucl.Fr+Nuclons+pions
1056  // e+Nuclear=>e+gamma+Nucl.Fr+Nuclons+pions
1057  // pi+Nuclear=>gamma+Nucl.Fr+Nuclons+pions
1058 
1059  if ((numOfParents == 1 && (MC::isPhoton(ancestorPDG) || MC::isElectron(ancestorPDG)) && numberOfChildren > 2 && NumOfNucFr != 0) ||
1060  (numOfParents == 1 && std::abs(ancestorPDG) == MC::PIPLUS && numberOfChildren > 10 && NumOfNucFr != 0) ||
1061  (numOfParents == 1 && MC::isPhoton(ancestorPDG) && numberOfChildren > 10 && MC::isStable(ancestor)) ||
1062  (numOfParents == 1 && MC::isNucleus(ancestorPDG) && std::abs(ancestorPDG) != MC::PROTON)) // FIXME vetoing protons here to preserve previous behaviour
1063  return NucReact;
1064 
1065  if (MC::isMuon(ancestorPDG) && NumOfMu == 0) return Mu;
1066  if (MC::isTau(ancestorPDG) && NumOfTau == 0) return TauLep;
1067 
1068  if (numOfParents == 1 && ancestor->status() == 3) return (foundISR)? ISRPhot:UndrPhot; // FIXME foundISR is always false at this point
1069 
1070  //-- to find initial and final state raiation and underline photons
1071  //-- SUSY
1072  if (numOfParents == 1 && (MC::isSMQuark(ancestorPDG) || MC::isGluon(ancestorPDG)) &&
1073  (numberOfChildren != NumOfPht + NumOfPartons || !MC::Pythia8::isConditionA(ancestor))) {
1074  for (const auto& pout: partProdVtx->particles_out()) {
1075  if (!pout) continue;
1076  if (ancestorPDG != pout->pdgId()) continue;
1077  const xAOD::TruthVertex* Vrtx = pout->decayVtx();
1078  if (!Vrtx) continue;
1079  if (Vrtx->nOutgoingParticles() != 1 && Vrtx->nIncomingParticles() == 1) continue;
1080  if (!Vrtx->outgoingParticle(0)) continue;
1081  if (Vrtx->outgoingParticle(0)->pdgId() == 91) foundISR = true; // Herwig "cluster"
1082  }
1083  return (foundISR)?ISRPhot:UndrPhot;
1084  }
1085 
1086  //-- to find final state radiation
1087  //-- Exotics
1088 
1089  // FSR from Photos
1090  //-- Exotics- CompHep
1091  if (numOfParents == 2 && ((MC::isElectron(ancestorPDG) && NumOfEl == 1 && NumOfPos == 1) || (MC::isMuon(ancestorPDG) && NumOfMu == 2) || (MC::isTau(ancestorPDG) && NumOfTau == 2))) {
1092  if (std::abs(partProdVtx->incomingParticle(0)->pdgId()) == std::abs(partProdVtx->incomingParticle(1)->pdgId())) return FSRPhot;
1093  }
1094 
1095  if (numOfParents == 2 && NumOfLep == 1 && NumOfNeut == 1 && (MC::isElectron(ancestorPDG) || std::abs(ancestorPDG) == MC::NU_E)) return FSRPhot;
1096 
1097  //-- Exotics - CompHep
1098  if (MC::isElectron(ancestorPDG) && numOfParents == 1 && numberOfChildren == 2 && (NumOfEl == 1 || NumOfPos == 1) && NumOfPht == 1 &&
1099  !( child && HepMC::is_same_generator_particle(child, ancestor)) && !HepMC::is_simulation_particle(child) && !HepMC::is_simulation_particle(ancestor))
1100  return FSRPhot;
1101 
1102  // FSR from Photos
1103  if (MC::isZ(ancestorPDG) && ((NumOfEl + NumOfPos == 2 || NumOfEl + NumOfPos == 4) || (NumOfMu == 2 || NumOfMu == 4) || (NumOfTau == 2 || NumOfTau == 4)) && NumOfPht > 0) return FSRPhot;
1104 
1105  if (NumOfPht > 0 && (std::abs(ancestorPDG) == MC::WBOSON_LRSM || MC::isNeutrinoRH(ancestorPDG))) return FSRPhot; // Left-right symmetric model WBoson || Right-handed neutrinos (Pythia-specific)
1106 
1107  if (numOfParents == 2 && NumOfLQ == 1) return FSRPhot;
1108 
1109  //--- other process
1110 
1111  if (MC::isZ(ancestorPDG)) return ZBoson;
1112  if (MC::isW(ancestorPDG)) {
1113 
1114  if (NumOfLep == 1 && NumOfNeut == 1 && numberOfChildren == NumOfLep + NumOfNeut + NumOfPht) return FSRPhot;
1115 
1116  if (ancestorProdVtx && ancestorProdVtx->nIncomingParticles() != 0) {
1117  const xAOD::TruthVertex* prodVert = ancestorProdVtx;
1118  const xAOD::TruthParticle* itrP;
1119  do {
1120  itrP = prodVert->incomingParticle(0); // FIXME just taking the first one
1121  prodVert = itrP->hasProdVtx() ? itrP->prodVtx() : nullptr;
1122  } while (MC::isW(itrP) && prodVert);
1123 
1124  if (prodVert && prodVert->nIncomingParticles() == 1 ) {
1125  if ( MC::isTau(itrP)) return TauLep;
1126  if ( MC::isMuon(itrP)) return Mu;
1127  if ( std::abs(itrP->pdgId()) == MC::RH_NU_E) return NuREle; // Right-handed NU_E (Pythia-specific)
1128  if ( std::abs(itrP->pdgId()) == MC::RH_NU_MU) return NuRMu; // Right-handed NU_MU (Pythia-specific)
1129  if ( std::abs(itrP->pdgId()) == MC::RH_NU_TAU) return NuRTau; // Right-handed NU_TAU (Pythia-specific)
1130  }
1131  } else
1132  return WBoson;
1133  }
1134 
1135  // MadGraphPythia ZWW*->lllnulnu
1136  if (numOfParents == 1 && numberOfChildren > 4 && (MC::isSMQuark(ancestorPDG) || MC::isGluon(ancestorPDG))) {
1137  bool isZboson = false;
1138  bool isWboson = false;
1139  bool skipnext = false;
1140  for (unsigned int ipOut = 0; ipOut + 1 < partProdVtx->nOutgoingParticles(); ipOut++) {
1141  if (skipnext) {
1142  skipnext = false;
1143  continue;
1144  }
1145  const xAOD::TruthParticle* aChild = partProdVtx->outgoingParticle(ipOut);
1146  if (!aChild) continue;
1147  const xAOD::TruthParticle* theNextChild{};
1148  for (unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->nOutgoingParticles(); ipOut1++) {
1149  theNextChild = partProdVtx->outgoingParticle(ipOut1);
1150  if (theNextChild) break;
1151  }
1152  if (!theNextChild) continue;
1153  if (MC::isTau(aChild) && MC::isTau(theNextChild)) {
1154  // Zboson
1155  if (thePriPart == aChild || thePriPart == theNextChild) {
1156  isZboson = true;
1157  break;
1158  }
1159  skipnext = true;
1160  } else if (MC::isTau(aChild) && std::abs(theNextChild->pdgId()) == MC::NU_TAU) {
1161  // WBoson
1162  if (thePriPart == aChild || thePriPart == theNextChild) {
1163  isWboson = true;
1164  break;
1165  }
1166  skipnext = true;
1167  }
1168  }
1169  if (isWboson) return WBoson;
1170  if (isZboson) return ZBoson;
1171  }
1172 
1173  //--Sherpa ZZ,ZW+FSR
1174  if (numOfParents == 4 && (numberOfChildren - NumOfPht) == 4 && (NumOfLep + NumOfNeut == 4)) {
1175  if (MC::isSMLepton(partProdVtx->incomingParticle(0))&&MC::isSMLepton(partProdVtx->incomingParticle(1))
1176  && MC::isSMLepton(partProdVtx->incomingParticle(2))&&MC::isSMLepton(partProdVtx->incomingParticle(3)))
1177  return FSRPhot;
1178  }
1179 
1180  //--New Sherpa single photon
1181  if (partProdVtx == ancestorProdVtx) {
1182  for (const auto *const pout: partProdVtx->particles_out()) {
1183  if (!pout) continue;
1184  for (const auto *const pin: partProdVtx->particles_in()) {
1185  if (!pin) continue;
1186  if (!HepMC::is_same_particle(pout,pin)) continue;
1187  if (MC::isPhoton(pout)) return SinglePhot;
1188  break; // break out of inner loop after having found two matching particles
1189  }
1190  }
1191  }
1192 
1193  if (MC::isHiggs(ancestorPDG)) return Higgs;
1194  if (std::abs(ancestorPDG) == MC::PI0) return PiZero;
1195  if (MC::isMSSMHiggs(ancestorPDG)) return HiggsMSSM; // MSSM Higgs bosons
1196  if (MC::isHeavyBoson(ancestorPDG) || std::abs(ancestorPDG) == 5100039 ) return HeavyBoson; // Heavy Bosons (Z' Z'' W'+) + KK excited graviton
1197 
1198  if (MC::isSUSY(ancestorPDG)) return SUSY;
1199  if (MC::isBSM(ancestorPDG)) return OtherBSM;
1200 
1201  // Pythia8 gamma+jet samples
1202  if (MC::Pythia8::isConditionA(ancestor) && MC::isStable(thePriPart) && NumOfPht == 1 && numberOfChildren == (NumOfPht + NumOfPartons)) return PromptPhot;
1203 
1204  const ParticleType pType = defTypeOfHadron(ancestorPDG);
1205  if ((pType == BBbarMesonPart || pType == CCbarMesonPart) && ancestorProdVtx && MC::isHardScatteringVertex(ancestorProdVtx)) isPrompt = true;
1206  return convHadronTypeToOrig(pType, ancestorPDG);
1207 }

◆ defOrigOfTau()

ParticleOrigin MCTruthClassifier::defOrigOfTau ( const xAOD::TruthParticleContainer xTruthParticleContainer,
const xAOD::TruthParticle thePart,
int  motherPDG,
MCTruthPartClassifier::Info info 
) const
private

Definition at line 774 of file MCTruthClassifierGen.cxx.

778 {
779  ATH_MSG_DEBUG("Executing DefOrigOfTau ");
780 
781  // Find the first copy of this particle stored in the xAOD::TruthParticleContainer (i.e. the particle prior to any interactions)
782  const xAOD::TruthParticle* thePriPart = MC::findMatching(xTruthParticleContainer, thePart);
783  if (!thePriPart) return NonDefined;
784  if (!MC::isTau(thePriPart)) return NonDefined;
785 
786  //-- to define tau outcome status
787  if (MC::isPhysical(thePriPart)) info.particleOutCome = defOutComeOfTau(thePriPart); // FIXME why do we need the additional check on MC::isPhysical here c.f. defOrigOfElectron and defOrigOfMuon?
788 
789  const xAOD::TruthVertex* partProdVtx = thePriPart->hasProdVtx() ? thePriPart->prodVtx() : nullptr;
790  if (!partProdVtx) return NonDefined;
791 
792  if (partProdVtx->nIncomingParticles() > 1) ATH_MSG_DEBUG("DefOrigOfTau:: tau has more than one parent.");
793 
794  const xAOD::TruthParticle* ancestor = MC::findMother(thePriPart);
795  info.setMotherProperties(ancestor);
796  if (!ancestor) { return NonDefined; } // ancestor is not a nullptr beyond this point
797 
798  // "method 1" for finding Sherpa loops from defOrigOfElectron not used here. Why?
799 
800  // Difference from defOrigOfElectron and defOrigOfMuon - no loop through ancestor particles
801 
802  if (MC::isW(ancestorPDGin) && ancestor->hasProdVtx()) { // FIXME ancestorPDGin here could in principle be inconsistent with ancestorProdVtx
803  const xAOD::TruthParticle* ancestorParent = MC::findMother(ancestor);
804  if (ancestorParent && MC::isTop(ancestorParent->pdgId())) {
805  ancestor = ancestorParent; //...so ancestor cannot be nullptr
806  }
807  }
808 
809  const int ancestorPDG = ancestor->pdgId();
810  info.setMotherProperties(ancestor);
811  const xAOD::TruthVertex* ancestorProdVtx = ancestor->hasProdVtx() ? ancestor->prodVtx() : nullptr;
812  partProdVtx = ancestor->decayVtx();
813  if (!partProdVtx) return NonDefined; // FIXME not sure this could ever be true?
814  const int numOfParents = partProdVtx->nIncomingParticles();
815 
816  // Determine decay products
817  auto DP = DecayProducts(partProdVtx);
818  const int numberOfChildren = DP.size();
819  const int NumOfPhot = DP.pd(MC::PHOTON);
820  const int NumOfEl = DP.pd(MC::ELECTRON);
821  const int NumOfPos = DP.pd(MC::POSITRON);
822  const int NumOfElNeut = DP.apd(MC::NU_E);
823  const int NumOfMuNeut = DP.apd(MC::NU_MU);
824  /* const int NumOfLQ = DP.apd(MC::LEPTOQUARK); */ // FIXME Leptoquarks not an option?
825  const int NumOfquark = DP.apd({MC::DQUARK,MC::UQUARK,MC::SQUARK,MC::CQUARK,MC::BQUARK,MC::TQUARK});
826  const int NumOfgluon = DP.apd(MC::GLUON);
827  const int NumOfMuPl = DP.pd(-MC::MUON);
828  const int NumOfMuMin = DP.pd(MC::MUON);
829  const int NumOfTau = DP.apd(MC::TAU);
830  const int NumOfTauNeut = DP.apd(MC::NU_TAU);
831  // End of section determining decay products
832 
833  if (MC::isTop(ancestorPDG)) return top;
834  if (MC::isW(ancestorPDG) && ancestorProdVtx && ancestorProdVtx->nIncomingParticles() != 0) {
835  const xAOD::TruthVertex* prodVert = ancestorProdVtx;
836  const xAOD::TruthParticle* itrP;
837  do {
838  itrP = prodVert->incomingParticle(0); // FIXME just taking the first one
839  prodVert = itrP->hasProdVtx() ? itrP->prodVtx() : nullptr;
840  } while (MC::isW(itrP) && prodVert);
841 
842  if (prodVert && prodVert->nIncomingParticles() == 1 ) {
843  if (std::abs(itrP->pdgId()) == MC::RH_NU_E) return NuREle; // Right-handed NU_E (Pythia-specific)
844  if (std::abs(itrP->pdgId()) == MC::RH_NU_MU) return NuRMu; // Right-handed NU_MU (Pythia-specific)
845  if (std::abs(itrP->pdgId()) == MC::RH_NU_TAU) return NuRTau; // Right-handed NU_TAU (Pythia-specific)
846  }
847  return WBoson;
848  }
849  if (MC::isW(ancestorPDG)) { return WBoson;}
850  if (MC::isZ(ancestorPDG)) { return ZBoson;}
851  if (numOfParents == 1 && numberOfChildren > 4 && (MC::isSMQuark(ancestorPDG) || MC::isGluon(ancestorPDG))) {
852  bool isZboson = false;
853  bool isWboson = false;
854  bool skipnext = false;
855  for (unsigned int ipOut = 0; ipOut + 1 < partProdVtx->nOutgoingParticles(); ipOut++) {
856  if (skipnext) {
857  skipnext = false;
858  continue;
859  }
860  const xAOD::TruthParticle* aChild = partProdVtx->outgoingParticle(ipOut);
861  if (!aChild) continue;
862  const xAOD::TruthParticle* theNextChild{};
863  for (unsigned int ipOut1 = ipOut + 1; ipOut1 < partProdVtx->nOutgoingParticles(); ipOut1++) {
864  theNextChild = partProdVtx->outgoingParticle(ipOut1);
865  if (theNextChild) break;
866  }
867  if (!theNextChild) {
868  continue;
869  }
870  if (MC::isTau(aChild) && MC::isTau(theNextChild)) {
871  // Zboson
872  if (thePriPart == aChild || thePriPart == theNextChild) {
873  isZboson = true;
874  break;
875  }
876  skipnext = true;
877  } else if (MC::isTau(aChild) && std::abs(theNextChild->pdgId()) == MC::NU_TAU) {
878  // WBoson
879  if (thePriPart == aChild || thePriPart == theNextChild) {
880  isWboson = true;
881  break;
882  }
883  skipnext = true;
884  }
885  }
886  if (isWboson) return WBoson;
887  if (isZboson) return ZBoson;
888  }
889  if (numOfParents == 2 ) {
890  const int pdg1 = partProdVtx->incomingParticle(0)->pdgId();
891  const int pdg2 = partProdVtx->incomingParticle(1)->pdgId();
892  //--Sherpa Z->tautau
893  if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfTau == 2 && (MC::isQuark(pdg1)||MC::isGluon(pdg1)) && (MC::isQuark(pdg2)||MC::isGluon(pdg2))) return ZBoson; // FIXME Why the extra checks on incoming particles compared to Z->ee, Z->mumu and Z->nunu?
894 
895  //--Sherpa W->taunu new
896  if ((numberOfChildren - NumOfquark - NumOfgluon) == 2 && NumOfTau == 1 && NumOfTauNeut == 1) return WBoson;
897 
898  //--Sherpa ZZ,ZW
899  if ((numberOfChildren - NumOfquark - NumOfgluon) == 4 &&
900  (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 4) &&
901  (MC::isQuark(pdg1)||MC::isGluon(pdg1)) && (MC::isQuark(pdg2)||MC::isGluon(pdg2))) return DiBoson;
902 
903  //--Sherpa VVV -- Note, have to allow for prompt photon radiation or these get lost
904  if ((numberOfChildren - NumOfquark - NumOfgluon - NumOfPhot) == 6 &&
905  (NumOfEl + NumOfPos + NumOfMuPl + NumOfMuMin + NumOfTau + NumOfElNeut + NumOfMuNeut + NumOfTauNeut == 6) &&
906  (MC::isQuark(pdg1)||MC::isGluon(pdg1)) && (MC::isQuark(pdg2)||MC::isGluon(pdg2))) return MultiBoson;
907  }
908 
909  // New Sherpa Z->tautau
910  if (partProdVtx == ancestorProdVtx) {
911  int NumOfTauLoop = 0;
912  int NumOfTauNeuLoop = 0;
913  int NumOfLepLoop = 0;
914  for ( const auto *const pout: partProdVtx->particles_out()) {
915  if (!pout) continue;
916  for (const auto *const pin: partProdVtx->particles_in()) {
917  if (!pin) continue;
918  if (!HepMC::is_same_particle(pout,pin)) continue;
919  if (MC::isTau(pout)) NumOfTauLoop++;
920  if (std::abs(pout->pdgId()) == MC::NU_TAU) NumOfTauNeuLoop++;
921  if (MC::isSMLepton(pout)) NumOfLepLoop++;
922  break; // break out of inner loop after having found two matching particles
923  }
924  }
925  if (NumOfTauLoop == 2 && NumOfTauNeuLoop == 0) return ZBoson;
926  if (NumOfTauLoop == 1 && NumOfTauNeuLoop == 1) return WBoson;
927  if ((NumOfTauLoop == 4 && NumOfTauNeuLoop == 0) || (NumOfTauLoop == 3 && NumOfTauNeuLoop == 1) || (NumOfTauLoop == 2 && NumOfTauNeuLoop == 2)) return DiBoson;
928  if (NumOfLepLoop == 4) return DiBoson;
929  }
930 
931  //-- McAtNLo
932 
933  if (MC::isHiggs(ancestorPDG)) return Higgs;
934  if (MC::isMSSMHiggs(ancestorPDG)) return HiggsMSSM; // MSSM Higgs bosons
935  if (MC::isHeavyBoson(ancestorPDG)) return HeavyBoson; // Heavy bosons( Z', Z'', W'+)
936  if (std::abs(ancestorPDG) == MC::WBOSON_LRSM) return WBosonLRSM; // Left-right symmetric model WBoson (Pythia-specific)
937  if (std::abs(ancestorPDG) == MC::RH_NU_TAU) return NuRTau; // Right-handed NU_TAU (Pythia-specific)
938  if (MC::isSUSY(ancestorPDG)) return SUSY;
939  if (MC::isBSM(ancestorPDG)) return OtherBSM;
940  if (std::abs(ancestorPDG) == MC::JPSI) return JPsi;
941 
942  const ParticleType pType = defTypeOfHadron(ancestorPDG);
943  return convHadronTypeToOrig(pType, ancestorPDG);
944 }

◆ detEta()

double MCTruthClassifier::detEta ( double  x,
double  y 
) const
inlineprivate

Definition at line 169 of file MCTruthClassifier.h.

◆ detPhi()

double MCTruthClassifier::detPhi ( double  x,
double  y 
) const
inlineprivate

Definition at line 170 of file MCTruthClassifier.h.

◆ detStore()

const ServiceHandle<StoreGateSvc>& AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

95 { return m_detStore; }

◆ egammaClusMatch()

const xAOD::TruthParticle * MCTruthClassifier::egammaClusMatch ( const xAOD::CaloCluster clus,
bool  isFwrdEle,
MCTruthPartClassifier::Info info 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 44 of file MCTruthClassifierAthena.cxx.

45 {
46  ATH_MSG_DEBUG("Executing egammaClusMatch ");
47  const xAOD::TruthParticle* theMatchPart = nullptr;
48  const EventContext& ctx = info ? info->eventContext : Gaudi::Hive::currentContext();
49  // retrieve collection and get a pointer
51 
52  if (!truthParticleContainerReadHandle.isValid()) {
53  ATH_MSG_WARNING( " Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.key());
54  return theMatchPart;
55  }
56 
58  if (!caloMgrHandle.isValid()) {
59  ATH_MSG_WARNING(" Invalid ReadCondHandle for CaloDetDescrManager with key: " << m_caloMgrKey.key());
60  return theMatchPart;
61  }
62 
63  const CaloDetDescrManager* caloDDMgr = *caloMgrHandle;
64  const xAOD::TruthParticle* theEgamma(nullptr);
65  const xAOD::TruthParticle* theLeadingPartInCone(nullptr);
66  const xAOD::TruthParticle* theBestPartOutCone(nullptr);
67  const xAOD::TruthParticle* theBestPartdR(nullptr);
68  double LeadingPhtPT(0);
69  double LeadingPartPT(0);
70  double LeadingPhtdR(999.);
71  double LeadingPartdR(999.);
72  double BestPartdR(999.);
73  double etaClus = clus->etaBE(2);
74  double phiClus = clus->phiBE(2);
75  if (etaClus < -900) {
76  etaClus = clus->eta();
77  }
78  if (phiClus < -900) {
79  phiClus = clus->phi();
80  }
81  std::vector<const xAOD::TruthParticle*> tps;
82  if (!m_truthInConeTool->particlesInCone(ctx, etaClus, phiClus, 0.5, tps)) {
83  ATH_MSG_WARNING("Truth Particle in Cone failed");
84  return theMatchPart;
85  }
86 
87  for (const auto* const thePart : tps) {
88  // loop over the stable particle
89  if (!MC::isStable(thePart)) continue;
90  // excluding G4 particle
91  if ((!isFwrdEle || (isFwrdEle && m_FwdElectronUseG4Sel)) && HepMC::is_simulation_particle(thePart)) continue;
92  long iParticlePDG = thePart->pdgId();
93  // excluding neutrino
94  if (std::abs(iParticlePDG) == 12 || std::abs(iParticlePDG) == 14 || std::abs(iParticlePDG) == 16) continue;
95  double pt = thePart->pt() / Athena::Units::GeV;
96  double q = thePart?thePart->charge():0.0;
97  // exclude charged particles with pT<1 GeV
98  if (q != 0 && pt < m_pTChargePartCut) continue;
99  if (q == 0 && pt < m_pTNeutralPartCut) continue;
100 
101  // eleptical cone for extrapolations m_partExtrConePhi X m_partExtrConeEta
102  if (!isFwrdEle && m_ROICone && std::hypot( detPhi(phiClus, thePart->phi())/m_partExtrConePhi, detEta(etaClus, thePart->eta())/m_partExtrConeEta) > 1.0) {
103  continue;
104  }
105  // Also check if the clus and true have different sign , i they need both to be <0 or >0
106  if (isFwrdEle && // It is forward and
107  (((etaClus < 0) - (thePart->eta() < 0) != 0)
108  // The truth eta has different sign wrt to the fwd electron
109  || (std::fabs(thePart->eta()) < m_FwdElectronTruthExtrEtaCut) // or the truth is less than 2.4 (default cut)
110  || (std::fabs(thePart->eta() - etaClus) > m_FwdElectronTruthExtrEtaWindowCut) // or if the delta Eta between el and truth is > 0.15
111  ) // then do no extrapolate this truth Particle for this fwd electron
112  ) {
113  continue;
114  }
115  double dR(-999.);
116  bool isNCone = false;
117  bool isExt = genPartToCalo(ctx, clus, thePart, isFwrdEle, dR, isNCone, *caloDDMgr);
118  if (!isExt) continue;
119  theMatchPart = MC::findMatching(truthParticleContainerReadHandle.ptr(), thePart);
120  if (info) {
121  info->egPartPtr.push_back(thePart);
122  info->egPartdR.push_back(dR);
123  info->egPartClas.push_back(particleTruthClassifier(theMatchPart, info));
124  }
125  // Gen particles Not forward
126  if (!isFwrdEle) {
127  // the leading photon or electron inside narrow eleptical cone
128  // m_phtClasConePhi X m_phtClasConeEta
129  if ((iParticlePDG == 22 || std::abs(iParticlePDG) == 11) && isNCone && pt > LeadingPhtPT) {
130  theEgamma = thePart;
131  LeadingPhtPT = pt;
132  LeadingPhtdR = dR;
133  }
134  // leading particle (excluding photon and electron) inside narrow eleptic
135  // cone m_phtClasConePhi X m_phtClasConeEta
136  if ((iParticlePDG != 22 && std::abs(iParticlePDG) != 11) && isNCone && pt > LeadingPartPT) {
137  theLeadingPartInCone = thePart;
138  LeadingPartPT = pt;
139  LeadingPartdR = dR;
140  };
141  // the best dR matched particle outside narrow eleptic cone cone
142  // m_phtClasConePhi X m_phtClasConeEta
143  if (!isNCone && dR < BestPartdR) {
144  theBestPartOutCone = thePart;
145  BestPartdR = dR;
146  };
147  } else {
148  if (dR < BestPartdR) {
149  theBestPartdR = thePart;
150  BestPartdR = dR;
151  };
152  }
153  }
154 
155  if (theEgamma != nullptr) {
156  theMatchPart = MC::findMatching(truthParticleContainerReadHandle.ptr(), theEgamma);
157  if (info) info->deltaRMatch = LeadingPhtdR;
158  } else if (theLeadingPartInCone != nullptr) {
159  theMatchPart = MC::findMatching(truthParticleContainerReadHandle.ptr(),theLeadingPartInCone);
160  if (info) info->deltaRMatch = LeadingPartdR;
161  } else if (theBestPartOutCone != nullptr) {
162  theMatchPart = MC::findMatching(truthParticleContainerReadHandle.ptr(),theBestPartOutCone);
163  if (info) info->deltaRMatch = BestPartdR;
164  } else if (isFwrdEle && theBestPartdR != nullptr) {
165  theMatchPart = MC::findMatching(truthParticleContainerReadHandle.ptr(),theBestPartdR );
166  if (info) info->deltaRMatch = BestPartdR;
167  } else {
168  theMatchPart = nullptr;
169  }
170  if (isFwrdEle || theMatchPart != nullptr || !m_inclG4part) return theMatchPart;
171 
172  // additional loop over G4 particles,
173  for (const auto* const thePart : tps) {
174  if (!MC::isStable(thePart)) continue;
175  if (!HepMC::is_simulation_particle(thePart)) continue;
176  long iParticlePDG = thePart->pdgId();
177  // exclude neutrino
178  if (std::abs(iParticlePDG) == 12 || std::abs(iParticlePDG) == 14 || std::abs(iParticlePDG) == 16) continue;
179  if (thePart->decayVtx() != nullptr) continue;
180  if (std::hypot( detPhi(phiClus, thePart->phi())/m_partExtrConePhi, detEta(etaClus, thePart->eta())/m_partExtrConeEta ) > 1.0) continue;
181 
182  double pt = thePart->pt() / Athena::Units::GeV;
183  double q = thePart->charge();
184  // exclude charged particles with pT<1 GeV
185  if (q != 0 && pt < m_pTChargePartCut) continue;
186  if (q == 0 && pt < m_pTNeutralPartCut) continue;
187 
188  double dR(-999.);
189  bool isNCone = false;
190  bool isExt = genPartToCalo(ctx, clus, thePart, isFwrdEle, dR, isNCone, *caloDDMgr);
191  if (!isExt) continue;
192 
193  theMatchPart = MC::findMatching(truthParticleContainerReadHandle.ptr(),thePart);
194  if (info) {
195  info->egPartPtr.push_back(thePart);
196  info->egPartdR.push_back(dR);
197  info->egPartClas.push_back(particleTruthClassifier(theMatchPart, info));
198  }
199  // the leading photon or electron inside narrow eleptical cone
200  // m_phtClasConePhi X m_phtClasConeEta
201  if ((iParticlePDG == 22 || std::abs(iParticlePDG) == 11) && isNCone && pt > LeadingPhtPT) {
202  theEgamma = thePart;
203  LeadingPhtPT = pt;
204  LeadingPhtdR = dR;
205  }
206  // leading particle (excluding photon or electron) inside narrow eleptic
207  // cone m_phtClasConePhi X m_phtClasConeEta
208  if ((iParticlePDG != 22 && std::abs(iParticlePDG) != 11) && isNCone && pt > LeadingPartPT) {
209  theLeadingPartInCone = thePart;
210  LeadingPartPT = pt;
211  LeadingPartdR = dR;
212  }
213  // the best dR matched particle outside narrow eleptic cone cone
214  // m_phtClasConePhi X m_phtClasConeEta
215  if (!isNCone && dR < BestPartdR) {
216  theBestPartOutCone = thePart;
217  BestPartdR = dR;
218  }
219  }
220 
221  if (theEgamma != nullptr) {
222  theMatchPart = MC::findMatching(truthParticleContainerReadHandle.ptr(),theEgamma);
223  if (info) info->deltaRMatch = LeadingPhtdR;
224  } else if (theLeadingPartInCone != nullptr) {
225  theMatchPart = MC::findMatching(truthParticleContainerReadHandle.ptr(),theLeadingPartInCone);
226  if (info) info->deltaRMatch = LeadingPartdR;
227  } else if (theBestPartOutCone != nullptr) {
228  theMatchPart = MC::findMatching(truthParticleContainerReadHandle.ptr(),theBestPartOutCone);
229  if (info) info->deltaRMatch = BestPartdR;
230  } else {
231  theMatchPart = nullptr;
232  }
233  ATH_MSG_DEBUG("succeeded egammaClusMatch ");
234  return theMatchPart;
235 }

◆ evtStore() [1/2]

ServiceHandle<StoreGateSvc>& AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

85 { return m_evtStore; }

◆ evtStore() [2/2]

const ServiceHandle<StoreGateSvc>& AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( ) const
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 90 of file AthCommonDataStore.h.

90 { return m_evtStore; }

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase &  ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ findJetConstituents()

void MCTruthClassifier::findJetConstituents ( const xAOD::Jet jet,
std::set< const xAOD::TruthParticle * > &  constituents,
bool  DR 
) const
private

Definition at line 278 of file MCRecoToTruth.cxx.

281 {
282  if (DR) {
283  // use a DR matching scheme (default)
284  // retrieve collection and get a pointer
286 
287  if (!truthParticleContainerReadHandle.isValid()) {
288  ATH_MSG_WARNING(" Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.key());
289  return;
290  }
291  ATH_MSG_DEBUG("xAODTruthParticleContainer with key " << truthParticleContainerReadHandle.key() << " has valid ReadHandle ");
292  // find the matching truth particles
293  for (const auto *const thePart : *truthParticleContainerReadHandle) {
294  // match truth particles to the jet
295  if (MC::isStable(thePart) && thePart->p4().DeltaR(jet->p4()) < m_jetPartDRMatch) {
296  constituents.insert(thePart);
297  }
298  }
299  }
300  else {
301  xAOD::JetConstituentVector vec = jet->getConstituents();
302  for (const auto *particle0 : vec) {
303  const xAOD::TruthParticle* thePart = dynamic_cast<const xAOD::TruthParticle*>(particle0->rawConstituent());
304  if (MC::isStable(thePart)) {
305  constituents.insert(thePart);
306  }
307  }
308  }
309 }

◆ fracParticleInJet()

double MCTruthClassifier::fracParticleInJet ( const xAOD::TruthParticle thePart,
const xAOD::Jet jet,
bool  DR,
bool  nparts 
) const
private

Definition at line 310 of file MCRecoToTruth.cxx.

311 {
312  std::set<const xAOD::TruthParticle*> constituents;
313  std::set<const xAOD::TruthParticle*> daughters;
314  std::set<const xAOD::TruthParticle*> intersect;
315 
316  findJetConstituents(jet, constituents, DR);
317  MC::findParticleStableDescendants(thePart, daughters);
318  if (daughters.empty()) daughters.insert(thePart);
319  // Get the intersection of constituents and daughters
320  std::set_intersection(constituents.begin(),
321  constituents.end(),
322  daughters.begin(),
323  daughters.end(),
324  std::inserter(intersect, intersect.begin()));
325 
326  if (nparts) return 1.0*intersect.size() / daughters.size();
327  double frac = 0;
328  double tot = 0;
329  for (const auto *daughter : daughters) { tot += daughter->pt();}
330  for (const auto *particle : intersect) { frac += particle->pt();}
331  return frac/tot;
332 }

◆ genPartToCalo()

bool MCTruthClassifier::genPartToCalo ( const EventContext &  ctx,
const xAOD::CaloCluster clus,
const xAOD::TruthParticle thePart,
bool  isFwrdEle,
double &  dRmatch,
bool &  isNarrowCone,
const CaloDetDescrManager caloDDMgr 
) const
private

Definition at line 237 of file MCTruthClassifierAthena.cxx.

244 {
245  dRmatch = -999.;
246  isNarrowCone = false;
247  if (thePart == nullptr) return false;
248  double phiClus = clus->phiBE(2);
249  double etaClus = clus->etaBE(2);
250  if (etaClus < -900) {
251  etaClus = clus->eta();
252  }
253  if (phiClus < -900) {
254  phiClus = clus->phi();
255  }
256  //--FixMe
257  if (isFwrdEle || (etaClus == 0. && phiClus == 0.)) {
258  phiClus = clus->phi();
259  etaClus = clus->eta();
260  }
261  // define calo sample
263  if ((clus->inBarrel() && !clus->inEndcap()) ||
264  (clus->inBarrel() && clus->inEndcap() && clus->eSample(CaloSampling::EMB2) >= clus->eSample(CaloSampling::EME2))) {
265  // Barrel
267  } else if ((!clus->inBarrel() && clus->inEndcap() && !isFwrdEle) ||
268  (clus->inBarrel() && clus->inEndcap() && clus->eSample(CaloSampling::EME2) > clus->eSample(CaloSampling::EMB2))) {
269  // End-cap
271  } else if (isFwrdEle && clus->inEndcap()) {
272  // FCAL
274  } else {
275  return false;
276  }
277  std::unique_ptr<Trk::CurvilinearParameters> params = extractParamFromTruth(*thePart);
278  if (!params) return false;
279  // create extension to sample
280  std::vector<CaloSampling::CaloSample> samples = { sample };
281  auto extension = m_caloExtensionTool->layersCaloExtension(ctx, *params, samples, etaClus, caloDDMgr);
282  bool extensionOK = (!extension.empty());
283  if (!extensionOK) {
284  ATH_MSG_WARNING("extrapolation of Truth Particle with eta " << thePart->eta() << " , charge " << thePart->charge() << " , Pt " << thePart->pt() << " to calo failed");
285  return false;
286  }
287  double etaCalo = extension[0].second->position().eta();
288  double phiCalo = extension[0].second->position().phi();
289 
290  double dPhi = detPhi(phiCalo, phiClus);
291  double dEta = detEta(etaCalo, etaClus);
292  dRmatch = std::hypot(dPhi, dEta);
293 
294  if ((!isFwrdEle && dRmatch > m_phtdRtoTrCut) || (isFwrdEle && dRmatch > m_fwrdEledRtoTrCut)) return false;
295  if (!isFwrdEle && std::hypot( dPhi/m_phtClasConePhi, dEta/m_phtClasConeEta ) <= 1.0) isNarrowCone = true;
296  return true;
297 }

◆ getGenPart()

const xAOD::TruthParticle * MCTruthClassifier::getGenPart ( const xAOD::TrackParticle trk,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 181 of file MCRecoToTruth.cxx.

182 {
183  // return GenParticle corresponding to given TrackParticle
184  ATH_MSG_DEBUG("Executing getGenPart ");
185  if (!trk) return nullptr;
186  if (info) {
187  info->deltaRMatch = -999.;
188  info->deltaPhi = -999.;
189  info->probTrkToTruth = 0;
190  info->numOfSiHits = 0;
191  }
192 
193  uint8_t NumOfPixHits = 0;
194  uint8_t NumOfSCTHits = 0;
196 
197  static const SG::AuxElement::Accessor<TruthLink_t> tPL("truthParticleLink");
198  if (!tPL.isAvailable(*trk)) {
199  ATH_MSG_DEBUG("Track particle is not associated to truth particle");
200  return nullptr;
201  }
202 
203  const auto& truthLink = tPL(*trk);
204  if (!truthLink.isValid()) {
205  ATH_MSG_DEBUG("Invalid link to truth particle");
206  return nullptr;
207  }
208 
209  const xAOD::TruthParticle* theGenParticle = (*truthLink);
210  if (!theGenParticle) {
211  ATH_MSG_DEBUG("Could not find truth matching for track");
212  return nullptr;
213  }
214 
215  if (info) {
216  static const SG::AuxElement::Accessor<float> tMP("truthMatchProbability");
217  if (tMP.isAvailable(*trk)) {
218  info->probTrkToTruth = tMP(*trk);
219  } else {
220  ATH_MSG_DEBUG("Truth match probability not available");
221  }
222  }
223 
224  if (theGenParticle->status() == 3) {
225  ATH_MSG_WARNING("track matched to the truth with status " << theGenParticle->status());
226  }
227  else if (MC::isDecayed(theGenParticle)) {
228  // Matching to status == 2 particles is to be expected if
229  // quasi-stable particle simulation was used.
230  ATH_MSG_DEBUG("track matched to the truth with status " << theGenParticle->status());
231  }
232 
233  if (MC::isDecayed(theGenParticle) && (MC::isElectron(theGenParticle) || MC::isMuon(theGenParticle))) {
234  const xAOD::TruthVertex* EndVrtx = theGenParticle->decayVtx();
235  const xAOD::TruthParticle* theGenPartTmp(nullptr);
236 
237  if (EndVrtx != nullptr) {
238  int itr = 0;
239  do {
240  theGenPartTmp = nullptr;
241  for (const auto & theDaugt: EndVrtx->particles_out()) {
242  if (!theDaugt) continue;
243  if (theDaugt->pdgId() == theGenParticle->pdgId()) theGenPartTmp = theDaugt;
244  if (theDaugt->pdgId() != theGenParticle->pdgId() && !MC::isPhoton(theDaugt)) theGenPartTmp = nullptr;
245  }
246  itr++;
247  if (itr > 100) {
248  ATH_MSG_WARNING("getGenPart infinite while");
249  break;
250  }
251  EndVrtx = theGenPartTmp ? theGenPartTmp->decayVtx() : nullptr;
252  } while (theGenPartTmp && theGenPartTmp->pdgId() == theGenParticle->pdgId() && MC::isDecayed(theGenPartTmp) && EndVrtx != nullptr);
253 
254  if (theGenPartTmp && theGenPartTmp->pdgId() == theGenParticle->pdgId()) theGenParticle = theGenPartTmp;
255  }
256  }
257 
258  if (!trk->summaryValue(NumOfSCTHits, xAOD::numberOfSCTHits)) ATH_MSG_DEBUG("Could not retrieve number of SCT hits");
259  if (!trk->summaryValue(NumOfPixHits, xAOD::numberOfPixelHits)) ATH_MSG_DEBUG("Could not retrieve number of Pixel hits");
260 
261  uint8_t NumOfSiHits = NumOfSCTHits + NumOfPixHits;
262 
263  float deltaPhi = detPhi(theGenParticle->phi(), trk->phi());
264  float deteta = detEta(theGenParticle->eta(), trk->eta());
265  float deltaRMatch = std::hypot(deltaPhi, deteta);
266  if ((NumOfSiHits > m_NumOfSiHitsCut && deltaRMatch > m_deltaRMatchCut) ||
267  (NumOfSiHits <= m_NumOfSiHitsCut && deltaPhi > m_deltaPhiMatchCut)) theGenParticle = nullptr;
268 
269  if (info) {
270  info->deltaRMatch = deltaRMatch;
271  info->deltaPhi = deltaPhi;
272  info->numOfSiHits = NumOfSiHits;
273  }
274  ATH_MSG_DEBUG("getGenPart succeeded ");
275  return (theGenParticle);
276 }

◆ getKey()

SG::sgkey_t asg::AsgTool::getKey ( const void *  ptr) const
inherited

Get the (hashed) key of an object that is in the event store.

This is a bit of a special one. StoreGateSvc and xAOD::TEvent both provide ways for getting the SG::sgkey_t key for an object that is in the store, based on a bare pointer. But they provide different interfaces for doing so.

In order to allow tools to efficiently perform this operation, they can use this helper function.

See also
asg::AsgTool::getName
Parameters
ptrThe bare pointer to the object that the event store should know about
Returns
The hashed key of the object in the store. If not found, an invalid (zero) key.

Definition at line 119 of file AsgTool.cxx.

119  {
120 
121 #ifdef XAOD_STANDALONE
122  // In case we use @c xAOD::TEvent, we have a direct function call
123  // for this.
124  return evtStore()->event()->getKey( ptr );
125 #else
126  const SG::DataProxy* proxy = evtStore()->proxy( ptr );
127  return ( proxy == nullptr ? 0 : proxy->sgkey() );
128 #endif // XAOD_STANDALONE
129  }

◆ getName()

const std::string & asg::AsgTool::getName ( const void *  ptr) const
inherited

Get the name of an object that is / should be in the event store.

This is a bit of a special one. StoreGateSvc and xAOD::TEvent both provide ways for getting the std::string name for an object that is in the store, based on a bare pointer. But they provide different interfaces for doing so.

In order to allow tools to efficiently perform this operation, they can use this helper function.

See also
asg::AsgTool::getKey
Parameters
ptrThe bare pointer to the object that the event store should know about
Returns
The string name of the object in the store. If not found, an empty string.

Definition at line 106 of file AsgTool.cxx.

106  {
107 
108 #ifdef XAOD_STANDALONE
109  // In case we use @c xAOD::TEvent, we have a direct function call
110  // for this.
111  return evtStore()->event()->getName( ptr );
112 #else
113  const SG::DataProxy* proxy = evtStore()->proxy( ptr );
114  static const std::string dummy = "";
115  return ( proxy == nullptr ? dummy : proxy->name() );
116 #endif // XAOD_STANDALONE
117  }

◆ getProperty()

template<class T >
const T* asg::AsgTool::getProperty ( const std::string &  name) const
inherited

Get one of the tool's properties.

◆ initialize()

virtual StatusCode MCTruthClassifier::initialize ( )
inlineoverridevirtual

Dummy implementation of the initialisation function.

It's here to allow the dual-use tools to skip defining an initialisation function. Since many are doing so...

Reimplemented from asg::AsgTool.

Reimplemented in D3PD::D3PDMCTruthClassifier.

Definition at line 101 of file MCTruthClassifier.h.

107  {
108  ATH_CHECK(m_caloExtensionTool.retrieve());
109  } else {
110  m_caloExtensionTool.disable();
111  }
112 
114 
115  if (!m_truthInConeTool.empty()) {
116  ATH_CHECK(m_truthInConeTool.retrieve());
117  } else {
118  m_truthInConeTool.disable();
119  }
120 #endif
121  return StatusCode::SUCCESS;
122  }
123  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin>
125 
126 #ifndef XAOD_ANALYSIS /*These can not run in Analysis Base*/
127  virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin>

◆ inputHandles()

virtual std::vector<Gaudi::DataHandle*> AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ msg() [1/2]

MsgStream& AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24  {
25  return this->msgStream();
26  }

◆ msg() [2/2]

MsgStream& AthCommonMsg< AlgTool >::msg ( const MSG::Level  lvl) const
inlineinherited

Definition at line 27 of file AthCommonMsg.h.

27  {
28  return this->msgStream(lvl);
29  }

◆ msg_level_name()

const std::string & asg::AsgTool::msg_level_name ( ) const
inherited

A deprecated function for getting the message level's name.

Instead of using this, weirdly named function, user code should get the string name of the current minimum message level (in case they really need it...), with:

MSG::name( msg().level() )

This function's name doesn't follow the ATLAS coding rules, and as such will be removed in the not too distant future.

Returns
The string name of the current minimum message level that's printed

Definition at line 101 of file AsgTool.cxx.

101  {
102 
103  return MSG::name( msg().level() );
104  }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level  lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30  {
31  return this->msgLevel(lvl);
32  }

◆ outputHandles()

virtual std::vector<Gaudi::DataHandle*> AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ particleHepMCTruthClassifier() [1/2]

std::pair< ParticleType, ParticleOrigin > MCTruthClassifier::particleHepMCTruthClassifier ( const HepMcParticleLink theLink,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 26 of file MCTruthClassifierGen.cxx.

26  {
27  // Retrieve the links between HepMC and xAOD::TruthParticle
28  const EventContext& ctx = info ? info->eventContext : Gaudi::Hive::currentContext();
30  if (!truthParticleLinkVecReadHandle.isValid()) {
31  ATH_MSG_WARNING(" Invalid ReadHandle for xAODTruthParticleLinkVector with key: " << truthParticleLinkVecReadHandle.key());
32  return std::make_pair(Unknown, NonDefined);
33  }
34  ElementLink<xAOD::TruthParticleContainer> tplink = truthParticleLinkVecReadHandle->find (theLink);
35  if (tplink.isValid()) {
36  return particleTruthClassifier (*tplink, info);
37  }
38  return std::make_pair(Unknown, NonDefined);
39 }

◆ particleHepMCTruthClassifier() [2/2]

std::pair< ParticleType, ParticleOrigin > MCTruthClassifier::particleHepMCTruthClassifier ( HepMC::ConstGenParticlePtr  theGenPart,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 42 of file MCTruthClassifierGen.cxx.

42  {
43  ParticleType partType = Unknown;
44  ParticleOrigin partOrig = NonDefined;
45 
46  if (!theGenPart) return std::make_pair(partType, partOrig);
47 
48  // Retrieve the links between HepMC and xAOD::TruthParticle
49  const EventContext& ctx = info ? info->eventContext : Gaudi::Hive::currentContext();
50 
52  if (!truthParticleLinkVecReadHandle.isValid()) {
53  ATH_MSG_WARNING( " Invalid ReadHandle for xAODTruthParticleLinkVector with key: " << truthParticleLinkVecReadHandle.key());
54  return std::make_pair(partType, partOrig);
55  }
56  for (const auto *const entry : *truthParticleLinkVecReadHandle) {
57  if (entry->first.isValid() && entry->second.isValid() && HepMC::is_same_particle(entry->first,theGenPart)) {
58  const xAOD::TruthParticle* truthParticle = *entry->second;
59  if (!theGenPart || !truthParticle ||
60  theGenPart->pdg_id() != truthParticle->pdgId() ||
61  theGenPart->status() != truthParticle->status() ||
62  HepMC::is_same_particle(theGenPart,truthParticle)) {
64  "HepMC::GenParticle and xAOD::TruthParticle do not match");
65  return std::make_pair(partType, partOrig);
66  }
67  return particleTruthClassifier(truthParticle, info);
68  }
69  }
70  return std::make_pair(partType, partOrig);
71 }

◆ particleTruthClassifier() [1/7]

std::pair< ParticleType, ParticleOrigin > MCTruthClassifier::particleTruthClassifier ( const xAOD::CaloCluster clus,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 114 of file MCRecoToTruth.cxx.

115 {
116  ATH_MSG_DEBUG("Executing egamma photon Classifier with cluster Input");
117  ParticleType parttype = Unknown;
118  ParticleOrigin partorig = NonDefined;
119  if (!clus) return std::make_pair(parttype, partorig);
120  if (std::fabs(clus->eta()) > 10.0 || std::fabs(clus->phi()) > M_PI || (clus->et()) <= 0.) return std::make_pair(parttype, partorig);
121  const xAOD::TruthParticle* genPart = nullptr;
122 #ifndef XAOD_ANALYSIS // Fwd electron available only in Athena
123  genPart = egammaClusMatch(clus, false, info);
124 #else
125  ATH_MSG_WARNING("Cluster Classification using extrapolation to Calo is available only in Athena , check your enviroment. ");
126 #endif
127  if (!genPart) return std::make_pair(parttype, partorig);
128  ATH_MSG_DEBUG("Calo Cluster Classifier succeeded ");
129  if (info) info->genPart = genPart;
130  return particleTruthClassifier(genPart, info);
131 }

◆ particleTruthClassifier() [2/7]

std::pair< ParticleType, ParticleOrigin > MCTruthClassifier::particleTruthClassifier ( const xAOD::Electron elec,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 24 of file MCRecoToTruth.cxx.

25 {
26  ATH_MSG_DEBUG("Executing egamma electron Classifier");
27  ParticleType parttype = Unknown;
28  ParticleOrigin partorig = NonDefined;
29  const xAOD::TruthParticle* genPart = nullptr;
30  const xAOD::TrackParticle* trkPtr = elec->trackParticle();
31  if (elec->author() != xAOD::EgammaParameters::AuthorFwdElectron ||trkPtr) {
32  // Central electron or forward electron with track (when reco
33  // implemented in the future)
34  if (!trkPtr){
35  return std::make_pair(parttype, partorig);
36  }
37  genPart = getGenPart(trkPtr);
38  } else {
39 #ifndef XAOD_ANALYSIS // cluster matching available only in Athena
40  const xAOD::CaloCluster* clus = elec->caloCluster();
41  genPart = egammaClusMatch(clus, true, info);
42 #else
43  ATH_MSG_WARNING("Forward Electron classification using extrapolation to Calo is available only in Athena , check your enviroment. ");
44 #endif
45  }
46 
47  if (info) info->genPart = genPart;
48  if (!genPart) return std::make_pair(parttype, partorig);
49  ATH_MSG_DEBUG("egamma electron Classifier succeeded ");
50  return particleTruthClassifier(genPart, info);
51 }

◆ particleTruthClassifier() [3/7]

std::pair< ParticleType, ParticleOrigin > MCTruthClassifier::particleTruthClassifier ( const xAOD::Jet jet,
bool  DR,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 134 of file MCRecoToTruth.cxx.

135 {
136  ATH_MSG_DEBUG("Executing Classifier with jet Input");
137  ParticleType parttype = UnknownJet;
138  ParticleOrigin partorig = NonDefined;
139  ParticleType tempparttype = UnknownJet;
140  std::set<const xAOD::TruthParticle*> allJetMothers;
141  std::set<const xAOD::TruthParticle*> constituents;
142  if (!jet) return std::make_pair(parttype, partorig);
143  allJetMothers.clear();
144  constituents.clear();
145  findJetConstituents(jet, constituents, DR);
146  // AV: Jet type is the type of hadron with "heaviest" flavour among the jet constituents.
147  // AV: No hadrons in the jet -- the flavour is unknown.
148  // AV: The algorithm will fail on 4/5 quark hadrons and probably on nonBSM hadrons. To be fixed.
149  for (const auto& thePart: constituents) {
150  MC::findParticleAncestors(thePart, allJetMothers);
151  //AV: probably skip ME particles
152  if (!MC::isPhysical(thePart)) continue;
153  // determine if hadron and its type
154  tempparttype = particleTruthClassifier(thePart, info).first;
155  if (tempparttype != Hadron) continue;
156  tempparttype = defTypeOfHadron(thePart->pdgId());
157  // classify the jet
158  if (tempparttype == BBbarMesonPart || tempparttype == BottomMesonPart || tempparttype == BottomBaryonPart) {
159  parttype = BJet;
160  continue;
161  }
162  if (tempparttype == CCbarMesonPart || tempparttype == CharmedMesonPart || tempparttype == CharmedBaryonPart) {
163  if (parttype != BJet) parttype = CJet;
164  continue;
165  }
166  if (tempparttype == StrangeBaryonPart || tempparttype == LightBaryonPart || tempparttype == StrangeMesonPart || tempparttype == LightMesonPart) {
167  if (parttype != BJet && parttype != CJet) parttype = LJet;
168  continue;
169  }
170  }
171 
172  // clasify the jet origin
173  partorig = defJetOrig(allJetMothers);
174  allJetMothers.clear();
175  constituents.clear();
176  ATH_MSG_DEBUG(" jet Classifier succeeded");
177  return std::make_pair(parttype, partorig);
178 }

◆ particleTruthClassifier() [4/7]

std::pair< ParticleType, ParticleOrigin > MCTruthClassifier::particleTruthClassifier ( const xAOD::Muon mu,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 93 of file MCRecoToTruth.cxx.

94 {
95  ATH_MSG_DEBUG("Executing muon Classifier");
96  ParticleType parttype = Unknown;
97  ParticleOrigin partorig = NonDefined;
98  const xAOD::TrackParticle* trkPtr = nullptr;
99  if (mu->primaryTrackParticleLink().isValid()) trkPtr = *mu->primaryTrackParticleLink();
100  else if (mu->combinedTrackParticleLink().isValid()) trkPtr = *mu->combinedTrackParticleLink();
101  else if (mu->inDetTrackParticleLink().isValid()) trkPtr = *mu->combinedTrackParticleLink();
102  else if (mu->muonSpectrometerTrackParticleLink().isValid()) trkPtr = *mu->muonSpectrometerTrackParticleLink();
103 
104  if (!trkPtr) return std::make_pair(parttype, partorig);
105 
106  const xAOD::TruthParticle* genPart = getGenPart(trkPtr);
107  if (!genPart) return std::make_pair(parttype, partorig);
108  if (info) info->genPart = genPart;
109  ATH_MSG_DEBUG("muon Classifier succeeded ");
110  return particleTruthClassifier(genPart, info);
111 }

◆ particleTruthClassifier() [5/7]

std::pair< ParticleType, ParticleOrigin > MCTruthClassifier::particleTruthClassifier ( const xAOD::Photon phot,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 54 of file MCRecoToTruth.cxx.

55 {
56  ATH_MSG_DEBUG("Executing egamma photon Classifier");
57  ParticleType parttype = Unknown;
58  ParticleOrigin partorig = NonDefined;
59  const xAOD::CaloCluster* clus = phot->caloCluster();
60  if (!clus) return std::make_pair(parttype, partorig);
61  if (std::fabs(clus->eta()) > 10.0 || std::fabs(clus->phi()) > 6.28 || (clus->et()) <= 0.) return std::make_pair(parttype, partorig);
62 
63  const xAOD::Vertex* VxCvPtr = phot->vertex();
64  if (VxCvPtr != nullptr) {
65  for (int itrk = 0; itrk < (int)VxCvPtr->nTrackParticles(); itrk++) {
66  if (itrk > 1) continue;
67  const xAOD::TrackParticle* trkPtr = VxCvPtr->trackParticle(itrk);
68  if (!trkPtr) continue;
69  const xAOD::TruthParticle* thePart = getGenPart(trkPtr);
70  std::pair<ParticleType, ParticleOrigin> classif = particleTruthClassifier(thePart, info);
71  if (info) {
72  info->cnvPhotTrkPtr.push_back(trkPtr);
73  info->cnvPhotTrkToTruthPart.push_back(thePart);
74  info->cnvPhotPartType.push_back(classif.first);
75  info->cnvPhotPartOrig.push_back(classif.second);
76  }
77  }
78  }
79 
80  const xAOD::TruthParticle* genPart = nullptr;
81 #ifndef XAOD_ANALYSIS // Fwd electron available only in Athena
82  genPart = egammaClusMatch(clus, false, info);
83 #else
84  ATH_MSG_WARNING("Photon Classification using extrapolation to Calo is available only in Athena , check your enviroment. ");
85 #endif
86  if (!genPart) return std::make_pair(parttype, partorig);
87  if (info) info->genPart = genPart;
88  ATH_MSG_DEBUG("egamma photon Classifier succeeded ");
89  return particleTruthClassifier(genPart, info);
90 }

◆ particleTruthClassifier() [6/7]

std::pair< ParticleType, ParticleOrigin > MCTruthClassifier::particleTruthClassifier ( const xAOD::TrackParticle trkPtr,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 11 of file MCRecoToTruth.cxx.

12 {
13  ATH_MSG_DEBUG("Executing trackClassifier");
14  ParticleType parttype = Unknown;
15  ParticleOrigin partorig = NonDefined;
16  const xAOD::TruthParticle* genPart = getGenPart(trkPtr);
17  if (info) info->genPart = genPart;
18  if (!genPart) return std::make_pair(parttype, partorig);
19  ATH_MSG_DEBUG("trackClassifier succeeded ");
20  return particleTruthClassifier(genPart, info);
21 }

◆ particleTruthClassifier() [7/7]

std::pair< ParticleType, ParticleOrigin > MCTruthClassifier::particleTruthClassifier ( const xAOD::TruthParticle thePart,
MCTruthPartClassifier::Info info = nullptr 
) const
finaloverridevirtual

Implements IMCTruthClassifier.

Definition at line 75 of file MCTruthClassifierGen.cxx.

75  {
77  MCTruthPartClassifier::Info& info = (infoin) ? *infoin : tmpinfo;
78 
79  ATH_MSG_DEBUG("Executing particleTruthClassifier");
80 
81  ParticleType partType = Unknown;
82  ParticleOrigin partOrig = NonDefined;
83  if (!thePart) {
84  return std::make_pair(partType, partOrig);
85  }
86  info.genPart = thePart;
87 
88  // retrieve collection and get a pointer
89  SG::ReadHandle<xAOD::TruthParticleContainer> truthParticleContainerReadHandle(m_truthParticleContainerKey,info.eventContext);
90  if (!truthParticleContainerReadHandle.isValid()) {
91  ATH_MSG_WARNING( " Invalid ReadHandle for xAOD::TruthParticleContainer with key: " << truthParticleContainerReadHandle.key());
92  return std::make_pair(partType, partOrig);
93  }
94 
95  ATH_MSG_DEBUG("xAODTruthParticleContainer with key " << truthParticleContainerReadHandle.key() << " has valid ReadHandle ");
96 
97  if (!MC::isStable(thePart) && !MC::isDecayed(thePart)) {
98  return std::make_pair(GenParticle, partOrig);
99  }
100  const bool isPartHadr = MC::isHadron(thePart) && !MC::isBeam(thePart);
101  if (MC::isDecayed(thePart) && (!MC::isTau(thePart) && !isPartHadr)) return std::make_pair(GenParticle, partOrig);
102 
103  // SUSY datasets: tau(status==2)->tau(status==2)
104  if (MC::isDecayed(thePart) && MC::isTau(thePart)) {
105  const xAOD::TruthVertex* endVert = thePart->decayVtx();
106  if (endVert) {
107  if (endVert->nOutgoingParticles() == 1 && MC::isTau(endVert->outgoingParticle(0))) {
108  return std::make_pair(GenParticle, partOrig);
109  }
110  }
111  }
112 
113  if (MC::isStable(thePart) && MC::isSUSY(thePart)) return std::make_pair(SUSYParticle, partOrig);
114 
115  if (MC::isStable(thePart) && MC::isBSM(thePart)) return std::make_pair(OtherBSMParticle, partOrig);
116 
117  if (MC::isDecayed(thePart) &&
118  (!MC::isElectron(thePart) && !MC::isMuon(thePart) &&
119  !MC::isTau(thePart) && !MC::isPhoton(thePart)) &&
120  !isPartHadr)
121  return std::make_pair(GenParticle, partOrig);
122 
123  // FIXME vetoing protons here to preserve previous behaviour
124  if (MC::isNucleus(thePart) && std::abs(thePart->pdgId()) != MC::PROTON) return std::make_pair(NuclFrag, partOrig);
125 
126  if ( !MC::isSMLepton(thePart) && !MC::isPhoton(thePart) && !isPartHadr) return std::make_pair(partType, partOrig);
127  // don't consider generator particles
128 
129  const xAOD::TruthVertex* partProdVtx = thePart->hasProdVtx() ? thePart->prodVtx() : nullptr;
130 
131  const xAOD::TruthParticle* parent{};
132  if (partProdVtx) {
133  for (const auto& temp: partProdVtx->particles_in()) {if (temp) parent = temp;}
134  }
135  const int parentPDG = parent?parent->pdg_id():0;
136  info.setMotherProperties(parent);
137 
138  if (!partProdVtx && HepMC::is_simulation_particle(thePart)) {
139  return std::make_pair(NonPrimary, partOrig);
140  }
141  if (!partProdVtx && MC::isElectron(thePart)) {
142  // to define electron outcome status
143  bool isPrompt = false; // updated by defOrigOfElectron
144  partOrig = defOrigOfElectron(*truthParticleContainerReadHandle, thePart, isPrompt, info);
145  return std::make_pair(UnknownElectron, partOrig);
146  }
147  if (!partProdVtx && MC::isMuon(thePart)) {
148  // to define electron outcome status
149  bool isPrompt = false; // updated by defOrigOfMuon
150  partOrig = defOrigOfMuon(*truthParticleContainerReadHandle, thePart, isPrompt, info);
151  return std::make_pair(UnknownMuon, partOrig);
152  }
153  if (!partProdVtx && MC::isTau(thePart)) {
154  // to define electron outcome status
155  partOrig = defOrigOfTau(*truthParticleContainerReadHandle, thePart, parentPDG, info);
156  return std::make_pair(UnknownTau, partOrig);
157  }
158  if (!partProdVtx && MC::isPhoton(thePart)) {
159  // to define photon outcome
160  bool isPrompt = false; // updated by defOrigOfPhoton
161  partOrig = defOrigOfPhoton(*truthParticleContainerReadHandle, thePart, isPrompt, info);
162  return std::make_pair(UnknownPhoton, partOrig);
163  }
164  if (!partProdVtx && MC::isNeutrino(thePart)) {
165  // to define neutrino outcome
166  info.particleOutCome = NonInteract;
167  return std::make_pair(Neutrino, partOrig);
168  }
169 
170  if (thePart && info.Mother() && HepMC::is_same_generator_particle(thePart,info.Mother()))
171  return std::make_pair(NonPrimary, partOrig);
172 
173  if (isPartHadr) return std::make_pair(Hadron, partOrig);
174 
175  if (partProdVtx && parentPDG == 0 && partProdVtx->nOutgoingParticles() == 1 &&
176  partProdVtx->nIncomingParticles() == 0) {
177  if (MC::isElectron(thePart)) {
178  info.particleOutCome = defOutComeOfElectron(thePart);
179  return std::make_pair(IsoElectron, SingleElec);
180  }
181  if (MC::isMuon(thePart)) {
182  info.particleOutCome = defOutComeOfMuon(thePart);
183  return std::make_pair(IsoMuon, SingleMuon);
184  }
185  if (MC::isTau(thePart)) {
186  info.particleOutCome = defOutComeOfTau(thePart);
187  return std::make_pair(IsoTau, SingleTau);
188  }
189  if (MC::isPhoton(thePart)) {
190  info.particleOutCome = defOutComeOfPhoton(thePart);
191  return std::make_pair(IsoPhoton, SinglePhot);
192  }
193  }
194 
195  if (parentPDG == thePart->pdg_id() && parent && parent->status() == 3 && MC::isDecayed(thePart)) return std::make_pair(GenParticle, partOrig);
196 
197  if (MC::isElectron(thePart)) {
198  bool isPrompt = false; // updated by defOrigOfElectron
199  partOrig = defOrigOfElectron(*truthParticleContainerReadHandle, thePart, isPrompt, info);
200  partType = defTypeOfElectron(partOrig, isPrompt);
201  } else if (MC::isMuon(thePart)) {
202  bool isPrompt = false; // updated by defOrigOfMuon
203  partOrig = defOrigOfMuon(*truthParticleContainerReadHandle, thePart, isPrompt, info);
204  partType = defTypeOfMuon(partOrig, isPrompt);
205  } else if (MC::isTau(thePart)) {
206  partOrig = defOrigOfTau(*truthParticleContainerReadHandle, thePart, parentPDG, info);
207  partType = defTypeOfTau(partOrig);
208  } else if (MC::isPhoton(thePart)) {
209  bool isPrompt = false; // updated by defOrigOfPhoton
210  partOrig = defOrigOfPhoton(*truthParticleContainerReadHandle, thePart, isPrompt, info);
211  partType = defTypeOfPhoton(partOrig);
212  } else if (MC::isNeutrino(thePart)) {
213  bool isPrompt = false; // updated by defOrigOfNeutrino
214  partOrig = defOrigOfNeutrino(*truthParticleContainerReadHandle, thePart, isPrompt, info);
215  partType = Neutrino;
216  }
217 
218  ATH_MSG_DEBUG("particleTruthClassifier succeeded ");
219  return std::make_pair(partType, partOrig);
220 }

◆ print() [1/2]

void asg::AsgTool::print ( ) const
virtualinherited

◆ print() [2/2]

virtual void asg::IAsgTool::print ( ) const
pure virtualinherited

◆ renounce()

std::enable_if_t<std::is_void_v<std::result_of_t<decltype(&T::renounce)(T)> > && !std::is_base_of_v<SG::VarHandleKeyArray, T> && std::is_base_of_v<Gaudi::DataHandle, T>, void> AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T &  h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381  {
382  h.renounce();
383  PBASE::renounce (h);
384  }

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364  {
365  handlesArray.renounce();
366  }

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in DerivationFramework::CfAthAlgTool, AthCheckedComponent< AthAlgTool >, AthCheckedComponent<::AthAlgTool >, and asg::AsgMetadataTool.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ TruthLoopDetectionMethod1()

bool MCTruthClassifier::TruthLoopDetectionMethod1 ( const xAOD::TruthVertex childOrigVtx,
const xAOD::TruthParticle parent 
) const
private

Definition at line 223 of file MCTruthClassifierGen.cxx.

224 {
225  // Start of method 1 of protecting against loops
226  const int parentPDG = parent->pdgId();
227  for (const auto& aChild: childOrigVtx->particles_out()) {
228  if (!aChild) continue;
229  if (parentPDG == aChild->pdgId() && HepMC::is_same_generator_particle(aChild, parent)) {
230  // One of the children produced in the decay of parent is
231  // actually the same particle. NB In the case of multiple
232  // children this child may not necessarily be
233  // thePriPart. Does this matter?
234  return true;
235  }
236  }
237 
238  // to resolve Sherpa loop
239  return TruthLoopDetectionMethod3(childOrigVtx, parent);
240  // End of method 1 of protecting against loops
241 }

◆ TruthLoopDetectionMethod2()

bool MCTruthClassifier::TruthLoopDetectionMethod2 ( const xAOD::TruthParticle child,
const xAOD::TruthParticle parent 
) const
private

Definition at line 244 of file MCTruthClassifierGen.cxx.

245 {
246  // Start of method 2 of protecting against loops
247  // to prevent Sherpa loop
248  const xAOD::TruthVertex* child_prdVtx{};
249  const xAOD::TruthVertex* child_endVtx{};
250  if (child) {
251  child_prdVtx = child->hasProdVtx() ? child->prodVtx() : nullptr;
252  child_endVtx = child->decayVtx();
253  }
254  const xAOD::TruthVertex* parent_prdVtx{};
255  const xAOD::TruthVertex* parent_endVtx{};
256  if (parent) {
257  parent_prdVtx = parent->hasProdVtx() ? parent->prodVtx() : nullptr;
258  parent_endVtx = parent->decayVtx();
259  }
260  // V0->parent->V1-> ...->V2->child->V3
261  // V3 == V0 && V1 == V2
262  return (child_endVtx == parent_prdVtx && child_prdVtx == parent_endVtx);
263 }

◆ TruthLoopDetectionMethod3()

bool MCTruthClassifier::TruthLoopDetectionMethod3 ( const xAOD::TruthVertex childOrigVtx,
const xAOD::TruthParticle parent 
) const
private

Definition at line 266 of file MCTruthClassifierGen.cxx.

267 {
268  // Start of method 3 of protecting against loops
269  // to resolve Sherpa loop
270  const xAOD::TruthVertex* parentOrigVtx = parent->hasProdVtx() ? parent->prodVtx() : nullptr;
271  if (parentOrigVtx && HepMC::is_same_vertex(parentOrigVtx,childOrigVtx)) {
272  // The "parent" and the "child" have the same production vertex.
273  return true;
274  }
275  return false;
276  // End of method 3 of protecting against loops
277 }

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase &  )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308  {
309  // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310  // << " size: " << m_vhka.size() << endmsg;
311  for (auto &a : m_vhka) {
312  std::vector<SG::VarHandleKey*> keys = a->keys();
313  for (auto k : keys) {
314  k->setOwner(this);
315  }
316  }
317  }

Member Data Documentation

◆ m_caloExtensionTool

ToolHandle<Trk::IParticleCaloExtensionTool> MCTruthClassifier::m_caloExtensionTool {this,"ParticleCaloExtensionTool",""}
private

Definition at line 236 of file MCTruthClassifier.h.

◆ m_caloMgrKey

SG::ReadCondHandleKey<CaloDetDescrManager> MCTruthClassifier::m_caloMgrKey {this,"CaloDetDescrManager",""}
private

Definition at line 237 of file MCTruthClassifier.h.

◆ m_deltaPhiMatchCut

float MCTruthClassifier::m_deltaPhiMatchCut
private

Definition at line 264 of file MCTruthClassifier.h.

◆ m_deltaRMatchCut

float MCTruthClassifier::m_deltaRMatchCut
private

Definition at line 263 of file MCTruthClassifier.h.

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default)

Definition at line 393 of file AthCommonDataStore.h.

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default)

Definition at line 390 of file AthCommonDataStore.h.

◆ m_FwdElectronTruthExtrEtaCut

float MCTruthClassifier::m_FwdElectronTruthExtrEtaCut
private

Definition at line 242 of file MCTruthClassifier.h.

◆ m_FwdElectronTruthExtrEtaWindowCut

float MCTruthClassifier::m_FwdElectronTruthExtrEtaWindowCut
private

Definition at line 243 of file MCTruthClassifier.h.

◆ m_FwdElectronUseG4Sel

bool MCTruthClassifier::m_FwdElectronUseG4Sel
private

Definition at line 241 of file MCTruthClassifier.h.

◆ m_fwrdEledRtoTrCut

float MCTruthClassifier::m_fwrdEledRtoTrCut
private

Definition at line 250 of file MCTruthClassifier.h.

◆ m_inclG4part

bool MCTruthClassifier::m_inclG4part
private

Definition at line 255 of file MCTruthClassifier.h.

◆ m_jetPartDRMatch

float MCTruthClassifier::m_jetPartDRMatch
private

Definition at line 266 of file MCTruthClassifier.h.

◆ m_NumOfSiHitsCut

int MCTruthClassifier::m_NumOfSiHitsCut
private

Definition at line 265 of file MCTruthClassifier.h.

◆ m_partExtrConeEta

float MCTruthClassifier::m_partExtrConeEta
private

Definition at line 244 of file MCTruthClassifier.h.

◆ m_partExtrConePhi

float MCTruthClassifier::m_partExtrConePhi
private

Definition at line 245 of file MCTruthClassifier.h.

◆ m_phtClasConeEta

float MCTruthClassifier::m_phtClasConeEta
private

Definition at line 248 of file MCTruthClassifier.h.

◆ m_phtClasConePhi

float MCTruthClassifier::m_phtClasConePhi
private

Definition at line 247 of file MCTruthClassifier.h.

◆ m_phtdRtoTrCut

float MCTruthClassifier::m_phtdRtoTrCut
private

Definition at line 249 of file MCTruthClassifier.h.

◆ m_pTChargePartCut

float MCTruthClassifier::m_pTChargePartCut
private

Definition at line 253 of file MCTruthClassifier.h.

◆ m_pTNeutralPartCut

float MCTruthClassifier::m_pTNeutralPartCut
private

Definition at line 254 of file MCTruthClassifier.h.

◆ m_ROICone

bool MCTruthClassifier::m_ROICone
private

Definition at line 251 of file MCTruthClassifier.h.

◆ m_truthInConeTool

ToolHandle<xAOD::ITruthParticlesInConeTool> MCTruthClassifier::m_truthInConeTool {this,"TruthInConeTool","xAOD::TruthParticlesInConeTool/TruthParticlesInConeTool"}
private

Definition at line 239 of file MCTruthClassifier.h.

◆ m_truthLinkVecReadHandleKey

SG::ReadHandleKey<xAODTruthParticleLinkVector> MCTruthClassifier::m_truthLinkVecReadHandleKey {this,"xAODTruthLinkVector","xAODTruthLinks", "ReadHandleKey for xAODTruthParticleLinkVector"}
private

Definition at line 260 of file MCTruthClassifier.h.

◆ m_truthParticleContainerKey

SG::ReadHandleKey<xAOD::TruthParticleContainer> MCTruthClassifier::m_truthParticleContainerKey {this,"xAODTruthParticleContainerName","TruthParticles","ReadHandleKey for xAOD::TruthParticleContainer"}
private

Definition at line 233 of file MCTruthClassifier.h.

◆ m_useCaching

bool MCTruthClassifier::m_useCaching
private

Definition at line 246 of file MCTruthClassifier.h.

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


The documentation for this class was generated from the following files:
xAOD::CaloCluster_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition: CaloCluster_v1.cxx:256
xAOD::TruthVertex_v1::nOutgoingParticles
size_t nOutgoingParticles() const
Get the number of outgoing particles.
GetLCDefs::Unknown
@ Unknown
Definition: GetLCDefs.h:21
NuRMu
@ NuRMu
Definition: TruthClasses.h:73
temp
Definition: JetEventDict.h:21
IsoPhoton
@ IsoPhoton
Definition: TruthClasses.h:23
MCTruthPartClassifier::defOutComeOfMuon
ParticleOutCome defOutComeOfMuon(T thePart)
Definition: TruthClassifiers.h:213
LightBaryonPart
@ LightBaryonPart
Definition: TruthClasses.h:40
MCTruthPartClassifier::defTypeOfPhoton
ParticleType defTypeOfPhoton(ParticleOrigin PhotOrig)
Definition: TruthClassifiers.h:115
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:18
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:79
calibdata.pout
def pout(output, newline=True)
Definition: calibdata.py:129
TauLep
@ TauLep
Definition: TruthClasses.h:63
isNucleus
bool isNucleus(const T &p)
PDG rule 16 Nuclear codes are given as 10-digit numbers ±10LZZZAAAI.
Definition: AtlasPID.h:697
HepMC::is_same_vertex
bool is_same_vertex(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same vertex.
Definition: MagicNumbers.h:369
xAOD::Vertex_v1::nTrackParticles
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
Definition: Vertex_v1.cxx:270
OtherBSMParticle
@ OtherBSMParticle
Definition: TruthClasses.h:32
MCTruthClassifier::m_FwdElectronTruthExtrEtaWindowCut
float m_FwdElectronTruthExtrEtaWindowCut
Definition: MCTruthClassifier.h:243
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:407
isHeavyBoson
bool isHeavyBoson(const T &p)
APID: Additional "Heavy"/"prime" versions of W and Z bosons (Used in MCTruthClassifier)
Definition: AtlasPID.h:383
NuREle
@ NuREle
Definition: TruthClasses.h:72
Mu
@ Mu
Definition: TruthClasses.h:62
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
xAOD::TruthVertex_v1::particles_in
std::vector< const TruthParticle * > particles_in() const
Get the incoming particles.
Definition: TruthVertex_v1.cxx:60
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:558
MC::findParticleAncestors
void findParticleAncestors(T thePart, std::set< T > &allancestors)
Function to find all ancestors of the particle.
Definition: HepMCHelpers.h:156
WBosonLRSM
@ WBosonLRSM
Definition: TruthClasses.h:71
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
SingleTau
@ SingleTau
Definition: TruthClasses.h:57
isBSM
bool isBSM(const T &p)
APID: graviton and all Higgs extensions are BSM.
Definition: AtlasPID.h:836
PionDecay
@ PionDecay
Definition: TruthClasses.h:90
MCTruthClassifier::findJetConstituents
void findJetConstituents(const xAOD::Jet *, std::set< const xAOD::TruthParticle * > &constituents, bool DR) const
Definition: MCRecoToTruth.cxx:278
SG::ReadHandle< xAOD::TruthParticleContainer >
MCTruthPartClassifier::defOutComeOfTau
ParticleOutCome defOutComeOfTau(T thePart)
Definition: TruthClassifiers.h:240
MCTruthClassifier::defOrigOfElectron
MCTruthPartClassifier::ParticleOrigin defOrigOfElectron(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
Definition: MCTruthClassifierGen.cxx:280
xAOD::TrackParticle_v1::eta
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition: TrackParticle_v1.cxx:78
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:161
MCTruthClassifier::m_phtClasConeEta
float m_phtClasConeEta
Definition: MCTruthClassifier.h:248
xAOD::TrackParticle_v1::summaryValue
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
Definition: TrackParticle_v1.cxx:737
ElMagProc
@ ElMagProc
Definition: TruthClasses.h:61
xAOD::Egamma_v1::author
uint16_t author(uint16_t bitmask=EgammaParameters::AuthorALL) const
Get author.
Definition: Egamma_v1.cxx:166
MCTruthClassifier::m_partExtrConeEta
float m_partExtrConeEta
Definition: MCTruthClassifier.h:244
isNeutrino
bool isNeutrino(const T &p)
APID: the fourth generation neutrinos are neutrinos.
Definition: AtlasPID.h:209
test_pyathena.pt
pt
Definition: test_pyathena.py:11
M_PI
#define M_PI
Definition: ActiveFraction.h:11
MCTruthClassifier::TruthLoopDetectionMethod1
bool TruthLoopDetectionMethod1(const xAOD::TruthVertex *childOrigVtx, const xAOD::TruthParticle *parent) const
Definition: MCTruthClassifierGen.cxx:223
AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
StoreGateSvc_t m_evtStore
Pointer to StoreGate (event store by default)
Definition: AthCommonDataStore.h:390
AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
std::vector< SG::VarHandleKeyArray * > m_vhka
Definition: AthCommonDataStore.h:398
xAOD::CaloCluster_v1::et
double et() const
Definition: CaloCluster_v1.h:859
IsoElectron
@ IsoElectron
Definition: TruthClasses.h:11
SingleElec
@ SingleElec
Definition: TruthClasses.h:54
PhotonConv
@ PhotonConv
Definition: TruthClasses.h:59
MCTruthClassifier::m_caloExtensionTool
ToolHandle< Trk::IParticleCaloExtensionTool > m_caloExtensionTool
Definition: MCTruthClassifier.h:236
CharmedMesonPart
@ CharmedMesonPart
Definition: TruthClasses.h:36
ISRPhot
@ ISRPhot
Definition: TruthClasses.h:95
xAOD::numberOfPixelHits
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Definition: TrackingPrimitives.h:260
xAOD::Electron_v1::trackParticle
const xAOD::TrackParticle * trackParticle(size_t index=0) const
Pointer to the xAOD::TrackParticle/s that match the electron candidate.
Definition: Electron_v1.cxx:55
PromptPhot
@ PromptPhot
Definition: TruthClasses.h:93
xAOD::CaloCluster_v1::phiBE
float phiBE(const unsigned layer) const
Get the phi in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:634
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:9
MCTruthPartClassifier::defTypeOfElectron
ParticleType defTypeOfElectron(ParticleOrigin EleOrig, bool isPrompt)
Definition: TruthClassifiers.h:61
BottomMesonPart
@ BottomMesonPart
Definition: TruthClasses.h:34
NuRTau
@ NuRTau
Definition: TruthClasses.h:74
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
MCTruthClassifier::m_pTNeutralPartCut
float m_pTNeutralPartCut
Definition: MCTruthClassifier.h:254
xAOD::EgammaParameters::AuthorFwdElectron
const uint16_t AuthorFwdElectron
Electron reconstructed by the Forward cluster-based algorithm.
Definition: EgammaDefs.h:30
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
UnknownMuon
@ UnknownMuon
Definition: TruthClasses.h:14
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:560
ZBoson
@ ZBoson
Definition: TruthClasses.h:67
UnknownTau
@ UnknownTau
Definition: TruthClasses.h:18
Hadron
@ Hadron
Definition: TruthClasses.h:26
xAOD::TruthParticle_v1::pdg_id
int pdg_id() const
PDG ID code.
Definition: TruthParticle_v1.h:52
HepMC::is_same_particle
bool is_same_particle(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same particle.
Definition: MagicNumbers.h:366
StrangeMesonPart
@ StrangeMesonPart
Definition: TruthClasses.h:41
MCTruthClassifier::m_truthParticleContainerKey
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthParticleContainerKey
Definition: MCTruthClassifier.h:233
WBoson
@ WBoson
Definition: TruthClasses.h:66
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
isSMLepton
bool isSMLepton(const T &p)
APID: the fourth generation leptons are not standard model leptons.
Definition: AtlasPID.h:191
isSMQuark
bool isSMQuark(const T &p)
Definition: AtlasPID.h:169
isGluon
bool isGluon(const T &p)
Definition: AtlasPID.h:370
SG::VarHandleKeyArray::setOwner
virtual void setOwner(IDataHandleHolder *o)=0
FSRPhot
@ FSRPhot
Definition: TruthClasses.h:96
isHiggs
bool isHiggs(const T &p)
APID: HIGGS boson is only one particle.
Definition: AtlasPID.h:387
IDTPMcnv.htype
htype
Definition: IDTPMcnv.py:29
NuclFrag
@ NuclFrag
Definition: TruthClasses.h:28
BBbarMesonPart
@ BBbarMesonPart
Definition: TruthClasses.h:33
MCTruthPartClassifier::defTypeOfMuon
ParticleType defTypeOfMuon(ParticleOrigin MuOrig, bool isPrompt)
Definition: TruthClassifiers.h:80
NonDefined
@ NonDefined
Definition: TruthClasses.h:52
MCTruthClassifier::m_NumOfSiHitsCut
int m_NumOfSiHitsCut
Definition: MCTruthClassifier.h:265
HiggsMSSM
@ HiggsMSSM
Definition: TruthClasses.h:69
xAOD::CaloCluster_v1::etaBE
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:628
MC::isPhysical
bool isPhysical(const T &p)
Identify if the particle is physical, i.e. is stable or decayed.
Definition: HepMCHelpers.h:51
CCbarMesonPart
@ CCbarMesonPart
Definition: TruthClasses.h:35
AthCommonDataStore::declareGaudiProperty
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>
Definition: AthCommonDataStore.h:156
MCTruthClassifier::m_jetPartDRMatch
float m_jetPartDRMatch
Definition: MCTruthClassifier.h:266
isQuark
bool isQuark(const T &p)
PDG rule 2: Quarks and leptons are numbered consecutively starting from 1 and 11 respectively; to do ...
Definition: AtlasPID.h:164
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
Neutrino
@ Neutrino
Definition: TruthClasses.h:27
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:62
xAOD::CaloCluster_v1::inEndcap
bool inEndcap() const
Returns true if at least one clustered cell in the endcap.
Definition: CaloCluster_v1.h:892
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
MCTruthClassifier::m_FwdElectronTruthExtrEtaCut
float m_FwdElectronTruthExtrEtaCut
Definition: MCTruthClassifier.h:242
HepMC::is_same_generator_particle
bool is_same_generator_particle(const T1 &p1, const T2 &p2)
Method to establish if two particles in the GenEvent actually represent the same generated particle.
Definition: MagicNumbers.h:363
columnar::ContainerId::particle0
particle particle0
Definition: ParticleDef.h:22
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
AthCommonDataStore
Definition: AthCommonDataStore.h:52
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:116
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
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
CaloSampling::CaloSample
CaloSample
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:22
TruthLink_t
ElementLink< xAOD::TruthParticleContainer > TruthLink_t
Definition: TauxAODHelpers.cxx:7
MC::findMatching
T findMatching(C TruthContainer, T p)
Function to find a particle in container.
Definition: HepMCHelpers.h:133
UnknownElectron
@ UnknownElectron
Definition: TruthClasses.h:10
MCTruthClassifier::defOrigOfMuon
MCTruthPartClassifier::ParticleOrigin defOrigOfMuon(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
Definition: MCTruthClassifierGen.cxx:556
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
checkxAOD.frac
frac
Definition: Tools/PyUtils/bin/checkxAOD.py:259
ParticleOrigin
ParticleOrigin
Definition: TruthClasses.h:51
PiZero
@ PiZero
Definition: TruthClasses.h:98
AthCommonDataStore::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Definition: AthCommonDataStore.h:145
xAOD::EgammaHelpers::isElectron
bool isElectron(const xAOD::Egamma *eg)
is the object an electron (not Fwd)
Definition: EgammaxAODHelpers.cxx:12
MultiBoson
@ MultiBoson
Definition: TruthClasses.h:101
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
TauGNNUtils::Variables::Track::dPhi
bool dPhi(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:549
xAOD::Egamma_v1::caloCluster
const xAOD::CaloCluster * caloCluster(size_t index=0) const
Pointer to the xAOD::CaloCluster/s that define the electron candidate.
Definition: Egamma_v1.cxx:388
xAOD::TruthParticle_v1::hasProdVtx
bool hasProdVtx() const
Check for a production vertex on this particle.
Definition: TruthParticle_v1.cxx:69
CalibDbCompareRT.dummy
dummy
Definition: CalibDbCompareRT.py:59
MCTruthClassifier::defOrigOfNeutrino
MCTruthPartClassifier::ParticleOrigin defOrigOfNeutrino(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
Definition: MCTruthClassifierGen.cxx:1210
xAOD::CaloCluster_v1::inBarrel
bool inBarrel() const
Returns true if at least one clustered cell in the barrel.
Definition: CaloCluster_v1.h:887
test_pyathena.parent
parent
Definition: test_pyathena.py:15
DiBoson
@ DiBoson
Definition: TruthClasses.h:99
IsoTau
@ IsoTau
Definition: TruthClasses.h:19
MCTruthClassifier::egammaClusMatch
virtual const xAOD::TruthParticle * egammaClusMatch(const xAOD::CaloCluster *, bool, MCTruthPartClassifier::Info *info) const override final
Definition: MCTruthClassifierAthena.cxx:44
LQ
@ LQ
Definition: TruthClasses.h:75
LightMesonPart
@ LightMesonPart
Definition: TruthClasses.h:42
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
JPsi
@ JPsi
Definition: TruthClasses.h:84
MSG::name
const std::string & name(Level lvl)
Convenience function for translating message levels to strings.
Definition: MsgLevel.cxx:19
MCTruthClassifier::m_truthLinkVecReadHandleKey
SG::ReadHandleKey< xAODTruthParticleLinkVector > m_truthLinkVecReadHandleKey
Definition: MCTruthClassifier.h:260
MC::findParticleStableDescendants
void findParticleStableDescendants(T thePart, std::set< T > &allstabledescendants)
Function to get the particle stable MC daughters.
Definition: HepMCHelpers.h:168
MC::findMother
T findMother(T thePart)
Function to get a mother of particle. MCTruthClassifier legacy.
Definition: HepMCHelpers.h:100
xAOD::Vertex_v1::trackParticle
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
Definition: Vertex_v1.cxx:249
AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
StoreGateSvc_t m_detStore
Pointer to StoreGate (detector store by default)
Definition: AthCommonDataStore.h:393
MCTruthClassifier::TruthLoopDetectionMethod2
bool TruthLoopDetectionMethod2(const xAOD::TruthParticle *child, const xAOD::TruthParticle *parent) const
Definition: MCTruthClassifierGen.cxx:244
xAOD::TruthVertex_v1::incomingParticle
const TruthParticle_v1 * incomingParticle(size_t index) const
Get one of the incoming particles.
Definition: TruthVertex_v1.cxx:70
IsoMuon
@ IsoMuon
Definition: TruthClasses.h:15
StrangeBaryonPart
@ StrangeBaryonPart
Definition: TruthClasses.h:39
MCTruthClassifier::m_phtClasConePhi
float m_phtClasConePhi
Definition: MCTruthClassifier.h:247
MCTruthClassifier::m_partExtrConePhi
float m_partExtrConePhi
Definition: MCTruthClassifier.h:245
CharmedBaryonPart
@ CharmedBaryonPart
Definition: TruthClasses.h:38
MCTruthPartClassifier::defTypeOfHadron
ParticleType defTypeOfHadron(int pdg)
Definition: TruthClassifiers.h:46
columnar::final
CM final
Definition: ColumnAccessor.h:106
isSUSY
bool isSUSY(const T &p)
Definition: AtlasPID.h:620
LJet
@ LJet
Definition: TruthClasses.h:45
MCTruthClassifier::defOrigOfPhoton
MCTruthPartClassifier::ParticleOrigin defOrigOfPhoton(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, bool &isPrompt, MCTruthPartClassifier::Info &info) const
Definition: MCTruthClassifierGen.cxx:947
MCTruthClassifier::genPartToCalo
bool genPartToCalo(const EventContext &ctx, const xAOD::CaloCluster *clus, const xAOD::TruthParticle *thePart, bool isFwrdEle, double &dRmatch, bool &isNarrowCone, const CaloDetDescrManager &caloDDMgr) const
Definition: MCTruthClassifierAthena.cxx:237
isTau
bool isTau(const T &p)
Definition: AtlasPID.h:205
MCTruthClassifier::TruthLoopDetectionMethod3
bool TruthLoopDetectionMethod3(const xAOD::TruthVertex *childOrigVtx, const xAOD::TruthParticle *parent) const
Definition: MCTruthClassifierGen.cxx:266
MC::Pythia8::isConditionA
bool isConditionA(const T &p)
To be understood.
Definition: HepMCHelpers.h:23
SG::VarHandleKeyArray::renounce
virtual void renounce()=0
SG::HandleClassifier::type
std::conditional< std::is_base_of< SG::VarHandleKeyArray, T >::value, VarHandleKeyArrayType, type2 >::type type
Definition: HandleClassifier.h:54
xAOD::TruthParticle_v1::decayVtx
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
xAOD::TruthParticle_v1::prodVtx
const TruthVertex_v1 * prodVtx() const
The production vertex of this particle.
Definition: TruthParticle_v1.cxx:75
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
BJet
@ BJet
Definition: TruthClasses.h:43
xAOD::TruthVertex_v1
Class describing a truth vertex in the MC record.
Definition: TruthVertex_v1.h:37
SinglePhot
@ SinglePhot
Definition: TruthClasses.h:56
MCTruthPartClassifier::defOutComeOfElectron
ParticleOutCome defOutComeOfElectron(T thePart)
Definition: TruthClassifiers.h:189
BottomBaryonPart
@ BottomBaryonPart
Definition: TruthClasses.h:37
merge_scale_histograms.doc
string doc
Definition: merge_scale_histograms.py:9
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
SUSY
@ SUSY
Definition: TruthClasses.h:77
HeavyBoson
@ HeavyBoson
Definition: TruthClasses.h:70
MCTruthClassifier::m_inclG4part
bool m_inclG4part
Definition: MCTruthClassifier.h:255
isHadron
bool isHadron(const T &p)
Definition: AtlasPID.h:348
isNeutrinoRH
bool isNeutrinoRH(const T &p)
PDG Rule 12: APID: Helper function for right-handed neutrino states These are generator defined PDG I...
Definition: AtlasPID.h:417
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
xAOD::TruthVertex_v1::particles_out
std::vector< const TruthParticle * > particles_out() const
Get the outgoing particles.
Definition: TruthVertex_v1.cxx:65
xAOD::TruthParticle_v1::eta
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition: TruthParticle_v1.cxx:169
UndrPhot
@ UndrPhot
Definition: TruthClasses.h:94
NucReact
@ NucReact
Definition: TruthClasses.h:97
NonInteract
@ NonInteract
Definition: TruthClasses.h:110
QuarkWeakDec
@ QuarkWeakDec
Definition: TruthClasses.h:65
MCTruthClassifier::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Definition: MCTruthClassifier.h:237
isW
bool isW(const T &p)
Definition: AtlasPID.h:379
xAOD::TruthParticle_v1::status
int status() const
Status code.
MC::isStable
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
Definition: HepMCHelpers.h:45
xAOD::CaloCluster_v1::eSample
float eSample(const CaloSample sampling) const
Definition: CaloCluster_v1.cxx:514
SUSYParticle
@ SUSYParticle
Definition: TruthClasses.h:31
a
TList * a
Definition: liststreamerinfos.cxx:10
isTop
bool isTop(const T &p)
Definition: AtlasPID.h:182
h
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
Amg::intersect
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
Definition: GeoPrimitivesHelpers.h:347
xAOD::TruthParticle_v1::phi
virtual double phi() const override final
The azimuthal angle ( ) of the particle.
Definition: TruthParticle_v1.cxx:176
MCTruthPartClassifier::isPrompt
int isPrompt(const unsigned int classify, bool allow_prompt_tau_decays=true)
Definition: TruthClassifiers.h:180
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::TruthVertex_v1::nIncomingParticles
size_t nIncomingParticles() const
Get the number of incoming particles.
MC::isDecayed
bool isDecayed(const T &p)
Identify if the particle decayed.
Definition: HepMCHelpers.h:42
xAOD::EgammaHelpers::isPhoton
bool isPhoton(const xAOD::Egamma *eg)
is the object a photon
Definition: EgammaxAODHelpers.cxx:21
MC::isBeam
bool isBeam(const T &p)
Identify if the particle is beam particle.
Definition: HepMCHelpers.h:39
MCTruthClassifier::m_deltaRMatchCut
float m_deltaRMatchCut
Definition: MCTruthClassifier.h:263
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
MCTruthPartClassifier::convHadronTypeToOrig
ParticleOrigin convHadronTypeToOrig(ParticleType pType, int motherPDG)
Definition: TruthClassifiers.h:15
NonPrimary
@ NonPrimary
Definition: TruthClasses.h:29
Higgs
@ Higgs
Definition: TruthClasses.h:68
MCTruthClassifier::m_deltaPhiMatchCut
float m_deltaPhiMatchCut
Definition: MCTruthClassifier.h:264
MCTruthPartClassifier::defJetOrig
ParticleOrigin defJetOrig(const T &allJetMothers)
Definition: TruthClassifiers.h:131
isSMNeutrino
bool isSMNeutrino(const T &p)
Definition: AtlasPID.h:212
SG::VarHandleBase::vhKey
SG::VarHandleKey & vhKey()
Return a non-const reference to the HandleKey.
Definition: StoreGate/src/VarHandleBase.cxx:629
extractSporadic.q
list q
Definition: extractSporadic.py:97
xAOD::TruthParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TruthParticle_v1.cxx:161
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:269
MCTruthClassifier::m_pTChargePartCut
float m_pTChargePartCut
Definition: MCTruthClassifier.h:253
SingleMuon
@ SingleMuon
Definition: TruthClasses.h:55
CaloCell_ID_FCS::FCAL2
@ FCAL2
Definition: FastCaloSim_CaloCell_ID.h:42
MCTruthPartClassifier::defTypeOfTau
ParticleType defTypeOfTau(ParticleOrigin TauOrig)
Definition: TruthClassifiers.h:98
xAOD::JetConstituentVector
A vector of jet constituents at the scale used during jet finding.
Definition: JetConstituentVector.h:117
UnknownJet
@ UnknownJet
Definition: TruthClasses.h:48
OtherBSM
@ OtherBSM
Definition: TruthClasses.h:78
MCTruthClassifier::m_truthInConeTool
ToolHandle< xAOD::ITruthParticlesInConeTool > m_truthInConeTool
Definition: MCTruthClassifier.h:239
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:801
DalitzDec
@ DalitzDec
Definition: TruthClasses.h:60
top
@ top
Definition: TruthClasses.h:64
MCTruthPartClassifier::defOutComeOfPhoton
ParticleOutCome defOutComeOfPhoton(T thePart)
Definition: TruthClassifiers.h:268
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
PowhegControl_ttFCNC_NLO.params
params
Definition: PowhegControl_ttFCNC_NLO.py:226
CJet
@ CJet
Definition: TruthClasses.h:44
KaonDecay
@ KaonDecay
Definition: TruthClasses.h:91
xAOD::TruthParticle_v1::pdgId
int pdgId() const
PDG ID code.
MCTruthClassifier::defOrigOfTau
MCTruthPartClassifier::ParticleOrigin defOrigOfTau(const xAOD::TruthParticleContainer &xTruthParticleContainer, const xAOD::TruthParticle *, int motherPDG, MCTruthPartClassifier::Info &info) const
Definition: MCTruthClassifierGen.cxx:774
TauGNNUtils::Variables::Track::dEta
bool dEta(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:538
set_intersection
Set * set_intersection(Set *set1, Set *set2)
Perform an intersection of two sets.
MCTruthClassifier::particleTruthClassifier
virtual std::pair< MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin > particleTruthClassifier(const xAOD::TruthParticle *, MCTruthPartClassifier::Info *info=nullptr) const override final
Definition: MCTruthClassifierGen.cxx:75
MCTruthClassifier::m_FwdElectronUseG4Sel
bool m_FwdElectronUseG4Sel
Definition: MCTruthClassifier.h:241
SG::DataProxy
Definition: DataProxy.h:45
ParticleType
ParticleType
Definition: TruthClasses.h:8
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:51
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
MCTruthClassifier::m_fwrdEledRtoTrCut
float m_fwrdEledRtoTrCut
Definition: MCTruthClassifier.h:250
MCTruthPartClassifier::Info
Definition: IMCTruthClassifier.h:49
Neutrino
Definition: Neutrino.h:33
xAOD::Photon_v1::vertex
const xAOD::Vertex * vertex(size_t index=0) const
Pointer to the xAOD::Vertex/es that match the photon candidate.
Definition: Photon_v1.cxx:46
python.ParticleTypeUtil.info
def info
Definition: ParticleTypeUtil.py:87
xAOD::TruthVertex_v1::outgoingParticle
const TruthParticle_v1 * outgoingParticle(size_t index) const
Get one of the outgoing particles.
Definition: TruthVertex_v1.cxx:120
MCTruthClassifier::detEta
double detEta(double x, double y) const
Definition: MCTruthClassifier.h:169
MCTruthClassifier::m_ROICone
bool m_ROICone
Definition: MCTruthClassifier.h:251
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56
xAOD::TruthParticle_v1::charge
double charge() const
Physical charge.
UnknownPhoton
@ UnknownPhoton
Definition: TruthClasses.h:22
isMSSMHiggs
bool isMSSMHiggs(const T &p)
APID: Additional Higgs bosons for MSSM (Used in MCTruthClassifier)
Definition: AtlasPID.h:391
xAOD::TrackParticle_v1::phi
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
fitman.k
k
Definition: fitman.py:528
BremPhot
@ BremPhot
Definition: TruthClasses.h:92
GenParticle
@ GenParticle
Definition: TruthClasses.h:30
MC::isHardScatteringVertex
bool isHardScatteringVertex(T pVert)
Function to classify the vertex as hard scattering vertex.
Definition: HepMCHelpers.h:184
MCTruthClassifier::m_phtdRtoTrCut
float m_phtdRtoTrCut
Definition: MCTruthClassifier.h:249
MCTruthClassifier::detPhi
double detPhi(double x, double y) const
Definition: MCTruthClassifier.h:170
isMuon
bool isMuon(const T &p)
Definition: AtlasPID.h:202
isLeptoQuark
bool isLeptoQuark(const T &p)
PDG rule 11c: “One-of-a-kind” exotic particles are assigned numbers in the range 41–80.
Definition: AtlasPID.h:405
MCTruthClassifier::getGenPart
virtual const xAOD::TruthParticle * getGenPart(const xAOD::TrackParticle *, MCTruthPartClassifier::Info *info=nullptr) const override final
Definition: MCRecoToTruth.cxx:181