Skip to content

RASMapper Stored Maps: Arrival Time, Duration, and Percent Time Inundated

RasProcess.store_maps() generates rendered result rasters through the HEC-RAS mapping engine (RasMapperLib via the bundled RasStoreMapHelper.exe). This notebook covers the whole-simulation map types added alongside the profile-based ones (WSE, Depth, Velocity, ...):

Parameter RasMapperLib MapType Output label
arrival_time=True arrival time Arrival Time (0.5ft hrs).tif
duration=True duration Duration (0.5ft hrs).tif
percent_inundated=True fraction inundated Percent Time Inundated (0.5ft).tif

Key behaviors:

  • These types are computed over the entire simulation — the profile argument does not apply to them (profile-based types in the same call still honor it).
  • arrival_depth sets the wet/dry depth threshold (model vertical units) and appears in the output filenames instead of a profile name.
  • RasMapperLib builds a PostProcessing.hdf cache for these products that can exceed the plan HDF in size — plan disk space accordingly.
  • There is no recession MapType in RasMapperLib (verified against the 6.6 and 7.0.1 MapTypes tables); only RasMapperLib-native products are offered.

Requirements: Windows, HEC-RAS 6.6+, and a computed plan HDF.

Python
# Install ras-commander if needed (uncomment)
# %pip install ras-commander

from pathlib import Path

from ras_commander import RasExamples, init_ras_project, RasCmdr, RasProcess

1. Extract the example project and compute a plan

BaldEagleCrkMulti2D ships without results, so we compute plan 07 first (a 2D dam-break run — takes several minutes). Skip the compute cell if the plan HDF already exists from a previous session.

Python
project_path = RasExamples.extract_project("BaldEagleCrkMulti2D")
ras = init_ras_project(project_path, ras_object="new")

plan_hdf = project_path / "BaldEagleDamBrk.p07.hdf"
print(f"Plan HDF exists: {plan_hdf.exists()}")
Python
if not plan_hdf.exists():
    RasCmdr.compute_plan("07", ras_object=ras)
    print(f"Computed. Plan HDF exists: {plan_hdf.exists()}")

2. Generate arrival time, duration, and percent-inundated maps

A single store_maps() call injects the stored-map definitions into the .rasmap (restored afterwards from backup), runs StoreAllMaps once, and moves the outputs to output_path. Here we use a 0.5 ft wet/dry threshold.

Python
output_dir = project_path / "whole_simulation_maps"

results = RasProcess.store_maps(
    plan_number="07",
    output_path=output_dir,
    wse=False,
    depth=False,
    velocity=False,
    arrival_time=True,
    duration=True,
    percent_inundated=True,
    arrival_depth=0.5,
    render_mode="sloping",
    ras_object=ras,
    timeout=3600,
)

for map_type, paths in results.items():
    print(f"{map_type}:")
    for p in paths:
        print(f"  {Path(p).name}")

3. Validate the outputs

Physically sensible ranges for a 72-hour dam-break simulation: arrival within 0–72 hrs, duration up to 72 hrs (still inundated at the end of the run), and percent time inundated within 0–100%.

Python
import rasterio

for map_type, paths in results.items():
    for p in paths:
        with rasterio.open(p) as ds:
            data = ds.read(1, masked=True)
            print(
                f"{Path(p).name}: crs={ds.crs}, "
                f"wet_px={data.count():,}, "
                f"range={data.min():.2f} to {data.max():.2f}"
            )

4. Visualize arrival time

Hours (from simulation start) for water to first reach the 0.5 ft depth threshold — the propagation of the dam-break wave down the valley.

Python
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 3, figsize=(18, 6))
titles = ["arrival_time", "duration", "percent_inundated"]
cmaps = ["viridis", "plasma", "cividis"]
units = ["hours", "hours", "%"]

for ax, key, cmap, unit in zip(axes, titles, cmaps, units):
    if not results.get(key):
        ax.set_title(f"{key} (not generated)")
        continue
    with rasterio.open(results[key][0]) as ds:
        data = ds.read(1, masked=True)
    im = ax.imshow(data, cmap=cmap)
    ax.set_title(key)
    ax.set_axis_off()
    fig.colorbar(im, ax=ax, shrink=0.7, label=unit)

plt.tight_layout()
plt.show()

Notes

  • Combine whole-simulation and profile-based types in one call — e.g. wse=True, depth=True, arrival_time=True, profile="Max" renders WSE/Depth at Max while arrival time still spans the full simulation.
  • The ArrivalDepth threshold is written into the rasmap MapParameters; RASMapper's own UI exposes additional start-time controls (ArrivalStartMode, ArrivalAbsDateTime, ...) that are not yet wrapped.
  • For project-free mapping (only a plan HDF + terrain TIFF on hand), see ras2cng's map-hdf command, which scaffolds a minimal project around the HDF and calls store_maps().
  • Clean up PostProcessing.hdf from the output folder when done — it is a RasMapperLib cache, not a deliverable.