Skip to content

BuildingLossEstimator#

BuildingLossEstimator maps the continuous hazard IDs of an exposure export onto the lookup tables, combines wind and flood, and weights the resulting loss ratios by the annual event probabilities to give each building's expected annual loss (EAL). Use it when you need building-by-event loss ratios or the building EAL table.

Inputs#

Inherited from LookupTableBuilder: the tables and the event probabilities.

Field Default Notes
inventory_csv_path Outputs/exposure/Inventory.csv STARR inventory table with M, C, the value columns and the zone column.
wind_ids_path, flood_ids_path Wind_Tr.npy, Flood_Tr.npy next to the inventory Memory-mapped (n_buildings, n_events) arrays. Hurricane_name.npy next to them supplies the event names when present.
zone_id_col i_lh740 Zone column carried into the building results.
index_mode floor How continuous IDs select table bins (below).
combine_mode additive additive or joint (below).
value_basis structure_value structure_value, contents_value or home_value.
chunk_size 100000 Rows processed per chunk when streaming the arrays.

load_exposure_inputs() reads the export from disk and validates that the inventory rows, the array rows and the event count of Hurricane_Prob agree. load_from_exposure(exposure) takes the same export from an in-memory Exposure object through Exposure.calculate_starr_export(), so the zone filter is applied identically on both paths.

Index Conventions#

Wind_Tr and Flood_Tr are continuous, 1-based IDs (for example 2.5 lies between the 50 mph and 55 mph knots). index_mode decides which table bin a value selects:

index_mode Rule Provenance
floor (default) int(id) - 1 The runtime convention of the STARR workflow; reproduces the published Eastern North Carolina EAL maps.
ceil first bin at or above the ID (ceil(id) - 1) The searchsorted mode of the verified STARR export and of DamageProbabilityProvider.
round nearest bin, ties to even (rint(id) - 1) Comparison only.
linear interpolation between the two neighbouring bins over the full ID range The scripts' interpolation clamp never reached the last bin; that clamp is not reproduced.

The convention matters

On the frozen Eastern North Carolina run (unit i_lh503, structure value), the wind EAL maximum under ceil is 40.7% above floor, under round 21.2% above and under linear 20.2% above; the flood and combined maxima move by 2.7% and 4.7% under ceil. State the convention with every result.

Combined Mode#

  • additive (default): combined = wind_lookup[...] + flood_lookup[...], the convention of STARR and of the published figures.
  • joint: combined is read from the full surface calculate_expected_ratio_surface, which keeps the wind-flood interaction encoded in the library. Under linear the surface is interpolated bilinearly.

Adding the two marginals discards that interaction and can push the implied combined ratio above the 1.4 ceiling of the damage states; on the frozen run the largest per-event combined ratio was 1.174 under floor and 1.310 under ceil.

Value Basis#

The monetary loss is loss_ratio * value with value the value_basis column: structure_value (default, the basis of the published figures), contents_value or home_value = structure_value + contents_value. In the frozen inventory contents_value is half the structure value, so home_value overshoots the published panels by 50% to 111%.

Expected Annual Loss#

For building b with per-event loss ratio lr_bh and annual event probability p_h,

EAL_b = sum_h p_h lr_bh value_b.

p_h is column 1 of Hurricane_Prob (97 events, sum 0.3235 per year, not normalized). The arrays are streamed in chunks of chunk_size rows, so the full export of 1.15 million buildings and 97 events stays memory-mapped. Column j of the arrays is event j of Hurricane_Prob; the loaders assert that the counts agree. Pass hurricane_probabilities to BaseLossEstimation to use a custom event set.

Outputs And Returns#

Method Returns
calculate_lookup_loss_ratio(lookup, m0, c0, hazard_id, index_mode) Loss ratios (n_buildings, n_events) from one marginal table; m0, c0 are 0-based (n_buildings, 1) indices.
calculate_joint_loss_ratio(surface, m0, c0, wind_id, flood_id, index_mode) Combined loss ratios from the joint surface.
calculate_event_loss_ratios(m0, c0, wind_id, flood_id, surface=None) (wind, flood, combined) loss ratios for a chunk.
calculate_eal_ratios(building_types, component_configurations, wind_ids, flood_ids, probabilities, surface=None) Wind, flood and combined EAL ratios per building.
calculate_building_eal(building_table, wind_ids, flood_ids, probabilities, surface=None) Table with building_key, building_ID, M, C, the zone column, value, eal_wind_ratio, eal_flood_ratio, eal_combined_ratio, eal_wind, eal_flood, eal_combined.
save_loss_ratios(output_dir=None) Writes LossRatio_WIND.npy, LossRatio_FLOOD.npy, LossRatio_COMBINED.npy as memory-mapped (n_buildings, n_events) files.
save_building_eal(path=None) Writes building_eal.csv.

Configuration Behavior#

With Config.AUTO_LOAD_DATASETS=True, __post_init__ loads the export when its three files exist (otherwise it logs that load_exposure_inputs or load_from_exposure must be called). With Config.AUTO_EXECUTE_METHODS=True it assigns building_eal (and the surface in joint mode) once an export and the tables are available.

Minimal Examples#

Automatic execution from a saved export:

from cheersafe.loss_estimation import BuildingLossEstimator

estimator = BuildingLossEstimator(
    prob_ds_file_path="Outputs/ProbDS_wfd_dictMaxIter3000_aggregated.pkl",
    inventory_csv_path="Outputs/exposure/Inventory.csv",
    wind_ids_path="Outputs/exposure/Wind_Tr.npy",
    flood_ids_path="Outputs/exposure/Flood_Tr.npy",
)
print(estimator.building_eal[["building_ID", "eal_wind", "eal_flood", "eal_combined"]].head())

Manual control comparing index conventions:

from cheersafe.config import Config
from cheersafe.loss_estimation import BuildingLossEstimator

Config.AUTO_LOAD_DATASETS = False
Config.AUTO_EXECUTE_METHODS = False

estimator = BuildingLossEstimator(
    prob_ds_file_path="Outputs/ProbDS_wfd_dictMaxIter3000_aggregated.pkl",
    inventory_csv_path="Outputs/exposure/Inventory.csv",
)
estimator.load_damage_library()
estimator.load_hurricane_probabilities()
estimator.load_exposure_inputs()
estimator.wind_lookup, estimator.flood_lookup = estimator.calculate_marginal_lookups(
    estimator.prob_damage_states, estimator.damage_states[:, 1], 8, 192
)
probabilities = estimator.hurricane_prob[:, 1]
for mode in ("floor", "ceil", "round", "linear"):
    estimator.index_mode = mode
    eal = estimator.calculate_building_eal(
        estimator.building_table, estimator.wind_ids, estimator.flood_ids, probabilities
    )
    print(mode, eal["eal_combined"].sum())