casa
$Rev:20696$
|
00001 //# ImageUtilities.h: Some utility functions handy for accessing images 00002 //# Copyright (C) 1996,1997,1999,2000,2001,2002 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 //# 00027 //# $Id: ImageUtilities.h 20229 2008-01-29 15:19:06Z gervandiepen $ 00028 #ifndef IMAGES_IMAGEUTILITIES_H 00029 #define IMAGES_IMAGEUTILITIES_H 00030 00031 00032 #include <casa/aips.h> 00033 #include <components/ComponentModels/ComponentType.h> 00034 #include <components/ComponentModels/GaussianBeam.h> 00035 #include <coordinates/Coordinates/DirectionCoordinate.h> 00036 #include <images/Images/MaskSpecifier.h> 00037 #include <measures/Measures/Stokes.h> 00038 #include <lattices/Lattices/TiledShape.h> 00039 #include <casa/Utilities/PtrHolder.h> 00040 #include <casa/Containers/SimOrdMap.h> 00041 00042 #include <memory> 00043 00044 namespace casa { //# NAMESPACE CASA - BEGIN 00045 00046 //# Forward Declarations 00047 template <class T> class ImageInterface; 00048 template <class T> class Vector; 00049 template <class T> class Quantum; 00050 template <class T> class MaskedArray; 00051 class LatticeBase; 00052 class CoordinateSystem; 00053 class Coordinate; 00054 class SkyComponent; 00055 class ImageInfo; 00056 class String; 00057 class IPosition; 00058 class LogIO; 00059 class Unit; 00060 class AxesSpecifier; 00061 00062 // 00063 // <summary> 00064 // Utility functions for Image manipulation 00065 // </summary> 00066 // 00067 // 00068 // <use visibility=export> 00069 // 00070 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00071 // </reviewed> 00072 // 00073 // <prerequisite> 00074 // <li> IPosition 00075 // <li> Arrays 00076 // <li> Lattice 00077 // </prerequisite> 00078 // 00079 // <synopsis> 00080 // Some helpful static functions that are common to some of my image 00081 // analysis application classes. 00082 // </synopsis> 00083 // 00084 // <motivation> 00085 // I needed some bits and pieces. My goal isto move this rag-tag bunch 00086 // out of here into other classes as time goes on. So far 00087 // I have eliminated 80% of the original ! 00088 // </motivation> 00089 // 00090 // <todo asof="1996/11/27"> 00091 // <li> 00092 // </todo> 00093 00094 00095 class ImageUtilities 00096 { 00097 public: 00098 // Open disk image (can be any registered image). Exception 00099 // if fileName empty or file does not exist or file is not 00100 // of legal image type. For aips++ images, the default mask is 00101 // applied. 00102 // <group> 00103 static void openImage( 00104 std::auto_ptr<ImageInterface<Float> >& image, 00105 const String& fileName, LogIO& os 00106 ); 00107 00108 static void openImage( 00109 ImageInterface<Float>*& image, 00110 const String& fileName, LogIO& os 00111 ); 00112 // </group> 00113 00114 // Copy MiscInfo, ImageInfo, brightness unit and logger (history) from in to out 00115 template <typename T, typename U> 00116 static void copyMiscellaneous ( 00117 ImageInterface<T>& out, 00118 const ImageInterface<U>& in, 00119 const Bool copyImageInfo = True 00120 ); 00121 00122 // Copy a mask from one image to another 00123 static void copyMask (ImageInterface<Float>& out, 00124 const ImageInterface<Float>& in, 00125 const String& maskOut, const String& maskIn, 00126 AxesSpecifier axesSpecifier); 00127 00128 // Add one degenerate axis for each of the specified coordinate types. 00129 // If the outfile string is given the new image is a PagedImage. 00130 // If the outfile string is empty, the new image is a TempImage. 00131 static void addDegenerateAxes ( 00132 LogIO& os, 00133 PtrHolder<ImageInterface<Float> >& outImage, 00134 const ImageInterface<Float>& inImage, 00135 const String& outFile, Bool direction, 00136 Bool spectral, const String& stokes, 00137 Bool linear, Bool tabular, Bool overwrite 00138 ); 00139 00140 // Function to bin up (average data) one axis of an N-D MaskedArray. The interface 00141 // is pretty specific to a particular application. It's here because 00142 // its implemented with ImageRebin. On input, the output MA *must* 00143 // have zero shape. The input and output Coordinates must have the 00144 // same type and have only one axis (Linear,Spectral & Tabular). 00145 // The output coordinate is adjusted for the binning. The binning 00146 // factor does not have to fit integrally into the shape of the specified 00147 // axis. 00148 template <typename T> 00149 static void bin (MaskedArray<T>& out, Coordinate& coordOut, 00150 const MaskedArray<T>& in, const Coordinate& coordIn, 00151 uInt axis, uInt bin); 00152 00153 // This function converts pixel coordinates to world coordinates. You 00154 // specify a vector of pixel coordinates (<src>pixels</src>) for only one 00155 // axis, the <src>pixelAxis</src>. For the other pixel axes in the 00156 // <src>CoordinateSystem</src>, if a pixel axis "i" is found in the 00157 // <src>CursorAxes</src> vector, its pixel coordinate is set to 00158 // the average of the selected region from the image for that axis 00159 // (<src>(blc(i)+trc(i))/2)</src>), otherwise it is set to the reference pixel. 00160 // The vector of world coordinates for <src>pixelAxis</src> is returned as formatted 00161 // Strings. If for some reason it can't make the conversion, the element 00162 // element is returned as "?" Returns <src>False</src> if the lengths of 00163 // <<src>blc</src> and <src>trc</src> are not equal to the number of pixel axes 00164 // in the coordinate system. 00165 static Bool pixToWorld ( 00166 Vector<String>& sWorld, 00167 CoordinateSystem& cSys, 00168 const Int& pixelAxis, 00169 const Vector<Int>& cursorAxes, 00170 const IPosition& blc, 00171 const IPosition& trc, 00172 const Vector<Double>& pixels, 00173 const Int& prec, 00174 const Bool usePrecForMixed=False 00175 ); 00176 00177 // Convert long axis names "Right Ascension", "Declination", "Frequency" and 00178 // "Velocity" to "RA", "Dec", "Freq", "Vel" respectively. Unknown strings 00179 // are returned as given. 00180 static String shortAxisName (const String& axisName); 00181 00182 // These functions convert between a vector of doubles holding SkyComponent values 00183 // (the output from SkyComponent::toPixel) and a SkyComponent. The coordinate 00184 // values are in the 'x' and 'y' frames. It is possible that the x and y axes of 00185 // the pixel array are lat/long (xIsLong=False) rather than long/lat. 00186 // facToJy converts the brightness units from whatevers per whatever 00187 // to Jy per whatever (e.g. mJy/beam to Jy/beam). It is unity if it 00188 // can't be done and you get a warning. In the SkyComponent the flux 00189 // is integral. In the parameters vector it is peak. 00190 // 00191 // pars(0) = FLux image units (e.g. Jy/beam). 00192 // pars(1) = x cen abs pix 00193 // pars(2) = y cen abs pix 00194 // pars(3) = major pix 00195 // pars(4) = minor pix 00196 // pars(5) = pa radians (pos +x -> +y) 00197 // 00198 // 5 values for ComponentType::Gaussian, CT::Disk. 3 values for CT::Point. 00199 // 00200 // <group> 00201 static SkyComponent encodeSkyComponent(LogIO& os, Double& facToJy, 00202 const CoordinateSystem& cSys, 00203 const Unit& brightnessUnit, 00204 ComponentType::Shape type, 00205 const Vector<Double>& parameters, 00206 Stokes::StokesTypes stokes, 00207 Bool xIsLong, const GaussianBeam& beam); 00208 00209 // for some reason, this method was in ImageAnalysis but also belongs here. 00210 // Obviously hugely confusing to have to methods with the same name and 00211 // which presumably are for the same thing in two different classes. I'm 00212 // moving ImageAnalysis' method here and also moving that implamentation to 00213 // here as well and also being consistent regarding callers (ie those that 00214 // called the ImageAnalysis method will now call this method). I couldn't 00215 // tell you which of the two implementations is the better one to use 00216 // for new code, but this version does call the version that already existed 00217 // in ImageUtilities, so this version seems to do a bit more. 00218 // I also hate having a class with anything like Utilities in the name, 00219 // but I needed to move this somewhere and can only tackle one issue 00220 // at a time. 00221 static casa::SkyComponent encodeSkyComponent( 00222 casa::LogIO& os, casa::Double& fluxRatio, 00223 const casa::ImageInterface<casa::Float>& im, 00224 casa::ComponentType::Shape modelType, 00225 const casa::Vector<casa::Double>& parameters, 00226 casa::Stokes::StokesTypes stokes, 00227 casa::Bool xIsLong, casa::Bool deconvolveIt, 00228 const GaussianBeam& beam 00229 ); 00230 00231 // Deconvolve SkyComponent from beam 00232 // moved from ImageAnalysis. this needs to be moved to a more appropriate class at some point 00233 static SkyComponent deconvolveSkyComponent( 00234 LogIO& os, const SkyComponent& skyIn, 00235 const GaussianBeam& beam 00236 ); 00237 00238 /* 00239 // moved from ImageAnalysis. this needs to be moved to a more appropriate class at some point 00240 // Put beam into +x -> +y frame 00241 static GaussianBeam putBeamInXYFrame ( 00242 const GaussianBeam& beam, 00243 const casa::DirectionCoordinate& dirCoord 00244 ); 00245 */ 00246 00247 // moved from ImageAnalysis. this needs to be moved to a more appropriate class at some point 00248 static Vector<Double> decodeSkyComponent ( 00249 const SkyComponent& sky, const ImageInfo& ii, 00250 const CoordinateSystem& cSys, const Unit& brightnessUnit, 00251 Stokes::StokesTypes stokes, Bool xIsLong 00252 ); 00253 // </group> 00254 00255 // moved from ImageAnalysis. this needs to be moved to a more appropriate class at some point 00256 // Deconvolve from beam 00257 // Returns True if the deconvolved source is a point source, False otherwise. 00258 /* 00259 static Bool deconvolveFromBeam( 00260 Angular2DGaussian& deconvolvedSize, 00261 const Angular2DGaussian& convolvedSize, 00262 Bool& successFit, LogIO& os, 00263 const GaussianBeam& beam, const Bool verbose=True 00264 ); 00265 */ 00266 00267 /* 00268 static Bool deconvolveFromBeam( 00269 Quantity& majorFit, Quantity& minorFit, 00270 Quantity& paFit, casa::Bool& successFit, casa::LogIO& os, 00271 const Vector<Quantity>& sourceIn, const GaussianBeam& beam, 00272 const Bool verbose=True 00273 ); 00274 */ 00275 00276 // 00277 // Convert 2d shape from world (world parameters=x, y, major axis, 00278 // minor axis, position angle) to pixel (major, minor, pa). 00279 // Can handle quantum units 'pix'. If one width is 00280 // in pixel units both must be in pixel units. pixelAxes describes which 00281 // 2 pixel axes of the coordinate system our 2D shape is in. 00282 // If axes are not from the same coordinate type units must be pixels. 00283 // If doRef is True, then x and y are taken from the reference 00284 // value rather than the parameters vector. 00285 // 00286 // On input, pa is N->E (at ref pix) for celestial planes. 00287 // Otherwise pa is in pixel coordinate system +x -> +y 00288 // On output, pa (radians) is positive +x -> +y in pixel frame 00289 static void worldWidthsToPixel (LogIO& os, Vector<Double>& dParameters, 00290 const Vector<Quantum<Double> >& parameters, 00291 const CoordinateSystem& cSys, 00292 const IPosition& pixelAxes, 00293 Bool doRef=False); 00294 00295 00296 // Convert 2d shape from pixels (parameters=x,y, major axis, 00297 // minor axis, position angle) to world (major, minor, pa) 00298 // at specified location. pixelAxes describes which 00299 // 2 pixel axes of the coordinate system our 2D shape is in. 00300 // If doRef is True, then x and y are taken from the reference 00301 // pixel rather than the paraneters vector. 00302 // 00303 // On input pa is positive for +x -> +y in pixel frame 00304 // On output pa is positive N->E 00305 // Returns True if major/minor exchanged themselves on conversion to world. 00306 static Bool pixelWidthsToWorld (LogIO& os, 00307 GaussianBeam& wParameters, 00308 const Vector<Double>& pParameters, 00309 const CoordinateSystem& cSys, 00310 const IPosition& pixelAxes, 00311 Bool doRef=False); 00312 00313 // write the specified image and add the specified pixels to it. 00314 // Currently no checks are done to ensure the pixel array size and 00315 // mapShape are compatible; the caller is responsible for this check. 00316 static void writeImage( 00317 const TiledShape& mapShape, 00318 const CoordinateSystem& coordinateInfo, 00319 const String& imageName, 00320 const Array<Float>& pixels, LogIO& log, 00321 const Array<Bool>& pixelMask = Array<Bool>() 00322 ); 00323 00324 static GaussianBeam makeFakeBeam( 00325 LogIO& logIO, const CoordinateSystem& csys, 00326 Bool suppressWarnings = False 00327 ); 00328 00329 static void getUnitAndDoppler( 00330 String& xUnit, String& doppler, 00331 const uInt axis, const CoordinateSystem& csys 00332 ); 00333 00334 private: 00335 00336 // Convert 2d sky shape (parameters=major axis, minor axis, position angle) 00337 // from pixels to world at reference pixel. pixelAxes describes which 00338 // 2 pixel axes of the coordinate system our 2D shape is in. 00339 // On input pa is positive for +x -> +y in pixel frame 00340 // On output pa is positive N->E 00341 // Returns True if major/minor exchanged themselves on conversion to world. 00342 static Bool skyPixelWidthsToWorld (LogIO& os, 00343 GaussianBeam& wParameters, 00344 const CoordinateSystem& cSys, 00345 const Vector<Double>& pParameters, 00346 const IPosition& pixelAxes, Bool doRef); 00347 00348 // Convert a length and position angle in world units (for a non-coupled 00349 // coordinate) to pixels. The length is in some 2D plane in the 00350 // CoordinateSystem specified by pixelAxes. 00351 static Double worldWidthToPixel (LogIO& os, Double positionAngle, 00352 const Quantum<Double>& length, 00353 const CoordinateSystem& cSys, 00354 const IPosition& pixelAxes); 00355 00356 00357 00358 static Quantum<Double> pixelWidthToWorld (LogIO& os, Double positionAngle, 00359 Double length, 00360 const CoordinateSystem& cSys, 00361 const IPosition& pixelAxes); 00362 }; 00363 00364 00365 00366 } //# NAMESPACE CASA - END 00367 00368 #ifndef CASACORE_NO_AUTO_TEMPLATES 00369 #include <images/Images/ImageUtilities2.tcc> 00370 #endif //# CASACORE_NO_AUTO_TEMPLATES 00371 #endif