Skip to content

Working with eBFE Models

The Problem: eBFE Models Are Broken

FEMA's Estimated Base Flood Elevation (eBFE) database provides valuable Base Level Engineering (BLE) HEC-RAS models for 400+ study areas nationwide. However, these models are delivered in a format that makes them completely unusable without extensive manual fixes.

What's Wrong with eBFE Models

eBFE models are intentionally separated into folders that prevent them from running:

  1. Output/ Folder Separation
  2. Pre-run HDF result files (often 40+ GB) stored separately from project
  3. HEC-RAS can't find results → Can't view expected runtime
  4. Manual fix required: Move gigabytes of HDF files into project folder

  5. Terrain/ Misplacement

  6. Terrain data (often 15+ GB) placed outside project folder
  7. .rasmap files reference Terrain\RAS_Terrain\Terrain.hdf (doesn't exist)
  8. Actual terrain location: Terrain\Terrain.hdf (different path)
  9. Manual fix required: Move terrain folders + edit .rasmap XML manually

  10. Absolute and Incorrect DSS Paths

  11. DSS references use paths from original FEMA system: C:\eBFE\Projects\...
  12. Also wrong relative paths: .\DSS_Input\file.dss (subdirectory doesn't exist)
  13. HEC-RAS shows GUI popup: "DSS path needs correction"
  14. Manual fix required: Click through 30+ GUI dialogs or edit .u## files manually

User Experience Without This Library

Text Only
1. Download eBFE model (hours for large models)
2. Extract nested archives (complex structure)
3. Open in HEC-RAS → ERROR: "Terrain not found"
4. Manually move Terrain/ folder (15+ GB)
5. Open again → ERROR: "DSS path needs correction"
6. Click through GUI dialogs fixing 30+ DSS paths
7. Try to view results → ERROR: Can't find HDF files
8. Manually move Output/ folder (40+ GB)
9. Open again → ERROR: More path corrections needed
10. Edit .rasmap XML manually to fix terrain references
11. Finally works (30-120 minutes later)

Automation: Impossible - GUI error popups block automated workflows

The Solution: RasEbfeModels

The RasEbfeModels class solves this problem by applying delivery-format normalization that transforms inconsistent eBFE archives into portable source candidates with explicit validation boundaries.

Quick Start

Python
import os
from ras_commander.sources import RasEbfeModels
from ras_commander import init_ras_project
from pathlib import Path

workspace = (
    Path(os.environ.get("RAS_COMMANDER_EBFE_ROOT", r"H:\Testing\eBFE"))
    / "12100201"
)

# Download/cache, extract, and organize by model slug
organized = RasEbfeModels.organize_model(
    "upper-guadalupe",
    download_root=workspace / "raw",
    output_root=workspace / "organized",
    validate_dss=False,
)

# Open the organized source with its authored engine
init_ras_project(organized / "RAS Model/UPGU1", "6.3.1")

# Organization is not a completed-result claim. Use the documented bounded
# pre-compute workflow before describing a source as unsteady-start qualified.

Time: 15 minutes vs 60-120 minutes manual fixes

Workspace and Path-Length Rule

FEMA archives can contain deeply nested members that exceed limits still used by HEC-RAS and older Windows utilities. Preflight the maximum expanded path before extraction. The raw cache uses long-path-safe I/O when a source member is inherently too long; HEC-RAS-active organized project and run paths must remain at or below 240 characters. Configure a concise workspace with RAS_COMMANDER_EBFE_ROOT; new work on the shared Windows host uses:

Text Only
H:\Testing\eBFE\<HUC8>\
├── raw\
├── organized\
├── runs\
└── reports\

Do not create improvised folders at the drive root. ras-commander extraction uses long-path-safe I/O, restores archive timestamps, audits member sizes and CRC32 values, then writes a completion receipt. A non-empty legacy folder is audited before reuse; an incomplete cache is preserved and reported rather than silently accepted or deleted. Older validation records under H:\Testing\eBFE Model Organization remain historical evidence, but new work should use the concise layout.

To inspect the built-in model catalog:

Python
from ras_commander.sources import RasEbfeModels

RasEbfeModels.available_models()

Current import paths

Use from ras_commander.sources import RasEbfeModels for model-source organizers. The ras_commander.sources package exports model sources only. Coastal forecast helpers live under ras_commander.boundaries.CoastalBoundary.

Current built-in organizers include:

Slug HUC8 Delivery Notes
spring-creek 12040102 Single 2D model with nested final archive.
east-galveston-bay 12040202 Public 2D delivery with a copied HMS project and optional nested RAS extraction. The outer inventory does not establish the RAS version, plan/geometry IDs, flow regime, or runtime readiness.
austin-oyster 12040205 One HEC-RAS 5.07 2D unsteady project with seven plans. The compiled terrain, land cover, DSS inputs, projection, RASMapper file, geometry HDF, and seven result HDFs are delivered; deterministic reconstruction is required before runtime qualification.
north-galveston-bay 12040203 Compound HMS plus nested 2D RAS delivery.
upper-guadalupe 12100201 Four cascaded HEC-RAS 6.3.1 2D watershed models with complete modified-terrain triplets. Fresh p01 source-run qualification is tracked in the Record of Deficiencies.
san-gabriel 12070205 Five-project DSS fan-in covering the Round Rock and Florence ras2fim-2d test area. Unsteady-start validated; shared compiled terrain was not provided.
eleven-point 11010011 Small split-delivery 2D model archive; organized, path-audited, results-ready, and geometry-preprocessor validated with HEC-RAS 6.6.
spring-river 11010010 Distinct Spring HUC model archive using SpringRiver_11010010 naming to avoid confusion with spring-creek / SpringCreek_12040102.
lower-colorado-cummins 12090301 2,378 HEC-RAS 4.1.0 1D steady reach projects, each containing plan 01. There are 2,377 seven-profile projects and one delivered six-profile project. The delivery has 2,332 projects at the usual river/reach depth and 46 valid projects nested under intermediate reach groups; terrain is not required.
pedernales 12090206 530 HEC-RAS 4.1.0-era 1D steady projects. Eight misplaced delivered result/preprocessor assets are copied to their referenced projects; terrain is not applicable, not missing. All 530 selected plan-01 runs passed in isolated two-core HEC-RAS 6.6 copies.
cibolo 12100304 One HEC-RAS 5.0.7 2D unsteady project. Terrain, land cover, seven DSS inputs, and the projection are delivered; plan 14 reached owned unsteady-solver startup in an isolated two-core copy.
medina 12100302 Five HEC-RAS 6.4.1 2D unsteady projects. Four have complete modified terrain and reached owned unsteady-solver startup; UpperMedinaHeadwaters is blocked by an undelivered load-bearing modified Terrain.hdf. Land cover, infiltration, and soils are delivered for all five projects.
rio-hondo 13060008 1D steady BLE reach-model collection.
amite 08070202 Louisiana component delivery with terrain rebuild handling for CRS mismatches.
tickfaw 08070203 Large Louisiana 2D model archive.
lake-maurepas 08070204 Louisiana 2D model archive.
lower-brazos 12070104 Very large component delivery; manifest-only by default.

East Galveston Bay source boundary

east-galveston-bay is the public FEMA eBFE/BLE delivery for HUC8 12040202. It is separate from any RBFS source package. The public outer archive identifies a 2D delivery, an HEC-HMS project at Hydrology/HMS/EastGalvestonBay, and a nested Hydraulic_Models/RAS_Submittal.zip. It does not establish a HEC-RAS version, plan or geometry identifiers, flow regime, or hydraulic readiness.

Python
from pathlib import Path
from ras_commander import RasExamples
from ras_commander.sources import RasEbfeModels

# Canonical source-aware API.
organized = RasEbfeModels.organize_model(
    "east-galveston-bay",
    output_root=Path(r"D:/eBFE/organized"),
    extract_ras_nested=False,
)

# Convenience entry point; it never changes RasExamples.extract_project().
organized = RasExamples.organize_ebfe_model(
    "east-galveston-bay", output_path=Path(r"D:/eBFE/organized")
)

The organizer downloads and verified-extracts the 10.7 GB outer archive in both modes. extract_ras_nested=False retains the nested RAS submission in the raw extraction and avoids expanding it into the generated RAS Model folder. Use extract_ras_nested=True only after allocating additional local storage. It extracts Input, Terrain, and LandCover by default; the approximately 10 GB Output archive stays in the immutable source unless include_results=True is explicitly selected. A local 7-Zip CLI is required when the public outer ZIP contains Deflate64 members unsupported by the active Python runtime. The organizer records extraction state but does not execute HEC-RAS or promote a runtime qualification. Zero-byte *.sr.lock files delivered under Features/ are archived GIS session artifacts. The organizer removes them only from its generated copy and records every removed relative path in the manifest; it does not remove other locks or alter the source archive.

Austin–Oyster reconstruction boundary

The austin-oyster source entry covers eBFE HUC8 12040205. The public archive contains one HEC-RAS 5.07 2D unsteady project with seven registered plans. Its load-bearing terrain, land cover, seven DSS inputs, projection, RASMapper configuration, geometry HDF, and seven plan/result HDFs are present. The delivered Terrain.hdf contains no terrain-modification groups, matching the absence of modification layers in the delivered .rasmap; the organizer must preserve that evidence rather than rebuild or substitute terrain.

Reconstruction expands the nested archive chain, relocates fourteen delivered Output assets plus the projection file, and corrects one RASMapper projection path. The organizer also checks all twenty-eight terrain/land-cover attributes in the seven plan HDFs. Independent reconstruction found all 28 attributes already path-equivalent, so it preserved their delivered bytes and performed zero HDF mutations. The eBFE webmap's count of 29 describes its proposed metadata-repair surface, not the mutations actually required by the archive.

The two independently reviewed missing references are the optional local basemap definitions Google Map.xml and Google Hybrid.xml. They affect only RASMapper display and are not hydraulic inputs. The audit's static RasCheck sample ran against plan p03 and recorded one error; it did not start or run HEC-RAS computation. Independent CEWS validation subsequently preprocessed plan p08 (1PAC) with HEC-RAS 5.0.7 and two cores, reached an owned RasUnsteady64.exe child with the complete fresh artifact set, and stopped at the intended solver-start boundary in 64.9 seconds. This qualifies source assembly and unsteady startup, not completed results. The durable Record of Deficiencies preserves the evidence boundary and the CEWS staging location.

Pedernales, Cibolo, and Medina source boundaries

The pedernales, cibolo, and medina entries use dedicated, fail-closed organizers. They bind the public FEMA object to its expected URL, byte size, and retained multipart ETag; validate the recoverable ZIP members; and apply only the study's audited repairs in a staged copy. Fresh organizer manifests remain pending until their own copies run; durable registry qualification is recorded separately from reviewed RAS Commander receipts.

Python
from pathlib import Path

from ras_commander.sources import RasEbfeModels

root = Path(r"H:\Testing\eBFE")
for slug, huc8 in (
    ("pedernales", "12090206"),
    ("cibolo", "12100304"),
    ("medina", "12100302"),
):
    organized = RasEbfeModels.organize_model(
        slug,
        download_root=root / huc8 / "raw",
        output_root=root / huc8 / "organized",
    )

Pedernales is a corpus of 530 independent 1D steady projects. The organizer selects each project's p01/g01/f01 chain and copies eight misplaced, delivered assets to the three projects that reference them. No model in the corpus references terrain. Terrain is therefore not applicable, and its absence must not be reported as a delivery gap. All 530 path-identified p01 plans completed in isolated two-core HEC-RAS 6.6 runs. This establishes corpus runnability in 6.6; it does not claim numerical equivalence with the unavailable authored 4.10 engine. See the Pedernales Record of Deficiencies.

Cibolo is one 2D unsteady project inside a nested _Final.zip. The organizer stages the delivered compiled terrain, component rasters, VRT, Manning's-n land-cover HDF/raster, projection, and seven DSS files. It rewrites the seven active DSS references and one RASMapper projection reference. Terrain and land cover are delivered and are not rebuilt. The canonical 1% test is plan p14, geometry g05, and unsteady-flow file u02. That plan reached owned unsteady-solver startup with two cores in HEC-RAS 5.0.7. See the Cibolo Record of Deficiencies.

Medina contains Leon1, Leon2, Leon3, MiddleLowerMedina, and UpperMedinaHeadwaters. Land cover, infiltration, and soils are delivered for all five projects. Four projects also contain the compiled modified terrain used by their active geometry. UpperMedinaHeadwaters does not: its required Terrain.hdf, including the referenced UpperMedinaHW_TerrainModifications group, is absent. This is a critical, load-bearing source gap that blocks downstream use of that project. Separately, the public ZIP ends inside UpperMedinaHW.p01.hdf; that member is a supplied result HDF, so the publisher truncation is a recoverable delivery defect, not the hydraulic-source blocker. Leon1, Leon2, Leon3, and MiddleLowerMedina each reached owned unsteady-solver startup with two cores in HEC-RAS 6.4.1; this does not change UpperMedinaHeadwaters' blocked status. See the Medina Record of Deficiencies.

For large 2D studies, keep the authoritative organized source and durable receipts on the CEWS H: data library, but make bounded execution copies on a fixed local disk. Cibolo and Medina repeatedly exceeded the startup wait when preprocessing directly from H:, while unchanged local I: copies reached the same RAS Commander gate. This is an execution-tier rule, not permission to move or modify the authoritative delivery.

Alabama BLE watershed corpora

Alabama's statewide BLE catalog is exposed through the separate AlabamaBleModels source adapter. It joins the public ArcGIS model layer to the public model-link table by publisher ModelID and downloads only the table's WebPath. The publisher's bare object-store prefixes are not browsable directory endpoints, so callers must not scrape or construct URLs from those prefixes.

The qualified AL03130002 study key identifies the Middle Chattahoochee-Lake Harding HUC8 corpus: 197 1D steady projects grouped into eight source basins. The adapter preserves all of them in one movable delivery folder for FIM Commander and writes a relative-path inventory of each project's registered plan, geometry, flow, geometry HDF, and source archive.

Python
from pathlib import Path

from ras_commander.sources import AlabamaBleModels

workspace = Path("D:/ble/AL03130002")

# Dynamic ArcGIS/WebPath inventory: all 197 models, or one named source basin.
all_models = AlabamaBleModels.list_watershed_models("AL03130002")
halawakee = AlabamaBleModels.list_watershed_models(
    "03130002",
    basin="Halawakee Creek",
)

# Reuse a separately retained raw corpus when it contains every verified ZIP
# and source-identity sidecar; extracted folders alone are not trusted.
# Otherwise download, verify, extract, and organize the complete HUC8 directly.
raw_source = workspace / "raw"
if raw_source.exists():
    delivery = AlabamaBleModels.organize_watershed(
        "03130002",
        raw_source,
        workspace / "organized",
    )
else:
    delivery = AlabamaBleModels.download_watershed(
        "03130002",
        workspace / "organized",
    )
if not delivery.success:
    raise RuntimeError(delivery.message)

inventory = AlabamaBleModels.build_watershed_delivery_inventory(
    delivery.model_path
)

The organized root contains Source Archives/, RAS Models/, and Documentation/. Basin grouping is retained below the first two folders; paths in Documentation/watershed_delivery_inventory.json are relative to the delivery root. The retained source manifest uses ras_commander.watershed_source_manifest contract 1.0.0; its download mode retains the downloader's archive provenance block, while staged-copy retains the verified staging provenance block. Both modes share the same source identity and extraction keys and require source ZIPs, strong-ETag sidecars, and archive-bound extraction receipts. The inventory contract is identified by ras_commander.watershed_delivery_inventory version 1.0.0; it is the canonical FIM intake. The Example Project Library's four-layer combined PMTiles is a display derivative and must not replace it.

Current source qualification found 197 registered steady plans, 197 geometry HDFs, and 5,365 cross sections. Delivered plan metadata identifies 135 plans as 6.20 and two as 6.31; 60 omit Program Version, so the source adapter does not apply a blanket version. No plan computation has yet been run across this corpus. One extra physical file, OSANIPPA CREEK.p02, is preserved but is not registered by its project and is excluded from the canonical plan inventory. Because these are pure 1D geometry models, absence of a terrain HDF is not a source deficiency for this corpus product.

Delivery Validation Gate

An organized eBFE model is not considered fully delivery-ready until it passes preprocessor validation. File organization and dataframe path checks confirm that the project is self-contained, but the key proof is running the geometry preprocessor and reviewing compute messages for missing terrain, land cover, projection, DSS, or file path errors.

Use the reusable checklist in eBFE Delivery Validation for the standard readiness gates:

  1. organized
  2. hms_validated
  3. path_validated
  4. preprocessor_validated
  5. results_validated
  6. notebook_validated

For combined hms-commander plus ras-commander examples, hms_validated means that delivered HEC-HMS projects are copied under HMS Model/ and their HMS file references resolve locally, then hms-commander can load the organized project without path repair. RAS-only deliveries should keep a HMS Model/README.md explaining whether hydrology is supplied by steady flow files, DSS inputs, gridded precipitation, or another documented source.

Use GeomPreprocessor.run_geometry_preprocessor() as the assembly validation hook for both 1D steady and 2D/unsteady models. It enables detailed logging, runs the HEC-RAS geometry preprocessor through ras-commander, and reviews compute messages without requiring full unsteady calculations or floodplain mapping/post-processing as the delivery-format gate. For 1D steady BLE reach models, document terrain or land cover checks only when mapper layers exist.

For Lower Colorado-Cummins, run exactly one plan per project from isolated copies. The study-aware runner automatically enables nested-project discovery, uses the organized source as immutable input, and records the run-copy path:

PowerShell
.\.venv\Scripts\python scripts\ebfe_steady_plan_batch.py `
  --study 12090301 `
  --workspace "H:\Testing\eBFE\12090301" `
  --plan 01 `
  --ras-version 6.6 `
  --num-cores 2 `
  --force-geompre

The source metadata distinguishes the delivered HEC-RAS 4.1.0 version from the qualified 6.6 execution version and lists the separate public Models, SpatialData, and Documents packages. The SpatialData package contains published depth and water-surface-elevation results, not a terrain surface. Absence of a Terrain HDF or RASMapper file is therefore not a deficiency for these 1D steady projects. Study metadata also applies a 600-second per-plan timeout; a stalled owned process tree is cancelled through RasCmdr.cancel_plan() and recorded as a failed project, while legacy explicit-root runs retain their prior no-timeout default.

Study mode also supplies the delivered profile-count contract: seven profiles for 2,377 projects and six for WALNUT 0329. The organizer repairs the missing Flow File=f01 record in exactly PINEY 062 and PINEY 089 after validating their source fingerprints; it never modifies the downloaded source.

The separate source packages use the same integrity-checked download and extraction path as the Models archive:

Python
from ras_commander.sources import RasEbfeModels

documents = RasEbfeModels.download_source_asset(
    "12090301",
    "documents",
    workspace / "raw",
)
spatial_data = RasEbfeModels.download_source_asset(
    "12090301",
    "spatial_data",
    workspace / "raw",
)

For repeatable end-to-end checks from the repository, use:

PowerShell
.\.venv\Scripts\python scripts\ebfe_end_to_end_validation.py `
  --models north-galveston-bay `
  --download-root "H:\Testing\eBFE Model Organization\Downloads" `
  --output-root "H:\Testing\eBFE Model Organization\Organized" `
  --report-root "H:\Testing\eBFE Model Organization\Validation\ebfe_delivery" `
  --run-preprocessor `
  --max-wait 7200

The script uses RasEbfeModels.organize_model() for download/extraction and organization, then uses GeomPreprocessor.run_geometry_preprocessor() through the reusable batch validation flow.

Core Delivery Fixes

Early eBFE organizers focused on three recurring breakages: separated outputs, terrain paths, and DSS paths. The current delivery format also standardizes projection and land-cover assets because those are required for reliable geometry-preprocessor validation.

Fix #0: Shared HDF Asset Reference Normalization

Compiled geometry and plan/result HDFs can carry /Geometry attributes that point at terrain, land-cover, and infiltration sidecars. Recent organizer work standardizes those references across the normalized Terrain/, Land Cover/, and legacy Land Classification/ folders.

  • If a delivered model already points at a legacy .\Land Classification\... sidecar, ras-commander preserves that HDF attribute and copies the required sidecars into the legacy folder instead of forcing a rename.
  • If the organized project needs normalized terrain or land-cover references, the organizer rewrites those HDF attributes to the local asset that actually exists in the standardized project tree.

This keeps geometry-HDF association checks aligned with the organized delivery format while still supporting legacy eBFE asset layouts that appear in the wild.

Fix #1: Output/ Folder Integration

Problem: Pre-run HDF result files separated from project folder

eBFE delivers:

Text Only
UPGU1/
├── Input/ (project folder)
│   └── UPGU1.prj ✗ Can't find results
└── Output/
    └── UPGU1.p01.hdf (1.1 GB) ✗ Inaccessible

RasEbfeModels fixes:

Text Only
RAS Model/UPGU1/
├── UPGU1.prj ✓ Finds results
└── UPGU1.p01.hdf ✓ Accessible

Implementation:

Python
# Move all Output/*.hdf files INTO Input/ folder
output_source = model_source / "Output"
if output_source.exists():
    for output_file in output_source.rglob('*'):
        if output_file.is_file():
            shutil.copy2(output_file, input_dest / output_file.name)

Result: Can view expected runtime from pre-computed results

Fix #2: Terrain/ Integration

Problem: Terrain folder placed outside project, .rasmap references break

eBFE delivers:

Text Only
UPGU1/
├── Input/
│   └── UPGU1.rasmap ✗ References "..\Terrain\RAS_Terrain\Terrain.hdf"
└── Terrain/
    └── Terrain.hdf (3.98 GB) ✗ At "..\Terrain\Terrain.hdf"

RasEbfeModels fixes:

Text Only
RAS Model/UPGU1/
├── UPGU1.rasmap ✓ References ".\Terrain\Terrain.hdf"
└── Terrain/
    └── Terrain.hdf ✓ Exactly where .rasmap expects

Implementation:

Python
# Move Terrain/ INTO Input/ folder
terrain_source = model_source / "Terrain"
if terrain_source.exists():
    shutil.copytree(terrain_source, input_dest / "Terrain", dirs_exist_ok=True)

# Correct .rasmap terrain path to actual location
actual_terrain_hdf = list(project_folder.glob('Terrain/**/*.hdf'))[0]
rel_path = actual_terrain_hdf.relative_to(project_folder)
# Update <Layer Type="TerrainLayer" Filename="...">

Result: Model runs without terrain errors, RAS Mapper loads terrain

Fix #3: ALL Paths to Relative References

Problem: Absolute and incorrect paths cause GUI error popups

eBFE delivers (in UPGU1.u01):

Text Only
DSS Filename=.\DSS_Input\UPGU_precip.dss  ✗ Wrong subdirectory

Also (in other files):

Text Only
DSS File=C:\eBFE\Projects\12100201\UPGU1\Input\UPGU1.dss  ✗ Absolute path

RasEbfeModels fixes:

Text Only
DSS Filename=UPGU_precip.dss  ✓ Relative, verified exists

Implementation:

Python
# Find where DSS files ACTUALLY exist
dss_files = list(ras_model_folder.glob('**/*.dss'))
dss_lookup = {dss.name: dss for dss in dss_files}

# For each HEC-RAS file (.u##, .prj, .p##)
for hecras_file in hecras_files:
    # Find "DSS File=" or "DSS Filename=" references
    for match in dss_pattern.finditer(content):
        old_path = match.group(1).strip()
        dss_filename = Path(old_path).name

        # Check if DSS file exists in organized structure
        if dss_filename in dss_lookup and dss_lookup[dss_filename].exists():
            # Calculate correct relative path
            rel_path = dss_lookup[dss_filename].relative_to(hecras_file.parent)
            # Replace with verified path
            content = content.replace(f"DSS File={old_path}", f"DSS File={rel_path}")

Result: No GUI error popups, automation works

Available Models

Spring Creek (12040102) - Pattern 3a

Model Type: Single 2D unsteady flow model Size: 9.7 GB Plans: 8 with pre-computed results Terrain: 504.6 MB self-contained

Usage:

Python
from ras_commander.sources import RasEbfeModels
from ras_commander import init_ras_project

organized = RasEbfeModels.organize_spring_creek(
    downloaded_folder,
    validate_dss=True
)

init_ras_project(organized / "RAS Model", "5.0.7")

Fixes Applied: - DSS path corrections - .rasmap terrain path corrections - Output/ integration (if present)

Example Notebook: examples/950_ebfe_spring_creek.ipynb

North Galveston Bay (12040203) - Pattern 4

Model Type: Compound HMS + RAS (coastal flood analysis) Size: 8.2 GB HMS: 7 storm frequencies (10yr-500yr) + sensitivity RAS: 2D coastal model (nested 6.1 GB zip)

Usage:

Python
from ras_commander.sources import RasEbfeModels

organized = RasEbfeModels.organize_north_galveston_bay(
    downloaded_folder,
    extract_ras_nested=True,
    validate_dss=True
)

# HMS and normalized RAS model folders are ready
hms_project = organized / "HMS Model/NorthGalvestonBay/NorthGalvestonBay.hms"
ras_project = organized / "RAS Model"

Fixes Applied: - HMS/RAS separation - DSS path corrections (when RAS extracted) - Output/, Terrain/, Land Cover/, and Projection/ integration

Note: extract_ras_nested=True extracts and normalizes the nested RAS_Submittal archive in place.

Example Notebook: examples/951_ebfe_north_galveston_bay.ipynb

Upper Guadalupe (12100201) - Pattern 3b

Model Type: 4 cascaded 2D watershed models Source size: 58,575,220,457 bytes Models: UPGU1 → UPGU2 → UPGU3 → UPGU4 (hydraulic cascade) Plans: 28 total (7 AEP frequencies × 4 models) DSS: 10 delivered files; 21 live upstream-to-downstream references checked

Usage:

Python
from ras_commander.sources import RasEbfeModels
from ras_commander import RasCmdr, RasPreprocess, RasPrj, init_ras_project

# Organize (applies delivery normalization across all 4 models)
organized = RasEbfeModels.organize_upper_guadalupe(
    downloaded_folder,
    validate_dss=False,
)

# Bounded source qualification (upstream to downstream)
for model in ['UPGU1', 'UPGU2', 'UPGU3', 'UPGU4']:
    ras_obj = RasPrj()
    init_ras_project(organized / "RAS Model" / model, "6.3.1", ras_object=ras_obj)
    result = RasPreprocess.preprocess_plan("01", ras_object=ras_obj)
    assert result.success
    RasCmdr.cancel_plan_exact("01", ras_object=ras_obj)

Fixes Applied: - 56 delivered Output assets placed at their expected Input locations in the staged copy - 4 complete terrain triplets staged without replacing their channel or polygon modifications - DSS assets copied into per-project DSS Inputs/ folders and references rewritten - Land cover copied into per-project Land Cover/ folders - The one delivered shared projection copied under each project Projection/ folder - .rasmap terrain, land cover, and projection paths rewritten to local folders

Current qualification gate: historical preprocessor artifacts do not replace fresh source-run evidence. UPGU1 p01 reached owned unsteady-solver startup in an isolated two-core run. UPGU2's receipt records natural_completion without owned solver-start evidence after property-table rebuilding was observed, and UPGU3–UPGU4 were not run; those three projects therefore remain unqualified in the Record of Deficiencies.

Example Notebook: examples/952_ebfe_upper_guadalupe_cascade.ipynb

San Gabriel (12070205) - Pattern 3b

Model Type: Five linked 2D unsteady projects

HEC-RAS: 6.3

Dependency: LBSG_501, LBSG_502, LBSG_503, and LBSG_504 feed LBSG_505

Test use: Round Rock is in LBSG_504; Florence is nearest LBSG_503

Validation: One 1% plan per model reached unsteady computation

Python
import os
from pathlib import Path

from ras_commander.sources import RasEbfeModels

workspace = (
    Path(os.environ.get("RAS_COMMANDER_EBFE_ROOT", r"H:\Testing\eBFE"))
    / "12070205"
)
organized = RasEbfeModels.organize_model(
    "san-gabriel",
    download_root=workspace / "raw",
    output_root=workspace / "organized",
    validate_dss=True,
)

The organizer preserves each LBSG_50#\Input project and its sibling land cover folder, stages delivered plan-result HDFs beside their plan files, copies the delivered HEC-HMS 4.10 project, and rewrites only the known LBSG_505 cross-project DSS prefixes. Every terrain layer in all five .rasmap files is normalized to the one shared organized target, RAS Model\Terrain\Terrain.hdf. It does not use basename-based DSS repair because the delivery contains several unrelated files named 100.dss.

Critical 2D source gap: computational terrain not provided

The hydraulic inventory and all five .rasmap files name one shared Terrain\Terrain.hdf, but no public San Gabriel package contains it. The three HDEMs and the terrain spatial files are preserved under RAS Model\Terrain Submittal; deeply nested supplemental reports remain in the audited raw cache, outside the active RAS tree. The HDEMs omit the two road-crossing ground-line layers and Lake Georgetown polygon named as terrain modifications. The organizer does not automatically synthesize a replacement. An explicitly authorized working copy can build one shared HDEM-only terrain through RasTerrain.create_terrain_hdf(...); all five projects then point to that file, but it is not FEMA's original and cannot support a numerical-equivalence claim. For a 2D model this is a critical, model-blocking deficiency: the public delivery is not reproducible or usable for downstream hydraulic computation, and a viewable supplied result HDF does not cure the gap. The generated Record of Deficiencies preserves that distinction. unsteady_start is compute evidence only; delivery readiness is critical_source_gap and the model must not be presented as a runnable example until source-equivalent terrain is restored.

Qualified 1% smoke plans:

Project Plan Geometry Unsteady file
LBSG_501 01 02 01
LBSG_502 02 03 01
LBSG_503 04 04 01
LBSG_504 05 05 01
LBSG_505 06 06 02

API Reference

RasEbfeModels.organize_spring_creek()

Python
@staticmethod
@log_call
def organize_spring_creek(
    downloaded_folder: Path,
    output_folder: Optional[Path] = None,
    validate_dss: bool = True
) -> Path

Organizes: Spring Creek (12040102) - Pattern 3a

Parameters: - downloaded_folder: Path to extracted 12040102_Spring_Models folder - output_folder: Output location (default: ./ebfe_organized/SpringCreek_12040102/) - validate_dss: Run DSS validation checks (default: True)

Returns: Path to organized model with runnable HEC-RAS project

Fixes Applied: 1. Extracts nested _Final.zip (9.67 GB) 2. Organizes into 4 folders (HMS/RAS/Spatial/Documentation) 3. Corrects DSS paths to relative references 4. Corrects .rasmap terrain paths 5. Validates DSS pathnames 6. Creates agent/model_log.md

Output Structure:

Text Only
SpringCreek_12040102/
├── RAS Model/           # Runnable HEC-RAS project
├── Spatial Data/        # Shapefiles, terrain copy
├── Documentation/       # Inventory, reports
├── HMS Model/           # (empty for Pattern 3a)
└── agent/model_log.md   # Documents fixes applied

RasEbfeModels.organize_north_galveston_bay()

Python
@staticmethod
@log_call
def organize_north_galveston_bay(
    downloaded_folder: Path,
    output_folder: Optional[Path] = None,
    extract_ras_nested: bool = False,
    validate_dss: bool = True
) -> Path

Organizes: North Galveston Bay (12040203) - Pattern 4

Parameters: - downloaded_folder: Path to extracted 12040203_NorthGalvestonBay_Models folder - output_folder: Output location (default: ./ebfe_organized/NorthGalvestonBay_12040203/) - extract_ras_nested: Extract and normalize RAS_Submittal.zip when True. RasEbfeModels.organize_model("north-galveston-bay") enables this by default. - validate_dss: Run DSS validation checks (default: True)

Returns: Path to organized model

Fixes Applied: 1. Separates HMS from RAS content 2. Organizes 7 storm frequencies + sensitivity analysis 3. Handles nested 6.1 GB RAS zip extraction 4. Corrects DSS paths when RAS extracted 5. Moves Output/, Terrain/, Land Cover/, and Projection/ assets into the project 6. Creates agent/model_log.md

Output Structure:

Text Only
NorthGalvestonBay_12040203/
├── HMS Model/           # HEC-HMS with 7 storm frequencies
├── RAS Model/           # 2D coastal model (after extraction)
├── Spatial Data/        # (pending RAS extraction)
├── Documentation/       # BLE reports, metadata
└── agent/model_log.md

RasEbfeModels.organize_upper_guadalupe()

Python
@staticmethod
@log_call
def organize_upper_guadalupe(
    downloaded_folder: Optional[Union[str, Path]] = None,
    output_folder: Optional[Union[str, Path]] = None,
    validate_dss: bool = False
) -> Path

Organizes: Upper Guadalupe (12100201) - Pattern 3b

Parameters: - downloaded_folder: Optional path to the retained ZIP or an extracted delivery; when omitted, the pinned FEMA object is downloaded - output_folder: Output location (default: ./ebfe_organized/UpperGuadalupe_12100201/) - validate_dss: Optionally inventory the ten staged DSS files (default: False)

Returns: Path to the four-project organized source candidate. Organization alone is not a runtime or full-completion claim.

Fixes Applied (x 4 models): 1. Places 56 delivered Output assets at their expected Input locations in the staged copy 2. Stages all four complete terrain triplets while preserving their terrain modifications 3. Copies DSS assets into per-project DSS Inputs/ folders and rewrites references 4. Copies land-cover assets into per-project Land Cover/ folders 5. Materializes the one delivered shared CRS file under each project Projection/ folder 6. Rewrites .rasmap terrain, land cover, and projection references 7. Creates comprehensive agent/model_log.md

Output Structure:

Text Only
UpperGuadalupe_12100201/
└── RAS Model/
    ├── UPGU1/  # Upstream source project
    ├── UPGU2/  # Receives UPGU1 flow via DSS
    ├── UPGU3/  # Receives UPGU2 flow via DSS
    └── UPGU4/  # Downstream source project

Cascade Execution (sequential required):

Python
for model in ['UPGU1', 'UPGU2', 'UPGU3', 'UPGU4']:
    ras_obj = RasPrj()
    init_ras_project(organized / "RAS Model" / model, "6.3.1", ras_object=ras_obj)
    RasCmdr.compute_plan("01", ras_object=ras_obj, num_cores=4)
    # Upstream results feed downstream via DSS

RasEbfeModels.organize_san_gabriel()

Python
@staticmethod
@log_call
def organize_san_gabriel(
    downloaded_folder: Optional[str | Path] = None,
    output_folder: Optional[str | Path] = None,
    validate_dss: bool = True,
) -> Path

This additive organizer retains the five-project folder relationships, applies the documented 1% smoke-plan table flags, restores classification timestamps recorded in each selected geometry HDF, and writes agent/san_gabriel_manifest.json. The existing organize_model() return type and compact available_models() schema are unchanged; detailed dependency and deficiency metadata is exposed through ModelMetadata.extra.

Standardized 4-Folder Structure

All organized models use the same structure:

Text Only
{ModelName}_{HUC8}/
├── HMS Model/          # HEC-HMS hydrologic models (if present)
├── RAS Model/          # HEC-RAS hydraulic models (RUNNABLE)
│   └── {Model}/
│       ├── *.prj, *.g##, *.p##, *.u##
│       ├── *.hdf (pre-run results, moved from Output/)
│       ├── DSS Inputs/ (DSS paths corrected)
│       ├── Projection/ (project CRS copied or generated)
│       ├── *.rasmap (terrain paths corrected)
│       ├── Terrain/ (moved here, where HEC-RAS expects it)
│       └── Land Cover/ (local land cover and sidecar assets)
├── Spatial Data/       # GIS data, shapefiles
├── Documentation/      # BLE reports, inventories
└── agent/
    └── model_log.md    # REQUIRED - documents all fixes applied

agent/model_log.md Requirement

Every organized model MUST have agent/model_log.md documenting: - Organization actions taken - Files classified and moved (HMS/RAS/Spatial/Docs) - Critical fixes applied (Output/, DSS Inputs/, Projection/, Terrain/, Land Cover/) - Number of corrections made - DSS validation results - Compute test instructions

Why: Provides audit trail of what was fixed, enables troubleshooting, documents decisions made

Validation Features

DSS Pathname Validation

Organizers can optionally inventory DSS catalogs when validate_dss=True:

Python
from ras_commander.dss import RasDss

# Validates all pathnames in all DSS files
for dss_file in dss_files:
    catalog = RasDss.get_catalog(dss_file)
    for pathname in catalog['pathname']:
        result = RasDss.check_pathname(dss_file, pathname)
        # Invalid pathnames documented in agent/model_log.md

Upper Guadalupe's required source gate is narrower and reproducible: ten DSS files exist, 28 project-local precipitation references resolve, and all 21 cross-project transfer references remain live rather than copied snapshots.

Path Existence Validation

Before correcting any path, we verify the target file actually exists:

Python
if dss_filename in dss_lookup:
    actual_dss_path = dss_lookup[dss_filename]

    # CRITICAL: Verify file exists
    if actual_dss_path.exists():
        # Calculate correct relative path
        rel_path = actual_dss_path.relative_to(hecras_file.parent)
        # Replace path
    else:
        print(f"WARNING: DSS file not found: {dss_filename}")

Result: Only corrects paths to files that actually exist

Example Notebooks

Complete working examples demonstrating each model:

950_ebfe_spring_creek.ipynb

Demonstrates: - Organizing Pattern 3a (single 2D model) - The 3 critical fixes (before/after comparison) - DSS validation - Extracting pre-computed 2D results - Visualizing water surface elevations - Terrain validation

Key Sections: - Problem explanation (why eBFE models are broken) - Automated fixes (what RasEbfeModels does) - Before/after file structure - Time savings (30 min → 5 min)

951_ebfe_north_galveston_bay.ipynb

Demonstrates: - Organizing Pattern 4 (compound HMS + RAS) - HMS storm frequency exploration (7 frequencies) - HMS → RAS workflow understanding - Handling large nested RAS extraction - DSS time series validation

Key Sections: - Compound model complexity - HMS/RAS separation - Manual extraction handling (6.1 GB nested zip)

952_ebfe_upper_guadalupe_cascade.ipynb

Demonstrates: - Organizing Pattern 3b (cascaded watersheds) - Large split-folder source assembly - Project-local precipitation and live transfer-DSS validation - Cascaded model ordering (UPGU1→2→3→4) - Gridded precipitation DSS - Pre-run results extraction

Key Sections: - Complete before/after breakdown - All 3 fixes explained with file sizes - Cascade structure and execution - Emphasis: "This library exists to solve this exact problem"

953_ebfe_rio_hondo_steady_collection.ipynb

Demonstrates: - Organizing and validating the Rio Hondo 1D steady BLE reach-model collection. - Sequential steady-plan validation for 253 projects. - Reading generated HDF compute messages after successful steady-plan execution. - Distinguishing 1D steady result generation from 2D preprocessor validation.

954_ebfe_lake_maurepas_validation.ipynb

Demonstrates: - Organizing Pattern 3 single-archive Louisiana 2D model delivery. - Validating the delivered Lake Maurepas HEC-HMS project from HMS Model/ with hms-commander. - Confirming local projection, terrain, land-cover, and RASMapper assets. - Reusing saved ras-commander geometry-preprocessor evidence for plan 02. - Documenting a preprocessor-valid model where full hydraulic result HDFs are absent from the source archive.

955_ebfe_tickfaw_validation.ipynb

Demonstrates: - Organizing Pattern 3 single-archive Louisiana 2D model delivery with results. - Confirming local projection, terrain, land-cover, and RASMapper assets. - Reusing saved ras-commander geometry-preprocessor evidence for plan 13. - Verifying that all seven plan result HDF paths resolve inside the organized RAS project folder.

956_hydrofabric_conflation_visual_qa.ipynb

Demonstrates: - Conflating the Texas Lower Colorado-Cummins SHILOH BRANCH footprint, reach, and 40 cross sections to NextGen v2.2 VPU 12 flowpaths. - Mapping native NextGen wb-* flowpaths, cat-* catchments, WBD HUC12 boundaries, ranked candidates, and direct cross-section intersections for visual QA. - Auditing candidate score components and the confidence margin while resolving native nex-* links and preferring total upstream drainage area. - Comparing default and deliberately strict thresholds to expose matched, ambiguous, and unmatched states without fake accepted identifiers. - Verifying along-flowpath cross-section measures and a two-feature NextGen reach sequence.

957_ebfe_spring_river_validation.ipynb

Demonstrates: - Organizing the distinct Spring River HUC 11010010 delivery without confusing it with Spring Creek. - Confirming local projection, terrain, land-cover, legacy land-classification compatibility assets, DSS inputs, and RASMapper references. - Executing a fresh HEC-RAS 6.1 geometry-preprocessor validation for plan 01 / geometry 01. - Archiving the fresh preprocessor HDF before restoring the delivered full-result Spring_BLE.p01.hdf. - Verifying that all seven plan result HDF paths resolve inside the organized RAS project folder.

Organizing New Models

For eBFE models not included in RasEbfeModels, use the ebfe_organize_models agent skill:

Bash
# In Claude Code:
"Organize West Fork San Jacinto (12040101) using ebfe_organize_models skill"

Agent produces: 1. Organized 4-folder structure with all 3 critical fixes 2. agent/model_log.md documenting fixes 3. MANIFEST.md with file inventory 4. Generated function: organize_westforksanjacinto_12040101.py 5. DSS validation results 6. Compute test instructions 7. Haiku results check template

After testing: Promote generated function to RasEbfeModels class

Growing Library: Each organization adds a tested function

Time Savings

Model Manual Fix Time With RasEbfeModels Savings
Spring Creek 30-45 min 5-10 min 20-35 min
North Galveston Bay 45-90 min 10-15 min plus nested zip extraction 30-75 min
Upper Guadalupe 60-120 min 15-20 min 45-100 min

Additional Benefit: Enables automation (no GUI popups)

Automation Benefits

Without Path Corrections

Python
# Automation FAILS - GUI popup blocks workflow
init_ras_project(broken_ebfe_model, "6.5")
RasCmdr.compute_plan("01")  # Hangs on "DSS path needs correction" dialog

With Path Corrections

Python
# Portable assembly and bounded solver-start qualification
organized = RasEbfeModels.organize_upper_guadalupe(source, validate_dss=False)
init_ras_project(organized / "RAS Model/UPGU1", "6.3.1")
result = RasPreprocess.preprocess_plan("01")
assert result.success  # Solver-start evidence; not full-plan completion

Testing and Validation

End-to-End Evidence

Current validation is tracked in the repository-level VALIDATION_MATRIX.md, with generated audit reports under the H: workspace: H:\Testing\eBFE Model Organization\Validation\ebfe_delivery.

  • Lower Colorado-Cummins: plan 01 was attempted for all 2,378 isolated project copies with HEC-RAS 6.6. After two exact missing-flow-reference repairs and recognition of the one delivered six-profile project, 2,375 passed with HDF results. Three remain model-blocked by delivered hydraulic data defects: overlapping blocked obstructions in ALUM CREEK, and flow boundaries assigned to nonexistent cross sections in WALNUT 0613 and WILLBARGER 0185.
  • Rio Hondo: 253 1D steady reach projects passed sequential geometry preprocessor validation, and 253/253 steady plans computed successfully in steady_plan_validation_20260424_160022.json.
  • Spring Creek: 2D geometry preprocessor passed.
  • North Galveston Bay: nested download/extract/organize path passed geometry preprocessor validation; delivered HMS project loads through hms-commander.
  • Upper Guadalupe: UPGU1 p01 reached owned unsteady-solver startup in a fresh two-core isolated run. UPGU2's receipt records natural_completion without owned solver-start evidence after its property-table rebuild was observed, and UPGU3–UPGU4 were not attempted, so those three remain unqualified. Supplied plan HDFs are publication artifacts, not fresh execution evidence.
  • San Gabriel: all five selected 1% plans reached the unsteady-computation phase through ras-commander. This is unsteady_start compute evidence only. The required compiled terrain and terrain-modification payloads are Not Provided in Source, a critical_source_gap that makes the public 2D model non-reproducible and unusable for downstream computation. The HDEM-only diagnostic rebuild does not promote its delivery-readiness status.
  • Eleven Point: organized from the split Input.zip, Terrain.zip, and Land_Cover.zip delivery; path-audited with zero issues, seven local plan HDFs, and a passing ras-commander geometry-preprocessor run using HEC-RAS 6.6.
  • Spring River: cataloged separately from Spring Creek as spring-river / SpringRiver_11010010; downloaded, organized, path-audited with zero issues, preprocessor-valid in HEC-RAS 6.1, and results-ready with seven local plan HDFs. The validation notebook preserves the legacy Land Classification compatibility copy referenced by Spring_BLE.g01.hdf, archives fresh preprocessor evidence, and restores the delivered full-result plan HDF; see examples/957_ebfe_spring_river_validation.ipynb.
  • Lower Brazos: LB_MA01, LB_MA02, and LB_MA03 are downloaded, extracted, organized, path-audited with zero issues, and results-ready with 61 local plan HDFs in the latest audit. LB_MA02 passed ras-commander geometry-preprocessor validation in 3846.3 seconds; LB_MA01 exceeded the 7200-second timeout with no compute messages, and LB_MA03 returned without producing compute messages, so Lower Brazos remains partially preprocessor-validated.
  • Amite: full E2E organization completed for five RAS projects. WA1, WA2, WA3, and WA5 passed geometry preprocessor validation; WA4 is blocked by a RasGeomWriter / ERROR: Incorrect Type in ./Projection. (Expected String) failure and requires manual terrain rebuild or repair inside RASMapper.
  • Tickfaw: organized, path-audited, preprocessor-valid, and results-ready with seven local hydraulic plan HDFs; see examples/955_ebfe_tickfaw_validation.ipynb.
  • Lake Maurepas: organized, HMS-validated through hms-commander, path-audited, and preprocessor-valid; source archive scan found no RAS plan-result HDFs, so it is not yet a results-ready demo; see examples/954_ebfe_lake_maurepas_validation.ipynb.

Notebook Testing

Current eBFE notebooks 950-957 execute against the shared H:\Testing\eBFE Model Organization workspace by default, with RAS_COMMANDER_EBFE_ROOT available for overrides. Stored notebook outputs were refreshed after delivery-format updates, and notebook QA confirmed no error outputs in the eBFE notebook set.

Upper Guadalupe active-reference audit

  • 10 delivered DSS files
  • 28 project-local precipitation references
  • 21 live cascade-transfer references
  • 28 plan geometry/unsteady bindings
  • 224 fixed-length HDF association attributes
  • 12 terrain payload files and 5 terrain-modification groups

Why This Matters

For Engineers

Before this library: 1. Download valuable BLE model from FEMA 2. Spend 30-120 minutes manually fixing broken file structure 3. Risk missing corrections → Model still doesn't work 4. Frustration, wasted time

With this library: 1. Download BLE model 2. One function call → Runnable model 3. Confidence: All paths validated, all fixes documented 4. Start analysis immediately

For Automation

eBFE models enable: - Automated flood risk analysis at scale - Batch processing of multiple study areas - Programmatic model execution - Integration with other workflows

But GUI error popups kill automation

Our path corrections eliminate GUI popups → Automation works

See Also


The Bottom Line: eBFE models are fundamentally broken and unusable without significant manual effort. RasEbfeModels fixes them automatically, creating runnable HEC-RAS models that work for automation. This is what the library is for.