Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-09-28 07:02:51

0001 /**
0002  \file
0003  Implementation of class ParticleIdentifier.
0004  
0005  \author    Thomas Burton
0006  \date      2011-10-10
0007  \copyright 2011 Brookhaven National Lab
0008  */
0009 
0010 #include "eicsmear/erhic/ParticleIdentifier.h"
0011 
0012 #include <algorithm>
0013 #include <iostream>
0014 #include <vector>
0015 #include <string>
0016 
0017 #include <TParticlePDG.h>
0018 #include <TDatabasePDG.h>
0019 
0020 #include "eicsmear/erhic/EventMC.h"
0021 
0022 using std::string;
0023 using std::cout;
0024 using std::cerr;
0025 using std::endl;
0026 
0027 
0028 // =============================================================================
0029 // Constructor
0030 // =============================================================================
0031 ParticleIdentifier::ParticleIdentifier(const int leptonBeamPdgCode)
0032 : mChargedCurrent(false)
0033 , mLeptonBeamPdgCode(leptonBeamPdgCode)
0034 , mScatteredPdgCode(leptonBeamPdgCode)
0035 { }
0036 
0037 // =============================================================================
0038 // Identify the lepton beam particle
0039 // =============================================================================
0040 bool ParticleIdentifier::isBeamLepton(
0041          const erhic::VirtualParticle& particle) const {
0042   // Beam?
0043   if ( particle.GetParentIndex() != 0 ) return false;
0044   // Lepton?
0045   if ( particle.Id() != GetLeptonBeamPdgCode() ) return false;
0046   // Beam status?
0047   switch (particle.GetStatus()){
0048   case 21 : return true;  // pythia6 et al
0049   case 201 : return true; // SOPHIA
0050   case 4: return true;    // HepMC
0051   }
0052   return false;
0053 }
0054 
0055 // =============================================================================
0056 // Identify the scattered lepton
0057 // =============================================================================
0058 bool ParticleIdentifier::isScatteredLepton(const erhic::VirtualParticle& particle) const {
0059   auto pdgl = TDatabasePDG::Instance()->GetParticle( particle.Id() );
0060   
0061   return ( particle.GetStatus() == 1  && string(pdgl->ParticleClass()) == "Lepton" );
0062   // the old version here ignores flavor change, such as charged current dis
0063   // return ( particle.GetStatus() == 1  && particle.Id()==mScatteredPdgCode);
0064 }
0065 
0066 // =============================================================================
0067 // Return true if the particle matches any of the following:
0068 //  - Outgoing electron with KS 21 - we instead pick up the
0069 //                                   repeat entry, when KS < 21.
0070 //  - Repeat of incoming nucleon.
0071 //  - Intermediate gluon.
0072 //  - Intermediate quark.
0073 // =============================================================================
0074 bool ParticleIdentifier::SkipParticle(
0075          const erhic::VirtualParticle& particle) const {
0076   int kI1 = particle.GetStatus();
0077   int pdgCode = particle.Id();
0078   int parent = particle.GetParentIndex();
0079   // Remove duplicate outgoing electron, info is picked up later when KS < 21
0080   if (21 == kI1 && pdgCode == GetLeptonBeamPdgCode() && parent == 1) {
0081     return true;
0082   }  // if
0083     // Remove repeat of incoming nucelon
0084   if (21 == kI1 && (pdgCode == 2112 || pdgCode == 2212) && parent == 2) {
0085     return true;
0086   }  // if
0087     // Remove intermediate gluons
0088   if (21 == kI1 && pdgCode == 21) {
0089     return true;
0090   }  // if
0091     // Remove intermediate (anti)quarks
0092   if (21 == kI1 && ::abs(pdgCode) < 10) {
0093     return true;
0094   }  // if
0095   return false;
0096 }
0097 
0098 // =============================================================================
0099 // Identify the virtual photon based on its PDG code and PYTHIA K(I,1)
0100 // =============================================================================
0101 bool ParticleIdentifier::IsVirtualPhoton(
0102          const erhic::VirtualParticle& particle) const {
0103   const int pdg = abs(particle.Id());
0104   auto status = particle.GetStatus();
0105   // special case for placeholder particle in ff2ff events
0106   if ( particle.GetStatus() == 0 && status ==0 ) return true;
0107   
0108   if (pdg<22) return false;
0109   if (pdg>24) return false;
0110   if ( status == 21 ) return true; // pythia6 et al
0111   if ( status == 13 ) return true; // pythia8
0112   return false;
0113 }
0114 
0115 // =============================================================================
0116 // Identify the nucleon beam particle
0117 // =============================================================================
0118 bool ParticleIdentifier::isBeamNucleon(
0119          const erhic::VirtualParticle& particle) const {
0120   // Beam?
0121   if ( particle.GetParentIndex() != 0 ) return false;
0122   // Hadron?
0123   if ( particle.Id() != 2112 && particle.Id() != 2212 // e+P
0124        && abs(particle.Id()) < 1000000000 ) return false; // allow ions in eA
0125   // Beam status?
0126   switch (particle.GetStatus()){
0127   case 21 : return true;  // pythia6 et al
0128   case 201 : return true; // SOPHIA
0129   case 4: return true;    // HepMC
0130   }
0131 
0132   return false;
0133 }
0134 
0135 // =============================================================================
0136 // beam electron (11) --> scattered nu_e (12)
0137 // beam positron (-11) --> scattered nu_e_bar (-12)
0138 // =============================================================================
0139 Int_t ParticleIdentifier::DetermineScatteredType(Int_t beamType) {
0140   if (!mChargedCurrent) {
0141     return beamType;
0142   }  // if
0143   int sign = beamType / abs(beamType);
0144   return sign * (abs(beamType) + 1);
0145 }
0146 
0147 // =============================================================================
0148 // =============================================================================
0149 void ParticleIdentifier::SetLeptonBeamPdgCode(const int pdgCode) {
0150   mLeptonBeamPdgCode = pdgCode;
0151   if (mChargedCurrent) {
0152     mScatteredPdgCode = DetermineScatteredType(pdgCode);
0153   } else {
0154     mScatteredPdgCode = pdgCode;
0155   }  // if
0156 }
0157 
0158 bool ParticleIdentifier::SetChargedCurrent(bool cc) {
0159   // If charged current status is changed we need to update
0160   // the expected scattered lepton type. But we need to call
0161   // DetermineScatteredType() *after* updating mChargedCurrent.
0162   bool changed = !mChargedCurrent && cc;
0163   mChargedCurrent = cc;
0164   if (changed) {
0165     mScatteredPdgCode = DetermineScatteredType(mLeptonBeamPdgCode);
0166   }  // if
0167   return cc;
0168 }
0169 
0170 // =============================================================================
0171 // Identify the beams from an event and store their properties in a
0172 // BeamParticles object.
0173 // See BeamParticles.h for the quantities stored.
0174 // Returns true if all beams are found, false if not.
0175 // =============================================================================
0176 bool ParticleIdentifier::IdentifyBeams(const erhic::VirtualEvent& event,
0177                                        BeamParticles& beams) {
0178   beams.Reset();
0179   std::vector<const erhic::VirtualParticle*> particles;
0180   bool foundAll = IdentifyBeams(event, particles);
0181   if (particles.at(0)) {
0182     beams.SetBeamLepton(particles.at(0)->Get4Vector());
0183   }  // if
0184   if (particles.at(1)) {
0185     beams.SetBeamHadron(particles.at(1)->Get4Vector());
0186   }  // if
0187   if (particles.at(2)) {
0188     beams.SetBoson(particles.at(2)->Get4Vector());
0189   }  // if
0190   if (particles.at(3)) {
0191     beams.SetScatteredLepton(particles.at(3)->Get4Vector());
0192   }  // if
0193   return foundAll;
0194 }
0195 
0196 // =============================================================================
0197 // =============================================================================
0198 bool ParticleIdentifier::IdentifyBeams(const erhic::VirtualEvent& event,
0199          std::vector<const erhic::VirtualParticle*>& beams) {
0200   // Initialise a vector with four NULL pointers,
0201   // one beam particle of interest.
0202   const erhic::VirtualParticle* const null(NULL);
0203   beams.assign(4, null);
0204   // Configure the particle finder.
0205   ParticleIdentifier finder;
0206   if (event.GetTrack(0)) {
0207     finder.SetLeptonBeamPdgCode(event.GetTrack(0)->Id());
0208   }  // if
0209   // Count leptons so we don't overwrite the beam and scattered lepton with
0210   // subsequent leptons of the same type.
0211   int leptonCount(0);
0212   // Set to true once we find the first virtual photon, so we can skip
0213   // subsequent virtual photons.
0214   bool foundExchangeBoson(false);
0215   bool foundAll(false);
0216   for (unsigned n(0); n < event.GetNTracks(); ++n) {
0217     const erhic::VirtualParticle* particle = event.GetTrack(n);
0218     if (!particle) {
0219       continue;
0220     }  // if
0221     // Test for beam lepton/hadron, exchange boson and scattered lepton.
0222     if (finder.isBeamNucleon(*particle)) {
0223       // cout << "Found the beam nucleon" << endl;
0224       beams.at(1) = particle;
0225     } else if (finder.isBeamLepton(*particle) && 0 == leptonCount) {
0226       // cout << "Found the beam lepton" << endl;
0227       beams.at(0) = particle;
0228       ++leptonCount;
0229     } else if (finder.isScatteredLepton(*particle) && 1 == leptonCount) {
0230       // cout << "Found the scattered lepton" << endl;
0231       beams.at(3) = particle;
0232       // Protect against additional KS == 1 leptons following this
0233       ++leptonCount;
0234     } else if (finder.IsVirtualPhoton(*particle) && !foundExchangeBoson) {
0235       // cout << "Found the boson" << endl;
0236       beams.at(2) = particle;
0237       foundExchangeBoson = true;
0238       // Check for charged current events, in which the scattered lepton
0239       // ID will not be the same as the incident lepton ID.
0240       finder.SetChargedCurrent(abs(particle->Id()) == 24);
0241     }  // if
0242     // Break out if we've found all four beams (should happen at/near the
0243     // start of the event record, so checking the other particles is a
0244     // waste of time).
0245     foundAll = std::find(beams.begin(), beams.end(), null) == beams.end();
0246     if (foundAll) {
0247       break;
0248     }  // if
0249   }  // for
0250   return foundAll;
0251 }