Skip to content

Commit edb3c66

Browse files
authored
Merge pull request #17 from michaeltryby/dev
Ongoing development
2 parents c29e328 + 84f18c8 commit edb3c66

6 files changed

Lines changed: 108 additions & 39 deletions

File tree

output/epanet/output/__init__.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ def __init__(self, output_handle):
123123

124124
# Determine unit system from flow setting
125125
if self._flow.value <= oapi.FlowUnits.AFD.value:
126-
self.unit_labels = type(self)._unit_labels_us_
126+
self._unit_labels = type(self)._unit_labels_us_
127127
else:
128-
self.unit_labels = type(self)._unit_labels_si_
128+
self._unit_labels = type(self)._unit_labels_si_
129129

130130
# Determine mass units from quality settings
131131
if self._qual == oapi.QualUnits.MGL:
@@ -137,25 +137,25 @@ def __init__(self, output_handle):
137137

138138

139139
self._metadata = {
140-
oapi.NodeAttribute.DEMAND: ("Demand", self.unit_labels[self._flow]),
141-
oapi.NodeAttribute.HEAD: ("Head", self.unit_labels[Units.HYD_HEAD]),
142-
oapi.NodeAttribute.PRESSURE: ("Pressure", self.unit_labels[self._press]),
143-
oapi.NodeAttribute.QUALITY: ("Quality", self.unit_labels[self._qual]),
140+
oapi.NodeAttribute.DEMAND: ("Demand", self._unit_labels[self._flow]),
141+
oapi.NodeAttribute.HEAD: ("Head", self._unit_labels[Units.HYD_HEAD]),
142+
oapi.NodeAttribute.PRESSURE: ("Pressure", self._unit_labels[self._press]),
143+
oapi.NodeAttribute.QUALITY: ("Quality", self._unit_labels[self._qual]),
144144

145-
oapi.LinkAttribute.FLOW: ("Flow", self.unit_labels[self._flow]),
146-
oapi.LinkAttribute.VELOCITY: ("Velocity", self.unit_labels[Units.VELOCITY]),
147-
oapi.LinkAttribute.HEADLOSS: ("Unit Headloss", self.unit_labels[Units.HEADLOSS]),
148-
oapi.LinkAttribute.AVG_QUALITY: ("Quality", self.unit_labels[self._qual]),
149-
oapi.LinkAttribute.STATUS: ("Status", self.unit_labels[Units.NONE]),
150-
oapi.LinkAttribute.SETTING: ("Setting", self.unit_labels[Units.NONE]),
151-
oapi.LinkAttribute.RX_RATE: ("Reaction Rate", self.unit_labels[self._rx_rate]),
152-
oapi.LinkAttribute.FRCTN_FCTR: ("Friction Factor", self.unit_labels[Units.UNITLESS])
145+
oapi.LinkAttribute.FLOW: ("Flow", self._unit_labels[self._flow]),
146+
oapi.LinkAttribute.VELOCITY: ("Velocity", self._unit_labels[Units.VELOCITY]),
147+
oapi.LinkAttribute.HEADLOSS: ("Unit Headloss", self._unit_labels[Units.HEADLOSS]),
148+
oapi.LinkAttribute.AVG_QUALITY: ("Quality", self._unit_labels[self._qual]),
149+
oapi.LinkAttribute.STATUS: ("Status", self._unit_labels[Units.NONE]),
150+
oapi.LinkAttribute.SETTING: ("Setting", self._unit_labels[Units.NONE]),
151+
oapi.LinkAttribute.RX_RATE: ("Reaction Rate", self._unit_labels[self._rx_rate]),
152+
oapi.LinkAttribute.FRCTN_FCTR: ("Friction Factor", self._unit_labels[Units.UNITLESS])
153153
}
154154

155155

156156
def get_attribute_metadata(self, attribute):
157157
'''
158-
Takes an attribute enum and returns the name and units in a tuple.
158+
Takes an attribute enum and returns a tuple with name and units.
159159
'''
160160
return self._metadata[attribute]
161161

output/epanet/output/output.i

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,16 @@ and return a (possibly) different pointer */
118118
/* OUTPUT argout */
119119
%append_output(SWIG_NewPointerObj(SWIG_as_voidptr(retval$argnum), $1_descriptor, 0));
120120
}
121+
%typemap(in) ENR_Handle* p_handle_inout (ENR_Handle retval)
122+
{
123+
/* INOUT in */
124+
SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&retval), 0, 0);
125+
$1 = &retval;
126+
}
121127
/* No need for special IN typemap for opaque pointers, it works anyway */
122128

123129

130+
124131
/* TYPEMAP FOR IGNORING INT ERROR CODE RETURN VALUE */
125132
%typemap(out) int {
126133
$result = Py_None;
@@ -231,16 +238,26 @@ int DLLEXPORT ENR_getEnergyUsage(ENR_Handle p_handle, int pumpIndex,
231238
int* int_out, float** float_out, int* int_dim);
232239
int DLLEXPORT ENR_getNetReacts(ENR_Handle p_handle, float** float_out, int* int_dim);
233240

234-
241+
int DLLEXPORT ENR_getNodeSeries(ENR_Handle p_handle_in, int nodeIndex, ENR_NodeAttribute t_enum,
242+
int startPeriod, int endPeriod, float** float_out, int* int_dim);
243+
int DLLEXPORT ENR_getLinkSeries(ENR_Handle p_handle_in, int linkIndex, ENR_LinkAttribute t_enum,
244+
int startPeriod, int endPeriod, float** float_out, int* int_dim);
245+
235246
int DLLEXPORT ENR_getNodeAttribute(ENR_Handle p_handle, int periodIndex,
236-
ENR_NodeAttribute t_enum, float** float_out, int* int_dim);
247+
ENR_NodeAttribute t_enum, float** float_out, int* int_dim);
237248
int DLLEXPORT ENR_getLinkAttribute(ENR_Handle p_handle, int periodIndex,
238-
ENR_LinkAttribute t_enum, float** float_out, int* int_dim);
249+
ENR_LinkAttribute t_enum, float** float_out, int* int_dim);
250+
251+
int DLLEXPORT ENR_getNodeResult(ENR_Handle p_handle_in, int periodIndex,
252+
int nodeIndex, float** float_out, int* int_dim);
253+
int DLLEXPORT ENR_getLinkResult(ENR_Handle p_handle_in, int periodIndex,
254+
int linkIndex, float** float_out, int* int_dim);
255+
239256
%exception;
240257

241258
/* NO EXCEPTION HANDLING FOR THESE FUNCTIONS */
242259
int DLLEXPORT ENR_init(ENR_Handle* p_handle_out);
243-
int DLLEXPORT ENR_close(ENR_Handle* p_handle_out);
260+
int DLLEXPORT ENR_close(ENR_Handle* p_handle_inout);
244261
void DLLEXPORT ENR_free(void** array);
245262

246263
void DLLEXPORT ENR_clearError(ENR_Handle p_handle);

output/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@
3838
package_data = {'epanet.output':['*epanet-output.dll', '*epanet-output.so']},
3939

4040
install_requires = [
41-
'enum34'
41+
'aenum'
4242
]
4343
)

output/tests/test_output.py

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
11

22

33
import pytest
4+
import numpy as np
45

56
from epanet.output import OutputMetadata
67
from epanet.output import output as oapi
78

89
from data import OUTPUT_FILE_EXAMPLE1
910

1011

11-
def test_outputmetadata_handle():
12+
13+
@pytest.fixture()
14+
def handle(request):
15+
_handle = oapi.init()
16+
oapi.open(_handle, OUTPUT_FILE_EXAMPLE1)
17+
18+
def close():
19+
oapi.close(_handle)
20+
21+
request.addfinalizer(close)
22+
return _handle
23+
24+
25+
def test_outputmetadata_handle(handle):
1226

27+
om = OutputMetadata(handle)
28+
1329
ref = {
1430
oapi.NodeAttribute.DEMAND: ("Demand", "gal/min"),
1531
oapi.NodeAttribute.HEAD: ("Head", "ft"),
@@ -24,11 +40,6 @@ def test_outputmetadata_handle():
2440
oapi.LinkAttribute.SETTING: ("Setting", ""),
2541
oapi.LinkAttribute.RX_RATE: ("Reaction Rate", "mg/hr"),
2642
oapi.LinkAttribute.FRCTN_FCTR: ("Friction Factor", "unitless")}
27-
28-
handle = oapi.init()
29-
oapi.open(handle, OUTPUT_FILE_EXAMPLE1)
30-
31-
om = OutputMetadata(handle)
3243

3344
for attr in oapi.NodeAttribute:
3445
temp = om.get_attribute_metadata(attr)
@@ -38,3 +49,51 @@ def test_outputmetadata_handle():
3849
temp = om.get_attribute_metadata(attr)
3950
assert temp == ref[attr]
4051

52+
53+
def test_getnodeSeries(handle):
54+
55+
ref_array = np.array(
56+
[119.25731,
57+
120.45029,
58+
121.19854,
59+
122.00622,
60+
122.37414,
61+
122.8122,
62+
122.82034,
63+
122.90379,
64+
123.40434,
65+
123.81807])
66+
67+
array = oapi.getnodeseries(handle, 2, oapi.NodeAttribute.PRESSURE, 0, 10)
68+
assert len(array) == 10
69+
70+
assert np.allclose(array, ref_array)
71+
72+
73+
def test_getlinkseries(handle):
74+
pass
75+
76+
def test_getnodeattribute(handle):
77+
ref_array = np.array([ 1., 0.44407997, 0.43766347, 0.42827705, 0.41342604,
78+
0.42804748, 0.44152543, 0.40502965, 0.38635802, 1., 0.96745253])
79+
80+
array = oapi.getnodeattribute(handle, 1, oapi.NodeAttribute.QUALITY)
81+
assert len(array) == 11
82+
assert np.allclose(array, ref_array)
83+
84+
85+
def test_getlinkattribute(handle):
86+
ref_array = np.array([ 1848.58117676, 1220.42736816, 130.11161804,
87+
187.68930054, 119.88839722, 40.46448898, -748.58111572, 478.15377808,
88+
191.73458862, 30.11160851, 140.4644928, 59.53551483, 1848.58117676])
89+
90+
array = oapi.getlinkattribute(handle, 1, oapi.LinkAttribute.FLOW)
91+
assert len(array) == 13
92+
assert np.allclose(array, ref_array)
93+
94+
95+
def test_getnoderesult(handle):
96+
pass
97+
98+
def test_getlinkresult(handle):
99+
pass

toolkit/epanet/toolkit/toolkit.i

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ and return a (possibly) different pointer */
208208

209209

210210
/* RENAME FUNCTIONS PYTHON STYLE */
211-
%rename("%(undercase)s") "";
211+
%rename("%(regex:/^\w+_([a-zA-Z]+)/\L\\1/)s") "";
212212

213213
/* GENERATES DOCUMENTATION */
214214
%feature("autodoc", "2");
@@ -229,10 +229,6 @@ and return a (possibly) different pointer */
229229
}
230230

231231
/* INSERT EXCEPTION HANDLING FOR THESE FUNCTIONS */
232-
// RUNNING A COMPLETE CMD LINE STYLE SIMULATION
233-
int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *inpFile,
234-
const char *rptFile, const char *binOutFile, void(*callback) (char *));
235-
236232
// OPENING A CLOSING THE EPANET TOOLKIT SYSTEM
237233
int DLLEXPORT EN_open(EN_ProjectHandle ph, const char *f1, const char *f2, const char *f3);
238234
int DLLEXPORT EN_close(EN_ProjectHandle ph);
@@ -306,8 +302,8 @@ int DLLEXPORT EN_setstatusreport(EN_ProjectHandle ph, int code);
306302
%exception;
307303

308304
/* NO EXCEPTION HANDLING FOR THESE FUNCTIONS */
309-
int DLLEXPORT EN_alloc(EN_ProjectHandle *ph_out);
310-
int DLLEXPORT EN_free(EN_ProjectHandle *ph_inout);
305+
int DLLEXPORT EN_createproject(EN_ProjectHandle *ph_out);
306+
int DLLEXPORT EN_deleteproject(EN_ProjectHandle *ph_inout);
311307

312308
int DLLEXPORT EN_getversion(int *version);
313309

toolkit/setup.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,16 @@
2323
version = "0.0.1",
2424
ext_modules = [
2525
Extension("epanet.toolkit._toolkit",
26-
include_dirs = ['epanet/toolkit/'],
26+
include_dirs = ['epanet/toolkit'],
2727
libraries = ['epanet'],
2828
library_dirs = ['epanet/toolkit'],
2929
sources = ['epanet/toolkit/toolkit.i'],
30-
swig_opts=['-py3'],
30+
swig_opts = ['-py3'],
3131
language = 'C'
3232
)
3333
],
3434
packages = {'epanet.toolkit'},
3535
py_modules = ['toolkit'],
3636
package_data = {'epanet.toolkit':['*epanet.dll', '*epanet.so']},
37-
38-
install_requires = [
39-
'enum34'
40-
]
37+
4138
)

0 commit comments

Comments
 (0)