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
)
Related References#
- API: Loss Estimation
- Upstream: Exposure
- Related notebook: Loss Estimation Workflow
- Related notebook: Eastern North Carolina Loss Figures