Skip to content

Advanced Structure Validation with RasCheck

This notebook demonstrates the advanced structure validation features added to RasCheck in December 2025:

  • Culvert hydraulics validation (CV_LF_01, CV_LF_02, CV_CF_01, CV_CF_02, CV_TF_04)
  • Starting WSE method validation (PF_IC_00, PF_IC_01, PF_IC_02, PF_IC_03, PF_IC_04)
Python
# =============================================================================
# DEVELOPMENT MODE TOGGLE
# =============================================================================
USE_LOCAL_SOURCE = True  # <-- Set to True for check module (in development)

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")
    print("⚠️  WARNING: Check module may not be available in pip package yet")

# Import ras-commander
from ras_commander import HdfPlan, HdfResultsPlan, HdfStruc, RasCheck, RasCmdr, RasExamples, init_ras_project, ras

# Verify which version loaded
import ras_commander
print(f"✓ Loaded: {ras_commander.__file__}")
Text Only
📁 LOCAL SOURCE MODE: Loading from C:\GH\ras-commander/ras_commander


2025-12-30 09:52:54 - numexpr.utils - INFO - NumExpr defaulting to 8 threads.


✓ Loaded: C:\GH\ras-commander\ras_commander\__init__.py

Parameters

Configure these values to customize the notebook for your project.

Python
# =============================================================================
# PARAMETERS - Edit these to customize the notebook
# =============================================================================
from pathlib import Path

# Project Configuration
PROJECT_NAME = "ConSpan Culvert"  # Steady flow culvert project (fast execution ~10 sec)
RAS_VERSION = "7.0"               # HEC-RAS version (6.3, 6.5, 6.6, etc.)
SUFFIX = "801"                    # Notebook identifier for project extraction

# Execution Settings
PLAN = "01"                       # Plan number to execute (will be updated based on available plans)
NUM_CORES = 4                     # CPU cores for 2D computation

# Note: All outputs are saved within the extracted project folder
print(f"Project will be extracted to: example_projects/{PROJECT_NAME}_{SUFFIX}/")
Text Only
Project will be extracted to: example_projects/ConSpan Culvert_801/

Import Required Modules

Python
from ras_commander import (
    RasExamples, init_ras_project, ras,
    RasCmdr, HdfResultsPlan
)
from ras_commander.hdf import HdfStruc, HdfPlan
from ras_commander.check import (
    RasCheck, CheckResults, Severity,
    RasCheckReport, ReportMetadata,
    get_default_thresholds
)

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from pathlib import Path

# Set pandas display options
pd.set_option('display.max_rows', 20)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)

Extract and Initialize Project

We'll use the ConSpan Culvert example which is a steady flow project with culvert structures. This project executes quickly (~10 seconds) making it ideal for automated testing.

Verification for Structure Validation

After running structure validation checks:

  • [ ] All culvert flow classifications are reasonable (Inlet/Outlet control)
  • [ ] Bridge expansion coefficients < 0.5 (FHWA HDS-1 guidance)
  • [ ] Starting WSE within 0.5 ft of computed water surface
  • [ ] Structure geometry matches as-built dimensions

References: - FHWA HDS-1: Bridge Hydraulics - FHWA HDS-5: Culvert Hydraulics - USACE EM 1110-2-1416, Chapter 12: Hydraulic Structures

Python
# Extract the Bald Eagle Creek example project
project_path = RasExamples.extract_project(PROJECT_NAME, suffix=SUFFIX)
print(f"Extracted project to: {project_path}")
Text Only
2025-12-30 09:52:56 - ras_commander.RasExamples - INFO - Found zip file: C:\GH\ras-commander\examples\Example_Projects_6_6.zip


2025-12-30 09:52:56 - ras_commander.RasExamples - INFO - Loading project data from CSV...


2025-12-30 09:52:56 - ras_commander.RasExamples - INFO - Loaded 68 projects from CSV.


2025-12-30 09:52:56 - ras_commander.RasExamples - INFO - ----- RasExamples Extracting Project -----


2025-12-30 09:52:56 - ras_commander.RasExamples - INFO - Extracting project 'ConSpan Culvert' as 'ConSpan Culvert_801'


2025-12-30 09:52:56 - ras_commander.RasExamples - INFO - Folder 'ConSpan Culvert_801' already exists. Deleting existing folder...


2025-12-30 09:52:56 - ras_commander.RasExamples - INFO - Existing folder 'ConSpan Culvert_801' has been deleted.


2025-12-30 09:52:56 - ras_commander.RasExamples - INFO - Successfully extracted project 'ConSpan Culvert' to C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801


Extracted project to: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801
Python
# Initialize the project
init_ras_project(project_path, RAS_VERSION)
print(f"Initialized project: {ras.project_name}")

# View available plans
print("\nAvailable plans:")
display(ras.plan_df[['plan_number', 'Plan Title', 'flow_type']])
Text Only
2025-12-30 09:52:56 - ras_commander.RasPrj - INFO - No unsteady flow files found in the project.


2025-12-30 09:52:56 - ras_commander.RasMap - INFO - Successfully parsed RASMapper file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.rasmap


Initialized project: ConSpan

Available plans:
plan_number Plan Title flow_type
0 01 ConSpan Culvert Steady
1 02 Twin Circular Culverts Steady
Python
# Find a steady flow plan for structure validation
steady_plans = ras.plan_df[ras.plan_df['flow_type'] == 'Steady']

if steady_plans.empty:
    print("⚠️  No steady flow plans found - using first available plan")
    plan_number = ras.plan_df.iloc[0]['plan_number']
else:
    # Use plan 02 if available, otherwise first steady plan
    if '02' in steady_plans['plan_number'].values:
        plan_number = '02'
    else:
        plan_number = steady_plans.iloc[0]['plan_number']

print(f"Selected plan: {plan_number} ({ras.plan_df[ras.plan_df['plan_number']==plan_number].iloc[0]['flow_type']})")

# Execute the plan (skip if results already exist)
print(f"Running Plan {plan_number}...")
success = RasCmdr.compute_plan(plan_number, skip_existing=True)
if success:
    print(f"✓ Plan {plan_number} ready for validation")
else:
    print(f"✗ Plan {plan_number} execution failed")
Text Only
2025-12-30 09:52:56 - ras_commander.RasCmdr - INFO - Using ras_object with project folder: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801


2025-12-30 09:52:56 - ras_commander.RasCmdr - INFO - Running HEC-RAS from the Command Line:


2025-12-30 09:52:56 - ras_commander.RasCmdr - INFO - Running command: "C:\Program Files (x86)\HEC\HEC-RAS\6.6\Ras.exe" -c "C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.prj" "C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02"


Selected plan: 02 (Steady)
Running Plan 02...


2025-12-30 09:52:59 - ras_commander.RasCmdr - INFO - HEC-RAS execution completed for plan: 02


2025-12-30 09:52:59 - ras_commander.RasCmdr - INFO - Total run time for plan 02: 2.82 seconds


✓ Plan 02 ready for validation
Python
# Display results summary from results_df
ras.results_df[['plan_number', 'plan_title', 'completed', 'has_errors', 'has_warnings', 'runtime_complete_process_hours']]
Python
# Get HDF paths with defensive checking
print(f"DEBUG: Looking for plan '{plan_number}'")
print(f"DEBUG: Available plan numbers: {ras.plan_df['plan_number'].tolist()}")

# Filter for the plan
filtered_plans = ras.plan_df[ras.plan_df['plan_number'] == plan_number]
print(f"DEBUG: Filtered result shape: {filtered_plans.shape}")

# Defensive check before accessing
if filtered_plans.empty:
    raise ValueError(
        f"Plan '{plan_number}' not found in project. "
        f"Available plans: {ras.plan_df['plan_number'].tolist()}"
    )

plan_row = filtered_plans.iloc[0]
plan_hdf = Path(plan_row['HDF_Results_Path'])

# Geometry HDF has .g##.hdf suffix (NOT .hdf replacing .g##)
geom_path = Path(plan_row['Geom Path'])
geom_hdf = Path(str(geom_path) + '.hdf')  # e.g., geometry.g01.hdf

print(f"Plan HDF: {plan_hdf}")
print(f"Geom HDF: {geom_hdf}")

# Verify files exist
if not plan_hdf.exists():
    print(f"⚠️  WARNING: Plan HDF not found: {plan_hdf}")
if not geom_hdf.exists():
    print(f"⚠️  WARNING: Geom HDF not found: {geom_hdf}")
Text Only
DEBUG: Looking for plan '02'
DEBUG: Available plan numbers: ['01', '02']
DEBUG: Filtered result shape: (1, 21)
Plan HDF: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf
Geom HDF: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf

Part 1: Culvert Hydraulics Extraction

The new HdfStruc.get_culvert_hydraulics() function extracts comprehensive culvert data from geometry HDF files.

Python
# Extract culvert hydraulic properties
culvert_data = HdfStruc.get_culvert_hydraulics(geom_hdf)

if not culvert_data.empty:
    print(f"Found {len(culvert_data)} culverts in geometry")
    print(f"\nColumns: {list(culvert_data.columns)}")
    display(culvert_data)
else:
    print("No culverts found in this project")
Text Only
2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - ERROR - Error reading culvert hydraulics from C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf: Cannot use .str.contains with values of inferred dtype 'bytes'.


No culverts found in this project

Culvert Hydraulics Data Fields

Field Description FHWA Reference
Structure_ID Unique culvert identifier -
Flow_Regime Flow regime setting (e.g., "Pressure and Weir Flow") HDS-5
Entrance_Coefficient Entrance loss coefficient (Ke) HDS-5 Table 1
Exit_Coefficient Exit loss coefficient (Kx) Typically 1.0
Scale_Factor Culvert scale factor -
Chart Chart selection for culvert analysis HDS-5

Reference: FHWA HDS-5 "Hydraulic Design of Highway Culverts"

Visualize Culvert Coefficients

Compare entrance and exit coefficients against FHWA guidelines:

Python
if not culvert_data.empty and 'Entrance_Coefficient' in culvert_data.columns:
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

    # Entrance coefficients
    ax1.barh(culvert_data['Structure_ID'], culvert_data['Entrance_Coefficient'], color='steelblue')
    ax1.axvline(0.2, color='red', linestyle='--', label='FHWA Min (0.2)')
    ax1.axvline(1.0, color='orange', linestyle='--', label='FHWA Max (1.0)')
    ax1.set_xlabel('Entrance Coefficient (Ke)')
    ax1.set_ylabel('Structure ID')
    ax1.set_title('Culvert Entrance Loss Coefficients')
    ax1.legend()
    ax1.grid(True, alpha=0.3)

    # Exit coefficients
    ax2.barh(culvert_data['Structure_ID'], culvert_data['Exit_Coefficient'], color='forestgreen')
    ax2.axvline(1.0, color='red', linestyle='--', label='Typical Value (1.0)')
    ax2.set_xlabel('Exit Coefficient (Kx)')
    ax2.set_ylabel('Structure ID')
    ax2.set_title('Culvert Exit Loss Coefficients')
    ax2.legend()
    ax2.grid(True, alpha=0.3)

    plt.tight_layout()
    plt.show()
else:
    print("No culvert coefficient data available for visualization")
Text Only
No culvert coefficient data available for visualization

Part 2: Culvert Validation Checks

RasCheck now includes 5 culvert validation checks:

Check ID Description Severity
CV_LF_01 Entrance loss coefficient out of FHWA range (0.2-1.0) WARNING
CV_LF_02 Exit loss coefficient deviates from typical (1.0) WARNING
CV_CF_01 Chart selection may not be appropriate WARNING
CV_CF_02 Flow regime classification questionable WARNING
CV_TF_04 Multiple barrel flow distribution issues WARNING
Python
# Extract steady profiles
profiles = HdfResultsPlan.get_steady_profile_names(plan_hdf)
print(f"Profiles: {profiles}")

# Run structure checks (includes culvert validation)
structure_results = RasCheck.check_structures(plan_hdf, geom_hdf, profiles)

print(f"Structure Check Results:")
print(f"  Total Messages: {len(structure_results.messages)}")
print(f"  Errors: {structure_results.get_error_count()}")
print(f"  Warnings: {structure_results.get_warning_count()}")
Text Only
2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Found 4 steady state profiles: ['5 yr', '10 yr', '25 yr', '50 yr']


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - WARNING - Dataset not found: Geometry/Structures/Bridge Coefficient Attributes


2025-12-30 09:52:59 - ras_commander.hdf.HdfBase - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfBase - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfBase - CRITICAL - No valid projection found. Checked:
1. HDF file projection attribute: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf
 was checked and no projection attribute found2. No RASMapper projection file found
To fix this:
1. Open RASMapper
2. Click Map > Set Projection
3. Select an appropriate projection file or coordinate system
4. Save the RASMapper project


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - WARNING - Bridge Coefficient Attributes missing or 'Structure ID' not present.


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Successfully extracted structures GeoDataFrame.


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Successfully extracted structures GeoDataFrame with attributes.


Profiles: ['5 yr', '10 yr', '25 yr', '50 yr']
Structure Check Results:
  Total Messages: 3
  Errors: 0
  Warnings: 3
Python
# Filter for culvert-specific messages (CV_ prefix)
culvert_msgs = [msg for msg in structure_results.messages if msg.message_id.startswith('CV_')]

if culvert_msgs:
    print(f"Found {len(culvert_msgs)} culvert validation messages:\n")
    for msg in culvert_msgs:
        print(f"[{msg.severity.value}] {msg.message_id}: {msg.message}")
        if msg.help_text:
            print(f"  → {msg.help_text}")
        print()
else:
    print("✓ No culvert validation issues found")
Text Only
✓ No culvert validation issues found

Culvert Check Details

CV_LF_01: Entrance Loss Coefficient

What it checks: Entrance loss coefficients (Ke) should be within FHWA guidelines (0.2 to 1.0)

Why it matters: - Too low (<0.2): Underestimates entrance losses, overpredicts capacity - Too high (>1.0): Overestimates losses, underpredicts capacity

FHWA Reference: HDS-5 Table 1 - Entrance Loss Coefficients

CV_LF_02: Exit Loss Coefficient

What it checks: Exit loss coefficients (Kx) typically should be 1.0

Why it matters: Exit losses represent full velocity head recovery. Values other than 1.0 should be justified.

CV_CF_01 & CV_CF_02: Chart and Flow Regime

What it checks: Appropriate chart selection and flow regime classification

Why it matters: Using the wrong chart or flow regime leads to incorrect culvert performance predictions.

CV_TF_04: Multiple Barrel Distribution

What it checks: Flow distribution among multiple barrels

Why it matters: Unequal flow distribution can cause unexpected hydraulic behavior.


Part 3: Starting WSE Method Extraction

The new HdfPlan.get_starting_wse_method() function extracts initial condition methods from plan HDF files.

Python
# Extract starting WSE method
wse_method = HdfPlan.get_starting_wse_method(plan_hdf)

print("Starting Water Surface Elevation Method:")
print("="*50)
for key, value in wse_method.items():
    print(f"  {key}: {value}")
Text Only
2025-12-30 09:52:59 - ras_commander.hdf.HdfPlan - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfPlan - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfPlan - WARNING - Starting WSE method not found in C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfPlan - INFO - Successfully extracted starting WSE method: Unknown


Starting Water Surface Elevation Method:
==================================================
  method: Unknown
  note: Boundary condition method not found in HDF file

Starting WSE Methods Explained

Method When to Use Parameters
Normal Depth Subcritical flow, mild slope Requires friction slope
Critical Depth Supercritical flow (Fr > 1.0) None
Known WSE Specific boundary elevation available Requires WSE value
EGL Slope Line Gradually varied flow Requires energy slope

Note: The starting WSE method applies at the downstream boundary for steady flow computations.

Python
# Visualize method parameters if applicable
method = wse_method.get('method', 'Unknown')

if 'Normal' in method and 'slope' in wse_method:
    slope = wse_method['slope']
    print(f"\nNormal Depth Analysis:")
    print(f"  Friction Slope: {slope:.6f}")
    print(f"  Slope as ratio: 1:{1/slope:.0f}" if slope > 0 else "  Slope: Invalid")

    # Check reasonableness
    if abs(slope) < 0.0001:
        print("  ⚠️  WARNING: Very flat slope - may cause convergence issues")
    elif abs(slope) > 0.1:
        print("  ⚠️  WARNING: Very steep slope - verify this is correct")
    else:
        print("  ✓ Slope appears reasonable")

elif 'Known' in method and 'wse' in wse_method:
    wse_value = wse_method['wse']
    print(f"\nKnown WSE Analysis:")
    print(f"  Specified WSE: {wse_value:.2f} ft")

    # Check reasonableness
    if wse_value < -100 or wse_value > 10000:
        print("  ⚠️  WARNING: WSE may be unreasonable for this project")
    else:
        print("  ✓ WSE appears reasonable")

Part 4: Starting WSE Validation Checks

RasCheck now includes 4 starting WSE validation checks:

Check ID Description Severity
PF_IC_00 Starting WSE method could not be determined WARNING
PF_IC_01 Known WSE may be unreasonable WARNING
PF_IC_02 Normal depth slope may cause convergence issues WARNING
PF_IC_03 Critical depth used (informational) INFO
PF_IC_04 EGL slope method used (informational) INFO
Python
# Run profile checks (includes starting WSE validation)
profile_results = RasCheck.check_profiles(plan_hdf, profiles)

print(f"Profile Check Results:")
print(f"  Total Messages: {len(profile_results.messages)}")
print(f"  Errors: {profile_results.get_error_count()}")
print(f"  Warnings: {profile_results.get_warning_count()}")
print(f"  Info: {len([m for m in profile_results.messages if m.severity == Severity.INFO])}")
Text Only
2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Extracted steady results: 40 rows (4 profiles x 10 cross sections)


Profile Check Results:
  Total Messages: 127
  Errors: 0
  Warnings: 100
  Info: 27
Python
# Filter for starting WSE messages (PF_IC_ prefix)
wse_msgs = [msg for msg in profile_results.messages if msg.message_id.startswith('PF_IC_')]

if wse_msgs:
    print(f"Found {len(wse_msgs)} starting WSE validation messages:\n")
    for msg in wse_msgs:
        print(f"[{msg.severity.value}] {msg.message_id}: {msg.message}")
        if msg.help_text:
            print(f"  → {msg.help_text}")
        print()
else:
    print("✓ No starting WSE validation issues found")
Text Only
✓ No starting WSE validation issues found

Starting WSE Check Details

PF_IC_01: Known WSE Range

What it checks: Known WSE values should be within realistic range (-100 to 10,000 ft)

Why it matters: Extreme values likely indicate data entry errors.

PF_IC_02: Normal Depth Slope

What it checks: - Very flat slopes (<0.0001) may cause convergence problems - Very steep slopes (>0.1) are unusual and should be verified

Why it matters: Inappropriate slopes lead to computational instability or incorrect boundary conditions.

PF_IC_03: Critical Depth Appropriateness

What it checks: Critical depth is appropriate when Froude number > 1.0 (supercritical flow)

Why it matters: Using critical depth for subcritical flow is incorrect.

PF_IC_04: EGL Method Verification

What it checks: Energy grade line method is appropriate for gradually varied flow

Why it matters: Verifies boundary condition method matches flow regime.


Part 5: Comprehensive Validation Report

Generate a complete validation report including all new checks:

Python
# Run all checks
all_results = RasCheck.run_all(plan_number)

print("Complete Validation Results:")
print("="*50)
print(f"  Total Messages: {len(all_results.messages)}")
print(f"  Errors: {all_results.get_error_count()}")
print(f"  Warnings: {all_results.get_warning_count()}")
print(f"  Info: {len([m for m in all_results.messages if m.severity == Severity.INFO])}")
Text Only
2025-12-30 09:52:59 - ras_commander.check.RasCheck - INFO - Detected flow type: steady


2025-12-30 09:52:59 - ras_commander.check.RasCheck - WARNING - Could not check structure transition coefficients: could not convert string to float: '20.208*'


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Extracted steady results: 40 rows (4 profiles x 10 cross sections)


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - WARNING - Dataset not found: Geometry/Structures/Bridge Coefficient Attributes


2025-12-30 09:52:59 - ras_commander.hdf.HdfBase - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfBase - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfBase - CRITICAL - No valid projection found. Checked:
1. HDF file projection attribute: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.g02.hdf
 was checked and no projection attribute found2. No RASMapper projection file found
To fix this:
1. Open RASMapper
2. Click Map > Set Projection
3. Select an appropriate projection file or coordinate system
4. Save the RASMapper project


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - WARNING - Bridge Coefficient Attributes missing or 'Structure ID' not present.


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Successfully extracted structures GeoDataFrame.


2025-12-30 09:52:59 - ras_commander.hdf.HdfStruc - INFO - Successfully extracted structures GeoDataFrame with attributes.


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Using existing Path object HDF file: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ConSpan.p02.hdf


2025-12-30 09:52:59 - ras_commander.hdf.HdfResultsPlan - INFO - Extracted steady results: 40 rows (4 profiles x 10 cross sections)


Complete Validation Results:
==================================================
  Total Messages: 168
  Errors: 0
  Warnings: 127
  Info: 41
Python
# Show new check coverage
new_check_ids = ['CV_LF_01', 'CV_LF_02', 'CV_CF_01', 'CV_CF_02', 'CV_TF_04',
                 'PF_IC_00', 'PF_IC_01', 'PF_IC_02', 'PF_IC_03', 'PF_IC_04']

new_checks_found = [msg for msg in all_results.messages if msg.message_id in new_check_ids]

print(f"\nNew Advanced Validation Checks (9 total):")
print(f"  Messages from new checks: {len(new_checks_found)}")

if new_checks_found:
    print("\n  Check IDs triggered:")
    for check_id in set(msg.message_id for msg in new_checks_found):
        count = len([m for m in new_checks_found if m.message_id == check_id])
        print(f"    {check_id}: {count} message(s)")
Text Only
New Advanced Validation Checks (9 total):
  Messages from new checks: 0
Python
# Generate HTML report
report_path = project_path / "ras_checker" / "advanced_validation_report.html"
report_path.parent.mkdir(parents=True, exist_ok=True)

metadata = ReportMetadata(
    project_name=ras.project_name,
    project_path=project_path,
    plan_name="Steady Flow with Advanced Checks"
)

output_path = all_results.to_html(report_path, metadata=metadata)
print(f"\n✓ HTML report generated: {output_path}")
Text Only
2025-12-30 09:52:59 - ras_commander.check.report - INFO - Generated HTML report: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ras_checker\advanced_validation_report.html



✓ HTML report generated: C:\GH\ras-commander\examples\example_projects\ConSpan Culvert_801\ras_checker\advanced_validation_report.html

Summary

This notebook demonstrated the 9 new validation checks added to RasCheck:

Culvert Checks (5)

  • CV_LF_01: Entrance loss coefficient validation
  • CV_LF_02: Exit loss coefficient validation
  • CV_CF_01: Chart selection appropriateness
  • CV_CF_02: Flow regime classification
  • CV_TF_04: Multiple barrel flow distribution

Starting WSE Checks (4)

  • PF_IC_00: Method determination
  • PF_IC_01: Known WSE reasonableness
  • PF_IC_02: Normal depth slope validation
  • PF_IC_03: Critical depth applicability
  • PF_IC_04: EGL method verification

New HDF Extraction Functions

  • HdfStruc.get_culvert_hydraulics() - Extract comprehensive culvert data
  • HdfPlan.get_starting_wse_method() - Extract initial condition method
  • 300_quality_assurance_rascheck.ipynb - Comprehensive RasCheck overview
  • 302_custom_workflows_and_standards.ipynb - State-specific standards and custom workflows
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.