Swmm water quality
Skill Zhonghao1995/agentic-swmm-workflow/skills/swmm-water-quality
Agentic SWMM is an automated, auditable, and memory-informed framework for reproducible stormwater modelling, integrating QGIS and EPA SWMM through the aiswmm runtime, reusable Skills, and MCP interfaces, with QA verification, provenance tracking, calibration support, and Codex, Hermes, Claude code as well as OpenClaw compatibility
npx -y skills add Zhonghao1995/agentic-swmm-workflow --skill swmm-water-qualityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
6.4 KB, as published. Nobody here has run it
SWMM Water Quality Skill
Purpose
Complete SWMM engine coverage for pollutant buildup/washoff simulation and load reporting. This skill provides:
validate_wq_config.py— validate a WQ config JSON before passing it to the builder.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 namesrunoff_quality_continuity— mass-balance rows (metric + per-pollutant kg)quality_routing_continuity— routing mass-balance rowssubcatchment_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
| Field | Type | Default | Notes |
|---|---|---|---|
name | string | required | No spaces |
units | string | required | MG/L, UG/L, or #/L |
c_rain | float | 0 | Concentration in precipitation |
c_gw | float | 0 | Concentration in groundwater |
c_ii | float | 0 | Concentration in RDII |
k_decay_per_day | float | 0 | First-order decay (1/days) |
snow_only | bool | false | Buildup during snow only |
co_pollutant | string | "*" | Co-pollutant name or "*" |
co_fraction | float | 0 | Co-pollutant fraction (0–1) |
init_conc | float | 0 | Initial dry-weather concentration |
landuses entries
| Field | Type | Default | Notes |
|---|---|---|---|
name | string | required | |
sweep_interval | float | 0 | Days between sweeping (0 = no sweeping) |
availability | float | 0 | Fraction of buildup removed by sweeping (0–1) |
last_sweep | float | 0 | Days since last sweep at start |
coverages entries
| Field | Type | Notes |
|---|---|---|
subcatchment | string | Must reference an existing subcatchment |
landuse | string | Must reference a defined land use |
percent | float (0–100) | Percent coverage; per-subcatchment sum must be ≤ 100 |
buildup entries
| Field | Type | Notes |
|---|---|---|
landuse | string | Must reference a defined land use |
pollutant | string | Must reference a defined pollutant |
func_type | string | POW, EXP, or SAT (EXT not supported in v1) |
c1 | float | Max buildup (kg/ha or count/ha when normalizer=AREA) |
c2 | float | Rate constant |
c3 | float | Third coefficient (unused for EXP/SAT) |
normalizer | string | AREA or CURBLENGTH |
washoff entries
| Field | Type | Notes |
|---|---|---|
landuse | string | Must reference a defined land use |
pollutant | string | Must reference a defined pollutant |
func_type | string | EXP, RC, or EMC |
c1 | float | Coefficient 1 |
c2 | float | Coefficient 2 (0 for EMC) |
sweep_removal | float (0–1) | Fraction removed by sweeping |
bmp_removal | float (0–1) | Fraction removed |
loadings entries (optional)
| Field | Type | Notes |
|---|---|---|
subcatchment | string | Must reference an existing subcatchment |
pollutant | string | Must reference a defined pollutant |
init_buildup | float | Initial buildup mass |
Scripts
scripts/validate_wq_config.py— standalone CLI validatorscripts/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]