00001 //# HDF5Lattice.h: Templated paged array in an HDF5 file 00002 //# Copyright (C) 2008 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_HDF5LATTICE_H 00029 #define LATTICES_HDF5LATTICE_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/casa/HDF5/HDF5File.h> 00036 #include <casacore/casa/HDF5/HDF5Group.h> 00037 #include <casacore/casa/HDF5/HDF5DataSet.h> 00038 #include <casacore/casa/BasicSL/String.h> 00039 00040 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00041 00042 // <summary> 00043 // A Lattice that is read from or written to an HDF5 dataset. 00044 // </summary> 00045 00046 // <use visibility=export> 00047 00048 // <reviewed reviewer="" date="" tests="tHDF5Lattice.cc"> 00049 // </reviewed> 00050 00051 // <prerequisite> 00052 // <li> <linkto class="PagedArray">PagedArray</linkto> 00053 // <li> <linkto class="TiledShape">TiledShape</linkto> 00054 // <li> <linkto class="HDF5File">HDF5File</linkto> 00055 // </prerequisite> 00056 00057 // <synopsis> 00058 // Astronomical data arrays (like images) have to be persistent. 00059 // A Lattice is a templated abstract base class to hold any Casacore array. 00060 // The PagedArray class is a Lattice specialization which stores the data 00061 // in a Casacore table. 00062 // <br> 00063 // HDF5Lattice ia another Lattice specialization making it possible to store 00064 // an array as a dataset in a group in an HDF5 file. 00065 // <p> 00066 // When you construct an HDF5Lattice you do not read any data into 00067 // memory. Instead an HDF5 disk file is created, in a place you 00068 // specify, to hold the data. This means you need to have enough disk space 00069 // to hold the array. Constructing a new HDF5Lattice is equivalent to 00070 // creating a data set in an HDF5 file. 00071 // <p> 00072 // To access the data in a HDF5Lattice you can (in order of preference): 00073 // <ol> 00074 // <li> Use a <linkto class=LatticeIterator>LatticeIterator</linkto> 00075 // <li> Use the getSlice and putSlice member functions 00076 // <li> Use the parenthesis operator or getAt and putAt functions 00077 // </ol> 00078 // Class PagedArray contains some more info and examples. 00079 // </synopsis> 00080 00081 // <example> 00082 // Create a HDF5Lattice of Floats of shape [1024,1024,4,256] in a file 00083 // called "myData_tmp.array" and initialize it to zero. 00084 // <srcblock> 00085 // const IPosition arrayShape(4,1024,1024,4,256); 00086 // const String filename("myData_tmp.array"); 00087 // HDF5Lattice<Float> diskArray(arrayShape, filename); 00088 // cout << "Created a HDF5Lattice of shape " << diskArray.shape() 00089 // << " (" << diskArray.shape().product()/1024/1024*sizeof(Float) 00090 // << " MBytes)" << endl 00091 // << "in the table called " << diskArray.tableName() << endl; 00092 // diskArray.set(0.0f); 00093 // // Using the set function is an efficient way to initialize the HDF5Lattice 00094 // // as it uses a LatticeIterator internally. Note that the set function is 00095 // // defined in the Lattice class that HDF5Lattice is derived from. 00096 // </srcblock> 00097 // </example> 00098 00099 // <motivation> 00100 // There was a need to be able to use HDF5 files to hold image data. 00101 // </motivation> 00102 00103 // <templating arg=T> 00104 // <li> HDF5DataSet supports only a limited amount of types. 00105 // This restricts the template argument to 00106 // the types Bool, Int Float, Double, Complex, and DComplex. 00107 // </templating> 00108 00109 template<typename T> class HDF5Lattice : public Lattice<T> 00110 { 00111 //# Make members of parent class known. 00112 public: 00113 using Lattice<T>::ndim; 00114 00115 public: 00116 // The default constructor creates an HDF5Lattice that is useless for just 00117 // about everything, except that it can be assigned to with the assignment 00118 // operator. 00119 HDF5Lattice(); 00120 00121 // Construct a new HDF5Lattice with the specified shape. 00122 // A new HDF5 file with the specified filename is constructed to hold 00123 // the array. The file will remain on disk after the HDF5Lattice goes 00124 // out of scope or is deleted. 00125 // Optionally the name of an HDF5 group can be given to create the array in. 00126 // The group is created if not existing yet. 00127 HDF5Lattice (const TiledShape& shape, const String& filename, 00128 const String& arrayName = "array", 00129 const String& groupName = String()); 00130 00131 // Construct a temporary HDF5Lattice with the specified shape. 00132 // A scratch file is created in the current working directory to hold 00133 // the array. This file will be deleted automatically when the HDF5Lattice 00134 // goes out of scope or is deleted. 00135 explicit HDF5Lattice (const TiledShape& shape); 00136 00137 // Construct a new HDF5Lattice, with the specified shape, in the given 00138 // HDF5 file. The array gets the given name. 00139 // Optionally the name of an HDF5 group can be given to create the array in. 00140 // The group is created if not existing yet. 00141 HDF5Lattice (const TiledShape& shape, const CountedPtr<HDF5File>& file, 00142 const String& arrayName, const String& groupName = String()); 00143 00144 // Reconstruct from a pre-existing HDF5Lattice in the HDF5 file and group 00145 // with the given names. 00146 explicit HDF5Lattice (const String& fileName, 00147 const String& arrayName = "array", 00148 const String& groupName = String()); 00149 00150 // Reconstruct from a pre-existing HDF5Lattice in the HDF5 file and group 00151 // with the given name. 00152 explicit HDF5Lattice (const CountedPtr<HDF5File>& file, 00153 const String& arrayName, 00154 const String& groupName = String()); 00155 00156 // The copy constructor which uses reference semantics. Copying by value 00157 // doesn't make sense, because it would require the creation of a 00158 // temporary (but possibly huge) file on disk. 00159 HDF5Lattice (const HDF5Lattice<T>& other); 00160 00161 // The destructor flushes the HDF5Lattice's contents to disk. 00162 ~HDF5Lattice(); 00163 00164 // The assignment operator with reference semantics. As with the copy 00165 // constructor assigning by value does not make sense. 00166 HDF5Lattice<T>& operator= (const HDF5Lattice<T>& other); 00167 00168 // Make a copy of the object (reference semantics). 00169 virtual Lattice<T>* clone() const; 00170 00171 // A HDF5Lattice is always persistent. 00172 virtual Bool isPersistent() const; 00173 00174 // A HDF5Lattice is always paged to disk. 00175 virtual Bool isPaged() const; 00176 00177 // Is the HDF5Lattice writable? 00178 virtual Bool isWritable() const; 00179 00180 // Returns the shape of the HDF5Lattice. 00181 virtual IPosition shape() const; 00182 00183 // Return the current HDF5 file name. 00184 // By default this includes the full path. 00185 // The path preceeding the file name can be stripped off on request. 00186 virtual String name (Bool stripPath=False) const; 00187 00188 // Return the current HDF5File object. 00189 const CountedPtr<HDF5File>& file() const 00190 { return itsFile; } 00191 00192 // Return the current HDF5Group object. 00193 const CountedPtr<HDF5Group>& group() const 00194 { return itsGroup; } 00195 00196 // Returns the name of this HDF5Lattice. 00197 const String& arrayName() const 00198 { return itsDataSet->getName(); } 00199 00200 // Returns the current tile shape for this HDF5Lattice. 00201 IPosition tileShape() const; 00202 00203 // Set the actual cache size for this Array to be big enough for the 00204 // indicated number of tiles. This cache is not shared with other 00205 // HDF5Lattices, 00206 // Tiles are cached using an LRU algorithm. 00207 virtual void setCacheSizeInTiles (uInt howManyTiles); 00208 00209 // Set the cache size as to "fit" the indicated access pattern. 00210 virtual void setCacheSizeFromPath (const IPosition& sliceShape, 00211 const IPosition& windowStart, 00212 const IPosition& windowLength, 00213 const IPosition& axisPath); 00214 00215 // Return the value of the single element located at the argument 00216 // IPosition. 00217 // Note that <src>Lattice::operator()</src> can also be used. 00218 virtual T getAt (const IPosition& where) const; 00219 00220 // Put the value of a single element. 00221 virtual void putAt (const T& value, const IPosition& where); 00222 00223 // A function which checks for internal consistency. Returns False if 00224 // something nasty has happened to the HDF5Lattice. In that case 00225 // it also throws an exception. 00226 virtual Bool ok() const; 00227 00228 // This function is used by the LatticeIterator class to generate an 00229 // iterator of the correct type for a specified Lattice. Not recommended 00230 // for general use. 00231 virtual LatticeIterInterface<T>* makeIter (const LatticeNavigator& navigator, 00232 Bool useRef) const; 00233 00234 // Do the actual getting of an array of values. 00235 virtual Bool doGetSlice (Array<T>& buffer, const Slicer& section); 00236 00237 // Do the actual getting of an array of values. 00238 virtual void doPutSlice (const Array<T>& sourceBuffer, 00239 const IPosition& where, 00240 const IPosition& stride); 00241 00242 // Returns the maximum recommended number of pixels for a cursor. This is 00243 // the number of pixels in a tile. 00244 virtual uInt advisedMaxPixels() const; 00245 00246 // Get the best cursor shape. 00247 virtual IPosition doNiceCursorShape (uInt maxPixels) const; 00248 00249 // Flush the data (but do not unlock). 00250 virtual void flush(); 00251 00252 private: 00253 // Make the Array in the HDF5 file and group. 00254 void makeArray (const TiledShape& shape, const String& arrayName, 00255 const String& groupName); 00256 // Open the Array in the HDF5 file and group. 00257 void openArray (const String& arrayName, const String& groupName); 00258 // Check if the file is writable. 00259 void checkWritable() const; 00260 00261 00262 CountedPtr<HDF5File> itsFile; 00263 CountedPtr<HDF5Group> itsGroup; 00264 CountedPtr<HDF5DataSet> itsDataSet; 00265 }; 00266 00267 00268 } //# NAMESPACE CASACORE - END 00269 00270 #ifndef CASACORE_NO_AUTO_TEMPLATES 00271 #include <casacore/lattices/Lattices/HDF5Lattice.tcc> 00272 #endif //# CASACORE_NO_AUTO_TEMPLATES 00273 00274 #endif