cloudnetpy 1.95.5__tar.gz → 1.95.7__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 (147) hide show
  1. {cloudnetpy-1.95.5/cloudnetpy.egg-info → cloudnetpy-1.95.7}/PKG-INFO +1 -1
  2. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/classify.py +3 -1
  3. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/containers.py +2 -0
  4. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/cli.py +18 -0
  5. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/arm_ceilo.py +2 -0
  6. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/kazr.py +28 -6
  7. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/plotting/plotting.py +9 -1
  8. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/version.py +1 -1
  9. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7/cloudnetpy.egg-info}/PKG-INFO +1 -1
  10. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/LICENSE +0 -0
  11. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/MANIFEST.in +0 -0
  12. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/README.md +0 -0
  13. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/__init__.py +0 -0
  14. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/arm.py +0 -0
  15. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/__init__.py +0 -0
  16. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/atmos_utils.py +0 -0
  17. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/attenuation.py +0 -0
  18. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
  19. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
  20. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
  21. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
  22. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
  23. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/categorize.py +0 -0
  24. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/disdrometer.py +0 -0
  25. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/droplet.py +0 -0
  26. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/falling.py +0 -0
  27. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/freezing.py +0 -0
  28. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/insects.py +0 -0
  29. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/lidar.py +0 -0
  30. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/melting.py +0 -0
  31. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/model.py +0 -0
  32. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/mwr.py +0 -0
  33. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/categorize/radar.py +0 -0
  34. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/cloudnetarray.py +0 -0
  35. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/concat_lib.py +0 -0
  36. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/constants.py +0 -0
  37. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/datasource.py +0 -0
  38. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/disdronator/__init__.py +0 -0
  39. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/disdronator/lpm.py +0 -0
  40. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/disdronator/parsivel.py +0 -0
  41. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/disdronator/process.py +0 -0
  42. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/disdronator/rd80.py +0 -0
  43. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/disdronator/utils.py +0 -0
  44. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/exceptions.py +0 -0
  45. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/__init__.py +0 -0
  46. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/arm_ld.py +0 -0
  47. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/arm_utils.py +0 -0
  48. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/basta.py +0 -0
  49. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/bowtie.py +0 -0
  50. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/ceilo.py +0 -0
  51. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/ceilometer.py +0 -0
  52. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/cl61d.py +0 -0
  53. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
  54. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/copernicus.py +0 -0
  55. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/da10.py +0 -0
  56. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/dealias.py +0 -0
  57. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/disdrometer.py +0 -0
  58. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/fd12p.py +0 -0
  59. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/galileo.py +0 -0
  60. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/hatpro.py +0 -0
  61. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/instruments.py +0 -0
  62. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/lufft.py +0 -0
  63. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/mira.py +0 -0
  64. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/mmcr.py +0 -0
  65. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/mrr.py +0 -0
  66. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/mwr3c.py +0 -0
  67. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/mwrlos.py +0 -0
  68. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/nc_lidar.py +0 -0
  69. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/nc_radar.py +0 -0
  70. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/pollyxt.py +0 -0
  71. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/radiometrics.py +0 -0
  72. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/rain_e_h3.py +0 -0
  73. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/rpg.py +0 -0
  74. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/rpg_reader.py +0 -0
  75. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/toa5.py +0 -0
  76. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/vaisala.py +0 -0
  77. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/weather_radar.py +0 -0
  78. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/instruments/weather_station.py +0 -0
  79. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/metadata.py +0 -0
  80. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/__init__.py +0 -0
  81. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/file_handler.py +0 -0
  82. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/metadata.py +0 -0
  83. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
  84. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
  85. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
  86. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
  87. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
  88. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
  89. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/products/advance_methods.py +0 -0
  90. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
  91. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
  92. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
  93. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
  94. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/products/tools.py +0 -0
  95. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
  96. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
  97. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
  98. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
  99. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
  100. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
  101. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
  102. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
  103. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
  104. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
  105. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
  106. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
  107. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
  108. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
  109. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
  110. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
  111. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
  112. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
  113. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
  114. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
  115. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
  116. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
  117. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
  118. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
  119. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/model_evaluation/utils.py +0 -0
  120. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/output.py +0 -0
  121. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/plotting/__init__.py +0 -0
  122. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/plotting/plot_meta.py +0 -0
  123. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/__init__.py +0 -0
  124. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/classification.py +0 -0
  125. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/der.py +0 -0
  126. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/drizzle.py +0 -0
  127. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/drizzle_error.py +0 -0
  128. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/drizzle_tools.py +0 -0
  129. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/epsilon_lidar.py +0 -0
  130. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/epsilon_radar.py +0 -0
  131. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/ier.py +0 -0
  132. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/iwc.py +0 -0
  133. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/iwc_weather_radar.py +0 -0
  134. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/lwc.py +0 -0
  135. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/mie_lu_tables.nc +0 -0
  136. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/mwr_tools.py +0 -0
  137. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/products/product_tools.py +0 -0
  138. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/py.typed +0 -0
  139. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy/utils.py +0 -0
  140. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy.egg-info/SOURCES.txt +0 -0
  141. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy.egg-info/dependency_links.txt +0 -0
  142. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy.egg-info/entry_points.txt +0 -0
  143. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy.egg-info/requires.txt +0 -0
  144. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/cloudnetpy.egg-info/top_level.txt +0 -0
  145. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/docs/source/conf.py +0 -0
  146. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/pyproject.toml +0 -0
  147. {cloudnetpy-1.95.5 → cloudnetpy-1.95.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnetpy
3
- Version: 1.95.5
3
+ Version: 1.95.7
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -62,7 +62,9 @@ def classify_measurements(data: Observations) -> ClassificationResult:
62
62
 
63
63
  bits.melting = melting.find_melting_layer(obs)
64
64
  bits.freezing = freezing.find_freezing_region(obs, bits.melting)
65
- liquid_from_lidar = droplet.find_liquid(obs)
65
+ # Vaisala CL51/CL61 have reliable near-range data, so allow lower liquid peaks
66
+ is_cl = any(model in obs.lidar_type.lower() for model in ("cl51", "cl61"))
67
+ liquid_from_lidar = droplet.find_liquid(obs, min_alt=70 if is_cl else 100)
66
68
  if obs.lv0_files is not None and len(obs.lv0_files) > 0:
67
69
  if "rpg-fmcw-94" not in obs.radar_type.lower():
68
70
  msg = "VoodooNet is only implemented for RPG-FMCW-94 radar."
@@ -56,6 +56,7 @@ class ClassData:
56
56
  height (ndarray): 1D height vector (m).
57
57
  model_type (str): Model identifier.
58
58
  radar_type (str): Radar identifier.
59
+ lidar_type (str): Lidar identifier.
59
60
  is_rain (ndarray): 2D boolean array denoting rain.
60
61
  is_clutter (ndarray): 2D boolean array denoting clutter.
61
62
  altitude: site altitude.
@@ -76,6 +77,7 @@ class ClassData:
76
77
  self.tw = data.model.data["Tw"][:]
77
78
  self.model_type = data.model.source_type
78
79
  self.beta = data.lidar.data["beta"][:]
80
+ self.lidar_type = data.lidar.source
79
81
  self.lwp = (
80
82
  data.mwr.data["lwp"][:]
81
83
  if data.mwr is not None
@@ -437,6 +437,8 @@ def _process_instrument_product(
437
437
  input_files = input_folder
438
438
  case ("mrr", _id):
439
439
  fun = instruments.mrr2nc
440
+ case ("weather-radar", _id):
441
+ fun = instruments.wr2nc
440
442
  case ("weather-station", _id):
441
443
  fun = instruments.ws2nc
442
444
  case (invalid_product_id, invalid_instrument_id):
@@ -770,6 +772,10 @@ def _plot(
770
772
  options = PlotParameters()
771
773
  if args.max_y is not None:
772
774
  options.max_y = args.max_y
775
+ if args.start_time is not None:
776
+ options.start_time = args.start_time
777
+ if args.stop_time is not None:
778
+ options.stop_time = args.stop_time
773
779
  try:
774
780
  generate_figure(
775
781
  filepath,
@@ -949,6 +955,18 @@ def main() -> None:
949
955
  help="Maximum y-axis value (km) in 2D time/height plots (default: 12)",
950
956
  default=None,
951
957
  )
958
+ parser.add_argument(
959
+ "--start-time",
960
+ type=float,
961
+ help="Start time in fractional hours since midnight UTC (default: 0)",
962
+ default=None,
963
+ )
964
+ parser.add_argument(
965
+ "--stop-time",
966
+ type=float,
967
+ help="Stop time in fractional hours since midnight UTC (default: 24)",
968
+ default=None,
969
+ )
952
970
  parser.add_argument(
953
971
  "-o",
954
972
  "--options",
@@ -112,6 +112,8 @@ class ArmCeilo(Ceilometer):
112
112
  self.data["time"] = np.array(nc["time"][:])
113
113
  calibration_factor = float(self.site_meta.get("calibration_factor", 1))
114
114
  backscatter = ma.masked_invalid(nc["backscatter"][:])
115
+ # Missing profiles are filled with int32 min without _FillValue
116
+ backscatter = ma.masked_less(backscatter, -1e6)
115
117
  self.data["beta_raw"] = backscatter * BACKSCATTER_SCALE * calibration_factor
116
118
  self.data["calibration_factor"] = calibration_factor
117
119
  self.data["zenith_angle"] = float(ma.median(nc["tilt_angle"][:]))
@@ -12,6 +12,7 @@ from uuid import UUID
12
12
 
13
13
  import netCDF4
14
14
  import numpy as np
15
+ import numpy.typing as npt
15
16
  from numpy import ma
16
17
 
17
18
  from cloudnetpy import output, utils
@@ -363,7 +364,7 @@ class Kazr(CloudnetInstrument):
363
364
  zh_key = next(k for k, v in self.keymap.items() if v == "Zh")
364
365
  bias = getattr(nc[zh_key], "applied_bias_correction", None)
365
366
  if bias is not None:
366
- self.offset_applied = round(float(bias), 2)
367
+ self.offset_applied = _parse_bias(bias)
367
368
  self.serial_number = getattr(nc, "serial_number", None) or None
368
369
  self.append_data(np.array(nc["range"][:], dtype=float), "range")
369
370
  self.append_data(0.0, "zenith_angle")
@@ -473,18 +474,29 @@ def _find_ldr_floor(
473
474
  def _ldr_scatter(
474
475
  excess: ma.MaskedArray, snr: ma.MaskedArray, valid: np.ndarray
475
476
  ) -> np.ndarray:
476
- """Estimates noise scatter (std) of LDR around the floor per SNR bin."""
477
+ """Estimates noise scatter (std) of LDR around the floor per SNR bin.
478
+
479
+ Bins with too few samples near the floor (typically low SNR, where only
480
+ strongly depolarizing targets have a detectable cross-polar signal) take
481
+ the scatter of the nearest populated bin.
482
+ """
477
483
  edges = np.arange(-10, 60, 5.0)
478
- scatter = np.full(excess.shape, np.inf)
479
484
  near_floor = valid & (np.abs(excess) < 3)
480
- for lo, hi in pairwise(edges):
485
+ per_bin = np.full(len(edges) - 1, np.nan)
486
+ for i, (lo, hi) in enumerate(pairwise(edges)):
481
487
  in_bin = (snr >= lo) & (snr < hi)
482
488
  samples = excess[in_bin & near_floor].compressed()
483
489
  if samples.size < 100:
484
490
  continue
485
491
  mad = np.median(np.abs(samples - np.median(samples)))
486
- scatter[in_bin] = 1.4826 * mad
487
- return scatter
492
+ per_bin[i] = 1.4826 * mad
493
+ known = ~np.isnan(per_bin)
494
+ if not known.any():
495
+ return np.full(excess.shape, np.inf)
496
+ ind = np.arange(per_bin.size)
497
+ per_bin = np.interp(ind, ind[known], per_bin[known])
498
+ bin_ind = np.clip(np.digitize(ma.filled(snr, -np.inf), edges) - 1, 0, ind[-1])
499
+ return np.where(ma.getmaskarray(snr), np.inf, per_bin[bin_ind])
488
500
 
489
501
 
490
502
  def _parse_global_attribute(nc: netCDF4.Dataset, key: str) -> float | None:
@@ -545,3 +557,13 @@ ATTRIBUTES = {
545
557
  "zenith_angle": COMMON_ATTRIBUTES["zenith_angle"]._replace(dimensions=None),
546
558
  "nyquist_velocity": COMMON_ATTRIBUTES["nyquist_velocity"]._replace(dimensions=None),
547
559
  }
560
+
561
+
562
+ def _parse_bias(bias: npt.ArrayLike) -> float | None:
563
+ """Parses ARM reflectivity bias attribute, which may be an empty array."""
564
+ values = np.atleast_1d(np.asarray(bias, dtype=float))
565
+ if len(values) == 0:
566
+ return None
567
+ if len(np.unique(values)) > 1:
568
+ logging.warning("Multiple bias corrections %s, using the first one", values)
569
+ return round(float(values[0]), 2)
@@ -54,6 +54,8 @@ class PlotParameters:
54
54
  plotted variable.
55
55
  minor_ticks: Whether to display minor ticks on the x-axis.
56
56
  plot_above_ground: Whether to plot above ground instead of above mean sea level.
57
+ start_time: Start time in fractional hours for time-axis limits.
58
+ stop_time: Stop time in fractional hours for time-axis limits.
57
59
 
58
60
  """
59
61
 
@@ -70,6 +72,8 @@ class PlotParameters:
70
72
  raise_on_empty: bool = False
71
73
  minor_ticks: bool = True
72
74
  plot_above_ground: bool = True
75
+ start_time: float | None = None
76
+ stop_time: float | None = None
73
77
 
74
78
 
75
79
  class Dimensions:
@@ -337,7 +341,11 @@ class SubPlot:
337
341
  if self.options.minor_ticks:
338
342
  self.ax.xaxis.set_minor_locator(AutoMinorLocator(4))
339
343
  self.ax.tick_params(which="minor", length=2.5)
340
- self.ax.set_xlim(0, 24)
344
+ start_time = (
345
+ self.options.start_time if self.options.start_time is not None else 0
346
+ )
347
+ stop_time = self.options.stop_time if self.options.stop_time is not None else 24
348
+ self.ax.set_xlim(start_time, stop_time)
341
349
 
342
350
  def set_yax(
343
351
  self,
@@ -1,4 +1,4 @@
1
1
  MAJOR = 1
2
2
  MINOR = 95
3
- PATCH = 5
3
+ PATCH = 7
4
4
  __version__ = f"{MAJOR}.{MINOR}.{PATCH}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnetpy
3
- Version: 1.95.5
3
+ Version: 1.95.7
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