cloudnetpy 1.49.9__py3-none-any.whl → 1.87.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cloudnetpy/categorize/__init__.py +1 -2
- cloudnetpy/categorize/atmos_utils.py +297 -67
- cloudnetpy/categorize/attenuation.py +31 -0
- cloudnetpy/categorize/attenuations/__init__.py +37 -0
- cloudnetpy/categorize/attenuations/gas_attenuation.py +30 -0
- cloudnetpy/categorize/attenuations/liquid_attenuation.py +84 -0
- cloudnetpy/categorize/attenuations/melting_attenuation.py +78 -0
- cloudnetpy/categorize/attenuations/rain_attenuation.py +84 -0
- cloudnetpy/categorize/categorize.py +332 -156
- cloudnetpy/categorize/classify.py +127 -125
- cloudnetpy/categorize/containers.py +107 -76
- cloudnetpy/categorize/disdrometer.py +40 -0
- cloudnetpy/categorize/droplet.py +23 -21
- cloudnetpy/categorize/falling.py +53 -24
- cloudnetpy/categorize/freezing.py +25 -12
- cloudnetpy/categorize/insects.py +35 -23
- cloudnetpy/categorize/itu.py +243 -0
- cloudnetpy/categorize/lidar.py +36 -41
- cloudnetpy/categorize/melting.py +34 -26
- cloudnetpy/categorize/model.py +84 -37
- cloudnetpy/categorize/mwr.py +18 -14
- cloudnetpy/categorize/radar.py +215 -102
- cloudnetpy/cli.py +578 -0
- cloudnetpy/cloudnetarray.py +43 -89
- cloudnetpy/concat_lib.py +218 -78
- cloudnetpy/constants.py +28 -10
- cloudnetpy/datasource.py +61 -86
- cloudnetpy/exceptions.py +49 -20
- cloudnetpy/instruments/__init__.py +5 -0
- cloudnetpy/instruments/basta.py +29 -12
- cloudnetpy/instruments/bowtie.py +135 -0
- cloudnetpy/instruments/ceilo.py +138 -115
- cloudnetpy/instruments/ceilometer.py +164 -80
- cloudnetpy/instruments/cl61d.py +21 -5
- cloudnetpy/instruments/cloudnet_instrument.py +74 -36
- cloudnetpy/instruments/copernicus.py +108 -30
- cloudnetpy/instruments/da10.py +54 -0
- cloudnetpy/instruments/disdrometer/common.py +126 -223
- cloudnetpy/instruments/disdrometer/parsivel.py +453 -94
- cloudnetpy/instruments/disdrometer/thies.py +254 -87
- cloudnetpy/instruments/fd12p.py +201 -0
- cloudnetpy/instruments/galileo.py +65 -23
- cloudnetpy/instruments/hatpro.py +123 -49
- cloudnetpy/instruments/instruments.py +113 -1
- cloudnetpy/instruments/lufft.py +39 -17
- cloudnetpy/instruments/mira.py +268 -61
- cloudnetpy/instruments/mrr.py +187 -0
- cloudnetpy/instruments/nc_lidar.py +19 -8
- cloudnetpy/instruments/nc_radar.py +109 -55
- cloudnetpy/instruments/pollyxt.py +135 -51
- cloudnetpy/instruments/radiometrics.py +313 -59
- cloudnetpy/instruments/rain_e_h3.py +171 -0
- cloudnetpy/instruments/rpg.py +321 -189
- cloudnetpy/instruments/rpg_reader.py +74 -40
- cloudnetpy/instruments/toa5.py +49 -0
- cloudnetpy/instruments/vaisala.py +95 -343
- cloudnetpy/instruments/weather_station.py +774 -105
- cloudnetpy/metadata.py +90 -19
- cloudnetpy/model_evaluation/file_handler.py +55 -52
- cloudnetpy/model_evaluation/metadata.py +46 -20
- cloudnetpy/model_evaluation/model_metadata.py +1 -1
- cloudnetpy/model_evaluation/plotting/plot_tools.py +32 -37
- cloudnetpy/model_evaluation/plotting/plotting.py +327 -117
- cloudnetpy/model_evaluation/products/advance_methods.py +92 -83
- cloudnetpy/model_evaluation/products/grid_methods.py +88 -63
- cloudnetpy/model_evaluation/products/model_products.py +43 -35
- cloudnetpy/model_evaluation/products/observation_products.py +41 -35
- cloudnetpy/model_evaluation/products/product_resampling.py +17 -7
- cloudnetpy/model_evaluation/products/tools.py +29 -20
- cloudnetpy/model_evaluation/statistics/statistical_methods.py +30 -20
- cloudnetpy/model_evaluation/tests/e2e/conftest.py +3 -3
- cloudnetpy/model_evaluation/tests/e2e/process_cf/main.py +9 -5
- cloudnetpy/model_evaluation/tests/e2e/process_cf/tests.py +15 -14
- cloudnetpy/model_evaluation/tests/e2e/process_iwc/main.py +9 -5
- cloudnetpy/model_evaluation/tests/e2e/process_iwc/tests.py +15 -14
- cloudnetpy/model_evaluation/tests/e2e/process_lwc/main.py +9 -5
- cloudnetpy/model_evaluation/tests/e2e/process_lwc/tests.py +15 -14
- cloudnetpy/model_evaluation/tests/unit/conftest.py +42 -41
- cloudnetpy/model_evaluation/tests/unit/test_advance_methods.py +41 -48
- cloudnetpy/model_evaluation/tests/unit/test_grid_methods.py +216 -194
- cloudnetpy/model_evaluation/tests/unit/test_model_products.py +23 -21
- cloudnetpy/model_evaluation/tests/unit/test_observation_products.py +37 -38
- cloudnetpy/model_evaluation/tests/unit/test_plot_tools.py +43 -40
- cloudnetpy/model_evaluation/tests/unit/test_plotting.py +30 -36
- cloudnetpy/model_evaluation/tests/unit/test_statistical_methods.py +68 -31
- cloudnetpy/model_evaluation/tests/unit/test_tools.py +33 -26
- cloudnetpy/model_evaluation/utils.py +2 -1
- cloudnetpy/output.py +170 -111
- cloudnetpy/plotting/__init__.py +2 -1
- cloudnetpy/plotting/plot_meta.py +562 -822
- cloudnetpy/plotting/plotting.py +1142 -704
- cloudnetpy/products/__init__.py +1 -0
- cloudnetpy/products/classification.py +370 -88
- cloudnetpy/products/der.py +85 -55
- cloudnetpy/products/drizzle.py +77 -34
- cloudnetpy/products/drizzle_error.py +15 -11
- cloudnetpy/products/drizzle_tools.py +79 -59
- cloudnetpy/products/epsilon.py +211 -0
- cloudnetpy/products/ier.py +27 -50
- cloudnetpy/products/iwc.py +55 -48
- cloudnetpy/products/lwc.py +96 -70
- cloudnetpy/products/mwr_tools.py +186 -0
- cloudnetpy/products/product_tools.py +170 -128
- cloudnetpy/utils.py +455 -240
- cloudnetpy/version.py +2 -2
- {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info}/METADATA +44 -40
- cloudnetpy-1.87.3.dist-info/RECORD +127 -0
- {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info}/WHEEL +1 -1
- cloudnetpy-1.87.3.dist-info/entry_points.txt +2 -0
- docs/source/conf.py +2 -2
- cloudnetpy/categorize/atmos.py +0 -361
- cloudnetpy/products/mwr_multi.py +0 -68
- cloudnetpy/products/mwr_single.py +0 -75
- cloudnetpy-1.49.9.dist-info/RECORD +0 -112
- {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info/licenses}/LICENSE +0 -0
- {cloudnetpy-1.49.9.dist-info → cloudnetpy-1.87.3.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import netCDF4
|
|
2
2
|
import numpy as np
|
|
3
|
-
import numpy.testing as testing
|
|
4
3
|
import pytest
|
|
4
|
+
from numpy import testing
|
|
5
5
|
|
|
6
6
|
from cloudnetpy.model_evaluation.products.model_products import ModelManager
|
|
7
7
|
|
|
@@ -14,31 +14,31 @@ PRODUCT = "iwc"
|
|
|
14
14
|
"cycle, model, answer",
|
|
15
15
|
[("test_file_12-23", "icon", "_12-23"), ("test_file", "ecmwf", "")],
|
|
16
16
|
)
|
|
17
|
-
def test_read_cycle_name(cycle, model, answer, model_file):
|
|
17
|
+
def test_read_cycle_name(cycle, model, answer, model_file) -> None:
|
|
18
18
|
obj = ModelManager(str(model_file), model, OUTPUT_FILE, PRODUCT)
|
|
19
19
|
x = obj._read_cycle_name(cycle)
|
|
20
20
|
assert x == answer
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def test_get_cf(model_file):
|
|
23
|
+
def test_get_cf(model_file) -> None:
|
|
24
24
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
|
25
25
|
obj._get_cf()
|
|
26
|
-
assert f"{MODEL}_cf" in obj.data
|
|
26
|
+
assert f"{MODEL}_cf" in obj.data
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
def test_get_iwc(model_file):
|
|
29
|
+
def test_get_iwc(model_file) -> None:
|
|
30
30
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
|
31
31
|
obj._get_iwc()
|
|
32
|
-
assert f"{MODEL}_iwc" in obj.data
|
|
32
|
+
assert f"{MODEL}_iwc" in obj.data
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
def test_get_lwc(model_file):
|
|
35
|
+
def test_get_lwc(model_file) -> None:
|
|
36
36
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, "lwc")
|
|
37
37
|
obj._get_lwc()
|
|
38
|
-
assert f"{MODEL}_lwc" in obj.data
|
|
38
|
+
assert f"{MODEL}_lwc" in obj.data
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
def test_read_config(model_file):
|
|
41
|
+
def test_read_config(model_file) -> None:
|
|
42
42
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
|
43
43
|
var = obj.get_model_var_names(("p",))
|
|
44
44
|
assert "pressure" in var
|
|
@@ -47,7 +47,7 @@ def test_read_config(model_file):
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
@pytest.mark.parametrize("key", ["pressure", "temperature"])
|
|
50
|
-
def test_set_variables(key, model_file):
|
|
50
|
+
def test_set_variables(key, model_file) -> None:
|
|
51
51
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
|
52
52
|
var = obj.getvar(key)
|
|
53
53
|
x = netCDF4.Dataset(model_file).variables[key]
|
|
@@ -55,41 +55,43 @@ def test_set_variables(key, model_file):
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
@pytest.mark.parametrize("p, T, q", [(1, 2, 3), (20, 40, 80), (0.3, 0.6, 0.9)])
|
|
58
|
-
def test_calc_water_content(p, T, q, model_file):
|
|
58
|
+
def test_calc_water_content(p, T, q, model_file) -> None:
|
|
59
59
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
|
60
60
|
x = q * p / (287 * T)
|
|
61
61
|
testing.assert_almost_equal(x, obj._calc_water_content(q, p, T))
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
@pytest.mark.parametrize(
|
|
65
|
-
"key",
|
|
65
|
+
"key",
|
|
66
|
+
["time", "level", "horizontal_resolution", "latitude", "longitude"],
|
|
66
67
|
)
|
|
67
|
-
def test_add_common_variables_false(key, model_file):
|
|
68
|
+
def test_add_common_variables_false(key, model_file) -> None:
|
|
68
69
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
|
69
70
|
obj._is_file = False
|
|
70
71
|
obj._add_variables()
|
|
71
|
-
assert key in obj.data
|
|
72
|
+
assert key in obj.data
|
|
72
73
|
|
|
73
74
|
|
|
74
75
|
@pytest.mark.parametrize(
|
|
75
|
-
"key",
|
|
76
|
+
"key",
|
|
77
|
+
["time", "level", "horizontal_resolution", "latitude", "longitude"],
|
|
76
78
|
)
|
|
77
|
-
def test_add_common_variables_true(key, model_file, regrid_file):
|
|
79
|
+
def test_add_common_variables_true(key, model_file, regrid_file) -> None:
|
|
78
80
|
obj = ModelManager(str(model_file), MODEL, regrid_file, PRODUCT)
|
|
79
81
|
obj._is_file = True
|
|
80
82
|
obj._add_variables()
|
|
81
|
-
assert key not in obj.data
|
|
83
|
+
assert key not in obj.data
|
|
82
84
|
|
|
83
85
|
|
|
84
86
|
@pytest.mark.parametrize("key", ["height", "forecast_time"])
|
|
85
|
-
def test_add_cycle_variables_no_products(key, model_file):
|
|
87
|
+
def test_add_cycle_variables_no_products(key, model_file) -> None:
|
|
86
88
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
|
87
89
|
obj._is_file = False
|
|
88
90
|
obj._add_variables()
|
|
89
|
-
assert f"{MODEL}_{key}" in obj.data
|
|
91
|
+
assert f"{MODEL}_{key}" in obj.data
|
|
90
92
|
|
|
91
93
|
|
|
92
|
-
def test_cut_off_extra_levels(model_file):
|
|
94
|
+
def test_cut_off_extra_levels(model_file) -> None:
|
|
93
95
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
|
94
96
|
data = np.array([np.arange(100), np.arange(100)])
|
|
95
97
|
compare = np.array([np.arange(88), np.arange(88)])
|
|
@@ -97,7 +99,7 @@ def test_cut_off_extra_levels(model_file):
|
|
|
97
99
|
testing.assert_array_almost_equal(x, compare)
|
|
98
100
|
|
|
99
101
|
|
|
100
|
-
def test_calculate_wind_speed(model_file):
|
|
102
|
+
def test_calculate_wind_speed(model_file) -> None:
|
|
101
103
|
obj = ModelManager(str(model_file), MODEL, OUTPUT_FILE, PRODUCT)
|
|
102
104
|
u = obj.getvar("uwind")
|
|
103
105
|
v = obj.getvar("vwind")
|
|
@@ -1,48 +1,47 @@
|
|
|
1
|
-
from datetime import datetime
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
-
import numpy.ma as ma
|
|
5
|
-
import numpy.testing as testing
|
|
6
4
|
import pytest
|
|
5
|
+
from numpy import ma, testing
|
|
7
6
|
|
|
8
7
|
from cloudnetpy.model_evaluation.products.product_resampling import ObservationManager
|
|
9
|
-
from cloudnetpy.products.product_tools import CategorizeBits
|
|
8
|
+
from cloudnetpy.products.product_tools import CategorizeBits, CategoryBits
|
|
10
9
|
|
|
11
10
|
PRODUCT = "iwc"
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
class CatBits:
|
|
15
|
-
def __init__(self):
|
|
16
|
-
self.category_bits =
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def test_get_date(obs_file):
|
|
14
|
+
def __init__(self) -> None:
|
|
15
|
+
self.category_bits = CategoryBits(
|
|
16
|
+
droplet=np.asarray([[1, 0, 1, 1, 1, 1], [0, 1, 1, 1, 0, 0]], dtype=bool),
|
|
17
|
+
falling=np.asarray([[0, 0, 0, 0, 1, 0], [0, 0, 0, 1, 1, 1]], dtype=bool),
|
|
18
|
+
freezing=np.asarray([[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 0, 1]], dtype=bool),
|
|
19
|
+
melting=np.asarray([[1, 0, 1, 0, 0, 0], [1, 1, 0, 0, 0, 0]], dtype=bool),
|
|
20
|
+
aerosol=np.asarray([[1, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0]], dtype=bool),
|
|
21
|
+
insect=np.asarray([[1, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0]], dtype=bool),
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_get_date(obs_file) -> None:
|
|
27
26
|
obj = ObservationManager(PRODUCT, str(obs_file))
|
|
28
|
-
date = datetime(2019, 5, 23, 0, 0, 0)
|
|
27
|
+
date = datetime(2019, 5, 23, 0, 0, 0, tzinfo=timezone.utc)
|
|
29
28
|
assert obj._get_date() == date
|
|
30
29
|
|
|
31
30
|
|
|
32
31
|
@pytest.mark.parametrize("key", ["iwc", "lwc", "cf"])
|
|
33
|
-
def test_generate_product(key, obs_file):
|
|
32
|
+
def test_generate_product(key, obs_file) -> None:
|
|
34
33
|
obj = ObservationManager(key, str(obs_file))
|
|
35
34
|
obj._generate_product()
|
|
36
|
-
assert key in obj.data
|
|
35
|
+
assert key in obj.data
|
|
37
36
|
|
|
38
37
|
|
|
39
|
-
def test_add_height(obs_file):
|
|
38
|
+
def test_add_height(obs_file) -> None:
|
|
40
39
|
obj = ObservationManager(PRODUCT, str(obs_file))
|
|
41
40
|
obj._generate_product()
|
|
42
|
-
assert "height" in obj.data
|
|
41
|
+
assert "height" in obj.data
|
|
43
42
|
|
|
44
43
|
|
|
45
|
-
def test_generate_cf(obs_file):
|
|
44
|
+
def test_generate_cf(obs_file) -> None:
|
|
46
45
|
obj = ObservationManager("cf", str(obs_file))
|
|
47
46
|
x = obj._generate_cf()
|
|
48
47
|
compare = ma.array(
|
|
@@ -53,13 +52,13 @@ def test_generate_cf(obs_file):
|
|
|
53
52
|
[0, 0, 0, 1],
|
|
54
53
|
[1, 0, 0, 0],
|
|
55
54
|
[0, 0, 0, 0],
|
|
56
|
-
]
|
|
55
|
+
],
|
|
57
56
|
)
|
|
58
57
|
compare[~obj._rain_index(), :] = ma.masked
|
|
59
58
|
testing.assert_array_almost_equal(compare, x)
|
|
60
59
|
|
|
61
60
|
|
|
62
|
-
def test_basic_cloud_mask(obs_file):
|
|
61
|
+
def test_basic_cloud_mask(obs_file) -> None:
|
|
63
62
|
cat = CategorizeBits(str(obs_file))
|
|
64
63
|
obj = ObservationManager("cf", str(obs_file))
|
|
65
64
|
x = obj._classify_basic_mask(cat.category_bits)
|
|
@@ -71,12 +70,12 @@ def test_basic_cloud_mask(obs_file):
|
|
|
71
70
|
[0, 0, 0, 1],
|
|
72
71
|
[0, 0, 6, 6],
|
|
73
72
|
[7, 2, 0, 7],
|
|
74
|
-
]
|
|
73
|
+
],
|
|
75
74
|
)
|
|
76
75
|
testing.assert_array_almost_equal(x, compare)
|
|
77
76
|
|
|
78
77
|
|
|
79
|
-
def test_mask_cloud_bits(obs_file):
|
|
78
|
+
def test_mask_cloud_bits(obs_file) -> None:
|
|
80
79
|
cat = CategorizeBits(str(obs_file))
|
|
81
80
|
obj = ObservationManager("cf", str(obs_file))
|
|
82
81
|
mask = obj._classify_basic_mask(cat.category_bits)
|
|
@@ -89,41 +88,41 @@ def test_mask_cloud_bits(obs_file):
|
|
|
89
88
|
[0, 0, 0, 1],
|
|
90
89
|
[0, 0, 0, 0],
|
|
91
90
|
[0, 0, 0, 0],
|
|
92
|
-
]
|
|
91
|
+
],
|
|
93
92
|
)
|
|
94
93
|
testing.assert_array_almost_equal(x, compare)
|
|
95
94
|
|
|
96
95
|
|
|
97
|
-
def test_basic_cloud_mask_all_values(obs_file):
|
|
96
|
+
def test_basic_cloud_mask_all_values(obs_file) -> None:
|
|
98
97
|
cat = CatBits()
|
|
99
98
|
obj = ObservationManager("cf", str(obs_file))
|
|
100
|
-
x = obj._classify_basic_mask(cat.category_bits)
|
|
99
|
+
x = obj._classify_basic_mask(cat.category_bits) # type: ignore
|
|
101
100
|
compare = np.array([[8, 7, 6, 1, 3, 1], [0, 1, 7, 5, 2, 4]])
|
|
102
101
|
testing.assert_array_almost_equal(x, compare)
|
|
103
102
|
|
|
104
103
|
|
|
105
|
-
def test_mask_cloud_bits_all_values(obs_file):
|
|
104
|
+
def test_mask_cloud_bits_all_values(obs_file) -> None:
|
|
106
105
|
cat = CatBits()
|
|
107
106
|
obj = ObservationManager("cf", str(obs_file))
|
|
108
|
-
mask = obj._classify_basic_mask(cat.category_bits)
|
|
107
|
+
mask = obj._classify_basic_mask(cat.category_bits) # type: ignore
|
|
109
108
|
x = obj._mask_cloud_bits(mask)
|
|
110
109
|
compare = np.array([[0, 0, 0, 1, 1, 1], [0, 1, 0, 1, 0, 1]])
|
|
111
110
|
testing.assert_array_almost_equal(x, compare)
|
|
112
111
|
|
|
113
112
|
|
|
114
|
-
def test_check_rainrate(obs_file):
|
|
113
|
+
def test_check_rainrate(obs_file) -> None:
|
|
115
114
|
obj = ObservationManager("cf", str(obs_file))
|
|
116
115
|
x = obj._check_rainrate()
|
|
117
116
|
assert x is True
|
|
118
117
|
|
|
119
118
|
|
|
120
|
-
def test_get_rainrate_threshold(obs_file):
|
|
119
|
+
def test_get_rainrate_threshold(obs_file) -> None:
|
|
121
120
|
obj = ObservationManager("cf", str(obs_file))
|
|
122
121
|
x = obj._get_rainrate_threshold()
|
|
123
122
|
assert x == 8
|
|
124
123
|
|
|
125
124
|
|
|
126
|
-
def test_rain_index(obs_file):
|
|
125
|
+
def test_rain_index(obs_file) -> None:
|
|
127
126
|
obj = ObservationManager("cf", str(obs_file))
|
|
128
127
|
x = obj._rain_index()
|
|
129
128
|
compare = np.array([0, 0, 0, 1, 0, 1], dtype=bool)
|
|
@@ -131,13 +130,13 @@ def test_rain_index(obs_file):
|
|
|
131
130
|
|
|
132
131
|
|
|
133
132
|
@pytest.mark.parametrize("key", ["iwc", "iwc_att", "iwc_rain"])
|
|
134
|
-
def test_generate_iwc_masks(key, obs_file):
|
|
133
|
+
def test_generate_iwc_masks(key, obs_file) -> None:
|
|
135
134
|
obj = ObservationManager(PRODUCT, str(obs_file))
|
|
136
135
|
obj._generate_iwc_masks()
|
|
137
|
-
assert key in obj.data
|
|
136
|
+
assert key in obj.data
|
|
138
137
|
|
|
139
138
|
|
|
140
|
-
def test_get_rain_iwc(obs_file):
|
|
139
|
+
def test_get_rain_iwc(obs_file) -> None:
|
|
141
140
|
obj = ObservationManager("iwc", str(obs_file))
|
|
142
141
|
iwc_status = obj.getvar("iwc_retrieval_status")
|
|
143
142
|
x = np.zeros(iwc_status.shape)
|
|
@@ -148,7 +147,7 @@ def test_get_rain_iwc(obs_file):
|
|
|
148
147
|
testing.assert_array_almost_equal(x, compare[:])
|
|
149
148
|
|
|
150
149
|
|
|
151
|
-
def test_mask_iwc_att(obs_file):
|
|
150
|
+
def test_mask_iwc_att(obs_file) -> None:
|
|
152
151
|
obj = ObservationManager("iwc", str(obs_file))
|
|
153
152
|
iwc = obj.getvar("iwc")
|
|
154
153
|
iwc_status = obj.getvar("iwc_retrieval_status")
|
|
@@ -4,58 +4,59 @@ from numpy import ma, testing
|
|
|
4
4
|
from cloudnetpy.model_evaluation.plotting import plot_tools as plt
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def test_parse_wanted_names(regrid_file):
|
|
7
|
+
def test_parse_wanted_names(regrid_file) -> None:
|
|
8
8
|
"""nc_file: str, name: str, model: str,
|
|
9
9
|
vars: list | None = None,
|
|
10
|
-
advance: bool = False
|
|
10
|
+
advance: bool = False
|
|
11
|
+
"""
|
|
11
12
|
compare = ["ecmwf_cf", "cf_ecmwf"]
|
|
12
13
|
x, _ = plt.parse_wanted_names(regrid_file, "cf", "ecmwf")
|
|
13
14
|
assert x == compare
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
def test_parse_wanted_names_adv(regrid_file):
|
|
17
|
+
def test_parse_wanted_names_adv(regrid_file) -> None:
|
|
17
18
|
compare = ["ecmwf_cf", "cf_adv_ecmwf"]
|
|
18
19
|
_, x_adv = plt.parse_wanted_names(regrid_file, "cf", "ecmwf")
|
|
19
20
|
assert x_adv == compare
|
|
20
21
|
|
|
21
22
|
|
|
22
|
-
def test_parse_wanted_names_advance_False(regrid_file):
|
|
23
|
+
def test_parse_wanted_names_advance_False(regrid_file) -> None:
|
|
23
24
|
compare = ["ecmwf_cf", "cf_ecmwf"]
|
|
24
25
|
x, _ = plt.parse_wanted_names(regrid_file, "cf", "ecmwf", advance=False)
|
|
25
26
|
assert x == compare
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
def test_parse_wanted_names_advance_True(regrid_file):
|
|
29
|
+
def test_parse_wanted_names_advance_True(regrid_file) -> None:
|
|
29
30
|
compare = ["ecmwf_cf", "ecmwf_cf_cirrus", "ecmwf_cf_snow", "cf_ecmwf"]
|
|
30
31
|
x, _ = plt.parse_wanted_names(regrid_file, "cf", "ecmwf", advance=True)
|
|
31
32
|
assert x == compare
|
|
32
33
|
|
|
33
34
|
|
|
34
|
-
def test_parse_wanted_names_adv_advance_True(regrid_file):
|
|
35
|
+
def test_parse_wanted_names_adv_advance_True(regrid_file) -> None:
|
|
35
36
|
compare = ["ecmwf_cf", "ecmwf_cf_cirrus", "ecmwf_cf_snow", "cf_adv_ecmwf"]
|
|
36
37
|
_, x_adv = plt.parse_wanted_names(regrid_file, "cf", "ecmwf", advance=True)
|
|
37
38
|
assert x_adv == compare
|
|
38
39
|
|
|
39
40
|
|
|
40
|
-
def test_parse_wanted_names_adv_advance_False(regrid_file):
|
|
41
|
+
def test_parse_wanted_names_adv_advance_False(regrid_file) -> None:
|
|
41
42
|
compare = ["ecmwf_cf", "cf_adv_ecmwf"]
|
|
42
43
|
_, x_adv = plt.parse_wanted_names(regrid_file, "cf", "ecmwf", advance=False)
|
|
43
44
|
assert x_adv == compare
|
|
44
45
|
|
|
45
46
|
|
|
46
|
-
def test_parse_wanted_names_fixed_list(regrid_file):
|
|
47
|
+
def test_parse_wanted_names_fixed_list(regrid_file) -> None:
|
|
47
48
|
compare = ["ecmwf_cf", "ecmwf_cf_cirrus"]
|
|
48
49
|
x, _ = plt.parse_wanted_names(regrid_file, "cf", "ecmwf", variables=compare)
|
|
49
50
|
assert x == compare
|
|
50
51
|
|
|
51
52
|
|
|
52
|
-
def test_parse_wanted_names_adv_fixed_list(regrid_file):
|
|
53
|
+
def test_parse_wanted_names_adv_fixed_list(regrid_file) -> None:
|
|
53
54
|
compare = ["ecmwf_cf_cirrus", "cf_adv_ecmwf"]
|
|
54
55
|
x_adv, _ = plt.parse_wanted_names(regrid_file, "cf", "ecmwf", variables=compare)
|
|
55
56
|
assert x_adv == compare
|
|
56
57
|
|
|
57
58
|
|
|
58
|
-
def test_sort_model2first_element():
|
|
59
|
+
def test_sort_model2first_element() -> None:
|
|
59
60
|
a = ["ec_i", "cf_ec_i", "cf_ec_ii", "ec_ii"]
|
|
60
61
|
e = "ec"
|
|
61
62
|
compare = ["ec_i", "ec_ii", "cf_ec_i", "cf_ec_ii"]
|
|
@@ -63,7 +64,7 @@ def test_sort_model2first_element():
|
|
|
63
64
|
assert x == compare
|
|
64
65
|
|
|
65
66
|
|
|
66
|
-
def test_sort_cycles_vars():
|
|
67
|
+
def test_sort_cycles_vars() -> None:
|
|
67
68
|
a = ["era5_cf_1-12", "era5_cf_7-18", "cf_era5_1-12", "cf_era5_7-18"]
|
|
68
69
|
e = "era5"
|
|
69
70
|
compare = [
|
|
@@ -74,7 +75,7 @@ def test_sort_cycles_vars():
|
|
|
74
75
|
assert x == compare
|
|
75
76
|
|
|
76
77
|
|
|
77
|
-
def test_sort_cycles_simo():
|
|
78
|
+
def test_sort_cycles_simo() -> None:
|
|
78
79
|
a = ["era5_cf_1-12", "era5_cf_7-18", "cf_era5_1-12", "cf_era5_7-18"]
|
|
79
80
|
e = "era5"
|
|
80
81
|
compare = ["1-12", "7-18"]
|
|
@@ -82,7 +83,7 @@ def test_sort_cycles_simo():
|
|
|
82
83
|
assert y == compare
|
|
83
84
|
|
|
84
85
|
|
|
85
|
-
def test_sort_cycles_vars_missing():
|
|
86
|
+
def test_sort_cycles_vars_missing() -> None:
|
|
86
87
|
a = ["icon_cf_12-23", "icon_cf_36-47", "cf_icon_12-23", "cf_icon_36-47"]
|
|
87
88
|
e = "icon"
|
|
88
89
|
compare = [
|
|
@@ -93,7 +94,7 @@ def test_sort_cycles_vars_missing():
|
|
|
93
94
|
assert x == compare
|
|
94
95
|
|
|
95
96
|
|
|
96
|
-
def test_sort_cycles_cycles_missing():
|
|
97
|
+
def test_sort_cycles_cycles_missing() -> None:
|
|
97
98
|
a = ["icon_cf_12-23", "icon_cf_36-47", "cf_icon_12-23", "cf_icon_36-47"]
|
|
98
99
|
e = "icon"
|
|
99
100
|
compare = ["12-23", "36-47"]
|
|
@@ -101,7 +102,7 @@ def test_sort_cycles_cycles_missing():
|
|
|
101
102
|
assert y == compare
|
|
102
103
|
|
|
103
104
|
|
|
104
|
-
def test_read_data_characters(regrid_file):
|
|
105
|
+
def test_read_data_characters(regrid_file) -> None:
|
|
105
106
|
t = np.array([[2, 2], [6, 6], [10, 10]])
|
|
106
107
|
h = np.array([[0.01, 0.014], [0.008, 0.014], [0.009, 0.015]])
|
|
107
108
|
data = np.array([[0, 2], [3, 6], [5, 8]])
|
|
@@ -112,7 +113,7 @@ def test_read_data_characters(regrid_file):
|
|
|
112
113
|
testing.assert_array_almost_equal(compare[i], test[i])
|
|
113
114
|
|
|
114
115
|
|
|
115
|
-
def test_mask_small_values_lwc():
|
|
116
|
+
def test_mask_small_values_lwc() -> None:
|
|
116
117
|
name = "lwc_lol"
|
|
117
118
|
data = ma.array([[0, 1], [3, 6], [5, 8]])
|
|
118
119
|
data = plt.mask_small_values(data, name)
|
|
@@ -121,7 +122,7 @@ def test_mask_small_values_lwc():
|
|
|
121
122
|
testing.assert_array_almost_equal(data.mask, compare.mask)
|
|
122
123
|
|
|
123
124
|
|
|
124
|
-
def test_mask_small_values_lwc_mask():
|
|
125
|
+
def test_mask_small_values_lwc_mask() -> None:
|
|
125
126
|
name = "lwc_lol"
|
|
126
127
|
data = ma.array([[0, 0.000001], [3, 6], [5, 8]])
|
|
127
128
|
data = plt.mask_small_values(data, name)
|
|
@@ -131,7 +132,7 @@ def test_mask_small_values_lwc_mask():
|
|
|
131
132
|
testing.assert_array_almost_equal(data.mask, compare.mask)
|
|
132
133
|
|
|
133
134
|
|
|
134
|
-
def test_mask_small_values_iwc():
|
|
135
|
+
def test_mask_small_values_iwc() -> None:
|
|
135
136
|
name = "iwc_lol"
|
|
136
137
|
data = ma.array([[0, 1], [3, 6], [5, 8]])
|
|
137
138
|
data = plt.mask_small_values(data, name)
|
|
@@ -140,7 +141,7 @@ def test_mask_small_values_iwc():
|
|
|
140
141
|
testing.assert_array_almost_equal(data.mask, compare.mask)
|
|
141
142
|
|
|
142
143
|
|
|
143
|
-
def test_mask_small_values_iwc_mask():
|
|
144
|
+
def test_mask_small_values_iwc_mask() -> None:
|
|
144
145
|
name = "iwc_lol"
|
|
145
146
|
data = ma.array([[0, 0.00000001], [3, 6], [5, 8]])
|
|
146
147
|
data = plt.mask_small_values(data, name)
|
|
@@ -150,7 +151,7 @@ def test_mask_small_values_iwc_mask():
|
|
|
150
151
|
testing.assert_array_almost_equal(data.mask, compare.mask)
|
|
151
152
|
|
|
152
153
|
|
|
153
|
-
def test_mask_small_values():
|
|
154
|
+
def test_mask_small_values() -> None:
|
|
154
155
|
name = "cf_lol"
|
|
155
156
|
data = ma.array([[0, 1], [3, 6], [5, 8]])
|
|
156
157
|
data = plt.mask_small_values(data, name)
|
|
@@ -159,7 +160,7 @@ def test_mask_small_values():
|
|
|
159
160
|
testing.assert_array_almost_equal(data.mask, compare.mask)
|
|
160
161
|
|
|
161
162
|
|
|
162
|
-
def test_mask_small_values_mask():
|
|
163
|
+
def test_mask_small_values_mask() -> None:
|
|
163
164
|
name = "cf_lol"
|
|
164
165
|
data = ma.array([[0, -0.000001], [3, 6], [5, 8]])
|
|
165
166
|
data_mask = plt.mask_small_values(data, name)
|
|
@@ -169,7 +170,7 @@ def test_mask_small_values_mask():
|
|
|
169
170
|
testing.assert_array_equal(data_mask.mask, compare.mask)
|
|
170
171
|
|
|
171
172
|
|
|
172
|
-
def test_reshape_1d2nd():
|
|
173
|
+
def test_reshape_1d2nd() -> None:
|
|
173
174
|
oned = np.array([1, 2, 3, 4])
|
|
174
175
|
twod = np.array([[0, 0], [0, 0], [0, 0], [0, 0]])
|
|
175
176
|
compare = np.array([[1, 1], [2, 2], [3, 3], [4, 4]])
|
|
@@ -177,29 +178,31 @@ def test_reshape_1d2nd():
|
|
|
177
178
|
testing.assert_array_almost_equal(x, compare)
|
|
178
179
|
|
|
179
180
|
|
|
180
|
-
def test_create_segment_values():
|
|
181
|
+
def test_create_segment_values() -> None:
|
|
181
182
|
model_mask = np.array([[0, 1, 1, 0], [0, 0, 1, 0], [1, 0, 0, 0]], dtype=bool)
|
|
183
|
+
model = ma.array(np.ones(model_mask.shape), mask=model_mask)
|
|
182
184
|
obs_mask = np.array([[0, 0, 0, 0], [0, 0, 1, 0], [1, 0, 1, 1]], dtype=bool)
|
|
183
|
-
|
|
185
|
+
obs = ma.array(np.ones(obs_mask.shape), mask=obs_mask)
|
|
186
|
+
x = plt.create_segment_values(model, obs)
|
|
184
187
|
compare = np.array([[2, 3, 3, 2], [2, 2, 0, 2], [0, 2, 1, 1]])
|
|
185
188
|
testing.assert_array_almost_equal(x, compare)
|
|
186
189
|
|
|
187
190
|
|
|
188
|
-
def test_rolling_mean():
|
|
191
|
+
def test_rolling_mean() -> None:
|
|
189
192
|
data = np.ma.array([1, 2, 7, 4, 2, 3, 8, 5])
|
|
190
193
|
x = plt.rolling_mean(data, 2)
|
|
191
194
|
compare = np.array([1.5, 4.5, 5.5, 3, 2.5, 5.5, 6.5, 5])
|
|
192
195
|
testing.assert_array_almost_equal(x, compare)
|
|
193
196
|
|
|
194
197
|
|
|
195
|
-
def test_rolling_mean_nan():
|
|
198
|
+
def test_rolling_mean_nan() -> None:
|
|
196
199
|
data = np.ma.array([1, 2, np.nan, 4, 2, np.nan, 8, 5])
|
|
197
200
|
x = plt.rolling_mean(data, 2)
|
|
198
201
|
compare = np.array([1.5, 2, 4, 3, 2, 8, 6.5, 5])
|
|
199
202
|
testing.assert_array_almost_equal(x, compare)
|
|
200
203
|
|
|
201
204
|
|
|
202
|
-
def test_rolling_mean_mask():
|
|
205
|
+
def test_rolling_mean_mask() -> None:
|
|
203
206
|
data = np.ma.array([1, 2, 7, 4, 2, 3, 8, 5])
|
|
204
207
|
data.mask = np.array([0, 0, 1, 0, 1, 0, 0, 1])
|
|
205
208
|
x = plt.rolling_mean(data, 2)
|
|
@@ -207,7 +210,7 @@ def test_rolling_mean_mask():
|
|
|
207
210
|
testing.assert_array_almost_equal(x, compare)
|
|
208
211
|
|
|
209
212
|
|
|
210
|
-
def test_rolling_mean_all_mask():
|
|
213
|
+
def test_rolling_mean_all_mask() -> None:
|
|
211
214
|
data = np.ma.array([1, 2, 7, 4, 2, 3, 8, 5])
|
|
212
215
|
data.mask = np.array([0, 1, 1, 1, 1, 0, 0, 1])
|
|
213
216
|
x = plt.rolling_mean(data, 2)
|
|
@@ -215,16 +218,16 @@ def test_rolling_mean_all_mask():
|
|
|
215
218
|
testing.assert_array_almost_equal(x, compare)
|
|
216
219
|
|
|
217
220
|
|
|
218
|
-
def test_change2one_dim_axes_maskY():
|
|
221
|
+
def test_change2one_dim_axes_maskY() -> None:
|
|
219
222
|
x = np.ma.array(
|
|
220
|
-
[[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]]
|
|
223
|
+
[[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]],
|
|
221
224
|
)
|
|
222
225
|
y = np.ma.array(
|
|
223
|
-
[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
|
|
226
|
+
[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]],
|
|
224
227
|
)
|
|
225
228
|
y[1] = np.ma.masked
|
|
226
229
|
data = np.ma.array(
|
|
227
|
-
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
|
|
230
|
+
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]],
|
|
228
231
|
)
|
|
229
232
|
x, y, data = plt.change2one_dim_axes(x, y, data)
|
|
230
233
|
compare_x = np.array([1, 2, 3, 4])
|
|
@@ -233,16 +236,16 @@ def test_change2one_dim_axes_maskY():
|
|
|
233
236
|
testing.assert_array_almost_equal(y, compare_y)
|
|
234
237
|
|
|
235
238
|
|
|
236
|
-
def test_change2one_dim_axes_maskX():
|
|
239
|
+
def test_change2one_dim_axes_maskX() -> None:
|
|
237
240
|
x = np.ma.array(
|
|
238
|
-
[[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]]
|
|
241
|
+
[[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]],
|
|
239
242
|
)
|
|
240
243
|
y = np.ma.array(
|
|
241
|
-
[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
|
|
244
|
+
[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]],
|
|
242
245
|
)
|
|
243
246
|
x[1] = np.ma.masked
|
|
244
247
|
data = np.ma.array(
|
|
245
|
-
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
|
|
248
|
+
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]],
|
|
246
249
|
)
|
|
247
250
|
x, y, data = plt.change2one_dim_axes(x, y, data)
|
|
248
251
|
compare_x = np.array([1, 2, 3, 4])
|
|
@@ -251,17 +254,17 @@ def test_change2one_dim_axes_maskX():
|
|
|
251
254
|
testing.assert_array_almost_equal(y, compare_y)
|
|
252
255
|
|
|
253
256
|
|
|
254
|
-
def test_change2one_dim_axes():
|
|
257
|
+
def test_change2one_dim_axes() -> None:
|
|
255
258
|
x = np.ma.array(
|
|
256
|
-
[[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]]
|
|
259
|
+
[[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]],
|
|
257
260
|
)
|
|
258
261
|
compare_x = np.copy(x)
|
|
259
262
|
y = np.ma.array(
|
|
260
|
-
[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
|
|
263
|
+
[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]],
|
|
261
264
|
)
|
|
262
265
|
compare_y = np.copy(y)
|
|
263
266
|
data = np.ma.array(
|
|
264
|
-
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]
|
|
267
|
+
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]],
|
|
265
268
|
)
|
|
266
269
|
x, y, data = plt.change2one_dim_axes(x, y, data)
|
|
267
270
|
testing.assert_array_almost_equal(x, compare_x)
|