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
✓ Loaded: c:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:09 - ras_commander.RasExamples - INFO - Found zip file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\Example_Projects_6_6.zip
2026-01-11 20:44:09 - ras_commander.RasExamples - INFO - Loading project data from CSV...
2026-01-11 20:44:09 - ras_commander.RasExamples - INFO - Loaded 68 projects from CSV.
2026-01-11 20:44:09 - ras_commander.RasExamples - INFO - ----- RasExamples Extracting Project -----
2026-01-11 20:44:09 - ras_commander.RasExamples - INFO - Extracting project 'Balde Eagle Creek' as 'Balde Eagle Creek_103'
2026-01-11 20:44:09 - ras_commander.RasExamples - INFO - Successfully extracted project 'Balde Eagle Creek' to C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103
C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:09 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-01-11 20:44:09 - ras_commander.RasPrj - INFO - Updated results_df with 2 plan(s)
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 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | 02 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | Unsteady |
| 1 | 02 | None | 01 | Steady Flow Run | NaN | SteadyRun | 02/18/1999,0000,02/24/1999,0500 | 2MIN | NaN | 1 | ... | None | dss | 1 | None | 01 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | 02 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | Steady |
2 rows × 27 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-01-11 20:44:09 - ras_commander.RasUtils - INFO - File cloned from C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p01 to C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:09 - ras_commander.RasUtils - INFO - Successfully updated file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:09 - ras_commander.RasUtils - INFO - Project file updated with new Plan entry: 03
2026-01-11 20:44:09 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-01-11 20:44:09 - ras_commander.RasPrj - INFO - Updated results_df with 3 plan(s)
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 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | 02 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... |
| 1 | 02 | None | 01 | Steady Flow Run | NaN | SteadyRun | 02/18/1999,0000,02/24/1999,0500 | 2MIN | NaN | 1 | ... | NaN | None | dss | 1 | None | 01 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | 02 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... |
| 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 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | 02 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... |
3 rows × 26 columns
New plan file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:09 - ras_commander.RasPlan - INFO - Retrieved Plan Title: Unsteady with Bridges and Dam
2026-01-11 20:44:09 - 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-01-11 20:44:09 - ras_commander.RasUtils - INFO - Constructed plan file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:09 - ras_commander.RasPlan - INFO - Updated Plan Title in plan file to: Unsteady with Bridges and Dam clonedplan
2026-01-11 20:44:09 - ras_commander.RasPlan - WARNING - Short Identifier too long (24 char max). Truncating: Combined Test Plan clonedplan
2026-01-11 20:44:09 - ras_commander.RasUtils - INFO - Constructed plan file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:09 - ras_commander.RasPlan - INFO - Updated Short Identifier in plan file to: Combined Test Plan clone
2026-01-11 20:44:09 - ras_commander.RasPlan - INFO - Retrieved Plan Title: Unsteady with Bridges and Dam clonedplan
2026-01-11 20:44:09 - 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-01-11 20:44:09 - ras_commander.RasPlan - INFO - Retrieved Plan Title: Unsteady with Bridges and Dam clonedplan
2026-01-11 20:44:09 - 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-01-11 20:44:09 - ras_commander.RasUtils - INFO - File cloned from C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g01 to C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g02
2026-01-11 20:44:10 - ras_commander.RasUtils - INFO - File cloned from C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g01.hdf to C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g02.hdf
2026-01-11 20:44:10 - ras_commander.RasUtils - INFO - Project file updated with new Geom entry: 02
New geometry created: 02
Updated geometry files:
| geom_file | geom_number | full_path | hdf_path | |
|---|---|---|---|---|
| 0 | g01 | 01 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... |
| 1 | g02 | 02 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... |
2026-01-11 20:44:10 - ras_commander.RasPlan - INFO - Found geometry path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g02
New geometry file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.g02
New geometry details:
Geometry number: 02
Geometry file: Not available
File path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:10 - ras_commander.RasUtils - INFO - File cloned from C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.u02 to C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.u01
2026-01-11 20:44:10 - ras_commander.RasUtils - INFO - Successfully updated file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.u01
2026-01-11 20:44:10 - ras_commander.RasUtils - INFO - Project file updated with new Unsteady entry: 01
2026-01-11 20:44:10 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.rasmap
2026-01-11 20:44:10 - ras_commander.RasPrj - INFO - Updated results_df with 3 plan(s)
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 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 02 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | Flow Hydrograph 2 | 6.30 | 0 | Disable | No Wind Forces | None | None | 0 | mm/hr | DSS |
| 1 | 01 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | 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: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:10 - ras_commander.RasPlan - INFO - Updated Geom File in plan file to g02 for plan 03
2026-01-11 20:44:10 - ras_commander.RasPlan - INFO - Geometry for plan 03 set to 02
Updated geometry for plan 03 to geometry 02
Plan file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:10 - ras_commander.geom.GeomPreprocessor - INFO - Clearing geometry preprocessor file for single plan: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:10 - ras_commander.geom.GeomPreprocessor - WARNING - No geometry preprocessor file found for: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:10 - ras_commander.geom.GeomPreprocessor - INFO - Geometry dataframe updated successfully.
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()}")
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-01-11 20:44:10 - ras_commander.RasUtils - INFO - Constructed plan file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:10 - ras_commander.RasUtils - INFO - Successfully updated file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:10 - ras_commander.RasUtils - INFO - Successfully updated file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:10 - ras_commander.RasPlan - INFO - Updated simulation date in plan file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:10 - ras_commander.RasPlan - INFO - Successfully updated intervals in plan file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:10 - ras_commander.RasPlan - INFO - Successfully updated run flags in plan file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\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-01-11 20:44:10 - ras_commander.RasPlan - WARNING - Unknown key: Run UNet. Valid keys are: Run RASMapper, Short Identifier, Mapping Interval, Run UNET, Description, Run WQNET, PS Cores, Simulation Date, Run Post Process, UNET D2 Solver Type, Geom File, UNET 1D Methodology, UNET Use Existing IB Tables, Plan Title, Run HTab, Program Version, Run Sediment, Flow File, DSS File, UNET D2 Cores, UNET D1 Cores, Plan File, Friction Slope Method, UNET D2 Name, Computation Interval
Add more keys and explanations in get_plan_value() as needed.
Verified run flag values:
- Run HTab (Geometry Preprocessor): -1
- Run UNet (Unsteady Flow): -1
2026-01-11 20:44:10 - ras_commander.RasPlan - WARNING - No description found in plan file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
Updated description for plan 03
Current plan description:
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-01-11 20:44:10 - ras_commander.RasCmdr - INFO - Using ras_object with project folder: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103
2026-01-11 20:44:10 - ras_commander.geom.GeomPreprocessor - INFO - Clearing geometry preprocessor file for single plan: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:10 - ras_commander.geom.GeomPreprocessor - WARNING - No geometry preprocessor file found for: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03
2026-01-11 20:44:10 - ras_commander.geom.GeomPreprocessor - INFO - Geometry dataframe updated successfully.
2026-01-11 20:44:10 - ras_commander.RasCmdr - INFO - Cleared geometry preprocessor files for plan: 03
2026-01-11 20:44:10 - ras_commander.RasCmdr - INFO - Running HEC-RAS from the Command Line:
2026-01-11 20:44:10 - ras_commander.RasCmdr - INFO - Running command: "C:\Program Files (x86)\HEC\HEC-RAS\6.6\Ras.exe" -c "C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.prj" "C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03"
Computing plan 03...
2026-01-11 20:46:11 - ras_commander.RasCmdr - INFO - HEC-RAS execution completed for plan: 03
2026-01-11 20:46:11 - ras_commander.RasCmdr - INFO - Total run time for plan 03: 120.78 seconds
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Using existing Path object HDF file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Reading computation messages from HDF: BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Successfully extracted 1756 characters from HDF
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Using existing Path object HDF file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Extracting Plan Information from: BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Plan Name: Unsteady with Bridges and Dam clonedplan
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Simulation Duration (hours): 119.98333333333333
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Using existing Path object HDF file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Using existing Path object HDF file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
c:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\ras_commander\RasPrj.py:1513: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.
self.results_df = pd.concat([self.results_df, new_results], ignore_index=True)
2026-01-11 20:46:11 - ras_commander.RasPrj - INFO - Updated results_df with 1 plan(s)
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... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | 02 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | 01 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... |
1 rows × 27 columns
Plan 03 has a valid HDF results file:
HDF Path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
All plan entries with their HDF paths:
| plan_number | HDF_Results_Path | |
|---|---|---|
| 0 | 01 | None |
| 1 | 02 | None |
| 2 | 03 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... |
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.")
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Extracting Plan Information from: BaldEagle.p03.hdf
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Plan Name: Unsteady with Bridges and Dam clonedplan
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Simulation Duration (hours): 119.98333333333333
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.025894 | N/A | 0.003038 | 0.032869 | 39489.851892 | 3650.361706 |
2026-01-11 20:46:11 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_103\BaldEagle.p03.hdf
Simulation Duration: 431940.00 seconds
Computation Time: 0.03287 hours
Computation Speed: 3650.36 (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 | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... |
| hdf_exists | False | False | True |
| hdf_mtime | NaT | NaT | 2026-01-11 20:46:10.766280 |
| completed | False | False | True |
| has_errors | False | False | False |
| has_warnings | False | False | False |
| error_count | 0 | 0 | 0 |
| warning_count | 0 | 0 | 0 |
| first_error_line | None | None | None |
| rt_simulation_start | NaT | NaT | 2023-01-01 00:00:00 |
| rt_simulation_end | NaT | NaT | 2023-01-05 23:59:00 |
| rt_simulation_hours | NaN | NaN | 119.983333 |
| rt_complete_process_hours | NaN | NaN | 0.032869 |
| rt_unsteady_compute_hours | NaN | NaN | 0.003038 |
| rt_complete_process_speed | NaN | NaN | 3650.361706 |
| unsteady_time_of_maximum_stage | NaN | NaN | None |
| unsteady_time_of_maximum_velocity | NaN | NaN | None |
| unsteady_time_of_maximum_flow | NaN | NaN | None |
| unsteady_computation_interval | NaN | NaN | None |
| steady_solution | NaN | NaN | NaN |
| vol_Error | NaN | NaN | -12.049353 |
| vol_Error_Percent | NaN | NaN | 0.005847 |
| vol_Total_Boundary_Flux_of_Water_In | NaN | NaN | 196776.984375 |
| vol_Total_Boundary_Flux_of_Water_Out | NaN | NaN | 104118.132812 |
| vol_Vol_Accounting_in | NaN | NaN | Acre Feet |
| vol_Volume_Ending | NaN | NaN | 101953.601562 |
| vol_Volume_Starting | NaN | NaN | 9306.797852 |
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}")
# 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)}")
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.