casa
$Rev:20696$
|
00001 //# Measure.h: Physical quantities within reference frame 00002 //# Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 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 //# 00027 //# $Id: Measure.h 21024 2011-03-01 11:46:18Z gervandiepen $ 00028 00029 #ifndef MEASURES_MEASURE_H 00030 #define MEASURES_MEASURE_H 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <casa/iosfwd.h> 00035 00036 namespace casa { //# NAMESPACE CASA - BEGIN 00037 00038 //# Forward Declarations 00039 class String; 00040 class Unit; 00041 class MeasValue; 00042 class MRBase; 00043 template <class T> class Quantum; 00044 template <class T> class Vector; 00045 00046 // <summary> 00047 // Physical quantities within reference frame 00048 // </summary> 00049 00050 // <use visibility=export> 00051 00052 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tMeasure" demos=""> 00053 // </reviewed> 00054 00055 // <prerequisite> 00056 // <li> <linkto module="Measures">Measures module</linkto> description 00057 // <li> <linkto class=Quantum>Quantum</linkto> dimensioned values 00058 // <li> <linkto class=MeasValue>MeasValue</linkto> internal measure values 00059 // <li> <linkto class=MeasRef>MeasRef</linkto> class to specify reference 00060 // frame 00061 // <li> <linkto class=MeasConvert>MeasConvert</linkto> class, doing actual conversions 00062 // of a measure from one reference frame to another 00063 // <li> Some classes if you really want to understand details: 00064 // <ul> 00065 // <li> <linkto class=MeasBase>MeasBase</linkto> class, the immediate 00066 // parent of all specific Measures 00067 // <li> <linkto class=MCBase>MCBase</linkto> class, the base class 00068 // for all specific conversion routines (like 00069 // <linkto class=MCEpoch>MCEpoch</linkto>). 00070 // <li> <linkto class=MeasData>MeasData</linkto> class, containing a set 00071 // of generally usable constants, and all program data necessary for 00072 // conversions. 00073 // </ul> 00074 // <li> <linkto class=MeasTable>MeasTab;e</linkto> class, containing 00075 // the interface for external Tables (like leap-seconds, IERS data, 00076 // JPL data). 00077 // </prerequisite> 00078 // 00079 // <etymology> 00080 // </etymology> 00081 // 00082 // <synopsis> 00083 // Measure forms the abstract base class for physical quantities within 00084 // a reference frame. Examples of derived classes are: 00085 // <ul> 00086 // <li> <linkto class=MEpoch>MEpoch</linkto>: a moment in time 00087 // <li> <linkto class=MDirection>MDirection</linkto>: a direction in space 00088 // <li> <linkto class=MPosition>MPosition</linkto>: a position on Earth 00089 // <li> <linkto class=MFrequency>MFrequency</linkto>: wave characteristics 00090 // <li> <linkto class=MRadialVelocity>MRadialVelocity</linkto>: a space 00091 // radial velocity 00092 // <li> <linkto class=MDoppler>MDoppler</linkto>: a Doppler velocity 00093 // </ul> 00094 // Measure is the generic name for the more specific instances like, e.g., 00095 // MEpoch, an instant in time.<br> 00096 // A Measure has both a value (specified in some value internal to the specific 00097 // Measure, in general called <em>MVMeasure</em> (e.g. MVEpoch)), see 00098 // <linkto class=MeasValue>MeasValue</linkto> for general details; and a 00099 // reference type and frame specifier (see 00100 // <linkto class=MeasRef>MeasRef</linkto> class).<br> 00101 // The <linkto class=MeasRef>MeasRef</linkto> specifies the reference type 00102 // of the value, e.g. TAI, UTC, LAST. In addition the 00103 // <linkto class=MeasRef>MeasRef</linkto> specifies a possible offset (e.g. 00104 // the beginning of the year, or today), and, if necessary, Measures necessary 00105 // for defining the absolute quantity (e.g. an 00106 // <linkto class=MPosition>MPosition</linkto> on Earth for LAST), using a 00107 // reference frame specifier (see 00108 // <linkto class=MeasFrame>MeasFrame</linkto> class).<br> 00109 // The <src>MeasRef</src> class is templated, but typedefs exist 00110 // (and should be used) to 00111 // easily specify the correct one, e.g. <src>MEpoch::Ref</src>.<br> 00112 // A Measure can be converted from one reference frame to another (e.g. 00113 // an MDirection can be converted from J2000 to apparent coordinates) by 00114 // setting up a measure specific conversion engine (see 00115 // <linkto class=MeasConvert>MeasConvert</linkto> class and below). 00116 // From an input 00117 // <src>MeasRef</src> frame and an output <src>MeasRef</src> frame it 00118 // constructs a conversion <em>functional</em>, that can be fed values (with 00119 // the <src>() operator</src>).<br> 00120 // Some conversions can, in addition to the main type (like TAI), specify 00121 // details to completely describe any conversion process (e.g. the type 00122 // of nutation calculation) by specifying 00123 // <linkto class=Aipsrc>Aipsrc</linkto> keyword/value pairs. <br> 00124 // <p> 00125 // Measures can in general be constructed from a <src>MeasRef</src> and a 00126 // value. The value can be expressed in the internally used units (e.g. 00127 // <linkto class=MVEpoch>MVEpoch</linkto> for <src>MEpoch</src>, 00128 // <linkto class=MVDirection>MVDirection</linkto> for <src>MDirection</src>), or 00129 // as a <src>Quantum</src>, i.e. a value with a dimension (e.g. (20,"km/s")) 00130 // (see <linkto class=Quantum>Quantum</linkto> class). The preferred way of 00131 // construction is by using the constructor: 00132 // <srcblock> 00133 // Measure(MVmeasure, Measure::Ref) 00134 // </srcblock> 00135 // where the reference can be omitted, 00136 // defaulting to <src>Measure::DEFAULT</src>), or in simple cases (not needing 00137 // additional frame information) be specified directly as a code (e.g. 00138 // <src>MEpoch::IAT</src>).<br> 00139 // <p> 00140 // The value of the <src>Measure</src> can be obtained by a variety of 00141 // <src>get</src> functions, returning in general internal or <src>Quantum</src> 00142 // values. The preferred way is a <src>getValue(void)</src>, which returns 00143 // the specific <src>MVmeasure</src> value, which can then be further formatted 00144 // using the appropiate <src>MVmeasure</src> get() functions.<br> 00145 // Special formatting (like hh:mm:ss.t, dd.mm.ss.t, yy/mm/dd etc) 00146 // are catered for in <em>conversion-type</em> classes like 00147 // <linkto class=MVAngle>MVAngle</linkto>, 00148 // <linkto class=MVTime>MVTime</linkto>.<br> 00149 // <p> 00150 // Conversion (within a Measure type) from one reference frame to another 00151 // is done by the <linkto class=MeasConvert>MeasConvert</linkto> class. The 00152 // class is templated, but has typedefs <src>Measure::Convert</src> (e.g. 00153 // MEpoch::Convert) for easy, and recommended, reference.<br> 00154 // The basic constructors for a 00155 // <src>Measure::Convert</src> are: 00156 // <srcblock> 00157 // // With a default Measure included 00158 // Measure::Convert(Measure val, Measure::Ref outref); 00159 // // With only input and output reference frames given 00160 // Mesaure::Convert( Measure::Ref inref, Measure::Ref outref); 00161 // </srcblock> 00162 // The <src>val</src> 00163 // is used as a <em>model</em> for subsequent input values into this 00164 // <em>conversion engine</em>, including possible units; the <src>outref</src> 00165 // specifies the output reference frame wanted. The constructor analyses the 00166 // conversion wanted, and sets up a vector of routine calls to be called 00167 // in sequence for the conversion. The actual conversion is done 00168 // by the <src>() operator</src>.<br> 00169 // To aid in using the raw measures, each class has also a Measure::MVType and 00170 // Measure::MCType defined. They denote respectively the Measure Value class 00171 // of the internal value, and the class with conversion routines. 00172 // <p> 00173 // <note role=tip> In the member description a number of <em>dummy</em> routines are 00174 // present. They are the only way I have found to get <em>cxx2html</em> to 00175 // get the belonging text properly present. 00176 // </note> 00177 // </synopsis> 00178 // 00179 // <example> 00180 // <srcblock> 00181 // #include <measures/Measures.h> 00182 // #include <casa/Measure/MEpoch.h> 00183 // // Example is only to show what can be done, not the easiest way 00184 // // Set up a simple reference (no offset or secondary Measures). It 00185 // // indicates that times are given in MJD TAI. 00186 // MEpoch::Ref reftai(MEpoch::TAI); 00187 // // Same, but indicating MJD UTC 00188 // MEpoch::Ref refutc(MEpoch::UTC); 00189 // // Set up an MEpoch (note that no reference is given. In that case a 00190 // // default is assumed (for MEpoch UTC). MJD2000 is a provided constant 00191 // // of the MJD at 2000.0 00192 // MEpoch UTCval(Quantity(MeasData::MJD2000, "d"), reftai); 00193 // // Set up, just for fun, an epoch, UTC for B1950.0: 00194 // MEpoch val1950(Quantity(MeasData::MJDB1950, "d")); 00195 // // and use it as an offset in a reference 00196 // MEpoch::Ref ref1950(MEpoch::TAI, val1950); 00197 // // An epoch for J2000 with an offset of B1950.0 will than be 00198 // MEpoch val20_50(Quantity(MeasData::MJD2000-MeasData::MJDB1950, "d"), 00199 // ref1950); 00200 // // Set up conversion from TAI(with values in days w.r.t. B1950.0) to UTC: 00201 // MEpoch::Convert tai_to_utc(val20_50, refutc); 00202 // // And convert a value (in this case the value in val20_50, the model) 00203 // // from TAI(relative to B1950.0) to 'absolute' UTC 00204 // MEpoch result = tai_to_utc(); 00205 // // Show result 00206 // cout << "Result 1: " << result << endl; 00207 // // To convert 10 years since B1950.0 00208 // result = tai_to_utc(Quantity(10.,"a")); 00209 // cout << "Result 2: " << result << endl; 00210 // // To convert any value in years(the last used units of the model) since B1950.0 00211 // result = tai_to_utc(12.3); 00212 // cout << "Result 3: " << result << endl; 00213 // </srcblock> 00214 // Which generates the output: 00215 // <srcblock> 00216 // Result 1: Epoch: 51544::11:59:25.2154 00217 // Result 2: Epoch: 36934::10:09:42.1283 00218 // Result 3: Epoch: 37774::11:57:41.1085 00219 // </srcblock> 00220 // </example> 00221 // 00222 // <motivation> 00223 // To be able to specify a physical entity absolutely in any reference frame; 00224 // and to be able to convert from one frame to another. E.g. Local Sidereal 00225 // Time to Temps Atomic International. A templated version for the MeasRef 00226 // and MeasConvert was chosen to be able to check most arguments at 00227 // compile time. 00228 // </motivation> 00229 // 00230 // <todo asof='1997/04/15'> 00231 // <li> more Measures, e.g. MPlanet 00232 // <li> operators on Measures (e.g. MEpoch - MEpoch == MDuration) 00233 // </todo> 00234 00235 class Measure { 00236 00237 public: 00238 //# Enumerations 00239 // Each derived class should have a <src>Types</src> enumeration, specifying 00240 // the recognised frame types. It is formatted as: 00241 // <srcblock> 00242 // enum Types { 00243 // CODE1, 00244 // CODE2, 00245 // ..., 00246 // N_Types, // Number of types 00247 // SPEC1 = n, // Possible special manipulator code 00248 // ....., 00249 // SYNONYM1 = CODEn, // Probable synonyms 00250 // ...., 00251 // DEFAULT = CODEm}; 00252 // </srcblock> 00253 // Dummy for cxx2html 00254 enum Types {N_Types, DEFAULT = 0}; 00255 00256 //# Typedefs 00257 // Each Measure should have typedefs of the form: 00258 // <srcblock> 00259 // typedef MeasConvert<class a_Measure, class its_MV, its_MC> Convert; 00260 // typedef MeasRef<class a_Measure> Ref; 00261 // </srcblock> 00262 // Dummy for cxx2html 00263 typedef void* Convert; 00264 //# Friends 00265 // Each derived class should have: 00266 // <srcblock> 00267 // friend class MeasConvert<a_Measure, its_MV, its_MC>; 00268 // </srcblock> 00269 // Output a Measure 00270 friend std::ostream &operator<<(std::ostream &os, const Measure &meas); 00271 00272 //# Constructors 00273 00274 //# Destructor 00275 // Destructor 00276 virtual ~Measure(); 00277 00278 //# Operators 00279 00280 //# General Member Functions 00281 // Each Measure should have the following set functions (with appropiate 00282 // MVs and Ref): 00283 // <srcblock> 00284 // void set(const MVmeasure &dt); 00285 // void set(const Measure::Ref &rf); 00286 // void set(const MVmeasure &dt, const Measure::Ref &rf); 00287 // </srcblock> 00288 // <group> 00289 virtual void set(const MeasValue &dt) = 0; 00290 virtual Bool putValue(const Vector<Quantum<Double> > &in) = 0; 00291 // </group> 00292 // Set the offset in the reference (False if non-matching Measure) 00293 virtual Bool setOffset(const Measure &in) = 0; 00294 // 00295 // Check the type of derived Measure entity (e.g. "Epoch") 00296 virtual Bool areYou(const String &tp) const = 0; 00297 // Get the type (== Register() of derived Measure (faster than Strings) 00298 // All should have: 00299 // static uInt myType(); 00300 virtual uInt type() const = 0; 00301 // Assert that we are the correct Measure type 00302 // <thrown> 00303 // <li> AipsError if wrong Measure type 00304 // </thrown> 00305 // Each Measure should have: 00306 // <src> static void assure(const Measure &in); </src> 00307 // <group> 00308 virtual void assured(const String &tp) const = 0; 00309 // </group> 00310 // Tell me your Measure type (e.g. "Epoch") 00311 virtual const String &tellMe() const = 0; 00312 00313 // Each Measure should have the following static methods to give its 00314 // name (e.g. Epoch) or reference type (e.g. UTC):<br> 00315 // <srcblock> 00316 // // Show the Measure type (e.g. "Direction") 00317 // static const String &showMe(); 00318 // // Cast an integer to the appropriate reference type. Avaialable to provide 00319 // // a safe cast in cases where Measure type is not explicitly known. 00320 // static Measure::Types castType(uInt tp); 00321 // // Show the reference type (e.g. MEpoch::showType(MEpoch::IAT) == "TAI") 00322 // static const String &showType(uInt tp); 00323 // static const String &showType(Measure::Types tp); 00324 // </srcblock> 00325 // <group> 00326 virtual String getRefString() const = 0; 00327 // </group> 00328 // Tell me if you are a pure model (e.g. a planet) 00329 virtual Bool isModel() const; 00330 // 00331 // Each derived class should have a string-to-code translation routine 00332 // for the reference type. The routine returns False if unknown String (and 00333 // a default mr), else an appropiate mr reference. 00334 // <srcblock> 00335 // Bool giveMe(Measure::Ref &mr, const String &in); 00336 // static Bool getType(Measure::Types &tp, const String &in); 00337 // </srcblock> 00338 // <group> 00339 // Dummy for cxx2html 00340 void dummy_giveMe() const {} 00341 // </group> 00342 // 00343 // Set the reference type to the specified String. False if illegal 00344 // string, reference set to DEFAULT. 00345 virtual Bool setRefString(const String &in) = 0; 00346 // Get the default reference type 00347 virtual const String &getDefaultType() const = 0; 00348 // Get a list of all known reference codes. nall returns the number in list, 00349 // nextra the number of specials (like planets) that should be at 00350 // end of list). typ returns the list of corresponding types. 00351 // All should have 00352 // <srcblock> 00353 // static const String* allMyTypes(Int &nall, Int &nextra, 00354 // const uInt *&typ); 00355 // </srcblock> 00356 // <group> 00357 virtual const String* allTypes(Int &nall, Int &nextra, 00358 const uInt *&typ) const; 00359 // </group> 00360 // 00361 // Check if all internal tables of types (both enum and String) are 00362 // complete and correct. This function is called automatically if and when 00363 // necessary. 00364 // <thrown> 00365 // <li> AipsError if a (programming) error in the types. 00366 // </thrown> 00367 // All should have 00368 // <srcblock> 00369 // static void checkMyTypes(); 00370 // </srcblock> 00371 // <group> 00372 virtual void checkTypes() const = 0; 00373 // </group> 00374 // 00375 // A general string checking routine to be used in derived measures. 00376 // Its arguments are the string to be converted (in), an array of 00377 // strings to check against (tname), and its length (N_name). The check 00378 // is case insensitive and mini-max. A return value less than N_name indicates 00379 // success. 00380 static uInt giveMe(const String &in, Int N_name, 00381 const String tname[]); 00382 // Each class should have a function to return its reference: 00383 // <srcblock> 00384 // Measure::Ref getRef() const; 00385 // </srcblock> 00386 // <group> 00387 // Dummy for cxx2html 00388 void dummy_getRef() const {} 00389 // </group> 00390 // 00391 // Each derived class should be able to get its internal value and have: 00392 // <srcblock> 00393 // const MVmeasure &getValue() const; 00394 // </srcblock> 00395 // To get dimensioned data, each derived class should contain the 00396 // appropiate one of: 00397 // <srcblock> 00398 // Quantity get(const Unit &unit) const; 00399 // Quantum<Vector<Double> > get(const Unit &unit) const; 00400 // </srcblock> 00401 // <group> 00402 void dummy_getValue() const {} 00403 // </group> 00404 // 00405 // 00406 // Get unit (only available if Measure generated from a Quantum, else "") 00407 virtual const Unit &getUnit() const = 0; 00408 00409 // Get data pointer (used by MeasConvert) 00410 virtual const MeasValue* getData() const = 0; 00411 00412 // Get general reference pointer 00413 virtual MRBase *getRefPtr() const = 0; 00414 00415 // Print a Measure 00416 virtual void print(std::ostream &os) const = 0; 00417 // Create a copy 00418 // <group> 00419 virtual Measure *clone() const = 0; 00420 // </group> 00421 protected: 00422 00423 private: 00424 //# Enumerations 00425 00426 //# Data 00427 // Each class will have the following information: 00428 // Actual data 00429 // <srcblock> 00430 // MVmeasure data; 00431 // </srcblock> 00432 // Reference frame data 00433 // <srcblock> 00434 // MeasRef<Measure> ref; 00435 // </srcblock> 00436 // Possible input units 00437 // <srcblock> 00438 // Unit unit; 00439 // </srcblock> 00440 // And maybe later (or somewhere else) 00441 // <srcblock> 00442 // MeasErr error; 00443 // </srcblock> 00444 // <group> 00445 // Dummy for cxx2html 00446 void dummy_data() const {} 00447 // </group> 00448 // 00449 //# Member functions 00450 // Clear the measure 00451 virtual void clear() = 0; 00452 00453 }; 00454 00455 //# Global functions 00456 // <summary> Global functions </summary> 00457 // <group name=Output> 00458 // Output declaration 00459 std::ostream &operator<<(std::ostream &os, const Measure &meas); 00460 // </group> 00461 00462 00463 } //# NAMESPACE CASA - END 00464 00465 #endif