{ "cells": [ { "cell_type": "markdown", "id": "a97e4813", "metadata": {}, "source": [ "# PCSWMM Generic Engineering Review Dashboard v0.4\n", "\n", "This dashboard detects the active model's features and runs only the\n", "applicable deterministic review modules.\n", "\n", "It is not specific to a pond model." ] }, { "cell_type": "markdown", "id": "fed3f9c3", "metadata": {}, "source": [ "## 1. Load SDK" ] }, { "cell_type": "code", "execution_count": 1, "id": "07197572", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "{'pcpy_type': \"\",\n", " 'project_open': True,\n", " 'project': {'captured_at': '2026-08-01T08:00:39',\n", " 'project_open': True,\n", " 'project_name': 'Valleyfield to-be dual system',\n", " 'project_folder': 'D:\\\\Documents\\\\EPA SWMM Projects\\\\',\n", " 'model_file': 'D:\\\\Documents\\\\EPA SWMM Projects\\\\Valleyfield to-be dual system.inp',\n", " 'swmm_version': 'SWMM5.0.022',\n", " 'run_status': 'PCSWMM.Scripts.PySWMMRunStatus',\n", " 'scenario_count': 2,\n", " 'node_count': 20,\n", " 'link_count': 28,\n", " 'junction_count': 18,\n", " 'conduit_count': 18,\n", " 'subcatchment_count': 9,\n", " 'storage_count': 1,\n", " 'outfall_count': 1,\n", " 'graph_file_count': 1},\n", " 'capabilities': {'model_archetype': 'collection_system_with_storage',\n", " 'has_subcatchments': True,\n", " 'has_conveyance': True,\n", " 'has_storage': True,\n", " 'has_outlet_structures': True,\n", " 'has_water_quality': False,\n", " 'has_lid': False,\n", " 'has_snowmelt': False,\n", " 'has_groundwater': False,\n", " 'has_controls': False,\n", " 'counts': {'Scenarios': 2,\n", " 'Nodes': 20,\n", " 'Links': 28,\n", " 'Subcatchments': 9,\n", " 'Junctions': 18,\n", " 'Outfalls': 1,\n", " 'Dividers': 0,\n", " 'Storages': 1,\n", " 'Conduits': 18,\n", " 'Pumps': 0,\n", " 'Orifices': 0,\n", " 'Weirs': 0,\n", " 'Outlets': 10,\n", " 'Raingages': 2,\n", " 'Curves': 2,\n", " 'TimeSeries': 2,\n", " 'Controls': 0,\n", " 'Patterns': 0,\n", " 'Pollutants': 0}}}" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import sys\n", "import importlib\n", "from pathlib import Path\n", "\n", "REQUIRED_VERSION = \"0.4.0\"\n", "ROOT = Path.cwd()\n", "\n", "preferred = [\n", " ROOT / \"PCSWMM_Engineering_SDK_v0_4\",\n", " ROOT / \"PCSWMM_Engineering_SDK_v0_4\" / \"PCSWMM_Engineering_SDK_v0_4\",\n", "]\n", "\n", "SDK_ROOT = next(\n", " (path for path in preferred if (path / \"pcswmm_ai\").is_dir()),\n", " None,\n", ")\n", "\n", "if SDK_ROOT is None:\n", " matches = [\n", " p.parent for p in ROOT.rglob(\"pcswmm_ai\")\n", " if p.is_dir() and \"Engineering_SDK_v0_4\" in str(p.parent)\n", " ]\n", " SDK_ROOT = matches[0] if matches else None\n", "\n", "if SDK_ROOT is None:\n", " raise FileNotFoundError(\"PCSWMM Engineering SDK v0.4 was not found.\")\n", "\n", "for module_name in list(sys.modules):\n", " if module_name == \"pcswmm_ai\" or module_name.startswith(\"pcswmm_ai.\"):\n", " del sys.modules[module_name]\n", "\n", "sys.path = [\n", " p for p in sys.path\n", " if \"PCSWMM_AI_SDK_v0_\" not in str(p)\n", " and \"PCSWMM_Engineering_SDK_v0_\" not in str(p)\n", "]\n", "sys.path.insert(0, str(SDK_ROOT))\n", "importlib.invalidate_caches()\n", "\n", "from pcswmm_ai import PCSWMMClient, __version__\n", "\n", "if __version__ != REQUIRED_VERSION:\n", " raise RuntimeError(\n", " f\"Expected SDK {REQUIRED_VERSION}; loaded {__version__}\"\n", " )\n", "\n", "client = PCSWMMClient(pcpy)\n", "client.health()" ] }, { "cell_type": "markdown", "id": "01ca5af0", "metadata": {}, "source": [ "## 2. Detect model capabilities" ] }, { "cell_type": "code", "execution_count": 2, "id": "8df01f33", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CapabilityValue
0model_archetypecollection_system_with_storage
1has_subcatchmentsTrue
2has_conveyanceTrue
3has_storageTrue
4has_outlet_structuresTrue
5has_water_qualityFalse
6has_lidFalse
7has_snowmeltFalse
8has_groundwaterFalse
9has_controlsFalse
\n", "
" ], "text/plain": [ " Capability Value\n", "0 model_archetype collection_system_with_storage\n", "1 has_subcatchments True\n", "2 has_conveyance True\n", "3 has_storage True\n", "4 has_outlet_structures True\n", "5 has_water_quality False\n", "6 has_lid False\n", "7 has_snowmelt False\n", "8 has_groundwater False\n", "9 has_controls False" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "### Applicable review modules" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Module
0project
1inventory
2topology
3scenario_paths
4hydrology
5hydraulics
6storage
7outlet_structures
\n", "
" ], "text/plain": [ " Module\n", "0 project\n", "1 inventory\n", "2 topology\n", "3 scenario_paths\n", "4 hydrology\n", "5 hydraulics\n", "6 storage\n", "7 outlet_structures" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pandas as pd\n", "from IPython.display import display, Markdown\n", "\n", "capabilities = client.capabilities.detect()\n", "\n", "display(pd.DataFrame(\n", " [\n", " {\"Capability\": key, \"Value\": value}\n", " for key, value in capabilities.items()\n", " if key != \"counts\"\n", " ]\n", "))\n", "\n", "display(Markdown(\"### Applicable review modules\"))\n", "display(pd.DataFrame({\n", " \"Module\": client.capabilities.applicable_review_modules()\n", "}))" ] }, { "cell_type": "markdown", "id": "87dc6b09", "metadata": {}, "source": [ "## 3. Generic project and topology review" ] }, { "cell_type": "code", "execution_count": 3, "id": "c5a955d5", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PropertyValue
0captured_at2026-08-01T08:00:57
1project_openTrue
2project_nameValleyfield to-be dual system
3project_folderD:\\Documents\\EPA SWMM Projects\\
4model_fileD:\\Documents\\EPA SWMM Projects\\Valleyfield to-...
5swmm_versionSWMM5.0.022
6run_statusPCSWMM.Scripts.PySWMMRunStatus
7scenario_count2
8node_count20
9link_count28
10junction_count18
11conduit_count18
12subcatchment_count9
13storage_count1
14outfall_count1
15graph_file_count1
\n", "
" ], "text/plain": [ " Property Value\n", "0 captured_at 2026-08-01T08:00:57\n", "1 project_open True\n", "2 project_name Valleyfield to-be dual system\n", "3 project_folder D:\\Documents\\EPA SWMM Projects\\\n", "4 model_file D:\\Documents\\EPA SWMM Projects\\Valleyfield to-...\n", "5 swmm_version SWMM5.0.022\n", "6 run_status PCSWMM.Scripts.PySWMMRunStatus\n", "7 scenario_count 2\n", "8 node_count 20\n", "9 link_count 28\n", "10 junction_count 18\n", "11 conduit_count 18\n", "12 subcatchment_count 9\n", "13 storage_count 1\n", "14 outfall_count 1\n", "15 graph_file_count 1" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "### Collection inventory" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
collectioncounttype
0Scenarios2<class 'PCSWMM.Scripts.PythonDictionaryExt'>
1Nodes20<class 'PCSWMM.Scripts.PythonDictionaryExt'>
2Links28<class 'PCSWMM.Scripts.PythonDictionaryExt'>
3Subcatchments9<class 'PCSWMM.Scripts.PythonDictionaryExt'>
4Junctions18<class 'PCSWMM.Scripts.PythonDictionaryExt'>
5Outfalls1<class 'PCSWMM.Scripts.PythonDictionaryExt'>
6Dividers0<class 'PCSWMM.Scripts.PythonDictionaryExt'>
7Storages1<class 'PCSWMM.Scripts.PythonDictionaryExt'>
8Conduits18<class 'PCSWMM.Scripts.PythonDictionaryExt'>
9Pumps0<class 'PCSWMM.Scripts.PythonDictionaryExt'>
10Orifices0<class 'PCSWMM.Scripts.PythonDictionaryExt'>
11Weirs0<class 'PCSWMM.Scripts.PythonDictionaryExt'>
12Outlets10<class 'PCSWMM.Scripts.PythonDictionaryExt'>
13Raingages2<class 'PCSWMM.Scripts.PythonDictionaryExt'>
14Curves2<class 'PCSWMM.Scripts.PythonDictionaryExt'>
15TimeSeries2<class 'PCSWMM.Scripts.PythonDictionaryExt'>
16Controls0<class 'str'>
17Patterns0<class 'PCSWMM.Scripts.PythonDictionaryExt'>
18Pollutants0<class 'PCSWMM.Scripts.PythonDictionaryExt'>
\n", "
" ], "text/plain": [ " collection count type\n", "0 Scenarios 2 \n", "1 Nodes 20 \n", "2 Links 28 \n", "3 Subcatchments 9 \n", "4 Junctions 18 \n", "5 Outfalls 1 \n", "6 Dividers 0 \n", "7 Storages 1 \n", "8 Conduits 18 \n", "9 Pumps 0 \n", "10 Orifices 0 \n", "11 Weirs 0 \n", "12 Outlets 10 \n", "13 Raingages 2 \n", "14 Curves 2 \n", "15 TimeSeries 2 \n", "16 Controls 0 \n", "17 Patterns 0 \n", "18 Pollutants 0 " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "### Link endpoints" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
linkfrom_nodeto_node
0C7J7J8
1C7-SJ7-SJ8-S
2C2J2J3
3C6-SJ6-SJ7-S
4J7-ICJ7-SJ7
5C9J9J4
6J9-ICJ9-SJ9
7J6-ICJ6-SJ6
8C1J1J2
9J8-ICJ8-SJ8
10C3-SJ3-SJ4-S
11J5-ICJ5-SJ5
12C2-SJ2-SJ3-S
13C9-SJ9-SJ4-S
14J4-ICJ4-SJ4
15J3-ICJ3-SJ3
16C4J4J8
17PondOutletPondOutfall
18C8-SJ8-SPond
19J2-ICJ2-SJ2
20C3J3J4
21J1-ICJ1-SJ1
22C6J6J7
23C5-SJ5-SJ6-S
24C4-SJ4-SJ8-S
25C5J5J6
26C8J8Pond
27C1-SJ1-SJ2-S
\n", "
" ], "text/plain": [ " link from_node to_node\n", "0 C7 J7 J8\n", "1 C7-S J7-S J8-S\n", "2 C2 J2 J3\n", "3 C6-S J6-S J7-S\n", "4 J7-IC J7-S J7\n", "5 C9 J9 J4\n", "6 J9-IC J9-S J9\n", "7 J6-IC J6-S J6\n", "8 C1 J1 J2\n", "9 J8-IC J8-S J8\n", "10 C3-S J3-S J4-S\n", "11 J5-IC J5-S J5\n", "12 C2-S J2-S J3-S\n", "13 C9-S J9-S J4-S\n", "14 J4-IC J4-S J4\n", "15 J3-IC J3-S J3\n", "16 C4 J4 J8\n", "17 PondOutlet Pond Outfall\n", "18 C8-S J8-S Pond\n", "19 J2-IC J2-S J2\n", "20 C3 J3 J4\n", "21 J1-IC J1-S J1\n", "22 C6 J6 J7\n", "23 C5-S J5-S J6-S\n", "24 C4-S J4-S J8-S\n", "25 C5 J5 J6\n", "26 C8 J8 Pond\n", "27 C1-S J1-S J2-S" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "### Orphan links" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
" ], "text/plain": [ "Empty DataFrame\n", "Columns: []\n", "Index: []" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "### Isolated nodes" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
" ], "text/plain": [ "Empty DataFrame\n", "Columns: []\n", "Index: []" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(pd.DataFrame(\n", " list(client.project.summary().items()),\n", " columns=[\"Property\", \"Value\"],\n", "))\n", "\n", "display(Markdown(\"### Collection inventory\"))\n", "display(pd.DataFrame(client.collections.summary()))\n", "\n", "display(Markdown(\"### Link endpoints\"))\n", "display(pd.DataFrame(client.topology.link_endpoints()))\n", "\n", "display(Markdown(\"### Orphan links\"))\n", "display(pd.DataFrame(client.topology.orphan_links()))\n", "\n", "display(Markdown(\"### Isolated nodes\"))\n", "display(pd.DataFrame(client.topology.isolated_nodes()))" ] }, { "cell_type": "markdown", "id": "da05eee1", "metadata": {}, "source": [ "## 4. Conditional hydrology review" ] }, { "cell_type": "code", "execution_count": 4, "id": "e14293ce", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
MetricValue
0subcatchment_count9.00
1total_area_model_units7.17
2weighted_percent_impervious30.00
3finding_count9.00
\n", "
" ], "text/plain": [ " Metric Value\n", "0 subcatchment_count 9.00\n", "1 total_area_model_units 7.17\n", "2 weighted_percent_impervious 30.00\n", "3 finding_count 9.00" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameAreaWidthWidthAreaRatioSlopePctImpervCurveNumberOutletissues
0S11.41148.4210105.2631210.530.0NoneJ1-S[width-to-area ratio outside screening range]
1S21.05110.5263105.2631430.530.0NoneJ2-S[width-to-area ratio outside screening range]
2S31.03108.4210105.2631070.530.0NoneJ3-S[width-to-area ratio outside screening range]
3S40.5557.8947105.2630910.530.0NoneJ4-S[width-to-area ratio outside screening range]
4S50.1818.9474105.2633330.530.0NoneJ5-S[width-to-area ratio outside screening range]
5S60.97102.1053105.2631960.530.0NoneJ6-S[width-to-area ratio outside screening range]
6S71.49156.8420105.2630870.530.0NoneJ7-S[width-to-area ratio outside screening range]
7S80.2627.3684105.2630770.530.0NoneJ8-S[width-to-area ratio outside screening range]
8S90.2324.2105105.2630430.530.0NoneJ9-S[width-to-area ratio outside screening range]
\n", "
" ], "text/plain": [ " Name Area Width WidthAreaRatio Slope PctImperv CurveNumber Outlet \\\n", "0 S1 1.41 148.4210 105.263121 0.5 30.0 None J1-S \n", "1 S2 1.05 110.5263 105.263143 0.5 30.0 None J2-S \n", "2 S3 1.03 108.4210 105.263107 0.5 30.0 None J3-S \n", "3 S4 0.55 57.8947 105.263091 0.5 30.0 None J4-S \n", "4 S5 0.18 18.9474 105.263333 0.5 30.0 None J5-S \n", "5 S6 0.97 102.1053 105.263196 0.5 30.0 None J6-S \n", "6 S7 1.49 156.8420 105.263087 0.5 30.0 None J7-S \n", "7 S8 0.26 27.3684 105.263077 0.5 30.0 None J8-S \n", "8 S9 0.23 24.2105 105.263043 0.5 30.0 None J9-S \n", "\n", " issues \n", "0 [width-to-area ratio outside screening range] \n", "1 [width-to-area ratio outside screening range] \n", "2 [width-to-area ratio outside screening range] \n", "3 [width-to-area ratio outside screening range] \n", "4 [width-to-area ratio outside screening range] \n", "5 [width-to-area ratio outside screening range] \n", "6 [width-to-area ratio outside screening range] \n", "7 [width-to-area ratio outside screening range] \n", "8 [width-to-area ratio outside screening range] " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "if capabilities[\"has_subcatchments\"]:\n", " display(pd.DataFrame(\n", " list(client.hydrology.summary().items()),\n", " columns=[\"Metric\", \"Value\"],\n", " ))\n", " display(pd.DataFrame(client.hydrology.review()))\n", "else:\n", " print(\"Hydrology review is not applicable to this model.\")" ] }, { "cell_type": "markdown", "id": "94e3a023", "metadata": {}, "source": [ "## 5. Conditional storage and outlet review" ] }, { "cell_type": "code", "execution_count": 5, "id": "5edb6b42", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/markdown": [ "### Storage summary" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
MetricValue
0storage_count1
1outlet_structure_count10
2finding_count0
\n", "
" ], "text/plain": [ " Metric Value\n", "0 storage_count 1\n", "1 outlet_structure_count 10\n", "2 finding_count 0" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "### Storage records" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameObjectTypeConductivityDWInflowDWInflowsDepthDescriptionDirectInflowDirectInflowsEvapFactor...SewershedAreaStorageCurveTypeSuctionHeadSurchargeDepthTagTreatmentTreatmentsUHXY
0PondStorages0.0PCSWMM.Scripts.IndexProperty`2[System.String,P...PCSWMM.Scripts.PythonDictionaryExt2.0NonePCSWMM.Scripts.IndexProperty`2[System.String,P...PCSWMM.Scripts.PythonDictionaryExt0.0...0.0FUNCTIONAL0.00.0PCSWMM.Scripts.IndexProperty`2[System.String,S...PCSWMM.Scripts.PythonDictionaryExt254377.0715015025.677
\n", "

1 rows × 29 columns

\n", "
" ], "text/plain": [ " Name ObjectType Conductivity \\\n", "0 Pond Storages 0.0 \n", "\n", " DWInflow \\\n", "0 PCSWMM.Scripts.IndexProperty`2[System.String,P... \n", "\n", " DWInflows Depth Description \\\n", "0 PCSWMM.Scripts.PythonDictionaryExt 2.0 None \n", "\n", " DirectInflow \\\n", "0 PCSWMM.Scripts.IndexProperty`2[System.String,P... \n", "\n", " DirectInflows EvapFactor ... SewershedArea \\\n", "0 PCSWMM.Scripts.PythonDictionaryExt 0.0 ... 0.0 \n", "\n", " StorageCurveType SuctionHead SurchargeDepth Tag \\\n", "0 FUNCTIONAL 0.0 0.0 \n", "\n", " Treatment \\\n", "0 PCSWMM.Scripts.IndexProperty`2[System.String,S... \n", "\n", " Treatments UH X Y \n", "0 PCSWMM.Scripts.PythonDictionaryExt 254377.071 5015025.677 \n", "\n", "[1 rows x 29 columns]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "### Outlet structures" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
NameObjectTypeCurveDescriptionFlapGateFunctionCoeffFunctionExpInletNodeInletOffsetNotesOutletNodeRatingCurveTypeTagStructureCollection
0J2-ICOutletsCatchbasinNoneNO10.00.5J2-S0.0System.Collections.Generic.List`1[PCSWMM.Scrip...J2TABULAR/DEPTHOutlets
1J8-ICOutletsCatchbasinNoneNO10.00.5J8-S0.0System.Collections.Generic.List`1[PCSWMM.Scrip...J8TABULAR/DEPTHOutlets
2J3-ICOutletsCatchbasinNoneNO10.00.5J3-S0.0System.Collections.Generic.List`1[PCSWMM.Scrip...J3TABULAR/DEPTHOutlets
3J1-ICOutletsCatchbasinNoneNO10.00.5J1-S0.0System.Collections.Generic.List`1[PCSWMM.Scrip...J1TABULAR/DEPTHOutlets
4J9-ICOutletsCatchbasinNoneNO10.00.5J9-S0.0System.Collections.Generic.List`1[PCSWMM.Scrip...J9TABULAR/DEPTHOutlets
5J4-ICOutletsCatchbasinNoneNO10.00.5J4-S0.0System.Collections.Generic.List`1[PCSWMM.Scrip...J4TABULAR/DEPTHOutlets
6J7-ICOutletsCatchbasinNoneNO10.00.5J7-S0.0System.Collections.Generic.List`1[PCSWMM.Scrip...J7TABULAR/DEPTHOutlets
7J5-ICOutletsCatchbasinNoneNO10.00.5J5-S0.0System.Collections.Generic.List`1[PCSWMM.Scrip...J5TABULAR/DEPTHOutlets
8J6-ICOutletsCatchbasinNoneNO10.00.5J6-S0.0System.Collections.Generic.List`1[PCSWMM.Scrip...J6TABULAR/DEPTHOutlets
9PondOutletOutletsPondOutletNoneNO10.00.5Pond0.0System.Collections.Generic.List`1[PCSWMM.Scrip...OutfallTABULAR/DEPTHOutlets
\n", "
" ], "text/plain": [ " Name ObjectType Curve Description FlapGate FunctionCoeff \\\n", "0 J2-IC Outlets Catchbasin None NO 10.0 \n", "1 J8-IC Outlets Catchbasin None NO 10.0 \n", "2 J3-IC Outlets Catchbasin None NO 10.0 \n", "3 J1-IC Outlets Catchbasin None NO 10.0 \n", "4 J9-IC Outlets Catchbasin None NO 10.0 \n", "5 J4-IC Outlets Catchbasin None NO 10.0 \n", "6 J7-IC Outlets Catchbasin None NO 10.0 \n", "7 J5-IC Outlets Catchbasin None NO 10.0 \n", "8 J6-IC Outlets Catchbasin None NO 10.0 \n", "9 PondOutlet Outlets PondOutlet None NO 10.0 \n", "\n", " FunctionExp InletNode InletOffset \\\n", "0 0.5 J2-S 0.0 \n", "1 0.5 J8-S 0.0 \n", "2 0.5 J3-S 0.0 \n", "3 0.5 J1-S 0.0 \n", "4 0.5 J9-S 0.0 \n", "5 0.5 J4-S 0.0 \n", "6 0.5 J7-S 0.0 \n", "7 0.5 J5-S 0.0 \n", "8 0.5 J6-S 0.0 \n", "9 0.5 Pond 0.0 \n", "\n", " Notes OutletNode \\\n", "0 System.Collections.Generic.List`1[PCSWMM.Scrip... J2 \n", "1 System.Collections.Generic.List`1[PCSWMM.Scrip... J8 \n", "2 System.Collections.Generic.List`1[PCSWMM.Scrip... J3 \n", "3 System.Collections.Generic.List`1[PCSWMM.Scrip... J1 \n", "4 System.Collections.Generic.List`1[PCSWMM.Scrip... J9 \n", "5 System.Collections.Generic.List`1[PCSWMM.Scrip... J4 \n", "6 System.Collections.Generic.List`1[PCSWMM.Scrip... J7 \n", "7 System.Collections.Generic.List`1[PCSWMM.Scrip... J5 \n", "8 System.Collections.Generic.List`1[PCSWMM.Scrip... J6 \n", "9 System.Collections.Generic.List`1[PCSWMM.Scrip... Outfall \n", "\n", " RatingCurveType Tag StructureCollection \n", "0 TABULAR/DEPTH Outlets \n", "1 TABULAR/DEPTH Outlets \n", "2 TABULAR/DEPTH Outlets \n", "3 TABULAR/DEPTH Outlets \n", "4 TABULAR/DEPTH Outlets \n", "5 TABULAR/DEPTH Outlets \n", "6 TABULAR/DEPTH Outlets \n", "7 TABULAR/DEPTH Outlets \n", "8 TABULAR/DEPTH Outlets \n", "9 TABULAR/DEPTH Outlets " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "### Findings" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
" ], "text/plain": [ "Empty DataFrame\n", "Columns: []\n", "Index: []" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "if capabilities[\"has_storage\"] or capabilities[\"has_outlet_structures\"]:\n", " display(Markdown(\"### Storage summary\"))\n", " display(pd.DataFrame(\n", " list(client.storage.summary().items()),\n", " columns=[\"Metric\", \"Value\"],\n", " ))\n", "\n", " display(Markdown(\"### Storage records\"))\n", " display(pd.DataFrame(client.storage.storage_records()))\n", "\n", " display(Markdown(\"### Outlet structures\"))\n", " display(pd.DataFrame(client.storage.outlet_structure_records()))\n", "\n", " display(Markdown(\"### Findings\"))\n", " display(pd.DataFrame(client.storage.review()))\n", "else:\n", " print(\"Storage/outlet review is not applicable to this model.\")" ] }, { "cell_type": "markdown", "id": "75c80e2f", "metadata": {}, "source": [ "## 6. Scenario path review" ] }, { "cell_type": "code", "execution_count": 6, "id": "46e32ca4", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
MetricValue
0scenario_count2
1existing_path_count1
2missing_path_count1
\n", "
" ], "text/plain": [ " Metric Value\n", "0 scenario_count 2\n", "1 existing_path_count 1\n", "2 missing_path_count 1" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
scenario_pathexistssuffixfile_nameparent
0D:\\Documents\\EPA SWMM Projects\\Valleyfield to-...True.inpValleyfield to-be dual system.inpD:\\Documents\\EPA SWMM Projects
1C:\\Users\\Raza Ali\\Documents\\EPA SWMM Projects\\...False.inpValleyfield to-be dual system.inpC:\\Users\\Raza Ali\\Documents\\EPA SWMM Projects
\n", "
" ], "text/plain": [ " scenario_path exists suffix \\\n", "0 D:\\Documents\\EPA SWMM Projects\\Valleyfield to-... True .inp \n", "1 C:\\Users\\Raza Ali\\Documents\\EPA SWMM Projects\\... False .inp \n", "\n", " file_name \\\n", "0 Valleyfield to-be dual system.inp \n", "1 Valleyfield to-be dual system.inp \n", "\n", " parent \n", "0 D:\\Documents\\EPA SWMM Projects \n", "1 C:\\Users\\Raza Ali\\Documents\\EPA SWMM Projects " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(pd.DataFrame(\n", " list(client.scenarios.summary().items()),\n", " columns=[\"Metric\", \"Value\"],\n", "))\n", "display(pd.DataFrame(client.scenarios.path_status()))" ] }, { "cell_type": "markdown", "id": "39006904", "metadata": {}, "source": [ "## 7. Run generic review engine" ] }, { "cell_type": "code", "execution_count": 7, "id": "a1a3fc12", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Model archetype: collection_system_with_storage\n", "Applicable modules: ['project', 'inventory', 'topology', 'scenario_paths', 'hydrology', 'hydraulics', 'storage', 'outlet_structures']\n", "Report sections: ['generated_at', 'classification', 'project', 'capabilities', 'applicable_modules', 'inventory', 'topology', 'general_engineering', 'scenario_paths', 'hydrology', 'storage_and_outlets']\n" ] } ], "source": [ "review = client.review_engine.run()\n", "\n", "print(\"Model archetype:\", review[\"capabilities\"][\"model_archetype\"])\n", "print(\"Applicable modules:\", review[\"applicable_modules\"])\n", "print(\"Report sections:\", list(review.keys()))" ] }, { "cell_type": "markdown", "id": "71ba8a3b", "metadata": {}, "source": [ "## 8. Optional hydraulic result examples" ] }, { "cell_type": "code", "execution_count": 8, "id": "163f0b89", "metadata": { "tags": [] }, "outputs": [], "source": [ "# Confirm PCSWMM result labels and units before uncommenting.\n", "\n", "# Generic link peak:\n", "# display(pd.DataFrame(\n", "# client.hydraulics.peak_link_results(\"Flow\", \"CMS\")\n", "# ))\n", "\n", "# Generic node peak:\n", "# display(pd.DataFrame(\n", "# client.hydraulics.peak_node_results(\"Depth\", \"m\")\n", "# ))" ] }, { "cell_type": "markdown", "id": "1d8a23a8", "metadata": {}, "source": [ "## Design principle\n", "\n", "The SDK core is model-agnostic.\n", "\n", "- A runoff-only model activates hydrology review.\n", "- A pipe network activates conveyance and topology review.\n", "- A storage model activates storage/outlet review.\n", "- A combined network activates all applicable modules.\n", "- Future water-quality, LID, groundwater, snowmelt, and municipal rule packs\n", " will follow the same capability-based architecture." ] }, { "cell_type": "code", "execution_count": null, "id": "7a098d53-b24a-4d39-bb4d-35dbc6e3c796", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 }