ampycloud 2.2.0__tar.gz → 2.2.1__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.
Files changed (37) hide show
  1. {ampycloud-2.2.0 → ampycloud-2.2.1}/CHANGELOG +6 -0
  2. {ampycloud-2.2.0 → ampycloud-2.2.1}/PKG-INFO +2 -2
  3. {ampycloud-2.2.0 → ampycloud-2.2.1}/README.md +1 -1
  4. {ampycloud-2.2.0 → ampycloud-2.2.1}/pyproject.toml +1 -1
  5. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/wmo.py +31 -20
  6. {ampycloud-2.2.0 → ampycloud-2.2.1}/AUTHORS +0 -0
  7. {ampycloud-2.2.0 → ampycloud-2.2.1}/LICENSE +0 -0
  8. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/__init__.py +0 -0
  9. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/__main__.py +0 -0
  10. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/ceilo_data.py +0 -0
  11. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/cluster.py +0 -0
  12. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/core.py +0 -0
  13. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/data.py +0 -0
  14. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/dynamic.py +0 -0
  15. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/errors.py +0 -0
  16. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/fluffer.py +0 -0
  17. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/hardcoded.py +0 -0
  18. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/icao.py +0 -0
  19. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/layer.py +0 -0
  20. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/logger.py +0 -0
  21. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/metarize.py +0 -0
  22. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/plots/__init__.py +0 -0
  23. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/plots/core.py +0 -0
  24. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/plots/diagnostics.py +0 -0
  25. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/plots/hardcoded.py +0 -0
  26. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/plots/mpl_styles/base.mplstyle +0 -0
  27. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/plots/mpl_styles/latex.mplstyle +0 -0
  28. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/plots/mpl_styles/metsymb.mplstyle +0 -0
  29. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/plots/secondary.py +0 -0
  30. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/plots/tools.py +0 -0
  31. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/prms/ampycloud_default_prms.yml +0 -0
  32. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/scaler.py +0 -0
  33. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/utils/__init__.py +0 -0
  34. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/utils/mocker.py +0 -0
  35. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/utils/performance.py +0 -0
  36. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/utils/utils.py +0 -0
  37. {ampycloud-2.2.0 → ampycloud-2.2.1}/src/ampycloud/version.py +0 -0
@@ -3,6 +3,12 @@ All notable changes to ampycloud will be documented in this file.
3
3
  The format is inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
5
 
6
+ ## [v2.2.1]
7
+ ### Added:
8
+ - [pjuda, 2026-09-14] Fix perc2okta function for consistency with referenced publication
9
+ ### Fixed:
10
+ - [srethore, 2026-09-15] Fix link to the published documentation.
11
+
6
12
  ## [v2.2.0]
7
13
  ### Added:
8
14
  - [srethore, 2026-09-01] Refactor pypi action using trusted publishing
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ampycloud
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: Determining the sky coverage fraction and base height of cloud layers using ceilometer data
5
5
  License-Expression: BSD-3-Clause
6
6
  License-File: AUTHORS
@@ -48,5 +48,5 @@ ampycloud is released under the terms of **the 3-Clause BSD license**. The copyr
48
48
 
49
49
  ### Contributing to ampycloud
50
50
 
51
- Please see the [contributing guidelines](CONTRIBUTING.md) for details.
51
+ Please see the [contributing guidelines](https://github.com/MeteoSwiss/ampycloud/blob/main/CONTRIBUTING.md) for details.
52
52
 
@@ -21,4 +21,4 @@ ampycloud is released under the terms of **the 3-Clause BSD license**. The copyr
21
21
 
22
22
  ### Contributing to ampycloud
23
23
 
24
- Please see the [contributing guidelines](CONTRIBUTING.md) for details.
24
+ Please see the [contributing guidelines](https://github.com/MeteoSwiss/ampycloud/blob/main/CONTRIBUTING.md) for details.
@@ -52,7 +52,7 @@ dev = [
52
52
 
53
53
  [tool.poetry]
54
54
  requires-poetry = ">=2.0,<3.0"
55
- version = "2.2.0" # DO NOT SET. The version of the package is always set by the CI/CD pipeline.
55
+ version = "2.2.1" # DO NOT SET. The version of the package is always set by the CI/CD pipeline.
56
56
  packages = [{ include = "ampycloud", from = "src" }]
57
57
  include = [
58
58
  "CHANGELOG",
@@ -34,15 +34,19 @@ def perc2okta(val: Union[int, float, np.ndarray]) -> np.ndarray:
34
34
  One okta corresponds to 1/8 of the sky covered by clouds. The cases of 0 and 8 oktas are
35
35
  special, in that these indicate that the sky is covered at *exactly* 0%, respectively 100%.
36
36
  This implies that the 1 okta and 7 okta bins are larger than others.
37
+ Each bin's lower bound is inclusive (except 1 okta bin), and its upper bound is exclusive.
37
38
 
38
39
  Specifically:
39
40
 
40
- - 0 okta == val=0
41
- - 1 okta == 0 < val <= 1.5*100/8
42
- - 2 oktas == 1.5*100/8 < val <= 2.5*100/8
43
- - ...
44
- - 7 oktas == 6.5*100/8 < val < 100
45
- - 8 oktas == val=100
41
+ - 0 okta == val = 0
42
+ - 1 okta == 0 < val < 1.5*100/8
43
+ - 2 oktas == 1.5*100/8 <= val < 2.5*100/8
44
+ - 3 oktas == 2.5*100/8 <= val < 3.5*100/8
45
+ - 4 oktas == 3.5*100/8 <= val < 4.5*100/8
46
+ - 5 oktas == 4.5*100/8 <= val < 5.5*100/8
47
+ - 6 oktas == 5.5*100/8 <= val < 6.5*100/8
48
+ - 7 oktas == 6.5*100/8 <= val < 100
49
+ - 8 oktas == val = 100
46
50
 
47
51
  Reference:
48
52
  Boers, R., de Haij, M. J., Wauben, W. M. F., Baltink, H. K., van Ulft, L. H.,
@@ -52,7 +56,7 @@ def perc2okta(val: Union[int, float, np.ndarray]) -> np.ndarray:
52
56
  """
53
57
 
54
58
  # A basic sanity check
55
- if not np.all((val >= 0) * (val <= 100)):
59
+ if not np.all((val >= 0) & (val <= 100)):
56
60
  raise AmpycloudError(f"I need 0<=val<=100, but I got: {val}")
57
61
 
58
62
  # If I did not receive a numpy array, build one to be efficient afterwards ...
@@ -60,19 +64,26 @@ def perc2okta(val: Union[int, float, np.ndarray]) -> np.ndarray:
60
64
  val = np.array([val])
61
65
 
62
66
  # Prepare the out array with floats for now. We will round things later on.
63
- out = np.full_like(val, -1.0, dtype=float)
64
-
65
- # Deal with the edge cases first
66
- out[(val == 0)] = 0
67
- out[(val == 100)] = 8
68
-
69
- # Now deal with the other cases
70
- out[out == -1] = val[out == -1] / (100 / 8)
71
- # Now we round/floor/ceil as required, remembering that the 1 and 7 okta bins are special.
72
- out[out < 1] = np.ceil(out[out < 1])
73
- out[out > 7] = np.floor(out[out > 7])
74
- # Everything else, we just round as usual
75
- out = np.round(out)
67
+ # 0% is already correctly handled by this default value.
68
+ out = np.zeros_like(val, dtype=float)
69
+
70
+ # "Regular" values, i.e. strictly between 0% and 100%.
71
+ is_regular = (val > 0) & (val < 100)
72
+
73
+ # Deal with the only other edge case: exactly 100%.
74
+ out[val == 100] = 8
75
+
76
+ # For the regular values, first get the "raw" fractional okta ...
77
+ out[is_regular] = val[is_regular] / (100 / 8)
78
+ # ... then round it "half up" (e.g. 1.5 -> 2), since each okta bin's lower bound is
79
+ # inclusive and its upper bound is exclusive.
80
+ rounded = np.floor(out[is_regular] + 0.5)
81
+ # The 1 okta and 7 okta bins are wider than the others: any regular value that would
82
+ # otherwise round to 0 or 8 must be clamped back to 1, resp. 7 (0 and 8 are reserved for
83
+ # the exact 0% and 100% edge cases only).
84
+ rounded[rounded == 0] = 1
85
+ rounded[rounded == 8] = 7
86
+ out[is_regular] = rounded
76
87
 
77
88
  # Return ints, to make it clear that we do not work with fractional oktas
78
89
  return out.astype(int)
File without changes
File without changes