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

blackhole at projects.hepforge.org blackhole at projects.hepforge.org
Thu May 3 15:52:00 BST 2012


Author: buckley
Date: Thu May  3 15:51:59 2012
New Revision: 466

Log:
Adding nice constructor behaviours to the Histo1D and Profile2D Python interfaces, and adding the mkScatter operation for Profile1D.

Modified:
   trunk/ChangeLog
   trunk/TODO
   trunk/pyext/yoda/include/30-Scatter2D.pyx
   trunk/pyext/yoda/include/40-Histo1D.pyx
   trunk/pyext/yoda/include/40-Profile1D.pyx

Modified: trunk/ChangeLog
==============================================================================
--- trunk/ChangeLog	Thu May  3 15:37:28 2012	(r465)
+++ trunk/ChangeLog	Thu May  3 15:51:59 2012	(r466)
@@ -1,6 +1,8 @@
 2012-05-03  Andy Buckley  <andy.buckley at cern.ch>
 
-	* Adding nice constructor behaviours to the Histo1D Python interface.
+	* Adding nice constructor behaviours to the Histo1D and Profile2D
+	Python interfaces, and adding the mkScatter operation for
+	Profile1D.
 
 	* Adding more default constructors for analysis objects, to allow
 	member variable and STL container use without pointers.

Modified: trunk/TODO
==============================================================================
--- trunk/TODO	Thu May  3 15:37:28 2012	(r465)
+++ trunk/TODO	Thu May  3 15:51:59 2012	(r466)
@@ -3,8 +3,6 @@
 
 NOW
 
-* Add extra constructors and path/title handling to Profile1D Python interface (AB)
-
 * Axis2D needs a complete rewrite. (AB)
   Additionally: Fix order in which points are specified in the
   Bin2D constructor. Add a merge() method in Bin2D. Add a constructor

Modified: trunk/pyext/yoda/include/30-Scatter2D.pyx
==============================================================================
--- trunk/pyext/yoda/include/30-Scatter2D.pyx	Thu May  3 15:37:28 2012	(r465)
+++ trunk/pyext/yoda/include/30-Scatter2D.pyx	Thu May  3 15:51:59 2012	(r466)
@@ -7,6 +7,8 @@
         cScatter2D (vector[cPoint2D]&, string, string)
         cScatter2D ()
 
+
+
 cdef class Scatter2D(AnalysisObject):
     cdef tuple _points
 
@@ -21,7 +23,7 @@
         for i in range(N):
             item = points[i]
             point_vector[i] = item.ptr()[0]
-        
+
         scatter = new cScatter2D(point_vector, string(path), string(title))
         self.setptr(scatter, True)
 
@@ -30,7 +32,7 @@
     @property
     def numPoints(self):
         return self.ptr().numPoints()
-    
+
     cdef cScatter2D * ptr(self):
         return <cScatter2D *> self.thisptr
 
@@ -60,7 +62,7 @@
     def __repr__(self):
         return '<Scatter2D>'
 
-        
+
 # dealloc decides whether or not the python object is responsible for freeing
 # used memory. Most times, it's not - we're just wrapping a C++ instance.
 # However, the same classes should be used for both wrapping and creating.

Modified: trunk/pyext/yoda/include/40-Histo1D.pyx
==============================================================================
--- trunk/pyext/yoda/include/40-Histo1D.pyx	Thu May  3 15:37:28 2012	(r465)
+++ trunk/pyext/yoda/include/40-Histo1D.pyx	Thu May  3 15:51:59 2012	(r466)
@@ -1,13 +1,9 @@
 cdef extern from "YODA/Histo1D.h" namespace "YODA":
-    #cHisto1D operator + (cHisto1D &, cHisto1D &)
-    #cHisto1D operator - (cHisto1D &, cHisto1D &)
-    #cScatter2D operator / (cHisto1D &, cHisto1D &)"""
 
     cdef cppclass cHisto1D "YODA::Histo1D"(cAnalysisObject):
         cHisto1D()
         cHisto1D(size_t nbins, double lower, double upper, string &path, string &title)
         cHisto1D(vector[double] &binedges, string &path, string &title)
-        cHisto1D(vector[double] &binedges)
         cHisto1D(cHisto1D &h, string &path)
         cHisto1D(cHisto1D &h)
 
@@ -40,14 +36,13 @@
         double stdDev(bool includeoverflows)
         double stdErr(bool includeoverflows)
 
-
+# TODO: Remove shims and depend on Cython > 0.13
 cdef extern from "shims.h":
     cHisto1D add_Histo1D (cHisto1D &, cHisto1D &)
     cHisto1D subtract_Histo1D (cHisto1D &, cHisto1D &)
     cScatter2D divide_Histo1D (cHisto1D &, cHisto1D &)
     cScatter2D Scatter2D_mkScatter(cHisto1D &)
 
-from cython.operator cimport dereference as deref
 
 
 cdef class Histo1D(AnalysisObject):
@@ -61,7 +56,7 @@
         * Histo1D(binedges[, path, title]) -- explicit bin edges (no bin gaps)
 
         The path and title arguments are optional, and may either be specified via the
-        positional parameters or via expliit keyword arguments, e.g. path='/foo/bar'.
+        positional parameters or via explicit keyword arguments, e.g. path='/foo/bar'.
         """
         self._dealloc = True
         cdef:

Modified: trunk/pyext/yoda/include/40-Profile1D.pyx
==============================================================================
--- trunk/pyext/yoda/include/40-Profile1D.pyx	Thu May  3 15:37:28 2012	(r465)
+++ trunk/pyext/yoda/include/40-Profile1D.pyx	Thu May  3 15:51:59 2012	(r466)
@@ -1,12 +1,9 @@
 cdef extern from "YODA/Profile1D.h" namespace "YODA":
-    #cProfile1D operator + (cProfile1D &, cProfile1D &)
-    #cProfile1D operator - (cProfile1D &, cProfile1D &)
-    #cScatter2D operator / (cProfile1D &, cProfile1D &)"""
 
     cdef cppclass cProfile1D "YODA::Profile1D"(cAnalysisObject):
+        cProfile1D()
         cProfile1D(size_t nbins, double lower, double upper, string &path, string &title)
         cProfile1D(vector[double] &binedges, string &path, string &title)
-        cProfile1D(vector[double] &binedges)
         cProfile1D(cProfile1D &h, string &path)
         cProfile1D(cProfile1D &h)
 
@@ -25,8 +22,9 @@
         cDbn2D &totalDbn()
         cDbn2D &underflow()
         cDbn2D &overflow()
-        #addBin
-        #void eraseBin(size_t index)
+        void addBin(double low, double high)
+        void addBins(vector[double] &binedges)
+        void eraseBin(size_t index)
 
         # Statistical functions
         #double integral(bool includeoverflows)
@@ -34,48 +32,92 @@
         double sumW(bool includeoverflows)
         double sumW2(bool includeoverflows)
 
-
     cProfile1D add(cProfile1D &, cProfile1D &)
     cProfile1D subtract(cProfile1D &, cProfile1D &)
     cScatter2D divide(cProfile1D &, cProfile1D &)
     #cScatter2D mkScatter(cProfile1D &)
 
-from cython.operator cimport dereference as deref
+cdef extern from "YODA/Scatter2D.h" namespace "YODA":
+    cScatter2D mkScatter(cProfile1D &)
+
 
 
 cdef class Profile1D(AnalysisObject):
+
     def __init__(self, *args, **kwargs):
+        """
+        Profile1D constructor. Several sets of arguments are permitted:
+
+        * Profile1D() -- default constructor. Not usually useful in Python, due to availability of None.
+        * Profile1D(nbins, low, high[, path, title]) -- linear binning with n bins between low-high.
+        * Profile1D(binedges[, path, title]) -- explicit bin edges (no bin gaps)
+
+        The path and title arguments are optional, and may either be specified via the
+        positional parameters or via explicit keyword arguments, e.g. path='/foo/bar'.
+        """
         self._dealloc = True
         cdef:
             size_t nbins
             double lower
             double upper
+            vector[double] binedges
             char* path = '/'
             char* title = ''
 
-        if len(args) == 3:
-            nbins, lower, upper = args[0], args[1], args[2]
-            self.setptr(
-                new cProfile1D(nbins, lower, upper, string(path), string(title))
-            )
+        ## Permit path and title specification via kwargs
+        if "path" in kwargs:
+            path = kwargs["path"]
+        if "title" in kwargs:
+            path = kwargs["title"]
+
+        ## Trigger different C++ constructors depending on Python args
+        # TODO: Map copy constructors, esp. the path-resetting one
+        if len(args) == 0:
+            self.setptr(new cProfile1D())
         else:
-            raise ValueError('Profile1D: Expected 3 arguments')
+            if type(args[0]) is list:
+                try:
+                    for i in args[0]:
+                        binedges.push_back(float(i))
+                except:
+                    raise Exception("Invalid binedges container supplied to Profile1D constructor")
+                if len(args) >= 2:
+                    assert "path" not in kwargs
+                    path = args[1]
+                if len(args) == 3:
+                    assert "title" not in kwargs
+                    path = args[2]
+                if len(args) > 3:
+                    raise ValueError("Too many arguments supplied to Profile1D constructor with a binedge list first arg")
+                self.setptr(new cProfile1D(binedges, string(path), string(title)))
+            else:
+                assert len(args) >= 3
+                nbins, lower, upper = args[0:3]
+                if len(args) >= 4:
+                    assert "path" not in kwargs
+                    path = args[3]
+                if len(args) == 5:
+                    assert "title" not in kwargs
+                    path = args[4]
+                if len(args) > 5:
+                    raise ValueError("Too many arguments supplied to Profile1D constructor")
+                self.setptr(new cProfile1D(nbins, lower, upper, string(path), string(title)))
 
 
     cdef cProfile1D* ptr(self):
         return <cProfile1D *> self.thisptr
 
 
-    # def asScatter(self):
-    #     """
-    #     h.asScatter() -> Scatter2D
-
-    #     Return a 2D scatter data object from the profile's bins and heights
-
-    #     """
-    #     cdef cScatter2D *s = new cScatter2D()
-    #     s[0] = Scatter2D_mkScatter(self.ptr()[0])
-    #     return Scatter2D_fromptr(s, True)
+    def asScatter(self):
+        """
+        h.asScatter() -> Scatter2D
+
+        Return a 2D scatter data object from the profile's bins and heights
+
+        """
+        cdef cScatter2D *s = new cScatter2D()
+        s[0] = mkScatter(self.ptr()[0])
+        return Scatter2D_fromptr(s, True)
 
 
     def fill(self, double x, double weight=1.0):


More information about the yoda-svn mailing list