casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
TileStepper.h
Go to the documentation of this file.
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