diff --git a/tests/data/example1.out b/tests/data/example1.out new file mode 100644 index 0000000..416c98b Binary files /dev/null and b/tests/data/example1.out differ diff --git a/tests/test_output.cpp b/tests/test_output.cpp index 3a0607e..c7fdc7a 100644 --- a/tests/test_output.cpp +++ b/tests/test_output.cpp @@ -22,7 +22,7 @@ #include "epanet_output.h" -#define DATA_PATH "./net1.out" +#define DATA_PATH "./example1.out" using namespace std; @@ -142,6 +142,15 @@ BOOST_FIXTURE_TEST_CASE(test_getNetSize, Fixture) ENR_free((void**)&i_array); } +BOOST_FIXTURE_TEST_CASE(test_getUnits, Fixture) { + int flag; + + error = ENR_getUnits(p_handle, ENR_chemUnits, &flag); + BOOST_REQUIRE(error == 0); + + BOOST_CHECK_EQUAL(flag, ENR_MGL); +} + BOOST_FIXTURE_TEST_CASE(test_getElementName, Fixture) { char* name = new char[MAXID]; int length, index = 1; diff --git a/tools/epanet-output/include/epanet_output.h b/tools/epanet-output/include/epanet_output.h index 0066d16..8a9b70e 100644 --- a/tools/epanet-output/include/epanet_output.h +++ b/tools/epanet-output/include/epanet_output.h @@ -18,22 +18,42 @@ typedef void* ENR_Handle; typedef enum { - ENR_node = 1, - ENR_link = 2 + ENR_node = 1, + ENR_link = 2 } ENR_ElementType; typedef enum { - ENR_getSeries = 1, - ENR_getAttribute = 2, - ENR_getResult = 3, - ENR_getReacts = 4, - ENR_getEnergy = 5 -} ENR_ApiFunction; + ENR_flowUnits = 1, + ENR_pressUnits = 2, + ENR_chemUnits = 3 +} ENR_Units; typedef enum { - ENR_flowUnits = 1, - ENR_pressUnits = 2 -} ENR_Units; + ENR_CFS = 0, + ENR_GPM = 1, + ENR_MGD = 2, + ENR_IMGD = 3, + ENR_AFD = 4, + ENR_LPS = 5, + ENR_LPM = 6, + ENR_MLD = 7, + ENR_CMH = 8, + ENR_CMD = 9 +} ENR_FlowUnits; + +typedef enum { + ENR_PSI = 0, + ENR_MTRS = 1, + ENR_KPA = 2 +} ENR_PressUnits; + +typedef enum { + ENR_NONE = 0, + ENR_MGL = 1, + ENR_UGL = 2, + ENR_HOURS = 3, + ENR_PRCNT = 4 +} ENR_ChemUnits; typedef enum { ENR_reportStart = 1, @@ -43,21 +63,21 @@ typedef enum { }ENR_Time; typedef enum { - ENR_demand = 1, - ENR_head = 2, - ENR_pressure = 3, - ENR_quality = 4 + ENR_demand = 1, + ENR_head = 2, + ENR_pressure = 3, + ENR_quality = 4 } ENR_NodeAttribute; typedef enum { - ENR_flow = 1, - ENR_velocity = 2, - ENR_headloss = 3, - ENR_avgQuality = 4, - ENR_status = 5, - ENR_setting = 6, - ENR_rxRate = 7, - ENR_frctnFctr = 8 + ENR_flow = 1, + ENR_velocity = 2, + ENR_headloss = 3, + ENR_avgQuality = 4, + ENR_status = 5, + ENR_setting = 6, + ENR_rxRate = 7, + ENR_frctnFctr = 8 } ENR_LinkAttribute; diff --git a/tools/epanet-output/src/epanet_output.c b/tools/epanet-output/src/epanet_output.c index 486ef81..7f21bee 100644 --- a/tools/epanet-output/src/epanet_output.c +++ b/tools/epanet-output/src/epanet_output.c @@ -57,7 +57,8 @@ #define MINNREC 14 // Minimum allowable number of records #define PROLOGUE 884 // Preliminary fixed length section of header -#define MAXID_P1 32 // Max. # characters in ID name +#define MAXID_P1 32 // EPANET max characters in ID name PLUS 1 +#define MAXMSG_P1 80 // EPANET max characters in message text PLUS 1 #define NELEMENTTYPES 5 // Number of element types #define NENERGYRESULTS 6 // Number of energy results @@ -303,6 +304,8 @@ int DLLEXPORT ENR_getUnits(ENR_Handle p_handle, ENR_Units code, int* unitFlag) */ { int errorcode = 0; + F_OFF offset; + char temp[MAXID_P1]; data_t* p_data; *unitFlag = -1; @@ -315,15 +318,37 @@ int DLLEXPORT ENR_getUnits(ENR_Handle p_handle, ENR_Units code, int* unitFlag) switch (code) { case ENR_flowUnits: - fseek(p_data->file, 9*WORDSIZE, SEEK_SET); + _fseek(p_data->file, 9*WORDSIZE, SEEK_SET); fread(unitFlag, WORDSIZE, 1, p_data->file); break; case ENR_pressUnits: - fseek(p_data->file, 10*WORDSIZE, SEEK_SET); + _fseek(p_data->file, 10*WORDSIZE, SEEK_SET); fread(unitFlag, WORDSIZE, 1, p_data->file); break; + case ENR_chemUnits: + offset = 7*WORDSIZE; + _fseek(p_data->file, offset, SEEK_SET); + fread(unitFlag, WORDSIZE, 1, p_data->file); + + if (*unitFlag == 0) *unitFlag = ENR_NONE; + + else if (*unitFlag == 1) { + offset = 15*WORDSIZE + 3*MAXMSG_P1 + 2*(MAXFNAME+1) + MAXID_P1; + _fseek(p_data->file, offset, SEEK_SET); + fread(temp, MAXID_P1, 1, p_data->file); + + if (!strcmp(temp, "mg/L")) *unitFlag = ENR_MGL; + else *unitFlag = ENR_UGL; + } + + else if (*unitFlag == 2) *unitFlag = ENR_HOURS; + + else *unitFlag = ENR_PRCNT; + + break; + default: errorcode = 421; } } @@ -378,6 +403,12 @@ int DLLEXPORT ENR_getTimes(ENR_Handle p_handle, ENR_Time code, int* time) return set_error(p_data->error_handle, errorcode); } +int DLLEXPORT ENR_getChemData(ENR_Handle p_handle, char** name, int* length) + +{ + return 0; +} + int DLLEXPORT ENR_getElementName(ENR_Handle p_handle, ENR_ElementType type, int elementIndex, char** name, int* length) /*------------------------------------------------------------------------ @@ -815,7 +846,7 @@ void errorLookup(int errcode, char* dest_msg, int dest_len) default: msg = ERRERR; } - strncpy(dest_msg, msg, MAXMSG); + strncpy(dest_msg, msg, MSGMAXLEN); } int validateFile(ENR_Handle p_handle) diff --git a/tools/epanet-output/src/messages.h b/tools/epanet-output/src/messages.h index 78725a1..d2515e9 100644 --- a/tools/epanet-output/src/messages.h +++ b/tools/epanet-output/src/messages.h @@ -10,7 +10,7 @@ #ifndef MESSAGES_H_ #define MESSAGES_H_ /*------------------- Error Messages --------------------*/ -#define MAXMSG 53 +#define MSGMAXLEN 53 #define WARN10 "Warning: model run issued warnings" diff --git a/tools/epanet-output/test/epanet_output_test.py b/tools/epanet-output/test/epanet_output_test.py deleted file mode 100644 index fa23d62..0000000 --- a/tools/epanet-output/test/epanet_output_test.py +++ /dev/null @@ -1,102 +0,0 @@ -# -# epanet_output_test.py -# -# Created: 11/8/2017 -# Author: Michael E. Tryby -# US EPA - ORD/NRMRL -# -# Unit testing for EPANET Output API using pytest. -# - -import pytest -import numpy as np - -import epanet_output as oapi - -from data import OUTPUT_FILE_EXAMPLE1 - -@pytest.fixture() -def enr_handle(request): - _handle = oapi.enr_init() - oapi.enr_open(_handle, OUTPUT_FILE_EXAMPLE1) - - def enr_close(): - oapi.enr_close() - - request.addfinalizer(enr_close) - return _handle - - -def test_get_times(enr_handle): - num_periods = oapi.enr_get_times(enr_handle, oapi.Time.NUM_PERIODS) - assert num_periods == 25 - - -# def test_get_size(file_path): -# handle = oapi.enr_init() -# oapi.enr_open(handle, file_path) -# -# size = oapi.enr_get_net_size(handle) -# -# print(size) -# -# handle = oapi.enr_close() -# -# def test_get_names(file_path): -# handle = oapi.enr_init() -# oapi.enr_open(handle, file_path) -# -# name = oapi.enr_get_element_name(handle, oapi.ElementType.NODE, 10) -# -# print(name) -# -# handle = oapi.enr_close() -# -# def test_get_energy(file_path): -# handle = oapi.enr_init() -# oapi.enr_open(handle, file_path) -# -# result = oapi.enr_get_energy_usage(handle, 1) -# -# print(result) -# -# handle = oapi.enr_close() -# -# def test_get_react(file_path): -# handle = oapi.enr_init() -# oapi.enr_open(handle, file_path) -# -# result = oapi.enr_get_net_reacts(handle) -# -# print(result) -# -# handle = oapi.enr_close() -# -def test_get_node_attribute(enr_handle): - ref_array = np.array([ 1., 0.44407997, 0.43766347, 0.42827705, 0.41342604, - 0.42804748, 0.44152543, 0.40502965, 0.38635802, 1., 0.96745253]) - - array = oapi.enr_get_node_attribute(enr_handle, 1, oapi.NodeAttribute.QUALITY) - assert len(array) == 11 - assert np.allclose(array, ref_array) - -def test_get_link_attribute(enr_handle): - ref_array = np.array([ 1848.58117676, 1220.42736816, 130.11161804, - 187.68930054, 119.88839722, 40.46448898, -748.58111572, 478.15377808, - 191.73458862, 30.11160851, 140.4644928, 59.53551483, 1848.58117676]) - - array = oapi.enr_get_link_attribute(enr_handle, 1, oapi.LinkAttribute.FLOW) - assert len(array) == 13 - assert np.allclose(array, ref_array) - -# if __name__ == "__main__": -# -# file_path = "M:\\net mydocuments\\EPA Projects\\EPAnet Examples\\net1.out" -# test_get_times(file_path) -# test_get_size(file_path) -# test_get_names(file_path) -# test_get_energy(file_path) -# test_get_react(file_path) -# test_get_node_attribute(file_path) -# test_get_link_attribute(file_path) -# \ No newline at end of file