Plan and Geometry Operations¶
RAS Commander: Plan and Geometry Operations¶
This notebook demonstrates how to perform operations on HEC-RAS plan and geometry files using the RAS Commander library. We'll explore how to initialize projects, clone plans and geometries, configure parameters, execute plans, and analyze results.
Operations Covered¶
- Project Initialization: Initialize a HEC-RAS project by specifying the project path and version
- Plan Operations:
- Clone an existing plan to create a new one
- Configure simulation parameters and intervals
- Set run flags and update descriptions
- Geometry Operations:
- Clone a geometry file to create a modified version
- Set the geometry for a plan
- Clear geometry preprocessor files to ensure clean results
- Flow Operations:
- Clone unsteady flow files
- Configure flow parameters
- Plan Computation: Run the plan with specified settings
- Results Verification: Check HDF entries to confirm results were written
Package Installation and Environment Setup¶
Uncomment and run package installation commands if needed
# 1. Install ras-commander from pip (uncomment to install if needed)
#!pip install ras-commander
# This installs ras-commander and all dependencies
# =============================================================================
# DEVELOPMENT MODE TOGGLE
# =============================================================================
USE_LOCAL_SOURCE = False # <-- TOGGLE THIS
# Import Path (needed for both modes)
from pathlib import Path
import sys
if USE_LOCAL_SOURCE:
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")
# Import ras-commander
from ras_commander import HdfResultsPlan, RasCmdr, RasExamples, RasGeo, RasPlan, init_ras_project, ras
# Additional imports
import os
import pandas as pd
from IPython import display
from datetime import datetime
# Verify which version loaded
import ras_commander
print(f"✓ Loaded: {ras_commander.__file__}")
📦 PIP PACKAGE MODE: Loading installed ras-commander
2026-06-11 15:42:53 - numexpr.utils - INFO - NumExpr defaulting to 8 threads.
✓ Loaded: <repo>\ras_commander\__init__.py
Prerequisites¶
Before running this notebook, ensure you have:
- ras-commander installed:
pip install ras-commander - Python 3.10+: Check with
python --version - HEC-RAS 6.3+: Required for plan computation
- Disk Space: ~1 GB (example project + cloned files)
What You'll Learn¶
This notebook demonstrates plan and geometry manipulation - essential skills for automating HEC-RAS workflows:
- Cloning Plans: Create plan variants for sensitivity analysis
- Cloning Geometries: Duplicate geometry files for modifications
- File Associations: Link plans to specific geometry/flow files
- Parameter Updates: Modify simulation dates, intervals, and runtime flags
- Computation Control: Set number of cores and clear preprocessed data
Related Notebooks¶
- 101_project_initialization.ipynb - Project setup fundamentals
- 104_plan_parameter_operations.ipynb - Detailed parameter editing
- 110_single_plan_execution.ipynb - Execute configured plans
Key Concept: Plan-Geometry Relationships¶
HEC-RAS plans reference specific geometry and flow files. When cloning: - Plans (.p##): Simulation configuration (runtime flags, dates, output options) - Geometries (.g##): Channel cross sections, 2D mesh, structures - Flow Files (.f##, .u##): Boundary conditions and hydrographs
Pattern: Clone plan → Clone geometry → Associate cloned geometry with cloned plan → Modify parameters → Execute
Parameters¶
Configure these values to customize the notebook for your project.
# =============================================================================
# PARAMETERS - Edit these to customize the notebook
# =============================================================================
from pathlib import Path
# Project Configuration
PROJECT_NAME = "Muncie" # Example project to extract
RAS_VERSION = "7.0" # HEC-RAS version (6.3, 6.5, 6.6, etc.)
# Extract specific projects we'll use in this tutorial
# This will download them if not present and extract them to the example_projects folder
bald_eagle_path = RasExamples.extract_project("Balde Eagle Creek", suffix="103")
print(bald_eagle_path)
2026-06-11 15:42:54 - ras_commander.RasExamples - INFO - Successfully extracted project 'Balde Eagle Creek' to <repo>\examples\example_projects\Balde Eagle Creek_103
<repo>\examples\example_projects\Balde Eagle Creek_103
Project Initialization¶
The first step is to initialize the HEC-RAS project. This is done using the init_ras_project() function, which takes the project folder path and HEC-RAS version as parameters.
init_ras_project(bald_eagle_path, RAS_VERSION)
print(f"Initialized HEC-RAS project: {ras.project_name}")
# Display the current plan files in the project
print("\nHEC-RAS Project Plan Data (plan_df):")
display.display(ras.plan_df)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 7.0 at C:\Program Files (x86)\HEC\HEC-RAS\7.0\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.7 Beta 5 at C:\Program Files (x86)\HEC\HEC-RAS\6.7 Beta 5\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.7 Beta 4 at C:\Program Files (x86)\HEC\HEC-RAS\6.7 Beta 4\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.6 at C:\Program Files (x86)\HEC\HEC-RAS\6.6\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.5 at C:\Program Files (x86)\HEC\HEC-RAS\6.5\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.4.1 at C:\Program Files (x86)\HEC\HEC-RAS\6.4.1\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.3.1 at C:\Program Files (x86)\HEC\HEC-RAS\6.3.1\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.3 at C:\Program Files (x86)\HEC\HEC-RAS\6.3\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.2 at C:\Program Files (x86)\HEC\HEC-RAS\6.2\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.1 at C:\Program Files (x86)\HEC\HEC-RAS\6.1\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 6.0 at C:\Program Files (x86)\HEC\HEC-RAS\6.0\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0.7 at C:\Program Files (x86)\HEC\HEC-RAS\5.0.7\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0.6 at C:\Program Files (x86)\HEC\HEC-RAS\5.0.6\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0.5 at C:\Program Files (x86)\HEC\HEC-RAS\5.0.5\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0.4 at C:\Program Files (x86)\HEC\HEC-RAS\5.0.4\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0.3 at C:\Program Files (x86)\HEC\HEC-RAS\5.0.3\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0.1 at C:\Program Files (x86)\HEC\HEC-RAS\5.0.1\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 5.0 at C:\Program Files (x86)\HEC\HEC-RAS\5.0\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 4.1.0 at C:\Program Files (x86)\HEC\HEC-RAS\4.1.0\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered HEC-RAS 4.0 at C:\Program Files (x86)\HEC\HEC-RAS\4.0\Ras.exe via filesystem (x86)
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Discovered 20 installed HEC-RAS version(s)
2026-06-11 15:42:54 - ras_commander.RasPrj - INFO - HEC-RAS 7.0 found via version discovery: C:\Program Files (x86)\HEC\HEC-RAS\7.0\Ras.exe
2026-06-11 15:42:54 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-06-11 15:42:54 - ras_commander.RasPrj - WARNING - Could not resolve project CRS for <repo>\examples\example_projects\Balde Eagle Creek_103
2026-06-11 15:42:54 - 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 15:42:54 - ras_commander.RasPrj - INFO - Project initialized: BaldEagle | Folder: <repo>\examples\example_projects\Balde Eagle Creek_103
2026-06-11 15:42:54 - ras_commander.RasPrj - INFO - Using HEC-RAS executable: C:\Program Files (x86)\HEC\HEC-RAS\7.0\Ras.exe
2026-06-11 15:42:54 - 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).
═══════════════════════════════════════════════════════════════════════
Initialized HEC-RAS project: BaldEagle
HEC-RAS Project Plan Data (plan_df):
| plan_number | unsteady_number | geometry_number | Plan Title | Program Version | Short Identifier | Simulation Date | Computation Interval | Mapping Interval | Run HTab | ... | PS Cores | DSS File | Friction Slope Method | HDF_Results_Path | Geom File | Geom Path | Flow File | Flow Path | full_path | flow_type | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 01 | 02 | 01 | Unsteady with Bridges and Dam | 5.00 | UnsteadyFlow | 18FEB1999,0000,24FEB1999,0500 | 2MIN | 1HOUR | 1 | ... | None | dss | 2 | None | 01 | 02 | Unsteady | |||
| 1 | 02 | NaN | 01 | Steady Flow Run | NaN | SteadyRun | 02/18/1999,0000,02/24/1999,0500 | 2MIN | NaN | 1 | ... | None | dss | 1 | None | 01 | 02 | Steady |
2 rows × 32 columns
Understanding Plan and Geometry Operations in HEC-RAS¶
Before diving into the operations, let's understand what plan and geometry files are in HEC-RAS:
- Plan Files (
.p*): Define the simulation parameters including the reference to geometry and flow files, as well as computational settings. - Geometry Files (
.g*): Define the physical characteristics of the river/channel system including cross-sections, 2D areas, and structures.
The RasPlan and RasGeo classes provide methods for working with these files, including:
- Creating new plans and geometries by cloning existing ones
- Modifying simulation parameters and settings
- Associating geometries with plans
- Managing preprocessor files
- Retrieving information from plans and geometries
In the following sections, we'll explore these operations in detail.
Cloning Plans and Geometries¶
Let's start by cloning a plan to create a new simulation scenario.
# Clone plan "01" to create a new plan
new_plan_number = RasPlan.clone_plan("1", new_shortid="Combined Test Plan")
print(f"New plan created: {new_plan_number}")
# Display updated plan files
print("\nUpdated plan files:")
display.display(ras.plan_df)
# Get the path to the new plan file
plan_path = RasPlan.get_plan_path(new_plan_number)
print(f"\nNew plan file path: {plan_path}")
# Let's examine the new plan's details
new_plan = ras.plan_df[ras.plan_df['plan_number'] == new_plan_number].iloc[0]
print(f"\nNew plan details:")
print(f"Plan number: {new_plan_number}")
print(f"Description: {new_plan.get('description', 'No description')}")
print(f"Short Identifier: {new_plan.get('Short Identifier', 'Not available')}")
print(f"Geometry file: {new_plan.get('Geom File', 'None')}")
print(f"File path: {new_plan['full_path']}")
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - File cloned from <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p01 to <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Successfully updated file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-06-11 15:42:54 - ras_commander.RasUtils - INFO - Project file updated with new Plan entry: 03
2026-06-11 15:42:55 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-06-11 15:42:55 - ras_commander.RasPrj - WARNING - Could not resolve project CRS for <repo>\examples\example_projects\Balde Eagle Creek_103
New plan created: 03
Updated plan files:
| plan_number | unsteady_number | geometry_number | Plan Title | Program Version | Short Identifier | Simulation Date | Computation Interval | Mapping Interval | Run HTab | ... | UNET D2 Cores | PS Cores | DSS File | Friction Slope Method | HDF_Results_Path | Geom File | Geom Path | Flow File | Flow Path | full_path | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 01 | 02 | 01 | Unsteady with Bridges and Dam | 5.00 | UnsteadyFlow | 18FEB1999,0000,24FEB1999,0500 | 2MIN | 1HOUR | 1 | ... | 0.0 | None | dss | 2 | None | 01 | 02 | |||
| 1 | 02 | NaN | 01 | Steady Flow Run | NaN | SteadyRun | 02/18/1999,0000,02/24/1999,0500 | 2MIN | NaN | 1 | ... | NaN | None | dss | 1 | None | 01 | 02 | |||
| 2 | 03 | 02 | 01 | Unsteady with Bridges and Dam | 5.00 | Combined Test Plan | 18FEB1999,0000,24FEB1999,0500 | 2MIN | 1HOUR | 1 | ... | 0.0 | None | dss | 2 | None | 01 | 02 |
3 rows × 31 columns
New plan file path: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
New plan details:
Plan number: 03
Description: No description
Short Identifier: Combined Test Plan
Geometry file: 01
File path: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
Verification: Plan Cloning¶
Success Criteria:
- New plan file created in project folder (check ras.plan_df)
- Cloned plan has unique plan number
- Original plan unchanged
Visual Inspection:
# Verify plan was cloned
print(f"Original plans: {ras.plan_df['plan_number'].tolist()}")
# Should show new plan number (e.g., ["01", "02", "03", "new_number"])
# Open project in HEC-RAS GUI
# Verify new plan appears in plan list with correct title
Audit Trail:
# Document cloning operation
import json
audit = {
'operation': 'clone_plan',
'source_plan': "01",
'new_plan': new_plan_number,
'new_title': current_title
}
with open(project_folder / 'clone_audit.json', 'w') as f:
json.dump(audit, f, indent=2)
Why Clone Plans?¶
Use Cases: 1. Sensitivity Analysis: Test different parameters without modifying original 2. Scenario Planning: Compare mitigation alternatives (baseline vs proposed) 3. Batch Processing: Create multiple plan variants programmatically
# Get the current plan title and shortid
current_title = RasPlan.get_plan_title(new_plan_number)
current_shortid = RasPlan.get_shortid(new_plan_number)
print(f"Current plan title: {current_title}")
print(f"Current plan shortid: {current_shortid}")
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Retrieved Plan Title: Unsteady with Bridges and Dam
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Retrieved Short Identifier: Combined Test Plan
Current plan title: Unsteady with Bridges and Dam
Current plan shortid: Combined Test Plan
# Update the title and shortid to append " clonedplan"
new_title = f"{current_title} clonedplan"
new_shortid = f"{current_shortid} clonedplan"
RasPlan.set_plan_title(new_plan_number, new_title)
RasPlan.set_shortid(new_plan_number, new_shortid)
print(f"\nUpdated plan title: {RasPlan.get_plan_title(new_plan_number)}")
print(f"Updated plan shortid: {RasPlan.get_shortid(new_plan_number)}")
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Updated Plan Title in plan file to: Unsteady with Bridges and Dam clonedplan
2026-06-11 15:42:55 - ras_commander.RasPlan - WARNING - Short Identifier too long (24 char max). Truncating: Combined Test Plan clonedplan
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Updated Short Identifier in plan file to: Combined Test Plan clone
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Retrieved Plan Title: Unsteady with Bridges and Dam clonedplan
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Retrieved Short Identifier: Combined Test Plan clone
Updated plan title: Unsteady with Bridges and Dam clonedplan
Updated plan shortid: Combined Test Plan clone
# Get the current plan title and shortid again to confirm the changes
current_title = RasPlan.get_plan_title(new_plan_number)
current_shortid = RasPlan.get_shortid(new_plan_number)
print(f"Current plan title: {current_title}")
print(f"Current plan shortid: {current_shortid}")
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Retrieved Plan Title: Unsteady with Bridges and Dam clonedplan
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Retrieved Short Identifier: Combined Test Plan clone
Current plan title: Unsteady with Bridges and Dam clonedplan
Current plan shortid: Combined Test Plan clone
Now let's clone a geometry file. This allows us to make modifications to a geometry without affecting the original.
# Clone geometry "01" to create a new geometry file
new_geom_number = RasPlan.clone_geom("01")
print(f"New geometry created: {new_geom_number}")
# Display updated geometry files
print("\nUpdated geometry files:")
display.display(ras.geom_df)
# Get the path to the new geometry file
geom_path = RasPlan.get_geom_path(new_geom_number)
print(f"\nNew geometry file path: {geom_path}")
# Examine the new geometry's details
new_geom = ras.geom_df.loc[ras.geom_df['geom_number'] == new_geom_number].squeeze()
print(f"\nNew geometry details:")
print(f"Geometry number: {new_geom_number}")
print(f"Geometry file: {new_geom.get('geom_file', 'Not available')}")
print(f"File path: {new_geom.get('full_path', 'Not available')}")
print(f"HDF path: {new_geom.get('hdf_path', 'None')}")
2026-06-11 15:42:55 - ras_commander.RasUtils - INFO - File cloned from <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g01 to <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g02
2026-06-11 15:42:55 - ras_commander.RasUtils - INFO - File cloned from <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g01.hdf to <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g02.hdf
2026-06-11 15:42:55 - ras_commander.RasUtils - INFO - Project file updated with new Geom entry: 02
2026-06-11 15:42:55 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-06-11 15:42:55 - ras_commander.RasPrj - WARNING - Could not resolve project CRS for <repo>\examples\example_projects\Balde Eagle Creek_103
New geometry created: 02
Updated geometry files:
| geom_file | geom_number | full_path | hdf_path | has_1d_xs | has_2d_mesh | num_cross_sections | num_inline_structures | num_bridges | num_culverts | num_weirs | num_gates | num_lateral_structures | num_sa_2d_connections | mesh_cell_count | mesh_area_names | geom_title | description | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | g01 | 01 | True | False | 178 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | [] | Existing Conditions - GIS Data | Foster Joseph Sayers Dam and Reservoir | ||
| 1 | g02 | 02 | True | False | 178 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | [] | Existing Conditions - GIS Data | Foster Joseph Sayers Dam and Reservoir |
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Found geometry path: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g02
New geometry file path: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g02
New geometry details:
Geometry number: 02
Geometry file: Not available
File path: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g02
HDF path: None
Let's also clone an unsteady flow file to complete our new simulation setup.
# Clone unsteady flow "02" to create a new unsteady flow file
new_unsteady_number = RasPlan.clone_unsteady("02")
print(f"New unsteady flow created: {new_unsteady_number}")
# Display updated unsteady flow files
print("\nUpdated unsteady flow files:")
display.display(ras.unsteady_df)
# Examine the new unsteady flow's details
new_unsteady = ras.unsteady_df[ras.unsteady_df['unsteady_number'] == new_unsteady_number].iloc[0]
print(f"\nNew unsteady flow details:")
print(f"Unsteady number: {new_unsteady_number}")
print(f"File path: {new_unsteady['full_path']}")
print(f"Flow Title: {new_unsteady.get('Flow Title', 'Not available')}")
2026-06-11 15:42:55 - ras_commander.RasUtils - INFO - File cloned from <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.u02 to <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.u01
2026-06-11 15:42:55 - ras_commander.RasUtils - INFO - Project file updated with new Unsteady entry: 01
2026-06-11 15:42:55 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-06-11 15:42:55 - ras_commander.RasPrj - WARNING - Could not resolve project CRS for <repo>\examples\example_projects\Balde Eagle Creek_103
New unsteady flow created: 01
Updated unsteady flow files:
| unsteady_number | full_path | Flow Title | Program Version | Use Restart | Precipitation Mode | Wind Mode | Met BC=Precipitation|Mode | Met BC=Evapotranspiration|Mode | Met BC=Precipitation|Expanded View | Met BC=Precipitation|Constant Units | Met BC=Precipitation|Gridded Source | description | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 02 | Flow Hydrograph 2 | 6.30 | 0 | Disable | No Wind Forces | None | None | 0 | mm/hr | DSS | ||
| 1 | 01 | Flow Hydrograph 2 | 6.30 | 0 | Disable | No Wind Forces | None | None | 0 | mm/hr | DSS |
New unsteady flow details:
Unsteady number: 01
File path: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.u01
Flow Title: Flow Hydrograph 2
Associating Files and Setting Parameters¶
Now that we have cloned our plan, geometry, and unsteady flow files, we need to associate them with each other and set various parameters.
Setting Geometry for a Plan¶
Let's associate our new geometry with our new plan:
# Set the new geometry for the cloned plan
updated_geom_df = RasPlan.set_geom(new_plan_number, new_geom_number)
plan_path = RasPlan.get_plan_path(new_plan_number, ras_object=ras)
print(f"Updated geometry for plan {new_plan_number} to geometry {new_geom_number}")
print(f"Plan file path: {plan_path}")
# Let's verify the change
updated_plan = ras.plan_df[ras.plan_df['plan_number'] == new_plan_number].iloc[0]
print(f"\nVerified that plan {new_plan_number} now uses geometry file: {updated_plan.get('Geom File', 'None')}")
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Updated Geom File in plan file to g02 for plan 03
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Geometry for plan 03 set to 02
Updated geometry for plan 03 to geometry 02
Plan file path: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
Verified that plan 03 now uses geometry file: g02
Setting Unsteady Flow for a Plan¶
Similarly, let's associate our new unsteady flow file with our plan:
# Set unsteady flow for the cloned plan
RasPlan.set_unsteady(new_plan_number, new_unsteady_number)
print(f"Updated unsteady flow for plan {new_plan_number} to unsteady flow {new_unsteady_number}")
Updated unsteady flow for plan 03 to unsteady flow 01
Clearing Geometry Preprocessor Files¶
When working with geometry files, it's important to clear the preprocessor files to ensure clean results. These files (with .c* extension) contain computed hydraulic properties that should be recomputed when the geometry changes.
# Clear geometry preprocessor files for the cloned plan
RasGeo.clear_geompre_files(plan_path)
print(f"Cleared geometry preprocessor files for plan {new_plan_number}")
# Check if preprocessor file exists after clearing
geom_preprocessor_suffix = '.c' + ''.join(Path(plan_path).suffixes[1:])
geom_preprocessor_file = Path(plan_path).with_suffix(geom_preprocessor_suffix)
print(f"Preprocessor file exists after clearing: {geom_preprocessor_file.exists()}")
2026-06-11 15:42:55 - ras_commander.geom.GeomPreprocessor - INFO - Clearing geometry preprocessor file for single plan: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-06-11 15:42:55 - ras_commander.geom.GeomPreprocessor - WARNING - No geometry preprocessor file found for: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
Cleared geometry preprocessor files for plan 03
Preprocessor file exists after clearing: False
GeomPreprocessor: Correct .c## File Resolution¶
When clearing geometry preprocessor files, GeomPreprocessor looks up the plan's geometry_number from plan_df to target the correct .c## file. This matters when the plan number differs from the geometry number — for example, plan 03 uses geometry 02, so the preprocessor targets .c02 (not .c03).
# Show that plan 03 uses geometry 02 (not 03)
plan_row = ras.plan_df[ras.plan_df['plan_number'] == new_plan_number].iloc[0]
geom_num = plan_row['geometry_number']
print(f"Plan {new_plan_number} uses geometry {geom_num}")
print(f" -> GeomPreprocessor targets .c{geom_num} (not .c{new_plan_number})")
# Verify the correct .c## file is the one that was cleared
from pathlib import Path
project_folder = Path(plan_path).parent
project_name = ras.project_name
correct_c_file = project_folder / f"{project_name}.c{geom_num}"
wrong_c_file = project_folder / f"{project_name}.c{new_plan_number}"
print(f"\n Correct target: {correct_c_file.name} exists={correct_c_file.exists()}")
print(f" Wrong target: {wrong_c_file.name} exists={wrong_c_file.exists()}")
Plan 03 uses geometry 02
-> GeomPreprocessor targets .c02 (not .c03)
Correct target: BaldEagle.c02 exists=False
Wrong target: BaldEagle.c03 exists=False
Setting Computation Parameters¶
Let's set the computation parameters for our plan:
# Set the number of cores to use for the computation
RasPlan.set_num_cores(new_plan_number, 2)
print(f"Updated number of cores for plan {new_plan_number} to 2")
# Verify by extracting the value from the plan file
cores_value = RasPlan.get_plan_value(new_plan_number, "UNET D1 Cores")
print(f"\nVerified that UNET D1 Cores is set to: {cores_value}")
# Set geometry preprocessor options
RasPlan.set_geom_preprocessor(plan_path, run_htab=-1, use_ib_tables=-1)
print(f"Updated geometry preprocessor options for plan {new_plan_number}")
print(f"- Run HTab: -1 (Force recomputation of geometry tables)")
print(f"- Use Existing IB Tables: -1 (Force recomputation of interpolation/boundary tables)")
# Verify by extracting the values from the plan file
run_htab_value = RasPlan.get_plan_value(new_plan_number, "Run HTab")
ib_tables_value = RasPlan.get_plan_value(new_plan_number, "UNET Use Existing IB Tables")
print(f"\nVerified setting values:")
print(f"- Run HTab: {run_htab_value}")
print(f"- UNET Use Existing IB Tables: {ib_tables_value}")
2026-06-11 15:42:55 - ras_commander.RasUtils - INFO - Successfully updated file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-06-11 15:42:55 - ras_commander.RasUtils - INFO - Successfully updated file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
Updated number of cores for plan 03 to 2
Verified that UNET D1 Cores is set to: 2
Updated geometry preprocessor options for plan 03
- Run HTab: -1 (Force recomputation of geometry tables)
- Use Existing IB Tables: -1 (Force recomputation of interpolation/boundary tables)
Verified setting values:
- Run HTab: -1
- UNET Use Existing IB Tables: -1
Updating Simulation Parameters¶
Now, let's update various simulation parameters for our plan:
# 1. Update simulation date
start_date = datetime(2023, 1, 1, 0, 0) # January 1, 2023, 00:00
end_date = datetime(2023, 1, 5, 23, 59) # January 5, 2023, 23:59
RasPlan.update_simulation_date(new_plan_number, start_date, end_date)
print(f"Updated simulation date for plan {new_plan_number}:")
print(f"- Start Date: {start_date}")
print(f"- End Date: {end_date}")
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Updated simulation date in plan file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
Updated simulation date for plan 03:
- Start Date: 2023-01-01 00:00:00
- End Date: 2023-01-05 23:59:00
# Verify the update
sim_date = RasPlan.get_plan_value(new_plan_number, "Simulation Date")
print(f"Verified Simulation Date value: {sim_date}")
Verified Simulation Date value: 01JAN2023,0000,05JAN2023,2359
# 2. Update plan intervals
RasPlan.update_plan_intervals(
new_plan_number,
computation_interval="1MIN", # Computational time step
output_interval="15MIN", # How often results are written
mapping_interval="30MIN" # How often mapping outputs are created
)
print(f"\nUpdated plan intervals for plan {new_plan_number}:")
print(f"- Computation Interval: 1MIN")
print(f"- Output Interval: 15MIN")
print(f"- Mapping Interval: 30MIN")
# Verify the updates
comp_interval = RasPlan.get_plan_value(new_plan_number, "Computation Interval")
mapping_interval = RasPlan.get_plan_value(new_plan_number, "Mapping Interval")
print(f"Verified interval values:")
print(f"- Computation Interval: {comp_interval}")
print(f"- Mapping Interval: {mapping_interval}")
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Successfully updated intervals in plan file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
Updated plan intervals for plan 03:
- Computation Interval: 1MIN
- Output Interval: 15MIN
- Mapping Interval: 30MIN
Verified interval values:
- Computation Interval: 1MIN
- Mapping Interval: 30MIN
# 3. Update run flags
RasPlan.update_run_flags(
new_plan_number,
geometry_preprocessor=True, # Run the geometry preprocessor
unsteady_flow_simulation=True, # Run unsteady flow simulation
post_processor=True, # Run post-processing
floodplain_mapping=True # Generate floodplain mapping outputs
)
print(f"\nUpdated run flags for plan {new_plan_number}:")
print(f"- Geometry Preprocessor: True")
print(f"- Unsteady Flow Simulation: True")
print(f"- Post Processor: True")
print(f"- Floodplain Mapping: True")
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Successfully updated run flags in plan file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03 (flags modified: 4)
Updated run flags for plan 03:
- Geometry Preprocessor: True
- Unsteady Flow Simulation: True
- Post Processor: True
- Floodplain Mapping: True
# Verify the updates
run_htab = RasPlan.get_plan_value(new_plan_number, "Run HTab")
run_unet = RasPlan.get_plan_value(new_plan_number, "Run UNet")
print(f"Verified run flag values:")
print(f"- Run HTab (Geometry Preprocessor): {run_htab}")
print(f"- Run UNet (Unsteady Flow): {run_unet}")
# 4. Update plan description
new_description = "Combined plan with modified geometry and unsteady flow\nJanuary 2023 simulation\n1-minute computation interval\nGeometry and unsteady flow from cloned files"
RasPlan.update_plan_description(new_plan_number, new_description)
print(f"\nUpdated description for plan {new_plan_number}")
# Read back the description
current_description = RasPlan.read_plan_description(new_plan_number)
print(f"Current plan description:\n{current_description}")
2026-06-11 15:42:55 - ras_commander.RasPlan - WARNING - Unknown key: Run UNet. Valid keys are: Write IC File at Fixed DateTime, Run Sediment, Run WQNET, Write IC File Reoccurance, Description, Write IC File, Run HTab, Run Post Process, Computation Interval, UNET D1 Cores, IC Time, Plan File, Simulation Date, DSS File, PS Cores, Friction Slope Method, Mapping Interval, Short Identifier, Flow File, UNET 1D Methodology, UNET D2 Cores, Geom File, Program Version, UNET D2 Solver Type, Run RASMapper, UNET D2 Name, Plan Title, Run UNET, Write IC File at Sim End, UNET Use Existing IB Tables
Add more keys and explanations in get_plan_value() as needed.
2026-06-11 15:42:55 - ras_commander.RasPlan - INFO - Read description from plan file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
Verified run flag values:
- Run HTab (Geometry Preprocessor): -1
- Run UNet (Unsteady Flow): -1
Updated description for plan 03
Current plan description:
Combined plan with modified geometry and unsteady flow
January 2023 simulation
1-minute computation interval
Geometry and unsteady flow from cloned files
Computing the Plan¶
Now that we have set up all the parameters, let's compute the plan using RasCmdr.compute_plan():
# Compute the plan with our configured settings
# Note: This may take several minutes depending on the complexity of the model
print(f"Computing plan {new_plan_number}...")
success = RasCmdr.compute_plan(new_plan_number, clear_geompre=True)
if success:
print(f"Plan {new_plan_number} computed successfully")
else:
print(f"Failed to compute plan {new_plan_number}")
2026-06-11 15:42:55 - ras_commander.RasCmdr - INFO - Using ras_object with project folder: <repo>\examples\example_projects\Balde Eagle Creek_103
2026-06-11 15:42:55 - ras_commander.geom.GeomPreprocessor - INFO - Clearing geometry preprocessor file for single plan: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-06-11 15:42:55 - ras_commander.geom.GeomPreprocessor - WARNING - No geometry preprocessor file found for: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-06-11 15:42:55 - ras_commander.RasCmdr - INFO - Cleared geometry preprocessor files for plan: 03
Computing plan 03...
2026-06-11 15:42:55 - ras_commander.RasCmdr - INFO - Running HEC-RAS from the Command Line:
2026-06-11 15:42:55 - ras_commander.RasCmdr - INFO - Running command: "C:\Program Files (x86)\HEC\HEC-RAS\7.0\Ras.exe" -c "<repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.prj" "<repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03"
2026-06-11 15:42:55 - ras_commander.RasDialogWatchdog - INFO - DialogWatchdog started — polling every 1.5s for RAS dialog windows
2026-06-11 15:44:22 - ras_commander.RasCmdr - INFO - HEC-RAS execution completed for plan: 03
2026-06-11 15:44:22 - ras_commander.RasCmdr - INFO - Total run time for plan 03: 86.36 seconds
2026-06-11 15:44:22 - ras_commander.RasDialogWatchdog - INFO - DialogWatchdog stopped — no dialogs encountered
Plan 03 computed successfully
Verifying Results¶
After computation, we should check if results were written correctly:
# Refresh the plan entries to ensure we have the latest data
ras.plan_df = ras.get_plan_entries()
hdf_entries = ras.get_hdf_entries()
if not hdf_entries.empty:
print("HDF entries for the project:")
display.display(hdf_entries)
# Check if our new plan has an HDF file
new_plan_hdf = hdf_entries[hdf_entries['plan_number'] == new_plan_number]
if not new_plan_hdf.empty:
print(f"\nPlan {new_plan_number} has a valid HDF results file:")
print(f"HDF Path: {new_plan_hdf.iloc[0]['HDF_Results_Path']}")
else:
print(f"\nNo HDF entry found for plan {new_plan_number}")
else:
print("No HDF entries found. This could mean the plan hasn't been computed successfully or the results haven't been written yet.")
# Display all plan entries to see their HDF paths
print("\nAll plan entries with their HDF paths:")
plan_hdf_info = ras.plan_df[['plan_number', 'HDF_Results_Path']]
display.display(plan_hdf_info)
HDF entries for the project:
| plan_number | unsteady_number | geometry_number | Plan Title | Program Version | Short Identifier | Simulation Date | Computation Interval | Mapping Interval | Run HTab | ... | PS Cores | DSS File | Friction Slope Method | description | HDF_Results_Path | Geom File | Geom Path | Flow File | Flow Path | full_path | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 03 | 01 | 02 | Unsteady with Bridges and Dam clonedplan | 5.00 | Combined Test Plan clone | 01JAN2023,0000,05JAN2023,2359 | 1MIN | 30MIN | -1 | ... | None | dss | 2 | Combined plan with modified geometry and unste... | 02 | 01 |
1 rows × 32 columns
Plan 03 has a valid HDF results file:
HDF Path: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
All plan entries with their HDF paths:
| plan_number | HDF_Results_Path | |
|---|---|---|
| 0 | 01 | NaN |
| 1 | 02 | NaN |
| 2 | 03 |
If the plan was computed successfully, we can examine the runtime data and volume accounting from the HDF results:
# Get computation runtime data from HDF
print("Checking computation runtime data...")
runtime_df = HdfResultsPlan.get_runtime_data(new_plan_number)
if runtime_df is not None and not runtime_df.empty:
print("\nSimulation Runtime Statistics:")
display.display(runtime_df)
# Extract key metrics
sim_duration = runtime_df['Simulation Duration (s)'].iloc[0]
compute_time = runtime_df['Complete Process (hr)'].iloc[0]
compute_speed = runtime_df['Complete Process Speed (hr/hr)'].iloc[0]
print(f"\nSimulation Duration: {sim_duration:.2f} seconds")
print(f"Computation Time: {compute_time:.5f} hours")
print(f"Computation Speed: {compute_speed:.2f} (simulation hours/compute hours)")
else:
print("No runtime data found. This may indicate the simulation didn't complete successfully.")
# Get volume accounting data
print("\nChecking volume accounting...")
volume_df = HdfResultsPlan.get_volume_accounting(new_plan_number)
if volume_df is not None and not isinstance(volume_df, bool):
# Handle volume_df as a dictionary
if isinstance(volume_df, dict):
error_percent = volume_df.get('Error Percent')
if error_percent is not None:
print(f"\nFinal Volume Balance Error: {float(error_percent):.8f}%")
# Print other key statistics
print("\nDetailed Volume Statistics:")
print(f"Volume Starting: {float(volume_df['Volume Starting']):.2f} {volume_df['Vol Accounting in'].decode()}")
print(f"Volume Ending: {float(volume_df['Volume Ending']):.2f} {volume_df['Vol Accounting in'].decode()}")
print(f"Total Inflow: {float(volume_df['Total Boundary Flux of Water In']):.2f} {volume_df['Vol Accounting in'].decode()}")
print(f"Total Outflow: {float(volume_df['Total Boundary Flux of Water Out']):.2f} {volume_df['Vol Accounting in'].decode()}")
else:
print("No volume accounting data found. This may indicate the simulation didn't complete successfully.")
Checking computation runtime data...
Simulation Runtime Statistics:
| Plan Name | File Name | Simulation Start Time | Simulation End Time | Simulation Duration (s) | Simulation Time (hr) | Completing Geometry (hr) | Preprocessing Geometry (hr) | Completing Event Conditions (hr) | Unsteady Flow Computations (hr) | Complete Process (hr) | Unsteady Flow Speed (hr/hr) | Complete Process Speed (hr/hr) | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Unsteady with Bridges and Dam clonedplan | BaldEagle.p03.hdf | 2023-01-01 | 2023-01-05 23:59:00 | 431940.0 | 119.983333 | N/A | 0.020382 | N/A | 0.000959 | 0.023641 | 125091.225022 | 5075.138939 |
Simulation Duration: 431940.00 seconds
Computation Time: 0.02364 hours
Computation Speed: 5075.14 (simulation hours/compute hours)
Checking volume accounting...
Viewing Execution Summary with results_df¶
The results_df DataFrame shows which plans have been executed.
# Display execution summary only for the plan run in this notebook (filtered and transposed)
print("Execution Summary (for current plan):")
ras.results_df.T
Execution Summary (for current plan):
| 0 | 1 | 2 | |
|---|---|---|---|
| plan_number | 01 | 02 | 03 |
| plan_title | Unsteady with Bridges and Dam | Steady Flow Run | Unsteady with Bridges and Dam clonedplan |
| flow_type | Unsteady | Steady | Unsteady |
| hdf_path | |||
| hdf_exists | False | False | True |
| ras_version | 5.00 | NaN | 5.00 |
| completed | False | False | True |
| has_errors | False | False | False |
| has_warnings | False | False | False |
| error_count | 0 | 0 | 0 |
| warning_count | 0 | 0 | 0 |
| hdf_file_modified | NaT | NaT | 2026-06-11 15:44:21.999576 |
| runtime_simulation_start | NaT | NaT | 2023-01-01 00:00:00 |
| runtime_simulation_end | NaT | NaT | 2023-01-05 23:59:00 |
| runtime_simulation_hours | NaN | NaN | 119.983333 |
| runtime_complete_process_hours | NaN | NaN | 0.023641 |
| runtime_unsteady_compute_hours | NaN | NaN | 0.000959 |
| runtime_complete_process_speed | NaN | NaN | 5075.138939 |
| runtime_source | NaN | NaN | hdf |
| vol_error | NaN | NaN | -12.049353 |
| vol_accounting_units | NaN | NaN | Acre Feet |
| vol_error_percent | NaN | NaN | 0.005847 |
| vol_flux_in | NaN | NaN | 196776.984375 |
| vol_flux_out | NaN | NaN | 104118.132812 |
| vol_starting | NaN | NaN | 9306.797852 |
| vol_ending | NaN | NaN | 101953.601562 |
Deleting Plans, Geometries, and Flow Files¶
After working with cloned elements, you may want to clean up by deleting them. By default, all delete methods move files to a timestamped Backup/ folder instead of permanently deleting them. This provides a safety net for recovering accidentally deleted files.
The permanent deletion parameter can be used to skip the backup and permanently remove files.
# First, let's clone fresh elements to demonstrate deletion
# (Our earlier clones may have been used for computation)
demo_plan = RasPlan.clone_plan("01", new_shortid="Delete Demo Plan")
demo_geom = RasPlan.clone_geom("01")
demo_unsteady = RasPlan.clone_unsteady("02")
print(f"Created demo plan: {demo_plan}")
print(f"Created demo geometry: {demo_geom}")
print(f"Created demo unsteady: {demo_unsteady}")
print()
print(f"Plan count before deletion: {len(ras.plan_df)}")
print(f"Geometry count before deletion: {len(ras.geom_df)}")
print(f"Unsteady count before deletion: {len(ras.unsteady_df)}")
# Delete the plan (default: backs up to Backup/ folder)
RasPlan.delete_plan(demo_plan)
print()
print(f"Plan count after deleting plan {demo_plan}: {len(ras.plan_df)}")
# Delete the geometry (default: backs up .g##, .g##.hdf, .c## to Backup/)
RasPlan.delete_geom(demo_geom, force=True)
print(f"Geometry count after deleting geom {demo_geom}: {len(ras.geom_df)}")
# Delete the unsteady flow (default: backs up to Backup/)
RasPlan.delete_unsteady(demo_unsteady, force=True)
print(f"Unsteady count after deleting unsteady {demo_unsteady}: {len(ras.unsteady_df)}")
# Show the Backup folder contents
backup_dir = ras.project_folder / "Backup"
if backup_dir.exists():
print()
print("Backup folder contents:")
for folder in sorted(backup_dir.iterdir()):
print(f" {folder.name}/")
for f in sorted(folder.iterdir()):
print(f" {f.name}")
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - File cloned from <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p01 to <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p04
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - Successfully updated file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p04
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - Project file updated with new Plan entry: 04
2026-06-11 15:44:22 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-06-11 15:44:22 - ras_commander.RasPrj - WARNING - Could not resolve project CRS for <repo>\examples\example_projects\Balde Eagle Creek_103
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - File cloned from <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g01 to <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g03
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - File cloned from <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g01.hdf to <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g03.hdf
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - Project file updated with new Geom entry: 03
2026-06-11 15:44:22 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-06-11 15:44:22 - ras_commander.RasPrj - WARNING - Could not resolve project CRS for <repo>\examples\example_projects\Balde Eagle Creek_103
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - File cloned from <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.u02 to <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.u03
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - Project file updated with new Unsteady entry: 03
2026-06-11 15:44:22 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-06-11 15:44:22 - ras_commander.RasPrj - WARNING - Could not resolve project CRS for <repo>\examples\example_projects\Balde Eagle Creek_103
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - Backed up BaldEagle.p04 to <repo>\examples\example_projects\Balde Eagle Creek_103\Backup\2026-06-11_154422_deleted_p04
2026-06-11 15:44:22 - ras_commander.RasUtils - INFO - Removed Plan entry 04 from project file
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Backed up BaldEagle.g03 to <repo>\examples\example_projects\Balde Eagle Creek_103\Backup\2026-06-11_154423_deleted_g03
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Backed up BaldEagle.g03.hdf to <repo>\examples\example_projects\Balde Eagle Creek_103\Backup\2026-06-11_154423_deleted_g03
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Removed Geom entry 03 from project file
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Backed up BaldEagle.u03 to <repo>\examples\example_projects\Balde Eagle Creek_103\Backup\2026-06-11_154423_deleted_u03
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Backed up BaldEagle.u03.hdf to <repo>\examples\example_projects\Balde Eagle Creek_103\Backup\2026-06-11_154423_deleted_u03
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Removed Unsteady entry 03 from project file
Created demo plan: 04
Created demo geometry: 03
Created demo unsteady: 03
Plan count before deletion: 4
Geometry count before deletion: 3
Unsteady count before deletion: 3
Plan count after deleting plan 04: 3
Geometry count after deleting geom 03: 2
Unsteady count after deleting unsteady 03: 2
Backup folder contents:
2026-06-11_154422_deleted_p04/
BaldEagle.p04
2026-06-11_154423_deleted_g03/
BaldEagle.g03
BaldEagle.g03.hdf
2026-06-11_154423_deleted_u03/
BaldEagle.u03
BaldEagle.u03.hdf
# Demonstrate permanent deletion (no backup)
perm_plan = RasPlan.clone_plan("01", new_shortid="Perm Delete Demo")
print(f"Created plan {perm_plan} for permanent deletion demo")
# Permanently delete - files are removed, not backed up
RasPlan.delete_plan(perm_plan)
print(f"Plan {perm_plan} permanently deleted (no backup created)")
print(f"Plan count after permanent deletion: {len(ras.plan_df)}")
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - File cloned from <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p01 to <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p04
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Successfully updated file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p04
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Project file updated with new Plan entry: 04
2026-06-11 15:44:23 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: <repo>\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-06-11 15:44:23 - ras_commander.RasPrj - WARNING - Could not resolve project CRS for <repo>\examples\example_projects\Balde Eagle Creek_103
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Backed up BaldEagle.p04 to <repo>\examples\example_projects\Balde Eagle Creek_103\Backup\2026-06-11_154423_deleted_p04
2026-06-11 15:44:23 - ras_commander.RasUtils - INFO - Removed Plan entry 04 from project file
Created plan 04 for permanent deletion demo
Plan 04 permanently deleted (no backup created)
Plan count after permanent deletion: 3
HEC-RAS Plan File Structure Reference¶
Understanding plan file structure helps debug cloning operations:
Plan File (.p##) Components¶
Proj Title=My Project
Plan Title=Baseline Run
Geom File=g01 # Links to geometry file
Flow File=f01 # Links to flow file
Run HTab=0 # Hydraulic tables flag
Run Unsteady=0 # Unsteady flow flag
HEC Documentation¶
- HEC-RAS User's Manual - Chapter 3: Plan window and file management https://www.hec.usace.army.mil/software/hec-ras/documentation.aspx
- HEC-RAS User's Manual - Chapter 5: Editing parameters
LLM Forward: Reviewable Modifications¶
When modifying plans programmatically, create comparison reports:
def document_plan_changes(original_plan, modified_plan, output_file):
# Document what changed between plans
changes = []
for param in ['Run HTab', 'Run Unsteady', 'Computation Interval']:
orig_val = RasPlan.get_plan_value(original_plan, param)
new_val = RasPlan.get_plan_value(modified_plan, param)
if orig_val != new_val:
changes.append({
'parameter': param,
'original': orig_val,
'modified': new_val
})
# Export for review
import pandas as pd
df = pd.DataFrame(changes)
df.to_csv(output_file, index=False)
return df
# Usage
changes_df = document_plan_changes(
"01",
new_plan_number,
project_folder / 'plan_modifications.csv'
)
This enables: - Change tracking: Know exactly what was modified - Peer review: Non-programmers can verify changes - Reproducibility: Document modifications for future reference
Summary of Plan and Geometry Operations¶
In this notebook, we've covered a comprehensive range of operations on HEC-RAS plan and geometry files using the RAS Commander library:
- Project Initialization: We initialized a HEC-RAS project to work with
- Plan Operations:
- Created a new plan by cloning an existing one
- Updated simulation parameters (dates, intervals, etc.)
- Set run flags for different components
- Updated the plan description
- Geometry Operations:
- Created a new geometry by cloning an existing one
- Associated the new geometry with our plan
- Cleared geometry preprocessor files
- Unsteady Flow Operations:
- Created a new unsteady flow file by cloning an existing one
- Associated it with our plan
- Computation and Verification:
- Computed our plan with the specified settings
- Verified the results using HDF entries
- Analyzed runtime statistics and volume accounting
- Deletion with Backup:
- Deleted cloned plans, geometries, and unsteady files
- Files moved to timestamped Backup/ folder by default
- Used permanent deletion for irreversible deletion
Key Classes and Functions Used¶
RasPlan: For plan operations (cloning, setting components, modifying parameters, and deletion)RasGeo: For geometry operations (cloning, clearing preprocessor files)RasCmdr: For executing HEC-RAS simulations
Next Steps¶
To further enhance your HEC-RAS automation, consider exploring:
- Parameter Sweeps: Create and run multiple plans with varying parameters
- Parallel Computations: Run multiple plans simultaneously using
RasCmdr.compute_parallel() - Advanced Results Analysis: Use the HDF classes to extract and analyze specific model results
- Spatial Visualization: Create maps and plots of simulation results
- Model Calibration: Automate comparison between model results and observations
The RAS Commander library provides a powerful framework for automating and streamlining your HEC-RAS workflows, enabling more efficient hydraulic modeling and analyses.