ATLAS Offline Software
PhotonTruthTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // $Id$
14 #include "PhotonTruthTool.h"
15 #include "xAODEgamma/Photon.h"
18 #include <vector>
19 #include <cmath>
20 
21 namespace D3PD {
22 
23 
31  const std::string& name,
32  const IInterface* parent)
33  : AthAlgTool (type, name, parent),
34  m_classifier ("MCTruthClassifier")
35 {
36  declareProperty ("Classifier", m_classifier, "Classifier tool instance.");
37  declareProperty ("ZTruthConv", m_zTruthConv = 50e3);
38  declareProperty ("RTruthConv", m_rTruthConv = 800);
39  declareProperty ("UseG4Particles", m_useG4Particles = false);
40 }
41 
42 
47 {
49  CHECK( m_classifier.retrieve() );
50  return StatusCode::SUCCESS;
51 }
52 
53 
58 PhotonTruthTool::queryInterface( const InterfaceID& riid, void** ppvIf )
59 {
60  if ( riid == PhotonTruthTool::interfaceID() ) {
61  *ppvIf = static_cast<PhotonTruthTool*> (this);
62  addRef();
63  return StatusCode::SUCCESS;
64  }
65 
66  return AthAlgTool::queryInterface( riid, ppvIf );
67 }
68 
69 
77 {
79  m_classifier->particleTruthClassifier (&g, &info);
80  return info.genPart;
81 }
82 
83 
91 bool
93  float& RconvMC,
94  float& ZconvMC) const
95 {
96  RconvMC = +9.999e+10 ;
97  ZconvMC = +9.999e+10 ;
98  if (!truePart) return false;
99 
100  const xAOD::TruthVertex* v = truePart->decayVtx();
101  if (!v || v->nOutgoingParticles() < 2)
102  return false;
103 
104  int pdgId = truePart->pdgId();
105 
106  RconvMC = v->perp();
107  ZconvMC = v->z();
108 
109  bool OKint = ( RconvMC < m_rTruthConv ) && ( fabs(ZconvMC) < m_zTruthConv );
110 
111  if ( pdgId == 22 ) { // photon
112  if ( v->nOutgoingParticles() == 2 ) {
113  int pdgChild[2] = {0};
114  for ( unsigned u=0; u<2 ; ++u) {
115  const xAOD::TruthParticle* p = v->outgoingParticle(u);
116  if (p)
117  pdgChild[u] = p->pdgId();
118  }
119  if ( pdgChild[0]+pdgChild[1]==0 && pdgChild[0]*pdgChild[1]==-121 ) {
120  // gamma -> e+e-
121  return OKint ;
122  }
123  }
124  }
125  else if ( std::abs(pdgId) == 11 ) { // e+/e-
126  v = truePart->prodVtx();
127  if ( v->nIncomingParticles()==1 && v->nOutgoingParticles()==2 ) {
128  int pdgBrother[2] = {0};
129  for ( unsigned u=0 ; u<2 ; ++u ) {
130  const xAOD::TruthParticle* p = v->outgoingParticle(u);
131  if (p)
132  pdgBrother[u] = p->pdgId();
133  }
134  if ( pdgBrother[0]+pdgBrother[1]==(22+pdgId) &&
135  pdgBrother[0]*pdgBrother[1]==(22*pdgId) )
136  {
137  // e(+/-) -> e(+/-)gamma
138  return OKint ;
139  }
140  }
141  }
142  return false ;
143 }
144 
145 
150  (const xAOD::TruthParticle* truePart) const
151 {
152  return ( isFinalStatePhotonMC(truePart) && isPromptParticleMC(truePart) ) ;
153 }
154 
155 
160  (const xAOD::TruthParticle* truePart) const
161 {
162  if ( truePart == 0 ) return false ;
163  const std::vector<const xAOD::TruthParticle*> mothers =
164  getMothers(truePart);
165  unsigned nmothers = mothers.size() ;
166  if ( nmothers == 0 ) {
167  // particles with NO mother are NEVER classified as PROMPT:
168  return false ;
169  }
170  else if ( nmothers == 1 ) {
171  // particles with ONE mother are classified as PROMPT if coming
172  // from non-QCD-boson decay:
173  // (including exotics like heavy bosons, MSSM Higgs, graviton)
174  int aPdgMother = abs(mothers[0]->pdgId());
175  return (( aPdgMother>=23 && aPdgMother<=39 ) || aPdgMother==5000039 ) ;
176  }
177  else {
178  // particles with more mothers are classified as PROMPT
179  // if they come from at least 1 parton:
180  // (is this sensible?)
181  int nParentPartons = 0 ;
182  for ( unsigned u=0 ; u<nmothers ; ++u ) {
183  int pdgMother = mothers[u]->pdgId() ;
184  if ( pdgMother==21 || ( std::abs(pdgMother)<7 && pdgMother!=0 ) )
185  ++nParentPartons ;
186  }
187  return ( nParentPartons >= 1 ) ;
188  }
189 }
190 
191 
196  (const xAOD::TruthParticle* truePart) const
197 {
198  if ( ! isFinalStatePhotonMC(truePart) ) return false ;
199  const std::vector<const xAOD::TruthParticle*> mothers =
200  getMothers(truePart) ;
201  if ( mothers.size() != 1 ) return false ;
202  int pdgMother = mothers[0]->pdgId() ;
203  return ( pdgMother==21 || ( std::abs(pdgMother)<7 && pdgMother!=0 ) ) ;
204 }
205 
206 
211  (const xAOD::TruthParticle* truePart) const
212 {
213  return ( isFinalState(truePart) && MC::isPhoton(truePart) ) ;
214 }
215 
216 
220 bool
222 {
223  if ( truePart == nullptr ) return false;
224  if ( !MC::isStable(truePart)) return false;
225  if ( !m_useG4Particles ) return ( !HepMC::is_simulation_particle(truePart) );
226  // if it is a photon, keep it regardless of its Geant interaction
227  if ( MC::isPhoton(truePart) ) return true ;
228  // reject Geant electron from conversion
229  if ( MC::isElectron(truePart) && HepMC::is_simulation_particle(truePart) ) {
230  const xAOD::TruthParticle* mother = getMother(truePart) ;
231  if ( mother!=0 && MC::isPhoton(mother) ) return false ;
232  }
233 
234  // reject particles interacted in detector
235  const xAOD::TruthVertex* v = truePart->decayVtx();
236  if (!v) return false;// should never happen, but just in case...
237  if ( v->nOutgoingParticles()>0 ) {
238  if ( v->perp()<m_rTruthConv
239  && fabs(v->z())<m_zTruthConv ) return false ;
240  }
241  return true ;
242 }
243 
244 
248 const xAOD::TruthVertex*
250 {
251  const xAOD::TruthVertex* v = p->prodVtx();
252 
253  // if mother is a duplicate, try climbing up the tree by one step...
254  while (v && v->nIncomingParticles() == 1 &&
255  v->incomingParticle(0)->pdgId() == p->pdgId())
256  {
257  p = v->incomingParticle(0);
258  v = p->prodVtx();
259  }
260 
261  return v;
262 }
263 
264 
268 const xAOD::TruthParticle*
270 {
271  const xAOD::TruthVertex* v = getMotherVert (p);
272 
273  if (!v || v->nIncomingParticles() == 0)
274  return 0;
275 
276  return v->incomingParticle(0);
277 }
278 
279 
283 std::vector<const xAOD::TruthParticle*>
285 {
286  std::vector<const xAOD::TruthParticle*> out;
287  const xAOD::TruthVertex* v = getMotherVert (p);
288 
289  if (v) {
290  int n = v->nIncomingParticles();
291  out.reserve (n);
292  for (int i = 0; i < n; i++)
293  out.push_back (v->incomingParticle(i));
294  }
295 
296  return out;
297 }
298 
299 
300 } // namespace D3PD
grepfile.info
info
Definition: grepfile.py:38
D3PD::PhotonTruthTool
Definition: PhotonTruthTool.h:40
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
D3PD::PhotonTruthTool::getMothers
std::vector< const xAOD::TruthParticle * > getMothers(const xAOD::TruthParticle *p) const
Return list of mother particles of p.
Definition: PhotonTruthTool.cxx:284
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
initialize
void initialize()
Definition: run_EoverP.cxx:894
D3PD::PhotonTruthTool::getMotherVert
const xAOD::TruthVertex * getMotherVert(const xAOD::TruthParticle *p) const
Get the mother vertex for p.
Definition: PhotonTruthTool.cxx:249
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
D3PD::PhotonTruthTool::isQuarkBremMC
bool isQuarkBremMC(const xAOD::TruthParticle *truePart) const
Test for a brem.
Definition: PhotonTruthTool.cxx:196
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:83
PowhegPy8EG_H2a.pdgId
dictionary pdgId
Definition: PowhegPy8EG_H2a.py:128
D3PD::PhotonTruthTool::isPromptParticleMC
bool isPromptParticleMC(const xAOD::TruthParticle *truePart) const
Test for a prompt particle.
Definition: PhotonTruthTool.cxx:160
D3PD::PhotonTruthTool::getMother
const xAOD::TruthParticle * getMother(const xAOD::TruthParticle *p) const
Get the (first) mother particle of p.
Definition: PhotonTruthTool.cxx:269
D3PD
Block filler tool for noisy FEB information.
Definition: InnerDetector/InDetMonitoring/InDetGlobalMonitoring/macros/EnhancedPrimaryVertexMonitoring/TrigD3PD/ChainGroup.h:21
CheckAppliedSFs.e3
e3
Definition: CheckAppliedSFs.py:264
PhotonTruthTool.h
Helpers to categorize photon TruthParticle's.
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:299
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
Photon.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
xAOD::EgammaHelpers::isElectron
bool isElectron(const xAOD::Egamma *eg)
is the object an electron (not Fwd)
Definition: EgammaxAODHelpers.cxx:13
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:41
D3PD::PhotonTruthTool::getMCConv
bool getMCConv(const xAOD::TruthParticle *truePart, float &RconvMC, float &ZconvMC) const
Check a truth particle for a conversion.
Definition: PhotonTruthTool.cxx:92
test_pyathena.parent
parent
Definition: test_pyathena.py:15
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
D3PD::PhotonTruthTool::queryInterface
virtual StatusCode queryInterface(const InterfaceID &riid, void **ppvIf)
Standard Gaudi queryInterface method.
Definition: PhotonTruthTool.cxx:58
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:80
xAOD::TruthVertex_v1
Class describing a truth vertex in the MC record.
Definition: TruthVertex_v1.h:41
D3PD::PhotonTruthTool::initialize
virtual StatusCode initialize()
Standard Gaudi initialize method.
Definition: PhotonTruthTool.cxx:46
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
errorcheck.h
Helpers for checking error return status codes and reporting errors.
D3PD::PhotonTruthTool::isFinalState
bool isFinalState(const xAOD::TruthParticle *truePart) const
Test for a final-state particle.
Definition: PhotonTruthTool.cxx:221
python.PyAthena.v
v
Definition: PyAthena.py:157
MC::isStable
bool isStable(const T &p)
Definition: HepMCHelpers.h:30
xAOD::Photon_v1
Definition: Photon_v1.h:37
D3PD::PhotonTruthTool::interfaceID
static const InterfaceID & interfaceID()
Gaudi interface definition.
Definition: PhotonTruthTool.h:43
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
xAOD::EgammaHelpers::isPhoton
bool isPhoton(const xAOD::Egamma *eg)
is the object a photon
Definition: EgammaxAODHelpers.cxx:22
D3PD::PhotonTruthTool::m_useG4Particles
bool m_useG4Particles
Property.
Definition: PhotonTruthTool.h:133
D3PD::PhotonTruthTool::m_zTruthConv
float m_zTruthConv
Property: Conversion vertex z cut.
Definition: PhotonTruthTool.h:127
D3PD::PhotonTruthTool::isFinalStatePhotonMC
bool isFinalStatePhotonMC(const xAOD::TruthParticle *truePart) const
Test for a final-state photon.
Definition: PhotonTruthTool.cxx:211
D3PD::PhotonTruthTool::m_classifier
ToolHandle< IMCTruthClassifier > m_classifier
Property: classifier tool.
Definition: PhotonTruthTool.h:124
D3PD::PhotonTruthTool::PhotonTruthTool
PhotonTruthTool(const std::string &type, const std::string &name, const IInterface *parent)
Standard Gaudi tool constructor.
Definition: PhotonTruthTool.cxx:30
AthAlgTool
Definition: AthAlgTool.h:26
xAOD::TruthParticle_v1::pdgId
int pdgId() const
PDG ID code.
MCTruthPartClassifier::Info
Definition: IMCTruthClassifier.h:49
D3PD::PhotonTruthTool::toTruthParticle
const xAOD::TruthParticle * toTruthParticle(const xAOD::Photon &g) const
Go from a photon to a matching TruthParticle.
Definition: PhotonTruthTool.cxx:76
D3PD::PhotonTruthTool::m_rTruthConv
float m_rTruthConv
Property: Conversion vertex r cut.
Definition: PhotonTruthTool.h:130
HepMCHelpers.h
D3PD::PhotonTruthTool::isPromptPhotonMC
bool isPromptPhotonMC(const xAOD::TruthParticle *truePart) const
Test for a prompt photon.
Definition: PhotonTruthTool.cxx:150