Floodplain Mapping via GUI Automation¶
This notebook demonstrates floodplain mapping using HEC-RAS GUI automation to generate: - Maximum Water Surface Elevation (WSE) rasters - Maximum Depth rasters
The workflow is fully automated: HEC-RAS opens, computes the stored maps, and auto-closes when complete. No manual interaction is required.
How It Works¶
RasMap.postprocess_stored_maps() handles the full workflow:
1. Backs up plan and .rasmap files
2. Sets run flags to floodplain-mapping-only (skips simulation)
3. Configures stored map layers in .rasmap XML (creates RASResults layer if missing)
4. Opens HEC-RAS GUI and clicks Compute
5. Polls plan HDF for "Complete Process" signal to detect completion
6. Auto-closes HEC-RAS and restores original files
Comparison with RasProcess CLI (Notebook 601)¶
| Method | Speed | GUI Required | Best For |
|---|---|---|---|
| GUI Automation (this notebook) | ~15 sec | Yes (auto-managed) | Debugging, visual verification |
| RasProcess CLI (notebook 601) | ~8 sec | No | Production, batch processing |
Prerequisites¶
- HEC-RAS 6.x installed (provides GUI executable)
- Windows operating system
- Required packages:
ras-commander,rasterio,matplotlib,pywin32
# =============================================================================
# DEVELOPMENT MODE TOGGLE
# =============================================================================
USE_LOCAL_SOURCE = True # <-- Set to True to use local ras-commander source
if USE_LOCAL_SOURCE:
import sys
from pathlib import Path
local_path = str(Path.cwd().parent)
if local_path not in sys.path:
sys.path.insert(0, local_path)
print(f"LOCAL SOURCE MODE: Loading from {local_path}/ras_commander")
else:
print("PIP PACKAGE MODE: Loading installed ras-commander")
from ras_commander import RasCmdr, RasExamples, RasMap, init_ras_project, ras
import rasterio
from rasterio.plot import show
import matplotlib.pyplot as plt
from pathlib import Path
import ras_commander
print(f"Loaded: {ras_commander.__file__}")
LOCAL SOURCE MODE: Loading from <workspace>/ras_commander
Loaded: <workspace>\ras_commander\__init__.py
Parameters¶
# =============================================================================
# PARAMETERS
# =============================================================================
PROJECT_NAME = "BaldEagleCrkMulti2D"
RAS_VERSION = "7.0"
PLAN = "06" # Dam break plan
print(f"Project: {PROJECT_NAME}, Plan: {PLAN}")
Project: BaldEagleCrkMulti2D, Plan: 06
Step 1: Extract Example Project and Initialize¶
project_path = RasExamples.extract_project(PROJECT_NAME, suffix="600")
init_ras_project(project_path, RAS_VERSION)
print(f"Project: {ras.project_name}")
print(f"Folder: {ras.project_folder}")
print(f"\nPlans:")
print(ras.plan_df[['plan_number', 'Plan Title']].to_string())
2026-06-11 17:03:52 - ras_commander.RasExamples - INFO - Successfully extracted project 'BaldEagleCrkMulti2D' to <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 7.0 at <hec_ras_install>\7.0\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.7 Beta 5 at <hec_ras_install>\6.7 Beta 5\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.6 at <hec_ras_install>\6.6\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.5 at <hec_ras_install>\6.5\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.4.1 at <hec_ras_install>\6.4.1\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.3.1 at <hec_ras_install>\6.3.1\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.3 at <hec_ras_install>\6.3\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.2 at <hec_ras_install>\6.2\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.1 at <hec_ras_install>\6.1\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.0 at <hec_ras_install>\6.0\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0.7 at <hec_ras_install>\5.0.7\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0.6 at <hec_ras_install>\5.0.6\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0.3 at <hec_ras_install>\5.0.3\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 4.1.0 at <hec_ras_install>\4.1.0\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 4.0 at <hec_ras_install>\4.0\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.7 Beta 4a at <hec_ras_install>\6.7 Beta 4a\Ras.exe via filesystem (x86)
2026-06-11 17:03:52 - ras_commander.RasUtils - INFO - Discovered 16 installed HEC-RAS version(s)
2026-06-11 17:03:52 - ras_commander.RasPrj - INFO - HEC-RAS 7.0 found via version discovery: <hec_ras_install>\7.0\Ras.exe
2026-06-11 17:03:53 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.rasmap
2026-06-11 17:03:53 - ras_commander.RasPrj - INFO - ras-commander v0.98.0 | An open-source project of CLB Engineering Corporation (https://clbengineering.com/) | Docs: https://rascommander.info | GitHub: https://github.com/gpt-cmdr/ras-commander
2026-06-11 17:03:53 - ras_commander.RasPrj - INFO - Project initialized: BaldEagleDamBrk | Folder: <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600
2026-06-11 17:03:53 - ras_commander.RasPrj - INFO - Using HEC-RAS executable: <hec_ras_install>\7.0\Ras.exe
2026-06-11 17:03:53 - ras_commander.RasPrj - INFO -
═══════════════════════════════════════════════════════════════════════
ras-commander | HEC-RAS Automation Library
Docs: https://rascommander.info/
Repo: https://github.com/gpt-cmdr/ras-commander
═══════════════════════════════════════════════════════════════════════
PROJECT DATAFRAMES (single source of truth — use these, not file globbing):
ras.plan_df Plans, HDF paths, geometry/flow associations
ras.geom_df Geometry files and HDF preprocessor paths
ras.flow_df Steady flow files
ras.unsteady_df Unsteady flow files and configurations
ras.boundaries_df Boundary conditions (type, name, location)
ras.results_df Lightweight HDF results summaries
ras.rasmap_df RASMapper layers, terrain, land cover paths
KEY APIS (static classes — call directly, never instantiate):
Execution: RasCmdr.compute_plan() / compute_parallel() / compute_test_mode()
Plan Files: RasPlan.clone_plan() / clone_geom() / set_geom()
Unsteady: RasUnsteady — IC/BC management, gate openings, precipitation
Geometry: GeomCrossSection, GeomBridge, GeomStorage, GeomLateral, GeomMesh
HDF Results: HdfResultsPlan.get_wse() / get_compute_messages()
HdfResultsMesh.get_mesh_max_ws() / get_mesh_cells_timeseries()
HdfMesh.get_mesh_cell_points()
QA/QC: RasCheck.run_check() / RasFixit (geometry repair)
DSS: RasDss.get_timeseries() / check_pathname()
USGS: UsgsGaugeSpatial, GaugeMatcher, RasUsgsBoundaryGeneration
Precipitation: StormGenerator, Atlas14Storm, PrecipAorc, Atlas14Variance
Terrain: RasTerrain.create_terrain_hdf() / RasTerrainMod
MULTI-PROJECT: Pass ras_object= to all API calls when using local RasPrj instances.
EXAMPLES: 100+ notebooks in examples/ (100s=execution, 200s=geometry, 300s=unsteady,
400s=HDF results, 500s=remote, 800s=QA/QC, 900s=data integration).
Review relevant notebooks before assembling new workflows.
PLATFORM: Most HEC-RAS operations require Windows. Linux/Wine support for
headless execution, data access, geometry modification, and preprocessing
is available via RasProcess (HEC-RAS 6.6+). See ras_commander/RasProcess.py.
Remote distributed execution: ras_commander/remote/ (PsExec, Docker, SSH, cloud).
═══════════════════════════════════════════════════════════════════════
Project: BaldEagleDamBrk
Folder: <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600
Plans:
plan_number Plan Title
0 13 PMF with Multi 2D Areas
1 15 1d-2D Dambreak Refined Grid
2 17 2D to 1D No Dam
3 18 2D to 2D Run
4 19 SA to 2D Dam Break Run
5 03 Single 2D Area - Internal Dam Structure
6 04 SA to 2D Area Conn - 2D Levee Structure
7 02 SA to Detailed 2D Breach
8 01 SA to Detailed 2D Breach FEQ
9 05 Single 2D area with Bridges FEQ
10 06 Gridded Precip - Infiltration
Step 2: Compute Plan (if needed)¶
GUI automation generates stored maps from existing HDF results. The plan must be computed first.
hdf_path = ras.project_folder / f"{ras.project_name}.p{PLAN}.hdf"
if not hdf_path.exists():
print(f"Computing plan {PLAN}...")
RasCmdr.compute_plan(PLAN, num_cores=2)
print(f"Plan {PLAN} complete.")
else:
print(f"Plan {PLAN} already computed ({hdf_path.stat().st_size / (1024*1024):.1f} MB)")
2026-06-11 17:03:53 - ras_commander.RasCmdr - INFO - Using ras_object with project folder: <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600
2026-06-11 17:03:53 - ras_commander.RasUtils - INFO - Successfully updated file: <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.p06
Computing plan 06...
2026-06-11 17:03:53 - ras_commander.RasCmdr - INFO - Set number of cores to 2 for plan: 06
2026-06-11 17:03:53 - ras_commander.RasCmdr - INFO - Running HEC-RAS from the Command Line:
2026-06-11 17:03:53 - ras_commander.RasCmdr - INFO - Running command: "<hec_ras_install>\7.0\Ras.exe" -c "<workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.prj" "<workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.p06"
2026-06-11 17:03:53 - ras_commander.RasDialogWatchdog - INFO - DialogWatchdog started — polling every 1.5s for RAS dialog windows
2026-06-11 17:22:46 - ras_commander.RasCmdr - INFO - HEC-RAS execution completed for plan: 06
2026-06-11 17:22:46 - ras_commander.RasCmdr - INFO - Total run time for plan 06: 1132.87 seconds
2026-06-11 17:22:46 - ras_commander.RasDialogWatchdog - INFO - DialogWatchdog stopped — no dialogs encountered
Plan 06 complete.
Step 3: Generate Maps via GUI Automation¶
One function call handles everything:
- Configures .rasmap with stored map layers
- Sets plan flags to mapping-only (skips re-running the simulation)
- Opens HEC-RAS, clicks Compute, monitors HDF for completion
- Auto-closes HEC-RAS when maps are generated
- Restores original plan and .rasmap files
# Get available terrains
rasmap_path = ras.project_folder / f"{ras.project_name}.rasmap"
terrains = RasMap.get_terrain_names(rasmap_path)
print(f"Available terrains: {terrains}")
# Generate stored maps — HEC-RAS will open and auto-close
success = RasMap.postprocess_stored_maps(
plan_number=PLAN,
specify_terrain=terrains[0] if terrains else None,
layers=['Depth', 'WSEL']
)
if success:
print("\nSuccessfully generated stored maps via GUI automation")
else:
print("\nFailed to generate stored maps")
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Extracted terrain names: ['Terrain50']
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Checking .rasmap compatibility...
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - .rasmap file is already compatible (version 2.0.0)
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - .rasmap compatibility check passed: Already compatible (version 2.0.0)
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Backing up plan file <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.p06 to <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.p06.storedmap.bak
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Updating plan run flags for floodplain mapping for plan 06...
2026-06-11 17:22:46 - ras_commander.RasPlan - INFO - Successfully updated run flags in plan file: <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.p06 (flags modified: 4)
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Backing up rasmap file <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.rasmap to <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.rasmap.storedmap.bak
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Created new RASResults layer 'Gridded Precip - Infiltration' for plan 06 (none existed in .rasmap)
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Added 'Depth' stored map to results layer for plan 06.
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Added 'WSE' stored map to results layer for plan 06.
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Filtered terrains, keeping only 'Terrain50'.
2026-06-11 17:22:46 - ras_commander.RasMap - INFO - Using GUI automation to run floodplain mapping...
2026-06-11 17:22:46 - ras_commander.gui.workflows.open_compute - INFO - Setting current plan to 06 in project file...
2026-06-11 17:22:46 - ras_commander.RasPrj - INFO - Set current plan to p06 in <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.prj
2026-06-11 17:22:46 - ras_commander.gui.workflows.open_compute - INFO - Current plan set to 06 in <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.prj
2026-06-11 17:22:46 - ras_commander.gui.hecras_elements - INFO - Opening HEC-RAS...
2026-06-11 17:22:46 - ras_commander.gui.hecras_elements - INFO - HEC-RAS opened with Process ID: 9104
Available terrains: ['Terrain50']
2026-06-11 17:22:50 - ras_commander.gui.hecras_elements - INFO - Waiting for HEC-RAS main window...
2026-06-11 17:22:52 - ras_commander.gui.hecras_elements - INFO - Found HEC-RAS main window: HEC-RAS 7.0
2026-06-11 17:22:53 - ras_commander.gui.workflows.open_compute - INFO - Clicking 'Run > Unsteady Flow Analysis' menu...
2026-06-11 17:22:54 - ras_commander.gui.win32_primitives - INFO - Clicked menu item ID: 47
2026-06-11 17:22:56 - ras_commander.gui.workflows.open_compute - INFO - Looking for Unsteady Flow Analysis dialog...
2026-06-11 17:22:56 - ras_commander.gui.workflows.open_compute - INFO - Found dialog matching 'Unsteady Flow Analysis'
2026-06-11 17:22:56 - ras_commander.gui.workflows.open_compute - INFO - Found dialog window: 'Unsteady Flow Analysis'
2026-06-11 17:22:56 - ras_commander.gui.workflows.open_compute - INFO - Looking for Compute button...
2026-06-11 17:22:56 - ras_commander.gui.workflows.open_compute - WARNING - Could not find Compute button - trying keyboard shortcut...
2026-06-11 17:22:56 - ras_commander.gui.workflows.open_compute - INFO - Sent Enter key via win32api
2026-06-11 17:22:57 - ras_commander.gui.workflows.open_compute - INFO - Polling HDF for completion signal: BaldEagleDamBrk.p06.hdf
2026-06-11 17:23:09 - ras_commander.gui.workflows.open_compute - INFO - Detected 'Complete Process' in HDF — computation complete
2026-06-11 17:23:09 - ras_commander.gui.workflows.open_compute - INFO - Closing HEC-RAS...
2026-06-11 17:23:09 - ras_commander.gui.workflows.open_compute - INFO - HEC-RAS closed automatically after computation
2026-06-11 17:23:09 - ras_commander.RasMap - INFO - Floodplain mapping computation successful.
2026-06-11 17:23:09 - ras_commander.RasMap - INFO - Restoring original plan file from <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.p06.storedmap.bak
2026-06-11 17:23:09 - ras_commander.RasMap - INFO - Restoring original rasmap file from <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\BaldEagleDamBrk.rasmap.storedmap.bak
Successfully generated stored maps via GUI automation
Step 4: Verify Output Files¶
# Find the output directory using Short Identifier from plan_df
plan_info = ras.plan_df[ras.plan_df['plan_number'] == PLAN].iloc[0]
short_id = plan_info.get('Short Identifier', f'Plan_{PLAN}')
output_folder = ras.project_folder / short_id
print(f"Output folder: {output_folder}")
if output_folder.exists():
tif_files = sorted(output_folder.glob('*.tif'))
vrt_files = sorted(output_folder.glob('*.vrt'))
print(f"\nGenerated files:")
for f in tif_files + vrt_files:
print(f" {f.name} ({f.stat().st_size / 1024:.1f} KB)")
else:
print("Output folder not found — maps were not generated")
Output folder: <workspace>\examples\example_projects\BaldEagleCrkMulti2D_600\Grid Precip Infiltration
Generated files:
Depth (Max).Terrain50.dtm_20ft.tif (4952.5 KB)
WSE (Max).Terrain50.dtm_20ft.tif (3546.9 KB)
Depth (Max).vrt (3.3 KB)
WSE (Max).vrt (3.0 KB)
Step 5: Visualize Results¶
# Find depth and WSE TIF files
depth_tifs = sorted(output_folder.glob('Depth*.tif')) if output_folder.exists() else []
wse_tifs = sorted(output_folder.glob('WSE*.tif')) if output_folder.exists() else []
if depth_tifs:
fig, axes = plt.subplots(1, 2, figsize=(16, 8))
# Plot depth raster
with rasterio.open(depth_tifs[0]) as src:
show(src, ax=axes[0], cmap='Blues')
axes[0].set_title(f'Max Depth - Plan {PLAN}')
axes[0].set_xlabel('Easting')
axes[0].set_ylabel('Northing')
print(f"Depth raster: {src.width}x{src.height}, CRS: {src.crs}")
# Plot WSE raster
if wse_tifs:
with rasterio.open(wse_tifs[0]) as src:
show(src, ax=axes[1], cmap='terrain')
axes[1].set_title(f'Max WSE - Plan {PLAN}')
axes[1].set_xlabel('Easting')
axes[1].set_ylabel('Northing')
print(f"WSE raster: {src.width}x{src.height}, CRS: {src.crs}")
plt.tight_layout()
plt.show()
else:
print("No depth rasters found for visualization")
Depth raster: 6705x4852, CRS: EPSG:2271
WSE raster: 6705x4852, CRS: EPSG:2271

Technical Notes¶
Completion Detection¶
The GUI automation detects when floodplain mapping is complete by polling the plan HDF file:
1. Records the HDF modification time before launching HEC-RAS
2. After clicking Compute, polls every 2 seconds
3. When the HDF is modified AND contains "Complete Process" in compute messages, mapping is done
4. HEC-RAS is terminated automatically and backup files are restored
RASResults Layer Creation¶
Some example projects have an empty <Results /> section in their .rasmap file (no RASResults layers). The function automatically creates the required <Layer Type="RASResults"> XML element when one doesn't exist, referencing the plan's HDF file.
When to Use GUI vs RasProcess¶
- GUI Automation (this notebook): Useful when you need to debug mapping issues or verify output visually in RASMapper. The HEC-RAS window is visible during computation.
- RasProcess CLI (notebook 601): Faster, headless, recommended for production and batch workflows. No GUI window opens.