casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
PagedImage.h
Go to the documentation of this file.
00001 //# PagedImage.h: read, store and manipulate astronomical images
00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001,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: PagedImage.h 20505 2009-01-19 14:37:24Z gervandiepen $
00027 
00028 #ifndef IMAGES_PAGEDIMAGE_H
00029 #define IMAGES_PAGEDIMAGE_H
00030 
00031 
00032 //# Includes
00033 #include <images/Images/ImageInterface.h>
00034 #include <lattices/Lattices/PagedArray.h>
00035 #include <tables/Tables/Table.h>
00036 #include <casa/Utilities/DataType.h>
00037 #include <tables/Tables/TableRecord.h>
00038 
00039 //# Forward Declarations
00040 #include <casa/iosfwd.h>
00041 
00042 namespace casa { //# NAMESPACE CASA - BEGIN
00043 
00044 // <summary>
00045 // Read, store, and manipulate astronomical images.
00046 // </summary>
00047 
00048 // <use visibility=export>
00049 
00050 // <reviewed reviewer="" date="" tests="tPagedmage.cc" demos="dPagedImage.cc">
00051 // </reviewed>
00052 
00053 // <prerequisite>
00054 //   <li> <linkto class=CoordinateSystem>CoordinateSystem</linkto>
00055 //   <li> <linkto class=ImageInterface>ImageInterface</linkto>
00056 //   <li> <linkto class=Lattice>Lattice</linkto>
00057 //   <li> <linkto class=LatticeIterator>LatticeIterator</linkto>
00058 //   <li> <linkto class=LatticeNavigator>LatticeNavigator</linkto>
00059 //   <li> <linkto class=ImageRegion>ImageRegion</linkto>
00060 // </prerequisite>
00061 
00062 // <etymology>
00063 // The PagedImage name comes from its role as the Image class with paging 
00064 // from persistent memory.  Users are thus invited to treat the 
00065 // PagedImage instances like AIPS++ Lattices  
00066 // </etymology>
00067 
00068 // <synopsis> 
00069 // All AIPS++ Images are Lattices.  They may be treated like any other Lattice;
00070 // getSlice(...), putSlice(...), LatticeIterator for iterating, etc.
00071 // ArrayImages contain a map, a mask for that map, and coordinate 
00072 // information.  This provides a Lattice interface for images and their 
00073 // respective coordinates.  Additional functionality is defined by the 
00074 // ImageInterface class. 
00075 //
00076 // You can use the global function <src>imagePixelType</src> to determine
00077 // what the pixel type of an image is before you open the image if your
00078 // code can work with Images of many possible types, or for error checking.
00079 //
00080 // </synopsis> 
00081 
00082 // <example>
00083 // This example shows how to create a mask for an image, fill it, and
00084 // make it known to the image.
00085 // <srcblock>
00086 //   // Open the image (as readonly for the moment).
00087 //   PagedImage<Float> myimage ("image.name");
00088 //   // Create a mask for the image.
00089 //   // The mask will be stored in a subtable of the image.
00090 //   LCPagedMask mask (RegionHandler::makeMask (myimage, "mask.name"));
00091 //   // Fill the mask with whatever values (e.g. all True).
00092 //   mask.set (True);
00093 //   // Make the mask known to the image (with name mask1).
00094 //   myimage.defineRegion ("mask1", mask, RegionHandler::Masks);
00095 //   // Make the mask the default mask for this image.
00096 //   myimage.setDefaultMask ("mask1");
00097 // </srcblock>
00098 // It is possible to create as many masks as one likes. They can all
00099 // be defined as masks for the image (with different names, of course).
00100 // However, only one of them can be the default mask (the mask used
00101 // by default when the image is opened). When another mask has to be
00102 // used, one can do two things:
00103 // <ul>
00104 //  <li> Use setDefaultMask to make the other mask the default mask.
00105 //   This is advisable when the change should be more or less permanent.
00106 //  <li> Open the PagedImage without using a default mask. Thereafter
00107 //   a <linkto class=SubImage>SubImage</linkto> object can be created
00108 //   from the PagedImage and the mask. This is advisable when it the
00109 //   mask has to be used only one time.
00110 // </ul>
00111 // </example>
00112 
00113 // <motivation>
00114 // The size of astronomical data can be very large.  The ability to fit an 
00115 // entire image into random access memory cannot be guaranteed.  Paging from 
00116 // disk pieces of the image appeared to be the way to deal with this problem.
00117 // </motivation>
00118 
00119 //
00120 // <note>
00121 //  When you make a new PagedImage, and you are transferring
00122 //  information from some other PagedImage, be aware that you
00123 //  must copy, manually, things like miscInfo, imageInfo, units,
00124 //  logSink (history) to the new file.
00125 // </note>
00126 // <todo asof="1996/09/04">
00127 //   <li> The CoordinateSystem::store() function returns a TableRecord.  That
00128 // TableRecord should be stored in the same row as our image.  This will 
00129 // allow ImageStack members to have their own coordinate frames.
00130 // </todo>
00131 
00132 
00133 template <class T> class PagedImage: public ImageInterface<T>
00134 {
00135 public: 
00136   // Construct a new Image from shape and coordinate information.
00137   // Data will be stored in the argument table.
00138   PagedImage (const TiledShape& mapShape,
00139               const CoordinateSystem& coordinateInfo,
00140               Table& table,
00141               uInt rowNumber = 0);
00142   
00143   // Construct a new Image from shape and coordinate information. Table
00144   // will be stored in the named file.
00145   PagedImage (const TiledShape& mapShape,
00146               const CoordinateSystem& coordinateInfo,
00147               const String& nameOfNewFile,
00148               uInt rowNumber = 0);
00149   
00150   // Construct a new Image from shape and coordinate information. Table
00151   // will be stored in the named file.
00152   // The lock options may be specified
00153   // <group>
00154   PagedImage (const TiledShape& mapShape,
00155               const CoordinateSystem& coordinateInfo,
00156               const String& nameOfNewFile,
00157               TableLock::LockOption,
00158               uInt rowNumber = 0);
00159   PagedImage (const TiledShape& mapShape,
00160               const CoordinateSystem& coordinateInfo,
00161               const String& nameOfNewFile,
00162               const TableLock& lockOptions,
00163               uInt rowNumber = 0);
00164   // </group>
00165   
00166   // Reconstruct an image from a pre-existing file.
00167   // By default the default pixelmask (if available) is used.
00168   explicit PagedImage (Table& table, MaskSpecifier = MaskSpecifier(),
00169                        uInt rowNumber = 0);
00170   
00171   // Reconstruct an image from a pre-existing file.
00172   // By default the default pixelmask (if available) is used.
00173   explicit PagedImage (const String& filename, MaskSpecifier = MaskSpecifier(),
00174                        uInt rowNumber = 0);
00175   
00176   // Reconstruct an image from a pre-existing file with Locking.
00177   // By default the default pixelmask (if available) is used.
00178   // <group>
00179   PagedImage (const String& filename, TableLock::LockOption,
00180               MaskSpecifier = MaskSpecifier(), uInt rowNumber = 0);
00181   PagedImage (const String& filename, const TableLock& lockOptions,
00182               MaskSpecifier = MaskSpecifier(), uInt rowNumber = 0);
00183   // </group>
00184   
00185   // Copy constructor (reference semantics).
00186   PagedImage (const PagedImage<T>& other);
00187 
00188   ~PagedImage();
00189   
00190   // Assignment operator (reference semantics).
00191   PagedImage<T>& operator= (const PagedImage<T>& other);
00192   
00193   // Make a copy of the object (reference semantics).
00194   virtual ImageInterface<T>* cloneII() const;
00195 
00196   // Get the image type (returns name of derived class).
00197   virtual String imageType() const;
00198 
00199   static String className();
00200 
00201   // A PagedImage is always persistent.
00202   virtual Bool isPersistent() const;
00203 
00204   // A PagedImage is always paged to disk.
00205   virtual Bool isPaged() const;
00206 
00207   // Is the PagedImage writable?
00208   virtual Bool isWritable() const;
00209 
00210   // Does the image object use a pixelmask?
00211   virtual Bool hasPixelMask() const;
00212 
00213   // Get access to the pixelmask used.
00214   // An exception is thrown if the image does not use a pixelmask.
00215   // <group>
00216   virtual const Lattice<Bool>& pixelMask() const;
00217   virtual Lattice<Bool>& pixelMask();
00218   // </group>
00219 
00220   // Get a pointer the default pixelmask object used with this image.
00221   // It returns 0 if no default pixelmask is used.
00222   virtual const LatticeRegion* getRegionPtr() const;
00223 
00224   // Set the default pixelmask to the mask with the given name
00225   // (which has to exist in the "masks" group).
00226   // If the image table is writable, the setting is persistent by writing
00227   // the name as a keyword.
00228   // If the given regionName is the empty string,
00229   // the default pixelmask is unset.
00230   virtual void setDefaultMask (const String& maskName);
00231 
00232   // Use the mask as specified.
00233   // If a mask was already in use, it is replaced by the new one.
00234   virtual void useMask (MaskSpecifier = MaskSpecifier());
00235 
00236   // Function to change the name of the Table file on disk.
00237   // PagedImage is given a file name at construction time.  You may change
00238   // that name here.
00239   void rename (const String& newName);
00240 
00241   // Return the current Table name. By default this includes the full path. 
00242   // the path preceding the file name can be stripped off on request.
00243   virtual String name (Bool stripPath=False) const;
00244 
00245   // Return the current TableColumn row number.
00246   uInt rowNumber() const;
00247 
00248   // Return the shape of the image.
00249   virtual IPosition shape() const;
00250 
00251   // Change the shape of the image (N.B. the data is thrown away).
00252   virtual void resize (const TiledShape& newShape);
00253 
00254   // Function which extracts an array from the map.
00255   virtual Bool doGetSlice (Array<T>& buffer, const Slicer& theSlice);
00256   
00257   // Function to replace the values in the map with soureBuffer.
00258   virtual void doPutSlice (const Array<T>& sourceBuffer,
00259                            const IPosition& where,
00260                            const IPosition& stride);
00261 
00262   // Replace every element, x, of the lattice with the result of f(x).
00263   // you must pass in the address of the function -- so the function
00264   // must be declared and defined in the scope of your program.  
00265   // Both versions of apply require a function that accepts a single 
00266   // argument of type T (the Lattice template actual type) and returns
00267   // a result of the same type.  The first apply expects a function with
00268   // an argument passed by value; the second expects the argument to
00269   // be passed by const reference.  The first form ought to run faster
00270   // for the built-in types, which may be an issue for large Lattices
00271   // stored in memory, where disk access is not an issue.
00272   // <group>
00273   virtual void apply (T (*function)(T));
00274   virtual void apply (T (*function)(const T& ));
00275   virtual void apply (const Functional<T,T>& function);
00276   // </group>
00277 
00278   // Add a lattice to this image.
00279   PagedImage<T>& operator+= (const Lattice<T>& other);
00280 
00281   // Function which sets the units associated with the image
00282   // pixels (i.e. the "brightness" unit). <src>setUnits()</src> returns
00283   // False if it cannot set the unit for some reason (e.g. the underlying
00284   // file is not writable).
00285   virtual Bool setUnits (const Unit& newUnits);
00286 
00287   // Return the table holding the data.
00288   Table& table()
00289     { return map_p.table(); }
00290 
00291   // Flushes the new coordinate system to disk if the table is writable.
00292   virtual Bool setCoordinateInfo (const CoordinateSystem& coords);
00293 
00294   // Check for symmetry in data members.
00295   virtual Bool ok() const;
00296 
00297   // These are the true implementations of the paran operator.
00298   // <note> Not for public use </note>
00299   // <group>
00300   virtual T getAt (const IPosition& where) const;
00301   virtual void putAt (const T& value, const IPosition& where);
00302   // </group>
00303 
00304   // Replace the miscinfo in the PagedImage.
00305   // It can fail if, e.g., the underlying table is not writable.
00306   virtual Bool setMiscInfo (const RecordInterface& newInfo);
00307 
00308   // The ImageInfo object contains some miscellaneous information about the
00309   // image, which unlike that stored in MiscInfo, has a standard list of
00310   // things, such as the restoring beam.
00311   // Note that setImageInfo REPLACES the information with the new information.
00312   // It can fail if, e.g., the underlying table is not writable.
00313   virtual Bool setImageInfo(const ImageInfo& info);
00314 
00315   // Remove a region/mask belonging to the image from the given group
00316   // (which can be Any).
00317   // If a mask removed is the default mask, the image gets unmasked.
00318   // <br>Optionally an exception is thrown if the region does not exist.
00319   virtual void removeRegion (const String& name,
00320                              RegionHandler::GroupType = RegionHandler::Any,
00321                              Bool throwIfUnknown = True);
00322 
00323   // This is the implementation of the letter for the envelope Iterator
00324   // class. <note> Not for public use </note>.
00325   virtual LatticeIterInterface<T>* makeIter
00326                                  (const LatticeNavigator& navigator,
00327                                   Bool useRef) const;
00328 
00329   // Returns the maximum recommended number of pixels for a cursor. This is
00330   // the number of pixels in a tile. 
00331   virtual uInt advisedMaxPixels() const;
00332 
00333   // Help the user pick a cursor for most efficient access.
00334   virtual IPosition doNiceCursorShape (uInt maxPixels) const;
00335 
00336   // Maximum size - not necessarily all used. In pixels.
00337   virtual uInt maximumCacheSize() const;
00338 
00339   // Set the maximum (allowed) cache size as indicated.
00340   virtual void setMaximumCacheSize (uInt howManyPixels);
00341 
00342   // Set the cache size as to "fit" the indicated path.
00343   virtual void setCacheSizeFromPath (const IPosition& sliceShape,
00344                                      const IPosition& windowStart,
00345                                      const IPosition& windowLength,
00346                                      const IPosition& axisPath);
00347     
00348   // Set the actual cache size for this Array to be be big enough for the
00349   // indicated number of tiles. This cache is not shared with PagedArrays
00350   // in other rows and is always clipped to be less than the maximum value
00351   // set using the setMaximumCacheSize member function.
00352   // tiles. Tiles are cached using a first in first out algorithm. 
00353   virtual void setCacheSizeInTiles (uInt howManyTiles);
00354 
00355   // Clears and frees up the caches, but the maximum allowed cache size is 
00356   // unchanged from when setCacheSize was called
00357   virtual void clearCache();
00358 
00359   // Report on cache success.
00360   virtual void showCacheStatistics (ostream& os) const;
00361 
00362   // Handle the (un)locking.
00363   // Unlocking also unlocks the logtable and a possible mask table.
00364   // Locking only locks the image itself.
00365   // <group>
00366   virtual Bool lock (FileLocker::LockType, uInt nattempts);
00367   virtual void unlock();
00368   virtual Bool hasLock (FileLocker::LockType) const;
00369   // </group>
00370 
00371   // Resynchronize the PagedImage object with the table contents.
00372   // The logtable and possible mask table are also synchronized if
00373   // they do not have a readlock.
00374   // <br>This function is only useful if no read-locking is used, ie.
00375   // if the table lock option is UserNoReadLocking or AutoNoReadLocking.
00376   // In that cases the table system does not acquire a read-lock, thus
00377   // does not synchronize itself automatically.
00378   virtual void resync();
00379 
00380   // Flush the data.
00381   virtual void flush();
00382 
00383   // Close the Image and associated files temporarily.
00384   // It'll be reopened automatically when needed or when
00385   // <src>reopen</src> is called explicitly.
00386   virtual void tempClose();
00387 
00388   // If needed, reopen a temporarily closed Image.
00389   virtual void reopen();
00390 
00391 private:
00392   // Function to return the internal Table object to the RegionHandler.
00393   static Table& getTable (void* imagePtr, Bool writable);
00394 
00395   // This must be called in every constructor and place where the image
00396   // is attached to a new image.
00397   void attach_logtable();
00398   void open_logtable();
00399   void restoreUnits (const TableRecord& rec);
00400   void restoreMiscInfo (const TableRecord& rec);
00401   void restoreImageInfo (const TableRecord& rec);
00402   void restoreAll (const TableRecord& rec);
00403 
00404   void check_conformance (const Lattice<T>& other);
00405   void reopenRW();
00406   void setTableType();
00407   void applyMaskSpecifier (const MaskSpecifier&);
00408   void applyMask (const String& maskName);
00409   void makePagedImage (const TiledShape& mapShape,
00410                        const CoordinateSystem& coordinateInfo,
00411                        const String& nameOfNewFile,
00412                        const TableLock& lockOptions,
00413                        uInt rowNumber);
00414   void makePagedImage (const String& filename, const TableLock& lockOptions,
00415                        const MaskSpecifier&, uInt rowNumber);
00416 
00417   const Table& table() const
00418     { return const_cast<PagedImage<T>*>(this)->table(); }
00419 
00420 
00421   PagedArray<T>  map_p;
00422   LatticeRegion* regionPtr_p;
00423   const static String _className;
00424 
00425   //# Make members of parent class known.
00426 public:
00427   using ImageInterface<T>::logSink;
00428   using ImageInterface<T>::logger;
00429   using ImageInterface<T>::imageInfo;
00430   using ImageInterface<T>::coordinates;
00431   using ImageInterface<T>::getDefaultMask;
00432   using ImageInterface<T>::hasRegion;
00433   using ImageInterface<T>::getImageRegionPtr;
00434 protected:
00435   using ImageInterface<T>::setCoordsMember;
00436   using ImageInterface<T>::setMiscInfoMember;
00437   using ImageInterface<T>::setLogMember;
00438   using ImageInterface<T>::setUnitMember;
00439   // using ImageInterface<T>::setImageInfoMember;
00440 };
00441 
00442 
00443 //# A nasty - the column name is hard-coded into this function, needs to
00444 //# be centralized somewhere.
00445 // Determine the pixel type in the PagedImage contained in
00446 // <src>fileName</src>.  If the file doesn't appear to be a Table or cannot
00447 // be opened, TpOther is returned.
00448 // <group name="pixeltype")
00449     DataType imagePixelType(const String& fileName);
00450 // </group>
00451 
00452 
00453 
00454 
00455 
00456 } //# NAMESPACE CASA - END
00457 
00458 #ifndef CASACORE_NO_AUTO_TEMPLATES
00459 #include <images/Images/PagedImage.tcc>
00460 #endif //# CASACORE_NO_AUTO_TEMPLATES
00461 #endif