cf.Units

class cf.Units(units=None, calendar=None, format=None, names=None, definition=None, _ut_unit=None)

Bases: object

Store, combine and compare physical units.

Units are as defined in UNIDATA’s Udunits package, with the exceptions given by the CF conventions.

Parameters:
  • units (str) – Optional. Set the new units from this string.
  • calendar (str) – Optional. Set the reference time units’ calendar.
  • format (bool) – Optional. Format the string representation of the unit in a standardized manner. See the format method.
  • names (bool) – Optional. Format the string representation of the units using names instead of symbols. See the format method.
  • definition (bool) – Optional. Format the string representation of the units using basic units. See the format method.

Units may be set, retrieved and deleted via the units attribute. Its value is a string that can be recognized by UNIDATA’s Udunits package, with the few exceptions given in the CF conventions.

>>> u = cf.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 = cf.Units('m/s')
>>> v = cf.Units('m s-1')
>>> w = cf.Units('km.s-1')
>>> x = cf.Units('0.001 kilometer.second-1')
>>> y = cf.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 = cf.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 = cf.Units('days since 2000-1-1')
>>> u.calendar
AttributeError: Can't get 'Units' attribute 'calendar'
>>> v = cf.Units('days since 2000-1-1')
>>> v.calendar = 'gregorian'
>>> v.equals(u)
True

Changing the calendar

Warning

Do not change the calendar of reference time units. Whilst this is possible, it will almost certainly result in an incorrect interpretation of the data array or an error. Allowing the calendar to be changed is under development and will be available soon.

Allowed non-Udunits units

Although deprecated in the CF conventions, the units level, layer, and sigma_level are still allowed, typically for dimensionless vertical coordinates, and are internally equivalent to setting dimensionless units of 1.

>>> u.units
'level'
>>> v.units
'1'
>>> u.equals(v)
True

Modiying data for equivalent units

Any scalar number or numpy array may be modified for equivalent units using the conform static method.

>>> cf.Units.conform(2, cf.Units('km'), cf.Units('m'))
2000.0
>>> a = numpy.arange(5.0)
>>> cf.Units.conform(a, cf.Units('minute'), cf.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:

>>> cf.Units.conform(a,
                     cf.Units('days since 2000-12-1'),
                     cf.Units('days since 2001-1-1'), inplace=True)
array([-31., -30., -29., -28., -27.])
>>> a
array([-31., -30., -29., -28., -27.])

Store units and support arithmetic manipulation of units and conversion of values between compatible scales of measurement.

Parameters:**kwargs

The ‘units’ and ‘calendar’ attributes may be set with keyword parameters.

Methods and attributes defined here:

calendar

Stores the calendar for reference time units. May be any string allowed by the ‘calendar’ attribute in the CF conventions.

Examples:

>>> u = cf.Units()
>>> u.calendar = 'gregorian'
>>> u.calendar
'gregorian'
>>> u = cf.Units(calendar='365_day')
>>> u.calendar
'365_day'
>>> del u.calendar
change_reftime_units(units)
static conform(x, x_units, to_units, inplace=False)
equals(other, rtol=None, atol=None)

Return True if two units are identical

  1. Equal units attributes (if set)
  2. Equal calendar attributes (if set)

Equality of numbers is to within a tolerance. Refer to cf for details.

Parameters:
  • other (object) – The variable to compare against for equality.
  • atol (None or float) – Optional. If None then use the default method for setting the absolute tolerance for equality of real numbers (refer to cf for details). If a float then set the absolute tolerance to this value for all comparisons (refer to the override parameter).
  • rtol (None or float) – Optional. If None then use the default method for setting the relative tolerance for equality of real numbers (refer to cf for details). If a float then set the relative tolerance to this value for all comparisons (refer to the override parameter).
Returns:

True if the two objects are congruent, False otherwise.

Examples:

>>> u = cf.Units(units='km')
>>> v = cf.Units(units='1000m')
>>> u.equals(v)
True
>>> u = cf.Units(units='m s-1')
>>> m = cf.Units(units='m')
>>> s = cf.Units(units='s')
>>> u.equals(m)
False
>>> u.equals(m/s)
True
>>> (m/s).equals(u)
True
equivalent(other, x=None)

Returns True if it is possible to convert the units to the other units and False otherwise.

Parameters:other (Units) – The other units.
Returns:True or False

Examples:

>>> u = cf.Units(units='m')
>>> v = cf.Units(units='km')
>>> w = cf.Units(units='s')
>>> u.equivalent(v)
True
>>> u.equivalent(w)
False
>>> u = cf.Units(units='days since 2000-1-1')
>>> v = cf.Units(units='days since 2000-1-1', calendar='366_day')
>>> w = cf.Units(units='seconds since 1978-3-12')
>>> u.equivalent(v)
False
>>> u.equivalent(w)
True
format(names=None, definition=None)

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:
  • names (bool) – Optional. Use unit names instead of symbols.
  • definition (bool) – Optional. The formatted string is given in terms of basic-units instead of stopping any expansion at the highest level possible.
Returns:

The formatted string.

Examples:

>>> u = cf.Units(units='W')
>>> u.units
'W'
>>> u.format()
>>> u.units
'W'
>>> u.format(names=1)
>>> u.units
'watt'
>>> u.format(definition=1)
>>> u.units
'm2.kg.s-3'
>>> u.format(names=1, definition=1)
'meter^2-kilogram-second^-3'
>>> u.format()
'W'
>>> u.units='dram'
In [14]: a.Units.format(names=1)
Out[14]: '1.848345703125e-06 meter^3'

Formatting is also available during object initialization:

>>> u = cf.Units(units='m/s', format=1)
>>> u.units
'm.s-1'
>>> u = cf.Units(units='dram', names=1)
>>> u.units
'1.848345703125e-06 m3'
>>> u = cf.Units(units='W', names=1, definition=1)
>>> u.units
'meter^2-kilogram-second^-3'
free()

Frees resources associated with the UDUNITS-2 C API.

isreftime

True if and only if the units are reference time units. Note that the calendar attribute on its own is not sufficient for identifying the presence of time units.

Examples:

>>> u = cf.Units(units='days since 1989-1-1')
>>> u.isreftime
True
>>> u = cf.Units(units='hours since 2100-1-1', calendar='noleap')
>>> u.isreftime
True
>>> u = cf.Units(units='kg')
>>> u.isreftime
False
>>> u = cf.Units(calendar='360_day')
>>> u.isreftime
False
istime

True if and only if the units are time units. Note that the calendar attribute on its own is not sufficient for identifying the presence of time units.

Examples:

>>> u = cf.Units(units='days since 1989-1-1')
>>> u.istime
True
>>> u = cf.Units(units='hours since 2100-1-1', calendar='noleap')
>>> u.istime
True
>>> u = cf.Units(units='kg')
>>> u.istime
False
>>> u = cf.Units(calendar='360_day')
>>> u.istime
False
log(base)

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 = cf.Units(units='W', names=1)
>>> 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)>
units

Stores the units string. May be any string allowed by the ‘units’ attribute in the CF conventions.

Examples:

>>> u = cf.Units()
>>> u.units = 'kg'
>>> u.units
'kg'
>>> u = cf.Units(units='percent')
>>> u.units
'percent'
>>> del u.units

Previous topic

cf.CellMethods

Next topic

cf.Data

This Page