Skip to content

Commit e7c8441

Browse files
authored
Merge pull request #165 from aerispaha/profile_plotter
Add profile plotter and pyswmm integration
2 parents ea2b532 + 83a598d commit e7c8441

24 files changed

+1305
-203
lines changed

lib/linux/swmm5

-628 KB
Binary file not shown.

lib/windows/swmm5_22.exe

-432 KB
Binary file not shown.

requirements.txt

+3
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ m2r
1313
mistune==0.8.4
1414
# Run dependencies
1515
pyproj>=3.0.0
16+
geopandas
17+
matplotlib
18+
pyswmm>=1.2

swmmio/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
from swmmio.elements import *
33
from swmmio.version_control import *
44
from swmmio.utils.dataframes import dataframe_from_bi, dataframe_from_rpt, dataframe_from_inp
5+
from swmmio.utils.functions import find_network_trace
56
from swmmio.graphics.swmm_graphics import create_map
7+
from swmmio.graphics.profiler import (build_profile_plot, add_hgl_plot,
8+
add_node_labels_plot, add_link_labels_plot)
69

710
# import swmmio.core as swmmio
811
'''Python SWMM Input/Output Tools'''

swmmio/__main__.py

+45-42
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,61 @@
1+
import argparse
2+
import os
3+
from itertools import chain
4+
15
from swmmio.run_models.run import run_simple, run_hot_start_sequence
26
from swmmio.run_models import start_pool
37

4-
from swmmio import Model
5-
from itertools import chain
6-
import os
7-
import argparse
8-
from multiprocessing import Pool, cpu_count
9-
from datetime import datetime
108

11-
#parse the arguments
12-
parser = argparse.ArgumentParser(description='Process some stuff')
13-
parser.add_argument('-r', '--run', dest='model_to_run', nargs="+")
14-
parser.add_argument('-rhs', '--run_hotstart', dest='hotstart_model_to_run', nargs="+")
15-
parser.add_argument('-sp', '--start_pool', dest='start_pool', nargs="+")
16-
parser.add_argument('-cores_left', '--cores_left', dest='cores_left', default=4, type=int)
17-
parser.add_argument('-pp', '--post_process', dest='post_process', nargs="+")
9+
def main():
10+
# parse the arguments
11+
parser = argparse.ArgumentParser(description='Process some stuff')
12+
parser.add_argument('-r', '--run', dest='model_to_run', nargs="+")
13+
parser.add_argument('-rhs', '--run_hotstart', dest='hotstart_model_to_run', nargs="+")
14+
parser.add_argument('-sp', '--start_pool', dest='start_pool', nargs="+")
15+
parser.add_argument('-cores_left', '--cores_left', dest='cores_left', default=4, type=int)
16+
parser.add_argument('-pp', '--post_process', dest='post_process', nargs="+")
17+
18+
args = parser.parse_args()
19+
wd = os.getcwd() # current directory script is being called from
1820

19-
args = parser.parse_args()
20-
wd = os.getcwd() #current directory script is being called from
21+
if args.model_to_run is not None:
2122

22-
if args.model_to_run is not None:
23+
models_paths = [os.path.join(wd, f) for f in args.model_to_run]
24+
print('Adding models to queue:\n\t{}'.format('\n\t'.join(models_paths)))
2325

24-
models_paths = [os.path.join(wd, f) for f in args.model_to_run]
25-
print('Adding models to queue:\n\t{}'.format('\n\t'.join(models_paths)))
26+
# run the models in series (one after the other)
27+
list(map(run_simple, models_paths))
28+
# run_simple(args.model_to_run)
2629

27-
#run the models in series (one after the other)
28-
list(map(run_simple, models_paths))
29-
# run_simple(args.model_to_run)
30+
elif args.hotstart_model_to_run is not None:
31+
models_paths = [os.path.join(wd, f) for f in args.hotstart_model_to_run]
32+
print('hotstart_model_to_run the model: {}'.format(args.hotstart_model_to_run))
33+
# m = Model(args.hotstart_model_to_run)
34+
# run_hot_start_sequence(m)#args.hotstart_model_to_run)
35+
list(map(run_hot_start_sequence, models_paths))
3036

31-
elif args.hotstart_model_to_run is not None:
32-
models_paths = [os.path.join(wd, f) for f in args.hotstart_model_to_run]
33-
print('hotstart_model_to_run the model: {}'.format(args.hotstart_model_to_run))
34-
# m = Model(args.hotstart_model_to_run)
35-
# run_hot_start_sequence(m)#args.hotstart_model_to_run)
36-
list(map(run_hot_start_sequence, models_paths))
37+
elif args.start_pool is not None:
3738

38-
elif args.start_pool is not None:
39+
models_dirs = [os.path.join(wd, f) for f in args.start_pool]
40+
print('Searching for models in:\n\t{}'.format('\n\t'.join(models_dirs)))
41+
# combine the segments and options (combinations) into one iterable
42+
inp_paths = []
43+
for root, dirs, files in chain.from_iterable(os.walk(path) for path in models_dirs):
44+
for f in files:
45+
if f.endswith('.inp') and 'bk' not in root:
46+
# we've found a directory containing an inp
47+
inp_paths.append(os.path.join(root, f))
3948

40-
models_dirs = [os.path.join(wd, f) for f in args.start_pool]
41-
print('Searching for models in:\n\t{}'.format('\n\t'.join(models_dirs)))
42-
#combine the segments and options (combinations) into one iterable
43-
inp_paths = []
44-
for root, dirs, files in chain.from_iterable(os.walk(path) for path in models_dirs):
45-
for f in files:
46-
if f.endswith('.inp') and 'bk' not in root:
47-
#we've found a directory containing an inp
48-
inp_paths.append(os.path.join(root, f))
49+
# call the main() function in start_pool.py
50+
start_pool.main(inp_paths, args.cores_left)
4951

52+
print("swmmio has completed running {} models".format(len(inp_paths)))
5053

51-
#call the main() function in start_pool.py
52-
start_pool.main(inp_paths, args.cores_left)
54+
else:
55+
print('you need to pass in some args')
5356

54-
print("swmmio has completed running {} models".format(len(inp_paths)))
57+
return 0
5558

5659

57-
else:
58-
print('you need to pass in some args')
60+
if __name__ == '__main__':
61+
main()

swmmio/core.py

+34-4
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ class inp(SWMMIOFile):
504504
def __init__(self, file_path):
505505
self._options_df = None
506506
self._files_df = None
507+
self._report_df = None
507508
self._conduits_df = None
508509
self._xsections_df = None
509510
self._pumps_df = None
@@ -529,6 +530,7 @@ def __init__(self, file_path):
529530
self._sections = [
530531
'[OPTIONS]',
531532
'[FILES]',
533+
'[REPORT]',
532534
'[CONDUITS]',
533535
'[XSECTIONS]',
534536
'[PUMPS]',
@@ -562,9 +564,12 @@ def save(self, target_path=None):
562564
"""
563565
from swmmio.utils.modify_model import replace_inp_section
564566
import shutil
565-
target_path = target_path if target_path is not None else self.path
566567

567-
shutil.copyfile(self.path, target_path)
568+
if target_path is not None:
569+
shutil.copyfile(self.path, target_path)
570+
else:
571+
target_path = self.path
572+
568573
for section in self._sections:
569574
# reformate the [SECTION] to section (and _section_df)
570575
sect_id = section.translate({ord(i): None for i in '[]'}).lower()
@@ -651,8 +656,6 @@ def files(self):
651656
652657
:return: files section of the INP file
653658
:rtype: pandas.DataFrame
654-
655-
Examples:
656659
"""
657660
if self._files_df is None:
658661
self._files_df = dataframe_from_inp(self.path, "[FILES]")
@@ -664,6 +667,33 @@ def files(self, df):
664667
first_col = df.columns[0]
665668
self._files_df = df.set_index(first_col)
666669

670+
@property
671+
def report(self):
672+
"""
673+
Get/set report section of the INP file.
674+
675+
:return: report section of the INP file
676+
:rtype: pandas.DataFrame
677+
678+
>>> from swmmio.examples import jersey
679+
>>> jersey.inp.report #doctest: +NORMALIZE_WHITESPACE
680+
Status
681+
Param
682+
INPUT YES
683+
CONTROLS YES
684+
SUBCATCHMENTS NONE
685+
NODES ALL
686+
LINKS NONE
687+
"""
688+
if self._report_df is None:
689+
self._report_df = dataframe_from_inp(self.path, "report")
690+
return self._report_df
691+
692+
@report.setter
693+
def report(self, df):
694+
"""Set inp.report DataFrame."""
695+
self._report_df = df
696+
667697
@property
668698
def conduits(self):
669699
"""

swmmio/defs/config.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@
33
# This is the swmmio project root
44
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
55

6-
# path to the SWMM5 executable used within the run_models module
7-
if os.name == 'posix':
8-
SWMM_ENGINE_PATH = os.path.join(ROOT_DIR, 'lib', 'linux', 'swmm5')
9-
else:
10-
SWMM_ENGINE_PATH = os.path.join(ROOT_DIR, 'lib', 'windows', 'swmm5_22.exe')
6+
# path to the Python executable used to run your version of Python
7+
PYTHON_EXE_PATH = "python"#os.path.join(os.__file__.split("lib/")[0],"bin","python")
118

129
# feature class name of parcels in geodatabase
1310
PARCEL_FEATURES = r'PWD_PARCELS_SHEDS_PPORT'
@@ -25,3 +22,5 @@
2522
BASEMAP_PATH = os.path.join(ROOT_DIR, 'swmmio', 'reporting', 'basemaps', 'index.html')
2623
BETTER_BASEMAP_PATH = os.path.join(ROOT_DIR, 'swmmio', 'reporting', 'basemaps', 'mapbox_base.html')
2724

25+
# PySWMM Wrapper Path
26+
PYSWMM_WRAPPER_PATH = os.path.join(ROOT_DIR, 'swmmio', 'wrapper', 'pyswmm_wrapper.py')

0 commit comments

Comments
 (0)