Skip to content

weights for flow accumulation #3734

Description

@jkingslake

Reason or Problem

flow_accumulation only computes a count of upstream cells draining through each cell. There's no way to weight that accumulation by another raster (e.g. precipitation or snowmelt), so getting a physically meaningful accumulated flux currently requires reimplementing the traversal outside the library.

Proposal

Add an optional weight parameter to flow_accumulation_d8 and the other flow_accumulation functions.

Design:

def flow_accumulation_d8(
    flow_dir: xr.DataArray,
    weight: xr.DataArray | None = None,
    name: str = 'flow_accumulation',
) -> xr.DataArray:

When weight is None, behavior is unchanged. When provided, each output cell equals the sum of weight over itself and all upstream cells draining through it, instead of a cell count. I.s. weight acts like a precipitation or surface melt field.

Usage:

melt_accum = flow_accumulation_d8(flow_dir, weight=melt)

weight must be on the same grid as flow_dir.

Stakeholders and Impacts

Anyone using xarray-spatial for hydrology.

Unresolved Questions

How NaN values in weight should be handled (zero contribution vs. propagating as no-data downstream).

Activity

  1. brendancol commented on Aug 26, 2026

    @brendancol
    Contributor

    @jkingslake totally yes. Ive been doing some work on the surface_distance stuff so it makes sense to include a weight surface here. Really cool idea. I'd be happy to help review if you'd like to take a shot at it or if not, I'd be happy to address some time soon.

  2. brendancol commented on Aug 26, 2026

    @brendancol
    Contributor

    I think the answer to the "How to handle NaN" question is that they are zero contribution, like you have it in the melt example...so if there is a valid flow_dir cell, and a NaN weight, then the NaN would have no impact...also said, the output would NOT propagate a NaN value to the output based on that NaN weight.

    I think we are on the same page here.

  3. jkingslake commented on Aug 26, 2026

    @jkingslake
    Author

    Great! I am happy to have a go at this at some point. Probably with the help of claude.

    I can see where currently uniform weights are assumed:

    and

    I guess that instead iterating through the new weights array would be a good place to start:

    accum[r, c] = weights[r, c]
    

    We would also need to take account of when weights[r,c] = np.nan and make accum[r, c] zero.

    Would this be the main change do you think? (along with adding weights as an input etc.) Or would the be more involved things to do related to dask, cupy, cuda?

  4. brendancol commented on Aug 26, 2026

    @brendancol
    Contributor

    @jkingslake I tasked a claude agent with planning and the simple xarray-spatial loop, but we DON'T HAVE to go down that path if we don't want to.

    From a library perspective, the hydrology tool spellings / api isn't perfect and I think it has some sprawl due to the d8 vs dinf, vs mdf...but let's ignore that for a moment.

    The weight would need to be added to the datasets / datarray accessor methods and then each of the method specific / array-backends...basically a bunch of stamp collecting

  5. brendancol commented on Aug 26, 2026

    @brendancol
    Contributor

    @jkingslake I would love your help and don't mean to rush a PR up here. If you like to look at what the /rockout command from xarray-spatial-skills produced you can see it here: #3735

  6. brendancol commented on Aug 26, 2026

    @brendancol
    Contributor

    any chance you have example that we could run this against to test accuracy or build a test around?

  7. jkingslake commented on Aug 26, 2026

    @jkingslake
    Author

    I do not have anything to test this against particularly. The tests you have already looked at good and were along the lines of any synthetic tests I was imagining. I have a use case with an Antarctic DEM and fields of input from a regional climate model, but I don't think that will help test the implementation as such.

  8. brendancol commented on Aug 26, 2026

    @brendancol
    Contributor

    @jkingslake no worries. Maybe we could come up with a test that could confirm you or I's intuition about how it should work just on the simple create array example.

  9. brendancol commented on Aug 27, 2026

    @brendancol
    Contributor

    @jkingslake hey I've added some additional tests here that are more than just hand-rolled grids. I think we would probably gain more confidence through validating against pysheds...

    some new tests are here: https://github.com/xarray-contrib/xarray-spatial/blob/990e5eddc74aad2e189fbe05f58bc5cf246fa81a/xrspatial/hydro/tests/test_flow_accumulation_weight_accuracy.py

  10. brendancol commented on Aug 27, 2026

    @brendancol
    Contributor
  11. jkingslake commented on Aug 27, 2026

    @jkingslake
    Author

    Great work @brendancol !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:hydrologyArea: hydrologyenhancementNew feature or requestproposalIdea that needs design discussion

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions