casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MeasConvert.h
Go to the documentation of this file.
00001 //# MeasConvert.h: Conversion of Measures
00002 //# Copyright (C) 1995,1996,1997,1998,1999,2000,2001
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: MeasConvert.h 21024 2011-03-01 11:46:18Z gervandiepen $
00028 
00029 #ifndef MEASURES_MEASCONVERT_H
00030 #define MEASURES_MEASCONVERT_H
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <casa/Containers/Block.h>
00035 #include <measures/Measures/MConvertBase.h>
00036 #include <casa/Quanta/Quantum.h>
00037 #include <measures/Measures/Measure.h>
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00041 
00042 //# Forward Declarations
00043 class MCBase;
00044 class MeasVal;
00045 
00046 //# Typedefs
00047 
00048 //# Constants
00049 
00050 // <summary> Conversion of Measures </summary>
00051 
00052 // <use visibility=export>
00053 
00054 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tMeasure" demos="">
00055 // </reviewed>
00056 
00057 // <prerequisite>
00058 //   <li> <linkto class=Measure>Measure</linkto> class 
00059 //   <li> <linkto class=MRBase>MeasRef</linkto> base class 
00060 //   <li> <linkto class=MConvertBase>MConvertBase</linkto> class 
00061 //   <li> <linkto class=Quantum>Quantum</linkto> class 
00062 // </prerequisite>
00063 //
00064 // <etymology>
00065 // </etymology>
00066 //
00067 // <synopsis>
00068 // MeasConvert can convert a Measure to the same type of Measure in a
00069 // different reference frame. The MeasConvert is a templated class, but
00070 // has typedefs, which are strongly recommended to be used,
00071 // for the allowed conversions, like <src>MEpoch::Convert.</src><br>
00072 // The basic operation is to create a MeasConvert with either of:
00073 // <ul>
00074 //   <li> MEpoch::Convert(MEpoch, MEpoch::Ref), where the 
00075 //      <linkto class=MEpoch>MEpoch</linkto> is a template for subsequent
00076 //      conversions, i.e. it will remember the value (with its reference) and 
00077 //      the <linkto class=MeasRef>MeasRef</linkto> output reference.
00078 //   <li> MEpoch::Convert(MEpoch) with a subsequent setOut(MEpoch::Ref)
00079 //   <li> MEpoch::Convert(MEpoch::Ref in, MEpoch::Ref out) is a template for
00080 //       conversions from the input reference to the output reference. The
00081 //      'template' model used is the default value for the Measure, with
00082 //      no units. 
00083 //   <li> MEpoch::Convert(Unit, MEpoch::Ref in, MEpoch::Ref out) is a
00084 //       template for
00085 //       conversions from the input reference to the output reference. The
00086 //      'template' model used is the default value for the Measure, with
00087 //      the default units as specified.
00088 //   <li> MEpoch::Convert() with a setModel(MEpoch) and setOut().
00089 // </ul>
00090 // An empty MeasRef argument indicates no conversion will be attempted<br>.
00091 // The constructor, and set functions, analyse the 'template' Measure and the
00092 // output reference frame, and construct a pointer (in practice a list
00093 // of pointers to bypass the necessity of creating too many conversion
00094 // functions) to a conversion routine.
00095 // 
00096 // An <src>isNOP()</src> function is available to test if the created
00097 // conversion engine is empty.
00098 //
00099 // Actual conversions are done with the () operator, which produces a new
00100 // MEpoch (or other appropiate Measure).<br>
00101 // Possible arguments are (MVEpoch is used here generic, and indicates the
00102 // internal format of a Measure; possibly, to make sure distinction between
00103 // values with and without units possible, even simple Measures will
00104 // have their own internal class format, e.g. MVDouble. 
00105 // The possible arguments to the () conversion operator are (again Epoch
00106 // is used for the generic Measure):
00107 // <ul>
00108 //   <li> (MEpoch, MEpoch::Ref): will create a new conversion method, and use 
00109 //      it to produce the result of converting the MEpoch to the specified
00110 //      frame
00111 //    <li> (MEpoch): will create a new conversion method from the
00112 //      MEpoch to the MeasRef belonging to the MeasConvert
00113 //    <li> (Quantity): will use the conversion chain deduced from the
00114 //      MEpoch model in the definition of MeasConvert, and will convert the
00115 //      Quantity
00116 //    <li> (Quantum<Vector<Double> >) as previous
00117 //    <li> (Double): will use the units (if present) as specified in the
00118 //              MeasConvert object to construct the internal value
00119 //               to be converted
00120 //    <li> (Vector<Double> >): as previous
00121 // </ul>
00122 // Float versions will be produced if necessary.<br>
00123 // The conversion analyser expects that all Measure classes have a set
00124 // of routines to do the actual analysing and conversion.
00125 // (see <linkto class=MCBase>MCBase</linkto> class for how this is done in
00126 // practice).<br>
00127 // If the standard conversion is not sufficient, additional methods can be
00128 // added at the end of the list with the <src>addMethod()</src> member
00129 // function (for real pros).<br>
00130 // </synopsis>
00131 //
00132 // <example>
00133 // See <linkto class=Measure>Measure</linkto> for an example
00134 // </example>
00135 //
00136 // <motivation>
00137 // Conversion of Measures will in general be done on a series of values.
00138 // Separating the analysis of the calculations necessary for the conversion
00139 // from the actual conversion could speed up the process.
00140 // </motivation>
00141 //
00142 // <todo asof="1999/09/24">
00143 // </todo>
00144 
00145 template<class M> class MeasConvert : public MConvertBase {
00146 
00147 public:
00148 
00149   //# Friends
00150 
00151   //# Constructors
00152   // <note role=tip> In the following constructors and other functions, all 
00153   // <em>MeasRef</em> can be replaced with simple <src>Measure::TYPE</src>
00154   // where no offsets or frames are needed in the reference.</note>
00155   // Construct an empty MeasConvert. It is not usable, unless a setModel, and
00156   // probably a setOut has been done.
00157   MeasConvert();
00158   // Copy constructor
00159   MeasConvert(const MeasConvert<M> &other);
00160   // Copy assignment
00161   MeasConvert<M> &operator=(const MeasConvert<M> &other);
00162   
00163   // Construct a conversion for the specified Measure and reference
00164   // <group>
00165   MeasConvert(const M &ep);
00166   MeasConvert(const M &ep, const typename M::Ref &mr);
00167   MeasConvert(const Measure &ep, const typename M::Ref &mr);
00168   MeasConvert(const M &ep, typename M::Types mr);
00169   MeasConvert(const Measure &ep, typename M::Types mr);
00170   MeasConvert(const typename M::Ref &mrin, const typename M::Ref &mr);
00171   MeasConvert(const typename M::Ref &mrin, typename M::Types mr);
00172   MeasConvert(typename M::Types mrin, const typename M::Ref &mr);
00173   MeasConvert(typename M::Types mrin, typename M::Types mr);
00174   MeasConvert(const Unit &inunit, const typename M::Ref &mrin, 
00175               const typename M::Ref &mr);
00176   MeasConvert(const Unit &inunit, const typename M::Ref &mrin, 
00177               typename M::Types mr);
00178   MeasConvert(const Unit &inunit, typename M::Types mrin, 
00179               const typename M::Ref &mr);
00180   MeasConvert(const Unit &inunit, typename M::Types mrin, 
00181               typename M::Types mr);
00182   // </group>
00183   
00184   //# Destructor
00185   ~MeasConvert();
00186   
00187   //# Operators
00188   // The actual conversion operations
00189   // <group>
00190   // Convert model Measure to output frame
00191   const M &operator()();
00192   const M &operator()(Double val);
00193   const M &operator()(const Vector<Double> &val);
00194   const M &operator()(const Quantum<Double> &val);
00195   const M &operator()(const Quantum<Vector<Double> > &val);
00196   const M &operator()(const typename M::MVType &val);
00197   const M &operator()(const MeasVal *val);
00198   const M &operator()(const M &val);
00199   const M &operator()(const M &val, const typename M::Ref &mr);
00200   const M &operator()(const M &val, typename M::Types mr);
00201   const M &operator()(const typename M::Ref &mr);
00202   const M &operator()(typename M::Types mr);
00203   // </group>
00204   
00205   //# General Member Functions
00206   // Set a new model for the conversion
00207   virtual void setModel(const Measure &val);
00208   // Set a new output reference
00209   // <group>
00210   void setOut(const typename M::Ref &mr);
00211   void setOut(typename M::Types mr);
00212   // </group>
00213   // Set a new model and reference
00214   // <group>
00215   void set(const M &val, const typename M::Ref &mr);
00216   void set(const M &val, typename M::Types mr);
00217   // </group>
00218   // Set a new model value only
00219   virtual void set(const MeasValue &val);
00220   // Set a new model unit only
00221   virtual void set(const Unit &inunit);
00222   
00223   // Add a method (Note: uInt should be an enum from the appropiate Measure)
00224   virtual void addMethod(uInt method);
00225   // Add the frame type (Note: tp should be an MeasFrame::FrameType)
00226   virtual void addFrameType(uInt tp);
00227   // Get number of methods
00228   virtual Int nMethod() const;
00229   // Get method
00230   virtual uInt getMethod(uInt which) const;
00231   // Is the conversion engine empty?
00232   Bool isNOP() { return crout.nelements() == 0; }
00233   // Print conversion engine
00234   virtual void print(ostream &os) const;
00235   
00236 private:
00237   //# Data
00238   // The model template Measure
00239   Measure *model;
00240   // The model unit to be used in conversions
00241   Unit unit;
00242   // The output reference
00243   typename M::Ref outref;
00244   // The input offset
00245   typename M::MVType *offin;
00246   // The output offset
00247   typename M::MVType *offout;
00248   // Vector of conversion routines (length variable)
00249   Block<uInt> crout;
00250   // Coded (with MeasFrame::FrameTypes) frames used in conversion
00251   uInt crtype;
00252   // Local conversion data
00253   MCBase *cvdat;
00254   // Cyclic buffer for return values
00255   // <group>
00256   // Current pointer
00257   Int lres;
00258   M *result[4];
00259   // </group>
00260   // Local variables that can be used in conversion
00261   // <group>
00262   typename M::MVType *locres;
00263   // </group>
00264   
00265   //# Member functions
00266   // Initialise pointers
00267   void init();
00268   // Copy a MeasConvert
00269   void copy(const MeasConvert<M> &other);
00270   // Clear self
00271   void clear();
00272   // Create the conversion routine chain
00273   void create();
00274   // Convert a value
00275   // <group>
00276   const typename M::MVType &convert();
00277   const typename M::MVType &convert(const typename M::MVType &val);
00278   // </group>
00279 };
00280 
00281 //# Global functions
00282 
00283 
00284 } //# NAMESPACE CASA - END
00285 
00286 #ifndef CASACORE_NO_AUTO_TEMPLATES
00287 #include <measures/Measures/MeasConvert.tcc>
00288 #endif //# CASACORE_NO_AUTO_TEMPLATES
00289 #endif