|
[Rivet-svn] r3233 - branches/2011-07-aida2yoda/include/YODAblackhole at projects.hepforge.org blackhole at projects.hepforge.orgThu Jul 21 18:04:58 BST 2011
Author: mkawalec Date: Thu Jul 21 18:04:58 2011 New Revision: 3233 Log: Moved the second dimension stuff to YODA svn. Added: branches/2011-07-aida2yoda/include/YODA/AnalysisObject.h branches/2011-07-aida2yoda/include/YODA/Axis1D.h branches/2011-07-aida2yoda/include/YODA/Bin.h branches/2011-07-aida2yoda/include/YODA/Dbn1D.h branches/2011-07-aida2yoda/include/YODA/Exceptions.h branches/2011-07-aida2yoda/include/YODA/Histo1D.h branches/2011-07-aida2yoda/include/YODA/HistoBin1D.h branches/2011-07-aida2yoda/include/YODA/Point2D.h branches/2011-07-aida2yoda/include/YODA/Profile1D.h branches/2011-07-aida2yoda/include/YODA/ReaderAIDA.h branches/2011-07-aida2yoda/include/YODA/Scatter2D.h branches/2011-07-aida2yoda/include/YODA/Writer.h branches/2011-07-aida2yoda/include/YODA/WriterAIDA.h Added: branches/2011-07-aida2yoda/include/YODA/AnalysisObject.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/AnalysisObject.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,186 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_AnalysisObject_h +#define YODA_AnalysisObject_h + +#include "YODA/Exceptions.h" +#include "YODA/Config/BuildConfig.h" +#include <string> +#include <map> + +namespace YODA { + + /// AnalysisObject is the base class for histograms and scatters + class AnalysisObject { + + public: + + /// Collection type for annotations, as a string-string map. + typedef std::map<std::string, std::string> Annotations; + + + /// @name Creation and destruction + //@{ + + /// Default constructor + AnalysisObject() { } + + /// Constructor giving a type, a path and an optional title + AnalysisObject(const std::string& type, const std::string& path, const std::string& title="") { + setAnnotation("Type", type); + setPath(path); + setTitle(title); + } + + /// Constructor giving a type, a path, another AO to copy annotation from, and an optional title + AnalysisObject(const std::string& type, const std::string& path, + const AnalysisObject& ao, const std::string& title="") { + setAnnotations(ao.annotations()); + setAnnotation("Type", type); + setPath(path); + setTitle(title); + } + + /// Default destructor + virtual ~AnalysisObject() { } + + /// Reset this analysis object + virtual void reset() = 0; + + //@} + + + public: + + ///@name Annotations + //@{ + + /// @brief Add or set an annotation by name + /// Note: Templated on arg type, but stored as a string. + template <typename T> + void setAnnotation(const std::string& name, const T& value) { + _annotations[name] = boost::lexical_cast<std::string>(value); + } + + /// @brief Add or set an annotation by name + /// Note: Templated on arg type, but stored as a string. Synonym for setAnnotation + template <typename T> + void addAnnotation(const std::string& name, const T& value) { + setAnnotation(name, value); + } + + /// Check if an annotation is defined + bool hasAnnotation(const std::string& name) const { + return _annotations.find(name) != _annotations.end(); + } + + /// Get all the annotations (as const ref) + const Annotations& annotations() const { + return _annotations; + } + + /// Set all annotations at once + void setAnnotations(const Annotations& anns) { + _annotations = anns; + } + + /// @brief Get an annotation by name (as a string) + const std::string& annotation(const std::string& name) const { + Annotations::const_iterator v = _annotations.find(name); + if (v == _annotations.end()) { + std::string missing = "YODA::AnalysisObject: No annotation named " + name; + throw AnnotationError(missing); + } + return v->second; + } + + /// @brief Get an annotation by name (copied to another type) + /// Note: templated on return type, with default as string + template <typename T> + const T annotation(const std::string& name) const { + std::string s = annotation(name); + return boost::lexical_cast<T>(s); + } + + + /// Delete an annotation by name + void rmAnnotation(const std::string& name) { + _annotations.erase(name); + } + + /// Delete an annotation by name + void clearAnnotations() { + _annotations.clear(); + } + + //@} + + + /// @name Standard annotations + //@{ + + /// Get the AO title. + /// Returns a null string if undefined, rather than throwing an exception cf. the Title annotation. + const std::string title() const { + try { + return annotation("Title"); + } catch (AnnotationError& ae) { + return ""; + } + } + + /// Set the AO title + void setTitle(const std::string& title) { + setAnnotation("Title", title); + } + + /// Get the AO path. + /// Returns a null string if undefined, rather than throwing an exception cf. the Title annotation. + const std::string path() const { + try { + return annotation("Path"); + } catch (AnnotationError& ae) { + return ""; + } + } + + /// Set the AO path + void setPath(const std::string& path) { + if (path.length() > 0 && path.find("/") != 0) { + throw AnnotationError("Histo paths must start with a slash (/) character."); + } + setAnnotation("Path", path); + } + + //@} + + + public: + + /// @name Persistency hooks + //@{ + + /// @todo Maybe make these private, and make Writer a friend of AO + + /// Get name of the analysis object type, for persistency + virtual std::string _aotype() const { + return annotation("Type"); + } + + //@} + + + private: + + /// The annotations indexed by name + std::map<std::string,std::string> _annotations; + + }; + + +} + +#endif // YODA_AnalysisObject_h Added: branches/2011-07-aida2yoda/include/YODA/Axis1D.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/Axis1D.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,349 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_Axis1D_h +#define YODA_Axis1D_h + +#include "YODA/AnalysisObject.h" +#include "YODA/Exceptions.h" +#include "YODA/Bin.h" +#include "YODA/Utils/sortedvector.h" +#include "YODA/Utils/MathUtils.h" +#include <string> +#include <cassert> +#include <cmath> +#include <algorithm> + +using namespace std; + +namespace YODA { + + + /// @brief A 1D templated container of ordered bins + template <typename BIN> + class Axis1D { + public: + + + typedef BIN Bin; + typedef typename Utils::sortedvector<BIN> Bins; + + + /// @name Helper functions to make bin edge vectors (see @file MathUtils.h) + //@{ + + static inline std::vector<double> mkBinEdgesLin(double start, double end, size_t nbins) { + return linspace(start, end, nbins); + } + + static inline std::vector<double> mkBinEdgesLog(double start, double end, size_t nbins) { + return logspace(start, end, nbins); + } + + //@} + + + private: + + /// @todo Remove + void _mkBinHash() { + for (size_t i = 0; i < numBins(); i++) { + // Insert upper bound mapped to bin ID + _binHash.insert(make_pair(_cachedBinEdges[i+1],i)); + } + } + + + void _mkAxis(const vector<double>& binedges) { + const size_t nbins = binedges.size() - 1; + for (size_t i = 0; i < nbins; ++i) { + _bins.push_back( BIN(binedges.at(i), binedges.at(i+1)) ); + } + //Sorting _bins to impose order: + _bins.sort(); + /// @todo Remove + _cachedBinEdges = binedges; + std::sort(_cachedBinEdges.begin(), _cachedBinEdges.end()); + _mkBinHash(); + } + + + void _mkAxis(const Bins& bins) { + _bins = bins; + + /// @todo Remove + for (size_t i = 0; i < bins.size(); ++i) { + _cachedBinEdges.push_back(bins.at(i).lowEdge()); + } + _cachedBinEdges.push_back(bins.back().highEdge()); + _mkBinHash(); + } + + + public: + + + /// Null constructor. + /// @todo Remove if we can. + Axis1D() { } + + + /// Constructor with a list of bin edges + /// @todo Accept a general iterable and remove this silly special-casing for std::vector + Axis1D(const vector<double>& binedges) { + assert(binedges.size() > 1); + _mkAxis(binedges); + } + + + /// Constructor with histogram limits, number of bins, and a bin distribution enum + Axis1D(size_t nbins, double lower, double upper) { + _mkAxis(linspace(lower, upper, nbins)); + } + + + /// @todo Accept a general iterable and remove this silly special-casing for std::vector + Axis1D(const vector<BIN>& bins) { + assert(!bins.empty()); + Bins sbins; + for (typename vector<BIN>::const_iterator b = bins.begin(); b != bins.end(); ++b) { + sbins.insert(*b); + } + _mkAxis(sbins); + } + + + /// @todo Accept a general iterable (and remove this internal detail special-casing?) + Axis1D(const Bins& bins) { + assert(!bins.empty()); + _mkAxis(bins); + } + + + ///////////////////// + + + public: + + unsigned int numBins() const { + return _bins.size(); + } + + + // void addBin() { + // } + + + Bins& bins() { + return _bins; + } + + + const Bins& bins() const { + return _bins; + } + + + std::pair<double,double> binEdges(size_t binId) const { + assert(binId < numBins()); + return make_pair(_cachedBinEdges[binId], _cachedBinEdges[binId+1]); + } + + + double lowEdge() const { + return _bins.front().lowEdge(); + } + + double highEdge() const { + return _bins.back().highEdge(); + } + + + BIN& bin(size_t index) { + if (index >= numBins()) + throw RangeError("YODA::Histo: index out of range"); + return _bins[index]; + } + + + const BIN& bin(size_t index) const { + if (index >= numBins()) + throw RangeError("YODA::Histo: index out of range"); + return _bins[index]; + } + + + BIN& binByCoord(double x) { + return bin(findBinIndex(x)); + } + + const BIN& binByCoord(double x) const { + return bin(findBinIndex(x)); + } + + + Dbn1D& totalDbn() { + return _dbn; + } + + const Dbn1D& totalDbn() const { + return _dbn; + } + + + Dbn1D& underflow() { + return _underflow; + } + + const Dbn1D& underflow() const { + return _underflow; + } + + + Dbn1D& overflow() { + return _overflow; + } + + const Dbn1D& overflow() const { + return _overflow; + } + + + size_t findBinIndex(double coord) const { + /// @todo Improve! + if (coord < _cachedBinEdges[0] || coord >= _cachedBinEdges[numBins()]) { + throw RangeError("Coordinate is outside the valid range: you should request the underflow or overflow"); + } + size_t i = _binHash.upper_bound(coord)->second; + return i; + } + + + void reset() { + _dbn.reset(); + _underflow.reset(); + _overflow.reset(); + for (typename Bins::iterator b = _bins.begin(); b != _bins.end(); ++b) { + b->reset(); + } + } + + + /// Scale the axis coordinates (i.e. bin edges) + /// @todo Base this on a general transformation of the axis coordinates via a supplied function (object) + void scale(double scalefactor) { + /// @todo Implement! + throw std::runtime_error("Axis coordinate transformations not yet implemented! Pester me, please."); + } + + + void scaleW(double scalefactor) { + _dbn.scaleW(scalefactor); + _underflow.scaleW(scalefactor); + _overflow.scaleW(scalefactor); + for (typename Bins::iterator b = _bins.begin(); b != _bins.end(); ++b) { + b->scaleW(scalefactor); + } + } + + + public: + + bool operator == (const Axis1D& other) const { + /// @todo Need/want to compare bin hash? + return + _cachedBinEdges == other._cachedBinEdges && + _binHash == other._binHash; + } + + + bool operator != (const Axis1D& other) const { + return ! operator == (other); + } + + + Axis1D<BIN>& operator += (const Axis1D<BIN>& toAdd) { + if (*this != toAdd) { + throw LogicError("YODA::Histo1D: Cannot add axes with different binnings."); + } + for (size_t i = 0; i < bins().size(); ++i) { + bins().at(i) += toAdd.bins().at(i); + } + _dbn += toAdd._dbn; + _underflow += toAdd._underflow; + _overflow += toAdd._overflow; + return *this; + } + + + Axis1D<BIN>& operator -= (const Axis1D<BIN>& toSubtract) { + if (*this != toSubtract) { + throw LogicError("YODA::Histo1D: Cannot subtract axes with different binnings."); + } + for (size_t i = 0; i < bins().size(); ++i) { + bins().at(i) += toSubtract.bins().at(i); + } + _dbn -= toSubtract._dbn; + _underflow -= toSubtract._underflow; + _overflow -= toSubtract._overflow; + return *this; + } + + + private: + + + /// @todo Store bins in a more flexible (and sorted) way + /// @todo Check non-overlap of bins + /// @todo Bin access by index + /// @todo Overall y-dbn for profiles? + + + /// @name Bin data + //@{ + + /// The bins contained in this histogram + Bins _bins; + + /// A distribution counter for overflow fills + Dbn1D _underflow; + /// A distribution counter for underlow fills + Dbn1D _overflow; + + /// A distribution counter for the whole histogram + Dbn1D _dbn; + + /// Bin edges: lower edges, except last entry, + /// which is the high edge of the last bin + std::vector<double> _cachedBinEdges; + + /// Map for fast bin lookup + std::map<double,size_t> _binHash; + //@} + + }; + + + + template <typename BIN> + Axis1D<BIN> operator + (const Axis1D<BIN>& first, const Axis1D<BIN>& second) { + Axis1D<BIN> tmp = first; + tmp += second; + return tmp; + } + + + template <typename BIN> + Axis1D<BIN> operator - (const Axis1D<BIN>& first, const Axis1D<BIN>& second) { + Axis1D<BIN> tmp = first; + tmp -= second; + return tmp; + } + + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/Bin.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/Bin.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,55 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_Bin_h +#define YODA_Bin_h + +#include <string> +#include <utility> + +namespace YODA { + + + /// @brief Base class for bins in 1D and 2D histograms. + /// This base class only provides very basic functionality for fill + /// weight statistics access, as 1D/2D and basic/profile histos have + /// quite difference implementations. + class Bin { + + public: + + /// @name Miscellaneous + //@{ + + /// Reset this bin + virtual void reset() = 0; + + //@} + + + public: + + /// @name Fill statistics + //@{ + + /// The number of entries + virtual unsigned long numEntries() const = 0; + + /// The sum of weights + virtual double sumW() const = 0; + + /// The sum of weights squared + virtual double sumW2() const = 0; + + //@} + + }; + + +} + + + +#endif Added: branches/2011-07-aida2yoda/include/YODA/Dbn1D.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/Dbn1D.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,151 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_Dbn1D_h +#define YODA_Dbn1D_h + +#include "YODA/Exceptions.h" + +namespace YODA { + + + /// @brief A 1D distribution This class is used internally by YODA to + /// centralise the calculation of statistics of unbounded, unbinned sampled + /// distributions. Each distribution fill contributes a weight, \f$ w \f$, and + /// a value, \f$ x \f$. By storing the total number of fills (ignoring + /// weights), \f$ \sum w \f$, \f$ \sum w^2 \f$, \f$ \sum wx \f$, + /// and \f$ \sum wx^2 \f$, the Dbn1D can calculate the mean and spread + /// (\f$ \sigma^2 \f$, \f$ \sigma \f$ and \f$ \hat{\sigma} \f$) of the + /// sampled distribution. It is used to provide this information in bins + /// and for the "hidden" \f$ y \f$ distribution in profile histogram bins. + class Dbn1D { + public: + + /// Constructor. + Dbn1D() { + reset(); + } + + + /// @name Modifiers + //@{ + + /// @brief Contribute a sample at @a val with weight @a weight. + /// @todo Be careful about negative weights. + void fill(double val, double weight=1.0); + + /// Reset the internal counters. + void reset(); + + /// Rescale as if all fill weights had been different by factor @a scalefactor. + void scaleW(double scalefactor) { + const double sf = scalefactor; + const double sf2 = sf*sf; + _sumW *= sf; + _sumW2 *= sf2; + _sumWX *= sf; + _sumWX2 *= sf2; + } + + //@} + + + public: + + /// @name High-level info + //@{ + + // bool isUnfilled() const { + // return (numEntries() == 0); + // } + + // bool isEmpty() const { + // return (sumW() == 0) + // } + + //@} + + + /// @name Distribution statistics + //@{ + + /// Weighted mean, \f$ \bar{x} \f$, of distribution. + double mean() const; + + /// Weighted variance, \f$ \sigma^2 \f$, of distribution. + double variance() const; + + /// Weighted standard deviation, \f$ \sigma \f$, of distribution. + double stdDev() const; + + /// Weighted standard error, \f$ \sim \sigma/\sqrt{N-1} \f$, of distribution. + double stdErr() const; + + //@} + + + /// @name Raw distribution running sums + //@{ + + /// Number of entries (number of times @c fill was called, ignoring weights) + unsigned long numEntries() const; + + /// Effective number of entries \f$ = (\sum w)^2 / \sum w^2 \f$ + double effNumEntries() const; + + /// The sum of weights + double sumW() const; + + /// The sum of weights squared + double sumW2() const; + + /// The sum of x*weight + double sumWX() const; + + /// The sum of x^2 * weight + double sumWX2() const; + + //@} + + + public: + + /// Add two dbns + Dbn1D& operator += (const Dbn1D&); + + /// Subtract one dbn from another + Dbn1D& operator -= (const Dbn1D&); + + + protected: + + /// Add two dbns (internal, explicitly named version) + Dbn1D& add(const Dbn1D&); + + /// Subtract one dbn from another (internal, explicitly named version) + Dbn1D& subtract(const Dbn1D&); + + + private: + + unsigned long _numFills; + double _sumW; + double _sumW2; + double _sumWX; + double _sumWX2; + + }; + + + /// Add two dbns + Dbn1D operator + (const Dbn1D& a, const Dbn1D& b); + + /// Subtract one dbn from another + Dbn1D operator - (const Dbn1D& a, const Dbn1D& b); + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/Exceptions.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/Exceptions.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,71 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_Exception_h +#define YODA_Exception_h + +#include <string> +#include <exception> +#include <stdexcept> + +namespace YODA { + + + /// @brief Generic unspecialised YODA runtime error. + /// NB. We don't use "Error" because that's a useful stats + /// word to have available! + class Exception : public std::runtime_error { + public: + Exception(const std::string& what) : std::runtime_error(what) {} + }; + + + /// Error for e.g. use of invalid bin ranges. + class RangeError : public Exception { + public: + RangeError(const std::string& what) : Exception(what) {} + }; + + + /// Error for places where it should not have been possible to get to! + class LogicError : public Exception { + public: + LogicError(const std::string& what) : Exception(what) {} + }; + + + /// @brief Errors relating to event/bin weights + /// Arises in computing statistical quantities because e.g. the bin + /// weight is zero or negative. + class WeightError : public Exception { + public: + WeightError(const std::string& what) : Exception(what) {} + }; + + + /// @brief Errors relating to insufficient (effective) statistics + class LowStatsError : public Exception { + public: + LowStatsError(const std::string& what) : Exception(what) {} + }; + + + /// @brief Error for unfound or broken AnalysisObject annotations + class AnnotationError : public Exception { + public: + AnnotationError(const std::string& what) : Exception(what) {} + }; + + + /// @brief Error for file reading errors + class ReadError : public Exception { + public: + ReadError(const std::string& what) : Exception(what) {} + }; + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/Histo1D.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/Histo1D.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,249 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_Histo1D_h +#define YODA_Histo1D_h + +#include "YODA/AnalysisObject.h" +#include "YODA/HistoBin1D.h" +#include "YODA/Scatter2D.h" +#include "YODA/Axis1D.h" +#include "YODA/Exceptions.h" +#include <vector> +#include <string> +#include <map> + +namespace YODA { + + + /// Convenience typedef + typedef Axis1D<HistoBin1D> Histo1DAxis; + + + /// A one-dimensional histogram. + class Histo1D : public AnalysisObject { + + public: + + /// Convenience typedefs + typedef Histo1DAxis Axis; + typedef Axis::Bins Bins; + + + /// @name Constructors + //@{ + + /// Constructor giving range and number of bins. + /// @todo Remove binning enum stuff + Histo1D(size_t nbins, double lower, double upper, + const std::string& path="", const std::string& title="") + : AnalysisObject("Histo1D", path, title), + _axis(nbins, lower, upper) + { } + + /// @brief Constructor giving explicit bin edges. + /// For n bins, binedges.size() == n+1, the last + /// one being the upper bound of the last bin + Histo1D(const std::vector<double>& binedges, + const std::string& path="", const std::string& title="") + : AnalysisObject("Histo1D", path, title), + _axis(binedges) + { } + + /// Constructor giving a vector of bins. + /// @todo Allow any iterable of bins (use Boost::Range?) + Histo1D(const std::vector<HistoBin1D>& bins, + const std::string& path="", const std::string& title="") + : AnalysisObject("Histo1D", path, title), + _axis(bins) + { } + + /// Copy constructor with optional new path + Histo1D(const Histo1D& h, const std::string& path=""); + + /// Constructor from a Scatter2D's binning, with optional new path + Histo1D(const Scatter2D& s, const std::string& path=""); + + /// Constructor from a Profile1D's binning, with optional new path + Histo1D(const Profile1D& p, const std::string& path=""); + + //@} + + + public: + + /// @name Persistency hooks + //@{ + + /// Get name of the analysis object type, for persisting + std::string _aotype() const { return "Histo1D"; } + + /// Set the state of the histo object, for unpersisting + /// @todo Need to set annotations (do that on AO), all-histo Dbns, and dbns for every bin. Delegate! + // void _setstate() = 0; + + //@} + + + /// @name Modifiers + //@{ + + /// Fill histo by value and weight + void fill(double x, double weight=1.0); + + /// @brief Reset the histogram. + /// Keep the binning but set all bin contents and related quantities to zero + virtual void reset() { + _axis.reset(); + } + + /// Rescale as if all fill weights had been different by factor @a scalefactor. + void scaleW(double scalefactor) { + _axis.scaleW(scalefactor); + } + + //@} + + + public: + + /// @name Bin accessors + //@{ + + /// Number of bins on this axis (not counting under/overflow) + size_t numBins() const { + return bins().size(); + } + + /// Low edge of this histo's axis + double lowEdge() const { + return _axis.lowEdge(); + } + + /// High edge of this histo's axis + double highEdge() const { + return _axis.highEdge(); + } + + /// Access the bin vector + /// @todo Actually, it's a Histo + std::vector<YODA::HistoBin1D>& bins() { + return _axis.bins(); + } + + /// Access the bin vector (const version) + const std::vector<YODA::HistoBin1D>& bins() const { + return _axis.bins(); + } + + /// Access a bin by index (non-const version) + HistoBin1D& bin(size_t index) { + return _axis.bins()[index]; + } + + /// Access a bin by index (const version) + const HistoBin1D& bin(size_t index) const { + return _axis.bins()[index]; + } + + /// Access a bin by coordinate (non-const version) + HistoBin1D& binByCoord(double x) { + return _axis.binByCoord(x); + } + + /// Access a bin by coordinate (const version) + const HistoBin1D& binByCoord(double x) const { + return _axis.binByCoord(x); + } + + //@} + + + public: + + /// @name Whole histo data + //@{ + + /// Get the total area of the histogram + double integral(bool includeoverflows=true) const { + return sumW(includeoverflows); + } + + /// Get sum of weights in histo + double sumW(bool includeoverflows=true) const; + + /// Get sum of squared weights in histo + double sumW2(bool includeoverflows=true) const; + + /// Get the mean + double mean(bool includeoverflows=true) const; + + /// Get the variance + double variance(bool includeoverflows=true) const; + + /// Get the standard deviation + double stdDev(bool includeoverflows=true) const { + return std::sqrt(variance(includeoverflows)); + } + + //@} + + + public: + + /// @name Adding and subtracting histograms + //@{ + + /// Add another histogram to this + Histo1D& operator += (const Histo1D& toAdd) { + _axis += toAdd._axis; + return *this; + } + + /// Subtract another histogram from this + Histo1D& operator -= (const Histo1D& toSubtract) { + _axis -= toSubtract._axis; + return *this; + } + + //@} + + + private: + + /// @name Bin data + //@{ + + /// Definition of bin edges and contents + Axis1D<HistoBin1D> _axis; + + //@} + + }; + + + /// @name Combining histos: global operators + //@{ + + /// Add two histograms + inline Histo1D operator + (const Histo1D& first, const Histo1D& second) { + Histo1D tmp = first; + tmp += second; + return tmp; + } + + /// Subtract two histograms + inline Histo1D operator - (const Histo1D& first, const Histo1D& second) { + Histo1D tmp = first; + tmp -= second; + return tmp; + } + + //@} + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/HistoBin1D.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/HistoBin1D.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,106 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_HistoBin1D_h +#define YODA_HistoBin1D_h + +#include "YODA/Bin1D.h" +#include "YODA/Exceptions.h" + +namespace YODA { + + + /// @brief A Bin in a 1D histogram + class HistoBin1D : public Bin1D { + + public: + + /// @name Constructor giving bin low and high edges. + //@{ + HistoBin1D(double lowedge, double highedge); + HistoBin1D(std::pair<double,double> edges); + //@} + + + public: + + /// @name Modifiers + //@{ + + /// @brief Fill this bin with weight @a weight at position @a coord. + void fill(double coord, double weight=1.0); + + /// @brief Fill this bin with weight @a weight. + void fillBin(double weight=1.0); + + /// Reset this bin + void reset() { + Bin1D::reset(); + } + + /// Rescale as if all fill weights had been different by factor @a scalefactor. + void scaleW(double scalefactor) { + _xdbn.scaleW(scalefactor); + } + + //@} + + + public: + + /// @name Bin content info + //@{ + /// The area is the sum of weights in the bin, i.e. the + /// width of the bin has no influence on this figure. + double area() const; + + /// The height is defined as area/width. + double height() const; + //@} + + /// @name Error info + //@{ + + /// Error computed using binomial statistics on the sum of bin weights, + /// i.e. err_area = sqrt{sum{weights}} + double areaError() const; + + /// As for the height vs. area, the height error includes a scaling factor + /// of the bin width, i.e. err_height = sqrt{sum{weights}} / width. + double heightError() const; + + //@} + + + public: + + /// Add two bins (for use by Histo1D). + HistoBin1D& operator += (const HistoBin1D&); + + /// Subtract two bins + HistoBin1D& operator -= (const HistoBin1D&); + + + protected: + + /// Add two bins (internal, explicitly named version) + HistoBin1D& add(const HistoBin1D&); + + /// Subtract one bin from another (internal, explicitly named version) + HistoBin1D& subtract(const HistoBin1D&); + + }; + + + /// Add two bins + HistoBin1D operator + (const HistoBin1D& a, const HistoBin1D& b); + + /// Subtract two bins + HistoBin1D operator - (const HistoBin1D& a, const HistoBin1D& b); + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/Point2D.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/Point2D.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,270 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_POINT2D_H +#define YODA_POINT2D_H + +#include "YODA/Exceptions.h" +#include "YODA/Utils/MathUtils.h" +#include <utility> + +namespace YODA { + + + /// A 2D data point to be contained in a Scatter2D + class Point2D { + public: + + typedef std::pair<double,double> ValuePair; + + + /// @name Constructors + //@{ + + // Default constructor + Point2D() { } + + + /// Values with optional symmetric errors + Point2D(double x, double y, double ex=0.0, double ey=0.0) + : _x(x), _y(y) + { + _ex = std::make_pair(ex, ex); + _ey = std::make_pair(ey, ey); + } + + + /// Values with explicit asymmetric errors + Point2D(double x, double y, + double exminus, + double explus, + double eyminus, + double eyplus) + : _x(x), _y(y) + { + _ex = std::make_pair(exminus, explus); + _ey = std::make_pair(eyplus, eyplus); + } + + + /// Values with symmetric errors on x and asymmetric errors on y + Point2D(double x, double y, double ex, const std::pair<double,double>& ey) + : _x(x), _y(y), _ey(ey) + { + _ex = std::make_pair(ex, ex); + } + + + /// Values with asymmetric errors on x and symmetric errors on y + Point2D(double x, double y, const std::pair<double,double>& ex, double ey) + : _x(x), _y(y), _ex(ex) + { + _ey = std::make_pair(ey, ey); + } + + + /// Values with asymmetric errors on both x and y + Point2D(double x, double y, const std::pair<double,double>& ex, const std::pair<double,double>& ey) + : _x(x), _y(y), _ex(ex), _ey(ey) + { + } + + //@} + + + public: + + /// @name Value and error accessors + //@{ + + /// Get x value + double x() const { return _x; } + + /// Set x value + void setX(double x) { _x = x; } + + /// Get y value + double y() const { return _y; } + + /// Set y value + void setY(double y) { _y = y; } + + //@} + + + /// @name x error accessors + //@{ + + /// Get x-error values + const std::pair<double,double>& xErrs() const { + return _ex; + } + + /// Get negative x-error value + const double xErrMinus() const { + return _ex.first; + } + + /// Get positive x-error value + const double xErrPlus() const { + return _ex.second; + } + + /// Get average x-error value + double xErrAvg() const { + return (_ex.first + _ex.second)/2.0; + } + + /// Set symmetric x error + void setXErr(double ex) { + _ex.first = ex; + _ex.second = ex; + } + + /// Set asymmetric x error + void setXErr(std::pair<double,double> ex) { + _ex = ex; + } + + /// Set asymmetric x error + void setXErr(double exminus, double explus) { + _ex.first = exminus; + _ex.second = explus; + } + + /// Get value minus negative x-error + const double xMin() const { + return _x - _ex.first; + } + + /// Get value plus positive x-error + const double xMax() const { + return _x + _ex.second; + } + + //@} + + + /// @name y error accessors + //@{ + + /// Get y-error values + const std::pair<double,double>& yErrs() const { + return _ey; + } + + /// Get negative y-error value + const double yErrMinus() const { + return _ey.first; + } + + /// Get positive y-error value + const double yErrPlus() const { + return _ey.second; + } + + /// Get average y-error value + double yErrAvg() const { + return (_ey.first + _ey.second)/2.0; + } + + /// Set symmetric y error + void setYErr(double ey) { + _ey.first = ey; + _ey.second = ey; + } + + /// Set asymmetric y error + void setYErr(std::pair<double,double> ey) { + _ey = ey; + } + + /// Set asymmetric y error + void setYErr(double eyminus, double eyplus) { + _ey.first = eyminus; + _ey.second = eyplus; + } + + /// Get value minus negative y-error + const double yMin() const { + return _y - _ey.first; + } + + /// Get value plus positive y-error + const double yMax() const { + return _y + _ey.second; + } + + //@} + + + protected: + + /// @name Value and error variables + //@{ + + double _x; + double _y; + std::pair<double,double> _ex; + std::pair<double,double> _ey; + + //@} + + }; + + + + /// @name Comparison operators + //@{ + + /// Equality test of x characteristics only + inline bool operator==(const YODA::Point2D& a, const YODA::Point2D& b) { + const bool same_val = YODA::fuzzyEquals(a.x(), b.x()); + const bool same_eminus = YODA::fuzzyEquals(a.xErrMinus(), b.xErrMinus()); + const bool same_eplus = YODA::fuzzyEquals(a.xErrPlus(), b.xErrPlus()); + return same_val && same_eminus && same_eplus; + } + + /// Equality test of x characteristics only + inline bool operator!=(const YODA::Point2D& a, const YODA::Point2D& b) { + return !(a == b); + } + + /// Less-than operator used to sort bins by x-ordering + inline bool operator<(const YODA::Point2D& a, const YODA::Point2D& b) { + if (!YODA::fuzzyEquals(a.x(), b.x())) { + return a.x() < b.x(); + } + if (!YODA::fuzzyEquals(a.xErrMinus(), b.xErrMinus())) { + return a.xErrMinus() < b.xErrMinus(); + } + if (!YODA::fuzzyEquals(a.xErrPlus(), b.xErrPlus())) { + return a.xErrPlus() < b.xErrPlus(); + } + return false; + } + + /// Less-than-or-equals operator used to sort bins by x-ordering + inline bool operator<=(const YODA::Point2D& a, const YODA::Point2D& b) { + if (a == b) return true; + return a < b; + } + + /// Greater-than operator used to sort bins by x-ordering + inline bool operator>(const YODA::Point2D& a, const YODA::Point2D& b) { + return !(a <= b); + } + + /// Greater-than-or-equals operator used to sort bins by x-ordering + inline bool operator>=(const YODA::Point2D& a, const YODA::Point2D& b) { + return !(a < b); + } + + //@} + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/Profile1D.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/Profile1D.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,210 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_Profile1D_h +#define YODA_Profile1D_h + +#include "YODA/AnalysisObject.h" +#include "YODA/ProfileBin1D.h" +#include "YODA/Axis1D.h" +#include "YODA/Exceptions.h" +#include <vector> +#include <string> +#include <map> + +namespace YODA { + + // Forward declarations + class Histo1D; + class Scatter2D; + + + /// Convenience typedef + typedef Axis1D<ProfileBin1D> Profile1DAxis; + + + /// A one-dimensional profile histogram. + class Profile1D : public AnalysisObject { + public: + + /// Convenience typedefs + typedef Profile1DAxis Axis; + typedef Axis::Bins Bins; + + + /// @name Constructors + //@{ + + /// Constructor giving range and number of bins + Profile1D(size_t nxbins, double xlower, double xupper, + const std::string& path="", const std::string& title="") + : AnalysisObject("Profile1D", path, title), + _axis(nxbins, xlower, xupper) + { } + + /// Constructor giving explicit bin edges + /// For n bins, binedges.size() == n+1, the last + /// one being the upper bound of the last bin + Profile1D(const std::vector<double>& xbinedges, + const std::string& path="", const std::string& title="") + : AnalysisObject("Profile1D", path, title), + _axis(xbinedges) + { } + + /// Constructor giving a vector of bins + Profile1D(const std::vector<ProfileBin1D>& xbins, + const std::string& path="", const std::string& title="") + : AnalysisObject("Profile1D", path, title), + _axis(xbins) + { } + + + /// Copy constructor with optional new path + Profile1D(const Profile1D& p, const std::string& path=""); + + /// Constructor from a Scatter2D's binning, with optional new path + Profile1D(const Scatter2D& s, const std::string& path=""); + + /// Constructor from a Histo1D's binning, with optional new path + Profile1D(const Histo1D& h, const std::string& path=""); + + + //@} + + + /// @name Persistency hooks + //@{ + + /// Get name of the analysis object type, for persisting + std::string _aotype() const { return "Profile1D"; } + + /// Set the state of the profile object, for unpersisting + /// @todo Need to set annotations (do that on AO), all-histo Dbns, and dbns for every bin. Delegate! + // void _setstate() = 0; + + //@} + + + /// @name Modifiers + //@{ + + /// Fill histo by value and weight + void fill(double x, double y, double weight=1.0); + + /// @brief Reset the histogram + /// Keep the binning but set all bin contents and related quantities to zero + void reset() { + _axis.reset(); + } + + /// Rescale as if all fill weights had been different by factor @a scalefactor. + void scaleW(double scalefactor) { + _axis.scaleW(scalefactor); + } + + //@} + + + /// @name Bin accessors + //@{ + + /// Number of bins on this axis (not counting under/overflow) + size_t numBins() const { + return bins().size(); + } + + /// Access the bin vector + std::vector<YODA::ProfileBin1D>& bins() { + return _axis.bins(); + } + + /// Access the bin vector + const std::vector<YODA::ProfileBin1D>& bins() const { + return _axis.bins(); + } + + /// Access a bin by x-coordinate. + ProfileBin1D& binByCoord(double x) { + return _axis.binByCoord(x); + } + + /// Access a bin by x-coordinate. + const ProfileBin1D& binByCoord(double x) const { + return _axis.binByCoord(x); + } + + //@} + + + public: + + /// @name Whole histo data + //@{ + + /// Get sum of weights in histo. + double sumW(bool includeoverflows=true) const; + + /// Get sum of squared weights in histo. + double sumW2(bool includeoverflows=true) const; + + //@} + + + public: + + /// @name Adding and subtracting histograms + //@{ + + /// Add another histogram to this + Profile1D& operator += (const Profile1D& toAdd) { + _axis += toAdd._axis; + return *this; + } + + /// Subtract another histogram from this + Profile1D& operator -= (const Profile1D& toSubtract) { + _axis -= toSubtract._axis; + return *this; + } + + //@} + + + private: + + /// @name Bin data + //@{ + + /// The bins contained in this profile histogram + Axis1D<ProfileBin1D> _axis; + + //@} + + }; + + + /// @name Combining profile histos: global operators + //@{ + + /// Add two profile histograms + inline Profile1D operator + (const Profile1D& first, const Profile1D& second) { + Profile1D tmp = first; + tmp += second; + return tmp; + } + + /// Subtract two profile histograms + inline Profile1D operator - (const Profile1D& first, const Profile1D& second) { + Profile1D tmp = first; + tmp -= second; + return tmp; + } + + //@} + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/ReaderAIDA.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/ReaderAIDA.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,54 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_READERAIDA_H +#define YODA_READERAIDA_H + +#include "YODA/AnalysisObject.h" +#include "YODA/Reader.h" + +namespace YODA { + + + /// @brief Persistency reader for AIDA XML format. + class ReaderAIDA : public Reader { + public: + + /// Singleton creation function + static Reader& create() { + static ReaderAIDA _instance; + return _instance; + } + + + void read(std::istream& stream, std::vector<AnalysisObject*>& aos) { + _readDoc(stream, aos); + } + + // Include definitions of all read methods (all fulfilled by Reader::read(...)) + //#include "YODA/ReaderMethods.icc" + + + + protected: + + void _readDoc(std::istream& stream, vector<AnalysisObject*>& aos); + //void readGenericAO(std::istream& stream); + // virtual void readHisto(std::istream& stream, const Histo1D& h); + // virtual void readProfile(std::istream& stream, const Profile1D& p); + //void readScatter(std::istream& stream, const Scatter2D& p); + + + private: + + /// Private constructor, since it's a singleton. + ReaderAIDA() { } + + }; + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/Scatter2D.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/Scatter2D.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,282 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_SCATTER2D_H +#define YODA_SCATTER2D_H + +#include "YODA/AnalysisObject.h" +#include "YODA/Point2D.h" +#include "YODA/Utils/sortedvector.h" +#include <vector> +#include <set> +#include <string> +#include <utility> + +namespace YODA { + + + class Histo1D; + class Profile1D; + + + /// A very generic data type which is just a collection of 2D data points with errors + class Scatter2D : public AnalysisObject { + public: + + /// Type of the native Point2D collection + typedef Utils::sortedvector<Point2D> Points; + + + /// @name Constructors + //@{ + + Scatter2D(const std::string& path="", const std::string& title="") + : AnalysisObject("Scatter2D", path, title) + { } + + + Scatter2D(const Points& points, + const std::string& path="", const std::string& title="") + : AnalysisObject("Scatter2D", path, title), + _points(points) + { } + + /// @todo Add constructor from generic container/Range + + /// Values with no errors + Scatter2D(const std::vector<double>& x, const std::vector<double>& y, + const std::string& path="", const std::string& title="") + : AnalysisObject("Scatter2D", path, title) + { + assert(x.size() == y.size()); + for (size_t i = 0; i < x.size(); ++i) { + addPoint(x[i], y[i]); + } + } + + /// Values with symmetric errors on x and y + Scatter2D(const std::vector<double>& x, const std::vector<double>& y, + const std::vector<double>& ex, const std::vector<double>& ey, + const std::string& path="", const std::string& title="") + : AnalysisObject("Scatter2D", path, title) + { + assert(x.size() == y.size() && x.size() == ex.size() && x.size() == ey.size()); + for (size_t i = 0; i < x.size(); ++i) { + addPoint(x[i], y[i], ex[i], ey[i]); + } + } + + /// Values with symmetric errors on x and asymmetric errors on y + Scatter2D(const std::vector<double>& x, const std::vector<double>& y, + const std::vector<double>& ex, const std::vector<std::pair<double,double> >& ey, + const std::string& path="", const std::string& title="") + : AnalysisObject("Scatter2D", path, title) + { + assert(x.size() == y.size() && x.size() == ex.size() && x.size() == ey.size()); + for (size_t i = 0; i < x.size(); ++i) { + addPoint(Point2D(x[i], y[i], ex[i], ey[i])); + } + } + + /// Values with asymmetric errors on x and symmetric errors on y + Scatter2D(const std::vector<double>& x, const std::vector<double>& y, + const std::vector<std::pair<double,double> >& ex, const std::vector<double>& ey, + const std::string& path="", const std::string& title="") + : AnalysisObject("Scatter2D", path, title) + { + assert(x.size() == y.size() && x.size() == ex.size() && x.size() == ey.size()); + for (size_t i = 0; i < x.size(); ++i) { + addPoint(Point2D(x[i], y[i], ex[i], ey[i])); + } + } + + /// Values with asymmetric errors on both x and y + Scatter2D(const std::vector<double>& x, const std::vector<double>& y, + const std::vector<std::pair<double,double> >& ex, const std::vector<std::pair<double,double> >& ey, + const std::string& path="", const std::string& title="") + : AnalysisObject("Scatter2D", path, title) + { + assert(x.size() == y.size() && x.size() == ex.size() && x.size() == ey.size()); + for (size_t i = 0; i < x.size(); ++i) { + addPoint(Point2D(x[i], y[i], ex[i], ey[i])); + } + } + + /// Values with completely explicit asymmetric errors + Scatter2D(const std::vector<double>& x, const std::vector<double>& y, + const std::vector<double>& exminus, + const std::vector<double>& explus, + const std::vector<double>& eyminus, + const std::vector<double>& eyplus, + const std::string& path="", const std::string& title="") + : AnalysisObject("Scatter2D", path, title) + { + assert(x.size() == y.size() && + x.size() == exminus.size() && x.size() == explus.size() && + x.size() == eyminus.size() && x.size() == eyplus.size()); + for (size_t i = 0; i < x.size(); ++i) { + addPoint(Point2D(x[i], exminus[i], explus[i], y[i], eyminus[i], eyplus[i])); + } + } + + //@} + + + /// Clear all points + void reset() { + _points.clear(); + } + + + /// @name Persistency hooks + //@{ + + /// Set the state of the profile object, for unpersisting + /// @todo Need to set annotations (do that on AO), all-histo Dbns, and dbns for every bin. Delegate! + // void _setstate() = 0; + + //@} + + + /////////////////////////////////////////////////// + + /// @name Point accessors + //@{ + + size_t numPoints() const { + return _points.size(); + } + + + const Points& points() const { + return _points; + } + + + Point2D& point(size_t index) { + assert(index < numPoints()); + return _points.at(index); + } + + + const Point2D& point(size_t index) const { + assert(index < numPoints()); + return _points.at(index); + } + + //@} + + + /// @name Point adders + //@{ + + Scatter2D& addPoint(const Point2D& pt) { + _points.insert(pt); + return *this; + } + + Scatter2D& addPoint(double x, double y) { + _points.insert(Point2D(x, y)); + return *this; + } + + Scatter2D& addPoint(double x, double y, double ex, double ey) { + _points.insert(Point2D(x, y, ex, ey)); + return *this; + } + + Scatter2D& addPoint(double x, double y, std::pair<double,double> ex, double ey) { + _points.insert(Point2D(x, y, ex, ey)); + return *this; + } + + Scatter2D& addPoint(double x, double y, double ex, std::pair<double,double> ey) { + _points.insert(Point2D(x, y, ex, ey)); + return *this; + } + + Scatter2D& addPoint(double x, double y, std::pair<double,double> ex, std::pair<double,double> ey) { + _points.insert(Point2D(x, y, ex, ey)); + return *this; + } + + Scatter2D& addPoint(double x, double exminus, double explus, + double y, double eyminus, double eyplus) { + _points.insert(Point2D(x, exminus, explus, y, eyminus, eyplus)); + return *this; + } + + Scatter2D& addPoints(Points pts) { + foreach (const Point2D& pt, pts) { + addPoint(pt); + } + return *this; + } + + //@} + + + /// @todo Better name? + Scatter2D& combineWith(const Scatter2D& other) { + addPoints(other.points()); + return *this; + } + + + /// @todo Better name? + /// @todo Convert to accept a Range or generic + Scatter2D& combineWith(const std::vector<Scatter2D>& others) { + foreach (const Scatter2D& s, others) { + combineWith(s); + } + return *this; + } + + + private: + + Points _points; + + std::string _myaotype; + + }; + + + + inline Scatter2D combine(const Scatter2D& a, const Scatter2D& b) { + Scatter2D rtn = a; + rtn.combineWith(b); + return rtn; + } + + + inline Scatter2D combine(const std::vector< Scatter2D >& scatters) { + Scatter2D rtn; + for (std::vector<Scatter2D>::const_iterator s = scatters.begin(); + s != scatters.end(); ++s) { + rtn.combineWith(*s); + } + return rtn; + } + + + ////////////////////////////////// + + + /// @name Conversion functions from other data types + //@{ + + /// Make a Scatter2D representation of a Histo1D + Scatter2D mkScatter(const Histo1D& h); + + /// Make a Scatter2D representation of a Profile1D + Scatter2D mkScatter(const Profile1D& p); + + //@} + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/Writer.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/Writer.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,130 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_Writer_h +#define YODA_Writer_h + +#include "YODA/AnalysisObject.h" +#include "YODA/Histo1D.h" +#include "YODA/Profile1D.h" +#include "YODA/Scatter2D.h" +#include <string> +#include <fstream> + +namespace YODA { + + + /// Pure virtual base class for various output writers. + class Writer { + public: + + /// Virtual destructor + virtual ~Writer() {} + + + /// @name Writing a single analysis object. + //@{ + + /// Write out object @a ao to output stream @a stream. + void write(std::ostream& stream, const AnalysisObject& ao); + + /// Write out object @a ao to file @a filename. + void write(const std::string& filename, const AnalysisObject& ao); + + //@} + + + /// @name Writing multiple analysis objects by collection. + //@{ + + /// Write out a collection of objects @a objs to output stream @a stream. + void write(std::ostream& stream, const std::vector<AnalysisObject*>& aos) { + write(stream, aos.begin(), aos.end()); + } + /// Write out a collection of objects @a objs to file @a filename. + void write(const std::string& filename, const std::vector<AnalysisObject*>& aos) { + write(filename, aos.begin(), aos.end()); + } + + + /// Write out a collection of objects @a objs to output stream @a stream. + void write(std::ostream& stream, const std::list<AnalysisObject*>& aos) { + write(stream, aos.begin(), aos.end()); + } + /// Write out a collection of objects @a objs to file @a filename. + void write(const std::string& filename, const std::list<AnalysisObject*>& aos) { + write(filename, aos.begin(), aos.end()); + } + + + /// Write out a collection of objects @a objs to output stream @a stream. + void write(std::ostream& stream, const std::set<AnalysisObject*>& aos) { + write(stream, aos.begin(), aos.end()); + } + /// Write out a collection of objects @a objs to file @a filename. + void write(const std::string& filename, const std::set<AnalysisObject*>& aos) { + write(filename, aos.begin(), aos.end()); + } + + + /// Write out a collection of objects @a objs to output stream @a stream. + void write(std::ostream& stream, const std::deque<AnalysisObject*>& aos) { + write(stream, aos.begin(), aos.end()); + } + /// Write out a collection of objects @a objs to file @a filename. + void write(const std::string& filename, const std::deque<AnalysisObject*>& aos) { + write(filename, aos.begin(), aos.end()); + } + + //@} + + + /// @name Writing multiple analysis objects by iterator range. + //@{ + + /// Write out the objects specified by start iterator @a begin and end + /// iterator @a end to output stream @a stream. + template <typename AOITER> + void write(std::ostream& stream, const AOITER& begin, const AOITER& end) { + writeHeader(stream); + for (AOITER ipao = begin; ipao != end; ++ipao) { + writeBody(stream, **ipao); + } + writeFooter(stream); + } + + /// Write out the objects specified by start iterator @a begin and end + /// iterator @a end to file @a filename. + template <typename AOITER> + void write(const std::string& filename, + const AOITER& begin, + const AOITER& end) { + std::ofstream outstream; + outstream.open(filename.c_str()); + write(outstream, begin, end); + outstream.close(); + } + + //@} + + + protected: + + /// Main writer elements + virtual void writeHeader(std::ostream& stream) = 0; + void writeBody(std::ostream& stream, const AnalysisObject& ao); + virtual void writeFooter(std::ostream& stream) = 0; + + /// Specific AO type writer implementations + virtual void writeHisto1D(std::ostream& os, const Histo1D& h) = 0; + virtual void writeProfile1D(std::ostream& os, const Profile1D& p) = 0; + virtual void writeScatter2D(std::ostream& os, const Scatter2D& s) = 0; + + }; + + +} + +#endif Added: branches/2011-07-aida2yoda/include/YODA/WriterAIDA.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ branches/2011-07-aida2yoda/include/YODA/WriterAIDA.h Thu Jul 21 18:04:58 2011 (r3233) @@ -0,0 +1,54 @@ +// -*- C++ -*- +// +// This file is part of YODA -- Yet more Objects for Data Analysis +// Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) +// +#ifndef YODA_WRITERAIDA_H +#define YODA_WRITERAIDA_H + +#include "YODA/AnalysisObject.h" +#include "YODA/Writer.h" + +#include <vector> +#include <string> +#include <ostream> + +namespace YODA { + + + /// @brief Persistency writer for AIDA XML format. + class WriterAIDA : public Writer { + public: + + /// Singleton creation function + static Writer& create() { + static WriterAIDA _instance; + return _instance; + } + + + // Include definitions of all write methods (all fulfilled by Writer::write(...)) + #include "YODA/WriterMethods.icc" + + + protected: + + void writeHeader(std::ostream& stream); + void writeFooter(std::ostream& stream); + + void writeHisto1D(std::ostream& os, const Histo1D& h); + void writeProfile1D(std::ostream& os, const Profile1D& p); + void writeScatter2D(std::ostream& os, const Scatter2D& s); + + + private: + + /// Private since it's a singleton. + WriterAIDA() { } + + }; + + +} + +#endif
More information about the Rivet-svn mailing list |