casacore
UnitVal.h
Go to the documentation of this file.
1 //# UnitVal.h: defines the class describing a unit as a value and a dimension
2 //# Copyright (C) 1994-1999,2000,2001,2004
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef CASA_UNITVAL_H
29 #define CASA_UNITVAL_H
30 
31 
32 //# Includes
33 #include <casacore/casa/aips.h>
34 #include <casacore/casa/Quanta/UnitDim.h>
35 #include <casacore/casa/iosfwd.h>
36 
37 namespace casacore { //# NAMESPACE CASACORE - BEGIN
38 
39 //# Forward Declarations
40 class String;
41 class MUString;
42 class UnitMap;
43 class UMaps;
44 
45 //
46 // <summary>
47 // describes any valid unit as a factor and a dimenion of SI units
48 // </summary>
49 
50 // <use visibility=export>
51 
52 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tUnit">
53 //
54 // <prerequisite>
55 // You should have at least a preliminary understanding of these classes:
56 // <li> <linkto class=Unit>Unit</linkto>
57 // </prerequisite>
58 //
59 // <etymology>
60 // The class name derives from Units and gives a Value for a unit string
61 // </etymology>
62 //
63 // <synopsis>
64 // Physical units are strings consisting of one or more names of known
65 // basic units, separated by '.' or ' ' (for multiplication) or '/' (for
66 // division). Each name can optionally be preceded by a standard decimal
67 // prefix, and/or followed by an (optionally signed) exponent.
68 // Example:
69 // km/s/(Mpc.s)2 is identical to km.s-1.Mpc-2.s-2
70 //
71 // See the <linkto class="Unit">Unit</linkto> class for more details.
72 //
73 // The UnitVal class maps a Unit string to a factor and a dimension of SI
74 // defining units. E.g 'km/s' will be 1000 m.s-1 .
75 // This class is only of interest if the manipulation of units is of
76 // direct interest. Normally units will be used as Quantities and Quantums
77 // (see the <linkto class=Quantum>Quantum</linkto> class) only,
78 // i.e. as a physical quantity having a value and unit.
79 // The class can also be used to check the validity of a unit string.
80 //
81 // <h3> Constructing UnitVal values </h3>
82 //
83 // UnitVal has the following constructors:
84 // <ul>
85 // <li> UnitVal() creates an (non-dimensioned) value 1.
86 // <li> UnitVal(Double f) creates an (non-dimensioned) value f.
87 // <li> UnitVal(Double f, String s) creates value f with unit s
88 // <li> UnitVal(Double f, Int i) (private) creates value f with unit
89 // at position i in dimension vector
90 // </ul>
91 //
92 //
93 // <h3> Manipulating unit values </h3>
94 //
95 // The UnitVal can be manipulated by the following operators and functions:
96 // <ul>
97 // <li> *, / generates combined UnitVal (e.g. 1 yd * 1 m = 0.9 m2)
98 // <li> pow(Int) UnitVal(2,"km")->pow(2) = 4000000 m2
99 // <li> root(Int) UnitVal(4000000,"m2")->root(2) = 2 km
100 // <li> ==, != compares dimensions only: 1 yd == 5 ly: True
101 // <li> getFac() will return the factor (Double)
102 // <li> getDim() will return the dimensions (as UnitDim)
103 // <li> << will output formatted unit (factor and dimension)
104 // </ul>
105 // To aid in checking the dimensionality of units, the following constants
106 // are available:
107 // <ul>
108 // <li> UnitVal::NODIM
109 // <li> UnitVal::UNDIM
110 // <li> UnitVal::LENGTH
111 // <li> UnitVal::MASS
112 // <li> UnitVal::ANGLE
113 // <li> UnitVal::SOLIDANGLE
114 // <li> UnitVal::MOLAR
115 // <li> UnitVal::CURRENT
116 // <li> UnitVal::TIME
117 // <li> UnitVal::TEMPERATURE
118 // <li> UnitVal::INTENSITY
119 // </ul>
120 // <note role=tip>
121 // Any other dimension can be checked by a combination. To check e.g. if
122 // a unit is an acceleration, use: UnitVal::LENGTH/UnitVal::TIME/UnitVal::TIME
123 // </note>
124 //
125 // <h3> Checking for valid unit strings </h3>
126 //
127 // The validity of a unit string can be checked by:
128 // <srcblock>
129 // // Check if the given String is a valid unit representation. The String
130 // // will be cached in the unit maps for later reference if True
131 // if ( UnitVal::check( "km/s/Mpc") ) {...}
132 // </srcblock>
133 //
134 // </synopsis>
135 //
136 // <example>
137 // An observation contains values in Janskys and in Westerbork Units. The
138 // data can be combined by the following code:
139 // <srcblock>
140 // // The Fits tape gave JY, we check if defined, else we define them
141 // if ( !UnitVal::check( "JY")) {
142 // UnitMap::putUser("JY", UnitVal(1.,"Jy"), "FITS way to write Jy");
143 // }
144 // // The Fits tape gave WU (which are defined):
145 // // We check if JY and WU are of the same dimension:
146 // if (UnitVal(1.,"JY") != UnitVal(1.,"WU")) {
147 // cerr << "Wrong dimension for either JY ( " <<
148 // UnitVal(1.,"JY")->getDim() <<
149 // ") or WU ( " <<
150 // UnitVal(1.,"WU")->getDim() << ")" << endl;
151 // }
152 // // And output the relation between WU and JY, and the WU value:
153 // cout << "1 WU = " << ( UnitVal(1.,"WU")/UnitVal(1.,"Jy") )->getVal() <<
154 // " JY with 1 WU = " << UnitVal(1.,"WU") << endl;
155 // </srcblock>
156 // </example>
157 
158 // <motivation>
159 // To separate the actual manipulation of unit values from the related
160 // quantity
161 // </motivation>
162 //
163 // <todo asof="941110">
164 // <li> Some inlining (did not work first go)
165 // </todo>
166 
167 class UnitVal {
168  //# Friends
169  // Multiply
170  friend UnitVal operator*(const UnitVal &in, const UnitVal &other);
171  // Divide
172  friend UnitVal operator/(const UnitVal &in, const UnitVal &other);
173  // Output a unit as a value and a string of SI defining units
174  friend ostream& operator<<(ostream &os, const UnitVal &ku);
175  // ensure that statics are initialized
177 
178  public:
179  //# Constructors
180  // Construct an non-dimensioned value of 1
182  // Copy constructor
183  UnitVal(const UnitVal &other);
184 
185  // Construct an non-dimensioned value
186  UnitVal(Double factor) { init(factor); }
187 
188  // Construct a fully dimensioned value
189  // <thrown>
190  // <li> AipsError
191  // </thrown>
192  UnitVal(Double factor, const String &s, UMaps* = 0);
193 
194  // Construct a value with a single unit at position specified
195  UnitVal(Double factor, Int pos) { init(factor, pos); }
196 
197  // Destructor
199 
200  //# Operators
201  // Assignment (copy semantics)
202  UnitVal &operator=(const UnitVal &other);
203 
204  // Manipulate units
205  // <group name="manipulate">
206  // Multiply different units
207  UnitVal &operator*=(const UnitVal &other);
208 
209  // Divide different units
210  UnitVal &operator/=(const UnitVal &other);
211 
212  // Compare the dimensionality of different units
213  Bool operator==(const UnitVal &other) const;
214  Bool operator!=(const UnitVal &other) const;
215  // </group>
216 
217  //# General member functions
218 
219  // Raise a unit to an integer power
221 
222  // Take integer root
223  // <thrown>
224  // <li> AipsError if power equals zero
225  // <li> AipsError if unit dimensions not multiple of power
226  // </thrown>
227  // <group>
228  UnitVal root(Int p) const;
229  UnitVal sqrt() const;
230  // </group>
231 
232  // Get the data parts of the unit value definition
233  // <group name="get data">
234  // Get the dimensions in the defining SI units
235  const UnitDim &getDim() const;
236 
237  // Get the factor of the unit (as compared to pure SI units)
238  Double getFac() const;
239  // </group>
240 
241  //# Helper functions
242  // Convert a unit string to a proper unit value and cache the result. The
243  // function will return False if invalid string specified
244  static Bool check(const String &s);
245 
246  // Convert a unit string to a proper unit value, cache the result and compare
247  // the dimension with the specified unit value. False if any of the steps fails
248  static Bool check(const String &s, UnitVal &loc);
249 
250 
251  //# Data members
252  // Some constants to check type of units
253  // <group name="unit kinds">
254  static UnitVal NODIM;
255  static UnitVal UNDIM;
256  static UnitVal LENGTH;
257  static UnitVal MASS;
258  static UnitVal TIME;
259  static UnitVal CURRENT;
262  static UnitVal MOLAR;
263  static UnitVal ANGLE;
265  // </group>
266 
267  protected:
268  // alternate initialization
269  void init(Double factor);
270  void init(Double factor, Int pos);
271 
272  private:
273  //# Data members
274  // The factor necessary to express the specified unit in the defining SI units
276 
277  // The dimensions of the unit in the defining SI units
279 
280  // Convert (and check) a unit string to an SI value representation
281  // <group>
282  static Bool create(const String &s, UnitVal &res, UMaps* = 0);
283  static Bool create(MUString &str, UnitVal &res, UMaps* = 0);
284  // </group>
285 
286  // Determine sign of unit power (i.e. if '.' or '/')
287  static Int psign(MUString &str);
288 
289  // Determine exponent of unit symbol
290  static Int power(MUString &str);
291 
292  // Determine symbol name in unit string
293  static Bool field(MUString &str, UnitVal &res, UMaps*);
294 
295 };
296 
297 //# Inline Implementations
298 
299 //# Global functions
300 // <summary> Global output function </summary>
301 // <group name=output>
302 // Output
303 ostream& operator<<(ostream &os, const UnitVal &ku);
304 // </group>
305 
306 // <summary> Static initialisation of UnitVal constants </summary>
307 static class UnitVal_static_initializer {
308  public:
310  if ( ! initialized ) {
322  initialized = 1;
323  }
324  }
325  private:
326  static int initialized;
328 
329 
330 } //# NAMESPACE CASACORE - END
331 
332 #endif
333 
String: the storage and methods of handling collections of characters.
Definition: String.h:225
Define a struct containing the static data members.
Definition: UnitMap.h:50
Static initialisation of UnitVal constants
Definition: UnitVal.h:309
friend UnitVal operator/(const UnitVal &in, const UnitVal &other)
Divide.
UnitVal sqrt() const
void init(Double factor, Int pos)
static UnitVal ANGLE
Definition: UnitVal.h:264
static UnitVal TEMPERATURE
Definition: UnitVal.h:261
static UnitVal UNDIM
Definition: UnitVal.h:256
void init(Double factor)
alternate initialization
static UnitVal TIME
Definition: UnitVal.h:259
UnitDim kindDim
The dimensions of the unit in the defining SI units.
Definition: UnitVal.h:278
UnitVal & operator=(const UnitVal &other)
Assignment (copy semantics)
UnitVal(Double factor)
Construct an non-dimensioned value.
Definition: UnitVal.h:186
static UnitVal NODIM
Some constants to check type of units
Definition: UnitVal.h:255
UnitVal(Double factor, const String &s, UMaps *=0)
Construct a fully dimensioned value.
friend UnitVal operator*(const UnitVal &in, const UnitVal &other)
Multiply.
static UnitVal CURRENT
Definition: UnitVal.h:260
UnitVal pow(Int p)
Raise a unit to an integer power.
static UnitVal MASS
Definition: UnitVal.h:258
friend ostream & operator<<(ostream &os, const UnitVal &ku)
Output a unit as a value and a string of SI defining units.
static Int power(MUString &str)
Determine exponent of unit symbol.
UnitVal()
Construct an non-dimensioned value of 1.
static UnitVal INTENSITY
Definition: UnitVal.h:262
static UnitVal SOLIDANGLE
Definition: UnitVal.h:265
Double getFac() const
Get the factor of the unit (as compared to pure SI units)
static Int psign(MUString &str)
Determine sign of unit power (i.e.
~UnitVal()
Destructor.
UnitVal & operator*=(const UnitVal &other)
Manipulate units
Double kindFactor
The factor necessary to express the specified unit in the defining SI units.
Definition: UnitVal.h:275
Bool operator==(const UnitVal &other) const
Compare the dimensionality of different units.
static UnitVal MOLAR
Definition: UnitVal.h:263
static Bool create(MUString &str, UnitVal &res, UMaps *=0)
UnitVal(const UnitVal &other)
Copy constructor.
static Bool check(const String &s)
Convert a unit string to a proper unit value and cache the result.
Bool operator!=(const UnitVal &other) const
static Bool check(const String &s, UnitVal &loc)
Convert a unit string to a proper unit value, cache the result and compare the dimension with the spe...
UnitVal & operator/=(const UnitVal &other)
Divide different units.
UnitVal root(Int p) const
Take integer root.
UnitVal(Double factor, Int pos)
Construct a value with a single unit at position specified.
Definition: UnitVal.h:195
static UnitVal LENGTH
Definition: UnitVal.h:257
static Bool create(const String &s, UnitVal &res, UMaps *=0)
Convert (and check) a unit string to an SI value representation.
const UnitDim & getDim() const
Get the data parts of the unit value definition
static Bool field(MUString &str, UnitVal &res, UMaps *)
Determine symbol name in unit string.
static class casacore::UnitVal_static_initializer unitval_static_initializer
this file contains all the compiler specific defines
Definition: mainpage.dox:28
int Int
Definition: aipstype.h:50
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
ostream & operator<<(ostream &os, const IComplex &)
Show on ostream.
double Double
Definition: aipstype.h:55