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/RivetAIDA.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() = 0;
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() = 0;
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     bool needsCrossSection() const {
00233       return info().needsCrossSection();
00234     }
00235     /// Declare whether this analysis needs to know the process cross-section from the generator.
00236     Analysis& setNeedsCrossSection(bool needed=true) {
00237       info().setNeedsCrossSection(needed);
00238       return *this;
00239     }
00240 
00241     //@}
00242 
00243 
00244     /// @name Internal metadata modifiying methods
00245     //@{
00246 
00247     /// Get the actual AnalysisInfo object in which all this metadata is stored (non-const).
00248     AnalysisInfo& info() {
00249       assert(_info.get() != 0 && "No AnalysisInfo object :O");
00250       return *_info;
00251     }
00252 
00253     /// Set the required beams
00254     /// @deprecated To be removed in 2.0.0. Use .info file and AnalysisInfo class instead
00255     virtual Analysis& setBeams(PdgId beam1, PdgId beam2) {
00256       /// @todo Print out a warning to use setRequiredBeams() instead (and really to use .info files)
00257       return setRequiredBeams(std::vector<PdgIdPair>(1, make_pair(beam1, beam2)));
00258     }
00259 
00260     //@}
00261 
00262 
00263     /// @name Run conditions
00264     //@{
00265 
00266     /// Incoming beams for this run
00267     const ParticlePair& beams() const;
00268 
00269     /// Incoming beam IDs for this run
00270     const PdgIdPair beamIds() const;
00271 
00272     /// Centre of mass energy for this run
00273     double sqrtS() const;
00274 
00275     //@}
00276 
00277 
00278     /// @name Analysis / beam compatibility testing
00279     //@{
00280 
00281     /// Check if analysis is compatible with the provided beam particle IDs and energies
00282     bool isCompatible(const ParticlePair& beams) const;
00283 
00284     /// Check if analysis is compatible with the provided beam particle IDs and energies
00285     bool isCompatible(PdgId beam1, PdgId beam2, double e1, double e2) const;
00286 
00287     /// Check if analysis is compatible with the provided beam particle IDs and energies
00288     bool isCompatible(const PdgIdPair& beams, const std::pair<double,double>& energies) const;
00289 
00290     //@}
00291 
00292 
00293   public:
00294 
00295     /// Access the controlling AnalysisHandler object.
00296     AnalysisHandler& handler() const { return *_analysishandler; }
00297 
00298     /// Normalize the given histogram, @a histo. After this call the
00299     /// histogram will have been transformed to a DataPointSet with the
00300     /// same name and path. It has the same effect as
00301     /// @c scale(histo, norm/sumOfWeights).
00302     /// @param histo The histogram to be normalised.
00303     /// @param norm The new area of the histogram.
00304     /// @warning The old histogram will be deleted, and its pointer set to zero.
00305     void normalize(AIDA::IHistogram1D*& histo, double norm=1.0);
00306 
00307     /// Multiplicatively scale the given histogram, @a histo. After this call the
00308     /// histogram will have been transformed to a DataPointSet with the same name and path.
00309     /// @param histo The histogram to be scaled.
00310     /// @param scale The factor used to multiply the histogram bin heights.
00311     /// @warning The old histogram will be deleted, and its pointer set to zero.
00312     void scale(AIDA::IHistogram1D*& histo, double scale);
00313 
00314     /// Normalize the given histogram, @a histo. After this call the
00315     /// histogram will have been transformed to a DataPointSet with the
00316     /// same name and path. It has the same effect as
00317     /// @c scale(histo, norm/sumOfWeights).
00318     /// @param histo The histogram to be normalised.
00319     /// @param norm The new area of the histogram.
00320     /// @warning The old histogram will be deleted, and its pointer set to zero.
00321     void normalize(AIDA::IHistogram2D*& histo, double norm=1.0);
00322 
00323     /// Multiplicatively scale the given histogram, @a histo. After this call the
00324     /// histogram will have been transformed to a DataPointSet with the same name and path.
00325     /// @param histo The histogram to be scaled.
00326     /// @param scale The factor used to multiply the histogram bin heights.
00327     /// @warning The old histogram will be deleted, and its pointer set to zero.
00328     void scale(AIDA::IHistogram2D*& histo, double scale);
00329 
00330     /// Set the cross section from the generator
00331     Analysis& setCrossSection(double xs);
00332 
00333 
00334   protected:
00335 
00336     /// Get a Log object based on the name() property of the calling analysis object.
00337     Log& getLog() const;
00338 
00339     /// Get the process cross-section in pb. Throws if this hasn't been set.
00340     double crossSection() const;
00341 
00342     /// Get the process cross-section per generated event in pb. Throws if this
00343     /// hasn't been set.
00344     double crossSectionPerEvent() const;
00345 
00346     /// Get the number of events seen (via the analysis handler). Use in the
00347     /// finalize phase only.
00348     size_t numEvents() const;
00349 
00350     /// Get the sum of event weights seen (via the analysis handler). Use in the
00351     /// finalize phase only.
00352     double sumOfWeights() const;
00353 
00354 
00355   protected:
00356 
00357     /// @name AIDA analysis infrastructure.
00358     //@{
00359     /// Access the AIDA analysis factory of the controlling AnalysisHandler object.
00360     AIDA::IAnalysisFactory& analysisFactory();
00361 
00362     /// Access the AIDA tree of the controlling AnalysisHandler object.
00363     AIDA::ITree& tree();
00364 
00365     /// Access the AIDA histogram factory of the controlling AnalysisHandler object.
00366     AIDA::IHistogramFactory& histogramFactory();
00367 
00368     /// Access the AIDA histogram factory of the controlling AnalysisHandler object.
00369     AIDA::IDataPointSetFactory& datapointsetFactory();
00370 
00371     /// Get the canonical histogram "directory" path for this analysis.
00372     const std::string histoDir() const;
00373 
00374     /// Get the canonical histogram path for the named histogram in this analysis.
00375     const std::string histoPath(const std::string& hname) const;
00376 
00377     /// Get the internal histogram name for given d, x and y (cf. HepData)
00378     const std::string makeAxisCode(size_t datasetId, size_t xAxisId, size_t yAxisId) const;
00379 
00380     //@}
00381 
00382 
00383     /// @name Internal histogram booking (for use by Analysis sub-classes).
00384     //@{
00385 
00386     /// Get bin edges for a named histo (using ref AIDA caching)
00387     const BinEdges& binEdges(const std::string& hname) const;
00388 
00389     /// Get bin edges for a numbered histo (using ref AIDA caching)
00390     const BinEdges& binEdges(size_t datasetId, size_t xAxisId, size_t yAxisId) const;
00391 
00392     /// Get bin edges with logarithmic widths
00393     BinEdges logBinEdges(size_t nbins, double lower, double upper);
00394 
00395     /// Book a 1D histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00396     /// (NB. this returns a pointer rather than a reference since it will
00397     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00398     /// get the pointer from a reference before they can use it!)
00399     AIDA::IHistogram1D* bookHistogram1D(const std::string& name,
00400                                         size_t nbins, double lower, double upper,
00401                                         const std::string& title="",
00402                                         const std::string& xtitle="", const std::string& ytitle="");
00403 
00404     /// Book a 1D histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00405     /// (NB. this returns a pointer rather than a reference since it will
00406     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00407     /// get the pointer from a reference before they can use it!)
00408     AIDA::IHistogram1D* bookHistogram1D(const std::string& name,
00409                                         const std::vector<double>& binedges, const std::string& title="",
00410                                         const std::string& xtitle="", const std::string& ytitle="");
00411 
00412     /// Book a 2D histogram with @a nxbins and @a nybins uniformly
00413     /// distributed across the ranges @a xlower - @a xupper and @a
00414     /// ylower - @a yupper respectively along the x- and y-axis.
00415     /// (NB. this returns a pointer rather than a reference since it
00416     /// will have to be stored in the analysis class - there's no
00417     /// point in forcing users to explicitly get the pointer from a
00418     /// reference before they can use it!)
00419     AIDA::IHistogram2D*
00420     bookHistogram2D(const std::string& name,
00421             size_t nxbins, double xlower, double xupper,
00422             size_t nybins, double ylower, double yupper,
00423             const std::string& title="", const std::string& xtitle="",
00424             const std::string& ytitle="", const std::string& ztitle="");
00425 
00426     /// Book a 2D histogram with non-uniform bins defined by the
00427     /// vectorx of bin edges @a xbinedges and @a ybinedges.
00428     /// (NB. this returns a pointer rather than a reference since it
00429     /// will have to be stored in the analysis class - there's no
00430     /// point in forcing users to explicitly get the pointer from a
00431     /// reference before they can use it!)
00432     AIDA::IHistogram2D*
00433     bookHistogram2D(const std::string& name,
00434             const std::vector<double>& xbinedges,
00435             const std::vector<double>& ybinedges,
00436             const std::string& title="", const std::string& xtitle="",
00437             const std::string& ytitle="", const std::string& ztitle="");
00438 
00439     /// Book a 1D histogram based on the name in the corresponding AIDA
00440     /// file. The binnings will be obtained by reading the bundled AIDA data
00441     /// record file with the same filename as the analysis' name() property.
00442     AIDA::IHistogram1D* bookHistogram1D(const std::string& name, const std::string& title="",
00443                                         const std::string& xtitle="", const std::string& ytitle="");
00444 
00445     /// Book a 1D histogram based on the paper, dataset and x/y-axis IDs in the corresponding
00446     /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file
00447     /// of the same filename as the analysis' name() property.
00448     AIDA::IHistogram1D* bookHistogram1D(size_t datasetId, size_t xAxisId, size_t yAxisId,
00449                                         const std::string& title="",
00450                                         const std::string& xtitle="", const std::string& ytitle="");
00451 
00452     //@}
00453 
00454 
00455     /// @name Internal profile histogram booking (for use by Analysis sub-classes).
00456     //@{
00457 
00458     /// Book a 1D profile histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00459     /// (NB. this returns a pointer rather than a reference since it will
00460     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00461     /// get the pointer from a reference before they can use it!)
00462     AIDA::IProfile1D* bookProfile1D(const std::string& name,
00463                                     size_t nbins, double lower, double upper,
00464                                     const std::string& title="",
00465                                     const std::string& xtitle="", const std::string& ytitle="");
00466 
00467     /// Book a 1D profile histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00468     /// (NB. this returns a pointer rather than a reference since it will
00469     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00470     /// get the pointer from a reference before they can use it!)
00471     AIDA::IProfile1D* bookProfile1D(const std::string& name,
00472                                     const std::vector<double>& binedges,
00473                                     const std::string& title="",
00474                                     const std::string& xtitle="", const std::string& ytitle="");
00475 
00476     /// Book a 1D profile histogram based on the name in the corresponding AIDA
00477     /// file. The binnings will be obtained by reading the bundled AIDA data
00478     /// record file with the same filename as the analysis' name() property.
00479     AIDA::IProfile1D* bookProfile1D(const std::string& name, const std::string& title="",
00480                                     const std::string& xtitle="", const std::string& ytitle="");
00481 
00482     /// Book a 1D profile histogram based on the paper, dataset and x/y-axis IDs in the corresponding
00483     /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file
00484     /// of the same filename as the analysis' name() property.
00485     AIDA::IProfile1D* bookProfile1D(size_t datasetId, size_t xAxisId, size_t yAxisId,
00486                                     const std::string& title="",
00487                                     const std::string& xtitle="", const std::string& ytitle="");
00488     //@}
00489 
00490 
00491     /// @name Internal data point set booking (for use by Analysis sub-classes).
00492     //@{
00493 
00494     /// Book a 2-dimensional data point set.
00495     /// (NB. this returns a pointer rather than a reference since it will
00496     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00497     /// get the pointer from a reference before they can use it!)
00498     AIDA::IDataPointSet* bookDataPointSet(const std::string& name, const std::string& title="",
00499                                           const std::string& xtitle="", const std::string& ytitle="");
00500 
00501 
00502     /// Book a 2-dimensional data point set with equally spaced points in a range.
00503     /// (NB. this returns a pointer rather than a reference since it will
00504     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00505     /// get the pointer from a reference before they can use it!)
00506     AIDA::IDataPointSet* bookDataPointSet(const std::string& name,
00507                                           size_t npts, double lower, double upper,
00508                                           const std::string& title="",
00509                                           const std::string& xtitle="", const std::string& ytitle="");
00510 
00511     /// Book a 2-dimensional data point set based on the corresponding AIDA data
00512     /// file. The binnings (x-errors) will be obtained by reading the bundled
00513     /// AIDA data record file of the same filename as the analysis' name()
00514     /// property.
00515     //AIDA::IDataPointSet* bookDataPointSet(const std::string& name, const std::string& title);
00516 
00517     /// Book a 2-dimensional data point set based on the paper, dataset and x/y-axis IDs in the corresponding
00518     /// HepData record. The binnings (x-errors) will be obtained by reading the bundled AIDA data record file
00519     /// of the same filename as the analysis' name() property.
00520     AIDA::IDataPointSet* bookDataPointSet(size_t datasetId, size_t xAxisId, size_t yAxisId,
00521                                           const std::string& title="",
00522                                           const std::string& xtitle="", const std::string& ytitle="");
00523 
00524     //@}
00525 
00526 
00527   private:
00528 
00529     /// @name Utility functions
00530     //@{
00531 
00532     /// Make the histogram directory.
00533     void _makeHistoDir();
00534 
00535     /// Get the bin edges for this paper from the reference AIDA file, and cache them.
00536     void _cacheBinEdges() const;
00537 
00538     /// Get the x-axis points for this paper from the reference AIDA file, and cache them.
00539     void _cacheXAxisData() const;
00540 
00541     //@}
00542 
00543 
00544   protected:
00545 
00546     /// Name passed to constructor (used to find .info analysis data file, and as a fallback)
00547     string _defaultname;
00548 
00549     /// Pointer to analysis metadata object
00550     shared_ptr<AnalysisInfo> _info;
00551 
00552 
00553   private:
00554 
00555     /// @name Cross-section variables
00556     //@{
00557     double _crossSection;
00558     bool _gotCrossSection;
00559     //@}
00560 
00561     /// The controlling AnalysisHandler object.
00562     AnalysisHandler* _analysishandler;
00563 
00564     /// Flag to indicate whether the histogram directory is present
00565     mutable bool _madeHistoDir;
00566 
00567     /// Collection of x-axis point data to speed up many autobookings: the
00568     /// reference data file should only be read once.
00569     /// @todo Reduce memory occupancy, or clear after initialisation?
00570     mutable map<string, vector<DPSXPoint> > _dpsData;
00571 
00572     /// Collection of cached bin edges to speed up many autobookings: the
00573     /// reference data file should only be read once.
00574     /// @todo Reduce memory occupancy, or clear after initialisation?
00575     mutable map<string, BinEdges> _histBinEdges;
00576 
00577 
00578   private:
00579 
00580     /// The assignment operator is private and must never be called.
00581     /// In fact, it should not even be implemented.
00582     Analysis& operator=(const Analysis&);
00583 
00584   };
00585 
00586 
00587 }
00588 
00589 
00590 // Include definition of analysis plugin system so that analyses automatically see it when including Analysis.hh
00591 #include "Rivet/AnalysisBuilder.hh"
00592 
00593 
00594 #endif