Documentation

ClimateCast Documentation

How climate, demographic, and risk values are computed for each location.

This document explains how ClimateCast computes the climate, demographic, and risk values shown for each location. It is written for a technically literate reader who wants to understand where the numbers come from and whether they should trust them.

Geography

Each ZIP code is represented by a single latitude and longitude used for all climate data lookups. We use a centroid hierarchy to pick the most representative point:

  1. Primary source: HUD population-weighted centroid. The U.S. Department of Housing and Urban Development publishes pre-computed centroids that reflect where residents are concentrated within each ZIP code, rather than the geometric center of the ZIP's boundary.
  2. Fallback: ZCTA geometric centroid. When HUD does not provide a centroid for a given 5-digit ZIP code, we fall back to the geometric center of the Census Bureau's ZIP Code Tabulation Area (ZCTA) polygon from TIGER/Line 2023.
  3. Land-snap. If the chosen point falls in water (common for coastal ZIPs), we shift it inland to the nearest land pixel using a CONUS land mask derived from WorldClim.
Output fields:
FieldDescription
meta.centroid_sourceEither "hud_population_weighted" or "zcta_geometric_fallback".
meta.large_zctatrue when the ZCTA spans more than 50 km.
meta.coastal_water_zctatrue when the ZCTA is predominantly water and climate data is unavailable.
meta.usps_preferred_cityOptional. USPS preferred city from HUD (USPS_ZIP_PREF_CITY), used for the location report headline when present.
meta.zcta_boundaryOptional. Simplified ZCTA outline as GeoJSON for the county/ZIP map section.

Current Monthly Climate

Source: WorldClim historical monthly weather (CRU-TS 4.09 downscaled with WorldClim 2.1), averaged over the 2005–2024 reference period, 2.5 arc-minute resolution (~4.6 km per pixel).

Method: Year-by-year monthly rasters over 2005–2024 are averaged per calendar month, then point-sampled at the representative latitude and longitude selected for each ZIP. No area-averaging is performed; each ZIP gets the value of the single grid cell containing its representative point.

Output fields:
FieldDescription
climate.current.monthly.tmin_c12-element array of monthly minimum temperature in °C.
climate.current.monthly.tmax_c12-element array of monthly maximum temperature in °C.
climate.current.monthly.prec_mm12-element array of monthly total precipitation in mm.

Attribution: Fick, S.E. and R.J. Hijmans, 2017. WorldClim 2: new 1-km spatial resolution climate surfaces for global land areas. International Journal of Climatology 37(12): 4302–4315.

Extreme Heat Days and Wet-Bulb Days (Current)

These metrics require daily temperature distributions and cannot be derived from WorldClim monthly means alone. We compute them from NOAA's Global Historical Climatology Network Daily (GHCNd) dataset.

Station Selection

RuleDetail
Baseline period2005–2024 (recent 20-year window)
Quality thresholdAt least 16 complete years during 2005–2024
ZIP assignmentNearest qualifying station within 150 km; otherwise values are null

The assigned station is recorded in:

FieldDescription
climate.current.monthly.noaa_station_idNOAA GHCNd station identifier for the assigned station.
climate.current.monthly.noaa_station_distance_kmDistance from the ZIP centroid to that station.

Heat Day Thresholds

For each month, ClimateCast counts the average annual days where TMAX exceeds the threshold below.

ThresholdField
90 °F (32.2 °C)climate.current.monthly.heat_days_90f
95 °F (35.0 °C)climate.current.monthly.heat_days_95f
100 °F (37.8 °C)climate.current.monthly.heat_days_100f

Wet-Bulb Temperature Calculation

Wet-bulb temperature (Tw) uses the Stull (2011) empirical approximation:

Tw = T · atan(0.151977 · (RH + 8.313659)^0.5)
   + atan(T + RH)
   - atan(RH − 1.676331)
   + 0.00391838 · RH^1.5 · atan(0.023101 · RH)
   − 4.686035

Where T is dry-bulb temperature in °C and RH is relative humidity in %.

Relative humidity is derived from TMAX and dew-point using the Magnus formula. When dew-point is missing, ClimateCast uses TMIN as a dew-point proxy (a conservative approach that can bias wet-bulb counts high in arid climates).

ThresholdField
28 °C wet-bulb exceedance daysclimate.current.monthly.wet_bulb_days_28c
30 °C wet-bulb exceedance daysclimate.current.monthly.wet_bulb_days_30c

Frost Dates

MetricDefinitionField
Last spring frostLatest day in spring (Jan–Jun) with TMIN ≤ 28 °Fclimate.current.frost.last_spring_frost_doy
First fall frostEarliest day in fall (Jul–Dec) with TMIN ≤ 28 °Fclimate.current.frost.first_fall_frost_doy

Future Monthly Climate

Source: WorldClim CMIP6 downscaled projections, 10 arc-minute resolution (~18 km per pixel on the UC Davis mirror), point-sampled at the same representative location as historical data (nearest finite cell search handles occasional coastal nodata on the coarse grid).

Scenarios and Time Periods

ClimateCast exposes three SSP pathways:

Frontend labelSSP scenarioApproximate warming by 2100
Low emissionsSSP1-2.6~1.8 °C
Medium emissionsSSP2-4.5~2.7 °C
High emissionsSSP5-8.5~4.4 °C

Each scenario includes four 20-year windows:

Label in API / UITwenty-year window
"2040"2021–2040
"2060"2041–2060
"2080"2061–2080
"2100"2081–2100

Multi-Model Mean

Future values are averaged across eight WorldClim CMIP6 GCMs (same set for every emissions pathway):

  1. ACCESS-CM2
  2. BCC-CSM2-MR
  3. CNRM-CM6-1
  4. CNRM-ESM2-1
  5. CanESM5
  6. IPSL-CM6A-LR
  7. MIROC6
  8. MRI-ESM2-0

GFDL-ESM4 (the ninth GCM on WorldClim) is excluded because the UC Davis download mirror lacks complete coverage for the SSPs we use.

Output fields:

Scenario keys are low, mid, and high; period keys are 2040, 2060, 2080, and 2100 (each maps to the twenty-year windows above). All monthly.* arrays are 12 elements (Jan–Dec). In the paths below, <tier> is one of low, mid, or high, and <window> is one of 2040, 2060, 2080, or 2100.

FieldDescription
climate.future.sourceDataset note for projections (8-model mean), when present.
climate.future.scenarios.<tier>.sourcePer-scenario CMIP6 ensemble note (same eight-model mean), when present.
climate.future.scenarios.<tier>.sspSSP label (e.g. SSP1-2.6), when present.
climate.future.scenarios.<tier>.periods.<window>.periodHuman-readable window label, when present.
climate.future.scenarios.<tier>.periods.<window>.monthly.tmin_cMonthly minimum temperature in °C.
climate.future.scenarios.<tier>.periods.<window>.monthly.tmax_cMonthly maximum temperature in °C.
climate.future.scenarios.<tier>.periods.<window>.monthly.prec_mmMonthly total precipitation in mm.
climate.future.scenarios.<tier>.periods.<window>.monthly.heat_days_90fTwelve monthly values recomputed with the delta method below; same semantics as the current monthly 90 °F heat-day series.
climate.future.scenarios.<tier>.periods.<window>.monthly.wet_bulb_days_28cMonthly wet-bulb exceedance counts at 28 °C.
climate.future.scenarios.<tier>.periods.<window>.monthly.wet_bulb_days_30cMonthly wet-bulb exceedance counts at 30 °C.
climate.future.scenarios.<tier>.periods.<window>.frost.last_spring_frost_doyLast spring frost day-of-year.
climate.future.scenarios.<tier>.periods.<window>.frost.first_fall_frost_doyFirst fall frost day-of-year.

Delta Method for Future Heat and Wet-Bulb Days

ClimateCast uses a mean-shift (delta) approach:

  1. Compute Δtmax = CMIP6_future_tmax − WorldClim_historical_tmax
  2. Shift the historical daily TMAX distribution by Δtmax
  3. Recount threshold exceedances and recompute wet-bulb days

This method does not model shifts in variance/tails, only the mean.

Climate analog (reference locations)

Shows which existing places have a baseline climate most similar to this ZIP's projected future — one closest match from the combined U.S. + international catalog. This is an illustrative similarity in climate-variable space, not a forecast that a ZIP "becomes" another city.

How it works

The app compares each reference location's WorldClim / CRU-TS 4.09 (2005–2024) baseline against this ZIP's projected monthly climate (CMIP6 multi-model mean for the selected scenario and period) across seven dimensions:

DimensionDefinition
Mean annual daily high (°F)Mean of 12 monthly tmax, converted from °C
Mean annual daily low (°F)Mean of 12 monthly tmin, converted from °C
Annual precipitation (in)Sum of 12 monthly prec_mm, converted to inches
Aridity indexMAP (mm) / MAE (mm), Hargreaves-style reference evaporation by latitude. Same formula as Drought Risk below. Undefined cases excluded.
Temperature seasonality (°C)Max monthly tmax − min monthly tmin (continental vs maritime)
Precipitation phase (cos)When rain falls: months placed on a circle and weighted by rainfall give a vector, rotated so the local warm season sits at 0°. cos > 0 = warm-season-wet (monsoon), cos < 0 = cool-season-wet (Mediterranean). Hemisphere-agnostic.
Precipitation phase (sin)Quadrature component of the same precipitation-timing vector.

Distance calculation

All reference features are z-scored using means and standard deviations from the full reference set. The projected vector is z-scored with the same parameters. Distance is weighted Euclidean in z-space with weights: mean high 2.2, mean low 2.2, aridity index 1.9, temperature seasonality 0.85, precipitation phase 0.7 each (cos and sin), and annual precipitation 0.8. Temperature is weighted most, followed by aridity; annual precipitation is down-weighted because it overlaps heavily with the aridity and precipitation-phase dimensions.

The single closest row from the full combined reference set is reported. The user's own location is excluded from candidates by ZIP and by normalized place name + state (same city at a different catalog ZIP).

When it's omitted

The section is hidden when the reference dataset fails to load, monthly futures are incomplete, or centroid latitude is missing. Centroid longitude is only needed for the map arcs.

Downloads (same origin as the site; use “Save link as…” if your browser opens JSON instead of downloading):

ResourceNotes
climate-analog-reference.jsonBuilt reference data (JSON).

Drought Risk

Drought risk is derived, not pass-through from an external risk tier dataset. It uses an Aridity Index (AI):

AI = MAP / MAE

Where:

SymbolMeaning
MAPMean annual precipitation (mm)
MAEMean annual potential evapotranspiration (Hargreaves-Samani estimate)

Classification thresholds:

AI rangeDrought risk levelUNEP climate zone
AI < 0.05very_highHyper-arid
0.05 ≤ AI < 0.20highArid
0.20 ≤ AI < 0.50elevatedSemi-arid
0.50 ≤ AI < 0.65moderateDry sub-humid
AI ≥ 0.65lowHumid
Output field:
FieldDescription
risks.drought.levelBinned drought risk level from the AI ranges above.

Risk Level Binning

ClimateCast reports eight risk categories:

  • Six county-level scores from ProPublica/Rhodium
  • One storm intensity category from EPA CREAT
  • One derived drought category

ProPublica / Rhodium Group Risks

Categories: heat, wet_bulb, farm_crop_yields, sea_level_rise, very_large_fires, economic_damages.

ProPublica publishes county-level scores on a 1–10 scale. ClimateCast bins those scores:

Score rangeRisk level
1–2low
3–4moderate
5–6elevated
7–8high
9–10very_high

Storm Intensity (EPA CREAT)

Category: storm_intensity

Binning thresholds:

% change in intensityRisk level
< 10%low
10–20%moderate
20–30%elevated
30–40%high
≥ 40%very_high

Null Reason Values

null_reason valueWhen it applies
"no_data_for_state"Unsupported state coverage in source datasets.
"missing"Other missingness causes.

Demographics

Three demographic fields are included as pass-through values from named sources.

TopicSourceGeographyOutput field(s)
Median household incomeU.S. Census ACS 5-year estimates (B19013_001E)ZCTAdemographics.median_household_income_usd
Life expectancyCDC USALEEP (2010–2015)Census tract aggregated to ZCTAdemographics.life_expectancy_years, demographics.life_expectancy_period
Plant hardiness zoneUSDA PHZM 2023demographics.plant_hardiness_zone

On city and county pages (see City and County Pages), median household income and total population are pulled directly from ACS at the Census place and county summary levels rather than aggregated from ZIP values, so they are the official figures for the whole place or county.

ZIP-to-County Assignment

Each ZIP is assigned to a single county for county-level risk joins.

AspectDetail
SourceHUD USPS ZIP Crosswalk
RuleSelect county with highest residential-address share
Output fields:
FieldDescription
meta.county_fipsAssigned county FIPS code.
meta.county_nameAssigned county name.
meta.stateState for the assigned county.
meta.crosswalk_vintageHUD crosswalk file vintage used for the assignment.

Representative ZIP per county

Each county also has one representative ZIP, used for the county page's climate data (see City and County Pages) and as the climate source for that county.

AspectDetail
SourceHUD USPS ZIP Crosswalk (same quarterly file), with optional ACS ZIP population as a tie-break helper
GoalAvoid selecting a large metro ZIP that only partially overlaps the clicked county and is primarily associated with a neighboring county.

Selection order (first match wins; later steps break ties):

StepCriterion
1Prefer ZIPs where that county is the ZIP's primary county (highest residential share for that ZIP).
2Then highest county share (res_ratio).
3Then highest ZIP population (if available).
4Final tie-break by ZIP code for deterministic output.

City and County Pages

Alongside ZIP reports, ClimateCast publishes city and county pages. Searching for a city opens its city page, and clicking a county in the county-risk map opens that county page.

Geography

Page typeEntityRoute
CityU.S. Census place (STATEFP + PLACEFP, 7 digits)/city/{geoid}
CountyCounty FIPS (5 digits)/county/{fips}
ZIP5-digit ZIP / ZCTA/location/{zip}

How values are sourced

DataCity pageCounty page
Income & populationACS at the place levelACS at the county level
ClimateRepresentative ZIP for the placeRepresentative ZIP for the county
Life expectancy & plant hardinessRepresentative ZIPRepresentative ZIP
RisksRepresentative ZIP's countyThe county itself

Income and population are read directly from ACS for the whole place or county, so they are not a single ZIP's numbers nor an average of ZIP medians. Climate, life expectancy, and plant hardiness use one representative ZIP (see Representative ZIP per county for how the county ZIP is chosen). For cities, the pipeline first picks the highest-population allowed ZCTA whose centroid falls inside the Census place; if none qualify, it uses the highest-population ZCTA that intersects the place polygon.

Search routing

Search routes by the selected result's place type: a city or locality opens the matching city page, an administrative area opens the county page, and a ZIP code or street address opens the ZIP page. The city search index lists only places with a published city/{geoid}.json (representative ZIP must exist in the location dataset). When a city can't be matched to that index, search shows an error instead of silently falling back to a ZIP page.

Known Limitations

TopicDetail
Life expectancyCDC tract-based values are from 2010–2015.
ProPublica / Rhodium risksCounty scores are from 2020 and based on RCP 8.5.
EPA CREAT (storm intensity)Coarse 0.5° grid and may miss sub-county variation.
Wet-bulb estimatesTMIN-as-dew-point proxy can overestimate humidity for some stations.
Future heat / wet-bulb (delta method)Adjusts mean but not variance/tails.
CMIP6 multi-model meanUses eight GCMs (excludes GFDL-ESM4 — incomplete on the UC Davis mirror for our SSPs).
Climate analog “match”Similarity in a few z-scored climate averages (current references vs your selected projected window); not a full ecological forecast; references use 2005–2024 baselines only.
City / county climateUses a single representative ZIP, not an area average; a city or county that spans multiple climates is summarized by one point. Risks for a city reflect its representative ZIP's county.

Data Sources