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