Analysis.hh

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifndef RIVET_Analysis_HH
00003 #define RIVET_Analysis_HH
00004 
00005 #include "Rivet/Rivet.hh"
00006 #include "Rivet/Analysis.fhh"
00007 #include "Rivet/Event.hh"
00008 #include "Rivet/Projection.hh"
00009 #include "Rivet/ProjectionApplier.hh"
00010 #include "Rivet/ProjectionHandler.hh"
00011 #include "Rivet/Constraints.hh"
00012 #include "Rivet/AnalysisHandler.fhh"
00013 #include "Rivet/AnalysisLoader.hh"
00014 #include "Rivet/Tools/Logging.fhh"
00015 #include "Rivet/RivetAIDA.fhh"
00016 
00017 
00018 /// @def vetoEvent
00019 /// Preprocessor define for vetoing events, including the log message and return.
00020 #define vetoEvent { getLog() << Log::DEBUG << "Vetoing event on line " << __LINE__ << " of " << __FILE__ << endl; return; }
00021 
00022 
00023 namespace Rivet {
00024 
00025   // Forward declaration
00026   class AnalysisInfo;
00027 
00028 
00029   /// @brief This is the base class of all analysis classes in Rivet.
00030   ///
00031   /// There are
00032   /// three virtual functions which should be implemented in base classes:
00033   ///
00034   /// void init() is called by Rivet before a run is started. Here the
00035   /// analysis class should book necessary histograms. The needed
00036   /// projections should probably rather be constructed in the
00037   /// constructor.
00038   ///
00039   /// void analyze(const Event&) is called once for each event. Here the
00040   /// analysis class should apply the necessary Projections and fill the
00041   /// histograms.
00042   ///
00043   /// void finalize() is called after a run is finished. Here the analysis
00044   /// class should do whatever manipulations are necessary on the
00045   /// histograms. Writing the histograms to a file is, however, done by
00046   /// the Rivet class.
00047   class Analysis : public ProjectionApplier {
00048 
00049     /// The AnalysisHandler is a friend.
00050     friend class AnalysisHandler;
00051 
00052 
00053   public:
00054 
00055     /// @name Standard constructors and destructors.
00056     //@{
00057 
00058     /// The default constructor.
00059     //Analysis();
00060 
00061     /// Constructor
00062     Analysis(const std::string& name);
00063 
00064     /// The destructor.
00065     virtual ~Analysis();
00066 
00067     //@}
00068 
00069 
00070   public:
00071 
00072     /// @name Main analysis methods
00073     //@{
00074 
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     /// Set the cross section from the generator
00222     Analysis& setCrossSection(double xs);
00223 
00224     /// Return true if this analysis needs to know the process cross-section.
00225     bool needsCrossSection() const;
00226 
00227 
00228   protected:
00229 
00230 
00231     /// Get a Log object based on the name() property of the calling analysis object.
00232     Log& getLog() const;
00233 
00234     /// Get the process cross-section in pb. Throws if this hasn't been set.
00235     double crossSection() const;
00236 
00237     /// Get the process cross-section per generated event in pb. Throws if this
00238     /// hasn't been set.
00239     double crossSectionPerEvent() const;
00240 
00241     /// Get the number of events seen (via the analysis handler). Use in the
00242     /// finalize phase only.
00243     size_t numEvents() const;
00244 
00245     /// Get the sum of event weights seen (via the analysis handler). Use in the
00246     /// finalize phase only.
00247     double sumOfWeights() const;
00248 
00249 
00250   protected:
00251 
00252     /// @name AIDA analysis infrastructure.
00253     //@{
00254     /// Access the AIDA analysis factory of the controlling AnalysisHandler object.
00255     AIDA::IAnalysisFactory& analysisFactory();
00256 
00257     /// Access the AIDA tree of the controlling AnalysisHandler object.
00258     AIDA::ITree& tree();
00259 
00260     /// Access the AIDA histogram factory of the controlling AnalysisHandler object.
00261     AIDA::IHistogramFactory& histogramFactory();
00262 
00263     /// Access the AIDA histogram factory of the controlling AnalysisHandler object.
00264     AIDA::IDataPointSetFactory& datapointsetFactory();
00265 
00266     /// Get the canonical histogram "directory" path for this analysis.
00267     const std::string histoDir() const;
00268 
00269     /// Get the canonical histogram path for the named histogram in this analysis.
00270     const std::string histoPath(const std::string& hname) const;
00271 
00272     //@}
00273 
00274 
00275     /// @name Internal histogram booking (for use by Analysis sub-classes).
00276     //@{
00277 
00278     /// Get bin edges for a named histo (using ref AIDA caching)
00279     const BinEdges& binEdges(const std::string& hname) const;
00280 
00281     /// Get bin edges for a numbered histo (using ref AIDA caching)
00282     const BinEdges& binEdges(size_t datasetId, size_t xAxisId, size_t yAxisId) const;
00283 
00284     /// Get bin edges with logarithmic widths
00285     BinEdges logBinEdges(size_t nbins, double lower, double upper);
00286 
00287     /// Book a 1D histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00288     /// (NB. this returns a pointer rather than a reference since it will
00289     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00290     /// get the pointer from a reference before they can use it!)
00291     AIDA::IHistogram1D* bookHistogram1D(const std::string& name,
00292                                         size_t nbins, double lower, double upper,
00293                                         const std::string& title="",
00294                                         const std::string& xtitle="", const std::string& ytitle="");
00295 
00296     /// Book a 1D histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00297     /// (NB. this returns a pointer rather than a reference since it will
00298     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00299     /// get the pointer from a reference before they can use it!)
00300     AIDA::IHistogram1D* bookHistogram1D(const std::string& name,
00301                                         const std::vector<double>& binedges, const std::string& title="",
00302                                         const std::string& xtitle="", const std::string& ytitle="");
00303 
00304     /// Book a 1D histogram based on the name in the corresponding AIDA
00305     /// file. The binnings will be obtained by reading the bundled AIDA data
00306     /// record file with the same filename as the analysis' name() property.
00307     AIDA::IHistogram1D* bookHistogram1D(const std::string& name, const std::string& title="",
00308                                         const std::string& xtitle="", const std::string& ytitle="");
00309 
00310     /// Book a 1D histogram based on the paper, dataset and x/y-axis IDs in the corresponding
00311     /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file
00312     /// of the same filename as the analysis' name() property.
00313     AIDA::IHistogram1D* bookHistogram1D(size_t datasetId, size_t xAxisId, size_t yAxisId,
00314                                         const std::string& title="",
00315                                         const std::string& xtitle="", const std::string& ytitle="");
00316 
00317     //@}
00318 
00319 
00320     /// @name Internal profile histogram booking (for use by Analysis sub-classes).
00321     //@{
00322 
00323     /// Book a 1D profile histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00324     /// (NB. this returns a pointer rather than a reference since it will
00325     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00326     /// get the pointer from a reference before they can use it!)
00327     AIDA::IProfile1D* bookProfile1D(const std::string& name,
00328                                     size_t nbins, double lower, double upper,
00329                                     const std::string& title="",
00330                                     const std::string& xtitle="", const std::string& ytitle="");
00331 
00332     /// Book a 1D profile histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00333     /// (NB. this returns a pointer rather than a reference since it will
00334     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00335     /// get the pointer from a reference before they can use it!)
00336     AIDA::IProfile1D* bookProfile1D(const std::string& name,
00337                                     const std::vector<double>& binedges,
00338                                     const std::string& title="",
00339                                     const std::string& xtitle="", const std::string& ytitle="");
00340 
00341     /// Book a 1D profile histogram based on the name in the corresponding AIDA
00342     /// file. The binnings will be obtained by reading the bundled AIDA data
00343     /// record file with the same filename as the analysis' name() property.
00344     AIDA::IProfile1D* bookProfile1D(const std::string& name, const std::string& title="",
00345                                     const std::string& xtitle="", const std::string& ytitle="");
00346 
00347     /// Book a 1D profile histogram based on the paper, dataset and x/y-axis IDs in the corresponding
00348     /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file
00349     /// of the same filename as the analysis' name() property.
00350     AIDA::IProfile1D* bookProfile1D(size_t datasetId, size_t xAxisId, size_t yAxisId,
00351                                     const std::string& title="",
00352                                     const std::string& xtitle="", const std::string& ytitle="");
00353     //@}
00354 
00355 
00356     /// @name Internal data point set booking (for use by Analysis sub-classes).
00357     //@{
00358 
00359     /// Book a 2-dimensional data point set.
00360     /// (NB. this returns a pointer rather than a reference since it will
00361     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00362     /// get the pointer from a reference before they can use it!)
00363     AIDA::IDataPointSet* bookDataPointSet(const std::string& name, const std::string& title="",
00364                                           const std::string& xtitle="", const std::string& ytitle="");
00365 
00366 
00367     /// Book a 2-dimensional data point set with equally spaced points in a range.
00368     /// (NB. this returns a pointer rather than a reference since it will
00369     /// have to be stored in the analysis class - there's no point in forcing users to explicitly
00370     /// get the pointer from a reference before they can use it!)
00371     AIDA::IDataPointSet* bookDataPointSet(const std::string& name,
00372                                           size_t npts, double lower, double upper,
00373                                           const std::string& title="",
00374                                           const std::string& xtitle="", const std::string& ytitle="");
00375 
00376     /// Book a 2-dimensional data point set based on the corresponding AIDA data
00377     /// file. The binnings (x-errors) will be obtained by reading the bundled
00378     /// AIDA data record file of the same filename as the analysis' name()
00379     /// property.
00380     //AIDA::IDataPointSet* bookDataPointSet(const std::string& name, const std::string& title);
00381 
00382     /// Book a 2-dimensional data point set based on the paper, dataset and x/y-axis IDs in the corresponding
00383     /// HepData record. The binnings (x-errors) will be obtained by reading the bundled AIDA data record file
00384     /// of the same filename as the analysis' name() property.
00385     AIDA::IDataPointSet* bookDataPointSet(size_t datasetId, size_t xAxisId, size_t yAxisId,
00386                                           const std::string& title="",
00387                                           const std::string& xtitle="", const std::string& ytitle="");
00388 
00389     //@}
00390 
00391 
00392   private:
00393 
00394     /// @name Utility functions
00395     //@{
00396 
00397     /// Make the histogram directory.
00398     void _makeHistoDir();
00399 
00400     /// Get the bin edges for this paper from the reference AIDA file, and cache them.
00401     void _cacheBinEdges() const;
00402 
00403     /// Get the x-axis points for this paper from the reference AIDA file, and cache them.
00404     void _cacheXAxisData() const;
00405 
00406     //@}
00407 
00408 
00409   protected:
00410 
00411     /// Set the colliding beam pair.
00412     /// @deprecated Use .info file and AnalysisInfo class instead
00413     Analysis& setBeams(PdgId beam1, PdgId beam2);
00414 
00415     /// Declare whether this analysis needs to know the process cross-section from the generator.
00416     Analysis& setNeedsCrossSection(bool needed);
00417 
00418 
00419   protected:
00420 
00421     /// Name passed to constructor (used to find .info analysis data file, and as a fallback)
00422     string _defaultname;
00423 
00424     /// Pointer to analysis metadata object
00425     shared_ptr<AnalysisInfo> _info;
00426 
00427 
00428   private:
00429 
00430     /// @name Cross-section variables
00431     //@{
00432     double _crossSection;
00433     bool _gotCrossSection;
00434     bool _needsCrossSection;
00435     //@}
00436 
00437     /// The controlling AnalysisHandler object.
00438     AnalysisHandler* _analysishandler;
00439 
00440     /// Flag to indicate whether the histogram directory is present
00441     mutable bool _madeHistoDir;
00442 
00443     /// Collection of x-axis point data to speed up many autobookings: the
00444     /// reference data file should only be read once.
00445     /// @todo Reduce memory occupancy, or clear after initialisation?
00446     mutable map<string, vector<DPSXPoint> > _dpsData;
00447 
00448     /// Collection of cached bin edges to speed up many autobookings: the
00449     /// reference data file should only be read once.
00450     /// @todo Reduce memory occupancy, or clear after initialisation?
00451     mutable map<string, BinEdges> _histBinEdges;
00452 
00453 
00454   private:
00455 
00456     /// The assignment operator is private and must never be called.
00457     /// In fact, it should not even be implemented.
00458     Analysis& operator=(const Analysis&);
00459 
00460   };
00461 
00462 
00463 
00464   /////////////////////////////////////////////////////////////////////
00465 
00466 
00467   /// @cond ANALYSIS_PLUGIN_DETAILS
00468 
00469   /// @brief Interface for analysis builders
00470   class AnalysisBuilderBase {
00471   public:
00472     AnalysisBuilderBase() { }
00473     virtual ~AnalysisBuilderBase() { }
00474 
00475     virtual Analysis* mkAnalysis() const = 0;
00476 
00477     const string name() const {
00478       Analysis* a = mkAnalysis();
00479       string rtn = a->name();
00480       delete a;
00481       return rtn;
00482     }
00483 
00484   protected:
00485     void _register() {
00486       AnalysisLoader::_registerBuilder(this);
00487     }
00488   };
00489 
00490 
00491   /// @brief Self-registering analysis plugin builder
00492   template <typename T>
00493   class AnalysisBuilder : public AnalysisBuilderBase {
00494   public:
00495     AnalysisBuilder() {
00496       _register();
00497     }
00498 
00499     Analysis* mkAnalysis() const {
00500       return new T();
00501     }
00502   };
00503 
00504   /// @endcond
00505 
00506 }
00507 
00508 #endif