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