cdo-toolkit 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.
- cdo_toolkit/__init__.py +47 -0
- cdo_toolkit/__main__.py +6 -0
- cdo_toolkit/api.py +573 -0
- cdo_toolkit/cli.py +166 -0
- cdo_toolkit/cmip.py +61 -0
- cdo_toolkit/constants.py +9 -0
- cdo_toolkit/errors.py +79 -0
- cdo_toolkit/memory.py +22 -0
- cdo_toolkit/paths.py +30 -0
- cdo_toolkit/pipeline.py +2230 -0
- cdo_toolkit/resolution.py +19 -0
- cdo_toolkit/timing.py +36 -0
- cdo_toolkit/ui.py +650 -0
- cdo_toolkit/workers.py +277 -0
- cdo_toolkit-0.1.0.dist-info/METADATA +78 -0
- cdo_toolkit-0.1.0.dist-info/RECORD +19 -0
- cdo_toolkit-0.1.0.dist-info/WHEEL +4 -0
- cdo_toolkit-0.1.0.dist-info/entry_points.txt +2 -0
- cdo_toolkit-0.1.0.dist-info/licenses/LICENSE +28 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Resolution parsing helpers."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def calc_resolution(res: str | float | int) -> float:
|
|
7
|
+
"""Parse nominal_resolution metadata into degrees."""
|
|
8
|
+
if isinstance(res, (float, int)):
|
|
9
|
+
return float(res)
|
|
10
|
+
if not res:
|
|
11
|
+
return 9999.0
|
|
12
|
+
res = str(res).lower().replace(" ", "")
|
|
13
|
+
if m := re.match(r"([\d.]+)km", res):
|
|
14
|
+
return float(m.group(1)) / 111.0
|
|
15
|
+
if m := re.match(r"([\d.]+)x([\d.]+)degree", res):
|
|
16
|
+
return (float(m.group(1)) + float(m.group(2))) / 2.0
|
|
17
|
+
if m := re.match(r"([\d.]+)degree", res):
|
|
18
|
+
return float(m.group(1))
|
|
19
|
+
return 9999.0
|
cdo_toolkit/timing.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Timing helpers for progress reporting."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def print_timestamp(console: Console, message: str = "START") -> time.struct_time:
|
|
10
|
+
"""Print a standardized timestamp using a Rich console."""
|
|
11
|
+
timestamp = time.localtime()
|
|
12
|
+
console.print(
|
|
13
|
+
f":clock3: {message}: {time.strftime('%Y-%m-%d %H:%M:%S', timestamp)}\n"
|
|
14
|
+
)
|
|
15
|
+
return timestamp
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_processing_time(start_time: time.struct_time, end_time: Optional[time.struct_time] = None) -> float:
|
|
19
|
+
"""Return elapsed seconds between two struct_time values."""
|
|
20
|
+
if end_time is None:
|
|
21
|
+
end_time = time.localtime()
|
|
22
|
+
return time.mktime(end_time) - time.mktime(start_time)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def format_processing_time(processing_time: Optional[float] = None) -> str:
|
|
26
|
+
"""Format seconds as a human-readable duration string."""
|
|
27
|
+
if processing_time is None:
|
|
28
|
+
return "Timing not available"
|
|
29
|
+
hours = int(processing_time // 3600)
|
|
30
|
+
minutes = int((processing_time % 3600) // 60)
|
|
31
|
+
seconds = int(processing_time % 60)
|
|
32
|
+
if hours > 0:
|
|
33
|
+
return f"{hours}h {minutes}m {seconds}s"
|
|
34
|
+
if minutes > 0:
|
|
35
|
+
return f"{minutes}m {seconds}s"
|
|
36
|
+
return f"{seconds}s"
|