anemoi-utils 0.1.7__tar.gz → 0.1.8__tar.gz

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.

Potentially problematic release.


This version of anemoi-utils might be problematic. Click here for more details.

Files changed (41) hide show
  1. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/PKG-INFO +1 -1
  2. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi/utils/_version.py +2 -2
  3. anemoi_utils-0.1.8/src/anemoi/utils/caching.py +59 -0
  4. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi/utils/grib.py +56 -3
  5. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi_utils.egg-info/PKG-INFO +1 -1
  6. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi_utils.egg-info/SOURCES.txt +1 -0
  7. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/tests/test_utils.py +8 -1
  8. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/.github/workflows/python-publish.yml +0 -0
  9. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/.gitignore +0 -0
  10. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/.pre-commit-config.yaml +0 -0
  11. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/.readthedocs.yaml +0 -0
  12. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/LICENSE +0 -0
  13. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/README.md +0 -0
  14. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/Makefile +0 -0
  15. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/_static/logo.png +0 -0
  16. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/_static/style.css +0 -0
  17. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/_templates/.gitkeep +0 -0
  18. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/conf.py +0 -0
  19. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/index.rst +0 -0
  20. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/installing.rst +0 -0
  21. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/modules/checkpoints.rst +0 -0
  22. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/modules/config.rst +0 -0
  23. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/modules/dates.rst +0 -0
  24. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/modules/grib.rst +0 -0
  25. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/modules/humanize.rst +0 -0
  26. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/modules/provenance.rst +0 -0
  27. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/modules/text.rst +0 -0
  28. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/docs/requirements.txt +0 -0
  29. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/pyproject.toml +0 -0
  30. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/setup.cfg +0 -0
  31. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi/utils/__init__.py +0 -0
  32. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi/utils/checkpoints.py +0 -0
  33. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi/utils/config.py +0 -0
  34. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi/utils/dates.py +0 -0
  35. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi/utils/humanize.py +0 -0
  36. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi/utils/provenance.py +0 -0
  37. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi/utils/text.py +0 -0
  38. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi_utils.egg-info/dependency_links.txt +0 -0
  39. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi_utils.egg-info/requires.txt +0 -0
  40. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/src/anemoi_utils.egg-info/top_level.txt +0 -0
  41. {anemoi_utils-0.1.7 → anemoi_utils-0.1.8}/tests/requirements.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: anemoi-utils
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: A package to hold various functions to support training of ML models on ECMWF data.
5
5
  Author-email: "European Centre for Medium-Range Weather Forecasts (ECMWF)" <software.support@ecmwf.int>
6
6
  License: Apache License
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.1.7'
16
- __version_tuple__ = version_tuple = (0, 1, 7)
15
+ __version__ = version = '0.1.8'
16
+ __version_tuple__ = version_tuple = (0, 1, 8)
@@ -0,0 +1,59 @@
1
+ # (C) Copyright 2024 European Centre for Medium-Range Weather Forecasts.
2
+ # This software is licensed under the terms of the Apache Licence Version 2.0
3
+ # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
4
+ # In applying this licence, ECMWF does not waive the privileges and immunities
5
+ # granted to it by virtue of its status as an intergovernmental organisation
6
+ # nor does it submit to any jurisdiction.
7
+
8
+ import hashlib
9
+ import json
10
+ import os
11
+ import time
12
+
13
+
14
+ def cache(key, proc, collection="default", expires=None):
15
+ path = os.path.join(os.path.expanduser("~"), ".cache", "anemoi", collection)
16
+ os.makedirs(path, exist_ok=True)
17
+
18
+ key = json.dumps(key, sort_keys=True)
19
+ m = hashlib.md5()
20
+ m.update(key.encode("utf-8"))
21
+
22
+ filename = os.path.join(path, m.hexdigest())
23
+ if os.path.exists(filename):
24
+ with open(filename, "r") as f:
25
+ data = json.load(f)
26
+ if expires is None or data["expires"] > time.time():
27
+ if data["key"] == key:
28
+ return data["value"]
29
+
30
+ value = proc()
31
+ data = {"key": key, "value": value}
32
+ if expires is not None:
33
+ data["expires"] = time.time() + expires
34
+
35
+ with open(filename, "w") as f:
36
+ json.dump(data, f)
37
+
38
+ return value
39
+
40
+
41
+ class cached:
42
+
43
+ def __init__(self, collection="default", expires=None):
44
+ self.collection = collection
45
+ self.expires = expires
46
+
47
+ def __call__(self, func):
48
+
49
+ full = f"{func.__module__}.{func.__name__}"
50
+
51
+ def wrapped(*args, **kwargs):
52
+ return cache(
53
+ (full, args, kwargs),
54
+ lambda: func(*args, **kwargs),
55
+ self.collection,
56
+ self.expires,
57
+ )
58
+
59
+ return wrapped
@@ -16,10 +16,21 @@ import re
16
16
 
17
17
  import requests
18
18
 
19
+ from .caching import cached
20
+
19
21
  LOG = logging.getLogger(__name__)
20
22
 
21
23
 
22
- def _search(name):
24
+ @cached(collection="grib", expires=30 * 24 * 60 * 60)
25
+ def _units():
26
+ r = requests.get("https://codes.ecmwf.int/parameter-database/api/v1/unit/")
27
+ r.raise_for_status()
28
+ units = r.json()
29
+ return {str(u["id"]): u["name"] for u in units}
30
+
31
+
32
+ @cached(collection="grib", expires=30 * 24 * 60 * 60)
33
+ def _search_param(name):
23
34
  name = re.escape(name)
24
35
  r = requests.get(f"https://codes.ecmwf.int/parameter-database/api/v1/param/?search=^{name}$&regex=true")
25
36
  r.raise_for_status()
@@ -56,7 +67,7 @@ def shortname_to_paramid(shortname: str) -> int:
56
67
  167
57
68
 
58
69
  """
59
- return _search(shortname)["id"]
70
+ return _search_param(shortname)["id"]
60
71
 
61
72
 
62
73
  def paramid_to_shortname(paramid: int) -> str:
@@ -76,4 +87,46 @@ def paramid_to_shortname(paramid: int) -> str:
76
87
  '2t'
77
88
 
78
89
  """
79
- return _search(str(paramid))["shortname"]
90
+ return _search_param(str(paramid))["shortname"]
91
+
92
+
93
+ def units(param) -> str:
94
+ """Return the units of a GRIB parameter given its name or id.
95
+
96
+ Parameters
97
+ ----------
98
+ paramid : int or str
99
+ Parameter id ir name.
100
+
101
+ Returns
102
+ -------
103
+ str
104
+ Parameter unit.
105
+
106
+ >>> unit(167)
107
+ 'K'
108
+
109
+ """
110
+
111
+ unit_id = str(_search_param(str(param))["unit_id"])
112
+ return _units()[unit_id]
113
+
114
+
115
+ def must_be_positive(param):
116
+ """Check if a parameter must be positive.
117
+
118
+ Parameters
119
+ ----------
120
+ param : int or str
121
+ Parameter id or shortname.
122
+
123
+ Returns
124
+ -------
125
+ bool
126
+ True if the parameter must be positive.
127
+
128
+ >>> must_be_positive("tp")
129
+ True
130
+
131
+ """
132
+ return units(param) in ["m", "kg kg**-1", "m of water equivalent"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: anemoi-utils
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: A package to hold various functions to support training of ML models on ECMWF data.
5
5
  Author-email: "European Centre for Medium-Range Weather Forecasts (ECMWF)" <software.support@ecmwf.int>
6
6
  License: Apache License
@@ -22,6 +22,7 @@ docs/modules/provenance.rst
22
22
  docs/modules/text.rst
23
23
  src/anemoi/utils/__init__.py
24
24
  src/anemoi/utils/_version.py
25
+ src/anemoi/utils/caching.py
25
26
  src/anemoi/utils/checkpoints.py
26
27
  src/anemoi/utils/config.py
27
28
  src/anemoi/utils/dates.py
@@ -7,6 +7,8 @@
7
7
 
8
8
 
9
9
  from anemoi.utils.config import DotDict
10
+ from anemoi.utils.grib import paramid_to_shortname
11
+ from anemoi.utils.grib import shortname_to_paramid
10
12
 
11
13
 
12
14
  def test_dotdict():
@@ -26,5 +28,10 @@ def test_dotdict():
26
28
  assert d.d.x == 6
27
29
 
28
30
 
31
+ def test_grib():
32
+ assert shortname_to_paramid("2t") == 167
33
+ assert paramid_to_shortname(167) == "2t"
34
+
35
+
29
36
  if __name__ == "__main__":
30
- test_dotdict()
37
+ test_grib()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes