Skip to content

Add WMO long-wave-downwards parameter (0,5,3) + fix zero-group constant-field decode - #4

Merged
oliverbrass merged 2 commits into
masterfrom
fix/wmo-surface-longwave-radiation-downwards
Jul 21, 2026
Merged

Add WMO long-wave-downwards parameter (0,5,3) + fix zero-group constant-field decode#4
oliverbrass merged 2 commits into
masterfrom
fix/wmo-surface-longwave-radiation-downwards

Conversation

@FranzThomsen1089

@FranzThomsen1089 FranzThomsen1089 commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Two related fixes for reading ECCC MSC HRDPS and similar GRIB2 data, shipping in 0.13.4.

1. Add WMO parameter (0, 5, 3) - surface long-wave (thermal) radiation downwards

NGrib's table carried downward long-wave radiation only as the NCEP-local variant (category 5, number 192). ECCC HRDPS and the WMO standard (code table 4.2-0-5) encode it as category 5, number 3, which was missing - so that record resolved to no Parameter and consumers dropped it. Short-wave (category 4, number 7) already works. Added the WMO entry, mirroring the short-wave one; the reflection-based lookup picks it up automatically (purely additive).

2. Fix template 5.3 (complex packing + spatial differencing) decode of zero-group constant fields

A constant field encoded with NumberOfGroups == 0 (e.g. an all-zero sea-ice-fraction field) decoded as garbage (max 99785552): the group-decoding loop never writes the secondary-value buffer, which comes from ArrayPool.Rent and holds stale data, and that garbage flowed through the spatial-differencing reconstruction into the output. Zeroing the buffer after renting makes an unwritten (zero-group) field decode to the reference value - matching eccodes, which returns all zeros for this field.

This also corrects two pre-existing broken assertions in Grib2Reader_EastChinaJapan_Test that the bug masked: the Ice test compared KeyValuePair elements against 0 (never valid) - now asserts every decoded value is 0; and the U10 test's expected average was a wrong constant (-0.0677 -> -0.6774, confirmed with eccodes; min/max already matched).

Verification

  • New Grib2Reader_HrdpsLongWave_Test: direct Parameter.Get(0,5,3) lookup + reading a real HRDPS DLWRF grib, with the decoded field checked cell-for-cell against an independent OpenJPEG decode (min 522543.5, max 1724543.5 J m-2).
  • The sea-ice constant-field decode was cross-checked with eccodes (all 45 240 values = 0, both before-expected and after-fix).
  • Full suite green: 51/51.

Bumps the package version to 0.13.4.

…5,3)

NGrib's parameter table only carried downward long-wave radiation as the NCEP-local
variant (category 5, number 192). ECCC MSC HRDPS - and the WMO standard - encode it as
category 5, number 3 ("Surface long-wave (thermal) radiation downwards"), which was
absent, so that record resolved to no parameter and consumers dropped it. Adds the WMO
entry (mirroring the existing category-4 number-7 short-wave downwards entry).

Tests: a direct Parameter.Get(0,5,3) lookup, and reading a real HRDPS DLWRF grib sample
(Jpeg2000 accumulation) asserting the parameter resolves and the decoded field matches an
independent OpenJPEG decode (min 522543.5 = referenceValue*100, max 1724543.5 J m-2).

Bumps the package version to 0.13.4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@oliverbrass oliverbrass left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

A field encoded with complex packing + spatial differencing but zero groups
(NumberOfGroups == 0, e.g. a constant all-reference-value field such as an all-zero
sea-ice-fraction field) was decoded as garbage: the group-decoding loop never writes the
secondary-value buffer, which comes from ArrayPool.Rent and holds stale data, and that
garbage then flows through the spatial-differencing reconstruction into the output.

Zero the secondary-value buffer after renting so an unwritten (zero-group) field decodes
to the reference value, matching eccodes (which returns all zeros for this field).

Also corrects two pre-existing assertions in Grib2Reader_EastChinaJapan_Test that this
exposes: the Ice test compared KeyValuePair elements against 0 (never valid) - it now
asserts every decoded value is 0; and the U10 test's expected average was wrong
(-0.0677 -> -0.6774, confirmed with eccodes; min/max already matched).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@FranzThomsen1089 FranzThomsen1089 changed the title Add WMO surface long-wave (thermal) radiation downwards parameter (0,5,3) Add WMO long-wave-downwards parameter (0,5,3) + fix zero-group constant-field decode Jul 21, 2026

@oliverbrass oliverbrass left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

@oliverbrass
oliverbrass merged commit 017f77a into master Jul 21, 2026
1 check passed
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