casa
$Rev:20696$
|
00001 //# TileStepper.h: Steps a cursor optimally through a tiled Lattice 00002 //# Copyright (C) 1997,1998,1999,2000 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id: TileStepper.h 20652 2009-07-06 05:04:32Z Malte.Marquarding $ 00027 00028 #ifndef LATTICES_TILESTEPPER_H 00029 #define LATTICES_TILESTEPPER_H 00030 00031 //# Includes 00032 #include <casa/aips.h> 00033 #include <lattices/Lattices/LatticeNavigator.h> 00034 #include <lattices/Lattices/LatticeIndexer.h> 00035 #include <casa/Arrays/IPosition.h> 00036 00037 00038 namespace casa { //# NAMESPACE CASA - BEGIN 00039 00040 // <summary> 00041 // traverse a tiled Lattice optimally with a tile cursor 00042 // </summary> 00043 00044 // <use visibility=export> 00045 00046 // <reviewed reviewer="Peter Barnes" date="1999/10/30" tests="tTileStepper.cc" demos=""> 00047 // </reviewed> 00048 00049 // <prerequisite> 00050 // <li> <linkto class=LatticeNavigator> LatticeNavigator </linkto> 00051 // </prerequisite> 00052 00053 // <etymology> 00054 // TileStepper is used to step optimally through a tiled Lattice. 00055 // </etymology> 00056 00057 // <synopsis> 00058 // When you wish to traverse a Lattice (say, a PagedArray or an Image) you 00059 // will usually create a LatticeIterator. Once created, you may attach a 00060 // LatticeNavigator to the iterator. A TileStepper is a concrete class 00061 // derived from the abstract LatticeNavigator that allows you to step 00062 // through the Lattice in a way that will minimize the amount of cache 00063 // memory consumed and maximize the speed. 00064 // <p> 00065 // Some Lattices (in particular PagedArrays) are stored (on disk) in 00066 // tiles. For an N-dimensional Lattice a tile is an N-dimensional 00067 // subsection with fewer elements along each axis. For example a Lattice of 00068 // shape [512,512,4,32] may have a tile shape of [32,16,4,16], and there 00069 // will be 16*32*1*2 (=1024) tiles in the entire Lattice. To allow efficient 00070 // access of the data in a Lattice some tiles are cached in memory. As each 00071 // tile may consume a fair bit of memory (in this example 128kBytes, 00072 // assuming each element consumes 4 bytes), it is desirable to minimise the 00073 // number of tiles held in the cache. But it is also desirable to minimise 00074 // the number of times a tiles must be read into or written from the 00075 // cache as this may require a time consuming operation like disk I/O. 00076 // <p> 00077 // TileStepper steps through a lattice in a tile-by-tile way. 00078 // This means that the cache contains 1 tile only and that a tile is 00079 // accessed only once. 00080 // It should be clear that traversing a lattice in this way cannot 00081 // be used if an entire vector or plane is needed. It is, however, very 00082 // well suited for purposes like initialising a lattice, where the 00083 // order in which the lattice pixels are accessed is not important. 00084 // <p> 00085 // In constructing a TileStepper, you specify the Lattice shape, the 00086 // tile shape and optionally the axis path. The axis path defines the order 00087 // in which the tiles are fetched from the lattice. Default is the natural 00088 // order (thus x-axis in the inner loop). 00089 // <br>It is possible to use the function <src>subSection</src> to 00090 // traverse only a subsection of the lattice. 00091 // <p> 00092 // The cursor position can be incremented or decremented to retrieve the next 00093 // or previous tile in the Lattice. The position of the next tile in the 00094 // Lattice will depend on the tile shape, and is described above. 00095 // <br>Note that the cursor shape does not need to be constant when iterating 00096 // through the lattice. If the lattice shape is not an integer multiple of 00097 // the tile shape, the cursor will be smaller on the edges of the lattice. 00098 // </synopsis> 00099 00100 // <example> 00101 // This example initializes a lattice with the given value. 00102 // <srcblock> 00103 // void init (Lattice<Complex>& cArray, Complex value) 00104 // { 00105 // const IPosition latticeShape = cArray.shape(); 00106 // const IPosition tileShape = cArray.niceCursorShape(); 00107 // TileStepper tsx(latticeShape, tileShape); 00108 // LatticeIterator<Complex> lix(cArray, tsx); 00109 // for (lix.reset();!lix.atEnd();lix++) 00110 // lix.woCursor() = value; 00111 // } 00112 // } 00113 // </srcblock> 00114 // Note that a TileStepper is the default navigator for an iterator. 00115 // So the code above could be made simpler like shown below. 00116 // Also note that this example is a bit artificial, because the Lattice::set() 00117 // function should be used to initialize a lattice. 00118 // <srcblock> 00119 // void init (Lattice<Complex>& cArray, Complex value) 00120 // { 00121 // LatticeIterator<Complex> lix(cArray); 00122 // for (lix.reset();!lix.atEnd();lix++) 00123 // lix.woCursor() = value; 00124 // } 00125 // } 00126 // </srcblock> 00127 // </example> 00128 00129 // <motivation> 00130 // This class makes it possible to traverse a lattice in the optimal way. 00131 // </motivation> 00132 // 00133 //# <todo asof="1997/11/21"> 00134 //# <li> 00135 //# </todo> 00136 00137 00138 class TileStepper: public LatticeNavigator 00139 { 00140 public: 00141 00142 // Construct a TileStepper by specifying the Lattice shape, a tile shape, 00143 // and an optional axis path (default is natural order). 00144 // Is is nearly always advisable to make the tileShape identical 00145 // to the Lattice tileShape. This can be obtained by 00146 // <src>lat.niceCursorShape()</src> where <src>lat</src> is 00147 // a Lattice object. 00148 // <group> 00149 TileStepper (const IPosition& latticeShape, 00150 const IPosition& tileShape); 00151 TileStepper (const IPosition& latticeShape, 00152 const IPosition& tileShape, 00153 const IPosition& axisPath); 00154 // </group> 00155 00156 // Copy constructor (copy semantics). 00157 TileStepper (const TileStepper& other); 00158 00159 ~TileStepper(); 00160 00161 // Assignment (copy semantics). 00162 TileStepper& operator= (const TileStepper& other); 00163 00164 // Increment operator (postfix or prefix version) - move the cursor 00165 // forward one step. Returns True if the cursor was moved. 00166 virtual Bool operator++(int); 00167 00168 // Decrement operator (postfix or prefix version) - move the cursor 00169 // backwards one step. Returns True if the cursor was moved. 00170 virtual Bool operator--(int); 00171 00172 // Function to move the cursor to the beginning of the Lattice. Also 00173 // resets the number of steps (<src>nsteps</src> function) to zero. 00174 virtual void reset(); 00175 00176 // Function which returns "True" if the cursor is at the beginning of the 00177 // Lattice, otherwise, returns "False" 00178 virtual Bool atStart() const; 00179 00180 // Function which returns "True" if an attempt has been made to increment 00181 // the cursor beyond the end of the Lattice. 00182 virtual Bool atEnd() const; 00183 00184 // Function to return the number of steps (increments & decrements) taken 00185 // since construction (or since last reset). This is a running count of 00186 // all cursor movement (operator++ or operator--), even though 00187 // N-increments followed by N-decrements will always leave the cursor in 00188 // the original position. 00189 virtual uInt nsteps() const; 00190 00191 // Function which returns the current position of the beginning of the 00192 // cursor. The <src>position</src> function is relative to the origin 00193 // in the main Lattice. 00194 virtual IPosition position() const; 00195 00196 // Function which returns the current position of the end of the 00197 // cursor. The <src>endPosition</src> function is relative the origin 00198 // in the main Lattice. 00199 virtual IPosition endPosition() const; 00200 00201 // Functions which return the shape of the Lattice being iterated 00202 // through. <src>latticeShape</src> always returns the shape of the main 00203 // Lattice while <src>subLatticeShape</src> returns the shape of any 00204 // sub-Lattice defined using the <src>subSection</src> function. 00205 // <group> 00206 virtual IPosition latticeShape() const; 00207 virtual IPosition subLatticeShape() const; 00208 // </group> 00209 00210 // Function which returns the shape of the cursor. This always includes 00211 // all axes (i.e. it includes degenerates axes) 00212 virtual IPosition cursorShape() const; 00213 00214 // Function which returns the axes of the cursor. 00215 virtual IPosition cursorAxes() const; 00216 00217 // Function which returns the shape of the "tile" the cursor will iterate 00218 // through before moving onto the next tile. 00219 IPosition tileShape() const; 00220 00221 // Function which returns "True" if the increment/decrement operators have 00222 // moved the cursor position such that part of the cursor beginning or end 00223 // is hanging over the edge of the Lattice. This always returns False. 00224 virtual Bool hangOver() const; 00225 00226 // Functions to specify a "section" of the Lattice to step over. A section 00227 // is defined in terms of the Bottom Left Corner (blc), Top Right Corner 00228 // (trc), and step size (inc), on ALL of its axes, including degenerate 00229 // axes. The step size defaults to one if not specified. 00230 // <group> 00231 virtual void subSection (const IPosition& blc, const IPosition& trc); 00232 virtual void subSection (const IPosition& blc, const IPosition& trc, 00233 const IPosition& inc); 00234 // </group> 00235 00236 // Return the bottom left hand corner (blc), top right corner (trc) or 00237 // step size (increment) used by the current sub-Lattice. If no 00238 // sub-Lattice has been defined (with the <src>subSection</src> function) 00239 // these functions return blc=0, trc=latticeShape-1, increment=1, ie. the 00240 // entire Lattice. 00241 // <group> 00242 virtual IPosition blc() const; 00243 virtual IPosition trc() const; 00244 virtual IPosition increment() const; 00245 // </group> 00246 00247 // Return the axis path. 00248 virtual const IPosition& axisPath() const; 00249 00250 // Function which returns a pointer to dynamic memory of an exact copy 00251 // of this instance. The pointer returned by this function must 00252 // be deleted externally. 00253 virtual LatticeNavigator* clone() const; 00254 00255 // Function which checks the internal data of this class for correct 00256 // dimensionality and consistant values. 00257 // Returns True if everything is fine otherwise returns False 00258 virtual Bool ok() const; 00259 00260 // Calculate the cache size (in tiles) for this type of access to a lattice 00261 // in the given row of the tiled hypercube. 00262 virtual uInt calcCacheSize (const IPosition& cubeShape, 00263 const IPosition& tileShape, 00264 uInt maxCacheSize, uInt bucketSize) const; 00265 00266 private: 00267 // Prevent the default constructor from being used. 00268 TileStepper(); 00269 00270 00271 IPosition itsBlc; //# Bottom Left Corner 00272 IPosition itsTrc; //# Top Right Corner 00273 IPosition itsInc; //# Increment 00274 LatticeIndexer itsSubSection; //# The current subsection 00275 LatticeIndexer itsTiler; //# For moving between tiles 00276 IPosition itsTilerCursorPos; //# The current position of the iterator 00277 IPosition itsTileShape; //# The tile shape (= itsTiler cursor shape) 00278 IPosition itsAxisPath; //# Path for traversing 00279 IPosition itsCurBlc; //# Blc of the current position. 00280 IPosition itsCurTrc; //# Trc of the current position. 00281 uInt itsNsteps; //# The number of iterator steps taken so far 00282 Bool itsEnd; //# Is the cursor beyond the end? 00283 Bool itsStart; //# Is the cursor at the beginning? 00284 }; 00285 00286 00287 00288 } //# NAMESPACE CASA - END 00289 00290 #endif