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 #include "Rivet/Tools/Cuts.hh"
00009 #include "Rivet/Tools/Utils.hh"
00010 #include "Rivet/Math/LorentzTrans.hh"
00011 // NOTE: Rivet/Tools/ParticleUtils.hh included at the end
00012 #include "fastjet/PseudoJet.hh"
00013 
00014 namespace Rivet {
00015 
00016 
00017   /// Particle representation, either from a HepMC::GenEvent or reconstructed.
00018   class Particle : public ParticleBase {
00019   public:
00020 
00021     /// @name Constructors
00022     //@{
00023 
00024     /// Default constructor.
00025     /// @note A particle without info is useless. This only exists to keep STL containers happy.
00026     Particle()
00027       : ParticleBase(),
00028         _original(0), _id(0)
00029     { }
00030 
00031     /// Constructor without GenParticle.
00032     Particle(PdgId pid, const FourMomentum& mom, const FourVector& pos=FourVector())
00033       : ParticleBase(),
00034         _original(0), _id(pid), _momentum(mom), _origin(pos)
00035     { }
00036 
00037     /// Constructor from a HepMC GenParticle pointer.
00038     Particle(const GenParticle* gp)
00039       : ParticleBase(),
00040         _original(gp), _id(gp->pdg_id()),
00041         _momentum(gp->momentum())
00042     {
00043       const GenVertex* vprod = gp->production_vertex();
00044       if (vprod != NULL)
00045         setOrigin(vprod->position().t(), vprod->position().x(), vprod->position().y(), vprod->position().z());
00046     }
00047 
00048     /// Constructor from a HepMC GenParticle.
00049     Particle(const GenParticle& gp)
00050       : ParticleBase(),
00051         _original(&gp), _id(gp.pdg_id()),
00052         _momentum(gp.momentum())
00053     {
00054       const GenVertex* vprod = gp.production_vertex();
00055       if (vprod != NULL)
00056         setOrigin(vprod->position().t(), vprod->position().x(), vprod->position().y(), vprod->position().z());
00057     }
00058 
00059     //@}
00060 
00061 
00062     /// @name Other representations and implicit casts
00063     //@{
00064 
00065     /// Converter to FastJet3 PseudoJet
00066     virtual fastjet::PseudoJet pseudojet() const {
00067       return fastjet::PseudoJet(mom().px(), mom().py(), mom().pz(), mom().E());
00068     }
00069 
00070     /// Cast operator to FastJet3 PseudoJet
00071     operator PseudoJet () const { return pseudojet(); }
00072 
00073 
00074     /// Get a const pointer to the original GenParticle.
00075     const GenParticle* genParticle() const {
00076       return _original;
00077     }
00078 
00079     /// Cast operator for conversion to GenParticle*
00080     operator const GenParticle* () const { return genParticle(); }
00081 
00082     //@}
00083 
00084 
00085     /// @name Kinematic properties
00086     //@{
00087 
00088     /// The momentum.
00089     const FourMomentum& momentum() const {
00090       return _momentum;
00091     }
00092 
00093     /// Set the momentum.
00094     Particle& setMomentum(const FourMomentum& momentum) {
00095       _momentum = momentum;
00096       return *this;
00097     }
00098 
00099     /// Set the momentum via components.
00100     Particle& setMomentum(double E, double px, double py, double pz) {
00101       _momentum = FourMomentum(E, px, py, pz);
00102       return *this;
00103     }
00104 
00105     /// Apply an active Lorentz transform to this particle
00106     Particle& transformBy(const LorentzTransform& lt);
00107 
00108     //@
00109 
00110 
00111     /// @name Positional properties
00112     //@{
00113 
00114     /// The origin position.
00115     const FourVector& origin() const {
00116       return _origin;
00117     }
00118     /// Set the origin position.
00119     Particle& setOrigin(const FourVector& position) {
00120       _origin = position;
00121       return *this;
00122     }
00123     /// Set the origin position via components.
00124     Particle& setOrigin(double t, double x, double y, double z) {
00125       _origin = FourMomentum(t, x, y, z);
00126       return *this;
00127     }
00128 
00129     //@}
00130 
00131 
00132     /// @name Particle ID code accessors
00133     //@{
00134 
00135     /// This Particle's PDG ID code.
00136     PdgId pid() const { return _id; }
00137     /// Absolute value of the PDG ID code.
00138     PdgId abspid() const { return std::abs(_id); }
00139     /// This Particle's PDG ID code (alias).
00140     /// @deprecated Prefer the pid/abspid form
00141     PdgId pdgId() const { return _id; }
00142 
00143     //@}
00144 
00145 
00146     /// @name Particle species properties
00147     //@{
00148 
00149     /// The charge of this Particle.
00150     double charge() const { return PID::charge(pid()); }
00151 
00152     /// The absolute charge of this Particle.
00153     double abscharge() const { return PID::abscharge(pid()); }
00154 
00155     /// Three times the charge of this Particle (i.e. integer multiple of smallest quark charge).
00156     int charge3() const { return PID::charge3(pid()); }
00157 
00158     /// Alias for charge3
00159     /// @deprecated Use charge3
00160     int threeCharge() const { return PID::threeCharge(pid()); }
00161 
00162     /// Three times the absolute charge of this Particle (i.e. integer multiple of smallest quark charge).
00163     int abscharge3() const { return PID::abscharge3(pid()); }
00164 
00165     /// Is this a hadron?
00166     bool isHadron() const { return PID::isHadron(pid()); }
00167 
00168     /// Is this a meson?
00169     bool isMeson() const { return PID::isMeson(pid()); }
00170 
00171     /// Is this a baryon?
00172     bool isBaryon() const { return PID::isBaryon(pid()); }
00173 
00174     /// Is this a lepton?
00175     bool isLepton() const { return PID::isLepton(pid()); }
00176 
00177     /// Is this a neutrino?
00178     bool isNeutrino() const { return PID::isNeutrino(pid()); }
00179 
00180     /// Does this (hadron) contain a b quark?
00181     bool hasBottom() const { return PID::hasBottom(pid()); }
00182 
00183     /// Does this (hadron) contain a c quark?
00184     bool hasCharm() const { return PID::hasCharm(pid()); }
00185 
00186     // /// Does this (hadron) contain an s quark?
00187     // bool hasStrange() const { return PID::hasStrange(pid()); }
00188 
00189     /// Is this particle potentially visible in a detector?
00190     bool isVisible() const;
00191 
00192     //@}
00193 
00194 
00195     /// @name Ancestry properties
00196     //@{
00197 
00198     /// @todo Add physicalAncestors, allAncestors?
00199 
00200     /// Get a list of the direct parents of the current particle (with optional selection Cut)
00201     ///
00202     /// @note This is valid in MC, but may not be answerable
00203     /// experimentally -- use this function with care when replicating
00204     /// experimental analyses!
00205     Particles parents(const Cut& c=Cuts::OPEN) const;
00206 
00207     /// Get a list of the direct parents of the current particle (with selector function)
00208     ///
00209     /// @note This is valid in MC, but may not be answerable
00210     /// experimentally -- use this function with care when replicating
00211     /// experimental analyses!
00212     template <typename FN>
00213     Particles parents(const FN& f) const {
00214       return filter_select(parents(), f);
00215     }
00216 
00217     /// Check whether a given PID is found in the particle's parent list
00218     ///
00219     /// @note This question is valid in MC, but may not be answerable
00220     /// experimentally -- use this function with care when replicating
00221     /// experimental analyses!
00222     ///
00223     /// @deprecated Prefer e.g. parents(Cut::pid == 123).size()
00224     bool hasParent(PdgId pid) const;
00225 
00226     /// Check whether a particle in the particle's parent list has the requested property
00227     ///
00228     /// @note This question is valid in MC, but may not be answerable
00229     /// experimentally -- use this function with care when replicating
00230     /// experimental analyses!
00231     ///
00232     /// @deprecated Prefer parents(Cut) or parents(FN) methods and .empty()
00233     template <typename FN>
00234     bool hasParentWith(const FN& f) const {
00235       return _hasRelativeWith(HepMC::parents, f);
00236     }
00237     bool hasParentWith(const Cut& c) const;
00238 
00239     /// Check whether a given PID is found in the particle's ancestor list
00240     ///
00241     /// @note This question is valid in MC, but may not be answerable
00242     /// experimentally -- use this function with care when replicating
00243     /// experimental analyses!
00244     bool hasAncestor(PdgId pid) const;
00245 
00246     /// Check whether a particle in the particle's ancestor list has the requested property
00247     ///
00248     /// @note This question is valid in MC, but may not be answerable
00249     /// experimentally -- use this function with care when replicating
00250     /// experimental analyses!
00251     template <typename FN>
00252     bool hasAncestorWith(const FN& f) const {
00253       return _hasRelativeWith(HepMC::ancestors, f);
00254     }
00255     bool hasAncestorWith(const Cut& c) const;
00256 
00257     /// @brief Determine whether the particle is from a b-hadron decay
00258     ///
00259     /// @note This question is valid in MC, but may not be perfectly answerable
00260     /// experimentally -- use this function with care when replicating
00261     /// experimental analyses!
00262     bool fromBottom() const;
00263 
00264     /// @brief Determine whether the particle is from a c-hadron decay
00265     ///
00266     /// @note If a hadron contains b and c quarks it is considered a bottom
00267     /// hadron and NOT a charm hadron.
00268     ///
00269     /// @note This question is valid in MC, but may not be perfectly answerable
00270     /// experimentally -- use this function with care when replicating
00271     /// experimental analyses!
00272     bool fromCharm() const;
00273 
00274     // /// @brief Determine whether the particle is from a s-hadron decay
00275     // ///
00276     // /// @note If a hadron contains b or c quarks as well as strange it is
00277     // /// considered a b or c hadron, but NOT a strange hadron.
00278     // ///
00279     // /// @note This question is valid in MC, but may not be perfectly answerable
00280     // /// experimentally -- use this function with care when replicating
00281     // /// experimental analyses!
00282     // bool fromStrange() const;
00283 
00284     /// @brief Determine whether the particle is from a hadron decay
00285     ///
00286     /// @note This question is valid in MC, but may not be perfectly answerable
00287     /// experimentally -- use this function with care when replicating
00288     /// experimental analyses!
00289     bool fromHadron() const;
00290 
00291     /// @brief Determine whether the particle is from a tau decay
00292     ///
00293     /// @note This question is valid in MC, but may not be perfectly answerable
00294     /// experimentally -- use this function with care when replicating
00295     /// experimental analyses!
00296     bool fromTau(bool prompt_taus_only=false) const;
00297 
00298     /// @brief Determine whether the particle is from a prompt tau decay
00299     ///
00300     /// @note This question is valid in MC, but may not be perfectly answerable
00301     /// experimentally -- use this function with care when replicating
00302     /// experimental analyses!
00303     bool fromPromptTau() const { return fromTau(true); }
00304 
00305     /// @brief Determine whether the particle is from a hadron or tau decay
00306     ///
00307     /// Specifically, walk up the ancestor chain until a status 2 hadron or
00308     /// tau is found, if at all.
00309     ///
00310     /// @note This question is valid in MC, but may not be perfectly answerable
00311     /// experimentally -- use this function with care when replicating
00312     /// experimental analyses!
00313     bool fromDecay() const { return fromHadron() || fromPromptTau(); }
00314 
00315     /// @brief Shorthand definition of 'promptness' based on set definition flags
00316     ///
00317     /// The boolean arguments allow a decay lepton to be considered prompt if
00318     /// its parent was a "real" prompt lepton.
00319     ///
00320     /// @note This one doesn't make any judgements about final-stateness
00321     bool isPrompt(bool allow_from_prompt_tau=false, bool allow_from_prompt_mu=false) const;
00322 
00323     //@}
00324 
00325 
00326     /// @name Decay info
00327     //@{
00328 
00329     /// Whether this particle is stable according to the generator
00330     bool isStable() const;
00331 
00332     /// Get a list of the direct descendants from the current particle (with optional selection Cut)
00333     Particles children(const Cut& c=Cuts::OPEN) const;
00334 
00335     /// Get a list of the direct descendants from the current particle (with selector function)
00336     template <typename FN>
00337     Particles children(const FN& f) const {
00338       return filter_select(children(), f);
00339     }
00340 
00341     /// Get a list of all the descendants from the current particle (with optional selection Cut)
00342     Particles allDescendants(const Cut& c=Cuts::OPEN, bool remove_duplicates=true) const;
00343 
00344     /// Get a list of all the descendants from the current particle (with selector function)
00345     template <typename FN>
00346     Particles allDescendants(const FN& f, bool remove_duplicates=true) const {
00347       return filter_select(allDescendants(Cuts::OPEN, remove_duplicates), f);
00348     }
00349 
00350     /// Get a list of all the stable descendants from the current particle (with optional selection Cut)
00351     ///
00352     /// @todo Use recursion through replica-avoiding MCUtils functions to avoid bookkeeping duplicates
00353     /// @todo Insist that the current particle is post-hadronization, otherwise throw an exception?
00354     Particles stableDescendants(const Cut& c=Cuts::OPEN) const;
00355 
00356     /// Get a list of all the stable descendants from the current particle (with selector function)
00357     template <typename FN>
00358     Particles stableDescendants(const FN& f) const {
00359       return filter_select(stableDescendants(), f);
00360     }
00361 
00362     /// Flight length (divide by mm or cm to get the appropriate units)
00363     double flightLength() const;
00364 
00365     //@}
00366 
00367 
00368   protected:
00369 
00370     template <typename FN>
00371     bool _hasRelativeWith(HepMC::IteratorRange relation, const FN& f) const {
00372       for (const GenParticle* ancestor : particles(genParticle(), relation)) {
00373         if (f(Particle(ancestor))) return true;
00374       }
00375       return false;
00376     }
00377 
00378     /// A pointer to the original GenParticle from which this Particle is projected.
00379     const GenParticle* _original;
00380 
00381     /// The PDG ID code for this Particle.
00382     PdgId _id;
00383 
00384     /// The momentum of this particle.
00385     FourMomentum _momentum;
00386 
00387     /// The creation position of this particle.
00388     FourVector _origin;
00389 
00390   };
00391 
00392 
00393   /// @name String representation and streaming support
00394   //@{
00395 
00396   /// Represent a Particle as a string.
00397   std::string to_str(const Particle& p);
00398 
00399   /// Allow a Particle to be passed to an ostream.
00400   inline std::ostream& operator<<(std::ostream& os, const Particle& p) {
00401     os << to_str(p);
00402     return os;
00403   }
00404 
00405 
00406   /// Represent a ParticlePair as a string.
00407   std::string to_str(const ParticlePair& pair);
00408 
00409   /// Allow ParticlePair to be passed to an ostream.
00410   inline std::ostream& operator<<(std::ostream& os, const ParticlePair& pp) {
00411     os << to_str(pp);
00412     return os;
00413   }
00414 
00415   //@}
00416 
00417 
00418 }
00419 
00420 
00421 #include "Rivet/Tools/ParticleUtils.hh"
00422 
00423 #endif