riverarchitect.lifespan

Lifespan and design mapping for river restoration features.

The open-source replacement for the ArcGIS LifespanDesign module. It answers two questions per cell, for a chosen feature:

Lifespan - how many years is this feature expected to survive here? Each modelled discharge carries a flood return period. For every criterion the feature has a threshold for; the analysis finds the lowest return period at which the threshold is exceeded, which is when the feature fails. Cells that survive every modelled flood stay NoData: their lifespan is longer than the largest modelled event and cannot be quantified from the data.

Design - how big does the feature have to be to reach a target lifespan? For grain-based features that is the stable grain size at the design flood.

Note

The streamwood design map of the original, which sized a stable log from water depth and Froude number rather than from a Shields criterion, is not implemented. Streamwood still gets a lifespan map; it simply gets no design map, and LifespanDesign.run_feature() omits design_raster from its result rather than writing a wrong one.

Threshold values come from FEATURES, which reproduces the defaults of the original threshold_values.xlsx. Load a customised workbook with load_threshold_workbook(), or build a Feature directly.

Relation to the original

This implements the analysis hierarchy as documented in the wiki (see docs/wiki/LifespanDesign.md) rather than transcribing the arcpy control flow, which threaded results through a mutable raster_dict and a chain of Con() calls whose behaviour depended on which rasters happened to exist. The semantics are the documented ones:

  • every hydraulic criterion produces a failure return period raster, and the lifespan is their cell-wise minimum - the first flood that breaks the feature;

  • the spatial criteria (depth to water table, detrended DEM, morphological units, topographic change, terrain slope) are masks applied to that result;

  • two-argument con is used throughout, so the false branch is NoData, never zero.

class riverarchitect.lifespan.Feature(fid, name, group='', tau_cr=None, safety_factor=None, h_max=None, u_max=None, froude_max=None, d2w_min=None, d2w_max=None, det_min=None, det_max=None, grain_max=None, terrain_slope=None, scour_rate=None, fill_rate=None, inverse_tcd=False, design_frequency=None, mu_avoid=None, mu_relevant=None, mu_method=0, lifespan_mapping=True, design_mapping=False)[source]

Bases: object

Threshold values for one restoration feature.

Every threshold is optional. A criterion whose threshold is None, or whose input raster the condition does not have, is skipped - which is how the original behaved and why a sparsely defined feature still produces a map.

Parameters:
  • fid (str) – short feature id, used in output file names (lf_<fid>.tif).

  • name (str) – human-readable name.

  • group (str) – feature group, for the interface.

  • tau_cr (float) – critical dimensionless bed shear stress.

  • safety_factor (float) – safety factor for the mobile-grain analysis. When set, the mobile-grain analysis runs instead of the dimensionless shear-stress one.

  • h_max (float) – water depth above which the feature fails, in the condition’s length unit.

  • u_max (float) – flow velocity above which the feature fails.

  • froude_max (float) – Froude number above which the feature fails.

  • d2w_min (float) – depth-to-water-table range the feature needs.

  • d2w_max (float) – depth-to-water-table range the feature needs.

  • det_min (float) – detrended-DEM range the feature is restricted to.

  • det_max (float) – detrended-DEM range the feature is restricted to.

  • grain_max (float) – largest admissible grain size, for fine-sediment features.

  • terrain_slope (float) – slope above which nature-based engineering is required.

  • scour_rate (float) – topographic change thresholds.

  • fill_rate (float) – topographic change thresholds.

  • inverse_tcd (bool) – True when the feature is relevant below those rates rather than above them.

  • design_frequency (float) – target lifespan in years for the design map.

  • mu_avoid (list) – morphological units to exclude or restrict to.

  • mu_relevant (list) – morphological units to exclude or restrict to.

  • mu_method (int) – 0 to avoid mu_avoid, 1 to keep only mu_relevant.

  • lifespan_mapping (bool) – which maps the feature supports.

  • design_mapping (bool) – which maps the feature supports.

riverarchitect.lifespan.FEATURES = {'Box_est': Feature('Box_est', 'Box Elder (established)'), 'Generic': Feature('Generic', 'Generic planting'), 'Generic_est': Feature('Generic_est', 'Generic (established)'), 'Whi_est': Feature('Whi_est', 'White Alder (established)'), 'Wil_est': Feature('Wil_est', 'Willow (established)'), 'backwt': Feature('backwt', 'Backwater'), 'bio': Feature('bio', 'Other nature-based eng.'), 'box': Feature('box', 'Box Elder'), 'cot': Feature('cot', 'Cottonwood'), 'cot_est': Feature('cot_est', 'Cottonwood (established)'), 'fines': Feature('fines', 'Incorporation of fine sediment'), 'grade': Feature('grade', 'Grading'), 'gravin': Feature('gravin', 'Gravel: In'), 'gravou': Feature('gravou', 'Gravel: Out'), 'rocks': Feature('rocks', 'Angular boulders'), 'sideca': Feature('sideca', 'Side cavities'), 'sidech': Feature('sidech', 'Side channels'), 'whi': Feature('whi', 'White Alder'), 'widen': Feature('widen', 'Widen'), 'wil': Feature('wil', 'Willow'), 'wood': Feature('wood', 'Streamwood')}

Default features and thresholds, reproducing LifespanDesign/.templates/threshold_values.xlsx of the original. Values are in U.S. customary units, as that workbook was.

class riverarchitect.lifespan.LifespanDesign(condition, unit='us', manning_n=0.0473934, features=None)[source]

Bases: object

Run lifespan and design mapping for one condition.

Parameters:
  • condition (Condition or str) – the condition, or its name.

  • unit (str) – "us" or "si"; must match the condition’s rasters.

  • manning_n (float) – Manning’s n in s/m^(1/3); converted for U.S. customary units.

  • features (dict) – feature id -> Feature. Defaults to FEATURES.

Variables:

error (bool) – True when at least one feature could not be mapped.

critical_grain_size(depth, velocity, tau_cr, safety_factor=1.0)[source]

Grain diameter that just starts to move, in the condition’s length unit.

shields_stress(depth, velocity, grain, token=None)[source]

Dimensionless bed shear stress theta84, referenced to D84 = 2.2 * Dmean.

Replaces the Keulegan-only expression of the original (arcpy counterpart: analyse_taux) with the regime-aware closure of riverarchitect.shear, which stays physically meaningful in the shallow cells the logarithmic law cannot describe. When token is given, the relative submergence and regime rasters of that discharge are kept for write_shear_diagnostics().

run_feature(feature, output_dir)[source]

Map one feature. Returns a summary dict, or None when nothing could be mapped.

write_shear_diagnostics(output_dir)[source]

Write the bed shear stress rasters of each discharge beside the lifespan maps.

Four per discharge - ts (Shields stress), tb (u*^2), hks (relative submergence) and regime (which resistance closure applied) - named exactly as riverarchitect.preprocessing.bed_shear_stress() names them in the condition folder. Idempotent per output directory and per run.

run(feature_ids=None, output_dir=None)[source]

Map several features.

Parameters:
  • feature_ids (list) – feature ids; defaults to every feature that supports lifespan mapping.

  • output_dir (str) – where the rasters go. Defaults to Output/LifespanDesign/<condition>.

Returns:

one summary dict per mapped feature.

Return type:

list

riverarchitect.lifespan.load_threshold_workbook(path)[source]

Read a threshold_values.xlsx in the original layout.

Lets a project keep using a workbook it has already calibrated. Row 5 holds the feature id and each following row one threshold, exactly as the original expected.

Parameters:

path (str) – path to the workbook.

Returns:

feature id -> Feature.

Return type:

dict

riverarchitect.lifespan.feature_groups(features=None)[source]

Group features by Feature.group, preserving definition order.

Returns:

group name -> list of Feature.

Return type:

dict