Skip to content

Add 80m wind, temperature, and pressure to NOAA GEFS#749

Draft
mrshll wants to merge 2 commits into
mainfrom
claude/gefs-add-80m-variables
Draft

Add 80m wind, temperature, and pressure to NOAA GEFS#749
mrshll wants to merge 2 commits into
mainfrom
claude/gefs-add-80m-variables

Conversation

@mrshll

@mrshll mrshll commented Jul 15, 2026

Copy link
Copy Markdown
Member

What

Adds four near-surface data variables at the 80 metre level to the shared NOAA GEFS data-variable config (src/reformatters/noaa/gefs/common_gefs_template_config.py):

  • wind_u_80m, wind_v_80m (80 m U/V wind component)
  • temperature_80m (80 m temperature)
  • pressure_80m (80 m pressure)

All four come from the GEFS 0.5° "b" file (pgrb2b.0p50, gefs_file_type="b") — the same file type as the existing wind_u_100m/wind_v_100m.

Affected datasets (template metadata regenerated):

  • noaa-gefs-forecast-35-day — gains the 80m level
  • noaa-gefs-analysis — gains the 80m level
  • noaa-gefs-forecast-10-day-spatial-devunaffected; it filters to _S_FILE_TYPES (0.25° s-files) and so excludes gefs_file_type="b" variables by design (just like the existing 100m wind). Its template is unchanged.

Why

Customer wind-energy use case: 80 m is a common wind-turbine hub height, so U/V wind plus temperature and pressure at that level support hub-height wind and air-density calculations.

Source verification

Source availability was verified against a live GEFS GRIB index: UGRD, VGRD, TMP, and PRES at 80 m above ground are all present in the 0.5° b file. NOAA byte-range matching keys off grib_element + grib_index_level (+ lead-time string), which the new configs set to match the live index. The 80m read/regrid path is the same b-file path already exercised in production by the existing 100m wind.

Metadata mirrors existing equivalents: wind mirrors wind_u_100m/wind_v_100m, temperature mirrors temperature_2m (K→°C conversion happens automatically on read), pressure mirrors pressure_surface but uses the generic-height CF standard_name="air_pressure" (not surface_air_pressure). keep_mantissa_bits: wind 6, temperature 7, pressure 10 (matching the dataset's pressure_surface).

CF-compliance exemptions

tests/common/datasets_cf_compliance_test.py validates long_name/short_name against the ECMWF parameter database. ECMWF has 80m U/V wind (80u/80v, already exempt for HRRR) but no 80m temperature or 80m pressure parameter, so 80t/80sp and their long names were added to the existing ECMWF_SHORTNAME_EXEMPT / ECMWF_LONGNAME_EXEMPT sets — the test's designed mechanism for quantities without an ECMWF entry. Without this the compliance test fails.

Verification

Verified on the canonical Python 3.14.6 toolchain: update-template for all three GEFS datasets produces zero diff vs. the checked-in metadata (spatial-dev unchanged, confirming the b-file filter); ruff / ty check / pytest (259 passed) all pass; and a decode of real GEFS GRIB produced physically sensible values. See the verification comment below.

Scope

Template metadata only. Post-merge work — history backfill, validation (incl. a K→°C sanity check on the b-file temperature), and catalog docs — is tracked in #752.

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 GEFS data-variable config (from the 0.5 degree b file, like the
existing 100m wind), so noaa-gefs-forecast-35-day and noaa-gefs-analysis
gain the 80m level. The 0.25 degree 10-day-spatial dataset excludes
b-file variables by design and is unaffected. Template metadata only;
backfill is a separate follow-up.

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-gefs-forecast-35-day, noaa-gefs-analysis, and noaa-gefs-forecast-10-day-spatial-devzero diff vs. checked-in metadata. The spatial-dev dataset shows no change, confirming the new b-file (gefs_file_type="b") vars are correctly filtered out by _S_FILE_TYPES.

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

  • common_template_config_subclasses_test + datasets_cf_compliance_test: 259 passed.

  • Decode (GEFS forecast-35-day, member 0, first lead times) — all physically sensible, no NaN:

    variable units min max
    temperature_80m degree_Celsius -54.25 40.5
    pressure_80m Pa 49792 103104
    wind_u_80m m s-1 -31.0 35.0
    wind_v_80m m s-1 -33.0 35.5

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

⚠️ Merge-order dedupe with #748 — exemption kept here

This PR and #748 both add 80t / 80sp (+ long names) to the cf-compliance exempt sets. I tested removing them from this branch: datasets_cf_compliance_test then fails for noaa-gefs-analysis and noaa-gefs-forecast-35-day (the 80m temperature/pressure vars have no ECMWF param-DB entry). So the exemption must stay on this branch and cannot be pre-emptively dropped here.

Consequence: whichever of #748 / #749 merges second must drop the duplicate 80t / 80sp / 80 metre temperature / 80 metre pressure lines the first merge already added, to avoid a duplicate-key conflict.

Automated verification; PR left as draft for human review.

The 80 m above ground level is not present in the GEFS v12 reforecast
archive (2000-2019), so the reforecast integration test must exclude
the new 80m variables.

Claude-Session: https://claude.ai/code/session_01HX6W8Ru3TvKaUBgQFCUgAZ
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.

2 participants