Skip to content

Architecture Overview

RAS Commander provides a comprehensive Python API for HEC-RAS automation. This page describes the library's architecture and key design patterns.

The Standard Workflow

Every RAS Commander script follows this pattern:

flowchart LR
    A["1️⃣ Initialize"] --> B["2️⃣ Configure"]
    B --> C["3️⃣ Execute"]
    C --> D["4️⃣ Extract"]

    A1["init_ras_project()"] -.-> A
    B1["RasPlan, Geom*"] -.-> B
    C1["RasCmdr.compute_plan()"] -.-> C
    D1["HdfResults*"] -.-> D

    style A fill:#4CAF50,color:#fff
    style B fill:#2196F3,color:#fff
    style C fill:#FF9800,color:#fff
    style D fill:#9C27B0,color:#fff
Python
# The 4-step pattern in code:
from ras_commander import init_ras_project, RasCmdr, HdfResultsMesh, ras

init_ras_project("/path/to/project", "6.5")  # 1. Initialize
# Optionally modify: RasPlan.set_num_cores("01", 4)  # 2. Configure
RasCmdr.compute_plan("01")                   # 3. Execute
max_wse = HdfResultsMesh.get_mesh_max_ws("01")  # 4. Extract

The Two Worlds: Config vs Results

This is the key insight for understanding which class to use:

flowchart TB
    subgraph BEFORE["📝 BEFORE Execution"]
        TXT["Plain text files<br/>.p##, .g##, .u##"]
        RAS["Ras*, Geom* classes"]
        TXT <--> RAS
    end

    subgraph AFTER["📊 AFTER Execution"]
        HDF[".p##.hdf files"]
        HDFC["Hdf* classes"]
        HDF --> HDFC
    end

    BEFORE -->|"RasCmdr.compute_plan()"| AFTER

    style BEFORE fill:#E3F2FD,stroke:#1976D2
    style AFTER fill:#FFF3E0,stroke:#F57C00
I want to... Use Example
Modify plan settings RasPlan RasPlan.set_num_cores("01", 4)
Parse geometry Geom* classes GeomCrossSection.get_station_elevation(...)
Run a simulation RasCmdr RasCmdr.compute_plan("01")
Extract results Hdf* classes HdfResultsMesh.get_mesh_max_ws("01")

Class Categories

Project Management

Class Description
RasPrj Manages HEC-RAS project state, file discovery, and DataFrames
init_ras_project() Initialize projects and set up RAS objects
RasExamples Download and manage HEC-RAS example projects

Plan Execution

Class Description
RasCmdr Execute plans via command line (single, sequential, parallel)
RasControl Legacy COM interface for HEC-RAS 3.x-6.x

File Operations

Class Description
RasPlan Plan file operations (cloning, parameters, descriptions)
RasGeo Geometry file operations (2D Manning's n land cover)
RasGeometry 1D geometry parsing (cross sections, storage, connections)
RasStruct Inline structure parsing (bridges, culverts, weirs)
RasBreach Breach parameter modification in plan files
RasUnsteady Unsteady flow file management
RasUtils General utility functions
RasMap RASMapper configuration parsing
RasDss DSS file operations for boundary conditions
RasFixit Geometry repair (blocked obstructions)

HDF Data Access

Class Description
HdfBase Core HDF operations (time parsing, attributes)
HdfPlan Plan-level information from HDF files
HdfMesh Mesh geometry data (cells, faces, points)
HdfResultsMesh Mesh results (WSE, velocity, depth)
HdfResultsPlan Plan results (volume accounting, runtime)
HdfResultsXsec 1D cross-section results
HdfStruc Structure geometry and SA/2D connections
HdfResultsBreach Dam breach results extraction
HdfHydraulicTables Cross section property tables (HTAB)
HdfPipe Pipe network analysis
HdfPump Pump station analysis
HdfFluvialPluvial Fluvial-pluvial boundary analysis
HdfBndry Boundary condition geometry features
HdfPlot, HdfResultsPlot Visualization utilities

Design Patterns

Static Class Pattern

Most RAS Commander classes use static methods with no instantiation required:

Python
# Correct - static method call
RasCmdr.compute_plan("01")
RasPlan.set_num_cores("01", 4)

# Incorrect - don't instantiate
# cmd = RasCmdr()  # Not needed

The @log_call decorator provides automatic logging:

Python
from ras_commander import RasCmdr

# Call is automatically logged at DEBUG level
success = RasCmdr.compute_plan("01")

Global vs Named RAS Objects

For single projects, use the global ras object:

Python
from ras_commander import init_ras_project, ras

init_ras_project("/path/to/project", "6.5")
print(ras.plan_df)  # Global object populated

For multiple projects, create named instances:

Python
from ras_commander import RasPrj, init_ras_project

project1 = RasPrj()
init_ras_project("/path/project1", "6.5", ras_object=project1)

project2 = RasPrj()
init_ras_project("/path/project2", "6.5", ras_object=project2)

# Always specify which project
RasCmdr.compute_plan("01", ras_object=project1)

Input Standardization

The @standardize_input decorator accepts multiple input types:

Python
from ras_commander import HdfResultsMesh

# All of these work:
HdfResultsMesh.get_mesh_max_ws("01")              # Plan number
HdfResultsMesh.get_mesh_max_ws(1)                 # Integer
HdfResultsMesh.get_mesh_max_ws(Path("project.p01.hdf"))  # Path
HdfResultsMesh.get_mesh_max_ws("/full/path.hdf")  # String path

Plain Text vs HDF Separation

The library separates plain text file operations (Ras classes) from HDF operations (Hdf classes):

  • Ras* classes: Read/write plan files (.p##), geometry files (.g##), unsteady files (.u##)
  • Hdf* classes: Read HDF results files (.p##.hdf) and preprocessed geometry (.g##.hdf)

Example with dam breach:

Python
from ras_commander import RasBreach, HdfResultsBreach

# Plain text: modify breach parameters in plan file
RasBreach.update_breach_block("01", "Dam1", start_time=10.0)

# HDF: extract breach results after computation
summary = HdfResultsBreach.get_breach_summary("01")

Data Flow

Text Only
Project Folder
    ├── .prj file ─────────────────► init_ras_project()
    │                                       │
    ├── .p## plan files ───────────────────►├── ras.plan_df
    ├── .g## geometry files ───────────────►├── ras.geom_df
    ├── .f## steady flow files ────────────►├── ras.flow_df
    ├── .u## unsteady flow files ──────────►├── ras.unsteady_df
    │                                       └── ras.boundaries_df
    ├── RasCmdr.compute_plan() ─────────────► HEC-RAS Execution
    └── .p##.hdf result files ──────────────► Hdf* classes
                                                  ├── HdfResultsMesh
                                                  ├── HdfResultsXsec
                                                  └── HdfResultsPlan

Module Organization

Text Only
ras_commander/
├── __init__.py           # Main exports
├── RasPrj.py             # Project management
├── RasCmdr.py            # Plan execution
├── RasPlan.py            # Plan file operations
├── RasGeo.py             # Geometry operations
├── RasUnsteady.py        # Unsteady flow files
├── RasUtils.py           # Utilities
├── RasExamples.py        # Example project management
├── RasMap.py             # RASMapper parsing
├── RasControl.py         # Legacy COM interface
├── hdf/                  # HDF submodule
│   ├── HdfBase.py
│   ├── HdfPlan.py
│   ├── HdfMesh.py
│   ├── HdfResults*.py
│   └── ...
├── geom/                 # Geometry parsing submodule
│   ├── RasGeometry.py
│   ├── RasStruct.py
│   └── ...
├── dss/                  # DSS file operations
│   └── RasDss.py
├── fixit/                # Geometry repair
│   ├── RasFixit.py
│   ├── obstructions.py
│   └── log_parser.py
└── remote/               # Remote execution
    ├── LocalWorker.py
    ├── PsexecWorker.py
    ├── DockerWorker.py
    └── ...

Function Naming Conventions

Function names follow the conventions of their underlying data source:

RasControl (Legacy COM)

Uses abbreviated names matching HECRASController:

Python
RasControl.get_comp_msgs()    # Matches .comp_msgs.txt file naming

HdfResultsPlan (Modern HDF)

Uses descriptive names matching HDF structure:

Python
HdfResultsPlan.get_compute_messages()  # Matches HDF dataset naming

This is intentional - each reflects the conventions of its technology source.

Error Handling

The library uses Python exceptions with informative messages:

Python
from ras_commander import init_ras_project

try:
    init_ras_project("/nonexistent/path", "6.5")
except FileNotFoundError as e:
    print(f"Project not found: {e}")
except ValueError as e:
    print(f"Invalid parameter: {e}")

All operations are logged via the centralized LoggingConfig:

Python
import logging

# Increase verbosity
logging.getLogger('ras_commander').setLevel(logging.DEBUG)
CLB Engineering Corporation  ·  LLM Forward Engineering
RAS Commander is a free and open-source project maintained by CLB Engineering Corporation. For agencies and firms seeking to modernize H&H workflows with LLM Forward approaches, contact CLB to partner with the engineers who wrote the automation.