smithery/gpt-cmdr

hecras_compute_rascontrol

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. win32com, steady results, unsteady results, version compa…

Installation

$ npx skills add smithery/gpt-cmdr --skill hecras-compute-rascontrol

Also in this package

Other skills from smithery/gpt-cmdr · top by installs.

npx skills add smithery/gpt-cmdr

Browse all from smithery/gpt-cmdr

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Skill metadata

Parsed from SKILL.md frontmatter.

Declared agents claude-code

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 11,241 B
  • docs SUMMARY.md 714 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

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 (comopen_close())
  • Lines 746-884: run_plan() with smart skip and watchdog protection
  • Lines 936-1177: getsteadyresults() - extract steady state profiles
  • Lines 1179-1458: getunsteadyresults() - extract time series with Max WS
  • Lines 1647-1909: Process management API (orphan cleanup)

2. Working Examples (Jupyter Notebooks)

  • examples/120automatingraswithwin32com.ipynb - Low-level win32com exploration
  • examples/121legacyhecrascontrollerandrascontrol.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

# Initialize project with version
init_ras_project(project_path, "5.0.6")  # Or "506", "4.1", "41", etc.

# Run plan (checks if current, skips if up-to-date)
success, msgs = RasControl.run_plan("02")

# Force recomputation
success, msgs = RasControl.run_plan("02", force_recompute=True)

# Extract steady state results
df_steady = RasControl.get_steady_results("02")

# Extract unsteady time series (includes Max WS row)
df_unsteady = RasControl.get_unsteady_results("01")

Version Format Support

RasControl accepts flexible version formats:

# All equivalent - HEC-RAS 4.1
init_ras_project(path, "4.1")
init_ras_project(path, "41")

# All equivalent - HEC-RAS 5.0.6
init_ras_project(path, "5.0.6")
init_ras_project(path, "506")

# All equivalent - HEC-RAS 6.6
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

# Max WS contains computational maximums (critical for design!)
df_maxws = df_unsteady[df_unsteady['time_string'] == 'Max WS']
df_timeseries = df_unsteady[df_unsteady['datetime'].notna()]

# Plot time series with Max WS reference line
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 comopen_close():

# Internal pattern (you don't call this directly)
# 1. Create COM object: win32com.client.Dispatch("RAS66.HECRASController")
# 2. Open project: com_rc.Project_Open(project_path)
# 3. Create session lock for crash recovery
# 4. Execute operation
# 5. Close HEC-RAS: com_rc.QuitRas()
# 6. Clean up session tracking

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:

# List tracked processes
df = RasControl.list_processes()
print(df)  # Shows PID, tracked status, project, age

# List all ras.exe (including untracked)
df_all = RasControl.list_processes(show_all=True)

Orphan Detection and Cleanup

After crashes or Jupyter kernel restarts:

# Scan for orphaned processes
orphans = RasControl.scan_orphans()
if orphans:
    print(f"Found {len(orphans)} orphaned processes")

# Interactive cleanup (prompts for confirmation)
RasControl.cleanup_orphans()

# Automatic cleanup (no prompts)
count = RasControl.cleanup_orphans(interactive=False)

# Dry run (see what would be cleaned)
RasControl.cleanup_orphans(dry_run=True)

# Nuclear option - kill ALL ras.exe (requires "YES" confirmation)
RasControl.force_cleanup_all()

Watchdog Protection

For long-running operations in Jupyter:

# With watchdog (default) - survives kernel restarts
success, msgs = RasControl.run_plan("01", use_watchdog=True, max_runtime=3600)

# Without watchdog (not recommended in Jupyter)
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")

# DataFrame columns:
# - river, reach, node_id (location)
# - profile (profile name)
# - wsel (water surface elevation)
# - velocity, flow, froude, energy, max_depth, min_ch_el

Unsteady Results with Datetime

df = RasControl.get_unsteady_results("01")

# DataFrame columns:
# - river, reach, node_id (location)
# - time_index (1 = Max WS, 2+ = timesteps)
# - time_string ("Max WS" or "18FEB1999 0000")
# - datetime (datetime64[ns], NaT for Max WS)
# - wsel, velocity, flow, froude, energy, max_depth, min_ch_el

Computation Messages

# Read computation messages (tries .txt then HDF)
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:
    # Clone plan for this version
    new_plan = RasPlan.clone_plan("01", new_shortid=f"v{version_code}")

    # Run with this version
    init_ras_project(project_path, version_name)
    RasControl.run_plan(new_plan, force_recompute=True)

    # Extract results
    results[version_name] = RasControl.get_unsteady_results(new_plan)

# Compare across versions
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}")

    # Clean up any orphaned processes
    RasControl.cleanup_orphans(interactive=False)

    # Read computation messages for diagnosis
    comp_msgs = RasControl.get_comp_msgs("01")
    print(f"Computation messages:\n{comp_msgs}")

Pattern: Extract Before Running

# Check if results are current 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")

# Extract results (works whether run or skipped)
df = RasControl.get_unsteady_results("01")

Troubleshooting

COM Object Not Found

# Error: "COM object not found" or "Class not registered"

# Verify HEC-RAS COM registration
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

# Check for orphaned processes
RasControl.list_processes(show_all=True)

# Clean up orphans
RasControl.cleanup_orphans()

# If still stuck, nuclear option (kills ALL ras.exe)
RasControl.force_cleanup_all()

Results Extraction Fails

# If get_steady_results() or get_unsteady_results() fails:

# 1. Check if plan was executed
success, msgs = RasControl.run_plan("01", force_recompute=True)

# 2. Check computation messages
comp_msgs = RasControl.get_comp_msgs("01")
print(comp_msgs)

# 3. Look for "error" or "warning" in messages
if "error" in comp_msgs.lower():
    print("Computation had errors - fix model issues")

Version Mismatch

# Error: Version 'X.Y' not supported

# Check supported versions
print(RasControl.VERSION_MAP.keys())

# Use normalized format
init_ras_project(path, "5.0.6")  # Not "5.06" or "5.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

  • Large unsteady simulations may consume significant RAM
  • Use max_times parameter to limit extraction:

``python df = RasControl.getunsteadyresults("01", max_times=20) ``

Migration Path: RasControl to RasCmdr

When upgrading to HEC-RAS 6.x+:

# Legacy (RasControl - HEC-RAS 5.x)
init_ras_project(path, "5.0.6")
RasControl.run_plan("01")
df = RasControl.get_steady_results("01")

# Modern (RasCmdr - HEC-RAS 6.x)
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):

  • hecrascomputeplans -- Preferred: modern RasCmdr execution (HEC-RAS 6.x+)
  • hecrasextractresults -- Downstream: extract results after COM execution

Primary sources:

  • ras_commander/RasControl.py -- HECRASController wrapper
  • examples/120automatingraswithwin32com.ipynb -- COM automation tutorial
  • examples/121legacyhecrascontrollerandrascontrol.ipynb -- RasControl patterns