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