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