casacore
DirectionCoordinate.h
Go to the documentation of this file.
1 //# DirectionCoordinate.h: Interconvert pixel positions and directions (e.g. RA/DEC)
2 //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2004
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 //#
27 //# $Id:
28 
29 
30 #ifndef COORDINATES_DIRECTIONCOORDINATE_H
31 #define COORDINATES_DIRECTIONCOORDINATE_H
32 
33 #include <casacore/casa/aips.h>
34 #include <casacore/coordinates/Coordinates/Coordinate.h>
35 #include <casacore/coordinates/Coordinates/Projection.h>
36 #include <casacore/casa/Arrays/Vector.h>
37 #include <casacore/measures/Measures/MDirection.h>
38 #include <casacore/measures/Measures/MeasConvert.h>
39 #include <casacore/casa/Quanta/RotMatrix.h>
40 #include <wcslib/wcs.h>
41 
42 struct celprm;
43 struct prjprm;
44 struct wcsprm;
45 
46 namespace casacore { //# NAMESPACE CASACORE - BEGIN
47 
48 class MVDirection;
49 class MVAngle;
50 class LogIO;
51 template<class T> class Quantum;
52 
53 
54 // <summary>
55 // Interconvert pixel positions and directions (e.g. RA/DEC).
56 // </summary>
57 
58 // <use visibility=export>
59 
60 // <reviewed reviewer="Peter Barnes" date="1999/12/24" tests="tDirectionCoordinate">
61 // </reviewed>
62 
63 
64 // <prerequisite>
65 // <li> Knowledge of astronomical coordinate conversions in general. Probably the
66 // best documents are the papers by Mark Calabretta and Eric Greisen.
67 // The initial draft from 1996 can be found at
68 // http://www.atnf.csiro.au/~mcalabre. It is this draft that the
69 // Coordinate classes are based upon. Since then, this paper has evolved
70 // into three which can be found at the above address, and will be published in the
71 // Astronomy and Astrophysics Supplement Series (probably in 2000).
72 // The design has changed since the initial draft. When these papers
73 // are finalized, and the IAU has ratified the new standards, WCSLIB
74 // (Mark Calabretta's implementation of these conventions) will be
75 // revised for the new designs. At that time, the Coordinate classes
76 // may also be revised.
77 // <li> <linkto class=Coordinate>Coordinate</linkto> defines the fundamental
78 // interface to coordinate conversions.
79 // <li> <linkto class=MDirection>MDirection</linkto> defines the types of
80 // directions (J2000 etc.) which are defined. The measures machinery
81 // also implements "astronomical" conversions which are outside the
82 // scope of these coordinates (for example, <src>J2000</src> to
83 // <src>B1950</src>).
84 // <li> <linkto class=Projection>Projection</linkto> defines the types of
85 // celestial projections which are available.
86 // </prerequisite>
87 //
88 // <synopsis>
89 // This class implements pixel to world coordinate conversions. This class
90 // implements geometric conversions (e.g. SIN projection) via the WCS library
91 // and also provides an interface to astronomical conversions (RA/DEC <--> l,b)
92 // via the <linkto module=Measures>Measures</linkto> module.
93 // </synopsis>
94 //
95 //
96 // <note role=caution>
97 // All absolute pixels coordinates are zero relative.
98 // </note>
99 //
100 // <example>
101 // Let's make a DirectionCoordinate --- used to represent a direction,
102 // usually an RA/DEC, but it could also be, e.g., an AZ/EL pair.
103 // <srcblock>
104 // Matrix<Double> xform(2,2); // 1
105 // xform = 0.0; xform.diagonal() = 1.0; // 2
106 // DirectionCoordinate radec(MDirection::J2000, // 3
107 // Projection(Projection::SIN), // 4
108 // 135*C::pi/180.0, 60*C::pi/180.0, // 5
109 // -1*C::pi/180.0, 1*C::pi/180, // 6
110 // xform, // 7
111 // 128, 128); // 8
112 // </srcblock>
113 // <ul>
114 // <li> <i>1-2:</i>Here we set up a diagonal transformation matrix.
115 // Normally this matrix should be diagonal, however if you wanted
116 // to introduce a rotation or skew, you would do it through this
117 // matrix.
118 // <li> <i>3:</i>This defines the astronomical type of the world
119 // coordinate. Most of the time it will probably be J2000
120 // or B1950, but many other possibilities are possible as listed
121 // in the <linkto class=MDirection>MDirection</linkto> class
122 // header.
123 // <li> <i>4:</i>The <linkto class=Projection>Projection</linkto> class
124 // defines the "geometry" that is used to map <src>xy<-->world</src>. SIN
125 // is the most common projection for radio interferometers. Note that
126 // SIN can optionally take parameters as defined in Calabretta and Greisen.
127 // If not provided, they default to 0.0, which is the "old" SIN
128 // convention.
129 // <li> <i>5:</i>Set the reference position to RA=135, DEC=60 degrees.
130 // Note that the native units of a Direction is radians.
131 // <li> <i>6:</i> Set the increments to -1 degree in RA, and +1 degree
132 // in DEC.
133 // <li> <i>7:</i> Set the previously defined transformation matrix.
134 // <li> <i>8:</i> Set the zero-relative reference pixel. Note that it does
135 // not have to be incremental. At the reference pixel, the world
136 // coordinate has the reference value.
137 // </ul>
138 //
139 // In this example is is more convenient to change the units to degrees. This can
140 // be accomplished as follows:
141 // <srcblock>
142 // Vector<String> units(2); units = "deg"; // 9
143 // radec.setWorldAxisUnits(units); // 10
144 // </srcblock>
145 // The increment and reference value are updated appropriately.
146 //
147 // Set up a couple of vectors to use the world and pixel coordinate values.
148 // <srcblock>
149 // Vector<Double> world(2), pixel(2); // 11
150 // pixel = 138.0; // 12
151 // </srcblock>
152 // We use 138 as an arbitrary pixel position which is near the reference pixel
153 // so we can tell if the answers look foolish or not.
154 // We can actually perform a transformation like this as follows. If
155 // it succeeds we print the value of the world coordinate.
156 // <srcblock>
157 // Bool ok = radec.toWorld(world, pixel); // 13
158 // if (!ok) { // 14
159 // cout << "Error: " << radec.errorMessage() << endl; // 15
160 // return 1; // 16
161 // } // 17
162 // cout << world << " <--- " << pixel << endl; // 18
163 // </srcblock>
164 // There is an overloaded "toWorld" function that produces an MDirection
165 // in case you want to, e.g., find out what the position in B1950 coordinates
166 // would be.
167 //
168 // The reverse transformation takes place similarly:
169 // <srcblock>
170 // ok = radec.toPixel(pixel, world); // 19
171 // </srcblock>
172 // </example>
173 //
174 // <example>
175 // We could also have made the above DirectionCoordinate using the Quantum-based
176 // constructor, which is a little more elegant if you want to use degrees.
177 //
178 // Matrix<Double> xform(2,2);
179 // xform = 0.0; xform.diagonal() = 1.0;
180 // Quantum<Double> refLon(135.0, "deg");
181 // Quantum<Double> refLat(60.0, "deg");
182 // Quantum<Double> incLon(-1.0, "deg");
183 // Quantum<Double> incLat(1.0, "deg");
184 // DirectionCoordinate radec(MDirection::J2000,
185 // Projection(Projection::SIN),
186 // refLon, refLat,
187 // incLon, incLat,
188 // xform,
189 // 128, 128);
190 //
191 // But note that the constructor will have converted the native units
192 // of the DirectionCoordinate to radians. So the Double-based toWorld and
193 // toPixel functions will be in terms of radians. If you want the native
194 // units to be degrees, then again you can use
195 //
196 // <srcblock>
197 // Vector<String> units(2); units = "deg";
198 // radec.setWorldAxisUnits(units);
199 // </srcblock>
200 // and thereafter degrees are the native units.
201 // </example>
202 //
203 // <motivation>
204 // Directions in the sky are fundamental to astronomy.
205 // </motivation>
206 //
207 //
208 // <thrown>
209 // <li> AipsError
210 // </thrown>
211 //
212 // <todo asof="2000/01/01">
213 // <li> Nothing
214 // </todo>
215 
216 
218 {
219 public:
220  // The default constructor creates a J2000 DirectionCoordinate with a
221  // CARtesion projection with longitude,latitude 0,0 at pixel 0,0 and an
222  // increment of +1 radian per pixel on both axes.
224 
225  // Define the DirectionCoordinate transformation. <src>refLong</src> and
226  // <src>refLat</src> will normally the the RA/DEC of the pixel described by
227  // <src>refX/refY</src>. <src>incLat/incLong</src>
228  // are the increments per pixel (RA is usually negative), and the <src>xform</src>
229  // matrix is usually the unit diagonal matrix unless you have a rotation or
230  // some other linear transformation between the pixel and world axes.
231  //
232  // Note that the units are radians initially. You can change it to degrees
233  // or something else with the <src>setWorldAxisUnits</src> method later if you want.
234  //
235  // longPole and latPole are defined by Calabretta and Greisen (these
236  // are reference points not at the native pole). In general
237  // you can leave these out and the default values will cause them
238  // to be computed appropriately. However, when reading from FITS
239  // the LONPOLE and LATPOLE keywords are passed along here.
241  const Projection &projection,
242  Double refLong, Double refLat,
243  Double incLong, Double incLat,
244  const Matrix<Double> &xform,
245  Double refX, Double refY,
246  Double longPole=999.0, Double latPole=999.0);
247 
248  // Create DirectionCoordinate with Quantum-based interface.
249  // Parameters are the same as above.
250  // Regardless of the units of the quanta, the initial units
251  // of the DirectionCoordinate will be converted radians.
252  // You can change it to degrees or something else with the
253  // setWorldAxisUnits method later if you want.
254  //
255  // longPole and latPole are defined by Calabretta and Greisen (these
256  // are reference points not at the native pole). In general
257  // you can leave these out and the default values will cause them
258  // to be computed appropriately. However, when reading from FITS
259  // the LONPOLE and LATPOLE keywords are passed along here.
260  // To get the default the 999.0 value should be used (units
261  // are irrelevant in that case)
263  const Projection &projection,
264  const Quantum<Double>& refLong,
265  const Quantum<Double>& refLat,
266  const Quantum<Double>& incLong,
267  const Quantum<Double>& incLat,
268  const Matrix<Double> &xform,
269  Double refX, Double refY,
270  const Quantum<Double>& longPole=Quantum<Double>(999.0,Unit("rad")),
271  const Quantum<Double>& latPole=Quantum<Double>(999.0,Unit("rad")));
272 
273  // Constructor from WCS structure; must hold ONLY a celestial wcs structure
274  // Specify whether the absolute pixel coordinates in the wcs structure
275  // are 0- or 1-relative. The coordinate is always constructed with 0-relative
276  // pixel coordinates
278  const ::wcsprm& wcs, Bool oneRel=True);
279 
280  // Copy constructor (copy semantics)
282 
283  // Assignment (copy semantics).
285 
286  // Destructor
288 
289  // Return Coordinate::DIRECTION
290  virtual Coordinate::Type type() const;
291 
292  // Always returns the String "Direction".
293  virtual String showType() const;
294 
295  // Always returns 2.
296  // <group>
297  virtual uInt nPixelAxes() const;
298  virtual uInt nWorldAxes() const;
299  // </group>
300 
301 
302  // Set extra conversion type. Whenever a conversion from pixel to world is done,
303  // the world value is then further converted to this MDirection::Types value.
304  // For example, your DirectionCoordinate may be defined in J2000.
305  // You can use this to get the world values out in say GALACTIC.
306  // Similarly, whenever you convert from world to pixel, the world
307  // value is assumed to be that appropriate to the conversionDirectionType.
308  // It is first converted to the MDirection::Types with which the
309  // DirectionCoordinate was constructed and from there to pixel.
310  // If you don't call this function, or you set the same type
311  // for which the DirectionCoordinate was constructed, no extra
312  // conversions occur. Some conversions will fail. These are the
313  // ones that require extra frame information (epoch, position) such
314  // as to AZEL from J2000 etc. This will be added later.
315  //
316  // In the mixed pixel/world conversion routine <src>toMix</src>
317  // the implementation is only partial. See the comments for this
318  // function below.
319  // <group>
323  // </group>
324 
325  // Convert a pixel position to a world position or vice versa. Returns True
326  // if the conversion succeeds, otherwise it returns False and method
327  // errorMessage returns its error message.
328  // The output vectors are appropriately resized.
329  // if <src>useConversionFrame</src>, if the coordinate has a conversion
330  // layer frame, it is used. Else, the native frame is used for the conversion.
331  // <group>
332  virtual Bool toWorld(Vector<Double> &world,
333  const Vector<Double> &pixel, Bool useConversionFrame=True) const;
334 
335  // <src>world</src> values must have units equivalent to the world axis
336  // units. If the coordinate has a conversion layer, the world coordinates
337  // must be supplied in the conversion frame.
338  virtual Bool toPixel(Vector<Double> &pixel,
339  const Vector<Double> &world) const;
340  // </group>
341 
342  // Mixed pixel/world coordinate conversion.
343  // <src>worldIn</src> and <src>worldAxes</src> are of length
344  // nWorldAxes.
345  // <src>pixelIn</src> and <src>pixelAxes</src> are of length nPixelAxes.
346  // <src>worldAxes(i)=True</src> specifies you have given a world
347  // value in <src>worldIn(i)</src> to convert to pixel.
348  // <src>pixelAxes(i)=True</src> specifies you have given a pixel
349  // value in <src>pixelIn(i)</src> to convert to world.
350  // You cannot specify the same axis via <src>worldAxes</src>
351  // and <src>pixelAxes</src>.
352  // Values in <src>pixelIn</src> are converted to world and
353  // put into <src>worldOut</src> in the appropriate world axis
354  // location. Values in <src>worldIn</src> are copied to
355  // <src>worldOut</src>.
356  // Values in <src>worldIn</src> are converted to pixel and
357  // put into <src>pixelOut</src> in the appropriate pixel axis
358  // location. Values in <src>pixelIn</src> are copied to
359  // <src>pixelOut</src>.
360  //
361  // <src>worldMin</src> and <src>worldMax</src> specify the range of the world
362  // coordinate (in the world axis units of that world axis
363  // in the CoordinateSystem) being solved for in a mixed calculation
364  // for each world axis. Some mixed solutions can be degenerate, whereupon you
365  // you must say which one you want. Use functions <src>setWorldMixRanges</src>
366  // and <src>worldMixMin, worldMixMax</src> to set these ranges,
367  // If you don't know, use the defaults (function <src>setDefaultWorldMixRanges</src>.
368  // Removed axes are handled (for example, a removed pixel
369  // axis with remaining corresponding world axis will
370  // correctly be converted to world using the replacement
371  // value).
372  // Returns True if the conversion succeeds, otherwise it returns False and
373  // <src>errorMessage()</src> contains an error message. The output vectors
374  // are resized.
375  //
376  // If you actually request a pure pixel to world or world to pixel
377  // via <src>toMix</src>, then the functions <src>toWorld</src> or <src>toPixel</src>
378  // will be invoked directly (see above) and the extra conversion layer
379  // invoked through function <src>setReferenceConversion</src> will be active.
380  // However, if you request a true mixed pixel/world conversion,
381  // the extra conversion layer is not activated (because of the nature of mixed
382  // conversions). This situation may change in the future
383  // with a partial implementation added.
384  virtual Bool toMix(Vector<Double>& worldOut,
385  Vector<Double>& pixelOut,
386  const Vector<Double>& worldIn,
387  const Vector<Double>& pixelIn,
388  const Vector<Bool>& worldAxes,
389  const Vector<Bool>& pixelAxes,
390  const Vector<Double>& worldMin,
391  const Vector<Double>& worldMax) const;
392 
393  // Compute and retrieve the world min and max ranges, for use in function <src>toMix</src>,
394  // for a lattice of the given shape (for this coordinate). Using these
395  // ranges in <src>toMix</src> should speed it up and help avoid ambiguity.
396  // If the shape is negative, that indicates that the shape is unknown
397  // for that axis. The default range is used for that axis. This situation
398  // arises in a CoordinateSystem for which a pixel, but not a world axis
399  // has been removed.
400  // The output vectors are resized. Returns False if fails (and
401  // then <src>setDefaultWorldMixRanges</src> generates the ranges)
402  // with a reason in <src>errorMessage()</src>.
403  // The <src>setDefaultWorldMixRanges</src> function
404  // just gives you [-90->90], [-180,180] (in appropriate units)
405  // <group>
407  virtual void setDefaultWorldMixRanges ();
408  // </group>
409 
410  // Non-virtual function. When <src>which</src> is T, use the
411  // world value as the center for the mix world range.
412  void setWorldMixRanges (const Vector<Bool>& which,
413  const Vector<Double>& world);
414 
415  // A convenient way to turn the world vector into an MDirection or MVDirection
416  // for further processing in the Measures system.
417  // <br>We could improve the performance of this if it would be useful. However it is
418  // expected that normally one would just call this once to get a template
419  // MDirection, and then call the vector versions.
420  // <br>In case of a failure, the versions with a Bool return value will return
421  // False. The other versions will throw an exception.
422  // <group>
423  Bool toWorld(MDirection &world, const Vector<Double> &pixel) const;
424  Bool toPixel(Vector<Double> &pixel, const MDirection &world) const;
425  Bool toWorld(MVDirection &world, const Vector<Double> &pixel) const;
426  Bool toPixel(Vector<Double> &pixel, const MVDirection &world) const;
427  MVDirection toWorld(const Vector<Double> &pixel) const;
428  Vector<Double> toPixel(const MVDirection &world) const;
429  Vector<Double> toPixel(const MDirection &world) const;
430  //</group>
431 
432  // Batch up a lot of transformations. The first (most rapidly varying) axis
433  // of the matrices contain the coordinates. Returns False if any conversion
434  // failed and <src>errorMessage()</src> will hold a message.
435  // The <src>failures</src> array is the length of the number of conversions
436  // (True for failure, False for success)
437  // <group>
439  const Matrix<Double> &pixel,
440  Vector<Bool> &failures) const;
442  const Matrix<Double> &world,
443  Vector<Bool> &failures) const;
444  // </group>
445 
446 
447  // Make absolute world coordinates relative and vice-versa (relative to
448  // the reference value). Note that these functions are independent
449  // of the MDirection::Types (set either at construction or by function
450  // <src>setReferenceConversion</src>). The vectors must be
451  // of length <src>nWorldAxes</src> or memory access errors will occur
452  //<group>
453  virtual void makeWorldRelative (Vector<Double>& world) const;
454  virtual void makeWorldRelative (MDirection& world) const;
455  virtual void makeWorldAbsolute (Vector<Double>& world) const;
456  virtual void makeWorldAbsolute (MDirection& world) const;
457  //</group>
458 
459  // Make absolute coordinates relative and vice versa with respect
460  // to the given reference value. Add the other functions in this grouping
461  // as needed.
462  //<group>
463  virtual void makeWorldAbsoluteRef (Vector<Double>& world,
464  const Vector<Double>& refVal) const;
465  //</group>
466 
467  // Recover the requested attribute.
468  // <group>
469  MDirection::Types directionType(Bool showConversion=False) const;
474  virtual Vector<Double> increment() const;
477  // </group>
478 
479  // Set the value of the requested attribute. Note that these just
480  // change the internal values, they do not cause any recomputation.
481  // <group>
482  virtual Bool setWorldAxisNames(const Vector<String> &names);
483  virtual Bool setReferencePixel(const Vector<Double> &refPix);
484  virtual Bool setLinearTransform(const Matrix<Double> &xform);
485  virtual Bool setIncrement(const Vector<Double> &inc);
486  virtual Bool setReferenceValue(const Vector<Double> &refval);
487  // </group>
488 
489  // Change the world axis units. Adjust the increment and
490  // reference value by the ratio of the old and new units.
491  // The units must be compatible with
492  // angle. The units are initially "rad" (radians).
493  virtual Bool setWorldAxisUnits(const Vector<String> &units);
494 
495  // Return canonical axis names for the given MDirection type,
496  // giving FITS names if desired.
497  // BEG think this should be in the MDirection class, but WNB
498  // disagrees. Leave it here for now.
500  Bool FITSName = False);
501 
502  // Comparison function. Any private Double data members are compared
503  // with the specified fractional tolerance. Don't compare on the specified
504  // axes in the Coordinate. If the comparison returns False, method
505  // errorMessage returns a message about why.
506  // <group>
507  virtual Bool near(const Coordinate& other,
508  Double tol=1e-6) const;
509  virtual Bool near(const Coordinate& other,
510  const Vector<Int>& excludeAxes,
511  Double tol=1e-6) const;
512  // </group>
513 
514 
515  // Format a DirectionCoordinate coordinate world value nicely through the
516  // common format interface. See <linkto class=Coordinate>Coordinate</linkto>
517  // for basics.
518  //
519  // Formatting types that are allowed are SCIENTIFIC, FIXED, MIXED, and TIME
520  // If you ask for format type Coordinate::DEFAULT then the
521  // selected format depends upon what the value of the enum
522  // MDirection::GlobalTypes is for this DirectionCoordinate.
523  // For example, if it is GRADEC or GHADEC you would
524  // get Coordinate::TIME style formatting (DD:MM:SS.SS), otherwise
525  // you would get Coordinate::FIXED formatting by default.
526  //
527  // <src>axis</src> says which axis in this Coordinate we are formatting.
528  // We have to know this because we may format Longitude and Latitude differently.
529  // For Coordinate::TIME style formatting, precision
530  // refers to the places after the decimal in the SS field.
531  //
532  // If you leave <src>units</src> empty, then it makes up a nice unit for you.
533  //<group>
534  virtual void getPrecision (Int& precision,
536  Bool showAsAbsolute,
537  Int defPrecScientific,
538  Int defPrecFixed,
539  Int defPrecTime) const;
540  virtual String format(String& units,
542  Double worldValue,
543  uInt axis,
544  Bool isAbsolute,
545  Bool showAsAbsolute,
546  Int precision=-1, Bool usePrecForMixed=False) const;
547  //</group>
548 
549  // Fix cylindrical coordinates to put the longitude in [-180,180] range.
550  // If False returned, it failed an an error is in <src>errorMessage</src>
551  // This fix is not done automatically internally because of the dependence
552  // on the image shape. It should be called for any foreign image
553  // (such as FITS) that is imported
554  Bool cylindricalFix (Int shapeLong, Int shapeLat);
555 
556  // Find the Coordinate for when we Fourier Transform ourselves. This pointer
557  // must be deleted by the caller. Axes specifies which axes of the Coordinate
558  // you wish to transform. Shape specifies the shape of the image
559  // associated with all the axes of the Coordinate. Currently the
560  // output reference pixel is always shape/2. If the pointer returned is 0,
561  // it failed with a message in <src>errorMessage</src>
563  const Vector<Int>& shape) const;
564 
565  // Save the DirectionCoordinate into the supplied record using the supplied field name.
566  // The field must not exist, otherwise <src>False</src> is returned.
567  virtual Bool save(RecordInterface &container,
568  const String &fieldName) const;
569 
570  // Recover the DirectionCoordinate from a record.
571  // A null pointer means that the restoration did not succeed.
572  static DirectionCoordinate *restore(const RecordInterface &container,
573  const String &fieldName);
574 
575  // Make a copy of the DirectionCoordinate using new. The caller
576  // is responsible for calling delete.
577  virtual Coordinate *clone() const;
578 
579  // Fish out the ref and non-native poles (refLong, refLat, longPole, latPole)
580  // Not for general use. Units are degrees.
582 
583  // get the pixel area.
585 
586  // Convert this coordinate to another reference frame by rotating it about
587  // the reference pixel so the the axes of the new reference frame are
588  // aligned along the current pixel axes. The reference pixel remains the
589  // same and the conversion is exact for the reference pixel and in general
590  // becomes less accurate as distance from reference pixel increases. The
591  // latitude like and the longitude like pixel increments are preserved.
592  // Conversions which require extra information such as epoch and position
593  // are not supported. The <src>angle</src> parameter is the angle between
594  // the new coordinate and the pixel coordinate, measured clockwise from the
595  // positive y-axis of the new coordinate to the positive y-axis of the pixel
596  // coordinate; ie, it is the clockwise angle through which the current world
597  // coordinate would have to be rotated so that the new coordinate's axes
598  // would be parallel to the pixel axes. The accuracy of the returned angle
599  // is good to at least 7 digits.
602  ) const;
603 
604  // Set the projection.
605  void setProjection(const Projection&);
606 
607  // Set the base (as opposed to conversion) reference frame.
609 
610  // Are the pixels square?
612 
613  // Is the projection equivalent to NCP?
614  Bool isNCP() const;
615 
616 private:
617  // Direction type
619 
620  // Projection parameters
622 
623  // WCS structure. This is mutable because the wcs functions
624  // that do toPixel and toWorld (which have const signature)
625  // require a non const wcs structure. so either all of these
626  // virtual functions lose their const or we use mutable...
627  mutable ::wcsprm wcs_p;
628 
629  // WCS computes in degrees - use this to convert back and forth between
630  // current DirectionCoordinate units and degrees or radians
631  Vector<Double> to_degrees_p; // From current units to degrees
632  Vector<Double> to_radians_p; // From current units to radians
633 
634  // Axis names.
636 
637  // Current units.
639 
640  // Rotation matrix used to handle relative coordinates
642 
643  // Conversion machines.
644  // "To" handles type_p -> conversionType_p
645  // "From" handles conversionType_p -> type_p;
648 
649  // Interconvert between the current units and wcs units (degrees)
650  // <group>
651  void toCurrent(Vector<Double>& degrees) const;
652  void fromCurrent(Vector<Double>& current) const;
653  // </group>
654 
655  // Check formatting types.
657  Bool absolute) const;
658 
659  // Format a latitude.
661  Bool absolute,
663  Int prec) const;
664  // Format a longitude.
667  Bool absolute,
669  Int prec) const;
670 
671  // Mixed pixel/world coordinate conversion. Vector in must
672  // be length nWorldAxes (2). Specify whether longitude
673  // (in(0)) or latitude (in(1)) is the world coordinate . It is
674  // assumed that the other value is the pixel coordinate.
676  const Vector<Double>& minWorld, const Vector<Double>& maxWorld,
677  Bool longIsWorld) const;
678 
679  // Initialize unit conversion vectors and units
681 
682  // Helper functions interfacing to WCS.
683  // <group>
685  const Projection& proj, Double refLong, Double refLat,
686  Double incLong, Double incLat,
687  const Matrix<Double> &xform,
688  Double refX, Double refY,
689  Double longPole, Double latPole);
690 //
691  void makeWCS(::wcsprm& wcs, const Matrix<Double>& xform,
693  Double refPixLong, Double refPixLat,
694  Double refLong, Double refLat,
695  Double incLong, Double incLat,
696  Double longPole, Double latPole);
697  // </group>
698 
699  // Normalize each row of the PC matrix such that increment() will return the actual
700  // angular increment and any scale factors are removed from the PC matrix
701  // (modifies wcs_p.pc _and_ wcs_p.cdelt _and_ wcs_p.altlin,
702  // executes set_wcs() and hence wcsset() on the struct)
703  // See Greisen & Calabretta, A&A 395, 1061-1075 (2002), equation (4)
705 
706  Double putLongInPiRange (Double lon, const String& unit) const;
707 
708  // Set up conversion machine
710 
711  // Convert from type_p -> conversionType_p
712  // <group>
713  virtual void convertTo (Vector<Double>& world) const;
714  virtual void convertFrom (Vector<Double>& world) const;
715  // </group>
716 
717  // Copy private data
718  void copy (const DirectionCoordinate& other);
719 
720  // Set up the offset coordinate rotation matrix. Units
721  // of long and lat are current world units
722  // <group>
724  void setRotationMatrix (RotMatrix& rot, Double lon, Double lat) const;
725  // </group>
726 
727  // Return unit conversion vector for converting to current units
729 
730 };
731 
732 } //# NAMESPACE CASACORE - END
733 
734 
735 #endif
736 
Type
This enum lists the types of the derived classes.
Definition: Coordinate.h:144
formatType
This enum is used for formatting world values into Strings.
Definition: Coordinate.h:162
void setReferenceFrame(const MDirection::Types rf)
Set the base (as opposed to conversion) reference frame.
MDirection::Types directionType(Bool showConversion=False) const
Recover the requested attribute.
Quantity getPixelArea() const
get the pixel area.
static Vector< String > axisNames(MDirection::Types type, Bool FITSName=False)
Return canonical axis names for the given MDirection type, giving FITS names if desired.
DirectionCoordinate & operator=(const DirectionCoordinate &other)
Assignment (copy semantics).
Vector< String > units_p
Current units.
Vector< Double > to_degrees_p
WCS computes in degrees - use this to convert back and forth between current DirectionCoordinate unit...
virtual ~DirectionCoordinate()
Destructor.
virtual void makeWorldAbsoluteRef(Vector< Double > &world, const Vector< Double > &refVal) const
Make absolute coordinates relative and vice versa with respect to the given reference value.
virtual void setDefaultWorldMixRanges()
virtual uInt nWorldAxes() const
virtual void makeWorldRelative(Vector< Double > &world) const
Make absolute world coordinates relative and vice-versa (relative to the reference value).
virtual Bool setWorldAxisUnits(const Vector< String > &units)
Change the world axis units.
void makeConversionMachines()
Set up conversion machine.
virtual Bool toWorldMany(Matrix< Double > &world, const Matrix< Double > &pixel, Vector< Bool > &failures) const
Batch up a lot of transformations.
virtual Vector< Double > referenceValue() const
void toCurrent(Vector< Double > &degrees) const
Interconvert between the current units and wcs units (degrees)
virtual String format(String &units, Coordinate::formatType format, Double worldValue, uInt axis, Bool isAbsolute, Bool showAsAbsolute, Int precision=-1, Bool usePrecForMixed=False) const
virtual Bool save(RecordInterface &container, const String &fieldName) const
Save the DirectionCoordinate into the supplied record using the supplied field name.
virtual Bool near(const Coordinate &other, Double tol=1e-6) const
Comparison function.
void makeWCS(::wcsprm &wcs, const Matrix< Double > &xform, const Projection &proj, MDirection::Types directionType, Double refPixLong, Double refPixLat, Double refLong, Double refLat, Double incLong, Double incLat, Double longPole, Double latPole)
void makeDirectionCoordinate(MDirection::Types directionType, const Projection &proj, Double refLong, Double refLat, Double incLong, Double incLat, const Matrix< Double > &xform, Double refX, Double refY, Double longPole, Double latPole)
Helper functions interfacing to WCS.
virtual Vector< Double > increment() const
Bool toPixel(Vector< Double > &pixel, const MDirection &world) const
virtual void makeWorldRelative(MDirection &world) const
mutable ::wcsprm wcs_p
WCS structure.
DirectionCoordinate convert(Quantity &angle, MDirection::Types directionType) const
Convert this coordinate to another reference frame by rotating it about the reference pixel so the th...
virtual Bool setIncrement(const Vector< Double > &inc)
MDirection::Types type_p
Direction type.
virtual Vector< Double > referencePixel() const
virtual Bool toPixel(Vector< Double > &pixel, const Vector< Double > &world) const
world values must have units equivalent to the world axis units.
virtual Bool setWorldAxisNames(const Vector< String > &names)
Set the value of the requested attribute.
RotMatrix rot_p
Rotation matrix used to handle relative coordinates.
DirectionCoordinate(MDirection::Types directionType, const ::wcsprm &wcs, Bool oneRel=True)
Constructor from WCS structure; must hold ONLY a celestial wcs structure Specify whether the absolute...
virtual Bool setReferenceValue(const Vector< Double > &refval)
void setProjection(const Projection &)
Set the projection.
Bool cylindricalFix(Int shapeLong, Int shapeLat)
Fix cylindrical coordinates to put the longitude in [-180,180] range.
virtual Matrix< Double > linearTransform() const
virtual Bool toWorld(Vector< Double > &world, const Vector< Double > &pixel, Bool useConversionFrame=True) const
Convert a pixel position to a world position or vice versa.
Projection projection() const
Bool toWorld(MVDirection &world, const Vector< Double > &pixel) const
MVDirection toWorld(const Vector< Double > &pixel) const
Vector< Double > longLatPoles() const
Fish out the ref and non-native poles (refLong, refLat, longPole, latPole) Not for general use.
virtual Bool toMix(Vector< Double > &worldOut, Vector< Double > &pixelOut, const Vector< Double > &worldIn, const Vector< Double > &pixelIn, const Vector< Bool > &worldAxes, const Vector< Bool > &pixelAxes, const Vector< Double > &worldMin, const Vector< Double > &worldMax) const
Mixed pixel/world coordinate conversion.
void setReferenceConversion(MDirection::Types type)
Set extra conversion type.
void getReferenceConversion(MDirection::Types &type) const
void setRotationMatrix()
Set up the offset coordinate rotation matrix.
void setWorldMixRanges(const Vector< Bool > &which, const Vector< Double > &world)
Non-virtual function.
Bool toMix2(Vector< Double > &out, const Vector< Double > &in, const Vector< Double > &minWorld, const Vector< Double > &maxWorld, Bool longIsWorld) const
Mixed pixel/world coordinate conversion.
Bool hasSquarePixels() const
Are the pixels square?
virtual void makeWorldAbsolute(MDirection &world) const
virtual Bool setLinearTransform(const Matrix< Double > &xform)
Double putLongInPiRange(Double lon, const String &unit) const
MDirection::Convert * pConversionMachineTo_p
Conversion machines.
Vector< String > names_p
Axis names.
virtual Coordinate::Type type() const
Return Coordinate::DIRECTION.
virtual String showType() const
Always returns the String "Direction".
DirectionCoordinate(const DirectionCoordinate &other)
Copy constructor (copy semantics)
String formatLongitude(String &units, MVAngle &mVA, MDirection::GlobalTypes gtype, Bool absolute, Coordinate::formatType form, Int prec) const
Format a longitude.
void initializeFactors()
Initialize unit conversion vectors and units.
String formatLatitude(String &units, MVAngle &mVA, Bool absolute, Coordinate::formatType form, Int prec) const
Format a latitude.
static DirectionCoordinate * restore(const RecordInterface &container, const String &fieldName)
Recover the DirectionCoordinate from a record.
virtual void convertFrom(Vector< Double > &world) const
virtual Coordinate * makeFourierCoordinate(const Vector< Bool > &axes, const Vector< Int > &shape) const
Find the Coordinate for when we Fourier Transform ourselves.
void checkFormat(Coordinate::formatType &format, Bool absolute) const
Check formatting types.
void fromCurrent(Vector< Double > &current) const
virtual void getPrecision(Int &precision, Coordinate::formatType &format, Bool showAsAbsolute, Int defPrecScientific, Int defPrecFixed, Int defPrecTime) const
Format a DirectionCoordinate coordinate world value nicely through the common format interface.
MDirection::Convert * pConversionMachineFrom_p
DirectionCoordinate()
The default constructor creates a J2000 DirectionCoordinate with a CARtesion projection with longitud...
Vector< Double > toPixel(const MVDirection &world) const
DirectionCoordinate(MDirection::Types directionType, const Projection &projection, const Quantum< Double > &refLong, const Quantum< Double > &refLat, const Quantum< Double > &incLong, const Quantum< Double > &incLat, const Matrix< Double > &xform, Double refX, Double refY, const Quantum< Double > &longPole=Quantum< Double >(999.0, Unit("rad")), const Quantum< Double > &latPole=Quantum< Double >(999.0, Unit("rad")))
Create DirectionCoordinate with Quantum-based interface.
virtual void makeWorldAbsolute(Vector< Double > &world) const
virtual Bool near(const Coordinate &other, const Vector< Int > &excludeAxes, Double tol=1e-6) const
virtual Bool setReferencePixel(const Vector< Double > &refPix)
DirectionCoordinate(MDirection::Types directionType, const Projection &projection, Double refLong, Double refLat, Double incLong, Double incLat, const Matrix< Double > &xform, Double refX, Double refY, Double longPole=999.0, Double latPole=999.0)
Define the DirectionCoordinate transformation.
void copy(const DirectionCoordinate &other)
Copy private data.
virtual Vector< String > worldAxisUnits() const
void setRotationMatrix(RotMatrix &rot, Double lon, Double lat) const
Bool toPixel(Vector< Double > &pixel, const MVDirection &world) const
Projection projection_p
Projection parameters.
Bool isNCP() const
Is the projection equivalent to NCP?
virtual Bool toPixelMany(Matrix< Double > &pixel, const Matrix< Double > &world, Vector< Bool > &failures) const
Bool toWorld(MDirection &world, const Vector< Double > &pixel) const
A convenient way to turn the world vector into an MDirection or MVDirection for further processing in...
virtual Vector< String > worldAxisNames() const
Return the requested attributed.
const Vector< Double > toCurrentFactors() const
Return unit conversion vector for converting to current units.
virtual void convertTo(Vector< Double > &world) const
Convert from type_p -> conversionType_p.
virtual Bool setWorldMixRanges(const IPosition &shape)
Compute and retrieve the world min and max ranges, for use in function toMix, for a lattice of the gi...
virtual uInt nPixelAxes() const
Always returns 2.
void normalizePCMatrix()
Normalize each row of the PC matrix such that increment() will return the actual angular increment an...
virtual Coordinate * clone() const
Make a copy of the DirectionCoordinate using new.
Vector< Double > toPixel(const MDirection &world) const
Types
Types of known MDirections Warning: The order defines the order in the translation matrix FromTo in ...
Definition: MDirection.h:188
GlobalTypes
Global types.
Definition: MDirection.h:234
String: the storage and methods of handling collections of characters.
Definition: String.h:225
const Double e
e and functions thereof:
this file contains all the compiler specific defines
Definition: mainpage.dox:28
const Bool False
Definition: aipstype.h:44
unsigned int uInt
Definition: aipstype.h:51
TableExprNode shape(const TableExprNode &array)
Function operating on any scalar or array resulting in a Double array containing the shape.
Definition: ExprNode.h:1987
int Int
Definition: aipstype.h:50
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
const Bool True
Definition: aipstype.h:43
double Double
Definition: aipstype.h:55