cloudnetpy 1.49.9__py3-none-any.whl → 1.87.3__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 (116) hide show
  1. cloudnetpy/categorize/__init__.py +1 -2
  2. cloudnetpy/categorize/atmos_utils.py +297 -67
  3. cloudnetpy/categorize/attenuation.py +31 -0
  4. cloudnetpy/categorize/attenuations/__init__.py +37 -0
  5. cloudnetpy/categorize/attenuations/gas_attenuation.py +30 -0
  6. cloudnetpy/categorize/attenuations/liquid_attenuation.py +84 -0
  7. cloudnetpy/categorize/attenuations/melting_attenuation.py +78 -0
  8. cloudnetpy/categorize/attenuations/rain_attenuation.py +84 -0
  9. cloudnetpy/categorize/categorize.py +332 -156
  10. cloudnetpy/categorize/classify.py +127 -125
  11. cloudnetpy/categorize/containers.py +107 -76
  12. cloudnetpy/categorize/disdrometer.py +40 -0
  13. cloudnetpy/categorize/droplet.py +23 -21
  14. cloudnetpy/categorize/falling.py +53 -24
  15. cloudnetpy/categorize/freezing.py +25 -12
  16. cloudnetpy/categorize/insects.py +35 -23
  17. cloudnetpy/categorize/itu.py +243 -0
  18. cloudnetpy/categorize/lidar.py +36 -41
  19. cloudnetpy/categorize/melting.py +34 -26
  20. cloudnetpy/categorize/model.py +84 -37
  21. cloudnetpy/categorize/mwr.py +18 -14
  22. cloudnetpy/categorize/radar.py +215 -102
  23. cloudnetpy/cli.py +578 -0
  24. cloudnetpy/cloudnetarray.py +43 -89
  25. cloudnetpy/concat_lib.py +218 -78
  26. cloudnetpy/constants.py +28 -10
  27. cloudnetpy/datasource.py +61 -86
  28. cloudnetpy/exceptions.py +49 -20
  29. cloudnetpy/instruments/__init__.py +5 -0
  30. cloudnetpy/instruments/basta.py +29 -12
  31. cloudnetpy/instruments/bowtie.py +135 -0
  32. cloudnetpy/instruments/ceilo.py +138 -115
  33. cloudnetpy/instruments/ceilometer.py +164 -80
  34. cloudnetpy/instruments/cl61d.py +21 -5
  35. cloudnetpy/instruments/cloudnet_instrument.py +74 -36
  36. cloudnetpy/instruments/copernicus.py +108 -30
  37. cloudnetpy/instruments/da10.py +54 -0
  38. cloudnetpy/instruments/disdrometer/common.py +126 -223
  39. cloudnetpy/instruments/disdrometer/parsivel.py +453 -94
  40. cloudnetpy/instruments/disdrometer/thies.py +254 -87
  41. cloudnetpy/instruments/fd12p.py +201 -0
  42. cloudnetpy/instruments/galileo.py +65 -23
  43. cloudnetpy/instruments/hatpro.py +123 -49
  44. cloudnetpy/instruments/instruments.py +113 -1
  45. cloudnetpy/instruments/lufft.py +39 -17
  46. cloudnetpy/instruments/mira.py +268 -61
  47. cloudnetpy/instruments/mrr.py +187 -0
  48. cloudnetpy/instruments/nc_lidar.py +19 -8
  49. cloudnetpy/instruments/nc_radar.py +109 -55
  50. cloudnetpy/instruments/pollyxt.py +135 -51
  51. cloudnetpy/instruments/radiometrics.py +313 -59
  52. cloudnetpy/instruments/rain_e_h3.py +171 -0
  53. cloudnetpy/instruments/rpg.py +321 -189
  54. cloudnetpy/instruments/rpg_reader.py +74 -40
  55. cloudnetpy/instruments/toa5.py +49 -0
  56. cloudnetpy/instruments/vaisala.py +95 -343
  57. cloudnetpy/instruments/weather_station.py +774 -105
  58. cloudnetpy/metadata.py +90 -19
  59. cloudnetpy/model_evaluation/file_handler.py +55 -52
  60. cloudnetpy/model_evaluation/metadata.py +46 -20
  61. cloudnetpy/model_evaluation/model_metadata.py +1 -1
  62. cloudnetpy/model_evaluation/plotting/plot_tools.py +32 -37
  63. cloudnetpy/model_evaluation/plotting/plotting.py +327 -117
  64. cloudnetpy/model_evaluation/products/advance_methods.py +92 -83
  65. cloudnetpy/model_evaluation/products/grid_methods.py +88 -63
  66. cloudnetpy/model_evaluation/products/model_products.py +43 -35
  67. cloudnetpy/model_evaluation/products/observation_products.py +41 -35
  68. cloudnetpy/model_evaluation/products/product_resampling.py +17 -7
  69. cloudnetpy/model_evaluation/products/tools.py +29 -20
  70. cloudnetpy/model_evaluation/statistics/statistical_methods.py +30 -20
  71. cloudnetpy/model_evaluation/tests/e2e/conftest.py +3 -3
  72. cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +9 -5
  73. cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +15 -14
  74. cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +9 -5
  75. cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +15 -14
  76. cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +9 -5
  77. cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +15 -14
  78. cloudnetpy/model_evaluation/tests/unit/conftest.py +42 -41
  79. cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +41 -48
  80. cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +216 -194
  81. cloudnetpy/model_evaluation/tests/unit/test_model_products.py +23 -21
  82. cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +37 -38
  83. cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +43 -40
  84. cloudnetpy/model_evaluation/tests/unit/test_plotting.py +30 -36
  85. cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +68 -31
  86. cloudnetpy/model_evaluation/tests/unit/test_tools.py +33 -26
  87. cloudnetpy/model_evaluation/utils.py +2 -1
  88. cloudnetpy/output.py +170 -111
  89. cloudnetpy/plotting/__init__.py +2 -1
  90. cloudnetpy/plotting/plot_meta.py +562 -822
  91. cloudnetpy/plotting/plotting.py +1142 -704
  92. cloudnetpy/products/__init__.py +1 -0
  93. cloudnetpy/products/classification.py +370 -88
  94. cloudnetpy/products/der.py +85 -55
  95. cloudnetpy/products/drizzle.py +77 -34
  96. cloudnetpy/products/drizzle_error.py +15 -11
  97. cloudnetpy/products/drizzle_tools.py +79 -59
  98. cloudnetpy/products/epsilon.py +211 -0
  99. cloudnetpy/products/ier.py +27 -50
  100. cloudnetpy/products/iwc.py +55 -48
  101. cloudnetpy/products/lwc.py +96 -70
  102. cloudnetpy/products/mwr_tools.py +186 -0
  103. cloudnetpy/products/product_tools.py +170 -128
  104. cloudnetpy/utils.py +455 -240
  105. cloudnetpy/version.py +2 -2
  106. {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info}/METADATA +44 -40
  107. cloudnetpy-1.87.3.dist-info/RECORD +127 -0
  108. {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info}/WHEEL +1 -1
  109. cloudnetpy-1.87.3.dist-info/entry_points.txt +2 -0
  110. docs/source/conf.py +2 -2
  111. cloudnetpy/categorize/atmos.py +0 -361
  112. cloudnetpy/products/mwr_multi.py +0 -68
  113. cloudnetpy/products/mwr_single.py +0 -75
  114. cloudnetpy-1.49.9.dist-info/RECORD +0 -112
  115. {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info/licenses}/LICENSE +0 -0
  116. {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info}/top_level.txt +0 -0
@@ -1,361 +0,0 @@
1
- """ This module contains functions to calculate
2
- various atmospheric parameters.
3
- """
4
- import numpy as np
5
- import scipy.constants
6
- from numpy import ma
7
-
8
- from cloudnetpy import constants as con
9
- from cloudnetpy import utils
10
- from cloudnetpy.categorize.atmos_utils import (
11
- calc_psychrometric_constant,
12
- calc_saturation_vapor_pressure,
13
- )
14
- from cloudnetpy.categorize.containers import ClassificationResult
15
- from cloudnetpy.categorize.model import Model
16
-
17
- M_TO_KM = 0.001
18
- TWO_WAY = 2
19
-
20
-
21
- def calc_lwc_change_rate(temperature: np.ndarray, pressure: np.ndarray) -> np.ndarray:
22
- """Returns rate of change of condensable water (LWC).
23
-
24
- Calculates the theoretical adiabatic rate of increase of LWC
25
- with height, given the cloud base temperature and pressure.
26
-
27
- Args:
28
- temperature: Temperature of cloud base (K).
29
- pressure: Pressure of cloud base (Pa).
30
-
31
- Returns:
32
- dlwc/dz (kg m-3 m-1)
33
-
34
- References:
35
- Brenguier, 1991, https://bit.ly/2QCSJtb
36
-
37
- """
38
- svp = calc_saturation_vapor_pressure(temperature)
39
- svp_mixing_ratio = calc_mixing_ratio(svp, pressure)
40
- air_density = calc_air_density(pressure, temperature, svp_mixing_ratio)
41
- kelvin_per_kg = calc_psychrometric_constant(temperature)
42
- pressure_difference = pressure - svp
43
- f1 = kelvin_per_kg - 1
44
- f2 = 1 / (
45
- kelvin_per_kg
46
- + (con.LATENT_HEAT * svp_mixing_ratio * air_density / pressure_difference)
47
- )
48
- f3 = con.MW_RATIO * svp * pressure_difference**-2
49
- dqs_dp = f1 * f2 * f3
50
- dqs_dz = dqs_dp * air_density**2 * -scipy.constants.g
51
- return dqs_dz
52
-
53
-
54
- def calc_mixing_ratio(svp: np.ndarray, pressure: np.ndarray) -> np.ndarray:
55
- """Calculates mixing ratio from saturation vapor pressure and pressure.
56
-
57
- Args:
58
- svp: Saturation vapor pressure (Pa).
59
- pressure: Atmospheric pressure (Pa).
60
-
61
- Returns:
62
- Mixing ratio (kg kg-1).
63
-
64
- """
65
- return con.MW_RATIO * svp / (pressure - svp)
66
-
67
-
68
- def calc_air_density(
69
- pressure: np.ndarray, temperature: np.ndarray, svp_mixing_ratio: np.ndarray
70
- ) -> np.ndarray:
71
- """Calculates air density (kg m-3).
72
-
73
- Args:
74
- pressure: Pressure (Pa).
75
- temperature: Temperature (K).
76
- svp_mixing_ratio: Saturation vapor pressure mixing ratio (kg/kg).
77
-
78
- Returns:
79
- Air density (kg m-3).
80
-
81
- """
82
- return pressure / (con.RS * temperature * (0.6 * svp_mixing_ratio + 1))
83
-
84
-
85
- def get_attenuations(data: dict, classification: ClassificationResult) -> dict:
86
- """Calculates attenuations due to atmospheric gases and liquid water.
87
-
88
- Args:
89
- data: Containing :class:`Model` and :class:`Mwr` instances.
90
- classification: A :class:`ClassificationResult` instance.
91
-
92
- Returns:
93
- Dictionary containing `radar_gas_atten`, `radar_liquid_atten`,
94
- `liquid_atten_err`, `liquid_corrected` and `liquid_uncorrected` fields.
95
-
96
- """
97
- gas = GasAttenuation(data, classification)
98
- liquid = LiquidAttenuation(data, classification)
99
- return {
100
- "radar_gas_atten": gas.atten,
101
- "radar_liquid_atten": liquid.atten,
102
- "liquid_atten_err": liquid.atten_err,
103
- "liquid_corrected": liquid.corrected,
104
- "liquid_uncorrected": liquid.uncorrected,
105
- }
106
-
107
-
108
- class Attenuation:
109
- """Base class for gas and liquid attenuations.
110
-
111
- Args:
112
- model: The :class:`Model` instance.
113
- classification: The :class:`ClassificationResult` instance.
114
-
115
- Attributes:
116
- classification (ClassificationResult): The :class:`ClassificationResult`
117
- instance.
118
-
119
- """
120
-
121
- def __init__(self, model: Model, classification: ClassificationResult):
122
- self._dheight = utils.mdiff(model.height)
123
- self._model = model.data_dense
124
- self._liquid_in_pixel = utils.isbit(classification.category_bits, 0)
125
- self.classification = classification
126
-
127
-
128
- class GasAttenuation(Attenuation):
129
- """Radar gas attenuation class. Child of Attenuation.
130
-
131
- Args:
132
- data: Containing :class:`Model` instance.
133
- classification: The :class:`ClassificationResult` instance.
134
-
135
- Attributes:
136
- atten (ndarray): Gas attenuation (dB).
137
-
138
- """
139
-
140
- def __init__(self, data: dict, classification: ClassificationResult):
141
- super().__init__(data["model"], classification)
142
- self.atten = self._calc_gas_atten()
143
-
144
- def _calc_gas_atten(self) -> np.ndarray:
145
- specific_atten = ma.copy(self._model["specific_gas_atten"])
146
- specific_atten_corrected = self._fix_atten_in_liquid(specific_atten)
147
- gas_atten = self._specific_to_gas_atten(specific_atten_corrected)
148
- return gas_atten
149
-
150
- def _fix_atten_in_liquid(self, atten: np.ndarray) -> np.ndarray:
151
- saturated_atten = self._model["specific_saturated_gas_atten"]
152
- atten[self._liquid_in_pixel] = saturated_atten[self._liquid_in_pixel]
153
- return atten
154
-
155
- def _specific_to_gas_atten(self, specific_atten: np.ndarray) -> np.ndarray:
156
- layer1_atten = self._model["gas_atten"][:, 0]
157
- atten_cumsum = ma.cumsum(specific_atten, axis=1)
158
- atten = TWO_WAY * atten_cumsum * self._dheight * M_TO_KM
159
- atten += utils.transpose(layer1_atten)
160
- atten = np.insert(atten, 0, layer1_atten, axis=1)[:, :-1]
161
- return ma.array(atten, mask=atten_cumsum.mask)
162
-
163
-
164
- class LiquidAttenuation(Attenuation):
165
- """Radar liquid attenuation class. Child of Attenuation.
166
-
167
- Args:
168
- data: Containing :class:`Model` and :class:`Mwr` instances.
169
- classification: The :class:`ClassificationResult` instance.
170
-
171
- Attributes:
172
- atten (ndarray): Radar liquid attenuation (dB).
173
- atten_err (ndarray): Error of radar liquid attenuation (dB).
174
- uncorrected (ndarray): Boolean array denoting uncorrected pixels.
175
- corrected (ndarray): Boolean array denoting corrected pixels.
176
-
177
- """
178
-
179
- def __init__(self, data: dict, classification: ClassificationResult):
180
- super().__init__(data["model"], classification)
181
- self._mwr = data["mwr"].data
182
- self._lwc_dz_err = self._get_lwc_change_rate_error()
183
- self.atten = self._get_liquid_atten()
184
- self.atten_err = self._get_liquid_atten_err()
185
- self.uncorrected = self._find_pixels_hard_to_correct()
186
- self.corrected = self._find_corrected_pixels()
187
- self._mask_uncorrected_attenuation()
188
-
189
- def _get_lwc_change_rate_error(self) -> np.ndarray:
190
- atmosphere = (self._model["temperature"], self._model["pressure"])
191
- return fill_clouds_with_lwc_dz(atmosphere, self._liquid_in_pixel)
192
-
193
- def _get_liquid_atten(self) -> ma.MaskedArray:
194
- """Finds radar liquid attenuation."""
195
- lwp = ma.copy(self._mwr["lwp"][:])
196
- lwp[lwp < 0] = 0
197
- lwc = calc_adiabatic_lwc(self._lwc_dz_err, self._dheight)
198
- lwc_scaled = distribute_lwp_to_liquid_clouds(lwc, lwp)
199
- return self._calc_attenuation(lwc_scaled)
200
-
201
- def _get_liquid_atten_err(self) -> ma.MaskedArray:
202
- """Finds radar liquid attenuation error."""
203
- lwc_err_scaled = distribute_lwp_to_liquid_clouds(
204
- self._lwc_dz_err, self._mwr["lwp_error"][:]
205
- )
206
- return self._calc_attenuation(lwc_err_scaled)
207
-
208
- def _calc_attenuation(self, lwc_scaled: np.ndarray) -> ma.MaskedArray:
209
- """Calculates liquid attenuation (dB)."""
210
- liquid_attenuation = ma.zeros(lwc_scaled.shape)
211
- spec_liq = self._model["specific_liquid_atten"]
212
- lwp_cumsum = ma.cumsum(lwc_scaled[:, :-1] * spec_liq[:, :-1], axis=1)
213
- liquid_attenuation[:, 1:] = TWO_WAY * lwp_cumsum * M_TO_KM
214
- return liquid_attenuation
215
-
216
- def _find_pixels_hard_to_correct(self) -> np.ndarray:
217
- melting_layer = utils.isbit(self.classification.category_bits, 3)
218
- hard_to_correct = np.cumsum(melting_layer, axis=1) >= 1
219
- hard_to_correct[self.classification.is_rain, :] = True
220
- attenuated = self._find_attenuated_part_of_atmosphere()
221
- hard_to_correct[attenuated & self.atten.mask] = True
222
- return hard_to_correct
223
-
224
- def _find_corrected_pixels(self) -> np.ndarray:
225
- proper_values = self.atten > 0
226
- assert isinstance(proper_values, ma.MaskedArray)
227
- return proper_values.filled(False) & ~self.uncorrected
228
-
229
- def _mask_uncorrected_attenuation(self) -> None:
230
- self.atten[self.uncorrected] = ma.masked
231
-
232
- def _find_attenuated_part_of_atmosphere(self) -> np.ndarray:
233
- return np.cumsum(self._lwc_dz_err, axis=1) > 0
234
-
235
-
236
- def fill_clouds_with_lwc_dz(atmosphere: tuple, is_liquid: np.ndarray) -> np.ndarray:
237
- """Fills liquid clouds with lwc change rate at the cloud bases.
238
-
239
- Args:
240
- atmosphere: 2-element tuple containing temperature (K) and pressure (Pa).
241
- is_liquid: Boolean array indicating presence of liquid clouds.
242
-
243
- Returns:
244
- Liquid water content change rate (kg/m3/m), so that for each cloud the base
245
- value is filled for the whole cloud.
246
-
247
- """
248
- lwc_dz = get_lwc_change_rate_at_bases(atmosphere, is_liquid)
249
- lwc_dz_filled = ma.zeros(lwc_dz.shape)
250
- lwc_dz_filled[is_liquid] = utils.ffill(lwc_dz[is_liquid])
251
- return lwc_dz_filled
252
-
253
-
254
- def get_lwc_change_rate_at_bases(
255
- atmosphere: tuple, is_liquid: np.ndarray
256
- ) -> np.ndarray:
257
- """Finds LWC change rate in liquid cloud bases.
258
-
259
- Args:
260
- atmosphere: 2-element tuple containing temperature (K) and pressure (Pa).
261
- is_liquid: Boolean array indicating presence of liquid clouds.
262
-
263
- Returns:
264
- Liquid water content change rate at cloud bases (kg/m3/m).
265
-
266
- """
267
- liquid_bases = find_cloud_bases(is_liquid)
268
- lwc_dz = ma.zeros(liquid_bases.shape)
269
- lwc_dz[liquid_bases] = calc_lwc_change_rate(
270
- atmosphere[0][liquid_bases], atmosphere[1][liquid_bases]
271
- )
272
- return lwc_dz
273
-
274
-
275
- def find_cloud_bases(array: np.ndarray) -> np.ndarray:
276
- """Finds bases of clouds.
277
-
278
- Args:
279
- array: 2D boolean array denoting clouds or some other similar field.
280
-
281
- Returns:
282
- Boolean array indicating bases of the individual clouds.
283
-
284
- """
285
- zeros = np.zeros(array.shape[0])
286
- array_padded = np.insert(array, 0, zeros, axis=1).astype(int)
287
- return np.diff(array_padded, axis=1) == 1
288
-
289
-
290
- def find_cloud_tops(array: np.ndarray) -> np.ndarray:
291
- """Finds tops of clouds.
292
-
293
- Args:
294
- array: 2D boolean array denoting clouds or some other similar field.
295
-
296
- Returns:
297
- Boolean array indicating tops of the individual clouds.
298
-
299
- """
300
- array_flipped = np.fliplr(array)
301
- bases_of_flipped = find_cloud_bases(array_flipped)
302
- return np.fliplr(bases_of_flipped)
303
-
304
-
305
- def find_lowest_cloud_bases(
306
- cloud_mask: np.ndarray, height: np.ndarray
307
- ) -> ma.MaskedArray:
308
- """Finds altitudes of cloud bases."""
309
- cloud_heights = cloud_mask * height
310
- return _find_lowest_heights(cloud_heights)
311
-
312
-
313
- def find_highest_cloud_tops(
314
- cloud_mask: np.ndarray, height: np.ndarray
315
- ) -> ma.MaskedArray:
316
- """Finds altitudes of cloud tops."""
317
- cloud_heights = cloud_mask * height
318
- cloud_heights_flipped = np.fliplr(cloud_heights)
319
- return _find_lowest_heights(cloud_heights_flipped)
320
-
321
-
322
- def _find_lowest_heights(cloud_heights: np.ndarray) -> ma.MaskedArray:
323
- inds = (cloud_heights != 0).argmax(axis=1)
324
- heights = np.array([cloud_heights[i, ind] for i, ind in enumerate(inds)])
325
- return ma.masked_equal(heights, 0.0)
326
-
327
-
328
- def calc_adiabatic_lwc(lwc_change_rate: np.ndarray, dheight: float) -> np.ndarray:
329
- """Calculates adiabatic liquid water content (kg/m3).
330
-
331
- Args:
332
- lwc_change_rate: Liquid water content change rate (kg/m3/m) calculated at the
333
- base of each cloud and filled to that cloud.
334
- dheight: Median difference of the height vector (m).
335
-
336
- Returns:
337
- Liquid water content (kg/m3).
338
-
339
- """
340
- is_liquid = lwc_change_rate != 0
341
- ind_from_base = utils.cumsumr(is_liquid, axis=1)
342
- return ind_from_base * dheight * lwc_change_rate
343
-
344
-
345
- def distribute_lwp_to_liquid_clouds(lwc: np.ndarray, lwp: np.ndarray) -> np.ndarray:
346
- """Finds LWC that would produce measured LWP.
347
-
348
- Calculates LWP-weighted, normalized LWC. This is the measured
349
- LWP distributed to liquid cloud pixels according to their
350
- theoretical proportion, i.e., sum(scaled LWC) = measured LWP.
351
-
352
- Args:
353
- lwc: 2D liquid water content (kg/m3).
354
- lwp: 1D liquid water path (kg/m2).
355
-
356
- Returns:
357
- 2D LWP-weighted, normalized LWC (kg/m2).
358
-
359
- """
360
- lwc_sum = ma.sum(lwc, axis=1)
361
- return (lwc.T / lwc_sum * lwp).T
@@ -1,68 +0,0 @@
1
- from tempfile import NamedTemporaryFile
2
-
3
- import netCDF4
4
- from mwrpy.level2.write_lev2_nc import lev2_to_nc
5
- from mwrpy.version import __version__ as mwrpy_version
6
-
7
- from cloudnetpy import output, utils
8
- from cloudnetpy.products import product_tools
9
-
10
-
11
- def generate_mwr_multi(
12
- mwr_l1c_file: str, output_file: str, uuid: str | None = None
13
- ) -> str:
14
- file_uuid = uuid if uuid is not None else utils.get_uuid()
15
- coeffs = product_tools.get_mwrpy_coeffs(mwr_l1c_file)
16
-
17
- with (
18
- NamedTemporaryFile() as temp_file,
19
- NamedTemporaryFile() as abs_hum_file,
20
- NamedTemporaryFile() as rel_hum_file,
21
- NamedTemporaryFile() as t_pot_file,
22
- NamedTemporaryFile() as eq_temp_file,
23
- ):
24
- for prod, file in zip(
25
- ("2P02", "2P03", "2P04", "2P07", "2P08"),
26
- (temp_file, abs_hum_file, rel_hum_file, t_pot_file, eq_temp_file),
27
- ):
28
- lev2_to_nc(
29
- coeffs,
30
- prod,
31
- mwr_l1c_file,
32
- file.name,
33
- temp_file=temp_file.name if prod not in ("2P02", "2P03") else None,
34
- hum_file=abs_hum_file.name if prod not in ("2P02", "2P03") else None,
35
- )
36
-
37
- with (
38
- netCDF4.Dataset(output_file, "w", format="NETCDF4_CLASSIC") as nc_output,
39
- netCDF4.Dataset(mwr_l1c_file, "r") as nc_l1c,
40
- netCDF4.Dataset(temp_file.name, "r") as nc_temp,
41
- netCDF4.Dataset(rel_hum_file.name, "r") as nc_rel_hum,
42
- netCDF4.Dataset(t_pot_file.name, "r") as nc_t_pot,
43
- netCDF4.Dataset(eq_temp_file.name, "r") as nc_eq_temp,
44
- ):
45
- nc_output.createDimension("time", len(nc_temp.variables["time"][:]))
46
- nc_output.createDimension("height", len(nc_temp.variables["height"][:]))
47
-
48
- for source, variables in (
49
- (nc_l1c, ("latitude", "longitude", "altitude")),
50
- (nc_temp, ("time", "height", "temperature")),
51
- (nc_rel_hum, ("relative_humidity",)),
52
- (nc_t_pot, ("potential_temperature",)),
53
- (nc_eq_temp, ("equivalent_potential_temperature",)),
54
- ):
55
- output.copy_variables(source, nc_output, variables)
56
-
57
- output.add_standard_global_attributes(nc_output, file_uuid)
58
- output.copy_global(nc_l1c, nc_output, ("year", "month", "day", "location"))
59
- nc_output.title = f"MWR multiple-pointing from {nc_l1c.location}"
60
- nc_output.cloudnet_file_type = "mwr-multi"
61
- nc_output.mwrpy_version = mwrpy_version
62
- output.fix_time_attributes(nc_output)
63
- nc_output.history = (
64
- f"{utils.get_time()} - MWR multiple-pointing product created \n"
65
- f"{nc_l1c.history}"
66
- )
67
-
68
- return file_uuid
@@ -1,75 +0,0 @@
1
- from tempfile import NamedTemporaryFile
2
-
3
- import netCDF4
4
- from mwrpy.level2.write_lev2_nc import lev2_to_nc
5
- from mwrpy.version import __version__ as mwrpy_version
6
-
7
- from cloudnetpy import output, utils
8
- from cloudnetpy.products import product_tools
9
-
10
-
11
- def generate_mwr_single(
12
- mwr_l1c_file: str, output_file: str, uuid: str | None = None
13
- ) -> str:
14
- file_uuid = uuid if uuid is not None else utils.get_uuid()
15
- coeffs = product_tools.get_mwrpy_coeffs(mwr_l1c_file)
16
-
17
- with (
18
- NamedTemporaryFile() as lwp_file,
19
- NamedTemporaryFile() as iwv_file,
20
- NamedTemporaryFile() as t_prof_file,
21
- NamedTemporaryFile() as abs_hum_file,
22
- ):
23
- for prod, file in zip(
24
- ("2I01", "2I02", "2P01", "2P03"),
25
- (lwp_file, iwv_file, t_prof_file, abs_hum_file),
26
- ):
27
- lev2_to_nc(coeffs, prod, mwr_l1c_file, file.name)
28
-
29
- with (
30
- netCDF4.Dataset(output_file, "w", format="NETCDF4_CLASSIC") as nc_output,
31
- netCDF4.Dataset(lwp_file.name, "r") as nc_lwp,
32
- netCDF4.Dataset(iwv_file.name, "r") as nc_iwv,
33
- netCDF4.Dataset(abs_hum_file.name, "r") as nc_hum,
34
- netCDF4.Dataset(t_prof_file.name, "r") as nc_t_prof,
35
- netCDF4.Dataset(mwr_l1c_file, "r") as nc_l1c,
36
- ):
37
- nc_output.createDimension("height", len(nc_t_prof.variables["height"][:]))
38
- nc_output.createDimension("time", len(nc_lwp.variables["time"][:]))
39
-
40
- for source, variables in (
41
- (nc_iwv, ("iwv",)),
42
- (nc_hum, ("absolute_humidity",)),
43
- (nc_t_prof, ("temperature", "height")),
44
- (nc_l1c, ("latitude", "longitude", "altitude")),
45
- (
46
- nc_lwp,
47
- (
48
- "time",
49
- "lwp",
50
- "lwp_random_error",
51
- "lwp_offset",
52
- "lwp_systematic_error",
53
- "azimuth_angle",
54
- ),
55
- ),
56
- ):
57
- output.copy_variables(source, nc_output, variables)
58
-
59
- output.add_standard_global_attributes(nc_output, file_uuid)
60
- output.copy_global(nc_l1c, nc_output, ("year", "month", "day", "location"))
61
- nc_output.title = f"MWR single-pointing from {nc_l1c.location}"
62
- nc_output.cloudnet_file_type = "mwr-single"
63
- nc_output.mwrpy_version = mwrpy_version
64
- output.fix_time_attributes(nc_output)
65
- output.replace_attribute_with_standard_value(
66
- nc_output,
67
- ("lwp", "iwv", "temperature", "azimuth_angle"),
68
- ("units", "long_name", "standard_name"),
69
- )
70
- nc_output.history = (
71
- f"{utils.get_time()} - MWR single-pointing product created \n"
72
- f"{nc_l1c.history}"
73
- )
74
-
75
- return file_uuid
@@ -1,112 +0,0 @@
1
- cloudnetpy/__init__.py,sha256=X_FqY-4yg5GUj5Edo14SToLEos6JIsC3fN-v1FUgQoA,43
2
- cloudnetpy/cloudnetarray.py,sha256=v1WUaZX_ZeUWZdCOOPsJr2oy8xebc-nacbwkbLy3Bms,6747
3
- cloudnetpy/concat_lib.py,sha256=3HmHXSIGPkm4yDlNg6TKFQYtsDs7fvcO3dG0Pwt-Jd8,9517
4
- cloudnetpy/constants.py,sha256=CC6qwVMcznFY6H4j3wz4mxUFnSn81QbScGi-PjF_3i4,402
5
- cloudnetpy/datasource.py,sha256=k3kNlSV1g5n951qbY4aiXDJckOcVtL2YbccxbqAnZzw,7143
6
- cloudnetpy/exceptions.py,sha256=sXcxhlyz_8ICLa1eliujfescrUuK1UM0aAEXexx91Gw,981
7
- cloudnetpy/metadata.py,sha256=-oRmr4HWjG_-P8jOjdBYMgRkOYnJKr6jmGIF-38Tno8,5023
8
- cloudnetpy/output.py,sha256=6ysoCcrk_pS_fWhyQoJX29V403f7UOloFw0SZjHCwKk,14236
9
- cloudnetpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- cloudnetpy/utils.py,sha256=lKVPF7VpbX2IPXTztI8eJZm8rLne9IuhMngQXKP12vg,26971
11
- cloudnetpy/version.py,sha256=9-68xePfMHaLncSAg8bypChDl3kWclNySiDUpZXxX6k,72
12
- cloudnetpy/categorize/__init__.py,sha256=gP5q3Vis1y9u9OWgA_idlbjfWXYN_S0IBSWdwBhL_uU,69
13
- cloudnetpy/categorize/atmos.py,sha256=_8VU0UpzKh7ZFh3TbGs-g3SYMRsRIR5mio0PmP66O7o,12372
14
- cloudnetpy/categorize/atmos_utils.py,sha256=6WdfGqzOvnaDW7vlMMrZBJIxW_eHQdjH-Xl_iPv1TTI,3716
15
- cloudnetpy/categorize/categorize.py,sha256=mSwHPxFmT6ceuZbo-seBXW_5vqhQKONzLsG2jjLMWaY,16675
16
- cloudnetpy/categorize/classify.py,sha256=1-6HD4wQIw2pCP7TLlDhXaOTezFHKKDIFuYrJKdvWCE,8762
17
- cloudnetpy/categorize/containers.py,sha256=n22WHXORoC0qhuA9ttl1TyZ1tY4BTwiHMMnyAvuF6uw,4535
18
- cloudnetpy/categorize/droplet.py,sha256=YKRBCquMMNxJf_Zi9hSiwGzwLCBVhLjY0VLKU-kjrgg,8694
19
- cloudnetpy/categorize/falling.py,sha256=k21J-lsN07YxtMkIIwEnQmJjgqaw4dpNMMVDqzWdKHU,3424
20
- cloudnetpy/categorize/freezing.py,sha256=sNt02CK45QkOCrWymgOQIrdo0E4C3rqmJQo1h_A74AE,3538
21
- cloudnetpy/categorize/insects.py,sha256=9fW3HErD2MDWAOU-NhW6e19CNaMYEfiMFTq-t-7KTcU,5156
22
- cloudnetpy/categorize/lidar.py,sha256=Ev5dMg8X-CHLR2xVJCyqgyQEoyBJsUgj7B3lkOHkpc8,2521
23
- cloudnetpy/categorize/melting.py,sha256=DFlIHYgOjyIj3KNopgrTf2mC8awGa6tQWLvkbRG1lL8,6032
24
- cloudnetpy/categorize/model.py,sha256=NkYX5DLbjDqt9sCOAYuSmVKTe1kuLS0G1geIaXqLPNE,5070
25
- cloudnetpy/categorize/mwr.py,sha256=PSXf-OukhRLlQIpXtkKhcdgiy-fQy-X-CaVh_G42P9s,1411
26
- cloudnetpy/categorize/radar.py,sha256=3Or3_jWxs9rbwJ3XKzl4hPilg0bFdCRMrbkIAuS3H08,12425
27
- cloudnetpy/instruments/__init__.py,sha256=-MOKjKNu8PRciX_PXEBRihGVaKrPIc_2sR-n0D9NEkc,374
28
- cloudnetpy/instruments/basta.py,sha256=9KeP65uxOTUH1YavaI8sp35n-VcM-WgtqMfB3bxKSPo,3714
29
- cloudnetpy/instruments/ceilo.py,sha256=jo7BF54gu65ePKbfhHNkB3Z6n70R5ANOfBTrBPm11G8,7778
30
- cloudnetpy/instruments/ceilometer.py,sha256=j3Wb2wJlSGLaZkguPe3nv4751TfGd-hJjithKYNOsO4,10498
31
- cloudnetpy/instruments/cl61d.py,sha256=Qk2YQRrRkivc6nW2gOI7KKLt9rR4JAWF0bfbj8Hd_lY,1653
32
- cloudnetpy/instruments/cloudnet_instrument.py,sha256=nnaOtJJotXzYdoMoYGKeLZ1MciDYBx7tqVBFKBQjKL0,3304
33
- cloudnetpy/instruments/copernicus.py,sha256=FDS7Rsunp4ieTPFh_T_LXvreNi5_HTv4ZzR3OnTcAX8,5013
34
- cloudnetpy/instruments/galileo.py,sha256=F_XyoAb9PR-ifGhqhXziKnv0KfyOh-yEBaE1NgRMzNg,4318
35
- cloudnetpy/instruments/hatpro.py,sha256=H0FgTIxIp3fl59nrTS9z8NyRX7ugkR32B2N1uwEOWtQ,7438
36
- cloudnetpy/instruments/instruments.py,sha256=FGiN0369--1z8uYzgDP9_1A7DFLL_Cl4-Ca-OMsjBdI,2824
37
- cloudnetpy/instruments/lufft.py,sha256=E2qzvya206gNiML7BSM6vm1lzeOMBePrIuPT81NHPvw,3397
38
- cloudnetpy/instruments/mira.py,sha256=5wmmJGYHVglxaCpSuL92WIisADRD-85k_jlsC9mKLgQ,5063
39
- cloudnetpy/instruments/nc_lidar.py,sha256=9FSsInEM8fdyyhgNXb2INBjb5OEGFE5ZaVSowHjzoCA,1386
40
- cloudnetpy/instruments/nc_radar.py,sha256=hjmtgLuBPnfsyRInOZeKzAw3oZ82WSumrlPpycqBbjk,5530
41
- cloudnetpy/instruments/pollyxt.py,sha256=Ezuq9rJxQREKz5ed1sdMsuqHZwlKMQC_w5CZSpzQQko,7847
42
- cloudnetpy/instruments/radiometrics.py,sha256=r73gDsB6ZSVRfMPkkf2mnhVSX8MxGTOuTjQyVmaQ5v8,7304
43
- cloudnetpy/instruments/rpg.py,sha256=szH59pXNKp6AfiL65_EQ5MRHSXduhO-uJoryfQpT7Mg,15741
44
- cloudnetpy/instruments/rpg_reader.py,sha256=8YaEZogUdIfIgVyZtvZ5f_lqm37SGcvmGCWdhaXG9xI,10711
45
- cloudnetpy/instruments/vaisala.py,sha256=wOziQs_NuPTcZm8fg0UH9HCslhBCWromyxulQgS8xyw,14266
46
- cloudnetpy/instruments/weather_station.py,sha256=gwPh4opv8SDf_vi4yBq5oHe8IFxGUF7ktB5yOBerd1g,5829
47
- cloudnetpy/instruments/disdrometer/__init__.py,sha256=lyjwttWvFvuwYxEkusoAvgRcbBmglmOp5HJOpXUqLWo,93
48
- cloudnetpy/instruments/disdrometer/common.py,sha256=_IWuhRtFIiYdIUjnS9R715C4eyr0dGd96ZDvQWJYetc,15006
49
- cloudnetpy/instruments/disdrometer/parsivel.py,sha256=q4h7VNkCHq0Qutf3P2BgNcX0ijB8CU9C90bsbI3L1WY,13069
50
- cloudnetpy/instruments/disdrometer/thies.py,sha256=YB328052yqlkOW7sGZSfUUCwLS3GPzYrWDiSg8C3C-s,5022
51
- cloudnetpy/model_evaluation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
- cloudnetpy/model_evaluation/file_handler.py,sha256=xYEkCsgwpF1kQNkG3ydxGM6DjFd-tryZ9ULlA9HUIAE,6321
53
- cloudnetpy/model_evaluation/metadata.py,sha256=4w7rzkxYLO-ihpC4xeqRvHJEOPwM68_LBINHBWXTV8k,8404
54
- cloudnetpy/model_evaluation/model_metadata.py,sha256=4W9qvJMCWqIgvRdI3coWq_dFCCVCsF59qemxGM4iJ1w,1411
55
- cloudnetpy/model_evaluation/utils.py,sha256=PjaqKkpsSotRY91u_louWENibqaZ9dnE5Az1EsNWN6U,117
56
- cloudnetpy/model_evaluation/plotting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
- cloudnetpy/model_evaluation/plotting/plot_meta.py,sha256=K18Ugohh24uVAIxjZgJsmK80YwsMstm6B7ptVafONAw,3557
58
- cloudnetpy/model_evaluation/plotting/plot_tools.py,sha256=vu-NFDBzzkvaKJjeey8yBzVa7GPeLYEAhIcIUrVS0Kk,5215
59
- cloudnetpy/model_evaluation/plotting/plotting.py,sha256=Ux3VvKJBNIWZN4awPo8XsU37znZhfzQFbTUf_dWnyro,26254
60
- cloudnetpy/model_evaluation/products/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
- cloudnetpy/model_evaluation/products/advance_methods.py,sha256=y4nzuLgOaCqmvMR4wWgie7KiWWz7FcyBMOtdx1iuE-U,8697
62
- cloudnetpy/model_evaluation/products/grid_methods.py,sha256=dR8f7HSHkducd033hWs3dGq374AR3W13s4QdMtCIIo0,8377
63
- cloudnetpy/model_evaluation/products/model_products.py,sha256=NidddlJsS6tqPbHiEgCDcY6cwXVXedi_Zp8iQKwx2Os,6629
64
- cloudnetpy/model_evaluation/products/observation_products.py,sha256=RtUqvf11iUXYd5iRnUVlkJKM288YXpYHUgQ0E0ccvTw,5344
65
- cloudnetpy/model_evaluation/products/product_resampling.py,sha256=5IXwDjzK_SuL0ITNHcl7Q_GR1WPagWr37CWapfSOmRw,3568
66
- cloudnetpy/model_evaluation/products/tools.py,sha256=Q1jh_KsBt_ZAy7uKki-svA1h5k0TUs_i1gL4wT41-50,2835
67
- cloudnetpy/model_evaluation/statistics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- cloudnetpy/model_evaluation/statistics/statistical_methods.py,sha256=aHF271vc2I67Cqa7j-22CVczXjVz8ByB0G9u4rraSA4,5898
69
- cloudnetpy/model_evaluation/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- cloudnetpy/model_evaluation/tests/e2e/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
- cloudnetpy/model_evaluation/tests/e2e/conftest.py,sha256=oEpiAOZnoaNTWsx2wSWD7YUp5HwjwFGv1fevz_o-Tq8,287
72
- cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
- cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py,sha256=LE_nz4Ir44P5hjKzdFJde1m4w69h0MZXMoEdpk6AucQ,1238
74
- cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py,sha256=4LqTCSmNmmexLSWHc_-q0XRiFoihh1Y3xuxhkYtSRMc,1754
75
- cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
- cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py,sha256=VbONC12QLu2iYL9HsAXFkgwEgtKZPMXQUmoXnGBaO7k,1317
77
- cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py,sha256=oQvYZYOPo5NuDYgxoD4kOQILLeWQbGHol3gtcDPlPzk,1870
78
- cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
- cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py,sha256=_VpfClNdcdUI8kcQkBTH9wQCrfKNf6Tyiq9X-Gom3FM,1255
80
- cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py,sha256=it6wqbC7kGbd2DokKUiNggAAPpGCb-vDhrGUtF4iD80,1692
81
- cloudnetpy/model_evaluation/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- cloudnetpy/model_evaluation/tests/unit/conftest.py,sha256=-m1VSVoQ_l6qZbwULW0z2rr4bJvvvdn8Iyn2MqtfQNU,7382
83
- cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py,sha256=vX_1W10Aqb5ozxF-WgCJCJ3OE-cCw2mQODsidXDCKI8,10545
84
- cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py,sha256=crV-82AK8kQDGRbzQvxXMl5yEFwyuoUAN1FrjQhWOoU,26101
85
- cloudnetpy/model_evaluation/tests/unit/test_model_products.py,sha256=JC27yqdUvJ8EOo6VPQmgrJVvEczuSwHY4Q2_aDtHnno,3417
86
- cloudnetpy/model_evaluation/tests/unit/test_observation_products.py,sha256=7NN_vAT3ZpWOzMgjpKCYyCjUhjQJvTwr3JNe6CVMKIY,4783
87
- cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py,sha256=forAV4ebkhpXRqVzdlUrDELO533P6eiy6Phwao1IEvg,8867
88
- cloudnetpy/model_evaluation/tests/unit/test_plotting.py,sha256=fUxstYMjWSFXZaEV1uRW7-JeThMMNZe3onFKCfkoDZ8,3192
89
- cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py,sha256=CPbFwLQNn5PKRMQvTNzmsV8AWm7ODtVk7vDygh3G5RA,8795
90
- cloudnetpy/model_evaluation/tests/unit/test_tools.py,sha256=84b1TxMogC1hyACQol7xthOWNkYXp3oZJF4GFokEkd4,3630
91
- cloudnetpy/plotting/__init__.py,sha256=3bhBlLx8o_SjVyuPxgT7mfZ145pd5erwcCoVNuj2z48,62
92
- cloudnetpy/plotting/plot_meta.py,sha256=CrRCwh5-YxOrIe2bJXnL9akdUGi-amsUCCHc5VoHAL8,26217
93
- cloudnetpy/plotting/plotting.py,sha256=kmB1pRt38tpDYLLJ38OyeDt-jCCOP-EMQsHzIpi4hco,28163
94
- cloudnetpy/products/__init__.py,sha256=hGkngQT-YAC5cmDiHkSkQw2ZBrg0hN2z40Fizz0QU5Y,210
95
- cloudnetpy/products/classification.py,sha256=0Y5dEVDZFbq3UcFnyHomml5Au12SSMVznQTgAMyqh2I,7701
96
- cloudnetpy/products/der.py,sha256=zDehcsSCwDTADmxrK4Dmy5VcsrJmDbb-t_SiSU-C3M0,12241
97
- cloudnetpy/products/drizzle.py,sha256=2MUB3jVt2EzXFYaoUggUmH0TofenC0vHJlue0ULkdqI,10561
98
- cloudnetpy/products/drizzle_error.py,sha256=RBMtEmuOjiplgdpK0o_6KF6cQlheB1WlJ-x2l-Ig2yw,6123
99
- cloudnetpy/products/drizzle_tools.py,sha256=oksgyS_Nlj5PRdpWaNxek3KSXiaw4AEMeDt1bTqnCiU,10570
100
- cloudnetpy/products/ier.py,sha256=z0g0VKtnow9QlD492f6z1jPtslqvfmBBuITTrLYH3cI,7775
101
- cloudnetpy/products/iwc.py,sha256=0sAGYcTGOJcVH3MxqGxuwxiUpiEG0NuPg49gPsI0wLo,10076
102
- cloudnetpy/products/lwc.py,sha256=8G8pJppEsLZjXOvX5xvXEqEVSCMZZLfIeOoAMX6Gnu8,18642
103
- cloudnetpy/products/mie_lu_tables.nc,sha256=It4fYpqJXlqOgL8jeZ-PxGzP08PMrELIDVe55y9ob58,16637951
104
- cloudnetpy/products/mwr_multi.py,sha256=9dw5DqU9uae54SDk0Pjzp4EKtQrjo1DeP-Xx41NEF_g,2804
105
- cloudnetpy/products/mwr_single.py,sha256=tfUYvkVf_Hh1GcpBnjjE8T30EYzyYc07UuzGJCBME-8,2931
106
- cloudnetpy/products/product_tools.py,sha256=Gk5e4N1m071IIFT9dy9lUvcDICsMYx-pMEtcWTJ54nw,9739
107
- docs/source/conf.py,sha256=baQlgkkUGJi4952W6NRhLkIBbRtwFgqrIOBuEeSCLfk,1488
108
- cloudnetpy-1.49.9.dist-info/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
109
- cloudnetpy-1.49.9.dist-info/METADATA,sha256=QIEUcBQ2i-8GC9zevX-MMjHC13njOZwMfqV9dhhruQ0,5759
110
- cloudnetpy-1.49.9.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
111
- cloudnetpy-1.49.9.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
112
- cloudnetpy-1.49.9.dist-info/RECORD,,