cloudnetpy 1.96.2__tar.gz → 1.96.3__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.96.2/cloudnetpy.egg-info → cloudnetpy-1.96.3}/PKG-INFO +1 -1
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/insects.py +24 -2
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/melting.py +41 -5
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/cli.py +8 -2
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/version.py +1 -1
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3/cloudnetpy.egg-info}/PKG-INFO +1 -1
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/LICENSE +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/MANIFEST.in +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/README.md +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/arm.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/atmos_utils.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuation.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/gas_attenuation.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/liquid_attenuation.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/melting_attenuation.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/rain_attenuation.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/categorize.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/classify.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/containers.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/disdrometer.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/droplet.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/falling.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/freezing.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/lidar.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/model.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/mwr.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/radar.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/cloudnetarray.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/concat_lib.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/constants.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/datasource.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/lpm.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/parsivel.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/process.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/rd80.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/disdronator/utils.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/exceptions.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/arm_ceilo.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/arm_ld.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/arm_utils.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/basta.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/bowtie.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/ceilo.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/ceilometer.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/cl61d.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/copernicus.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/da10.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/dealias.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/disdrometer.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/fd12p.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/galileo.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/hatpro.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/instruments.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/kazr.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/lufft.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mira.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mmcr.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mrr.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mwr3c.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/mwrlos.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/nc_lidar.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/nc_radar.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/pollyxt.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/radiometrics.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/rain_e_h3.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/rpg.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/rpg_reader.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/toa5.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/vaisala.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/weather_radar.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/instruments/weather_station.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/metadata.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/file_handler.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/metadata.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/model_metadata.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/plotting/plotting.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/advance_methods.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/grid_methods.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/tools.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/conftest.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/utils.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/output.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/plotting/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/plotting/plotting.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/__init__.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/classification.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/cod.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/der.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/drizzle.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/drizzle_error.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/drizzle_tools.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/epsilon_lidar.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/epsilon_radar.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/ier.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/iwc.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/iwc_weather_radar.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/lwc.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/mie_lu_tables.nc +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/mwr_tools.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/products/product_tools.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/py.typed +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/utils.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/SOURCES.txt +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/dependency_links.txt +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/entry_points.txt +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/requires.txt +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy.egg-info/top_level.txt +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/docs/source/conf.py +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/pyproject.toml +0 -0
- {cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/setup.cfg +0 -0
|
@@ -58,7 +58,9 @@ def _insect_probability(obs: ClassData) -> tuple[npt.NDArray, npt.NDArray]:
|
|
|
58
58
|
prob_from_ldr = _calc_prob_from_ldr(prob)
|
|
59
59
|
prob_from_others = _calc_prob_from_all(prob)
|
|
60
60
|
prob_from_others = _adjust_for_radar(obs, prob, prob_from_others)
|
|
61
|
-
|
|
61
|
+
prob_from_others = _adjust_for_lidar(obs, prob_from_others)
|
|
62
|
+
is_ldr = ~ma.getmaskarray(obs.ldr) if hasattr(obs, "ldr") else None
|
|
63
|
+
prob_combined = _fill_missing_pixels(prob_from_ldr, prob_from_others, is_ldr)
|
|
62
64
|
return prob_combined, prob_from_others
|
|
63
65
|
|
|
64
66
|
|
|
@@ -147,11 +149,31 @@ def _adjust_for_radar(
|
|
|
147
149
|
return prob_from_others
|
|
148
150
|
|
|
149
151
|
|
|
152
|
+
def _adjust_for_lidar(
|
|
153
|
+
obs: ClassData,
|
|
154
|
+
prob_from_others: npt.NDArray,
|
|
155
|
+
weight: float = 0.8,
|
|
156
|
+
) -> npt.NDArray:
|
|
157
|
+
"""Reduces probability above the lidar signal, where liquid may be hidden."""
|
|
158
|
+
is_beta = ~ma.getmaskarray(obs.beta)
|
|
159
|
+
n_gates = is_beta.shape[1]
|
|
160
|
+
top = n_gates - np.argmax(is_beta[:, ::-1], axis=1)
|
|
161
|
+
top[~is_beta.any(axis=1)] = 0
|
|
162
|
+
above_lidar = np.arange(n_gates)[np.newaxis, :] >= top[:, np.newaxis]
|
|
163
|
+
prob_from_others[above_lidar] *= weight
|
|
164
|
+
return prob_from_others
|
|
165
|
+
|
|
166
|
+
|
|
150
167
|
def _fill_missing_pixels(
|
|
151
168
|
prob_from_ldr: npt.NDArray,
|
|
152
169
|
prob_from_others: npt.NDArray,
|
|
170
|
+
is_ldr: npt.NDArray | None = None,
|
|
153
171
|
) -> npt.NDArray:
|
|
154
|
-
|
|
172
|
+
"""Combines probabilities trusting measured ldr over other parameters."""
|
|
173
|
+
prob = np.maximum(prob_from_ldr, prob_from_others)
|
|
174
|
+
if is_ldr is not None:
|
|
175
|
+
prob[is_ldr] = prob_from_ldr[is_ldr]
|
|
176
|
+
return prob
|
|
155
177
|
|
|
156
178
|
|
|
157
179
|
def _screen_insects(
|
|
@@ -10,6 +10,10 @@ from cloudnetpy import utils
|
|
|
10
10
|
from cloudnetpy.categorize import droplet
|
|
11
11
|
from cloudnetpy.categorize.containers import ClassData
|
|
12
12
|
|
|
13
|
+
MIN_LAPSE_RATE = 0.004 # K m-1
|
|
14
|
+
MIN_LDR_COVERAGE = 0.5
|
|
15
|
+
T0_TOLERANCE = 1 # K
|
|
16
|
+
|
|
13
17
|
|
|
14
18
|
def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
15
19
|
"""Finds melting layer from model temperature, ldr, and velocity.
|
|
@@ -27,11 +31,15 @@ def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
|
27
31
|
The peak in *ldr* is the primary parameter we analyze. If
|
|
28
32
|
*ldr* has a proper peak, and *v* < -1 m/s in the base, melting layer
|
|
29
33
|
has been found. If *ldr* is missing we only analyze the behaviour
|
|
30
|
-
of *v*, which is always present, to detect the melting layer.
|
|
34
|
+
of *v*, which is always present, to detect the melting layer. If *ldr*
|
|
35
|
+
covers the profile but shows no peak, there is no melting layer.
|
|
31
36
|
|
|
32
37
|
Model temperature is used to limit the melting layer search to a certain
|
|
33
38
|
temperature range around 0 C. For ECMWF the range is -4..+3, and for
|
|
34
|
-
the rest -8..+6.
|
|
39
|
+
the rest -8..+6. Model temperature must also reach -1 C in the profile,
|
|
40
|
+
and the search is limited in altitude above the highest 0 C level,
|
|
41
|
+
because in temperature inversions the temperature range alone may
|
|
42
|
+
span several kilometers.
|
|
35
43
|
|
|
36
44
|
Notes:
|
|
37
45
|
This melting layer detection method is novel and needs to be validated.
|
|
@@ -63,7 +71,7 @@ def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
|
63
71
|
t_range = _find_model_temperature_range(obs.model_type)
|
|
64
72
|
|
|
65
73
|
for ind, t_prof in enumerate(obs.tw):
|
|
66
|
-
temp_indices = _get_temp_indices(t_prof, t_range)
|
|
74
|
+
temp_indices = _get_temp_indices(t_prof, t_range, obs.height)
|
|
67
75
|
if len(temp_indices) <= 1:
|
|
68
76
|
continue
|
|
69
77
|
z_prof = obs.z[ind, temp_indices]
|
|
@@ -90,6 +98,8 @@ def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
|
90
98
|
z_prof,
|
|
91
99
|
)
|
|
92
100
|
except (ValueError, IndexError, AssertionError):
|
|
101
|
+
if _has_ldr_coverage(ldr_prof, v_prof):
|
|
102
|
+
continue
|
|
93
103
|
height = obs.height[temp_indices]
|
|
94
104
|
if hasattr(obs, "width"):
|
|
95
105
|
width_prof = obs.width[ind, temp_indices]
|
|
@@ -104,6 +114,16 @@ def find_melting_layer(obs: ClassData, *, smooth: bool = True) -> npt.NDArray:
|
|
|
104
114
|
return melting_layer
|
|
105
115
|
|
|
106
116
|
|
|
117
|
+
def _has_ldr_coverage(ldr_prof: npt.NDArray | None, v_prof: npt.NDArray) -> bool:
|
|
118
|
+
"""Checks if ldr covers enough of the profile to rule out melting layer."""
|
|
119
|
+
if ldr_prof is None:
|
|
120
|
+
return False
|
|
121
|
+
is_v = ~ma.getmaskarray(v_prof)
|
|
122
|
+
is_ldr = ~ma.getmaskarray(ldr_prof)
|
|
123
|
+
n_ldr = np.count_nonzero(is_ldr & is_v)
|
|
124
|
+
return bool(n_ldr >= MIN_LDR_COVERAGE * np.count_nonzero(is_v))
|
|
125
|
+
|
|
126
|
+
|
|
107
127
|
def _find_melting_layer_from_ldr(
|
|
108
128
|
ldr_prof: npt.NDArray,
|
|
109
129
|
ldr_dprof: npt.NDArray,
|
|
@@ -166,12 +186,28 @@ def _basetop(dprof: npt.NDArray, pind: int) -> tuple[int, int]:
|
|
|
166
186
|
return base, top
|
|
167
187
|
|
|
168
188
|
|
|
169
|
-
def _get_temp_indices(
|
|
189
|
+
def _get_temp_indices(
|
|
190
|
+
t_prof: npt.NDArray, t_range: tuple, height: npt.NDArray | None = None
|
|
191
|
+
) -> npt.NDArray:
|
|
170
192
|
"""Finds indices of temperature profile covering the given range."""
|
|
171
|
-
|
|
193
|
+
in_range = (t_prof > min(t_range) + T0) & (t_prof < max(t_range) + T0)
|
|
194
|
+
if height is not None:
|
|
195
|
+
in_range &= height <= _find_max_height(t_prof, t_range, height)
|
|
196
|
+
ind = np.where(in_range)[0]
|
|
172
197
|
return np.array([]) if len(ind) == 0 else np.arange(np.min(ind), np.max(ind) + 1)
|
|
173
198
|
|
|
174
199
|
|
|
200
|
+
def _find_max_height(t_prof: npt.NDArray, t_range: tuple, height: npt.NDArray) -> float:
|
|
201
|
+
"""Finds maximum melting layer height assuming realistic lapse rate."""
|
|
202
|
+
warm = np.where(t_prof >= T0)[0]
|
|
203
|
+
if len(warm) == 0:
|
|
204
|
+
# Model may be slightly too cold when melting layer is near the ground
|
|
205
|
+
warm = np.where(t_prof >= T0 - T0_TOLERANCE)[0]
|
|
206
|
+
if len(warm) == 0:
|
|
207
|
+
return -np.inf
|
|
208
|
+
return height[warm[-1]] - min(t_range) / MIN_LAPSE_RATE
|
|
209
|
+
|
|
210
|
+
|
|
175
211
|
def _find_model_temperature_range(model_type: str) -> tuple[float, float]:
|
|
176
212
|
"""Returns temperature range around 0C for given model type."""
|
|
177
213
|
if model_type == "gdas1":
|
|
@@ -928,9 +928,11 @@ def main() -> None:
|
|
|
928
928
|
)
|
|
929
929
|
parser.add_argument(
|
|
930
930
|
"--show",
|
|
931
|
-
|
|
931
|
+
nargs="?",
|
|
932
|
+
const=True,
|
|
932
933
|
default=False,
|
|
933
|
-
|
|
934
|
+
metavar="VARIABLES",
|
|
935
|
+
help="Show plotted image, optionally only given variables (comma-separated)",
|
|
934
936
|
)
|
|
935
937
|
parser.add_argument(
|
|
936
938
|
"--dl",
|
|
@@ -980,6 +982,10 @@ def main() -> None:
|
|
|
980
982
|
default=None,
|
|
981
983
|
)
|
|
982
984
|
args = parser.parse_args()
|
|
985
|
+
if isinstance(args.show, str):
|
|
986
|
+
if args.variables is None:
|
|
987
|
+
args.variables = args.show
|
|
988
|
+
args.show = True
|
|
983
989
|
|
|
984
990
|
logger = logging.getLogger()
|
|
985
991
|
logger.setLevel(logging.INFO)
|
|
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.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/gas_attenuation.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/liquid_attenuation.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/categorize/attenuations/melting_attenuation.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/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
|
|
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.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/advance_methods.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/grid_methods.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/model_products.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/products/observation_products.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/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.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py
RENAMED
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py
RENAMED
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py
RENAMED
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py
RENAMED
|
File without changes
|
|
File without changes
|
{cloudnetpy-1.96.2 → cloudnetpy-1.96.3}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|