cloudnetpy 1.60.2__tar.gz → 1.60.4__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.60.2/cloudnetpy.egg-info → cloudnetpy-1.60.4}/PKG-INFO +1 -1
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/model_metadata.py +1 -1
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/plotting/plotting.py +31 -9
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/products/advance_methods.py +35 -49
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/products/grid_methods.py +45 -62
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/conftest.py +31 -30
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -25
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +88 -85
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/plotting/plotting.py +5 -4
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/version.py +1 -1
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4/cloudnetpy.egg-info}/PKG-INFO +1 -1
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/LICENSE +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/MANIFEST.in +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/README.md +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/atmos.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/atmos_utils.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/categorize.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/classify.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/containers.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/disdrometer.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/droplet.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/falling.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/freezing.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/insects.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/lidar.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/melting.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/model.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/mwr.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/categorize/radar.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/cloudnetarray.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/concat_lib.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/constants.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/datasource.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/exceptions.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/basta.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/campbell_scientific.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/ceilo.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/ceilometer.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/cl61d.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/cloudnet_instrument.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/copernicus.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/disdrometer/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/disdrometer/common.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/disdrometer/parsivel.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/disdrometer/thies.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/galileo.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/hatpro.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/instruments.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/lufft.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/mira.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/mrr.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/nc_lidar.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/nc_radar.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/pollyxt.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/radiometrics.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/rpg.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/rpg_reader.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/vaisala.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/instruments/weather_station.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/metadata.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/file_handler.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/metadata.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/plotting/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/plotting/plot_tools.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/products/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/products/model_products.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/products/observation_products.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/products/product_resampling.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/products/tools.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/statistics/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/statistics/statistical_methods.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/conftest.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/process_cf/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/test_model_products.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/test_plotting.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/tests/unit/test_tools.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/utils.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/output.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/plotting/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/plotting/plot_meta.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/__init__.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/classification.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/der.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/drizzle.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/drizzle_error.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/drizzle_tools.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/ier.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/iwc.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/lwc.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/mie_lu_tables.nc +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/mwr_tools.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/products/product_tools.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/py.typed +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/utils.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy.egg-info/SOURCES.txt +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy.egg-info/dependency_links.txt +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy.egg-info/requires.txt +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy.egg-info/top_level.txt +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/docs/source/conf.py +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/pyproject.toml +0 -0
- {cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/setup.cfg +0 -0
@@ -28,7 +28,7 @@ MODELS = {
|
|
28
28
|
level=88,
|
29
29
|
cycle="1-12, 7-18",
|
30
30
|
),
|
31
|
-
"harmonie": ModelMetaData(
|
31
|
+
"harmonie-fmi-6-11": ModelMetaData(
|
32
32
|
model_name="HARMONIE-AROME",
|
33
33
|
long_name="the HIRLAM–ALADIN Research on Mesoscale Operational NWP in Euromed", # noqa: RUF001
|
34
34
|
level=65,
|
@@ -17,7 +17,7 @@ import cloudnetpy.model_evaluation.plotting.plot_tools as p_tools
|
|
17
17
|
from cloudnetpy.model_evaluation.model_metadata import MODELS
|
18
18
|
from cloudnetpy.model_evaluation.plotting.plot_meta import ATTRIBUTES
|
19
19
|
from cloudnetpy.model_evaluation.statistics.statistical_methods import DayStatistics
|
20
|
-
from cloudnetpy.plotting.plotting import get_log_cbar_tick_labels, lin2log
|
20
|
+
from cloudnetpy.plotting.plotting import Dimensions, get_log_cbar_tick_labels, lin2log
|
21
21
|
|
22
22
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
23
23
|
|
@@ -34,7 +34,7 @@ def generate_L3_day_plots(
|
|
34
34
|
save_path: str | None = None,
|
35
35
|
image_name: str | None = None,
|
36
36
|
show: bool | None = False,
|
37
|
-
) ->
|
37
|
+
) -> list[Dimensions]:
|
38
38
|
"""Generate visualizations for level 3 dayscale products.
|
39
39
|
With figure type visualizations can be subplot in group, pair, single or
|
40
40
|
statistic of given product. In group fig_type all different methods are plot
|
@@ -93,7 +93,11 @@ def generate_L3_day_plots(
|
|
93
93
|
model_info = MODELS[model]
|
94
94
|
model_name = model_info.model_name
|
95
95
|
name_set = p_tools.parse_wanted_names(nc_file, product, model, var_list)
|
96
|
-
for
|
96
|
+
unique_tuples = {tuple(lst) for lst in name_set}
|
97
|
+
name_set_unique = tuple(list(tup) for tup in unique_tuples)
|
98
|
+
|
99
|
+
dimensions = []
|
100
|
+
for names in name_set_unique:
|
97
101
|
if len(names) > 0:
|
98
102
|
try:
|
99
103
|
cycle_names, cycles = p_tools.sort_cycles(names, model)
|
@@ -120,7 +124,11 @@ def generate_L3_day_plots(
|
|
120
124
|
save_path,
|
121
125
|
image_name,
|
122
126
|
]
|
123
|
-
getattr(cls, f"get_{fig_type}_plots")(
|
127
|
+
figs, axes = getattr(cls, f"get_{fig_type}_plots")(
|
128
|
+
*params, **kwargs
|
129
|
+
)
|
130
|
+
for fig, ax in zip(figs, axes, strict=False):
|
131
|
+
dimensions.append(Dimensions(fig, ax))
|
124
132
|
except AttributeError:
|
125
133
|
params = [
|
126
134
|
product,
|
@@ -143,7 +151,10 @@ def generate_L3_day_plots(
|
|
143
151
|
save_path,
|
144
152
|
image_name,
|
145
153
|
]
|
146
|
-
getattr(cls, f"get_{fig_type}_plots")(*params, **kwargs)
|
154
|
+
figs, axes = getattr(cls, f"get_{fig_type}_plots")(*params, **kwargs)
|
155
|
+
for fig, ax in zip(figs, axes, strict=False):
|
156
|
+
dimensions.append(Dimensions(fig, ax))
|
157
|
+
return dimensions
|
147
158
|
|
148
159
|
|
149
160
|
def get_group_plots(
|
@@ -159,7 +170,7 @@ def get_group_plots(
|
|
159
170
|
cycle: str = "",
|
160
171
|
title: bool = True,
|
161
172
|
include_xlimits: bool = False,
|
162
|
-
) ->
|
173
|
+
) -> tuple:
|
163
174
|
"""Group subplot visualization for both standard and advection downsampling.
|
164
175
|
Generates group subplot figure for product with model and all different
|
165
176
|
downsampling methods. Generates separated figures for standard and advection
|
@@ -204,6 +215,7 @@ def get_group_plots(
|
|
204
215
|
[product, model_run, "group"],
|
205
216
|
show=show,
|
206
217
|
)
|
218
|
+
return fig, ax
|
207
219
|
|
208
220
|
|
209
221
|
def get_pair_plots(
|
@@ -280,7 +292,7 @@ def get_single_plots(
|
|
280
292
|
cycle: str = "",
|
281
293
|
title: bool = True,
|
282
294
|
include_xlimits: bool = False,
|
283
|
-
) ->
|
295
|
+
) -> tuple[list, list]:
|
284
296
|
"""Generates figures of each product variable from given file in loop.
|
285
297
|
|
286
298
|
Args:
|
@@ -295,9 +307,13 @@ def get_single_plots(
|
|
295
307
|
cycle (str): Name of cycle if exists
|
296
308
|
title (bool): True or False if wanted to add title to subfig
|
297
309
|
"""
|
310
|
+
figs = []
|
311
|
+
axes = []
|
298
312
|
variable_info = ATTRIBUTES[product]
|
299
|
-
for
|
313
|
+
for name in names:
|
300
314
|
fig, ax = initialize_figure(1)
|
315
|
+
figs.append(fig)
|
316
|
+
axes.append(ax)
|
301
317
|
set_yax(ax[0], 12, ylabel=None)
|
302
318
|
set_xax(ax[0], include_xlimits=include_xlimits)
|
303
319
|
|
@@ -318,6 +334,7 @@ def get_single_plots(
|
|
318
334
|
[name, "single"],
|
319
335
|
show=show,
|
320
336
|
)
|
337
|
+
return figs, axes
|
321
338
|
|
322
339
|
|
323
340
|
def plot_colormesh(ax, data: np.ndarray, axes: tuple, variable_info) -> None:
|
@@ -349,7 +366,7 @@ def get_statistic_plots(
|
|
349
366
|
show: bool,
|
350
367
|
cycle: str = "",
|
351
368
|
title: bool = True,
|
352
|
-
) ->
|
369
|
+
) -> tuple:
|
353
370
|
"""Statistical subplots for day scale products.
|
354
371
|
Statistical analysis can be done by day scale with relative error ('error'),
|
355
372
|
total data area analysis ('area'), histogram ('hist') or vertical profiles
|
@@ -387,12 +404,16 @@ def get_statistic_plots(
|
|
387
404
|
err_msg = f"No data in {model_name} or observation"
|
388
405
|
raise ValueError(err_msg)
|
389
406
|
|
407
|
+
figs = []
|
408
|
+
axes = []
|
390
409
|
for stat in stats:
|
391
410
|
try:
|
392
411
|
obs_missing = False
|
393
412
|
model_missing = False
|
394
413
|
variable_info = ATTRIBUTES[product]
|
395
414
|
fig, ax = initialize_figure(len(names) - 1, stat)
|
415
|
+
figs.append(fig)
|
416
|
+
axes.append(ax)
|
396
417
|
model_data, _, _ = p_tools.read_data_characters(nc_file, names[0], model)
|
397
418
|
if np.all(model_data.mask is True):
|
398
419
|
model_missing = True
|
@@ -443,6 +464,7 @@ def get_statistic_plots(
|
|
443
464
|
[name, stat, model_run],
|
444
465
|
show=show,
|
445
466
|
)
|
467
|
+
return figs, axes
|
446
468
|
|
447
469
|
|
448
470
|
def initialize_statistic_plots(
|
{cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/products/advance_methods.py
RENAMED
@@ -2,8 +2,9 @@ import importlib
|
|
2
2
|
import logging
|
3
3
|
|
4
4
|
import numpy as np
|
5
|
+
import scipy.special
|
6
|
+
import scipy.stats
|
5
7
|
from numpy import ma
|
6
|
-
from scipy.special import gamma
|
7
8
|
|
8
9
|
import cloudnetpy.utils as cl_tools
|
9
10
|
from cloudnetpy.datasource import DataSource
|
@@ -44,7 +45,7 @@ class AdvanceProductMethods(DataSource):
|
|
44
45
|
name = f"get_advance_{self.product}"
|
45
46
|
getattr(cls, name)(self)
|
46
47
|
except AttributeError as error:
|
47
|
-
logging.
|
48
|
+
logging.debug("No advance method for %s: %s", self.product, error)
|
48
49
|
|
49
50
|
def get_advance_cf(self) -> None:
|
50
51
|
self.cf_cirrus_filter()
|
@@ -60,24 +61,36 @@ class AdvanceProductMethods(DataSource):
|
|
60
61
|
cf_filtered = self.filter_high_iwc_low_cf(cf, iwc, lwc)
|
61
62
|
cloud_iwc, ice_ind = self.find_ice_in_clouds(cf_filtered, iwc, lwc)
|
62
63
|
variance_iwc = self.iwc_variance(h, ice_ind)
|
63
|
-
|
64
|
+
|
64
65
|
for i, ind in enumerate(zip(ice_ind[0], ice_ind[-1], strict=True)):
|
65
|
-
|
66
|
+
try:
|
67
|
+
iwc_dist = self.calculate_iwc_distribution(
|
68
|
+
cloud_iwc[i], variance_iwc[i]
|
69
|
+
)
|
70
|
+
except ValueError:
|
71
|
+
continue
|
72
|
+
|
66
73
|
p_iwc = self.gamma_distribution(iwc_dist, variance_iwc[i], cloud_iwc[i])
|
74
|
+
|
75
|
+
if np.isinf(p_iwc).any():
|
76
|
+
cf_filtered[ind] = ma.masked
|
77
|
+
continue
|
78
|
+
|
67
79
|
if np.sum(p_iwc) == 0 or p_iwc[-1] > 0.01 * np.sum(p_iwc):
|
68
|
-
cf_filtered[ind] =
|
80
|
+
cf_filtered[ind] = ma.masked
|
69
81
|
continue
|
70
|
-
|
71
|
-
|
72
|
-
tZT
|
73
|
-
tT
|
74
|
-
tZ
|
75
|
-
t
|
76
|
-
float(t_screened[ind]),
|
77
|
-
float(z_sen[ind]),
|
82
|
+
|
83
|
+
min_iwc = 10 ** (
|
84
|
+
tZT * z_sen[ind] * t_screened[ind]
|
85
|
+
+ tT * t_screened[ind]
|
86
|
+
+ tZ * z_sen[ind]
|
87
|
+
+ t
|
78
88
|
)
|
89
|
+
obs_index = iwc_dist > min_iwc
|
79
90
|
cf_filtered[ind] = self.filter_cirrus(p_iwc, obs_index, cf_filtered[ind])
|
91
|
+
|
80
92
|
cf_filtered[cf_filtered < 0.05] = ma.masked
|
93
|
+
|
81
94
|
self._model_obj.append_data(
|
82
95
|
cf_filtered,
|
83
96
|
f"{self._model_obj.model}{self._model_obj.cycle}_cf_cirrus",
|
@@ -132,7 +145,7 @@ class AdvanceProductMethods(DataSource):
|
|
132
145
|
iwc: np.ndarray,
|
133
146
|
lwc: np.ndarray,
|
134
147
|
) -> np.ndarray:
|
135
|
-
cf_filtered =
|
148
|
+
cf_filtered = ma.copy(cf)
|
136
149
|
weird_ind = (iwc / cf > 0.5e-3) & (cf < 0.001)
|
137
150
|
weird_ind = weird_ind | (iwc == 0) & (lwc == 0) & (cf == 0)
|
138
151
|
cf_filtered[weird_ind] = ma.masked
|
@@ -199,7 +212,9 @@ class AdvanceProductMethods(DataSource):
|
|
199
212
|
n_std: int = 5,
|
200
213
|
n_dist: int = 250,
|
201
214
|
) -> np.ndarray:
|
202
|
-
finish = cloud_iwc + n_std * (
|
215
|
+
finish = cloud_iwc + n_std * (ma.sqrt(f_variance_iwc) * cloud_iwc)
|
216
|
+
if isinstance(finish, ma.MaskedArray) and finish.mask.all():
|
217
|
+
raise ValueError
|
203
218
|
iwc_dist = np.arange(0, finish, finish / (n_dist - 1))
|
204
219
|
if cloud_iwc < iwc_dist[2]:
|
205
220
|
finish = cloud_iwc * 10
|
@@ -208,40 +223,11 @@ class AdvanceProductMethods(DataSource):
|
|
208
223
|
|
209
224
|
@staticmethod
|
210
225
|
def gamma_distribution(
|
211
|
-
iwc_dist: np.ndarray,
|
212
|
-
f_variance_iwc: float,
|
213
|
-
cloud_iwc: float,
|
214
|
-
) -> np.ndarray:
|
215
|
-
def calculate_gamma_dist() -> float:
|
216
|
-
alpha = 1 / f_variance_iwc
|
217
|
-
return (
|
218
|
-
1
|
219
|
-
/ gamma(alpha)
|
220
|
-
* (alpha / cloud_iwc) ** alpha
|
221
|
-
* iwc_dist[i] ** (alpha - 1)
|
222
|
-
* ma.exp(-(alpha * iwc_dist[i] / cloud_iwc))
|
223
|
-
)
|
224
|
-
|
225
|
-
p_iwc = np.zeros(iwc_dist.shape)
|
226
|
-
for i in range(len(iwc_dist)):
|
227
|
-
p_iwc[i] = calculate_gamma_dist()
|
228
|
-
return p_iwc
|
229
|
-
|
230
|
-
@staticmethod
|
231
|
-
def get_observation_index(
|
232
|
-
iwc_dist: np.ndarray,
|
233
|
-
tZT: float,
|
234
|
-
tT: float,
|
235
|
-
tZ: float,
|
236
|
-
t: np.ndarray,
|
237
|
-
temperature: float,
|
238
|
-
z_sen: float,
|
226
|
+
iwc_dist: np.ndarray, f_variance_iwc: float, cloud_iwc: float
|
239
227
|
) -> np.ndarray:
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
iwc_min = calculate_min_iwc()
|
244
|
-
return iwc_dist > iwc_min
|
228
|
+
alpha = 1 / f_variance_iwc
|
229
|
+
theta = cloud_iwc / alpha
|
230
|
+
return scipy.stats.gamma.pdf(iwc_dist, a=alpha, scale=theta)
|
245
231
|
|
246
232
|
@staticmethod
|
247
233
|
def filter_cirrus(
|
@@ -249,4 +235,4 @@ class AdvanceProductMethods(DataSource):
|
|
249
235
|
obs_index: np.ndarray,
|
250
236
|
cf_filtered: np.ndarray,
|
251
237
|
) -> np.ndarray:
|
252
|
-
return (
|
238
|
+
return (ma.sum(p_iwc * obs_index) / ma.sum(p_iwc)) * cf_filtered
|
{cloudnetpy-1.60.2 → cloudnetpy-1.60.4}/cloudnetpy/model_evaluation/products/grid_methods.py
RENAMED
@@ -119,56 +119,35 @@ class ProductGrid:
|
|
119
119
|
|
120
120
|
def _cf_method_storage(self) -> tuple[dict, dict]:
|
121
121
|
cf_dict = {
|
122
|
-
"cf_V":
|
123
|
-
"cf_A":
|
122
|
+
"cf_V": ma.zeros(self._model_height.shape),
|
123
|
+
"cf_A": ma.zeros(self._model_height.shape),
|
124
124
|
}
|
125
125
|
cf_adv_dict = {
|
126
|
-
"cf_V_adv":
|
127
|
-
"cf_A_adv":
|
126
|
+
"cf_V_adv": ma.zeros(self._model_height.shape),
|
127
|
+
"cf_A_adv": ma.zeros(self._model_height.shape),
|
128
128
|
}
|
129
129
|
return cf_dict, cf_adv_dict
|
130
130
|
|
131
131
|
def _iwc_method_storage(self) -> tuple[dict, dict]:
|
132
132
|
iwc_dict = {
|
133
|
-
"iwc":
|
134
|
-
"iwc_att":
|
135
|
-
"iwc_rain":
|
133
|
+
"iwc": ma.zeros(self._model_height.shape),
|
134
|
+
"iwc_att": ma.zeros(self._model_height.shape),
|
135
|
+
"iwc_rain": ma.zeros(self._model_height.shape),
|
136
136
|
}
|
137
137
|
iwc_adv_dict = {
|
138
|
-
"iwc_adv":
|
139
|
-
"iwc_att_adv":
|
140
|
-
"iwc_rain_adv":
|
138
|
+
"iwc_adv": ma.zeros(self._model_height.shape),
|
139
|
+
"iwc_att_adv": ma.zeros(self._model_height.shape),
|
140
|
+
"iwc_rain_adv": ma.zeros(self._model_height.shape),
|
141
141
|
}
|
142
142
|
return iwc_dict, iwc_adv_dict
|
143
143
|
|
144
144
|
def _product_method_storage(self) -> tuple[dict, dict]:
|
145
|
-
product_dict = {f"{self._obs_obj.obs}":
|
145
|
+
product_dict = {f"{self._obs_obj.obs}": ma.zeros(self._model_height.shape)}
|
146
146
|
product_adv_dict = {
|
147
|
-
f"{self._obs_obj.obs}_adv":
|
147
|
+
f"{self._obs_obj.obs}_adv": ma.zeros(self._model_height.shape),
|
148
148
|
}
|
149
149
|
return product_dict, product_adv_dict
|
150
150
|
|
151
|
-
@staticmethod
|
152
|
-
def _regrid_cf(storage: dict, i: int, j: int, data: np.ndarray | None) -> dict:
|
153
|
-
"""Calculates average cloud fraction value to grid point"""
|
154
|
-
for key, downsample in storage.items():
|
155
|
-
if data is not None:
|
156
|
-
if isinstance(data, ma.MaskedArray) and data.mask.all():
|
157
|
-
downsample[i, j] = np.nan
|
158
|
-
elif not np.isnan(data).all():
|
159
|
-
downsample[i, j] = np.nanmean(data)
|
160
|
-
else:
|
161
|
-
downsample[i, j] = np.nan
|
162
|
-
if "_A" in key and (
|
163
|
-
not np.isnan(data).all()
|
164
|
-
and not (isinstance(data, ma.MaskedArray) and data.mask.all())
|
165
|
-
):
|
166
|
-
downsample[i, j] = tl.average_column_sum(data)
|
167
|
-
else:
|
168
|
-
downsample[i, j] = np.nan
|
169
|
-
storage[key] = downsample
|
170
|
-
return storage
|
171
|
-
|
172
151
|
def _reshape_data_to_window(
|
173
152
|
self,
|
174
153
|
ind: np.ndarray,
|
@@ -181,6 +160,17 @@ class ProductGrid:
|
|
181
160
|
return self._obs_data[ind].reshape(window_size)
|
182
161
|
return None
|
183
162
|
|
163
|
+
@staticmethod
|
164
|
+
def _regrid_cf(storage: dict, i: int, j: int, data: np.ndarray) -> dict:
|
165
|
+
"""Calculates average cloud fraction value to grid point."""
|
166
|
+
data_ma = ma.array(data) if not isinstance(data, ma.MaskedArray) else data
|
167
|
+
for key, downsample in storage.items():
|
168
|
+
downsample[i, j] = ma.mean(data_ma)
|
169
|
+
if "_A" in key and not data_ma.mask.all():
|
170
|
+
downsample[i, j] = tl.average_column_sum(data_ma)
|
171
|
+
storage[key] = downsample
|
172
|
+
return storage
|
173
|
+
|
184
174
|
def _regrid_iwc(
|
185
175
|
self,
|
186
176
|
storage: dict,
|
@@ -189,40 +179,33 @@ class ProductGrid:
|
|
189
179
|
ind_rain: np.ndarray,
|
190
180
|
ind_no_rain: np.ndarray,
|
191
181
|
) -> dict:
|
192
|
-
"""Calculates average iwc value for grid point"""
|
193
|
-
for key,
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
elif "rain" in key and not self._obs_data[ind_rain].mask.all():
|
204
|
-
downsample[i, j] = np.nanmean(self._obs_data[ind_rain])
|
205
|
-
else:
|
206
|
-
downsample[i, j] = np.nan
|
182
|
+
"""Calculates average iwc value for each grid point."""
|
183
|
+
for key, down_sample in storage.items():
|
184
|
+
down_sample[i, j] = ma.masked
|
185
|
+
if "rain" not in key:
|
186
|
+
no_rain_data = self._obs_data[ind_no_rain]
|
187
|
+
if ind_no_rain.any() and not no_rain_data.mask.all():
|
188
|
+
down_sample[i, j] = ma.mean(no_rain_data)
|
189
|
+
if "rain" in key:
|
190
|
+
rain_data = self._obs_data[ind_rain]
|
191
|
+
if ind_rain.any() and not rain_data.mask.all():
|
192
|
+
down_sample[i, j] = ma.mean(rain_data)
|
207
193
|
if "att" in key:
|
208
|
-
|
209
|
-
if
|
210
|
-
|
211
|
-
|
212
|
-
downsample[i, j] = np.nanmean(iwc_att[ind_no_rain])
|
213
|
-
storage[key] = downsample
|
194
|
+
no_rain_att_data = self._obs_obj.data["iwc_att"][ind_no_rain]
|
195
|
+
if ind_no_rain.any() and not no_rain_att_data.mask.all():
|
196
|
+
down_sample[i, j] = ma.mean(no_rain_att_data)
|
197
|
+
storage[key] = down_sample
|
214
198
|
return storage
|
215
199
|
|
216
200
|
def _regrid_product(self, storage: dict, i: int, j: int, ind: np.ndarray) -> dict:
|
217
|
-
"""Calculates average of standard product value
|
201
|
+
"""Calculates average of standard product value for each grid point."""
|
218
202
|
for key, down_sample in storage.items():
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
down_sample[i, j] = np.nan
|
203
|
+
obs_data_selected = ma.masked_invalid(self._obs_data[ind])
|
204
|
+
down_sample[i, j] = (
|
205
|
+
ma.mean(obs_data_selected)
|
206
|
+
if not obs_data_selected.mask.all()
|
207
|
+
else ma.masked
|
208
|
+
)
|
226
209
|
storage[key] = down_sample
|
227
210
|
return storage
|
228
211
|
|
@@ -3,6 +3,7 @@ from datetime import date
|
|
3
3
|
import netCDF4
|
4
4
|
import numpy as np
|
5
5
|
import pytest
|
6
|
+
from numpy import ma
|
6
7
|
|
7
8
|
|
8
9
|
@pytest.fixture(scope="session")
|
@@ -28,7 +29,7 @@ def model_file(tmpdir_factory, file_metadata) -> str:
|
|
28
29
|
root_grp.createDimension("level", level)
|
29
30
|
_create_global_attributes(root_grp, file_metadata)
|
30
31
|
var = root_grp.createVariable("time", "f8", "time")
|
31
|
-
var[:] =
|
32
|
+
var[:] = ma.array([2, 6, 10])
|
32
33
|
var = root_grp.createVariable("level", "f8", "level")
|
33
34
|
var[:] = level
|
34
35
|
var = root_grp.createVariable("latitude", "f8")
|
@@ -38,24 +39,24 @@ def model_file(tmpdir_factory, file_metadata) -> str:
|
|
38
39
|
var = root_grp.createVariable("horizontal_resolution", "f8")
|
39
40
|
var[:] = 9
|
40
41
|
var = root_grp.createVariable("height", "f8", ("time", "level"))
|
41
|
-
var[:] =
|
42
|
+
var[:] = ma.array([[10, 14], [8, 14], [9, 15]])
|
42
43
|
var.units = "km"
|
43
44
|
var = root_grp.createVariable("forecast_time", "f8", "time")
|
44
|
-
var[:] =
|
45
|
+
var[:] = ma.array([1, 5, 10])
|
45
46
|
var = root_grp.createVariable("cloud_fraction", "f8", ("time", "level"))
|
46
|
-
var[:] =
|
47
|
+
var[:] = ma.array([[0, 2], [3, 6], [5, 8]])
|
47
48
|
var = root_grp.createVariable("qi", "f8", ("time", "level"))
|
48
|
-
var[:] =
|
49
|
+
var[:] = ma.array([[0.01, 0.00], [0.02, 0.03], [0.06, 0.08]])
|
49
50
|
var = root_grp.createVariable("ql", "f8", ("time", "level"))
|
50
|
-
var[:] =
|
51
|
+
var[:] = ma.array([[0.008, 0.09], [0.004, 0.007], [0.0001, 0.0002]])
|
51
52
|
var = root_grp.createVariable("temperature", "f8", ("time", "level"))
|
52
|
-
var[:] =
|
53
|
+
var[:] = ma.array([[300, 301], [302, 299], [305, 298]])
|
53
54
|
var = root_grp.createVariable("pressure", "f8", ("time", "level"))
|
54
|
-
var[:] =
|
55
|
+
var[:] = ma.array([[1000, 1001], [1010, 1003], [1020, 1005]])
|
55
56
|
var = root_grp.createVariable("uwind", "f8", ("time", "level"))
|
56
|
-
var[:] =
|
57
|
+
var[:] = ma.array([[1, 2], [2, 2], [3, 1]])
|
57
58
|
var = root_grp.createVariable("vwind", "f8", ("time", "level"))
|
58
|
-
var[:] =
|
59
|
+
var[:] = ma.array([[3, 1], [2, 1], [5, 2]])
|
59
60
|
root_grp.close()
|
60
61
|
return file_name
|
61
62
|
|
@@ -70,9 +71,9 @@ def obs_file(tmpdir_factory, file_metadata) -> str:
|
|
70
71
|
root_grp.createDimension("height", height)
|
71
72
|
_create_global_attributes(root_grp, file_metadata)
|
72
73
|
var = root_grp.createVariable("time", "f8", "time")
|
73
|
-
var[:] =
|
74
|
+
var[:] = ma.array([0, 2, 4, 6, 8, 10])
|
74
75
|
var = root_grp.createVariable("height", "f8", "height")
|
75
|
-
var[:] =
|
76
|
+
var[:] = ma.array([8, 9, 12, 15])
|
76
77
|
var.units = "km"
|
77
78
|
var = root_grp.createVariable("latitude", "f8")
|
78
79
|
var[:] = 1
|
@@ -84,11 +85,11 @@ def obs_file(tmpdir_factory, file_metadata) -> str:
|
|
84
85
|
var = root_grp.createVariable("radar_frequency", "f8")
|
85
86
|
var[:] = 35.5
|
86
87
|
var = root_grp.createVariable("rainrate", "i4", "time")
|
87
|
-
var[:] =
|
88
|
+
var[:] = ma.array([1, 2, 0, 10, 5, 13])
|
88
89
|
var = root_grp.createVariable("Z_sensitivity", "f8", "height")
|
89
|
-
var[:] =
|
90
|
+
var[:] = ma.array([0.1, 0.2, 0.0, 1.0])
|
90
91
|
var = root_grp.createVariable("category_bits", "i4", ("time", "height"))
|
91
|
-
var[:] =
|
92
|
+
var[:] = ma.array(
|
92
93
|
[
|
93
94
|
[0, 1, 2, 0],
|
94
95
|
[2, 8, 4, 1],
|
@@ -99,7 +100,7 @@ def obs_file(tmpdir_factory, file_metadata) -> str:
|
|
99
100
|
],
|
100
101
|
)
|
101
102
|
var = root_grp.createVariable("quality_bits", "i4", ("time", "height"))
|
102
|
-
var[:] =
|
103
|
+
var[:] = ma.array(
|
103
104
|
[
|
104
105
|
[0, 1, 2, 4],
|
105
106
|
[8, 16, 32, 16],
|
@@ -110,7 +111,7 @@ def obs_file(tmpdir_factory, file_metadata) -> str:
|
|
110
111
|
],
|
111
112
|
)
|
112
113
|
var = root_grp.createVariable("iwc", "f8", ("time", "height"))
|
113
|
-
var[:] =
|
114
|
+
var[:] = ma.array(
|
114
115
|
[
|
115
116
|
[0.01, 0.02, 0.06, 0.01],
|
116
117
|
[0.02, 0.06, 0.00, 0.03],
|
@@ -121,7 +122,7 @@ def obs_file(tmpdir_factory, file_metadata) -> str:
|
|
121
122
|
],
|
122
123
|
)
|
123
124
|
var = root_grp.createVariable("iwc_retrieval_status", "f8", ("time", "height"))
|
124
|
-
var[:] =
|
125
|
+
var[:] = ma.array(
|
125
126
|
[
|
126
127
|
[1, 2, 6, 1],
|
127
128
|
[2, 6, 5, 3],
|
@@ -132,7 +133,7 @@ def obs_file(tmpdir_factory, file_metadata) -> str:
|
|
132
133
|
],
|
133
134
|
)
|
134
135
|
var = root_grp.createVariable("lwc", "f8", ("time", "height"))
|
135
|
-
var[:] =
|
136
|
+
var[:] = ma.array(
|
136
137
|
[
|
137
138
|
[0.08, 0.04, 0.01, 0.08],
|
138
139
|
[0.04, 0.01, 0.09, 0.07],
|
@@ -143,7 +144,7 @@ def obs_file(tmpdir_factory, file_metadata) -> str:
|
|
143
144
|
],
|
144
145
|
)
|
145
146
|
var = root_grp.createVariable("data", "i4", ("time", "height"))
|
146
|
-
var[:] =
|
147
|
+
var[:] = ma.array(
|
147
148
|
[
|
148
149
|
[2, 4, 3, 6],
|
149
150
|
[7, 1, 9, 7],
|
@@ -167,7 +168,7 @@ def regrid_file(tmpdir_factory, file_metadata) -> str:
|
|
167
168
|
root_grp.createDimension("level", level)
|
168
169
|
_create_global_attributes(root_grp, file_metadata)
|
169
170
|
var = root_grp.createVariable("time", "f8", "time")
|
170
|
-
var[:] =
|
171
|
+
var[:] = ma.array([2, 6, 10])
|
171
172
|
var = root_grp.createVariable("level", "f8", "level")
|
172
173
|
var[:] = level
|
173
174
|
var = root_grp.createVariable("latitude", "f8")
|
@@ -177,23 +178,23 @@ def regrid_file(tmpdir_factory, file_metadata) -> str:
|
|
177
178
|
var = root_grp.createVariable("horizontal_resolution", "f8")
|
178
179
|
var[:] = 9
|
179
180
|
var = root_grp.createVariable("ecmwf_height", "f8", ("time", "level"))
|
180
|
-
var[:] =
|
181
|
+
var[:] = ma.array([[10, 14], [8, 14], [9, 15]])
|
181
182
|
var = root_grp.createVariable("ecmwf_forecast_time", "f8", "time")
|
182
|
-
var[:] =
|
183
|
+
var[:] = ma.array([1, 5, 10])
|
183
184
|
var = root_grp.createVariable("ecmwf_cf", "f8", ("time", "level"))
|
184
|
-
var[:] =
|
185
|
+
var[:] = ma.array([[0, 2], [3, 6], [5, 8]])
|
185
186
|
var = root_grp.createVariable("ecmwf_cf_cirrus", "f8", ("time", "level"))
|
186
|
-
var[:] =
|
187
|
+
var[:] = ma.array([[0, 2], [3, 6], [5, 7]])
|
187
188
|
var = root_grp.createVariable("ecmwf_cf_snow", "f8", ("time", "level"))
|
188
|
-
var[:] =
|
189
|
+
var[:] = ma.array([[0, 2], [4, 6], [5, 8]])
|
189
190
|
var = root_grp.createVariable("cf_ecmwf", "f8", ("time", "level"))
|
190
|
-
var[:] =
|
191
|
+
var[:] = ma.array([[0, 2], [3, 6], [5, 8]])
|
191
192
|
var = root_grp.createVariable("cf_adv_ecmwf", "f8", ("time", "level"))
|
192
|
-
var[:] =
|
193
|
+
var[:] = ma.array([[0, 2], [3, 6], [5, 8]])
|
193
194
|
var = root_grp.createVariable("temperature", "f8", ("time", "level"))
|
194
|
-
var[:] =
|
195
|
+
var[:] = ma.array([[300, 301], [302, 299], [305, 298]])
|
195
196
|
var = root_grp.createVariable("pressure", "f8", ("time", "level"))
|
196
|
-
var[:] =
|
197
|
+
var[:] = ma.array([[1000, 1001], [1010, 1003], [1020, 1005]])
|
197
198
|
root_grp.close()
|
198
199
|
return file_name
|
199
200
|
|
@@ -248,31 +248,6 @@ def test_gamma_distribution(obs_file, model_file) -> None:
|
|
248
248
|
testing.assert_array_almost_equal(x, compare)
|
249
249
|
|
250
250
|
|
251
|
-
def test_get_observation_index(obs_file, model_file) -> None:
|
252
|
-
obs = ObservationManager(PRODUCT, str(obs_file))
|
253
|
-
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
254
|
-
adv_pro = AdvanceProductMethods(model, str(model_file), obs)
|
255
|
-
tZT = 0.01
|
256
|
-
z_sen = 0.02
|
257
|
-
temperature = -13
|
258
|
-
tT = 0.04
|
259
|
-
tZ = 0.05
|
260
|
-
t = 0.06
|
261
|
-
min_iwc = 10 ** (tZT * z_sen * temperature + tT * temperature + tZ * z_sen + t)
|
262
|
-
iwc_dist = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
|
263
|
-
compare = iwc_dist > min_iwc
|
264
|
-
x = adv_pro.get_observation_index(
|
265
|
-
iwc_dist,
|
266
|
-
tZT,
|
267
|
-
tT,
|
268
|
-
tZ,
|
269
|
-
np.array([t]),
|
270
|
-
temperature,
|
271
|
-
z_sen,
|
272
|
-
)
|
273
|
-
testing.assert_array_almost_equal(x, compare)
|
274
|
-
|
275
|
-
|
276
251
|
def test_filter_cirrus(obs_file, model_file) -> None:
|
277
252
|
obs = ObservationManager(PRODUCT, str(obs_file))
|
278
253
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|