anemoi-datasets 0.5.7__py3-none-any.whl → 0.5.10__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 (124) hide show
  1. anemoi/datasets/__init__.py +11 -3
  2. anemoi/datasets/__main__.py +2 -3
  3. anemoi/datasets/_version.py +2 -2
  4. anemoi/datasets/commands/__init__.py +2 -3
  5. anemoi/datasets/commands/cleanup.py +9 -0
  6. anemoi/datasets/commands/compare.py +3 -3
  7. anemoi/datasets/commands/copy.py +38 -68
  8. anemoi/datasets/commands/create.py +20 -5
  9. anemoi/datasets/commands/finalise-additions.py +9 -0
  10. anemoi/datasets/commands/finalise.py +9 -0
  11. anemoi/datasets/commands/init-additions.py +9 -0
  12. anemoi/datasets/commands/init.py +9 -0
  13. anemoi/datasets/commands/inspect.py +3 -1
  14. anemoi/datasets/commands/load-additions.py +9 -0
  15. anemoi/datasets/commands/load.py +9 -0
  16. anemoi/datasets/commands/patch.py +9 -0
  17. anemoi/datasets/commands/publish.py +9 -0
  18. anemoi/datasets/commands/scan.py +9 -0
  19. anemoi/datasets/compute/__init__.py +8 -0
  20. anemoi/datasets/compute/recentre.py +3 -2
  21. anemoi/datasets/create/__init__.py +61 -10
  22. anemoi/datasets/create/check.py +4 -3
  23. anemoi/datasets/create/chunks.py +3 -2
  24. anemoi/datasets/create/config.py +5 -5
  25. anemoi/datasets/create/functions/__init__.py +22 -7
  26. anemoi/datasets/create/functions/filters/__init__.py +2 -1
  27. anemoi/datasets/create/functions/filters/empty.py +3 -2
  28. anemoi/datasets/create/functions/filters/noop.py +2 -2
  29. anemoi/datasets/create/functions/filters/pressure_level_relative_humidity_to_specific_humidity.py +3 -2
  30. anemoi/datasets/create/functions/filters/pressure_level_specific_humidity_to_relative_humidity.py +3 -2
  31. anemoi/datasets/create/functions/filters/rename.py +16 -10
  32. anemoi/datasets/create/functions/filters/rotate_winds.py +3 -2
  33. anemoi/datasets/create/functions/filters/single_level_dewpoint_to_relative_humidity.py +3 -2
  34. anemoi/datasets/create/functions/filters/single_level_relative_humidity_to_dewpoint.py +3 -2
  35. anemoi/datasets/create/functions/filters/single_level_relative_humidity_to_specific_humidity.py +2 -2
  36. anemoi/datasets/create/functions/filters/single_level_specific_humidity_to_relative_humidity.py +2 -2
  37. anemoi/datasets/create/functions/filters/speeddir_to_uv.py +3 -2
  38. anemoi/datasets/create/functions/filters/unrotate_winds.py +3 -2
  39. anemoi/datasets/create/functions/filters/uv_to_speeddir.py +3 -2
  40. anemoi/datasets/create/functions/sources/__init__.py +2 -2
  41. anemoi/datasets/create/functions/sources/accumulations.py +10 -4
  42. anemoi/datasets/create/functions/sources/constants.py +3 -2
  43. anemoi/datasets/create/functions/sources/empty.py +3 -2
  44. anemoi/datasets/create/functions/sources/forcings.py +3 -2
  45. anemoi/datasets/create/functions/sources/grib.py +2 -2
  46. anemoi/datasets/create/functions/sources/hindcasts.py +3 -2
  47. anemoi/datasets/create/functions/sources/mars.py +97 -17
  48. anemoi/datasets/create/functions/sources/netcdf.py +3 -2
  49. anemoi/datasets/create/functions/sources/opendap.py +2 -2
  50. anemoi/datasets/create/functions/sources/recentre.py +3 -2
  51. anemoi/datasets/create/functions/sources/source.py +3 -2
  52. anemoi/datasets/create/functions/sources/tendencies.py +3 -2
  53. anemoi/datasets/create/functions/sources/xarray/__init__.py +8 -2
  54. anemoi/datasets/create/functions/sources/xarray/coordinates.py +3 -2
  55. anemoi/datasets/create/functions/sources/xarray/field.py +3 -2
  56. anemoi/datasets/create/functions/sources/xarray/fieldlist.py +12 -2
  57. anemoi/datasets/create/functions/sources/xarray/flavour.py +2 -2
  58. anemoi/datasets/create/functions/sources/xarray/grid.py +2 -2
  59. anemoi/datasets/create/functions/sources/xarray/metadata.py +3 -2
  60. anemoi/datasets/create/functions/sources/xarray/time.py +2 -2
  61. anemoi/datasets/create/functions/sources/xarray/variable.py +6 -6
  62. anemoi/datasets/create/functions/sources/xarray_kerchunk.py +2 -2
  63. anemoi/datasets/create/functions/sources/xarray_zarr.py +2 -2
  64. anemoi/datasets/create/functions/sources/zenodo.py +2 -2
  65. anemoi/datasets/create/input/__init__.py +3 -17
  66. anemoi/datasets/create/input/action.py +3 -2
  67. anemoi/datasets/create/input/concat.py +3 -2
  68. anemoi/datasets/create/input/context.py +3 -2
  69. anemoi/datasets/create/input/data_sources.py +3 -2
  70. anemoi/datasets/create/input/empty.py +3 -2
  71. anemoi/datasets/create/input/filter.py +3 -2
  72. anemoi/datasets/create/input/function.py +3 -2
  73. anemoi/datasets/create/input/join.py +3 -2
  74. anemoi/datasets/create/input/misc.py +3 -2
  75. anemoi/datasets/create/input/pipe.py +3 -2
  76. anemoi/datasets/create/input/repeated_dates.py +3 -2
  77. anemoi/datasets/create/input/result.py +154 -6
  78. anemoi/datasets/create/input/step.py +4 -2
  79. anemoi/datasets/create/input/template.py +3 -2
  80. anemoi/datasets/create/input/trace.py +3 -2
  81. anemoi/datasets/create/patch.py +9 -1
  82. anemoi/datasets/create/persistent.py +3 -2
  83. anemoi/datasets/create/size.py +3 -2
  84. anemoi/datasets/create/statistics/__init__.py +3 -2
  85. anemoi/datasets/create/statistics/summary.py +3 -2
  86. anemoi/datasets/create/utils.py +15 -2
  87. anemoi/datasets/create/writer.py +3 -2
  88. anemoi/datasets/create/zarr.py +3 -2
  89. anemoi/datasets/data/__init__.py +27 -1
  90. anemoi/datasets/data/concat.py +5 -1
  91. anemoi/datasets/data/dataset.py +216 -37
  92. anemoi/datasets/data/debug.py +4 -1
  93. anemoi/datasets/data/ensemble.py +4 -1
  94. anemoi/datasets/data/fill_missing.py +165 -0
  95. anemoi/datasets/data/forwards.py +23 -1
  96. anemoi/datasets/data/grids.py +236 -58
  97. anemoi/datasets/data/indexing.py +4 -1
  98. anemoi/datasets/data/interpolate.py +4 -1
  99. anemoi/datasets/data/join.py +12 -9
  100. anemoi/datasets/data/masked.py +36 -10
  101. anemoi/datasets/data/merge.py +180 -0
  102. anemoi/datasets/data/misc.py +18 -3
  103. anemoi/datasets/data/missing.py +4 -1
  104. anemoi/datasets/data/rescale.py +4 -1
  105. anemoi/datasets/data/select.py +4 -1
  106. anemoi/datasets/data/statistics.py +4 -1
  107. anemoi/datasets/data/stores.py +66 -3
  108. anemoi/datasets/data/subset.py +6 -1
  109. anemoi/datasets/data/unchecked.py +4 -1
  110. anemoi/datasets/data/xy.py +20 -5
  111. anemoi/datasets/dates/__init__.py +9 -7
  112. anemoi/datasets/dates/groups.py +3 -1
  113. anemoi/datasets/fields.py +3 -1
  114. anemoi/datasets/grids.py +86 -2
  115. anemoi/datasets/testing.py +3 -2
  116. anemoi/datasets/utils/__init__.py +8 -0
  117. anemoi/datasets/utils/fields.py +2 -2
  118. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/METADATA +11 -29
  119. anemoi_datasets-0.5.10.dist-info/RECORD +124 -0
  120. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/WHEEL +1 -1
  121. anemoi_datasets-0.5.7.dist-info/RECORD +0 -122
  122. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/LICENSE +0 -0
  123. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/entry_points.txt +0 -0
  124. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2024 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
  import itertools
10
11
  import logging
11
12
  import math
@@ -33,9 +34,61 @@ LOG = logging.getLogger(__name__)
33
34
  def _fields_metatata(variables, cube):
34
35
  assert isinstance(variables, tuple), variables
35
36
 
36
- result = {}
37
- for i, c in enumerate(cube.iterate_cubelets()):
38
- assert c._coords_names[1] == variables[i], (c._coords_names[1], variables[i])
37
+ KNOWN = {
38
+ "cos_julian_day": dict(computed_forcing=True, constant_in_time=False),
39
+ "cos_latitude": dict(computed_forcing=True, constant_in_time=True),
40
+ "cos_local_time": dict(computed_forcing=True, constant_in_time=False),
41
+ "cos_longitude": dict(computed_forcing=True, constant_in_time=True),
42
+ "cos_solar_zenith_angle": dict(computed_forcing=True, constant_in_time=False),
43
+ "insolation": dict(computed_forcing=True, constant_in_time=False),
44
+ "latitude": dict(computed_forcing=True, constant_in_time=True),
45
+ "longitude": dict(computed_forcing=True, constant_in_time=True),
46
+ "sin_julian_day": dict(computed_forcing=True, constant_in_time=False),
47
+ "sin_latitude": dict(computed_forcing=True, constant_in_time=True),
48
+ "sin_local_time": dict(computed_forcing=True, constant_in_time=False),
49
+ "sin_longitude": dict(computed_forcing=True, constant_in_time=True),
50
+ }
51
+
52
+ def _merge(md1, md2):
53
+ assert set(md1.keys()) == set(md2.keys()), (set(md1.keys()), set(md2.keys()))
54
+ result = {}
55
+ for k in md1.keys():
56
+ v1 = md1[k]
57
+ v2 = md2[k]
58
+
59
+ if v1 == v2:
60
+ result[k] = v1
61
+ continue
62
+
63
+ if isinstance(v1, list):
64
+ assert v2 not in v1, (v1, v2)
65
+ result[k] = sorted(v1 + [v2])
66
+ continue
67
+
68
+ if isinstance(v2, list):
69
+ assert v1 not in v2, (v1, v2)
70
+ result[k] = sorted(v2 + [v1])
71
+ continue
72
+
73
+ result[k] = sorted([v1, v2])
74
+
75
+ return result
76
+
77
+ mars = {}
78
+ other = defaultdict(dict)
79
+ i = -1
80
+ date = None
81
+ for c in cube.iterate_cubelets():
82
+
83
+ if date is None:
84
+ date = c._coords_names[0]
85
+
86
+ if date != c._coords_names[0]:
87
+ continue
88
+
89
+ if i == -1 or c._coords_names[1] != variables[i]:
90
+ i += 1
91
+
39
92
  f = cube[c.coords]
40
93
  md = f.metadata(namespace="mars")
41
94
  if not md:
@@ -49,7 +102,102 @@ def _fields_metatata(variables, cube):
49
102
  md["param"] = str(f.metadata("paramId", default="unknown"))
50
103
  # assert md['param'] != 'unknown', (md, f.metadata('param'))
51
104
 
52
- result[variables[i]] = md
105
+ startStep = f.metadata("startStep", default=None)
106
+ assert startStep is None or isinstance(startStep, int), (startStep, type(f))
107
+
108
+ endStep = f.metadata("endStep", default=None)
109
+ assert endStep is None or isinstance(endStep, int), endStep
110
+
111
+ stepTypeForConversion = f.metadata("stepTypeForConversion", default=None)
112
+ typeOfStatisticalProcessing = f.metadata("typeOfStatisticalProcessing", default=None)
113
+ timeRangeIndicator = f.metadata("timeRangeIndicator", default=None)
114
+
115
+ # GRIB1 precipitation accumulations are not correctly encoded
116
+ if startStep == endStep and stepTypeForConversion == "accum":
117
+ startStep = 0
118
+
119
+ if startStep != endStep:
120
+ # https://codes.ecmwf.int/grib/format/grib2/ctables/4/10/
121
+ TYPE_OF_STATISTICAL_PROCESSING = {
122
+ None: None,
123
+ 0: "average",
124
+ 1: "accumulation",
125
+ 2: "maximum",
126
+ 3: "minimum",
127
+ 4: "difference(end-start)",
128
+ 5: "root_mean_square",
129
+ 6: "standard_deviation",
130
+ 7: "covariance",
131
+ 8: "difference(start-end)",
132
+ 9: "ratio",
133
+ 10: "standardized_anomaly",
134
+ 11: "summation",
135
+ 100: "severity",
136
+ 101: "mode",
137
+ }
138
+
139
+ # https://codes.ecmwf.int/grib/format/grib1/ctable/5/
140
+
141
+ TIME_RANGE_INDICATOR = {
142
+ 4: "accumulation",
143
+ 3: "average",
144
+ }
145
+
146
+ STEP_TYPE_FOR_CONVERSION = {
147
+ "min": "minimum",
148
+ "max": "maximum",
149
+ "accum": "accumulation",
150
+ }
151
+
152
+ #
153
+ # A few patches
154
+ #
155
+
156
+ PATCHES = {
157
+ "10fg6": "maximum",
158
+ "mntpr3": "minimum", # Not in param db
159
+ "mntpr6": "minimum", # Not in param db
160
+ "mxtpr3": "maximum", # Not in param db
161
+ "mxtpr6": "maximum", # Not in param db
162
+ }
163
+
164
+ process = TYPE_OF_STATISTICAL_PROCESSING.get(typeOfStatisticalProcessing)
165
+ if process is None:
166
+ process = TIME_RANGE_INDICATOR.get(timeRangeIndicator)
167
+ if process is None:
168
+ process = STEP_TYPE_FOR_CONVERSION.get(stepTypeForConversion)
169
+ if process is None:
170
+ process = PATCHES.get(md["param"])
171
+ if process is not None:
172
+ LOG.error(f"Unknown process {stepTypeForConversion} for {md['param']}, using {process} instead")
173
+
174
+ if process is None:
175
+ raise ValueError(
176
+ f"Unknown for {md['param']}:"
177
+ f" {stepTypeForConversion=} ({STEP_TYPE_FOR_CONVERSION.get('stepTypeForConversion')}),"
178
+ f" {typeOfStatisticalProcessing=} ({TYPE_OF_STATISTICAL_PROCESSING.get(typeOfStatisticalProcessing)}),"
179
+ f" {timeRangeIndicator=} ({TIME_RANGE_INDICATOR.get(timeRangeIndicator)})"
180
+ )
181
+
182
+ # print(md["param"], "startStep", startStep, "endStep", endStep, "process", process, "typeOfStatisticalProcessing", typeOfStatisticalProcessing)
183
+ other[variables[i]]["process"] = process
184
+ other[variables[i]]["period"] = (startStep, endStep)
185
+
186
+ for k in md.copy().keys():
187
+ if k.startswith("_"):
188
+ md.pop(k)
189
+
190
+ if variables[i] in mars:
191
+ mars[variables[i]] = _merge(md, mars[variables[i]])
192
+ else:
193
+ mars[variables[i]] = md
194
+
195
+ result = {}
196
+ for k, v in mars.items():
197
+ result[k] = dict(mars=v) if v else {}
198
+ result[k].update(other[k])
199
+ result[k].update(KNOWN.get(k, {}))
200
+ assert result[k], k
53
201
 
54
202
  assert i + 1 == len(variables), (i + 1, len(variables))
55
203
  return result
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2024 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
  import logging
10
11
  from copy import deepcopy
11
12
 
@@ -59,6 +60,7 @@ class StepAction(Action):
59
60
  )
60
61
 
61
62
  def __repr__(self):
63
+ # raise NotImplementedError(f"Not implemented in {self.__class__.__name__}")
62
64
  return super().__repr__(self.previous_step, _inline_=str(self.kwargs))
63
65
 
64
66
 
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2023 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
 
10
11
  import logging
11
12
  import re
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2024 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
 
10
11
  import logging
11
12
  import textwrap
@@ -1,4 +1,12 @@
1
- #!/usr/bin/env python3
1
+ # (C) Copyright 2024 Anemoi contributors.
2
+ #
3
+ # This software is licensed under the terms of the Apache Licence Version 2.0
4
+ # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
6
+ # In applying this licence, ECMWF does not waive the privileges and immunities
7
+ # granted to it by virtue of its status as an intergovernmental organisation
8
+ # nor does it submit to any jurisdiction.
9
+
2
10
  import json
3
11
  import logging
4
12
  import os
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2023 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
 
10
11
  import glob
11
12
  import hashlib
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2023 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
 
10
11
  import logging
11
12
  import os
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2024 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
  import datetime
10
11
  import glob
11
12
  import hashlib
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2024 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
  import json
10
11
  from collections import defaultdict
11
12
 
@@ -1,14 +1,16 @@
1
- # (C) Copyright 2023 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
 
10
11
  import datetime
11
12
  import os
13
+ import warnings
12
14
  from contextlib import contextmanager
13
15
 
14
16
  import numpy as np
@@ -31,12 +33,23 @@ def cache_context(dirname):
31
33
  def to_datetime_list(*args, **kwargs):
32
34
  from earthkit.data.utils.dates import to_datetime_list as to_datetime_list_
33
35
 
36
+ warnings.warn(
37
+ "to_datetime_list() is deprecated. Call earthkit.data.utils.dates.to_datetime_list() instead.",
38
+ DeprecationWarning,
39
+ stacklevel=2,
40
+ )
34
41
  return to_datetime_list_(*args, **kwargs)
35
42
 
36
43
 
37
44
  def to_datetime(*args, **kwargs):
38
45
  from earthkit.data.utils.dates import to_datetime as to_datetime_
39
46
 
47
+ warnings.warn(
48
+ "to_datetime() is deprecated. Call earthkit.data.utils.dates.to_datetime() instead.",
49
+ DeprecationWarning,
50
+ stacklevel=2,
51
+ )
52
+
40
53
  return to_datetime_(*args, **kwargs)
41
54
 
42
55
 
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2023 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
 
10
11
  import logging
11
12
 
@@ -1,11 +1,12 @@
1
- # (C) Copyright 2023 ECMWF.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
2
  #
3
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
4
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
5
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
6
7
  # granted to it by virtue of its status as an intergovernmental organisation
7
8
  # nor does it submit to any jurisdiction.
8
- #
9
+
9
10
  import datetime
10
11
  import logging
11
12
  import shutil
@@ -1,6 +1,8 @@
1
- # (C) Copyright 2023 European Centre for Medium-Range Weather Forecasts.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
+ #
2
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
3
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
4
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
5
7
  # granted to it by virtue of its status as an intergovernmental organisation
6
8
  # nor does it submit to any jurisdiction.
@@ -25,7 +27,31 @@ class MissingDateError(Exception):
25
27
  pass
26
28
 
27
29
 
30
+ def _convert(x):
31
+
32
+ if isinstance(x, list):
33
+ return [_convert(a) for a in x]
34
+
35
+ if isinstance(x, tuple):
36
+ return tuple(_convert(a) for a in x)
37
+
38
+ if isinstance(x, dict):
39
+ return {k: _convert(v) for k, v in x.items()}
40
+
41
+ if x.__class__.__name__ in ("DictConfig", "ListConfig"):
42
+ from omegaconf import OmegaConf
43
+
44
+ return OmegaConf.to_container(x, resolve=True)
45
+
46
+ return x
47
+
48
+
28
49
  def open_dataset(*args, **kwargs):
50
+
51
+ # That will get rid of OmegaConf objects
52
+
53
+ args, kwargs = _convert(args), _convert(kwargs)
54
+
29
55
  ds = _open_dataset(*args, **kwargs)
30
56
  ds = ds.mutate()
31
57
  ds.arguments = {"args": args, "kwargs": kwargs}
@@ -1,10 +1,13 @@
1
- # (C) Copyright 2024 European Centre for Medium-Range Weather Forecasts.
1
+ # (C) Copyright 2024 Anemoi contributors.
2
+ #
2
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
3
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
4
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
5
7
  # granted to it by virtue of its status as an intergovernmental organisation
6
8
  # nor does it submit to any jurisdiction.
7
9
 
10
+
8
11
  import logging
9
12
  from functools import cached_property
10
13
 
@@ -148,6 +151,7 @@ def concat_factory(args, kwargs):
148
151
 
149
152
  datasets = kwargs.pop("concat")
150
153
  fill_missing_gaps = kwargs.pop("fill_missing_gaps", False)
154
+
151
155
  assert isinstance(datasets, (list, tuple))
152
156
  assert len(args) == 0
153
157