cloudnetpy 1.96.3__tar.gz → 1.96.4__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.3/cloudnetpy.egg-info → cloudnetpy-1.96.4}/PKG-INFO +1 -1
  2. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/disdronator/parsivel.py +17 -0
  3. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/products/advance_methods.py +14 -5
  4. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +17 -1
  5. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/version.py +1 -1
  6. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4/cloudnetpy.egg-info}/PKG-INFO +1 -1
  7. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/LICENSE +0 -0
  8. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/MANIFEST.in +0 -0
  9. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/README.md +0 -0
  10. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/__init__.py +0 -0
  11. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/arm.py +0 -0
  12. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/__init__.py +0 -0
  13. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/atmos_utils.py +0 -0
  14. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/attenuation.py +0 -0
  15. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
  16. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
  17. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
  18. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
  19. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
  20. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/categorize.py +0 -0
  21. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/classify.py +0 -0
  22. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/containers.py +0 -0
  23. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/disdrometer.py +0 -0
  24. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/droplet.py +0 -0
  25. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/falling.py +0 -0
  26. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/freezing.py +0 -0
  27. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/insects.py +0 -0
  28. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/lidar.py +0 -0
  29. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/melting.py +0 -0
  30. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/model.py +0 -0
  31. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/mwr.py +0 -0
  32. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/categorize/radar.py +0 -0
  33. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/cli.py +0 -0
  34. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/cloudnetarray.py +0 -0
  35. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/concat_lib.py +0 -0
  36. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/constants.py +0 -0
  37. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/datasource.py +0 -0
  38. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/disdronator/__init__.py +0 -0
  39. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/disdronator/lpm.py +0 -0
  40. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/disdronator/process.py +0 -0
  41. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/disdronator/rd80.py +0 -0
  42. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/disdronator/utils.py +0 -0
  43. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/exceptions.py +0 -0
  44. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/__init__.py +0 -0
  45. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/arm_ceilo.py +0 -0
  46. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/arm_ld.py +0 -0
  47. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/arm_utils.py +0 -0
  48. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/basta.py +0 -0
  49. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/bowtie.py +0 -0
  50. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/ceilo.py +0 -0
  51. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/ceilometer.py +0 -0
  52. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/cl61d.py +0 -0
  53. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
  54. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/copernicus.py +0 -0
  55. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/da10.py +0 -0
  56. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/dealias.py +0 -0
  57. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/disdrometer.py +0 -0
  58. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/fd12p.py +0 -0
  59. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/galileo.py +0 -0
  60. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/hatpro.py +0 -0
  61. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/instruments.py +0 -0
  62. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/kazr.py +0 -0
  63. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/lufft.py +0 -0
  64. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/mira.py +0 -0
  65. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/mmcr.py +0 -0
  66. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/mrr.py +0 -0
  67. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/mwr3c.py +0 -0
  68. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/mwrlos.py +0 -0
  69. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/nc_lidar.py +0 -0
  70. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/nc_radar.py +0 -0
  71. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/pollyxt.py +0 -0
  72. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/radiometrics.py +0 -0
  73. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/rain_e_h3.py +0 -0
  74. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/rpg.py +0 -0
  75. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/rpg_reader.py +0 -0
  76. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/toa5.py +0 -0
  77. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/vaisala.py +0 -0
  78. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/weather_radar.py +0 -0
  79. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/instruments/weather_station.py +0 -0
  80. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/metadata.py +0 -0
  81. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/__init__.py +0 -0
  82. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/file_handler.py +0 -0
  83. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/metadata.py +0 -0
  84. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
  85. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
  86. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
  87. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
  88. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
  89. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
  90. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
  91. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
  92. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
  93. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
  94. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/products/tools.py +0 -0
  95. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
  96. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
  97. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
  98. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
  99. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
  100. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
  101. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
  102. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
  103. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
  104. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
  105. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
  106. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
  107. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
  108. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
  109. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
  110. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
  111. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
  112. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
  113. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
  114. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
  115. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
  116. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
  117. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
  118. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/model_evaluation/utils.py +0 -0
  119. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/output.py +0 -0
  120. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/plotting/__init__.py +0 -0
  121. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/plotting/plot_meta.py +0 -0
  122. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/plotting/plotting.py +0 -0
  123. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/__init__.py +0 -0
  124. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/classification.py +0 -0
  125. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/cod.py +0 -0
  126. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/der.py +0 -0
  127. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/drizzle.py +0 -0
  128. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/drizzle_error.py +0 -0
  129. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/drizzle_tools.py +0 -0
  130. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/epsilon_lidar.py +0 -0
  131. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/epsilon_radar.py +0 -0
  132. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/ier.py +0 -0
  133. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/iwc.py +0 -0
  134. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/iwc_weather_radar.py +0 -0
  135. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/lwc.py +0 -0
  136. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/mie_lu_tables.nc +0 -0
  137. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/mwr_tools.py +0 -0
  138. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/products/product_tools.py +0 -0
  139. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/py.typed +0 -0
  140. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy/utils.py +0 -0
  141. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy.egg-info/SOURCES.txt +0 -0
  142. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy.egg-info/dependency_links.txt +0 -0
  143. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy.egg-info/entry_points.txt +0 -0
  144. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy.egg-info/requires.txt +0 -0
  145. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/cloudnetpy.egg-info/top_level.txt +0 -0
  146. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/docs/source/conf.py +0 -0
  147. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/pyproject.toml +0 -0
  148. {cloudnetpy-1.96.3 → cloudnetpy-1.96.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnetpy
3
- Version: 1.96.3
3
+ Version: 1.96.4
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -475,6 +475,21 @@ def _read_leipzig(filename: str | PathLike) -> ParsivelOutput:
475
475
  return time, data
476
476
 
477
477
 
478
+ def _read_cloudlab(filename: str | PathLike) -> ParsivelOutput:
479
+ # Data acquired with ASDO and converted to daily netCDF files. The netCDF
480
+ # files are similar to parsivel2nc files but without "number_concentration"
481
+ # and "fall_velocity" variables.
482
+ with netCDF4.Dataset(filename) as nc:
483
+ time = cftime.num2pydate(nc["time"][:], units=nc["time"].units)
484
+ data = {
485
+ num: nc[key][:]
486
+ for key, num in PARSIVEL2NC_KEYS.items()
487
+ if key in nc.variables
488
+ }
489
+ data[13] = np.repeat(int(nc.Sensor_ID), len(time))
490
+ return time, data
491
+
492
+
478
493
  def _read_parsivel(
479
494
  filename: str | PathLike,
480
495
  telegram: Sequence[int | str | None] | None = None,
@@ -483,6 +498,8 @@ def _read_parsivel(
483
498
  ) -> ParsivelOutput:
484
499
  try:
485
500
  with netCDF4.Dataset(filename) as nc:
501
+ if hasattr(nc, "Title") and "CLOUDLAB" in nc.Title:
502
+ return _read_cloudlab(filename)
486
503
  if "number_concentration" in nc.variables:
487
504
  return _read_parsivel2nc(filename)
488
505
  if "fieldN" in nc.variables:
@@ -105,11 +105,20 @@ class AdvanceProductMethods:
105
105
  if self._obs_obj.height is None:
106
106
  msg = "No height in observation file"
107
107
  raise ValueError(msg)
108
- z_sen = [
109
- cl_tools.rebin_1d(self._obs_obj.height, self._obs_obj.z_sensitivity, h[i])
110
- for i in range(len(h))
111
- ]
112
- return np.asarray(z_sen)
108
+ # Interpolate at the model level heights: rebinning assumes evenly
109
+ # spaced levels, which maps stretched model levels to wrong heights.
110
+ obs_height = self._obs_obj.height_agl
111
+ if obs_height is None:
112
+ obs_height = self._obs_obj.height
113
+ obs_height = np.asarray(ma.filled(obs_height, np.nan), dtype=float)
114
+ z_obs = np.asarray(ma.filled(self._obs_obj.z_sensitivity, np.nan), dtype=float)
115
+ is_valid = np.isfinite(obs_height) & np.isfinite(z_obs)
116
+ model_height = np.asarray(ma.filled(h, np.nan), dtype=float)
117
+ z_sen = np.interp(
118
+ model_height, obs_height[is_valid], z_obs[is_valid], right=np.nan
119
+ )
120
+ z_sen[~np.isfinite(model_height)] = np.nan
121
+ return z_sen
113
122
 
114
123
  def filter_high_iwc_low_cf(
115
124
  self,
@@ -69,14 +69,30 @@ def test_fit_z_sensitivity(obs_file, model_file) -> None:
69
69
  obs = ObservationManager(PRODUCT, str(obs_file))
70
70
  model = ModelManager(str(model_file), MODEL, PRODUCT)
71
71
  advance = AdvanceProductMethods(model, obs)
72
+ # obs heights above ground 7, 8, 11 and 14 km with sensitivities
73
+ # 0.1, 0.2, 0.0, 1.0; levels above the radar range are NaN
72
74
  height = np.array(
73
75
  [[5000, 9000, 13000], [10000, 15000, 20000], [8000, 12000, 16000]]
74
76
  )
75
- expected = ma.masked_invalid([[np.nan, 0.15, 0.5], [0.1, 1, np.nan], [0.15, 0, 1]])
77
+ expected = np.array(
78
+ [[0.1, 0.4 / 3, 2 / 3], [0.2 / 3, np.nan, np.nan], [0.2, 1 / 3, np.nan]]
79
+ )
76
80
  result = advance.fit_z_sensitivity(height)
77
81
  testing.assert_array_almost_equal(result, expected)
78
82
 
79
83
 
84
+ def test_fit_z_sensitivity_stretched_grid(obs_file, model_file) -> None:
85
+ obs = ObservationManager(PRODUCT, str(obs_file))
86
+ model = ModelManager(str(model_file), MODEL, PRODUCT)
87
+ advance = AdvanceProductMethods(model, obs)
88
+ # unevenly spaced model levels within the radar range must all get a value
89
+ height = np.array([[7000, 7100, 7300, 7700, 8500, 10000, 13000, 14000]])
90
+ result = advance.fit_z_sensitivity(height)
91
+ assert np.isfinite(result).all()
92
+ assert result[0, 0] == pytest.approx(0.1)
93
+ assert result[0, -1] == pytest.approx(1.0)
94
+
95
+
80
96
  def test_filter_high_iwc_low_cf(obs_file, model_file) -> None:
81
97
  obs = ObservationManager(PRODUCT, str(obs_file))
82
98
  model = ModelManager(str(model_file), MODEL, PRODUCT)
@@ -1,4 +1,4 @@
1
1
  MAJOR = 1
2
2
  MINOR = 96
3
- PATCH = 3
3
+ PATCH = 4
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.3
3
+ Version: 1.96.4
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