Ecohydraulics
What the design is worth ecologically. Three independent analyses; all of them need a prepared condition, and habitat area additionally needs a flow duration curve from Get started, terminology and signposts.
Habitat Area (SHArC)
riverarchitect.sharc - the Ecohydraulics ▸ Habitat Area (SHArC) tab.
Turns 2D hydrodynamic results into a map of how good the habitat is for a given fish species and lifestage, and then into a single number a project can be judged on.
Habitat suitability curves come from
Fish.xlsx: for each species and lifestage, a piecewise-linear curve mapping flow depth, velocity, substrate size or cover radius onto a suitability index between 0 and 1.Hydraulic HSI rasters apply those curves to the depth and velocity rasters of a discharge, giving
dsiandvsi.Composite HSI (
cHSI) combines them by geometric mean or product, optionally with a cover HSI, and is masked to the wetted area.Usable area at a discharge is the area where
cHSIexceeds a threshold (0.4 by default), optionally weighted by the meancHSIthere.SHArea integrates usable area over the flow duration curve, so habitat that only exists at a rare discharge counts for little.
with \(E_i\) the cumulative per-cent exceedance of discharge \(i\) and \(A_i\) its usable area.
That reproduces the =(E5-E4)/100*F5 column of the original CONDITION_sharea_template.xlsx
exactly.
Read the mean cHSI, not only the area
Usable area is not monotonic in discharge. A high flow can inundate a large area of channel margin shallowly enough to clear the threshold even though the reach as a whole is less suitable. Area and quality are different questions; SHArea is the one that weighs them together.
Cover
Depth and velocity say whether a fish can be somewhere. Cover says whether it is safe
to be there - a fry in open water at the right depth and velocity is still a meal. Pass
cover=True to riverarchitect.sharc.SHArC.run(), or call
riverarchitect.sharc.cover_hsi() directly.
Cover type |
Source |
How it is applied |
|---|---|---|
|
the grain size raster |
mapped through its suitability curve, like depth or velocity |
|
grain size 0.064 - 0.256 m |
presence, spread over the curve’s radius |
|
grain size above 0.256 m |
presence, spread over the curve’s radius |
|
|
presence, spread over the curve’s radius |
|
|
presence, spread over the curve’s radius |
A cover element shelters everything within its radius, taken from the first x value of
its curve in Fish.xlsx, and those cells take the curve’s suitability. The result is the
cell-wise maximum across the types present: the best shelter available at a cell is what
counts, not the sum of every kind of it. Cover is cropped to water the lifestage can reach -
shelter a fish cannot get to shelters nothing.
With cover, the composite is the cube root of dsi * vsi * cover rather than the square root
of dsi * vsi.
Where the radius came from
The original produced it by converting the cover raster to points, running
SpatialJoin_analysis(..., match_option="CLOSEST", search_radius=r) against a point per
cell, and converting back. That is a Euclidean distance transform written the only way
arcpy allowed; here it is riverarchitect.raster.within_radius(), which also handles
anisotropic cells correctly.
Species and lifestages
The workbook defines Chinook Salmon, Rainbow / Steelhead Trout, Lamprey, Green Sturgeon and a generic “All Aquatic” block, each with its own lifestages, seasons, curves and swimming thresholds. Lifestage labels are read from the workbook rather than assumed, because they vary by species - offset 3 is “fry” for salmon but “ammocoetes” for lamprey.
Names are matched ignoring case and spacing, so "Chinook salmon" and the workbook’s
"Chinook Salmon" both work. In the original, and in early versions of this port, the
capitalisation of a caller’s argument decided whether the analysis ran at all.
To add or edit a species, edit the packaged Fish.xlsx - see the Edit Fish template page
below.
Relation to the original
cHSI.nested_con_raster_calc built one Con() raster per curve segment and took their
cell-wise maximum: a piecewise-linear interpolation written the only way arcpy map algebra
allowed. Here it is riverarchitect.sharc.apply_curve(), which is numpy.interp with
the same end behaviour - hold the first suitability below the curve, but drop to zero
above it. That asymmetry is deliberate: a depth beyond the curve is unsuitable, not maximally
suitable, and clamping there would invent habitat at the highest discharges.
Stranding Risk
riverarchitect.stranding - the Ecohydraulics ▸ Stranding Risk tab.
As discharge falls the wetted area shrinks and breaks apart; pools that lose their connection to the main channel trap fish. Threshold each depth raster at the minimum swimming depth of the species and lifestage, label the wetted regions, and every region that does not reach the main channel is a stranding risk.
The main channel is defined once, as the largest wetted region at the lowest analysed discharge, and every higher discharge is judged against it - the same target the original built its least-cost escape routes towards.
Output |
|
|---|---|
|
one per discharge |
|
the highest discharge at which each cell was disconnected: the flow at which that spot becomes a trap as the hydrograph recedes |
|
the individual pools at the worst discharge |
table |
wetted area, stranded area and pool count per discharge |
The minimum swimming depth comes from Fish.xlsx (0.2 ft for Chinook fry). It is the
single most influential parameter in the analysis - at h_min = 0 every wet cell counts
and much of the pool count is single cells at the wetted edge, real in the raster and
meaningless in the river. State the value you used alongside any result.
The velocity criterion is not applied
The original also blocked escape routes where the flow was faster than the lifestage could
swim against. This port applies the depth criterion only.
riverarchitect.stranding.StrandingRisk.velocity_limited is False to record that,
and u_max carries the threshold that would have been used, so a result can state it.
Riparian Seedling Recruitment
riverarchitect.recruitment - the Ecohydraulics ▸ Riparian Seedling Recruitment
tab.
Cottonwood and willow seedlings establish only where four things happen in the right order over a single season, and this maps where all four coincide - the Recruitment Box Model of Braatne et al. (2007).
Objective |
Question |
|---|---|
Bed preparation |
did a winter flow mobilise the bed, clearing a seedbed? |
Recession rate (desiccation) |
did the water table drop slowly enough for roots to follow? |
Prolonged inundation |
did the seedling stay under water long enough to drown? |
Scour |
did a later flow uproot it? |
Each is scored 1 (good), 0.5 (stressed) or 0 (fatal), and the recruitment potential is their product - a seedling has to survive every one of them, so a zero anywhere is a zero overall.
This is the one module that needs a daily flow record: bed preparation, recession and scour are about when flows happened, not just which flows are possible.
Three details decide the result, and all three follow the original:
a stressful or lethal recession day is only counted where the cell is dry that day - a submerged seedling is not desiccating, however fast the surface is dropping;
a cell that goes dry during seed dispersal starts again from there, because that is when its seed actually landed, so both the counts and their denominator are per cell;
the inundation objective uses the longest run of consecutive submerged days, not their total. Fourteen days under water in one stretch drowns a seedling; fourteen days spread over a season does not.
In this section
- Seasonal Habitat Area Calculator (SHArC)
- Introduction to Habitat Suitability evaluation
- Quick GUIde to habitat suitability evaluation
- SHArC - Working Principles
- Working principles
- SHArC - Code modification
- Fish species and lifestages
- Changing the structure of
Fish.xlsx - Stranding Risk Assessment
- Introduction to Stranding Risk Module
- Quick GUIde to Stranding Risk Assessment
- Defining Travel Thresholds
- Methodology
- References
- Riparian Seedling Recruitment (RSR)
- Introduction to Riparian Seedling Recruitment Module
- Quick GUIde to Riparian Recruitment Assessment
- Defining Criteria
- Methodology
- References
See also
riverarchitect.sharc, riverarchitect.stranding and
riverarchitect.recruitment in the API reference.