anemoi-datasets 0.5.27__py3-none-any.whl → 0.5.28__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/_version.py +2 -2
- anemoi/datasets/commands/recipe/__init__.py +93 -0
- anemoi/datasets/commands/recipe/format.py +55 -0
- anemoi/datasets/commands/recipe/migrate.py +555 -0
- anemoi/datasets/create/__init__.py +42 -1
- anemoi/datasets/create/config.py +2 -0
- anemoi/datasets/create/input/__init__.py +43 -63
- anemoi/datasets/create/input/action.py +296 -236
- anemoi/datasets/create/input/context/__init__.py +71 -0
- anemoi/datasets/create/input/context/field.py +54 -0
- anemoi/datasets/create/input/data_sources.py +2 -1
- anemoi/datasets/create/input/misc.py +0 -71
- anemoi/datasets/create/input/repeated_dates.py +0 -114
- anemoi/datasets/create/input/result/__init__.py +17 -0
- anemoi/datasets/create/input/{result.py → result/field.py} +9 -89
- anemoi/datasets/create/sources/accumulations.py +74 -94
- anemoi/datasets/create/sources/accumulations2.py +16 -45
- anemoi/datasets/create/sources/anemoi_dataset.py +46 -42
- anemoi/datasets/create/sources/constants.py +39 -38
- anemoi/datasets/create/sources/empty.py +26 -22
- anemoi/datasets/create/sources/forcings.py +29 -28
- anemoi/datasets/create/sources/grib.py +92 -72
- anemoi/datasets/create/sources/grib_index.py +46 -42
- anemoi/datasets/create/sources/hindcasts.py +56 -55
- anemoi/datasets/create/sources/legacy.py +10 -62
- anemoi/datasets/create/sources/mars.py +107 -131
- anemoi/datasets/create/sources/netcdf.py +28 -24
- anemoi/datasets/create/sources/opendap.py +28 -24
- anemoi/datasets/create/sources/recentre.py +42 -41
- anemoi/datasets/create/sources/repeated_dates.py +44 -0
- anemoi/datasets/create/sources/source.py +26 -48
- anemoi/datasets/create/sources/tendencies.py +67 -94
- anemoi/datasets/create/sources/xarray_support/__init__.py +29 -24
- anemoi/datasets/create/sources/xarray_support/field.py +4 -4
- anemoi/datasets/create/sources/xarray_zarr.py +28 -24
- anemoi/datasets/create/sources/zenodo.py +43 -39
- anemoi/datasets/create/utils.py +0 -42
- anemoi/datasets/data/dataset.py +6 -0
- anemoi/datasets/data/grids.py +0 -152
- anemoi/datasets/data/rolling_average.py +141 -0
- anemoi/datasets/data/stores.py +7 -9
- anemoi/datasets/dates/__init__.py +2 -0
- anemoi/datasets/dumper.py +76 -0
- anemoi/datasets/grids.py +1 -178
- anemoi/datasets/schemas/recipe.json +131 -0
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/METADATA +5 -2
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/RECORD +51 -51
- anemoi/datasets/create/filter.py +0 -47
- anemoi/datasets/create/input/concat.py +0 -161
- anemoi/datasets/create/input/context.py +0 -86
- anemoi/datasets/create/input/empty.py +0 -53
- anemoi/datasets/create/input/filter.py +0 -117
- anemoi/datasets/create/input/function.py +0 -232
- anemoi/datasets/create/input/join.py +0 -129
- anemoi/datasets/create/input/pipe.py +0 -66
- anemoi/datasets/create/input/step.py +0 -173
- anemoi/datasets/create/input/template.py +0 -161
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/WHEEL +0 -0
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/entry_points.txt +0 -0
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/licenses/LICENSE +0 -0
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/top_level.txt +0 -0
|
@@ -9,65 +9,69 @@
|
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
|
|
12
|
-
from .
|
|
12
|
+
from . import source_registry
|
|
13
|
+
from .legacy import LegacySource
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
@
|
|
16
|
-
|
|
17
|
-
import earthkit.data as ekd
|
|
16
|
+
@source_registry.register("anemoi_dataset")
|
|
17
|
+
class AnemoiDatasetSource(LegacySource):
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
@staticmethod
|
|
20
|
+
def _execute(context, dates, params=None, **kwargs):
|
|
21
|
+
import earthkit.data as ekd
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
# dates_to_index = {date: i for i, date in enumerate(ds.dates)}
|
|
23
|
+
from anemoi.datasets import open_dataset
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
idx = np.where(ds.dates == date)[0]
|
|
27
|
-
if len(idx) == 0:
|
|
28
|
-
continue
|
|
29
|
-
indices.append((int(idx[0]), date))
|
|
25
|
+
ds = open_dataset(**kwargs)
|
|
26
|
+
# dates_to_index = {date: i for i, date in enumerate(ds.dates)}
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
indices = []
|
|
29
|
+
for date in dates:
|
|
30
|
+
idx = np.where(ds.dates == date)[0]
|
|
31
|
+
if len(idx) == 0:
|
|
32
|
+
continue
|
|
33
|
+
indices.append((int(idx[0]), date))
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
params
|
|
35
|
+
vars = ds.variables
|
|
36
|
+
if params is None:
|
|
37
|
+
params = vars
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
if not isinstance(params, (list, tuple, set)):
|
|
40
|
+
params = [params]
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
longitudes = ds.longitudes
|
|
42
|
+
params = set(params)
|
|
43
|
+
results = []
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
ensemble = ds.shape[2] > 1
|
|
46
|
+
latitudes = ds.latitudes
|
|
47
|
+
longitudes = ds.longitudes
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
for idx, date in indices:
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
metadata = dict(valid_datetime=date, latitudes=latitudes, longitudes=longitudes)
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
for j, y in enumerate(ds[idx]):
|
|
54
|
+
|
|
55
|
+
param = vars[j]
|
|
56
|
+
if param not in params:
|
|
57
|
+
continue
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
# metadata['name'] = param
|
|
60
|
+
# metadata['param_level'] = param
|
|
61
|
+
metadata["param"] = param
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
for k, e in enumerate(y):
|
|
64
|
+
if ensemble:
|
|
65
|
+
metadata["number"] = k + 1
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
metadata["values"] = e
|
|
64
68
|
|
|
65
|
-
|
|
69
|
+
results.append(metadata.copy())
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
print(results[0].keys())
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
# "list-of-dicts" does support resolution
|
|
74
|
+
results = ekd.from_source("list-of-dicts", results)
|
|
71
75
|
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
# return new_fieldlist_from_list([new_field_from_latitudes_longitudes(x, latitudes, longitudes) for x in results])
|
|
77
|
+
return results
|
|
@@ -11,41 +11,42 @@ from typing import Any
|
|
|
11
11
|
|
|
12
12
|
from earthkit.data import from_source
|
|
13
13
|
|
|
14
|
-
from .
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
14
|
+
from . import source_registry
|
|
15
|
+
from .legacy import LegacySource
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@source_registry.register("constants")
|
|
19
|
+
class ConstantsSource(LegacySource):
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def _execute(context: Any, dates: list[str], template: dict[str, Any], param: str) -> Any:
|
|
23
|
+
"""Deprecated function to retrieve constants data.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
context : Any
|
|
28
|
+
The context object for tracing.
|
|
29
|
+
dates : list of str
|
|
30
|
+
List of dates for which data is required.
|
|
31
|
+
template : dict of str to Any
|
|
32
|
+
Template dictionary for the data source.
|
|
33
|
+
param : str
|
|
34
|
+
Parameter to retrieve.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
Any
|
|
39
|
+
Data retrieved from the source.
|
|
40
|
+
"""
|
|
41
|
+
from warnings import warn
|
|
42
|
+
|
|
43
|
+
warn(
|
|
44
|
+
"The source `constants` is deprecated, use `forcings` instead.",
|
|
45
|
+
DeprecationWarning,
|
|
46
|
+
stacklevel=2,
|
|
47
|
+
)
|
|
48
|
+
context.trace("✅", f"from_source(constants, {template}, {param}")
|
|
49
|
+
if len(template) == 0:
|
|
50
|
+
raise ValueError("Forcings template is empty.")
|
|
51
|
+
|
|
52
|
+
return from_source("forcings", source_or_dataset=template, date=list(dates), param=param)
|
|
@@ -12,25 +12,29 @@ from typing import Any
|
|
|
12
12
|
|
|
13
13
|
import earthkit.data as ekd
|
|
14
14
|
|
|
15
|
-
from .
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
15
|
+
from . import source_registry
|
|
16
|
+
from .legacy import LegacySource
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@source_registry.register("empty")
|
|
20
|
+
class EmptySource(LegacySource):
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def _execute(context: Any, dates: list[str], **kwargs: Any) -> ekd.FieldList:
|
|
24
|
+
"""Executes the loading of an empty data source.
|
|
25
|
+
|
|
26
|
+
Parameters
|
|
27
|
+
----------
|
|
28
|
+
context : object
|
|
29
|
+
The context in which the function is executed.
|
|
30
|
+
dates : list
|
|
31
|
+
List of dates for which data is to be loaded.
|
|
32
|
+
**kwargs : dict
|
|
33
|
+
Additional keyword arguments.
|
|
34
|
+
|
|
35
|
+
Returns
|
|
36
|
+
-------
|
|
37
|
+
ekd.FieldList
|
|
38
|
+
Loaded empty data source.
|
|
39
|
+
"""
|
|
40
|
+
return ekd.from_source("empty")
|
|
@@ -11,31 +11,32 @@ from typing import Any
|
|
|
11
11
|
|
|
12
12
|
from earthkit.data import from_source
|
|
13
13
|
|
|
14
|
-
from .
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
14
|
+
from . import source_registry
|
|
15
|
+
from .legacy import LegacySource
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@source_registry.register("forcings")
|
|
19
|
+
class ForcingsSource(LegacySource):
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def _execute(context: Any, dates: list[str], template: str, param: str) -> Any:
|
|
23
|
+
"""Loads forcing data from a specified source.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
context : object
|
|
28
|
+
The context in which the function is executed.
|
|
29
|
+
dates : list
|
|
30
|
+
List of dates for which data is to be loaded.
|
|
31
|
+
template : FieldList
|
|
32
|
+
Template for the data source.
|
|
33
|
+
param : str
|
|
34
|
+
Parameter for the data source.
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
object
|
|
39
|
+
Loaded forcing data.
|
|
40
|
+
"""
|
|
41
|
+
context.trace("✅", f"from_source(forcings, {template}, {param}")
|
|
42
|
+
return from_source("forcings", source_or_dataset=template, date=list(dates), param=param)
|
|
@@ -20,7 +20,8 @@ from anemoi.transform.grids import grid_registry
|
|
|
20
20
|
from earthkit.data import from_source
|
|
21
21
|
from earthkit.data.utils.patterns import Pattern
|
|
22
22
|
|
|
23
|
-
from .
|
|
23
|
+
from . import source_registry
|
|
24
|
+
from .legacy import LegacySource
|
|
24
25
|
|
|
25
26
|
LOG = logging.getLogger(__name__)
|
|
26
27
|
|
|
@@ -47,6 +48,14 @@ def check(ds: Any, paths: list[str], **kwargs: Any) -> None:
|
|
|
47
48
|
if isinstance(v, (tuple, list)):
|
|
48
49
|
count *= len(v)
|
|
49
50
|
|
|
51
|
+
# in the case of static data (e.g repeated dates) dates might be empty
|
|
52
|
+
if len(ds) != count and kwargs.get("dates", []) == []:
|
|
53
|
+
LOG.warning(
|
|
54
|
+
f"Expected {count} fields, got {len(ds)} (kwargs={kwargs}, paths={paths})"
|
|
55
|
+
f" Received empty dates - assuming this is static data."
|
|
56
|
+
)
|
|
57
|
+
return
|
|
58
|
+
|
|
50
59
|
if len(ds) != count:
|
|
51
60
|
raise ValueError(f"Expected {count} fields, got {len(ds)} (kwargs={kwargs}, paths={paths})")
|
|
52
61
|
|
|
@@ -73,74 +82,85 @@ def _expand(paths: list[str]) -> Any:
|
|
|
73
82
|
yield path
|
|
74
83
|
|
|
75
84
|
|
|
76
|
-
@
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
for
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
85
|
+
@source_registry.register("grib")
|
|
86
|
+
class GribSource(LegacySource):
|
|
87
|
+
|
|
88
|
+
@staticmethod
|
|
89
|
+
def _execute(
|
|
90
|
+
context: Any,
|
|
91
|
+
dates: list[Any],
|
|
92
|
+
path: str | list[str],
|
|
93
|
+
flavour: str | dict[str, Any] | None = None,
|
|
94
|
+
grid_definition: dict[str, Any] | None = None,
|
|
95
|
+
*args: Any,
|
|
96
|
+
**kwargs: Any,
|
|
97
|
+
) -> ekd.FieldList:
|
|
98
|
+
"""Executes the function to load data from GRIB files.
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
context : Any
|
|
103
|
+
The context in which the function is executed.
|
|
104
|
+
dates : list of Any
|
|
105
|
+
List of dates.
|
|
106
|
+
path : str or list of str
|
|
107
|
+
Path or list of paths to the GRIB files.
|
|
108
|
+
flavour : str or dict of str to Any, optional
|
|
109
|
+
Flavour information, by default None.
|
|
110
|
+
grid_definition : dict of str to Any, optional
|
|
111
|
+
Grid definition configuration to create a Grid object, by default None.
|
|
112
|
+
*args : Any
|
|
113
|
+
Additional positional arguments.
|
|
114
|
+
**kwargs : Any
|
|
115
|
+
Additional keyword arguments.
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
Any
|
|
120
|
+
The loaded dataset.
|
|
121
|
+
"""
|
|
122
|
+
given_paths = path if isinstance(path, list) else [path]
|
|
123
|
+
if flavour is not None:
|
|
124
|
+
flavour = RuleBasedFlavour(flavour)
|
|
125
|
+
|
|
126
|
+
if grid_definition is not None:
|
|
127
|
+
grid = grid_registry.from_config(grid_definition)
|
|
128
|
+
else:
|
|
129
|
+
grid = None
|
|
130
|
+
|
|
131
|
+
ds = from_source("empty")
|
|
132
|
+
dates = [d.isoformat() for d in dates]
|
|
133
|
+
|
|
134
|
+
for path in given_paths:
|
|
135
|
+
|
|
136
|
+
# do not substitute if not needed
|
|
137
|
+
if "{" not in path:
|
|
138
|
+
paths = [path]
|
|
139
|
+
else:
|
|
140
|
+
paths = Pattern(path).substitute(*args, date=dates, allow_extra=True, **kwargs)
|
|
141
|
+
|
|
142
|
+
for name in ("grid", "area", "rotation", "frame", "resol", "bitmap"):
|
|
143
|
+
if name in kwargs:
|
|
144
|
+
raise ValueError(f"MARS interpolation parameter '{name}' not supported")
|
|
145
|
+
|
|
146
|
+
for path in _expand(paths):
|
|
147
|
+
context.trace("📁", "PATH", path)
|
|
148
|
+
s = from_source("file", path)
|
|
149
|
+
if flavour is not None:
|
|
150
|
+
s = flavour.map(s)
|
|
151
|
+
sel_kwargs = kwargs.copy()
|
|
152
|
+
if dates != []:
|
|
153
|
+
sel_kwargs["valid_datetime"] = dates
|
|
154
|
+
s = s.sel(**sel_kwargs)
|
|
155
|
+
ds = ds + s
|
|
156
|
+
|
|
157
|
+
if kwargs and not context.partial_ok:
|
|
158
|
+
check(ds, given_paths, valid_datetime=dates, **kwargs)
|
|
159
|
+
|
|
160
|
+
if grid is not None:
|
|
161
|
+
ds = new_fieldlist_from_list([new_field_from_grid(f, grid) for f in ds])
|
|
162
|
+
|
|
163
|
+
if len(ds) == 0:
|
|
164
|
+
LOG.warning(f"No fields found for {dates} in {given_paths} (kwargs={kwargs})")
|
|
165
|
+
|
|
166
|
+
return ds
|
|
@@ -19,7 +19,8 @@ from anemoi.transform.flavour import RuleBasedFlavour
|
|
|
19
19
|
from cachetools import LRUCache
|
|
20
20
|
from earthkit.data.indexing.fieldlist import FieldArray
|
|
21
21
|
|
|
22
|
-
from .
|
|
22
|
+
from . import source_registry
|
|
23
|
+
from .legacy import LegacySource
|
|
23
24
|
|
|
24
25
|
LOG = logging.getLogger(__name__)
|
|
25
26
|
|
|
@@ -569,44 +570,47 @@ class GribIndex:
|
|
|
569
570
|
yield data
|
|
570
571
|
|
|
571
572
|
|
|
572
|
-
@
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
573
|
+
@source_registry.register("grib_index")
|
|
574
|
+
class GribIndexSource(LegacySource):
|
|
575
|
+
|
|
576
|
+
@staticmethod
|
|
577
|
+
def _execute(
|
|
578
|
+
context: Any,
|
|
579
|
+
dates: list[Any],
|
|
580
|
+
indexdb: str,
|
|
581
|
+
flavour: str | None = None,
|
|
582
|
+
**kwargs: Any,
|
|
583
|
+
) -> FieldArray:
|
|
584
|
+
"""Execute the GRIB data retrieval process.
|
|
585
|
+
|
|
586
|
+
Parameters
|
|
587
|
+
----------
|
|
588
|
+
context : Any
|
|
589
|
+
The execution context.
|
|
590
|
+
dates : List[Any]
|
|
591
|
+
List of dates to retrieve data for.
|
|
592
|
+
indexdb : str
|
|
593
|
+
Path to the GRIB index database.
|
|
594
|
+
flavour : Optional[str], optional
|
|
595
|
+
Flavour configuration for mapping fields, by default None.
|
|
596
|
+
**kwargs : Any
|
|
597
|
+
Additional filtering criteria.
|
|
598
|
+
|
|
599
|
+
Returns
|
|
600
|
+
-------
|
|
601
|
+
FieldArray
|
|
602
|
+
An array of retrieved GRIB fields.
|
|
603
|
+
"""
|
|
604
|
+
index = GribIndex(indexdb)
|
|
605
|
+
result = []
|
|
606
|
+
|
|
607
|
+
if flavour is not None:
|
|
608
|
+
flavour = RuleBasedFlavour(flavour)
|
|
609
|
+
|
|
610
|
+
for grib in index.retrieve(dates, **kwargs):
|
|
611
|
+
field = ekd.from_source("memory", grib)[0]
|
|
612
|
+
if flavour:
|
|
613
|
+
field = flavour.apply(field)
|
|
614
|
+
result.append(field)
|
|
615
|
+
|
|
616
|
+
return FieldArray(result)
|