Coverage for tests/probabilty/test_functions.py: 100%
55 statements
« prev ^ index » next coverage.py v7.3.2, created at 2024-02-28 12:51 +1100
« prev ^ index » next coverage.py v7.3.2, created at 2024-02-28 12:51 +1100
1"""
2This module contains unit tests for scores.probability.functions
3"""
4import numpy as np
5import pytest
6import xarray as xr
8import scores.probability.checks
9import scores.probability.functions
10from tests import assertions
11from tests.probabilty import cdf_test_data, crps_test_data
12from tests.probabilty import functions_test_data as ftd
15def test_round_values_exception():
16 """Test rounding throws the right exceptions"""
17 with pytest.raises(ValueError):
18 scores.probability.functions.round_values(xr.DataArray(), -1, 5)
21@pytest.mark.parametrize(
22 ("array", "rounding_precision", "expected"),
23 [
24 (ftd.DA_ROUND, 0, ftd.EXP_ROUND1),
25 (ftd.DA_ROUND, 0.2, ftd.EXP_ROUND2),
26 (ftd.DA_ROUND, 5, ftd.EXP_ROUND3),
27 ],
28)
29def test_round_values(array, rounding_precision, expected):
30 """Tests `round_values` with a variety of inputs."""
31 output_as = scores.probability.functions.round_values(array, rounding_precision)
32 assertions.assert_dataarray_equal(output_as, expected, decimals=7)
35def test_propagate_nan_error():
36 """Test propagating throws the right exceptions"""
37 faulty_array = xr.Dataset({"lertitude": [1, 2, np.NaN, 4], "longitude": [20, 21, 22, 23, 24]})
38 with pytest.raises(ValueError):
39 scores.probability.functions.propagate_nan(faulty_array, "latitude")
42@pytest.mark.parametrize(
43 ("dim", "expected"),
44 [
45 ("x", cdf_test_data.EXP_PROPNAN_X),
46 ("y", cdf_test_data.EXP_PROPNAN_Y),
47 ],
48)
49def test_propagate_nan(dim, expected):
50 """Tests `propagate_nan` with a variety of inputs."""
51 result = scores.probability.functions.propagate_nan(cdf_test_data.DA_PROPNAN, dim)
52 assertions.assert_dataarray_equal(result, expected, decimals=7)
55def test_observed_cdf_errors():
56 """Test `osbserved_cdf_errors` with a variety of inputs."""
57 obs = xr.DataArray.from_dict({"dims": "temp", "data": [np.NaN, np.NaN, np.NaN, np.NaN]})
58 threshold_dim = "irrelevant for test"
59 threshold_values = None
60 badprecision = -1
62 # Bad precision raises a value error
63 with pytest.raises(ValueError):
64 scores.probability.functions.observed_cdf(obs, threshold_dim, threshold_values, precision=badprecision)
66 # Null obs and a null threshold value raises a value error
67 with pytest.raises(ValueError):
68 scores.probability.functions.observed_cdf(obs, threshold_dim, threshold_values)
71@pytest.mark.parametrize(
72 ("function_values", "expected"),
73 [
74 (crps_test_data.DA_ISPL1, crps_test_data.EXP_ISPL1),
75 (crps_test_data.DA_ISPL2, crps_test_data.EXP_ISPL2),
76 (crps_test_data.DA_ISPL3, crps_test_data.EXP_ISPL3),
77 ],
78)
79def test_integrate_square_piecewise_linear(function_values, expected):
80 """Tests `integrate_square_piecewise_linear` with a variety of inputs."""
81 result = scores.probability.functions.integrate_square_piecewise_linear(function_values, "x")
82 assertions.assert_dataarray_equal(result, expected, decimals=7)
85@pytest.mark.parametrize(
86 ("method", "min_nonnan", "expected"),
87 [
88 ("linear", 2, cdf_test_data.EXP_FILL_CDF1A),
89 ("step", 1, cdf_test_data.EXP_FILL_CDF1B),
90 ("step", 2, cdf_test_data.EXP_FILL_CDF1C),
91 ("forward", 1, cdf_test_data.EXP_FILL_CDF1D),
92 ("backward", 1, cdf_test_data.EXP_FILL_CDF1E),
93 ],
94)
95def test_fill_cdf(method, min_nonnan, expected):
96 """Tests `fill_cdf` with a variety of inputs."""
97 output = scores.probability.functions.fill_cdf(cdf_test_data.DA_FILL_CDF1, "x", method, min_nonnan)
98 assertions.assert_dataarray_equal(output, expected, decimals=7)
101@pytest.mark.parametrize(
102 (
103 "cdf",
104 "threshold_dim",
105 "method",
106 "min_nonnan",
107 "error_class",
108 "error_msg_snippet",
109 ),
110 [
111 ( # cdf values outside [0,1]
112 cdf_test_data.DA_CDF_FROM_QUANTS4,
113 "q_level",
114 "linear",
115 2,
116 ValueError,
117 "Input CDF has some values less than 0 or greater than 1.",
118 ),
119 (
120 cdf_test_data.DA_FILL_CDF1,
121 "y",
122 "linear",
123 2,
124 ValueError,
125 "'y' is not a dimension of `cdf`",
126 ),
127 (
128 cdf_test_data.DA_FILL_CDF1,
129 "x",
130 "linear",
131 1,
132 ValueError,
133 "`min_nonnan` must be at least 2 when `method='linear'`",
134 ),
135 (
136 cdf_test_data.DA_FILL_CDF1,
137 "x",
138 "step",
139 0,
140 ValueError,
141 "`min_nonnan` must be at least 1 when `method='step'`",
142 ),
143 (
144 cdf_test_data.DA_FILL_CDF1,
145 "x",
146 "quad",
147 0,
148 ValueError,
149 "`method` must be 'linear', 'step', 'forward' or 'backward'",
150 ),
151 ],
152)
153# pylint: disable=too-many-arguments
154def test_fill_cdf_raises(cdf, threshold_dim, method, min_nonnan, error_class, error_msg_snippet):
155 """`fill_cdf` raises an exception as expected."""
156 with pytest.raises(error_class, match=error_msg_snippet):
157 scores.probability.functions.fill_cdf(
158 cdf,
159 threshold_dim,
160 method,
161 min_nonnan,
162 )
165@pytest.mark.parametrize(
166 (
167 "cdf",
168 "threshold_dim",
169 "tolerance",
170 "error_msg_snippet",
171 ),
172 [
173 (
174 cdf_test_data.DA_DECREASING_CDFS1,
175 "y",
176 0,
177 "'y' is not a dimension of `cdf`",
178 ),
179 (
180 cdf_test_data.DA_DECREASING_CDFS1,
181 "x",
182 -1,
183 "`tolerance` must be nonnegative.",
184 ),
185 (
186 cdf_test_data.DA_CDF_ENVELOPE2,
187 "y",
188 0,
189 "'y' is not a dimension of `cdf`",
190 ),
191 (
192 cdf_test_data.DA_CDF_ENVELOPE1,
193 "x",
194 0,
195 "CDFs should have no NaNs or be all NaN along `threshold_dim`",
196 ),
197 (
198 cdf_test_data.DA_NAN_DECREASING_CDFS2,
199 "x",
200 0,
201 "Coordinates along 'x' dimension should be increasing.",
202 ),
203 ],
204)
205def test_check_nan_decreasing_inputs(cdf, threshold_dim, tolerance, error_msg_snippet):
206 """Tests that `_check_nan_decreasing_inputs` raises an exception as expected."""
207 with pytest.raises(ValueError, match=error_msg_snippet):
208 scores.probability.checks.check_nan_decreasing_inputs(cdf, threshold_dim, tolerance)
211@pytest.mark.parametrize(
212 ("cdf"),
213 [
214 (cdf_test_data.DA_CDF_ENVELOPE1),
215 (cdf_test_data.DA_CDF_ENVELOPE2),
216 ],
217)
218def test_cdf_envelope(cdf):
219 """Tests `cdf_envelope` with a variety of inputs."""
220 result = scores.probability.functions.cdf_envelope(cdf, "x")
221 assertions.assert_dataarray_equal(result, cdf_test_data.EXP_CDF_ENVELOPE1, decimals=7)
224def test_cdf_envelope_raises():
225 """Tests that `cdf_envelope` raises the correct error."""
226 with pytest.raises(ValueError, match="'y' is not a dimension of `cdf`"):
227 scores.probability.functions.cdf_envelope(cdf_test_data.DA_CDF_ENVELOPE1, "y")