Skip to content

Reject NaN/Inf weights in mcda combine and ahp_weights (#1311)#1312

Merged
brendancol merged 2 commits intomainfrom
issue-1311
Apr 29, 2026
Merged

Reject NaN/Inf weights in mcda combine and ahp_weights (#1311)#1312
brendancol merged 2 commits intomainfrom
issue-1311

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Summary

Closes #1311.

_validate_weights and owa()'s order-weights check only verified that weights summed to about 1.0. Since abs(NaN - 1.0) > 0.01 is False, a NaN weight slipped past the check, hit every pixel, and the function happily returned an all-NaN raster with no exception. ahp_weights has the same problem one level down: its if val <= 0: guard lets NaN through into the comparison matrix, and the eigenvector solve produces NaN weights from there.

Changes

  • xrspatial/mcda/combine.py: added _check_finite_weights and called it from _validate_weights. Same idea applied per-position to order_weights in owa(). Error messages name the offending criterion or list index.
  • xrspatial/mcda/weights.py: ahp_weights rejects NaN/Inf comparison values before the existing val <= 0 check.
  • xrspatial/tests/test_mcda.py: 18 new tests for NaN/Inf in wlc, wpm, owa (criterion weights and order weights), and ahp_weights. A few positive-path tests too, to make sure the new check doesn't break valid inputs.

All 166 mcda tests pass.

Test plan

Notes

One fix per PR, per the security-sweep convention. The mcda audit also turned up some MEDIUM items that aren't fixed here: sensitivity._monte_carlo eagerly computing the full dask Dataset, combine.owa stacking criteria via xr.concat without a size guard, n_samples=0 divides by zero, and wpm will accept zero-base/negative-weight combinations. Those are recorded in .claude/sweep-security-state.csv for follow-up.

_validate_weights and the owa() order_weights check only verified that
weights summed to ~1.0. Because abs(NaN - 1.0) > 0.01 is False, a NaN
weight passed validation, propagated through every pixel, and returned
an all-NaN raster with no exception. ahp_weights had the same shape of
bug: its `if val <= 0:` guard let NaN slip into the comparison matrix,
producing NaN weights from the eigenvector solve.

Add explicit np.isfinite checks before the sum-to-1 check in
_validate_weights, mirror the same sweep over order_weights inside owa,
and extend the ahp_weights value guard to reject NaN/Inf comparisons.
Errors name the offending criterion or position.

Also record the mcda security audit row in
.claude/sweep-security-state.csv.
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label Apr 29, 2026
@brendancol
Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Co-authored-by: brendancol <433221+brendancol@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 29, 2026

@copilot resolve the merge conflicts in this pull request

Merge conflicts resolved in commit 0b8df8e. Merged origin/main (which included the TIFF predictor-3 fix, kriging guard, and surface-distance guard) cleanly into the branch — no conflicts in the mcda files.

@brendancol brendancol merged commit 9cbc4e4 into main Apr 29, 2026
1 check was pending
brendancol added a commit that referenced this pull request Apr 30, 2026
`wpm` computes `prod(x_i ** w_i)`, which is undefined for `x_i <= 0`
when `w_i` is non-integer. A zero base collapses the product to zero
and masks upstream standardization bugs; a negative base produces NaN
with no warning. The function docstring claimed inputs should be
standardized 0-1 but no runtime check enforced it.

Add `_check_wpm_positive` to scan each criterion's data and raise
`ValueError` naming any variable whose minimum is `<= 0`. NaN values
still propagate, preserving the documented behaviour exercised by
`test_wpm_nan`. Update the existing zero/all-zero tests to assert the
new error and add three more tests covering negative inputs, error
text, and the positive-path baseline.

Sibling Cat 3 follow-up to #1311 / #1312.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wlc/wpm/owa/ahp_weights silently propagate NaN weights to all-NaN raster

2 participants