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$ 00027 00028 #ifndef LATTICES_LATTICES_H 00029 #define LATTICES_LATTICES_H 00030 00031 00032 //#include <casacore/casa/Arrays/ArrayLattice.h> 00033 //#include <casacore/casa/Arrays/PagedArray.h> 00034 //#include <casacore/casa/Arrays/TempLattice.h> 00035 //#include <casacore/casa/Arrays/LatticeLocker.h> 00036 //#include <casacore/casa/Arrays/TiledShape.h> 00037 00038 //#include <casacore/casa/Arrays/LatticeApply.h> 00039 //#include <casacore/casa/Arrays/LatticeIterator.h> 00040 //#include <casacore/casa/Arrays/LatticeStepper.h> 00041 //#include <casacore/casa/Arrays/TileStepper.h> 00042 //#include <casacore/casa/Arrays/TiledLineStepper.h> 00043 00044 //#include <casacore/lattices/Lattices/SubLattice.h> 00045 00046 //#include <casacore/lattices/LRegions.h> 00047 //#include <casacore/lattices/LEL.h> 00048 //#include <casacore/lattices/LatticeMath.h> 00049 00050 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00051 00052 // <module> 00053 00054 // <summary> 00055 // Regular N-dimensional data structures. 00056 // </summary> 00057 00058 // <prerequisite> 00059 // <li> Programmers of new Lattice classes should understand Inheritance 00060 // <li> Users of the Lattice classes should understand Polymorphism. 00061 // <li> class <linkto class=IPosition>IPosition</linkto> 00062 // <li> class <linkto class=Array>Array</linkto> 00063 // </prerequisite> 00064 00065 // <reviewed reviewer="Peter Barnes" date="1999/10/30" demos=""> 00066 // </reviewed> 00067 00068 // <etymology> 00069 // Lattice: "A regular, periodic configuration of points, particles, or 00070 // objects, throughout an area of a space..." (American Heritage Directory) 00071 // This definition matches our own: an N-dimensional arrangement of data 00072 // on regular orthogonal axes. 00073 // <p> 00074 // In Casacore, we have used the ability to call many things by one generic 00075 // name (Lattice) to create a number of classes which have different storage 00076 // techniques (e.g. core memory, disk, etc...). The name Lattice should 00077 // make the user think of a class interface (or member functions) which all 00078 // Lattice objects have in common. If functions require a Lattice 00079 // argument, the classes described here may be used interchangeably, even 00080 // though their actual internal workings are very different. 00081 // </etymology> 00082 00083 // <synopsis> 00084 // The Lattice module may be broken up into a few areas: 00085 // <ol> 00086 // 00087 // <li> Lattices - the actual holders of lattice-like data which all share a 00088 // common <linkto class="Lattice">interface</linkto>. The following items 00089 // are all Lattices and may be used polymorphically wherever a Lattice is 00090 // called for. 00091 // <ul> 00092 // <li>The <linkto class="ArrayLattice">ArrayLattice</linkto> class adds 00093 // the interface requirements of a Lattice to a Casacore 00094 // <linkto class="Array">Array</linkto>. The data inside an ArrayLattice 00095 // are not stored on disk. This n-dimensional array class is the simplest 00096 // of the Lattices. Users construct the ArrayLattice with an argument 00097 // which is either an IPosition which describes the array shape or a 00098 // previously instantiated Array object that may already contain data. In 00099 // the former case, some Lattice operation must be done to fill the data. 00100 // The ArrayLattice, like all Lattices, may be iterated through with a 00101 // <linkto class=LatticeIterator>LatticeIterator</linkto> (see below). 00102 // <br>Iteration can also be done using 00103 // <linkto class=LatticeApply>LatticeApply</linkto> and some helper 00104 // classes. It makes it possible to concentrate on the algorithm. 00105 // <srcblock> 00106 // // Make an Array of shape 3x4x5 00107 // 00108 // Array<Float> simpleArray(IPosition(3,3,4,5)); 00109 // 00110 // // fill it with a gradient 00111 // 00112 // for (Int k=0; k<5; k++) 00113 // for (Int j=0; j<4; j++) 00114 // for (Int i=0; i<3; i++) 00115 // simpleArray(IPosition(3,i,j,k)) = i+j+k; 00116 // 00117 // // use the array to create an ArrayLattice. 00118 // 00119 // ArrayLattice<Float> lattice(simpleArray); 00120 // </srcblock> 00121 // 00122 // <li>The <linkto class="PagedArray">PagedArray</linkto> class stores its 00123 // data on disk in the Table format 00124 // and pages it into random access memory for use. Paging is 00125 // used here to describe the process of getting pieces of data small 00126 // enough to fit into active memory even if the whole data set is much too 00127 // large. This class "feels" like an array but may hold very large amounts 00128 // of data. The paging has an added effect: all the data may be made 00129 // persistent, so it stays around after the application ends. 00130 // When you use PagedArrays - use 00131 // them because you need persistent data and/or paging into large data sets. 00132 // <br> 00133 // The persistence is done using a <linkto module="Tables">Table</linkto>, 00134 // and uses the <linkto module="Tables:TiledStMan">tiled storage 00135 // manager</linkto>. This means that accessing the data along any axis is 00136 // equally efficient (depending on the tile shape used). 00137 // <br> 00138 // A PagedArray constructor allows previously created PagedArrays to be 00139 // recalled from disk. Much of the time, the PagedArray will be 00140 // constructed with a <linkto class=TiledShape>TiledShape</linkto> 00141 // argument which describes the array and tile shape 00142 // and a Table argument for use as the place of storage. Then the 00143 // PagedArray may be filled using any of the access functions of Lattices 00144 // (like the LatticeIterator.) 00145 // 00146 // <srcblock> 00147 // // Create a PagedArray from a Table already existing on disk. 00148 // 00149 // PagedArray<Float> lattice(fileName); 00150 // 00151 // // Create a LatticeIterator to access the Lattice in optimal tile 00152 // // shaped chunks. 00153 // 00154 // LatticeIterator<Float> iter(lattice); 00155 // 00156 // // Iterate through and do something simple; here we just 00157 // // sum up all the values in the Lattice 00158 // 00159 // Float dSum = 0; 00160 // for(iter.reset(); !iter.atEnd(); iter++) { 00161 // dSum += sum(iter.cursor()); 00162 // } 00163 // </srcblock> 00164 // 00165 // <li>The <linkto class="HDF5Lattice">HDF5Lattice</linkto> class stores its 00166 // data on disk in <a href="http://www.hdfgroup.org/HDF5">HDF5</a> format. 00167 // It works in the same way as PagedArray. 00168 // 00169 // </ul> 00170 // 00171 // <li> <linkto class="LatticeIterator">LatticeIterator</linkto> - the 00172 // object which allows iteration through any Lattice's data. This comes in 00173 // two types: the <src>RO_LatticeIterator</src> which should be used if you 00174 // are not going to change the Lattice's data, and the 00175 // <src>LatticeIterator</src> if you need to change the data in the Lattice. 00176 // <br>Note that iteration can also be done using 00177 // <linkto class=LatticeApply>LatticeApply</linkto> and some helper 00178 // classes. It makes it possible to concentrate on the algorithm. 00179 // <ul> 00180 // <li> The <linkto class="RO_LatticeIterator">RO_LatticeIterator</linkto> 00181 // class name reflects its role as a means of iterating a "Read-Only" array 00182 // (hereafter refered to as a "cursor") through a Lattice based object, 00183 // from beginning to end. Think of a window into the Lattice that moves to 00184 // a new location when requested. The Lattice doesn't change but you may 00185 // see all or part of its data as the cursor "window" moves around. This 00186 // class allows optimized read-only iteration through any instance of a 00187 // class derived from Lattice. The cursor's shape is defined by the user and 00188 // moved through the Lattice in an orderly fashion also defined by the user. 00189 // Since the cursor is "read-only" it can only be used to "get" the data 00190 // out of the Lattice. RO_LatticeIterators are constructed with the Lattice 00191 // to be iterated as the first argument. The optional second constructor 00192 // argument is either an IPosition which defines the shape of the cursor 00193 // or a <linkto class=LatticeNavigator>LatticeNavigator</linkto> argument. 00194 // The IPosition argument cause the iterator 00195 // to move the cursor in a simple pattern; the cursor starts at the Lattice's 00196 // origin and moves in the direction of the x-axis, then the y-axis, then 00197 // the z-axis, etc.. If a LatticeNavigator argument is given, more 00198 // control over the cursor shape and path are available. If no second 00199 // argument is given, the optimal 00200 // <linkto class=TileStepper>TileStepper</linkto> navigator will be used. 00201 // <srcblock> 00202 // // simple route - define a cursor shape that is the xy plane of our 00203 // lattice. 00204 // 00205 // IPosition cursorShape(2, lattice.shape()(0), lattice.shape()(1)); 00206 // LatticeIterator<Float> iter(lattice, cursorShape); 00207 // for (iter.reset(); !iter.atEnd(); iter++) { 00208 // minMax(iter.cursor(), min, max); 00209 // } 00210 // </srcblock> 00211 // 00212 // <li> The <linkto class="LatticeIterator">LatticeIterator</linkto> class 00213 // name reflects its role as a means of iterating a read and write cursor 00214 // through a Lattice based object. Not only does the cursor allow you to 00215 // inspect the Lattice data but you may also change the Lattice via 00216 // operations on the cursor. This class provides optimized read and write 00217 // iteration through any class derived from Lattice. The technique is 00218 // identical to the RO_LatticeIterator. But the cursor, in this case, is 00219 // a reference back to the data in the Lattice. This means that changes 00220 // made to the cursor propagate back to the Lattice. This is especially 00221 // useful for the PagedArray and PagedImage classes. These two classes 00222 // are constructed empty and need iteration to fill in the Lattice data. 00223 // <srcblock> 00224 // // make an empty PagedArray and fill it. The Table that stores the 00225 // // PagedArray is deleted when the PagedArray goes out of scope 00226 // 00227 // PagedArray<Float> lattice(IPosition(4,100,200,300,50)); 00228 // LatticeIterator<Float> iter(lattice, IPosition(2, 100, 200)); 00229 // 00230 // // fill each plane with the "distance" of the iterator from the origin 00231 // 00232 // for(iter.reset();!iter.atEnd(); iter++) { 00233 // iter.woCursor() = iter.nsteps(); 00234 // } 00235 // </srcblock> 00236 // </ul> 00237 // 00238 // <li> LatticeNavigators - the objects which define the method and path used 00239 // by a LatticeIterator to move the cursor through a Lattice. Many 00240 // different paths are possible. We leave it you to choose the 00241 // <linkto class=LatticeNavigator>LatticeNavigator</linkto> 00242 // (method and path) when using a LatticeIterator. 00243 // <ul> 00244 // <li> The <linkto class="LatticeStepper">LatticeStepper</linkto> class 00245 // is used to define the steps which the cursor takes during its path 00246 // through the Lattice. Every element of the Lattice will be covered, 00247 // starting at the origin and ending at the "top right corner." This 00248 // class provides the information needed by a LatticeIterator to do 00249 // non-standard movements of the cursor during iteration. The shape of 00250 // the cursor is specified by the second IPosition argument of the 00251 // LatticeStepper. The order of the axis is important. An IPosition(1,5) 00252 // is a five element vector along the x-axis. An IPosition(3,1,1,5) is a 00253 // five element vector along the z-axis. The degenerate axes (axes with 00254 // lengths of one) act as place holders. The third argument in the 00255 // LatticeStepper constructor is the "orientation" IPosition. This 00256 // describes the order of the axis for the cursor to follow. Again, we 00257 // treat the elements, in order, of the IPosition as the designators of 00258 // the appropriate axis. The zeroth element indicates which axis is the 00259 // fastest moving, the first element indicates which axis is the second 00260 // fastest moving etc. eg. The IPosition(3,2,0,1) says the LatticeIterator 00261 // should start with the z-axis, next follow the x-axis, and finish with 00262 // the y-axis. A single element cursor would thus move through a cube of 00263 // dimension(x,y,z) from (0,0,0) up the z-axis until reaching the maximum 00264 // (0,0,z-1) and then start on (1,0,0) and move to (1,0,z-1), etc. 00265 // <srcblock> 00266 // // The shape of our Lattice - a 4 dimensional image of shape (x,y,z,t) - 00267 // // and the shape of the cursor 00268 // 00269 // IPosition latticeShape(image.shape()); 00270 // IPosition cursorShape(3, lattticeShape(0), 1, latticeShape(2)); 00271 // 00272 // // Define the path the cursor should follow, we list x and z first, even though 00273 // // no iterations will be done along those axes since the cursor is an 00274 // // integral subshape of the Lattice. The cursor will move along the y-axis 00275 // // and then increment the t-axis. The construct the Navigator and Iterator 00276 // 00277 // IPosition order(4,0,2,1,3); 00278 // LatticeStepper nav(latticeShape, cursorShape, order); 00279 // LatticeIterator<Float> iter(image, nav); 00280 // </srcblock> 00281 // 00282 // <li> 00283 // The <linkto class="TiledLineStepper">TiledLineStepper</linkto> class 00284 // allows you to iterate through a Lattice with a Vector cursor. 00285 // However, it steps through the Lattice in an order which is 00286 // optimum with regard to the I/O of the tiles with which the Lattice is 00287 // constructed. 00288 // 00289 // <srcblock> 00290 // 00291 // // Set up a TiledLineStepper to return profiles along the specified 00292 // // axis from a PagedArray (not all Lattices have the tileShape member 00293 // // function). Then create the iterator as well. 00294 // 00295 // TiledLineStepper nav(lattice.shape(), lattice.tileShape(), axis); 00296 // LatticeIterator<Complex> nav(lattice, nav); 00297 // </srcblock> 00298 // 00299 // <li> 00300 // The <linkto class="TileStepper">TileStepper</linkto> class 00301 // allows you to iterate through a Lattice in the optimum way. 00302 // It steps through the lattice tile by tile minimizing I/O and memory usage. 00303 // It is very well suited for pixel based operations. 00304 // However, its iteration order is such that it cannot be used for 00305 // a certain subset of pixels (e.g. a vector) is needed. 00306 // <br>This navigator is the default when no navigator is given when 00307 // constructing a (RO_)LatticeIterator. 00308 // 00309 // </ul> 00310 // 00311 // <li> <linkto class="MaskedLattice">MaskedLattice</linkto> - a 00312 // Lattice with a mask. It is an abstract base class for 00313 // various types of MaskedLattices. A MaskedLattice does not need 00314 // to contain a mask (see e.g. SubLattice below), although the user 00315 // can always ask for the mask. The function <src>isMasked()</src> 00316 // tells if there is really a mask. If not, users could take 00317 // advantage by shortcutting some code for better performance. 00318 // I.e. a function can test if a the MaskedLattice is really masked 00319 // and can take a special route if not. 00320 // Of course, doing that requires more coding, so it should only 00321 // be done where performance is a real issue. 00322 // <ul> 00323 // <li> A <linkto class="SubLattice">SubLattice</linkto> represents 00324 // a rectangular subset of a Lattice. The SubLattice can be a simple 00325 // box, but it can also be a circle, polygon, etc. 00326 // In the latter case the SubLattice contains a mask 00327 // telling which pixels in the bounding box actually belong to the 00328 // circle or polygon. In the case of a box there is no mask, because 00329 // there is no need to (because a box is already rectangular). 00330 // <br> A SubLattice can be constructed from any Lattice and a 00331 // <linkto class=LatticeRegion>LatticeRegion</linkto> telling which 00332 // part to take from the Lattice. 00333 // If the SubLattice is constructed from a <src>const Lattice</src>, 00334 // the SubLattice is not writable. Otherwise it is writable if the 00335 // lattice is writable. 00336 // <p> 00337 // There is a rich variety of <linkto class=LCRegion>region</linkto> 00338 // classes which can be used to define a LatticeRegion in pixel coordinates. 00339 // They are described in module 00340 // <a href="group__LRegions__module.html">LRegions</a>. 00341 // 00342 // <li> Module <a href="group__LEL__module.html">LEL</a> contains classes to 00343 // form a mathematical expression of lattices. All standard operators, regions, 00344 // and many, many <linkto class=LatticeExprNode>functions</linkto> 00345 // can be used in an expression. 00346 // </ul> 00347 // 00348 // <li> <linkto class=LatticeLocker>LatticeLocker</linkto> 00349 // can be used to acquire a (user) lock on a lattice. 00350 // The lock can be a read or write lock. 00351 // The destructor releases the lock when needed. 00352 // <br>Lattices on disk can be used (read and write) by multiple processes. 00353 // The Table locking/synchronization mechanism takes care that sharing 00354 // such a lattice is done in an orderly way. 00355 // Usually the default locking mechanism is sufficient. 00356 // LatticeLocker is useful when finer locking control is needed for a 00357 // disk-based lattice. 00358 // 00359 // <note role=warning> The following are listed for low-level programmers. 00360 // Lattice users need not understand them.</note> The Lattice directory 00361 // contains several files relevant only to implementation. 00362 // 00363 // <ul> 00364 // <li> <linkto class="LatticeBase">LatticeBase</linkto> - a non-templated 00365 // abstract base class defining the type-independent interface to classes 00366 // which must act as Lattices do. 00367 // <li> <linkto class="Lattice">Lattice</linkto> - a templated 00368 // abstract base class (derived from LatticeBase) 00369 // defining the interface to classes which must act as Lattices do. 00370 // The user simply publicly inherits from Lattice and defines the member 00371 // functions declared as pure abstract in the Lattice header file. 00372 // <li> The <linkto class="LatticeNavigator">LatticeNavigator</linkto> 00373 // class name defines the interface used for navigating through a Lattice 00374 // by iteration. This class is an abstract base. Classes derived from 00375 // this (currently 00376 // <linkto class="LatticeStepper">LatticeStepper</linkto>, 00377 // <linkto class="TiledLineStepper">TiledLineStepper</linkto>, and 00378 // <linkto class="TileStepper">TileStepper</linkto>) must 00379 // define the path the iterator cursor follows, the size of the movement 00380 // of the cursor with each iteration, and the behaviour of that cursor 00381 // shape as it moves through a Lattice. 00382 // <li> <linkto class="LatticeIndexer">LatticeIndexer</linkto> - this 00383 // class contains the currently defined Lattice and sub-Lattice shape. It 00384 // is used only by navigator classes as it contains 00385 // member functions for moving a cursor through a defined sub-Lattice. 00386 // <li> The 00387 // <linkto class="LatticeIterInterface">LatticeIterInterface</linkto> 00388 // class defines the interface for a specific Lattice's iterator. This 00389 // class is a base class with a default iterator implementation. 00390 // Lattice based classes may need to derive an iterator from 00391 // LatticeIterInterface to optimize for the LatticeIterator 00392 // internals which impact upon the new Lattice. 00393 // <li> <linkto class="PagedArrIter">PagedArrIter</linkto> - this class is 00394 // the PagedArray's optimized method of iterating. This class is a 00395 // "letter" utilized within the LatticeIterator "envelope" and cannot 00396 // be instantiated by any user. 00397 // <li> <linkto class="LCRegion">LCRegion</linkto> - this class is the 00398 // (abstract) base class for regions in pixel coordinates. 00399 // </ul> 00400 // </ol> 00401 // </synopsis> 00402 00403 // <motivation> 00404 // Lattices allow the various holders of data to assume a general method 00405 // of treatment; by making interfaces in terms of the Lattice class, 00406 // the programmer can polymorphically operate on objects derived from the 00407 // Lattice class. 00408 // </motivation> 00409 00410 // <todo asof="1998/10/10"> 00411 // <li> Make MaskedIterator class? 00412 // </todo> 00413 00414 // </module> 00415 00416 00417 } //# NAMESPACE CASACORE - END 00418 00419 #endif