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:
- Output/ Folder Separation
- Pre-run HDF result files (often 40+ GB) stored separately from project
- HEC-RAS can't find results → Can't view expected runtime
-
Manual fix required: Move gigabytes of HDF files into project folder
-
Terrain/ Misplacement
- Terrain data (often 15+ GB) placed outside project folder
- .rasmap files reference
Terrain\RAS_Terrain\Terrain.hdf(doesn't exist) - Actual terrain location:
Terrain\Terrain.hdf(different path) -
Manual fix required: Move terrain folders + edit .rasmap XML manually
-
Absolute and Incorrect DSS Paths
- DSS references use paths from original FEMA system:
C:\eBFE\Projects\... - Also wrong relative paths:
.\DSS_Input\file.dss(subdirectory doesn't exist) - HEC-RAS shows GUI popup: "DSS path needs correction"
- Manual fix required: Click through 30+ GUI dialogs or edit .u## files manually
User Experience Without This Library¶
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¶
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:
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:
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.
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.
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.
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:
organizedhms_validatedpath_validatedpreprocessor_validatedresults_validatednotebook_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:
.\.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:
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:
.\.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:
UPGU1/
├── Input/ (project folder)
│ └── UPGU1.prj ✗ Can't find results
└── Output/
└── UPGU1.p01.hdf (1.1 GB) ✗ Inaccessible
RasEbfeModels fixes:
Implementation:
# 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:
UPGU1/
├── Input/
│ └── UPGU1.rasmap ✗ References "..\Terrain\RAS_Terrain\Terrain.hdf"
└── Terrain/
└── Terrain.hdf (3.98 GB) ✗ At "..\Terrain\Terrain.hdf"
RasEbfeModels fixes:
RAS Model/UPGU1/
├── UPGU1.rasmap ✓ References ".\Terrain\Terrain.hdf"
└── Terrain/
└── Terrain.hdf ✓ Exactly where .rasmap expects
Implementation:
# 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):
Also (in other files):
RasEbfeModels fixes:
Implementation:
# 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:
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:
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:
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
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()¶
@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:
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()¶
@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:
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()¶
@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:
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):
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()¶
@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:
{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:
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:
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:
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¶
# 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¶
# 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
01was 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 inALUM CREEK, and flow boundaries assigned to nonexistent cross sections inWALNUT 0613andWILLBARGER 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
p01reached owned unsteady-solver startup in a fresh two-core isolated run. UPGU2's receipt recordsnatural_completionwithout 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_startcompute evidence only. The required compiled terrain and terrain-modification payloads areNot Provided in Source, acritical_source_gapthat 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, andLand_Cover.zipdelivery; 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 legacyLand Classificationcompatibility copy referenced bySpring_BLE.g01.hdf, archives fresh preprocessor evidence, and restores the delivered full-result plan HDF; seeexamples/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¶
- eBFE Delivery Validation
VALIDATION_MATRIX.md- 950_ebfe_spring_creek.ipynb
- 955_ebfe_tickfaw_validation.ipynb
- 957_ebfe_spring_river_validation.ipynb
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.