casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Coordinates.h
Go to the documentation of this file.
1 //# Coordinates.h : Classes to interconvert computation positions with physical
2 //# Copyright (C) 1996,1997,1998,1999,2000,2001
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef COORDINATES_COORDINATES_H
29 #define COORDINATES_COORDINATES_H
30 
31 //# Module includes
32 #include <casacore/casa/aips.h>
43 
44 namespace casacore { //# NAMESPACE CASACORE - BEGIN
45 
46 // <module>
47 //
48 // <summary>
49 // Classes to interconvert pixel and world (physical) coordinates
50 // </summary>
51 
52 // <prerequisite>
53 // <li> Knowledge of astronomical coordinate conversions in general. Probably the
54 // best documents are the papers by Mark Calabretta and Eric Greisen.
55 // The initial draft from 1996 can be found at
56 // http://www.atnf.csiro.au/~mcalabre. It is this draft that the
57 // Coordinate classes are based upon. Since then, this paper has evolved
58 // into three which can be found at the above address, and will be published in the
59 // Astronomy and Astrophysics Supplement Series (probably in 2000).
60 // The design has changed since the initial draft. When these papers
61 // are finalized, and the IAU has ratified the new standards, WCSLIB
62 // (Mark Calabretta's implementation of these conventions) will be
63 // revised for the new designs. At that time, the Coordinate classes
64 // may also be revised.
65 // <li> Generic Casacore classes; especially those in the
66 // <linkto module=Arrays>Arrays</linkto> module.
67 // <li> The <linkto module=Measures>Measures</linkto> module.
68 // </prerequisite>
69 //
70 
71 // <reviewed reviewer="Peter Barnes" date="1999/12/24">
72 // </reviewed>
73 
74 // <synopsis>
75 // The primary notion is that a <linkto class=Coordinate>Coordinate</linkto>
76 // can interconvert between a length "n" Vector<Double> (the
77 // pixel coordinate) and a length "m" Vector<Double> (the
78 // "world" coordinate). Note that "m" and "n" do not in
79 // principle have to be the same (so that one can get both the RA and DEC from
80 // an image slice, for example), however in practice they currently always are.
81 // Each Coordinate has the full mapping from pixel to world coordinates, i.e.
82 // it has a reference value, reference pixel, increments, and an arbitrary
83 // transformation matrix. To go from a pixel to a world coordinate the following
84 // steps are applied:
85 // <ol>
86 // <li> The reference pixel is subtracted from the pixel position.
87 // <li> The result is multiplied by the transformation matrix.
88 // <li> The result is multiplied by an increment per output axis to convert
89 // it into physical coordinates.
90 // <li> For some coordinate types (e.g., Direction), a non-linear function is
91 // applied to this result.
92 // </ol>
93 //
94 // The classes are arranged as follows. The base class is
95 // <linkto class=Coordinate>Coordinate</linkto> which defines the
96 // interface. Classes derived from it are
97 // <ol>
98 // <li> <linkto class=DirectionCoordinate>DirectionCoordinate</linkto>
99 // <li> <linkto class=LinearCoordinate>LinearCoordinate</linkto>
100 // <li> <linkto class=SpectralCoordinate>SpectralCoordinate</linkto>
101 // <li> <linkto class=TabularCoordinate>TabularCoordinate</linkto>
102 // <li> <linkto class=StokesCoordinate>StokesCoordinate</linkto>
103 // <li> <linkto class=CoordinateSystem>CoordinateSystem</linkto>
104 // </ol>
105 //
106 // Other classes are <linkto class=Projection>Projection</linkto>
107 // which is used to specify an astronomical projection for
108 // DirectionCoordinates, and <linkto class=LinearXform>LinearXform</linkto>
109 // a helper class which the application programmer will not interact with.
110 //
111 // <linkto class=CoordinateSystem>CoordinateSystem</linkto> is
112 // the class that application programmers will usually interact
113 // with. A CoordinateSystem consists of a collection of the other
114 // classes derived from Coordinate. Normally one group will be for
115 // RA/DEC, another for a Stokes axis, and another group for the spectral axis.
116 // The axes may be transposed arbitrarily, for example RA could be
117 // the first axis, and DEC the third.
118 //
119 // Normally the CoordinateSystem being manipulated will be embedded in a PagedImage
120 // or other object. Note that the axes of the PagedImage do not
121 // necessarily map directly to the axes in the CoordinateSystem. Functionality
122 // is provided to determine this mapping.
123 //
124 // One or more axes from the CoordinateSystem may be removed. Pixel axes and/or
125 // world axes may be removed. You are encouraged to leave all the world axes
126 // when you remove pixel axes.
127 // <br>
128 // If a world axis is removed, the corresponding pixel axis is also removed.
129 // This means that one can be sure that a pixel axis always has a
130 // corresponding world axis (it makes no sense otherwise). The opposite is
131 // not necessarily true: a world axis can exist without a pixel axis.
132 //
133 // The linear transformation and sky projection computations are carried out in an
134 // underlying library -- WCSLIB -- written by Mark Calabretta of the ATNF.
135 //
136 // </synopsis>
137 //
138 //
139 // <note role=caution>
140 // All pixels coordinates are zero relative.
141 // </note>
142 //
143 // <example>
144 // First, let's make a DirectionCoordinate --- used to represent a direction,
145 // usually an RA/DEC, but it could also be, e.g., an AZ/EL pair.
146 // <srcblock>
147 // Matrix<Double> xform(2,2); // 1
148 // xform = 0.0; xform.diagonal() = 1.0; // 2
149 // Quantum<Double> refLon(135.0, "deg");
150 // Quantum<Double> refLat(60.0, "deg");
151 // Quantum<Double> incLon(-1.0, "deg");
152 // Quantum<Double> incLat(1.0, "deg");
153 // DirectionCoordinate radec(MDirection::J2000, // 3
154 // Projection(Projection::SIN), // 4
155 // refLon, refLat, // 5
156 // incLon, incLat, // 6
157 // xform, // 7
158 // 128, 128); // 8
159 // </srcblock>
160 // <ul>
161 // <li> <i>1-2:</i>Here we set up a diagonal transformation matrix.
162 // Normally this matrix should be diagonal, however if you wanted
163 // to introduce a rotation or skew, you would do it through this
164 // matrix.
165 // <li> <i>3:</i>This defines the astronomical type of the world
166 // coordinate. Most of the time it will probably be J2000
167 // or B1950, but there are many other possibilities as listed
168 // in the <linkto class=MDirection>MDirection</linkto> class
169 // header.
170 // <li> <i>4:</i>The <linkto class=Projection>Projection</linkto> class
171 // defines the "geometry" that is used to map <src>xy<-->world</src>. SIN
172 // is the most common projection for radio interferometers. Note that
173 // SIN can optionally take parameters as defined in Calabretta and Greisen.
174 // If not provided, they default to 0.0, which is the "old" SIN
175 // convention.
176 // <li> <i>5:</i>Set the reference position to RA=135, DEC=60 degrees.
177 // Note that the native units of a DirectionCoordinate is radians.
178 // <li> <i>6:</i> Set the increments to -1 degree in RA, and +1 degree
179 // in DEC.
180 // <li> <i>7:</i> Set the previously defined transformation matrix.
181 // <li> <i>8:</i> Set the zero-relative reference pixel. Note that it does
182 // not have to be incremental. At the reference pixel, the world
183 // coordinate has the reference value.
184 // </ul>
185 //
186 // Although we happeend to create our DirectionCoordinate with Quanta in degrees,
187 // these have been converted to radians by the constructor. We can set the native units
188 // to degrees if we wish as follows:
189 // <srcblock>
190 // Vector<String> units(2); units = "deg"; // 9
191 // radec.setWorldAxisUnits(units); // 10
192 // </srcblock>
193 // The increment and reference value are updated appropriately.
194 //
195 // Set up a couple of vectors to use the world and pixel coordinate values.
196 // <srcblock>
197 // Vector<Double> world(2), pixel(2); // 11
198 // pixel = 138.0; // 12
199 // </srcblock>
200 // We use 138 as an abitrary pixel position which is near the reference pixel
201 // so we can tell if the answers look foolish or not.
202 //
203 // We can actually perform a transformation like this as follows. If
204 // it succeeds we print the value of the world coordinate.
205 // <srcblock>
206 // Bool ok = radec.toWorld(world, pixel); // 13
207 // if (!ok) { // 14
208 // cout << "Error: " << radec.errorMessage() << endl; // 15
209 // return 1; // 16
210 // } // 17
211 // cout << world << " <--- " << pixel << endl; // 18
212 // </srcblock>
213 // There is an overloaded "toWorld" function that produces an MDirection
214 // in case you want to, e.g., find out what the position in B1950 coordinates
215 // would be.
216 //
217 // The reverse transformation takes place similarly:
218 // <srcblock>
219 // ok = radec.toPixel(pixel, world); // 19
220 // </srcblock>
221 //
222 // Suppose we have an image with a Stokes axis. It can be set up as follows:
223 // <srcblock>
224 // Vector<Int> iquv(4);
225 // iquv(0) = Stokes::I; iquv(1) = Stokes::Q; // 21
226 // iquv(2) = Stokes::U; iquv(3) = Stokes::V; // 22
227 // StokesCoordinate stokes(iquv); // 23
228 // </srcblock>
229 // We create an integer array the same length as the Stokes axis, and place
230 // the corresponding Stokes enum into each element of the array. The values
231 // must be unique, e.g. there can only be one "I" plane.
232 // Besides the generic <src>Vector<Double></src> toWorld/toPixel interface,
233 // you can also directly interconvert between Stokes enum and and (zero-relative)
234 // plane number:
235 // <srcblock>
236 // Int plane; // 24
237 // ok = stokes.toPixel(plane, Stokes::Q); // 25
238 // </srcblock>
239 // Here it will return <src>True</src> and set plane to 1. On the other
240 // hand, it would return <src>False</src> for:
241 // <srcblock>
242 // ok = stokes.toPixel(plane, Stokes::XX); // 26
243 // </srcblock>
244 // since "XX" is not one of the Stokes enumerations we used to create this
245 // coordinate.
246 //
247 // A Spectral ("frequency") coordinate may be created as follows:
248 // <srcblock>
249 // SpectralCoordinate spectral(MFrequency::TOPO, // 27
250 // 1.4E+9, // 28
251 // 2.0E+4, // 29
252 // 0, // 30
253 // 1420.40575E+6); // 31
254 // </srcblock>
255 // The default frequency units of a spectral coordinate are Hz, although they
256 // may be changed to whatever is convenient. The first line (27) defines the
257 // type of frequency we have -- topocentric here. The second (28) line
258 // defines the frequency at the reference pixel, 0 (28) here. The channel
259 // increment is defined on line 29. A rest frequency of the spectral may
260 // be provided. It is useful in calculating doppler velocities. These calculations
261 // are carried out by the <linkto class=MFrequency>MFrequency</linkto> and
262 // <linkto class=MDoppler>MDoppler</linkto> classes of the Measures system.
263 // </example>
264 //
265 // <motivation>
266 // The primary motivation is to provide support for converting pixel locations in an
267 // image to physical ("world") positions.
268 // </motivation>
269 
270 // <todo asof="2000/01/01">
271 // <li> Add measures interfaces that handle reference frame conversions
272 // <li> offset coordinates
273 // </todo>
274 
275 // </module>
276 
277 
278 } //# NAMESPACE CASACORE - END
279 
280 #endif