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.
- cloudnetpy/categorize/atmos.py +1 -0
- cloudnetpy/categorize/atmos_utils.py +1 -1
- cloudnetpy/categorize/categorize.py +1 -0
- cloudnetpy/categorize/classify.py +1 -0
- cloudnetpy/categorize/containers.py +3 -1
- cloudnetpy/categorize/disdrometer.py +1 -0
- cloudnetpy/categorize/droplet.py +2 -2
- cloudnetpy/categorize/falling.py +1 -0
- cloudnetpy/categorize/freezing.py +1 -0
- cloudnetpy/categorize/insects.py +1 -0
- cloudnetpy/categorize/lidar.py +1 -0
- cloudnetpy/categorize/melting.py +1 -0
- cloudnetpy/categorize/model.py +1 -0
- cloudnetpy/categorize/mwr.py +1 -0
- cloudnetpy/categorize/radar.py +1 -0
- cloudnetpy/cloudnetarray.py +2 -0
- cloudnetpy/concat_lib.py +1 -0
- cloudnetpy/constants.py +1 -0
- cloudnetpy/datasource.py +5 -3
- cloudnetpy/instruments/basta.py +1 -0
- cloudnetpy/instruments/ceilo.py +2 -1
- cloudnetpy/instruments/cl61d.py +1 -0
- cloudnetpy/instruments/copernicus.py +2 -1
- cloudnetpy/instruments/disdrometer/parsivel.py +6 -4
- cloudnetpy/instruments/galileo.py +1 -0
- cloudnetpy/instruments/hatpro.py +1 -0
- cloudnetpy/instruments/lufft.py +1 -0
- cloudnetpy/instruments/mira.py +1 -0
- cloudnetpy/instruments/mrr.py +1 -1
- cloudnetpy/instruments/nc_lidar.py +1 -0
- cloudnetpy/instruments/nc_radar.py +1 -0
- cloudnetpy/instruments/pollyxt.py +1 -0
- cloudnetpy/instruments/radiometrics.py +2 -1
- cloudnetpy/instruments/rpg.py +2 -1
- cloudnetpy/instruments/rpg_reader.py +1 -1
- cloudnetpy/instruments/toa5.py +1 -1
- cloudnetpy/instruments/vaisala.py +7 -6
- cloudnetpy/instruments/weather_station.py +2 -3
- cloudnetpy/model_evaluation/file_handler.py +2 -2
- cloudnetpy/model_evaluation/metadata.py +1 -1
- cloudnetpy/model_evaluation/plotting/plot_tools.py +2 -2
- cloudnetpy/model_evaluation/plotting/plotting.py +11 -8
- cloudnetpy/model_evaluation/products/grid_methods.py +1 -1
- cloudnetpy/model_evaluation/products/model_products.py +7 -7
- cloudnetpy/model_evaluation/products/observation_products.py +8 -8
- cloudnetpy/model_evaluation/products/tools.py +5 -7
- cloudnetpy/model_evaluation/statistics/statistical_methods.py +2 -2
- cloudnetpy/output.py +3 -1
- cloudnetpy/plotting/plot_meta.py +2 -2
- cloudnetpy/plotting/plotting.py +8 -11
- cloudnetpy/products/classification.py +10 -9
- cloudnetpy/products/der.py +3 -2
- cloudnetpy/products/drizzle.py +3 -3
- cloudnetpy/products/drizzle_tools.py +1 -1
- cloudnetpy/products/ier.py +1 -0
- cloudnetpy/products/iwc.py +4 -3
- cloudnetpy/products/lwc.py +2 -3
- cloudnetpy/products/mwr_tools.py +2 -4
- cloudnetpy/products/product_tools.py +2 -1
- cloudnetpy/utils.py +9 -14
- cloudnetpy/version.py +1 -1
- {cloudnetpy-1.61.15.dist-info → cloudnetpy-1.61.16.dist-info}/METADATA +1 -1
- cloudnetpy-1.61.16.dist-info/RECORD +115 -0
- {cloudnetpy-1.61.15.dist-info → cloudnetpy-1.61.16.dist-info}/WHEEL +1 -1
- cloudnetpy-1.61.15.dist-info/RECORD +0 -115
- {cloudnetpy-1.61.15.dist-info → cloudnetpy-1.61.16.dist-info}/LICENSE +0 -0
- {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
|
-
"""
|
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"
|
cloudnetpy/plotting/plot_meta.py
CHANGED
@@ -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.
|
cloudnetpy/plotting/plotting.py
CHANGED
@@ -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
|
-
|
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
|
125
|
-
|
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, "\
|
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
|
-
|
75
|
-
|
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
|
-
|
79
|
-
|
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
|
-
|
86
|
-
|
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
|
|
cloudnetpy/products/der.py
CHANGED
@@ -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
|
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
|
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
|
|
cloudnetpy/products/drizzle.py
CHANGED
@@ -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)
|
cloudnetpy/products/ier.py
CHANGED
cloudnetpy/products/iwc.py
CHANGED
@@ -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
|
-
|
96
|
-
|
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
|
|
cloudnetpy/products/lwc.py
CHANGED
@@ -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
|
-
|
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
|
cloudnetpy/products/mwr_tools.py
CHANGED
@@ -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
|
-
|
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
|
-
|
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
@@ -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,,
|