Skip to content

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

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

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

Conversation

@brendancol
Copy link
Copy Markdown
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
@brendancol brendancol deleted the more-hydrology branch May 4, 2026 13:06
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