|
[yoda-svn] r275 - in trunk: . include/YODAblackhole at projects.hepforge.org blackhole at projects.hepforge.orgThu Aug 18 12:15:54 BST 2011
Author: buckley Date: Thu Aug 18 12:15:53 2011 New Revision: 275 Log: More fixes, tidying and lots of comments and TODOs. Sorry Michal :( Modified: trunk/TODO trunk/include/YODA/Axis2D.h trunk/include/YODA/Bin2D.h trunk/include/YODA/Histo2D.h Modified: trunk/TODO ============================================================================== --- trunk/TODO Thu Aug 18 11:10:52 2011 (r274) +++ trunk/TODO Thu Aug 18 12:15:53 2011 (r275) @@ -26,7 +26,7 @@ MK: Done * Similarly, is there any reason to expose the isGriddy function publicly on - Axis2D and Histo1D? Can't it just be a private _isGrid()? (MICHAL) + Axis2D and Histo2D? Can't it just be a private _isGrid()? (MICHAL) MK: Done * Add copy constructors for Dbn1D/2D, Scatter2D, Histo/ProfileBin1D, Point2D/3D, HistoBin2D. Modified: trunk/include/YODA/Axis2D.h ============================================================================== --- trunk/include/YODA/Axis2D.h Thu Aug 18 11:10:52 2011 (r274) +++ trunk/include/YODA/Axis2D.h Thu Aug 18 12:15:53 2011 (r275) @@ -18,17 +18,15 @@ /// /// This class handles almost all boiler-plate operations /// on 2D bins (like creating axis, adding, searching, testing). + /// + /// @todo This needs an extra DBN template argument, cf. Axis1D template <typename BIN> class Axis2D { - public: - + /// Enabling Histo2D to check if its axis is a grid + /// @todo This should not be necessary friend class Histo2D; - // A few helpful typedefs - typedef BIN Bin; - typedef typename std::vector<BIN> Bins; - /// When edge is added to the collection it must /// obey the following format. size_t specifies the bin this /// edge is a member of, a pair contains a beginning and end of the edge. @@ -48,6 +46,13 @@ public: + // A few helpful typedefs + typedef BIN Bin; + typedef typename std::vector<BIN> Bins; + + + public: + /// @name Constructors: //@{ @@ -69,6 +74,8 @@ /// Most standard constructor, should be self-explanatory + /// @todo Never say "should be self-explanatory": explain it, even if it seems obvious + /// @todo This is too large/complex to be inline: move to the .cc Axis2D(size_t nbinsX, double lowerX, double upperX, size_t nbinsY, double lowerY, double upperY) { vector<Segment> binLimits; double coeffX = (upperX - lowerX)/(double)nbinsX; @@ -84,7 +91,9 @@ /// @brief A bin constructor + /// /// Creates an Axis2D from existing bins + /// @todo This is too large to be inline: move to the .cc Axis2D(const Bins& bins, const std::vector<std::vector<Dbn2D> >& outflows, const Dbn2D& totalDbn) @@ -107,7 +116,7 @@ //@} - /// @name Addition operators: + /// @name Bin insertion operators //@{ /// @brief Bin addition operator @@ -134,22 +143,22 @@ //@} - /// @name Helper functions + + /// @name Modifiers //@{ /// @brief Fill operator /// Called when it is wanted to fill a certain position on an Axis - int fill(double x, double y, double weight) - { + int fill(double x, double y, double weight) { /// Filling the total distribution - _dbn.fill(x, y, weight); + _dbn.fill(x, y, weight); /// Filling a bin if the coordinates point to one. int index = getBinIndex(x, y); if(index != -1) _bins[index].fill(x, y, weight); - - /// If coordinates point outside any of the bins and - /// and the outflows were properly set (i.e. we are dealing + + /// If coordinates point outside any of the bins and + /// and the outflows were properly set (i.e. we are dealing /// with a grid), fill a proper outflow. else if(_outflows.size() == 8) _fillOutflows(x, y, weight); @@ -157,12 +166,15 @@ return index; } + /// @brief Bin merging /// Try to merge a certain amount of bins + /// @todo This is far too big to be inline: move it to the .cc void mergeBins(size_t from, size_t to) { HistoBin2D& start = bin(from); HistoBin2D& end = bin(to); HistoBin2D temp = start; + /// @todo Yuck! start.isGhost() = true; if (start.midpoint().first > end.midpoint().first || @@ -181,6 +193,9 @@ bin(!_binHashSparse.first[y].second[x].first).isGhost()) { temp += bin(_binHashSparse.first[y].second[x].first); + /// @todo This sort of setting via a reference is quite confusing -- since Axis2D is a friend, + /// just use the _isGhost member. Or, better IMO, do all the "ghost" bookkeeping purely on + /// the axis and avoid storing an axis implementation feature on *all* the bins. bin(_binHashSparse.first[y].second[x].first).isGhost() = true; } } @@ -194,11 +209,27 @@ } + /// Reset the axis statistics + void reset() + { + _dbn.reset(); + for (size_t i = 0; i < _bins.size(); ++i) { + _bins[i].reset(); + } + } + + //@} + + + /// @name Accessors + //@{ + /// Get the total number of bins + /// @todo Can't this just be numBins? const size_t numBinsTotal() const { return _bins.size(); } - + /// Get the number of bins along X axis const size_t numBinsX() const { return _binHashSparse.second.size()/2; @@ -215,24 +246,22 @@ return _lowEdgeX; } - /// Get the value of the highest x-edge on the axis const double highEdgeX() const { return _highEdgeX; } - /// Get the value of the lowest y-edge on the axis const double lowEdgeY() const { return _lowEdgeY; } - /// Get the value of the highest y-edge on the axis const double highEdgeY() const { return _highEdgeY; } + /// Get the bins (non-const version) Bins& bins() { return _bins; @@ -244,10 +273,16 @@ } /// Get the outflows (const version) + vector<vector<Dbn2D> >& outflows() { + return _outflows; + } + + /// Get the outflows (const version) const vector<vector<Dbn2D> >& outflows() const { return _outflows; } + /// Get the bin with a given index (non-const version) BIN& bin(size_t index) { if (index >= _bins.size()) throw RangeError("Bin index out of range."); @@ -275,6 +310,7 @@ else throw RangeError("No bin found!!"); } + /// Get a bin at given coordinates (non-const version) BIN& binByCoord(pair<double, double>& coords) { return binByCoord(coords.first, coords.second); @@ -286,16 +322,17 @@ } - /// Get a total distribution (non-const version) + /// Get the total distribution (non-const version) Dbn2D& totalDbn() { return _dbn; } - /// Get a total distribution (const version) + /// Get the total distribution (const version) const Dbn2D& totalDbn() const { return _dbn; } + /// @brief Bin index finder /// /// Looks through all the bins to see which one contains the point of @@ -309,21 +346,18 @@ return -1; } + //@} - /// Reset the axis statistics - void reset() - { - _dbn.reset(); - for (size_t i = 0; i < _bins.size(); ++i) { - _bins[i].reset(); - } - } + /// @name Scaling operations + //@{ - /// @brief Axis scaler - /// Scales the axis with a given scale. If no scale is given, assumes - /// identity transform. - void scaleXY(double scaleX = 1.0, double scaleY = 1.0) { + /// @brief Rescale the axes + /// + /// Scales the axis with a given scale. + /// @todo This is far too big to be inline: move it to the .cc + /// @todo Add a specific check for a scaling of 1.0, to avoid doing work when no scaling is wanted. + void scaleXY(double scaleX, double scaleY) { // Two loops are put on purpose, just to protect // against improper _binHashSparse for (size_t i = 0; i < _binHashSparse.first.size(); ++i) { @@ -363,6 +397,7 @@ /// Scales the bin weights + /// @todo This is, I think, a bit too big to be inline: move it to the .cc void scaleW(double scalefactor) { _dbn.scaleW(scalefactor); for(size_t i = 0; i < _outflows.size(); ++i) { @@ -370,11 +405,12 @@ _outflows[i][j].scaleW(scalefactor); } } - + /// @todo Use foreach for situations like this for (size_t i = 0; i < _bins.size(); ++i) { _bins[i].scaleW(scalefactor); } } + //@} @@ -441,8 +477,9 @@ _outflows[7].resize(_binHashSparse.first.size()); } - + /// Outflow filler + /// @todo This is far too big to be inline: move it to the .cc void _fillOutflows(double x, double y, double weight) { if(x < _lowEdgeX && y > _highEdgeY) _outflows[0][0].fill(x, y, weight); else if(x > _lowEdgeX && x < _highEdgeX && y > _highEdgeY) @@ -472,12 +509,13 @@ } /// @brief 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 _isGrid() a very, very fast function. - /// @todo Is the name appropriate? Should it be private? + /// @todo This is far too big to be inline: move it to the .cc bool _isGrid() const { /// Check if the number of edges parallel to X axis @@ -528,6 +566,8 @@ /// to be needed, as edges are not generated by a user. /// /// This is also a perfect place to parallelize, if required. + /// + /// @todo This is far too big to be inline: move it to the .cc bool _validateEdge(vector<Segment>& edges) { /// Setting the return variable. True means that no cuts were detected. bool ret = true; @@ -566,6 +606,9 @@ /// 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. + /// + /// @todo This is far too big to be inline: move it to the .cc + /// @todo Does this actually have to be a member function? Isn't it just a function? size_t _binaryS(Utils::cachedvector<EdgeCollection>& toSearch, double value, size_t lower, size_t higher) { // Just a check if such degenerate situation happens @@ -602,6 +645,9 @@ /// 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. + /// + /// @todo Explain what "cuts" are -- this is not obvious + /// @todo This is far too big to be inline: move it to the .cc bool _findCutsX(Segment& edge) { // Look up the limits of search in the _binHashSparse // structure. We are not interested in the vertical edges @@ -632,6 +678,13 @@ /// @brief Function that finds cuts of vertical edges /// /// For a detailed description, see the documentation for _findCutsX(). + /// + /// @todo Explain what "cuts" are -- this is not obvious + /// + /// @todo This is far too big to be inline: move it to the .cc + /// + /// @todo Can the code for "cut" finding be abstracted to work in both + /// directions, to avoid writing (and maintaining) it twice? 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()); @@ -655,6 +708,8 @@ /// had failed the check. If this is needed such additional information /// can be readily implemented. void _dropEdge(vector<Segment>& edges) { + /// @todo WTF?! Finish what you start! Does this actually need to exist? + assert(0 && "Unimplemented :("); std::cerr << "A set of edges was dropped." << endl; } @@ -665,6 +720,8 @@ /// to properly add a bin. Specifially edges are added to /// the edge cache (_binHashSparse) and a bin is created from /// those edges. + /// + /// @todo This is far too large to be inline: move to the .cc void _addEdge(vector<Segment> edges, pair<Utils::cachedvector<EdgeCollection>, Utils::cachedvector<EdgeCollection> >& binHash, bool addBin = true) { // Check if there was no mistake made when adding segments to a vector. @@ -745,6 +802,8 @@ /// 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. + /// + /// @todo This is arguably too large to be inline: move to the .cc? void _fixOrientation(Segment& edge) { if (fuzzyEquals(edge.first.first, edge.second.first)) { if (edge.first.second > edge.second.second) { @@ -769,6 +828,8 @@ /// /// It accepts two extremal points of a rectangle (top-right and /// bottom-left) as input. + /// + /// @todo This is far too large to be inline: move to the .cc void _mkAxis(const vector<Segment>& binLimits) { // For each of the rectangles @@ -814,6 +875,8 @@ /// 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. + /// + /// @todo This is too large to be inline: move to the .cc void _regenDelimiters() { double highEdgeX = numeric_limits<double>::min(); double highEdgeY = numeric_limits<double>::min(); @@ -834,18 +897,24 @@ _highEdgeY = highEdgeY; } + private: /// Bins contained in this histogram Bins _bins; - /// Underflow distribution + /// Overflow distributions + /// + /// @todo Explain how the vector structure works! vector<vector<Dbn2D> > _outflows; /// The total distribution + /// + /// @todo This needs to be a templated DBN type Dbn2D _dbn; /// @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. Modified: trunk/include/YODA/Bin2D.h ============================================================================== --- trunk/include/YODA/Bin2D.h Thu Aug 18 11:10:52 2011 (r274) +++ trunk/include/YODA/Bin2D.h Thu Aug 18 12:15:53 2011 (r275) @@ -218,16 +218,25 @@ } //@} - + /// @name _isGhost accessor + /// @todo Improve Doxygen description -- it needs to actually explain what this *means* + /// @todo IMO this would be better implemented as a bookkeeping device on Axis2D, storing + /// a list of bin IDs to not write out -- it's ~purely a persistency trick, right? At the + /// moment we're storing an extra bool on every bin for a feature which will not appear in + /// > 99% of cases. //@{ /// non-const version + /// + /// @todo Improve Doxygen description (including Capitalising like proper text!) + /// @todo What is the point of this method? bool& isGhost() { return _isGhost; } /// const version + /// @todo Improve Doxygen description (including Capitalising like proper text!) const bool isGhost() const { return _isGhost; } Modified: trunk/include/YODA/Histo2D.h ============================================================================== --- trunk/include/YODA/Histo2D.h Thu Aug 18 11:10:52 2011 (r274) +++ trunk/include/YODA/Histo2D.h Thu Aug 18 12:15:53 2011 (r275) @@ -72,7 +72,7 @@ /// @brief State-setting constructor /// Mainly intended for internal persistency use. - Histo2D(const std::vector<HistoBin2D>& bins, + Histo2D(const std::vector<HistoBin2D>& bins, const std::vector<std::vector<Dbn2D> >& outflows, const Dbn2D& totalDbn, const std::string& path="", const std::string& title="") @@ -348,9 +348,9 @@ /// @todo Create x-wise and y-wise conversions to Profile1D -- ignore outflows for now, but mark as such /*Profile1D mkProfileX() { - throw Exception("To implement!"); - if(!_axis._isGrid()) throw GridError("Profile1D cannot be made from a histogram that is not a grid!"); - + throw Exception("To implement!"); + if (!_axis._isGrid()) throw GridError("Profile1D cannot be made from a histogram that is not a grid!"); + //Profile1D ret; return Profile1D(); }
More information about the yoda-svn mailing list |