casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Quantum.h
Go to the documentation of this file.
1 //# Quantum.h: class to manipulate physical, dimensioned quantities
2 //# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001
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: Quantum.h 20993 2010-11-08 13:36:32Z gervandiepen $
27 
28 #ifndef CASA_QUANTUM_H
29 #define CASA_QUANTUM_H
30 
31 #include <casacore/casa/aips.h>
34 
35 namespace casacore { //# NAMESPACE CASACORE - BEGIN
36 
37 //# Forward Declarations
38 template <class T> class Quantum;
39 
40 //# Typedefs
42 
43 // <summary>
44 // Quantities (i.e. dimensioned values)
45 // </summary>
46 
47 // <use visibility=export>
48 
49 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tQuantum">
50 // </reviewed>
51 //
52 // <prerequisite>
53 // <li> <linkto class=Unit>Unit</linkto>
54 // </prerequisite>
55 //
56 // <etymology>
57 // A Quantity is defined as a single Double value with attached units.
58 // From this definition the templated Quantum class arose, to have non-Double,
59 // non-scalar quantities.
60 // </etymology>
61 //
62 // <synopsis>
63 // Quantities are values with a unit. Their basic specification can be one of
64 // two forms:
65 // <srcblock>
66 // Quantity( Double value, String unit); // or: Unit unit
67 // Quantum<Type> ( Type value, String unit) // or: Unit unit
68 // </srcblock>
69 //
70 // A unit is a string of known unit fields separated
71 // by 'space' or '.' (to indicate multiply) or '/' (to indicate divide).
72 // See the <linkto class=Unit>Unit</linkto> class for details.
73 //
74 // Example: km/s/(Mpc.s)2 is identical to km.s-1.Mpc-2.s-2
75 //
76 // <h3> Defining a Quantum </h3>
77 // The following list of constructors is available.
78 // <note role=tip>
79 // In the following 'String' can be replaced by 'Unit' everywhere. The
80 // only difference being a check for a legitimate unit string being executed
81 // if Unit specified (with exception if error)
82 // </note>
83 // <note role=tip>
84 // <src>'Quantum<Type>'</src> can, if Type equals Double, be replaced
85 // with 'Quantity'
86 //
87 // 'Type' can be any simple or non-simple arithmetic type.
88 //
89 // E.g. <src><Double>, <Complex>, <Vector<Double> ></src>
90 // </note>
91 // <ul>
92 // <li> <src>Quantum<Type>() value 0 generated</src>
93 // <li> <src>Quantum<Type>( Quantum<Type>) copy constructor</src>
94 // <li> <src>Quantum<Type>( Type factor) value factor generated</src>
95 // <li> <src>Quantum<Type>( Type factor, Unit unit) specified quantity</src>
96 // <li> <src>Quantum<Type>( Type factor, Quantum<any> quant) specified factor,</src>
97 // the unit from the quant
98 // </ul>
99 //
100 //
101 // <h3> Manipulating quantities </h3>
102 // <linkto group="QMath.h#Quantum mathematical operations">Mathematical operators and functions</linkto> and
103 // <linkto group="QLogical.h#Quantum logical operations">logical operations</linkto> (comparisons)
104 // are defined on Quantums. They are,
105 // of course, only available if the template Type supports them.
106 // <ul>
107 // <li> <src>= assignment of identical <type></src>
108 // <li> <src>* *= multiple two Quantums of same <type>, or Quantum and type</src>
109 // <li> <src>/ /= divide two Quantums of same <type>, or Quantum and type</src>
110 // note:
111 // In multiplication and division, and if <src><type></src> is scalar, the left or
112 // right-hand side can be of type <src><type></src> (e.g 2.*Quantity is allowed)
113 // <li> <src>+ += add two Quantums of same <type> or Quantum and type</src>
114 // and same unit dimensions (else exception)
115 // <li> - -= subtract (same as +)
116 // <li> - negate Quantum
117 // <li> + unary + on Quantum
118 // <li> <src>== != compare unit dimensions and value of same <type>. They will</src>
119 // be unequal if the units do not match or the values (possibly
120 // converted to common base units). All comparisons work also
121 // on a <src>Quantum<type> and <type></src>
122 // <li> <src>< > compare unit dimensions. Exception if no match,</src>
123 // else compare the values
124 // <li> <src><= >= ibid</src>
125 // <li> pow(Int) raise to an (integer) power
126 // </ul>
127 //
128 //
129 // <h3> Manipulating the value and/or units of quanta </h3>
130 // Quantities can be converted to other units by the following set of member
131 // functions:
132 // <ul>
133 // <li> convert() will convert the quantum to canonical units.
134 // E.g. given myval=Quantity(5.,"Jy"),
135 // myval.convert() will convert the qunatum to
136 // Quantity(5.e-26,"kg.s-2")
137 // <li> convert(Unit unit) will convert the quantum to the
138 // specified unit with any remaining dimensions
139 // expressed in canonical units. E.g given
140 // myval as above, myval.convert("W/cm") will
141 // make it Quantity(5.e-28,"W/cm.m-1.s")
142 // <li> <src>convert(Quantum<Type> quant) will convert the quantum</src>
143 // to the units of the specified quant with the
144 // same conversion rules as the previous one
145 // </ul>
146 // <note role=tip> All converting type methods (i.e. convert(), get() and
147 // getValue() with specified units), will automatically convert also from
148 // time to angle units (or v.v) if necessary, as long as they are simple. I.e.
149 // deg will be converted to h, but asking to convert m/s to m/deg will
150 // produce the standard conversion to m/deg.rad/s. </note>
151 //
152 // Quanta can be checked for having the correct unit dimensions (e.g. before
153 // addition or comparing) by the following two member functions, which will
154 // return a Bool value:
155 // <ul>
156 // <li> isConform(Unit unit)
157 // <li> <src>isConform(Quantum<Type> quant)</src>
158 // <li> check(UnitVal kind)
159 // </ul>
160 // or by an assertion, which will throw an exception:<br>
161 // <ul>
162 // <li> assure(UnitVal kind)
163 // </ul>
164 //
165 // The quantum can be retrieved with a change in units by:
166 // <ul>
167 // <li> get() will return the quantum converted to canonical units.
168 // E.g. given myval=Quantity(5.,"Jy"),
169 // myval.get() will return
170 // Quantity(5.e-26,"kg.s-2")
171 // <li> get(Unit unit) will return the quantum converted to the
172 // specified unit with any remaining dimensions
173 // expressed in canonical units. E.g given
174 // myval as above, myval.get("W/cm") will
175 // return it as Quantity(5.e-28,"W/cm.m-1.s")
176 // <li> <src>get(Quantum<Type> quant) will return the quantum converted</src>
177 // to the units of the specified quant with the
178 // same conversion rules as the previous one
179 // </ul>
180 //
181 // The value and units of a quantum can be set or retrieved separately by the
182 // following member functions:
183 // <ul>
184 // <li> getValue() return the value (as Type) of the quantum.
185 // <note role=tip> myval.get().getValue() will return the
186 // value of myval expressed in canonical units
187 // </note>
188 // <li> getValue(Unit unit) return the value (as converted to unit)
189 // <li> getUnit() return the String part of the unit of the
190 // quantum (use getFullUnit if interested in
191 // the complete Unit, e.g. for re-use)
192 // <li> getFullUnit() return the complete unit of the Quantum (use
193 // getUnit() if interested in String part only)
194 // <li> setValue(Type val) replace the value of the quantum with val,
195 // leaving the units the same
196 // <li> scale(Type val) multiply the value (leaving units same) by the
197 // specified value
198 // <li> setUnit(Unit unit) replace the units of the quantum, leaving
199 // the value the same.
200 // <li> <src>setUnit(Quantum<Type> quant) ibid</src>
201 // <li> set(String quantity) replace the value and unit as deduced from quantity
202 // </ul>
203 //
204 // The output operator (<src><<</src>) will produce the value of the quantum and its
205 // units. Given <src>Quantity myval(5.,"mJy"), << myval</src> will produce:
206 // <src>5.0 mJy</src>; while <src><< myval.get("yW/m2")</src>
207 // will produce: <src>.00005 yW/m2.s</src>.<br>
208 // The input operator (<src>>></src>, or the static read functions) will
209 // convert a String to a Quantum (quantity only for now). The analysis
210 // will do the following:
211 // <ul>
212 // <li> Check if it can be converted as a time/angle, if so use
213 // (<linkto class=MVAngle>MVAngle</linkto>)
214 // <li> Check if it can be used as a date/time. if so use
215 // (<linkto class=MVTime>MVTime</linkto>)
216 // <li> Interpret as a value with units
217 // </ul>
218 // <note role=caution> Since e.g. <em>12d</em> could be interpreted as
219 // being both an angle (12 degrees) or a quantity (12 days), the only way
220 // is to differentiate them with a decimal point (12.d will be days)</note>
221 //
222 // </synopsis>
223 //
224 // <example>
225 // An experiment has measured the energy of a photon in keV. The following will
226 // output the wavelength and frequency of this photon (see the
227 // <linkto class=QC">QC</linkto> class for quantity constants):
228 // <srcblock>
229 // #include <casacore/casa/Quanta.h>
230 // Double myval; // keV photon energy
231 // Quantity quant(myval,"keV"); // make quantity
232 // cout << "A photon with energy " << quant << endl
233 // << " has a frequency of "
234 // << (quant/QC::h)->get("GHz") << endl // h=Planck
235 // << " and a wavelength of "
236 // << (QC::c/quant/QC::h)->get("nm") // c=light velocity
237 // << " or " << QC::c/quant/QC::h << endl;
238 // </srcblock>
239 // </example>
240 //
241 // <motivation>
242 // Major use is foreseen in all calculations with observed data.
243 // </motivation>
244 
245 // <templating arg=Qtype>
246 // <li> prefix +,-
247 // <li> + - * / and += -= *= /=
248 // <li> <src>< <= == != >= ></src>
249 // <li> sin
250 // <li> cos
251 // <li> tan
252 // <li> asin
253 // <li> acos
254 // <li> atan
255 // <li> atan2
256 // <li> abs
257 // <li> ceil
258 // <li> floor
259 // <li> <note role=caution>
260 // It is assumed that all these functions return either Bool or
261 // the same data type as inputted (i.e. QType). Special functions are
262 // provided in this module to convert Int and LogicalArray to Bool;
263 // and to convert were necessary to Complex (e.g. abs(Complex)).
264 // </note>
265 // </templating>
266 
267 // <todo asof="941123">
268 // <li> Some inlining (did not work first go)
269 // </todo>
270 
271 template <class Qtype> class Quantum : public QBase{
272  //# Friends
273  // Input, only quantity is supported now
274  friend istream& operator>> (istream &is, Quantity &ku);
275  public:
276  //# Constructors
277  // Default constructor, generates '0'
278  Quantum();
279  // Copy constructor (deep copy)
280  Quantum(const Quantum<Qtype> &other);
281  // Construct undimensioned quantum (i.e. unit="")
282  Quantum(const Qtype &factor);
283  // Construct dimensioned quantum (e.g. '1.23 km/Mpc')
284  // <thrown>
285  // <li> AipsError if non-matching unit dimensions
286  // </thrown>
287  // <group>
288  Quantum(const Qtype &factor, const Unit &s);
289  // </group>
290  // Construct quantum with unit copied from existing quantum
291  Quantum(const Qtype &factor, const QBase &other);
292 
293  // Destructor
294  ~Quantum();
295 
296  //# Operators
297  // Assignment (deep copy)
298  Quantum<Qtype> &operator=(const Quantum<Qtype> &other);
299 
300 
301  // Unary operations
302  // <group>
303  const Quantum<Qtype> &operator+() const;
304  Quantum<Qtype> operator-() const;
305  // </group>
306 
307  // In place arithmetic functions: left hand side changed in place
308  // <thrown>
309  // <li> AipsError if non-conforming units (+ and -)
310  // <li> AipsError if illegal result unit (* and /; programming error)
311  // </thrown>
312  // <group>
314  Quantum<Qtype> &operator+=(const Qtype &other);
316  Quantum<Qtype> &operator-=(const Qtype &other);
318  Quantum<Qtype> &operator*=(const Qtype &other);
320  Quantum<Qtype> &operator/=(const Qtype &other);
321  // </group>
322 
323  // Arithmetic operators: return Quantum<T>
324  // <thrown>
325  // <li> AipsError if non-conforming units (+ and -)
326  // </thrown>
327  // See <linkto group="QMath#Quantum mathematical operations">QMath</linkto> class for unequal argument types
328  // <group>
329  Quantum<Qtype> operator+(const Quantum<Qtype> &other) const;
330  Quantum<Qtype> operator-(const Quantum<Qtype> &other) const;
331  Quantum<Qtype> operator*(const Quantum<Qtype> &other) const;
332  Quantum<Qtype> operator/(const Quantum<Qtype> &other) const;
333  // </group>
334 
335  //# General member functions
336  // Get value of quantum in current units (i.e. in units specified in quantum)
337  // <group>
338  const Qtype &getValue() const;
339  Qtype &getValue();
340  // </group>
341  // Get value in canonical base units
342  Qtype getBaseValue() const;
343 
344  // Get value in specified units.
345  // If the <src>other</src> units do not conform to the units of this
346  // object and requireConform is True, an exception is thrown,
347  // with the following exceptions:
348  // <br>- angle to/from time conversions are implicitly supported
349  // <br>- frequency to/from/ wavelength conversions are implicitly supported
350  //# <br>Note, I added requireConform and made the default value False for
351  //# backward compatibility. However, I think that ultimately requireConform
352  //# should be removed and an exception should be thrown if the units do
353  //# not conform. It's not clear to me why this was not in the original
354  //# implementation; it's much too easy for non-conformation bugs to
355  //# slip by unnoticed. - dmehring 09feb2015
356  //# It should be left in since conversion from time to angle makes sense.
357  //# Maybe the default could be changed to True. - gvandiepen09feb2016
358  Qtype getValue(const Unit &other, Bool requireConform=False) const;
359 
360  // Get the unit (as Unit) that is attached to the Quantum. (use getUnit() if
361  // interested in the String part only, e.g. for output)
362  virtual const Unit &getFullUnit() const;
363 
364  // Re-specify parts of a quantum
365  // <group name="set value">
366  // Scale ( i.e. multiply) the value of the Quantum without changing units
367  void scale(const Qtype &factor);
368  // Set the value without changing units
369  void setValue(const Qtype &val);
370  // Set the value and unit deduced from input string
371  // <note role=caution> At the moment the implementation can only convert
372  // scalars to the appropiate Quantum. If format for Array input defined,
373  // it could easily be changed. In addition recognition of date/time/angle
374  // still has to be added </note>
375  // <group>
376  static Bool read(Quantity &res, const String &in);
377  static Bool read(Quantity &res, MUString &in);
378  // </group>
379  // </group>
380 
381  // Check if of specified type
382  Bool check(const UnitVal &uv) const;
383 
384  // Assert correct kind
385  // <thrown>
386  // <li> AipsError if non-conforming unit dimensions
387  // </thrown>
388  void assure(const UnitVal &uv) const;
389 
390  // Return a Quantum converted to specified units
391  // <group name="get">
392  // Convert to canonical units
393  Quantum<Qtype> get() const;
394  // Convert to specified units; any remainder will be expressed in canonical
395  // units. E.g. conversion of Jy/pc into W/ly2 will result in W/ly2.m-1.s .
396  // <thrown>
397  // <li> AipsError if illegal unit
398  // </thrown>
399  Quantum<Qtype> get(const Unit &s) const;
400  // Convert a Quantum to units from specified quantum (ibid example)
401  Quantum<Qtype> get(const Quantum<Qtype> &other) const;
402  // </group>
403 
404  // Convert a Quantum to specified units
405  // <group>
406  // Convert to canonical units
407  void convert();
408  // Convert to specified units; any remainder will be expressed in canonical
409  // units. E.g. conversion of Jy/pc into W/ly2 will result in W/ly2.m-1.s .
410  // <thrown>
411  // <li> AipsError if illegal unit
412  // </thrown>
413  void convert(const Unit &s);
414  // Convert a Quantum to units from specified quantum (ibid example)
415  void convert(const Quantum<Qtype> &other) ;
416  // </group>
417  // Get a copy of Quantum
418  virtual QBase *clone() const;
419  // Print a Quantum
420  virtual void print(ostream &os) const;
421  // Get the type (using QuantumType) of derived Quantum (faster than Strings)
422  // <group>
423  virtual uInt type() const;
424  static uInt myType();
425  // </group>
426 
427 private:
428  //# Data members
429  // Actual quantum value
430  Qtype qVal;
431 
432 };
433 
434 // Global functions
435 // <summary> Global input function </summary>
436 // Output/Input
437 // <group name=output>
438 // only Quantity is supported on input
439 istream& operator>> (istream &is, Quantity &ku);
440 Bool readQuantity(Quantity &res, MUString &in);
441 Bool readQuantity(Quantity &res, const String &in);
442 // </group>
443 
444 //# Declare extern templates for often used types.
445  extern template class Quantum<Double>;
446 
447 
448 } //# NAMESPACE CASACORE - END
449 
450 #ifndef CASACORE_NO_AUTO_TEMPLATES
451 #include <casacore/casa/Quanta/Quantum.tcc>
452 #endif //# CASACORE_NO_AUTO_TEMPLATES
453 #endif
void assure(const UnitVal &uv) const
Assert correct kind.
friend istream & operator>>(istream &is, Quantity &ku)
Input, only quantity is supported now.
Base for Quantities (i.e. dimensioned values)
Definition: QBase.h:80
Quantum< Qtype > & operator-=(const Quantum< Qtype > &other)
virtual const Unit & getFullUnit() const
Get the unit (as Unit) that is attached to the Quantum.
void setValue(const Qtype &val)
Set the value without changing units.
const Quantum< Qtype > & operator+() const
Unary operations.
Quantum< Qtype > & operator=(const Quantum< Qtype > &other)
Assignment (deep copy)
describes any valid unit as a factor and a dimenion of SI units
Definition: UnitVal.h:167
Quantum< Double > Quantity
Definition: Quantum.h:38
ostream & operator>>(ostream &is, MVTime &meas)
Quantum< Qtype > & operator*=(const Quantum< Qtype > &other)
virtual uInt type() const
Get the type (using QuantumType) of derived Quantum (faster than Strings)
~Quantum()
Destructor.
Pointed String class to aid analysis of quantity strings.
Definition: MUString.h:229
void convert()
Convert a Quantum to specified units.
virtual QBase * clone() const
Get a copy of Quantum.
static Bool read(Quantity &res, const String &in)
Set the value and unit deduced from input string Caution: At the moment the implementation can only ...
void scale(const Qtype &factor)
Re-specify parts of a quantum.
defines physical units
Definition: Unit.h:189
Quantum< Qtype > operator/(const Quantum< Qtype > &other) const
Quantum()
Default constructor, generates &#39;0&#39;.
static uInt myType()
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
Quantities (i.e. dimensioned values)
Definition: QuantumHolder.h:44
const Bool False
Definition: aipstype.h:44
Quantum< Qtype > operator-() const
virtual void print(ostream &os) const
Print a Quantum.
Qtype qVal
Actual quantum value.
Definition: Quantum.h:430
const Qtype & getValue() const
Get value of quantum in current units (i.e.
Bool check(const UnitVal &uv) const
Check if of specified type.
Qtype getBaseValue() const
Get value in canonical base units.
Quantum< Qtype > & operator/=(const Quantum< Qtype > &other)
String: the storage and methods of handling collections of characters.
Definition: String.h:223
Quantum< Qtype > & operator+=(const Quantum< Qtype > &other)
In place arithmetic functions: left hand side changed in place.
Quantum< Qtype > operator*(const Quantum< Qtype > &other) const
unsigned int uInt
Definition: aipstype.h:51
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42