[Rivet-svn] r3233 - branches/2011-07-aida2yoda/include/YODA

blackhole at projects.hepforge.org blackhole at projects.hepforge.org
Thu 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