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