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