Functionality Not Enabled Error When Opening GEM GRIB Files
What happened?
Hi! I was trying to open a file that has GEM model data after downloading it with the following code:
import xarray as xr
ds = xr.open_dataset(f"GEM GLOBAL/ABSV_ISBL_200/CMC_glb_ABSV_ISBL_200_latlon.15x.15_2025091712_P000.grib2", engine='cfgrib')
ds['absv'].values
I got a "Functionality Not Enabled Error" when trying to look at the values in the array corresponding to the variable key. This has only been an issue so far with the GEM Global. I am not able to reproduce this issue for other models like the GFS or the RTMA etc so far. I've been using the same environment when working with other models.
What are the steps to reproduce the bug?
-
Download a file for the GEM Global from https://dd.weather.gc.ca/
-
Try opening the file in xarray with engine='cfgrib'
-
Try inspecting the data array for the variable (e.g. ds['absv'].values)
Version
0.9.15.0
Platform (OS and architecture)
Windows 64
Relevant log output
---------------------------------------------------------------------------
FunctionalityNotEnabledError Traceback (most recent call last)
Cell In[3], line 1
----> 1 ds['absv'].values
File ~\miniconda3\envs\wxdata\Lib\site-packages\xarray\core\dataarray.py:797, in DataArray.values(self)
784 @property
785 def values(self) -> np.ndarray:
786 """
787 The array's data converted to numpy.ndarray.
788
(...) 795 to this array may be reflected in the DataArray as well.
796 """
--> 797 return self.variable.values
File ~\miniconda3\envs\wxdata\Lib\site-packages\xarray\core\variable.py:556, in Variable.values(self)
553 @property
554 def values(self) -> np.ndarray:
555 """The variable's data as a numpy.ndarray"""
--> 556 return _as_array_or_item(self._data)
File ~\miniconda3\envs\wxdata\Lib\site-packages\xarray\core\variable.py:336, in _as_array_or_item(data)
322 def _as_array_or_item(data):
323 """Return the given values as a numpy array, or as an individual item if
324 it's a 0d datetime64 or timedelta64 array.
325
(...) 334 TODO: remove this (replace with np.asarray) once these issues are fixed
335 """
--> 336 data = np.asarray(data)
337 if data.ndim == 0:
338 kind = data.dtype.kind
File ~\miniconda3\envs\wxdata\Lib\site-packages\xarray\core\indexing.py:577, in ExplicitlyIndexed.__array__(self, dtype, copy)
572 def __array__(
573 self, dtype: np.typing.DTypeLike = None, /, *, copy: bool | None = None
574 ) -> np.ndarray:
575 # Leave casting to an array up to the underlying array type.
576 if Version(np.__version__) >= Version("2.0.0"):
--> 577 return np.asarray(self.get_duck_array(), dtype=dtype, copy=copy)
578 else:
579 return np.asarray(self.get_duck_array(), dtype=dtype)
File ~\miniconda3\envs\wxdata\Lib\site-packages\xarray\core\indexing.py:943, in MemoryCachedArray.get_duck_array(self)
942 def get_duck_array(self):
--> 943 duck_array = self.array.get_duck_array()
944 # ensure the array object is cached in-memory
945 self.array = as_indexable(duck_array)
File ~\miniconda3\envs\wxdata\Lib\site-packages\xarray\core\indexing.py:897, in CopyOnWriteArray.get_duck_array(self)
896 def get_duck_array(self):
--> 897 return self.array.get_duck_array()
File ~\miniconda3\envs\wxdata\Lib\site-packages\xarray\core\indexing.py:737, in LazilyIndexedArray.get_duck_array(self)
734 from xarray.backends.common import BackendArray
736 if isinstance(self.array, BackendArray):
--> 737 array = self.array[self.key]
738 else:
739 array = apply_indexer(self.array, self.key)
File ~\miniconda3\envs\wxdata\Lib\site-packages\cfgrib\xarray_plugin.py:163, in CfGribArrayWrapper.__getitem__(self, key)
159 def __getitem__(
160 self,
161 key: xr.core.indexing.ExplicitIndexer,
162 ) -> np.ndarray:
--> 163 return xr.core.indexing.explicit_indexing_adapter(
164 key, self.shape, xr.core.indexing.IndexingSupport.BASIC, self._getitem
165 )
File ~\miniconda3\envs\wxdata\Lib\site-packages\xarray\core\indexing.py:1129, in explicit_indexing_adapter(key, shape, indexing_support, raw_indexing_method)
1107 """Support explicit indexing by delegating to a raw indexing method.
1108
1109 Outer and/or vectorized indexers are supported by indexing a second time
(...) 1126 Indexing result, in the form of a duck numpy-array.
1127 """
1128 raw_key, numpy_indices = decompose_indexer(key, shape, indexing_support)
-> 1129 result = raw_indexing_method(raw_key.tuple)
1130 if numpy_indices.tuple:
1131 # index the loaded duck array
1132 indexable = as_indexable(result)
File ~\miniconda3\envs\wxdata\Lib\site-packages\cfgrib\xarray_plugin.py:172, in CfGribArrayWrapper._getitem(self, key)
167 def _getitem(
168 self,
169 key: T.Tuple[T.Any, ...],
170 ) -> np.ndarray:
171 with self.datastore.lock:
--> 172 return self.array[key]
File ~\miniconda3\envs\wxdata\Lib\site-packages\cfgrib\dataset.py:374, in OnDiskArray.__getitem__(self, item)
372 # NOTE: fill a single field as found in the message
373 message = self.index.get_field(message_ids[0]) # type: ignore
--> 374 values = get_values_in_order(message, array_field[tuple(array_field_indexes)].shape)
375 array_field.__getitem__(tuple(array_field_indexes)).flat[:] = values
377 array = np.asarray(array_field[(Ellipsis,) + item[-self.geo_ndim :]])
File ~\miniconda3\envs\wxdata\Lib\site-packages\cfgrib\dataset.py:329, in get_values_in_order(message, shape)
326 def get_values_in_order(message, shape):
327 # type: (abc.Field, T.Tuple[int]) -> np.ndarray
328 # inform the data provider to return missing values as missing_value
--> 329 values = message["values"]
330 # for 2D array (lat/lon) re-arrange if alternative row scanning
331 if len(shape) == 2 and message.get("alternativeRowScanning", False):
File ~\miniconda3\envs\wxdata\Lib\site-packages\cfgrib\messages.py:247, in ComputedKeysAdapter.__getitem__(self, item)
245 return getter(self)
246 else:
--> 247 return self.context[item]
File ~\miniconda3\envs\wxdata\Lib\site-packages\cfgrib\messages.py:169, in Message.__getitem__(self, item)
167 raise ValueError("key type not supported %r" % key_type_text)
168 key_type = KEY_TYPES[key_type_text]
--> 169 return self.message_get(key, key_type=key_type)
File ~\miniconda3\envs\wxdata\Lib\site-packages\cfgrib\messages.py:132, in Message.message_get(self, item, key_type, default)
130 try:
131 if eccodes.codes_get_size(self.codes_id, item) > 1:
--> 132 values = eccodes.codes_get_array(self.codes_id, item, key_type)
133 else:
134 values = [eccodes.codes_get(self.codes_id, item, key_type)]
File ~\miniconda3\envs\wxdata\Lib\site-packages\gribapi\gribapi.py:2028, in grib_get_array(msgid, key, ktype)
2026 result = grib_get_long_array(msgid, key)
2027 elif ktype is float or ktype is np.float64:
-> 2028 result = grib_get_double_array(msgid, key)
2029 elif ktype is np.float32:
2030 result = grib_get_float_array(msgid, key)
File ~\miniconda3\envs\wxdata\Lib\site-packages\gribapi\gribapi.py:1196, in grib_get_double_array(msgid, key)
1194 vals_p = ffi.cast("double *", arr.ctypes.data)
1195 err = lib.grib_get_double_array(h, key.encode(ENC), vals_p, length_p)
-> 1196 GRIB_CHECK(err)
1197 return arr
File ~\miniconda3\envs\wxdata\Lib\site-packages\gribapi\gribapi.py:226, in GRIB_CHECK(errid)
218 """
219 Utility function checking the ecCodes error code and raising
220 an error if that was set.
(...) 223 @exception CodesInternalError
224 """
225 if errid:
--> 226 errors.raise_grib_error(errid)
File ~\miniconda3\envs\wxdata\Lib\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)
FunctionalityNotEnabledError: Functionality not enabled
Accompanying data
https://dd.weather.gc.ca/20250918/WXO-DD/model_gem_global/15km/grib2/lat_lon/00/000/
Organisation
No response
Hi @edrewitz, I downloaded a sample of this data and noticed that it is jpeg-encoded. Are you able to tell me how the ecCodes binary has been installed? You can inspect this by setting the following command-line environment variable before starting your Python program:
set ECCODES_PYTHON_TRACE_LIB_SEARCH=1
You should now get some output that tells you where the binary library is being found. That will help determine the cause - most likely that your version of the library has been built without jpeg support.
Hi @iainrussell and thank you for your reply. The version of ecCodes I am using is 2.43.0. Is there a newer version I should install for jpeg support? Also, I am using a Windows OS.
Hi @edrewitz, what I need to know is how you installed the ecCodes binary - this is separate from the ecCodes Python bindings. Perhaps you are running in a conda environment, or a pure 'pip' environment - these will have different builds of the ecCodes binary library. The environment variable I suggested above will also help us know where the binaries are coming from.
Hi @iainrussell I installed cfgrib and thus ecCodes via pip.
Hi @iainrussell I am curious if there are any plans in making the version on pip have the functionality the conda version has?