From 114b8e0e228b8f1d310c8b4a185e9a9d68ed4eb9 Mon Sep 17 00:00:00 2001 From: Stef Smeets Date: Mon, 7 Dec 2020 13:53:31 +0000 Subject: [PATCH] Add multimodel tests using samples of CMIP6 data (#856) Co-authored-by: Bouwe Andela --- .circleci/config.yml | 12 +- doc/contributing.rst | 11 + esmvalcore/preprocessor/_multimodel.py | 27 +- setup.cfg | 1 + setup.py | 3 + .../multimodel_statistics/test_multimodel.py | 236 ++++++++++++++++++ .../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 ...ies_daily_proleptic_gregorian-full-mean.nc | Bin 0 -> 18962 bytes ..._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 14 files changed, 276 insertions(+), 14 deletions(-) create mode 100644 tests/sample_data/multimodel_statistics/test_multimodel.py 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/.circleci/config.yml b/.circleci/config.yml index f0ea8afc78..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,10 +71,11 @@ jobs: pytest -n 2 esmvaltool version - save_cache: - key: python3-install-{{ .Branch }} + key: install-{{ .Branch }} paths: - "/opt/conda/pkgs" - ".eggs" + - ".pytest_cache" - store_artifacts: path: /logs - store_artifacts: diff --git a/doc/contributing.rst b/doc/contributing.rst index 0f731dc0bb..f271524d08 100644 --- a/doc/contributing.rst +++ b/doc/contributing.rst @@ -33,6 +33,17 @@ 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. + +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"`. +If you are adding new tests using sample data, please use the decorator ``@pytest.mark.use_sample_data``. + Code style ---------- diff --git a/esmvalcore/preprocessor/_multimodel.py b/esmvalcore/preprocessor/_multimodel.py index 360daf71c7..75d5859a70 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: @@ -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()]) @@ -357,8 +358,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 +383,25 @@ 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: str - 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 - list of data products or cubes containing the multimodel stats - computed. + set or dict or list + `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 ------ ValueError If span is neither overlap nor full. - """ logger.debug('Multimodel statistics: computing: %s', statistics) if len(products) < 2: diff --git a/setup.cfg b/setup.cfg index 6fd9f1591f..e794a1784d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,6 +21,7 @@ flake8-ignore = log_level = WARNING markers = installation: test requires installation of dependencies + use_sample_data: Run functional tests using real data [coverage:run] parallel = true diff --git a/setup.py b/setup.py index d777e07390..3554240a63 100755 --- a/setup.py +++ b/setup.py @@ -42,6 +42,7 @@ 'pyyaml', 'requests', 'scitools-iris>=2.2', + 'requests', 'shapely[vectorized]', 'stratify', 'yamale==2.*', @@ -57,6 +58,8 @@ 'pytest-metadata>=1.5.1', 'pytest-mock', 'pytest-xdist', + ('ESMValTool_sample_data @ ' + 'git+https://github.com/ESMValGroup/ESMValTool_sample_data@v0.0.1'), ], # Development dependencies # Use pip install -e .[develop] to install in development mode 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..a527a9b913 --- /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_cube(str(filename)) + 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') 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 zcmeHP4Qv$06`r-va5hT-7Yrdl&V(d}z+qDxD8j*JZDWEl$Tk)UO3lF?aKYTsyFJII zPD@Y-B54IBNl~MgpcX}_3PD6wf8?f66;cujN=cLcrB$Lt&_GKf1t~>JL+8!Rx3{-= z{R6l%>5j4A?%OwSX5O2h_ujr`XKhu@@VxPPjEdjSd~Bq+#Gk9Gqs%?0@c%x5*6bmQs0JrLbcr@UbwK zoyDAO;9hb&IbK$%Q1v8sX|}x0YEFc_n*vaylh z(_n~)YLHbeURqt>xOiE8OQTU)SIu-TOO5~J2ocm*F0JOoq83RNwan#Di#J^y%Ec$fDg|4yNM5{?N6bpwE;g(p4HzQl8 zSz>QpFJWvb$K;9{YeTIOs=|pxp;6}YU({Hih^&t%qM_LMXWyAeGhoPAqSJgs2=L+Oa12M^=U8vMCx~^L%(XiF$=ot*IknzD@}@t!&`$U^O#>PnXxlOH(0rXIU{Kx zSy@?{eP*x^iOPwUw6cD8e|0|NAeHW(r*S%8s+h-VY+tTu89_ol(CbAsfBIUc4{c2f z%?TlCK2k3ge{0BWSrZE$op++{;t+&DWMavB+3fC$yyIzPRSpiZNTF5YUkm4_yI&ND-o! zz=IF=2H-)DJsbEDiosCc7b?Jm5AFfM$J#+;H3mM?%1ZP3n(D|fMd#!LYYBMp8SbD5 zpW7VxJxXpP9C-8-TaA|O{fk7_;ioVGx2|VjX zs?Rc1Na0(ZdjW`nR7E#M!<^!p*oSST`Wy-s_7wOfuNaYrP&CnEMmBAZBtm8?5uwUH z{*Xsb`A=&+wjL2Ns%hlB7)Ajp0-~!vww$#yYDPXeq(%#W8}Qz|X>B3`D*^zT z5Al|49)X2VnQFXpOoaX*GL5%BO$2)OwXS;99(sqH>Z9N-d`3CHb}N@sgx1i_pEU%A z^sFu(fD{E0NlVz4(B*Rke!$rccCW5;^FaSW_vK1HdpMr@X;r;KU`5kk9XYNY{3h`wQu|})La2be2HE_>(Au{^74bD3gTYD&lR*P zco&`oJPCLb@Fd_#;QvYjb~_EP;e3?zfp-?aiys(4MBTsKz5#!rQ2GNh{Up>L6|Yap zz9HKN_Dz%ib7}dHU?zVp+E86n-B4X`RJX|2q6OUEq?cylkQquw%w9Ez*Qa4Vz!(`$ zss=1nHwM=@HYy7U-2{9SZ!8s~@EPB){;HGkEl)rG z6x&D$PC>ITqTl}vYo|xty%8Hxbl(wnjNdb*+k(sg>SCW01$Ufi!EP%Y^=Vhxp`Q|s zR|ZG|LjSoL+Rad8h7vPoMTYV+RcoIb8B;4mzrnhq_XlWH9^1Z3K-dQ=41{!D(1+9s2pr0A>SX(4!@`F{J<{~mj>z`IF6{BWGNpQ~hkI#F?8T`s$C@Iomt;hCu zjkZ!2oaA}4o#bWv-YRg$%JSwqsa}{@az)_kw&%ZCQ(LvrIur%=MA_w7fAeU2%b=xv zQ!ar1MNCOxVC-faJw(Z3w~|$aSpW&!)2`_Z!1LuHgulAW57upz6eixBh$NFdM%+_$ zn2rl@Pt(hc;?417)Qq-8IEg4^f>Ia}^x^oUFcT$#_xB4T0cn{x_bqq0u$x3vkyc8H zrX&ywv}UtkaeIc!B?+vY?;Pt@170}*UT60HYMPGmnZBP)tq5DXzef$Va$w63hl`V5WP)lwsX=a;n<2QgL&Td4&4&~}KQ{tIHvYN$ zsc(!ux!}M=;(_m2Fu&nj>n8`ZC-0OszA?Z`!YFZnIW=>e)7;3fl9EWOQ)Xk`Ae^|gy*%7I2HEfdA&nyc@>hp@Vt&v6}|+?ubOr4 zM;+3FpCb1O;fg&%6n0naF!A88E5)lna>dRQ1y>=NbL5J>ccgO>p}aCc5^(jrl-`(K zXUsk;m|fo)ienjSwa*h~pJ!jW@^z$m576K|w!KQAhoGxi${Jsrlnt>ap5m|7Wflaj zc$Re!KSO5JOojXGx78_nbjpLbt^}lCu+HHZVEVbio97qQD!(A0M2L_7+&@m&Z>nEF z9uMtQH{UOyPj_fp;v+yxGCFi>!B^=tAq$+oy&jxVBd6A}DZx901PxPE6 z#=k`s1s|shkrReQZ!0&JC6-?URvTjlT{24yEn|ZO1f?@e>=m-Ac|mp<;QM=O583?y z{(V_L{D8kwv%CuJx;Nwp@JZzA2V6~V`V)2CD+45ff%5~PR{K1Wet?>1+R?Xm4bZ4O zwtba=u$A#&4v0!s&ENS3OtPD1EAw24{@Tj4GxugIuk6)UR$-(s%CQ8+*llI|D+}1l 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