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