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

blackhole at projects.hepforge.org blackhole at projects.hepforge.org
Fri Jul 20 00:22:40 BST 2012


Author: buckley
Date: Fri Jul 20 00:22:40 2012
New Revision: 509

Log:
Bin, Dbn, and Point improvements

Modified:
   trunk/TODO
   trunk/include/YODA/ProfileBin1D.h
   trunk/pyext/yoda/Makefile.am
   trunk/pyext/yoda/include/20-Dbn1D.pyx
   trunk/pyext/yoda/include/20-Dbn2D.pyx
   trunk/pyext/yoda/include/20-Point2D.pyx
   trunk/pyext/yoda/include/20-Point3D.pyx
   trunk/pyext/yoda/include/30-HistoBin1D.pyx
   trunk/pyext/yoda/include/30-ProfileBin1D.pyx
   trunk/pyext/yoda/include/40-Histo2D.pyx

Modified: trunk/TODO
==============================================================================
--- trunk/TODO	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/TODO	Fri Jul 20 00:22:40 2012	(r509)
@@ -10,34 +10,44 @@
    Ignore anything after "#" on data lines -- use this to write convenience
    height & error info for each bin since not obvious from sumWX2 etc.
 
-* Add nice constructor behaviour and docstrings to the Scatter2D Python interface. (AB)
-
 * Remove nasty Cython shims (DM)
-   Does inheritance work automatically in Cython now?
+   Does inheritance work automatically in Cython now? Add operator support
+   everywhere it's needed.
 
-* Complete basic Histo2D and Profile2D functionality. (AB)
-   Axis2D is working
+* Add Axis2D -> Histo2D/Profile2D bin adding and erasing. (AB)
 
 * Make Python interface test scripts (DM)
 
-* Add copy assignment to Point/Scatter3D (AB)
+* Add copy assignment to both C++ and Cython (AB)
 
-* Improve tests Makefile setup to work out the path to the Python build dir. (AB)
+* Docstrings for Points, Dbns and Bins (AB)
+
+* Add stdErr to HistoBinXD (AB)
+
+* Add Dbn3D, ProfileBin2D, Profile2D and Scatter3D in Cython (AB)
+
+* Test Histo2D and Scatter2D from Python (AB)
 
+* Sort out _dealloc treatment (AB, DM)
+
+* Adding 2D operator support and bin-adding/erasing
 
 
 
 NEXT
 
-* Add "official" counter and bar-chart types (AB)
-   Need better names!
+* Auto-determine input and output formats (= readers/writers) from file extn (AB)
+
+* Improve tests Makefile setup to work out the path to the Python build dir. (AB)
 
-* Add a merge() method in Bin2D. Add a constructor that takes Dbns.
+* Add a merge() method in Bin2D. Add a constructor that takes Dbns (AB)
+   Use merge() to implement merging/rebinning in Axis2D -> Histo2D & Profile2D.
 
-* Rebinning: global rebinning of Axis2D -> Histo2D by integer factor(s) --
-  different factors in x and y directions.
+* Detecting perfect/imperfect 2D grids (AB)
 
-* Automatically determine input and output formats (= readers/writers) from file extn.
+* 2D bin merging and rebinning (AB)
+   Only rebin perfect grids? Global rebinning of Axis2D -> Histo2D by generally
+   different integer factors in x and y directions.
 
 * Test negative- and mixed-weighted stat calculations, and scaling.
 
@@ -48,12 +58,16 @@
 * Add Scatter1D/Point1D (AB)
 
 * Transform 1D differential to integral histos and vice versa.
-  Bins have to be contiguous. (AB)
+   Bins have to be contiguous. (AB)
 
 * Add a Counter type (mostly a UI/persistency wrapper on Dbn1D) (AB)
+   "Binning"/"axis" option on arbitrary types, particularly strings? ->
+   generalised bar charts.
+
+* "BinnedValues" type: use Axis behaviour to look up fixed values.
 
-* Multiple errors on Scatter2D -- via a vector of Error2D? How to implement
-  flexible error combination? Error correlations?
+* Multiple errors on Scatters -- via a vector of Errors?
+   Flexible error combination? Error correlations? Max/min?
 
 * WriterFlat and ReaderFlat, for Scatter2D representations only. (HH)
 

Modified: trunk/include/YODA/ProfileBin1D.h
==============================================================================
--- trunk/include/YODA/ProfileBin1D.h	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/include/YODA/ProfileBin1D.h	Fri Jul 20 00:22:40 2012	(r509)
@@ -100,6 +100,10 @@
       return _dbn.yStdErr();
     }
 
+    double rms() const {
+      return _dbn.yRMS();
+    }
+
     //@}
 
 

Modified: trunk/pyext/yoda/Makefile.am
==============================================================================
--- trunk/pyext/yoda/Makefile.am	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/pyext/yoda/Makefile.am	Fri Jul 20 00:22:40 2012	(r509)
@@ -5,15 +5,18 @@
 	$(PYTHON) -m cython --cplus yoda.pyx
 
 yoda.pyx: include/00-imports.pyx include/10-AnalysisObject.pyx \
-	include/20-Dbn1D.pyx include/20-Dbn2D.pyx include/20-Point2D.pyx include/20-Point3D.pyx \
-	include/30-HistoBin1D.pyx include/30-ProfileBin1D.pyx include/30-HistoBin2D.pyx \
-	include/30-Reader.pyx \
+	include/20-Dbn1D.pyx include/20-Dbn2D.pyx \
+	include/20-Point2D.pyx include/20-Point3D.pyx \
+	include/30-HistoBin1D.pyx include/30-ProfileBin1D.pyx \
+	include/30-HistoBin2D.pyx \
+	include/30-Reader.pyx include/30-Writer.pyx \
 	include/30-Scatter2D.pyx \
 	include/40-Histo1D.pyx include/40-Profile1D.pyx \
 	include/40-Histo2D.pyx \
 	include/40-WriterYODA.pyx include/40-WriterAIDA.pyx \
 	include/99-ReaderYODA.pyx include/99-ReaderAIDA.pyx
 	cat $+ > yoda.pyx
+#include/30-ProfileBin2D.pyx
 #include/30-Scatter3D.pyx
 #include/40-Profile2D.pyx
 

Modified: trunk/pyext/yoda/include/20-Dbn1D.pyx
==============================================================================
--- trunk/pyext/yoda/include/20-Dbn1D.pyx	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/pyext/yoda/include/20-Dbn1D.pyx	Fri Jul 20 00:22:40 2012	(r509)
@@ -26,9 +26,17 @@
 
 
 cdef class Dbn1D:
+    """
+    A 1D distribution 'counter', used and exposed by 1D histograms and their bins.
+
+    TODO: Allow no-arg construction?
+    TODO: map operator+ and operator-, both internal and external
+    """
+
     cdef cDbn1D *thisptr
     cdef bool _dealloc
 
+
     def __cinit__(self):
         self._dealloc = False
 
@@ -59,67 +67,101 @@
 
 
     def fill(self, double x, double weight=1.0):
+        "Fill the distribution with the given weight at given x."
         self.ptr().fill(x, weight)
 
     def reset(self):
+        "Reset the distribution counters to the unfilled state."
         self.ptr().reset()
 
     def scaleW(self, scalefactor):
+        "Scale the fill weights by the given factor"
         self.ptr().scaleW(scalefactor)
 
     def scaleX(self, factor):
+        "Scale the x variable by the given factor"
         self.ptr().scaleX(factor)
 
+    @property
     def mean(self):
+        "Get the weighted mean x (synonym for xMean)"
         return self.ptr().mean()
 
+    @property
     def xMean(self):
+        "Get the weighted mean x"
         return self.ptr().xMean()
 
+    @property
     def variance(self):
+        "Get the weighted variance of x (synonym for xVariance)"
         return self.ptr().variance()
 
+    @property
     def xVariance(self):
+        "Get the weighted variance of x"
         return self.ptr().xVariance()
 
+    @property
     def stdDev(self):
+        "Get the weighted standard deviation of x (synonym for xStdDev)"
         return self.ptr().stdDev()
 
+    @property
     def xStdDev(self):
+        "Get the weighted standard deviation of x"
         return self.ptr().xStdDev()
 
+    @property
     def stdErr(self):
+        "Get the weighted standard error on <x> (synonym for xStdErr)"
         return self.ptr().stdDev()
 
+    @property
     def xStdErr(self):
+        "Get the weighted standard error on <x>"
         return self.ptr().xStdDev()
 
+    @property
     def rms(self):
+        "Get the weighted RMS of x (synonym for xRMS)"
         return self.ptr().rms()
 
+    @property
     def xRMS(self):
+        "Get the weighted RMS of x"
         return self.ptr().xRMS()
 
+    @property
     def numEntries(self):
+        "Get the number of entries"
         return self.ptr().numEntries()
 
+    @property
     def effNumEntries(self):
+        "Get the effective number of entries (for weighted events)"
         return self.ptr().effNumEntries()
 
+    @property
     def sumW(self):
+        "Get the sum of weights"
         return self.ptr().sumW()
 
+    @property
     def sumW2(self):
+        "Get the sum of squared-weights"
         return self.ptr().sumW2()
 
+    @property
     def sumWX(self):
+        "Get the sum of weighted xs"
         return self.ptr().sumWX()
 
+    @property
     def sumWX2(self):
+        "Get the sum of weighted squared-xs"
         return self.ptr().sumWX2()
 
-    # TODO: map operator+ and operator-, both internal and external
-
 
 
 cdef Dbn1D Dbn1D_fromptr(cDbn1D *ptr, dealloc=False):

Modified: trunk/pyext/yoda/include/20-Dbn2D.pyx
==============================================================================
--- trunk/pyext/yoda/include/20-Dbn2D.pyx	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/pyext/yoda/include/20-Dbn2D.pyx	Fri Jul 20 00:22:40 2012	(r509)
@@ -31,7 +31,14 @@
 
 
 cdef class Dbn2D:
-    cdef cDbn2D *thisptr
+    """
+    A 2D distribution 'counter', used and exposed by 1D histograms and their bins.
+
+    TODO: Allow no-arg construction?
+    TODO: map operator+ and operator-, both internal and external
+    """
+
+    cdef cDbn2D* thisptr
     cdef bool _dealloc
 
     def __cinit__(self):
@@ -64,79 +71,120 @@
 
 
     def fill(self, double x, double y, double weight=1.0):
+        "Fill the distribution with the given weight at given x and y."
         self.ptr().fill(x, y, weight)
 
     def reset(self):
+        "Reset the distribution counters to the unfilled state."
         self.ptr().reset()
 
     def scaleW(self, scalefactor):
+        "Scale the fill weights by the given factor"
         self.ptr().scaleW(scalefactor)
 
     def scaleX(self, factor):
+        "Scale the x variable by the given factor"
         self.ptr().scaleX(factor)
 
     def scaleY(self, factor):
+        "Scale the y variable by the given factor"
         self.ptr().scaleY(factor)
 
+    @property
     def xMean(self):
+        "Get the weighted mean x"
         return self.ptr().xMean()
 
+    @property
     def yMean(self):
+        "Get the weighted mean y"
         return self.ptr().yMean()
 
+    @property
     def xVariance(self):
+        "Get the weighted variance of x"
         return self.ptr().xVariance()
 
+    @property
     def yVariance(self):
+        "Get the weighted variance of y"
         return self.ptr().yVariance()
 
+    @property
     def xStdDev(self):
+        "Get the weighted standard deviation of x"
         return self.ptr().xStdDev()
 
+    @property
     def yStdDev(self):
+        "Get the weighted standard deviation of y"
         return self.ptr().yStdDev()
 
+    @property
     def xStdErr(self):
+        "Get the weighted standard error on <x>"
         return self.ptr().xStdDev()
 
+    @property
     def yStdErr(self):
+        "Get the weighted standard error on <y>"
         return self.ptr().yStdDev()
 
+    @property
     def xRMS(self):
+        "Get the weighted RMS of x"
         return self.ptr().xRMS()
 
+    @property
     def yRMS(self):
+        "Get the weighted RMS of y"
         return self.ptr().yRMS()
 
+    @property
     def numEntries(self):
+        "Get the number of entries"
         return self.ptr().numEntries()
 
+    @property
     def effNumEntries(self):
+        "Get the effective number of entries (for weighted events)"
         return self.ptr().effNumEntries()
 
+    @property
     def sumW(self):
+        "Get the sum of weights"
         return self.ptr().sumW()
 
+    @property
     def sumW2(self):
+        "Get the sum of squared-weights"
         return self.ptr().sumW2()
 
+    @property
     def sumWX(self):
+        "Get the sum of weighted xs"
         return self.ptr().sumWX()
 
+    @property
     def sumWX2(self):
+        "Get the sum of weighted squared-xs"
         return self.ptr().sumWX2()
 
+    @property
     def sumWY(self):
+        "Get the sum of weighted ys"
         return self.ptr().sumWY()
 
+    @property
     def sumWY2(self):
+        "Get the sum of weighted squared-ys"
         return self.ptr().sumWY2()
 
+    @property
     def sumWXY(self):
+        "Get the sum of weighted (x*y)s"
         return self.ptr().sumWXY()
 
-    # TODO: map operator+ and operator-, both internal and external
-
 
 
 cdef Dbn2D Dbn2D_fromptr(cDbn2D *ptr, dealloc=False):

Modified: trunk/pyext/yoda/include/20-Point2D.pyx
==============================================================================
--- trunk/pyext/yoda/include/20-Point2D.pyx	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/pyext/yoda/include/20-Point2D.pyx	Fri Jul 20 00:22:40 2012	(r509)
@@ -20,8 +20,18 @@
 
 
 cdef class Point2D:
-    cdef cPoint2D* thisptr
+    """
+    A 2D point, as contained in Scatter2D.
+
+    Several constructor forms are supported:
 
+    * Point2D() - default point construction at (0,0)
+    * Point2D(x, y) - point construction at (x,y)
+    * Point2D(x, y, ex, ey) - point construction at (x,y) with errors. ex and ey can be pairs.
+    * Point2D(x, y, ex-, ex+, ey-, ey+) - point construction at (x,y) with asymm errors.
+    """
+
+    cdef cPoint2D* thisptr
     cdef bool _dealloc
 
     cdef cPoint2D* ptr(self):

Modified: trunk/pyext/yoda/include/20-Point3D.pyx
==============================================================================
--- trunk/pyext/yoda/include/20-Point3D.pyx	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/pyext/yoda/include/20-Point3D.pyx	Fri Jul 20 00:22:40 2012	(r509)
@@ -29,10 +29,21 @@
 
 
 cdef class Point3D:
-    cdef cPoint3D* thisptr
+    """
+    A 3D point, as contained in Scatter3D.
+
+    Several constructor forms are supported:
+
+    * Point3D() - default point construction at (0,0,0)
+    * Point3D(x, y, z) - point construction at (x,y,z)
+    * Point3D(x, y, z, ex, ey, ez) - point construction at (x,y,z) with errors. ex and ey can be pairs.
+    * Point3D(x, y, z, ex-, ex+, ey-, ey+, ez-, ez+) - point construction at (x,y,z) with asymm errors.
+    """
 
+    cdef cPoint3D* thisptr
     cdef bool _dealloc
 
+
     cdef cPoint3D* ptr(self):
         return self.thisptr
 
@@ -44,6 +55,7 @@
         self._dealloc = dealloc
         return self
 
+
     def __cinit__(self):
         self._dealloc = False
 
@@ -52,7 +64,7 @@
         self._dealloc = True
 
         if len(args) == 0:
-            self.pos = 0, 0
+            self.pos = 0, 0, 0
         elif len(args) == 3:
             self.pos = args
         elif len(args) == 6:

Modified: trunk/pyext/yoda/include/30-HistoBin1D.pyx
==============================================================================
--- trunk/pyext/yoda/include/30-HistoBin1D.pyx	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/pyext/yoda/include/30-HistoBin1D.pyx	Fri Jul 20 00:22:40 2012	(r509)
@@ -1,14 +1,15 @@
 cdef extern from "YODA/HistoBin1D.h" namespace "YODA":
 
     cdef cppclass cHistoBin1D "YODA::HistoBin1D":
-        cHistoBin1D (cHistoBin1D &h)
-        cHistoBin1D (double, double)
+        cHistoBin1D(cHistoBin1D &h)
+        cHistoBin1D(double, double)
         double area()
         double height()
         double areaErr()
         double heightErr()
         void reset()
 
+        # TODO
         # These are inherited methods from Bin1D... I can't seem to find a nice
         # way to make Cython acknowledge these (it seems to be a typedef parsing
         # issue rather than a technical issue).
@@ -25,6 +26,7 @@
         double xVariance()
         double xStdDev()
         double xStdErr()
+        double xRMS()
         double numEntries()
         double effNumEntries()
         double sumW()
@@ -33,16 +35,25 @@
         double sumWX2()
 
 
-#Ugly hack using shim header for Cython 0.13
+# TODO: Ugly hack using shim header for Cython 0.13
 cdef extern from "shims.h":
     cHistoBin1D add_HistoBin1D (cHistoBin1D &, cHistoBin1D &)
     cHistoBin1D subtract_HistoBin1D (cHistoBin1D &, cHistoBin1D &)
 
 
 cdef class HistoBin1D:
-    cdef cHistoBin1D *thisptr
+    """
+    A 1D histogram bin, as stored inside Histo1D.
+
+    Only one Python constructor:
+
+    * HistoBin1D(xlow, xhigh)
+    """
+
+    cdef cHistoBin1D* thisptr
     cdef bool _dealloc
 
+
     def __cinit__(self):
         self._dealloc = False
 
@@ -50,7 +61,13 @@
         if self._dealloc:
             del self.thisptr
 
-    cdef HistoBin1D setptr(self, cHistoBin1D *ptr, bool dealloc):
+
+    # TODO: Why does Cython hate this?!?
+    # def __init__(self, double xlow, double xhigh):
+    #     self.setptr(new cHistoBin1D(xlow, xhigh), dealloc=True)
+
+
+    cdef HistoBin1D setptr(self, cHistoBin1D* ptr, bool dealloc):
         if self._dealloc:
             del self.thisptr
 
@@ -61,6 +78,11 @@
     cdef cHistoBin1D* ptr(self):
         return self.thisptr
 
+
+    ##############################
+    # THIS IS ALL BIN1D STUFF: CAN WE INHERIT THE PY MAPPING?
+
+
     @property
     def lowEdge(self):
         """The lower of the two bin edges."""
@@ -68,6 +90,7 @@
 
     xMin = lowEdge
 
+
     @property
     def highEdge(self):
         """The higher of the two bin edges."""
@@ -75,6 +98,7 @@
 
     xMax = highEdge
 
+
     @property
     def width(self):
         """The width of the bin."""
@@ -90,6 +114,7 @@
         """The point half-way between the bin edges."""
         return self.ptr().midpoint()
 
+
     @property
     def xMean(self):
         """The mean of the x-values that have filled the bin."""
@@ -106,6 +131,16 @@
         return self.ptr().xStdDev()
 
     @property
+    def xStdErr(self):
+        """The standard error of the x-values that have filled the bin."""
+        return self.ptr().xStdErr()
+
+    @property
+    def xRMS(self):
+        """The RMS of the x-values that have filled the bin."""
+        return self.ptr().xRMS()
+
+    @property
     def numEntries(self):
         """The number of entries in the bin."""
         return self.ptr().numEntries()
@@ -136,6 +171,10 @@
         """Sum of the products of x-values squared and their weights."""
         return self.ptr().sumWX2()
 
+
+    ########################
+
+
     @property
     def area(self):
         """

Modified: trunk/pyext/yoda/include/30-ProfileBin1D.pyx
==============================================================================
--- trunk/pyext/yoda/include/30-ProfileBin1D.pyx	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/pyext/yoda/include/30-ProfileBin1D.pyx	Fri Jul 20 00:22:40 2012	(r509)
@@ -25,10 +25,12 @@
         double xVariance()
         double xStdDev()
         double xStdErr()
+        double xRMS()
         double mean()
         double variance()
         double stdDev()
         double stdErr()
+        double rms()
         double numEntries()
         double effNumEntries()
         double sumW()
@@ -46,7 +48,15 @@
 
 
 cdef class ProfileBin1D:
-    cdef cProfileBin1D *thisptr
+    """
+    A 1D profile histogram bin, as stored inside Histo1D.
+
+    Only one Python constructor:
+
+    * ProfileBin1D(xlow, xhigh)
+    """
+
+    cdef cProfileBin1D* thisptr
     cdef bool _dealloc
 
     def __cinit__(self):
@@ -56,7 +66,13 @@
         if self._dealloc:
             del self.thisptr
 
-    cdef ProfileBin1D setptr(self, cProfileBin1D *ptr, bool dealloc):
+
+    # TODO: Why does Cython hate this?!?
+    # def __init__(self, double xlow, double xhigh):
+    #     self.setptr(new cHistoBin1D(xlow, xhigh), dealloc=True)
+
+
+    cdef ProfileBin1D setptr(self, cProfileBin1D* ptr, bool dealloc):
         if self._dealloc:
             del self.thisptr
 
@@ -67,6 +83,10 @@
     cdef cProfileBin1D* ptr(self):
         return self.thisptr
 
+
+    ##############################
+    # THIS IS ALL BIN1D STUFF: CAN WE INHERIT THE PY MAPPING?
+
     @property
     def lowEdge(self):
         """The lower of the two bin edges."""
@@ -115,6 +135,14 @@
         return self.ptr().xStdErr()
 
     @property
+    def xRMS(self):
+        """The RMS of the x-values that have filled the bin."""
+        return self.ptr().xRMS()
+
+    ####################################
+
+
+    @property
     def mean(self):
         """The mean of the y-values that have filled the bin."""
         return self.ptr().mean()
@@ -135,6 +163,11 @@
         return self.ptr().stdErr()
 
     @property
+    def rms(self):
+        """The RMS of the y-values that have filled the bin."""
+        return self.ptr().rms()
+
+    @property
     def numEntries(self):
         """The number of entries in the bin."""
         return self.ptr().numEntries()

Modified: trunk/pyext/yoda/include/40-Histo2D.pyx
==============================================================================
--- trunk/pyext/yoda/include/40-Histo2D.pyx	Thu Jul 19 09:51:13 2012	(r508)
+++ trunk/pyext/yoda/include/40-Histo2D.pyx	Fri Jul 20 00:22:40 2012	(r509)
@@ -83,12 +83,10 @@
 
     TODO: Add constructors from Scatter and Profile
     TODO: Support adding and erasing bins
+    TODO: Support add, mul, div operators
     """
 
-    # cdef tuple _bins
-
     def __cinit__(self):
-        # self._bins = None
         self._dealloc = False
 
 


More information about the yoda-svn mailing list