From a1063cb9a37dc44ffd985b262f8fb0a2d4fd71f7 Mon Sep 17 00:00:00 2001 From: Bart Schilperoort Date: Wed, 21 Jun 2023 14:49:59 +0200 Subject: [PATCH] Make landcover output dynamic (#84) * Make landcover data time-dependent * Update tests * Add changelog entry, apply formatter. * Update changelog for release --- PyStemmusScope/forcing_io.py | 8 ++--- .../global_data/global_data_selection.py | 6 ++-- docs/CHANGELOG.md | 33 +++++++++++++------ tests/test_global_data_selection.py | 30 +++++++++++------ 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/PyStemmusScope/forcing_io.py b/PyStemmusScope/forcing_io.py index 426879b9..259c5d19 100644 --- a/PyStemmusScope/forcing_io.py +++ b/PyStemmusScope/forcing_io.py @@ -96,7 +96,9 @@ def read_forcing_data_plumber2(forcing_file: Path, start_time: str, end_time: st data["latitude"] = ds_forcing["latitude"].values data["longitude"] = ds_forcing["longitude"].values data["elevation"] = ds_forcing["elevation"].values - data["IGBP_veg_long"] = ds_forcing["IGBP_veg_long"].values + data["IGBP_veg_long"] = np.repeat( + ds_forcing["IGBP_veg_long"].values, ds_forcing.time.size + ).T data["reference_height"] = ds_forcing["reference_height"].values data["canopy_height"] = ds_forcing["canopy_height"].values @@ -209,8 +211,6 @@ def prepare_global_variables(data: dict, input_path: Path): function `read_forcing_data`. input_path: Path to which the file should be written to. """ - total_duration = data["total_timesteps"] - matfile_vars = [ "latitude", "longitude", @@ -223,7 +223,7 @@ def prepare_global_variables(data: dict, input_path: Path): ] matfiledata = {key: data[key] for key in matfile_vars} - matfiledata["Dur_tot"] = float(total_duration) # Matlab expects a 'double' + matfiledata["Dur_tot"] = float(data["total_timesteps"]) # Matlab expects a 'double' hdf5storage.savemat( input_path / "forcing_globals.mat", matfiledata, appendmat=False diff --git a/PyStemmusScope/global_data/global_data_selection.py b/PyStemmusScope/global_data/global_data_selection.py index 0419cf18..86e69f17 100644 --- a/PyStemmusScope/global_data/global_data_selection.py +++ b/PyStemmusScope/global_data/global_data_selection.py @@ -106,9 +106,7 @@ def collect_datasets( time_range, timestep, ) - # TODO see issue github.com/EcoExtreML/STEMMUS_SCOPE/issues/137 - # for now, we only use the first value of the time series - data["IGBP_veg_long"] = landcover_data["IGBP_veg_long"][0] - data["LCCS_landcover"] = landcover_data["LCCS_landcover"][0] + data["IGBP_veg_long"] = landcover_data["IGBP_veg_long"] + data["LCCS_landcover"] = landcover_data["LCCS_landcover"] return data diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 00329519..e48d2313 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,8 +6,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.2.1] - 2023-04-03 +### Added: + +### Removed: + +### Changed: + + +## [0.3.0] - 2023-06-21 +This version is only compatible with [STEMMUS_SCOPE 1.3.0](https://github.com/EcoExtreML/STEMMUS_SCOPE/releases/tag/1.2.0). + +### Changed: +- The landcover type outputs in `forcing_globals.mat` (e.g. `IGBP_veg_long`) are now time dependent, instead of a single constant value ([#84](https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/pull/84)). + +### Fixed: +- The regional landcover classes from the IGBP classification system are now supported as well ([#80](https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/pull/80)). + +## [0.2.1] - 2023-04-03 This version is only compatible with [STEMMUS_SCOPE 1.2.0](https://github.com/EcoExtreML/STEMMUS_SCOPE/releases/tag/1.2.0). ### Added: @@ -22,7 +38,6 @@ This version is only compatible with [STEMMUS_SCOPE 1.2.0](https://github.com/Ec - The output netcdf file is again compatible to the model evaluation website ([#76](https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/pull/76)). ## [0.2.0] - 2023-02-21 - This version is only compatible with [STEMMUS_SCOPE 1.2.0](https://github.com/EcoExtreML/STEMMUS_SCOPE/releases/tag/1.2.0). ### Added: @@ -40,11 +55,9 @@ This version is only compatible with [STEMMUS_SCOPE 1.2.0](https://github.com/Ec ## [0.1.0] - 2022-11-24 The first release of PyStemmusScope. Compatible with STEMMUS_SCOPE 1.1.11. -### Added - -### Removed - -### Changed - - +[Unreleased]: https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/compare/v0.3.0...HEAD +[0.1.0]: https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/releases/tag/v0.1.0 +[0.1.1]: https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/releases/tag/v0.1.1 +[0.2.0]: https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/releases/tag/v0.2.0 +[0.2.1]: https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/releases/tag/v0.2.1 +[0.3.0]: https://github.com/EcoExtreML/STEMMUS_SCOPE_Processing/releases/tag/v0.3.0 diff --git a/tests/test_global_data_selection.py b/tests/test_global_data_selection.py index 4de6006e..34da96d0 100644 --- a/tests/test_global_data_selection.py +++ b/tests/test_global_data_selection.py @@ -43,7 +43,7 @@ def get_forcing_data(): ) -expected_keys_values = [ +expected_keys_values_float = [ ("wind_speed", (1**2 + 2**2) ** 0.5), ("t_air_celcius", 10), ("precip_conv", 3 / 10), @@ -60,22 +60,32 @@ def get_forcing_data(): ("canopy_height", 1.0), ("reference_height", 10.0), ("doy_float", 0.0), +] + + +@pytest.mark.parametrize("key, val", expected_keys_values_float) +def test_extract_forcing_data_floats(get_forcing_data, key, val): + data = get_forcing_data + assert key in data.keys() + + np.testing.assert_almost_equal( + np.array([val]), + data[key][0] if hasattr(data[key], "__iter__") else data[key], + ) + + +expected_keys_values_str = [ ("IGBP_veg_long", "Evergreen Needleleaf Forests"), ("LCCS_landcover", "tree_needleleaved_evergreen_closed_to_open"), ] -@pytest.mark.parametrize("key, val", expected_keys_values) -def test_extract_forcing_data(get_forcing_data, key, val): +@pytest.mark.parametrize("key, val", expected_keys_values_str) +def test_extract_forcing_data_str(get_forcing_data, key, val): data = get_forcing_data assert key in data.keys() - if isinstance(val, str): - assert data[key] == val - else: - np.testing.assert_almost_equal( - np.array([val]), - data[key][0] if hasattr(data[key], "__iter__") else data[key], - ) + + assert np.array([val]) == data[key][0] class TestEra5: