From 235d10437f6589e768fc3a96351ef3727b635300 Mon Sep 17 00:00:00 2001 From: Baudouin Raoult Date: Sun, 25 Feb 2024 18:01:32 +0000 Subject: [PATCH 1/3] update --- climetlab/readers/netcdf/field.py | 9 ++++----- climetlab/readers/netcdf/fieldset.py | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/climetlab/readers/netcdf/field.py b/climetlab/readers/netcdf/field.py index 3ff3a46b..cd9298e8 100644 --- a/climetlab/readers/netcdf/field.py +++ b/climetlab/readers/netcdf/field.py @@ -84,7 +84,7 @@ def to_bounding_box(self): ) @cached_property - def projection(self): + def grid_mapping(self): def tidy(x): if isinstance(x, np.ndarray): return x.tolist() @@ -95,7 +95,9 @@ def tidy(x): return x return tidy( - self.owner.xr_dataset[self.owner.xr_dataset[self.variable].grid_mapping].attrs + self.owner.xr_dataset[ + self.owner.xr_dataset[self.variable].grid_mapping + ].attrs ) # Compatibility to GRIb fields below @@ -103,9 +105,6 @@ def tidy(x): def grid_points(self): return DataSet(self.owner.xr_dataset).grid_points(self.variable) - def grid_points_xy(self): - return DataSet(self.owner.xr_dataset).grid_points_xy(self.variable) - def to_numpy(self, reshape=True, dtype=None): dimensions = dict((s.name, s.index) for s in self.slices) values = self.owner.xr_dataset[self.variable].isel(dimensions).values diff --git a/climetlab/readers/netcdf/fieldset.py b/climetlab/readers/netcdf/fieldset.py index 8989b1da..4cd08682 100644 --- a/climetlab/readers/netcdf/fieldset.py +++ b/climetlab/readers/netcdf/fieldset.py @@ -214,7 +214,6 @@ def __init__(self, *args, **kwargs): MaskIndex.__init__(self, *args, **kwargs) self.path = "" - @cached_property def fields(self): return list(self.index[i] for i in self.indices) From 92c3da1ad9afcbd0361564cd4d319c3c0d65da93 Mon Sep 17 00:00:00 2001 From: Florian Pinault Date: Mon, 26 Feb 2024 10:36:11 +0000 Subject: [PATCH 2/3] added +6h -6h for constants sources --- climetlab/sources/constants.py | 31 +++++++++++++++++++++++++++++++ tests/sources/test_constants.py | 21 +++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/climetlab/sources/constants.py b/climetlab/sources/constants.py index 2bee39a6..59f1e8c8 100644 --- a/climetlab/sources/constants.py +++ b/climetlab/sources/constants.py @@ -181,6 +181,37 @@ def cos_solar_zenith_angle(self, date): ) return result.flatten() + def __getattr__(self, name): + if not "+" in name and not "-" in name: + # If we are here, we are looking for a method that does not exist, + # it has to be a method with a time delta. + raise AttributeError(name) + if "+" in name: + fname, delta = name.split("+") + sign = 1 + if "-" in name: + fname, delta = name.split("-") + sign = -1 + method = getattr(self, fname) + + if delta.endswith("h"): + factor = 60 + elif delta.endswith("d"): + factor = 24 * 60 + else: + raise ValueError(f"Invalid time delta {delta} in {name}") + + delta = delta[:-1] + delta = int(delta) + delta = datetime.timedelta(minutes=delta) * factor * sign + + def wrapper(date): + date = date + delta + value = method(date) + return value + + return wrapper + class ConstantField: def __init__( diff --git a/tests/sources/test_constants.py b/tests/sources/test_constants.py index fddc9207..5f7161ed 100644 --- a/tests/sources/test_constants.py +++ b/tests/sources/test_constants.py @@ -10,6 +10,7 @@ # import datetime +import numpy as np from climetlab import load_source from climetlab.testing import climetlab_file @@ -86,6 +87,26 @@ def test_constant_2(): assert len(ds) == len(params) * len(dates) * ntimes +def test_constant_3(): + sample = load_source("file", climetlab_file("docs/examples/test.grib")) + + date = sample[0].datetime() + date_plus_6h = date + datetime.timedelta(hours=6) + a = load_source("constants", sample, date=date_plus_6h, param="insolation") + b = load_source("constants", sample, date=date, param="insolation+6h") + assert np.all(a.to_numpy() == b.to_numpy()) + assert a.unique_values("param")["param"] == ("insolation",) + assert b.unique_values("param")["param"] == ("insolation+6h",) + + date = sample[0].datetime() + date_minus_30d = date + datetime.timedelta(days=-30) + a = load_source("constants", sample, date=date_minus_30d, param="insolation") + b = load_source("constants", sample, date=date, param="insolation-30d") + assert np.all(a.to_numpy() == b.to_numpy()) + assert a.unique_values("param")["param"] == ("insolation",) + assert b.unique_values("param")["param"] == ("insolation-30d",) + + if __name__ == "__main__": from climetlab.testing import main From 26f776a6d8ce8c88454bfc69d04c6c8f25f8ed39 Mon Sep 17 00:00:00 2001 From: Florian Pinault Date: Mon, 26 Feb 2024 10:37:11 +0000 Subject: [PATCH 3/3] Bump version 0.21.1 --- climetlab/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/climetlab/version b/climetlab/version index 88541566..a67cebaf 100644 --- a/climetlab/version +++ b/climetlab/version @@ -1 +1 @@ -0.21.0 +0.21.1