00001 //# PagedArray.h: templated Lattice, paged from disk to memory on demand 00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,2002,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_PAGEDARRAY_H 00029 #define LATTICES_PAGEDARRAY_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/lattices/Lattices/Lattice.h> 00034 #include <casacore/lattices/Lattices/TiledShape.h> 00035 #include <casacore/tables/Tables/ArrayColumn.h> 00036 #include <casacore/tables/Tables/Table.h> 00037 #include <casacore/tables/DataMan/TiledStManAccessor.h> 00038 #include <casacore/casa/BasicSL/String.h> 00039 00040 00041 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00042 00043 // <summary> 00044 // A Lattice that is read from or written to disk. 00045 // </summary> 00046 00047 // <use visibility=export> 00048 00049 // <reviewed reviewer="Peter Barnes" date="1999/10/30" tests="tPagedArray.cc" demos="dPagedArray.cc"> 00050 // </reviewed> 00051 00052 // <prerequisite> 00053 // <li> <linkto class="Lattice">Lattice</linkto> 00054 // <li> <linkto class="TiledShape">TiledShape</linkto> 00055 // </prerequisite> 00056 00057 // <etymology> 00058 // "Demand paging" is a technique used to implement virtual memory in 00059 // computer operating systems. In this scheme, code or data are read from 00060 // disk to memory only as needed by a process, and are read in fixed-sized 00061 // chunks called "pages". PagedArrays are somewhat the same -- though 00062 // without the automatic features found in virtual memory demand paging. 00063 // However PagedArrays do allow the user to access chunks of the disk in a 00064 // flexible way, that can match the requirements of many algorithms. 00065 // </etymology> 00066 00067 // <synopsis> 00068 // At the time of writing, typical scientific computers provide sufficient 00069 // memory for storing and manipulating 2-dimensional astronomical images, 00070 // which have average size of around 8 MBytes. Astronomy is increasingly 00071 // using three or higher dimensional arrays, which can be larger by one or 00072 // two orders of magnitude. PagedArrays provide a convenient way of 00073 // accessing these large arrays without requiring all the data to be read 00074 // into real or virtual memory. 00075 // <p> 00076 // When you construct a PagedArray you do not read any data into 00077 // memory. Instead a disk file (ie. a Table) is created, in a place you 00078 // specify, to hold the data. This means you need to have enough disk space 00079 // to hold the array. Constructing a PagedArray is equivalent to opening a 00080 // file. 00081 // <p> 00082 // Because the data is stored on disk it can be saved after the program, 00083 // function, or task that created the PagedArray has finished. This saved 00084 // array can then be read again at a later stage. 00085 // <p> 00086 // So there are two reasons for using a PagedArray: 00087 // <ol> 00088 // <li> To provide for arrays that are too large for the computer's memory. 00089 // <li> To provide a way of saving arrays to disk for later access. 00090 // </ol> 00091 // 00092 // To access the data in a PagedArray you can either: 00093 // <ol> 00094 // <li> Use a <linkto class=LatticeIterator>LatticeIterator</linkto> 00095 // <li> Use the getSlice and putSlice member functions 00096 // <li> Use the parenthesis operator or getAt and putAt functions 00097 // </ol> 00098 // These access methods are given in order of preference. Some examples of 00099 // these access methods are in the documentation for the 00100 // <linkto class=Lattice>Lattice</linkto> class as well as below. 00101 // <p> 00102 // In nearly all cases you access the PagedArray by reading a "slice" of the 00103 // PagedArray into a Casacore <linkto class=Array>Array</linkto>. Because the 00104 // slice is stored in memory it is important that the slice you read is not 00105 // too big compared to the physical memory on your computer. Otherwise your 00106 // computer will page excessively and performance will be poor. 00107 // <p> 00108 // To overcome this you may be tempted to access the PagedArray a pixel at a 00109 // time. This will use little memory but the overhead of accessing a large 00110 // data set by separately reading each pixel from disk will also lead to poor 00111 // performance. 00112 // <p> 00113 // In general the best way to access the data in PagedArrays is to use a 00114 // LatticeIterator with a cursor size that "fits" nicely into memory. Not 00115 // only do the LaticeIterator classes provide a relatively simple way to 00116 // read/write all the data but they optimally set up the cache that is 00117 // associated with each PagedArray. 00118 // <p> 00119 // If the LatticeIterator classes do not access the data the way you want 00120 // you can use the getSlice and putSlice member functions. These functions 00121 // do not set up the cache for you and improved performance may be obtained 00122 // by tweaking the cache using the setCacheSizeFromPath member frunction. 00123 // 00124 // <ANCHOR NAME="PagedArray:Advanced"><h3>More Details</h3></ANCHOR> 00125 // In order to utilise PagedArrays fully and understand many of the member 00126 // functions and data access methods in this class, you need to be familiar 00127 // with some of the concepts involved in the implementation of PagedArrays. 00128 // <p> 00129 // Each PagedArray is stored in one cell of a Table as an indirect Array 00130 // (see the documentation for the <linkto module="Tables">Tables</linkto> 00131 // module for more information). This means that multiple PagedArrays can be 00132 // stored in one Table. To specify which PagedArray you are referring to in 00133 // a given Table you need to specify the cell using its column name and row 00134 // number during construction. If a cell is not specified the default column 00135 // name (as given by the defaultColumnName function) and row number (as 00136 // given by the defaultRowNumber function) are used. This ability to store 00137 // multiple PagedArrays's is used in the PagedImage class where the image is 00138 // stored in one cell and a mask is optionally stored in a another column in 00139 // the same row. 00140 // <p> 00141 // There are currently a number of limitations when storing multiple 00142 // PagedArrays in the same Table. 00143 // <ul> 00144 // <li> All the PagedArrays in the same column MUST have the same number of 00145 // dimensions. The dimension used for any particular column is set when the 00146 // first PagedArray in that column is constructed. If you want to put a 00147 // say two-dimensional PagedArray into another row of a column that 00148 // already contains a four-dimensional PagedArray you need to add two 00149 // degenerate axes. In principle you could use the resize function, but see 00150 // below for why this is not recommended. It is better to just ensure that 00151 // all the PagedArrays have the same number of dimensions. 00152 // <li> All the cells in a column that contains PagedArrays must have their 00153 // shape defined. This becomes important if you are creating a PagedArray in 00154 // say row five of a Table that currently only has one row. The PagedArray 00155 // constructor will add another four rows to the Table, and put your 00156 // PagedArray (with the shape you specify) in row five. For the three 00157 // rows for which no shape was specified, the constructor will construct 00158 // PagedArrays with only one element (and of an appropriate 00159 // dimensionality). As you cannot resize these single element PagedArrays 00160 // without difficulty (see below), it is recommended that you add 00161 // PagedArrays to rows in your Table sequentially. It is necessary to have 00162 // the constructor define the shape of all cells in the Table as it is an 00163 // error to write a Table to disk with undefined cell shapes. 00164 // </ul> 00165 // 00166 // Each PagedArray is stored on disk using the tiled cell storage manager 00167 // (<linkto class=TiledCellStMan>TiledCellStMan</linkto>). This stores the 00168 // data in tiles which are regular subsections of the PagedArray. For 00169 // example a PagedArray of shape [1024,1024,4,128] may have a tile shape of 00170 // [32,16,4,16]. The data in each tile is stored as a unit on the disk. This 00171 // means that there is no preferred axis when accessing multi-dimensional 00172 // data. 00173 // <br> 00174 // The tile shape can be specified when constructing a new PagedArray but 00175 // not when reading an old one as it is intrinsic to the way the data is 00176 // stored on disk. It is NOT recommended that you specify the tile shape 00177 // unless you can control the lifetime of the PagedArray (this includes the 00178 // time it spends on disk), or can guarantee the access pattern. For example 00179 // if you know that a PagedArray of shape [512,512,4,32] will always be 00180 // sliced plane by plane you may prefer to specify a tile shape of 00181 // [512,64,1,1] rather than the default of [32,16,4,16]. 00182 // <br> 00183 // Tiles can be cached by the tile storage manager so that it does not need 00184 // to read the data from disk every time you are accessing the a pixel in a 00185 // different tile. In order to cache the correct tiles you should tell the 00186 // storage manager what section of the PagedArray you will be 00187 // accessing. This is done using the setCacheSizeFromPath member 00188 // function. Alternatively you can set the size of the cache using the 00189 // setCacheSizeInTiles member function. 00190 // <br> 00191 // By default there is no limit on how much memory the tile cache can 00192 // consume. This can be changed using the setMaximumCacheSize member 00193 // function. The tiled storage manager always tries to cache enough tiles to 00194 // ensure that each tile is read from disk only once, so setting the maximum 00195 // cache size will trade off memory usage for disk I/O. Setting the cache 00196 // size is illustrated in example 5 below. 00197 // <br> 00198 // The showCacheStatistics member function is provided to allow you to 00199 // evaluate the performance of the tile cache. 00200 // </synopsis> 00201 00202 // <example> 00203 // All the examples in this section are available in dPagedArray.cc 00204 // 00205 // <h4>Example 1:</h4> 00206 // Create a PagedArray of Floats of shape [1024,1024,4,256] in a file 00207 // called "myData_tmp.array" and initialize it to zero. This will create a 00208 // directory on disk called "myData_tmp.array" that contains files that 00209 // exceed 1024*1024*4*256*4 (= 4 GBytes) in size. 00210 // <srcblock> 00211 // const IPosition arrayShape(4,1024,1024,4,256); 00212 // const String filename("myData_tmp.array"); 00213 // PagedArray<Float> diskArray(arrayShape, filename); 00214 // cout << "Created a PagedArray of shape " << diskArray.shape() 00215 // << " (" << diskArray.shape().product()/1024/1024*sizeof(Float) 00216 // << " MBytes)" << endl 00217 // << "in the table called " << diskArray.tableName() << endl; 00218 // diskArray.set(0.0f); 00219 // // Using the set function is an efficient way to initialize the PagedArray 00220 // // as it uses a PagedArrIter internally. Note that the set function is 00221 // // defined in the Lattice class that PagedArray is derived from. 00222 // </srcblock> 00223 // 00224 // <h4>Example 2:</h4> 00225 // Read the PagedArray produced in Example 1 and put a Gaussian profile into 00226 // each spectral channel. 00227 // <srcblock> 00228 // PagedArray<Float> diskArray("myData_tmp.array"); 00229 // IPosition shape = diskArray.shape(); 00230 // // Construct a Gaussian Profile to be 10 channels wide and centred on 00231 // // channel 16. Its height is 1.0. 00232 // Gaussian1D<Float> g(1.0f, 16.0f, 10.0f); 00233 // // Create a vector to cache a sampled version of this profile. 00234 // Vector<Float> profile(shape(3)); 00235 // indgen(profile); 00236 // profile.apply(g); 00237 // // Now put this profile into every spectral channel in the paged array. This 00238 // // is best done using an iterator. 00239 // LatticeIterator<Float> iter(diskArray, 00240 // TiledLineStepper(shape, diskArray.tileShape(), 3)); 00241 // for (iter.reset(); !iter.atEnd(); iter++) { 00242 // iter.woCursor() = profile; 00243 // } 00244 // </srcblock> 00245 // 00246 // <h4>Example 3:</h4> 00247 // Now multiply the I-polarization data by 10.0 in this PagedArray. The 00248 // I-polarization data occupies 1 GByte of RAM which is too big to read 00249 // into the memory of most computers. So an iterator is used to get suitable 00250 // sized chunks. 00251 // <srcblock> 00252 // Table t("myData_tmp.array", Table::Update); 00253 // PagedArray<Float> da(t); 00254 // const IPosition latticeShape = da.shape(); 00255 // const nx = latticeShape(0); 00256 // const ny = latticeShape(1); 00257 // const npol = latticeShape(2); 00258 // const nchan = latticeShape(3); 00259 // IPosition cursorShape = da.niceCursorShape(); 00260 // cursorShape(2) = 1; 00261 // LatticeStepper step(latticeShape, cursorShape); 00262 // step.subSection(IPosition(4,0), IPosition(4,nx-1,ny-1,0,nchan-1)); 00263 // LatticeIterator<Float> iter(da, step); 00264 // for (iter.reset(); !iter.atEnd(); iter++) { 00265 // iter.rwCursor() *= 10.0f; 00266 // } 00267 // </srcblock> 00268 // 00269 // <h4>Example 4:</h4> 00270 // Use a direct call to getSlice to access a small central region of the 00271 // V-polarization in spectral channel 0 only. The region is small enough 00272 // to not warrant constructing iterators and setting up 00273 // LatticeNavigators. In this example the call to the getSlice function 00274 // is unnecessary but is done for illustration purposes anyway. 00275 // <srcblock> 00276 // SetupNewTable maskSetup("mask_tmp.array", TableDesc(), Table::New); 00277 // Table maskTable(maskSetup); 00278 // PagedArray<Bool> maskArray(IPosition(4,1024,1024,4,256), maskTable); 00279 // maskArray.set(False); 00280 // COWPtr<Array<Bool> > maskPtr; 00281 // maskArray.getSlice(maskPtr, IPosition(4,240,240,3,0), 00282 // IPosition(4,32,32,1,1), IPosition(4,1)); 00283 // maskPtr.rwRef() = True; 00284 // maskArray.putSlice(*maskPtr, IPosition(4,240,240,3,1)); 00285 // </srcblock> 00286 // 00287 // <h4>Example 5:</h4> 00288 // In this example the data in the PagedArray will be accessed a row at 00289 // a time while setting the cache size to different values. The comments 00290 // illustrate the results when running on an Ultra 1/140 with 64MBytes 00291 // of memory. 00292 // <srcblock> 00293 // PagedArray<Float> pa(IPosition(4,128,128,4,32)); 00294 // const IPosition latticeShape = pa.shape(); 00295 // cout << "The tile shape is:" << pa.tileShape() << endl; 00296 // // The tile shape is:[32, 16, 4, 16] 00297 // 00298 // // Setup to access the PagedArray a row at a time 00299 // const IPosition sliceShape(4,latticeShape(0), 1, 1, 1); 00300 // const IPosition stride(4,1); 00301 // Array<Float> row(sliceShape); 00302 // IPosition start(4, 0); 00303 // 00304 // // Set the cache size to enough pixels for one tile only. This uses 00305 // // 128kBytes of cache memory and takes 125 secs. 00306 // pa.setCacheSizeInTiles (1); 00307 // Timer clock; 00308 // for (start(3) = 0; start(3) < latticeShape(3); start(3)++) { 00309 // for (start(2) = 0; start(2) < latticeShape(2); start(2)++) { 00310 // for (start(1) = 0; start(1) < latticeShape(1); start(1)++) { 00311 // pa.getSlice(row, start, sliceShape, stride); 00312 // } 00313 // } 00314 // } 00315 // clock.show(); 00316 // pa.showCacheStatistics(cout); 00317 // pa.clearCache(); 00318 // 00319 // // Set the cache size to enough pixels for one row of tiles (ie. 4). 00320 // // This uses 512 kBytes of cache memory and takes 10 secs. 00321 // pa.setCacheSizeInTiles (4); 00322 // clock.mark(); 00323 // for (start(3) = 0; start(3) < latticeShape(3); start(3)++) { 00324 // for (start(2) = 0; start(2) < latticeShape(2); start(2)++) { 00325 // for (start(1) = 0; start(1) < latticeShape(1); start(1)++) { 00326 // pa.getSlice(row, start, sliceShape, stride); 00327 // } 00328 // } 00329 // } 00330 // clock.show(); 00331 // pa.showCacheStatistics(cout); 00332 // pa.clearCache(); 00333 // 00334 // // Set the cache size to enough pixels for one plane of tiles 00335 // // (ie. 4*8). This uses 4 MBytes of cache memory and takes 2 secs. 00336 // pa.setCacheSizeInTiles (4*8); 00337 // clock.mark(); 00338 // for (start(3) = 0; start(3) < latticeShape(3); start(3)++) { 00339 // for (start(2) = 0; start(2) < latticeShape(2); start(2)++) { 00340 // for (start(1) = 0; start(1) < latticeShape(1); start(1)++) { 00341 // pa.getSlice(row, start, sliceShape, stride); 00342 // } 00343 // } 00344 // } 00345 // clock.show(); 00346 // pa.showCacheStatistics(cout); 00347 // pa.clearCache(); 00348 // </srcblock> 00349 // </example> 00350 00351 // <motivation> 00352 // Arrays of data are sometimes much too large to hold in random access memory. 00353 // PagedArrays, especially in combination with LatticeIterator, 00354 // provide convenient access to such large data sets. 00355 // </motivation> 00356 00357 // <templating arg=T> 00358 // <li> Due to storage in Tables, the templated type must be able to be 00359 // stored in a Casacore Table. This restricts the template argument to all 00360 // the common types Bool, Float, Double, Complex, String etc.) More details 00361 // can be found in the RetypedArrayEngine class. 00362 // </templating> 00363 00364 // <todo asof="1997/04/14"> 00365 // <li> A better way of resizing PagedArrays 00366 // </todo> 00367 00368 // <linkfrom anchor="PagedArray" classes="Lattice ArrayLattice"> 00369 // <here>PagedArray</here> - a disk based Lattice. 00370 // </linkfrom> 00371 00372 00373 template <class T> class PagedArray : public Lattice<T> 00374 { 00375 //# Make members of parent class known. 00376 public: 00377 using Lattice<T>::ndim; 00378 00379 public: 00380 // The default constructor creates a PagedArray that is useless for just 00381 // about everything, except that it can be assigned to with the assignment 00382 // operator. 00383 PagedArray(); 00384 00385 // Construct a new PagedArray with the specified shape. A new Table with 00386 // the specified filename is constructed to hold the array. The Table will 00387 // remain on disk after the PagedArray goes out of scope or is deleted. 00388 PagedArray (const TiledShape& shape, const String& filename); 00389 00390 // Construct a new PagedArray with the specified shape. A scratch Table is 00391 // created in the current working directory to hold the array. This Table 00392 // will be deleted automatically when the PagedArray goes out of scope or 00393 // is deleted. 00394 explicit PagedArray (const TiledShape& shape); 00395 00396 // Construct a new PagedArray, with the specified shape, in the default 00397 // row and column of the supplied Table. 00398 PagedArray (const TiledShape& shape, Table& file); 00399 00400 // Construct a new PagedArray, with the specified shape, in the specified 00401 // row and column of the supplied Table. 00402 PagedArray (const TiledShape& shape, Table& file, 00403 const String& columnName, uInt rowNum); 00404 00405 // Reconstruct from a pre-existing PagedArray in the default row and 00406 // column of the supplied Table with the supplied filename. 00407 explicit PagedArray (const String& filename); 00408 00409 // Reconstruct from a pre-existing PagedArray in the default row and 00410 // column of the supplied Table. 00411 explicit PagedArray (Table& file); 00412 00413 // Reconstruct from a pre-existing PagedArray in the specified row and 00414 // column of the supplied Table. 00415 PagedArray (Table& file, const String& columnName, uInt rowNum); 00416 00417 // The copy constructor which uses reference semantics. Copying by value 00418 // doesn't make sense, because it would require the creation of a 00419 // temporary (but possibly huge) file on disk. 00420 PagedArray (const PagedArray<T>& other); 00421 00422 // The destructor flushes the PagedArrays contents to disk. 00423 ~PagedArray(); 00424 00425 // The assignment operator with reference semantics. As with the copy 00426 // constructor assigning by value does not make sense. 00427 PagedArray<T>& operator= (const PagedArray<T>& other); 00428 00429 // Make a copy of the object (reference semantics). 00430 virtual Lattice<T>* clone() const; 00431 00432 // A PagedArray is always persistent. 00433 virtual Bool isPersistent() const; 00434 00435 // A PagedArray is always paged to disk. 00436 virtual Bool isPaged() const; 00437 00438 // Is the PagedArray writable? 00439 virtual Bool isWritable() const; 00440 00441 // Returns the shape of the PagedArray. 00442 virtual IPosition shape() const; 00443 00444 // Return the current Table name. By default this includes the full path. 00445 // The path preceeding the file name can be stripped off on request. 00446 virtual String name (Bool stripPath=False) const; 00447 00448 // Functions to resize the PagedArray. The old contents are lost. Usage of 00449 // this function is NOT currently recommended (see the <linkto 00450 // class="PagedArray:Advanced">More Details</linkto> section above). 00451 void resize (const TiledShape& newShape); 00452 00453 // Returns the current table name (ie. filename) of this PagedArray. 00454 const String& tableName() const; 00455 00456 // Return the current table object. 00457 // <group> 00458 Table& table(); 00459 const Table& table() const; 00460 // </group> 00461 00462 // Returns the current Table column name of this PagedArray. 00463 const String& columnName() const; 00464 00465 // Returns the default TableColumn name for a PagedArray. 00466 static String defaultColumn(); 00467 00468 // Returns an accessor to the tiled storage manager. 00469 const ROTiledStManAccessor& accessor() const; 00470 00471 // Returns the current row number of this PagedArray. 00472 uInt rowNumber() const; 00473 00474 // Returns the default row number for a PagedArray. 00475 static uInt defaultRow(); 00476 00477 // Returns the current tile shape for this PagedArray. 00478 IPosition tileShape() const; 00479 00480 // Returns the maximum recommended number of pixels for a cursor. This is 00481 // the number of pixels in a tile. 00482 virtual uInt advisedMaxPixels() const; 00483 00484 // Set the maximum allowed cache size for all Arrays in this column of the 00485 // Table. The actual value used may be smaller. A value of zero means 00486 // that there is no maximum. 00487 virtual void setMaximumCacheSize (uInt howManyPixels); 00488 00489 // Return the maximum allowed cache size (in pixels) for all Arrays in 00490 // this column of the Table. The actual cache size may be smaller. A 00491 // value of zero means that no maximum is currently defined. 00492 virtual uInt maximumCacheSize() const; 00493 00494 // Set the actual cache size for this Array to be big enough for the 00495 // indicated number of tiles. This cache is not shared with PagedArrays 00496 // in other rows and is always clipped to be less than the maximum value 00497 // set using the setMaximumCacheSize member function. 00498 // Tiles are cached using a first in first out algorithm. 00499 virtual void setCacheSizeInTiles (uInt howManyTiles); 00500 00501 // Set the actual cache size for this Array to "fit" the indicated 00502 // path. This cache is not shared with PagedArrays in other rows and is 00503 // always less than the maximum value. The sliceShape is the cursor or 00504 // slice that you will be requiring (with each call to 00505 // {get,put}Slice). The windowStart and windowLength delimit the range of 00506 // pixels that will ultimatly be accessed. The AxisPath is described in 00507 // the documentation for the LatticeStepper class. 00508 virtual void setCacheSizeFromPath (const IPosition& sliceShape, 00509 const IPosition& windowStart, 00510 const IPosition& windowLength, 00511 const IPosition& axisPath); 00512 00513 // Clears and frees up the tile cache. The maximum allowed cache size is 00514 // unchanged from when <src>setMaximumCacheSize</src> was last called. 00515 virtual void clearCache(); 00516 00517 // Generate a report on how the cache is doing. This is reset every 00518 // time <src>clearCache</src> is called. 00519 virtual void showCacheStatistics (ostream& os) const; 00520 00521 // Return the value of the single element located at the argument 00522 // IPosition. 00523 // Note that <src>Lattice::operator()</src> can also be used. 00524 virtual T getAt (const IPosition& where) const; 00525 00526 // Put the value of a single element. 00527 virtual void putAt (const T& value, const IPosition& where); 00528 00529 // A function which checks for internal consistency. Returns False if 00530 // something nasty has happened to the PagedArray. In that case 00531 // it also throws an exception. 00532 virtual Bool ok() const; 00533 00534 // This function is used by the LatticeIterator class to generate an 00535 // iterator of the correct type for a specified Lattice. Not recommended 00536 // for general use. 00537 virtual LatticeIterInterface<T>* makeIter (const LatticeNavigator& navigator, 00538 Bool useRef) const; 00539 00540 // Do the actual getting of an array of values. 00541 virtual Bool doGetSlice (Array<T>& buffer, const Slicer& section); 00542 00543 // Do the actual getting of an array of values. 00544 virtual void doPutSlice (const Array<T>& sourceBuffer, 00545 const IPosition& where, 00546 const IPosition& stride); 00547 00548 // Get the best cursor shape. 00549 virtual IPosition doNiceCursorShape (uInt maxPixels) const; 00550 00551 // Handle the (un)locking. 00552 // <group> 00553 virtual Bool lock (FileLocker::LockType, uInt nattempts); 00554 virtual void unlock(); 00555 virtual Bool hasLock (FileLocker::LockType) const; 00556 // </group> 00557 00558 // Resynchronize the PagedArray object with the lattice file. 00559 // This function is only useful if no read-locking is used, ie. 00560 // if the table lock option is UserNoReadLocking or AutoNoReadLocking. 00561 // In that cases the table system does not acquire a read-lock, thus 00562 // does not synchronize itself automatically. 00563 virtual void resync(); 00564 00565 // Flush the data (but do not unlock). 00566 virtual void flush(); 00567 00568 // Temporarily close the lattice. 00569 // It will be reopened automatically on the next access. 00570 virtual void tempClose(); 00571 00572 // Explicitly reopen the temporarily closed lattice. 00573 virtual void reopen(); 00574 00575 private: 00576 // Set the data in the TableInfo file 00577 void setTableType(); 00578 // make the ArrayColumn 00579 void makeArray (const TiledShape& shape); 00580 // Make a Table to hold this PagedArray 00581 void makeTable (const String& filename, Table::TableOption option); 00582 // The default comment for PagedArray Colums 00583 static String defaultComment(); 00584 // Get the writable ArrayColumn object. 00585 // It reopens the table for write if needed. 00586 ArrayColumn<T>& getRWArray(); 00587 // Do the reopen of the table (if not open already). 00588 // <group> 00589 void doReopen() const; 00590 void tempReopen() const; 00591 // </group> 00592 00593 mutable Table itsTable; 00594 String itsColumnName; 00595 uInt itsRowNumber; 00596 mutable Bool itsIsClosed; 00597 mutable Bool itsMarkDelete; 00598 String itsTableName; 00599 Bool itsWritable; 00600 TableLock itsLockOpt; 00601 mutable ArrayColumn<T> itsArray; 00602 mutable ROTiledStManAccessor itsAccessor; 00603 }; 00604 00605 00606 template<class T> 00607 inline ArrayColumn<T>& PagedArray<T>::getRWArray() 00608 { 00609 if (itsIsClosed) { 00610 doReopen(); 00611 } 00612 if (!itsWritable) { 00613 itsTable.reopenRW(); 00614 itsWritable = True; 00615 } 00616 return itsArray; 00617 } 00618 00619 template<class T> 00620 inline Table& PagedArray<T>::table() 00621 { 00622 doReopen(); 00623 return itsTable; 00624 } 00625 template<class T> 00626 inline const Table& PagedArray<T>::table() const 00627 { 00628 doReopen(); 00629 return itsTable; 00630 } 00631 00632 template<class T> 00633 inline const String& PagedArray<T>::columnName() const 00634 { 00635 return itsColumnName; 00636 } 00637 00638 template<class T> 00639 inline String PagedArray<T>::defaultColumn() 00640 { 00641 return "PagedArray"; 00642 } 00643 00644 template<class T> 00645 inline const ROTiledStManAccessor& PagedArray<T>::accessor() const 00646 { 00647 return itsAccessor; 00648 } 00649 00650 template<class T> 00651 inline uInt PagedArray<T>::rowNumber() const 00652 { 00653 return itsRowNumber; 00654 } 00655 00656 template<class T> 00657 inline uInt PagedArray<T>::defaultRow() 00658 { 00659 return 0; 00660 } 00661 00662 template<class T> 00663 void PagedArray<T>::doReopen() const 00664 { 00665 if (itsIsClosed) { 00666 tempReopen(); 00667 } 00668 } 00669 00670 //# Declare extern templates for often used types. 00671 #ifdef AIPS_CXX11 00672 extern template class PagedArray<Float>; 00673 extern template class PagedArray<Complex>; 00674 #endif 00675 00676 00677 } //# NAMESPACE CASACORE - END 00678 00679 #ifndef CASACORE_NO_AUTO_TEMPLATES 00680 #include <casacore/lattices/Lattices/PagedArray.tcc> 00681 #endif //# CASACORE_NO_AUTO_TEMPLATES 00682 #endif