cloudnetpy 1.61.15__py3-none-any.whl → 1.61.16__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.
Files changed (67) hide show
  1. cloudnetpy/categorize/atmos.py +1 -0
  2. cloudnetpy/categorize/atmos_utils.py +1 -1
  3. cloudnetpy/categorize/categorize.py +1 -0
  4. cloudnetpy/categorize/classify.py +1 -0
  5. cloudnetpy/categorize/containers.py +3 -1
  6. cloudnetpy/categorize/disdrometer.py +1 -0
  7. cloudnetpy/categorize/droplet.py +2 -2
  8. cloudnetpy/categorize/falling.py +1 -0
  9. cloudnetpy/categorize/freezing.py +1 -0
  10. cloudnetpy/categorize/insects.py +1 -0
  11. cloudnetpy/categorize/lidar.py +1 -0
  12. cloudnetpy/categorize/melting.py +1 -0
  13. cloudnetpy/categorize/model.py +1 -0
  14. cloudnetpy/categorize/mwr.py +1 -0
  15. cloudnetpy/categorize/radar.py +1 -0
  16. cloudnetpy/cloudnetarray.py +2 -0
  17. cloudnetpy/concat_lib.py +1 -0
  18. cloudnetpy/constants.py +1 -0
  19. cloudnetpy/datasource.py +5 -3
  20. cloudnetpy/instruments/basta.py +1 -0
  21. cloudnetpy/instruments/ceilo.py +2 -1
  22. cloudnetpy/instruments/cl61d.py +1 -0
  23. cloudnetpy/instruments/copernicus.py +2 -1
  24. cloudnetpy/instruments/disdrometer/parsivel.py +6 -4
  25. cloudnetpy/instruments/galileo.py +1 -0
  26. cloudnetpy/instruments/hatpro.py +1 -0
  27. cloudnetpy/instruments/lufft.py +1 -0
  28. cloudnetpy/instruments/mira.py +1 -0
  29. cloudnetpy/instruments/mrr.py +1 -1
  30. cloudnetpy/instruments/nc_lidar.py +1 -0
  31. cloudnetpy/instruments/nc_radar.py +1 -0
  32. cloudnetpy/instruments/pollyxt.py +1 -0
  33. cloudnetpy/instruments/radiometrics.py +2 -1
  34. cloudnetpy/instruments/rpg.py +2 -1
  35. cloudnetpy/instruments/rpg_reader.py +1 -1
  36. cloudnetpy/instruments/toa5.py +1 -1
  37. cloudnetpy/instruments/vaisala.py +7 -6
  38. cloudnetpy/instruments/weather_station.py +2 -3
  39. cloudnetpy/model_evaluation/file_handler.py +2 -2
  40. cloudnetpy/model_evaluation/metadata.py +1 -1
  41. cloudnetpy/model_evaluation/plotting/plot_tools.py +2 -2
  42. cloudnetpy/model_evaluation/plotting/plotting.py +11 -8
  43. cloudnetpy/model_evaluation/products/grid_methods.py +1 -1
  44. cloudnetpy/model_evaluation/products/model_products.py +7 -7
  45. cloudnetpy/model_evaluation/products/observation_products.py +8 -8
  46. cloudnetpy/model_evaluation/products/tools.py +5 -7
  47. cloudnetpy/model_evaluation/statistics/statistical_methods.py +2 -2
  48. cloudnetpy/output.py +3 -1
  49. cloudnetpy/plotting/plot_meta.py +2 -2
  50. cloudnetpy/plotting/plotting.py +8 -11
  51. cloudnetpy/products/classification.py +10 -9
  52. cloudnetpy/products/der.py +3 -2
  53. cloudnetpy/products/drizzle.py +3 -3
  54. cloudnetpy/products/drizzle_tools.py +1 -1
  55. cloudnetpy/products/ier.py +1 -0
  56. cloudnetpy/products/iwc.py +4 -3
  57. cloudnetpy/products/lwc.py +2 -3
  58. cloudnetpy/products/mwr_tools.py +2 -4
  59. cloudnetpy/products/product_tools.py +2 -1
  60. cloudnetpy/utils.py +9 -14
  61. cloudnetpy/version.py +1 -1
  62. {cloudnetpy-1.61.15.dist-info → cloudnetpy-1.61.16.dist-info}/METADATA +1 -1
  63. cloudnetpy-1.61.16.dist-info/RECORD +115 -0
  64. {cloudnetpy-1.61.15.dist-info → cloudnetpy-1.61.16.dist-info}/WHEEL +1 -1
  65. cloudnetpy-1.61.15.dist-info/RECORD +0 -115
  66. {cloudnetpy-1.61.15.dist-info → cloudnetpy-1.61.16.dist-info}/LICENSE +0 -0
  67. {cloudnetpy-1.61.15.dist-info → cloudnetpy-1.61.16.dist-info}/top_level.txt +0 -0
@@ -58,7 +58,7 @@ class ObservationManager(DataSource):
58
58
  return None
59
59
 
60
60
  def _generate_product(self) -> None:
61
- """Process needed data of observation to a ObservationManager object"""
61
+ """Process needed data of observation to a ObservationManager object."""
62
62
  try:
63
63
  if self.obs == "cf":
64
64
  self.append_data(self._generate_cf(), "cf")
@@ -73,7 +73,7 @@ class ObservationManager(DataSource):
73
73
  raise
74
74
 
75
75
  def _generate_cf(self) -> np.ndarray:
76
- """Generates cloud fractions using categorize bits and masking conditions"""
76
+ """Generates cloud fractions using categorize bits and masking conditions."""
77
77
  categorize_bits = CategorizeBits(self._file)
78
78
  cloud_mask = self._classify_basic_mask(categorize_bits.category_bits)
79
79
  return self._mask_cloud_bits(cloud_mask)
@@ -91,7 +91,7 @@ class ObservationManager(DataSource):
91
91
 
92
92
  @staticmethod
93
93
  def _mask_cloud_bits(cloud_mask: np.ndarray) -> np.ndarray:
94
- """Creates cloud fraction"""
94
+ """Creates cloud fraction."""
95
95
  for i in [1, 3, 4, 5]:
96
96
  cloud_mask[cloud_mask == i] = 1
97
97
  for i in [2, 6, 7, 8]:
@@ -99,7 +99,7 @@ class ObservationManager(DataSource):
99
99
  return cloud_mask
100
100
 
101
101
  def _check_rainrate(self) -> bool:
102
- """Check if rainrate in file"""
102
+ """Check if rainrate in file."""
103
103
  try:
104
104
  self.getvar("rainrate")
105
105
  except RuntimeError:
@@ -122,7 +122,7 @@ class ObservationManager(DataSource):
122
122
  return rainrate > rainrate_threshold
123
123
 
124
124
  def _generate_iwc_masks(self) -> None:
125
- """Generates ice water content variables with different masks"""
125
+ """Generates ice water content variables with different masks."""
126
126
  # TODO: Differences with CloudnetPy (status=2) and Legacy data (status=3)
127
127
  iwc = self.getvar(self.obs)
128
128
  iwc_status = self.getvar("iwc_retrieval_status")
@@ -131,21 +131,21 @@ class ObservationManager(DataSource):
131
131
  self._mask_iwc(iwc, iwc_status)
132
132
 
133
133
  def _mask_iwc(self, iwc: np.ndarray, iwc_status: np.ndarray) -> None:
134
- """Leaves only reliable data and corrected liquid attenuation"""
134
+ """Leaves only reliable data and corrected liquid attenuation."""
135
135
  iwc_mask = ma.copy(iwc)
136
136
  iwc_mask[np.bitwise_and(iwc_status != 1, iwc_status != 2)] = ma.masked
137
137
  self.append_data(iwc_mask, "iwc")
138
138
 
139
139
  def _mask_iwc_att(self, iwc: np.ndarray, iwc_status: np.ndarray) -> None:
140
140
  """Leaves only where reliable data, corrected liquid attenuation
141
- and uncorrected liquid attenuation
141
+ and uncorrected liquid attenuation.
142
142
  """
143
143
  iwc_att = ma.copy(iwc)
144
144
  iwc_att[iwc_status > 3] = ma.masked
145
145
  self.append_data(iwc_att, "iwc_att")
146
146
 
147
147
  def _get_rain_iwc(self, iwc_status: np.ndarray) -> None:
148
- """Finds columns where is rain, return boolean of x-axis shape"""
148
+ """Finds columns where is rain, return boolean of x-axis shape."""
149
149
  iwc_rain = np.zeros(iwc_status.shape, dtype=bool)
150
150
  iwc_rain[iwc_status == 5] = 1
151
151
  iwc_rain = np.any(iwc_rain, axis=1)
@@ -10,7 +10,7 @@ from cloudnetpy.model_evaluation.products.observation_products import Observatio
10
10
 
11
11
 
12
12
  def check_model_file_list(name: str, models: list) -> None:
13
- """Check that files in models are from same model and date"""
13
+ """Check that files in models are from same model and date."""
14
14
  for m in models:
15
15
  if name not in m:
16
16
  logging.error("Invalid model file set")
@@ -35,16 +35,14 @@ def calculate_advection_time(
35
35
  wind: ma.MaskedArray,
36
36
  sampling: int,
37
37
  ) -> np.ndarray:
38
- """Calculates time which variable takes to go through the time window
38
+ """Calculates time which variable takes to go through the time window.
39
39
 
40
- Notes
40
+ Notes:
41
41
  Wind speed is stronger in upper levels, so advection time is more
42
42
  there then lower levels. Effect is small in a mid-latitudes,
43
43
  but visible in a tropics.
44
44
 
45
45
  sampling = 1 -> hour, sampling 1/6 -> 10min
46
-
47
- References
48
46
  """
49
47
  t_adv = resolution * 1000 / wind / 60**2
50
48
  t_adv[t_adv.mask] = 0
@@ -76,7 +74,7 @@ def get_adv_indices(
76
74
 
77
75
 
78
76
  def get_obs_window_size(ind_x: np.ndarray, ind_y: np.ndarray) -> tuple | None:
79
- """Returns shape (tuple) of window area, where values are True"""
77
+ """Returns shape (tuple) of window area, where values are True."""
80
78
  x = np.where(ind_x)[0]
81
79
  y = np.where(ind_y)[0]
82
80
  if np.any(x) and np.any(y):
@@ -90,5 +88,5 @@ def add_date(model_obj: ModelManager, obs_obj: ObservationManager) -> None:
90
88
 
91
89
 
92
90
  def average_column_sum(data: np.ndarray) -> np.ndarray:
93
- """Returns average sum of columns which have any data"""
91
+ """Returns average sum of columns which have any data."""
94
92
  return np.nanmean(np.nansum(data, 1) > 0)
@@ -9,7 +9,7 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
9
9
 
10
10
 
11
11
  class DayStatistics:
12
- """Class for calculating statistical analysis of day scale products
12
+ """Class for calculating statistical analysis of day scale products.
13
13
 
14
14
  Class generates one statistical method at the time with given model data
15
15
  and observation data of wanted product.
@@ -107,7 +107,7 @@ def combine_masked_indices(
107
107
  model: ma.MaskedArray,
108
108
  observation: ma.MaskedArray,
109
109
  ) -> tuple[ma.MaskedArray, ma.MaskedArray]:
110
- """Connects two array masked indices to one and add in two array same mask"""
110
+ """Connects two array masked indices to one and add in two array same mask."""
111
111
  observation[np.where(np.isnan(observation))] = ma.masked
112
112
  model[model < np.min(observation)] = ma.masked
113
113
  combine_mask = model.mask + observation.mask
cloudnetpy/output.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Functions for file writing."""
2
+
2
3
  import datetime
3
4
  import logging
4
5
  from os import PathLike
@@ -140,10 +141,11 @@ def get_l1b_title(instrument: Instrument, location: str) -> str:
140
141
 
141
142
 
142
143
  def get_references(identifier: str | None = None, extra: list | None = None) -> str:
143
- """ "Returns references.
144
+ """Returns references.
144
145
 
145
146
  Args:
146
147
  identifier: Cloudnet file type, e.g., 'iwc'.
148
+ extra: List of additional references to include
147
149
 
148
150
  """
149
151
  references = "https://doi.org/10.21105/joss.02123"
@@ -1,11 +1,11 @@
1
1
  """Metadata for plotting module."""
2
+
2
3
  from collections.abc import Sequence
3
4
  from typing import NamedTuple
4
5
 
5
6
 
6
7
  class PlotMeta(NamedTuple):
7
- """
8
- A class representing the metadata for plotting.
8
+ """A class representing the metadata for plotting.
9
9
 
10
10
  Attributes:
11
11
  cmap: The colormap to be used for the plot.
@@ -1,4 +1,5 @@
1
1
  """Misc. plotting routines for Cloudnet products."""
2
+
2
3
  import os.path
3
4
  import re
4
5
  import textwrap
@@ -27,8 +28,7 @@ from cloudnetpy.plotting.plot_meta import ATTRIBUTES, PlotMeta
27
28
 
28
29
  @dataclass
29
30
  class PlotParameters:
30
- """
31
- Class representing the parameters for plotting.
31
+ """Class representing the parameters for plotting.
32
32
 
33
33
  Attributes:
34
34
  dpi: The resolution of the plot in dots per inch.
@@ -57,9 +57,8 @@ class PlotParameters:
57
57
 
58
58
 
59
59
  class Dimensions:
60
- """
61
- Dimensions of a generated figure in pixels. Elements such as the figure
62
- title, labels, colorbar and legend are exluded from the margins.
60
+ """Dimensions of a generated figure in pixels. Elements such as the figure
61
+ title, labels, colorbar and legend are excluded from the margins.
63
62
 
64
63
  Attributes:
65
64
  width (int): Figure width in pixels.
@@ -121,9 +120,8 @@ class FigureData:
121
120
  sharex=True,
122
121
  )
123
122
  fig.subplots_adjust(left=0.06, right=0.73)
124
- if n_subplots == 1:
125
- axes = [axes]
126
- return fig, axes
123
+ axes_list = [axes] if isinstance(axes, Axes) else axes.tolist()
124
+ return fig, axes_list
127
125
 
128
126
  def add_subtitle(self, fig: Figure) -> None:
129
127
  fig.suptitle(
@@ -309,7 +307,7 @@ class Plot:
309
307
  "air_pressure": (multiply, 0.01, "hPa"),
310
308
  "relative_humidity": (multiply, 100, "%"),
311
309
  "rainfall_amount": (multiply, 1000, "mm"),
312
- "air_temperature": (add, -273.15, "\u00B0C"),
310
+ "air_temperature": (add, -273.15, "\u00b0C"),
313
311
  }
314
312
  conversion_method, conversion, units = units_conversion.get(
315
313
  self.sub_plot.variable.name, (multiply, 1, None)
@@ -756,8 +754,7 @@ def generate_figure(
756
754
  output_filename: os.PathLike | str | None = None,
757
755
  options: PlotParameters | None = None,
758
756
  ) -> Dimensions:
759
- """
760
- Generate a figure based on the given filename and variables.
757
+ """Generate a figure based on the given filename and variables.
761
758
 
762
759
  Args:
763
760
  filename: The path to the input file.
@@ -1,4 +1,5 @@
1
1
  """Module for creating classification file."""
2
+
2
3
  import numpy as np
3
4
  from numpy import ma
4
5
 
@@ -70,20 +71,20 @@ def _get_target_classification(
70
71
  classification = ma.zeros(bits["cold"].shape, dtype=int)
71
72
  classification[bits["droplet"] & ~bits["falling"]] = 1 # Cloud droplets
72
73
  classification[~bits["droplet"] & bits["falling"]] = 2 # Drizzle or rain
73
- classification[
74
- bits["droplet"] & bits["falling"]
75
- ] = 3 # Drizzle or rain and droplets
74
+ classification[bits["droplet"] & bits["falling"]] = (
75
+ 3 # Drizzle or rain and droplets
76
+ )
76
77
  classification[~bits["droplet"] & bits["falling"] & bits["cold"]] = 4 # ice
77
- classification[
78
- bits["droplet"] & bits["falling"] & bits["cold"]
79
- ] = 5 # ice + supercooled
78
+ classification[bits["droplet"] & bits["falling"] & bits["cold"]] = (
79
+ 5 # ice + supercooled
80
+ )
80
81
  classification[bits["melting"]] = 6 # melting layer
81
82
  classification[bits["melting"] & bits["droplet"]] = 7 # melting + droplets
82
83
  classification[bits["aerosol"]] = 8 # aerosols
83
84
  classification[bits["insect"] & ~clutter] = 9 # insects
84
- classification[
85
- bits["aerosol"] & bits["insect"] & ~clutter
86
- ] = 10 # insects + aerosols
85
+ classification[bits["aerosol"] & bits["insect"] & ~clutter] = (
86
+ 10 # insects + aerosols
87
+ )
87
88
  classification[clutter & ~bits["aerosol"]] = 0
88
89
  return classification
89
90
 
@@ -1,6 +1,7 @@
1
1
  """Module for creating Cloudnet droplet effective radius
2
2
  using the Frisch et al. 2002 method.
3
3
  """
4
+
4
5
  from typing import NamedTuple
5
6
 
6
7
  import numpy as np
@@ -33,7 +34,7 @@ def generate_der(
33
34
  parameters: Parameters | None = None,
34
35
  ) -> str:
35
36
  """Generates Cloudnet effective radius of liquid water droplets
36
- product acording to Frisch et al. 2002.
37
+ product according to Frisch et al. 2002.
37
38
 
38
39
  This function calculates liquid droplet effective radius def
39
40
  using the Frisch method. In this method, def is calculated
@@ -44,7 +45,7 @@ def generate_der(
44
45
  categorize_file: Categorize file name.
45
46
  output_file: Output file name.
46
47
  uuid: Set specific UUID for the file.
47
- parameters: Tuple of specific fixed paramaters
48
+ parameters: Tuple of specific fixed parameters
48
49
  (ddBZ, N, dN, sigma_x, dsigma_x, dQ)
49
50
  used in Frisch approach.
50
51
 
@@ -1,5 +1,5 @@
1
- """Module for creating Cloudnet drizzle product.
2
- """
1
+ """Module for creating Cloudnet drizzle product."""
2
+
3
3
  import numpy as np
4
4
  from numpy import ma
5
5
  from scipy.special import gamma
@@ -113,7 +113,7 @@ class DrizzleProducts:
113
113
  return np.divide(a, b, out=np.zeros_like(a), where=b != 0)
114
114
 
115
115
  def _calc_lwc(self) -> np.ndarray:
116
- """Calculates drizzle liquid water content (kg m-3)"""
116
+ """Calculates drizzle liquid water content (kg m-3)."""
117
117
  rho_water = 1000
118
118
  dia, mu, s = (self._params.get(key) for key in ("Do", "mu", "S"))
119
119
  dia = ma.array(dia)
@@ -185,7 +185,7 @@ class SpectralWidth:
185
185
  def _calc_horizontal_wind(self) -> np.ndarray:
186
186
  """Calculates magnitude of horizontal wind.
187
187
 
188
- Returns
188
+ Returns:
189
189
  ndarray: Horizontal wind (m s-1).
190
190
 
191
191
  """
@@ -1,4 +1,5 @@
1
1
  """Module for creating Cloudnet ice effective radius file using Z-T method."""
2
+
2
3
  import numpy as np
3
4
  from numpy import ma
4
5
 
@@ -1,4 +1,5 @@
1
1
  """Module for creating Cloudnet ice water content file using Z-T method."""
2
+
2
3
  import numpy as np
3
4
  from numpy import ma
4
5
 
@@ -91,9 +92,9 @@ class IwcSource(IceSource):
91
92
  retrieval_uncertainty,
92
93
  error_uncorrected,
93
94
  )
94
- iwc_error[
95
- (~ice_classification.is_ice | ice_classification.ice_above_rain)
96
- ] = ma.masked
95
+ iwc_error[(~ice_classification.is_ice | ice_classification.ice_above_rain)] = (
96
+ ma.masked
97
+ )
97
98
  self.append_data(iwc_error, f"{self.product}_error")
98
99
  return lwp_prior, retrieval_uncertainty
99
100
 
@@ -1,6 +1,7 @@
1
1
  """Module for creating Cloudnet liquid water content file using scaled-adiabatic
2
2
  method.
3
3
  """
4
+
4
5
  import numpy as np
5
6
  from numpy import ma
6
7
 
@@ -228,9 +229,7 @@ class CloudAdjustor:
228
229
 
229
230
  def _has_converged(self, ind: int) -> bool:
230
231
  lwc_sum = ma.sum(self.lwc_adiabatic[ind, :])
231
- if lwc_sum * self.lwc_source.dheight > self.lwc_source.lwp[ind]:
232
- return True
233
- return False
232
+ return lwc_sum * self.lwc_source.dheight > self.lwc_source.lwp[ind]
234
233
 
235
234
  def _out_of_bound(self, ind: int) -> bool:
236
235
  return ind >= self.lwc.shape[1] - 1
@@ -15,8 +15,7 @@ from cloudnetpy.products import product_tools
15
15
  def generate_mwr_single(
16
16
  mwr_l1c_file: str, output_file: str, uuid: str | None = None
17
17
  ) -> str:
18
- """
19
- Generates MWR single-pointing product including liquid water path, integrated
18
+ """Generates MWR single-pointing product including liquid water path, integrated
20
19
  water vapor, etc. from zenith measurements.
21
20
 
22
21
  Args:
@@ -36,8 +35,7 @@ def generate_mwr_single(
36
35
  def generate_mwr_multi(
37
36
  mwr_l1c_file: str, output_file: str, uuid: str | None = None
38
37
  ) -> str:
39
- """
40
- Generates MWR multiple-pointing product, including relative humidity profiles,
38
+ """Generates MWR multiple-pointing product, including relative humidity profiles,
41
39
  etc. from scanning measurements.
42
40
 
43
41
  Args:
@@ -1,4 +1,5 @@
1
1
  """General helper classes and functions for all products."""
2
+
2
3
  import os
3
4
  from typing import NamedTuple
4
5
 
@@ -185,7 +186,7 @@ class IceSource(DataSource):
185
186
  def _get_coefficients(self) -> IceCoefficients:
186
187
  """Returns coefficients for ice effective radius retrieval.
187
188
 
188
- References
189
+ References:
189
190
  Hogan et.al. 2006, https://doi.org/10.1175/JAM2340.1
190
191
  """
191
192
  if self.product == "ier":
cloudnetpy/utils.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """This module contains general helper functions."""
2
+
2
3
  import datetime
3
4
  import logging
4
5
  import os
@@ -75,7 +76,7 @@ def seconds2date(time_in_seconds: float, epoch: Epoch = (2001, 1, 1)) -> list:
75
76
  epoch_in_seconds = datetime.datetime.timestamp(
76
77
  datetime.datetime(*epoch, tzinfo=timezone.utc),
77
78
  )
78
- timestamp = time_in_seconds + epoch_in_seconds
79
+ timestamp = float(time_in_seconds) + epoch_in_seconds
79
80
  return (
80
81
  datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc)
81
82
  .strftime("%Y %m %d %H %M %S")
@@ -84,7 +85,7 @@ def seconds2date(time_in_seconds: float, epoch: Epoch = (2001, 1, 1)) -> list:
84
85
 
85
86
 
86
87
  def datetime2decimal_hours(data: np.ndarray | list) -> np.ndarray:
87
- """Converts array of datetime to decimal_hours"""
88
+ """Converts array of datetime to decimal_hours."""
88
89
  output = []
89
90
  for timestamp in data:
90
91
  t = timestamp.time()
@@ -153,13 +154,10 @@ def rebin_2d(
153
154
  statistic: Statistic to be calculated. Possible statistics are 'mean', 'std'.
154
155
  Default is 'mean'.
155
156
  n_min: Minimum number of points to have good statistics in a bin. Default is 1.
157
+ mask_zeros: Whether to mask 0 values in the returned array. Default is True.
156
158
 
157
159
  Returns:
158
160
  tuple: Rebinned data with shape (N, m) and indices of bins without enough data.
159
-
160
- Notes:
161
- 0-values are masked in the returned array.
162
-
163
161
  """
164
162
  edges = binvec(x_new)
165
163
  result = np.zeros((len(x_new), array.shape[1]))
@@ -208,6 +206,7 @@ def rebin_1d(
208
206
  x_new: 1-D target vector (center points) with shape (N,).
209
207
  statistic: Statistic to be calculated. Possible statistics are 'mean', 'std'.
210
208
  Default is 'mean'.
209
+ mask_zeros: Whether to mask 0 values in the returned array. Default is True.
211
210
 
212
211
  Returns:
213
212
  Re-binned data with shape (N,).
@@ -656,7 +655,7 @@ def isscalar(array: np.ndarray | float | list) -> bool:
656
655
 
657
656
  By "scalar" we mean that array has a single value.
658
657
 
659
- Examples
658
+ Examples:
660
659
  >>> isscalar(1)
661
660
  True
662
661
  >>> isscalar([1])
@@ -787,17 +786,13 @@ def range_to_height(range_los: np.ndarray, tilt_angle: float) -> np.ndarray:
787
786
 
788
787
  def is_empty_line(line: str) -> bool:
789
788
  """Tests if a line (of a text file) is empty."""
790
- if line in ("\n", "\r\n"):
791
- return True
792
- return False
789
+ return line in ("\n", "\r\n")
793
790
 
794
791
 
795
792
  def is_timestamp(timestamp: str) -> bool:
796
- """Tests if the input string is formatted as -yyyy-mm-dd hh:mm:ss"""
793
+ """Tests if the input string is formatted as -yyyy-mm-dd hh:mm:ss."""
797
794
  reg_exp = re.compile(r"-\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}")
798
- if reg_exp.match(timestamp) is not None:
799
- return True
800
- return False
795
+ return reg_exp.match(timestamp) is not None
801
796
 
802
797
 
803
798
  def get_sorted_filenames(file_path: str, extension: str) -> list:
cloudnetpy/version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  MAJOR = 1
2
2
  MINOR = 61
3
- PATCH = 15
3
+ PATCH = 16
4
4
  __version__ = f"{MAJOR}.{MINOR}.{PATCH}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cloudnetpy
3
- Version: 1.61.15
3
+ Version: 1.61.16
4
4
  Summary: Python package for Cloudnet processing
5
5
  Author: Simo Tukiainen
6
6
  License: MIT License
@@ -0,0 +1,115 @@
1
+ cloudnetpy/__init__.py,sha256=X_FqY-4yg5GUj5Edo14SToLEos6JIsC3fN-v1FUgQoA,43
2
+ cloudnetpy/cloudnetarray.py,sha256=Ol1ha4RPAmFZANL__U5CaMKX4oYMXYR6OnjoCZ9w3eo,7077
3
+ cloudnetpy/concat_lib.py,sha256=8Ek059RMLAfbbXCkX90cgnhw_8ZpcDrxw1yPvwtuitU,9846
4
+ cloudnetpy/constants.py,sha256=YVbi2porUnKIzO_PdGeH9pEO9gKa95vDcj6TBMSreoY,734
5
+ cloudnetpy/datasource.py,sha256=j7N4g59HPvOBWle-W9bOUF0BfRLgvR4zwOi_B50cI7Q,7921
6
+ cloudnetpy/exceptions.py,sha256=wrI0bZTwmS5C_cqOmvlJ8XJSEFyzuD1eD4voGJc_Gjg,1584
7
+ cloudnetpy/metadata.py,sha256=v_VDo2vbdTxB0zIsfP69IcrwSKiRlLpsGdq6JPI4CoA,5306
8
+ cloudnetpy/output.py,sha256=YkCaxVkG_Mt2hng_IVnhygHteV4UMKzKALkeFZwFJL8,14822
9
+ cloudnetpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ cloudnetpy/utils.py,sha256=JV0Fawnme1HoZgoiidV3eIzsn6vx0AEjBNmI1CcrBsA,28517
11
+ cloudnetpy/version.py,sha256=GO9xFdIg8VR1hdOJ3fERTqkbnoe6P85YNUOxd1OjCq4,73
12
+ cloudnetpy/categorize/__init__.py,sha256=gP5q3Vis1y9u9OWgA_idlbjfWXYN_S0IBSWdwBhL_uU,69
13
+ cloudnetpy/categorize/atmos.py,sha256=G4DmEJCt1FAPYyt7oXzBH47JTeb5lUOGDakkviOXblE,12390
14
+ cloudnetpy/categorize/atmos_utils.py,sha256=64uenj2uxj3P3Blaq_pBN1pBjcF-X4LYNt-uTOjvevg,3778
15
+ cloudnetpy/categorize/categorize.py,sha256=aoIxbBEwUFO-Xx_oofKM68aL0KEJuGi3OaWMKCCuUK8,17827
16
+ cloudnetpy/categorize/classify.py,sha256=l8XoO42GJysio5ODX6qoxWHD9RqtMyz_-T8ZOpOkMxU,9219
17
+ cloudnetpy/categorize/containers.py,sha256=aL_55tTDYjICS_TnG1u0FwBeXDS0S4mfDMU0kY_DUbs,4312
18
+ cloudnetpy/categorize/disdrometer.py,sha256=keU3pFvKtk840A0oLwAyNDuqOCswBPJEKf2bV0YWyA8,2004
19
+ cloudnetpy/categorize/droplet.py,sha256=894VHdL9ScaB8f1oxXwM2la4ShXd-uWywQDINoaoiD8,8687
20
+ cloudnetpy/categorize/falling.py,sha256=aI09_6H24x34lYr3vnKIgjWB0wzTkxOA6wE-gkdf6bs,4386
21
+ cloudnetpy/categorize/freezing.py,sha256=c4k5AIgfBpvw64EaVVVYPi2Fx4SpHk1cyfceE1ydD28,3755
22
+ cloudnetpy/categorize/insects.py,sha256=0pHJ-T-j3G9dbDU82xe8gsnVRyww3-ljdZ1SMAP9UKQ,5765
23
+ cloudnetpy/categorize/lidar.py,sha256=YQrM_LOz8NQrrD9l9HyujV1GSGwkQ8LMqXN13bEJRW4,2605
24
+ cloudnetpy/categorize/melting.py,sha256=mYdOKxfTC2InB8NdOPwr_7NpbouQMm-9f2Q1kfTqIJE,6262
25
+ cloudnetpy/categorize/model.py,sha256=hSmE-3hCzbpA26AcMtSeDUVlLHvtmODy_37b2kJO2eA,5536
26
+ cloudnetpy/categorize/mwr.py,sha256=rTyVYaMotXl7LRgRQBBcrLInsrWGl4sFdZ4pyM4jXMc,1436
27
+ cloudnetpy/categorize/radar.py,sha256=C4R74E_jmLOJqXLrfhdrAitHRHHA79UYuChz9VLxy58,13722
28
+ cloudnetpy/instruments/__init__.py,sha256=_jejVwi_viSZehmAOkEqTNI-0-exGgAJ_bHW1IRRwTI,398
29
+ cloudnetpy/instruments/basta.py,sha256=_OTnySd36ktvxk_swWBzbv_H4AVGlkF_Ce3KtPGD1rE,3758
30
+ cloudnetpy/instruments/campbell_scientific.py,sha256=2WHfBKQjtRSl0AqvtPeX7G8Hdi3Dn0WbvoAppFOMbA8,5270
31
+ cloudnetpy/instruments/ceilo.py,sha256=-QZNgdTiFmz0G57CU_gZ1cQtYzppgkFJqjndfleefH0,8924
32
+ cloudnetpy/instruments/ceilometer.py,sha256=-aPEZs_r0Gxeu53PHeWAkZMB2BUdauS47tkL7RFxo6k,12078
33
+ cloudnetpy/instruments/cl61d.py,sha256=g6DNBFju3wYhLFl32DKmC8pUup7y-EupXoUU0fuoGGA,1990
34
+ cloudnetpy/instruments/cloudnet_instrument.py,sha256=RG5HJxGM6p0F-IGyr85fvOizcMmgx48OeD_XeIsrgSU,3367
35
+ cloudnetpy/instruments/copernicus.py,sha256=nmgqGOjVQFngj7BNbpcuCwA-W3yksvBbqn__iq7MyDk,6469
36
+ cloudnetpy/instruments/galileo.py,sha256=yQBedd7dmDnwuWi1MtXOsg4-RyRx0uRAXumCY4YuH9k,4686
37
+ cloudnetpy/instruments/hatpro.py,sha256=EulfWATfJL-p7CJ1i3pntcIr4E2GzLScYIu249laR10,8514
38
+ cloudnetpy/instruments/instruments.py,sha256=jG5TYnZ8bdCZXnI303ZsaJBEdSKaIjKMbkGtnq6kQX0,3261
39
+ cloudnetpy/instruments/lufft.py,sha256=tip8UPqm1pelvIL-KvVkj9tx4B52gOQZ73lgf6lmd6Q,3630
40
+ cloudnetpy/instruments/mira.py,sha256=EyzEBTpWfDlgaspZVuIfaP4l73GYSVnSzEzBZc0lZNg,9333
41
+ cloudnetpy/instruments/mrr.py,sha256=efxqsxy0G-qj4uCWVZztgNwGxYooSxIpI6K2tYF36GA,5833
42
+ cloudnetpy/instruments/nc_lidar.py,sha256=5gQG9PApnNPrHmS9_zanl8HEYIQuGRpbnzC3wfTcOyQ,1705
43
+ cloudnetpy/instruments/nc_radar.py,sha256=7bKwIZZHM-RagW9AEdgldweaulfy9n61N3RH5fopTqo,6936
44
+ cloudnetpy/instruments/pollyxt.py,sha256=YuVEHr-BX31rtVOFsWGU-SQFAmcxpXL26eyCVMz_9hw,8933
45
+ cloudnetpy/instruments/radiometrics.py,sha256=ECN_bSfcV8Evdgfho9-Dl8RThXkAhHzIEj4DPOawSTc,7626
46
+ cloudnetpy/instruments/rpg.py,sha256=siPmiyOGdB_OtlnIiP0PAt_cySnped0clLLGnyzw02o,17317
47
+ cloudnetpy/instruments/rpg_reader.py,sha256=2eYu-tBd0QyreUKqJT726aIMbA29aIxXK-UJCkOXMLM,11356
48
+ cloudnetpy/instruments/toa5.py,sha256=CfmmBMv5iMGaWHIGBK01Rw24cuXC1R1RMNTXkmsm340,1760
49
+ cloudnetpy/instruments/vaisala.py,sha256=GGuA_v4S7kR9yApSr1-d0ETzNj4ehEZ7-pD1-AdPYRE,14662
50
+ cloudnetpy/instruments/weather_station.py,sha256=1vRMErPWQET5IoiCRxd2-DUbFDP_RFGdfC91PaDf6So,15221
51
+ cloudnetpy/instruments/disdrometer/__init__.py,sha256=lyjwttWvFvuwYxEkusoAvgRcbBmglmOp5HJOpXUqLWo,93
52
+ cloudnetpy/instruments/disdrometer/common.py,sha256=g52iK2aNp3Z88kovUmGVpC54NZomPa9D871gzO0AmQ4,9267
53
+ cloudnetpy/instruments/disdrometer/parsivel.py,sha256=HJZrEysQkx9MiIVPDV25CYHpXi_SjgZlgO-otoaKK34,25640
54
+ cloudnetpy/instruments/disdrometer/thies.py,sha256=8V_1wx-8ncBJKs40e1_kvpOh3wj5UIl8YwvkVHf34MA,10086
55
+ cloudnetpy/model_evaluation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ cloudnetpy/model_evaluation/file_handler.py,sha256=0Pg7V6eo1G6KYeE10B6lR8hIKIJoseO-pBaorcW42rY,6446
57
+ cloudnetpy/model_evaluation/metadata.py,sha256=PAsnOqcUoV3CJwplgWiVCF9Zt4io8tqj7CIgS4fEL-8,8412
58
+ cloudnetpy/model_evaluation/model_metadata.py,sha256=CxpY6RPm7GOTBBmPhcNVVpm9ateUmHSUwGtFXTLq3To,1436
59
+ cloudnetpy/model_evaluation/utils.py,sha256=Z9VqYVdtY9yTr2JeVfBn4nccIVWCN5Fd-BCyB_qYI-A,154
60
+ cloudnetpy/model_evaluation/plotting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
+ cloudnetpy/model_evaluation/plotting/plot_meta.py,sha256=K18Ugohh24uVAIxjZgJsmK80YwsMstm6B7ptVafONAw,3557
62
+ cloudnetpy/model_evaluation/plotting/plot_tools.py,sha256=gV042W_AHidwPsRe2L57xdWbt3W-utcHMt_9FmfYK3M,5033
63
+ cloudnetpy/model_evaluation/plotting/plotting.py,sha256=2c-7x_7meZ1Fq1ZFIbtZqIteG_gt32UZ---erEuXYbw,31209
64
+ cloudnetpy/model_evaluation/products/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
+ cloudnetpy/model_evaluation/products/advance_methods.py,sha256=rng3ZLR1Arv1AGUzq0Ehu-65628PC5LZVKpHSUpCIW8,8526
66
+ cloudnetpy/model_evaluation/products/grid_methods.py,sha256=4no7mbKc9HlEXSNKPioqLmFZxUefuI-yqX0-Ej2jMzU,9067
67
+ cloudnetpy/model_evaluation/products/model_products.py,sha256=uWi7zXQI7kR_ju0SL_BC1wozcq5DhaCcT-XZq33Q-bA,6861
68
+ cloudnetpy/model_evaluation/products/observation_products.py,sha256=vrbHT008T4RFXM2pKm7dWPLKb1smD4rUNOM6IhUcU_w,5500
69
+ cloudnetpy/model_evaluation/products/product_resampling.py,sha256=IuWvtwpya76URh1WmTTgtLxAo4HZxkz6GmftpZkMCGo,3640
70
+ cloudnetpy/model_evaluation/products/tools.py,sha256=lXnQ9XIEf5zqk_haY3mSrekPyGbAwNWvd6ZOol1Ip1Q,2918
71
+ cloudnetpy/model_evaluation/statistics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
+ cloudnetpy/model_evaluation/statistics/statistical_methods.py,sha256=9mmSNK9qsKNCdktUINxEExaz1oqf6zWyqJvP6dCV9zc,5984
73
+ cloudnetpy/model_evaluation/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
+ cloudnetpy/model_evaluation/tests/e2e/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
+ cloudnetpy/model_evaluation/tests/e2e/conftest.py,sha256=TENW6O-OsqNmFEtS0gZLlzVCoF0eXfLBEuFGB5bZ-k8,305
76
+ cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
+ cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py,sha256=1BhHb6hhJF68pTXhzd_tsUtIRzyt14aZHdw1HAIWNPo,1289
78
+ cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py,sha256=2PrANQKp7vMlWp1y0XPQnkNpcpYx0kScrCOlRgS48z0,1787
79
+ cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
+ cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py,sha256=9hndE5kVF31PH5zkjBnN9Jko865PMGHawRg13BujD6I,1368
81
+ cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py,sha256=0pgqdGmv4T9lbQ4DYXAsAHEf05WgKmO4xUSNIzx3Lf0,1903
82
+ cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
+ cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py,sha256=IFcPj-Vce9Yn0CfCy9gASxRf7NzlKFMfsDHzAuapY4I,1306
84
+ cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py,sha256=ANBA0LVao3Xrm-prRnwUmxM6BdQzqM7GZNKB3uz5BXQ,1725
85
+ cloudnetpy/model_evaluation/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
+ cloudnetpy/model_evaluation/tests/unit/conftest.py,sha256=WL_FgrDeoUYGp4PKjb37HLu79D9uu33PGQL40_ctqS0,7446
87
+ cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py,sha256=IkoAVtsWVFrPpFqQOLAPHKb9qgV-KjGGVEtWMudeiSo,10079
88
+ cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py,sha256=qkNPfHI25EE0-BXk73TijpeM7YwswX7e41-764o5lqE,26254
89
+ cloudnetpy/model_evaluation/tests/unit/test_model_products.py,sha256=FRbYLshSHH2E527uJPwvUIyZKTsPFSZrwDsPsNrFSSU,3475
90
+ cloudnetpy/model_evaluation/tests/unit/test_observation_products.py,sha256=P-W5QwRHMtem6p5SyyH7p9TvHGro3XW1baQcIwh6nFg,4892
91
+ cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py,sha256=POdypGWjV2NA4DCU7w8Unk_IdPfOpUb1qBDhfA3x1Bw,9222
92
+ cloudnetpy/model_evaluation/tests/unit/test_plotting.py,sha256=h9V8JKmrO4v9bOvv-UjRa06sZJQPhDNVHGBSImDdtkI,3277
93
+ cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py,sha256=Ra3r4V0qbqkpDuaTYvEIbaasl0nZ5gmTLR4eGC0glBQ,9724
94
+ cloudnetpy/model_evaluation/tests/unit/test_tools.py,sha256=Ia_VrLdV2NstX5gbx_3AZTOAlrgLAy_xFZ8fHYVX0xI,3817
95
+ cloudnetpy/plotting/__init__.py,sha256=lg9Smn4BI0dVBgnDLC3JVJ4GmwoSnO-qoSd4ApvwV6Y,107
96
+ cloudnetpy/plotting/plot_meta.py,sha256=JHrr-4A9fhqdi_tQFe6mR4Fdry3hkI-lmmVu5Ny2vco,15979
97
+ cloudnetpy/plotting/plotting.py,sha256=uOYm_-3NVjVLQ8cRB6zjIW54FzuVHcVNOUR0LTLGgDc,32936
98
+ cloudnetpy/products/__init__.py,sha256=2hRb5HG9hNrxH1if5laJkLeFeaZCd5W1q3hh4ewsX0E,273
99
+ cloudnetpy/products/classification.py,sha256=bNG8W1CMgGoUBpXopQjYAW3F-uEJGyojXb4A5jmErHo,7921
100
+ cloudnetpy/products/der.py,sha256=sITzQbvutU5u1D16hDG2Ke7XB9gBxSP22OLy2Yhi1zI,12446
101
+ cloudnetpy/products/drizzle.py,sha256=58C9Mo6oRXR8KpbVPghbJvHvFX9GfS3xUp058pbf0qw,10804
102
+ cloudnetpy/products/drizzle_error.py,sha256=4GwlHRtNbk9ks7bGtXCco-wXbcDOKeAQwKmbhzut6Qk,6132
103
+ cloudnetpy/products/drizzle_tools.py,sha256=LR2AtbFQRGFrJ2LGyiLxOfbnlznVLydXvb8RFDR0_4E,10848
104
+ cloudnetpy/products/ier.py,sha256=ge1f_aYick20Nlznq8zbBl5umWlTP-UwMivy4Y05Sck,7839
105
+ cloudnetpy/products/iwc.py,sha256=Q8dXV3JF3JUQgwkmQFOKakm21Tnf8oCWsH0CSqIEKl4,10209
106
+ cloudnetpy/products/lwc.py,sha256=LsqEPluRW1JmFnM8GiQHfciBR6q5CXjr8D-D2qcGQeM,18774
107
+ cloudnetpy/products/mie_lu_tables.nc,sha256=It4fYpqJXlqOgL8jeZ-PxGzP08PMrELIDVe55y9ob58,16637951
108
+ cloudnetpy/products/mwr_tools.py,sha256=3esU5cG5GI2WVmOENqrJ0FbMuxLegADv7q8TB0RorGg,4674
109
+ cloudnetpy/products/product_tools.py,sha256=VNw2diJj30POz68-3qNVkJP7r9AUspT_d1Fp0BbeIx8,10414
110
+ docs/source/conf.py,sha256=IKiFWw6xhUd8NrCg0q7l596Ck1d61XWeVjIFHVSG9Og,1490
111
+ cloudnetpy-1.61.16.dist-info/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
112
+ cloudnetpy-1.61.16.dist-info/METADATA,sha256=vwWCuMNtULjIu2yR0V3ql1dC6_ITghYCfEWyW1oDL0I,5785
113
+ cloudnetpy-1.61.16.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
114
+ cloudnetpy-1.61.16.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
115
+ cloudnetpy-1.61.16.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (71.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5