casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
VelocityMachine.h
Go to the documentation of this file.
00001 //# VelocityMachine.h: Converts between velocities and frequencies
00002 //# Copyright (C) 1998,1999,2000
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: VelocityMachine.h 18093 2004-11-30 17:51:10Z ddebonis $
00027 
00028 #ifndef MEASURES_VELOCITYMACHINE_H
00029 #define MEASURES_VELOCITYMACHINE_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <casa/Quanta/Unit.h>
00034 #include <casa/Quanta/Quantum.h>
00035 #include <measures/Measures/MCFrequency.h>
00036 #include <measures/Measures/MCDoppler.h>
00037 #include <measures/Measures/MeasConvert.h>
00038 
00039 namespace casa { //# NAMESPACE CASA - BEGIN
00040 
00041 //# Forward Declarations
00042 class MeasFrame;
00043 template <class T> class Vector;
00044 
00045 // <summary> Converts between velocities and frequencies </summary>
00046 
00047 // <use visibility=export>
00048 
00049 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tVelocityMachine.cc" demos="">
00050 // </reviewed>
00051 
00052 // <prerequisite>
00053 //   <li> <linkto module=Measures>Measures</linkto> module
00054 //   <li> <linkto class=MFrequency>MFrequency</linkto> class
00055 //   <li> <linkto class=MDoppler>MDoppler</linkto> class
00056 // </prerequisite>
00057 //
00058 // <etymology>
00059 // From Velocity and machinery
00060 // </etymology>
00061 //
00062 // <synopsis>
00063 // The construction of a VelocityMachine class object creates a machine that
00064 // can calculate the velocity from a frequency, or vice versa, a frequency
00065 // from a velocity.
00066 //
00067 // To be able to do the conversions, the machine (or rather its constructors)
00068 // needs to know the following information:
00069 // <ul>
00070 //   <li> Reference for frequencies. It should contain at least the reference
00071 //      code, to specify what type of frequency we are talking about
00072 //      (e.g. MFrequency::LSRK). The reference could also contain an offset.
00073 //      In that case all
00074 //      input frequencies are considered to be relative to this offset; all
00075 //      output frequencies will have this offset removed.<br>
00076 //      The reference can optionally contain a MeasFrame (which
00077 //      specifies where, when and in which direction you are
00078 //      observing). This frame is necessary if, in addition to
00079 //      converting between velocity and frequency, you also want to
00080 //      convert between different types (e.g. given an 'LSRK' velocity,
00081 //      you want to know the 'TOPO' frequency), and if the offset is
00082 //      in a different reference type. However, the MeasFrame
00083 //      can also be given explicitly in the machine constructor as an
00084 //      optional argument.
00085 //   <li> Preferred 'frequency' units (e.g. GHz, or cm). These units are used
00086 //      to output a frequency, or if an input frequency is given as a
00087 //      simple double, these units will be implicitly assumed.
00088 //   <li> Reference for velocity. It should contain at least the reference
00089 //      code, to specify what type of velocity we are talking about
00090 //      (e.g. MDoppler::OPTICAL, note
00091 //      that MDoppler::BETA is the 'true' velocity).
00092 //      The reference could also contain an offset. In that case all
00093 //      input velocities are considered to be relative to this offset; all
00094 //      output velocities will have this offset removed.
00095 //   <li> Preferred velocity units (e.g. AU/a). These units are used
00096 //      to output a velocity, or if an input velocity is given as a
00097 //      simple double, these units will be implicitly assumed.
00098 //   <li> The rest frequency to be used for converting between frequency and
00099 //      velocity. It is given as an MVFrequency.
00100 // </ul>
00101 // To be able to convert between different types (say a velocity
00102 // referenced with respect to the 'LSRK', and a frequency referenced
00103 // with respect to 'TOPO', the following additional, optional
00104 // information can be included explicitly in the constructors:
00105 // <ul>
00106 //   <li> A reference code for the velocity (given as a frequency reference
00107 //      code (e.g. MFrequency::TOPO)). If given, all input frequencies
00108 //      will be converted to the frequency belonging to this reference
00109 //      code; all output frequencies will be converted from this
00110 //      assumed reference to the specified Frequency reference. The
00111 //      net effect is that all velocities will be assumed to refer to
00112 //      this reference code. Note that in most cases the conversion
00113 //      will have to know the 'when, where, which direction'
00114 //      environment (the 'frame' -- a MeasFrame). This can be given
00115 //      either implicitly in the 'reference for the frequency', or
00116 //      explicitly (see next dot point).
00117 //   <li> A frame (MeasFrame). This frame will be used in any conversion
00118 //      between reference frames. If not given explicitly here, it will
00119 //      tacitly be assumed that if a frame is necessary, it has been specified
00120 //      in the frequency reference.
00121 // </ul>
00122 // Once the machine has been set up, operator() can be used to convert
00123 // between velocities and frequencies if the input argument type (e.g. an
00124 // MVFrequency) can be deduced. In other cases makeFrequency() or
00125 // makeVelocity() should be used (e.g. if the argument type is a
00126 // simple Double).
00127 // </synopsis>
00128 //
00129 // <example>
00130 // <srcblock>
00131 //      // Define a time/position frame
00132 //      MEpoch epo(MVEpoch(MVTime(98,5,16,0.5).day()));
00133 //      MPosition pos;
00134 //      MeasTable::Observatory(pos, "ATCA");
00135 //      MeasFrame frame(epo, pos);
00136 //      //
00137 //      // Note that e.g. the time in the frame can be changed later
00138 //      // Specify the frequency reference
00139 //      MFrequency::Ref fr(MFrequency::LSRK);
00140 //      //
00141 //      // Specify the velocity reference
00142 //      MDoppler::Ref vr(MDoppler::OPT);
00143 //      //
00144 //      // Specify the default units
00145 //      Unit fu("eV");
00146 //      Unit vu("AU/a");
00147 //      //
00148 //      // Get the rest frequency
00149 //      MVFrequency rfrq(QC::HI);
00150 //      //
00151 //      // Set up a machine (no conversion of reference frame)
00152 //      VelocityMachine exec(fr, fu, rfrq, vr, vu, frame);
00153 //      //
00154 //      // or as (with conversion of reference frame it could have been)
00155 //      // VelocityMachine exec(fr, fu, rfrq, vr, vu, MFrequency::TOPO, frame);
00156 //      // Given a current observational frequency of 5.87432837e-06 eV
00157 //      // its velocity will be (in AU/yr)
00158 //      cout << "Velocity: " << exec.makeVelocity(5.87432837e-06) << endl;
00159 //      //
00160 //      // Introducing an offset
00161 //      MFrequency foff(MVFrequency(Quantity(5.87432837e-06, "eV")),
00162 //                      MFrequency::LSRK);
00163 //      //
00164 //      // and setting it in the reference, and regenerating machine:
00165 //      fr.set(foff);
00166 //      exec.set(fr);
00167 //      //
00168 //      // the following will give the same result:
00169 //      cout << "Velocity: " << exec.makeVelocity(0.0) << endl;
00170 //      
00171 // </srcblock>
00172 // See the test program for more examples
00173 // </example>
00174 //
00175 // <motivation>
00176 // To aid in converting series of frequencies and velocities
00177 // </motivation>
00178 //
00179 // <todo asof="1998/06/02">
00180 //   <li> Nothing I know of
00181 // </todo>
00182 
00183 class VelocityMachine {
00184 public:
00185   //# Constructors
00186   // Construct a machine from the input values (no frame conversion, implicit
00187   // frame if necessary)
00188   VelocityMachine(const MFrequency::Ref &freqRef, const Unit &freqUnits,
00189                   const MVFrequency &restFreq,
00190                   const MDoppler::Ref &velRef, const Unit &velUnits);
00191 
00192   // Construct a machine from the input values (no frame conversion, explicit
00193   // frame will be added to freqRef)
00194   VelocityMachine(const MFrequency::Ref &freqRef, const Unit &freqUnits,
00195                   const MVFrequency &restFreq,
00196                   const MDoppler::Ref &velRef, const Unit &velUnits,
00197                   const MeasFrame &frame);
00198 
00199   // Construct a machine from the input values (frame conversion, implicit
00200   // frame assumed if necessary) with explicit velocity reference frame
00201   // specified.
00202   VelocityMachine(const MFrequency::Ref &freqRef, const Unit &freqUnits,
00203                   const MVFrequency &restFreq,
00204                   const MFrequency::Types &convertRef,
00205                   const MDoppler::Ref &velRef, const Unit &velUnits);
00206 
00207   // Construct a machine from the input values (frame conversion, explicit
00208   // frame) with explicit velocity reference frame
00209   // specified, and added to freqref.
00210   VelocityMachine(const MFrequency::Ref &freqref, const Unit &freqUnits,
00211                   const MVFrequency &restFreq,
00212                   const MFrequency::Types &convertRef,
00213                   const MDoppler::Ref &velRef, const Unit &velUnits,
00214                   const MeasFrame &frame);
00215 
00216   // Copy constructor (copy semantics)
00217   VelocityMachine(const VelocityMachine &other);
00218 
00219   // Copy assignment (copy semantics)
00220   VelocityMachine &operator=(const VelocityMachine &other);
00221 
00222   //# Destructor
00223   ~VelocityMachine();
00224 
00225   //# Operators
00226   // Return velocity if frequency given, or a frequency if a velocity is given
00227   // <group>
00228   const Quantum<Double> &operator()(const MVFrequency &in);
00229   const Quantum<Double> &operator()(const MVDoppler &in);
00230   const Quantum<Double> &operator()(const Quantum<Double> &in);
00231   const Quantum<Double> &makeVelocity(Double in);
00232   const Quantum<Double> &makeFrequency(Double in);
00233   const Quantum<Vector<Double> > &makeVelocity(const Vector<Double> &in);
00234   const Quantum<Vector<Double> > &makeFrequency(const Vector<Double> &in);
00235   // </group>
00236 
00237   //# Member functions
00238   // Set or reset the specified part of the machine. The machinery will be
00239   // reset to reflect the changes made.
00240   // <group>
00241   // Sets a new frequency reference. Note that if an explicit frame has been
00242   // used in earlier constructors, the frame should again be set explicitly
00243   // with set(MeasFrame).
00244   void set(const MFrequency::Ref &in);
00245   void set(const Unit &in);
00246   // Sets the rest frequency
00247   void set(const MVFrequency &in);
00248   void set(const MFrequency::Types &in);
00249   void set(const MDoppler::Ref &in);
00250   // Sets the MeasFrame to be used in conversions.
00251   void set(const MeasFrame &in);
00252   // </group>
00253 
00254   // Get the general information used in the machine (shadows the sets above
00255   // and the constructor arguments. The MeasFrame should be explicitly
00256   // asked for from the frequency reference by the user
00257   // <group>
00258   const MFrequency::Ref &getFrequencyReference() const;
00259   const Unit &getFrequencyUnits() const;
00260   const MDoppler::Ref &getDopplerReference() const;
00261   const Unit &getDopplerUnits() const;
00262   const MVFrequency &getRestFrequency() const;
00263   const MFrequency::Types &getConversionReference() const;
00264   // </group>
00265   // Recalculate the machinery from the original inputs. Note that in all
00266   // normal circumstances this function does not have to be used (the set()
00267   // methods will do it automatically). At the moment I cannot think of
00268   // any circumstance it should be used explicitly.
00269   void reCalculate();
00270 
00271 private:
00272 
00273   //# Constructors
00274   // Construct an empty machine (not implemented)
00275   VelocityMachine();
00276 
00277   //# Data
00278   // Frequency reference
00279   MFrequency::Ref fref_p;
00280   // Frequency units
00281   // <group>
00282   Unit fun_p;
00283   // </group>
00284   // Rest frequency
00285   MVFrequency rest_p;
00286   // Velocity frame
00287   MFrequency::Types vfm_p;
00288   // Velocity reference
00289   MDoppler::Ref vref_p;
00290   // Velocity units
00291   // <group>
00292   Unit vun_p;
00293   Double vfac_p;
00294   // </group>
00295   // Frequency conversion forward
00296   MFrequency::Convert cvfv_p;
00297   // Frequency conversion backward
00298   MFrequency::Convert cvvf_p;
00299   // Velocity conversion forward
00300   MDoppler::Convert cvvo_p;
00301   // Velocity conversion backward
00302   MDoppler::Convert cvov_p;
00303   // Result
00304   // <group>
00305   Quantum<Double> resv_p;
00306   Quantum<Double> resf_p;
00307   Quantum<Vector<Double> > vresv_p;
00308   Quantum<Vector<Double> > vresf_p;
00309   // </group>
00310 
00311   //# Private Member Functions
00312   // Initialise machinery
00313   void init();
00314   // Copy data members
00315   void copy(const VelocityMachine &other);
00316 };
00317 
00318 
00319 } //# NAMESPACE CASA - END
00320 
00321 #endif