Skip to content

Add D-inf and MFD variants of flow_path, watershed, and HAND#1020

Merged
brendancol merged 6 commits intomasterfrom
more-hydrology
Mar 17, 2026
Merged

Add D-inf and MFD variants of flow_path, watershed, and HAND#1020
brendancol merged 6 commits intomasterfrom
more-hydrology

Conversation

@brendancol
Copy link
Contributor

@brendancol brendancol commented Mar 16, 2026

Summary

Each module supports all four backends (numpy, cupy, dask, dask+cupy) and follows the same architecture as the existing D8 implementations. The D-inf variants use angle decomposition from _angle_to_neighbors; the MFD variants follow the highest-fraction neighbor at each step.

Six new modules, 84 new tests, all passing. No changes to existing modules or tests.

Test plan

  • 84 new tests pass across all 6 modules (pytest xrspatial/tests/test_{flow_path,watershed,hand}_{dinf,mfd}.py)
  • 55 existing tests for flow_path, watershed, and HAND still pass
  • Verify dask cross-tile propagation on larger grids
  • GPU backend validation (cupy, dask+cupy) on hardware with CUDA

Closes #1014, closes #1015, closes #1016, closes #1017, closes #1018, closes #1019

Implements six new hydrology modules, each with four backends
(numpy, cupy, dask, dask+cupy) and full test coverage:

- flow_path_dinf: D-inf flow path tracing (dominant neighbor)
- flow_path_mfd: MFD flow path tracing (dominant neighbor)
- watershed_dinf: D-inf watershed delineation
- watershed_mfd: MFD watershed delineation
- hand_dinf: D-inf Height Above Nearest Drainage
- hand_mfd: MFD Height Above Nearest Drainage

Closes #1014, closes #1015, closes #1016, closes #1017,
closes #1018, closes #1019
@github-actions github-actions bot added the performance PR touches performance-sensitive code label Mar 16, 2026
Moves 30 hydrology source modules and 30 test files into
xrspatial/hydrology/ and xrspatial/hydrology/tests/ respectively.
Also moves _boundary_store.py which is used exclusively by
hydrology code.

All internal cross-references updated. Top-level imports
(from xrspatial import flow_direction, etc.) still work via
xrspatial/__init__.py re-exports. The new xrspatial.hydrology
subpackage also provides direct access (from xrspatial.hydrology
import flow_direction).

457 hydrology tests pass, 2050 non-hydrology tests pass.
Rename all 13 unsuffixed D8 source files and their test files to
include a _d8 suffix (e.g. flow_direction.py -> flow_direction_d8.py),
matching the existing _dinf/_mfd convention.

Public functions inside each file are also renamed (flow_direction ->
flow_direction_d8, etc.). stream_order_d8's "method" parameter
(strahler/shreve) is renamed to "ordering" to avoid collision with the
routing dispatch.

hydro/__init__.py now provides unified wrappers via _RoutingDispatch,
so callers can do flow_direction(dem, routing='dinf') instead of
importing flow_direction_dinf directly. D8-only functions (basin, sink,
fill, twi, snap_pour_point) accept routing= for forward compatibility.

All cross-module imports, dinf/mfd helper imports, test imports, and
example imports are updated accordingly.
The cross-backend tests parametrize size and dtype for the random_data
fixture but the test functions didn't declare those parameters,
causing pytest collection to fail.
The random_data fixture lives in xrspatial/tests/conftest.py, which
pytest can't discover from xrspatial/hydro/tests/. Re-export it so
the flow_direction cross-backend parametrized tests can find it.
@brendancol brendancol merged commit 14113bc into master Mar 17, 2026
11 checks passed
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

1 participant