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