EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ParticleIdentifier.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ParticleIdentifier.cxx
1 
11 
12 #include <algorithm>
13 #include <iostream>
14 #include <vector>
15 #include <string>
16 
17 #include <TParticlePDG.h>
18 #include <TDatabasePDG.h>
19 
20 #include "eicsmear/erhic/EventMC.h"
21 
22 using std::string;
23 using std::cout;
24 using std::cerr;
25 using std::endl;
26 
27 
28 // =============================================================================
29 // Constructor
30 // =============================================================================
31 ParticleIdentifier::ParticleIdentifier(const int leptonBeamPdgCode)
32 : mChargedCurrent(false)
33 , mLeptonBeamPdgCode(leptonBeamPdgCode)
34 , mScatteredPdgCode(leptonBeamPdgCode)
35 { }
36 
37 // =============================================================================
38 // Identify the lepton beam particle
39 // =============================================================================
41  const erhic::VirtualParticle& particle) const {
42  // Beam?
43  if ( particle.GetParentIndex() != 0 ) return false;
44  // Lepton?
45  if ( particle.Id() != GetLeptonBeamPdgCode() ) return false;
46  // Beam status?
47  switch (particle.GetStatus()){
48  case 21 : return true; // pythia6 et al
49  case 201 : return true; // SOPHIA
50  case 4: return true; // HepMC
51  }
52  return false;
53 }
54 
55 // =============================================================================
56 // Identify the scattered lepton
57 // =============================================================================
59  auto pdgl = TDatabasePDG::Instance()->GetParticle( particle.Id() );
60 
61  return ( particle.GetStatus() == 1 && string(pdgl->ParticleClass()) == "Lepton" );
62  // the old version here ignores flavor change, such as charged current dis
63  // return ( particle.GetStatus() == 1 && particle.Id()==mScatteredPdgCode);
64 }
65 
66 // =============================================================================
67 // Return true if the particle matches any of the following:
68 // - Outgoing electron with KS 21 - we instead pick up the
69 // repeat entry, when KS < 21.
70 // - Repeat of incoming nucleon.
71 // - Intermediate gluon.
72 // - Intermediate quark.
73 // =============================================================================
75  const erhic::VirtualParticle& particle) const {
76  int kI1 = particle.GetStatus();
77  int pdgCode = particle.Id();
78  int parent = particle.GetParentIndex();
79  // Remove duplicate outgoing electron, info is picked up later when KS < 21
80  if (21 == kI1 && pdgCode == GetLeptonBeamPdgCode() && parent == 1) {
81  return true;
82  } // if
83  // Remove repeat of incoming nucelon
84  if (21 == kI1 && (pdgCode == 2112 || pdgCode == 2212) && parent == 2) {
85  return true;
86  } // if
87  // Remove intermediate gluons
88  if (21 == kI1 && pdgCode == 21) {
89  return true;
90  } // if
91  // Remove intermediate (anti)quarks
92  if (21 == kI1 && ::abs(pdgCode) < 10) {
93  return true;
94  } // if
95  return false;
96 }
97 
98 // =============================================================================
99 // Identify the virtual photon based on its PDG code and PYTHIA K(I,1)
100 // =============================================================================
102  const erhic::VirtualParticle& particle) const {
103  const int pdg = abs(particle.Id());
104  auto status = particle.GetStatus();
105  // special case for placeholder particle in ff2ff events
106  if ( particle.GetStatus() == 0 && status ==0 ) return true;
107 
108  if (pdg<22) return false;
109  if (pdg>24) return false;
110  if ( status == 21 ) return true; // pythia6 et al
111  if ( status == 13 ) return true; // pythia8
112  return false;
113 }
114 
115 // =============================================================================
116 // Identify the nucleon beam particle
117 // =============================================================================
119  const erhic::VirtualParticle& particle) const {
120  // Beam?
121  if ( particle.GetParentIndex() != 0 ) return false;
122  // Hadron?
123  if ( particle.Id() != 2112 && particle.Id() != 2212 // e+P
124  && abs(particle.Id()) < 1000000000 ) return false; // allow ions in eA
125  // Beam status?
126  switch (particle.GetStatus()){
127  case 21 : return true; // pythia6 et al
128  case 201 : return true; // SOPHIA
129  case 4: return true; // HepMC
130  }
131 
132  return false;
133 }
134 
135 // =============================================================================
136 // beam electron (11) --> scattered nu_e (12)
137 // beam positron (-11) --> scattered nu_e_bar (-12)
138 // =============================================================================
140  if (!mChargedCurrent) {
141  return beamType;
142  } // if
143  int sign = beamType / abs(beamType);
144  return sign * (abs(beamType) + 1);
145 }
146 
147 // =============================================================================
148 // =============================================================================
150  mLeptonBeamPdgCode = pdgCode;
151  if (mChargedCurrent) {
153  } else {
154  mScatteredPdgCode = pdgCode;
155  } // if
156 }
157 
159  // If charged current status is changed we need to update
160  // the expected scattered lepton type. But we need to call
161  // DetermineScatteredType() *after* updating mChargedCurrent.
162  bool changed = !mChargedCurrent && cc;
163  mChargedCurrent = cc;
164  if (changed) {
166  } // if
167  return cc;
168 }
169 
170 // =============================================================================
171 // Identify the beams from an event and store their properties in a
172 // BeamParticles object.
173 // See BeamParticles.h for the quantities stored.
174 // Returns true if all beams are found, false if not.
175 // =============================================================================
177  BeamParticles& beams) {
178  beams.Reset();
179  std::vector<const erhic::VirtualParticle*> particles;
180  bool foundAll = IdentifyBeams(event, particles);
181  if (particles.at(0)) {
182  beams.SetBeamLepton(particles.at(0)->Get4Vector());
183  } // if
184  if (particles.at(1)) {
185  beams.SetBeamHadron(particles.at(1)->Get4Vector());
186  } // if
187  if (particles.at(2)) {
188  beams.SetBoson(particles.at(2)->Get4Vector());
189  } // if
190  if (particles.at(3)) {
191  beams.SetScatteredLepton(particles.at(3)->Get4Vector());
192  } // if
193  return foundAll;
194 }
195 
196 // =============================================================================
197 // =============================================================================
199  std::vector<const erhic::VirtualParticle*>& beams) {
200  // Initialise a vector with four NULL pointers,
201  // one beam particle of interest.
202  const erhic::VirtualParticle* const null(NULL);
203  beams.assign(4, null);
204  // Configure the particle finder.
205  ParticleIdentifier finder;
206  if (event.GetTrack(0)) {
207  finder.SetLeptonBeamPdgCode(event.GetTrack(0)->Id());
208  } // if
209  // Count leptons so we don't overwrite the beam and scattered lepton with
210  // subsequent leptons of the same type.
211  int leptonCount(0);
212  // Set to true once we find the first virtual photon, so we can skip
213  // subsequent virtual photons.
214  bool foundExchangeBoson(false);
215  bool foundAll(false);
216  for (unsigned n(0); n < event.GetNTracks(); ++n) {
217  const erhic::VirtualParticle* particle = event.GetTrack(n);
218  if (!particle) {
219  continue;
220  } // if
221  // Test for beam lepton/hadron, exchange boson and scattered lepton.
222  if (finder.isBeamNucleon(*particle)) {
223  // cout << "Found the beam nucleon" << endl;
224  beams.at(1) = particle;
225  } else if (finder.isBeamLepton(*particle) && 0 == leptonCount) {
226  // cout << "Found the beam lepton" << endl;
227  beams.at(0) = particle;
228  ++leptonCount;
229  } else if (finder.isScatteredLepton(*particle) && 1 == leptonCount) {
230  // cout << "Found the scattered lepton" << endl;
231  beams.at(3) = particle;
232  // Protect against additional KS == 1 leptons following this
233  ++leptonCount;
234  } else if (finder.IsVirtualPhoton(*particle) && !foundExchangeBoson) {
235  // cout << "Found the boson" << endl;
236  beams.at(2) = particle;
237  foundExchangeBoson = true;
238  // Check for charged current events, in which the scattered lepton
239  // ID will not be the same as the incident lepton ID.
240  finder.SetChargedCurrent(abs(particle->Id()) == 24);
241  } // if
242  // Break out if we've found all four beams (should happen at/near the
243  // start of the event record, so checking the other particles is a
244  // waste of time).
245  foundAll = std::find(beams.begin(), beams.end(), null) == beams.end();
246  if (foundAll) {
247  break;
248  } // if
249  } // for
250  return foundAll;
251 }