Live views, snapshots, and statistics
The right result interface depends on what you want to keep. A live view follows
the simulation; a saved number remembers what you read. swmmrs offers four
result forms for different amounts of data and different lifetimes:
| Form | Use | Ownership |
|---|---|---|
| Live scalar view | Read one or a few current properties. | Generation-bound; each property reads current native state. |
| Snapshot | Copy coherent values for several objects. | Immutable native record; remains valid after advancing or closing. |
| Statistics | Copy cumulative continuity or object summaries. | Immutable native record; acquisition is valid only while RUNNING or COMPLETE. |
| Binary series | Query stored report periods through OutputReader. |
Independent reader over a finalized file or complete records recovered from an incomplete file. |
Live values
node = simulation.nodes["J1"]
link = simulation.links["C1"]
for current_time in simulation:
print(current_time, node.depth, link.flow)
Retaining a live view across advances in one project generation is valid. Retaining it after close() or a replacement open() is not; access then raises StaleViewError.
See Property getters and Live Views for acquisition costs, retention patterns, lifecycle boundaries, and the scalar-versus-snapshot tradeoff.
Coherent snapshots
nodes = simulation.nodes.snapshot(["J1", "J2"])
for object_id, depth, inflow in zip(
nodes.object_ids,
nodes.depth,
nodes.total_inflow,
strict=True,
):
print(object_id, depth, inflow)
Snapshot columns align with object_ids, in the order of your selected IDs.
For frequent sampling, select the objects you need. Copying the whole network
to inspect two nodes gives the computer a great deal of unnecessary employment.
Quality snapshots use pollutant-major matrices: the first index selects
pollutant_ids, and the second selects object_ids.
Owned native records
Snapshot and statistics classes are frozen Rust-backed Python value objects. Only the solver can construct them. Their properties, tuples, matrices, and mappings cannot be mutated, and existing records do not retain a Simulation Owner or project generation.
sample = simulation.nodes.snapshot(["J1"])
print(repr(sample))
# Build an explicitly mutable host representation when needed.
editable_depths = list(sample.depth)
editable_depths[0] = 2.5
copy.copy() and copy.deepcopy() are unsupported because a copy would still
be the same immutable record shape. Extract the specific fields needed into
lists or dictionaries instead. Those host-side edits never change the record or
solver state.
Final statistics
Manual or iterator advancement exposes COMPLETE, where final statistics are still available:
simulation.start(save_results=False)
while simulation.step() is not None:
pass
system_statistics = simulation.statistics
node_statistics = simulation.nodes.statistics()
simulation.end()
simulation.close()
Copy statistics before end(). Once you have the records, they remain valid
along with any snapshots you already collected.
Data validity
| Acquisition | OPEN |
RUNNING |
COMPLETE |
ENDED |
|---|---|---|---|---|
| Current hydraulic or quality value | No | Yes | Yes | Yes |
| Hydraulic or quality snapshot | No | Yes | Yes | Yes |
| Statistics | No | Yes | Yes | No |
| Previously copied Python record | Yes | Yes | Yes | Yes |
See Collect results and statistics for field lists, acquisition routes, units, and complete collection workflows. Use Read binary output when the stored report-period artifact is the source of truth.