MetPy Constants and Units

Complete list of constants at: https://unidata.github.io/MetPy/latest/api/generated/metpy.constants.html

[1]:
from metpy.units import units
import metpy.constants as c

Invoking constants in MetPy

All constants have a long name, short name, and associated units:

[2]:
print(c.earth_gravity, '   ', c.g)
9.80665 meter / second ** 2     9.80665 meter / second ** 2

Units functionality comes from the pint library. All arithmetic carries units with it:

[3]:
print(c.Rd,'\n' ,c.Cp_d,'\n' , c.Rd / c.Cp_d)
0.2870579959589441 joule / gram / kelvin
 1005 meter ** 2 / kelvin / second ** 2
 0.0002856298467253175 joule * second ** 2 / gram / meter ** 2

Simplifying units

You can see that there can be some ugly units going on sometimes. In pint there is a method to_base_units() that will sort this out and convert to the simplist SI units:

[4]:
diatomic_gas_ratio = c.Rd / c.Cp_d
print(diatomic_gas_ratio.to_base_units())
0.2856298467253175 dimensionless

Automatic dimensional analysis as a debugger

If you try to mix units, you will be reprimanded! This is a good thing - you can catch a lot of code bugs this way.

[5]:
abomination = c.water_heat_vaporization + c.water_gas_constant
---------------------------------------------------------------------------
DimensionalityError                       Traceback (most recent call last)
<ipython-input-5-1f23323fd30a> in <module>
----> 1 abomination = c.water_heat_vaporization + c.water_gas_constant

~/.conda/envs/aoes/lib/python3.6/site-packages/pint/quantity.py in __add__(self, other)
    969             return self.to_timedelta() + other
    970         else:
--> 971             return self._add_sub(other, operator.add)
    972
    973     __radd__ = __add__

~/.conda/envs/aoes/lib/python3.6/site-packages/pint/quantity.py in wrapped(self, *args, **kwargs)
    104         elif isinstance(other, list) and other and isinstance(other[0], type(self)):
    105             return NotImplemented
--> 106         result = f(self, *args, **kwargs)
    107         return result
    108

~/.conda/envs/aoes/lib/python3.6/site-packages/pint/quantity.py in _add_sub(self, other, op)
    882         if not self.dimensionality == other.dimensionality:
    883             raise DimensionalityError(
--> 884                 self._units, other._units, self.dimensionality, other.dimensionality
    885             )
    886

DimensionalityError: Cannot convert from 'meter ** 2 / second ** 2' ([length] ** 2 / [time] ** 2) to 'joule / gram / kelvin' ([length] ** 2 / [temperature] / [time] ** 2)

Changing units

Sometimes you have to add or change units. This is easy to do:

[ ]:
mean_slp = 101325.0 * units.pascal
print(mean_slp)
mean_slp

Note the different formatting of a variable with units between the print statement and inline printing. This is a pint feature - you will see this in other editors too, such as spyder. Note there is no such difference with “ordinary” numbers:

[ ]:
aa = 1.0
print(aa)
aa

The real usefulness is for units conversions. The obvious example:

[ ]:
freezing = 32.0 * units.fahrenheit
freezing.to(units.degC)
[ ]:
freezing.to(units.kelvin)

Note that a united variable (which can be a series, array, element of a dictionary, etc.) has two parts - the units and the magnitude. These can be parsed out separately:

[ ]:
freezing.magnitude

[ ]:
freezing.units
[ ]: