Skip to content

Loss Estimation#

Use this module after the damage-probability library exists and an exposure export (M, C, continuous hazard IDs, building values and zone ids) has been prepared. It turns the library into expected loss-ratio lookup tables, computes building-by-event loss ratios and expected annual loss (EAL), and aggregates the EAL to zones.

Classes#

Page Use when
DamageProbabilityProvider You need the damage-state probability library, or a joint (wind, flood) damage ratio for one building and one hazard pair.
LookupTableBuilder You need the wind-only and flood-only expected loss-ratio tables (L_mcw_wd, L_mcf_fld) or the full wind-flood surface.
BuildingLossEstimator You need loss ratios per building and event, or the expected annual loss per building.
RegionalLossEstimator You need EAL sums per zone (optionally in a coarser nested zone system) and regional loss per event.
LossEstimation You want the end-to-end orchestrator that returns every result at once.

The classes form one inheritance chain, BaseLossEstimation -> LookupTableBuilder -> BuildingLossEstimator -> RegionalLossEstimator -> LossEstimation; DamageProbabilityProvider is used by composition.

Shared Inputs#

File Shape Units or indexing Used by
Damage library pickle (prob_ds_file_path) dict[(m, c) -> (25, 136, 50)] Probability over the 50 damage states per wind ID and flood ID; keys are 1-based (M, C). The default is Outputs/ProbDS_wfd_dictMaxIter{NUM_OF_ITERATIONS}_aggregated.pkl; the Eastern North Carolina run used ProbDS_cwfd_MaxIter3000_V2.pkl. Provider, lookup tables, joint mode
Inputs/DamageState.json [50, 2] damage-state id, loss ratio 0 to 1.4 of the structure value Lookup tables
Inputs/WindSpeed.json [25, 3] id, mph, m/s Provider queries
Inputs/FloodDepth.json [136, 3] id, inches, m Provider queries
Inputs/Hurricane_ProbWindFlood.json["Hurricane_Prob"] [97, 2] event id 1..97, annual probability p_h; the sum is 0.3235 per year and is not normalized Expected annual loss
Exposure export (inventory_csv_path, wind_ids_path, flood_ids_path) n_buildings rows, (n_buildings, n_events) arrays Inventory.csv with M, C, structure_value, contents_value, home_value and the zone column; Wind_Tr.npy / Flood_Tr.npy continuous 1-based IDs Building and regional losses
Zone layer (zones_path) polygons Needed only to remap the zone column onto a coarser system such as i_lh503 Regional losses

Paths left as None resolve under Config.INPUTS_PATH; the exposure export defaults to <Config.OUTPUTS_PATH>/exposure/, and outputs go to <Config.OUTPUTS_PATH>/loss_estimation/.

Lookup Table Definition#

The damage library is the lookup table L : (M, C, w, f) -> p = [p_1, ..., p_50], where M is the structural archetype, C the resistance configuration, w the wind-speed ID (mph knots), f the flood-depth ID (inch knots) and p the probability of each damage state. The damage states are loss ratios from 0% to 140% of the structure's value (DamageState.json), so the expected loss ratio of one (M, C, w, f) is sum_d p_d DR_d. The loss-estimation module precomputes that expectation once per table entry; everything downstream is table indexing.

The earlier Inventory-Loss Link documentation described a Z variable, a Lookup.pkl, a Loss_DF.parquet and zone output trees. None of those are implemented here; the terminology above is what the package uses.

Configuration Behavior#

Config.AUTO_LOAD_DATASETS=True makes __post_init__ load the library through the provider, the event probabilities, the exposure export (when its files exist) and the zone layer. Config.AUTO_EXECUTE_METHODS=True then builds the lookup tables and, when an export is loaded, building_eal, aggregation_key, zone_eal and event_losses. With the flags off, call the load_* methods and assign the calculate_* results yourself. Config.NUM_OF_ITERATIONS names the default library file, and Config.INPUTS_PATH / Config.OUTPUTS_PATH resolve the path fields.

Minimal Examples#

Automatic initialization from a saved exposure export:

from cheersafe.loss_estimation import LossEstimation

estimator = LossEstimation(
    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",
    zones_path="Inputs/zones.gpkg",
    aggregation_col="i_lh503",
)
print(estimator.zone_eal.head())
paths = estimator.save_all_outputs()

Manual dependency injection, where the caller assigns every returned value:

from cheersafe.config import Config
from cheersafe.loss_estimation import LossEstimation

Config.AUTO_LOAD_DATASETS = False
Config.AUTO_EXECUTE_METHODS = False

estimator = LossEstimation(
    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",
    index_mode="floor",
    combine_mode="additive",
    value_basis="structure_value",
)
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]
estimator.building_eal = estimator.calculate_building_eal(
    estimator.building_table, estimator.wind_ids, estimator.flood_ids, probabilities
)
estimator.aggregation_key = estimator.calculate_aggregation_key(
    estimator.building_table, None, "i_lh740", None
)
estimator.zone_eal = estimator.calculate_zone_eal(estimator.building_eal, estimator.aggregation_key)
estimator.event_losses = estimator.calculate_event_losses(
    estimator.building_table, estimator.wind_ids, estimator.flood_ids, probabilities
)