| name | hecras_compute_rascontrol |
| shared_corpus | true |
| harness_scope | shared |
| source_owner | gpt-cmdr |
| security_review | internal |
| description | Executes HEC-RAS plans using RasControl class via HECRASController COM interface
for legacy HEC-RAS versions (3.x-5.x). Handles COM lifecycle management, session
tracking, orphan cleanup, steady/unsteady result extraction, and watchdog
protection for Jupyter notebooks. Use when automating legacy HEC-RAS, extracting
results from older versions, comparing across HEC-RAS versions, or needing
COM-based automation that RasCmdr cannot provide.
Triggers: RasControl, HECRASController, COM, legacy, HEC-RAS 4, HEC-RAS 5,
win32com, steady results, unsteady results, version comparison, COM interface,
legacy automation, 3.x, 4.x, 5.x, orphan cleanup, watchdog, session tracking.
|
Executing HEC-RAS Plans via RasControl (COM Interface)
Use RasControl to automate HEC-RAS versions 3.x-5.x via the HECRASController COM interface. For HEC-RAS 6.x+, use RasCmdr instead.
Primary Sources
1. RasControl Implementation
Location: ras_commander/RasControl.py
Read these key sections:
- Lines 438-527:
RasControl class with version mapping and output variable codes
- Lines 543-742: COM lifecycle management (
_com_open_close())
- Lines 746-884:
run_plan() with smart skip and watchdog protection
- Lines 936-1177:
get_steady_results() - extract steady state profiles
- Lines 1179-1458:
get_unsteady_results() - extract time series with Max WS
- Lines 1647-1909: Process management API (orphan cleanup)
2. Working Examples (Jupyter Notebooks)
examples/120_automating_ras_with_win32com.ipynb - Low-level win32com exploration
examples/121_legacy_hecrascontroller_and_rascontrol.ipynb - Complete RasControl workflows
3. Supporting Documentation
.claude/rules/hec-ras/execution.md - Execution mode comparison
ras_commander/AGENTS.md - Library context and module organization
When to Use RasControl vs RasCmdr
| Scenario | Use RasControl | Use RasCmdr |
|---|
| HEC-RAS 3.x-5.x | Yes | No |
| HEC-RAS 6.x+ | No (use COM only if needed) | Yes (preferred) |
| Need GUI interaction | Yes (COM opens GUI) | No (headless) |
| Version comparison | Yes | Yes |
| Production workflows | Limited | Preferred |
| Parallel execution | No (single-threaded) | Yes |
Quick Reference
Basic Workflow
from ras_commander import init_ras_project, RasControl
init_ras_project(project_path, "5.0.6")
success, msgs = RasControl.run_plan("02")
success, msgs = RasControl.run_plan("02", force_recompute=True)
df_steady = RasControl.get_steady_results("02")
df_unsteady = RasControl.get_unsteady_results("01")
Version Format Support
RasControl accepts flexible version formats:
init_ras_project(path, "4.1")
init_ras_project(path, "41")
init_ras_project(path, "5.0.6")
init_ras_project(path, "506")
init_ras_project(path, "7.0")
init_ras_project(path, "66")
Supported versions: 3.0-3.1.3, 4.0-4.1, 5.0-5.0.7, 6.0-6.7
Separating Max WS from Time Series
df_maxws = df_unsteady[df_unsteady['time_string'] == 'Max WS']
df_timeseries = df_unsteady[df_unsteady['datetime'].notna()]
import matplotlib.pyplot as plt
xs_data = df_timeseries[df_timeseries['node_id'] == '10000']
plt.plot(xs_data['datetime'], xs_data['wsel'])
plt.axhline(df_maxws[df_maxws['node_id'] == '10000']['wsel'].iloc[0],
color='r', linestyle='--', label='Max WS')
COM Lifecycle Management
Critical Pattern: Open-Operate-Close
RasControl handles COM lifecycle automatically via _com_open_close():
Why this matters:
- COM objects MUST be released properly
- Orphaned ras.exe processes consume resources
- Session tracking enables recovery after crashes
Session Tracking Infrastructure
RasControl tracks all active COM sessions:
df = RasControl.list_processes()
print(df)
df_all = RasControl.list_processes(show_all=True)
Orphan Detection and Cleanup
After crashes or Jupyter kernel restarts:
orphans = RasControl.scan_orphans()
if orphans:
print(f"Found {len(orphans)} orphaned processes")
RasControl.cleanup_orphans()
count = RasControl.cleanup_orphans(interactive=False)
RasControl.cleanup_orphans(dry_run=True)
RasControl.force_cleanup_all()
Watchdog Protection
For long-running operations in Jupyter:
success, msgs = RasControl.run_plan("01", use_watchdog=True, max_runtime=3600)
success, msgs = RasControl.run_plan("01", use_watchdog=False)
Watchdog features:
- Independent Python process monitors parent
- Terminates ras.exe if Python crashes
- Enforces max_runtime timeout
- Responds to manual lock file deletion
Result Extraction
Steady State Results
df = RasControl.get_steady_results("02")
Unsteady Results with Datetime
df = RasControl.get_unsteady_results("01")
Computation Messages
msgs = RasControl.get_comp_msgs("01")
print(msgs)
Common Patterns
Pattern: Version Comparison
from ras_commander import RasPlan
versions = [("5.0.6", "506"), ("6.3.1", "631"), ("7.0", "66")]
results = {}
for version_name, version_code in versions:
new_plan = RasPlan.clone_plan("01", new_shortid=f"v{version_code}")
init_ras_project(project_path, version_name)
RasControl.run_plan(new_plan, force_recompute=True)
results[version_name] = RasControl.get_unsteady_results(new_plan)
for version, df in results.items():
max_wse = df[df['time_string'] == 'Max WS']['wsel'].max()
print(f"v{version}: Max WSE = {max_wse:.2f} ft")
Pattern: Error Recovery
try:
success, msgs = RasControl.run_plan("01")
except Exception as e:
print(f"COM error: {e}")
RasControl.cleanup_orphans(interactive=False)
comp_msgs = RasControl.get_comp_msgs("01")
print(f"Computation messages:\n{comp_msgs}")
Pattern: Extract Before Running
success, msgs = RasControl.run_plan("01")
if "Results are current" in msgs[0]:
print("Skipped - results already up-to-date")
else:
print("Plan executed")
df = RasControl.get_unsteady_results("01")
Troubleshooting
COM Object Not Found
import win32com.client
try:
rc = win32com.client.Dispatch("RAS66.HECRASController")
print("COM registered correctly")
except Exception as e:
print(f"COM issue: {e}")
print("Solution: Reinstall HEC-RAS or run as Administrator")
HEC-RAS Freezes or Hangs
RasControl.list_processes(show_all=True)
RasControl.cleanup_orphans()
RasControl.force_cleanup_all()
Results Extraction Fails
success, msgs = RasControl.run_plan("01", force_recompute=True)
comp_msgs = RasControl.get_comp_msgs("01")
print(comp_msgs)
if "error" in comp_msgs.lower():
print("Computation had errors - fix model issues")
Version Mismatch
print(RasControl.VERSION_MAP.keys())
init_ras_project(path, "5.0.6")
Performance Considerations
COM is Single-Threaded
- RasControl cannot run plans in parallel
- Each operation opens/closes HEC-RAS GUI
- For parallel execution, use RasCmdr with HEC-RAS 6.x+
GUI Overhead
- COM interface opens HEC-RAS GUI (requires active desktop)
- Slower than RasCmdr subprocess execution
- Consider RDP session for headless servers
Memory Usage
Migration Path: RasControl to RasCmdr
When upgrading to HEC-RAS 6.x+:
init_ras_project(path, "5.0.6")
RasControl.run_plan("01")
df = RasControl.get_steady_results("01")
from ras_commander import RasCmdr
from ras_commander.hdf import HdfResultsPlan
init_ras_project(path, "7.0")
RasCmdr.compute_plan("01")
hdf = HdfResultsPlan(ras.plan_df.loc[0, 'HDF_Results_Path'])
wse = hdf.get_steady_wse()
Cross-References
Rules (follow these):
.claude/rules/hec-ras/execution.md -- General execution context
Agents (delegate when needed):
win32com-automation-expert -- Delegate for COM interface details and GUI automation
Skills (related workflows):
hecras_compute_plans -- Preferred: modern RasCmdr execution (HEC-RAS 6.x+)
hecras_extract_results -- Downstream: extract results after COM execution
Primary sources:
ras_commander/RasControl.py -- HECRASController wrapper
examples/120_automating_ras_with_win32com.ipynb -- COM automation tutorial
examples/121_legacy_hecrascontroller_and_rascontrol.ipynb -- RasControl patterns