cloudnetpy 1.60.2__py3-none-any.whl → 1.60.4__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/model_evaluation/model_metadata.py +1 -1
- cloudnetpy/model_evaluation/plotting/plotting.py +31 -9
- cloudnetpy/model_evaluation/products/advance_methods.py +35 -49
- cloudnetpy/model_evaluation/products/grid_methods.py +45 -62
- cloudnetpy/model_evaluation/tests/unit/conftest.py +31 -30
- cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +0 -25
- cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +88 -85
- cloudnetpy/plotting/plotting.py +5 -4
- cloudnetpy/version.py +1 -1
- {cloudnetpy-1.60.2.dist-info → cloudnetpy-1.60.4.dist-info}/METADATA +1 -1
- {cloudnetpy-1.60.2.dist-info → cloudnetpy-1.60.4.dist-info}/RECORD +14 -14
- {cloudnetpy-1.60.2.dist-info → cloudnetpy-1.60.4.dist-info}/WHEEL +1 -1
- {cloudnetpy-1.60.2.dist-info → cloudnetpy-1.60.4.dist-info}/LICENSE +0 -0
- {cloudnetpy-1.60.2.dist-info → cloudnetpy-1.60.4.dist-info}/top_level.txt +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(
|
@@ -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
|
@@ -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)
|
@@ -122,7 +122,7 @@ def test_regrid_cf_area(model_file, obs_file) -> None:
|
|
122
122
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
123
123
|
obj = ProductGrid(model, obs)
|
124
124
|
data = ma.array([[1, 1, 1], [0, 1, 1], [0, 0, 1], [0, 0, 0]])
|
125
|
-
d = {"cf_A":
|
125
|
+
d = {"cf_A": ma.zeros((1, 1))}
|
126
126
|
d = obj._regrid_cf(d, 0, 0, data)
|
127
127
|
x = d["cf_A"]
|
128
128
|
assert x[0, 0] == 0.75
|
@@ -134,7 +134,7 @@ def test_regrid_cf_area_masked(model_file, obs_file) -> None:
|
|
134
134
|
obj = ProductGrid(model, obs)
|
135
135
|
data = ma.array([[1, 1, 1], [0, 1, 1], [0, 0, 1], [0, 0, 0]])
|
136
136
|
data[1, :] = ma.masked
|
137
|
-
d = {"cf_A":
|
137
|
+
d = {"cf_A": ma.zeros((1, 1))}
|
138
138
|
d = obj._regrid_cf(d, 0, 0, data)
|
139
139
|
x = d["cf_A"]
|
140
140
|
assert round(x[0, 0], 3) == 0.667
|
@@ -146,18 +146,19 @@ def test_regrid_cf_area_all_masked(model_file, obs_file) -> None:
|
|
146
146
|
obj = ProductGrid(model, obs)
|
147
147
|
data = ma.array([[1, 1, 1], [0, 1, 1], [0, 0, 1], [0, 0, 0]])
|
148
148
|
data[:, :] = ma.masked
|
149
|
-
d = {"cf_A":
|
149
|
+
d = {"cf_A": ma.zeros((1, 1))}
|
150
150
|
d = obj._regrid_cf(d, 0, 0, data)
|
151
151
|
x = d["cf_A"]
|
152
|
-
testing.assert_equal(x,
|
152
|
+
testing.assert_equal(x, ma.masked)
|
153
153
|
|
154
154
|
|
155
155
|
def test_regrid_cf_area_nan(model_file, obs_file) -> None:
|
156
156
|
obs = ObservationManager(PRODUCT, str(obs_file))
|
157
157
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
158
158
|
obj = ProductGrid(model, obs)
|
159
|
-
data = ma.array([[1,
|
160
|
-
|
159
|
+
data = ma.array([[1, 99, 1], [0, 1, 1], [99, 0, 1], [0, 0, 0]])
|
160
|
+
data = ma.masked_where(data == 99, data)
|
161
|
+
d = {"cf_A": ma.zeros((1, 1))}
|
161
162
|
d = obj._regrid_cf(d, 0, 0, data)
|
162
163
|
x = d["cf_A"]
|
163
164
|
assert x[0, 0] == 0.75
|
@@ -169,18 +170,16 @@ def test_regrid_cf_area_all_nan(model_file, obs_file) -> None:
|
|
169
170
|
obj = ProductGrid(model, obs)
|
170
171
|
data = ma.array(
|
171
172
|
[
|
172
|
-
[
|
173
|
-
[
|
174
|
-
[
|
175
|
-
[
|
176
|
-
],
|
173
|
+
[1, 1, 1],
|
174
|
+
[1, 1, 1],
|
175
|
+
[1, 1, 1],
|
176
|
+
[1, 1, 1],
|
177
|
+
], mask=True
|
177
178
|
)
|
178
|
-
d = {"cf_A":
|
179
|
+
d = {"cf_A": ma.zeros((1, 1))}
|
179
180
|
d = obj._regrid_cf(d, 0, 0, data)
|
180
181
|
x = d["cf_A"]
|
181
|
-
|
182
|
-
# testing.assert_equal(x, 0.0)
|
183
|
-
testing.assert_equal(x, np.nan)
|
182
|
+
testing.assert_equal(x, ma.masked)
|
184
183
|
|
185
184
|
|
186
185
|
def test_regrid_cf_volume(model_file, obs_file) -> None:
|
@@ -188,7 +187,7 @@ def test_regrid_cf_volume(model_file, obs_file) -> None:
|
|
188
187
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
189
188
|
obj = ProductGrid(model, obs)
|
190
189
|
data = ma.array([[1, 1, 1], [0, 1, 1], [0, 0, 1], [0, 0, 0]])
|
191
|
-
d = {"cf_V":
|
190
|
+
d = {"cf_V": ma.zeros((1, 1))}
|
192
191
|
d = obj._regrid_cf(d, 0, 0, data)
|
193
192
|
x = d["cf_V"]
|
194
193
|
assert x[0, 0] == 0.5
|
@@ -198,8 +197,9 @@ def test_regrid_cf_volume_nan(model_file, obs_file) -> None:
|
|
198
197
|
obs = ObservationManager(PRODUCT, str(obs_file))
|
199
198
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
200
199
|
obj = ProductGrid(model, obs)
|
201
|
-
data = ma.array([[1,
|
202
|
-
|
200
|
+
data = ma.array([[1, 99, 1], [0, 1, 1], [99, 0, 1], [0, 0, 0]])
|
201
|
+
data = ma.masked_where(data == 99, data)
|
202
|
+
d = {"cf_V": ma.zeros((1, 1))}
|
203
203
|
d = obj._regrid_cf(d, 0, 0, data)
|
204
204
|
x = d["cf_V"]
|
205
205
|
assert x[0, 0] == 0.5
|
@@ -211,16 +211,17 @@ def test_regrid_cf_volume_all_nan(model_file, obs_file) -> None:
|
|
211
211
|
obj = ProductGrid(model, obs)
|
212
212
|
data = ma.array(
|
213
213
|
[
|
214
|
-
[
|
215
|
-
[
|
216
|
-
[
|
217
|
-
[
|
214
|
+
[99, 99, 99],
|
215
|
+
[99, 99, 99],
|
216
|
+
[99, 99, 99],
|
217
|
+
[99, 99, 99],
|
218
218
|
],
|
219
219
|
)
|
220
|
-
|
220
|
+
data = ma.masked_where(data == 99, data)
|
221
|
+
d = {"cf_V": ma.zeros((1, 1))}
|
221
222
|
d = obj._regrid_cf(d, 0, 0, data)
|
222
223
|
x = d["cf_V"]
|
223
|
-
testing.assert_equal(x,
|
224
|
+
testing.assert_equal(x, ma.masked)
|
224
225
|
|
225
226
|
|
226
227
|
def test_regrid_cf_volume_masked(model_file, obs_file) -> None:
|
@@ -229,7 +230,7 @@ def test_regrid_cf_volume_masked(model_file, obs_file) -> None:
|
|
229
230
|
obj = ProductGrid(model, obs)
|
230
231
|
data = ma.array([[1, 1, 1], [0, 1, 1], [0, 0, 1], [0, 0, 0]])
|
231
232
|
data[1, :] = ma.masked
|
232
|
-
d = {"cf_V":
|
233
|
+
d = {"cf_V": ma.zeros((1, 1))}
|
233
234
|
d = obj._regrid_cf(d, 0, 0, data)
|
234
235
|
x = d["cf_V"]
|
235
236
|
assert round(x[0, 0], 3) == 0.444
|
@@ -241,10 +242,10 @@ def test_regrid_cf_volume_all_masked(model_file, obs_file) -> None:
|
|
241
242
|
obj = ProductGrid(model, obs)
|
242
243
|
data = ma.array([[1, 1, 1], [0, 1, 1], [0, 0, 1], [0, 0, 0]])
|
243
244
|
data[:, :] = ma.masked
|
244
|
-
d = {"cf_V":
|
245
|
+
d = {"cf_V": ma.zeros((1, 1))}
|
245
246
|
d = obj._regrid_cf(d, 0, 0, data)
|
246
247
|
x = d["cf_V"]
|
247
|
-
testing.assert_equal(x,
|
248
|
+
testing.assert_equal(x, ma.masked)
|
248
249
|
|
249
250
|
|
250
251
|
def test_reshape_data_to_window(model_file, obs_file) -> None:
|
@@ -338,7 +339,7 @@ def test_regrid_iwc(model_file, obs_file) -> None:
|
|
338
339
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
339
340
|
obj = ProductGrid(model, obs)
|
340
341
|
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 3]])
|
341
|
-
d = {"iwc":
|
342
|
+
d = {"iwc": ma.zeros((1, 1))}
|
342
343
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
343
344
|
no_rain = ma.array(
|
344
345
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],
|
@@ -354,9 +355,10 @@ def test_regrid_iwc_nan(model_file, obs_file) -> None:
|
|
354
355
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
355
356
|
obj = ProductGrid(model, obs)
|
356
357
|
obj._obs_data = ma.array(
|
357
|
-
[[1, 1,
|
358
|
+
[[1, 1, 99, 1], [2, 99, 2, 2], [3, 3, 3, 3], [4, 4, 4, 99]],
|
358
359
|
)
|
359
|
-
|
360
|
+
obj._obs_data = ma.masked_where(obj._obs_data == 99, obj._obs_data)
|
361
|
+
d = {"iwc": ma.zeros((1, 1))}
|
360
362
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
361
363
|
no_rain = ma.array(
|
362
364
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],
|
@@ -373,21 +375,21 @@ def test_regrid_iwc_all_nan(model_file, obs_file) -> None:
|
|
373
375
|
obj = ProductGrid(model, obs)
|
374
376
|
obj._obs_data = ma.array(
|
375
377
|
[
|
376
|
-
[
|
377
|
-
[
|
378
|
-
[
|
379
|
-
[
|
378
|
+
[99, 99, 99, 99],
|
379
|
+
[99, 99, 99, 99],
|
380
|
+
[99, 99, 99, 99],
|
381
|
+
[99, 99, 99, 99],
|
380
382
|
],
|
381
383
|
)
|
382
|
-
|
384
|
+
obj._obs_data = ma.masked_where(obj._obs_data == 99, obj._obs_data)
|
385
|
+
d = {"iwc": ma.zeros((1, 1))}
|
383
386
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
384
387
|
no_rain = ma.array(
|
385
388
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],
|
386
389
|
dtype=bool,
|
387
390
|
)
|
388
391
|
d = obj._regrid_iwc(d, 0, 0, ind, no_rain)
|
389
|
-
|
390
|
-
testing.assert_almost_equal(x[0, 0], np.nan)
|
392
|
+
assert d["iwc"][0, 0].mask == True
|
391
393
|
|
392
394
|
|
393
395
|
def test_regrid_iwc_masked(model_file, obs_file) -> None:
|
@@ -396,7 +398,7 @@ def test_regrid_iwc_masked(model_file, obs_file) -> None:
|
|
396
398
|
obj = ProductGrid(model, obs)
|
397
399
|
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]])
|
398
400
|
obj._obs_data[1, :] = ma.masked
|
399
|
-
d = {"iwc":
|
401
|
+
d = {"iwc": ma.zeros((1, 1))}
|
400
402
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
401
403
|
no_rain = ma.array(
|
402
404
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],
|
@@ -411,17 +413,15 @@ def test_regrid_iwc_all_masked(model_file, obs_file) -> None:
|
|
411
413
|
obs = ObservationManager(PRODUCT, str(obs_file))
|
412
414
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
413
415
|
obj = ProductGrid(model, obs)
|
414
|
-
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]])
|
415
|
-
|
416
|
-
d = {"iwc": np.zeros((1, 1))}
|
416
|
+
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]], mask=True)
|
417
|
+
d = {"iwc": ma.zeros((1, 1))}
|
417
418
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
418
419
|
no_rain = ma.array(
|
419
420
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]],
|
420
421
|
dtype=bool,
|
421
422
|
)
|
422
423
|
d = obj._regrid_iwc(d, 0, 0, ind, no_rain)
|
423
|
-
|
424
|
-
testing.assert_almost_equal(x[0, 0], np.nan)
|
424
|
+
assert d["iwc"][0, 0].mask == True
|
425
425
|
|
426
426
|
|
427
427
|
def test_regrid_iwc_none(model_file, obs_file) -> None:
|
@@ -429,22 +429,21 @@ def test_regrid_iwc_none(model_file, obs_file) -> None:
|
|
429
429
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
430
430
|
obj = ProductGrid(model, obs)
|
431
431
|
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]])
|
432
|
-
d = {"iwc":
|
432
|
+
d = {"iwc": ma.zeros((1, 1))}
|
433
433
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
434
434
|
no_rain = ma.array(
|
435
435
|
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
|
436
436
|
dtype=bool,
|
437
437
|
)
|
438
438
|
d = obj._regrid_iwc(d, 0, 0, ind, no_rain)
|
439
|
-
|
440
|
-
testing.assert_equal(x[0, 0], np.nan)
|
439
|
+
assert d["iwc"][0, 0].mask == True
|
441
440
|
|
442
441
|
|
443
442
|
def test_regrid_iwc_att(model_file, obs_file) -> None:
|
444
443
|
obs = ObservationManager(PRODUCT, str(obs_file))
|
445
444
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
446
445
|
obj = ProductGrid(model, obs)
|
447
|
-
d = {"iwc_att":
|
446
|
+
d = {"iwc_att": ma.zeros((1, 1))}
|
448
447
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
449
448
|
no_rain = ma.array(
|
450
449
|
[
|
@@ -477,7 +476,7 @@ def test_regrid_iwc_att_masked(model_file, obs_file) -> None:
|
|
477
476
|
],
|
478
477
|
dtype=bool,
|
479
478
|
)
|
480
|
-
d = {"iwc_att":
|
479
|
+
d = {"iwc_att": ma.zeros((1, 1))}
|
481
480
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
482
481
|
no_rain = ma.array(
|
483
482
|
[
|
@@ -510,7 +509,7 @@ def test_regrid_iwc_att_all_masked(model_file, obs_file) -> None:
|
|
510
509
|
],
|
511
510
|
dtype=bool,
|
512
511
|
)
|
513
|
-
d = {"iwc_att":
|
512
|
+
d = {"iwc_att": ma.zeros((1, 1))}
|
514
513
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
515
514
|
no_rain = ma.array(
|
516
515
|
[
|
@@ -525,14 +524,15 @@ def test_regrid_iwc_att_all_masked(model_file, obs_file) -> None:
|
|
525
524
|
)
|
526
525
|
d = obj._regrid_iwc(d, 0, 0, ind, no_rain)
|
527
526
|
x = d["iwc_att"]
|
528
|
-
|
527
|
+
# Simo: not sure if this should be masked or not
|
528
|
+
assert x[0, 0] == 0.01
|
529
529
|
|
530
530
|
|
531
531
|
def test_regrid_iwc_att_none(model_file, obs_file) -> None:
|
532
532
|
obs = ObservationManager(PRODUCT, str(obs_file))
|
533
533
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
534
534
|
obj = ProductGrid(model, obs)
|
535
|
-
d = {"iwc_att":
|
535
|
+
d = {"iwc_att": ma.zeros((1, 1))}
|
536
536
|
ind = ma.array([[0, 1, 1, 1]], dtype=bool)
|
537
537
|
no_rain = ma.array(
|
538
538
|
[
|
@@ -547,7 +547,7 @@ def test_regrid_iwc_att_none(model_file, obs_file) -> None:
|
|
547
547
|
)
|
548
548
|
d = obj._regrid_iwc(d, 0, 0, ind, no_rain)
|
549
549
|
x = d["iwc_att"]
|
550
|
-
assert
|
550
|
+
assert x[0, 0].mask == True
|
551
551
|
|
552
552
|
|
553
553
|
def test_regrid_iwc_rain(model_file, obs_file) -> None:
|
@@ -555,7 +555,7 @@ def test_regrid_iwc_rain(model_file, obs_file) -> None:
|
|
555
555
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
556
556
|
obj = ProductGrid(model, obs)
|
557
557
|
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 3]])
|
558
|
-
d = {"iwc_rain":
|
558
|
+
d = {"iwc_rain": ma.zeros((1, 1))}
|
559
559
|
ind = ma.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]], dtype=bool)
|
560
560
|
no_rain = ma.array(
|
561
561
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]],
|
@@ -572,13 +572,14 @@ def test_regrid_iwc_rain_nan(model_file, obs_file) -> None:
|
|
572
572
|
obj = ProductGrid(model, obs)
|
573
573
|
obj._obs_data = ma.array(
|
574
574
|
[
|
575
|
-
[1,
|
576
|
-
[2, 2, 2,
|
575
|
+
[1, 99, 1, 1],
|
576
|
+
[2, 2, 2, 99],
|
577
577
|
[3, 3, 3, 3],
|
578
|
-
[
|
578
|
+
[99, 4, 4, 99],
|
579
579
|
],
|
580
580
|
)
|
581
|
-
|
581
|
+
obj._obs_data = ma.masked_where(obj._obs_data == 99, obj._obs_data)
|
582
|
+
d = {"iwc_rain": ma.zeros((1, 1))}
|
582
583
|
ind = ma.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]], dtype=bool)
|
583
584
|
no_rain = ma.array(
|
584
585
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]],
|
@@ -595,13 +596,14 @@ def test_regrid_iwc_rain_all_nan(model_file, obs_file) -> None:
|
|
595
596
|
obj = ProductGrid(model, obs)
|
596
597
|
obj._obs_data = ma.array(
|
597
598
|
[
|
598
|
-
[
|
599
|
-
[
|
600
|
-
[
|
601
|
-
[
|
599
|
+
[99, 99, 99, 99],
|
600
|
+
[99, 99, 99, 99],
|
601
|
+
[99, 99, 99, 99],
|
602
|
+
[99, 99, 99, 99],
|
602
603
|
],
|
603
604
|
)
|
604
|
-
|
605
|
+
obj._obs_data = ma.masked_where(obj._obs_data == 99, obj._obs_data)
|
606
|
+
d = {"iwc_rain": ma.zeros((1, 1))}
|
605
607
|
ind = ma.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]], dtype=bool)
|
606
608
|
no_rain = ma.array(
|
607
609
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]],
|
@@ -609,7 +611,7 @@ def test_regrid_iwc_rain_all_nan(model_file, obs_file) -> None:
|
|
609
611
|
)
|
610
612
|
d = obj._regrid_iwc(d, 0, 0, ind, no_rain)
|
611
613
|
x = d["iwc_rain"]
|
612
|
-
|
614
|
+
assert x[0, 0].mask == True
|
613
615
|
|
614
616
|
|
615
617
|
def test_regrid_iwc_rain_masked(model_file, obs_file) -> None:
|
@@ -618,7 +620,7 @@ def test_regrid_iwc_rain_masked(model_file, obs_file) -> None:
|
|
618
620
|
obj = ProductGrid(model, obs)
|
619
621
|
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]])
|
620
622
|
obj._obs_data[2, :] = ma.masked
|
621
|
-
d = {"iwc_rain":
|
623
|
+
d = {"iwc_rain": ma.zeros((1, 1))}
|
622
624
|
ind = ma.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]], dtype=bool)
|
623
625
|
no_rain = ma.array(
|
624
626
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]],
|
@@ -635,7 +637,7 @@ def test_regrid_iwc_rain_all_masked(model_file, obs_file) -> None:
|
|
635
637
|
obj = ProductGrid(model, obs)
|
636
638
|
obj._obs_data = ma.array([[1, 3, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]])
|
637
639
|
obj._obs_data[:, :] = ma.masked
|
638
|
-
d = {"iwc_rain":
|
640
|
+
d = {"iwc_rain": ma.zeros((1, 1))}
|
639
641
|
ind = ma.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]], dtype=bool)
|
640
642
|
no_rain = ma.array(
|
641
643
|
[[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]],
|
@@ -643,7 +645,7 @@ def test_regrid_iwc_rain_all_masked(model_file, obs_file) -> None:
|
|
643
645
|
)
|
644
646
|
d = obj._regrid_iwc(d, 0, 0, ind, no_rain)
|
645
647
|
x = d["iwc_rain"]
|
646
|
-
|
648
|
+
assert x[0, 0].mask == True
|
647
649
|
|
648
650
|
|
649
651
|
def test_regrid_product(model_file, obs_file) -> None:
|
@@ -651,7 +653,7 @@ def test_regrid_product(model_file, obs_file) -> None:
|
|
651
653
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, "lwc")
|
652
654
|
obj = ProductGrid(model, obs)
|
653
655
|
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 1, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]])
|
654
|
-
d = {"lwc":
|
656
|
+
d = {"lwc": ma.zeros((1, 1))}
|
655
657
|
ind = ma.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], dtype=bool)
|
656
658
|
d = obj._regrid_product(d, 0, 0, ind)
|
657
659
|
x = d["lwc"]
|
@@ -664,13 +666,14 @@ def test_regrid_product_nan(model_file, obs_file) -> None:
|
|
664
666
|
obj = ProductGrid(model, obs)
|
665
667
|
obj._obs_data = ma.array(
|
666
668
|
[
|
667
|
-
[1,
|
668
|
-
[
|
669
|
-
[3, 3,
|
670
|
-
[4,
|
669
|
+
[1, 99, 1, 1],
|
670
|
+
[99, 1, 2, 2],
|
671
|
+
[3, 3, 99, 3],
|
672
|
+
[4, 99, 4, 4],
|
671
673
|
],
|
672
674
|
)
|
673
|
-
|
675
|
+
obj._obs_data = ma.masked_where(obj._obs_data == 99, obj._obs_data)
|
676
|
+
d = {"lwc": ma.zeros((1, 1))}
|
674
677
|
ind = ma.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], dtype=bool)
|
675
678
|
d = obj._regrid_product(d, 0, 0, ind)
|
676
679
|
x = d["lwc"]
|
@@ -681,19 +684,19 @@ def test_regrid_product_all_nan(model_file, obs_file) -> None:
|
|
681
684
|
obs = ObservationManager("lwc", str(obs_file))
|
682
685
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, "lwc")
|
683
686
|
obj = ProductGrid(model, obs)
|
684
|
-
|
687
|
+
data = ma.array(
|
685
688
|
[
|
686
|
-
[
|
687
|
-
[
|
688
|
-
[
|
689
|
-
[
|
689
|
+
[99, 99, 99, 99],
|
690
|
+
[99, 99, 99, 99],
|
691
|
+
[99, 99, 99, 99],
|
692
|
+
[99, 99, 99, 99],
|
690
693
|
],
|
691
694
|
)
|
692
|
-
|
695
|
+
obj._obs_data = ma.masked_where(data == 99, data)
|
696
|
+
d = {"lwc": ma.zeros((1, 1))}
|
693
697
|
ind = np.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], dtype=bool)
|
694
698
|
d = obj._regrid_product(d, 0, 0, ind)
|
695
|
-
|
696
|
-
testing.assert_almost_equal(x[0, 0], np.nan)
|
699
|
+
assert d["lwc"][0, 0].mask == True
|
697
700
|
|
698
701
|
|
699
702
|
def test_regrid_product_masked(model_file, obs_file) -> None:
|
@@ -702,7 +705,7 @@ def test_regrid_product_masked(model_file, obs_file) -> None:
|
|
702
705
|
obj = ProductGrid(model, obs)
|
703
706
|
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 1, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]])
|
704
707
|
obj._obs_data[2, :] = ma.masked
|
705
|
-
d = {"lwc":
|
708
|
+
d = {"lwc": ma.zeros((1, 1))}
|
706
709
|
ind = np.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], dtype=bool)
|
707
710
|
d = obj._regrid_product(d, 0, 0, ind)
|
708
711
|
x = d["lwc"]
|
@@ -715,11 +718,11 @@ def test_regrid_product_all_masked(model_file, obs_file) -> None:
|
|
715
718
|
obj = ProductGrid(model, obs)
|
716
719
|
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 1, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]])
|
717
720
|
obj._obs_data[:, :] = ma.masked
|
718
|
-
d = {"lwc":
|
721
|
+
d = {"lwc": ma.zeros((1, 1))}
|
719
722
|
ind = np.array([[0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]], dtype=bool)
|
720
723
|
d = obj._regrid_product(d, 0, 0, ind)
|
721
724
|
x = d["lwc"]
|
722
|
-
testing.assert_almost_equal(x,
|
725
|
+
testing.assert_almost_equal(x, ma.masked)
|
723
726
|
|
724
727
|
|
725
728
|
def test_regrid_product_none(model_file, obs_file) -> None:
|
@@ -727,11 +730,11 @@ def test_regrid_product_none(model_file, obs_file) -> None:
|
|
727
730
|
model = ModelManager(str(model_file), MODEL, OUTPUT_FILE, "lwc")
|
728
731
|
obj = ProductGrid(model, obs)
|
729
732
|
obj._obs_data = ma.array([[1, 1, 1, 1], [2, 1, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]])
|
730
|
-
d = {"lwc":
|
733
|
+
d = {"lwc": ma.zeros((1, 1))}
|
731
734
|
ind = np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], dtype=bool)
|
732
735
|
d = obj._regrid_product(d, 0, 0, ind)
|
733
736
|
x = d["lwc"]
|
734
|
-
|
737
|
+
assert x[0, 0].mask == True
|
735
738
|
|
736
739
|
|
737
740
|
@pytest.mark.parametrize("product", ["cf_A", "cf_V", "cf_A_adv", "cf_V_adv"])
|
cloudnetpy/plotting/plotting.py
CHANGED
@@ -281,10 +281,11 @@ class SubPlot:
|
|
281
281
|
|
282
282
|
def _read_plot_meta(self, file_type: str | None) -> PlotMeta:
|
283
283
|
if self.options.plot_meta is not None:
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
284
|
+
plot_meta = self.options.plot_meta
|
285
|
+
else:
|
286
|
+
fallback = ATTRIBUTES["fallback"].get(self.variable.name, PlotMeta())
|
287
|
+
file_attributes = ATTRIBUTES.get(file_type or "", {})
|
288
|
+
plot_meta = file_attributes.get(self.variable.name, fallback)
|
288
289
|
if plot_meta.clabel is None:
|
289
290
|
plot_meta = plot_meta._replace(clabel=_reformat_units(self.variable.units))
|
290
291
|
return plot_meta
|
cloudnetpy/version.py
CHANGED
@@ -8,7 +8,7 @@ cloudnetpy/metadata.py,sha256=v_VDo2vbdTxB0zIsfP69IcrwSKiRlLpsGdq6JPI4CoA,5306
|
|
8
8
|
cloudnetpy/output.py,sha256=WoVTNuxni0DUr163vZ-_mDr1brXhY15XSlGMrq9Aoqw,14700
|
9
9
|
cloudnetpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
cloudnetpy/utils.py,sha256=0TlHm71YtSrKXBsRKctitnhQrvZPE-ulEVeAQW-oK58,27398
|
11
|
-
cloudnetpy/version.py,sha256=
|
11
|
+
cloudnetpy/version.py,sha256=06fW2hQK7Jbkp2HWa_QZu8yzkaZk1XNjYTDo93YsO94,72
|
12
12
|
cloudnetpy/categorize/__init__.py,sha256=gP5q3Vis1y9u9OWgA_idlbjfWXYN_S0IBSWdwBhL_uU,69
|
13
13
|
cloudnetpy/categorize/atmos.py,sha256=fWW8ye_8HZASRAiYwURFKWzcGOYIA2RKeVxCq0lVOuM,12389
|
14
14
|
cloudnetpy/categorize/atmos_utils.py,sha256=wndpwJxc2-QnNTkV8tc8I11Vs_WkNz9sVMX1fuGgUC4,3777
|
@@ -54,15 +54,15 @@ cloudnetpy/instruments/disdrometer/thies.py,sha256=h7EwZ9tn47UUMiYqDQ68vkXv4q0rE
|
|
54
54
|
cloudnetpy/model_evaluation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
55
55
|
cloudnetpy/model_evaluation/file_handler.py,sha256=oUGIblcEWLLv16YKUch-M5KA-dGRAcuHa-9anP3xtX4,6447
|
56
56
|
cloudnetpy/model_evaluation/metadata.py,sha256=7ZL87iDbaQJIMu8wfnMvb01cGVPkl8RtvEm_tt9uIHE,8413
|
57
|
-
cloudnetpy/model_evaluation/model_metadata.py,sha256=
|
57
|
+
cloudnetpy/model_evaluation/model_metadata.py,sha256=CxpY6RPm7GOTBBmPhcNVVpm9ateUmHSUwGtFXTLq3To,1436
|
58
58
|
cloudnetpy/model_evaluation/utils.py,sha256=Z9VqYVdtY9yTr2JeVfBn4nccIVWCN5Fd-BCyB_qYI-A,154
|
59
59
|
cloudnetpy/model_evaluation/plotting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
60
|
cloudnetpy/model_evaluation/plotting/plot_meta.py,sha256=K18Ugohh24uVAIxjZgJsmK80YwsMstm6B7ptVafONAw,3557
|
61
61
|
cloudnetpy/model_evaluation/plotting/plot_tools.py,sha256=0CU9glFeYPCLhrUjvJXPL75DC-aG0dXzmcbfld5TVww,5031
|
62
|
-
cloudnetpy/model_evaluation/plotting/plotting.py,sha256=
|
62
|
+
cloudnetpy/model_evaluation/plotting/plotting.py,sha256=h3iouEKrJncPDGOMmD34hLMnrHOIsDHXpkc1yvVD63k,30877
|
63
63
|
cloudnetpy/model_evaluation/products/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
|
-
cloudnetpy/model_evaluation/products/advance_methods.py,sha256=
|
65
|
-
cloudnetpy/model_evaluation/products/grid_methods.py,sha256=
|
64
|
+
cloudnetpy/model_evaluation/products/advance_methods.py,sha256=rng3ZLR1Arv1AGUzq0Ehu-65628PC5LZVKpHSUpCIW8,8526
|
65
|
+
cloudnetpy/model_evaluation/products/grid_methods.py,sha256=fRYdPRSewsXlv1frJWOKeCIYWlRAAXRRcKgvmNeBWwY,9066
|
66
66
|
cloudnetpy/model_evaluation/products/model_products.py,sha256=SOd7dZ5lBh0ampovzJ9DryfHOC_tqFa-EN5lAQUHb3Y,6854
|
67
67
|
cloudnetpy/model_evaluation/products/observation_products.py,sha256=ttz-NINIQCSjuyZtRn-vuctHItLT8RLtwwiNXsys-UA,5492
|
68
68
|
cloudnetpy/model_evaluation/products/product_resampling.py,sha256=IuWvtwpya76URh1WmTTgtLxAo4HZxkz6GmftpZkMCGo,3640
|
@@ -82,9 +82,9 @@ cloudnetpy/model_evaluation/tests/e2e/process_lwc/__init__.py,sha256=47DEQpj8HBS
|
|
82
82
|
cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py,sha256=IFcPj-Vce9Yn0CfCy9gASxRf7NzlKFMfsDHzAuapY4I,1306
|
83
83
|
cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py,sha256=ANBA0LVao3Xrm-prRnwUmxM6BdQzqM7GZNKB3uz5BXQ,1725
|
84
84
|
cloudnetpy/model_evaluation/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
85
|
-
cloudnetpy/model_evaluation/tests/unit/conftest.py,sha256=
|
86
|
-
cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py,sha256=
|
87
|
-
cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py,sha256=
|
85
|
+
cloudnetpy/model_evaluation/tests/unit/conftest.py,sha256=WL_FgrDeoUYGp4PKjb37HLu79D9uu33PGQL40_ctqS0,7446
|
86
|
+
cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py,sha256=IkoAVtsWVFrPpFqQOLAPHKb9qgV-KjGGVEtWMudeiSo,10079
|
87
|
+
cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py,sha256=qkNPfHI25EE0-BXk73TijpeM7YwswX7e41-764o5lqE,26254
|
88
88
|
cloudnetpy/model_evaluation/tests/unit/test_model_products.py,sha256=FRbYLshSHH2E527uJPwvUIyZKTsPFSZrwDsPsNrFSSU,3475
|
89
89
|
cloudnetpy/model_evaluation/tests/unit/test_observation_products.py,sha256=P-W5QwRHMtem6p5SyyH7p9TvHGro3XW1baQcIwh6nFg,4892
|
90
90
|
cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py,sha256=POdypGWjV2NA4DCU7w8Unk_IdPfOpUb1qBDhfA3x1Bw,9222
|
@@ -93,7 +93,7 @@ cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py,sha256=Ra3r4V
|
|
93
93
|
cloudnetpy/model_evaluation/tests/unit/test_tools.py,sha256=Ia_VrLdV2NstX5gbx_3AZTOAlrgLAy_xFZ8fHYVX0xI,3817
|
94
94
|
cloudnetpy/plotting/__init__.py,sha256=lg9Smn4BI0dVBgnDLC3JVJ4GmwoSnO-qoSd4ApvwV6Y,107
|
95
95
|
cloudnetpy/plotting/plot_meta.py,sha256=cLdCZrhbP-gaobS_zjcf8d2xVALzl7zh2qpttxCHyrg,15983
|
96
|
-
cloudnetpy/plotting/plotting.py,sha256=
|
96
|
+
cloudnetpy/plotting/plotting.py,sha256=bve91iM9RcWmKaZOFWxVh2y3DPmupI1944MMYDdv17I,32459
|
97
97
|
cloudnetpy/products/__init__.py,sha256=2hRb5HG9hNrxH1if5laJkLeFeaZCd5W1q3hh4ewsX0E,273
|
98
98
|
cloudnetpy/products/classification.py,sha256=0E9OUGR3uLCsS1nORwQu0SqW0_8uX7n6LlRcVhtzKw4,7845
|
99
99
|
cloudnetpy/products/der.py,sha256=mam6jWV7A2h8V5WC3DIeFp6ou7UD1JOw9r7h2B0su-s,12403
|
@@ -107,8 +107,8 @@ cloudnetpy/products/mie_lu_tables.nc,sha256=It4fYpqJXlqOgL8jeZ-PxGzP08PMrELIDVe5
|
|
107
107
|
cloudnetpy/products/mwr_tools.py,sha256=PRm5aCULccUehU-Byk55wYhhEHseMjoAjGBu5TSyHao,4621
|
108
108
|
cloudnetpy/products/product_tools.py,sha256=rhx_Ru9FLlQqCNM-awoiHx18-Aq1eBwL9LiUaQoJs6k,10412
|
109
109
|
docs/source/conf.py,sha256=IKiFWw6xhUd8NrCg0q7l596Ck1d61XWeVjIFHVSG9Og,1490
|
110
|
-
cloudnetpy-1.60.
|
111
|
-
cloudnetpy-1.60.
|
112
|
-
cloudnetpy-1.60.
|
113
|
-
cloudnetpy-1.60.
|
114
|
-
cloudnetpy-1.60.
|
110
|
+
cloudnetpy-1.60.4.dist-info/LICENSE,sha256=wcZF72bdaoG9XugpyE95Juo7lBQOwLuTKBOhhtANZMM,1094
|
111
|
+
cloudnetpy-1.60.4.dist-info/METADATA,sha256=3k80uCASgoavEpHtQM00w8S7ndKtjmqKDP0v0BoeLAw,5784
|
112
|
+
cloudnetpy-1.60.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
113
|
+
cloudnetpy-1.60.4.dist-info/top_level.txt,sha256=ibSPWRr6ojS1i11rtBFz2_gkIe68mggj7aeswYfaOo0,16
|
114
|
+
cloudnetpy-1.60.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|