feat: ERA5 + GLDAS NetCDF forcing support#79
Conversation
…d parity
Extend NetcdfForcingProvider to support three forcing products (CMFD2, ERA5, GLDAS),
all verified to produce identical forcing values and legacy output compared to CSV baselines.
ERA5 changes:
- Fix end-boundary file enumeration: add lookahead day for accumulated field
forward-differencing (tp, ssr) so the last simulation timestep has a valid increment
- Implement forward-difference conversion for accumulated fields (tp → mm/day,
ssr → W/m²) with reset handling and small-negative tolerance
- Apply CSV quantization rules (precip 4dp, temp 2dp, RH 4dp, wind 2dp + 0.05
floor, radiation integer) to ERA5 branch for baseline parity
- Set RADIATION_KIND=SWNET for ERA5 (ssr is net shortwave, not downward)
GLDAS (new, PRODUCT=GLDAS):
- Per-timestep file layout: {year}/{doy}/GLDAS_NOAH025_3H.A{yyyymmdd}.{hhmm}.021.nc4
- Efficient timestep enumeration via direct path construction (no directory scan)
- NcVarPointMeta: lightweight shared-handle reader to avoid re-opening the same
.nc4 file for each of 6 variables per timestep
- _FillValue water-mask handling: stations mapping to missing cells are automatically
remapped to nearest valid grid cell (logged)
- Variable mapping: Rainf_f_tavg(kg/m²/s)→mm/day, Tair_f_inst(K)→°C,
Qair_f_inst+Psurf_f_inst→RH (same formula as CMFD2), Wind_f_inst→m/s,
SWdown_f_tavg→W/m²
- CSV quantization and threshold rules applied consistently
Verification (QHH 10-day, all three products):
- Forcing: max_abs_diff = 0 (CSV baseline vs NetCDF, all 5 variables)
- Legacy output: .dat files SHA256-identical between CSV and NetCDF runs
- Baseline (CMFD2 CSV) unbroken
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code Review: PR #79 — ERA5 + GLDAS NetCDF Forcing SupportScore: 4/5 — Nitpicks 🤓 Verification Evidence
Issues Found🟡 MEDIUM (tracked for follow-up, not blocking given verification pass) 🟡 MEDIUM | Correctness |
🔵 LOW (non-blocking) 🔵 LOW | Quality |
🔵 LOW | Correctness |
🔵 LOW | Quality |
🔵 LOW | Documentation |
Positive Aspects
|
Summary
Extend
NetcdfForcingProviderto support three forcing products (CMFD2, ERA5, GLDAS), all regression-verified against CSV baselines.ERA5 changes
tp,ssr)tp→ mm/day,ssr→ W/m²) with reset handling and small-negative toleranceRADIATION_KIND=SWNETfor ERA5 (ssris net shortwave)GLDAS (new,
PRODUCT=GLDAS){year}/{doy}/GLDAS_NOAH025_3H.A{yyyymmdd}.{hhmm}.021.nc4NcVarPointMeta: lightweight shared-handle reader to avoid re-opening same.nc4for each variable_FillValuewater-mask handling: stations on missing cells auto-remap to nearest valid grid cellRainf_f_tavg→mm/day,Tair_f_inst→°C,Qair_f_inst+Psurf_f_inst→RH,Wind_f_inst→m/s,SWdown_f_tavg→W/m²NLDAS assessment
.grb) incompatible with current NetCDF architectureVerification (QHH 10-day)
Files changed
src/classes/NetcdfForcingProvider.cpp: +837/-113 lines (ERA5 fixes + GLDAS implementation)Test plan
make shud NETCDF=1compiles successfullyThe successful end.)The successful end.)🤖 Generated with Claude Code