anemoi-datasets 0.5.7__py3-none-any.whl → 0.5.11__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 +62 -12
  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 -11
  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 +8 -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 -3
  54. anemoi/datasets/create/functions/sources/xarray/coordinates.py +3 -2
  55. anemoi/datasets/create/functions/sources/xarray/field.py +6 -5
  56. anemoi/datasets/create/functions/sources/xarray/fieldlist.py +12 -4
  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 -9
  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 -8
  67. anemoi/datasets/create/input/concat.py +3 -2
  68. anemoi/datasets/create/input/context.py +3 -8
  69. anemoi/datasets/create/input/data_sources.py +3 -9
  70. anemoi/datasets/create/input/empty.py +3 -9
  71. anemoi/datasets/create/input/filter.py +3 -9
  72. anemoi/datasets/create/input/function.py +3 -9
  73. anemoi/datasets/create/input/join.py +3 -2
  74. anemoi/datasets/create/input/misc.py +3 -8
  75. anemoi/datasets/create/input/pipe.py +9 -3
  76. anemoi/datasets/create/input/repeated_dates.py +14 -8
  77. anemoi/datasets/create/input/result.py +154 -12
  78. anemoi/datasets/create/input/step.py +4 -9
  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 +4 -2
  113. anemoi/datasets/grids.py +86 -2
  114. anemoi/datasets/testing.py +3 -2
  115. anemoi/datasets/utils/__init__.py +8 -0
  116. anemoi/datasets/utils/fields.py +2 -2
  117. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.11.dist-info}/METADATA +11 -29
  118. anemoi_datasets-0.5.11.dist-info/RECORD +123 -0
  119. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.11.dist-info}/WHEEL +1 -1
  120. anemoi/datasets/fields.py +0 -66
  121. anemoi_datasets-0.5.7.dist-info/RECORD +0 -122
  122. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.11.dist-info}/LICENSE +0 -0
  123. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.11.dist-info}/entry_points.txt +0 -0
  124. {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.11.dist-info}/top_level.txt +0 -0
@@ -1,21 +1,15 @@
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 functools import cached_property
11
12
 
12
- from anemoi.utils.dates import as_datetime as as_datetime
13
- from anemoi.utils.dates import frequency_to_timedelta as frequency_to_timedelta
14
-
15
- from anemoi.datasets.dates import DatesProvider as DatesProvider
16
- from anemoi.datasets.fields import FieldArray as FieldArray
17
- from anemoi.datasets.fields import NewValidDateTimeField as NewValidDateTimeField
18
-
19
13
  from .action import Action
20
14
  from .action import action_factory
21
15
  from .misc import _tidy
@@ -1,21 +1,15 @@
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 functools import cached_property
11
12
 
12
- from anemoi.utils.dates import as_datetime as as_datetime
13
- from anemoi.utils.dates import frequency_to_timedelta as frequency_to_timedelta
14
-
15
- from anemoi.datasets.dates import DatesProvider as DatesProvider
16
- from anemoi.datasets.fields import FieldArray as FieldArray
17
- from anemoi.datasets.fields import NewValidDateTimeField as NewValidDateTimeField
18
-
19
13
  from .misc import assert_fieldlist
20
14
  from .result import Result
21
15
  from .trace import trace_datasource
@@ -1,21 +1,15 @@
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 functools import cached_property
11
12
 
12
- from anemoi.utils.dates import as_datetime as as_datetime
13
- from anemoi.utils.dates import frequency_to_timedelta as frequency_to_timedelta
14
-
15
- from anemoi.datasets.dates import DatesProvider as DatesProvider
16
- from anemoi.datasets.fields import FieldArray as FieldArray
17
- from anemoi.datasets.fields import NewValidDateTimeField as NewValidDateTimeField
18
-
19
13
  from ..functions import import_function
20
14
  from .function import FunctionContext
21
15
  from .misc import _tidy
@@ -1,21 +1,15 @@
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 functools import cached_property
11
12
 
12
- from anemoi.utils.dates import as_datetime as as_datetime
13
- from anemoi.utils.dates import frequency_to_timedelta as frequency_to_timedelta
14
-
15
- from anemoi.datasets.dates import DatesProvider as DatesProvider
16
- from anemoi.datasets.fields import FieldArray as FieldArray
17
- from anemoi.datasets.fields import NewValidDateTimeField as NewValidDateTimeField
18
-
19
13
  from ..functions import import_function
20
14
  from .action import Action
21
15
  from .misc import _tidy
@@ -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 functools import cached_property
11
12
 
@@ -1,23 +1,18 @@
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 functools import wraps
11
12
 
12
- from anemoi.utils.dates import as_datetime as as_datetime
13
- from anemoi.utils.dates import frequency_to_timedelta as frequency_to_timedelta
14
13
  from earthkit.data.core.fieldlist import MultiFieldList
15
14
  from earthkit.data.indexing.fieldlist import FieldList
16
15
 
17
- from anemoi.datasets.dates import DatesProvider as DatesProvider
18
- from anemoi.datasets.fields import FieldArray as FieldArray
19
- from anemoi.datasets.fields import NewValidDateTimeField as NewValidDateTimeField
20
-
21
16
  from ..functions import import_function
22
17
 
23
18
  LOG = logging.getLogger(__name__)
@@ -1,11 +1,13 @@
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
+
10
+ import json
9
11
  import logging
10
12
 
11
13
  from .action import Action
@@ -19,7 +21,11 @@ LOG = logging.getLogger(__name__)
19
21
  class PipeAction(Action):
20
22
  def __init__(self, context, action_path, *configs):
21
23
  super().__init__(context, action_path, *configs)
22
- assert len(configs) > 1, configs
24
+ if len(configs) <= 1:
25
+ raise ValueError(
26
+ f"PipeAction requires at least two actions, got {len(configs)}\n{json.dumps(configs, indent=2)}"
27
+ )
28
+
23
29
  current = action_factory(configs[0], context, action_path + ["0"])
24
30
  for i, c in enumerate(configs[1:]):
25
31
  current = step_factory(c, context, action_path + [str(i + 1)], previous_step=current)
@@ -1,22 +1,22 @@
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
  from collections import defaultdict
12
13
 
13
14
  import numpy as np
15
+ from anemoi.transform.fields import new_field_with_valid_datetime
16
+ from anemoi.transform.fields import new_fieldlist_from_list
14
17
  from anemoi.utils.dates import as_datetime
15
18
  from anemoi.utils.dates import frequency_to_timedelta
16
19
 
17
- from anemoi.datasets.fields import FieldArray
18
- from anemoi.datasets.fields import NewValidDateTimeField
19
-
20
20
  from .action import Action
21
21
  from .action import action_factory
22
22
  from .join import JoinResult
@@ -115,9 +115,10 @@ class DateMapperClosest(DateMapper):
115
115
 
116
116
 
117
117
  class DateMapperClimatology(DateMapper):
118
- def __init__(self, source, year, day):
118
+ def __init__(self, source, year, day, hour=None):
119
119
  self.year = year
120
120
  self.day = day
121
+ self.hour = hour
121
122
 
122
123
  def transform(self, group_of_dates):
123
124
  from anemoi.datasets.dates.groups import GroupOfDates
@@ -129,6 +130,8 @@ class DateMapperClimatology(DateMapper):
129
130
  new_dates = defaultdict(list)
130
131
  for date in dates:
131
132
  new_date = date.replace(year=self.year, day=self.day)
133
+ if self.hour is not None:
134
+ new_date = new_date.replace(hour=self.hour, minute=0, second=0)
132
135
  new_dates[new_date].append(date)
133
136
 
134
137
  for date, dates in new_dates.items():
@@ -184,9 +187,12 @@ class DateMapperResult(Result):
184
187
 
185
188
  for field in self.source_results.datasource:
186
189
  for date in self.original_group_of_dates:
187
- result.append(NewValidDateTimeField(field, date))
190
+ result.append(new_field_with_valid_datetime(field, date))
191
+
192
+ if not result:
193
+ raise ValueError("repeated_dates: no input data found")
188
194
 
189
- return FieldArray(result)
195
+ return new_fieldlist_from_list(result)
190
196
 
191
197
 
192
198
  class RepeatedDatesAction(Action):
@@ -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
@@ -14,16 +15,10 @@ from collections import defaultdict
14
15
  from functools import cached_property
15
16
 
16
17
  import numpy as np
17
- from anemoi.utils.dates import as_datetime as as_datetime
18
- from anemoi.utils.dates import frequency_to_timedelta as frequency_to_timedelta
19
18
  from anemoi.utils.humanize import seconds_to_human
20
19
  from anemoi.utils.humanize import shorten_list
21
20
  from earthkit.data.core.order import build_remapping
22
21
 
23
- from anemoi.datasets.dates import DatesProvider as DatesProvider
24
- from anemoi.datasets.fields import FieldArray as FieldArray
25
- from anemoi.datasets.fields import NewValidDateTimeField as NewValidDateTimeField
26
-
27
22
  from .trace import trace
28
23
  from .trace import trace_datasource
29
24
 
@@ -33,9 +28,61 @@ LOG = logging.getLogger(__name__)
33
28
  def _fields_metatata(variables, cube):
34
29
  assert isinstance(variables, tuple), variables
35
30
 
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])
31
+ KNOWN = {
32
+ "cos_julian_day": dict(computed_forcing=True, constant_in_time=False),
33
+ "cos_latitude": dict(computed_forcing=True, constant_in_time=True),
34
+ "cos_local_time": dict(computed_forcing=True, constant_in_time=False),
35
+ "cos_longitude": dict(computed_forcing=True, constant_in_time=True),
36
+ "cos_solar_zenith_angle": dict(computed_forcing=True, constant_in_time=False),
37
+ "insolation": dict(computed_forcing=True, constant_in_time=False),
38
+ "latitude": dict(computed_forcing=True, constant_in_time=True),
39
+ "longitude": dict(computed_forcing=True, constant_in_time=True),
40
+ "sin_julian_day": dict(computed_forcing=True, constant_in_time=False),
41
+ "sin_latitude": dict(computed_forcing=True, constant_in_time=True),
42
+ "sin_local_time": dict(computed_forcing=True, constant_in_time=False),
43
+ "sin_longitude": dict(computed_forcing=True, constant_in_time=True),
44
+ }
45
+
46
+ def _merge(md1, md2):
47
+ assert set(md1.keys()) == set(md2.keys()), (set(md1.keys()), set(md2.keys()))
48
+ result = {}
49
+ for k in md1.keys():
50
+ v1 = md1[k]
51
+ v2 = md2[k]
52
+
53
+ if v1 == v2:
54
+ result[k] = v1
55
+ continue
56
+
57
+ if isinstance(v1, list):
58
+ assert v2 not in v1, (v1, v2)
59
+ result[k] = sorted(v1 + [v2])
60
+ continue
61
+
62
+ if isinstance(v2, list):
63
+ assert v1 not in v2, (v1, v2)
64
+ result[k] = sorted(v2 + [v1])
65
+ continue
66
+
67
+ result[k] = sorted([v1, v2])
68
+
69
+ return result
70
+
71
+ mars = {}
72
+ other = defaultdict(dict)
73
+ i = -1
74
+ date = None
75
+ for c in cube.iterate_cubelets():
76
+
77
+ if date is None:
78
+ date = c._coords_names[0]
79
+
80
+ if date != c._coords_names[0]:
81
+ continue
82
+
83
+ if i == -1 or c._coords_names[1] != variables[i]:
84
+ i += 1
85
+
39
86
  f = cube[c.coords]
40
87
  md = f.metadata(namespace="mars")
41
88
  if not md:
@@ -49,7 +96,102 @@ def _fields_metatata(variables, cube):
49
96
  md["param"] = str(f.metadata("paramId", default="unknown"))
50
97
  # assert md['param'] != 'unknown', (md, f.metadata('param'))
51
98
 
52
- result[variables[i]] = md
99
+ startStep = f.metadata("startStep", default=None)
100
+ assert startStep is None or isinstance(startStep, int), (startStep, type(f))
101
+
102
+ endStep = f.metadata("endStep", default=None)
103
+ assert endStep is None or isinstance(endStep, int), endStep
104
+
105
+ stepTypeForConversion = f.metadata("stepTypeForConversion", default=None)
106
+ typeOfStatisticalProcessing = f.metadata("typeOfStatisticalProcessing", default=None)
107
+ timeRangeIndicator = f.metadata("timeRangeIndicator", default=None)
108
+
109
+ # GRIB1 precipitation accumulations are not correctly encoded
110
+ if startStep == endStep and stepTypeForConversion == "accum":
111
+ startStep = 0
112
+
113
+ if startStep != endStep:
114
+ # https://codes.ecmwf.int/grib/format/grib2/ctables/4/10/
115
+ TYPE_OF_STATISTICAL_PROCESSING = {
116
+ None: None,
117
+ 0: "average",
118
+ 1: "accumulation",
119
+ 2: "maximum",
120
+ 3: "minimum",
121
+ 4: "difference(end-start)",
122
+ 5: "root_mean_square",
123
+ 6: "standard_deviation",
124
+ 7: "covariance",
125
+ 8: "difference(start-end)",
126
+ 9: "ratio",
127
+ 10: "standardized_anomaly",
128
+ 11: "summation",
129
+ 100: "severity",
130
+ 101: "mode",
131
+ }
132
+
133
+ # https://codes.ecmwf.int/grib/format/grib1/ctable/5/
134
+
135
+ TIME_RANGE_INDICATOR = {
136
+ 4: "accumulation",
137
+ 3: "average",
138
+ }
139
+
140
+ STEP_TYPE_FOR_CONVERSION = {
141
+ "min": "minimum",
142
+ "max": "maximum",
143
+ "accum": "accumulation",
144
+ }
145
+
146
+ #
147
+ # A few patches
148
+ #
149
+
150
+ PATCHES = {
151
+ "10fg6": "maximum",
152
+ "mntpr3": "minimum", # Not in param db
153
+ "mntpr6": "minimum", # Not in param db
154
+ "mxtpr3": "maximum", # Not in param db
155
+ "mxtpr6": "maximum", # Not in param db
156
+ }
157
+
158
+ process = TYPE_OF_STATISTICAL_PROCESSING.get(typeOfStatisticalProcessing)
159
+ if process is None:
160
+ process = TIME_RANGE_INDICATOR.get(timeRangeIndicator)
161
+ if process is None:
162
+ process = STEP_TYPE_FOR_CONVERSION.get(stepTypeForConversion)
163
+ if process is None:
164
+ process = PATCHES.get(md["param"])
165
+ if process is not None:
166
+ LOG.error(f"Unknown process {stepTypeForConversion} for {md['param']}, using {process} instead")
167
+
168
+ if process is None:
169
+ raise ValueError(
170
+ f"Unknown for {md['param']}:"
171
+ f" {stepTypeForConversion=} ({STEP_TYPE_FOR_CONVERSION.get('stepTypeForConversion')}),"
172
+ f" {typeOfStatisticalProcessing=} ({TYPE_OF_STATISTICAL_PROCESSING.get(typeOfStatisticalProcessing)}),"
173
+ f" {timeRangeIndicator=} ({TIME_RANGE_INDICATOR.get(timeRangeIndicator)})"
174
+ )
175
+
176
+ # print(md["param"], "startStep", startStep, "endStep", endStep, "process", process, "typeOfStatisticalProcessing", typeOfStatisticalProcessing)
177
+ other[variables[i]]["process"] = process
178
+ other[variables[i]]["period"] = (startStep, endStep)
179
+
180
+ for k in md.copy().keys():
181
+ if k.startswith("_"):
182
+ md.pop(k)
183
+
184
+ if variables[i] in mars:
185
+ mars[variables[i]] = _merge(md, mars[variables[i]])
186
+ else:
187
+ mars[variables[i]] = md
188
+
189
+ result = {}
190
+ for k, v in mars.items():
191
+ result[k] = dict(mars=v) if v else {}
192
+ result[k].update(other[k])
193
+ result[k].update(KNOWN.get(k, {}))
194
+ assert result[k], k
53
195
 
54
196
  assert i + 1 == len(variables), (i + 1, len(variables))
55
197
  return result
@@ -1,21 +1,15 @@
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
 
12
- from anemoi.utils.dates import as_datetime as as_datetime
13
- from anemoi.utils.dates import frequency_to_timedelta as frequency_to_timedelta
14
-
15
- from anemoi.datasets.dates import DatesProvider as DatesProvider
16
- from anemoi.datasets.fields import FieldArray as FieldArray
17
- from anemoi.datasets.fields import NewValidDateTimeField as NewValidDateTimeField
18
-
19
13
  from .action import Action
20
14
  from .context import Context
21
15
  from .misc import is_function
@@ -59,6 +53,7 @@ class StepAction(Action):
59
53
  )
60
54
 
61
55
  def __repr__(self):
56
+ # raise NotImplementedError(f"Not implemented in {self.__class__.__name__}")
62
57
  return super().__repr__(self.previous_step, _inline_=str(self.kwargs))
63
58
 
64
59
 
@@ -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