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/rescale.py
CHANGED
|
@@ -8,11 +8,22 @@
|
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
import datetime
|
|
11
12
|
import logging
|
|
12
13
|
from functools import cached_property
|
|
14
|
+
from typing import Any
|
|
15
|
+
from typing import Dict
|
|
16
|
+
from typing import List
|
|
17
|
+
from typing import Optional
|
|
18
|
+
from typing import Tuple
|
|
19
|
+
from typing import Union
|
|
13
20
|
|
|
14
21
|
import numpy as np
|
|
22
|
+
from numpy.typing import NDArray
|
|
15
23
|
|
|
24
|
+
from .dataset import Dataset
|
|
25
|
+
from .dataset import FullIndex
|
|
26
|
+
from .dataset import TupleIndex
|
|
16
27
|
from .debug import Node
|
|
17
28
|
from .debug import debug_indexing
|
|
18
29
|
from .forwards import Forwards
|
|
@@ -24,8 +35,23 @@ from .indexing import update_tuple
|
|
|
24
35
|
LOG = logging.getLogger(__name__)
|
|
25
36
|
|
|
26
37
|
|
|
27
|
-
def make_rescale(
|
|
38
|
+
def make_rescale(
|
|
39
|
+
variable: str, rescale: Union[Tuple[float, float], List[str], Dict[str, float]]
|
|
40
|
+
) -> Tuple[float, float]:
|
|
41
|
+
"""Create rescale parameters (scale and offset) based on the input rescale specification.
|
|
28
42
|
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
variable : str
|
|
46
|
+
The variable name.
|
|
47
|
+
rescale : Union[Tuple[float, float], List[str], Dict[str, float]]
|
|
48
|
+
The rescale specification.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
Tuple[float, float]
|
|
53
|
+
The scale and offset values.
|
|
54
|
+
"""
|
|
29
55
|
if isinstance(rescale, (tuple, list)):
|
|
30
56
|
|
|
31
57
|
assert len(rescale) == 2, rescale
|
|
@@ -57,7 +83,20 @@ def make_rescale(variable, rescale):
|
|
|
57
83
|
|
|
58
84
|
|
|
59
85
|
class Rescale(Forwards):
|
|
60
|
-
|
|
86
|
+
"""A class to apply rescaling to dataset variables."""
|
|
87
|
+
|
|
88
|
+
def __init__(
|
|
89
|
+
self, dataset: Dataset, rescale: Dict[str, Union[Tuple[float, float], List[str], Dict[str, float]]]
|
|
90
|
+
) -> None:
|
|
91
|
+
"""Initialize the Rescale object.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
dataset : Dataset
|
|
96
|
+
The dataset to be rescaled.
|
|
97
|
+
rescale : Dict[str, Union[Tuple[float, float], List[str], Dict[str, float]]]
|
|
98
|
+
The rescale specifications.
|
|
99
|
+
"""
|
|
61
100
|
super().__init__(dataset)
|
|
62
101
|
for n in rescale:
|
|
63
102
|
assert n in dataset.variables, n
|
|
@@ -80,15 +119,41 @@ class Rescale(Forwards):
|
|
|
80
119
|
self._a = self._a.astype(self.forward.dtype)
|
|
81
120
|
self._b = self._b.astype(self.forward.dtype)
|
|
82
121
|
|
|
83
|
-
def tree(self):
|
|
122
|
+
def tree(self) -> Node:
|
|
123
|
+
"""Get the tree representation of the rescale operation.
|
|
124
|
+
|
|
125
|
+
Returns
|
|
126
|
+
-------
|
|
127
|
+
Node
|
|
128
|
+
The tree representation.
|
|
129
|
+
"""
|
|
84
130
|
return Node(self, [self.forward.tree()], rescale=self.rescale)
|
|
85
131
|
|
|
86
|
-
def
|
|
132
|
+
def forwards_subclass_metadata_specific(self) -> Dict[str, Any]:
|
|
133
|
+
"""Get the metadata specific to the rescale subclass.
|
|
134
|
+
|
|
135
|
+
Returns
|
|
136
|
+
-------
|
|
137
|
+
Dict[str, Any]
|
|
138
|
+
The metadata dictionary.
|
|
139
|
+
"""
|
|
87
140
|
return dict(rescale=self.rescale)
|
|
88
141
|
|
|
89
142
|
@debug_indexing
|
|
90
143
|
@expand_list_indexing
|
|
91
|
-
def _get_tuple(self, index):
|
|
144
|
+
def _get_tuple(self, index: TupleIndex) -> NDArray[Any]:
|
|
145
|
+
"""Get a tuple of rescaled data based on the provided index.
|
|
146
|
+
|
|
147
|
+
Parameters
|
|
148
|
+
----------
|
|
149
|
+
index : TupleIndex
|
|
150
|
+
The index to retrieve data.
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
NDArray[Any]
|
|
155
|
+
The rescaled data.
|
|
156
|
+
"""
|
|
92
157
|
index, changes = index_to_slices(index, self.shape)
|
|
93
158
|
index, previous = update_tuple(index, 1, slice(None))
|
|
94
159
|
result = self.forward[index]
|
|
@@ -98,13 +163,36 @@ class Rescale(Forwards):
|
|
|
98
163
|
return result
|
|
99
164
|
|
|
100
165
|
@debug_indexing
|
|
101
|
-
def __get_slice_(self, n):
|
|
166
|
+
def __get_slice_(self, n: slice) -> NDArray[Any]:
|
|
167
|
+
"""Get a slice of rescaled data.
|
|
168
|
+
|
|
169
|
+
Parameters
|
|
170
|
+
----------
|
|
171
|
+
n : slice
|
|
172
|
+
The slice to retrieve data.
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
NDArray[Any]
|
|
177
|
+
The rescaled data.
|
|
178
|
+
"""
|
|
102
179
|
data = self.forward[n]
|
|
103
180
|
return data * self._a + self._b
|
|
104
181
|
|
|
105
182
|
@debug_indexing
|
|
106
|
-
def __getitem__(self, n):
|
|
107
|
-
|
|
183
|
+
def __getitem__(self, n: FullIndex) -> NDArray[Any]:
|
|
184
|
+
"""Get an item or slice of rescaled data based on the provided index.
|
|
185
|
+
|
|
186
|
+
Parameters
|
|
187
|
+
----------
|
|
188
|
+
n : FullIndex
|
|
189
|
+
The index to retrieve data.
|
|
190
|
+
|
|
191
|
+
Returns
|
|
192
|
+
-------
|
|
193
|
+
NDArray[Any]
|
|
194
|
+
The rescaled data.
|
|
195
|
+
"""
|
|
108
196
|
if isinstance(n, tuple):
|
|
109
197
|
return self._get_tuple(n)
|
|
110
198
|
|
|
@@ -116,7 +204,8 @@ class Rescale(Forwards):
|
|
|
116
204
|
return data * self._a[0] + self._b[0]
|
|
117
205
|
|
|
118
206
|
@cached_property
|
|
119
|
-
def statistics(self):
|
|
207
|
+
def statistics(self) -> Dict[str, NDArray[Any]]:
|
|
208
|
+
"""Get the statistics of the rescaled data."""
|
|
120
209
|
result = {}
|
|
121
210
|
a = self._a.squeeze()
|
|
122
211
|
assert np.all(a >= 0)
|
|
@@ -135,7 +224,19 @@ class Rescale(Forwards):
|
|
|
135
224
|
|
|
136
225
|
return result
|
|
137
226
|
|
|
138
|
-
def statistics_tendencies(self, delta=None):
|
|
227
|
+
def statistics_tendencies(self, delta: Optional[datetime.timedelta] = None) -> Dict[str, NDArray[Any]]:
|
|
228
|
+
"""Get the tendencies of the statistics of the rescaled data.
|
|
229
|
+
|
|
230
|
+
Parameters
|
|
231
|
+
----------
|
|
232
|
+
delta : Optional[datetime.timedelta]
|
|
233
|
+
The time delta for tendencies calculation.
|
|
234
|
+
|
|
235
|
+
Returns
|
|
236
|
+
-------
|
|
237
|
+
Dict[str, NDArray[Any]]
|
|
238
|
+
The tendencies statistics dictionary.
|
|
239
|
+
"""
|
|
139
240
|
result = {}
|
|
140
241
|
a = self._a.squeeze()
|
|
141
242
|
assert np.all(a >= 0)
|
anemoi/datasets/data/select.py
CHANGED
|
@@ -8,9 +8,20 @@
|
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
import datetime
|
|
11
12
|
import logging
|
|
12
13
|
from functools import cached_property
|
|
14
|
+
from typing import Any
|
|
15
|
+
from typing import Dict
|
|
16
|
+
from typing import List
|
|
17
|
+
from typing import Optional
|
|
13
18
|
|
|
19
|
+
from numpy.typing import NDArray
|
|
20
|
+
|
|
21
|
+
from .dataset import Dataset
|
|
22
|
+
from .dataset import FullIndex
|
|
23
|
+
from .dataset import Shape
|
|
24
|
+
from .dataset import TupleIndex
|
|
14
25
|
from .debug import Node
|
|
15
26
|
from .debug import Source
|
|
16
27
|
from .debug import debug_indexing
|
|
@@ -24,10 +35,20 @@ LOG = logging.getLogger(__name__)
|
|
|
24
35
|
|
|
25
36
|
|
|
26
37
|
class Select(Forwards):
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
def __init__(self, dataset, indices, reason):
|
|
30
|
-
|
|
38
|
+
"""Class to select a subset of variables from a dataset."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, dataset: Dataset, indices: List[int], reason: Dict[str, Any]) -> None:
|
|
41
|
+
"""Initialize the Select class.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
dataset : Dataset
|
|
46
|
+
The dataset to select from.
|
|
47
|
+
indices : List[int]
|
|
48
|
+
The indices of the variables to select.
|
|
49
|
+
reason : Dict[str, Any]
|
|
50
|
+
The reason for the selection.
|
|
51
|
+
"""
|
|
31
52
|
reason = reason.copy()
|
|
32
53
|
|
|
33
54
|
while isinstance(dataset, Select):
|
|
@@ -35,23 +56,53 @@ class Select(Forwards):
|
|
|
35
56
|
reason.update(dataset.reason)
|
|
36
57
|
dataset = dataset.dataset
|
|
37
58
|
|
|
38
|
-
self.dataset = dataset
|
|
59
|
+
self.dataset: Dataset = dataset
|
|
39
60
|
self.indices = list(indices)
|
|
40
61
|
assert len(self.indices) > 0
|
|
41
62
|
self.reason = reason or {"indices": self.indices}
|
|
42
63
|
|
|
43
|
-
# Forward other properties to the main dataset
|
|
44
64
|
super().__init__(dataset)
|
|
45
65
|
|
|
46
|
-
def clone(self, dataset):
|
|
66
|
+
def clone(self, dataset: Dataset) -> Dataset:
|
|
67
|
+
"""Clone the Select object with a new dataset.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
dataset : Dataset
|
|
72
|
+
The new dataset.
|
|
73
|
+
|
|
74
|
+
Returns
|
|
75
|
+
-------
|
|
76
|
+
Select
|
|
77
|
+
The cloned Select object.
|
|
78
|
+
"""
|
|
47
79
|
return self.__class__(dataset, self.indices, self.reason).mutate()
|
|
48
80
|
|
|
49
|
-
def mutate(self):
|
|
81
|
+
def mutate(self) -> Dataset:
|
|
82
|
+
"""Mutate the dataset.
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
Dataset
|
|
87
|
+
The mutated dataset.
|
|
88
|
+
"""
|
|
50
89
|
return self.forward.swap_with_parent(parent=self)
|
|
51
90
|
|
|
52
91
|
@debug_indexing
|
|
53
92
|
@expand_list_indexing
|
|
54
|
-
def _get_tuple(self, index):
|
|
93
|
+
def _get_tuple(self, index: TupleIndex) -> NDArray[Any]:
|
|
94
|
+
"""Get a tuple of data.
|
|
95
|
+
|
|
96
|
+
Parameters
|
|
97
|
+
----------
|
|
98
|
+
index : TupleIndex
|
|
99
|
+
The index to retrieve.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
NDArray[Any]
|
|
104
|
+
The retrieved data.
|
|
105
|
+
"""
|
|
55
106
|
index, changes = index_to_slices(index, self.shape)
|
|
56
107
|
index, previous = update_tuple(index, 1, slice(None))
|
|
57
108
|
result = self.dataset[index]
|
|
@@ -61,7 +112,19 @@ class Select(Forwards):
|
|
|
61
112
|
return result
|
|
62
113
|
|
|
63
114
|
@debug_indexing
|
|
64
|
-
def __getitem__(self, n):
|
|
115
|
+
def __getitem__(self, n: FullIndex) -> NDArray[Any]:
|
|
116
|
+
"""Get an item from the dataset.
|
|
117
|
+
|
|
118
|
+
Parameters
|
|
119
|
+
----------
|
|
120
|
+
n : FullIndex
|
|
121
|
+
The index to retrieve.
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
NDArray[Any]
|
|
126
|
+
The retrieved data.
|
|
127
|
+
"""
|
|
65
128
|
if isinstance(n, tuple):
|
|
66
129
|
return self._get_tuple(n)
|
|
67
130
|
|
|
@@ -72,46 +135,112 @@ class Select(Forwards):
|
|
|
72
135
|
return row[self.indices]
|
|
73
136
|
|
|
74
137
|
@cached_property
|
|
75
|
-
def shape(self):
|
|
138
|
+
def shape(self) -> Shape:
|
|
139
|
+
"""Get the shape of the dataset."""
|
|
76
140
|
return (len(self), len(self.indices)) + self.dataset.shape[2:]
|
|
77
141
|
|
|
78
142
|
@cached_property
|
|
79
|
-
def variables(self):
|
|
143
|
+
def variables(self) -> List[str]:
|
|
144
|
+
"""Get the variables of the dataset."""
|
|
80
145
|
return [self.dataset.variables[i] for i in self.indices]
|
|
81
146
|
|
|
82
147
|
@cached_property
|
|
83
|
-
def variables_metadata(self):
|
|
148
|
+
def variables_metadata(self) -> Dict[str, Any]:
|
|
149
|
+
"""Get the metadata of the variables."""
|
|
84
150
|
return {k: v for k, v in self.dataset.variables_metadata.items() if k in self.variables}
|
|
85
151
|
|
|
86
152
|
@cached_property
|
|
87
|
-
def name_to_index(self):
|
|
153
|
+
def name_to_index(self) -> Dict[str, int]:
|
|
154
|
+
"""Get the mapping of variable names to indices."""
|
|
88
155
|
return {k: i for i, k in enumerate(self.variables)}
|
|
89
156
|
|
|
90
157
|
@cached_property
|
|
91
|
-
def statistics(self):
|
|
158
|
+
def statistics(self) -> Dict[str, NDArray[Any]]:
|
|
159
|
+
"""Get the statistics of the dataset."""
|
|
92
160
|
return {k: v[self.indices] for k, v in self.dataset.statistics.items()}
|
|
93
161
|
|
|
94
|
-
def statistics_tendencies(self, delta=None):
|
|
162
|
+
def statistics_tendencies(self, delta: Optional[datetime.timedelta] = None) -> Dict[str, NDArray[Any]]:
|
|
163
|
+
"""Get the statistical tendencies of the dataset.
|
|
164
|
+
|
|
165
|
+
Parameters
|
|
166
|
+
----------
|
|
167
|
+
delta : Optional[datetime.timedelta]
|
|
168
|
+
The time delta for the tendencies.
|
|
169
|
+
|
|
170
|
+
Returns
|
|
171
|
+
-------
|
|
172
|
+
Dict[str, NDArray[Any]]
|
|
173
|
+
The statistical tendencies.
|
|
174
|
+
"""
|
|
95
175
|
if delta is None:
|
|
96
176
|
delta = self.frequency
|
|
97
177
|
return {k: v[self.indices] for k, v in self.dataset.statistics_tendencies(delta).items()}
|
|
98
178
|
|
|
99
|
-
def metadata_specific(self, **kwargs):
|
|
179
|
+
def metadata_specific(self, **kwargs: Any) -> Dict[str, Any]:
|
|
180
|
+
"""Get the specific metadata of the dataset.
|
|
181
|
+
|
|
182
|
+
Parameters
|
|
183
|
+
----------
|
|
184
|
+
**kwargs : Any
|
|
185
|
+
Additional keyword arguments.
|
|
186
|
+
|
|
187
|
+
Returns
|
|
188
|
+
-------
|
|
189
|
+
Dict[str, Any]
|
|
190
|
+
The specific metadata.
|
|
191
|
+
"""
|
|
100
192
|
return super().metadata_specific(indices=self.indices, **kwargs)
|
|
101
193
|
|
|
102
|
-
def source(self, index):
|
|
194
|
+
def source(self, index: int) -> Source:
|
|
195
|
+
"""Get the source of the dataset.
|
|
196
|
+
|
|
197
|
+
Parameters
|
|
198
|
+
----------
|
|
199
|
+
index : int
|
|
200
|
+
The index of the source.
|
|
201
|
+
|
|
202
|
+
Returns
|
|
203
|
+
-------
|
|
204
|
+
Source
|
|
205
|
+
The source of the dataset.
|
|
206
|
+
"""
|
|
103
207
|
return Source(self, index, self.dataset.source(self.indices[index]))
|
|
104
208
|
|
|
105
|
-
def tree(self):
|
|
209
|
+
def tree(self) -> Node:
|
|
210
|
+
"""Get the tree representation of the dataset.
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
Node
|
|
215
|
+
The tree representation of the dataset.
|
|
216
|
+
"""
|
|
106
217
|
return Node(self, [self.dataset.tree()], **self.reason)
|
|
107
218
|
|
|
108
|
-
def
|
|
219
|
+
def forwards_subclass_metadata_specific(self) -> Dict[str, Any]:
|
|
220
|
+
"""Get the metadata specific to the subclass.
|
|
221
|
+
|
|
222
|
+
Returns
|
|
223
|
+
-------
|
|
224
|
+
Dict[str, Any]
|
|
225
|
+
The metadata specific to the subclass.
|
|
226
|
+
"""
|
|
109
227
|
# return dict(indices=self.indices)
|
|
110
228
|
return dict(reason=self.reason)
|
|
111
229
|
|
|
112
230
|
|
|
113
231
|
class Rename(Forwards):
|
|
114
|
-
|
|
232
|
+
"""Class to rename variables in a dataset."""
|
|
233
|
+
|
|
234
|
+
def __init__(self, dataset: Dataset, rename: Dict[str, str]) -> None:
|
|
235
|
+
"""Initialize the Rename class.
|
|
236
|
+
|
|
237
|
+
Parameters
|
|
238
|
+
----------
|
|
239
|
+
dataset : Dataset
|
|
240
|
+
The dataset to rename.
|
|
241
|
+
rename : Dict[str, str]
|
|
242
|
+
The mapping of old names to new names.
|
|
243
|
+
"""
|
|
115
244
|
super().__init__(dataset)
|
|
116
245
|
for n in rename:
|
|
117
246
|
assert n in dataset.variables, n
|
|
@@ -122,19 +251,32 @@ class Rename(Forwards):
|
|
|
122
251
|
self.rename = rename
|
|
123
252
|
|
|
124
253
|
@property
|
|
125
|
-
def variables(self):
|
|
254
|
+
def variables(self) -> List[str]:
|
|
255
|
+
"""Get the renamed variables."""
|
|
126
256
|
return self._variables
|
|
127
257
|
|
|
128
258
|
@property
|
|
129
|
-
def variables_metadata(self):
|
|
259
|
+
def variables_metadata(self) -> Dict[str, Any]:
|
|
260
|
+
"""Get the renamed variables metadata."""
|
|
130
261
|
return self._variables_metadata
|
|
131
262
|
|
|
132
263
|
@cached_property
|
|
133
|
-
def name_to_index(self):
|
|
264
|
+
def name_to_index(self) -> Dict[str, int]:
|
|
265
|
+
"""Get the mapping of renamed variable names to indices."""
|
|
134
266
|
return {k: i for i, k in enumerate(self.variables)}
|
|
135
267
|
|
|
136
|
-
def tree(self):
|
|
268
|
+
def tree(self) -> Node:
|
|
269
|
+
"""Get the tree representation of the dataset.
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
Node: The tree representation of the dataset.
|
|
273
|
+
"""
|
|
137
274
|
return Node(self, [self.forward.tree()], rename=self.rename)
|
|
138
275
|
|
|
139
|
-
def
|
|
276
|
+
def forwards_subclass_metadata_specific(self) -> Dict[str, Any]:
|
|
277
|
+
"""Get the metadata specific to the subclass.
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
Dict[str, Any]: The metadata specific to the subclass.
|
|
281
|
+
"""
|
|
140
282
|
return dict(rename=self.rename)
|
|
@@ -8,10 +8,18 @@
|
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
import datetime
|
|
11
12
|
import logging
|
|
12
13
|
from functools import cached_property
|
|
14
|
+
from typing import Any
|
|
15
|
+
from typing import Dict
|
|
16
|
+
from typing import Optional
|
|
17
|
+
from typing import Set
|
|
18
|
+
|
|
19
|
+
from numpy.typing import NDArray
|
|
13
20
|
|
|
14
21
|
from . import open_dataset
|
|
22
|
+
from .dataset import Dataset
|
|
15
23
|
from .debug import Node
|
|
16
24
|
from .forwards import Forwards
|
|
17
25
|
|
|
@@ -19,7 +27,26 @@ LOG = logging.getLogger(__name__)
|
|
|
19
27
|
|
|
20
28
|
|
|
21
29
|
class Statistics(Forwards):
|
|
22
|
-
|
|
30
|
+
"""A class to represent statistics for a dataset.
|
|
31
|
+
|
|
32
|
+
Attributes
|
|
33
|
+
----------
|
|
34
|
+
dataset : Dataset
|
|
35
|
+
The dataset object.
|
|
36
|
+
statistic : Any
|
|
37
|
+
The statistic data.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, dataset: Dataset, statistic: Any) -> None:
|
|
41
|
+
"""Initialize the Statistics object.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
dataset : Dataset
|
|
46
|
+
The dataset object.
|
|
47
|
+
statistic : Any
|
|
48
|
+
The statistic data.
|
|
49
|
+
"""
|
|
23
50
|
super().__init__(dataset)
|
|
24
51
|
self._statistic = open_dataset(statistic, select=dataset.variables)
|
|
25
52
|
# TODO: relax that check to allow for a subset of variables
|
|
@@ -29,20 +56,54 @@ class Statistics(Forwards):
|
|
|
29
56
|
)
|
|
30
57
|
|
|
31
58
|
@cached_property
|
|
32
|
-
def statistics(self):
|
|
59
|
+
def statistics(self) -> Dict[str, NDArray[Any]]:
|
|
60
|
+
"""Get the statistics."""
|
|
33
61
|
return self._statistic.statistics
|
|
34
62
|
|
|
35
|
-
def statistics_tendencies(self, delta=None):
|
|
63
|
+
def statistics_tendencies(self, delta: Optional[datetime.timedelta] = None) -> Dict[str, NDArray[Any]]:
|
|
64
|
+
"""Get the statistics tendencies.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
delta : Optional[datetime.timedelta]
|
|
69
|
+
The time delta.
|
|
70
|
+
|
|
71
|
+
Returns
|
|
72
|
+
-------
|
|
73
|
+
Dict[str, NDArray[Any]]
|
|
74
|
+
The statistics tendencies.
|
|
75
|
+
"""
|
|
36
76
|
if delta is None:
|
|
37
77
|
delta = self.frequency
|
|
38
78
|
return self._statistic.statistics_tendencies(delta)
|
|
39
79
|
|
|
40
|
-
def
|
|
80
|
+
def forwards_subclass_metadata_specific(self) -> Dict[str, Any]:
|
|
81
|
+
"""Get the metadata specific to the forwards subclass.
|
|
82
|
+
|
|
83
|
+
Returns
|
|
84
|
+
-------
|
|
85
|
+
Dict[str, Any]
|
|
86
|
+
The metadata specific to the forwards subclass.
|
|
87
|
+
"""
|
|
41
88
|
return dict(statistics=self._statistic.metadata_specific())
|
|
42
89
|
|
|
43
|
-
def tree(self):
|
|
90
|
+
def tree(self) -> Node:
|
|
91
|
+
"""Get the tree representation of the statistics.
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
Node
|
|
96
|
+
The tree representation of the statistics.
|
|
97
|
+
"""
|
|
44
98
|
return Node(self, [self.forward.tree()])
|
|
45
99
|
|
|
46
|
-
def get_dataset_names(self, names):
|
|
100
|
+
def get_dataset_names(self, names: Set[str]) -> None:
|
|
101
|
+
"""Get the dataset names.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
names : Set[str]
|
|
106
|
+
The set of dataset names.
|
|
107
|
+
"""
|
|
47
108
|
super().get_dataset_names(names)
|
|
48
109
|
self._statistic.get_dataset_names(names)
|