Claude Code Plugins

Community-maintained marketplace

Feedback
35
0

|

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name ebfe-validator
model sonnet
description Validate organized eBFE/BLE model using ras-commander dataframes. Uses init_ras_project() then checks plan_df, boundary_df, rasmap_df to verify: - All plan files exist - All DSS files exist with relative paths - All terrain files exist with relative paths - All HDF results accessible - No absolute paths (would cause GUI popups) Use after organizing eBFE model to verify it's actually runnable. Generates validation report and script for user re-verification.

eBFE Model Validator Skill

Purpose

Validate organized eBFE models using ras-commander's built-in dataframe validation capabilities.

Why This Matters: Not enough to just organize files - must verify the HEC-RAS project is actually runnable using ras-commander's own validation.

Validation Using ras-commander Dataframes

Step 1: Initialize Project

from ras_commander import init_ras_project
from pathlib import Path

# Initialize organized model
ras = init_ras_project(organized_ras_folder, version)

# If this succeeds, basic project structure is valid
# Now check dataframes for path validity

Step 2: Validate plan_df

Check all plan file references:

print("Validating Plans (plan_df)...")

for idx, row in ras.plan_df.iterrows():
    plan_number = row['plan_number']

    checks = {}

    # Check plan file exists
    plan_file = Path(row['plan_file'])
    checks['plan_file_exists'] = plan_file.exists()

    # Check geometry file exists
    if 'geom_file' in row and pd.notna(row['geom_file']):
        geom_file = Path(row['geom_file'])
        checks['geom_file_exists'] = geom_file.exists()

    # Check flow file exists
    if 'flow_file' in row and pd.notna(row['flow_file']):
        flow_file = Path(row['flow_file'])
        checks['flow_file_exists'] = flow_file.exists()

    # Check HDF file exists (pre-run results)
    if 'hdf_path' in row and pd.notna(row['hdf_path']):
        hdf_file = Path(row['hdf_path'])
        checks['hdf_exists'] = hdf_file.exists()
        if hdf_file.exists():
            print(f"  ✓ Plan {plan_number}: Pre-run results found")

    # Check for absolute paths (CRITICAL)
    checks['no_absolute_paths'] = not plan_file.is_absolute()

    if all(v for k, v in checks.items() if v is not None):
        print(f"  ✓ Plan {plan_number}: All checks passed")
    else:
        failed = [k for k, v in checks.items() if v is False]
        print(f"  ✗ Plan {plan_number}: Failed checks: {failed}")

Step 3: Validate boundary_df (DSS Files)

Check all DSS boundary condition references:

print("\nValidating Boundary Conditions (boundary_df)...")

if hasattr(ras, 'boundary_df') and ras.boundary_df is not None:
    for idx, row in ras.boundary_df.iterrows():
        if 'dss_file' in row and pd.notna(row['dss_file']):
            dss_path = Path(row['dss_file'])

            # CRITICAL: Check if absolute (causes GUI popup)
            if dss_path.is_absolute():
                print(f"  ✗ FAIL: Absolute DSS path: {dss_path}")
                print(f"    Will cause 'DSS path needs correction' GUI popup")
                print(f"    AUTOMATION BLOCKER - must fix")
                continue

            # Check if file exists
            if dss_path.exists():
                print(f"  ✓ PASS: DSS found: {dss_path}")
            else:
                # Try relative to project
                dss_resolved = ras.prj_file.parent / dss_path
                if dss_resolved.exists():
                    print(f"  ✓ PASS: DSS found (relative): {dss_path}")

                    # Validate DSS pathname contents
                    from ras_commander.dss import RasDss
                    catalog = RasDss.get_catalog(dss_resolved)
                    print(f"    Contains {len(catalog)} pathname(s)")

                    # Validate pathnames
                    for pathname in catalog['pathname']:
                        result = RasDss.check_pathname(dss_resolved, pathname)
                        if not result.is_valid:
                            print(f"    ⚠️ Invalid pathname: {pathname}")
                else:
                    print(f"  ✗ FAIL: DSS not found: {dss_path}")
                    print(f"    Model will not run")

Step 4: Validate rasmap_df (Terrain Files)

Check terrain file references:

print("\nValidating Terrain (rasmap_df)...")

if hasattr(ras, 'rasmap_df') and ras.rasmap_df is not None:
    for idx, row in ras.rasmap_df.iterrows():
        if 'terrain_file' in row and pd.notna(row['terrain_file']):
            terrain_path = Path(row['terrain_file'])

            # CRITICAL: Check if absolute
            if terrain_path.is_absolute():
                print(f"  ✗ FAIL: Absolute terrain path: {terrain_path}")
                print(f"    Will cause errors in RAS Mapper")
                continue

            # Check if file exists
            if terrain_path.exists():
                print(f"  ✓ PASS: Terrain found: {terrain_path}")

                # Validate using RasMap
                from ras_commander import RasMap
                is_valid = RasMap.is_valid_layer(terrain_path, layer_type='terrain')
                if is_valid:
                    print(f"    ✓ Terrain layer valid")
                else:
                    print(f"    ⚠️ Terrain layer validation failed")
            else:
                # Try relative to project
                terrain_resolved = ras.prj_file.parent / terrain_path
                if terrain_resolved.exists():
                    print(f"  ✓ PASS: Terrain found (relative): {terrain_path}")
                else:
                    print(f"  ✗ FAIL: Terrain not found: {terrain_path}")
                    print(f"    Model will not run")

                    # Search for terrain file
                    terrain_name = terrain_path.name
                    found = list(ras.prj_file.parent.glob(f'**/{terrain_name}'))
                    if found:
                        print(f"    Found at: {found[0]}")
                        print(f"    .rasmap needs correction to: {found[0].relative_to(ras.prj_file.parent)}")

Step 5: Validation Summary

print("\n" + "="*80)
print("Validation Summary")
print("="*80)

summary = {
    'plans_checked': len(ras.plan_df),
    'plans_valid': plans_valid_count,
    'dss_checked': dss_count,
    'dss_valid': dss_valid_count,
    'terrain_checked': terrain_count,
    'terrain_valid': terrain_valid_count,
    'absolute_paths_found': absolute_path_count,
    'all_checks_passed': all_checks_passed
}

print(f"\nPlans: {summary['plans_valid']}/{summary['plans_checked']} valid")
print(f"DSS Files: {summary['dss_valid']}/{summary['dss_checked']} valid")
print(f"Terrain Files: {summary['terrain_valid']}/{summary['terrain_checked']} valid")
print(f"Absolute paths: {summary['absolute_paths_found']}")

if summary['all_checks_passed']:
    print("\n✓ MODEL IS FULLY VALIDATED AND RUNNABLE")
    print("  - All paths are relative")
    print("  - All files exist")
    print("  - Ready for HEC-RAS")
    print("  - Ready for automation (no GUI popups)")
else:
    print("\n✗ MODEL HAS ISSUES")
    print("  See validation details above")
    print("  May need additional path corrections")

return summary

Output Format

Validation Report (agent/validation_report.md)

# eBFE Model Validation Report

**Model**: {StudyArea} ({HUC8})
**Pattern**: {Pattern}
**Validated**: {Date}

## Validation Using ras-commander Dataframes

### Plan Validation (plan_df)
- Plans checked: X
- Plans valid: X
- HDF files found: X (pre-run results)
- Issues: {list any issues}

### Boundary Condition Validation (boundary_df)
- DSS files checked: X
- DSS files valid: X
- Absolute paths: X (FAIL if > 0)
- DSS pathnames validated: X,XXX
- Issues: {list any issues}

### Terrain Validation (rasmap_df)
- Terrain files checked: X
- Terrain files valid: X
- Absolute paths: X (FAIL if > 0)
- Issues: {list any issues}

## Overall Status

{✓ PASS or ✗ FAIL}

{If PASS}: Model is fully validated and runnable
{If FAIL}: See issues above, additional path corrections needed

Validation Script (validate_{model}_{huc8}.py)

Agent generates standalone script for user to re-run validation

See Also

  • eBFE Agent: .claude/agents/ebfe-organizer/SUBAGENT.md - Complete agent
  • Path Validation: .claude/rules/validation/validation-patterns.md
  • DSS Validation: .claude/rules/hec-ras/dss-files.md
  • Critical Fixes: feature_dev_notes/eBFE_Integration/CRITICAL_FIXES.md