From 5a9044c6086fb8bcbe720f61144789e7975a5355 Mon Sep 17 00:00:00 2001 From: EddyCMWF Date: Fri, 19 Jul 2024 11:54:19 +0100 Subject: [PATCH] coords_as_attributes functionality --- cfgrib/dataset.py | 7 ++++++- cfgrib/xarray_plugin.py | 2 ++ tests/sample-data/soil-surface-level-mix.grib | Bin 0 -> 1836 bytes tests/test_50_xarray_plugin.py | 12 ++++++++++++ 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/sample-data/soil-surface-level-mix.grib diff --git a/cfgrib/dataset.py b/cfgrib/dataset.py index e29136db..63009722 100644 --- a/cfgrib/dataset.py +++ b/cfgrib/dataset.py @@ -494,6 +494,7 @@ def build_variable_components( read_keys: T.Iterable[str] = (), time_dims: T.Sequence[str] = ("time", "step"), extra_coords: T.Dict[str, str] = {}, + coords_as_attributes: T.Dict[str, str] = {}, cache_geo_coords: bool = True, ) -> T.Tuple[T.Dict[str, int], Variable, T.Dict[str, Variable]]: data_var_attrs = enforce_unique_attributes(index, DATA_ATTRIBUTES_KEYS, filter_by_keys) @@ -520,6 +521,9 @@ def build_variable_components( and "GRIB_typeOfLevel" in data_var_attrs ): coord_name = data_var_attrs["GRIB_typeOfLevel"] + if coord_name in coords_as_attributes and len(values) == 1: + data_var_attrs[f"GRIB_{coord_name}"] = values + continue coord_name_key_map[coord_name] = coord_key attributes = { "long_name": "original GRIB coordinate for key: %s(%s)" % (orig_name, coord_name), @@ -666,6 +670,7 @@ def build_dataset_components( read_keys: T.Iterable[str] = (), time_dims: T.Sequence[str] = ("time", "step"), extra_coords: T.Dict[str, str] = {}, + coords_as_attributes: T.Dict[str, str] = {}, cache_geo_coords: bool = True, ) -> T.Tuple[T.Dict[str, int], T.Dict[str, Variable], T.Dict[str, T.Any], T.Dict[str, T.Any]]: dimensions = {} # type: T.Dict[str, int] @@ -692,6 +697,7 @@ def build_dataset_components( read_keys=read_keys, time_dims=time_dims, extra_coords=extra_coords, + coords_as_attributes=coords_as_attributes, cache_geo_coords=cache_geo_coords, ) except DatasetBuildError as ex: @@ -814,5 +820,4 @@ def open_file( stream = messages.FileStream(path, errors=errors) index_keys = compute_index_keys(time_dims, extra_coords) index = open_fileindex(stream, indexpath, index_keys, ignore_keys=ignore_keys, filter_by_keys=filter_by_keys) - return open_from_index(index, read_keys, time_dims, extra_coords, errors=errors, **kwargs) diff --git a/cfgrib/xarray_plugin.py b/cfgrib/xarray_plugin.py index 4a972512..b5eea32c 100644 --- a/cfgrib/xarray_plugin.py +++ b/cfgrib/xarray_plugin.py @@ -105,6 +105,7 @@ def open_dataset( time_dims: T.Iterable[str] = ("time", "step"), errors: str = "warn", extra_coords: T.Dict[str, str] = {}, + coords_as_attributes: T.Dict[str, str] = {}, cache_geo_coords: bool = True, ) -> xr.Dataset: store = CfGribDataStore( @@ -119,6 +120,7 @@ def open_dataset( lock=lock, errors=errors, extra_coords=extra_coords, + coords_as_attributes=coords_as_attributes, cache_geo_coords=cache_geo_coords, ) with xr.core.utils.close_on_error(store): diff --git a/tests/sample-data/soil-surface-level-mix.grib b/tests/sample-data/soil-surface-level-mix.grib new file mode 100644 index 0000000000000000000000000000000000000000..a4dfe37b7083e8d9cc5c30ecd010fa962445314b GIT binary patch literal 1836 zcmZ<{@^oTg*uu!bVA7B@@qfc|AWMu9NB|KCh(ahh$tcdm!f0S%UH_Q+*e^iUhj27-I}6;b6sS8Akt)GU z+!gE}=+p>KVPHs_6By(A!`vi^r6k8B$48{OqxwxQB28j@!2W&t$ zJ6D*B7$vCb__Ab7F%VJJDf&_{qhv#!fzy-P2UQL=29+fZD=^&*4Chq^>@w7LGtXav zSe390-wDnw&Kh5^y7Pfs29Z znvw;@J4*i4N5odt&ZthPeN*|SaROF1Z!eHZp{kpCoCW1(3ar@BppaV-oZw|)q0#D5 zdn5lwjDlN+?T;3Zq>hji78^JX7#LDJ{I05 zOn|w8Eur&6y+f%*@`u)nc@I|INW8JhVME5IAICQw*lHMD)ey4Mei=B`^ak;wEf7*F9*|hJZbpA@u7Rm+ANq$n}GQN4zRgdliK-I&{{eH zf4pE nQ0ijX#VxCX=JBlV+Qd;lr(_Z5x!`+SjbJYIUjbtQX^@)%3;( None: @@ -164,3 +165,14 @@ def test_xr_open_dataset_file_missing_vals() -> None: t2 = ds["t2m"] assert np.isclose(np.nanmean(t2.values[0, :, :]), 268.375) assert np.isclose(np.nanmean(t2.values[1, :, :]), 270.716) + + +def test_xr_open_dataset_coords_to_attributes() -> None: + ds = xr.open_dataset( + TEST_DATA_MULTI_LEVTYPES, engine="cfgrib", coords_as_attributes=["surface", "depthBelowLandLayer"] + ) + assert "surface" not in ds.coords + assert "depthBelowLandLayer" not in ds.coords + + assert "GRIB_surface" in ds["t2m"].attrs + assert "GRIB_depthBelowLandLayer" in ds["stl1"].attrs \ No newline at end of file