casa
$Rev:20696$
|
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