rivet is hosted by Hepforge, IPPP Durham
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/AnalysisInfo.hh"
00008 #include "Rivet/Event.hh"
00009 #include "Rivet/Projection.hh"
00010 #include "Rivet/ProjectionApplier.hh"
00011 #include "Rivet/ProjectionHandler.hh"
00012 #include "Rivet/Constraints.hh"
00013 #include "Rivet/AnalysisHandler.fhh"
00014 #include "Rivet/AnalysisLoader.hh"
00015 #include "Rivet/Tools/Logging.fhh"
00016 #include "Rivet/RivetYODA.fhh"
00017 
00018 
00019 /// @def vetoEvent
00020 /// Preprocessor define for vetoing events, including the log message and return.
00021 #define vetoEvent                                                       \
00022   do { MSG_DEBUG("Vetoing event on line " << __LINE__ << " of " << __FILE__); return; } while(0)
00023 
00024 /// @def DECLARE_RIVET_PLUGIN
00025 /// Preprocessor define to prettify the global-object plugin hook mechanism.
00026 #define DECLARE_RIVET_PLUGIN(clsname) Rivet::AnalysisBuilder<clsname> plugin_ ## clsname
00027 
00028 
00029 
00030 namespace Rivet {
00031 
00032 
00033   /// @brief This is the base class of all analysis classes in Rivet.
00034   ///
00035   /// There are
00036   /// three virtual functions which should be implemented in base classes:
00037   ///
00038   /// void init() is called by Rivet before a run is started. Here the
00039   /// analysis class should book necessary histograms. The needed
00040   /// projections should probably rather be constructed in the
00041   /// constructor.
00042   ///
00043   /// void analyze(const Event&) is called once for each event. Here the
00044   /// analysis class should apply the necessary Projections and fill the
00045   /// histograms.
00046   ///
00047   /// void finalize() is called after a run is finished. Here the analysis
00048   /// class should do whatever manipulations are necessary on the
00049   /// histograms. Writing the histograms to a file is, however, done by
00050   /// the Rivet class.
00051   class Analysis : public ProjectionApplier {
00052 
00053     /// The AnalysisHandler is a friend.
00054     friend class AnalysisHandler;
00055 
00056 
00057   public:
00058 
00059     /// @name Standard constructors and destructors.
00060     //@{
00061 
00062     // /// The default constructor.
00063     // Analysis();
00064 
00065     /// Constructor
00066     Analysis(const std::string& name);
00067 
00068     /// The destructor.
00069     virtual ~Analysis() {}
00070 
00071     //@}
00072 
00073 
00074   public:
00075 
00076     /// @name Main analysis methods
00077     //@{
00078 
00079     /// Initialize this analysis object. A concrete class should here
00080     /// book all necessary histograms. An overridden function must make
00081     /// sure it first calls the base class function.
00082     virtual void init() { }
00083 
00084     /// Analyze one event. A concrete class should here apply the
00085     /// necessary projections on the \a event and fill the relevant
00086     /// histograms. An overridden function must make sure it first calls
00087     /// the base class function.
00088     virtual void analyze(const Event& event) = 0;
00089 
00090     /// Finalize this analysis object. A concrete class should here make
00091     /// all necessary operations on the histograms. Writing the
00092     /// histograms to a file is, however, done by the Rivet class. An
00093     /// overridden function must make sure it first calls the base class
00094     /// function.
00095     virtual void finalize() { }
00096 
00097     //@}
00098 
00099 
00100   public:
00101 
00102     /// @name Metadata
00103     /// Metadata is used for querying from the command line and also for
00104     /// building web pages and the analysis pages in the Rivet manual.
00105     //@{
00106 
00107     /// Get the actual AnalysisInfo object in which all this metadata is stored.
00108     const AnalysisInfo& info() const {
00109       assert(_info.get() != 0 && "No AnalysisInfo object :O");
00110       return *_info;
00111     }
00112 
00113     /// @brief Get the name of the analysis.
00114     ///
00115     /// By default this is computed by combining the results of the experiment,
00116     /// year and Spires ID metadata methods and you should only override it if
00117     /// there's a good reason why those won't work.
00118     virtual std::string name() const {
00119       return (info().name().empty()) ? _defaultname : info().name();
00120     }
00121 
00122     /// Get the Inspire ID code for this analysis.
00123     virtual std::string inspireId() const {
00124       return info().inspireId();
00125     }
00126 
00127     /// Get the SPIRES ID code for this analysis (~deprecated).
00128     virtual std::string spiresId() const {
00129       return info().spiresId();
00130     }
00131 
00132     /// @brief Names & emails of paper/analysis authors.
00133     ///
00134     /// Names and email of authors in 'NAME <EMAIL>' format. The first
00135     /// name in the list should be the primary contact person.
00136     virtual std::vector<std::string> authors() const {
00137       return info().authors();
00138     }
00139 
00140     /// @brief Get a short description of the analysis.
00141     ///
00142     /// Short (one sentence) description used as an index entry.
00143     /// Use @a description() to provide full descriptive paragraphs
00144     /// of analysis details.
00145     virtual std::string summary() const {
00146       return info().summary();
00147     }
00148 
00149     /// @brief Get a full description of the analysis.
00150     ///
00151     /// Full textual description of this analysis, what it is useful for,
00152     /// what experimental techniques are applied, etc. Should be treated
00153     /// as a chunk of restructuredText (http://docutils.sourceforge.net/rst.html),
00154     /// with equations to be rendered as LaTeX with amsmath operators.
00155     virtual std::string description() const {
00156       return info().description();
00157     }
00158 
00159     /// @brief Information about the events needed as input for this analysis.
00160     ///
00161     /// Event types, energies, kinematic cuts, particles to be considered
00162     /// stable, etc. etc. Should be treated as a restructuredText bullet list
00163     /// (http://docutils.sourceforge.net/rst.html)
00164     virtual std::string runInfo() const {
00165       return info().runInfo();
00166     }
00167 
00168     /// Experiment which performed and published this analysis.
00169     virtual std::string experiment() const {
00170       return info().experiment();
00171     }
00172 
00173     /// Collider on which the experiment ran.
00174     virtual std::string collider() const {
00175       return info().collider();
00176     }
00177 
00178     /// When the original experimental analysis was published.
00179     virtual std::string year() const {
00180       return info().year();
00181     }
00182 
00183     /// Journal, and preprint references.
00184     virtual std::vector<std::string> references() const {
00185       return info().references();
00186     }
00187 
00188     /// BibTeX citation key for this article.
00189     virtual std::string bibKey() const {
00190       return info().bibKey();
00191     }
00192 
00193     /// BibTeX citation entry for this article.
00194     virtual std::string bibTeX() const {
00195       return info().bibTeX();
00196     }
00197 
00198     /// Whether this analysis is trusted (in any way!)
00199     virtual std::string status() const {
00200       return (info().status().empty()) ? "UNVALIDATED" : info().status();
00201     }
00202 
00203     /// Any work to be done on this analysis.
00204     virtual std::vector<std::string> todos() const {
00205       return info().todos();
00206     }
00207 
00208 
00209     /// Return the allowed pairs of incoming beams required by this analysis.
00210     virtual const std::vector<PdgIdPair>& requiredBeams() const {
00211       return info().beams();
00212     }
00213     /// Declare the allowed pairs of incoming beams required by this analysis.
00214     virtual Analysis& setRequiredBeams(const std::vector<PdgIdPair>& requiredBeams) {
00215       info().setBeams(requiredBeams);
00216       return *this;
00217     }
00218 
00219 
00220     /// Sets of valid beam energy pairs, in GeV
00221     virtual const std::vector<std::pair<double, double> >& requiredEnergies() const {
00222       return info().energies();
00223     }
00224     /// Declare the list of valid beam energy pairs, in GeV
00225     virtual Analysis& setRequiredEnergies(const std::vector<std::pair<double, double> >& requiredEnergies) {
00226       info().setEnergies(requiredEnergies);
00227       return *this;
00228     }
00229 
00230 
00231     /// Return true if this analysis needs to know the process cross-section.
00232     /// @todo Remove this and require HepMC >= 2.06
00233     bool needsCrossSection() const {
00234       return info().needsCrossSection();
00235     }
00236     /// Declare whether this analysis needs to know the process cross-section from the generator.
00237     /// @todo Remove this and require HepMC >= 2.06
00238     Analysis& setNeedsCrossSection(bool needed=true) {
00239       info().setNeedsCrossSection(needed);
00240       return *this;
00241     }
00242 
00243     //@}
00244 
00245 
00246     /// @name Internal metadata modifying methods
00247     //@{
00248 
00249     /// Get the actual AnalysisInfo object in which all this metadata is stored (non-const).
00250     AnalysisInfo& info() {
00251       assert(_info.get() != 0 && "No AnalysisInfo object :O");
00252       return *_info;
00253     }
00254 
00255     //@}
00256 
00257 
00258     /// @name Run conditions
00259     //@{
00260 
00261     /// Incoming beams for this run
00262     const ParticlePair& beams() const;
00263 
00264     /// Incoming beam IDs for this run
00265     const PdgIdPair beamIds() const;
00266 
00267     /// Centre of mass energy for this run
00268     double sqrtS() const;
00269 
00270     //@}
00271 
00272 
00273     /// @name Analysis / beam compatibility testing
00274     //@{
00275 
00276     /// Check if analysis is compatible with the provided beam particle IDs and energies
00277     bool isCompatible(const ParticlePair& beams) const;
00278 
00279     /// Check if analysis is compatible with the provided beam particle IDs and energies
00280     bool isCompatible(PdgId beam1, PdgId beam2, double e1, double e2) const;
00281 
00282     /// Check if analysis is compatible with the provided beam particle IDs and energies
00283     bool isCompatible(const PdgIdPair& beams, const std::pair<double,double>& energies) const;
00284 
00285     //@}
00286 
00287 
00288   public:
00289 
00290     /// Access the controlling AnalysisHandler object.
00291     AnalysisHandler& handler() const { return *_analysishandler; }
00292 
00293     /// Normalize the given histogram, @a histo, to area = @a norm.
00294     ///
00295     /// NB. The histogram is no longer invalidated by this procedure.
00296     void normalize(Histo1DPtr histo, double norm=1.0, bool includeoverflows=true);
00297 
00298     /// Multiplicatively scale the given histogram, @a histo, by factor @s scale.
00299     ///
00300     /// NB. The histogram is no longer invalidated by this procedure.
00301     void scale(Histo1DPtr histo, double scale);
00302 
00303     /// Normalize the given histogram, @a histo, to area = @a norm.
00304     ///
00305     /// NB. The histogram is no longer invalidated by this procedure.
00306     // void normalize(Histo2DPtr histo, double norm=1.0);
00307 
00308     /// Multiplicatively scale the given histogram, @a histo, by factor @s scale.
00309     ///
00310     /// NB. The histogram is no longer invalidated by this procedure.
00311     // void scale(Histo2DPtr histo, double scale);
00312 
00313     /// Set the cross section from the generator
00314     Analysis& setCrossSection(double xs);
00315 
00316     /// Helper for histogram division. Preserves the path information
00317     /// of the target.
00318     void divide(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const;
00319 
00320     /// Helper for profile histogram division. Preserves the path information
00321     /// of the target.
00322     void divide(Profile1DPtr p1, Profile1DPtr p2, Scatter2DPtr s) const;
00323 
00324     /// Helper for histogram division. Preserves the path information
00325     /// of the target.
00326     void divide(const YODA::Histo1D & h1,
00327                 const YODA::Histo1D & h2, Scatter2DPtr s) const;
00328 
00329     /// Helper for profile histogram division. Preserves the path information
00330     /// of the target.
00331     void divide(const YODA::Profile1D & p1,
00332                 const YODA::Profile1D & p2, Scatter2DPtr s) const;
00333 
00334 
00335   protected:
00336 
00337     /// Get a Log object based on the name() property of the calling analysis object.
00338     Log& getLog() const;
00339 
00340     /// Get the process cross-section in pb. Throws if this hasn't been set.
00341     double crossSection() const;
00342 
00343     /// Get the process cross-section per generated event in pb. Throws if this
00344     /// hasn't been set.
00345     double crossSectionPerEvent() const;
00346 
00347     /// Get the number of events seen (via the analysis handler). Use in the
00348     /// finalize phase only.
00349     size_t numEvents() const;
00350 
00351     /// Get the sum of event weights seen (via the analysis handler). Use in the
00352     /// finalize phase only.
00353     double sumOfWeights() const;
00354 
00355 
00356   protected:
00357 
00358     /// @name AIDA analysis infrastructure.
00359     //@{
00360     /// Get the canonical histogram "directory" path for this analysis.
00361     const std::string histoDir() const;
00362 
00363     /// Get the canonical histogram path for the named histogram in this analysis.
00364     const std::string histoPath(const std::string& hname) const;
00365 
00366     /// Get the canonical histogram path for the numbered histogram in this analysis.
00367     const std::string histoPath(size_t datasetId, size_t xAxisId, size_t yAxisId) const;
00368 
00369     /// Get the internal histogram name for given d, x and y (cf. HepData)
00370     const std::string makeAxisCode(size_t datasetId, size_t xAxisId, size_t yAxisId) const;
00371 
00372     //@}
00373 
00374 
00375     /// @name Internal histogram booking (for use by Analysis sub-classes).
00376     //@{
00377 
00378     /// Get reference data for a named histo
00379     const YODA::Scatter2D & referenceData(const string& hname) const;
00380 
00381     /// Get reference data for a numbered histo
00382     const YODA::Scatter2D & referenceData(size_t datasetId,
00383                                           size_t xAxisId, size_t yAxisId) const;
00384 
00385     /// Book a 1D histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00386     /// (NB. this returns a pointer rather than a reference since it will
00387     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00388     /// get the pointer from a reference before they can use it!)
00389     Histo1DPtr bookHisto1D(const std::string& name,
00390                            size_t nbins, double lower, double upper,
00391                            const std::string& title="",
00392                            const std::string& xtitle="", const std::string& ytitle="");
00393 
00394     /// Book a 1D histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00395     /// (NB. this returns a pointer rather than a reference since it will
00396     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00397     /// get the pointer from a reference before they can use it!)
00398     Histo1DPtr bookHisto1D(const std::string& name,
00399                            const std::vector<double>& binedges, const std::string& title="",
00400                            const std::string& xtitle="", const std::string& ytitle="");
00401 
00402     // /// Book a 2D histogram with @a nxbins and @a nybins uniformly
00403     // /// distributed across the ranges @a xlower - @a xupper and @a
00404     // /// ylower - @a yupper respectively along the x- and y-axis.
00405     // /// (NB. this returns a pointer rather than a reference since it
00406     // /// will have to be stored in the analysis class - there's no
00407     // /// point in forcing users to explicitly get the pointer from a
00408     // /// reference before they can use it!)
00409     // AIDA::IHistogram2D*
00410     // bookHistogram2D(const std::string& name,
00411     //          size_t nxbins, double xlower, double xupper,
00412     //          size_t nybins, double ylower, double yupper,
00413     //          const std::string& title="", const std::string& xtitle="",
00414     //          const std::string& ytitle="", const std::string& ztitle="");
00415 
00416     // /// Book a 2D histogram with non-uniform bins defined by the
00417     // /// vectorx of bin edges @a xbinedges and @a ybinedges.
00418     // /// (NB. this returns a pointer rather than a reference since it
00419     // /// will have to be stored in the analysis class - there's no
00420     // /// point in forcing users to explicitly get the pointer from a
00421     // /// reference before they can use it!)
00422     // AIDA::IHistogram2D*
00423     // bookHistogram2D(const std::string& name,
00424     //          const std::vector<double>& xbinedges,
00425     //          const std::vector<double>& ybinedges,
00426     //          const std::string& title="", const std::string& xtitle="",
00427     //          const std::string& ytitle="", const std::string& ztitle="");
00428 
00429     /// Book a 1D histogram based on the name in the corresponding AIDA
00430     /// file. The binnings will be obtained by reading the bundled AIDA data
00431     /// record file with the same filename as the analysis' name() property.
00432     Histo1DPtr bookHisto1D(const std::string& name,
00433                            const std::string& title="",
00434                            const std::string& xtitle="",
00435                            const std::string& ytitle="");
00436 
00437     /// Book a 1D histogram based on the paper, dataset and x/y-axis IDs in the corresponding
00438     /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file
00439     /// of the same filename as the analysis' name() property.
00440     Histo1DPtr bookHisto1D(size_t datasetId, size_t xAxisId, size_t yAxisId,
00441                            const std::string& title="",
00442                            const std::string& xtitle="",
00443                            const std::string& ytitle="");
00444 
00445     //@}
00446 
00447 
00448     /// @name Internal profile histogram booking (for use by Analysis sub-classes).
00449     //@{
00450 
00451     /// Book a 1D profile histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00452     /// (NB. this returns a pointer rather than a reference since it will
00453     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00454     /// get the pointer from a reference before they can use it!)
00455     Profile1DPtr bookProfile1D(const std::string& name,
00456                                size_t nbins, double lower, double upper,
00457                                const std::string& title="",
00458                                const std::string& xtitle="", const std::string& ytitle="");
00459 
00460     /// Book a 1D profile histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00461     /// (NB. this returns a pointer rather than a reference since it will
00462     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00463     /// get the pointer from a reference before they can use it!)
00464     Profile1DPtr bookProfile1D(const std::string& name,
00465                                const std::vector<double>& binedges,
00466                                const std::string& title="",
00467                                const std::string& xtitle="", const std::string& ytitle="");
00468 
00469     /// Book a 1D profile histogram based on the name in the corresponding AIDA
00470     /// file. The binnings will be obtained by reading the bundled AIDA data
00471     /// record file with the same filename as the analysis' name() property.
00472     Profile1DPtr bookProfile1D(const std::string& name, const std::string& title="",
00473                                const std::string& xtitle="", const std::string& ytitle="");
00474 
00475     /// Book a 1D profile histogram based on the paper, dataset and x/y-axis IDs in the corresponding
00476     /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file
00477     /// of the same filename as the analysis' name() property.
00478     Profile1DPtr bookProfile1D(size_t datasetId, size_t xAxisId, size_t yAxisId,
00479                                const std::string& title="",
00480                                const std::string& xtitle="", const std::string& ytitle="");
00481     //@}
00482 
00483 
00484     /// @name Internal data point set booking (for use by Analysis sub-classes).
00485     //@{
00486 
00487     /// Book a 2-dimensional data point set.
00488     /// (NB. this returns a pointer rather than a reference since it will
00489     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00490     /// get the pointer from a reference before they can use it!)
00491     Scatter2DPtr bookScatter2D(const std::string& name, const std::string& title="",
00492                                const std::string& xtitle="", const std::string& ytitle="");
00493 
00494 
00495     /// Book a 2-dimensional data point set with equally spaced points in a range.
00496     /// (NB. this returns a pointer rather than a reference since it will
00497     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00498     /// get the pointer from a reference before they can use it!)
00499     Scatter2DPtr bookScatter2D(const std::string& name,
00500                                size_t npts, double lower, double upper,
00501                                const std::string& title="",
00502                                const std::string& xtitle="", const std::string& ytitle="");
00503 
00504     /// Book a 2-dimensional data point set based on the corresponding AIDA data
00505     /// file. The binnings (x-errors) will be obtained by reading the bundled
00506     /// AIDA data record file of the same filename as the analysis' name()
00507     /// property.
00508     Scatter2DPtr bookScatter2D(const std::string& name, const std::string& title);
00509 
00510     /// Book a 2-dimensional data point set based on the paper, dataset and x/y-axis IDs in the corresponding
00511     /// HepData record. The binnings (x-errors) will be obtained by reading the bundled AIDA data record file
00512     /// of the same filename as the analysis' name() property.
00513     Scatter2DPtr bookScatter2D(size_t datasetId, size_t xAxisId, size_t yAxisId,
00514                                const std::string& title="",
00515                                const std::string& xtitle="", const std::string& ytitle="");
00516 
00517     //@}
00518 
00519   public:
00520     /// List of registered plot objects
00521     const vector<AnalysisObjectPtr> & plots() const {
00522       return _plotobjects;
00523     }
00524 
00525   private:
00526 
00527     /// @name Utility functions
00528     //@{
00529 
00530     /// Get the reference data for this paper and cache it.
00531     void _cacheRefData() const;
00532 
00533     //@}
00534 
00535 
00536   protected:
00537 
00538     /// Add a plot object to the final output list
00539     void addPlot(AnalysisObjectPtr);
00540 
00541     /// Name passed to constructor (used to find .info analysis data file, and as a fallback)
00542     string _defaultname;
00543 
00544     /// Pointer to analysis metadata object
00545     shared_ptr<AnalysisInfo> _info;
00546 
00547 
00548   private:
00549 
00550     /// Storage of all plot objects
00551     vector<AnalysisObjectPtr> _plotobjects;
00552 
00553     /// @name Cross-section variables
00554     //@{
00555     double _crossSection;
00556     bool _gotCrossSection;
00557     //@}
00558 
00559     /// The controlling AnalysisHandler object.
00560     AnalysisHandler* _analysishandler;
00561 
00562     /// Collection of cached refdata to speed up many autobookings: the
00563     /// reference data file should only be read once.
00564     mutable RefDataMap _refdata;
00565 
00566   private:
00567 
00568     /// The assignment operator is private and must never be called.
00569     /// In fact, it should not even be implemented.
00570     Analysis& operator=(const Analysis&);
00571 
00572   };
00573 
00574 
00575 }
00576 
00577 
00578 // Include definition of analysis plugin system so that analyses automatically see it when including Analysis.hh
00579 #include "Rivet/AnalysisBuilder.hh"
00580 
00581 
00582 #endif