casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
EarthMagneticMachine.h
Go to the documentation of this file.
00001 //# EarthMagneticMachine.h: Calculates magnetic field in a direction  
00002 //# Copyright (C) 1998,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: EarthMagneticMachine.h 18093 2004-11-30 17:51:10Z ddebonis $
00027 
00028 #ifndef MEASURES_EARTHMAGNETICMACHINE_H
00029 #define MEASURES_EARTHMAGNETICMACHINE_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <measures/Measures.h>
00034 #include <measures/Measures/MCDirection.h>
00035 #include <casa/Quanta/MVPosition.h>
00036 #include <measures/Measures/EarthField.h>
00037 #include <casa/Quanta/MVEarthMagnetic.h>
00038 
00039 namespace casa { //# NAMESPACE CASA - BEGIN
00040 
00041 //# Forward Declarations
00042 class MeasFrame;
00043 class MPosition;
00044 class MEpoch;
00045 
00046 template <class T> class Vector;
00047 
00048 // <summary> Calculates magnetic field in a direction </summary>
00049 
00050 // <use visibility=export>
00051 
00052 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tEarthMagneticMachine.cc" demos="">
00053 // </reviewed>
00054 
00055 // <prerequisite>
00056 //   <li> <linkto class=MEarthMagnetic>MEarthMagnetic</linkto> class
00057 //   <li> <linkto class=MDirection>MDirection</linkto> class
00058 // </prerequisite>
00059 //
00060 // <etymology>
00061 // From Earth' magnetic Field and machinery
00062 // </etymology>
00063 //
00064 // <synopsis>
00065 // The construction of an EarthMagneticMachine class object creates a
00066 // machine that can
00067 // calculate the magnetic field in an arbitrary direction.
00068 //
00069 // The constructors need a reference code (and possibly frame) input 
00070 // <linkto class=MDirection>MDirection::Ref</linkto>  to specify how the
00071 // the input coordinates have to be interpreted (e.g. MDirection::HADEC).
00072 // It also needs an altitude above the Earth for which the field has to be
00073 // calculated. The position on Earth can be given as either a 
00074 // <linkto class=MPosition>position</linkto>, or as a frame containing the
00075 // position. In the latter case the frame will also be used in the
00076 // coordinate transformations.
00077 //
00078 // Once the EarthMagneticMachine has been established, it can be used to
00079 // calculate
00080 // the field by the <em>calculate(MVDirection)</em> method. A variety of
00081 // get methods let you obtain e.g. the field along the line of sight, the
00082 // longitude of the point for which the field was calculated (e.g. the
00083 // sub-ionospheric point). 
00084 // </synopsis>
00085 //
00086 // <example>
00087 // <srcblock>
00088 //      // Define a time/position frame
00089 //      MEpoch epo(MVEpoch(MVTime(98,5,16,0.5).day()));
00090 //      MPosition pos;
00091 //      MeasTable::Observatory(pos, "ATCA");
00092 //      MeasFrame frame(epo, pos);
00093 //      // Note that e.g. the time in the frame can be changed later
00094 //      // Set up a machine
00095 //      EarthMagneticMachine exec(MDirection::B1950, Quantity(200, "km"), frame);
00096 //      // Given a current observational direction
00097 //      MDirection indir(Quantity(3.25745692, "rad"),
00098 //                       Quantity(0.040643336,"rad"),
00099 //                       MDirection::Ref(MDirection::B1950));
00100 //      // The field in this direction is calculated
00101 //      exec.calculate(indir.getValue());
00102 //      // Show some data
00103 //      cout << "Parallel field: " << exec.getLOSField() << " nT" << endl;
00104 //      cout << "Sub-ionosphere long: " << exec.getLong("deg") << endl;
00105 // </srcblock>
00106 // </example>
00107 //
00108 // <motivation>
00109 // To aid calculating fields in a simple way.
00110 // </motivation>
00111 //
00112 // <todo asof="1998/01/21">
00113 //   <li> add more get() values if necessary
00114 // </todo>
00115 
00116 class EarthMagneticMachine {
00117 public:
00118   //# Constructors
00119   // Construct an empty machine (probably not usable unles set() used)
00120   EarthMagneticMachine();
00121   // Construct a machine from the input values. Either a height or direction
00122   // is normally specified. The other can be set(), or can be iterated
00123   // over in the () operator or the getLOSfield().
00124   // <thrown>
00125   //   <li> AipsError if frame does not contain position and time
00126   // </thrown>
00127   // <group>
00128   EarthMagneticMachine(const MDirection::Ref &in, const Quantum<Double> &hgt,
00129                        MeasFrame &frame);
00130   EarthMagneticMachine(const MDirection::Ref &in, const Quantum<Double> &hgt,
00131                        const MPosition &pos, const MEpoch &tm);
00132   EarthMagneticMachine(const MDirection::Ref &in, const MVDirection &dir,
00133                        MeasFrame &frame);
00134   EarthMagneticMachine(const MDirection::Ref &in, const MVDirection &dir,
00135                        const MPosition &pos, const MEpoch &tm);
00136   // </group>
00137   // Copy constructor
00138   EarthMagneticMachine(const EarthMagneticMachine &other);
00139   // Copy assignments
00140   EarthMagneticMachine &operator=(const EarthMagneticMachine &other);
00141 
00142   //# Destructor
00143   ~EarthMagneticMachine();
00144 
00145   //# Operators
00146   // Return line-of-sight field (nT or given units) (from previous calculate
00147   // if no direction or height given)
00148   // <group>
00149   Double operator()();
00150   Quantum<Double> operator()(const Unit &un);
00151   Double operator()(const MVDirection &in);
00152   Quantum<Double> operator()(const MVDirection &in, const Unit &un);
00153   Double operator()(const Quantum<Double> &in);
00154   Quantum<Double> operator()(const Quantum<Double> &in, const Unit &un);
00155   Double operator()(const Double in);
00156   Quantum<Double> operator()(const Double in, const Unit &un);
00157   // </group>
00158 
00159   //# Member functions
00160   // Set or reset part of the machine
00161   // <group>
00162   void set(const MDirection::Ref &in);
00163   void set(const Quantum<Double> &hgt);
00164   void set(MeasFrame &frame);
00165   void set(const MPosition &pos);
00166   void set(const MEpoch &tm);
00167   void set(const MVDirection &dir);
00168   //</group>
00169   // Calculate a value from direction or height (in m if not Quantity)
00170   // <group>
00171   Bool calculate(const MVDirection &in);
00172   Bool calculate(const Quantum<Double> &hgt);
00173   Bool calculate(const Double hgt);
00174   // </group>
00175   // Return data
00176   // <group>
00177   // Line-of-sight field in nT
00178   // <group>
00179   Double getLOSField();
00180   Double getLOSField(const MVDirection &in);
00181   Double getLOSField(const Quantum<Double> &in);
00182   Double getLOSField(const Double in);
00183   // </group>
00184   // Line-of-sight field in specified units (e.g. G)
00185   // <group>
00186   Quantum<Double> getLOSField(const Unit &un);
00187   Quantum<Double> getLOSField(const MVDirection &in, const Unit &un);
00188   Quantum<Double> getLOSField(const Quantum<Double> &in, const Unit &un);
00189   Quantum<Double> getLOSField(const Double in, const Unit &un);
00190   // </group>
00191   // Field (in nT, in ITRF)
00192   // <group>
00193   const MVEarthMagnetic &getField();
00194   const MVEarthMagnetic &getField(const MVDirection &in);
00195   // </group>
00196   // Longitude (rad)
00197   // <group>
00198   Double getLong();
00199   Double getLong(const MVDirection &in);
00200   // </group>
00201   // Longitude in units (e.g. deg)
00202   // <group>
00203   Quantum<Double> getLong(const Unit &un);
00204   Quantum<Double> getLong(const MVDirection &in, const Unit &un);
00205   // </group>
00206   // Position point
00207   // <group>
00208   const MVPosition &getPosition();
00209   const MVPosition &getPosition(const MVDirection &in);
00210   // </group>
00211   // </group>
00212   // Recalculate the machinery
00213   void reCalculate();
00214 
00215 private:
00216 
00217   //# Data
00218   // Input direction reference
00219   MDirection::Ref inref_p;
00220   // Height (m)
00221   Double hgt_p;
00222   // Observatory position
00223   MVPosition pos_p;
00224   // Distance to Earth centre
00225   Double posl_p;
00226   // Distance squared to sub-point
00227   Double subl_p;
00228   // Epoch
00229   Double epo_p;
00230   // Conversion engine
00231   MDirection::Convert conv_p;
00232   // Input position
00233   MVDirection in_p;
00234   // Re-typed input position
00235   MVDirection rin_p;
00236   // Extension calculated
00237   // <group>
00238   Bool fex_p;
00239   Bool pex_p;
00240   // </group>
00241   // Position sub-point
00242   MVPosition sub_p;
00243   // Earth field calculator
00244   EarthField fldc_p;
00245   // Magnetic field
00246   MVEarthMagnetic fld_p;
00247   // Line-of-sight field
00248   Double los_p;
00249   // Field position
00250   Vector<Double> pl_p;
00251   // Fields filled
00252   Int fil_p;
00253   // Cumulative filled fields
00254   Int cumf_p;
00255   // Calc done
00256   Bool clx_p;
00257 
00258   //# Private Member Functions
00259   // Initialise machinery
00260   void init();
00261   // Copy data members
00262   void copy(const EarthMagneticMachine &other);
00263   // Calculate field
00264   void calculate();
00265 };
00266 
00267 
00268 } //# NAMESPACE CASA - END
00269 
00270 #endif