casa
$Rev:20696$
|
00001 //# LinearCoordinate.h: Assume a general linear relation between pixel and world axes. 00002 //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2004 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: LinearCoordinate.h 18823 2005-07-07 20:36:33Z ddebonis $ 00028 00029 00030 #ifndef COORDINATES_LINEARCOORDINATE_H 00031 #define COORDINATES_LINEARCOORDINATE_H 00032 00033 #include <casa/aips.h> 00034 #include <coordinates/Coordinates/Coordinate.h> 00035 #include <casa/Arrays/Vector.h> 00036 #include <wcslib/wcs.h> 00037 00038 namespace casa { //# NAMESPACE CASA - BEGIN 00039 00040 template<class T> class Quantum; 00041 00042 00043 // <summary> 00044 // Interconvert between pixel and a linear world coordinate. 00045 // </summary> 00046 00047 // <use visibility=export> 00048 00049 // <reviewed reviewer="Peter Barnes" date="1999/12/24" tests="tLinearCoordinate"> 00050 // </reviewed> 00051 00052 // <prerequisite> 00053 // <li> <linkto class=Coordinate>Coordinate</linkto> defines the fundamental 00054 // interface to coordinate conversions. 00055 // </prerequisite> 00056 // 00057 // <synopsis> 00058 // The LinearCoordinate class ties pixel and world axes together through 00059 // a general linear transformation. 00060 // 00061 // <srcblock> 00062 // world = (cdelt * PC * (pixel - crpix)) + crval 00063 // </srcblock> 00064 // Where PC is an NxN matrix; pixel, crval, crpix and world are length N 00065 // vectors, and cdelt is an NxN diagonal matrix, represented as a length 00066 // N vector. 00067 // 00068 // The LinearCoordinate can contain several uncoupled axes (similar to the way 00069 // in which the DirectionCoordinate contains two axes). 00070 // </synopsis> 00071 // 00072 // <note role=caution> 00073 // All pixels coordinates are zero relative. 00074 // </note> 00075 // 00076 // <example> 00077 // Let's make a LinearCoordinate with just one axis containing 00078 // a coordinate describing length. 00079 // <srcblock> 00080 // Vector<Double> crpix(1); crpix = 0.0; 00081 // Vector<Double> crval(1); crval = 100.0; 00082 // Vector<Double> cdelt(1); cdelt = -10.0; 00083 // Matrix<Double> pc(1,1); pc= 0; pc.diagonal() = 1.0; 00084 // Vector<String> name(1); name = "length"; 00085 // Vector<String> units(1); units = "km"; 00086 // 00087 // LinearCoordinate lin(names, units, crval, cdelt, pc, crpix); 00088 // </srcblock> 00089 // 00090 // Now do a coordinate conversion 00091 // 00092 // <srcblock> 00093 // Vector<Double> world, pixel(1); 00094 // pixel = 2.0; 00095 // if (!lin.toWorld(world, pixel)) { 00096 // cerr << "Error : " << lin.errorMessage() << endl; 00097 // } else { 00098 // cerr << "pixel, world = " << pixel << world << endl; 00099 // } 00100 // </srcblock> 00101 // The answer should of course be -20km. 00102 // </example> 00103 // 00104 // <motivation> 00105 // This class is intended for use with axes which do not have specific coordinate 00106 // types. A "time" axis would be a good example. 00107 // </motivation> 00108 // 00109 // <thrown> 00110 // <li> AipsError 00111 // </thrown> 00112 // 00113 // <todo asof="2000/01/01"> 00114 // <li> Allow differing numbers of world and pixel axes. Requires a change in 00115 // WCS or use of a different library. 00116 // </todo> 00117 // 00118 00119 00120 class LinearCoordinate : public Coordinate 00121 { 00122 public: 00123 // The default constructor makes a LinearCoordinate for which pixel 00124 // and world coordinates are equal. <src>naxes</src> gives the number 00125 // of axes in the Coordinate. 00126 LinearCoordinate(uInt naxes = 1); 00127 00128 // Construct the LinearCoordinate 00129 LinearCoordinate(const Vector<String> &names, 00130 const Vector<String> &units, 00131 const Vector<Double> &refVal, 00132 const Vector<Double> &inc, 00133 const Matrix<Double> &pc, 00134 const Vector<Double> &refPix); 00135 00136 // Construct LinearCoordinate with Quantum-based interface. 00137 // The units of the increment (<src>inc</src>) will be converted to 00138 // those of the reference value (<src>refVal</src>) which will 00139 // then serve as the units of the Coordinate. 00140 LinearCoordinate(const Vector<String> &names, 00141 const Vector<Quantum<Double> >& refVal, 00142 const Vector<Quantum<Double> >& inc, 00143 const Matrix<Double> &pc, 00144 const Vector<Double> &refPix); 00145 00146 // Constructor from WCS structure; must hold ONLY a linear wcs structure 00147 // Specify whether the absolute pixel coordinates in the wcs structure 00148 // are 0- or 1-relative. The coordinate is always constructed with 0-relative 00149 // pixel coordinates 00150 LinearCoordinate(const wcsprm& wcs, Bool oneRel=True); 00151 00152 // Copy constructor (copy semantics). 00153 LinearCoordinate(const LinearCoordinate &other); 00154 00155 // Assignment (copy semantics). 00156 LinearCoordinate &operator=(const LinearCoordinate &other); 00157 00158 // Destructor. 00159 virtual ~LinearCoordinate(); 00160 00161 // Returns Coordinate::LINEAR. 00162 virtual Coordinate::Type type() const; 00163 00164 // Returns the String "Linear". 00165 virtual String showType() const; 00166 00167 // Returns the number of pixel/world axes. The number of axes is arbitrary, 00168 // however the number of world and pixel axes must at present be the same. 00169 // <group> 00170 virtual uInt nPixelAxes() const; 00171 virtual uInt nWorldAxes() const; 00172 // </group> 00173 00174 // Convert a pixel position to a worl position or vice versa. Returns True 00175 // if the conversion succeeds, otherwise it returns False and method 00176 // errorMessage returns an error message. The output 00177 // vectors are appropriately resized. 00178 // <group> 00179 virtual Bool toWorld(Vector<Double> &world, 00180 const Vector<Double> &pixel) const; 00181 virtual Bool toPixel(Vector<Double> &pixel, 00182 const Vector<Double> &world) const; 00183 // </group> 00184 00185 00186 // Return the requested attribute 00187 // <group> 00188 virtual Vector<String> worldAxisNames() const; 00189 virtual Vector<Double> referenceValue() const; 00190 virtual Vector<Double> increment() const; 00191 virtual Matrix<Double> linearTransform() const; 00192 virtual Vector<Double> referencePixel() const; 00193 virtual Vector<String> worldAxisUnits() const; 00194 // </group> 00195 00196 // Set the value of the requested attributed. Note that these just 00197 // change the internal values, they do not cause any recomputation. 00198 // <group> 00199 virtual Bool setWorldAxisNames(const Vector<String> &names); 00200 virtual Bool setReferencePixel(const Vector<Double> &refPix); 00201 virtual Bool setLinearTransform(const Matrix<Double> &pc); 00202 virtual Bool setIncrement(const Vector<Double> &inc); 00203 virtual Bool setReferenceValue(const Vector<Double> &refval); 00204 // </group> 00205 00206 // Set the world axis units. Adjust the increment and 00207 // reference value by the ratio of the old and new units. 00208 // The units must be compatible with the current units. 00209 virtual Bool setWorldAxisUnits(const Vector<String> &units); 00210 00211 // Overwrite the world axis units with no compatibility 00212 // checks or adjustment. 00213 Bool overwriteWorldAxisUnits(const Vector<String> &units); 00214 00215 // Comparison function. Any private Double data members are compared 00216 // with the specified fractional tolerance. Don't 00217 // compare on the specified 00218 // axes in the Coordinate. If the comparison returns False, method 00219 // errorMessage contains a message about why. 00220 // <group> 00221 virtual Bool near(const Coordinate& other, 00222 Double tol=1e-6) const; 00223 virtual Bool near(const Coordinate& other, 00224 const Vector<Int>& excludeAxes, 00225 Double tol=1e-6) const; 00226 // </group> 00227 00228 // Find the Coordinate for when we Fourier Transform ourselves. This pointer 00229 // must be deleted by the caller. Axes specifies which axes of the Coordinate 00230 // you wish to transform. Shape specifies the shape of the image 00231 // associated with all the axes of the Coordinate. Currently the 00232 // output reference pixel is always shape/2. If the pointer returned is 0, 00233 // it failed with a message in <src>errorMessage</src> 00234 virtual Coordinate* makeFourierCoordinate (const Vector<Bool>& axes, 00235 const Vector<Int>& shape) const; 00236 00237 // Save the LinearCoordinate into the supplied record using the supplied field name. 00238 // The field must not already exist, otherwise <src>False</src> is returned. 00239 virtual Bool save(RecordInterface &container, const String &fieldName) const; 00240 00241 // Restore the LinearCoordinate from a record. 00242 // A null pointer means that the restoration did not succeed - probably 00243 // because fieldName doesn't exist or doesn't contain a CoordinateSystem. 00244 static LinearCoordinate *restore(const RecordInterface &container, 00245 const String &fieldName); 00246 00247 // Make a copy of the LinearCoordinate using new. The caller is responsible for calling 00248 // delete. 00249 virtual Coordinate *clone() const; 00250 00251 private: 00252 00253 // An interface to the WCSLIB linear transformation routines. 00254 mutable ::wcsprm wcs_p; 00255 00256 // Copy private data 00257 void copy (const LinearCoordinate& other); 00258 00259 // Make wcs structure 00260 void makeWCS (wcsprm& wcs, uInt naxis, const Vector<Double>& refPix, 00261 const Vector<Double>& refVal, 00262 const Vector<Double>& incr, 00263 const Matrix<Double>& pc, 00264 const Vector<String>& units, 00265 const Vector<String>& names); 00266 }; 00267 00268 } //# NAMESPACE CASA - END 00269 00270 00271 #endif 00272