pproc-core 0.1.0__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.
- earthkit/workflows/plugins/pproc/__init__.py +0 -0
- earthkit/workflows/plugins/pproc/_version.py +2 -0
- earthkit/workflows/plugins/pproc/config/accumulation.py +58 -0
- earthkit/workflows/plugins/pproc/config/mask.py +25 -0
- earthkit/workflows/plugins/pproc/config/threshold.py +47 -0
- earthkit/workflows/plugins/pproc/fluent.py +822 -0
- earthkit/workflows/plugins/pproc/metadata/accumulation.py +56 -0
- earthkit/workflows/plugins/pproc/metadata/threshold.py +99 -0
- earthkit/workflows/plugins/pproc/utils/__init__.py +0 -0
- earthkit/workflows/plugins/pproc/utils/metadata.py +31 -0
- earthkit/workflows/plugins/pproc/utils/pydantic_utils.py +9 -0
- earthkit/workflows/plugins/pproc/utils/request.py +117 -0
- ppcore/__init__.py +0 -0
- ppcore/config.py +295 -0
- ppcore/configs/__init__.py +80 -0
- ppcore/configs/common/__init__.py +0 -0
- ppcore/configs/common/accumulation.py +145 -0
- ppcore/configs/common/input.py +71 -0
- ppcore/configs/common/output.py +58 -0
- ppcore/configs/common/preprocessing.py +100 -0
- ppcore/configs/common/source.py +35 -0
- ppcore/configs/common/stats.py +48 -0
- ppcore/configs/common/target.py +42 -0
- ppcore/configs/entrypoint/base.py +46 -0
- ppcore/configs/entrypoint/execution.py +11 -0
- ppcore/configs/entrypoint/log.py +26 -0
- ppcore/configs/product/__init__.py +59 -0
- ppcore/configs/product/ensemble.py +71 -0
- ppcore/product.py +34 -0
- ppcore/products/__init__.py +138 -0
- ppcore/products/base.py +22 -0
- ppcore/products/ensemble.py +153 -0
- ppcore/schema/__init__.py +3 -0
- ppcore/schema/base.py +311 -0
- ppcore/schema/config.py +63 -0
- ppcore/schema/deriver.py +296 -0
- ppcore/schema/filters.py +37 -0
- ppcore/schema/forecast.py +281 -0
- ppcore/schema/input.py +416 -0
- ppcore/schema/schema.py +109 -0
- ppcore/schema/step.py +133 -0
- ppcore/utils/dicts.py +44 -0
- ppcore/utils/entrypoint.py +25 -0
- ppcore/utils/helpers.py +13 -0
- ppcore/utils/io.py +17 -0
- ppcore/utils/mars.py +77 -0
- ppcore/utils/qube.py +27 -0
- ppcore/utils/requests.py +148 -0
- ppcore/utils/stepseq.py +70 -0
- pproc_core-0.1.0.dist-info/METADATA +47 -0
- pproc_core-0.1.0.dist-info/RECORD +55 -0
- pproc_core-0.1.0.dist-info/WHEEL +5 -0
- pproc_core-0.1.0.dist-info/entry_points.txt +3 -0
- pproc_core-0.1.0.dist-info/licenses/LICENSE +79 -0
- pproc_core-0.1.0.dist-info/top_level.txt +2 -0
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 European Centre for Medium-Range Weather Forecasts (ECMWF)
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from typing import Literal, Optional, Union, Annotated
|
|
6
|
+
import datetime
|
|
7
|
+
|
|
8
|
+
from earthkit.time.calendar import MonthInYear
|
|
9
|
+
from earthkit.time.sequence import MonthlySequence
|
|
10
|
+
|
|
11
|
+
from pydantic import Field, ConfigDict
|
|
12
|
+
|
|
13
|
+
from earthkit.workflows.plugins.pproc.utils.pydantic_utils import PProcBaseModel
|
|
14
|
+
|
|
15
|
+
NumericCoord = int
|
|
16
|
+
NumericCoords = Union[list[int], range]
|
|
17
|
+
|
|
18
|
+
Coord = Union[str, NumericCoord]
|
|
19
|
+
Coords = Union[list[str], NumericCoords]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Default(PProcBaseModel):
|
|
23
|
+
model_config = ConfigDict(validate_by_name=True)
|
|
24
|
+
|
|
25
|
+
type_: Literal["default"] = Field("default", alias="type")
|
|
26
|
+
length: Optional[int] = None
|
|
27
|
+
|
|
28
|
+
def name(self, coords: Coords) -> str:
|
|
29
|
+
if len(coords) == 0:
|
|
30
|
+
return ""
|
|
31
|
+
end = coords[-1]
|
|
32
|
+
if len(coords) == 1 and (self.length is None or isinstance(coords[0], str)):
|
|
33
|
+
return f"{end}"
|
|
34
|
+
start = coords[0] if self.length is None else int(end) - self.length
|
|
35
|
+
return f"{start}-{end}"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Monthly(PProcBaseModel):
|
|
39
|
+
model_config = ConfigDict(validate_by_name=True)
|
|
40
|
+
|
|
41
|
+
type_: Literal["monthly"] = Field("monthly", alias="type")
|
|
42
|
+
date: str
|
|
43
|
+
|
|
44
|
+
def name(self, coords: Coords) -> str:
|
|
45
|
+
if len(coords) == 0:
|
|
46
|
+
return ""
|
|
47
|
+
end = coords[-1]
|
|
48
|
+
fcdate = datetime.datetime.strptime(self.date, "%Y%m%d")
|
|
49
|
+
end = int(end)
|
|
50
|
+
seq = MonthlySequence(1)
|
|
51
|
+
seq.next(fcdate, False)
|
|
52
|
+
this_month = fcdate + datetime.timedelta(hours=end - 1)
|
|
53
|
+
month_length = MonthInYear(this_month.year, this_month.month).length() * 24
|
|
54
|
+
start = end - month_length
|
|
55
|
+
return f"{start}-{end}"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
AccumName = Annotated[Union[Default, Monthly], Field(discriminator="type")]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 European Centre for Medium-Range Weather Forecasts (ECMWF)
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from typing import Any, Literal
|
|
6
|
+
|
|
7
|
+
from pydantic import model_validator
|
|
8
|
+
|
|
9
|
+
from earthkit.workflows.plugins.pproc.utils.pydantic_utils import PProcBaseModel
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MaskExpression(PProcBaseModel):
|
|
13
|
+
select: dict
|
|
14
|
+
comparison: Literal["<", ">", ">=", "<=", "==", "!="]
|
|
15
|
+
value: float
|
|
16
|
+
|
|
17
|
+
@model_validator(mode="before")
|
|
18
|
+
@classmethod
|
|
19
|
+
def validate_model(cls, data: Any) -> Any:
|
|
20
|
+
if isinstance(data, list):
|
|
21
|
+
assert (
|
|
22
|
+
len(data) == 3
|
|
23
|
+
), "Mask expression should be a [select, comparison, value] list"
|
|
24
|
+
return {"select": data[0], "comparison": data[1], "value": data[2]}
|
|
25
|
+
return data
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 European Centre for Medium-Range Weather Forecasts (ECMWF)
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from pydantic import model_validator
|
|
6
|
+
from typing import Any, Optional, Literal
|
|
7
|
+
|
|
8
|
+
from earthkit.workflows.plugins.pproc.utils.pydantic_utils import PProcBaseModel
|
|
9
|
+
|
|
10
|
+
Comparisons = Literal["<", ">", "<=", ">="]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Threshold(PProcBaseModel):
|
|
14
|
+
select: Optional[dict] = None
|
|
15
|
+
lower_scale_factor: int = 0
|
|
16
|
+
lower_comparison: Comparisons
|
|
17
|
+
lower_value: float
|
|
18
|
+
upper_scale_factor: int = 0
|
|
19
|
+
upper_comparison: Optional[Comparisons] = None
|
|
20
|
+
upper_value: Optional[float] = None
|
|
21
|
+
|
|
22
|
+
@model_validator(mode="before")
|
|
23
|
+
def validate_threshold(cls, data: Any) -> Any:
|
|
24
|
+
if isinstance(data, dict):
|
|
25
|
+
if "comparison" in data:
|
|
26
|
+
data["lower_comparison"] = data.pop("comparison")
|
|
27
|
+
data["lower_value"] = data.pop("value")
|
|
28
|
+
data["lower_scale_factor"] = data.pop("scale_factor", 0)
|
|
29
|
+
if any(k in data for k in ["upper_comparison", "upper_value"]) and not all(
|
|
30
|
+
k in data for k in ["upper_comparison", "upper_value"]
|
|
31
|
+
):
|
|
32
|
+
raise ValueError(
|
|
33
|
+
"Both upper_comparison and upper_value must be provided together"
|
|
34
|
+
)
|
|
35
|
+
# Derive scale factors for custom thresholds
|
|
36
|
+
for value in ["lower_value", "upper_value"]:
|
|
37
|
+
upper_or_lower = value.split("_")[0]
|
|
38
|
+
if (
|
|
39
|
+
isinstance(data.get(value), float)
|
|
40
|
+
and f"{upper_or_lower}_scale_factor" not in data
|
|
41
|
+
):
|
|
42
|
+
scale_factor = 0
|
|
43
|
+
while abs(data[value] * 10**scale_factor) < 1:
|
|
44
|
+
scale_factor += 1
|
|
45
|
+
data[f"{upper_or_lower}_scale_factor"] = scale_factor
|
|
46
|
+
data[value] = round(data[value] * 10**scale_factor)
|
|
47
|
+
return data
|