casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LatticeIterator.h
Go to the documentation of this file.
1 //# LatticeIterator.h: Iterators for Lattices: readonly or read/write
2 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2003
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef LATTICES_LATTICEITERATOR_H
29 #define LATTICES_LATTICEITERATOR_H
30 
31 //# Includes
32 #include <casacore/casa/aips.h>
37 
38 namespace casacore { //# NAMESPACE CASACORE - BEGIN
39 
40 //# Forward Declarations
41 class IPosition;
42 class LatticeNavigator;
43 
44 // <summary>
45 // A readonly iterator for Lattices
46 // </summary>
47 
48 // <use visibility=export>
49 
50 // <reviewed reviewer="Peter Barnes" date="1999/10/30" tests="tLatticeIterator.cc">
51 // </reviewed>
52 
53 // <prerequisite>
54 // <li> <linkto class="Lattice">Lattice</linkto>
55 // <li> <linkto class="LatticeNavigator">LatticeNavigator</linkto>
56 // <li> <linkto class="Array">Array</linkto>
57 // </prerequisite>
58 
59 // <etymology>
60 // The leading "RO" is shorthand for "readonly", which indicates that an
61 // RO_LatticeIterator is used for traversing a Lattice, examining and
62 // possibly extracting its contents, but not for modifying it.
63 // </etymology>
64 
65 // <synopsis>
66 // This class provides a convenient way to traverse any class derived from
67 // Lattice. You can iterate through the Lattice's data from "start" to "end"
68 // by calling <src>operator++</src>, and reverse direction by calling
69 // <src>operator--</src>. You can return immediately to the beginning by
70 // calling the <src>reset</src> function. The RO_LatticeIterator gives the
71 // user the opportunity to methodically walk through the data, in an
72 // efficient way.
73 // <p>
74 // The supplied <linkto class=LatticeNavigator>LatticeNavigator</linkto>
75 // determines how to step through the Lattice. It can, for instance,
76 // be line by line, but it can also be in a more complicated way.
77 // When no navigator is supplied, a default navigator will be used
78 // which steps in the optimum way.
79 // <p>
80 // A cursor (which is an <linkto class=Array>Array</linkto> object) is
81 // used to return the data for each step in the iteration process.
82 // Depending on the navigator used the cursor can have a different shape
83 // for each step of the iteration. This is especially true when the
84 // end of an axis is reached for a non-integrally fitting cursor shape.
85 // <br> The cursor() function returns an Array which has the same
86 // dimensionality as the Lattice. It is, however, also possible to get
87 // an Array with a lower dimensionality by using the correct function
88 // in the group <src>vectorCursor()</src>, <src>matrixCursor()</src>, and
89 // <src>cubeCursor()</src>. Those functions remove (some) degenerated axes
90 // resulting in a vector, matrix or cube.
91 // When, for example, a LatticeStepper with shape [64,1,1] is used, the
92 // <src>vectorCursor()</src> can be used. It will remove the degenerated
93 // axes (length 1) and return the cursor as a Vector object. Note that
94 // <src>matrixCursor()</src> cannot be used, because removing the degenerated
95 // axes results in a 1D array.
96 // <p>
97 // Generally iterators should not be long-lived objects - create new ones
98 // when needed rather than keeping one around for a long time to be
99 // reused. This is because the cache memory used by the cursor will be
100 // released when the iterator is destroyed.
101 // <p>
102 // The purpose of this class is to hide the possibly complicated
103 // implementation and structure of the Lattice classes, and allow you to
104 // iterate through a Lattice with the same ease as one iterates through a
105 // Fortran or C vector. For example, and assuming that initialization has
106 // been done properly, here's a typical 'for' loop:
107 // <srcblock>
108 // // code omitted which associates Lattice object and the iterator
109 // for (iterator.reset(); !iterator.atEnd(); iterator++) {
110 // meanValue = mean(iterator.cursor());
111 // }
112 // </srcblock>
113 // The iterator's <src>cursor()</src> member function returns a reference to
114 // that part of the Lattice data which is presently "seen" by the
115 // LatticeIterator.
116 // <p>
117 // Before explaining the initialization of an iterator, the LatticeNavigator
118 // class must be further introduced. This is an abstract base class, from which
119 // concrete navigators are derived. After one of these is created, you
120 // attach it to the LatticeIterator, and it provides a specific technique
121 // for navigating through the Lattice. Different navigators deliver
122 // different traversal schemes. The most basic is
123 // <linkto class=LatticeStepper>LatticeStepper</linkto>, which
124 // moves a specified shape sequentially through the Lattice -- for example,
125 // by moving one plane at a time, front to back, through a cube. Another
126 // (future) navigator might be designed to move a small, 2-dimensional plane
127 // through a cube, centering each iteration on the brightest pixel of the
128 // cube's plane, and ignoring the darker regions of the cube.
129 // <p>
130 // The performance and memory usage of an iteration through a lattice
131 // (in particular through a <linkto class=PagedArray>PagedArray</linkto>)
132 // depends very heavily on the navigator used. Currently there are three
133 // navigators available:
134 // <ol>
135 // <li> <linkto class=LatticeStepper>LatticeStepper</linkto> steps
136 // sequentially through a lattice with the given cursor shape.
137 // This can use a lot of memory for the PagedArray cache.
138 // <li> <linkto class=TiledLineStepper>TiledLineStepper</linkto>
139 // steps line by line through a lattice. However, it is doing that
140 // in such a way that as few tiles as possible need to kept in the
141 // PagedArray cache. This reduces memory usage considerably.
142 // <li> <linkto class=TileStepper>TileStepper</linkto> steps tile
143 // by tile through a lattice. This navigator requires a PagedArray cache
144 // of 1 tile only. However, it can only be used for application in which
145 // the iteration order is not important (e.g. addition, determining max).
146 // </ol>
147 // The class <linkto class=LatticeApply>LatticeApply</linkto> is very useful
148 // to iterate through a Lattice while applying an algorithm. It makes it
149 // possible for the user to concentrate on the algorithm.
150 // <p>
151 // Here's a typical iterator declaration:
152 // <srcblock>
153 // RO_LatticeIterator<Float> iterator(pagedArray, stepper);
154 // </srcblock>
155 // The template identifier <src>Float</src> defines the data type of
156 // Array object that will be the iterator's cursor.
157 //<br>
158 // The <src>pagedArray</src> constructor argument names a PagedArray object,
159 // which is what the iterator will traverse. The <src>stepper</src>
160 // argument is a LatticeStepper which defines the method of iteration.
161 
162 // <example>
163 // When passed the name of a previously created PagedArray stored on disk,
164 // this function will traverse the whole array, and report the average value
165 // of all of the elements. Imagine that the filename contains a PagedArray
166 // with dimension 64 x 64 x 8.
167 // <srcblock>
168 // void demonstrateIterator (const String& filename)
169 // {
170 // PagedArray<Float> pagedArray(filename);
171 // IPosition latticeShape = pagedArray.shape();
172 // cout << "paged array has shape: " << latticeShape << endl;
173 //
174 // // Construct the iterator. since we only want to read the PagedArray,
175 // // use the read-only class, which disallows writing back to the cursor.
176 // // No navigator is given, so the default TileStepper is used
177 // // which ensures optimum performance.
178 // RO_LatticeIterator<Float> iterator(pagedArray);
179 //
180 // // Add for each iteration step the sum of the cursor elements to the sum.
181 // // Note that the cursor is an Array object and that the function sum
182 // // is defined in ArrayMath.h.
183 // Float runningSum = 0.0;
184 // for (iterator.reset(); !iterator.atEnd(); iterator++) {
185 // runningSum += sum(iterator.cursor());
186 // }
187 // cout << "average value, from demonstrateIterator: "
188 // << runningSum / latticeShape.product() << endl;
189 // }
190 // </srcblock>
191 // </example>
192 
193 // <motivation>
194 // Iterator classes are a standard feature in C++ libraries -- they
195 // provide convenience and allow the implementation of the "iteratee"
196 // to be kept hidden.
197 // </motivation>
198 
199 //# <todo asof="1995/09/12">
200 //# <li>
201 //# </todo>
202 
203 
204 template <class T> class RO_LatticeIterator
205 {
206 public:
207 
208  // The default constructor creates an empty object which is practically
209  // unusable.
210  // It can only be used as the source or target of an assignment. It can
211  // also be used as the source for the copy constructor and the copy function.
212  // Other functions do not check if the object is empty and will usually
213  // give a segmentation fault.
214  // The function isNull() can be used to test if the object is empty.
216 
217  // Construct the Iterator with the supplied data.
218  // It uses a TileStepper as the default iteration strategy.
219  // useRef=True means that if possible the cursor arrays returned
220  // reference the data in the underlying lattice. This is only possible
221  // for ArrayLattice objects (or e.g. a SubLattice using it).
222  explicit RO_LatticeIterator (const Lattice<T>& data, Bool useRef=True);
223 
224  // Construct the Iterator with the supplied data, and iteration strategy
225  RO_LatticeIterator (const Lattice<T>& data, const LatticeNavigator& method,
226  Bool useRef=True);
227 
228  // Construct the Iterator with the supplied data.
229  // It uses a LatticeStepper with the supplied cursor shape as the
230  // iteration strategy.
231  RO_LatticeIterator (const Lattice<T>& data, const IPosition& cursorShape,
232  Bool useRef=True);
233 
234  // The copy constructor uses reference semantics (ie. NO real copy is made).
235  // The function <src>copy</src> can be used to make a true copy.
237 
238  // Destructor (cleans up dangling references and releases memory)
240 
241  // Assignment uses reference semantics (ie. NO real copy is made).
242  // The function <src>copy</src> can be used to make a true copy.
244 
245  // Make a copy of the iterator object.
246  // This means that an independent navigator object is created to
247  // be able to iterate independently through the same Lattice.
248  // The position in the copied navigator is the same as the original.
249  // The reset function has to be used to start at the beginning.
250  // <br>Note that if the Lattice uses a cache (e.g. PagedArray), the
251  // cache is shared by the iterators.
252  RO_LatticeIterator<T> copy() const;
253 
254  // Is the iterator object empty?
255  Bool isNull() const
256  { return itsIterPtr.null(); }
257 
258  // Return the underlying lattice.
260  { return itsIterPtr->lattice(); }
261 
262  // Increment operator - increment the cursor to the next position. These
263  // functions are forwarded to the current LatticeNavigator and both
264  // postfix and prefix versions will do the same thing.
265  // <br>They return True if the cursor moved (which should always be the
266  // case if the iterator is not at the end).
267  // <group>
268  Bool operator++();
269  Bool operator++(int);
270  // </group>
271 
272  // Decrement operator - decrement the cursor to the previous
273  // position. These functions are forwarded to the current LatticeNavigator
274  // and both postfix and prefix versions will do the same thing.
275  // <br>They return True if the cursor moved (which should always be the
276  // case if the iterator is not at the start).
277  // <group>
278  Bool operator--();
279  Bool operator--(int);
280  // </group>
281 
282  // Function which resets the cursor to the beginning of the Lattice and
283  // resets the number of steps taken to zero.
284  void reset();
285 
286  // Function which returns a value of "True" if the cursor is at the
287  // beginning of the Lattice, otherwise, returns "False".
288  Bool atStart() const;
289 
290  // Function which returns a value of "True" if an attempt has been made
291  // to move the cursor beyond the end of the Lattice.
292  Bool atEnd() const;
293 
294  // Function to return the number of steps (increments or decrements) taken
295  // since construction (or since last reset). This is a running count of
296  // all cursor movement, thus doing N increments followed by N decrements
297  // results in 2N steps.
298  uInt nsteps() const;
299 
300  // Function which returns the current position of the beginning of the
301  // cursor within the Lattice. The returned IPosition will have the same
302  // number of axes as the underlying Lattice.
303  IPosition position() const;
304 
305  // Function which returns the current position of the end of the
306  // cursor. The returned IPosition will have the same number of axes as the
307  // underlying Lattice.
308  IPosition endPosition() const;
309 
310  // Function which returns the shape of the Lattice being iterated through.
311  // The returned IPosition will always have the same number of axes as the
312  // underlying Lattice.
313  IPosition latticeShape() const;
314 
315  // Function which returns the shape of the cursor which is iterating
316  // through the Lattice. The returned IPosition will have the same number
317  // of axes as the underlying Lattice.
318  IPosition cursorShape() const;
319 
320  // Functions which returns a window to the data in the Lattice. These are
321  // used to read the data within the Lattice. Use the function that is
322  // appropriate to the current cursor dimension, AFTER REMOVING DEGENERATE
323  // AXES, or use the <src>cursor</src> function which works with any number
324  // of dimensions in the cursor. A call of the function whose return value
325  // is inappropriate with respect to the current cursor dimension will
326  // throw an exception (AipsError).
327  // <group>
328  const Vector<T>& vectorCursor() const;
329  const Matrix<T>& matrixCursor() const;
330  const Cube<T>& cubeCursor() const;
331  const Array<T>& cursor() const;
332  // </group>
333 
334  // Function which checks the internals of the class for consistency.
335  // Returns True if everything is fine otherwise returns False.
336  Bool ok() const;
337 
338 protected:
339  // The pointer to the Iterator
341 };
342 
343 
344 
345 // <summary>
346 // A read/write lattice iterator
347 // </summary>
348 
349 // <use visibility=export>
350 
351 // <reviewed reviewer="Peter Barnes" date="1999/10/30" tests="tLatticeIterator.cc">
352 // </reviewed>
353 
354 // <prerequisite>
355 // <li> <linkto class="RO_LatticeIterator">RO_LatticeIterator</linkto>
356 // <li> <linkto class="Lattice">Lattice</linkto>
357 // <li> <linkto class="LatticeNavigator">LatticeNavigator</linkto>
358 // <li> <linkto class="Array">Array</linkto>
359 // </prerequisite>
360 
361 // <synopsis>
362 // LatticeIterator differs from the RO_LatticeIterator class in that
363 // the window into the Lattice data which moves with each iterative step may
364 // be used to alter the Lattice data itself. The moving "cursor" gives the
365 // user the door to reach in and change the basic Lattice before moving to
366 // another section of the Lattice.
367 // <p>
368 // LatticeIterator can be used in 3 ways:
369 // <br> - For readonly purposes using the cursor() functions. Note that if
370 // the entire iteration is readonly, it is better to use an
371 // <linkto class=RO_LatticeIterator>RO_LatticeIterator</linkto> object.
372 // <br> - To update (part of)the contents of the lattice (e.g. clip the value
373 // of some pixels). For this purpose the <src>rwCursor</src> functions
374 // should be used. They read the data (if not read yet) and mark the
375 // cursor for write.
376 // <br> - To fill the lattice. For this purpose the <src>woCursor</src>
377 // functions should be used. They do not read the data, but only mark the
378 // cursor for write.
379 // <p>
380 // When needed, writing the cursor data is done automatically when the
381 // cursor position changes or when the iterator is destructed.
382 // </synopsis>
383 
384 // <example>
385 // Here's an iterator that runs through a cube, assigning every element
386 // of each plane of the cube a value equal to the number of the plane.
387 // See <linkto class=LatticeStepper>LatticeStepper</linkto> for an
388 // explanation of the navigator used here.
389 // <srcblock>
390 // PagedArray<Float> pa("someName");
391 // IPosition windowShape(2,pa.shape(0), pa.shape(1));
392 // LatticeStepper stepper(pa.shape(), windowShape);
393 // LatticeIterator<Float> iterator(pa, stepper);
394 // Int planeNumber = 0;
395 // for (iterator.reset(); !iterator.atEnd(); iterator++) {
396 // iterator.woCursor() = planeNumber++;
397 // }
398 // </srcblock>
399 //
400 // Here's an iterator that runs through a cube, subtracting the mean from
401 // each line of the cube with a mean < 0.
402 // See <linkto class=TiledLineStepper>TiledLineStepper</linkto> for an
403 // explanation of the navigator used here.
404 // <srcblock>
405 // PagedArray<Float> pa("someName");
406 // TiledLineStepper stepper(pa.shape(), pa.niceCursorShape(), 0);
407 // LatticeIterator<Float> iterator(pa, stepper);
408 // Int planeNumber = 0;
409 // for (iterator.reset(); !iterator.atEnd(); iterator++) {
410 // Float meanLine = mean(iterator.cursor());
411 // if (meanLine < 0) {
412 // iterator.rwCursor() -= meanLine;
413 // }
414 // }
415 // </srcblock>
416 // Note that in this last example no more vectors than required are written.
417 // This is achieved by using the readonly function <src>cursor</src> in
418 // the test and using <src>rwCursor</src> only when data needs to be changed.
419 // <br>Note that <src>rwCursor</src> does not read the data again. They are
420 // still readily available.
421 // </example>
422 
423 
424 template <class T> class LatticeIterator : public RO_LatticeIterator<T>
425 {
426 public:
427 
428  // The default constructor creates an empty object which is practically
429  // unusable.
430  // It can only be used as the source or target of an assignment. It can
431  // also be used as the source for the copy constructor and the copy function.
432  // Other functions do not check if the object is empty and will usually
433  // give a segmentation fault.
434  // The function isNull() can be used to test if the object is empty.
435  LatticeIterator();
436 
437  // Construct the Iterator with the supplied data.
438  // It uses a TileStepper as the default iteration strategy.
439  // useRef=True means that if possible the cursor arrays returned
440  // reference the data in the underlying lattice. This is only possible
441  // for ArrayLattice objects (or e.g. a SubLattice using it).
442  explicit LatticeIterator (Lattice<T>& data, Bool useRef=True);
443 
444  // Construct the Iterator with the supplied data, and iteration strategy
445  LatticeIterator (Lattice<T>& data, const LatticeNavigator& method,
446  Bool useRef=True);
447 
448  // Iterate through the data with a LatticeStepper that has uses the
449  // supplied cursorShape.
451  Bool useRef=True);
452 
453  // The copy constructor uses reference semantics (ie. NO real copy is made).
454  // The function <src>copy</src> can be used to make a true copy.
455  LatticeIterator (const LatticeIterator<T>& other);
456 
457  // destructor (cleans up dangling references and releases memory)
459 
460  // Assignment uses reference semantics (ie. NO real copy is made).
461  // The function <src>copy</src> can be used to make a true copy.
463 
464  // Make a copy of the iterator object.
465  // This means that an independent navigator object is created to
466  // be able to iterate independently through the same Lattice.
467  // The position in the copied navigator is the same as the original.
468  // The reset function has to be used to start at the beginning.
469  // <br>Note that if the Lattice uses a cache (e.g. PagedArray), the
470  // cache is shared by the iterators.
471  LatticeIterator<T> copy() const;
472 
473  // Functions to return a window to the data in the Lattice. Use the function
474  // that is appropriate to the current cursor dimension, AFTER REMOVING
475  // DEGENERATE AXES, or use the <src>cursor</src> function which works with
476  // any number of dimensions in the cursor. A call of the function whose
477  // return value is inappropriate with respect to the current cursor
478  // dimension will throw an exception (AipsError) (e.g. VectorCursor
479  // cannot be used when the cursor is 2D).
480  // <br>
481  // When the iterator state changes (e.g. by moving, destruction) the
482  // data are automatically rewritten before the iterator state is changed.
483  // <br>The <src>rw</src> (read/write) versions should be used to read the
484  // data first. They are useful to update a lattice.
485  // The <src>wo</src> (writeonly) versions do not read the data.
486  // They only return a cursor of the correct shape and are useful to
487  // fill a lattice. Note that it sets the state to 'data read'. I.e.,
488  // a subsequent call to, say, <src>cursor()</src> does not read the
489  // data, which would destroy the contents of the cursor which may
490  // just be filled by the user.
491  // <group>
495  Array<T>& rwCursor();
499  Array<T>& woCursor();
500  //</group>
501 
502  // Function which checks the internals of the class for consistency.
503  // Returns True if everything is fine. Otherwise returns False.
504  Bool ok() const;
505 
506  //# Make members of parent class known.
507 public:
512 protected:
514 };
515 
516 
517 
518 } //# NAMESPACE CASACORE - END
519 
520 //# See comments in Lattice.h why Lattice.tcc is included here.
521 #ifndef CASACORE_NO_AUTO_TEMPLATES
522 #include <casacore/lattices/Lattices/Lattice.tcc>
523 #include <casacore/lattices/Lattices/LatticeIterator.tcc>
524 #endif //# CASACORE_NO_AUTO_TEMPLATES
525 #endif
A Vector of integers, for indexing into Array&lt;T&gt; objects.
Definition: IPosition.h:118
~RO_LatticeIterator()
Destructor (cleans up dangling references and releases memory)
const Matrix< T > & matrixCursor() const
IPosition latticeShape() const
Function which returns the shape of the Lattice being iterated through.
A read/write lattice iterator.
Definition: ImageRegrid.h:46
void reset()
Function which resets the cursor to the beginning of the Lattice and resets the number of steps taken...
IPosition position() const
Function which returns the current position of the beginning of the cursor within the Lattice...
A 3-D Specialization of the Array class.
Definition: ArrayFwd.h:11
IPosition endPosition() const
Function which returns the current position of the end of the cursor.
Bool operator++()
Increment operator - increment the cursor to the next position.
LatticeIterator< T > & operator=(const LatticeIterator< T > &other)
Assignment uses reference semantics (ie.
RO_LatticeIterator< T > copy() const
Make a copy of the iterator object.
const Array< T > & cursor() const
Bool operator--()
Decrement operator - decrement the cursor to the previous position.
LatticeIterator()
The default constructor creates an empty object which is practically unusable.
Matrix< T > & rwMatrixCursor()
Bool atStart() const
Function which returns a value of &quot;True&quot; if the cursor is at the beginning of the Lattice...
Bool ok() const
Function which checks the internals of the class for consistency.
const Cube< T > & cubeCursor() const
A readonly iterator for Lattices.
Bool atEnd() const
Function which returns a value of &quot;True&quot; if an attempt has been made to move the cursor beyond the en...
CountedPtr< LatticeIterInterface< T > > itsIterPtr
The pointer to the Iterator.
A templated, abstract base class for array-like objects.
Definition: Functional.h:37
Referenced counted pointer for constant data.
Definition: CountedPtr.h:80
Lattice< T > & lattice() const
Return the underlying lattice.
Matrix< T > & woMatrixCursor()
Vector< T > & woVectorCursor()
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
RO_LatticeIterator()
The default constructor creates an empty object which is practically unusable.
LatticeIterator< T > copy() const
Make a copy of the iterator object.
IPosition cursorShape() const
Function which returns the shape of the cursor which is iterating through the Lattice.
Bool ok() const
Function which checks the internals of the class for consistency.
Bool isNull() const
Is the iterator object empty?
uInt nsteps() const
Function to return the number of steps (increments or decrements) taken since construction (or since ...
Cube< T > & rwCubeCursor()
RO_LatticeIterator< T > & operator=(const RO_LatticeIterator< T > &other)
Assignment uses reference semantics (ie.
const Vector< T > & vectorCursor() const
Functions which returns a window to the data in the Lattice.
~LatticeIterator()
destructor (cleans up dangling references and releases memory)
Vector< T > & rwVectorCursor()
Functions to return a window to the data in the Lattice.
Cube< T > & woCubeCursor()
const Bool True
Definition: aipstype.h:43
unsigned int uInt
Definition: aipstype.h:51
Abstract base class to steer lattice iterators.