casa
$Rev:20696$
|
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