anemoi-datasets 0.5.26__py3-none-any.whl → 0.5.28__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 (116) hide show
  1. anemoi/datasets/__init__.py +1 -2
  2. anemoi/datasets/_version.py +16 -3
  3. anemoi/datasets/commands/check.py +1 -1
  4. anemoi/datasets/commands/copy.py +1 -2
  5. anemoi/datasets/commands/create.py +1 -1
  6. anemoi/datasets/commands/inspect.py +27 -35
  7. anemoi/datasets/commands/recipe/__init__.py +93 -0
  8. anemoi/datasets/commands/recipe/format.py +55 -0
  9. anemoi/datasets/commands/recipe/migrate.py +555 -0
  10. anemoi/datasets/commands/validate.py +59 -0
  11. anemoi/datasets/compute/recentre.py +3 -6
  12. anemoi/datasets/create/__init__.py +64 -26
  13. anemoi/datasets/create/check.py +10 -12
  14. anemoi/datasets/create/chunks.py +1 -2
  15. anemoi/datasets/create/config.py +5 -6
  16. anemoi/datasets/create/input/__init__.py +44 -65
  17. anemoi/datasets/create/input/action.py +296 -238
  18. anemoi/datasets/create/input/context/__init__.py +71 -0
  19. anemoi/datasets/create/input/context/field.py +54 -0
  20. anemoi/datasets/create/input/data_sources.py +7 -9
  21. anemoi/datasets/create/input/misc.py +2 -75
  22. anemoi/datasets/create/input/repeated_dates.py +11 -130
  23. anemoi/datasets/{utils → create/input/result}/__init__.py +10 -1
  24. anemoi/datasets/create/input/{result.py → result/field.py} +36 -120
  25. anemoi/datasets/create/input/trace.py +1 -1
  26. anemoi/datasets/create/patch.py +1 -2
  27. anemoi/datasets/create/persistent.py +3 -5
  28. anemoi/datasets/create/size.py +1 -3
  29. anemoi/datasets/create/sources/accumulations.py +120 -145
  30. anemoi/datasets/create/sources/accumulations2.py +20 -53
  31. anemoi/datasets/create/sources/anemoi_dataset.py +46 -42
  32. anemoi/datasets/create/sources/constants.py +39 -40
  33. anemoi/datasets/create/sources/empty.py +22 -19
  34. anemoi/datasets/create/sources/fdb.py +133 -0
  35. anemoi/datasets/create/sources/forcings.py +29 -29
  36. anemoi/datasets/create/sources/grib.py +94 -78
  37. anemoi/datasets/create/sources/grib_index.py +57 -55
  38. anemoi/datasets/create/sources/hindcasts.py +57 -59
  39. anemoi/datasets/create/sources/legacy.py +10 -62
  40. anemoi/datasets/create/sources/mars.py +121 -149
  41. anemoi/datasets/create/sources/netcdf.py +28 -25
  42. anemoi/datasets/create/sources/opendap.py +28 -26
  43. anemoi/datasets/create/sources/patterns.py +4 -6
  44. anemoi/datasets/create/sources/recentre.py +46 -48
  45. anemoi/datasets/create/sources/repeated_dates.py +44 -0
  46. anemoi/datasets/create/sources/source.py +26 -51
  47. anemoi/datasets/create/sources/tendencies.py +68 -98
  48. anemoi/datasets/create/sources/xarray.py +4 -6
  49. anemoi/datasets/create/sources/xarray_support/__init__.py +40 -36
  50. anemoi/datasets/create/sources/xarray_support/coordinates.py +8 -12
  51. anemoi/datasets/create/sources/xarray_support/field.py +20 -16
  52. anemoi/datasets/create/sources/xarray_support/fieldlist.py +11 -15
  53. anemoi/datasets/create/sources/xarray_support/flavour.py +42 -42
  54. anemoi/datasets/create/sources/xarray_support/grid.py +15 -9
  55. anemoi/datasets/create/sources/xarray_support/metadata.py +19 -128
  56. anemoi/datasets/create/sources/xarray_support/patch.py +4 -6
  57. anemoi/datasets/create/sources/xarray_support/time.py +10 -13
  58. anemoi/datasets/create/sources/xarray_support/variable.py +21 -21
  59. anemoi/datasets/create/sources/xarray_zarr.py +28 -25
  60. anemoi/datasets/create/sources/zenodo.py +43 -41
  61. anemoi/datasets/create/statistics/__init__.py +3 -6
  62. anemoi/datasets/create/testing.py +4 -0
  63. anemoi/datasets/create/typing.py +1 -2
  64. anemoi/datasets/create/utils.py +0 -43
  65. anemoi/datasets/create/zarr.py +7 -2
  66. anemoi/datasets/data/__init__.py +15 -6
  67. anemoi/datasets/data/complement.py +7 -12
  68. anemoi/datasets/data/concat.py +5 -8
  69. anemoi/datasets/data/dataset.py +48 -47
  70. anemoi/datasets/data/debug.py +7 -9
  71. anemoi/datasets/data/ensemble.py +4 -6
  72. anemoi/datasets/data/fill_missing.py +7 -10
  73. anemoi/datasets/data/forwards.py +22 -26
  74. anemoi/datasets/data/grids.py +12 -168
  75. anemoi/datasets/data/indexing.py +9 -12
  76. anemoi/datasets/data/interpolate.py +7 -15
  77. anemoi/datasets/data/join.py +8 -12
  78. anemoi/datasets/data/masked.py +6 -11
  79. anemoi/datasets/data/merge.py +5 -9
  80. anemoi/datasets/data/misc.py +41 -45
  81. anemoi/datasets/data/missing.py +11 -16
  82. anemoi/datasets/data/observations/__init__.py +8 -14
  83. anemoi/datasets/data/padded.py +3 -5
  84. anemoi/datasets/data/records/backends/__init__.py +2 -2
  85. anemoi/datasets/data/rescale.py +5 -12
  86. anemoi/datasets/data/rolling_average.py +141 -0
  87. anemoi/datasets/data/select.py +13 -16
  88. anemoi/datasets/data/statistics.py +4 -7
  89. anemoi/datasets/data/stores.py +22 -29
  90. anemoi/datasets/data/subset.py +8 -11
  91. anemoi/datasets/data/unchecked.py +7 -11
  92. anemoi/datasets/data/xy.py +25 -21
  93. anemoi/datasets/dates/__init__.py +15 -18
  94. anemoi/datasets/dates/groups.py +7 -10
  95. anemoi/datasets/dumper.py +76 -0
  96. anemoi/datasets/grids.py +4 -185
  97. anemoi/datasets/schemas/recipe.json +131 -0
  98. anemoi/datasets/testing.py +93 -7
  99. anemoi/datasets/validate.py +598 -0
  100. {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.28.dist-info}/METADATA +7 -4
  101. anemoi_datasets-0.5.28.dist-info/RECORD +134 -0
  102. anemoi/datasets/create/filter.py +0 -48
  103. anemoi/datasets/create/input/concat.py +0 -164
  104. anemoi/datasets/create/input/context.py +0 -89
  105. anemoi/datasets/create/input/empty.py +0 -54
  106. anemoi/datasets/create/input/filter.py +0 -118
  107. anemoi/datasets/create/input/function.py +0 -233
  108. anemoi/datasets/create/input/join.py +0 -130
  109. anemoi/datasets/create/input/pipe.py +0 -66
  110. anemoi/datasets/create/input/step.py +0 -177
  111. anemoi/datasets/create/input/template.py +0 -162
  112. anemoi_datasets-0.5.26.dist-info/RECORD +0 -131
  113. {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.28.dist-info}/WHEEL +0 -0
  114. {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.28.dist-info}/entry_points.txt +0 -0
  115. {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.28.dist-info}/licenses/LICENSE +0 -0
  116. {anemoi_datasets-0.5.26.dist-info → anemoi_datasets-0.5.28.dist-info}/top_level.txt +0 -0
@@ -1,233 +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
- import logging
11
- from functools import cached_property
12
- from typing import Any
13
- from typing import Dict
14
-
15
- from earthkit.data import FieldList
16
-
17
- from ...dates.groups import GroupOfDates
18
- from .action import Action
19
- from .misc import _tidy
20
- from .misc import assert_fieldlist
21
- from .result import Result
22
- from .template import notify_result
23
- from .template import substitute
24
- from .trace import trace
25
- from .trace import trace_datasource
26
- from .trace import trace_select
27
-
28
- LOG = logging.getLogger(__name__)
29
-
30
-
31
- class FunctionContext:
32
- """A FunctionContext is passed to all functions, it will be used to pass information
33
- to the functions from the other actions and filters and results.
34
- """
35
-
36
- def __init__(self, owner: Result) -> None:
37
- """Initializes a FunctionContext instance.
38
-
39
- Parameters
40
- ----------
41
- owner : object
42
- The owner object.
43
- """
44
- self.owner = owner
45
- self.use_grib_paramid: bool = owner.context.use_grib_paramid
46
-
47
- def trace(self, emoji: str, *args: Any) -> None:
48
- """Traces the given arguments with an emoji.
49
-
50
- Parameters
51
- ----------
52
- emoji : str
53
- The emoji to use.
54
- *args : Any
55
- The arguments to trace.
56
- """
57
- trace(emoji, *args)
58
-
59
- def info(self, *args: Any, **kwargs: Any) -> None:
60
- """Logs an info message.
61
-
62
- Parameters
63
- ----------
64
- *args : Any
65
- The arguments for the log message.
66
- **kwargs : Any
67
- The keyword arguments for the log message.
68
- """
69
- LOG.info(*args, **kwargs)
70
-
71
- @property
72
- def dates_provider(self) -> object:
73
- """Returns the dates provider."""
74
- return self.owner.group_of_dates.provider
75
-
76
- @property
77
- def partial_ok(self) -> bool:
78
- """Returns whether partial results are acceptable."""
79
- return self.owner.group_of_dates.partial_ok
80
-
81
- def get_result(self, *args, **kwargs) -> Any:
82
- return self.owner.context.get_result(*args, **kwargs)
83
-
84
-
85
- class FunctionAction(Action):
86
- """Represents an action that executes a function.
87
-
88
- Attributes
89
- ----------
90
- name : str
91
- The name of the function.
92
- """
93
-
94
- def __init__(self, context: object, action_path: list, _name: str, source, **kwargs: Dict[str, Any]) -> None:
95
- """Initializes a FunctionAction instance.
96
-
97
- Parameters
98
- ----------
99
- context : object
100
- The context object.
101
- action_path : list
102
- The action path.
103
- _name : str
104
- The name of the function.
105
- **kwargs : Dict[str, Any]
106
- Additional keyword arguments.
107
- """
108
- super().__init__(context, action_path, **kwargs)
109
- self.name: str = _name
110
- self.source = source
111
-
112
- @trace_select
113
- def select(self, group_of_dates: GroupOfDates) -> "FunctionResult":
114
- """Selects the function result for the given group of dates.
115
-
116
- Parameters
117
- ----------
118
- group_of_dates : GroupOfDates
119
- The group of dates.
120
-
121
- Returns
122
- -------
123
- FunctionResult
124
- The function result instance.
125
- """
126
- return FunctionResult(self.context, self.action_path, group_of_dates, action=self)
127
-
128
- def __repr__(self) -> str:
129
- """Returns a string representation of the FunctionAction instance."""
130
- content: str = ""
131
- content += ",".join([self._short_str(a) for a in self.args])
132
- content += " ".join([self._short_str(f"{k}={v}") for k, v in self.kwargs.items()])
133
- content = self._short_str(content)
134
- return self._repr(_inline_=content, _indent_=" ")
135
-
136
- def _trace_select(self, group_of_dates: GroupOfDates) -> str:
137
- """Traces the selection of the function for the given group of dates.
138
-
139
- Parameters
140
- ----------
141
- group_of_dates : GroupOfDates
142
- The group of dates.
143
-
144
- Returns
145
- -------
146
- str
147
- The trace string.
148
- """
149
- return f"{self.name}({group_of_dates})"
150
-
151
-
152
- class FunctionResult(Result):
153
- """Represents the result of executing a function.
154
-
155
- Attributes
156
- ----------
157
- action : Action
158
- The action instance.
159
- args : tuple
160
- The positional arguments for the function.
161
- kwargs : dict
162
- The keyword arguments for the function.
163
- """
164
-
165
- def __init__(self, context: object, action_path: list, group_of_dates: GroupOfDates, action: Action) -> None:
166
- """Initializes a FunctionResult instance.
167
-
168
- Parameters
169
- ----------
170
- context : object
171
- The context object.
172
- action_path : list
173
- The action path.
174
- group_of_dates : GroupOfDates
175
- The group of dates.
176
- action : Action
177
- The action instance.
178
- """
179
- super().__init__(context, action_path, group_of_dates)
180
- assert isinstance(action, Action), type(action)
181
- self.action: Action = action
182
-
183
- self.args, self.kwargs = substitute(context, (self.action.args, self.action.kwargs))
184
-
185
- def _trace_datasource(self, *args: Any, **kwargs: Any) -> str:
186
- """Traces the datasource for the given arguments.
187
-
188
- Parameters
189
- ----------
190
- *args : Any
191
- The arguments.
192
- **kwargs : Any
193
- The keyword arguments.
194
-
195
- Returns
196
- -------
197
- str
198
- The trace string.
199
- """
200
- return f"{self.action.name}({self.group_of_dates})"
201
-
202
- @cached_property
203
- @assert_fieldlist
204
- @notify_result
205
- @trace_datasource
206
- def datasource(self) -> FieldList:
207
- """Returns the datasource for the function result."""
208
- # args, kwargs = resolve(self.context, (self.args, self.kwargs))
209
- self.action.source.context = FunctionContext(self)
210
-
211
- return _tidy(
212
- self.action.source.execute(
213
- list(self.group_of_dates), # Will provide a list of datetime objects
214
- )
215
- )
216
-
217
- def __repr__(self) -> str:
218
- """Returns a string representation of the FunctionResult instance."""
219
- try:
220
- return f"{self.action.name}({self.group_of_dates})"
221
- except Exception:
222
- return f"{self.__class__.__name__}(unitialised)"
223
-
224
- @property
225
- def function(self) -> None:
226
- """Raises NotImplementedError as this property is not implemented.
227
-
228
- Raises
229
- ------
230
- NotImplementedError
231
- Always raised.
232
- """
233
- raise NotImplementedError(f"Not implemented in {self.__class__.__name__}")
@@ -1,130 +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
- import logging
11
- from functools import cached_property
12
- from typing import Any
13
- from typing import List
14
-
15
- from earthkit.data import FieldList
16
-
17
- from ...dates.groups import GroupOfDates
18
- from .action import Action
19
- from .action import action_factory
20
- from .empty import EmptyResult
21
- from .misc import _tidy
22
- from .misc import assert_fieldlist
23
- from .result import Result
24
- from .template import notify_result
25
- from .trace import trace_datasource
26
- from .trace import trace_select
27
-
28
- LOG = logging.getLogger(__name__)
29
-
30
-
31
- class JoinResult(Result):
32
- """Represents a result that combines multiple results.
33
-
34
- Attributes
35
- ----------
36
- context : object
37
- The context object.
38
- action_path : list
39
- The action path.
40
- group_of_dates : GroupOfDates
41
- The group of dates.
42
- results : List[Result]
43
- The list of results.
44
- """
45
-
46
- def __init__(
47
- self, context: object, action_path: list, group_of_dates: GroupOfDates, results: List[Result], **kwargs: Any
48
- ) -> None:
49
- """Initializes a JoinResult instance.
50
-
51
- Parameters
52
- ----------
53
- context : object
54
- The context object.
55
- action_path : list
56
- The action path.
57
- group_of_dates : GroupOfDates
58
- The group of dates.
59
- results : List[Result]
60
- The list of results.
61
- """
62
- super().__init__(context, action_path, group_of_dates)
63
- self.results: List[Result] = [r for r in results if not r.empty]
64
-
65
- @cached_property
66
- @assert_fieldlist
67
- @notify_result
68
- @trace_datasource
69
- def datasource(self) -> FieldList:
70
- """Returns the combined datasource from all results."""
71
- ds: FieldList = EmptyResult(self.context, self.action_path, self.group_of_dates).datasource
72
- for i in self.results:
73
- ds += i.datasource
74
- return _tidy(ds)
75
-
76
- def __repr__(self) -> str:
77
- """Returns a string representation of the JoinResult instance."""
78
- content: str = "\n".join([str(i) for i in self.results])
79
- return self._repr(content)
80
-
81
-
82
- class JoinAction(Action):
83
- """Represents an action that combines multiple actions.
84
-
85
- Attributes
86
- ----------
87
- context : object
88
- The context object.
89
- action_path : list
90
- The action path.
91
- actions : List[Action]
92
- The list of actions.
93
- """
94
-
95
- def __init__(self, context: object, action_path: list, *configs: dict) -> None:
96
- """Initializes a JoinAction instance.
97
-
98
- Parameters
99
- ----------
100
- context : object
101
- The context object.
102
- action_path : list
103
- The action path.
104
- *configs : dict
105
- The configuration dictionaries.
106
- """
107
- super().__init__(context, action_path, *configs)
108
- self.actions: List[Action] = [action_factory(c, context, action_path + [str(i)]) for i, c in enumerate(configs)]
109
-
110
- def __repr__(self) -> str:
111
- """Returns a string representation of the JoinAction instance."""
112
- content: str = "\n".join([str(i) for i in self.actions])
113
- return self._repr(content)
114
-
115
- @trace_select
116
- def select(self, group_of_dates: GroupOfDates) -> JoinResult:
117
- """Selects the results for the given group of dates.
118
-
119
- Parameters
120
- ----------
121
- group_of_dates : GroupOfDates
122
- The group of dates.
123
-
124
- Returns
125
- -------
126
- JoinResult
127
- The combined result for the given group of dates.
128
- """
129
- results: List[Result] = [a.select(group_of_dates) for a in self.actions]
130
- return JoinResult(self.context, self.action_path, group_of_dates, results)
@@ -1,66 +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
- import json
11
- import logging
12
- from typing import Any
13
-
14
- from .action import Action
15
- from .action import action_factory
16
- from .step import step_factory
17
- from .trace import trace_select
18
-
19
- LOG = logging.getLogger(__name__)
20
-
21
-
22
- class PipeAction(Action):
23
- """A class to represent a pipeline of actions."""
24
-
25
- def __init__(self, context: Any, action_path: list, *configs: dict) -> None:
26
- """Initialize the PipeAction.
27
-
28
- Parameters
29
- ----------
30
- context : Any
31
- The context for the action.
32
- action_path : list
33
- The path of the action.
34
- configs : dict
35
- The configurations for the actions.
36
- """
37
- super().__init__(context, action_path, *configs)
38
- if len(configs) <= 1:
39
- raise ValueError(
40
- f"PipeAction requires at least two actions, got {len(configs)}\n{json.dumps(configs, indent=2)}"
41
- )
42
-
43
- current: Any = action_factory(configs[0], context, action_path + ["0"])
44
- for i, c in enumerate(configs[1:]):
45
- current = step_factory(c, context, action_path + [str(i + 1)], previous_step=current)
46
- self.last_step: Any = current
47
-
48
- @trace_select
49
- def select(self, group_of_dates: Any) -> Any:
50
- """Select data based on the group of dates.
51
-
52
- Parameters
53
- ----------
54
- group_of_dates : Any
55
- The group of dates to select data for.
56
-
57
- Returns
58
- -------
59
- Any
60
- The selected data.
61
- """
62
- return self.last_step.select(group_of_dates)
63
-
64
- def __repr__(self) -> str:
65
- """Return a string representation of the PipeAction."""
66
- return f"PipeAction({self.last_step})"
@@ -1,177 +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
- import logging
11
- from copy import deepcopy
12
- from typing import Any
13
- from typing import Dict
14
- from typing import List
15
- from typing import Optional
16
- from typing import Type
17
-
18
- from .action import Action
19
- from .action import ActionContext
20
- from .context import Context
21
- from .result import Result
22
- from .template import notify_result
23
- from .trace import trace_datasource
24
- from .trace import trace_select
25
-
26
- LOG = logging.getLogger(__name__)
27
-
28
-
29
- class StepResult(Result):
30
- """Represents the result of a step in the data processing pipeline."""
31
-
32
- def __init__(
33
- self, context: Context, action_path: List[str], group_of_dates: Any, action: Action, upstream_result: Result
34
- ) -> None:
35
- """Initialize a StepResult instance.
36
-
37
- Parameters
38
- ----------
39
- context
40
- The context in which the step is executed.
41
- action_path
42
- The path of actions leading to this step.
43
- group_of_dates
44
- The group of dates associated with this step.
45
- action
46
- The action associated with this step.
47
- upstream_result
48
- The result of the upstream step.
49
- """
50
- super().__init__(context, action_path, group_of_dates)
51
- assert isinstance(upstream_result, Result), type(upstream_result)
52
- self.upstream_result: Result = upstream_result
53
- self.action: Action = action
54
-
55
- @property
56
- @notify_result
57
- @trace_datasource
58
- def datasource(self) -> Any:
59
- """Retrieve the datasource associated with this step result."""
60
- raise NotImplementedError(f"Not implemented in {self.__class__.__name__}")
61
-
62
-
63
- class StepAction(Action):
64
- """Represents an action that is part of a step in the data processing pipeline."""
65
-
66
- result_class: Optional[Type[StepResult]] = None
67
-
68
- def __init__(
69
- self, context: ActionContext, action_path: List[str], previous_step: Any, *args: Any, **kwargs: Any
70
- ) -> None:
71
- """Initialize a StepAction instance.
72
-
73
- Parameters
74
- ----------
75
- context
76
- The context in which the action is executed.
77
- action_path
78
- The path of actions leading to this step.
79
- previous_step
80
- The previous step in the pipeline.
81
- """
82
- super().__init__(context, action_path, *args, **kwargs)
83
- self.previous_step: Any = previous_step
84
-
85
- @trace_select
86
- def select(self, group_of_dates: Any) -> StepResult:
87
- """Select the result for a given group of dates.
88
-
89
- Parameters
90
- ----------
91
- group_of_dates
92
- The group of dates to select the result for.
93
-
94
- Returns
95
- -------
96
- unknown
97
- The result of the step.
98
- """
99
- return self.result_class(
100
- self.context,
101
- self.action_path,
102
- group_of_dates,
103
- self,
104
- self.previous_step.select(group_of_dates),
105
- )
106
-
107
- def __repr__(self) -> str:
108
- """Return a string representation of the StepAction instance.
109
-
110
- Returns
111
- -------
112
- unknown
113
- String representation of the instance.
114
- """
115
- return self._repr(self.previous_step, _inline_=str(self.kwargs))
116
-
117
-
118
- def step_factory(config: Dict[str, Any], context: ActionContext, action_path: List[str], previous_step: Any) -> Any:
119
- """Factory function to create a step action based on the given configuration.
120
-
121
- Parameters
122
- ----------
123
- config
124
- The configuration dictionary for the step.
125
- context
126
- The context in which the step is executed.
127
- action_path
128
- The path of actions leading to this step.
129
- previous_step
130
- The previous step in the pipeline.
131
-
132
- Returns
133
- -------
134
- unknown
135
- An instance of a step action.
136
- """
137
-
138
- from .filter import FilterStepAction
139
- from .filter import FunctionStepAction
140
-
141
- assert isinstance(context, Context), (type, context)
142
- if not isinstance(config, dict):
143
- raise ValueError(f"Invalid input config {config}")
144
-
145
- config = deepcopy(config)
146
- assert len(config) == 1, config
147
-
148
- key = list(config.keys())[0]
149
- cls = dict(
150
- filter=FilterStepAction,
151
- # rename=RenameAction,
152
- # remapping=RemappingAction,
153
- ).get(key)
154
-
155
- if isinstance(config[key], list):
156
- args, kwargs = config[key], {}
157
-
158
- if isinstance(config[key], dict):
159
- args, kwargs = [], config[key]
160
-
161
- if isinstance(config[key], str):
162
- args, kwargs = [config[key]], {}
163
-
164
- if cls is not None:
165
- return cls(context, action_path, previous_step, *args, **kwargs)
166
-
167
- # Try filters from transform filter registry
168
- from anemoi.transform.filters import filter_registry as transform_filter_registry
169
-
170
- if transform_filter_registry.is_registered(key):
171
- from ..filter import TransformFilter
172
-
173
- return FunctionStepAction(
174
- context, action_path + [key], previous_step, key, TransformFilter(context, key, config)
175
- )
176
-
177
- raise ValueError(f"Unknown step action `{key}`")