Skip to content

Commit

Permalink
Merge pull request #181 from mdbartos/mfd
Browse files Browse the repository at this point in the history
Add multiple flow directions (MFD) routing
  • Loading branch information
mdbartos authored Jan 27, 2022
2 parents 63551e5 + c683077 commit 1951f63
Show file tree
Hide file tree
Showing 10 changed files with 1,145 additions and 165 deletions.
32 changes: 21 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,17 +451,24 @@ Performance benchmarks on a 2015 MacBook Pro (M: million, K: thousand):

| Function | Routing | Number of cells | Run time |
| ----------------------- | ------- | ------------------------ | -------- |
| `flowdir` | D8 | 36M | 1.09 [s] |
| `flowdir` | DINF | 36M | 6.64 [s] |
| `accumulation` | D8 | 36M | 3.65 [s] |
| `accumulation` | DINF | 36M | 16.2 [s] |
| `catchment` | D8 | 9.76M | 3.43 [s] |
| `catchment` | DINF | 9.76M | 5.41 [s] |
| `distance_to_outlet` | D8 | 9.76M | 4.74 [s] |
| `distance_to_outlet` | DINF | 9.76M | 1 [m] 13 [s] |
| `distance_to_ridge` | D8 | 36M | 6.83 [s] |
| `hand` | D8 | 36M total, 730K channel | 12.9 [s] |
| `hand` | DINF | 36M total, 770K channel | 18.7 [s] |
| `flowdir` | D8 | 36M | 1.14 [s] |
| `flowdir` | DINF | 36M | 7.01 [s] |
| `flowdir` | MFD | 36M | 4.21 [s] |
| `accumulation` | D8 | 36M | 3.44 [s] |
| `accumulation` | DINF | 36M | 14.9 [s] |
| `accumulation` | MFD | 36M | 32.5 [s] |
| `catchment` | D8 | 9.76M | 2.19 [s] |
| `catchment` | DINF | 9.76M | 3.5 [s] |
| `catchment` | MFD | 9.76M | 17.1 [s] |
| `distance_to_outlet` | D8 | 9.76M | 2.98 [s] |
| `distance_to_outlet` | DINF | 9.76M | 5.49 [s] |
| `distance_to_outlet` | MFD | 9.76M | 13.1 [s] |
| `distance_to_ridge` | D8 | 36M | 4.53 [s] |
| `distance_to_ridge` | DINF | 36M | 14.5 [s] |
| `distance_to_ridge` | MFD | 36M | 31.3 [s] |
| `hand` | D8 | 36M total, 730K channel | 12.3 [s] |
| `hand` | DINF | 36M total, 770K channel | 15.8 [s] |
| `hand` | MFD | 36M total, 770K channel | 29.8 [s] |
| `stream_order` | D8 | 36M total, 1M channel | 3.99 [s] |
| `extract_river_network` | D8 | 36M total, 345K channel | 4.07 [s] |
| `detect_pits` | N/A | 36M | 1.80 [s] |
Expand All @@ -471,10 +478,13 @@ Performance benchmarks on a 2015 MacBook Pro (M: million, K: thousand):
| `resolve_flats` | N/A | 36M | 9.56 [s] |
| `cell_dh` | D8 | 36M | 2.34 [s] |
| `cell_dh` | DINF | 36M | 4.92 [s] |
| `cell_dh` | MFD | 36M | 30.1 [s] |
| `cell_distances` | D8 | 36M | 1.11 [s] |
| `cell_distances` | DINF | 36M | 2.16 [s] |
| `cell_distances` | MFD | 36M | 26.8 [s] |
| `cell_slopes` | D8 | 36M | 4.01 [s] |
| `cell_slopes` | DINF | 36M | 10.2 [s] |
| `cell_slopes` | MFD | 36M | 58.7 [s] |

Speed tests were run on a conditioned DEM from the HYDROSHEDS DEM repository
(linked above as `elevation.tiff`).
Expand Down
116 changes: 115 additions & 1 deletion docs/flow-directions.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,121 @@ Raster([[ nan, nan, nan, ..., nan, nan, nan],

Note that each entry takes a value between 0 and 2π, with `np.nan` representing unknown flow directions.

Note that you must also specify `routing=dinf` when using `grid.catchment` or `grid.accumulation` with a D-infinity output grid.
Note that you must also specify `routing='dinf'` when using other functions that use the flow direction grid such as `grid.catchment` or `grid.accumulation`.

## Multiple flow directions (MFD)

The multiple flow direction (MFD) routing scheme partitions flow from each cell to among as many as eight of its neighbors. The proportion of the cell that flows to each of its neighbors is proportional to the height gradient between the neighboring cells.

MFD routing can be selected by using the keyword argument `routing='mfd'`.

```python
fdir = grid.flowdir(inflated_dem, routing='mfd')
```

<details>
<summary>Output...</summary>
<p>

<pre>
fdir

MultiRaster([[[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0.37428797, 0.41595555, ..., 0. ,
0. , 0. ],
[0. , 0.35360402, 0.42297009, ..., 0.06924557,
0. , 0. ],
...,
[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ]],

[[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0.36288963, 0.33088875, ..., 0.06863035,
0. , 0. ],
[0. , 0.40169546, 0.36123674, ..., 0.23938736,
0.17013502, 0. ],
...,
[0. , 0.00850506, 0.10102002, ..., 0. ,
0. , 0. ],
[0. , 0. , 0.04147018, ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ]],

[[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0.14276847, 0.06932945, ..., 0.48528137,
0.39806072, 0. ],
[0. , 0.1217316 , 0.06042334, ..., 0.4193337 ,
0.48612365, 0. ],
...,
[0. , 0.1683329 , 0.28176027, ..., 0. ,
0. , 0. ],
[0. , 0.13663963, 0.24437534, ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ]],

...,

[[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
...,
[0. , 0.20829874, 0.04770285, ..., 0.29010027,
0.31952507, 0. ],
[0. , 0.20128372, 0.11750307, ..., 0.23404662,
0.28716789, 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ]],

[[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
...,
[0. , 0. , 0. , ..., 0.03460397,
0.06389793, 0. ],
[0. , 0.0151827 , 0. , ..., 0. ,
0.06675575, 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ]],

[[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0.12005394, 0.18382625, ..., 0. ,
0. , 0. ],
[0. , 0.12296892, 0.15536983, ..., 0. ,
0. , 0. ],
...,
[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ],
[0. , 0. , 0. , ..., 0. ,
0. , 0. ]]])
</pre>

</p>
</details>

<br>

Note that if the original DEM is of shape `(m, n)`, then the returned flow direction grid will be of shape `(8, m, n)`. The first dimension corresponds to the eight flow directions, with index 0 corresponding to North, index 1 corresponding to Northeast, index 2 corresponding to East, and so on until index 7 corresponding to Northwest. The value of a given array element (k, i, j) represents the proportion of flow that is transferred from cell (i, j) to the neighboring cell k (where k ∈ [0, 7]).

Note that you must also specify `routing='mfd'` when using other functions that use the flow direction grid such as `grid.catchment` or `grid.accumulation`.


## Effect of map projections on routing

Expand Down
32 changes: 21 additions & 11 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,17 +455,24 @@ Performance benchmarks on a 2015 MacBook Pro (M: million, K: thousand):

| Function | Routing | Number of cells | Run time |
| ----------------------- | ------- | ------------------------ | -------- |
| `flowdir` | D8 | 36M | 1.09 [s] |
| `flowdir` | DINF | 36M | 6.64 [s] |
| `accumulation` | D8 | 36M | 3.65 [s] |
| `accumulation` | DINF | 36M | 16.2 [s] |
| `catchment` | D8 | 9.76M | 3.43 [s] |
| `catchment` | DINF | 9.76M | 5.41 [s] |
| `distance_to_outlet` | D8 | 9.76M | 4.74 [s] |
| `distance_to_outlet` | DINF | 9.76M | 1 [m] 13 [s] |
| `distance_to_ridge` | D8 | 36M | 6.83 [s] |
| `hand` | D8 | 36M total, 730K channel | 12.9 [s] |
| `hand` | DINF | 36M total, 770K channel | 18.7 [s] |
| `flowdir` | D8 | 36M | 1.14 [s] |
| `flowdir` | DINF | 36M | 7.01 [s] |
| `flowdir` | MFD | 36M | 4.21 [s] |
| `accumulation` | D8 | 36M | 3.44 [s] |
| `accumulation` | DINF | 36M | 14.9 [s] |
| `accumulation` | MFD | 36M | 32.5 [s] |
| `catchment` | D8 | 9.76M | 2.19 [s] |
| `catchment` | DINF | 9.76M | 3.5 [s] |
| `catchment` | MFD | 9.76M | 17.1 [s] |
| `distance_to_outlet` | D8 | 9.76M | 2.98 [s] |
| `distance_to_outlet` | DINF | 9.76M | 5.49 [s] |
| `distance_to_outlet` | MFD | 9.76M | 13.1 [s] |
| `distance_to_ridge` | D8 | 36M | 4.53 [s] |
| `distance_to_ridge` | DINF | 36M | 14.5 [s] |
| `distance_to_ridge` | MFD | 36M | 31.3 [s] |
| `hand` | D8 | 36M total, 730K channel | 12.3 [s] |
| `hand` | DINF | 36M total, 770K channel | 15.8 [s] |
| `hand` | MFD | 36M total, 770K channel | 29.8 [s] |
| `stream_order` | D8 | 36M total, 1M channel | 3.99 [s] |
| `extract_river_network` | D8 | 36M total, 345K channel | 4.07 [s] |
| `detect_pits` | N/A | 36M | 1.80 [s] |
Expand All @@ -475,10 +482,13 @@ Performance benchmarks on a 2015 MacBook Pro (M: million, K: thousand):
| `resolve_flats` | N/A | 36M | 9.56 [s] |
| `cell_dh` | D8 | 36M | 2.34 [s] |
| `cell_dh` | DINF | 36M | 4.92 [s] |
| `cell_dh` | MFD | 36M | 30.1 [s] |
| `cell_distances` | D8 | 36M | 1.11 [s] |
| `cell_distances` | DINF | 36M | 2.16 [s] |
| `cell_distances` | MFD | 36M | 26.8 [s] |
| `cell_slopes` | D8 | 36M | 4.01 [s] |
| `cell_slopes` | DINF | 36M | 10.2 [s] |
| `cell_slopes` | MFD | 36M | 58.7 [s] |

Speed tests were run on a conditioned DEM from the HYDROSHEDS DEM repository
(linked above as `elevation.tiff`).
Expand Down
2 changes: 1 addition & 1 deletion pysheds/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.3.1"
__version__ = "0.3.2"
Loading

0 comments on commit 1951f63

Please sign in to comment.