Merged
Conversation
New xrspatial.mcda subpackage with five modules: - standardize: value functions (linear, sigmoidal, gaussian, triangular, piecewise, categorical) - weights: AHP eigenvector method with consistency ratio, rank-order weighting (ROC, RS, RR) - combine: WLC, WPM, OWA, fuzzy overlay, boolean overlay - constrain: exclusion mask application - sensitivity: one-at-a-time perturbation and Monte Carlo CV analysis
69 tests covering standardize (all 6 methods + dask), AHP and rank weights, WLC/WPM/OWA/fuzzy/boolean combination, constraints, sensitivity analysis, and an end-to-end suitability workflow. Also fix nanmin/nanmax in linear standardize when bounds are not given.
Covers the full workflow: synthetic terrain criteria, all six standardization methods, AHP and rank-order weights, WLC/WPM/OWA/fuzzy combination, constraint masking, and sensitivity analysis with side-by-side method comparison plots.
Correctness: - Fix triangular degenerate cases (peak==low, peak==high, all equal) returning 0 instead of the correct one-sided triangle shape - Fix _get_xp returning cupy for dask+cupy arrays, which would pass dask arrays to cupy ops and fail or materialize full arrays - Fix dask+cupy map_blocks closures in categorical/piecewise using np.asarray to handle cupy chunks - Clamp sigmoidal exponent to [-500, 500] to prevent overflow warnings - Suppress RuntimeWarning from nanmin/nanmax on all-NaN input - Remove unused baseline variable in _oat sensitivity - Remove unused stacked.copy() in OWA Performance: - Monte Carlo sensitivity: compute dask criteria eagerly before the loop to prevent graph explosion (1000 iterations was creating 35,000+ chained graph tasks with no parallelism) - Fuse two separate dask.compute calls for nanmin/nanmax into one - Replace xr.where(a < b, a, b) with np.minimum in fuzzy and/or Tests: add 10 edge case tests (degenerate triangles, sigmoid overflow, all-NaN input, NaN propagation in WLC, OWA exact equality, dask MC).
Warn when AHP receives fewer than n(n-1)/2 pairwise comparisons, since missing pairs silently default to equal importance. 28 new tests covering: - Single-pixel rasters through all standardize methods and combine - NaN propagation through WLC, WPM, OWA, and all 5 fuzzy operators - Piecewise extrapolation outside breakpoint range - Categorical float precision (exact match only) and integer data - AHP incomplete comparison warning and no-warn for complete input - Mismatched coords producing NaN outside overlap region - Dask chunk alignment for standardize, WLC, fuzzy, and OAT sensitivity - WPM with all-ones and all-zeros - Constrain with empty exclude list and full exclusion
Input validation: - Raise on inverted bounds in linear standardize (lo > hi) - Raise on duplicate piecewise breakpoints - Raise on AHP self-comparisons, zero, and negative values - Raise when weights dict has keys not in criteria Dataset - Boolean overlay casts float input to bool instead of TypeError 25 new test classes / cases covering: - Inverted bounds, duplicate breakpoints, AHP validation - Extra weight keys, boolean overlay with float data - Inf values treated as NaN across all standardize methods - Sensitivity weight clamping to [0, 1] boundary - Monte Carlo reproducibility (same seed = same output) - Gaussian with very small std (delta function behavior) - OWA risk attitude ordering (conservative <= optimistic) - Rank weights with 20 criteria (sum, monotonicity) - Constant surface with no bounds returns 0.5 - Overlapping constraint masks
Fixes: - Single-criterion sensitivity: _perturb_weights returned weights summing to <1 when no other criteria exist to absorb the remainder. Now returns unmodified weights (perturbation is a no-op). - Duplicate criteria names in AHP and rank_weights: silently corrupted results by overwriting index mapping. Now raises ValueError. 16 new tests covering: - Single-criterion Dataset through WLC, WPM, OWA, all fuzzy operators - Boolean overlay NaN gotcha (bool(NaN)=True documented) - Sensitivity with single criterion (OAT and MC both zero) - Sensitivity with WPM combine method (OAT and MC) - AHP with 16 criteria (>15, _RI table fallback) - Duplicate criteria names in AHP and rank_weights - Constrain with integer mask - Monte Carlo with n_samples=1 (zero CV) - 3D DataArray input (band, y, x)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #
Proposed Changes