rivet is hosted by Hepforge, IPPP Durham
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/Rivet.hh"
00006 #include "Rivet/Particle.fhh"
00007 #include "Rivet/ParticleBase.hh"
00008 #include "Rivet/ParticleName.hh"
00009 #include "Rivet/Math/Vectors.hh"
00010 #include "Rivet/Tools/Logging.hh"
00011 #include "Rivet/Tools/ParticleIdUtils.hh"
00012 
00013 namespace Rivet {
00014 
00015 
00016   /// Representation of particles from a HepMC::GenEvent.
00017   class Particle : public ParticleBase {
00018   public:
00019 
00020     /// Default constructor.
00021     /// @deprecated A particle without info is useless. This only exists to keep STL containers happy.
00022     Particle()
00023       : ParticleBase(),
00024         _original(0), _id(0), _momentum()
00025     { }
00026 
00027     /// Constructor without GenParticle.
00028     Particle(PdgId pid, const FourMomentum& mom)
00029       : ParticleBase(),
00030         _original(0), _id(pid), _momentum(mom)
00031     { }
00032 
00033     /// Constructor from a HepMC GenParticle.
00034     Particle(const GenParticle& gp)
00035       : ParticleBase(),
00036         _original(&gp), _id(gp.pdg_id()),
00037         _momentum(gp.momentum())
00038     { }
00039 
00040     /// Constructor from a HepMC GenParticle pointer.
00041     Particle(const GenParticle* gp)
00042       : ParticleBase(),
00043         _original(gp), _id(gp->pdg_id()),
00044         _momentum(gp->momentum())
00045     { }
00046 
00047 
00048   public:
00049 
00050     /// @name Basic particle specific properties
00051     //@{
00052 
00053     /// Get a const reference to the original GenParticle.
00054     const GenParticle* genParticle() const {
00055       return _original;
00056     }
00057 
00058     /// The momentum.
00059     const FourMomentum& momentum() const {
00060       return _momentum;
00061     }
00062     /// Set the momentum.
00063     Particle& setMomentum(const FourMomentum& momentum) {
00064       _momentum = momentum;
00065       return *this;
00066     }
00067 
00068     /// This Particle's PDG ID code.
00069     PdgId pdgId() const {
00070       return _id;
00071     }
00072 
00073     /// The charge of this Particle.
00074     double charge() const {
00075       return PID::charge(pdgId());
00076     }
00077     /// Three times the charge of this Particle (i.e. integer multiple of smallest quark charge).
00078     int threeCharge() const {
00079       return PID::threeCharge(pdgId());
00080     }
00081 
00082     /// @todo Add isHadron, etc. PID-based properties as methods?
00083 
00084     //@}
00085 
00086 
00087     /// @name Ancestry properties
00088     //@{
00089 
00090     /// Check whether a given PID is found in the GenParticle's ancestor list
00091     ///
00092     /// @note This question is valid in MC, but may not be answerable
00093     /// experimentally -- use this function with care when replicating
00094     /// experimental analyses!
00095     bool hasAncestor(PdgId pdg_id) const;
00096 
00097     /// @brief Determine whether the particle is from a hadron or tau decay
00098     ///
00099     /// Specifically, walk up the ancestor chain until a status 2 hadron or
00100     /// tau is found, if at all.
00101     ///
00102     /// @note This question is valid in MC, but may not be answerable
00103     /// experimentally -- use this function with care when replicating
00104     /// experimental analyses!
00105     bool fromDecay() const;
00106 
00107     /// @todo Add methods like fromS/C/BHadron(), fromTau()?
00108 
00109     //@}
00110 
00111 
00112   private:
00113 
00114     /// A pointer to the original GenParticle from which this Particle is projected.
00115     const GenParticle* _original;
00116 
00117     /// The PDG ID code for this Particle.
00118     PdgId _id;
00119 
00120     /// The momentum of this projection of the Particle.
00121     FourMomentum _momentum;
00122 
00123     /// @todo Also store production and decay positions and make them available.
00124 
00125   };
00126 
00127 
00128   /// @name String representation
00129   //@{
00130 
00131   /// Print a ParticlePair as a string.
00132   inline std::string toString(const ParticlePair& pair) {
00133     stringstream out;
00134     out << "["
00135         << PID::toParticleName(pair.first.pdgId()) << " @ "
00136         << pair.first.momentum().E()/GeV << " GeV, "
00137         << PID::toParticleName(pair.second.pdgId()) << " @ "
00138         << pair.second.momentum().E()/GeV << " GeV]";
00139     return out.str();
00140   }
00141 
00142   /// Allow ParticlePair to be passed to an ostream.
00143   inline std::ostream& operator<<(std::ostream& os, const ParticlePair& pp) {
00144     os << toString(pp);
00145     return os;
00146   }
00147 
00148   //@}
00149 
00150 
00151   /// @name Comparison functors
00152   //@{
00153   /// Sort by descending transverse momentum, \f$ p_\perp \f$
00154   inline bool cmpParticleByPt(const Particle& a, const Particle& b) {
00155     return a.momentum().pT() > b.momentum().pT();
00156   }
00157   /// Sort by ascending transverse momentum, \f$ p_\perp \f$
00158   inline bool cmpParticleByAscPt(const Particle& a, const Particle& b) {
00159     return a.momentum().pT() < b.momentum().pT();
00160   }
00161   /// Sort by descending momentum, \f$ p \f$
00162   inline bool cmpParticleByP(const Particle& a, const Particle& b) {
00163     return a.momentum().vector3().mod() > b.momentum().vector3().mod();
00164   }
00165   /// Sort by ascending momentum, \f$ p \f$
00166   inline bool cmpParticleByAscP(const Particle& a, const Particle& b) {
00167     return a.momentum().vector3().mod() < b.momentum().vector3().mod();
00168   }
00169   /// Sort by descending transverse energy, \f$ E_\perp \f$
00170   inline bool cmpParticleByEt(const Particle& a, const Particle& b) {
00171     return a.momentum().Et() > b.momentum().Et();
00172   }
00173   /// Sort by ascending transverse energy, \f$ E_\perp \f$
00174   inline bool cmpParticleByAscEt(const Particle& a, const Particle& b) {
00175     return a.momentum().Et() < b.momentum().Et();
00176   }
00177   /// Sort by descending energy, \f$ E \f$
00178   inline bool cmpParticleByE(const Particle& a, const Particle& b) {
00179     return a.momentum().E() > b.momentum().E();
00180   }
00181   /// Sort by ascending energy, \f$ E \f$
00182   inline bool cmpParticleByAscE(const Particle& a, const Particle& b) {
00183     return a.momentum().E() < b.momentum().E();
00184   }
00185   /// Sort by descending pseudorapidity, \f$ \eta \f$
00186   inline bool cmpParticleByDescPseudorapidity(const Particle& a, const Particle& b) {
00187     return a.momentum().pseudorapidity() > b.momentum().pseudorapidity();
00188   }
00189   /// Sort by ascending pseudorapidity, \f$ \eta \f$
00190   inline bool cmpParticleByAscPseudorapidity(const Particle& a, const Particle& b) {
00191     return a.momentum().pseudorapidity() < b.momentum().pseudorapidity();
00192   }
00193   /// Sort by descending absolute pseudorapidity, \f$ |\eta| \f$
00194   inline bool cmpParticleByDescAbsPseudorapidity(const Particle& a, const Particle& b) {
00195     return fabs(a.momentum().pseudorapidity()) > fabs(b.momentum().pseudorapidity());
00196   }
00197   /// Sort by ascending absolute pseudorapidity, \f$ |\eta| \f$
00198   inline bool cmpParticleByAscAbsPseudorapidity(const Particle& a, const Particle& b) {
00199     return fabs(a.momentum().pseudorapidity()) < fabs(b.momentum().pseudorapidity());
00200   }
00201   /// Sort by descending rapidity, \f$ y \f$
00202   inline bool cmpParticleByDescRapidity(const Particle& a, const Particle& b) {
00203     return a.momentum().rapidity() > b.momentum().rapidity();
00204   }
00205   /// Sort by ascending rapidity, \f$ y \f$
00206   inline bool cmpParticleByAscRapidity(const Particle& a, const Particle& b) {
00207     return a.momentum().rapidity() < b.momentum().rapidity();
00208   }
00209   /// Sort by descending absolute rapidity, \f$ |y| \f$
00210   inline bool cmpParticleByDescAbsRapidity(const Particle& a, const Particle& b) {
00211     return fabs(a.momentum().rapidity()) > fabs(b.momentum().rapidity());
00212   }
00213   /// Sort by ascending absolute rapidity, \f$ |y| \f$
00214   inline bool cmpParticleByAscAbsRapidity(const Particle& a, const Particle& b) {
00215     return fabs(a.momentum().rapidity()) < fabs(b.momentum().rapidity());
00216   }
00217   //@}
00218 
00219   inline double deltaR(const Particle& p1, const Particle& p2,
00220                        RapScheme scheme = PSEUDORAPIDITY) {
00221     return deltaR(p1.momentum(), p2.momentum(), scheme);
00222   }
00223 
00224   inline double deltaR(const Particle& p, const FourMomentum& v,
00225                        RapScheme scheme = PSEUDORAPIDITY) {
00226     return deltaR(p.momentum(), v, scheme);
00227   }
00228 
00229   inline double deltaR(const Particle& p, const FourVector& v,
00230                        RapScheme scheme = PSEUDORAPIDITY) {
00231     return deltaR(p.momentum(), v, scheme);
00232   }
00233 
00234   inline double deltaR(const Particle& p, const Vector3& v) {
00235     return deltaR(p.momentum(), v);
00236   }
00237 
00238   inline double deltaR(const Particle& p, double eta, double phi) {
00239     return deltaR(p.momentum(), eta, phi);
00240   }
00241 
00242   inline double deltaR(const FourMomentum& v, const Particle& p,
00243                        RapScheme scheme = PSEUDORAPIDITY) {
00244     return deltaR(v, p.momentum(), scheme);
00245   }
00246 
00247   inline double deltaR(const FourVector& v, const Particle& p,
00248                        RapScheme scheme = PSEUDORAPIDITY) {
00249     return deltaR(v, p.momentum(), scheme);
00250   }
00251 
00252   inline double deltaR(const Vector3& v, const Particle& p) {
00253     return deltaR(v, p.momentum());
00254   }
00255 
00256   inline double deltaR(double eta, double phi, const Particle& p) {
00257     return deltaR(eta, phi, p.momentum());
00258   }
00259 
00260 
00261   inline double deltaPhi(const Particle& p1, const Particle& p2) {
00262     return deltaPhi(p1.momentum(), p2.momentum());
00263   }
00264 
00265   inline double deltaPhi(const Particle& p, const FourMomentum& v) {
00266     return deltaPhi(p.momentum(), v);
00267   }
00268 
00269   inline double deltaPhi(const Particle& p, const FourVector& v) {
00270     return deltaPhi(p.momentum(), v);
00271   }
00272 
00273   inline double deltaPhi(const Particle& p, const Vector3& v) {
00274     return deltaPhi(p.momentum(), v);
00275   }
00276 
00277   inline double deltaPhi(const Particle& p, double phi) {
00278     return deltaPhi(p.momentum(), phi);
00279   }
00280 
00281   inline double deltaPhi(const FourMomentum& v, const Particle& p) {
00282     return deltaPhi(v, p.momentum());
00283   }
00284 
00285   inline double deltaPhi(const FourVector& v, const Particle& p) {
00286     return deltaPhi(v, p.momentum());
00287   }
00288 
00289   inline double deltaPhi(const Vector3& v, const Particle& p) {
00290     return deltaPhi(v, p.momentum());
00291   }
00292 
00293   inline double deltaPhi(double phi, const Particle& p) {
00294     return deltaPhi(phi, p.momentum());
00295   }
00296 
00297 
00298   inline double deltaEta(const Particle& p1, const Particle& p2) {
00299     return deltaEta(p1.momentum(), p2.momentum());
00300   }
00301 
00302   inline double deltaEta(const Particle& p, const FourMomentum& v) {
00303     return deltaEta(p.momentum(), v);
00304   }
00305 
00306   inline double deltaEta(const Particle& p, const FourVector& v) {
00307     return deltaEta(p.momentum(), v);
00308   }
00309 
00310   inline double deltaEta(const Particle& p, const Vector3& v) {
00311     return deltaEta(p.momentum(), v);
00312   }
00313 
00314   inline double deltaEta(const Particle& p, double eta) {
00315     return deltaEta(p.momentum(), eta);
00316   }
00317 
00318   inline double deltaEta(const FourMomentum& v, const Particle& p) {
00319     return deltaEta(v, p.momentum());
00320   }
00321 
00322   inline double deltaEta(const FourVector& v, const Particle& p) {
00323     return deltaEta(v, p.momentum());
00324   }
00325 
00326   inline double deltaEta(const Vector3& v, const Particle& p) {
00327     return deltaEta(v, p.momentum());
00328   }
00329 
00330   inline double deltaEta(double eta, const Particle& p) {
00331     return deltaEta(eta, p.momentum());
00332   }
00333 
00334 }
00335 
00336 #endif