Analysis.hh

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef RIVET_Analysis_HH
00003 #define RIVET_Analysis_HH
00004 
00005 #include "Rivet/Rivet.hh"
00006 #include "Rivet/Projection.fhh"
00007 #include "Rivet/Constraints.hh"
00008 #include "Rivet/AnalysisHandler.fhh"
00009 #include "Rivet/Event.fhh"
00010 #include "Rivet/Tools/Logging.fhh"
00011 #include "Rivet/RivetAIDA.fhh"
00012 
00013 
00014 namespace Rivet {
00015 
00016   /// @brief This is the base class of all analysis classes in Rivet.
00017   ///
00018   /// There are
00019   /// three virtual functions which should be implemented in base classes:
00020   ///
00021   /// void init() is called by Rivet before a run is started. Here the
00022   /// analysis class should book necessary histograms. The needed
00023   /// projections should probably rather be constructed in the
00024   /// constructor.
00025   ///
00026   /// void analyze(const Event&) is called once for each event. Here the
00027   /// analysis class should apply the necessary Projections and fill the
00028   /// histograms.
00029   ///
00030   /// void finish() is called after a run is finished. Here the analysis
00031   /// class should do whatever manipulations are necessary on the
00032   /// histograms. Writing the histograms to a file is, however, done by
00033   /// the Rivet class.
00034   class Analysis {
00035     
00036     /// The AnalysisHandler is a friend.
00037     friend class AnalysisHandler;
00038 
00039   public:
00040 
00041     /// Factory method for making an analysis - to be implemented in concrete classes.
00042     /// @todo Does inheritance apply to statics? Is this useful in enforcing a uniform interface?
00043     //static Analysis* create() = 0;
00044 
00045   public:
00046 
00047     /// @name Standard constructors and destructors.
00048     //@{
00049 
00050     /// The default constructor.
00051     inline Analysis() 
00052       : _theHandler(0), _madeHistoDir(false)
00053     { 
00054       setBeams(ANY, ANY);
00055     }
00056 
00057 //     /// Copy constructor from a pointer.
00058 //     inline Analysis(const Analysis* other) 
00059 //       : _theHandler(other->_theHandler), _madeHistoDir(other->_madeHistoDir)
00060 //     { 
00061 //       setBeams(ANY, ANY);
00062 //     }
00063 
00064     /// The destructor.
00065     inline virtual ~Analysis() { }
00066     //@}
00067 
00068   public:
00069 
00070     /// Initialize this analysis object. A concrete class should here
00071     /// book all necessary histograms. An overridden function must make
00072     /// sure it first calls the base class function.
00073     virtual void init() = 0;
00074 
00075     /// Analyze one event. A concrete class should here apply the
00076     /// necessary projections on the \a event and fill the relevant
00077     /// histograms. An overridden function must make sure it first calls
00078     /// the base class function.
00079     virtual void analyze(const Event& event) = 0;
00080 
00081     /// Finalize this analysis object. A concrete class should here make
00082     /// all necessary operations on the histograms. Writing the
00083     /// histograms to a file is, however, done by the Rivet class. An
00084     /// overridden function must make sure it first calls the base class
00085     /// function.
00086     virtual void finalize() = 0;
00087 
00088     /// Return the Cuts object of this analysis object. Derived
00089     /// classes should re-implement this function to return the combined
00090     /// RivetInfo object of this object and of any Projection objects
00091     /// upon which this depends.
00092     virtual const Cuts getCuts() const;
00093 
00094     /// Return the pair of incoming beams required by this analysis.
00095     inline virtual const BeamPair& getBeams() const {
00096       return _beams;
00097     }
00098 
00099     /// Is this analysis compatible with the named quantity set at the supplied value?
00100     inline virtual const bool isCompatible(const string& quantity, const double value) const {
00101       Cuts::const_iterator cut = getCuts().find(quantity);
00102       if (cut == getCuts().end()) return true;
00103       if (value > cut->second.lowerthan()) return false;
00104       if (value < cut->second.higherthan()) return false;
00105       return true;
00106     }
00107 
00108     /// Is this analysis able to run on the supplied pair of beams?
00109     inline virtual const bool isCompatible(const ParticleName& beam1, const ParticleName& beam2) const {
00110       BeamPair beams(beam1, beam2);
00111       return compatible(beams, getBeams());
00112       /// @todo Need to also check internal consistency of the analysis' 
00113       /// beam requirements with those of the projections it uses.
00114     }
00115 
00116     /// Is this analysis able to run on the BeamPair @a beams ?
00117     inline virtual const bool isCompatible(const BeamPair& beams) const {
00118       return compatible(beams, getBeams());
00119       /// @todo Need to also check internal consistency of the analysis' 
00120       /// beam requirements with those of the projections it uses.
00121     }
00122 
00123     /// Access the controlling AnalysisHandler object.
00124     inline AnalysisHandler& getHandler() const {
00125       return *_theHandler;
00126     }
00127 
00128     /// Get the name of the analysis (returns mangled RTTI name by default)
00129     inline virtual string getName() const {
00130       return typeid(*this).name();
00131     }
00132 
00133 
00134   protected:
00135     /// Get a Log object based on the getName() property of the calling analysis object.
00136     Log& getLog();
00137 
00138     /// Is this analysis able to run on the BeamPair @a beams ?
00139     virtual const bool checkConsistency() const;
00140     
00141     /// Get all the projections used by this analysis, including recursion. 
00142     /// WARNING: No caching or loop-avoidance is implemented at the moment.
00143     set<Projection*> getProjections() const;
00144 
00145   protected:
00146     /// @name AIDA analysis infrastructure.
00147     //@{
00148     /// Access the AIDA analysis factory of the controlling AnalysisHandler object.
00149     AIDA::IAnalysisFactory& analysisFactory();
00150 
00151     /// Access the AIDA tree of the controlling AnalysisHandler object.
00152     AIDA::ITree& tree();
00153 
00154     /// Access the AIDA histogram factory of the controlling AnalysisHandler object.
00155     AIDA::IHistogramFactory& histogramFactory();
00156 
00157     /// Access the AIDA histogram factory of the controlling AnalysisHandler object.
00158     AIDA::IDataPointSetFactory& datapointsetFactory();
00159 
00160     /// Get the canonical AIDA histogram path for this analysis.
00161     inline const string getHistoDir() const {
00162         return "/" + getName();
00163     }
00164     //@}
00165 
00166 
00167     /// @name Internal histogram and data point set booking (for use by Analysis sub-classes).
00168     //@{
00169 
00170     /// Book a 1D histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00171     /// (NB. this returns a pointer rather than a reference since it will 
00172     /// have to be stored in the analysis class - there's no point in forcing users to explicitly 
00173     /// get the pointer from a reference before they can use it!)
00174     AIDA::IHistogram1D* bookHistogram1D(const string& name, const string& title, 
00175                                         const size_t nbins, const double lower, const double upper);
00176 
00177     /// Book a 1D histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00178     /// (NB. this returns a pointer rather than a reference since it will 
00179     /// have to be stored in the analysis class - there's no point in forcing users to explicitly 
00180     /// get the pointer from a reference before they can use it!)
00181     AIDA::IHistogram1D* bookHistogram1D(const string& name, const string& title, 
00182                                         const vector<double>& binedges);
00183 
00184     /// Book a 1D histogram based on the paper, dataset and x/y-axis IDs in the corresponding
00185     /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file
00186     /// of the same filename as the analysis' getName() property.
00187     AIDA::IHistogram1D* bookHistogram1D(const size_t datasetId, const size_t xAxisId, 
00188                                         const size_t yAxisId, const string& title);
00189 
00190 
00191 
00192     /// Book a 2-dimensional data point set.
00193     /// (NB. this returns a pointer rather than a reference since it will 
00194     /// have to be stored in the analysis class - there's no point in forcing users to explicitly 
00195     /// get the pointer from a reference before they can use it!)
00196     AIDA::IDataPointSet* bookDataPointSet(const string& name, const string& title);
00197 
00198 
00199     /// Book a 2-dimensional data point set with equally spaced points in a range.
00200     /// (NB. this returns a pointer rather than a reference since it will 
00201     /// have to be stored in the analysis class - there's no point in forcing users to explicitly 
00202     /// get the pointer from a reference before they can use it!)
00203     AIDA::IDataPointSet* bookDataPointSet(const string& name, const string& title, 
00204                                           const size_t npts, const double lower, const double upper);
00205 
00206     /// Book a 2-dimensional data point set based on the paper, dataset and x/y-axis IDs in the corresponding
00207     /// HepData record. The binnings (x-errors) will be obtained by reading the bundled AIDA data record file
00208     /// of the same filename as the analysis' getName() property.
00209     AIDA::IDataPointSet* bookDataPointSet(const size_t datasetId, const size_t xAxisId, 
00210                                           const size_t yAxisId, const string& title);
00211     //@}
00212 
00213 
00214   private:
00215 
00216     /// Make the histogram directory.
00217     inline void makeHistoDir();
00218 
00219 
00220   protected:
00221 
00222     /// Set the colliding beam pair.
00223     inline Analysis& setBeams(const ParticleName& beam1, const ParticleName& beam2) {
00224       _beams.first = beam1;
00225       _beams.second = beam2;
00226       return *this;
00227     }
00228 
00229     /// Add a cut
00230     inline Analysis& addCut(const string& quantity, const Comparison& comparison, const double value) {
00231       _cuts.addCut(quantity, comparison, value);
00232       return *this;
00233     }
00234 
00235     /// Add a projection dependency to the projection list.
00236     inline Analysis& addProjection(Projection& proj) {
00237       _projections.insert(&proj);
00238       return *this;
00239     }
00240 
00241     /// Collection of pointers to projections, for automatically combining constraints.
00242     set<Projection*> _projections;
00243 
00244   private:
00245 
00246     /// Parameter constraints.
00247     Cuts _cuts;
00248 
00249     /// Allowed beam-type pair.
00250     BeamPair _beams;
00251 
00252     /// The controlling AnalysisHandler object.
00253     AnalysisHandler* _theHandler;
00254 
00255     /// Flag to indicate whether the histogram directory is present
00256     bool _madeHistoDir;
00257 
00258   private:
00259     /// The assignment operator is private and must never be called.
00260     /// In fact, it should not even be implemented.
00261     Analysis& operator=(const Analysis&);
00262   };
00263 
00264 
00265 }
00266 
00267 #endif