anemoi-datasets 0.5.16__py3-none-any.whl → 0.5.18__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 +558 -62
- 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.18.dist-info}/METADATA +9 -6
- anemoi_datasets-0.5.18.dist-info/RECORD +137 -0
- {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.18.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.18.dist-info}/entry_points.txt +0 -0
- {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.18.dist-info/licenses}/LICENSE +0 -0
- {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.18.dist-info}/top_level.txt +0 -0
|
@@ -11,20 +11,41 @@ import datetime
|
|
|
11
11
|
import logging
|
|
12
12
|
import warnings
|
|
13
13
|
from copy import deepcopy
|
|
14
|
+
from typing import Any
|
|
15
|
+
from typing import Dict
|
|
16
|
+
from typing import Generator
|
|
17
|
+
from typing import List
|
|
18
|
+
from typing import Optional
|
|
19
|
+
from typing import Tuple
|
|
20
|
+
from typing import Union
|
|
14
21
|
|
|
15
22
|
import earthkit.data as ekd
|
|
16
23
|
import numpy as np
|
|
17
24
|
from earthkit.data.core.temporary import temp_file
|
|
18
25
|
from earthkit.data.readers.grib.output import new_grib_output
|
|
26
|
+
from numpy.typing import NDArray
|
|
19
27
|
|
|
20
28
|
from anemoi.datasets.create.utils import to_datetime_list
|
|
21
29
|
|
|
30
|
+
from .legacy import legacy_source
|
|
22
31
|
from .mars import mars
|
|
23
32
|
|
|
24
33
|
LOG = logging.getLogger(__name__)
|
|
25
34
|
|
|
26
35
|
|
|
27
|
-
def _member(field):
|
|
36
|
+
def _member(field: Any) -> int:
|
|
37
|
+
"""Retrieves the member number from the field metadata.
|
|
38
|
+
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
field : Any
|
|
42
|
+
The field from which to retrieve the member number.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
int
|
|
47
|
+
The member number.
|
|
48
|
+
"""
|
|
28
49
|
# Bug in eccodes has number=0 randomly
|
|
29
50
|
number = field.metadata("number", default=0)
|
|
30
51
|
if number is None:
|
|
@@ -33,26 +54,70 @@ def _member(field):
|
|
|
33
54
|
|
|
34
55
|
|
|
35
56
|
class Accumulation:
|
|
36
|
-
|
|
57
|
+
"""Class to handle data accumulation for a specific parameter, date, time, and member."""
|
|
58
|
+
|
|
59
|
+
buggy_steps: bool = False
|
|
60
|
+
|
|
61
|
+
def __init__(
|
|
62
|
+
self,
|
|
63
|
+
out: Any,
|
|
64
|
+
/,
|
|
65
|
+
param: str,
|
|
66
|
+
date: int,
|
|
67
|
+
time: int,
|
|
68
|
+
number: int,
|
|
69
|
+
step: List[int],
|
|
70
|
+
frequency: int,
|
|
71
|
+
**kwargs: Any,
|
|
72
|
+
) -> None:
|
|
73
|
+
"""Initializes an Accumulation instance.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
out : Any
|
|
78
|
+
Output object for writing data.
|
|
79
|
+
param : str
|
|
80
|
+
Parameter name.
|
|
81
|
+
date : int
|
|
82
|
+
Date of the accumulation.
|
|
83
|
+
time : int
|
|
84
|
+
Time of the accumulation.
|
|
85
|
+
number : int
|
|
86
|
+
Member number.
|
|
87
|
+
step : List[int]
|
|
88
|
+
List of steps.
|
|
89
|
+
frequency : int
|
|
90
|
+
Frequency of accumulation.
|
|
91
|
+
**kwargs : Any
|
|
92
|
+
Additional keyword arguments.
|
|
93
|
+
"""
|
|
37
94
|
self.out = out
|
|
38
95
|
self.param = param
|
|
39
96
|
self.date = date
|
|
40
97
|
self.time = time
|
|
41
98
|
self.steps = step
|
|
42
99
|
self.number = number
|
|
43
|
-
self.values = None
|
|
100
|
+
self.values: Optional[NDArray[None]] = None
|
|
44
101
|
self.seen = set()
|
|
45
|
-
self.startStep = None
|
|
46
|
-
self.endStep = None
|
|
102
|
+
self.startStep: Optional[int] = None
|
|
103
|
+
self.endStep: Optional[int] = None
|
|
47
104
|
self.done = False
|
|
48
105
|
self.frequency = frequency
|
|
49
106
|
self._check = None
|
|
50
107
|
|
|
51
108
|
@property
|
|
52
|
-
def key(self):
|
|
109
|
+
def key(self) -> Tuple[str, int, int, List[int], int]:
|
|
110
|
+
"""Returns the key for the accumulation."""
|
|
53
111
|
return (self.param, self.date, self.time, self.steps, self.number)
|
|
54
112
|
|
|
55
|
-
def check(self, field):
|
|
113
|
+
def check(self, field: Any) -> None:
|
|
114
|
+
"""Checks the field metadata against the accumulation parameters.
|
|
115
|
+
|
|
116
|
+
Parameters
|
|
117
|
+
----------
|
|
118
|
+
field : Any
|
|
119
|
+
The field to check.
|
|
120
|
+
"""
|
|
56
121
|
if self._check is None:
|
|
57
122
|
self._check = field.metadata(namespace="mars")
|
|
58
123
|
|
|
@@ -82,8 +147,14 @@ class Accumulation:
|
|
|
82
147
|
if k not in ("step",):
|
|
83
148
|
assert self._check[k] == mars[k], (k, self._check[k], mars[k])
|
|
84
149
|
|
|
85
|
-
def write(self, template):
|
|
150
|
+
def write(self, template: Any) -> None:
|
|
151
|
+
"""Writes the accumulated values to the output.
|
|
86
152
|
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
template : Any
|
|
156
|
+
Template for writing the output.
|
|
157
|
+
"""
|
|
87
158
|
assert self.startStep != self.endStep, (self.startStep, self.endStep)
|
|
88
159
|
if np.all(self.values < 0):
|
|
89
160
|
LOG.warning(
|
|
@@ -101,8 +172,16 @@ class Accumulation:
|
|
|
101
172
|
self.values = None
|
|
102
173
|
self.done = True
|
|
103
174
|
|
|
104
|
-
def add(self, field, values):
|
|
175
|
+
def add(self, field: Any, values: NDArray[Any]) -> None:
|
|
176
|
+
"""Adds values to the accumulation.
|
|
105
177
|
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
field : Any
|
|
181
|
+
The field containing the values.
|
|
182
|
+
values : np.ndarray
|
|
183
|
+
The values to add.
|
|
184
|
+
"""
|
|
106
185
|
self.check(field)
|
|
107
186
|
|
|
108
187
|
step = field.metadata("step")
|
|
@@ -131,8 +210,37 @@ class Accumulation:
|
|
|
131
210
|
self.write(template=field)
|
|
132
211
|
|
|
133
212
|
@classmethod
|
|
134
|
-
def mars_date_time_steps(
|
|
135
|
-
|
|
213
|
+
def mars_date_time_steps(
|
|
214
|
+
cls,
|
|
215
|
+
dates: List[datetime.datetime],
|
|
216
|
+
step1: int,
|
|
217
|
+
step2: int,
|
|
218
|
+
frequency: Optional[int],
|
|
219
|
+
base_times: List[int],
|
|
220
|
+
adjust_step: bool,
|
|
221
|
+
) -> Generator[Tuple[int, int, Tuple[int, ...]], None, None]:
|
|
222
|
+
"""Generates MARS date-time steps.
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
dates : List[datetime.datetime]
|
|
227
|
+
List of dates.
|
|
228
|
+
step1 : int
|
|
229
|
+
First step.
|
|
230
|
+
step2 : int
|
|
231
|
+
Second step.
|
|
232
|
+
frequency : Optional[int]
|
|
233
|
+
Frequency of accumulation.
|
|
234
|
+
base_times : List[int]
|
|
235
|
+
List of base times.
|
|
236
|
+
adjust_step : bool
|
|
237
|
+
Whether to adjust the step.
|
|
238
|
+
|
|
239
|
+
Returns
|
|
240
|
+
-------
|
|
241
|
+
Generator[Tuple[int, int, Tuple[int, ...]], None, None]
|
|
242
|
+
A generator of MARS date-time steps.
|
|
243
|
+
"""
|
|
136
244
|
# assert step1 > 0, (step1, step2, frequency)
|
|
137
245
|
|
|
138
246
|
for valid_date in dates:
|
|
@@ -152,14 +260,33 @@ class Accumulation:
|
|
|
152
260
|
yield cls._mars_date_time_step(base_date, step1, step2, add_step, frequency)
|
|
153
261
|
|
|
154
262
|
def __repr__(self) -> str:
|
|
263
|
+
"""Returns a string representation of the Accumulation instance.
|
|
264
|
+
|
|
265
|
+
Returns
|
|
266
|
+
-------
|
|
267
|
+
str
|
|
268
|
+
String representation of the Accumulation instance.
|
|
269
|
+
"""
|
|
155
270
|
return f"{self.__class__.__name__}({self.key})"
|
|
156
271
|
|
|
157
272
|
|
|
158
273
|
class AccumulationFromStart(Accumulation):
|
|
159
|
-
|
|
274
|
+
"""Class to handle data accumulation from the start of the forecast."""
|
|
160
275
|
|
|
161
|
-
|
|
276
|
+
buggy_steps = True
|
|
162
277
|
|
|
278
|
+
def compute(self, values: NDArray[Any], startStep: int, endStep: int) -> None:
|
|
279
|
+
"""Computes the accumulation from the start.
|
|
280
|
+
|
|
281
|
+
Parameters
|
|
282
|
+
----------
|
|
283
|
+
values : np.ndarray
|
|
284
|
+
The values to accumulate.
|
|
285
|
+
startStep : int
|
|
286
|
+
The start step.
|
|
287
|
+
endStep : int
|
|
288
|
+
The end step.
|
|
289
|
+
"""
|
|
163
290
|
assert startStep == 0, startStep
|
|
164
291
|
|
|
165
292
|
if self.values is None:
|
|
@@ -186,7 +313,29 @@ class AccumulationFromStart(Accumulation):
|
|
|
186
313
|
self.values = np.maximum(self.values, 0)
|
|
187
314
|
|
|
188
315
|
@classmethod
|
|
189
|
-
def _mars_date_time_step(
|
|
316
|
+
def _mars_date_time_step(
|
|
317
|
+
cls, base_date: datetime.datetime, step1: int, step2: int, add_step: int, frequency: Optional[int]
|
|
318
|
+
) -> Tuple[int, int, Tuple[int, ...]]:
|
|
319
|
+
"""Generates a MARS date-time step.
|
|
320
|
+
|
|
321
|
+
Parameters
|
|
322
|
+
----------
|
|
323
|
+
base_date : datetime.datetime
|
|
324
|
+
The base date.
|
|
325
|
+
step1 : int
|
|
326
|
+
First step.
|
|
327
|
+
step2 : int
|
|
328
|
+
Second step.
|
|
329
|
+
add_step : int
|
|
330
|
+
Additional step.
|
|
331
|
+
frequency : Optional[int]
|
|
332
|
+
Frequency of accumulation.
|
|
333
|
+
|
|
334
|
+
Returns
|
|
335
|
+
-------
|
|
336
|
+
Tuple[int, int, Tuple[int, ...]]
|
|
337
|
+
A tuple representing the MARS date-time step.
|
|
338
|
+
"""
|
|
190
339
|
assert not frequency, frequency
|
|
191
340
|
|
|
192
341
|
steps = (step1 + add_step, step2 + add_step)
|
|
@@ -201,10 +350,22 @@ class AccumulationFromStart(Accumulation):
|
|
|
201
350
|
|
|
202
351
|
|
|
203
352
|
class AccumulationFromLastStep(Accumulation):
|
|
204
|
-
|
|
353
|
+
"""Class to handle data accumulation from the last step of the forecast."""
|
|
205
354
|
|
|
206
|
-
|
|
355
|
+
buggy_steps = False
|
|
207
356
|
|
|
357
|
+
def compute(self, values: NDArray[Any], startStep: int, endStep: int) -> None:
|
|
358
|
+
"""Computes the accumulation from the last step.
|
|
359
|
+
|
|
360
|
+
Parameters
|
|
361
|
+
----------
|
|
362
|
+
values : np.ndarray
|
|
363
|
+
The values to accumulate.
|
|
364
|
+
startStep : int
|
|
365
|
+
The start step.
|
|
366
|
+
endStep : int
|
|
367
|
+
The end step.
|
|
368
|
+
"""
|
|
208
369
|
assert endStep - startStep == self.frequency, (
|
|
209
370
|
startStep,
|
|
210
371
|
endStep,
|
|
@@ -227,7 +388,29 @@ class AccumulationFromLastStep(Accumulation):
|
|
|
227
388
|
self.values += values
|
|
228
389
|
|
|
229
390
|
@classmethod
|
|
230
|
-
def _mars_date_time_step(
|
|
391
|
+
def _mars_date_time_step(
|
|
392
|
+
cls, base_date: datetime.datetime, step1: int, step2: int, add_step: int, frequency: int
|
|
393
|
+
) -> Tuple[int, int, Tuple[int, ...]]:
|
|
394
|
+
"""Generates a MARS date-time step.
|
|
395
|
+
|
|
396
|
+
Parameters
|
|
397
|
+
----------
|
|
398
|
+
base_date : datetime.datetime
|
|
399
|
+
The base date.
|
|
400
|
+
step1 : int
|
|
401
|
+
First step.
|
|
402
|
+
step2 : int
|
|
403
|
+
Second step.
|
|
404
|
+
add_step : int
|
|
405
|
+
Additional step.
|
|
406
|
+
frequency : int
|
|
407
|
+
Frequency of accumulation.
|
|
408
|
+
|
|
409
|
+
Returns
|
|
410
|
+
-------
|
|
411
|
+
Tuple[int, int, Tuple[int, ...]]
|
|
412
|
+
A tuple representing the MARS date-time step.
|
|
413
|
+
"""
|
|
231
414
|
assert frequency > 0, frequency
|
|
232
415
|
# assert step1 > 0, (step1, step2, frequency, add_step, base_date)
|
|
233
416
|
|
|
@@ -241,20 +424,58 @@ class AccumulationFromLastStep(Accumulation):
|
|
|
241
424
|
)
|
|
242
425
|
|
|
243
426
|
|
|
244
|
-
def _identity(x):
|
|
427
|
+
def _identity(x: Any) -> Any:
|
|
428
|
+
"""Identity function that returns the input as is.
|
|
429
|
+
|
|
430
|
+
Parameters
|
|
431
|
+
----------
|
|
432
|
+
x : Any
|
|
433
|
+
Input value.
|
|
434
|
+
|
|
435
|
+
Returns
|
|
436
|
+
-------
|
|
437
|
+
Any
|
|
438
|
+
The input value.
|
|
439
|
+
"""
|
|
245
440
|
return x
|
|
246
441
|
|
|
247
442
|
|
|
248
443
|
def _compute_accumulations(
|
|
249
|
-
context,
|
|
250
|
-
dates,
|
|
251
|
-
request,
|
|
252
|
-
user_accumulation_period=6,
|
|
253
|
-
data_accumulation_period=None,
|
|
254
|
-
patch=_identity,
|
|
255
|
-
base_times=None,
|
|
256
|
-
use_cdsapi_dataset=None,
|
|
257
|
-
):
|
|
444
|
+
context: Any,
|
|
445
|
+
dates: List[datetime.datetime],
|
|
446
|
+
request: Dict[str, Any],
|
|
447
|
+
user_accumulation_period: Union[int, Tuple[int, int]] = 6,
|
|
448
|
+
data_accumulation_period: Optional[int] = None,
|
|
449
|
+
patch: Any = _identity,
|
|
450
|
+
base_times: Optional[List[int]] = None,
|
|
451
|
+
use_cdsapi_dataset: Optional[str] = None,
|
|
452
|
+
) -> Any:
|
|
453
|
+
"""Computes accumulations based on the provided parameters.
|
|
454
|
+
|
|
455
|
+
Parameters
|
|
456
|
+
----------
|
|
457
|
+
context : Any
|
|
458
|
+
Context for the computation.
|
|
459
|
+
dates : List[datetime.datetime]
|
|
460
|
+
List of dates.
|
|
461
|
+
request : Dict[str, Any]
|
|
462
|
+
Request parameters.
|
|
463
|
+
user_accumulation_period : Union[int, Tuple[int, int]], optional
|
|
464
|
+
User-defined accumulation period. Defaults to 6.
|
|
465
|
+
data_accumulation_period : Optional[int], optional
|
|
466
|
+
Data accumulation period. Defaults to None.
|
|
467
|
+
patch : Any, optional
|
|
468
|
+
Patch function. Defaults to _identity.
|
|
469
|
+
base_times : Optional[List[int]], optional
|
|
470
|
+
List of base times. Defaults to None.
|
|
471
|
+
use_cdsapi_dataset : Optional[str], optional
|
|
472
|
+
CDSAPI dataset to use. Defaults to None.
|
|
473
|
+
|
|
474
|
+
Returns
|
|
475
|
+
-------
|
|
476
|
+
Any
|
|
477
|
+
The computed accumulations.
|
|
478
|
+
"""
|
|
258
479
|
adjust_step = isinstance(user_accumulation_period, int)
|
|
259
480
|
|
|
260
481
|
if not isinstance(user_accumulation_period, (list, tuple)):
|
|
@@ -355,13 +576,37 @@ def _compute_accumulations(
|
|
|
355
576
|
return ds
|
|
356
577
|
|
|
357
578
|
|
|
358
|
-
def _to_list(x):
|
|
579
|
+
def _to_list(x: Union[List[Any], Tuple[Any], Any]) -> List[Any]:
|
|
580
|
+
"""Converts the input to a list if it is not already a list or tuple.
|
|
581
|
+
|
|
582
|
+
Parameters
|
|
583
|
+
----------
|
|
584
|
+
x : Union[List[Any], Tuple[Any], Any]
|
|
585
|
+
Input value.
|
|
586
|
+
|
|
587
|
+
Returns
|
|
588
|
+
-------
|
|
589
|
+
List[Any]
|
|
590
|
+
The input value as a list.
|
|
591
|
+
"""
|
|
359
592
|
if isinstance(x, (list, tuple)):
|
|
360
593
|
return x
|
|
361
594
|
return [x]
|
|
362
595
|
|
|
363
596
|
|
|
364
|
-
def _scda(request):
|
|
597
|
+
def _scda(request: Dict[str, Any]) -> Dict[str, Any]:
|
|
598
|
+
"""Modifies the request stream based on the time.
|
|
599
|
+
|
|
600
|
+
Parameters
|
|
601
|
+
----------
|
|
602
|
+
request : Dict[str, Any]
|
|
603
|
+
Request parameters.
|
|
604
|
+
|
|
605
|
+
Returns
|
|
606
|
+
-------
|
|
607
|
+
Dict[str, Any]
|
|
608
|
+
The modified request parameters.
|
|
609
|
+
"""
|
|
365
610
|
if request["time"] in (6, 18, 600, 1800):
|
|
366
611
|
request["stream"] = "scda"
|
|
367
612
|
else:
|
|
@@ -369,7 +614,28 @@ def _scda(request):
|
|
|
369
614
|
return request
|
|
370
615
|
|
|
371
616
|
|
|
372
|
-
|
|
617
|
+
@legacy_source(__file__)
|
|
618
|
+
def accumulations(
|
|
619
|
+
context: Any, dates: List[datetime.datetime], use_cdsapi_dataset: Optional[str] = None, **request: Any
|
|
620
|
+
) -> Any:
|
|
621
|
+
"""Computes accumulations based on the provided context, dates, and request parameters.
|
|
622
|
+
|
|
623
|
+
Parameters
|
|
624
|
+
----------
|
|
625
|
+
context : Any
|
|
626
|
+
Context for the computation.
|
|
627
|
+
dates : List[datetime.datetime]
|
|
628
|
+
List of dates.
|
|
629
|
+
use_cdsapi_dataset : Optional[str], optional
|
|
630
|
+
CDSAPI dataset to use. Defaults to None.
|
|
631
|
+
**request : Any
|
|
632
|
+
Additional request parameters.
|
|
633
|
+
|
|
634
|
+
Returns
|
|
635
|
+
-------
|
|
636
|
+
Any
|
|
637
|
+
The computed accumulations.
|
|
638
|
+
"""
|
|
373
639
|
_to_list(request["param"])
|
|
374
640
|
class_ = request.get("class", "od")
|
|
375
641
|
stream = request.get("stream", "oper")
|
|
@@ -7,10 +7,35 @@
|
|
|
7
7
|
# granted to it by virtue of its status as an intergovernmental organisation
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
|
+
from typing import Any
|
|
11
|
+
from typing import Dict
|
|
12
|
+
from typing import List
|
|
13
|
+
|
|
10
14
|
from earthkit.data import from_source
|
|
11
15
|
|
|
16
|
+
from .legacy import legacy_source
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@legacy_source(__file__)
|
|
20
|
+
def constants(context: Any, dates: List[str], template: Dict[str, Any], param: str) -> Any:
|
|
21
|
+
"""Deprecated function to retrieve constants data.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
context : Any
|
|
26
|
+
The context object for tracing.
|
|
27
|
+
dates : list of str
|
|
28
|
+
List of dates for which data is required.
|
|
29
|
+
template : dict of str to Any
|
|
30
|
+
Template dictionary for the data source.
|
|
31
|
+
param : str
|
|
32
|
+
Parameter to retrieve.
|
|
12
33
|
|
|
13
|
-
|
|
34
|
+
Returns
|
|
35
|
+
-------
|
|
36
|
+
Any
|
|
37
|
+
Data retrieved from the source.
|
|
38
|
+
"""
|
|
14
39
|
from warnings import warn
|
|
15
40
|
|
|
16
41
|
warn(
|
|
@@ -25,4 +50,4 @@ def constants(context, dates, template, param):
|
|
|
25
50
|
return from_source("forcings", source_or_dataset=template, date=dates, param=param)
|
|
26
51
|
|
|
27
52
|
|
|
28
|
-
execute = constants
|
|
53
|
+
execute: Any = constants
|
|
@@ -8,9 +8,13 @@
|
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
from .
|
|
11
|
+
from . import source_registry
|
|
12
|
+
from .xarray import XarraySourceBase
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
@source_registry.register("eccc_fstd")
|
|
16
|
+
class XarrayECCCSource(XarraySourceBase):
|
|
17
|
+
"""An Xarray data source that uses the `fstd` engine."""
|
|
18
|
+
|
|
19
|
+
emoji = "🍁"
|
|
15
20
|
options = {"engine": "fstd"}
|
|
16
|
-
return load_many("🍁", context, dates, path, *args, options=options, **kwargs)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# (C) Copyright 2024 Anemoi contributors.
|
|
2
|
+
#
|
|
3
|
+
# This software is licensed under the terms of the Apache Licence Version 2.0
|
|
4
|
+
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
5
|
+
#
|
|
6
|
+
# In applying this licence, ECMWF does not waive the privileges and immunities
|
|
7
|
+
# granted to it by virtue of its status as an intergovernmental organisation
|
|
8
|
+
# nor does it submit to any jurisdiction.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from typing import Any
|
|
12
|
+
from typing import List
|
|
13
|
+
|
|
14
|
+
import earthkit.data as ekd
|
|
15
|
+
|
|
16
|
+
from .legacy import legacy_source
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@legacy_source(__file__)
|
|
20
|
+
def execute(context: Any, dates: List[str], **kwargs: Any) -> ekd.FieldList:
|
|
21
|
+
"""Executes the loading of an empty data source.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
context : object
|
|
26
|
+
The context in which the function is executed.
|
|
27
|
+
dates : list
|
|
28
|
+
List of dates for which data is to be loaded.
|
|
29
|
+
**kwargs : dict
|
|
30
|
+
Additional keyword arguments.
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
ekd.FieldList
|
|
35
|
+
Loaded empty data source.
|
|
36
|
+
"""
|
|
37
|
+
return ekd.from_source("empty")
|
|
@@ -7,10 +7,34 @@
|
|
|
7
7
|
# granted to it by virtue of its status as an intergovernmental organisation
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
|
+
from typing import Any
|
|
11
|
+
from typing import List
|
|
12
|
+
|
|
10
13
|
from earthkit.data import from_source
|
|
11
14
|
|
|
15
|
+
from .legacy import legacy_source
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@legacy_source(__file__)
|
|
19
|
+
def forcings(context: Any, dates: List[str], template: str, param: str) -> Any:
|
|
20
|
+
"""Loads forcing data from a specified source.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
context : object
|
|
25
|
+
The context in which the function is executed.
|
|
26
|
+
dates : list
|
|
27
|
+
List of dates for which data is to be loaded.
|
|
28
|
+
template : str
|
|
29
|
+
Template for the data source.
|
|
30
|
+
param : str
|
|
31
|
+
Parameter for the data source.
|
|
12
32
|
|
|
13
|
-
|
|
33
|
+
Returns
|
|
34
|
+
-------
|
|
35
|
+
object
|
|
36
|
+
Loaded forcing data.
|
|
37
|
+
"""
|
|
14
38
|
context.trace("✅", f"from_source(forcings, {template}, {param}")
|
|
15
39
|
return from_source("forcings", source_or_dataset=template, date=dates, param=param)
|
|
16
40
|
|