rivet is hosted by Hepforge, IPPP Durham
Event.hh
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef RIVET_Event_HH
00003 #define RIVET_Event_HH
00004 
00005 #include "Rivet/Config/RivetCommon.hh"
00006 #include "Rivet/Particle.hh"
00007 #include "Rivet/Projection.hh"
00008 
00009 namespace Rivet {
00010 
00011 
00012   /// Rivet wrapper for HepMC event and Projection references.
00013   ///
00014   /// Event is a concrete class representing an generated event in Rivet. It is
00015   /// constructed given a HepMC::GenEvent, a pointer to which is kept by the
00016   /// Event object throughout its lifetime. The user must therefore make sure
00017   /// that the corresponding HepMC::GenEvent will persist at least as long as
00018   /// the Event object.
00019   ///
00020   /// In addition to the HepMC::GenEvent object the Event also keeps track of
00021   /// all Projection objects which have been applied to the Event so far.
00022   class Event {
00023   public:
00024 
00025     /// @name Constructors and destructors.
00026     //@{
00027 
00028     /// Constructor from a HepMC GenEvent pointer
00029     Event(const GenEvent* ge)
00030       : _genevent_original(ge), _genevent(*ge)
00031     { assert(ge); _init(*ge); }
00032 
00033     /// Constructor from a HepMC GenEvent reference
00034     /// @deprecated HepMC uses pointers, so we should talk to HepMC via pointers
00035     Event(const GenEvent& ge)
00036       : _genevent_original(&ge), _genevent(ge)
00037     { _init(ge); }
00038 
00039     /// Copy constructor
00040     Event(const Event& e)
00041       : _genevent_original(e._genevent_original), _genevent(e._genevent)
00042     {  }
00043 
00044     //@}
00045 
00046 
00047     /// @name Major event properties
00048     //@{
00049 
00050     /// Get the beam particles
00051     ParticlePair beams() const;
00052 
00053     /// Get the beam centre-of-mass energy
00054     double sqrtS() const;
00055 
00056     /// Get the beam centre-of-mass energy per nucleon
00057     double asqrtS() const;
00058 
00059     // /// Get the boost to the beam centre-of-mass
00060     // Vector3 beamCMSBoost() const;
00061 
00062     // /// Get the boost to the beam centre-of-mass
00063     // LorentzTransform beamCMSTransform();
00064 
00065     /// The generated event obtained from an external event generator
00066     const GenEvent* genEvent() const { return &_genevent; }
00067 
00068     /// All the raw GenEvent particles, wrapped in Rivet::Particle objects
00069     const Particles& allParticles() const;
00070 
00071     /// @brief All the raw GenEvent particles, wrapped in Rivet::Particle objects, but with a Cut applied
00072     ///
00073     /// @note Due to the cut, this returns by value, i.e. involves an expensive copy
00074     inline Particles allParticles(const Cut& c) const {
00075       return filter_select(allParticles(), c);
00076     }
00077 
00078     /// @brief All the raw GenEvent particles, wrapped in Rivet::Particle objects, but with a selection function applied
00079     ///
00080     /// @note Due to the cut, this returns by value, i.e. involves an expensive copy
00081     template <typename FN>
00082     inline Particles allParticles(const FN& f) const {
00083       return filter_select(allParticles(), f);
00084     }
00085 
00086     /// @brief The generation weight associated with the event
00087     ///
00088     /// @todo This needs to be revisited when we finally add the mechanism to
00089     /// support NLO counter-events and weight vectors.
00090     double weight() const;
00091 
00092     //@}
00093 
00094 
00095     /// @name Projection running
00096     //@{
00097 
00098     /// @brief Add a projection @a p to this Event.
00099     ///
00100     /// If an equivalent Projection has been applied before, the
00101     /// Projection::project(const Event&) of @a p is not called and a reference
00102     /// to the previous equivalent projection is returned. If no previous
00103     /// Projection was found, the Projection::project(const Event&) of @a p is
00104     /// called and a reference to @a p is returned.
00105     template <typename PROJ>
00106     const PROJ& applyProjection(PROJ& p) const {
00107       const Projection* cpp(&p);
00108       std::set<const Projection*>::const_iterator old = _projections.find(cpp);
00109       if (old != _projections.end()) {
00110         const Projection& pRef = **old;
00111         return pcast<PROJ>(pRef);
00112       }
00113       // Add the projection via the Projection base class (only
00114       // possible because Event is a friend of Projection)
00115       Projection* pp = const_cast<Projection*>(cpp);
00116       pp->project(*this);
00117       _projections.insert(pp);
00118       return p;
00119     }
00120 
00121     /// @brief Add a projection @a p to this Event by pointer.
00122     template <typename PROJ>
00123     const PROJ& applyProjection(PROJ* pp) const {
00124       if (!pp) throw Error("Event::applyProjection(PROJ*): Projection pointer is null.");
00125       return applyProjection(*pp);
00126     }
00127 
00128     //@}
00129 
00130 
00131   private:
00132 
00133     /// @brief Actual (shared) implementation of the constructors from GenEvents
00134     void _init(const GenEvent& ge);
00135 
00136     // /// @brief Convert the GenEvent to use conventional alignment
00137     // ///
00138     // /// For example, FHerwig only produces DIS events in the unconventional
00139     // /// hadron-lepton orientation and has to be corrected for DIS analysis
00140     // /// portability.
00141     // void _geNormAlignment();
00142 
00143     /// @brief The generated event, as obtained from an external generator.
00144     ///
00145     /// This is the original GenEvent. In practise the version seen by users
00146     /// will often/always be a modified one.
00147     ///
00148     /// @todo Provide access to this via an Event::originalGenEvent() method? If requested...
00149     const GenEvent* _genevent_original;
00150 
00151     /// @brief The GenEvent used by Rivet analysis projections etc.
00152     ///
00153     /// This version may be rotated to a "normal" alignment, have
00154     /// generator-specific particles stripped out, etc.  If an analysis is
00155     /// affected by these modifications, it is probably an unphysical analysis!
00156     ///
00157     /// Stored as a non-pointer since it may get overwritten, and memory for
00158     /// copying and cleanup is neater this way.
00159     /// @todo Change needed for HepMC3?
00160     mutable GenEvent _genevent;
00161 
00162     /// All the GenEvent particles, wrapped as Rivet::Particles
00163     /// @note To be populated lazily, hence mutability
00164     mutable Particles _particles;
00165 
00166     /// The set of Projection objects applied so far
00167     mutable std::set<ConstProjectionPtr> _projections;
00168 
00169   };
00170 
00171 
00172 }
00173 
00174 #endif