Refine climate metrics and data pipeline

This commit is contained in:
2026-07-24 22:55:14 -04:00
parent 016f7386d8
commit 4e2d878e5b
32 changed files with 3557 additions and 3347 deletions
+28 -7
View File
@@ -25,7 +25,6 @@ import numpy as np
import pandas as pd
import xarray as xr
STATE_FIPS_TO_ABBR = {
"01": "AL",
"04": "AZ",
@@ -80,6 +79,7 @@ STATE_FIPS_TO_ABBR = {
CONUS_STATE_FIPS = set(STATE_FIPS_TO_ABBR)
REQUIRED_VARIABLES = ("sph", "rmax", "rmin")
SUMMER_MONTHS = {6, 7, 8}
DEFAULT_HEAT_INDEX_THRESHOLD_F = 90.0
NOAA_REGION_CODE_TO_FIPS_OVERRIDES = {
"18511": "11001",
}
@@ -436,8 +436,12 @@ def _county_means_chunk(
def _heat_index_f(t_f: np.ndarray, rh_pct: np.ndarray) -> np.ndarray:
"""Return the NWS Heat Index for Fahrenheit temperature and percent RH."""
rh = np.clip(rh_pct, 0, 100)
heat_index = (
simple_heat_index = 0.5 * (t_f + 61.0 + ((t_f - 68.0) * 1.2) + (rh * 0.094))
simple_heat_index = (simple_heat_index + t_f) / 2
regression_heat_index = (
-42.379
+ 2.04901523 * t_f
+ 10.14333127 * rh
@@ -451,9 +455,17 @@ def _heat_index_f(t_f: np.ndarray, rh_pct: np.ndarray) -> np.ndarray:
low_rh_adjustment = ((13 - rh) / 4) * np.sqrt(np.maximum((17 - np.abs(t_f - 95)) / 17, 0))
high_rh_adjustment = ((rh - 85) / 10) * ((87 - t_f) / 5)
heat_index = np.where((rh < 13) & (80 <= t_f) & (t_f <= 112), heat_index - low_rh_adjustment, heat_index)
heat_index = np.where((rh > 85) & (80 <= t_f) & (t_f <= 87), heat_index + high_rh_adjustment, heat_index)
return np.where(t_f >= 80, heat_index, t_f)
regression_heat_index = np.where(
(rh < 13) & (80 <= t_f) & (t_f <= 112),
regression_heat_index - low_rh_adjustment,
regression_heat_index,
)
regression_heat_index = np.where(
(rh > 85) & (80 <= t_f) & (t_f <= 87),
regression_heat_index + high_rh_adjustment,
regression_heat_index,
)
return np.where(simple_heat_index >= 80, regression_heat_index, simple_heat_index)
def _time_dimension(data_array: xr.DataArray, lat_dim: str, lon_dim: str) -> str:
@@ -646,7 +658,8 @@ def summarize(args: argparse.Namespace) -> None:
"gridmetSource": (
f"gridmet-{source_period} county-cell-weighted; "
"relative-humidity=(rmax+rmin)/2; "
"humidHeatDays=noaa-nclimgrid-tmax+gridmet-rmin heat-index-gte-90f"
"humidHeatDays=noaa-nclimgrid-tmax+gridmet-rmin "
f"heat-index-gte-{args.heat_index_threshold_f:g}f"
),
}
)
@@ -680,7 +693,15 @@ def main() -> int:
parser.add_argument("--years", type=_parse_years, default=None, help="Optional comma/range years, e.g. 1991-2020.")
parser.add_argument("--start-year", type=int, default=None)
parser.add_argument("--end-year", type=int, default=None)
parser.add_argument("--heat-index-threshold-f", type=float, default=90.0)
parser.add_argument(
"--heat-index-threshold-f",
type=float,
default=DEFAULT_HEAT_INDEX_THRESHOLD_F,
help=(
"Daily Heat Index threshold in F. The default 90 F is the lower "
"bound of the NWS Extreme Caution category."
),
)
parser.add_argument("--chunk-days", type=int, default=31)
summarize(parser.parse_args())
return 0