swmm-pandas 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- swmm/pandas/__init__.py +7 -0
- swmm/pandas/constants.py +37 -0
- swmm/pandas/input/README.md +61 -0
- swmm/pandas/input/__init__.py +2 -0
- swmm/pandas/input/_section_classes.py +2309 -0
- swmm/pandas/input/input.py +888 -0
- swmm/pandas/input/model.py +403 -0
- swmm/pandas/output/__init__.py +2 -0
- swmm/pandas/output/output.py +2580 -0
- swmm/pandas/output/structure.py +317 -0
- swmm/pandas/output/tools.py +32 -0
- swmm/pandas/py.typed +0 -0
- swmm/pandas/report/__init__.py +1 -0
- swmm/pandas/report/report.py +773 -0
- swmm_pandas-0.6.0.dist-info/METADATA +71 -0
- swmm_pandas-0.6.0.dist-info/RECORD +19 -0
- swmm_pandas-0.6.0.dist-info/WHEEL +4 -0
- swmm_pandas-0.6.0.dist-info/entry_points.txt +4 -0
- swmm_pandas-0.6.0.dist-info/licenses/LICENSE.md +157 -0
|
@@ -0,0 +1,888 @@
|
|
|
1
|
+
# swmm-pandas input
|
|
2
|
+
# scope:
|
|
3
|
+
# - high level api for loading, inspecting, changing, and
|
|
4
|
+
# altering a SWMM input file using pandas dataframes
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from swmm.pandas.input._section_classes import SectionBase, _sections
|
|
8
|
+
import swmm.pandas.input._section_classes as sc
|
|
9
|
+
import pathlib
|
|
10
|
+
import re
|
|
11
|
+
import warnings
|
|
12
|
+
from typing import TYPE_CHECKING, Optional, Self
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from swmm.pandas.input.model import Model
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class InputFile:
|
|
19
|
+
_section_re = re.compile(R"^\[[\s\S]*?(?=^\[)", re.MULTILINE)
|
|
20
|
+
_section_keys = tuple(_sections.keys())
|
|
21
|
+
|
|
22
|
+
def __init__(self, inpfile: Optional[str | pathlib.Path] = None):
|
|
23
|
+
"""Base class for a SWMM input file.
|
|
24
|
+
|
|
25
|
+
The input object provides an attribute for each section supported the SWMM inp file. The
|
|
26
|
+
section properties are created dynamically at runtime to keep source code dry and concise, but
|
|
27
|
+
typehints provide minimal docstrings for dataframe column names. Most sections are represented
|
|
28
|
+
by a pandas dataframe, with the exception of a few.
|
|
29
|
+
|
|
30
|
+
This class was written based on the `SWMM Users Manual`_, any parsing bugs might require bug reports to the
|
|
31
|
+
USEPA repo for updates to the users manual.
|
|
32
|
+
|
|
33
|
+
.. DANGER::
|
|
34
|
+
This class provides **minimal to no error checking** on your input file when loading it or writing it.
|
|
35
|
+
|
|
36
|
+
When creating new model elements or updating the properties of existing ones, swmm.pandas expects
|
|
37
|
+
that the user knows what they are doing.
|
|
38
|
+
|
|
39
|
+
Just because swmm.pandas allows you to do something, does not mean SWMM will accept it.
|
|
40
|
+
|
|
41
|
+
.. _SWMM Users Manual: https://www.epa.gov/system/files/documents/2022-04/swmm-users-manual-version-5.2.pdf
|
|
42
|
+
|
|
43
|
+
.. code-block:: python
|
|
44
|
+
|
|
45
|
+
# Using a the _close method
|
|
46
|
+
>>> from swmm.pandas import Input
|
|
47
|
+
>>> inp = Input('tests/data/bench_inp.inp')
|
|
48
|
+
>>> print(inp.option.head())
|
|
49
|
+
Value desc
|
|
50
|
+
Option
|
|
51
|
+
FLOW_UNITS CFS
|
|
52
|
+
INFILTRATION GREEN_AMPT
|
|
53
|
+
FLOW_ROUTING DYNWAVE
|
|
54
|
+
LINK_OFFSETS DEPTH
|
|
55
|
+
MIN_SLOPE 0
|
|
56
|
+
>>> print(inp.junc.head())
|
|
57
|
+
Elevation MaxDepth InitDepth SurDepth Aponded desc
|
|
58
|
+
Name
|
|
59
|
+
JUNC1 1.5 10.25 0 0 5000
|
|
60
|
+
JUNC2 -1.04 6.2 0 0 5000
|
|
61
|
+
JUNC3 -3.47 11.5 0 0 5000
|
|
62
|
+
JUNC4 -5.25 13.8 0 0 5000
|
|
63
|
+
JUNC6 0 9 0 200 0
|
|
64
|
+
>>> inp.junc['Elevation']+=100
|
|
65
|
+
>>> inp.junc['Elevation']
|
|
66
|
+
Name
|
|
67
|
+
JUNC1 101.5
|
|
68
|
+
JUNC2 98.96
|
|
69
|
+
JUNC3 96.53
|
|
70
|
+
JUNC4 94.75
|
|
71
|
+
JUNC6 100
|
|
72
|
+
Name: Elevation, dtype: object
|
|
73
|
+
>>> inp.to_file('new_inp_file.inp')
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
inpfile: str
|
|
78
|
+
model inp file path
|
|
79
|
+
"""
|
|
80
|
+
if inpfile is not None:
|
|
81
|
+
self.path: str = inpfile
|
|
82
|
+
self._load_inp_file()
|
|
83
|
+
# for sect in _sections.keys():
|
|
84
|
+
# # print(sect)
|
|
85
|
+
# self._set_section_prop(sect)
|
|
86
|
+
|
|
87
|
+
def _load_inp_file(self) -> None:
|
|
88
|
+
with open(self.path) as inp:
|
|
89
|
+
self.text: str = inp.read()
|
|
90
|
+
|
|
91
|
+
self._sections: dict[str, SectionBase] = {}
|
|
92
|
+
self._section_texts: dict[str, str] = {}
|
|
93
|
+
|
|
94
|
+
for section in self._section_re.findall(self.text):
|
|
95
|
+
name = re.findall(R"^\[(.*)\]", section)[0]
|
|
96
|
+
|
|
97
|
+
data = "\n".join(re.findall(R"^(?!;{2,}|\[).+$", section, re.MULTILINE))
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
section_idx = list(
|
|
101
|
+
name.lower().startswith(x.lower()) for x in _sections
|
|
102
|
+
).index(True)
|
|
103
|
+
section_key = self._section_keys[section_idx]
|
|
104
|
+
self._section_texts[section_key] = data
|
|
105
|
+
except Exception as e:
|
|
106
|
+
print(e)
|
|
107
|
+
self._sections[name] = data
|
|
108
|
+
# self.__setattr__(name.lower(), "Not Implemented")
|
|
109
|
+
|
|
110
|
+
print(f"Section {name} not yet supported")
|
|
111
|
+
|
|
112
|
+
def _get_section(self, key):
|
|
113
|
+
if key in self._section_texts:
|
|
114
|
+
data = self._section_texts[key]
|
|
115
|
+
return _sections[key].from_section_text(data)
|
|
116
|
+
|
|
117
|
+
else:
|
|
118
|
+
return _sections[key]._new_empty()
|
|
119
|
+
|
|
120
|
+
@classmethod
|
|
121
|
+
def _set_section_prop(cls, section: str) -> None:
|
|
122
|
+
section_class = _sections[section]
|
|
123
|
+
public_property_name = section_class.__name__.lower()
|
|
124
|
+
private_property_name = f"_{public_property_name}"
|
|
125
|
+
|
|
126
|
+
def getter(self):
|
|
127
|
+
if not hasattr(self, private_property_name):
|
|
128
|
+
setattr(self, private_property_name, self._get_section(section))
|
|
129
|
+
return getattr(self, private_property_name)
|
|
130
|
+
|
|
131
|
+
def setter(self, obj):
|
|
132
|
+
setattr(self, private_property_name, section_class._newobj(obj))
|
|
133
|
+
|
|
134
|
+
setattr(cls, public_property_name, property(getter, setter))
|
|
135
|
+
|
|
136
|
+
def to_string(self):
|
|
137
|
+
with warnings.catch_warnings():
|
|
138
|
+
warnings.simplefilter(action="ignore", category=FutureWarning)
|
|
139
|
+
out_str = ""
|
|
140
|
+
for sect in _sections.keys():
|
|
141
|
+
section_class = _sections[sect]
|
|
142
|
+
public_property_name = section_class.__name__.lower()
|
|
143
|
+
# private_property_name = f"_{public_property_name}"
|
|
144
|
+
if len(sect_obj := getattr(self, public_property_name)) > 0:
|
|
145
|
+
try:
|
|
146
|
+
sect_string = sect_obj.to_swmm_string()
|
|
147
|
+
out_str += f"[{sect_obj._section_name}]\n{sect_string}\n\n"
|
|
148
|
+
except Exception as e:
|
|
149
|
+
print(f"error parsing {sect_obj.__class__.__name__}")
|
|
150
|
+
raise e
|
|
151
|
+
|
|
152
|
+
return out_str
|
|
153
|
+
|
|
154
|
+
def to_file(self, path: str | pathlib.Path):
|
|
155
|
+
with open(path, "w") as f:
|
|
156
|
+
f.write(self.to_string())
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
def title(self) -> sc.Title:
|
|
160
|
+
|
|
161
|
+
if not hasattr(self, "_title"):
|
|
162
|
+
self._title = self._get_section("TITLE")
|
|
163
|
+
|
|
164
|
+
return self._title
|
|
165
|
+
|
|
166
|
+
@title.setter
|
|
167
|
+
def title(self, obj) -> None:
|
|
168
|
+
self._title = sc.Title._newobj(obj)
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def option(self) -> sc.Option:
|
|
172
|
+
"['Option', 'Value', 'desc']"
|
|
173
|
+
|
|
174
|
+
if not hasattr(self, "_option"):
|
|
175
|
+
self._option = self._get_section("OPTION")
|
|
176
|
+
|
|
177
|
+
return self._option
|
|
178
|
+
|
|
179
|
+
@option.setter
|
|
180
|
+
def option(self, obj) -> None:
|
|
181
|
+
self._option = sc.Option._newobj(obj)
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def report(self) -> sc.Report:
|
|
185
|
+
|
|
186
|
+
if not hasattr(self, "_report"):
|
|
187
|
+
self._report = self._get_section("REPORT")
|
|
188
|
+
|
|
189
|
+
return self._report
|
|
190
|
+
|
|
191
|
+
@report.setter
|
|
192
|
+
def report(self, obj) -> None:
|
|
193
|
+
self._report = sc.Report._newobj(obj)
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def event(self) -> sc.Event:
|
|
197
|
+
"['Start', 'End', 'desc']"
|
|
198
|
+
|
|
199
|
+
if not hasattr(self, "_event"):
|
|
200
|
+
self._event = self._get_section("EVENT")
|
|
201
|
+
|
|
202
|
+
return self._event
|
|
203
|
+
|
|
204
|
+
@event.setter
|
|
205
|
+
def event(self, obj) -> None:
|
|
206
|
+
self._event = sc.Event._newobj(obj)
|
|
207
|
+
|
|
208
|
+
@property
|
|
209
|
+
def files(self) -> sc.Files:
|
|
210
|
+
|
|
211
|
+
if not hasattr(self, "_files"):
|
|
212
|
+
self._files = self._get_section("FILE")
|
|
213
|
+
|
|
214
|
+
return self._files
|
|
215
|
+
|
|
216
|
+
@files.setter
|
|
217
|
+
def files(self, obj) -> None:
|
|
218
|
+
self._files = sc.Files._newobj(obj)
|
|
219
|
+
|
|
220
|
+
@property
|
|
221
|
+
def raingage(self) -> sc.Raingage:
|
|
222
|
+
"['Name', 'Format', 'Interval', 'SCF', 'Source_Type', 'Source', 'Station', 'Units', 'desc']"
|
|
223
|
+
|
|
224
|
+
if not hasattr(self, "_raingage"):
|
|
225
|
+
self._raingage = self._get_section("RAINGAGE")
|
|
226
|
+
|
|
227
|
+
return self._raingage
|
|
228
|
+
|
|
229
|
+
@raingage.setter
|
|
230
|
+
def raingage(self, obj) -> None:
|
|
231
|
+
self._raingage = sc.Raingage._newobj(obj)
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def evap(self) -> sc.Evap:
|
|
235
|
+
"['Type', 'param1', 'param2', 'param3', 'param4', 'param5', 'param6', 'param7', 'param8', 'param9', 'param10', 'param11', 'param12', 'desc']"
|
|
236
|
+
|
|
237
|
+
if not hasattr(self, "_evap"):
|
|
238
|
+
self._evap = self._get_section("EVAP")
|
|
239
|
+
|
|
240
|
+
return self._evap
|
|
241
|
+
|
|
242
|
+
@evap.setter
|
|
243
|
+
def evap(self, obj) -> None:
|
|
244
|
+
self._evap = sc.Evap._newobj(obj)
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def temperature(self) -> sc.Temperature:
|
|
248
|
+
"['Option', 'param1', 'param2', 'param3', 'param4', 'param5', 'param6', 'param7', 'param8', 'param9', 'param10', 'param11', 'param12', 'param13', 'desc']"
|
|
249
|
+
|
|
250
|
+
if not hasattr(self, "_temperature"):
|
|
251
|
+
self._temperature = self._get_section("TEMPERATURE")
|
|
252
|
+
|
|
253
|
+
return self._temperature
|
|
254
|
+
|
|
255
|
+
@temperature.setter
|
|
256
|
+
def temperature(self, obj) -> None:
|
|
257
|
+
self._temperature = sc.Temperature._newobj(obj)
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def adjustments(self) -> sc.Adjustments:
|
|
261
|
+
"['Parameter', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'desc']"
|
|
262
|
+
|
|
263
|
+
if not hasattr(self, "_adjustments"):
|
|
264
|
+
self._adjustments = self._get_section("ADJUSTMENT")
|
|
265
|
+
|
|
266
|
+
return self._adjustments
|
|
267
|
+
|
|
268
|
+
@adjustments.setter
|
|
269
|
+
def adjustments(self, obj) -> None:
|
|
270
|
+
self._adjustments = sc.Adjustments._newobj(obj)
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
def subcatchment(self) -> sc.Subcatchment:
|
|
274
|
+
"['Name', 'RainGage', 'Outlet', 'Area', 'PctImp', 'Width', 'Slope', 'CurbLeng', 'SnowPack', 'desc']"
|
|
275
|
+
|
|
276
|
+
if not hasattr(self, "_subcatchment"):
|
|
277
|
+
self._subcatchment = self._get_section("SUBCATCHMENT")
|
|
278
|
+
|
|
279
|
+
return self._subcatchment
|
|
280
|
+
|
|
281
|
+
@subcatchment.setter
|
|
282
|
+
def subcatchment(self, obj) -> None:
|
|
283
|
+
self._subcatchment = sc.Subcatchment._newobj(obj)
|
|
284
|
+
|
|
285
|
+
@property
|
|
286
|
+
def subarea(self) -> sc.Subarea:
|
|
287
|
+
"['Subcatchment', 'Nimp', 'Nperv', 'Simp', 'Sperv', 'PctZero', 'RouteTo', 'PctRouted', 'desc']"
|
|
288
|
+
|
|
289
|
+
if not hasattr(self, "_subarea"):
|
|
290
|
+
self._subarea = self._get_section("SUBAREA")
|
|
291
|
+
|
|
292
|
+
return self._subarea
|
|
293
|
+
|
|
294
|
+
@subarea.setter
|
|
295
|
+
def subarea(self, obj) -> None:
|
|
296
|
+
self._subarea = sc.Subarea._newobj(obj)
|
|
297
|
+
|
|
298
|
+
@property
|
|
299
|
+
def infil(self) -> sc.Infil:
|
|
300
|
+
"['Subcatchment', 'param1', 'param2', 'param3', 'param4', 'param5', 'Method', 'desc']"
|
|
301
|
+
|
|
302
|
+
if not hasattr(self, "_infil"):
|
|
303
|
+
self._infil = self._get_section("INFIL")
|
|
304
|
+
|
|
305
|
+
return self._infil
|
|
306
|
+
|
|
307
|
+
@infil.setter
|
|
308
|
+
def infil(self, obj) -> None:
|
|
309
|
+
self._infil = sc.Infil._newobj(obj)
|
|
310
|
+
|
|
311
|
+
@property
|
|
312
|
+
def lid_control(self) -> sc.LID_Control:
|
|
313
|
+
"['Name', 'Type', 'param1', 'param2', 'param3', 'param4', 'param5', 'param6', 'param7', 'desc']"
|
|
314
|
+
|
|
315
|
+
if not hasattr(self, "_lid_control"):
|
|
316
|
+
self._lid_control = self._get_section("LID_CONTROL")
|
|
317
|
+
|
|
318
|
+
return self._lid_control
|
|
319
|
+
|
|
320
|
+
@lid_control.setter
|
|
321
|
+
def lid_control(self, obj) -> None:
|
|
322
|
+
self._lid_control = sc.LID_Control._newobj(obj)
|
|
323
|
+
|
|
324
|
+
@property
|
|
325
|
+
def lid_usage(self) -> sc.LID_Usage:
|
|
326
|
+
"['Subcatchment', 'LIDProcess', 'Number', 'Area', 'Width', 'InitSat', 'FromImp', 'ToPerv', 'RptFile', 'DrainTo', 'FromPerv', 'desc']"
|
|
327
|
+
|
|
328
|
+
if not hasattr(self, "_lid_usage"):
|
|
329
|
+
self._lid_usage = self._get_section("LID_USAGE")
|
|
330
|
+
|
|
331
|
+
return self._lid_usage
|
|
332
|
+
|
|
333
|
+
@lid_usage.setter
|
|
334
|
+
def lid_usage(self, obj) -> None:
|
|
335
|
+
self._lid_usage = sc.LID_Usage._newobj(obj)
|
|
336
|
+
|
|
337
|
+
@property
|
|
338
|
+
def aquifer(self) -> sc.Aquifer:
|
|
339
|
+
"['Name', 'Por', 'WP', 'FC', 'Ksat', 'Kslope', 'Tslope', 'ETu', 'ETs', 'Seep', 'Ebot', 'Egw', 'Umc', 'ETupat', 'desc']"
|
|
340
|
+
|
|
341
|
+
if not hasattr(self, "_aquifer"):
|
|
342
|
+
self._aquifer = self._get_section("AQUIFER")
|
|
343
|
+
|
|
344
|
+
return self._aquifer
|
|
345
|
+
|
|
346
|
+
@aquifer.setter
|
|
347
|
+
def aquifer(self, obj) -> None:
|
|
348
|
+
self._aquifer = sc.Aquifer._newobj(obj)
|
|
349
|
+
|
|
350
|
+
@property
|
|
351
|
+
def groundwater(self) -> sc.Groundwater:
|
|
352
|
+
"['Subcatchment', 'Aquifer', 'Node', 'Esurf', 'A1', 'B1', 'A2', 'B2', 'A3', 'Dsw', 'Egwt', 'Ebot', 'Wgr', 'Umc', 'desc']"
|
|
353
|
+
|
|
354
|
+
if not hasattr(self, "_groundwater"):
|
|
355
|
+
self._groundwater = self._get_section("GROUNDWATER")
|
|
356
|
+
|
|
357
|
+
return self._groundwater
|
|
358
|
+
|
|
359
|
+
@groundwater.setter
|
|
360
|
+
def groundwater(self, obj) -> None:
|
|
361
|
+
self._groundwater = sc.Groundwater._newobj(obj)
|
|
362
|
+
|
|
363
|
+
@property
|
|
364
|
+
def gwf(self) -> sc.GWF:
|
|
365
|
+
"['Subcatch', 'Type', 'Expr', 'desc']"
|
|
366
|
+
|
|
367
|
+
if not hasattr(self, "_gwf"):
|
|
368
|
+
self._gwf = self._get_section("GWF")
|
|
369
|
+
|
|
370
|
+
return self._gwf
|
|
371
|
+
|
|
372
|
+
@gwf.setter
|
|
373
|
+
def gwf(self, obj) -> None:
|
|
374
|
+
self._gwf = sc.GWF._newobj(obj)
|
|
375
|
+
|
|
376
|
+
@property
|
|
377
|
+
def snowpack(self) -> sc.Snowpack:
|
|
378
|
+
"['Name', 'Surface', 'param1', 'param2', 'param3', 'param4', 'param5', 'param6', 'param7', 'desc']"
|
|
379
|
+
|
|
380
|
+
if not hasattr(self, "_snowpack"):
|
|
381
|
+
self._snowpack = self._get_section("SNOWPACK")
|
|
382
|
+
|
|
383
|
+
return self._snowpack
|
|
384
|
+
|
|
385
|
+
@snowpack.setter
|
|
386
|
+
def snowpack(self, obj) -> None:
|
|
387
|
+
self._snowpack = sc.Snowpack._newobj(obj)
|
|
388
|
+
|
|
389
|
+
@property
|
|
390
|
+
def junc(self) -> sc.Junc:
|
|
391
|
+
"['Name', 'Elevation', 'MaxDepth', 'InitDepth', 'SurDepth', 'Aponded', 'desc']"
|
|
392
|
+
|
|
393
|
+
if not hasattr(self, "_junc"):
|
|
394
|
+
self._junc = self._get_section("JUNC")
|
|
395
|
+
|
|
396
|
+
return self._junc
|
|
397
|
+
|
|
398
|
+
@junc.setter
|
|
399
|
+
def junc(self, obj) -> None:
|
|
400
|
+
self._junc = sc.Junc._newobj(obj)
|
|
401
|
+
|
|
402
|
+
@property
|
|
403
|
+
def outfall(self) -> sc.Outfall:
|
|
404
|
+
"['Name', 'Elevation', 'Type', 'StageData', 'Gated', 'RouteTo', 'desc']"
|
|
405
|
+
|
|
406
|
+
if not hasattr(self, "_outfall"):
|
|
407
|
+
self._outfall = self._get_section("OUTFALL")
|
|
408
|
+
|
|
409
|
+
return self._outfall
|
|
410
|
+
|
|
411
|
+
@outfall.setter
|
|
412
|
+
def outfall(self, obj) -> None:
|
|
413
|
+
self._outfall = sc.Outfall._newobj(obj)
|
|
414
|
+
|
|
415
|
+
@property
|
|
416
|
+
def divider(self) -> sc.Divider:
|
|
417
|
+
"['Name', 'Elevation', 'DivLink', 'DivType', 'DivCurve', 'Qmin', 'Height', 'Cd', 'Ymax', 'Y0', 'Ysur', 'Apond', 'desc']"
|
|
418
|
+
|
|
419
|
+
if not hasattr(self, "_divider"):
|
|
420
|
+
self._divider = self._get_section("DIVIDER")
|
|
421
|
+
|
|
422
|
+
return self._divider
|
|
423
|
+
|
|
424
|
+
@divider.setter
|
|
425
|
+
def divider(self, obj) -> None:
|
|
426
|
+
self._divider = sc.Divider._newobj(obj)
|
|
427
|
+
|
|
428
|
+
@property
|
|
429
|
+
def storage(self) -> sc.Storage:
|
|
430
|
+
"['Name', 'Elev', 'MaxDepth', 'InitDepth', 'Shape', 'CurveName', 'A1_L', 'A2_W', 'A0_Z', 'SurDepth', 'Fevap', 'Psi', 'Ksat', 'IMD', 'desc']"
|
|
431
|
+
|
|
432
|
+
if not hasattr(self, "_storage"):
|
|
433
|
+
self._storage = self._get_section("STORAGE")
|
|
434
|
+
|
|
435
|
+
return self._storage
|
|
436
|
+
|
|
437
|
+
@storage.setter
|
|
438
|
+
def storage(self, obj) -> None:
|
|
439
|
+
self._storage = sc.Storage._newobj(obj)
|
|
440
|
+
|
|
441
|
+
@property
|
|
442
|
+
def conduit(self) -> sc.Conduit:
|
|
443
|
+
"['Name', 'FromNode', 'ToNode', 'Length', 'Roughness', 'InOffset', 'OutOffset', 'InitFlow', 'MaxFlow', 'desc']"
|
|
444
|
+
|
|
445
|
+
if not hasattr(self, "_conduit"):
|
|
446
|
+
self._conduit = self._get_section("CONDUIT")
|
|
447
|
+
|
|
448
|
+
return self._conduit
|
|
449
|
+
|
|
450
|
+
@conduit.setter
|
|
451
|
+
def conduit(self, obj) -> None:
|
|
452
|
+
self._conduit = sc.Conduit._newobj(obj)
|
|
453
|
+
|
|
454
|
+
@property
|
|
455
|
+
def pump(self) -> sc.Pump:
|
|
456
|
+
"['Name', 'FromNode', 'ToNode', 'PumpCurve', 'Status', 'Startup', 'Shutoff', 'desc']"
|
|
457
|
+
|
|
458
|
+
if not hasattr(self, "_pump"):
|
|
459
|
+
self._pump = self._get_section("PUMP")
|
|
460
|
+
|
|
461
|
+
return self._pump
|
|
462
|
+
|
|
463
|
+
@pump.setter
|
|
464
|
+
def pump(self, obj) -> None:
|
|
465
|
+
self._pump = sc.Pump._newobj(obj)
|
|
466
|
+
|
|
467
|
+
@property
|
|
468
|
+
def orifice(self) -> sc.Orifice:
|
|
469
|
+
"['Name', 'FromNode', 'ToNode', 'Type', 'Offset', 'Qcoeff', 'Gated', 'CloseTime', 'desc']"
|
|
470
|
+
|
|
471
|
+
if not hasattr(self, "_orifice"):
|
|
472
|
+
self._orifice = self._get_section("ORIFICE")
|
|
473
|
+
|
|
474
|
+
return self._orifice
|
|
475
|
+
|
|
476
|
+
@orifice.setter
|
|
477
|
+
def orifice(self, obj) -> None:
|
|
478
|
+
self._orifice = sc.Orifice._newobj(obj)
|
|
479
|
+
|
|
480
|
+
@property
|
|
481
|
+
def weir(self) -> sc.Weir:
|
|
482
|
+
"['Name', 'FromNode', 'ToNode', 'Type', 'CrestHt', 'Qcoeff', 'Gated', 'EndCon', 'EndCoeff', 'Surcharge', 'RoadWidth', 'RoadSurf', 'CoeffCurve', 'desc']"
|
|
483
|
+
|
|
484
|
+
if not hasattr(self, "_weir"):
|
|
485
|
+
self._weir = self._get_section("WEIR")
|
|
486
|
+
|
|
487
|
+
return self._weir
|
|
488
|
+
|
|
489
|
+
@weir.setter
|
|
490
|
+
def weir(self, obj) -> None:
|
|
491
|
+
self._weir = sc.Weir._newobj(obj)
|
|
492
|
+
|
|
493
|
+
@property
|
|
494
|
+
def outlet(self) -> sc.Outlet:
|
|
495
|
+
"['Name', 'FromNode', 'ToNode', 'Offset', 'Type', 'CurveName', 'Qcoeff', 'Qexpon', 'Gated', 'desc']"
|
|
496
|
+
|
|
497
|
+
if not hasattr(self, "_outlet"):
|
|
498
|
+
self._outlet = self._get_section("OUTLET")
|
|
499
|
+
|
|
500
|
+
return self._outlet
|
|
501
|
+
|
|
502
|
+
@outlet.setter
|
|
503
|
+
def outlet(self, obj) -> None:
|
|
504
|
+
self._outlet = sc.Outlet._newobj(obj)
|
|
505
|
+
|
|
506
|
+
@property
|
|
507
|
+
def xsections(self) -> sc.Xsections:
|
|
508
|
+
"['Link', 'Shape', 'Geom1', 'Curve', 'Geom2', 'Geom3', 'Geom4', 'Barrels', 'Culvert', 'desc']"
|
|
509
|
+
|
|
510
|
+
if not hasattr(self, "_xsections"):
|
|
511
|
+
self._xsections = self._get_section("XSECT")
|
|
512
|
+
|
|
513
|
+
return self._xsections
|
|
514
|
+
|
|
515
|
+
@xsections.setter
|
|
516
|
+
def xsections(self, obj) -> None:
|
|
517
|
+
self._xsections = sc.Xsections._newobj(obj)
|
|
518
|
+
|
|
519
|
+
@property
|
|
520
|
+
def transects(self) -> sc.Transects:
|
|
521
|
+
|
|
522
|
+
if not hasattr(self, "_transects"):
|
|
523
|
+
self._transects = self._get_section("TRANSECT")
|
|
524
|
+
|
|
525
|
+
return self._transects
|
|
526
|
+
|
|
527
|
+
@transects.setter
|
|
528
|
+
def transects(self, obj) -> None:
|
|
529
|
+
self._transects = sc.Transects._newobj(obj)
|
|
530
|
+
|
|
531
|
+
@property
|
|
532
|
+
def street(self) -> sc.Street:
|
|
533
|
+
"['Name', 'Tcrown', 'Hcurb', 'Sroad', 'nRoad', 'Hdep', 'Wdep', 'Sides', 'Wback', 'Sback', 'nBack', 'desc']"
|
|
534
|
+
|
|
535
|
+
if not hasattr(self, "_street"):
|
|
536
|
+
self._street = self._get_section("STREETS")
|
|
537
|
+
|
|
538
|
+
return self._street
|
|
539
|
+
|
|
540
|
+
@street.setter
|
|
541
|
+
def street(self, obj) -> None:
|
|
542
|
+
self._street = sc.Street._newobj(obj)
|
|
543
|
+
|
|
544
|
+
@property
|
|
545
|
+
def inlet_usage(self) -> sc.Inlet_Usage:
|
|
546
|
+
"['Conduit', 'Inlet', 'Node', 'Number', '%Clogged', 'MaxFlow', 'hDStore', 'wDStore', 'Placement', 'desc']"
|
|
547
|
+
|
|
548
|
+
if not hasattr(self, "_inlet_usage"):
|
|
549
|
+
self._inlet_usage = self._get_section("INLET_USAGE")
|
|
550
|
+
|
|
551
|
+
return self._inlet_usage
|
|
552
|
+
|
|
553
|
+
@inlet_usage.setter
|
|
554
|
+
def inlet_usage(self, obj) -> None:
|
|
555
|
+
self._inlet_usage = sc.Inlet_Usage._newobj(obj)
|
|
556
|
+
|
|
557
|
+
@property
|
|
558
|
+
def inlet(self) -> sc.Inlet:
|
|
559
|
+
"['Name', 'Type', 'param1', 'param2', 'param3', 'param4', 'param5', 'desc']"
|
|
560
|
+
|
|
561
|
+
if not hasattr(self, "_inlet"):
|
|
562
|
+
self._inlet = self._get_section("INLET")
|
|
563
|
+
|
|
564
|
+
return self._inlet
|
|
565
|
+
|
|
566
|
+
@inlet.setter
|
|
567
|
+
def inlet(self, obj) -> None:
|
|
568
|
+
self._inlet = sc.Inlet._newobj(obj)
|
|
569
|
+
|
|
570
|
+
@property
|
|
571
|
+
def losses(self) -> sc.Losses:
|
|
572
|
+
"['Link', 'Kentry', 'Kexit', 'Kavg', 'FlapGate', 'Seepage', 'desc']"
|
|
573
|
+
|
|
574
|
+
if not hasattr(self, "_losses"):
|
|
575
|
+
self._losses = self._get_section("LOSS")
|
|
576
|
+
|
|
577
|
+
return self._losses
|
|
578
|
+
|
|
579
|
+
@losses.setter
|
|
580
|
+
def losses(self, obj) -> None:
|
|
581
|
+
self._losses = sc.Losses._newobj(obj)
|
|
582
|
+
|
|
583
|
+
@property
|
|
584
|
+
def controls(self) -> sc.Controls:
|
|
585
|
+
|
|
586
|
+
if not hasattr(self, "_controls"):
|
|
587
|
+
self._controls = self._get_section("CONTROL")
|
|
588
|
+
|
|
589
|
+
return self._controls
|
|
590
|
+
|
|
591
|
+
@controls.setter
|
|
592
|
+
def controls(self, obj) -> None:
|
|
593
|
+
self._controls = sc.Controls._newobj(obj)
|
|
594
|
+
|
|
595
|
+
@property
|
|
596
|
+
def pollutants(self) -> sc.Pollutants:
|
|
597
|
+
"['Name', 'Units', 'Crain', 'Cgw', 'Crdii', 'Kdecay', 'SnowOnly', 'CoPollutant', 'CoFrac', 'Cdwf', 'Cinit', 'desc']"
|
|
598
|
+
|
|
599
|
+
if not hasattr(self, "_pollutants"):
|
|
600
|
+
self._pollutants = self._get_section("POLLUT")
|
|
601
|
+
|
|
602
|
+
return self._pollutants
|
|
603
|
+
|
|
604
|
+
@pollutants.setter
|
|
605
|
+
def pollutants(self, obj) -> None:
|
|
606
|
+
self._pollutants = sc.Pollutants._newobj(obj)
|
|
607
|
+
|
|
608
|
+
@property
|
|
609
|
+
def landuse(self) -> sc.LandUse:
|
|
610
|
+
"['Name', 'SweepInterval', 'Availability', 'LastSweep', 'desc']"
|
|
611
|
+
|
|
612
|
+
if not hasattr(self, "_landuse"):
|
|
613
|
+
self._landuse = self._get_section("LANDUSE")
|
|
614
|
+
|
|
615
|
+
return self._landuse
|
|
616
|
+
|
|
617
|
+
@landuse.setter
|
|
618
|
+
def landuse(self, obj) -> None:
|
|
619
|
+
self._landuse = sc.LandUse._newobj(obj)
|
|
620
|
+
|
|
621
|
+
@property
|
|
622
|
+
def coverage(self) -> sc.Coverage:
|
|
623
|
+
"['Subcatchment', 'landuse', 'Percent', 'desc']"
|
|
624
|
+
|
|
625
|
+
if not hasattr(self, "_coverage"):
|
|
626
|
+
self._coverage = self._get_section("COVERAGE")
|
|
627
|
+
|
|
628
|
+
return self._coverage
|
|
629
|
+
|
|
630
|
+
@coverage.setter
|
|
631
|
+
def coverage(self, obj) -> None:
|
|
632
|
+
self._coverage = sc.Coverage._newobj(obj)
|
|
633
|
+
|
|
634
|
+
@property
|
|
635
|
+
def loading(self) -> sc.Loading:
|
|
636
|
+
"['Subcatchment', 'Pollutant', 'InitBuildup', 'desc']"
|
|
637
|
+
|
|
638
|
+
if not hasattr(self, "_loading"):
|
|
639
|
+
self._loading = self._get_section("LOADING")
|
|
640
|
+
|
|
641
|
+
return self._loading
|
|
642
|
+
|
|
643
|
+
@loading.setter
|
|
644
|
+
def loading(self, obj) -> None:
|
|
645
|
+
self._loading = sc.Loading._newobj(obj)
|
|
646
|
+
|
|
647
|
+
@property
|
|
648
|
+
def buildup(self) -> sc.Buildup:
|
|
649
|
+
"['Landuse', 'Pollutant', 'FuncType', 'C1', 'C2', 'C3', 'PerUnit', 'desc']"
|
|
650
|
+
|
|
651
|
+
if not hasattr(self, "_buildup"):
|
|
652
|
+
self._buildup = self._get_section("BUILDUP")
|
|
653
|
+
|
|
654
|
+
return self._buildup
|
|
655
|
+
|
|
656
|
+
@buildup.setter
|
|
657
|
+
def buildup(self, obj) -> None:
|
|
658
|
+
self._buildup = sc.Buildup._newobj(obj)
|
|
659
|
+
|
|
660
|
+
@property
|
|
661
|
+
def washoff(self) -> sc.Washoff:
|
|
662
|
+
"['Landuse', 'Pollutant', 'FuncType', 'C1', 'C2', 'SweepRmvl', 'BmpRmvl', 'desc']"
|
|
663
|
+
|
|
664
|
+
if not hasattr(self, "_washoff"):
|
|
665
|
+
self._washoff = self._get_section("WASHOFF")
|
|
666
|
+
|
|
667
|
+
return self._washoff
|
|
668
|
+
|
|
669
|
+
@washoff.setter
|
|
670
|
+
def washoff(self, obj) -> None:
|
|
671
|
+
self._washoff = sc.Washoff._newobj(obj)
|
|
672
|
+
|
|
673
|
+
@property
|
|
674
|
+
def treatment(self) -> sc.Treatment:
|
|
675
|
+
"['Node', 'Pollutant', 'Func', 'desc']"
|
|
676
|
+
|
|
677
|
+
if not hasattr(self, "_treatment"):
|
|
678
|
+
self._treatment = self._get_section("TREATMENT")
|
|
679
|
+
|
|
680
|
+
return self._treatment
|
|
681
|
+
|
|
682
|
+
@treatment.setter
|
|
683
|
+
def treatment(self, obj) -> None:
|
|
684
|
+
self._treatment = sc.Treatment._newobj(obj)
|
|
685
|
+
|
|
686
|
+
@property
|
|
687
|
+
def inflow(self) -> sc.Inflow:
|
|
688
|
+
"['Node', 'Constituent', 'TimeSeries', 'Type', 'Mfactor', 'Sfactor', 'Baseline', 'Pattern', 'desc']"
|
|
689
|
+
|
|
690
|
+
if not hasattr(self, "_inflow"):
|
|
691
|
+
self._inflow = self._get_section("INFLOW")
|
|
692
|
+
|
|
693
|
+
return self._inflow
|
|
694
|
+
|
|
695
|
+
@inflow.setter
|
|
696
|
+
def inflow(self, obj) -> None:
|
|
697
|
+
self._inflow = sc.Inflow._newobj(obj)
|
|
698
|
+
|
|
699
|
+
@property
|
|
700
|
+
def dwf(self) -> sc.DWF:
|
|
701
|
+
"['Node', 'Constituent', 'Baseline', 'Pat1', 'Pat2', 'Pat3', 'Pat4', 'desc']"
|
|
702
|
+
|
|
703
|
+
if not hasattr(self, "_dwf"):
|
|
704
|
+
self._dwf = self._get_section("DWF")
|
|
705
|
+
|
|
706
|
+
return self._dwf
|
|
707
|
+
|
|
708
|
+
@dwf.setter
|
|
709
|
+
def dwf(self, obj) -> None:
|
|
710
|
+
self._dwf = sc.DWF._newobj(obj)
|
|
711
|
+
|
|
712
|
+
@property
|
|
713
|
+
def rdii(self) -> sc.RDII:
|
|
714
|
+
"['Node', 'UHgroup', 'SewerArea', 'desc']"
|
|
715
|
+
|
|
716
|
+
if not hasattr(self, "_rdii"):
|
|
717
|
+
self._rdii = self._get_section("RDII")
|
|
718
|
+
|
|
719
|
+
return self._rdii
|
|
720
|
+
|
|
721
|
+
@rdii.setter
|
|
722
|
+
def rdii(self, obj) -> None:
|
|
723
|
+
self._rdii = sc.RDII._newobj(obj)
|
|
724
|
+
|
|
725
|
+
@property
|
|
726
|
+
def hydrographs(self) -> sc.Hydrographs:
|
|
727
|
+
"['Name', 'Month_RG', 'Response', 'R', 'T', 'K', 'IA_max', 'IA_rec', 'IA_ini', 'desc']"
|
|
728
|
+
|
|
729
|
+
if not hasattr(self, "_hydrographs"):
|
|
730
|
+
self._hydrographs = self._get_section("HYDROGRAPH")
|
|
731
|
+
|
|
732
|
+
return self._hydrographs
|
|
733
|
+
|
|
734
|
+
@hydrographs.setter
|
|
735
|
+
def hydrographs(self, obj) -> None:
|
|
736
|
+
self._hydrographs = sc.Hydrographs._newobj(obj)
|
|
737
|
+
|
|
738
|
+
@property
|
|
739
|
+
def curves(self) -> sc.Curves:
|
|
740
|
+
"['Name', 'Type', 'X_Value', 'Y_Value', 'desc']"
|
|
741
|
+
|
|
742
|
+
if not hasattr(self, "_curves"):
|
|
743
|
+
self._curves = self._get_section("CURVE")
|
|
744
|
+
|
|
745
|
+
return self._curves
|
|
746
|
+
|
|
747
|
+
@curves.setter
|
|
748
|
+
def curves(self, obj) -> None:
|
|
749
|
+
self._curves = sc.Curves._newobj(obj)
|
|
750
|
+
|
|
751
|
+
@property
|
|
752
|
+
def timeseries(self) -> sc.Timeseries:
|
|
753
|
+
|
|
754
|
+
if not hasattr(self, "_timeseries"):
|
|
755
|
+
self._timeseries = self._get_section("TIMESERIES")
|
|
756
|
+
|
|
757
|
+
return self._timeseries
|
|
758
|
+
|
|
759
|
+
@timeseries.setter
|
|
760
|
+
def timeseries(self, obj) -> None:
|
|
761
|
+
self._timeseries = sc.Timeseries._newobj(obj)
|
|
762
|
+
|
|
763
|
+
@property
|
|
764
|
+
def patterns(self) -> sc.Patterns:
|
|
765
|
+
"['Name', 'Type', 'Multiplier', 'desc']"
|
|
766
|
+
|
|
767
|
+
if not hasattr(self, "_patterns"):
|
|
768
|
+
self._patterns = self._get_section("PATTERN")
|
|
769
|
+
|
|
770
|
+
return self._patterns
|
|
771
|
+
|
|
772
|
+
@patterns.setter
|
|
773
|
+
def patterns(self, obj) -> None:
|
|
774
|
+
self._patterns = sc.Patterns._newobj(obj)
|
|
775
|
+
|
|
776
|
+
@property
|
|
777
|
+
def map(self) -> sc.Map:
|
|
778
|
+
|
|
779
|
+
if not hasattr(self, "_map"):
|
|
780
|
+
self._map = self._get_section("MAP")
|
|
781
|
+
|
|
782
|
+
return self._map
|
|
783
|
+
|
|
784
|
+
@map.setter
|
|
785
|
+
def map(self, obj) -> None:
|
|
786
|
+
self._map = sc.Map._newobj(obj)
|
|
787
|
+
|
|
788
|
+
@property
|
|
789
|
+
def polygons(self) -> sc.Polygons:
|
|
790
|
+
"['Subcatch', 'X', 'Y', 'desc']"
|
|
791
|
+
|
|
792
|
+
if not hasattr(self, "_polygons"):
|
|
793
|
+
self._polygons = self._get_section("POLYGON")
|
|
794
|
+
|
|
795
|
+
return self._polygons
|
|
796
|
+
|
|
797
|
+
@polygons.setter
|
|
798
|
+
def polygons(self, obj) -> None:
|
|
799
|
+
self._polygons = sc.Polygons._newobj(obj)
|
|
800
|
+
|
|
801
|
+
@property
|
|
802
|
+
def coordinates(self) -> sc.Coordinates:
|
|
803
|
+
"['Node', 'X', 'Y', 'desc']"
|
|
804
|
+
|
|
805
|
+
if not hasattr(self, "_coordinates"):
|
|
806
|
+
self._coordinates = self._get_section("COORDINATE")
|
|
807
|
+
|
|
808
|
+
return self._coordinates
|
|
809
|
+
|
|
810
|
+
@coordinates.setter
|
|
811
|
+
def coordinates(self, obj) -> None:
|
|
812
|
+
self._coordinates = sc.Coordinates._newobj(obj)
|
|
813
|
+
|
|
814
|
+
@property
|
|
815
|
+
def vertices(self) -> sc.Vertices:
|
|
816
|
+
"['Link', 'X', 'Y', 'desc']"
|
|
817
|
+
|
|
818
|
+
if not hasattr(self, "_vertices"):
|
|
819
|
+
self._vertices = self._get_section("VERTICES")
|
|
820
|
+
|
|
821
|
+
return self._vertices
|
|
822
|
+
|
|
823
|
+
@vertices.setter
|
|
824
|
+
def vertices(self, obj) -> None:
|
|
825
|
+
self._vertices = sc.Vertices._newobj(obj)
|
|
826
|
+
|
|
827
|
+
@property
|
|
828
|
+
def labels(self) -> sc.Labels:
|
|
829
|
+
"['Xcoord', 'Ycoord', 'Label', 'Anchor', 'Font', 'Size', 'Bold', 'Italic', 'desc']"
|
|
830
|
+
|
|
831
|
+
if not hasattr(self, "_labels"):
|
|
832
|
+
self._labels = self._get_section("LABEL")
|
|
833
|
+
|
|
834
|
+
return self._labels
|
|
835
|
+
|
|
836
|
+
@labels.setter
|
|
837
|
+
def labels(self, obj) -> None:
|
|
838
|
+
self._labels = sc.Labels._newobj(obj)
|
|
839
|
+
|
|
840
|
+
@property
|
|
841
|
+
def symbols(self) -> sc.Symbols:
|
|
842
|
+
"['Gage', 'X', 'Y', 'desc']"
|
|
843
|
+
|
|
844
|
+
if not hasattr(self, "_symbols"):
|
|
845
|
+
self._symbols = self._get_section("SYMBOL")
|
|
846
|
+
|
|
847
|
+
return self._symbols
|
|
848
|
+
|
|
849
|
+
@symbols.setter
|
|
850
|
+
def symbols(self, obj) -> None:
|
|
851
|
+
self._symbols = sc.Symbols._newobj(obj)
|
|
852
|
+
|
|
853
|
+
@property
|
|
854
|
+
def backdrop(self) -> sc.Backdrop:
|
|
855
|
+
|
|
856
|
+
if not hasattr(self, "_backdrop"):
|
|
857
|
+
self._backdrop = self._get_section("BACKDROP")
|
|
858
|
+
|
|
859
|
+
return self._backdrop
|
|
860
|
+
|
|
861
|
+
@backdrop.setter
|
|
862
|
+
def backdrop(self, obj) -> None:
|
|
863
|
+
self._backdrop = sc.Backdrop._newobj(obj)
|
|
864
|
+
|
|
865
|
+
@property
|
|
866
|
+
def profile(self) -> sc.Profile:
|
|
867
|
+
|
|
868
|
+
if not hasattr(self, "_profile"):
|
|
869
|
+
self._profile = self._get_section("PROFILE")
|
|
870
|
+
|
|
871
|
+
return self._profile
|
|
872
|
+
|
|
873
|
+
@profile.setter
|
|
874
|
+
def profile(self, obj) -> None:
|
|
875
|
+
self._profile = sc.Profile._newobj(obj)
|
|
876
|
+
|
|
877
|
+
@property
|
|
878
|
+
def tags(self) -> sc.Tags:
|
|
879
|
+
"['Element', 'Name', 'Tag', 'desc']"
|
|
880
|
+
|
|
881
|
+
if not hasattr(self, "_tags"):
|
|
882
|
+
self._tags = self._get_section("TAG")
|
|
883
|
+
|
|
884
|
+
return self._tags
|
|
885
|
+
|
|
886
|
+
@tags.setter
|
|
887
|
+
def tags(self, obj) -> None:
|
|
888
|
+
self._tags = sc.Tags._newobj(obj)
|