SWMM Water Quality Skill

SkillDev tools

Complete SWMM engine coverage: pollutant buildup/washoff simulation support and load reporting. Validate water-quality config JSON, build INPs with WQ sections, and extract pollutant load summaries from completed runs.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the SWMM Water Quality Skill skill

What this skill tells your AI

The instructions your AI receives, as published by zhonghao1995/agentic-swmm-workflow in skills/swmm-water-quality/SKILL.md and read by ahel’s review.

Purpose

Complete SWMM engine coverage for pollutant buildup/washoff simulation and load reporting. This skill provides:

  1. validate_wq_config.py — validate a WQ config JSON before passing it to the builder.
  2. extract_wq_loads.py — extract WQ load summaries from a SWMM RPT.

The water-quality sections ([POLLUTANTS], [LANDUSES], [COVERAGES], [BUILDUP], [WASHOFF], [LOADINGS]) are emitted by skills/swmm-builder/scripts/build_swmm_inp.py via the --water-quality-json flag (see also build_inp tool's water_quality_json argument).

Agent tool: read_wq_loads

Read pollutant load summaries from a completed run's .rpt file. Returns wq_present=false for non-WQ runs.

read_wq_loads(rpt_path="runs/my_run/model.rpt")

Returns a structured JSON with:

  • wq_present (bool)
  • pollutants — sorted list of pollutant names
  • runoff_quality_continuity — mass-balance rows (metric + per-pollutant kg)
  • quality_routing_continuity — routing mass-balance rows
  • subcatchment_washoff — per-subcatchment loads (kg per pollutant)
  • link_loads — per-link transport loads (kg per pollutant)
  • outfall_loads — per-outfall flow stats + pollutant loads

WQ config JSON schema

Top-level keys (all required when the key is present; empty arrays are valid):

{
  "pollutants": [...],
  "landuses": [...],
  "coverages": [...],
  "buildup": [...],
  "washoff": [...],
  "loadings": []
}

pollutants entries

FieldTypeDefaultNotes
namestringrequiredNo spaces
unitsstringrequiredMG/L, UG/L, or #/L
c_rainfloat0Concentration in precipitation
c_gwfloat0Concentration in groundwater
c_iifloat0Concentration in RDII
k_decay_per_dayfloat0First-order decay (1/days)
snow_onlyboolfalseBuildup during snow only
co_pollutantstring"*"Co-pollutant name or "*"
co_fractionfloat0Co-pollutant fraction (0–1)
init_concfloat0Initial dry-weather concentration

landuses entries

FieldTypeDefaultNotes
namestringrequired
sweep_intervalfloat0Days between sweeping (0 = no sweeping)
availabilityfloat0Fraction of buildup removed by sweeping (0–1)
last_sweepfloat0Days since last sweep at start

coverages entries

FieldTypeNotes
subcatchmentstringMust reference an existing subcatchment
landusestringMust reference a defined land use
percentfloat (0–100)Percent coverage; per-subcatchment sum must be ≤ 100

buildup entries

FieldTypeNotes
landusestringMust reference a defined land use
pollutantstringMust reference a defined pollutant
func_typestringPOW, EXP, or SAT (EXT not supported in v1)
c1floatMax buildup (kg/ha or count/ha when normalizer=AREA)
c2floatRate constant
c3floatThird coefficient (unused for EXP/SAT)
normalizerstringAREA or CURBLENGTH

washoff entries

FieldTypeNotes
landusestringMust reference a defined land use
pollutantstringMust reference a defined pollutant
func_typestringEXP, RC, or EMC
c1floatCoefficient 1
c2floatCoefficient 2 (0 for EMC)
sweep_removalfloat (0–1)Fraction removed by sweeping
bmp_removalfloat (0–1)Fraction removed

loadings entries (optional)

FieldTypeNotes
subcatchmentstringMust reference an existing subcatchment
pollutantstringMust reference a defined pollutant
init_buildupfloatInitial buildup mass

Scripts

  • scripts/validate_wq_config.py — standalone CLI validator
  • scripts/extract_wq_loads.py — RPT load extractor

Executed examples

Validate a WQ config JSON

# Write a minimal WQ config JSON:
cat > /tmp/wq_example.json << 'EOJSON'
{
  "pollutants": [{"name": "TSS", "units": "MG/L", "c_rain": 0, "c_gw": 0,
                  "c_ii": 0, "k_decay_per_day": 0, "snow_only": false,
                  "co_pollutant": "*", "co_fraction": 0, "init_conc": 0}],
  "landuses": [{"name": "Residential", "sweep_interval": 0, "availability": 0, "last_sweep": 0}],
  "coverages": [{"subcatchment": "S1", "landuse": "Residential", "percent": 100}],
  "buildup": [{"landuse": "Residential", "pollutant": "TSS", "func_type": "EXP",
               "c1": 15, "c2": 0.5, "c3": 0, "normalizer": "AREA"}],
  "washoff": [{"landuse": "Residential", "pollutant": "TSS", "func_type": "EMC",
               "c1": 50, "c2": 0, "sweep_removal": 0, "bmp_removal": 0}],
  "loadings": []
}
EOJSON

python3 skills/swmm-water-quality/scripts/validate_wq_config.py \
    --wq-json /tmp/wq_example.json
# Output: {"ok": true, "pollutant_count": 1, "landuse_count": 1, ...}

Extract WQ load summaries from a completed run RPT

python3 skills/swmm-water-quality/scripts/extract_wq_loads.py \
    --rpt tests/fixtures/wq/wq_smoke.rpt
# Output: {"ok": true, "wq_present": true, "pollutants": ["TSS"],
#          "runoff_quality_continuity": [...], ...}

Build an INP with water quality sections

python3 skills/swmm-builder/scripts/build_swmm_inp.py \
    --subcatchments-csv <subcatchments.csv> \
    --params-json <params.json> \
    --network-json <network.json> \
    --water-quality-json /tmp/wq_example.json \
    --out-inp /tmp/wq_model.inp \
    --out-manifest /tmp/wq_model_manifest.json

Validation constraints

Enforced by both validate_wq_config.py and build_swmm_inp.py:

  • Referential: every [BUILDUP]/[WASHOFF] landuse/pollutant must exist
  • Referential: every [COVERAGES]/[LOADINGS] subcatchment must exist
  • Enum: units ∈ {MG/L, UG/L, #/L}
  • Enum: buildup func_type ∈ {POW, EXP, SAT} (EXT rejected with message)
  • Enum: washoff func_type ∈ {EXP, RC, EMC}
  • Range: coverage percent ∈ [0, 100]; per-subcatchment sum ≤ 100
  • Range: sweep_removal, bmp_removal, co_fraction ∈ [0, 1]

Signals

GitHub stars
28
Forks
13
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
swmm-water-quality
Source
github.com/zhonghao1995/agentic-swmm-workflow