io_grib.py — Writing FLEXPART-Ready GRIB2 Files =============================================== Overview -------- FLEXPART expects meteorological input files in **GRIB2 format**, one file per forecast step (e.g. ``dispf2025072912.grib``). This module takes meteorological fields stored as ``xarray.DataArray`` objects and writes them to GRIB2 files that FLEXPART can directly use. GRIB1 inputs are automatically **converted to GRIB2** by overriding metadata from a GRIB2 Template 4.0 (instantaneous forecast). Purpose ------- This module standardizes all fields by: #. **Standardization of all fields to GRIB2** #. **Normalization of metadata** for surface and model-level parameters #. **Definition of temporal properties**, such as instantaneous versus 1-hour accumulated fields #. **Consistent writing of one GRIB file per forecast step** Key GRIB Metadata ----------------- .. list-table:: :header-rows: 1 * - Key - Meaning - Example * - **typeOfFirstFixedSurface** - Lower boundary of the field - ``1`` = surface, ``103`` = height above ground, ``105`` = hybrid model level * - **scaledValueOfFirstFixedSurface** - Numeric value of the level - ``2`` → 2 m above ground * - **typeOfSecondFixedSurface** - Upper boundary of the layer - ``8`` = top of atmosphere, ``255`` = missing * - **productDefinitionTemplateNumber** - Time interpretation - ``0`` = instantaneous, ``8`` = accumulation * - **indicatorOfUnitOfTimeRange** - Unit of forecast step - ``1`` = hours Field-Specific Conversions -------------------------- Each variable type is mapped to GRIB2 metadata describing its **vertical level** and **temporal behavior**. The table below summarizes all transformations applied in ``io_grib.py``. .. note:: - “Instantaneous” means a snapshot at the forecast time. - “Accumulation” means the value represents the total or flux **over the previous hour**. .. list-table:: :header-rows: 1 * - Variable(s) - Meaning - Temporal Type - Vertical Definition - Template (``PDTN``) - Notes * - **u, v, t, q** - Model-level wind, temperature, humidity - Instantaneous - As in source - 0 - Already GRIB2. * - **10u, 10v** - 10 m wind - Instantaneous - HeightAboveGround / 10 m - 0 - Added explicit 10 m level. * - **2t, 2d** - 2 m temperature & dewpoint - Instantaneous - HeightAboveGround / 2 m - 0 - Added explicit 2 m level. * - **sp, lsm** - Surface pressure, land–sea mask - Instantaneous - Surface / 1 - 0 - Converted from GRIB1; scale keys unset for GRIB2 compliance. * - **tcc** - Total cloud cover - Instantaneous - Surface → TopOfAtmosphere - 0 - Defines vertical column layer. * - **sd, sdor, z** - Snow depth, orography, geopotential - Instantaneous - Hybrid level 1 - 0 - Model-level fields. * - **cp, lsp, sshf, ssr, ewss, nsss** - Precipitation & fluxes - 1-hour accumulation - Surface / 1 - 8 - Written as 1-hour sums (PDT 8). * - **omega (w)** - Vertical velocity - Instantaneous - Hybrid model level K - 0 - Written with canonical ``w`` shortName. Output ------ For each forecast step, one GRIB2 file is produced:: dispfYYYYMMDDHH.grib