anemoi-datasets 0.5.25__py3-none-any.whl → 0.5.26__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 (41) hide show
  1. anemoi/datasets/_version.py +2 -2
  2. anemoi/datasets/commands/grib-index.py +1 -1
  3. anemoi/datasets/create/filter.py +22 -24
  4. anemoi/datasets/create/input/step.py +2 -16
  5. anemoi/datasets/create/sources/planetary_computer.py +44 -0
  6. anemoi/datasets/create/sources/xarray_support/__init__.py +6 -22
  7. anemoi/datasets/create/sources/xarray_support/coordinates.py +8 -0
  8. anemoi/datasets/create/sources/xarray_support/field.py +1 -4
  9. anemoi/datasets/create/sources/xarray_support/flavour.py +44 -6
  10. anemoi/datasets/create/sources/xarray_support/patch.py +44 -1
  11. anemoi/datasets/create/sources/xarray_support/variable.py +6 -2
  12. anemoi/datasets/data/complement.py +44 -10
  13. anemoi/datasets/data/forwards.py +8 -2
  14. anemoi/datasets/data/stores.py +7 -56
  15. anemoi/datasets/grids.py +6 -3
  16. {anemoi_datasets-0.5.25.dist-info → anemoi_datasets-0.5.26.dist-info}/METADATA +3 -2
  17. {anemoi_datasets-0.5.25.dist-info → anemoi_datasets-0.5.26.dist-info}/RECORD +21 -40
  18. anemoi/datasets/create/filters/__init__.py +0 -33
  19. anemoi/datasets/create/filters/empty.py +0 -37
  20. anemoi/datasets/create/filters/legacy.py +0 -93
  21. anemoi/datasets/create/filters/noop.py +0 -37
  22. anemoi/datasets/create/filters/orog_to_z.py +0 -58
  23. anemoi/datasets/create/filters/pressure_level_relative_humidity_to_specific_humidity.py +0 -83
  24. anemoi/datasets/create/filters/pressure_level_specific_humidity_to_relative_humidity.py +0 -84
  25. anemoi/datasets/create/filters/rename.py +0 -205
  26. anemoi/datasets/create/filters/rotate_winds.py +0 -105
  27. anemoi/datasets/create/filters/single_level_dewpoint_to_relative_humidity.py +0 -78
  28. anemoi/datasets/create/filters/single_level_relative_humidity_to_dewpoint.py +0 -84
  29. anemoi/datasets/create/filters/single_level_relative_humidity_to_specific_humidity.py +0 -163
  30. anemoi/datasets/create/filters/single_level_specific_humidity_to_relative_humidity.py +0 -451
  31. anemoi/datasets/create/filters/speeddir_to_uv.py +0 -95
  32. anemoi/datasets/create/filters/sum.py +0 -68
  33. anemoi/datasets/create/filters/transform.py +0 -51
  34. anemoi/datasets/create/filters/unrotate_winds.py +0 -105
  35. anemoi/datasets/create/filters/uv_to_speeddir.py +0 -94
  36. anemoi/datasets/create/filters/wz_to_w.py +0 -98
  37. anemoi/datasets/create/testing.py +0 -76
  38. {anemoi_datasets-0.5.25.dist-info → anemoi_datasets-0.5.26.dist-info}/WHEEL +0 -0
  39. {anemoi_datasets-0.5.25.dist-info → anemoi_datasets-0.5.26.dist-info}/entry_points.txt +0 -0
  40. {anemoi_datasets-0.5.25.dist-info → anemoi_datasets-0.5.26.dist-info}/licenses/LICENSE +0 -0
  41. {anemoi_datasets-0.5.25.dist-info → anemoi_datasets-0.5.26.dist-info}/top_level.txt +0 -0
@@ -1,105 +0,0 @@
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
-
10
- from collections import defaultdict
11
- from typing import Any
12
-
13
- import earthkit.data as ekd
14
- from anemoi.transform.fields import new_field_from_numpy
15
- from anemoi.transform.fields import new_fieldlist_from_list
16
- from earthkit.geo.rotate import unrotate_vector
17
-
18
- from .legacy import legacy_filter
19
-
20
-
21
- @legacy_filter(__file__)
22
- def execute(context: Any, input: ekd.FieldList, u: str, v: str) -> ekd.FieldList:
23
- """Unrotate the wind components of a GRIB file.
24
-
25
- Parameters
26
- ----------
27
- context : Any
28
- The execution context.
29
- input : List[Any]
30
- The list of input fields.
31
- u : str
32
- The parameter name for the u-component of the wind.
33
- v : str
34
- The parameter name for the v-component of the wind.
35
-
36
- Returns
37
- -------
38
- ekd.FieldList
39
- The resulting field array with unrotated wind components.
40
- """
41
- result = []
42
-
43
- wind_params = (u, v)
44
- wind_pairs = defaultdict(dict)
45
-
46
- for f in input:
47
- key = f.metadata(namespace="mars")
48
- param = key.pop("param")
49
-
50
- if param not in wind_params:
51
- result.append(f)
52
- continue
53
-
54
- key = tuple(key.items())
55
-
56
- if param in wind_pairs[key]:
57
- raise ValueError(f"Duplicate wind component {param} for {key}")
58
-
59
- wind_pairs[key][param] = f
60
-
61
- for _, pairs in wind_pairs.items():
62
- if len(pairs) != 2:
63
- raise ValueError("Missing wind component")
64
-
65
- x = pairs[u]
66
- y = pairs[v]
67
-
68
- lats, lons = x.grid_points()
69
- raw_lats, raw_longs = x.grid_points_unrotated()
70
-
71
- assert x.rotation == y.rotation
72
-
73
- u_new, v_new = unrotate_vector(
74
- lats,
75
- lons,
76
- x.to_numpy(flatten=True),
77
- y.to_numpy(flatten=True),
78
- *x.rotation[:2],
79
- south_pole_rotation_angle=x.rotation[2],
80
- lat_unrotated=raw_lats,
81
- lon_unrotated=raw_longs,
82
- )
83
-
84
- result.append(new_field_from_numpy(x, u_new))
85
- result.append(new_field_from_numpy(y, v_new))
86
-
87
- return new_fieldlist_from_list(result)
88
-
89
-
90
- if __name__ == "__main__":
91
- from earthkit.data import from_source
92
-
93
- source = from_source(
94
- "mars",
95
- date=-1,
96
- param="10u/10v",
97
- levtype="sfc",
98
- grid=[1, 1],
99
- area=[28, 0, -14, 40],
100
- rotation=[-22, -40],
101
- )
102
-
103
- source.save("source.grib")
104
-
105
- execute(None, source, "10u", "10v")
@@ -1,94 +0,0 @@
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
-
10
- """This module provides a function to convert u and v wind components to wind speed and direction."""
11
-
12
- from collections import defaultdict
13
- from typing import Any
14
- from typing import List
15
-
16
- import earthkit.data as ekd
17
- import numpy as np
18
- from anemoi.transform.fields import new_field_from_numpy
19
- from anemoi.transform.fields import new_fieldlist_from_list
20
- from earthkit.meteo.wind.array import xy_to_polar
21
-
22
- from .legacy import legacy_filter
23
-
24
-
25
- @legacy_filter(__file__)
26
- def execute(
27
- context: Any,
28
- input: List[Any],
29
- u_component: str,
30
- v_component: str,
31
- wind_speed: str,
32
- wind_dir: str,
33
- in_radians: bool = False,
34
- ) -> ekd.FieldList:
35
- """Converts u and v wind components to wind speed and direction.
36
-
37
- Parameters
38
- ----------
39
- context : Any
40
- The context in which the function is executed.
41
- input : List[Any]
42
- List of input fields containing wind components.
43
- u_component : str
44
- The name of the u component field.
45
- v_component : str
46
- The name of the v component field.
47
- wind_speed : str
48
- The name of the wind speed field to be created.
49
- wind_dir : str
50
- The name of the wind direction field to be created.
51
- in_radians : bool, optional
52
- If True, the wind direction is returned in radians. Default is False.
53
-
54
- Returns
55
- -------
56
- ekd.FieldList
57
- A FieldArray containing the wind speed and direction fields.
58
- """
59
- result = []
60
-
61
- wind_params = (u_component, v_component)
62
- wind_pairs = defaultdict(dict)
63
-
64
- for f in input:
65
- key = f.metadata(namespace="mars")
66
- param = key.pop("param")
67
-
68
- if param not in wind_params:
69
- result.append(f)
70
- continue
71
-
72
- key = tuple(key.items())
73
-
74
- if param in wind_pairs[key]:
75
- raise ValueError(f"Duplicate wind component {param} for {key}")
76
-
77
- wind_pairs[key][param] = f
78
-
79
- for _, pairs in wind_pairs.items():
80
- if len(pairs) != 2:
81
- raise ValueError("Missing wind component")
82
-
83
- u = pairs[u_component]
84
- v = pairs[v_component]
85
-
86
- # assert speed.grid_mapping == dir.grid_mapping
87
- magnitude, direction = xy_to_polar(u.to_numpy(flatten=True), v.to_numpy(flatten=True))
88
- if in_radians:
89
- direction = np.deg2rad(direction)
90
-
91
- result.append(new_field_from_numpy(u, magnitude, params=wind_speed))
92
- result.append(new_field_from_numpy(v, direction, params=wind_dir))
93
-
94
- return new_fieldlist_from_list(result)
@@ -1,98 +0,0 @@
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
-
10
- from collections import defaultdict
11
- from typing import Any
12
-
13
- import earthkit.data as ekd
14
- from anemoi.transform.fields import new_field_from_numpy
15
- from anemoi.transform.fields import new_fieldlist_from_list
16
-
17
- from .legacy import legacy_filter
18
-
19
-
20
- @legacy_filter(__file__)
21
- def execute(context: Any, input: ekd.FieldList, wz: str, t: str, w: str = "w") -> ekd.FieldList:
22
- """Convert geometric vertical velocity (m/s) to vertical velocity (Pa / s).
23
-
24
- Parameters
25
- ----------
26
- context : Any
27
- The context for the execution.
28
- input : List[Any]
29
- The list of input fields.
30
- wz : str
31
- The parameter name for geometric vertical velocity.
32
- t : str
33
- The parameter name for temperature.
34
- w : str, optional
35
- The parameter name for vertical velocity. Defaults to "w".
36
-
37
- Returns
38
- -------
39
- ekd.FieldList
40
- The resulting FieldArray with converted vertical velocity fields.
41
- """
42
- result = []
43
-
44
- params = (wz, t)
45
- pairs = defaultdict(dict)
46
-
47
- for f in input:
48
- key = f.metadata(namespace="mars")
49
- param = key.pop("param")
50
- if param in params:
51
- key = tuple(key.items())
52
-
53
- if param in pairs[key]:
54
- raise ValueError(f"Duplicate field {param} for {key}")
55
-
56
- pairs[key][param] = f
57
- if param == t:
58
- result.append(f)
59
- else:
60
- result.append(f)
61
-
62
- for keys, values in pairs.items():
63
-
64
- if len(values) != 2:
65
- raise ValueError("Missing fields")
66
-
67
- wz_pl = values[wz].to_numpy(flatten=True)
68
- t_pl = values[t].to_numpy(flatten=True)
69
- pressure = next(
70
- float(v) * 100 for k, v in keys if k in ["level", "levelist"]
71
- ) # Looks first for "level" then "levelist" value
72
- w_pl = wz_to_w(wz_pl, t_pl, pressure)
73
- result.append(new_field_from_numpy(values[wz], w_pl, param=w))
74
-
75
- return new_fieldlist_from_list(result)
76
-
77
-
78
- def wz_to_w(wz: Any, t: Any, pressure: float) -> Any:
79
- """Convert geometric vertical velocity (m/s) to vertical velocity (Pa / s).
80
-
81
- Parameters
82
- ----------
83
- wz : Any
84
- The geometric vertical velocity data.
85
- t : Any
86
- The temperature data.
87
- pressure : float
88
- The pressure value.
89
-
90
- Returns
91
- -------
92
- Any
93
- The vertical velocity data in Pa / s.
94
- """
95
- g = 9.81
96
- Rd = 287.058
97
-
98
- return -wz * g * pressure / (t * Rd)
@@ -1,76 +0,0 @@
1
- # (C) Copyright 2025- 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
-
10
- import tempfile
11
- from typing import Any
12
- from typing import Dict
13
- from typing import List
14
- from typing import Optional
15
- from typing import Union
16
-
17
- import yaml
18
-
19
- from anemoi.datasets.create import creator_factory
20
-
21
-
22
- class TestingContext:
23
- pass
24
-
25
-
26
- def create_dataset(
27
- *,
28
- config: Union[str, Dict[str, Any]],
29
- output: Optional[str],
30
- delta: Optional[List[str]] = None,
31
- is_test: bool = False,
32
- ) -> str:
33
- """Create a dataset based on the provided configuration.
34
-
35
- Parameters
36
- ----------
37
- config : Union[str, Dict[str, Any]]
38
- The configuration for the dataset. Can be a path to a YAML file or a dictionary.
39
- output : Optional[str]
40
- The output path for the dataset. If None, a temporary directory will be created.
41
- delta : Optional[List[str]], optional
42
- List of delta for secondary statistics, by default None.
43
- is_test : bool, optional
44
- Flag indicating if the dataset creation is for testing purposes, by default False.
45
-
46
- Returns
47
- -------
48
- str
49
- The path to the created dataset.
50
- """
51
- if isinstance(config, dict):
52
- temp_file = tempfile.NamedTemporaryFile(mode="w", suffix=".yaml")
53
- yaml.dump(config, temp_file)
54
- config = temp_file.name
55
-
56
- if output is None:
57
- output = tempfile.mkdtemp(suffix=".zarr")
58
-
59
- creator_factory("init", config=config, path=output, overwrite=True, test=is_test).run()
60
- creator_factory("load", path=output).run()
61
- creator_factory("finalise", path=output).run()
62
- creator_factory("patch", path=output).run()
63
-
64
- if delta is not None:
65
- creator_factory("init_additions", path=output, delta=delta).run()
66
- creator_factory("run_additions", path=output, delta=delta).run()
67
- creator_factory("finalise_additions", path=output, delta=delta).run()
68
-
69
- creator_factory("cleanup", path=output).run()
70
-
71
- if delta is not None:
72
- creator_factory("cleanup", path=output, delta=delta).run()
73
-
74
- creator_factory("verify", path=output).run()
75
-
76
- return output