From 7b3800c5c7cddc0c1b709e75a43201560c50152a Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 4 Nov 2020 12:06:13 +0100 Subject: [PATCH 01/65] Fix doc-string --- esmvalcore/preprocessor/_multimodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esmvalcore/preprocessor/_multimodel.py b/esmvalcore/preprocessor/_multimodel.py index 360daf71c7..515f99266d 100644 --- a/esmvalcore/preprocessor/_multimodel.py +++ b/esmvalcore/preprocessor/_multimodel.py @@ -384,7 +384,7 @@ def multi_model_statistics(products, span, statistics, output_products=None): missing data. output_products: dict dictionary of output products. - statistics: str + statistics: list statistical measure to be computed. Available options: mean, median, max, min, std, or pXX.YY (for percentile XX.YY; decimal part optional). From e62479f1700c425fd36b43a867e4be3c654db7f5 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 4 Nov 2020 12:06:32 +0100 Subject: [PATCH 02/65] Add useful error message --- esmvalcore/preprocessor/_multimodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esmvalcore/preprocessor/_multimodel.py b/esmvalcore/preprocessor/_multimodel.py index 515f99266d..5483412413 100644 --- a/esmvalcore/preprocessor/_multimodel.py +++ b/esmvalcore/preprocessor/_multimodel.py @@ -106,7 +106,7 @@ def _compute_statistic(data, statistic_name): quantile = float(statistic_name[1:]) / 100 statistic_function = partial(_quantile, quantile=quantile) else: - raise NotImplementedError + raise ValueError(f'No such statistic: `{statistic_name}`') # no plevs if len(data[0].shape) < 3: From f4938a148d57d240e616685dcab3306e45887d6d Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 4 Nov 2020 12:08:15 +0100 Subject: [PATCH 03/65] Add tests using real data using `esmvaltool_sample_data` https://github.com/ESMValGroup/ESMValTool_sample_data --- tests/system/test_multimodel.py | 70 +++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 tests/system/test_multimodel.py diff --git a/tests/system/test_multimodel.py b/tests/system/test_multimodel.py new file mode 100644 index 0000000000..42e14d89ca --- /dev/null +++ b/tests/system/test_multimodel.py @@ -0,0 +1,70 @@ +"""System test for :func:`esmvalcore.preprocessor._multimodel`.""" + +import esmvaltool_sample_data +import pytest + +from esmvalcore.preprocessor import ( + extract_levels, + multi_model_statistics, + regrid, +) + + +def preprocess_data(data): + regrid_kwargs = { + 'target_grid': '2.5x2.5', + 'scheme': 'linear', + } + extract_kwargs = { + 'levels': [100000.0, 92500.0], + 'scheme': 'linear', + } + + data = [regrid(d, **regrid_kwargs) for d in data] + data = [extract_levels(d, **extract_kwargs) for d in data] + + return data + + +def get_timeseries_data(): + """Representative timeseries data.""" + timeseries_data = esmvaltool_sample_data.load_timeseries_data() + timeseries_data = preprocess_data(timeseries_data) + return timeseries_data + + +def get_map_data(): + """Representative timeseries data.""" + map_data = esmvaltool_sample_data.load_map_data() + map_data = preprocess_data(map_data) + return map_data + + +def get_profile_data(): + """Representative timeseries data.""" + profile_data = esmvaltool_sample_data.load_profile_data() + profile_data = preprocess_data(profile_data) + return profile_data + + +data_list = [ + get_timeseries_data(), + # get_map_data(), + # get_profile_data(), +] + + +@pytest.mark.parametrize('data', data_list) +def test_multimodel_overlap_mean(data): + """Test statistic.""" + stat = multi_model_statistics(data, span='overlap', statistics=['mean']) + + +@pytest.mark.skip('Takes too long to run') +@pytest.mark.parametrize('data', data_list) +def test_multimodel_full_mean(data): + """Test statistic.""" + stat = multi_model_statistics(data, span='full', statistics=['mean']) + + +# mean, median, min, max, std, p75 From 732b5efc7ea45859c1fa953307be6f5d9f5a06fd Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Thu, 5 Nov 2020 14:28:45 +0100 Subject: [PATCH 04/65] Fix documentation --- esmvalcore/preprocessor/_multimodel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esmvalcore/preprocessor/_multimodel.py b/esmvalcore/preprocessor/_multimodel.py index 5483412413..399839cf00 100644 --- a/esmvalcore/preprocessor/_multimodel.py +++ b/esmvalcore/preprocessor/_multimodel.py @@ -390,8 +390,8 @@ def multi_model_statistics(products, span, statistics, output_products=None): Returns ------- - list - list of data products or cubes containing the multimodel stats + list or dict + list data products or dict of cubes containing the multimodel stats computed. Raises From 0faa524466738a9c380dcabe2a58bba8b6c9e576 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Thu, 5 Nov 2020 17:06:43 +0100 Subject: [PATCH 05/65] Update tests --- tests/system/test_multimodel.py | 77 ++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/tests/system/test_multimodel.py b/tests/system/test_multimodel.py index 42e14d89ca..2558fd91f8 100644 --- a/tests/system/test_multimodel.py +++ b/tests/system/test_multimodel.py @@ -1,6 +1,7 @@ """System test for :func:`esmvalcore.preprocessor._multimodel`.""" import esmvaltool_sample_data +import numpy as np import pytest from esmvalcore.preprocessor import ( @@ -10,9 +11,13 @@ ) -def preprocess_data(data): +def preprocess_data(cubes): + first_cube = cubes[0] + t1, t2 = 0, 50 # time-slicing first N items + + # regrid to first cube regrid_kwargs = { - 'target_grid': '2.5x2.5', + 'target_grid': first_cube, 'scheme': 'linear', } extract_kwargs = { @@ -20,51 +25,53 @@ def preprocess_data(data): 'scheme': 'linear', } - data = [regrid(d, **regrid_kwargs) for d in data] - data = [extract_levels(d, **extract_kwargs) for d in data] + cubes = [cube[t1:t2] for cube in cubes] + cubes = [regrid(cube, **regrid_kwargs) for cube in cubes] + cubes = [extract_levels(cube, **extract_kwargs) for cube in cubes] - return data + return cubes -def get_timeseries_data(): +@pytest.fixture +def timeseries_cubes(): """Representative timeseries data.""" - timeseries_data = esmvaltool_sample_data.load_timeseries_data() - timeseries_data = preprocess_data(timeseries_data) - return timeseries_data - + timeseries_cubes = esmvaltool_sample_data.load_timeseries_cubes() + timeseries_cubes = preprocess_data(timeseries_cubes) + return timeseries_cubes -def get_map_data(): - """Representative timeseries data.""" - map_data = esmvaltool_sample_data.load_map_data() - map_data = preprocess_data(map_data) - return map_data +@pytest.fixture +def map_cubes(): + """Representative map data.""" + map_cubes = esmvaltool_sample_data.load_map_cubes() + map_cubes = preprocess_data(map_cubes) + return map_cubes -def get_profile_data(): - """Representative timeseries data.""" - profile_data = esmvaltool_sample_data.load_profile_data() - profile_data = preprocess_data(profile_data) - return profile_data +@pytest.fixture +def profile_cubes(): + """Representative profile data.""" + profile_cubes = esmvaltool_sample_data.load_profile_cubes() + profile_cubes = preprocess_data(profile_cubes) + return profile_cubes -data_list = [ - get_timeseries_data(), - # get_map_data(), - # get_profile_data(), -] - -@pytest.mark.parametrize('data', data_list) -def test_multimodel_overlap_mean(data): +@pytest.mark.parametrize('span', ('overlap', 'full')) +def test_multimodel_overlap(timeseries_cubes, span): """Test statistic.""" - stat = multi_model_statistics(data, span='overlap', statistics=['mean']) + cubes = timeseries_cubes + statistic = 'mean' + statistics = [statistic] + expected_shape = cubes[0].shape + output = multi_model_statistics(cubes, span=span, statistics=statistics) -@pytest.mark.skip('Takes too long to run') -@pytest.mark.parametrize('data', data_list) -def test_multimodel_full_mean(data): - """Test statistic.""" - stat = multi_model_statistics(data, span='full', statistics=['mean']) + assert isinstance(output, dict) + assert all(stat in output for stat in statistics) + + output_cube = output[statistic] + # make sure data are not completely masked + assert np.all(output_cube.data.mask == False) # noqa -# mean, median, min, max, std, p75 + assert output_cube.shape == expected_shape From 0541c1edeed80bf9cd1358eddcf48f9a9efbd5c1 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Thu, 5 Nov 2020 17:07:31 +0100 Subject: [PATCH 06/65] Rename system -> functional tests --- tests/{system => functional}/test_multimodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/{system => functional}/test_multimodel.py (96%) diff --git a/tests/system/test_multimodel.py b/tests/functional/test_multimodel.py similarity index 96% rename from tests/system/test_multimodel.py rename to tests/functional/test_multimodel.py index 2558fd91f8..5a430e5f8a 100644 --- a/tests/system/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -1,4 +1,4 @@ -"""System test for :func:`esmvalcore.preprocessor._multimodel`.""" +"""Functional test for :func:`esmvalcore.preprocessor._multimodel`.""" import esmvaltool_sample_data import numpy as np From 56303ad9bb07c5b71072ff7d658c6d86ae07522b Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 09:34:02 +0100 Subject: [PATCH 07/65] Add mark to functional tests using real data i.e. `pytest -m functional` --- setup.cfg | 1 + tests/functional/test_multimodel.py | 1 + 2 files changed, 2 insertions(+) diff --git a/setup.cfg b/setup.cfg index 6fd9f1591f..6905ec23ce 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,6 +21,7 @@ flake8-ignore = log_level = WARNING markers = installation: test requires installation of dependencies + functional: Run functional tests using real data [coverage:run] parallel = true diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 5a430e5f8a..1713e78539 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -56,6 +56,7 @@ def profile_cubes(): return profile_cubes +@pytest.mark.functional @pytest.mark.parametrize('span', ('overlap', 'full')) def test_multimodel_overlap(timeseries_cubes, span): """Test statistic.""" From 6e2cda9b7041c87fcd3de40e11d0bb3919ebe03e Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 10:15:21 +0100 Subject: [PATCH 08/65] Add regression test --- tests/functional/test_multimodel.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 1713e78539..a538697c61 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -1,6 +1,9 @@ """Functional test for :func:`esmvalcore.preprocessor._multimodel`.""" +from pathlib import Path + import esmvaltool_sample_data +import iris import numpy as np import pytest @@ -61,6 +64,7 @@ def profile_cubes(): def test_multimodel_overlap(timeseries_cubes, span): """Test statistic.""" cubes = timeseries_cubes + name = 'timeseries' statistic = 'mean' statistics = [statistic] expected_shape = cubes[0].shape @@ -76,3 +80,15 @@ def test_multimodel_overlap(timeseries_cubes, span): assert np.all(output_cube.data.mask == False) # noqa assert output_cube.shape == expected_shape + + # NOTE for the regression test + # The following test will fail if the data are changed or if the + # multimodel code changes significantly. To update the data for the + # regression test, remove the corresponding `.nc` files. + filename = Path(__file__).with_name(f'{name}-{span}-{statistic}.nc') + if filename.exists(): + expected_cube = iris.load(str(filename))[0] + assert np.allclose(output_cube.data, expected_cube.data) + else: + iris.save(output_cube, filename) + raise RuntimeError(f'Wrote file {filename.absolute()}') From 61876f02c3b28b86cf2877526bd5e6d77c00ed88 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 10:39:24 +0100 Subject: [PATCH 09/65] Add regression data --- tests/functional/timeseries-full-mean.nc | Bin 0 -> 21010 bytes tests/functional/timeseries-overlap-mean.nc | Bin 0 -> 24947 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/functional/timeseries-full-mean.nc create mode 100644 tests/functional/timeseries-overlap-mean.nc diff --git a/tests/functional/timeseries-full-mean.nc b/tests/functional/timeseries-full-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..ca0df69f5a142d6208b683dd5052b86280f8092b GIT binary patch literal 21010 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 EPdpR}*Z=?k literal 0 HcmV?d00001 diff --git a/tests/functional/timeseries-overlap-mean.nc b/tests/functional/timeseries-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..7dd1b0144aded0fdbb3842d942adfa476ec0e7d6 GIT binary patch literal 24947 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 MT`ZXECbq!;1I8j) Date: Fri, 6 Nov 2020 10:39:57 +0100 Subject: [PATCH 10/65] Test different variations of the dataset --- tests/functional/test_multimodel.py | 64 +++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index a538697c61..42e391981c 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -59,13 +59,7 @@ def profile_cubes(): return profile_cubes -@pytest.mark.functional -@pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_overlap(timeseries_cubes, span): - """Test statistic.""" - cubes = timeseries_cubes - name = 'timeseries' - statistic = 'mean' +def multi_model_test(cubes, span, statistic): statistics = [statistic] expected_shape = cubes[0].shape @@ -78,9 +72,20 @@ def test_multimodel_overlap(timeseries_cubes, span): # make sure data are not completely masked assert np.all(output_cube.data.mask == False) # noqa - assert output_cube.shape == expected_shape + return output_cube + + +@pytest.mark.functional +@pytest.mark.parametrize('span', ('overlap', 'full')) +def test_multimodel_overlap(timeseries_cubes, span): + """Test statistic.""" + cubes = timeseries_cubes + name = 'timeseries' + statistic = 'mean' + output_cube = multi_model_test(cubes, span=span, statistic=statistic) + # NOTE for the regression test # The following test will fail if the data are changed or if the # multimodel code changes significantly. To update the data for the @@ -92,3 +97,46 @@ def test_multimodel_overlap(timeseries_cubes, span): else: iris.save(output_cube, filename) raise RuntimeError(f'Wrote file {filename.absolute()}') + + +@pytest.mark.functional +@pytest.mark.parametrize('span', ('overlap', 'full')) +def test_multimodel_overlap_without_vertical_dimension(timeseries_cubes, span): + """Test statistic without vertical dimension.""" + cubes = [cube[0:50, 0] for cube in timeseries_cubes] + statistic = 'mean' + multi_model_test(cubes, span=span, statistic=statistic) + + +@pytest.mark.functional +@pytest.mark.parametrize('span', ('overlap', 'full')) +def test_multimodel_overlap_without_horizontal_dimension( + timeseries_cubes, span): + """Test statistic without horizontal dimension.""" + cubes = [cube[0:50, :, 0, 0] for cube in timeseries_cubes] + # Coordinate not found error + statistic = 'mean' + with pytest.raises(iris.exceptions.CoordinateNotFoundError): + # iris.exceptions.CoordinateNotFoundError: + # 'Expected to find exactly 1 depth coordinate, but found none.' + multi_model_test(cubes, span=span, statistic=statistic) + + +@pytest.mark.functional +@pytest.mark.parametrize('span', ('overlap', 'full')) +def test_multimodel_overlap_only_time_dimension(timeseries_cubes, span): + """Test statistic without only the time dimension.""" + cubes = [cube[0:50, 0, 0, 0] for cube in timeseries_cubes] + statistic = 'mean' + multi_model_test(cubes, span=span, statistic=statistic) + + +@pytest.mark.functional +@pytest.mark.parametrize('span', ('overlap', 'full')) +def test_multimodel_overlap_no_time_dimension(timeseries_cubes, span): + """Test statistic without time dimension.""" + cubes = [cube[0] for cube in timeseries_cubes] + statistic = 'mean' + with pytest.raises(ValueError): + # ValueError: Cannot guess bounds for a coordinate of length 1. + multi_model_test(cubes, span=span, statistic=statistic) From 1c8dbb2ba3ddf92c942633ca00d2063423ba51ed Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 11:14:05 +0100 Subject: [PATCH 11/65] Add sample data git link to setup.py for develop installs --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 9d889a06e2..6e32e3e213 100755 --- a/setup.py +++ b/setup.py @@ -72,6 +72,7 @@ 'vprof', 'yamllint', 'yapf', + 'ESMValTool_sample_data @ git+https://github.com/ESMValGroup/ESMValTool_sample_data@make_package', ], } From fec69677d144c516dbdd9c9378c93b935b421acd Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 11:22:19 +0100 Subject: [PATCH 12/65] Move sample data dependency to 'test' --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 6e32e3e213..4f66a7c84c 100755 --- a/setup.py +++ b/setup.py @@ -57,6 +57,7 @@ 'pytest-metadata>=1.5.1', 'pytest-mock', 'pytest-xdist', + 'ESMValTool_sample_data @ git+https://github.com/ESMValGroup/ESMValTool_sample_data@make_package', ], # Development dependencies # Use pip install -e .[develop] to install in development mode @@ -72,7 +73,6 @@ 'vprof', 'yamllint', 'yapf', - 'ESMValTool_sample_data @ git+https://github.com/ESMValGroup/ESMValTool_sample_data@make_package', ], } From 282cb7ec326e834aa8e33f5e659a03ce6ac3eb94 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 11:29:09 +0100 Subject: [PATCH 13/65] Avoid Flake8 fail --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4f66a7c84c..6c5063cefd 100755 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ 'pytest-metadata>=1.5.1', 'pytest-mock', 'pytest-xdist', - 'ESMValTool_sample_data @ git+https://github.com/ESMValGroup/ESMValTool_sample_data@make_package', + 'ESMValTool_sample_data @ git+https://github.com/ESMValGroup/ESMValTool_sample_data@make_package', # noqa ], # Development dependencies # Use pip install -e .[develop] to install in development mode From 37028ef847d2274cc6190748b845c5b395c0bd95 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 11:40:26 +0100 Subject: [PATCH 14/65] Add documentation --- doc/contributing.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/contributing.rst b/doc/contributing.rst index 0f731dc0bb..59772f506d 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -33,6 +33,11 @@ adding ``-m 'not installation'`` to the previous command. Tests will also be run automatically by `CircleCI `__. +Sample data +----------- + +If you need sample data to work with, `this repository `__ contains samples of real data for use with ESMValTool development, demonstration purposes and automated testing. The goal is to keep the repository size small (~ 100 MB), so it can be easily downloaded and distributed. + Code style ---------- From 578336aaa25fe91e4b08e67566f4167d1d6bfff8 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 19 Oct 2020 16:09:49 +0200 Subject: [PATCH 15/65] Add the missing requests dependency --- package/meta.yaml | 1 + setup.py | 1 + 2 files changed, 2 insertions(+) diff --git a/package/meta.yaml b/package/meta.yaml index 6b881937bc..4be730bdd3 100644 --- a/package/meta.yaml +++ b/package/meta.yaml @@ -53,6 +53,7 @@ requirements: - psutil - pydot - pyyaml + - requests - shapely - yamale==2.* # in esmvalgroup channel diff --git a/setup.py b/setup.py index 6c5063cefd..563d6d9f4c 100755 --- a/setup.py +++ b/setup.py @@ -42,6 +42,7 @@ 'psutil', 'pyyaml', 'scitools-iris>=2.2', + 'requests', 'shapely[vectorized]', 'stratify', 'yamale==2.*', From 19dbf1fa155f7ae70d28b41d247b1e08331cc424 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 13:34:47 +0100 Subject: [PATCH 16/65] Fix conda build --- package/meta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/meta.yaml b/package/meta.yaml index 4be730bdd3..103f5b7934 100644 --- a/package/meta.yaml +++ b/package/meta.yaml @@ -73,7 +73,7 @@ test: - r-yaml - ncl commands: - - pytest -n 2 --ignore=run_test.py + - pytest -n 2 --ignore=run_test.py -m "not functional" - esmvaltool -- --help - esmvaltool version imports: From a95d02dd1a0131ac48d8a1e8ce458848a348645c Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 14:22:08 +0100 Subject: [PATCH 17/65] Remove pytest step in conda build --- package/meta.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/package/meta.yaml b/package/meta.yaml index 103f5b7934..cd9e2e3558 100644 --- a/package/meta.yaml +++ b/package/meta.yaml @@ -73,7 +73,6 @@ test: - r-yaml - ncl commands: - - pytest -n 2 --ignore=run_test.py -m "not functional" - esmvaltool -- --help - esmvaltool version imports: From d1ad030869cca28e4337fb18cf10804d63db6ab1 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 6 Nov 2020 14:27:01 +0100 Subject: [PATCH 18/65] Ignore functional tests for conda build --- package/meta.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/package/meta.yaml b/package/meta.yaml index cd9e2e3558..f485f0d2b8 100644 --- a/package/meta.yaml +++ b/package/meta.yaml @@ -73,6 +73,7 @@ test: - r-yaml - ncl commands: + - pytest -n 2 --ignore=run_test.py --ignore=tests/functional - esmvaltool -- --help - esmvaltool version imports: From 7505bfa66be0b982428b3ca771d64ca95d4abf5e Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 10 Nov 2020 10:53:17 +0100 Subject: [PATCH 19/65] Skip tests if sample data repo cannot be imported --- tests/functional/test_multimodel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 42e391981c..98fd553fec 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -2,7 +2,6 @@ from pathlib import Path -import esmvaltool_sample_data import iris import numpy as np import pytest @@ -13,6 +12,8 @@ regrid, ) +esmvaltool_sample_data = pytest.importorskip("esmvaltool_sample_data") + def preprocess_data(cubes): first_cube = cubes[0] From 0dd7253544c648c6b9695018fafef7319c0c1b39 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 10 Nov 2020 10:54:23 +0100 Subject: [PATCH 20/65] Rely on pytest.importskip to ignore functional tests --- package/meta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/meta.yaml b/package/meta.yaml index f485f0d2b8..4be730bdd3 100644 --- a/package/meta.yaml +++ b/package/meta.yaml @@ -73,7 +73,7 @@ test: - r-yaml - ncl commands: - - pytest -n 2 --ignore=run_test.py --ignore=tests/functional + - pytest -n 2 --ignore=run_test.py - esmvaltool -- --help - esmvaltool version imports: From d8bf2042ed8282ba48c1228b4db10d9a3c619b76 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 10 Nov 2020 10:59:44 +0100 Subject: [PATCH 21/65] Update developer documentation --- doc/contributing.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/contributing.rst b/doc/contributing.rst index 59772f506d..02e5541c37 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -38,6 +38,10 @@ Sample data If you need sample data to work with, `this repository `__ contains samples of real data for use with ESMValTool development, demonstration purposes and automated testing. The goal is to keep the repository size small (~ 100 MB), so it can be easily downloaded and distributed. +The data are installed as part of the developer dependencies, and used by the functional tests (i.e. in the `multimodel tests` `__) + +To avoid running these tests as they can be time-consuming, use `pytest -m "not functional"`. + Code style ---------- From 5cb0f3db5d7d3f7416163d8efec973d2ec4e8737 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 10 Nov 2020 14:43:08 +0100 Subject: [PATCH 22/65] Update regression data --- tests/functional/timeseries-full-mean.nc | Bin 21010 -> 21010 bytes tests/functional/timeseries-overlap-mean.nc | Bin 24947 -> 24947 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/functional/timeseries-full-mean.nc b/tests/functional/timeseries-full-mean.nc index ca0df69f5a142d6208b683dd5052b86280f8092b..acc00ef7b14261e08365549cf617f6bb0d6d69b8 100644 GIT binary patch delta 2152 zcmZA1dvp}l9l-I0fTR=>p&<$dPQXOvQ8W@E5hNSFv4Clhq7WWh8?8JKgp_P{cXnoX zW@l&Tu7MN|G{MszL*$_dq2(d!p+*v*C^jV&Yz?olNhuGB<)u6dkq%t!AH9FfXXZZU z-gEEocUP?Iv|?SSEhYW++|7&0omNWrmc@*$DkYxpW5FN%RJeUqSNQ2(=b=ZIhn&eC z(*IVjj$;(LT!^t!Bvx)2TX=-5)3UD>+h zFgrt#cG>2M;etM2>o$k0cdEzs{!*ROVzc4PDCbk7G>x{XONw%Kghg$0gw3|e>dzyL z2${KL1zCW!tR|B4t*6NWq$Z>R()kIm-5@o~6D22%}{_^7(-=)M@&^N}xC4#mG1QAnEpC|~m2>LY&wm6>nOz_xj z!GrBK&94fb_ER>;Pur|N7Uig;_-B-xd!mGzEyABf@ibZN8)I?q=O!BmTO4}YbW_QD(og=b09(8InbI}L zl4Ol0Yr}$}q&qu^LvTP@7npXIDw3CWI65yka0RnjeI{Jsn`C*6?t}yvmg6wQI z$nI+Js{W~g_uo3_S6QSEw5a@@#nmAe-(*DyTr!#TNCa`tL|x--;aVrM-xN$(CCJUN z`L37E$v!qoU2Ntg#AtK2KEa9hy3`n3X9}z=!KOk%?~#I%>w;6x)_>6YNB^batY0VU3qTV|~0(=cOveN2Ze|!z&c#k5rgbs-WZtNO#(YTvJfT`xtdpqvv#$ zn=y^&pH*3V%gcvJK2C1;a(R!JldlA*A0ME2Sb)5g0LLEIX?`onp6el|uMcu5N#}zu zy3T|HA!@qobn1xU-4S7m%c8=`hN>!)NW|n~rOD$JCO^s*G>#LD$P*lJ-uvxyg7cjy z$xe{IR2k*%X2C;=F@kM^RL91HHoKkZf27H#HbD@-;ap^22r{n;mL3)?uM#ZLFW4-L zI5(0L`Ijx5TW6yTj@b-vjZ&N(rN6NF^gkA}iY)ewG^rX9W@?&AUPTzaHq5)r!z^AF zW?m@F-Ww{D8x=wiYpDGK?AoQFm1xZ0tnomx#;BJSviAFkKdnDCPj(M2zdmpu`hpiu|c%*sT~0Cn-s-+%(Gh94Qsbu7eOsEA&~|qM zS2wBAU0ReRP3tXnrAq7jN^1s4jX_d(#vOH+D{Y9Zh!2<6KQ67wlDe~{X=A1FTxmU0 zV}i7(KUvQcFO=5Ilp3!{i(Yed=6A(s$%^`UQe&aC=-1M;GO0_E#x-e;AvG+i zJ0?wADs?Tt=ltt#ms8x8SMTadE0h)$x|8oTI7`TtUf;eby{6X~*S!wz|I@hlEjv5U ai}%KTugkr?p+|kUmCJ{A-JU!yA?3g3R6#fZ delta 2152 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 H5;*$5S6op6 delta 3168 zcmY+`3slrr8VB(3PzRKk4-P0=PeoB{s~(q1MJxJOgcZ~Z;;X9^=8;S?4@Yc)$&ewL z3J6tXL~&Kbs@txvtrlFZj|F@z?ur)0=K_izs1uQ#WTcP+Pm|I z$_~%GV2>hqW@vNR*~vix2Rrx}f9R!}8Y zTz<%))|W=y95XJ=HsjV<8WF8}Z26f*^ix*Ay-`N!cF~AA$D!>EhcQ|jt1}FEhc}{c zmJxTh&^VK2K%t4lS(bzOx*n$!^r#Zt4*4t0*s;uv`WZY-<9G~mJ20@wfv%Kn2u;~& z9$?2rKRYh^OZYZa!oPS4%~=wz`-_NRMC_g*;)?L5h&De71>cD%sFE=Lkc7|x5h2kc z{-+mlJYB@w|KRb|Y{&A2IY^$H1MZt_Xoh8D$9X%d&)5-|Y=tSv4A)N?sQWPkdWRXG zT;b5M&W7drHe7scM8h;1H{UiREYggW(F{fg8qo4R3nAn?7D-cCT;L4oHQ5ZWC^Les z3>?$+cr5P__>jff=QKj2^oZWZqIxrnk>d==@X+B#0)v}z40g>nfN#{oHJ(NLI2M_? zI#7Gl5zcJyKGc*kHzyHmvQ?edZ@l7J)$ABwry_%Ii&k04@l9}yLKBG4k@UbzI% zZ4!#|bMfd6dHLTH@k^qJ-1$5*p4(A1T7czs0e7|8`112?MC{}-U@H%wKC96Au@&w2 zGvIe8LtaG-8WJs-CfTryx1nFN5oPTRZs(cNE}2m^kU`=R`H~2c9GWI_Xjsjn;RFp~ zfm~?wO_=>DgWaM5`#o4>Q7pJh22{NP;nz(Ve$9mTRs-@1^@wz`I3TbXxSxiXO^=iP zIk^4hF1n`&108(MGFV>AVCf4T+6&XM{}_YFlMMbDqeY`O4MN;%1G?52@a|;>WjZ|? z3gi=6$0B(kjp$e%md<7%#ma3{Y60fSogiNV;le76IA_AvP!nEeSrD+sg400`+)i*{ z_tqS=ZOlP=gdKHVb~p#|nC#Evu}eba1_@M~gsN5vnUaXG7EwT8nTW@m+yUc_B0ktBV((`nZpj~f^amc51DseK=tS}!9&5_%_-nZXGs+xz)W?P- zlNI+HGqAWm1M%am5XM-LXtbdv&4&N_n9wxW2+bQ-+zz*5&lDDGf&~VLFPTt#-h?P` z7MD7Wh#6u*^dJk4Ph`+_fWb+*V#BIAT<@gu<$nx_cXDXV;V@#D0bV6~1j#={8u^DP zvy!w3e3FLJI2zO(8qEb36l*MSuC?K+(}sJ;OxSeMgh%o> z-5z1Z+ISxPYYwz&1U&T;aCBuhGVAT=6nP}&@HqTXge6kKh++wMiX@ag%7t*sC1T1f z5wFh>@sU+RH7$35{C|*lQ9_DEMAQ)xr{!y9mRqQ}mjl}ZcyxZ7gC%!!P#9{*+}dm` zO6Bq3eIDd5XM9YL&RAl_LSoD^Vn-^mM%%4GQN=WwuyVxVR-(p6>{v~_v4(i=BVt7s zG1E>=br9nOVwsazluLAp#7v3Exn$+zQ>h=5iR87!ggjzYJ~6z27_yGouaHO;5r0yA z_zB6a>xox35Vgg`TZ+pzlH4HMeS9jmgiO>ZPH~f5rTEq+lJ_Zwmy%qr7_yn<5=H+l zB)b%i&wFxA>CZ7mp~7eW@hLSi%gV>x^+>4+pk5hIDlOsRz5V37kqr5!f}$QY$M=@+ z73zCVlk7P?<`tcZB>!fLk`<{H%KnP2X(X#w=t)*}8c9}7HFszE_+*2k0#}h8R4JuA zR9iF1>#7YOlB`;jNwTUln`BihPqONQ965J?|DFxm;YwYp1}gQXsuATk$U~J<>P@vn z$*K>!>rfu5HQuEtsaMrvrEXR8mHJi9RO(mNs?@P6 zy*`Fqe|e+l1ePd;tvXsMY}E=StA;5BuUe*LRgF^jsxBp~c9keC-KD&csWgUahmut} zrBPHLC|NaCX&lvNC95VYjilO;rc5*_CMcbydP2$0l$v{AuctFd{_fbiJwt Date: Tue, 10 Nov 2020 14:43:32 +0100 Subject: [PATCH 23/65] Fix function names --- tests/functional/test_multimodel.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 98fd553fec..165140b88b 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -80,7 +80,7 @@ def multi_model_test(cubes, span, statistic): @pytest.mark.functional @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_overlap(timeseries_cubes, span): +def test_multimodel(timeseries_cubes, span): """Test statistic.""" cubes = timeseries_cubes name = 'timeseries' @@ -102,7 +102,7 @@ def test_multimodel_overlap(timeseries_cubes, span): @pytest.mark.functional @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_overlap_without_vertical_dimension(timeseries_cubes, span): +def test_multimodel_without_vertical_dimension(timeseries_cubes, span): """Test statistic without vertical dimension.""" cubes = [cube[0:50, 0] for cube in timeseries_cubes] statistic = 'mean' @@ -111,8 +111,7 @@ def test_multimodel_overlap_without_vertical_dimension(timeseries_cubes, span): @pytest.mark.functional @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_overlap_without_horizontal_dimension( - timeseries_cubes, span): +def test_multimodel_without_horizontal_dimension(timeseries_cubes, span): """Test statistic without horizontal dimension.""" cubes = [cube[0:50, :, 0, 0] for cube in timeseries_cubes] # Coordinate not found error @@ -125,7 +124,7 @@ def test_multimodel_overlap_without_horizontal_dimension( @pytest.mark.functional @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_overlap_only_time_dimension(timeseries_cubes, span): +def test_multimodel_only_time_dimension(timeseries_cubes, span): """Test statistic without only the time dimension.""" cubes = [cube[0:50, 0, 0, 0] for cube in timeseries_cubes] statistic = 'mean' @@ -134,7 +133,7 @@ def test_multimodel_overlap_only_time_dimension(timeseries_cubes, span): @pytest.mark.functional @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_overlap_no_time_dimension(timeseries_cubes, span): +def test_multimodel_no_time_dimension(timeseries_cubes, span): """Test statistic without time dimension.""" cubes = [cube[0] for cube in timeseries_cubes] statistic = 'mean' From 201ef5f27d7f0f3d132b891db4cd0693da8cf7df Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 17 Nov 2020 16:53:05 +0100 Subject: [PATCH 24/65] Rewrite tests --- tests/functional/test_multimodel.py | 164 +++++++++++--------- tests/functional/timeseries-full-mean.nc | Bin 21010 -> 0 bytes tests/functional/timeseries-overlap-mean.nc | Bin 24947 -> 0 bytes 3 files changed, 94 insertions(+), 70 deletions(-) delete mode 100644 tests/functional/timeseries-full-mean.nc delete mode 100644 tests/functional/timeseries-overlap-mean.nc diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 165140b88b..09b83bce0d 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -6,11 +6,7 @@ import numpy as np import pytest -from esmvalcore.preprocessor import ( - extract_levels, - multi_model_statistics, - regrid, -) +from esmvalcore.preprocessor import multi_model_statistics esmvaltool_sample_data = pytest.importorskip("esmvaltool_sample_data") @@ -21,71 +17,49 @@ def preprocess_data(cubes): # regrid to first cube regrid_kwargs = { - 'target_grid': first_cube, - 'scheme': 'linear', - } - extract_kwargs = { - 'levels': [100000.0, 92500.0], - 'scheme': 'linear', + 'grid': first_cube, + 'scheme': iris.analysis.Linear(), } cubes = [cube[t1:t2] for cube in cubes] - cubes = [regrid(cube, **regrid_kwargs) for cube in cubes] - cubes = [extract_levels(cube, **extract_kwargs) for cube in cubes] + cubes = [cube.regrid(**regrid_kwargs) for cube in cubes] return cubes @pytest.fixture -def timeseries_cubes(): +def timeseries_cubes_amon(): """Representative timeseries data.""" - timeseries_cubes = esmvaltool_sample_data.load_timeseries_cubes() + timeseries_cubes = esmvaltool_sample_data.load_timeseries_cubes( + mip_table='Amon') timeseries_cubes = preprocess_data(timeseries_cubes) return timeseries_cubes @pytest.fixture -def map_cubes(): - """Representative map data.""" - map_cubes = esmvaltool_sample_data.load_map_cubes() - map_cubes = preprocess_data(map_cubes) - return map_cubes - - -@pytest.fixture -def profile_cubes(): - """Representative profile data.""" - profile_cubes = esmvaltool_sample_data.load_profile_cubes() - profile_cubes = preprocess_data(profile_cubes) - return profile_cubes +def timeseries_cubes_day(): + """Representative timeseries data.""" + timeseries_cubes = esmvaltool_sample_data.load_timeseries_cubes( + mip_table='day') + timeseries_cubes = preprocess_data(timeseries_cubes) + return timeseries_cubes -def multi_model_test(cubes, span, statistic): +def multimodel_test(cubes, span, statistic): statistics = [statistic] - expected_shape = cubes[0].shape output = multi_model_statistics(cubes, span=span, statistics=statistics) - assert isinstance(output, dict) - assert all(stat in output for stat in statistics) - - output_cube = output[statistic] + return output - # make sure data are not completely masked - assert np.all(output_cube.data.mask == False) # noqa - assert output_cube.shape == expected_shape - return output_cube +def multimodel_regression_test(name, cubes, span): + statistic = 'mean' + output = multimodel_test(cubes, span=span, statistic=statistic) + assert isinstance(output, dict) -@pytest.mark.functional -@pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel(timeseries_cubes, span): - """Test statistic.""" - cubes = timeseries_cubes - name = 'timeseries' - statistic = 'mean' - output_cube = multi_model_test(cubes, span=span, statistic=statistic) + output_cube = output[statistic] # NOTE for the regression test # The following test will fail if the data are changed or if the @@ -95,48 +69,98 @@ def test_multimodel(timeseries_cubes, span): if filename.exists(): expected_cube = iris.load(str(filename))[0] assert np.allclose(output_cube.data, expected_cube.data) - else: - iris.save(output_cube, filename) - raise RuntimeError(f'Wrote file {filename.absolute()}') + # else: + # iris.save(output_cube, filename) + # raise RuntimeError(f'Wrote file {filename.absolute()}') + + +@pytest.mark.functional +@pytest.mark.parametrize( + 'span', + ( + pytest.param( + 'overlap', + marks=pytest.mark.xfail( + reason= + '`BUG: multimodel_statistics returns `list` instead of `dict`') + ), + # 'overlap', + 'full', + )) +def test_multimodel_regression_amon(timeseries_cubes_amon, span): + """Test statistic.""" + cubes = timeseries_cubes_amon + name = 'timeseries' + multimodel_regression_test( + name=name, + cubes=cubes, + span=span, + ) + + +@pytest.mark.functional +@pytest.mark.parametrize( + 'span', + ( + pytest.param( + 'overlap', + marks=pytest.mark.xfail( + reason= + '`BUG: multimodel_statistics returns `list` instead of `dict`') + ), + # 'overlap', + 'full', + )) +def test_multimodel_regression_day(timeseries_cubes_day, span): + """Test statistic.""" + cubes = timeseries_cubes_day + name = 'timeseries' + multimodel_regression_test( + name=name, + cubes=cubes, + span=span, + ) @pytest.mark.functional +@pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_without_vertical_dimension(timeseries_cubes, span): +def test_multimodel_without_vertical_dimension(timeseries_cubes_amon, span): """Test statistic without vertical dimension.""" - cubes = [cube[0:50, 0] for cube in timeseries_cubes] - statistic = 'mean' - multi_model_test(cubes, span=span, statistic=statistic) + cubes = timeseries_cubes_amon + cubes = [cube[0:50, 0] for cube in cubes] + multimodel_test(cubes, span=span, statistic='mean') @pytest.mark.functional +@pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_without_horizontal_dimension(timeseries_cubes, span): +def test_multimodel_without_horizontal_dimension(timeseries_cubes_amon, span): """Test statistic without horizontal dimension.""" - cubes = [cube[0:50, :, 0, 0] for cube in timeseries_cubes] + cubes = timeseries_cubes_amon + cubes = [cube[0:50, :, 0, 0] for cube in cubes] # Coordinate not found error - statistic = 'mean' - with pytest.raises(iris.exceptions.CoordinateNotFoundError): - # iris.exceptions.CoordinateNotFoundError: - # 'Expected to find exactly 1 depth coordinate, but found none.' - multi_model_test(cubes, span=span, statistic=statistic) + # iris.exceptions.CoordinateNotFoundError: + # 'Expected to find exactly 1 depth coordinate, but found none.' + multimodel_test(cubes, span=span, statistic='mean') @pytest.mark.functional +@pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_only_time_dimension(timeseries_cubes, span): +def test_multimodel_only_time_dimension(timeseries_cubes_amon, span): """Test statistic without only the time dimension.""" - cubes = [cube[0:50, 0, 0, 0] for cube in timeseries_cubes] - statistic = 'mean' - multi_model_test(cubes, span=span, statistic=statistic) + cubes = timeseries_cubes_amon + cubes = [cube[0:50, 0, 0, 0] for cube in cubes] + multimodel_test(cubes, span=span, statistic='mean') @pytest.mark.functional +@pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_no_time_dimension(timeseries_cubes, span): +def test_multimodel_no_time_dimension(timeseries_cubes_amon, span): """Test statistic without time dimension.""" - cubes = [cube[0] for cube in timeseries_cubes] - statistic = 'mean' - with pytest.raises(ValueError): - # ValueError: Cannot guess bounds for a coordinate of length 1. - multi_model_test(cubes, span=span, statistic=statistic) + cubes = timeseries_cubes_amon + cubes = [cube[0] for cube in cubes] + # ValueError: Cannot guess bounds for a coordinate of length 1. + multimodel_test(cubes, span=span, statistic='mean') diff --git a/tests/functional/timeseries-full-mean.nc b/tests/functional/timeseries-full-mean.nc deleted file mode 100644 index acc00ef7b14261e08365549cf617f6bb0d6d69b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21010 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 diff --git a/tests/functional/timeseries-overlap-mean.nc b/tests/functional/timeseries-overlap-mean.nc deleted file mode 100644 index c490e344ac650333baa6ec9114c87eba08193bd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24947 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 From 61d277813103e608f12b6f136462239499002717 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 17 Nov 2020 17:22:04 +0100 Subject: [PATCH 25/65] Add debug comment --- tests/functional/test_multimodel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 09b83bce0d..5f17c0eee8 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -57,6 +57,7 @@ def multimodel_regression_test(name, cubes, span): statistic = 'mean' output = multimodel_test(cubes, span=span, statistic=statistic) + # this fails for span='overlap', for which `output == cubes` (???) assert isinstance(output, dict) output_cube = output[statistic] From 03f3b06c2193e39d6e83e264df281a12de0d66ae Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 17 Nov 2020 17:22:14 +0100 Subject: [PATCH 26/65] Rename variables --- tests/functional/test_multimodel.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 5f17c0eee8..ef6b31e14c 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -30,19 +30,19 @@ def preprocess_data(cubes): @pytest.fixture def timeseries_cubes_amon(): """Representative timeseries data.""" - timeseries_cubes = esmvaltool_sample_data.load_timeseries_cubes( + cubes = esmvaltool_sample_data.load_timeseries_cubes( mip_table='Amon') - timeseries_cubes = preprocess_data(timeseries_cubes) - return timeseries_cubes + cubes = preprocess_data(cubes) + return cubes @pytest.fixture def timeseries_cubes_day(): """Representative timeseries data.""" - timeseries_cubes = esmvaltool_sample_data.load_timeseries_cubes( + cubes = esmvaltool_sample_data.load_timeseries_cubes( mip_table='day') - timeseries_cubes = preprocess_data(timeseries_cubes) - return timeseries_cubes + cubes = preprocess_data(cubes) + return cubes def multimodel_test(cubes, span, statistic): From dd7e4dc8882b7e81f72ca4a4e46d26f0a78044a1 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 18 Nov 2020 09:37:20 +0100 Subject: [PATCH 27/65] Update `multimodel_statistics` docstring to reflect current behaviour --- esmvalcore/preprocessor/_multimodel.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/esmvalcore/preprocessor/_multimodel.py b/esmvalcore/preprocessor/_multimodel.py index 399839cf00..e4b58f4241 100644 --- a/esmvalcore/preprocessor/_multimodel.py +++ b/esmvalcore/preprocessor/_multimodel.py @@ -357,8 +357,7 @@ def _assemble_full_data(cubes, statistic): def multi_model_statistics(products, span, statistics, output_products=None): - """ - Compute multi-model statistics. + """Compute multi-model statistics. Multimodel statistics computed along the time axis. Can be computed across a common overlap in time (set span: overlap) @@ -383,22 +382,27 @@ def multi_model_statistics(products, span, statistics, output_products=None): span; if full, statistics are computed on full time spans, ignoring missing data. output_products: dict - dictionary of output products. - statistics: list - statistical measure to be computed. Available options: mean, median, - max, min, std, or pXX.YY (for percentile XX.YY; decimal part optional). + dictionary of output products. MUST be specified if products are NOT + cubes + statistics: list of str + list of statistical measure(s) to be computed. Available options: + mean, median, max, min, std, or pXX.YY (for percentile XX.YY; decimal + part optional). Returns ------- - list or dict - list data products or dict of cubes containing the multimodel stats - computed. + set or dict or list + Either: + - `set` of data products if `output_products` is given + - `dict` of cubes if `output_products` is not given + containing the multimodel stats computed or: + - `list` of input cubes if there is no overlap between cubes when + using `span='overlap'` Raises ------ ValueError If span is neither overlap nor full. - """ logger.debug('Multimodel statistics: computing: %s', statistics) if len(products) < 2: From 09b0a53b4cedf84061320365a0edee0e270ebfa1 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 13:47:13 +0100 Subject: [PATCH 28/65] Group daily data by calendar Multimodel statistics is known to yield incorrect output with mixed calendars --- tests/functional/test_multimodel.py | 42 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index ef6b31e14c..11c3811280 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -5,6 +5,7 @@ import iris import numpy as np import pytest +from itertools import groupby from esmvalcore.preprocessor import multi_model_statistics @@ -53,7 +54,7 @@ def multimodel_test(cubes, span, statistic): return output -def multimodel_regression_test(name, cubes, span): +def multimodel_regression_test(cubes, span, name): statistic = 'mean' output = multimodel_test(cubes, span=span, statistic=statistic) @@ -79,13 +80,7 @@ def multimodel_regression_test(name, cubes, span): @pytest.mark.parametrize( 'span', ( - pytest.param( - 'overlap', - marks=pytest.mark.xfail( - reason= - '`BUG: multimodel_statistics returns `list` instead of `dict`') - ), - # 'overlap', + 'overlap', 'full', )) def test_multimodel_regression_amon(timeseries_cubes_amon, span): @@ -94,8 +89,8 @@ def test_multimodel_regression_amon(timeseries_cubes_amon, span): name = 'timeseries' multimodel_regression_test( name=name, - cubes=cubes, span=span, + cubes=cubes, ) @@ -103,24 +98,27 @@ def test_multimodel_regression_amon(timeseries_cubes_amon, span): @pytest.mark.parametrize( 'span', ( - pytest.param( - 'overlap', - marks=pytest.mark.xfail( - reason= - '`BUG: multimodel_statistics returns `list` instead of `dict`') - ), - # 'overlap', + 'overlap', 'full', )) def test_multimodel_regression_day(timeseries_cubes_day, span): """Test statistic.""" cubes = timeseries_cubes_day - name = 'timeseries' - multimodel_regression_test( - name=name, - cubes=cubes, - span=span, - ) + + def calendar(cube): + return cube.coord('time').units.calendar + + # groupby requires sorted list + grouped = groupby(sorted(cubes, key=calendar), key=calendar) + + for key, cube_group in grouped: + cube_group = list(cube_group) + name = f'timeseries_{key}' + multimodel_regression_test( + name=name, + span=span, + cubes=cube_group, + ) @pytest.mark.functional From 3309bdbf116b637ff14081bf72424ffa49f924cd Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 13:48:18 +0100 Subject: [PATCH 29/65] Add extract time and caching to speed up tests --- tests/functional/test_multimodel.py | 84 ++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 11c3811280..e74b0c88cd 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -1,20 +1,25 @@ """Functional test for :func:`esmvalcore.preprocessor._multimodel`.""" +from itertools import groupby from pathlib import Path import iris import numpy as np import pytest -from itertools import groupby -from esmvalcore.preprocessor import multi_model_statistics +from esmvalcore.preprocessor import extract_time, multi_model_statistics esmvaltool_sample_data = pytest.importorskip("esmvaltool_sample_data") +CACHE_FILES = True + + +def preprocess_data(cubes, time_slice: dict = None): + """Regrid the data to the first cube and optional time-slicing.""" + if time_slice: + cubes = [extract_time(cube, **time_slice) for cube in cubes] -def preprocess_data(cubes): first_cube = cubes[0] - t1, t2 = 0, 50 # time-slicing first N items # regrid to first cube regrid_kwargs = { @@ -22,27 +27,60 @@ def preprocess_data(cubes): 'scheme': iris.analysis.Linear(), } - cubes = [cube[t1:t2] for cube in cubes] cubes = [cube.regrid(**regrid_kwargs) for cube in cubes] return cubes -@pytest.fixture +@pytest.fixture(scope="module") def timeseries_cubes_amon(): """Representative timeseries data.""" - cubes = esmvaltool_sample_data.load_timeseries_cubes( - mip_table='Amon') - cubes = preprocess_data(cubes) + + if CACHE_FILES: + filename = Path(__file__).with_name('monthly.nc') + if filename.exists(): + return iris.load(str(filename)) + + time_slice = { + 'start_year': 1985, + 'end_year': 1986, + 'start_month': 12, + 'end_month': 1, + 'start_day': 1, + 'end_day': 30, + } + cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='Amon') + cubes = preprocess_data(cubes, time_slice=time_slice) + + if CACHE_FILES: + iris.save(cubes, filename) + return cubes -@pytest.fixture +@pytest.fixture(scope="module") def timeseries_cubes_day(): """Representative timeseries data.""" - cubes = esmvaltool_sample_data.load_timeseries_cubes( - mip_table='day') - cubes = preprocess_data(cubes) + + if CACHE_FILES: + filename = Path(__file__).with_name('daily.nc') + if filename.exists(): + return iris.load(str(filename)) + + time_slice = { + 'start_year': 2001, + 'end_year': 2002, + 'start_month': 12, + 'end_month': 1, + 'start_day': 1, + 'end_day': 30, + } + cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='day') + cubes = preprocess_data(cubes, time_slice=time_slice) + + if CACHE_FILES: + iris.save(cubes, filename) + return cubes @@ -77,12 +115,10 @@ def multimodel_regression_test(cubes, span, name): @pytest.mark.functional -@pytest.mark.parametrize( - 'span', - ( - 'overlap', - 'full', - )) +@pytest.mark.parametrize('span', ( + 'overlap', + 'full', +)) def test_multimodel_regression_amon(timeseries_cubes_amon, span): """Test statistic.""" cubes = timeseries_cubes_amon @@ -95,12 +131,10 @@ def test_multimodel_regression_amon(timeseries_cubes_amon, span): @pytest.mark.functional -@pytest.mark.parametrize( - 'span', - ( - 'overlap', - 'full', - )) +@pytest.mark.parametrize('span', ( + 'overlap', + 'full', +)) def test_multimodel_regression_day(timeseries_cubes_day, span): """Test statistic.""" cubes = timeseries_cubes_day From 8f268f143e205b0586c3c4f58924f192168efac3 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 14:00:42 +0100 Subject: [PATCH 30/65] Implement regression tests for grouped daily data --- tests/functional/test_multimodel.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index e74b0c88cd..73958589e9 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -88,6 +88,8 @@ def multimodel_test(cubes, span, statistic): statistics = [statistic] output = multi_model_statistics(cubes, span=span, statistics=statistics) + assert isinstance(output, dict) + assert statistic in output return output @@ -95,10 +97,6 @@ def multimodel_test(cubes, span, statistic): def multimodel_regression_test(cubes, span, name): statistic = 'mean' output = multimodel_test(cubes, span=span, statistic=statistic) - - # this fails for span='overlap', for which `output == cubes` (???) - assert isinstance(output, dict) - output_cube = output[statistic] # NOTE for the regression test @@ -109,9 +107,9 @@ def multimodel_regression_test(cubes, span, name): if filename.exists(): expected_cube = iris.load(str(filename))[0] assert np.allclose(output_cube.data, expected_cube.data) - # else: - # iris.save(output_cube, filename) - # raise RuntimeError(f'Wrote file {filename.absolute()}') + else: + iris.save(output_cube, filename) + raise RuntimeError(f'Wrote file {filename.absolute()}') @pytest.mark.functional @@ -122,7 +120,7 @@ def multimodel_regression_test(cubes, span, name): def test_multimodel_regression_amon(timeseries_cubes_amon, span): """Test statistic.""" cubes = timeseries_cubes_amon - name = 'timeseries' + name = 'timeseries_monthly' multimodel_regression_test( name=name, span=span, @@ -147,7 +145,13 @@ def calendar(cube): for key, cube_group in grouped: cube_group = list(cube_group) - name = f'timeseries_{key}' + + # skip groups with 1 member + if len(cube_group) <= 1: + print('skipping', key) + continue + + name = f'timeseries_daily_{key}' multimodel_regression_test( name=name, span=span, From 6493565d3cbed1e0b79fccadc5b7dfe35fde4f71 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 14:04:01 +0100 Subject: [PATCH 31/65] Rename _amon -> _month --- tests/functional/test_multimodel.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 73958589e9..d9ba31c19a 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -33,7 +33,7 @@ def preprocess_data(cubes, time_slice: dict = None): @pytest.fixture(scope="module") -def timeseries_cubes_amon(): +def timeseries_cubes_month(): """Representative timeseries data.""" if CACHE_FILES: @@ -117,9 +117,9 @@ def multimodel_regression_test(cubes, span, name): 'overlap', 'full', )) -def test_multimodel_regression_amon(timeseries_cubes_amon, span): +def test_multimodel_regression_month(timeseries_cubes_month, span): """Test statistic.""" - cubes = timeseries_cubes_amon + cubes = timeseries_cubes_month name = 'timeseries_monthly' multimodel_regression_test( name=name, @@ -162,9 +162,9 @@ def calendar(cube): @pytest.mark.functional @pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_without_vertical_dimension(timeseries_cubes_amon, span): +def test_multimodel_without_vertical_dimension(timeseries_cubes_month, span): """Test statistic without vertical dimension.""" - cubes = timeseries_cubes_amon + cubes = timeseries_cubes_month cubes = [cube[0:50, 0] for cube in cubes] multimodel_test(cubes, span=span, statistic='mean') @@ -172,9 +172,9 @@ def test_multimodel_without_vertical_dimension(timeseries_cubes_amon, span): @pytest.mark.functional @pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_without_horizontal_dimension(timeseries_cubes_amon, span): +def test_multimodel_without_horizontal_dimension(timeseries_cubes_month, span): """Test statistic without horizontal dimension.""" - cubes = timeseries_cubes_amon + cubes = timeseries_cubes_month cubes = [cube[0:50, :, 0, 0] for cube in cubes] # Coordinate not found error # iris.exceptions.CoordinateNotFoundError: @@ -185,9 +185,9 @@ def test_multimodel_without_horizontal_dimension(timeseries_cubes_amon, span): @pytest.mark.functional @pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_only_time_dimension(timeseries_cubes_amon, span): +def test_multimodel_only_time_dimension(timeseries_cubes_month, span): """Test statistic without only the time dimension.""" - cubes = timeseries_cubes_amon + cubes = timeseries_cubes_month cubes = [cube[0:50, 0, 0, 0] for cube in cubes] multimodel_test(cubes, span=span, statistic='mean') @@ -195,9 +195,9 @@ def test_multimodel_only_time_dimension(timeseries_cubes_amon, span): @pytest.mark.functional @pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_no_time_dimension(timeseries_cubes_amon, span): +def test_multimodel_no_time_dimension(timeseries_cubes_month, span): """Test statistic without time dimension.""" - cubes = timeseries_cubes_amon + cubes = timeseries_cubes_month cubes = [cube[0] for cube in cubes] # ValueError: Cannot guess bounds for a coordinate of length 1. multimodel_test(cubes, span=span, statistic='mean') From 3f018615fd5320aacb8732d5863319e5ca368174 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 14:16:45 +0100 Subject: [PATCH 32/65] Update tests with special cases --- tests/functional/test_multimodel.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index d9ba31c19a..cd7eb47761 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -43,7 +43,7 @@ def timeseries_cubes_month(): time_slice = { 'start_year': 1985, - 'end_year': 1986, + 'end_year': 1987, 'start_month': 12, 'end_month': 1, 'start_day': 1, @@ -160,9 +160,8 @@ def calendar(cube): @pytest.mark.functional -@pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_without_vertical_dimension(timeseries_cubes_month, span): +def test_multimodel_month_no_vertical_dimension(timeseries_cubes_month, span): """Test statistic without vertical dimension.""" cubes = timeseries_cubes_month cubes = [cube[0:50, 0] for cube in cubes] @@ -170,12 +169,13 @@ def test_multimodel_without_vertical_dimension(timeseries_cubes_month, span): @pytest.mark.functional -@pytest.mark.skip('Fix problems with `multimodel_statistics` first') +@pytest.mark.xfail('iris.exceptions.CoordinateNotFoundError') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_without_horizontal_dimension(timeseries_cubes_month, span): +def test_multimodel_month_no_horizontal_dimension(timeseries_cubes_month, + span): """Test statistic without horizontal dimension.""" cubes = timeseries_cubes_month - cubes = [cube[0:50, :, 0, 0] for cube in cubes] + cubes = [cube[:, :, 0, 0] for cube in cubes] # Coordinate not found error # iris.exceptions.CoordinateNotFoundError: # 'Expected to find exactly 1 depth coordinate, but found none.' @@ -183,19 +183,19 @@ def test_multimodel_without_horizontal_dimension(timeseries_cubes_month, span): @pytest.mark.functional -@pytest.mark.skip('Fix problems with `multimodel_statistics` first') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_only_time_dimension(timeseries_cubes_month, span): +def test_multimodel_month_only_time_dimension(timeseries_cubes_month, span): """Test statistic without only the time dimension.""" cubes = timeseries_cubes_month - cubes = [cube[0:50, 0, 0, 0] for cube in cubes] + cubes = [cube[:, 0, 0, 0] for cube in cubes] multimodel_test(cubes, span=span, statistic='mean') @pytest.mark.functional -@pytest.mark.skip('Fix problems with `multimodel_statistics` first') +@pytest.mark.xfail( + 'ValueError: Cannot guess bounds for a coordinate of length 1.') @pytest.mark.parametrize('span', ('overlap', 'full')) -def test_multimodel_no_time_dimension(timeseries_cubes_month, span): +def test_multimodel_month_no_time_dimension(timeseries_cubes_month, span): """Test statistic without time dimension.""" cubes = timeseries_cubes_month cubes = [cube[0] for cube in cubes] From d2403bba3c01b3d8b06af1bfc26a93026749442e Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 14:54:15 +0100 Subject: [PATCH 33/65] Add special cases for daily tests --- tests/functional/test_multimodel.py | 149 +++++++++++++++++++--------- 1 file changed, 104 insertions(+), 45 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index cd7eb47761..75b8508771 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -13,6 +13,22 @@ CACHE_FILES = True +CALENDAR_PARAMS = ( + pytest.param( + '360_day', + marks=pytest.mark.xfail( + reason='Cannot calculate statistics with single cube in list')), + '365_day', + 'gregorian', + 'proleptic_gregorian', + pytest.param( + 'julian', + marks=pytest.mark.xfail( + reason='Cannot calculate statistics with single cube in list')), +) + +SPAN_PARAMS = ('overlap', 'full') + def preprocess_data(cubes, time_slice: dict = None): """Regrid the data to the first cube and optional time-slicing.""" @@ -60,28 +76,36 @@ def timeseries_cubes_month(): @pytest.fixture(scope="module") def timeseries_cubes_day(): - """Representative timeseries data.""" + """Representative timeseries data sorted by calendar.""" if CACHE_FILES: filename = Path(__file__).with_name('daily.nc') if filename.exists(): - return iris.load(str(filename)) + cubes = iris.load(str(filename)) + else: + time_slice = { + 'start_year': 2001, + 'end_year': 2002, + 'start_month': 12, + 'end_month': 1, + 'start_day': 1, + 'end_day': 30, + } + cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='day') + cubes = preprocess_data(cubes, time_slice=time_slice) + + if CACHE_FILES: + iris.save(cubes, filename) - time_slice = { - 'start_year': 2001, - 'end_year': 2002, - 'start_month': 12, - 'end_month': 1, - 'start_day': 1, - 'end_day': 30, - } - cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='day') - cubes = preprocess_data(cubes, time_slice=time_slice) + def calendar(cube): + return cube.coord('time').units.calendar - if CACHE_FILES: - iris.save(cubes, filename) + # groupby requires sorted list + grouped = groupby(sorted(cubes, key=calendar), key=calendar) - return cubes + cube_dict = {key: list(group) for key, group in grouped} + + return cube_dict def multimodel_test(cubes, span, statistic): @@ -129,48 +153,34 @@ def test_multimodel_regression_month(timeseries_cubes_month, span): @pytest.mark.functional +@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) @pytest.mark.parametrize('span', ( 'overlap', 'full', )) -def test_multimodel_regression_day(timeseries_cubes_day, span): +def test_multimodel_regression_day(timeseries_cubes_day, span, calendar): """Test statistic.""" - cubes = timeseries_cubes_day - - def calendar(cube): - return cube.coord('time').units.calendar - - # groupby requires sorted list - grouped = groupby(sorted(cubes, key=calendar), key=calendar) - - for key, cube_group in grouped: - cube_group = list(cube_group) - - # skip groups with 1 member - if len(cube_group) <= 1: - print('skipping', key) - continue - - name = f'timeseries_daily_{key}' - multimodel_regression_test( - name=name, - span=span, - cubes=cube_group, - ) + cubes = timeseries_cubes_day[calendar] + name = f'timeseries_daily_{calendar}' + multimodel_regression_test( + name=name, + span=span, + cubes=cubes, + ) @pytest.mark.functional -@pytest.mark.parametrize('span', ('overlap', 'full')) +@pytest.mark.parametrize('span', SPAN_PARAMS) def test_multimodel_month_no_vertical_dimension(timeseries_cubes_month, span): """Test statistic without vertical dimension.""" cubes = timeseries_cubes_month - cubes = [cube[0:50, 0] for cube in cubes] + cubes = [cube[:, 0] for cube in cubes] multimodel_test(cubes, span=span, statistic='mean') @pytest.mark.functional @pytest.mark.xfail('iris.exceptions.CoordinateNotFoundError') -@pytest.mark.parametrize('span', ('overlap', 'full')) +@pytest.mark.parametrize('span', SPAN_PARAMS) def test_multimodel_month_no_horizontal_dimension(timeseries_cubes_month, span): """Test statistic without horizontal dimension.""" @@ -183,7 +193,7 @@ def test_multimodel_month_no_horizontal_dimension(timeseries_cubes_month, @pytest.mark.functional -@pytest.mark.parametrize('span', ('overlap', 'full')) +@pytest.mark.parametrize('span', SPAN_PARAMS) def test_multimodel_month_only_time_dimension(timeseries_cubes_month, span): """Test statistic without only the time dimension.""" cubes = timeseries_cubes_month @@ -192,12 +202,61 @@ def test_multimodel_month_only_time_dimension(timeseries_cubes_month, span): @pytest.mark.functional -@pytest.mark.xfail( - 'ValueError: Cannot guess bounds for a coordinate of length 1.') -@pytest.mark.parametrize('span', ('overlap', 'full')) +@pytest.mark.xfail('ValueError') +@pytest.mark.parametrize('span', SPAN_PARAMS) def test_multimodel_month_no_time_dimension(timeseries_cubes_month, span): """Test statistic without time dimension.""" cubes = timeseries_cubes_month cubes = [cube[0] for cube in cubes] # ValueError: Cannot guess bounds for a coordinate of length 1. multimodel_test(cubes, span=span, statistic='mean') + + +@pytest.mark.functional +@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) +@pytest.mark.parametrize('span', SPAN_PARAMS) +def test_multimodel_day_no_vertical_dimension(timeseries_cubes_day, span, + calendar): + """Test statistic without vertical dimension.""" + cubes = timeseries_cubes_day[calendar] + cubes = [cube[:, 0] for cube in cubes] + multimodel_test(cubes, span=span, statistic='mean') + + +@pytest.mark.functional +@pytest.mark.xfail('iris.exceptions.CoordinateNotFoundError') +@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) +@pytest.mark.parametrize('span', SPAN_PARAMS) +def test_multimodel_day_no_horizontal_dimension(timeseries_cubes_day, span, + calendar): + """Test statistic without horizontal dimension.""" + cubes = timeseries_cubes_day[calendar] + cubes = [cube[:, :, 0, 0] for cube in cubes] + # Coordinate not found error + # iris.exceptions.CoordinateNotFoundError: + # 'Expected to find exactly 1 depth coordinate, but found none.' + multimodel_test(cubes, span=span, statistic='mean') + + +@pytest.mark.functional +@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) +@pytest.mark.parametrize('span', SPAN_PARAMS) +def test_multimodel_day_only_time_dimension(timeseries_cubes_day, span, + calendar): + """Test statistic without only the time dimension.""" + cubes = timeseries_cubes_day[calendar] + cubes = [cube[:, 0, 0, 0] for cube in cubes] + multimodel_test(cubes, span=span, statistic='mean') + + +@pytest.mark.functional +@pytest.mark.xfail('ValueError') +@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) +@pytest.mark.parametrize('span', SPAN_PARAMS) +def test_multimodel_day_no_time_dimension(timeseries_cubes_day, span, + calendar): + """Test statistic without time dimension.""" + cubes = timeseries_cubes_day[calendar] + cubes = [cube[0] for cube in cubes] + # ValueError: Cannot guess bounds for a coordinate of length 1. + multimodel_test(cubes, span=span, statistic='mean') From 71cf40cae8007c8a05cf9b7f5907ff84920e56b2 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 15:14:57 +0100 Subject: [PATCH 34/65] Remove redundant tests Most issues are already covered by the other tests --- tests/functional/test_multimodel.py | 85 +++++------------------------ 1 file changed, 14 insertions(+), 71 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 75b8508771..e058a76042 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -137,10 +137,7 @@ def multimodel_regression_test(cubes, span, name): @pytest.mark.functional -@pytest.mark.parametrize('span', ( - 'overlap', - 'full', -)) +@pytest.mark.parametrize('span', SPAN_PARAMS) def test_multimodel_regression_month(timeseries_cubes_month, span): """Test statistic.""" cubes = timeseries_cubes_month @@ -154,10 +151,7 @@ def test_multimodel_regression_month(timeseries_cubes_month, span): @pytest.mark.functional @pytest.mark.parametrize('calendar', CALENDAR_PARAMS) -@pytest.mark.parametrize('span', ( - 'overlap', - 'full', -)) +@pytest.mark.parametrize('span', SPAN_PARAMS) def test_multimodel_regression_day(timeseries_cubes_day, span, calendar): """Test statistic.""" cubes = timeseries_cubes_day[calendar] @@ -170,9 +164,9 @@ def test_multimodel_regression_day(timeseries_cubes_day, span, calendar): @pytest.mark.functional -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_month_no_vertical_dimension(timeseries_cubes_month, span): - """Test statistic without vertical dimension.""" +def test_multimodel_no_vertical_dimension(timeseries_cubes_month): + """Test statistic without vertical dimension using monthly data.""" + span = 'full' cubes = timeseries_cubes_month cubes = [cube[:, 0] for cube in cubes] multimodel_test(cubes, span=span, statistic='mean') @@ -180,10 +174,9 @@ def test_multimodel_month_no_vertical_dimension(timeseries_cubes_month, span): @pytest.mark.functional @pytest.mark.xfail('iris.exceptions.CoordinateNotFoundError') -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_month_no_horizontal_dimension(timeseries_cubes_month, - span): - """Test statistic without horizontal dimension.""" +def test_multimodel_no_horizontal_dimension(timeseries_cubes_month): + """Test statistic without horizontal dimension using monthly data.""" + span = 'full' cubes = timeseries_cubes_month cubes = [cube[:, :, 0, 0] for cube in cubes] # Coordinate not found error @@ -193,70 +186,20 @@ def test_multimodel_month_no_horizontal_dimension(timeseries_cubes_month, @pytest.mark.functional -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_month_only_time_dimension(timeseries_cubes_month, span): - """Test statistic without only the time dimension.""" +def test_multimodel_only_time_dimension(timeseries_cubes_month): + """Test statistic without only the time dimension using monthly data.""" cubes = timeseries_cubes_month + span = 'full' cubes = [cube[:, 0, 0, 0] for cube in cubes] multimodel_test(cubes, span=span, statistic='mean') @pytest.mark.functional @pytest.mark.xfail('ValueError') -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_month_no_time_dimension(timeseries_cubes_month, span): - """Test statistic without time dimension.""" +def test_multimodel_no_time_dimension(timeseries_cubes_month): + """Test statistic without time dimension using monthly data.""" + span = 'full' cubes = timeseries_cubes_month cubes = [cube[0] for cube in cubes] # ValueError: Cannot guess bounds for a coordinate of length 1. multimodel_test(cubes, span=span, statistic='mean') - - -@pytest.mark.functional -@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_day_no_vertical_dimension(timeseries_cubes_day, span, - calendar): - """Test statistic without vertical dimension.""" - cubes = timeseries_cubes_day[calendar] - cubes = [cube[:, 0] for cube in cubes] - multimodel_test(cubes, span=span, statistic='mean') - - -@pytest.mark.functional -@pytest.mark.xfail('iris.exceptions.CoordinateNotFoundError') -@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_day_no_horizontal_dimension(timeseries_cubes_day, span, - calendar): - """Test statistic without horizontal dimension.""" - cubes = timeseries_cubes_day[calendar] - cubes = [cube[:, :, 0, 0] for cube in cubes] - # Coordinate not found error - # iris.exceptions.CoordinateNotFoundError: - # 'Expected to find exactly 1 depth coordinate, but found none.' - multimodel_test(cubes, span=span, statistic='mean') - - -@pytest.mark.functional -@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_day_only_time_dimension(timeseries_cubes_day, span, - calendar): - """Test statistic without only the time dimension.""" - cubes = timeseries_cubes_day[calendar] - cubes = [cube[:, 0, 0, 0] for cube in cubes] - multimodel_test(cubes, span=span, statistic='mean') - - -@pytest.mark.functional -@pytest.mark.xfail('ValueError') -@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_day_no_time_dimension(timeseries_cubes_day, span, - calendar): - """Test statistic without time dimension.""" - cubes = timeseries_cubes_day[calendar] - cubes = [cube[0] for cube in cubes] - # ValueError: Cannot guess bounds for a coordinate of length 1. - multimodel_test(cubes, span=span, statistic='mean') From a327af3a24537f1ce6f29b9ce6bfaa3bc72238d9 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 15:15:15 +0100 Subject: [PATCH 35/65] Tweak time slices to include entire last month --- tests/functional/test_multimodel.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index e058a76042..d008760dc3 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -61,9 +61,9 @@ def timeseries_cubes_month(): 'start_year': 1985, 'end_year': 1987, 'start_month': 12, - 'end_month': 1, + 'end_month': 2, 'start_day': 1, - 'end_day': 30, + 'end_day': 1, } cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='Amon') cubes = preprocess_data(cubes, time_slice=time_slice) @@ -87,9 +87,9 @@ def timeseries_cubes_day(): 'start_year': 2001, 'end_year': 2002, 'start_month': 12, - 'end_month': 1, + 'end_month': 2, 'start_day': 1, - 'end_day': 30, + 'end_day': 1, } cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='day') cubes = preprocess_data(cubes, time_slice=time_slice) From 8b67e2715cc7980ed1b9d67153cc253f4e462784 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 15:22:59 +0100 Subject: [PATCH 36/65] Fix cache for daily data --- tests/functional/test_multimodel.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index d008760dc3..4186997792 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -78,11 +78,14 @@ def timeseries_cubes_month(): def timeseries_cubes_day(): """Representative timeseries data sorted by calendar.""" + get_cubes = True if CACHE_FILES: filename = Path(__file__).with_name('daily.nc') if filename.exists(): cubes = iris.load(str(filename)) - else: + get_cubes = False + + if get_cubes: time_slice = { 'start_year': 2001, 'end_year': 2002, From e9533fd183e8f18869ac80553ba5ab5303849b11 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 15:46:07 +0100 Subject: [PATCH 37/65] Compare cube metadata for regression test --- tests/functional/test_multimodel.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 4186997792..512a00345e 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -11,7 +11,7 @@ esmvaltool_sample_data = pytest.importorskip("esmvaltool_sample_data") -CACHE_FILES = True +CACHE_FILES = False CALENDAR_PARAMS = ( pytest.param( @@ -76,7 +76,7 @@ def timeseries_cubes_month(): @pytest.fixture(scope="module") def timeseries_cubes_day(): - """Representative timeseries data sorted by calendar.""" + """Representative timeseries data grouped by calendar.""" get_cubes = True if CACHE_FILES: @@ -134,6 +134,11 @@ def multimodel_regression_test(cubes, span, name): if filename.exists(): expected_cube = iris.load(str(filename))[0] assert np.allclose(output_cube.data, expected_cube.data) + assert expected_cube.coords() == output_cube.coords() + # remove Conventions which are added by Iris on save + output_cube.attributes.pop('Conventions') + assert expected_cube.metadata == output_cube.metadata + else: iris.save(output_cube, filename) raise RuntimeError(f'Wrote file {filename.absolute()}') From 270f33d007d98c5ff85e91bbe12daab5a9f9824b Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 15:46:42 +0100 Subject: [PATCH 38/65] Fix url sample data repo --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b82b2aa4f2..c17805b33e 100755 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ 'pytest-metadata>=1.5.1', 'pytest-mock', 'pytest-xdist', - 'ESMValTool_sample_data @ git+https://github.com/ESMValGroup/ESMValTool_sample_data@make_package', # noqa + 'ESMValTool_sample_data @ git+https://github.com/ESMValGroup/ESMValTool_sample_data@master', # noqa ], # Development dependencies # Use pip install -e .[develop] to install in development mode From dfd108f4985ee611972800a1c9f7f5380ed3e678 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Fri, 27 Nov 2020 15:57:45 +0100 Subject: [PATCH 39/65] Mark some tests as skip instead of xfail --- tests/functional/test_multimodel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 512a00345e..1ff5d4e68f 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -16,14 +16,14 @@ CALENDAR_PARAMS = ( pytest.param( '360_day', - marks=pytest.mark.xfail( + marks=pytest.mark.skip( reason='Cannot calculate statistics with single cube in list')), '365_day', 'gregorian', 'proleptic_gregorian', pytest.param( 'julian', - marks=pytest.mark.xfail( + marks=pytest.mark.skip( reason='Cannot calculate statistics with single cube in list')), ) From 472a4e94a0e7ce3452d5f3b2d215e3fc63b93767 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 30 Nov 2020 15:20:58 +0100 Subject: [PATCH 40/65] Use pytest's caching mechanism for loading the data This saves about 30-60 seconds. Cubes are not natively serializable via json, so we must go via pickle and decode to a string object. --- tests/functional/test_multimodel.py | 59 +++++++++++++++-------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 1ff5d4e68f..df18b0af8d 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -1,5 +1,6 @@ """Functional test for :func:`esmvalcore.preprocessor._multimodel`.""" +import pickle from itertools import groupby from pathlib import Path @@ -49,43 +50,44 @@ def preprocess_data(cubes, time_slice: dict = None): @pytest.fixture(scope="module") -def timeseries_cubes_month(): +def timeseries_cubes_month(request): """Representative timeseries data.""" - if CACHE_FILES: - filename = Path(__file__).with_name('monthly.nc') - if filename.exists(): - return iris.load(str(filename)) - - time_slice = { - 'start_year': 1985, - 'end_year': 1987, - 'start_month': 12, - 'end_month': 2, - 'start_day': 1, - 'end_day': 1, - } - cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='Amon') - cubes = preprocess_data(cubes, time_slice=time_slice) + # cache the cubes to save about 30-60 seconds on repeat use + data = request.config.cache.get("functional/monthly", None) + + if data: + cubes = pickle.loads(data.encode('latin1')) + else: + time_slice = { + 'start_year': 1985, + 'end_year': 1987, + 'start_month': 12, + 'end_month': 2, + 'start_day': 1, + 'end_day': 1, + } + cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='Amon') + cubes = preprocess_data(cubes, time_slice=time_slice) - if CACHE_FILES: - iris.save(cubes, filename) + # cubes are not serializable via json, so we must go via pickle + request.config.cache.set("functional/monthly", + pickle.dumps(cubes).decode('latin1')) return cubes @pytest.fixture(scope="module") -def timeseries_cubes_day(): +def timeseries_cubes_day(request): """Representative timeseries data grouped by calendar.""" - get_cubes = True - if CACHE_FILES: - filename = Path(__file__).with_name('daily.nc') - if filename.exists(): - cubes = iris.load(str(filename)) - get_cubes = False + # cache the cubes to save about 30-60 seconds on repeat use + data = request.config.cache.get("functional/daily", None) + + if data: + cubes = pickle.loads(data.encode('latin1')) - if get_cubes: + else: time_slice = { 'start_year': 2001, 'end_year': 2002, @@ -97,8 +99,9 @@ def timeseries_cubes_day(): cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='day') cubes = preprocess_data(cubes, time_slice=time_slice) - if CACHE_FILES: - iris.save(cubes, filename) + # cubes are not serializable via json, so we must go via pickle + request.config.cache.set("functional/daily", + pickle.dumps(cubes).decode('latin1')) def calendar(cube): return cube.coord('time').units.calendar From 0953eea950a91b9750e66308a7063a7f12b0fd2a Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 30 Nov 2020 16:32:40 +0100 Subject: [PATCH 41/65] Add regression tests for cube comparison --- tests/functional/test_multimodel.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index df18b0af8d..8a4358192d 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -12,8 +12,6 @@ esmvaltool_sample_data = pytest.importorskip("esmvaltool_sample_data") -CACHE_FILES = False - CALENDAR_PARAMS = ( pytest.param( '360_day', @@ -31,6 +29,13 @@ SPAN_PARAMS = ('overlap', 'full') +def assert_array_equal(a, b): + """Assert that array a equals array b.""" + np.testing.assert_array_equal(a, b) + if np.ma.isMaskedArray(a) or np.ma.isMaskedArray(b): + np.testing.assert_array_equal(a.mask, b.mask) + + def preprocess_data(cubes, time_slice: dict = None): """Regrid the data to the first cube and optional time-slicing.""" if time_slice: @@ -127,7 +132,7 @@ def multimodel_test(cubes, span, statistic): def multimodel_regression_test(cubes, span, name): statistic = 'mean' output = multimodel_test(cubes, span=span, statistic=statistic) - output_cube = output[statistic] + this_cube = output[statistic] # NOTE for the regression test # The following test will fail if the data are changed or if the @@ -135,15 +140,21 @@ def multimodel_regression_test(cubes, span, name): # regression test, remove the corresponding `.nc` files. filename = Path(__file__).with_name(f'{name}-{span}-{statistic}.nc') if filename.exists(): - expected_cube = iris.load(str(filename))[0] - assert np.allclose(output_cube.data, expected_cube.data) - assert expected_cube.coords() == output_cube.coords() + other_cube = iris.load(str(filename))[0] + assert_array_equal(this_cube.data, other_cube.data) + + # Compare coords + for this_coord, other_coord in zip(this_cube.coords(), + other_cube.coords()): + assert this_coord == other_coord + # remove Conventions which are added by Iris on save - output_cube.attributes.pop('Conventions') - assert expected_cube.metadata == output_cube.metadata + other_cube.attributes.pop('Conventions', None) + + assert other_cube.metadata == this_cube.metadata else: - iris.save(output_cube, filename) + iris.save(this_cube, filename) raise RuntimeError(f'Wrote file {filename.absolute()}') From 3789d266f35e7f0edd248782550235dd7db3cd2b Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 30 Nov 2020 17:33:33 +0100 Subject: [PATCH 42/65] Add issues numbers to xfail comments --- tests/functional/test_multimodel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 8a4358192d..eb8ca390b9 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -195,7 +195,7 @@ def test_multimodel_no_vertical_dimension(timeseries_cubes_month): @pytest.mark.functional -@pytest.mark.xfail('iris.exceptions.CoordinateNotFoundError') +@pytest.mark.xfail('https://github.com/ESMValGroup/ESMValCore/issues/891') def test_multimodel_no_horizontal_dimension(timeseries_cubes_month): """Test statistic without horizontal dimension using monthly data.""" span = 'full' @@ -217,7 +217,7 @@ def test_multimodel_only_time_dimension(timeseries_cubes_month): @pytest.mark.functional -@pytest.mark.xfail('ValueError') +@pytest.mark.xfail('https://github.com/ESMValGroup/ESMValCore/issues/890') def test_multimodel_no_time_dimension(timeseries_cubes_month): """Test statistic without time dimension using monthly data.""" span = 'full' From 9589115ff73066717cd100bbf5f331c7839d60e3 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 1 Dec 2020 10:38:20 +0100 Subject: [PATCH 43/65] Add missing `var_name` when `overlap == 'full'` --- esmvalcore/preprocessor/_multimodel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esmvalcore/preprocessor/_multimodel.py b/esmvalcore/preprocessor/_multimodel.py index e4b58f4241..bad69c169d 100644 --- a/esmvalcore/preprocessor/_multimodel.py +++ b/esmvalcore/preprocessor/_multimodel.py @@ -150,7 +150,8 @@ def _put_in_cube(template_cube, cube_data, statistic, t_axis): tunits = cf_units.Unit(unit_name, calendar="standard") times = iris.coords.DimCoord(t_axis, standard_name='time', - units=tunits) + units=tunits, + var_name='time') coord_names = [c.long_name for c in template_cube.coords()] coord_names.extend([c.standard_name for c in template_cube.coords()]) From c00c30cfb1d36314eaa5abfcca8b6d702e7ac826 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 1 Dec 2020 10:38:57 +0100 Subject: [PATCH 44/65] Move issue to reason in xfail marks --- tests/functional/test_multimodel.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index eb8ca390b9..974e1bb353 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -195,7 +195,9 @@ def test_multimodel_no_vertical_dimension(timeseries_cubes_month): @pytest.mark.functional -@pytest.mark.xfail('https://github.com/ESMValGroup/ESMValCore/issues/891') +@pytest.mark.xfail( + 'iris.exceptions.CoordinateNotFoundError', + reason='https://github.com/ESMValGroup/ESMValCore/issues/891') def test_multimodel_no_horizontal_dimension(timeseries_cubes_month): """Test statistic without horizontal dimension using monthly data.""" span = 'full' @@ -217,7 +219,9 @@ def test_multimodel_only_time_dimension(timeseries_cubes_month): @pytest.mark.functional -@pytest.mark.xfail('https://github.com/ESMValGroup/ESMValCore/issues/890') +@pytest.mark.xfail( + 'ValueError', + reason='https://github.com/ESMValGroup/ESMValCore/issues/890') def test_multimodel_no_time_dimension(timeseries_cubes_month): """Test statistic without time dimension using monthly data.""" span = 'full' From 6c60dcf716c2ef0ec2b2566610e8f54003f076bd Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 1 Dec 2020 10:52:38 +0100 Subject: [PATCH 45/65] Add regression data --- .../timeseries_daily_365_day-full-mean.nc | Bin 0 -> 18962 bytes .../timeseries_daily_365_day-overlap-mean.nc | Bin 0 -> 25378 bytes .../timeseries_daily_gregorian-full-mean.nc | Bin 0 -> 18954 bytes .../timeseries_daily_gregorian-overlap-mean.nc | Bin 0 -> 25558 bytes ...eries_daily_proleptic_gregorian-full-mean.nc | Bin 0 -> 18962 bytes ...es_daily_proleptic_gregorian-overlap-mean.nc | Bin 0 -> 25378 bytes .../functional/timeseries_monthly-full-mean.nc | Bin 0 -> 18962 bytes .../timeseries_monthly-overlap-mean.nc | Bin 0 -> 22899 bytes 8 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/functional/timeseries_daily_365_day-full-mean.nc create mode 100644 tests/functional/timeseries_daily_365_day-overlap-mean.nc create mode 100644 tests/functional/timeseries_daily_gregorian-full-mean.nc create mode 100644 tests/functional/timeseries_daily_gregorian-overlap-mean.nc create mode 100644 tests/functional/timeseries_daily_proleptic_gregorian-full-mean.nc create mode 100644 tests/functional/timeseries_daily_proleptic_gregorian-overlap-mean.nc create mode 100644 tests/functional/timeseries_monthly-full-mean.nc create mode 100644 tests/functional/timeseries_monthly-overlap-mean.nc diff --git a/tests/functional/timeseries_daily_365_day-full-mean.nc b/tests/functional/timeseries_daily_365_day-full-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..6bcd2070498c02b333b4e465d3c14871637081f3 GIT binary patch literal 18962 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 literal 0 HcmV?d00001 diff --git a/tests/functional/timeseries_daily_365_day-overlap-mean.nc b/tests/functional/timeseries_daily_365_day-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..9e9d47f70a97d851be64f21afc1abf3de12fd5ee GIT binary patch literal 25378 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 aeIBn3PIT|rR(3Y1Lj#A__?H(a2mS*+cwj65 literal 0 HcmV?d00001 diff --git a/tests/functional/timeseries_daily_gregorian-overlap-mean.nc b/tests/functional/timeseries_daily_gregorian-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..5e2c46e578b0ff942c887a3acd74a4191e6358c2 GIT binary patch literal 25558 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 literal 0 HcmV?d00001 diff --git a/tests/functional/timeseries_daily_proleptic_gregorian-overlap-mean.nc b/tests/functional/timeseries_daily_proleptic_gregorian-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..29c55592c3b3da6bf3c3f700de8a0442972cac1a GIT binary patch literal 25378 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 literal 0 HcmV?d00001 diff --git a/tests/functional/timeseries_monthly-overlap-mean.nc b/tests/functional/timeseries_monthly-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..f51bb8382f3e0930209ac080a509bb1fd8277710 GIT binary patch literal 22899 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 W7v-ILXUqjksDRLy*q?8+1pW_hHG$Ot literal 0 HcmV?d00001 From eb69778a2cc011d5e22efb2502a4fc328f201f21 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 1 Dec 2020 10:54:53 +0100 Subject: [PATCH 46/65] Add documentation and fix linter errors --- tests/functional/test_multimodel.py | 32 ++++++++++++++++------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 974e1bb353..ee305d2c7e 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -29,11 +29,11 @@ SPAN_PARAMS = ('overlap', 'full') -def assert_array_equal(a, b): - """Assert that array a equals array b.""" - np.testing.assert_array_equal(a, b) - if np.ma.isMaskedArray(a) or np.ma.isMaskedArray(b): - np.testing.assert_array_equal(a.mask, b.mask) +def assert_array_equal(this, other): + """Assert that array `this` equals array `other`.""" + np.testing.assert_array_equal(this, other) + if np.ma.isMaskedArray(this) or np.ma.isMaskedArray(other): + np.testing.assert_array_equal(this.mask, other.mask) def preprocess_data(cubes, time_slice: dict = None): @@ -56,8 +56,7 @@ def preprocess_data(cubes, time_slice: dict = None): @pytest.fixture(scope="module") def timeseries_cubes_month(request): - """Representative timeseries data.""" - + """Load representative timeseries data.""" # cache the cubes to save about 30-60 seconds on repeat use data = request.config.cache.get("functional/monthly", None) @@ -84,8 +83,7 @@ def timeseries_cubes_month(request): @pytest.fixture(scope="module") def timeseries_cubes_day(request): - """Representative timeseries data grouped by calendar.""" - + """Load representative timeseries data grouped by calendar.""" # cache the cubes to save about 30-60 seconds on repeat use data = request.config.cache.get("functional/daily", None) @@ -120,6 +118,7 @@ def calendar(cube): def multimodel_test(cubes, span, statistic): + """Run multimodel test with some simple checks.""" statistics = [statistic] output = multi_model_statistics(cubes, span=span, statistics=statistics) @@ -130,14 +129,18 @@ def multimodel_test(cubes, span, statistic): def multimodel_regression_test(cubes, span, name): + """Run multimodel regression test. + + This test will fail if the input data or multimodel code changed. To + update the data for the regression test, remove the corresponding + `.nc` files in this directory and re-run the tests. The tests will + fail the first time with a RuntimeError, because the reference data + are being written. + """ statistic = 'mean' output = multimodel_test(cubes, span=span, statistic=statistic) this_cube = output[statistic] - # NOTE for the regression test - # The following test will fail if the data are changed or if the - # multimodel code changes significantly. To update the data for the - # regression test, remove the corresponding `.nc` files. filename = Path(__file__).with_name(f'{name}-{span}-{statistic}.nc') if filename.exists(): other_cube = iris.load(str(filename))[0] @@ -154,8 +157,9 @@ def multimodel_regression_test(cubes, span, name): assert other_cube.metadata == this_cube.metadata else: + # The test will fail if no regression data are available. iris.save(this_cube, filename) - raise RuntimeError(f'Wrote file {filename.absolute()}') + raise RuntimeError(f'Wrote reference data to {filename.absolute()}') @pytest.mark.functional From c0b544345b7e8987fcc47f00ce12363ab56f0c0f Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Tue, 1 Dec 2020 12:13:17 +0100 Subject: [PATCH 47/65] Fix documentation build --- esmvalcore/preprocessor/_multimodel.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/esmvalcore/preprocessor/_multimodel.py b/esmvalcore/preprocessor/_multimodel.py index bad69c169d..75d5859a70 100644 --- a/esmvalcore/preprocessor/_multimodel.py +++ b/esmvalcore/preprocessor/_multimodel.py @@ -393,12 +393,10 @@ def multi_model_statistics(products, span, statistics, output_products=None): Returns ------- set or dict or list - Either: - - `set` of data products if `output_products` is given - - `dict` of cubes if `output_products` is not given - containing the multimodel stats computed or: - - `list` of input cubes if there is no overlap between cubes when - using `span='overlap'` + `set` of data products if `output_products` is given + `dict` of cubes if `output_products` is not given + `list` of input cubes if there is no overlap between cubes when + using `span='overlap'` Raises ------ From 5449d4a4be0f84aef767bac5e94fadf30dfd6593 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 2 Dec 2020 10:50:03 +0100 Subject: [PATCH 48/65] Split long repo string --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2e01c4f662..f85a2cfc51 100755 --- a/setup.py +++ b/setup.py @@ -58,7 +58,8 @@ 'pytest-metadata>=1.5.1', 'pytest-mock', 'pytest-xdist', - 'ESMValTool_sample_data @ git+https://github.com/ESMValGroup/ESMValTool_sample_data@master', # noqa + ('ESMValTool_sample_data @ ' + 'git+https://github.com/ESMValGroup/ESMValTool_sample_data@master'), ], # Development dependencies # Use pip install -e .[develop] to install in development mode From 9bc34819b16a1621949e3a9897a0e3c164698093 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 2 Dec 2020 10:53:01 +0100 Subject: [PATCH 49/65] Adjust array comparison Use `almost_equal` to account for possible small errors, and check if masks are equal first. --- tests/functional/test_multimodel.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index ee305d2c7e..bb90dd50a6 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -29,11 +29,13 @@ SPAN_PARAMS = ('overlap', 'full') -def assert_array_equal(this, other): - """Assert that array `this` equals array `other`.""" - np.testing.assert_array_equal(this, other) +def assert_array_almost_equal(this, other): + """Assert that array `this` almost equals array `other`.""" if np.ma.isMaskedArray(this) or np.ma.isMaskedArray(other): - np.testing.assert_array_equal(this.mask, other.mask) + np.testing.assert_array_almost_equal(this.mask, other.mask) + + np.testing.assert_array_almost_equal(this[this.mask == False], + other[other.mask == False]) def preprocess_data(cubes, time_slice: dict = None): @@ -144,7 +146,7 @@ def multimodel_regression_test(cubes, span, name): filename = Path(__file__).with_name(f'{name}-{span}-{statistic}.nc') if filename.exists(): other_cube = iris.load(str(filename))[0] - assert_array_equal(this_cube.data, other_cube.data) + assert_array_almost_equal(this_cube.data, other_cube.data) # Compare coords for this_coord, other_coord in zip(this_cube.coords(), From 4118290659c2010b296cd4504fa157d07225dc5c Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 2 Dec 2020 11:04:15 +0100 Subject: [PATCH 50/65] Revert testing unmasked data only --- tests/functional/test_multimodel.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index bb90dd50a6..89029f87c9 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -34,8 +34,7 @@ def assert_array_almost_equal(this, other): if np.ma.isMaskedArray(this) or np.ma.isMaskedArray(other): np.testing.assert_array_almost_equal(this.mask, other.mask) - np.testing.assert_array_almost_equal(this[this.mask == False], - other[other.mask == False]) + np.testing.assert_array_almost_equal(this, other) def preprocess_data(cubes, time_slice: dict = None): From 7930cf76657574a4a0a7103c2d1655f1d9f366cf Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 2 Dec 2020 12:02:29 +0100 Subject: [PATCH 51/65] Update regression data --- .../timeseries_daily_365_day-full-mean.nc | Bin 18962 -> 18962 bytes .../timeseries_daily_365_day-overlap-mean.nc | Bin 25378 -> 25378 bytes .../timeseries_monthly-full-mean.nc | Bin 18962 -> 18962 bytes .../timeseries_monthly-overlap-mean.nc | Bin 22899 -> 22899 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/functional/timeseries_daily_365_day-full-mean.nc b/tests/functional/timeseries_daily_365_day-full-mean.nc index 6bcd2070498c02b333b4e465d3c14871637081f3..3eee9a524674265da329dc45acbdeb7ae2a03d9c 100644 GIT binary patch delta 119 zcmV--0EqvRlmU{I0kBXU0XCCS92;VKu_NopjdeqEmvuv1sC7ehtaU>$9(F^@9Cky! zF?>UXHGD(4EPO*eE__3z7JNgk6?{Vo-gHB;;dDcfDs@8{DRo0GGj>DLFLpyFKzTz# ZMR`Nn33)@H3wcA@&Uizp&9lxNL@n20F2Dc) delta 119 zcmV--0EqvRlmU{I0kBXU0X36R92;U_b7nTMD|JKHG<8F4ICVq6J9R@kqIE;spLIhq zJ$ysCKzu`OO?*R(PJBauO?*TDOMF8TsB}Yat8_z3{d7b2`*cIF1$INN0(L{y5_v-w Z7kNWhzFs_3#E^#J&W=0c+7&LB&$#4oKzrFX`Ywh)$pB#>y zBo!gWxE(q!xt0n|Zjm$N5{)U3%eY0w5E)`Ruk**}*}vcOti9L!uJ`+X-?ema)Y83C z>#IdYb$Bl}DkXZsq))%x)GO+VM@rosXg5^#-!w*jzZuB!;&N2*p&2ZrrLt@=9 zMRmel|I;#0n0DFH>XN0!X2Wxz8`?Z?Xe;ZtSWWY=re(QB3p+Mib_yqREgQ#JiVyni zDfT&cD5CiGdqv|Ck9I$JtoFjZ>xUV++tO&SrKF1G!~>S^8f#Rd=GSFDYnS`2E4l~AT821 z;C!2aoQ|4_&uCUjVEa2#+TkzHVw*-(2%kQ%$7Cryz_tJ10E3m zxMEmyRq83VjoTu%H9kv3c(q>gnIN>O?{liI&*T9HM`~X0PfbiEL-ie++uJo2;}xk& z(QA}q@fbyvl=|U3Mdm)ko&$!XqOW>gBZeR4r5p0{!=EVL77}VGp0BPLyu#zvUjbMdN=1b^;66Q=~k3b`%iq*?@YyJ<-H%`kJ0 z;p4@I)3R4Zl%Yw!rfy`RW`B{T-$9FQXjv$Xe_1wpNop*oaJykZo(SpZwuYV)G(*Q} zuAH_+pSN`R#ByYVr9e7npmfgIVTQ%Ih8`F?_B6y+HN5kHLG1~M5#nDAND$mw0Y`-% zrBeSs7e$rt8Io%mu6$wmW~(7b@pPNCGp3>8Ctup7yvj z$)jz^qx8`*bLxlb@kp3n!bag2F|(9NSC5Pi9t90OauYlnHTCGUE zMu({w6eeHT_m)d&p39I`@?7K6R^B<#z++oGal>TG=dHv|lPt@{h}MV^&B*kqp6zk6 z>G1OVl%5%N=RO@j6nzPiS0+f-!s+CIi5=va<#?WwcA2CV@quFLJBmfK6!UI~t^RK4 zztB)549+pqT81b`(MZ#B5irumQR5m}D#A)%s~8}C zf8e&_kGqN~2NkuylZ?a>ON5l=;&jsg?x=t@BgG*fk;otS==70C+!Bw7_2?sXT`eM8 zC)PSv4Ce2K)OhiU+HyjjT@IzVM0a!P)?G>$?UGW(C3(JPcVvNP+FP1!LQbA0SuklX z|LEmniX8@)I8@|1oPW_F;hxW$N}9AsG;#GbjoWMTp42>h$>GpdhZnXwL<>J{a+v&y zgYy@0IAPd+&8&TzopZ%_=E(08E-im@x%Re8>~s=402ys&98HXMEN~Q@199kAi7E2u(EOuBaiz@0HcEm{! zKWMoAvu55ennsU@NN5q_gBl^q9}ZDGIz*|EBECPOK-1-YO~O3Qfq|Mgg-ySPNWT_h zLZ(BdehzI8I?OF{#1$i&>w7d=8|2orUgNITL<`j~Iuu@TNSBO@g~{7p625XteN5Ii zkdMb}R@T;Rc~FxibnNCZpohblX_CYn4uiKiG?P-)EB8@C7nz{TPy5U)^yydR(_xpx z*gX!*B5ynN7NW8p#=juHGkx;=$-*?Bqdi6WsWMp7eXg!`xb?Br_9=&5PdXfaJ;d-S zAxZ}NB);I2)5<4P+;ClEpA2DUoI}rOhuwb*kufC16P-hR*&##^>oYpfr(&E>>3E+= z%ov}+xpF^i;S$%*Wn`91#sHVHOqT(@U9N~AufMLD8_0N-%gGcu&X!r4JCj_V4!Qh$ zv%^gh+@)$#t{8_an+%`H3|ZicHk9GN8R8qleC_gqby?NXrFAC};4&%k5+}mcBQjQ{ z7n}bz;F}Z~Acw^V4vCm9d$>0|x{vgz^POW=SdP kH+O0Cl*f@avROAxYMQiGtY%Sld5VBm7H*1bR=dmp0P>m)L;wH) delta 3032 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 A8vpXfjeZ}ConnVA?zRJI8o2>mpm!p zSWkEx!%#cJuPDR#Ee3a(!KpA5mI@4C6xel0VC7+f^4$WnNhr;a%~n6^bNwiA_~AL| z2g|2E4Wg_g2zz%Bb!4zNh+5M6Rz+&R3egi%@w`XHv6m`b^1P7NO2uU$=oI#Kkn*~s&y2Tc{Lj1MAJ09CN5dS4l-+lh9Z)^ zTthkOOxDm&9$i)NqDsM7Sb?oV!O1HMMudV;jv7W4nLHat%DFI{?l5vl?R9~n8v=c& z1iYsOwqyyM$rSKR2hd6~2Li|-j)nj>k&J!a6EhsTgzuFS2C^lXvm|`<3rqzBOfG?Y v*m_@N#B_wvl0ktaWuw&X_cF zmZgRZ6QY8W%*;guX_S{t+Nmou=mNEH5tSJo7e6>>cX*!D)f3v)6FQQg5Sr0lkPz>y zXs*l5Xme8D?xgXulYVg`%gKJ5lXJ5M<07WlVCkkoR;@u)jlqLo3fqPv@s%QfN^!4U z;Sf(}H6imF`+z3@`)K>5DY&g!6gh>O zTLqdQ{R##Z*F1`3uVTDb5nH3!d&S^+rNP=sIp~zZt`vi|g9a13-P}lYlZu;F5p&*6 zRGynJ<6goiyyU#}(kG5gd-?v>%i8+@_JsfmGrjhY zn2d??IFq1g-EQI%uN(b*X!5gI?A#zUGY==E?|m|mH3E{Za;NLR3v7qNm^rf+%7!)gaB(u_1KtX%({_WzyPopr{U z5<9AqdSPHBWJ$WEiH3v~c<7>qf`ZZ#gf0R>J9r`XdGTDl@bSV6-*lHW-6cI+E=l&f zU};}aZGKI#KSNp)M%l3`%)34C^Yf2OGQyoQ>QiLcQf189WVA%chaiLo1yJKM^H1z>vJ4Er5vNN9JQomwF{x^T-frJVbK_) zUWUM92K#sJMfL|_sILV9^54zLpnAN>)?Z49le7( zPQ22QLjtmnr)0>fqm2xg>3B(^Pg&SNKIU6^Ln`wu6p_8BO{9|6LKF4GMncHcyoDJu zPQH-mq@6Tt7C14v1(ghVom5Cxs3Cmknw8v^Wg(G_Wmxz?WWR~yWa$GFlPxCXno59{nd?I`sk;PRbZ<_;2|lG5{M>_at2<(qEH>fFiv(j`eql*ZsW*~q{o?X RW13uTbz^O-KQz2J?mw=WGZg>; delta 716 zcmWmCTS!z<6b9giCTvQ|$grG3MM_E|V;WHlA^t+7v{V{v$jZwYgC>~!oZQ>Foavlq zM?R=nnifJPL=@ke z5v2mp|1hMiFvPxR$Q@#MQpcc@-Z74q2@dxIj^htG%oQAu%Q@!E3K}*k=pJV%m}Ho2 zX83iN!5!j$-1)(A_CCin$;{(u$>o@DV?aB@H7~<{A48vuA*z%i?y|r@k-*{!fiEX% zu|xrRK%jq*2U@HLN$?;!;5*f|zC>W~h(NqupwU9Lk?Jc9{lzQ+J7Vc6Nabwr(wc~9jw&n1#B>dk SXKL`RwFafFJzHX2>Hh&A05AIh From bb8f32723038938ae1f33d0acd5bf898b056a59d Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 2 Dec 2020 12:08:45 +0100 Subject: [PATCH 52/65] Do not use `assert_array_almost_equal` for boolean masks --- tests/functional/test_multimodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/test_multimodel.py b/tests/functional/test_multimodel.py index 89029f87c9..6291088fcf 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/functional/test_multimodel.py @@ -32,7 +32,7 @@ def assert_array_almost_equal(this, other): """Assert that array `this` almost equals array `other`.""" if np.ma.isMaskedArray(this) or np.ma.isMaskedArray(other): - np.testing.assert_array_almost_equal(this.mask, other.mask) + np.testing.assert_array_equal(this.mask, other.mask) np.testing.assert_array_almost_equal(this, other) From a27362ae6285c0d59b2ba4739842937cd9d4456c Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 2 Dec 2020 12:12:00 +0100 Subject: [PATCH 53/65] Cache pytest cache Loading sample data takes ~30 seconds. To save some time, store the pytest cache for next time. --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index f0ea8afc78..5d567e076b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,6 +68,7 @@ jobs: paths: - "/opt/conda/pkgs" - ".eggs" + - ".pytest_cache" - store_artifacts: path: /logs - store_artifacts: From c065fb5ebe528a053a98d9acacd525a9f3790f53 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Wed, 2 Dec 2020 12:16:16 +0100 Subject: [PATCH 54/65] Rename functional -> (use_)sample_data --- doc/contributing.rst | 4 ++-- .../timeseries_daily_365_day-full-mean.nc | Bin 18962 -> 0 bytes .../timeseries_daily_365_day-overlap-mean.nc | Bin 25378 -> 0 bytes .../timeseries_daily_gregorian-full-mean.nc | Bin 18954 -> 0 bytes ...timeseries_daily_gregorian-overlap-mean.nc | Bin 25558 -> 0 bytes ...ies_daily_proleptic_gregorian-full-mean.nc | Bin 18962 -> 0 bytes ..._daily_proleptic_gregorian-overlap-mean.nc | Bin 25378 -> 0 bytes .../timeseries_monthly-full-mean.nc | Bin 18962 -> 0 bytes .../timeseries_monthly-overlap-mean.nc | Bin 22899 -> 0 bytes .../test_multimodel.py | 22 +++++++++--------- 10 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 tests/functional/timeseries_daily_365_day-full-mean.nc delete mode 100644 tests/functional/timeseries_daily_365_day-overlap-mean.nc delete mode 100644 tests/functional/timeseries_daily_gregorian-full-mean.nc delete mode 100644 tests/functional/timeseries_daily_gregorian-overlap-mean.nc delete mode 100644 tests/functional/timeseries_daily_proleptic_gregorian-full-mean.nc delete mode 100644 tests/functional/timeseries_daily_proleptic_gregorian-overlap-mean.nc delete mode 100644 tests/functional/timeseries_monthly-full-mean.nc delete mode 100644 tests/functional/timeseries_monthly-overlap-mean.nc rename tests/{functional => sample_data}/test_multimodel.py (93%) diff --git a/doc/contributing.rst b/doc/contributing.rst index 02e5541c37..6c7b752a54 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -38,9 +38,9 @@ Sample data If you need sample data to work with, `this repository `__ contains samples of real data for use with ESMValTool development, demonstration purposes and automated testing. The goal is to keep the repository size small (~ 100 MB), so it can be easily downloaded and distributed. -The data are installed as part of the developer dependencies, and used by the functional tests (i.e. in the `multimodel tests` `__) +The data are installed as part of the developer dependencies, and used by some larger tests (i.e. in the `multimodel tests` `__) -To avoid running these tests as they can be time-consuming, use `pytest -m "not functional"`. +To avoid running these tests as they can be time-consuming, use `pytest -m "not use_sample_data"`. Code style ---------- diff --git a/tests/functional/timeseries_daily_365_day-full-mean.nc b/tests/functional/timeseries_daily_365_day-full-mean.nc deleted file mode 100644 index 3eee9a524674265da329dc45acbdeb7ae2a03d9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18962 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 hkx)eHy!UD=+bh(eLSHADM>l9C@LzU&RT%&P diff --git a/tests/functional/timeseries_daily_365_day-overlap-mean.nc b/tests/functional/timeseries_daily_365_day-overlap-mean.nc deleted file mode 100644 index 060b6120adc62ab88924faa9d1fb6a5b28df1402..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25378 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

!DrHjN;gPp7#g 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 X0idILHzG4+aR$d;8vpz!YvBI?`!XdT literal 0 HcmV?d00001 diff --git a/tests/sample_data/timeseries_daily_gregorian-full-mean.nc b/tests/sample_data/timeseries_daily_gregorian-full-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..0b8601465c93efd59ddbb21969fbd3dcd7db8d53 GIT binary patch literal 18954 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 aeIBn3PIT|rR(3Y1Lj#A__?H(a2mS*+cwj65 literal 0 HcmV?d00001 diff --git a/tests/sample_data/timeseries_daily_gregorian-overlap-mean.nc b/tests/sample_data/timeseries_daily_gregorian-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..5e2c46e578b0ff942c887a3acd74a4191e6358c2 GIT binary patch literal 25558 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 literal 0 HcmV?d00001 diff --git a/tests/sample_data/timeseries_daily_proleptic_gregorian-overlap-mean.nc b/tests/sample_data/timeseries_daily_proleptic_gregorian-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..29c55592c3b3da6bf3c3f700de8a0442972cac1a GIT binary patch literal 25378 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 T>zxTLP(cNRzQq50o+a=<&me^F literal 0 HcmV?d00001 From 4f80146d0902fe7277ecef950415f0d4c490500b Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Thu, 3 Dec 2020 10:58:42 +0100 Subject: [PATCH 57/65] Update developer documentation --- doc/contributing.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/contributing.rst b/doc/contributing.rst index 6c7b752a54..326beac63d 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -40,7 +40,9 @@ If you need sample data to work with, `this repository `__) -To avoid running these tests as they can be time-consuming, use `pytest -m "not use_sample_data"`. +The loading and preprocessing of the data can be somewhat time-consuming (~30 secs) and are cached by ``pytest`` to make the tests more performant. +Clear the cache by using running pytest with the ``--cache-clear`` flag. To avoid running these tests using sample data, use `pytest -m "not use_sample_data"`. +If you are adding new tests using sample data, please use the decorator ``@pytest.mark.use_sample_data``. Code style ---------- From 9e04e85754559b407be7f73c8c9231ca4064c238 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 7 Dec 2020 09:29:42 +0100 Subject: [PATCH 58/65] Move tests to subdirectory --- tests/sample_data/test_multimodel.py | 236 ------------------ .../timeseries_daily_365_day-full-mean.nc | Bin 18962 -> 0 bytes .../timeseries_daily_365_day-overlap-mean.nc | Bin 25378 -> 0 bytes .../timeseries_daily_gregorian-full-mean.nc | Bin 18954 -> 0 bytes ...timeseries_daily_gregorian-overlap-mean.nc | Bin 25558 -> 0 bytes ...ies_daily_proleptic_gregorian-full-mean.nc | Bin 18962 -> 0 bytes ..._daily_proleptic_gregorian-overlap-mean.nc | Bin 25378 -> 0 bytes .../timeseries_monthly-full-mean.nc | Bin 18962 -> 0 bytes .../timeseries_monthly-overlap-mean.nc | Bin 22899 -> 0 bytes 9 files changed, 236 deletions(-) delete mode 100644 tests/sample_data/test_multimodel.py delete mode 100644 tests/sample_data/timeseries_daily_365_day-full-mean.nc delete mode 100644 tests/sample_data/timeseries_daily_365_day-overlap-mean.nc delete mode 100644 tests/sample_data/timeseries_daily_gregorian-full-mean.nc delete mode 100644 tests/sample_data/timeseries_daily_gregorian-overlap-mean.nc delete mode 100644 tests/sample_data/timeseries_daily_proleptic_gregorian-full-mean.nc delete mode 100644 tests/sample_data/timeseries_daily_proleptic_gregorian-overlap-mean.nc delete mode 100644 tests/sample_data/timeseries_monthly-full-mean.nc delete mode 100644 tests/sample_data/timeseries_monthly-overlap-mean.nc diff --git a/tests/sample_data/test_multimodel.py b/tests/sample_data/test_multimodel.py deleted file mode 100644 index 288336aa86..0000000000 --- a/tests/sample_data/test_multimodel.py +++ /dev/null @@ -1,236 +0,0 @@ -"""Test using sample data for :func:`esmvalcore.preprocessor._multimodel`.""" - -import pickle -from itertools import groupby -from pathlib import Path - -import iris -import numpy as np -import pytest - -from esmvalcore.preprocessor import extract_time, multi_model_statistics - -esmvaltool_sample_data = pytest.importorskip("esmvaltool_sample_data") - -CALENDAR_PARAMS = ( - pytest.param( - '360_day', - marks=pytest.mark.skip( - reason='Cannot calculate statistics with single cube in list')), - '365_day', - 'gregorian', - 'proleptic_gregorian', - pytest.param( - 'julian', - marks=pytest.mark.skip( - reason='Cannot calculate statistics with single cube in list')), -) - -SPAN_PARAMS = ('overlap', 'full') - - -def assert_array_almost_equal(this, other): - """Assert that array `this` almost equals array `other`.""" - if np.ma.isMaskedArray(this) or np.ma.isMaskedArray(other): - np.testing.assert_array_equal(this.mask, other.mask) - - np.testing.assert_array_almost_equal(this, other) - - -def preprocess_data(cubes, time_slice: dict = None): - """Regrid the data to the first cube and optional time-slicing.""" - if time_slice: - cubes = [extract_time(cube, **time_slice) for cube in cubes] - - first_cube = cubes[0] - - # regrid to first cube - regrid_kwargs = { - 'grid': first_cube, - 'scheme': iris.analysis.Linear(), - } - - cubes = [cube.regrid(**regrid_kwargs) for cube in cubes] - - return cubes - - -@pytest.fixture(scope="module") -def timeseries_cubes_month(request): - """Load representative timeseries data.""" - # cache the cubes to save about 30-60 seconds on repeat use - data = request.config.cache.get("sample_data/monthly", None) - - if data: - cubes = pickle.loads(data.encode('latin1')) - else: - time_slice = { - 'start_year': 1985, - 'end_year': 1987, - 'start_month': 12, - 'end_month': 2, - 'start_day': 1, - 'end_day': 1, - } - cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='Amon') - cubes = preprocess_data(cubes, time_slice=time_slice) - - # cubes are not serializable via json, so we must go via pickle - request.config.cache.set("sample_data/monthly", - pickle.dumps(cubes).decode('latin1')) - - return cubes - - -@pytest.fixture(scope="module") -def timeseries_cubes_day(request): - """Load representative timeseries data grouped by calendar.""" - # cache the cubes to save about 30-60 seconds on repeat use - data = request.config.cache.get("sample_data/daily", None) - - if data: - cubes = pickle.loads(data.encode('latin1')) - - else: - time_slice = { - 'start_year': 2001, - 'end_year': 2002, - 'start_month': 12, - 'end_month': 2, - 'start_day': 1, - 'end_day': 1, - } - cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='day') - cubes = preprocess_data(cubes, time_slice=time_slice) - - # cubes are not serializable via json, so we must go via pickle - request.config.cache.set("sample_data/daily", - pickle.dumps(cubes).decode('latin1')) - - def calendar(cube): - return cube.coord('time').units.calendar - - # groupby requires sorted list - grouped = groupby(sorted(cubes, key=calendar), key=calendar) - - cube_dict = {key: list(group) for key, group in grouped} - - return cube_dict - - -def multimodel_test(cubes, span, statistic): - """Run multimodel test with some simple checks.""" - statistics = [statistic] - - output = multi_model_statistics(cubes, span=span, statistics=statistics) - assert isinstance(output, dict) - assert statistic in output - - return output - - -def multimodel_regression_test(cubes, span, name): - """Run multimodel regression test. - - This test will fail if the input data or multimodel code changed. To - update the data for the regression test, remove the corresponding - `.nc` files in this directory and re-run the tests. The tests will - fail the first time with a RuntimeError, because the reference data - are being written. - """ - statistic = 'mean' - output = multimodel_test(cubes, span=span, statistic=statistic) - this_cube = output[statistic] - - filename = Path(__file__).with_name(f'{name}-{span}-{statistic}.nc') - if filename.exists(): - other_cube = iris.load(str(filename))[0] - assert_array_almost_equal(this_cube.data, other_cube.data) - - # Compare coords - for this_coord, other_coord in zip(this_cube.coords(), - other_cube.coords()): - assert this_coord == other_coord - - # remove Conventions which are added by Iris on save - other_cube.attributes.pop('Conventions', None) - - assert other_cube.metadata == this_cube.metadata - - else: - # The test will fail if no regression data are available. - iris.save(this_cube, filename) - raise RuntimeError(f'Wrote reference data to {filename.absolute()}') - - -@pytest.mark.use_sample_data -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_regression_month(timeseries_cubes_month, span): - """Test statistic.""" - cubes = timeseries_cubes_month - name = 'timeseries_monthly' - multimodel_regression_test( - name=name, - span=span, - cubes=cubes, - ) - - -@pytest.mark.use_sample_data -@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) -@pytest.mark.parametrize('span', SPAN_PARAMS) -def test_multimodel_regression_day(timeseries_cubes_day, span, calendar): - """Test statistic.""" - cubes = timeseries_cubes_day[calendar] - name = f'timeseries_daily_{calendar}' - multimodel_regression_test( - name=name, - span=span, - cubes=cubes, - ) - - -@pytest.mark.use_sample_data -def test_multimodel_no_vertical_dimension(timeseries_cubes_month): - """Test statistic without vertical dimension using monthly data.""" - span = 'full' - cubes = timeseries_cubes_month - cubes = [cube[:, 0] for cube in cubes] - multimodel_test(cubes, span=span, statistic='mean') - - -@pytest.mark.use_sample_data -@pytest.mark.xfail( - 'iris.exceptions.CoordinateNotFoundError', - reason='https://github.com/ESMValGroup/ESMValCore/issues/891') -def test_multimodel_no_horizontal_dimension(timeseries_cubes_month): - """Test statistic without horizontal dimension using monthly data.""" - span = 'full' - cubes = timeseries_cubes_month - cubes = [cube[:, :, 0, 0] for cube in cubes] - # Coordinate not found error - # iris.exceptions.CoordinateNotFoundError: - # 'Expected to find exactly 1 depth coordinate, but found none.' - multimodel_test(cubes, span=span, statistic='mean') - - -@pytest.mark.use_sample_data -def test_multimodel_only_time_dimension(timeseries_cubes_month): - """Test statistic without only the time dimension using monthly data.""" - cubes = timeseries_cubes_month - span = 'full' - cubes = [cube[:, 0, 0, 0] for cube in cubes] - multimodel_test(cubes, span=span, statistic='mean') - - -@pytest.mark.use_sample_data -@pytest.mark.xfail( - 'ValueError', - reason='https://github.com/ESMValGroup/ESMValCore/issues/890') -def test_multimodel_no_time_dimension(timeseries_cubes_month): - """Test statistic without time dimension using monthly data.""" - span = 'full' - cubes = timeseries_cubes_month - cubes = [cube[0] for cube in cubes] - # ValueError: Cannot guess bounds for a coordinate of length 1. - multimodel_test(cubes, span=span, statistic='mean') diff --git a/tests/sample_data/timeseries_daily_365_day-full-mean.nc b/tests/sample_data/timeseries_daily_365_day-full-mean.nc deleted file mode 100644 index 3eee9a524674265da329dc45acbdeb7ae2a03d9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18962 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 hkx)eHy!UD=+bh(eLSHADM>l9C@LzU&RT%&P diff --git a/tests/sample_data/timeseries_daily_365_day-overlap-mean.nc b/tests/sample_data/timeseries_daily_365_day-overlap-mean.nc deleted file mode 100644 index 060b6120adc62ab88924faa9d1fb6a5b28df1402..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25378 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

!DrHjN;gPp7#g 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 X0idILHzG4+aR$d;8vpz!YvBI?`!XdT diff --git a/tests/sample_data/timeseries_daily_gregorian-full-mean.nc b/tests/sample_data/timeseries_daily_gregorian-full-mean.nc deleted file mode 100644 index 0b8601465c93efd59ddbb21969fbd3dcd7db8d53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18954 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 aeIBn3PIT|rR(3Y1Lj#A__?H(a2mS*+cwj65 diff --git a/tests/sample_data/timeseries_daily_gregorian-overlap-mean.nc b/tests/sample_data/timeseries_daily_gregorian-overlap-mean.nc deleted file mode 100644 index 5e2c46e578b0ff942c887a3acd74a4191e6358c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25558 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 diff --git a/tests/sample_data/timeseries_daily_proleptic_gregorian-overlap-mean.nc b/tests/sample_data/timeseries_daily_proleptic_gregorian-overlap-mean.nc deleted file mode 100644 index 29c55592c3b3da6bf3c3f700de8a0442972cac1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25378 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 T>zxTLP(cNRzQq50o+a=<&me^F From 8c8e88b8d98452e2519bfcd9a7ffeecc7a89344e Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 7 Dec 2020 09:36:10 +0100 Subject: [PATCH 59/65] Rename this/other to result/reference cube --- .../multimodel_statistics/test_multimodel.py | 236 ++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 tests/sample_data/multimodel_statistics/test_multimodel.py diff --git a/tests/sample_data/multimodel_statistics/test_multimodel.py b/tests/sample_data/multimodel_statistics/test_multimodel.py new file mode 100644 index 0000000000..b203305c6d --- /dev/null +++ b/tests/sample_data/multimodel_statistics/test_multimodel.py @@ -0,0 +1,236 @@ +"""Test using sample data for :func:`esmvalcore.preprocessor._multimodel`.""" + +import pickle +from itertools import groupby +from pathlib import Path + +import iris +import numpy as np +import pytest + +from esmvalcore.preprocessor import extract_time, multi_model_statistics + +esmvaltool_sample_data = pytest.importorskip("esmvaltool_sample_data") + +CALENDAR_PARAMS = ( + pytest.param( + '360_day', + marks=pytest.mark.skip( + reason='Cannot calculate statistics with single cube in list')), + '365_day', + 'gregorian', + 'proleptic_gregorian', + pytest.param( + 'julian', + marks=pytest.mark.skip( + reason='Cannot calculate statistics with single cube in list')), +) + +SPAN_PARAMS = ('overlap', 'full') + + +def assert_array_almost_equal(this, other): + """Assert that array `this` almost equals array `other`.""" + if np.ma.isMaskedArray(this) or np.ma.isMaskedArray(other): + np.testing.assert_array_equal(this.mask, other.mask) + + np.testing.assert_array_almost_equal(this, other) + + +def preprocess_data(cubes, time_slice: dict = None): + """Regrid the data to the first cube and optional time-slicing.""" + if time_slice: + cubes = [extract_time(cube, **time_slice) for cube in cubes] + + first_cube = cubes[0] + + # regrid to first cube + regrid_kwargs = { + 'grid': first_cube, + 'scheme': iris.analysis.Linear(), + } + + cubes = [cube.regrid(**regrid_kwargs) for cube in cubes] + + return cubes + + +@pytest.fixture(scope="module") +def timeseries_cubes_month(request): + """Load representative timeseries data.""" + # cache the cubes to save about 30-60 seconds on repeat use + data = request.config.cache.get("sample_data/monthly", None) + + if data: + cubes = pickle.loads(data.encode('latin1')) + else: + time_slice = { + 'start_year': 1985, + 'end_year': 1987, + 'start_month': 12, + 'end_month': 2, + 'start_day': 1, + 'end_day': 1, + } + cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='Amon') + cubes = preprocess_data(cubes, time_slice=time_slice) + + # cubes are not serializable via json, so we must go via pickle + request.config.cache.set("sample_data/monthly", + pickle.dumps(cubes).decode('latin1')) + + return cubes + + +@pytest.fixture(scope="module") +def timeseries_cubes_day(request): + """Load representative timeseries data grouped by calendar.""" + # cache the cubes to save about 30-60 seconds on repeat use + data = request.config.cache.get("sample_data/daily", None) + + if data: + cubes = pickle.loads(data.encode('latin1')) + + else: + time_slice = { + 'start_year': 2001, + 'end_year': 2002, + 'start_month': 12, + 'end_month': 2, + 'start_day': 1, + 'end_day': 1, + } + cubes = esmvaltool_sample_data.load_timeseries_cubes(mip_table='day') + cubes = preprocess_data(cubes, time_slice=time_slice) + + # cubes are not serializable via json, so we must go via pickle + request.config.cache.set("sample_data/daily", + pickle.dumps(cubes).decode('latin1')) + + def calendar(cube): + return cube.coord('time').units.calendar + + # groupby requires sorted list + grouped = groupby(sorted(cubes, key=calendar), key=calendar) + + cube_dict = {key: list(group) for key, group in grouped} + + return cube_dict + + +def multimodel_test(cubes, span, statistic): + """Run multimodel test with some simple checks.""" + statistics = [statistic] + + result = multi_model_statistics(cubes, span=span, statistics=statistics) + assert isinstance(result, dict) + assert statistic in result + + return result + + +def multimodel_regression_test(cubes, span, name): + """Run multimodel regression test. + + This test will fail if the input data or multimodel code changed. To + update the data for the regression test, remove the corresponding + `.nc` files in this directory and re-run the tests. The tests will + fail the first time with a RuntimeError, because the reference data + are being written. + """ + statistic = 'mean' + result = multimodel_test(cubes, span=span, statistic=statistic) + result_cube = result[statistic] + + filename = Path(__file__).with_name(f'{name}-{span}-{statistic}.nc') + if filename.exists(): + reference_cube = iris.load(str(filename))[0] + assert_array_almost_equal(result_cube.data, reference_cube.data) + + # Compare coords + for this_coord, other_coord in zip(result_cube.coords(), + reference_cube.coords()): + assert this_coord == other_coord + + # remove Conventions which are added by Iris on save + reference_cube.attributes.pop('Conventions', None) + + assert reference_cube.metadata == result_cube.metadata + + else: + # The test will fail if no regression data are available. + iris.save(result_cube, filename) + raise RuntimeError(f'Wrote reference data to {filename.absolute()}') + + +@pytest.mark.use_sample_data +@pytest.mark.parametrize('span', SPAN_PARAMS) +def test_multimodel_regression_month(timeseries_cubes_month, span): + """Test statistic.""" + cubes = timeseries_cubes_month + name = 'timeseries_monthly' + multimodel_regression_test( + name=name, + span=span, + cubes=cubes, + ) + + +@pytest.mark.use_sample_data +@pytest.mark.parametrize('calendar', CALENDAR_PARAMS) +@pytest.mark.parametrize('span', SPAN_PARAMS) +def test_multimodel_regression_day(timeseries_cubes_day, span, calendar): + """Test statistic.""" + cubes = timeseries_cubes_day[calendar] + name = f'timeseries_daily_{calendar}' + multimodel_regression_test( + name=name, + span=span, + cubes=cubes, + ) + + +@pytest.mark.use_sample_data +def test_multimodel_no_vertical_dimension(timeseries_cubes_month): + """Test statistic without vertical dimension using monthly data.""" + span = 'full' + cubes = timeseries_cubes_month + cubes = [cube[:, 0] for cube in cubes] + multimodel_test(cubes, span=span, statistic='mean') + + +@pytest.mark.use_sample_data +@pytest.mark.xfail( + 'iris.exceptions.CoordinateNotFoundError', + reason='https://github.com/ESMValGroup/ESMValCore/issues/891') +def test_multimodel_no_horizontal_dimension(timeseries_cubes_month): + """Test statistic without horizontal dimension using monthly data.""" + span = 'full' + cubes = timeseries_cubes_month + cubes = [cube[:, :, 0, 0] for cube in cubes] + # Coordinate not found error + # iris.exceptions.CoordinateNotFoundError: + # 'Expected to find exactly 1 depth coordinate, but found none.' + multimodel_test(cubes, span=span, statistic='mean') + + +@pytest.mark.use_sample_data +def test_multimodel_only_time_dimension(timeseries_cubes_month): + """Test statistic without only the time dimension using monthly data.""" + cubes = timeseries_cubes_month + span = 'full' + cubes = [cube[:, 0, 0, 0] for cube in cubes] + multimodel_test(cubes, span=span, statistic='mean') + + +@pytest.mark.use_sample_data +@pytest.mark.xfail( + 'ValueError', + reason='https://github.com/ESMValGroup/ESMValCore/issues/890') +def test_multimodel_no_time_dimension(timeseries_cubes_month): + """Test statistic without time dimension using monthly data.""" + span = 'full' + cubes = timeseries_cubes_month + cubes = [cube[0] for cube in cubes] + # ValueError: Cannot guess bounds for a coordinate of length 1. + multimodel_test(cubes, span=span, statistic='mean') From 66efb21323a0778ca820004c1c47436b5dde54b7 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 7 Dec 2020 09:37:49 +0100 Subject: [PATCH 60/65] Use `load_cube` to load regression data --- tests/sample_data/multimodel_statistics/test_multimodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sample_data/multimodel_statistics/test_multimodel.py b/tests/sample_data/multimodel_statistics/test_multimodel.py index b203305c6d..a527a9b913 100644 --- a/tests/sample_data/multimodel_statistics/test_multimodel.py +++ b/tests/sample_data/multimodel_statistics/test_multimodel.py @@ -144,7 +144,7 @@ def multimodel_regression_test(cubes, span, name): filename = Path(__file__).with_name(f'{name}-{span}-{statistic}.nc') if filename.exists(): - reference_cube = iris.load(str(filename))[0] + reference_cube = iris.load_cube(str(filename)) assert_array_almost_equal(result_cube.data, reference_cube.data) # Compare coords From e58d52d11f5f23e65ec6dc836b3a519036c0bd5c Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 7 Dec 2020 09:38:58 +0100 Subject: [PATCH 61/65] Pin dependency to revision --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f85a2cfc51..9399f0b808 100755 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ 'pytest-mock', 'pytest-xdist', ('ESMValTool_sample_data @ ' - 'git+https://github.com/ESMValGroup/ESMValTool_sample_data@master'), + 'git+https://github.com/ESMValGroup/ESMValTool_sample_data@035c45b'), ], # Development dependencies # Use pip install -e .[develop] to install in development mode From 6416018d84792c014c567617b012a5d7e2c25eb4 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 7 Dec 2020 08:39:58 +0000 Subject: [PATCH 62/65] Update doc/contributing.rst Co-authored-by: Bouwe Andela --- doc/contributing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/contributing.rst b/doc/contributing.rst index 326beac63d..f271524d08 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -38,7 +38,7 @@ Sample data If you need sample data to work with, `this repository `__ contains samples of real data for use with ESMValTool development, demonstration purposes and automated testing. The goal is to keep the repository size small (~ 100 MB), so it can be easily downloaded and distributed. -The data are installed as part of the developer dependencies, and used by some larger tests (i.e. in the `multimodel tests` `__) +The data are installed as part of the developer dependencies, and used by some larger tests (i.e. in the `multimodel tests `__) The loading and preprocessing of the data can be somewhat time-consuming (~30 secs) and are cached by ``pytest`` to make the tests more performant. Clear the cache by using running pytest with the ``--cache-clear`` flag. To avoid running these tests using sample data, use `pytest -m "not use_sample_data"`. From c953d8db20a59b3466a8a1d2ec0c069a57760c6d Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 7 Dec 2020 11:23:36 +0100 Subject: [PATCH 63/65] Re-add regression data --- .../timeseries_daily_365_day-full-mean.nc | Bin 0 -> 18962 bytes .../timeseries_daily_365_day-overlap-mean.nc | Bin 0 -> 25378 bytes .../timeseries_daily_gregorian-full-mean.nc | Bin 0 -> 18954 bytes .../timeseries_daily_gregorian-overlap-mean.nc | Bin 0 -> 25558 bytes ...eries_daily_proleptic_gregorian-full-mean.nc | Bin 0 -> 18962 bytes ...es_daily_proleptic_gregorian-overlap-mean.nc | Bin 0 -> 25378 bytes .../timeseries_monthly-full-mean.nc | Bin 0 -> 18962 bytes .../timeseries_monthly-overlap-mean.nc | Bin 0 -> 22899 bytes 8 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/sample_data/multimodel_statistics/timeseries_daily_365_day-full-mean.nc create mode 100644 tests/sample_data/multimodel_statistics/timeseries_daily_365_day-overlap-mean.nc create mode 100644 tests/sample_data/multimodel_statistics/timeseries_daily_gregorian-full-mean.nc create mode 100644 tests/sample_data/multimodel_statistics/timeseries_daily_gregorian-overlap-mean.nc create mode 100644 tests/sample_data/multimodel_statistics/timeseries_daily_proleptic_gregorian-full-mean.nc create mode 100644 tests/sample_data/multimodel_statistics/timeseries_daily_proleptic_gregorian-overlap-mean.nc create mode 100644 tests/sample_data/multimodel_statistics/timeseries_monthly-full-mean.nc create mode 100644 tests/sample_data/multimodel_statistics/timeseries_monthly-overlap-mean.nc diff --git a/tests/sample_data/multimodel_statistics/timeseries_daily_365_day-full-mean.nc b/tests/sample_data/multimodel_statistics/timeseries_daily_365_day-full-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..3eee9a524674265da329dc45acbdeb7ae2a03d9c GIT binary patch literal 18962 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 hkx)eHy!UD=+bh(eLSHADM>l9C@LzU&RT%&P literal 0 HcmV?d00001 diff --git a/tests/sample_data/multimodel_statistics/timeseries_daily_365_day-overlap-mean.nc b/tests/sample_data/multimodel_statistics/timeseries_daily_365_day-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..060b6120adc62ab88924faa9d1fb6a5b28df1402 GIT binary patch literal 25378 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

!DrHjN;gPp7#g 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 X0idILHzG4+aR$d;8vpz!YvBI?`!XdT literal 0 HcmV?d00001 diff --git a/tests/sample_data/multimodel_statistics/timeseries_daily_gregorian-full-mean.nc b/tests/sample_data/multimodel_statistics/timeseries_daily_gregorian-full-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..0b8601465c93efd59ddbb21969fbd3dcd7db8d53 GIT binary patch literal 18954 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 aeIBn3PIT|rR(3Y1Lj#A__?H(a2mS*+cwj65 literal 0 HcmV?d00001 diff --git a/tests/sample_data/multimodel_statistics/timeseries_daily_gregorian-overlap-mean.nc b/tests/sample_data/multimodel_statistics/timeseries_daily_gregorian-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..5e2c46e578b0ff942c887a3acd74a4191e6358c2 GIT binary patch literal 25558 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 literal 0 HcmV?d00001 diff --git a/tests/sample_data/multimodel_statistics/timeseries_daily_proleptic_gregorian-overlap-mean.nc b/tests/sample_data/multimodel_statistics/timeseries_daily_proleptic_gregorian-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..29c55592c3b3da6bf3c3f700de8a0442972cac1a GIT binary patch literal 25378 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 T>zxTLP(cNRzQq50o+a=<&me^F literal 0 HcmV?d00001 From 84ebcc77a517eb2728edd8eb9dccb195b08c0107 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 7 Dec 2020 13:19:22 +0000 Subject: [PATCH 64/65] Update setup.cfg Co-authored-by: Bouwe Andela --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 6905ec23ce..e794a1784d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,7 +21,7 @@ flake8-ignore = log_level = WARNING markers = installation: test requires installation of dependencies - functional: Run functional tests using real data + use_sample_data: Run functional tests using real data [coverage:run] parallel = true From adab2d2ef49f1a309330f84562f397665cef4328 Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Mon, 7 Dec 2020 14:24:19 +0100 Subject: [PATCH 65/65] Pin to ESMValTool sample data v0.0.1 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9399f0b808..3554240a63 100755 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ 'pytest-mock', 'pytest-xdist', ('ESMValTool_sample_data @ ' - 'git+https://github.com/ESMValGroup/ESMValTool_sample_data@035c45b'), + 'git+https://github.com/ESMValGroup/ESMValTool_sample_data@v0.0.1'), ], # Development dependencies # Use pip install -e .[develop] to install in development mode

!DrHjN;gPp7#g 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 X0idILHzG4+aR$d;8vpz!YvBI?`!XdT diff --git a/tests/functional/timeseries_daily_gregorian-full-mean.nc b/tests/functional/timeseries_daily_gregorian-full-mean.nc deleted file mode 100644 index 0b8601465c93efd59ddbb21969fbd3dcd7db8d53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18954 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 aeIBn3PIT|rR(3Y1Lj#A__?H(a2mS*+cwj65 diff --git a/tests/functional/timeseries_daily_gregorian-overlap-mean.nc b/tests/functional/timeseries_daily_gregorian-overlap-mean.nc deleted file mode 100644 index 5e2c46e578b0ff942c887a3acd74a4191e6358c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25558 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 diff --git a/tests/functional/timeseries_daily_proleptic_gregorian-overlap-mean.nc b/tests/functional/timeseries_daily_proleptic_gregorian-overlap-mean.nc deleted file mode 100644 index 29c55592c3b3da6bf3c3f700de8a0442972cac1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25378 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 T>zxTLP(cNRzQq50o+a=<&me^F diff --git a/tests/functional/test_multimodel.py b/tests/sample_data/test_multimodel.py similarity index 93% rename from tests/functional/test_multimodel.py rename to tests/sample_data/test_multimodel.py index 6291088fcf..288336aa86 100644 --- a/tests/functional/test_multimodel.py +++ b/tests/sample_data/test_multimodel.py @@ -1,4 +1,4 @@ -"""Functional test for :func:`esmvalcore.preprocessor._multimodel`.""" +"""Test using sample data for :func:`esmvalcore.preprocessor._multimodel`.""" import pickle from itertools import groupby @@ -59,7 +59,7 @@ def preprocess_data(cubes, time_slice: dict = None): def timeseries_cubes_month(request): """Load representative timeseries data.""" # cache the cubes to save about 30-60 seconds on repeat use - data = request.config.cache.get("functional/monthly", None) + data = request.config.cache.get("sample_data/monthly", None) if data: cubes = pickle.loads(data.encode('latin1')) @@ -76,7 +76,7 @@ def timeseries_cubes_month(request): cubes = preprocess_data(cubes, time_slice=time_slice) # cubes are not serializable via json, so we must go via pickle - request.config.cache.set("functional/monthly", + request.config.cache.set("sample_data/monthly", pickle.dumps(cubes).decode('latin1')) return cubes @@ -86,7 +86,7 @@ def timeseries_cubes_month(request): def timeseries_cubes_day(request): """Load representative timeseries data grouped by calendar.""" # cache the cubes to save about 30-60 seconds on repeat use - data = request.config.cache.get("functional/daily", None) + data = request.config.cache.get("sample_data/daily", None) if data: cubes = pickle.loads(data.encode('latin1')) @@ -104,7 +104,7 @@ def timeseries_cubes_day(request): cubes = preprocess_data(cubes, time_slice=time_slice) # cubes are not serializable via json, so we must go via pickle - request.config.cache.set("functional/daily", + request.config.cache.set("sample_data/daily", pickle.dumps(cubes).decode('latin1')) def calendar(cube): @@ -163,7 +163,7 @@ def multimodel_regression_test(cubes, span, name): raise RuntimeError(f'Wrote reference data to {filename.absolute()}') -@pytest.mark.functional +@pytest.mark.use_sample_data @pytest.mark.parametrize('span', SPAN_PARAMS) def test_multimodel_regression_month(timeseries_cubes_month, span): """Test statistic.""" @@ -176,7 +176,7 @@ def test_multimodel_regression_month(timeseries_cubes_month, span): ) -@pytest.mark.functional +@pytest.mark.use_sample_data @pytest.mark.parametrize('calendar', CALENDAR_PARAMS) @pytest.mark.parametrize('span', SPAN_PARAMS) def test_multimodel_regression_day(timeseries_cubes_day, span, calendar): @@ -190,7 +190,7 @@ def test_multimodel_regression_day(timeseries_cubes_day, span, calendar): ) -@pytest.mark.functional +@pytest.mark.use_sample_data def test_multimodel_no_vertical_dimension(timeseries_cubes_month): """Test statistic without vertical dimension using monthly data.""" span = 'full' @@ -199,7 +199,7 @@ def test_multimodel_no_vertical_dimension(timeseries_cubes_month): multimodel_test(cubes, span=span, statistic='mean') -@pytest.mark.functional +@pytest.mark.use_sample_data @pytest.mark.xfail( 'iris.exceptions.CoordinateNotFoundError', reason='https://github.com/ESMValGroup/ESMValCore/issues/891') @@ -214,7 +214,7 @@ def test_multimodel_no_horizontal_dimension(timeseries_cubes_month): multimodel_test(cubes, span=span, statistic='mean') -@pytest.mark.functional +@pytest.mark.use_sample_data def test_multimodel_only_time_dimension(timeseries_cubes_month): """Test statistic without only the time dimension using monthly data.""" cubes = timeseries_cubes_month @@ -223,7 +223,7 @@ def test_multimodel_only_time_dimension(timeseries_cubes_month): multimodel_test(cubes, span=span, statistic='mean') -@pytest.mark.functional +@pytest.mark.use_sample_data @pytest.mark.xfail( 'ValueError', reason='https://github.com/ESMValGroup/ESMValCore/issues/890') From 20a3db1f75fabd2440e900b143563c78d6b3148a Mon Sep 17 00:00:00 2001 From: Bouwe Andela Date: Wed, 2 Dec 2020 12:37:55 +0100 Subject: [PATCH 55/65] Add cache to test job --- .circleci/config.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5d567e076b..b537f152a2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,10 +26,17 @@ jobs: - image: esmvalgroup/esmvalcore:development steps: - checkout + - restore_cache: + key: test-{{ .Branch }} - run: command: | pip install .[test] pytest -n 2 -m "not installation" + - save_cache: + key: test-{{ .Branch }} + paths: + - ".eggs" + - ".pytest_cache" - store_test_results: path: test-reports/ - store_artifacts: @@ -44,7 +51,7 @@ jobs: - checkout - check_changes - restore_cache: - key: python3-install-{{ .Branch }} + key: install-{{ .Branch }} - run: command: | . /opt/conda/etc/profile.d/conda.sh @@ -64,7 +71,7 @@ jobs: pytest -n 2 esmvaltool version - save_cache: - key: python3-install-{{ .Branch }} + key: install-{{ .Branch }} paths: - "/opt/conda/pkgs" - ".eggs" From 72ace2fe2160acebae1f221e781d1d4262647354 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Thu, 3 Dec 2020 09:42:59 +0100 Subject: [PATCH 56/65] Add regression data --- .../timeseries_daily_365_day-full-mean.nc | Bin 0 -> 18962 bytes .../timeseries_daily_365_day-overlap-mean.nc | Bin 0 -> 25378 bytes .../timeseries_daily_gregorian-full-mean.nc | Bin 0 -> 18954 bytes .../timeseries_daily_gregorian-overlap-mean.nc | Bin 0 -> 25558 bytes ...eries_daily_proleptic_gregorian-full-mean.nc | Bin 0 -> 18962 bytes ...es_daily_proleptic_gregorian-overlap-mean.nc | Bin 0 -> 25378 bytes .../sample_data/timeseries_monthly-full-mean.nc | Bin 0 -> 18962 bytes .../timeseries_monthly-overlap-mean.nc | Bin 0 -> 22899 bytes 8 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/sample_data/timeseries_daily_365_day-full-mean.nc create mode 100644 tests/sample_data/timeseries_daily_365_day-overlap-mean.nc create mode 100644 tests/sample_data/timeseries_daily_gregorian-full-mean.nc create mode 100644 tests/sample_data/timeseries_daily_gregorian-overlap-mean.nc create mode 100644 tests/sample_data/timeseries_daily_proleptic_gregorian-full-mean.nc create mode 100644 tests/sample_data/timeseries_daily_proleptic_gregorian-overlap-mean.nc create mode 100644 tests/sample_data/timeseries_monthly-full-mean.nc create mode 100644 tests/sample_data/timeseries_monthly-overlap-mean.nc diff --git a/tests/sample_data/timeseries_daily_365_day-full-mean.nc b/tests/sample_data/timeseries_daily_365_day-full-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..3eee9a524674265da329dc45acbdeb7ae2a03d9c GIT binary patch literal 18962 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 hkx)eHy!UD=+bh(eLSHADM>l9C@LzU&RT%&P literal 0 HcmV?d00001 diff --git a/tests/sample_data/timeseries_daily_365_day-overlap-mean.nc b/tests/sample_data/timeseries_daily_365_day-overlap-mean.nc new file mode 100644 index 0000000000000000000000000000000000000000..060b6120adc62ab88924faa9d1fb6a5b28df1402 GIT binary patch literal 25378 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