Skip to content

Commit

Permalink
Update for latest version of gimli.units (#169)
Browse files Browse the repository at this point in the history
* Remove duplicate install of testing dependencies

* Require latest version of model_metadata

* Remove obsolete esmpy requirement

* Don't install components for testing

The subsequent call to `mamba install` updates *shapely* to 2.0,
which breaks the <1.9 requirement from #164.

* import UnitSystem from gimli.units

* remove redundant gimli.units unit tests

* checkout gimli.units raises UdunitsError

* Consolidate requirements in one install step

* Fix typos

* Roll back model_metadata for older models

---------

Co-authored-by: mcflugen <[email protected]>
  • Loading branch information
mdpiper and mcflugen authored Oct 10, 2024
1 parent 485211b commit 78cfd16
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 236 deletions.
10 changes: 4 additions & 6 deletions .github/workflows/test-notebooks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,16 @@ jobs:
- name: Install requirements
run: |
mamba install --file=requirements.txt
mamba install \
--file=requirements.txt \
--file=requirements-testing.txt \
--file=requirements-notebooks.txt
mamba list
- name: Build and install package
run: |
pip install -e .
- name: Install testing dependencies
run: |
mamba install --file=requirements-testing.txt
mamba install --file=requirements-notebooks.txt
- name: Test jupyter notebooks
timeout-minutes: 30
run: |
Expand Down
20 changes: 8 additions & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,20 @@ jobs:
mamba install --file=requirements.txt --file=requirements-testing.txt
mamba list
- name: Install Windows requirements
if: matrix.os == 'windows-latest'
run: |
mamba install pymt_child pymt_hydrotrend pymt_permamodel
# - name: Install Windows requirements
# if: matrix.os == 'windows-latest'
# run: |
# mamba install pymt_child pymt_hydrotrend pymt_permamodel

- name: Install Unix requirements
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
run: |
mamba install esmpy
mamba install pymt_cem pymt_child pymt_hydrotrend pymt_permamodel
# - name: Install Unix requirements
# if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
# run: |
# mamba install pymt_cem pymt_child pymt_hydrotrend pymt_permamodel

- name: Build and install package
run: |
pip install -e .
- name: Install testing dependencies
run: mamba install --file=requirements-testing.txt

- name: Test
run: |
python -c 'import pymt; print(pymt.__version__)'
Expand Down
2 changes: 1 addition & 1 deletion pymt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from gimli import UnitSystem
from gimli.units import UnitSystem

from ._version import __version__
from .model_collection import ModelCollection
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ gimli.units>=0.3.2
jinja2
landlab>=2
matplotlib
model_metadata>=0.7
model_metadata<0.8
netcdf4
pyyaml
scipy<1.9 # see #162
Expand Down
6 changes: 3 additions & 3 deletions tests/framework/test_bmi_var_units.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
import pytest
from gimli import IncompatibleUnitsError, UnitNameError
from gimli._udunits2 import UdunitsError
from numpy.testing import assert_array_equal

from pymt.framework.bmi_bridge import BmiTimeInterpolator, GridMapperMixIn, _BmiCap
Expand Down Expand Up @@ -64,12 +64,12 @@ def test_unit_conversion():
def test_incompatible_units():
"""Test wrapping BMI time methods."""
bmi = Bmi()
with pytest.raises(IncompatibleUnitsError):
with pytest.raises(UdunitsError):
bmi.get_value("elevation", units="kg")


def test_bad_units():
"""Test wrapping BMI time methods."""
bmi = Bmi()
with pytest.raises(UnitNameError):
with pytest.raises(UdunitsError):
bmi.get_value("elevation", units="not_real_units")
213 changes: 0 additions & 213 deletions tests/test_units.py
Original file line number Diff line number Diff line change
@@ -1,222 +1,9 @@
import os
import random

import numpy as np
import pytest
from gimli import IncompatibleUnitsError, UnitFormatting, UnitNameError, UnitStatus

from pymt import UnitSystem
from pymt.units import transform_azimuth_to_math, transform_math_to_azimuth


@pytest.fixture
def system():
os.environ.pop("UDUNITS2_XML_PATH", None)
return UnitSystem()


def test_get_xml():
os.environ.pop("UDUNITS2_XML_PATH", None)
path, status = UnitSystem.get_xml_path()
assert path.is_file()
assert status == UnitStatus.OPEN_DEFAULT

path, status = UnitSystem.get_xml_path(path)
assert path.is_file()
assert status == UnitStatus.OPEN_ARG

os.environ["UDUNITS2_XML_PATH"] = str(path)
path, status = UnitSystem.get_xml_path()
assert path.is_file()
assert status == UnitStatus.OPEN_ENV


def test_default_system():
os.environ.pop("UDUNITS2_XML_PATH", None)
system = UnitSystem()
assert system.status == "default"
assert system.database.is_file()


def test_user_system():
path = UnitSystem().database
system = UnitSystem(path)
assert system.status == "user"
assert system.database.is_file()
assert system == UnitSystem()
assert UnitSystem(path) == UnitSystem(str(path))


def test_env_system(system):
os.environ["UDUNITS2_XML_PATH"] = str(system.database)
env_system = UnitSystem()

assert env_system.status == "env"
assert env_system.database.is_file()
assert str(env_system) == str(system)
assert env_system.database.samefile(system.database)
assert env_system == system


def test_system_dimensionless(system):
assert system.dimensionless_unit() == system.Unit("1")
assert str(system.dimensionless_unit()) == "1"


def test_system_unit_by_name(system):
assert system.unit_by_name("meter") == system.Unit("m")
assert system.unit_by_name("meters") == system.Unit("m")
assert system.unit_by_name("m") is None
assert system.unit_by_name("meter2") is None
assert system.unit_by_name("not_a_name") is None


def test_system_unit_by_symbol(system):
assert system.unit_by_symbol("m") == system.Unit("m")
assert system.unit_by_symbol("km") is None
assert system.unit_by_symbol("meter") is None
assert system.unit_by_symbol("m s-2") is None
assert system.unit_by_symbol("not_a_symbol") is None


def test_unit_formatting(system):
unit = system.Unit("0.1 lg(re m/(5 s)^2) @ 50")
assert (
unit.format(encoding="ascii", formatting=UnitFormatting.NAMES)
== "0.1 lg(re 0.04 meter-second^-2) from 50"
)
assert (
unit.format(encoding="ascii", formatting=UnitFormatting.DEFINITIONS)
== "0.1 lg(re 0.04 m.s-2) @ 50"
)

assert (
unit.format(encoding="iso-8859-1", formatting=UnitFormatting.NAMES)
== "0.1 lg(re 0.04 meter/second²) from 50"
)
assert (
unit.format(encoding="iso-8859-1", formatting=UnitFormatting.DEFINITIONS)
== "0.1 lg(re 0.04 m/s²) @ 50"
)

assert (
unit.format(encoding="latin-1", formatting=UnitFormatting.NAMES)
== "0.1 lg(re 0.04 meter/second²) from 50"
)
assert (
unit.format(encoding="latin-1", formatting=UnitFormatting.DEFINITIONS)
== "0.1 lg(re 0.04 m/s²) @ 50"
)

assert (
unit.format(encoding="utf-8", formatting=UnitFormatting.NAMES)
== "0.1 lg(re 0.04 meter·second⁻²) from 50"
)
assert (
unit.format(encoding="utf-8", formatting=UnitFormatting.DEFINITIONS)
== "0.1 lg(re 0.04 m·s⁻²) @ 50"
)


@pytest.mark.parametrize(
("lhs", "cmp_", "rhs"),
[
("m", "lt", "km"),
("m", "le", "km"),
("m", "le", "m"),
("m", "eq", "m"),
("m", "ne", "km"),
("km", "ge", "m"),
("km", "ge", "km"),
("km", "gt", "m"),
],
)
def test_unit_comparisons(system, lhs, cmp_, rhs):
compare = getattr(system.Unit(lhs), f"__{cmp_}__")
assert compare(system.Unit(rhs))
with pytest.raises(TypeError):
compare(rhs)


def test_unit_symbol(system):
meters = system.Unit("m")
assert meters.symbol == "m"

km = system.Unit("km")
assert km.symbol is None


def test_unit_name(system):
meters = system.Unit("m")
assert meters.name == "meter"

km = system.Unit("km")
assert km.name is None


def test_unit_is_dimensionless(system):
assert not system.Unit("m").is_dimensionless
assert system.Unit("1").is_dimensionless
assert system.Unit("rad").is_dimensionless


def test_unit_is_convertible(system):
assert system.Unit("m").is_convertible_to(system.Unit("km"))
assert not system.Unit("m").is_convertible_to(system.Unit("kg"))

with pytest.raises(TypeError):
system.Unit("m").is_convertible_to("km")


def test_unit_converter_length(system):
meters = system.Unit("m")
km = system.Unit("km")

assert meters.to(km)(1.0) == pytest.approx(1e-3)
with pytest.raises(TypeError):
meters.to("km")

m_to_km = meters.to(km)
assert m_to_km(1.0) == pytest.approx(1e-3)


def test_unit_converter_time(system):
hours = system.Unit("h")
seconds = system.Unit("s")
hours_to_seconds = hours.to(seconds)
assert hours_to_seconds(1.0) == pytest.approx(3600.0)

with pytest.raises(TypeError):
hours.to("s")


def test_unit_converter_same_units(system):
hours = system.Unit("h")
hours_to_hours = hours.to(system.Unit("h"))
assert hours_to_hours(1.0) == pytest.approx(1.0)


@pytest.mark.parametrize(
("to_", "from_"),
[("not_a_unit", "m"), ("m", "not_a_unit"), ("not_a_unit", "not_a_unit")],
)
def test_unit_converter_bad_from_units(system, to_, from_):
with pytest.raises(UnitNameError):
system.Unit(from_).to(system.Unit(to_))


def test_unit_converter_incompatible_units(system):
with pytest.raises(IncompatibleUnitsError):
system.Unit("s").to(system.Unit("m"))


def test_unit_converter_inverse(system):
val = random.random()
seconds_to_hours = system.Unit("s").to(system.Unit("h"))
hours_to_seconds = system.Unit("h").to(system.Unit("s"))
assert hours_to_seconds(seconds_to_hours(val)) == pytest.approx(val)


def test_math_to_azimuth():
angle = transform_math_to_azimuth(np.pi * 0.5, "rad")
assert angle == pytest.approx(0.0)
Expand Down

0 comments on commit 78cfd16

Please sign in to comment.