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