Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TruthTrackerHepMC.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TruthTrackerHepMC.C
1 #include "TruthTrackerHepMC.h"
2 #include "DISKinematicsReco.h"
3 
4 /* ROOT includes */
5 #include <TDatabasePDG.h>
6 
7 /* STL includes */
8 #include <iostream>
9 
10 using namespace std;
11 
12 
14 {
15 
16 }
17 
18 
19 HepMC::GenParticle* TruthTrackerHepMC::FindParticle( int pid )
20 {
21 
22  HepMC::GenParticle *particle = NULL;
23 
24  /* --> Loop over all truth events in event generator collection */
25  for (PHHepMCGenEventMap::ReverseIter iter = _genevtmap->rbegin(); iter != _genevtmap->rend(); ++iter)
26  {
27  PHHepMCGenEvent *genevt = iter->second;
28  HepMC::GenEvent *theEvent = genevt->getEvent();
29 
30  /* check if GenEvent object found */
31  if ( !theEvent )
32  {
33  cout << "ERROR: Missing GenEvent!" << endl;
34  return NULL;
35  }
36 
37  /* Loop over all truth particles in event generator collection */
38  for ( HepMC::GenEvent::particle_iterator p = theEvent->particles_begin();
39  p != theEvent->particles_end(); ++p ) {
40 
41  /* check particle ID */
42  if ( (*p)->pdg_id() == pid )
43  {
44  particle = (*p);
45 
46  /* end loop if matching particle found */
47  break;
48  } // end if matching PID //
49  } // end loop over all particles in event //
50  }// end loop over genevtmap //
51 
52  return particle;
53 }
54 
55 
56 HepMC::GenParticle* TruthTrackerHepMC::FindDaughterParticle( int pid, HepMC::GenParticle* particle_mother )
57 {
58  HepMC::GenParticle* particle_daughter = NULL;
59 
60  /*Check if particle mother is found*/
61  if(!particle_mother);
62  /* Where does mother particle end (=decay)? */
63  else if ( particle_mother->end_vertex() )
64  {
65  /* Loop over child particles at mother's end vertex */
66  for ( HepMC::GenVertex::particle_iterator child
67  = particle_mother->end_vertex()->
68  particles_begin(HepMC::children);
69  child != particle_mother->end_vertex()->
70  particles_end(HepMC::children);
71  ++child )
72  {
73 
74  /* Has child correct PDG code? */
75  if ( (*child)->pdg_id() == pid )
76  {
77  particle_daughter = (*child);
78  UpdateFinalStateParticle( particle_daughter );
79  }
80  }
81  }
82 
83  return particle_daughter;
84 }
85 
86 
87 HepMC::GenParticle* TruthTrackerHepMC::FindBeamLepton( )
88 {
89  HepMC::GenParticle *particle = NULL;
90 
91  int embedding_id = 1;
92  PHHepMCGenEvent *theEvent = _genevtmap->get(embedding_id);
93 
94  /* check if GenEvent object found */
95  if ( !theEvent )
96  {
97  cout << "ERROR: Missing GenEvent!" << endl;
98  return NULL;
99  }
100 
101  HepMC::GenEvent* genEvent = theEvent->getEvent();
102  /* Find beam lepton */
103  particle = genEvent->beam_particles().first;
104  return particle;
105 }
106 
107 
108 HepMC::GenParticle* TruthTrackerHepMC::FindBeamHadron( )
109 {
110  HepMC::GenParticle *particle = NULL;
111 
112  int embedding_id = 1;
113  PHHepMCGenEvent *theEvent = _genevtmap->get(embedding_id);
114 
115  /* check if GenEvent object found */
116  if ( !theEvent )
117  {
118  cout << "ERROR: Missing GenEvent!" << endl;
119  return NULL;
120  }
121 
122  HepMC::GenEvent* genEvent = theEvent->getEvent();
123 
124  particle = genEvent->beam_particles().second;
125 
126  return particle;
127 }
128 
129 
131 {
132  HepMC::GenParticle *particle = NULL;
133 
134  /* @TODO How to select scattered lepton in an unambiguous way for
135  DIS and Exclusive Processes? (Pythia, Sartre, ...)
136  Return NULL pointer for now. */
137  /* In some event generators (SARTRE), no beam particles are created,
138  if so, assume beam lepton is an electron for now */
139  int pid_beam_lepton=0;
140  if(FindBeamLepton()==NULL)
141  {
142  /* Assume electron beam */
143  pid_beam_lepton=11;
144  }
145  else
146  {
147  pid_beam_lepton = FindBeamLepton()->pdg_id();
148  }
149  int embedding_id = 1;
150 
151  PHHepMCGenEvent *genevt = _genevtmap->get(embedding_id);
152  HepMC::GenEvent *theEvent = genevt->getEvent();
153 
154  /* check if GenEvent object found */
155  if ( !theEvent )
156  {
157  cout << "ERROR: Missing GenEvent!" << endl;
158  return NULL;
159  }
160  /* Loop over all truth particles in event generator collection */
161  for ( HepMC::GenEvent::particle_iterator p = theEvent->particles_begin();
162  p != theEvent->particles_end(); ++p ) {
163 
164  /* check particle status and ID */
165  if ( (*p)->status() == 1 &&
166  (*p)->pdg_id() == pid_beam_lepton )
167  {
168  particle = (*p);
169 
170  /* end loop if matching particle found */
171  break;
172  } // end if matching status and PID //
173  } // end loop over all particles in event //
174  return particle;
175 }
176 
177 
178 void
180 {
181  bool final_state = false;
182  while ( !final_state )
183  {
184  /* if particle has no vertex it is final state */
185  if(!particle->end_vertex()) break;
186 
187  /* Loop over all children at the end vertex of this particle */
188  for ( HepMC::GenVertex::particle_iterator child
189  = particle->end_vertex()->particles_begin(HepMC::children);
190  child != particle->end_vertex()->particles_end(HepMC::children);
191  ++child )
192  {
193 
194  /* If there is a child of same particle ID, this was not the final state particle- update pointer to particle and repeat */
195  if ( (*child)->pdg_id() == particle->pdg_id() )
196  {
197  particle = (*child);
198  break;
199  }
200  final_state = true;
201  }
202  }
203  return;
204 }
205 
206 
207 void
208 TruthTrackerHepMC::FindDecayParticles( HepMC::GenParticle *particle_mother, uint &decay_prong, uint &decay_hcharged, uint &decay_lcharged)
209 {
210  /* Reset counter variables */
211  decay_prong = 0;
212  decay_hcharged = 0;
213  decay_lcharged = 0;
214 
215  /* Loop over particles at end vertex of particle */
216  for ( HepMC::GenVertex::particle_iterator decay
217  = particle_mother->end_vertex()->
218  particles_begin(HepMC::children);
219  decay != particle_mother->end_vertex()->
220  particles_end(HepMC::children);
221  ++decay )
222  {
223  /* check if particle decays further */
224  if(!(*decay)->end_vertex()){
225 
226  /* Get entry from TParticlePDG because HepMC::GenPArticle does not provide charge or class of particle */
227  TParticlePDG * pdg_p = TDatabasePDG::Instance()->GetParticle( (*decay)->pdg_id() );
228 
229  /* Check if particle is charged */
230  if ( pdg_p->Charge() != 0 )
231  {
232  decay_prong += 1;
233 
234  /* Check if particle is lepton */
235  if ( string( pdg_p->ParticleClass() ) == "Lepton" )
236  decay_lcharged += 1;
237 
238  /* Check if particle is hadron, i.e. Meson or Baryon */
239  else if ( ( string( pdg_p->ParticleClass() ) == "Meson" ) ||
240  ( string( pdg_p->ParticleClass() ) == "Baryon" ) )
241  decay_hcharged += 1;
242  }
243  }
244 
245  /* loop over decay if particle decays further */
246  else if((*decay)->end_vertex()){
247 
248  /*further decay loop */
249  for ( HepMC::GenVertex::particle_iterator second_decay
250  = (*decay)->end_vertex()->
251  particles_begin(HepMC::children);
252  second_decay != (*decay)->end_vertex()->
253  particles_end(HepMC::children);
254  ++second_decay )
255  {
256 
257  // Get entry from TParticlePDG because HepMC::GenPArticle does not provide charge or class of particle
258  TParticlePDG * pdg_p2 = TDatabasePDG::Instance()->GetParticle( (*second_decay)->pdg_id() );
259 
260  // Check if particle is charged
261  if ( pdg_p2->Charge() != 0 )
262  {
263  decay_prong += 1;
264 
265  // Check if particle is lepton
266  if ( string( pdg_p2->ParticleClass() ) == "Lepton" )
267  decay_lcharged += 1;
268 
269  // Check if particle is hadron, i.e. Meson or Baryon
270  else if ( ( string( pdg_p2->ParticleClass() ) == "Meson" ) ||
271  ( string( pdg_p2->ParticleClass() ) == "Baryon" ) )
272  decay_hcharged += 1;
273  }
274  }
275  }
276  }
277 
278  return;
279 
280  /* @TODO: Below = Function that calls itself instead of doing the same loop. Still need to debug */
281 
282  // for ( HepMC::GenVertex::particle_iterator decay
283  // = particle_mother->end_vertex()->
284  // particles_begin(HepMC::children);
285  // decay != particle_mother->end_vertex()->
286  // particles_end(HepMC::children);
287  // ++decay )
288  // {
289  //
290  // if(!(*decay)->end_vertex()){
291  //
292  // // Get entry from TParticlePDG because HepMC::GenPArticle does not provide charge or class of particle
293  // TParticlePDG * pdg_p = TDatabasePDG::Instance()->GetParticle( (*decay)->pdg_id() );
294  //
295  // // Check if particle is charged
296  // if ( pdg_p->Charge() != 0 )
297  // {
298  // decay_prong += 1;
299  //
300  // // Check if particle is lepton
301  // if ( string( pdg_p->ParticleClass() ) == "Lepton" )
302  // decay_lcharged += 1;
303  //
304  // // Check if particle is hadron, i.e. Meson or Baryon
305  // else if ( ( string( pdg_p->ParticleClass() ) == "Meson" ) ||
306  // ( string( pdg_p->ParticleClass() ) == "Baryon" ) )
307  // decay_hcharged += 1;
308  // }
309  // }
310  //
311  // //HepMC::GenVertex::particle_iterator secondary_decay = (*decay)->end_vertex;
312  // else if((*decay)->end_vertex()) FindDecayProducts((*decay), decay_prong, decay_hcharged, decay_lcharged);
313  // }
314 
315 }
316 
317 
318 void
319 TruthTrackerHepMC::FindMissingPt( float &pt_miss, float &pt_miss_phi )
320 {
321  /* set output values to '0' */
322  pt_miss = 0;
323  pt_miss_phi = 0;
324 
325  /* variables to keep track of components */
326  float px_sum = 0;
327  float py_sum = 0;
328 
329  /* --> Loop over all truth events in event generator collection */
330  for (PHHepMCGenEventMap::ReverseIter iter = _genevtmap->rbegin(); iter != _genevtmap->rend(); ++iter)
331  {
332  PHHepMCGenEvent *genevt = iter->second;
333  HepMC::GenEvent *theEvent = genevt->getEvent();
334 
335  /* check if GenEvent object found */
336  if ( !theEvent )
337  {
338  cout << "ERROR: Missing GenEvent!" << endl;
339  return;
340  }
341 
342  /* Loop over all truth particles in event generator collection */
343  for ( HepMC::GenEvent::particle_iterator p = theEvent->particles_begin();
344  p != theEvent->particles_end(); ++p ) {
345 
346  /* skip particles that are not stable final state particles */
347  if ( (*p)->status() != 1 )
348  continue;
349 
350  /* Get entry from TParticlePDG because HepMC::GenPArticle does not provide charge or class of particle */
351  TParticlePDG * pdg_p = TDatabasePDG::Instance()->GetParticle( (*p)->pdg_id() );
352 
353  /* skip neutral leptons = neutrinos (invisible to detector) */
354  if ( ( string( pdg_p->ParticleClass() ) == "Lepton" ) &&
355  ( pdg_p->Charge() == 0 ) )
356  continue;
357 
358  /* update momentum component sum */
359  px_sum += (*p)->momentum().px();
360  py_sum += (*p)->momentum().py();
361 
362  } // end loop over all particles in event //
363  }// end loop over genevtmap //
364 
365  /* calculate pt_miss and phi */
366  pt_miss = sqrt( px_sum * px_sum + py_sum * py_sum );
367  pt_miss_phi = atan( py_sum / px_sum );
368 
369  return;
370 }