00001 //# UnitMap.h: defines the UnitMap class containing standard unit definitions 00002 //# Copyright (C) 1994-2002,2007 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$ 00027 00028 #ifndef CASA_UNITMAP_H 00029 #define CASA_UNITMAP_H 00030 00031 00032 //# Includes 00033 #include <casacore/casa/aips.h> 00034 #include <casacore/casa/BasicSL/Constants.h> 00035 #include <casacore/casa/stdmap.h> 00036 #include <casacore/casa/BasicSL/String.h> 00037 #include <casacore/casa/Quanta/UnitDim.h> 00038 #include <casacore/casa/Quanta/UnitVal.h> 00039 #include <casacore/casa/Quanta/UnitName.h> 00040 #include <casacore/casa/OS/Mutex.h> 00041 00042 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00043 00044 //# Forward Declarations 00045 00046 //* Constants 00047 // <note role=warning> 00048 // SUN compiler does not accept non-simple default arguments 00049 // </note> 00050 // IAU definition of Gaussian grav. constant for calculating IAU units 00051 const Double IAU_k=0.01720209895; 00052 // Number of FITS units recognised (change the FITSstring and FITSunit lists 00053 // in the UnitMap.cc when changing this number. 00054 const uInt N_FITS = 19; 00055 00056 // <summary> 00057 // contains all simple known physical units 00058 // </summary> 00059 00060 // <use visibility=export> 00061 00062 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tUnit"> 00063 // 00064 // <prerequisite> 00065 // You should have at least a preliminary understanding of these classes: 00066 // <li> <linkto class=Unit>Unit</linkto> 00067 // </prerequisite> 00068 // 00069 // <etymology> 00070 // Based on Units and the Casacore container classes called 'Map' 00071 // </etymology> 00072 // 00073 // <synopsis> 00074 // Physical units are strings consisting of one or more names of known 00075 // basic units, separated by '.' or ' ' (for multiplication) or '/' (for 00076 // division). Each name can optionally be preceded by a standard decimal 00077 // prefix, and/or followed by an (optionally signed) exponent. 00078 // Example: 00079 // km/s/(Mpc.s)2 is identical to km.s-1.Mpc-2.s-2 00080 // 00081 // See the <linkto class="Unit">Unit</linkto> class for more details. 00082 // 00083 // The UnitMap class contains the known standard basic units, and any 00084 // other basic unit defined by the user of the Unit related classes. 00085 // The known units are divided into 5 different groups: 00086 // <ol> 00087 // <li> Defining units: m, kg, s, A, K, cd, mol, rad, sr, _ 00088 // <li> SI units: including a.o. Jy, AU etc) 00089 // <li> Customary units: e.g. lb, hp, ly etc 00090 // <li> User defined units: defined by user (e.g. Beam, KPH, KM) 00091 // <li> Cached units: cached unit strings for speed in operations 00092 // </ol> 00093 // The full list of known units can be viewed by running the tUnit test 00094 // program. 00095 // <note role=caution> 00096 // There is a difference between units without a dimension (non-dimensioned 00097 // I will call them), and undimensioned units. Non-dimensioned examples are 00098 // "", "%"; undimensioned examples: "beam", "pixel". 00099 // </note> 00100 // 00101 // Information about the contents of the unit maps can be obtained by 00102 // the Bool functions (False if not present): 00103 // <ul> 00104 // <li> UnitMap::getPref("string", UnitName &) prefix 00105 // <li> UnitMap::getUnit("string", UnitName &) search user, 00106 // customary, SI (in that order) 00107 // <li> UnitMap::getCache("string", UnitVal &) search cache 00108 // </ul> 00109 // 00110 // The standard units can be viewed by the following commands, which 00111 // output to cout: 00112 // <ul> 00113 // <li> UnitMap::list() all prefixes and SI, Cust and User units 00114 // <li> UnitMap::listCache() current cache contents 00115 // <li> UnitMap::listPref() all prefixes 00116 // <li> UnitMap::listDef() all defining units 00117 // <li> UnitMap::listSI() all SI Units 00118 // <li> UnitMap::listCust() all customary units 00119 // <li> UnitMap::listUser() all user defined units 00120 // </ul> 00121 // 00122 // Units can be defined in the user list by: 00123 // <note role=tip> The cache will be cleared if a user defined unit is overwritten, 00124 // to make sure no old value will be used. </note> 00125 // <srcblock> 00126 // UnitMap::putUser("tag", UnitVal(factor,"unit"), "full name (optional)"); 00127 // or: 00128 // UnitMap::putUser(UnitName); 00129 // </srcblock> 00130 // <note role=caution> 00131 // If using an explicit Unit variable (e.g. <src>Unit a("5Bolton/beam")</src>), 00132 // the check on the legality of the given string, and the conversion to the 00133 // cached canonical value in the variable 'a', is only done at creation time. This 00134 // means that if the user changes the value of a unit involved by the 00135 // <linkto class=UnitMap>putUser()</linkto> method, the unit using it should be 00136 // re-created (<src> a = Unit("5Bolton/beam");</src>). 00137 // </note> 00138 // A special set of 'units' used in FITS datasets can be added by the command 00139 // <srcblock> 00140 // UnitMap::addFITS(); 00141 // </srcblock> 00142 // This set can be cleared from the user table by: 00143 // <srcblock> 00144 // UnitMap::clearFITS(); 00145 // </srcblock> 00146 // Note that Unitmap keeps track of the inclusion of the FITS inclusion, 00147 // making multiple calls inexpensive. The list of current FITS units can 00148 // be viewed by running the tUnit program, or looking at the FITSunit 00149 // table. 00150 // 00151 // Once the UnitMap::addFITS() has been run, the FITS units can be used as 00152 // any other unit. In addition, a FITS unit can be translated to standard 00153 // SI units by a call to <em>Unit UnitMap::fromFITS(const Unit)</em>. Any 00154 // unit that is defined as a standard FITS unit will be translated. Unknown 00155 // ones will not be translated, making the way clear for having standard 00156 // units in a FITS units string. A comparable <em>toFITS()</em> translates in 00157 // the same way in the reversed direction. 00158 // 00159 // The cache can be cleared by: 00160 // <srcblock> 00161 // UnitMap::clearCache(); 00162 // </srcblock> 00163 // </synopsis> 00164 // 00165 // <example> 00166 // Check for legal prefix: 00167 // <srcblock> 00168 // UnitName myUnit; 00169 // if (UnitMap::getPref("k", myUnit)) { cout << "k has value " << myUnit;} 00170 // </srcblock> 00171 // Define a value for the unit 'beam': 00172 // <srcblock> 00173 // UnitMap::putUser("beam",UnitVal(C::pi * 0.1, "\"_2"),"telescope beam"); 00174 // </srcblock> 00175 // List current cache: 00176 // <srcblock> 00177 // UnitMap::listCache(); 00178 // </srcblock> 00179 // </example> 00180 // 00181 // <motivation> 00182 // Standard list available to try to enhance use of SI and related units 00183 // </motivation> 00184 // 00185 // <todo asof="941110"> 00186 // <li> Some inlining (did not work first go) 00187 // </todo> 00188 00189 class UnitMap { 00190 public: 00191 00192 //# Constructors 00193 // Default constructor of maps 00194 UnitMap(); 00195 00196 // Destructor 00197 ~UnitMap(); 00198 00199 //# General member functions 00200 // Remove all maps (just to get no memory leaks at end of program) 00201 static void releaseUM(); 00202 // Check if a unit name is known, and return its value if True 00203 // <group name="find"> 00204 // Get a prefix definition from key 00205 static Bool getPref(const String &s, UnitName &name); 00206 00207 // Get a cached definition 00208 static Bool getCache(const String &s, UnitVal &val); 00209 00210 // Get a standard unit definition (search order: User, Customary, SI) 00211 static Bool getUnit(const String &s, UnitName &name); 00212 // </group> 00213 // Save a definition of a full unit name in the cache (the cache will be 00214 // cleared if getting too large (200 entries) 00215 static void putCache(const String &s, const UnitVal &val); 00216 00217 // Define a user defined standard unit. If the unit is being redefined, and it 00218 // has already been used in a user's <src>Unit</src> variable, the value 00219 // cached in that variable will not change. 00220 // <group name="define"> 00221 static void putUser(const String &s, const UnitVal &val); 00222 static void putUser(const String &s, const UnitVal &val, 00223 const String &name); 00224 static void putUser(const UnitName &name); 00225 // </group> 00226 // Remove a user unit 00227 // <group> 00228 static void removeUser(const String &name); 00229 static void removeUser(const UnitName &name); 00230 // </group> 00231 00232 // Clear out the cache 00233 static void clearCache(); 00234 00235 // Define FITS related unit names 00236 static void addFITS(); 00237 00238 // Clear FITS related units from user list 00239 static void clearFITS(); 00240 00241 // Translate a FITS unit to the proper units. Note that this is a translation 00242 // of the string only, no conversion. Unknown FITS units are not translated. 00243 // Hence any new definition of the FITS units will work ok 00244 static Unit fromFITS(const Unit &un); 00245 00246 // Translate to a FITS unit 00247 static Unit toFITS(const Unit &un); 00248 00249 // List some part of the standard unit lists on cout or stream 00250 // <group name="list"> 00251 // List all known unit symbols 00252 // <group> 00253 static void list(ostream &os); 00254 static void list(); 00255 // </group> 00256 00257 // List all units in cache 00258 // <group> 00259 static void listCache(ostream &os); 00260 static void listCache(); 00261 // </group> 00262 00263 // List all prefixes 00264 // <group> 00265 static void listPref(ostream &os); 00266 static void listPref(); 00267 // </group> 00268 00269 // List all defining units 00270 // <group> 00271 static void listDef(ostream &os); 00272 static void listDef(); 00273 // </group> 00274 00275 // List all SI units 00276 // <group> 00277 static void listSI(ostream &os); 00278 static void listSI(); 00279 // </group> 00280 00281 // List all customary units 00282 // <group> 00283 static void listCust(ostream &os); 00284 static void listCust(); 00285 // </group> 00286 00287 // List all user defined units 00288 // <group> 00289 static void listUser(ostream &os); 00290 static void listUser(); 00291 // </group> 00292 // </group> 00293 00294 // Return the different maps 00295 // <group> 00296 static const map<String, UnitName> &givePref(); 00297 static const map<String, UnitName> &giveDef(); 00298 static const map<String, UnitName> &giveSI(); 00299 static const map<String, UnitName> &giveCust(); 00300 static const map<String, UnitName> &giveUser(); 00301 static const map<String, UnitVal> &giveCache(); 00302 // </group> 00303 00304 private: 00305 //# Constructors 00306 // Copy constructor (not implemented) 00307 UnitMap(const UnitMap &other); 00308 00309 //# Operators 00310 // Copy assignment (not implemented) 00311 UnitMap &operator=(const UnitMap &other); 00312 00313 //# Data members 00314 00315 // Decimal prefix list 00316 static map<String, UnitName> *mapPref; 00317 00318 // Defining SI unit list 00319 static map<String, UnitName> *mapDef; 00320 00321 // SI unit list 00322 static map<String, UnitName> *mapSI; 00323 00324 // Customary list 00325 static map<String, UnitName> *mapCust; 00326 00327 // User defined unit list 00328 static map<String, UnitName> *mapUser; 00329 00330 // Cached list 00331 static map<String, UnitVal> *mapCache; 00332 // FITS unit list inclusion 00333 static Bool doneFITS; 00334 static Mutex fitsMutex; 00335 00336 //# member functions 00337 // Get the name of a FITS unit 00338 static Bool getNameFITS(const UnitName *&name, uInt which); 00339 // Get the belonging unit to a FITS unit 00340 static const String &getStringFITS(uInt which); 00341 // Initialise the static maps 00342 static void initUM(); 00343 static void doInitUM (void*); 00344 // Bits and pieces of initUM() to get compilation speed improved 00345 // <group> 00346 static void initUMPrefix(); 00347 static void initUMSI1(); 00348 static void initUMSI2(); 00349 static void initUMCust1(); 00350 static void initUMCust2(); 00351 static void initUMCust3(); 00352 // </group> 00353 00354 }; 00355 00356 //# Inline Implementations 00357 00358 00359 } //# NAMESPACE CASACORE - END 00360 00361 #endif