casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
StokesCoordinate.h
Go to the documentation of this file.
00001 //# StokesCoordinate.h: Interconvert between pixel number and Stokes value.
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: StokesCoordinate.h 20886 2010-04-29 14:06:56Z gervandiepen $
00028 
00029 
00030 #ifndef COORDINATES_STOKESCOORDINATE_H
00031 #define COORDINATES_STOKESCOORDINATE_H
00032 
00033 #include <casa/aips.h>
00034 #include <coordinates/Coordinates/Coordinate.h>
00035 #include <measures/Measures/Stokes.h>
00036 #include <casa/Containers/Block.h>
00037 #include <casa/Arrays/Vector.h>
00038 
00039 namespace casa { //# NAMESPACE CASA - BEGIN
00040 
00041 
00042 
00043 // <summary>
00044 // Interconvert between pixel and Stokes value.
00045 // </summary>
00046 
00047 // <use visibility=export>
00048 
00049 // <reviewed reviewer="Peter Barnes" date="1999/12/24" tests="tStokesCoordinate">
00050 // </reviewed>
00051 //
00052 // <prerequisite>
00053 //   <li> <linkto class=Coordinate>Coordinate</linkto>
00054 //   <li> <linkto class=Stokes>Stokes</linkto>
00055 // </prerequisite>
00056 //
00057 // <synopsis>
00058 // Although not really a "coordinate", an axis where pixel numbers are used
00059 // for different Stokes values is in wide use.     The StokesCoordinate
00060 // is a poor fit to the Coordinate polymorphic model.
00061 // You will probably find that if you try to use the Coordinate
00062 // classes polymorphically, that StokesCoordinate will cause you
00063 // to break the polymorphism.  I.e. you may have to deal with
00064 // a specific StokesCoordinate)
00065 //
00066 // The StokesCoordinate just maintains a list (given in the constructor) of 
00067 // possibly non-monotonic  Stokes values.   The values of the list are the
00068 // world values (they are values from the Stokes::StokesTypes enum).
00069 // Thus  world = list[pixel]  where pixel is the pixel coordinate (0,1, ...)
00070 // 
00071 // This means that concepts such as reference pixel, reference value,
00072 // increment etc are meaningless for StokesCoordinate.  You can recover these
00073 // these attributes, but the functions to set these attributes have no effect.
00074 //
00075 // Note also that for the StokesCoordinate relative world coordinates are defined to be the 
00076 // as absolute, since there is no meaning for a relative Stokes world value (e.g.
00077 // what is XX -RL ??   Relative pixel coordinates are defined.
00078 //
00079 // </synopsis>
00080 //
00081 // <note role=caution>
00082 // All pixel coordinates are zero relative.
00083 // </note>
00084 //
00085 // <example>
00086 // In this example we create a StokesCoordinate housing IQUV
00087 // <srcblock>
00088 //    Vector<Int> iquv(4);
00089 //    iquv(0) = Stokes::I; iquv(1) = Stokes::Q;
00090 //    iquv(2) = Stokes::U; iquv(3) = Stokes::V;
00091 //    StokesCoordinate stokes(iquv);           
00092 // </srcblock>
00093 // </example>
00094 //
00095 // <motivation>
00096 // It is conventional to make a pseudo-axis of Stokes parameters.
00097 // Another approach is to make an image type called Stokes.
00098 // </motivation>
00099 //
00100 // <todo asof="1997/1/14">
00101 //   <li> This could probably be generalized into an "enumeration axis" class.
00102 // </todo>
00103 // 
00104 
00105 class StokesCoordinate : public Coordinate
00106 {
00107 public:
00108 
00109     // The length of whichStokes is the length of the axis, and the values
00110     // define which stokes are in which axis value. Often the vector will be of
00111     // length 4 and will contain Stokes::I, Q, U and V, however any valid value
00112     // from the stokes enum may be used. The values may not repeat however, e.g.
00113     // only one axis position may contain "I".
00114     explicit StokesCoordinate(const Vector<Int> &whichStokes);
00115 
00116     // Copy constructor (copy semantics)
00117     StokesCoordinate(const StokesCoordinate &other);
00118 
00119     // Assignment (copy semantics)
00120     StokesCoordinate &operator=(const StokesCoordinate &other);
00121 
00122     // Destructor.
00123     virtual ~StokesCoordinate();
00124 
00125     // Returns Coordinates::STOKES.
00126     virtual Coordinate::Type type() const;
00127 
00128     // Always returns the String "Stokes".
00129     virtual String showType() const;
00130 
00131     // Always returns 1.
00132     // <group>
00133     virtual uInt nPixelAxes() const;
00134     virtual uInt nWorldAxes() const;
00135     // </group>
00136 
00137     // Convert a pixel to a world coordinate or vice versa. Returns True
00138     // if the conversion succeeds, otherwise it returns False and method
00139     // <src>errorMessage</src> returns an error message.
00140     // The output vectors are appropriately resized before use.
00141     // <group>
00142     virtual Bool toWorld(Vector<Double> &world, 
00143                                 const Vector<Double> &pixel) const;
00144     virtual Bool toPixel(Vector<Double> &pixel, 
00145                                 const Vector<Double> &world) const;
00146     // </group>
00147 
00148     // Interconvert between pixel and world as a Stokes type.
00149     // It returns False if no conversion could be done.
00150     // <group>
00151     Bool toPixel(Int &pixel, Stokes::StokesTypes stokes) const;
00152     Bool toWorld(Stokes::StokesTypes &stokes, Int pixel) const;
00153     // </group>
00154 
00155     // Interconvert between world stored as a Double and world stored as
00156     // a Stokes type.  Since these functions are static, any valid
00157     // Stokes type can be used.  The second function returns 
00158     // Stokes::Undefined if world is illegal.
00159     // <group>
00160     static Double toWorld (Stokes::StokesTypes stokes);
00161     static Stokes::StokesTypes toWorld (Double world);
00162     // </group>
00163 
00164     // Make absolute coordinates relative and vice-versa. 
00165     // For the StokesCoordinate relative world coordinates are defined to be the 
00166     // same as absolute world coordinates.  Relative pixels do have meaning
00167     // and are implemented (rel = abs - refPix)
00168     // <group>
00169     virtual void makePixelRelative (Vector<Double>& pixel) const;
00170     virtual void makePixelAbsolute (Vector<Double>& pixel) const;
00171     virtual void makeWorldRelative (Vector<Double>& world) const;
00172     virtual void makeWorldAbsolute (Vector<Double>& world) const;
00173     // </group>
00174  
00175 
00176     // Get the Stokes values (Stokes::StokesType) that we constructed 
00177     // with into a vector
00178     Vector<Int> stokes() const;
00179 
00180     // Set a new vector of Stokes values (a vector of Stokes::StokesType) 
00181     void setStokes (const Vector<Int> &whichStokes);
00182    
00183     // Report the value of the requested attribute.
00184     // <group>
00185     virtual Vector<String> worldAxisNames() const;
00186     virtual Vector<Double> referencePixel() const;
00187     virtual Matrix<Double> linearTransform() const;
00188     virtual Vector<Double> increment() const;
00189     virtual Vector<Double> referenceValue() const;
00190     // </group>
00191 
00192     // Set the value of the requested attribute.  For the StokesCoordinate,
00193     // these have no effect (always return True) except for setWorldAxisNames.
00194     // <group>
00195     virtual Bool setWorldAxisNames(const Vector<String> &names);
00196     virtual Bool setReferencePixel(const Vector<Double> &refPix);
00197     virtual Bool setLinearTransform(const Matrix<Double> &xform);
00198     virtual Bool setIncrement(const Vector<Double> &inc) ;
00199     virtual Bool setReferenceValue(const Vector<Double> &refval) ;
00200     // </group>
00201 
00202     // The set function has no effect as the units must be empty for a StokesCoordinate
00203     // Always returns True
00204     // <group>
00205     virtual Bool setWorldAxisUnits(const Vector<String> &units);
00206     virtual Vector<String> worldAxisUnits() const;
00207     // </group>
00208 
00209     // Set the world min and max ranges, for use in function <src>toMix</src>,
00210     // for  a lattice of the given shape (for this coordinate).
00211     // The implementation here gives world coordinates at the start 
00212     // and end of the Stokes axis.
00213     // The output vectors are resized.  Returns False if fails (and
00214     // then <src>setDefaultWorldMixRanges</src> generates the ranges)
00215     // with a reason in <src>errorMessage()</src>.
00216     // The <src>setDefaultWorldMixRanges</src> function
00217     // gives you [-1e99->1e99]. 
00218     // <group>
00219     virtual Bool setWorldMixRanges (const IPosition& shape);
00220     virtual void setDefaultWorldMixRanges ();
00221     //</group>
00222 
00223     // Format a StokesCoordinate world value with the common format 
00224     // interface (refer to the base class <linkto class=Coordinate>Coordinate</linkto>
00225     // for basics.
00226     //
00227     // A StokesCoordinate is formatted differently from other Coordinate
00228     // types.  The world value is converted to the character representation
00229     // as defined by the enum <src>StokesTypes</src> in the class
00230     // <linkto class=Stokes>Stokes</linkto>.
00231     //
00232     // Thus, all other arguments to do with formatting and precision are ignored.
00233     virtual String format(String& units,
00234                           Coordinate::formatType format,
00235                           Double worldValue,
00236                           uInt worldAxis,
00237                           Bool isAbsolute=True,
00238                           Bool showAsAbsolute=True,
00239                           Int precision = -1, Bool usePrecForMixed=False) const;
00240 
00241     // Comparison function. Any private Double data members are compared    
00242     // with the specified fractional tolerance.  Don't compare on the specified     
00243     // axes in the Coordinate.  If the comparison returns False,  method
00244     // errorMessage returns a message about why.
00245     // <group>
00246     virtual Bool near(const Coordinate& other,  
00247                       Double tol=1e-6) const;
00248     virtual Bool near(const Coordinate& other,  
00249                       const Vector<Int>& excludeAxes,
00250                       Double tol=1e-6) const;
00251     // </group>
00252 
00253     // Save the StokesCoordinate into the supplied record using the supplied field name.
00254     // The field must not exist, otherwise <src>False</src> is returned.
00255     virtual Bool save(RecordInterface &container,
00256                     const String &fieldName) const;
00257 
00258     // Recover the StokesCoordinate from a record.
00259     // A null pointer means that the restoration did not succeed - probably 
00260     // because fieldName doesn't exist or doesn't contain a CoordinateSystem.
00261     static StokesCoordinate* restore(const RecordInterface &container,
00262                                      const String &fieldName);
00263 
00264     // Make a copy of the StokesCoordinate using new. The caller is responsible for calling
00265     // delete.
00266     virtual Coordinate *clone() const;
00267 
00268 
00269     // Comparison only made for specified axes in this and other Coordinate
00270     virtual Bool doNearPixel (const Coordinate& other,
00271                               const Vector<Bool>&  thisAxes,
00272                               const Vector<Bool>& otherAxes,
00273                               Double tol=1.0e-6) const; 
00274 
00275 private:
00276 
00277     Bool toWorld(Double& world,  const Double pixel) const;
00278     Bool toPixel(Double& pixel,  const Double world) const;
00279 //
00280     Block<Int> values_p;
00281 
00282     // Keep these for subimaging purposes.
00283     Double crval_p, crpix_p, matrix_p, cdelt_p;
00284     String name_p;
00285     String unit_p;
00286     Int nValues_p;
00287 
00288     // Undefined and inaccessible
00289     StokesCoordinate();
00290 };
00291 
00292 } //# NAMESPACE CASA - END
00293 
00294 
00295 #endif
00296