Skip to content

Add 80m wind, temperature, and pressure to NOAA GFS#748

Merged
mrshll merged 2 commits into
mainfrom
claude/gfs-add-80m-variables
Jul 20, 2026
Merged

Add 80m wind, temperature, and pressure to NOAA GFS#748
mrshll merged 2 commits into
mainfrom
claude/gfs-add-80m-variables

Conversation

@mrshll

@mrshll mrshll commented Jul 15, 2026

Copy link
Copy Markdown
Member

What & why

Adds four near-surface 80 metre variables to the shared NOAA GFS data-variable config (NoaaGfsCommonTemplateConfig.get_data_vars):

  • wind_u_80m, wind_v_80m (U/V wind components)
  • temperature_80m
  • pressure_80m

Because the config is shared, both noaa-gfs-forecast and noaa-gfs-analysis gain the 80m level (in-sync by design). The 80m wind/temperature fields are requested for a customer wind-energy use case (hub-height winds), with temperature and pressure alongside for density/power-curve corrections.

Details

  • Each new DataVar mirrors its nearest existing sibling, changing only the level-specific fields: temperature_80mtemperature_2m, pressure_80mpressure_surface, wind_u_80m/wind_v_80mwind_u_100m/wind_v_100m. Same encoding, dims, chunks, and shards as siblings.
  • pressure_80m uses the generic-height CF standard_name="air_pressure" (not surface_air_pressure). Temperature stays degree_Celsius (GDAL performs the K→C conversion on read), matching temperature_2m.
  • keep_mantissa_bits: wind = 6, temperature = 7, pressure = 10 — matching the equivalent existing variables.
  • Also exempts 80t/80sp and their long names from datasets_cf_compliance_test.py's ECMWF-parameter-database check. ECMWF has no 80m level, so these have no param-DB entry; this mirrors the pre-existing 80u/80v HRRR exemption. Without it the repo's own CF compliance test fails.

Source availability verified

Confirmed against a live GFS GRIB index (gfs.t00z.pgrb2.0p25) and the first archived init time (gfs.20210501/00 f002): UGRD/VGRD/TMP/PRES at 80 m above ground are all present. NOAA byte-range matching keys off grib_element + grib_index_level + lead-time (not index_position, which only orders downloads), so these will match correctly.

Verification

Verified on the canonical Python 3.14.6 toolchain: update-template for both datasets produces zero diff vs. the checked-in metadata; ruff / ty check / pytest (259 passed) all pass; and an end-to-end decode of real GFS GRIB produced physically sensible values (temperature_80m ≈ −58..41 °C, pressure_80m ≈ 48.8–104.8 kPa, winds ≈ ±35 m/s, no all-NaN). See the verification comment below.

Scope

Template metadata only. Post-merge work — history backfill, validation, and catalog docs — is tracked in #751.

Merge-order note: #748 and #749 both add the 80t/80sp CF exemption and will conflict; whichever merges second must drop the duplicate lines.

🤖 Generated with Claude Code

https://claude.ai/code/session_015ZY5VagHhMYq9D6WXVXxvq

Adds wind_u_80m, wind_v_80m, temperature_80m, and pressure_80m to the shared GFS data-variable config, so both noaa-gfs-forecast and noaa-gfs-analysis gain the 80m level. Template metadata only; backfill is a separate follow-up.

Also exempts 80t/80sp and their long names from the ECMWF parameter compliance check (ECMWF has no 80m level), matching the existing 80u/80v HRRR exemption.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ZY5VagHhMYq9D6WXVXxvq
@mrshll

mrshll commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

Verification on canonical Python 3.14 toolchain

Re-verified on real 3.14.6 (uv sync, template regen, ruff/ty/pytest, and decode of real source GRIB).

  • Template diff: regenerated noaa-gfs-forecast + noaa-gfs-analysiszero diff vs. checked-in metadata.

  • ruff format / ruff check / ty check: all clean.

  • common_template_config_subclasses_test + datasets_cf_compliance_test: 259 passed.

  • Decode (GFS forecast, init 2021-05-01T00z, first lead times) — all physically sensible, no NaN:

    variable units min max
    temperature_80m degree_Celsius -58.5 40.75
    pressure_80m Pa 48800 104768
    wind_u_80m m s-1 -34.0 35.0
    wind_v_80m m s-1 -29.25 30.0

    (pressure_80m keep_mantissa_bits=10 correctly matches the existing GFS Pa pressure vars.)

No corrections needed — the branch is correct as-is.

⚠️ Merge-order dedupe with #749

This PR and #749 both add 80t / 80sp and their long names to ECMWF_SHORTNAME_EXEMPT / ECMWF_LONGNAME_EXEMPT in tests/common/datasets_cf_compliance_test.py, so they will conflict. Per the plan, the exemption is kept here (GFS). Whoever merges second must drop the duplicate 80t / 80sp (+ 80 metre temperature / 80 metre pressure) lines that the first merge already introduced.

Automated verification; PR left as draft for human review.

Adding the four 80m variables changes the analysis operational job
split (25 vars into 3 jobs) and the expected forecast data var list.

Claude-Session: https://claude.ai/code/session_01HX6W8Ru3TvKaUBgQFCUgAZ
@mrshll
mrshll marked this pull request as ready for review July 20, 2026 20:36
@mrshll
mrshll merged commit d7a1657 into main Jul 20, 2026
5 checks passed
@mrshll
mrshll deleted the claude/gfs-add-80m-variables branch July 20, 2026 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants