casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
CoordinateUtil.h
Go to the documentation of this file.
00001 //# CoordinateUtils.h: static functions dealing with coordinates
00002 //# Copyright (C) 1997,1998,1999,2000,2001,2002,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 //# $Id: CoordinateUtil.h 20652 2009-07-06 05:04:32Z Malte.Marquarding $
00027 
00028 #ifndef COORDINATES_COORDINATEUTIL_H
00029 #define COORDINATES_COORDINATEUTIL_H
00030 
00031 
00032 #include <casa/aips.h>
00033 #include <casa/Arrays/Vector.h>
00034 #include <measures/Measures/Stokes.h>
00035 #include <coordinates/Coordinates/Coordinate.h>
00036 
00037 #include <measures/Measures/MDirection.h>        //# For enums
00038 #include <measures/Measures/MFrequency.h>
00039 #include <measures/Measures/MeasConvert.h>
00040 
00041 namespace casa { //# NAMESPACE CASA - BEGIN
00042 
00043 class CoordinateSystem;
00044 class DirectionCoordinate;
00045 class ObsInfo;
00046 class String;
00047 class LogIO;
00048 class MEpoch;
00049 class MPosition;
00050 class Unit;
00051 
00052 
00053 // <summary>Functions for creating default CoordinateSystems</summary>
00054 // <use visibility=export>
00055 
00056 // <reviewed reviewer="" date="" tests="" demos="">
00057 // </reviewed>
00058 
00059 // <prerequisite>
00060 //   <li> <linkto class="CoordinateSystem">CoordinateSystem</linkto>
00061 // </prerequisite>
00062 //
00063 // <etymology> 
00064 // CoordinateUtils follows the AIPS++ naming convention for static functions
00065 // that are associated with a class.
00066 // </etymology>
00067 //
00068 // <synopsis>
00069 // This file contains declarations for static functions that manipulate
00070 // coordinate systems. It currently contains functions for:
00071 // <ul>
00072 // <li> Adding default axes to a CoordinateSystem
00073 // <li> Creating a default CoordinateSystem
00074 // <li> Finding specified axes in a CoordinateSystem
00075 // </ul>
00076 // 
00077 // The functions for adding default axes to a CoordinateSystem can add
00078 // either a RA/DEC pair of axes, a Polarisation Axis, or a Spectral Axis to
00079 // a user supplied coordinate system. The default values for these functions
00080 // are:
00081 // <ul>
00082 // <li> <src>addDirAxes</src> this adds a DirectionCoordinate with a
00083 // reference pixel of (0,0) corresponding to an RA/DEC of (0,0) in a
00084 // J2000 reference frame. The pixel increment is 1 arc-minute.
00085 // <li> <src>addIQUVAxis</src> this adds a polarization axis with four
00086 // elements corresponding to the Stokes (I,Q,U,V) components.
00087 // <li> <src>addIAxis</src> this adds a polarization axis with one
00088 // element corresponding to the Stokes I component only
00089 // <li> <src>addFreqAxis</src> this adds a spectral axis with a reference
00090 // frequency of 1.415GHz on channel 0. The channel bandwidth (pixel
00091 // increment) is 1kHz, and the reference frame is the kinematical Local Standard of
00092 // rest (<linkto class="MFrequency">MFrequency</linkto>::LSRK). 
00093 // </ul>
00094 //
00095 // The <src>defaultCoords</src> functions, create from scratch a
00096 // CoordinateSystem using the above described <src>addXXXAxis</src>
00097 // functions to add the required number of dimensions to the
00098 // CoordinateSystem. Only 2, 3 or 4 dimensional coordinate systems can be
00099 // constructed using these functions. The coordinate systems always have
00100 // RA/Dec axes. Three dimensional Systems add a spectral axis and
00101 // four-dimensional systems add an IQUV  polarization axis. An exception
00102 // (AipsError) is thrown if <src>defaultCoords(uInt)</src> is called with a
00103 // parameter that is not 2, 3, or 4. 
00104 //
00105 // The <src>defaultCoordsXX</src> functions return the coordinate system by
00106 // value (which involves a copy of the CoordinateSystem) and hence are not
00107 // as effcient as the <src>addXXXAxis</src> functions.
00108 //
00109 // If the default axes provided by these functions are not quite what is
00110 // required it is possible to use member functions of the 
00111 // <linkto class="CoordinateSystem">CoordinateSystem</linkto>
00112 // and <linkto class="Coordinate">Coordinate</linkto> classes 
00113 // (<linkto class="DirectionCoordinate">DirectionCoordinate</linkto>,
00114 // <linkto class="StokesCoordinate">StokesCoordinate</linkto>,
00115 // <linkto class="SpectralCoordinate">SpectralCoordinate</linkto> etc.)
00116 // to tweak the appropriate parameters of the specified axis.
00117 //
00118 // Now we turn to the functions for finding axes in a CoordinateSystem. With
00119 // a CoordinateSystem object it is not required that the first Coordinate
00120 // axis in the the CoordinateSystem map to the first pixel axis in an
00121 // image. Hence it is necessary to determine which pixel axis corresponds to a
00122 // specified Coordinate and this can be done using these functions. Some
00123 // coordinate types, in particular DirectionCoordinate, usually map to more
00124 // than one pixel axis (DirectionsCoordinates are inherently two-dimensional).
00125 // 
00126 // This group contains declarations for static functions that search
00127 // CoordinateSystem's for a coordinate of the specified type. It returns the
00128 // pixel axis (zero relative) of the specified coordinate type. If the supplied
00129 // Coordinate system does not contain the specified coordinate type the
00130 // returned value is function specific (but usually -1). If the supplied   
00131 // CoordinateSystem contains two or more of the specified coordinateType then
00132 // an exception (AipsError) is thrown.
00133 //
00134 // Finally functions are provided for removing lists of pixel/world axes
00135 // from a CoordinateSystem.
00136 // This process is made a little awkward by the fact that when you
00137 // remove one axis, all the rest shuffle down one, so it is
00138 // provided here.  Generally, one only needs to remove one axis
00139 // (in which case you should use the CoordinateSystem::removeWorldAxis and
00140 // CoordinateSystem::removcePixelAxis functions), but on occaision,
00141 // the multiple need is there.
00142 // </synopsis>
00143 //
00144 // <example>
00145 // I use these functions when creating test images. 
00146 // <srcblock>
00147 // PagedImage(IPosition(4,256,256,4,32), CoordinateUtil::defaultCoords4D(),
00148 //            String("test.image"));
00149 // </srcblock>
00150 // </example>
00151 //
00152 // <example>
00153 // Functions are needed to handle images without specifying a canonical
00154 // coordinate order. For example suppose we want to find the spectral aixs
00155 // of a PagedImage object.
00156 //     
00157 // <srcblock>
00158 //   const Int spectralAxis = CoordinateUtil::findSpectralAxis(image.coordinates());
00159 //   cout << "The spectral axis is of shape " << image.shape()(spectralAxis) << endl;
00160 // </srcblock>
00161 // </example>
00162 //
00163 // <example>
00164 // Here we remove the first and last world axes, and their associated
00165 // pixel axes from a 3D CoordinateSystem.  The reference values and
00166 // reference pixels are used for the replacement values.
00167 //     
00168 // <srcblock>
00169 //   CoordinateSystem cSys = CoordinateUtil::defaultCoords3D();
00170 //   Vector<Int> worldAxes(2);
00171 //   worldAxes(0) = 0; worldAxes(1) = cSys.nWorldAxes()-1;
00172 //   Vector<Double> worldRep;
00173 //   Bool ok = CoordinateUtil::removeAxes(cSys, worldRep, worldAxes, True);
00174 //   cout << "For world axes used " << worldRep << " for replacement" << endl;
00175 // </srcblock>
00176 // </example>
00177 //
00178 //
00179 // <motivation>
00180 // I got fed up writing small functions to create and find coordinates when writing
00181 // test programs involving Images and ComponentModels.
00182 // </motivation>
00183 //
00184 // <thrown>
00185 //    <li> AipsError
00186 // </thrown>
00187 //
00188 // <todo asof="1997/01/23">
00189 //   <li> This code does all I want at the moment
00190 // </todo>
00191 
00192 //  <linkfrom anchor=defaultAxes classes="CoordinateSystem">
00193 //      Static functions for creating <here>default</here> coordinate systems
00194 //  </linkfrom>
00195 
00196 class CoordinateUtil
00197 {
00198 public: 
00199 
00200 // Add a RA/DEC pair of direction axes (ie. a DirectionCoordinate) to the
00201 // user supplied CoordinateSystem. See the synopsis above for the current
00202 // default values.
00203 static void addDirAxes(CoordinateSystem& coords);
00204 
00205 // Add a Stokes I,Q,U,V axis to the user supplied CoordinateSystem.
00206 static void addIQUVAxis(CoordinateSystem& coords);
00207 
00208 // Add a Stokes I (only) axis to the user supplied CoordinateSystem.
00209 static void addIAxis(CoordinateSystem& coords);
00210 
00211 // Add a Stokes axis of length 1 to 4 selected from I,Q,U,V
00212 // E.g. if shape=2 you get IQ.   Returns False if shape
00213 // is not in the range 1 to 4
00214 static Bool addStokesAxis(CoordinateSystem& coords, uInt shape);
00215 
00216 // Add Linear axes.  The LinearCoordinate can have > 1 axes (like
00217 // the DirectionCoordinate has 2).  The number of axes is given
00218 // by the length of the names argument.   If you supply a shape,
00219 // it will be used to set the reference pixel to 1/2 the shape.
00220 // If the shape does not have the same number of elements as
00221 // the names variable, the reference pixel will be 0
00222 static void addLinearAxes (CoordinateSystem & coords,
00223                            const Vector<String>& names,
00224                            const IPosition& shape);
00225 
00226 // Add a spectral axis to the user supplied CoordinateSystem. See the
00227 // synopsis above for the current default values.
00228 static void addFreqAxis(CoordinateSystem& coords);
00229 
00230 // Return a 2-dimensional coordinate system with RA/DEC axes only. 
00231 static CoordinateSystem defaultCoords2D();
00232 
00233 // Return a 3-dimensional coordinate system with RA/DEC axes and a spectral axis.
00234 static CoordinateSystem defaultCoords3D();
00235 
00236 // Return a 4-dimensional coordinate system with RA/DEC axes, an IQUV
00237 // polarisation axis  and a spectral axis.
00238 static CoordinateSystem defaultCoords4D();
00239 
00240 // Calls one of the above three functions depending of the arguement. An
00241 // AipsError is thrown if dims is not 2, 3, or 4.
00242 static CoordinateSystem defaultCoords(uInt dims);
00243 
00244 // If doLinear=False, Tries to make a standard RA/DEC/Stokes/Frequency CoordinateSystem
00245 // depending upon the shape.   The shape for the Stokes axis
00246 // must be <= 4.   If axis 2 can't be Stokes it will be a Spectral
00247 // axis instead.  AFter the standard types, the rest (if any)
00248 // of the CoordinateSystem consists of LinearCoordinates.
00249 // If doLinear=True, then you just get a linear coordinate system
00250 static CoordinateSystem makeCoordinateSystem(const IPosition& shape,
00251                                              Bool doLinear=False);
00252 
00253 //
00254 // Find which pixel axis in the CoordinateSystem corresponds to the
00255 // SpectralCoordinate. If there is no SpectralCoordinate in the coordinate
00256 // system then return -1.
00257 static Int findSpectralAxis(const CoordinateSystem & coords);
00258 
00259 // Find the SpectralCoordinate in the CoordinateSystem, and then
00260 // return the most general description of where it is.  
00261 // If there is no SpectralCoordinate in the CoordinateSystem then return 
00262 // -1 for coordinate.  If the world or pixel axis has been removed,
00263 // return -1 for that value. 
00264 static void findSpectralAxis(Int& pixelAxis, Int& worldAxis, Int& coordinate,
00265                              const CoordinateSystem & coords);
00266 
00267 // Find which pixel axes correspond to the DirectionCoordinate in the 
00268 // supplied coordinate system and return this as a Vector. If there is no 
00269 // DirectionCoordinate in the CoordinateSystem then return a Vector of zero 
00270 // length. Normally the returned Vector will have a length of two.  
00271 // However, if the pixel axis has been removed, then the resultant
00272 // vector will take the value -1 for that axis.
00273 static Vector<Int> findDirectionAxes(const CoordinateSystem & coords);
00274 
00275 // Find which pixel axes correspond to the DirectionCoordinate in the supplied coordinate
00276 // system and return the most general description of where it is. If there is 
00277 // no DirectionCoordinate then coordinate is returned with value -1.
00278 // Values of -1 in the returned vectors indicate an axis has been removed.
00279 static void findDirectionAxes(Vector<Int>& pixelAxes, Vector<Int>& worldAxes,
00280                               Int& coordinate, const CoordinateSystem & coords);
00281 
00282 // Find which pixel axis is the polarisation axis in the supplied
00283 // CoordinateSystem and return this. If there is no StokesCoordinate in the
00284 // CoordinateSystem return a negative number. The actual polarisations on the
00285 // returned pixel axis are returned in the whichPols Vector. Each element of
00286 // this Vector is a Stokes::StokesTypes enumerator and the length of the Vector
00287 // is the same as the length of the polarisation axis. If there is no
00288 // polarisation axis the whichPols returns a unit length Vector containing
00289 // Stokes::I
00290 static Int findStokesAxis(Vector<Stokes::StokesTypes>& whichPols, 
00291                           const CoordinateSystem& coords);
00292 
00293 // Find the StokesCoordinate in the CoordinateSystem, and then
00294 // return the most general description of where it is.  
00295 // If there is no StokesCoordinate in the CoordinateSystem then return 
00296 // -1 for coordinate.  If the world or pixel axis has been removed,
00297 // return -1 for that value. 
00298 static void findStokesAxis(Int& pixelAxis, Int& worldAxis, Int& coordinate,
00299                            const CoordinateSystem & coords);
00300 
00301 // Find Coordinate type for this pixel or world axis
00302 // <group>
00303 static Coordinate::Type findPixelAxis (const CoordinateSystem& cSys, Int axis);
00304 static Coordinate::Type findWorldAxis (const CoordinateSystem& cSys, Int axis);
00305 // </group>
00306 
00307 // Remove a list of world axes and their associated
00308 // pixel axes from a <src>CoordinateSystem</src>. The list of world
00309 // axes to be removed is derived from a list giving either axes to remove, 
00310 // or axes to keep (controlled by whether <src>remove</src> 
00311 // is <src>True</src> or <src>False</src>.  The replacement values (see functions 
00312 // <src>CoordinateSystem::removeWorldAxis</src>) for the world axes
00313 // can be given.  For the associated pixel axes, the pixel replacement
00314 // coordinate is found by converting the world coordinate 
00315 // to a pixel coordinate. If the length of the replacement value 
00316 // vector is not the number of world axes to be removed then
00317 // the reference values will be used (e.g. use zero length
00318 // vectors).
00319 static Bool removeAxes(CoordinateSystem& cSys,
00320                        Vector<Double>& worldReplacement,
00321                        const Vector<Int>& worldAxes,
00322                        const Bool remove);
00323 
00324 // Remove a list of pixel axes but not their associated
00325 // world axes from a <src>CoordinateSystem</src>. 
00326 // The list of pixel axes to be removed is derived from a 
00327 // list giving either axes to remove, 
00328 // or axes to keep (controlled by whether <src>remove</src> 
00329 // is <src>True</src> or <src>False</src>.  The replacement values (see functions 
00330 // <src>CoordinateSystem::removePixelAxis</src>) for the pixel axes
00331 // can be given.  If the length of the replacement value 
00332 // vector is not the number of pixel axes to be removed then
00333 // the reference pixel will be used (e.g. use zero length
00334 // vectors).
00335 static Bool removePixelAxes(CoordinateSystem& cSys,
00336                             Vector<Double>& pixelReplacement,
00337                             const Vector<Int>& pixelAxes,
00338                             const Bool remove);
00339 
00340 // Physically (nont just virtually) drop coordinates from the CoordinateSystem
00341 // if all axes are fully removed. For coordinates with axes partially removed
00342 // (world/pixel) preserve that removal state in the output CS.  No effort
00343 // is made to deal in any way with transposed systems, unless perserveAxesOrder
00344 // is True, and then the ordering of the axes of the output coordinate system
00345 // will be the same as the input cSysIn (sans dropped axes of course).
00346 static Bool dropRemovedAxes (
00347         CoordinateSystem& cSysOut, const CoordinateSystem& cSysIn,
00348         Bool preserveAxesOrder=False
00349 );
00350 
00351 // Setup Measures conversion machine for MDirections.
00352 // Returns True if the machine was needed and set.  Returns False
00353 // if the machine was not needed and not set.  
00354   static Bool makeDirectionMachine(LogIO& os, MDirection::Convert& machine,
00355                                    const DirectionCoordinate& dirCoordTo,
00356                                    const DirectionCoordinate& dirCoordFrom,
00357                                    const ObsInfo& obsTo,
00358                                    const ObsInfo& obsFrom);
00359 
00360 // Setup Measures conversion machines for MFrequencies. 
00361 // Returns False if a trial conversion failed, else returns True.
00362 // There must be both a Direction and a Spectral
00363 // Coordinate in the CoordinateSystem when making the Frequency machine,
00364 // else an exception occurs.
00365    static Bool makeFrequencyMachine(LogIO& os, MFrequency::Convert& machine, 
00366                                     Int coordinateTo, Int coordinateFrom, 
00367                                     const CoordinateSystem& coordsTo, 
00368                                     const CoordinateSystem& coordsFrom,
00369                                     const Unit& unit=Unit(String("Hz")));
00370 
00371 // Setup Measures conversion machines for MFrequencies.
00372 // Returns False if a trial conversion failed, else returns True.
00373    static Bool makeFrequencyMachine(LogIO& os, MFrequency::Convert& machine,
00374                                     MFrequency::Types typeTo, MFrequency::Types typeFrom,
00375                                     const MDirection& dirTo, const MDirection& dirFrom,
00376                                     const MEpoch& epochTo, const MEpoch& epochFrom,
00377                                     const MPosition& posTo, const MPosition& posFrom,
00378                                     const Unit& unit=Unit(String("Hz")));
00379 
00380 // Find the Sky in the CoordinateSystem. Assumes only one DirectionCoordinate.
00381 // <src>pixelAxes</src> and <src>worldAxes</src>  say where
00382 // in the CS the DirectionCoordinate axes are (long then lat).
00383 // Returns False and an error message if it can't find the sky.
00384    static Bool findSky(String& errorMessage, Int& dirCoord, Vector<Int>& pixelAxes,
00385                        Vector<Int>& worldAxes, const CoordinateSystem& cSys);
00386 //
00387 
00388 // Does the CoordinateSystem hold just the sky ?  Exception if not.
00389 // Returns True if CS pixel axis 0 is the longitude and 1 latitude  
00390 // else returns False
00391    static Bool isSky (LogIO& os, const CoordinateSystem& cSys);
00392 
00393 // Do the specified axes hold the sky ?  Returns False if no DirectionCoordinate
00394 // or if only one axis of the DirectionCoordinate is held or the specified
00395 // pixel axes don't pertain to the DirectionCoordinate.  
00396    static Bool holdsSky (Bool& holdsOneSkyAxis, const CoordinateSystem& cSys, 
00397                          Vector<Int> pixelAxes);
00398 
00399 
00400 // Find the Stokes for the specified pixel. If there is no Stokes in the
00401 // CoordinateSystem, returns Stokes::I
00402    static Stokes::StokesTypes findSingleStokes (LogIO& os, const CoordinateSystem& cSys,
00403                                                 uInt pixel=0);
00404 
00405 // Set the world axis units in the CS to 'deg' for Direction. For Spectral
00406 // set the velocity handling to use 'km/s' units.  Other coordinates
00407 // are not touched.
00408    static void setNiceAxisLabelUnits(CoordinateSystem& cSys);
00409 
00410 // Set world axis units for specific Coordinate.  Returnd False if fails to set units
00411 // with error in cSys.errorMessage().  
00412    static Bool setCoordinateUnits (CoordinateSystem& cSys, const Vector<String>& units,
00413                                    uInt which);
00414 
00415 // Set a unit for all unremoved world axes in the DirectionCoordinate in the
00416 // CS.  Returns False if fails to set unit with error in cSys.  If no DC
00417 // returns True
00418    static Bool setDirectionUnit (CoordinateSystem& cSys, const String& unit, Int which=-1);
00419 
00420 // Set Direction conversion layer of DirectionCoordinate in CoordinateSystem
00421 // so that pixel<->world go to the specified direction system (a valid
00422 // MDirection::Types string).  Returns False with error if direction
00423 // system invalid.  If no DirectionCoordinate returns True
00424    static Bool setDirectionConversion (String& errorMsg, CoordinateSystem& cSys,
00425                                       const String directionSystem);
00426 
00427 // Set spectral state of SpectralCoordinate in CoordinateSystem.
00428 // Unit must be consistent with Hz or m/s and the doppler a valid MDoppler string.
00429 // For no change, leave either String empty.
00430 // Returns False if invalid inputs (and CS not changed) and an error message. 
00431    static Bool setSpectralState (String& errorMsg, CoordinateSystem& cSys, 
00432                                  const String& unit, const String& spcquant);
00433 
00434 // Set rest frequency of SpectralCoordinate in CoordinateSystem.
00435 // Unit must be consistent with Hz or m.
00436 // Returns False if invalid inputs (and CS not changed) and an error message.
00437    static Bool setRestFrequency (String& errorMsg, CoordinateSystem& cSys,
00438                                         const String& unit,
00439                                         const Double& value);
00440 
00441 // Set velocity state of SpectralCoordinate in CoordinateSystem.
00442 // Unit must be consistent m/s and the doppler a valid MDoppler string.
00443 // For no change, leave either String empty.
00444 // Returns False if invalid inputs (and CS not changed) and an error message. 
00445    static Bool setVelocityState (String& errorMsg, CoordinateSystem& cSys, 
00446                                  const String& unit, const String& spcquant);
00447 
00448 // Set Spectral conversion layer of SpectralCoordinate in CoordinateSystem
00449 // so that pixel<->world go to the specified frequency system (a valid
00450 // MFrequency::Types string).  Returns False if frequency system invalid
00451 // or if no DirectionCoordinate or if cant get Date/Epoch
00452    static Bool setSpectralConversion (String& errorMsg, CoordinateSystem& cSys,
00453                                       const String frequencySystem);
00454 
00455 // Set default format unit and doppler velocity state of SpectralCoordinate in CoordinateSystem.
00456 // Unit can be consistent with Hz or m/s
00457 // Returns False if invalid inputs (and CS not changed) and an error message. 
00458    static Bool setSpectralFormatting (String& errorMsg, CoordinateSystem& cSys, 
00459                                       const String& unit, const String& spcquant);
00460 
00461 // Convert an absolute pixel coordinate to world and format with 
00462 // default Coordinate formatting
00463 // <group>
00464    static String formatCoordinate(const IPosition& pixel, const CoordinateSystem& cSys, Int precision = -1);
00465    static String formatCoordinate(const Vector<Double>& pixel, const CoordinateSystem& cSys, Int precision = -1);
00466 // </group>
00467 
00468 // Generate axis label String from coordinate. Specify coordinate axis,
00469 // whether world or pixel labels required, whether absolute or
00470 // relative.   For spectral coordinates, doVel says if you want to 
00471 // use the velocity information contained in it to generate the label
00472    static String axisLabel (const Coordinate& coord, uInt axisInCoordinate=0,
00473                             Bool doWorld=True, Bool doAbs=True, Bool doVel=False);
00474 
00475   // <group name=Coordinate comparison>
00476   // Check how the coordinates of this and that compare.
00477   // The return value tells how they compare.
00478   // <br>-1: left is subset
00479   // <br>0: equal 
00480   // <br>1: left is superset
00481   // <br>9: invalid (mismatch)
00482   static Int compareCoordinates (const CoordinateSystem& thisCsys,
00483                                  const CoordinateSystem& thatCsys);
00484 
00485   // Convert the world axes map given in worldAxes to a pixel axes map.
00486   static Vector<Int> toPixelAxes (const CoordinateSystem& thisCsys,
00487                                   const CoordinateSystem& thatCsys,
00488                                   const Vector<Int>& worldAxes);
00489 
00490   // Check if the axes in the pixel axes map are in ascending order.
00491   static Bool checkOrder (const Vector<Int>& pixelAxes);
00492 
00493   // Find the new and stretch axes when comparing the old and new
00494   // coordinates and shapes (helper for ExtendImage).
00495   static Bool findExtendAxes (IPosition& newAxes,
00496                               IPosition& stretchAxes,
00497                               const IPosition& newShape,
00498                               const IPosition& oldShape,
00499                               const CoordinateSystem& newCsys,
00500                               const CoordinateSystem& oldCsys);
00501   // </group>
00502 
00503   // Fix up Cylindrical parameters in any DirectionCoordinate for when the longitude 
00504   // is outside of [-180,180] range.  If it returns False, it failed and an error 
00505   // message is returned as well.  This function should be called on any
00506   // CS made from an imported image like FITS
00507   static Bool cylindricalFix (CoordinateSystem& cSys, String& errorMessage, const IPosition& shape);
00508 
00509   // Apply the binning factors to the CS and create a new one reflecting the binning
00510   // You can optionally throw an exception if factors is non-unit for any Stokes axis
00511   static CoordinateSystem makeBinnedCoordinateSystem (const IPosition& factors,
00512                                                       const CoordinateSystem& cSysIn,
00513                                                       Bool failOnStokes=False);
00514 private:
00515   // Sets pos to the position found for tel in the database, or
00516   // raises an exception + error message.
00517   static void findObservatoryOrRaiseException(LogIO& os, MPosition& pos,
00518                                               const String& tel);
00519 };
00520 
00521 
00522 } //# NAMESPACE CASA - END
00523 
00524 #endif