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