There may eventually be a large collection of tools for traversing Lattices. At this writing (December 1999) there are three concrete classes derived from LatticeNavigator: LatticeStepper, TiledLineStepper, and TileStepper.
The LatticeStepper class moves through a Lattice in fixed steps defined by the user specified cursor, incrementing to the next portion of the Lattice with each step, and wrapping around axes as needed. Other position generators might follow the brightest pixel, traverse a number of predefined subregions, or change size automatically when near the edges.
The TiledLineStepper class moves a Vector cursor through a Lattice, until all the lines in the set of tiles along the specified axis have been exhausted. It then moves to the next set of tiles. This is a memory-efficient way to move a Vector cursor through a Lattice.
The most important member functions of this class are those which move the cursor to the next position. These are the operator++ and operator-- member functions, (in postfix and prefix forms).
The cursor shape need not be constant as it moves through the Lattice, but may change depending on its current position. For the LatticeStepper and TiledLineStepper classes , however, the cursor shape is constant as it steps through the Lattice.
It is not possible to randomly move the cursor to an arbitrary place in the Lattice, although the cursor can be moved to the starting position at any time using the reset member function.
The position of the cursor can be queried at any time using the position member function. This gives the position of the bottom left hand corner of the cursor. The position of the top right hand corner of the cursor is obtained using the endPosition member function, and the current cursor shape is obtained using the cursorShape member function. Note that the endPosition does not take an overhang into account.
It is possible that for some positions of the cursor, part of it will "hang over" the edge of the Lattice. When this occurs the hangOver member function will return True. This will occur with a LatticeStepper if the Lattice shape is not a multiple of the cursor shape. Hangover cannot occur with the TiledLineStepper as the length of the Vector cursor is defined by the Lattice Shape.
It may be possible (depending on the concrete LatticeNavigator actually used) to specify that only a region of the Lattice (defined by a top right hand corner, bottom left hand corner, and step increment) be traversed by the LatticeNavigator. This is done using the subSection member function. At any time the region can be redefined by calling the subSection function again. This replaces the previously defined region with the new one.
Using the subSection function always sets the cursor position to the origin of the currently defined sub-lattice. This is a backdoor way to move the cursor to random locations in the Lattice.
It is an error to define a sub-lattice that is bigger than the current Lattice. If using a LatticeStepper it may also be necessary to resize the cursor (using the setCursorShape member function) prior to calling the subSection function as the cursor cannot be bigger than the sub-Lattice on any axis.
The arguments (trc, blc and inc) to the subSection function are always relative to the main Lattice. This is also true of the position and endPosition functions. To get the position of the cursor relative to the currently defined sub-Lattice use the relativePosition and relativeEndPosition member functions.
Many of the LatticeIterator member functions are directly forwarded to
virtual functions of this class, and classes derived from it. For
instance, LatticeIterator
Copy constructor.
Assignment.
A virtual destructor. A virtual is needed to ensure that derived
classes accessed through pointers to a LatticeNavigator will scope
their destructor to the derived class destructor.
Increment operator - increment the cursor to the next position. The
implementation of the prefix operator calls the postfix one.
Decrement operator - decrement the cursor to the previous position. The
implementation of the prefix operator calls the postfix one.
Function to reset the cursor to the beginning of the Lattice and
reset the number of steps taken to zero.
Function which returns "True" if the cursor is at the beginning of the
Lattice, otherwise, returns "False"
Function which returns "True" if an attempt has been made to increment
the cursor beyond the end of the Lattice.
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 since doing N increments followed by N decrements
does not necessarily put the cursor back at the origin of the Lattice.
Functions which return the current position of the beginning of the
cursor. The position function is relative to the origin in
the main Lattice and the relativePosition function is
relative to the origin and increment used in the sub-Lattice (defined
using the subSection function).
The returned IPosition will have the same number of axes as
the underlying Lattice.
Functions which return the current position of the end of the
cursor. The endPosition function is relative to the origin in
the main Lattice and the relativeEndPosition function is
relative to the origin and increment used in the sub-Lattice (defined
using the subSection function).
The returned IPosition will have the same number of axes as
the underlying Lattice.
Functions which return the shape of the Lattice being iterated
through. latticeShape always returns the shape of the main
Lattice while subLatticeShape returns the shape of any
sub-Lattice defined using the subSection function. In the
default implementation of this class it is not possible to use the
subsection function (it throws an exception) so the default
implementation of the subLatticeShape function calls the
latticeShape function. The returned IPosition will always
have the same number of axes as the underlying Lattice.
Function which returns the current shape of the cursor which is
iterating through the Lattice. The returned IPosition will have the
same number of axes as the underlying Lattice.
Function which returns the axes of the cursor.
These are the axes which should not be removed by the
iterator functions vectorCursor(), etc..
Function which returns "True" if the increment/decrement operators have
moved the cursor position such that part of the cursor is hanging over
the edge of the Lattice. This function may always return a value of
"False" for some iteration methods that do not move the cursor past the
Lattice boundaries.
Functions which return the "bottom left corner" and the "top right corner"
of the cursor that does not hangover. Use these functions to extract the
valid part of the cursor when the hangover member function is true. If
there is no hangover then hangOverBLC returns an IPosition of zero and
hangOverTRC() returns the cursorShape - 1;
Function to specify a "section" of the Lattice to Navigate over. A
section is defined in terms of the Bottom Left Corner (blc), Top Right
Corner (trc), and step size (inc), on ALL of its axes, including
degenerate axes. The step size defaults to one if not specified.
In the default implementation of this class subsectioning is not
supported and using the subsection function will throw an
exception (AipsError).
Return the bottom left hand corner (blc), top right corner (trc) or
step size (increment) used by the current sub-Lattice. In the default
implementation of this class sub-sectioning is not supported and these
functions will always return blc=0, trc=latticeShape-1, increment=1,
ie. the entire Lattice.
Return the axis path.
See
Calculate the cache size (in tiles) for this type of access to a lattice
in the given row of the tiled hypercube.
A zero pointer indicates there is no hypercube, but that the data
is in memory instead. Then a cache size of 0 is returned.
Function which returns a pointer to dynamic memory of an exact copy
of this LatticeNavigator. It is the responsibility of the caller to
release this memory.
Function which checks the internals of the class for consistency.
Returns True if everything is fine otherwise returns False. The default
implementation always returns True.
Example
See the examples in the
LatticeStepper class, the
TiledLineStepper class, and the
TileStepper class.
Motivation
Iterator classes are quite common in C++. What's novel about the design
which includes this class is the separation of iterator mechanisms from
traversal strategy. The iterator provides a lot of functionality: it
provides a cursor, damage notification and tracking, and reading and
writing to the underlying data structure. Traversal strategies can and
should be isolated from these things. Because every LatticeIterator
uses a Navigator, it gets the benefits of a derived concrete navigator
without getting involved in its mechanism.
To Do
Member Description
LatticeNavigator()
Default constructor.
LatticeNavigator (const LatticeNavigator&)
LatticeNavigator& operator= (const LatticeNavigator&)
virtual ~LatticeNavigator()
virtual Bool operator++(int) = 0
Bool operator++()
virtual Bool operator--(int) = 0
Bool operator--()
virtual void reset() = 0
virtual Bool atStart() const = 0
virtual Bool atEnd() const = 0
virtual uInt nsteps() const = 0
virtual IPosition position() const = 0
virtual IPosition relativePosition() const
The default implementation of the relativePosition
function returns (position() - blc()) / increment().
virtual IPosition endPosition() const = 0
virtual IPosition relativeEndPosition() const
It returns the end position in the lattice and
does not take overhang into account.
The default implementation of the relativeEndPosition
function returns (endPosition() - blc()) / increment().
virtual IPosition latticeShape() const = 0
virtual IPosition subLatticeShape() const
virtual IPosition cursorShape() const = 0
virtual IPosition cursorAxes() const = 0
virtual Bool hangOver() const = 0
virtual IPosition hangOverBlc() const
virtual IPosition hangOverTrc() const
virtual void subSection(const IPosition& blc, const IPosition& trc)
virtual void subSection(const IPosition& blc, const IPosition& trc, const IPosition& inc)
virtual IPosition blc() const
virtual IPosition trc() const
virtual IPosition increment() const
virtual const IPosition& axisPath() const = 0
uInt calcCacheSize (const ROTiledStManAccessor*, Int rowNumber) const
virtual LatticeNavigator* clone() const = 0
virtual Bool ok() const
virtual uInt calcCacheSize (const ROTiledStManAccessor&, uInt rowNumber) const = 0
Calculate the cache size (in tiles) for this type of access to a lattice
in the given row of the tiled hypercube.