casa
$Rev:20696$
|
00001 //# TabularCoordinate.h: Table lookup 1-D coordinate, with interpolation 00002 //# Copyright (C) 1997,1998,1999,2000,2001,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: TabularCoordinate.h 18823 2005-07-07 20:36:33Z ddebonis $ 00028 00029 00030 #ifndef COORDINATES_TABULARCOORDINATE_H 00031 #define COORDINATES_TABULARCOORDINATE_H 00032 00033 #include <casa/aips.h> 00034 #include <casa/Arrays/ArrayMath.h> 00035 #include <casa/Arrays/Vector.h> 00036 #include <coordinates/Coordinates/Coordinate.h> 00037 00038 namespace casa { //# NAMESPACE CASA - BEGIN 00039 00040 template<class Domain, class Range> class Interpolate1D; 00041 template<class T> class Quantum; 00042 class LogIO; 00043 00044 00045 00046 // <summary> 00047 // Table lookup 1-D coordinate, with interpolation. 00048 // </summary> 00049 00050 // <use visibility=export> 00051 00052 // <reviewed reviewer="Peter Barnes" date="1999/12/24" tests="tTabularCoordinate"> 00053 // </reviewed> 00054 00055 // <prerequisite> 00056 // <li> <linkto class=Coordinate>Coordinate</linkto> 00057 // </prerequisite> 00058 // 00059 // <synopsis> 00060 // This class is used where the world and pixel values are determined by a 00061 // lookup table. For fractional pixel values, a linear interpolation is used. 00062 // The values returned for, e.g., the increment, are based on 00063 // the average of the whole table. At present, 00064 // the values must either increase or decrease monotonically. 00065 // </synopsis> 00066 // 00067 // <note role=caution> 00068 // All pixels coordinates are zero relative. 00069 // </note> 00070 // 00071 // <example> 00072 // Let's make a non-linear TabularCoordinate and convert a pixel 00073 // value to world (which will use linear interpolation) 00074 // <srcblock> 00075 // Vector<Double> pixelValues(3); 00076 // Vector<Double> worldValues(3); 00077 // pixelValues(0) = 122.0; 00078 // pixelValues(1) = 300.0; 00079 // pixelValues(2) = 6524.0; 00080 // worldValues(0) = 1.1e6; 00081 // worldValues(1) = 2.1e6; 00082 // worldValues(2) = 2.2e6; 00083 // 00084 // String unit("km"); 00085 // String axisName("length"); 00086 // 00087 // TabularCoordinate tc(pixelValues, worldValues, unit, axisName); 00088 // 00089 // Double world, pixel; 00090 // pixel = 200.12; 00091 // if (!tc.toWorld(world, pixel)) { 00092 // cerr << "Error : " << tc.errorMessage() << endl; 00093 // } else { 00094 // cerr << "pixel, world = " << pixel << ", " << world << endl; 00095 // } 00096 // </srcblock> 00097 // </example> 00098 // 00099 // <motivation> 00100 // This class was motivated by the need for an irregular axis, such as a collection 00101 // of frequencies. For example, the SpectralCoordinate class contains a TabularCoordinate. 00102 // </motivation> 00103 // 00104 // 00105 // <thrown> 00106 // <li> AipsError 00107 // </thrown> 00108 // 00109 // <todo asof="1997/07/12"> 00110 // <li> Allow interpolations other than linear. 00111 // </todo> 00112 00113 00114 class TabularCoordinate : public Coordinate 00115 { 00116 public: 00117 // Default constructor. It is equivalent to 00118 // TabularCoordinate(0,1,0, "", "Tabular"); 00119 TabularCoordinate(); 00120 00121 // Create a linear TabularCoordinate where 00122 // <src>world = refval + inc*(pixel-refpix)</src> 00123 TabularCoordinate(Double refval, Double inc, Double refpix, 00124 const String &unit, const String &axisName); 00125 00126 // Create a linear TabularCoordinate with a Quantum-based interface where 00127 // <src>world = refval + inc*(pixel-refpix)</src>. The units of the 00128 // increment (<src>inc</src>) will be converted to 00129 // those of the reference value (<src>refVal</src>) which will 00130 // then serve as the units of the Coordinate. 00131 TabularCoordinate(const Quantum<Double>& refval, 00132 const Quantum<Double>& inc, 00133 Double refpix, const String& axisName); 00134 00135 // Construct a TabularCoordinate with the specified world values. The 00136 // increments and related functions return the average values 00137 // calculated from the first and last world values. The number of pixel 00138 // and world values must be the same. Normally the pixel values will be 00139 // 0,1,2,..., but this is not required. 00140 // 00141 // A linear interpolation/extrapolation is used for channels which are not 00142 // supplied. The reference channel (pixel) is chosen to be 0. The 00143 // frequencies must increase or decrease monotonically (otherwise the 00144 // toPixel lookup would not be possible). 00145 TabularCoordinate(const Vector<Double> &pixelValues, 00146 const Vector<Double> &worldValues, 00147 const String &unit, const String &axisName); 00148 00149 // Construct a TabularCoordinate with the specified world values 00150 // via the Quantum-based interface. All comments for the 00151 // previous constructor apply 00152 TabularCoordinate(const Vector<Double>& pixelValues, 00153 const Quantum<Vector<Double> >& worldValues, 00154 const String &axisName); 00155 00156 // Copy constructor (copy semantics). 00157 TabularCoordinate(const TabularCoordinate &other); 00158 00159 // Assignment (copy semantics). 00160 TabularCoordinate &operator=(const TabularCoordinate &other); 00161 00162 // Destructor. 00163 virtual ~TabularCoordinate(); 00164 00165 // Returns Coordinate::TABULAR. 00166 virtual Coordinate::Type type() const; 00167 00168 // Always returns the String "Tabular". 00169 virtual String showType() const; 00170 00171 // Always returns 1. 00172 // <group> 00173 virtual uInt nPixelAxes() const; 00174 virtual uInt nWorldAxes() const; 00175 // </group> 00176 00177 // Convert a pixel position to a world position or vice versa. Returns True 00178 // if the conversion succeeds, otherwise it returns False and method 00179 // errorMessage contains an error message. The output 00180 // vectors are appropriately resized. 00181 // <group> 00182 virtual Bool toWorld(Vector<Double> &world, 00183 const Vector<Double> &pixel) const; 00184 virtual Bool toPixel(Vector<Double> &pixel, 00185 const Vector<Double> &world) const; 00186 Bool toWorld(Double &world, Double pixel) const; 00187 Bool toPixel(Double &pixel, Double world) const; 00188 // </group> 00189 00190 // Batch up a lot of transformations. The first (most rapidly varying) axis 00191 // of the matrices contain the coordinates. Returns False if any conversion 00192 // failed and <src>errorMessage()</src> will hold a message. 00193 // The <src>failures</src> array (True for fail, False for success) 00194 // is the length of the number of conversions and 00195 // holds an error status for each conversion. 00196 // <group> 00197 virtual Bool toWorldMany(Matrix<Double> &world, 00198 const Matrix<Double> &pixel, 00199 Vector<Bool>& failures) const; 00200 virtual Bool toPixelMany(Matrix<Double>& pixel, 00201 const Matrix<Double>& world, 00202 Vector<Bool>& failures) const; 00203 // </group> 00204 00205 00206 // Make absolute coordinates relative and vice-versa (with 00207 // respect to the referencfe value). 00208 // Vectors must be length <src>nPixelAxes()</src> or 00209 // <src>nWorldAxes()</src> or memory access errors will occur 00210 // <group> 00211 virtual void makePixelRelative (Vector<Double>& pixel) const {pixel -= crpix_p;}; 00212 virtual void makePixelAbsolute (Vector<Double>& pixel) const {pixel += crpix_p;}; 00213 virtual void makeWorldRelative (Vector<Double>& world) const {world -= crval_p;}; 00214 virtual void makeWorldAbsolute (Vector<Double>& world) const {world += crval_p;}; 00215 // </group> 00216 00217 // Return the requested attribute. 00218 // <group> 00219 virtual Vector<String> worldAxisNames() const; 00220 virtual Vector<Double> referencePixel() const; 00221 virtual Matrix<Double> linearTransform() const; 00222 virtual Vector<Double> increment() const; 00223 virtual Vector<Double> referenceValue() const; 00224 // </group> 00225 00226 // Set the value of the requested attribute. Note that these just 00227 // change the internal values, they do not cause any recomputation. 00228 // <group> 00229 virtual Bool setWorldAxisNames(const Vector<String> &names); 00230 virtual Bool setReferencePixel(const Vector<Double> &refPix); 00231 virtual Bool setLinearTransform(const Matrix<Double> &xform); 00232 virtual Bool setIncrement(const Vector<Double> &inc) ; 00233 virtual Bool setReferenceValue(const Vector<Double> &refval); 00234 // </group> 00235 00236 // Set/get the axis unit. Adjust the increment and 00237 // reference value by the ratio of the old and new units. 00238 // The unit must be compatible with the current units. 00239 // <group> 00240 virtual Bool setWorldAxisUnits(const Vector<String> &units); 00241 virtual Vector<String> worldAxisUnits() const; 00242 // </group> 00243 00244 // Overwrite the world axis units with no compatibility 00245 // checks or adjustment. 00246 Bool overwriteWorldAxisUnits(const Vector<String> &units); 00247 00248 // Get the table, i.e. the pixel and world values. The length of these 00249 // Vectors will be zero if this axis is pure linear. 00250 // <group> 00251 Vector<Double> pixelValues() const; 00252 Vector<Double> worldValues() const; 00253 // </group> 00254 00255 // Comparison function. Any private Double data members are compared 00256 // with the specified fractional tolerance. Don't compare on the specified 00257 // axes in the Coordinate. If the comparison returns False, method 00258 // errorMessage() contains a message about why. 00259 // <group> 00260 virtual Bool near(const Coordinate& other, 00261 Double tol=1e-6) const; 00262 virtual Bool near(const Coordinate& other, 00263 const Vector<Int>& excludeAxes, 00264 Double tol=1e-6) const; 00265 // </group> 00266 00267 // Find the Coordinate for when we Fourier Transform ourselves. This pointer 00268 // must be deleted by the caller. Axes specifies which axes of the Coordinate 00269 // you wish to transform. Shape specifies the shape of the image 00270 // associated with all the axes of the Coordinate. Currently the 00271 // output reference pixel is always shape/2. If the pointer returned is 0, 00272 // it failed with a message in <src>errorMessage</src> 00273 virtual Coordinate* makeFourierCoordinate (const Vector<Bool>& axes, 00274 const Vector<Int>& shape) const; 00275 00276 // Save the TabularCoordinate into the supplied record using the supplied field name. 00277 // The field must not exist, otherwise <src>False</src> is returned. 00278 virtual Bool save(RecordInterface &container, const String &fieldName) const; 00279 00280 // Recover the TabularCoordinate from a record. 00281 // A null pointer means that the restoration did not succeed - probably 00282 // because fieldName doesn't exist or doesn't contain a CoordinateSystem. 00283 static TabularCoordinate *restore(const RecordInterface &container, 00284 const String &fieldName); 00285 00286 // Make a copy of the TabularCoordinate using new. The caller is responsible for calling 00287 // delete. 00288 virtual Coordinate *clone() const; 00289 00290 private: 00291 Double crval_p, cdelt_p, crpix_p; 00292 Double matrix_p; 00293 String unit_p; 00294 String name_p; 00295 00296 // Channel_True = channel_corrections_p(Channel_average). 00297 // <group> 00298 Interpolate1D<Double,Double> *channel_corrector_p; 00299 Interpolate1D<Double,Double> *channel_corrector_rev_p; 00300 // </group> 00301 00302 // Common for assignment operator and destructor. 00303 void clear_self(); 00304 00305 // Common code for copy ctor and assignment operator. 00306 void copy(const TabularCoordinate &other); 00307 00308 void makeNonLinearTabularCoordinate(const Vector<Double> &pixelValues, 00309 const Vector<Double> &worldValues); 00310 }; 00311 00312 } //# NAMESPACE CASA - END 00313 00314 00315 #endif