casacore
Loading...
Searching...
No Matches
TiledLineStepper.h
Go to the documentation of this file.
1// # TiledLineStepper.h: Step a Vector cursor optimally through a tiled Lattice
2// # Copyright (C) 1997,1998,1999,2000
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: casa-feedback@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#ifndef LATTICES_TILEDLINESTEPPER_H
27#define LATTICES_TILEDLINESTEPPER_H
28
29// # Includes
30#include <casacore/casa/aips.h>
31#include <casacore/lattices/Lattices/LatticeNavigator.h>
32#include <casacore/lattices/Lattices/LatticeIndexer.h>
33#include <casacore/casa/Arrays/IPosition.h>
34
35namespace casacore { // # NAMESPACE CASACORE - BEGIN
36
37// <summary>
38// Step a Vector cursor optimally through a tiled Lattice.
39// </summary>
40// <use visibility=export>
41
42// <reviewed reviewer="Peter Barnes" date="1999/10/30" tests="tTiledLineStepper.cc">
43// </reviewed>
44
45// <prerequisite>
46// <li> <linkto class=LatticeNavigator> LatticeNavigator </linkto>
47// </prerequisite>
48
49// <etymology>
50// TiledLineStepper is used to step a Vector cursor optimally through
51// a Lattice that is tiled.
52// </etymology>
53
54// <synopsis>
55// When you wish to traverse a Lattice (say, a PagedArray or an Image) you
56// will usually create a LatticeIterator. Once created, you may attach a
57// LatticeNavigator to the iterator. A TiledLineStepper, is a concrete class
58// derived from the abstract LatticeNavigator that allows you to move
59// a Vector cursor through the Lattice in a way that will minimize the
60// amount of cache memory consumed.
61// <p>
62// Some Lattices (in particular PagedArrays) are stored (on disk) in
63// tiles. For an N-dimensional Lattice a tile is an N-dimensional
64// subsection with fewer elements along each axis. For example a Lattice of
65// shape [512,512,4,32] may have a tile shape of [32,16,4,16], and there
66// will be 16*32*1*2 (=1024) tiles in the entire Lattice. To allow efficient
67// access of the data in a Lattice some tiles are cached in memory. As each
68// tile may consume a fair bit of memory (in this example 128kBytes,
69// assuming each element consumes 4 bytes), it is desirable to minimise the
70// number of tiles held in the cache. But it is also desirable to minimise
71// the number of times a tiles must be read into or written from the
72// cache as this may require a time consuming operation like disk I/O.
73// <p>
74// Now suppose you wanted to traverse a Lattice with a Vector cursor of
75// length 512 pixel aligned along the x-axis. Using a
76// <linkto class=LatticeStepper>LatticeStepper</linkto>, each Vector is
77// retrieved from the Lattice sequentially and without any consideration of
78// the underlying tile shape. What is the optimal cache size for the above
79// example?
80// <p>
81// Suppose we have a cache size of 16 ie., the number of tiles along the
82// x-axis. Then Vectors beginning at positions [0,0,0,0] to [0,15,0,0] will
83// be stored in the cache. But the next Vector beginning at position
84// [0,16,0,0] will flush the cache and read in another 16 tiles. This I/O
85// takes time and will occur 16 times for each plane in the four dimensional
86// Lattice. Further when the cursor moves to position [0,0,1,0] the 16 tiles
87// that where initially in the cache will need to be read again. To avoid
88// all this cache I/O it is better to have a bigger cache.
89// <p>
90// Suppose the cache size is 16*32 (=512) ie., enough tiles to contain an
91// (x,y)-plane. Then the cache size will not be flushed until the cursor is
92// moved to position [0,0,0,16]. Further the cache will never need to read
93// back into memory tiles that had previously been stored in there. The
94// cache is big enough to store tiles until they have been completely
95// used. But this cache is 64MBytes in size, and consumes too much memory
96// for many computers.
97// <p>
98// This where a TiledLineStepper is useful. Because it knows the shape of the
99// tiles in the underlying Lattice it moves the cursor to return all the
100// Vectors in the smallest possible cache of tiles before moving on to the
101// next set of tiles. Using the above example again, the TiledLineStepper will
102// move the beginning of the Vector cursor in the following pattern.
103// <srcblock>
104// [0,0,0,0], [0,1,0,0], [0,2,0,0], ... [0,15,0,0]
105// [0,0,1,0], [0,1,1,0], ... [0,15,1,0],
106// ... [0,15,3,0],
107// [0,0,0,1], ... [0,15,3,15]
108// </srcblock>
109// Moving the Vector cursor through all 16*4*16 (=1024 positions) can be
110// done by caching only 16 tiles in memory (those along the x-axis). Hence
111// the cache size need only be 2MBytes in size. Further once all 1024
112// vectors have been returned it is not necessary to read these 16 tiles
113// back into memory. All the data in those tiles has already been
114// accessed. Using a TiledLineStepper rather than a LatticeStepper has,
115// in this example, resulted in a drop in the required cache size from
116// 64MBytes down to 2MBytes.
117// <p>
118// In constructing a TiledLineStepper, you specify the Lattice shape, the
119// tile shape and the axis the Vector cursor will be aligned with. Specifying
120// an axis=0 will align the cursor with the x-axis and axis=2 will produce a
121// cursor that is along the z-axis. The length of the cursor is always the
122// same as the number of elements in the Lattice along the axis the cursor
123// is aligned with.
124// <br>It is possible to use the function <src>subSection</src> to
125// traverse only a subsection of the lattice.
126// <p>
127// The cursor position can be incremented or decremented to retrieve the next
128// or previous Vector in the Lattice. The position of the next Vector in the
129// Lattice will depend on the tile shape, and is described above. Within a tile
130// the Vector cursor will move first through the x-axis and then the y-axis
131// (assuming we have a cursor oriented along the z-axis). In general the lower
132// dimensions will be exhausted (within a tile) before moving the cursor
133// through higher dimensions. This intra-tile behaviour for cursor movement
134// extends to the inter-tile movement of the cursor between tiles.
135// </synopsis>
136
137// <example>
138// This example is of a global function that will do a 2-D inplace
139// complex Fourier transform of an arbitrary large Lattice (which
140// must have at least two dimensions).
141//
142// A two dimensional transform is done by successive one dimensional
143// transforms along all the rows and then all the columns in the
144// lattice. Scoping is used to destroy iterators once they have been
145// used. This frees up the cache memory associated with the cursor in each
146// iterator.
147//
148// <srcblock>
149// void FFT2DComplex (Lattice<Complex>& cArray,
150// const Bool direction)
151// {
152// const uInt ndim = cArray.ndim();
153// AlwaysAssert(ndim > 1, AipsError);
154// const IPosition latticeShape = cArray.shape();
155// const uInt nx=latticeShape(0);
156// const uInt ny=latticeShape(1);
157// const IPosition tileShape = cArray.niceCursorShape();
158//
159// {
160// TiledLineStepper tsx(latticeShape, tileShape, 0);
161// LatticeIterator<Complex> lix(cArray, tsx);
162// FFTServer<Float,Complex> fftx(IPosition(1, nx));
163// for (lix.reset();!lix.atEnd();lix++) {
164// fftx.fft(lix.rwVectorCursor(), direction);
165// }
166// }
167// {
168// TiledLineStepper tsy(latticeShape, tileShape, 1);
169// LatticeIterator<Complex> liy(cArray, tsy);
170// FFTServer<Float,Complex> ffty(IPosition(1, ny));
171// for (liy.reset();!liy.atEnd();liy++) {
172// ffty.fft(liy.rwVectorCursor(), direction);
173// }
174// }
175// }
176// </srcblock>
177// </example>
178
179// <motivation>
180// Moving through a Lattice by equal sized chunks, and without regard
181// to the nature of the data, is a basic and common procedure.
182// </motivation>
183
184// <todo asof="1997/03/28">
185// <li> Support for Matrix and higher dimensional cursors can be used.
186// </todo>
187
189 public:
190 // Construct a TiledLineStepper by specifying the Lattice shape,
191 // a tile shape and the axis along which the Vector cursor will lie
192 // (0 means the x-axis). Is is nearly always advisable to make the
193 // tileShape identical to the Lattice tileShape. This can be obtained by
194 // <src>lat.niceCursorShape(lat.advisedMaxPixels())</src>
195 // where <src>lat</src> is a Lattice object.
197
198 // The copy constructor uses copy semantics.
200
202
203 // The assignment operator uses copy semantics.
205
206 // Increment operator (postfix or prefix version) - move the cursor
207 // forward one step. Returns True if the cursor was moved.
208 virtual Bool operator++(int);
209
210 // Decrement operator (postfix or prefix version) - move the cursor
211 // backwards one step. Returns True if the cursor was moved.
212 virtual Bool operator--(int);
213
214 // Function to move the cursor to the beginning of the Lattice. Also
215 // resets the number of steps (<src>nsteps</src> function) to zero.
216 virtual void reset();
217
218 // Function which returns "True" if the cursor is at the beginning of the
219 // Lattice, otherwise, returns "False"
220 virtual Bool atStart() const;
221
222 // Function which returns "True" if an attempt has been made to increment
223 // the cursor beyond the end of the Lattice.
224 virtual Bool atEnd() const;
225
226 // Function to return the number of steps (increments & decrements) taken
227 // since construction (or since last reset). This is a running count of
228 // all cursor movement (operator++ or operator--), even though
229 // N-increments followed by N-decrements will always leave the cursor in
230 // the original position.
231 virtual uInt nsteps() const;
232
233 // Function which returns the current position of the beginning of the
234 // cursor. The <src>position</src> function is relative to the origin
235 // in the main Lattice.
236 // <group>
237 virtual IPosition position() const;
238 // </group>
239
240 // Function which returns the current position of the end of the
241 // cursor. The <src>endPosition</src> function is relative to the origin
242 // in the main Lattice.
243 // <group>
244 virtual IPosition endPosition() const;
245 // </group>
246
247 // Functions which returns the shape of the Lattice being iterated
248 // through. <src>latticeShape</src> always returns the shape of the main
249 // Lattice while <src>subLatticeShape</src> returns the shape of any
250 // sub-Lattice defined using the <src>subSection</src> function.
251 // <group>
252 virtual IPosition latticeShape() const;
253 virtual IPosition subLatticeShape() const;
254 // </group>
255
256 // Function which returns the shape of the cursor. This always includes
257 // all axes (ie. it includes degenerates axes)
258 virtual IPosition cursorShape() const;
259
260 // Function which returns the axes of the cursor.
261 virtual IPosition cursorAxes() const;
262
263 // Function which returns the shape of the "tile" the cursor will iterate
264 // through before moving onto the next tile. THIS IS NOT THE SAME AS THE
265 // TILE SHAPE USED BY THE LATTICE. It is nearly the same except that the
266 // axis the cursor is aligned with is replaced by the shape of the Lattice
267 // on that axis. eg., If a Lattice has a shape of [512,512,4,32] and a
268 // tile shape of [32,16,4,16] then <src>tileShape()</src> will return
269 // [512,16,4,16] if the cursor is along the x-axis and [32,512,4,16] if the
270 // cursor is along the y-axis.
272
273 // Function which returns "True" if the increment/decrement operators have
274 // moved the cursor position such that part of the cursor beginning or end
275 // is hanging over the edge of the Lattice. This always returns False.
276 virtual Bool hangOver() const;
277
278 // Functions to specify a "section" of the Lattice to step over. A section
279 // is defined in terms of the Bottom Left Corner (blc), Top Right Corner
280 // (trc), and step size (inc), on ALL of its axes, including degenerate
281 // axes. The step size defaults to one if not specified.
282 // <group>
283 virtual void subSection(const IPosition& blc, const IPosition& trc);
284 virtual void subSection(const IPosition& blc, const IPosition& trc, const IPosition& inc);
285 // </group>
286
287 // Return the bottom left hand corner (blc), top right corner (trc) or
288 // step size (increment) used by the current sub-Lattice. If no
289 // sub-Lattice has been defined (with the <src>subSection</src> function)
290 // these functions return blc=0, trc=latticeShape-1, increment=1, ie. the
291 // entire Lattice.
292 // <group>
293 virtual IPosition blc() const;
294 virtual IPosition trc() const;
295 virtual IPosition increment() const;
296 // </group>
297
298 // Return the axis path.
299 // See <linkto class=LatticeStepper>LatticeStepper</linkto> for a
300 // description and examples.
301 virtual const IPosition& axisPath() const;
302
303 // Function which returns a pointer to dynamic memory of an exact copy
304 // of this instance. The pointer returned by this function must
305 // be deleted externally.
306 virtual LatticeNavigator* clone() const;
307
308 // Function which checks the internal data of this class for correct
309 // dimensionality and consistant values.
310 // Returns True if everything is fine otherwise returns False
311 virtual Bool ok() const;
312
313 // Calculate the cache size (in tiles) for this type of access to a lattice
314 // in the given row of the tiled hypercube.
315 virtual uInt calcCacheSize(const IPosition& cubeShape, const IPosition& tileShape,
316 uInt maxCacheSize, uInt bucketSize) const;
317
318 private:
319 // Prevent the default constructor from being used.
321
322 IPosition itsBlc; // # Bottom Left Corner
323 IPosition itsTrc; // # Top Right Corner
324 IPosition itsInc; // # Increment
325 LatticeIndexer itsSubSection; // # The current subsection
326 LatticeIndexer itsIndexer; // # For moving within a tile
327 LatticeIndexer itsTiler; // # For moving between tiles
328 IPosition itsIndexerCursorPos; // # The current position of the iterator.
329 IPosition itsTilerCursorPos; // # The current position of the iterator.
330 IPosition itsCursorShape; // # The shape of the cursor for itsIndexer
331 IPosition itsTileShape; // # The tile shape (= itsTiler cursor shape)
332 IPosition itsAxisPath; // # Path for traversing
333 uInt itsNsteps; // # The number of iterator steps taken so far;
334 uInt itsAxis; // # The axis containing the data vector
335 Bool itsEnd; // # Is the cursor beyond the end?
336 Bool itsStart; // # Is the cursor at the beginning?
337};
338
339} // namespace casacore
340
341#endif
LatticeNavigator()
Default constructor.
virtual Bool atEnd() const
Function which returns "True" if an attempt has been made to increment the cursor beyond the end of t...
virtual Bool operator++(int)
Increment operator (postfix or prefix version) - move the cursor forward one step.
virtual IPosition blc() const
Return the bottom left hand corner (blc), top right corner (trc) or step size (increment) used by the...
virtual LatticeNavigator * clone() const
Function which returns a pointer to dynamic memory of an exact copy of this instance.
virtual Bool atStart() const
Function which returns "True" if the cursor is at the beginning of the Lattice, otherwise,...
TiledLineStepper(const TiledLineStepper &other)
The copy constructor uses copy semantics.
TiledLineStepper(const IPosition &latticeShape, const IPosition &tileShape, const uInt axis)
Construct a TiledLineStepper by specifying the Lattice shape, a tile shape and the axis along which t...
TiledLineStepper()
Prevent the default constructor from being used.
virtual Bool ok() const
Function which checks the internal data of this class for correct dimensionality and consistant value...
virtual Bool hangOver() const
Function which returns "True" if the increment/decrement operators have moved the cursor position suc...
virtual void subSection(const IPosition &blc, const IPosition &trc, const IPosition &inc)
virtual uInt calcCacheSize(const IPosition &cubeShape, const IPosition &tileShape, uInt maxCacheSize, uInt bucketSize) const
Calculate the cache size (in tiles) for this type of access to a lattice in the given row of the tile...
virtual IPosition trc() const
virtual const IPosition & axisPath() const
Return the axis path.
virtual IPosition position() const
Function which returns the current position of the beginning of the cursor.
virtual IPosition subLatticeShape() const
virtual IPosition cursorAxes() const
Function which returns the axes of the cursor.
virtual IPosition latticeShape() const
Functions which returns the shape of the Lattice being iterated through.
TiledLineStepper & operator=(const TiledLineStepper &other)
The assignment operator uses copy semantics.
virtual uInt nsteps() const
Function to return the number of steps (increments & decrements) taken since construction (or since l...
virtual void subSection(const IPosition &blc, const IPosition &trc)
Functions to specify a "section" of the Lattice to step over.
virtual Bool operator--(int)
Decrement operator (postfix or prefix version) - move the cursor backwards one step.
IPosition tileShape() const
Function which returns the shape of the "tile" the cursor will iterate through before moving onto the...
virtual void reset()
Function to move the cursor to the beginning of the Lattice.
virtual IPosition cursorShape() const
Function which returns the shape of the cursor.
virtual IPosition increment() const
virtual IPosition endPosition() const
Function which returns the current position of the end of the cursor.
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
unsigned int uInt
Definition aipstype.h:49
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40