This file is indexed.

/usr/include/casacore/coordinates/Coordinates/Coordinate.h is in casacore-dev 2.2.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
//# Coordinate.h: Interface for converting between world and pixel coordinates
//# Copyright (C) 1997,1999,2000,2001,2002,2003,2004
//# Associated Universities, Inc. Washington DC, USA.
//#
//# This library is free software; you can redistribute it and/or modify it
//# under the terms of the GNU Library General Public License as published by
//# the Free Software Foundation; either version 2 of the License, or (at your
//# option) any later version.
//#
//# This library is distributed in the hope that it will be useful, but WITHOUT
//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
//# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
//# License for more details.
//#
//# You should have received a copy of the GNU Library General Public License
//# along with this library; if not, write to the Free Software Foundation,
//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
//#
//# Correspondence concerning AIPS++ should be addressed as follows:
//#        Internet email: aips2-request@nrao.edu.
//#        Postal address: AIPS++ Project Office
//#                        National Radio Astronomy Observatory
//#                        520 Edgemont Road
//#                        Charlottesville, VA 22903-2475 USA
//#
//#
//# $Id$


#ifndef COORDINATES_COORDINATE_H
#define COORDINATES_COORDINATE_H

#include <casacore/casa/aips.h>
#include <casacore/casa/BasicSL/String.h>
#include <casacore/casa/Arrays/Vector.h>
#include <wcslib/wcs.h>

namespace casacore { //# NAMESPACE CASACORE - BEGIN


template<class T> class Quantum;
template<class T> class Matrix;
class IPosition;
class RecordInterface;
class Projection;

// <summary>
// Interface for converting between world and pixel coordinates.
// </summary>

// <use visibility=export>

// <reviewed reviewer="Peter Barnes" date="1999/12/24">
// </reviewed>

// <prerequisite>
//   <li> Knowledge of astronomical coordinate conversions in general. Probably the
//        best documents are the papers by Mark Calabretta and Eric Greisen.
//        The initial draft from 1996 can be found at
//        http://www.atnf.csiro.au/~mcalabre.  It is this draft that the
//        Coordinate classes are based upon.  Since then, this paper has evolved
//        into three which can be found at the above address, and will be published in the
//        Astronomy and Astrophysics Supplement Series (probably in 2000).
//        The design has changed since the initial draft.  When these papers
//        are finalized, and the IAU has ratified the new standards, WCSLIB
//        (Mark Calabretta's implementation of these conventions) will be
//        revised for the new designs.  At that time, the Coordinate classes
//        may also be revised.
//   <li> Generic Casacore classes; especially those in the 
//        <linkto module=Arrays>Arrays</linkto> module.
//   <li> Perhaps some of the information in the
//        <linkto module=Measures>Measures</linkto> module.
// </prerequisite>
//
// <synopsis>
// The Coordinate class defines the generic interface whereby a pixel position
// is converted to a world (sky, frequency, stokes, ...) position and vice
// versa. The pixel and world coordinates are in general
// multi-dimensional values. In general there need not be the same number of
// pixel and world axes, although this will normally be the case.
//
// The fundamental model is that a pixel is first converted into a relative
// physical coordinate by:
// <ol>
//    <li> Subtracting a reference pixel value from the pixel location; then
//    <li> Multiplying this offset by a general transformation matrix (usually
//         to account for rotation, but any matrix is allowed); then
//    <li> Multiplying this product by an increment in physical units.
// </ol>
// After this linear stage, the final coordinate value is computed from this
// relative physical unit and a reference value, and possibly some other 
// parameters. In the case of a sky position, these latter include at least the
// projection type. In the case of a purely linear coordinate, the reference value
// is merely added to the relative physical coordinate. The interface also
// allows the axes to be assigned names (reasonable defaults will be selected),
// and for physical units.
// 
// Both absolute and relative coordinates are supported.  The main
// interface supports conversion between absolute pixel
// and absolute world coordinate.  There are then functions to
// convert absolute coordinates to relative and vice versa.
// A relative pixel coordinate is defined according to 
// 
// relative = absolute - reference
//
// A relative world coordinate is similar, although there may
// be deviations from this formula (e.g. for DirectionCoordinate
// a cos(latitude) term is incorporated and for StokesCoordinate
// relative world coordinates  are defined to be the same as
// absolute world coordinates.
//
// </synopsis>
//
// <note role=caution>
// All absolute pixels coordinates are zero relative.
// </note>
//
// <example>
// This is a base class so there is no direct example, but
// see the example in <linkto module=Coordinates>Coordinates.h</linkto>
// for use of the derived classes.
// </example>
//
// <motivation>
// Encapsulate the common interface to coordinate conversion so that it may
// be used polymorphically.
// </motivation>
//
// <thrown>
//   <li>  AipsError
//   <li>  AllocError
// </thrown>
//
// <todo asof="1997/1/13">
//   <li> Perhaps common FITS related interfaces should go in this class.
// </todo>
//

class Coordinate
{
public:
    // This enum lists the types of the derived classes. It is primarly used
    // in the CoordinateSystem class.
    enum Type { 
	// Linear axes.
	LINEAR, 
	// A direction. Usually RA/DEC.
	DIRECTION, 
	// A spectral axis.
	SPECTRAL, 
	// A Stokes axis.
	STOKES, 
	// A one-dimensional Cooordinate system, usually created from a table
        // although it can also be purely linear.
	TABULAR,
	// to mark DATA and ERROR values
	QUALITY,
	// A CoordinateSystem (a collection of Coordinates).
	COORDSYS };

    // This enum is used for formatting world values into Strings
    enum formatType {
       // Default; formatter decides
       DEFAULT,
       // Scientific format (e.g. -1.2397E+03)
       SCIENTIFIC,
       // Fixed floating format (e.g. 12.134)
       FIXED,
       // Either scientific or floating point, auto-selected by the C++
       // STL formatting routines.  May not be available for all Coordinate
       // types.
       MIXED,
       // HHH:MM:SS.SSS style formatting
       TIME };

    // Destructor.  Needs to be public so the user can delete Coordinate* objects
    virtual ~Coordinate();

    // List the type of this Coordinate object. 
    // <group>
    virtual Type type() const = 0;
    virtual String showType() const = 0;
    static String typeToString (Coordinate::Type type);
    // </group>

    // How many world/pixel axes are there in this Coordinate? While the number
    // of world and pixel axes will generally be the same, it is not a 
    // requirement. For example, in CoordinateSystem you could remove a pixel
    // axis and leave the corresponding world axis. Also, if we ever implement
    // a "SlicedCoordinate" class then there would be more world than pixel
    // coordinates (the pixel coordinate would be a pixel number along the slice,
    // whereas the world axes would continue to be RA/DEC).
    // <group>
    virtual uInt nPixelAxes() const = 0;
    virtual uInt nWorldAxes() const = 0;
    // </group>

    // Convert an absolute pixel position to an absolute world position or vice 
    // versa. Returns True
    // if the conversion succeeds, otherwise it returns False and method
    // errorMessage contains an error message. The input vector must be of length
    // <src>nPixelAxes</src> or <src>nWorldAxes</src>.  The output vector
    // is resized appropriately.
    // if <src>useConversionFrame</src>, if the coordinate has a conversion layer frame
    // (such as can be present in spectral and direction coordinates), it
    // is used. Else, the native frame is used for the conversion.
    // <group>
    virtual Bool toWorld(Vector<Double> &world, 
			 const Vector<Double> &pixel, Bool useConversionFrame=True) const = 0;
    virtual Bool toPixel(Vector<Double> &pixel, 
			 const Vector<Double> &world) const = 0;
    // </group>

    // Mixed absolute pixel/world coordinate conversion.
    // worldIn and worldAxes are vectors of length <src>nWorldAxes</src>.
    // <src>pixelIn</src> and <src>pixelAxes</src> are of length <src>nPixelAxes</src>.
    // <src>worldAxes(i) = True</src> specifies you have given a world
    // value in <src>worldIn(i)</src> to convert to pixel.
    // <src>pixelAxes(i)=True</src> specifies you have given a pixel 
    // value in <src>pixelIn(i)</src> to convert to world.
    // You cannot specify the same axis via <src>worldAxes</src>
    // and <src>pixelAxes</src>.
    // Values in <src>pixelIn</src> are converted to world and
    // put into <src>worldOut</src> in the appropriate world axis
    // location.  Values in <src>worldIn</src> are copied to
    // <src>worldOut</src>.
    // Values in <src>worldIn</src> are converted to pixel and
    // put into <src>pixelOut</src> in the appropriate pixel axis
    // location.  Values in <src>pixelIn</src> are copied to
    // <src>pixelOut</src>.
    // <src>worldMin</src> and <src>worldMax</src> specify the range of the world
    // coordinate (in the world axis units of that world axis
    // in the CoordinateSystem) being solved for in a mixed calculation
    // for each world axis. They are only actually needed for DirectionCoordinates
    // and for all other Coordinates the relevant elements   
    // can be undefined.   If you don't know, use -180 to 180
    // degrees for longitude, and -90 to 90 for latitude.
    // Removed axes are handled (for example, a removed pixel
    // axis with remaining corresponding world axis will
    // correctly be converted to world using the replacement
    // value).
    // Returns True if the conversion succeeds, otherwise it returns False and
    // <src>errorMessage()</src> contains an error message. The output vectors
    // are resized.
    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;

    // Set the world min and max ranges, for use in function <src>toMix</src>, for 
    // a lattice of the given shape for this coordinate. The default implementation
    // here sets the range for pixels dangling 25% off the image.
    // Returns False if fails with a reason  in <src>errorMessage()</src>.
    // setDefaultWorldMixRanges sets the range for each axis to +/-1e99
    // The ranges remain zero length vectors until you explicitly
    // initialize them.
    // <group>
    virtual Bool setWorldMixRanges (const IPosition& shape);
    virtual void setDefaultWorldMixRanges ();
    Vector<Double> worldMixMin () const {return worldMin_p;};
    Vector<Double> worldMixMax () const {return worldMax_p;};
    //</group>


    // Batch up a lot of transformations. The first (most rapidly varying) axis
    // of the matrices contain the coordinates. Returns False if any conversion
    // failed  and  <src>errorMessage()</src> will hold a message.
    // The <src>failures</src> array (True for fail, False for success)
    // is the length of the number of conversions and
    // holds an error status for each conversion.  The default
    // implementation is provided that works with the "single" version of
    // <src>toWorld</src> and <src>toPixel</src>, but for maximum efficiency these should be
    // overridden.
    // <group>
    virtual Bool toWorldMany(Matrix<Double>& world, 
                             const Matrix<Double>& pixel, 
                             Vector<Bool>& failures) const;
    virtual Bool toPixelMany(Matrix<Double>& pixel, 
                             const Matrix<Double>& world, 
                             Vector<Bool>& failures) const;
    // </group>

    // Make absolute coordinates relative and vice-versa (with
    // respect to the reference value).
    // Vectors must be length <src>nPixelAxes()</src> or
    // <src>nWorldAxes()</src> or memory access errors will occur
    // <group>
    virtual void makePixelRelative (Vector<Double>& pixel) const;
    virtual void makePixelAbsolute (Vector<Double>& pixel) const;
    virtual void makeWorldRelative (Vector<Double>& world) const;
    virtual void makeWorldAbsolute (Vector<Double>& world) const;
    // </group>

    // Make absolute coordinates relative and vice versa with respect
    // to the given reference value.  Add the other functions in this grouping
    // as needed. Vectors must be length <src>nPixelAxes()</src> or
    // <src>nWorldAxes()</src> or memory access errors will occur
    // <group>
    virtual void makeWorldAbsoluteRef (Vector<Double>& world,
                                       const Vector<Double>& refVal) const;
    // </group>


    // Batch up a lot of absolute/relative transformations. 
    // Parameters as above  for 
    // <src>toWorldMany</src> and <src>toPixelMany</src>
    // <group>
    virtual void makePixelRelativeMany (Matrix<Double>& pixel) const;
    virtual void makePixelAbsoluteMany (Matrix<Double>& pixel) const;
    virtual void makeWorldRelativeMany (Matrix<Double>& world) const;
    virtual void makeWorldAbsoluteMany (Matrix<Double>& world) const;
    // </group>


    // Return the requested attributed.
    // <group>
    virtual Vector<String> worldAxisNames() const = 0;
    virtual Vector<Double> referencePixel() const = 0;
    virtual Matrix<Double> linearTransform() const = 0;
    virtual Vector<Double> increment() const = 0;
    virtual Vector<Double> referenceValue() const = 0;
    virtual Vector<String> worldAxisUnits() const = 0;
    // </group>

    // Set the requested attribute.  Note that these just
    // change the internal values, they do not cause any recomputation.
    // <group>
    virtual Bool setWorldAxisNames(const Vector<String> &names) = 0;
    virtual Bool setReferencePixel(const Vector<Double> &refPix) = 0;
    virtual Bool setLinearTransform(const Matrix<Double> &xform) = 0;
    virtual Bool setIncrement(const Vector<Double> &inc)  = 0;
    virtual Bool setReferenceValue(const Vector<Double> &refval)  = 0;
    // </group>

    // Change the units. Adjust the increment and
    // reference value by the ratio of the old and new units. This implies that
    // the units must be known <linkto class=Unit>Unit</linkto> strings, and that
    // they must be compatible, e.g. they can't change from time to length.
    //
    // A default implementation is available which does everything except set
    // the units vector, which must be done in the derived class.
    virtual Bool setWorldAxisUnits(const Vector<String> &units) = 0;

    // Find the Coordinate for when we Fourier Transform ourselves.  This pointer 
    // must be deleted by the caller. Axes specifies which axes of the Coordinate
    // you wish to transform.   Shape specifies the shape of the image
    // associated with all the axes of the Coordinate. Currently the
    // output reference pixel is always shape/2.
    virtual Coordinate* makeFourierCoordinate (const Vector<Bool>& axes,
                                               const Vector<Int>& shape) const;

    // If the last conversion to world or pixel coordinates resulted in an
    // error, report that error. If the last conversion succeeded, it is
    // undefined what this will return (it might well contain the last error
    // message).
    const String& errorMessage() const;

    // Comparison to fractional tolerance (for floating point values). 
    // Don't compare on specified axes in Coordinate. If the comparison
    // returns False, <src>errorMessage()</src> contains a message.
    // <group>
    virtual Bool near(const Coordinate& other, 
                      Double tol=1.0e-6) const = 0;
    virtual Bool near(const Coordinate& other, 
                      const Vector<Int>& excludeAxes,
                      Double tol=1.0e-6) const = 0;
    // </group>


    // Provide a common interface to getting formatted representations of
    // coordinate values.    Different derived Coordinate types are formatted
    // in different ways.  For example, an RA/DEC  DirectionCoordinate
    // uses an HMS.SS/DMS.SS representation. A Galactic Lat/Long DirectionCoordinate
    // uses floating format in degrees.  Other derived Coordinates are formatted with 
    // scientific format or floating format. The derived class format functions
    // provide this functionality.   
    // 
    // You may specify the format with the format argument and a value
    // from the enum <src>Coordinate::formatType</src>. If you give it the value 
    // <src>Coordinate::DEFAULT</src> then a sensible default is used.
    //
    // A mechanism for specifying the precision number of significant digits after 
    // decimal point is provided.  You can specify the precision directly when 
    // calling format if it is unambiguous how the derived Coordinate is 
    // going to be formatted.  For example, a LinearCoordinate is always formatted with 
    // scientific format.  However, if you are using these classes polymorphically, you 
    // don't want to have to know this and some derived Coordinates may be formatted
    // in multiple ways (such as the DirectionCoordinate examples above).
    // Therefore, the function getPrecision enables 
    // you to set default precisions for the different styles of formatting 
    // used variously in the base and derived classes.   This function chooses the 
    // precision from these default values, according to the type of derived 
    // Coordinate that your object is and what value for format that
    // you give (refer to the derived classes for details on this).
    // 
    // Some derived classes will format differently depending upon whether
    // you want to format an absolute or offset world value input via 
    // absolute (e.g. DirectionCoordinates).
    // 
    // The provided <src>worldValue</src> must be in the native units
    // of the Coordinate.  It may be an absolute (<src>isAbsolute=True</src>)
    // or relative (<src>isAbsolute=False</src>) value.   You may choose to
    // format the world value as absolute (<src>showAsAbsolute=True</src>) or
    // relative (<src>showAsAbsolute=False</src>).  <src>axis</src>
    // specifies which axis of the Coordinate this value belongs to.
    //
    // <src>units</src> specifies the units in which the input world value
    // will be formatted.  
    // If <src>units</src> is empty, the native unit for the given axis 
    // is used.
    //
    // Some derived classes will format in units different from the 
    // native unit of the Coordinate. The units of
    // the formatted number are returned in <src>units</src>.
    // If the <src>units</src> string is provided, the unit must be
    // consistent with the native unit of the coordinate.  The input
    // world value will be converted to this unit.
    //
    // You can also use the Quantum interface.  The units of the Quantum 
    // can then be anything  consistent with the Coordinate.
    // 
    // The default implementation here is to format only
    // with scientific or fixed formats. If precision is negative, a 
    // the default precision is used.
    //
    //<group>
    virtual void getPrecision(Int &precision,
                              Coordinate::formatType& format,
                              Bool showAsAbsolute,
                              Int defPrecScientific,
                              Int defPrecFixed,
                              Int defPrecTime) const;
    virtual String format(
    	String& units,
    	Coordinate::formatType format,
    	Double worldValue,
    	uInt axis,
    	Bool isAbsolute=True,
    	Bool showAsAbsolute=True,
    	Int precision=-1,
    	Bool usePrecForMixed=False
    ) const;

    String formatQuantity(String& units,
                          Coordinate::formatType format, 
                          const Quantum<Double>& worldValue, 
                          uInt axis, 
                          Bool isAbsolute=True,
                          Bool showAsAbsolute=True,
        		  Int precision=-1);
    //</group>

    // Used for persistence. Derived classes will have similar static
    // restore methods. It will typically only return False if fieldName
    // has already been defined.
    virtual Bool save(RecordInterface &container,
		    const String &fieldName) const = 0;

    // Make a copy of ourself. This pointer has been allocated with
    // <src>new</src> and must be deleted by the caller.
    virtual Coordinate *clone() const = 0;

    // Comparison only made for specified axes in this and other Coordinate 
    // The default implementation should be ok for all Coordinate types
    // except Stokes and Quality...
    virtual Bool doNearPixel (const Coordinate& other, 
                              const Vector<Bool>&  thisAxes,
                              const Vector<Bool>& otherAxes,
                              Double tol=1.0e-6) const;

    // return the result of rotating the coordinate clockwise through the specified angle.
    // Rotation occurs about the reference pixel.
    // Coordinate must have exactly two pixel axes. The return type is the same
    // as the input type. It is the caller's responsibility to delete the returned pointer
    // when done with it to prevent a memory leak.
    // This method ultimately just changes the input coordinate's linear transform matrix.
    virtual Coordinate* rotate(const Quantum<Double>& angle) const;

protected:
    // Default constructor. Make an empty coordinate.  Used by derived classes.
    Coordinate();

    // Copy constructor (copy semantics)
    Coordinate(const Coordinate& other);

    // Assignment (copy semantics) 
    Coordinate& operator=(const Coordinate& other);

    // Set error message
    void set_error(const String &errorMsg) const;

    //
    Bool find_scale_factor(String &error, Vector<Double> &factor, 
			   const Vector<String> &units, 
			   const Vector<String> &oldUnits);


    // Tries to find a canonical unit for input unit (e.g.  GHz -> Hz), and
    // tells you the output name and unit for the Fourier coordinate 
    // pairing with the canonical unit
    void fourierUnits (String& nameOut, String& unitOut, String& unitInCanon,
                       Coordinate::Type type, Int axis, 
                       const String& unitIn, 
                       const String& nameIn) const;

   // Functions to interconvert pixel<->world via wcs.  These functions are called 
   // explicitly by the to{world,Pixel} functions in the appropriate wcs-based derived
   // classes. 
   // <group>
   Bool toWorldWCS (Vector<Double> &world, const Vector<Double> &pixel, wcsprm& wcs) const;
   Bool toPixelWCS(Vector<Double> &pixel,  const Vector<Double> &world, wcsprm& wcs) const;
   Bool toWorldManyWCS (Matrix<Double>& world, const Matrix<Double>& pixel,
                        Vector<Bool>& failures, wcsprm& wcs) const;
   Bool toPixelManyWCS (Matrix<Double>& pixel, const Matrix<Double>& world,
                        Vector<Bool>& failures, wcsprm& wcs) const;

   // Functions for handling conversion between the current units and
   // the wcs units. These are called explicitly by the appropriate 
   // derived class.
   // <src>convertFrom</src>
   // <group>
   void toCurrentMany (Matrix<Double>& world, const Vector<Double>& toCurrentFactors) const;
   void fromCurrentMany(Matrix<Double>& world, const Vector<Double>& toCurrentFactors) const;
   // </group>


   // Functions for handling conversion between the current reference frame 
   // and the native one. The default implementations do nothing.  They
   // should be over-ridden in the derived classes.
   // <group>
   virtual void convertTo (Vector<Double>&) const
     {}
   virtual void convertFrom (Vector<Double>&) const
     {}
   // </group>

   // Functions for handling conversion between the current reference frame 
   // and the native one for many conversions.  These functions just
   // call the virtual functions for single conversions.
   // <group>
   void convertToMany (Matrix<Double>& world) const;
   void convertFromMany (Matrix<Double>& world) const;
   // </group>

   // Interconvert between wcs PC cards and Matrix xForm format 
   void pcToXform (Matrix<Double>& xForm, const wcsprm& wcs) const;
   void xFormToPC (wcsprm& wcs, const Matrix<Double>& xForm) const;
   // </group>

   // Call wcsset on the wcs structure
   void set_wcs (wcsprm& wcs);

    // toMix ranges.  Should be set by derived class.
    Vector<Double> worldMin_p, worldMax_p;

private:
    mutable String error_p;

    // Check format type
    void checkFormat(Coordinate::formatType& format,         
                     const Bool absolute) const;

    void makeWorldAbsRelMany (Matrix<Double>& value, Bool toAbs) const; 
    void makePixelAbsRelMany (Matrix<Double>& value, Bool toAbs) const; 


};

//###### Inlines

inline const String& Coordinate::errorMessage() const
{
    return error_p;
}

} //# NAMESPACE CASACORE - END

#endif