[yoda-svn] r506 - in trunk: . include/YODA pyext/yoda/include src

blackhole at projects.hepforge.org blackhole at projects.hepforge.org
Thu Jul 19 09:29:24 BST 2012


Author: buckley
Date: Thu Jul 19 09:29:24 2012
New Revision: 506

Log:
Adding stdErr for Histo2D + Python mapping, and more Cython improvements.

Modified:
   trunk/ChangeLog
   trunk/include/YODA/Histo2D.h
   trunk/include/YODA/Profile2D.h
   trunk/pyext/yoda/include/30-Scatter2D.pyx
   trunk/pyext/yoda/include/40-Histo2D.pyx
   trunk/src/Histo1D.cc
   trunk/src/Histo2D.cc

Modified: trunk/ChangeLog
==============================================================================
--- trunk/ChangeLog	Thu Jul 19 08:39:29 2012	(r505)
+++ trunk/ChangeLog	Thu Jul 19 09:29:24 2012	(r506)
@@ -1,5 +1,7 @@
 2012-07-19  Andy Buckley  <andy.buckley at cern.ch>
 
+	* Adding stdErr for Histo2D + Python mapping, and more Cython improvements.
+
 	* Adding path/title-only AO constructors and making nice Python constructor for Histo2D.
 
 	* Cython mapping improvements & additions for Point3D + Scatter3D.

Modified: trunk/include/YODA/Histo2D.h
==============================================================================
--- trunk/include/YODA/Histo2D.h	Thu Jul 19 08:39:29 2012	(r505)
+++ trunk/include/YODA/Histo2D.h	Thu Jul 19 09:29:24 2012	(r506)
@@ -340,6 +340,12 @@
       return std::sqrt(yVariance(includeoverflows));
     }
 
+    /// Get the standard error in x
+    double xStdErr(bool includeoverflows=true) const;
+
+    /// Get the standard error in y
+    double yStdErr(bool includeoverflows=true) const;
+
     //@}
 
 

Modified: trunk/include/YODA/Profile2D.h
==============================================================================
--- trunk/include/YODA/Profile2D.h	Thu Jul 19 08:39:29 2012	(r505)
+++ trunk/include/YODA/Profile2D.h	Thu Jul 19 09:29:24 2012	(r506)
@@ -42,6 +42,7 @@
         _axis()
     { }
 
+
     /// Constructor giving range and number of bins
     Profile2D(size_t nbinsX, double lowerX, double upperX,
               size_t nbinsY, double lowerY, double upperY,
@@ -50,6 +51,7 @@
         _axis(nbinsX, std::make_pair(lowerX, upperX), nbinsY, std::make_pair(lowerY, upperY))
     { }
 
+
     /// Constructor giving explicit bin edges in the direction of X and Y
     Profile2D(const std::vector<double>& xedges, const std::vector<double>& yedges,
               const std::string& path="", const std::string& title="")
@@ -57,6 +59,7 @@
         _axis(xedges, yedges)
     { }
 
+
     /// A copy constructor with optional new path
     Profile2D(const Profile2D& p, const std::string& path="");
 

Modified: trunk/pyext/yoda/include/30-Scatter2D.pyx
==============================================================================
--- trunk/pyext/yoda/include/30-Scatter2D.pyx	Thu Jul 19 08:39:29 2012	(r505)
+++ trunk/pyext/yoda/include/30-Scatter2D.pyx	Thu Jul 19 09:29:24 2012	(r506)
@@ -7,8 +7,9 @@
 
         size_t numPoints()
         vector[cPoint2D] points()
-        cPoint2D& point(size_t i)
 
+        cPoint2D& point(size_t i)
+        void erasePoint(size_t i)
 
 
 cdef class Scatter2D(AnalysisObject):
@@ -80,6 +81,7 @@
 
     @property
     def numPoints(self):
+        "The number of points in this scatter"
         return self.ptr().numPoints()
 
     cdef cScatter2D * ptr(self):
@@ -93,20 +95,10 @@
 
     @property
     def points(self):
+        "Access the points"
         cdef size_t i
         cdef Point2D pt
-        if self._points:
-            return self._points
-        else:
-            out = []
-
-            for i in range(self.ptr().numPoints()):
-                pt = Point2D_fromptr(& self.ptr().point(i))
-                out.append(pt)
-
-            out = tuple(out)
-            self._points = out
-            return out
+        return tuple(Point2D_fromptr(& self.ptr().point(i)) for i in xrange(self.ptr().numPoints()))
 
     def __repr__(self):
         return '<Scatter2D>'

Modified: trunk/pyext/yoda/include/40-Histo2D.pyx
==============================================================================
--- trunk/pyext/yoda/include/40-Histo2D.pyx	Thu Jul 19 08:39:29 2012	(r505)
+++ trunk/pyext/yoda/include/40-Histo2D.pyx	Thu Jul 19 09:29:24 2012	(r506)
@@ -34,7 +34,8 @@
         vector[cHistoBin2D]& bins()
         cHistoBin2D& binByCoord(double x, double y)
 
-        void eraseBin(size_t index)
+        cHistoBin2D& bin(size_t i)
+        void eraseBin(size_t i)
 
         # Statistical functions
         double integral(bool includeoverflows)
@@ -50,6 +51,9 @@
         double xStdDev(bool includeoverflows)
         double yStdDev(bool includeoverflows)
 
+        double xStdErr(bool includeoverflows)
+        double yStdErr(bool includeoverflows)
+
 
 cdef class Histo2D(AnalysisObject):
     """
@@ -126,16 +130,17 @@
 
 
     def fill(self, double x, double y, double weight=1.0):
+        "Fill the bin at (x, y) with the given weight"
         self.ptr().fill(x, y, weight)
 
 
     def reset(self):
-        """Reset the histogram but leave the bin structure"""
+        """Reset the histogram counters but leave the bin structure"""
         self.ptr().reset()
 
 
     def scaleW(self, double factor):
-        """Scale the histogram and its statistics by given factor"""
+        """Scale the histogram and its statistics by the given factor"""
         self.ptr().scaleW(factor)
 
 
@@ -149,48 +154,53 @@
 
     @property
     def bins(self):
-        cdef size_t numbins = self.ptr().numBins()
+        "Access the bins"
         cdef size_t i
-
-        if self._bins is None:
-            self._bins = tuple([HistoBin2D_fromptr(& self.ptr().bins().at(i))
-                          for i in xrange(numbins)])
-
-        return self._bins
-
+        return tuple(HistoBin2D_fromptr(&self.ptr().bin(i)) for i in xrange(self.ptr().numBins()))
 
     @property
     def lowEdgeX(self):
+        "The lower bound of the histogram bin range in x"
         return self.ptr().lowEdgeX()
 
 
     @property
     def lowEdgeY(self):
+        "The lower bound of the histogram bin range in y"
         return self.ptr().lowEdgeY()
 
 
     @property
     def highEdgeX(self):
+        "The upper bound of the histogram bin range in x"
         return self.ptr().highEdgeX()
 
 
     @property
     def highEdgeY(self):
+        "The upper bound of the histogram bin range in y"
         return self.ptr().highEdgeY()
 
 
     @property
     def totalDbn(self):
         """
-        h.totalDbn -> Distribution2D
+        h.totalDbn -> Dbn2D
 
-        Return the Distribution2D object representing the total distribution.
+        Return the Dbn2D object representing the total distribution.
 
         """
         return Dbn2D_fromptr(&self.ptr().totalDbn())
 
 
     def outflow(self, ix, iy):
+        """
+        h.outflow(ix, iy) -> Dbn2D
+
+        Return the Dbn2D object representing the outflow in the (ix,iy)
+        direction, where ix, iy = {-1, 0, 1}.
+        """
+
         return Dbn2D_fromptr(&self.ptr().outflow(ix, iy))
 
 
@@ -203,32 +213,81 @@
 
 
     def integral(self, bool overflows=True):
+        """
+        h.integral([bool overflows=True] -> float
+
+        Get the integral of the histo, with an optional bool argument to decide
+        whether the bin-range overflows are to be included. Effectively a
+        synonym for sumW.
+        """
         return self.ptr().integral(overflows)
 
 
     def sumW(self, bool overflows=True):
+        """
+        h.sumW([bool overflows=True] -> float
+
+        Get the weight integral of the histo, with an optional bool argument to
+        decide whether the bin-range overflows are to be included.
+        """
         return self.ptr().sumW(overflows)
 
 
     def sumW2(self, bool overflows=True):
+        """
+        h.sumW2([bool overflows=True] -> float
+
+        Get the weight**2 integral of the histo, with an optional bool argument
+        to decide whether the bin-range overflows are to be included.
+        """
         return self.ptr().sumW2(overflows)
 
 
     def mean(self, bool overflows=True):
+        """
+        h.mean([bool overflows=True] -> (float, float)
+
+        Get the mean (x,y) point for this histo, with an optional bool argument
+        to decide whether the bin-range overflows are to be included.
+        """
         cdef cHisto2D *s = self.ptr()
         return (s.xMean(overflows), s.yMean(overflows))
 
 
     def variance(self, bool overflows=True):
+        """
+        h.variance([bool overflows=True] -> (float, float)
+
+        Get the (x,y) variances for this histo, with an optional bool argument
+        to decide whether the bin-range overflows are to be included.
+        """
         cdef cHisto2D *s = self.ptr()
         return (s.xVariance(overflows), s.yVariance(overflows))
 
 
     def stdDev(self, bool overflows=True):
+        """
+        h.stdDev([bool overflows=True] -> (float, float)
+
+        Get the (x,y) standard deviations for this histo, with an optional bool
+        argument to decide whether the bin-range overflows are to be included.
+        """
         cdef cHisto2D *s = self.ptr()
         return (s.xStdDev(overflows), s.yStdDev(overflows))
 
 
+    def stdErr(self, bool overflows=True):
+        """
+        h.stdErr([bool overflows=True] -> (float, float)
+
+        Get the (x,y) standard errors on the mean for this histo, with an
+        optional bool argument to decide whether the bin-range overflows are to
+        be included.
+        """
+        cdef cHisto2D *s = self.ptr()
+        return (s.xStdErr(overflows), s.yStdErr(overflows))
+
+
 
     # def __add__(Histo2D a, Histo2D b):
     #     cdef cHisto2D *res

Modified: trunk/src/Histo1D.cc
==============================================================================
--- trunk/src/Histo1D.cc	Thu Jul 19 08:39:29 2012	(r505)
+++ trunk/src/Histo1D.cc	Thu Jul 19 09:29:24 2012	(r506)
@@ -120,7 +120,6 @@
       bins.push_back(HistoBin1D(b.xMin(), b.xMax()));
     }
     _axis = Histo1DAxis(bins);
-
   }
 
 

Modified: trunk/src/Histo2D.cc
==============================================================================
--- trunk/src/Histo2D.cc	Thu Jul 19 08:39:29 2012	(r505)
+++ trunk/src/Histo2D.cc	Thu Jul 19 09:29:24 2012	(r506)
@@ -11,13 +11,6 @@
 namespace YODA {
 
 
-  /// @todo Move to header?
-  Histo2D::Histo2D(const Histo2D& h, const std::string& path)
-    : AnalysisObject("Histo2D", (path.size() == 0) ? h.path() : path, h, h.title()),
-      _axis(h._axis)
-  { }
-
-
   void Histo2D::fill(double x, double y, double weight) {
     // Fill the overall distribution
     _axis.totalDbn().fill(x, y, weight);
@@ -94,6 +87,57 @@
   }
 
 
+  double Histo2D::xStdErr(bool includeoverflows) const {
+    if (includeoverflows) return _axis.totalDbn().xStdErr();
+    const double effNumEntries = sumW(false)*sumW(false)/sumW2(false);
+    return std::sqrt(xVariance(false) / effNumEntries);
+  }
+
+
+  double Histo2D::yStdErr(bool includeoverflows) const {
+    if (includeoverflows) return _axis.totalDbn().yStdErr();
+    const double effNumEntries = sumW(false)*sumW(false)/sumW2(false);
+    return std::sqrt(yVariance(false) / effNumEntries);
+  }
+
+
+  /////////////////////////////////////
+
+
+  /// Copy constructor with optional new path
+  Histo2D::Histo2D(const Histo2D& h, const std::string& path)
+    : AnalysisObject("Histo2D", (path.size() == 0) ? h.path() : path, h, h.title()),
+      _axis(h._axis)
+  { }
+
+
+  // /// Constructor from a Scatter3D's binning, with optional new path
+  // Histo2D::Histo2D(const Scatter3D& s, const std::string& path)
+  //   : AnalysisObject("Histo2D", (path.size() == 0) ? s.path() : path, s, s.title())
+  // {
+  //   std::vector<HistoBin2D> bins;
+  //   foreach (const Scatter3D::Point& p, s.points()) {
+  //     bins.push_back(HistoBin2D(p.xMin(), p.xMax(), p.yMin(), p.yMax()));
+  //   }
+  //   _axis = Histo2DAxis(bins);
+  // }
+
+
+  // /// Constructor from a Profile2D's binning, with optional new path
+  // Histo2D::Histo2D(const Profile2D& p, const std::string& path)
+  //   : AnalysisObject("Histo2D", (path.size() == 0) ? p.path() : path, p, p.title())
+  // {
+  //   std::vector<HistoBin2D> bins;
+  //   foreach (const ProfileBin2D& b, p.bins()) {
+  //     bins.push_back(HistoBin2D(b.xMin(), b.xMax(), b.yMin(), b.yMax()));
+  //   }
+  //   _axis = Histo2DAxis(bins);
+  // }
+
+
+  ////////////////////////////////////
+
+
   // Histo1D Histo2D::cutterX(double atY, const std::string& path, const std::string& title) {
   //   if (!_axis.isGrid()) throw GridError("Attempt to cut a Histo2D that is not a grid!");
 


More information about the yoda-svn mailing list