Bases: object
Store, combine and compare physical units and convert numeric values to different units.
Units are as defined in UNIDATA’s Udunits-2 package, with a few exceptions for greater consistency with the CF conventions, namely support for CF calendars and new units defintions.
Modifications to the standard Udunits database
Whilst a standard Udunits-2 database may be used, greater consistency with CF is achieved by using a modified database. The following units are either new to, modified from, or removed from the standard Udunits-2 database (version 2.1.24):
Unit name | Symbol | Definition | Status |
---|---|---|---|
practical_salinity_unit | psu | 1e-3 | New unit |
level | 1 | New unit | |
sigma_level | 1 | New unit | |
layer | 1 | New unit | |
decibel | dB | 1 | New unit |
bel | 10 dB | New unit | |
sverdrup | Sv | 1e6 m3 s-1 | Added symbol |
sievert | J kg-1 | Removed symbol |
Plural forms of the new units’ names are allowed, such as practical_salinity_units.
The modified database is in the udunits subdirectory of the etc directory found in the same location as this module.
Accessing units
Units may be set, retrieved and deleted via the units attribute. Its value is a string that can be recognized by UNIDATA’s Udunits-2 package, with the few exceptions given in the CF conventions.
>>> u = Units('m s-1')
>>> u
<Cf Units: 'm s-1'>
>>> u.units = 'days since 2004-3-1'
>>> u
<CF Units: days since 2004-3-1>
Equality and equivalence of units
There are methods for assessing whether two units are equivalent (equivalent) or equal (equals or the == operator). Two units are equivalent if numeric values in one unit are convertible to numeric values in the other unit (such as kilometres and metres). Two units are equal if they are equivalent and their conversion is a scale factor of 1 and an offset of 0 (such as kilometres and 1000 metres). Note that equivalence and equality are based on internally stored binary representations of the units, rather than their string representations.
>>> u = Units('m/s')
>>> v = Units('m s-1')
>>> w = Units('km.s-1')
>>> x = Units('0.001 kilometer.second-1')
>>> y = Units('gram')
>>> u.equivalent(v), u.equals(v),
(True, True)
>>> u.equivalent(w), u.equals(w)
(True, False)
>>> u.equivalent(x), u.equals(x)
(True, True)
>>> u.equivalent(y), u.equals(y)
(False, False)
Time and reference time units
Time units may be given as durations of time (time units) or as an amount of time since a reference time (reference time units):
>>> v = Units()
>>> v.units = 's'
>>> v.units = 'day'
>>> v.units = 'days since 1970-01-01'
>>> v.units = 'seconds since 1992-10-8 15:15:42.5 -6:00'
Note
It is recommended that the units year and month be used with caution, as explained in the following excerpt from the CF conventions: “The Udunits package defines a year to be exactly 365.242198781 days (the interval between 2 successive passages of the sun through vernal equinox). It is not a calendar year. Udunits includes the following definitions for years: a common_year is 365 days, a leap_year is 366 days, a Julian_year is 365.25 days, and a Gregorian_year is 365.2425 days. For similar reasons the unit month, which is defined to be exactly year/12, should also be used with caution.”
Calendar
The date given in reference time units is associated with one of the calendars recognized by the CF conventions and may be set with the calendar attribute. However, as in the CF conventions, if the calendar is not set then, for the purposes of calculation and comparison, it defaults to the mixed Gregorian/Julian calendar as defined by Udunits:
>>> u = Units('days since 2000-1-1')
>>> u.calendar
AttributeError: Can't get 'Units' attribute 'calendar'
>>> v = Units('days since 2000-1-1')
>>> v.calendar = 'gregorian'
>>> v.equals(u)
True
Arithmetic with units
The following operators, operations and assignments are overloaded:
Comparison operators:
==, !=
Binary arithmetic operations:
+, -, *, /, pow(), **
Unary arithmetic operations:
-, +
Augmented arithmetic assignments:
+=, -=, *=, /=, **=
The comparison operations return a boolean and all other operations return a new units object or modify the units object in place.
>>> u = Units('m')
<CF Units: m>
>>> v = u * 1000
>>> v
<CF Units: 1000 m>
>>> u == v
False
>>> u != v
True
>>> u **= 2
>>> u
<CF Units: m2>
It islso possible to create the logarithm of a unit corresponding to the given logarithmic base:
>>> u = Units('seconds')
>>> u.log(10)
<CF Units: lg(re 1 s)>
Modifying data for equivalent units
Any numpy array or python numeric type may be modified for equivalent units using the conform static method.
>>> Units.conform(2, Units('km'), Units('m'))
2000.0
>>> import numpy
>>> a = numpy.arange(5.0)
>>> Units.conform(a, Units('minute'), Units('second'))
array([ 0., 60., 120., 180., 240.])
>>> a
array([ 0., 1., 2., 3., 4.])
If the inplace keyword is True, then a numpy array is modified in place, without any copying overheads:
>>> Units.conform(a,
Units('days since 2000-12-1'),
Units('days since 2001-1-1'), inplace=True)
array([-31., -30., -29., -28., -27.])
>>> a
array([-31., -30., -29., -28., -27.])
Interface
Parameters: |
|
---|
Methods and attributes defined here:
Stores the calendar for reference time units. May be any string allowed by the calendar attribute in the CF conventions.
Examples:
>>> u = Units()
>>> u.calendar = 'gregorian'
>>> u.calendar
'gregorian'
>>> u = Units(calendar='365_day')
>>> u.calendar
'365_day'
>>> del u.calendar
Conform values in one unit to equivalent values in another, compatible unit. Returns the conformed values.
The values may either be a numpy array or a python numeric type. The returned value is of the same type, except that input integers are converted to floats (see the inplace keyword).
Parameters: |
|
---|---|
Returns: | The modified numeric values. |
Examples:
>>> Units.conform(2, Units('km'), Units('m'))
2000.0
>>> import numpy
>>> a = numpy.arange(5.0)
>>> Units.conform(a, Units('minute'), Units('second'))
array([ 0., 60., 120., 180., 240.])
>>> a
array([ 0., 1., 2., 3., 4.])
>>> Units.conform(a,
Units('days since 2000-12-1'),
Units('days since 2001-1-1'), inplace=True)
array([-31., -30., -29., -28., -27.])
>>> a
array([-31., -30., -29., -28., -27.])
Warning
Do not change the calendar of reference time units in the current version. Whilst this is possible, it will almost certainly result in an incorrect interpretation of the data or an error. Allowing the calendar to be changed is under development and will be available soon.
x.copy() <==> copy.deepcopy(x)
Return True if and only if numeric values in one unit are convertible to numeric values in the other unit and their conversion is a scale factor of 1.
Parameters: | other (Units) – The other units |
---|---|
Returns: | True or False |
Examples:
>>> u = Units(units='km')
>>> v = Units(units='1000m')
>>> u.equals(v)
True
>>> u = Units(units='m s-1')
>>> m = Units(units='m')
>>> s = Units(units='s')
>>> u.equals(m)
False
>>> u.equals(m/s)
True
>>> (m/s).equals(u)
True
Undefined units are considered equal:
>>> u = Units()
>>> v = Units()
>>> u.equals(v)
True
Returns True if and only if numeric values in one unit are convertible to numeric values in the other unit
Parameters: | other (Units) – The other units. |
---|---|
Returns: | True or False |
Examples:
>>> u = Units(units='m')
>>> v = Units(units='km')
>>> w = Units(units='s')
>>> u.equivalent(v)
True
>>> u.equivalent(w)
False
>>> u = Units(units='days since 2000-1-1')
>>> v = Units(units='days since 2000-1-1', calendar='366_day')
>>> w = Units(units='seconds since 1978-3-12')
>>> u.equivalent(v)
False
>>> u.equivalent(w)
True
Formats the string stored in the units attribute in a standardized manner. The units attribute is modified in place and its new value is returned.
Parameters: |
|
---|---|
Returns: | The formatted string. |
Examples:
>>> u = Units(units='W')
>>> u.units
'W'
>>> u.format()
>>> u.units
'W'
>>> u.format(names=True)
>>> u.units
'watt'
>>> u.format(definition=True)
>>> u.units
'm2.kg.s-3'
>>> u.format(names=True, definition=True)
'meter^2-kilogram-second^-3'
>>> u.format()
'W'
>>> u.units='dram'
>>> u.format(names=True)
'1.848345703125e-06 meter^3'
Formatting is also available during object initialization:
>>> u = Units(units='m/s', format=True)
>>> u.units
'm.s-1'
>>> u = Units(units='dram', names=True)
>>> u.units
'1.848345703125e-06 m3'
>>> u = Units(units='W', names=True, definition=True)
>>> u.units
'meter^2-kilogram-second^-3'
True if the units are latitude units, i.e. if the units attribute is ‘degrees_north’, false otherwise.
Examples:
>>> u = Units(units='degrees_north')
>>> u.islatitude
True
>>> u = Units(units='degrees')
>>> u.islatitude
False
>>> u = Units(units='degrees_east')
>>> u.islatitude
False
True if the units are longitude units, i.e. if the units attribute is ‘degrees_east’, false otherwise.
Examples:
>>> u = Units(units='degrees_east')
>>> u.islongitude
True
>>> u = Units(units='degrees')
>>> u.islongitude
False
>>> u = Units(units='degrees_north')
>>> u.islongitude
False
True if the units are pressure units, false otherwise.
Examples:
>>> u = Units(units='bar')
>>> u.ispressure
True
>>> u = Units(units='hours since 2100-1-1', calendar='noleap')
>>> u.ispressure
False
True if the units are reference time units, false otherwise.
Note that time units are not reference time units and that the existence of the calendar attribute on its own is not sufficient for identifying the presence of reference time units.
Examples:
>>> u = Units(units='days since 1989-1-1')
>>> u.isreftime
True
>>> u = Units(units='hours since 2100-1-1', calendar='noleap')
>>> u.isreftime
True
>>> u = Units(units='kg')
>>> u.isreftime
False
>>> u = Units(units='hours')
>>> u.isreftime
False
>>> u = Units(calendar='360_day')
>>> u.isreftime
False
True if the units are time units, false otherwise.
Note that reference time units are not time units.
Returns: | True or False |
---|
Examples:
>>> u = Units(units='days')
>>> u.istime
True
>>> u = Units(units='hours since 2100-1-1', calendar='noleap')
>>> u.istime
False
>>> u = Units(calendar='360_day')
>>> u.istime
False
>>> u = Units(units='kg')
>>> u.istime
False
Returns the logarithmic unit corresponding to the given logarithmic base.
Parameters: | base (int or float) – The logarithmic base. |
---|---|
Returns: | The logarithmic unit corresponding to the given logarithmic base. |
Examples:
>>> u = Units(units='W', names=True)
>>> u
<CF Units: watt>
>>> u.log(10)
<CF Units: lg(re 1 W)>
>>> u.log(2)
<CF Units: lb(re 1 W)>
>>> import math
>>> u.log(math.e)
<CF Units: ln(re 1 W)>
>>> u.log(3.5)
<CF Units: 0.798235600147928 ln(re 1 W)>
Stores the units string. May be any string allowed by the units attribute in the CF conventions.
Examples:
>>> u = Units()
>>> u.units = 'kg'
>>> u.units
'kg'
>>> u = Units(units='percent')
>>> u.units
'percent'
>>> del u.units