cloudnetpy 1.96.4__tar.gz → 1.96.6__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 (148) hide show
  1. {cloudnetpy-1.96.4/cloudnetpy.egg-info → cloudnetpy-1.96.6}/PKG-INFO +1 -1
  2. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/cli.py +9 -4
  3. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/disdronator/process.py +5 -0
  4. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/mira.py +64 -3
  5. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/version.py +1 -1
  6. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6/cloudnetpy.egg-info}/PKG-INFO +1 -1
  7. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/LICENSE +0 -0
  8. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/MANIFEST.in +0 -0
  9. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/README.md +0 -0
  10. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/__init__.py +0 -0
  11. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/arm.py +0 -0
  12. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/__init__.py +0 -0
  13. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/atmos_utils.py +0 -0
  14. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/attenuation.py +0 -0
  15. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
  16. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
  17. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
  18. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
  19. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
  20. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/categorize.py +0 -0
  21. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/classify.py +0 -0
  22. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/containers.py +0 -0
  23. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/disdrometer.py +0 -0
  24. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/droplet.py +0 -0
  25. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/falling.py +0 -0
  26. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/freezing.py +0 -0
  27. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/insects.py +0 -0
  28. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/lidar.py +0 -0
  29. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/melting.py +0 -0
  30. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/model.py +0 -0
  31. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/mwr.py +0 -0
  32. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/categorize/radar.py +0 -0
  33. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/cloudnetarray.py +0 -0
  34. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/concat_lib.py +0 -0
  35. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/constants.py +0 -0
  36. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/datasource.py +0 -0
  37. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/disdronator/__init__.py +0 -0
  38. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/disdronator/lpm.py +0 -0
  39. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/disdronator/parsivel.py +0 -0
  40. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/disdronator/rd80.py +0 -0
  41. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/disdronator/utils.py +0 -0
  42. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/exceptions.py +0 -0
  43. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/__init__.py +0 -0
  44. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/arm_ceilo.py +0 -0
  45. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/arm_ld.py +0 -0
  46. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/arm_utils.py +0 -0
  47. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/basta.py +0 -0
  48. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/bowtie.py +0 -0
  49. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/ceilo.py +0 -0
  50. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/ceilometer.py +0 -0
  51. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/cl61d.py +0 -0
  52. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
  53. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/copernicus.py +0 -0
  54. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/da10.py +0 -0
  55. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/dealias.py +0 -0
  56. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/disdrometer.py +0 -0
  57. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/fd12p.py +0 -0
  58. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/galileo.py +0 -0
  59. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/hatpro.py +0 -0
  60. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/instruments.py +0 -0
  61. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/kazr.py +0 -0
  62. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/lufft.py +0 -0
  63. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/mmcr.py +0 -0
  64. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/mrr.py +0 -0
  65. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/mwr3c.py +0 -0
  66. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/mwrlos.py +0 -0
  67. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/nc_lidar.py +0 -0
  68. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/nc_radar.py +0 -0
  69. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/pollyxt.py +0 -0
  70. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/radiometrics.py +0 -0
  71. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/rain_e_h3.py +0 -0
  72. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/rpg.py +0 -0
  73. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/rpg_reader.py +0 -0
  74. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/toa5.py +0 -0
  75. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/vaisala.py +0 -0
  76. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/weather_radar.py +0 -0
  77. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/instruments/weather_station.py +0 -0
  78. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/metadata.py +0 -0
  79. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/__init__.py +0 -0
  80. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/file_handler.py +0 -0
  81. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/metadata.py +0 -0
  82. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
  83. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
  84. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
  85. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
  86. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
  87. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
  88. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/products/advance_methods.py +0 -0
  89. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
  90. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
  91. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
  92. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
  93. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/products/tools.py +0 -0
  94. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
  95. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
  96. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
  97. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
  98. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
  99. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
  100. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
  101. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
  102. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
  103. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
  104. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
  105. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
  106. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
  107. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
  108. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
  109. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
  110. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
  111. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
  112. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
  113. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
  114. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
  115. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
  116. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
  117. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
  118. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/model_evaluation/utils.py +0 -0
  119. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/output.py +0 -0
  120. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/plotting/__init__.py +0 -0
  121. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/plotting/plot_meta.py +0 -0
  122. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/plotting/plotting.py +0 -0
  123. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/__init__.py +0 -0
  124. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/classification.py +0 -0
  125. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/cod.py +0 -0
  126. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/der.py +0 -0
  127. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/drizzle.py +0 -0
  128. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/drizzle_error.py +0 -0
  129. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/drizzle_tools.py +0 -0
  130. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/epsilon_lidar.py +0 -0
  131. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/epsilon_radar.py +0 -0
  132. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/ier.py +0 -0
  133. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/iwc.py +0 -0
  134. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/iwc_weather_radar.py +0 -0
  135. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/lwc.py +0 -0
  136. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/mie_lu_tables.nc +0 -0
  137. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/mwr_tools.py +0 -0
  138. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/products/product_tools.py +0 -0
  139. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/py.typed +0 -0
  140. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy/utils.py +0 -0
  141. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy.egg-info/SOURCES.txt +0 -0
  142. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy.egg-info/dependency_links.txt +0 -0
  143. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy.egg-info/entry_points.txt +0 -0
  144. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy.egg-info/requires.txt +0 -0
  145. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/cloudnetpy.egg-info/top_level.txt +0 -0
  146. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/docs/source/conf.py +0 -0
  147. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/pyproject.toml +0 -0
  148. {cloudnetpy-1.96.4 → cloudnetpy-1.96.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnetpy
3
- Version: 1.96.4
3
+ Version: 1.96.6
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -2,6 +2,7 @@ import argparse
2
2
  import base64
3
3
  import concurrent.futures
4
4
  import datetime
5
+ import functools
5
6
  import gzip
6
7
  import hashlib
7
8
  import importlib
@@ -385,9 +386,8 @@ def _process_instrument_product(
385
386
  fun: Callable
386
387
  match (product, instrument.instrument_id):
387
388
  case ("radar", _id) if "mira" in _id:
388
- site_meta["range_correction_factor"] = calibration.get(
389
- "range_correction_factor"
390
- )
389
+ for key in ("range_correction_factor", "radar_constant"):
390
+ site_meta[key] = calibration.get(key)
391
391
  fun = instruments.mira2nc
392
392
  case ("radar", _id) if "rpg" in _id:
393
393
  fun = instruments.rpg2nc
@@ -401,7 +401,12 @@ def _process_instrument_product(
401
401
  case ("radar", _id) if "galileo" in _id:
402
402
  fun = instruments.galileo2nc
403
403
  case ("disdrometer", _id) if "parsivel" in _id:
404
- fun = instruments.parsivel2nc
404
+ fun = functools.partial(
405
+ instruments.parsivel2nc,
406
+ telegram=calibration.get("telegram"),
407
+ field_separator=calibration.get("field_separator", ";"),
408
+ decimal_separator=calibration.get("decimal_separator", "."),
409
+ )
405
410
  case ("disdrometer", _id) if "thies" in _id:
406
411
  fun = instruments.thies2nc
407
412
  case ("disdrometer", _id) if "rd-80" in _id:
@@ -53,6 +53,11 @@ def process_l2(l1: DisdroL1) -> DisdroL2:
53
53
  data_raw = l1.data_raw[time_ind]
54
54
  interval = l1.interval[time_ind]
55
55
 
56
+ is_valid = interval > 0
57
+ time = time[is_valid]
58
+ data_raw = data_raw[is_valid]
59
+ interval = interval[is_valid]
60
+
56
61
  n_time = len(time)
57
62
  n_diameter = len(l1.diameter)
58
63
  n_particles = data_raw.reshape(n_time, -1).sum(axis=1)
@@ -42,7 +42,8 @@ def mira2nc(
42
42
  output_file: Output filename.
43
43
  site_meta: Dictionary containing information about the site. Required
44
44
  key-value pair is `name`. Optional `model` takes `mira-35` (default),
45
- `mira-35s`, `mira-35c`, or `mira-10`.
45
+ `mira-35s`, `mira-35c`, or `mira-10`. Optional `radar_constant` (dB)
46
+ is used to calculate Zh from SNRg in old files without Zg.
46
47
  uuid: Set specific UUID for the file.
47
48
  date: Expected date as YYYY-MM-DD of all profiles in the file.
48
49
 
@@ -78,8 +79,9 @@ def mira2nc(
78
79
  mira.date = date
79
80
  mira.sort_timestamps()
80
81
  mira.remove_duplicate_timestamps()
81
- mira.linear_to_db(("Zh", "ldr", "SNR"))
82
82
  mira.screen_low_power()
83
+ mira.add_zh_from_snr()
84
+ mira.linear_to_db(("Zh", "ldr", "SNR"))
83
85
 
84
86
  if "snr_limit" in site_meta and site_meta["snr_limit"] is not None:
85
87
  snr_limit = site_meta["snr_limit"]
@@ -240,6 +242,58 @@ class Mira(NcRadar):
240
242
  self.data["tpow"].data[:] *= 100
241
243
  self.data["tpow"].correction_factor = 100
242
244
 
245
+ def add_zh_from_snr(self) -> None:
246
+ """Calculates unfiltered Zh from SNRg in old mmclx files without Zg.
247
+
248
+ Old files contain only Ze, where signal classified as plankton
249
+ (insects) has been removed. Zh is calculated as
250
+ SNRg * range^2 * K / tpow, where the radar constant K (dB) is given
251
+ in `site_meta["radar_constant"]`. Without it, K is estimated from
252
+ Ze in the file.
253
+
254
+ Example case:
255
+
256
+ - Lindenberg 2007-06-16: K = -81.61 dB
257
+ """
258
+ if "Zg" in self.dataset.variables or "SNR" not in self.data:
259
+ return
260
+ if "tpow" not in self.data:
261
+ logging.warning("Variable tpow missing, can not calculate Zh from SNRg")
262
+ return
263
+ radar_constant = self.site_meta.get("radar_constant")
264
+ if radar_constant is None:
265
+ radar_constant = self._estimate_radar_constant()
266
+ if radar_constant is None:
267
+ logging.warning("Can not estimate radar_constant, using Ze")
268
+ return
269
+ logging.warning(
270
+ "No radar_constant given, using estimate from file: %s dB",
271
+ radar_constant,
272
+ )
273
+ logging.info("Variable Zg missing, calculating Zh from SNRg")
274
+ snrg = self.data["SNR"][:]
275
+ range_sq = np.array(self.getvar("range")) ** 2
276
+ tpow = self.data["tpow"][:]
277
+ factor = utils.db2lin(float(radar_constant)) / tpow
278
+ self.append_data(snrg * range_sq * factor[:, np.newaxis], "Zh")
279
+ self.data["radar_constant"] = CloudnetArray(
280
+ float(radar_constant), "radar_constant"
281
+ )
282
+
283
+ def _estimate_radar_constant(self) -> float | None:
284
+ """Estimates radar constant K (dB) from Ze = SNR * range^2 * K / tpow."""
285
+ try:
286
+ ze = ma.masked_less_equal(ma.masked_invalid(self.getvar("Ze")), 0)
287
+ snr = ma.masked_less_equal(ma.masked_invalid(self.getvar("SNR")), 0)
288
+ tpow = self.getvar("tpow")
289
+ except KeyError:
290
+ return None
291
+ range_sq = np.array(self.getvar("range")) ** 2
292
+ factor = ma.median(ze / (snr * range_sq), axis=1) * tpow
293
+ if ma.getmaskarray(factor).all():
294
+ return None
295
+ return round(float(utils.lin2db(ma.median(factor))), 2)
296
+
243
297
  def screen_invalid_ldr(self) -> None:
244
298
  """Masks LDR in MIRA STSR mode data.
245
299
  Is there a better way to identify this mode?
@@ -309,7 +363,8 @@ def _parse_input_files(
309
363
 
310
364
  keymap = _get_keymap(filetypes[0])
311
365
 
312
- variables = list(keymap.keys())
366
+ # SNR and Ze are needed to recover Zh in old files without Zg
367
+ variables = [*keymap.keys(), "SNR"]
313
368
  concat_lib.concatenate_files(
314
369
  valid_files,
315
370
  input_filename,
@@ -418,6 +473,12 @@ ATTRIBUTES = {
418
473
  "tpow": MetaData(
419
474
  long_name="Average Transmit Power", units="W", dimensions=("time",)
420
475
  ),
476
+ "radar_constant": MetaData(
477
+ long_name="Radar constant",
478
+ units="dB",
479
+ comment="Zh = SNRg * range^2 * radar_constant / tpow",
480
+ dimensions=None,
481
+ ),
421
482
  "zenith_offset": MetaData(
422
483
  long_name="Zenith offset of the instrument",
423
484
  units="degrees",
@@ -1,4 +1,4 @@
1
1
  MAJOR = 1
2
2
  MINOR = 96
3
- PATCH = 4
3
+ PATCH = 6
4
4
  __version__ = f"{MAJOR}.{MINOR}.{PATCH}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnetpy
3
- Version: 1.96.4
3
+ Version: 1.96.6
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