cloudnetpy 1.61.3__py3-none-any.whl → 1.61.5__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.
- cloudnetpy/categorize/categorize.py +12 -9
- cloudnetpy/categorize/disdrometer.py +4 -0
- cloudnetpy/instruments/disdrometer/thies.py +13 -6
- cloudnetpy/version.py +1 -1
- {cloudnetpy-1.61.3.dist-info → cloudnetpy-1.61.5.dist-info}/METADATA +1 -1
- {cloudnetpy-1.61.3.dist-info → cloudnetpy-1.61.5.dist-info}/RECORD +9 -9
- {cloudnetpy-1.61.3.dist-info → cloudnetpy-1.61.5.dist-info}/LICENSE +0 -0
- {cloudnetpy-1.61.3.dist-info → cloudnetpy-1.61.5.dist-info}/WHEEL +0 -0
- {cloudnetpy-1.61.3.dist-info → cloudnetpy-1.61.5.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,6 @@
|
|
1
1
|
"""Module that generates Cloudnet categorize file."""
|
2
|
+
import logging
|
3
|
+
|
2
4
|
from cloudnetpy import output, utils
|
3
5
|
from cloudnetpy.categorize import atmos, classify
|
4
6
|
from cloudnetpy.categorize.disdrometer import Disdrometer
|
@@ -7,7 +9,7 @@ from cloudnetpy.categorize.model import Model
|
|
7
9
|
from cloudnetpy.categorize.mwr import Mwr
|
8
10
|
from cloudnetpy.categorize.radar import Radar
|
9
11
|
from cloudnetpy.datasource import DataSource
|
10
|
-
from cloudnetpy.exceptions import ValidTimeStampError
|
12
|
+
from cloudnetpy.exceptions import DisdrometerDataError, ValidTimeStampError
|
11
13
|
from cloudnetpy.metadata import MetaData
|
12
14
|
|
13
15
|
|
@@ -61,7 +63,7 @@ def generate_categorize(
|
|
61
63
|
def _interpolate_to_cloudnet_grid() -> list:
|
62
64
|
wl_band = utils.get_wl_band(data["radar"].radar_frequency)
|
63
65
|
data["mwr"].rebin_to_grid(time)
|
64
|
-
if
|
66
|
+
if data["disdrometer"] is not None:
|
65
67
|
data["disdrometer"].interpolate_to_grid(time)
|
66
68
|
data["model"].interpolate_to_common_height(wl_band)
|
67
69
|
model_gap_ind = data["model"].interpolate_to_grid(time, height)
|
@@ -94,7 +96,7 @@ def generate_categorize(
|
|
94
96
|
def _prepare_output() -> dict:
|
95
97
|
data["radar"].add_meta()
|
96
98
|
data["model"].screen_sparse_fields()
|
97
|
-
if
|
99
|
+
if data["disdrometer"] is not None:
|
98
100
|
data["radar"].data.pop("rainfall_rate", None)
|
99
101
|
data["disdrometer"].data.pop("n_particles", None)
|
100
102
|
for key in ("category_bits", "insect_prob"):
|
@@ -111,7 +113,7 @@ def generate_categorize(
|
|
111
113
|
**data["model"].data,
|
112
114
|
**data["model"].data_sparse,
|
113
115
|
**data["mwr"].data,
|
114
|
-
**(data["disdrometer"].data if
|
116
|
+
**(data["disdrometer"].data if data["disdrometer"] is not None else {}),
|
115
117
|
}
|
116
118
|
|
117
119
|
def _define_dense_grid() -> tuple:
|
@@ -123,17 +125,18 @@ def generate_categorize(
|
|
123
125
|
obj.close()
|
124
126
|
|
125
127
|
try:
|
126
|
-
is_disdrometer = "disdrometer" in input_files
|
127
|
-
|
128
128
|
data: dict = {
|
129
129
|
"radar": Radar(input_files["radar"]),
|
130
130
|
"lidar": Lidar(input_files["lidar"]),
|
131
131
|
"mwr": Mwr(input_files["mwr"]),
|
132
132
|
"lv0_files": input_files.get("lv0_files"),
|
133
|
-
"disdrometer":
|
134
|
-
if is_disdrometer
|
135
|
-
else None,
|
133
|
+
"disdrometer": None,
|
136
134
|
}
|
135
|
+
if "disdrometer" in input_files:
|
136
|
+
try:
|
137
|
+
data["disdrometer"] = Disdrometer(input_files["disdrometer"])
|
138
|
+
except DisdrometerDataError as err:
|
139
|
+
logging.warning("Unable to use disdrometer: %s", err)
|
137
140
|
data["model"] = Model(input_files["model"], data["radar"].altitude)
|
138
141
|
time, height = _define_dense_grid()
|
139
142
|
valid_ind = _interpolate_to_cloudnet_grid()
|
@@ -7,6 +7,7 @@ from scipy.interpolate import interp1d
|
|
7
7
|
|
8
8
|
from cloudnetpy.categorize.lidar import get_gap_ind
|
9
9
|
from cloudnetpy.datasource import DataSource
|
10
|
+
from cloudnetpy.exceptions import DisdrometerDataError
|
10
11
|
|
11
12
|
|
12
13
|
class Disdrometer(DataSource):
|
@@ -29,6 +30,9 @@ class Disdrometer(DataSource):
|
|
29
30
|
def _init_rainfall_rate(self) -> None:
|
30
31
|
keys = ("rainfall_rate", "n_particles")
|
31
32
|
for key in keys:
|
33
|
+
if key not in self.dataset.variables:
|
34
|
+
msg = f"variable {key} is missing"
|
35
|
+
raise DisdrometerDataError(msg)
|
32
36
|
self.append_data(self.dataset.variables[key][:], key)
|
33
37
|
|
34
38
|
def _interpolate(self, y: ma.MaskedArray, x_new: np.ndarray) -> np.ndarray:
|
@@ -194,9 +194,13 @@ class Thies(Disdrometer):
|
|
194
194
|
|
195
195
|
def _read_line(self, line: str, timestamp: datetime.datetime | None = None):
|
196
196
|
raw_values = line.split(";")
|
197
|
-
|
197
|
+
# Support custom truncated format used in Leipzig LIM.
|
198
|
+
expected_columns = self.site_meta.get("truncate_columns", 521)
|
199
|
+
if len(raw_values) != expected_columns:
|
198
200
|
return
|
199
201
|
for i, key in TELEGRAM4:
|
202
|
+
if i >= expected_columns - 1:
|
203
|
+
break
|
200
204
|
value: Any
|
201
205
|
if key == "_date":
|
202
206
|
value = _parse_date(raw_values[i])
|
@@ -227,11 +231,12 @@ class Thies(Disdrometer):
|
|
227
231
|
else:
|
228
232
|
value = int(raw_values[i])
|
229
233
|
self.raw_data[key].append(value)
|
230
|
-
|
231
|
-
|
232
|
-
|
234
|
+
if expected_columns > 79:
|
235
|
+
self.raw_data["spectrum"].append(
|
236
|
+
np.array(list(map(int, raw_values[79:-2])), dtype="i2").reshape(
|
237
|
+
self.n_diameter, self.n_velocity
|
238
|
+
)
|
233
239
|
)
|
234
|
-
)
|
235
240
|
if timestamp is not None:
|
236
241
|
self.raw_data["time"].append(timestamp)
|
237
242
|
else:
|
@@ -266,7 +271,9 @@ class Thies(Disdrometer):
|
|
266
271
|
|
267
272
|
def _parse_date(date: str) -> datetime.date:
|
268
273
|
day, month, year = map(int, date.split("."))
|
269
|
-
|
274
|
+
if year < 100:
|
275
|
+
year += 2000
|
276
|
+
return datetime.date(year, month, day)
|
270
277
|
|
271
278
|
|
272
279
|
def _parse_time(time: str) -> datetime.time:
|
cloudnetpy/version.py
CHANGED
@@ -8,14 +8,14 @@ cloudnetpy/metadata.py,sha256=v_VDo2vbdTxB0zIsfP69IcrwSKiRlLpsGdq6JPI4CoA,5306
|
|
8
8
|
cloudnetpy/output.py,sha256=WoVTNuxni0DUr163vZ-_mDr1brXhY15XSlGMrq9Aoqw,14700
|
9
9
|
cloudnetpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
cloudnetpy/utils.py,sha256=0TlHm71YtSrKXBsRKctitnhQrvZPE-ulEVeAQW-oK58,27398
|
11
|
-
cloudnetpy/version.py,sha256=
|
11
|
+
cloudnetpy/version.py,sha256=wWSbFMdT54VpsZJNxnh15y-5LNveGZg6cV6si07cF60,72
|
12
12
|
cloudnetpy/categorize/__init__.py,sha256=gP5q3Vis1y9u9OWgA_idlbjfWXYN_S0IBSWdwBhL_uU,69
|
13
13
|
cloudnetpy/categorize/atmos.py,sha256=fWW8ye_8HZASRAiYwURFKWzcGOYIA2RKeVxCq0lVOuM,12389
|
14
14
|
cloudnetpy/categorize/atmos_utils.py,sha256=wndpwJxc2-QnNTkV8tc8I11Vs_WkNz9sVMX1fuGgUC4,3777
|
15
|
-
cloudnetpy/categorize/categorize.py,sha256=
|
15
|
+
cloudnetpy/categorize/categorize.py,sha256=p3LLBXSu5AOMrJWwAZeS6J-Xzh4PkXuPmOCZiEHzt2w,17678
|
16
16
|
cloudnetpy/categorize/classify.py,sha256=x7aqPfhw4xuER22sqOb9ES9nijwk1E8b7HF7uaFJD7k,9218
|
17
17
|
cloudnetpy/categorize/containers.py,sha256=j6oSKPeZcq9vFthYaocAw1m6yReRNNPYUQF5UTDq4YM,4232
|
18
|
-
cloudnetpy/categorize/disdrometer.py,sha256=
|
18
|
+
cloudnetpy/categorize/disdrometer.py,sha256=daPB1JgERRqa0Ekxx_LYCP8mDe3XnUYj2VlsIKAB7sE,2003
|
19
19
|
cloudnetpy/categorize/droplet.py,sha256=pUmB-gN0t9sVgsGLof6X9N0nuEb4EBtEUswwpoQapTY,8687
|
20
20
|
cloudnetpy/categorize/falling.py,sha256=xES5ZdYs34tbX1p4a9kzt9r3G5s25Mpvs5WeFs1KNzo,4385
|
21
21
|
cloudnetpy/categorize/freezing.py,sha256=684q83TPQ5hHrbbHX-E36VoTlWLSOlGfOW1FC8b3wfI,3754
|
@@ -51,7 +51,7 @@ cloudnetpy/instruments/weather_station.py,sha256=gTY3Y5UATqJo9Gld4hm7WdsKBwcF8Wg
|
|
51
51
|
cloudnetpy/instruments/disdrometer/__init__.py,sha256=lyjwttWvFvuwYxEkusoAvgRcbBmglmOp5HJOpXUqLWo,93
|
52
52
|
cloudnetpy/instruments/disdrometer/common.py,sha256=g52iK2aNp3Z88kovUmGVpC54NZomPa9D871gzO0AmQ4,9267
|
53
53
|
cloudnetpy/instruments/disdrometer/parsivel.py,sha256=WiL-vCjw9Gmb5irvW3AXddsyprp8MGOfqcVAlfy0zpc,25521
|
54
|
-
cloudnetpy/instruments/disdrometer/thies.py,sha256=
|
54
|
+
cloudnetpy/instruments/disdrometer/thies.py,sha256=lNR5ahOKIsO_gcpmbYZwh2UP2aawpQ5J9RrrnPKFFIE,10046
|
55
55
|
cloudnetpy/model_evaluation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
56
56
|
cloudnetpy/model_evaluation/file_handler.py,sha256=oUGIblcEWLLv16YKUch-M5KA-dGRAcuHa-9anP3xtX4,6447
|
57
57
|
cloudnetpy/model_evaluation/metadata.py,sha256=7ZL87iDbaQJIMu8wfnMvb01cGVPkl8RtvEm_tt9uIHE,8413
|
@@ -108,8 +108,8 @@ cloudnetpy/products/mie_lu_tables.nc,sha256=It4fYpqJXlqOgL8jeZ-PxGzP08PMrELIDVe5
|
|
108
108
|
cloudnetpy/products/mwr_tools.py,sha256=PRm5aCULccUehU-Byk55wYhhEHseMjoAjGBu5TSyHao,4621
|
109
109
|
cloudnetpy/products/product_tools.py,sha256=rhx_Ru9FLlQqCNM-awoiHx18-Aq1eBwL9LiUaQoJs6k,10412
|
110
110
|
docs/source/conf.py,sha256=IKiFWw6xhUd8NrCg0q7l596Ck1d61XWeVjIFHVSG9Og,1490
|
111
|
-
cloudnetpy-1.61.
|
112
|
-
cloudnetpy-1.61.
|
113
|
-
cloudnetpy-1.61.
|
114
|
-
cloudnetpy-1.61.
|
115
|
-
cloudnetpy-1.61.
|
111
|
+
cloudnetpy-1.61.5.dist-info/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
|
112
|
+
cloudnetpy-1.61.5.dist-info/METADATA,sha256=yj6xgn1999ZwuQIreZDzaDsYYfX9lnjDmA0oTL93Y4M,5784
|
113
|
+
cloudnetpy-1.61.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
114
|
+
cloudnetpy-1.61.5.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
|
115
|
+
cloudnetpy-1.61.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|