Skip to content

Compare units through UDUNITS instead of a parser of our own - #34

Merged
xylar merged 1 commit into
ismip:mainfrom
xylar:units-via-udunits
Sep 17, 2026
Merged

xylar merged 1 commit into
ismip:mainfrom
xylar:units-via-udunits

Conversation

@xylar

@xylar xylar commented Sep 17, 2026

Copy link
Copy Markdown
Member

From https://github.com/orgs/ismip/discussions/46#discussioncomment-18483514: PISM writes kg m^-2 second^-1 and kelvin, and the checker rejects both. Its units parser compares base names literally, so second ≠ s and kelvin ≠ K. An alias table would fix those two and wait for the next (seconds, sec, metre, meters, degK, watts, ...); PISM's strings come from its own UDUNITS, so it can emit any name UDUNITS knows.

CF defines a valid units attribute as "a string that can be recognized by the UDUNITS package," so this PR makes the comparison UDUNITS's own, through cf-units (SciTools' UDUNITS-2 binding). _units_match becomes six lines and the ~90-line parser goes.

Semantics, verified against 3.3.1:

  • Equal means same dimension, same scale, same offset: m yr-1 is still not m s-1, kPa is not Pa, degC is not K, percent is not 1. So the range check's "units attribute that lies" case is unaffected.
  • Every row of the old test_units_match table gives the same answer except kg/(m2 s), which the parser gave up on and UDUNITS understands.
  • A string UDUNITS cannot parse (e.g. M) is now reported as "not one UDUNITS recognizes" rather than as the wrong unit, which would send the modeler looking for a factor.
  • New test: every units string in the shipped data request parses, since a typo there would fail every file of a variable.

Dependency: cf-units >=3.3,<4 (3.3 is the first release built against numpy 2). Added to pyproject.toml, isschecker_env.yml, ci/isschecker_env_floor.yml and the dependency table in the developer docs. It's on conda-forge for linux-64/aarch64, osx-64/arm64 and win-64, with PyPI wheels. At release, the feedstock's run: requirements need cf-units >=3.3,<4 added, as the releasing guide describes for a dependency change.

Bumps the version to 0.5.0 for the new dependency and the changed check; one release covers this and #33.

🤖 Generated with Claude Code

The checker's small units parser compared base names literally, so
'kelvin' was not 'K' and 'second' was not 's', and PISM's files, whose
units strings come from its own UDUNITS, failed on both (discussion
ismip#46).  An alias table would fix those two and wait for the next:
seconds, sec, metre, meters, degK, watts.

CF says a units attribute must be "a string that can be recognized by
the UDUNITS package", so the comparison is now UDUNITS's own, through
cf-units.  Equal means the same dimension at the same scale with the
same offset, so 'm yr-1' is still not 'm s-1', 'kPa' is not 'Pa' and
'degC' is not 'K'; and a string UDUNITS cannot parse is reported as
such rather than as the wrong unit.  Every row of the old test table
gives the same answer, except 'kg/(m2 s)', which the parser gave up on
and UDUNITS understands.  A test checks that the request's own units
strings all parse, since a typo there would fail every file of a
variable.

cf-units >=3.3 is the floor: the first release built against numpy 2.
It goes into pyproject.toml, both environment files and the dependency
table, and needs adding to the feedstock recipe at release.

Bump the version to 0.5.0 for the new dependency and the changed check.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@xylar
xylar marked this pull request as ready for review September 17, 2026 16:04
@xylar
xylar merged commit f29072d into ismip:main Sep 17, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant