From 72675177f2b2cfb9cd0e5c017fe3adb07592dbe0 Mon Sep 17 00:00:00 2001 From: Florian Pinault Date: Thu, 21 Nov 2024 16:30:59 +0000 Subject: [PATCH 1/3] adding sum (experimental) --- src/anemoi/transform/filters/sum.py | 48 +++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/anemoi/transform/filters/sum.py diff --git a/src/anemoi/transform/filters/sum.py b/src/anemoi/transform/filters/sum.py new file mode 100644 index 0000000..775a653 --- /dev/null +++ b/src/anemoi/transform/filters/sum.py @@ -0,0 +1,48 @@ +# (C) Copyright 2024 Anemoi contributors. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation +# nor does it submit to any jurisdiction. + + +from . import filter_registry +from .base import SimpleFilter + + +@filter_registry.register("sum") +class Sum(SimpleFilter): + """A filter to sum some parameters""" + + def __init__( + self, + *, + formula, + ): + assert isinstance(formula, dict) + assert len(formula) == 1 + self.name = list(formula.keys())[0] + self.args = list(formula.values())[0] + + def forward(self, data): + return self._transform(data, self.forward_transform, *self.args) + + def backward(self, data): + raise NotImplementedError("Fire is not reversible") + + def forward_transform(self, *args): + """Sum the fuel components to get the total fuel""" + total = None + for arg in args: + if total is None: + template = arg + total = template.to_numpy() + else: + total += arg.to_numpy() + + yield self.new_field_from_numpy(total, template=template, param=self.name) + + def backward_transform(self, total_fuel): + raise NotImplementedError("Fire is not reversible") From aa6ec0a1ab89dcbc493570d575efb1cfe545634e Mon Sep 17 00:00:00 2001 From: Florian Pinault Date: Thu, 21 Nov 2024 16:32:53 +0000 Subject: [PATCH 2/3] adding sum (experimental) --- src/anemoi/transform/filters/sum.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/anemoi/transform/filters/sum.py b/src/anemoi/transform/filters/sum.py index 775a653..0f5072b 100644 --- a/src/anemoi/transform/filters/sum.py +++ b/src/anemoi/transform/filters/sum.py @@ -30,7 +30,7 @@ def forward(self, data): return self._transform(data, self.forward_transform, *self.args) def backward(self, data): - raise NotImplementedError("Fire is not reversible") + raise NotImplementedError("Sum is not reversible") def forward_transform(self, *args): """Sum the fuel components to get the total fuel""" @@ -44,5 +44,5 @@ def forward_transform(self, *args): yield self.new_field_from_numpy(total, template=template, param=self.name) - def backward_transform(self, total_fuel): - raise NotImplementedError("Fire is not reversible") + def backward_transform(self, data): + raise NotImplementedError("Sum is not reversible") From 32729f6de9b4ef8688469374e9dd4f18f27f7eeb Mon Sep 17 00:00:00 2001 From: Florian Pinault Date: Tue, 26 Nov 2024 19:18:48 +0000 Subject: [PATCH 3/3] experimental "timeseries" filter. Syntax is bad, and will change --- src/anemoi/transform/filters/sum.py | 5 ++ src/anemoi/transform/filters/timeseries.py | 65 ++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/anemoi/transform/filters/timeseries.py diff --git a/src/anemoi/transform/filters/sum.py b/src/anemoi/transform/filters/sum.py index 0f5072b..bda7f12 100644 --- a/src/anemoi/transform/filters/sum.py +++ b/src/anemoi/transform/filters/sum.py @@ -8,9 +8,13 @@ # nor does it submit to any jurisdiction. +import logging + from . import filter_registry from .base import SimpleFilter +LOG = logging.getLogger(__name__) + @filter_registry.register("sum") class Sum(SimpleFilter): @@ -25,6 +29,7 @@ def __init__( assert len(formula) == 1 self.name = list(formula.keys())[0] self.args = list(formula.values())[0] + LOG.warning("Using the sum filter will be deprecated in the future. Please do not rely on it.") def forward(self, data): return self._transform(data, self.forward_transform, *self.args) diff --git a/src/anemoi/transform/filters/timeseries.py b/src/anemoi/transform/filters/timeseries.py new file mode 100644 index 0000000..c9ceb72 --- /dev/null +++ b/src/anemoi/transform/filters/timeseries.py @@ -0,0 +1,65 @@ +# (C) Copyright 2024 Anemoi contributors. +# +# This software is licensed under the terms of the Apache Licence Version 2.0 +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. +# +# In applying this licence, ECMWF does not waive the privileges and immunities +# granted to it by virtue of its status as an intergovernmental organisation +# nor does it submit to any jurisdiction. + + +import logging + +import numpy as np + +from . import filter_registry +from .base import SimpleFilter + +LOG = logging.getLogger(__name__) + +# class MyFilter(SuperSimpleFilter): +# def __init__(self, *, param): +# self.param = param +# +# def transform(date, tp, lsm): +# new = tp + lsm + self.data(self.param, date) +# return dict(q_500 = new) + + +@filter_registry.register("timeseries") +class Timeseries(SimpleFilter): + """A source to add a timeseries depending on time but not on location""" + + def __init__(self, *, netcdf=None, template_param="2t"): + if netcdf: + import xarray as xr + + self.ds = xr.open_dataset(netcdf["path"]) # .to_dataframe() + LOG.warning("Using the timeseries filter will be deprecated in the future. Please do not rely on it.") + + self.template_param = template_param + + def forward(self, data): + return self._transform( + data, + self.forward_transform, + self.template_param, + ) + + def forward_transform(self, template): + """Convert snow depth and snow density to snow cover""" + dt = template.metadata("valid_datetime") + template_array = template.to_numpy() + + sel = self.ds.sel(time=dt) + + for name in self.ds.data_vars: + value = sel[name].values + data = np.full_like(template_array, value) + yield self.new_field_from_numpy(data, template=template, param=name) + + def backward(self, data): + raise NotImplementedError("SnowCover is not reversible") + + def backward_transform(self, sd, rsn): + raise NotImplementedError("SnowCover is not reversible")