From 2b2527e1f73d0f8eb6ae0558ffffa68befd784d4 Mon Sep 17 00:00:00 2001 From: Kevin Schwarzwald Date: Tue, 13 Feb 2024 17:34:35 -0500 Subject: [PATCH] add new python versions for tests, fix optional dependencies --- ci/environment-noxesmf.yml | 22 ++++++++ ci/environment-py3.11.yml | 25 +++++++++ ci/environment-py3.12.yml | 25 +++++++++ ...onment-py3.8.yml => environment-py3.9.yml} | 2 +- setup.py | 7 +++ tests/test_core.py | 54 ++++++++++--------- xagg/core.py | 9 ++-- 7 files changed, 116 insertions(+), 28 deletions(-) create mode 100644 ci/environment-noxesmf.yml create mode 100644 ci/environment-py3.11.yml create mode 100644 ci/environment-py3.12.yml rename ci/{environment-py3.8.yml => environment-py3.9.yml} (97%) diff --git a/ci/environment-noxesmf.yml b/ci/environment-noxesmf.yml new file mode 100644 index 0000000..0ad44c2 --- /dev/null +++ b/ci/environment-noxesmf.yml @@ -0,0 +1,22 @@ +name: test_env_xagg_noxe +channels: + - conda-forge +dependencies: + - python=3.12 + ############## Without xesmf / esmpy / esmf explicitly installed, to check optional dependency + - numpy + - scipy + - xarray + - pandas + - netcdf4 + - geopandas >= 0.12.0 + - shapely + - cf_xarray >= 0.5.1 + - pytables + ############## + - pytest + - pip: + - codecov + - pytest-cov + - coverage[toml] + # - tables >= 3.7.0 # For exporting hd5 files through wm.to_file() (3.6.0 may have issues) diff --git a/ci/environment-py3.11.yml b/ci/environment-py3.11.yml new file mode 100644 index 0000000..252817c --- /dev/null +++ b/ci/environment-py3.11.yml @@ -0,0 +1,25 @@ +name: test_env_xagg_38 +channels: + - conda-forge +dependencies: + - python=3.11 + ############## These will have to be adjusted to your specific project + - numpy + - scipy + - xarray + - pandas + - netcdf4 + - geopandas >= 0.12.0 + - shapely + - xesmf >= 0.7.0 # These versions and explicit loads are to fix an issue in xesmf's call to cf_xarray (possibly through esmpy) + - cf_xarray >= 0.5.1 + - esmf >= 8.1.0 + - esmpy >= 8.1.0 + - pytables + ############## + - pytest + - pip: + - codecov + - pytest-cov + - coverage[toml] + # - tables >= 3.7.0 # For exporting hd5 files through wm.to_file() (3.6.0 may have issues) diff --git a/ci/environment-py3.12.yml b/ci/environment-py3.12.yml new file mode 100644 index 0000000..94c272d --- /dev/null +++ b/ci/environment-py3.12.yml @@ -0,0 +1,25 @@ +name: test_env_xagg_38 +channels: + - conda-forge +dependencies: + - python=3.12 + ############## These will have to be adjusted to your specific project + - numpy + - scipy + - xarray + - pandas + - netcdf4 + - geopandas >= 0.12.0 + - shapely + - xesmf >= 0.7.0 # These versions and explicit loads are to fix an issue in xesmf's call to cf_xarray (possibly through esmpy) + - cf_xarray >= 0.5.1 + - esmf >= 8.1.0 + - esmpy >= 8.1.0 + - pytables + ############## + - pytest + - pip: + - codecov + - pytest-cov + - coverage[toml] + # - tables >= 3.7.0 # For exporting hd5 files through wm.to_file() (3.6.0 may have issues) diff --git a/ci/environment-py3.8.yml b/ci/environment-py3.9.yml similarity index 97% rename from ci/environment-py3.8.yml rename to ci/environment-py3.9.yml index 880980a..1968ed8 100644 --- a/ci/environment-py3.8.yml +++ b/ci/environment-py3.9.yml @@ -2,7 +2,7 @@ name: test_env_xagg_38 channels: - conda-forge dependencies: - - python=3.8 + - python=3.9 ############## These will have to be adjusted to your specific project - numpy - scipy diff --git a/setup.py b/setup.py index 65d5d3a..9de00be 100644 --- a/setup.py +++ b/setup.py @@ -31,4 +31,11 @@ 'tables', 'cf_xarray>=0.5.1', ], + extras_require=[ + 'xesmf>=0.7.1', + 'esmpy>=8.1.0', + 'matplotlib', + 'cmocean', + 'cartopy', + ] ) diff --git a/tests/test_core.py b/tests/test_core.py index c05ed21..b9418d3 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -6,7 +6,12 @@ from geopandas import testing as gpdt from unittest import TestCase from shapely.geometry import Polygon -import xesmf as xe +try: + import xesmf as xe + _has_xesmf=True +except ImportError: + # To be able to test the rest with environments without xesmf + _has_xesmf=False from xagg.core import (process_weights,create_raster_polygons,get_pixel_overlaps,aggregate,NoOverlapError) @@ -46,32 +51,33 @@ def test_process_weights_basic(): xr.testing.assert_allclose(ds_compare,ds_t) # (weights_info isn't currently used by anything) -def test_process_weights_regrid_weights(): - # Now, test with a weights array twice the resolution as the - # ds, so it needs to be regridded - ds = xr.Dataset(coords={'lat':(['lat'],np.array([0,1])), - 'lon':(['lon'],np.array([0,1])), - }) - - # Synthetic weights grid, with double the resolution, and shifted - # by a half degree. Should regrid to the same weights grid as above - weights = xr.DataArray(data=np.array([[-0.5,0.5,0.5,1.5], - [0.5,-0.5,1.5,0.5], - [1.5,2.5,2.5,3.5], - [2.5,1.5,3.5,2.5]]), - dims=['lat','lon'], - coords=[np.array([-0.25,0.25,0.75,1.25]), - np.array([-0.25,0.25,0.75,1.25])]) +if _has_xesmf: + def test_process_weights_regrid_weights(): + # Now, test with a weights array twice the resolution as the + # ds, so it needs to be regridded + ds = xr.Dataset(coords={'lat':(['lat'],np.array([0,1])), + 'lon':(['lon'],np.array([0,1])), + }) + + # Synthetic weights grid, with double the resolution, and shifted + # by a half degree. Should regrid to the same weights grid as above + weights = xr.DataArray(data=np.array([[-0.5,0.5,0.5,1.5], + [0.5,-0.5,1.5,0.5], + [1.5,2.5,2.5,3.5], + [2.5,1.5,3.5,2.5]]), + dims=['lat','lon'], + coords=[np.array([-0.25,0.25,0.75,1.25]), + np.array([-0.25,0.25,0.75,1.25])]) - ds_t,weights_info = process_weights(ds,weights=weights) + ds_t,weights_info = process_weights(ds,weights=weights) - ds_compare = xr.Dataset({'weights':(('lat','lon'),np.array([[0,1],[2,3]]))}, - coords={'lat':(['lat'],np.array([0,1])), - 'lon':(['lon'],np.array([0,1])), - }) + ds_compare = xr.Dataset({'weights':(('lat','lon'),np.array([[0,1],[2,3]]))}, + coords={'lat':(['lat'],np.array([0,1])), + 'lon':(['lon'],np.array([0,1])), + }) - # Check if weights were correctly added to ds - xr.testing.assert_allclose(ds_compare,ds_t) + # Check if weights were correctly added to ds + xr.testing.assert_allclose(ds_compare,ds_t) def test_process_weights_close_weights(): # Make sure weights that are within `np.allclose` but not exactly diff --git a/xagg/core.py b/xagg/core.py index 1acff30..beacbc3 100644 --- a/xagg/core.py +++ b/xagg/core.py @@ -7,6 +7,11 @@ import warnings import re import os +try: + import xesmf as xe + _has_xesmf=True +except ImportError: + _has_xesmf=False from . auxfuncs import (find_rel_area,normalize,fix_ds,get_bnds,subset_find,list_or_first) from . classes import (weightmap,aggregated) @@ -155,9 +160,7 @@ def process_weights(ds,weights=None,target='ds',silent=False): # Import xesmf here to allow the code to work without it (it # often has dependency issues and isn't necessary for many # features of xagg) - try: - import xesmf as xe - except ImportError: + if not _has_xesmf: raise ImportError('If the `weights` grid and the `ds` grid are different, '+ '`xesmf` is needed for `xagg` to regrid them to match; however, '+ '`xesmf` is not installed. Either install `xesmf` or '+