Loading...
Searching...
No Matches
Quantum.h
Go to the documentation of this file.
//# Quantum.h: class to manipulate physical, dimensioned quantities
//# Copyright (C) 1994,1995,1996,1997,1998,1999,2000,2001
//# 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: casa-feedback@nrao.edu.
//# Postal address: AIPS++ Project Office
//# National Radio Astronomy Observatory
//# 520 Edgemont Road
//# Charlottesville, VA 22903-2475 USA
#ifndef CASA_QUANTUM_H
#define CASA_QUANTUM_H
#include <casacore/casa/aips.h>
#include <casacore/casa/Quanta/QBase.h>
#include <casacore/casa/iosstrfwd.h>
namespace casacore { //# NAMESPACE CASACORE - BEGIN
//# Forward Declarations
template <class T> class Quantum;
//# Typedefs
typedef Quantum<Double> Quantity;
// <summary>
// Quantities (i.e. dimensioned values)
// </summary>
// <use visibility=export>
// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tQuantum">
// </reviewed>
//
// <prerequisite>
// <li> <linkto class=Unit>Unit</linkto>
// </prerequisite>
//
// <etymology>
// A Quantity is defined as a single Double value with attached units.
// From this definition the templated Quantum class arose, to have non-Double,
// non-scalar quantities.
// </etymology>
//
// <synopsis>
// Quantities are values with a unit. Their basic specification can be one of
// two forms:
// <srcblock>
// Quantity( Double value, String unit); // or: Unit unit
// Quantum<Type> ( Type value, String unit) // or: Unit unit
// </srcblock>
//
// A unit is a string of known unit fields separated
// by 'space' or '.' (to indicate multiply) or '/' (to indicate divide).
// See the <linkto class=Unit>Unit</linkto> class for details.
//
// Example: km/s/(Mpc.s)2 is identical to km.s-1.Mpc-2.s-2
//
// <h3> Defining a Quantum </h3>
// The following list of constructors is available.
// <note role=tip>
// In the following 'String' can be replaced by 'Unit' everywhere. The
// only difference being a check for a legitimate unit string being executed
// if Unit specified (with exception if error)
// </note>
// <note role=tip>
// <src>'Quantum<Type>'</src> can, if Type equals Double, be replaced
// with 'Quantity'
//
// 'Type' can be any simple or non-simple arithmetic type.
//
// E.g. <src><Double>, <Complex>, <Vector<Double> ></src>
// </note>
// <ul>
// <li> <src>Quantum<Type>() value 0 generated</src>
// <li> <src>Quantum<Type>( Quantum<Type>) copy constructor</src>
// <li> <src>Quantum<Type>( Type factor) value factor generated</src>
// <li> <src>Quantum<Type>( Type factor, Unit unit) specified quantity</src>
// <li> <src>Quantum<Type>( Type factor, Quantum<any> quant) specified factor,</src>
// the unit from the quant
// </ul>
//
//
// <h3> Manipulating quantities </h3>
// <linkto group="QMath.h#Quantum mathematical operations">Mathematical operators and functions</linkto> and
// <linkto group="QLogical.h#Quantum logical operations">logical operations</linkto> (comparisons)
// are defined on Quantums. They are,
// of course, only available if the template Type supports them.
// <ul>
// <li> <src>= assignment of identical <type></src>
// <li> <src>* *= multiple two Quantums of same <type>, or Quantum and type</src>
// <li> <src>/ /= divide two Quantums of same <type>, or Quantum and type</src>
// note:
// In multiplication and division, and if <src><type></src> is scalar, the left or
// right-hand side can be of type <src><type></src> (e.g 2.*Quantity is allowed)
// <li> <src>+ += add two Quantums of same <type> or Quantum and type</src>
// and same unit dimensions (else exception)
// <li> - -= subtract (same as +)
// <li> - negate Quantum
// <li> + unary + on Quantum
// <li> <src>== != compare unit dimensions and value of same <type>. They will</src>
// be unequal if the units do not match or the values (possibly
// converted to common base units). All comparisons work also
// on a <src>Quantum<type> and <type></src>
// <li> <src>< > compare unit dimensions. Exception if no match,</src>
// else compare the values
// <li> <src><= >= ibid</src>
// <li> pow(Int) raise to an (integer) power
// </ul>
//
//
// <h3> Manipulating the value and/or units of quanta </h3>
// Quantities can be converted to other units by the following set of member
// functions:
// <ul>
// <li> convert() will convert the quantum to canonical units.
// E.g. given myval=Quantity(5.,"Jy"),
// myval.convert() will convert the qunatum to
// Quantity(5.e-26,"kg.s-2")
// <li> convert(Unit unit) will convert the quantum to the
// specified unit with any remaining dimensions
// expressed in canonical units. E.g given
// myval as above, myval.convert("W/cm") will
// make it Quantity(5.e-28,"W/cm.m-1.s")
// <li> <src>convert(Quantum<Type> quant) will convert the quantum</src>
// to the units of the specified quant with the
// same conversion rules as the previous one
// </ul>
// <note role=tip> All converting type methods (i.e. convert(), get() and
// getValue() with specified units), will automatically convert also from
// time to angle units (or v.v) if necessary, as long as they are simple. I.e.
// deg will be converted to h, but asking to convert m/s to m/deg will
// produce the standard conversion to m/deg.rad/s. </note>
//
// Quanta can be checked for having the correct unit dimensions (e.g. before
// addition or comparing) by the following two member functions, which will
// return a Bool value:
// <ul>
// <li> isConform(Unit unit)
// <li> <src>isConform(Quantum<Type> quant)</src>
// <li> check(UnitVal kind)
// </ul>
// or by an assertion, which will throw an exception:<br>
// <ul>
// <li> assure(UnitVal kind)
// </ul>
//
// The quantum can be retrieved with a change in units by:
// <ul>
// <li> get() will return the quantum converted to canonical units.
// E.g. given myval=Quantity(5.,"Jy"),
// myval.get() will return
// Quantity(5.e-26,"kg.s-2")
// <li> get(Unit unit) will return the quantum converted to the
// specified unit with any remaining dimensions
// expressed in canonical units. E.g given
// myval as above, myval.get("W/cm") will
// return it as Quantity(5.e-28,"W/cm.m-1.s")
// <li> <src>get(Quantum<Type> quant) will return the quantum converted</src>
// to the units of the specified quant with the
// same conversion rules as the previous one
// </ul>
//
// The value and units of a quantum can be set or retrieved separately by the
// following member functions:
// <ul>
// <li> getValue() return the value (as Type) of the quantum.
// <note role=tip> myval.get().getValue() will return the
// value of myval expressed in canonical units
// </note>
// <li> getValue(Unit unit) return the value (as converted to unit)
// <li> getUnit() return the String part of the unit of the
// quantum (use getFullUnit if interested in
// the complete Unit, e.g. for re-use)
// <li> getFullUnit() return the complete unit of the Quantum (use
// getUnit() if interested in String part only)
// <li> setValue(Type val) replace the value of the quantum with val,
// leaving the units the same
// <li> scale(Type val) multiply the value (leaving units same) by the
// specified value
// <li> setUnit(Unit unit) replace the units of the quantum, leaving
// the value the same.
// <li> <src>setUnit(Quantum<Type> quant) ibid</src>
// <li> set(String quantity) replace the value and unit as deduced from quantity
// </ul>
//
// The output operator (<src><<</src>) will produce the value of the quantum and its
// units. Given <src>Quantity myval(5.,"mJy"), << myval</src> will produce:
// <src>5.0 mJy</src>; while <src><< myval.get("yW/m2")</src>
// will produce: <src>.00005 yW/m2.s</src>.<br>
// The input operator (<src>>></src>, or the static read functions) will
// convert a String to a Quantum (quantity only for now). The analysis
// will do the following:
// <ul>
// <li> Check if it can be converted as a time/angle, if so use
// (<linkto class=MVAngle>MVAngle</linkto>)
// <li> Check if it can be used as a date/time. if so use
// (<linkto class=MVTime>MVTime</linkto>)
// <li> Interpret as a value with units
// </ul>
// <note role=caution> Since e.g. <em>12d</em> could be interpreted as
// being both an angle (12 degrees) or a quantity (12 days), the only way
// is to differentiate them with a decimal point (12.d will be days)</note>
//
// </synopsis>
//
// <example>
// An experiment has measured the energy of a photon in keV. The following will
// output the wavelength and frequency of this photon (see the
// <linkto class=QC">QC</linkto> class for quantity constants):
// <srcblock>
// #include <casacore/casa/Quanta.h>
// Double myval; // keV photon energy
// Quantity quant(myval,"keV"); // make quantity
// cout << "A photon with energy " << quant << endl
// << " has a frequency of "
// << (quant/QC::h)->get("GHz") << endl // h=Planck
// << " and a wavelength of "
// << (QC::c/quant/QC::h)->get("nm") // c=light velocity
// << " or " << QC::c/quant/QC::h << endl;
// </srcblock>
// </example>
//
// <motivation>
// Major use is foreseen in all calculations with observed data.
// </motivation>
// <templating arg=Qtype>
// <li> prefix +,-
// <li> + - * / and += -= *= /=
// <li> <src>< <= == != >= ></src>
// <li> sin
// <li> cos
// <li> tan
// <li> asin
// <li> acos
// <li> atan
// <li> atan2
// <li> abs
// <li> ceil
// <li> floor
// <li> <note role=caution>
// It is assumed that all these functions return either Bool or
// the same data type as inputted (i.e. QType). Special functions are
// provided in this module to convert Int and LogicalArray to Bool;
// and to convert were necessary to Complex (e.g. abs(Complex)).
// </note>
// </templating>
// <todo asof="941123">
// <li> Some inlining (did not work first go)
// </todo>
template <class Qtype> class Quantum : public QBase{
//# Friends
// Input, only quantity is supported now
friend istream& operator>> (istream &is, Quantity &ku);
public:
//# Constructors
// Default constructor, generates '0'
Quantum();
// Copy constructor (deep copy)
Quantum(const Quantum<Qtype> &other);
// Construct undimensioned quantum (i.e. unit="")
Quantum(const Qtype &factor);
// Construct dimensioned quantum (e.g. '1.23 km/Mpc')
// <thrown>
// <li> AipsError if non-matching unit dimensions
// </thrown>
// <group>
Quantum(const Qtype &factor, const Unit &s);
// </group>
// Construct quantum with unit copied from existing quantum
Quantum(const Qtype &factor, const QBase &other);
//# Operators
// Assignment (deep copy)
Quantum<Qtype> &operator=(const Quantum<Qtype> &other);
// Unary operations
// <group>
const Quantum<Qtype> &operator+() const;
Quantum<Qtype> operator-() const;
// </group>
// In place arithmetic functions: left hand side changed in place
// <thrown>
// <li> AipsError if non-conforming units (+ and -)
// <li> AipsError if illegal result unit (* and /; programming error)
// </thrown>
// <group>
Quantum<Qtype> &operator+=(const Quantum<Qtype> &other);
Quantum<Qtype> &operator+=(const Qtype &other);
Quantum<Qtype> &operator-=(const Quantum<Qtype> &other);
Quantum<Qtype> &operator-=(const Qtype &other);
Quantum<Qtype> &operator*=(const Quantum<Qtype> &other);
Quantum<Qtype> &operator*=(const Qtype &other);
Quantum<Qtype> &operator/=(const Quantum<Qtype> &other);
Quantum<Qtype> &operator/=(const Qtype &other);
// </group>
// Arithmetic operators: return Quantum<T>
// <thrown>
// <li> AipsError if non-conforming units (+ and -)
// </thrown>
// See <linkto group="QMath#Quantum mathematical operations">QMath</linkto> class for unequal argument types
// <group>
Quantum<Qtype> operator+(const Quantum<Qtype> &other) const;
Quantum<Qtype> operator-(const Quantum<Qtype> &other) const;
Quantum<Qtype> operator*(const Quantum<Qtype> &other) const;
Quantum<Qtype> operator/(const Quantum<Qtype> &other) const;
// </group>
//# General member functions
// Get value of quantum in current units (i.e. in units specified in quantum)
// <group>
const Qtype &getValue() const;
Qtype &getValue();
// </group>
// Get value in canonical base units
Qtype getBaseValue() const;
// Get value in specified units.
// If the <src>other</src> units do not conform to the units of this
// object and requireConform is True, an exception is thrown,
// with the following exceptions:
// <br>- angle to/from time conversions are implicitly supported
// <br>- frequency to/from/ wavelength conversions are implicitly supported
//# <br>Note, I added requireConform and made the default value False for
//# backward compatibility. However, I think that ultimately requireConform
//# should be removed and an exception should be thrown if the units do
//# not conform. It's not clear to me why this was not in the original
//# implementation; it's much too easy for non-conformation bugs to
//# slip by unnoticed. - dmehring 09feb2015
//# It should be left in since conversion from time to angle makes sense.
//# Maybe the default could be changed to True. - gvandiepen09feb2016
Qtype getValue(const Unit &other, Bool requireConform=False) const;
// Get the unit (as Unit) that is attached to the Quantum. (use getUnit() if
// interested in the String part only, e.g. for output)
virtual const Unit &getFullUnit() const;
// Re-specify parts of a quantum
// <group name="set value">
// Scale ( i.e. multiply) the value of the Quantum without changing units
void scale(const Qtype &factor);
// Set the value without changing units
void setValue(const Qtype &val);
// Set the value and unit deduced from input string
// <note role=caution> At the moment the implementation can only convert
// scalars to the appropiate Quantum. If format for Array input defined,
// it could easily be changed. In addition recognition of date/time/angle
// still has to be added </note>
// <group>
static Bool read(Quantity &res, const String &in);
static Bool read(Quantity &res, MUString &in);
// </group>
// </group>
// Check if of specified type
Bool check(const UnitVal &uv) const;
// Assert correct kind
// <thrown>
// <li> AipsError if non-conforming unit dimensions
// </thrown>
void assure(const UnitVal &uv) const;
// Return a Quantum converted to specified units
// <group name="get">
// Convert to canonical units
Quantum<Qtype> get() const;
// Convert to specified units; any remainder will be expressed in canonical
// units. E.g. conversion of Jy/pc into W/ly2 will result in W/ly2.m-1.s .
// <thrown>
// <li> AipsError if illegal unit
// </thrown>
Quantum<Qtype> get(const Unit &s) const;
// Convert a Quantum to units from specified quantum (ibid example)
Quantum<Qtype> get(const Quantum<Qtype> &other) const;
// </group>
// Convert a Quantum to specified units
// <group>
// Convert to canonical units
void convert();
// Convert to specified units; any remainder will be expressed in canonical
// units. E.g. conversion of Jy/pc into W/ly2 will result in W/ly2.m-1.s .
// <thrown>
// <li> AipsError if illegal unit
// </thrown>
void convert(const Unit &s);
// Convert a Quantum to units from specified quantum (ibid example)
void convert(const Quantum<Qtype> &other) ;
// </group>
// Get a copy of Quantum
virtual QBase *clone() const;
// Print a Quantum
virtual void print(ostream &os) const;
// Get the type (using QuantumType) of derived Quantum (faster than Strings)
// <group>
virtual uInt type() const;
static uInt myType();
// </group>
private:
//# Data members
// Actual quantum value
Qtype qVal;
};
// Global functions
// <summary> Global input function </summary>
// Output/Input
// <group name=output>
// only Quantity is supported on input
istream& operator>> (istream &is, Quantity &ku);
Bool readQuantity(Quantity &res, MUString &in);
Bool readQuantity(Quantity &res, const String &in);
// </group>
//# Declare extern templates for often used types.
extern template class Quantum<Double>;
} //# NAMESPACE CASACORE - END
#ifndef CASACORE_NO_AUTO_TEMPLATES
#include <casacore/casa/Quanta/Quantum.tcc>
#endif //# CASACORE_NO_AUTO_TEMPLATES
#endif
casacore::MUString
Definition MUString.h:228
casacore::QBase::QBase
QBase()
Default constructor, generates "".
casacore::Quantum
Definition Quantum.h:269
casacore::Quantum::Quantum
Quantum(const Quantum< Qtype > &other)
Copy constructor (deep copy).
casacore::Quantum::getValue
Qtype & getValue()
casacore::Quantum::Quantum
Quantum(const Qtype &factor, const Unit &s)
Construct dimensioned quantum (e.g.
casacore::Quantum::Quantum
Quantum(const Qtype &factor, const QBase &other)
Construct quantum with unit copied from existing quantum.
casacore::Quantum::operator/=
Quantum< Qtype > & operator/=(const Qtype &other)
casacore::Quantum::convert
void convert()
Convert a Quantum to specified units.
casacore::Quantum::convert
void convert(const Quantum< Qtype > &other)
Convert a Quantum to units from specified quantum (ibid example).
casacore::Quantum< Double >::qVal
Double qVal
Definition Quantum.h:424
casacore::Quantum::clone
virtual QBase * clone() const
Get a copy of Quantum.
casacore::Quantum::check
Bool check(const UnitVal &uv) const
Check if of specified type.
casacore::Quantum::operator*
Quantum< Qtype > operator*(const Quantum< Qtype > &other) const
casacore::Quantum::getFullUnit
virtual const Unit & getFullUnit() const
Get the unit (as Unit) that is attached to the Quantum.
casacore::Quantum::get
Quantum< Qtype > get(const Unit &s) const
Convert to specified units; any remainder will be expressed in canonical units.
casacore::Quantum::operator/=
Quantum< Qtype > & operator/=(const Quantum< Qtype > &other)
casacore::Quantum::operator-=
Quantum< Qtype > & operator-=(const Quantum< Qtype > &other)
casacore::Quantum::operator+
Quantum< Qtype > operator+(const Quantum< Qtype > &other) const
Arithmetic operators: return Quantum<T>.
casacore::Quantum::convert
void convert(const Unit &s)
Convert to specified units; any remainder will be expressed in canonical units.
casacore::Quantum::scale
void scale(const Qtype &factor)
Re-specify parts of a quantum .
casacore::Quantum::get
Quantum< Qtype > get() const
Return a Quantum converted to specified units .
casacore::Quantum::print
virtual void print(ostream &os) const
Print a Quantum.
casacore::Quantum::operator/
Quantum< Qtype > operator/(const Quantum< Qtype > &other) const
casacore::Quantum::getValue
Qtype getValue(const Unit &other, Bool requireConform=False) const
Get value in specified units.
casacore::Quantum::getBaseValue
Qtype getBaseValue() const
Get value in canonical base units.
casacore::Quantum::operator+=
Quantum< Qtype > & operator+=(const Qtype &other)
casacore::Quantum::get
Quantum< Qtype > get(const Quantum< Qtype > &other) const
Convert a Quantum to units from specified quantum (ibid example).
casacore::Quantum::operator*=
Quantum< Qtype > & operator*=(const Qtype &other)
casacore::Quantum::getValue
const Qtype & getValue() const
Get value of quantum in current units (i.e.
casacore::Quantum::operator-
Quantum< Qtype > operator-() const
casacore::Quantum::operator+=
Quantum< Qtype > & operator+=(const Quantum< Qtype > &other)
In place arithmetic functions: left hand side changed in place.
casacore::Quantum::type
virtual uInt type() const
Get the type (using QuantumType) of derived Quantum (faster than Strings).
casacore::Quantum::operator*=
Quantum< Qtype > & operator*=(const Quantum< Qtype > &other)
casacore::Quantum::operator+
const Quantum< Qtype > & operator+() const
Unary operations.
casacore::Quantum::Quantum
Quantum(const Qtype &factor)
Construct undimensioned quantum (i.e.
casacore::Quantum::read
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 ...
casacore::Quantum::myType
static uInt myType()
casacore::Quantum::assure
void assure(const UnitVal &uv) const
Assert correct kind.
casacore::Quantum::setValue
void setValue(const Qtype &val)
Set the value without changing units.
casacore::Quantum::Quantum
Quantum()
Default constructor, generates '0'.
casacore::Quantum::operator=
Quantum< Qtype > & operator=(const Quantum< Qtype > &other)
Assignment (deep copy).
casacore::Quantum::read
static Bool read(Quantity &res, MUString &in)
casacore::Quantum::operator-
Quantum< Qtype > operator-(const Quantum< Qtype > &other) const
casacore::Quantum::operator-=
Quantum< Qtype > & operator-=(const Qtype &other)
casacore::Quantum::operator>>
friend istream & operator>>(istream &is, Quantity &ku)
Input, only quantity is supported now.
casacore::String
String: the storage and methods of handling collections of characters.
Definition String.h:223
casacore::UnitVal
Definition UnitVal.h:165
casacore::Unit
Definition Unit.h:187
casacore
this file contains all the compiler specific defines
Definition mainpage.dox:28
casacore::False
const Bool False
Definition aipstype.h:42
casacore::operator>>
friend AipsIO & operator>>(AipsIO &os, Record &rec)
Read the Record from an input stream.
Definition Record.h:462
casacore::factor
int * factor
Definition hdu.h:478
casacore::uInt
unsigned int uInt
Definition aipstype.h:49
casacore::Bool
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40
casacore::Quantity
Quantum< Double > Quantity
Definition Quantum.h:39
casacore::Quantum_global_functions_output
Global functions.
Definition Quantum.h:433
casacore::Quantum_global_functions_output::readQuantity
Bool readQuantity(Quantity &res, const String &in)
casacore::Quantum_global_functions_output::operator>>
istream & operator>>(istream &is, Quantity &ku)
only Quantity is supported on input
casacore::Quantum_global_functions_output::readQuantity
Bool readQuantity(Quantity &res, MUString &in)