//# UnitMap.h: defines the UnitMap class containing standard unit definitions //# Copyright (C) 1994-2002,2007 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ #ifndef CASA_UNITMAP_H #define CASA_UNITMAP_H //# Includes #include #include #include #include #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN //# Forward Declarations // Define a struct containing the static data members. // The static struct object is created in function getMaps // to ensure proper static initialization order. class UMaps { public: UMaps() {init();} // Decimal prefix list map mapPref; // Defining SI unit list map mapDef; // SI unit list map mapSI; // Customary list map mapCust; // User defined unit list map mapUser; // FITS unit list inclusion Bool doneFITS; private: void init(); }; //* Constants // IAU definition of Gaussian grav. constant for calculating IAU units const Double IAU_k=0.01720209895; // Number of FITS units recognised (change the FITSstring and FITSunit lists // in the UnitMap.cc when changing this number. const uInt N_FITS = 19; // // contains all simple known physical units // // // // // // You should have at least a preliminary understanding of these classes: //
  • Unit // // // // Based on Units and the Casacore container classes called 'Map' // // // // Physical units are strings consisting of one or more names of known // basic units, separated by '.' or ' ' (for multiplication) or '/' (for // division). Each name can optionally be preceded by a standard decimal // prefix, and/or followed by an (optionally signed) exponent. // Example: // km/s/(Mpc.s)2 is identical to km.s-1.Mpc-2.s-2 // // See the Unit class for more details. // // The UnitMap class contains the known standard basic units, and any // other basic unit defined by the user of the Unit related classes. // The known units are divided into 5 different groups: //
      //
    1. Defining units: m, kg, s, A, K, cd, mol, rad, sr, _ //
    2. SI units: including a.o. Jy, AU etc) //
    3. Customary units: e.g. lb, hp, ly etc //
    4. User defined units: defined by user (e.g. Beam, KPH, KM) //
    5. Cached units: cached unit strings for speed in operations //
    // The full list of known units can be viewed by running the tUnit test // program. // // There is a difference between units without a dimension (non-dimensioned // I will call them), and undimensioned units. Non-dimensioned examples are // "", "%"; undimensioned examples: "beam", "pixel". // // // Information about the contents of the unit maps can be obtained by // the Bool functions (False if not present): //
      //
    • UnitMap::getPref("string", UnitName &) prefix //
    • UnitMap::getUnit("string", UnitName &) search user, // customary, SI (in that order) //
    • UnitMap::getCache("string", UnitVal &) search cache //
    // // The standard units can be viewed by the following commands, which // output to cout: //
      //
    • UnitMap::list() all prefixes and SI, Cust and User units //
    • UnitMap::listCache() current cache contents //
    • UnitMap::listPref() all prefixes //
    • UnitMap::listDef() all defining units //
    • UnitMap::listSI() all SI Units //
    • UnitMap::listCust() all customary units //
    • UnitMap::listUser() all user defined units //
    // // Units can be defined in the user list by: // The cache will be cleared if a user defined unit is overwritten, // to make sure no old value will be used. // // UnitMap::putUser("tag", UnitVal(factor,"unit"), "full name (optional)"); // or: // UnitMap::putUser(UnitName); // // // If using an explicit Unit variable (e.g. Unit a("5Bolton/beam")), // the check on the legality of the given string, and the conversion to the // cached canonical value in the variable 'a', is only done at creation time. This // means that if the user changes the value of a unit involved by the // putUser() method, the unit using it should be // re-created ( a = Unit("5Bolton/beam");). // // A special set of 'units' used in FITS datasets can be added by the command // // UnitMap::addFITS(); // // This set can be cleared from the user table by: // // UnitMap::clearFITS(); // // Note that Unitmap keeps track of the inclusion of the FITS inclusion, // making multiple calls inexpensive. The list of current FITS units can // be viewed by running the tUnit program, or looking at the FITSunit // table. // // Once the UnitMap::addFITS() has been run, the FITS units can be used as // any other unit. In addition, a FITS unit can be translated to standard // SI units by a call to Unit UnitMap::fromFITS(const Unit). Any // unit that is defined as a standard FITS unit will be translated. Unknown // ones will not be translated, making the way clear for having standard // units in a FITS units string. A comparable toFITS() translates in // the same way in the reversed direction. // // The cache can be cleared by: // // UnitMap::clearCache(); // //
    // // // Check for legal prefix: // // UnitName myUnit; // if (UnitMap::getPref("k", myUnit)) { cout << "k has value " << myUnit;} // // Define a value for the unit 'beam': // // UnitMap::putUser("beam",UnitVal(C::pi * 0.1, "\"_2"),"telescope beam"); // // List current cache: // // UnitMap::listCache(); // // // // // Standard list available to try to enhance use of SI and related units // // // //
  • Some inlining (did not work first go) // class UnitMap { public: friend class UMaps; //# Constructors // Default constructor of maps UnitMap(); // Destructor ~UnitMap(); //# General member functions // Check if a unit name is known, and return its value if True // // Get a prefix definition from key static Bool getPref(const String &s, UnitName &name, UMaps* maps=0); // Get a standard unit definition (search order: User, Customary, SI) static Bool getUnit(const String &s, UnitName &name, UMaps* maps=0); // Get a cached definition static Bool getCache(const String &s, UnitVal &val); // // Save a definition of a full unit name in the cache (the cache will be // cleared if getting too large (200 entries) static void putCache(const String &s, const UnitVal &val); // Define a user defined standard unit. If the unit is being redefined, and it // has already been used in a user's Unit variable, the value // cached in that variable will not change. // static void putUser(const String &s, const UnitVal &val); static void putUser(const String &s, const UnitVal &val, const String &name); static void putUser(const UnitName &name); // // Remove a user unit // static void removeUser(const String &name); static void removeUser(const UnitName &name); // // Clear out the cache static void clearCache(); // Define FITS related unit names static void addFITS(); // Clear FITS related units from user list static void clearFITS(); // Translate a FITS unit to the proper units. Note that this is a translation // of the string only, no conversion. Unknown FITS units are not translated. // Hence any new definition of the FITS units will work ok static Unit fromFITS(const Unit &un); // Translate to a FITS unit static Unit toFITS(const Unit &un); // List some part of the standard unit lists on cout or stream // // List all known unit symbols // static void list(ostream &os); static void list(); // // List all units in cache // static void listCache(ostream &os); static void listCache(); // // List all prefixes // static void listPref(ostream &os); static void listPref(); // // List all defining units // static void listDef(ostream &os); static void listDef(); // // List all SI units // static void listSI(ostream &os); static void listSI(); // // List all customary units // static void listCust(ostream &os); static void listCust(); // // List all user defined units // static void listUser(ostream &os); static void listUser(); // // // Return the different maps // static const map &givePref(); static const map &giveDef(); static const map &giveSI(); static const map &giveCust(); static const map &giveUser(); static const map &giveCache(); // private: //# Constructors // Copy constructor (not implemented) UnitMap(const UnitMap &other); //# Operators // Copy assignment (not implemented) UnitMap &operator=(const UnitMap &other); static std::mutex fitsMutex; //# member functions // Get the static UMaps struct. static UMaps& getMaps(); // Get the static mapCache object. // This cannot be part of the UMaps struct, because the UnitVal ctor // is called in the initialization of UMaps, but uses mapCache resulting // in a recursive call. static map& getMapCache(); // Get the name of a FITS unit static Bool getNameFITS(const UnitName *&name, uInt which); // Get the belonging unit to a FITS unit static const String &getStringFITS(uInt which); static void initUM(); // Bits and pieces of initUM() to get compilation speed improved // static void initUMPrefix (UMaps&); static void initUMSI1 (UMaps&); static void initUMSI2 (UMaps&); static void initUMCust1 (UMaps&); static void initUMCust2 (UMaps&); static void initUMCust3 (UMaps&); // }; } //# NAMESPACE CASACORE - END #endif