00001 //# ImageInterface.h: a base class for astronomical images 00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001 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_IMAGEINTERFACE_H 00029 #define IMAGES_IMAGEINTERFACE_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/images/Regions/RegionHandler.h> 00035 #include <casacore/images/Images/MaskSpecifier.h> 00036 #include <casacore/images/Images/ImageInfo.h> 00037 #include <casacore/images/Images/ImageAttrHandler.h> 00038 #include <casacore/lattices/Lattices/MaskedLattice.h> 00039 #include <casacore/coordinates/Coordinates/CoordinateSystem.h> 00040 #include <casacore/tables/LogTables/LoggerHolder.h> 00041 #include <casacore/tables/Tables/TableRecord.h> 00042 #include <casacore/casa/Quanta/Unit.h> 00043 00044 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00045 00046 //# Forward Declarations 00047 template <class T> class LatticeIterInterface; 00048 template <class T> class Vector; 00049 template <class T> class COWPtr; 00050 class ImageRegion; 00051 class IPosition; 00052 class TiledShape; 00053 00054 00055 // <summary> 00056 // A base class for astronomical images. 00057 // </summary> 00058 00059 // <use visibility=export> 00060 00061 // <reviewed reviewer="" date="" tests="" demos=""> 00062 // </reviewed> 00063 00064 // <prerequisite> 00065 // <li> <linkto class=Lattice>Lattices</linkto> 00066 // <li> <linkto class=CoordinateSystem>CoordinateSystem</linkto> 00067 // </prerequisite> 00068 00069 // <etymology> 00070 // The ImageInterface class name is derived from its role as the cookie cutter 00071 // Interface base class for Images. 00072 // </etymology> 00073 00074 // <synopsis> 00075 // The ImageInterface class is an abstract base class. All Image classes 00076 // should derive from this class to ensure functions which operate on Images 00077 // will work for all Image derivations. 00078 // 00079 // An Image is currently defined as an Array of pixels, a Boolean mask, 00080 // defining which pixels are valid and coordinates to define the reference 00081 // frame. The only concrete class currently derived from this Interface is 00082 // PagedImage, which allows the image to be stored on disk, and only reads 00083 // specified portions of the image into memory. 00084 // </synopsis> 00085 00086 // <example> 00087 // As this is an abstract base class it is not possible to construct an 00088 // instance of this object. It can however be used as a function argument.<br> 00089 // eg 1. (used in dImageInterface.cc) 00090 // <srcblock> 00091 // Float sumPixels(const ImageInterface<Float>& image){ 00092 // uInt rowLength = image.shape()(0); 00093 // IPosition rowShape(image.ndim()); 00094 // rowShape = 1; rowShape(0) = rowLength; 00095 // Float sumPix = 0; 00096 // RO_LatticeIterator<Float> iter(image, rowShape); 00097 // while(!iter.atEnd()){ 00098 // sumPix += sum(iter.vectorCursor()); 00099 // iter++; 00100 // } 00101 // return sumPix; 00102 // } 00103 // </srcblock> 00104 // 00105 // The main purpose of this class is for programming objects, the following 00106 // example is of how one would derive from ImageInterface: <br> 00107 // eg 2. 00108 // <srcblock> 00109 // template <class T> class myNewImage : public ImageInterface<T> 00110 // { 00111 // public: 00112 // // default constructor 00113 // myNewImage(); 00114 // 00115 // // argumented constructor 00116 // myNewImage(...); 00117 // 00118 // // destructor 00119 // ~myNewImage 00120 // 00121 // // the shape function is forced upon us by the Lattice base class 00122 // IPosition shape() const; 00123 // 00124 // // doGetSlice is another function required of all Lattice objects. 00125 // Bool doGetSlice(<Array<T>& buffer, const Slicer& section); 00126 // 00127 // // etc... 00128 // private: 00129 // // put the actual map data down here. 00130 // // etc... 00131 // }; 00132 // </srcblock> 00133 // </example> 00134 00135 // <motivation> 00136 // The use of abstract base classes to guide inheritance seemed appropriate 00137 // for Images to ensure that CoordinateSystems and masking get handled 00138 // uniformly. 00139 // </motivation> 00140 00141 // <todo asof="1995/04/25"> 00142 // <li> replace ImageCoordinates 00143 // </todo> 00144 00145 00146 template <class T> class ImageInterface: public MaskedLattice<T> 00147 { 00148 //# Make members of parent class known. 00149 public: 00150 using MaskedLattice<T>::shape; 00151 00152 public: 00153 ImageInterface(); 00154 00155 // Construct for a specific region handler object. 00156 ImageInterface (const RegionHandler& regionHandler); 00157 00158 // Copy constructor (copy semantics). 00159 ImageInterface (const ImageInterface& other); 00160 00161 virtual ~ImageInterface(); 00162 00163 // Make a copy of the derived object (reference semantics). 00164 // <group> 00165 virtual MaskedLattice<T>* cloneML() const; 00166 virtual ImageInterface<T>* cloneII() const = 0; 00167 // </group> 00168 00169 // Get the image type (returns name of derived class). 00170 virtual String imageType() const = 0; 00171 00172 // Function which changes the shape of the image (N.B. the data is thrown 00173 // away - the Image will be filled with nonsense afterwards) 00174 virtual void resize (const TiledShape& newShape) = 0; 00175 00176 // Function which get and set the units associated with the image 00177 // pixels (i.e. the "brightness" unit). <src>setUnits()</src> returns 00178 // False if it cannot set the unit for some reason (e.g. the underlying 00179 // file is not writable). 00180 // <group> 00181 virtual Bool setUnits (const Unit& newUnits); 00182 virtual const Unit& units() const 00183 { return unit_p; } 00184 // </group> 00185 00186 // Return the name of the current ImageInterface object. This will generally 00187 // be a file name for images that have a persistent form. Any path 00188 // before the actual file name can be optionally stripped off. 00189 virtual String name (Bool stripPath=False) const = 0; 00190 00191 // Functions to set or replace the coordinate information in the Image 00192 // Returns False on failure, e.g. if the number of axes do not match. 00193 // <group> 00194 virtual Bool setCoordinateInfo (const CoordinateSystem& coords); 00195 const CoordinateSystem& coordinates() const 00196 { return coords_p; } 00197 // </group> 00198 00199 // Function to get a LELCoordinate object containing the coordinates. 00200 virtual LELCoordinates lelCoordinates() const; 00201 00202 // Get access to the LoggerHolder. 00203 // <group> 00204 LoggerHolder& logger() 00205 { return log_p; } 00206 const LoggerHolder& logger() const 00207 { return log_p; } 00208 // </group> 00209 00210 // Allow messages to be logged to this ImageInterface. 00211 // <group> 00212 LogIO& logSink() 00213 { return logger().logio(); } 00214 const LogIO& logSink() const 00215 { return const_cast<ImageInterface<T>*>(this)->logSink(); } 00216 // </group> 00217 00218 // Add the messages from the other image logger to this one. 00219 void appendLog (const LoggerHolder& other) 00220 { log_p.append (other); } 00221 00222 // Often we have miscellaneous information we want to attach to an image. 00223 // This is where it goes. 00224 // <br> 00225 // Note that setMiscInfo REPLACES the information with the new information. 00226 // It can fail if, e.g., the underlying table is not writable. 00227 // <group> 00228 const TableRecord& miscInfo() const 00229 { return miscInfo_p; } 00230 virtual Bool setMiscInfo (const RecordInterface& newInfo); 00231 // </group> 00232 00233 // The ImageInfo object contains some miscellaneous information about the image 00234 // which unlike that stored in MiscInfo, has a standard list of things, 00235 // such as the restoring beam. 00236 // 00237 // Note that setImageInfo REPLACES the information with the new information. 00238 // It is up to the derived class to make the ImageInfo permanent. 00239 // <group> 00240 const ImageInfo& imageInfo() const 00241 { return imageInfo_p; } 00242 virtual Bool setImageInfo (const ImageInfo& info); 00243 // </group> 00244 00245 // Get access to the attribute handler. 00246 // By default an empty handler is returned where no groups can be added to. 00247 // <group> 00248 virtual ImageAttrHandler& attrHandler (Bool createHandler=False); 00249 ImageAttrHandler& roAttrHandler() const 00250 { return const_cast<ImageInterface<T>*>(this)->attrHandler(False); } 00251 // </group> 00252 00253 // Can the image handle region definition? 00254 Bool canDefineRegion() const 00255 { return regHandPtr_p->canDefineRegion(); } 00256 00257 // Make a mask which is suitable for the type of image. 00258 // Optionally the mask can be initialized with the given value 00259 // (by default it will not). 00260 // <br>Optionally the mask can be defined as an image region/mask 00261 // and turned in the default mask for the image. By default it will. 00262 virtual ImageRegion makeMask (const String& name, 00263 Bool defineAsRegion = True, 00264 Bool setAsDefaultMask = True, 00265 Bool initialize = False, 00266 Bool value = True); 00267 00268 // Define a region/mask belonging to the image. 00269 // The group type determines if it stored as a region or mask. 00270 // If overwrite=False, an exception will be thrown if the region 00271 // already exists. 00272 // <br>An exception is thrown if canDefineRegion is False. 00273 virtual void defineRegion (const String& name, const ImageRegion& region, 00274 RegionHandler::GroupType, 00275 Bool overwrite = False); 00276 00277 // Does the image have a region with the given name? 00278 virtual Bool hasRegion (const String& regionName, 00279 RegionHandler::GroupType = RegionHandler::Any) const; 00280 00281 // Get a region/mask belonging to the image from the given group 00282 // (which can be Any). 00283 // <br>Optionally an exception is thrown if the region does not exist. 00284 // A zero pointer is returned if the region does not exist. 00285 // The caller has to delete the <src>ImageRegion</src> object created. 00286 virtual ImageRegion* getImageRegionPtr 00287 (const String& name, 00288 RegionHandler::GroupType = RegionHandler::Any, 00289 Bool throwIfUnknown = True) const; 00290 00291 // Rename a region. 00292 // If a region with the new name already exists, it is deleted or 00293 // an exception is thrown (depending on <src>overwrite</src>). 00294 // The region name is looked up in the given group(s). 00295 // <br>An exception is thrown if the old region name does not exist. 00296 virtual void renameRegion (const String& newName, 00297 const String& oldName, 00298 RegionHandler::GroupType = RegionHandler::Any, 00299 Bool overwrite = False); 00300 00301 // Remove a region/mask belonging to the image from the given group 00302 // (which can be Any). 00303 // <br>Optionally an exception is thrown if the region does not exist. 00304 virtual void removeRegion (const String& name, 00305 RegionHandler::GroupType = RegionHandler::Any, 00306 Bool throwIfUnknown = True); 00307 00308 // Get the names of all regions/masks. 00309 virtual Vector<String> regionNames 00310 (RegionHandler::GroupType = RegionHandler::Any) const; 00311 00312 // Use the mask as specified. 00313 // If a mask was already in use, it is replaced by the new one. 00314 virtual void useMask (MaskSpecifier = MaskSpecifier()); 00315 00316 // Set the default pixelmask to the mask with the given name 00317 // (which has to exist in the "masks" group). 00318 // If the image table is writable, the setting is persistent by writing 00319 // the name as a keyword. 00320 // If the given regionName is the empty string, 00321 // the default pixelmask is unset. 00322 virtual void setDefaultMask (const String& regionName); 00323 00324 // Get the name of the default pixelmask. 00325 // An empty string is returned if no default pixelmask. 00326 virtual String getDefaultMask() const; 00327 00328 // Get a region belonging to the image. 00329 // An exception is thrown if the region does not exist. 00330 ImageRegion getRegion (const String& regionName, 00331 RegionHandler::GroupType = RegionHandler::Any) const; 00332 00333 // Make a unique region name from the given root name, thus make it such 00334 // that the name is not already in use for a region or mask. 00335 // The root name is returned if it is already unique. 00336 // Otherwise a number is appended to the root name to make it unique. 00337 // The number starts at the given number and is incremented until the name 00338 // is unique. 00339 String makeUniqueRegionName (const String& rootName, 00340 uInt startNumber = 1) const; 00341 00342 // Check class invariants. 00343 virtual Bool ok() const = 0; 00344 00345 // Save and restore an ImageInterface object to or from a state Record 00346 Bool toRecord (String& error, RecordInterface& outRec); 00347 Bool fromRecord (String& error, const RecordInterface& inRec); 00348 00349 protected: 00350 // Assignment (copy semantics) is only useful for derived classes. 00351 ImageInterface& operator= (const ImageInterface& other); 00352 00353 // Restore the image info from the record. 00354 Bool restoreImageInfo (const RecordInterface& rec); 00355 00356 // Set the image logger variable. 00357 void setLogMember (const LoggerHolder& logger) 00358 { log_p = logger; } 00359 00360 // Set the image info variable. 00361 void setImageInfoMember (const ImageInfo& imageInfo); 00362 00363 // Set the coordinate system variable. 00364 void setCoordsMember (const CoordinateSystem& coords) 00365 { coords_p = coords; } 00366 00367 // Set the unit variable. 00368 void setUnitMember (const Unit& unit) 00369 { unit_p = unit; } 00370 00371 // Set the miscinfo variable. 00372 void setMiscInfoMember (const RecordInterface& rec) 00373 { miscInfo_p.assign (rec); } 00374 00375 // Get access to the region handler. 00376 RegionHandler* getRegionHandler() 00377 { return regHandPtr_p; } 00378 00379 // Get non-const access to the ImageInfo. 00380 ImageInfo& rwImageInfo() 00381 { return imageInfo_p; } 00382 00383 private: 00384 // It is the job of the derived class to make these variables valid. 00385 CoordinateSystem coords_p; 00386 LoggerHolder log_p; 00387 ImageInfo imageInfo_p; 00388 Unit unit_p; 00389 TableRecord miscInfo_p; 00390 00391 // The region handling object. 00392 RegionHandler* regHandPtr_p; 00393 00394 // The attribute handling object. 00395 ImageAttrHandler itsBaseAttrHandler; 00396 }; 00397 00398 00399 //# Declare extern templates for often used types. 00400 #ifdef AIPS_CXX11 00401 extern template class ImageInterface<Float>; 00402 extern template class ImageInterface<Complex>; 00403 #endif 00404 00405 00406 } //# NAMESPACE CASACORE - END 00407 00408 #ifndef CASACORE_NO_AUTO_TEMPLATES 00409 #include <casacore/images/Images/ImageInterface.tcc> 00410 #endif //# CASACORE_NO_AUTO_TEMPLATES 00411 #endif