casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
LinearXform.h
Go to the documentation of this file.
00001 //# LinearXform.h: Perform a linear transform between input and output vectors
00002 //# Copyright (C) 1997-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: LinearXform.h 18823 2005-07-07 20:36:33Z ddebonis $
00028 
00029 #ifndef COORDINATES_LINEARXFORM_H
00030 #define COORDINATES_LINEARXFORM_H
00031 
00032 #include <casa/aips.h>
00033 #include <wcslib/lin.h>
00034 
00035 namespace casa { //# NAMESPACE CASA - BEGIN
00036 
00037 template<class T> class Vector;
00038 template<class T> class Matrix;
00039 class String;
00040 
00041 // <summary>
00042 // Perform a linear transform between input and output vectors
00043 // </summary>
00044 
00045 // <use visibility=local>
00046 
00047 // <reviewed reviewer="Peter Barnes" date="1999/12/24" tests="tLinearXform">
00048 // </reviewed>
00049 
00050 // <prerequisite>
00051 //   <li> General knowledge of AIPS++ Arrays
00052 //   <li> Knowledge of FITS terminology in coordinate transformations
00053 // </prerequisite>
00054 //
00055 // <synopsis>
00056 // This class represents the common linear part of a FITS coordinate
00057 // transformation. In particular it does the following:
00058 // <srcblock>
00059 // world = cdelt * PC * (pixel - crpix)
00060 // </srcblock>
00061 // Where PC is an NxN matrix; pixel, crpix (reference pixel) and world are
00062 // length N vectors; and cdelt (increment) is an NxN diagonal matrix,
00063 // represented as a length N vector.
00064 //
00065 // Normally this class isn't used directly, rather it is used indirectly through
00066 // a class like <linkto class=LinearCoordinate>LinearCoordinate</linkto>.
00067 //
00068 // The actual computations are performed by WCSLIB, written by Mark Calabretta
00069 // of the ATNF.
00070 // </synopsis>
00071 //
00072 // <example>
00073 //   Let's make a LinearXform housing two axes with a unit
00074 //   diagonal PC matrix and convert from pixel to world
00075 //
00076 // <srcblock>
00077 //    Vector<Double> crpix(2), cdelt(2);
00078 //    crpix(0) = 10.0; crpix(1) = 20.0;
00079 //    cdelt(0) = 1.0; cdelt(1) = -1.0;
00080 //    LinearXform lxf(crpix, cdelt);
00081 //
00082 //    String errMsg;
00083 //    Vector<Double> world, pixel(2);
00084 //    pixel = 10.0;
00085 //    Bool ok = lxf.reverse(world, pixel, errMsg);
00086 //    if (ok) {
00087 //       cerr << "pixel, world = " << pixel << world << endl;
00088 //    } else {
00089 //       cerr << "Error : " << errMsg << endl;
00090 //    }
00091 // </srcblock>
00092 // The answer should be a world vector with values 0 and -10.
00093 // </example>
00094 //
00095 // <motivation>
00096 // Factor out the common linear part of coordinate transformations.
00097 // </motivation>
00098 //
00099 // <thrown>
00100 //   <li>  AipsError
00101 // </thrown>
00102 //
00103 // <todo asof="1997/01/13">
00104 //   <li> Allow different numbers of pixel and world axes.
00105 // </todo>
00106 //
00107 
00108 
00109 class LinearXform
00110 {
00111 public:
00112     // Construct with specified number of axes.  The reference pixel is
00113     // assumed to be 0, and the increment is assumed to be unity, and the
00114     // PC matrix is assumed to be diagonal.
00115     LinearXform(uInt naxis=1);
00116 
00117     // Construct the linear transformation from the supplied reference pixel
00118     // and increment. The PC matrix is the unit matrix.
00119     // <src>crpix</src> and <src>cdelt</src> must have the same number
00120     // of elements.
00121     LinearXform(const Vector<Double> &crpix, const Vector<Double> &cdelt);
00122 
00123     // Construct a linear transformation, supplying all of the reference pixel,
00124     // increment and PC matrix.
00125     // The vectors must be of the same length ("n") and the number of rows and
00126     // columns in the matrix must also be n.
00127     LinearXform(const Vector<Double> &crpix, const Vector<Double> &cdelt,
00128                 const Matrix<Double> &pc);
00129 
00130     // Copy constructor (copy sematics)
00131     LinearXform(const LinearXform &other);
00132 
00133     // Assignment (copy sematics)
00134     LinearXform &operator=(const LinearXform &other);
00135 
00136     // Destructor
00137     ~LinearXform();
00138 
00139     // Returns the number of world axes, which for this class is also the
00140     // number of pixel axes.
00141     uInt nWorldAxes() const;
00142 
00143     // Convert world coordinates to pixel coordinates (forward), or pixel
00144     // coordinates to world (reverse). If the conversion works True is returned,
00145     // otherwise False is returned and errorMsg is set.  The output vectors
00146     // are resized appropriately.
00147     // <group>
00148     Bool forward(Vector<Double> &pixel, const Vector<Double> &world,
00149                         String &errorMsg) const;
00150     Bool reverse(Vector<Double> &world, const Vector<Double> &pixel,
00151                         String &errorMsg) const;
00152     // </group>
00153 
00154     // Retrieve the value of crpix, cdelt, and pc.
00155     // <group>
00156     Vector<Double> crpix() const;
00157     Vector<Double> cdelt() const;
00158     Matrix<Double> pc() const;
00159     // </group>
00160 
00161     // Set the value of crpix, cdelt, and pc. Note that since you can only
00162     // set one of them, you cannot change the dimensionality of the transform
00163     // using these functions. Instead use assignment on a temporary, i.e.:
00164     // <src> linxform = LinearXform (crpix,crval,pc); </src>
00165     // <group>
00166     void crpix(const Vector<Double> &newvals);
00167     void cdelt(const Vector<Double> &newvals);
00168     void pc(const Matrix<Double> &newvals);
00169     // </group>
00170 
00171     // Invert the LinearXform ready for use in a Fourier Transformed Coordinate.
00172     // It is the callers responsibility to delete the pointer. If it fails
00173     // the pointer is 0 and an error message is provided
00174     LinearXform* fourierInvert (String& errMsg, const Vector<Bool>& axes,
00175                                const Vector<Double>& crpix,
00176                                const Vector<Double>& scale) const;
00177 
00178     // Comparison function. Any private Double data members are compared
00179     // with the specified fractional tolerance.  You can specify axes to
00180     // exclude from the comparison if you wish.
00181     // <group>
00182     Bool near(const LinearXform& other,
00183               Double tol=1e-6) const;
00184     Bool near(const LinearXform& other,
00185               const Vector<Int>& excludeAxes,
00186               Double tol=1e-6) const;
00187     // </group>
00188 
00189 private:
00190     // A WCSLIB C-structure.
00191     mutable linprm linprm_p;
00192 
00193     Bool isPCDiagonal_p;
00194     void set_linprm();
00195 };
00196 
00197 } //# NAMESPACE CASA - END
00198 
00199 #endif