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/Rivet.hh"
00006 #include "Rivet/Projection.hh"
00007 
00008 namespace Rivet {
00009 
00010 
00011   /// Rivet wrapper for HepMC event and Projection references.
00012   ///
00013   /// Event is a concrete class representing an generated event in
00014   /// Rivet. It is constructed given a HepMC::GenEvent, a pointer to
00015   /// which is kept by the Event object throughout its lifetime. The user
00016   /// must therefore make sure that the corresponding HepMC::GenEvent
00017   /// will persist at least as long as the Event object.
00018   ///
00019   /// In addition to the HepMC::GenEvent object the Event also keeps
00020   /// track of all Projections object which have been applied to the
00021   /// Event so far.
00022   class Event {
00023   public:
00024 
00025     /// @name Standard constructors and destructors.
00026     //@{
00027 
00028     /// Constructor from a HepMC GenEvent reference
00029     Event(const GenEvent& ge)
00030       : _originalGenEvent(&ge), _genEvent(ge)
00031     { _init(ge); }
00032 
00033     /// Constructor from a HepMC GenEvent pointer
00034     Event(const GenEvent* ge)
00035       : _originalGenEvent(ge), _genEvent(*ge)
00036     { assert(ge); _init(*ge); }
00037 
00038     /// Copy constructor
00039     Event(const Event& e)
00040       : _originalGenEvent(e._originalGenEvent), _genEvent(e._genEvent)
00041     {  }
00042 
00043     //@}
00044 
00045 
00046   public:
00047 
00048     /// The generated event obtained from an external event generator
00049     const GenEvent* genEvent() const {
00050       return &_genEvent;
00051     }
00052 
00053     /// @brief The generation weight associated with the event
00054     ///
00055     /// @todo This needs to be revisited when we finally add the mechanism to
00056     /// support NLO counter-events and weight vectors.
00057     double weight() const {
00058       return (!_genEvent.weights().empty()) ? _genEvent.weights()[0] : 1.0;
00059     }
00060 
00061 
00062   public:
00063 
00064     /// @brief Add a projection @a p to this Event.
00065     ///
00066     /// If an equivalent Projection has been applied before, the
00067     /// Projection::project(const Event&) of @a p is not called and a reference
00068     /// to the previous equivalent projection is returned. If no previous
00069     /// Projection was found, the Projection::project(const Event&) of @a p is
00070     /// called and a reference to @a p is returned.
00071     template <typename PROJ>
00072     const PROJ& applyProjection(PROJ& p) const {
00073       const Projection* cpp(&p);
00074       std::set<const Projection*>::const_iterator old = _projections.find(cpp);
00075       if (old != _projections.end()) {
00076         const Projection& pRef = **old;
00077         return pcast<PROJ>(pRef);
00078       }
00079       // Add the projection via the Projection base class (only
00080       // possible because Event is a friend of Projection)
00081       Projection* pp = const_cast<Projection*>(cpp);
00082       pp->project(*this);
00083       _projections.insert(pp);
00084       return p;
00085     }
00086 
00087 
00088     template <typename PROJ>
00089     const PROJ& applyProjection(PROJ* pp) const {
00090       if (!pp) throw Error("Event::applyProjection(PROJ*): Projection pointer is null.");
00091       return applyProjection(*pp);
00092     }
00093 
00094 
00095   private:
00096 
00097     /// @brief Actual (shared) implementation of the constructors from GenEvents
00098     ///
00099     /// @todo When we can require C++11, constructors can call each other and
00100     /// this can be removed.
00101     void _init(const GenEvent& ge);
00102 
00103     /// @brief Convert the GenEvent to use conventional alignment
00104     ///
00105     /// For example, FHerwig only produces DIS events in the unconventional
00106     /// hadron-lepton orientation and has to be corrected for DIS analysis
00107     /// portability.
00108     void _geNormAlignment();
00109 
00110     /// @brief The generated event, as obtained from an external generator.
00111     ///
00112     /// This is the original GenEvent. In practise the version seen by users
00113     /// will often/always be a modified one.
00114     ///
00115     /// @todo Provide access to this via an Event::originalGenEvent() method? If requested...
00116     const GenEvent* _originalGenEvent;
00117 
00118     /// @brief The GenEvent used by Rivet analysis projections etc.
00119     ///
00120     /// This version may be rotated to a "normal" alignment, have
00121     /// generator-specific particles stripped out, etc.  If an analysis is
00122     /// affected by these modifications, it is probably an unphysical analysis!
00123     ///
00124     /// Stored as a non-pointer since it may get overwritten, and memory for
00125     /// copying and cleanup is much neater this way.
00126     GenEvent _genEvent;
00127 
00128     /// The set of Projection objects applied so far.
00129     mutable std::set<ConstProjectionPtr> _projections;
00130 
00131   };
00132 
00133 
00134 }
00135 
00136 #endif