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
anemoi/datasets/data/debug.py
CHANGED
|
@@ -12,6 +12,17 @@ import logging
|
|
|
12
12
|
import os
|
|
13
13
|
import textwrap
|
|
14
14
|
from functools import wraps
|
|
15
|
+
from typing import TYPE_CHECKING
|
|
16
|
+
from typing import Any
|
|
17
|
+
from typing import Callable
|
|
18
|
+
from typing import List
|
|
19
|
+
from typing import Optional
|
|
20
|
+
|
|
21
|
+
from anemoi.utils.text import Tree
|
|
22
|
+
from numpy.typing import NDArray
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from .dataset import Dataset
|
|
15
26
|
|
|
16
27
|
LOG = logging.getLogger(__name__)
|
|
17
28
|
|
|
@@ -24,20 +35,55 @@ DEPTH = 0
|
|
|
24
35
|
# a.flags.writeable = False
|
|
25
36
|
|
|
26
37
|
|
|
27
|
-
def css(name):
|
|
38
|
+
def css(name: str) -> str:
|
|
39
|
+
"""Get the CSS content from a file.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
name : str
|
|
44
|
+
The name of the CSS file.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
str
|
|
49
|
+
The CSS content.
|
|
50
|
+
"""
|
|
28
51
|
path = os.path.join(os.path.dirname(__file__), f"{name}.css")
|
|
29
52
|
with open(path) as f:
|
|
30
53
|
return f"<style>{f.read()}</style>"
|
|
31
54
|
|
|
32
55
|
|
|
33
56
|
class Node:
|
|
34
|
-
|
|
57
|
+
"""A class to represent a node in a dataset tree."""
|
|
58
|
+
|
|
59
|
+
def __init__(self, dataset: "Dataset", kids: List[Any], **kwargs: Any) -> None:
|
|
60
|
+
"""Initializes a Node object.
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
dataset : Dataset
|
|
65
|
+
The dataset associated with the node.
|
|
66
|
+
kids : List[Any]
|
|
67
|
+
List of child nodes.
|
|
68
|
+
kwargs : Any
|
|
69
|
+
Additional keyword arguments.
|
|
70
|
+
"""
|
|
35
71
|
self.dataset = dataset
|
|
36
72
|
self.kids = kids
|
|
37
73
|
self.kwargs = kwargs
|
|
38
74
|
|
|
39
|
-
def _put(self, indent, result):
|
|
40
|
-
|
|
75
|
+
def _put(self, indent: int, result: List[str]) -> None:
|
|
76
|
+
"""Helper method to add the node representation to the result list.
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
indent : int
|
|
81
|
+
Indentation level.
|
|
82
|
+
result : List[str]
|
|
83
|
+
List to store the node representation.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def _spaces(indent: int) -> str:
|
|
41
87
|
return " " * indent if indent else ""
|
|
42
88
|
|
|
43
89
|
result.append(f"{_spaces(indent)}{self.dataset.__class__.__name__}")
|
|
@@ -49,12 +95,28 @@ class Node:
|
|
|
49
95
|
for kid in self.kids:
|
|
50
96
|
kid._put(indent + 2, result)
|
|
51
97
|
|
|
52
|
-
def __repr__(self):
|
|
53
|
-
|
|
98
|
+
def __repr__(self) -> str:
|
|
99
|
+
"""Returns the string representation of the node.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
str
|
|
104
|
+
String representation of the node.
|
|
105
|
+
"""
|
|
106
|
+
result: List[str] = []
|
|
54
107
|
self._put(0, result)
|
|
55
108
|
return "\n".join(result)
|
|
56
109
|
|
|
57
|
-
def graph(self, digraph, nodes):
|
|
110
|
+
def graph(self, digraph: List[str], nodes: dict) -> None:
|
|
111
|
+
"""Generates a graph representation of the node.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
digraph : List[str]
|
|
116
|
+
List to store the graph representation.
|
|
117
|
+
nodes : dict
|
|
118
|
+
Dictionary to store the node labels.
|
|
119
|
+
"""
|
|
58
120
|
label = self.dataset.label # dataset.__class__.__name__.lower()
|
|
59
121
|
if self.kwargs:
|
|
60
122
|
param = []
|
|
@@ -88,7 +150,14 @@ class Node:
|
|
|
88
150
|
digraph.append(f"N{id(self)} -> N{id(kid)}")
|
|
89
151
|
kid.graph(digraph, nodes)
|
|
90
152
|
|
|
91
|
-
def digraph(self):
|
|
153
|
+
def digraph(self) -> str:
|
|
154
|
+
"""Returns the graph representation of the node.
|
|
155
|
+
|
|
156
|
+
Returns
|
|
157
|
+
-------
|
|
158
|
+
str
|
|
159
|
+
Graph representation of the node.
|
|
160
|
+
"""
|
|
92
161
|
digraph = ["digraph {"]
|
|
93
162
|
digraph.append("node [shape=box];")
|
|
94
163
|
nodes = {}
|
|
@@ -101,8 +170,16 @@ class Node:
|
|
|
101
170
|
digraph.append("}")
|
|
102
171
|
return "\n".join(digraph)
|
|
103
172
|
|
|
104
|
-
def _html(self, indent, rows):
|
|
173
|
+
def _html(self, indent: str, rows: List[List[str]]) -> None:
|
|
174
|
+
"""Helper method to add the node representation to the HTML rows.
|
|
105
175
|
|
|
176
|
+
Parameters
|
|
177
|
+
----------
|
|
178
|
+
indent : str
|
|
179
|
+
Indentation level.
|
|
180
|
+
rows : List[List[str]]
|
|
181
|
+
List to store the HTML rows.
|
|
182
|
+
"""
|
|
106
183
|
kwargs = {}
|
|
107
184
|
|
|
108
185
|
for k, v in self.kwargs.items():
|
|
@@ -130,7 +207,14 @@ class Node:
|
|
|
130
207
|
for kid in self.kids:
|
|
131
208
|
kid._html(indent + " ", rows)
|
|
132
209
|
|
|
133
|
-
def html(self):
|
|
210
|
+
def html(self) -> str:
|
|
211
|
+
"""Returns the HTML representation of the node.
|
|
212
|
+
|
|
213
|
+
Returns
|
|
214
|
+
-------
|
|
215
|
+
str
|
|
216
|
+
HTML representation of the node.
|
|
217
|
+
"""
|
|
134
218
|
result = [css("debug")]
|
|
135
219
|
|
|
136
220
|
result.append('<table class="dataset">')
|
|
@@ -145,37 +229,78 @@ class Node:
|
|
|
145
229
|
result.append("</table>")
|
|
146
230
|
return "\n".join(result)
|
|
147
231
|
|
|
148
|
-
def _as_tree(self, tree):
|
|
232
|
+
def _as_tree(self, tree: Any) -> None:
|
|
233
|
+
"""Helper method to add the node representation to the tree.
|
|
149
234
|
|
|
235
|
+
Parameters
|
|
236
|
+
----------
|
|
237
|
+
tree : Any
|
|
238
|
+
Tree object to store the node representation.
|
|
239
|
+
"""
|
|
150
240
|
for kid in self.kids:
|
|
151
241
|
n = tree.node(kid)
|
|
152
242
|
kid._as_tree(n)
|
|
153
243
|
|
|
154
|
-
def as_tree(self):
|
|
155
|
-
|
|
244
|
+
def as_tree(self) -> Tree:
|
|
245
|
+
"""Returns the tree representation of the node.
|
|
246
|
+
|
|
247
|
+
Returns
|
|
248
|
+
-------
|
|
249
|
+
Tree
|
|
250
|
+
Tree representation of the node.
|
|
251
|
+
"""
|
|
156
252
|
|
|
157
253
|
tree = Tree(self)
|
|
158
254
|
self._as_tree(tree)
|
|
159
255
|
return tree
|
|
160
256
|
|
|
161
257
|
@property
|
|
162
|
-
def summary(self):
|
|
258
|
+
def summary(self) -> str:
|
|
259
|
+
"""Returns the summary of the node."""
|
|
163
260
|
return self.dataset.label
|
|
164
261
|
|
|
165
|
-
def as_dict(self):
|
|
262
|
+
def as_dict(self) -> dict:
|
|
263
|
+
"""Returns the dictionary representation of the node.
|
|
264
|
+
|
|
265
|
+
Returns
|
|
266
|
+
-------
|
|
267
|
+
dict
|
|
268
|
+
Dictionary representation of the node.
|
|
269
|
+
"""
|
|
166
270
|
return {}
|
|
167
271
|
|
|
168
272
|
|
|
169
273
|
class Source:
|
|
170
|
-
"""
|
|
171
|
-
|
|
172
|
-
def __init__(self, dataset, index, source=None, info=None):
|
|
274
|
+
"""A class used to follow the provenance of a data point."""
|
|
275
|
+
|
|
276
|
+
def __init__(self, dataset: Any, index: int, source: Optional[Any] = None, info: Optional[Any] = None) -> None:
|
|
277
|
+
"""Initializes a Source object.
|
|
278
|
+
|
|
279
|
+
Parameters
|
|
280
|
+
----------
|
|
281
|
+
dataset : Any
|
|
282
|
+
The dataset associated with the source.
|
|
283
|
+
index : int
|
|
284
|
+
Index of the data point.
|
|
285
|
+
source : Optional[Any], optional
|
|
286
|
+
Source of the data point, by default None.
|
|
287
|
+
info : Optional[Any], optional
|
|
288
|
+
Additional information, by default None.
|
|
289
|
+
"""
|
|
173
290
|
self.dataset = dataset
|
|
291
|
+
|
|
174
292
|
self.index = index
|
|
175
293
|
self.source = source
|
|
176
294
|
self.info = info
|
|
177
295
|
|
|
178
|
-
def __repr__(self):
|
|
296
|
+
def __repr__(self) -> str:
|
|
297
|
+
"""Returns the string representation of the source.
|
|
298
|
+
|
|
299
|
+
Returns
|
|
300
|
+
-------
|
|
301
|
+
str
|
|
302
|
+
String representation of the source.
|
|
303
|
+
"""
|
|
179
304
|
p = s = self.source
|
|
180
305
|
while s is not None:
|
|
181
306
|
p = s
|
|
@@ -183,22 +308,49 @@ class Source:
|
|
|
183
308
|
|
|
184
309
|
return f"{self.dataset}[{self.index}, {self.dataset.variables[self.index]}] ({p})"
|
|
185
310
|
|
|
186
|
-
def target(self):
|
|
311
|
+
def target(self) -> Any:
|
|
312
|
+
"""Returns the target source.
|
|
313
|
+
|
|
314
|
+
Returns
|
|
315
|
+
-------
|
|
316
|
+
Any
|
|
317
|
+
Target source.
|
|
318
|
+
"""
|
|
187
319
|
p = s = self.source
|
|
188
320
|
while s is not None:
|
|
189
321
|
p = s
|
|
190
322
|
s = s.source
|
|
191
323
|
return p
|
|
192
324
|
|
|
193
|
-
def dump(self, depth=0):
|
|
325
|
+
def dump(self, depth: int = 0) -> None:
|
|
326
|
+
"""Dumps the source information.
|
|
327
|
+
|
|
328
|
+
Parameters
|
|
329
|
+
----------
|
|
330
|
+
depth : int, optional
|
|
331
|
+
Indentation level, by default 0.
|
|
332
|
+
"""
|
|
194
333
|
print(" " * depth, self)
|
|
195
334
|
if self.source is not None:
|
|
196
335
|
self.source.dump(depth + 1)
|
|
197
336
|
|
|
198
337
|
|
|
199
|
-
def _debug_indexing(method):
|
|
338
|
+
def _debug_indexing(method: Callable[..., NDArray[Any]]) -> Callable[..., NDArray[Any]]:
|
|
339
|
+
"""Decorator to debug indexing methods.
|
|
340
|
+
|
|
341
|
+
Parameters
|
|
342
|
+
----------
|
|
343
|
+
method : Callable[..., NDArray[Any]]
|
|
344
|
+
The method to be decorated.
|
|
345
|
+
|
|
346
|
+
Returns
|
|
347
|
+
-------
|
|
348
|
+
Callable[..., NDArray[Any]]
|
|
349
|
+
The decorated method.
|
|
350
|
+
"""
|
|
351
|
+
|
|
200
352
|
@wraps(method)
|
|
201
|
-
def wrapper(self, index):
|
|
353
|
+
def wrapper(self: Any, index: Any) -> NDArray[Any]:
|
|
202
354
|
global DEPTH
|
|
203
355
|
# if isinstance(index, tuple):
|
|
204
356
|
print(" " * DEPTH, "->", self, method.__name__, index)
|
|
@@ -212,8 +364,20 @@ def _debug_indexing(method):
|
|
|
212
364
|
return wrapper
|
|
213
365
|
|
|
214
366
|
|
|
215
|
-
def _identity(
|
|
216
|
-
|
|
367
|
+
def _identity(method: Callable[..., NDArray[Any]]) -> Callable[..., NDArray[Any]]:
|
|
368
|
+
"""Identity function.
|
|
369
|
+
|
|
370
|
+
Parameters
|
|
371
|
+
----------
|
|
372
|
+
method : Callable[..., NDArray[Any]]
|
|
373
|
+
Input method.
|
|
374
|
+
|
|
375
|
+
Returns
|
|
376
|
+
-------
|
|
377
|
+
Callable[..., NDArray[Any]]
|
|
378
|
+
The input method.
|
|
379
|
+
"""
|
|
380
|
+
return method
|
|
217
381
|
|
|
218
382
|
|
|
219
383
|
if DEBUG_ZARR_INDEXING:
|
|
@@ -222,6 +386,13 @@ else:
|
|
|
222
386
|
debug_indexing = _identity
|
|
223
387
|
|
|
224
388
|
|
|
225
|
-
def debug_zarr_loading(on_off):
|
|
389
|
+
def debug_zarr_loading(on_off: int) -> None:
|
|
390
|
+
"""Enables or disables Zarr loading debugging.
|
|
391
|
+
|
|
392
|
+
Parameters
|
|
393
|
+
----------
|
|
394
|
+
on_off : int
|
|
395
|
+
1 to enable debugging, 0 to disable.
|
|
396
|
+
"""
|
|
226
397
|
global DEBUG_ZARR_LOADING
|
|
227
398
|
DEBUG_ZARR_LOADING = on_off
|
anemoi/datasets/data/ensemble.py
CHANGED
|
@@ -9,9 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
import logging
|
|
12
|
+
from typing import Any
|
|
13
|
+
from typing import Dict
|
|
14
|
+
from typing import Tuple
|
|
12
15
|
|
|
13
16
|
import numpy as np
|
|
17
|
+
from numpy.typing import NDArray
|
|
14
18
|
|
|
19
|
+
from .dataset import Dataset
|
|
20
|
+
from .dataset import FullIndex
|
|
21
|
+
from .dataset import Shape
|
|
15
22
|
from .debug import Node
|
|
16
23
|
from .forwards import Forwards
|
|
17
24
|
from .forwards import GivenAxis
|
|
@@ -27,7 +34,18 @@ OFFSETS = dict(number=1, numbers=1, member=0, members=0)
|
|
|
27
34
|
|
|
28
35
|
|
|
29
36
|
class Number(Forwards):
|
|
30
|
-
|
|
37
|
+
"""A class to represent a subset of ensemble members from a dataset."""
|
|
38
|
+
|
|
39
|
+
def __init__(self, forward: Dataset, **kwargs: Any) -> None:
|
|
40
|
+
"""Initializes a Number object.
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
forward : Any
|
|
45
|
+
The dataset to forward.
|
|
46
|
+
kwargs : Any
|
|
47
|
+
Additional keyword arguments specifying the members.
|
|
48
|
+
"""
|
|
31
49
|
super().__init__(forward)
|
|
32
50
|
|
|
33
51
|
self.members = []
|
|
@@ -45,10 +63,23 @@ class Number(Forwards):
|
|
|
45
63
|
self._shape, _ = update_tuple(forward.shape, 2, len(self.members))
|
|
46
64
|
|
|
47
65
|
@property
|
|
48
|
-
def shape(self):
|
|
66
|
+
def shape(self) -> Shape:
|
|
67
|
+
"""Returns the shape of the dataset."""
|
|
49
68
|
return self._shape
|
|
50
69
|
|
|
51
|
-
def __getitem__(self, index):
|
|
70
|
+
def __getitem__(self, index: FullIndex) -> NDArray[Any]:
|
|
71
|
+
"""Retrieves data from the dataset based on the given index.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
index : FullIndex
|
|
76
|
+
Index specifying the data to retrieve.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
NDArray[Any]
|
|
81
|
+
Data array from the dataset based on the index.
|
|
82
|
+
"""
|
|
52
83
|
if isinstance(index, int):
|
|
53
84
|
result = self.forward[index]
|
|
54
85
|
result = result[:, self.mask, :]
|
|
@@ -59,26 +90,80 @@ class Number(Forwards):
|
|
|
59
90
|
result = result[:, :, self.mask, :]
|
|
60
91
|
return result
|
|
61
92
|
|
|
62
|
-
index, changes = index_to_slices(index, self.shape)
|
|
93
|
+
index, changes = index_to_slices(index, self.forward.shape)
|
|
63
94
|
result = self.forward[index]
|
|
64
95
|
result = result[:, :, self.mask, :]
|
|
65
96
|
return apply_index_to_slices_changes(result, changes)
|
|
66
97
|
|
|
67
|
-
def tree(self):
|
|
98
|
+
def tree(self) -> Node:
|
|
99
|
+
"""Generates a hierarchical tree structure for the dataset.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
Node
|
|
104
|
+
A Node object representing the dataset.
|
|
105
|
+
"""
|
|
68
106
|
return Node(self, [self.forward.tree()], numbers=[n + 1 for n in self.members])
|
|
69
107
|
|
|
70
|
-
def metadata_specific(self):
|
|
108
|
+
def metadata_specific(self, **kwargs: Any) -> Dict[str, Any]:
|
|
109
|
+
"""Returns metadata specific to the Number object.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
kwargs : Any
|
|
114
|
+
Additional keyword arguments.
|
|
115
|
+
|
|
116
|
+
Returns
|
|
117
|
+
-------
|
|
118
|
+
Dict[str, Any]
|
|
119
|
+
Metadata specific to the Number object.
|
|
120
|
+
"""
|
|
71
121
|
return {
|
|
72
122
|
"numbers": [n + 1 for n in self.members],
|
|
73
123
|
}
|
|
74
124
|
|
|
125
|
+
def forwards_subclass_metadata_specific(self) -> Dict[str, Any]:
|
|
126
|
+
"""Returns metadata specific to the Number object."""
|
|
127
|
+
return {}
|
|
128
|
+
|
|
75
129
|
|
|
76
130
|
class Ensemble(GivenAxis):
|
|
77
|
-
|
|
131
|
+
"""A class to represent an ensemble of datasets combined along a given axis."""
|
|
132
|
+
|
|
133
|
+
def tree(self) -> Node:
|
|
134
|
+
"""Generates a hierarchical tree structure for the ensemble datasets.
|
|
135
|
+
|
|
136
|
+
Returns
|
|
137
|
+
-------
|
|
138
|
+
Node
|
|
139
|
+
A Node object representing the ensemble datasets.
|
|
140
|
+
"""
|
|
78
141
|
return Node(self, [d.tree() for d in self.datasets])
|
|
79
142
|
|
|
143
|
+
def forwards_subclass_metadata_specific(self) -> Dict[str, Any]:
|
|
144
|
+
"""Get the metadata specific to the forwards subclass.
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
Dict[str, Any]: The metadata specific to the forwards subclass.
|
|
148
|
+
"""
|
|
149
|
+
return {}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def ensemble_factory(args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Ensemble:
|
|
153
|
+
"""Factory function to create an Ensemble object.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
args : Tuple[Any, ...]
|
|
158
|
+
Positional arguments.
|
|
159
|
+
kwargs : dict
|
|
160
|
+
Keyword arguments.
|
|
80
161
|
|
|
81
|
-
|
|
162
|
+
Returns
|
|
163
|
+
-------
|
|
164
|
+
Ensemble
|
|
165
|
+
An Ensemble object.
|
|
166
|
+
"""
|
|
82
167
|
if "grids" in kwargs:
|
|
83
168
|
raise NotImplementedError("Cannot use both 'ensemble' and 'grids'")
|
|
84
169
|
|