Skip to content

Commit a8d360d

Browse files
authored
Fix false CMIP7 QC failures at closed-range boundaries (#495)
* Fix CMIP7 QC boundary tolerance for float32 noise * pre-commit
1 parent 52501b8 commit a8d360d

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

src/access_moppy/qc/cmip7.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ def _is_outside_allowed_range(observed: float, minimum: float, maximum: float) -
9393
``-6e-24`` are treated as zero for a lower bound of ``0``.
9494
"""
9595

96-
tolerance = 1e-12
96+
# Many CMIP outputs are derived from float32 fields where boundary values
97+
# (for example 100%) can round to slightly above/below the nominal limit.
98+
# Use a scale-aware absolute tolerance so closed-interval checks remain
99+
# robust without masking meaningfully out-of-range values.
100+
scale = max(abs(observed), abs(minimum), abs(maximum), 1.0)
101+
tolerance = max(1e-12, 8.0 * np.finfo(np.float32).eps * scale)
97102
lower_violation = observed < minimum and not np.isclose(
98103
observed, minimum, rtol=0.0, atol=tolerance
99104
)

tests/unit/test_cmip7_qc.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,21 @@ def test_validate_cmip7_output_allows_tiny_negative_noise_at_zero_bound(tmp_path
178178
validate_cmip7_output(path)
179179

180180

181+
@pytest.mark.unit
182+
def test_validate_cmip7_output_allows_float32_boundary_noise_for_percent_range(
183+
tmp_path,
184+
):
185+
path = _write_cmip7_output(
186+
tmp_path,
187+
values=[0.0, 100.00003],
188+
experiment_id="historical",
189+
variable_id="snc",
190+
units="%",
191+
)
192+
193+
validate_cmip7_output(path)
194+
195+
181196
@pytest.mark.unit
182197
def test_validate_cmip7_output_tas_fails_for_picontrol_range(tmp_path):
183198
path = _write_cmip7_output(

0 commit comments

Comments
 (0)