cloudnetpy 1.71.1__tar.gz → 1.71.3__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 (131) hide show
  1. {cloudnetpy-1.71.1/cloudnetpy.egg-info → cloudnetpy-1.71.3}/PKG-INFO +1 -1
  2. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/campbell_scientific.py +84 -33
  3. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/epsilon.py +3 -0
  4. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/ier.py +2 -2
  5. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/iwc.py +2 -2
  6. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/version.py +1 -1
  7. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3/cloudnetpy.egg-info}/PKG-INFO +1 -1
  8. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/LICENSE +0 -0
  9. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/MANIFEST.in +0 -0
  10. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/README.md +0 -0
  11. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/__init__.py +0 -0
  12. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/__init__.py +0 -0
  13. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/atmos_utils.py +0 -0
  14. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/attenuation.py +0 -0
  15. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
  16. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
  17. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
  18. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
  19. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
  20. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/categorize.py +0 -0
  21. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/classify.py +0 -0
  22. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/containers.py +0 -0
  23. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/disdrometer.py +0 -0
  24. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/droplet.py +0 -0
  25. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/falling.py +0 -0
  26. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/freezing.py +0 -0
  27. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/insects.py +0 -0
  28. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/itu.py +0 -0
  29. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/lidar.py +0 -0
  30. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/melting.py +0 -0
  31. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/model.py +0 -0
  32. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/mwr.py +0 -0
  33. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/categorize/radar.py +0 -0
  34. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/cli.py +0 -0
  35. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/cloudnetarray.py +0 -0
  36. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/concat_lib.py +0 -0
  37. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/constants.py +0 -0
  38. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/datasource.py +0 -0
  39. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/exceptions.py +0 -0
  40. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/__init__.py +0 -0
  41. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/basta.py +0 -0
  42. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/ceilo.py +0 -0
  43. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/ceilometer.py +0 -0
  44. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/cl61d.py +0 -0
  45. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
  46. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/copernicus.py +0 -0
  47. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/disdrometer/__init__.py +0 -0
  48. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/disdrometer/common.py +0 -0
  49. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/disdrometer/parsivel.py +0 -0
  50. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/disdrometer/thies.py +0 -0
  51. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/galileo.py +0 -0
  52. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/hatpro.py +0 -0
  53. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/instruments.py +0 -0
  54. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/lufft.py +0 -0
  55. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/mira.py +0 -0
  56. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/mrr.py +0 -0
  57. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/nc_lidar.py +0 -0
  58. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/nc_radar.py +0 -0
  59. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/pollyxt.py +0 -0
  60. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/radiometrics.py +0 -0
  61. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/rain_e_h3.py +0 -0
  62. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/rpg.py +0 -0
  63. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/rpg_reader.py +0 -0
  64. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/toa5.py +0 -0
  65. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/vaisala.py +0 -0
  66. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/instruments/weather_station.py +0 -0
  67. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/metadata.py +0 -0
  68. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/__init__.py +0 -0
  69. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/file_handler.py +0 -0
  70. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/metadata.py +0 -0
  71. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
  72. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
  73. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
  74. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
  75. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
  76. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
  77. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/products/advance_methods.py +0 -0
  78. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
  79. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
  80. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
  81. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
  82. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/products/tools.py +0 -0
  83. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
  84. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
  85. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
  86. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
  87. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
  88. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
  89. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
  90. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
  91. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
  92. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
  93. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
  94. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
  95. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
  96. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
  97. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
  98. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
  99. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
  100. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
  101. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
  102. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
  103. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
  104. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
  105. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
  106. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
  107. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/model_evaluation/utils.py +0 -0
  108. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/output.py +0 -0
  109. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/plotting/__init__.py +0 -0
  110. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/plotting/plot_meta.py +0 -0
  111. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/plotting/plotting.py +0 -0
  112. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/__init__.py +0 -0
  113. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/classification.py +0 -0
  114. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/der.py +0 -0
  115. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/drizzle.py +0 -0
  116. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/drizzle_error.py +0 -0
  117. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/drizzle_tools.py +0 -0
  118. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/lwc.py +0 -0
  119. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/mie_lu_tables.nc +0 -0
  120. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/mwr_tools.py +0 -0
  121. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/products/product_tools.py +0 -0
  122. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/py.typed +0 -0
  123. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy/utils.py +0 -0
  124. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy.egg-info/SOURCES.txt +0 -0
  125. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy.egg-info/dependency_links.txt +0 -0
  126. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy.egg-info/entry_points.txt +0 -0
  127. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy.egg-info/requires.txt +0 -0
  128. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/cloudnetpy.egg-info/top_level.txt +0 -0
  129. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/docs/source/conf.py +0 -0
  130. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/pyproject.toml +0 -0
  131. {cloudnetpy-1.71.1 → cloudnetpy-1.71.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cloudnetpy
3
- Version: 1.71.1
3
+ Version: 1.71.3
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -1,6 +1,6 @@
1
1
  import binascii
2
+ import datetime
2
3
  import re
3
- from datetime import datetime, timezone
4
4
  from typing import NamedTuple
5
5
 
6
6
  import numpy as np
@@ -11,6 +11,34 @@ from cloudnetpy.instruments import instruments
11
11
  from cloudnetpy.instruments.ceilometer import Ceilometer
12
12
 
13
13
 
14
+ def _date_format_to_regex(fmt: bytes) -> bytes:
15
+ """Converts a date format string to a regex pattern."""
16
+ mapping = {
17
+ b"%Y": rb"\d{4}",
18
+ b"%m": rb"0[1-9]|1[0-2]",
19
+ b"%d": rb"0[1-9]|[12]\d|3[01]",
20
+ b"%H": rb"[01]\d|2[0-3]",
21
+ b"%M": rb"[0-5]\d",
22
+ b"%S": rb"[0-5]\d",
23
+ b"%f": rb"\d{6}",
24
+ }
25
+ pattern = re.escape(fmt)
26
+ for key, value in mapping.items():
27
+ pattern = pattern.replace(
28
+ re.escape(key), b"(?P<" + key[1:] + b">" + value + b")"
29
+ )
30
+ return pattern
31
+
32
+
33
+ FORMATS = [
34
+ re.compile(_date_format_to_regex(fmt))
35
+ for fmt in [
36
+ b"%Y-%m-%dT%H:%M:%S.%f,",
37
+ b"%%% %Y/%m/%d %H:%M:%S %%%\n",
38
+ ]
39
+ ]
40
+
41
+
14
42
  class Cs135(Ceilometer):
15
43
  def __init__(
16
44
  self,
@@ -34,25 +62,34 @@ class Cs135(Ceilometer):
34
62
  tilt_angles = []
35
63
  range_resolutions = []
36
64
 
37
- parts = re.split(rb"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}),", content)
38
- for i in range(1, len(parts), 2):
39
- timestamp = datetime.strptime(
40
- parts[i].decode(),
41
- "%Y-%m-%dT%H:%M:%S.%f",
42
- ).replace(tzinfo=timezone.utc)
43
- try:
44
- self._check_timestamp(timestamp)
45
- except ValidTimeStampError:
46
- continue
47
- try:
48
- message = _read_message(parts[i + 1])
49
- except InvalidMessageError:
50
- continue
51
- profile = (message.data[:-2] * 1e-8) * (message.scale / 100)
52
- timestamps.append(timestamp)
53
- profiles.append(profile)
54
- tilt_angles.append(message.tilt_angle)
55
- range_resolutions.append(message.range_resolution)
65
+ for fmt in FORMATS:
66
+ parts = re.split(fmt, content)
67
+ for i in range(1, len(parts), fmt.groups + 1):
68
+ timestamp = datetime.datetime(
69
+ int(parts[i + fmt.groupindex["Y"] - 1]),
70
+ int(parts[i + fmt.groupindex["m"] - 1]),
71
+ int(parts[i + fmt.groupindex["d"] - 1]),
72
+ int(parts[i + fmt.groupindex["H"] - 1]),
73
+ int(parts[i + fmt.groupindex["M"] - 1]),
74
+ int(parts[i + fmt.groupindex["S"] - 1]),
75
+ int(parts[i + fmt.groupindex["f"] - 1])
76
+ if "f" in fmt.groupindex
77
+ else 0,
78
+ tzinfo=datetime.timezone.utc,
79
+ )
80
+ try:
81
+ self._check_timestamp(timestamp)
82
+ except ValidTimeStampError:
83
+ continue
84
+ try:
85
+ message = _read_message(parts[i + fmt.groups])
86
+ except InvalidMessageError:
87
+ continue
88
+ profile = (message.data[:-2] * 1e-8) * (message.scale / 100)
89
+ timestamps.append(timestamp)
90
+ profiles.append(profile)
91
+ tilt_angles.append(message.tilt_angle)
92
+ range_resolutions.append(message.range_resolution)
56
93
 
57
94
  if len(timestamps) == 0:
58
95
  msg = "No valid timestamps found in the file"
@@ -77,7 +114,7 @@ class Cs135(Ceilometer):
77
114
  self.data["time"] = utils.datetime2decimal_hours(timestamps)
78
115
  self.data["zenith_angle"] = np.median(tilt_angles)
79
116
 
80
- def _check_timestamp(self, timestamp: datetime) -> None:
117
+ def _check_timestamp(self, timestamp: datetime.datetime) -> None:
81
118
  timestamp_components = str(timestamp.date()).split("-")
82
119
  if (
83
120
  self.expected_date is not None
@@ -119,19 +156,33 @@ def _read_message(message: bytes) -> Message:
119
156
  f"got {actual_checksum:04x}"
120
157
  )
121
158
  raise InvalidMessageError(msg)
122
- lines = message.splitlines()
123
- if len(lines[0]) != 11:
124
- msg = f"Expected 11 characters in first line, got {len(lines[0])}"
159
+ lines = message[1 : end_idx - 1].splitlines()
160
+ n_lines = len(lines) + 1
161
+ n_first = len(lines[0]) + 1
162
+ if n_first != 11:
163
+ msg = f"Expected 11 characters in first line, got {n_first}"
125
164
  raise NotImplementedError(msg)
126
- if (msg_no := lines[0][-4:-1]) != b"002":
127
- msg = f"Message number {msg_no.decode()} not implemented"
128
- raise NotImplementedError(msg)
129
- if len(lines) != 5:
130
- msg = f"Expected 5 lines, got {len(lines)}"
131
- raise InvalidMessageError(msg)
132
- scale, res, n, energy, lt, ti, bl, pulse, rate, _sum = map(int, lines[2].split())
133
- data = _read_backscatter(lines[3].strip(), n)
134
- return Message(scale, res, energy, lt, ti, bl, pulse, rate, data)
165
+ msg_no = lines[0][-4:-1]
166
+ if msg_no == b"002":
167
+ if n_lines != 5:
168
+ msg = f"Expected 5 lines, got {len(lines)}"
169
+ raise InvalidMessageError(msg)
170
+ scale, res, n, energy, lt, ti, bl, pulse, rate, _sum = map(
171
+ int, lines[2].split()
172
+ )
173
+ data = _read_backscatter(lines[3].strip(), n)
174
+ return Message(scale, res, energy, lt, ti, bl, pulse, rate, data)
175
+ if msg_no == b"004":
176
+ if n_lines != 6:
177
+ msg = f"Expected 6 lines, got {len(lines)}"
178
+ raise InvalidMessageError(msg)
179
+ scale, res, n, energy, lt, ti, bl, pulse, rate, _sum = map(
180
+ int, lines[3].split()
181
+ )
182
+ data = _read_backscatter(lines[4].strip(), n)
183
+ return Message(scale, res, energy, lt, ti, bl, pulse, rate, data)
184
+ msg = f"Message number {msg_no.decode()} not implemented"
185
+ raise NotImplementedError(msg)
135
186
 
136
187
 
137
188
  def _read_backscatter(data: bytes, n_gates: int) -> np.ndarray:
@@ -11,6 +11,7 @@ from doppy.product.turbulence import HorizontalWind, Options, Turbulence, Vertic
11
11
  from scipy.interpolate import LinearNDInterpolator, NearestNDInterpolator
12
12
 
13
13
  import cloudnetpy
14
+ from cloudnetpy.exceptions import ValidTimeStampError
14
15
  from cloudnetpy.output import copy_variables
15
16
  from cloudnetpy.utils import get_time, get_uuid
16
17
 
@@ -131,6 +132,8 @@ def _horizontal_wind_from_doppler_lidar_file(
131
132
  vmask = np.array(nc["vwind"][:].mask, dtype=np.bool_)
132
133
  V = np.sqrt(uwind**2 + vwind**2)
133
134
  mask = umask | vmask
135
+ if np.all(mask):
136
+ raise ValidTimeStampError
134
137
  t = np.broadcast_to(time[:, None], mask.shape)[~mask]
135
138
  h = np.broadcast_to(height[None, :], mask.shape)[~mask]
136
139
  interp_linear = LinearNDInterpolator(list(zip(t, h, strict=False)), V[~mask])
@@ -83,9 +83,9 @@ class IerSource(IceSource):
83
83
 
84
84
 
85
85
  def _add_ier_comment(attributes: dict, ier: IerSource) -> dict:
86
- freq = ier.radar_frequency
86
+ freq = round(ier.radar_frequency, 3)
87
87
  coeffs = ier.coefficients
88
- factor = np.round((coeffs[0] / 0.93), 3)
88
+ factor = round(coeffs[0] / 0.93, 3)
89
89
  attributes["ier"] = attributes["ier"]._replace(
90
90
  comment=f"This variable was calculated from the {freq}-GHz radar\n"
91
91
  f"reflectivity factor after correction for gaseous attenuation,\n"
@@ -113,9 +113,9 @@ def _add_iwc_error_comment(attributes: dict, lwp_prior, uncertainty: float) -> d
113
113
 
114
114
 
115
115
  def _add_iwc_comment(attributes: dict, iwc: IwcSource) -> dict:
116
- freq = iwc.radar_frequency
116
+ freq = round(iwc.radar_frequency, 3)
117
117
  coeffs = iwc.coefficients
118
- factor = round((coeffs[0] / 0.93) * 1000) / 1000
118
+ factor = round(coeffs[0] / 0.93, 3)
119
119
  attributes["iwc"] = attributes["iwc"]._replace(
120
120
  comment=f"This variable was calculated from the {freq}-GHz radar reflectivity\n"
121
121
  "factor after correction for gaseous attenuation, and temperature taken from\n"
@@ -1,4 +1,4 @@
1
1
  MAJOR = 1
2
2
  MINOR = 71
3
- PATCH = 1
3
+ PATCH = 3
4
4
  __version__ = f"{MAJOR}.{MINOR}.{PATCH}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cloudnetpy
3
- Version: 1.71.1
3
+ Version: 1.71.3
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
File without changes
File without changes
File without changes
File without changes
File without changes