casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
LatticeNavigator.h
Go to the documentation of this file.
00001 //# LatticeNavigator.h: Abstract base class to steer lattice iterators
00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999
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: LatticeNavigator.h 20652 2009-07-06 05:04:32Z Malte.Marquarding $
00027 
00028 #ifndef LATTICES_LATTICENAVIGATOR_H
00029 #define LATTICES_LATTICENAVIGATOR_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 
00035 namespace casa { //# NAMESPACE CASA - BEGIN
00036 
00037 //# Forward Declarations
00038 class IPosition;
00039 class ROTiledStManAccessor;
00040 
00041 
00042 // <summary>
00043 // Abstract base class to steer lattice iterators.
00044 // </summary>
00045 
00046 // <use visibility=local>
00047 
00048 // <reviewed reviewer="Peter Barnes" date="1999/10/30" tests="tLatticeStepper.cc">
00049 // </reviewed>
00050 
00051 // <prerequisite>
00052 //   <li> <linkto class=LatticeIterator>LatticeIterator</linkto>
00053 //   <li> <linkto class=Lattice>Lattice</linkto>
00054 // </prerequisite>
00055 
00056 // <etymology>
00057 // Lattice iteration can proceed with a number of different strategies -
00058 // all of which answer the question:  where do I go from here?
00059 // You could travel through by making calculations on the lattice subscripts,
00060 // viewing ascending planes in an image cube, for example, or you could 
00061 // travel through by making calculations on the data, viewing small 
00062 // subimage planes in order of descending brightness over the whole cube.  
00063 // Concrete classes derived  from this base class implement different
00064 // navigation strategies - but they are all "navigators".
00065 // </etymology>
00066 
00067 // <synopsis> 
00068 // This abstract base class defines the interface for objects which generate
00069 // positions for LatticeIterators. This position is not just a single point
00070 // in the Lattice but a region or "cursor" that is moved through the
00071 // Lattice. The LatticeIterator classes actually retrieve the data in the
00072 // cursor from the Lattice. The class decribed here (and those derived from it)
00073 // are responsible for moving the cursor to the next position and determining
00074 // its shape.
00075 //
00076 // There may eventually be a large collection of tools for traversing
00077 // Lattices.  At this writing (December 1999) there are three concrete
00078 // classes derived from LatticeNavigator: 
00079 // <linkto class="LatticeStepper">LatticeStepper</linkto>,
00080 // <linkto class="TiledLineStepper">TiledLineStepper</linkto>, and
00081 // <linkto class="TileStepper">TileStepper</linkto>. 
00082 //
00083 // The <src>LatticeStepper</src> class moves through a Lattice in fixed
00084 // steps defined by the user specified cursor, incrementing to the next
00085 // portion of the Lattice with each step, and wrapping around axes as
00086 // needed.  Other position generators might follow the brightest pixel,
00087 // traverse a number of predefined subregions, or change size automatically
00088 // when near the edges.
00089 //
00090 // The <src>TiledLineStepper</src> class moves a Vector cursor through a
00091 // Lattice, until all the lines in the set of tiles along the specified
00092 // axis have been exhausted. It then moves to the next set of tiles. This is
00093 // a memory-efficient way to move a Vector cursor through a Lattice.
00094 //
00095 // The most important member functions of this class are those which move
00096 // the cursor to the next position. These are the <src>operator++</src> and
00097 // <src>operator--</src> member functions, (in postfix and prefix forms). 
00098 //
00099 // The cursor shape need not be constant as it moves through the Lattice,
00100 // but may change depending on its current position. For the LatticeStepper
00101 // and TiledLineStepper classes , however, the cursor shape is constant
00102 // as it steps through the Lattice.
00103 //
00104 // It is not possible to randomly move the cursor to an arbitrary place in
00105 // the Lattice, although the cursor can be moved to the starting position at
00106 // any time using the <src>reset</src> member function.
00107 //
00108 // The position of the cursor can be queried at any time using the
00109 // <src>position</src> member function. This gives the position of the
00110 // bottom left hand corner of the cursor. The position of the top right hand
00111 // corner of the cursor is obtained using the <src>endPosition</src> member
00112 // function, and the current cursor shape is obtained using the
00113 // <src>cursorShape</src> member function. Note that the endPosition
00114 // does not take an overhang into account.
00115 //
00116 // It is possible that for some positions of the cursor, part of it will
00117 // "hang over" the edge of the Lattice. When this occurs the
00118 // <src>hangOver</src> member function will return True. This will occur
00119 // with a LatticeStepper if the Lattice shape is not a multiple of the
00120 // cursor shape. Hangover cannot occur with the TiledLineStepper as the length
00121 // of the Vector cursor is defined by the Lattice Shape.
00122 //
00123 // It may be possible (depending on the concrete LatticeNavigator actually
00124 // used) to specify that only a region of the Lattice (defined by a top
00125 // right hand corner, bottom left hand corner, and step increment) be
00126 // traversed by the LatticeNavigator. This is done using the
00127 // <src>subSection</src> member function. At any time the region can be
00128 // redefined by calling the <src>subSection</src> function again. This
00129 // replaces the previously defined region with the new one.
00130 //
00131 // Using the subSection function always sets the cursor position to the
00132 // origin of the currently defined sub-lattice. This is a backdoor way to
00133 // move the cursor to random locations in the Lattice.
00134 //
00135 // It is an error to define a sub-lattice that is bigger than the current
00136 // Lattice. If using a LatticeStepper it may also be necessary to resize the
00137 // cursor (using the <src>setCursorShape</src> member function) prior to
00138 // calling the subSection function as the cursor cannot be bigger than the
00139 // sub-Lattice on any axis.
00140 //
00141 // The arguments (<src>trc</src>, <src>blc</src> and <src>inc</src>)
00142 // to the <src>subSection</src> function are always
00143 // relative to the main Lattice. This is also true of the <src>position</src>
00144 // and <src>endPosition</src> functions. To get the position of the cursor
00145 // relative to the currently defined sub-Lattice use the
00146 // <src>relativePosition</src> and <src>relativeEndPosition</src> member
00147 // functions.
00148 //
00149 // Many of the LatticeIterator member functions are directly forwarded to
00150 // virtual functions of this class, and classes derived from it. For
00151 // instance, LatticeIterator<T>::operator++() calls
00152 // LatticeIterInterface->operator++() which calls
00153 // LatticeNavigator->operator++() which might resolve to
00154 // LatticeStepper->operator++(). Other functions like this are documented in
00155 // the <linkto class="LatticeIterator">LatticeIterator</linkto> class.
00156 // </synopsis> 
00157 
00158 // <example>
00159 // See the examples in the 
00160 // <linkto class="LatticeStepper">LatticeStepper</linkto> class, the 
00161 // <linkto class="TiledLineStepper">TiledLineStepper</linkto> class, and the
00162 // <linkto class="TileStepper">TileStepper</linkto> class.
00163 // </example>
00164 //
00165 // <motivation>
00166 // Iterator classes are quite common in C++.  What's novel about the design
00167 // which includes this class is the separation of iterator mechanisms from
00168 // traversal strategy.  The iterator provides a lot of functionality: it
00169 // provides a cursor, damage notification and tracking, and reading and
00170 // writing to the underlying data structure.  Traversal strategies can and
00171 // should be isolated from these things. Because every LatticeIterator
00172 // uses a Navigator, it gets the benefits of a derived concrete navigator
00173 // without getting involved in its mechanism.
00174 // </motivation>
00175 //
00176 // <todo asof="1997/31/01">
00177 //  <li> Think about how to implement Navigators which can traverse
00178 //  arbitrary shaped regions.
00179 // </todo>
00180 
00181 
00182 class LatticeNavigator {
00183 public:
00184   // Default constructor.
00185   LatticeNavigator()
00186     {;}
00187 
00188   // Copy constructor.
00189   LatticeNavigator (const LatticeNavigator&)
00190     {;}
00191 
00192   // Assignment.
00193   LatticeNavigator& operator= (const LatticeNavigator&)
00194     { return *this; }
00195 
00196   // A virtual destructor.  A virtual is needed to ensure that derived
00197   // classes accessed through pointers to a LatticeNavigator will scope
00198   // their destructor to the derived class destructor.
00199   virtual ~LatticeNavigator();
00200 
00201   // Increment operator - increment the cursor to the next position. The
00202   // implementation of the prefix operator calls the postfix one.
00203   // <group>
00204   virtual Bool operator++(int) = 0;
00205   Bool operator++();
00206   // </group>
00207 
00208   // Decrement operator - decrement the cursor to the previous position. The
00209   // implementation of the prefix operator calls the postfix one.
00210   // <group>
00211   virtual Bool operator--(int) = 0;
00212   Bool operator--();
00213   // </group>
00214 
00215   // Function to reset the cursor to the beginning of the Lattice and
00216   // reset the number of steps taken to zero.
00217   virtual void reset() = 0;
00218 
00219   // Function which returns "True" if the cursor is at the beginning of the
00220   // Lattice, otherwise, returns "False"
00221   virtual Bool atStart() const = 0;
00222 
00223   // Function which returns "True" if an attempt has been made to increment
00224   // the cursor beyond the end of the Lattice.
00225   virtual Bool atEnd() const = 0;
00226 
00227   // Function to return the number of steps (increments or decrements) taken
00228   // since construction (or since last reset).  This is a running count of
00229   // all cursor movement since doing N increments followed by N decrements
00230   // does not necessarily put the cursor back at the origin of the Lattice.
00231   virtual uInt nsteps() const = 0;
00232 
00233   // Functions which return the current position of the beginning of the
00234   // cursor. The <src>position</src> function is relative to the origin in
00235   // the main Lattice and the <src>relativePosition</src> function is
00236   // relative to the origin and increment used in the sub-Lattice (defined
00237   // using the <src>subSection</src> function).
00238   // The returned IPosition will have the same number of axes as
00239   // the underlying Lattice.
00240   // <br>The default implementation of the <src>relativePosition</src>
00241   // function returns <src>(position() - blc()) / increment()</src>.
00242   // <group>
00243   virtual IPosition position() const = 0;
00244   virtual IPosition relativePosition() const;
00245   // </group>
00246 
00247   // Functions which return the current position of the end of the
00248   // cursor. The <src>endPosition</src> function is relative to the origin in
00249   // the main Lattice and the <src>relativeEndPosition</src> function is
00250   // relative to the origin and increment used in the sub-Lattice (defined
00251   // using the <src>subSection</src> function).
00252   // The returned IPosition will have the same number of axes as
00253   // the underlying Lattice.
00254   // <note role=caution> It returns the end position in the lattice and
00255   // does not take overhang into account. </note>
00256   // <br>The default implementation of the <src>relativeEndPosition</src>
00257   // function returns <src>(endPosition() - blc()) / increment()</src>.
00258   // <group>
00259   virtual IPosition endPosition() const = 0;
00260   virtual IPosition relativeEndPosition() const;
00261   // </group>
00262   
00263   // Functions which return the shape of the Lattice being iterated
00264   // through. <src>latticeShape</src> always returns the shape of the main
00265   // Lattice while <src>subLatticeShape</src> returns the shape of any
00266   // sub-Lattice defined using the <src>subSection</src> function.  In the
00267   // default implementation of this class it is not possible to use the
00268   // <src>subsection</src> function (it throws an exception) so the default
00269   // implementation of the <src>subLatticeShape</src> function calls the
00270   // <src>latticeShape</src> function.  The returned IPosition will always
00271   // have the same number of axes as the underlying Lattice.
00272   // <group>
00273   virtual IPosition latticeShape() const = 0;
00274   virtual IPosition subLatticeShape() const;
00275   // </group>
00276 
00277   // Function which returns the current shape of the cursor which is
00278   // iterating through the Lattice.  The returned IPosition will have the
00279   // same number of axes as the underlying Lattice.
00280   virtual IPosition cursorShape() const = 0;  
00281 
00282   // Function which returns the axes of the cursor.
00283   // These are the axes which should not be removed by the
00284   // iterator functions <src>vectorCursor()</src>, etc..
00285   virtual IPosition cursorAxes() const = 0;
00286 
00287   // Function which returns "True" if the increment/decrement operators have
00288   // moved the cursor position such that part of the cursor is hanging over
00289   // the edge of the Lattice. This function may always return a value of
00290   // "False" for some iteration methods that do not move the cursor past the
00291   // Lattice boundaries.
00292   virtual Bool hangOver() const = 0;
00293 
00294   // Functions which return the "bottom left corner" and the "top right corner"
00295   // of the cursor that does not hangover. Use these functions to extract the
00296   // valid part of the cursor when the hangover member function is true. If
00297   // there is no hangover then hangOverBLC returns an IPosition of zero and
00298   // hangOverTRC() returns the cursorShape - 1;
00299   // <group>
00300   virtual IPosition hangOverBlc() const;
00301   virtual IPosition hangOverTrc() const;
00302   // </group>
00303 
00304 
00305   // Function to specify a "section" of the Lattice to Navigate over. A
00306   // section is defined in terms of the Bottom Left Corner (blc), Top Right
00307   // Corner (trc), and step size (inc), on ALL of its axes, including
00308   // degenerate axes. The step size defaults to one if not specified.  
00309   // In the default implementation of this class subsectioning is not
00310   // supported and using the <src>subsection</src> function will throw an
00311   // exception (AipsError).
00312   // <group>
00313   virtual void subSection(const IPosition& blc, const IPosition& trc);
00314   virtual void subSection(const IPosition& blc, const IPosition& trc, 
00315                           const IPosition& inc);
00316   // </group>
00317 
00318   // Return the bottom left hand corner (blc), top right corner (trc) or
00319   // step size (increment) used by the current sub-Lattice. In the default
00320   // implementation of this class sub-sectioning is not supported and these
00321   // functions will always return blc=0, trc=latticeShape-1, increment=1,
00322   // ie. the entire Lattice.
00323   // <group>
00324   virtual IPosition blc() const;
00325   virtual IPosition trc() const;
00326   virtual IPosition increment() const;
00327   // </group>
00328 
00329   // Return the axis path.
00330   // See <linkto class=LatticeStepper>LatticeStepper</linkto> for a
00331   // description and examples.
00332   virtual const IPosition& axisPath() const = 0;
00333 
00334   // Calculate the cache size (in tiles) for this type of access to a lattice
00335   // in the given row of the tiled hypercube.
00336   // A zero bucket size indicates that the data are not tiled, but in memory.
00337   // Then a cache size of 0 is returned.
00338   virtual uInt calcCacheSize (const IPosition& cubeShape,
00339                               const IPosition& tileShape,
00340                               uInt maxCacheSize, uInt bucketSize) const = 0;
00341 
00342   // Function which returns a pointer to dynamic memory of an exact copy 
00343   // of this LatticeNavigator. It is the responsibility of the caller to
00344   // release this memory. 
00345   virtual LatticeNavigator* clone() const = 0;
00346 
00347   // Function which checks the internals of the class for consistency.
00348   // Returns True if everything is fine otherwise returns False. The default
00349   // implementation always returns True.
00350   virtual Bool ok() const;
00351 };
00352 
00353 
00354 inline Bool LatticeNavigator::operator++()
00355 {
00356   return operator++(0);
00357 }
00358 inline Bool LatticeNavigator::operator--()
00359 {
00360   return operator--(0);
00361 }
00362 
00363 
00364 
00365 } //# NAMESPACE CASA - END
00366 
00367 #endif