anemoi-datasets 0.5.26__py3-none-any.whl → 0.5.27__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 +1 -2
- anemoi/datasets/_version.py +16 -3
- anemoi/datasets/commands/check.py +1 -1
- anemoi/datasets/commands/copy.py +1 -2
- anemoi/datasets/commands/create.py +1 -1
- anemoi/datasets/commands/inspect.py +27 -35
- anemoi/datasets/commands/validate.py +59 -0
- anemoi/datasets/compute/recentre.py +3 -6
- anemoi/datasets/create/__init__.py +22 -25
- anemoi/datasets/create/check.py +10 -12
- anemoi/datasets/create/chunks.py +1 -2
- anemoi/datasets/create/config.py +3 -6
- anemoi/datasets/create/filter.py +1 -2
- anemoi/datasets/create/input/__init__.py +1 -2
- anemoi/datasets/create/input/action.py +3 -5
- anemoi/datasets/create/input/concat.py +5 -8
- anemoi/datasets/create/input/context.py +3 -6
- anemoi/datasets/create/input/data_sources.py +5 -8
- anemoi/datasets/create/input/empty.py +1 -2
- anemoi/datasets/create/input/filter.py +2 -3
- anemoi/datasets/create/input/function.py +1 -2
- anemoi/datasets/create/input/join.py +4 -5
- anemoi/datasets/create/input/misc.py +4 -6
- anemoi/datasets/create/input/repeated_dates.py +13 -18
- anemoi/datasets/create/input/result.py +29 -33
- anemoi/datasets/create/input/step.py +4 -8
- anemoi/datasets/create/input/template.py +3 -4
- anemoi/datasets/create/input/trace.py +1 -1
- anemoi/datasets/create/patch.py +1 -2
- anemoi/datasets/create/persistent.py +3 -5
- anemoi/datasets/create/size.py +1 -3
- anemoi/datasets/create/sources/accumulations.py +47 -52
- anemoi/datasets/create/sources/accumulations2.py +4 -8
- anemoi/datasets/create/sources/constants.py +1 -3
- anemoi/datasets/create/sources/empty.py +1 -2
- anemoi/datasets/create/sources/fdb.py +133 -0
- anemoi/datasets/create/sources/forcings.py +1 -2
- anemoi/datasets/create/sources/grib.py +6 -10
- anemoi/datasets/create/sources/grib_index.py +13 -15
- anemoi/datasets/create/sources/hindcasts.py +2 -5
- anemoi/datasets/create/sources/legacy.py +1 -1
- anemoi/datasets/create/sources/mars.py +17 -21
- anemoi/datasets/create/sources/netcdf.py +1 -2
- anemoi/datasets/create/sources/opendap.py +1 -3
- anemoi/datasets/create/sources/patterns.py +4 -6
- anemoi/datasets/create/sources/recentre.py +8 -11
- anemoi/datasets/create/sources/source.py +3 -6
- anemoi/datasets/create/sources/tendencies.py +2 -5
- anemoi/datasets/create/sources/xarray.py +4 -6
- anemoi/datasets/create/sources/xarray_support/__init__.py +12 -13
- anemoi/datasets/create/sources/xarray_support/coordinates.py +8 -12
- anemoi/datasets/create/sources/xarray_support/field.py +16 -12
- anemoi/datasets/create/sources/xarray_support/fieldlist.py +11 -15
- anemoi/datasets/create/sources/xarray_support/flavour.py +42 -42
- anemoi/datasets/create/sources/xarray_support/grid.py +15 -9
- anemoi/datasets/create/sources/xarray_support/metadata.py +19 -128
- anemoi/datasets/create/sources/xarray_support/patch.py +4 -6
- anemoi/datasets/create/sources/xarray_support/time.py +10 -13
- anemoi/datasets/create/sources/xarray_support/variable.py +21 -21
- anemoi/datasets/create/sources/xarray_zarr.py +1 -2
- anemoi/datasets/create/sources/zenodo.py +3 -5
- anemoi/datasets/create/statistics/__init__.py +3 -6
- anemoi/datasets/create/testing.py +4 -0
- anemoi/datasets/create/typing.py +1 -2
- anemoi/datasets/create/utils.py +1 -2
- anemoi/datasets/create/zarr.py +7 -2
- anemoi/datasets/data/__init__.py +15 -6
- anemoi/datasets/data/complement.py +7 -12
- anemoi/datasets/data/concat.py +5 -8
- anemoi/datasets/data/dataset.py +42 -47
- anemoi/datasets/data/debug.py +7 -9
- anemoi/datasets/data/ensemble.py +4 -6
- anemoi/datasets/data/fill_missing.py +7 -10
- anemoi/datasets/data/forwards.py +22 -26
- anemoi/datasets/data/grids.py +12 -16
- anemoi/datasets/data/indexing.py +9 -12
- anemoi/datasets/data/interpolate.py +7 -15
- anemoi/datasets/data/join.py +8 -12
- anemoi/datasets/data/masked.py +6 -11
- anemoi/datasets/data/merge.py +5 -9
- anemoi/datasets/data/misc.py +41 -45
- anemoi/datasets/data/missing.py +11 -16
- anemoi/datasets/data/observations/__init__.py +8 -14
- anemoi/datasets/data/padded.py +3 -5
- anemoi/datasets/data/records/backends/__init__.py +2 -2
- anemoi/datasets/data/rescale.py +5 -12
- anemoi/datasets/data/select.py +13 -16
- anemoi/datasets/data/statistics.py +4 -7
- anemoi/datasets/data/stores.py +16 -21
- anemoi/datasets/data/subset.py +8 -11
- anemoi/datasets/data/unchecked.py +7 -11
- anemoi/datasets/data/xy.py +25 -21
- anemoi/datasets/dates/__init__.py +13 -18
- anemoi/datasets/dates/groups.py +7 -10
- anemoi/datasets/grids.py +5 -9
- anemoi/datasets/testing.py +93 -7
- anemoi/datasets/validate.py +598 -0
- {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.27.dist-info}/METADATA +4 -4
- anemoi_datasets-0.5.27.dist-info/RECORD +134 -0
- anemoi/datasets/utils/__init__.py +0 -8
- anemoi_datasets-0.5.26.dist-info/RECORD +0 -131
- {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.27.dist-info}/WHEEL +0 -0
- {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.27.dist-info}/entry_points.txt +0 -0
- {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.27.dist-info}/licenses/LICENSE +0 -0
- {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.27.dist-info}/top_level.txt +0 -0
anemoi/datasets/data/forwards.py
CHANGED
|
@@ -14,10 +14,6 @@ import warnings
|
|
|
14
14
|
from abc import abstractmethod
|
|
15
15
|
from functools import cached_property
|
|
16
16
|
from typing import Any
|
|
17
|
-
from typing import Dict
|
|
18
|
-
from typing import List
|
|
19
|
-
from typing import Optional
|
|
20
|
-
from typing import Set
|
|
21
17
|
|
|
22
18
|
import numpy as np
|
|
23
19
|
from numpy.typing import NDArray
|
|
@@ -75,7 +71,7 @@ class Forwards(Dataset):
|
|
|
75
71
|
return self.forward[n]
|
|
76
72
|
|
|
77
73
|
@property
|
|
78
|
-
def name(self) ->
|
|
74
|
+
def name(self) -> str | None:
|
|
79
75
|
"""Returns the name of the forward dataset."""
|
|
80
76
|
if self._name is not None:
|
|
81
77
|
return self._name
|
|
@@ -112,26 +108,26 @@ class Forwards(Dataset):
|
|
|
112
108
|
return self.forward.longitudes
|
|
113
109
|
|
|
114
110
|
@property
|
|
115
|
-
def name_to_index(self) ->
|
|
111
|
+
def name_to_index(self) -> dict[str, int]:
|
|
116
112
|
"""Returns a dictionary mapping variable names to their indices."""
|
|
117
113
|
return self.forward.name_to_index
|
|
118
114
|
|
|
119
115
|
@property
|
|
120
|
-
def variables(self) ->
|
|
116
|
+
def variables(self) -> list[str]:
|
|
121
117
|
"""Returns the variables of the forward dataset."""
|
|
122
118
|
return self.forward.variables
|
|
123
119
|
|
|
124
120
|
@property
|
|
125
|
-
def variables_metadata(self) ->
|
|
121
|
+
def variables_metadata(self) -> dict[str, Any]:
|
|
126
122
|
"""Returns the metadata of the variables in the forward dataset."""
|
|
127
123
|
return self.forward.variables_metadata
|
|
128
124
|
|
|
129
125
|
@property
|
|
130
|
-
def statistics(self) ->
|
|
126
|
+
def statistics(self) -> dict[str, NDArray[Any]]:
|
|
131
127
|
"""Returns the statistics of the forward dataset."""
|
|
132
128
|
return self.forward.statistics
|
|
133
129
|
|
|
134
|
-
def statistics_tendencies(self, delta:
|
|
130
|
+
def statistics_tendencies(self, delta: datetime.timedelta | None = None) -> dict[str, NDArray[Any]]:
|
|
135
131
|
"""Returns the statistics tendencies of the forward dataset.
|
|
136
132
|
|
|
137
133
|
Parameters
|
|
@@ -159,7 +155,7 @@ class Forwards(Dataset):
|
|
|
159
155
|
return self.forward.dtype
|
|
160
156
|
|
|
161
157
|
@property
|
|
162
|
-
def missing(self) ->
|
|
158
|
+
def missing(self) -> set[int]:
|
|
163
159
|
"""Returns the missing data information of the forward dataset."""
|
|
164
160
|
return self.forward.missing
|
|
165
161
|
|
|
@@ -168,7 +164,7 @@ class Forwards(Dataset):
|
|
|
168
164
|
"""Returns the grids of the forward dataset."""
|
|
169
165
|
return self.forward.grids
|
|
170
166
|
|
|
171
|
-
def metadata_specific(self, **kwargs: Any) ->
|
|
167
|
+
def metadata_specific(self, **kwargs: Any) -> dict[str, Any]:
|
|
172
168
|
"""Returns metadata specific to the forward dataset.
|
|
173
169
|
|
|
174
170
|
Parameters
|
|
@@ -187,7 +183,7 @@ class Forwards(Dataset):
|
|
|
187
183
|
**kwargs,
|
|
188
184
|
)
|
|
189
185
|
|
|
190
|
-
def collect_supporting_arrays(self, collected:
|
|
186
|
+
def collect_supporting_arrays(self, collected: list[Any], *path: Any) -> None:
|
|
191
187
|
"""Collects supporting arrays from the forward dataset.
|
|
192
188
|
|
|
193
189
|
Parameters
|
|
@@ -199,7 +195,7 @@ class Forwards(Dataset):
|
|
|
199
195
|
"""
|
|
200
196
|
self.forward.collect_supporting_arrays(collected, *path)
|
|
201
197
|
|
|
202
|
-
def collect_input_sources(self, collected:
|
|
198
|
+
def collect_input_sources(self, collected: list[Any]) -> None:
|
|
203
199
|
"""Collects input sources from the forward dataset.
|
|
204
200
|
|
|
205
201
|
Parameters
|
|
@@ -225,11 +221,11 @@ class Forwards(Dataset):
|
|
|
225
221
|
return self.forward.source(index)
|
|
226
222
|
|
|
227
223
|
@abstractmethod
|
|
228
|
-
def forwards_subclass_metadata_specific(self) ->
|
|
224
|
+
def forwards_subclass_metadata_specific(self) -> dict[str, Any]:
|
|
229
225
|
"""Returns metadata specific to the subclass."""
|
|
230
226
|
pass
|
|
231
227
|
|
|
232
|
-
def get_dataset_names(self, names:
|
|
228
|
+
def get_dataset_names(self, names: set[str]) -> None:
|
|
233
229
|
"""Collects the names of the datasets.
|
|
234
230
|
|
|
235
231
|
Parameters
|
|
@@ -240,7 +236,7 @@ class Forwards(Dataset):
|
|
|
240
236
|
self.forward.get_dataset_names(names)
|
|
241
237
|
|
|
242
238
|
@property
|
|
243
|
-
def constant_fields(self) ->
|
|
239
|
+
def constant_fields(self) -> list[str]:
|
|
244
240
|
"""Returns the constant fields of the forward dataset."""
|
|
245
241
|
return self.forward.constant_fields
|
|
246
242
|
|
|
@@ -248,7 +244,7 @@ class Forwards(Dataset):
|
|
|
248
244
|
class Combined(Forwards):
|
|
249
245
|
"""A class to combine multiple datasets into a single dataset."""
|
|
250
246
|
|
|
251
|
-
def __init__(self, datasets:
|
|
247
|
+
def __init__(self, datasets: list[Dataset]) -> None:
|
|
252
248
|
"""Initializes a Combined object.
|
|
253
249
|
|
|
254
250
|
Parameters
|
|
@@ -466,7 +462,7 @@ class Combined(Forwards):
|
|
|
466
462
|
self.check_same_variables(d1, d2)
|
|
467
463
|
self.check_same_dates(d1, d2)
|
|
468
464
|
|
|
469
|
-
def provenance(self) ->
|
|
465
|
+
def provenance(self) -> list[Any]:
|
|
470
466
|
"""Returns the provenance of the combined datasets.
|
|
471
467
|
|
|
472
468
|
Returns
|
|
@@ -487,7 +483,7 @@ class Combined(Forwards):
|
|
|
487
483
|
lst = ", ".join(repr(d) for d in self.datasets)
|
|
488
484
|
return f"{self.__class__.__name__}({lst})"
|
|
489
485
|
|
|
490
|
-
def metadata_specific(self, **kwargs: Any) ->
|
|
486
|
+
def metadata_specific(self, **kwargs: Any) -> dict[str, Any]:
|
|
491
487
|
"""Returns metadata specific to the combined datasets.
|
|
492
488
|
|
|
493
489
|
Parameters
|
|
@@ -508,7 +504,7 @@ class Combined(Forwards):
|
|
|
508
504
|
**kwargs,
|
|
509
505
|
)
|
|
510
506
|
|
|
511
|
-
def collect_supporting_arrays(self, collected:
|
|
507
|
+
def collect_supporting_arrays(self, collected: list[Any], *path: Any) -> None:
|
|
512
508
|
"""Collects supporting arrays from the combined datasets.
|
|
513
509
|
|
|
514
510
|
Parameters
|
|
@@ -524,7 +520,7 @@ class Combined(Forwards):
|
|
|
524
520
|
d.collect_supporting_arrays(collected, *path, name)
|
|
525
521
|
|
|
526
522
|
@property
|
|
527
|
-
def missing(self) ->
|
|
523
|
+
def missing(self) -> set[int]:
|
|
528
524
|
"""Returns the missing data information of the combined datasets.
|
|
529
525
|
|
|
530
526
|
Raises
|
|
@@ -534,7 +530,7 @@ class Combined(Forwards):
|
|
|
534
530
|
"""
|
|
535
531
|
raise NotImplementedError("missing() not implemented for Combined")
|
|
536
532
|
|
|
537
|
-
def get_dataset_names(self, names:
|
|
533
|
+
def get_dataset_names(self, names: set[str]) -> None:
|
|
538
534
|
"""Collects the names of the combined datasets.
|
|
539
535
|
|
|
540
536
|
Parameters
|
|
@@ -549,7 +545,7 @@ class Combined(Forwards):
|
|
|
549
545
|
class GivenAxis(Combined):
|
|
550
546
|
"""A class to combine datasets along a given axis."""
|
|
551
547
|
|
|
552
|
-
def __init__(self, datasets:
|
|
548
|
+
def __init__(self, datasets: list[Any], axis: int) -> None:
|
|
553
549
|
"""Initializes a GivenAxis object.
|
|
554
550
|
|
|
555
551
|
Parameters
|
|
@@ -656,10 +652,10 @@ class GivenAxis(Combined):
|
|
|
656
652
|
return np.concatenate([d[n] for d in self.datasets], axis=self.axis - 1)
|
|
657
653
|
|
|
658
654
|
@cached_property
|
|
659
|
-
def missing(self) ->
|
|
655
|
+
def missing(self) -> set[int]:
|
|
660
656
|
"""Returns the missing data information of the combined dataset along the given axis."""
|
|
661
657
|
offset = 0
|
|
662
|
-
result:
|
|
658
|
+
result: set[int] = set()
|
|
663
659
|
for d in self.datasets:
|
|
664
660
|
result.update(offset + m for m in d.missing)
|
|
665
661
|
if self.axis == 0: # Advance if axis is time
|
anemoi/datasets/data/grids.py
CHANGED
|
@@ -11,10 +11,6 @@
|
|
|
11
11
|
import logging
|
|
12
12
|
from functools import cached_property
|
|
13
13
|
from typing import Any
|
|
14
|
-
from typing import Dict
|
|
15
|
-
from typing import List
|
|
16
|
-
from typing import Optional
|
|
17
|
-
from typing import Tuple
|
|
18
14
|
|
|
19
15
|
import numpy as np
|
|
20
16
|
from numpy.typing import NDArray
|
|
@@ -189,7 +185,7 @@ class Concat(Combined):
|
|
|
189
185
|
class GridsBase(GivenAxis):
|
|
190
186
|
"""A base class for handling grids in datasets."""
|
|
191
187
|
|
|
192
|
-
def __init__(self, datasets:
|
|
188
|
+
def __init__(self, datasets: list[Any], axis: int) -> None:
|
|
193
189
|
"""Initializes a GridsBase object.
|
|
194
190
|
|
|
195
191
|
Parameters
|
|
@@ -229,7 +225,7 @@ class GridsBase(GivenAxis):
|
|
|
229
225
|
# We don't check the resolution, because we want to be able to combine
|
|
230
226
|
pass
|
|
231
227
|
|
|
232
|
-
def metadata_specific(self, **kwargs: Any) ->
|
|
228
|
+
def metadata_specific(self, **kwargs: Any) -> dict[str, Any]:
|
|
233
229
|
"""Returns metadata specific to the GridsBase object.
|
|
234
230
|
|
|
235
231
|
Parameters
|
|
@@ -246,7 +242,7 @@ class GridsBase(GivenAxis):
|
|
|
246
242
|
multi_grids=True,
|
|
247
243
|
)
|
|
248
244
|
|
|
249
|
-
def collect_input_sources(self, collected:
|
|
245
|
+
def collect_input_sources(self, collected: list[Any]) -> None:
|
|
250
246
|
"""Collects input sources from the datasets.
|
|
251
247
|
|
|
252
248
|
Parameters
|
|
@@ -275,7 +271,7 @@ class Grids(GridsBase):
|
|
|
275
271
|
return np.concatenate([d.longitudes for d in self.datasets])
|
|
276
272
|
|
|
277
273
|
@property
|
|
278
|
-
def grids(self) ->
|
|
274
|
+
def grids(self) -> tuple[Any, ...]:
|
|
279
275
|
"""Returns the grids of all datasets."""
|
|
280
276
|
result = []
|
|
281
277
|
for d in self.datasets:
|
|
@@ -292,7 +288,7 @@ class Grids(GridsBase):
|
|
|
292
288
|
"""
|
|
293
289
|
return Node(self, [d.tree() for d in self.datasets], mode="concat")
|
|
294
290
|
|
|
295
|
-
def forwards_subclass_metadata_specific(self) ->
|
|
291
|
+
def forwards_subclass_metadata_specific(self) -> dict[str, Any]:
|
|
296
292
|
"""Get the metadata specific to the forwards subclass.
|
|
297
293
|
|
|
298
294
|
Returns:
|
|
@@ -306,12 +302,12 @@ class Cutout(GridsBase):
|
|
|
306
302
|
|
|
307
303
|
def __init__(
|
|
308
304
|
self,
|
|
309
|
-
datasets:
|
|
305
|
+
datasets: list[Any],
|
|
310
306
|
axis: int = 3,
|
|
311
307
|
cropping_distance: float = 2.0,
|
|
312
308
|
neighbours: int = 5,
|
|
313
|
-
min_distance_km:
|
|
314
|
-
plot:
|
|
309
|
+
min_distance_km: float | None = None,
|
|
310
|
+
plot: bool | None = None,
|
|
315
311
|
) -> None:
|
|
316
312
|
"""Initializes a Cutout object for hierarchical management of Limited Area
|
|
317
313
|
Models (LAMs) and a global dataset, handling overlapping regions.
|
|
@@ -487,7 +483,7 @@ class Cutout(GridsBase):
|
|
|
487
483
|
|
|
488
484
|
return apply_index_to_slices_changes(result, changes)
|
|
489
485
|
|
|
490
|
-
def collect_supporting_arrays(self, collected:
|
|
486
|
+
def collect_supporting_arrays(self, collected: list[Any], *path: Any) -> None:
|
|
491
487
|
"""Collect supporting arrays, including masks for each LAM and the global dataset.
|
|
492
488
|
|
|
493
489
|
Parameters
|
|
@@ -577,7 +573,7 @@ class Cutout(GridsBase):
|
|
|
577
573
|
"""
|
|
578
574
|
return Node(self, [d.tree() for d in self.datasets])
|
|
579
575
|
|
|
580
|
-
def forwards_subclass_metadata_specific(self) ->
|
|
576
|
+
def forwards_subclass_metadata_specific(self) -> dict[str, Any]:
|
|
581
577
|
"""Returns metadata specific to the Cutout object.
|
|
582
578
|
|
|
583
579
|
Returns
|
|
@@ -588,7 +584,7 @@ class Cutout(GridsBase):
|
|
|
588
584
|
return {}
|
|
589
585
|
|
|
590
586
|
|
|
591
|
-
def grids_factory(args:
|
|
587
|
+
def grids_factory(args: tuple[Any, ...], kwargs: dict) -> Dataset:
|
|
592
588
|
"""Factory function to create a Grids object.
|
|
593
589
|
|
|
594
590
|
Parameters
|
|
@@ -618,7 +614,7 @@ def grids_factory(args: Tuple[Any, ...], kwargs: dict) -> Dataset:
|
|
|
618
614
|
return Grids(datasets, axis=axis)._subset(**kwargs)
|
|
619
615
|
|
|
620
616
|
|
|
621
|
-
def cutout_factory(args:
|
|
617
|
+
def cutout_factory(args: tuple[Any, ...], kwargs: dict[str, Any]) -> Dataset:
|
|
622
618
|
"""Factory function to create a Cutout object.
|
|
623
619
|
|
|
624
620
|
Parameters
|
anemoi/datasets/data/indexing.py
CHANGED
|
@@ -8,12 +8,9 @@
|
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
from collections.abc import Callable
|
|
11
12
|
from functools import wraps
|
|
12
13
|
from typing import Any
|
|
13
|
-
from typing import Callable
|
|
14
|
-
from typing import List
|
|
15
|
-
from typing import Tuple
|
|
16
|
-
from typing import Union
|
|
17
14
|
|
|
18
15
|
import numpy as np
|
|
19
16
|
from numpy.typing import NDArray
|
|
@@ -23,7 +20,7 @@ from .dataset import Shape
|
|
|
23
20
|
from .dataset import TupleIndex
|
|
24
21
|
|
|
25
22
|
|
|
26
|
-
def _tuple_with_slices(t: TupleIndex, shape: Shape) ->
|
|
23
|
+
def _tuple_with_slices(t: TupleIndex, shape: Shape) -> tuple[TupleIndex, tuple[int, ...]]:
|
|
27
24
|
"""Replace all integers in a tuple with slices, so we preserve the dimensionality.
|
|
28
25
|
|
|
29
26
|
Parameters:
|
|
@@ -87,7 +84,7 @@ def _index_to_tuple(index: FullIndex, shape: Shape) -> TupleIndex:
|
|
|
87
84
|
raise ValueError(f"Invalid index: {index}")
|
|
88
85
|
|
|
89
86
|
|
|
90
|
-
def index_to_slices(index:
|
|
87
|
+
def index_to_slices(index: int | slice | tuple, shape: Shape) -> tuple[TupleIndex, tuple[int, ...]]:
|
|
91
88
|
"""Convert an index to a tuple of slices, with the same dimensionality as the shape.
|
|
92
89
|
|
|
93
90
|
Parameters:
|
|
@@ -100,7 +97,7 @@ def index_to_slices(index: Union[int, slice, Tuple], shape: Shape) -> Tuple[Tupl
|
|
|
100
97
|
return _tuple_with_slices(_index_to_tuple(index, shape), shape)
|
|
101
98
|
|
|
102
99
|
|
|
103
|
-
def apply_index_to_slices_changes(result: NDArray[Any], changes:
|
|
100
|
+
def apply_index_to_slices_changes(result: NDArray[Any], changes: tuple[int, ...]) -> NDArray[Any]:
|
|
104
101
|
"""Apply changes to the result array based on the slices.
|
|
105
102
|
|
|
106
103
|
Parameters:
|
|
@@ -118,7 +115,7 @@ def apply_index_to_slices_changes(result: NDArray[Any], changes: Tuple[int, ...]
|
|
|
118
115
|
return result
|
|
119
116
|
|
|
120
117
|
|
|
121
|
-
def update_tuple(t:
|
|
118
|
+
def update_tuple(t: tuple, index: int, value: Any) -> tuple[tuple, Any]:
|
|
122
119
|
"""Replace the elements of a tuple at the given index with a new value.
|
|
123
120
|
|
|
124
121
|
Parameters:
|
|
@@ -135,7 +132,7 @@ def update_tuple(t: Tuple, index: int, value: Any) -> Tuple[Tuple, Any]:
|
|
|
135
132
|
return tuple(t), prev
|
|
136
133
|
|
|
137
134
|
|
|
138
|
-
def length_to_slices(index: slice, lengths:
|
|
135
|
+
def length_to_slices(index: slice, lengths: list[int]) -> list[slice | None]:
|
|
139
136
|
"""Convert an index to a list of slices, given the lengths of the dimensions.
|
|
140
137
|
|
|
141
138
|
Parameters:
|
|
@@ -174,7 +171,7 @@ def length_to_slices(index: slice, lengths: List[int]) -> List[Union[slice, None
|
|
|
174
171
|
return result
|
|
175
172
|
|
|
176
173
|
|
|
177
|
-
def _as_tuples(index:
|
|
174
|
+
def _as_tuples(index: tuple) -> tuple:
|
|
178
175
|
"""Convert elements of the index to tuples if they are lists or arrays.
|
|
179
176
|
|
|
180
177
|
Parameters:
|
|
@@ -219,7 +216,7 @@ def expand_list_indexing(method: Callable[..., NDArray[Any]]) -> Callable[..., N
|
|
|
219
216
|
if not any(isinstance(i, (list, tuple)) for i in index):
|
|
220
217
|
return method(self, index)
|
|
221
218
|
|
|
222
|
-
which:
|
|
219
|
+
which: list[int] = []
|
|
223
220
|
for i, idx in enumerate(index):
|
|
224
221
|
if isinstance(idx, (list, tuple)):
|
|
225
222
|
which.append(i)
|
|
@@ -241,7 +238,7 @@ def expand_list_indexing(method: Callable[..., NDArray[Any]]) -> Callable[..., N
|
|
|
241
238
|
return wrapper
|
|
242
239
|
|
|
243
240
|
|
|
244
|
-
def make_slice_or_index_from_list_or_tuple(indices:
|
|
241
|
+
def make_slice_or_index_from_list_or_tuple(indices: list[int]) -> list[int] | slice:
|
|
245
242
|
"""Convert a list or tuple of indices to a slice or an index, if possible.
|
|
246
243
|
|
|
247
244
|
Parameters:
|
|
@@ -12,12 +12,6 @@ import datetime
|
|
|
12
12
|
import logging
|
|
13
13
|
from functools import cached_property
|
|
14
14
|
from typing import Any
|
|
15
|
-
from typing import Dict
|
|
16
|
-
from typing import List
|
|
17
|
-
from typing import Optional
|
|
18
|
-
from typing import Set
|
|
19
|
-
from typing import Tuple
|
|
20
|
-
from typing import Union
|
|
21
15
|
|
|
22
16
|
import numpy as np
|
|
23
17
|
from anemoi.utils.dates import frequency_to_timedelta
|
|
@@ -193,7 +187,7 @@ class InterpolateFrequency(Forwards):
|
|
|
193
187
|
return Node(self, [self.forward.tree()], frequency=self.frequency)
|
|
194
188
|
|
|
195
189
|
@cached_property
|
|
196
|
-
def missing(self) ->
|
|
190
|
+
def missing(self) -> set[int]:
|
|
197
191
|
"""Get the missing data indices."""
|
|
198
192
|
result = []
|
|
199
193
|
j = 0
|
|
@@ -204,10 +198,10 @@ class InterpolateFrequency(Forwards):
|
|
|
204
198
|
result.append(j)
|
|
205
199
|
j += 1
|
|
206
200
|
|
|
207
|
-
result =
|
|
201
|
+
result = {x for x in result if x < self._len}
|
|
208
202
|
return result
|
|
209
203
|
|
|
210
|
-
def forwards_subclass_metadata_specific(self) ->
|
|
204
|
+
def forwards_subclass_metadata_specific(self) -> dict[str, Any]:
|
|
211
205
|
"""Get the metadata specific to the InterpolateFrequency subclass.
|
|
212
206
|
|
|
213
207
|
Returns
|
|
@@ -221,9 +215,7 @@ class InterpolateFrequency(Forwards):
|
|
|
221
215
|
|
|
222
216
|
|
|
223
217
|
class InterpolateNearest(Forwards):
|
|
224
|
-
def __init__(
|
|
225
|
-
self, dataset: Dataset, interpolate_variables: List[str], max_distance: Optional[float] = None
|
|
226
|
-
) -> None:
|
|
218
|
+
def __init__(self, dataset: Dataset, interpolate_variables: list[str], max_distance: float | None = None) -> None:
|
|
227
219
|
"""Initialize the InterpolateNearest class.
|
|
228
220
|
|
|
229
221
|
Parameters
|
|
@@ -262,7 +254,7 @@ class InterpolateNearest(Forwards):
|
|
|
262
254
|
return self.forward.shape
|
|
263
255
|
|
|
264
256
|
@property
|
|
265
|
-
def metadata(self) ->
|
|
257
|
+
def metadata(self) -> dict[str, Any]:
|
|
266
258
|
return self.forward.metadata()
|
|
267
259
|
|
|
268
260
|
@staticmethod
|
|
@@ -281,12 +273,12 @@ class InterpolateNearest(Forwards):
|
|
|
281
273
|
result = target_data[(slice(None),) + index[1:]]
|
|
282
274
|
return apply_index_to_slices_changes(result, changes)
|
|
283
275
|
|
|
284
|
-
def __getitem__(self, index:
|
|
276
|
+
def __getitem__(self, index: int | slice | tuple[int | slice, ...]) -> NDArray[Any]:
|
|
285
277
|
if isinstance(index, (int, slice)):
|
|
286
278
|
index = (index, slice(None), slice(None), slice(None))
|
|
287
279
|
return self._get_tuple(index)
|
|
288
280
|
|
|
289
|
-
def subclass_metadata_specific(self) ->
|
|
281
|
+
def subclass_metadata_specific(self) -> dict[str, Any]:
|
|
290
282
|
return {
|
|
291
283
|
"interpolate_variables": self.vars,
|
|
292
284
|
}
|
anemoi/datasets/data/join.py
CHANGED
|
@@ -12,10 +12,6 @@ import datetime
|
|
|
12
12
|
import logging
|
|
13
13
|
from functools import cached_property
|
|
14
14
|
from typing import Any
|
|
15
|
-
from typing import Dict
|
|
16
|
-
from typing import List
|
|
17
|
-
from typing import Optional
|
|
18
|
-
from typing import Set
|
|
19
15
|
|
|
20
16
|
import numpy as np
|
|
21
17
|
from numpy.typing import NDArray
|
|
@@ -182,10 +178,10 @@ class Join(Combined):
|
|
|
182
178
|
return Select(self, indices, {"overlay": variables})
|
|
183
179
|
|
|
184
180
|
@cached_property
|
|
185
|
-
def variables(self) ->
|
|
181
|
+
def variables(self) -> list[str]:
|
|
186
182
|
"""Get the variables of the joined dataset."""
|
|
187
183
|
seen = set()
|
|
188
|
-
result:
|
|
184
|
+
result: list[str] = []
|
|
189
185
|
for d in reversed(self.datasets):
|
|
190
186
|
for v in reversed(d.variables):
|
|
191
187
|
while v in seen:
|
|
@@ -196,7 +192,7 @@ class Join(Combined):
|
|
|
196
192
|
return result
|
|
197
193
|
|
|
198
194
|
@property
|
|
199
|
-
def variables_metadata(self) ->
|
|
195
|
+
def variables_metadata(self) -> dict[str, Any]:
|
|
200
196
|
"""Get the metadata of the variables."""
|
|
201
197
|
result = {}
|
|
202
198
|
variables = [v for v in self.variables if not (v.startswith("(") and v.endswith(")"))]
|
|
@@ -216,18 +212,18 @@ class Join(Combined):
|
|
|
216
212
|
return result
|
|
217
213
|
|
|
218
214
|
@cached_property
|
|
219
|
-
def name_to_index(self) ->
|
|
215
|
+
def name_to_index(self) -> dict[str, int]:
|
|
220
216
|
"""Get the mapping of variable names to indices."""
|
|
221
217
|
return {k: i for i, k in enumerate(self.variables)}
|
|
222
218
|
|
|
223
219
|
@property
|
|
224
|
-
def statistics(self) ->
|
|
220
|
+
def statistics(self) -> dict[str, NDArray[Any]]:
|
|
225
221
|
"""Get the statistics of the joined dataset."""
|
|
226
222
|
return {
|
|
227
223
|
k: np.concatenate([d.statistics[k] for d in self.datasets], axis=0) for k in self.datasets[0].statistics
|
|
228
224
|
}
|
|
229
225
|
|
|
230
|
-
def statistics_tendencies(self, delta:
|
|
226
|
+
def statistics_tendencies(self, delta: datetime.timedelta | None = None) -> dict[str, NDArray[Any]]:
|
|
231
227
|
"""Get the statistics tendencies of the joined dataset.
|
|
232
228
|
|
|
233
229
|
Parameters
|
|
@@ -268,9 +264,9 @@ class Join(Combined):
|
|
|
268
264
|
assert False
|
|
269
265
|
|
|
270
266
|
@cached_property
|
|
271
|
-
def missing(self) ->
|
|
267
|
+
def missing(self) -> set[int]:
|
|
272
268
|
"""Get the missing data indices."""
|
|
273
|
-
result:
|
|
269
|
+
result: set[int] = set()
|
|
274
270
|
for d in self.datasets:
|
|
275
271
|
result = result | d.missing
|
|
276
272
|
return result
|
anemoi/datasets/data/masked.py
CHANGED
|
@@ -11,11 +11,6 @@
|
|
|
11
11
|
import logging
|
|
12
12
|
from functools import cached_property
|
|
13
13
|
from typing import Any
|
|
14
|
-
from typing import Dict
|
|
15
|
-
from typing import List
|
|
16
|
-
from typing import Optional
|
|
17
|
-
from typing import Tuple
|
|
18
|
-
from typing import Union
|
|
19
14
|
|
|
20
15
|
import numpy as np
|
|
21
16
|
from numpy.typing import NDArray
|
|
@@ -117,7 +112,7 @@ class Masked(Forwards):
|
|
|
117
112
|
result = apply_index_to_slices_changes(result, changes)
|
|
118
113
|
return result
|
|
119
114
|
|
|
120
|
-
def collect_supporting_arrays(self, collected:
|
|
115
|
+
def collect_supporting_arrays(self, collected: list[tuple], *path: Any) -> None:
|
|
121
116
|
"""Collect supporting arrays.
|
|
122
117
|
|
|
123
118
|
Parameters
|
|
@@ -134,7 +129,7 @@ class Masked(Forwards):
|
|
|
134
129
|
class Thinning(Masked):
|
|
135
130
|
"""A class to represent a thinned dataset."""
|
|
136
131
|
|
|
137
|
-
def __init__(self, forward: Dataset, thinning:
|
|
132
|
+
def __init__(self, forward: Dataset, thinning: int | None, method: str) -> None:
|
|
138
133
|
"""Initialize the Thinning class.
|
|
139
134
|
|
|
140
135
|
Parameters
|
|
@@ -195,7 +190,7 @@ class Thinning(Masked):
|
|
|
195
190
|
"""
|
|
196
191
|
return Node(self, [self.forward.tree()], thinning=self.thinning, method=self.method)
|
|
197
192
|
|
|
198
|
-
def forwards_subclass_metadata_specific(self) ->
|
|
193
|
+
def forwards_subclass_metadata_specific(self) -> dict[str, Any]:
|
|
199
194
|
"""Get the metadata specific to the Thinning subclass.
|
|
200
195
|
|
|
201
196
|
Returns
|
|
@@ -209,7 +204,7 @@ class Thinning(Masked):
|
|
|
209
204
|
class Cropping(Masked):
|
|
210
205
|
"""A class to represent a cropped dataset."""
|
|
211
206
|
|
|
212
|
-
def __init__(self, forward: Dataset, area:
|
|
207
|
+
def __init__(self, forward: Dataset, area: Dataset | tuple[float, float, float, float]) -> None:
|
|
213
208
|
"""Initialize the Cropping class.
|
|
214
209
|
|
|
215
210
|
Parameters
|
|
@@ -245,7 +240,7 @@ class Cropping(Masked):
|
|
|
245
240
|
"""
|
|
246
241
|
return Node(self, [self.forward.tree()], area=self.area)
|
|
247
242
|
|
|
248
|
-
def forwards_subclass_metadata_specific(self) ->
|
|
243
|
+
def forwards_subclass_metadata_specific(self) -> dict[str, Any]:
|
|
249
244
|
"""Get the metadata specific to the Cropping subclass.
|
|
250
245
|
|
|
251
246
|
Returns
|
|
@@ -314,7 +309,7 @@ class TrimEdge(Masked):
|
|
|
314
309
|
"""
|
|
315
310
|
return Node(self, [self.forward.tree()], edge=self.edge)
|
|
316
311
|
|
|
317
|
-
def forwards_subclass_metadata_specific(self) ->
|
|
312
|
+
def forwards_subclass_metadata_specific(self) -> dict[str, Any]:
|
|
318
313
|
"""Get the metadata specific to the TrimEdge subclass.
|
|
319
314
|
|
|
320
315
|
Returns
|
anemoi/datasets/data/merge.py
CHANGED
|
@@ -12,10 +12,6 @@ import datetime
|
|
|
12
12
|
import logging
|
|
13
13
|
from functools import cached_property
|
|
14
14
|
from typing import Any
|
|
15
|
-
from typing import Dict
|
|
16
|
-
from typing import List
|
|
17
|
-
from typing import Set
|
|
18
|
-
from typing import Tuple
|
|
19
15
|
|
|
20
16
|
import numpy as np
|
|
21
17
|
from numpy.typing import NDArray
|
|
@@ -40,7 +36,7 @@ LOG = logging.getLogger(__name__)
|
|
|
40
36
|
class Merge(Combined):
|
|
41
37
|
"""A class to merge multiple datasets along the dates axis, handling gaps in dates if allowed."""
|
|
42
38
|
|
|
43
|
-
def __init__(self, datasets:
|
|
39
|
+
def __init__(self, datasets: list[Dataset], allow_gaps_in_dates: bool = False) -> None:
|
|
44
40
|
"""Initialize the Merge object.
|
|
45
41
|
|
|
46
42
|
Parameters
|
|
@@ -128,10 +124,10 @@ class Merge(Combined):
|
|
|
128
124
|
return self._frequency
|
|
129
125
|
|
|
130
126
|
@cached_property
|
|
131
|
-
def missing(self) ->
|
|
127
|
+
def missing(self) -> set[int]:
|
|
132
128
|
"""Get the indices of missing dates in the merged dataset."""
|
|
133
129
|
# TODO: optimize
|
|
134
|
-
result:
|
|
130
|
+
result: set[int] = set()
|
|
135
131
|
|
|
136
132
|
for i, (dataset, row) in enumerate(self._indices):
|
|
137
133
|
if dataset == self._missing_index:
|
|
@@ -192,7 +188,7 @@ class Merge(Combined):
|
|
|
192
188
|
"""
|
|
193
189
|
return Node(self, [d.tree() for d in self.datasets], allow_gaps_in_dates=self.allow_gaps_in_dates)
|
|
194
190
|
|
|
195
|
-
def metadata_specific(self) ->
|
|
191
|
+
def metadata_specific(self) -> dict[str, Any]:
|
|
196
192
|
"""Get the specific metadata for the merged dataset.
|
|
197
193
|
|
|
198
194
|
Returns
|
|
@@ -265,7 +261,7 @@ class Merge(Combined):
|
|
|
265
261
|
return np.stack([self[i] for i in range(*s.indices(self._len))])
|
|
266
262
|
|
|
267
263
|
|
|
268
|
-
def merge_factory(args:
|
|
264
|
+
def merge_factory(args: tuple, kwargs: dict[str, Any]) -> Dataset:
|
|
269
265
|
"""Factory function to create a merged dataset.
|
|
270
266
|
|
|
271
267
|
Parameters
|