Using eBFE Models: Rio Hondo 1D Steady Collection¶
This notebook demonstrates the Rio Hondo (13060008) eBFE/BLE 1D steady model collection. The delivery is different from the large 2D eBFE examples: it contains hundreds of small 1D steady HEC-RAS projects, and results HDF files are generally absent until the steady plans are run.
The validation target for this collection is therefore straightforward: organize the projects, run each steady plan through ras-commander, read the detailed compute messages, and confirm every selected plan completed without blocking errors.
Workflow¶
- Use
RasEbfeModels.organize_model("rio-hondo")so downloads, extraction, and organization use the same ras-commander entry point as the audit scripts. - Discover valid HEC-RAS project folders with
RasUtils.find_valid_ras_folders(). - Run the sequential steady-plan validation batch script for the full collection.
- Read the JSON/Markdown evidence report and inspect compute-message summaries.
The full steady-plan batch can take a while because it touches 253 projects, so it is intentionally opt-in inside the notebook.
from pathlib import Path
import json
import os
import subprocess
import sys
import pandas as pd
try:
from ras_commander import HdfResultsPlan, RasPrj, RasUtils, init_ras_project
from ras_commander.results.ResultsParser import ResultsParser
from ras_commander.sources.federal import RasEbfeModels
except ImportError:
repo_root = Path.cwd().parent
sys.path.insert(0, str(repo_root))
from ras_commander import HdfResultsPlan, RasPrj, RasUtils, init_ras_project
from ras_commander.results.ResultsParser import ResultsParser
from ras_commander.sources.federal import RasEbfeModels
Configure the eBFE Workspace¶
The shared eBFE workspace is on H:\\Testing\\eBFE Model Organization. Set RAS_COMMANDER_EBFE_ROOT if you want to use a different local cache.
EBFE_WORKSPACE = Path(os.environ.get("RAS_COMMANDER_EBFE_ROOT", r"H:\Testing\eBFE Model Organization"))
DOWNLOAD_ROOT = EBFE_WORKSPACE / "Downloads"
ORGANIZED_ROOT = EBFE_WORKSPACE / "Organized"
VALIDATION_ROOT = EBFE_WORKSPACE / "Validation" / "ebfe_delivery"
repo_candidates = [Path.cwd(), Path.cwd().parent]
VALIDATION_MATRIX = next(
(candidate / "VALIDATION_MATRIX.md" for candidate in repo_candidates if (candidate / "VALIDATION_MATRIX.md").exists()),
Path.cwd() / "VALIDATION_MATRIX.md",
)
organized_folder = ORGANIZED_ROOT / "RioHondo_13060008"
if not organized_folder.exists():
organized_folder = RasEbfeModels.organize_model(
"rio-hondo",
download_root=DOWNLOAD_ROOT,
output_root=ORGANIZED_ROOT,
)
ras_model_root = organized_folder / "RAS Model"
print(f"Rio Hondo organized folder: {organized_folder}")
print(f"RAS Model root exists: {ras_model_root.exists()}")
print(f"Validation root: {VALIDATION_ROOT}")
print(f"Validation matrix: {VALIDATION_MATRIX}")
Rio Hondo organized folder: H:\Testing\eBFE Model Organization\Organized\RioHondo_13060008
RAS Model root exists: True
Validation root: H:\Testing\eBFE Model Organization\Validation\ebfe_delivery
Validation matrix: C:\GH\ras-commander\VALIDATION_MATRIX.md
Discover the RAS Projects¶
Rio Hondo is a 1D steady collection, so the unit of validation is each individual HEC-RAS project folder.
projects = RasUtils.find_valid_ras_folders(
ras_model_root,
max_depth=10,
return_project_info=True,
)
project_df = pd.DataFrame(projects)
print(f"Discovered {len(project_df)} HEC-RAS project folders")
project_df.head()
2026-04-28 23:37:26 - ras_commander.RasUtils - INFO - Searching for HEC-RAS projects in: H:\Testing\eBFE Model Organization\Organized\RioHondo_13060008\RAS Model
2026-04-28 23:37:34 - ras_commander.RasUtils - INFO - Found 253 valid HEC-RAS project folders
Discovered 253 HEC-RAS project folders
| folder | project_name | prj_file | plan_count | plan_numbers | |
|---|---|---|---|---|---|
| 0 | H:\Testing\eBFE Model Organization\Organized\R... | BarnDraw | H:\Testing\eBFE Model Organization\Organized\R... | 1 | [01] |
| 1 | H:\Testing\eBFE Model Organization\Organized\R... | BarnDrawTrib1 | H:\Testing\eBFE Model Organization\Organized\R... | 1 | [01] |
| 2 | H:\Testing\eBFE Model Organization\Organized\R... | BarnDrawTrib1A | H:\Testing\eBFE Model Organization\Organized\R... | 1 | [01] |
| 3 | H:\Testing\eBFE Model Organization\Organized\R... | BerrendoCreek | H:\Testing\eBFE Model Organization\Organized\R... | 1 | [01] |
| 4 | H:\Testing\eBFE Model Organization\Organized\R... | BerrendoCreekTrib | H:\Testing\eBFE Model Organization\Organized\R... | 1 | [01] |
Inspect One Project¶
A quick initialization pass confirms that ras-commander can read the project metadata before running the full batch.
sample_project = Path(project_df.iloc[0]["folder"])
sample_ras = RasPrj()
init_ras_project(
sample_project,
"6.6",
ras_object=sample_ras,
load_results_summary=False,
)
sample_ras.plan_df[["plan_number", "flow_type", "Geom File", "Flow File", "HDF_Results_Path"]]
2026-04-28 23:37:34 - ras_commander.RasPrj - INFO - No unsteady flow files found in the project.
2026-04-28 23:37:34 - ras_commander.RasMap - WARNING - RASMapper file not found: H:\Testing\eBFE Model Organization\Organized\RioHondo_13060008\RAS Model\Berrendo Creek\BarnDraw\BarnDraw.rasmap
2026-04-28 23:37:34 - ras_commander.RasMap - WARNING - No .rasmap file found for this project. Creating empty rasmap_df.
| plan_number | flow_type | Geom File | Flow File | HDF_Results_Path | |
|---|---|---|---|---|---|
| 0 | 01 | Steady | 01 | 01 | H:\Testing\eBFE Model Organization\Organized\R... |
Run or Reuse the Full Steady-Plan Validation¶
Set RUN_FULL_STEADY_VALIDATION = True to run all Rio Hondo steady plans. The script uses RasCmdr.compute_plan(..., verify=True), then reads detailed compute messages and writes evidence under Validation/ebfe_delivery/steady_plan_validation.
The saved notebook run keeps the batch compute disabled by default and loads the latest existing validation report when one is present. That makes the committed example fast while still showing the evidence trail used for acceptance.
RUN_FULL_STEADY_VALIDATION = False
repo_root = Path.cwd().parent if Path.cwd().name == "examples" else Path.cwd()
batch_script = repo_root / "scripts" / "ebfe_steady_plan_batch.py"
cmd = [
sys.executable,
str(batch_script),
"--root",
str(ras_model_root),
"--ras-version",
"6.6",
"--output-dir",
str(VALIDATION_ROOT / "steady_plan_validation"),
]
if RUN_FULL_STEADY_VALIDATION:
subprocess.run(cmd, check=True)
else:
print("Full validation is opt-in. Command to run:")
print(" ".join(f'\"{part}\"' if " " in part else part for part in cmd))
Full validation is opt-in. Command to run:
C:\Users\billk_clb\anaconda3\python.exe C:\GH\ras-commander\scripts\ebfe_steady_plan_batch.py --root "H:\Testing\eBFE Model Organization\Organized\RioHondo_13060008\RAS Model" --ras-version 6.6 --output-dir "H:\Testing\eBFE Model Organization\Validation\ebfe_delivery\steady_plan_validation"
Review Validation Evidence¶
After the batch run completes, this cell loads the latest JSON report and summarizes project pass/fail status.
report_dir = VALIDATION_ROOT / "steady_plan_validation"
reports = sorted(report_dir.glob("steady_plan_validation_*.json"))
if not reports:
print(f"No steady validation reports found yet in {report_dir}")
else:
latest_report = reports[-1]
payload = json.loads(latest_report.read_text(encoding="utf-8"))
records = payload["records"]
validation_df = pd.DataFrame(
{
"project": record["project_name"],
"status": record["status"],
"plans": len(record.get("plans", [])),
"seconds": record.get("elapsed_seconds"),
}
for record in records
)
print(f"Loaded existing report: {latest_report}")
if not RUN_FULL_STEADY_VALIDATION:
print("Saved notebook run reused existing validation evidence; set RUN_FULL_STEADY_VALIDATION = True to regenerate it.")
display(validation_df["status"].value_counts())
validation_df.head()
Loaded existing report: H:\Testing\eBFE Model Organization\Validation\ebfe_delivery\steady_plan_validation\steady_plan_validation_20260424_160022.json
Saved notebook run reused existing validation evidence; set RUN_FULL_STEADY_VALIDATION = True to regenerate it.
status
passed 253
Name: count, dtype: int64
Inspect Detailed Compute Messages¶
For this collection, results are considered resolved when the generated HDFs contain Complete Process and the parsed compute messages do not contain blocking errors.
sample_hdf = next(ras_model_root.glob("**/*.p01.hdf"), None)
if sample_hdf is None:
print("No plan HDF found yet. Run the steady validation batch first.")
else:
messages = HdfResultsPlan.get_compute_messages_hdf_only(sample_hdf)
parsed = ResultsParser.parse_compute_messages(messages)
print(sample_hdf)
parsed
2026-04-28 23:37:34 - ras_commander.hdf.HdfResultsPlan - INFO - Using existing Path object HDF file: H:\Testing\eBFE Model Organization\Organized\RioHondo_13060008\RAS Model\Rio Ruidoso\BradyCanyon\BradyCanyon.p01.hdf
2026-04-28 23:37:34 - ras_commander.hdf.HdfResultsPlan - INFO - Final validated file path: H:\Testing\eBFE Model Organization\Organized\RioHondo_13060008\RAS Model\Rio Ruidoso\BradyCanyon\BradyCanyon.p01.hdf
2026-04-28 23:37:34 - ras_commander.hdf.HdfResultsPlan - INFO - Reading computation messages from HDF: BradyCanyon.p01.hdf
2026-04-28 23:37:34 - ras_commander.hdf.HdfResultsPlan - INFO - Successfully extracted 715 characters from HDF
H:\Testing\eBFE Model Organization\Organized\RioHondo_13060008\RAS Model\Rio Ruidoso\BradyCanyon\BradyCanyon.p01.hdf
Delivery-Format Interpretation¶
Unlike the larger 2D eBFE projects, Rio Hondo does not depend on terrain or land cover layers for validation. The key delivery-format proof is that each 1D steady project can initialize, run its steady plan, produce a plan HDF, and expose detailed compute messages confirming successful completion.
In the committed notebook output, the expensive batch run is opt-in and the notebook loads the latest existing validation report from the shared eBFE workspace. Regenerate that report with RUN_FULL_STEADY_VALIDATION = True whenever the organized source data or ras-commander execution path changes.