cloudnetpy 1.83.1__tar.gz → 1.84.0__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 (133) hide show
  1. {cloudnetpy-1.83.1/cloudnetpy.egg-info → cloudnetpy-1.84.0}/PKG-INFO +1 -1
  2. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/categorize.py +1 -1
  3. cloudnetpy-1.84.0/cloudnetpy/categorize/disdrometer.py +37 -0
  4. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/lidar.py +1 -12
  5. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/mwr.py +6 -9
  6. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/utils.py +56 -1
  7. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/version.py +2 -2
  8. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0/cloudnetpy.egg-info}/PKG-INFO +1 -1
  9. cloudnetpy-1.83.1/cloudnetpy/categorize/disdrometer.py +0 -60
  10. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/LICENSE +0 -0
  11. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/MANIFEST.in +0 -0
  12. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/README.md +0 -0
  13. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/__init__.py +0 -0
  14. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/__init__.py +0 -0
  15. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/atmos_utils.py +0 -0
  16. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/attenuation.py +0 -0
  17. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
  18. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
  19. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
  20. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
  21. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
  22. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/classify.py +0 -0
  23. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/containers.py +0 -0
  24. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/droplet.py +0 -0
  25. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/falling.py +0 -0
  26. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/freezing.py +0 -0
  27. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/insects.py +0 -0
  28. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/itu.py +0 -0
  29. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/melting.py +0 -0
  30. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/model.py +0 -0
  31. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/categorize/radar.py +0 -0
  32. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/cli.py +0 -0
  33. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/cloudnetarray.py +0 -0
  34. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/concat_lib.py +0 -0
  35. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/constants.py +0 -0
  36. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/datasource.py +0 -0
  37. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/exceptions.py +0 -0
  38. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/__init__.py +0 -0
  39. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/basta.py +0 -0
  40. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/bowtie.py +0 -0
  41. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/ceilo.py +0 -0
  42. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/ceilometer.py +0 -0
  43. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/cl61d.py +0 -0
  44. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
  45. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/copernicus.py +0 -0
  46. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/disdrometer/__init__.py +0 -0
  47. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/disdrometer/common.py +0 -0
  48. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/disdrometer/parsivel.py +0 -0
  49. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/disdrometer/thies.py +0 -0
  50. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/fd12p.py +0 -0
  51. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/galileo.py +0 -0
  52. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/hatpro.py +0 -0
  53. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/instruments.py +0 -0
  54. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/lufft.py +0 -0
  55. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/mira.py +0 -0
  56. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/mrr.py +0 -0
  57. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/nc_lidar.py +0 -0
  58. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/nc_radar.py +0 -0
  59. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/pollyxt.py +0 -0
  60. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/radiometrics.py +0 -0
  61. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/rain_e_h3.py +0 -0
  62. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/rpg.py +0 -0
  63. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/rpg_reader.py +0 -0
  64. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/toa5.py +0 -0
  65. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/vaisala.py +0 -0
  66. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/instruments/weather_station.py +0 -0
  67. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/metadata.py +0 -0
  68. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/__init__.py +0 -0
  69. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/file_handler.py +0 -0
  70. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/metadata.py +0 -0
  71. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
  72. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
  73. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
  74. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
  75. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
  76. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
  77. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/products/advance_methods.py +0 -0
  78. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
  79. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
  80. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
  81. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
  82. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/products/tools.py +0 -0
  83. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
  84. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
  85. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
  86. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
  87. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
  88. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
  89. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
  90. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
  91. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
  92. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
  93. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
  94. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
  95. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
  96. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
  97. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
  98. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
  99. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
  100. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
  101. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
  102. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
  103. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
  104. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
  105. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
  106. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
  107. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/model_evaluation/utils.py +0 -0
  108. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/output.py +0 -0
  109. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/plotting/__init__.py +0 -0
  110. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/plotting/plot_meta.py +0 -0
  111. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/plotting/plotting.py +0 -0
  112. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/__init__.py +0 -0
  113. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/classification.py +0 -0
  114. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/der.py +0 -0
  115. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/drizzle.py +0 -0
  116. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/drizzle_error.py +0 -0
  117. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/drizzle_tools.py +0 -0
  118. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/epsilon.py +0 -0
  119. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/ier.py +0 -0
  120. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/iwc.py +0 -0
  121. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/lwc.py +0 -0
  122. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/mie_lu_tables.nc +0 -0
  123. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/mwr_tools.py +0 -0
  124. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/products/product_tools.py +0 -0
  125. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy/py.typed +0 -0
  126. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy.egg-info/SOURCES.txt +0 -0
  127. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy.egg-info/dependency_links.txt +0 -0
  128. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy.egg-info/entry_points.txt +0 -0
  129. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy.egg-info/requires.txt +0 -0
  130. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/cloudnetpy.egg-info/top_level.txt +0 -0
  131. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/docs/source/conf.py +0 -0
  132. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/pyproject.toml +0 -0
  133. {cloudnetpy-1.83.1 → cloudnetpy-1.84.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnetpy
3
- Version: 1.83.1
3
+ Version: 1.84.0
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -93,7 +93,7 @@ def generate_categorize(
93
93
  if data.disdrometer is not None:
94
94
  data.disdrometer.interpolate_to_grid(time)
95
95
  if data.mwr is not None:
96
- data.mwr.rebin_to_grid(time)
96
+ data.mwr.interpolate_to_grid(time)
97
97
  data.model.calc_attenuations(data.radar.radar_frequency)
98
98
  data.model.interpolate_to_common_height()
99
99
  model_gap_ind = data.model.interpolate_to_grid(time, height)
@@ -0,0 +1,37 @@
1
+ """Mwr module, containing the :class:`Mwr` class."""
2
+
3
+ from os import PathLike
4
+
5
+ import numpy.typing as npt
6
+
7
+ from cloudnetpy.datasource import DataSource
8
+ from cloudnetpy.exceptions import DisdrometerDataError
9
+ from cloudnetpy.utils import interpolate_1d
10
+
11
+
12
+ class Disdrometer(DataSource):
13
+ """Disdrometer class, child of DataSource.
14
+
15
+ Args:
16
+ ----
17
+ full_path: Cloudnet Level 1b disdrometer file.
18
+
19
+ """
20
+
21
+ def __init__(self, full_path: str | PathLike) -> None:
22
+ super().__init__(full_path)
23
+ self._init_rainfall_rate()
24
+
25
+ def interpolate_to_grid(self, time_grid: npt.NDArray) -> None:
26
+ for key, array in self.data.items():
27
+ self.data[key].data = interpolate_1d(
28
+ self.time, array.data, time_grid, max_time=1
29
+ )
30
+
31
+ def _init_rainfall_rate(self) -> None:
32
+ keys = ("rainfall_rate", "n_particles")
33
+ for key in keys:
34
+ if key not in self.dataset.variables:
35
+ msg = f"variable {key} is missing"
36
+ raise DisdrometerDataError(msg)
37
+ self.append_data(self.dataset.variables[key][:], key)
@@ -4,12 +4,11 @@ import logging
4
4
  from os import PathLike
5
5
  from typing import Literal
6
6
 
7
- import numpy as np
8
7
  import numpy.typing as npt
9
8
  from numpy import ma
10
9
 
11
10
  from cloudnetpy.datasource import DataSource
12
- from cloudnetpy.utils import interpolate_2d_nearest
11
+ from cloudnetpy.utils import get_gap_ind, interpolate_2d_nearest
13
12
 
14
13
 
15
14
  class Lidar(DataSource):
@@ -70,13 +69,3 @@ class Lidar(DataSource):
70
69
  self.append_data(float(self.getvar("wavelength")), "lidar_wavelength")
71
70
  self.append_data(0.5, "beta_error")
72
71
  self.append_data(3.0, "beta_bias")
73
-
74
-
75
- def get_gap_ind(
76
- grid: npt.NDArray, new_grid: npt.NDArray, threshold: float
77
- ) -> list[int]:
78
- return [
79
- ind
80
- for ind, value in enumerate(new_grid)
81
- if np.min(np.abs(grid - value)) > threshold
82
- ]
@@ -8,6 +8,7 @@ import numpy.typing as npt
8
8
  from cloudnetpy import utils
9
9
  from cloudnetpy.constants import G_TO_KG
10
10
  from cloudnetpy.datasource import DataSource
11
+ from cloudnetpy.utils import interpolate_1d
11
12
 
12
13
 
13
14
  class Mwr(DataSource):
@@ -23,15 +24,11 @@ class Mwr(DataSource):
23
24
  self._init_lwp_data()
24
25
  self._init_lwp_error()
25
26
 
26
- def rebin_to_grid(self, time_grid: npt.NDArray) -> None:
27
- """Approximates lwp and its error in a grid using mean.
28
-
29
- Args:
30
- time_grid: 1D target time grid.
31
-
32
- """
33
- for array in self.data.values():
34
- array.rebin_data(self.time, time_grid)
27
+ def interpolate_to_grid(self, time_grid: npt.NDArray, max_time: float = 1) -> None:
28
+ for key, array in self.data.items():
29
+ self.data[key].data = interpolate_1d(
30
+ self.time, array.data, time_grid, max_time=max_time
31
+ )
35
32
 
36
33
  def _init_lwp_data(self) -> None:
37
34
  lwp = self.dataset.variables["lwp"][:]
@@ -3,6 +3,7 @@
3
3
  import base64
4
4
  import datetime
5
5
  import hashlib
6
+ import logging
6
7
  import os
7
8
  import re
8
9
  import textwrap
@@ -17,7 +18,12 @@ import numpy as np
17
18
  import numpy.typing as npt
18
19
  from numpy import ma
19
20
  from scipy import ndimage, stats
20
- from scipy.interpolate import RectBivariateSpline, RegularGridInterpolator, griddata
21
+ from scipy.interpolate import (
22
+ RectBivariateSpline,
23
+ RegularGridInterpolator,
24
+ griddata,
25
+ interp1d,
26
+ )
21
27
 
22
28
  from cloudnetpy.cloudnetarray import CloudnetArray
23
29
  from cloudnetpy.constants import SEC_IN_DAY, SEC_IN_HOUR, SEC_IN_MINUTE
@@ -413,6 +419,55 @@ def interpolate_2d_nearest(
413
419
  return fun((xx, yy)).T
414
420
 
415
421
 
422
+ def interpolate_1d(
423
+ time: npt.NDArray, y: ma.MaskedArray, time_new: npt.NDArray, max_time: float
424
+ ) -> npt.NDArray:
425
+ """1D linear interpolation preserving the mask.
426
+
427
+ Args:
428
+ time: 1D array in fraction hour.
429
+ y: 1D masked array, data values.
430
+ time_new: 1D array, new time coordinates.
431
+ max_time: Maximum allowed gap in minutes. Values outside this gap will
432
+ be masked.
433
+ """
434
+ if np.max(time) > 24 or np.min(time) < 0:
435
+ msg = "Time vector must be in fraction hours between 0 and 24"
436
+ raise ValueError(msg)
437
+ if ma.is_masked(y):
438
+ if y.mask.all():
439
+ return ma.masked_all(time_new.shape)
440
+ time = time[~y.mask]
441
+ y = y[~y.mask]
442
+ fun = interp1d(time, y, fill_value=(y[0], y[-1]), bounds_error=False)
443
+ interpolated = ma.array(fun(time_new))
444
+ bad_idx = get_gap_ind(time, time_new, max_time / 60)
445
+
446
+ if len(bad_idx) > 0:
447
+ msg = f"Unable to interpolate for {len(bad_idx)} time steps"
448
+ logging.warning(msg)
449
+ interpolated[bad_idx] = ma.masked
450
+
451
+ return interpolated
452
+
453
+
454
+ def get_gap_ind(
455
+ grid: npt.NDArray, new_grid: npt.NDArray, threshold: float
456
+ ) -> list[int]:
457
+ """Finds indices in new_grid that are too far from grid."""
458
+ if grid.size == 0:
459
+ return list(range(len(new_grid)))
460
+ idxs = np.searchsorted(grid, new_grid)
461
+ left_dist = np.where(idxs > 0, np.abs(new_grid - grid[idxs - 1]), np.inf)
462
+ right_dist = np.where(
463
+ idxs < len(grid),
464
+ np.abs(new_grid - grid[np.clip(idxs, 0, len(grid) - 1)]),
465
+ np.inf,
466
+ )
467
+ nearest = np.minimum(left_dist, right_dist)
468
+ return np.where(nearest > threshold)[0].tolist()
469
+
470
+
416
471
  def calc_relative_error(reference: npt.NDArray, array: npt.NDArray) -> npt.NDArray:
417
472
  """Calculates relative error (%)."""
418
473
  return ((array - reference) / reference) * 100
@@ -1,4 +1,4 @@
1
1
  MAJOR = 1
2
- MINOR = 83
3
- PATCH = 1
2
+ MINOR = 84
3
+ PATCH = 0
4
4
  __version__ = f"{MAJOR}.{MINOR}.{PATCH}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudnetpy
3
- Version: 1.83.1
3
+ Version: 1.84.0
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -1,60 +0,0 @@
1
- """Mwr module, containing the :class:`Mwr` class."""
2
-
3
- import logging
4
- from os import PathLike
5
-
6
- import numpy as np
7
- import numpy.typing as npt
8
- from numpy import ma
9
- from scipy.interpolate import interp1d
10
-
11
- from cloudnetpy.categorize.lidar import get_gap_ind
12
- from cloudnetpy.datasource import DataSource
13
- from cloudnetpy.exceptions import DisdrometerDataError
14
-
15
-
16
- class Disdrometer(DataSource):
17
- """Disdrometer class, child of DataSource.
18
-
19
- Args:
20
- ----
21
- full_path: Cloudnet Level 1b disdrometer file.
22
-
23
- """
24
-
25
- def __init__(self, full_path: str | PathLike) -> None:
26
- super().__init__(full_path)
27
- self._init_rainfall_rate()
28
-
29
- def interpolate_to_grid(self, time_grid: npt.NDArray) -> None:
30
- for key, array in self.data.items():
31
- self.data[key].data = self._interpolate(array.data, time_grid)
32
-
33
- def _init_rainfall_rate(self) -> None:
34
- keys = ("rainfall_rate", "n_particles")
35
- for key in keys:
36
- if key not in self.dataset.variables:
37
- msg = f"variable {key} is missing"
38
- raise DisdrometerDataError(msg)
39
- self.append_data(self.dataset.variables[key][:], key)
40
-
41
- def _interpolate(self, y: ma.MaskedArray, x_new: npt.NDArray) -> npt.NDArray:
42
- time = self.time
43
- mask = ma.getmask(y)
44
- if mask is not ma.nomask:
45
- if np.all(mask):
46
- return ma.masked_all(x_new.shape)
47
- not_masked = ~mask
48
- y = y[not_masked]
49
- time = time[not_masked]
50
- fun = interp1d(time, y, fill_value="extrapolate")
51
- interpolated_array = ma.array(fun(x_new))
52
- max_time = 1 / 60 # min -> fraction hour
53
- mask_ind = get_gap_ind(time, x_new, max_time)
54
-
55
- if len(mask_ind) > 0:
56
- msg = f"Unable to interpolate disdrometer for {len(mask_ind)} time steps"
57
- logging.warning(msg)
58
- interpolated_array[mask_ind] = ma.masked
59
-
60
- return interpolated_array
File without changes
File without changes
File without changes
File without changes
File without changes