From 108266e72d01c173e15cdf4ca00612a0d4f0a8ca Mon Sep 17 00:00:00 2001 From: "Joran R. Angevaare" Date: Tue, 9 Jul 2024 20:05:28 +0200 Subject: [PATCH] Test interp nominal lon (#365) --- CITATION.cff | 6 +++++- tests/test_preprocessing.py | 39 +++++++++++++++++++++++++++++++++++++ xmip/preprocessing.py | 2 +- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 63fca2c3..f3458b76 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -12,7 +12,7 @@ authors: orcid: "https://orcid.org/0000-0002-1660-7822" - family-names: "Nicholas" given-names: "Thomas" - orcid: "0000-0002-2176-0530" + orcid: "https://orcid.org/0000-0002-2176-0530" - family-names: "Magin" given-names: "Justus" orcid: "https://orcid.org/0000-0002-4254-8002" @@ -21,6 +21,10 @@ authors: given-names: "Markus" orcid: "https://orcid.org/0000-0001-7464-7075" affiliation: "Universität Hamburg, Germany" +- family-names: "Angevaare" + given-names: "Joran J. R." + orcid: "https://orcid.org/0000-0003-3392-8123" + affiliation: "KNMI" title: "xMIP" url: "https://github.com/jbusecke/xMIP" diff --git a/tests/test_preprocessing.py b/tests/test_preprocessing.py index 0183c1b5..7b7245ef 100644 --- a/tests/test_preprocessing.py +++ b/tests/test_preprocessing.py @@ -20,6 +20,7 @@ rename_cmip6, replace_x_y_nominal_lat_lon, sort_vertex_order, + _interp_nominal_lon, ) @@ -191,6 +192,44 @@ def test_replace_x_y_nominal_lat_lon(dask, nans): assert set(replaced_ds.lat.dims) == set(["x", "y"]) +def test_interp_nominal_lon(): + """ + Check that https://github.com/jbusecke/xMIP/issues/295 was fixed in https://github.com/jbusecke/xMIP/pull/296 + + In https://github.com/jbusecke/xMIP/blob/0270f4b4977d512adc2337d4a547b39e25d2f2da/tests/test_preprocessing.py, + the old issue was replicated (and illustrated that the tests would have failed then). + """ + + def _get_dummy_longitude() -> np.ndarray: + # Totally arbitrary data (although len(lon) has to be > 360 to see the issue) + lon = np.linspace(0, 360, 513)[:-1] + + # Add some NaN values just as an example + lon[2 + 30 : len(lon) // 2 + 50] = np.nan + return lon + + def _lons_parsed_make_sense( + input_lons: np.ndarray, lons_parsed: np.ndarray + ) -> bool: + """ + Check if the parsed longitudes make sense. + Since we know that the input-lons are all monotonically increasing, the parsed lons should also do that. + """ + accepted_differences_between_lon_coords = np.unique(np.diff(input_lons)) + if len(accepted_differences_between_lon_coords) not in [1, 2]: + raise RuntimeError( + f"Cannot work with changed format of inputdata {accepted_differences_between_lon_coords}" + ) + diff_pars_lons = np.unique(np.diff(lons_parsed)) + return np.all( + [x in accepted_differences_between_lon_coords for x in diff_pars_lons] + ) + + lons = _get_dummy_longitude() + lons_parsed = _interp_nominal_lon(lons) + assert _lons_parsed_make_sense(lons, lons_parsed) + + @pytest.mark.parametrize( "coord", [ diff --git a/xmip/preprocessing.py b/xmip/preprocessing.py index f8556d76..1c902707 100644 --- a/xmip/preprocessing.py +++ b/xmip/preprocessing.py @@ -137,7 +137,7 @@ def broadcast_lonlat(ds, verbose=True): return ds -def _interp_nominal_lon(lon_1d): +def _interp_nominal_lon(lon_1d: np.ndarray) -> np.ndarray: x = np.arange(len(lon_1d)) idx = np.isnan(lon_1d) # Assume that longitudes are cyclic (i.e. that the period equals the length of lon)