Skip to content

Commit c802190

Browse files
brhooperbayliffe
andauthored
Add acceptance tests for SAMOS CLIs where nothing should be returned (#2219)
* Add null return to CLIs is no gams have been found. * Add handling for rolling window calculations returning NaN for all values due to having insufficient input data. * Improve test doc-string. * Add acceptance tests for SAMOS estimation CLIs for occasions where nothing should be returned. Improve doc-string. * Update acceptance test doc-strings following review. * Fix acceptance tests for EMOS and SAMOS which were incorrectly checking for no output. --------- Co-authored-by: bayliffe <[email protected]>
1 parent 2dd65b3 commit c802190

File tree

6 files changed

+208
-2
lines changed

6 files changed

+208
-2
lines changed

improver/calibration/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ def split_cubes_for_samos(
391391
cubes. If False, an error will be raised if any such cubes are found.
392392
393393
Raises:
394+
IOError:
395+
If no forecast cube is found and/or no truth cube is found when a
396+
truth_attribute has been provided.
394397
IOError:
395398
If EMOS coefficients cubes are found when they are not expected.
396399
IOError:

improver_tests/acceptance/test_estimate_emos_coefficients_from_table.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,6 @@ def test_return_none(tmp_path):
176176
"--output",
177177
output_path,
178178
]
179-
assert run_cli(args) is None
179+
run_cli(args)
180+
# Check no file has been written to disk.
181+
assert not output_path.exists()

improver_tests/acceptance/test_estimate_samos_coefficients.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,31 @@ def test_estimate_samos_coefficients_sites(tmp_path):
138138
acc.compare(
139139
output_path, kgo_path, atol=COMPARE_EMOS_TOLERANCE, rtol=COMPARE_EMOS_TOLERANCE
140140
)
141+
142+
143+
def test_estimate_samos_coefficients_no_gam(tmp_path):
144+
"""
145+
Test estimate-samos-coefficients when no GAM is provided. The CLI should return
146+
None in this instance.
147+
"""
148+
# The source data is from the estimate-emos-coefficients acceptance tests
149+
source_emos_dir = acc.kgo_root() / "estimate-emos-coefficients/normal/sites"
150+
history_path = source_emos_dir / "history/*.nc"
151+
truth_path = source_emos_dir / "truth/*.nc"
152+
153+
output_path = tmp_path / "output.nc"
154+
gam_features = "latitude,longitude,height"
155+
156+
args = [
157+
history_path,
158+
truth_path,
159+
"--truth-attribute",
160+
"mosg__model_configuration=uk_det",
161+
"--gam-features",
162+
gam_features,
163+
"--output",
164+
output_path,
165+
]
166+
run_cli(args)
167+
# Check no file has been written to disk.
168+
assert not output_path.exists()

improver_tests/acceptance/test_estimate_samos_coefficients_from_table.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,40 @@ def test_additional_gam_features_cube(tmp_path):
114114
)
115115

116116

117+
@pytest.mark.slow
118+
def test_no_gam(tmp_path):
119+
"""
120+
Test estimate-samos-coefficients-from-table when no GAM is provided. The CLI should
121+
return None in this instance.
122+
"""
123+
source_dir = acc.kgo_root() / "estimate-emos-coefficients-from-table/"
124+
history_path = source_dir / "forecast_table"
125+
truth_path = source_dir / "truth_table"
126+
127+
output_path = tmp_path / "output.nc"
128+
129+
compulsory_args = [history_path, truth_path]
130+
named_args = [
131+
"--gam-features",
132+
"latitude,longitude,altitude",
133+
"--percentiles",
134+
"10,20,30,40,50,60,70,80,90",
135+
"--forecast-period",
136+
"86400",
137+
"--training-length",
138+
"5",
139+
"--diagnostic",
140+
"temperature_at_screen_level",
141+
"--cycletime",
142+
"20210805T2100Z",
143+
"--output",
144+
output_path,
145+
]
146+
run_cli(compulsory_args + named_args)
147+
# Check no file has been written to disk.
148+
assert not output_path.exists()
149+
150+
117151
@pytest.mark.slow
118152
def test_return_none(tmp_path):
119153
"""
@@ -144,4 +178,6 @@ def test_return_none(tmp_path):
144178
"--output",
145179
output_path,
146180
]
147-
assert run_cli(compulsory_args + named_args) is None
181+
run_cli(compulsory_args + named_args)
182+
# Check no file has been written to disk.
183+
assert not output_path.exists()

improver_tests/acceptance/test_estimate_samos_gams.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,45 @@ def test_gam_at_sites(tmp_path):
146146
# pickled objects are the same, not the actual objects as
147147
# there is no function to compare the GAM class objects.
148148
acc.compare(output_path, kgo_path, file_type="generic_pickle")
149+
150+
151+
def test_insufficient_data(tmp_path):
152+
"""
153+
Test estimate-samos-gams returns None when insufficient data is available at all
154+
sites.
155+
156+
This test provides 3 days of input data but uses a window length of 11 days. This
157+
will cause the training data at all sites to be considered insufficient to fit the
158+
GAMs (at least 50% of the possible data points are required). Hence, None should be
159+
returned.
160+
"""
161+
source_emos_dir = acc.kgo_root() / "estimate-emos-coefficients/normal/sites"
162+
history_path = source_emos_dir / "history/*.nc"
163+
truth_path = source_emos_dir / "truth/*.nc"
164+
165+
kgo_dir = acc.kgo_root() / "estimate-samos-gam"
166+
model_specification_path = kgo_dir / "samos_model_spec_simple.json"
167+
output_path = tmp_path / "output.pkl"
168+
169+
gam_features = "latitude,longitude,height"
170+
args = [
171+
history_path,
172+
truth_path,
173+
"--distribution",
174+
"normal",
175+
"--truth-attribute",
176+
"mosg__model_configuration=uk_det",
177+
"--tolerance",
178+
TOLERANCE,
179+
"--gam-features",
180+
gam_features,
181+
"--model-specification",
182+
model_specification_path,
183+
"--window-length",
184+
"11",
185+
"--output",
186+
output_path,
187+
]
188+
run_cli(args)
189+
# Check no file has been written to disk.
190+
assert not output_path.exists()

improver_tests/acceptance/test_estimate_samos_gams_from_table.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,98 @@ def test_additional_features_cubes(
173173
# pickled objects are the same, not the actual objects as
174174
# there is no function to compare the GAM class objects.
175175
acc.compare(output_path, kgo_path, file_type="generic_pickle")
176+
177+
178+
@pytest.mark.slow
179+
def test_no_forecast(
180+
tmp_path,
181+
):
182+
"""
183+
Test estimate-samos-gams-from-table returns None when no forecast data is available
184+
for the given leadtime in the given table.
185+
"""
186+
source_dir = acc.kgo_root() / "estimate-emos-coefficients-from-table/"
187+
history_path = source_dir / "forecast_table"
188+
truth_path = source_dir / "truth_table"
189+
190+
kgo_dir = acc.kgo_root() / "estimate-samos-gams-from-table/"
191+
192+
output_path = tmp_path / "output.pkl"
193+
compulsory_args = [history_path, truth_path]
194+
named_args = [
195+
"--diagnostic",
196+
"temperature_at_screen_level",
197+
"--cycletime",
198+
"20210805T2100Z",
199+
"--forecast-period",
200+
"3600000",
201+
"--training-length",
202+
"5",
203+
"--distribution",
204+
"normal",
205+
"--tolerance",
206+
"1e-4",
207+
"--gam-features",
208+
"latitude,longitude,altitude",
209+
"--model-specification",
210+
kgo_dir / "samos_model_spec_simple.json",
211+
"--percentiles",
212+
"10,20,30,40,50,60,70,80,90",
213+
"--window-length",
214+
"3",
215+
"--output",
216+
output_path,
217+
]
218+
run_cli(compulsory_args + named_args)
219+
# Check no file has been written to disk.
220+
assert not output_path.exists()
221+
222+
223+
@pytest.mark.slow
224+
def test_insufficient_data(
225+
tmp_path,
226+
):
227+
"""
228+
Test estimate-samos-gams-from-table returns None when insufficient data is
229+
available at all sites.
230+
231+
This test provides 3 days of input data but uses a window length of 11 days. This
232+
will cause the training data at all sites to be considered insufficient to fit the
233+
GAMs (at least 50% of the possible data points are required). Hence, None should be
234+
returned.
235+
"""
236+
source_dir = acc.kgo_root() / "estimate-emos-coefficients-from-table/"
237+
history_path = source_dir / "forecast_table"
238+
truth_path = source_dir / "truth_table"
239+
240+
kgo_dir = acc.kgo_root() / "estimate-samos-gams-from-table/"
241+
242+
output_path = tmp_path / "output.pkl"
243+
compulsory_args = [history_path, truth_path]
244+
named_args = [
245+
"--diagnostic",
246+
"temperature_at_screen_level",
247+
"--cycletime",
248+
"20210805T2100Z",
249+
"--forecast-period",
250+
"86400",
251+
"--training-length",
252+
"5",
253+
"--distribution",
254+
"normal",
255+
"--tolerance",
256+
"1e-4",
257+
"--gam-features",
258+
"latitude,longitude,altitude",
259+
"--model-specification",
260+
kgo_dir / "samos_model_spec_simple.json",
261+
"--percentiles",
262+
"10,20,30,40,50,60,70,80,90",
263+
"--window-length",
264+
"11",
265+
"--output",
266+
output_path,
267+
]
268+
run_cli(compulsory_args + named_args)
269+
# Check no file has been written to disk.
270+
assert not output_path.exists()

0 commit comments

Comments
 (0)