anemoi-datasets 0.5.15__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.15.dist-info → anemoi_datasets-0.5.17.dist-info}/METADATA +10 -7
- anemoi_datasets-0.5.17.dist-info/RECORD +137 -0
- {anemoi_datasets-0.5.15.dist-info → anemoi_datasets-0.5.17.dist-info}/WHEEL +1 -1
- {anemoi_datasets-0.5.15.dist-info → anemoi_datasets-0.5.17.dist-info/licenses}/LICENSE +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.15.dist-info/RECORD +0 -129
- {anemoi_datasets-0.5.15.dist-info → anemoi_datasets-0.5.17.dist-info}/entry_points.txt +0 -0
- {anemoi_datasets-0.5.15.dist-info → anemoi_datasets-0.5.17.dist-info}/top_level.txt +0 -0
|
@@ -10,9 +10,16 @@
|
|
|
10
10
|
import logging
|
|
11
11
|
from copy import deepcopy
|
|
12
12
|
from functools import cached_property
|
|
13
|
+
from typing import Any
|
|
14
|
+
from typing import Dict
|
|
15
|
+
from typing import List
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
from earthkit.data import FieldList
|
|
13
19
|
|
|
14
20
|
from anemoi.datasets.dates import DatesProvider
|
|
15
21
|
|
|
22
|
+
from ...dates.groups import GroupOfDates
|
|
16
23
|
from .action import Action
|
|
17
24
|
from .action import action_factory
|
|
18
25
|
from .empty import EmptyResult
|
|
@@ -27,7 +34,31 @@ LOG = logging.getLogger(__name__)
|
|
|
27
34
|
|
|
28
35
|
|
|
29
36
|
class ConcatResult(Result):
|
|
30
|
-
|
|
37
|
+
"""Represents the result of concatenating multiple results."""
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
context: object,
|
|
42
|
+
action_path: List[str],
|
|
43
|
+
group_of_dates: GroupOfDates,
|
|
44
|
+
results: List[Result],
|
|
45
|
+
**kwargs: Any,
|
|
46
|
+
) -> None:
|
|
47
|
+
"""Initializes a ConcatResult instance.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
context : object
|
|
52
|
+
The context object.
|
|
53
|
+
action_path : List[str]
|
|
54
|
+
The action path.
|
|
55
|
+
group_of_dates : GroupOfDates
|
|
56
|
+
The group of dates.
|
|
57
|
+
results : List[Result]
|
|
58
|
+
The list of results.
|
|
59
|
+
kwargs : Any
|
|
60
|
+
Additional keyword arguments.
|
|
61
|
+
"""
|
|
31
62
|
super().__init__(context, action_path, group_of_dates)
|
|
32
63
|
self.results = [r for r in results if not r.empty]
|
|
33
64
|
|
|
@@ -35,15 +66,16 @@ class ConcatResult(Result):
|
|
|
35
66
|
@assert_fieldlist
|
|
36
67
|
@notify_result
|
|
37
68
|
@trace_datasource
|
|
38
|
-
def datasource(self):
|
|
69
|
+
def datasource(self) -> FieldList:
|
|
70
|
+
"""Returns the concatenated datasource from all results."""
|
|
39
71
|
ds = EmptyResult(self.context, self.action_path, self.group_of_dates).datasource
|
|
40
72
|
for i in self.results:
|
|
41
73
|
ds += i.datasource
|
|
42
74
|
return _tidy(ds)
|
|
43
75
|
|
|
44
76
|
@property
|
|
45
|
-
def variables(self):
|
|
46
|
-
"""
|
|
77
|
+
def variables(self) -> List[str]:
|
|
78
|
+
"""Returns the list of variables, ensuring all results have the same variables."""
|
|
47
79
|
variables = None
|
|
48
80
|
for f in self.results:
|
|
49
81
|
if f.empty:
|
|
@@ -54,13 +86,33 @@ class ConcatResult(Result):
|
|
|
54
86
|
assert variables is not None, self.results
|
|
55
87
|
return variables
|
|
56
88
|
|
|
57
|
-
def __repr__(self):
|
|
89
|
+
def __repr__(self) -> str:
|
|
90
|
+
"""Returns a string representation of the ConcatResult instance.
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
str
|
|
95
|
+
A string representation of the ConcatResult instance.
|
|
96
|
+
"""
|
|
58
97
|
content = "\n".join([str(i) for i in self.results])
|
|
59
|
-
return
|
|
98
|
+
return self._repr(content)
|
|
60
99
|
|
|
61
100
|
|
|
62
101
|
class ConcatAction(Action):
|
|
63
|
-
|
|
102
|
+
"""Represents an action that concatenates multiple actions based on their dates."""
|
|
103
|
+
|
|
104
|
+
def __init__(self, context: object, action_path: List[str], *configs: Dict[str, Any]) -> None:
|
|
105
|
+
"""Initializes a ConcatAction instance.
|
|
106
|
+
|
|
107
|
+
Parameters
|
|
108
|
+
----------
|
|
109
|
+
context : object
|
|
110
|
+
The context object.
|
|
111
|
+
action_path : List[str]
|
|
112
|
+
The action path.
|
|
113
|
+
configs : Dict[str, Any]
|
|
114
|
+
The configuration dictionaries.
|
|
115
|
+
"""
|
|
64
116
|
super().__init__(context, action_path, *configs)
|
|
65
117
|
parts = []
|
|
66
118
|
for i, cfg in enumerate(configs):
|
|
@@ -74,12 +126,31 @@ class ConcatAction(Action):
|
|
|
74
126
|
parts.append((filtering_dates, action))
|
|
75
127
|
self.parts = parts
|
|
76
128
|
|
|
77
|
-
def __repr__(self):
|
|
129
|
+
def __repr__(self) -> str:
|
|
130
|
+
"""Returns a string representation of the ConcatAction instance.
|
|
131
|
+
|
|
132
|
+
Returns
|
|
133
|
+
-------
|
|
134
|
+
str
|
|
135
|
+
A string representation of the ConcatAction instance.
|
|
136
|
+
"""
|
|
78
137
|
content = "\n".join([str(i) for i in self.parts])
|
|
79
|
-
return
|
|
138
|
+
return self._repr(content)
|
|
80
139
|
|
|
81
140
|
@trace_select
|
|
82
|
-
def select(self, group_of_dates):
|
|
141
|
+
def select(self, group_of_dates: GroupOfDates) -> Union[ConcatResult, EmptyResult]:
|
|
142
|
+
"""Selects the concatenated result for the given group of dates.
|
|
143
|
+
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
group_of_dates : GroupOfDates
|
|
147
|
+
The group of dates.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
Union[ConcatResult, EmptyResult]
|
|
152
|
+
The concatenated result or an empty result.
|
|
153
|
+
"""
|
|
83
154
|
from anemoi.datasets.dates.groups import GroupOfDates
|
|
84
155
|
|
|
85
156
|
results = []
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
import logging
|
|
11
11
|
import textwrap
|
|
12
|
+
from typing import Any
|
|
13
|
+
from typing import List
|
|
14
|
+
from typing import Tuple
|
|
15
|
+
from typing import Union
|
|
12
16
|
|
|
13
17
|
from anemoi.utils.humanize import plural
|
|
14
18
|
|
|
@@ -19,18 +23,37 @@ LOG = logging.getLogger(__name__)
|
|
|
19
23
|
|
|
20
24
|
|
|
21
25
|
class Context:
|
|
22
|
-
|
|
26
|
+
"""Class to handle the build context in the dataset creation process."""
|
|
27
|
+
|
|
28
|
+
def __init__(self) -> None:
|
|
29
|
+
"""Initializes a Context instance."""
|
|
23
30
|
# used_references is a set of reference paths that will be needed
|
|
24
31
|
self.used_references = set()
|
|
25
32
|
# results is a dictionary of reference path -> obj
|
|
26
33
|
self.results = {}
|
|
27
34
|
|
|
28
|
-
def will_need_reference(self, key):
|
|
35
|
+
def will_need_reference(self, key: Union[List, Tuple]) -> None:
|
|
36
|
+
"""Marks a reference as needed.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
key : Union[List, Tuple]
|
|
41
|
+
The reference key.
|
|
42
|
+
"""
|
|
29
43
|
assert isinstance(key, (list, tuple)), key
|
|
30
44
|
key = tuple(key)
|
|
31
45
|
self.used_references.add(key)
|
|
32
46
|
|
|
33
|
-
def notify_result(self, key, result):
|
|
47
|
+
def notify_result(self, key: Union[List, Tuple], result: Any) -> None:
|
|
48
|
+
"""Notifies that a result is available for a reference.
|
|
49
|
+
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
key : Union[List, Tuple]
|
|
53
|
+
The reference key.
|
|
54
|
+
result : Any
|
|
55
|
+
The result object.
|
|
56
|
+
"""
|
|
34
57
|
trace(
|
|
35
58
|
"🎯",
|
|
36
59
|
step(key),
|
|
@@ -45,7 +68,19 @@ class Context:
|
|
|
45
68
|
raise ValueError(f"Duplicate result {key}")
|
|
46
69
|
self.results[key] = result
|
|
47
70
|
|
|
48
|
-
def get_result(self, key):
|
|
71
|
+
def get_result(self, key: Union[List, Tuple]) -> Any:
|
|
72
|
+
"""Retrieves the result for a given reference.
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
key : Union[List, Tuple]
|
|
77
|
+
The reference key.
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
Any
|
|
82
|
+
The result for the given reference.
|
|
83
|
+
"""
|
|
49
84
|
assert isinstance(key, (list, tuple)), key
|
|
50
85
|
key = tuple(key)
|
|
51
86
|
if key in self.results:
|
|
@@ -9,7 +9,14 @@
|
|
|
9
9
|
|
|
10
10
|
import logging
|
|
11
11
|
from functools import cached_property
|
|
12
|
+
from typing import Any
|
|
13
|
+
from typing import Dict
|
|
14
|
+
from typing import List
|
|
15
|
+
from typing import Union
|
|
12
16
|
|
|
17
|
+
from earthkit.data import FieldList
|
|
18
|
+
|
|
19
|
+
from ...dates.groups import GroupOfDates
|
|
13
20
|
from .action import Action
|
|
14
21
|
from .action import action_factory
|
|
15
22
|
from .misc import _tidy
|
|
@@ -19,7 +26,28 @@ LOG = logging.getLogger(__name__)
|
|
|
19
26
|
|
|
20
27
|
|
|
21
28
|
class DataSourcesAction(Action):
|
|
22
|
-
|
|
29
|
+
"""Class to handle data sources actions in the dataset creation process."""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
context: object,
|
|
34
|
+
action_path: List[str],
|
|
35
|
+
sources: Union[Dict[str, Any], List[Dict[str, Any]]],
|
|
36
|
+
input: Dict[str, Any],
|
|
37
|
+
) -> None:
|
|
38
|
+
"""Initializes a DataSourcesAction instance.
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
context : object
|
|
43
|
+
The context object.
|
|
44
|
+
action_path : List[str]
|
|
45
|
+
The action path.
|
|
46
|
+
sources : Union[Dict[str, Any], List[Dict[str, Any]]]
|
|
47
|
+
The sources configuration.
|
|
48
|
+
input : Dict[str, Any]
|
|
49
|
+
The input configuration.
|
|
50
|
+
"""
|
|
23
51
|
super().__init__(context, ["data_sources"], *sources)
|
|
24
52
|
if isinstance(sources, dict):
|
|
25
53
|
configs = [(str(k), c) for k, c in sources.items()]
|
|
@@ -31,7 +59,19 @@ class DataSourcesAction(Action):
|
|
|
31
59
|
self.sources = [action_factory(config, context, ["data_sources"] + [a_path]) for a_path, config in configs]
|
|
32
60
|
self.input = action_factory(input, context, ["input"])
|
|
33
61
|
|
|
34
|
-
def select(self, group_of_dates):
|
|
62
|
+
def select(self, group_of_dates: GroupOfDates) -> "DataSourcesResult":
|
|
63
|
+
"""Selects the data sources result for the given group of dates.
|
|
64
|
+
|
|
65
|
+
Parameters
|
|
66
|
+
----------
|
|
67
|
+
group_of_dates : GroupOfDates
|
|
68
|
+
The group of dates.
|
|
69
|
+
|
|
70
|
+
Returns
|
|
71
|
+
-------
|
|
72
|
+
DataSourcesResult
|
|
73
|
+
The data sources result.
|
|
74
|
+
"""
|
|
35
75
|
sources_results = [a.select(group_of_dates) for a in self.sources]
|
|
36
76
|
return DataSourcesResult(
|
|
37
77
|
self.context,
|
|
@@ -41,13 +81,38 @@ class DataSourcesAction(Action):
|
|
|
41
81
|
sources_results,
|
|
42
82
|
)
|
|
43
83
|
|
|
44
|
-
def __repr__(self):
|
|
84
|
+
def __repr__(self) -> str:
|
|
85
|
+
"""Returns a string representation of the DataSourcesAction instance."""
|
|
45
86
|
content = "\n".join([str(i) for i in self.sources])
|
|
46
|
-
return
|
|
87
|
+
return self._repr(content)
|
|
47
88
|
|
|
48
89
|
|
|
49
90
|
class DataSourcesResult(Result):
|
|
50
|
-
|
|
91
|
+
"""Class to represent the result of data sources actions in the dataset creation process."""
|
|
92
|
+
|
|
93
|
+
def __init__(
|
|
94
|
+
self,
|
|
95
|
+
context: object,
|
|
96
|
+
action_path: List[str],
|
|
97
|
+
dates: object,
|
|
98
|
+
input_result: Result,
|
|
99
|
+
sources_results: List[Result],
|
|
100
|
+
) -> None:
|
|
101
|
+
"""Initializes a DataSourcesResult instance.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
context : object
|
|
106
|
+
The context object.
|
|
107
|
+
action_path : List[str]
|
|
108
|
+
The action path.
|
|
109
|
+
dates : object
|
|
110
|
+
The dates object.
|
|
111
|
+
input_result : Result
|
|
112
|
+
The input result.
|
|
113
|
+
sources_results : List[Result]
|
|
114
|
+
The list of sources results.
|
|
115
|
+
"""
|
|
51
116
|
super().__init__(context, action_path, dates)
|
|
52
117
|
# result is the main input result
|
|
53
118
|
self.input_result = input_result
|
|
@@ -55,7 +120,8 @@ class DataSourcesResult(Result):
|
|
|
55
120
|
self.sources_results = sources_results
|
|
56
121
|
|
|
57
122
|
@cached_property
|
|
58
|
-
def datasource(self):
|
|
123
|
+
def datasource(self) -> FieldList:
|
|
124
|
+
"""Returns the combined datasource from all sources."""
|
|
59
125
|
for i in self.sources_results:
|
|
60
126
|
# for each result trigger the datasource to be computed
|
|
61
127
|
# and saved in context
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
import logging
|
|
11
11
|
from functools import cached_property
|
|
12
|
+
from typing import List
|
|
13
|
+
|
|
14
|
+
from earthkit.data import FieldList
|
|
12
15
|
|
|
13
16
|
from .misc import assert_fieldlist
|
|
14
17
|
from .result import Result
|
|
@@ -18,19 +21,34 @@ LOG = logging.getLogger(__name__)
|
|
|
18
21
|
|
|
19
22
|
|
|
20
23
|
class EmptyResult(Result):
|
|
24
|
+
"""Class to represent an empty result in the dataset creation process."""
|
|
25
|
+
|
|
21
26
|
empty = True
|
|
22
27
|
|
|
23
|
-
def __init__(self, context, action_path, dates):
|
|
28
|
+
def __init__(self, context: object, action_path: list, dates: object) -> None:
|
|
29
|
+
"""Initializes an EmptyResult instance.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
context : object
|
|
34
|
+
The context object.
|
|
35
|
+
action_path : list
|
|
36
|
+
The action path.
|
|
37
|
+
dates : object
|
|
38
|
+
The dates object.
|
|
39
|
+
"""
|
|
24
40
|
super().__init__(context, action_path + ["empty"], dates)
|
|
25
41
|
|
|
26
42
|
@cached_property
|
|
27
43
|
@assert_fieldlist
|
|
28
44
|
@trace_datasource
|
|
29
|
-
def datasource(self):
|
|
45
|
+
def datasource(self) -> FieldList:
|
|
46
|
+
"""Returns an empty datasource."""
|
|
30
47
|
from earthkit.data import from_source
|
|
31
48
|
|
|
32
49
|
return from_source("empty")
|
|
33
50
|
|
|
34
51
|
@property
|
|
35
|
-
def variables(self):
|
|
52
|
+
def variables(self) -> List[str]:
|
|
53
|
+
"""Returns an empty list of variables."""
|
|
36
54
|
return []
|
|
@@ -9,8 +9,11 @@
|
|
|
9
9
|
|
|
10
10
|
import logging
|
|
11
11
|
from functools import cached_property
|
|
12
|
+
from typing import Any
|
|
13
|
+
from typing import Type
|
|
14
|
+
|
|
15
|
+
from earthkit.data import FieldList
|
|
12
16
|
|
|
13
|
-
from ..functions import import_function
|
|
14
17
|
from .function import FunctionContext
|
|
15
18
|
from .misc import _tidy
|
|
16
19
|
from .misc import assert_fieldlist
|
|
@@ -27,14 +30,17 @@ class FilterStepResult(StepResult):
|
|
|
27
30
|
@notify_result
|
|
28
31
|
@assert_fieldlist
|
|
29
32
|
@trace_datasource
|
|
30
|
-
def datasource(self):
|
|
31
|
-
|
|
33
|
+
def datasource(self) -> FieldList:
|
|
34
|
+
"""Returns the filtered datasource."""
|
|
35
|
+
ds: FieldList = self.upstream_result.datasource
|
|
32
36
|
ds = ds.sel(**self.action.kwargs)
|
|
33
37
|
return _tidy(ds)
|
|
34
38
|
|
|
35
39
|
|
|
36
40
|
class FilterStepAction(StepAction):
|
|
37
|
-
|
|
41
|
+
"""Represents an action to filter a step result."""
|
|
42
|
+
|
|
43
|
+
result_class: Type[FilterStepResult] = FilterStepResult
|
|
38
44
|
|
|
39
45
|
|
|
40
46
|
class StepFunctionResult(StepResult):
|
|
@@ -42,11 +48,13 @@ class StepFunctionResult(StepResult):
|
|
|
42
48
|
@assert_fieldlist
|
|
43
49
|
@notify_result
|
|
44
50
|
@trace_datasource
|
|
45
|
-
def datasource(self):
|
|
51
|
+
def datasource(self) -> FieldList:
|
|
52
|
+
"""Returns the datasource after applying the function."""
|
|
53
|
+
|
|
54
|
+
self.action.filter.context = FunctionContext(self)
|
|
46
55
|
try:
|
|
47
56
|
return _tidy(
|
|
48
|
-
self.action.
|
|
49
|
-
FunctionContext(self),
|
|
57
|
+
self.action.filter.execute(
|
|
50
58
|
self.upstream_result.datasource,
|
|
51
59
|
*self.action.args[1:],
|
|
52
60
|
**self.action.kwargs,
|
|
@@ -57,14 +65,54 @@ class StepFunctionResult(StepResult):
|
|
|
57
65
|
LOG.error(f"Error in {self.action.name}", exc_info=True)
|
|
58
66
|
raise
|
|
59
67
|
|
|
60
|
-
def _trace_datasource(self, *args, **kwargs):
|
|
68
|
+
def _trace_datasource(self, *args: Any, **kwargs: Any) -> str:
|
|
69
|
+
"""Traces the datasource for the given arguments.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
*args : Any
|
|
74
|
+
The arguments.
|
|
75
|
+
**kwargs : Any
|
|
76
|
+
The keyword arguments.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
str
|
|
81
|
+
A string representation of the traced datasource.
|
|
82
|
+
"""
|
|
61
83
|
return f"{self.action.name}({self.group_of_dates})"
|
|
62
84
|
|
|
63
85
|
|
|
64
86
|
class FunctionStepAction(StepAction):
|
|
65
|
-
|
|
87
|
+
"""Represents an action to apply a function to a step result."""
|
|
88
|
+
|
|
89
|
+
result_class: Type[StepFunctionResult] = StepFunctionResult
|
|
90
|
+
|
|
91
|
+
def __init__(
|
|
92
|
+
self,
|
|
93
|
+
context: object,
|
|
94
|
+
action_path: list,
|
|
95
|
+
previous_step: StepAction,
|
|
96
|
+
name: str,
|
|
97
|
+
filter: Any,
|
|
98
|
+
*args: Any,
|
|
99
|
+
**kwargs: Any,
|
|
100
|
+
) -> None:
|
|
101
|
+
"""Initializes a FunctionStepAction instance.
|
|
66
102
|
|
|
67
|
-
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
context : object
|
|
106
|
+
The context object.
|
|
107
|
+
action_path : list
|
|
108
|
+
The action path.
|
|
109
|
+
previous_step : StepAction
|
|
110
|
+
The previous step action.
|
|
111
|
+
*args : Any
|
|
112
|
+
Additional arguments.
|
|
113
|
+
**kwargs : Any
|
|
114
|
+
Additional keyword arguments.
|
|
115
|
+
"""
|
|
68
116
|
super().__init__(context, action_path, previous_step, *args, **kwargs)
|
|
69
|
-
self.name =
|
|
70
|
-
self.
|
|
117
|
+
self.name = name
|
|
118
|
+
self.filter = filter
|