casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
UVWMachine.h
Go to the documentation of this file.
00001 //# UVWMachine.h: Converts UVW coordinates between coordinate systems 
00002 //# Copyright (C) 1998,2001
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: UVWMachine.h 21024 2011-03-01 11:46:18Z gervandiepen $
00027 #ifndef MEASURES_UVWMACHINE_H
00028 #define MEASURES_UVWMACHINE_H
00029 
00030 //# Includes
00031 #include <casa/aips.h>
00032 #include <measures/Measures.h>
00033 #include <measures/Measures/MCDirection.h>
00034 #include <casa/Quanta/MVPosition.h>
00035 #include <casa/Quanta/RotMatrix.h>
00036 
00037 namespace casa { //# NAMESPACE CASA - BEGIN
00038 
00039 //# Forward Declarations
00040 class MeasFrame;
00041 template <class T> class Vector;
00042 
00043 // <summary> Converts UVW coordinates between coordinate systems  </summary>
00044 
00045 // <use visibility=export>
00046 
00047 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tUVWMachine.cc" demos="">
00048 // </reviewed>
00049 
00050 // <prerequisite>
00051 //   <li> <linkto class=MDirection>MDirection</linkto> class
00052 // </prerequisite>
00053 //
00054 // <etymology>
00055 // From UVW coordinates and machinery
00056 // </etymology>
00057 //
00058 // <synopsis>
00059 // The construction of a UVWMachine class object creates a machine that can
00060 // convert UVW coordinates from one coordinate system to another. In addition
00061 // it can also supply the phase rotation necessary to move to a new position.
00062 //
00063 // The constructors need an input 
00064 // <linkto class=MDirection>MDirection</linkto>  to specify the input UVW
00065 // coordinates reference direction and coordinate system.
00066 // An EW flag can be specified to indicate the different type of UVW 
00067 // coordinates. I.e. projection along polar axis rather than towards
00068 // observing direction (not implemented yet).
00069 // A project flag, if set, will re-project the resulting UV plane onto the
00070 // in-direction reference plane.
00071 //
00072 // The constructors also need an output coordinate system
00073 // (<linkto class=MeasRef>MDirection::Ref</linkto>) or an output
00074 // MDirection (including the reference coordinate system). The first case
00075 // indicates that the real position on the sky does not change (only the
00076 // coordinate system used); the second indicates that the UVW should be
00077 // for a new position on the sky (in addition to maybe a different
00078 // coordinate system). In the first case only the UVW coordinates will change,
00079 // in the second the UVW positions will change, but also the phase of the
00080 // observed data will have to change. For some conversions a reference
00081 // <linkto class=MeasFrame>frame</linkto> is needed (to indicate e.g. the
00082 // position or time). This frame can be part of one of the constructor
00083 // references, but can also be specified separately in the constructor. A
00084 // change in the frame parameter can be made outside the UVWMachine
00085 // by e.g. <em>frame.reset(anMEpoch)</em>.
00086 // <note role=caution>
00087 // If the frame is changed by the user of the conversion machine, the
00088 // machine has to be reinitialised before using it for output by using
00089 // <tt>reCalculate()</tt>.
00090 //
00091 // Projection entails a rotation. For changes to a fixed frame (i.e. not
00092 // changing with e.g. time), the rotation matrix is calculated only once. In
00093 // other cases it has to be calculated per series of uvw conversions. The
00094 // latter case can hence be time consuming.
00095 // </note>
00096 // <note role=tip>
00097 // If either the input or output direction/reference specifies a planet, action
00098 // is special. Planets are assumed to be in J2000 positions, since that is
00099 // the only way to carry them from conversion to conversion (and also have a
00100 // variable phase-center; which can, btw, always be obtained by the
00101 // phaseCenter() member).</note>
00102 // Note that a reCalculate() is necessary between calls of the engine,
00103 // since the planetary position will change from time to time (i.e. with
00104 // the Frame).
00105 //
00106 // If no explicit output coordinate is given (i.e. no phase shift necessary),
00107 // and the conversion from input to output is an essential NOP, and no
00108 // reprojection to the input plane is required, the machine will bypass all
00109 // calculations. This state can be inspected by the <src>isNOP()</src> method.
00110 //
00111 // If you want to convert to say an azimuth/elevation map of the Sun, this
00112 // can be done to have either two conversion engines (original to Sun, then
00113 // Sun to AzEl), or by conversion of the Sun to AzEl before entering the
00114 // engine.
00115 // <note role=tip>
00116 // The output of the machine is either a set of rotation matrices that can
00117 // be used to convert UVW coordinates (and, if necessary, phases); or the
00118 // UVW conversion and actual phase can be calculated from a given
00119 // UVW coordinate (or set of coordinates).
00120 // </note>
00121 // <note role=tip> Since e.g. in an EW interferometer (or any set of baselines
00122 // on a line) the phase correction and UVW transform scales with the length
00123 // of the baseline, conversion of a nominal (say 1m) baseline suffices to
00124 // easily calculate others. The same is true for baselines in a plane,
00125 // where a conversion of two orthogonal baselines in that plane will suffice.
00126 // </note>
00127 // </synopsis>
00128 //
00129 // <example>
00130 // <srcblock>
00131 //      // Given a current phase stopping Center
00132 //      MDirection indir(Quantity(3.25745692, "rad"),
00133 //                       Quantity(0.040643336,"rad"),
00134 //                       MDirection::Ref(MDirection::B1950));
00135 //      // Conversion to J2000 is set by:
00136 //      UVWMachine uvm(MDirection::Ref(MDirection::J2000), indir);
00137 //      // The rotation matrix to go to new UVW is obtained by:
00138 //      RotMatrix rm(uvm.rotationUVM());
00139 //      // If an UVW specified:
00140 //      MVPosition uvw(-739.048461, -1939.10604, 1168.62562);
00141 //      // This can be converted by e.g.:
00142 //      uvw *= rm;
00143 //      // Or, alternatively, by e.g.:
00144 //      uvm.convertUVW(uvw);
00145 // </srcblock>
00146 // </example>
00147 //
00148 // <motivation>
00149 // To aid making maps in different coordinate systems
00150 // </motivation>
00151 //
00152 // <todo asof="1998/01/21">
00153 //   <li> add EW UVW coordinates
00154 //   <li> check if non right-handed coordinates systems (like AzEl) are
00155 //      handled correctly
00156 //   <li> provide a MVuvw and Muvw class to cater for second order effects
00157 //              appropiately
00158 // </todo>
00159 
00160 class UVWMachine {
00161  public:
00162   //# Constructors
00163   // Constructors have an EW flag, which will give a projection parallel to
00164   // the polar axis rather than in the direction of the fieldcenter, and a
00165   // project flag. The last will correct the UV coordinates to re-project
00166   // them onto the plane specified by the in direction
00167   // <group>
00168   // Construct a UVW conversion machine from the in coordinate and its
00169   // system to the out coordinate system (output absolute direction 
00170   // remains the same)
00171   UVWMachine(const MDirection::Ref &out, const MDirection &in,
00172              Bool EW=False, Bool project=False);
00173   // Construct a UVW conversion machine from the in coordinate and its
00174   // system to the out coordinate and its system
00175   UVWMachine(const MDirection &out, const MDirection &in,
00176              Bool EW=False, Bool project=False);
00177   // Construct UVW conversion machine with an explicitly given frame
00178   // <group>
00179   UVWMachine(const MDirection::Ref &out, const MDirection &in,
00180              const MeasFrame &frame, Bool EW=False, Bool project=False);
00181   UVWMachine(const MDirection &out, const MDirection &in, 
00182              const MeasFrame &frame, Bool EW=False, Bool project=False);
00183   // </group>
00184   // </group>
00185   // Copy constructor
00186   UVWMachine(const UVWMachine &other);
00187   // Copy assignments
00188   UVWMachine &operator=(const UVWMachine &other);
00189 
00190   //# Destructor
00191   ~UVWMachine();
00192 
00193   //# Operators
00194   // Return converted UVW coordinates
00195   // <group>
00196   Vector<Double> operator()(const Vector<Double> &uv) const;
00197   Vector<Vector<Double> > operator()(const Vector<Vector<Double> > &uv) const;
00198   MVPosition operator()(const MVPosition &uv) const;
00199   Vector<MVPosition > operator()(const Vector<MVPosition > &uv) const;
00200   // </group>
00201 
00202   //# Member functions
00203   // Return the new phase center coordinates
00204   const MDirection &phaseCenter() const;
00205   // Return if the engine is an effective NOP
00206   Bool isNOP() { return nop_p; }
00207   // Return a rotation matrix that can be used to convert UVW coordinates:
00208   // UVW(new) = UVW(old) * rotationUVW()
00209   const RotMatrix &rotationUVW() const;
00210   // Return a position vector that can produce the phase correction:
00211   // dPhase = rotationPhase * UVW(new)
00212   const MVPosition &rotationPhase() const;
00213   // replace UVW with converted values
00214   // <group>
00215   void convertUVW(Vector<Double> &uv) const;
00216   void convertUVW(Vector<Vector<Double> > &uv) const;
00217   void convertUVW(MVPosition &uv) const;
00218   void convertUVW(Vector<MVPosition > &uv) const;
00219   // </group>
00220   // Get phase shift (in implied units of UVW), and change input uvw as well
00221   // <group>
00222   Double getPhase(Vector<Double> &uv) const;
00223   Vector<Double> getPhase(Vector<Vector<Double> > &uv) const;
00224   Double getPhase(MVPosition &uv) const;
00225   Vector<Double> getPhase(Vector<MVPosition > &uv) const;
00226   // </group>
00227   // Replace UVW with converted, and return phase
00228   // <group>
00229   void convertUVW(Double &phase, Vector<Double> &uv) const;
00230   void convertUVW(Vector<Double> &phase, Vector<Vector<Double> > &uv) const;
00231   void convertUVW(Double &phase, MVPosition &uv) const;
00232   void convertUVW(Vector<Double> &phase, Vector<MVPosition> &uv) const;
00233   // </group>
00234 
00235   // Recalculate the parameters for the machine after e.g. a frame change
00236   void reCalculate();
00237 
00238  private:
00239 
00240   //# Data
00241   // EW flag
00242   Bool ew_p;
00243   // Projection flag
00244   Bool proj_p;
00245   // Zero phase flag (for speed)
00246   Bool zp_p;
00247   // No conversion necessary flag
00248   Bool nop_p;
00249   // Old phase center
00250   MDirection in_p;
00251   // New coordinate reference
00252   MDirection::Ref outref_p;
00253   // Old phase center in new coordinates
00254   MDirection outin_p;
00255   // New phase center
00256   MDirection out_p;
00257   // Rotation Matrix to go from input UVW to coordinate system
00258   RotMatrix rot1_p;
00259   // Rotation matrix to go from old system to new system
00260   RotMatrix rot2_p;
00261   // Rotation Matrix to go from new coordinate system to output UVW
00262   RotMatrix rot3_p;
00263   // Rotation Matrix to project UV-plane onto
00264   RotMatrix rot4_p;
00265   // UVW rotation
00266   RotMatrix uvrot_p;
00267   // UVW rotation including projection
00268   RotMatrix uvproj_p;
00269   // Phase rotation
00270   MVPosition phrot_p;
00271   // Conversion engine
00272   MDirection::Convert conv_p;
00273 
00274   //# Constructors
00275   // default constructor: not implemented
00276   UVWMachine();
00277 
00278   //# Private Member Functions
00279   // Initialise machinery
00280   void init();
00281   // Planet handling
00282   void planetinit();
00283   // Copy data members
00284   void copy(const UVWMachine &other);
00285 };
00286 
00287 
00288 } //# NAMESPACE CASA - END
00289 
00290 #endif
00291 
00292