|
[yoda-svn] r222 - in trunk: include/YODA srcblackhole at projects.hepforge.org blackhole at projects.hepforge.orgSat Aug 6 21:04:31 BST 2011
Author: mkawalec Date: Sat Aug 6 13:04:59 2011 New Revision: 222 Log: Added a lot of comments and fixed binary search. Modified: trunk/include/YODA/Axis2D.h trunk/include/YODA/Bin1D.h trunk/include/YODA/Bin2D.h trunk/include/YODA/Dbn1D.h trunk/include/YODA/Dbn2D.h trunk/include/YODA/Exceptions.h trunk/include/YODA/Histo2D.h trunk/include/YODA/HistoBin1D.h trunk/src/Bin1D.cc trunk/src/Bin2D.cc trunk/src/Dbn1D.cc trunk/src/Histo2D.cc trunk/src/HistoBin1D.cc Modified: trunk/include/YODA/Axis2D.h ============================================================================== --- trunk/include/YODA/Axis2D.h Thu Aug 4 09:58:42 2011 (r221) +++ trunk/include/YODA/Axis2D.h Sat Aug 6 13:04:59 2011 (r222) @@ -15,97 +15,140 @@ using namespace std; -// A big number for the low/high search: +/// A big number for the low/high search: /// @todo This isn't good enough! Why would this be guaranteed to be /// larger than the axis scale? Use e.g. std::limits<double> and/or determine /// the true extent when booking. /// @todo Also, the code convention is that _foo is a private member variable/function: /// for constants use all-caps, e.g. LARGENUM. -const double _largeNum = 10000000000000.0; +const double _largeNum = 1000000000000000000000.0; + namespace YODA { template <typename BIN> class Axis2D { public: - + + /// A collection of helpful typedefs typedef BIN Bin; typedef typename std::vector<BIN> Bins; + typedef typename std::pair<size_t, std::pair<double,double> > Edge; + typedef typename std::pair<double, std::vector<Edge> > EdgeCollection; + typedef typename std::pair<double, double> Point; + typedef typename std::pair<Point, Point> Segment; private: - /// Edge validator - /** Checks if an edge is vertical or horisontal and launches - * an appropriate checking function + /// @brief Segment validator function + /** This a 'dispatcher' function. It checks if the segment in question + * is vertical or horizontal and launches the appropriate function + * searching for cuts in the prope direction. Since it operates on + * a vector of segments it is prepared to act on arbitrarly large sets of edges, + * in practice usually being four sides of a rectangular bin. + * + * Notice that it will never be checked, in the current state, if there is a cut + * in edges in the edgeset. This imposes the requirement of provide the program + * with non-degenerate bins, until checking in implemented. However, it doesn't seem + * to be needed, as edges are not generated by a user. + * + * This is also a perfect place to paralellize the program, if required. */ - bool _validateEdge(vector<pair<pair<double,double>, pair<double,double> > >& edges) { + bool _validateEdge(vector<Segment>& edges) + { + /// Setting the return variable. True means that no cuts were detected. bool ret = true; + + /// Looping over all the edges provided for(unsigned int i=0; i < edges.size(); i++) { + /** If the X coordinate of the starting point is the same + * as X coordinate of the ending one, checks if there are cuts + * on this vertical segment. + */ if(fuzzyEquals(edges[i].first.first, edges[i].second.first)) ret = _findCutsY(edges[i]); + + /// Check if the segment is horizontal and is it cutting any bin that already exists else if(fuzzyEquals(edges[i].first.second, edges[i].second.second)) ret = _findCutsX(edges[i]); + + /** This is a check that discards the bin if it is not a rectangle + * composed of vertical and horizontal segments. + */ else ret = false; - + + /** If a cut was detected, say it. There is no point in checking other edges + * in the set. + */ if(!ret) return false; } + /// If no cuts were detected in any of the edges, tell the launching function about this return true; } - - /// Inclusion validator - /** An uncompleted function that checks if there exist a group of bins - * included in each other. It will be invoked before adding two Axises2D - */ - bool _validateInclusion(pair<Utils::cachedvector<pair<double,vector<pair<size_t, pair<double,double> > > > >, Utils::cachedvector<pair<double,std::vector<pair<size_t, pair<double,double> > > > > >& edges) { - /// Making sure that the cache we will be using soon is correct and actual: - edges.first.regenCache(); - edges.second.regenCache(); - - /// Now, checking if any of the edges is cutting any other: - for(unsigned int i=0; i < edges.first.size(); i++) { - for(unsigned int j = 0; j < edges.first[i].second.size(); j++) { - size_t startX = edges.second._cache.lower_bound(approx(edges.first[i].second[j].second.first)); - size_t endX = edges.second._cache.upper_bound(edges.first[i].second[j].second.second); - for(int p = startX; p < endX; p++) { - if(edges.first[i].first > edges.second[i].second[p].second.first && - edges.first[i].first < edges.second[i].second[p].second.second){ - return false; - } - } - } - } - - //TODO: Check inclusion - } - - /// @name Binary search functions - //@{ - /** I am exploiting the fact that we are operating on - * a sorted vector all the time. Therefore employing - * binary search to find the lower bound seems to be - * a logical step. + + /// @brief A binary search function + /** This is conceptually the same implementation as in STL + * but because it returns the index of an element in a vector, + * it is easier to use in our case than the STL implementation + * that returns a pointer at the element. */ - size_t _binaryS(Utils::cachedvector<pair<double, vector<pair<size_t, pair<double,double> > > > >& toSearch, double value, size_t lower, size_t higher) { + size_t _binaryS(Utils::cachedvector<EdgeCollection>& toSearch, + double value, size_t lower, size_t higher) + { + /// Just a check if such degenerate situation happens if(lower == higher) return lower; + + /// Choose a midpoint that will be our pivot size_t where = (higher+lower)/2; + /// Launch the same procedure on half of the range above the pivot if(value >= toSearch[where].first) { if(where == toSearch.size() - 1) return where; if(value <= toSearch[where+1].first) return where; return _binaryS(toSearch, value, where, higher); } - if(where == 0) return where; + + /** This is not a redundant check, because + * of the nature of int division. + */ + if (where == 0) return where; + + /** Check if the value is somewhere inbetween + * an element at the position in question and + * an element at a lower position. If so, return + * an index to the current positon. + */ if(value >= toSearch[where-1].first) return where; + + /** If none of the above occurs, the value must + * be smaller that the element at the current + * position. In such case, launch the search on + * half of the interval below the current position. + */ return _binaryS(toSearch, value, lower, where); } - //@} - /// Function checking the cuts of horizontal segments - /** It searches for edges such that they may cut the edge in question and - * then checks if a cut indeed occurs. + + /// @brief Function that finds cuts of horizontal edges. + /** A specialised function that tries to exploit the fact + * that edges can cut one another only on right angles + * to the highest extent. The inner workings are explained + * in the comments placed in the function body. */ - bool _findCutsX(pair<pair<double,double>, pair<double,double> >& edge) { + bool _findCutsX(Segment& edge) { + /** Look up the limits of search in the _binHashSparse + * structure. We are not interested in the vertical edges + * that are before the beginning of our segment or after its end. + */ size_t i = _binaryS(_binHashSparse.second, edge.first.first, 0, _binHashSparse.second.size()); size_t end = _binaryS(_binHashSparse.second, edge.second.first, 0, _binHashSparse.second.size()); - for(; i < end; i++) { + for(; i < end; i++) { + + /** Scroll through all the vertical segments with a given X coordinate + * and see if any of those fulfills the cutting requirement. If it does, + * announce it. + */ for(unsigned int j = 0; j < _binHashSparse.second[i].second.size(); j++) { + /** Note that we are not taking into account the edges touching the + * segment in question. That's because sides of a bin touch + */ if(_binHashSparse.second[i].second[j].second.first < edge.first.second && _binHashSparse.second[i].second[j].second.second > edge.first.second && !fuzzyEquals(_binHashSparse.second[i].second[j].second.first, edge.first.second) && @@ -114,11 +157,15 @@ } } } + /// If none of the existing edges is cutting this edge, announce it return true; } - /// Checking the cuts of vertical segments - bool _findCutsY(pair<pair<double,double>, pair<double,double> >& edge) { + /// @brief Function that finds cuts of vertical edges + /** For a detailed descpription, please look into + * documentation for _findCutsX(). + */ + bool _findCutsY(Segment& edge) { size_t i = _binaryS(_binHashSparse.first, edge.first.second, 0, _binHashSparse.first.size()); size_t end = _binaryS(_binHashSparse.first, edge.second.second, 0, _binHashSparse.first.size()); for(; i < end; i++) { @@ -135,35 +182,76 @@ return true; } - /// What to execute when an edge is dropped. - void _dropEdge(vector<pair<pair<double,double>, pair<double,double> > >& edges) { - std::cerr << "A set of edges was dropped. No additional information is implemented yet, so none can be given. Have a good day." << endl; + /// @brief Function executed when a set of edges is dropped. + /** It does not have any information about which edge in the set + * had failed the check. If this is needed such additional information + * can be readily implemented. + */ + void _dropEdge(vector<Segment>& edges) { + std::cerr << "A set of edges was dropped." << endl; } - /// Function that adds an edge after it was verified by _validateEdge() - void _addEdge(vector<pair<pair<double,double>, pair<double,double> > >& edges) { + /// @brief Bin adder. + /** It contains all the commands that need to executed + * to properly add a bin. Specifially edges are added to + * the edge cache (_binHashSparse) and a bin is created from + * those edges. + */ + void _addEdge(vector<Segment>& edges) { + /// Check if there was no mistake made when adding segments to a vector. + if(edges.size() != 4) throw Exception("The segments supplied don't describe a full bin!"); + + /** This is the part in charge of adding each of the segments + * to the edge cache. Segments are assumed to be validated + * beforehand. + */ for(unsigned int j=0; j < edges.size(); j++) { - pair<pair<double,double>, pair<double,double> > edge = edges[j]; + /// Association made for convinience. + Segment edge = edges[j]; + + /** Do the following if the edge is vertical. + * Those two cases need to be distinguished + * because of the way in which edge cache is structured. + */ if(edge.first.first == edge.second.first) { + /** See if our edge has the same X coordinate as any other + * edge that is currently in the cache. + */ + + /// Keeps the status of the search bool found = false; + + /** There is only a certain set of X coordinates that we need to sweep + * to check if our segment has the same X coordinate. Find them. + */ size_t i = _binaryS(_binHashSparse.second, edge.first.first, 0, _binHashSparse.second.size())-1; if(i < 0) i = 0; size_t end = i+3; + + /** For the coordinates in range, check if one of them is an X coordinate of + * the sement. + */ for(; i < _binHashSparse.second.size() && i < end ; i++) { - if(fuzzyEquals(_binHashSparse.second[i].first, edge.first.first)) { - _binHashSparse.second[i].second.push_back( - make_pair(_bins.size(),make_pair(edge.first.second, edge.second.second))); - found = true; + /// If this is the case, do what is needed to be done. + if(fuzzyEquals(_binHashSparse.second[i].first, edge.first.first)) { + _binHashSparse.second[i].second.push_back(make_pair(_bins.size(),make_pair(edge.first.second, edge.second.second))); + found = true; + break; } } + + /** If no edge with the same X coordinate exist, create + * a new subhash at the X coordinate of a segment. + */ if(!found) { - vector<pair<size_t, pair<double,double> > > temp; + vector<Edge> temp; temp.push_back(make_pair(_bins.size(), make_pair(edge.first.second, edge.second.second))); _binHashSparse.second.push_back(make_pair(edge.first.first,temp)); sort(_binHashSparse.second.begin(), _binHashSparse.second.end()); } } - + + /// See the vertical case for description of a horizontal one else if(edge.first.second == edge.second.second) { bool found = false; size_t i = _binaryS(_binHashSparse.first, edge.first.second, 0, _binHashSparse.first.size())-1; @@ -171,26 +259,28 @@ size_t end = i+3; for(; i < _binHashSparse.first.size() && i < end; i++) { if(fuzzyEquals(_binHashSparse.first[i].first, edge.first.second)) { - _binHashSparse.first[i].second.push_back( - make_pair(_bins.size(),make_pair(edge.first.first, edge.second.first))); + _binHashSparse.first[i].second.push_back(make_pair(_bins.size(),make_pair(edge.first.first, edge.second.first))); found = true; } } if(!found) { - vector<pair<size_t, pair<double,double> > > temp; + vector<Edge> temp; temp.push_back(make_pair(_bins.size(), make_pair(edge.first.first, edge.second.first))); _binHashSparse.first.push_back(make_pair(edge.second.second, temp)); sort(_binHashSparse.first.begin(), _binHashSparse.first.end()); } } } + /// Now, create a bin with the edges provided _bins.push_back(BIN(edges)); } - /** This funcion looks on the orientation of an edge and - * if it is incorrect, returns the correct orientation. - */ - void _fixOrientation(pair<pair<double,double>, pair<double,double> >& edge) { + /// @brief Orientation fixer + /** Check if the orientation of an edge is proper + * for the rest of the algorithm to work on, and if it is not + * fix it. + */ + void _fixOrientation(Segment& edge) { if(fuzzyEquals(edge.first.first, edge.second.first)) { if(edge.first.second > edge.second.second) { double temp = edge.second.second; @@ -204,51 +294,69 @@ edge.second.first = temp; } } + + /// @brief Axis creator + /** The top-level function taking part in the process of + * adding edges. Creating an axis is the same operation + * for it as adding new bins so it can be as well used to + * add some custom bins. + * + * It accepts two extremal points of a rectangle + * (top-right and bottom-left) as input. + */ + void _mkAxis(const vector<Segment>& binLimits) { + + /// For each of the rectangles + for(unsigned int i=0; i < binLimits.size(); i++) { + /// Produce the segments that a rectangle is composed of + Segment edge1 = + make_pair(binLimits[i].first, + make_pair(binLimits[i].first.first, binLimits[i].second.second)); + Segment edge2 = + make_pair(make_pair(binLimits[i].first.first, binLimits[i].second.second), + binLimits[i].second); + Segment edge3 = + make_pair(make_pair(binLimits[i].second.first, binLimits[i].first.second), + binLimits[i].second); + Segment edge4 = + make_pair(binLimits[i].first, + make_pair(binLimits[i].second.first, binLimits[i].first.second)); - /// A function if charge of adding the edges. - void _mkAxis(const vector<pair<pair<double,double>,pair<double,double> > >& binedges) { - for(unsigned int i=0; i < binedges.size(); i++) { - pair<pair<double,double>, pair<double,double> > edge1 = - make_pair(binedges[i].first, - make_pair(binedges[i].first.first, binedges[i].second.second)); - pair<pair<double,double>, pair<double,double> > edge2 = - make_pair(make_pair(binedges[i].first.first, binedges[i].second.second), - binedges[i].second); - pair<pair<double,double>, pair<double,double> > edge3 = - make_pair(make_pair(binedges[i].second.first, binedges[i].first.second), - binedges[i].second); - pair<pair<double,double>, pair<double,double> > edge4 = - make_pair(binedges[i].first, - make_pair(binedges[i].second.first, binedges[i].first.second)); - + /// Check if they are made properly _fixOrientation(edge1); _fixOrientation(edge2); _fixOrientation(edge3); _fixOrientation(edge4); - vector<pair<pair<double,double>, pair<double,double> > > edges; + /// Add all the segments to a vector + vector<Segment> edges; edges.push_back(edge1); edges.push_back(edge2); edges.push_back(edge3); edges.push_back(edge4); - //TODO: the _dropEdge() part should be moved into _addEdge() function and indicate which edge - // is the conflicting one, not dropping the whole edgeset, as it is doing now. Same in addBins. + /// And check if a bin is a proper one, if it is, add it. if(_validateEdge(edges)) _addEdge(edges); else _dropEdge(edges); } - - //Setting all the caches + /// Setting all the caches _binHashSparse.first.regenCache(); _binHashSparse.second.regenCache(); _regenDelimiters(); } - /// Generating the extrema of the graph. + /// @brief Plot extrema (re)generator. + /** Since scrolling through every bin is an expensive + * operation to do every time we need the limits of + * the plot, there are caches set up. This function + * regenerates them. It should be run after any change is made + * to bin layout. + */ void _regenDelimiters() { double highEdgeX = -_largeNum; double highEdgeY = -_largeNum; double lowEdgeX = _largeNum; double lowEdgeY = _largeNum; - + + /// Scroll through the bins and set the delimiters. for(unsigned int i=0; i < _bins.size(); i++) { if(_bins[i].xMin() < lowEdgeX) lowEdgeX = _bins[i].xMin(); if(_bins[i].xMax() > highEdgeX) highEdgeX = _bins[i].xMax(); @@ -266,46 +374,58 @@ /// @name Constructors: //@{ - /// Empty constructor: + /// @brief Empty constructor + /** Only added because it is required by SWIG. + * It doesn't make much sense to use it. + */ Axis2D() { - vector<pair<pair<double,double>, pair<double,double> > > edges; + vector<Segment> edges; _mkAxis(edges); } - - ///Default constructor - Axis2D(const vector<pair<pair<double,double>, pair<double,double> > >& binedges) { - _mkAxis(binedges); + + /// Constructor provided with a vector of bin delimiters + Axis2D(const vector<Segment>& binLimits) { + _mkAxis(binLimits); } ///Most standard constructor, should be self-explanatory Axis2D(size_t nbinsX, double lowerX, double upperX, size_t nbinsY, double lowerY, double upperY) { - vector<pair<pair<double,double>, pair<double,double> > > edges; + vector<Segment> binLimits; double coeffX = (upperX - lowerX)/(double)nbinsX; double coeffY = (upperY - lowerX)/(double)nbinsY; for(double i=lowerX; i < upperX; i+=coeffX) { for(double j=lowerY; j < upperY; j+=coeffY) { - edges.push_back(make_pair(make_pair(i, j), + binLimits.push_back(make_pair(make_pair(i, j), make_pair((double)(i+coeffX), (double)(j+coeffY)))); } } - _mkAxis(edges); + _mkAxis(binLimits); } //@} /// @name Addition operators: //@{ - /** This is a bin addition operator. It is given a set of boindary points (bottom-left - * and top-right) that uniquely determine a bin and it adds a set of bins basing on that. - * Please, try to include as many bins as possible in one call, as regenCache() is too - * computationaly expensive to be called for each single bin in a series. - */ - void addBin(const vector<pair<pair<double,double>, pair<double,double> > >& vertexCoords) { - _mkAxis(vertexCoords); + + /// @brief Bin addition operator + /** This operator is provided a vector of limiting + * points in the format required by _mkAxis(). + * It should be noted that there is nothing special about + * the initiation stage of Axis2D, and the edges can be added + * online if they meet all the requirements of non-degeneracy. + * No merging is supported, and I don't think it should before the support + * for merging for '+' operator (codewise it should be the same thing). + */ + void addBin(const vector<Segment>& binLimits) { + _mkAxis(binLimits); } - + + /// @brief Bin addition operator + /** This operator is supplied with whe extreamal coordinates of just + * one bin. It then launches the standard bin addition procedure. + */ void addBin(double lowX, double lowY, double highX, double highY) { - vector<pair<pair<double,double>, pair<double,double> > > coords; + vector<Segment> coords; coords.push_back(make_pair(make_pair(lowX, lowY), make_pair(highX, highY))); addBin(coords); @@ -315,13 +435,19 @@ /// @name Some helper functions: //@{ - /// Return a total number of bins in Histo - /// Checks if our bins form a grid. - /** Uses a very neat property of _binCacheSparse, - * namely that it will containg the same number of - * edges on inner sides and half the number on outer ones*/ + /// @name Checks if our bins form a grid. + /** This function uses a neat property of _binHashSparse. + * If it is containing a set of edges forming a grid without + * gaps in the middle it will have the same number of edges in the + * inner subcaches and half of this amount in the outer (grid boundary) + * subcaches. This makes isGriddy() a very, very fast function. + */ int isGriddy() { + + /** Check if the number of edges parallel to X axis + * is proper in every subcache. + */ unsigned int sizeX = _binHashSparse.first[0].second.size(); for(unsigned int i=1; i < _binHashSparse.first.size(); i++) { if(i == _binHashSparse.first.size() - 1) { @@ -333,6 +459,8 @@ return -1; } } + + /// Do the same for edges parallel to Y axis. unsigned int sizeY = _binHashSparse.second[0].second.size(); for(unsigned int i=1; i < _binHashSparse.second.size(); i++) { if(i!= _binHashSparse.second.size() - 1) { @@ -342,10 +470,13 @@ } else if(_binHashSparse.second[i].second.size() != sizeY) return -1; } + + /// If everything is proper, announce it. return 0; } + /// Return a total number of bins in a Histo unsigned int numBinsTotal() const { return _bins.size(); } @@ -465,14 +596,14 @@ } /// Get the binHash(non-const version) - std::pair<Utils::cachedvector<pair<double,std::vector<pair<size_t, pair<double,double> > > > >, - Utils::cachedvector<pair<double,std::vector<pair<size_t, pair<double,double> > > > > > getHash() { + std::pair<Utils::cachedvector<EdgeCollection>, + Utils::cachedvector<EdgeCollection> > getHash() { return _binHashSparse; } /// Get the binHash(const version) - const std::pair<Utils::cachedvector<pair<double,std::vector<pair<size_t, pair<double,double> > > > >, - Utils::cachedvector<pair<double,std::vector<pair<size_t, pair<double,double> > > > > > getHash() const { + const std::pair<Utils::cachedvector<EdgeCollection>, + Utils::cachedvector<EdgeCollection > > getHash() const { return _binHashSparse; } @@ -484,6 +615,10 @@ * found, ie. (coordX, coordY) is a point in empty space -1 is returned. */ int findBinIndex(double coordX, double coordY) const { + /** It is need to apply this trick not to have a coordinate + * pointing directly on the edge. Notice that this is lower that + * fuzzyEquals() tolerance. + */ coordX += 0.0000000001; coordY += 0.00000000001; size_t indexY = (*_binHashSparse.first._cache.lower_bound(approx(coordY))).second; @@ -516,7 +651,12 @@ for (size_t i=0; i<_bins.size(); i++) _bins[i].reset(); } - /// Scales the axis in a given direction by a specified coefficient + /// @brief Axis scaler + /** Scales the axis with a given scale. If no scale is given, assumes + * identity transform. + * + * @todo Should a support for matrix transformations be added? + */ void scale(double scaleX = 1.0, double scaleY = 1.0) { // Two loops are put on purpose, just to protect // against improper _binHashSparse @@ -535,11 +675,11 @@ } } + /// Regenerate the bin edges cache. _binHashSparse.first.regenCache(); _binHashSparse.second.regenCache(); - // Now, as we have the map rescaled, we need to update the bins - // in their own structure in order to have high/low edges correct + /// Now, as we have the map rescaled, we need to update the bins for(unsigned int i=0; i < _bins.size(); i++) _bins[i].scale(scaleX, scaleY); _dbn.scale(scaleX, scaleY); _underflow.scale(scaleX, scaleY); @@ -571,9 +711,9 @@ return ! operator == (other); } - /// Addition operator + /// @brief Addition operator /** At this stage it is only possible to add two histograms with - * the same binnings. Compatible but not equal binning soon to come + * the same binnings. Compatible but not equal binning to come soon. */ Axis2D<BIN>& operator += (const Axis2D<BIN>& toAdd) { if (*this != toAdd) { @@ -615,14 +755,14 @@ /// The total distribution Dbn2D _dbn; - /// Bin hash structure + /// @brief Bin hash structure /** First in pair is holding the horizontal edges indexed by first.first * which is an y coordinate. The last pair specifies x coordinates (begin, end) of * the horizontal edge. * Analogous for the second member of the pair. */ - std::pair<Utils::cachedvector<pair<double,std::vector<pair<size_t, pair<double,double> > > > >, - Utils::cachedvector<pair<double,std::vector<pair<size_t, pair<double,double> > > > > > + std::pair<Utils::cachedvector<EdgeCollection>, + Utils::cachedvector<EdgeCollection> > _binHashSparse; /// Low/High edges: @@ -646,11 +786,6 @@ return tmp; } - /// Less-than operator - inline bool operator < (const pair<vector<double>, vector<double> >& a, const pair<vector<double>, vector<double> >& b) { - if(a.first == b.first) return a.second < b.second; - return a.first < b.first; - } } Modified: trunk/include/YODA/Bin1D.h ============================================================================== --- trunk/include/YODA/Bin1D.h Thu Aug 4 09:58:42 2011 (r221) +++ trunk/include/YODA/Bin1D.h Sat Aug 6 13:04:59 2011 (r222) @@ -26,6 +26,10 @@ Bin1D(std::pair<double,double> edges); + /// A constructor for cutting along a given axis: + Bin1D(double lowedge, double highedge, unsigned long numFills, + double sumW, double sumW2, double sumWX, double sumWX2); + //@} @@ -113,13 +117,6 @@ //@} - /// Setters - void setW(double sumW); - void setW2(double sumW2); - void setWX(double sumWX); - void setWX2(double sumWX2); - void setNumFills(double numFills); - public: Modified: trunk/include/YODA/Bin2D.h ============================================================================== --- trunk/include/YODA/Bin2D.h Thu Aug 4 09:58:42 2011 (r221) +++ trunk/include/YODA/Bin2D.h Sat Aug 6 13:04:59 2011 (r222) @@ -3,7 +3,6 @@ #include "YODA/Bin.h" #include "YODA/Dbn2D.h" -#include "YODA/HistoBin1D.h" #include <string> #include <utility> #include <vector> @@ -84,24 +83,9 @@ double sumWX2() const; double sumWY2() const; - /// Setters - void setW(double sumW); - void setW2(double sumW2); - void setWX(double sumWX); - void setWY(double sumWY); - void setWX2(double sumWX2); - void setWY2(double sumWY2); - void setWXY(double sumWXY); - ///@name Transformers //@{ - /// Transform, taking X coordinates as a bin width - HistoBin1D transformX(); - - /// Transform, taking Y coordinates as bin width - HistoBin1D transformY(); - /// Addition operators: Bin2D& operator += (const Bin2D&); Bin2D& operator -= (const Bin2D&); Modified: trunk/include/YODA/Dbn1D.h ============================================================================== --- trunk/include/YODA/Dbn1D.h Thu Aug 4 09:58:42 2011 (r221) +++ trunk/include/YODA/Dbn1D.h Sat Aug 6 13:04:59 2011 (r222) @@ -21,6 +21,7 @@ /// sampled distribution. It is used to provide this information in bins /// and for the "hidden" \f$ y \f$ distribution in profile histogram bins. class Dbn1D { + friend class Bin1D; public: /// Constructor. @@ -28,7 +29,6 @@ reset(); } - /// @name Modifiers //@{ @@ -115,14 +115,6 @@ //@} - /// Setters - void setW(double sumW); - void setW2(double sumW2); - void setWX(double sumWX); - void setWX2(double sumWX2); - void setNumFills(double numFills); - - public: /// Add two dbns Modified: trunk/include/YODA/Dbn2D.h ============================================================================== --- trunk/include/YODA/Dbn2D.h Thu Aug 4 09:58:42 2011 (r221) +++ trunk/include/YODA/Dbn2D.h Sat Aug 6 13:04:59 2011 (r222) @@ -37,16 +37,6 @@ _sumWXY *= scaleX*scaleY; } - /// Setters - void setW(double sumW) { _sumW = sumW;} - void setW2(double sumW2) { _sumW2 = sumW2;} - void setWX(double sumWX) { _sumWX = sumWX;} - void setWY(double sumWY) { _sumWY = sumWY;} - void setWX2(double sumWX2) { _sumWX2 = sumWX2;} - void setWY2(double sumWY2) { _sumWY2 = sumWY2;} - void setWXY(double sumWXY) { _sumWXY = sumWXY;} - void setNumfills(unsigned long numFills) {_numFills = numFills;} - /// Some in-distribution variables. Should be self-evident. double xMean() const; double yMean() const; Modified: trunk/include/YODA/Exceptions.h ============================================================================== --- trunk/include/YODA/Exceptions.h Thu Aug 4 09:58:42 2011 (r221) +++ trunk/include/YODA/Exceptions.h Sat Aug 6 13:04:59 2011 (r222) @@ -28,7 +28,7 @@ RangeError(const std::string& what) : Exception(what) {} }; - /// Error to throw when a slicing is requested on a non-slicable state of an object: + /// Error to throw when a slicing is requested on a non-slicable state of an object. class GridError : public Exception { public: GridError(const std::string& what) : Exception(what) {} Modified: trunk/include/YODA/Histo2D.h ============================================================================== --- trunk/include/YODA/Histo2D.h Thu Aug 4 09:58:42 2011 (r221) +++ trunk/include/YODA/Histo2D.h Sat Aug 6 13:04:59 2011 (r222) @@ -8,6 +8,7 @@ #include "YODA/AnalysisObject.h" #include "YODA/HistoBin2D.h" +#include "YODA/HistoBin1D.h" #include "YODA/Scatter3D.h" #include "YODA/Axis2D.h" #include "YODA/Exceptions.h" @@ -288,10 +289,13 @@ if(atY < lowEdgeY() || atY > highEdgeY()) throw RangeError("Y is outside the grid"); HistoBin2D first = binByCoord(lowEdgeX(), atY); vector<HistoBin1D> temp; - temp.push_back(first.transformX()); + temp.push_back(HistoBin1D(first.lowEdgeX(), first.highEdgeX(), first.numEntries(), + first.sumW(), first.sumW2(), first.sumWX(), first.sumWX2())); for(double i = first.xMax() + first.widthX()/2; i < highEdgeX(); i+=first.widthX()){ - temp.push_back(binByCoord(i,atY).transformX()); + HistoBin2D tempBin = binByCoord(i, atY); + temp.push_back(HistoBin1D(tempBin.lowEdgeX(), tempBin.highEdgeX(), tempBin.numEntries(), + tempBin.sumW(), tempBin.sumW2(), tempBin.sumWX(), tempBin.sumWX2())); } Histo1D ret(temp); @@ -302,10 +306,13 @@ if(atX < lowEdgeX() || atX > highEdgeX()) throw RangeError("X is outside the grid"); HistoBin2D first = binByCoord(lowEdgeX(), atX); vector<HistoBin1D> temp; - temp.push_back(first.transformY()); + temp.push_back(HistoBin1D(first.lowEdgeY(), first.highEdgeY(), first.numEntries(), + first.sumW(), first.sumW2(), first.sumWX(), first.sumWX2())); for(double i = first.yMax() + first.widthY()/2; i < highEdgeY(); i+=first.widthY()){ - temp.push_back(binByCoord(atX,i).transformY()); + HistoBin2D tempBin = binByCoord(atX, i); + temp.push_back(HistoBin1D(tempBin.lowEdgeY(), tempBin.highEdgeY(), tempBin.numEntries(), + tempBin.sumW(), tempBin.sumW2(), tempBin.sumWX(), tempBin.sumWX2())); } Histo1D ret(temp); Modified: trunk/include/YODA/HistoBin1D.h ============================================================================== --- trunk/include/YODA/HistoBin1D.h Thu Aug 4 09:58:42 2011 (r221) +++ trunk/include/YODA/HistoBin1D.h Sat Aug 6 13:04:59 2011 (r222) @@ -22,6 +22,8 @@ //@{ HistoBin1D(double lowedge, double highedge); HistoBin1D(std::pair<double,double> edges); + HistoBin1D(double lowedge, double highedge, unsigned long numFills, + double sumW, double sumW2, double sumWX, double sumWX2); //@} Modified: trunk/src/Bin1D.cc ============================================================================== --- trunk/src/Bin1D.cc Thu Aug 4 09:58:42 2011 (r221) +++ trunk/src/Bin1D.cc Sat Aug 6 13:04:59 2011 (r222) @@ -25,6 +25,17 @@ assert( _edges.second >= _edges.first ); } + Bin1D::Bin1D(double lowedge, double highedge, unsigned long numFills, + double sumW, double sumW2, double sumWX, double sumWX2) + :_edges( make_pair(lowedge, highedge) ) + { + _xdbn._numFills = numFills; + _xdbn._sumW = sumW; + _xdbn._sumW2 = sumW2; + _xdbn._sumWX = sumWX; + _xdbn._sumWX2 = sumWX2; + } + void Bin1D::reset () { _xdbn.reset(); @@ -109,12 +120,6 @@ return _xdbn.sumWX2(); } - void Bin1D::setW(double sumW) {_xdbn.setW(sumW);} - void Bin1D::setW2(double sumW2) {_xdbn.setW2(sumW2);} - void Bin1D::setWX(double sumWX) {_xdbn.setWX(sumWX);} - void Bin1D::setWX2(double sumWX2) {_xdbn.setWX2(sumWX2);} - void Bin1D::setNumFills(double numFills) {_xdbn.setNumFills(numFills);} - Bin1D& Bin1D::add(const Bin1D& b) { assert(_edges == b._edges); _xdbn += b._xdbn; Modified: trunk/src/Bin2D.cc ============================================================================== --- trunk/src/Bin2D.cc Thu Aug 4 09:58:42 2011 (r221) +++ trunk/src/Bin2D.cc Sat Aug 6 13:04:59 2011 (r222) @@ -136,41 +136,6 @@ return _dbn.sumWY2(); } - /// Dbn setters: - void Bin2D::setW(double sumW) {_dbn.setW(sumW);} - void Bin2D::setW2(double sumW2) {_dbn.setW2(sumW2);} - void Bin2D::setWX(double sumWX) {_dbn.setWX(sumWX);} - void Bin2D::setWY(double sumWY) {_dbn.setWY(sumWY);} - void Bin2D::setWX2(double sumWX2) {_dbn.setWX2(sumWX2);} - void Bin2D::setWY2(double sumWY2) {_dbn.setWY2(sumWY2);} - void Bin2D::setWXY(double sumWXY) {_dbn.setWY2(sumWXY);} - - /// Transformer transforming taking X as width - HistoBin1D Bin2D::transformX() { - HistoBin1D temp(lowEdgeX(), highEdgeX()); - - temp.setW(sumW()); - temp.setW2(sumW2()); - temp.setWX(sumWX()); - temp.setWX2(sumWX2()); - temp.setNumFills(numEntries()); - - return temp; - } - - /// Transformer transforming taking Y as width - HistoBin1D Bin2D::transformY() { - HistoBin1D temp(lowEdgeY(), highEdgeY()); - - temp.setW(sumW()); - temp.setW2(sumW2()); - temp.setWX(sumWY()); - temp.setWX2(sumWY2()); - temp.setNumFills(numEntries()); - - return temp; - } - Bin2D& Bin2D::add(const Bin2D& b) { assert(_edges == b._edges); _dbn += b._dbn; Modified: trunk/src/Dbn1D.cc ============================================================================== --- trunk/src/Dbn1D.cc Thu Aug 4 09:58:42 2011 (r221) +++ trunk/src/Dbn1D.cc Sat Aug 6 13:04:59 2011 (r222) @@ -103,13 +103,6 @@ return std::sqrt(variance() / effNumEntries()); } - /// Setters - void Dbn1D::setW(double sumW) {_sumW = sumW;} - void Dbn1D::setW2(double sumW2) {_sumW2 = sumW2;} - void Dbn1D::setWX(double sumWX) {_sumWX = sumWX;} - void Dbn1D::setWX2(double sumWX2) {_sumWX2 = sumWX2;} - void Dbn1D::setNumFills(double numFills) {_numFills = numFills;} - Dbn1D& Dbn1D::add(const Dbn1D& d) { _numFills += d._numFills; Modified: trunk/src/Histo2D.cc ============================================================================== --- trunk/src/Histo2D.cc Thu Aug 4 09:58:42 2011 (r221) +++ trunk/src/Histo2D.cc Sat Aug 6 13:04:59 2011 (r222) @@ -4,7 +4,7 @@ // Copyright (C) 2008-2011 The YODA collaboration (see AUTHORS for details) // #include "YODA/Histo2D.h" -#include "YODA/Scatter2D.h" +#include "YODA/Scatter3D.h" #include <cmath> #include <iostream> @@ -32,6 +32,7 @@ } else if (x < _axis.lowEdgeX()) { _axis.underflow().fill(x, y, weight); } else if (x >= _axis.highEdgeX()) { _axis.overflow().fill(x, y, weight); } + else throw GridError("You are trying to fill an empty space on a grid!"); return index; } Modified: trunk/src/HistoBin1D.cc ============================================================================== --- trunk/src/HistoBin1D.cc Thu Aug 4 09:58:42 2011 (r221) +++ trunk/src/HistoBin1D.cc Sat Aug 6 13:04:59 2011 (r222) @@ -20,6 +20,11 @@ : Bin1D(edges) { } + HistoBin1D::HistoBin1D(double low, double high, unsigned long numFills, double sumW, + double sumW2, double sumWX, double sumWX2) + : Bin1D(low, high, numFills, sumW, sumW2, sumWX, sumWX2) + { } + void HistoBin1D::fill(double x, double w) { assert( _edges.first < _edges.second );
More information about the yoda-svn mailing list |