UnitMap.h

Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1