unsteady_plan

UnsteadyUnsteadyPlan - read HEC-RAS unsteady plan HDF5 files (.p*.hdf).

Plan HDF files embed the same Geometry/ group as geometry HDF files plus Results/Unsteady/... time-series and summary output.

UnsteadyUnsteadyPlan inherits Geometry so all geometry accessors are available. FlowAreaResults extends FlowArea with lazy time-series properties, summary DataFrames, and computed depth / velocity methods. Raster export methods delegate to rivia.geo via a deferred import so this module is fully usable without rasterio or scipy installed.

class rivia.hdf.unsteady_plan.BridgeResults(geom, group)[source]

Bases: _StructureResultsMixin, Bridge

Geometry and time-series results for one HEC-RAS bridge structure.

Inherits geometry from Bridge and shared HDF result access from _StructureResultsMixin.

The HDF group is at Results/.../DSS Hydrograph Output/.../Bridge/<river reach rs>.

Parameters:
  • geom (Bridge) – Geometry object from StructureCollection.

  • group (Group) – h5py.Group at the bridge result path.

class rivia.hdf.unsteady_plan.ComputeSummary(run, volume, volume_1d, volume_2d)[source]

Bases: object

Full unsteady simulation summary for a plan HDF file.

Aggregates all summary groups under Results/Unsteady/Summary.

Variables:
  • run – Overall run metadata (solution status, timing, stability).

  • volume – Model-wide volume accounting (1D + 2D combined).

  • volume_1d – Volume accounting for 1-D components only.

  • volume_2d – Per-area volume accounting for each 2-D flow area. Empty dict when the model has no 2-D flow areas.

Parameters:
errors()[source]

Return key convergence and volume-balance error metrics.

Derives four scalar error measures from this summary that are useful for quick quality-control checks after a run.

Returns:

A flat dictionary with the following keys:

"wse"

Maximum water-surface elevation error across all cells (model units — feet or metres). None when the simulation went unstable before the run converged.

"volume_error_pct"

Overall volume balance error as a percentage of total inflow, read directly from the HEC-RAS Results/Unsteady/Summary volume accounting block.

"volume_1d_error_pct"

1-D volume balance error (%) computed from the individual 1-D flux terms:

error = -(flow_us_in + net_other_fluxes + storage_change)
supply = reach_vol_start + sa_vol_start + flow_us_in
         + hydro_lat + hydro_sa + diversions
         + groundwater + precip_excess
error_pct = error / supply * 100

where net_other_fluxes = -flow_ds_out + hydro_lat + hydro_sa + diversions + groundwater + precip_excess. supply is the total 1-D water budget (initial storage plus all non-DS-outflow fluxes); for a 1D-only model this matches the HEC-RAS overall "Error Percent" attribute. Returns nan when total 1-D supply is zero.

"volume_2d_error_pct"

Largest-magnitude 2-D volume balance error (%) across all 2-D flow areas, preserving the sign of the worst-case area. Zero when the model has no 2-D flow areas.

Return type:

dict[str, float]

See also

ok

Quality-control pass/fail check with threshold logging.

ok(wse_threshold=0.5, volume_error_pct_threshold=1.0, volume_1d_error_pct_threshold=1.0, volume_2d_error_pct_threshold=1.0)[source]

Return True if the simulation completed stably and all error metrics are within their thresholds.

Checks stability first, then each error metric against its threshold. All failures are collected and logged before returning so the caller sees the complete picture in one pass.

If the simulation went unstable every failure is logged at CRITICAL; otherwise threshold violations are logged at WARNING.

Parameters:
  • wse_threshold (float) – Maximum allowable water-surface elevation error in model units (feet or metres). Default: 0.5.

  • volume_error_pct_threshold (float) – Maximum allowable overall volume balance error (%). Default: 1.0.

  • volume_1d_error_pct_threshold (float) – Maximum allowable 1-D volume balance error (%). Default: 1.0.

  • volume_2d_error_pct_threshold (float) – Maximum allowable 2-D volume balance error (%) per 2-D flow area. Default: 1.0.

Returns:

True if the simulation is stable and all metrics are within bounds; False otherwise.

Return type:

bool

See also

errors

Raw error metric values.

run: RunStatus
to_dict()[source]

Return a nested dict with short, meaningful keys.

Top-level keys: "run", "volume", "volume_1d", "volume_2d". The "volume_2d" value is a dict keyed by 2-D flow area name.

Return type:

dict[str, Any]

volume: VolumeAccounting
volume_1d: VolumeAccounting1D
volume_2d: dict[str, VolumeAccounting2DArea]
class rivia.hdf.unsteady_plan.CrossSectionResults(geom, hdf, index, root)[source]

Bases: _CrossSectionResultsBase

Geometry and results for one XS from the Base Output block.

Corresponds to UnsteadyPlan.cross_sections (mapping output interval). All variables written by HEC-RAS at the mapping interval are exposed.

Parameters:
  • geom (CrossSection) – Geometry object from CrossSectionCollection.

  • hdf (File) – Open h5py.File — kept alive by the parent UnsteadyPlan context.

  • index (int) – Column index of this XS in the (n_t, n_xs) result datasets.

  • root (str) – HDF path prefix — _TS_XS.

property flow_cumulative: ndarray

Cumulative flow volume time series. Shape (n_t,).

property flow_lateral: ndarray

Lateral flow time series. Shape (n_t,).

property velocity_channel: ndarray

Channel velocity time series. Shape (n_t,).

property velocity_total: ndarray

Total velocity time series. Shape (n_t,).

class rivia.hdf.unsteady_plan.CrossSectionResultsCollection(hdf, root, result_cls=<class 'rivia.hdf.unsteady_plan.CrossSectionResults'>, attrs_path=None)[source]

Bases: CrossSectionCollection

Plan-enriched cross section collection with time-series results.

Parameterised over the concrete result class and the HDF path used to map cross sections to column indices, so one implementation serves all three output blocks.

Parameters:
  • hdf (File) – Open h5py.File handle.

  • root (str) – HDF path to the cross section result group: _TS_XS, _DSS_XS, or _POSTPROC_XS.

  • result_cls (type[_CrossSectionResultsBase]) – Concrete result class to instantiate per cross section — CrossSectionResults, CrossSectionResultsDSS, or CrossSectionResultsInstantaneous.

  • attrs_path (str | None) – HDF path to the Cross Section Attributes structured array used to map (river, reach, station) → column index. Defaults to f"{root}/Cross Section Attributes", which is correct for Base Output and DSS blocks. Pass _POSTPROC_GEOM_ATTRS for the Post Process block, where attributes live outside the XS result group.

property names: list[str]

Cross section keys available in this result block.

Returns:

Keys of the form "<river> <reach> <station>".

Return type:

list[str]

class rivia.hdf.unsteady_plan.CrossSectionResultsDSS(geom, hdf, index, root)[source]

Bases: _CrossSectionResultsBase

Geometry and results for one XS from the DSS Hydrograph Output block.

Corresponds to UnsteadyPlan.cross_sections_output (hydrograph output interval). Available datasets: wse, flow, flow_cumulative.

Parameters:
  • geom (CrossSection) – Geometry object from CrossSectionCollection.

  • hdf (File) – Open h5py.File — kept alive by the parent UnsteadyPlan context.

  • index (int) – Column index of this XS in the (n_t, n_xs) result datasets.

  • root (str) – HDF path prefix — _DSS_XS.

property flow_cumulative: ndarray

Cumulative flow volume time series. Shape (n_t,).

class rivia.hdf.unsteady_plan.CrossSectionResultsInstantaneous(geom, hdf, index, root)[source]

Bases: _CrossSectionResultsBase

Geometry and results for one XS from the Post Process Profiles block.

Corresponds to UnsteadyPlan.cross_sections_instantaneous.

All result arrays have shape (n_profiles,) where index 0 is the Max WS profile and indices 1: are the instantaneous profiles written at the instantaneous interval. Use UnsteadyPlan.instantaneous_timestamps for the datetime index of indices 1:.

Available top-level datasets: water_surface, flow, energy_grade. All Additional Variables sub-group datasets are exposed as named properties (e.g. flow_total, velocity_channel) and are also reachable via additional_variable() for programmatic access.

Parameters:
  • geom (CrossSection) – Geometry object from CrossSectionCollection.

  • hdf (File) – Open h5py.File — kept alive by the parent UnsteadyPlan context.

  • index (int) – Column index of this XS in the (n_profiles, n_xs) result datasets.

  • root (str) – HDF path prefix — _POSTPROC_XS.

additional_variable(name)[source]

Load one column from the Additional Variables sub-group.

Parameters:

name (str) – Dataset name inside Additional Variables/, e.g. "Flow Total", "Velocity Channel", "Conveyance Total".

Returns:

Index 0 = Max WS profile; indices 1: = instantaneous profiles.

Return type:

ndarray, shape (n_profiles,)

Raises:

KeyError – If name is not present in Additional Variables/.

property alpha: ndarray

Velocity-head correction factor α. Shape (n_profiles,).

property beta: ndarray

Momentum correction factor β. Shape (n_profiles,).

property conveyance_channel: ndarray

Channel conveyance (m³/s). Shape (n_profiles,).

property conveyance_left_ob: ndarray

Left overbank conveyance (m³/s). Shape (n_profiles,).

property conveyance_right_ob: ndarray

Right overbank conveyance (m³/s). Shape (n_profiles,).

property conveyance_total: ndarray

Total conveyance (m³/s). Shape (n_profiles,).

property critical_energy_grade: ndarray

Critical energy grade line elevation (m). Shape (n_profiles,).

property critical_water_surface: ndarray

Critical water surface elevation (m). Shape (n_profiles,).

property energy_grade: ndarray

Energy grade line elevation (m). Shape (n_profiles,).

Index 0 = Max WS profile; indices 1: = instantaneous profiles.

property energy_grade_slope: ndarray

Energy grade slope (m/m). Shape (n_profiles,).

property flow_area_channel: ndarray

Channel flow area (m²). Shape (n_profiles,).

property flow_area_left_ob: ndarray

Left overbank flow area (m²). Shape (n_profiles,).

property flow_area_right_ob: ndarray

Right overbank flow area (m²). Shape (n_profiles,).

property flow_area_total: ndarray

Total flow area (m²). Shape (n_profiles,).

property flow_channel: ndarray

Channel flow (m³/s). Shape (n_profiles,).

property flow_left_ob: ndarray

Left overbank flow (m³/s). Shape (n_profiles,).

property flow_right_ob: ndarray

Right overbank flow (m³/s). Shape (n_profiles,).

property flow_total: ndarray

Total flow (m³/s). Shape (n_profiles,).

property friction_slope: ndarray

Friction slope (m/m). Shape (n_profiles,).

property hydraulic_depth_channel: ndarray

Channel hydraulic depth (m). Shape (n_profiles,).

property hydraulic_depth_left_ob: ndarray

Left overbank hydraulic depth (m). Shape (n_profiles,).

property hydraulic_depth_right_ob: ndarray

Right overbank hydraulic depth (m). Shape (n_profiles,).

property hydraulic_depth_total: ndarray

Total hydraulic depth (m). Shape (n_profiles,).

property hydraulic_radius_channel: ndarray

Channel hydraulic radius (m). Shape (n_profiles,).

property hydraulic_radius_left_ob: ndarray

Left overbank hydraulic radius (m). Shape (n_profiles,).

property hydraulic_radius_right_ob: ndarray

Right overbank hydraulic radius (m). Shape (n_profiles,).

property hydraulic_radius_total: ndarray

Total hydraulic radius (m). Shape (n_profiles,).

property ineffective_area_channel: ndarray

Channel area including ineffective zones (m²). Shape (n_profiles,).

property ineffective_area_left_ob: ndarray

Left overbank area including ineffective zones (m²). Shape (n_profiles,).

property ineffective_area_right_ob: ndarray

Right overbank area including ineffective zones (m²). Shape (n_profiles,).

property ineffective_area_total: ndarray

Total area including ineffective zones (m²). Shape (n_profiles,).

property mannings_n_channel: ndarray

Weighted/composite channel Manning’s n. Shape (n_profiles,).

property mannings_n_left_ob: ndarray

Left overbank Manning’s n. Shape (n_profiles,).

property mannings_n_right_ob: ndarray

Right overbank Manning’s n. Shape (n_profiles,).

property mannings_n_total: ndarray

Total weighted Manning’s n. Shape (n_profiles,).

property max_depth_total: ndarray

Total maximum water depth (m). Shape (n_profiles,).

property shear: ndarray

Bed shear stress (N/m²). Shape (n_profiles,).

property top_width_channel: ndarray

Channel top width (m). Shape (n_profiles,).

property top_width_channel_with_ineffective: ndarray

Channel top width including ineffective areas (m). Shape (n_profiles,).

property top_width_left_ob: ndarray

Left overbank top width (m). Shape (n_profiles,).

property top_width_left_ob_with_ineffective: ndarray

Left overbank top width including ineffective areas (m). Shape (n_profiles,).

property top_width_right_ob: ndarray

Right overbank top width (m). Shape (n_profiles,).

property top_width_right_ob_with_ineffective: ndarray

Right overbank top width including ineffective areas (m). Shape (n_profiles,).

property top_width_total: ndarray

Total top width (m). Shape (n_profiles,).

property top_width_total_with_ineffective: ndarray

Total top width including ineffective areas (m). Shape (n_profiles,).

property velocity_channel: ndarray

Channel velocity (m/s). Shape (n_profiles,).

property velocity_left_ob: ndarray

Left overbank velocity (m/s). Shape (n_profiles,).

property velocity_right_ob: ndarray

Right overbank velocity (m/s). Shape (n_profiles,).

property velocity_total: ndarray

Total velocity (m/s). Shape (n_profiles,).

property wetted_perimeter_channel: ndarray

Channel wetted perimeter (m). Shape (n_profiles,).

property wetted_perimeter_left_ob: ndarray

Left overbank wetted perimeter (m). Shape (n_profiles,).

property wetted_perimeter_right_ob: ndarray

Right overbank wetted perimeter (m). Shape (n_profiles,).

property wetted_perimeter_total: ndarray

Total wetted perimeter (m). Shape (n_profiles,).

property wse_total: ndarray

Total stage / water surface elevation (m). Shape (n_profiles,).

Sourced from Additional Variables/Water Surface Total. Equivalent to wse for most configurations.

class rivia.hdf.unsteady_plan.FlowAreaResults(geom_group, ts_group, sum_group, name, n_cells)[source]

Bases: FlowArea

Geometry and time-series results for one named 2-D flow area.

Inherits all geometry properties from FlowArea.

Time-series properties return raw h5py.Dataset objects so the caller controls how much data is loaded:

area.water_surface[10]          # one timestep -> ndarray (n_cells,)
area.water_surface[10:20]       # slice -> ndarray (10, n_cells)
area.water_surface[:]           # all -> ndarray (n_t, n_cells)
Parameters:
  • geom_group (Group) – h5py.Group at Geometry/2D Flow Areas/<name>.

  • ts_group (Group) – h5py.Group at the time-series result path for this area.

  • sum_group (Group) – h5py.Group at the summary result path for this area.

  • name (str) – Flow area name.

  • n_cells (int) – Number of real computational cells.

cell_speed(timestep, method='area_weighted', wse_interp='average', face_velocity_location='normal_intercept')[source]

Velocity magnitude at each cell centre for one timestep.

Parameters:
Return type:

ndarray, shape (n_cells,)

property cell_velocity: Dataset | None

HEC-RAS cell-velocity speed scalar, or None if not output.

h5py.Dataset, shape (n_timesteps, n_cells). This is the optional output enabled in the HDF Write Parameters; see cell_velocity_vectors() for the derived vector field.

cell_velocity_angle(timestep, method='area_weighted', wse_interp='average', face_velocity_location='normal_intercept')[source]

Flow direction at each cell centre for one timestep.

Angle is measured in degrees clockwise from north (the conventional “flow-to” bearing used in hydraulics and GIS).

Parameters:
Returns:

Direction the flow is heading in degrees clockwise from north (0 = north, 90 = east, 180 = south, 270 = west). Cells whose speed is below 1e-10 return nan.

Return type:

ndarray, shape (n_cells,)

cell_velocity_vectors(timestep, method='area_weighted', wse_interp='average', face_velocity_location='normal_intercept')[source]

Reconstruct cell-centre velocity vectors via weighted least-squares.

Uses the WLS method prescribed by the HEC-RAS Technical Reference Manual (Section: 2D Unsteady Flow - Cell Velocity).

Parameters:
  • timestep (int) – 0-based index into the time dimension.

  • method (Literal['area_weighted', 'length_weighted', 'flow_ratio']) – "area_weighted" (default, matches HEC-RAS): weights are wetted face flow areas from the hydraulic property tables. "length_weighted": weights are face plan-view lengths. "flow_ratio": requires Face Flow output; back-calculates flow area as |Q|/|V_n|.

  • wse_interp (Literal['average', 'sloped', 'max']) – How to estimate face WSE when method="area_weighted". "average" (default): simple mean of the two adjacent cell WSEs. "sloped": distance-weighted interpolation at the face’s actual position - see face_velocity_location. "max": maximum of the two adjacent cell WSEs.

  • face_velocity_location (Literal['centroid', 'normal_intercept']) – Position used as the face normal velocity measurement point when wse_interp="sloped". "normal_intercept" (default): the point where the cell-centre connecting line crosses the face polyline, matching how HEC-RAS locates its finite-difference gradient. "centroid": the geometric centroid of the face polyline. Has no effect when wse_interp is "average" or "max".

Returns:

[Vx, Vy] depth-averaged velocity components for real cells.

Return type:

ndarray, shape (n_cells, 2)

depth(timestep)[source]

Water depth at each cell centre for one timestep.

Depth = max(0, WSE - bed_elevation), where bed elevation is the cell minimum elevation from the geometry.

Parameters:

timestep (int) – 0-based index into the time dimension.

Returns:

Real cells only (ghost rows excluded).

Return type:

ndarray, shape (n_cells,)

export_hydraulic_rasters(timestep, reference_raster, *, wse_path=None, depth_path=None, velocity_path=None, nodata=-9999.0, render_mode='sloping', use_depth_weights=False, shallow_to_flat=False, depth_threshold=0.001, tight_extent=True)[source]

Export water-surface elevation, depth, and velocity rasters in one call.

Convenience wrapper that calls export_raster() three times — once each for "water_surface", "depth", and "velocity" — sharing the same render settings.

Parameters:
  • timestep (int) – 0-based time index. Required — all three outputs need a specific timestep (velocity has no max-value fallback).

  • reference_raster (str | Path) – Path to the terrain DEM GeoTIFF. Required — used to derive depth (WSE minus DEM) and to inherit the output CRS and transform.

  • wse_path (str | Path | None) – Destination .tif for the water-surface elevation raster. None returns an open in-memory rasterio.DatasetReader.

  • depth_path (str | Path | None) – Destination .tif for the depth raster. None returns an open in-memory rasterio.DatasetReader.

  • velocity_path (str | Path | None) – Destination .tif for the velocity magnitude raster. None returns an open in-memory rasterio.DatasetReader.

  • nodata (float) – Fill value for dry / out-of-domain pixels (default -9999).

  • render_mode (Literal[‘horizontal’, ‘sloping’, ‘hybrid’]) – Passed to export_raster() for all three variables.

  • use_depth_weights (bool) – Passed to export_raster(). hybrid only.

  • shallow_to_flat (bool) – Passed to export_raster(). hybrid only.

  • depth_threshold (float) – Minimum depth for a pixel to be considered wet (default 0.001).

  • tight_extent (bool) – When True (default), pixels outside the flow-area boundary are set to nodata.

Return type:

dict[str, Path | ‘rasterio.io.DatasetReader’]

Returns:

  • dict with keys "water_surface", "depth", "velocity".

  • Each value is the written Path (when the corresponding *_path

  • argument is given) or an open in-memory rasterio.DatasetReader

  • (when None). The caller must close any in-memory datasets.

export_raster(variable, timestep=None, output_path=None, *, reference_raster=None, cell_size=None, crs=None, nodata=-9999.0, render_mode='sloping', use_depth_weights=False, shallow_to_flat=False, depth_threshold=0.001, tight_extent=True)[source]

Rasterize a result variable using the RASMapper-exact algorithm.

Implements the pixel-perfect pipeline reverse-engineered from RasMapperLib/ (decompiled C# source, HEC-RAS 6.6), validated against RASMapper VRT exports — median diff = 0.000000.

Parameters:
  • variable (Literal[‘wse’, ‘water_surface’, ‘depth’, ‘velocity’, ‘velocity_vector’]) – "wse" / "water_surface" — water-surface elevation. "depth" — water depth (WSE minus terrain); requires reference_raster. "velocity" — 1-band speed raster sqrt(Vx²+Vy²); requires an explicit timestep. "velocity_vector" — 4-band raster [Vx, Vy, speed, direction_deg]; requires an explicit timestep.

  • timestep (int | None) – 0-based time index. Pass None to use the time of maximum water-surface elevation ("wse"/"water_surface" and "depth" only; raises ValueError for "velocity").

  • output_path (str | Path | None) – Destination .tif file path. None returns an open in-memory rasterio.DatasetReader; the caller must close it.

  • reference_raster (str | Path | None) – Existing GeoTIFF whose transform and CRS are inherited. Also used as the terrain DEM for depth computation. Required when variable="depth". Mutually exclusive with cell_size.

  • cell_size (float | None) – Output pixel size in model coordinate units. Used when no reference_raster is supplied; grid origin is derived from the flow-area perimeter bounding box. Mutually exclusive with reference_raster.

  • crs (Any | None) – Output CRS. Inherited from reference_raster when None.

  • nodata (float) – Fill value for dry / out-of-domain pixels (default -9999).

  • render_mode (Literal[‘horizontal’, ‘sloping’, ‘hybrid’]) – "sloping" (default) — RASMapper “Sloping Cell Corners”; uses corner facepoints only. RasMapperLib hardcodes shallow_to_flat=True for this mode; the user-supplied value is overridden. Matches store_map(render_mode="sloping"). "hybrid" — “Sloping Cell Corners + Face Centers”; use_depth_weights and shallow_to_flat are honoured. Matches store_map(render_mode="hybrid"). "horizontal" — flat per-cell value; facepoint interpolation is skipped. Matches store_map(render_mode="horizontal").

  • use_depth_weights (bool) – Weight face contributions by water depth. ``hybrid`` only; forced False for other modes. Requires reference_raster.

  • shallow_to_flat (bool) – Render cells with no hydraulically-connected faces flat. ``hybrid`` only (user-configurable); forced True for "sloping" per RasMapperLib, False for "horizontal".

  • depth_threshold (float) – Minimum depth for a pixel to be considered wet (default 0.001). Matches RASResults.MinWSPlotTolerance.

  • tight_extent (bool) – When True (default), pixels outside the flow-area boundary polygon are set to nodata.

Return type:

Path | rasterio.io.DatasetReader

Returns:

  • Path – Written GeoTIFF path when output_path is given.

  • rasterio.io.DatasetReader – Open in-memory dataset when output_path is None.

Raises:
  • ImportError – If rasterio or shapely are not installed.

  • ValueError – If variable="depth" and reference_raster is not provided. If variable="velocity" or variable="velocity_vector" and timestep=None. If neither reference_raster nor cell_size is provided.

property face_flow: Dataset | None

Volumetric face-flow time series, or None if not output.

h5py.Dataset, shape (n_timesteps, n_faces).

property face_velocity: Dataset

Signed face-normal velocity time series.

h5py.Dataset, shape (n_timesteps, n_faces).

face_velocity_vectors(timestep)[source]

Full 2D velocity [Vx, Vy] at each face midpoint.

Implements the RASMapper-exact C-stencil least-squares reconstruction (Step A + Step 2 from geo/_rasmapper_pipeline.py):

  • Step A — hydraulic connectivity: determines which faces are actively conveying flow based on adjacent-cell WSE and bed elevation.

  • Step 2 — for each face, a 3-face C-stencil (the face itself plus its clockwise and counter-clockwise neighbors within each adjacent cell) solves a 2×2 WLS system to recover the full (Vx, Vy) vector from the stored face-normal scalar. The result from each adjacent cell is averaged to give a single face vector.

Replicates ReconstructFaceVelocitiesLeastSquares from RasMapperLib/MeshFV2D.cs.

Parameters:

timestep (int) – 0-based index into the time dimension.

Returns:

[Vx, Vy] velocity at each face midpoint. Disconnected (dry) faces receive [0, 0].

Return type:

ndarray, shape (n_faces, 2)

facepoint_velocity_vectors(timestep)[source]

Full 2D velocity [Vx, Vy] at each mesh facepoint (corner).

Implements the RASMapper-exact pipeline (Steps A + 2 + 3):

  • Step A — hydraulic connectivity (compute_face_wss()).

  • Step 2 — C-stencil face velocity reconstruction (reconstruct_face_velocities()).

  • Step 3 — inverse-face-length weighted facepoint averaging (compute_facepoint_velocities()). Each facepoint has one arc-context velocity vector per adjacent face; these are averaged to produce a single [Vx, Vy] per facepoint.

Replicates ComputeVertexVelocities from RasMapperLib/MeshFV2D.cs.

Parameters:

timestep (int) – 0-based index into the time dimension.

Returns:

[Vx, Vy] velocity at each mesh corner. Facepoints adjacent only to dry faces receive [0, 0].

Return type:

ndarray, shape (n_facepoints, 2)

max_depth()[source]

Maximum depth per cell using the time of maximum WSE.

value = max(0, max_WSE - bed_elevation). time is the elapsed time of maximum WSE (days); this is an approximation - maximum depth may not coincide with maximum WSE.

Return type:

DataFrame with columns ['value', 'time'], index = cell index.

property max_face_velocity: DataFrame

Maximum face velocity per face.

DataFrame with columns ['value', 'time']. Index: 0-based face index.

property max_water_surface: DataFrame

Maximum WSE per cell.

DataFrame with columns ['value', 'time']. value: maximum water-surface elevation (model units). time: elapsed simulation time (days) when max occurred. Index: 0-based cell index. Real cells only (ghost rows excluded).

property min_water_surface: DataFrame

Minimum WSE per cell. Same column layout as max_water_surface. Real cells only (ghost rows excluded).

velocity_plot(timestep, cell_index, *, render_mode='sloping', buffer=1, reference_raster=None, use_depth_weights=False, shallow_to_flat=False, pixel_size=None, n_arrows=200, ax=None)[source]

Quiver plot of rasterized velocity vectors around a target cell.

Rasterizes the neighbourhood of cell_index using the RASMapper-exact pipeline (rasterize_results with variable="velocity"), then draws quiver arrows at the pixel centres of wet pixels. Arrows show the final, fully interpolated [Vx, Vy] value at each pixel — the same values that appear in RASMapper’s velocity map.

Mesh polygon outlines and cell index labels are drawn as context.

Requires matplotlib (pip install matplotlib).

Parameters:
  • timestep (int) – 0-based time index.

  • cell_index (int) – Target cell. The neighbourhood is expanded by BFS from this cell.

  • render_mode (Literal['horizontal', 'sloping', 'hybrid']) – "horizontal", "sloping" (default), or "hybrid" — passed to export_raster().

  • buffer (int) – Number of face-adjacency hops to expand from cell_index. 1 = immediate neighbours; 2 = two rings out.

  • reference_raster (str | Path | None) – Optional path to a terrain DEM GeoTIFF. When supplied, the pixel size and CRS are inherited from the DEM and use_depth_weights=True becomes available. When None (default), the pixel size is auto-derived from the median face length in the neighbourhood.

  • use_depth_weights (bool) – Passed to export_raster(). hybrid mode only. Requires reference_raster.

  • shallow_to_flat (bool) – Passed to export_raster(). hybrid mode only.

  • pixel_size (float | None) – Raster pixel size in model coordinate units. Smaller values produce a finer grid and more potential arrow positions. Ignored when reference_raster is supplied (the DEM pixel size is used instead). Defaults to local_cell_size / 3, giving ~9 pixels per face-length unit so n_arrows has room to work.

  • n_arrows (int) – Target number of quiver arrows. Wet pixels are subsampled with stride ceil(sqrt(n_wet / n_arrows)) so the actual count is approximately n_arrows. Increase for denser plots (e.g. n_arrows=800); set to a very large number to show every wet pixel. Default 200.

  • ax (Any | None) – Existing matplotlib.Axes to draw on. If None a new figure/axes is created.

Return type:

matplotlib.axes.Axes

property water_surface: Dataset

Water-surface elevation time series.

h5py.Dataset, shape (n_timesteps, n_cells + n_ghost). HEC-RAS stores ghost cell WSE (boundary condition stages) in the trailing columns. Slice with [:self.n_cells] for real cells only, or [:] for all including ghost cells. Slice to read: area.water_surface[10].

water_surface_at_facepoints(timestep)[source]

WSE interpolated to facepoints for one timestep.

Convenience wrapper around wse_at_facepoints() that reads the water-surface time series internally.

Parameters:

timestep (int) – 0-based index into the time dimension.

Returns:

Facepoint WSE. nan where all adjacent cells are dry.

Return type:

ndarray, shape (n_facepoints,)

wet_cells(timestep, depth_min=0.0)[source]

Boolean mask of wet cells for one timestep.

A cell is wet when WSE - cell_min_elevation > depth_min.

Parameters:
  • timestep (int) – 0-based index into the time dimension.

  • depth_min (float) – Minimum depth threshold in model units. Default 0.0.

Return type:

ndarray, shape (n_cells,), dtype bool

wet_faces(timestep, depth_min=0.0)[source]

Boolean mask of wet faces for one timestep.

A face is wet when at least one of its adjacent cells is wet (see wet_cells()). Boundary faces are wet when their single adjacent real cell is wet.

Parameters:
  • timestep (int) – 0-based index into the time dimension.

  • depth_min (float) – Minimum cell depth threshold passed to wet_cells().

Return type:

ndarray, shape (n_faces,), dtype bool

wse(timestep)[source]

Water-surface elevation at each real cell for one timestep.

Parameters:

timestep (int) – 0-based index into the time dimension.

Returns:

Water-surface elevation in model units. Real cells only.

Return type:

ndarray, shape (n_cells,)

class rivia.hdf.unsteady_plan.FlowAreaResultsCollection(hdf)[source]

Bases: FlowAreaCollection

Collection of FlowAreaResults objects backed by a plan HDF file.

Overrides FlowAreaCollection to return FlowAreaResults instead of plain FlowArea instances.

Parameters:

hdf (h5py.File)

class rivia.hdf.unsteady_plan.InlineResults(geom, group)[source]

Bases: _StructureResultsMixin, InlineStructure

Geometry and time-series results for one HEC-RAS inline structure.

Inherits geometry from InlineStructure and shared HDF result access from _StructureResultsMixin.

The HDF group is at Results/.../DSS Hydrograph Output/.../Inline Structures/<river reach rs>.

Parameters:
  • geom (InlineStructure) – Geometry object from StructureCollection.

  • group (Group) – h5py.Group at the inline structure result path.

class rivia.hdf.unsteady_plan.LateralResults(geom, group)[source]

Bases: _StructureResultsMixin, LateralStructure

Geometry and time-series results for one HEC-RAS lateral structure.

Inherits geometry from LateralStructure and shared HDF result access from _StructureResultsMixin.

The HDF group is at Results/.../DSS Hydrograph Output/.../Lateral Structures/<river reach rs>.

downstream_node is the name of the connected Storage Area or 2-D Flow Area, or an empty string when flow exits the system.

Parameters:
  • geom (LateralStructure) – Geometry object from StructureCollection.

  • group (Group) – h5py.Group at the lateral structure result path.

property flow_hw_ds: ndarray

Flow at the downstream bounding cross section. Shape (n_t,).

property flow_hw_us: ndarray

Flow at the upstream bounding cross section. Shape (n_t,).

property stage_hw_ds: ndarray

Stage at the downstream bounding cross section. Shape (n_t,).

property stage_hw_us: ndarray

Stage at the upstream bounding cross section. Shape (n_t,).

class rivia.hdf.unsteady_plan.RunStatus(solution, run_window, compute_time_total, compute_time_dss, max_cores, max_wsel_error, time_unstable, timestamp_unstable)[source]

Bases: object

Overall run metadata from Results/Unsteady/Summary.

Variables:
  • solution – HEC-RAS solution status string, e.g. "Unsteady Finished Successfully" or "Unsteady Went Unstable".

  • run_window – Wall-clock window during which the simulation ran, as a raw string, e.g. "26NOV2025 15:58:44 to 26NOV2025 16:03:41".

  • compute_time_total – Total wall-clock computation time in "HH:MM:SS" format.

  • compute_time_dss – Time spent writing DSS output in "HH:MM:SS" format.

  • max_cores – Maximum number of CPU cores used.

  • max_wsel_error – Maximum water-surface elevation error (model units), or None when the simulation went unstable before convergence.

  • time_unstable – Elapsed simulation time (days) when the solution went unstable, or None if the run finished successfully.

  • timestamp_unstable – HEC-RAS date/time string for the instability, or None if the run finished successfully (HEC-RAS writes "Not Applicable").

Parameters:
  • solution (str)

  • run_window (str)

  • compute_time_total (str)

  • compute_time_dss (str)

  • max_cores (int)

  • max_wsel_error (float | None)

  • time_unstable (float | None)

  • timestamp_unstable (str | None)

compute_time_dss: str
compute_time_total: str
max_cores: int
max_wsel_error: float | None
parse_run_window()[source]

Parse run_window into (start, end) datetimes.

Splits the raw string on " to " and parses each half with the HEC-RAS timestamp format "%d%b%Y %H:%M:%S".

Returns:

(start, end) as timezone-naive datetime.datetime objects, or None when the string is missing, malformed, or cannot be parsed.

Return type:

tuple[datetime, datetime] or None

Examples

s = hdf.compute_summary()
window = s.run.parse_run_window()
if window:
    start, end = window
    print(end - start)   # wall-clock duration
run_window: str
solution: str
time_unstable: float | None
timestamp_unstable: str | None
to_dict()[source]

Return a dict with short, meaningful keys.

Return type:

dict[str, Any]

class rivia.hdf.unsteady_plan.SA2DConnectionResults(geom, group)[source]

Bases: _StructureResultsMixin, SA2DConnection

Geometry and time-series results for one HEC-RAS SA/2D connection.

Inherits geometry from SA2DConnection and shared HDF result access (structure_variables, total_flow, stage_hw, stage_tw, weir_variables, flow_gate) from _StructureResultsMixin.

Parameters:
  • geom (SA2DConnection) – Geometry object from StructureCollection.

  • group (Group) – h5py.Group at -/SA 2D Area Conn/<plan_name>.

property breaching_variables: Dataset | None

Breach geometry and flow time series, or None if not breach-capable.

Lazy h5py.Dataset, shape (n_t, 10). Columns: Stage HW, Stage TW, Bottom Width, Bottom Elevation, Left Side Slope, Right Side Slope, Breach Flow, Breach Velocity, Breach Flow Area, Top Elevation.

property headwater_cells: ndarray | None

2-D mesh cell indices on the headwater side, or None if absent.

Shape (n_faces,).

property tailwater_cells: ndarray | None

2-D mesh cell indices on the tailwater side, or None if absent.

For 2D↔2D connections (levees) these are stored as a flat int32 dataset at the group root. For SA↔2D connections (e.g. a dam with a storage-area headwater) they are stored as fixed-width byte strings in HW TW Segments/Tailwater Cells and are decoded here.

Shape (n_cells,).

class rivia.hdf.unsteady_plan.StorageAreaResults(sa, sa_index, ts_sa_group, sum_sa_group)[source]

Bases: StorageArea

Geometry and time-series results for one storage area.

Inherits all geometry properties from StorageArea (boundary, volume_elevation, volume_at_elevation(), etc.).

Time-series properties return numpy arrays (storage areas are scalar entities so their result datasets are small and eager loading is appropriate).

Parameters:
  • sa (StorageArea) – Parent geometry object whose fields are copied into this instance.

  • sa_index (int) – 0-based column index of this SA in the flat (n_t, n_sa) datasets (Water Surface, Flow) stored under Storage Areas/.

  • ts_sa_group (Group | None) – h5py.Group at -/Unsteady Time Series/Storage Areas, or None when the plan has no SA results.

  • sum_sa_group (Group | None) – h5py.Group at -/Summary Output/Storage Areas, or None.

property connection_names: list[str]

Names of the inflow connection sources (from HDF Connections attribute).

Falls back to index-based names if the attribute is absent.

property connections: ndarray | None

Inflow from each named connection.

Shape (n_t, n_conns), or None when no connection data is stored. Column names are in connection_names.

property flow: ndarray

Net inflow rate (positive = into SA). Shape (n_t,).

property inflow: ndarray

Total inflow rate (sum of all inflow sources). Shape (n_t,).

property inflow_net: ndarray

Net inflow rate. Shape (n_t,).

property max_wse: DataFrame

Maximum WSE.

DataFrame with columns ['value', 'time']. value: maximum WSE in model units. time: elapsed simulation time (days) when maximum occurred.

property min_wse: DataFrame

Minimum WSE. Same column layout as max_wse.

property outflow: ndarray

Total outflow rate (sum of all outflow sinks). Shape (n_t,).

property surface_area: ndarray

Water-surface area time series (model area units). Shape (n_t,).

property volume: ndarray

Stored volume time series (model volume units). Shape (n_t,).

property wse: ndarray

Water-surface elevation time series. Shape (n_t,).

class rivia.hdf.unsteady_plan.StorageAreaResultsCollection(hdf)[source]

Bases: StorageAreaCollection

Collection of StorageAreaResults backed by a plan HDF file.

Overrides StorageAreaCollection to return StorageAreaResults with both geometry and plan results.

Parameters:

hdf (h5py.File)

class rivia.hdf.unsteady_plan.StructureResultsCollection(hdf)[source]

Bases: StructureCollection

Plan-enriched structure collection: all structure types with results.

Overrides StructureCollection so each item carries both geometry attributes and time-series result access:

When no plan result group is found for a structure (e.g. DSS output was not requested for that type), the plain geometry object is kept unchanged.

Parameters:

hdf (h5py.File)

class rivia.hdf.unsteady_plan.UnsteadyPlan(filename, program_directory=None)[source]

Bases: _PlanHdf, Geometry

Read HEC-RAS plan HDF5 output files (*.p*.hdf).

A plan HDF file contains the same Geometry/ data as a geometry HDF file, plus Results/Unsteady/... time-series and summary output.

Parameters:
  • filename (str | Path) – Path to the plan HDF file. The .hdf suffix is appended automatically if absent.

  • program_directory (str | Path | None)

Examples

with UnsteadyPlan("MyModel.p01") as hdf:
    ts   = hdf.mapping_timestamps
    area = hdf.flow_areas["spillway"]

    wse   = area.water_surface[10]    # one timestep
    depth = area.depth(10)
    speed = area.cell_speed(10)
    max_d = area.max_depth()

    # requires rasterio + scipy:
    area.export_raster("depth", "depth.tif", timestep=None,
                       cell_size=5.0, crs="EPSG:26910")
    # or get an in-memory dataset:
    ds = area.export_raster("depth", timestep=None, cell_size=5.0)
    arr = ds.read(1)
    ds.close()
property computation_interval: timedelta | None

Base computation time step, or None if absent.

Read from Plan Data/Plan Information attribute Computation Time Step Base. HEC-RAS stores the value as a concatenated number-unit string, e.g. '20SEC', '5MIN', '1HR', '1HOUR', '1DAY'.

compute_errors()[source]

Return key convergence and volume-balance error metrics.

Convenience wrapper: calls compute_summary() and delegates to ComputeSummary.errors(). See that method for full documentation.

See also

ComputeSummary.errors

Full documentation and return-value details.

compute_ok

Quality-control pass/fail check with threshold logging.

Return type:

dict[str, float]

compute_ok(wse_threshold=0.5, volume_error_pct_threshold=1.0, volume_1d_error_pct_threshold=1.0, volume_2d_error_pct_threshold=1.0)[source]

Return True if the simulation completed stably and all error metrics are within their thresholds.

Convenience wrapper: calls compute_summary() and delegates to ComputeSummary.ok(). See that method for full documentation, including parameter descriptions and logging behaviour.

Return type:

bool

Parameters:
  • wse_threshold (float)

  • volume_error_pct_threshold (float)

  • volume_1d_error_pct_threshold (float)

  • volume_2d_error_pct_threshold (float)

Examples

Quick pass/fail check after a run:

if not hdf.compute_ok():
    raise RuntimeError("Simulation quality check failed.")

Custom thresholds:

if not hdf.compute_ok(wse_threshold=0.1, volume_error_pct_threshold=0.5):
    logger.warning("Tight-tolerance check failed.")

See also

ComputeSummary.ok

Full documentation and parameter descriptions.

compute_errors

Raw error metric values.

compute_summary()[source]

Return the full unsteady simulation summary.

Reads all groups under Results/Unsteady/Summary and returns a ComputeSummary dataclass aggregating run metadata, overall volume accounting, 1-D volume accounting, and per-area 2-D volume accounting.

Call ComputeSummary.to_dict() on the result for a nested dict with short, meaningful keys.

Return type:

ComputeSummary

Raises:

KeyError – If Results/Unsteady/Summary is absent — e.g. the file is a steady-flow plan or the simulation has not been run yet.

Examples

with UnsteadyPlan("MyModel.p01") as hdf:
    s = hdf.compute_summary()
    print(s.run.solution)
    print(s.volume.error_pct)
    d = s.to_dict()
property cross_sections: CrossSectionResultsCollection

1-D cross sections with geometry and Base Output results.

Results are at the mapping output interval (mapping_timestamps). All variables are available: water_surface, flow, flow_lateral, velocity_channel, velocity_total, flow_volume_cumulative.

See also cross_sections_output for the DSS hydrograph interval (fewer variables but finer timestep when DSS output was enabled).

property cross_sections_instantaneous: CrossSectionResultsCollection

1-D cross sections with geometry and Post Process Profiles results.

Items are CrossSectionResultsInstantaneous instances. Results are at the instantaneous profile interval (instantaneous_timestamps).

Each result array has shape (n_profiles,) where index 0 is the Max WS profile and indices 1: are the instantaneous profiles. Available variables: water_surface, flow, energy_grade, plus any Additional Variables dataset via additional_variable().

property cross_sections_output: CrossSectionResultsCollection

1-D cross sections with geometry and DSS Hydrograph Output results.

Items are CrossSectionResultsDSS instances. Results are at the hydrograph output interval (output_timestamps). Available variables: water_surface, flow, flow_volume_cumulative.

property flow_areas: FlowAreaResultsCollection

Access 2-D flow areas with both geometry and results data.

property instantaneous_interval: timedelta | None

Instantaneous profile output interval, or None if absent.

Derived from the difference between the first two actual profile timestamps in Profile Dates (i.e. entries at indices 1 and 2, skipping the "Max WS" entry at index 0).

property instantaneous_timestamps: DatetimeIndex

Instantaneous profile output timestamps as a pd.DatetimeIndex.

Parsed from Profile Dates in the Post Process Profiles group, skipping the first entry ("Max WS"). Format: "DDMONYYYY HHMM" (e.g. "01JAN2026 0002").

Use cross_sections_instantaneous[xs].wse[1:] (or [1:n+1]) to align result arrays with this index; index 0 of the result arrays holds the Max WS profile value.

Raises:

KeyError – If the Post Process Profiles group is absent from this HDF file.

property mapping_interval: timedelta | None

Mapping output interval, or None if absent.

Read from Plan Data/Plan Information attribute Base Output Interval. HEC-RAS stores the value as a concatenated number-unit string, e.g. '5MIN'.

property mapping_timestamps: DatetimeIndex

Simulation output time stamps as a pd.DatetimeIndex.

Parsed from the Time Date Stamp dataset written by HEC-RAS. Format: DD Mon YYYY HH:MM:SS (e.g. 03Jan2000 00:00:00).

property n_instantaneous_timestamps: int | None

Number of instantaneous profile time steps, or None if absent.

Reads only the dataset shape — no timestamp data is loaded. The "Max WS" entry at index 0 is excluded from the count.

property n_mapping_timestamps: int | None

Number of mapping output time steps, or None for steady-flow plans.

Reads only the dataset shape — no timestamp data is loaded.

property n_output_timestamps: int | None

Number of DSS hydrograph output time steps, or None if absent.

Reads only the dataset shape — no timestamp data is loaded.

property output_interval: timedelta | None

DSS hydrograph output interval, or None if absent.

Derived from the difference between the first two hydrograph time stamps.

property output_timestamps: DatetimeIndex

DSS hydrograph output time stamps as a pd.DatetimeIndex.

Parsed from Results/.../DSS Hydrograph Output/Unsteady Time Series/Time Date Stamp. Format: DD Mon YYYY HH:MM:SS.

property ras_version: str

HEC-RAS version string from the plan HDF root attribute.

Returns the File Version root attribute, e.g. 'HEC-RAS 6.6 September 2024'.

runtime_log()[source]

Read the runtime compute log from Results/Summary/.

Returns:

Log container with the full text/RTF compute messages, the compute-process table, and unsteady-specific parsing methods such as max_iterations() and adaptive_timesteps().

Return type:

UnsteadyRuntimeLog

Raises:

KeyError – If Results/Summary is absent from the HDF file.

property sa2d_connections: dict[str, SA2DConnection]

SA/2D hydraulic connections keyed by geometry name.

Convenience alias for hdf.structures.connections. Items are SA2DConnectionResults when plan output is present, plain SA2DConnection otherwise.

property storage_areas: StorageAreaResultsCollection

Access storage areas with both geometry and plan results data.

property structures: StructureResultsCollection

Access all structures with geometry and plan results.

Returns a StructureResultsCollection where each item is upgraded to the matching results class when plan output is present:

Use connections, inlines, laterals, and bridges for filtered access.

class rivia.hdf.unsteady_plan.VolumeAccounting(units, vol_start, vol_end, inflow, outflow, error, error_pct)[source]

Bases: object

Overall volume accounting from Results/Unsteady/Summary/Volume Accounting.

Covers the full model (1D + 2D combined).

Variables:
  • units – Volume units string written by HEC-RAS, e.g. "Acre Feet" or "1000 m^3".

  • vol_start – Total storage volume at the start of the simulation.

  • vol_end – Total storage volume at the end of the simulation.

  • inflow – Total boundary flux of water into the model.

  • outflow – Total boundary flux of water out of the model.

  • error – Volume balance error (vol_start + inflow - outflow - vol_end).

  • error_pct – Volume balance error as a percentage of total inflow.

Parameters:
error: float
error_pct: float
inflow: float
outflow: float
to_dict()[source]

Return a dict with short, meaningful keys.

Return type:

dict[str, Any]

units: str
vol_end: float
vol_start: float
class rivia.hdf.unsteady_plan.VolumeAccounting1D(units, reach_vol_start, reach_vol_end, sa_vol_start, sa_vol_end, flow_us_in, flow_ds_out, hydro_lat, hydro_sa, diversions, groundwater, precip_excess)[source]

Bases: object

1-D component volume accounting from Volume Accounting 1D.

Variables:
  • units – Volume units string, e.g. "Acre Feet" or "1000 m^3".

  • reach_vol_start – Total 1-D reach storage at simulation start.

  • reach_vol_end – Total 1-D reach storage at simulation end.

  • sa_vol_start – Storage-area volume at simulation start.

  • sa_vol_end – Storage-area volume at simulation end.

  • flow_us_in – Cumulative upstream inflow across all reaches.

  • flow_ds_out – Cumulative downstream outflow across all reaches.

  • hydro_lat – Cumulative lateral hydrograph exchange (positive = into model).

  • hydro_sa – Cumulative storage-area hydrograph exchange.

  • diversions – Cumulative diversions (negative = water removed).

  • groundwater – Cumulative groundwater exchange.

  • precip_excess – Cumulative precipitation excess (rainfall-runoff applied to reaches).

Parameters:
diversions: float
flow_ds_out: float
flow_us_in: float
groundwater: float
hydro_lat: float
hydro_sa: float
precip_excess: float
reach_vol_end: float
reach_vol_start: float
sa_vol_end: float
sa_vol_start: float
to_dict()[source]

Return a dict with short, meaningful keys.

Return type:

dict[str, Any]

units: str
class rivia.hdf.unsteady_plan.VolumeAccounting2DArea(units, vol_start, vol_end, cum_inflow, cum_outflow, error, error_pct)[source]

Bases: object

Volume accounting for one named 2-D flow area.

One instance per child group under Results/Unsteady/Summary/Volume Accounting/Volume Accounting 2D.

Variables:
  • units – Volume units string, e.g. "Acre Feet" or "1000 m^3".

  • vol_start – 2-D flow area storage at simulation start.

  • vol_end – 2-D flow area storage at simulation end.

  • cum_inflow – Cumulative inflow into this 2-D area.

  • cum_outflow – Cumulative outflow out of this 2-D area.

  • error – Volume balance error for this area.

  • error_pct – Volume balance error as a percentage of cumulative inflow.

Parameters:
cum_inflow: float
cum_outflow: float
error: float
error_pct: float
to_dict()[source]

Return a dict with short, meaningful keys.

Return type:

dict[str, Any]

units: str
vol_end: float
vol_start: float