casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ImageRegrid.h
Go to the documentation of this file.
00001 //# ImageRegrid.h: Regrid Images
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,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 //#
00027 //# $Id: ImageRegrid.h 20229 2008-01-29 15:19:06Z gervandiepen $
00028 
00029 #ifndef IMAGES_IMAGEREGRID_H
00030 #define IMAGES_IMAGEREGRID_H
00031 
00032 #include <casa/aips.h>
00033 #include <casa/Arrays/Matrix.h>
00034 #include <casa/Arrays/Cube.h>
00035 #include <measures/Measures/MDirection.h>
00036 #include <measures/Measures/MFrequency.h>
00037 #include <scimath/Mathematics/Interpolate2D.h>
00038 
00039 namespace casa { //# NAMESPACE CASA - BEGIN
00040 
00041 template<class T> class MaskedLattice;
00042 template<class T> class ImageInterface;
00043 template<class T> class Lattice;
00044 template<class T> class LatticeIterator;
00045 template<class T> class Vector;
00046 
00047 class CoordinateSystem;
00048 class DirectionCoordinate;
00049 class Coordinate;
00050 class ObsInfo;
00051 class IPosition;
00052 class Unit;
00053 class ProgressMeter;
00054 
00055 // <summary>This regrids one image to match the coordinate system of another</summary>
00056 
00057 // <use visibility=export>
00058 
00059 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00060 // </reviewed>
00061 
00062 // <prerequisite>
00063 //   <li> <linkto class="ImageInterface">ImageInterface</linkto>
00064 //   <li> <linkto class="CoordinateSystem">CoordinateSystem</linkto>
00065 //   <li> <linkto class="Interpolate2D">Interpolate2D</linkto>
00066 //   <li> <linkto class="InterpolateArray1D">InterpolateArray1D</linkto>
00067 // </prerequisite>
00068 //
00069 // <etymology>
00070 //  Regrids, or resamples, images.  
00071 // </etymology>
00072 //
00073 // <synopsis>
00074 //  This class enables you to regrid one image to the coordinate
00075 //  system of another.    You can regrid any or all of the
00076 //  axes in the image.  A range of interpolation schemes are available.
00077 //
00078 //  It will cope with coordinate systems being in different orders
00079 //  (coordinate, world axes, pixel axes).  The basic approach is to
00080 //  make a mapping from the input to the output coordinate systems,
00081 //  but the output CoordinateSystem order is preserved in the output
00082 //  image.
00083 //
00084 //  Any DirectionCoordinate or LinearCoordinate holding exactly two axes
00085 //  is regridded in one pass with a 2-D interpolation scheme.
00086 //  All other axes are regridded in separate passes with a 1D interpolation 
00087 //  scheme.    This means that a LinearCoordinate holding say 3 axes
00088 //  where some of them are coupled will not be correctly regridded.
00089 //  StokesCoordinates cannot be  regridded.
00090 //
00091 //  Multiple passes are made through the data, and the output of 
00092 //  each pass is the input of the next pass.  The intermediate 
00093 //  images are stored as TempImages which may be in memory or 
00094 //  on disk, depending on their size.
00095 //
00096 //  It can also simply insert this image into that one via
00097 //  an integer shift.
00098 // </synopsis>
00099 //
00100 // <example>
00101 // 
00102 // <srcblock>
00103 // </srcblock>
00104 // </example>
00105 //
00106 // <motivation> 
00107 // A common image analysis need is to regrid images, e.g. to compare
00108 // images from different telescopes.
00109 // </motivation>
00110 //
00111 // <thrown>
00112 // <li> AipsError 
00113 // </thrown>
00114 //
00115 // <todo asof="1999/04/20">
00116 // </todo>
00117 
00118 template <class T> class ImageRegrid
00119 {
00120 public:
00121 
00122   // Default constructor
00123   ImageRegrid();
00124 
00125   // copy constructor (copy semantics)
00126   ImageRegrid(const ImageRegrid &other);
00127 
00128   // destructor
00129   ~ImageRegrid();
00130 
00131   // Assignment copy semantics)
00132   ImageRegrid<T>& operator=(const ImageRegrid& other);
00133 
00134   // Regrid inImage onto the grid specified by outImage.
00135   // If outImage has a writable mask, it will be updated in that 
00136   // output pixels at which the regridding failed will be masked bad (False)
00137   // and the pixel value set to zero. Otherwise the output mask is not changed.
00138   // Specify which pixel axes of outImage are to be
00139   // regridded.  The coordinate and axis order of outImage
00140   // is preserved, regardless of where the relevant coordinates
00141   // are in inImage.
00142   //
00143   // decimate only applies when replicate=False. it is
00144   // the coordinate grid computation decimation FACTOR
00145   // (e.g.  nCoordGrid ~ nIn / decimate). 0 means no decimation
00146   // (slowest and most accurate)
00147   void regrid(ImageInterface<T>& outImage, 
00148               typename Interpolate2D::Method method,
00149               const IPosition& whichOutPixelAxes,
00150               const ImageInterface<T>& inImage,
00151               Bool replicate=False, uInt decimate=0,
00152               Bool showProgress=False, Bool forceRegrid=False);
00153 
00154 // Get and set the 2-D coordinate grid.  After a call to function <src>regrid</src>
00155 // in which coupled 2D coordinate (presently only DirectionCoordinate) is
00156 // regridded, this coordinate grid will be available.  It can be reused
00157 // via the <src>set2DCoordinateGrid</src> function for another like plane
00158 // (e.g. if you choose to regrid planes of a cube separately).   When you provide
00159 // the coordinate grid, it will no longer (for that 2D coordinate only) be
00160 // computed internally, which may save a lot of time.  Ordinarily, if you
00161 // regridded many planes of a cube in one call to regrid, the coordinate grid
00162 // is cached for you.   To trigger successive calls to regrid to go back to
00163 // internal computation, set zero length Cube and Matrix.  <src>gridMask</src>
00164 // is True for successfull coordinate conversions, and False otherwise.
00165 // <group>
00166   void get2DCoordinateGrid (Cube<Double>& grid, Matrix<Bool>& gridMask) const;
00167   void set2DCoordinateGrid (const Cube<Double>& grid, const Matrix<Bool>& gridMask, Bool notify=False);
00168 // </group>
00169 //
00170   // Inserts inImage into outImage.  The alignment is done by
00171   // placing the blc of inImage at the specified 
00172   // absolute pixel of the outImage (outPixelLocation).  If 
00173   // the outPixelLocation vector is of zero length, then the images 
00174   // are aligned by their reference pixels.  Only integral shifts are done
00175   // in the aligment process. If outImage has a mask,  it will be updated.
00176   // Returns False if no overlap of images, in which case the
00177   // output is not updated.
00178   Bool insert(ImageInterface<T>& outImage,
00179               const Vector<Double>& outPixelLocation,
00180               const ImageInterface<T>& inImage);
00181 
00182   // Print out useful debugging information (level 0 is none,
00183   // 1 is some, 2 is too much)
00184   void showDebugInfo(Int level=0) {itsShowLevel = level;};
00185 
00186   // Enable/disable Measures Reference conversions
00187   void disableReferenceConversions(Bool disable=True) {itsDisableConversions = disable;};
00188 
00189   // Helper function.  We are regridding from cSysFrom to cSysTo for the
00190   // specified pixel axes of cSyFrom. This function returns a CoordinateSystem which,
00191   // for the pixel axes being regridded, copies the coordinates from cSysTo
00192   // (if coordinate type present in cSysTo) or cSysFrom (coordinate
00193   // type not present in cSysTo).
00194   // For the axes not being regridded, it copies the coordinates from
00195   // cSysFrom.  This helps you build the cSys for function regrid.
00196   // The ObsInfo from cSysFrom is copied to the output CoordinateSystem.
00197   // If inShape has one or more elements it represenents the size of the
00198   // image to be regridded. It this must have the same number of elements
00199   // as the number of pixel axes in <src>cSysFrom</src>. If any of the values
00200   // are unity (ie the axes are degenerate), and the corresponding axis in <src>csysFrom</src> is the only
00201   // axis in its corresponding coordinate, this coordinate will not be replaced
00202   // even if the axis is specified in <src>axes</src>.
00203   static CoordinateSystem makeCoordinateSystem(
00204                   LogIO& os,
00205                   const CoordinateSystem& cSysTo,
00206                   const CoordinateSystem& cSysFrom,
00207                   const IPosition& axes,
00208                   const IPosition& inShape=IPosition()
00209   );
00210 
00211  private:
00212 
00213   Int itsShowLevel;
00214   Bool itsDisableConversions;
00215 //
00216   Cube<Double> its2DCoordinateGrid;
00217   Matrix<Bool> its2DCoordinateGridMask;
00218 //
00219   Cube<Double> itsUser2DCoordinateGrid;
00220   Matrix<Bool> itsUser2DCoordinateGridMask;
00221   Bool itsNotify;
00222 //  
00223   // Check shape and axes.  Exception if no good.  If pixelAxes
00224   // of length 0, set to all axes according to shape
00225   void checkAxes(IPosition& outPixelAxes,
00226                  const IPosition& inShape,
00227                  const IPosition& outShape,
00228                  const Vector<Int>& pixelAxisMap,
00229                  const CoordinateSystem& outCoords);
00230 
00231   // Find maps between coordinate systems
00232   void findMaps (uInt nDim, 
00233                  Vector<Int>& pixelAxisMap1,
00234                  Vector<Int>& pixelAxisMap2,
00235                  const CoordinateSystem& inCoords,
00236                  const CoordinateSystem& outCoords) const;
00237 
00238   // Find scale factor to conserve flux 
00239    Double findScaleFactor(const Unit& units, 
00240                           const CoordinateSystem& inCoords, 
00241                           const CoordinateSystem& outCoords, 
00242                           Int inCoordinate, Int outCoordinate,
00243                           LogIO& os) const;
00244 
00245   // Regrid one Coordinate
00246    void regridOneCoordinate (LogIO& os, IPosition& outShape2,
00247                              Vector<Bool>& doneOutPixelAxes,
00248                              MaskedLattice<T>* &finalOutPtr,  
00249                              MaskedLattice<T>* &inPtr,   
00250                              MaskedLattice<T>* &outPtr,  
00251                              CoordinateSystem& outCoords,
00252                              const CoordinateSystem& inCoords,
00253                              Int outPixelAxis,
00254                              const ImageInterface<T>& inImage,
00255                              const IPosition& outShape,
00256                              Bool replicate, uInt decimate,
00257                              Bool outIsMasked, Bool showProgress,
00258                              Bool forceRegrid, 
00259                              typename Interpolate2D::Method method);
00260 
00261   // Regrid  DirectionCoordinate or 2-axis LinearCoordinate
00262    void regridTwoAxisCoordinate  (LogIO& os, MaskedLattice<T>& outLattice,
00263                          const MaskedLattice<T>& inLattice,
00264                          const Unit& imageUnit, 
00265                          const CoordinateSystem& inCoords,
00266                          const CoordinateSystem& outCoords,
00267                          Int inCoordinate, Int outCoordinate,
00268                          const Vector<Int> inPixelAxes,
00269                          const Vector<Int> outPixelAxes,
00270                          const Vector<Int> pixelAxisMap1,  
00271                          const Vector<Int> pixelAxisMap2,
00272                          typename Interpolate2D::Method method,
00273                          Bool replicate, uInt decimate,
00274                          Bool showProgress);
00275 
00276   // Make regridding coordinate grid for this cursor.
00277   void make2DCoordinateGrid (LogIO& os, Bool& allFail, Bool&missedIt,
00278                              Double& minInX, Double& minInY, 
00279                              Double& maxInX, Double& maxInY,
00280                              Cube<Double>& in2DPos,
00281                              Matrix<Bool>& succeed,
00282                              const CoordinateSystem& inCoords,
00283                              const CoordinateSystem& outCoords,
00284                              Int inCoordinate, Int outCoordinate,
00285                              uInt xInAxis, uInt yInAxis,
00286                              uInt xOutAxis, uInt yOutAxis,
00287                              const IPosition& inPixelAxes,
00288                              const IPosition& outPixelAxes,
00289                              const IPosition& inShape,
00290                              const IPosition& outPos,
00291                              const IPosition& cursorShape,
00292                              uInt decimate=0);
00293 
00294   // Make replication coordinate grid for this cursor
00295    void make2DCoordinateGrid (Cube<Double>& in2DPos,
00296                               Double& minInX, Double& minInY, 
00297                               Double& maxInX, Double& maxInY,
00298                               const Vector<Double>& pixelScale, 
00299                               uInt xInAxis, uInt yInAxis,
00300                               uInt xOutAxis, uInt yOutAxis,
00301                               uInt xInCorrAxis, uInt yInCorrAxis,
00302                               uInt xOutCorrAxis, uInt yOutCorrAxis,
00303                               const IPosition& outPos, const IPosition& cursorShape);
00304 
00305   // Make regridding coordinate grid for this axis
00306    void make1DCoordinateGrid (Block<Float>& xOut,
00307                               Vector<Bool>& failed,
00308                               Bool& allFailed,
00309                               Bool& allGood,
00310                               const Coordinate& inCoord,
00311                               const Coordinate& outCoord,
00312                               Int inAxisInCoordinate,
00313                               Int outAxisInCoordinate,
00314                               MFrequency::Convert& machine,
00315                               Bool useMachine);
00316 
00317 
00318   // Make replication coordinate grid for this axis
00319    void make1DCoordinateGrid (Block<Float>& xOut, Float pixelScale) const;
00320 
00321   // Regrid 1 axis
00322   void regrid1D (MaskedLattice<T>& outLattice,
00323                  const MaskedLattice<T>& inLattice,
00324                  const Coordinate& inCoord,
00325                  const Coordinate& outCoord,
00326                  const Vector<Int>& inPixelAxes,
00327                  const Vector<Int>& outPixelAxes,
00328                  Int inAxisInCoordinate,
00329                  Int outAxisInCoordinate,
00330                  const Vector<Int> pixelAxisMap,
00331                  typename Interpolate2D::Method method,
00332                  MFrequency::Convert& machine,
00333                  Bool replicate,
00334                  Bool useMachine, Bool showProgress);
00335 
00336 //
00337    void regrid2DMatrix(Lattice<T>& outCursor,
00338                        LatticeIterator<Bool>*& outMaskIterPtr,
00339                        const Interpolate2D& interp,  
00340                                     ProgressMeter*& pProgress,
00341                                     Double& iPix,
00342                                     uInt nDim,
00343                                     uInt xInAxis, uInt yInAxis,
00344                                     uInt xOutAxis, uInt yOutAxis,
00345                                     Double scale,
00346                                     Bool inIsMasked, Bool outIsMasked,
00347                                     const IPosition& outPos,
00348                                     const IPosition& outCursorShape,
00349                                     const IPosition& inChunkShape,
00350                                     const IPosition& inChunkBlc,
00351                                     const IPosition& pixelAxisMap2,
00352                                     Array<T>& inDataChunk,
00353                                     Array<Bool>*& inMaskChunkPtr,
00354                                     const Cube<Double>& pix2DPos,
00355                                     const Matrix<Bool>& succeed);
00356 
00357    void findXYExtent (Bool& missedIt, Bool& allFailed,
00358                       Double& minInX, Double& minInY,
00359                       Double& maxInX, Double& maxInY,
00360                       Cube<Double>& in2DPos,
00361                       Matrix<Bool>& succeed,
00362                       uInt xInAxis, uInt yInAxis,
00363                       uInt xOutAxis, uInt yOutAxis,
00364                       const IPosition& outPos,
00365                       const IPosition& outCursorShape,
00366                       const IPosition& inShape);
00367 //
00368    Bool minmax(Double &minX, Double &maxX, Double& minY, Double& maxY,
00369                const Array<Double> &xData,
00370                const Array<Double> &yData,
00371                const Array<Bool>& mask);
00372 };
00373 
00374  
00375 
00376 } //# NAMESPACE CASA - END
00377 
00378 #ifndef CASACORE_NO_AUTO_TEMPLATES
00379 #include <images/Images/ImageRegrid.tcc>
00380 #endif //# CASACORE_NO_AUTO_TEMPLATES
00381 #endif
00382