SWAT-DG: Diagnostic-Guided SWAT Calibration
Python framework for the SWAT2012 hydrological model (Rev. 681+) with diagnostic-guided calibration — physics-based parameter tuning that converges in minutes, not days. Developed by Lynxce | Download Portable ZIP
The Problem: Calibration is a Bottleneck
SWAT has more than 45 adjustable parameters. Standard calibration tools try thousands of parameter combinations blindly — like tuning a complex instrument while blindfolded. The popular SCE-UA algorithm (used in SWAT-CUP) typically requires 5,000 to 50,000 model runs to converge. At one minute per run, that's 3 to 35 days of compute time.
Worse, blind optimization tells you what the best parameters are — but not why they work. When the model fails in a new scenario, you start over from scratch.
The Solution: Diagnose Before You Calibrate
SWAT-DG acts like an experienced hydrologist reading the hydrograph. Before touching any parameters, it runs 5 diagnostic checks on simulated vs. observed streamflow:
- Volume balance — Is total simulated water too high or too low?
- Baseflow partition — Is the groundwater/surface runoff split correct?
- Peak events — Are storm peaks the right magnitude and timing?
- Flow duration curve — Does the model reproduce wet, median, and dry flow statistics?
- KGE decomposition — Is poor performance from timing, variability, or bias?
These diagnostics feed 14 expert rules that prescribe targeted parameter adjustments in 4 sequential phases. The result:
| Method | Runs Needed | Time (1 min/run) |
|---|---|---|
| Monte Carlo | 1,000–10,000 | 17–167 hours |
| SCE-UA (SWAT-CUP) | 5,000–50,000 | 83–833 hours |
| SWAT-DG Diagnostic | 5–50 | 5–50 minutes |
SWAT-DG is a rapid screening tool and smart warm-start. For publication-quality calibration, run SWAT-DG first to get a physically informed starting point, then refine with SCE-UA — cutting total iterations by 30–60%.
Web Interface — No Code Required
SWAT-DG includes a 7-page Streamlit web app that runs 100% locally. All data stays on your computer. A portable Windows ZIP is available — no Python installation needed.
App pages:
- Project Setup — Load SWAT project, auto-detect executable, view project info
- Watershed Map — Interactive Folium map of subbasins and reaches with simulation output overlay
- Simulation Results — Browse raw SWAT outputs, compare runs, spatial summaries
- Observation Data — Import from USGS NWIS API, CSV, Excel, WQP/STORET with auto unit conversion
- Parameter Editor — Edit 45+ parameters with live bounds, batch editing, save/load presets
- Calibration — Choose mode (single-site, multi-site, sequential, partial-basin), algorithm, and run
- Results — Performance metrics, before/after hydrographs, scatter plots, FDC, diagnostic plots, export
Key Features
-
Diagnostic-Guided Calibration — Single diagnostic, ensemble (parallel runs for uncertainty), phased (hydrology → sediment → nitrogen → phosphorus), multi-constituent water quality calibration with load calculator and WQ-specific diagnostic engines
-
Traditional Calibration (SPOTPY) — 8+ algorithms (SCE-UA, DREAM, Monte Carlo, LHS, ROPE, DE-MCZ), 45+ parameters with recommended bounds, 8 objective functions (NSE, KGE, PBIAS, RMSE, MAE, R², RSR, Log-NSE), sensitivity analysis (FAST, Sobol), multi-site and sequential calibration, parallel multi-core support
-
Complete Python SWAT Wrapper — Run simulations, read/write all input files (.bsn, .sol, .mgt, .gw, .cio), parse all outputs to DataFrames, backup/restore with 99.9% size reduction, fig.fig routing parser with upstream/downstream traversal, partial-basin active subbasin optimization
-
Rich Visualization — Hydrographs (daily/monthly), scatter plots, flow duration curves, diagnostic plots (baseflow separation, peak comparison, seasonal bias, rating curves), interactive Plotly charts, sensitivity tornado charts, export to PNG/PDF/HTML
-
Data Automation — USGS NWIS streamflow/WQ import, Water Quality Portal (WQP/STORET) with auto unit conversion, NOAA CDO weather data, SSURGO soil data, NLCD land cover, DEM processing and watershed delineation
Installation
pip install swat-dg
Or install from source:
git clone https://github.com/wasailin/SWAT-DG.git
cd swat-dg
pip install -e .
For calibration features:
pip install swat-dg[calibration] # Installs spotpy, pathos
For GIS/spatial features:
pip install swat-dg[gis] # Installs geopandas, rasterio, pyproj, xarray, folium
For data automation:
pip install swat-dg[data] # Installs requests, openpyxl
For the Streamlit web app:
pip install swat-dg[app] # Installs streamlit, plotly, folium
For all features:
pip install swat-dg[full] # All above + scipy, shapely
Quick Start
Launch the Calibration App (Easiest!)
# Install with app dependencies
pip install -e ".[app]"
# Launch the calibration app
streamlit run src/swat_modern/app/main.py
# Opens browser at http://localhost:8501
# Browse to your SWAT project folder
# Load observation data, select parameters, run calibration!
The app runs 100% locally - all data stays on your computer.
Basic Usage
from swat_modern import SWATModel
# Load a SWAT project
model = SWATModel("C:/my_watershed", executable="C:/swat2012.exe")
# Run simulation
result = model.run()
# Get streamflow output
flow = model.get_output("FLOW_OUTcms", output_type="rch", unit_id=1)
print(flow.head())
# Modify parameters
model.modify_parameter("CN2", -0.1, method="multiply") # Reduce CN2 by 10%
# Run again
result2 = model.run()
Calibration
from swat_modern import SWATModel
from swat_modern.calibration import Calibrator
# Load model
model = SWATModel("C:/my_watershed")
# Create calibrator with observed data
calibrator = Calibrator(
model=model,
observed_data="streamflow.csv",
parameters=["CN2", "ESCO", "GW_DELAY", "ALPHA_BF", "GWQMN"],
output_variable="FLOW_OUT",
reach_id=1,
objective="nse"
)
# Run automatic calibration (parallel across cores)
results = calibrator.auto_calibrate(
n_iterations=5000,
algorithm="sceua",
parallel=True,
n_cores=4
)
# View results
results.print_summary()
results.plot_comparison()
# Save best parameters
results.save_best_parameters("best_params.json")
Diagnostic-Guided Calibration
from swat_modern.calibration import Calibrator
calibrator = Calibrator(model=model, observed_data="streamflow.csv", reach_id=1)
# Single diagnostic run (uses flow signatures to guide parameter selection)
result = calibrator.diagnostic_calibrate(n_iterations=2000)
# Ensemble diagnostic (multiple runs for uncertainty)
result = calibrator.ensemble_diagnostic_calibrate(n_ensemble=5, n_iterations=1000)
# Phased: hydrology first, then sediment, then nitrogen, then phosphorus
result = calibrator.phased_calibrate(phases=["hydrology", "sediment", "nitrogen", "phosphorus"])
Sensitivity Analysis
from swat_modern.calibration import Calibrator
calibrator = Calibrator(model=model, observed_data="streamflow.csv", reach_id=1)
# Parallel sensitivity analysis
sa_result = calibrator.sensitivity_analysis(
method="fast",
n_samples=500,
parallel=True,
n_cores=4
)
sa_result.plot_rankings()
print(sa_result.top_parameters(n=10))
Using Objective Functions
from swat_modern.calibration.objectives import nse, kge, pbias, rsr, evaluate_model
# Calculate single metric
score = nse(observed, simulated)
print(f"NSE = {score:.3f}")
# Calculate multiple metrics
metrics = evaluate_model(observed, simulated)
print(metrics) # {'nse': 0.85, 'kge': 0.78, 'pbias': 5.2, 'rsr': 0.45, ...}
Visualization Dashboard
from swat_modern.visualization import CalibrationDashboard
dashboard = CalibrationDashboard(
dates=dates,
observed=observed,
simulated=simulated,
site_name="Big Creek Watershed",
variable_name="Streamflow",
units="m³/s"
)
dashboard.create_dashboard()
dashboard.save("calibration_report.png")
dashboard.to_html("calibration_report.html")
Requirements
- Python 3.10+
- numpy, pandas, matplotlib
- SWAT2012 executable, Rev. 681 or above (available from Releases or the official SWAT website)
Documentation
See the docs/ folder:
Calibration Parameters (45+)
| Group | Parameters |
|---|---|
| Hydrology | CN2, ESCO, EPCO, SURLAG, OV_N, CANMX |
| Groundwater | GW_DELAY, ALPHA_BF, ALPHA_BF_D, GWQMN, REVAPMN, GW_REVAP, RCHRG_DP |
| Soil | SOL_AWC, SOL_K, SOL_BD |
| Routing | CH_N2, CH_K2 |
| Sediment | USLE_P, USLE_K, SPCON, SPEXP, CH_COV1, CH_COV2, PRF, ADJ_PKR |
| Nutrients | NPERCO, PPERCO, CMN, PSP, N_UPDIS, PHOSKD, ERORGP, and more |
Calibration Algorithms
Via SPOTPY integration:
- SCE-UA - Shuffled Complex Evolution (recommended for hydrology)
- DREAM - Differential Evolution Adaptive Metropolis (with uncertainty)
- MC - Monte Carlo sampling (fully parallelizable)
- LHS - Latin Hypercube Sampling (fully parallelizable)
- ROPE - Robust Parameter Estimation
- DE-MCZ - Differential Evolution MCMC
Diagnostic-guided (built-in):
- diagnostic - Physics-based single diagnostic run
- diagnostic_ensemble - Multiple diagnostic runs with uncertainty
- phased - Sequential hydrology → sediment → nitrogen → phosphorus
Project Status (v0.5.0)
Phase 1: Python Wrapper Foundation ✅
- Basic SWAT model wrapper (
SWATModel) - Output file parsing (output.rch, output.sub, output.hru, output.std, output.rsv)
- Input file parsing (.bsn, .sol, .mgt, .gw, .cio, fig.fig)
- Parameter modification (replace, multiply, add methods)
- Project backup/restore (selective file types for 99.9% size reduction)
Phase 2: Calibration Automation ✅
- SPOTPY calibration integration (8+ algorithms)
- Objective functions (NSE, KGE, PBIAS, RMSE, MAE, R², Log-NSE, RSR)
- 45+ calibration parameter definitions with recommended bounds
- Sensitivity analysis (FAST, Sobol) with parallel support
- Multi-site calibration (simultaneous and sequential upstream-to-downstream)
- Parameter boundary manager for custom search bounds
Phase 3: Input Data Automation ✅
- Weather data retrieval (NOAA API)
- SWAT weather file generation (.pcp, .tmp, WGEN)
- Soil data processing (SSURGO integration)
- Land cover (NLCD classification)
- DEM processing and watershed delineation
- USGS NWIS observation data import (streamflow and water quality)
- Multi-format observation loader (CSV, Excel, USGS RDB, WQP/STORET)
Phase 4: User Interface ✅
- Visualization dashboard (hydrograph, scatter, duration curves, metrics table)
- Diagnostic visualization (baseflow separation, peak comparison, seasonal bias, rating curves)
- Interactive Plotly charts (time series, multi-variable, scatter)
- Streamlit web app (7 pages) with session persistence
- Interactive parameter selection and boundary editing
- Export to JSON, CSV, HTML, PNG, PDF
Phase 5: Advanced Calibration ✅
- Diagnostic-guided calibration (baseflow separation, peak analysis, volume balance, FDC metrics)
- Ensemble diagnostic calibration with uncertainty
- Phased calibration (hydrology → sediment → nitrogen → phosphorus)
- Parallel multi-core calibration via pathos
- Multi-constituent WQ calibration (sediment, nitrogen, phosphorus)
- Load calculator for constituent loads
- WQ-specific diagnostic engines
Phase 6: Distribution & Performance ✅
- SWAT+ to SWAT2012 converter (CLI and API)
- fig.fig routing parser with upstream/downstream traversal
- Partial-basin active subbasin optimization (active_subs.dat)
- Portable SWAT-DG Windows package (embedded Python 3.11, no install needed)
- Intel ifx compiler build (2.4x faster than gfortran)
- GIS integration (Folium maps, shapefile loading)
Contributing
Contributions are welcome! Please see our contributing guidelines.
License
Apache 2.0 License - see LICENSE file for details.
Acknowledgments
This project builds on the SWAT model developed at Texas A&M University. See https://swat.tamu.edu/ for more information about SWAT.
References
- Arnold, J.G., et al. (2012). SWAT: Model Use, Calibration, and Validation. ASABE.
- Abbaspour, K.C. (2015). SWAT-CUP: SWAT Calibration and Uncertainty Programs.
- Moriasi, D.N., et al. (2007). Model evaluation guidelines. ASABE, 50(3), 885-900.
Metadata
Release files for swat-dg 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| swat_dg-0.6.1.tar.gz | 395.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| swat_dg-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 829.7 kB
Release files / swat_dg-0.6.1.tar.gz
| Download URL | swat_dg-0.6.1.tar.gz |
|---|---|
| Size | 395.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3a431033e8cfe45ad5bf7c1338c1f1d535c698c09a8ee8cea0fc487273304cc7
|
|
BLAKE2b-256 checksum How to use checksums |
c3261f487bbae3b1b1097d816fdcff4e30a8f123bdb967604ed30fc6c6c2809c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 11, 2026.
Transparency logRelease files / swat_dg-0.6.1-py3-none-any.whl
| Download URL | swat_dg-0.6.1-py3-none-any.whl |
|---|---|
| Size | 434.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8afa1539a39e4201e1c3c6188fab97552d57f099d209eab06b6691b8378eb45d
|
|
BLAKE2b-256 checksum How to use checksums |
90b5d1d5ee7aa999121272e61dfa3494fde04627eed450b8a4972fe94ff3c927
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 11, 2026.
Transparency log