Reference Lines and Points for 2D Calibration¶
This notebook demonstrates GeomReferenceFeatures — inserting and reading
reference lines and reference points in HEC-RAS plain text geometry files.
Reference lines act as virtual cross sections in 2D models, enabling integrated flow extraction for calibration against streamflow gauges. Reference points provide WSE/depth extraction at specific cell locations.
What You'll Learn¶
- Add reference lines to a 2D geometry file
- Add reference points to a 2D geometry file
- Read back reference lines and points
- Verify round-trip consistency
Python
from pathlib import Path
import sys
import numpy as np
try:
from ras_commander import (
RasExamples, init_ras_project, ras,
GeomReferenceFeatures,
)
except ImportError:
sys.path.append(str(Path('.').resolve().parent))
from ras_commander import (
RasExamples, init_ras_project, ras,
GeomReferenceFeatures,
)
Step 1 — Extract a 2D Example Project¶
Python
project_folder = RasExamples.extract_project("BaldEagleCrkMulti2D", suffix="207")
init_ras_project(project_folder, "7.0")
# Find the geometry file
geom_path = Path(ras.geom_df.iloc[0]['full_path'])
print(f"Project: {project_folder}")
print(f"Geometry: {geom_path.name}")
print(f"2D areas: {ras.geom_df.iloc[0].get('mesh_area_names', 'N/A')}")
Step 2 — Check for Existing Reference Features¶
Python
existing_lines = GeomReferenceFeatures.get_reference_lines(geom_path)
existing_points = GeomReferenceFeatures.get_reference_points(geom_path)
print(f"Existing reference lines: {len(existing_lines)}")
print(f"Existing reference points: {len(existing_points)}")
Step 3 — Add Reference Lines¶
Reference lines are defined by a name and a polyline of (x, y) coordinates. They must be associated with a 2D flow area (storage area name).
Python
# Get the 2D flow area name from geom_df
mesh_names = ras.geom_df.iloc[0].get('mesh_area_names', [])
storage_area = mesh_names[0] if mesh_names else 'BaldEagleCr'
print(f"Using 2D flow area: {storage_area}")
# Define two reference lines crossing the 2D mesh
ref_lines = [
{
"name": "Upstream_XS",
"coordinates": [
(1756000, 156000),
(1756500, 156000),
(1757000, 156000),
],
},
{
"name": "Downstream_XS",
"coordinates": [
(1762000, 150000),
(1762500, 150000),
(1763000, 150000),
],
},
]
n_added = GeomReferenceFeatures.add_reference_lines(
geom_path, lines=ref_lines, storage_area=storage_area
)
print(f"Added {n_added} reference lines")
Step 4 — Add Reference Points¶
Reference points are stored as IC Points with "Reference Point" prefix. They provide WSE/depth extraction at specific cell locations.
Python
ref_points = [
{"name": "Gauge_A", "x": 1758000, "y": 154000},
{"name": "Gauge_B", "x": 1761000, "y": 151000},
]
n_added = GeomReferenceFeatures.add_reference_points(geom_path, points=ref_points)
print(f"Added {n_added} reference points")
Step 5 — Read Back and Verify Round-Trip¶
Python
# Read reference lines
read_lines = GeomReferenceFeatures.get_reference_lines(geom_path)
print(f"Reference lines read back: {len(read_lines)}")
for rl in read_lines:
print(f" {rl['name']}: {len(rl['coordinates'])} points, area={rl['storage_area']}")
# Read reference points
read_points = GeomReferenceFeatures.get_reference_points(geom_path)
print(f"\nReference points read back: {len(read_points)}")
for rp in read_points:
print(f" {rp['name']}: ({rp['x']}, {rp['y']})")
# Verify counts
assert len(read_lines) >= 2, f"Expected >=2 lines, got {len(read_lines)}"
assert len(read_points) >= 2, f"Expected >=2 points, got {len(read_points)}"
print("\nRound-trip verification passed.")
Key Takeaways¶
add_reference_lines()inserts reference lines into the geometry file at the correct locationadd_reference_points()inserts points as IC Points with "Reference Point" prefix- Both methods create
.bakbackups before modifying files get_reference_lines()andget_reference_points()parse back the inserted features- Reference lines persist through HEC-RAS recomputation (read from plain text during preprocessing)
- Reference lines require a 2D flow area name; reference points do not