|
[yoda-svn] r390 - in trunk: pyext srcblackhole at projects.hepforge.org blackhole at projects.hepforge.orgSat Sep 3 15:07:14 BST 2011
Author: davemallows Date: Sat Sep 3 15:07:14 2011 New Revision: 390 Log: More work on python bindings: mapped Histo1D ~pythonically. Modified: trunk/pyext/cyoda.pxd trunk/pyext/yoda.pyx trunk/src/Histo1D.cc Modified: trunk/pyext/cyoda.pxd ============================================================================== --- trunk/pyext/cyoda.pxd Sat Sep 3 01:22:57 2011 (r389) +++ trunk/pyext/cyoda.pxd Sat Sep 3 15:07:14 2011 (r390) @@ -1,6 +1,7 @@ from libcpp.vector cimport vector from libcpp.string cimport string from libcpp.pair cimport pair +from libcpp cimport bool cdef extern from "YODA/AnalysisObject.h" namespace "YODA": cdef cppclass AnalysisObject: @@ -11,9 +12,10 @@ vector[AnalysisObject *] read(string filename) cdef extern from "YODA/Scatter2D.h" namespace "YODA": - cdef cppclass Scatter2D: + cdef cppclass Scatter2D(AnalysisObject): size_t numPoints() vector[Point2D] points() + Scatter2D (Scatter2D &s) cdef extern from "YODA/Point2D.h" namespace "YODA": cdef cppclass Point2D: @@ -27,3 +29,51 @@ cdef extern from "YODA/ReaderAIDA.h" namespace "YODA::ReaderAIDA": Reader& create() + +cdef extern from "YODA/Dbn1D.h" namespace "YODA": + cdef cppclass Dbn1D: + pass + +cdef extern from "YODA/HistoBin1D.h" namespace "YODA": + cdef cppclass HistoBin1D: + HistoBin1D (HistoBin1D &h) + double area() + double height() + double areaErr() + double heightErr() + HistoBin1D operator + (HistoBin1D &, HistoBin1D &) + HistoBin1D operator - (HistoBin1D &, HistoBin1D&) + pass + +cdef extern from "YODA/Histo1D.h" namespace "YODA": + Histo1D add(Histo1D &, Histo1D &) + Histo1D subtract(Histo1D &, Histo1D &) + Scatter2D divide(Histo1D &, Histo1D &) + + cdef cppclass Histo1D(AnalysisObject): + Histo1D(size_t nbins, double lower, double upper, string &path, + string &title) + Histo1D(vector[double] &binedges, string &path, string &title) + Histo1D(vector[double] &binedges) + Histo1D(Histo1D &h, string &path) + Histo1D(Histo1D &h) + void fill(double x, double weight) + void reset() + void scaleW(double scalefactor) + void mergeBins(size_t a, size_t b) + void rebin(int n) + # Bin Accessors + size_t numBins() + double lowEdge() + double highEdge() + vector[HistoBin1D] &bins() + Dbn1D &underflow() + Dbn1D &overflow() + void eraseBin(size_t index) + # Statistical functions + double integral(bool includeoverflows) + double integral(size_t a, size_t b) + double sumW(bool includeoverflows) + double sumW2(bool includeoverflows) + double variance(bool includeoverflows) + double stdDev(bool includeoverflows) Modified: trunk/pyext/yoda.pyx ============================================================================== --- trunk/pyext/yoda.pyx Sat Sep 3 01:22:57 2011 (r389) +++ trunk/pyext/yoda.pyx Sat Sep 3 15:07:14 2011 (r390) @@ -2,12 +2,17 @@ from libcpp.vector cimport vector from libcpp.string cimport string from libcpp.pair cimport pair +from libcpp cimport bool cdef class AnalysisObject: """Base object class""" cdef cyoda.AnalysisObject *thisptr + @property def type(self): + return self.type_() + + cdef str type_(self): return self.thisptr.type().c_str() cdef class Point2D: @@ -44,6 +49,10 @@ cdef cyoda.Scatter2D * ptr(self): return <cyoda.Scatter2D *> self.thisptr + cdef setptr(self, cyoda.Scatter2D *ptr): + self.thisptr = <cyoda.AnalysisObject *> ptr + return self + @property def points(self): cdef vector[cyoda.Point2D] vec @@ -59,6 +68,9 @@ return out + def __repr__(self): + return 'Scatter2D%r' % self.points + cdef class ReaderAIDA: def read(self, char *filename): cdef vector[cyoda.AnalysisObject *] vec @@ -67,8 +79,6 @@ out = [] for i in range(vec.size()): if str(vec[i].type().c_str()) == 'Scatter2D': - print (<cyoda.Scatter2D *> vec[i]).points().at(0).x(),\ - (<cyoda.Scatter2D *> vec[i]).points().at(0).y() ana = Scatter2D() else: ana = AnalysisObject() @@ -78,3 +88,182 @@ out.append(ana) return out + + +cdef class Histo1D(AnalysisObject): + def __cinit__(self, *args, **kwargs): + cdef: + size_t nbins + double lower + double upper + char* path = '/' + char* title = '' + + if len(args) == 3: + nbins, lower, upper = args[0], args[1], args[2] + + self.setptr( + new cyoda.Histo1D(nbins, lower, upper, string(path), string(title)) + ) + + cdef cyoda.Histo1D* ptr(self): + return <cyoda.Histo1D *> self.thisptr + + cdef setptr(self, cyoda.Histo1D *ptr): + self.thisptr = ptr + return self + + def fill(self, double x, double weight=1.0): + self.ptr().fill(x, weight) + + def reset(self): + """Reset the histogram but leave the bin structure""" + self.ptr().reset() + + def scaleW(self, double factor): + """Scale the histogram and its statistics by given factor""" + self.ptr().scaleW(factor) + + def mergeBins(self, size_t a, size_t b): + self.ptr().mergeBins(a, b) + + def rebin(self, int n): + self.ptr().rebin(n) + + @property + def bins(self): + cdef size_t numbins = self.ptr().numBins() + cdef size_t i + + cdef vector[cyoda.HistoBin1D] bins = self.ptr().bins() + + cdef cyoda.HistoBin1D *b + + out = [] + + for i in range(numbins): + out.append(HistoBin1D().set(bins[i])) + + return out + + @property + def lowEdge(self): + return self.ptr().lowEdge() + + @property + def highEdge(self): + return self.ptr().highEdge() + + def underflow(self): + pass + + def __delitem__(self, size_t ix): + self.ptr().eraseBin(ix) + + def __getitem__(self, size_t ix): + return HistoBin1D().set(self.ptr().bins()[ix]) + + def integral(self, bool overflows=True): + return self.ptr().integral(overflows) + + def sumW(self, bool overflows=True): + return self.ptr().sumW(overflows) + + def sumW2(self, bool overflows=True): + return self.ptr().sumW2(overflows) + + def variance(self, bool overflows=True): + return self.ptr().variance(overflows) + + def stdDev(self, bool overflows=True): + return self.ptr().stdDev(overflows) + + def __add__(Histo1D a, Histo1D b): + cdef cyoda.Histo1D *res + res = new cyoda.Histo1D(cyoda.add(a.ptr()[0], b.ptr()[0])) + return Histo1D().setptr(res) + + def __sub__(Histo1D a, Histo1D b): + cdef cyoda.Histo1D *res + res = new cyoda.Histo1D(cyoda.subtract(a.ptr()[0], b.ptr()[0])) + return Histo1D().setptr(res) + + def __mul__(x, y): + cdef cyoda.Histo1D *res + tx, ty = type(x), type(y) + if (tx is int or tx is float) and ty is Histo1D: + histo = <Histo1D> y; factor = <Histo1D> x + elif tx is Histo1D and (ty is int or ty is float): + histo = <Histo1D> x; factor = <Histo1D> y + else: + raise RuntimeError('Cannot multiply %r by %r' % (tx, ty)) + + print histo, factor + res = new cyoda.Histo1D(histo.ptr()[0]) + res.scaleW(factor) + return Histo1D().setptr(res) + + def _div_scalar(Histo1D x, double y): + cdef cyoda.Histo1D *res = new cyoda.Histo1D(x.ptr()[0]) + if y == 0: + raise ArithmeticError('Histo1D: Divide by zero scalar') + res.scaleW(1.0 / y) + return Histo1D().setptr(res) + + def _div_histo(Histo1D x, Histo1D y): + cdef cyoda.Scatter2D *res + + res = new cyoda.Scatter2D(cyoda.divide(x.ptr()[0], y.ptr()[0])) + return Scatter2D().setptr(res) + + def __div__(x, y): + tx = type(x); ty = type(y) + if tx is Histo1D: + if ty is int or ty is float: + return x._div_scalar(y) + elif ty is Histo1D: + return x._div_histo(y) + + raise RuntimeError('Cannot multiply %r by %r' % (tx, ty)) + + def __repr__(self): + return 'Histo1D%r' % self.bins + + +cdef class Dbn1D: + pass + +cdef class Bin1D: + pass + +cdef class HistoBin1D(Bin1D): + cdef cyoda.HistoBin1D *thisptr + + cdef setptr(self, cyoda.HistoBin1D *ptr): + return self + + cdef set(self, cyoda.HistoBin1D ptr): + self.thisptr = new cyoda.HistoBin1D(ptr) + return self + + cdef cyoda.HistoBin1D* ptr(self): + return self.thisptr + + @property + def area(self): + return self.ptr().area() + + @property + def height(self): + return self.ptr().height() + + @property + def heightErr(self): + return self.ptr().heightErr() + + @property + def areaErr(self): + return self.ptr().areaErr() + + def __repr__(self): + return 'HistoBin1D(%r)' % self.area Modified: trunk/src/Histo1D.cc ============================================================================== --- trunk/src/Histo1D.cc Sat Sep 3 01:22:57 2011 (r389) +++ trunk/src/Histo1D.cc Sat Sep 3 15:07:14 2011 (r390) @@ -13,10 +13,8 @@ namespace YODA { - // typedef vector<HistoBin1D> Bins; - void Histo1D::fill(double x, double weight) { // Fill the underflow and overflow nicely _axis.totalDbn().fill(x, weight); @@ -152,7 +150,7 @@ break; } - tmp.addPoint(x, exminus, explus, y, ey, ey); + tmp.addPoint(x, y, exminus, explus, ey, ey); } assert(tmp.numPoints() == numer.numBins());
More information about the yoda-svn mailing list |