00001 //# HDF5Image.h: astronomical image in HDF5 format 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 IMAGES_HDF5IMAGE_H 00029 #define IMAGES_HDF5IMAGE_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/images/Images/ImageInterface.h> 00034 #include <casacore/images/Images/ImageAttrHandlerHDF5.h> 00035 #include <casacore/lattices/Lattices/HDF5Lattice.h> 00036 00037 //# Forward Declarations 00038 #include <casacore/casa/iosfwd.h> 00039 00040 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00041 00042 // <summary> 00043 // Read, store, and manipulate astronomical images in HDF5 format. 00044 // </summary> 00045 00046 // <use visibility=export> 00047 00048 // <reviewed reviewer="" date="" tests="tHDF5Image.cc" demos="dHDF5Image.cc"> 00049 // </reviewed> 00050 00051 // <prerequisite> 00052 // <li> <linkto class=CoordinateSystem>CoordinateSystem</linkto> 00053 // <li> <linkto class=ImageInterface>ImageInterface</linkto> 00054 // <li> <linkto class=Lattice>Lattice</linkto> 00055 // <li> <linkto class=LatticeIterator>LatticeIterator</linkto> 00056 // <li> <linkto class=LatticeNavigator>LatticeNavigator</linkto> 00057 // <li> <linkto class=ImageRegion>ImageRegion</linkto> 00058 // </prerequisite> 00059 00060 // <etymology> 00061 // The HDF5Image name comes from its role as the Image class using HDF5. 00062 // </etymology> 00063 00064 // <synopsis> 00065 // All Casacore Images are Lattices. They may be treated like any other Lattice; 00066 // getSlice(...), putSlice(...), LatticeIterator for iterating, etc... 00067 // ArrayImages contain a map, a mask for that map, and coordinate 00068 // information. This provides a Lattice interface for images and their 00069 // respective coordinates. Additional functionality is defined by the 00070 // ImageInterface class. 00071 // 00072 // You can use the global function <src>imagePixelType</src> to determine 00073 // what the pixel type of an image is before you open the image if your 00074 // code can work with Images of many possible types, or for error checking. 00075 // 00076 // </synopsis> 00077 00078 // <example> 00079 // This example shows how to create a mask for an image, fill it, and 00080 // make it known to the image. 00081 // <srcblock> 00082 // // Open the image (as readonly for the moment). 00083 // HDF5Image<Float> myimage ("image.name"); 00084 // // Create a mask for the image. 00085 // // The mask will be stored in a subtable of the image. 00086 // LCPagedMask mask (RegionHandler::makeMask (myimage, "mask.name")); 00087 // // Fill the mask with whatever values (e.g. all True). 00088 // mask.set (True); 00089 // // Make the mask known to the image (with name mask1). 00090 // myimage.defineRegion ("mask1", mask, RegionHandler::Masks); 00091 // // Make the mask the default mask for this image. 00092 // myimage.setDefaultMask ("mask1"); 00093 // </srcblock> 00094 // It is possible to create as many masks as one likes. They can all 00095 // be defined as masks for the image (with different names, of course). 00096 // However, only one of them can be the default mask (the mask used 00097 // by default when the image is opened). When another mask has to be 00098 // used, one can do two things: 00099 // <ul> 00100 // <li> Use setDefaultMask to make the other mask the default mask. 00101 // This is advisable when the change should be more or less permanent. 00102 // <li> Open the HDF5Image without using a default mask. Thereafter 00103 // a <linkto class=SubImage>SubImage</linkto> object can be created 00104 // from the HDF5Image and the mask. This is advisable when it the 00105 // mask has to be used only one time. 00106 // </ul> 00107 // </example> 00108 00109 // <motivation> 00110 // The size of astronomical data can be very large. The ability to fit an 00111 // entire image into random access memory cannot be guaranteed. Paging from 00112 // disk pieces of the image appeared to be the way to deal with this problem. 00113 // </motivation> 00114 00115 // <note> 00116 // When you make a new HDF5Image, and you are transferring 00117 // information from some other HDF5Image, be aware that you 00118 // must copy, manually, things like miscInfo, imageInfo, units, 00119 // logSink (history) to the new file. 00120 // </note> 00121 00122 template <class T> class HDF5Image: public ImageInterface<T> 00123 { 00124 public: 00125 // Construct a new Image from shape and coordinate information. The image 00126 // will be stored in the named file. 00127 HDF5Image (const TiledShape& mapShape, 00128 const CoordinateSystem& coordinateInfo, 00129 const String& nameOfNewFile); 00130 00131 // Reconstruct an image from a pre-existing file. 00132 // By default the default pixelmask (if available) is used. 00133 explicit HDF5Image (const String& fileName, MaskSpecifier = MaskSpecifier()); 00134 00135 // Copy constructor (reference semantics). 00136 HDF5Image (const HDF5Image<T>& other); 00137 00138 ~HDF5Image(); 00139 00140 // Assignment operator (reference semantics). 00141 HDF5Image<T>& operator= (const HDF5Image<T>& other); 00142 00143 // Make a copy of the object (reference semantics). 00144 virtual ImageInterface<T>* cloneII() const; 00145 00146 // Get the image type (returns name of derived class). 00147 virtual String imageType() const; 00148 00149 // Return the current HDF5 file name. By default this includes the full path. 00150 // The path preceding the file name can be stripped off on request. 00151 virtual String name (Bool stripPath=False) const; 00152 00153 // Function which changes the shape of the ImageExpr. 00154 // Throws an exception as an HDF5Image cannot be resized. 00155 virtual void resize(const TiledShape& newShape); 00156 00157 // Check for symmetry in data members. 00158 virtual Bool ok() const; 00159 00160 // Return the shape of the image. 00161 virtual IPosition shape() const; 00162 00163 // Function which extracts an array from the map. 00164 virtual Bool doGetSlice (Array<T>& buffer, const Slicer& theSlice); 00165 00166 // Function to replace the values in the map with soureBuffer. 00167 virtual void doPutSlice (const Array<T>& sourceBuffer, 00168 const IPosition& where, 00169 const IPosition& stride); 00170 00171 // Get a pointer the default pixelmask object used with this image. 00172 // It returns 0 if no default pixelmask is used. 00173 virtual const LatticeRegion* getRegionPtr() const; 00174 00175 // An HDF5Image is always persistent. 00176 virtual Bool isPersistent() const; 00177 00178 // An HDF5Image is always paged to disk. 00179 virtual Bool isPaged() const; 00180 00181 // Is the HDF5Image writable? 00182 virtual Bool isWritable() const; 00183 00184 // Does the image object use a pixelmask? 00185 virtual Bool hasPixelMask() const; 00186 00187 // Get access to the pixelmask used. 00188 // An exception is thrown if the image does not use a pixelmask. 00189 // <group> 00190 virtual const Lattice<Bool>& pixelMask() const; 00191 virtual Lattice<Bool>& pixelMask(); 00192 // </group> 00193 00194 // Set the default pixelmask to the mask with the given name 00195 // (which has to exist in the "masks" group). 00196 // If the image file is writable, the setting is persistent by writing 00197 // the name as a keyword. 00198 // If the given mask name is the empty string, 00199 // the default pixelmask is unset. 00200 virtual void setDefaultMask (const String& maskName); 00201 00202 // Use the mask as specified. 00203 // If a mask was already in use, it is replaced by the new one. 00204 virtual void useMask (MaskSpecifier = MaskSpecifier()); 00205 00206 // Replace every element, x, of the lattice with the result of f(x). 00207 // you must pass in the address of the function -- so the function 00208 // must be declared and defined in the scope of your program. 00209 // Both versions of apply require a function that accepts a single 00210 // argument of type T (the Lattice template actual type) and returns 00211 // a result of the same type. The first apply expects a function with 00212 // an argument passed by value; the second expects the argument to 00213 // be passed by const reference. The first form ought to run faster 00214 // for the built-in types, which may be an issue for large Lattices 00215 // stored in memory, where disk access is not an issue. 00216 // <group> 00217 virtual void apply (T (*function)(T)); 00218 virtual void apply (T (*function)(const T& )); 00219 virtual void apply (const Functional<T,T>& function); 00220 // </group> 00221 00222 // Add a lattice to this image. 00223 HDF5Image<T>& operator+= (const Lattice<T>& other); 00224 00225 // Function which sets the units associated with the image 00226 // pixels (i.e. the "brightness" unit). <src>setUnits()</src> returns 00227 // False if it cannot set the unit for some reason (e.g. the underlying 00228 // file is not writable). 00229 virtual Bool setUnits (const Unit& newUnits); 00230 00231 // Flushes the new coordinate system to disk if the file is writable. 00232 virtual Bool setCoordinateInfo (const CoordinateSystem& coords); 00233 00234 // These are the true implementations of the paran operator. 00235 // <note> Not for public use </note> 00236 // <group> 00237 virtual T getAt (const IPosition& where) const; 00238 virtual void putAt (const T& value, const IPosition& where); 00239 // </group> 00240 00241 // Replace the miscinfo in the HDF5Image. 00242 // It can fail if, e.g., the underlying file is not writable. 00243 virtual Bool setMiscInfo (const RecordInterface& newInfo); 00244 00245 // The ImageInfo object contains some miscellaneous information about the 00246 // image, which unlike that stored in MiscInfo, has a standard list of 00247 // things, such as the restoring beam. 00248 // Note that setImageInfo REPLACES the information with the new information. 00249 // It can fail if, e.g., the underlying file is not writable. 00250 virtual Bool setImageInfo(const ImageInfo& info); 00251 00252 // Get access to the attribute handler. 00253 // If a handler keyword does not exist yet, it is created if 00254 // <src>createHandler</src> is set. 00255 // Otherwise the handler is empty and no groups can be created for it. 00256 virtual ImageAttrHandler& attrHandler (Bool createHandler=False); 00257 00258 // Remove a region/mask belonging to the image from the given group 00259 // (which can be Any). 00260 // If a mask removed is the default mask, the image gets unmasked. 00261 // <br>Optionally an exception is thrown if the region does not exist. 00262 virtual void removeRegion (const String& name, 00263 RegionHandler::GroupType = RegionHandler::Any, 00264 Bool throwIfUnknown = True); 00265 00266 // This is the implementation of the letter for the envelope Iterator 00267 // class. <note> Not for public use </note>. 00268 virtual LatticeIterInterface<T>* makeIter 00269 (const LatticeNavigator& navigator, 00270 Bool useRef) const; 00271 00272 // Returns the maximum recommended number of pixels for a cursor. This is 00273 // the number of pixels in a tile. 00274 virtual uInt advisedMaxPixels() const; 00275 00276 // Help the user pick a cursor for most efficient access. 00277 virtual IPosition doNiceCursorShape (uInt maxPixels) const; 00278 00279 // Flush the data. 00280 virtual void flush(); 00281 00282 00283 private: 00284 // Function to return the internal HDF5File object to the RegionHandler. 00285 static const CountedPtr<HDF5File>& getFile (void* imagePtr); 00286 00287 // This must be called in every constructor and place where the image 00288 // is attached to a new image. 00289 void attach_logtable(); 00290 void open_logtable(); 00291 void restoreUnits (const RecordInterface& rec); 00292 void restoreMiscInfo (const RecordInterface& rec); 00293 void restoreImageInfo (const RecordInterface& rec); 00294 void restoreAll(); 00295 00296 void check_conformance (const Lattice<T>& other); 00297 void applyMaskSpecifier (const MaskSpecifier&); 00298 void applyMask (const String& maskName); 00299 00300 //# Data members. 00301 HDF5Lattice<T> map_p; 00302 LatticeRegion* regionPtr_p; 00303 ImageAttrHandlerHDF5 itsAttrHandler; 00304 00305 //# Make members of parent class known. 00306 public: 00307 using ImageInterface<T>::logSink; 00308 using ImageInterface<T>::logger; 00309 using ImageInterface<T>::imageInfo; 00310 using ImageInterface<T>::coordinates; 00311 using ImageInterface<T>::getDefaultMask; 00312 using ImageInterface<T>::hasRegion; 00313 using ImageInterface<T>::getImageRegionPtr; 00314 protected: 00315 using ImageInterface<T>::setCoordsMember; 00316 using ImageInterface<T>::setMiscInfoMember; 00317 using ImageInterface<T>::setLogMember; 00318 using ImageInterface<T>::setUnitMember; 00319 using ImageInterface<T>::setImageInfoMember; 00320 }; 00321 00322 00323 // Tell if HDF5 images can be used. 00324 inline Bool canUseHDF5Image() 00325 { return HDF5Object::hasHDF5Support(); } 00326 00327 // Determine the pixel type in the HDF5Image contained in 00328 // <src>fileName</src>. If the file doesn't appear to be HDF5 or cannot 00329 // be opened, TpOther is returned. 00330 // <group name="pixeltype") 00331 DataType hdf5imagePixelType (const String& fileName); 00332 // Check if this HDF5 file is an HDF5 image. 00333 Bool isHDF5Image (const String& fileName); 00334 // </group> 00335 00336 00337 } //# NAMESPACE CASACORE - END 00338 00339 #ifndef CASACORE_NO_AUTO_TEMPLATES 00340 #include <casacore/images/Images/HDF5Image.tcc> 00341 #endif //# CASACORE_NO_AUTO_TEMPLATES 00342 #endif