00001 //# ImageConcat.h: concatenate images along an axis 00002 //# Copyright (C) 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$ 00027 00028 #ifndef IMAGES_IMAGECONCAT_H 00029 #define IMAGES_IMAGECONCAT_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/casa/Arrays/Vector.h> 00035 #include <casacore/casa/Containers/Block.h> 00036 #include <casacore/lattices/Lattices/Lattice.h> 00037 #include <casacore/lattices/Lattices/LatticeConcat.h> 00038 #include <casacore/images/Images/ImageInterface.h> 00039 00040 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00041 00042 //# Forward Declarations 00043 class CoordinateSystem; 00044 template <class T> class ImageSummary; 00045 template <class T> class MaskedLattice; 00046 00047 00048 // <summary> 00049 // Concatenates images along a specified axis 00050 // </summary> 00051 00052 // <use visibility=export> 00053 00054 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00055 // </reviewed> 00056 00057 // <prerequisite> 00058 // <li> <linkto class=LatticeConcat>LatticeConcat</linkto> 00059 // <li> <linkto class=ImageInterface>ImageInterface</linkto> 00060 // </prerequisite> 00061 00062 // <etymology> 00063 // This is a class designed to concatenate images along a specified axis 00064 // </etymology> 00065 00066 // <synopsis> 00067 // This is a class designed to concatenate images along a specified 00068 // axis. This means you can join them together. E.g., 00069 // join images of shape [10,20,30] and [10,20,40] into a lattice 00070 // of shape [10,20,70]. 00071 // 00072 // The ImageConcat object does not copy the input images, it 00073 // just references them. You can use the Lattice<T>::copyData(Lattice<T>) 00074 // function to fill an output image with the concatenated input images 00075 // 00076 // If you use the putSlice function, be aware that it will change the 00077 // underlying images if they are writable. 00078 // 00079 // You can also concatenate a lattice to an image. 00080 // </synopsis> 00081 // 00082 // <example> 00083 // <srcblock> 00084 // IPosition shape(2, 10, 20); 00085 // PagedImage<Float> im1(shape, CoordinateUtil::defaultCoords2D(), 00086 // "tImageConcat_tmp1.img"); 00087 // im1.set(1.0); 00088 // PagedImage<Float> im2(shape, CoordinateUtil::defaultCoords2D(), 00089 // "tImageConcat_tmp2.img"); 00090 // im2.set(2.0); 00091 // 00093 // 00094 // ImageConcat<Float> concat(0); 00095 // 00097 // 00098 // concat.setImage(im1, True); 00099 // concat.setImage(im2, True); 00100 // 00102 // 00103 // PagedImage<Float> im3(concat.shape(), CoordinateUtil::defaultCoords2D(), 00104 // "tImageConcat_tmp3.img"); 00105 // 00107 // 00108 // im3.copyData(concat); 00109 // 00110 // </srcblock> 00111 // See tImageConcat.cc for more examples. 00112 // </example> 00113 00114 00115 // <motivation> 00116 // Image concatentation is a useful enduser requirement. 00117 // </motivation> 00118 00119 // <todo asof="1999/10/23"> 00120 // <li> Offer the ability to increase the dimensionality of 00121 // the output image 00122 // </todo> 00123 00124 00125 template <class T> class ImageConcat : public ImageInterface<T> 00126 { 00127 public: 00128 00129 // Constructor. Specify the pixel axis for concatenation 00130 explicit ImageConcat (uInt axis, Bool tempClose=True); 00131 00132 // Construct the object from an AipsIO file with the given name. 00133 ImageConcat (AipsIO& aio, const String& fileName); 00134 00135 // Default constructor, Sets the concatenation axis to 0 00136 ImageConcat(); 00137 00138 // Copy constructor (reference semantics) 00139 ImageConcat (const ImageConcat<T> &other); 00140 00141 // Destructor 00142 virtual ~ImageConcat(); 00143 00144 // Assignment operator (reference semantics) 00145 ImageConcat<T> &operator= (const ImageConcat<T> &other); 00146 00147 // Make a copy of the object (reference semantics). 00148 virtual ImageInterface<T>* cloneII() const; 00149 00150 // Save the image in an AipsIO file with the given name. 00151 // It can be opened by the constructor taking a file name. 00152 virtual void save (const String& fileName) const; 00153 00154 // Get the image type (returns name of derived class). 00155 virtual String imageType() const; 00156 00157 // Is the lattice persistent and can it be loaded by other processes as well? 00158 virtual Bool isPersistent() const; 00159 00160 // Sets a new image into the list to be concatenated. 00161 // If relax is False, throws an exception if the images 00162 // are not contiguous along the concatenation axis. 00163 // If relax is True, it will create a non-regular TabularCoordinate 00164 // for non-contiguous images if the coordinates are monotonic. 00165 // Otherwise, it just uses the coordinates of the image 00166 void setImage (ImageInterface<T>& image, Bool relax); 00167 00168 // Add a clone of the lattice to the list to be concatenated. 00169 // You can only concatenate a lattice with an image if 00170 // you have first used setImage to set an image (this 00171 // provides the CooridinateSystem information) 00172 void setLattice (MaskedLattice<T>& lattice); 00173 00174 // Return the number of images/lattices set so far 00175 uInt nimages() const 00176 { return latticeConcat_p.nlattices(); } 00177 00178 // Returns the current concatenation axis (0 relative) 00179 uInt axis () const 00180 { return latticeConcat_p.axis(); } 00181 00182 // Returns the number of dimensions of the *input* images/lattices 00183 // Returns 0 if none yet set. 00184 uInt imageDim() const 00185 { return latticeConcat_p.latticeDim(); } 00186 00187 // Handle the (un)locking and syncing, etc. 00188 // <group> 00189 virtual Bool lock (FileLocker::LockType, uInt nattempts); 00190 virtual void unlock(); 00191 virtual Bool hasLock (FileLocker::LockType) const; 00192 virtual void resync(); 00193 virtual void flush(); 00194 virtual void tempClose(); 00195 virtual void reopen(); 00196 // </group> 00197 00198 // Return the name of the current ImageInterface object. 00199 // If the object is persistent, it returns its file name. 00200 // Otherwise it returns the string "Concatenation :" 00201 virtual String name (Bool stripPath=False) const; 00202 00203 // Has the object really a mask? 00204 virtual Bool isMasked() const; 00205 00206 // Does the image have a pixelmask? 00207 virtual Bool hasPixelMask() const; 00208 00209 // Get access to the pixelmask. 00210 // An exception is thrown if the image does not have a pixelmask 00211 // <group> 00212 virtual const Lattice<Bool>& pixelMask() const; 00213 virtual Lattice<Bool>& pixelMask(); 00214 // </group> 00215 00216 // Get the region used (always returns 0) 00217 virtual const LatticeRegion* getRegionPtr() const; 00218 00219 // If all of the underlying lattices are writable returns True 00220 virtual Bool isWritable() const; 00221 00222 // Return the shape of the concatenated image 00223 virtual IPosition shape() const; 00224 00225 00226 // Return the best cursor shape. This isn't very meaningful for an ImageConcat 00227 // Image since it isn't on disk ! But if you do copy it out, this is 00228 // what you should use. The maxPixels aregument is ignored. 00229 virtual IPosition doNiceCursorShape (uInt maxPixels) const; 00230 00231 // Do the actual get of the data. 00232 // The return value is always False, thus the buffer does not reference 00233 // another array. Generally the user should use function getSlice 00234 virtual Bool doGetSlice (Array<T>& buffer, const Slicer& section); 00235 00236 // Do the actual get of the mask data. 00237 // The return value is always False, thus the buffer does not reference 00238 // another array. Generally the user should use function getMaskSlice 00239 virtual Bool doGetMaskSlice (Array<Bool>& buffer, const Slicer& section); 00240 00241 // Do the actual put of the data into the Lattice. This will change the 00242 // underlying images (if they are writable) that were used to create the 00243 // ImageConcat object. It throws an exception if not writable. 00244 // Generally the user should use function putSlice 00245 virtual void doPutSlice (const Array<T>& sourceBuffer, 00246 const IPosition& where, 00247 const IPosition& stride); 00248 00249 // Throws an excpetion as you cannot reshape an ImageConcat object 00250 virtual void resize(const TiledShape&); 00251 00252 // Check class invariants. 00253 virtual Bool ok() const; 00254 00255 // These are the implementations of the LatticeIterator letters. 00256 // <note> not for public use </note> 00257 virtual LatticeIterInterface<T> *makeIter 00258 (const LatticeNavigator &navigator, 00259 Bool useRef) const; 00260 00261 00262 private: 00263 LatticeConcat<T> latticeConcat_p; 00264 Bool warnAxisNames_p, warnAxisUnits_p, warnImageUnits_p; 00265 Bool warnContig_p, warnRefPix_p, warnRefVal_p, warnInc_p, warnTab_p; 00266 Bool isContig_p; 00267 mutable String fileName_p; // Empty if not persistent 00268 Vector<Bool> isImage_p; 00269 Vector<Double> pixelValues_p; 00270 Vector<Double> worldValues_p; 00271 Coordinate::Type originalAxisType_p; 00272 00273 Double coordConvert(Int& worldAxis, LogIO& os, 00274 const CoordinateSystem& cSys, 00275 uInt axis, Double pixelCoord) const; 00276 00277 void _checkContiguous(const IPosition& shape1, 00278 const CoordinateSystem& cSys1, 00279 const CoordinateSystem& cSys2, 00280 LogIO& os, uInt axis, Bool relax); 00281 00282 void checkNonConcatAxisCoordinates (LogIO& os, 00283 const ImageInterface<T>& image, 00284 Bool relax); 00285 00286 Vector<Int> makeNewStokes(const Vector<Int>& stokes1, 00287 const Vector<Int>& stokes2); 00288 00289 // Updates the CoordinateSystem in the ImageConcat image. The first lattice must 00290 // be an image. The first lattice is contiguous by definition. The Coordinate 00291 // System for the first image must be set before calling this function. For 00292 // the first image, this function just sets up worldValues and pixelValues 00293 void setCoordinates(); 00294 00295 void _updatePixelAndWorldValues(uInt iIm); 00296 00297 //# Make members of parent class known. 00298 public: 00299 using ImageInterface<T>::logger; 00300 using ImageInterface<T>::coordinates; 00301 using ImageInterface<T>::units; 00302 using ImageInterface<T>::miscInfo; 00303 protected: 00304 using ImageInterface<T>::setCoordsMember; 00305 using ImageInterface<T>::setMiscInfoMember; 00306 }; 00307 00308 00309 00310 } //# NAMESPACE CASACORE - END 00311 00312 #ifndef CASACORE_NO_AUTO_TEMPLATES 00313 #include <casacore/images/Images/ImageConcat.tcc> 00314 #endif //# CASACORE_NO_AUTO_TEMPLATES 00315 #endif