Below is an extended summary of this code, which focuses on reading and accessing data from a SWMM output (.out) file via a Python interface. It describes the purpose, structure, and usage of each class, along with relevant methods and decorators.
Overview
This module provides a robust way to interact with SWMM’s output binary files in Python. It allows users to:
- Open or close SWMM output binary files.
- Query time-series data for subcatchments, nodes, links, and the overall system.
- Retrieve, filter, and present simulation results as Python dictionaries keyed by timestamps.
- Easily integrate with pandas or other data-processing tools, thanks to dictionary-based outputs.
Key elements include:
Output
class: Core functionality for opening and querying the binary file.output_open_handler
decorator: Ensures an output file is opened before any function runs.- Classes like
SubcatchSeries
,NodeSeries
,LinkSeries
, andSystemSeries
: High-level objects that map SWMM attributes (rainfall, flow rate, infiltration, etc.) into time-indexed Python dictionaries.
Core Functionality
1. Output
Class
Purpose: Manages a SWMM output (.out) file, including opening/closing it, reading metadata (like start time, end time, number of periods), and fetching results in various formats.
Key Methods and Properties:
-
File Handling
open()
: Initializes an internal handle to the output file. Loads critical info such as start date/time, reporting interval, total periods, etc.close()
: Closes the file and cleans up the internal handle.__enter__
/__exit__
: Implements Python’s context-manager protocol (with
statement), ensuring that the file automatically opens and closes.
-
Project/Simulation Metadata
project_size
: Returns counts for subcatchments, nodes, links, system objects, and pollutants.start
,end
,report
,period
: Start date/time, end date/time, reporting interval (in seconds), and number of reporting periods.version
: Returns the SWMM engine version used to produce this output file.units
: Shows the user’s unit system (US or SI), flow units (CFS, CMS, etc.), and pollutant units.
-
Model Element Dictionaries
subcatchments
,nodes
,links
,pollutants
: Each returns a dict mapping element IDs (e.g., “J1”, “C2”, “S1”) to integer indices. These indices are needed to make calls into the underlying SWMM output toolkit.
-
Time Management
times
: A list ofdatetime
objects for each reporting period in the simulation.- Internally, times are generated by starting at
self.start
and incrementing in steps ofself.report
seconds.
-
Retrieving Data
subcatch_series
,node_series
,link_series
,system_series
: Time-series retrieval for a single object (subcatch/node/link) or the entire system.- Returns a dictionary of
{ datetime: value }
.
- Returns a dictionary of
subcatch_attribute
,node_attribute
,link_attribute
: Snapshots of a single attribute for all subcatchments/nodes/links at a single time index.subcatch_result
,node_result
,link_result
: Returns all attributes for a single subcatchment/node/link at a single time index.system_result
: Returns a dictionary of system-wide attributes (e.g., total runoff, infiltration) at a single time index.
-
Validation Helpers
verify_index(...)
: Ensures a user-provided ID or index is valid for a given subcatchment/node/link dictionary.verify_time(...)
: Converts a user-supplieddatetime
or integer index into a valid time-step index. Raises exceptions if the time/index is out of range.
2. output_open_handler
Decorator
- Ensures that before any method runs (e.g.,
subcatch_series
,node_attribute
), the output file is open. - If
self.loaded
isFalse
, it callsself.open()
to establish a handle. - This decorator simplifies code by allowing users to call methods directly without worrying about manually opening the output file first.
3. High-Level Series Classes
-
SubcatchSeries
- Usage:
SubcatchSeries(out_handle)[‘S1’].rainfall
- Each property (e.g.,
.rainfall
,.snow_depth
) yields a time-series dictionary for the specified subcatchment. - Internally calls
Output.subcatch_series(...)
.
- Usage:
-
NodeSeries
- Usage:
NodeSeries(out_handle)[‘J1’].invert_depth
- Maps node attributes like
INVERT_DEPTH
,HYDRAULIC_HEAD
, etc. to time-series dictionaries.
- Usage:
-
LinkSeries
- Usage:
LinkSeries(out_handle)[‘C1:C2’].flow_rate
- Provides link attributes such as
FLOW_RATE
,FLOW_DEPTH
,FLOW_VELOCITY
.
- Usage:
-
SystemSeries
- Usage:
SystemSeries(out_handle).runoff_flow
- No element ID needed (the entire system is a single entity).
- Returns time-series data for system-level attributes (e.g., total rainfall, total inflow, outflow).
- Usage:
Common Patterns:
- Each of these series classes inherits from
OutAttributeBase
, which implements:- A dynamic
__getattr__
that interprets attribute names (e.g.,.flow_rate
) and calls the underlying PySWMM methods. - A
_series_type(...)
helper method that routes toOutput
methods like.subcatch_series
,.node_series
, etc.
- A dynamic
4. Example Usage
from pyswmm import Output, NodeSeries
# 1) Open a SWMM output file via the context manager
with Output("my_model.out") as out:
# 2) Access metadata
print("Start Time:", out.start)
print("End Time:", out.end)
print("Number of Nodes:", len(out.nodes))
# 3) Retrieve time-series data for a specific node
node_data = NodeSeries(out)["J1"].total_inflow
for time, inflow_value in node_data.items():
print(time, inflow_value)
# 4) Retrieve a single time snapshot for all nodes
snapshot_16h = out.node_attribute(
attribute=shared_enum.NodeAttribute.INVERT_DEPTH,
time_index=datetime(2020, 1, 1, 16, 0)
)
print(snapshot_16h) # {"J1": 10.2, "J2": 12.3, ...}
Benefits and Applications
-
Simplicity: Users can retrieve SWMM results using Python dictionaries keyed by datetime, making integration with other data libraries (like pandas or matplotlib) straightforward.
-
Flexibility:
- Retrieve results by time (snapshot across many objects) or by object (time-series for a single subcatchment/node/link).
- Retrieve single attributes or all attributes at once.
-
Error Handling:
- Clear exceptions (
OutputException
) if an ID or time-step is invalid. - Decorators ensuring the file is open before data retrieval.
- Clear exceptions (
-
Separation of Concerns:
Output
handles low-level file reading and indexing.SubcatchSeries
,NodeSeries
,LinkSeries
, andSystemSeries
provide higher-level, user-friendly interfaces to time-series data.
Conclusion
This code presents a comprehensive Python interface for processing SWMM output files. By abstracting the SWMM toolkit’s C-based calls into intuitive classes and decorators, it gives modelers and data scientists convenient access to simulation results at different levels (subcatchment, node, link, or entire system). Thanks to dictionary-based returns keyed by timestamps, it integrates naturally with Python’s ecosystem for data analysis and visualization, ultimately streamlining the post-processing workflow for stormwater and hydrological modeling projects.
No comments:
Post a Comment