|
[yoda-svn] r506 - in trunk: . include/YODA pyext/yoda/include srcblackhole at projects.hepforge.org blackhole at projects.hepforge.orgThu 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 |