Skip to content

Commit 667889d

Browse files
committed
Adds tests for specific humidity and mixing ratio conversions
1 parent fabc933 commit 667889d

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed

tests/operators/test_humidity.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# © Crown copyright, Met Office (2022-2026) and CSET contributors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Test humidity operators."""
16+
17+
import cf_units
18+
import iris.cube
19+
import numpy as np
20+
21+
from CSET.operators import humidity
22+
23+
24+
def test_mixing_ratio_from_specific_humidity(specific_humidity_for_conversions_cube):
25+
"""Test calculation of mixing ratio from specific humidity."""
26+
expected_data = specific_humidity_for_conversions_cube / (
27+
1 - specific_humidity_for_conversions_cube
28+
)
29+
assert np.allclose(
30+
expected_data.data,
31+
humidity.mixing_ratio_from_specific_humidity(
32+
specific_humidity_for_conversions_cube
33+
).data,
34+
rtol=1e-6,
35+
atol=1e-2,
36+
)
37+
38+
39+
def test_mixing_ratio_from_specific_humidity_name(
40+
specific_humidity_for_conversions_cube,
41+
):
42+
"""Test naming of mixing ratio cube."""
43+
expected_name = "mixing_ratio"
44+
assert (
45+
expected_name
46+
== humidity.mixing_ratio_from_specific_humidity(
47+
specific_humidity_for_conversions_cube
48+
).name()
49+
)
50+
51+
52+
def test_mixing_ratio_from_specific_humidity_unit(
53+
specific_humidity_for_conversions_cube,
54+
):
55+
"""Test units for mixing ratio."""
56+
expected_units = cf_units.Unit("kg/kg")
57+
assert (
58+
expected_units
59+
== humidity.mixing_ratio_from_specific_humidity(
60+
specific_humidity_for_conversions_cube
61+
).units
62+
)
63+
64+
65+
def test_mixing_ratio_from_specific_humidity_cubelist(
66+
specific_humidity_for_conversions_cube,
67+
):
68+
"""Test calculation of mixing ratio from specific humidity for a CubeList."""
69+
expected_data = specific_humidity_for_conversions_cube / (
70+
1 - specific_humidity_for_conversions_cube
71+
)
72+
expected_list = iris.cube.CubeList([expected_data, expected_data])
73+
input_list = iris.cube.CubeList(
74+
[specific_humidity_for_conversions_cube, specific_humidity_for_conversions_cube]
75+
)
76+
actual_cubelist = humidity.mixing_ratio_from_specific_humidity(input_list)
77+
for cube_a, cube_b in zip(expected_list, actual_cubelist, strict=True):
78+
assert np.allclose(cube_a.data, cube_b.data, rtol=1e-6, atol=1e-2)
79+
80+
81+
def test_mixing_ratio_from_specific_humidity_using_calculated(
82+
mixing_ratio_for_conversions_cube,
83+
):
84+
"""Test mixing ratio calculation using calculated q from mixing ratio."""
85+
calculated_w = humidity.mixing_ratio_from_specific_humidity(
86+
humidity.specific_humidity_from_mixing_ratio(mixing_ratio_for_conversions_cube)
87+
)
88+
assert np.allclose(
89+
mixing_ratio_for_conversions_cube.data, calculated_w.data, rtol=1e-6, atol=1e-2
90+
)
91+
92+
93+
def test_specific_humidity_from_mixing_ratio(mixing_ratio_for_conversions_cube):
94+
"""Test specific humidity calculation from mixing ratio."""
95+
expected_data = mixing_ratio_for_conversions_cube / (
96+
1 + mixing_ratio_for_conversions_cube
97+
)
98+
assert np.allclose(
99+
expected_data.data,
100+
humidity.specific_humidity_from_mixing_ratio(
101+
mixing_ratio_for_conversions_cube
102+
).data,
103+
rtol=1e-6,
104+
atol=1e-2,
105+
)
106+
107+
108+
def test_specific_humidity_from_mixing_ratio_name(mixing_ratio_for_conversions_cube):
109+
"""Test specific humidity cube is named."""
110+
expected_name = "specific_humidity"
111+
assert (
112+
expected_name
113+
== humidity.specific_humidity_from_mixing_ratio(
114+
mixing_ratio_for_conversions_cube
115+
).name()
116+
)
117+
118+
119+
def test_specific_humidity_from_mixing_ratio_units(mixing_ratio_for_conversions_cube):
120+
"""Test units of specific humidity."""
121+
expected_units = cf_units.Unit("kg/kg")
122+
assert (
123+
expected_units
124+
== humidity.specific_humidity_from_mixing_ratio(
125+
mixing_ratio_for_conversions_cube
126+
).units
127+
)
128+
129+
130+
def test_specific_humidity_from_mixing_ratio_cubelist(
131+
mixing_ratio_for_conversions_cube,
132+
):
133+
"""Test specific humidity calculation from mixing ratio with a CuebList."""
134+
expected_data = mixing_ratio_for_conversions_cube / (
135+
1 + mixing_ratio_for_conversions_cube
136+
)
137+
expected_list = iris.cube.CubeList([expected_data, expected_data])
138+
input_list = iris.cube.CubeList(
139+
[mixing_ratio_for_conversions_cube, mixing_ratio_for_conversions_cube]
140+
)
141+
actual_cubelist = humidity.specific_humidity_from_mixing_ratio(input_list)
142+
for cube_a, cube_b in zip(expected_list, actual_cubelist, strict=True):
143+
assert np.allclose(cube_a.data, cube_b.data, rtol=1e-6, atol=1e-2)
144+
145+
146+
def test_specific_humidity_from_mixing_ratio_using_calculated(
147+
specific_humidity_for_conversions_cube,
148+
):
149+
"""Test specific humidity calculation using calculated w from specific humidity."""
150+
calculated_q = humidity.specific_humidity_from_mixing_ratio(
151+
humidity.mixing_ratio_from_specific_humidity(
152+
specific_humidity_for_conversions_cube
153+
)
154+
)
155+
assert np.allclose(
156+
specific_humidity_for_conversions_cube.data,
157+
calculated_q.data,
158+
rtol=1e-6,
159+
atol=1e-2,
160+
)

0 commit comments

Comments
 (0)