casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Public Member Functions | Protected Attributes
casa::RO_LatticeIterator< T > Class Template Reference

A readonly iterator for Lattices. More...

#include <LatticeIterator.h>

Inheritance diagram for casa::RO_LatticeIterator< T >:
casa::LatticeIterator< T > casa::RO_MaskedLatticeIterator< T >

List of all members.

Public Member Functions

 RO_LatticeIterator ()
 The default constructor creates an empty object which is practically unusable.
 RO_LatticeIterator (const Lattice< T > &data, Bool useRef=True)
 Construct the Iterator with the supplied data.
 RO_LatticeIterator (const Lattice< T > &data, const LatticeNavigator &method, Bool useRef=True)
 Construct the Iterator with the supplied data, and iteration strategy.
 RO_LatticeIterator (const Lattice< T > &data, const IPosition &cursorShape, Bool useRef=True)
 Construct the Iterator with the supplied data.
 RO_LatticeIterator (const RO_LatticeIterator< T > &other)
 The copy constructor uses reference semantics (ie.
 ~RO_LatticeIterator ()
 Destructor (cleans up dangling references and releases memory)
RO_LatticeIterator< T > & operator= (const RO_LatticeIterator< T > &other)
 Assignment uses reference semantics (ie.
RO_LatticeIterator< T > copy () const
 Make a copy of the iterator object.
Bool isNull () const
 Is the iterator object empty?
Lattice< T > & lattice () const
 Return the underlying lattice.
Bool operator++ ()
 Increment operator - increment the cursor to the next position.
Bool operator++ (int)
Bool operator-- ()
 Decrement operator - decrement the cursor to the previous position.
Bool operator-- (int)
void reset ()
 Function which resets the cursor to the beginning of the Lattice and resets the number of steps taken to zero.
Bool atStart () const
 Function which returns a value of "True" if the cursor is at the beginning of the Lattice, otherwise, returns "False".
Bool atEnd () const
 Function which returns a value of "True" if an attempt has been made to move the cursor beyond the end of the Lattice.
uInt nsteps () const
 Function to return the number of steps (increments or decrements) taken since construction (or since last reset).
IPosition position () const
 Function which returns the current position of the beginning of the cursor within the Lattice.
IPosition endPosition () const
 Function which returns the current position of the end of the cursor.
IPosition latticeShape () const
 Function which returns the shape of the Lattice being iterated through.
IPosition cursorShape () const
 Function which returns the shape of the cursor which is iterating through the Lattice.
const Vector< T > & vectorCursor () const
 Functions which returns a window to the data in the Lattice.
const Matrix< T > & matrixCursor () const
const Cube< T > & cubeCursor () const
const Array< T > & cursor () const
Bool ok () const
 Function which checks the internals of the class for consistency.

Protected Attributes

CountedPtr
< LatticeIterInterface< T > > 
itsIterPtr
 The pointer to the Iterator.

Detailed Description

template<class T>
class casa::RO_LatticeIterator< T >

A readonly iterator for Lattices.

Intended use:

Public interface

Review Status

Reviewed By:
Peter Barnes
Date Reviewed:
1999/10/30
Test programs:
tLatticeIterator

Prerequisite

Etymology

The leading "RO" is shorthand for "readonly", which indicates that an RO_LatticeIterator is used for traversing a Lattice, examining and possibly extracting its contents, but not for modifying it.

Synopsis

This class provides a convenient way to traverse any class derived from Lattice. You can iterate through the Lattice's data from "start" to "end" by calling operator++, and reverse direction by calling operator--. You can return immediately to the beginning by calling the reset function. The RO_LatticeIterator gives the user the opportunity to methodically walk through the data, in an efficient way.

The supplied LatticeNavigator determines how to step through the Lattice. It can, for instance, be line by line, but it can also be in a more complicated way. When no navigator is supplied, a default navigator will be used which steps in the optimum way.

A cursor (which is an Array object) is used to return the data for each step in the iteration process. Depending on the navigator used the cursor can have a different shape for each step of the iteration. This is especially true when the end of an axis is reached for a non-integrally fitting cursor shape.
The cursor() function returns an Array which has the same dimensionality as the Lattice. It is, however, also possible to get an Array with a lower dimensionality by using the correct function in the group vectorCursor(), matrixCursor(), and cubeCursor(). Those functions remove (some) degenerated axes resulting in a vector, matrix or cube. When, for example, a LatticeStepper with shape [64,1,1] is used, the vectorCursor() can be used. It will remove the degenerated axes (length 1) and return the cursor as a Vector object. Note that matrixCursor() cannot be used, because removing the degenerated axes results in a 1D array.

Generally iterators should not be long-lived objects - create new ones when needed rather than keeping one around for a long time to be reused. This is because the cache memory used by the cursor will be released when the iterator is destroyed.

The purpose of this class is to hide the possibly complicated implementation and structure of the Lattice classes, and allow you to iterate through a Lattice with the same ease as one iterates through a Fortran or C vector. For example, and assuming that initialization has been done properly, here's a typical 'for' loop:

     // code omitted  which associates Lattice object and the iterator
     for (iterator.reset(); !iterator.atEnd(); iterator++) {
       meanValue = mean(iterator.cursor()); 
     }

The iterator's cursor() member function returns a reference to that part of the Lattice data which is presently "seen" by the LatticeIterator.

Before explaining the initialization of an iterator, the LatticeNavigator class must be further introduced. This is an abstract base class, from which concrete navigators are derived. After one of these is created, you attach it to the LatticeIterator, and it provides a specific technique for navigating through the Lattice. Different navigators deliver different traversal schemes. The most basic is LatticeStepper , which moves a specified shape sequentially through the Lattice -- for example, by moving one plane at a time, front to back, through a cube. Another (future) navigator might be designed to move a small, 2-dimensional plane through a cube, centering each iteration on the brightest pixel of the cube's plane, and ignoring the darker regions of the cube.

The performance and memory usage of an iteration through a lattice (in particular through a PagedArray ) depends very heavily on the navigator used. Currently there are three navigators available:

  1. LatticeStepper steps sequentially through a lattice with the given cursor shape. This can use a lot of memory for the PagedArray cache.
  2. TiledLineStepper steps line by line through a lattice. However, it is doing that in such a way that as few tiles as possible need to kept in the PagedArray cache. This reduces memory usage considerably.
  3. TileStepper steps tile by tile through a lattice. This navigator requires a PagedArray cache of 1 tile only. However, it can only be used for application in which the iteration order is not important (e.g. addition, determining max).

The class LatticeApply is very useful to iterate through a Lattice while applying an algorithm. It makes it possible for the user to concentrate on the algorithm.

Here's a typical iterator declaration:

    RO_LatticeIterator<Float> iterator(pagedArray, stepper);

The template identifier Float defines the data type of Array object that will be the iterator's cursor.
The pagedArray constructor argument names a PagedArray object, which is what the iterator will traverse. The stepper argument is a LatticeStepper which defines the method of iteration.

Example

When passed the name of a previously created PagedArray stored on disk, this function will traverse the whole array, and report the average value of all of the elements. Imagine that the filename contains a PagedArray with dimension 64 x 64 x 8.

    void demonstrateIterator (const String& filename)
    {
      PagedArray<Float> pagedArray(filename);
      IPosition latticeShape = pagedArray.shape();
      cout << "paged array has shape: " << latticeShape << endl;
    
      // Construct the iterator.  since we only want to read the PagedArray,
      // use the read-only class, which disallows writing back to the cursor.
      // No navigator is given, so the default TileStepper is used
      // which ensures optimum performance.
      RO_LatticeIterator<Float> iterator(pagedArray);
    
      // Add for each iteration step the sum of the cursor elements to the sum.
      // Note that the cursor is an Array object and that the function sum
      // is defined in ArrayMath.h.
      Float runningSum = 0.0;
      for (iterator.reset(); !iterator.atEnd(); iterator++) {
          runningSum += sum(iterator.cursor());
      }
      cout << "average value, from demonstrateIterator: " 
          << runningSum / latticeShape.product() << endl;
    }

Motivation

Iterator classes are a standard feature in C++ libraries -- they provide convenience and allow the implementation of the "iteratee" to be kept hidden.

Definition at line 208 of file LatticeIterator.h.


Constructor & Destructor Documentation

template<class T>
casa::RO_LatticeIterator< T >::RO_LatticeIterator ( )

The default constructor creates an empty object which is practically unusable.

It can only be used as the source or target of an assignment. It can also be used as the source for the copy constructor and the copy function. Other functions do not check if the object is empty and will usually give a segmentation fault. The function isNull() can be used to test if the object is empty.

template<class T>
casa::RO_LatticeIterator< T >::RO_LatticeIterator ( const Lattice< T > &  data,
Bool  useRef = True 
) [explicit]

Construct the Iterator with the supplied data.

It uses a TileStepper as the default iteration strategy. useRef=True means that if possible the cursor arrays returned reference the data in the underlying lattice. This is only possible for ArrayLattice objects (or e.g. a SubLattice using it).

template<class T>
casa::RO_LatticeIterator< T >::RO_LatticeIterator ( const Lattice< T > &  data,
const LatticeNavigator method,
Bool  useRef = True 
)

Construct the Iterator with the supplied data, and iteration strategy.

template<class T>
casa::RO_LatticeIterator< T >::RO_LatticeIterator ( const Lattice< T > &  data,
const IPosition cursorShape,
Bool  useRef = True 
)

Construct the Iterator with the supplied data.

It uses a LatticeStepper with the supplied cursor shape as the iteration strategy.

template<class T>
casa::RO_LatticeIterator< T >::RO_LatticeIterator ( const RO_LatticeIterator< T > &  other)

The copy constructor uses reference semantics (ie.

NO real copy is made). The function copy can be used to make a true copy.

template<class T>
casa::RO_LatticeIterator< T >::~RO_LatticeIterator ( )

Destructor (cleans up dangling references and releases memory)


Member Function Documentation

template<class T>
Bool casa::RO_LatticeIterator< T >::atEnd ( ) const

Function which returns a value of "True" if an attempt has been made to move the cursor beyond the end of the Lattice.

template<class T>
Bool casa::RO_LatticeIterator< T >::atStart ( ) const

Function which returns a value of "True" if the cursor is at the beginning of the Lattice, otherwise, returns "False".

template<class T>
RO_LatticeIterator<T> casa::RO_LatticeIterator< T >::copy ( ) const

Make a copy of the iterator object.

This means that an independent navigator object is created to be able to iterate independently through the same Lattice. The position in the copied navigator is the same as the original. The reset function has to be used to start at the beginning.
Note that if the Lattice uses a cache (e.g. PagedArray), the cache is shared by the iterators.

Reimplemented in casa::LatticeIterator< T >, casa::LatticeIterator< Float >, and casa::RO_MaskedLatticeIterator< T >.

template<class T>
const Cube<T>& casa::RO_LatticeIterator< T >::cubeCursor ( ) const
template<class T>
const Array<T>& casa::RO_LatticeIterator< T >::cursor ( ) const
template<class T>
IPosition casa::RO_LatticeIterator< T >::cursorShape ( ) const

Function which returns the shape of the cursor which is iterating through the Lattice.

The returned IPosition will have the same number of axes as the underlying Lattice.

template<class T>
IPosition casa::RO_LatticeIterator< T >::endPosition ( ) const

Function which returns the current position of the end of the cursor.

The returned IPosition will have the same number of axes as the underlying Lattice.

template<class T>
Bool casa::RO_LatticeIterator< T >::isNull ( ) const [inline]

Is the iterator object empty?

Definition at line 259 of file LatticeIterator.h.

template<class T>
Lattice<T>& casa::RO_LatticeIterator< T >::lattice ( ) const [inline]

Return the underlying lattice.

Reimplemented in casa::RO_MaskedLatticeIterator< T >.

Definition at line 263 of file LatticeIterator.h.

template<class T>
IPosition casa::RO_LatticeIterator< T >::latticeShape ( ) const

Function which returns the shape of the Lattice being iterated through.

The returned IPosition will always have the same number of axes as the underlying Lattice.

template<class T>
const Matrix<T>& casa::RO_LatticeIterator< T >::matrixCursor ( ) const
template<class T>
uInt casa::RO_LatticeIterator< T >::nsteps ( ) const

Function to return the number of steps (increments or decrements) taken since construction (or since last reset).

This is a running count of all cursor movement, thus doing N increments followed by N decrements results in 2N steps.

template<class T>
Bool casa::RO_LatticeIterator< T >::ok ( ) const

Function which checks the internals of the class for consistency.

Returns True if everything is fine otherwise returns False.

Reimplemented in casa::LatticeIterator< T >, and casa::LatticeIterator< Float >.

template<class T>
Bool casa::RO_LatticeIterator< T >::operator++ ( )

Increment operator - increment the cursor to the next position.

These functions are forwarded to the current LatticeNavigator and both postfix and prefix versions will do the same thing.
They return True if the cursor moved (which should always be the case if the iterator is not at the end).

template<class T>
Bool casa::RO_LatticeIterator< T >::operator++ ( int  )
template<class T>
Bool casa::RO_LatticeIterator< T >::operator-- ( )

Decrement operator - decrement the cursor to the previous position.

These functions are forwarded to the current LatticeNavigator and both postfix and prefix versions will do the same thing.
They return True if the cursor moved (which should always be the case if the iterator is not at the start).

template<class T>
Bool casa::RO_LatticeIterator< T >::operator-- ( int  )
template<class T>
RO_LatticeIterator<T>& casa::RO_LatticeIterator< T >::operator= ( const RO_LatticeIterator< T > &  other)

Assignment uses reference semantics (ie.

NO real copy is made). The function copy can be used to make a true copy.

template<class T>
IPosition casa::RO_LatticeIterator< T >::position ( ) const

Function which returns the current position of the beginning of the cursor within the Lattice.

The returned IPosition will have the same number of axes as the underlying Lattice.

template<class T>
void casa::RO_LatticeIterator< T >::reset ( )

Function which resets the cursor to the beginning of the Lattice and resets the number of steps taken to zero.

template<class T>
const Vector<T>& casa::RO_LatticeIterator< T >::vectorCursor ( ) const

Functions which returns a window to the data in the Lattice.

These are used to read the data within the Lattice. Use the function that is appropriate to the current cursor dimension, AFTER REMOVING DEGENERATE AXES, or use the cursor function which works with any number of dimensions in the cursor. A call of the function whose return value is inappropriate with respect to the current cursor dimension will throw an exception (AipsError).


Member Data Documentation

template<class T>
CountedPtr<LatticeIterInterface<T> > casa::RO_LatticeIterator< T >::itsIterPtr [protected]

The pointer to the Iterator.

Definition at line 344 of file LatticeIterator.h.

Referenced by casa::RO_LatticeIterator< Float >::isNull(), and casa::RO_LatticeIterator< Float >::lattice().


The documentation for this class was generated from the following file: