casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Lattices.h
Go to the documentation of this file.
1 //# Lattices.h: Regular N-dimensional data structures.
2 //# Copyright (C) 1996,1997,1998,1999,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_LATTICES_H
29 #define LATTICES_LATTICES_H
30 
31 
32 //#include <casacore/casa/Arrays/ArrayLattice.h>
33 //#include <casacore/casa/Arrays/PagedArray.h>
34 //#include <casacore/casa/Arrays/TempLattice.h>
35 //#include <casacore/casa/Arrays/LatticeLocker.h>
36 //#include <casacore/casa/Arrays/TiledShape.h>
37 
38 //#include <casacore/casa/Arrays/LatticeApply.h>
39 //#include <casacore/casa/Arrays/LatticeIterator.h>
40 //#include <casacore/casa/Arrays/LatticeStepper.h>
41 //#include <casacore/casa/Arrays/TileStepper.h>
42 //#include <casacore/casa/Arrays/TiledLineStepper.h>
43 
44 //#include <casacore/lattices/Lattices/SubLattice.h>
45 
46 //#include <casacore/lattices/LRegions.h>
47 //#include <casacore/lattices/LEL.h>
48 //#include <casacore/lattices/LatticeMath.h>
49 
50 namespace casacore { //# NAMESPACE CASACORE - BEGIN
51 
52 // <module>
53 
54 // <summary>
55 // Regular N-dimensional data structures.
56 // </summary>
57 
58 // <prerequisite>
59 // <li> Programmers of new Lattice classes should understand Inheritance
60 // <li> Users of the Lattice classes should understand Polymorphism.
61 // <li> class <linkto class=IPosition>IPosition</linkto>
62 // <li> class <linkto class=Array>Array</linkto>
63 // </prerequisite>
64 
65 // <reviewed reviewer="Peter Barnes" date="1999/10/30" demos="">
66 // </reviewed>
67 
68 // <etymology>
69 // Lattice: "A regular, periodic configuration of points, particles, or
70 // objects, throughout an area of a space..." (American Heritage Directory)
71 // This definition matches our own: an N-dimensional arrangement of data
72 // on regular orthogonal axes.
73 // <p>
74 // In Casacore, we have used the ability to call many things by one generic
75 // name (Lattice) to create a number of classes which have different storage
76 // techniques (e.g. core memory, disk, etc...). The name Lattice should
77 // make the user think of a class interface (or member functions) which all
78 // Lattice objects have in common. If functions require a Lattice
79 // argument, the classes described here may be used interchangeably, even
80 // though their actual internal workings are very different.
81 // </etymology>
82 
83 // <synopsis>
84 // The Lattice module may be broken up into a few areas:
85 // <ol>
86 //
87 // <li> Lattices - the actual holders of lattice-like data which all share a
88 // common <linkto class="Lattice">interface</linkto>. The following items
89 // are all Lattices and may be used polymorphically wherever a Lattice is
90 // called for.
91 // <ul>
92 // <li>The <linkto class="ArrayLattice">ArrayLattice</linkto> class adds
93 // the interface requirements of a Lattice to a Casacore
94 // <linkto class="Array">Array</linkto>. The data inside an ArrayLattice
95 // are not stored on disk. This n-dimensional array class is the simplest
96 // of the Lattices. Users construct the ArrayLattice with an argument
97 // which is either an IPosition which describes the array shape or a
98 // previously instantiated Array object that may already contain data. In
99 // the former case, some Lattice operation must be done to fill the data.
100 // The ArrayLattice, like all Lattices, may be iterated through with a
101 // <linkto class=LatticeIterator>LatticeIterator</linkto> (see below).
102 // <br>Iteration can also be done using
103 // <linkto class=LatticeApply>LatticeApply</linkto> and some helper
104 // classes. It makes it possible to concentrate on the algorithm.
105 // <srcblock>
106 // // Make an Array of shape 3x4x5
107 //
108 // Array<Float> simpleArray(IPosition(3,3,4,5));
109 //
110 // // fill it with a gradient
111 //
112 // for (Int k=0; k<5; k++)
113 // for (Int j=0; j<4; j++)
114 // for (Int i=0; i<3; i++)
115 // simpleArray(IPosition(3,i,j,k)) = i+j+k;
116 //
117 // // use the array to create an ArrayLattice.
118 //
119 // ArrayLattice<Float> lattice(simpleArray);
120 // </srcblock>
121 //
122 // <li>The <linkto class="PagedArray">PagedArray</linkto> class stores its
123 // data on disk in the Table format
124 // and pages it into random access memory for use. Paging is
125 // used here to describe the process of getting pieces of data small
126 // enough to fit into active memory even if the whole data set is much too
127 // large. This class "feels" like an array but may hold very large amounts
128 // of data. The paging has an added effect: all the data may be made
129 // persistent, so it stays around after the application ends.
130 // When you use PagedArrays - use
131 // them because you need persistent data and/or paging into large data sets.
132 // <br>
133 // The persistence is done using a <linkto module="Tables">Table</linkto>,
134 // and uses the <linkto module="Tables:TiledStMan">tiled storage
135 // manager</linkto>. This means that accessing the data along any axis is
136 // equally efficient (depending on the tile shape used).
137 // <br>
138 // A PagedArray constructor allows previously created PagedArrays to be
139 // recalled from disk. Much of the time, the PagedArray will be
140 // constructed with a <linkto class=TiledShape>TiledShape</linkto>
141 // argument which describes the array and tile shape
142 // and a Table argument for use as the place of storage. Then the
143 // PagedArray may be filled using any of the access functions of Lattices
144 // (like the LatticeIterator.)
145 //
146 // <srcblock>
147 // // Create a PagedArray from a Table already existing on disk.
148 //
149 // PagedArray<Float> lattice(fileName);
150 //
151 // // Create a LatticeIterator to access the Lattice in optimal tile
152 // // shaped chunks.
153 //
154 // LatticeIterator<Float> iter(lattice);
155 //
156 // // Iterate through and do something simple; here we just
157 // // sum up all the values in the Lattice
158 //
159 // Float dSum = 0;
160 // for(iter.reset(); !iter.atEnd(); iter++) {
161 // dSum += sum(iter.cursor());
162 // }
163 // </srcblock>
164 //
165 // <li>The <linkto class="HDF5Lattice">HDF5Lattice</linkto> class stores its
166 // data on disk in <a href="http://www.hdfgroup.org/HDF5">HDF5</a> format.
167 // It works in the same way as PagedArray.
168 //
169 // </ul>
170 //
171 // <li> <linkto class="LatticeIterator">LatticeIterator</linkto> - the
172 // object which allows iteration through any Lattice's data. This comes in
173 // two types: the <src>RO_LatticeIterator</src> which should be used if you
174 // are not going to change the Lattice's data, and the
175 // <src>LatticeIterator</src> if you need to change the data in the Lattice.
176 // <br>Note that iteration can also be done using
177 // <linkto class=LatticeApply>LatticeApply</linkto> and some helper
178 // classes. It makes it possible to concentrate on the algorithm.
179 // <ul>
180 // <li> The <linkto class="RO_LatticeIterator">RO_LatticeIterator</linkto>
181 // class name reflects its role as a means of iterating a "Read-Only" array
182 // (hereafter refered to as a "cursor") through a Lattice based object,
183 // from beginning to end. Think of a window into the Lattice that moves to
184 // a new location when requested. The Lattice doesn't change but you may
185 // see all or part of its data as the cursor "window" moves around. This
186 // class allows optimized read-only iteration through any instance of a
187 // class derived from Lattice. The cursor's shape is defined by the user and
188 // moved through the Lattice in an orderly fashion also defined by the user.
189 // Since the cursor is "read-only" it can only be used to "get" the data
190 // out of the Lattice. RO_LatticeIterators are constructed with the Lattice
191 // to be iterated as the first argument. The optional second constructor
192 // argument is either an IPosition which defines the shape of the cursor
193 // or a <linkto class=LatticeNavigator>LatticeNavigator</linkto> argument.
194 // The IPosition argument cause the iterator
195 // to move the cursor in a simple pattern; the cursor starts at the Lattice's
196 // origin and moves in the direction of the x-axis, then the y-axis, then
197 // the z-axis, etc.. If a LatticeNavigator argument is given, more
198 // control over the cursor shape and path are available. If no second
199 // argument is given, the optimal
200 // <linkto class=TileStepper>TileStepper</linkto> navigator will be used.
201 // <srcblock>
202 // // simple route - define a cursor shape that is the xy plane of our
203 // lattice.
204 //
205 // IPosition cursorShape(2, lattice.shape()(0), lattice.shape()(1));
206 // LatticeIterator<Float> iter(lattice, cursorShape);
207 // for (iter.reset(); !iter.atEnd(); iter++) {
208 // minMax(iter.cursor(), min, max);
209 // }
210 // </srcblock>
211 //
212 // <li> The <linkto class="LatticeIterator">LatticeIterator</linkto> class
213 // name reflects its role as a means of iterating a read and write cursor
214 // through a Lattice based object. Not only does the cursor allow you to
215 // inspect the Lattice data but you may also change the Lattice via
216 // operations on the cursor. This class provides optimized read and write
217 // iteration through any class derived from Lattice. The technique is
218 // identical to the RO_LatticeIterator. But the cursor, in this case, is
219 // a reference back to the data in the Lattice. This means that changes
220 // made to the cursor propagate back to the Lattice. This is especially
221 // useful for the PagedArray and PagedImage classes. These two classes
222 // are constructed empty and need iteration to fill in the Lattice data.
223 // <srcblock>
224 // // make an empty PagedArray and fill it. The Table that stores the
225 // // PagedArray is deleted when the PagedArray goes out of scope
226 //
227 // PagedArray<Float> lattice(IPosition(4,100,200,300,50));
228 // LatticeIterator<Float> iter(lattice, IPosition(2, 100, 200));
229 //
230 // // fill each plane with the "distance" of the iterator from the origin
231 //
232 // for(iter.reset();!iter.atEnd(); iter++) {
233 // iter.woCursor() = iter.nsteps();
234 // }
235 // </srcblock>
236 // </ul>
237 //
238 // <li> LatticeNavigators - the objects which define the method and path used
239 // by a LatticeIterator to move the cursor through a Lattice. Many
240 // different paths are possible. We leave it you to choose the
241 // <linkto class=LatticeNavigator>LatticeNavigator</linkto>
242 // (method and path) when using a LatticeIterator.
243 // <ul>
244 // <li> The <linkto class="LatticeStepper">LatticeStepper</linkto> class
245 // is used to define the steps which the cursor takes during its path
246 // through the Lattice. Every element of the Lattice will be covered,
247 // starting at the origin and ending at the "top right corner." This
248 // class provides the information needed by a LatticeIterator to do
249 // non-standard movements of the cursor during iteration. The shape of
250 // the cursor is specified by the second IPosition argument of the
251 // LatticeStepper. The order of the axis is important. An IPosition(1,5)
252 // is a five element vector along the x-axis. An IPosition(3,1,1,5) is a
253 // five element vector along the z-axis. The degenerate axes (axes with
254 // lengths of one) act as place holders. The third argument in the
255 // LatticeStepper constructor is the "orientation" IPosition. This
256 // describes the order of the axis for the cursor to follow. Again, we
257 // treat the elements, in order, of the IPosition as the designators of
258 // the appropriate axis. The zeroth element indicates which axis is the
259 // fastest moving, the first element indicates which axis is the second
260 // fastest moving etc. eg. The IPosition(3,2,0,1) says the LatticeIterator
261 // should start with the z-axis, next follow the x-axis, and finish with
262 // the y-axis. A single element cursor would thus move through a cube of
263 // dimension(x,y,z) from (0,0,0) up the z-axis until reaching the maximum
264 // (0,0,z-1) and then start on (1,0,0) and move to (1,0,z-1), etc.
265 // <srcblock>
266 // // The shape of our Lattice - a 4 dimensional image of shape (x,y,z,t) -
267 // // and the shape of the cursor
268 //
269 // IPosition latticeShape(image.shape());
270 // IPosition cursorShape(3, lattticeShape(0), 1, latticeShape(2));
271 //
272 // // Define the path the cursor should follow, we list x and z first, even though
273 // // no iterations will be done along those axes since the cursor is an
274 // // integral subshape of the Lattice. The cursor will move along the y-axis
275 // // and then increment the t-axis. The construct the Navigator and Iterator
276 //
277 // IPosition order(4,0,2,1,3);
278 // LatticeStepper nav(latticeShape, cursorShape, order);
279 // LatticeIterator<Float> iter(image, nav);
280 // </srcblock>
281 //
282 // <li>
283 // The <linkto class="TiledLineStepper">TiledLineStepper</linkto> class
284 // allows you to iterate through a Lattice with a Vector cursor.
285 // However, it steps through the Lattice in an order which is
286 // optimum with regard to the I/O of the tiles with which the Lattice is
287 // constructed.
288 //
289 // <srcblock>
290 //
291 // // Set up a TiledLineStepper to return profiles along the specified
292 // // axis from a PagedArray (not all Lattices have the tileShape member
293 // // function). Then create the iterator as well.
294 //
295 // TiledLineStepper nav(lattice.shape(), lattice.tileShape(), axis);
296 // LatticeIterator<Complex> nav(lattice, nav);
297 // </srcblock>
298 //
299 // <li>
300 // The <linkto class="TileStepper">TileStepper</linkto> class
301 // allows you to iterate through a Lattice in the optimum way.
302 // It steps through the lattice tile by tile minimizing I/O and memory usage.
303 // It is very well suited for pixel based operations.
304 // However, its iteration order is such that it cannot be used for
305 // a certain subset of pixels (e.g. a vector) is needed.
306 // <br>This navigator is the default when no navigator is given when
307 // constructing a (RO_)LatticeIterator.
308 //
309 // </ul>
310 //
311 // <li> <linkto class="MaskedLattice">MaskedLattice</linkto> - a
312 // Lattice with a mask. It is an abstract base class for
313 // various types of MaskedLattices. A MaskedLattice does not need
314 // to contain a mask (see e.g. SubLattice below), although the user
315 // can always ask for the mask. The function <src>isMasked()</src>
316 // tells if there is really a mask. If not, users could take
317 // advantage by shortcutting some code for better performance.
318 // I.e. a function can test if a the MaskedLattice is really masked
319 // and can take a special route if not.
320 // Of course, doing that requires more coding, so it should only
321 // be done where performance is a real issue.
322 // <ul>
323 // <li> A <linkto class="SubLattice">SubLattice</linkto> represents
324 // a rectangular subset of a Lattice. The SubLattice can be a simple
325 // box, but it can also be a circle, polygon, etc.
326 // In the latter case the SubLattice contains a mask
327 // telling which pixels in the bounding box actually belong to the
328 // circle or polygon. In the case of a box there is no mask, because
329 // there is no need to (because a box is already rectangular).
330 // <br> A SubLattice can be constructed from any Lattice and a
331 // <linkto class=LatticeRegion>LatticeRegion</linkto> telling which
332 // part to take from the Lattice.
333 // If the SubLattice is constructed from a <src>const Lattice</src>,
334 // the SubLattice is not writable. Otherwise it is writable if the
335 // lattice is writable.
336 // <p>
337 // There is a rich variety of <linkto class=LCRegion>region</linkto>
338 // classes which can be used to define a LatticeRegion in pixel coordinates.
339 // They are described in module
340 // <a href="group__LRegions__module.html">LRegions</a>.
341 //
342 // <li> Module <a href="group__LEL__module.html">LEL</a> contains classes to
343 // form a mathematical expression of lattices. All standard operators, regions,
344 // and many, many <linkto class=LatticeExprNode>functions</linkto>
345 // can be used in an expression.
346 // </ul>
347 //
348 // <li> <linkto class=LatticeLocker>LatticeLocker</linkto>
349 // can be used to acquire a (user) lock on a lattice.
350 // The lock can be a read or write lock.
351 // The destructor releases the lock when needed.
352 // <br>Lattices on disk can be used (read and write) by multiple processes.
353 // The Table locking/synchronization mechanism takes care that sharing
354 // such a lattice is done in an orderly way.
355 // Usually the default locking mechanism is sufficient.
356 // LatticeLocker is useful when finer locking control is needed for a
357 // disk-based lattice.
358 //
359 // <note role=warning> The following are listed for low-level programmers.
360 // Lattice users need not understand them.</note> The Lattice directory
361 // contains several files relevant only to implementation.
362 //
363 // <ul>
364 // <li> <linkto class="LatticeBase">LatticeBase</linkto> - a non-templated
365 // abstract base class defining the type-independent interface to classes
366 // which must act as Lattices do.
367 // <li> <linkto class="Lattice">Lattice</linkto> - a templated
368 // abstract base class (derived from LatticeBase)
369 // defining the interface to classes which must act as Lattices do.
370 // The user simply publicly inherits from Lattice and defines the member
371 // functions declared as pure abstract in the Lattice header file.
372 // <li> The <linkto class="LatticeNavigator">LatticeNavigator</linkto>
373 // class name defines the interface used for navigating through a Lattice
374 // by iteration. This class is an abstract base. Classes derived from
375 // this (currently
376 // <linkto class="LatticeStepper">LatticeStepper</linkto>,
377 // <linkto class="TiledLineStepper">TiledLineStepper</linkto>, and
378 // <linkto class="TileStepper">TileStepper</linkto>) must
379 // define the path the iterator cursor follows, the size of the movement
380 // of the cursor with each iteration, and the behaviour of that cursor
381 // shape as it moves through a Lattice.
382 // <li> <linkto class="LatticeIndexer">LatticeIndexer</linkto> - this
383 // class contains the currently defined Lattice and sub-Lattice shape. It
384 // is used only by navigator classes as it contains
385 // member functions for moving a cursor through a defined sub-Lattice.
386 // <li> The
387 // <linkto class="LatticeIterInterface">LatticeIterInterface</linkto>
388 // class defines the interface for a specific Lattice's iterator. This
389 // class is a base class with a default iterator implementation.
390 // Lattice based classes may need to derive an iterator from
391 // LatticeIterInterface to optimize for the LatticeIterator
392 // internals which impact upon the new Lattice.
393 // <li> <linkto class="PagedArrIter">PagedArrIter</linkto> - this class is
394 // the PagedArray's optimized method of iterating. This class is a
395 // "letter" utilized within the LatticeIterator "envelope" and cannot
396 // be instantiated by any user.
397 // <li> <linkto class="LCRegion">LCRegion</linkto> - this class is the
398 // (abstract) base class for regions in pixel coordinates.
399 // </ul>
400 // </ol>
401 // </synopsis>
402 
403 // <motivation>
404 // Lattices allow the various holders of data to assume a general method
405 // of treatment; by making interfaces in terms of the Lattice class,
406 // the programmer can polymorphically operate on objects derived from the
407 // Lattice class.
408 // </motivation>
409 
410 // <todo asof="1998/10/10">
411 // <li> Make MaskedIterator class?
412 // </todo>
413 
414 // </module>
415 
416 
417 } //# NAMESPACE CASACORE - END
418 
419 #endif