casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Lattices.h
Go to the documentation of this file.
00001 //# Lattices.h: Regular N-dimensional data structures.
00002 //# Copyright (C) 1996,1997,1998,1999,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: Lattices.h 20691 2009-07-14 03:13:54Z Malte.Marquarding $
00027 
00028 #ifndef LATTICES_LATTICES_H
00029 #define LATTICES_LATTICES_H
00030 
00031 
00032 //#include <casa/Arrays/ArrayLattice.h>
00033 //#include <casa/Arrays/PagedArray.h>
00034 //#include <casa/Arrays/TempLattice.h>
00035 //#include <casa/Arrays/LatticeLocker.h>
00036 //#include <casa/Arrays/TiledShape.h>
00037 
00038 //#include <casa/Arrays/LatticeApply.h>
00039 //#include <casa/Arrays/LatticeIterator.h>
00040 //#include <casa/Arrays/LatticeStepper.h>
00041 //#include <casa/Arrays/TileStepper.h>
00042 //#include <casa/Arrays/TiledLineStepper.h>
00043 
00044 //#include <lattices/Lattices/SubLattice.h>
00045 //#include <lattices/Lattices/LatticeExpr.h>
00046 
00047 //#include <lattices/Lattices/LatticeRegion.h>
00048 //#include <lattices/Lattices/LCSlicer.h>
00049 //#include <lattices/Lattices/LCBox.h>
00050 //#include <lattices/Lattices/LCEllipsoid.h>
00051 //#include <lattices/Lattices/LCPolygon.h>
00052 //#include <lattices/Lattices/LCUnion.h>
00053 //#include <lattices/Lattices/LCIntersection.h>
00054 //#include <lattices/Lattices/LCDifference.h>
00055 //#include <lattices/Lattices/LCConcatenation.h>
00056 //#include <lattices/Lattices/LCComplement.h>
00057 //#include <lattices/Lattices/LCExtension.h>
00058 
00059 namespace casa { //# NAMESPACE CASA - BEGIN
00060 
00061 // <module>
00062 
00063 // <summary>
00064 // Regular N-dimensional data structures.
00065 // </summary>
00066 
00067 // <prerequisite>
00068 //   <li> Programmers of new Lattice classes should understand Inheritance
00069 //   <li> Users of the Lattice classes should understand Polymorphism.
00070 //   <li> class <linkto class=IPosition>IPosition</linkto>
00071 //   <li> class <linkto class=Array>Array</linkto>
00072 // </prerequisite>
00073 
00074 // <reviewed reviewer="Peter Barnes" date="1999/10/30" demos="">
00075 // </reviewed>
00076 
00077 // <etymology>
00078 // Lattice: "A regular, periodic configuration of points, particles, or
00079 // objects, throughout an area of a space..." (American Heritage Directory)
00080 // This definition matches our own: an N-dimensional arrangement of data
00081 // on regular orthogonal axes.
00082 // <p>
00083 // In AIPS++, we have used the ability to call many things by one generic
00084 // name (Lattice) to create a number of classes which have different storage
00085 // techniques (e.g. core memory, disk, etc...).  The name Lattice should
00086 // make the user think of a class interface (or member functions) which all
00087 // Lattice objects have in common.  If functions require a Lattice
00088 // argument, the classes described here may be used interchangeably, even
00089 // though their actual internal workings are very different.
00090 // </etymology>
00091 
00092 // <synopsis>
00093 // The Lattice module may be broken up into a few areas:
00094 // <ol> 
00095 //
00096 // <li> Lattices - the actual holders of lattice-like data which all share a
00097 // common <linkto class="Lattice">interface</linkto>.  The following items
00098 // are all Lattices and may be used polymorphically wherever a Lattice is
00099 // called for.
00100 //  <ul>
00101 //   <li>The <linkto class="ArrayLattice">ArrayLattice</linkto> class adds
00102 //   the interface requirements of a Lattice to an AIPS++ 
00103 //   <linkto class="Array">Array</linkto>. The data inside an ArrayLattice
00104 //   are not stored on disk.  This n-dimensional array class is the simplest
00105 //   of the Lattices.  Users construct the ArrayLattice with an argument
00106 //   which is either an IPosition which describes the array shape or a
00107 //   previously instantiated Array object that may already contain data. In
00108 //   the former case, some Lattice operation must be done to fill the data.
00109 //   The ArrayLattice, like all Lattices, may be iterated through with a
00110 //   <linkto class=LatticeIterator>LatticeIterator</linkto> (see below).
00111 //   <br>Iteration can also be done using
00112 //   <linkto class=LatticeApply>LatticeApply</linkto> and some helper
00113 //   classes. It makes it possible to concentrate on the algorithm.
00114 // <srcblock>
00115 // // Make an Array of shape 3x4x5
00116 // 
00117 // Array<Float> simpleArray(IPosition(3,3,4,5));
00118 //
00119 // // fill it with a gradient
00120 //
00121 // for (Int k=0; k<5; k++)
00122 //   for (Int j=0; j<4; j++)
00123 //     for (Int i=0; i<3; i++) 
00124 //       simpleArray(IPosition(3,i,j,k)) = i+j+k;
00125 //
00126 // // use the array to create an ArrayLattice.
00127 //
00128 // ArrayLattice<Float> lattice(simpleArray);
00129 // </srcblock>
00130 //
00131 //   <li>The <linkto class="PagedArray">PagedArray</linkto> class stores its
00132 //   data on disk in the Table format
00133 //   and pages it into random access memory for use.  Paging is
00134 //   used here to describe the process of getting pieces of data small
00135 //   enough to fit into active memory even if the whole data set is much too
00136 //   large.  This class "feels" like an array but may hold very large amounts 
00137 //   of data.  The paging has an added effect: all the data may be made
00138 //   persistent, so it stays around after the application ends.
00139 //   When you use PagedArrays - use 
00140 //   them because you need persistent data and/or paging into large data sets.
00141 //   <br>
00142 //   The persistence is done using a <linkto module="Tables">Table</linkto>,
00143 //   and uses the <linkto module="Tables:TiledStMan">tiled storage
00144 //   manager</linkto>.  This means that accessing the data along any axis is
00145 //   equally efficient (depending on the tile shape used).
00146 //   <br>
00147 //   A PagedArray constructor allows previously created PagedArrays to be
00148 //   recalled from disk.  Much of the time, the PagedArray will be
00149 //   constructed with a <linkto class=TiledShape>TiledShape</linkto>
00150 //   argument which describes the array and tile shape
00151 //   and a Table argument for use as the place of storage.  Then the
00152 //   PagedArray may be filled using any of the access functions of Lattices
00153 //   (like the LatticeIterator.)
00154 //
00155 // <srcblock>
00156 // // Create a PagedArray from a Table already existing on disk.  
00157 //
00158 // PagedArray<Float> lattice(fileName);
00159 //
00160 // // Create a LatticeIterator to access the Lattice in optimal tile
00161 // // shaped chunks.
00162 //
00163 // LatticeIterator<Float> iter(lattice);
00164 //
00165 // // Iterate through and do something simple; here we just 
00166 // // sum up all the values in the Lattice
00167 //
00168 // Float dSum = 0;
00169 // for(iter.reset(); !iter.atEnd(); iter++) {
00170 //   dSum += sum(iter.cursor());
00171 // }
00172 // </srcblock>
00173 //
00174 //   <li>The <linkto class="HDF5Lattice">HDF5Lattice</linkto> class stores its
00175 //   data on disk in <a href="http://www.hdfgroup.org/HDF5">HDF5</a> format.
00176 //   It works in the same way as PagedArray.
00177 //
00178 //  </ul>
00179 //
00180 // <li> <linkto class="LatticeIterator">LatticeIterator</linkto> - the
00181 // object which allows iteration through any Lattice's data. This comes in
00182 // two types: the <src>RO_LatticeIterator</src> which should be used if you
00183 // are not going to change the Lattice's data, and the
00184 // <src>LatticeIterator</src> if you need to change the data in the Lattice.
00185 // <br>Note that iteration can also be done using
00186 // <linkto class=LatticeApply>LatticeApply</linkto> and some helper
00187 // classes. It makes it possible to concentrate on the algorithm.
00188 //  <ul>
00189 //  <li> The <linkto class="RO_LatticeIterator">RO_LatticeIterator</linkto>
00190 //  class name reflects its role as a means of iterating a "Read-Only" array
00191 //  (hereafter refered to as a "cursor") through a Lattice based object,
00192 //  from beginning to end.  Think of a window into the Lattice that moves to
00193 //  a new location when requested.  The Lattice doesn't change but you may
00194 //  see all or part of its data as the cursor "window" moves around.  This
00195 //  class allows optimized read-only iteration through any instance of a
00196 //  class derived from Lattice.   The cursor's shape is defined by the user and
00197 //  moved through the Lattice in an orderly fashion also defined by the user.
00198 //  Since the cursor is "read-only" it can only be used to "get" the data
00199 //  out of the Lattice.  RO_LatticeIterators are constructed with the Lattice
00200 //  to be iterated as the first argument. The optional second constructor 
00201 //  argument is either an IPosition which defines the shape of the cursor 
00202 //  or a <linkto class=LatticeNavigator>LatticeNavigator</linkto> argument.
00203 //  The IPosition argument cause the iterator
00204 //  to move the cursor in a simple pattern; the cursor starts at the Lattice's
00205 //  origin and moves in the direction of the x-axis, then the y-axis, then 
00206 //  the z-axis, etc..  If a LatticeNavigator argument is given, more
00207 //  control over the cursor shape and path are available. If no second
00208 //  argument is given, the optimal
00209 //  <linkto class=TileStepper>TileStepper</linkto> navigator will be used.
00210 // <srcblock>
00211 // // simple route - define a cursor shape that is the xy plane of our
00212 // lattice.
00213 //
00214 // IPosition cursorShape(2, lattice.shape()(0), lattice.shape()(1));
00215 // LatticeIterator<Float> iter(lattice, cursorShape);
00216 // for (iter.reset(); !iter.atEnd(); iter++) {
00217 //   minMax(iter.cursor(), min, max);
00218 // }
00219 // </srcblock>
00220 //
00221 //   <li> The <linkto class="LatticeIterator">LatticeIterator</linkto> class
00222 //   name reflects its role as a means of iterating a read and write cursor
00223 //   through a Lattice based object.  Not only does the cursor allow you to 
00224 //   inspect the Lattice data but you may also change the Lattice via
00225 //   operations on the cursor. This class provides optimized read and write
00226 //   iteration through any class derived from Lattice.  The technique is
00227 //   identical to the RO_LatticeIterator.  But the cursor, in this case, is
00228 //   a reference back to the data in the Lattice.  This means that changes
00229 //   made to the cursor propagate back to the Lattice.  This is especially
00230 //   useful for the PagedArray and PagedImage classes.  These two classes
00231 //   are constructed empty and need iteration to fill in the Lattice data.
00232 // <srcblock>
00233 // // make an empty PagedArray and fill it.   The Table that stores the 
00234 // // PagedArray is deleted when the PagedArray goes out of scope
00235 //
00236 // PagedArray<Float> lattice(IPosition(4,100,200,300,50));
00237 // LatticeIterator<Float> iter(lattice, IPosition(2, 100, 200));
00238 //
00239 // // fill each plane with the "distance" of the iterator from the origin
00240 //
00241 // for(iter.reset();!iter.atEnd(); iter++) {
00242 //    iter.woCursor() = iter.nsteps();
00243 // }
00244 // </srcblock>
00245 //  </ul>
00246 //
00247 // <li> LatticeNavigators - the objects which define the method and path used
00248 // by a LatticeIterator to move the cursor through a Lattice.   Many
00249 // different paths are possible.  We leave it you to choose the
00250 // <linkto class=LatticeNavigator>LatticeNavigator</linkto>
00251 // (method and path) when using a LatticeIterator.
00252 // <ul>
00253 //   <li> The <linkto class="LatticeStepper">LatticeStepper</linkto> class
00254 //   is used to define the steps which the cursor takes during its path
00255 //   through the Lattice.  Every element of the Lattice will be covered,
00256 //   starting at the origin and ending at the "top right corner."  This
00257 //   class provides the information needed by a LatticeIterator to do
00258 //   non-standard movements of the cursor during iteration.  The shape of
00259 //   the cursor is specified by the second IPosition argument of the
00260 //   LatticeStepper.  The order of the axis is important. An IPosition(1,5)
00261 //   is a five element vector along the x-axis.  An IPosition(3,1,1,5) is a
00262 //   five element vector along the z-axis.  The degenerate axes (axes with
00263 //   lengths of one) act as place holders.  The third argument in the
00264 //   LatticeStepper constructor is the "orientation" IPosition.  This
00265 //   describes the order of the axis for the cursor to follow.  Again, we
00266 //   treat the elements, in order, of the IPosition as the designators of
00267 //   the appropriate axis.  The zeroth element indicates which axis is the
00268 //   fastest moving, the first element indicates which axis is the second
00269 //   fastest moving etc. eg. The IPosition(3,2,0,1) says the LatticeIterator
00270 //   should start with the z-axis, next follow the x-axis, and finish with
00271 //   the y-axis.  A single element cursor would thus move through a cube of
00272 //   dimension(x,y,z) from (0,0,0) up the z-axis until reaching the maximum
00273 //   (0,0,z-1) and then start on (1,0,0) and move to (1,0,z-1), etc.
00274 // <srcblock>
00275 // // The shape of our Lattice - a 4 dimensional image of shape (x,y,z,t) -
00276 // // and the shape of the cursor
00277 //
00278 // IPosition latticeShape(image.shape());
00279 // IPosition cursorShape(3, lattticeShape(0), 1, latticeShape(2));
00280 //
00281 // // Define the path the cursor should follow, we list x and z first, even though
00282 // // no iterations will be done along those axes since the cursor is an 
00283 // // integral subshape of the Lattice. The cursor will move along the y-axis
00284 // // and then increment the t-axis.  The construct the Navigator and Iterator
00285 //
00286 // IPosition order(4,0,2,1,3);
00287 // LatticeStepper nav(latticeShape, cursorShape, order);
00288 // LatticeIterator<Float> iter(image, nav);
00289 // </srcblock>
00290 //
00291 // <li> 
00292 //  The <linkto class="TiledLineStepper">TiledLineStepper</linkto> class
00293 //  allows you to iterate through a Lattice with a Vector cursor.
00294 //  However, it steps through the Lattice in an order which is
00295 //  optimum with regard to the I/O of the tiles with which the Lattice is
00296 //  constructed.
00297 //
00298 // <srcblock>
00299 //
00300 // // Set up a TiledLineStepper to return profiles along the specified
00301 // // axis from a PagedArray (not all Lattices have the tileShape member
00302 // // function).  Then create the iterator as well.
00303 // 
00304 // TiledLineStepper nav(lattice.shape(), lattice.tileShape(), axis);
00305 // LatticeIterator<Complex> nav(lattice, nav);
00306 // </srcblock>
00307 //
00308 // <li> 
00309 //  The <linkto class="TileStepper">TileStepper</linkto> class
00310 //  allows you to iterate through a Lattice in the optimum way.
00311 //  It steps through the lattice tile by tile minimizing I/O and memory usage.
00312 //  It is very well suited for pixel based operations.
00313 //  However, its iteration order is such that it cannot be used for
00314 //  a certain subset of pixels (e.g. a vector) is needed.
00315 //  <br>This navigator is the default when no navigator is given when
00316 // constructing a (RO_)LatticeIterator.
00317 //
00318 // </ul>
00319 //
00320 // <li> <linkto class="MaskedLattice">MaskedLattice</linkto> - a
00321 // Lattice with a mask. It is an abstract base class for
00322 // various types of MaskedLattices. A MaskedLattice does not need
00323 // to contain a mask (see e.g. SubLattice below), although the user
00324 // can always ask for the mask. The function <src>isMasked()</src>
00325 // tells if there is really a mask. If not, users could take
00326 // advantage by shortcutting some code for better performance.
00327 // I.e. a function can test if a the MaskedLattice is really masked
00328 // and can take a special route if not.
00329 // Of course, doing that requires more coding, so it should only
00330 // be done where performance is a real issue.
00331 //  <ul>
00332 //  <li> A <linkto class="SubLattice">SubLattice</linkto> represents
00333 //  a rectangular subset of a Lattice. The SubLattice can be a simple
00334 //  box, but it can also be a circle, polygon, etc.
00335 //  In the latter case the SubLattice contains a mask
00336 //  telling which pixels in the bounding box actually belong to the
00337 //  circle or polygon. In the case of a box there is no mask, because
00338 //  there is no need to (because a box is already rectangular).
00339 //  <br> A SubLattice can be constructed from any Lattice and a
00340 //  <linkto class=LatticeRegion>LatticeRegion</linkto> telling which
00341 //  part to take from the Lattice.
00342 //  If the SubLattice is constructed from a <src>const Lattice</src>,
00343 //  the SubLattice is not writable. Otherwise it is writable if the
00344 //  lattice is writable.
00345 //  <p>
00346 //  There is a rich variety of <linkto class=LCRegion>region</linkto>
00347 //  classes which can be used to define a LatticeRegion in pixel coordinates.
00348 //  The elementary ones are <linkto class=LCBox>box</linkto>,
00349 //  <linkto class=LCEllipsoid>ellipsoid</linkto>,
00350 //  <linkto class=LCPolygon>polygon</linkto>,
00351 //  <linkto class=LCPixelSet>pixelset</linkto>, and
00352 //  <linkto class=LCPagedMask>good/bad mask</linkto>.
00353 //  Compound region classes can be used to make a
00354 //  <linkto class=LCUnion>union</linkto>,
00355 //  <linkto class=LCIntersection>intersection</linkto>,
00356 //  <linkto class=LCDifference>difference</linkto>,
00357 //  <linkto class=LCConcatenation>concatenation</linkto>,
00358 //  <linkto class=LCComplement>complement</linkto>, or
00359 //  <linkto class=LCExtension>extension</linkto>
00360 //  from one or more regions.
00361 //  <br>Apart from these region classes, class
00362 //  <linkto class=LCSlicer>LCSlicer</linkto> can be used to define
00363 //  a box with optional strides. It also offers the opportunity to
00364 //  define the box in fractions or to define it relative to the
00365 //  center of the lattice or relative to a reference pixel.
00366 //  <br>The final, and most general way, to define regions is by
00367 //  means of the world coordinates region classes in the
00368 //  <linkto module=Images>Images</linkto> module, in particular
00369 //  the <linkto class=WCRegion>WCRegion</linkto> class.
00370 //  However, world coordinate regions can only be used with images.
00371 //  
00372 //  <li>A <linkto class=LatticeExpr>LatticeExpr</linkto> represents
00373 //  a mathematical expression of lattices. All standard operators, regions,
00374 //  and many, many <linkto class=LatticeExprNode>functions</linkto>
00375 //  can be used in an expression.
00376 //  <br> An expression is calculated on-the-fly. Thus only when
00377 //  the user gets a part of the lattice, is the expression calculated
00378 //  for that part. Subexpressions resulting in a scalar are calculated
00379 //  only once, on a get of the first part of the lattice expression.
00380 //  <br> Note that a lattice expression is not writable, thus using
00381 //  the put function on such a lattice results in an exception.
00382 //  <br> <a href="../notes/223.html">Note 223</a>
00383 //  gives a more detailed
00384 //  explanation of the capabilities of LEL (Lattice Expression Language).
00385 //  <p>
00386 //  When the expression consists of images, the result can also be
00387 //  treated as an image using class <linkto class=ImageExpr>ImageExpr</linkto>.
00388 //  With the <src>command</src> function in
00389 //  <linkto class=ImageExprParse>ImageExprParse</linkto> it is possible
00390 //  to parse and execute a LEL expression given as as a string.
00391 //  </ul>
00392 //
00393 // <li> <linkto class=LatticeLocker>LatticeLocker</linkto> 
00394 // can be used to acquire a (user) lock on a lattice.
00395 // The lock can be a read or write lock.
00396 // The destructor releases the lock when needed.
00397 // <br>Lattices on disk can be used (read and write) by multiple processes.
00398 // The Table locking/synchronization mechanism takes care that sharing
00399 // such a lattice is done in an orderly way.
00400 // Usually the default locking mechanism is sufficient.
00401 // LatticeLocker is useful when finer locking control is needed for a
00402 // disk-based lattice.
00403 // 
00404 // <note role=warning> The following are listed for low-level programmers.  
00405 // Lattice users need not understand them.</note>  The Lattice directory
00406 // contains several files relevant only to implementation.
00407 //
00408 // <ul>
00409 //   <li> <linkto class="LatticeBase">LatticeBase</linkto> - a non-templated
00410 //   abstract base class defining the type-independent interface to classes
00411 //   which must act as Lattices do.
00412 //   <li> <linkto class="Lattice">Lattice</linkto> - a templated
00413 //   abstract base class (derived from LatticeBase)
00414 //   defining the interface to classes which must act as Lattices do.
00415 //   The user simply publicly inherits from Lattice and defines the member
00416 //   functions declared as pure abstract in the Lattice header file.
00417 //   <li> The <linkto class="LatticeNavigator">LatticeNavigator</linkto>
00418 //   class name defines the interface used for navigating through a Lattice
00419 //   by iteration.  This class is an abstract base.  Classes derived from
00420 //   this (currently 
00421 //   <linkto class="LatticeStepper">LatticeStepper</linkto>,
00422 //   <linkto class="TiledLineStepper">TiledLineStepper</linkto>, and
00423 //   <linkto class="TileStepper">TileStepper</linkto>) must
00424 //   define the path the iterator cursor follows, the size of the movement
00425 //   of the cursor with each iteration, and the behaviour of that cursor
00426 //   shape as it moves through a Lattice.
00427 //   <li> <linkto class="LatticeIndexer">LatticeIndexer</linkto> - this
00428 //   class contains the currently defined Lattice and sub-Lattice shape. It
00429 //   is used only by navigator classes as it contains
00430 //   member functions for moving a cursor through a defined sub-Lattice.
00431 //   <li> The 
00432 //   <linkto class="LatticeIterInterface">LatticeIterInterface</linkto>
00433 //   class defines the interface for a specific Lattice's iterator.  This
00434 //   class is a base class with a default iterator implementation.
00435 //   Lattice based classes may need to derive an iterator from
00436 //   LatticeIterInterface to optimize for the LatticeIterator
00437 //   internals which impact upon the new Lattice.
00438 //   <li> <linkto class="PagedArrIter">PagedArrIter</linkto> - this class is
00439 //   the PagedArray's optimized method of iterating. This class is a
00440 //   "letter" utilized within the LatticeIterator "envelope" and cannot
00441 //   be instantiated by any user.
00442 //   <li> <linkto class="LCRegion">LCRegion</linkto> - this class is the
00443 //   (abstract) base class for regions in pixel coordinates.
00444 //  </ul>
00445 // </ol>
00446 // </synopsis>
00447 
00448 // <motivation>
00449 // Lattices allow the various holders of data to assume a general method 
00450 // of treatment; by making interfaces in terms of the Lattice class,
00451 // the programmer can  polymorphically operate on objects derived  from the
00452 // Lattice class.
00453 // </motivation>
00454 
00455 // <todo asof="1998/10/10">
00456 //  <li> Make Lattice expressions mask aware.
00457 //  <li> Set cache size correctly in expressions and sublattices.
00458 //  <li> Make MaskedIterator class?
00459 // </todo>
00460 
00461 // </module>
00462 
00463 
00464 } //# NAMESPACE CASA - END
00465 
00466 #endif
00467 
00468