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/Config/RivetCommon.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 #include "Rivet/Tools/Cuts.hh"
00016 
00017 
00018 /// @def vetoEvent
00019 /// Preprocessor define for vetoing events, including the log message and return.
00020 #define vetoEvent                                                       \
00021   do { MSG_DEBUG("Vetoing event on line " << __LINE__ << " of " << __FILE__); return; } while(0)
00022 
00023 
00024 namespace Rivet {
00025 
00026 
00027   // Forward declaration
00028   class AnalysisHandler;
00029 
00030   /// @brief This is the base class of all analysis classes in Rivet.
00031   ///
00032   /// There are
00033   /// three virtual functions which should be implemented in base classes:
00034   ///
00035   /// void init() is called by Rivet before a run is started. Here the
00036   /// analysis class should book necessary histograms. The needed
00037   /// projections should probably rather be constructed in the
00038   /// constructor.
00039   ///
00040   /// void analyze(const Event&) is called once for each event. Here the
00041   /// analysis class should apply the necessary Projections and fill the
00042   /// histograms.
00043   ///
00044   /// void finalize() is called after a run is finished. Here the analysis
00045   /// class should do whatever manipulations are necessary on the
00046   /// histograms. Writing the histograms to a file is, however, done by
00047   /// the Rivet class.
00048   class Analysis : public ProjectionApplier {
00049 
00050     /// The AnalysisHandler is a friend.
00051     friend class AnalysisHandler;
00052 
00053 
00054   public:
00055 
00056     /// @name Standard constructors and destructors.
00057     //@{
00058 
00059     // /// The default constructor.
00060     // Analysis();
00061 
00062     /// Constructor
00063     Analysis(const std::string& name);
00064 
00065     /// The destructor.
00066     virtual ~Analysis() {}
00067 
00068     //@}
00069 
00070 
00071   public:
00072 
00073     /// @name Main analysis methods
00074     //@{
00075 
00076     /// Initialize this analysis object. A concrete class should here
00077     /// book all necessary histograms. An overridden function must make
00078     /// sure it first calls the base class function.
00079     virtual void init() { }
00080 
00081     /// Analyze one event. A concrete class should here apply the
00082     /// necessary projections on the \a event and fill the relevant
00083     /// histograms. An overridden function must make sure it first calls
00084     /// the base class function.
00085     virtual void analyze(const Event& event) = 0;
00086 
00087     /// Finalize this analysis object. A concrete class should here make
00088     /// all necessary operations on the histograms. Writing the
00089     /// histograms to a file is, however, done by the Rivet class. An
00090     /// overridden function must make sure it first calls the base class
00091     /// function.
00092     virtual void finalize() { }
00093 
00094     //@}
00095 
00096 
00097   public:
00098 
00099     /// @name Metadata
00100     /// Metadata is used for querying from the command line and also for
00101     /// building web pages and the analysis pages in the Rivet manual.
00102     //@{
00103 
00104     /// Get the actual AnalysisInfo object in which all this metadata is stored.
00105     const AnalysisInfo& info() const {
00106       assert(_info && "No AnalysisInfo object :O");
00107       return *_info;
00108     }
00109 
00110     /// @brief Get the name of the analysis.
00111     ///
00112     /// By default this is computed by combining the results of the experiment,
00113     /// year and Spires ID metadata methods and you should only override it if
00114     /// there's a good reason why those won't work.
00115     virtual std::string name() const {
00116       return (info().name().empty()) ? _defaultname : info().name();
00117     }
00118 
00119     /// Get the Inspire ID code for this analysis.
00120     virtual std::string inspireId() const {
00121       return info().inspireId();
00122     }
00123 
00124     /// Get the SPIRES ID code for this analysis (~deprecated).
00125     virtual std::string spiresId() const {
00126       return info().spiresId();
00127     }
00128 
00129     /// @brief Names & emails of paper/analysis authors.
00130     ///
00131     /// Names and email of authors in 'NAME <EMAIL>' format. The first
00132     /// name in the list should be the primary contact person.
00133     virtual std::vector<std::string> authors() const {
00134       return info().authors();
00135     }
00136 
00137     /// @brief Get a short description of the analysis.
00138     ///
00139     /// Short (one sentence) description used as an index entry.
00140     /// Use @a description() to provide full descriptive paragraphs
00141     /// of analysis details.
00142     virtual std::string summary() const {
00143       return info().summary();
00144     }
00145 
00146     /// @brief Get a full description of the analysis.
00147     ///
00148     /// Full textual description of this analysis, what it is useful for,
00149     /// what experimental techniques are applied, etc. Should be treated
00150     /// as a chunk of restructuredText (http://docutils.sourceforge.net/rst.html),
00151     /// with equations to be rendered as LaTeX with amsmath operators.
00152     virtual std::string description() const {
00153       return info().description();
00154     }
00155 
00156     /// @brief Information about the events needed as input for this analysis.
00157     ///
00158     /// Event types, energies, kinematic cuts, particles to be considered
00159     /// stable, etc. etc. Should be treated as a restructuredText bullet list
00160     /// (http://docutils.sourceforge.net/rst.html)
00161     virtual std::string runInfo() const {
00162       return info().runInfo();
00163     }
00164 
00165     /// Experiment which performed and published this analysis.
00166     virtual std::string experiment() const {
00167       return info().experiment();
00168     }
00169 
00170     /// Collider on which the experiment ran.
00171     virtual std::string collider() const {
00172       return info().collider();
00173     }
00174 
00175     /// When the original experimental analysis was published.
00176     virtual std::string year() const {
00177       return info().year();
00178     }
00179 
00180     /// Journal, and preprint references.
00181     virtual std::vector<std::string> references() const {
00182       return info().references();
00183     }
00184 
00185     /// BibTeX citation key for this article.
00186     virtual std::string bibKey() const {
00187       return info().bibKey();
00188     }
00189 
00190     /// BibTeX citation entry for this article.
00191     virtual std::string bibTeX() const {
00192       return info().bibTeX();
00193     }
00194 
00195     /// Whether this analysis is trusted (in any way!)
00196     virtual std::string status() const {
00197       return (info().status().empty()) ? "UNVALIDATED" : info().status();
00198     }
00199 
00200     /// Any work to be done on this analysis.
00201     virtual std::vector<std::string> todos() const {
00202       return info().todos();
00203     }
00204 
00205 
00206     /// Return the allowed pairs of incoming beams required by this analysis.
00207     virtual const std::vector<PdgIdPair>& requiredBeams() const {
00208       return info().beams();
00209     }
00210     /// Declare the allowed pairs of incoming beams required by this analysis.
00211     virtual Analysis& setRequiredBeams(const std::vector<PdgIdPair>& requiredBeams) {
00212       info().setBeams(requiredBeams);
00213       return *this;
00214     }
00215 
00216 
00217     /// Sets of valid beam energy pairs, in GeV
00218     virtual const std::vector<std::pair<double, double> >& requiredEnergies() const {
00219       return info().energies();
00220     }
00221     /// Declare the list of valid beam energy pairs, in GeV
00222     virtual Analysis& setRequiredEnergies(const std::vector<std::pair<double, double> >& requiredEnergies) {
00223       info().setEnergies(requiredEnergies);
00224       return *this;
00225     }
00226 
00227 
00228     /// Return true if this analysis needs to know the process cross-section.
00229     /// @todo Remove this and require HepMC >= 2.06
00230     bool needsCrossSection() const {
00231       return info().needsCrossSection();
00232     }
00233     /// Declare whether this analysis needs to know the process cross-section from the generator.
00234     /// @todo Remove this and require HepMC >= 2.06
00235     Analysis& setNeedsCrossSection(bool needed=true) {
00236       info().setNeedsCrossSection(needed);
00237       return *this;
00238     }
00239 
00240     //@}
00241 
00242 
00243     /// @name Internal metadata modifying methods
00244     //@{
00245 
00246     /// Get the actual AnalysisInfo object in which all this metadata is stored (non-const).
00247     AnalysisInfo& info() {
00248       assert(_info && "No AnalysisInfo object :O");
00249       return *_info;
00250     }
00251 
00252     //@}
00253 
00254 
00255     /// @name Run conditions
00256     //@{
00257 
00258     /// Incoming beams for this run
00259     const ParticlePair& beams() const;
00260 
00261     /// Incoming beam IDs for this run
00262     const PdgIdPair beamIds() const;
00263 
00264     /// Centre of mass energy for this run
00265     double sqrtS() const;
00266 
00267     //@}
00268 
00269 
00270     /// @name Analysis / beam compatibility testing
00271     //@{
00272 
00273     /// Check if analysis is compatible with the provided beam particle IDs and energies
00274     bool isCompatible(const ParticlePair& beams) const;
00275 
00276     /// Check if analysis is compatible with the provided beam particle IDs and energies
00277     bool isCompatible(PdgId beam1, PdgId beam2, double e1, double e2) const;
00278 
00279     /// Check if analysis is compatible with the provided beam particle IDs and energies
00280     bool isCompatible(const PdgIdPair& beams, const std::pair<double,double>& energies) const;
00281 
00282     //@}
00283 
00284 
00285     /// Set the cross section from the generator
00286     Analysis& setCrossSection(double xs);
00287 
00288     /// Access the controlling AnalysisHandler object.
00289     AnalysisHandler& handler() const { return *_analysishandler; }
00290 
00291 
00292   protected:
00293 
00294     /// Get a Log object based on the name() property of the calling analysis object.
00295     Log& getLog() const;
00296 
00297     /// Get the process cross-section in pb. Throws if this hasn't been set.
00298     double crossSection() const;
00299 
00300     /// Get the process cross-section per generated event in pb. Throws if this
00301     /// hasn't been set.
00302     double crossSectionPerEvent() const;
00303 
00304     /// Get the number of events seen (via the analysis handler). Use in the
00305     /// finalize phase only.
00306     size_t numEvents() const;
00307 
00308     /// Get the sum of event weights seen (via the analysis handler). Use in the
00309     /// finalize phase only.
00310     double sumOfWeights() const;
00311 
00312 
00313   protected:
00314 
00315     /// @name Histogram paths
00316     //@{
00317 
00318     /// Get the canonical histogram "directory" path for this analysis.
00319     const std::string histoDir() const;
00320 
00321     /// Get the canonical histogram path for the named histogram in this analysis.
00322     const std::string histoPath(const std::string& hname) const;
00323 
00324     /// Get the canonical histogram path for the numbered histogram in this analysis.
00325     const std::string histoPath(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const;
00326 
00327     /// Get the internal histogram name for given d, x and y (cf. HepData)
00328     const std::string makeAxisCode(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const;
00329 
00330     //@}
00331 
00332 
00333     /// @name Histogram reference data
00334     //@{
00335 
00336     /// Get reference data for a named histo
00337     /// @todo Move to the templated version when we have C++11 and can have a default fn template type
00338     const YODA::Scatter2D& refData(const string& hname) const;
00339 
00340     /// Get reference data for a numbered histo
00341     /// @todo Move to the templated version when we have C++11 and can have a default fn template type
00342     const YODA::Scatter2D& refData(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const;
00343 
00344     /// Get reference data for a named histo
00345     /// @todo Would be nice to just use these and ditch the S2D no-template version,
00346     ///   but we need C++11 for default args in function templates
00347     // template <typename T=Scatter2D>
00348     /// @todo SFINAE to ensure that the type inherits from YODA::AnalysisObject?
00349     template <typename T>
00350     const T& refData(const string& hname) const {
00351       _cacheRefData();
00352       MSG_TRACE("Using histo bin edges for " << name() << ":" << hname);
00353       if (!_refdata[hname]) {
00354         MSG_ERROR("Can't find reference histogram " << hname);
00355         throw Exception("Reference data " + hname + " not found.");
00356       }
00357       return dynamic_cast<T&>(*_refdata[hname]);
00358     }
00359 
00360     /// Get reference data for a numbered histo
00361     /// @todo Would be nice to just use these and ditch the S2D no-template version,
00362     ///   but we need C++11 for default args in function templates
00363     // template <typename T=Scatter2D>
00364     /// @todo SFINAE to ensure that the type inherits from YODA::AnalysisObject?
00365     template <typename T>
00366     const T& refData(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00367       const string hname = makeAxisCode(datasetId, xAxisId, yAxisId);
00368       return refData(hname);
00369     }
00370 
00371     //@}
00372 
00373 
00374     /// @name Counter booking
00375     //@{
00376 
00377     /// Book a counter.
00378     CounterPtr bookCounter(const std::string& name,
00379                            const std::string& title="");
00380                            // const std::string& valtitle=""
00381 
00382     /// Book a counter, using a path generated from the dataset and axis ID codes
00383     ///
00384     /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00385     CounterPtr bookCounter(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00386                            const std::string& title="");
00387                            // const std::string& valtitle=""
00388 
00389     //@}
00390 
00391 
00392     /// @name 1D histogram booking
00393     //@{
00394 
00395     /// Book a 1D histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00396     Histo1DPtr bookHisto1D(const std::string& name,
00397                            size_t nbins, double lower, double upper,
00398                            const std::string& title="",
00399                            const std::string& xtitle="",
00400                            const std::string& ytitle="");
00401 
00402     /// Book a 1D histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00403     Histo1DPtr bookHisto1D(const std::string& name,
00404                            const std::vector<double>& binedges,
00405                            const std::string& title="",
00406                            const std::string& xtitle="",
00407                            const std::string& ytitle="");
00408 
00409     /// Book a 1D histogram with binning from a reference scatter.
00410     Histo1DPtr bookHisto1D(const std::string& name,
00411                            const Scatter2D& refscatter,
00412                            const std::string& title="",
00413                            const std::string& xtitle="",
00414                            const std::string& ytitle="");
00415 
00416     /// Book a 1D histogram, using the binnings in the reference data histogram.
00417     Histo1DPtr bookHisto1D(const std::string& name,
00418                            const std::string& title="",
00419                            const std::string& xtitle="",
00420                            const std::string& ytitle="");
00421 
00422     /// Book a 1D histogram, using the binnings in the reference data histogram.
00423     ///
00424     /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00425     Histo1DPtr bookHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00426                            const std::string& title="",
00427                            const std::string& xtitle="",
00428                            const std::string& ytitle="");
00429 
00430     //@}
00431 
00432 
00433     /// @name 2D histogram booking
00434     //@{
00435 
00436     /// Book a 2D histogram with @a nxbins and @a nybins uniformly
00437     /// distributed across the ranges @a xlower - @a xupper and @a
00438     /// ylower - @a yupper respectively along the x- and y-axis.
00439     Histo2DPtr bookHisto2D(const std::string& name,
00440                            size_t nxbins, double xlower, double xupper,
00441                            size_t nybins, double ylower, double yupper,
00442                            const std::string& title="",
00443                            const std::string& xtitle="",
00444                            const std::string& ytitle="",
00445                            const std::string& ztitle="");
00446 
00447     /// Book a 2D histogram with non-uniform bins defined by the
00448     /// vectorx of bin edges @a xbinedges and @a ybinedges.
00449     Histo2DPtr bookHisto2D(const std::string& name,
00450                            const std::vector<double>& xbinedges,
00451                            const std::vector<double>& ybinedges,
00452                            const std::string& title="",
00453                            const std::string& xtitle="",
00454                            const std::string& ytitle="",
00455                            const std::string& ztitle="");
00456 
00457     // /// Book a 2D histogram with binning from a reference scatter.
00458     // Histo2DPtr bookHisto2D(const std::string& name,
00459     //                        const Scatter3D& refscatter,
00460     //                        const std::string& title="",
00461     //                        const std::string& xtitle="",
00462     //                        const std::string& ytitle="",
00463     //                        const std::string& ztitle="");
00464 
00465     // /// Book a 2D histogram, using the binnings in the reference data histogram.
00466     // Histo2DPtr bookHisto2D(const std::string& name,
00467     //                        const std::string& title="",
00468     //                        const std::string& xtitle="",
00469     //                        const std::string& ytitle="",
00470     //                        const std::string& ztitle="");
00471 
00472     // /// Book a 2D histogram, using the binnings in the reference data histogram.
00473     // ///
00474     // /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00475     // Histo2DPtr bookHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00476     //                        const std::string& title="",
00477     //                        const std::string& xtitle="",
00478     //                        const std::string& ytitle="",
00479     //                        const std::string& ztitle="");
00480 
00481     //@}
00482 
00483 
00484     /// @name 1D profile histogram booking
00485     //@{
00486 
00487     /// Book a 1D profile histogram with @a nbins uniformly distributed across the range @a lower - @a upper .
00488     Profile1DPtr bookProfile1D(const std::string& name,
00489                                size_t nbins, double lower, double upper,
00490                                const std::string& title="",
00491                                const std::string& xtitle="",
00492                                const std::string& ytitle="");
00493 
00494     /// Book a 1D profile histogram with non-uniform bins defined by the vector of bin edges @a binedges .
00495     Profile1DPtr bookProfile1D(const std::string& name,
00496                                const std::vector<double>& binedges,
00497                                const std::string& title="",
00498                                const std::string& xtitle="",
00499                                const std::string& ytitle="");
00500 
00501     /// Book a 1D profile histogram with binning from a reference scatter.
00502     Profile1DPtr bookProfile1D(const std::string& name,
00503                                const Scatter2D& refscatter,
00504                                const std::string& title="",
00505                                const std::string& xtitle="",
00506                                const std::string& ytitle="");
00507 
00508     /// Book a 1D profile histogram, using the binnings in the reference data histogram.
00509     Profile1DPtr bookProfile1D(const std::string& name,
00510                                const std::string& title="",
00511                                const std::string& xtitle="",
00512                                const std::string& ytitle="");
00513 
00514     /// Book a 1D profile histogram, using the binnings in the reference data histogram.
00515     ///
00516     /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00517     Profile1DPtr bookProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00518                                const std::string& title="",
00519                                const std::string& xtitle="",
00520                                const std::string& ytitle="");
00521 
00522     //@}
00523 
00524 
00525     /// @name 2D profile histogram booking
00526     //@{
00527 
00528     /// Book a 2D profile histogram with @a nxbins and @a nybins uniformly
00529     /// distributed across the ranges @a xlower - @a xupper and @a ylower - @a
00530     /// yupper respectively along the x- and y-axis.
00531     Profile2DPtr bookProfile2D(const std::string& name,
00532                                size_t nxbins, double xlower, double xupper,
00533                                size_t nybins, double ylower, double yupper,
00534                                const std::string& title="",
00535                                const std::string& xtitle="",
00536                                const std::string& ytitle="",
00537                                const std::string& ztitle="");
00538 
00539     /// Book a 2D profile histogram with non-uniform bins defined by the vectorx
00540     /// of bin edges @a xbinedges and @a ybinedges.
00541     Profile2DPtr bookProfile2D(const std::string& name,
00542                                const std::vector<double>& xbinedges,
00543                                const std::vector<double>& ybinedges,
00544                                const std::string& title="",
00545                                const std::string& xtitle="",
00546                                const std::string& ytitle="",
00547                                const std::string& ztitle="");
00548 
00549     /// Book a 2D profile histogram with binning from a reference scatter.
00550     // Profile2DPtr bookProfile2D(const std::string& name,
00551     //                            const Scatter3D& refscatter,
00552     //                            const std::string& title="",
00553     //                            const std::string& xtitle="",
00554     //                            const std::string& ytitle="",
00555     //                            const std::string& ztitle="");
00556 
00557     // /// Book a 2D profile histogram, using the binnings in the reference data histogram.
00558     // Profile2DPtr bookProfile2D(const std::string& name,
00559     //                            const std::string& title="",
00560     //                            const std::string& xtitle="",
00561     //                            const std::string& ytitle="",
00562     //                            const std::string& ztitle="");
00563 
00564     // /// Book a 2D profile histogram, using the binnings in the reference data histogram.
00565     // ///
00566     // /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00567     // Profile2DPtr bookProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00568     //                            const std::string& title="",
00569     //                            const std::string& xtitle="",
00570     //                            const std::string& ytitle="",
00571     //                            const std::string& ztitle="");
00572 
00573     //@}
00574 
00575 
00576     /// @name 2D scatter booking
00577     //@{
00578 
00579     /// @brief Book a 2-dimensional data point set with the given name.
00580     ///
00581     /// @note Unlike histogram booking, scatter booking by default makes no
00582     /// attempt to use reference data to pre-fill the data object. If you want
00583     /// this, which is sometimes useful e.g. when the x-position is not really
00584     /// meaningful and can't be extracted from the data, then set the @a
00585     /// copy_pts parameter to true. This creates points to match the reference
00586     /// data's x values and errors, but with the y values and errors zeroed...
00587     /// assuming that there is a reference histo with the same name: if there
00588     /// isn't, an exception will be thrown.
00589     Scatter2DPtr bookScatter2D(const std::string& name,
00590                                bool copy_pts=false,
00591                                const std::string& title="",
00592                                const std::string& xtitle="",
00593                                const std::string& ytitle="");
00594 
00595     /// @brief Book a 2-dimensional data point set, using the binnings in the reference data histogram.
00596     ///
00597     /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way.
00598     ///
00599     /// @note Unlike histogram booking, scatter booking by default makes no
00600     /// attempt to use reference data to pre-fill the data object. If you want
00601     /// this, which is sometimes useful e.g. when the x-position is not really
00602     /// meaningful and can't be extracted from the data, then set the @a
00603     /// copy_pts parameter to true. This creates points to match the reference
00604     /// data's x values and errors, but with the y values and errors zeroed.
00605     Scatter2DPtr bookScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00606                                bool copy_pts=false,
00607                                const std::string& title="",
00608                                const std::string& xtitle="",
00609                                const std::string& ytitle="");
00610 
00611     /// @brief Book a 2-dimensional data point set with equally spaced x-points in a range.
00612     ///
00613     /// The y values and errors will be set to 0.
00614     Scatter2DPtr bookScatter2D(const std::string& name,
00615                                size_t npts, double lower, double upper,
00616                                const std::string& title="",
00617                                const std::string& xtitle="",
00618                                const std::string& ytitle="");
00619 
00620     /// @brief Book a 2-dimensional data point set based on provided contiguous "bin edges".
00621     ///
00622     /// The y values and errors will be set to 0.
00623     Scatter2DPtr bookScatter2D(const std::string& hname,
00624                                const std::vector<double>& binedges,
00625                                const std::string& title,
00626                                const std::string& xtitle,
00627                                const std::string& ytitle);
00628 
00629     //@}
00630 
00631 
00632   public:
00633 
00634 
00635     /// @name Analysis object manipulation
00636     /// @todo Should really be protected: only public to keep BinnedHistogram happy for now...
00637     //@{
00638 
00639     /// Multiplicatively scale the given counter, @a cnt, by factor @s factor.
00640     void scale(CounterPtr cnt, double factor);
00641 
00642     /// Multiplicatively scale the given counters, @a cnts, by factor @s factor.
00643     /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh)
00644     /// @todo Use SFINAE for a generic iterable of CounterPtrs
00645     void scale(const std::vector<CounterPtr>& cnts, double factor) {
00646       for (auto& c : cnts) scale(c, factor);
00647     }
00648     /// @todo YUCK!
00649     template <std::size_t array_size>
00650     void scale(const CounterPtr (&cnts)[array_size], double factor) {
00651       // for (size_t i = 0; i < std::extent<decltype(cnts)>::value; ++i) scale(cnts[i], factor);
00652       for (auto& c : cnts) scale(c, factor);
00653     }
00654 
00655 
00656     /// Normalize the given histogram, @a histo, to area = @a norm.
00657     void normalize(Histo1DPtr histo, double norm=1.0, bool includeoverflows=true);
00658 
00659     /// Normalize the given histograms, @a histos, to area = @a norm.
00660     /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh)
00661     /// @todo Use SFINAE for a generic iterable of Histo1DPtrs
00662     void normalize(const std::vector<Histo1DPtr>& histos, double norm=1.0, bool includeoverflows=true) {
00663       for (auto& h : histos) normalize(h, norm, includeoverflows);
00664     }
00665     /// @todo YUCK!
00666     template <std::size_t array_size>
00667     void normalize(const Histo1DPtr (&histos)[array_size], double norm=1.0, bool includeoverflows=true) {
00668       for (auto& h : histos) normalize(h, norm, includeoverflows);
00669     }
00670 
00671     /// Multiplicatively scale the given histogram, @a histo, by factor @s factor.
00672     void scale(Histo1DPtr histo, double factor);
00673 
00674     /// Multiplicatively scale the given histograms, @a histos, by factor @s factor.
00675     /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh)
00676     /// @todo Use SFINAE for a generic iterable of Histo1DPtrs
00677     void scale(const std::vector<Histo1DPtr>& histos, double factor) {
00678       for (auto& h : histos) scale(h, factor);
00679     }
00680     /// @todo YUCK!
00681     template <std::size_t array_size>
00682     void scale(const Histo1DPtr (&histos)[array_size], double factor) {
00683       for (auto& h : histos) scale(h, factor);
00684     }
00685 
00686 
00687     /// Normalize the given histogram, @a histo, to area = @a norm.
00688     void normalize(Histo2DPtr histo, double norm=1.0, bool includeoverflows=true);
00689 
00690     /// Normalize the given histograms, @a histos, to area = @a norm.
00691     /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh)
00692     /// @todo Use SFINAE for a generic iterable of Histo2DPtrs
00693     void normalize(const std::vector<Histo2DPtr>& histos, double norm=1.0, bool includeoverflows=true) {
00694       for (auto& h : histos) normalize(h, norm, includeoverflows);
00695     }
00696     /// @todo YUCK!
00697     template <std::size_t array_size>
00698     void normalize(const Histo2DPtr (&histos)[array_size], double norm=1.0, bool includeoverflows=true) {
00699       for (auto& h : histos) normalize(h, norm, includeoverflows);
00700     }
00701 
00702     /// Multiplicatively scale the given histogram, @a histo, by factor @s factor.
00703     void scale(Histo2DPtr histo, double factor);
00704 
00705     /// Multiplicatively scale the given histograms, @a histos, by factor @s factor.
00706     /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh)
00707     /// @todo Use SFINAE for a generic iterable of Histo2DPtrs
00708     void scale(const std::vector<Histo2DPtr>& histos, double factor) {
00709       for (auto& h : histos) scale(h, factor);
00710     }
00711     /// @todo YUCK!
00712     template <std::size_t array_size>
00713     void scale(const Histo2DPtr (&histos)[array_size], double factor) {
00714       for (auto& h : histos) scale(h, factor);
00715     }
00716 
00717 
00718     /// Helper for counter division.
00719     ///
00720     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00721     void divide(CounterPtr c1, CounterPtr c2, Scatter1DPtr s) const;
00722 
00723     /// Helper for histogram division with raw YODA objects.
00724     ///
00725     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00726     void divide(const YODA::Counter& c1, const YODA::Counter& c2, Scatter1DPtr s) const;
00727 
00728 
00729     /// Helper for histogram division.
00730     ///
00731     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00732     void divide(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const;
00733 
00734     /// Helper for histogram division with raw YODA objects.
00735     ///
00736     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00737     void divide(const YODA::Histo1D& h1, const YODA::Histo1D& h2, Scatter2DPtr s) const;
00738 
00739 
00740     /// Helper for profile histogram division.
00741     ///
00742     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00743     void divide(Profile1DPtr p1, Profile1DPtr p2, Scatter2DPtr s) const;
00744 
00745     /// Helper for profile histogram division with raw YODA objects.
00746     ///
00747     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00748     void divide(const YODA::Profile1D& p1, const YODA::Profile1D& p2, Scatter2DPtr s) const;
00749 
00750 
00751     /// Helper for 2D histogram division.
00752     ///
00753     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00754     void divide(Histo2DPtr h1, Histo2DPtr h2, Scatter3DPtr s) const;
00755 
00756     /// Helper for 2D histogram division with raw YODA objects.
00757     ///
00758     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00759     void divide(const YODA::Histo2D& h1, const YODA::Histo2D& h2, Scatter3DPtr s) const;
00760 
00761 
00762     /// Helper for 2D profile histogram division.
00763     ///
00764     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00765     void divide(Profile2DPtr p1, Profile2DPtr p2, Scatter3DPtr s) const;
00766 
00767     /// Helper for 2D profile histogram division with raw YODA objects
00768     ///
00769     /// @note Assigns to the (already registered) output scatter, @a s.  Preserves the path information of the target.
00770     void divide(const YODA::Profile2D& p1, const YODA::Profile2D& p2, Scatter3DPtr s) const;
00771 
00772 
00773     /// Helper for histogram efficiency calculation.
00774     ///
00775     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00776     void efficiency(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const;
00777 
00778     /// Helper for histogram efficiency calculation.
00779     ///
00780     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00781     void efficiency(const YODA::Histo1D& h1, const YODA::Histo1D& h2, Scatter2DPtr s) const;
00782 
00783 
00784     /// Helper for histogram asymmetry calculation.
00785     ///
00786     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00787     void asymm(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const;
00788 
00789     /// Helper for histogram asymmetry calculation.
00790     ///
00791     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00792     void asymm(const YODA::Histo1D& h1, const YODA::Histo1D& h2, Scatter2DPtr s) const;
00793 
00794 
00795     /// Helper for converting a differential histo to an integral one.
00796     ///
00797     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00798     void integrate(Histo1DPtr h, Scatter2DPtr s) const;
00799 
00800     /// Helper for converting a differential histo to an integral one.
00801     ///
00802     /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target.
00803     void integrate(const Histo1D& h, Scatter2DPtr s) const;
00804 
00805     //@}
00806 
00807 
00808   public:
00809 
00810     /// List of registered analysis data objects
00811     const vector<AnalysisObjectPtr>& analysisObjects() const {
00812       return _analysisobjects;
00813     }
00814 
00815 
00816   protected:
00817 
00818     /// @name Data object registration, retrieval, and removal
00819     //@{
00820 
00821     /// Register a data object in the histogram system
00822     void addAnalysisObject(AnalysisObjectPtr ao);
00823 
00824     /// Get a data object from the histogram system
00825     /// @todo Use this default function template arg in C++11
00826     // template <typename AO=AnalysisObjectPtr>
00827     template <typename AO>
00828     const std::shared_ptr<AO> getAnalysisObject(const std::string& name) const {
00829       foreach (const AnalysisObjectPtr& ao, analysisObjects()) {
00830         if (ao->path() == histoPath(name)) return dynamic_pointer_cast<AO>(ao);
00831       }
00832       throw Exception("Data object " + histoPath(name) + " not found");
00833     }
00834 
00835     /// Get a data object from the histogram system (non-const)
00836     /// @todo Use this default function template arg in C++11
00837     // template <typename AO=AnalysisObjectPtr>
00838     template <typename AO>
00839     std::shared_ptr<AO> getAnalysisObject(const std::string& name) {
00840       foreach (const AnalysisObjectPtr& ao, analysisObjects()) {
00841         if (ao->path() == histoPath(name)) return dynamic_pointer_cast<AO>(ao);
00842       }
00843       throw Exception("Data object " + histoPath(name) + " not found");
00844     }
00845 
00846     /// Unregister a data object from the histogram system (by name)
00847     void removeAnalysisObject(const std::string& path);
00848 
00849     /// Unregister a data object from the histogram system (by pointer)
00850     void removeAnalysisObject(AnalysisObjectPtr ao);
00851 
00852 
00853     /// Get a named Histo1D object from the histogram system
00854     const Histo1DPtr getHisto1D(const std::string& name) const {
00855       return getAnalysisObject<Histo1D>(name);
00856     }
00857 
00858     /// Get a named Histo1D object from the histogram system (non-const)
00859     Histo1DPtr getHisto1D(const std::string& name) {
00860       return getAnalysisObject<Histo1D>(name);
00861     }
00862 
00863     /// Get a Histo1D object from the histogram system by axis ID codes (non-const)
00864     const Histo1DPtr getHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00865       return getAnalysisObject<Histo1D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00866     }
00867 
00868     /// Get a Histo1D object from the histogram system by axis ID codes (non-const)
00869     Histo1DPtr getHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00870       return getAnalysisObject<Histo1D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00871     }
00872 
00873 
00874     // /// Get a named Histo2D object from the histogram system
00875     // const Histo2DPtr getHisto2D(const std::string& name) const {
00876     //   return getAnalysisObject<Histo2D>(name);
00877     // }
00878 
00879     // /// Get a named Histo2D object from the histogram system (non-const)
00880     // Histo2DPtr getHisto2D(const std::string& name) {
00881     //   return getAnalysisObject<Histo2D>(name);
00882     // }
00883 
00884     // /// Get a Histo2D object from the histogram system by axis ID codes (non-const)
00885     // const Histo2DPtr getHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00886     //   return getAnalysisObject<Histo2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00887     // }
00888 
00889     // /// Get a Histo2D object from the histogram system by axis ID codes (non-const)
00890     // Histo2DPtr getHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00891     //   return getAnalysisObject<Histo2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00892     // }
00893 
00894 
00895     /// Get a named Profile1D object from the histogram system
00896     const Profile1DPtr getProfile1D(const std::string& name) const {
00897       return getAnalysisObject<Profile1D>(name);
00898     }
00899 
00900     /// Get a named Profile1D object from the histogram system (non-const)
00901     Profile1DPtr getProfile1D(const std::string& name) {
00902       return getAnalysisObject<Profile1D>(name);
00903     }
00904 
00905     /// Get a Profile1D object from the histogram system by axis ID codes (non-const)
00906     const Profile1DPtr getProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00907       return getAnalysisObject<Profile1D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00908     }
00909 
00910     /// Get a Profile1D object from the histogram system by axis ID codes (non-const)
00911     Profile1DPtr getProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00912       return getAnalysisObject<Profile1D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00913     }
00914 
00915 
00916     // /// Get a named Profile2D object from the histogram system
00917     // const Profile2DPtr getProfile2D(const std::string& name) const {
00918     //   return getAnalysisObject<Profile2D>(name);
00919     // }
00920 
00921     // /// Get a named Profile2D object from the histogram system (non-const)
00922     // Profile2DPtr getProfile2D(const std::string& name) {
00923     //   return getAnalysisObject<Profile2D>(name);
00924     // }
00925 
00926     // /// Get a Profile2D object from the histogram system by axis ID codes (non-const)
00927     // const Profile2DPtr getProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00928     //   return getAnalysisObject<Profile2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00929     // }
00930 
00931     // /// Get a Profile2D object from the histogram system by axis ID codes (non-const)
00932     // Profile2DPtr getProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00933     //   return getAnalysisObject<Profile2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00934     // }
00935 
00936 
00937     /// Get a named Scatter2D object from the histogram system
00938     const Scatter2DPtr getScatter2D(const std::string& name) const {
00939       return getAnalysisObject<Scatter2D>(name);
00940     }
00941 
00942     /// Get a named Scatter2D object from the histogram system (non-const)
00943     Scatter2DPtr getScatter2D(const std::string& name) {
00944       return getAnalysisObject<Scatter2D>(name);
00945     }
00946 
00947     /// Get a Scatter2D object from the histogram system by axis ID codes (non-const)
00948     const Scatter2DPtr getScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00949       return getAnalysisObject<Scatter2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00950     }
00951 
00952     /// Get a Scatter2D object from the histogram system by axis ID codes (non-const)
00953     Scatter2DPtr getScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) {
00954       return getAnalysisObject<Scatter2D>(makeAxisCode(datasetId, xAxisId, yAxisId));
00955     }
00956 
00957     //@}
00958 
00959 
00960   private:
00961 
00962     /// Name passed to constructor (used to find .info analysis data file, and as a fallback)
00963     string _defaultname;
00964 
00965     /// Pointer to analysis metadata object
00966     unique_ptr<AnalysisInfo> _info;
00967 
00968     /// Storage of all plot objects
00969     /// @todo Make this a map for fast lookup by path?
00970     vector<AnalysisObjectPtr> _analysisobjects;
00971 
00972     /// @name Cross-section variables
00973     //@{
00974     double _crossSection;
00975     bool _gotCrossSection;
00976     //@}
00977 
00978     /// The controlling AnalysisHandler object.
00979     AnalysisHandler* _analysishandler;
00980 
00981     /// Collection of cached refdata to speed up many autobookings: the
00982     /// reference data file should only be read once.
00983     mutable std::map<std::string, AnalysisObjectPtr> _refdata;
00984 
00985 
00986   private:
00987 
00988     /// @name Utility functions
00989     //@{
00990 
00991     /// Get the reference data for this paper and cache it.
00992     void _cacheRefData() const;
00993 
00994     //@}
00995 
00996 
00997     /// The assignment operator is private and must never be called.
00998     /// In fact, it should not even be implemented.
00999     Analysis& operator=(const Analysis&);
01000 
01001   };
01002 
01003 
01004 }
01005 
01006 
01007 // Include definition of analysis plugin system so that analyses automatically see it when including Analysis.hh
01008 #include "Rivet/AnalysisBuilder.hh"
01009 
01010 /// @def DECLARE_RIVET_PLUGIN
01011 /// Preprocessor define to prettify the global-object plugin hook mechanism.
01012 #define DECLARE_RIVET_PLUGIN(clsname) Rivet::AnalysisBuilder<clsname> plugin_ ## clsname
01013 
01014 /// @def DECLARE_ALIASED_RIVET_PLUGIN
01015 /// Preprocessor define to prettify the global-object plugin hook mechanism, with an extra alias name for this analysis.
01016 // #define DECLARE_ALIASED_RIVET_PLUGIN(clsname, alias) Rivet::AnalysisBuilder<clsname> plugin_ ## clsname ## ( ## #alias ## )
01017 #define DECLARE_ALIASED_RIVET_PLUGIN(clsname, alias) DECLARE_RIVET_PLUGIN(clsname)( #alias )
01018 
01019 /// @def DEFAULT_RIVET_ANA_CONSTRUCTOR
01020 /// Preprocessor define to prettify the manky constructor with name string argument
01021 #define DEFAULT_RIVET_ANALYSIS_CTOR(clsname) clsname() : Analysis(# clsname) {}
01022 
01023 // DEPRECATED ALIAS
01024 #define DEFAULT_RIVET_ANA_CONSTRUCTOR(clsname) DEFAULT_RIVET_ANALYSIS_CTOR(clsname)
01025 
01026 
01027 #endif