ERA5 → EOPF HEALPix Converter#
Converts ERA5 reanalysis surface fields (Gaussian N256/N320) to EOPF-compliant HEALPix zarr (level 7, ~50 km).
Pipeline: download GRIB via CDS (2 MARS requests) → PSFResampler → write zarr → inject STAC → push S3
import logging
from pathlib import Path
from healpix_convert.converters.era5 import ERA5Converter
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
Configuration#
DATE = "2025-01-01"
TIME = "00:00:00"
LOCAL_DIR = Path(".")
OUTPUT = LOCAL_DIR / f"S00__ADF_ECMWA_{DATE.replace('-', '')}.zarr"
PUSH_S3 = False # set True to push to S3
converter = ERA5Converter(
date=DATE,
time=TIME,
local_dir=LOCAL_DIR,
)
Step 1 — Prepare (download + PSFResampler)#
result = converter.prepare(output_path=str(OUTPUT))
print(f"Chunks: {result.n_chunks} | Timesteps: {result.n_times}")
Step 2 — Convert (all spatial chunks)#
for i in range(result.n_chunks):
converter.convert_group(i)
if (i + 1) % 20 == 0:
print(f" {i+1}/{result.n_chunks}")
Step 3 — Consolidate (STAC metadata)#
converter.consolidate()
print(f"Done: {OUTPUT}")
Validation#
import healpy as hp
import matplotlib.pyplot as plt
import xarray as xr
ds = xr.open_zarr(str(OUTPUT), consolidated=True)
print(ds)
var = "t2m"
data = ds[var].isel(time=0).values
hp.mollview(
hp.reorder(data - 273.15, n2r=True),
flip="geo",
nest=False,
cmap="RdBu_r",
min=-50,
max=50,
unit="°C",
title=f"ERA5 {var} — HEALPix level 7",
)
plt.show()