RUSLE NoDb Mod Specification
Living specification and implementation record.
This file captures both current shipped behavior and forward-looking design direction for a gridded
RUSLENoDb mod based on thedisturbed9002_wbtworkflow.Tense convention:
- present tense = behavior implemented in the current stack
- future/modal language (
should,may) = planned or optional extensions
Purpose
Define an academically defensible path for a gridded RUSLE implementation in
WEPPpy using the WBT backend in /workdir/weppcloud-wbt, with
disturbed9002_wbt as the initial configuration target.
The initial product provides a spatial representation of long-term average hillslope sheet-and-rill detachment potential, not event-scale erosion, not sediment delivery ratio, and not channel erosion.
The first implementation remains spatially gridded in its outputs, but
uses a run-constant, climate-derived R rather than an external gridded
erosivity surface.
Practically, this mod is intended to replace legacy heuristic gridded erosion visualizations with a product that is more explicit, more citable, and more academically defensible. It is treated as a visualization and prioritization layer, not as a regulatory estimate or a substitute for calibrated hillslope modeling.
Model Framing
The core equation is:
A = R * K * LS * C * P
For this mod:
Ais interpreted as long-term average annual hillslope soil loss or detachment potential from sheet-and-rill processes.- The model is applied only on hillslope cells.
- Channel cells, open water, wetlands, and urban/developed cells are treated as out-of-domain in the default hillslope interpretation.
- Channel cells, open water, wetlands, and urban/developed cells are masked out of the primary output.
- The first public-facing wording emphasizes
detachment potentialorrelative long-term detachment hazard, unless and until factor choices and validation support stronger wording.
Initial Scope
- Target config lineage:
wepppy/nodb/configs/disturbed9002_wbt.cfg - Backend: WhiteboxTools fork in
/workdir/weppcloud-wbt - Initial geography: United States workflows first
- First
Rdelivery: compute a scalarRfrom the run WEPP climate file and broadcast it tor.tif; do not depend on an external gridded runtimeRsource - Current output family in standard
Ruslebuilds:- shared outputs:
rusle/r.tifrusle/ls.tifrusle/l.tifrusle/s.tifrusle/sca.tifrusle/effective_slope_length.tifrusle/p.tifrusle/manifest.jsonrusle/README.md
- mode-specific outputs:
rusle/c_observed_rap.tiforrusle/c_scenario_sbs.tifrusle/a_<c_mode>_<default_k_mode>.tif- selected
rusle/k_polaris_nomograph.tifand/orrusle/k_polaris_epic.tif
- mode-support artifacts:
rusle/c_fg.tif(observed_rap)rusle/disturbed_class.tif(scenario_sbs)rusle/c_lookup_used.csv(scenario_sbs)- optional
rusle/sbs_4class.tifwhen an SBS raster is provided
- shared outputs:
- Historical generic aliases remain documented design references:
rusle/k.tifis available from the K integration helper whenwrite_default_k=True, but is not written by the standardRuslebuildrusle/a.tifandrusle/mask.tifare not emitted by the current standard controller path
Non-Goals
- Event-based detachment modeling
- Sediment delivery to channels or outlets
- Net erosion-deposition modeling
- Channel erosion or gully erosion
- A full clone of
RUSLE2
If future work needs deposition, the design should branch toward a
USPED-style or other transport-capacity workflow rather than stretching the
plain RUSLE label.
Spatial Masking Rules
Primary masking combines:
- WBT channel network products, especially
netful - NLCD landcover exclusions
- Optional explicit user masks
The initial NLCD exclusions include:
11open water21,22,23,24developed90,95woody wetlands and emergent herbaceous wetlands
Wetland Masking Rationale
The exclusion of NLCD 90 and 95 is a model-domain decision, not a claim
that wetlands never erode.
RUSLEis being used here as a hillslope sheet-and-rill detachment model for rainfall and overland flow, not as a wetland-process, channel-scour, or depositional-marsh model- woody wetlands and emergent herbaceous wetlands commonly represent saturated, ponded, or hydrologically connected environments that sit outside the intended upland hillslope domain of this mod
- wetlands often function as sediment-assimilation, storage, or filtering environments, so leaving them in the primary detachment map would tend to blur the distinction between upland sediment-source areas and downstream receiving or depositional areas
- this is documented as a default scope mask rather than a universal scientific statement; if a future workflow needs drained farmed wetlands, wet meadows, or other edge cases treated as hillslopes, that should be an explicit override with different assumptions
The mask also stops slope-length growth for LS.
Factor Design
LS
Implementation status: a purpose-built WBT tool (RusleLsFactor) now exists
and is the canonical LS path; SedimentTransportIndex remains comparison-only.
Rationale
- Whitebox's existing
SedimentTransportIndexis useful, but it is documented as a unit-stream-power substitute that is only sometimes used in place ofLS. - The mod needs an explicit, auditable
RUSLEtopographic factor, not a nearby terrain proxy. - A dedicated tool makes masking, slope-length truncation, and output diagnostics explicit.
Reviewed Precedents
The current LS decisions are based on both literature and existing open
implementations:
Desmet and Govers (1996)remains the canonical rasterL-factor basisMcCool et al. (1987, 1989)remains the canonicalRUSLEbasis forSand the slope-length exponentmTarboton (1997)provides the scientific basis for defaultDInfrouting and specific catchment areaSAGAis a useful open implementation precedent because it explicitly supportsDesmet and Govers (1996)and aspect-dependent specific catchment areaGRASS r.watershedis a useful open implementation precedent forblocking,max_slope_length, and default multiple-flow routing, but not for the canonical equation set because itsLSoutput is documented as using western-rangelands equations- Whitebox's existing
SedimentTransportIndexremains a comparison or diagnostic product only, not the canonicalLS
Implemented WBT Tool
Tool name: RusleLsFactor
Current inputs:
dem- optional precomputed
sca - optional precomputed
slope_deg - optional
channel_mask - optional
blocking_mask - optional
max_slope_length_m - routing mode selector, default
DInf
Current outputs:
ls.tifl.tifs.tifsca.tifeffective_slope_length.tif
Implementation locations:
weppcloud-wbt/whitebox-tools-app/src/tools/terrain_analysis/rusle_ls_factor.rs- registered via:
weppcloud-wbt/whitebox-tools-app/src/tools/terrain_analysis/mod.rsweppcloud-wbt/whitebox-tools-app/src/tools/mod.rs
- Python wrappers:
weppcloud-wbt/whitebox_tools.pyweppcloud-wbt/WBT/whitebox_tools.py
- WEPPpy integration entrypoint:
wepppy/nodb/mods/rusle/ls_integration.py
Locked v1 Method
RusleLsFactor implements one canonical v1 LS path rather than ship
multiple competing LS equations.
L Subfactor
- Use the
Desmet and Govers (1996)raster formulation - Drive
Lfrom upslope contributing area per unit contour width, not from a stream-power surrogate - Include the standard aspect-dependent contour-width correction from
Desmet and Govers (1996)rather than assuming contour width always equals cell size - Use the
RUSLEslope-length exponent:m = beta / (1 + beta)beta = (sin(theta) / 0.0896) / (3.0 * sin(theta)^0.8 + 0.56)
- Treat
thetaas the local slope angle; ifslope_degis supplied, convert it internally to radians before applying the equations
S Subfactor
- Use the standard
McCool/RUSLEsteepness equations based on local slope angle:S = 10.8 * sin(theta) + 0.03whentan(theta) < 0.09S = 16.8 * sin(theta) - 0.50whentan(theta) >= 0.09
- Use local slope only in v1, not distance-weighted average catchment slope
- Do not substitute the
Nearing (1997)continuous steep-slope form in v1; staying with the standardMcCool/RUSLEform keeps the tool closer to USDARUSLEpractice and the most common rasterLSimplementations - Do not implement the short-slope interrill-only branch from
McCool et al. (1987)in v1; that is an explicit scale assumption for a 30 m gridded product rather than a claim that the branch is scientifically invalid
Implementable Near-RUSLE2 Alternative (Non-Default)
The locked v1 default remains the moderate-condition McCool (1989) m
relationship above. A closer, still implementable bridge toward RUSLE2
behavior is to support an optional non-default rill/interrill regime control
for sensitivity analysis:
m_regime = slight | moderate | high_rill- compute
beta_baseusing the locked v1 equation - apply
beta = 0.5 * beta_baseforslight - apply
beta = 1.0 * beta_baseformoderate(v1 default) - apply
beta = 2.0 * beta_baseforhigh_rill
This is still not full dynamic RUSLE2 daily m behavior, but it is
implementable in raster workflows and scientifically closer than a single
hard-coded moderate regime.
Routing and DEM Assumptions
- Default routing mode:
DInf - Default flow input: specific catchment area from a hydrologically conditioned DEM
- The
RusleLsFactortool should assume the DEM is already hydrologically sound upstream; it should not silently fill or breach pits inside the tool - The tool should fail fast with an explicit, actionable error when interior no-flow artifacts indicate a likely unconditioned DEM
- If
scais supplied, it must already be a same-grid specific catchment area raster inm^2/m - If
slope_degis supplied, it must already be a same-grid local slope raster in degrees FD8may be supported as an alternate multiple-flow sensitivity pathD8may be supported as a comparison path only, not as the default
Slope-Length Termination and Masking
- Stop slope-length growth at channel cells
- Stop slope-length growth at masked
NLCDwater, urban, and wetland cells - Stop slope-length growth at explicit
blocking_maskcells such as roads, skid trails, treatment breaks, or other known barriers when those inputs are intentionally supplied - Define
ls_stop_maskas the union of:- channel mask
- non-hillslope land masks used by the
Ruslecontroller (NLCDwater, urban, wetlands by default) - optional explicit
blocking_mask
blocking_maskraster semantics are fixed for v1:- same extent, resolution, and grid alignment as
dem - value
> 0means stop cell - value
0means pass-through cell NoDatainblocking_maskis treated as pass-through unless another stop-mask component marks the cell as stop
- same extent, resolution, and grid alignment as
- Routing behavior at stop cells should be explicit and consistent across
routing modes:
- stop cells are terminal sinks with zero outflow for
LSrouting purposes - for multi-flow routing (
DInf,FD8), any routed fraction entering a stop cell is terminated and should not be renormalized onto nonstop receivers - stop-mask cells are excluded from primary hillslope
L,S, andLSoutputs
- stop cells are terminal sinks with zero outflow for
- Do not treat disturbance itself as an
LSinput. Disturbance affects the final map throughC, the joint hillslope mask, and scenario framing, not by changing the topographic factor equations - Apply a handbook-based default slope-length cap:
max_slope_length_m = 304.8(1000 ft)- basis:
RUSLE2 Handbookguidance that slope lengths longer than 1000 ft should generally not be used
- Allow
max_slope_length_moverride for explicit sensitivity analysis only. If a run changes this value, record both the value and rationale inrusle/manifest.json - The cap is part of the canonical v1 operational science contract, not a hidden visualization fallback
Output and Interpretation Assumptions
- Required v1 outputs from
RusleLsFactor:ls.tifl.tifs.tifsca.tifeffective_slope_length.tif
- Required metadata in output rasters and
rusle/manifest.jsonforLS:tool = RusleLsFactortool_versionl_method = desmet_govers_1996s_method = mccool_rusle_piecewisem_methodandm_regimerouting_modedem_hydrologically_sound_assumed = truemax_slope_length_mmax_slope_length_basis = rusle2_handbook_1000ftstop_mask_componentsstop_mask_routing_behavior = terminal_sink_no_renormalizationsca_source = derived | inputslope_source = derived | input
- Required v1 metadata typing and enum spellings (for Rust/Python parity):
toolandtool_version: stringl_method: enum, must bedesmet_govers_1996s_method: enum, must bemccool_rusle_piecewisem_method: enum, must bemccool_1989_beta_moderate_basem_regime: enum, one ofslight,moderate,high_rillrouting_mode: enum, one ofdinf,fd8,d8dem_hydrologically_sound_assumed: boolean, must betruemax_slope_length_m: float (304.8default)max_slope_length_basis: enum, must berusle2_handbook_1000ftstop_mask_components: string list subset ofchannel_mask,nlcd_water,nlcd_urban,nlcd_wetlands,blocking_maskstop_mask_routing_behavior: enum, must beterminal_sink_no_renormalizationsca_source: enum, one ofderived,inputslope_source: enum, one ofderived,inputblocking_mask_source: enum, one ofnone,input_raster
- The target interpretation is broad hillslope pattern and relative detachment potential at the run cell size, not microtopographic truth
SedimentTransportIndexmay still be exported as an auxiliary comparison layer, but not substituted for canonicalLS
The first implementation favors transparency and diagnostic outputs over micro-optimization.
R
Current runtime direction: use the run WEPP climate file to compute a static,
non-gridded R for the area of interest. In the current implementation, R
is spatially uniform within a run unless and until a separate gridded-climate
extension is intentionally added.
Key Constraint
RUSLE rainfall erosivity is not just precipitation total. It requires a
long-term annual sum of storm EI30, which in turn requires storm energy and
maximum 30-minute intensity.
Canonical RUSLE Definition of R
For this specification, the canonical definition of R is the USDA
USLE/RUSLE definition, not an app-specific adaptation:
Ris a long-term average annual erosivity index for a location- annual
Ris the average annual sum of erosivity values for individual storms from historical weather records - individual-storm erosivity is based on storm kinetic energy times maximum
30-minute intensity, commonly written as
EI30
That distinction matters. A single precipitation-frequency design value, even
if converted through a storm energy equation, is not by itself the same thing
as canonical annual RUSLE R.
Preferred Runtime Mode: cligen_static
- Preferred first shipping mode and current default
- Use the run WEPP climate file as the source of truth for rainfall erosivity when the product goal is to approximate the erosivity used by WEPP in the same run
- Compute one scalar
Rfor the full run climate record, then broadcast that value over the unmasked AOI - Treat
PRISM,NOAA Atlas 14, and similar external precipitation products as upstream climate-generation inputs only, not as runtimeRinputs for theRuslemod
Interpretation note:
cligen_staticis the WEPP-aligned approximation path in this spec- it is not the only academically defensible long-term erosivity climatology that the mod may eventually support
- the planned
momm2025mode below is complementary rather than contradictory: it targets published RUSLE2 planning climatology, not replay of the run's WEPP storm sequence
Required Computation Path
This path should be a requirement, not an optimization preference.
- Parse the run climate file, or an equivalent storm table carrying the same
storm parameters, including
year,prcp,dur,tp, andip - Reconstruct each storm using WEPP hyetograph segments
- Compute storm kinetic energy
Efrom the reconstructed WEPP hyetograph segments - Compute
I30from the same reconstructed storm - Compute event
EI30 - Sum event
EI30within each simulation year - Average annual
EI30totals across the available simulation years - Output a scalar run-level
R, then materializer.tifas a constant raster on the DEM grid for unmasked hillslope cells
The important guardrail is explicit: E must come from reconstructed WEPP
hyetograph segments. A shortcut that uses precipitation total, a single
exported peak-intensity field, or an external design-storm intensity without
segment-based energy reconstruction is not acceptable as the canonical
cligen_static path.
Existing Local Basis
The repository already has the core ingredients needed for a shared hyetograph implementation and for parity testing against existing Python behavior:
wepppy.climates.cligen.cligen._wepp_hyetograph_segments(...)reconstructs WEPP storm segments as(start_hr, end_hr, intensity_mm_hr)wepppy.climates.cligen.cligen.wepp_peak_intensities_from_hyetograph(...)already computes peak intensities from that reconstructed hyetographclimate/wepp_cli.parquetis already exported with storm parameters and derived intensities, includingprcp,dur,tp,ip,peak_intensity_10,peak_intensity_15,peak_intensity_30, andpeak_intensity_60
climate/wepp_cli.parquet is therefore the right audit and interchange
artifact. It should not be treated as the canonical computational input for
cligen_static R. The .cli file should remain the source of truth, both
because it is the native WEPP climate representation and because breakpoint
climate support is not guaranteed to round-trip through the parquet export.
The required scientific path still runs through segment-based E from the
reconstructed WEPP storm shape.
Implementation Direction
The first production implementation did two related things in
wepppyo3.climate:
- added a reusable Rust WEPP hyetograph reconstruction helper
- built the
cligen_static Rroutine on top of that shared helper
Delivered direction:
- Added a reusable Rust WEPP hyetograph reconstruction helper so existing callsites can adopt the Rust path over time
- Where callsites already have working Python hyetograph logic, Python fallback remained available during migration; new fallback paths were not added where none already existed
- Treated breakpoint-climate hyetograph/intensity support as Rust-first: if no legacy Python fallback path already exists for a breakpoint use case, no new Python fallback was added as part of this package
- Added a
wepppyo3.climateroutine to calculate run-level staticRfrom a WEPP.clifile - Reused the existing Rust climate-file parser in
wepppyo3rather than round-tripping large storm tables through Python - Kept the source of truth as the WEPP
.clifile;wepp_cli.parquetremains an audit artifact rather than an alternate static-Rinput - Did not add a production Python fallback for
cligen_static R; it is implemented directly in Rust once the shared hyetograph helper exists - For this package, cross-repo release synchronization remains limited to the
canonical WEPPpy runtime target:
/workdir/wepppyo3/release/linux/py312/ - Returned at least the mean annual
Rand per-year annual erosivity totals for manifesting and QA - Regression-tested the Rust hyetograph helper against the existing
cligen.pybehavior where comparable, and tested staticRfrom.cliinputs directly in Rust
Implementation status (2026-03-21):
- This scope is completed in
docs/work-packages/20260320_rusle_r_static_hyetograph_api/. wepppyo3.climatenow ships:build_hyetograph_non_breakpoint(...)build_hyetograph_breakpoint(...)compute_peak_intensities_from_hyetograph(...)compute_peak_intensities_non_breakpoint(...)compute_peak_intensities_breakpoint(...)compute_static_r_from_cli(...)
- WEPPpy callsites in
cligen.py, climate artifact export, interchange, and return-period staging are migrated to canonicalpeak_intensity_*outputs.
Static-R v1 Storm Kinetic Energy Contract (Resolved)
For cligen_static v1, storm kinetic energy is fixed to a WEPP/AH537-aligned
SI convention:
- segment intensity
i_mm_hrcomes from reconstructed WEPP hyetograph segments - segment unit energy:
e = 0wheni_mm_hr <= 0e = min(0.119 + 0.0873 * log10(i_mm_hr), 0.283)wheni_mm_hr > 0
eunits:MJ ha^-1 mm^-1- segment depth
delta_v_mmunits:mm - storm energy
E_event = sum(e * delta_v_mm)units:MJ ha^-1 I30_eventunits:mm hr^-1from the max continuous 30-minute window over the same reconstructed storm- event erosivity
EI30_event = E_event * I30_eventunits:MJ mm ha^-1 h^-1
Annual and run-level aggregation:
R_year = sum(EI30_event)over qualifying storms in a simulation yearR_mean = mean(R_year)across available simulation years- v1 reported run-level
RusesR_meaninMJ mm ha^-1 h^-1
Qualifying-storm convention for v1:
- include storms with depth
>= 12.5 mm(0.5 in) - storms below
12.5 mmare excluded until the canonical high-intensity exception path is explicitly implemented
Rationale:
- keeps static
Raligned with WEPP storm-shape energy behavior for this stack (/workdir/wepp-forest/src/idat.for) - avoids introducing a second erosivity-energy convention in the same runtime workflow
RUSLE2Eq. 6.2 (e = 0.29 * (1 - 0.72 * exp(-0.082 * i))) remains a future optional mode, not the v1 default
Resolved Contract: Hyetograph API and Breakpoint Artifact Compatibility
The shared wepppyo3.climate public contract is resolved as:
- ship both low-level segment builders and peak-intensity helpers
- treat peak-intensity helpers as the canonical WEPPpy callsite surface
- keep segment helpers public for static
R(EI30) and parity testing
Preferred public function shape:
build_hyetograph_non_breakpoint(...)build_hyetograph_breakpoint(...)compute_peak_intensities_from_hyetograph(...)- convenience wrappers:
compute_peak_intensities_non_breakpoint(...)compute_peak_intensities_breakpoint(...)
Canonical peak-intensity output keys:
peak_intensity_10peak_intensity_15peak_intensity_30peak_intensity_60
Backward-compatibility contract for climate/wepp_cli.parquet:
- always emit:
dur,tp,ip,storm_duration_hours,storm_duration,peak_intensity_10,peak_intensity_15,peak_intensity_30,peak_intensity_60 - breakpoint rows must carry real
peak_intensity_*values (no-1sentinel) - breakpoint rows keep
tpandipas nullable (NULL/NaN), not synthesized - breakpoint
durandstorm_duration_*derive from breakpoint intervals using WEPP-consistent duration semantics - zero-rain rows keep
peak_intensity_* = 0.0
Migration compatibility policy:
- dual-write canonical snake_case intensity columns and legacy labeled intensity columns during migration
- canonical snake_case becomes producer source of truth
- reader alias tolerance remains until explicit deprecation cleanup
Runtime Scope Boundary
legacy_r_gridis out of the initial runtime pathmrms_ei30is out of the initial runtime pathprism_atlas_regressionis out of the initial runtime pathPRISMandNOAA Atlas 14may still matter upstream when building or revising climate inputs, but they are not directR-factor dependencies for the firstRusledelivery
Planned Additional Runtime Mode: momm2025_county_region
This mode is implemented in the runtime controller.
Purpose:
- give the mod a second
Rpath tied to the public Momm et al. (2025) RUSLE2 isoerodent update for the continental US - keep
cligen_staticas the WEPP-aligned path when the goal is to approximate the erosivity used by WEPP for the run - let users opt into a published planning-climatology source without treating it as the same thing as the run's WEPP climate history
Vendored data assets:
wepppy/nodb/mods/rusle/data/momm2025/momm2025_county_region_monthly_r.parquetwepppy/nodb/mods/rusle/data/momm2025/momm2025_counties_conus_2010_500k.geoparquet
Academic highlights to preserve in implementation notes and manifests:
- the paper updates operational RUSLE2 isoerodent generation for the continental US
- the published workflow is reproducible and updatable rather than dependent on older hand-built surfaces
- the supplement distributes monthly erosivity values because RUSLE2 consumes monthly climate inputs
- the paper highlights small-event handling, spatially varying recurrence intervals, and weighted interpolation
- the improvement claim is mainly smoother spatial and temporal behavior while
staying broadly aligned with official RUSLE2 practice, not a claim that every
location's absolute
Rchanges dramatically
Availability boundary:
- dataset coverage is CONUS plus DC, not Alaska or Hawaii
- the public supplement is county or
REGIONtabular data, not a complete polygonal sub-county map - the county geometry companion in this repo uses the 2010 Census county
vintage because the public dataset still uses FIPS
46113(Shannon County, SD) and51515(Bedford city, VA)
Why it can be better:
- it offers a published and reproducible RUSLE2 planning climatology for CONUS
- it should improve smoothness and updateability relative to older manual or zone-built surfaces
- it is likely most useful near county or climate-zone seams and in areas where the older surface-construction workflow depended more heavily on manual adjustments or sparse-station interpolation
Shortcomings and caveats:
- it is not a WEPP run-specific erosivity reconstruction
- the public supplement does not ship sub-county
REGIONpolygons - the available public files appear to be final tabular outputs, not the full station-processing pipeline or cleaned storm archive
- any implementation that collapses monthly values to a single annual scalar must record that aggregation explicitly
Locked v1 decisions (2026-03-25):
momm2025_county_regionremains on the current scalar-Rcontroller contract rather than invent a gridded erosivity surface from county data- the runtime should select the source county by watershed centroid
- the runtime should sum the selected row's monthly values to annual
Rfor the scalar controller contract while preserving the monthly values in manifest provenance - user-facing provenance wording should stay explicit:
cligen_staticlabel:WEPP Climate-Derived Rcligen_statichelp text:Approximates the erosivity used by WEPP from this run's .cli climate record.momm2025_county_regionlabel:Momm 2025 County Climatologymomm2025_county_regionhelp text:Uses the published Momm et al. (2025) RUSLE2 monthly erosivity climatology for the watershed centroid county.
- provenance fields written by the eventual runtime should include enough
detail to audit the selection, for example:
r_moder_source_labelr_source_purposer_selection_method = watershed_centroidr_selected_fipsr_selected_countyr_selected_regionr_dataset_doir_scalar_units
Resolved runtime contract (2026-03-26):
- counties with multiple public
REGIONrows are resolved by matching the run-localised annual precipitation (inches/year) against the numeric publicREGIONinterval labels - there is no silent fallback to another
Rmode when the annual precipitation reference is unavailable or does not map to exactly one publishedREGIONrow - this keeps the mode truthful to the public data limitation (no shipped
sub-county
REGIONpolygons) while preserving deterministic centroid-county behavior for both single-row and split-row counties
Planned Additional Runtime Mode: canonical_rusle2
This mode is implemented in the runtime controller.
Purpose:
- give the mod a planning-climatology path tied to the vendored official RUSLE2 climate-database release rather than only the newer Momm 2025 update
- expose the official RUSLE2 climate-zone polygons and climate records as a
first-class
Rsource rather than leaving them as reference-only data - keep
cligen_staticas the WEPP-aligned path when the goal is to approximate the erosivity used by WEPP for the run
Vendored data assets:
wepppy/nodb/mods/rusle/data/rusle2/rusle2_official_climate_records.parquetwepppy/nodb/mods/rusle/data/rusle2/rusle2_official_climate_zones.geoparquetwepppy/nodb/mods/rusle/data/rusle2/rusle2_official_source_files.parquet
Why it matters:
- it is the vendored official RUSLE2 planning-climatology baseline, not a post-processed local fit or an indirect proxy
- it provides a broader official coverage footprint than the Momm 2025 CONUS update
- it allows future comparisons between the official baseline and the newer Momm 2025 update without leaving the repo
Shortcomings and caveats:
- it is not a WEPP run-specific erosivity reconstruction
- the official polygon bundle does not cover every official climate-table row
- the official distribution is legacy and required normalization into Parquet or GeoParquet for repo-native use
- some rows expose official
R_MONTHLY, while others require monthly values to be derived from official precipitation and erosivity-density fields - duplicate official climate rows can share one polygon
REC_LINK, so the vendored GeoParquet intentionally carries deterministic selected-record and duplicate-diagnostic fields
Working v1 position:
canonical_rusle2should remain on the current scalar-Rcontroller contract- the runtime should select the official climate zone by watershed centroid against the vendored GeoParquet
- the runtime should use the vendored deterministic selected record for the
matched official
REC_LINKand preserve enough provenance to audit the selection - the user-facing label should be
Canonical RUSLE2 - suggested help text:
Uses the vendored official RUSLE2 climate database and climate-zone polygons at the watershed centroid.
Resolved runtime contract (2026-03-26):
- v1 is limited to polygon-backed official links selected by watershed centroid against the vendored GeoParquet
- centroid hits that resolve to polygons without a climate record are rejected explicitly; there is no silent fallback to table-only rows
- centroid hits that ambiguously intersect multiple
REC_LINKpolygons are rejected explicitly to preserve deterministic provenance - runtime manifest provenance records at least:
selected_rec_linkselected_record_nameselected_record_variantselected_source_zip
Explicit Review Basis
The current interpretation of event-style R approaches in this working
document is based on an explicit review of:
- the local
/workdir/Culvert_web_appimplementation, especiallyculvert_app/utils/subroutine_rusle_analysis.py Panda et al., 2022full textMukherjee et al., 2025full text- USDA-ARS
RUSLE1.06candRUSLE2documentation describing howRis defined in canonicalUSLE/RUSLE
Comparison Note: Panda et al., Mukherjee et al., and Culvert_web_app
The reviewed culvert-vulnerability literature and codebase are useful precedent, but they should be described carefully.
What was reviewed:
Panda et al., 2022states thatRwas developed separately using aNOAA PFDS I30 raster, definesI30as30-min rainfall intensity for a 100-yr storm, and usesR = KE * I30Mukherjee et al., 2025states thatRwas developed separately using aNOAA-Atlas14 30-min 100-yr precipitation intensity (PI30) rasterand usesRi = KEi * PI30i- the local
Culvert_web_appimplementation follows the same general pattern: intersectingNOAA Atlas 1430 min / 100 yrrasters are extracted, resampled to the DEM grid, converted tomm/hr, and passed through a storm energy relation to computeR
What those sources do not appear to say:
- neither
Panda et al., 2022norMukherjee et al., 2025appears to call that method adesign-storm erosivity surrogatein those words - neither source appears to claim that the resulting raster is the canonical
long-term annual
RUSLE Rfactor derived from historical stormEI30sums
Working interpretation for this NoDb spec:
- the label
design-storm erosivity surrogateis our characterization of that method, not wording attributed to Panda or Mukherjee - that characterization is justified because the reviewed method substitutes a
single precipitation-frequency design raster, or a field derived directly
from it, for the canonical annual
RUSLE Rindex - the rainfall kinetic energy equations used in those papers are storm
energy-intensity relations from
USLE/RUSLEerosivity work; they are not annualR-surface fitting equations and they are not themselves a proof that a100-yr / 30-mindesign raster is equivalent to annualR
Conclusion:
- the
Panda/Mukherjee/CULVERTapproach is best treated here as precedent for a separate event-oriented or design-storm-oriented visualization mode - it should not be adopted as the default
Rpath for this NoDb mod if the output is presented as long-term detachment potential under standardRUSLEwording
K
Reviewed Precedents
The current K decisions are based on both primary model references and open
implementation precedents:
RUSLEand NRCSkwfactorkffactdefine the canonical U.S. soil erodibility target for comparison- the
Wischmeiernomograph-style path remains the closest conceptual match to canonicalRUSLE K, but it needs inputs that gridded products often do not supply directly, especially very fine sand, structure class, and profile permeability class SWAT+documents theWilliams (1995)EPICalternative, which is widely used when only texture and organic carbon are availableShojaeezadeh et al. (2024)provide direct CONUS precedent for derivingKfromPOLARISplus ancillary datasets, but also show the approximation burden: structure and permeability must be inferred, and their textural term uses gridded sand and silt rather than a directly observed very-fine-sand fieldRossiter et al. (2022)remain the key caution that fine-gridded digital soil maps are not automatically truer than survey-based products
Locked Mode Strategy
The design should explicitly support three K paths:
polaris_nomograph
- Preferred default for the main
Ruslemap product - Target a fine-earth,
kffact-likeKestimate fromPOLARIS - Best fit when the goal is a spatially informative detachment-potential map
that still speaks the language of
RUSLEand NRCSK
polaris_epic
- Supported as a secondary
POLARISmode, not the default - Use the
Williams (1995)EPICtexture-carbon approximation as documented inSWAT+ - Best fit as a lower-assumption fallback, sensitivity test, or reproducibility
path for users coming from
SWAT,MUSLE, or global gridded erosion studies
gnatsgo_kffact,gnatsgo_kwfact,gssurgo_kffact, orgssurgo_kwfact
- Reference or benchmark modes using NRCS soil-survey
Kfields - Expected to be less spatially variable within soil map units, but more
directly tied to official NRCS
Kinterpretations - Should remain available for comparison, quality review, and sensitivity testing
Interpretation Note
- The practical objective here is a visually interpretable detachment-potential
map with academic backing, not a claim that every sub-map-unit variation in
POLARISis truer than NRCS surveyK Rossiter et al. (2022)explicitly caution that digital soil mapping products, includingPOLARIS, can smooth real soil geography or introduce local artifacts relative to field survey products- Because of that tradeoff, runs should be able to compare
polaris_nomographandpolaris_epicagainst NRCSKproducts over the same area of interest - Most end users are unlikely to have a strong prior preference between
nomographandEPIC; that is an inference from the product goal here, not a cited survey result. The stronger preference is likely to come from technically literate reviewers:RUSLEor NRCS-oriented users will usually prefer the nomograph-facing pathSWAT,MUSLE, or large-area gridded-model users may prefer theEPICpath
- Because of that,
polaris_nomographshould remain the default andpolaris_epicshould be treated as an advanced or sensitivity option rather than a first-choice UI decision
POLARIS Extension Plan
Recent CONUS-scale erosion work has already derived soil erodibility from
POLARIS and related ancillary layers, so the general approach is precedented
and does not need to be invented from scratch.
The current disturbed9002_wbt Polaris fetch was intentionally minimal for
testing. The mod should extend the request set.
Minimum added Polaris properties:
sandsiltclayombdksat
Recommended depths:
0_55_15
The mod should compute a weighted near-surface value rather than relying only
on 0_5. Both polaris_nomograph and polaris_epic should use the same
thickness-weighted near-surface aggregation so comparisons are about the
equation family, not mismatched horizons.
Locked Assumptions by Mode
polaris_nomograph
- This is the preferred first-shipping
POLARISmode - It should be described as a
nomograph-likeorRUSLE-facingemulation, not as a literal reproduction of NRCSkffact - The main reason is data availability: the canonical particle-size term uses
silt plus very fine sand, while
POLARISdoes not provide a directly observed very-fine-sand field - For v1, estimate very fine sand using the
RUSLE2 User Reference Guidefallback equation when only sand, silt, and clay are known:f_vfs = 0.74 * f_sand - 0.62 * f_sand^2- equivalently, in percent units:
vfs_pct = 0.74 * sand_pct - 0.0062 * sand_pct^2
- Clamp the result to
[0, sand_pct]before using it in the nomograph particle-size term - Use that
RUSLE2equation rather than a PSD interpolation or hydraulic pedotransfer back-calculation because it is the only primary-source,RUSLE-native fallback we identified for missing very fine sand - This also fits the product goal better than a more elaborate PSD model:
it keeps the approximation inside the
RUSLE2semantics users are already likely to trust, and it is easier to audit against SSURGOsandvf_rorvfsand_wtavg Shojaeezadeh et al. (2024)show one defensible way to proceed: retain the nomograph family, infer structure and permeability classes from ancillary datasets, and accept a gridded texture approximation in place of literal survey terms- The tool should therefore make the approximation explicit in metadata and
documentation instead of implying that
POLARIScan reproduce NRCSKexactly - Manifest metadata should record that
vfsisrusle2_estimated_from_sand, not an observedPOLARISfield - Structure and permeability classes should be inferred from gridded covariates and documented as modeled classes, not observed survey descriptors
- If no profile coarse-fragment ancillary is supplied, the output should be
labeled and interpreted as a fine-earth,
kffact-like estimate - If a profile coarse-fragment adjustment is applied later, comparisons should
shift toward
kwfact
polaris_epic
- This mode should implement the
Williams (1995)alternative equation as documented bySWAT+ - It should use
POLARISsand,silt,clay, andom, converting organic matter to organic carbon where required by the equation - It should not require structure classes, permeability classes, or very fine sand
- That lower input burden is its main advantage
- Its main limitation is conceptual rather than computational: it is less
directly comparable to NRCS
kwfactorkffactand less obviously aligned with canonicalRUSLE K - For this project, it should therefore be treated as a secondary estimator for fallback, sensitivity, or reproducibility rather than the main default
Rock Fragments and Surface Rock
- First derive a fine-earth,
kffact-likeKestimate fromPOLARIS - Then handle profile rock fragments explicitly rather than letting stoniness silently distort the high-resolution texture signal
- Treat surface rock as a cover effect, not as a direct replacement for soil erodibility
- For v1, the optional profile coarse-fragment ancillary should be the ISRIC
SoilGrids
cfvolayer - That recommendation is pragmatic rather than perfect:
POLARISdoes not provide a directly observed coarse-fragment raster- SoilGrids
cfvois a documented coarse-fragment property with standard depth layers and broad availability - it is suitable as a broad profile-stoniness ancillary for the high-
resolution
POLARISworkflow
- SoilGrids
cfvoshould be interpreted as volumetric coarse fragments incm^3/dm^3(vol‰), with conversion tovol%by dividing stored values by10 - The current SoilGrids FAQ table should be treated as ambiguous for
cfvoconversion because it lists mapped unitscm^3/dm^3 (vol‰)but also lists conversion factor100; those two statements are inconsistent - For this mod, prefer the unit-algebra-consistent interpretation (
/10) and cross-check against live service metadata before changing scale assumptions - It should not be described as a literal
RUSLE2nomograph coarse-fragment input:- SoilGrids
cfvois a volumetric whole-soil coarse-fragment property - the strict
RUSLE2nomograph coarse-fragment input is not the same variable definition
- SoilGrids
- Because of that mismatch,
cfvoshould only support an explicitly labeled approximate profile-fragment adjustment, not a claim of exactkwfactreproduction - The ISRIC
cfvoraster should be reprojected, resampled, and depth-aligned to match thePOLARISgrid before use:- same CRS
- same extent
- same cell alignment
- same target depth support used by the
POLARISnear-surface aggregation - use the matching SoilGrids depth intervals where available, then aggregate
onto the same near-surface support as the
POLARISinputs
- Metadata should retain the native SoilGrids resolution and note that the
aligned
cfvolayer is an upscaled ancillary, not a true 30 m observation - Comparisons should be matched accordingly:
- compare fine-earth
POLARISestimates tokffactwhere available - compare
cfvo-adjusted estimates tokwfactwhere available, while noting the variable-definition mismatch - for direct coarse-fragment plausibility checks, compare against
SSURGO chfrags.fragvol_r(vol%, whole-soil basis), not only against weight-based fragment fields (fraggt10_r,frag3to10_r,sieveno10_r)
- compare fine-earth
Likely ancillary needs beyond the current Polaris request:
- optional ISRIC SoilGrids
cfvoprofile coarse-fragment fraction, aligned to thePOLARISgrid before use - a defensible structure-class mapping
- a defensible permeability-class mapping derived from
ksatand profile conditions
Product Decision
Support both polaris_nomograph and polaris_epic, but do not treat them as
co-equal defaults.
polaris_nomographis the default because it is closer toRUSLEand NRCSKsemantics, which better fits the academic-backing goal of this modpolaris_epicis worth supporting because it is substantially easier to compute from gridded soil products, is precedented in open modeling systems, and provides a useful sensitivity or fallback path when ancillary class mappings are weak or unavailable- In the current first user-facing release, the control exposes both options,
with
polaris_nomographas the default selection andpolaris_epicavailable as an analyst/sensitivity option
Important Distinction
Do not substitute WEPP Ki or Kr, or values from
wepppy/nodb/mods/disturbed/data/disturbed_land_soil_lookup.csv, for RUSLE
K. They are not the same parameter.
C
The C factor needs two source modes that share one common calculation engine.
Common Engine
Initial C is a simplified RUSLE-style cover-management factor driven
by:
- surface protection
- optional canopy, roughness, and consolidation terms later
The first implementation uses:
- a
RUSLE2-style surface-cover subfactor driven by RAP bare ground - canopy set to a neutral default in
observed_rapv1 - roughness, biomass, and consolidation set to neutral defaults unless separate data are introduced
Resolved Contract: Initial observed_rap Formula
The preferred initial observed_rap formula is a simplified RUSLE2 ground-
cover path, not an NDVI -> C regression and not a land-cover lookup table.
Use:
fg = clamp(100 - bare_ground_pct, 0, 100)as net ground cover percentC = exp(-b * fg)withb = 0.04for the initial implementationcanopy = 1.0,roughness = 1.0,biomass = 1.0, andconsolidation = 1.0inobserved_rapv1
Rationale:
RUSLE2defines the ground-cover subfactor as an exponential reduction in erosion with increasing net ground cover, and explicitly notes that net ground cover is effectively100 - bare ground- RAP directly observes
bare_ground,litter, and live fractional-cover components, but it does not directly observe theRUSLE2canopy inputs needed for a more defensible canopy subfactor, especially effective fall height and the split between above-ground canopy and live ground cover - using RAP bare ground as the primary control keeps litter and exposed interspace as first-class drivers, which is especially important for post-fire and semiarid rangeland conditions
NDVI -> Ctransforms are a weaker fit here because RAP already provides more physically relevant cover fractions than a greenness index, and review literature notes that broadNDVIformulas can behave unrealistically for grassland and woodland classes
Use RAP fractions as follows in observed_rap v1:
bare_groundis the direct input tofglitter,annual_forb_and_grass,perennial_forb_and_grass,shrub, andtreeare retained for QA, masking interpretation, and future canopy or roughness extensions- do not sum RAP fractional bands into a separate surface-cover term;
RUSLE2wants net ground cover rather than a potentially double-counted component sum
Mode 1: observed_rap
Use observed RAP fractional cover as the main condition source.
Best fit:
- current condition
- recent post-fire condition
- monitoring mode
Interpretation cautions:
- post-fire RAP vegetation recovery should not automatically imply a strongly
protective
C - litter and bare ground must remain first-class controls
Mode 2: scenario_sbs
Restrict this mode to runs where the Disturbed module is active.
Use explicit lookup values keyed by:
- canonical
disturbed_classfamily from the disturbed workflow - SBS class
Initial implementation choice:
- static low/moderate/high severity lookups only
- no time axis in v1
- add a time axis later only if a separate recovery-trajectory package defines and validates it against observations
Resolved contract:
scenario_sbsis a disturbed-only mode; do not expose it for generic runs that do not have the disturbed/SBS workflow active- use the disturbed workflow's canonical vegetation family instead of generic
landuse_class - normalize disturbed classes before lookup so the key space stays small and
stable:
forestandyoung forest->forest- shrub classes ->
shrub - grass classes ->
tall_grass
- do not key the lookup by severity-specific or treatment-suffixed raw
disturbed_classstrings such asforest moderate sev fire,forest high sev fire-mulch_15, orthinning; severity remains the separatesbs_classdimension
Required Raster Preprocessing
Rusle is raster/cell based, so scenario_sbs needs a gridded
disturbed_class product on the run DEM grid.
- create
rusle/disturbed_class.tifas a DEM-aligned raster of canonical disturbed-class family labels or integer codes - do not reuse the hillslope-level disturbed assignment directly; the existing
Disturbedworkflow maps classes to hillslopes, which is sufficient for WEPP input generation but not for rasterRUSLE C - build the gridded disturbed-class raster from the same landuse-to-disturbed
semantics used by
wepppy/wepp/management/data/disturbed.json - normalize to canonical families before applying SBS:
forestandyoung forest->forestshrub->shrubtall grass->tall_grass
- only apply SBS burn remapping to these three canonical families
- leave all other classes unchanged by SBS severity and handle them according to the non-burnable-class policy table below
Initial scenario_sbs Static Matrix
The first scenario_sbs implementation ships with an explicit static
matrix for the burnable canonical disturbed classes. These values are initial
defaults for rusle_c_lookup.csv, derived from the same simplified
RUSLE2-style form used elsewhere in this spec:
C = exp(-0.04 * fg)fgtaken from the static disturbed management ground-cover defaults
| Canonical disturbed class | Unburned | Low | Moderate | High | Notes |
|---|---|---|---|---|---|
forest |
0.0183 |
0.0334 |
0.0907 |
0.3010 |
includes young forest; initial fg = 100, 85, 60, 30 |
shrub |
0.0273 |
0.0408 |
0.1108 |
0.3010 |
initial fg = 90, 80, 55, 30 |
tall_grass |
0.0907 |
0.0907 |
0.2466 |
0.6703 |
initial fg = 60, 60, 35, 10 |
Rationale for these initial defaults:
- the values are not arbitrary lookup guesses; each row is computed directly
from the existing static disturbed management defaults already documented in
wepppy/nodb/mods/disturbed/README.md - for this initial
scenario_sbspath,fgis taken from the static near-surface cover state (inrcov/rilcov) rather than canopy cover because the v1Ccontract in this spec is intentionally a simplifiedRUSLE2ground-cover formulation - the severity progression follows the existing disturbed management templates:
- forest ground cover declines
1.00 -> 0.85 -> 0.60 -> 0.30 - shrub ground cover declines
0.90 -> 0.80 -> 0.55 -> 0.30 - tall-grass ground cover declines
0.60 -> 0.60 -> 0.35 -> 0.10
- forest ground cover declines
- those cover fractions are converted to percent (
100,85,60,30, etc.) and then mapped throughC = exp(-0.04 * fg) - this means the matrix is anchored to the same disturbed scenario semantics
that already drive WEPP management behavior, which keeps the first raster
scenario_sbsimplementation directionally consistent with the existing disturbed package rather than introducing a second, unrelated burn-severity interpretation - the forest and shrub rows show monotonic erosion-protection loss from unburned to high severity because the underlying disturbed management templates already reduce near-surface cover that way
- the
tall_grassunburned and low-severity rows are intentionally identical in v1 because the current disturbed management defaults assign the same ground-cover state (0.60) to both classes; if future validation shows that low-severity grass should diverge, the lookup table can be revised without changing the runtime contract young forestis folded into the canonicalforestfamily to keep the lookup key space small and becausescenario_sbsis keyed by canonical disturbed family plus severity, not by every management variant
These values are defaults, not permanent calibration truth. The matrix should
live in rusle_c_lookup.csv so future package work can revise it without
changing the runtime contract.
Non-Burnable NLCD / Disturbed-Class Policy
The classes below do not participate in the SBS burn matrix even when
scenario_sbs is active.
| NLCD classes | Disturbed mapping / family | SBS handling | C handling |
|---|---|---|---|
11, 21, 22, 23, 24, 90, 95 |
water, developed, wetlands | no burn | masked; C = nodata |
12 |
perennial ice/snow / no disturbed class | no burn | treat as out-of-domain and mask in scenario_sbs |
31 |
bare |
no burn | static row only; initial default C = 1.0 |
73, 74 |
short_grass |
no burn | static row only; initial default C = 0.2019 |
81, 82 |
agriculture_crops |
no burn | require explicit unburned lookup rows; do not infer wildfire severity effects |
any other unmasked class not normalized to forest, shrub, or tall_grass |
class-specific | no burn | require explicit unburned lookup row or fail fast |
Best fit:
- counterfactual pre-fire versus post-fire comparisons
- planning mode
- cases where observed RAP does not represent the scenario being compared
Lookup Recommendation
Do not overload disturbed_landsoil_lookup.csv for RUSLE C.
Create a dedicated lookup, for example:
wepppy/nodb/mods/rusle/data/rusle_c_lookup.csv
Suggested fields:
disturbed_classsbs_classnlcd_classcanopy_coverground_coverlitter_coverrock_covereffective_fall_heightc_overridenotes- optional future field:
years_since_disturbance
P
Initial default:
P = 1.0
Only vary P when explicit support-practice or treatment data exist. Avoid
invented P values.
Potential future P inputs:
- contouring
- terracing
- skid-trail treatment classes
- road drainage or hydrologic disconnection treatments
Controller Design
Controller: Rusle
Responsibilities:
- validate required run products and factor source availability
- acquire or align factor inputs to the run DEM grid
- build hillslope mask
- compute factor rasters
- compute final
Araster - persist run-scoped artifacts under
<wd>/rusle/ - expose metadata and summaries through NoDb and catalog entry updates
Current dependencies:
RonWatershedLanduseClimateDisturbed- internal
PolarisNoDb substrate for aligned soil-property rasters - internal single-year RAP raster retrieval built on the RAP dataset access
layer, but not on the
raporrap_tsNoDb mods wepppyo3.climatestaticRroutine
Config Direction
Initial development branched from disturbed9002_wbt rather than changing it
in place.
Possible extended config additions (beyond the currently consumed runtime options):
[nodb]
mods = ["disturbed", "debris_flow", "ash", "treatments", "polaris", "rusle"]
[rusle]
enabled = true
ls_mode = "wbt_rusle"
ls_routing = "dinf"
r_mode = "cligen_static"
# additional planning-climatology modes:
# r_mode = "momm2025_county_region" # watershed-centroid county + annual-precip REGION bin
# r_mode = "canonical_rusle2" # watershed-centroid official polygon (polygon-backed only)
k_mode = "polaris_nomograph"
c_mode = "observed_rap"
rap_year = "auto"
p_mode = "default"
mask_nlcd_water = true
mask_nlcd_urban = true
mask_nlcd_wetlands = true
mask_channels = true
max_slope_length_m = 304.8
The scientific defaults above remain the current working position. Optional
operational controls such as max_slope_length_m should still only change with
explicit validation and documented rationale.
Because polaris currently exists only to support rusle, its runtime default
request is shifted to the Rusle K layer set rather than the earlier minimal
test request:
- properties:
sand,silt,clay,om,bd,ksat - statistics:
mean - depths:
0_5,5_15
User Specification
Availability and Activation
Rusleis a user-toggleable optional mod in the run-headerModsmenu for disturbed projects- eligibility uses the presence of the
disturbedmod and the WBT delineation backend;Rusleis not presented as a generic mod for unrelated run types - enabling
rusleensures the internalpolarissubstrate is available for the run - enabling
rusledoes not auto-addraporrap_ts disturbedis already treated as non-removable for this project class, sorusledoes not need a separatedisturbedremoval guardpolarisdoes not have its own user-facing mods toggle or dedicated run-page section in this workflow- enabling
rusleonly registers/reveals the workflow; it does not trigger a background build automatically - disabling
rusleremoves onlyrusle; cleanup of internalpolarisstate remains an implementation detail rather than a user-facing contract
Run-Page Placement
- includes a dedicated
RUSLEnavigation entry and control section on the run page - appears after
WEPP - follows the standard
control_shellpattern:- status area
- stacktrace area
- job hint
- build/refresh action
- concise method summary
- target UX still includes showing prerequisite readiness for at least:
- DEM/watershed
- landuse
- climate
- disturbed
Required v1 Controls
- build/refresh button for the run-scoped
RUSLEartifacts - build/refresh enqueues an RQ job rather than running inline in the request cycle
Cmode selector:observed_rapscenario_sbs
- default
Cmode in the first user-facing release isobserved_rap RAPyear selector shown only whenc_mode = observed_rap- single year only
- valid year choices come from the same RAP implementation surface used by rap.py, which remains the source of truth for supported single-year RAP availability
- default is the latest available completed RAP year unless a saved
rusle.rap_yearalready exists
Kmode selector:polaris_nomographdefaultpolaris_epicsupported sensitivity option
Additional v1 Controls Worth Exposing
LSrouting selector in an advanced section:dinfdefaultfd8optional sensitivity path- keep
d8out of the ordinary UI unless it is intentionally added as a comparison-only analyst mode
max_slope_length_mnumeric input in an advanced section, default304.8- masking toggles in an advanced section:
mask_nlcd_watermask_nlcd_urbanmask_nlcd_wetlandsmask_channels
Fixed or Read-Only Method Rows
These should be shown as method summary rows rather than user-editable fields in the first release:
LS mode = wbt_rusleR mode = cligen_staticR mode = momm2025_county_region(split counties resolved by annual-precip REGION bin)R mode = canonical_rusle2(polygon-backed official links only in v1)P mode = default(1.0)
scenario_sbs User-Facing Contract
scenario_sbsconsumes the disturbed workflow's SBS state; do not add a second SBS upload control inside theRuslepanelscenario_sbsstays fixed to the canonical RUSLE disturbed-family policy and does not inherit optional Disturbed runtime knobs such as shrub/grass burn toggles- when a disturbed/BAER SBS map exists, use it
- when no SBS map exists,
scenario_sbsremains allowed and usesunburnedlookup parameters everywhere - the UI surfaces that state explicitly, for example:
No SBS map detected; using unburned parameters. - the gridded
disturbed_classraster remains required and must still be derived on the DEM grid from the disturbed mapping; do not substitute the hillslope-only disturbed assignment
observed_rap User-Facing Contract
Rusleretrieves the selected single-year RAP raster directly for the run- reuse the low-level RAP dataset access layer, but do not require the
raporrap_tsNoDb modules to be enabled or instantiated - store the retrieved RAP raster under the run-scoped
rusle/tree and record the selected year in manifest/catalog metadata - reuse an existing aligned RAP artifact only when the saved artifact matches the requested year and the current run extent/alignment contract; otherwise refresh it explicitly
Internal polaris Acquisition Contract
- there is no separate
POLARISUI forRusleusers in v1 - when a
Ruslebuild needsKinputs, the controller checks whether the aligned requiredPOLARISlayers already exist for the run - if required aligned layers are missing,
Ruslecalls the existingPolarisNoDb controller automatically - the automatic request targets the
Rusle Ksubstrate layer set:- properties:
sand,silt,clay,om,bd,ksat - statistics:
mean - depths:
0_5,5_15
- properties:
- even if
Polarisdefaults are changed to match theRusle Krequest, theRuslecontroller still passes an explicit acquisition payload so the build remains deterministic and self-describing in manifest history - if the existing
polaris/manifest.jsondoes not satisfy the required layer set or alignment contract,Ruslerefreshes the missing or drifted layers explicitly rather than assuming the currentpolaris/tree is valid - this remains idempotent:
- if the required aligned layers already exist and satisfy the request,
Ruslereuses them without re-fetching
- if the required aligned layers already exist and satisfy the request,
Build Scope Contract
- the standard
Ruslebuild writes only the selected active-mode outputs for user-facing factors, not every alternate estimator - specifically:
- selected
Kmode outputs only - selected
Cmode output only - active
LS,R,P, and finalAoutputs
- selected
- inactive comparison artifacts are reserved for explicit future comparison/debug workflows so ordinary users are less likely to browse or download the wrong raster by mistake
Artifact Naming Contract
- user-facing factor artifacts use mode-specific filenames rather than only generic names, so browsing/downloading makes the active estimator obvious
- generic aliases may still exist for internal convenience, but mode-specific names should be the primary auditable outputs
GL-Dashboard Output Visualization Contract
Rusleoutputs are discoverable in the rungl-dashboardas raster overlays when corresponding run artifacts exist- the layer list includes a dedicated
RUSLEsection under subcatchment overlays, placed afterWEPP RUSLElayer discovery is artifact-driven (only show rasters that are present), with mode-specific filenames as the primary selectors:A:a_observed_rap_polaris_nomograph.tif,a_observed_rap_polaris_epic.tif,a_scenario_sbs_polaris_nomograph.tif,a_scenario_sbs_polaris_epic.tifC:c_observed_rap.tif,c_scenario_sbs.tifK:k_polaris_nomograph.tif,k_polaris_epic.tif
- colormap and legend contract:
Ausesjet2, unitst/ha/yr, and a dynamic legend range derived from finite raster values for the active artifactCusesviridis, unitsunitless, and fixed legend range[0, 1]Kusesplasma, unitst*ha*h/(ha*MJ*mm), and current fixed range[0, 0.7]pending future validation updates
- raster NoData behavior in
gl-dashboardis transparent; NoData and non-finite cells render withalpha = 0so they do not mask valid outputs - raster tooltips use the standard raster pattern (layer path plus sampled pixel value) with no custom one-off tooltip contract
Preflight and Staleness Contract
Rusleintegrates with the preflight system as its own checklist item- a dedicated
TaskEnumentry exists for the mainRuslebuild and uses the🔱emoji in TOC/preflight surfaces - initial stale/invalidating events include:
- climate rebuild
- SBS map removal
- SBS map replacement or modification
- stale
Ruslestate clears its preflight-complete indicator until the user rebuilds
Failure UX Contract
- follows the existing control pattern for asynchronous failures:
- concise status message in the control
- stacktrace/details panel for deeper error information
- no custom one-off error presentation for
Rusle
Inputs Explicitly Out of Scope for v1 UI
m_regime- NRCS benchmark/reference
Kmodes - explicit
cfvocoarse-fragment adjustment controls - raw
POLARISproperty/statistic/depth selection controls - custom
scenario_sbslookup-table editing inside theRuslepanel
Source Precedence
Recommended initial precedence:
LS- purpose-built WBT
RusleLsFactor
- purpose-built WBT
R- current shipped mode:
cligen_staticfrom the run WEPP climate file when the goal is to approximate the erosivity used by WEPP - additional mode:
canonical_rusle2from the vendored official RUSLE2 climate zones and climate records when the goal is the canonical official planning-climatology baseline - additional mode:
momm2025_county_regionfrom the vendored CONUS county orREGIONmonthly climatology when the goal is a published RUSLE2 planning-climatology reference - no external gridded runtime source should be implied until the
split-county
REGIONspatialization contract is explicitly resolved
- current shipped mode:
Kpolaris_nomographfor default visualization modepolaris_epicfor advanced fallback or sensitivity modegnatsgo_kffact,gnatsgo_kwfact,gssurgo_kffact, orgssurgo_kwfactfor benchmark or reference mode
Cobserved_rap- or
scenario_sbs
P1.0unless explicit treatment/practice inputs exist
Validation Expectations
At minimum, validation should include:
- factor sanity checks by landscape position
- masked-versus-unmasked comparison review
- parity checks between the shared Rust hyetograph helper and the existing Python hyetograph behavior where comparable
- static-
Rregression tests from.cliinputs, including breakpoint-climate coverage if supported by the Rust parser path - annual
EI30distribution review for representative climates canonical_rusle2centroid-selection andREC_LINKprovenance tests if that mode is enabled- explicit canonical table-only acceptance or rejection tests for unsupported official rows
momm2025county-selection and multi-county aggregation tests if that mode is enabled- explicit split-county
REGIONacceptance or rejection tests for the public Momm 2025 mode - known hotspot comparison against field or mapped observations
polaris_nomographversuspolaris_epiccomparison on representative areas of interestpolaris_nomographorpolaris_epicversus NRCSkffactorkwfactcomparison on representative areas of interest, matched to the fragment assumption actually used- pre-fire/post-fire directional checks
- sensitivity checks for
LS,R, andC - sensitivity checks across
Kestimators where the differences materially affect the map pattern cfvo-adjusted versus fine-earthPOLARISKcomparison where the profile rock-fragment option is enabled
Longer term, the mod should be checked against:
- post-fire erosion monitoring plots
- sediment fence or trap datasets
- independent erosivity references where appropriate
- known disturbed hillslope inventories
Resolved Open Questions
- The preferred initial
Cformula forobserved_rapis the simplifiedRUSLE2surface-cover formC = exp(-0.04 * fg)wherefg = clamp(100 - bare_ground_pct, 0, 100). scenario_sbssupports static low/moderate/high severity lookups in v1, with no time axis until recovery trajectories are defined and validated.scenario_sbsis restricted to disturbed runs and keyed by canonicaldisturbed_classfamily plussbs_class, not genericlanduse_class.
Resolved Implementation Choices
LSuses a handbook-based defaultmax_slope_length_m = 304.8- DEM input is assumed hydrologically sound;
RusleLsFactorfails fast rather than condition DEMs internally - Stop-mask routing semantics are fixed: terminal sinks, no renormalization of terminated multi-flow fractions
Rstatic-cligenstorm energy uses the WEPP/AH537-aligned SI convention:e(i) = min(0.119 + 0.0873*log10(i_mm_hr), 0.283)withe = 0fori <= 0- Shared hyetograph API surface is dual-layer: segment builders plus peak-intensity helpers, with peak helpers as canonical WEPPpy callsite surface
- Breakpoint climate artifact compatibility is fixed: real
peak_intensity_*values, nullabletp/ip, derived breakpointdur, and no sentinel-1intensities - Initial
observed_rapCuses the simplifiedRUSLE2surface-cover formC = exp(-0.04 * fg)withfg = clamp(100 - bare_ground_pct, 0, 100)and neutral canopy/roughness/biomass/consolidation terms in v1 scenario_sbsv1 uses static severity lookups only; no time axis until a separate recovery-trajectory path is defined and validatedscenario_sbsis restricted to disturbed runs and uses canonicaldisturbed_classfamily plussbs_classas its lookup keyscenario_sbsrequires a DEM-aligned griddeddisturbed_classraster and only applies SBS burn remapping to canonicalforest,shrub, andtall_grassfamilies- user-facing
scenario_sbsremains available when no SBS map is present; that case must use explicitunburnedparameters everywhere rather than failing or silently changing modes Rusleretrieves single-year RAP internally forobserved_rapand does not depend on theraporrap_tsNoDb mods- enabling
ruslefrom the UI auto-addspolariswhen needed - first-release
RusleUI eligibility is keyed to the presence of thedisturbedmod - enabling
ruslereveals/registers the workflow but does not trigger a build automatically - default first-release user selection remains
c_mode = observed_rap scenario_sbsremains independent of optional Disturbed runtime burn toggles and uses the fixed canonical RUSLE disturbed-family policyRuslepasses an explicitPolarisacquisition payload even if the underlyingPolarisdefaults match the same layer set- valid
observed_rapyear choices are sourced from the RAP implementation surface used byrap.py, with latest available completed year as the default when the user has not saved an override - standard user-facing builds emit only selected active-mode outputs, so inactive estimator rasters are not surfaced by default
- the
Ruslecontrol appears afterWEPPon the run page Ruslebuilds run through RQRusleintegrates with preflight using a dedicatedTaskEnumentry and🔱emoji- initial
Ruslestaleness invalidators are climate rebuild plus SBS removal or change - user-facing artifacts prefer mode-specific filenames
scenario_sbswithout an SBS map does not emit a synthetic all-unburnedsbs_4class.tifartifact by defaultRuslefailure UX follows the standard status-plus-stacktrace control patterngl-dashboardexposes run-scopedRUSLEA/C/Krasters in a dedicated section afterWEPP, using factor-specific colormaps (A=jet2,C=viridis,K=plasma)gl-dashboardRUSLEAlegends auto-range from the active raster's finite values, whileCandKuse fixed validated rangesgl-dashboardraster NoData cells render transparent forRUSLEoverlays
Initial Milestones
Status update (2026-03-21):
- Milestone 1 completed in
docs/work-packages/20260320_rusle_ls_factor_wbt/. - Milestones 2-3 completed in
docs/work-packages/20260320_rusle_r_static_hyetograph_api/. - Milestone 4 completed in
docs/work-packages/20260321_rusle_k_polaris_implementation/. - Milestone 5 completed in
docs/work-packages/20260321_rusle_c_modes_implementation/. - Milestones 6-7 completed in
docs/work-packages/20260321_rusle_nodb_ui/.
- Created the WBT
RusleLsFactortool withDesmet-GoversL,McCool/RUSLES,DInfdefault routing, and diagnostic outputs; then validated outputs on representative disturbed terrain. - Added a reusable Rust WEPP hyetograph reconstruction helper to
wepppyo3.climateand validated it against existing Python behavior where comparable. - Implemented a
wepppyo3.climatestatic-Rroutine from WEPP.cliinputs using that helper, with no production Python fallback. - Extended Polaris acquisition for
polaris_nomographandpolaris_epic, starting with the nomograph-facing path, paired NRCSKbenchmark support, and optional aligned SoilGridscfvosupport for profile- fragment adjustment. - Defined the shared
Cengine and the two source modes. - Implemented the
RusleNoDb controller and run-scoped artifact layout. - Added validation runs using
disturbed9002_wbt-style workflows.
Related Local Files
wepppy/nodb/configs/disturbed9002_wbt.cfgwepppy/nodb/mods/polaris/polaris.pywepppy/nodb/mods/rap/rap.pywepppy/nodb/core/landuse.pywepppy/climates/cligen/cligen.pywepppy/wepp/interchange/_utils.pywepppy/nodb/mods/disturbed/data/disturbed_land_soil_lookup.csv/workdir/wepppyo3/cli_revision/src/lib.rs/workdir/weppcloud-wbt/whitebox-tools-app/src/tools/terrain_analysis/sediment_transport_index.rs
References and Data Sources
These references are the current basis for academic defensibility in this
working specification. Upstream climate-source products may still matter when
building WEPP climate files, but they are intentionally not treated as direct
runtime R inputs in the current Rusle design.
Core RUSLE Basis
- Renard, K. G., Foster, G. R., Weesies, G. A., McCool, D. K., and Yoder,
D. C., coordinators, 1997. Predicting Soil Erosion by Water: A Guide to
Conservation Planning with the Revised Universal Soil Loss Equation
(RUSLE). USDA Agriculture Handbook No. 703.
Canonical
RUSLE1reference for factor definitions and standard practice. - USDA-ARS. RUSLE2 Science Documentation.
https://www.ars.usda.gov/ARSUserFiles/60600505/rusle/rusle2_science_doc.pdf
Primary science reference for
RUSLE2, especially the cover-management factor and its canopy and ground-cover subfactors. - USDA-NRCS. RUSLE2 Handbook. https://www.nrcs.usda.gov/sites/default/files/2022-10/RUSLE2%20Handbook_0.pdf Operational guidance on factor selection, application limits, and hillslope profile framing.
- USDA-NRCS. National Agronomy Manual.
https://www.nrcs.usda.gov/sites/default/files/2022-10/National-Agronomy-Manual.pdf
NRCS planning context for
RUSLE-family use and conservation practice interpretation.
LS Factor and Rasterization
- Desmet, P. J. J., and Govers, G., 1996. A GIS procedure for automatically
calculating the USLE LS factor on topographically complex landscape units.
Journal of Soil and Water Conservation, 51(5), 427-433.
Canonical raster
L-factor reference for upslope-area-basedLScalculation. - McCool, D. K., Brown, L. C., Foster, G. R., Mutchler, C. K., and Meyer,
L. D., 1987. Revised Slope Steepness Factor for the Universal Soil Loss
Equation. Transactions of the ASAE, 30(5), 1387-1396.
https://doi.org/10.13031/2013.30576
Canonical
S-factor reference for the two-segmentRUSLEsteepness relationship and the separate short-slope branch that is intentionally not used in this 30 m gridded v1 design. - McCool, D. K., Foster, G. R., Mutchler, C. K., and Meyer, L. D., 1989.
Revised slope length factor for the universal soil loss equation.
Transactions of the ASAE, 32(5), 1571-1576.
https://doi.org/10.13031/2013.31192
Canonical
RUSLEreference for the slope-length exponent formulation used with rasterizedL. - Nearing, M. A., 1997. A Single, Continuous Function for Slope Steepness
Influence on Soil Loss. Soil Science Society of America Journal, 61(3),
917-919.
https://doi.org/10.2136/sssaj1997.03615995006100030029x
Continuous steep-slope alternative reviewed for this specification but not
adopted in the v1
LSmethod. - Tarboton, D. G., 1997. A new method for the determination of flow
directions and upslope areas in grid digital elevation models.
Water Resources Research, 33(2), 309-319.
https://doi.org/10.1029/96WR03137
Scientific basis for
D-infinityrouting and specific catchment area. - Panagos, P., Borrelli, P., and Meusburger, K., 2015.
A New European Slope Length and Steepness Factor (LS-Factor) for Modeling
Soil Erosion by Water. Geosciences, 5(2), 117-126.
https://doi.org/10.3390/geosciences5020117
Open-access precedent for implementing
Desmet and Govers (1996)with a multiple-flow algorithm at continental scale and for avoiding arbitrary global slope-length caps. - Benavidez, R., Jackson, B., Maxwell, D., and Norton, K., 2018.
A review of the (Revised) Universal Soil Loss Equation ((R)USLE): with a
view to increasing its global applicability and improving soil loss
estimates. Hydrology and Earth System Sciences, 22, 6059-6086.
https://doi.org/10.5194/hess-22-6059-2018
Review of
RUSLEfactor choices, limitations, and common rasterizedLSimplementations in complex terrain.
Open-Source LS Implementation Precedents
- GRASS GIS. r.watershed manual.
https://grass.osgeo.org/grass-stable/manuals/r.watershed.html
Useful open implementation precedent for default multiple-flow routing,
blocking, andmax_slope_lengthcontrols. The manual also makes clear that itsLSequations are not the exact canonicalDesmet and Govers (1996)raster path adopted here. - SAGA GIS. Tool Library Documentation: LS-Factor, Field Based.
https://saga-gis.sourceforge.io/saga_tool_doc/9.9.2/ta_hydrology_25.html
Useful open implementation precedent for exposing
Desmet and Govers (1996)as a named method and for handling aspect-dependent specific catchment area.
R Factor and Precipitation Data
- Wischmeier, W. H., and Smith, D. D., 1978. Predicting Rainfall Erosion
Losses: A Guide to Conservation Planning. USDA Agriculture Handbook No. 537.
Canonical
USLEreference for erosivity and the storm energy-intensity basis ofEI30. - USDA-ARS. Revised Universal Soil Loss Equation 1.06c: Description of
RUSLE1.06c.
https://www.ars.usda.gov/southeast-area/oxford-ms/national-sedimentation-laboratory/watershed-physical-processes-research/docs/revised-universal-soil-loss-equation-106-description-of-rusle106c/
Useful USDA summary of
Ras the average annual sum of individual storm erosivity values. - USDA-ARS. General Description of the CLIGEN Model and its History.
https://www.ars.usda.gov/ARSUserFiles/50201000/WEPP/cligen/cligendescription.pdf
Official description of
CLIGENas the WEPP stochastic weather generator and of its storm-parameter outputs, including storm duration, time to peak, and peak intensity. - Momm, H. G., McGehee, R. P., and coauthors, 2025.
Isoerodent surfaces of the continental US for conservation planning with the
RUSLE2 water erosion model. Catena, 249, 108879.
https://doi.org/10.1016/j.catena.2025.108879
Primary reference for the planned
momm2025mode: monthly CONUS RUSLE2 isoerodent update with reproducible interpolation workflow and smoother operational surfaces. - USDA ARS Agricultural Data Commons. Data from: Isoerodent surfaces of the
continental US for conservation planning with the RUSLE2 water erosion
model.
https://doi.org/10.15482/USDA.ADC/28821569.v1
Public dataset reference for the vendored
momm2025Parquet and GeoParquet inputs used in this repo. - Panda, S. S., Amatya, D. M., Grace, J. M., Caldwell, P., and Marion, D. A.,
2022. Extreme precipitation-based vulnerability assessment of road-crossing
drainage structures in forested watersheds using an integrated environmental
modeling approach. Environ. Model. Softw., 155, 105413.
https://doi.org/10.1016/j.envsoft.2022.105413
Important precedent for an event-oriented
Rworkflow using aNOAA PFDS I30raster rather than a canonical annual erosivity surface. - Mukherjee, S., Grushecky, S., Aust, W. M., Wang, J. J., Amatya, D. M.,
Caldwell, P. V., Marion, D. A., Grace, J. M., and Panda, S. S., 2025.
Hydro-geomorphological assessment of culvert vulnerability to flood-induced
soil erosion using an ensemble modeling approach. Environ. Model. Softw.,
183, 106243.
https://doi.org/10.1016/j.envsoft.2024.106243
Follow-on paper that states the
NOAA-Atlas14 30-min 100-yrPI30workflow and the piecewise kinetic-energy relation used in the culvert-model lineage.
K Factor and Soil Data
- Chaney, N. W., Minasny, B., Herman, J. D., Nauman, T. W., Brungard,
C. W., Morgan, C. L. S., McBratney, A. B., Wood, E. F., and Yimam, Y.,
2019. POLARIS Soil Properties: 30-m Probabilistic Maps of Soil Properties
Over the Contiguous United States. Water Resources Research, 55(4),
2916-2938.
https://doi.org/10.1029/2018WR022797
Primary reference for what
POLARISis, how it was built, and why it can supply finer spatial variability than polygon soil-survey products. - ISRIC. SoilGrids FAQs.
https://docs.isric.org/globaldata/soilgrids/SoilGrids_faqs_01.html
Primary reference for SoilGrids property semantics and standard depth layers.
Note: the current
cfvorow is internally ambiguous (cm^3/dm^3 (vol‰)is listed with conversion factor100), so conversion assumptions should be cross-checked against live service metadata. - ISRIC. SoilGrids
cfvoWMS capabilities. https://maps.isric.org/mapserv?map=/map/cfvo.map&SERVICE=WMS&REQUEST=GetCapabilities Live metadata reference used to verifycfvolayer naming and volumetric unit semantics (cm^3/dm^3/vol‰). - ISRIC. FAQ - WoSIS.
https://docs.isric.org/globaldata/wosis/faq-wosis.html
Official definition reference for
CFVOas volumetric coarse fragments in the whole soil. - USDA-NRCS. Gridded Soil Survey Geographic (gSSURGO) Database.
https://www.nrcs.usda.gov/resources/data-and-reports/gridded-soil-survey-geographic-gssurgo-database
Preferred U.S. gridded soil product when
kwfactorkffactcoverage is suitable. - USDA-NRCS. Gridded National Soil Survey Geographic Database (gNATSGO).
https://www.nrcs.usda.gov/resources/data-and-reports/gridded-national-soil-survey-geographic-database-gnatsgo
U.S. national gridded soil product and likely broad-coverage fallback to
gSSURGO. - USDA-NRCS. Soil Data Access Related Tables: Table Column Descriptions.
https://sdmdataaccess.nrcs.usda.gov/documents/TableColumnDescriptionsReport.pdf
Official definitions for
kwfactandkffact, including the distinction thatkwfactincludes rock-fragment adjustment. - SWAT+ Documentation. Soil Erodibility Factor.
https://swatplus.gitbook.io/io-docs/theoretical-documentation/section-4-erosion/sediment/musle/soil-erodibility-factor
Official open documentation for both the
Wischmeiernomograph-style equation and theWilliams (1995)EPICalternative used here as the secondaryPOLARISestimator. - USDA-ARS. RUSLE2 User Reference Guide.
https://www.ars.usda.gov/ARSUserFiles/60600505/RUSLE/RUSLE2_User_Ref_Guide.pdf
Primary source for the fallback very-fine-sand estimation equation used here
when only sand, silt, and clay are available for the
polaris_nomographpath. - Rossiter, D. G., Poggio, L., Beaudette, D., and Libohova, Z., 2022.
How well does digital soil mapping represent soil geography? An
investigation from the USA. SOIL, 8, 559-586.
https://doi.org/10.5194/soil-8-559-2022
Important caution that
POLARISand other digital soil mapping products can smooth local soil geography or introduce artifacts relative to field-survey products. - Shojaeezadeh, S. A., Al-Wardy, M., Nikoo, M. R., Ghorbani Mooselu, M.,
Alizadeh, M. R., Adamowski, J. F., Moradkhani, H., Alamdari, N., and
Gandomi, A. H., 2024. Soil erosion in the United States: Present and future
(2020-2050). Catena, 242, 108074.
https://doi.org/10.1016/j.catena.2024.108074
Open preprint with method detail:
https://opus.lib.uts.edu.au/bitstream/10453/167179/2/2207.06579v1.pdf
Recent CONUS-scale precedent for deriving soil erodibility from
POLARISand ancillary soil datasets rather than relying only on polygon-based NRCSKvalues. The preprint method details are also useful because they show the practical approximation burden of aPOLARISnomograph path, including inferred structure and permeability classes and the lack of a directly observed very-fine-sand field.
C Factor, Cover Data, and Masking
- Allred, B. W., Bestelmeyer, B. T., Boyd, C. S., Brown, C., Davies, K. W.,
Duniway, M. C., Ellsworth, L. M., Erickson, T. A., Fuhlendorf, S. D.,
Griffiths, T. V., Jansen, V., Jones, M. O., Karl, J. W., Knight, A. C.,
Maestas, J. D., Maynard, J. J., McCord, S. E., Naugle, D. E., Starns, H. D.,
Twidwell, D., and Uden, D. R., 2021. Improving Landsat predictions of
rangeland fractional cover with multitask learning and uncertainty.
Methods in Ecology and Evolution.
https://doi.org/10.1111/2041-210X.13564
Primary reference for the RAP fractional-cover product used in the
observed_rapCmode. The publication also cautions that RAP should be interpreted alongside local data and expert knowledge. - USDA-NRCS. National Range and Pasture Handbook, Chapter 7: Rangeland and Pastureland Hydrology and Erosion. https://www.nrcs.usda.gov/sites/default/files/2022-09/Chapter%207%20-%20Grazing%20Lands%20Hydrology.pdf Useful NRCS synthesis for why litter, vegetation, and exposed interspace are first-order controls on runoff and erosion in rangeland settings.
- Multi-Resolution Land Characteristics Consortium. National Land Cover Database Class Legend and Description. https://www.mrlc.gov/sites/default/files/NLCDclasses.pdf Official land-cover class definitions supporting water, developed, and wetland masking decisions.
- U.S. Environmental Protection Agency. National Guidance: Water Quality Standards for Wetlands. https://www.epa.gov/cwa-404/national-guidance-water-quality-standards-wetlands Useful reference for the point that wetlands often have important sediment assimilation, storage, and water-quality functions, which supports treating them as outside the primary upland detachment domain of this mod.
Notes on Evidence Hierarchy
- Prefer peer-reviewed model papers, USDA handbooks, and official agency data documentation over tertiary web summaries.
- Treat live operational status pages or current product indexes as date-stamped evidence, not permanent truths.
- During implementation, each factor builder should record its exact data
source, version, retrieval date, and any local transformations in
rusle/manifest.json.