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/Analysis.fhh"
00007 #include "Rivet/Event.hh"
00008 #include "Rivet/Projection.hh"
00009 #include "Rivet/ProjectionApplier.hh"
00010 #include "Rivet/ProjectionHandler.hh"
00011 #include "Rivet/Constraints.hh"
00012 #include "Rivet/AnalysisHandler.fhh"
00013 #include "Rivet/AnalysisLoader.hh"
00014 #include "Rivet/Tools/Logging.fhh"
00015 #include "Rivet/RivetAIDA.fhh"
00016 
00017 
00018 /// @def vetoEvent
00019 /// Preprocessor define for vetoing events, including the log message and return.
00020 #define vetoEvent { getLog() << Log::DEBUG << "Vetoing event on line " << __LINE__ << " of " << __FILE__ << endl; return; }
00021 
00022 
00023 namespace Rivet {
00024 
00025   // Forward declaration
00026   class AnalysisInfo;
00027 
00028 
00029   /// @brief This is the base class of all analysis classes in Rivet.
00030   ///
00031   /// There are
00032   /// three virtual functions which should be implemented in base classes:
00033   ///
00034   /// void init() is called by Rivet before a run is started. Here the
00035   /// analysis class should book necessary histograms. The needed
00036   /// projections should probably rather be constructed in the
00037   /// constructor.
00038   ///
00039   /// void analyze(const Event&) is called once for each event. Here the
00040   /// analysis class should apply the necessary Projections and fill the
00041   /// histograms.
00042   ///
00043   /// void finalize() is called after a run is finished. Here the analysis
00044   /// class should do whatever manipulations are necessary on the
00045   /// histograms. Writing the histograms to a file is, however, done by
00046   /// the Rivet class.
00047   class Analysis : public ProjectionApplier {
00048  
00049     /// The AnalysisHandler is a friend.
00050     friend class AnalysisHandler;
00051 
00052 
00053   public:
00054 
00055     /// @name Standard constructors and destructors.
00056     //@{
00057 
00058     /// The default constructor.
00059     //Analysis();
00060 
00061     /// Constructor
00062     Analysis(const std::string& name);
00063 
00064     /// The destructor.
00065     virtual ~Analysis();
00066 
00067     //@}
00068 
00069 
00070   public:
00071 
00072     /// @name Main analysis methods
00073     //@{
00074     /// Initialize this analysis object. A concrete class should here
00075     /// book all necessary histograms. An overridden function must make
00076     /// sure it first calls the base class function.
00077     virtual void init() = 0;
00078 
00079     /// Analyze one event. A concrete class should here apply the
00080     /// necessary projections on the \a event and fill the relevant
00081     /// histograms. An overridden function must make sure it first calls
00082     /// the base class function.
00083     virtual void analyze(const Event& event) = 0;
00084 
00085     /// Finalize this analysis object. A concrete class should here make
00086     /// all necessary operations on the histograms. Writing the
00087     /// histograms to a file is, however, done by the Rivet class. An
00088     /// overridden function must make sure it first calls the base class
00089     /// function.
00090     virtual void finalize() = 0;
00091 
00092     //@}
00093 
00094 
00095   public:
00096 
00097     /// @name Metadata
00098     /// Metadata is used for querying from the command line and also for
00099     /// building web pages and the analysis pages in the Rivet manual.
00100     //@{
00101 
00102     /// Get the actual AnalysisInfo object in which all this metadata is stored.
00103     virtual const AnalysisInfo& info() const;
00104 
00105     /// @brief Get the name of the analysis.
00106     ///
00107     /// By default this is computed by combining the results of the experiment,
00108     /// year and Spires ID metadata methods and you should only override it if
00109     /// there's a good reason why those won't work.
00110     virtual std::string name() const;
00111 
00112     /// Get a the SPIRES/Inspire ID code for this analysis.
00113     virtual std::string spiresId() const;
00114 
00115     /// @brief Names & emails of paper/analysis authors.
00116     ///
00117     /// Names and email of authors in 'NAME <EMAIL>' format. The first
00118     /// name in the list should be the primary contact person.
00119     virtual std::vector<std::string> authors() const;
00120 
00121     /// @brief Get a short description of the analysis.
00122     ///
00123     /// Short (one sentence) description used as an index entry.
00124     /// Use @a description() to provide full descriptive paragraphs
00125     /// of analysis details.
00126     virtual std::string summary() const;
00127 
00128     /// @brief Get a full description of the analysis.
00129     ///
00130     /// Full textual description of this analysis, what it is useful for,
00131     /// what experimental techniques are applied, etc. Should be treated
00132     /// as a chunk of restructuredText (http://docutils.sourceforge.net/rst.html),
00133     /// with equations to be rendered as LaTeX with amsmath operators.
00134     virtual std::string description() const;
00135 
00136     /// @brief Information about the events needed as input for this analysis.
00137     ///
00138     /// Event types, energies, kinematic cuts, particles to be considered
00139     /// stable, etc. etc. Should be treated as a restructuredText bullet list
00140     /// (http://docutils.sourceforge.net/rst.html)
00141     virtual std::string runInfo() const;
00142  
00143     /// Experiment which performed and published this analysis.
00144     virtual std::string experiment() const;
00145 
00146     /// Collider on which the experiment ran.
00147     virtual std::string collider() const;
00148 
00149     /// Return the pair of incoming beams required by this analysis.
00150     virtual const BeamPair requiredBeams() const;
00151 
00152     /// Sets of valid beam energy pairs, in GeV
00153     virtual const std::vector<std::pair<double, double> >& energies() const;
00154 
00155     /// @brief When the original experimental analysis was published.
00156     ///
00157     /// When the refereed paper on which this is based was published,
00158     /// according to SPIRES.
00159     virtual std::string year() const;
00160 
00161     /// Journal, and preprint references.
00162     virtual std::vector<std::string> references() const;
00163 
00164     /// Whether this analysis is trusted (in any way!)
00165     virtual std::string status() const;
00166 
00167     //@}
00168 
00169 
00170     /// @name Run conditions
00171 
00172     /// Incoming beams for this run
00173     const ParticlePair& beams() const;
00174 
00175     /// Incoming beam IDs for this run
00176     const BeamPair beamIds() const;
00177 
00178     /// Centre of mass energy for this run
00179     double sqrtS() const;
00180 
00181     //@}
00182 
00183 
00184   public:
00185 
00186     /// Is this analysis able to run on the supplied pair of beams?
00187     virtual bool isCompatible(const ParticleName& beam1, const ParticleName& beam2) const;
00188 
00189     /// Is this analysis able to run on the BeamPair @a beams ?
00190     virtual bool isCompatible(const BeamPair& beams) const;
00191 
00192     /// Access the controlling AnalysisHandler object.
00193     AnalysisHandler& handler() const;
00194 
00195     /// Normalize the given histogram, @a histo. After this call the
00196     /// histogram will have been transformed to a DataPointSet with the
00197     /// same name and path. It has the same effect as
00198     /// @c scale(histo, norm/sumOfWeights).
00199     /// @param histo The histogram to be normalised.
00200     /// @param norm The new area of the histogram.
00201     /// @warning The old histogram will be deleted, and its pointer set to zero.
00202     void normalize(AIDA::IHistogram1D*& histo, double norm=1.0);
00203 
00204     /// Multiplicatively scale the given histogram, @a histo. After this call the
00205     /// histogram will have been transformed to a DataPointSet with the same name and path.
00206     /// @param histo The histogram to be scaled.
00207     /// @param scale The factor used to multiply the histogram bin heights.
00208     /// @warning The old histogram will be deleted, and its pointer set to zero.
00209     void scale(AIDA::IHistogram1D*& histo, double scale);
00210 
00211     /// Set the cross section from the generator
00212     Analysis& setCrossSection(double xs);
00213 
00214     /// Return true if this analysis needs to know the process cross-section.
00215     bool needsCrossSection() const;
00216 
00217 
00218   protected:
00219 
00220 
00221     /// Get a Log object based on the name() property of the calling analysis object.
00222     Log& getLog() const;
00223 
00224     /// Get the process cross-section in pb. Throws if this hasn't been set.
00225     double crossSection() const;
00226  
00227     /// Get the process cross-section per generated event in pb. Throws if this
00228     /// hasn't been set.
00229     double crossSectionPerEvent() const;
00230 
00231     /// Get the number of events seen (via the analysis handler). Use in the
00232     /// finalize phase only.
00233     size_t numEvents() const;
00234 
00235     /// Get the sum of event weights seen (via the analysis handler). Use in the
00236     /// finalize phase only.
00237     double sumOfWeights() const;
00238  
00239 
00240   protected:
00241 
00242     /// @name AIDA analysis infrastructure.
00243     //@{
00244     /// Access the AIDA analysis factory of the controlling AnalysisHandler object.
00245     AIDA::IAnalysisFactory& analysisFactory();
00246 
00247     /// Access the AIDA tree of the controlling AnalysisHandler object.
00248     AIDA::ITree& tree();
00249 
00250     /// Access the AIDA histogram factory of the controlling AnalysisHandler object.
00251     AIDA::IHistogramFactory& histogramFactory();
00252 
00253     /// Access the AIDA histogram factory of the controlling AnalysisHandler object.
00254     AIDA::IDataPointSetFactory& datapointsetFactory();
00255 
00256     /// Get the canonical histogram "directory" path for this analysis.
00257     const std::string histoDir() const;
00258 
00259     /// Get the canonical histogram path for the named histogram in this analysis.
00260     const std::string histoPath(const std::string& hname) const;
00261 
00262     //@}
00263 
00264 
00265     /// @name Internal histogram booking (for use by Analysis sub-classes).
00266     //@{
00267 
00268     /// Get bin edges for a named histo (using ref AIDA caching)
00269     const BinEdges& binEdges(const std::string& hname) const;
00270 
00271     /// Get bin edges for a numbered histo (using ref AIDA caching)
00272     const BinEdges& binEdges(size_t datasetId, size_t xAxisId, size_t yAxisId) const;
00273 
00274     /// Get bin edges with logarithmic widths
00275     BinEdges logBinEdges(size_t nbins, double lower, double upper);
00276 
00277     /// Book a 1D histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00278     /// (NB. this returns a pointer rather than a reference since it will
00279     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00280     /// get the pointer from a reference before they can use it!)
00281     AIDA::IHistogram1D* bookHistogram1D(const std::string& name,
00282                                         size_t nbins, double lower, double upper,
00283                                         const std::string& title="",
00284                                         const std::string& xtitle="", const std::string& ytitle="");
00285 
00286     /// Book a 1D histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00287     /// (NB. this returns a pointer rather than a reference since it will
00288     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00289     /// get the pointer from a reference before they can use it!)
00290     AIDA::IHistogram1D* bookHistogram1D(const std::string& name,
00291                                         const std::vector<double>& binedges, const std::string& title="",
00292                                         const std::string& xtitle="", const std::string& ytitle="");
00293 
00294     /// Book a 1D histogram based on the name in the corresponding AIDA
00295     /// file. The binnings will be obtained by reading the bundled AIDA data
00296     /// record file with the same filename as the analysis' name() property.
00297     AIDA::IHistogram1D* bookHistogram1D(const std::string& name, const std::string& title="",
00298                                         const std::string& xtitle="", const std::string& ytitle="");
00299 
00300     /// Book a 1D histogram based on the paper, dataset and x/y-axis IDs in the corresponding
00301     /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file
00302     /// of the same filename as the analysis' name() property.
00303     AIDA::IHistogram1D* bookHistogram1D(size_t datasetId, size_t xAxisId, size_t yAxisId, 
00304                                         const std::string& title="",
00305                                         const std::string& xtitle="", const std::string& ytitle="");
00306 
00307     //@}
00308 
00309 
00310     /// @name Internal profile histogram booking (for use by Analysis sub-classes).
00311     //@{
00312 
00313     /// Book a 1D profile histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00314     /// (NB. this returns a pointer rather than a reference since it will
00315     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00316     /// get the pointer from a reference before they can use it!)
00317     AIDA::IProfile1D* bookProfile1D(const std::string& name,
00318                                     size_t nbins, double lower, double upper,
00319                                     const std::string& title="",
00320                                     const std::string& xtitle="", const std::string& ytitle="");
00321 
00322     /// Book a 1D profile histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00323     /// (NB. this returns a pointer rather than a reference since it will
00324     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00325     /// get the pointer from a reference before they can use it!)
00326     AIDA::IProfile1D* bookProfile1D(const std::string& name,
00327                                     const std::vector<double>& binedges,
00328                                     const std::string& title="",
00329                                     const std::string& xtitle="", const std::string& ytitle="");
00330 
00331     /// Book a 1D profile histogram based on the name in the corresponding AIDA
00332     /// file. The binnings will be obtained by reading the bundled AIDA data
00333     /// record file with the same filename as the analysis' name() property.
00334     AIDA::IProfile1D* bookProfile1D(const std::string& name, const std::string& title="",
00335                                     const std::string& xtitle="", const std::string& ytitle="");
00336  
00337     /// Book a 1D profile histogram based on the paper, dataset and x/y-axis IDs in the corresponding
00338     /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file
00339     /// of the same filename as the analysis' name() property.
00340     AIDA::IProfile1D* bookProfile1D(size_t datasetId, size_t xAxisId, size_t yAxisId, 
00341                                     const std::string& title="",
00342                                     const std::string& xtitle="", const std::string& ytitle="");
00343     //@}
00344 
00345 
00346     /// @name Internal data point set booking (for use by Analysis sub-classes).
00347     //@{
00348 
00349     /// Book a 2-dimensional data point set.
00350     /// (NB. this returns a pointer rather than a reference since it will
00351     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00352     /// get the pointer from a reference before they can use it!)
00353     AIDA::IDataPointSet* bookDataPointSet(const std::string& name, const std::string& title="",
00354                                           const std::string& xtitle="", const std::string& ytitle="");
00355 
00356 
00357     /// Book a 2-dimensional data point set with equally spaced points in a range.
00358     /// (NB. this returns a pointer rather than a reference since it will
00359     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00360     /// get the pointer from a reference before they can use it!)
00361     AIDA::IDataPointSet* bookDataPointSet(const std::string& name,
00362                                           size_t npts, double lower, double upper,
00363                                           const std::string& title="",
00364                                           const std::string& xtitle="", const std::string& ytitle="");
00365 
00366     /// Book a 2-dimensional data point set based on the corresponding AIDA data
00367     /// file. The binnings (x-errors) will be obtained by reading the bundled
00368     /// AIDA data record file of the same filename as the analysis' name()
00369     /// property.
00370     //AIDA::IDataPointSet* bookDataPointSet(const std::string& name, const std::string& title);
00371 
00372     /// Book a 2-dimensional data point set based on the paper, dataset and x/y-axis IDs in the corresponding
00373     /// HepData record. The binnings (x-errors) will be obtained by reading the bundled AIDA data record file
00374     /// of the same filename as the analysis' name() property.
00375     AIDA::IDataPointSet* bookDataPointSet(size_t datasetId, size_t xAxisId, size_t yAxisId, 
00376                                           const std::string& title="",
00377                                           const std::string& xtitle="", const std::string& ytitle="");
00378 
00379     //@}
00380 
00381 
00382   private:
00383 
00384     /// @name Utility functions
00385     //@{
00386 
00387     /// Make the histogram directory.
00388     void _makeHistoDir();
00389 
00390     /// Get the bin edges for this paper from the reference AIDA file, and cache them.
00391     void _cacheBinEdges() const;
00392 
00393     /// Get the x-axis points for this paper from the reference AIDA file, and cache them.
00394     void _cacheXAxisData() const;
00395 
00396     //@}
00397 
00398 
00399   protected:
00400 
00401     /// Set the colliding beam pair.
00402     /// @deprecated Use .info file and AnalysisInfo class instead
00403     Analysis& setBeams(const ParticleName& beam1, const ParticleName& beam2);
00404 
00405     /// Declare whether this analysis needs to know the process cross-section from the generator.
00406     Analysis& setNeedsCrossSection(bool needed);
00407 
00408 
00409   protected:
00410 
00411     /// Name passed to constructor (used to find .info analysis data file, and as a fallback)
00412     string _defaultname;
00413 
00414     /// Pointer to analysis metadata object
00415     shared_ptr<AnalysisInfo> _info;
00416 
00417  
00418   private:
00419 
00420     /// @name Cross-section variables
00421     //@{
00422     double _crossSection;
00423     bool _gotCrossSection;
00424     bool _needsCrossSection;
00425     //@}
00426  
00427     /// The controlling AnalysisHandler object.
00428     AnalysisHandler* _analysishandler;
00429 
00430     /// Flag to indicate whether the histogram directory is present
00431     mutable bool _madeHistoDir;
00432 
00433     /// Collection of x-axis point data to speed up many autobookings: the
00434     /// reference data file should only be read once.
00435     /// @todo Reduce memory occupancy, or clear after initialisation?
00436     mutable map<string, vector<DPSXPoint> > _dpsData;
00437 
00438     /// Collection of cached bin edges to speed up many autobookings: the
00439     /// reference data file should only be read once.
00440     /// @todo Reduce memory occupancy, or clear after initialisation?
00441     mutable map<string, BinEdges> _histBinEdges;
00442 
00443 
00444   private:
00445 
00446     /// The assignment operator is private and must never be called.
00447     /// In fact, it should not even be implemented.
00448     Analysis& operator=(const Analysis&);
00449 
00450   };
00451 
00452 
00453 
00454   /////////////////////////////////////////////////////////////////////
00455 
00456 
00457 
00458   // Interface for analysis builders
00459   class AnalysisBuilderBase {
00460   public:
00461     AnalysisBuilderBase() { }
00462     virtual ~AnalysisBuilderBase() { }
00463  
00464     virtual Analysis* mkAnalysis() const = 0;
00465 
00466     const string name() const {
00467       Analysis* a = mkAnalysis();
00468       string rtn = a->name();
00469       delete a;
00470       return rtn;
00471     }
00472 
00473   protected:
00474     void _register() {
00475       AnalysisLoader::_registerBuilder(this);
00476     }
00477   };
00478 
00479 
00480   // Self-registering analysis plugin builder
00481   template <typename T>
00482   class AnalysisBuilder : public AnalysisBuilderBase {
00483   public:
00484     AnalysisBuilder() {
00485       _register();
00486     }
00487 
00488     Analysis* mkAnalysis() const {
00489       return new T();
00490     }
00491   };
00492 
00493 
00494 }
00495 
00496 #endif