casa
$Rev:20696$
|
00001 //# Unit.h: defines the Unit class 00002 //# Copyright (C) 1994-1996,1998-2000,2008 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: Unit.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $ 00027 00028 #ifndef CASA_UNIT_H 00029 #define CASA_UNIT_H 00030 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <casa/BasicSL/String.h> 00035 #include <casa/Quanta/UnitVal.h> 00036 00037 namespace casa { //# NAMESPACE CASA - BEGIN 00038 00039 //# Forward Declarations 00040 00041 // <summary> 00042 // defines physical units 00043 // </summary> 00044 00045 // <use visibility=export> 00046 00047 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tUnit"> 00048 // </reviewed> 00049 // 00050 //# // <prerequisite> 00051 //# // </prerequisite> 00052 // 00053 //# // <etymology> 00054 //# // </etymology> 00055 // 00056 // <synopsis> 00057 // Physical units are basically used as quantities (see the 00058 // <linkto class=Quantum>Quantum</linkto> class), i.e. 00059 // a value and a dimension. The Unit class, or one of its subsidaries, will 00060 // in general not be called separately. The only reason to make use of these 00061 // classes is to generate additional 'tagged' units, i.e. units with a 00062 // special name, e.g. 'beam' for a telescope beam, or 'JY', a non-SI name 00063 // for Jy. 00064 // <h3> Units </h3> 00065 // A Unit is a String, and can be defined as either a Unit or a String 00066 // everywhere where a Unit is required.<br> 00067 // If defined as a Unit, the format of the string will be checked for a 00068 // legal definition and its value will be stored. If defined as a String, 00069 // the checking and determination of the value will be done each time 00070 // the string is encountered when a Unit is expected.<br> 00071 // <note role=tip> The use of a separate Unit variable will give a tremendous 00072 // speed increase, if compared to using the String representation in 00073 // e.g. <linkto class=Quantum>Quantity(5,"deg")</linkto> </note> 00074 // <note role=caution> 00075 // If using an explicit Unit variable (e.g. <src>Unit a("5Bolton/beam")</src>), 00076 // the check on the legality of the given string, and the conversion to the 00077 // cached canonical value in the variable 'a', is only done at creation time. This 00078 // means that if the user changes the value of a unit involved by the 00079 // <linkto class=UnitMap>putUser()</linkto> method, the unit using it should be 00080 // re-created (<src> a = Unit("5Bolton/beam");</src>). 00081 // </note> 00082 // A unit is a string of one or more fields separated 00083 // by 'space' or '.' or '*' (FITS option) 00084 // (to indicate multiply) or '/' (to indicate divide). 00085 // Multiple separators are acted upon (i.e. m//s == m.s). 00086 // Separators are acted upon left-to-right (i.e. m/s/A == (m/s)/A; use 00087 // () to indicate otherwise (e.g. m/(s/A))). 00088 // 00089 // A field is a name, or a unit enclosed in (), optionally followed by an, 00090 // optionally signed, decimal constant. 00091 // The decimal constant may be proceeded by '**' or '^' (FITS option) 00092 // 00093 // E.g. m.(m/s)-2 == m-1.s2) 00094 // <note role=tip> 00095 // A 'space' or '.' before an opening '(' can be omitted. 00096 // </note> 00097 // A name can consist of case-sensitive letters, '_', ''', ':', '"' and '0' 00098 // ('0' not as first character). Digits 1-9 are allowed if preceded with 00099 // an '_'. 00100 // 00101 // Possible legal names are e.g. Jy, R0, R_1, "_2. 00102 // <note role=tip> 00103 // <ul> 00104 // <li> ' is used for arcmin 00105 // <li> '' or " for arcsec 00106 // <li> : :: and ::: are used for h, min, s respectively 00107 // <li> _ is used for an undimensioned value (like beam or pixel) 00108 // </ul> 00109 // </note> 00110 // <note role=caution> The standard naming conventions for SI units are that they are 00111 // all in lowercase, unless derived from a person's name, when they start 00112 // with a capital letter. Notable exceptions are some of the astronomical 00113 // SI related units (e.g. AU). 00114 // </note> 00115 // A name can be preceded by a (standard) decimal prefix. 00116 // 00117 // A name must be defined in a Unit map before it can be used. 00118 // 00119 // All SI units and some customary units are part of the classes. User 00120 // defined names can be added by the UnitMap::putUser() function (see 00121 // the <linkto class=UnitMap>UnitMap</linkto> class). 00122 // 00123 // Example: 00124 // km/s/(Mpc.s)2 is identical to km.s-1.Mpc-2.s-2 00125 // 00126 // There are 5 name lists in the UnitMap, which are searched in reverse order: 00127 // <ol> 00128 // <li> Defining units: m, kg, s, A, K, cd, mol, rad, sr, _ 00129 // <li> SI units: including a.o. g, Jy, AU 00130 // <li> Customary units: e.g. lb, hp, ly 00131 // <li> User defined units: defined by user (e.g. beam, KPH, KM) 00132 // <li> Cached units: for speed in operations 00133 // </ol> 00134 // All known names can be viewed by running the tUnit test program, or 00135 // using the MapUnit::list() routine. 00136 // They are also (at least the 1999/09/15 values) available in the 00137 // <linkto module="Quanta">Quanta module documentation</linkto>. 00138 // <note role=caution> 00139 // There is a difference between units without a dimension (non-dimensioned 00140 // I will call them), and undimensioned units. Non-dimensioned examples are 00141 // "", "%"; undimensioned examples: "beam", "pixel". 00142 // </note> 00143 // 00144 // <h3> Unit class </h3> 00145 // The Unit class is not directly based on the String class, but Strings and 00146 // Units are interchangeable in all Unit and Quantum related calls. 00147 // (But notice the earlier note on speed if using explicit Strings often.) 00148 // 00149 // To calculate with Units (or Strings representing units), use the 00150 // <linkto class=UnitVal>UnitVal</linkto> class. To use dimensioned values, 00151 // use the <linkto class=Quantum>Quantum</linkto> (cq Quantity) class. 00152 // 00153 // Using Unit i.s.o. String will give an immediate check of the legality 00154 // of the unit string. 00155 // In addition the UnitVal class contains a check facility to determine the 00156 // legality of a unit string: 00157 // <srcblock> 00158 // Bool UnitVal::check("string"); 00159 // </srcblock> 00160 // 00161 // </synopsis> 00162 // 00163 // <example> 00164 // <srcblock> 00165 // #include <casa/Quanta.h> 00166 // // check if a string is a valid unit 00167 // if ( !UnitVal::check("Km") ) { cout << "Invalid unit string " << "Km" << endl; 00168 // // define some units 00169 // String unit1="km/Mpc"; 00170 // Unit unit2="uJy/Mpc"; 00171 // // define your own unit name 00172 // UnitMap::putUser("my_univ", UnitVal( C::pi, unit2), "My universe param"); 00173 // // use the units in model calculations 00174 // Quantity observed( 8.97, "Mmy_univ/a"); 00175 // Quantity theory (3.8e-9, "mmy_univ/s"); 00176 // if ( ( observed / theory) < 1.) { cout << "Eureka" << endl; 00177 // </srcblock> 00178 // </example> 00179 // 00180 // <motivation> 00181 // Make basis for all dimensioned values the SI system of units 00182 // </motivation> 00183 // 00184 // <todo asof="941110"> 00185 // <li> Some inlining (did not work first go) 00186 // <li> Look into possiblity of conversion routine from rad2 to sr 00187 // </todo> 00188 00189 class Unit { 00190 public: 00191 //# Constructors 00192 // Default empty string constructor 00193 Unit(); 00194 // Copy constructor 00195 Unit(const Unit &other); 00196 // String based constructors. 00197 // <thrown> 00198 // <li> AipsError if illegal unit string 00199 // </thrown> 00200 // <group name="constructor"> 00201 Unit(const String &other); 00202 Unit(const Char *other); 00203 explicit Unit(Char other); 00204 Unit(const Char *other, Int len); 00205 // </group> 00206 // Destructor 00207 ~Unit(); 00208 00209 //* Operators 00210 // Copy assignment 00211 Unit& operator=(const Unit &other); 00212 // Comparisons. Comparisons are done on the basis of the inherent units. I.e. 00213 // <src>m/s</src> are identical to <src>AU/cy</src>. 00214 // <group> 00215 Bool operator==(const Unit &other) const; 00216 Bool operator!=(const Unit &other) const; 00217 // Fast check for "" units 00218 Bool empty() const; 00219 // </group> 00220 //# Member functions 00221 // Get the unit value 00222 const UnitVal &getValue() const; 00223 // Get the unit name 00224 const String &getName() const; 00225 // Set the unit value 00226 void setValue(const UnitVal &in); 00227 // Set the unit name 00228 void setName(const String &in); 00229 00230 private: 00231 //# Data 00232 String uName; 00233 UnitVal uVal; 00234 00235 //# Member functions 00236 // Check format of unit string 00237 // <thrown> 00238 // <li> AipsError 00239 // </thrown> 00240 void check(); 00241 }; 00242 00243 //# Inline Implementations 00244 00245 00246 } //# NAMESPACE CASA - END 00247 00248 #endif