Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Code coverage report

# no permissions by default
permissions: {}

on:
pull_request:
push:

jobs:
run:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Setup pixi
uses: prefix-dev/setup-pixi@82d477f15f3a381dbcc8adc1206ce643fe110fb7 # v0.9.3
with:
cache: true

- name: Run tests with coverage
run: >
pixi run --environment testcov test_cov
9 changes: 2 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,14 @@ repos:
- --ignore-words-list=astroid,fo

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.10
rev: v0.15.0
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
- id: ruff-format

- repo: https://github.com/tox-dev/pyproject-fmt
rev: v2.11.1
hooks:
- id: pyproject-fmt

- repo: https://github.com/woodruffw/zizmor-pre-commit
rev: v1.19.0
rev: v1.22.0
hooks:
- id: zizmor

Expand Down
1,328 changes: 1,236 additions & 92 deletions pixi.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ dependencies = [
"cf-xarray",
"cftime",
"dask",
# "dask[complete]", # getting errors from pixi with the "complete"
"netcdf4",
"numpy",
"xarray>=2024.6",
Expand All @@ -51,7 +50,7 @@ optional-dependencies.dev = [
"sphinx-rtd-theme",
]
optional-dependencies.examples = [ "fsspec", "h5netcdf", "matplotlib", "s3fs", "zarr<3" ]
urls."Homepage" = "https://github.com/asascience-open/xarray-subset-grid"
urls."Homepage" = "https://github.com/ioos/xarray-subset-grid/"

[tool.setuptools]
packages = [ "xarray_subset_grid" ]
Expand Down Expand Up @@ -108,6 +107,7 @@ test311 = [ "dev", "py311" ]
test312 = [ "dev", "py312" ]
test313 = [ "dev", "py313" ]
test314 = [ "dev", "py314" ]
testcov = [ "dev", "py314" ]

[tool.pixi.system-requirements]
macos = "11.0"
Expand Down Expand Up @@ -146,6 +146,7 @@ myst-nb = "*"
lint = "ruff check tests xarray_subset_grid"
test = "pytest tests/"
test_all = "pytest --online tests/"
test_cov = "pytest --cov=xarray_subset_grid tests"

[tool.pixi.feature.examples.dependencies]
matplotlib = "*"
Expand Down
31 changes: 17 additions & 14 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,20 @@ def pytest_collection_modifyitems(config, items):
# if item.config.getoption("-E") not in envnames:
# pytest.skip(f"test requires env in {envnames!r}")

EXAMPLE_DATA = Path(__file__).parent / 'example_data'

UGRID_FILES = [EXAMPLE_DATA / 'SFBOFS_subset1.nc',
EXAMPLE_DATA / 'small_ugrid_zero_based.nc',
EXAMPLE_DATA / 'tris_and_bounds.nc',
]

SGRID_FILES = [EXAMPLE_DATA / 'arakawa_c_test_grid.nc',
]

RGRID_FILES = [EXAMPLE_DATA / '2D-rectangular_grid_wind.nc',
EXAMPLE_DATA / 'rectangular_grid_decreasing.nc',
EXAMPLE_DATA / 'AMSEAS-subset.nc',
]
EXAMPLE_DATA = Path(__file__).parent / "example_data"

UGRID_FILES = [
EXAMPLE_DATA / "SFBOFS_subset1.nc",
EXAMPLE_DATA / "small_ugrid_zero_based.nc",
EXAMPLE_DATA / "tris_and_bounds.nc",
]

SGRID_FILES = [
EXAMPLE_DATA / "arakawa_c_test_grid.nc",
]

RGRID_FILES = [
EXAMPLE_DATA / "2D-rectangular_grid_wind.nc",
EXAMPLE_DATA / "rectangular_grid_decreasing.nc",
EXAMPLE_DATA / "AMSEAS-subset.nc",
]
136 changes: 72 additions & 64 deletions tests/test_grids/test_regular_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

# It was created by the "OFS subsetter"


@pytest.mark.parametrize("test_file", RGRID_FILES)
def test_recognize(test_file):
"""
Expand Down Expand Up @@ -77,8 +78,6 @@ def create_synthetic_rectangular_grid_dataset(decreasing=False):
return ds




def test_grid_vars():
"""
Check if the grid vars are defined properly
Expand All @@ -88,7 +87,7 @@ def test_grid_vars():
grid_vars = ds.xsg.grid_vars

# ['mesh', 'nv', 'lon', 'lat', 'lonc', 'latc']
assert grid_vars == {'lat', 'lon'}
assert grid_vars == {"lat", "lon"}


def test_data_vars():
Expand All @@ -106,27 +105,28 @@ def test_data_vars():
# the extra "time" variables are not using the grid
# so they should not be listed as data_vars
assert data_vars == {
'water_w',
'salinity',
'surf_roughness',
'surf_temp_flux',
'water_v',
"water_w",
"salinity",
"surf_roughness",
"surf_temp_flux",
"water_v",
# 'time_offset',
'water_temp',
'water_baro_v',
'surf_atm_press',
'surf_el',
'surf_salt_flux',
'water_u',
'surf_wnd_stress_gridy',
'water_baro_u',
'watdep',
'surf_solar_flux',
"water_temp",
"water_baro_v",
"surf_atm_press",
"surf_el",
"surf_salt_flux",
"water_u",
"surf_wnd_stress_gridy",
"water_baro_u",
"watdep",
"surf_solar_flux",
# 'time1_run',
'surf_wnd_stress_gridx',
"surf_wnd_stress_gridx",
# 'time1_offset'
}


# might not be needed if tested elsewhere.
def test_data_vars2():
"""
Expand All @@ -141,7 +141,7 @@ def test_data_vars2():
data_vars = ds.xsg.data_vars
print(f"data_vars: {data_vars}")

assert data_vars == {'salt', 'temp'}
assert data_vars == {"salt", "temp"}


def test_extra_vars():
Expand All @@ -154,42 +154,43 @@ def test_extra_vars():

# the extra "time" variables are not using the grid
# so they should be listed as extra_vars
assert extra_vars == {
'time_offset',
'time1_run',
'time1_offset'
}
assert extra_vars == {"time_offset", "time1_run", "time1_offset"}


def test_subset_to_bb():
"""
Not a complete test by any means, but the basics are there.

NOTE: it doesn't test if the variables got subset corectly ...
NOTE: it doesn't test if the variables got subset correctly ...

"""
ds = xr.open_dataset(EXAMPLE_DATA / "2D-rectangular_grid_wind.nc")

print("initial bounds:", ds['lon'].data.min(),
ds['lat'].data.min(),
ds['lon'].data.max(),
ds['lat'].data.max(),
)
print(
"initial bounds:",
ds["lon"].data.min(),
ds["lat"].data.min(),
ds["lon"].data.max(),
ds["lat"].data.max(),
)

bbox = (-0.5, 0, 0.5, 0.5)

ds2 = ds.xsg.subset_bbox(bbox)

assert ds2['lat'].size == 15
assert ds2['lon'].size == 29
assert ds2["lat"].size == 15
assert ds2["lon"].size == 29

new_bounds = (ds2['lon'].data.min(),
ds2['lat'].data.min(),
ds2['lon'].data.max(),
ds2['lat'].data.max(),
)
new_bounds = (
ds2["lon"].data.min(),
ds2["lat"].data.min(),
ds2["lon"].data.max(),
ds2["lat"].data.max(),
)
print("new bounds:", new_bounds)
assert new_bounds == bbox


def test_decreasing_latitude():
"""
Some datasets have the latitude or longitude decreasing: 10, 9, 8 etc.
Expand All @@ -200,27 +201,31 @@ def test_decreasing_latitude():
"""
ds = xr.open_dataset(EXAMPLE_DATA / "rectangular_grid_decreasing.nc")

print("initial bounds:", ds['lon'].data.min(),
ds['lat'].data.min(),
ds['lon'].data.max(),
ds['lat'].data.max(),
)
print(
"initial bounds:",
ds["lon"].data.min(),
ds["lat"].data.min(),
ds["lon"].data.max(),
ds["lat"].data.max(),
)

bbox = (-0.5, 0, 0.5, 0.5)

ds2 = ds.xsg.subset_bbox(bbox)

assert ds2['lat'].size == 15
assert ds2['lon'].size == 29
assert ds2["lat"].size == 15
assert ds2["lon"].size == 29

new_bounds = (ds2['lon'].data.min(),
ds2['lat'].data.min(),
ds2['lon'].data.max(),
ds2['lat'].data.max(),
)
new_bounds = (
ds2["lon"].data.min(),
ds2["lat"].data.min(),
ds2["lon"].data.max(),
ds2["lat"].data.max(),
)
print("new bounds:", new_bounds)
assert new_bounds == bbox


def test_decreasing_coords():
"""
Redundant with above, but already written ...
Expand All @@ -239,20 +244,23 @@ def test_decreasing_coords():
assert subset.sizes["lat"] > 0
assert subset.sizes["lon"] > 0


def test_subset_polygon():
"""
Not a complete test by any means, but the basics are there.

NOTE: it doesn't test if the variables got subset corectly ...
NOTE: it doesn't test if the variables got subset correctly ...

"""
ds = xr.open_dataset(EXAMPLE_DATA / "2D-rectangular_grid_wind.nc")

print("initial bounds:", ds['lon'].data.min(),
ds['lat'].data.min(),
ds['lon'].data.max(),
ds['lat'].data.max(),
)
print(
"initial bounds:",
ds["lon"].data.min(),
ds["lat"].data.min(),
ds["lon"].data.max(),
ds["lat"].data.max(),
)

poly = [(-0.5, 0.0), (0.0, 0.5), (0.5, 0.5), (0.5, 0.0), (0, 0.0)]
# this poly has this bounding box:
Expand All @@ -261,19 +269,19 @@ def test_subset_polygon():

ds2 = ds.xsg.subset_polygon(poly)

assert ds2['lat'].size == 15
assert ds2['lon'].size == 29
assert ds2["lat"].size == 15
assert ds2["lon"].size == 29

new_bounds = (ds2['lon'].data.min(),
ds2['lat'].data.min(),
ds2['lon'].data.max(),
ds2['lat'].data.max(),
)
new_bounds = (
ds2["lon"].data.min(),
ds2["lat"].data.min(),
ds2["lon"].data.max(),
ds2["lat"].data.max(),
)
print("new bounds:", new_bounds)
assert new_bounds == (-0.5, 0, 0.5, 0.5)



# def test_vertical_levels():
# ds = xr.open_dataset(EXAMPLE_DATA / "SFBOFS_subset1.nc")
# ds = ugrid.assign_ugrid_topology(ds, **grid_topology)
Expand Down
13 changes: 5 additions & 8 deletions tests/test_grids/test_ugrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

EXAMPLE_DATA = Path(__file__).parent.parent / "example_data"


@pytest.mark.parametrize("test_file", UGRID_FILES[:3])
def test_recognize(test_file):
"""
Expand All @@ -31,14 +32,10 @@ def test_recognize(test_file):
except KeyError: # no mesh variable
# Hacky way to deal with non-conforming examples
# This should be in a config somewhere, or ??
if 'tris' in ds:
grid_top = {'face_node_connectivity': 'tris',
'node_coordinates': ('lon', 'lat')
}
elif 'nv' in ds:
grid_top = {'face_node_connectivity': 'nv',
'node_coordinates': ('lon', 'lat')
}
if "tris" in ds:
grid_top = {"face_node_connectivity": "tris", "node_coordinates": ("lon", "lat")}
elif "nv" in ds:
grid_top = {"face_node_connectivity": "nv", "node_coordinates": ("lon", "lat")}
ds = ugrid.assign_ugrid_topology(ds, **grid_top)

assert UGrid.recognize(ds)
Expand Down
Loading
Loading