From a5c2014bcc066fec3b58480f8aa070a27b63cc9d Mon Sep 17 00:00:00 2001 From: Sandor Kertesz Date: Mon, 8 Jun 2026 09:33:55 +0100 Subject: [PATCH] Allow setting raw metadata on field --- src/earthkit/data/core/field.py | 50 +++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/earthkit/data/core/field.py b/src/earthkit/data/core/field.py index 698969e0..fb39e3c0 100644 --- a/src/earthkit/data/core/field.py +++ b/src/earthkit/data/core/field.py @@ -1439,6 +1439,7 @@ def set(self, *args, **kwargs): return self _components = dict() + _raw = dict() for k, v in kwargs.items(): if k in self._components: _components[k] = v @@ -1448,7 +1449,12 @@ def set(self, *args, **kwargs): if key_name is not None and key_name != "": _kwargs[component_name][key_name] = v else: - raise KeyError(f"Key {k} cannot be set on the field.") + raise KeyError(f"Invalid key={k} specified.") + elif component_name == _METADATA: + if key_name is not None and key_name != "": + _raw[key_name] = v + else: + raise KeyError(f"Invalid key={k} specified.") else: raise KeyError(f"Key {k} cannot be set on the field.") @@ -1464,11 +1470,19 @@ def set(self, *args, **kwargs): s = component.set(**v) _components[component_name] = s + new_field = self if _components: - return self._from_set(**_components) + new_field = self._from_set(**_components) elif kwargs: raise ValueError("No valid keys to set in the field.") + if _raw: + new_field = new_field.sync() + if new_field is not self: + return new_field._set_metadata(_raw) + else: + return self._set_metadata(_raw) + return None def _set_values(self, array): @@ -1509,15 +1523,7 @@ def sync(self): >>> f2.metadata("shortName") 'msl' """ - if self._get_grib() and self._private and "_metadata" in self._private: - from earthkit.data.encoders.grib import GribEncoder - - encoder = GribEncoder() - f = encoder.encode(data=self).to_field() - if self.labels: - f = f.set(labels=self.labels) - return f - return self + return self._sync_metadata() def to_target(self, target, *args, **kwargs): r"""Write the field into a target object. @@ -1879,6 +1885,28 @@ def _get_grib_context(self, context): for m in self._components.values(): m.get_grib_context(context) + def _set_metadata(self, md): + new_field = self.sync() + g = new_field._get_grib() + if g is not None: + from earthkit.data.encoders.grib import GribEncoder + + encoder = GribEncoder() + d = encoder._encode(template=self, metadata=md) + return d.to_field() + return self + + def _sync_metadata(self): + if self._get_grib() and self._private and "_metadata" in self._private: + from earthkit.data.encoders.grib import GribEncoder + + encoder = GribEncoder() + f = encoder.encode(data=self).to_field() + if self.labels: + f = f.set(labels=self.labels) + return f + return self + @normalise("time.valid_datetime", "date") @normalise("time.base_datetime", "date") @normalise("time.forecast_reference_time", "date")