anemoi-datasets 0.5.16__py3-none-any.whl → 0.5.18__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.
Files changed (155) hide show
  1. anemoi/datasets/__init__.py +4 -1
  2. anemoi/datasets/__main__.py +12 -2
  3. anemoi/datasets/_version.py +9 -4
  4. anemoi/datasets/commands/cleanup.py +17 -2
  5. anemoi/datasets/commands/compare.py +18 -2
  6. anemoi/datasets/commands/copy.py +196 -14
  7. anemoi/datasets/commands/create.py +50 -7
  8. anemoi/datasets/commands/finalise-additions.py +17 -2
  9. anemoi/datasets/commands/finalise.py +17 -2
  10. anemoi/datasets/commands/init-additions.py +17 -2
  11. anemoi/datasets/commands/init.py +16 -2
  12. anemoi/datasets/commands/inspect.py +283 -62
  13. anemoi/datasets/commands/load-additions.py +16 -2
  14. anemoi/datasets/commands/load.py +16 -2
  15. anemoi/datasets/commands/patch.py +17 -2
  16. anemoi/datasets/commands/publish.py +17 -2
  17. anemoi/datasets/commands/scan.py +31 -3
  18. anemoi/datasets/compute/recentre.py +47 -11
  19. anemoi/datasets/create/__init__.py +612 -85
  20. anemoi/datasets/create/check.py +142 -20
  21. anemoi/datasets/create/chunks.py +64 -4
  22. anemoi/datasets/create/config.py +185 -21
  23. anemoi/datasets/create/filter.py +50 -0
  24. anemoi/datasets/create/filters/__init__.py +33 -0
  25. anemoi/datasets/create/filters/empty.py +37 -0
  26. anemoi/datasets/create/filters/legacy.py +93 -0
  27. anemoi/datasets/create/filters/noop.py +37 -0
  28. anemoi/datasets/create/filters/orog_to_z.py +58 -0
  29. anemoi/datasets/create/{functions/filters → filters}/pressure_level_relative_humidity_to_specific_humidity.py +33 -10
  30. anemoi/datasets/create/{functions/filters → filters}/pressure_level_specific_humidity_to_relative_humidity.py +32 -8
  31. anemoi/datasets/create/filters/rename.py +205 -0
  32. anemoi/datasets/create/{functions/filters → filters}/rotate_winds.py +43 -28
  33. anemoi/datasets/create/{functions/filters → filters}/single_level_dewpoint_to_relative_humidity.py +32 -9
  34. anemoi/datasets/create/{functions/filters → filters}/single_level_relative_humidity_to_dewpoint.py +33 -9
  35. anemoi/datasets/create/{functions/filters → filters}/single_level_relative_humidity_to_specific_humidity.py +55 -7
  36. anemoi/datasets/create/{functions/filters → filters}/single_level_specific_humidity_to_relative_humidity.py +98 -37
  37. anemoi/datasets/create/filters/speeddir_to_uv.py +95 -0
  38. anemoi/datasets/create/{functions/filters → filters}/sum.py +24 -27
  39. anemoi/datasets/create/filters/transform.py +53 -0
  40. anemoi/datasets/create/{functions/filters → filters}/unrotate_winds.py +27 -18
  41. anemoi/datasets/create/filters/uv_to_speeddir.py +94 -0
  42. anemoi/datasets/create/{functions/filters → filters}/wz_to_w.py +51 -33
  43. anemoi/datasets/create/input/__init__.py +76 -5
  44. anemoi/datasets/create/input/action.py +149 -13
  45. anemoi/datasets/create/input/concat.py +81 -10
  46. anemoi/datasets/create/input/context.py +39 -4
  47. anemoi/datasets/create/input/data_sources.py +72 -6
  48. anemoi/datasets/create/input/empty.py +21 -3
  49. anemoi/datasets/create/input/filter.py +60 -12
  50. anemoi/datasets/create/input/function.py +154 -37
  51. anemoi/datasets/create/input/join.py +86 -14
  52. anemoi/datasets/create/input/misc.py +67 -17
  53. anemoi/datasets/create/input/pipe.py +33 -6
  54. anemoi/datasets/create/input/repeated_dates.py +189 -41
  55. anemoi/datasets/create/input/result.py +202 -87
  56. anemoi/datasets/create/input/step.py +119 -22
  57. anemoi/datasets/create/input/template.py +100 -13
  58. anemoi/datasets/create/input/trace.py +62 -7
  59. anemoi/datasets/create/patch.py +52 -4
  60. anemoi/datasets/create/persistent.py +134 -17
  61. anemoi/datasets/create/size.py +15 -1
  62. anemoi/datasets/create/source.py +51 -0
  63. anemoi/datasets/create/sources/__init__.py +36 -0
  64. anemoi/datasets/create/{functions/sources → sources}/accumulations.py +296 -30
  65. anemoi/datasets/create/{functions/sources → sources}/constants.py +27 -2
  66. anemoi/datasets/create/{functions/sources → sources}/eccc_fstd.py +7 -3
  67. anemoi/datasets/create/sources/empty.py +37 -0
  68. anemoi/datasets/create/{functions/sources → sources}/forcings.py +25 -1
  69. anemoi/datasets/create/sources/grib.py +297 -0
  70. anemoi/datasets/create/{functions/sources → sources}/hindcasts.py +38 -4
  71. anemoi/datasets/create/sources/legacy.py +93 -0
  72. anemoi/datasets/create/{functions/sources → sources}/mars.py +168 -20
  73. anemoi/datasets/create/sources/netcdf.py +42 -0
  74. anemoi/datasets/create/sources/opendap.py +43 -0
  75. anemoi/datasets/create/{functions/sources/__init__.py → sources/patterns.py} +35 -4
  76. anemoi/datasets/create/sources/recentre.py +150 -0
  77. anemoi/datasets/create/{functions/sources → sources}/source.py +27 -5
  78. anemoi/datasets/create/{functions/sources → sources}/tendencies.py +64 -7
  79. anemoi/datasets/create/sources/xarray.py +92 -0
  80. anemoi/datasets/create/sources/xarray_kerchunk.py +36 -0
  81. anemoi/datasets/create/sources/xarray_support/README.md +1 -0
  82. anemoi/datasets/create/{functions/sources/xarray → sources/xarray_support}/__init__.py +109 -8
  83. anemoi/datasets/create/sources/xarray_support/coordinates.py +442 -0
  84. anemoi/datasets/create/{functions/sources/xarray → sources/xarray_support}/field.py +94 -16
  85. anemoi/datasets/create/{functions/sources/xarray → sources/xarray_support}/fieldlist.py +90 -25
  86. anemoi/datasets/create/sources/xarray_support/flavour.py +1036 -0
  87. anemoi/datasets/create/{functions/sources/xarray → sources/xarray_support}/grid.py +92 -31
  88. anemoi/datasets/create/sources/xarray_support/metadata.py +395 -0
  89. anemoi/datasets/create/sources/xarray_support/patch.py +91 -0
  90. anemoi/datasets/create/sources/xarray_support/time.py +391 -0
  91. anemoi/datasets/create/sources/xarray_support/variable.py +331 -0
  92. anemoi/datasets/create/sources/xarray_zarr.py +41 -0
  93. anemoi/datasets/create/{functions/sources → sources}/zenodo.py +34 -5
  94. anemoi/datasets/create/statistics/__init__.py +233 -44
  95. anemoi/datasets/create/statistics/summary.py +52 -6
  96. anemoi/datasets/create/testing.py +76 -0
  97. anemoi/datasets/create/{functions/filters/noop.py → typing.py} +6 -3
  98. anemoi/datasets/create/utils.py +97 -6
  99. anemoi/datasets/create/writer.py +26 -4
  100. anemoi/datasets/create/zarr.py +170 -23
  101. anemoi/datasets/data/__init__.py +51 -4
  102. anemoi/datasets/data/complement.py +191 -40
  103. anemoi/datasets/data/concat.py +141 -16
  104. anemoi/datasets/data/dataset.py +558 -62
  105. anemoi/datasets/data/debug.py +197 -26
  106. anemoi/datasets/data/ensemble.py +93 -8
  107. anemoi/datasets/data/fill_missing.py +165 -18
  108. anemoi/datasets/data/forwards.py +428 -56
  109. anemoi/datasets/data/grids.py +323 -97
  110. anemoi/datasets/data/indexing.py +112 -19
  111. anemoi/datasets/data/interpolate.py +92 -12
  112. anemoi/datasets/data/join.py +158 -19
  113. anemoi/datasets/data/masked.py +129 -15
  114. anemoi/datasets/data/merge.py +137 -23
  115. anemoi/datasets/data/misc.py +172 -16
  116. anemoi/datasets/data/missing.py +233 -29
  117. anemoi/datasets/data/rescale.py +111 -10
  118. anemoi/datasets/data/select.py +168 -26
  119. anemoi/datasets/data/statistics.py +67 -6
  120. anemoi/datasets/data/stores.py +149 -64
  121. anemoi/datasets/data/subset.py +159 -25
  122. anemoi/datasets/data/unchecked.py +168 -57
  123. anemoi/datasets/data/xy.py +168 -25
  124. anemoi/datasets/dates/__init__.py +191 -16
  125. anemoi/datasets/dates/groups.py +189 -47
  126. anemoi/datasets/grids.py +270 -31
  127. anemoi/datasets/testing.py +28 -1
  128. {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.18.dist-info}/METADATA +9 -6
  129. anemoi_datasets-0.5.18.dist-info/RECORD +137 -0
  130. {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.18.dist-info}/WHEEL +1 -1
  131. anemoi/datasets/create/functions/__init__.py +0 -66
  132. anemoi/datasets/create/functions/filters/__init__.py +0 -9
  133. anemoi/datasets/create/functions/filters/empty.py +0 -17
  134. anemoi/datasets/create/functions/filters/orog_to_z.py +0 -58
  135. anemoi/datasets/create/functions/filters/rename.py +0 -79
  136. anemoi/datasets/create/functions/filters/speeddir_to_uv.py +0 -78
  137. anemoi/datasets/create/functions/filters/uv_to_speeddir.py +0 -56
  138. anemoi/datasets/create/functions/sources/empty.py +0 -15
  139. anemoi/datasets/create/functions/sources/grib.py +0 -150
  140. anemoi/datasets/create/functions/sources/netcdf.py +0 -15
  141. anemoi/datasets/create/functions/sources/opendap.py +0 -15
  142. anemoi/datasets/create/functions/sources/recentre.py +0 -60
  143. anemoi/datasets/create/functions/sources/xarray/coordinates.py +0 -255
  144. anemoi/datasets/create/functions/sources/xarray/flavour.py +0 -472
  145. anemoi/datasets/create/functions/sources/xarray/metadata.py +0 -148
  146. anemoi/datasets/create/functions/sources/xarray/patch.py +0 -44
  147. anemoi/datasets/create/functions/sources/xarray/time.py +0 -177
  148. anemoi/datasets/create/functions/sources/xarray/variable.py +0 -188
  149. anemoi/datasets/create/functions/sources/xarray_kerchunk.py +0 -42
  150. anemoi/datasets/create/functions/sources/xarray_zarr.py +0 -15
  151. anemoi/datasets/utils/fields.py +0 -47
  152. anemoi_datasets-0.5.16.dist-info/RECORD +0 -129
  153. {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.18.dist-info}/entry_points.txt +0 -0
  154. {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.18.dist-info/licenses}/LICENSE +0 -0
  155. {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.18.dist-info}/top_level.txt +0 -0
@@ -10,7 +10,14 @@
10
10
 
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 Set
17
+ from typing import Tuple
18
+
19
+ from .dataset import Dataset
20
+ from .dataset import FullIndex
14
21
  from .debug import Node
15
22
  from .forwards import Combined
16
23
  from .misc import _auto_adjust
@@ -20,94 +27,217 @@ LOG = logging.getLogger(__name__)
20
27
 
21
28
 
22
29
  class ZipBase(Combined):
23
-
24
- def __init__(self, datasets, check_compatibility=True):
30
+ """Base class for handling zipped datasets."""
31
+
32
+ def __init__(self, datasets: List[Any], check_compatibility: bool = True) -> None:
33
+ """Initialize ZipBase with a list of datasets.
34
+
35
+ Parameters
36
+ ----------
37
+ datasets : List[Any]
38
+ List of datasets.
39
+ check_compatibility : bool, optional
40
+ Flag to check compatibility of datasets, by default True.
41
+ """
25
42
  self._check_compatibility = check_compatibility
26
43
  super().__init__(datasets)
27
44
 
28
- def swap_with_parent(self, parent):
45
+ def swap_with_parent(self, parent: Any) -> Any:
46
+ """Swap datasets with the parent.
47
+
48
+ Parameters
49
+ ----------
50
+ parent : Any
51
+ Parent dataset.
52
+
53
+ Returns
54
+ -------
55
+ Any
56
+ New parent dataset with swapped datasets.
57
+ """
29
58
  new_parents = [parent.clone(ds) for ds in self.datasets]
30
59
  return self.clone(new_parents)
31
60
 
32
- def clone(self, datasets):
61
+ def clone(self, datasets: List[Any]) -> "ZipBase":
62
+ """Clone the ZipBase with new datasets.
63
+
64
+ Parameters
65
+ ----------
66
+ datasets : List[Any]
67
+ List of new datasets.
68
+
69
+ Returns
70
+ -------
71
+ ZipBase
72
+ Cloned ZipBase instance.
73
+ """
33
74
  return self.__class__(datasets, check_compatibility=self._check_compatibility)
34
75
 
35
- def tree(self):
76
+ def tree(self) -> Node:
77
+ """Get the tree representation of the datasets.
78
+
79
+ Returns
80
+ -------
81
+ Node
82
+ Tree representation of the datasets.
83
+ """
36
84
  return Node(self, [d.tree() for d in self.datasets], check_compatibility=self._check_compatibility)
37
85
 
38
- def __len__(self):
86
+ def __len__(self) -> int:
87
+ """Get the length of the smallest dataset.
88
+
89
+ Returns
90
+ -------
91
+ int
92
+ Length of the smallest dataset.
93
+ """
39
94
  return min(len(d) for d in self.datasets)
40
95
 
41
- def __getitem__(self, n):
96
+ def __getitem__(self, n: FullIndex) -> Tuple[Any, ...]:
97
+ """Get the item at the specified index from all datasets.
98
+
99
+ Parameters
100
+ ----------
101
+ n : FullIndex
102
+ Index to retrieve.
103
+
104
+ Returns
105
+ -------
106
+ Tuple[Any, ...]
107
+ Tuple of items from all datasets.
108
+ """
42
109
  return tuple(d[n] for d in self.datasets)
43
110
 
44
- def check_same_resolution(self, d1, d2):
111
+ def check_same_resolution(self, d1: Dataset, d2: Dataset) -> None:
112
+ """Check if two datasets have the same resolution.
113
+
114
+ Parameters
115
+ ----------
116
+ d1 : Dataset
117
+ First dataset.
118
+ d2 : Dataset
119
+ Second dataset.
120
+ """
45
121
  pass
46
122
 
47
- def check_same_grid(self, d1, d2):
123
+ def check_same_grid(self, d1: Dataset, d2: Dataset) -> None:
124
+ """Check if two datasets have the same grid.
125
+
126
+ Parameters
127
+ ----------
128
+ d1 : Dataset
129
+ First dataset.
130
+ d2 : Dataset
131
+ Second dataset.
132
+ """
48
133
  pass
49
134
 
50
- def check_same_variables(self, d1, d2):
135
+ def check_same_variables(self, d1: Dataset, d2: Dataset) -> None:
136
+ """Check if two datasets have the same variables.
137
+
138
+ Parameters
139
+ ----------
140
+ d1 : Dataset
141
+ First dataset.
142
+ d2 : Dataset
143
+ Second dataset.
144
+ """
51
145
  pass
52
146
 
53
147
  @cached_property
54
- def missing(self):
55
- result = set()
148
+ def missing(self) -> Set[int]:
149
+ """Get the set of missing indices from all datasets."""
150
+ result: Set[int] = set()
56
151
  for d in self.datasets:
57
152
  result = result | d.missing
58
153
  return result
59
154
 
60
155
  @property
61
- def shape(self):
156
+ def shape(self) -> Tuple[Any, ...]:
157
+ """Get the shape of all datasets."""
62
158
  return tuple(d.shape for d in self.datasets)
63
159
 
64
160
  @property
65
- def field_shape(self):
161
+ def field_shape(self) -> Tuple[Any, ...]:
162
+ """Get the field shape of all datasets."""
66
163
  return tuple(d.shape for d in self.datasets)
67
164
 
68
165
  @property
69
- def latitudes(self):
166
+ def latitudes(self) -> Tuple[Any, ...]:
167
+ """Get the latitudes of all datasets."""
70
168
  return tuple(d.latitudes for d in self.datasets)
71
169
 
72
170
  @property
73
- def longitudes(self):
171
+ def longitudes(self) -> Tuple[Any, ...]:
172
+ """Get the longitudes of all datasets."""
74
173
  return tuple(d.longitudes for d in self.datasets)
75
174
 
76
175
  @property
77
- def dtype(self):
176
+ def dtype(self) -> Tuple[Any, ...]:
177
+ """Get the data types of all datasets."""
78
178
  return tuple(d.dtype for d in self.datasets)
79
179
 
80
180
  @property
81
- def grids(self):
181
+ def grids(self) -> Tuple[Any, ...]:
182
+ """Get the grids of all datasets."""
82
183
  return tuple(d.grids for d in self.datasets)
83
184
 
84
185
  @property
85
- def statistics(self):
186
+ def statistics(self) -> Tuple[Any, ...]:
187
+ """Get the statistics of all datasets."""
86
188
  return tuple(d.statistics for d in self.datasets)
87
189
 
88
190
  @property
89
- def resolution(self):
191
+ def resolution(self) -> Tuple[Any, ...]:
192
+ """Get the resolution of all datasets."""
90
193
  return tuple(d.resolution for d in self.datasets)
91
194
 
92
195
  @property
93
- def name_to_index(self):
196
+ def name_to_index(self) -> Tuple[Any, ...]:
197
+ """Get the name to index mapping of all datasets."""
94
198
  return tuple(d.name_to_index for d in self.datasets)
95
199
 
96
- def check_compatibility(self, d1, d2):
200
+ def check_compatibility(self, d1: Dataset, d2: Dataset) -> None:
201
+ """Check compatibility between two datasets.
202
+
203
+ Parameters
204
+ ----------
205
+ d1 : Dataset
206
+ First dataset.
207
+ d2 : Dataset
208
+ Second dataset.
209
+ """
97
210
  if self._check_compatibility:
98
211
  super().check_compatibility(d1, d2)
99
212
 
100
213
 
101
214
  class Zip(ZipBase):
215
+ """Class for handling zipped datasets."""
216
+
102
217
  pass
103
218
 
104
219
 
105
220
  class XY(ZipBase):
221
+ """Class for handling XY datasets."""
222
+
106
223
  pass
107
224
 
108
225
 
109
- def xy_factory(args, kwargs):
226
+ def xy_factory(args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> XY:
227
+ """Factory function to create an XY instance.
110
228
 
229
+ Parameters
230
+ ----------
231
+ args : Tuple[Any, ...]
232
+ Positional arguments.
233
+ kwargs : Dict[str, Any]
234
+ Keyword arguments.
235
+
236
+ Returns
237
+ -------
238
+ XY
239
+ An instance of XY.
240
+ """
111
241
  if "xy" in kwargs:
112
242
  xy = kwargs.pop("xy")
113
243
  else:
@@ -126,8 +256,21 @@ def xy_factory(args, kwargs):
126
256
  return XY(datasets, check_compatibility=check_compatibility)._subset(**kwargs)
127
257
 
128
258
 
129
- def zip_factory(args, kwargs):
259
+ def zip_factory(args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Zip:
260
+ """Factory function to create a Zip instance.
261
+
262
+ Parameters
263
+ ----------
264
+ args : Tuple[Any, ...]
265
+ Positional arguments.
266
+ kwargs : Dict[str, Any]
267
+ Keyword arguments.
130
268
 
269
+ Returns
270
+ -------
271
+ Zip
272
+ An instance of Zip.
273
+ """
131
274
  zip = kwargs.pop("zip")
132
275
  assert len(args) == 0
133
276
  assert isinstance(zip, (list, tuple))
@@ -12,6 +12,13 @@ import datetime
12
12
  import warnings
13
13
  from functools import reduce
14
14
  from math import gcd
15
+ from typing import Any
16
+ from typing import Dict
17
+ from typing import Iterator
18
+ from typing import List
19
+ from typing import Optional
20
+ from typing import Tuple
21
+ from typing import Union
15
22
 
16
23
  # from anemoi.utils.dates import as_datetime
17
24
  from anemoi.utils.dates import DateTimes
@@ -22,7 +29,17 @@ from anemoi.utils.hindcasts import HindcastDatesTimes
22
29
  from anemoi.utils.humanize import print_dates
23
30
 
24
31
 
25
- def extend(x):
32
+ def extend(x: Union[str, List[Any], Tuple[Any, ...]]) -> Iterator[datetime.datetime]:
33
+ """Extend a date range or list of dates into individual datetime objects.
34
+
35
+ Args:
36
+ x (Union[str, List[Any], Tuple[Any, ...]]): A date range string or list/tuple of dates.
37
+
38
+ Returns
39
+ -------
40
+ Iterator[datetime.datetime]
41
+ An iterator of datetime objects.
42
+ """
26
43
 
27
44
  if isinstance(x, (list, tuple)):
28
45
  for y in x:
@@ -69,7 +86,14 @@ class DatesProvider:
69
86
  3
70
87
  """
71
88
 
72
- def __init__(self, missing=None):
89
+ def __init__(self, missing: Optional[List[Union[str, datetime.datetime]]] = None) -> None:
90
+ """Initialize the DatesProvider with optional missing dates.
91
+
92
+ Parameters
93
+ ----------
94
+ missing : Optional[List[Union[str, datetime.datetime]]]
95
+ List of missing dates.
96
+ """
73
97
  if not missing:
74
98
  missing = []
75
99
  self.missing = list(extend(missing))
@@ -78,8 +102,17 @@ class DatesProvider:
78
102
  warnings.warn(f"Missing dates {len(diff)=} not in list.")
79
103
 
80
104
  @classmethod
81
- def from_config(cls, **kwargs):
105
+ def from_config(cls, **kwargs: Any) -> "DatesProvider":
106
+ """Create a DatesProvider instance from configuration.
107
+
108
+ Args:
109
+ **kwargs (Any): Configuration parameters.
82
110
 
111
+ Returns
112
+ -------
113
+ DatesProvider
114
+ An instance of DatesProvider.
115
+ """
83
116
  if kwargs.pop("hindcasts", False):
84
117
  return HindcastsDates(**kwargs)
85
118
 
@@ -88,35 +121,113 @@ class DatesProvider:
88
121
 
89
122
  return StartEndDates(**kwargs)
90
123
 
91
- def __iter__(self):
124
+ def __iter__(self) -> Iterator[datetime.datetime]:
125
+ """Iterate over the dates.
126
+
127
+ Yields
128
+ ------
129
+ Iterator[datetime.datetime]
130
+ An iterator of datetime objects.
131
+ """
92
132
  yield from self.values
93
133
 
94
- def __getitem__(self, i):
134
+ def __getitem__(self, i: int) -> datetime.datetime:
135
+ """Get a date by index.
136
+
137
+ Args:
138
+ i (int): Index of the date.
139
+
140
+ Returns
141
+ -------
142
+ datetime.datetime
143
+ The date at the specified index.
144
+ """
95
145
  return self.values[i]
96
146
 
97
- def __len__(self):
147
+ def __len__(self) -> int:
148
+ """Get the number of dates.
149
+
150
+ Returns
151
+ -------
152
+ int
153
+ The number of dates.
154
+ """
98
155
  return len(self.values)
99
156
 
100
157
  @property
101
- def summary(self):
158
+ def summary(self) -> str:
159
+ """Get a summary of the date range."""
102
160
  return f"📅 {self.values[0]} ... {self.values[-1]}"
103
161
 
104
162
 
105
163
  class ValuesDates(DatesProvider):
106
- def __init__(self, values, **kwargs):
164
+ """Class for handling a list of date values.
165
+
166
+ Args:
167
+ values (List[Union[str, datetime.datetime]]): List of date values.
168
+ **kwargs (Any): Additional arguments.
169
+ """
170
+
171
+ def __init__(self, values: List[Union[str, datetime.datetime]], **kwargs: Any) -> None:
172
+ """Initialize ValuesDates with a list of values.
173
+
174
+ Args:
175
+ values (List[Union[str, datetime.datetime]]): List of date values.
176
+ **kwargs (Any): Additional arguments.
177
+ """
107
178
  self.values = sorted([as_datetime(_) for _ in values])
108
179
  super().__init__(**kwargs)
109
180
 
110
- def __repr__(self):
181
+ def __repr__(self) -> str:
182
+ """Get a string representation of the ValuesDates instance.
183
+
184
+ Returns
185
+ -------
186
+ str
187
+ String representation of the instance.
188
+ """
111
189
  return f"{self.__class__.__name__}({self.values[0]}..{self.values[-1]})"
112
190
 
113
- def as_dict(self):
191
+ def as_dict(self) -> Dict[str, Any]:
192
+ """Convert the ValuesDates instance to a dictionary.
193
+
194
+ Returns
195
+ -------
196
+ Dict[str, Any]
197
+ Dictionary representation of the instance.
198
+ """
114
199
  return {"values": self.values[0]}
115
200
 
116
201
 
117
202
  class StartEndDates(DatesProvider):
118
- def __init__(self, start, end, frequency=1, **kwargs):
203
+ """Class for generating dates between a start and end date with a specified frequency.
119
204
 
205
+ Args:
206
+ start (Union[str, datetime.datetime]): Start date.
207
+ end (Union[str, datetime.datetime]): End date.
208
+ frequency (Union[int, str]): Frequency of dates.
209
+ **kwargs (Any): Additional arguments.
210
+ """
211
+
212
+ def __repr__(self) -> str:
213
+ """Get a string representation of the StartEndDates instance."""
214
+ return f"{self.__class__.__name__}({self.start}..{self.end} every {self.frequency})"
215
+
216
+ def __init__(
217
+ self,
218
+ start: Union[str, datetime.datetime],
219
+ end: Union[str, datetime.datetime],
220
+ frequency: Union[int, str] = 1,
221
+ **kwargs: Any,
222
+ ) -> None:
223
+ """Initialize StartEndDates with start, end, and frequency.
224
+
225
+ Args:
226
+ start (Union[str, datetime.datetime]): Start date.
227
+ end (Union[str, datetime.datetime]): End date.
228
+ frequency (Union[int, str]): Frequency of dates.
229
+ **kwargs (Any): Additional arguments.
230
+ """
120
231
  frequency = frequency_to_timedelta(frequency)
121
232
  assert isinstance(frequency, datetime.timedelta), frequency
122
233
 
@@ -148,7 +259,14 @@ class StartEndDates(DatesProvider):
148
259
 
149
260
  super().__init__(missing=missing)
150
261
 
151
- def as_dict(self):
262
+ def as_dict(self) -> Dict[str, Any]:
263
+ """Convert the StartEndDates instance to a dictionary.
264
+
265
+ Returns
266
+ -------
267
+ Dict[str, Any]
268
+ Dictionary representation of the instance.
269
+ """
152
270
  return {
153
271
  "start": self.start.isoformat(),
154
272
  "end": self.end.isoformat(),
@@ -157,8 +275,26 @@ class StartEndDates(DatesProvider):
157
275
 
158
276
 
159
277
  class Hindcast:
278
+ """Class representing a single hindcast date.
160
279
 
161
- def __init__(self, date, refdate, hdate, step):
280
+ Args:
281
+ date (datetime.datetime): The date of the hindcast.
282
+ refdate (datetime.datetime): The reference date.
283
+ hdate (datetime.datetime): The hindcast date.
284
+ step (int): The step value.
285
+ """
286
+
287
+ def __init__(
288
+ self, date: datetime.datetime, refdate: datetime.datetime, hdate: datetime.datetime, step: int
289
+ ) -> None:
290
+ """Initialize a Hindcast instance.
291
+
292
+ Args:
293
+ date (datetime.datetime): The date of the hindcast.
294
+ refdate (datetime.datetime): The reference date.
295
+ hdate (datetime.datetime): The hindcast date.
296
+ step (int): The step value.
297
+ """
162
298
  self.date = date
163
299
  self.refdate = refdate
164
300
  self.hdate = hdate
@@ -166,8 +302,33 @@ class Hindcast:
166
302
 
167
303
 
168
304
  class HindcastsDates(DatesProvider):
169
- def __init__(self, start, end, steps=[0], years=20, **kwargs):
305
+ """Class for generating hindcast dates over a range of years.
306
+
307
+ Args:
308
+ start (Union[str, List[str]]): Start date(s).
309
+ end (Union[str, List[str]]): End date(s).
310
+ steps (List[int]): List of step values.
311
+ years (int): Number of years.
312
+ **kwargs (Any): Additional arguments.
313
+ """
170
314
 
315
+ def __init__(
316
+ self,
317
+ start: Union[str, List[str]],
318
+ end: Union[str, List[str]],
319
+ steps: List[int] = [0],
320
+ years: int = 20,
321
+ **kwargs: Any,
322
+ ) -> None:
323
+ """Initialize HindcastsDates with start, end, steps, and years.
324
+
325
+ Args:
326
+ start (Union[str, List[str]]): Start date(s).
327
+ end (Union[str, List[str]]): End date(s).
328
+ steps (List[int]): List of step values.
329
+ years (int): Number of years.
330
+ **kwargs (Any): Additional arguments.
331
+ """
171
332
  if not isinstance(start, list):
172
333
  start = [start]
173
334
  end = [end]
@@ -232,10 +393,24 @@ class HindcastsDates(DatesProvider):
232
393
 
233
394
  super().__init__(missing=missing)
234
395
 
235
- def __repr__(self):
396
+ def __repr__(self) -> str:
397
+ """Get a string representation of the HindcastsDates instance.
398
+
399
+ Returns
400
+ -------
401
+ str
402
+ String representation of the instance.
403
+ """
236
404
  return f"{self.__class__.__name__}({self.values[0]}..{self.values[-1]})"
237
405
 
238
- def as_dict(self):
406
+ def as_dict(self) -> Dict[str, Any]:
407
+ """Convert the HindcastsDates instance to a dictionary.
408
+
409
+ Returns
410
+ -------
411
+ Dict[str, Any]
412
+ Dictionary representation of the instance.
413
+ """
239
414
  return {"hindcasts": self.hindcasts}
240
415
 
241
416