cloudnetpy 1.85.4__tar.gz → 1.86.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cloudnetpy-1.85.4/cloudnetpy.egg-info → cloudnetpy-1.86.0}/PKG-INFO +1 -1
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/containers.py +12 -4
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/disdrometer.py +5 -2
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/fd12p.py +0 -3
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/mrr.py +7 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/metadata.py +3 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/plotting/plot_meta.py +7 -1
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/plotting/plotting.py +11 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/classification.py +18 -5
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/utils.py +7 -2
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/version.py +2 -2
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0/cloudnetpy.egg-info}/PKG-INFO +1 -1
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/LICENSE +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/MANIFEST.in +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/README.md +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/atmos_utils.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuation.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/categorize.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/classify.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/droplet.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/falling.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/freezing.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/insects.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/itu.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/lidar.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/melting.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/model.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/mwr.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/radar.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/cli.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/cloudnetarray.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/concat_lib.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/constants.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/datasource.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/exceptions.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/basta.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/bowtie.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/ceilo.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/ceilometer.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/cl61d.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/copernicus.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/da10.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/disdrometer/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/disdrometer/common.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/disdrometer/parsivel.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/disdrometer/thies.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/galileo.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/hatpro.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/instruments.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/lufft.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/mira.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/nc_lidar.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/nc_radar.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/pollyxt.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/radiometrics.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/rain_e_h3.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/rpg.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/rpg_reader.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/toa5.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/vaisala.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/instruments/weather_station.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/file_handler.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/metadata.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/advance_methods.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/tools.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/utils.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/output.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/plotting/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/__init__.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/der.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/drizzle.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/drizzle_error.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/drizzle_tools.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/epsilon.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/ier.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/iwc.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/lwc.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/mie_lu_tables.nc +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/mwr_tools.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/products/product_tools.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/py.typed +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy.egg-info/SOURCES.txt +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy.egg-info/dependency_links.txt +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy.egg-info/entry_points.txt +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy.egg-info/requires.txt +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy.egg-info/top_level.txt +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/docs/source/conf.py +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/pyproject.toml +0 -0
- {cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/setup.cfg +0 -0
@@ -92,10 +92,18 @@ class ClassData:
|
|
92
92
|
rain_from_disdrometer = self._find_rain_from_disdrometer()
|
93
93
|
ind = ~rain_from_disdrometer.mask
|
94
94
|
is_rain[ind] = rain_from_disdrometer[ind]
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
95
|
+
# Filter out snowfall:
|
96
|
+
if (
|
97
|
+
self.data.disdrometer is not None
|
98
|
+
and "synop_WaWa" in self.data.disdrometer.data
|
99
|
+
):
|
100
|
+
wawa = self.data.disdrometer.data["synop_WaWa"].data
|
101
|
+
liquid_rain_only = (wawa >= 57) & (wawa <= 68)
|
102
|
+
else:
|
103
|
+
mask = ma.getmaskarray(self.tw)
|
104
|
+
first_valid_ind = np.nonzero(np.all(~mask, axis=0))[0][0]
|
105
|
+
liquid_rain_only = self.tw[:, first_valid_ind] > T0 + 5
|
106
|
+
return is_rain & liquid_rain_only
|
99
107
|
|
100
108
|
def _find_rain_from_radar_echo(self) -> npt.NDArray:
|
101
109
|
first_gate_with_data = np.argmin(self.z.mask.all(axis=0))
|
@@ -24,14 +24,17 @@ class Disdrometer(DataSource):
|
|
24
24
|
|
25
25
|
def interpolate_to_grid(self, time_grid: npt.NDArray) -> None:
|
26
26
|
for key, array in self.data.items():
|
27
|
+
method = "nearest" if key == "synop_WaWa" else "linear"
|
27
28
|
self.data[key].data = interpolate_1d(
|
28
|
-
self.time, array.data, time_grid, max_time=1
|
29
|
+
self.time, array.data, time_grid, max_time=1, method=method
|
29
30
|
)
|
30
31
|
|
31
32
|
def _init_rainfall_rate(self) -> None:
|
32
|
-
keys = ("rainfall_rate", "n_particles")
|
33
|
+
keys = ("rainfall_rate", "n_particles", "synop_WaWa")
|
33
34
|
for key in keys:
|
34
35
|
if key not in self.dataset.variables:
|
36
|
+
if key == "synop_WaWa":
|
37
|
+
continue
|
35
38
|
msg = f"variable {key} is missing"
|
36
39
|
raise DisdrometerDataError(msg)
|
37
40
|
self.append_data(self.dataset.variables[key][:], key)
|
@@ -104,6 +104,7 @@ def mrr2nc(
|
|
104
104
|
if date:
|
105
105
|
mrr.screen_by_date(date)
|
106
106
|
mrr.add_time_and_range()
|
107
|
+
mrr.fix_range()
|
107
108
|
mrr.add_site_geolocation()
|
108
109
|
mrr.add_zenith_angle()
|
109
110
|
mrr.add_radar_specific_variables()
|
@@ -161,6 +162,12 @@ class MrrPro(NcRadar):
|
|
161
162
|
valid_indices.append(ind)
|
162
163
|
self.screen_time_indices(valid_indices)
|
163
164
|
|
165
|
+
def fix_range(self) -> None:
|
166
|
+
# It seems like the "range" variable in MRR-PRO raw files is actually
|
167
|
+
# defined above mean sea level -> convert to range above ground level
|
168
|
+
range_data = self.data["range"].data
|
169
|
+
range_data -= range_data[0]
|
170
|
+
|
164
171
|
|
165
172
|
ATTRIBUTES = {
|
166
173
|
"lwc": MetaData(
|
@@ -19,6 +19,7 @@ class PlotMeta(NamedTuple):
|
|
19
19
|
moving_average: Whether to plot a moving average in a 1d plot.
|
20
20
|
contour: Whether to plot contours on top of a filled colormap.
|
21
21
|
zero_line: Whether to plot a zero line in a 1d plot.
|
22
|
+
mask_zero: Whether to mask zero values in the plot.
|
22
23
|
time_smoothing_duration: The duration of the time smoothing window
|
23
24
|
(in 2d plots) in minutes.
|
24
25
|
"""
|
@@ -30,6 +31,7 @@ class PlotMeta(NamedTuple):
|
|
30
31
|
moving_average: bool = True
|
31
32
|
contour: bool = False
|
32
33
|
zero_line: bool = False
|
34
|
+
mask_zeros: bool = False
|
33
35
|
time_smoothing_duration: int = 0
|
34
36
|
|
35
37
|
|
@@ -150,6 +152,7 @@ ATTRIBUTES = {
|
|
150
152
|
"rainfall_rate": PlotMeta(
|
151
153
|
cmap="Blues",
|
152
154
|
plot_range=(0, 50 / 3600000),
|
155
|
+
mask_zeros=True,
|
153
156
|
)
|
154
157
|
},
|
155
158
|
"mwr": {
|
@@ -390,6 +393,7 @@ ATTRIBUTES = {
|
|
390
393
|
"number_concentration": PlotMeta(plot_range=(1e-2, 1e3), log_scale=True),
|
391
394
|
"fall_velocity": PlotMeta(
|
392
395
|
plot_range=(0, 10),
|
396
|
+
mask_zeros=True,
|
393
397
|
),
|
394
398
|
"pressure": PlotMeta(
|
395
399
|
plot_range=(1e4, 1.2e5),
|
@@ -560,7 +564,7 @@ ATTRIBUTES = {
|
|
560
564
|
plot_range=(0, 5),
|
561
565
|
),
|
562
566
|
"radar_rain_atten": PlotMeta(
|
563
|
-
plot_range=(0,
|
567
|
+
plot_range=(0, 15),
|
564
568
|
),
|
565
569
|
"radar_melting_atten": PlotMeta(
|
566
570
|
plot_range=(0, 5),
|
@@ -598,6 +602,7 @@ ATTRIBUTES = {
|
|
598
602
|
cmap="Blues",
|
599
603
|
plot_range=(1e-5, 1e-2),
|
600
604
|
log_scale=True,
|
605
|
+
mask_zeros=True,
|
601
606
|
),
|
602
607
|
"lwc_error": PlotMeta(
|
603
608
|
cmap="RdYlGn_r",
|
@@ -608,6 +613,7 @@ ATTRIBUTES = {
|
|
608
613
|
),
|
609
614
|
"pia": PlotMeta(
|
610
615
|
plot_range=(0, 3),
|
616
|
+
mask_zeros=True,
|
611
617
|
),
|
612
618
|
"lwp": PlotMeta(
|
613
619
|
zero_line=True,
|
@@ -362,6 +362,10 @@ class Plot:
|
|
362
362
|
self._is_log = sub_plot.plot_meta.log_scale
|
363
363
|
self._ax = sub_plot.ax
|
364
364
|
|
365
|
+
def _mask_zeros(self) -> None:
|
366
|
+
self._data = ma.masked_where(self._data == 0, self._data)
|
367
|
+
self._data_orig = ma.masked_where(self._data_orig == 0, self._data_orig)
|
368
|
+
|
365
369
|
def _convert_units(self) -> str:
|
366
370
|
multiply, add = "multiply", "add"
|
367
371
|
units_conversion = {
|
@@ -491,6 +495,8 @@ class Plot:
|
|
491
495
|
class Plot2D(Plot):
|
492
496
|
def plot(self, figure_data: FigureData) -> None:
|
493
497
|
self._convert_units()
|
498
|
+
if self._plot_meta.mask_zeros:
|
499
|
+
self._mask_zeros()
|
494
500
|
if figure_data.file_type == "cpr-simulation":
|
495
501
|
min_x, max_x = 0, EARTHCARE_MAX_X
|
496
502
|
else:
|
@@ -693,6 +699,8 @@ class Plot1D(Plot):
|
|
693
699
|
msg = "All data is masked"
|
694
700
|
raise PlottingError(msg)
|
695
701
|
units = self._convert_units()
|
702
|
+
if self._plot_meta.mask_zeros:
|
703
|
+
self._mask_zeros()
|
696
704
|
self._mark_gaps(figure_data)
|
697
705
|
self._ax.plot(
|
698
706
|
figure_data.time_including_gaps,
|
@@ -823,6 +831,9 @@ class Plot1D(Plot):
|
|
823
831
|
max_y = max_data + gap
|
824
832
|
if min_y == 0 and max_y == 0:
|
825
833
|
return fallback
|
834
|
+
if min_y == max_y:
|
835
|
+
gap = np.abs(min_y) * percent_gap
|
836
|
+
return min_y - gap, max_y + gap
|
826
837
|
return min_y, max_y
|
827
838
|
|
828
839
|
def _get_plot_options(self) -> dict:
|
@@ -11,6 +11,7 @@ from numpy import ma
|
|
11
11
|
|
12
12
|
from cloudnetpy import output, utils
|
13
13
|
from cloudnetpy.categorize import atmos_utils
|
14
|
+
from cloudnetpy.constants import M_S_TO_MM_H
|
14
15
|
from cloudnetpy.datasource import DataSource
|
15
16
|
from cloudnetpy.metadata import MetaData
|
16
17
|
from cloudnetpy.products.product_tools import CategorizeBits, QualityBits
|
@@ -189,24 +190,36 @@ def _get_attenuation_classes(data_source: DataSource) -> AttenuationClass:
|
|
189
190
|
rain_atten = _read_atten("radar_rain_atten")
|
190
191
|
melting_atten = _read_atten("radar_melting_atten")
|
191
192
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
):
|
193
|
+
not_w_band = data_source.getvar("radar_frequency") < 90
|
194
|
+
|
195
|
+
if "lwp" not in data_source.dataset.variables or not_w_band:
|
196
196
|
lwp = np.zeros(data_source.time.shape)
|
197
197
|
else:
|
198
198
|
lwp_data = data_source.getvar("lwp")
|
199
199
|
lwp = lwp_data.filled(0) if isinstance(lwp_data, ma.MaskedArray) else lwp_data
|
200
200
|
|
201
|
+
if "rainfall_rate" not in data_source.dataset.variables or not_w_band:
|
202
|
+
rain_rate = np.zeros(data_source.time.shape)
|
203
|
+
else:
|
204
|
+
rain_data = data_source.getvar("rainfall_rate") * M_S_TO_MM_H
|
205
|
+
rain_rate = (
|
206
|
+
rain_data.filled(0) if isinstance(rain_data, ma.MaskedArray) else rain_data
|
207
|
+
)
|
208
|
+
|
201
209
|
total_atten = liquid_atten + rain_atten + melting_atten
|
202
210
|
|
203
211
|
threshold_moderate = 10 # dB
|
204
212
|
threshold_severe = 15 # dB
|
205
213
|
threshold_lwp = 1 # kg/m2
|
214
|
+
threshold_rain = 3 # mm/h
|
206
215
|
|
207
216
|
small = total_atten > 0
|
208
217
|
moderate = total_atten >= threshold_moderate
|
209
|
-
severe = (
|
218
|
+
severe = (
|
219
|
+
(total_atten > threshold_severe)
|
220
|
+
| (lwp[:, np.newaxis] > threshold_lwp)
|
221
|
+
| (rain_rate[:, np.newaxis] > threshold_rain)
|
222
|
+
)
|
210
223
|
|
211
224
|
return AttenuationClass(small=small, moderate=moderate, severe=severe)
|
212
225
|
|
@@ -420,7 +420,11 @@ def interpolate_2d_nearest(
|
|
420
420
|
|
421
421
|
|
422
422
|
def interpolate_1d(
|
423
|
-
time: npt.NDArray,
|
423
|
+
time: npt.NDArray,
|
424
|
+
y: ma.MaskedArray,
|
425
|
+
time_new: npt.NDArray,
|
426
|
+
max_time: float,
|
427
|
+
method: str = "linear",
|
424
428
|
) -> npt.NDArray:
|
425
429
|
"""1D linear interpolation preserving the mask.
|
426
430
|
|
@@ -430,6 +434,7 @@ def interpolate_1d(
|
|
430
434
|
time_new: 1D array, new time coordinates.
|
431
435
|
max_time: Maximum allowed gap in minutes. Values outside this gap will
|
432
436
|
be masked.
|
437
|
+
method: Interpolation method, 'linear' (default) or 'nearest'.
|
433
438
|
"""
|
434
439
|
if np.max(time) > 24 or np.min(time) < 0:
|
435
440
|
msg = "Time vector must be in fraction hours between 0 and 24"
|
@@ -439,7 +444,7 @@ def interpolate_1d(
|
|
439
444
|
return ma.masked_all(time_new.shape)
|
440
445
|
time = time[~y.mask]
|
441
446
|
y = y[~y.mask]
|
442
|
-
fun = interp1d(time, y, fill_value=(y[0], y[-1]), bounds_error=False)
|
447
|
+
fun = interp1d(time, y, kind=method, fill_value=(y[0], y[-1]), bounds_error=False)
|
443
448
|
interpolated = ma.array(fun(time_new))
|
444
449
|
bad_idx = get_gap_ind(time, time_new, max_time / 60)
|
445
450
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuations/gas_attenuation.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuations/liquid_attenuation.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuations/melting_attenuation.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/categorize/attenuations/rain_attenuation.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/advance_methods.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/grid_methods.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/model_products.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/observation_products.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/products/product_resampling.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py
RENAMED
File without changes
|
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py
RENAMED
File without changes
|
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py
RENAMED
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py
RENAMED
File without changes
|
File without changes
|
{cloudnetpy-1.85.4 → cloudnetpy-1.86.0}/cloudnetpy/model_evaluation/tests/unit/test_tools.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|