skill-author
Draft a well-formed new skill (a SKILL.md scaffold, optionally with scripts/references) from a described recurring need, for human review and approval. Use…
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.
$ npx -y skills add Zhonghao1995/agentic-swmm-workflow --skill swmm-water-quality --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/swmm-water-qualityContext preview
The summary Claude sees to decide when to auto-load this skill.
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.
name: swmm-water-quality description: > 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.
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).
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:
Top-level keys (all required when the key is present; empty arrays are valid):
{
"pollutants": [...],
"landuses": [...],
"coverages": [...],
"buildup": [...],
"washoff": [...],
"loadings": []
}| 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 |
| 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 |
| 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 |
| 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` |
| 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 |
| Field | Type | Notes | |---|---|---| | `subcatchment` | string | Must reference an existing subcatchment | | `pollutant` | string | Must reference a defined pollutant | | `init_buildup` | float | Initial buildup mass |
# 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, ...}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": [...], ...}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.jsonPre-1.0 · stable v0.9.4 · pip install aiswmm==0.9.4 · CHANGELOG Headaches from tedious model setup? Try our another project SWMMCanada, our automated model-building project: draw an area anywhere in Canada and get a ready-to-run SWMM model. Up and running now.
Repo: Zhonghao1995/agentic-swmm-workflow
Draft a well-formed new skill (a SKILL.md scaffold, optionally with scripts/references) from a described recurring need, for human review and approval. Use…
Synthesize a plausible SWMM drainage network from public data (OSM streets + DEM) when NO real pipe-network data exists — input is just a bbox. Use ONLY when…
Assemble a runnable SWMM INP deterministically from subcatchment geometry/attributes, merged parameter JSON, network JSON, and climate references. Use when…
Calibration and validation scaffold for EPA SWMM. Use when an agent needs to (1) compare simulated vs observed flow, (2) evaluate candidate parameter sets, (3)…
Fetch a ready-to-run SWMM model for any Canadian area from the SWMMCanada upstream service — real published municipal storm pipes where a supported city covers…
Deterministic rainfall/climate formatting for SWMM. Use when converting timestamped rainfall CSV files into SWMM-ready [TIMESERIES] lines and [RAINGAGES]…