casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
LinearCoordinate.h
Go to the documentation of this file.
00001 //# LinearCoordinate.h: Assume a general linear relation between pixel and world axes.
00002 //# Copyright (C) 1997,1998,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: LinearCoordinate.h 18823 2005-07-07 20:36:33Z ddebonis $
00028 
00029 
00030 #ifndef COORDINATES_LINEARCOORDINATE_H
00031 #define COORDINATES_LINEARCOORDINATE_H
00032 
00033 #include <casa/aips.h>
00034 #include <coordinates/Coordinates/Coordinate.h>
00035 #include <casa/Arrays/Vector.h>
00036 #include <wcslib/wcs.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 template<class T> class Quantum;
00041 
00042 
00043 // <summary>
00044 // Interconvert between pixel and a linear world coordinate.
00045 // </summary>
00046 
00047 // <use visibility=export>
00048 
00049 // <reviewed reviewer="Peter Barnes" date="1999/12/24" tests="tLinearCoordinate"> 
00050 // </reviewed>
00051 
00052 // <prerequisite>
00053 //   <li> <linkto class=Coordinate>Coordinate</linkto> defines the fundamental
00054 //        interface to coordinate conversions.
00055 // </prerequisite>
00056 //
00057 // <synopsis>
00058 // The LinearCoordinate class ties pixel and world axes together through 
00059 // a general linear transformation. 
00060 //
00061 // <srcblock>
00062 // world = (cdelt * PC * (pixel - crpix)) + crval
00063 // </srcblock>
00064 // Where PC is an NxN matrix; pixel, crval, crpix and world are length N 
00065 // vectors, and cdelt is an NxN diagonal matrix, represented as a length 
00066 // N vector.
00067 //
00068 // The LinearCoordinate can contain several uncoupled axes (similar to the way
00069 // in which the DirectionCoordinate contains two axes).
00070 // </synopsis>
00071 //
00072 // <note role=caution>
00073 // All pixels coordinates are zero relative.
00074 // </note>
00075 //
00076 // <example>
00077 // Let's make a LinearCoordinate with just one axis containing
00078 // a coordinate describing length.
00079 // <srcblock>
00080 //    Vector<Double> crpix(1); crpix = 0.0;
00081 //    Vector<Double> crval(1); crval = 100.0;
00082 //    Vector<Double> cdelt(1); cdelt = -10.0;
00083 //    Matrix<Double> pc(1,1); pc= 0; pc.diagonal() = 1.0;
00084 //    Vector<String> name(1);  name = "length";
00085 //    Vector<String> units(1); units = "km";
00086 //
00087 //    LinearCoordinate lin(names, units, crval, cdelt, pc, crpix);
00088 // </srcblock>
00089 //
00090 // Now do a coordinate conversion
00091 //
00092 // <srcblock>
00093 //   Vector<Double> world, pixel(1);
00094 //   pixel = 2.0;
00095 //   if (!lin.toWorld(world, pixel)) {
00096 //      cerr << "Error : " << lin.errorMessage() << endl;
00097 //   } else {
00098 //      cerr << "pixel, world = " << pixel << world << endl;
00099 //   }
00100 // </srcblock>
00101 // The answer should of course be -20km.
00102 // </example>
00103 //
00104 // <motivation>
00105 // This class is intended for use with axes which do not have specific coordinate
00106 // types. A "time" axis would be a good example.
00107 // </motivation>
00108 //
00109 // <thrown>
00110 //   <li>  AipsError
00111 // </thrown>
00112 //
00113 // <todo asof="2000/01/01">
00114 //   <li> Allow differing numbers of world and pixel axes. Requires a change in
00115 //        WCS or use of a different library.
00116 // </todo>
00117 //
00118 
00119 
00120 class LinearCoordinate : public Coordinate
00121 {
00122 public:
00123     // The default constructor makes a LinearCoordinate for which pixel 
00124     // and world coordinates are equal.  <src>naxes</src> gives the number
00125     // of axes in the Coordinate.
00126     LinearCoordinate(uInt naxes = 1);
00127 
00128     // Construct the LinearCoordinate
00129     LinearCoordinate(const Vector<String> &names,
00130                      const Vector<String> &units,
00131                      const Vector<Double> &refVal,
00132                      const Vector<Double> &inc,
00133                      const Matrix<Double> &pc,
00134                      const Vector<Double> &refPix);
00135 
00136     // Construct LinearCoordinate with Quantum-based interface.
00137     // The units of the increment (<src>inc</src>) will be converted to
00138     // those of the reference value (<src>refVal</src>) which will
00139     // then serve as the units of the Coordinate.
00140     LinearCoordinate(const Vector<String> &names,
00141                      const Vector<Quantum<Double> >& refVal,
00142                      const Vector<Quantum<Double> >& inc,
00143                      const Matrix<Double> &pc,
00144                      const Vector<Double> &refPix);
00145 
00146     // Constructor from WCS structure; must hold ONLY a linear wcs structure
00147     // Specify whether the absolute pixel coordinates in the wcs structure
00148     // are 0- or 1-relative.  The coordinate is always constructed with 0-relative    
00149     // pixel coordinates
00150     LinearCoordinate(const wcsprm& wcs, Bool oneRel=True);
00151 
00152     // Copy constructor (copy semantics).
00153     LinearCoordinate(const LinearCoordinate &other);
00154 
00155     // Assignment  (copy semantics).
00156     LinearCoordinate &operator=(const LinearCoordinate &other);
00157 
00158     // Destructor.
00159     virtual ~LinearCoordinate();
00160 
00161     // Returns Coordinate::LINEAR.
00162     virtual Coordinate::Type type() const;
00163 
00164     // Returns the String "Linear".
00165     virtual String showType() const;
00166 
00167     // Returns the number of pixel/world axes. The number of axes is arbitrary,
00168     // however the number of world and pixel axes must at present be the same.
00169     // <group>
00170     virtual uInt nPixelAxes() const;
00171     virtual uInt nWorldAxes() const;
00172     // </group>
00173 
00174     // Convert a pixel position to a worl position or vice versa. Returns True
00175     // if the conversion succeeds, otherwise it returns False and method
00176     // errorMessage returns an error message.  The output 
00177     // vectors are appropriately resized.
00178     // <group>
00179     virtual Bool toWorld(Vector<Double> &world, 
00180                          const Vector<Double> &pixel) const;
00181     virtual Bool toPixel(Vector<Double> &pixel, 
00182                          const Vector<Double> &world) const;
00183     // </group>
00184 
00185 
00186     // Return the requested attribute
00187     // <group>
00188     virtual Vector<String> worldAxisNames() const;
00189     virtual Vector<Double> referenceValue() const;
00190     virtual Vector<Double> increment() const;
00191     virtual Matrix<Double> linearTransform() const;
00192     virtual Vector<Double> referencePixel() const;
00193     virtual Vector<String> worldAxisUnits() const;
00194     // </group>
00195 
00196     // Set the value of the requested attributed. Note that these just
00197     // change the internal values, they do not cause any recomputation.
00198     // <group>
00199     virtual Bool setWorldAxisNames(const Vector<String> &names);
00200     virtual Bool setReferencePixel(const Vector<Double> &refPix);
00201     virtual Bool setLinearTransform(const Matrix<Double> &pc);
00202     virtual Bool setIncrement(const Vector<Double> &inc);
00203     virtual Bool setReferenceValue(const Vector<Double> &refval);
00204     // </group>
00205 
00206     // Set the world axis units. Adjust the increment and
00207     // reference value by the ratio of the old and new units.  
00208     // The units must be compatible with the current units.
00209     virtual Bool setWorldAxisUnits(const Vector<String> &units);
00210 
00211     // Overwrite the world axis units with no compatibility 
00212     // checks or adjustment.
00213     Bool overwriteWorldAxisUnits(const Vector<String> &units);
00214 
00215     // Comparison function. Any private Double data members are compared    
00216     // with the specified fractional tolerance.  Don't 
00217     // compare on the specified     
00218     // axes in the Coordinate.  If the comparison returns False, method
00219     // errorMessage contains a message about why.
00220     // <group>
00221     virtual Bool near(const Coordinate& other, 
00222                       Double tol=1e-6) const;
00223     virtual Bool near(const Coordinate& other, 
00224                       const Vector<Int>& excludeAxes,
00225                       Double tol=1e-6) const;
00226     // </group>
00227 
00228     // Find the Coordinate for when we Fourier Transform ourselves.  This pointer
00229     // must be deleted by the caller. Axes specifies which axes of the Coordinate
00230     // you wish to transform.   Shape specifies the shape of the image
00231     // associated with all the axes of the Coordinate.   Currently the
00232     // output reference pixel is always shape/2.  If the pointer returned is 0, 
00233     // it failed with a message in <src>errorMessage</src>
00234     virtual Coordinate* makeFourierCoordinate (const Vector<Bool>& axes,
00235                                                const Vector<Int>& shape) const;
00236 
00237     // Save the LinearCoordinate into the supplied record using the supplied field name.
00238     // The field must not already exist, otherwise <src>False</src> is returned.
00239     virtual Bool save(RecordInterface &container, const String &fieldName) const;
00240 
00241     // Restore the LinearCoordinate from a record.
00242     // A null pointer means that the restoration did not succeed - probably 
00243     // because fieldName doesn't exist or doesn't contain a CoordinateSystem.
00244     static LinearCoordinate *restore(const RecordInterface &container,
00245                                    const String &fieldName);
00246 
00247     // Make a copy of the LinearCoordinate using new. The caller is responsible for calling
00248     // delete.
00249     virtual Coordinate *clone() const;
00250 
00251 private:
00252 
00253 // An interface to the WCSLIB linear transformation routines.
00254     mutable ::wcsprm wcs_p;
00255 
00256 // Copy private data
00257    void copy (const LinearCoordinate& other);
00258 
00259 // Make wcs structure
00260    void makeWCS (wcsprm& wcs, uInt naxis, const Vector<Double>& refPix,
00261                  const Vector<Double>& refVal,
00262                  const Vector<Double>& incr,  
00263                  const Matrix<Double>& pc,  
00264                  const Vector<String>& units,
00265                  const Vector<String>& names);
00266 };
00267 
00268 } //# NAMESPACE CASA - END
00269 
00270 
00271 #endif
00272