Giter VIP home page Giter VIP logo

swmmio's Introduction

swmmio

v0.7.0 (2024/04/21)

Build status example workflow Documentation Status

Kool Picture swmmio is a set of python tools aiming to provide a means for version control and visualizing results from the EPA Stormwater Management Model (SWMM). Command line tools are also provided for running models individually and in parallel via Python's multiprocessing module. These tools are being developed specifically for the application of flood risk management, though most functionality is applicable to SWMM modeling in general.

Prerequisites

swmmio functions primarily by interfacing with .inp and .rpt (input and report) files produced by SWMM. Functions within the run_models module rely on a SWMM5 engine which can be downloaded here.

Installation:

Before installation, it's recommended to first activate a virtualenv to not crowd your system's package library. If you don't use any of the dependencies listed above, this step is less important. SWMMIO can be installed via pip in your command line:

pip install swmmio

Basic Usage

The swmmio.Model() class provides the basic endpoint for interfacing with SWMM models. To get started, save a SWMM5 model (.inp) in a directory with its report file (.rpt). A few examples:

import swmmio

#instantiate a swmmio model object
mymodel = swmmio.Model('/path/to/directory with swmm files')

# Pandas dataframe with most useful data related to model nodes, conduits, and subcatchments
nodes = mymodel.nodes.dataframe
links = mymodel.links.dataframe
subs = mymodel.subcatchments.dataframe

#enjoy all the Pandas functions
nodes.head()
InvertElevMaxDepthSurchargeDepthPondedAreaTypeAvgDepthMaxNodeDepthMaxHGLMaxDay_depthMaxHr_depthHoursFloodedMaxQMaxDay_floodMaxHr_floodTotalFloodVolMaximumPondDepthXYcoords
Name
S42A_10.N_413.5066736.3269775.0110.0JUNCTION0.696.3319.83012:010.010.200.011:520.0006.332689107.0227816.000[(2689107.0, 227816.0)]
D70_ShunkStreet_Trunk_438.5084132.4936475.0744.0JUNCTION0.040.238.74012:14NaNNaNNaNNaNNaNNaN2691329.5223675.813[(2691329.5, 223675.813)]
TD61_1_2_905.15000015.3980080.00.0JUNCTION0.6815.4020.55011:550.0119.170.011:560.00015.402698463.5230905.720[(2698463.5, 230905.72)]
D66_36.D.7.C.1_1919.3200003.3357605.06028.0JUNCTION0.573.3822.70012:000.496.450.011:510.0083.382691999.0230309.563[(2691999.0, 230309.563)]
#write to a csv
nodes.to_csv('/path/mynodes.csv')

#calculate average and weighted average impervious
avg_imperviousness = subs.PercImperv.mean()
weighted_avg_imp = (subs.Area * subs.PercImperv).sum() / len(subs)

Nodes and Links Objects

Specific sections of data from the inp and rpt can be extracted with Nodes and Links objects. Although these are the same object-type of the swmmio.Model.nodes and swmmio.Model.links, accessing them directly allows for custom control over what sections of data are retrieved.

from swmmio import Model, Nodes
m = Model("coolest-model.inp")

# pass custom init arguments into the Nodes object instead of using default settings referenced by m.nodes() 
nodes = Nodes(
    model=m, 
    inp_sections=['junctions', 'storages', 'outfalls'],
    rpt_sections=['Node Depth Summary', 'Node Inflow Summary'],
    columns=[ 'InvertElev', 'MaxDepth', 'InitDepth', 'SurchargeDepth', 'MaxTotalInflow', 'coords']
)

# access data 
nodes.dataframe 

Generating Graphics

Create an image (.png) visualization of the model. By default, pipe stress and node flood duration is visualized if your model includes output data (a .rpt file should accompany the .inp).

swmmio.draw_model(mymodel)

Default Draw Output

Use pandas to calculate some interesting stats, and generate a image to highlight what's interesting or important for your project:

#isolate nodes that have flooded for more than 30 minutes
flooded_series = nodes.loc[nodes.HoursFlooded>0.5, 'TotalFloodVol']
flood_vol = sum(flooded_series) #total flood volume (million gallons)
flooded_count = len(flooded_series) #count of flooded nodes

#highlight these nodes in a graphic
nodes['draw_color'] = '#787882' #grey, default node color
nodes.loc[nodes.HoursFlooded>0.5, 'draw_color'] = '#751167' #purple, flooded nodes

#set the radius of flooded nodes as a function of HoursFlooded
nodes.loc[nodes.HoursFlooded>1, 'draw_size'] = nodes.loc[nodes.HoursFlooded>1, 'HoursFlooded'] * 12

#make the conduits grey, sized as function of their geometry
conds['draw_color'] = '#787882'
conds['draw_size'] = conds.Geom1

#add an informative annotation, and draw:
annotation = 'Flooded Volume: {}MG\nFlooded Nodes:{}'.format(round(flood_vol), flooded_count)
swmmio.draw_model(mymodel, annotation=annotation, file_path='flooded_anno_example.png')

Flooded highlight

Building Variations of Models

Starting with a base SWMM model, other models can be created by inserting altered data into a new inp file. Useful for sensitivity analysis or varying boundary conditions, models can be created using a fairly simple loop, leveraging the modify_model package.

For example, climate change impacts can be investigated by creating a set of models with varying outfall Fixed Stage elevations:

import os
import swmmio

#initialize a baseline model object
baseline = swmmio.Model(r'path\to\baseline.inp')
rise = 0.0 #set the starting sea level rise condition

#create models up to 5ft of sea level rise.
while rise <= 5:

    #create a dataframe of the model's outfalls
    outfalls = baseline.inp.outfalls

    #create the Pandas logic to access the StageOrTimeseries column of  FIXED outfalls
    slice_condition = outfalls.OutfallType == 'FIXED', 'StageOrTimeseries'

    #add the current rise to the outfalls' stage elevation
    outfalls.loc[slice_condition] = pd.to_numeric(outfalls.loc[slice_condition]) + rise
    baseline.inp.outfalls = outfalls
    
    #copy the base model into a new directory    
    newdir = os.path.join(baseline.inp.dir, str(rise))
    os.mkdir(newdir)
    newfilepath = os.path.join(newdir, baseline.inp.name + "_" + str(rise) + '_SLR.inp')
    
    #Overwrite the OUTFALLS section of the new model with the adjusted data
    baseline.inp.save(newfilepath)

    #increase sea level rise for the next loop
    rise += 0.25

Access Model Network

The swmmio.Model class returns a Networkx MultiDiGraph representation of the model via that network parameter:

#access the model as a Networkx MutliDiGraph
G = model.network

#iterate through links
for u, v, key, data in model.network.edges(data=True, keys=True):

        print (key, data['Geom1'])
        # do stuff with the network

Running Models

Using the command line tool, individual SWMM5 models can be run by invoking the swmmio module in your shell as such:

$ python -m swmmio --run path/to/mymodel.inp

If you have many models to run and would like to take advantage of your machine's cores, you can start a pool of simulations with the --start_pool (or -sp) command. After pointing -sp to one or more directories, swmmio will search for SWMM .inp files and add all them to a multiprocessing pool. By default, -sp leaves 4 of your machine's cores unused. This can be changed via the -cores_left argument.

$ #run all models in models in directories Model_Dir1 Model_Dir2
$ python -m swmmio -sp Model_Dir1 Model_Dir2  

$ #leave 1 core unused
$ python -m swmmio -sp Model_Dir1 Model_Dir2  -cores_left=1

Warning

Using all cores for simultaneous model runs can put your machine's CPU usage at 100% for extended periods of time. This probably puts stress on your hardware. Use at your own risk.

Flood Model Options Generation

swmmio can take a set of independent storm flood relief (SFR) alternatives and combine them into every combination of potential infrastructure changes. This lays the ground work for identifying the most-efficient implementation sequence and investment level.

Consider the simplified situaiton where a city is interested in solving a flooding issue by installing new relief sewers along Street A and/or Street B. Further, the city wants to decide whether they should be 1 or 2 blocks long. Engineers then decide to build SWMM models for 4 potential relief sewer options:

  • A1 -> One block of relief sewer on Street A
  • A2 -> Two blocks of relief sewer on Street A
  • B1 -> One block of relief sewer on Street B
  • B2 -> Two blocks of relief sewer on Street B

To be comprehensive, implementation scenarios should be modeled for combinations of these options; it may be more cost-effective, for example, to build relief sewers on one block of Street A and Street B in combination, rather than two blocks on either street independently.

swmmio achieves this within the version_control module. The create_combinations() function builds models for every logical combinations of the segmented flood mitigation models. In the example above, models for the following scenarios will be created:

  • A1 with B1
  • A1 with B2
  • A2 with B1
  • A2 with B2

For the create_combinations() function to work, the model directory needs to be set up as follows:

├───Baseline
        baseline.inp
├───Combinations
└───Segments
    ├───A
    │   ├───A1
    │   │   A1.inp
    │   └───A2
    │       A2.inp
    └───B
        ├───B1
        │   B1.inp
        └───B2
            B2.inp

The new models will be built and saved within the Combinations directory. create_combinations() needs to know where these directories are and optionally takes version_id and comments data:

#load the version_control module
from swmmio.version_control import version_control as vc

#organize the folder structure
baseline_dir = r'path/to/Baseline/'
segments_dir = r'path/to/Segments/'
target_dir = r'path/to/Combinations/'

#generate flood mitigation options
vc.create_combinations(
    baseline_dir,
    segments_dir,
    target_dir,
    version_id='initial',
    comments='example flood model generation comments')

The new models will be saved in subdirectories within the target_dir. New models (and their containing directory) will be named based on a concatenation of their parent models' names. It is recommended to keep parent model names as concise as possible such that child model names are manageable. After running create_combinations(), your project directory will look like this:

├───Baseline
├───Combinations
│   ├───A1_B1
│   ├───A1_B2
│   ├───A2_B1
│   └───A2_B2
└───Segments
    ├───A
    │   ├───A1
    │   └───A2
    └───B
        ├───B1
        └───B2

SWMM Model Version Control

To add more segments to the model space, create a new segment directory and rerun the create_combinations() function. Optionally include a comment summarizing how the model space is changing:

vc.create_combinations(
    baseline_dir,
    alternatives_dir,
    target_dir,
    version_id='addA3',
    comments='added model A3 to the scope')

The create_combinations() function can also be used to in the same way to propogate a change in an existing segment (parent) model to all of the children. Version information for each model is stored within a subdirectory called vc within each model directory. Each time a model is modified from the create_combinations() function, a new "BuildInstructions" file is generated summarizing the changes. BuildInstructions files outline how to recreate the model with respect to the baseline model.

TO BE CONTINUED...

swmmio's People

Contributors

abhiramm7 avatar aerispaha avatar algchyhao avatar asselapathirana avatar bemcdonnell avatar buczynskirafal avatar cwhgis avatar dependabot[bot] avatar everettsp avatar jackieff avatar jennwuu avatar kaklise avatar stijnvanhoey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swmmio's Issues

Documentation

@aerispaha maybe I have overlooked something but is there some place where this code is documented with examples? It looks like it has plenty of nice features but I'm not entirely sure how to use them.

create_dataframeINP only works with Green & Ampt infiltration model

When working with the create_dataframeINP function in dataframes.py, it always inserts the header (column definitions) of the Green-Ampt model in the data frame. This seems to happen since the inp_header_dict dictionary (in sectionheaders.py) only provides the parameters of the Green & Ampt model:

'[INFILTRATION]':'Subcatchment Suction HydCon IMDmax'

As a workaround, I defined a simple function that checks the infiltration model from the options section and adjusts the header definition for infiltration accordingly:

dict_inf_headers = {'GREENAMPT': ['Subcatchment','Suction','HydCon','IMDmax'], 'HORTON': ['Subcatchment','MaxRate','MinRate','Decay','DryTime',' MaxInfil]'], 'CURVE_NUMBER': ['CurveNum','','DryTime']}

depreciate sectionheaders.py

Replace with JSON or YAML file with more flexibility and information about each INP section (e.g. column header variation, units)

Sample model to test

Hi,
Could you please forward the sample test swmm model for which results are displayed in the docs of github repo
Thanks!

Standardize the organization of the main and submodules

Follow the convention used within pyswmm: support cleaner importing of the main classes, straighten out the config and definitions.

support these pattern:

from swmmio import Model, FloodReport, ComparisonReport, INPDiff, BuildInstructions

mymodel = Model('model.inp')
mymodel.draw(param, ...) #is there a better function word?
mymodel.conduits = modified_conduits #setters/getters to make changing a model more straightforward

#access global/config variables in a more obvious way
import swmmio 
swmmio.config.prj = 'epsg:2272'
swmmio.config.shapefile_directory = '/path/containing/shapefiles/for/basemap'

problem with ImageFont.py

When I tried to ru sg.draw_model(mymodel) I got the following error:

---------------------------------------------------------------------------
IOError                                   Traceback (most recent call last)
<ipython-input-16-c8ed5de8abd8> in <module>()
      1 from swmmio.graphics import swmm_graphics as sg
----> 2 sg.draw_model(mymodel)

C:\Users\Test\AppData\Local\Continuum\anaconda2\lib\site-packages\swmmio\graphics\swmm_graphics.pyc in draw_model(model, nodes, conduits, parcels, title, annotation, file_path, bbox, px_width)
    111         if title: annotate_title(title, draw)
    112         if annotation: annotate_details(annotation, draw)
--> 113         annotate_timestamp(draw)
    114 
    115         #SAVE IMAGE TO DISK

C:\Users\Test\AppData\Local\Continuum\anaconda2\lib\site-packages\swmmio\graphics\drawing.pyc in annotate_timestamp(draw)
    206         size = (draw.im.getbbox()[2], draw.im.getbbox()[3])
    207         scale = 1 * size[0] / 2048
--> 208         fnt = ImageFont.truetype(config.font_file, int(20 *scale))
    209 
    210         timestamp = strftime("%b-%d-%Y %H:%M:%S")

C:\Users\Test\AppData\Local\Continuum\anaconda2\lib\site-packages\PIL\ImageFont.pyc in truetype(font, size, index, encoding)
    242 
    243     try:
--> 244         return FreeTypeFont(font, size, index, encoding)
    245     except IOError:
    246         ttf_filename = os.path.basename(font)

C:\Users\Test\AppData\Local\Continuum\anaconda2\lib\site-packages\PIL\ImageFont.pyc in __init__(self, font, size, index, encoding)
    131 
    132         if isPath(font):
--> 133             self.font = core.getfont(font, size, index, encoding)
    134         else:
    135             self.font_bytes = font.read()

IOError: cannot open resource

I should say that I have no admin rights on this machine and I won't have them

Possible Collaboration

Hi @aerispaha, you have pulled together a great collection of tools here! Great work! I wanted to mention that there might be possible avenues of collaboration on some of my tools which are under development.

  1. For running models we have pyswmm https://github.com/OpenWaterAnalytics/pyswmm
    This tool currently provides a pythonic interface to running SWMM. We are in the early stages of adding an Input API to SWMM (https://github.com/OpenWaterAnalytics/Stormwater-Management-Model/tree/InputAPI) so that we can expose hydraulic and hydrologic data read in from an *.inp file. The "finished" version of this tool will enable optimization.
  2. For rapidly pulling data out of the binary output file, you might consider looking at SWMMOutputAPI https://github.com/bemcdonnell/SWMMOutputAPI
    This tool provides a nice python interface to the binary output file.

syntax error when importing

Hi,
when I do from swmmio import swmmio I get a syntax error coming from the definitions package:

In [1]: from swmmio import swmmio
  File "C:\Users\jeff\Anaconda2\lib\site-packages\definitions\parser.py", line 83
    yield from cls._flat_tree(element)
             ^
SyntaxError: invalid syntax

I am running python 2.7. From what I can tell, the yield from syntax is only valid in python 3. Have you had this problem or know of a work around?

Assumed column data-type of elements with all numeric values causes conflicts

Reproduce with INP with associated pump InletNodes all numeric (int) values:

pumps_df = dataframes.create_dataframeINP(inp_pth, "[PUMPS]", comment_cols=False)
coords_df = dataframes.create_dataframeINP(inp_pth, "[COORDINATES]")
verts = dataframes.create_dataframeINP(inp_pth, '[VERTICES]')


pumps_df.apply(lambda r: dataframes.get_link_coords(r, coords_df, verts), axis=1)

Inside get_link_coords the dtype of InletNode in pumps_df is assumed to be integer which causes problems here:

def get_link_coords(row, nodexys, verticies):
    """for use in an df.apply, to get coordinates of a conduit/link """
    x1 = round(nodexys.at[row.InletNode, 'X'], 4)
    y1 = round(nodexys.at[row.InletNode, 'Y'], 4)
...

This throws this error:

---> 21 pumps_df.apply(lambda r: dataframes.get_link_coords(r, coords_df, verts), axis=1)
     22 # dataframes.get_link_coords
     23 

c:\projectcode\swmmio\swmmio\utils\dataframes.py in get_link_coords(row, nodexys, verticies)
     69 def get_link_coords(row, nodexys, verticies):
     70     """for use in an df.apply, to get coordinates of a conduit/link """
---> 71     x1 = round(nodexys.at[row.InletNode, 'X'], 4)
     72     y1 = round(nodexys.at[row.InletNode, 'Y'], 4)
     73     x2 = round(nodexys.at[row.OutletNode, 'X'], 4)

~\Anaconda3\envs\emnet\lib\site-packages\pandas\core\indexing.py in __getitem__(self, key)
   1866                 raise ValueError('Invalid call for scalar access (getting)!')
   1867 
-> 1868         key = self._convert_key(key)
   1869         return self.obj._get_value(*key, takeable=self._takeable)
   1870 

~\Anaconda3\envs\emnet\lib\site-packages\pandas\core\indexing.py in _convert_key(self, key, is_setter)
   1913             else:
   1914                 if is_integer(i):
-> 1915                     raise ValueError("At based indexing on an non-integer "
   1916                                      "index can only have non-integer "
   1917                                      "indexers")

ValueError: ('At based indexing on an non-integer index can only have non-integer indexers', 'occurred at index 106829.1')

Drawing functions, organization

Code relating to drawing is located in swmm_graphics and swmm_utils and should likely be all refactored into swm_graphics. Additionally, drawing options are clunky and could use a more streamlined approach.

handling models with duplicate coordinates

model.conduits() fails when the COORDINATES table in an inp file contains duplicate entries. The dataframes.get_link_coords() function fails because the dataframe.get_value(row.OutletNode, 'X') will return multiple records unexpectedly.

Add auto release logic to appveyor.yml

Create a new published release on PyPi using Appveyor

on_success:
  - "%PYTHON%\\python.exe -m pip install wheel"
  - "%PYTHON%\\python.exe setup.py bdist_wheel"
  - >
    IF "%APPVEYOR_REPO_BRANCH%" == "master"
    (
    IF "%APPVEYOR_REPO_TAG%" == "true"
    (
    echo SHOULD PUBLISH TO PyPi
    python -m pip install twine &&
    python -m twine upload dist/* --repository-url %REPO% -u %PYPI_USERNAME% -p %PYPI_PASSWORD%
    )
    )

Methods for comparing two models

Currently, there are multiple ways that models are compared within swmmio:

  • in compare_models.py
  • in the Change / BuildInstructions classes

Unify this process and scrap old junk code.

future warning from pandas

not sure what it means, but i get this warning when i try to use swmmio

Warning (from warnings module):
File "C:\Python37\lib\site-packages\swmmio\swmmio.py", line 289
all_nodes = pd.concat([juncs_df, outfalls_df, storage_df])
FutureWarning: Sorting because non-concatenation axis is not aligned. A future version
of pandas will change to not sort by default.

To accept the future behavior, pass 'sort=False'.

To retain the current behavior and silence the warning, pass 'sort=True'.

invalid import in swmmio.utils.modify_model

When calling import swmmio.utils.modify_model (needed to run the function replace_inp_section()) an import exception is thrown... This seems to be related to another import in version_control.

Output model as Networkx graph

Summary

Network analysis is often very useful in the context of water/drainage infrastructure. It would be convenient to provide a method for traversing/manipulating the swmmio.Model as a network/graph object. This could also provide a bridge to the sewergraph project.

Proposed API

m = swmmio.Model('path-to-model.inp')

# access the Networkx graph 
G = m.network

# analyze edges 
for u,v,d, in m.network.edges(data=True):
    upnode = G.node[u]
    dnnode = G.node[v]
    if dnnode['InvertElev'] > upnode['InvertElev']:
        print ('Backwards Conduit: ', d['Name'])

considered using GeoPandas for spatial functions?

Hi again @aerispaha,
I was just using this very useful library again and had a question for you. I want to write my nodes and conduits into a shapefile. I used your spatial.py function write_shapefile and that worked, but the datatypes in the dataframe didn't transfer. Everything came across as a string. Have you thought about using Geopandas for this instead of the shapefile library? It seems like a nice fit since you are using Pandas dataframes already (which I love, btw). It also carries the datatypes into the shapefile. I'm happy to code this up and submit a PR if you think it's a good change.

Dataframes vs dictionaries in swmmio.py

The organizeConduitData / NodeData functions were one of the first written for this project and can most likely be reworked to use dataframe parsing functions in swmmio.utils.dataframes. I assume this will make the code more standardized, clean, and possibly faster.

Is the multi-thread run requires hot start ?

I don't have hot start file defined, when run "python -m swmmio --run", it works, but when I try to run multiple cases by "python -m swmmio -sp Dir", it add hot start to the end of .inp file automatically and show error: "local variable 'simulationStart' referenced before assignment". Could you please kindly suggest?

Return GeoJSON representation of Model

Spatial data is carried within the model element dataframes. This information would be very useful is easily exportable as a GeoJSON feature dataset.

error in spatial.py

I am trying it and after installation in an Anaconda environmental i got this error when running the first line
from swmmio import swmmio

I got an error in the file spatial.py in line 1
from definitions import ROOT_DIR
error:
ImportError: No module named definitions

Error running many models in parallel

Hi Aerispaha,

I found that when I run SWMM in parallel, it fails randomly. For example, if I run 500 cases in parallel, 0-20 out of 500 may not getting any results and prompt 303 error: not compatible hot start file. The number of failed runs differs every try. What could be the problem please?

Alleviate Pandas .ix indexing depreciation warning

Pandas is giving this warning due to a flavor of indexing set to change in future versions:

See the documentation here:
  http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated
    full_set = pd.concat([df1.ix[common_ids], df2.ix[common_ids]])
  C:\projects\swmmio\swmmio\version_control\inp.py:152: DeprecationWarning: 
  .ix is deprecated. Please use
  .loc for label based indexing or
  .iloc for positional indexing

Update swmmio to use the supported Pandas indexing pattern.

Order of drawing

Need to allow user to have control over order of things drawn. also, labels (streets) should always be drawn last.

Scrub the swmmio.py module

(Re)move redundant / out of scope functions, pep8 compliance, consistency, review and clean up inheritance scheme

swmmio.py existing roadmap

class Model(object)

  • __init__
  • rpt_is_valid
  • to_map
  • _get_scenario
  • conduits
  • orifices
  • weirs
  • pumps
  • nodes
  • subcatchments
  • node
  • export_to_shapefile

class SWMMIOFile(object)

  • __init__
  • findByteRangeOfSection
  • createDictionary

class rpt(SWMMIOFile)

  • __init__
  • createByteLocDict
  • returnDataAtDTime

class inp(SWMMIOFile)

  • __init__

MaxQ column name is ambiguous

When returning a dataframe of nodes data via swmmio.Model.nodes(), the column named MaxQ is ambiguous. Currently, it refers to MaxQ from the Node FLooding Summary table in the rpt: effectively, the max flow of flood water leaving the node.

MaxQ should probably be reserved for actual flow in the node, not the max rate of flooding.

DataFrame columns names should reflect model units

The Pandas DataFrames returned by the function swmmio.create_dataframeRPT always include a CFS label even if the model is run in SI units. swmmio should provide column headers consistent with the model units.

This is related to #14.

provide read/write interface to all INP sections

Summary

All INP sections that follow the common tabular structure with unique indices as the first column can be read via the swmmio.utils.create_dataframeINP function. However, only a limited number of these sections have been added as properties in the higher-level swmmio.core.inp object.

Add coverage for read/writing all INP sections from the swmmio.core.inp object. INP sections are defined currently as properties with setter/getters in the swmmio.core module here. List of INP sections described here in the OWA SWMM repo.

INP Sections to Cover

  • TITLE
  • OPTIONS
  • FILES
  • RAINGAGES
  • TEMPERATURE
  • EVAPORATION
  • SUBCATCHMENT
  • SUBAREAS
  • INFILTRATION
  • AQUIFER
  • GROUNDWATER
  • SNOWPACK
  • JUNCTIONS
  • OUTFALLS
  • STORAGES
  • DIVIDERS
  • CONDUITS
  • PUMPS
  • ORIFICES
  • WEIRS
  • OUTLETS
  • XSECTIONS
  • TRANSECTS
  • LOSSES
  • CONTROLS
  • POLLUTION
  • LANDUSE
  • BUILDUP
  • WASHOFF
  • COVERAGE
  • INFLOW
  • DWF
  • PATTERN
  • RDII
  • HYDROGRAPH
  • LOADING
  • TREATMENT
  • CURVES
  • TIMESERIES
  • REPORT
  • MAP
  • COORDINATES
  • VERTICES
  • POLYGONS
  • SYMBOLS
  • LABELS
  • BACKDROP
  • TAGS
  • PROFILES
  • LID_CONTROLS
  • LID_USAGE
  • GWF
  • ADJUSTMENT
  • EVENT
  • STREETS (new in SWMM 5.2)
  • INLETS (new in SWMM 5.2)
  • INLET_USAGE (new in SWMM 5.2)

Pandas 0.25.x drops support for Python 2.7

This is causing an issue in Python 2.7 Windows builds. We should either drop support for Python 2.7 or set the Pandas version explicitly to v0.24.2. This is causing a build fail in #63.

Processing pandas-0.25.0.tar.gz
Writing c:\users\appveyor\appdata\local\temp\1\easy_install-4dl70z\pandas-0.25.0\setup.cfg
Running pandas-0.25.0\setup.py -q bdist_egg --dist-dir c:\users\appveyor\appdata\local\temp\1\easy_install-4dl70z\pandas-0.25.0\egg-dist-tmp-7pcggv
Traceback (most recent call last):
  File "setup.py", line 68, in <module>
    "Programming Language :: Python :: 3.6",
  File "C:\Python27\lib\site-packages\setuptools\__init__.py", line 143, in setup
    return distutils.core.setup(**attrs)
  File "C:\Python27\lib\distutils\core.py", line 151, in setup
    dist.run_commands()
  File "C:\Python27\lib\distutils\dist.py", line 953, in run_commands
    self.run_command(cmd)
  File "C:\Python27\lib\distutils\dist.py", line 972, in run_command
    cmd_obj.run()
  File "C:\Python27\lib\site-packages\setuptools\command\develop.py", line 38, in run
    self.install_for_development()
  File "C:\Python27\lib\site-packages\setuptools\command\develop.py", line 154, in install_for_development
    self.process_distribution(None, self.dist, not self.no_deps)
  File "C:\Python27\lib\site-packages\setuptools\command\easy_install.py", line 752, in process_distribution
    [requirement], self.local_index, self.easy_install
  File "C:\Python27\lib\site-packages\pkg_resources\__init__.py", line 780, in resolve
    replace_conflicting=replace_conflicting
  File "C:\Python27\lib\site-packages\pkg_resources\__init__.py", line 1063, in best_match
    return self.obtain(req, installer)
  File "C:\Python27\lib\site-packages\pkg_resources\__init__.py", line 1075, in obtain
    return installer(requirement)
  File "C:\Python27\lib\site-packages\setuptools\command\easy_install.py", line 679, in easy_install
    return self.install_item(spec, dist.location, tmpdir, deps)
  File "C:\Python27\lib\site-packages\setuptools\command\easy_install.py", line 705, in install_item
    dists = self.install_eggs(spec, download, tmpdir)
  File "C:\Python27\lib\site-packages\setuptools\command\easy_install.py", line 890, in install_eggs
    return self.build_and_install(setup_script, setup_base)
  File "C:\Python27\lib\site-packages\setuptools\command\easy_install.py", line 1158, in build_and_install
    self.run_setup(setup_script, setup_base, args)
  File "C:\Python27\lib\site-packages\setuptools\command\easy_install.py", line 1144, in run_setup
    run_setup(setup_script, args)
  File "C:\Python27\lib\site-packages\setuptools\sandbox.py", line 253, in run_setup
    raise
  File "C:\Python27\lib\contextlib.py", line 35, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\Python27\lib\site-packages\setuptools\sandbox.py", line 195, in setup_context
    yield
  File "C:\Python27\lib\contextlib.py", line 35, in __exit__
    self.gen.throw(type, value, traceback)
  File "C:\Python27\lib\site-packages\setuptools\sandbox.py", line 166, in save_modules
    saved_exc.resume()
  File "C:\Python27\lib\site-packages\setuptools\sandbox.py", line 141, in resume
    six.reraise(type, exc, self._tb)
  File "C:\Python27\lib\site-packages\setuptools\sandbox.py", line 154, in save_modules
    yield saved
  File "C:\Python27\lib\site-packages\setuptools\sandbox.py", line 195, in setup_context
    yield
  File "C:\Python27\lib\site-packages\setuptools\sandbox.py", line 250, in run_setup
    _execfile(setup_script, ns)
  File "C:\Python27\lib\site-packages\setuptools\sandbox.py", line 45, in _execfile
    exec(code, globals, locals)
  File "c:\users\appveyor\appdata\local\temp\1\easy_install-4dl70z\pandas-0.25.0\setup.py", line 21, in <module>
    return version
  File "c:\users\appveyor\appdata\local\temp\1\easy_install-4dl70z\pandas-0.25.0\versioneer.py", line 1629
    print("Adding sample versioneer config to setup.cfg", file=sys.stderr)
                                                              ^
SyntaxError: invalid syntax
Command exited with code 1

error "no module named swmmio"

I have pip install swmmio and when I run "python -m swmmio ..." it prompts "from swmmio.swmmio import Model \ no module named swmmio". I tried both python 2.7 and python 3.7, what could be the problem please?

Update:
main.py
line 3
modify
from .swmmio import Model
to
from swmmio import Model
solved the problem.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.