rivet is hosted by Hepforge, IPPP Durham
ProjectionApplier.hh
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef RIVET_ProjectionApplier_HH
00003 #define RIVET_ProjectionApplier_HH
00004 
00005 #include "Rivet/Rivet.hh"
00006 #include "Rivet/Projection.fhh"
00007 #include "Rivet/ProjectionHandler.hh"
00008 #include "Rivet/Tools/Logging.hh"
00009 
00010 namespace Rivet {
00011 
00012 
00013   // Forward declarations
00014   class Event;
00015 
00016 
00017   /// @brief Common base class for Projection and Analysis, used for internal polymorphism
00018   ///
00019   /// Empty interface used for storing Projection and Analysis pointers in the
00020   /// same container (used by the ProjectionHandler)
00021   class ProjectionApplier {
00022   public:
00023 
00024     // The proj handler needs access to reset the _allowProjReg flag before calling a.init()
00025     // friend class ProjectionHandler;
00026 
00027     /// Constructor
00028     ProjectionApplier();
00029 
00030     // Virtual destructor: ensure that inheritance is possible.
00031     virtual ~ProjectionApplier();
00032 
00033 
00034   public:
00035 
00036     /// @name Metadata functions
00037     //@{
00038     /// Get the name of this Projection or Analysis class
00039     virtual std::string name() const = 0;
00040     //@}
00041 
00042     /// @name Projection "getting" functions
00043     //@{
00044     /// Get the contained projections, including recursion.
00045     std::set<ConstProjectionPtr> getProjections() const {
00046       return getProjHandler().getChildProjections(*this, ProjectionHandler::DEEP);
00047     }
00048 
00049 
00050     /// Get the named projection, specifying return type via a template argument.
00051     template <typename PROJ>
00052     const PROJ& getProjection(const std::string& name) const {
00053       const Projection& p = getProjHandler().getProjection(*this, name);
00054       return pcast<PROJ>(p);
00055     }
00056 
00057 
00058     /// Get the named projection (non-templated, so returns as a reference to a
00059     /// Projection base class).
00060     const Projection& getProjection(const std::string& name) const {
00061       return getProjHandler().getProjection(*this, name);
00062     }
00063     //@}
00064 
00065 
00066     /// @name Projection applying functions
00067     //@{
00068     /// Apply the supplied projection on @a event.
00069     template <typename PROJ>
00070     const PROJ& applyProjection(const Event& evt, const PROJ& proj) const {
00071       return pcast<PROJ>(_applyProjection(evt, proj));
00072     }
00073 
00074 
00075     /// Apply the supplied projection on @a event.
00076     template <typename PROJ>
00077     const PROJ& applyProjection(const Event& evt, const Projection& proj) const {
00078       return pcast<PROJ>(_applyProjection(evt, proj));
00079     }
00080 
00081 
00082     /// Apply the named projection on @a event.
00083     template <typename PROJ>
00084     const PROJ& applyProjection(const Event& evt, const std::string& name) const {
00085       return pcast<PROJ>(_applyProjection(evt, name));
00086     }
00087     //@}
00088 
00089 
00090   protected:
00091 
00092     Log& getLog() const {
00093       return Log::getLog("Rivet.ProjectionHandler");
00094     }
00095 
00096     /// Get a reference to the ProjectionHandler for this thread.
00097     ProjectionHandler& getProjHandler() const {
00098       return _projhandler;
00099     }
00100 
00101 
00102   protected:
00103 
00104 
00105     /// @name Projection registration functions
00106     //@{
00107 
00108     /// Register a contained projection. The type of the argument is used to
00109     /// instantiate a new projection internally: this new object is applied to
00110     /// events rather than the argument object. Hence you are advised to only use
00111     /// locally-scoped Projection objects in your Projection and Analysis
00112     /// constructors, and to avoid polymorphism (e.g. handling @c ConcreteProjection
00113     /// via a pointer or reference to type @c Projection) since this will screw
00114     /// up the internal type management.
00115     template <typename PROJ>
00116     const PROJ& addProjection(const PROJ& proj, const std::string& name) {
00117       const Projection& reg = _addProjection(proj, name);
00118       const PROJ& rtn = dynamic_cast<const PROJ&>(reg);
00119       return rtn;
00120     }
00121 
00122 
00123     /// Untemplated function to do the work...
00124     const Projection& _addProjection(const Projection& proj, const std::string& name);
00125 
00126     //@}
00127 
00128 
00129   private:
00130 
00131     /// Non-templated version of string-based applyProjection, to work around
00132     /// header dependency issue.
00133     const Projection& _applyProjection(const Event& evt, const std::string& name) const;
00134 
00135     /// Non-templated version of proj-based applyProjection, to work around
00136     /// header dependency issue.
00137     const Projection& _applyProjection(const Event& evt, const Projection& proj) const;
00138 
00139 
00140   protected:
00141 
00142     /// Flag to forbid projection registration in analyses until the init phase
00143     bool _allowProjReg;
00144 
00145 
00146   private:
00147 
00148     /// Pointer to projection handler.
00149     ProjectionHandler& _projhandler;
00150 
00151   };
00152 
00153 }
00154 
00155 #endif