diff --git a/kerchunk/grib2.py b/kerchunk/grib2.py index 885b80c9..6536e7fc 100644 --- a/kerchunk/grib2.py +++ b/kerchunk/grib2.py @@ -120,6 +120,22 @@ def _store_array(store, z, data, var, inline_threshold, offset, size, attr): d.attrs.update(attr) +def contains_valid_level(message_keys: Set) -> bool: + """Check if the given set of message_keys contain a valid level value. + Some types of level, like depthBelowLandLayer for GEFS grib files, + represent slices of levels by "topLevel" and "bottomLevel" rather + than a discrete level value described by "level". + see https://github.com/fsspec/kerchunk/issues/559 + + Args: + message_keys: Set of keys to evaluate + + Returns: + True if message_keys contain a valid level value, False otherwise + """ + return "level" in message_keys or "topLevel" in message_keys + + def scan_grib( url, common=None, @@ -247,7 +263,7 @@ def scan_grib( _store_array( store_dict, z, vals, varName, inline_threshold, offset, size, attrs ) - if "typeOfLevel" in message_keys and "level" in message_keys: + if "typeOfLevel" in message_keys and contains_valid_level(message_keys: name = m["typeOfLevel"] coordinates.append(name) # convert to numpy scalar, so that .tobytes can be used for inlining diff --git a/tests/grib_idx_fixtures/gec00_20250101_00_soilw/gec00_20250101_00_soilw.grib b/tests/grib_idx_fixtures/gec00_20250101_00_soilw/gec00_20250101_00_soilw.grib new file mode 100644 index 00000000..a81aa640 Binary files /dev/null and b/tests/grib_idx_fixtures/gec00_20250101_00_soilw/gec00_20250101_00_soilw.grib differ