anemoi-datasets 0.5.16__py3-none-any.whl → 0.5.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- anemoi/datasets/__init__.py +4 -1
- anemoi/datasets/__main__.py +12 -2
- anemoi/datasets/_version.py +9 -4
- anemoi/datasets/commands/cleanup.py +17 -2
- anemoi/datasets/commands/compare.py +18 -2
- anemoi/datasets/commands/copy.py +196 -14
- anemoi/datasets/commands/create.py +50 -7
- anemoi/datasets/commands/finalise-additions.py +17 -2
- anemoi/datasets/commands/finalise.py +17 -2
- anemoi/datasets/commands/init-additions.py +17 -2
- anemoi/datasets/commands/init.py +16 -2
- anemoi/datasets/commands/inspect.py +283 -62
- anemoi/datasets/commands/load-additions.py +16 -2
- anemoi/datasets/commands/load.py +16 -2
- anemoi/datasets/commands/patch.py +17 -2
- anemoi/datasets/commands/publish.py +17 -2
- anemoi/datasets/commands/scan.py +31 -3
- anemoi/datasets/compute/recentre.py +47 -11
- anemoi/datasets/create/__init__.py +612 -85
- anemoi/datasets/create/check.py +142 -20
- anemoi/datasets/create/chunks.py +64 -4
- anemoi/datasets/create/config.py +185 -21
- anemoi/datasets/create/filter.py +50 -0
- anemoi/datasets/create/filters/__init__.py +33 -0
- anemoi/datasets/create/filters/empty.py +37 -0
- anemoi/datasets/create/filters/legacy.py +93 -0
- anemoi/datasets/create/filters/noop.py +37 -0
- anemoi/datasets/create/filters/orog_to_z.py +58 -0
- anemoi/datasets/create/{functions/filters → filters}/pressure_level_relative_humidity_to_specific_humidity.py +33 -10
- anemoi/datasets/create/{functions/filters → filters}/pressure_level_specific_humidity_to_relative_humidity.py +32 -8
- anemoi/datasets/create/filters/rename.py +205 -0
- anemoi/datasets/create/{functions/filters → filters}/rotate_winds.py +43 -28
- anemoi/datasets/create/{functions/filters → filters}/single_level_dewpoint_to_relative_humidity.py +32 -9
- anemoi/datasets/create/{functions/filters → filters}/single_level_relative_humidity_to_dewpoint.py +33 -9
- anemoi/datasets/create/{functions/filters → filters}/single_level_relative_humidity_to_specific_humidity.py +55 -7
- anemoi/datasets/create/{functions/filters → filters}/single_level_specific_humidity_to_relative_humidity.py +98 -37
- anemoi/datasets/create/filters/speeddir_to_uv.py +95 -0
- anemoi/datasets/create/{functions/filters → filters}/sum.py +24 -27
- anemoi/datasets/create/filters/transform.py +53 -0
- anemoi/datasets/create/{functions/filters → filters}/unrotate_winds.py +27 -18
- anemoi/datasets/create/filters/uv_to_speeddir.py +94 -0
- anemoi/datasets/create/{functions/filters → filters}/wz_to_w.py +51 -33
- anemoi/datasets/create/input/__init__.py +76 -5
- anemoi/datasets/create/input/action.py +149 -13
- anemoi/datasets/create/input/concat.py +81 -10
- anemoi/datasets/create/input/context.py +39 -4
- anemoi/datasets/create/input/data_sources.py +72 -6
- anemoi/datasets/create/input/empty.py +21 -3
- anemoi/datasets/create/input/filter.py +60 -12
- anemoi/datasets/create/input/function.py +154 -37
- anemoi/datasets/create/input/join.py +86 -14
- anemoi/datasets/create/input/misc.py +67 -17
- anemoi/datasets/create/input/pipe.py +33 -6
- anemoi/datasets/create/input/repeated_dates.py +189 -41
- anemoi/datasets/create/input/result.py +202 -87
- anemoi/datasets/create/input/step.py +119 -22
- anemoi/datasets/create/input/template.py +100 -13
- anemoi/datasets/create/input/trace.py +62 -7
- anemoi/datasets/create/patch.py +52 -4
- anemoi/datasets/create/persistent.py +134 -17
- anemoi/datasets/create/size.py +15 -1
- anemoi/datasets/create/source.py +51 -0
- anemoi/datasets/create/sources/__init__.py +36 -0
- anemoi/datasets/create/{functions/sources → sources}/accumulations.py +296 -30
- anemoi/datasets/create/{functions/sources → sources}/constants.py +27 -2
- anemoi/datasets/create/{functions/sources → sources}/eccc_fstd.py +7 -3
- anemoi/datasets/create/sources/empty.py +37 -0
- anemoi/datasets/create/{functions/sources → sources}/forcings.py +25 -1
- anemoi/datasets/create/sources/grib.py +297 -0
- anemoi/datasets/create/{functions/sources → sources}/hindcasts.py +38 -4
- anemoi/datasets/create/sources/legacy.py +93 -0
- anemoi/datasets/create/{functions/sources → sources}/mars.py +168 -20
- anemoi/datasets/create/sources/netcdf.py +42 -0
- anemoi/datasets/create/sources/opendap.py +43 -0
- anemoi/datasets/create/{functions/sources/__init__.py → sources/patterns.py} +35 -4
- anemoi/datasets/create/sources/recentre.py +150 -0
- anemoi/datasets/create/{functions/sources → sources}/source.py +27 -5
- anemoi/datasets/create/{functions/sources → sources}/tendencies.py +64 -7
- anemoi/datasets/create/sources/xarray.py +92 -0
- anemoi/datasets/create/sources/xarray_kerchunk.py +36 -0
- anemoi/datasets/create/sources/xarray_support/README.md +1 -0
- anemoi/datasets/create/{functions/sources/xarray → sources/xarray_support}/__init__.py +109 -8
- anemoi/datasets/create/sources/xarray_support/coordinates.py +442 -0
- anemoi/datasets/create/{functions/sources/xarray → sources/xarray_support}/field.py +94 -16
- anemoi/datasets/create/{functions/sources/xarray → sources/xarray_support}/fieldlist.py +90 -25
- anemoi/datasets/create/sources/xarray_support/flavour.py +1036 -0
- anemoi/datasets/create/{functions/sources/xarray → sources/xarray_support}/grid.py +92 -31
- anemoi/datasets/create/sources/xarray_support/metadata.py +395 -0
- anemoi/datasets/create/sources/xarray_support/patch.py +91 -0
- anemoi/datasets/create/sources/xarray_support/time.py +391 -0
- anemoi/datasets/create/sources/xarray_support/variable.py +331 -0
- anemoi/datasets/create/sources/xarray_zarr.py +41 -0
- anemoi/datasets/create/{functions/sources → sources}/zenodo.py +34 -5
- anemoi/datasets/create/statistics/__init__.py +233 -44
- anemoi/datasets/create/statistics/summary.py +52 -6
- anemoi/datasets/create/testing.py +76 -0
- anemoi/datasets/create/{functions/filters/noop.py → typing.py} +6 -3
- anemoi/datasets/create/utils.py +97 -6
- anemoi/datasets/create/writer.py +26 -4
- anemoi/datasets/create/zarr.py +170 -23
- anemoi/datasets/data/__init__.py +51 -4
- anemoi/datasets/data/complement.py +191 -40
- anemoi/datasets/data/concat.py +141 -16
- anemoi/datasets/data/dataset.py +552 -61
- anemoi/datasets/data/debug.py +197 -26
- anemoi/datasets/data/ensemble.py +93 -8
- anemoi/datasets/data/fill_missing.py +165 -18
- anemoi/datasets/data/forwards.py +428 -56
- anemoi/datasets/data/grids.py +323 -97
- anemoi/datasets/data/indexing.py +112 -19
- anemoi/datasets/data/interpolate.py +92 -12
- anemoi/datasets/data/join.py +158 -19
- anemoi/datasets/data/masked.py +129 -15
- anemoi/datasets/data/merge.py +137 -23
- anemoi/datasets/data/misc.py +172 -16
- anemoi/datasets/data/missing.py +233 -29
- anemoi/datasets/data/rescale.py +111 -10
- anemoi/datasets/data/select.py +168 -26
- anemoi/datasets/data/statistics.py +67 -6
- anemoi/datasets/data/stores.py +149 -64
- anemoi/datasets/data/subset.py +159 -25
- anemoi/datasets/data/unchecked.py +168 -57
- anemoi/datasets/data/xy.py +168 -25
- anemoi/datasets/dates/__init__.py +191 -16
- anemoi/datasets/dates/groups.py +189 -47
- anemoi/datasets/grids.py +270 -31
- anemoi/datasets/testing.py +28 -1
- {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.17.dist-info}/METADATA +9 -6
- anemoi_datasets-0.5.17.dist-info/RECORD +137 -0
- {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.17.dist-info}/WHEEL +1 -1
- anemoi/datasets/create/functions/__init__.py +0 -66
- anemoi/datasets/create/functions/filters/__init__.py +0 -9
- anemoi/datasets/create/functions/filters/empty.py +0 -17
- anemoi/datasets/create/functions/filters/orog_to_z.py +0 -58
- anemoi/datasets/create/functions/filters/rename.py +0 -79
- anemoi/datasets/create/functions/filters/speeddir_to_uv.py +0 -78
- anemoi/datasets/create/functions/filters/uv_to_speeddir.py +0 -56
- anemoi/datasets/create/functions/sources/empty.py +0 -15
- anemoi/datasets/create/functions/sources/grib.py +0 -150
- anemoi/datasets/create/functions/sources/netcdf.py +0 -15
- anemoi/datasets/create/functions/sources/opendap.py +0 -15
- anemoi/datasets/create/functions/sources/recentre.py +0 -60
- anemoi/datasets/create/functions/sources/xarray/coordinates.py +0 -255
- anemoi/datasets/create/functions/sources/xarray/flavour.py +0 -472
- anemoi/datasets/create/functions/sources/xarray/metadata.py +0 -148
- anemoi/datasets/create/functions/sources/xarray/patch.py +0 -44
- anemoi/datasets/create/functions/sources/xarray/time.py +0 -177
- anemoi/datasets/create/functions/sources/xarray/variable.py +0 -188
- anemoi/datasets/create/functions/sources/xarray_kerchunk.py +0 -42
- anemoi/datasets/create/functions/sources/xarray_zarr.py +0 -15
- anemoi/datasets/utils/fields.py +0 -47
- anemoi_datasets-0.5.16.dist-info/RECORD +0 -129
- {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.17.dist-info}/entry_points.txt +0 -0
- {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.17.dist-info/licenses}/LICENSE +0 -0
- {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.17.dist-info}/top_level.txt +0 -0
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
|
|
11
11
|
import logging
|
|
12
12
|
from collections import defaultdict
|
|
13
|
+
from typing import Any
|
|
14
|
+
from typing import Dict
|
|
15
|
+
from typing import Generator
|
|
16
|
+
from typing import List
|
|
17
|
+
from typing import Optional
|
|
18
|
+
from typing import Set
|
|
19
|
+
from typing import Tuple
|
|
13
20
|
|
|
14
21
|
import numpy as np
|
|
15
22
|
from anemoi.transform.fields import new_field_with_valid_datetime
|
|
@@ -27,11 +34,27 @@ LOG = logging.getLogger(__name__)
|
|
|
27
34
|
|
|
28
35
|
|
|
29
36
|
class DateMapper:
|
|
37
|
+
"""A factory class to create DateMapper instances based on the given mode."""
|
|
30
38
|
|
|
31
39
|
@staticmethod
|
|
32
|
-
def from_mode(mode, source, config):
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
def from_mode(mode: str, source: Any, config: Dict[str, Any]) -> "DateMapper":
|
|
41
|
+
"""Create a DateMapper instance based on the given mode.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
mode : str
|
|
46
|
+
The mode to use for the DateMapper.
|
|
47
|
+
source : Any
|
|
48
|
+
The data source.
|
|
49
|
+
config : dict
|
|
50
|
+
Configuration parameters.
|
|
51
|
+
|
|
52
|
+
Returns
|
|
53
|
+
-------
|
|
54
|
+
DateMapper
|
|
55
|
+
An instance of DateMapper.
|
|
56
|
+
"""
|
|
57
|
+
MODES: dict = dict(
|
|
35
58
|
closest=DateMapperClosest,
|
|
36
59
|
climatology=DateMapperClimatology,
|
|
37
60
|
constant=DateMapperConstant,
|
|
@@ -44,15 +67,42 @@ class DateMapper:
|
|
|
44
67
|
|
|
45
68
|
|
|
46
69
|
class DateMapperClosest(DateMapper):
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
"""A DateMapper implementation that maps dates to the closest available dates."""
|
|
71
|
+
|
|
72
|
+
def __init__(self, source: Any, frequency: str = "1h", maximum: str = "30d", skip_all_nans: bool = False) -> None:
|
|
73
|
+
"""Initialize DateMapperClosest.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
source : Any
|
|
78
|
+
The data source.
|
|
79
|
+
frequency : str
|
|
80
|
+
Frequency of the dates.
|
|
81
|
+
maximum : str
|
|
82
|
+
Maximum time delta.
|
|
83
|
+
skip_all_nans : bool
|
|
84
|
+
Whether to skip all NaN values.
|
|
85
|
+
"""
|
|
86
|
+
self.source: Any = source
|
|
87
|
+
self.maximum: Any = frequency_to_timedelta(maximum)
|
|
88
|
+
self.frequency: Any = frequency_to_timedelta(frequency)
|
|
89
|
+
self.skip_all_nans: bool = skip_all_nans
|
|
90
|
+
self.tried: Set[Any] = set()
|
|
91
|
+
self.found: Set[Any] = set()
|
|
92
|
+
|
|
93
|
+
def transform(self, group_of_dates: Any) -> Generator[Tuple[Any, Any], None, None]:
|
|
94
|
+
"""Transform the group of dates to the closest available dates.
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
group_of_dates : Any
|
|
99
|
+
The group of dates to transform.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
Generator[Tuple[Any, Any], None, None]
|
|
104
|
+
Transformed dates.
|
|
105
|
+
"""
|
|
56
106
|
from anemoi.datasets.dates.groups import GroupOfDates
|
|
57
107
|
|
|
58
108
|
asked_dates = list(group_of_dates)
|
|
@@ -133,12 +183,39 @@ class DateMapperClosest(DateMapper):
|
|
|
133
183
|
|
|
134
184
|
|
|
135
185
|
class DateMapperClimatology(DateMapper):
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
186
|
+
"""A DateMapper implementation that maps dates to specified climatology dates."""
|
|
187
|
+
|
|
188
|
+
def __init__(self, source: Any, year: int, day: int, hour: Optional[int] = None) -> None:
|
|
189
|
+
"""Initialize DateMapperClimatology.
|
|
190
|
+
|
|
191
|
+
Parameters
|
|
192
|
+
----------
|
|
193
|
+
source : Any
|
|
194
|
+
The data source.
|
|
195
|
+
year : int
|
|
196
|
+
The year to map to.
|
|
197
|
+
day : int
|
|
198
|
+
The day to map to.
|
|
199
|
+
hour : Optional[int]
|
|
200
|
+
The hour to map to.
|
|
201
|
+
"""
|
|
202
|
+
self.year: int = year
|
|
203
|
+
self.day: int = day
|
|
204
|
+
self.hour: Optional[int] = hour
|
|
205
|
+
|
|
206
|
+
def transform(self, group_of_dates: Any) -> Generator[Tuple[Any, Any], None, None]:
|
|
207
|
+
"""Transform the group of dates to the specified climatology dates.
|
|
208
|
+
|
|
209
|
+
Parameters
|
|
210
|
+
----------
|
|
211
|
+
group_of_dates : Any
|
|
212
|
+
The group of dates to transform.
|
|
213
|
+
|
|
214
|
+
Returns
|
|
215
|
+
-------
|
|
216
|
+
Generator[Tuple[Any, Any], None, None]
|
|
217
|
+
Transformed dates.
|
|
218
|
+
"""
|
|
142
219
|
from anemoi.datasets.dates.groups import GroupOfDates
|
|
143
220
|
|
|
144
221
|
dates = list(group_of_dates)
|
|
@@ -160,11 +237,34 @@ class DateMapperClimatology(DateMapper):
|
|
|
160
237
|
|
|
161
238
|
|
|
162
239
|
class DateMapperConstant(DateMapper):
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
240
|
+
"""A DateMapper implementation that maps dates to a constant date."""
|
|
241
|
+
|
|
242
|
+
def __init__(self, source: Any, date: Optional[Any] = None) -> None:
|
|
243
|
+
"""Initialize DateMapperConstant.
|
|
244
|
+
|
|
245
|
+
Parameters
|
|
246
|
+
----------
|
|
247
|
+
source : Any
|
|
248
|
+
The data source.
|
|
249
|
+
date : Optional[Any]
|
|
250
|
+
The constant date to map to.
|
|
251
|
+
"""
|
|
252
|
+
self.source: Any = source
|
|
253
|
+
self.date: Optional[Any] = date
|
|
254
|
+
|
|
255
|
+
def transform(self, group_of_dates: Any) -> Tuple[Any, Any]:
|
|
256
|
+
"""Transform the group of dates to a constant date.
|
|
257
|
+
|
|
258
|
+
Parameters
|
|
259
|
+
----------
|
|
260
|
+
group_of_dates : Any
|
|
261
|
+
The group of dates to transform.
|
|
262
|
+
|
|
263
|
+
Returns
|
|
264
|
+
-------
|
|
265
|
+
Tuple[Any, Any]
|
|
266
|
+
Transformed dates.
|
|
267
|
+
"""
|
|
168
268
|
from anemoi.datasets.dates.groups import GroupOfDates
|
|
169
269
|
|
|
170
270
|
if self.date is None:
|
|
@@ -184,24 +284,44 @@ class DateMapperConstant(DateMapper):
|
|
|
184
284
|
|
|
185
285
|
|
|
186
286
|
class DateMapperResult(Result):
|
|
287
|
+
"""A Result implementation that updates the valid datetime of the datasource."""
|
|
288
|
+
|
|
187
289
|
def __init__(
|
|
188
290
|
self,
|
|
189
|
-
context,
|
|
190
|
-
action_path,
|
|
191
|
-
group_of_dates,
|
|
192
|
-
source_result,
|
|
193
|
-
mapper,
|
|
194
|
-
original_group_of_dates,
|
|
195
|
-
):
|
|
291
|
+
context: Any,
|
|
292
|
+
action_path: List[str],
|
|
293
|
+
group_of_dates: Any,
|
|
294
|
+
source_result: Any,
|
|
295
|
+
mapper: DateMapper,
|
|
296
|
+
original_group_of_dates: Any,
|
|
297
|
+
) -> None:
|
|
298
|
+
"""Initialize DateMapperResult.
|
|
299
|
+
|
|
300
|
+
Parameters
|
|
301
|
+
----------
|
|
302
|
+
context : Any
|
|
303
|
+
The context.
|
|
304
|
+
action_path : list of str
|
|
305
|
+
The action path.
|
|
306
|
+
group_of_dates : Any
|
|
307
|
+
The group of dates.
|
|
308
|
+
source_result : Any
|
|
309
|
+
The source result.
|
|
310
|
+
mapper : DateMapper
|
|
311
|
+
The date mapper.
|
|
312
|
+
original_group_of_dates : Any
|
|
313
|
+
The original group of dates.
|
|
314
|
+
"""
|
|
196
315
|
super().__init__(context, action_path, group_of_dates)
|
|
197
316
|
|
|
198
|
-
self.source_results = source_result
|
|
199
|
-
self.mapper = mapper
|
|
200
|
-
self.original_group_of_dates = original_group_of_dates
|
|
317
|
+
self.source_results: Any = source_result
|
|
318
|
+
self.mapper: DateMapper = mapper
|
|
319
|
+
self.original_group_of_dates: Any = original_group_of_dates
|
|
201
320
|
|
|
202
321
|
@property
|
|
203
|
-
def datasource(self):
|
|
204
|
-
|
|
322
|
+
def datasource(self) -> Any:
|
|
323
|
+
"""Get the datasource with updated valid datetime."""
|
|
324
|
+
result: list = []
|
|
205
325
|
|
|
206
326
|
for field in self.source_results.datasource:
|
|
207
327
|
for date in self.original_group_of_dates:
|
|
@@ -214,15 +334,36 @@ class DateMapperResult(Result):
|
|
|
214
334
|
|
|
215
335
|
|
|
216
336
|
class RepeatedDatesAction(Action):
|
|
217
|
-
|
|
337
|
+
"""An Action implementation that selects and transforms a group of dates."""
|
|
338
|
+
|
|
339
|
+
def __init__(self, context: Any, action_path: List[str], source: Any, mode: str, **kwargs: Any) -> None:
|
|
340
|
+
"""Initialize RepeatedDatesAction.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
context (Any): The context.
|
|
344
|
+
action_path (List[str]): The action path.
|
|
345
|
+
source (Any): The data source.
|
|
346
|
+
mode (str): The mode for date mapping.
|
|
347
|
+
**kwargs (Any): Additional arguments.
|
|
348
|
+
"""
|
|
218
349
|
super().__init__(context, action_path, source, mode, **kwargs)
|
|
219
350
|
|
|
220
|
-
self.source = action_factory(source, context, action_path + ["source"])
|
|
221
|
-
self.mapper = DateMapper.from_mode(mode, self.source, kwargs)
|
|
351
|
+
self.source: Any = action_factory(source, context, action_path + ["source"])
|
|
352
|
+
self.mapper: DateMapper = DateMapper.from_mode(mode, self.source, kwargs)
|
|
222
353
|
|
|
223
354
|
@trace_select
|
|
224
|
-
def select(self, group_of_dates):
|
|
225
|
-
|
|
355
|
+
def select(self, group_of_dates: Any) -> JoinResult:
|
|
356
|
+
"""Select and transform the group of dates.
|
|
357
|
+
|
|
358
|
+
Args:
|
|
359
|
+
group_of_dates (Any): The group of dates to select.
|
|
360
|
+
|
|
361
|
+
Returns
|
|
362
|
+
-------
|
|
363
|
+
JoinResult
|
|
364
|
+
The result of the join operation.
|
|
365
|
+
"""
|
|
366
|
+
results: list = []
|
|
226
367
|
for one_date_group, many_dates_group in self.mapper.transform(group_of_dates):
|
|
227
368
|
results.append(
|
|
228
369
|
DateMapperResult(
|
|
@@ -237,5 +378,12 @@ class RepeatedDatesAction(Action):
|
|
|
237
378
|
|
|
238
379
|
return JoinResult(self.context, self.action_path, group_of_dates, results)
|
|
239
380
|
|
|
240
|
-
def __repr__(self):
|
|
381
|
+
def __repr__(self) -> str:
|
|
382
|
+
"""Get the string representation of the action.
|
|
383
|
+
|
|
384
|
+
Returns
|
|
385
|
+
-------
|
|
386
|
+
str
|
|
387
|
+
The string representation.
|
|
388
|
+
"""
|
|
241
389
|
return f"MultiDateMatchAction({self.source}, {self.mapper})"
|