casa
$Rev:20696$
|
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