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