Source code for swmm.pandas.input.model
# %%
# swmm-pandas input
# scope:
# - high level api for loading, inspecting, changing, and
# altering a SWMM input file using pandas dataframes
from __future__ import annotations
from swmm.pandas.input._section_classes import SectionBase, SectionDf, _sections
from swmm.pandas.input.input import InputFile
import pandas as pd
import swmm.pandas.input._section_classes as sc
import pathlib
import re
from typing import Optional, Callable, Any, TypeVar
import warnings
import copy
T = TypeVar("T")
def object_hasattr(obj: Any, name: str):
try:
object.__getattribute__(obj, name)
return True
except AttributeError:
return False
def object_getattr(obj: Any, name: str):
return object.__getattribute__(obj, name)
class NoAssignmentError(Exception):
def __init__(self, prop_name):
self.prop_name = prop_name
def __str__(self) -> str:
return f"Cannot assign '{self.prop_name}' property, only mutation is allowed."
class NoAccessError(Exception):
def __init__(self, prop_name):
self.prop_name = prop_name
def __str__(self) -> str:
return (
f"Cannot directly edit '{self.prop_name}' property in the Input object.\n"
f"Use the associated node/link table or use the InputFile object for lower level control. "
)
def no_setter_property(func: Callable[[Any], T]) -> property:
def readonly_setter(self: Any, obj: Any) -> None:
raise NoAssignmentError(func.__name__)
return property(fget=func, fset=readonly_setter, doc=func.__doc__)
[docs]
class Input:
def __init__(self, inpfile: Optional[str | InputFile] = None):
if isinstance(inpfile, InputFile):
self._inp = inpfile
elif isinstance(inpfile, str | pathlib.Path):
self._inp = InputFile(inpfile)
##########################################################
# region General df constructors and destructors #########
##########################################################
# destructors
def _general_destructor(
self, inp_frames: list[pd.DataFrame], output_frame: SectionDf
) -> None:
inp_dfs = []
output_frame_name = output_frame.__class__.__name__.lower()
cols = output_frame._data_cols(desc=False)
for inp_frame in inp_frames:
inp_df = inp_frame.loc[:, cols]
inp_dfs.append(inp_df)
out_df = copy.deepcopy(output_frame)
inp_df = pd.concat(inp_dfs, axis=0)
out_df = out_df.reindex(inp_df.index.rename(out_df.index.name))
out_df.loc[inp_df.index, cols] = inp_df[cols]
out_df = out_df.dropna(how="all")
setattr(self._inp, output_frame_name, out_df)
def _extract_table_and_restore_multi_index(
self,
input_frame: pd.DataFrame,
input_index_name: str,
output_frame: pd.DataFrame,
prepend: list[tuple[str, str]] = [],
append: list[tuple[str, str]] = [],
) -> pd.DataFrame:
cols = output_frame._data_cols(desc=False)
inp_df = input_frame.loc[:, cols]
# out_df = copy.deepcopy(output_frame)
levels = [pd.Index([val], name=nom) for nom, val in prepend]
levels += [inp_df.index.rename(input_index_name)]
levels += [pd.Index([val], name=nom) for nom, val in append]
new_idx = pd.MultiIndex.from_product(levels)
inp_df.index = new_idx
# out_df = out_df.reindex(out_df.index.union(inp_df.index))
# out_df.loc[inp_df.index, cols] = inp_df[cols]
# out_df = out_df.dropna(how="all")
return inp_df.dropna(how="all")
# constructors
def _general_constructor(self, inp_frames: list[SectionDf]) -> pd.DataFrame:
left = inp_frames.pop(0).drop("desc", axis=1, errors="ignore")
for right in inp_frames:
left = pd.merge(
left,
right.drop("desc", axis=1, errors="ignore"),
left_index=True,
right_index=True,
how="left",
)
return left
# endregion General df constructors and destructors ######
# %% ##########################################################
# region DESTRUCTORS ##########################################
# Methods to keep the input file class in sync with this class
###############################################################
def _destruct_tags(self) -> None:
tagged_dfs = [
(self.junc, "Node"),
(self.outfall, "Node"),
(self.storage, "Node"),
(self.divider, "Node"),
(self.conduit, "Link"),
(self.pump, "Link"),
(self.weir, "Link"),
(self.orifice, "Link"),
(self.outlet, "Link"),
(self.subcatchment, "Subcatch"),
]
tag_dfs = [
self._extract_table_and_restore_multi_index(
input_frame=inp_df,
input_index_name="Name",
output_frame=self._inp.tags,
prepend=[("Element", elem_type)],
)
for inp_df, elem_type in tagged_dfs
]
tag_df = pd.concat(tag_dfs, axis=0)
self._inp.tags = self._inp.tags.reindex(tag_df.index)
self._inp.tags.loc[tag_df.index, "Tag"] = tag_df["Tag"]
def _destruct_nodes(self) -> None:
node_dfs = [self.junc, self.outfall, self.storage, self.divider]
out_dfs = [self._inp.rdii, self._inp.coordinates]
inflo_dfs = [self._inp.dwf, self._inp.inflow]
for out_df in out_dfs:
self._general_destructor(inp_frames=node_dfs, output_frame=out_df)
for out_df in inflo_dfs:
output_frame_name = out_df.__class__.__name__.lower()
out_df = out_df.drop("FLOW", level="Constituent", errors="ignore")
inp_dfs = [
self._extract_table_and_restore_multi_index(
input_frame=inp_df,
input_index_name="Node",
output_frame=out_df,
append=[("Constituent", "FLOW")],
)
for inp_df in node_dfs
]
inp_dfs.append(out_df)
inp_df = pd.concat(inp_dfs).dropna(how="all")
setattr(self._inp, output_frame_name, inp_df)
def _destruct_xsect(self) -> None:
if (
hasattr(self, "_conduit_full")
or hasattr(self, "_weir_full")
or hasattr(self, "_orifice_full")
):
self._general_destructor(
inp_frames=[self.conduit, self.weir, self.orifice],
output_frame=self._inp.xsections,
)
# endregion DESTRUCTORS ######
# %% ###########################
# region Generalized NODES #####
################################
def _node_constructor(self, inp_df: SectionDf) -> pd.DataFrame:
return self._general_constructor(
[
inp_df,
self._inp.dwf.loc[(slice(None), slice("FLOW", "FLOW")), :].droplevel(
"Constituent"
),
self._inp.inflow.loc[(slice(None), slice("FLOW", "FLOW")), :].droplevel(
"Constituent"
),
self._inp.rdii,
self._inp.tags.loc[slice("Node", "Node"), slice(None)].droplevel(
"Element"
),
self._inp.coordinates,
]
)
# endregion NODES and LINKS ######
# %% ###########################
# region MAIN TABLES ###########
################################
######### JUNCTIONS #########
@no_setter_property
def junc(self) -> pd.DataFrame:
"""('Name')['Elevation', 'MaxDepth', 'InitDepth', 'SurDepth', 'Aponded', 'AvgValue', 'Pat1', 'Pat2', 'Pat3', 'Pat4', 'TimeSeries', 'InflowType', 'Mfactor', 'Sfactor', 'Baseline', 'Pattern', 'UHgroup', 'SewerArea', 'Tag', 'X', 'Y']"""
if not hasattr(self, "_junc_full"):
self._junc_full = self._node_constructor(self._inp.junc)
return self._junc_full
def _junction_destructor(self) -> None:
if hasattr(self, "_junc_full"):
self._general_destructor([self.junc], self._inp.junc)
######## OUTFALLS #########
@no_setter_property
def outfall(self) -> pd.DataFrame:
"""('Name')['Elevation', 'Type', 'StageData', 'Gated', 'RouteTo', 'AvgValue', 'Pat1', 'Pat2', 'Pat3', 'Pat4', 'TimeSeries', 'InflowType', 'Mfactor', 'Sfactor', 'Baseline', 'Pattern', 'UHgroup', 'SewerArea', 'Tag', 'X', 'Y']"""
if not hasattr(self, "_outfall_full"):
self._outfall_full = self._node_constructor(self._inp.outfall)
return self._outfall_full
def _outfall_destructor(self) -> None:
if hasattr(self, "_outfall_full"):
self._general_destructor([self.outfall], self._inp.outfall)
######## STORAGE #########
@no_setter_property
def storage(self):
"""('Name')['Elev', 'MaxDepth', 'InitDepth', 'Shape', 'CurveName', 'A1_L', 'A2_W', 'A0_Z', 'SurDepth', 'Fevap', 'Psi', 'Ksat', 'IMD', 'AvgValue', 'Pat1', 'Pat2', 'Pat3', 'Pat4', 'TimeSeries', 'InflowType', 'Mfactor', 'Sfactor', 'Baseline', 'Pattern', 'UHgroup', 'SewerArea', 'Tag', 'X', 'Y']"""
if not hasattr(self, "_storage_full"):
self._storage_full = self._node_constructor(self._inp.storage)
return self._storage_full
def _storage_destructor(self) -> None:
if hasattr(self, "_storage_full"):
self._general_destructor([self.storage], self._inp.storage)
######## DIVIDER #########
@no_setter_property
def divider(self):
"""('Name')['Elevation', 'DivLink', 'DivType', 'DivCurve', 'Qmin', 'Height', 'Cd', 'Ymax', 'Y0', 'Ysur', 'Apond', 'AvgValue', 'Pat1', 'Pat2', 'Pat3', 'Pat4', 'TimeSeries', 'InflowType', 'Mfactor', 'Sfactor', 'Baseline', 'Pattern', 'UHgroup', 'SewerArea', 'Tag', 'X', 'Y']"""
if not hasattr(self, "_divider_full"):
self._divider_full = self._node_constructor(self._inp.divider)
return self._divider_full
def _divider_destructor(self) -> None:
if hasattr(self, "_divider_full"):
self._general_destructor([self.divider], self._inp.divider)
######### CONDUITS #########
@no_setter_property
def conduit(self) -> pd.DataFrame:
"""('Name')['FromNode', 'ToNode', 'Length', 'Roughness', 'InOffset', 'OutOffset', 'InitFlow', 'MaxFlow', 'Kentry', 'Kexit', 'Kavg', 'FlapGate', 'Seepage', 'Shape', 'Geom1', 'Curve', 'Geom2', 'Geom3', 'Geom4', 'Barrels', 'Culvert', 'Tag']"""
if not hasattr(self, "_conduit_full"):
self._conduit_full = self._general_constructor(
[
self._inp.conduit,
self._inp.losses,
self._inp.xsections,
self._inp.tags.loc[slice("Link", "Link"), slice(None)].droplevel(0),
]
)
return self._conduit_full
def _conduit_destructor(self) -> None:
if hasattr(self, "_conduit_full"):
for frame in [self._inp.conduit, self._inp.losses]:
self._general_destructor([self.conduit], frame)
######## PUMPS #########
@no_setter_property
def pump(self) -> pd.DataFrame:
"""('Name')['FromNode', 'ToNode', 'PumpCurve', 'Status', 'Startup', 'Shutoff', 'Tag']"""
if not hasattr(self, "_pump_full"):
self._pump_full = self._general_constructor(
[
self._inp.pump,
self._inp.tags.loc[slice("Link", "Link"), slice(None)].droplevel(0),
]
)
return self._pump_full
def _pump_destructor(self) -> None:
if hasattr(self, "_pump_full"):
self._general_destructor([self.pump], self._inp.pump)
######## WEIRS #########
@no_setter_property
def weir(self) -> pd.DataFrame:
"""('Name')['FromNode', 'ToNode', 'Type', 'CrestHt', 'Qcoeff', 'Gated', 'EndCon', 'EndCoeff', 'Surcharge', 'RoadWidth', 'RoadSurf', 'CoeffCurve', 'Shape', 'Geom1', 'Curve', 'Geom2', 'Geom3', 'Geom4', 'Barrels', 'Culvert', 'Tag']"""
if not hasattr(self, "_weir_full"):
self._weir_full = self._general_constructor(
[
self._inp.weir,
self._inp.xsections,
self._inp.tags.loc[slice("Link", "Link"), slice(None)].droplevel(0),
]
)
return self._weir_full
def _weir_destructor(self) -> None:
if hasattr(self, "_weir_full"):
self._general_destructor(
[self.weir],
self._inp.weir,
)
######## ORIFICES #########
@no_setter_property
def orifice(self) -> pd.DataFrame:
"""('Name')['FromNode', 'ToNode', 'Type', 'Offset', 'Qcoeff', 'Gated', 'CloseTime', 'Shape', 'Geom1', 'Curve', 'Geom2', 'Geom3', 'Geom4', 'Barrels', 'Culvert', 'Tag']"""
if not hasattr(self, "_orifice_full"):
self._orifice_full = self._general_constructor(
[
self._inp.orifice,
self._inp.xsections,
self._inp.tags.loc[slice("Link", "Link"), slice(None)].droplevel(0),
]
)
return self._orifice_full
def _orifice_destructor(self) -> None:
if hasattr(self, "_orifice_full"):
self._general_destructor(
[self.orifice],
self._inp.orifice,
)
######## OULETS #########
@no_setter_property
def outlet(self) -> pd.DataFrame:
"""('Name')['FromNode', 'ToNode', 'Offset', 'Type', 'CurveName', 'Qcoeff', 'Qexpon', 'Gated', 'Tag']"""
if not hasattr(self, "_outlet_full"):
self._outlet_full = self._general_constructor(
[
self._inp.outlet,
self._inp.tags.loc[slice("Link", "Link"), slice(None)].droplevel(0),
]
)
return self._outlet_full
def _outlet_destructor(self) -> None:
if hasattr(self, "_outlet_full"):
self._general_destructor(
[self.outlet],
self._inp.outlet,
)
####### SUBCATCHMENTS
@no_setter_property
def subcatchment(self) -> pd.DataFrame:
"""
('Name')['RainGage', 'Outlet', 'Area', 'PctImp', 'Width', 'Slope', 'CurbLeng', 'SnowPack', 'Nimp', 'Nperv', 'Simp', 'Sperv', 'PctZero', 'RouteTo', 'PctRouted', 'Tag']
"""
if not hasattr(self, "_subcatch_full"):
self._subcatch_full = self._general_constructor(
[
self._inp.subcatchment,
self._inp.subarea,
self._inp.tags.loc[
slice("Subcatch", "Subcatch"), slice(None)
].droplevel("Element"),
]
)
return self._subcatch_full
def _subcatchment_destructor(self) -> None:
if hasattr(self, "_subcatch_full"):
self._general_destructor(
[self.subcatchment],
self._inp.subcatchment,
)
self._general_destructor(
[self.subcatchment],
self._inp.subarea,
)
# endregion MAIN TABLES ######
def _clear(self):
full_tables = filter(lambda x: "_full" in x, dir(self))
for table in full_tables:
delattr(self, table)
def _sync(self):
# nodes
self._junction_destructor()
self._outfall_destructor()
self._storage_destructor()
# links
self._conduit_destructor()
self._pump_destructor()
self._orifice_destructor()
self._weir_destructor()
self._outlet_destructor()
# subcatch
self._subcatchment_destructor()
# other
self._destruct_nodes()
self._destruct_xsect()
self._destruct_tags()
def to_file(self, path: str | pathlib.Path):
self._sync()
with open(path, "w") as f:
f.write(self._inp.to_string())
# region non-component sections
# This section is autgenerated by scripts/generate_input_sections.py
@property
def title(self) -> sc.Title:
return self._inp.title
@title.setter
def title(self, obj) -> None:
self._inp.title = obj
@property
def option(self) -> sc.Option:
"('Option')['Value', 'desc']"
return self._inp.option
@option.setter
def option(self, obj) -> None:
self._inp.option = obj
@property
def files(self) -> sc.Files:
"String to hold files section"
return self._inp.files
@files.setter
def files(self, obj) -> None:
self._inp.files = obj
@property
def raingage(self) -> sc.Raingage:
"('Name')['Format', 'Interval', 'SCF', 'Source_Type', 'Source', 'Station', 'Units', 'desc']"
return self._inp.raingage
@raingage.setter
def raingage(self, obj) -> None:
self._inp.raingage = obj
@property
def evap(self) -> sc.Evap:
"('Type')['param1', 'param2', 'param3', 'param4', 'param5', 'param6', 'param7', 'param8', 'param9', 'param10', 'param11', 'param12', 'desc']"
return self._inp.evap
@evap.setter
def evap(self, obj) -> None:
self._inp.evap = obj
@property
def temperature(self) -> sc.Temperature:
"('Option')['param1', 'param2', 'param3', 'param4', 'param5', 'param6', 'param7', 'param8', 'param9', 'param10', 'param11', 'param12', 'param13', 'desc']"
return self._inp.temperature
@temperature.setter
def temperature(self, obj) -> None:
self._inp.temperature = obj
@property
def subarea(self) -> sc.Subarea:
"('Subcatchment')['Nimp', 'Nperv', 'Simp', 'Sperv', 'PctZero', 'RouteTo', 'PctRouted', 'desc']"
return self._inp.subarea
@subarea.setter
def subarea(self, obj) -> None:
self._inp.subarea = obj
@property
def infil(self) -> sc.Infil:
"('Subcatchment')['param1', 'param2', 'param3', 'param4', 'param5', 'Method', 'desc']"
return self._inp.infil
@infil.setter
def infil(self, obj) -> None:
self._inp.infil = obj
@property
def lid_control(self) -> sc.LID_Control:
"('Name')['Type', 'param1', 'param2', 'param3', 'param4', 'param5', 'param6', 'param7', 'desc']"
return self._inp.lid_control
@lid_control.setter
def lid_control(self, obj) -> None:
self._inp.lid_control = obj
@property
def lid_usage(self) -> sc.LID_Usage:
"('Subcatchment', 'LIDProcess')['Number', 'Area', 'Width', 'InitSat', 'FromImp', 'ToPerv', 'RptFile', 'DrainTo', 'FromPerv', 'desc']"
return self._inp.lid_usage
@lid_usage.setter
def lid_usage(self, obj) -> None:
self._inp.lid_usage = obj
@property
def aquifer(self) -> sc.Aquifer:
"('Name')['Por', 'WP', 'FC', 'Ksat', 'Kslope', 'Tslope', 'ETu', 'ETs', 'Seep', 'Ebot', 'Egw', 'Umc', 'ETupat', 'desc']"
return self._inp.aquifer
@aquifer.setter
def aquifer(self, obj) -> None:
self._inp.aquifer = obj
@property
def groundwater(self) -> sc.Groundwater:
"('Subcatchment')['Aquifer', 'Node', 'Esurf', 'A1', 'B1', 'A2', 'B2', 'A3', 'Dsw', 'Egwt', 'Ebot', 'Wgr', 'Umc', 'desc']"
return self._inp.groundwater
@groundwater.setter
def groundwater(self, obj) -> None:
self._inp.groundwater = obj
@property
def gwf(self) -> sc.GWF:
"('Subcatch', 'Type')['Expr', 'desc']"
return self._inp.gwf
@gwf.setter
def gwf(self, obj) -> None:
self._inp.gwf = obj
@property
def snowpack(self) -> sc.Snowpack:
"('Name', 'Surface')['param1', 'param2', 'param3', 'param4', 'param5', 'param6', 'param7', 'desc']"
return self._inp.snowpack
@snowpack.setter
def snowpack(self, obj) -> None:
self._inp.snowpack = obj
@property
def xsections(self) -> sc.Xsections:
"('Link')['Shape', 'Geom1', 'Curve', 'Geom2', 'Geom3', 'Geom4', 'Barrels', 'Culvert', 'desc']"
return self._inp.xsections
@xsections.setter
def xsections(self, obj) -> None:
self._inp.xsections = obj
@property
def transects(self) -> sc.Transects:
"String to hold transects section."
return self._inp.transects
@transects.setter
def transects(self, obj) -> None:
self._inp.transects = obj
@property
def street(self) -> sc.Street:
"('Name')['Tcrown', 'Hcurb', 'Sroad', 'nRoad', 'Hdep', 'Wdep', 'Sides', 'Wback', 'Sback', 'nBack', 'desc']"
return self._inp.street
@street.setter
def street(self, obj) -> None:
self._inp.street = obj
@property
def inlet_usage(self) -> sc.Inlet_Usage:
"('Conduit')['Inlet', 'Node', 'Number', '%Clogged', 'MaxFlow', 'hDStore', 'wDStore', 'Placement', 'desc']"
return self._inp.inlet_usage
@inlet_usage.setter
def inlet_usage(self, obj) -> None:
self._inp.inlet_usage = obj
@property
def inlet(self) -> sc.Inlet:
"('Name', 'Type')['param1', 'param2', 'param3', 'param4', 'param5', 'desc']"
return self._inp.inlet
@inlet.setter
def inlet(self, obj) -> None:
self._inp.inlet = obj
@property
def losses(self) -> sc.Losses:
"('Link')['Kentry', 'Kexit', 'Kavg', 'FlapGate', 'Seepage', 'desc']"
return self._inp.losses
@losses.setter
def losses(self, obj) -> None:
self._inp.losses = obj
@property
def controls(self) -> sc.Controls:
"Dict of control rules stored as text."
return self._inp.controls
@controls.setter
def controls(self, obj) -> None:
self._inp.controls = obj
@property
def pollutants(self) -> sc.Pollutants:
"('Name')['Units', 'Crain', 'Cgw', 'Crdii', 'Kdecay', 'SnowOnly', 'CoPollutant', 'CoFrac', 'Cdwf', 'Cinit', 'desc']"
return self._inp.pollutants
@pollutants.setter
def pollutants(self, obj) -> None:
self._inp.pollutants = obj
@property
def landuse(self) -> sc.LandUse:
"('Name')['SweepInterval', 'Availability', 'LastSweep', 'desc']"
return self._inp.landuse
@landuse.setter
def landuse(self, obj) -> None:
self._inp.landuse = obj
@property
def coverage(self) -> sc.Coverage:
"('Subcatchment', 'LandUse')['Percent', 'desc']"
return self._inp.coverage
@coverage.setter
def coverage(self, obj) -> None:
self._inp.coverage = obj
@property
def loading(self) -> sc.Loading:
"('Subcatchment', 'Pollutant')['InitBuildup', 'desc']"
return self._inp.loading
@loading.setter
def loading(self, obj) -> None:
self._inp.loading = obj
@property
def buildup(self) -> sc.Buildup:
"('Landuse', 'Pollutant')['FuncType', 'C1', 'C2', 'C3', 'PerUnit', 'desc']"
return self._inp.buildup
@buildup.setter
def buildup(self, obj) -> None:
self._inp.buildup = obj
@property
def washoff(self) -> sc.Washoff:
"('Landuse', 'Pollutant')['FuncType', 'C1', 'C2', 'SweepRmvl', 'BmpRmvl', 'desc']"
return self._inp.washoff
@washoff.setter
def washoff(self, obj) -> None:
self._inp.washoff = obj
@property
def treatment(self) -> sc.Treatment:
"('Node', 'Pollutant')['Func', 'desc']"
return self._inp.treatment
@treatment.setter
def treatment(self, obj) -> None:
self._inp.treatment = obj
@property
def inflow(self) -> sc.Inflow:
"('Node', 'Constituent')['TimeSeries', 'InflowType', 'Mfactor', 'Sfactor', 'Baseline', 'Pattern', 'desc']"
return self._inp.inflow
@inflow.setter
def inflow(self, obj) -> None:
self._inp.inflow = obj
@property
def dwf(self) -> sc.DWF:
"('Node', 'Constituent')['AvgValue', 'Pat1', 'Pat2', 'Pat3', 'Pat4', 'desc']"
return self._inp.dwf
@dwf.setter
def dwf(self, obj) -> None:
self._inp.dwf = obj
@property
def rdii(self) -> sc.RDII:
"('Node')['UHgroup', 'SewerArea', 'desc']"
return self._inp.rdii
@rdii.setter
def rdii(self, obj) -> None:
self._inp.rdii = obj
@property
def hydrographs(self) -> sc.Hydrographs:
"('Name', 'Month_RG', 'Response')['R', 'T', 'K', 'IA_max', 'IA_rec', 'IA_ini', 'desc']"
return self._inp.hydrographs
@hydrographs.setter
def hydrographs(self, obj) -> None:
self._inp.hydrographs = obj
@property
def curves(self) -> sc.Curves:
"('Name')['Type', 'X_Value', 'Y_Value', 'desc']"
return self._inp.curves
@curves.setter
def curves(self, obj) -> None:
self._inp.curves = obj
@property
def timeseries(self) -> sc.Timeseries:
"Dict of dataframes or TimeseriesFile dataclass."
return self._inp.timeseries
@timeseries.setter
def timeseries(self, obj) -> None:
self._inp.timeseries = obj
@property
def patterns(self) -> sc.Patterns:
"('Name')['Type', 'Multiplier', 'desc']"
return self._inp.patterns
@patterns.setter
def patterns(self, obj) -> None:
self._inp.patterns = obj
@property
def report(self) -> sc.Report:
"Data class with attribute for each report option."
return self._inp.report
@report.setter
def report(self, obj) -> None:
self._inp.report = obj
@property
def adjustments(self) -> sc.Adjustments:
"('Parameter')['Subcatchment', 'Pattern', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'desc']"
return self._inp.adjustments
@adjustments.setter
def adjustments(self, obj) -> None:
self._inp.adjustments = obj
@property
def event(self) -> sc.Event:
"()['Start', 'End', 'desc']"
return self._inp.event
@event.setter
def event(self, obj) -> None:
self._inp.event = obj
@property
def tags(self) -> sc.Tags:
"('Element', 'Name')['Tag', 'desc']"
return self._inp.tags
@tags.setter
def tags(self, obj) -> None:
self._inp.tags = obj
@property
def map(self) -> sc.Map:
"String class to hold map section text."
return self._inp.map
@map.setter
def map(self, obj) -> None:
self._inp.map = obj
@property
def coordinates(self) -> sc.Coordinates:
"('Node')['X', 'Y', 'desc']"
return self._inp.coordinates
@coordinates.setter
def coordinates(self, obj) -> None:
self._inp.coordinates = obj
@property
def vertices(self) -> sc.Vertices:
"('Link')['X', 'Y', 'desc']"
return self._inp.vertices
@vertices.setter
def vertices(self, obj) -> None:
self._inp.vertices = obj
@property
def polygons(self) -> sc.Polygons:
"('Elem')['X', 'Y', 'desc']"
return self._inp.polygons
@polygons.setter
def polygons(self, obj) -> None:
self._inp.polygons = obj
@property
def symbols(self) -> sc.Symbols:
"('Gage')['X', 'Y', 'desc']"
return self._inp.symbols
@symbols.setter
def symbols(self, obj) -> None:
self._inp.symbols = obj
@property
def labels(self) -> sc.Labels:
"()['Xcoord', 'Ycoord', 'Label', 'Anchor', 'Font', 'Size', 'Bold', 'Italic', 'desc']"
return self._inp.labels
@labels.setter
def labels(self, obj) -> None:
self._inp.labels = obj
@property
def backdrop(self) -> sc.Backdrop:
"String class to hold backdrop section text."
return self._inp.backdrop
@backdrop.setter
def backdrop(self, obj) -> None:
self._inp.backdrop = obj
@property
def profile(self) -> sc.Profile:
"String class to hold profile section text"
return self._inp.profile
@profile.setter
def profile(self, obj) -> None:
self._inp.profile = obj
# endregion non-component sections