cloudnetpy 1.76.0__py3-none-any.whl → 1.76.1__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.
@@ -3,6 +3,7 @@
3
3
  import csv
4
4
  import datetime
5
5
  import logging
6
+ import math
6
7
  import os
7
8
  import re
8
9
  from operator import attrgetter
@@ -206,26 +207,30 @@ class RadiometricsMP:
206
207
  self.data["time"] = np.array(times, dtype="datetime64[s]")
207
208
  self.data["lwp"] = np.array(lwps) # mm => kg m-2
208
209
  self.data["iwv"] = np.array(iwvs) * 10 # cm => kg m-2
209
- self.data["irt"] = _find_closest(
210
- np.array(irt_times, dtype="datetime64[s]"),
211
- np.array(irts),
212
- self.data["time"],
213
- )
214
- self.data["temperature"] = _find_closest(
215
- np.array(temp_times, dtype="datetime64[s]"),
216
- np.array(temps),
217
- self.data["time"],
218
- )
219
- self.data["relative_humidity"] = _find_closest(
220
- np.array(rh_times, dtype="datetime64[s]"),
221
- np.array(rhs) / 100, # % => 1
222
- self.data["time"],
223
- )
224
- self.data["absolute_humidity"] = _find_closest(
225
- np.array(ah_times, dtype="datetime64[s]"),
226
- np.array(ahs) / 1000, # g m-3 => kg m-3
227
- self.data["time"],
228
- )
210
+ if irt_times:
211
+ self.data["irt"] = _find_closest(
212
+ np.array(irt_times, dtype="datetime64[s]"),
213
+ np.array(irts),
214
+ self.data["time"],
215
+ )
216
+ if temp_times:
217
+ self.data["temperature"] = _find_closest(
218
+ np.array(temp_times, dtype="datetime64[s]"),
219
+ np.array(temps),
220
+ self.data["time"],
221
+ )
222
+ if rh_times:
223
+ self.data["relative_humidity"] = _find_closest(
224
+ np.array(rh_times, dtype="datetime64[s]"),
225
+ np.array(rhs) / 100, # % => 1
226
+ self.data["time"],
227
+ )
228
+ if ah_times:
229
+ self.data["absolute_humidity"] = _find_closest(
230
+ np.array(ah_times, dtype="datetime64[s]"),
231
+ np.array(ahs) / 1000, # g m-3 => kg m-3
232
+ self.data["time"],
233
+ )
229
234
 
230
235
 
231
236
  class RadiometricsWVR:
@@ -241,8 +246,8 @@ class RadiometricsWVR:
241
246
  self.ranges: list[str] = []
242
247
 
243
248
  def read_raw_data(self) -> None:
244
- with open(self.filename, encoding="utf8") as infile:
245
- for line in infile:
249
+ with open(self.filename, encoding="utf8") as file:
250
+ for line in file:
246
251
  columns = line.split()
247
252
  if columns[:2] == ["date", "time"]:
248
253
  headers = columns
@@ -250,29 +255,28 @@ class RadiometricsWVR:
250
255
  else:
251
256
  msg = "No headers found"
252
257
  raise RuntimeError(msg)
253
- for key in headers:
254
- self.raw_data[key] = []
255
- for line in infile:
256
- for key, value in zip(headers, line.split(), strict=False):
257
- parsed_value: Any
258
- if key == "date":
259
- month, day, year = map(int, value.split("/"))
260
- if year < 100:
261
- year += 2000
262
- parsed_value = datetime.date(year, month, day)
263
- elif key == "time":
264
- hour, minute, second = map(int, value.split(":"))
265
- parsed_value = datetime.time(hour, minute, second)
258
+ for header in headers:
259
+ self.raw_data[header] = []
260
+ for line in file:
261
+ columns = line.split()
262
+ if len(columns) != len(headers):
263
+ continue
264
+ for header, column in zip(headers, columns, strict=True):
265
+ value: datetime.date | datetime.time | float
266
+ if header == "date":
267
+ value = _parse_date(column)
268
+ elif header == "time":
269
+ value = _parse_time(column)
266
270
  else:
267
- parsed_value = float(value)
268
- self.raw_data[key].append(parsed_value)
271
+ value = _parse_value(column)
272
+ self.raw_data[header].append(value)
269
273
 
270
274
  def read_data(self) -> None:
271
275
  self.data["time"] = np.array(
272
276
  [
273
277
  datetime.datetime.combine(date, time)
274
278
  for date, time in zip(
275
- self.raw_data["date"], self.raw_data["time"], strict=False
279
+ self.raw_data["date"], self.raw_data["time"], strict=True
276
280
  )
277
281
  ],
278
282
  dtype="datetime64[s]",
@@ -280,8 +284,11 @@ class RadiometricsWVR:
280
284
  self.data["lwp"] = np.array(self.raw_data["LiqCM"]) * 10 # cm => kg m-2
281
285
  self.data["iwv"] = np.array(self.raw_data["VapCM"]) * 10 # cm => kg m-2
282
286
  is_zenith = np.abs(np.array(self.raw_data["ELact"]) - 90.0) < 1.0
287
+ tb23_valid = np.array(self.raw_data["TbSky23"]) > 0
288
+ tb31_valid = np.array(self.raw_data["TbSky31"]) > 0
289
+ is_valid = is_zenith & tb23_valid & tb31_valid
283
290
  for key in self.data:
284
- self.data[key] = self.data[key][is_zenith]
291
+ self.data[key] = self.data[key][is_valid]
285
292
 
286
293
 
287
294
  class RadiometricsCombined:
@@ -363,6 +370,22 @@ def _read_file(filename: Path) -> RadiometricsMP | RadiometricsWVR:
363
370
  return obj
364
371
 
365
372
 
373
+ def _parse_value(text: str) -> float:
374
+ return math.nan if "*" in text else float(text)
375
+
376
+
377
+ def _parse_date(text: str) -> datetime.date:
378
+ month, day, year = map(int, text.split("/"))
379
+ if year < 100:
380
+ year += 2000
381
+ return datetime.date(year, month, day)
382
+
383
+
384
+ def _parse_time(text: str) -> datetime.time:
385
+ hour, minute, second = map(int, text.split(":"))
386
+ return datetime.time(hour, minute, second)
387
+
388
+
366
389
  def _parse_datetime(text: str) -> datetime.datetime:
367
390
  date, time = text.split()
368
391
  month, day, year = map(int, date.split("/"))
cloudnetpy/version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  MAJOR = 1
2
2
  MINOR = 76
3
- PATCH = 0
3
+ PATCH = 1
4
4
  __version__ = f"{MAJOR}.{MINOR}.{PATCH}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnetpy
3
- Version: 1.76.0
3
+ Version: 1.76.1
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -9,7 +9,7 @@ cloudnetpy/metadata.py,sha256=lO7BCbVAzFoH3Nq-VuezYX0f7MnbG1Zp11g5GSiuQwM,6189
9
9
  cloudnetpy/output.py,sha256=l0LoOhcGCBrg2EJ4NT1xZ7-UKWdV7X7yQ0fJmhkwJVc,15829
10
10
  cloudnetpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  cloudnetpy/utils.py,sha256=SSZWk82c4nkAiTcLdOKGVvxt5ovETdAMn_TLxVeYpBY,33473
12
- cloudnetpy/version.py,sha256=vHHlyjedUCAOK4akFXnc6Xk6GWb-5gg4KD85wtoljYA,72
12
+ cloudnetpy/version.py,sha256=h_CrP8sn9JN6-YKTFNNaJcVYnr_Y-PGPAYa6HOR0wGo,72
13
13
  cloudnetpy/categorize/__init__.py,sha256=s-SJaysvVpVVo5kidiruWQO6p3gv2TXwY1wEHYO5D6I,44
14
14
  cloudnetpy/categorize/atmos_utils.py,sha256=RcmbKxm2COkE7WEya0mK3yX5rzUbrewRVh3ekm01RtM,10598
15
15
  cloudnetpy/categorize/attenuation.py,sha256=Y_-fzmQTltWTqIZTulJhovC7a6ifpMcaAazDJcnMIOc,990
@@ -49,7 +49,7 @@ cloudnetpy/instruments/mrr.py,sha256=eeAzCp3CiHGauywjwvMUAFwZ4vBOZMcd3IlF8KsrLQo
49
49
  cloudnetpy/instruments/nc_lidar.py,sha256=5gQG9PApnNPrHmS9_zanl8HEYIQuGRpbnzC3wfTcOyQ,1705
50
50
  cloudnetpy/instruments/nc_radar.py,sha256=HlaZeH5939R86ukF8K-P4Kfzb5-CpLB15LU2u94C5eI,7330
51
51
  cloudnetpy/instruments/pollyxt.py,sha256=U3g-ttmcs02LuLwVOydP3GjeNcmDyoYQroB-leIGdHY,10060
52
- cloudnetpy/instruments/radiometrics.py,sha256=__H7KFBcXT0FP8lis3P25MuMa5-S8GrTzKtazMKO678,14822
52
+ cloudnetpy/instruments/radiometrics.py,sha256=_ZBHYiw3u4m0UDPaYRHnx-ofq2FS59Vdv3-fLiOzm9I,15471
53
53
  cloudnetpy/instruments/rain_e_h3.py,sha256=9TdpP4UzMBNIt2iE2GL6K9dFldzTHPLOrU8Q3tcosCU,5317
54
54
  cloudnetpy/instruments/rpg.py,sha256=m3-xLJ-w2T7Ip7jBveWsGrts4tmNvdc-Lb4HebvHQjQ,17319
55
55
  cloudnetpy/instruments/rpg_reader.py,sha256=ThztFuVrWxhmWVAfZTfQDeUiKK1XMTbtv08IBe8GK98,11364
@@ -116,10 +116,10 @@ cloudnetpy/products/lwc.py,sha256=sl6Al2tuH3KkCBrPbWTmuz3jlD5UQJ4D6qBsn1tt2CQ,18
116
116
  cloudnetpy/products/mie_lu_tables.nc,sha256=It4fYpqJXlqOgL8jeZ-PxGzP08PMrELIDVe55y9ob58,16637951
117
117
  cloudnetpy/products/mwr_tools.py,sha256=8HPZpQMTojKZP1JS1S83IE0sxmbDE9bxlaWoqmGnUZE,6199
118
118
  cloudnetpy/products/product_tools.py,sha256=uu4l6reuGbPcW3TgttbaSrqIKbyYGhBVTdnC7opKvmg,11101
119
- cloudnetpy-1.76.0.dist-info/licenses/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
119
+ cloudnetpy-1.76.1.dist-info/licenses/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
120
120
  docs/source/conf.py,sha256=IKiFWw6xhUd8NrCg0q7l596Ck1d61XWeVjIFHVSG9Og,1490
121
- cloudnetpy-1.76.0.dist-info/METADATA,sha256=sefr7DyZ7S4JNZcT_TvGj_b9hxEZOXJp887yXKW0tkg,5796
122
- cloudnetpy-1.76.0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
123
- cloudnetpy-1.76.0.dist-info/entry_points.txt,sha256=HhY7LwCFk4qFgDlXx_Fy983ZTd831WlhtdPIzV-Y3dY,51
124
- cloudnetpy-1.76.0.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
125
- cloudnetpy-1.76.0.dist-info/RECORD,,
121
+ cloudnetpy-1.76.1.dist-info/METADATA,sha256=D879CAfuvaUbCF960Vvrb0Xiik6hijq1yiFREIFjZcE,5796
122
+ cloudnetpy-1.76.1.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
123
+ cloudnetpy-1.76.1.dist-info/entry_points.txt,sha256=HhY7LwCFk4qFgDlXx_Fy983ZTd831WlhtdPIzV-Y3dY,51
124
+ cloudnetpy-1.76.1.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
125
+ cloudnetpy-1.76.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.4.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5