Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Reason given by maintainers: Non-maintainer uploaded package to pypi without coordinating with maintainers, pypi package ownership was transferred amicably to maintainers. Pypi releases of openforcefield software may be available from this org at a later date, but issues with unavailable dependencies need to be resolved first. Non-maintainers also have our blessing to create unofficial pypi pacakges of openff software under different package names.

openff-units

CI Status codecov pre-commit pre-commit.ci status conda

A common units module for the OpenFF software stack

Please note that there may still be some changes to the API prior to a stable 1.0.0 release.

This package provides a common unit registry for all OpenFF packages to use in order to ensure consistent unit definitions across the software ecosystem.

The unit definitions are currently sourced from the NIST 2018 CODATA, but may be updated in future versions as new CODATA updates are made.

While this repository is based on Pint, the main classes (Unit, Quantity, and Measurement) have been slightly modified in order to provide non-dynamic, more readily serialisable representations.

Installation

Install via mamba or a replacement:

mamba install openff-units -c conda-forge

Developer installation

Clone, install dev dependencies via Conda into a new environment, and finally install in editable mode with Pip:

git clone https://github.com/openforcefield/openff-units.git
cd openff-units
conda create -n openff-units-dev -f devtools/conda-envs/test_env.yaml
conda run -n openff-units-dev pip install --no-deps -e .

The important detail, as of December 2025, is the --no-deps argument.

Getting Started

Below shows how to tag a number with a unit (generating a Quantity object), get its magnitude with and without units, convert to another unit, and also get its magnitude after converting to another unit.

>>> from openff.units import Quantity
>>> bond_length = Quantity(1.4, "angstrom")
>>> bond_length
<Quantity(1.4, 'angstrom')>
>>> bond_length.magnitude
1.4
>>> bond_length.to("nanometer")
<Quantity(0.14, 'nanometer')>
>>> bond_length.m_as("nanometer")
0.14

One could also do the Pint tutorial using the unit object above as a drop-in replacement for ureg in the tutorial.

Serialization

Scalar quantities can be serialized to strings using the built-in str() function and deserialized using the unit.Quantity constructor.

>>> k = Quantity(10, "kilocalorie / mol / nanometer**2")
>>> k
<Quantity(10.0, 'kilocalorie / mole / nanometer ** 2')>
>>> str(k)
'10.0 kcal / mol / nm ** 2'
>>> Quantity(str(k))
<Quantity(10.0, 'kilocalorie / mole / nanometer ** 2')>

OpenMM Interoperability

For compatibility with OpenMM units, a submodule (openff.units.openmm) with conversion functions (to_openmm, from_openmm) is also provided.

>>> from openff.units import Quantity
>>> from openff.units.openmm import to_openmm, from_openmm
>>> distance = Quantity(24.0, "meter")
>>> converted = to_openmm(distance)
>>> converted
24.0 m
>>> type(converted)
<class 'openmm.unit.quantity.Quantity'>
>>> roundtripped = from_openmm(converted)
>>> roundtripped
<Quantity(24.0, 'meter')>
>>> type(roundtripped)
pint.Quantity

An effort is made to convert from OpenMM constructs, such as when OpenMM provides array-like data as a list of Vec3 objects:into Pint's wrapped NumPy arrays:

>>> from openmm import app
>>> positions = app.PDBFile("top.pdb").getPositions()
>>> positions
Quantity(value=[Vec3(x=-0.07890000000000001, y=-0.0198, z=-0.0), Vec3(x=-0.0006000000000000001, y=0.039200000000000006, z=-0.0), Vec3(x=0.07950000000000002, y=-0.0194, z=0.0), Vec3(x=0.9211, y=0.9802, z=1.0), Vec3(x=0.9994000000000001, y=1.0392, z=1.0), Vec3(x=1.0795000000000001, y=0.9805999999999999, z=1.0)], unit=nanometer)
>>> type(positions)
<class 'openmm.unit.quantity.Quantity'>
>>> type(positions._value)
<class 'list'>
>>> type(positions._value[0])
<class 'openmm.vec3.Vec3'>
>>> converted = from_openmm(positions)
>>> converted
<Quantity([[-7.8900e-02 -1.9800e-02 -0.0000e+00]
 [-6.0000e-04  3.9200e-02 -0.0000e+00]
 [ 7.9500e-02 -1.9400e-02  0.0000e+00]
 [ 9.2110e-01  9.8020e-01  1.0000e+00]
 [ 9.9940e-01  1.0392e+00  1.0000e+00]
 [ 1.0795e+00  9.8060e-01  1.0000e+00]], 'nanometer')>
>>> converted.m
array([[-7.8900e-02, -1.9800e-02, -0.0000e+00],
       [-6.0000e-04,  3.9200e-02, -0.0000e+00],
       [ 7.9500e-02, -1.9400e-02,  0.0000e+00],
       [ 9.2110e-01,  9.8020e-01,  1.0000e+00],
       [ 9.9940e-01,  1.0392e+00,  1.0000e+00],
       [ 1.0795e+00,  9.8060e-01,  1.0000e+00]])
>>> type(converted)
<class 'openff.units.units.Quantity'>
>>> type(converted.m)
<class 'numpy.ndarray'>

Dealing with multiple unit packages

You may find yourself needing to normalize a quantity to a particular unit package, while accepting inputs from either openff.units or openmm.unit. The ensure_quantity function simplifies this. It takes as arguments a quantity object from either unit solution and a string ("openff" or "openmm") indicating the desired unit type, and returns a quantity from that package. If the quantity argument is already the requested type, the function short-circuits, so it should not introduce substantial overhead compared to simply requiring the target quantity type.

>>> from openff.units import Quantity, ensure_quantity
>>> ensure_quantity(Quantity(4.0, "angstrom"), "openff")
<Quantity(4.0, 'angstrom')>  # OpenFF
>>> ensure_quantity(Quantity(4.0, "angstrom"), "openmm")
4.0 A
>>>
>>> import openmm.unit
>>> ensure_quantity(openmm.unit.Quantity(4.0, openmm.unit.angstrom), "openmm")
4.0 A
>>> ensure_quantity(openmm.unit.Quantity(4.0, openmm.unit.angstrom), "openff")
<Quantity(4.0, 'angstrom')>  # OpenFF

Known issues

There is a quirk with cached unit registry definitions that could cause issues when running tests in parallel (i.e. with pytest-xdist). See Issue #111 for more details. This was fixed in version 0.3.1.

Copyright (c) 2021, Open Force Field Initiative

Acknowledgements

Project based on the Computational Molecular Science Python Cookiecutter version 1.5.

Metadata

Release files for openff-units 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openff-units 0.3.2
File Size Uploaded
openff_units-0.3.2.tar.gz 33.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for openff-units 0.3.2
File Interpreter ABI Platform
openff_units-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 53.7 kB

Release files / openff_units-0.3.2.tar.gz

Download URL openff_units-0.3.2.tar.gz
Size 33.3 kB
Tags Source
SHA-256 checksum
How to use checksums
73c76e2d97216abd8a154ac1614a6316e34ef8eb04f8cf726b4028981a0f96e8
BLAKE2b-256 checksum
How to use checksums
74e8b2fd3c1d8dd17ede393c5f51689823d50e87260c4773fe7d24315f59791f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.13

Release files / openff_units-0.3.2-py3-none-any.whl

Download URL openff_units-0.3.2-py3-none-any.whl
Size 20.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
af9286e7edff89f91bb8f5537f7955cc205516554b2576ac4b010ca2f4926a07
BLAKE2b-256 checksum
How to use checksums
6e57fdc498716cc3a18a8cf15955d9900955171766e4303e2c936e3ee2ba688d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.13

Release history Release notifications | RSS feed

This release

0.3.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page