Swmm water quality
Skill Zhonghao1995/agentic-swmm-workflow/skills/swmm-water-quality
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.From its SKILL.md
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.
2 things 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.
- runs commandsInstructs the agent to run 3 commands, including `python3 skills/swmm-water-quality/scripts/validate_wq_config.py --wq-json /tmp/wq_example.json` and 2 more.
SKILL.md
6.4 KB, ~2.0k tokens by cl100k_base, 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]
What ships with it: 4 files
54.4 KB alongside SKILL.md, 3 of them executable
docs/
- rpt_wq_sections.md5.0 KB
scripts/
- extract_wq_loads.pyruns12.0 KB
- validate_wq_config.pyruns12.5 KB
tests/
- test_wq_builder_sections.pyruns25.0 KB