casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Measure.h
Go to the documentation of this file.
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