Skip to content

Commit fdd07db

Browse files
committed
Add date and time functions and tests to output module
1 parent 169623d commit fdd07db

4 files changed

Lines changed: 91 additions & 2 deletions

File tree

swmm-toolkit/src/swmm/toolkit/output.i

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,14 @@ and return a (possibly) different pointer */
6161

6262
%apply int *OUTPUT {
6363
int *version,
64-
int *time
64+
int *time,
65+
int *year,
66+
int *month,
67+
int *day,
68+
int *hour,
69+
int *minute,
70+
int *second,
71+
int *dayOfWeek
6572
}
6673

6774
%cstring_output_allocate_size(char **elementName, int *size, SMO_freeMemory(*$1));
@@ -84,6 +91,23 @@ and return a (possibly) different pointer */
8491
}
8592

8693

94+
/* TYPEMAPS FOR MEMORY MANAGEMNET OF DOUBLE ARRAYS */
95+
%typemap(in, numinputs=0)double **double_out (double *temp), int *int_dim (int temp){
96+
$1 = &temp;
97+
}
98+
%typemap(argout) (double **double_out, int *int_dim) {
99+
if (*$1) {
100+
PyObject *o = PyList_New(*$2);
101+
double* temp = *$1;
102+
for(int i=0; i<*$2; i++) {
103+
PyList_SetItem(o, i, PyFloat_FromDouble((double)temp[i]));
104+
}
105+
$result = SWIG_AppendOutput($result, o);
106+
SMO_freeMemory(*$1);
107+
}
108+
}
109+
110+
87111
/* TYPEMAPS FOR MEMORY MANAGEMENT OF INT ARRAYS */
88112
%typemap(in, numinputs=0)int **int_out (int *temp), int *int_dim (int temp){
89113
$1 = &temp;
@@ -151,6 +175,8 @@ and return a (possibly) different pointer */
151175
%ignore SMO_clearError;
152176
%ignore SMO_checkError;
153177

178+
%noexception SMO_decodeDate;
179+
154180
%include "swmm_output.h"
155181

156182
%exception;

swmm-toolkit/src/swmm/toolkit/output_rename.i

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
%rename(get_times) SMO_getTimes;
2121
%rename(get_elem_name) SMO_getElementName;
2222

23+
%rename(get_date_time) SMO_getDateTime;
24+
%rename(get_date_series) SMO_getDateSeries;
25+
%rename(decode_date) SMO_decodeDate;
26+
2327
%rename(get_subcatch_series) SMO_getSubcatchSeries;
2428
%rename(get_node_series) SMO_getNodeSeries;
2529
%rename(get_link_series) SMO_getLinkSeries;

swmm-toolkit/swmm-solver

swmm-toolkit/tests/test_output.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,65 @@ def test_getelementname(handle):
8585
assert output.get_elem_name(handle, shared_enum.ElementType.NODE, 1) == "10"
8686

8787

88+
89+
def test_getdatetime(handle):
90+
date0 = output.get_date_time(handle, 0)
91+
date1 = output.get_date_time(handle, 1)
92+
assert isinstance(date0, (float, np.floating))
93+
94+
step_seconds = output.get_times(handle, shared_enum.Time.REPORT_STEP)
95+
step_days = step_seconds / 86400.0
96+
97+
# consecutive timestamps differ by exactly one report step (in days)
98+
assert np.isclose(date1 - date0, step_days)
99+
100+
# first timestamp should be strictly after the saved start date anchor
101+
assert date0 > output.get_start_date(handle)
102+
103+
104+
def test_getdateseries(handle):
105+
start, end = 0, 5
106+
dates = output.get_date_series(handle, start, end)
107+
108+
assert len(dates) == end - start + 1
109+
110+
step_days = output.get_times(handle, shared_enum.Time.REPORT_STEP) / 86400.0
111+
diffs = np.diff(dates)
112+
113+
# monotonic and evenly spaced by report step
114+
assert np.allclose(diffs, step_days)
115+
assert np.isclose(dates[-1], dates[0] + (end - start) * step_days)
116+
117+
118+
def test_decodedate(handle):
119+
# decoded components are plausible
120+
date0 = output.get_date_time(handle, 0)
121+
y, m, d, hh, mm, ss, dow = output.decode_date(date0)
122+
123+
assert 1 <= m <= 12
124+
assert 1 <= d <= 31
125+
assert 0 <= hh <= 23
126+
assert 0 <= mm <= 59
127+
assert 0 <= ss <= 59
128+
assert 1 <= dow <= 7
129+
130+
# consecutive decode respects the report step
131+
date1 = output.get_date_time(handle, 1)
132+
y1, m1, d1, hh1, mm1, ss1, dow1 = output.decode_date(date1)
133+
134+
step_seconds = output.get_times(handle, shared_enum.Time.REPORT_STEP)
135+
step_hours = (step_seconds // 3600) % 24
136+
137+
# minutes/seconds remain constant for steps divisible by 60s
138+
if step_seconds % 60 == 0:
139+
assert mm1 == mm
140+
assert ss1 == ss
141+
142+
# hour advances by step_hours modulo 24 (day rollover allowed)
143+
assert ((hh1 - hh) % 24) == step_hours
144+
145+
146+
88147
def test_getsubcatchseries(handle):
89148

90149
ref_array = np.array([0.0,

0 commit comments

Comments
 (0)