# Hazard score calibration

Model 4.2. GENERATED by `scripts/generate-hazard-calibration.ts` from `lib/modeling/hazard-curves.ts` and the seeded scoring constants in `lib/modeling/model-parameters.ts`; `tests/docs/hazard-score-calibration-drift.test.ts` fails when this file and the code disagree. Do not edit by hand.

## What the score is

Each peril's 0-10 score is the **hazard** components alone, rescaled to their own weight:

```
score = round1( min( 10, 10 × Σ hazard points / Σ hazard max ) )
```

It is an ordinal index for ranking locations against each other on the frequency and intensity of the peril at that point. It is not a probability, a return period, or a loss, and it carries no property, occupancy or policy information. Components with role `proxy` — stand-ins for vulnerability or consequence — are computed, returned under `proxy_score`, and **excluded** from the score (credibility M-08).

The severity bands — EXTREME ≥ 8.5, HIGH ≥ 6.5, MODERATE ≥ 4, else LOW (`lib/peril-colors.ts`) — are presentation thresholds chosen for legibility of the 0-10 scale. They are not calibrated against losses or observed event rates and should not be read as risk classes.

## Components and roles

### earthquake

| Component | Input | Max | Role |
| --- | --- | --- | --- |
| USGS 2023 NSHM ground motion | PGA with a 2% chance of exceedance in 50 years, site class BC, g | 10.0 | hazard |
| Historical damage potential (Hazus W1 thresholds) | regional W1 slight-damage MMI | 3.5 | proxy |

Hazard weight 10.0; score = 10 × hazard points / 10.0.
Worked example — every hazard component at half its max, every proxy at full: score 5.0, proxy_score 3.50 / 3.50 (excluded).

Fallback, outside the USGS NSHM grids (Puerto Rico and the other territories):

| Component | Input | Max | Role |
| --- | --- | --- | --- |
| Seismic source zone activity | zone Gutenberg-Richter M5+ rate | 3.5 | hazard |
| Proximity to mapped Quaternary faults | distance to nearest mapped fault, km | 3.0 | hazard |
| Historical damage potential (Hazus W1 thresholds) | regional W1 slight-damage MMI | 3.5 | proxy |

Hazard weight 6.5; score = 10 × hazard points / 6.5.
Worked example — every hazard component at half its max, every proxy at full: score 5.0, proxy_score 3.50 / 3.50 (excluded).

### hurricane

| Component | Input | Max | Role |
| --- | --- | --- | --- |
| CAT3+ landfall return period | segment or scope return period, years | 3.5 | hazard |
| Distance to coastline | distance to coastline, km | 3.0 | hazard |
| Storm surge exposure | ground elevation, ft (coastal sites) | 3.5 | hazard |

Hazard weight 10.0; score = 10 × hazard points / 10.0.
Worked example — every hazard component at half its max, every proxy at full: score 5.0.

### wildfire

| Component | Input | Max | Role |
| --- | --- | --- | --- |
| Large fire frequency | local wildfires of 1,000+ acres per 10,000 km2 a year (MTBS); regional fires of 10,000+ acres a year outside MTBS | 3.5 | hazard |
| Wildland-Urban Interface exposure | share of homes in USFS WRC Direct/Indirect exposure zones, Census place else county, 0-1; NLCD development/wildland mixture outside WRC | 3.5 | hazard |
| Regional vegetation/fuel load proxy | regional constant | 3.0 | proxy |

Hazard weight 7.0; score = 10 × hazard points / 7.0.
Worked example — every hazard component at half its max, every proxy at full: score 5.0, proxy_score 3.00 / 3.00 (excluded).

### flood

| Component | Input | Max | Role |
| --- | --- | --- | --- |
| FEMA flood zone | zone designation | 4.0 | hazard |
| Elevation above base flood | height above BFE, ft | 3.0 | hazard |
| NFIP loss density | county NFIP flood claims per 1,000 homes a year (model 4.0); state FEMA flood declarations a year outside a county with a housing count | 3.0 | hazard |

Hazard weight 10.0; score = 10 × hazard points / 10.0.
Worked example — every hazard component at half its max, every proxy at full: score 5.0.

### winter_storm

| Component | Input | Max | Role |
| --- | --- | --- | --- |
| Winter events per forecast zone | events per year in the point's NWS zone (31 states, model 4.1); state average per zone elsewhere | 5.0 | hazard |
| Ice storm and blizzard share | share of winter events, 0-1 | 5.0 | hazard |

Hazard weight 10.0; score = 10 × hazard points / 10.0.
Worked example — every hazard component at half its max, every proxy at full: score 5.0.

### hail

| Component | Input | Max | Role |
| --- | --- | --- | --- |
| Significant hail days | NEXRAD significant (2 in+) hail days per year within 80 km (model 4.2); state hail-report rate outside radar coverage | 5.0 | hazard |
| Regional roof vulnerability proxy | regional constant | 5.0 | proxy |

Hazard weight 5.0; score = 10 × hazard points / 5.0.
Worked example — every hazard component at half its max, every proxy at full: score 5.0, proxy_score 5.00 / 5.00 (excluded).

### tornado

| Component | Input | Max | Role |
| --- | --- | --- | --- |
| Tornado event density | events per 10,000 km² per year | 5.0 | hazard |
| Manufactured housing density proxy | regional constant | 3.0 | proxy |
| Nocturnal tornado fraction | regional constant | 2.0 | proxy |

Hazard weight 5.0; score = 10 × hazard points / 5.0.
Worked example — every hazard component at half its max, every proxy at full: score 5.0, proxy_score 5.00 / 5.00 (excluded).

## Curves at the seeded constants

Every curve is one of six shapes in `lib/modeling/hazard-curves.ts`. The tables below evaluate each at its US-National seed values; a database row for a scope overrides the seed through the normal parameter chain and would move these numbers for that scope.

### USGS 2023 NSHM ground motion — `logScaleScore(PGA, nshm_pga_floor_g = 0.02 g, nshm_pga_ceiling_g = 1.5 g, 10)` = 10 · ln(PGA / 0.02) / ln(1.5 / 0.02), clamped

| PGA 2% in 50 yr, g | Points |
| --- | --- |
| 0.02 | 0.00 |
| 0.05 | 2.12 |
| 0.1 | 3.73 |
| 0.2 | 5.33 |
| 0.4 | 6.94 |
| 0.8 | 8.54 |
| 1.5 | 10.00 |
| 2.5 | 10.00 |

### Seismic source zone activity — `rateScaleScore(rate, seismic_rate_scale = 2.5, 3.5)`

| Zone M5+ rate /yr | Points |
| --- | --- |
| 0.05 | 0.13 |
| 0.10 | 0.25 |
| 0.50 | 1.25 |
| 1.00 | 2.50 |
| 1.40 | 3.50 |
| 2.00 | 3.50 |

### Fault proximity — `distanceBandScore(km, near 5 km → 3, mid 20 km → 2 then 1 → 0 at 50 km, beyond → 0.3)`

| Distance km | Points |
| --- | --- |
| 0 | 3.00 |
| 5 | 3.00 |
| 10 | 2.67 |
| 20 | 1.00 |
| 35 | 0.50 |
| 50 | 0.30 |
| 100 | 0.30 |

### Historical damage potential (PROXY, excluded) — `thresholdSlopeScore(anchor 8, W1 slight MMI, slope 1.17, 3.5)`

| W1 slight-damage MMI | Points |
| --- | --- |
| 5.0 | 3.50 |
| 5.5 | 2.92 |
| 6.0 | 2.34 |
| 6.5 | 1.75 |
| 7.0 | 1.17 |
| 8.0 | 0.00 |

### CAT3+ landfall return period — `returnPeriodDecayScore(rp, anchor 5 yr, decay 0.03/yr, floor 0.2, 3.5)` = max(floor, 3.5 · e^(−0.03·(rp − 5)))

| Return period yr | Points |
| --- | --- |
| 5 | 3.50 |
| 7.5 | 3.25 |
| 10 | 3.01 |
| 15 | 2.59 |
| 20 | 2.23 |
| 40 | 1.22 |
| 75 | 0.43 |
| 100 | 0.20 |

Per-segment return periods from the NOAA HRD landfall catalogue (1950-2024, counted by first listed landfall state; a site within 250 km of a segment's coastline reads that segment's row, credibility M-24):

| Segment | Landfalls | CAT3+ | Return period yr | Points |
| --- | --- | --- | --- | --- |
| Texas | 19 | 7 | 10.7 | 2.95 |
| Louisiana-Mississippi | 24 | 6 | 12.5 | 2.79 |
| Gulf-Panhandle | 20 | 10 | 7.5 | 3.25 |
| Florida-Gulf | 14 | 7 | 10.7 | 2.95 |
| Florida-Atlantic | 10 | 5 | 15 | 2.59 |
| Southeast-Atlantic | 28 | 7 | 10.7 | 2.95 |
| Mid-Atlantic-Northeast | 5 | 1 | 75 | 0.43 |

### Coastal proximity — `distanceBandScore(km, near 5 km → 3, mid 25 km → 2 then 1 → 0 at 100 km, beyond → 0)`

| Distance km | Points |
| --- | --- |
| 0 | 3.00 |
| 5 | 3.00 |
| 15 | 2.50 |
| 25 | 1.00 |
| 50 | 0.67 |
| 100 | 0.00 |
| 200 | 0.00 |

### Storm surge exposure — elevation bands (coastal sites only)

| Ground elevation | Points |
| --- | --- |
| below 5 ft | 3.50 |
| 5 to 10 ft | 2.50 |
| 10 to 20 ft | 1.50 |
| 20 to 30 ft | 0.50 |
| 30 ft and above | 0.00 |

### Large fire frequency — `rateScaleScore(fires/yr, fire_frequency_scale = 0.3, 3.5)`

| Fires of 10,000+ acres /yr | Points |
| --- | --- |
| 0 | 0.00 |
| 1 | 0.30 |
| 5 | 1.50 |
| 10 | 3.00 |
| 11.7 | 3.50 |
| 20 | 3.50 |
| 50 | 3.50 |

### WUI exposure — `rateScaleScore(mixture, wui_scale = 3.5, 3.5)`

| Development/wildland mixture | Points |
| --- | --- |
| 0.00 | 0.00 |
| 0.25 | 0.88 |
| 0.50 | 1.75 |
| 0.75 | 2.63 |
| 1.00 | 3.50 |

### Full-scale curves — `fullScaleScore(observed, full_scale, 5.0)` = min(5, 5 × observed / full_scale)

Hail density, the state tornado fallback and winter-event frequency are linear in the observed rate up to a full-scale rate that is the most-exposed state's observed value (`hail_full_scale_rate`, `tornado_full_scale_rate`, `winter_events_full_scale_rate`). Those rows live only in the database and have no seed, so they are not evaluated here. The local tornado density (model 3.8) is scaled against `tornado_ef2_local_full_scale_rate`, the 99th percentile of its own grid, generated with it by `scripts/derive-tornado-ef2-density.ts`; the local large-fire density (model 3.9) against `wildfire_local_full_scale_rate`, generated with its grid by `scripts/derive-wildfire-local-density.ts`.

Winter severity uses a seeded full scale, `severe_share_full_scale` = 0.3:

| Ice storm + blizzard share | Points |
| --- | --- |
| 0.00 | 0.00 |
| 0.10 | 1.67 |
| 0.20 | 3.33 |
| 0.30 | 5.00 |
| 0.48 | 5.00 |

## Proxies (excluded from every score)

| Peril | Component | Seeded US-National constant | Why it is a proxy |
| --- | --- | --- | --- |
| earthquake | historical_damage_potential | damage_default 1.5 (regional W1 thresholds where seeded) | How much shaking a wood frame takes before slight damage is a property of the building stock, not the ground. |
| wildfire | fuel_load | fuel_load_default 0.5 (regional rows where seeded) | A hand-typed regional table with no source; its ordering runs close to backwards against NLCD wildland cover. LANDFIRE replacement is open. |
| hail | roof_vulnerability | roof_vulnerability_default 1 (regional rows where seeded) | Roofs are what hail damages, not what makes hail fall. |
| tornado | mobile_home_density | mobile_home_density_default 0.5 (regional rows where seeded) | Who a tornado kills, not whether one comes. |
| tornado | nocturnal_risk | nocturnal_risk_default 0.3 (regional rows where seeded) | A fatality multiplier, not an occurrence rate. |
