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$ 00028 00029 00030 #ifndef COORDINATES_STOKESCOORDINATE_H 00031 #define COORDINATES_STOKESCOORDINATE_H 00032 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/coordinates/Coordinates/Coordinate.h> 00035 #include <casacore/measures/Measures/Stokes.h> 00036 #include <casacore/casa/Containers/Block.h> 00037 #include <casacore/casa/Arrays/Vector.h> 00038 00039 namespace casacore { //# NAMESPACE CASACORE - 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 // The Bool parameter in toWorld() is ignored as this coordinate does not 00142 // support a conversion layer frame. 00143 // <group> 00144 virtual Bool toWorld(Vector<Double> &world, 00145 const Vector<Double> &pixel, Bool=True) const; 00146 virtual Bool toPixel(Vector<Double> &pixel, 00147 const Vector<Double> &world) const; 00148 // </group> 00149 00150 // Interconvert between pixel and world as a Stokes type. 00151 // It returns False if no conversion could be done. 00152 // <group> 00153 Bool toPixel(Int &pixel, Stokes::StokesTypes stokes) const; 00154 Bool toWorld(Stokes::StokesTypes &stokes, Int pixel) const; 00155 // </group> 00156 00157 // Interconvert between world stored as a Double and world stored as 00158 // a Stokes type. Since these functions are static, any valid 00159 // Stokes type can be used. The second function returns 00160 // Stokes::Undefined if world is illegal. 00161 // <group> 00162 static Double toWorld (Stokes::StokesTypes stokes); 00163 static Stokes::StokesTypes toWorld (Double world); 00164 // </group> 00165 00166 // Make absolute coordinates relative and vice-versa. 00167 // For the StokesCoordinate relative world coordinates are defined to be the 00168 // same as absolute world coordinates. Relative pixels do have meaning 00169 // and are implemented (rel = abs - refPix) 00170 // <group> 00171 virtual void makePixelRelative (Vector<Double>& pixel) const; 00172 virtual void makePixelAbsolute (Vector<Double>& pixel) const; 00173 virtual void makeWorldRelative (Vector<Double>& world) const; 00174 virtual void makeWorldAbsolute (Vector<Double>& world) const; 00175 // </group> 00176 00177 00178 // Get the Stokes values (Stokes::StokesType) that we constructed 00179 // with into a vector 00180 Vector<Int> stokes() const; 00181 00182 // Get the stokes string representations 00183 Vector<String> stokesStrings() const; 00184 00185 // Set a new vector of Stokes values (a vector of Stokes::StokesType) 00186 void setStokes (const Vector<Int> &whichStokes); 00187 00188 // Report the value of the requested attribute. 00189 // <group> 00190 virtual Vector<String> worldAxisNames() const; 00191 virtual Vector<Double> referencePixel() const; 00192 virtual Matrix<Double> linearTransform() const; 00193 virtual Vector<Double> increment() const; 00194 virtual Vector<Double> referenceValue() const; 00195 // </group> 00196 00197 // Set the value of the requested attribute. For the StokesCoordinate, 00198 // these have no effect (always return True) except for setWorldAxisNames. 00199 // <group> 00200 virtual Bool setWorldAxisNames(const Vector<String> &names); 00201 virtual Bool setReferencePixel(const Vector<Double> &refPix); 00202 virtual Bool setLinearTransform(const Matrix<Double> &xform); 00203 virtual Bool setIncrement(const Vector<Double> &inc) ; 00204 virtual Bool setReferenceValue(const Vector<Double> &refval) ; 00205 // </group> 00206 00207 // The set function has no effect as the units must be empty for a StokesCoordinate 00208 // Always returns True 00209 // <group> 00210 virtual Bool setWorldAxisUnits(const Vector<String> &units); 00211 virtual Vector<String> worldAxisUnits() const; 00212 // </group> 00213 00214 // Set the world min and max ranges, for use in function <src>toMix</src>, 00215 // for a lattice of the given shape (for this coordinate). 00216 // The implementation here gives world coordinates at the start 00217 // and end of the Stokes axis. 00218 // The output vectors are resized. Returns False if fails (and 00219 // then <src>setDefaultWorldMixRanges</src> generates the ranges) 00220 // with a reason in <src>errorMessage()</src>. 00221 // The <src>setDefaultWorldMixRanges</src> function 00222 // gives you [-1e99->1e99]. 00223 // <group> 00224 virtual Bool setWorldMixRanges (const IPosition& shape); 00225 virtual void setDefaultWorldMixRanges (); 00226 //</group> 00227 00228 // Format a StokesCoordinate world value with the common format 00229 // interface (refer to the base class <linkto class=Coordinate>Coordinate</linkto> 00230 // for basics. 00231 // 00232 // A StokesCoordinate is formatted differently from other Coordinate 00233 // types. The world value is converted to the character representation 00234 // as defined by the enum <src>StokesTypes</src> in the class 00235 // <linkto class=Stokes>Stokes</linkto>. 00236 // 00237 // Thus, all other arguments to do with formatting and precision are ignored. 00238 virtual String format(String& units, 00239 Coordinate::formatType format, 00240 Double worldValue, 00241 uInt worldAxis, 00242 Bool isAbsolute=True, 00243 Bool showAsAbsolute=True, 00244 Int precision = -1, Bool usePrecForMixed=False) const; 00245 00246 // Comparison function. Any private Double data members are compared 00247 // with the specified fractional tolerance. Don't compare on the specified 00248 // axes in the Coordinate. If the comparison returns False, method 00249 // errorMessage returns a message about why. 00250 // <group> 00251 virtual Bool near(const Coordinate& other, 00252 Double tol=1e-6) const; 00253 virtual Bool near(const Coordinate& other, 00254 const Vector<Int>& excludeAxes, 00255 Double tol=1e-6) const; 00256 // </group> 00257 00258 // Save the StokesCoordinate into the supplied record using the supplied field name. 00259 // The field must not exist, otherwise <src>False</src> is returned. 00260 virtual Bool save(RecordInterface &container, 00261 const String &fieldName) const; 00262 00263 // Recover the StokesCoordinate from a record. 00264 // A null pointer means that the restoration did not succeed - probably 00265 // because fieldName doesn't exist or doesn't contain a CoordinateSystem. 00266 static StokesCoordinate* restore(const RecordInterface &container, 00267 const String &fieldName); 00268 00269 // Make a copy of the StokesCoordinate using new. The caller is responsible for calling 00270 // delete. 00271 virtual Coordinate *clone() const; 00272 00273 00274 // Comparison only made for specified axes in this and other Coordinate 00275 virtual Bool doNearPixel (const Coordinate& other, 00276 const Vector<Bool>& thisAxes, 00277 const Vector<Bool>& otherAxes, 00278 Double tol=1.0e-6) const; 00279 00280 private: 00281 00282 Bool toWorld(Double& world, const Double pixel) const; 00283 Bool toPixel(Double& pixel, const Double world) const; 00284 // 00285 Block<Int> values_p; 00286 00287 // Keep these for subimaging purposes. 00288 Double crval_p, crpix_p, matrix_p, cdelt_p; 00289 String name_p; 00290 String unit_p; 00291 Int nValues_p; 00292 00293 // Undefined and inaccessible 00294 StokesCoordinate(); 00295 }; 00296 00297 } //# NAMESPACE CASACORE - END 00298 00299 00300 #endif 00301