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:combinedis read from the full surfacecalculate_expected_ratio_surface, which keeps the wind-flood interaction encoded in the library. Underlinearthe 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())
Related References#
- API: Loss Estimation
- Previous step: LookupTableBuilder; next step: RegionalLossEstimator
- Related notebook: Loss Estimation Workflow