casa
$Rev:20696$
|
00001 //# Coordinates.h : Classes to interconvert computation positions with physical 00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001 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 //# $Id: Coordinates.h 20691 2009-07-14 03:13:54Z Malte.Marquarding $ 00027 00028 #ifndef COORDINATES_COORDINATES_H 00029 #define COORDINATES_COORDINATES_H 00030 00031 //# Module includes 00032 #include <coordinates/Coordinates/Coordinate.h> 00033 #include <coordinates/Coordinates/CoordinateSystem.h> 00034 #include <coordinates/Coordinates/DirectionCoordinate.h> 00035 #include <coordinates/Coordinates/LinearCoordinate.h> 00036 #include <coordinates/Coordinates/LinearXform.h> 00037 #include <coordinates/Coordinates/Projection.h> 00038 #include <coordinates/Coordinates/SpectralCoordinate.h> 00039 #include <coordinates/Coordinates/StokesCoordinate.h> 00040 #include <coordinates/Coordinates/TabularCoordinate.h> 00041 #include <coordinates/Coordinates/CoordinateUtil.h> 00042 00043 namespace casa { //# NAMESPACE CASA - BEGIN 00044 00045 // <module> 00046 // 00047 // <summary> 00048 // Classes to interconvert pixel and world (physical) coordinates 00049 // </summary> 00050 00051 // <prerequisite> 00052 // <li> Knowledge of astronomical coordinate conversions in general. Probably the 00053 // best documents are the papers by Mark Calabretta and Eric Greisen. 00054 // The initial draft from 1996 can be found at 00055 // http://www.atnf.csiro.au/~mcalabre. It is this draft that the 00056 // Coordinate classes are based upon. Since then, this paper has evolved 00057 // into three which can be found at the above address, and will be published in the 00058 // Astronomy and Astrophysics Supplement Series (probably in 2000). 00059 // The design has changed since the initial draft. When these papers 00060 // are finalized, and the IAU has ratified the new standards, WCSLIB 00061 // (Mark Calabretta's implementation of these conventions) will be 00062 // revised for the new designs. At that time, the Coordinate classes 00063 // may also be revised. 00064 // <li> Generic AIPS++ classes; especially those in the 00065 // <linkto module=Arrays>Arrays</linkto> module. 00066 // <li> The <linkto module=Measures>Measures</linkto> module. 00067 // </prerequisite> 00068 // 00069 00070 // <reviewed reviewer="Peter Barnes" date="1999/12/24"> 00071 // </reviewed> 00072 00073 // <synopsis> 00074 // The primary notion is that a <linkto class=Coordinate>Coordinate</linkto> 00075 // can interconvert between a length "n" Vector<Double> (the 00076 // pixel coordinate) and a length "m" Vector<Double> (the 00077 // "world" coordinate). Note that "m" and "n" do not in 00078 // principle have to be the same (so that one can get both the RA and DEC from 00079 // an image slice, for example), however in practice they currently always are. 00080 // Each Coordinate has the full mapping from pixel to world coordinates, i.e. 00081 // it has a reference value, reference pixel, increments, and an arbitrary 00082 // transformation matrix. To go from a pixel to a world coordinate the following 00083 // steps are applied: 00084 // <ol> 00085 // <li> The reference pixel is subtracted from the pixel position. 00086 // <li> The result is multiplied by the transformation matrix. 00087 // <li> The result is multiplied by an increment per output axis to convert 00088 // it into physical coordinates. 00089 // <li> For some coordinate types (e.g., Direction), a non-linear function is 00090 // applied to this result. 00091 // </ol> 00092 // 00093 // The classes are arranged as follows. The base class is 00094 // <linkto class=Coordinate>Coordinate</linkto> which defines the 00095 // interface. Classes derived from it are 00096 // <ol> 00097 // <li> <linkto class=DirectionCoordinate>DirectionCoordinate</linkto> 00098 // <li> <linkto class=LinearCoordinate>LinearCoordinate</linkto> 00099 // <li> <linkto class=SpectralCoordinate>SpectralCoordinate</linkto> 00100 // <li> <linkto class=TabularCoordinate>TabularCoordinate</linkto> 00101 // <li> <linkto class=StokesCoordinate>StokesCoordinate</linkto> 00102 // <li> <linkto class=CoordinateSystem>CoordinateSystem</linkto> 00103 // </ol> 00104 // 00105 // Other classes are <linkto class=Projection>Projection</linkto> 00106 // which is used to specify an astronomical projection for 00107 // DirectionCoordinates, and <linkto class=LinearXform>LinearXform</linkto> 00108 // a helper class which the application programmer will not interact with. 00109 // 00110 // <linkto class=CoordinateSystem>CoordinateSystem</linkto> is 00111 // the class that application programmers will usually interact 00112 // with. A CoordinateSystem consists of a collection of the other 00113 // classes derived from Coordinate. Normally one group will be for 00114 // RA/DEC, another for a Stokes axis, and another group for the spectral axis. 00115 // The axes may be transposed arbitrarily, for example RA could be 00116 // the first axis, and DEC the third. 00117 // 00118 // Normally the CoordinateSystem being manipulated will be embedded in a PagedImage 00119 // or other object. Note that the axes of the PagedImage do not 00120 // necessarily map directly to the axes in the CoordinateSystem. Functionality 00121 // is provided to determine this mapping. 00122 // 00123 // One or more axes from the CoordinateSystem may be removed. Pixel axes and/or 00124 // world axes may be removed. You are encouraged to leave all the world axes 00125 // when you remove pixel axes. 00126 // <br> 00127 // If a world axis is removed, the corresponding pixel axis is also removed. 00128 // This means that one can be sure that a pixel axis always has a 00129 // corresponding world axis (it makes no sense otherwise). The opposite is 00130 // not necessarily true: a world axis can exist without a pixel axis. 00131 // 00132 // The linear transformation and sky projection computations are carried out in an 00133 // underlying library -- WCSLIB -- written by Mark Calabretta of the ATNF. 00134 // 00135 // </synopsis> 00136 // 00137 // 00138 // <note role=caution> 00139 // All pixels coordinates are zero relative. 00140 // </note> 00141 // 00142 // <example> 00143 // First, let's make a DirectionCoordinate --- used to represent a direction, 00144 // usually an RA/DEC, but it could also be, e.g., an AZ/EL pair. 00145 // <srcblock> 00146 // Matrix<Double> xform(2,2); // 1 00147 // xform = 0.0; xform.diagonal() = 1.0; // 2 00148 // Quantum<Double> refLon(135.0, "deg"); 00149 // Quantum<Double> refLat(60.0, "deg"); 00150 // Quantum<Double> incLon(-1.0, "deg"); 00151 // Quantum<Double> incLat(1.0, "deg"); 00152 // DirectionCoordinate radec(MDirection::J2000, // 3 00153 // Projection(Projection::SIN), // 4 00154 // refLon, refLat, // 5 00155 // incLon, incLat, // 6 00156 // xform, // 7 00157 // 128, 128); // 8 00158 // </srcblock> 00159 // <ul> 00160 // <li> <i>1-2:</i>Here we set up a diagonal transformation matrix. 00161 // Normally this matrix should be diagonal, however if you wanted 00162 // to introduce a rotation or skew, you would do it through this 00163 // matrix. 00164 // <li> <i>3:</i>This defines the astronomical type of the world 00165 // coordinate. Most of the time it will probably be J2000 00166 // or B1950, but there are many other possibilities as listed 00167 // in the <linkto class=MDirection>MDirection</linkto> class 00168 // header. 00169 // <li> <i>4:</i>The <linkto class=Projection>Projection</linkto> class 00170 // defines the "geometry" that is used to map <src>xy<-->world</src>. SIN 00171 // is the most common projection for radio interferometers. Note that 00172 // SIN can optionally take parameters as defined in Calabretta and Greisen. 00173 // If not provided, they default to 0.0, which is the "old" SIN 00174 // convention. 00175 // <li> <i>5:</i>Set the reference position to RA=135, DEC=60 degrees. 00176 // Note that the native units of a DirectionCoordinate is radians. 00177 // <li> <i>6:</i> Set the increments to -1 degree in RA, and +1 degree 00178 // in DEC. 00179 // <li> <i>7:</i> Set the previously defined transformation matrix. 00180 // <li> <i>8:</i> Set the zero-relative reference pixel. Note that it does 00181 // not have to be incremental. At the reference pixel, the world 00182 // coordinate has the reference value. 00183 // </ul> 00184 // 00185 // Although we happeend to create our DirectionCoordinate with Quanta in degrees, 00186 // these have been converted to radians by the constructor. We can set the native units 00187 // to degrees if we wish as follows: 00188 // <srcblock> 00189 // Vector<String> units(2); units = "deg"; // 9 00190 // radec.setWorldAxisUnits(units); // 10 00191 // </srcblock> 00192 // The increment and reference value are updated appropriately. 00193 // 00194 // Set up a couple of vectors to use the world and pixel coordinate values. 00195 // <srcblock> 00196 // Vector<Double> world(2), pixel(2); // 11 00197 // pixel = 138.0; // 12 00198 // </srcblock> 00199 // We use 138 as an abitrary pixel position which is near the reference pixel 00200 // so we can tell if the answers look foolish or not. 00201 // 00202 // We can actually perform a transformation like this as follows. If 00203 // it succeeds we print the value of the world coordinate. 00204 // <srcblock> 00205 // Bool ok = radec.toWorld(world, pixel); // 13 00206 // if (!ok) { // 14 00207 // cout << "Error: " << radec.errorMessage() << endl; // 15 00208 // return 1; // 16 00209 // } // 17 00210 // cout << world << " <--- " << pixel << endl; // 18 00211 // </srcblock> 00212 // There is an overloaded "toWorld" function that produces an MDirection 00213 // in case you want to, e.g., find out what the position in B1950 coordinates 00214 // would be. 00215 // 00216 // The reverse transformation takes place similarly: 00217 // <srcblock> 00218 // ok = radec.toPixel(pixel, world); // 19 00219 // </srcblock> 00220 // 00221 // Suppose we have an image with a Stokes axis. It can be set up as follows: 00222 // <srcblock> 00223 // Vector<Int> iquv(4); 00224 // iquv(0) = Stokes::I; iquv(1) = Stokes::Q; // 21 00225 // iquv(2) = Stokes::U; iquv(3) = Stokes::V; // 22 00226 // StokesCoordinate stokes(iquv); // 23 00227 // </srcblock> 00228 // We create an integer array the same length as the Stokes axis, and place 00229 // the corresponding Stokes enum into each element of the array. The values 00230 // must be unique, e.g. there can only be one "I" plane. 00231 // Besides the generic <src>Vector<Double></src> toWorld/toPixel interface, 00232 // you can also directly interconvert between Stokes enum and and (zero-relative) 00233 // plane number: 00234 // <srcblock> 00235 // Int plane; // 24 00236 // ok = stokes.toPixel(plane, Stokes::Q); // 25 00237 // </srcblock> 00238 // Here it will return <src>True</src> and set plane to 1. On the other 00239 // hand, it would return <src>False</src> for: 00240 // <srcblock> 00241 // ok = stokes.toPixel(plane, Stokes::XX); // 26 00242 // </srcblock> 00243 // since "XX" is not one of the Stokes enumerations we used to create this 00244 // coordinate. 00245 // 00246 // A Spectral ("frequency") coordinate may be created as follows: 00247 // <srcblock> 00248 // SpectralCoordinate spectral(MFrequency::TOPO, // 27 00249 // 1.4E+9, // 28 00250 // 2.0E+4, // 29 00251 // 0, // 30 00252 // 1420.40575E+6); // 31 00253 // </srcblock> 00254 // The default frequency units of a spectral coordinate are Hz, although they 00255 // may be changed to whatever is convenient. The first line (27) defines the 00256 // type of frequency we have -- topocentric here. The second (28) line 00257 // defines the frequency at the reference pixel, 0 (28) here. The channel 00258 // increment is defined on line 29. A rest frequency of the spectral may 00259 // be provided. It is useful in calculating doppler velocities. These calculations 00260 // are carried out by the <linkto class=MFrequency>MFrequency</linkto> and 00261 // <linkto class=MDoppler>MDoppler</linkto> classes of the Measures system. 00262 // </example> 00263 // 00264 // <motivation> 00265 // The primary motivation is to provide support for converting pixel locations in an 00266 // image to physical ("world") positions. 00267 // </motivation> 00268 00269 // <todo asof="2000/01/01"> 00270 // <li> Add measures interfaces that handle reference frame conversions 00271 // <li> offset coordinates 00272 // </todo> 00273 00274 // </module> 00275 00276 00277 } //# NAMESPACE CASA - END 00278 00279 #endif