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.
- anemoi/datasets/__init__.py +11 -3
- anemoi/datasets/__main__.py +2 -3
- anemoi/datasets/_version.py +2 -2
- anemoi/datasets/commands/__init__.py +2 -3
- anemoi/datasets/commands/cleanup.py +9 -0
- anemoi/datasets/commands/compare.py +3 -3
- anemoi/datasets/commands/copy.py +38 -68
- anemoi/datasets/commands/create.py +20 -5
- anemoi/datasets/commands/finalise-additions.py +9 -0
- anemoi/datasets/commands/finalise.py +9 -0
- anemoi/datasets/commands/init-additions.py +9 -0
- anemoi/datasets/commands/init.py +9 -0
- anemoi/datasets/commands/inspect.py +3 -1
- anemoi/datasets/commands/load-additions.py +9 -0
- anemoi/datasets/commands/load.py +9 -0
- anemoi/datasets/commands/patch.py +9 -0
- anemoi/datasets/commands/publish.py +9 -0
- anemoi/datasets/commands/scan.py +9 -0
- anemoi/datasets/compute/__init__.py +8 -0
- anemoi/datasets/compute/recentre.py +3 -2
- anemoi/datasets/create/__init__.py +61 -10
- anemoi/datasets/create/check.py +4 -3
- anemoi/datasets/create/chunks.py +3 -2
- anemoi/datasets/create/config.py +5 -5
- anemoi/datasets/create/functions/__init__.py +22 -7
- anemoi/datasets/create/functions/filters/__init__.py +2 -1
- anemoi/datasets/create/functions/filters/empty.py +3 -2
- anemoi/datasets/create/functions/filters/noop.py +2 -2
- anemoi/datasets/create/functions/filters/pressure_level_relative_humidity_to_specific_humidity.py +3 -2
- anemoi/datasets/create/functions/filters/pressure_level_specific_humidity_to_relative_humidity.py +3 -2
- anemoi/datasets/create/functions/filters/rename.py +16 -10
- anemoi/datasets/create/functions/filters/rotate_winds.py +3 -2
- anemoi/datasets/create/functions/filters/single_level_dewpoint_to_relative_humidity.py +3 -2
- anemoi/datasets/create/functions/filters/single_level_relative_humidity_to_dewpoint.py +3 -2
- anemoi/datasets/create/functions/filters/single_level_relative_humidity_to_specific_humidity.py +2 -2
- anemoi/datasets/create/functions/filters/single_level_specific_humidity_to_relative_humidity.py +2 -2
- anemoi/datasets/create/functions/filters/speeddir_to_uv.py +3 -2
- anemoi/datasets/create/functions/filters/unrotate_winds.py +3 -2
- anemoi/datasets/create/functions/filters/uv_to_speeddir.py +3 -2
- anemoi/datasets/create/functions/sources/__init__.py +2 -2
- anemoi/datasets/create/functions/sources/accumulations.py +10 -4
- anemoi/datasets/create/functions/sources/constants.py +3 -2
- anemoi/datasets/create/functions/sources/empty.py +3 -2
- anemoi/datasets/create/functions/sources/forcings.py +3 -2
- anemoi/datasets/create/functions/sources/grib.py +2 -2
- anemoi/datasets/create/functions/sources/hindcasts.py +3 -2
- anemoi/datasets/create/functions/sources/mars.py +97 -17
- anemoi/datasets/create/functions/sources/netcdf.py +3 -2
- anemoi/datasets/create/functions/sources/opendap.py +2 -2
- anemoi/datasets/create/functions/sources/recentre.py +3 -2
- anemoi/datasets/create/functions/sources/source.py +3 -2
- anemoi/datasets/create/functions/sources/tendencies.py +3 -2
- anemoi/datasets/create/functions/sources/xarray/__init__.py +8 -2
- anemoi/datasets/create/functions/sources/xarray/coordinates.py +3 -2
- anemoi/datasets/create/functions/sources/xarray/field.py +3 -2
- anemoi/datasets/create/functions/sources/xarray/fieldlist.py +12 -2
- anemoi/datasets/create/functions/sources/xarray/flavour.py +2 -2
- anemoi/datasets/create/functions/sources/xarray/grid.py +2 -2
- anemoi/datasets/create/functions/sources/xarray/metadata.py +3 -2
- anemoi/datasets/create/functions/sources/xarray/time.py +2 -2
- anemoi/datasets/create/functions/sources/xarray/variable.py +6 -6
- anemoi/datasets/create/functions/sources/xarray_kerchunk.py +2 -2
- anemoi/datasets/create/functions/sources/xarray_zarr.py +2 -2
- anemoi/datasets/create/functions/sources/zenodo.py +2 -2
- anemoi/datasets/create/input/__init__.py +3 -17
- anemoi/datasets/create/input/action.py +3 -2
- anemoi/datasets/create/input/concat.py +3 -2
- anemoi/datasets/create/input/context.py +3 -2
- anemoi/datasets/create/input/data_sources.py +3 -2
- anemoi/datasets/create/input/empty.py +3 -2
- anemoi/datasets/create/input/filter.py +3 -2
- anemoi/datasets/create/input/function.py +3 -2
- anemoi/datasets/create/input/join.py +3 -2
- anemoi/datasets/create/input/misc.py +3 -2
- anemoi/datasets/create/input/pipe.py +3 -2
- anemoi/datasets/create/input/repeated_dates.py +3 -2
- anemoi/datasets/create/input/result.py +154 -6
- anemoi/datasets/create/input/step.py +4 -2
- anemoi/datasets/create/input/template.py +3 -2
- anemoi/datasets/create/input/trace.py +3 -2
- anemoi/datasets/create/patch.py +9 -1
- anemoi/datasets/create/persistent.py +3 -2
- anemoi/datasets/create/size.py +3 -2
- anemoi/datasets/create/statistics/__init__.py +3 -2
- anemoi/datasets/create/statistics/summary.py +3 -2
- anemoi/datasets/create/utils.py +15 -2
- anemoi/datasets/create/writer.py +3 -2
- anemoi/datasets/create/zarr.py +3 -2
- anemoi/datasets/data/__init__.py +27 -1
- anemoi/datasets/data/concat.py +5 -1
- anemoi/datasets/data/dataset.py +216 -37
- anemoi/datasets/data/debug.py +4 -1
- anemoi/datasets/data/ensemble.py +4 -1
- anemoi/datasets/data/fill_missing.py +165 -0
- anemoi/datasets/data/forwards.py +23 -1
- anemoi/datasets/data/grids.py +236 -58
- anemoi/datasets/data/indexing.py +4 -1
- anemoi/datasets/data/interpolate.py +4 -1
- anemoi/datasets/data/join.py +12 -9
- anemoi/datasets/data/masked.py +36 -10
- anemoi/datasets/data/merge.py +180 -0
- anemoi/datasets/data/misc.py +18 -3
- anemoi/datasets/data/missing.py +4 -1
- anemoi/datasets/data/rescale.py +4 -1
- anemoi/datasets/data/select.py +4 -1
- anemoi/datasets/data/statistics.py +4 -1
- anemoi/datasets/data/stores.py +66 -3
- anemoi/datasets/data/subset.py +6 -1
- anemoi/datasets/data/unchecked.py +4 -1
- anemoi/datasets/data/xy.py +20 -5
- anemoi/datasets/dates/__init__.py +9 -7
- anemoi/datasets/dates/groups.py +3 -1
- anemoi/datasets/fields.py +3 -1
- anemoi/datasets/grids.py +86 -2
- anemoi/datasets/testing.py +3 -2
- anemoi/datasets/utils/__init__.py +8 -0
- anemoi/datasets/utils/fields.py +2 -2
- {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/METADATA +11 -29
- anemoi_datasets-0.5.10.dist-info/RECORD +124 -0
- {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/WHEEL +1 -1
- anemoi_datasets-0.5.7.dist-info/RECORD +0 -122
- {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/LICENSE +0 -0
- {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/entry_points.txt +0 -0
- {anemoi_datasets-0.5.7.dist-info → anemoi_datasets-0.5.10.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# (C) Copyright
|
|
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
11
|
import importlib
|
|
@@ -21,6 +21,8 @@ def assert_is_fieldlist(obj):
|
|
|
21
21
|
|
|
22
22
|
def import_function(name, kind):
|
|
23
23
|
|
|
24
|
+
from anemoi.transform.filters import filter_registry
|
|
25
|
+
|
|
24
26
|
name = name.replace("-", "_")
|
|
25
27
|
|
|
26
28
|
plugins = {}
|
|
@@ -30,8 +32,21 @@ def import_function(name, kind):
|
|
|
30
32
|
if name in plugins:
|
|
31
33
|
return plugins[name].load()
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
try:
|
|
36
|
+
module = importlib.import_module(
|
|
37
|
+
f".{kind}.{name}",
|
|
38
|
+
package=__name__,
|
|
39
|
+
)
|
|
40
|
+
return module.execute
|
|
41
|
+
except ModuleNotFoundError:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
if kind == "filters":
|
|
45
|
+
if filter_registry.lookup(name, return_none=True):
|
|
46
|
+
|
|
47
|
+
def proc(context, data, *args, **kwargs):
|
|
48
|
+
return filter_registry.create(name, *args, **kwargs)(data)
|
|
49
|
+
|
|
50
|
+
return proc
|
|
51
|
+
|
|
52
|
+
raise ValueError(f"Unknown {kind} '{name}'")
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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 earthkit.data as ekd
|
|
11
12
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
11
|
def execute(context, input, *args, **kwargs):
|
anemoi/datasets/create/functions/filters/pressure_level_relative_humidity_to_specific_humidity.py
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from collections import defaultdict
|
|
11
12
|
|
anemoi/datasets/create/functions/filters/pressure_level_specific_humidity_to_relative_humidity.py
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from collections import defaultdict
|
|
11
12
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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 re
|
|
11
12
|
|
|
@@ -24,7 +25,9 @@ class RenamedFieldMapping:
|
|
|
24
25
|
def __init__(self, field, what, renaming):
|
|
25
26
|
self.field = field
|
|
26
27
|
self.what = what
|
|
27
|
-
self.renaming =
|
|
28
|
+
self.renaming = {}
|
|
29
|
+
for k, v in renaming.items():
|
|
30
|
+
self.renaming[k] = {str(a): str(b) for a, b in v.items()}
|
|
28
31
|
|
|
29
32
|
def metadata(self, key=None, **kwargs):
|
|
30
33
|
if key is None:
|
|
@@ -51,16 +54,19 @@ class RenamedFieldFormat:
|
|
|
51
54
|
format (str): A string that defines the new name of the field.
|
|
52
55
|
"""
|
|
53
56
|
|
|
54
|
-
def __init__(self, field, format):
|
|
57
|
+
def __init__(self, field, what, format):
|
|
55
58
|
self.field = field
|
|
59
|
+
self.what = what
|
|
56
60
|
self.format = format
|
|
57
61
|
self.bits = re.findall(r"{(\w+)}", format)
|
|
58
62
|
|
|
59
|
-
def metadata(self,
|
|
60
|
-
value = self.field.metadata(
|
|
61
|
-
if
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
def metadata(self, *args, **kwargs):
|
|
64
|
+
value = self.field.metadata(*args, **kwargs)
|
|
65
|
+
if args:
|
|
66
|
+
assert len(args) == 1
|
|
67
|
+
if args[0] == self.what:
|
|
68
|
+
bits = {b: self.field.metadata(b, **kwargs) for b in self.bits}
|
|
69
|
+
return self.format.format(**bits)
|
|
64
70
|
return value
|
|
65
71
|
|
|
66
72
|
def __getattr__(self, name):
|
|
@@ -69,6 +75,6 @@ class RenamedFieldFormat:
|
|
|
69
75
|
|
|
70
76
|
def execute(context, input, what="param", **kwargs):
|
|
71
77
|
if what in kwargs and isinstance(kwargs[what], str):
|
|
72
|
-
return FieldArray([RenamedFieldFormat(fs, kwargs[what]) for fs in input])
|
|
78
|
+
return FieldArray([RenamedFieldFormat(fs, what, kwargs[what]) for fs in input])
|
|
73
79
|
|
|
74
80
|
return FieldArray([RenamedFieldMapping(fs, what, kwargs) for fs in input])
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from collections import defaultdict
|
|
11
12
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from collections import defaultdict
|
|
11
12
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from collections import defaultdict
|
|
11
12
|
|
anemoi/datasets/create/functions/filters/single_level_relative_humidity_to_specific_humidity.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
11
|
import numpy as np
|
anemoi/datasets/create/functions/filters/single_level_specific_humidity_to_relative_humidity.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
11
|
import numpy as np
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from collections import defaultdict
|
|
11
12
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from collections import defaultdict
|
|
11
12
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from collections import defaultdict
|
|
11
12
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
import glob
|
|
11
11
|
import logging
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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 warnings
|
|
@@ -327,7 +328,9 @@ def _compute_accumulations(
|
|
|
327
328
|
_member(field),
|
|
328
329
|
)
|
|
329
330
|
values = field.values # optimisation
|
|
330
|
-
|
|
331
|
+
if key not in accumulations:
|
|
332
|
+
raise ValueError(f"Key not found: {key}. Is it an accumulation field?")
|
|
333
|
+
|
|
331
334
|
for a in accumulations[key]:
|
|
332
335
|
a.add(field, values)
|
|
333
336
|
|
|
@@ -370,12 +373,15 @@ def accumulations(context, dates, **request):
|
|
|
370
373
|
|
|
371
374
|
user_accumulation_period = request.pop("accumulation_period", 6)
|
|
372
375
|
|
|
376
|
+
# If `data_accumulation_period` is not set, this means that the accumulations are from the start
|
|
377
|
+
# of the forecast.
|
|
378
|
+
|
|
373
379
|
KWARGS = {
|
|
374
380
|
("od", "oper"): dict(patch=_scda),
|
|
375
381
|
("od", "elda"): dict(base_times=(6, 18)),
|
|
376
382
|
("ea", "oper"): dict(data_accumulation_period=1, base_times=(6, 18)),
|
|
377
383
|
("ea", "enda"): dict(data_accumulation_period=3, base_times=(6, 18)),
|
|
378
|
-
("rr", "oper"): dict(
|
|
384
|
+
("rr", "oper"): dict(base_times=(0, 3, 6, 9, 12, 15, 18, 21)),
|
|
379
385
|
("l5", "oper"): dict(data_accumulation_period=1, base_times=(0,)),
|
|
380
386
|
}
|
|
381
387
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from earthkit.data import from_source
|
|
10
11
|
|
|
11
12
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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 earthkit.data as ekd
|
|
11
12
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from earthkit.data import from_source
|
|
10
11
|
|
|
11
12
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
11
|
import glob
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
|
|
11
12
|
from earthkit.data.core.fieldlist import MultiFieldList
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
|
11
|
+
import re
|
|
10
12
|
|
|
11
13
|
from anemoi.utils.humanize import did_you_mean
|
|
12
14
|
from earthkit.data import from_source
|
|
@@ -31,6 +33,25 @@ def _date_to_datetime(d):
|
|
|
31
33
|
return datetime.datetime.fromisoformat(d)
|
|
32
34
|
|
|
33
35
|
|
|
36
|
+
def expand_to_by(x):
|
|
37
|
+
|
|
38
|
+
if isinstance(x, (str, int)):
|
|
39
|
+
return expand_to_by(str(x).split("/"))
|
|
40
|
+
|
|
41
|
+
if len(x) == 3 and x[1] == "to":
|
|
42
|
+
start = int(x[0])
|
|
43
|
+
end = int(x[2])
|
|
44
|
+
return list(range(start, end + 1))
|
|
45
|
+
|
|
46
|
+
if len(x) == 5 and x[1] == "to" and x[3] == "by":
|
|
47
|
+
start = int(x[0])
|
|
48
|
+
end = int(x[2])
|
|
49
|
+
by = int(x[4])
|
|
50
|
+
return list(range(start, end + 1, by))
|
|
51
|
+
|
|
52
|
+
return x
|
|
53
|
+
|
|
54
|
+
|
|
34
55
|
def normalise_time_delta(t):
|
|
35
56
|
if isinstance(t, datetime.timedelta):
|
|
36
57
|
assert t == datetime.timedelta(hours=t.hours), t
|
|
@@ -42,25 +63,48 @@ def normalise_time_delta(t):
|
|
|
42
63
|
return t
|
|
43
64
|
|
|
44
65
|
|
|
66
|
+
def _normalise_time(t):
|
|
67
|
+
t = int(t)
|
|
68
|
+
if t < 100:
|
|
69
|
+
t * 100
|
|
70
|
+
return "{:04d}".format(t)
|
|
71
|
+
|
|
72
|
+
|
|
45
73
|
def _expand_mars_request(request, date, request_already_using_valid_datetime=False, date_key="date"):
|
|
46
74
|
requests = []
|
|
47
|
-
|
|
48
|
-
|
|
75
|
+
|
|
76
|
+
user_step = to_list(expand_to_by(request.get("step", [0])))
|
|
77
|
+
user_time = None
|
|
78
|
+
user_date = None
|
|
79
|
+
|
|
80
|
+
if not request_already_using_valid_datetime:
|
|
81
|
+
user_time = request.get("time")
|
|
82
|
+
if user_time is not None:
|
|
83
|
+
user_time = to_list(user_time)
|
|
84
|
+
user_time = [_normalise_time(t) for t in user_time]
|
|
85
|
+
|
|
86
|
+
user_date = request.get(date_key)
|
|
87
|
+
if user_date is not None:
|
|
88
|
+
assert isinstance(user_date, str), user_date
|
|
89
|
+
user_date = re.compile("^{}$".format(user_date.replace("-", "").replace("?", ".")))
|
|
90
|
+
|
|
91
|
+
for step in user_step:
|
|
49
92
|
r = request.copy()
|
|
50
93
|
|
|
51
94
|
if not request_already_using_valid_datetime:
|
|
52
95
|
|
|
53
|
-
if isinstance(
|
|
54
|
-
assert
|
|
96
|
+
if isinstance(step, str) and "-" in step:
|
|
97
|
+
assert step.count("-") == 1, step
|
|
98
|
+
|
|
55
99
|
# this takes care of the cases where the step is a period such as 0-24 or 12-24
|
|
56
|
-
hours = int(str(
|
|
100
|
+
hours = int(str(step).split("-")[-1])
|
|
57
101
|
|
|
58
102
|
base = date - datetime.timedelta(hours=hours)
|
|
59
103
|
r.update(
|
|
60
104
|
{
|
|
61
105
|
date_key: base.strftime("%Y%m%d"),
|
|
62
106
|
"time": base.strftime("%H%M"),
|
|
63
|
-
"step":
|
|
107
|
+
"step": step,
|
|
64
108
|
}
|
|
65
109
|
)
|
|
66
110
|
|
|
@@ -69,12 +113,28 @@ def _expand_mars_request(request, date, request_already_using_valid_datetime=Fal
|
|
|
69
113
|
if isinstance(r[pproc], (list, tuple)):
|
|
70
114
|
r[pproc] = "/".join(str(x) for x in r[pproc])
|
|
71
115
|
|
|
116
|
+
if user_date is not None:
|
|
117
|
+
if not user_date.match(r[date_key]):
|
|
118
|
+
continue
|
|
119
|
+
|
|
120
|
+
if user_time is not None:
|
|
121
|
+
# It time is provided by the user, we only keep the requests that match the time
|
|
122
|
+
if r["time"] not in user_time:
|
|
123
|
+
continue
|
|
124
|
+
|
|
72
125
|
requests.append(r)
|
|
73
126
|
|
|
127
|
+
# assert requests, requests
|
|
128
|
+
|
|
74
129
|
return requests
|
|
75
130
|
|
|
76
131
|
|
|
77
|
-
def factorise_requests(
|
|
132
|
+
def factorise_requests(
|
|
133
|
+
dates,
|
|
134
|
+
*requests,
|
|
135
|
+
request_already_using_valid_datetime=False,
|
|
136
|
+
date_key="date",
|
|
137
|
+
):
|
|
78
138
|
updates = []
|
|
79
139
|
for req in requests:
|
|
80
140
|
# req = normalise_request(req)
|
|
@@ -87,6 +147,9 @@ def factorise_requests(dates, *requests, request_already_using_valid_datetime=Fa
|
|
|
87
147
|
date_key=date_key,
|
|
88
148
|
)
|
|
89
149
|
|
|
150
|
+
if not updates:
|
|
151
|
+
return
|
|
152
|
+
|
|
90
153
|
compressed = Availability(updates)
|
|
91
154
|
for r in compressed.iterate():
|
|
92
155
|
for k, v in r.items():
|
|
@@ -177,13 +240,24 @@ MARS_KEYS = [
|
|
|
177
240
|
]
|
|
178
241
|
|
|
179
242
|
|
|
180
|
-
def mars(
|
|
243
|
+
def mars(
|
|
244
|
+
context,
|
|
245
|
+
dates,
|
|
246
|
+
*requests,
|
|
247
|
+
request_already_using_valid_datetime=False,
|
|
248
|
+
date_key="date",
|
|
249
|
+
**kwargs,
|
|
250
|
+
):
|
|
251
|
+
|
|
181
252
|
if not requests:
|
|
182
253
|
requests = [kwargs]
|
|
183
254
|
|
|
184
255
|
for r in requests:
|
|
256
|
+
param = r.get("param", [])
|
|
257
|
+
if not isinstance(param, (list, tuple)):
|
|
258
|
+
param = [param]
|
|
185
259
|
# check for "Norway bug" where yaml transforms 'no' into False, etc.
|
|
186
|
-
for p in
|
|
260
|
+
for p in param:
|
|
187
261
|
if p is False:
|
|
188
262
|
raise ValueError(
|
|
189
263
|
"'param' cannot be 'False'. If you wrote 'param: no' or 'param: off' in yaml, you may want to use quotes?"
|
|
@@ -197,12 +271,18 @@ def mars(context, dates, *requests, request_already_using_valid_datetime=False,
|
|
|
197
271
|
"'param' cannot be 'True'. If you wrote 'param: on' in yaml, you may want to use quotes?"
|
|
198
272
|
)
|
|
199
273
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
274
|
+
if len(dates) == 0: # When using `repeated_dates`
|
|
275
|
+
assert len(requests) == 1, requests
|
|
276
|
+
assert "date" in requests[0], requests[0]
|
|
277
|
+
if isinstance(requests[0]["date"], datetime.date):
|
|
278
|
+
requests[0]["date"] = requests[0]["date"].strftime("%Y%m%d")
|
|
279
|
+
else:
|
|
280
|
+
requests = factorise_requests(
|
|
281
|
+
dates,
|
|
282
|
+
*requests,
|
|
283
|
+
request_already_using_valid_datetime=request_already_using_valid_datetime,
|
|
284
|
+
date_key=date_key,
|
|
285
|
+
)
|
|
206
286
|
|
|
207
287
|
requests = list(requests)
|
|
208
288
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
|
from .xarray import load_many
|
|
11
12
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# (C) Copyright 2024
|
|
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
11
|
from .xarray import load_many
|