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