From 491619a334a435cea27c6803f5369033f58154c6 Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Sun, 20 Mar 2022 14:34:10 +0100 Subject: [PATCH 1/3] Bunch of deprecation warnings --- docs/api.rst | 4 ++-- docs/cloud.rst | 2 ++ docs/installing-oggm.rst | 22 ++++++++++++++-------- docs/requirements.txt | 1 + oggm/core/centerlines.py | 9 ++++----- oggm/core/gis.py | 8 +++----- oggm/shop/gcm_climate.py | 4 ++-- oggm/tests/__init__.py | 4 ++-- oggm/tests/test_prepro.py | 14 +++++++------- oggm/tests/test_shop.py | 7 ++++--- oggm/tests/test_utils.py | 7 +++---- oggm/utils/_funcs.py | 10 +++++----- 12 files changed, 49 insertions(+), 43 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 7be1e17f0..675e7faeb 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -288,9 +288,9 @@ Users usually don't have to care about *where* the data is located. fdem = gdir.get_filepath('dem') fdem - import xarray as xr + import rioxarray as rioxr @savefig plot_gdir_dem.png width=80% - xr.open_rasterio(fdem).plot(cmap='terrain'); + rioxr.open_rasterio(fdem).plot(cmap='terrain'); This persistence on disk allows for example to continue a workflow that has been previously interrupted. Initialising a GlacierDirectory from a non-empty diff --git a/docs/cloud.rst b/docs/cloud.rst index 8860d85a2..8c85133d0 100644 --- a/docs/cloud.rst +++ b/docs/cloud.rst @@ -18,6 +18,8 @@ link below to get you started! .. image:: https://img.shields.io/badge/Launch-OGGM%20tutorials-579ACA.svg?style=popout&logo=data:image/png;base64,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 :target: https://mybinder.org/v2/gh/OGGM/binder/stable?urlpath=git-pull?repo=https://github.com/OGGM/tutorials%26amp%3Bbranch=master%26amp%3Burlpath=lab/tree/tutorials/notebooks/welcome.ipynb%3Fautodecode +
+ If you are new to the Jupyter Notebooks or to JupyterLab, you will probably find this `introduction to interactive notebooks`_ quite useful. diff --git a/docs/installing-oggm.rst b/docs/installing-oggm.rst index 833b1482e..3c1413294 100644 --- a/docs/installing-oggm.rst +++ b/docs/installing-oggm.rst @@ -113,7 +113,7 @@ window, type:: conda create --name oggm_env python=3.X -where ``3.X`` is the Python version shipped with conda (currently 3.8). +where ``3.X`` is the Python version shipped with conda (currently 3.9). You can of course use any other name for your environment. Don't forget to activate it before going on:: @@ -124,15 +124,20 @@ Don't forget to activate it before going on:: .. _environment: https://conda.io/projects/conda/en/latest/user-guide/concepts/environments.html -Feeling adventurous? Try mamba (optional) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In a hurry? Try mamba (optional) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The conda package manager has recently been criticized for being slow (it *is* -quite slow to be honest). A new, faster tool is now available to replace conda: `mamba `_. -Mamba is a drop-in replacement for all conda commands. -If you feel like it, install mamba in your conda environment (``conda install -c conda-forge mamba``) +The conda package manager has been criticized for being slow (it *is* +quite slow to be honest). A new, faster tool is now available +to replace conda: `mamba `_. Mamba is a drop-in +replacement for all conda commands. If you feel like it, install mamba in your conda +environment (``conda install -c conda-forge mamba``) and replace all occurrences of ``conda`` with ``mamba`` in the instructions below. +*Note March 2022: soon, conda will use mamba per default. See +`this post `_ +for more info.* + Install dependencies ~~~~~~~~~~~~~~~~~~~~ @@ -303,7 +308,7 @@ environment from the following ``environment.yml`` file used to work:: channels: - conda-forge dependencies: - - python=3.8 + - python=3.9 - jupyter - jupyterlab - numpy @@ -324,6 +329,7 @@ environment from the following ``environment.yml`` file used to work:: - cartopy - geopandas - rasterio + - rioxarray - seaborn - pytables - salem diff --git a/docs/requirements.txt b/docs/requirements.txt index 8115e0782..1ce8d6ed7 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -13,6 +13,7 @@ scikit-image configobj joblib xarray +rioxarray progressbar2 pytest tables diff --git a/oggm/core/centerlines.py b/oggm/core/centerlines.py index 0dd09b70c..13b17db06 100644 --- a/oggm/core/centerlines.py +++ b/oggm/core/centerlines.py @@ -19,7 +19,7 @@ import copy from itertools import groupby from collections import Counter -from distutils.version import LooseVersion +from packaging.version import Version # External libs import numpy as np @@ -28,9 +28,8 @@ import scipy.signal import shapely.geometry as shpg from scipy.interpolate import RegularGridInterpolator -from scipy.ndimage.filters import gaussian_filter1d -from scipy.ndimage.morphology import distance_transform_edt -from scipy.ndimage.measurements import label, find_objects +from scipy.ndimage import (gaussian_filter1d, distance_transform_edt, + label, find_objects) # Optional libs try: @@ -1605,7 +1604,7 @@ def catchment_intersections(gdir): to_crs=gdir.grid.proj, inplace=True) except TypeError: # from_crs not available yet - if LooseVersion(gpd.__version__) >= LooseVersion('0.7.0'): + if Version(gpd.__version__) >= Version('0.7.0'): raise ImportError('You have installed geopandas v0.7 or higher. ' 'Please also update salem for compatibility.') gdfc.crs = gdir.grid diff --git a/oggm/core/gis.py b/oggm/core/gis.py index 59905b49b..8ef1f4048 100644 --- a/oggm/core/gis.py +++ b/oggm/core/gis.py @@ -6,7 +6,7 @@ import os import logging import warnings -from distutils.version import LooseVersion +from packaging.version import Version from functools import partial # External libs @@ -16,9 +16,7 @@ import xarray as xr import shapely.geometry as shpg import scipy.signal -from scipy.ndimage.measurements import label -from scipy.ndimage import binary_erosion -from scipy.ndimage.morphology import distance_transform_edt +from scipy.ndimage import label, distance_transform_edt, binary_erosion from scipy.interpolate import griddata from scipy import optimize as optimization @@ -358,7 +356,7 @@ def _get_nodata(rio_ds): if len(dem_list) == 1: dem_dss = [rasterio.open(dem_list[0])] # if one tile, just open it dem_data = rasterio.band(dem_dss[0], 1) - if LooseVersion(rasterio.__version__) >= LooseVersion('1.0'): + if Version(rasterio.__version__) >= Version('1.0'): src_transform = dem_dss[0].transform else: src_transform = dem_dss[0].affine diff --git a/oggm/shop/gcm_climate.py b/oggm/shop/gcm_climate.py index 71cc8b265..e89c75240 100644 --- a/oggm/shop/gcm_climate.py +++ b/oggm/shop/gcm_climate.py @@ -1,7 +1,7 @@ """Climate data pre-processing""" # Built ins import logging -from distutils.version import LooseVersion +from packaging.version import Version import warnings # External libs @@ -209,7 +209,7 @@ def process_cesm_data(gdir, filesuffix='', fpath_temp=None, fpath_precc=None, fpath_precl = cfg.PATHS['cesm_precl_file'] # read the files - if LooseVersion(xr.__version__) < LooseVersion('0.11'): + if Version(xr.__version__) < Version('0.11'): raise ImportError('This task needs xarray v0.11 or newer to run.') tempds = xr.open_dataset(fpath_temp) diff --git a/oggm/tests/__init__.py b/oggm/tests/__init__.py index 69cf284e0..c0cdc7af0 100644 --- a/oggm/tests/__init__.py +++ b/oggm/tests/__init__.py @@ -1,5 +1,5 @@ import os -from distutils.version import LooseVersion +from packaging.version import Version import pytest import matplotlib.ft2font @@ -12,7 +12,7 @@ # Matplotlib version changes plots, too HAS_MPL_FOR_TESTS = False -if LooseVersion(matplotlib.__version__) >= LooseVersion('2'): +if Version(matplotlib.__version__) >= Version('2'): HAS_MPL_FOR_TESTS = True BASELINE_DIR = os.path.join(cfg.CACHE_DIR, 'oggm-sample-data-%s' % SAMPLE_DATA_COMMIT, diff --git a/oggm/tests/test_prepro.py b/oggm/tests/test_prepro.py index c33cae46b..2f5e88e05 100644 --- a/oggm/tests/test_prepro.py +++ b/oggm/tests/test_prepro.py @@ -1,7 +1,7 @@ import unittest import os import shutil -from distutils.version import LooseVersion +from packaging.version import Version import pytest import warnings @@ -301,8 +301,8 @@ def test_glacier_masks(self): with pytest.raises(RuntimeError): gis.glacier_masks(gdir) - @pytest.mark.skipif((LooseVersion(rasterio.__version__) < - LooseVersion('1.0')), + @pytest.mark.skipif((Version(rasterio.__version__) < + Version('1.0')), reason='requires rasterio >= 1.0') def test_simple_glacier_masks(self): @@ -357,8 +357,8 @@ def test_simple_glacier_masks(self): assert dft.sum()[0] == 1000 assert utils.rmsd(dft['ref'], dft['oggm']) < 5 - @pytest.mark.skipif((LooseVersion(rasterio.__version__) < - LooseVersion('1.0')), + @pytest.mark.skipif((Version(rasterio.__version__) < + Version('1.0')), reason='requires rasterio >= 1.0') def test_glacier_masks_other_glacier(self): @@ -390,8 +390,8 @@ def test_glacier_masks_other_glacier(self): np.testing.assert_allclose(dfh['Zmax'], entity.Zmax, atol=20) np.testing.assert_allclose(dfh['Zmin'], entity.Zmin, atol=20) - @pytest.mark.skipif((LooseVersion(rasterio.__version__) < - LooseVersion('1.0')), + @pytest.mark.skipif((Version(rasterio.__version__) < + Version('1.0')), reason='requires rasterio >= 1.0') def test_rasterio_glacier_masks(self): diff --git a/oggm/tests/test_shop.py b/oggm/tests/test_shop.py index 4a0f518bb..f86893dc5 100644 --- a/oggm/tests/test_shop.py +++ b/oggm/tests/test_shop.py @@ -7,6 +7,7 @@ import oggm import xarray as xr +import rioxarray as rioxr import numpy as np import pandas as pd from oggm import utils @@ -66,9 +67,9 @@ def test_repro_to_glacier(self, class_case_dir, monkeypatch): gis.rasterio_to_gdir(gdir, region_files['ALA']['vy'], 'its_live_vy', resampling='bilinear') - with xr.open_rasterio(gdir.get_filepath('its_live_vx')) as da: + with rioxr.open_rasterio(gdir.get_filepath('its_live_vx')) as da: _vx = da.where(mask).data.squeeze() - with xr.open_rasterio(gdir.get_filepath('its_live_vy')) as da: + with rioxr.open_rasterio(gdir.get_filepath('its_live_vy')) as da: _vy = da.where(mask).data.squeeze() _vel = np.sqrt(_vx**2 + _vy**2) @@ -552,7 +553,7 @@ def test_add_consensus(self, class_case_dir, monkeypatch): with xr.open_dataset(gdir.get_filepath('gridded_data')) as ds: mine = ds.consensus_ice_thickness - with xr.open_rasterio(gdir.get_filepath('consensus')) as ds: + with rioxr.open_rasterio(gdir.get_filepath('consensus')) as ds: ref = ds.isel(band=0) # Check area diff --git a/oggm/tests/test_utils.py b/oggm/tests/test_utils.py index 77c6fdff5..8ee7a6550 100644 --- a/oggm/tests/test_utils.py +++ b/oggm/tests/test_utils.py @@ -1653,10 +1653,9 @@ def prepare_verify_test(self, valid_size=True, valid_crc32=True, file_sha256 = file_sha256.digest() data = utils.get_dl_verify_data('cluster.klima.uni-bremen.de') - s = pd.Series({'size': file_size, 'sha256': file_sha256}, - name='test.txt') - data = data.append(s) - cfg.DATA['dl_verify_data_test.com'] = data + s = pd.DataFrame({'size': file_size, 'sha256': file_sha256}, + index=['test.txt']) + cfg.DATA['dl_verify_data_test.com'] = pd.concat([data, s]) return 'https://test.com/test.txt' diff --git a/oggm/utils/_funcs.py b/oggm/utils/_funcs.py index 66869a4e5..1b33663b4 100644 --- a/oggm/utils/_funcs.py +++ b/oggm/utils/_funcs.py @@ -8,12 +8,12 @@ import logging import warnings import shutil -from distutils.version import LooseVersion +from packaging.version import Version # External libs import pandas as pd import numpy as np -from scipy.ndimage import filters +from scipy.ndimage import convolve1d try: from scipy.signal.windows import gaussian except AttributeError: @@ -268,7 +268,7 @@ def smooth1d(array, window_size=None, kernel='gaussian'): else: raise NotImplementedError('Kernel: ' + kernel) kernel = kernel / np.asarray(kernel).sum() - return filters.convolve1d(array, kernel, mode='mirror') + return convolve1d(array, kernel, mode='mirror') def line_interpol(line, dx): @@ -375,7 +375,7 @@ def clip_scalar(value, vmin, vmax): return vmin if value < vmin else vmax if value > vmax else value -if LooseVersion(np.__version__) < LooseVersion('1.17'): +if Version(np.__version__) < Version('1.17'): clip_array = np.clip else: # TODO: reassess this when https://github.com/numpy/numpy/issues/14281 @@ -509,7 +509,7 @@ def polygon_intersections(gdf): '{}.'.format(line.type)) line = gpd.GeoDataFrame([[i, j, line]], columns=out_cols) - out = out.append(line) + out = pd.concat([out, line]) return out From 030d349145c6ba9cb76eae6bf4e93ba6b8bae287 Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Sun, 20 Mar 2022 14:38:41 +0100 Subject: [PATCH 2/3] Update base image --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 3874e8e32..b2a0c1458 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -24,7 +24,7 @@ jobs: - workflow-multi - graphics-mpl container: - - ghcr.io/oggm/untested_base:20211114 + - ghcr.io/oggm/untested_base:20220320 - ghcr.io/oggm/untested_base:py3.7 - ghcr.io/oggm/untested_base:py3.9 include: From 3c44162e155dd1fe832ada4d4ac44192aafd1848 Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Sun, 20 Mar 2022 15:36:43 +0100 Subject: [PATCH 3/3] Some more small changes --- docs/installing-oggm.rst | 6 ++++++ oggm/core/centerlines.py | 5 ++++- oggm/tests/test_prepro.py | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/installing-oggm.rst b/docs/installing-oggm.rst index 3c1413294..4fa182aa8 100644 --- a/docs/installing-oggm.rst +++ b/docs/installing-oggm.rst @@ -64,6 +64,7 @@ GIS tools: - shapely - pyproj - rasterio + - rioxarray - geopandas Testing: @@ -277,6 +278,11 @@ If everything worked fine, you should see something like:: You can safely ignore deprecation warnings and other messages (if any), as long as the tests end without errors. +.. important:: + + The tests (without the ``--run-slow`` option) should run in 5 to 10 minutes. + If this takes too long, this may be an indiv + This runs a minimal suite of tests. If you want to run the entire test suite (including graphics and slow running tests), type:: diff --git a/oggm/core/centerlines.py b/oggm/core/centerlines.py index 13b17db06..4a3a6e0ab 100644 --- a/oggm/core/centerlines.py +++ b/oggm/core/centerlines.py @@ -1325,7 +1325,10 @@ def _point_width(normals, point, centerline, poly, poly_no_nunataks): # Make sure we are always returning a MultiLineString for later line = line.intersection(poly) if line.type == 'LineString': - line = shpg.MultiLineString([line]) + try: + line = shpg.MultiLineString([line]) + except shapely.errors.EmptyPartError: + return np.NaN, shpg.MultiLineString() elif line.type == 'MultiLineString': pass # nothing to be done elif line.type == 'GeometryCollection': diff --git a/oggm/tests/test_prepro.py b/oggm/tests/test_prepro.py index 2f5e88e05..799a6ffeb 100644 --- a/oggm/tests/test_prepro.py +++ b/oggm/tests/test_prepro.py @@ -3086,7 +3086,7 @@ def test_find_calving_full_fl(self): df = inversion.find_inversion_calving(gdir) assert df['calving_flux'] > 2 - assert df['calving_rate_myr'] > 500 + assert df['calving_rate_myr'] > 450 assert df['calving_mu_star'] == 0 # Test that new MB equal flux