Skip to main content

CF-compliant unit registry and formatter for Pint

Project description

pint-cf

This package extends Pint with a CF-compliant unit registry and formatter.

Features

  • A CF-compliant Pint UnitRegistry, understanding UDUNITS-2 unit strings.
  • A cf format for Unit/Quantity, to write results back out as CF strings.
  • CFContext, to correctly read CF's units_metadata temperature attribute.
  • CF units that UDUNITS-2 itself doesn't define (level, psu, decibel, sverdrup's Sv symbol, ...), included by default.

Known limitations:

  • No support for time coordinates (e.g. days since 2001-01-01) or climate calendars (e.g. 360_day). Use cftime for those instead.
  • decibel/bel are treated as plain dimensionless ratio units, matching cfunits/cf-units - CF's own reference level for a dB value depends on the variable's standard_name, but neither of those reference packages resolves it either, so pint-cf follows the same convention rather than the letter of the spec.

Installation

Install via pip:

pip install pint-cf

Usage

Create a CF-ready unit registry with cf_unitregistry(). This also registers the cf format.

from pint_cf import cf_unitregistry

ureg = cf_unitregistry()

q = ureg('10 meters per second^2').to('km s-2')

print(f"{q:cf}")   # 0.01 kilometer-second^-2
print(f"{q:~cf}")  # 0.01 km/s2

Temperature units_metadata

CF distinguishes an on-scale temperature (e.g. today's temperature) from a temperature difference (e.g. an anomaly) with a units_metadata attribute - the plain units string alone can't tell them apart.

When reading a variable that has this attribute, wrap the value in CFContext:

from pint_cf import cf_unitregistry, CFContext

ureg = cf_unitregistry()

with CFContext(units_metadata="temperature: difference"):
    q = ureg.Quantity(1, "degree_C")

print(q.units)  # delta_degree_Celsius

Without CFContext (or with units_metadata absent), nothing changes - an on-scale temperature is read as usual.

When writing a result back out, cf_attributes_for does the reverse: it derives the units_metadata attribute from an already-computed Unit or Quantity, ready to merge into a NetCDF variable's attributes:

from pint_cf import cf_attributes_for

print(cf_attributes_for(q))                   # {"units_metadata": "temperature: difference"}
print(cf_attributes_for(ureg.Unit("meter")))  # {} - not a temperature unit

ds[name].attrs.update(cf_attributes_for(q.units))

This round-trips exactly for Celsius and Fahrenheit. Kelvin and Rankine have no zero-offset, so on-scale and difference look identical for them - cf_attributes_for reports "temperature: unknown" rather than guessing.

CF units not in UDUNITS-2

CF defines a few units that UDUNITS-2 doesn't (details), sourced from cfunits. cf_unitregistry() includes them by default:

Unit Behavior
level, sigma_level, layer Dimensionless; kept only for legacy COARDS files, so using one raises a DeprecationWarning.
practical_salinity_unit / psu 1e-3, not 1 (CF's own FAQ is out of date here).
decibel / dB, bel Plain dimensionless ratio units (see "Known limitations" above).
sverdrup / Sv Sv now means sverdrup (ocean volume transport), not sievert - sievert itself still works by its full name.

Pass cf_extensions=False to cf_unitregistry() for a registry that matches plain UDUNITS-2 instead, without any of these additions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pint_cf-0.2.0.tar.gz (42.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pint_cf-0.2.0-py3-none-any.whl (36.2 kB view details)

Uploaded Python 3

File details

Details for the file pint_cf-0.2.0.tar.gz.

File metadata

  • Download URL: pint_cf-0.2.0.tar.gz
  • Upload date:
  • Size: 42.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pint_cf-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7d3b193ee3d51edef277c56a94b8eb4b5d191da6bcd0eee64053550f1e5ddd93
MD5 95e70aa12f43c5c111af3bf1b2a07c29
BLAKE2b-256 1a0a21a5cca909f31ec69938351f8df1d86237543c2f2aef56398fc93b534585

See more details on using hashes here.

Provenance

The following attestation bundles were made for pint_cf-0.2.0.tar.gz:

Publisher: python-publish.yml on pgamez/pint-cf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pint_cf-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pint_cf-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 36.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pint_cf-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9862be60c3ffdd0a90c646c54ee1e2c43171ed0f15dbd79704fdfc8f48213f4a
MD5 e95a92f9786cebe6b1e1994a1b0b3510
BLAKE2b-256 d0c2de419e59896c1648af1586e474c502b3cf06289a89ec75381d1c3e627bb8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pint_cf-0.2.0-py3-none-any.whl:

Publisher: python-publish.yml on pgamez/pint-cf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page