Methodology

How orbitWx computes the odds

Every number in this app is an empirical frequency drawn from three decades of NASA satellite-derived observations. Nothing is modelled, forecast or interpolated beyond what NASA POWER already publishes.

Step 0

The data source

orbitWx reads the NASA POWER Daily Point API. POWER serves meteorology derived from NASA's MERRA-2 assimilation model — satellite observations fused with a physical reanalysis — available from 1 January 1981 to near-present on a 0.5° × 0.625° latitude/longitude grid.

We use 1996-01-01 → 2025-12-31: exactly 30 full calendar years. Your coordinates are snapped to the grid cell POWER actually serves, and the cell used is reported back in every response.

ParameterMeaningUnit
T2M_MAXDaily maximum temperature at 2 m°C
T2M_MINDaily minimum temperature at 2 m°C
T2MDaily mean temperature at 2 m°C
PRECTOTCORRBias-corrected total precipitationmm/day
WS10MWind speed at 10 mm/s
WS2MWind speed at 2 mm/s
RH2MRelative humidity at 2 m%
T2MDEWDew point at 2 m°C

POWER marks missing observations with the fill value -999. Those are removed before any calculation and counted in metadata.fill_value_days.

Step 1

Day-of-year window sampling

A single calendar date gives only 30 observations in 30 years — far too few for a stable probability. So orbitWx widens the target date into a ±7-day window (adjustable 1–15) and pools every matching day across every year:

15 days per year × 30 years = up to 450 observations

The window is built with real date arithmetic in each year, so it wraps correctly across the year boundary — a January 3rd target reaches back into the previous December. A February 29th target falls back to February 28th in non-leap years so leap-day events still get the full record.

Trade-off: a wider window buys statistical stability at the cost of seasonal sharpness. Seven days is the default because most climates change slowly over a fortnight, but the slider is there if your location's season turns fast.

Step 2

Empirical exceedance probability

For each condition we simply count. No distribution is fitted, no parameters are estimated — the probability is the observed frequency:

P(condition) = count(days breaching threshold) / count(valid days)
ConditionVariableDefault threshold
Very HotT2M_MAX> 35 °C
Very ColdT2M_MIN< 5 °C
Very WindyWS10M> 10 m/s
Very WetPRECTOTCORR> 10 mm/day
Very UncomfortableHeat index> 40 °C

Rainfall is additionally reported at three fixed tiers — ≥ 1 mm (“any rain”), ≥ 5 mm and ≥ 10 mm — regardless of your threshold, because “will it rain on my parade” is really a question about any rain at all.

Each condition also reports where your threshold sits inside the local distribution. “35 °C is the 68th percentile here” tells you far more than a bare probability: it says whether you picked a genuinely extreme bar for this place, or an ordinary Tuesday.

Step 3

The heat index

“Very uncomfortable” uses the NOAA/Rothfusz regression, the same polynomial the US National Weather Service publishes. Daily maximum temperature is converted to °F and combined with relative humidity:

HI = -42.379 + 2.04901523·T + 10.14333127·RH
     - 0.22475541·T·RH - 0.00683783·T²
     - 0.05481717·RH² + 0.00122874·T²·RH
     + 0.00085282·T·RH² - 0.00000199·T²·RH²

T  = temperature (°F)
RH = relative humidity (%)

The regression is only valid at or above 80 °F (26.7 °C); below that the NWS reports the dry-bulb temperature unchanged, and so do we. The result is converted back to °C.

Caveat worth knowing: POWER publishes a daily maximum temperature and a daily mean humidity. Pairing them is the standard approach for daily climatology, but humidity typically dips when temperature peaks — so this heat index runs slightly warm compared with an hourly calculation. Treat it as a consistent comparative index rather than a precise instantaneous reading.

Step 4

Climate trend regression

Extreme-weather probabilities are not static, so a single 30-year average can hide a moving target. For each condition orbitWx computes that year's exceedance fraction inside the window, then fits a degree-1 least-squares line against year:

fraction(year) ≈ slope · year + intercept
slope_per_decade = slope × 10

Alongside the slope we report a plain-language comparison of the first decade (1996–2005) against the last (2016–2025) — for example, “Heavy-rain odds on this date rose from 18% (1996–2005) to 27% (2016–2025)”. Differences under 2 percentage points are reported as steady rather than dressed up as a trend.

A linear fit over 30 noisy annual points is a descriptive summary, not a significance test. Read it as direction and magnitude, not proof.

Honest limits

What this cannot do

  • It is not a forecast. orbitWx cannot tell you whether it will rain on 15 October next year — only how often it has rained on that date historically.
  • Grid, not point. A 0.5° × 0.625° cell is roughly 55 km × 60 km at the equator. Microclimates, valleys and coastlines inside a cell are averaged away.
  • Reanalysis, not a rain gauge. MERRA-2 assimilates observations into a model. It is excellent for climatology and less exact than a co-located station for a single day.
  • Stationarity is assumed. The headline probability treats all 30 years as one pool. The trend panel exists precisely because that assumption is imperfect.

Check the numbers yourself

Every result ships with a CSV/JSON export of the exact rows that fed the calculation, plus the POWER request URL that produced them. Nothing in orbitWx is a black box.

Run an analysis →