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/AnalysisInfo.hh"
00007 #include "Rivet/Event.hh"
00008 #include "Rivet/Projection.hh"
00009 #include "Rivet/ProjectionApplier.hh"
00010 #include "Rivet/ProjectionHandler.hh"
00011 #include "Rivet/AnalysisLoader.hh"
00012 #include "Rivet/Tools/RivetYODA.hh"
00013 #include "Rivet/Tools/Logging.hh"
00014 #include "Rivet/Tools/ParticleUtils.hh"
00015 
00016 
00017 /// @def vetoEvent
00018 /// Preprocessor define for vetoing events, including the log message and return.
00019 #define vetoEvent                                                       \
00020   do { MSG_DEBUG("Vetoing event on line " << __LINE__ << " of " << __FILE__); return; } while(0)
00021 
00022 
00023 namespace Rivet {
00024 
00025 
00026   // Forward declaration
00027   class AnalysisHandler;
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() { }
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() { }
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     const AnalysisInfo& info() const {
00105       assert(_info.get() != 0 && "No AnalysisInfo object :O");
00106       return *_info;
00107     }
00108 
00109     /// @brief Get the name of the analysis.
00110     ///
00111     /// By default this is computed by combining the results of the experiment,
00112     /// year and Spires ID metadata methods and you should only override it if
00113     /// there's a good reason why those won't work.
00114     virtual std::string name() const {
00115       return (info().name().empty()) ? _defaultname : info().name();
00116     }
00117 
00118     /// Get the Inspire ID code for this analysis.
00119     virtual std::string inspireId() const {
00120       return info().inspireId();
00121     }
00122 
00123     /// Get the SPIRES ID code for this analysis (~deprecated).
00124     virtual std::string spiresId() const {
00125       return info().spiresId();
00126     }
00127 
00128     /// @brief Names & emails of paper/analysis authors.
00129     ///
00130     /// Names and email of authors in 'NAME <EMAIL>' format. The first
00131     /// name in the list should be the primary contact person.
00132     virtual std::vector<std::string> authors() const {
00133       return info().authors();
00134     }
00135 
00136     /// @brief Get a short description of the analysis.
00137     ///
00138     /// Short (one sentence) description used as an index entry.
00139     /// Use @a description() to provide full descriptive paragraphs
00140     /// of analysis details.
00141     virtual std::string summary() const {
00142       return info().summary();
00143     }
00144 
00145     /// @brief Get a full description of the analysis.
00146     ///
00147     /// Full textual description of this analysis, what it is useful for,
00148     /// what experimental techniques are applied, etc. Should be treated
00149     /// as a chunk of restructuredText (http://docutils.sourceforge.net/rst.html),
00150     /// with equations to be rendered as LaTeX with amsmath operators.
00151     virtual std::string description() const {
00152       return info().description();
00153     }
00154 
00155     /// @brief Information about the events needed as input for this analysis.
00156     ///
00157     /// Event types, energies, kinematic cuts, particles to be considered
00158     /// stable, etc. etc. Should be treated as a restructuredText bullet list
00159     /// (http://docutils.sourceforge.net/rst.html)
00160     virtual std::string runInfo() const {
00161       return info().runInfo();
00162     }
00163 
00164     /// Experiment which performed and published this analysis.
00165     virtual std::string experiment() const {
00166       return info().experiment();
00167     }
00168 
00169     /// Collider on which the experiment ran.
00170     virtual std::string collider() const {
00171       return info().collider();
00172     }
00173 
00174     /// When the original experimental analysis was published.
00175     virtual std::string year() const {
00176       return info().year();
00177     }
00178 
00179     /// Journal, and preprint references.
00180     virtual std::vector<std::string> references() const {
00181       return info().references();
00182     }
00183 
00184     /// BibTeX citation key for this article.
00185     virtual std::string bibKey() const {
00186       return info().bibKey();
00187     }
00188 
00189     /// BibTeX citation entry for this article.
00190     virtual std::string bibTeX() const {
00191       return info().bibTeX();
00192     }
00193 
00194     /// Whether this analysis is trusted (in any way!)
00195     virtual std::string status() const {
00196       return (info().status().empty()) ? "UNVALIDATED" : info().status();
00197     }
00198 
00199     /// Any work to be done on this analysis.
00200     virtual std::vector<std::string> todos() const {
00201       return info().todos();
00202     }
00203 
00204 
00205     /// Return the allowed pairs of incoming beams required by this analysis.
00206     virtual const std::vector<PdgIdPair>& requiredBeams() const {
00207       return info().beams();
00208     }
00209     /// Declare the allowed pairs of incoming beams required by this analysis.
00210     virtual Analysis& setRequiredBeams(const std::vector<PdgIdPair>& requiredBeams) {
00211       info().setBeams(requiredBeams);
00212       return *this;
00213     }
00214 
00215 
00216     /// Sets of valid beam energy pairs, in GeV
00217     virtual const std::vector<std::pair<double, double> >& requiredEnergies() const {
00218       return info().energies();
00219     }
00220     /// Declare the list of valid beam energy pairs, in GeV
00221     virtual Analysis& setRequiredEnergies(const std::vector<std::pair<double, double> >& requiredEnergies) {
00222       info().setEnergies(requiredEnergies);
00223       return *this;
00224     }
00225 
00226 
00227     /// Return true if this analysis needs to know the process cross-section.
00228     /// @todo Remove this and require HepMC >= 2.06
00229     bool needsCrossSection() const {
00230       return info().needsCrossSection();
00231     }
00232     /// Declare whether this analysis needs to know the process cross-section from the generator.
00233     /// @todo Remove this and require HepMC >= 2.06
00234     Analysis& setNeedsCrossSection(bool needed=true) {
00235       info().setNeedsCrossSection(needed);
00236       return *this;
00237     }
00238 
00239     //@}
00240 
00241 
00242     /// @name Internal metadata modifying methods
00243     //@{
00244 
00245     /// Get the actual AnalysisInfo object in which all this metadata is stored (non-const).
00246     AnalysisInfo& info() {
00247       assert(_info.get() != 0 && "No AnalysisInfo object :O");
00248       return *_info;
00249     }
00250 
00251     //@}
00252 
00253 
00254     /// @name Run conditions
00255     //@{
00256 
00257     /// Incoming beams for this run
00258     const ParticlePair& beams() const;
00259 
00260     /// Incoming beam IDs for this run
00261     const PdgIdPair beamIds() const;
00262 
00263     /// Centre of mass energy for this run
00264     double sqrtS() const;
00265 
00266     //@}
00267 
00268 
00269     /// @name Analysis / beam compatibility testing
00270     //@{
00271 
00272     /// Check if analysis is compatible with the provided beam particle IDs and energies
00273     bool isCompatible(const ParticlePair& beams) const;
00274 
00275     /// Check if analysis is compatible with the provided beam particle IDs and energies
00276     bool isCompatible(PdgId beam1, PdgId beam2, double e1, double e2) const;
00277 
00278     /// Check if analysis is compatible with the provided beam particle IDs and energies
00279     bool isCompatible(const PdgIdPair& beams, const std::pair<double,double>& energies) const;
00280 
00281     //@}
00282 
00283 
00284     /// Set the cross section from the generator
00285     Analysis& setCrossSection(double xs);
00286 
00287     /// Access the controlling AnalysisHandler object.
00288     AnalysisHandler& handler() const { return *_analysishandler; }
00289 
00290 
00291   protected:
00292 
00293     /// Get a Log object based on the name() property of the calling analysis object.
00294     Log& getLog() const;
00295 
00296     /// Get the process cross-section in pb. Throws if this hasn't been set.
00297     double crossSection() const;
00298 
00299     /// Get the process cross-section per generated event in pb. Throws if this
00300     /// hasn't been set.
00301     double crossSectionPerEvent() const;
00302 
00303     /// Get the number of events seen (via the analysis handler). Use in the
00304     /// finalize phase only.
00305     size_t numEvents() const;
00306 
00307     /// Get the sum of event weights seen (via the analysis handler). Use in the
00308     /// finalize phase only.
00309     double sumOfWeights() const;
00310 
00311 
00312   protected:
00313 
00314     /// @name Histogram paths
00315     //@{
00316 
00317     /// Get the canonical histogram "directory" path for this analysis.
00318     const std::string histoDir() const;
00319 
00320     /// Get the canonical histogram path for the named histogram in this analysis.
00321     const std::string histoPath(const std::string& hname) const;
00322 
00323     /// Get the canonical histogram path for the numbered histogram in this analysis.
00324     const std::string histoPath(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const;
00325 
00326     /// Get the internal histogram name for given d, x and y (cf. HepData)
00327     const std::string makeAxisCode(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const;
00328 
00329     //@}
00330 
00331 
00332     /// @name Histogram reference data
00333     //@{
00334 
00335     /// Get reference data for a named histo
00336     const YODA::Scatter2D & refData(const string& hname) const;
00337 
00338     /// Get reference data for a numbered histo
00339     const YODA::Scatter2D & refData(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const;
00340 
00341     //@}
00342 
00343 
00344     /// @name 1D histogram booking
00345     //@{
00346 
00347     /// Book a 1D histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00348     Histo1DPtr bookHisto1D(const std::string& name,
00349                            size_t nbins, double lower, double upper,
00350                            const std::string& title="",
00351                            const std::string& xtitle="",
00352                            const std::string& ytitle="");
00353 
00354     /// Book a 1D histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00355     Histo1DPtr bookHisto1D(const std::string& name,
00356                            const std::vector<double>& binedges,
00357                            const std::string& title="",
00358                            const std::string& xtitle="",
00359                            const std::string& ytitle="");
00360 
00361     /// Book a 1D histogram with binning from a reference scatter.
00362     Histo1DPtr bookHisto1D(const std::string& name,
00363                            const Scatter2D& refscatter,
00364                            const std::string& title="",
00365                            const std::string& xtitle="",
00366                            const std::string& ytitle="");
00367 
00368     /// Book a 1D histogram, using the binnings in the reference data histogram.
00369     Histo1DPtr bookHisto1D(const std::string& name,
00370                            const std::string& title="",
00371                            const std::string& xtitle="",
00372                            const std::string& ytitle="");
00373 
00374     /// Book a 1D histogram, using the binnings in the reference data histogram.
00375     ///
00376     /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00377     Histo1DPtr bookHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00378                            const std::string& title="",
00379                            const std::string& xtitle="",
00380                            const std::string& ytitle="");
00381 
00382     //@}
00383 
00384 
00385     // /// @name 2D histogram booking
00386     // //@{
00387 
00388     // /// Book a 2D histogram with @a nxbins and @a nybins uniformly
00389     // /// distributed across the ranges @a xlower - @a xupper and @a
00390     // /// ylower - @a yupper respectively along the x- and y-axis.
00391     // Histogram2DPtr bookHisto2D(const std::string& name,
00392     //                            size_t nxbins, double xlower, double xupper,
00393     //                            size_t nybins, double ylower, double yupper,
00394     //                            const std::string& title="",
00395     //                            const std::string& xtitle="",
00396     //                            const std::string& ytitle="",
00397     //                            const std::string& ztitle="");
00398 
00399     // /// Book a 2D histogram with non-uniform bins defined by the
00400     // /// vectorx of bin edges @a xbinedges and @a ybinedges.
00401     // Histogram2DPtr bookHisto2D(const std::string& name,
00402     //                            const std::vector<double>& xbinedges,
00403     //                            const std::vector<double>& ybinedges,
00404     //                            const std::string& title="",
00405     //                            const std::string& xtitle="",
00406     //                            const std::string& ytitle="",
00407     //                            const std::string& ztitle="");
00408 
00409     /// Book a 2D histogram with binning from a reference scatter.
00410     // Histogram2DPtr bookHisto2D(const std::string& name,
00411     //                            const Scatter3D& refscatter,
00412     //                            const std::string& title="",
00413     //                            const std::string& xtitle="",
00414     //                            const std::string& ytitle="",
00415     //                            const std::string& ztitle="");
00416 
00417     // /// Book a 2D histogram, using the binnings in the reference data histogram.
00418     // Histogram2DPtr bookHisto2D(const std::string& name,
00419     //                            const std::string& title="",
00420     //                            const std::string& xtitle="",
00421     //                            const std::string& ytitle="",
00422     //                            const std::string& ztitle="");
00423 
00424     // /// Book a 2D histogram, using the binnings in the reference data histogram.
00425     // ///
00426     // /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00427     // Histogram2DPtr bookHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00428     //                            const std::string& title="",
00429     //                            const std::string& xtitle="",
00430     //                            const std::string& ytitle="",
00431     //                            const std::string& ztitle="");
00432 
00433     // //@}
00434 
00435 
00436     /// @name 1D profile histogram booking
00437     //@{
00438 
00439     /// Book a 1D profile histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00440     Profile1DPtr bookProfile1D(const std::string& name,
00441                                size_t nbins, double lower, double upper,
00442                                const std::string& title="",
00443                                const std::string& xtitle="",
00444                                const std::string& ytitle="");
00445 
00446     /// Book a 1D profile histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00447     Profile1DPtr bookProfile1D(const std::string& name,
00448                                const std::vector<double>& binedges,
00449                                const std::string& title="",
00450                                const std::string& xtitle="",
00451                                const std::string& ytitle="");
00452 
00453     /// Book a 1D profile histogram with binning from a reference scatter.
00454     Profile1DPtr bookProfile1D(const std::string& name,
00455                                const Scatter2D& refscatter,
00456                                const std::string& title="",
00457                                const std::string& xtitle="",
00458                                const std::string& ytitle="");
00459 
00460     /// Book a 1D profile histogram, using the binnings in the reference data histogram.
00461     Profile1DPtr bookProfile1D(const std::string& name,
00462                                const std::string& title="",
00463                                const std::string& xtitle="",
00464                                const std::string& ytitle="");
00465 
00466     /// Book a 1D profile histogram, using the binnings in the reference data histogram.
00467     ///
00468     /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00469     Profile1DPtr bookProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00470                                const std::string& title="",
00471                                const std::string& xtitle="",
00472                                const std::string& ytitle="");
00473 
00474     //@}
00475 
00476 
00477     // /// @name 2D profile histogram booking
00478     // //@{
00479 
00480     // /// Book a 2D profile histogram with @a nxbins and @a nybins uniformly
00481     // /// distributed across the ranges @a xlower - @a xupper and @a ylower - @a
00482     // /// yupper respectively along the x- and y-axis.
00483     // Profile2DPtr bookProfile2D(const std::string& name,
00484     //                            size_t nxbins, double xlower, double xupper,
00485     //                            size_t nybins, double ylower, double yupper,
00486     //                            const std::string& title="",
00487     //                            const std::string& xtitle="",
00488     //                            const std::string& ytitle="",
00489     //                            const std::string& ztitle="");
00490 
00491     // /// Book a 2D profile histogram with non-uniform bins defined by the vectorx
00492     // /// of bin edges @a xbinedges and @a ybinedges.
00493     // Profile2DPtr bookProfile2D(const std::string& name,
00494     //                            const std::vector<double>& xbinedges,
00495     //                            const std::vector<double>& ybinedges,
00496     //                            const std::string& title="",
00497     //                            const std::string& xtitle="",
00498     //                            const std::string& ytitle="",
00499     //                            const std::string& ztitle="");
00500 
00501     /// Book a 2D profile histogram with binning from a reference scatter.
00502     // Profile2DPtr bookProfile2D(const std::string& name,
00503     //                            const Scatter3D& refscatter,
00504     //                            const std::string& title="",
00505     //                            const std::string& xtitle="",
00506     //                            const std::string& ytitle="",
00507     //                            const std::string& ztitle="");
00508 
00509     // /// Book a 2D profile histogram, using the binnings in the reference data histogram.
00510     // Profile2DPtr bookProfile2D(const std::string& name,
00511     //                            const std::string& title="",
00512     //                            const std::string& xtitle="",
00513     //                            const std::string& ytitle="",
00514     //                            const std::string& ztitle="");
00515 
00516     // /// Book a 2D profile histogram, using the binnings in the reference data histogram.
00517     // ///
00518     // /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00519     // Profile2DPtr bookProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00520     //                            const std::string& title="",
00521     //                            const std::string& xtitle="",
00522     //                            const std::string& ytitle="",
00523     //                            const std::string& ztitle="");
00524 
00525     // //@}
00526 
00527 
00528     /// @name 2D scatter booking
00529     //@{
00530 
00531     /// @brief Book a 2-dimensional data point set with the given name.
00532     ///
00533     /// @note Unlike histogram booking, scatter booking by default makes no
00534     /// attempt to use reference data to pre-fill the data object. If you want
00535     /// this, which is sometimes useful e.g. when the x-position is not really
00536     /// meaningful and can't be extracted from the data, then set the @a
00537     /// copy_pts parameter to true. This creates points to match the reference
00538     /// data's x values and errors, but with the y values and errors zeroed...
00539     /// assuming that there is a reference histo with the same name: if there
00540     /// isn't, an exception will be thrown.
00541     Scatter2DPtr bookScatter2D(const std::string& name,
00542                                bool copy_pts=false,
00543                                const std::string& title="",
00544                                const std::string& xtitle="",
00545                                const std::string& ytitle="");
00546 
00547     /// @brief Book a 2-dimensional data point set, using the binnings in the reference data histogram.
00548     ///
00549     /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00550     ///
00551     /// @note Unlike histogram booking, scatter booking by default makes no
00552     /// attempt to use reference data to pre-fill the data object. If you want
00553     /// this, which is sometimes useful e.g. when the x-position is not really
00554     /// meaningful and can't be extracted from the data, then set the @a
00555     /// copy_pts parameter to true. This creates points to match the reference
00556     /// data's x values and errors, but with the y values and errors zeroed.
00557     Scatter2DPtr bookScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00558                                bool copy_pts=false,
00559                                const std::string& title="",
00560                                const std::string& xtitle="",
00561                                const std::string& ytitle="");
00562 
00563     /// @brief Book a 2-dimensional data point set with equally spaced x-points in a range.
00564     ///
00565     /// The y values and errors will be set to 0.
00566     Scatter2DPtr bookScatter2D(const std::string& name,
00567                                size_t npts, double lower, double upper,
00568                                const std::string& title="",
00569                                const std::string& xtitle="",
00570                                const std::string& ytitle="");
00571 
00572     /// @brief Book a 2-dimensional data point set based on provided contiguous "bin edges".
00573     ///
00574     /// The y values and errors will be set to 0.
00575     Scatter2DPtr bookScatter2D(const std::string& hname,
00576                                const std::vector<double>& binedges,
00577                                const std::string& title,
00578                                const std::string& xtitle,
00579                                const std::string& ytitle);
00580 
00581     //@}
00582 
00583 
00584     /// @todo Should really be protected: only public to keep BinnedHistogram happy for now...
00585   public:
00586 
00587     /// @name Histogram manipulation
00588     //@{
00589 
00590     /// Normalize the given histogram, @a histo, to area = @a norm.
00591     ///
00592     /// @note The histogram is no longer invalidated by this procedure.
00593     void normalize(Histo1DPtr histo, double norm=1.0, bool includeoverflows=true);
00594 
00595     /// Multiplicatively scale the given histogram, @a histo, by factor @s scale.
00596     ///
00597     /// @note The histogram is no longer invalidated by this procedure.
00598     void scale(Histo1DPtr histo, double scale);
00599 
00600     /// Normalize the given histogram, @a histo, to area = @a norm.
00601     ///
00602     /// @note The histogram is no longer invalidated by this procedure.
00603     // void normalize(Histo2DPtr histo, double norm=1.0);
00604 
00605     /// Multiplicatively scale the given histogram, @a histo, by factor @s scale.
00606     ///
00607     /// @note The histogram is no longer invalidated by this procedure.
00608     // void scale(Histo2DPtr histo, double scale);
00609 
00610 
00611     /// Helper for histogram division.
00612     ///
00613     /// @note Preserves the path information of the target.
00614     void divide(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const;
00615 
00616     /// Helper for profile histogram division.
00617     ///
00618     /// @note Preserves the path information of the target.
00619     void divide(Profile1DPtr p1, Profile1DPtr p2, Scatter2DPtr s) const;
00620 
00621     /// Helper for histogram division.
00622     ///
00623     /// @note Preserves the path information of the target.
00624     void divide(const YODA::Histo1D & h1,
00625                 const YODA::Histo1D & h2, Scatter2DPtr s) const;
00626 
00627     /// Helper for profile histogram division
00628     ///
00629     /// @note Preserves the path information of the target.
00630     void divide(const YODA::Profile1D & p1,
00631                 const YODA::Profile1D & p2, Scatter2DPtr s) const;
00632 
00633 
00634     /// Helper for converting a differential histo to an integral one.
00635     ///
00636     /// @note Preserves the path information of the target.
00637     void integrate(Histo1DPtr h, Scatter2DPtr s) const;
00638 
00639     /// Helper for converting a differential histo to an integral one.
00640     ///
00641     /// @note Preserves the path information of the target.
00642     void integrate(const Histo1D& h, Scatter2DPtr s) const;
00643 
00644 
00645     /// @todo Add integrate helpers for 2D histos (defined somehow...)
00646 
00647     //@}
00648 
00649 
00650   public:
00651 
00652     /// List of registered analysis data objects
00653     const vector<AnalysisObjectPtr>& analysisObjects() const {
00654       return _analysisobjects;
00655     }
00656 
00657 
00658   protected:
00659 
00660     /// @name Data object registration, retrieval, and removal
00661     //@{
00662 
00663     /// Register a data object in the histogram system
00664     void addAnalysisObject(AnalysisObjectPtr ao);
00665 
00666     /// Get a data object from the histogram system
00667     /// @todo Use this default function template arg in C++11
00668     // template <typename AO=AnalysisObjectPtr>
00669     template <typename AO>
00670     const shared_ptr<AO> getAnalysisObject(const std::string& name) const {
00671       foreach (const AnalysisObjectPtr& ao, analysisObjects()) {
00672         if (ao->path() == histoPath(name)) return dynamic_pointer_cast<AO>(ao);
00673       }
00674       throw Exception("Data object " + histoPath(name) + " not found");
00675     }
00676 
00677     /// Get a data object from the histogram system (non-const)
00678     /// @todo Use this default function template arg in C++11
00679     // template <typename AO=AnalysisObjectPtr>
00680     template <typename AO>
00681     shared_ptr<AO> getAnalysisObject(const std::string& name) {
00682       foreach (const AnalysisObjectPtr& ao, analysisObjects()) {
00683         if (ao->path() == histoPath(name)) return dynamic_pointer_cast<AO>(ao);
00684       }
00685       throw Exception("Data object " + histoPath(name) + " not found");
00686     }
00687 
00688     /// Unregister a data object from the histogram system (by name)
00689     void removeAnalysisObject(const std::string& path);
00690 
00691     /// Unregister a data object from the histogram system (by pointer)
00692     void removeAnalysisObject(AnalysisObjectPtr ao);
00693 
00694 
00695     /// Get a named Histo1D object from the histogram system
00696     const Histo1DPtr getHisto1D(const std::string& name) const {
00697       return getAnalysisObject<Histo1D>(name);
00698     }
00699 
00700     /// Get a named Histo1D object from the histogram system (non-const)
00701     Histo1DPtr getHisto1D(const std::string& name) {
00702       return getAnalysisObject<Histo1D>(name);
00703     }
00704 
00705     /// Get a Histo1D object from the histogram system by axis ID codes (non-const)
00706     const Histo1DPtr getHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00707       return getAnalysisObject<Histo1D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00708     }
00709 
00710     /// Get a Histo1D object from the histogram system by axis ID codes (non-const)
00711     Histo1DPtr getHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00712       return getAnalysisObject<Histo1D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00713     }
00714 
00715 
00716     // /// Get a named Histo2D object from the histogram system
00717     // const Histo2DPtr getHisto2D(const std::string& name) const {
00718     //   return getAnalysisObject<Histo2D>(name);
00719     // }
00720 
00721     // /// Get a named Histo2D object from the histogram system (non-const)
00722     // Histo2DPtr getHisto2D(const std::string& name) {
00723     //   return getAnalysisObject<Histo2D>(name);
00724     // }
00725 
00726     // /// Get a Histo2D object from the histogram system by axis ID codes (non-const)
00727     // const Histo2DPtr getHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00728     //   return getAnalysisObject<Histo2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00729     // }
00730 
00731     // /// Get a Histo2D object from the histogram system by axis ID codes (non-const)
00732     // Histo2DPtr getHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00733     //   return getAnalysisObject<Histo2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00734     // }
00735 
00736 
00737     /// Get a named Profile1D object from the histogram system
00738     const Profile1DPtr getProfile1D(const std::string& name) const {
00739       return getAnalysisObject<Profile1D>(name);
00740     }
00741 
00742     /// Get a named Profile1D object from the histogram system (non-const)
00743     Profile1DPtr getProfile1D(const std::string& name) {
00744       return getAnalysisObject<Profile1D>(name);
00745     }
00746 
00747     /// Get a Profile1D object from the histogram system by axis ID codes (non-const)
00748     const Profile1DPtr getProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00749       return getAnalysisObject<Profile1D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00750     }
00751 
00752     /// Get a Profile1D object from the histogram system by axis ID codes (non-const)
00753     Profile1DPtr getProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00754       return getAnalysisObject<Profile1D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00755     }
00756 
00757 
00758     // /// Get a named Profile2D object from the histogram system
00759     // const Profile2DPtr getProfile2D(const std::string& name) const {
00760     //   return getAnalysisObject<Profile2D>(name);
00761     // }
00762 
00763     // /// Get a named Profile2D object from the histogram system (non-const)
00764     // Profile2DPtr getProfile2D(const std::string& name) {
00765     //   return getAnalysisObject<Profile2D>(name);
00766     // }
00767 
00768     // /// Get a Profile2D object from the histogram system by axis ID codes (non-const)
00769     // const Profile2DPtr getProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00770     //   return getAnalysisObject<Profile2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00771     // }
00772 
00773     // /// Get a Profile2D object from the histogram system by axis ID codes (non-const)
00774     // Profile2DPtr getProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00775     //   return getAnalysisObject<Profile2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00776     // }
00777 
00778 
00779     /// Get a named Scatter2D object from the histogram system
00780     const Scatter2DPtr getScatter2D(const std::string& name) const {
00781       return getAnalysisObject<Scatter2D>(name);
00782     }
00783 
00784     /// Get a named Scatter2D object from the histogram system (non-const)
00785     Scatter2DPtr getScatter2D(const std::string& name) {
00786       return getAnalysisObject<Scatter2D>(name);
00787     }
00788 
00789     /// Get a Scatter2D object from the histogram system by axis ID codes (non-const)
00790     const Scatter2DPtr getScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00791       return getAnalysisObject<Scatter2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00792     }
00793 
00794     /// Get a Scatter2D object from the histogram system by axis ID codes (non-const)
00795     Scatter2DPtr getScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00796       return getAnalysisObject<Scatter2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00797     }
00798 
00799     //@}
00800 
00801 
00802   private:
00803 
00804     /// Name passed to constructor (used to find .info analysis data file, and as a fallback)
00805     string _defaultname;
00806 
00807     /// Pointer to analysis metadata object
00808     shared_ptr<AnalysisInfo> _info;
00809 
00810     /// Storage of all plot objects
00811     /// @todo Make this a map for fast lookup by path?
00812     vector<AnalysisObjectPtr> _analysisobjects;
00813 
00814     /// @name Cross-section variables
00815     //@{
00816     double _crossSection;
00817     bool _gotCrossSection;
00818     //@}
00819 
00820     /// The controlling AnalysisHandler object.
00821     AnalysisHandler* _analysishandler;
00822 
00823     /// Collection of cached refdata to speed up many autobookings: the
00824     /// reference data file should only be read once.
00825     mutable std::map<std::string, Scatter2DPtr> _refdata;
00826 
00827 
00828   private:
00829 
00830     /// @name Utility functions
00831     //@{
00832 
00833     /// Get the reference data for this paper and cache it.
00834     void _cacheRefData() const;
00835 
00836     //@}
00837 
00838 
00839     /// The assignment operator is private and must never be called.
00840     /// In fact, it should not even be implemented.
00841     Analysis& operator=(const Analysis&);
00842 
00843   };
00844 
00845 
00846 }
00847 
00848 
00849 // Include definition of analysis plugin system so that analyses automatically see it when including Analysis.hh
00850 #include "Rivet/AnalysisBuilder.hh"
00851 
00852 /// @def DECLARE_RIVET_PLUGIN
00853 /// Preprocessor define to prettify the global-object plugin hook mechanism.
00854 #define DECLARE_RIVET_PLUGIN(clsname) Rivet::AnalysisBuilder<clsname> plugin_ ## clsname
00855 
00856 /// @def DEFAULT_RIVET_ANA_CONSTRUCTOR
00857 /// Preprocessor define to prettify the manky constructor with name string argument
00858 #define DEFAULT_RIVET_ANA_CONSTRUCTOR(clsname) clsname() : Analysis(# clsname) {}
00859 
00860 
00861 #endif