Particle.hh
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #ifndef RIVET_Particle_HH 00003 #define RIVET_Particle_HH 00004 00005 #include "Rivet/Particle.fhh" 00006 #include "Rivet/ParticleBase.hh" 00007 #include "Rivet/Config/RivetCommon.hh" 00008 #include "Rivet/Tools/Utils.hh" 00009 // NOTE: Rivet/Tools/ParticleUtils.hh included at the end 00010 #include "fastjet/PseudoJet.hh" 00011 00012 namespace Rivet { 00013 00014 00015 /// Representation of particles from a HepMC::GenEvent. 00016 class Particle : public ParticleBase { 00017 public: 00018 00019 /// Default constructor. 00020 /// @note A particle without info is useless. This only exists to keep STL containers happy. 00021 Particle() 00022 : ParticleBase(), 00023 _original(0), _id(0), _momentum() 00024 { } 00025 00026 /// Constructor without GenParticle. 00027 Particle(PdgId pid, const FourMomentum& mom) 00028 : ParticleBase(), 00029 _original(0), _id(pid), _momentum(mom) 00030 { } 00031 00032 /// Constructor from a HepMC GenParticle. 00033 Particle(const GenParticle& gp) 00034 : ParticleBase(), 00035 _original(&gp), _id(gp.pdg_id()), 00036 _momentum(gp.momentum()) 00037 { } 00038 00039 /// Constructor from a HepMC GenParticle pointer. 00040 Particle(const GenParticle* gp) 00041 : ParticleBase(), 00042 _original(gp), _id(gp->pdg_id()), 00043 _momentum(gp->momentum()) 00044 { } 00045 00046 00047 public: 00048 00049 /// Converter to FastJet3 PseudoJet 00050 virtual fastjet::PseudoJet pseudojet() const { 00051 return fastjet::PseudoJet(mom().px(), mom().py(), mom().pz(), mom().E()); 00052 } 00053 00054 /// Cast operator to FastJet3 PseudoJet 00055 operator PseudoJet () const { return pseudojet(); } 00056 00057 00058 public: 00059 00060 /// @name Basic particle specific properties 00061 //@{ 00062 00063 /// Get a const pointer to the original GenParticle. 00064 const GenParticle* genParticle() const { 00065 return _original; 00066 } 00067 00068 /// Cast operator for conversion to GenParticle* 00069 operator const GenParticle* () const { return genParticle(); } 00070 00071 /// The momentum. 00072 const FourMomentum& momentum() const { 00073 return _momentum; 00074 } 00075 /// Set the momentum. 00076 Particle& setMomentum(const FourMomentum& momentum) { 00077 _momentum = momentum; 00078 return *this; 00079 } 00080 00081 //@} 00082 00083 00084 /// @name Particle ID code accessors 00085 //@{ 00086 00087 /// This Particle's PDG ID code. 00088 PdgId pid() const { return _id; } 00089 /// Absolute value of the PDG ID code. 00090 PdgId abspid() const { return std::abs(_id); } 00091 /// This Particle's PDG ID code (alias). 00092 /// @deprecated Prefer the pid/abspid form 00093 PdgId pdgId() const { return _id; } 00094 00095 //@} 00096 00097 00098 /// @name Particle species properties 00099 //@{ 00100 00101 /// The charge of this Particle. 00102 double charge() const { 00103 return PID::charge(pid()); 00104 } 00105 /// Three times the charge of this Particle (i.e. integer multiple of smallest quark charge). 00106 int threeCharge() const { 00107 return PID::threeCharge(pid()); 00108 } 00109 00110 /// Is this a hadron? 00111 bool isHadron() const { return PID::isHadron(pid()); } 00112 00113 /// Is this a meson? 00114 bool isMeson() const { return PID::isMeson(pid()); } 00115 00116 /// Is this a baryon? 00117 bool isBaryon() const { return PID::isBaryon(pid()); } 00118 00119 /// Is this a lepton? 00120 bool isLepton() const { return PID::isLepton(pid()); } 00121 00122 /// Is this a neutrino? 00123 bool isNeutrino() const { return PID::isNeutrino(pid()); } 00124 00125 /// Does this (hadron) contain a b quark? 00126 bool hasBottom() const { return PID::hasBottom(pid()); } 00127 00128 /// Does this (hadron) contain a c quark? 00129 bool hasCharm() const { return PID::hasCharm(pid()); } 00130 00131 /// Is this particle potentially visible in a detector? 00132 bool isVisible() const { 00133 // Charged particles are visible 00134 if ( PID::threeCharge(pid()) != 0 ) return true; 00135 // Neutral hadrons are visible 00136 if ( PID::isHadron(pid()) ) return true; 00137 // Photons are visible 00138 if ( pid() == PID::PHOTON ) return true; 00139 // Gluons are visible (for parton level analyses) 00140 if ( pid() == PID::GLUON ) return true; 00141 // Everything else is invisible 00142 return false; 00143 } 00144 00145 // /// Does this (hadron) contain an s quark? 00146 // bool hasStrange() const { return PID::hasStrange(pid()); } 00147 00148 //@} 00149 00150 00151 /// @name Ancestry properties 00152 //@{ 00153 00154 /// Check whether a given PID is found in the GenParticle's ancestor list 00155 /// 00156 /// @note This question is valid in MC, but may not be answerable 00157 /// experimentally -- use this function with care when replicating 00158 /// experimental analyses! 00159 bool hasAncestor(PdgId pdg_id) const; 00160 00161 /// @brief Determine whether the particle is from a b-hadron decay 00162 /// 00163 /// @note This question is valid in MC, but may not be perfectly answerable 00164 /// experimentally -- use this function with care when replicating 00165 /// experimental analyses! 00166 bool fromBottom() const; 00167 00168 /// @brief Determine whether the particle is from a c-hadron decay 00169 /// 00170 /// @note If a hadron contains b and c quarks it is considered a bottom 00171 /// hadron and NOT a charm hadron. 00172 /// 00173 /// @note This question is valid in MC, but may not be perfectly answerable 00174 /// experimentally -- use this function with care when replicating 00175 /// experimental analyses! 00176 bool fromCharm() const; 00177 00178 // /// @brief Determine whether the particle is from a s-hadron decay 00179 // /// 00180 // /// @note If a hadron contains b or c quarks as well as strange it is 00181 // /// considered a b or c hadron, but NOT a strange hadron. 00182 // /// 00183 // /// @note This question is valid in MC, but may not be perfectly answerable 00184 // /// experimentally -- use this function with care when replicating 00185 // /// experimental analyses! 00186 // bool fromStrange() const; 00187 00188 /// @brief Determine whether the particle is from a hadron decay 00189 /// 00190 /// @note This question is valid in MC, but may not be perfectly answerable 00191 /// experimentally -- use this function with care when replicating 00192 /// experimental analyses! 00193 bool fromHadron() const; 00194 00195 /// @brief Determine whether the particle is from a tau decay 00196 /// 00197 /// @note This question is valid in MC, but may not be perfectly answerable 00198 /// experimentally -- use this function with care when replicating 00199 /// experimental analyses! 00200 bool fromTau(bool prompt_taus_only=false) const; 00201 00202 /// @brief Determine whether the particle is from a prompt tau decay 00203 /// 00204 /// @note This question is valid in MC, but may not be perfectly answerable 00205 /// experimentally -- use this function with care when replicating 00206 /// experimental analyses! 00207 bool fromPromptTau() const { return fromTau(true); } 00208 00209 /// @brief Determine whether the particle is from a hadron or tau decay 00210 /// 00211 /// Specifically, walk up the ancestor chain until a status 2 hadron or 00212 /// tau is found, if at all. 00213 /// 00214 /// @note This question is valid in MC, but may not be perfectly answerable 00215 /// experimentally -- use this function with care when replicating 00216 /// experimental analyses! 00217 bool fromDecay() const { return fromHadron() || fromPromptTau(); } 00218 00219 //@} 00220 00221 00222 /// @name Decay info 00223 //@{ 00224 00225 /// Whether this particle is stable according to the generator 00226 bool isStable() const { 00227 return genParticle() != NULL && genParticle()->status() == 1 && genParticle()->end_vertex() == NULL; 00228 } 00229 00230 /// Get a list of the direct descendants from the current particle 00231 vector<Particle> children() const { 00232 vector<Particle> rtn; 00233 if (isStable()) return rtn; 00234 /// @todo Remove this const mess crap when HepMC doesn't suck 00235 HepMC::GenVertex* gv = const_cast<HepMC::GenVertex*>( genParticle()->end_vertex() ); 00236 /// @todo Would like to do this, but the range objects are broken 00237 // foreach (const GenParticle* gp, gv->particles(HepMC::children)) 00238 // rtn += Particle(gp); 00239 for (GenVertex::particle_iterator it = gv->particles_begin(HepMC::children); it != gv->particles_end(HepMC::children); ++it) 00240 rtn += Particle(*it); 00241 return rtn; 00242 } 00243 00244 /// Get a list of all the descendants (including duplication of parents and children) from the current particle 00245 /// @todo Use recursion through replica-avoiding MCUtils functions to avoid bookkeeping duplicates 00246 /// @todo Insist that the current particle is post-hadronization, otherwise throw an exception? 00247 vector<Particle> allDescendants() const { 00248 vector<Particle> rtn; 00249 if (isStable()) return rtn; 00250 /// @todo Remove this const mess crap when HepMC doesn't suck 00251 HepMC::GenVertex* gv = const_cast<HepMC::GenVertex*>( genParticle()->end_vertex() ); 00252 /// @todo Would like to do this, but the range objects are broken 00253 // foreach (const GenParticle* gp, gv->particles(HepMC::descendants)) 00254 // rtn += Particle(gp); 00255 for (GenVertex::particle_iterator it = gv->particles_begin(HepMC::descendants); it != gv->particles_end(HepMC::descendants); ++it) 00256 rtn += Particle(*it); 00257 return rtn; 00258 } 00259 00260 /// Get a list of all the stable descendants from the current particle 00261 /// @todo Use recursion through replica-avoiding MCUtils functions to avoid bookkeeping duplicates 00262 /// @todo Insist that the current particle is post-hadronization, otherwise throw an exception? 00263 vector<Particle> stableDescendants() const { 00264 vector<Particle> rtn; 00265 if (isStable()) return rtn; 00266 /// @todo Remove this const mess crap when HepMC doesn't suck 00267 HepMC::GenVertex* gv = const_cast<HepMC::GenVertex*>( genParticle()->end_vertex() ); 00268 /// @todo Would like to do this, but the range objects are broken 00269 // foreach (const GenParticle* gp, gv->particles(HepMC::descendants)) 00270 // if (gp->status() == 1 && gp->end_vertex() == NULL) 00271 // rtn += Particle(gp); 00272 for (GenVertex::particle_iterator it = gv->particles_begin(HepMC::descendants); it != gv->particles_end(HepMC::descendants); ++it) 00273 if ((*it)->status() == 1 && (*it)->end_vertex() == NULL) 00274 rtn += Particle(*it); 00275 return rtn; 00276 } 00277 00278 /// Flight length (divide by mm or cm to get the appropriate units) 00279 double flightLength() const { 00280 if (isStable()) return -1; 00281 if (genParticle() == NULL) return 0; 00282 if (genParticle()->production_vertex() == NULL) return 0; 00283 const HepMC::FourVector v1 = genParticle()->production_vertex()->position(); 00284 const HepMC::FourVector v2 = genParticle()->end_vertex()->position(); 00285 return sqrt(sqr(v2.x()-v1.x()) + sqr(v2.y()-v1.y()) + sqr(v2.z()-v1.z())); 00286 } 00287 00288 //@} 00289 00290 00291 private: 00292 00293 /// A pointer to the original GenParticle from which this Particle is projected. 00294 const GenParticle* _original; 00295 00296 /// The PDG ID code for this Particle. 00297 PdgId _id; 00298 00299 /// The momentum of this projection of the Particle. 00300 FourMomentum _momentum; 00301 00302 }; 00303 00304 00305 /// @name String representation 00306 //@{ 00307 00308 /// Print a ParticlePair as a string. 00309 inline std::string to_str(const ParticlePair& pair) { 00310 stringstream out; 00311 out << "[" 00312 << PID::toParticleName(pair.first.pid()) << " @ " 00313 << pair.first.momentum().E()/GeV << " GeV, " 00314 << PID::toParticleName(pair.second.pid()) << " @ " 00315 << pair.second.momentum().E()/GeV << " GeV]"; 00316 return out.str(); 00317 } 00318 00319 /// Allow ParticlePair to be passed to an ostream. 00320 inline std::ostream& operator<<(std::ostream& os, const ParticlePair& pp) { 00321 os << to_str(pp); 00322 return os; 00323 } 00324 00325 //@} 00326 00327 00328 } 00329 00330 00331 #include "Rivet/Tools/ParticleUtils.hh" 00332 00333 #endif Generated on Thu Mar 10 2016 08:29:52 for The Rivet MC analysis system by ![]() |