diff --git a/output/setup.py b/output/setup.py new file mode 100644 index 00000000..526d9f59 --- /dev/null +++ b/output/setup.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +# +# setup.py +# +# Author: Michael E. Tryby +# US EPA - ORD/NRMRL +# +# + +'''Setup up script for SWMM Output API python extension''' + +try: + from setuptools import setup, Extension + from setuptools.command.build_ext import build_ext +except ImportError: + from distutils.core import setup, Extension + from distutils.command.build_ext import build_ext + + +setup( + name = "swmm-output", + version = "0.1.0-alpha", + + ext_modules = [ + Extension("swmm.output._output", + include_dirs = ['swmm/output/'], + libraries = ['swmm-output'], + library_dirs = ['swmm/output/'], + sources = ['swmm/output/output.i'], + swig_opts=['-py3'], + language='C' + ) + ], + packages = ['swmm.output'], + py_modules = ['output'], + package_data = {'swmm.output':['*swmm-output.dll', '*swmm-output.so']}, + + install_requires = [ + 'enum34' + ] +) diff --git a/output/swmm/output/__init__.py b/output/swmm/output/__init__.py new file mode 100644 index 00000000..75801509 --- /dev/null +++ b/output/swmm/output/__init__.py @@ -0,0 +1,87 @@ + +from swmm.output import output + + +# Units of Measurement +# +# Parameter Long Name US Customary SI Metric +# AREA_SUBCATCH Subcatchment Area acres ac hectares ha +# AREA_STOR Storage Unit Area square feet sq ft square meters sq m +# AREA_POND Ponding Area square feet sq ft square meters sq m +# CAP_SUC Capillary Suction inches in millimeters mm +# CONC Concentration milligrams/liter mg/L milligrams/liter mg/L +# micrograms/liter ug/L micrograms/liter ug/L +# counts/liter Count/L counts/liter Count/L +# INFIL_DECAY Infiltration Decay Constant 1/hours 1/hrs 1/hours 1/hrs +# POLLUT_DECAY Pollutant Decay Constant 1/days 1/days 1/days 1/days +# DEPRES_STOR Depression Storage inches in millimeters mm +# DEPTH Depth feet ft meters m +# DIAM Diameter feet ft meters m +# DISC_COEFF_ORIF Orifice Discharge Coefficient dimensionless dimless dimensionless dimless +# DISC_COEFF_WEIR Weir Discharge Coefficient CFS/foot^n CFS/ft^n CMS/meter^n CMS/m^n +# ELEV Elevation feet ft meters m +# EVAP_RATE Evaporation inches/day in/day millimeters/day mm/day +# FLOW_RATE Flow cubic feet/sec CFS cubic meter/sec CMS +# gallons/minute GPM liter/sec LPS +# million gallons/day MGD million liter/day MLD +# HEAD Head feet ft meters m +# HYD_CONDUCT Hydraulic Conductivity inches/hour in/hr millimeters/hour mm/hr +# INFIL_RATE Infiltration Rate inches/hour in/hr millimeters/hour mm/hr +# LEN Length feet ft meters m +# MANN_N Manning's n seconds/meter^1/3 sec/m^1/3 seconds/meter^1/3 sec/m^1/3 +# POLLUT_BUILDUP Pollutant Buildup mass/length mass/len mass/length mass/len +# mass/acre mass/ac mass/hectare mass/ha +# RAIN_INTENSITY Rainfall Intensity inches/hour in/hr millimeters/hour mm/hr +# RAIN_VOLUME Rainfall Volume inches in millimeters mm +# SLOPE_SUBCATCH Subcatchment Slope percent percent percent percent +# SLOPE_XSEC Cross Section Slope rise/run rise/run rise/run rise/run +# STREET_CLEAN_INT Street Cleaning Interval days days days days +# VOLUME Volume cubic feet cu ft cubic meters cu m +# WIDTH Width feet ft meters m + + +# Output Metadata +# +# Subcatch Attributes Long Name Parameter Name +# RAINFALL Rainfall RAIN_INTENSITY +# SNOW_DEPTH Snow Depth DEPTH +# EVAP_LOSS Evaporation Loss LOSS_RATE +# INFIL_LOSS Infiltration Loss LOSS_RATE +# RUNOFF_RATE Runoff Rate FLOW_RATE +# GW_OUTFLOW_RATE Groundwater Flow Rate FLOW_RATE +# GW_TABLE_ELEV Groundwater Elevation ELEV +# SOIL_MOISTURE Soil Moisture PERCENT +# POLLUT_CONC Pollutant Concentration CONC + +# Node Attributes +# INVERT_DEPTH Invert Depth DEPTH +# HYDRAULIC_HEAD Hydraulic Head HEAD +# PONDED_VOLUME Ponded Volume VOLUME +# LATERAL_INFLOW Lateral Inflow FLOW_RATE +# TOTAL_INFLOW Total Inflow FLOW_RATE +# FLOODING_LOSSES Flooding Loss FLOW_RATE +# POLLUT_CONC Pollutant Concentration CONC + +# Link Attributes +# FLOW_RATE Flow Rate FLOW_RATE +# FLOW_DEPTH Flow Depth DEPTH +# FLOW_VELOCITY Flow Velocity VELOCITY +# FLOW_VOLUME Flow Volume VOLUME +# CAPACITY Capacity PERCENT +# POLLUT_CONC Pollutant Concentration CONC + +# System Attributes +# AIR_TEMP Temperature TEMP +# RAINFALL Rainfall RAIN_INTENSITY +# SNOW_DEPTH Snow Depth DEPTH +# EVAP_INFIL_LOSS Evap and Infil Losses LOSS_RATE +# RUNOFF_FLOW Runoff Flow Rate FLOW_RATE +# DRY_WEATHER_INFLOW Dry Weather Inflow FLOW_RATE +# GW_INFLOW Groundwater Inflow FLOW_RATE +# RDII_INFLOW RDII Inflow FLOW_RATE +# DIRECT_INFLOW Direct Inflow FLOW_RATE +# TOTAL_LATERAL_INFLOW Total Lateral Inflow FLOW_RATE +# FLOOD_LOSSES Flood Losses FLOW_RATE +# OUTFALL_FLOWS Outfall Flow FLOW_RATE +# VOLUME_STORED Volume Stored VOLUME +# EVAP_RATE Evaporation Rate LOSS_RATE diff --git a/output/swmm/output/output.i b/output/swmm/output/output.i new file mode 100644 index 00000000..99b11ce7 --- /dev/null +++ b/output/swmm/output/output.i @@ -0,0 +1,343 @@ +/* + * swmm_output.i - SWIG interface description file for SWMM Output API + * + * Created: 11/3/2017 + * Author: Michael E. Tryby + * US EPA - ORD/NRMRL + * +*/ + +%module(package="swmm") output +%{ +#include "swmm_output.h" + +#define SWIG_FILE_WITH_INIT +%} + +%include "typemaps.i" + +/* DEFINE AND TYPEDEF MUST BE INCLUDED */ +typedef void* SMO_Handle; + +typedef enum { + SMO_flow_rate, + SMO_concentration +} SMO_unit; + +typedef enum { + SMO_subcatch, + SMO_node, + SMO_link, + SMO_sys +} SMO_elementType; + +typedef enum { + SMO_reportStep, + SMO_numPeriods +} SMO_time; + +typedef enum { + SMO_rainfall_subcatch, // (in/hr or mm/hr), + SMO_snow_depth_subcatch, // (in or mm), + SMO_evap_loss, // (in/hr or mm/hr), + SMO_infil_loss, // (in/hr or mm/hr), + SMO_runoff_rate, // (flow units), + SMO_gwoutflow_rate, // (flow units), + SMO_gwtable_elev, // (ft or m), + SMO_soil_moisture, // unsaturated zone moisture content (-), + SMO_pollutant_conc_subcatch // first pollutant +} SMO_subcatchAttribute; + +typedef enum { + SMO_invert_depth, // (ft or m), + SMO_hydraulic_head, // (ft or m), + SMO_stored_ponded_volume, // (ft3 or m3), + SMO_lateral_inflow, // (flow units), + SMO_total_inflow, // lateral + upstream (flow units), + SMO_flooding_losses, // (flow units), + SMO_pollutant_conc_node // first pollutant, +} SMO_nodeAttribute; + +typedef enum { + SMO_flow_rate_link, // (flow units), + SMO_flow_depth, // (ft or m), + SMO_flow_velocity, // (ft/s or m/s), + SMO_flow_volume, // (ft3 or m3), + SMO_capacity, // (fraction of conduit filled), + SMO_pollutant_conc_link // first pollutant, +} SMO_linkAttribute; + +typedef enum { + SMO_air_temp, // (deg. F or deg. C), + SMO_rainfall_system, // (in/hr or mm/hr), + SMO_snow_depth_system, // (in or mm), + SMO_evap_infil_loss, // (in/hr or mm/hr), + SMO_runoff_flow, // (flow units), + SMO_dry_weather_inflow, // (flow units), + SMO_groundwater_inflow, // (flow units), + SMO_RDII_inflow, // (flow units), + SMO_direct_inflow, // user defined (flow units), + SMO_total_lateral_inflow, // (sum of variables 4 to 8) //(flow units), + SMO_flood_losses, // (flow units), + SMO_outfall_flows, // (flow units), + SMO_volume_stored, // (ft3 or m3), + SMO_evap_rate // (in/day or mm/day), + //p_evap_rate // (in/day or mm/day) +} SMO_systemAttribute; + + +#ifdef WINDOWS + #ifdef __cplusplus + #define DLLEXPORT __declspec(dllexport) __cdecl + #else + #define DLLEXPORT __declspec(dllexport) __stdcall + #endif +#else + #define DLLEXPORT +#endif + + +/* TYPEMAPS FOR VOID POINTER */ +/* Used for functions that output a new opaque pointer */ +%typemap(in, numinputs=0) SMO_Handle* p_handle_out (void* retval) +{ + /* OUTPUT in */ + retval = NULL; + $1 = &retval; +} +/* used for functions that take in an opaque pointer (or NULL) +and return a (possibly) different pointer */ +%typemap(argout) SMO_Handle* p_handle_out +{ + /* OUTPUT argout */ + %append_output(SWIG_NewPointerObj(SWIG_as_voidptr(retval$argnum), $1_descriptor, 0)); +} +/* No need for special IN typemap for opaque pointers, it works anyway */ + + +/* TYPEMAP FOR IGNORING INT ERROR CODE RETURN VALUE */ +%typemap(out) int { + $result = Py_None; + Py_INCREF($result); +} + + +/* TYPEMAPS FOR DOUBLE ARGUMENT AS RETURN VALUE */ +%typemap(in, numinputs=0) double* double_out (double temp) { + $1 = &temp; +} +%typemap(argout) double* double_out { + %append_output(PyFloat_FromDouble(*$1)); +} + + +/* TYPEMAPS FOR INT ARGUMENT AS RETURN VALUE */ +%typemap(in, numinputs=0) int* int_out (int temp) { + $1 = &temp; +} +%typemap(argout) int* int_out { + %append_output(PyInt_FromLong(*$1)); +} + + +/* TYPEMAP FOR MEMORY MANAGEMENT AND ENCODING OF STRINGS */ +%typemap(in, numinputs=0)char** string_out (char* temp), int* slen (int temp){ + $1 = &temp; +} +%typemap(argout)(char** string_out, int* slen) { + if (*$1) { + PyObject* o; + o = PyUnicode_FromStringAndSize(*$1, *$2); + + $result = SWIG_Python_AppendOutput($result, o); + free(*$1); + } +} + +/* TYPEMAPS FOR MEMORY MANAGEMNET OF FLOAT ARRAYS */ +%typemap(in, numinputs=0)float** float_out (float* temp), int* int_dim (int temp){ + $1 = &temp; +} +%typemap(argout) (float** float_out, int* int_dim) { + if (*$1) { + PyObject *o = PyList_New(*$2); + int i; + float* temp = *$1; + for(i=0; i<*$2; i++) { + PyList_SetItem(o, i, PyFloat_FromDouble((double)temp[i])); + } + $result = SWIG_Python_AppendOutput($result, o); + free(*$1); + } +} + + +/* TYPEMAPS FOR MEMORY MANAGEMNET OF INT ARRAYS */ +%typemap(in, numinputs=0)int** int_out (long* temp), int* int_dim (int temp){ + $1 = &temp; +} +%typemap(argout) (int** int_out, int* int_dim) { + if (*$1) { + PyObject *o = PyList_New(*$2); + int i; + long* temp = (long*)*$1; + for(i=0; i<*$2; i++) { + PyList_SetItem(o, i, PyInt_FromLong(temp[i])); + } + $result = SWIG_Python_AppendOutput($result, o); + free(*$1); + } +} + + +/* TYPEMAP FOR ENUMERATED TYPES */ +%typemap(in) EnumeratedType (int val, int ecode = 0) { + if (PyObject_HasAttrString($input,"value")) { + PyObject* o; + o = PyObject_GetAttrString($input, "value"); + ecode = SWIG_AsVal_int(o, &val); + } + else { + SWIG_exception_fail(SWIG_ArgError(ecode), "in method '" "$symname" "', argument " "$argnum"" of type '" "$ltype""'"); + } + + $1 = ($1_type)(val); +} +%apply EnumeratedType {SMO_unit, SMO_elementType, SMO_time, SMO_subcatchAttribute, +SMO_nodeAttribute, SMO_linkAttribute, SMO_systemAttribute}; + + +/* RENAME FUNCTIONS PYTHON STYLE */ +%rename("%(undercase)s") ""; + +/* GENERATES DOCUMENTATION */ +%feature("autodoc", "2"); + + +/* INSERTS CUSTOM EXCEPTION HANDLING IN WRAPPER */ +%exception +{ + char* err_msg; + SMO_clearError(arg1); + $function + if (SMO_checkError(arg1, &err_msg)) + { + PyErr_SetString(PyExc_Exception, err_msg); + SWIG_fail; + } +} + +/* INSERT EXCEPTION HANDLING FOR THESE FUNCTIONS */ + +int DLLEXPORT SMO_open(SMO_Handle p_handle, const char* path); + +int DLLEXPORT SMO_getVersion(SMO_Handle p_handle, int* int_out); +int DLLEXPORT SMO_getProjectSize(SMO_Handle p_handle, int** int_out, int* int_dim); +int DLLEXPORT SMO_getFlowUnits(SMO_Handle p_handle, int* int_out); +int DLLEXPORT SMO_getPollutantUnits(SMO_Handle p_handle, int** int_out, int* int_dim); +int DLLEXPORT SMO_getStartDate(SMO_Handle p_handle, double* double_out); +int DLLEXPORT SMO_getTimes(SMO_Handle p_handle, SMO_time code, int* int_out); +int DLLEXPORT SMO_getElementName(SMO_Handle p_handle, SMO_elementType type, + int elementIndex, char** string_out, int* slen); + +int DLLEXPORT SMO_getSubcatchSeries(SMO_Handle p_handle, int subcatchIndex, + SMO_subcatchAttribute attr, int startPeriod, int endPeriod, float** float_out, int* int_dim); +int DLLEXPORT SMO_getNodeSeries(SMO_Handle p_handle, int nodeIndex, SMO_nodeAttribute attr, + int startPeriod, int endPeriod, float** float_out, int* int_dim); +int DLLEXPORT SMO_getLinkSeries(SMO_Handle p_handle, int linkIndex, SMO_linkAttribute attr, + int startPeriod, int endPeriod, float** float_out, int* int_dim); +int DLLEXPORT SMO_getSystemSeries(SMO_Handle p_handle, SMO_systemAttribute attr, + int startPeriod, int endPeriod, float** float_out, int* int_dim); + +int DLLEXPORT SMO_getSubcatchAttribute(SMO_Handle p_handle, int timeIndex, + SMO_subcatchAttribute attr, float** float_out, int* int_dim); +int DLLEXPORT SMO_getNodeAttribute(SMO_Handle p_handle, int timeIndex, + SMO_nodeAttribute attr, float** float_out, int* int_dim); +int DLLEXPORT SMO_getLinkAttribute(SMO_Handle p_handle, int timeIndex, + SMO_linkAttribute attr, float** float_out, int* int_dim); +int DLLEXPORT SMO_getSystemAttribute(SMO_Handle p_handle, int timeIndex, + SMO_systemAttribute attr, float** float_out, int* int_dim); + +int DLLEXPORT SMO_getSubcatchResult(SMO_Handle p_handle, int timeIndex, + int subcatchIndex, float** float_out, int* int_dim); +int DLLEXPORT SMO_getNodeResult(SMO_Handle p_handle, int timeIndex, + int nodeIndex, float** float_out, int* int_dim); +int DLLEXPORT SMO_getLinkResult(SMO_Handle p_handle, int timeIndex, + int linkIndex, float** float_out, int* int_dim); +int DLLEXPORT SMO_getSystemResult(SMO_Handle p_handle, int timeIndex, + int dummyIndex, float** float_out, int* int_dim); + +%exception; + +/* NO EXCEPTION HANDLING FOR THESE FUNCTIONS */ +int DLLEXPORT SMO_init(SMO_Handle* p_handle_out); +int DLLEXPORT SMO_close(SMO_Handle* p_handle_out); +void DLLEXPORT SMO_free(void** array); + +void DLLEXPORT SMO_clearError(SMO_Handle p_handle); +int DLLEXPORT SMO_checkError(SMO_Handle p_handle, char** msg_buffer); + + +/* CODE ADDED DIRECTLY TO SWIGGED INTERFACE MODULE */ +%pythoncode%{ +import enum + +class Unit(enum.Enum): + FLOW_UNIT = SMO_flow_rate + CONC_UNIT = SMO_concentration + +class ElementType(enum.Enum): + SUBCATCH = SMO_subcatch + NODE = SMO_node + LINK = SMO_link + SYSTEM = SMO_sys + +class Time(enum.Enum): + REPORT_STEP = SMO_reportStep + NUM_PERIODS = SMO_numPeriods + +class SubcatchAttribute(enum.Enum): + RAINFALL = SMO_rainfall_subcatch + SNOW_DEPTH = SMO_snow_depth_subcatch + EVAP_LOSS = SMO_evap_loss + INFIL_LOSS = SMO_infil_loss + RUNOFF_RATE = SMO_runoff_rate + GW_OUTFLOW_RATE = SMO_gwoutflow_rate + GW_TABLE_ELEV = SMO_gwtable_elev + SOIL_MOISTURE = SMO_soil_moisture + POLLUT_CONC = SMO_pollutant_conc_subcatch + +class NodeAttribute(enum.Enum): + INVERT_DEPTH = SMO_invert_depth + HYDRAULIC_HEAD = SMO_hydraulic_head + PONDED_VOLUME = SMO_stored_ponded_volume + LATERAL_INFLOW = SMO_lateral_inflow + TOTAL_INFLOW = SMO_total_inflow + FLOODING_LOSSES = SMO_flooding_losses + POLLUT_CONC = SMO_pollutant_conc_node + +class LinkAttribute(enum.Enum): + FLOW_RATE = SMO_flow_rate_link + FLOW_DEPTH = SMO_flow_depth + FLOW_VELOCITY = SMO_flow_velocity + FLOW_VOLUME = SMO_flow_volume + CAPACITY = SMO_capacity + POLLUT_CONC = SMO_pollutant_conc_link + +class SystemAttribute(enum.Enum): + AIR_TEMP = SMO_air_temp + RAINFALL = SMO_rainfall_system + SNOW_DEPTH = SMO_snow_depth_system + EVAP_INFIL_LOSS = SMO_evap_infil_loss + RUNOFF_FLOW = SMO_runoff_flow + DRY_WEATHER_INFLOW = SMO_dry_weather_inflow + GW_INFLOW = SMO_groundwater_inflow + RDII_INFLOW = SMO_RDII_inflow + DIRECT_INFLOW = SMO_direct_inflow + TOTAL_LATERAL_INFLOW = SMO_total_lateral_inflow + FLOOD_LOSSES = SMO_flood_losses + OUTFALL_FLOWS = SMO_outfall_flows + VOLUME_STORED = SMO_volume_stored + EVAP_RATE = SMO_evap_rate + +%} diff --git a/swmm-toolkit/setup.py b/toolkit/setup.py similarity index 62% rename from swmm-toolkit/setup.py rename to toolkit/setup.py index 759ff316..d8b29c13 100644 --- a/swmm-toolkit/setup.py +++ b/toolkit/setup.py @@ -18,24 +18,27 @@ from distutils.core import setup, Extension from distutils.command.build_ext import build_ext + setup( - name = "swmm-toolkit", - version = "0.0.1", + name = 'swmm_toolkit', + version = '0.0.1', + ext_modules = [ - Extension("_swmm_toolkit", - include_dirs = ['include/'], + Extension('swmm.toolkit._toolkit', + include_dirs = ['swmm/toolkit/'], libraries = ['swmm5'], - library_dirs = ['lib/'], - sources = ['src/swmm_toolkit.i'], + library_dirs = ['swmm/toolkit/'], + sources = ['swmm/toolkit/toolkit.i'], swig_opts=['-py3'], language = 'C' ) ], - package_dir = {'':'src'}, - py_modules = ['swmm_toolkit'], - + + packages=['swmm.toolkit'], + py_modules = ['toolkit'], + package_data = {'swmm.toolkit':['*swmm5.dll', '*swmm5.so']}, + install_requires = [ 'enum34' ] - ) diff --git a/toolkit/swmm/toolkit/__init__.py b/toolkit/swmm/toolkit/__init__.py new file mode 100644 index 00000000..d96cfbd5 --- /dev/null +++ b/toolkit/swmm/toolkit/__init__.py @@ -0,0 +1,2 @@ + +from swmm.toolkit import toolkit \ No newline at end of file diff --git a/swmm-toolkit/src/swmm_toolkit.i b/toolkit/swmm/toolkit/toolkit.i similarity index 96% rename from swmm-toolkit/src/swmm_toolkit.i rename to toolkit/swmm/toolkit/toolkit.i index 7e0d5d88..2323f4da 100644 --- a/swmm-toolkit/src/swmm_toolkit.i +++ b/toolkit/swmm/toolkit/toolkit.i @@ -1,5 +1,5 @@ /* - * swmm_toolkit.i - SWIG interface description file for SWMM toolkit + * toolkit.i - SWIG interface description file for SWMM toolkit * * Created: 7/2/2018 * Author: Michael E. Tryby @@ -10,7 +10,7 @@ * */ -%module swmm_toolkit +%module(package="swmm") toolkit %{ #include "swmm5.h" #include "toolkitAPI.h" @@ -64,6 +64,12 @@ and return a (possibly) different pointer */ Py_INCREF($result); } +/* RENAME FUNCTIONS PYTHON STYLE */ +%rename("%(undercase)s") ""; + +/* GENERATES DOCUMENTATION */ +%feature("autodoc", "2"); + /* INSERTS CUSTOM EXCEPTION HANDLING IN WRAPPER */ %exception