casa
$Rev:20696$
|
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