Skip to content

Commit b4e10cf

Browse files
committed
WIP test_series
1 parent 5794c0b commit b4e10cf

1 file changed

Lines changed: 96 additions & 0 deletions

File tree

swmm-toolkit/tests/test_series.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
from datetime import datetime, timedelta
2+
import os
3+
import pytest
4+
from swmm.toolkit import solver, output, shared_enum
5+
6+
DATA_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), "data")
7+
INPUT_FILE = os.path.join(DATA_PATH, "test_Example1.inp")
8+
REPORT_FILE = os.path.join(DATA_PATH, "temp_align.rpt")
9+
OUTPUT_FILE = os.path.join(DATA_PATH, "temp_align.out")
10+
11+
REPORT_STEP_SECONDS = 3600 # Example1
12+
13+
def _curr_dt():
14+
y, m, d, hh, mm, ss = solver.simulation_get_current_datetime()
15+
return datetime(y, m, d, hh, mm, ss)
16+
17+
def build_link_flow_solver_tuples_aligned():
18+
tuples = []
19+
solver.swmm_open(INPUT_FILE, REPORT_FILE, OUTPUT_FILE)
20+
try:
21+
solver.swmm_start(0)
22+
# After start callback
23+
# period_end = _curr_dt()
24+
# value = solver.link_get_result(0, shared_enum.LinkResult.FLOW)
25+
# tuples.append((period_end, value))
26+
27+
while True:
28+
# Before step callback
29+
#
30+
time_left = solver.swmm_stride(REPORT_STEP_SECONDS)
31+
# After step callback
32+
#
33+
if time_left == 0:
34+
break
35+
# Value for the interval that just ended; align to its period-end timestamp
36+
period_end = _curr_dt() - timedelta(seconds=REPORT_STEP_SECONDS)
37+
value = solver.link_get_result(0, shared_enum.LinkResult.FLOW)
38+
tuples.append((period_end, value))
39+
40+
# Before end callback
41+
period_end = _curr_dt() - timedelta(seconds=REPORT_STEP_SECONDS)
42+
value = solver.link_get_result(0, shared_enum.LinkResult.FLOW)
43+
tuples.append((period_end, value))
44+
45+
solver.swmm_end()
46+
# After end callback
47+
#
48+
49+
finally:
50+
solver.swmm_close()
51+
# After close callback
52+
#
53+
return tuples
54+
55+
def build_link_flow_output_tuples():
56+
EPOCH_SWMM = datetime(1899, 12, 30)
57+
h = output.init()
58+
output.open(h, os.path.join(DATA_PATH, "test_Example1.out"))
59+
try:
60+
start_days = output.get_start_date(h)
61+
rpt = output.get_times(h, shared_enum.Time.REPORT_STEP)
62+
n = output.get_times(h, shared_enum.Time.NUM_PERIODS)
63+
start_dt = EPOCH_SWMM + timedelta(days=start_days)
64+
vals = output.get_link_series(h, 0, shared_enum.LinkAttribute.FLOW_RATE, 0, n - 1)
65+
tuples = [(start_dt + timedelta(seconds=i * rpt), float(vals[i])) for i in range(n)]
66+
finally:
67+
output.close(h)
68+
return tuples
69+
70+
def test_compare_aligned_series():
71+
s = build_link_flow_solver_tuples_aligned()
72+
o = build_link_flow_output_tuples()
73+
74+
# times must match
75+
solver_times = [t.strftime("%Y-%m-%d %H:%M:%S") for t, _ in s]
76+
output_times = [t.strftime("%Y-%m-%d %H:%M:%S") for t, _ in o]
77+
assert solver_times == output_times, (
78+
"Time axes differ.\n"
79+
f"Solver times: {solver_times[:5]} ...\n"
80+
f"Output times: {output_times[:5]} ..."
81+
)
82+
83+
# values should match within tolerance
84+
import numpy as np
85+
86+
solver_vals = np.array([v for _, v in s])
87+
output_vals = np.array([v for _, v in o])
88+
89+
assert np.allclose(solver_vals, output_vals, rtol=1e-6, atol=1e-9), (
90+
"Solver and output values differ. "
91+
"See zipped output for details:\n" +
92+
"\n".join(
93+
f"{t1.strftime('%Y-%m-%d %H:%M:%S')} | {v1:.6f} || {t2.strftime('%Y-%m-%d %H:%M:%S')} | {v2:.6f} | diff={v1-v2:.2e}"
94+
for (t1, v1), (t2, v2) in list(zip(s, o))[:10]
95+
)
96+
)

0 commit comments

Comments
 (0)