PagedArray.h

Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1