Skip to content

FunctionNotImplementedError when getting gridSpec from grib metadata #679

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
HCookie opened this issue Apr 16, 2025 · 4 comments
Open
Assignees
Labels
bug Something isn't working

Comments

@HCookie
Copy link
Member

HCookie commented Apr 16, 2025

What happened?

After updating to the new eccodes 2.41.0 running

data.metadata("gridSpec", default=None)

results in a FunctionNotImplementedError being raised from gribapi. In prior versions, the default was properly used, and returned.

What are the steps to reproduce the bug?

With eccodes==2.41.0

import earthkit.data as ekd
data = ekd.from_source('sample', 'aifs-single-mse-example.grib')

data.sel(param = '2t', step = 24).metadata("gridSpec", default=None)

Version

0.13.3

Platform (OS and architecture)

ATOS

Relevant log output

---------------------------------------------------------------------------
FunctionNotImplementedError               Traceback (most recent call last)
Cell In[4], line 1
----> 1 aifs.sel(param = '2t', step = 24).metadata("gridSpec", default=None)

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/earthkit/data/core/fieldlist.py:1297, in FieldList.metadata(self, *args, **kwargs)
   1295 result = []
   1296 for s in self:
-> 1297     result.append(s.metadata(*args, **kwargs))
   1298 return result

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/earthkit/data/core/fieldlist.py:623, in Field.metadata(self, astype, remapping, patches, *keys, **kwargs)
    619 raise_on_missing = "default" not in kwargs
    620 default = kwargs.pop("default", None)
    622 r = [
--> 623     self._metadata.get(
    624         k,
    625         default=default,
    626         astype=kt,
    627         raise_on_missing=raise_on_missing,
    628         **kwargs,
    629     )
    630     for k, kt in zip(key, astype)
    631 ]
    633 if key_arg_type is str:
    634     return r[0]

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/earthkit/data/core/metadata.py:119, in MetadataCacheHandler.cache_get.<locals>.wrapped(self, key, default, astype, raise_on_missing)
    116 if cache_id in self._cache:
    117     return self._cache[cache_id]
--> 119 v = func(self, key, default=default, astype=astype, raise_on_missing=raise_on_missing)
    120 self._cache[cache_id] = v
    121 return v

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/earthkit/data/core/metadata.py:81, in MetadataAccessor.__call__.<locals>.wrapped(cls, key, *args, **kwargs)
     79 if key in self:
     80     return self.get(cls, key, *args, **kwargs)
---> 81 return func(cls, key, *args, **kwargs)

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/earthkit/data/readers/grib/metadata.py:384, in GribMetadata.get(self, key, default, astype, raise_on_missing)
    380     key = key[5:]
    382 key = _key_name(key)
--> 384 v = self._handle.get(key, ktype=astype, **_kwargs)
    386 # special case when  "shortName" is "~".
    387 if key == "shortName" and v == "~":

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/earthkit/data/readers/grib/codes.py:155, in GribCodesHandle.get(self, name, ktype, **kwargs)
    152 elif name == "md5GridSection":
    153     return self.get_md5GridSection()
--> 155 return super().get(name, ktype, **kwargs)

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/earthkit/data/utils/message.py:215, in CodesHandle.get(self, name, ktype, **kwargs)
    212         ktype = CodesHandle.KEY_TYPES[key_type_str]
    214 if "default" in kwargs:
--> 215     return super().get(name, ktype=ktype, **kwargs)
    216 else:
    217     # this will throw if name is not available
    218     return super()._get(name, ktype=ktype)

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/eccodes/highlevel/message.py:68, in Message.get(self, name, default, ktype)
     56 """Get the value of a key
     57 
     58 Parameters
   (...)     65 ktype: type
     66     Request a specific type for the value. Overrides the suffix in ``name``"""
     67 try:
---> 68     return self._get(name, ktype=ktype)
     69 except KeyError:
     70     return default

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/eccodes/highlevel/message.py:53, in Message._get(self, name, ktype)
     51 if eccodes.codes_get_size(self._handle, name) > 1:
     52     return eccodes.codes_get_array(self._handle, name, ktype=ktype)
---> 53 return eccodes.codes_get(self._handle, name, ktype=ktype)

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/gribapi/gribapi.py:2021, in grib_get(msgid, key, ktype)
   2019     result = grib_get_double(msgid, key)
   2020 elif ktype is str:
-> 2021     result = grib_get_string(msgid, key)
   2022 elif ktype is bytes:
   2023     result = grib_get_string(msgid, key)

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/gribapi/gribapi.py:497, in grib_get_string(msgid, key)
    495 length_p = ffi.new("size_t *", length)
    496 err = lib.grib_get_string(h, key.encode(ENC), values, length_p)
--> 497 GRIB_CHECK(err)
    498 return _decode_bytes(values, length_p[0])

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/gribapi/gribapi.py:232, in GRIB_CHECK(errid)
    224 """
    225 Utility function checking the ecCodes error code and raising
    226 an error if that was set.
   (...)    229 @exception CodesInternalError
    230 """
    231 if errid:
--> 232     errors.raise_grib_error(errid)

File /etc/ecmwf/nfs/dh1_2_perm_a/ecm1947/venvs/earthkit/latest/lib/python3.12/site-packages/gribapi/errors.py:381, in raise_grib_error(errid)
    377 def raise_grib_error(errid):
    378     """
    379     Raise the GribInternalError corresponding to ``errid``.
    380     """
--> 381     raise ERROR_MAP[errid](errid)

FunctionNotImplementedError: Function not yet implemented

Accompanying data

No response

Organisation

ECMWF

@HCookie HCookie added the bug Something isn't working label Apr 16, 2025
@shahramn
Copy link

shahramn commented Apr 16, 2025

The gridSpec key is available but disabled. To enable it we have to make ecCodes depend on eckit (turning on the cmake option ENABLE_ECKIT_GEO). This is not ready yet so when you decode the gridSpec key, you get the error code GRIB_NOT_IMPLEMENTED

@sandorkertesz
Copy link
Collaborator

@shahramn, It comes down to the high level python API in ecCodes, which only returns the specified default value when there is a KeyError. Should not it do the same when the key is not implemented??

def get(self, name, default=None, ktype=None):
        """Get the value of a key

        Parameters
        ----------
        name: str
            Name of the key. Can be suffixed with ":str", ":int", or ":float" to
            request a specific type.
        default: any, optional
            Value if the key is not Found, or ``None`` if not specified.
        ktype: type
            Request a specific type for the value. Overrides the suffix in ``name``"""
        try:
            return self._get(name, ktype=ktype)
        except KeyError:
            return default

@shahramn
Copy link

OK. I can change the function to include FunctionNotImplementedError:

def raise_keyerror(name):
"""Make operations on a key raise a KeyError if not found"""
try:
yield
except (eccodes.KeyValueNotFoundError, eccodes.FunctionNotImplementedError):
raise KeyError(name)

@shahramn
Copy link

I have added a JIRA issue for ecCodes. See https://jira.ecmwf.int/browse/ECC-2072

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants