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

blackhole at projects.hepforge.org blackhole at projects.hepforge.org
Mon May 13 20:21:43 BST 2013


Author: buckley
Date: Mon May 13 20:21:43 2013
New Revision: 598

Log:
Adding combined value+error setX/Y functions on Point2D. Adding HistoBin1D::relErr()

Modified:
   trunk/ChangeLog
   trunk/include/YODA/HistoBin1D.h
   trunk/include/YODA/HistoBin2D.h
   trunk/include/YODA/Point2D.h
   trunk/include/YODA/ProfileBin1D.h
   trunk/include/YODA/ProfileBin2D.h
   trunk/pyext/yoda/include/Histo1D.pyx
   trunk/pyext/yoda/include/IO.pyx
   trunk/pyext/yoda/util.pyx

Modified: trunk/ChangeLog
==============================================================================
--- trunk/ChangeLog	Tue May  7 14:58:17 2013	(r597)
+++ trunk/ChangeLog	Mon May 13 20:21:43 2013	(r598)
@@ -1,3 +1,9 @@
+2013-05-13  Andy Buckley  <andy.buckley at cern.ch>
+
+	* Adding combined value+error setX/Y functions on Point2D.
+
+	* Adding HistoBin1D::relErr()
+
 2013-04-23  Andy Buckley  <andy.buckley at cern.ch>
 
 	* Adding Python output handling for single AOs and to be able to

Modified: trunk/include/YODA/HistoBin1D.h
==============================================================================
--- trunk/include/YODA/HistoBin1D.h	Tue May  7 14:58:17 2013	(r597)
+++ trunk/include/YODA/HistoBin1D.h	Mon May 13 20:21:43 2013	(r598)
@@ -115,6 +115,11 @@
       return areaErr() / width();
     }
 
+    /// The relative size of the error (same for either area or height errors)
+    double relErr() const {
+      return sqrt(sumW2()) / sumW();
+    }
+
     //@}
 
 

Modified: trunk/include/YODA/HistoBin2D.h
==============================================================================
--- trunk/include/YODA/HistoBin2D.h	Tue May  7 14:58:17 2013	(r597)
+++ trunk/include/YODA/HistoBin2D.h	Mon May 13 20:21:43 2013	(r598)
@@ -105,6 +105,12 @@
       return volumeErr()/(widthX()*widthY());
     }
 
+    /// @todo Add relative error
+    // /// The relative size of the error (same for either area or height errors)
+    // double relErr() const {
+    //   return sqrt(sumW2()) / sumW();
+    // }
+
     //@}
 
 

Modified: trunk/include/YODA/Point2D.h
==============================================================================
--- trunk/include/YODA/Point2D.h	Tue May  7 14:58:17 2013	(r597)
+++ trunk/include/YODA/Point2D.h	Mon May 13 20:21:43 2013	(r598)
@@ -265,7 +265,48 @@
 
     /// @todo Support multiple weights (then need to discard setYMin/Max?)
 
-    /// @todo Add setY(y, err) combinations for user convenience
+
+    /// @name Combined x/y value and error setters
+    //@{
+
+    /// Set x value and symmetric error
+    void setX(double x, double ex) {
+      setX(x);
+      setXErr(ex);
+    }
+
+    /// Set x value and asymmetric error
+    void setX(double x, double exminus, double explus) {
+      setX(x);
+      setXErr(exminus, explus);
+    }
+
+    /// Set x value and asymmetric error
+    void setX(double x, std::pair<double,double> ex) {
+      setX(x);
+      setXErr(ex);
+    }
+
+
+    /// Set y value and symmetric error
+    void setY(double y, double ey) {
+      setY(y);
+      setYErr(ey);
+    }
+
+    /// Set y value and asymmetric error
+    void setY(double y, double eyminus, double eyplus) {
+      setY(y);
+      setYErr(eyminus, eyplus);
+    }
+
+    /// Set y value and asymmetric error
+    void setY(double y, std::pair<double,double> ey) {
+      setY(y);
+      setYErr(ey);
+    }
+
+    //@}
 
 
     // @name Manipulations

Modified: trunk/include/YODA/ProfileBin1D.h
==============================================================================
--- trunk/include/YODA/ProfileBin1D.h	Tue May  7 14:58:17 2013	(r597)
+++ trunk/include/YODA/ProfileBin1D.h	Mon May 13 20:21:43 2013	(r598)
@@ -100,6 +100,12 @@
       return _dbn.yStdErr();
     }
 
+    /// @todo Add relative error
+    // /// The relative size of the error (same for either area or height errors)
+    // double relErr() const {
+    //   return sqrt(sumW2()) / sumW();
+    // }
+
     double rms() const {
       return _dbn.yRMS();
     }

Modified: trunk/include/YODA/ProfileBin2D.h
==============================================================================
--- trunk/include/YODA/ProfileBin2D.h	Tue May  7 14:58:17 2013	(r597)
+++ trunk/include/YODA/ProfileBin2D.h	Mon May 13 20:21:43 2013	(r598)
@@ -106,6 +106,12 @@
       return _dbn.zStdErr();
     }
 
+    /// @todo Add relative error
+    // /// The relative size of the error (same for either area or height errors)
+    // double relErr() const {
+    //   return sqrt(sumW2()) / sumW();
+    // }
+
     double rms() const {
       return _dbn.zRMS();
     }

Modified: trunk/pyext/yoda/include/Histo1D.pyx
==============================================================================
--- trunk/pyext/yoda/include/Histo1D.pyx	Tue May  7 14:58:17 2013	(r597)
+++ trunk/pyext/yoda/include/Histo1D.pyx	Mon May 13 20:21:43 2013	(r598)
@@ -1,10 +1,8 @@
 
-
-
 cdef class Histo1D(AnalysisObject):
     """
     1D histogram. Complete histogramming is supported, including
-    uniform/regular binning, variable wideth bininng, unbinned gaps in
+    uniform/regular binning, variable-width bininng, unbinned gaps in
     the covered range, and under/overflows. Rebinning by integer
     factors, or by explicit merging of contiguous bins is also
     supported.
@@ -30,10 +28,6 @@
     Histo1D(nbins, low, high, path="", title="")
     """
 
-    # Is there a reason why this sounds like an advert? I'VE ALREADY SOLD OUT.
-    # DAMMIT!
-
-
     cdef inline c.Histo1D *_Histo1D(self) except NULL:
         return <c.Histo1D*> self.ptr()
 
@@ -107,8 +101,7 @@
     @property
     def totalDbn(self):
         """The Dbn1D representing the total distribution."""
-        # TODO: Now does this actually involve a copy in Cython? We should probably
-        # find out!
+        # TODO: Now does this actually involve a copy in Cython? We should find out!
         return util.new_borrowed_cls(
             Dbn1D, &self._Histo1D().totalDbn(), self)
 

Modified: trunk/pyext/yoda/include/IO.pyx
==============================================================================
--- trunk/pyext/yoda/include/IO.pyx	Tue May  7 14:58:17 2013	(r597)
+++ trunk/pyext/yoda/include/IO.pyx	Mon May 13 20:21:43 2013	(r598)
@@ -1,16 +1,15 @@
-# Readers and writers
-# TODO: (low priority) refactor to improve readability.
+"""Readers and writers
 
-# The basic idea here is to provide Python IO semantics by using Python to do
-# the IO. Otherwise we get C++ IO semantics in Python. It also means we can use
-# dummy files, e.g. anything with read/write attributes. Generally a much better
-# idea than just "give this a filename", and well worth the inefficiencies and
-# potential memory limits.
+The basic idea here is to provide Python IO semantics by using Python to do
+the IO. Otherwise we get C++ IO semantics in Python. It also means we can use
+dummy files, e.g. anything with read/write attributes. Generally a much better
+idea than just "give this a filename", and well worth the inefficiencies and
+potential memory limits.
+"""
 
 import sys
 
-
-cdef list aobjects_to_list(vector[c.AnalysisObject*] *aobjects):
+cdef list _aobjects_to_list(vector[c.AnalysisObject*] *aobjects):
     cdef list out = []
     cdef c.AnalysisObject *ao
     cdef size_t i
@@ -22,7 +21,7 @@
     return out
 
 # Set a istringstream's string from a C/Python string
-cdef void make_iss(c.istringstream &iss, char *s):
+cdef void _make_iss(c.istringstream &iss, char *s):
     iss.str(string(s))
 
 
@@ -40,10 +39,10 @@
     cdef vector[c.AnalysisObject*] aobjects
     with open(filename) as f:
         s = f.read()
-    make_iss(iss, s)
+    _make_iss(iss, s)
     c.Reader_create(filename).read(iss, aobjects)
     # Not as expensive as it looks!
-    return aobjects_to_list(&aobjects)
+    return _aobjects_to_list(&aobjects)
 
 
 def readYODA(file_or_filename):
@@ -60,11 +59,11 @@
         with open(file_or_filename) as f:
             s = f.read()
 
-    make_iss(iss, s)
+    _make_iss(iss, s)
     c.ReaderYODA_create().read(iss, aobjects)
 
     # Not as expensive as it looks!
-    return aobjects_to_list(&aobjects)
+    return _aobjects_to_list(&aobjects)
 
 
 def readAIDA(file_or_filename):
@@ -81,11 +80,11 @@
         with open(file_or_filename) as f:
             s = f.read()
 
-    make_iss(iss, s)
+    _make_iss(iss, s)
     c.ReaderAIDA_create().read(iss, aobjects)
 
     # Not as expensive as it looks!
-    return aobjects_to_list(&aobjects)
+    return _aobjects_to_list(&aobjects)
 
 
 ##

Modified: trunk/pyext/yoda/util.pyx
==============================================================================
--- trunk/pyext/yoda/util.pyx	Tue May  7 14:58:17 2013	(r597)
+++ trunk/pyext/yoda/util.pyx	Mon May 13 20:21:43 2013	(r598)
@@ -14,16 +14,17 @@
 
     raise TypeError(_msg)
 
+
 class Edges(tuple):
-    'Edges(low, high)' 
+    'Edges(low, high)'
 
-    __slots__ = () 
+    __slots__ = ()
 
-    _fields = ('low', 'high') 
+    _fields = ('low', 'high')
 
     def __new__(_cls, low, high):
         'Create new instance of Edges(low, high)'
-        return tuple.__new__(_cls, (low, high)) 
+        return tuple.__new__(_cls, (low, high))
 
     @classmethod
     def _make(cls, iterable, new=tuple.__new__, len=len):
@@ -31,43 +32,43 @@
         result = new(cls, iterable)
         if len(result) != 2:
             raise TypeError('Expected 2 arguments, got %d' % len(result))
-        return result 
+        return result
 
     def __repr__(self):
         'Return a nicely formatted representation string'
-        return 'Edges(low=%r, high=%r)' % self 
+        return 'Edges(low=%r, high=%r)' % self
 
     def _asdict(self):
         'Return a new dict which maps field names to their values'
-        return dict(zip(self._fields, self)) 
+        return dict(zip(self._fields, self))
 
-    __dict__ = property(_asdict) 
+    __dict__ = property(_asdict)
 
     def _replace(_self, **kwds):
         'Return a new Edges object replacing specified fields with new values'
         result = _self._make(map(kwds.pop, ('low', 'high'), _self))
         if kwds:
             raise ValueError('Got unexpected field names: %r' % kwds.keys())
-        return result 
+        return result
 
     def __getnewargs__(self):
         'Return self as a plain tuple.  Used by copy and pickle.'
-        return tuple(self) 
+        return tuple(self)
 
     low = property(itemgetter(0), doc='Alias for field number 0')
     high = property(itemgetter(1), doc='Alias for field number 1')
 
 
 class Errors(tuple):
-    'Errors(minus, plus)' 
+    'Errors(minus, plus)'
 
-    __slots__ = () 
+    __slots__ = ()
 
-    _fields = ('minus', 'plus') 
+    _fields = ('minus', 'plus')
 
     def __new__(_cls, minus, plus):
         'Create new instance of Errors(minus, plus)'
-        return tuple.__new__(_cls, (minus, plus)) 
+        return tuple.__new__(_cls, (minus, plus))
 
     @classmethod
     def _make(cls, iterable, new=tuple.__new__, len=len):
@@ -75,28 +76,28 @@
         result = new(cls, iterable)
         if len(result) != 2:
             raise TypeError('Expected 2 arguments, got %d' % len(result))
-        return result 
+        return result
 
     def __repr__(self):
         'Return a nicely formatted representation string'
-        return 'Errors(minus=%r, plus=%r)' % self 
+        return 'Errors(minus=%r, plus=%r)' % self
 
     def _asdict(self):
         'Return a new dict which maps field names to their values'
-        return dict(zip(self._fields, self)) 
+        return dict(zip(self._fields, self))
 
-    __dict__ = property(_asdict) 
+    __dict__ = property(_asdict)
 
     def _replace(_self, **kwds):
         'Return a new Errors object replacing specified fields with new values'
         result = _self._make(map(kwds.pop, ('minus', 'plus'), _self))
         if kwds:
             raise ValueError('Got unexpected field names: %r' % kwds.keys())
-        return result 
+        return result
 
     def __getnewargs__(self):
         'Return self as a plain tuple.  Used by copy and pickle.'
-        return tuple(self) 
+        return tuple(self)
 
     minus = property(itemgetter(0), doc='Alias for field number 0')
     plus = property(itemgetter(1), doc='Alias for field number 1')
@@ -106,15 +107,15 @@
 #Errors = namedtuple('Errors', ('minus', 'plus'))
 #XY = namedtuple('XY', ('x', 'y'))
 class XY(tuple):
-    'XY(x, y)' 
+    'XY(x, y)'
 
-    __slots__ = () 
+    __slots__ = ()
 
-    _fields = ('x', 'y') 
+    _fields = ('x', 'y')
 
     def __new__(_cls, x, y):
         'Create new instance of XY(x, y)'
-        return tuple.__new__(_cls, (x, y)) 
+        return tuple.__new__(_cls, (x, y))
 
     @classmethod
     def _make(cls, iterable, new=tuple.__new__, len=len):
@@ -122,44 +123,44 @@
         result = new(cls, iterable)
         if len(result) != 2:
             raise TypeError('Expected 2 arguments, got %d' % len(result))
-        return result 
+        return result
 
     def __repr__(self):
         'Return a nicely formatted representation string'
-        return 'XY(x=%r, y=%r)' % self 
+        return 'XY(x=%r, y=%r)' % self
 
     def _asdict(self):
         'Return a new dict which maps field names to their values'
-        return dict(zip(self._fields, self)) 
+        return dict(zip(self._fields, self))
 
-    __dict__ = property(_asdict) 
+    __dict__ = property(_asdict)
 
     def _replace(_self, **kwds):
         'Return a new XY object replacing specified fields with new values'
         result = _self._make(map(kwds.pop, ('x', 'y'), _self))
         if kwds:
             raise ValueError('Got unexpected field names: %r' % kwds.keys())
-        return result 
+        return result
 
     def __getnewargs__(self):
         'Return self as a plain tuple.  Used by copy and pickle.'
-        return tuple(self) 
+        return tuple(self)
 
     x = property(itemgetter(0), doc='Alias for field number 0')
     y = property(itemgetter(1), doc='Alias for field number 1')
 
-#XYZ = namedtuple('XYZ', ('x', 'y', 'z'))
 
+#XYZ = namedtuple('XYZ', ('x', 'y', 'z'))
 class XYZ(tuple):
-    'XYZ(x, y, z)' 
+    'XYZ(x, y, z)'
 
-    __slots__ = () 
+    __slots__ = ()
 
-    _fields = ('x', 'y', 'z') 
+    _fields = ('x', 'y', 'z')
 
     def __new__(_cls, x, y, z):
         'Create new instance of XYZ(x, y, z)'
-        return tuple.__new__(_cls, (x, y, z)) 
+        return tuple.__new__(_cls, (x, y, z))
 
     @classmethod
     def _make(cls, iterable, new=tuple.__new__, len=len):
@@ -167,30 +168,29 @@
         result = new(cls, iterable)
         if len(result) != 3:
             raise TypeError('Expected 3 arguments, got %d' % len(result))
-        return result 
+        return result
 
     def __repr__(self):
         'Return a nicely formatted representation string'
-        return 'XYZ(x=%r, y=%r, z=%r)' % self 
+        return 'XYZ(x=%r, y=%r, z=%r)' % self
 
     def _asdict(self):
         'Return a new dict which maps field names to their values'
-        return dict(zip(self._fields, self)) 
+        return dict(zip(self._fields, self))
 
-    __dict__ = property(_asdict) 
+    __dict__ = property(_asdict)
 
     def _replace(_self, **kwds):
         'Return a new XYZ object replacing specified fields with new values'
         result = _self._make(map(kwds.pop, ('x', 'y', 'z'), _self))
         if kwds:
             raise ValueError('Got unexpected field names: %r' % kwds.keys())
-        return result 
+        return result
 
     def __getnewargs__(self):
         'Return self as a plain tuple.  Used by copy and pickle.'
-        return tuple(self) 
+        return tuple(self)
 
     x = property(itemgetter(0), doc='Alias for field number 0')
     y = property(itemgetter(1), doc='Alias for field number 1')
     z = property(itemgetter(2), doc='Alias for field number 2')
-


More information about the yoda-svn mailing list