Skip to content

1D Breakout Extraction

RasBreakout1D creates an independent, steady-flow HEC-RAS project from a continuous slice of one 1D river reach. Selection and extraction are separate, so a station range, polygon, network edge, or explicit cross-section set can feed the same fail-closed writer and validation workflow.

Select a reach slice

Python
from ras_commander import RasBreakout1D

selection = RasBreakout1D.select_by_stations(
    source_geometry_file,
    river="White River",
    reach="Main Stem",
    upstream_station=24000,
    downstream_station=12000,
)

Other selectors accept:

  • a contiguous cross-section station set with select_by_cross_sections();
  • a Shapely polygon intersecting the desired cut lines with select_by_polygon();
  • a Shapely network edge and optional search tolerance with select_by_network_edge() (select_by_network_segment() is an alias).

Polygon and network geometries must use the geometry file's coordinate system. An omitted river/reach is accepted only when the selection resolves to exactly one reach.

Network-edge selection includes one additional downstream cross section by default. This matches Ripple1D's shared-boundary convention for reach-sized submodels and provides an internal target reach with a downstream boundary section. Pass downstream_overlap_xs=0 for the directly intersected span only, or a larger integer for a wider transition zone.

Optional upstream_buffer_distance and downstream_buffer_distance values expand a network-edge selection using the source geometry's main-channel reach lengths. These values use HEC-RAS reach-length/model units; by contrast, tolerance uses the network geometry's spatial coordinate-system units. Expansion retains the first cross section at or beyond each requested distance and stops at the available upstream or downstream terminus.

Separate computation and inundation domains

Use select_domains_by_network_edge() when a model should retain hydraulic transition length without expanding its published inundation footprint:

Python
domains = RasBreakout1D.select_domains_by_network_edge(
    source_geometry_file,
    target_edge.geometry,
    river="White River",
    reach="Main Stem",
    inside_fraction=target_edge.inside_fraction,
)

computation_selection = domains.computation_selection
inundation_selection = domains.inundation_selection

When inside_fraction indicates that the network edge is fully inside the model, omitted buffer distances default to 10% of the full source-reach main channel length upstream and 25% downstream. Explicit distances override those defaults independently. Partial edges receive no automatic distance buffer.

The inundation selection remains the directly intersected span plus one shared downstream cross section by default. The computation selection always contains that strict export selection and extends to the first cross section meeting each hydraulic buffer distance, or to the source-model terminus. This allows the larger project to absorb boundary effects while a later raster-clipping step uses the smaller, overlapping export domain.

inundation_overlap_xs records the requested overlap and inundation_overlap_xs_applied records how many downstream sections were available before the model terminus. The *_buffer_applied distances report only the hydraulic distance expansion; they do not count the strict raster overlap that is unioned into the computation selection.

Extract and validate

Python
result = RasBreakout1D.extract_selection(
    source_ras,
    r"D:\models\white_river_breakout",
    selection,
    plan_number="01",
    destination_name="white_river_breakout",
    boundary_mode="auto",
)

assert result.validation.is_valid
print(result.project_file)
print(result.boundary_provenance)

The destination receives its own .prj, .p01, .g01, and .f01 files and an initialized RasPrj. The geometry writer preserves complete retained cross-section and inline-structure blocks, including Manning's n, bank stations, levees, ineffective areas, blocked obstructions, and HTAB settings. It clips the one-reach Reach XY centerline to the retained boundary-section crossings, keeps upstream reach lengths, and zeroes the downstream retained section's L/Ch/R reach lengths because no downstream section remains. Steady-flow change locations inside the retained range are preserved, and the active source flow is propagated to the new upstream limit.

The validation dataframe checks project/plan/geometry/flow relationships, retained stations and blocks, flow profiles and change locations, reach-length termination, boundary data, and source-geometry immutability. Use result.validation.raise_for_errors() when validating separately.

Downstream boundaries

boundary_mode controls an internal downstream cut:

Mode Behavior
auto Use source steady-plan WSE results when available; otherwise preserve the source boundary and record the fallback.
source_results Require usable steady-plan HDF results and write known WSE values by profile.
preserve Preserve the source reach boundary.

Pass downstream_boundary={...} to explicitly override those modes with a boundary definition accepted by RasSteady.write_flow_file().

Run and compare

Execution is always routed through RasCmdr:

Python
compute_result = RasBreakout1D.run(result, verify=True)

geometry_delta = RasBreakout1D.compare_geometry(
    source_geometry_file,
    result.geometry_file,
    result.selection,
)

results_delta = RasBreakout1D.compare_results(
    source_plan_hdf,
    destination_plan_hdf,
    result.selection,
)

compare_geometry() reports exact retained cross-section payload agreement and whether intervening structure blocks match. compare_results() reports numeric differences at retained cross sections for matching steady profiles after both plans have completed.

MVP boundaries

The initial workflow intentionally fails closed for multi-reach or junction selections, non-contiguous cross sections, unsteady or sediment plans, lateral structures, and selections with fewer than two cross sections. The one-reach writer clips Reach XY only when both retained boundary cut lines intersect the source centerline; otherwise it preserves the source header. Multi-reach centerline clipping and reconnection remain outside the MVP.

RasBreakout1D

Static workflow for extracting an independent 1D steady breakout.

select_by_stations staticmethod

Python
select_by_stations(geom_file: Union[str, Path], river: str, reach: str, upstream_station: Union[str, float, int], downstream_station: Union[str, float, int]) -> Breakout1DSelection

Select every cross section between inclusive station bounds.

select_by_cross_sections staticmethod

Python
select_by_cross_sections(geom_file: Union[str, Path], river: str, reach: str, stations: Sequence[Union[str, float, int]]) -> Breakout1DSelection

Resolve a supplied, contiguous cross-section set on one reach.

Non-contiguous sets fail closed. A later multi-segment workflow can define how gaps should be reconnected without weakening this contract.

select_by_polygon staticmethod

Python
select_by_polygon(geom_file: Union[str, Path], polygon: Any, *, river: Optional[str] = None, reach: Optional[str] = None) -> Breakout1DSelection

Select the continuous reach span whose XS cut lines intersect a polygon.

The polygon and geometry cut lines must use the same coordinate system. If river and reach are omitted, the intersections must resolve to exactly one reach.

select_by_network_edge staticmethod

Python
select_by_network_edge(geom_file: Union[str, Path], network_edge: Any, *, river: Optional[str] = None, reach: Optional[str] = None, tolerance: float = 0.0, downstream_overlap_xs: int = 1, upstream_buffer_distance: float = 0.0, downstream_buffer_distance: float = 0.0) -> Breakout1DSelection

Select the continuous XS span associated with a network edge.

network_edge must be a Shapely-like line in the geometry coordinate system. A positive tolerance buffers it in spatial coordinate-system units before testing intersections. Optional upstream and downstream buffer distances use HEC-RAS main-channel reach-length/model units. The first cross section at or beyond each requested distance is retained, or selection stops at the reach terminus.

By default, the selection also includes the next cross section downstream of the distance-buffered span. That shared boundary section preserves the Ripple1D breakout convention and gives an internal reach a usable downstream boundary.

Set downstream_overlap_xs=0 to retain only directly intersected cross sections. Values greater than one are supported for workflows that need a wider shared transition zone; the selection stops at the source reach boundary when fewer downstream sections are available.

select_domains_by_network_edge staticmethod

Python
select_domains_by_network_edge(geom_file: Union[str, Path], network_edge: Any, *, river: Optional[str] = None, reach: Optional[str] = None, tolerance: float = 0.0, inside_fraction: Optional[float] = None, upstream_buffer_distance: Optional[float] = None, downstream_buffer_distance: Optional[float] = None, upstream_buffer_fraction: float = 0.1, downstream_buffer_fraction: float = 0.25, inundation_overlap_xs: int = 1, fully_inside_tolerance: float = 1e-09) -> Breakout1DDomainSelection

Resolve nested hydraulic-computation and raster-export domains.

Explicit buffer distances override percentage defaults independently. When inside_fraction indicates that the network edge is fully inside the model, omitted distances default to 10% upstream and 25% downstream of the source reach's main-channel length. For partial edges, omitted distances resolve to zero. Expansion stops at the available reach termini.

The inundation selection requests inundation_overlap_xs shared downstream cross sections and reports how many were available. The computation selection always contains that strict export selection, even when no hydraulic distance buffer is requested.

select_network_edge_domains staticmethod

Python
select_network_edge_domains(geom_file: Union[str, Path], network_edge: Any, *, river: Optional[str] = None, reach: Optional[str] = None, tolerance: float = 0.0, inside_fraction: Optional[float] = None, upstream_buffer_distance: Optional[float] = None, downstream_buffer_distance: Optional[float] = None, upstream_buffer_fraction: float = 0.1, downstream_buffer_fraction: float = 0.25, inundation_overlap_xs: int = 1, fully_inside_tolerance: float = 1e-09) -> Breakout1DDomainSelection

Compatibility alias for :meth:select_domains_by_network_edge.

select_by_network_segment staticmethod

Python
select_by_network_segment(geom_file: Union[str, Path], segment: Any, *, river: Optional[str] = None, reach: Optional[str] = None, tolerance: float = 0.0, downstream_overlap_xs: int = 1, upstream_buffer_distance: float = 0.0, downstream_buffer_distance: float = 0.0) -> Breakout1DSelection

Alias for :meth:select_by_network_edge.

extract_reach staticmethod

Python
extract_reach(source_ras: RasPrj, destination: Union[str, Path], river: str, reach: str, upstream_station: Union[str, float, int], downstream_station: Union[str, float, int], *, plan_number: Optional[Union[str, int]] = None, destination_name: Optional[str] = None, boundary_mode: str = 'auto', source_plan_hdf: Optional[Union[str, Path]] = None, downstream_boundary: Optional[Mapping[str, Any]] = None, run: bool = False, verify_run: bool = True, compute_kwargs: Optional[Mapping[str, Any]] = None) -> Breakout1DResult

Extract one station-bounded reach into a new steady project.

extract_selection staticmethod

Python
extract_selection(source_ras: RasPrj, destination: Union[str, Path], selection: Breakout1DSelection, *, plan_number: Optional[Union[str, int]] = None, destination_name: Optional[str] = None, boundary_mode: str = 'auto', source_plan_hdf: Optional[Union[str, Path]] = None, downstream_boundary: Optional[Mapping[str, Any]] = None, run: bool = False, verify_run: bool = True, compute_kwargs: Optional[Mapping[str, Any]] = None) -> Breakout1DResult

Extract a previously resolved one-reach selection.

boundary_mode='auto' uses source-plan WSE at an internal downstream cut when results exist, otherwise preserves the source reach boundary and records that fallback in the result. 'source_results' requires a usable steady plan HDF. 'preserve' always keeps the source reach boundary. downstream_boundary overrides all three modes.

validate staticmethod

Python
validate(source_ras: RasPrj, destination_ras: RasPrj, selection: Breakout1DSelection, *, source_plan_number: Optional[Union[str, int]] = None, source_geometry_sha256: Optional[str] = None, boundary_provenance: str = 'unknown') -> Breakout1DValidationReport

Validate project links, retained blocks, reach lengths, and flow data.

run staticmethod

Python
run(breakout: Union[Breakout1DResult, RasPrj], *, plan_number: Union[str, int] = '01', verify: bool = True, **compute_kwargs: Any) -> Any

Explicitly run a destination breakout through RasCmdr.

compare_geometry staticmethod

Python
compare_geometry(source_geometry: Union[str, Path], destination_geometry: Union[str, Path], selection: Breakout1DSelection) -> pd.DataFrame

Compare complete retained source/destination geometry node blocks.

compare_results staticmethod

Python
compare_results(source_plan_hdf: Union[str, Path], destination_plan_hdf: Union[str, Path], selection: Breakout1DSelection) -> pd.DataFrame

Compare steady results at retained sections and return numeric deltas.