Executing Plan Sets¶
# =============================================================================
# DEVELOPMENT MODE TOGGLE
# =============================================================================
USE_LOCAL_SOURCE = False # <-- TOGGLE THIS
if USE_LOCAL_SOURCE:
import sys
from pathlib import Path
local_path = str(Path.cwd().parent)
if local_path not in sys.path:
sys.path.insert(0, local_path)
print(f"📁 LOCAL SOURCE MODE: Loading from {local_path}/ras_commander")
else:
print("📦 PIP PACKAGE MODE: Loading installed ras-commander")
# Import ras-commander
from ras_commander import RasCmdr, RasExamples, RasPlan, RasPrj, init_ras_project, ras
# Additional imports
import os
import numpy as np
import pandas as pd
from IPython import display
import matplotlib.pyplot as plt
import psutil # For getting system CPU info
from concurrent.futures import ThreadPoolExecutor, as_completed
import time
import subprocess
import shutil
# 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 execution
- Disk Space: ~2 GB (example project + execution results)
What You'll Learn¶
This notebook demonstrates selective plan execution patterns:
- Specific Plan Lists: Execute chosen plans, not all plans
- Conditional Execution: Run only plans missing HDF results
- Sequential Processing: Control execution order for dependent plans
Related Notebooks¶
- 110_single_plan_execution.ipynb - Execute individual plans
- 112_sequential_plan_execution.ipynb - Test mode debugging
- 113_parallel_execution.ipynb - Parallel plan sets
Key Concept: Plan Selection Strategies¶
Strategy 1: Explicit List
# Run specific plans by number
plans_to_run = ["01", "03", "05"]
for plan in plans_to_run:
RasCmdr.compute_plan(plan)
Strategy 2: Conditional Selection
# Run only plans without results
plans_without_hdf = ras.plan_df[~ras.plan_df['hdf_path'].apply(Path).map(lambda p: p.exists())]
missing_plans = plans_without_hdf['plan_number'].tolist()
Strategy 3: Filtered by Criteria
# Run only unsteady plans
unsteady_plans = ras.plan_df[ras.plan_df['plan_title'].str.contains('Unsteady')]
plans_to_run = unsteady_plans['plan_number'].tolist()
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.)
# Execution Settings
PLAN = "01" # Plan number to execute
NUM_CORES = 4 # CPU cores for 2D computation
RUN_SUFFIX = "run" # Suffix for run folder (e.g., Muncie_run)
# Extract the Bald Eagle Creek example project
# The extract_project method downloads the project from GitHub if not already present,
# and extracts it to the example_projects folder
bald_eagle_path = RasExamples.extract_project("Balde Eagle Creek", suffix="111")
print(f"Extracted project to: {bald_eagle_path}")
# Verify the path exists
print(f"Bald Eagle Creek project exists: {bald_eagle_path.exists()}")
2026-01-11 22:11:01 - 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 22:11:01 - ras_commander.RasExamples - INFO - Loading project data from CSV...
2026-01-11 22:11:01 - ras_commander.RasExamples - INFO - Loaded 68 projects from CSV.
2026-01-11 22:11:01 - ras_commander.RasExamples - INFO - ----- RasExamples Extracting Project -----
2026-01-11 22:11:01 - ras_commander.RasExamples - INFO - Extracting project 'Balde Eagle Creek' as 'Balde Eagle Creek_111'
2026-01-11 22:11:01 - ras_commander.RasExamples - INFO - Folder 'Balde Eagle Creek_111' already exists. Deleting existing folder...
2026-01-11 22:11:01 - ras_commander.RasExamples - INFO - Existing folder 'Balde Eagle Creek_111' has been deleted.
2026-01-11 22:11:01 - 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_111
Extracted project to: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111
Bald Eagle Creek project exists: True
Step 1: Project Initialization¶
Let's initialize the HEC-RAS project using the init_ras_project() function and explore the available plans.
# Initialize the HEC-RAS project
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("\nAvailable plans in the project:")
display.display(ras.plan_df)
# Check plan details to understand what each plan represents
plan_details = []
for index, row in ras.plan_df.iterrows():
plan_number = row['plan_number']
# Get plan description if available
description = None
if 'description' in row:
description = row['description']
else:
try:
description = RasPlan.read_plan_description(plan_number)
except:
pass
# Get short identifier if available
short_id = None
if 'Short Identifier' in row:
short_id = row['Short Identifier']
# Get geometry file
geom_file = None
if 'Geom File' in row:
geom_file = row['Geom File']
# Check if the plan has results
has_results = False
if 'HDF_Results_Path' in row and row['HDF_Results_Path']:
has_results = True
plan_details.append({
'Plan Number': plan_number,
'Short ID': short_id,
'Description': description[:50] + '...' if description and len(description) > 50 else description,
'Geometry': geom_file,
'Has Results': has_results
})
# Create a DataFrame with the plan details
plan_details_df = pd.DataFrame(plan_details)
print("\nPlan details:")
display.display(plan_details_df)
2026-01-11 22:11:01 - 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_111\BaldEagle.rasmap
2026-01-11 22:11:01 - ras_commander.RasPrj - INFO - Updated results_df with 2 plan(s)
Initialized HEC-RAS project: BaldEagle
Available plans in 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 | 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
2026-01-11 22:11:01 - 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_111\BaldEagle.p01
2026-01-11 22:11:01 - 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_111\BaldEagle.p02
Plan details:
| Plan Number | Short ID | Description | Geometry | Has Results | |
|---|---|---|---|---|---|
| 0 | 01 | UnsteadyFlow | 01 | False | |
| 1 | 02 | SteadyRun | 01 | False |
Step 2: Sequential Execution of Specific Plans¶
Let's execute specific plans in sequence using RasCmdr.compute_test_mode() with a list of plan numbers. This approach allows us to run only the plans we need, in the order we specify.
print("Executing specific plans sequentially...")
print("This may take several minutes...")
# Define the plans to execute
specific_plans = ["01", "03"]
print(f"Selected plans: {', '.join(specific_plans)}")
# Record start time for performance measurement
start_time = time.time()
# Execute specific plans sequentially
execution_results = RasCmdr.compute_test_mode(
plan_number=specific_plans,
dest_folder_suffix="[SpecificSequential]",
num_cores=6,
overwrite_dest=True
)
# Record end time and calculate duration
end_time = time.time()
sequential_duration = end_time - start_time
print(f"Sequential execution of specific plans completed in {sequential_duration:.2f} seconds")
# Create a DataFrame from the execution results for better visualization
sequential_results_df = pd.DataFrame([
{"Plan": plan, "Success": success, "Execution Type": "Sequential"}
for plan, success in execution_results.items()
])
sequential_results_df
# Ensure the 'Plan' column exists before sorting
if 'Plan' in sequential_results_df.columns:
sequential_results_df = sequential_results_df.sort_values("Plan")
else:
print("Warning: 'Plan' column not found in execution results.")
# Display the results
print("\nSequential Execution Results:")
display.display(sequential_results_df)
# Check the test folder
test_folder = bald_eagle_path.parent / f"{ras.project_name} [SpecificSequential]"
if test_folder.exists():
print(f"\nTest folder exists: {test_folder}")
# Check for results
hdf_files = list(test_folder.glob("*.p*.hdf"))
if hdf_files:
print(f"Found {len(hdf_files)} HDF result files:")
for file in hdf_files:
file_size = file.stat().st_size / (1024 * 1024) # Size in MB
print(f" {file.name}: {file_size:.1f} MB")
else:
print("No HDF result files found in the test folder")
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Starting the compute_test_mode...
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Creating the test folder: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [SpecificSequential]...
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Copied project folder to compute folder: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [SpecificSequential]
2026-01-11 22:11:01 - 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_111 [SpecificSequential]\BaldEagle.rasmap
2026-01-11 22:11:01 - ras_commander.RasPrj - INFO - Updated results_df with 2 plan(s)
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Initialized RAS project in compute folder: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [SpecificSequential]\BaldEagle.prj
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Getting plan entries...
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Retrieved plan entries successfully.
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Filtered plans to execute: ['01', '03']
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Running selected plans sequentially...
2026-01-11 22:11:01 - 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_111 [SpecificSequential]
2026-01-11 22:11:01 - ras_commander.RasUtils - INFO - Using provided plan file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [SpecificSequential]\BaldEagle.p01
2026-01-11 22:11:01 - ras_commander.RasUtils - INFO - Successfully updated file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [SpecificSequential]\BaldEagle.p01
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Set number of cores to 6 for plan: 01
2026-01-11 22:11:01 - ras_commander.RasCmdr - INFO - Running HEC-RAS from the Command Line:
Executing specific plans sequentially...
This may take several minutes...
Selected plans: 01, 03
2026-01-11 22:11:01 - 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_111 [SpecificSequential]\BaldEagle.prj" "C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [SpecificSequential]\BaldEagle.p01"
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - HEC-RAS execution completed for plan: 01
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Total run time for plan 01: 94.24 seconds
2026-01-11 22:12:35 - 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_111 [SpecificSequential]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [SpecificSequential]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Reading computation messages from HDF: BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Successfully extracted 1693 characters from HDF
2026-01-11 22:12:35 - 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_111 [SpecificSequential]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [SpecificSequential]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Extracting Plan Information from: BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Plan Name: Unsteady with Bridges and Dam
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Simulation Duration (hours): 149.0
2026-01-11 22:12:35 - 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_111 [SpecificSequential]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [SpecificSequential]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [SpecificSequential]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [SpecificSequential]\BaldEagle.p01.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 22:12:35 - ras_commander.RasPrj - INFO - Updated results_df with 1 plan(s)
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Successfully computed plan 01
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Total run time for plan 01: 94.29 seconds
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - All selected plans have been executed.
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Consolidating HDF results from C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [SpecificSequential] back to original project folder...
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Consolidated 3 HDF file(s) to original project folder
2026-01-11 22:12:35 - ras_commander.RasCmdr - WARNING - Failed to remove test folder C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [SpecificSequential]: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\billk_clb\\anaconda3\\envs\\rascmdr_piptest\\Lib\\site-packages\\examples\\example_projects\\Balde Eagle Creek_111 [SpecificSequential]'
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - compute_test_mode completed.
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO -
Execution Results:
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Plan 01: Successful
2026-01-11 22:12:35 - 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_111\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111\BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Reading computation messages from HDF: BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Successfully extracted 1693 characters from HDF
2026-01-11 22:12:35 - 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_111\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111\BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Extracting Plan Information from: BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Plan Name: Unsteady with Bridges and Dam
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Simulation Duration (hours): 149.0
2026-01-11 22:12:35 - 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_111\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111\BaldEagle.p01.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 22:12:35 - ras_commander.RasPrj - INFO - Updated results_df with 1 plan(s)
Sequential execution of specific plans completed in 94.37 seconds
Sequential Execution Results:
| Plan | Success | Execution Type | |
|---|---|---|---|
| 0 | 01 | True | Sequential |
Step 3: Running Only Plans Without HDF Results¶
An important use case is to identify and execute only those plans that have no existing HDF results. This approach can save time by avoiding redundant computations, especially useful when adding new plans to an existing project or after making limited changes.
Let's demonstrate how to:
- Use the
rasobject to identify plans without results - Create a filtered list of these plans
- Execute only the missing plans
print("Identifying and executing plans without HDF results...")
# Use the ras object to determine which plans don't have results
plans_no_results = ras.plan_df[ras.plan_df['HDF_Results_Path'].isna()]['plan_number'].tolist()
if not plans_no_results:
print("All plans already have HDF results. Creating a test scenario...")
# For demonstration purposes, pretend some plans don't have results
plans_no_results = ["04", "05"]
print(f"Simulating no results for plans: {', '.join(plans_no_results)}")
else:
print(f"Found {len(plans_no_results)} plans without HDF results: {', '.join(plans_no_results)}")
# Record start time for performance measurement
start_time = time.time()
# Execute only the plans without results
if plans_no_results:
print(f"\nExecuting {len(plans_no_results)} plans without results...")
execution_results = RasCmdr.compute_test_mode(
plan_number=plans_no_results,
dest_folder_suffix="[MissingPlans]",
num_cores=6,
overwrite_dest=True
)
# Record end time and calculate duration
end_time = time.time()
duration = end_time - start_time
print(f"Execution completed in {duration:.2f} seconds")
# Create a DataFrame from the execution results
missing_results_df = pd.DataFrame([
{"Plan": plan, "Success": success, "Execution Type": "Missing Plans"}
for plan, success in execution_results.items()
])
# Sort by plan number
missing_results_df = missing_results_df.sort_values("Plan")
# Display the results
print("\nExecution Results for Plans Without HDF Results:")
display.display(missing_results_df)
# Check the test folder
test_folder = bald_eagle_path.parent / f"{ras.project_name} [MissingPlans]"
if test_folder.exists():
print(f"\nTest folder exists: {test_folder}")
# Check for results
hdf_files = list(test_folder.glob("*.p*.hdf"))
if hdf_files:
print(f"Found {len(hdf_files)} HDF result files:")
for file in hdf_files:
file_size = file.stat().st_size / (1024 * 1024) # Size in MB
print(f" {file.name}: {file_size:.1f} MB")
else:
print("No HDF result files found in the test folder")
else:
print("No plans without results to execute.")
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Starting the compute_test_mode...
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Creating the test folder: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [MissingPlans]...
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Compute folder 'C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [MissingPlans]' exists. Overwriting as per overwrite_dest=True.
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Copied project folder to compute folder: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [MissingPlans]
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.rasmap
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Reading computation messages from HDF: BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Successfully extracted 1693 characters from HDF
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Extracting Plan Information from: BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Plan Name: Unsteady with Bridges and Dam
2026-01-11 22:12:35 - ras_commander.hdf.HdfResultsPlan - INFO - Simulation Duration (hours): 149.0
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.p01.hdf
2026-01-11 22:12:35 - ras_commander.RasPrj - INFO - Updated results_df with 2 plan(s)
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Initialized RAS project in compute folder: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [MissingPlans]\BaldEagle.prj
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Getting plan entries...
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Retrieved plan entries successfully.
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Filtered plans to execute: ['02']
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Running selected plans sequentially...
2026-01-11 22:12:35 - 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_111 [MissingPlans]
2026-01-11 22:12:35 - ras_commander.RasUtils - INFO - Using provided plan file path: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [MissingPlans]\BaldEagle.p02
2026-01-11 22:12:35 - ras_commander.RasUtils - INFO - Successfully updated file: C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [MissingPlans]\BaldEagle.p02
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Set number of cores to 6 for plan: 02
2026-01-11 22:12:35 - ras_commander.RasCmdr - INFO - Running HEC-RAS from the Command Line:
2026-01-11 22:12:35 - 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_111 [MissingPlans]\BaldEagle.prj" "C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [MissingPlans]\BaldEagle.p02"
Identifying and executing plans without HDF results...
Found 1 plans without HDF results: 02
Executing 1 plans without results...
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO - HEC-RAS execution completed for plan: 02
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO - Total run time for plan 02: 3.92 seconds
2026-01-11 22:12:39 - 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_111 [MissingPlans]\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111 [MissingPlans]\BaldEagle.p02.hdf
2026-01-11 22:12:39 - ras_commander.hdf.HdfResultsPlan - INFO - Reading computation messages from HDF: BaldEagle.p02.hdf
2026-01-11 22:12:39 - ras_commander.hdf.HdfResultsPlan - INFO - Successfully extracted 529 characters from HDF
2026-01-11 22:12:39 - 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_111 [MissingPlans]\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111 [MissingPlans]\BaldEagle.p02.hdf
2026-01-11 22:12:39 - ras_commander.hdf.HdfResultsPlan - INFO - Extracting Plan Information from: BaldEagle.p02.hdf
2026-01-11 22:12:39 - ras_commander.hdf.HdfResultsPlan - ERROR - Error parsing simulation times: time data 'Unknown' does not match format '%d%b%Y %H:%M:%S'
2026-01-11 22:12:39 - 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_111 [MissingPlans]\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111 [MissingPlans]\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111 [MissingPlans]\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111 [MissingPlans]\BaldEagle.p02.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 22:12:39 - ras_commander.RasPrj - INFO - Updated results_df with 1 plan(s)
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO - Successfully computed plan 02
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO - Total run time for plan 02: 3.95 seconds
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO - All selected plans have been executed.
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO - Consolidating HDF results from C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [MissingPlans] back to original project folder...
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO - Consolidated 4 HDF file(s) to original project folder
2026-01-11 22:12:39 - ras_commander.RasCmdr - WARNING - Failed to remove test folder C:\Users\billk_clb\anaconda3\envs\rascmdr_piptest\Lib\site-packages\examples\example_projects\Balde Eagle Creek_111 [MissingPlans]: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\billk_clb\\anaconda3\\envs\\rascmdr_piptest\\Lib\\site-packages\\examples\\example_projects\\Balde Eagle Creek_111 [MissingPlans]'
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO - compute_test_mode completed.
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO -
Execution Results:
2026-01-11 22:12:39 - ras_commander.RasCmdr - INFO - Plan 02: Successful
2026-01-11 22:12:39 - 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_111\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111\BaldEagle.p02.hdf
2026-01-11 22:12:39 - ras_commander.hdf.HdfResultsPlan - INFO - Reading computation messages from HDF: BaldEagle.p02.hdf
2026-01-11 22:12:39 - ras_commander.hdf.HdfResultsPlan - INFO - Successfully extracted 529 characters from HDF
2026-01-11 22:12:39 - 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_111\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111\BaldEagle.p02.hdf
2026-01-11 22:12:39 - ras_commander.hdf.HdfResultsPlan - INFO - Extracting Plan Information from: BaldEagle.p02.hdf
2026-01-11 22:12:39 - ras_commander.hdf.HdfResultsPlan - ERROR - Error parsing simulation times: time data 'Unknown' does not match format '%d%b%Y %H:%M:%S'
2026-01-11 22:12:39 - 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_111\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111\BaldEagle.p02.hdf
2026-01-11 22:12:39 - 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_111\BaldEagle.p02.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 22:12:39 - ras_commander.RasPrj - INFO - Updated results_df with 1 plan(s)
Execution completed in 4.04 seconds
Execution Results for Plans Without HDF Results:
| Plan | Success | Execution Type | |
|---|---|---|---|
| 0 | 02 | True | Missing Plans |
Verification of Results¶
After executing the plans that were missing HDF results, it's important to verify that the results were properly generated. Let's check if the execution actually created the expected output files.
# Re-initialize the project with the test folder to see updated results
missing_plans_folder = bald_eagle_path.parent / f"{ras.project_name} [MissingPlans]"
if missing_plans_folder.exists():
# Initialize the project from the test folder
test_ras = RasPrj()
init_ras_project(missing_plans_folder, RAS_VERSION, ras_object=test_ras)
# Check which plans now have results
plans_with_results = test_ras.plan_df[test_ras.plan_df['HDF_Results_Path'].notna()]['plan_number'].tolist()
print(f"Plans with results after execution: {', '.join(plans_with_results)}")
# Verify if all previously missing plans now have results
all_generated = all(plan in plans_with_results for plan in plans_no_results)
if all_generated:
print("✅ Successfully generated results for all missing plans")
else:
print("⚠️ Some plans still don't have results after execution")
missing_after = [plan for plan in plans_no_results if plan not in plans_with_results]
print(f"Plans still missing results: {', '.join(missing_after)}")
Viewing Execution Summary with results_df¶
The results_df DataFrame provides execution status, timing, and error/warning information for all executed plans.
Execution Summary:
| 0 | 1 | |
|---|---|---|
| plan_number | 01 | 02 |
| plan_title | Unsteady with Bridges and Dam | Steady Flow Run |
| flow_type | Unsteady | Unsteady |
| hdf_path | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... | C:\Users\billk_clb\anaconda3\envs\rascmdr_pipt... |
| hdf_exists | True | True |
| hdf_mtime | 2026-01-11 22:12:35.461179 | 2026-01-11 22:12:39.546552 |
| completed | True | True |
| has_errors | False | False |
| has_warnings | False | False |
| error_count | 0 | 0 |
| warning_count | 0 | 0 |
| first_error_line | None | None |
| rt_simulation_start | 1999-02-18 00:00:00 | NaT |
| rt_simulation_end | 1999-02-24 05:00:00 | NaT |
| rt_simulation_hours | 149.0 | NaN |
| rt_complete_process_hours | 0.025616 | NaN |
| rt_unsteady_compute_hours | 0.000886 | NaN |
| rt_complete_process_speed | 5816.588772 | NaN |
| unsteady_time_of_maximum_stage | None | None |
| unsteady_time_of_maximum_velocity | None | None |
| unsteady_time_of_maximum_flow | None | None |
| unsteady_computation_interval | None | None |
| steady_solution | NaN | NaN |
| vol_Error | -29.546846 | NaN |
| vol_Error_Percent | 0.014071 | NaN |
| vol_Total_Boundary_Flux_of_Water_In | 200682.453125 | NaN |
| vol_Total_Boundary_Flux_of_Water_Out | 112574.828125 | NaN |
| vol_Vol_Accounting_in | Acre Feet | NaN |
| vol_Volume_Ending | 97384.882812 | NaN |
| vol_Volume_Starting | 9306.797852 | NaN |
Plan Set Execution Best Practices¶
Common Patterns¶
Pattern 1: Baseline + Alternatives
baseline_plan = "01"
alternatives = ["02", "03", "04", "05"]
# Run baseline first
print("Running baseline...")
RasCmdr.compute_plan(baseline_plan)
# Then run alternatives
print("Running alternatives...")
for plan in alternatives:
RasCmdr.compute_plan(plan)
Pattern 2: Sensitivity Analysis Grid
# Create plan matrix: different roughness values
roughness_values = [0.030, 0.035, 0.040, 0.045]
plan_map = {}
for i, roughness in enumerate(roughness_values, start=1):
plan_num = f"{i:02d}"
plan_map[plan_num] = roughness
# Execute all sensitivity plans
for plan_num in plan_map.keys():
print(f"Running plan {plan_num} (n={plan_map[plan_num]})...")
RasCmdr.compute_plan(plan_num)
Pattern 3: Phased Execution
# Phase 1: Quick steady-state runs
steady_plans = ras.plan_df[ras.plan_df['plan_title'].str.contains('Steady')]
for plan in steady_plans['plan_number']:
RasCmdr.compute_plan(plan)
# Phase 2: Longer unsteady runs
unsteady_plans = ras.plan_df[ras.plan_df['plan_title'].str.contains('Unsteady')]
for plan in unsteady_plans['plan_number']:
RasCmdr.compute_plan(plan)
LLM Forward: Execution Audit Trail¶
Document which plans were executed and why:
def log_plan_execution_set(plans_executed, selection_criteria, output_file):
import json
from datetime import datetime
execution_log = {
'timestamp': datetime.now().isoformat(),
'selection_criteria': selection_criteria,
'plans_executed': plans_executed,
'plan_details': []
}
for plan in plans_executed:
plan_info = ras.plan_df[ras.plan_df['plan_number'] == plan].iloc[0]
execution_log['plan_details'].append({
'plan_number': plan,
'plan_title': plan_info['plan_title'],
'geom_file': plan_info['geom_file'],
'flow_file': plan_info.get('flow_file', 'N/A')
})
with open(output_file, 'w') as f:
json.dump(execution_log, f, indent=2)
print(f"Execution log saved: {output_file}")
# Usage
log_plan_execution_set(
plans_executed=["01", "03", "05"],
selection_criteria="Sensitivity analysis: Manning's n variations",
output_file=Path('execution_log.json')
)
This provides: - Reproducibility: Know exactly which plans were run - Audit trail: Document selection rationale - Peer review: Non-programmers can verify correct plans executed
Summary of Plan Specification Techniques¶
In this notebook, we've explored different ways to specify and execute HEC-RAS plans using the RAS Commander library. Here's a summary of the key techniques we've covered:
- Basic Plan Specification
- Single plan by number:
"01" - List of specific plans:
["01", "03"] -
All plans:
ras.plan_df['plan_number'].tolist() -
Advanced Selection
- Categorization: Grouping plans by purpose or type
- Dependencies: Ensuring prerequisite plans are run first
-
Ordered execution: Running plans in a specific sequence
-
Run Plans with Missing Results (HDF)
- Using ras object to determine which plans have results
- Creating a list of plans with no results
-
Running those plans sequentially
-
NOTE: run_parallel can also run a list of plans, but compute_plan is only made for single plan execution.
Best Practices for Plan Specification¶
- Consistent Formatting: Use two-digit strings for plan numbers ("01" instead of 1)
- Descriptive Naming: Use meaningful short identifiers that describe the plan's purpose
- Verify Availability: Check that specified plans exist before trying to execute them
- Document Dependencies: Keep track of which plans depend on others
- Use Appropriate Execution Method: Choose sequential or parallel based on dependencies and resources
- Monitor Performance: Track execution times to identify optimization opportunities
By applying these techniques, you can create efficient and organized workflows for executing HEC-RAS plans, from simple batch processing to complex dependency-based execution sequences.