Below is an extended summary of the code, describing its purpose, structure, and how the classes integrate with PySWMM to manage and query subcatchment data within a SWMM model.
Overview
This module provides Pythonic wrappers for interacting with subcatchments in a SWMM (Storm Water Management Model) simulation. It defines two main classes:
Subcatchments– A container/iterator over all subcatchments, allowing you to list, retrieve, and check the existence of subcatchments by ID.Subcatchment– A single subcatchment object, offering property-based access to both static parameters (e.g., area, slope) and dynamic simulation results (e.g., rainfall, runoff).
Together, they bridge SWMM’s low-level C toolkit and Python, enabling users to modify or read subcatchment data in near real-time as a simulation proceeds.
Subcatchments
Purpose
- Acts as a Python collection of all subcatchments in an open SWMM model.
- Integrates with PySWMM’s internal
_modelpointer (which references the SWMM engine) to iterate through or lookup individual subcatchments.
Key Behaviors
-
Initialization
subcatchments = Subcatchments(simulation_object)- Checks if the model is open; otherwise raises a
PYSWMMException.
- Checks if the model is open; otherwise raises a
-
Length and Containment
len(subcatchments)returns the total number of subcatchments in the model."S1" in subcatchmentschecks if a subcatchment with ID"S1"exists.
-
Lookup
subcatchments["S1"]returns aSubcatchmentinstance corresponding to subcatchmentS1.- Raises a
PYSWMMExceptionif the ID is invalid.
-
Iteration
for sc in subcatchments:yieldsSubcatchmentobjects one by one, in the order the subcatchments are stored in SWMM.
Example Usage
from pyswmm import Simulation, Subcatchments
with Simulation("my_model.inp") as sim:
subcs = Subcatchments(sim)
print(len(subcs)) # e.g., prints total number of subcatchments
for sc in subcs:
print(sc.subcatchmentid) # e.g., "S1", "S2"
Subcatchment
Purpose
- Represents one subcatchment in a SWMM model.
- Exposes both static parameters (width, area, slope) and dynamic (time-varying) results (runoff, infiltration, etc.).
Initialization
subcatchment_obj = Subcatchment(model, "S1")
- Validates that
"S1"exists in the model’s subcatchment list.
Key Properties
-
Identifiers & Connections
subcatchmentid: The SWMM ID (e.g., "S1").connection: A tuple indicating where runoff is sent (another subcatchment or a node). Example return:(2, 'J2'), meaning the runoff flows to a node with ID "J2."
-
Subcatchment Parameters
width(effective flow width).area(subcatchment area).percent_impervious(fraction of area that is impervious).slope(average slope).curb_length(total length of curbs).
Each parameter has both a getter and setter, allowing real-time or pre-run modifications:
s1.area = 50.0 current_area = s1.area -
Simulation Results
rainfall: Instantaneous rainfall on the subcatchment (in user-defined units).evaporation_loss: Current evaporation rate from the subcatchment.infiltration_loss: Current infiltration rate.runon: Lateral inflow from other surfaces.runoff: Current runoff rate leaving the subcatchment.snow_depth: Current snow depth (if snowmelt is modeled).
-
Pollutant-Related
buildup: Surface buildup amounts for each pollutant.conc_ponded: Pollutant concentration in any ponded water.pollut_quality: Pollutant concentration in subcatchment runoff.runoff_total_loading: Total pollutant mass leaving the subcatchment in runoff.
Each of these returns a dictionary keyed by pollutant ID, e.g.:
{ "TSS": 12.3, "Lead": 0.05 } -
statistics- Returns rolling/cumulative subcatchment flow stats (total precipitation, runon, evap, infiltration, total runoff, and peak runoff rate).
- Example structure:
{ "precipitation": 2.15, "runon": 0.5, "evaporation": 0.1, "infiltration": 0.3, "runoff": 1.7, "peak_runoff_rate": 0.12 }
Example Usage
with Simulation("my_model.inp") as sim:
s1 = Subcatchments(sim)["S1"]
# Modify area
s1.area = 20.0
# Access time-varying results during the run
for step in sim:
print("Runoff at this timestep:", s1.runoff)
print("Pollutant buildup:", s1.buildup)
Typical Workflow
- Open a Simulation (context-manager recommended):
from pyswmm import Simulation, Subcatchments with Simulation("model.inp") as sim: subc_collection = Subcatchments(sim) ... - Access a Subcatchment:
s1 = subc_collection["S1"] print(s1.area, s1.percent_impervious) s1.slope = 0.015 - Iterate During a Simulation:
for step in sim: current_runoff = s1.runoff # Possibly adjust properties or log data - Utilize Pollutant Data (if water quality is enabled):
# e.g., TSS concentration in S1's runoff tss_conc = s1.pollut_quality["TSS"] - Close:
- The
Simulationcontext manager automatically finalizes the SWMM run.
- The
Error Handling
- A
PYSWMMExceptionis raised if:- The SWMM model file hasn’t been opened.
- A subcatchment ID doesn’t exist when requested.
Key Benefits
-
Pythonic Access:
- Subcatchment properties (e.g., area, slope) and real-time results (e.g., runoff rate) can be read or updated via standard property syntax, making the code more readable and maintainable than direct calls to the C API.
-
Real-Time Control:
- Parameters can be modified mid-simulation if needed, supporting advanced scenario testing or real-time control strategies.
-
Intuitive Iteration:
- The
Subcatchmentsclass supports Python’s iteration protocol and membership checks, improving discoverability and dynamic analysis of subcatchments.
- The
-
Pollutant Loading & Quality:
- Built-in methods return dictionaries keyed by pollutant ID, simplifying water quality analysis or post-processing tasks.
Conclusion
The Subcatchments and Subcatchment classes offer a high-level interface to SWMM’s subcatchment data, allowing Python developers and modelers to manipulate and observe hydrologic processes in near real-time. By exposing subcatchment parameters and simulation outputs in a straightforward, property-based manner, they further streamline typical tasks like:
- Parameter adjustments (e.g., changing area or slope).
- Hydrologic result retrieval (e.g., rainfall, infiltration, or runoff).
- Pollutant water quality checks (e.g., buildup, runoff concentration).
Together, they make modeling workflows in PySWMM more intuitive, robust, and Pythonic.