qdyn.units module¶
Conversion between physical units
Summary¶
Classes:
Perform conversion between different physical units |
|
Class for a float value with a physical unit. |
Reference¶
-
class
qdyn.units.
UnitConvert
(units_file=None)[source]¶ Bases:
object
Perform conversion between different physical units
- Parameters
units_file (str) – file from which to read unit definitions. The content in the file must be in the format specified in
read_units_definition()
. The file must contain two columns. The first columns contains the unit name, the second column the conversion factor between internal units and the unit. Units are separated into category blocks of compatible units by comment lines (starting with ‘#’). Only units in the same category (i.e., the same block in units_file) can be converted into each other. If not given, the converter is initialized with a default set of units, using atomic units internally.
Note
The special unit name ‘iu’ indicates “internal units”, from and to which any unit can be converted. By default, this is atomic units (and ‘au’ is an alias for ‘iu’). Different internal units may be used by loading a units_file, although there is little reason to do so. It is required that hbar is 1 in internal units, making energy and time directly inverse quantities.
Examples
>>> convert = UnitConvert() >>> print("%.2f" % convert.convert(1000, 'MHz', 'GHz')) 1.00 >>> v = UnitFloat(1000, 'MHz') >>> print("%s" % convert.convert(v, to_unit='GHz')) 1_GHz >>> v_in_MHz = numpy.linspace(0, 1000, 3) >>> v_in_GHz = convert.convert(v_in_MHz, 'MHz', 'GHz') >>> print(", ".join([("%.2f" % entry) for entry in v_in_GHz])) 0.00, 0.50, 1.00
-
convert
(value, from_unit=None, to_unit=None)[source]¶ Convert value between units. The result will be of the same type as the input value.
- Parameters
value (float, numpy.ndarray, UnitFloat) – Value (or array of values) to convert
from_unit (str) – Unit of value. Alternatively, if value is an instance of
UnitFloat
, the from_unit can be taken from value. If given neither directly or obtained from value, convert from ‘internal units’to_unit (str) – Unit to which to convert. If not given, convert to ‘internal units’. Note that from_unit and to_unit must be compatible (i.e., both must be units of the same category, e.g. energy, length, or time)
- Raises
ValueError – if from_unit and to_unit are not compatible, from_unit is incompatible with value, or either from_unit or to_unit are unknown units
-
add_unit
(unit, convfactor, compatible_with=None)[source]¶ Register a new unit
- Parameters
unit (str) – name of the unit
convfactor (float) – conversion factor to internal units
compatible_with (str) – name of another unit that unit can be converted to. Compatibility is transitive, i.e. unit will also be convertible to anything compatible with compatible_with. If not given, the new unit can only be converted to internal units.
>>> convert = UnitConvert() >>> convert.add_unit("THz", 6.579683918175572e3, compatible_with='J') >>> print(" ".join(sorted(convert.compatible_units('GHz')))) Hartree Hz J K MHz THz au cminv eV hartree iu kHz
-
compatible_units
(unit)[source]¶ Set of all units to which unit can be converted
>>> convert = UnitConvert() >>> print(" ".join(sorted(convert.compatible_units('GHz')))) Hartree Hz J K MHz au cminv eV hartree iu kHz
-
property
units
¶ Set of all defined unit names
-
class
qdyn.units.
UnitFloat
(val=0.0, unit=None)[source]¶ Bases:
object
Class for a float value with a physical unit. Behaves like a float in most contexts.
- Parameters
val (float, UnitFloat) – The value. If val is an instance of UnitFloat and unit is given also, the value will be converted.
unit (str, None) – The unit. If None, the unit is take from val if val is an instance of UnitFloat, or else the unit is set to
unitless
. Any unit known to to the unternal unit convert may be used. Using internal units (unit='iu'
) is valid, but should be avoided.
- Class Attributes:
unit_convert (UnitConvert): internal unit converter
Examples
>>> v = UnitFloat(1.0, 'GHz') >>> print(v) 1_GHz
>>> v = UnitFloat(1.0) >>> print(v) 1_unitless
>>> v2 = UnitFloat(1.0, 'GHz') >>> v = UnitFloat(v2, 'MHz') >>> print(v) 1000_MHz
-
unit_convert
= <qdyn.units.UnitConvert object>¶
-
classmethod
from_str
(val_str)[source]¶ Create instance from a string >>> v = UnitFloat.from_str(‘1.0_GHz’) >>> v == UnitFloat(1.0, ‘GHz’) True >>> try: … v = UnitFloat.from_str(‘abcd’) … except ValueError as e: … print(e) String ‘abcd’ does not describe a UnitFloat
-
to_str
(fmt='%g')[source]¶ Convert to string while using the specified format for the value part.
>>> print(UnitFloat(5.2, 'GHz').to_str('%.2f')) 5.20_GHz
-
__str__
()[source]¶ String representation. Equivalent to
to_str()
.>>> f = UnitFloat(1.0, 'GHz') >>> print(f) 1_GHz >>> print(str(f)) 1_GHz >>> print("%s" % str(f)) 1_GHz >>> print(UnitFloat(5.2, 'GHz')) 5.2_GHz >>> print(UnitFloat(1000.2, 'GHz')) 1000.2_GHz >>> print(UnitFloat(100000000000.2, 'GHz')) 1e+11_GHz >>> print(UnitFloat(1.2e12, 'GHz')) 1.2e+12_GHz >>> print(UnitFloat(0)) 0 >>> print(UnitFloat(1.2)) 1.2_unitless
-
__repr__
()¶ String representation. Equivalent to
to_str()
.>>> f = UnitFloat(1.0, 'GHz') >>> print(f) 1_GHz >>> print(str(f)) 1_GHz >>> print("%s" % str(f)) 1_GHz >>> print(UnitFloat(5.2, 'GHz')) 5.2_GHz >>> print(UnitFloat(1000.2, 'GHz')) 1000.2_GHz >>> print(UnitFloat(100000000000.2, 'GHz')) 1e+11_GHz >>> print(UnitFloat(1.2e12, 'GHz')) 1.2e+12_GHz >>> print(UnitFloat(0)) 0 >>> print(UnitFloat(1.2)) 1.2_unitless
-
__eq__
(other)[source]¶ Test equality. Two instances of UnitFloat are the same if their string representation is the same, making the equality check robust against conversion rounding errors.
>>> UnitFloat(1.0, 'GHz') == UnitFloat(1.0, 'GHz') True >>> UnitFloat(1.0, 'GHz') == UnitFloat(2.0, 'GHz') False >>> UnitFloat(1.0, 'GHz') != UnitFloat(2.0, 'GHz') True >>> UnitFloat(1.0, 'GHz') == UnitFloat(1000, 'MHz') True >>> UnitFloat(1.0, 'GHz') == '1_GHz' True >>> UnitFloat(1.0, 'GHz') == (1, 'GHz') True >>> UnitFloat(1.0) == 1 True
-
__gt__
(other)[source]¶ Compare two numbers
>>> UnitFloat(1.0, 'GHz') > UnitFloat(1.0, 'GHz') False >>> UnitFloat(2.0, 'GHz') > UnitFloat(1.0, 'GHz') True >>> UnitFloat(1.0, 'GHz') >= UnitFloat(1.0, 'GHz') True >>> UnitFloat(1.0, 'GHz') < UnitFloat(2.0, 'GHz') True >>> UnitFloat(1.0, 'GHz') <= UnitFloat(1.0, 'GHz') True >>> UnitFloat(1.0, 'GHz') > UnitFloat(900, 'MHz') True >>> try: ... UnitFloat(1.0, 'GHz') < UnitFloat(2.0, 'ns') ... except ValueError as e: ... print(e) Incompatible units in conversion: GHz, ns
-
__abs__
()[source]¶ Absolute value of number
>>> print(abs(UnitFloat(-1.1, 'GHz'))) 1.1_GHz >>> print(abs(UnitFloat(1.1, 'GHz'))) 1.1_GHz
-
__round__
(n)[source]¶ Round to n decimal places. This results in a
UnitFloat
in Python 3 and a float in Python 2.
-
__floor__
()[source]¶ Round down to nearest integer. This results in a
UnitFloat
in Python 3 and a float in Python 2.
-
__ceil__
()[source]¶ Round up to nearest integer. This results in a
UnitFloat
in Python 3 and a float in Python 2.
-
__add__
(other)[source]¶ Add two numbers, which must use exactly the same unit.
>>> print(UnitFloat(1.1, 'GHz') + UnitFloat(2.1, 'GHz')) 3.2_GHz >>> print(UnitFloat(1.1, 'GHz') - UnitFloat(2.0, 'GHz')) -0.9_GHz >>> print(UnitFloat(1.0, 'GHz') + UnitFloat(100, 'MHz')) 1.1_GHz
>>> try: ... UnitFloat(1.0, 'GHz') + 1.0 ... except TypeError as e: ... print(e) All arguments must be instances of UnitFloat
-
__mul__
(factor)[source]¶ Multiply with a number
>>> print(2*UnitFloat(1.1, 'GHz')) 2.2_GHz >>> print(UnitFloat(1.1, 'GHz')*2) 2.2_GHz >>> print(UnitFloat(1.1, 'GHz')*"2.0") 2.2_GHz >>> try: ... print(UnitFloat(1.1, 'GHz')*UnitFloat(1.1, 'GHz')) ... except TypeError as e: ... print(e) Factor cannot be an instance of UnitFloat >>> try: ... print(UnitFloat(1.1, 'GHz')*2.0j) ... except TypeError as e: ... print(e) can't convert complex to float
-
__rmul__
(factor)¶ Multiply with a number
>>> print(2*UnitFloat(1.1, 'GHz')) 2.2_GHz >>> print(UnitFloat(1.1, 'GHz')*2) 2.2_GHz >>> print(UnitFloat(1.1, 'GHz')*"2.0") 2.2_GHz >>> try: ... print(UnitFloat(1.1, 'GHz')*UnitFloat(1.1, 'GHz')) ... except TypeError as e: ... print(e) Factor cannot be an instance of UnitFloat >>> try: ... print(UnitFloat(1.1, 'GHz')*2.0j) ... except TypeError as e: ... print(e) can't convert complex to float
-
__iadd__
(other)[source]¶ Augmented assignment
>>> v = UnitFloat(1.1, 'GHz') >>> v += 1 >>> print(v) 2.1_GHz >>> v -= 1 >>> print(v) 1.1_GHz >>> v2 = UnitFloat(1.0, 'GHz') >>> v += v2 >>> print(v) 2.1_GHz >>> v -= v2 >>> print(v) 1.1_GHz >>> v2 = UnitFloat(100.0, 'MHz') >>> v += v2 >>> print(v) 1.2_GHz >>> v2 = UnitFloat(1.0, 'ns') >>> try: ... v += v2 ... except ValueError as e: ... print(e) Incompatible units in conversion: ns, GHz
-
__imul__
(factor)[source]¶ Augmented multiplication
>>> v = UnitFloat(1.1, 'GHz') >>> v *= 2 >>> print(v) 2.2_GHz
-
__truediv__
(other)[source]¶ Division
>>> v = UnitFloat(1.1, 'GHz') >>> r = v / UnitFloat(0.1, 'GHz') >>> isinstance(r, float) True >>> print("%.1f" % r) 11.0 >>> print("%.1f" % (v / UnitFloat(100, 'MHz'))) 11.0 >>> print(v / 10) 0.11_GHz
-
__div__
(other)¶ Division
>>> v = UnitFloat(1.1, 'GHz') >>> r = v / UnitFloat(0.1, 'GHz') >>> isinstance(r, float) True >>> print("%.1f" % r) 11.0 >>> print("%.1f" % (v / UnitFloat(100, 'MHz'))) 11.0 >>> print(v / 10) 0.11_GHz
-
__itruediv__
(quotient)[source]¶ Augmented division
>>> v = UnitFloat(1.1, 'GHz') >>> v /= 10 >>> print(v) 0.11_GHz
-
__idiv__
(quotient)¶ Augmented division
>>> v = UnitFloat(1.1, 'GHz') >>> v /= 10 >>> print(v) 0.11_GHz
-
__float__
()[source]¶ Convert to float (discarding unit)
>>> float(UnitFloat(1.1, 'GHz')) 1.1 >>> float(UnitFloat(1.1, 'MHz')) 1.1 >>> float(UnitFloat(1.1)) 1.1
The conversion is also invoked for format strings:
>>> print("%.1f" % UnitFloat(1.1, 'GHz')) 1.1 >>> print("%s" % UnitFloat(1.1, 'GHz')) 1.1_GHz