Skip to main content

A Unified Python Toolkit for Building, Editing, Running, Importing, Visualizing, and Exporting EPA SWMM Models.

Project description


License PyPI Python versions Build Downloads

Development notice: swmmx is under active testing and development. Issues are being identified and corrected continuously, so please make sure you are using the latest available release before reporting unexpected behavior.

Disclaimer

  • Domain knowledge required: swmmx is a programmatic wrapper and toolkit for EPA SWMM. Effective use requires an understanding of hydrologic and hydraulic principles, SWMM input conventions, and the mechanics of the EPA SWMM engine.
  • Engineering judgment required: Simulation results should always be validated before use. Professional engineering judgment is required to interpret, verify, and apply any output generated by this package for real-world design, planning, or decision-making.
  • Beta software / notice of risk: This project is actively maintained, but it may still contain bugs, errors, or unresolved issues that can cause incorrect calculations, incomplete outputs, or runtime errors. Please verify critical calculations independently and report bugs through the repository Issues tab.

swmmx

swmmx A Unified Python Toolkit for Building, Editing, Running, Importing, Visualizing, and Exporting EPA SWMM Models:

Help: Documentation

Install:

pip install swmmx

How to use:

from swmmx import swmm

m = swmm("examples/example.inp")
m.plot_layout()
print(m.time.count())
lengths = m.get.conduit.length()
m.set.conduit.roughness(0.013)
m.run()
print(m.log())
m.plot_timeseries.link.flow()

Version 0.0.39 currently provides:

  • swmm(path=None, new=None, flow_unit=None, custom_dll_path=None)
  • m.time.vector(), m.time.count(), m.time.vector_run(), m.time.count_run()
  • structured parameter access through m.get.<main_category>.<sub_category>() and m.set.<main_category>.<sub_category>()
  • discoverable object counts through m.count.<main_category>(), m.count.model(), m.count.model_dict(), and m.count.model_df()
  • editable model construction through m.add.<category>.<element_type>() and m.remove.<category>.<element_type>()
  • matplotlib plotting through m.plot_layout(), m.plot_timeseries.<category>.<sub_category>(), and m.plot_profile.*
  • tabular and spatial imports through m.import_csv.<category>.<element_type>() and m.import_gis.<category>.<element_type>()
  • external-format export through m.export.gis(), m.export.csv(), and m.export.excel()
  • m.save(), m.run(), m.runs() for step-by-step simulation, m.validate(), m.log(), and m.clone()
  • lazy native-engine loading for bundled Windows/Linux/macOS engines plus custom engine paths
  • preserving .inp parsing/writing that keeps comments, unknown sections, and section order whenever possible

Constructor examples:

m = swmm("examples/example.inp")         # open an existing model
m = swmm()                               # new SI model, LPS by default
m = swmm(new="SI", flow_unit="CMS")      # new SI model
m = swmm(new="US", flow_unit="GPM")      # new US model

Examples

The repository includes a small learning suite in examples/. The main folder now holds the simplest teaching scripts: no main() function, no try blocks, and fewer defensive branches, so the API is easy to read line by line. The fuller runnable versions live in examples/standard/, where they include validation, safer branching, and file-output handling.

Topic Simple learning version Standard example
Open, validate, and run 01_open_validate_run.py standard/01_open_validate_run.py
Modify conduit diameters and compare 02_modify_conduit_diameters_compare.py standard/02_modify_conduit_diameters_compare.py
Step-by-step runs 03_step_by_step_runs_dynamic_control.py standard/03_step_by_step_runs_dynamic_control.py
Layout plots 04_plot_layout_examples.py standard/04_plot_layout_examples.py
Time-series plots 05_plot_timeseries_examples.py standard/05_plot_timeseries_examples.py
Profile plots 06_plot_profile_examples.py standard/06_plot_profile_examples.py
GIS/CSV/Excel export 07_export_examples.py standard/07_export_examples.py
Time and count helpers 08_time_and_count_functions.py standard/08_time_and_count_functions.py
Get/set patterns 09_get_set_examples.py standard/09_get_set_examples.py
Build a model from scratch 10_create_model_from_scratch_add_remove.py standard/10_create_model_from_scratch_add_remove.py

Run them from the repository root:

python examples/01_open_validate_run.py
python examples/standard/01_open_validate_run.py

The examples use examples/example.inp, avoid overwriting it, and write generated files into examples/output/.

Installation note

swmmx intentionally does not install third-party scientific packages for you. This keeps package installation lightweight and avoids changing an existing scientific Python environment unexpectedly.

Before creating a model, install the runtime packages you need:

python -m pip install numpy pandas matplotlib networkx

When you call swmm(...), the package checks that those runtime packages are available and raises a clear error if any are missing.

Native engines

The package includes the supplied bundled engines:

  • Windows 64-bit: swmm5.dll
  • Linux 64-bit: libswmm5.so
  • macOS: libswmm5.dylib

Time semantics

m.time.vector() mirrors SWMM reporting behavior: it starts at the first report interval after REPORT_START_* and proceeds through END_*.

frame = m.time.vector() # pandas DataFrame with timestamp index

Run-time vectors use the actual period count read from the .out file after the engine finishes. m.time.count() remains the expected pre-run count; m.time.count_run() is the actual post-run count and requires results.

Step-by-step simulation with m.runs()

m.runs() is one of the most powerful tools in swmmx: it exposes the native SWMM step loop as a Python iterator. Use it when you want to monitor a simulation as it advances, build progress displays, inspect step times, or prepare workflows that react during a run instead of waiting only for the final .out file.

for step in m.runs():
    print(step.index, step.time, step.elapsed_days)

print(m.time.count_run())  # available after the stepped run finishes

Parameter access

lengths = m.get.conduit.length()
one_length = m.get.conduit.length("P001")
flow = m.get.link.flow(ids=["P001", "P005"], format="df")

m.set.conduit.roughness(0.013)
m.set.conduit.roughness([0.013, 0.014], ids=["P001", "P005"])

Supported getters default to NumPy output; format="df" gives pandas output. dir(m.get.<category>) now exposes the full declared parameter surface, including input fields, attached records, derived values, and result variables. dir(m.set.<category>) exposes the full editable surface. Attempting to set a derived or result parameter raises a read-only error. If a valid model simply has no objects of a requested type, an all-object getter such as m.get.weir.crest_height() returns an empty result; explicit missing IDs still raise a clear UnknownIDError.

API reference notebooks

For users who prefer a browsable learning reference, the examples/ folder includes several complete Jupyter notebooks:

  • examples/11_all_get_functions.ipynb: a categorized guide to every available m.get.<main_category>.<sub_category>() function. It lists all categories and sub-items, shows the callable form, identifies input fields such as ids and format, and explains expected outputs for scalar values, arrays, DataFrames, structured fields, result variables, and empty object collections.
  • examples/12_all_set_functions.ipynb: a categorized guide to every available m.set.<main_category>.<sub_category>() path. It explains accepted value types, scalar broadcasting, 1D vector/Series inputs, structured payloads such as coordinates and geometry, reference validation, and which parameters are intentionally read-only.
  • examples/13_all_add_functions.ipynb: a complete constructor reference for m.add.<category>.<element_type>().
  • examples/14_all_remove_functions.ipynb: a complete removal reference for m.remove.<category>.<element_type>().
  • examples/15_all_plot_functions.ipynb: a complete plotting reference for layout, time-series, and profile functions.
  • examples/16_all_import_export_functions.ipynb: a complete import/export reference for m.import_csv, m.import_gis, and m.export.

These notebooks are useful both as tutorials and as a practical API checklist when editing models interactively in Jupyter, VS Code, or Spyder.

Counts

m.count.conduit()
m.count.node()
m.count.subcatchment()

total = m.count.model()
by_type = m.count.model_dict()
summary = m.count.model_df()

Count helpers take no ids or format arguments and always reflect the current in-memory model, including unsaved add/remove edits. m.count.model() totals detailed element types without double-counting composite rollups such as node and link; the dictionary and DataFrame summaries expose the detailed counts behind that total.

Add and remove elements

from swmmx import swmm

m = swmm(new="SI")

m.add.node.junction("J1", x=0.0, y=0.0, invert_elevation=10, max_depth=3)
m.add.node.outfall("OUT1", x=100.0, y=0.0, invert_elevation=9, type="FREE")

m.add.link.conduit(
    "C1",
    from_node="J1",
    to_node="OUT1",
    length=100,
    roughness=0.013,
    shape="CIRCULAR",
    diameter=1.0,
)

# Referenced objects must exist before they are used.
m.add.time.time_series(
    "Rain1",
    data=[
        ("2026-01-01 00:00", 0.0),
        ("2026-01-01 00:05", 5.0),
    ],
)
m.add.hydrology.rain_gage(
    "RG1",
    format="INTENSITY",
    interval="00:05",
    source_type="TIMESERIES",
    time_series="Rain1",
)
m.add.hydrology.subcatchment(
    "S1",
    rain_gage="RG1",
    outlet="J1",
    x=0.0,
    y=0.0,
    area=1.0,
)

m.save("new_model.inp")

m.remove.link.conduit("C1")

The add API validates IDs, required fields, numeric values, enums, and references before it writes EPA SWMM records. The remove API validates dependencies before deletion; by default it refuses unsafe removals, while force=True performs only conservative cascades that are known to remain valid. For example, removing a node with force=True can remove dependent conduits, but unsupported cascades raise a clear error instead of leaving broken references.

Coordinate handling is explicit where geometry is part of the object definition:

  • new node objects require x and y map coordinates;
  • new subcatchments require x and y centroid coordinates, while polygon= remains the optional outline geometry;
  • new rain gages may still omit coordinates, in which case swmmx uses the maximum mapped x and y, or (0, 0) when the model has no map coordinates.

Every add or remove operation sets m.modified to True. If the model already had results, the edit also sets m.results_stale to True and invalidates the old result accessors until the model is run again.

Generic fallbacks are also available:

m.add_element("node", "junction", "J2", x=200.0, y=0.0, invert_elevation=11, max_depth=2)
m.remove_element("node", "junction", "J2")

Add/remove reference notebooks

For a full constructor/removal reference, see:

  • examples/13_all_add_functions.ipynb: every m.add.<category>.<element_type>() endpoint, grouped by category, with tables for required inputs, optional inputs, types, defaults, coordinate rules, references, implementation status, and conditions.
  • examples/14_all_remove_functions.ipynb: every m.remove.<category>.<element_type>() endpoint, grouped by category, with tables for ids, force, dependency checks, removal summaries, implementation status, and safe-cascade behavior.

Plotting

swmmx uses matplotlib directly for network maps, result time series, and longitudinal profiles:

m.plot_layout()

m.plot_layout(
    title="Drainage Network",
    legend=True,
    grid=True,
    axis=True,
)

m.plot_layout(
    links={
        "color": {
            "by": "parameter",
            "category": "conduit",
            "variable": "roughness",
            "mode": "continuous",
            "cmap": "viridis",
        }
    }
)

m.plot_layout(
    annotation={
        "nodes": "id",
        "conduits": {
            "template": "{id}\nD={diameter:.2f} m",
            "rotation": "link",
            "bbox": True,
        },
    }
)

m.plot_timeseries.link.flow(["C1", "C2"])

m.plot_profile.nodes(
    "J1",
    "OUT1",
    show_hgl=True,
    aggregation="max",
)

m.plot_layout() draws mapped subcatchments, links, nodes, rain gages, and LID usages from the model coordinates. Subcatchments show dashed outlet connectors from each polygon centroid to its outlet node or downstream subcatchment. The default symbology is type-aware: node types use different markers, link types use different line styles, and LID controls use distinct markers in the legend when present. Presentation controls are explicit: title=... sets the map title, axis=True shows coordinate axes, grid=True keeps a visible reference grid even when coordinate labels stay hidden, and show=False suppresses automatic figure display while still returning (fig, ax). Layout maps now render titles, grids, and visible coordinate axes with safe ordinary artists instead of Matplotlib's native title/tick/grid machinery, avoiding the Spyder/Agg recursive tick-copy path while keeping the same public API. On non-interactive matplotlib canvases such as Agg, show=True avoids useless GUI calls but keeps the figure available for Spyder/Jupyter rendering; show=False removes only the library-created figure manager so hidden plots stay hidden.

Layer dictionaries support ordinary static styling as well as data-driven styling from fixed input parameters, simulation results, or your own ID-to-value mappings. Nodes, links, and subcatchments can be colored with continuous or discrete colormaps; nodes can use data-driven marker size, and links can use data-driven line width (or the size alias). Result-driven styles require a completed run; user-data styles are useful for classes such as risk bands, inspection status, or scenario groups. When color, size, or width is data-driven, the plot adds a dedicated legend section so the encoded value is visible on the finished figure instead of living only in the function call. Continuous-color legends are rendered with safe sampled swatches rather than native Matplotlib colorbar axes, which keeps Spyder/Agg rendering out of the recursive tick-copy path.

m.plot_layout(annotation=...) adds map labels without changing existing layout behavior. It supports simple ID annotations, multi-field labels, templates such as {id}\nD={diameter:.2f} m, prefixes, suffixes, numeric formatting, callables, per-layer styling, ID and conditional filtering, max_labels, external user data, and link-aligned rotation with rotation="link".

m.plot_timeseries.<category>.<sub_category>() routes through the result API and plots one or many timestamped series with matplotlib. The time axis has three explicit modes: time_format="datetime" for full date-time labels, time_format="clock" for hour-minute labels, and time_format="elapsed" for elapsed hours. X-axis tick labels are rotated 45 degrees by default for readability. Time-series and profile plots draw their title, grid, frame, ticks, and axis labels with safe ordinary artists instead of Matplotlib's native Axis artists, and their legends use lightweight proxy handles rather than cloning plotted Line2D artists. This keeps Spyder/Agg out of both recursive marker-copy paths while preserving the same public plotting API.

m.plot_profile.nodes(), .links(), and .longest() render geometry-first longitudinal profiles, with HGL/water overlays available after a run. Profiles show prominent vertical dotted node guides, shaded conduit barrels between invert and crown, and link names by default; distance and elevation axes infer ft or m automatically from the model units. m.plot_profile.links([...]) accepts any connected ordered walk, even when the supplied sequence runs opposite to the hydraulic direction.

All plotting calls return (fig, ax), accept ax= for composition, and support save_path= / save_format=. Common errors are explicit: layout plots need coordinates, result-based plots need m.run(), invalid IDs raise UnknownIDError, and disconnected profile requests raise NoPathError.

For a complete plotting reference, see examples/15_all_plot_functions.ipynb. It documents every plotting endpoint, every input and default, all dynamic time-series variables, runnable layer-dictionary examples for nodes/links/subcatchments/connectors/rain gages/LIDs/labels, custom-style legend behavior, profile controls, outputs, save behavior, and common validation errors.

Import

swmmx uses m.import_csv and m.import_gis instead of m.import because import is a reserved Python keyword. The import API mirrors the rest of the package:

m.import_csv.node.junction("junctions.csv")
m.import_csv.node.outfall("outfalls.csv")
m.import_csv.link.conduit("conduits.csv")
m.import_csv.hydrology.subcatchment("subcatchments.csv")

m.import_gis.node.junction("junctions.shp")
m.import_gis.link.conduit("pipes.geojson")
m.import_gis.hydrology.subcatchment("subcatchments.gpkg", layer="subcatchments")

Importers normalize column names, apply aliases such as Node ID -> id, Easting -> x, Northing -> y, validate rows, and return an ImportResult:

import_result = m.import_csv.node.junction("junctions.csv")
print(import_result.summary())

result = m.import_csv.link.conduit(
    "pipes.csv",
    field_map={
        "id": "PipeID",
        "from_node": "FromNode",
        "to_node": "ToNode",
        "length": "Length",
        "roughness": "ManningN",
        "diameter": "Diameter",
    },
)

print(result.summary())
print(result.to_frame())

Use dry_run=True to validate without modifying the model, and mode="upsert" to add missing objects while updating existing ones:

dry_run = m.import_csv.node.junction("junctions.csv", dry_run=True)
upserted = m.import_csv.node.junction("junctions.csv", mode="upsert")

Group-level shortcuts dispatch rows by a type column:

m.import_csv.node("nodes.csv", default_type="junction")
m.import_csv.link("links.csv", default_type="conduit")
m.import_gis.node("nodes.shp")
m.import_gis.link("links.shp")

Common options are mode="add" | "update" | "upsert", dry_run=True, on_missing_required="error" | "skip", on_unknown_fields="ignore" | "warn" | "error", and on_error="raise" | "skip" | "collect". GIS import lazily requires geopandas and shapely; install them with pip install geopandas shapely.

CSV files created by m.export.csv() are designed to import back cleanly. Exact SWMM input columns take priority over result or derived columns with similar names (for example, max_depth is preferred over exported result depth), and exported helper fields such as element_type, stage_data, source_data, and serialized coordinates are translated back into the matching import options where possible.

For a complete import/export reference, see examples/16_all_import_export_functions.ipynb.

Export

m.export.gis()

m.export.gis(
    path="exports/gis",
    elements=["nodes", "links", "subcatchments"],
)

m.export.csv(
    path="exports/csv",
    elements="all",
    time_step=-1,
)

m.export.excel(
    path="exports",
    file_name="model_export.xlsx",
)

If path is omitted, exports go beside the model file when one exists, otherwise into the current working directory. file_name controls a single workbook name or the prefix used for multi-file CSV/GIS exports. elements accepts named tables, groups such as hydrology or quality, or "all".

When results are available, time_step=-1 attaches the last simulated snapshot to result-capable tables. Without results, exports continue with parameter-only tables and a warning by default; use strict_results=True when missing results should be treated as an error. CSV writes one UTF-8 file per table, while Excel writes one workbook with one sheet per selected table. All CSV, Excel, and GIS export tables include a coordinates field: point objects store [x,y], links store the full coordinate chain from upstream node through vertices to downstream node, and subcatchments store polygon coordinates when available. Node-based and point-based export tables also include plain x and y fields: all node types use [COORDINATES], rain gages use [SYMBOLS], node-attached records inherit their node coordinates, and subcatchments/subcatchment-attached records use the polygon centre point.

GIS export writes spatial layers for nodes, links, subcatchments, and rain gages. It requires the optional packages geopandas and shapely (pip install geopandas shapely). Existing outputs are protected by default; pass overwrite=True only when replacing files is intentional.

Public parameter catalog

The public dotted API is organized into the following categories and subcategories:

  • option_general: flow_units, infiltration_model, flow_routing, link_offsets, force_main_equation, allow_ponding, minimum_slope, skip_steady_state, system_flow_tolerance, lateral_flow_tolerance
  • option_process: ignore_rainfall, ignore_snowmelt, ignore_groundwater, ignore_rdii, ignore_routing, ignore_quality
  • option_date_time: start_date, start_time, end_date, end_time, report_start_date, report_start_time, report_step, wet_step, dry_step, routing_step, rule_step, sweep_start, sweep_end, dry_days
  • option_dynamic_wave: inertial_damping, normal_flow_limited, surcharge_method, variable_step, minimum_step, lengthening_step, minimum_surface_area, head_tolerance, maximum_trials, threads
  • rain_gage: id, count, format, interval, snow_catch_factor, source_type, time_series, filename, station, units, rainfall
  • subcatchment: id, count, rain_gage, outlet, area, width, slope, impervious_percent, curb_length, snow_pack, tag, polygon, centroid, rainfall, snow_depth, evaporation, infiltration, runoff, groundwater_flow, groundwater_elevation, soil_moisture, pollutant_concentration, n_impervious, n_pervious, depression_storage_impervious, depression_storage_pervious, zero_depression_storage_impervious_percent, subarea_routing, percent_routed
  • infiltration_horton: maximum_rate, minimum_rate, decay, dry_time, maximum_volume
  • infiltration_green_ampt: suction_head, hydraulic_conductivity, initial_moisture_deficit
  • infiltration_curve_number: curve_number, conductivity, dry_time
  • node: id, count, type, invert_elevation, max_depth, initial_depth, surcharge_depth, ponded_area, tag, coordinate, external_inflow, dry_weather_flow, treatment, depth, head, volume, lateral_inflow, total_inflow, flooding, overflow, pollutant_concentration
  • junction: id, count, invert_elevation, max_depth, initial_depth, surcharge_depth, ponded_area
  • outfall: id, count, invert_elevation, type, fixed_stage, tidal_curve, time_series, tide_gate, route_to
  • flow_divider: id, count, invert_elevation, max_depth, initial_depth, surcharge_depth, ponded_area, type, diverted_link, cutoff_flow, diversion_curve, weir_height, weir_coefficient
  • storage_unit: id, count, invert_elevation, max_depth, initial_depth, storage_curve_type, storage_curve, area, area_coefficient, area_exponent, area_constant, evaporation_factor, seepage_loss
  • link: id, count, type, from_node, to_node, inlet_offset, outlet_offset, initial_flow, maximum_flow, flap_gate, tag, vertices, flow, depth, velocity, volume, capacity, setting, pollutant_concentration
  • conduit: id, count, from_node, to_node, length, roughness, inlet_offset, outlet_offset, initial_flow, maximum_flow, shape, geometry, barrels, culvert_code, entry_loss, exit_loss, average_loss, flap_gate, seepage_rate, slope, full_area, full_depth, hydraulic_radius, full_flow, normal_depth, critical_depth, flow, depth, velocity, capacity
  • pump: id, count, from_node, to_node, curve, initial_status, startup_depth, shutoff_depth, flow, status, setting, energy
  • orifice: id, count, from_node, to_node, type, shape, height, width, offset, discharge_coefficient, flap_gate, open_close_time, flow, setting
  • weir: id, count, from_node, to_node, type, crest_height, length, side_slope, discharge_coefficient, flap_gate, end_contractions, end_coefficient, surcharge, road_width, road_surface, flow, setting
  • outlet: id, count, from_node, to_node, offset, flap_gate, rating_type, curve, coefficient, exponent, flow, setting
  • cross_section: link, shape, geometry_1, geometry_2, geometry_3, geometry_4, barrels, culvert_code, height, width, side_slope, shape_curve
  • transect: id, count, roughness_left, roughness_right, roughness_channel, left_bank, right_bank, stations, elevations, modifiers
  • curve: id, count, type, x, y, points
  • coordinate: node_coordinates, subcatchment_coordinates, link_vertices, polygons, labels, map_dimensions, map_units
  • street: id, count, crown_width, curb_height, cross_slope, roughness, depression_storage, gutter_width, gutter_slope, spread
  • inlet: id, count, type, grate_length, grate_width, grate_type, curb_length, curb_height, slotted_length, slotted_width, captured_flow
  • inlet_usage: node, inlet, conduit, number, clogging_factor, flow_restriction
  • lid_control: id, count, type
  • lid_surface: storage_depth, vegetation_fraction, roughness, slope, side_slope
  • lid_pavement: thickness, void_ratio, impervious_surface_fraction, permeability, clogging_factor
  • lid_soil: thickness, porosity, field_capacity, wilting_point, conductivity, conductivity_slope, suction_head
  • lid_storage: height, void_ratio, seepage_rate, clogging_factor
  • lid_drain: coefficient, exponent, offset_height, delay, open_level, closed_level, control_curve
  • lid_usage: subcatchment, lid_control, number, area, width, initial_saturation, from_impervious_percent, from_pervious_percent, outlet, drain_to, inflow, evaporation, infiltration, surface_outflow, drain_outflow, storage
  • aquifer: id, count, porosity, wilting_point, field_capacity, conductivity, conductivity_slope, tension_slope, upper_evaporation_fraction, lower_evaporation_depth, lower_groundwater_loss_rate, bottom_elevation, water_table_elevation, unsaturated_moisture, upper_evaporation_pattern
  • groundwater: subcatchment, aquifer, node, surface_elevation, a1, b1, a2, b2, a3, fixed_depth, threshold_elevation, lateral_flow_equation, deep_flow_equation
  • snow_pack: id, count, plowable_fraction, impervious_fraction, pervious_fraction, minimum_melt_coefficient, maximum_melt_coefficient, base_temperature, free_water_capacity_fraction, initial_snow_depth, initial_free_water, depth_at_100_percent_cover, removal_depth, fraction_to_impervious, fraction_to_pervious, fraction_to_immediate_melt, fraction_to_subcatchment, fraction_to_outflow, destination_subcatchment
  • climate: temperature_time_series, evaporation_type, evaporation_constant, evaporation_monthly, evaporation_time_series, evaporation_recovery_pattern, evaporation_dry_only, wind_speed_type, wind_speed_monthly, snowmelt_parameters, areal_depletion_impervious, areal_depletion_pervious
  • climate_adjustment: temperature, evaporation, rainfall, conductivity
  • pollutant: id, count, units, rain_concentration, groundwater_concentration, rdii_concentration, decay_coefficient, snow_only, co_pollutant, co_pollutant_fraction, dry_weather_flow_concentration, initial_concentration
  • land_use: id, count, sweeping_interval, sweeping_availability, last_swept
  • coverage: subcatchment, land_use, percent
  • loading: subcatchment, pollutant, initial_buildup
  • buildup: land_use, pollutant, function, maximum_buildup, rate_constant, power, normalizer
  • washoff: land_use, pollutant, function, coefficient, exponent, cleaning_efficiency, bmp_efficiency
  • treatment: node, pollutant, expression
  • time_series: id, count, datetime, values, filename, description
  • time_pattern: id, count, type, multipliers
  • external_inflow: node, constituent, time_series, type, units_factor, scale_factor, baseline, pattern
  • dry_weather_flow: node, constituent, average_value, monthly_pattern, daily_pattern, hourly_pattern, weekend_pattern
  • rdii: node, unit_hydrograph, sewer_area
  • unit_hydrograph: id, count, rain_gage, month, short_term_r, short_term_t, short_term_k, medium_term_r, medium_term_t, medium_term_k, long_term_r, long_term_t, long_term_k
  • control_rule: id, count, text, conditions, actions, priority, enabled, action_log
  • interface_file: rainfall, runoff, hotstart, rdii, inflow, outflow, use_file, save_file
  • system_result: air_temperature, rainfall, snow_depth, evaporation, infiltration, runoff, dry_weather_inflow, groundwater_inflow, rdii_inflow, direct_inflow, total_lateral_inflow, flooding, outfall_flow, storage_volume, pollutant_loading
  • summary: model, counts, options, subcatchment_runoff, subcatchment_washoff, node_depth, node_inflow, node_flooding, node_surcharge, storage_volume, outfall_loading, link_flow, link_velocity, conduit_surcharge, pump_operation, lid_performance, runoff_continuity, flow_routing_continuity, quality_routing_continuity, validation_issues

Validation

validation = m.validate()
print(validation.ok)
print(validation.to_frame())

The first validator checks duplicate IDs, missing required options, invalid unit values, missing nodes/links, conduit endpoints, and several common cross-section/reference errors.

Comparison with common EPA SWMM Python packages

Feature / capability swmmx PySWMM swmm_api swmmio swmm-toolkit
Main purpose End-to-end SWMM modeling toolkit Runtime SWMM control SWMM file/result automation Pandas-based model/result analysis Low-level solver/output bindings
Unified model object Yes — m = swmm(...) Partial Partial Yes, but more DataFrame/file oriented No
Discoverable dotted API Yes — m.get, m.set, m.add, m.remove, m.import_csv, m.import_gis, m.export Limited More section/object oriented More pandas/DataFrame oriented Low-level API
Open existing .inp model Yes Yes Yes Yes Solver-level
Create new model from scratch Yes — swmm(new="SI"), m.add.* Limited / not main focus Supported in workflows Limited / not main focus No
Add/remove SWMM elements Yes — validated m.add.* and m.remove.* Limited Yes, through model/input structures Some support No
Structured parameter get/set Yes — broad public parameter catalog Yes for runtime objects Yes Yes via DataFrames Low-level
Step-by-step simulation Yes — m.runs() iterator Very strong; core strength Run support, less runtime-control focused Usually external / via integration Engine-level possible
Runtime control during simulation Developing / possible through m.runs() workflows Strongest option Not primary focus Not primary focus Low-level possible
Run SWMM from Python Yes — m.run() and m.runs() Yes Yes Usually via integration/tools Yes
Read simulation results Yes — result variables through m.get.* and plots Yes Yes, including .out / .rpt workflows Yes Output API level
Layout plotting Yes — built-in m.plot_layout() Not primary Available in ecosystem/examples Yes / visualization support No
Time-series plotting Yes — m.plot_timeseries.* User builds or uses ecosystem Possible Possible No
Longitudinal profile plotting Yes — m.plot_profile.* Not primary Available / supported in workflows Some visualization support No
CSV import Yes — m.import_csv.<category>.<element_type>() Not primary Possible through user workflows DataFrame-based workflows No
GIS import Yes — m.import_gis.<category>.<element_type>() Not primary GIS interaction available GeoDataFrame support No
CSV export Yes — m.export.csv() Not primary Possible DataFrame export possible No
GIS export Yes — m.export.gis() Not primary GIS interaction available GeoDataFrame support No
Excel export Yes — m.export.excel() Not primary Possible through pandas workflows Possible through pandas workflows No
Round-trip import/export workflow Yes — exported CSV designed to import back cleanly No Partial / workflow dependent Partial / workflow dependent No
Preserve .inp comments / unknown sections / section order Yes, where possible Not main focus Strong .inp handling .inp handling support No
Validation helpers Yes — m.validate() and import result reporting Engine/runtime errors Strong file/model checks depending workflow Data checks possible Low-level
Native engine handling Bundled Windows/Linux/macOS engines plus custom path Uses SWMM engine bindings Runs SWMM through configured executable/tooling Usually external / integration Solver bindings
Best use case Complete model lifecycle in one Python API Real-time control and simulation intervention Advanced .inp, .rpt, .out automation Pandas/GeoPandas engineering analysis Developers needing solver/output bindings
Main strength Unified, readable, high-level workflow Runtime control Mature file/result automation Pandas-first productivity Low-level SWMM access

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

swmmx-0.0.39.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

swmmx-0.0.39-py3-none-any.whl (1.2 MB view details)

Uploaded Python 3

File details

Details for the file swmmx-0.0.39.tar.gz.

File metadata

  • Download URL: swmmx-0.0.39.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for swmmx-0.0.39.tar.gz
Algorithm Hash digest
SHA256 89b8eb4777dddf55f04a59562ff7de4f2e4298d62b4ed4ea2bd905e1fd266a79
MD5 fab2413b5e6b2ad179975f52beaf111a
BLAKE2b-256 bec3e2d4d4872dc4f40a64b4c5286224f4df4fb204fa8717f4d51c8cd5547f33

See more details on using hashes here.

Provenance

The following attestation bundles were made for swmmx-0.0.39.tar.gz:

Publisher: publish.yml on mgeranmehr/swmmx_dev

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file swmmx-0.0.39-py3-none-any.whl.

File metadata

  • Download URL: swmmx-0.0.39-py3-none-any.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for swmmx-0.0.39-py3-none-any.whl
Algorithm Hash digest
SHA256 1080e16d130470576b06bdbb19c45229cb6e9f270859f27c05143219c12e305a
MD5 d89f791d1a2b0e4fd2aa6756c6706376
BLAKE2b-256 0d71413131475d655c31898dc0e22a0c7de078780955bc95bf9ba04e8f6a0aa6

See more details on using hashes here.

Provenance

The following attestation bundles were made for swmmx-0.0.39-py3-none-any.whl:

Publisher: publish.yml on mgeranmehr/swmmx_dev

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page