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