Releases: awickert/r.fluvial
Release list
r.fluvial 0.4.0
This release adds objective channel-head extraction and a flow-routing / landscape-evolution engine to the toolkit, and renames the project to r.fluvial.
Highlights
r.fluvial.channelheads method=dreich — DrEICH morphological channel heads. A faithful Python/NumPy port of the LSDTopoTools DrEICH algorithm (Clubb et al., 2014): depression fill, D8 routing, second-order polynomial tangential curvature, valley detection, and the per-valley χ–z regression split. Validated stage-by-stage against an instrumented LSDTopoTools run on Mid Bailey Run, OH — routing/sources, valley junctions (768), hilltops (768/768), and head count (634) are bit-exact; 630/634 head locations match. Emits channel-head points, the downstream network as vector lines (v.stream.network format) and/or a raster stream map, and accepts an external D8 routing raster via direction=.
r.fluvial.fastscape — D8 flow routing + optional landscape evolution. Routing-first: by default (nsteps=0) it routes a DEM (filled, direction, accumulation) as a fast O(n) drainage solver and a routing front-end to r.fluvial.channelheads; with nsteps>0 it evolves the landscape under stream-power incision (dz/dt = U − K·Aᵐ·Sⁿ) using the implicit, unconditionally stable FastScape algorithm (Braun & Willett, 2013).
rivernetworkx library gains the χ integral coordinate (Perron & Royden, 2013), the DrEICH χ–z head-finder, Strahler ordering, drainage-divide extraction, and a slope–area break detector.
Also in this release
v.stream.profiler→v.fluvial.profiler— breaking rename; the geomorphic-analysis modules now form afluvialfamily on the sharedrivernetworkxcore.- Repository renamed
GRASS-fluvial-profiler→r.fluvial(old URLs redirect). - Proper attribution added for every ported algorithm (Clubb 2014; Mudd 2014, 2019; Perron & Royden 2013; Evans 1980; Zevenbergen & Thorne 1987; Braun & Willett 2013; Strahler 1957).
- Fix:
v.stream.networkno longer crashes on networks with both confluences and an off-map outlet.
The API is still pre-1.0 and may change. Full details in the CHANGELOG.
v0.3.0 — Shared rivernetworkx core and module modernization
This release migrates the toolkit onto a single shared river-network library,
modernizes the modules, and makes several correctness fixes. The API is still
pre-1.0 and may change.
Added
rivernetworkx: a new importable Python package (pure NetworkX, no GRASS)
that single-sources the river-network logic — graph construction
(build_network/build_graph), raster sampling, breadth-first traversal,
cumulative-distance accumulation, per-segment smoothing and densification,
channel slope (−d z/d s) and slope–area, and node-link
JSON I/O. The GRASS modules are now thin consumers of it, and the same
representation is reusable outside GRASS (e.g. the GRLP coupling).v.stream.networkgains an optionaljson=export (withelevation=,
accumulation=,accum_mult=): it builds the NetworkX river-network graph,
samples rasters along each segment, computes cumulative distance upstream of
the outlet, and writes node-link JSON. This is the capability formerly
provided by the separatev.stream.networkxmodule.v.stream.networkandv.stream.profilergain a-cflag (the region
contains the full basin): a negative-accumulation channel head is then treated
as anr.watershedboundary artifact (a divide on the region edge) rather than
off-map inflow, skipping the off-map error.
Changed
v.stream.profilerrebuilt onrivernetworkx. It walks either downstream
to the outlet or upstream through all tributaries, samples
elevation/accumulation/slope along the channel, optionally densifies
(dx_target=) and smooths (window=) per segment (smoothing and
densification never cross tributary junctions, preserving the natural breaks),
and outputs a text long-profile table and/or a node-link JSON sub-network
(json=).- Drainage area sampled from
r.watershedis returned as a positive magnitude
(the outlet cells, which GRASS marks negative as a boundary flag, are
recovered). examples/clean_coarsen_network.pynow post-processes the
v.stream.network json=export; its accumulation array is optional.
Fixed
v.stream.profilerwas non-functional on current GRASS GIS and pandas (a
stalegrass.rasterimport and aSeries→intcoercion); it runs again,
and its long-standing branching bug is fixed by construction.v.stream.networkwrites the off-map outlettostreamas0(an earlier
partial migration wrote-1); diverging (distributary/braided) networks now
stop with a clear error instead of writing a partialtostream.- Raster sampling is limited to the network's extent (covers the whole network
even when the current region does not, and avoids reading a full large
region), includes points exactly on the east/south region edges, and tolerates
coincident vertices. - Incomplete catchments (off-map upstream contributing area, flagged by negative
r.watershedaccumulation reaching a channel head) are caught with a clear
error rather than silently producing a misleading network; the-cflag
overrides this when the region truly holds the full basin. - Raster NULL cells are read as NaN rather than a silent
0, so missing data
stays honest; sampling accumulation with no data under a channel cell now
errors clearly instead of slipping through as a fake0. export_jsonemits standards-compliant JSON (non-finite floats asnull, not
the bareNaNtoken that strict parsers reject);load_jsonrestores them.
Removed
v.stream.networkx: retired. Its sole job (build graph → JSON) is now
thejson=option onv.stream.network, backed byrivernetworkx.v.stream.profiler/RiverNetwork.py: the bespoke network class is replaced
by the sharedrivernetworkxlibrary.
Full changelog: v0.2.0...v0.3.0
v0.2.0 — NetworkX river networks and GRASS modernization
First release since 2017. It modernizes the toolkit for current GRASS GIS and
adds NetworkX-based river-network analysis, developed in collaboration with
Fergus McNab (GFZ Potsdam) and presented at AGU 2025:
Wickert, A. D., and F. McNab (2025), Simulating Geomorphic Evolution Through
River Networks, EP23D-1702, AGU Fall Meeting, New Orleans, LA, USA.
The API is still pre-1.0 and may change.
Added
- v.stream.networkx — a new module that builds a NetworkX
directed graph of a river network, samples elevation and flow accumulation
along each segment, computes cumulative distance upstream of the outlet by a
breadth-first sweep, and optionally exports the graph as JSON. Ships with a
Makefile and HTML manual page so it installs as a GRASS addon. - examples/clean_coarsen_network.py — a post-processing ("stage 2") script
that despikes, smooths, and coarsens av.stream.networkxJSON export for use
as input to a downstream long-profile model such as GRLP. - LICENSE (GNU GPL v3 or later), CITATION.cff, a project README, and
this CHANGELOG.
Changed
- v.stream.profiler reworked and modernized for current GRASS GIS; adopts
Pandas; produces river long profiles and slope–accumulation (e.g., slope–area)
outputs. - v.stream.network updated for current GRASS GIS; GRASS+NumPy raster reads
modernized to a single step;tostreamenforced as integer; the off-map
outlet segment is coded as0.
Removed
- Legacy scripts outside the fluvial-profiler scope (PRMS/MODFLOW/GSFLOW grid and
parameter builders, an older standalone network extractor, and assorted one-off
utilities). Standalone, multicore, and other Python-2 development scripts were
moved toarchive/.
Full changelog: v0.1.0...v0.2.0