casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Coordinate.h
Go to the documentation of this file.
00001 //# Coordinate.h: Interface for converting between world and pixel coordinates
00002 //# Copyright (C) 1997,1999,2000,2001,2002,2003,2004
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //#
00027 //# $Id: Coordinate.h 20652 2009-07-06 05:04:32Z Malte.Marquarding $
00028 
00029 
00030 #ifndef COORDINATES_COORDINATE_H
00031 #define COORDINATES_COORDINATE_H
00032 
00033 #include <casa/aips.h>
00034 #include <casa/BasicSL/String.h>
00035 #include <casa/Arrays/Vector.h>
00036 #include <wcslib/wcs.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 
00041 template<class T> class Quantum;
00042 template<class T> class Matrix;
00043 class IPosition;
00044 class RecordInterface;
00045 class Projection;
00046 
00047 // <summary>
00048 // Interface for converting between world and pixel coordinates.
00049 // </summary>
00050 
00051 // <use visibility=export>
00052 
00053 // <reviewed reviewer="Peter Barnes" date="1999/12/24">
00054 // </reviewed>
00055 
00056 // <prerequisite>
00057 //   <li> Knowledge of astronomical coordinate conversions in general. Probably the
00058 //        best documents are the papers by Mark Calabretta and Eric Greisen.
00059 //        The initial draft from 1996 can be found at
00060 //        http://www.atnf.csiro.au/~mcalabre.  It is this draft that the
00061 //        Coordinate classes are based upon.  Since then, this paper has evolved
00062 //        into three which can be found at the above address, and will be published in the
00063 //        Astronomy and Astrophysics Supplement Series (probably in 2000).
00064 //        The design has changed since the initial draft.  When these papers
00065 //        are finalized, and the IAU has ratified the new standards, WCSLIB
00066 //        (Mark Calabretta's implementation of these conventions) will be
00067 //        revised for the new designs.  At that time, the Coordinate classes
00068 //        may also be revised.
00069 //   <li> Generic AIPS++ classes; especially those in the 
00070 //        <linkto module=Arrays>Arrays</linkto> module.
00071 //   <li> Perhaps some of the information in the
00072 //        <linkto module=Measures>Measures</linkto> module.
00073 // </prerequisite>
00074 //
00075 // <synopsis>
00076 // The Coordinate class defines the generic interface whereby a pixel position
00077 // is converted to a world (sky, frequency, stokes, ...) position and vice
00078 // versa. The pixel and world coordinates are in general
00079 // multi-dimensional values. In general there need not be the same number of
00080 // pixel and world axes, although this will normally be the case.
00081 //
00082 // The fundamental model is that a pixel is first converted into a relative
00083 // physical coordinate by:
00084 // <ol>
00085 //    <li> Subtracting a reference pixel value from the pixel location; then
00086 //    <li> Multiplying this offset by a general transformation matrix (usually
00087 //         to account for rotation, but any matrix is allowed); then
00088 //    <li> Multiplying this product by an increment in physical units.
00089 // </ol>
00090 // After this linear stage, the final coordinate value is computed from this
00091 // relative physical unit and a reference value, and possibly some other 
00092 // parameters. In the case of a sky position, these latter include at least the
00093 // projection type. In the case of a purely linear coordinate, the reference value
00094 // is merely added to the relative physical coordinate. The interface also
00095 // allows the axes to be assigned names (reasonable defaults will be selected),
00096 // and for physical units.
00097 // 
00098 // Both absolute and relative coordinates are supported.  The main
00099 // interface supports conversion between absolute pixel
00100 // and absolute world coordinate.  There are then functions to
00101 // convert absolute coordinates to relative and vice versa.
00102 // A relative pixel coordinate is defined according to 
00103 // 
00104 // relative = absolute - reference
00105 //
00106 // A relative world coordinate is similar, although there may
00107 // be deviations from this formula (e.g. for DirectionCoordinate
00108 // a cos(latitude) term is incorporated and for StokesCoordinate
00109 // relative world coordinates  are defined to be the same as
00110 // absolute world coordinates.
00111 //
00112 // </synopsis>
00113 //
00114 // <note role=caution>
00115 // All absolute pixels coordinates are zero relative.
00116 // </note>
00117 //
00118 // <example>
00119 // This is a base class so there is no direct example, but
00120 // see the example in <linkto module=Coordinates>Coordinates.h</linkto>
00121 // for use of the derived classes.
00122 // </example>
00123 //
00124 // <motivation>
00125 // Encapsulate the common interface to coordinate conversion so that it may
00126 // be used polymorphically.
00127 // </motivation>
00128 //
00129 // <thrown>
00130 //   <li>  AipsError
00131 //   <li>  AllocError
00132 // </thrown>
00133 //
00134 // <todo asof="1997/1/13">
00135 //   <li> Perhaps common FITS related interfaces should go in this class.
00136 // </todo>
00137 //
00138 
00139 class Coordinate
00140 {
00141 public:
00142     // This enum lists the types of the derived classes. It is primarly used
00143     // in the CoordinateSystem class.
00144     enum Type { 
00145         // Linear axes.
00146         LINEAR, 
00147         // A direction. Usually RA/DEC.
00148         DIRECTION, 
00149         // A spectral axis.
00150         SPECTRAL, 
00151         // A Stokes axis.
00152         STOKES, 
00153         // A one-dimensional Cooordinate system, usually created from a table
00154         // although it can also be purely linear.
00155         TABULAR,
00156         // to mark DATA and ERROR values
00157         QUALITY,
00158         // A CoordinateSystem (a collection of Coordinates).
00159         COORDSYS };
00160 
00161     // This enum is used for formatting world values into Strings
00162     enum formatType {
00163        // Default; formatter decides
00164        DEFAULT,
00165        // Scientific format (e.g. -1.2397E+03)
00166        SCIENTIFIC,
00167        // Fixed floating format (e.g. 12.134)
00168        FIXED,
00169        // Either scientific or floating point, auto-selected by the C++
00170        // STL formatting routines.  May not be available for all Coordinate
00171        // types.
00172        MIXED,
00173        // HHH:MM:SS.SSS style formatting
00174        TIME };
00175 
00176     // Destructor.  Needs to be public so the user can delete Coordinate* objects
00177     virtual ~Coordinate();
00178 
00179     // List the type of this Coordinate object. 
00180     // <group>
00181     virtual Type type() const = 0;
00182     virtual String showType() const = 0;
00183     static String typeToString (Coordinate::Type type);
00184     // </group>
00185 
00186     // How many world/pixel axes are there in this Coordinate? While the number
00187     // of world and pixel axes will generally be the same, it is not a 
00188     // requirement. For example, in CoordinateSystem you could remove a pixel
00189     // axis and leave the corresponding world axis. Also, if we ever implement
00190     // a "SlicedCoordinate" class then there would be more world than pixel
00191     // coordinates (the pixel coordinate would be a pixel number along the slice,
00192     // whereas the world axes would continue to be RA/DEC).
00193     // <group>
00194     virtual uInt nPixelAxes() const = 0;
00195     virtual uInt nWorldAxes() const = 0;
00196     // </group>
00197 
00198     // Convert an absolute pixel position to an absolute world position or vice 
00199     // versa. Returns True
00200     // if the conversion succeeds, otherwise it returns False and method
00201     // errorMessage contains an error message. The input vector must be of length
00202     // <src>nPixelAxes</src> or <src>nWorldAxes</src>.  The output vector
00203     // is resized appropriately.
00204     // <group>
00205     virtual Bool toWorld(Vector<Double> &world, 
00206                          const Vector<Double> &pixel) const = 0;
00207     virtual Bool toPixel(Vector<Double> &pixel, 
00208                          const Vector<Double> &world) const = 0;
00209     // </group>
00210 
00211     // Mixed absolute pixel/world coordinate conversion.
00212     // worldIn and worldAxes are vectors of length <src>nWorldAxes</src>.
00213     // <src>pixelIn</src> and <src>pixelAxes</src> are of length <src>nPixelAxes</src>.
00214     // <src>worldAxes(i) = True</src> specifies you have given a world
00215     // value in <src>worldIn(i)</src> to convert to pixel.
00216     // <src>pixelAxes(i)=True</src> specifies you have given a pixel 
00217     // value in <src>pixelIn(i)</src> to convert to world.
00218     // You cannot specify the same axis via <src>worldAxes</src>
00219     // and <src>pixelAxes</src>.
00220     // Values in <src>pixelIn</src> are converted to world and
00221     // put into <src>worldOut</src> in the appropriate world axis
00222     // location.  Values in <src>worldIn</src> are copied to
00223     // <src>worldOut</src>.
00224     // Values in <src>worldIn</src> are converted to pixel and
00225     // put into <src>pixelOut</src> in the appropriate pixel axis
00226     // location.  Values in <src>pixelIn</src> are copied to
00227     // <src>pixelOut</src>.
00228     // <src>worldMin</src> and <src>worldMax</src> specify the range of the world
00229     // coordinate (in the world axis units of that world axis
00230     // in the CoordinateSystem) being solved for in a mixed calculation
00231     // for each world axis. They are only actually needed for DirectionCoordinates
00232     // and for all other Coordinates the relevant elements   
00233     // can be undefined.   If you don't know, use -180 to 180
00234     // degrees for longitude, and -90 to 90 for latitude.
00235     // Removed axes are handled (for example, a removed pixel
00236     // axis with remaining corresponding world axis will
00237     // correctly be converted to world using the replacement
00238     // value).
00239     // Returns True if the conversion succeeds, otherwise it returns False and
00240     // <src>errorMessage()</src> contains an error message. The output vectors
00241     // are resized.
00242     virtual Bool toMix(Vector<Double>& worldOut,
00243                        Vector<Double>& pixelOut,
00244                        const Vector<Double>& worldIn,
00245                        const Vector<Double>& pixelIn,
00246                        const Vector<Bool>& worldAxes,   
00247                        const Vector<Bool>& pixelAxes,
00248                        const Vector<Double>& worldMin,
00249                        const Vector<Double>& worldMax) const;
00250 
00251     // Set the world min and max ranges, for use in function <src>toMix</src>, for 
00252     // a lattice of the given shape for this coordinate. The default implementation
00253     // here sets the range for pixels dangling 25% off the image.
00254     // Returns False if fails with a reason  in <src>errorMessage()</src>.
00255     // setDefaultWorldMixRanges sets the range for each axis to +/-1e99
00256     // The ranges remain zero length vectors until you explicitly
00257     // initialize them.
00258     // <group>
00259     virtual Bool setWorldMixRanges (const IPosition& shape);
00260     virtual void setDefaultWorldMixRanges ();
00261     Vector<Double> worldMixMin () const {return worldMin_p;};
00262     Vector<Double> worldMixMax () const {return worldMax_p;};
00263     //</group>
00264 
00265 
00266     // Batch up a lot of transformations. The first (most rapidly varying) axis
00267     // of the matrices contain the coordinates. Returns False if any conversion
00268     // failed  and  <src>errorMessage()</src> will hold a message.
00269     // The <src>failures</src> array (True for fail, False for success)
00270     // is the length of the number of conversions and
00271     // holds an error status for each conversion.  The default
00272     // implementation is provided that works with the "single" version of
00273     // <src>toWorld</src> and <src>toPixel</src>, but for maximum efficiency these should be
00274     // overridden.
00275     // <group>
00276     virtual Bool toWorldMany(Matrix<Double>& world, 
00277                              const Matrix<Double>& pixel, 
00278                              Vector<Bool>& failures) const;
00279     virtual Bool toPixelMany(Matrix<Double>& pixel, 
00280                              const Matrix<Double>& world, 
00281                              Vector<Bool>& failures) const;
00282     // </group>
00283 
00284     // Make absolute coordinates relative and vice-versa (with
00285     // respect to the reference value).
00286     // Vectors must be length <src>nPixelAxes()</src> or
00287     // <src>nWorldAxes()</src> or memory access errors will occur
00288     // <group>
00289     virtual void makePixelRelative (Vector<Double>& pixel) const;
00290     virtual void makePixelAbsolute (Vector<Double>& pixel) const;
00291     virtual void makeWorldRelative (Vector<Double>& world) const;
00292     virtual void makeWorldAbsolute (Vector<Double>& world) const;
00293     // </group>
00294 
00295     // Make absolute coordinates relative and vice versa with respect
00296     // to the given reference value.  Add the other functions in this grouping
00297     // as needed. Vectors must be length <src>nPixelAxes()</src> or
00298     // <src>nWorldAxes()</src> or memory access errors will occur
00299     // <group>
00300     virtual void makeWorldAbsoluteRef (Vector<Double>& world,
00301                                        const Vector<Double>& refVal) const;
00302     // </group>
00303 
00304 
00305     // Batch up a lot of absolute/relative transformations. 
00306     // Parameters as above  for 
00307     // <src>toWorldMany</src> and <src>toPixelMany</src>
00308     // <group>
00309     virtual void makePixelRelativeMany (Matrix<Double>& pixel) const;
00310     virtual void makePixelAbsoluteMany (Matrix<Double>& pixel) const;
00311     virtual void makeWorldRelativeMany (Matrix<Double>& world) const;
00312     virtual void makeWorldAbsoluteMany (Matrix<Double>& world) const;
00313     // </group>
00314 
00315 
00316     // Return the requested attributed.
00317     // <group>
00318     virtual Vector<String> worldAxisNames() const = 0;
00319     virtual Vector<Double> referencePixel() const = 0;
00320     virtual Matrix<Double> linearTransform() const = 0;
00321     virtual Vector<Double> increment() const = 0;
00322     virtual Vector<Double> referenceValue() const = 0;
00323     virtual Vector<String> worldAxisUnits() const = 0;
00324     // </group>
00325 
00326     // Set the requested attribute.  Note that these just
00327     // change the internal values, they do not cause any recomputation.
00328     // <group>
00329     virtual Bool setWorldAxisNames(const Vector<String> &names) = 0;
00330     virtual Bool setReferencePixel(const Vector<Double> &refPix) = 0;
00331     virtual Bool setLinearTransform(const Matrix<Double> &xform) = 0;
00332     virtual Bool setIncrement(const Vector<Double> &inc)  = 0;
00333     virtual Bool setReferenceValue(const Vector<Double> &refval)  = 0;
00334     // </group>
00335 
00336     // Change the units. Adjust the increment and
00337     // reference value by the ratio of the old and new units. This implies that
00338     // the units must be known <linkto class=Unit>Unit</linkto> strings, and that
00339     // they must be compatible, e.g. they can't change from time to length.
00340     //
00341     // A default implementation is available which does everything except set
00342     // the units vector, which must be done in the derived class.
00343     virtual Bool setWorldAxisUnits(const Vector<String> &units) = 0;
00344 
00345     // Find the Coordinate for when we Fourier Transform ourselves.  This pointer 
00346     // must be deleted by the caller. Axes specifies which axes of the Coordinate
00347     // you wish to transform.   Shape specifies the shape of the image
00348     // associated with all the axes of the Coordinate. Currently the
00349     // output reference pixel is always shape/2.
00350     virtual Coordinate* makeFourierCoordinate (const Vector<Bool>& axes,
00351                                                const Vector<Int>& shape) const;
00352 
00353     // If the last conversion to world or pixel coordinates resulted in an
00354     // error, report that error. If the last conversion succeeded, it is
00355     // undefined what this will return (it might well contain the last error
00356     // message).
00357     const String& errorMessage() const;
00358 
00359     // Comparison to fractional tolerance (for floating point values). 
00360     // Don't compare on specified axes in Coordinate. If the comparison
00361     // returns False, <src>errorMessage()</src> contains a message.
00362     // <group>
00363     virtual Bool near(const Coordinate& other, 
00364                       Double tol=1.0e-6) const = 0;
00365     virtual Bool near(const Coordinate& other, 
00366                       const Vector<Int>& excludeAxes,
00367                       Double tol=1.0e-6) const = 0;
00368     // </group>
00369 
00370 
00371     // Provide a common interface to getting formatted representations of
00372     // coordinate values.    Different derived Coordinate types are formatted
00373     // in different ways.  For example, an RA/DEC  DirectionCoordinate
00374     // uses an HMS.SS/DMS.SS representation. A Galactic Lat/Long DirectionCoordinate
00375     // uses floating format in degrees.  Other derived Coordinates are formatted with 
00376     // scientific format or floating format. The derived class format functions
00377     // provide this functionality.   
00378     // 
00379     // You may specify the format with the format argument and a value
00380     // from the enum <src>Coordinate::formatType</src>. If you give it the value 
00381     // <src>Coordinate::DEFAULT</src> then a sensible default is used.
00382     //
00383     // A mechanism for specifying the precision number of significant digits after 
00384     // decimal point is provided.  You can specify the precision directly when 
00385     // calling format if it is unambiguous how the derived Coordinate is 
00386     // going to be formatted.  For example, a LinearCoordinate is always formatted with 
00387     // scientific format.  However, if you are using these classes polymorphically, you 
00388     // don't want to have to know this and some derived Coordinates may be formatted
00389     // in multiple ways (such as the DirectionCoordinate examples above).
00390     // Therefore, the function getPrecision enables 
00391     // you to set default precisions for the different styles of formatting 
00392     // used variously in the base and derived classes.   This function chooses the 
00393     // precision from these default values, according to the type of derived 
00394     // Coordinate that your object is and what value for format that
00395     // you give (refer to the derived classes for details on this).
00396     // 
00397     // Some derived classes will format differently depending upon whether
00398     // you want to format an absolute or offset world value input via 
00399     // absolute (e.g. DirectionCoordinates).
00400     // 
00401     // The provided <src>worldValue</src> must be in the native units
00402     // of the Coordinate.  It may be an absolute (<src>isAbsolute=True</src>)
00403     // or relative (<src>isAbsolute=False</src>) value.   You may choose to
00404     // format the world value as absolute (<src>showAsAbsolute=True</src>) or
00405     // relative (<src>showAsAbsolute=False</src>).  <src>axis</src>
00406     // specifies which axis of the Coordinate this value belongs to.
00407     //
00408     // <src>units</src> specifies the units in which the input world value
00409     // will be formatted.  
00410     // If <src>units</src> is empty, the native unit for the given axis 
00411     // is used.
00412     //
00413     // Some derived classes will format in units different from the 
00414     // native unit of the Coordinate. The units of
00415     // the formatted number are returned in <src>units</src>.
00416     // If the <src>units</src> string is provided, the unit must be
00417     // consistent with the native unit of the coordinate.  The input
00418     // world value will be converted to this unit.
00419     //
00420     // You can also use the Quantum interface.  The units of the Quantum 
00421     // can then be anything  consistent with the Coordinate.
00422     // 
00423     // The default implementation here is to format only
00424     // with scientific or fixed formats. If precision is negative, a 
00425     // the default precision is used.
00426     //
00427     //<group>
00428     virtual void getPrecision(Int &precision,
00429                               Coordinate::formatType& format,
00430                               Bool showAsAbsolute,
00431                               Int defPrecScientific,
00432                               Int defPrecFixed,
00433                               Int defPrecTime) const;
00434     virtual String format(
00435         String& units,
00436         Coordinate::formatType format,
00437         Double worldValue,
00438         uInt axis,
00439         Bool isAbsolute=True,
00440         Bool showAsAbsolute=True,
00441         Int precision=-1,
00442         Bool usePrecForMixed=False
00443     ) const;
00444 
00445     String formatQuantity(String& units,
00446                           Coordinate::formatType format, 
00447                           const Quantum<Double>& worldValue, 
00448                           uInt axis, 
00449                           Bool isAbsolute=True,
00450                           Bool showAsAbsolute=True,
00451                           Int precision=-1);
00452     //</group>
00453 
00454     // Used for persistence. Derived classes will have similar static
00455     // restore methods. It will typically only return False if fieldName
00456     // has already been defined.
00457     virtual Bool save(RecordInterface &container,
00458                     const String &fieldName) const = 0;
00459 
00460     // Make a copy of ourself. This pointer has been allocated with
00461     // <src>new</src> and must be deleted by the caller.
00462     virtual Coordinate *clone() const = 0;
00463 
00464     // Comparison only made for specified axes in this and other Coordinate 
00465     // The default implementation should be ok for all Coordinate types
00466     // except Stokes and Quality...
00467     virtual Bool doNearPixel (const Coordinate& other, 
00468                               const Vector<Bool>&  thisAxes,
00469                               const Vector<Bool>& otherAxes,
00470                               Double tol=1.0e-6) const;
00471 
00472     // return the result of rotating the coordinate clockwise through the specified angle.
00473     // Rotation occurs about the reference pixel.
00474     // Coordinate must have exactly two pixel axes. The return type is the same
00475     // as the input type. It is the caller's responsibility to delete the returned pointer
00476     // when done with it to prevent a memory leak.
00477     // This method ultimately just changes the input coordinate's linear transform matrix.
00478     virtual Coordinate* rotate(const Quantum<Double>& angle) const;
00479 
00480 protected:
00481     // Default constructor. Make an empty coordinate.  Used by derived classes.
00482     Coordinate();
00483 
00484     // Copy constructor (copy semantics)
00485     Coordinate(const Coordinate& other);
00486 
00487     // Assignment (copy semantics) 
00488     Coordinate& operator=(const Coordinate& other);
00489 
00490     // Set error message
00491     void set_error(const String &errorMsg) const;
00492 
00493     //
00494     Bool find_scale_factor(String &error, Vector<Double> &factor, 
00495                            const Vector<String> &units, 
00496                            const Vector<String> &oldUnits);
00497 
00498 
00499     // Tries to find a canonical unit for input unit (e.g.  GHz -> Hz), and
00500     // tells you the output name and unit for the Fourier coordinate 
00501     // pairing with the canonical unit
00502     void fourierUnits (String& nameOut, String& unitOut, String& unitInCanon,
00503                        Coordinate::Type type, Int axis, 
00504                        const String& unitIn, 
00505                        const String& nameIn) const;
00506 
00507    // Functions to interconvert pixel<->world via wcs.  These functions are called 
00508    // explicitly by the to{world,Pixel} functions in the appropriate wcs-based derived
00509    // classes. 
00510    // <group>
00511    Bool toWorldWCS (Vector<Double> &world, const Vector<Double> &pixel, wcsprm& wcs) const;
00512    Bool toPixelWCS(Vector<Double> &pixel,  const Vector<Double> &world, wcsprm& wcs) const;
00513    Bool toWorldManyWCS (Matrix<Double>& world, const Matrix<Double>& pixel,
00514                         Vector<Bool>& failures, wcsprm& wcs) const;
00515    Bool toPixelManyWCS (Matrix<Double>& pixel, const Matrix<Double>& world,
00516                         Vector<Bool>& failures, wcsprm& wcs) const;
00517 
00518    // Functions for handling conversion between the current units and
00519    // the wcs units. These are called explicitly by the appropriate 
00520    // derived class.
00521    // <src>convertFrom</src>
00522    // <group>
00523    void toCurrentMany (Matrix<Double>& world, const Vector<Double>& toCurrentFactors) const;
00524    void fromCurrentMany(Matrix<Double>& world, const Vector<Double>& toCurrentFactors) const;
00525    // </group>
00526 
00527 
00528    // Functions for handling conversion between the current reference frame 
00529    // and the native one. The default implementations do nothing.  They
00530    // should be over-ridden in the derived classes.
00531    // <group>
00532    virtual void convertTo (Vector<Double>&) const
00533      {}
00534    virtual void convertFrom (Vector<Double>&) const
00535      {}
00536    // </group>
00537 
00538    // Functions for handling conversion between the current reference frame 
00539    // and the native one for many conversions.  These functions just
00540    // call the virtual functions for single conversions.
00541    // <group>
00542    void convertToMany (Matrix<Double>& world) const;
00543    void convertFromMany (Matrix<Double>& world) const;
00544    // </group>
00545 
00546    // Interconvert between wcs PC cards and Matrix xForm format 
00547    void pcToXform (Matrix<Double>& xForm, const wcsprm& wcs) const;
00548    void xFormToPC (wcsprm& wcs, const Matrix<Double>& xForm) const;
00549    // </group>
00550 
00551    // Call wcsset on the wcs structure
00552    void set_wcs (wcsprm& wcs);
00553 
00554     // toMix ranges.  Should be set by derived class.
00555     Vector<Double> worldMin_p, worldMax_p;
00556 
00557 private:
00558     mutable String error_p;
00559 
00560     // Check format type
00561     void checkFormat(Coordinate::formatType& format,         
00562                      const Bool absolute) const;
00563 
00564     void makeWorldAbsRelMany (Matrix<Double>& value, Bool toAbs) const; 
00565     void makePixelAbsRelMany (Matrix<Double>& value, Bool toAbs) const; 
00566 
00567 
00568 };
00569 
00570 //###### Inlines
00571 
00572 inline const String& Coordinate::errorMessage() const
00573 {
00574     return error_p;
00575 }
00576 
00577 } //# NAMESPACE CASA - END
00578 
00579 #endif