anemoi-datasets 0.5.16__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.
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 +552 -61
  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.17.dist-info}/METADATA +9 -6
  129. anemoi_datasets-0.5.17.dist-info/RECORD +137 -0
  130. {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.17.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.17.dist-info}/entry_points.txt +0 -0
  154. {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.17.dist-info/licenses}/LICENSE +0 -0
  155. {anemoi_datasets-0.5.16.dist-info → anemoi_datasets-0.5.17.dist-info}/top_level.txt +0 -0
@@ -10,6 +10,13 @@
10
10
 
11
11
  import logging
12
12
  from collections import defaultdict
13
+ from typing import Any
14
+ from typing import Dict
15
+ from typing import Generator
16
+ from typing import List
17
+ from typing import Optional
18
+ from typing import Set
19
+ from typing import Tuple
13
20
 
14
21
  import numpy as np
15
22
  from anemoi.transform.fields import new_field_with_valid_datetime
@@ -27,11 +34,27 @@ LOG = logging.getLogger(__name__)
27
34
 
28
35
 
29
36
  class DateMapper:
37
+ """A factory class to create DateMapper instances based on the given mode."""
30
38
 
31
39
  @staticmethod
32
- def from_mode(mode, source, config):
33
-
34
- MODES = dict(
40
+ def from_mode(mode: str, source: Any, config: Dict[str, Any]) -> "DateMapper":
41
+ """Create a DateMapper instance based on the given mode.
42
+
43
+ Parameters
44
+ ----------
45
+ mode : str
46
+ The mode to use for the DateMapper.
47
+ source : Any
48
+ The data source.
49
+ config : dict
50
+ Configuration parameters.
51
+
52
+ Returns
53
+ -------
54
+ DateMapper
55
+ An instance of DateMapper.
56
+ """
57
+ MODES: dict = dict(
35
58
  closest=DateMapperClosest,
36
59
  climatology=DateMapperClimatology,
37
60
  constant=DateMapperConstant,
@@ -44,15 +67,42 @@ class DateMapper:
44
67
 
45
68
 
46
69
  class DateMapperClosest(DateMapper):
47
- def __init__(self, source, frequency="1h", maximum="30d", skip_all_nans=False):
48
- self.source = source
49
- self.maximum = frequency_to_timedelta(maximum)
50
- self.frequency = frequency_to_timedelta(frequency)
51
- self.skip_all_nans = skip_all_nans
52
- self.tried = set()
53
- self.found = set()
54
-
55
- def transform(self, group_of_dates):
70
+ """A DateMapper implementation that maps dates to the closest available dates."""
71
+
72
+ def __init__(self, source: Any, frequency: str = "1h", maximum: str = "30d", skip_all_nans: bool = False) -> None:
73
+ """Initialize DateMapperClosest.
74
+
75
+ Parameters
76
+ ----------
77
+ source : Any
78
+ The data source.
79
+ frequency : str
80
+ Frequency of the dates.
81
+ maximum : str
82
+ Maximum time delta.
83
+ skip_all_nans : bool
84
+ Whether to skip all NaN values.
85
+ """
86
+ self.source: Any = source
87
+ self.maximum: Any = frequency_to_timedelta(maximum)
88
+ self.frequency: Any = frequency_to_timedelta(frequency)
89
+ self.skip_all_nans: bool = skip_all_nans
90
+ self.tried: Set[Any] = set()
91
+ self.found: Set[Any] = set()
92
+
93
+ def transform(self, group_of_dates: Any) -> Generator[Tuple[Any, Any], None, None]:
94
+ """Transform the group of dates to the closest available dates.
95
+
96
+ Parameters
97
+ ----------
98
+ group_of_dates : Any
99
+ The group of dates to transform.
100
+
101
+ Returns
102
+ -------
103
+ Generator[Tuple[Any, Any], None, None]
104
+ Transformed dates.
105
+ """
56
106
  from anemoi.datasets.dates.groups import GroupOfDates
57
107
 
58
108
  asked_dates = list(group_of_dates)
@@ -133,12 +183,39 @@ class DateMapperClosest(DateMapper):
133
183
 
134
184
 
135
185
  class DateMapperClimatology(DateMapper):
136
- def __init__(self, source, year, day, hour=None):
137
- self.year = year
138
- self.day = day
139
- self.hour = hour
140
-
141
- def transform(self, group_of_dates):
186
+ """A DateMapper implementation that maps dates to specified climatology dates."""
187
+
188
+ def __init__(self, source: Any, year: int, day: int, hour: Optional[int] = None) -> None:
189
+ """Initialize DateMapperClimatology.
190
+
191
+ Parameters
192
+ ----------
193
+ source : Any
194
+ The data source.
195
+ year : int
196
+ The year to map to.
197
+ day : int
198
+ The day to map to.
199
+ hour : Optional[int]
200
+ The hour to map to.
201
+ """
202
+ self.year: int = year
203
+ self.day: int = day
204
+ self.hour: Optional[int] = hour
205
+
206
+ def transform(self, group_of_dates: Any) -> Generator[Tuple[Any, Any], None, None]:
207
+ """Transform the group of dates to the specified climatology dates.
208
+
209
+ Parameters
210
+ ----------
211
+ group_of_dates : Any
212
+ The group of dates to transform.
213
+
214
+ Returns
215
+ -------
216
+ Generator[Tuple[Any, Any], None, None]
217
+ Transformed dates.
218
+ """
142
219
  from anemoi.datasets.dates.groups import GroupOfDates
143
220
 
144
221
  dates = list(group_of_dates)
@@ -160,11 +237,34 @@ class DateMapperClimatology(DateMapper):
160
237
 
161
238
 
162
239
  class DateMapperConstant(DateMapper):
163
- def __init__(self, source, date=None):
164
- self.source = source
165
- self.date = date
166
-
167
- def transform(self, group_of_dates):
240
+ """A DateMapper implementation that maps dates to a constant date."""
241
+
242
+ def __init__(self, source: Any, date: Optional[Any] = None) -> None:
243
+ """Initialize DateMapperConstant.
244
+
245
+ Parameters
246
+ ----------
247
+ source : Any
248
+ The data source.
249
+ date : Optional[Any]
250
+ The constant date to map to.
251
+ """
252
+ self.source: Any = source
253
+ self.date: Optional[Any] = date
254
+
255
+ def transform(self, group_of_dates: Any) -> Tuple[Any, Any]:
256
+ """Transform the group of dates to a constant date.
257
+
258
+ Parameters
259
+ ----------
260
+ group_of_dates : Any
261
+ The group of dates to transform.
262
+
263
+ Returns
264
+ -------
265
+ Tuple[Any, Any]
266
+ Transformed dates.
267
+ """
168
268
  from anemoi.datasets.dates.groups import GroupOfDates
169
269
 
170
270
  if self.date is None:
@@ -184,24 +284,44 @@ class DateMapperConstant(DateMapper):
184
284
 
185
285
 
186
286
  class DateMapperResult(Result):
287
+ """A Result implementation that updates the valid datetime of the datasource."""
288
+
187
289
  def __init__(
188
290
  self,
189
- context,
190
- action_path,
191
- group_of_dates,
192
- source_result,
193
- mapper,
194
- original_group_of_dates,
195
- ):
291
+ context: Any,
292
+ action_path: List[str],
293
+ group_of_dates: Any,
294
+ source_result: Any,
295
+ mapper: DateMapper,
296
+ original_group_of_dates: Any,
297
+ ) -> None:
298
+ """Initialize DateMapperResult.
299
+
300
+ Parameters
301
+ ----------
302
+ context : Any
303
+ The context.
304
+ action_path : list of str
305
+ The action path.
306
+ group_of_dates : Any
307
+ The group of dates.
308
+ source_result : Any
309
+ The source result.
310
+ mapper : DateMapper
311
+ The date mapper.
312
+ original_group_of_dates : Any
313
+ The original group of dates.
314
+ """
196
315
  super().__init__(context, action_path, group_of_dates)
197
316
 
198
- self.source_results = source_result
199
- self.mapper = mapper
200
- self.original_group_of_dates = original_group_of_dates
317
+ self.source_results: Any = source_result
318
+ self.mapper: DateMapper = mapper
319
+ self.original_group_of_dates: Any = original_group_of_dates
201
320
 
202
321
  @property
203
- def datasource(self):
204
- result = []
322
+ def datasource(self) -> Any:
323
+ """Get the datasource with updated valid datetime."""
324
+ result: list = []
205
325
 
206
326
  for field in self.source_results.datasource:
207
327
  for date in self.original_group_of_dates:
@@ -214,15 +334,36 @@ class DateMapperResult(Result):
214
334
 
215
335
 
216
336
  class RepeatedDatesAction(Action):
217
- def __init__(self, context, action_path, source, mode, **kwargs):
337
+ """An Action implementation that selects and transforms a group of dates."""
338
+
339
+ def __init__(self, context: Any, action_path: List[str], source: Any, mode: str, **kwargs: Any) -> None:
340
+ """Initialize RepeatedDatesAction.
341
+
342
+ Args:
343
+ context (Any): The context.
344
+ action_path (List[str]): The action path.
345
+ source (Any): The data source.
346
+ mode (str): The mode for date mapping.
347
+ **kwargs (Any): Additional arguments.
348
+ """
218
349
  super().__init__(context, action_path, source, mode, **kwargs)
219
350
 
220
- self.source = action_factory(source, context, action_path + ["source"])
221
- self.mapper = DateMapper.from_mode(mode, self.source, kwargs)
351
+ self.source: Any = action_factory(source, context, action_path + ["source"])
352
+ self.mapper: DateMapper = DateMapper.from_mode(mode, self.source, kwargs)
222
353
 
223
354
  @trace_select
224
- def select(self, group_of_dates):
225
- results = []
355
+ def select(self, group_of_dates: Any) -> JoinResult:
356
+ """Select and transform the group of dates.
357
+
358
+ Args:
359
+ group_of_dates (Any): The group of dates to select.
360
+
361
+ Returns
362
+ -------
363
+ JoinResult
364
+ The result of the join operation.
365
+ """
366
+ results: list = []
226
367
  for one_date_group, many_dates_group in self.mapper.transform(group_of_dates):
227
368
  results.append(
228
369
  DateMapperResult(
@@ -237,5 +378,12 @@ class RepeatedDatesAction(Action):
237
378
 
238
379
  return JoinResult(self.context, self.action_path, group_of_dates, results)
239
380
 
240
- def __repr__(self):
381
+ def __repr__(self) -> str:
382
+ """Get the string representation of the action.
383
+
384
+ Returns
385
+ -------
386
+ str
387
+ The string representation.
388
+ """
241
389
  return f"MultiDateMatchAction({self.source}, {self.mapper})"