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
287  virtual ~DirectionCoordinate();
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>
322  {type=conversionType_p;};
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  virtual Bool toPixel(Vector<Double> &pixel,
335  const Vector<Double> &world) const;
336  // </group>
337 
338  // Mixed pixel/world coordinate conversion.
339  // <src>worldIn</src> and <src>worldAxes</src> are of length
340  // nWorldAxes.
341  // <src>pixelIn</src> and <src>pixelAxes</src> are of length nPixelAxes.
342  // <src>worldAxes(i)=True</src> specifies you have given a world
343  // value in <src>worldIn(i)</src> to convert to pixel.
344  // <src>pixelAxes(i)=True</src> specifies you have given a pixel
345  // value in <src>pixelIn(i)</src> to convert to world.
346  // You cannot specify the same axis via <src>worldAxes</src>
347  // and <src>pixelAxes</src>.
348  // Values in <src>pixelIn</src> are converted to world and
349  // put into <src>worldOut</src> in the appropriate world axis
350  // location. Values in <src>worldIn</src> are copied to
351  // <src>worldOut</src>.
352  // Values in <src>worldIn</src> are converted to pixel and
353  // put into <src>pixelOut</src> in the appropriate pixel axis
354  // location. Values in <src>pixelIn</src> are copied to
355  // <src>pixelOut</src>.
356  //
357  // <src>worldMin</src> and <src>worldMax</src> specify the range of the world
358  // coordinate (in the world axis units of that world axis
359  // in the CoordinateSystem) being solved for in a mixed calculation
360  // for each world axis. Some mixed solutions can be degenerate, whereupon you
361  // you must say which one you want. Use functions <src>setWorldMixRanges</src>
362  // and <src>worldMixMin, worldMixMax</src> to set these ranges,
363  // If you don't know, use the defaults (function <src>setDefaultWorldMixRanges</src>.
364  // Removed axes are handled (for example, a removed pixel
365  // axis with remaining corresponding world axis will
366  // correctly be converted to world using the replacement
367  // value).
368  // Returns True if the conversion succeeds, otherwise it returns False and
369  // <src>errorMessage()</src> contains an error message. The output vectors
370  // are resized.
371  //
372  // If you actually request a pure pixel to world or world to pixel
373  // via <src>toMix</src>, then the functions <src>toWorld</src> or <src>toPixel</src>
374  // will be invoked directly (see above) and the extra conversion layer
375  // invoked through function <src>setReferenceConversion</src> will be active.
376  // However, if you request a true mixed pixel/world conversion,
377  // the extra conversion layer is not activated (because of the nature of mixed
378  // conversions). This situation may change in the future
379  // with a partial implementation added.
380  virtual Bool toMix(Vector<Double>& worldOut,
381  Vector<Double>& pixelOut,
382  const Vector<Double>& worldIn,
383  const Vector<Double>& pixelIn,
384  const Vector<Bool>& worldAxes,
385  const Vector<Bool>& pixelAxes,
386  const Vector<Double>& worldMin,
387  const Vector<Double>& worldMax) const;
388 
389  // Compute and retrieve the world min and max ranges, for use in function <src>toMix</src>,
390  // for a lattice of the given shape (for this coordinate). Using these
391  // ranges in <src>toMix</src> should speed it up and help avoid ambiguity.
392  // If the shape is negative, that indicates that the shape is unknown
393  // for that axis. The default range is used for that axis. This situation
394  // arises in a CoordinateSystem for which a pixel, but not a world axis
395  // has been removed.
396  // The output vectors are resized. Returns False if fails (and
397  // then <src>setDefaultWorldMixRanges</src> generates the ranges)
398  // with a reason in <src>errorMessage()</src>.
399  // The <src>setDefaultWorldMixRanges</src> function
400  // just gives you [-90->90], [-180,180] (in appropriate units)
401  // <group>
402  virtual Bool setWorldMixRanges (const IPosition& shape);
403  virtual void setDefaultWorldMixRanges ();
404  // </group>
405 
406  // Non-virtual function. When <src>which</src> is T, use the
407  // world value as the center for the mix world range.
408  void setWorldMixRanges (const Vector<Bool>& which,
409  const Vector<Double>& world);
410 
411  // A convenient way to turn the world vector into an MDirection or MVDirection
412  // for further processing in the Measures system.
413  // <br>We could improve the performance of this if it would be useful. However it is
414  // expected that normally one would just call this once to get a template
415  // MDirection, and then call the vector versions.
416  // <br>In case of a failure, the versions with a Bool return value will return
417  // False. The other versions will throw an exception.
418  // <group>
419  Bool toWorld(MDirection &world, const Vector<Double> &pixel) const;
420  Bool toPixel(Vector<Double> &pixel, const MDirection &world) const;
421  Bool toWorld(MVDirection &world, const Vector<Double> &pixel) const;
422  Bool toPixel(Vector<Double> &pixel, const MVDirection &world) const;
423  MVDirection toWorld(const Vector<Double> &pixel) const;
424  Vector<Double> toPixel(const MVDirection &world) const;
425  Vector<Double> toPixel(const MDirection &world) const;
426  //</group>
427 
428  // Batch up a lot of transformations. The first (most rapidly varying) axis
429  // of the matrices contain the coordinates. Returns False if any conversion
430  // failed and <src>errorMessage()</src> will hold a message.
431  // The <src>failures</src> array is the length of the number of conversions
432  // (True for failure, False for success)
433  // <group>
434  virtual Bool toWorldMany(Matrix<Double> &world,
435  const Matrix<Double> &pixel,
436  Vector<Bool> &failures) const;
437  virtual Bool toPixelMany(Matrix<Double> &pixel,
438  const Matrix<Double> &world,
439  Vector<Bool> &failures) const;
440  // </group>
441 
442 
443  // Make absolute world coordinates relative and vice-versa (relative to
444  // the reference value). Note that these functions are independent
445  // of the MDirection::Types (set either at construction or by function
446  // <src>setReferenceConversion</src>). The vectors must be
447  // of length <src>nWorldAxes</src> or memory access errors will occur
448  //<group>
449  virtual void makeWorldRelative (Vector<Double>& world) const;
450  virtual void makeWorldRelative (MDirection& world) const;
451  virtual void makeWorldAbsolute (Vector<Double>& world) const;
452  virtual void makeWorldAbsolute (MDirection& world) const;
453  //</group>
454 
455  // Make absolute coordinates relative and vice versa with respect
456  // to the given reference value. Add the other functions in this grouping
457  // as needed.
458  //<group>
459  virtual void makeWorldAbsoluteRef (Vector<Double>& world,
460  const Vector<Double>& refVal) const;
461  //</group>
462 
463  // Recover the requested attribute.
464  // <group>
465  MDirection::Types directionType(Bool showConversion=False) const;
466  Projection projection() const;
467  virtual Vector<String> worldAxisNames() const;
468  virtual Vector<String> worldAxisUnits() const;
469  virtual Vector<Double> referenceValue() const;
470  virtual Vector<Double> increment() const;
471  virtual Matrix<Double> linearTransform() const;
472  virtual Vector<Double> referencePixel() const;
473  // </group>
474 
475  // Set the value of the requested attribute. Note that these just
476  // change the internal values, they do not cause any recomputation.
477  // <group>
478  virtual Bool setWorldAxisNames(const Vector<String> &names);
479  virtual Bool setReferencePixel(const Vector<Double> &refPix);
480  virtual Bool setLinearTransform(const Matrix<Double> &xform);
481  virtual Bool setIncrement(const Vector<Double> &inc);
482  virtual Bool setReferenceValue(const Vector<Double> &refval);
483  // </group>
484 
485  // Change the world axis units. Adjust the increment and
486  // reference value by the ratio of the old and new units.
487  // The units must be compatible with
488  // angle. The units are initially "rad" (radians).
489  virtual Bool setWorldAxisUnits(const Vector<String> &units);
490 
491  // Return canonical axis names for the given MDirection type,
492  // giving FITS names if desired.
493  // BEG think this should be in the MDirection class, but WNB
494  // disagrees. Leave it here for now.
496  Bool FITSName = False);
497 
498  // Comparison function. Any private Double data members are compared
499  // with the specified fractional tolerance. Don't compare on the specified
500  // axes in the Coordinate. If the comparison returns False, method
501  // errorMessage returns a message about why.
502  // <group>
503  virtual Bool near(const Coordinate& other,
504  Double tol=1e-6) const;
505  virtual Bool near(const Coordinate& other,
506  const Vector<Int>& excludeAxes,
507  Double tol=1e-6) const;
508  // </group>
509 
510 
511  // Format a DirectionCoordinate coordinate world value nicely through the
512  // common format interface. See <linkto class=Coordinate>Coordinate</linkto>
513  // for basics.
514  //
515  // Formatting types that are allowed are SCIENTIFIC, FIXED, MIXED, and TIME
516  // If you ask for format type Coordinate::DEFAULT then the
517  // selected format depends upon what the value of the enum
518  // MDirection::GlobalTypes is for this DirectionCoordinate.
519  // For example, if it is GRADEC or GHADEC you would
520  // get Coordinate::TIME style formatting (DD:MM:SS.SS), otherwise
521  // you would get Coordinate::FIXED formatting by default.
522  //
523  // <src>axis</src> says which axis in this Coordinate we are formatting.
524  // We have to know this because we may format Longitude and Latitude differently.
525  // For Coordinate::TIME style formatting, precision
526  // refers to the places after the decimal in the SS field.
527  //
528  // If you leave <src>units</src> empty, then it makes up a nice unit for you.
529  //<group>
530  virtual void getPrecision (Int& precision,
532  Bool showAsAbsolute,
533  Int defPrecScientific,
534  Int defPrecFixed,
535  Int defPrecTime) const;
536  virtual String format(String& units,
537  Coordinate::formatType format,
538  Double worldValue,
539  uInt axis,
540  Bool isAbsolute,
541  Bool showAsAbsolute,
542  Int precision=-1, Bool usePrecForMixed=False) const;
543  //</group>
544 
545  // Fix cylindrical coordinates to put the longitude in [-180,180] range.
546  // If False returned, it failed an an error is in <src>errorMessage</src>
547  // This fix is not done automatically internally because of the dependence
548  // on the image shape. It should be called for any foreign image
549  // (such as FITS) that is imported
550  Bool cylindricalFix (Int shapeLong, Int shapeLat);
551 
552  // Find the Coordinate for when we Fourier Transform ourselves. This pointer
553  // must be deleted by the caller. Axes specifies which axes of the Coordinate
554  // you wish to transform. Shape specifies the shape of the image
555  // associated with all the axes of the Coordinate. Currently the
556  // output reference pixel is always shape/2. If the pointer returned is 0,
557  // it failed with a message in <src>errorMessage</src>
558  virtual Coordinate* makeFourierCoordinate (const Vector<Bool>& axes,
559  const Vector<Int>& shape) const;
560 
561  // Save the DirectionCoordinate into the supplied record using the supplied field name.
562  // The field must not exist, otherwise <src>False</src> is returned.
563  virtual Bool save(RecordInterface &container,
564  const String &fieldName) const;
565 
566  // Recover the DirectionCoordinate from a record.
567  // A null pointer means that the restoration did not succeed.
568  static DirectionCoordinate *restore(const RecordInterface &container,
569  const String &fieldName);
570 
571  // Make a copy of the DirectionCoordinate using new. The caller
572  // is responsible for calling delete.
573  virtual Coordinate *clone() const;
574 
575  // Fish out the ref and non-native poles (refLong, refLat, longPole, latPole)
576  // Not for general use. Units are degrees.
578 
579  // get the pixel area.
580  Quantity getPixelArea() const;
581 
582  // Convert this coordinate to another reference frame by rotating it
583  // about the reference pixel so the the axes of the new reference frame
584  // are aligned along the cardinal directions (left-right, up-down).
585  // The reference pixel remains the same and the conversion is
586  // exact for the reference pixel and in general becomes less accurate
587  // as distance from reference pixel increases. The latitude like and
588  // the longitude like pixel increments are preserved.
589  // Conversions for which require extra information such as epoch and
590  // position are not supported. The <src>angle</src> parameter is the angle
591  // through which this coordinate had to be rotated clockwise to produce
592  // the new coordinate.
594  MDirection::Types directionType) const;
595 
596  // Set the projection.
597  void setProjection(const Projection&);
598 
599  // Set the base (as opposed to conversion) reference frame.
600  void setReferenceFrame(const MDirection::Types rf);
601 
602  // Are the pixels square?
603  Bool hasSquarePixels() const;
604 
605  // Is the projection equivalent to NCP?
606  Bool isNCP() const;
607 
608 private:
609  // Direction type
611 
612  // Projection parameters
614 
615  // WCS structure. This is mutable because the wcs functions
616  // that do toPixel and toWorld (which have const signature)
617  // require a non const wcs structure. so either all of these
618  // virtual functions lose their const or we use mutable...
619  mutable ::wcsprm wcs_p;
620 
621  // WCS computes in degrees - use this to convert back and forth between
622  // current DirectionCoordinate units and degrees or radians
623  Vector<Double> to_degrees_p; // From current units to degrees
624  Vector<Double> to_radians_p; // From current units to radians
625 
626  // Axis names.
628 
629  // Current units.
631 
632  // Rotation matrix used to handle relative coordinates
634 
635  // Conversion machines.
636  // "To" handles type_p -> conversionType_p
637  // "From" handles conversionType_p -> type_p;
640 
641  // Interconvert between the current units and wcs units (degrees)
642  // <group>
643  void toCurrent(Vector<Double>& degrees) const;
644  void fromCurrent(Vector<Double>& current) const;
645  // </group>
646 
647  // Check formatting types.
648  void checkFormat(Coordinate::formatType& format,
649  Bool absolute) const;
650 
651  // Format a latitude.
652  String formatLatitude (String& units, MVAngle& mVA,
653  Bool absolute,
655  Int prec) const;
656  // Format a longitude.
657  String formatLongitude (String& units, MVAngle& mVA,
659  Bool absolute,
661  Int prec) const;
662 
663  // Mixed pixel/world coordinate conversion. Vector in must
664  // be length nWorldAxes (2). Specify whether longitude
665  // (in(0)) or latitude (in(1)) is the world coordinate . It is
666  // assumed that the other value is the pixel coordinate.
667  Bool toMix2(Vector<Double>& out, const Vector<Double>& in,
668  const Vector<Double>& minWorld, const Vector<Double>& maxWorld,
669  Bool longIsWorld) const;
670 
671  // Initialize unit conversion vectors and units
672  void initializeFactors ();
673 
674  // Helper functions interfacing to WCS.
675  // <group>
676  void makeDirectionCoordinate(MDirection::Types directionType,
677  const Projection& proj, Double refLong, Double refLat,
678  Double incLong, Double incLat,
679  const Matrix<Double> &xform,
680  Double refX, Double refY,
681  Double longPole, Double latPole);
682 //
683  void makeWCS(::wcsprm& wcs, const Matrix<Double>& xform,
684  const Projection& proj, MDirection::Types directionType,
685  Double refPixLong, Double refPixLat,
686  Double refLong, Double refLat,
687  Double incLong, Double incLat,
688  Double longPole, Double latPole);
689  // </group>
690 
691  // Normalize each row of the PC matrix such that increment() will return the actual
692  // angular increment and any scale factors are removed from the PC matrix
693  // (modifies wcs_p.pc _and_ wcs_p.cdelt _and_ wcs_p.altlin,
694  // executes set_wcs() and hence wcsset() on the struct)
695  // See Greisen & Calabretta, A&A 395, 1061-1075 (2002), equation (4)
696  void normalizePCMatrix();
697 
698  Double putLongInPiRange (Double lon, const String& unit) const;
699 
700  // Set up conversion machine
701  void makeConversionMachines();
702 
703  // Convert from type_p -> conversionType_p
704  // <group>
705  virtual void convertTo (Vector<Double>& world) const;
706  virtual void convertFrom (Vector<Double>& world) const;
707  // </group>
708 
709  // Copy private data
710  void copy (const DirectionCoordinate& other);
711 
712  // Set up the offset coordinate rotation matrix. Units
713  // of long and lat are current world units
714  // <group>
715  void setRotationMatrix ();
716  void setRotationMatrix (RotMatrix& rot, Double lon, Double lat) const;
717  // </group>
718 
719  // Return unit conversion vector for converting to current units
720  const Vector<Double> toCurrentFactors () const;
721 
722  static Double _longitudeDifference(const Quantity& longAngleDifference,
723  const Quantity& latitude,
724  const Quantity& longitudePixelIncrement);
725 };
726 
727 } //# NAMESPACE CASACORE - END
728 
729 
730 #endif
731 
A Vector of integers, for indexing into Array<T> objects.
Definition: IPosition.h:119
A Measure: astronomical direction.
Definition: MDirection.h:174
virtual ~DirectionCoordinate()
Destructor.
int Int
Definition: aipstype.h:50
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 setReferencePixel(const Vector< Double > &refPix)
virtual Coordinate::Type type() const
Return Coordinate::DIRECTION.
void setProjection(const Projection &)
Set the projection.
virtual Vector< Double > referencePixel() const
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)
MDirection::Types directionType(Bool showConversion=False) const
Recover the requested attribute.
virtual void convertTo(Vector< Double > &world) const
Convert from type_p -> conversionType_p.
Geometric parameters needed for a sky projection to a plane.
Definition: Projection.h:95
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.
virtual Bool setWorldAxisUnits(const Vector< String > &units)
Change the world axis units.
DirectionCoordinate & operator=(const DirectionCoordinate &other)
Assignment (copy semantics).
void getReferenceConversion(MDirection::Types &type) const
virtual Bool near(const Coordinate &other, Double tol=1e-6) const
Comparison function.
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 setReferenceFrame(const MDirection::Types rf)
Set the base (as opposed to conversion) reference frame.
virtual Bool toPixelMany(Matrix< Double > &pixel, const Matrix< Double > &world, Vector< Bool > &failures) const
virtual Bool setWorldAxisNames(const Vector< String > &names)
Set the value of the requested attribute.
virtual void makeWorldRelative(Vector< Double > &world) const
Make absolute world coordinates relative and vice-versa (relative to the reference value)...
virtual Vector< Double > increment() const
static Double _longitudeDifference(const Quantity &longAngleDifference, const Quantity &latitude, const Quantity &longitudePixelIncrement)
virtual Matrix< Double > linearTransform() const
MDirection::Convert * pConversionMachineTo_p
Conversion machines.
GlobalTypes
Global types.
Definition: MDirection.h:234
void copy(const DirectionCoordinate &other)
Copy private data.
A 3x3 rotation matrix.
Definition: RotMatrix.h:85
virtual Bool setIncrement(const Vector< Double > &inc)
formatType
This enum is used for formatting world values into Strings.
Definition: Coordinate.h:162
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...
void initializeFactors()
Initialize unit conversion vectors and units.
virtual Coordinate * clone() const
Make a copy of the DirectionCoordinate using new.
MDirection::Types type_p
Direction type.
virtual void makeWorldAbsolute(Vector< Double > &world) const
Types
Types of known MDirections Warning: The order defines the order in the translation matrix FromTo in ...
Definition: MDirection.h:188
defines physical units
Definition: Unit.h:189
void checkFormat(Coordinate::formatType &format, Bool absolute) const
Check formatting types.
Bool cylindricalFix(Int shapeLong, Int shapeLat)
Fix cylindrical coordinates to put the longitude in [-180,180] range.
virtual Bool toPixel(Vector< Double > &pixel, const Vector< Double > &world) const
void normalizePCMatrix()
Normalize each row of the PC matrix such that increment() will return the actual angular increment an...
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.
Projection projection_p
Projection parameters.
Interconvert pixel positions and directions (e.g. RA/DEC).
Interface for converting between world and pixel coordinates.
Definition: Coordinate.h:139
virtual Coordinate * makeFourierCoordinate(const Vector< Bool > &axes, const Vector< Int > &shape) const
Find the Coordinate for when we Fourier Transform ourselves.
const Vector< Double > toCurrentFactors() const
Return unit conversion vector for converting to current units.
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.
Vector< Double > longLatPoles() const
Fish out the ref and non-native poles (refLong, refLat, longPole, latPole) Not for general use...
double Double
Definition: aipstype.h:55
virtual Bool save(RecordInterface &container, const String &fieldName) const
Save the DirectionCoordinate into the supplied record using the supplied field name.
void setRotationMatrix()
Set up the offset coordinate rotation matrix.
String formatLatitude(String &units, MVAngle &mVA, Bool absolute, Coordinate::formatType form, Int prec) const
Format a latitude.
virtual Bool setLinearTransform(const Matrix< Double > &xform)
Quantity getPixelArea() const
get the pixel area.
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
static DirectionCoordinate * restore(const RecordInterface &container, const String &fieldName)
Recover the DirectionCoordinate from a record.
virtual String showType() const
Always returns the String "Direction".
virtual String format(String &units, Coordinate::formatType format, Double worldValue, uInt axis, Bool isAbsolute, Bool showAsAbsolute, Int precision=-1, Bool usePrecForMixed=False) const
void fromCurrent(Vector< Double > &current) const
virtual Bool setReferenceValue(const Vector< Double > &refval)
const Bool False
Definition: aipstype.h:44
virtual Vector< String > worldAxisUnits() const
TableExprNode shape(const TableExprNode &array)
Function operating on any scalar or array resulting in a Double array containing the shape...
Definition: ExprNode.h:2151
Vector< String > names_p
Axis names.
Double putLongInPiRange(Double lon, const String &unit) const
Type
This enum lists the types of the derived classes.
Definition: Coordinate.h:144
virtual Vector< Double > referenceValue() const
Bool hasSquarePixels() const
Are the pixels square?
DirectionCoordinate()
The default constructor creates a J2000 DirectionCoordinate with a CARtesion projection with longitud...
String formatLongitude(String &units, MVAngle &mVA, MDirection::GlobalTypes gtype, Bool absolute, Coordinate::formatType form, Int prec) const
Format a longitude.
const Double e
e and functions thereof:
static Vector< String > axisNames(MDirection::Types type, Bool FITSName=False)
Return canonical axis names for the given MDirection type, giving FITS names if desired.
virtual uInt nWorldAxes() const
void makeConversionMachines()
Set up conversion machine.
Vector< Double > to_degrees_p
WCS computes in degrees - use this to convert back and forth between current DirectionCoordinate unit...
virtual void setDefaultWorldMixRanges()
void setReferenceConversion(MDirection::Types type)
Set extra conversion type.
String: the storage and methods of handling collections of characters.
Definition: String.h:223
Vector of three direction cosines.
Definition: MVDirection.h:106
virtual Bool toWorldMany(Matrix< Double > &world, const Matrix< Double > &pixel, Vector< Bool > &failures) const
Batch up a lot of transformations.
Abstract base class for Record classes.
void toCurrent(Vector< Double > &degrees) const
Interconvert between the current units and wcs units (degrees)
virtual void convertFrom(Vector< Double > &world) const
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...
Vector< String > units_p
Current units.
Class to handle angle type conversions and I/O.
Definition: MVAngle.h:245
MDirection::Convert * pConversionMachineFrom_p
const Bool True
Definition: aipstype.h:43
this file contains all the compiler specific defines
Definition: mainpage.dox:28
mutable ::wcsprm wcs_p
WCS structure.
Bool isNCP() const
Is the projection equivalent to NCP?
virtual uInt nPixelAxes() const
Always returns 2.
RotMatrix rot_p
Rotation matrix used to handle relative coordinates.
Projection projection() 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...
unsigned int uInt
Definition: aipstype.h:51
virtual Vector< String > worldAxisNames() const
Return the requested attributed.