Skip to content

Commit 36de2be

Browse files
manugvsoxofaan
authored andcommitted
Added acceptable pixel tolerances feature for testing.
1 parent 05a132c commit 36de2be

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

openeo/testing/results.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020

2121
_DEFAULT_RTOL = 1e-6
2222
_DEFAULT_ATOL = 1e-6
23+
_DEFAULT_PXTOL = 0.0
2324

2425
# https://paulbourke.net/dataformats/asciiart
2526
DEFAULT_GRAYSCALE_70_CHARACTERS = r"$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "[::-1]
2627
DEFAULT_GRAYSCALE_10_CHARACTERS = " .:-=+*#%@"
2728

29+
2830
def _load_xarray_netcdf(path: Union[str, Path], **kwargs) -> xarray.Dataset:
2931
"""
3032
Load a netCDF file as Xarray Dataset
@@ -194,10 +196,11 @@ def _compare_xarray_dataarray(
194196
*,
195197
rtol: float = _DEFAULT_RTOL,
196198
atol: float = _DEFAULT_ATOL,
199+
pxtol: Optional[float] = _DEFAULT_PXTOL,
197200
name: str = None,
198201
) -> List[str]:
199202
"""
200-
Compare two xarray DataArrays with tolerance and report mismatch issues (as strings)
203+
Compare two xarray DataArrays either with tolerance or with allowable pixels and report mismatch issues (as strings)
201204
202205
Checks that are done (with tolerance):
203206
- (optional) Check fraction of mismatching pixels (difference exceeding some tolerance).
@@ -230,7 +233,12 @@ def _compare_xarray_dataarray(
230233
issues.append(f"Shape mismatch: {actual.shape} != {expected.shape}")
231234
compatible = len(issues) == 0
232235
try:
233-
xarray.testing.assert_allclose(a=actual, b=expected, rtol=rtol, atol=atol)
236+
if pxtol > _DEFAULT_PXTOL:
237+
assert (
238+
actual != expected
239+
).mean().item() <= pxtol, "Percentage number of pixels that are different is above the threshold"
240+
else:
241+
xarray.testing.assert_allclose(a=actual, b=expected, rtol=rtol, atol=atol)
234242
except AssertionError as e:
235243
# TODO: message of `assert_allclose` is typically multiline, split it again or make it one line?
236244
issues.append(str(e).strip())
@@ -266,12 +274,14 @@ def assert_xarray_dataarray_allclose(
266274
if issues:
267275
raise AssertionError("\n".join(issues))
268276

277+
269278
def _compare_xarray_datasets(
270279
actual: Union[xarray.Dataset, str, Path],
271280
expected: Union[xarray.Dataset, str, Path],
272281
*,
273282
rtol: float = _DEFAULT_RTOL,
274283
atol: float = _DEFAULT_ATOL,
284+
pxtol: Optional[float] = _DEFAULT_PXTOL,
275285
) -> List[str]:
276286
"""
277287
Compare two xarray ``DataSet``s with tolerance and report mismatch issues (as strings)
@@ -290,7 +300,7 @@ def _compare_xarray_datasets(
290300
all_issues.append(f"Xarray DataSet variables mismatch: {actual_vars} != {expected_vars}")
291301
for var in expected_vars.intersection(actual_vars):
292302
_log.debug(f"_compare_xarray_datasets: comparing variable {var!r}")
293-
issues = _compare_xarray_dataarray(actual[var], expected[var], rtol=rtol, atol=atol, name=var)
303+
issues = _compare_xarray_dataarray(actual[var], expected[var], rtol=rtol, atol=atol, pxtol=pxtol, name=var)
294304
if issues:
295305
all_issues.append(f"Issues for variable {var!r}:")
296306
all_issues.extend(issues)
@@ -387,6 +397,7 @@ def _compare_job_results(
387397
*,
388398
rtol: float = _DEFAULT_RTOL,
389399
atol: float = _DEFAULT_ATOL,
400+
pxtol: Optional[float] = _DEFAULT_PXTOL,
390401
tmp_path: Optional[Path] = None,
391402
) -> List[str]:
392403
"""
@@ -415,12 +426,16 @@ def _compare_job_results(
415426
all_issues.append(f"Issues for metadata file {filename!r}:")
416427
all_issues.extend(issues)
417428
elif expected_path.suffix.lower() in {".nc", ".netcdf"}:
418-
issues = _compare_xarray_datasets(actual=actual_path, expected=expected_path, rtol=rtol, atol=atol)
429+
issues = _compare_xarray_datasets(
430+
actual=actual_path, expected=expected_path, rtol=rtol, atol=atol, pxtol=pxtol
431+
)
419432
if issues:
420433
all_issues.append(f"Issues for file {filename!r}:")
421434
all_issues.extend(issues)
422435
elif expected_path.suffix.lower() in {".tif", ".tiff", ".gtiff", ".geotiff"}:
423-
issues = _compare_xarray_dataarray(actual=actual_path, expected=expected_path, rtol=rtol, atol=atol)
436+
issues = _compare_xarray_dataarray(
437+
actual=actual_path, expected=expected_path, rtol=rtol, atol=atol, pxtol=pxtol
438+
)
424439
if issues:
425440
all_issues.append(f"Issues for file {filename!r}:")
426441
all_issues.extend(issues)
@@ -463,6 +478,7 @@ def assert_job_results_allclose(
463478
*,
464479
rtol: float = _DEFAULT_RTOL,
465480
atol: float = _DEFAULT_ATOL,
481+
pxtol: Optional[float] = _DEFAULT_PXTOL,
466482
tmp_path: Optional[Path] = None,
467483
):
468484
"""
@@ -474,6 +490,7 @@ def assert_job_results_allclose(
474490
:py:meth:`~openeo.rest.job.JobResults` object or path to directory with downloaded assets.
475491
:param rtol: relative tolerance
476492
:param atol: absolute tolerance
493+
:param pxtol: allowable tolerance for the number of pixels in percentage
477494
:param tmp_path: root temp path to download results if needed.
478495
It's recommended to pass pytest's `tmp_path` fixture here
479496
:raises AssertionError: if not equal within the given tolerance
@@ -483,6 +500,6 @@ def assert_job_results_allclose(
483500
.. warning::
484501
This function is experimental and subject to change.
485502
"""
486-
issues = _compare_job_results(actual, expected, rtol=rtol, atol=atol, tmp_path=tmp_path)
503+
issues = _compare_job_results(actual, expected, rtol=rtol, atol=atol, pxtol=pxtol, tmp_path=tmp_path)
487504
if issues:
488505
raise AssertionError("\n".join(issues))

0 commit comments

Comments
 (0)