GRIB: converting to NetCDF

[1]:
import earthkit.data as ekd
from earthkit.data.utils.summary import ncdump

ekd.download_example_file("tuv_pl.grib")
# we only select the temperature fields
ds = ekd.from_source("file", "tuv_pl.grib").to_fieldlist().sel({"parameter.variable": "t"})

Using the earthkit accessor

To convert GRIB data to NetCDF first we need to convert GRIB to Xarray with to_xarray() then generate NetCDF from it with xarray.Dataset.to_netcdf(). Earthkit-data attaches some special attributes to the generated Xarray dataset that cannot be written to NetCDF. In order to make to_netcdf work we need to call it on the “earthkit” accessor and not directly on the Xarray dataset.

[2]:
ds.to_xarray().earthkit.to_netcdf("_tuv_pl.nc")
[3]:
ncdump("_tuv_pl.nc")
netcdf _tuv_pl {
dimensions:
        level = 6 ;
        latitude = 7 ;
        longitude = 12 ;
variables:
        double t(level, latitude, longitude) ;
                t:_FillValue = NaN ;
                t:standard_name = "air_temperature" ;
                t:long_name = "Temperature" ;
                t:units = "kelvin" ;
                t:level_type = "pressure" ;
        int64 level(level) ;
                level:standard_name = "air_pressure" ;
                level:long_name = "pressure" ;
                level:units = "hectopascal" ;
                level:positive = "down" ;
        double latitude(latitude) ;
                latitude:_FillValue = NaN ;
                latitude:units = "degrees_north" ;
                latitude:standard_name = "latitude" ;
                latitude:long_name = "latitude" ;
        double longitude(longitude) ;
                longitude:_FillValue = NaN ;
                longitude:units = "degrees_east" ;
                longitude:standard_name = "longitude" ;
                longitude:long_name = "longitude" ;

// global attributes:
                :Conventions = "CF-1.8" ;
                :institution = "ECMWF" ;
}

Using add_earthkit_attrs=False

Alternatively, we can use the add_earthkit_attrs=False option in to_xarray(). With this the earthkit attributes are not added to the generated dataset and it is safe to call xarray.Dataset.to_netcdf() directly on it.

[4]:
ds.to_xarray(add_earthkit_attrs=False).to_netcdf("_tuv_pl_1.nc")
ncdump("_tuv_pl_1.nc")
netcdf _tuv_pl_1 {
dimensions:
        level = 6 ;
        latitude = 7 ;
        longitude = 12 ;
variables:
        double t(level, latitude, longitude) ;
                t:_FillValue = NaN ;
                t:standard_name = "air_temperature" ;
                t:long_name = "Temperature" ;
                t:units = "kelvin" ;
                t:level_type = "pressure" ;
        int64 level(level) ;
                level:standard_name = "air_pressure" ;
                level:long_name = "pressure" ;
                level:units = "hectopascal" ;
                level:positive = "down" ;
        double latitude(latitude) ;
                latitude:_FillValue = NaN ;
                latitude:units = "degrees_north" ;
                latitude:standard_name = "latitude" ;
                latitude:long_name = "latitude" ;
        double longitude(longitude) ;
                longitude:_FillValue = NaN ;
                longitude:units = "degrees_east" ;
                longitude:standard_name = "longitude" ;
                longitude:long_name = "longitude" ;

// global attributes:
                :Conventions = "CF-1.8" ;
                :institution = "ECMWF" ;
}

Using to_target

We can call to_target() on the fieldlist and the Xarray conversion and writing to NetCDF will happen automatically under the hood using the default options. In this case add_earthkit_attrs=False is always enforced.

[5]:
ds.to_target("file", "_tuv_pl_2.nc")
ncdump("_tuv_pl_2.nc")
netcdf _tuv_pl_2 {
dimensions:
        level = 6 ;
        latitude = 7 ;
        longitude = 12 ;
variables:
        double t(level, latitude, longitude) ;
                t:_FillValue = NaN ;
                t:standard_name = "air_temperature" ;
                t:long_name = "Temperature" ;
                t:units = "kelvin" ;
                t:level_type = "pressure" ;
        int64 level(level) ;
                level:standard_name = "air_pressure" ;
                level:long_name = "pressure" ;
                level:units = "hectopascal" ;
                level:positive = "down" ;
        double latitude(latitude) ;
                latitude:_FillValue = NaN ;
                latitude:units = "degrees_north" ;
                latitude:standard_name = "latitude" ;
                latitude:long_name = "latitude" ;
        double longitude(longitude) ;
                longitude:_FillValue = NaN ;
                longitude:units = "degrees_east" ;
                longitude:standard_name = "longitude" ;
                longitude:long_name = "longitude" ;

// global attributes:
                :Conventions = "CF-1.8" ;
                :institution = "ECMWF" ;
}

To control the Xarray conversion we can pass options to the earthkit Xarray engine via earthkit_to_xarray_kwargs.

[6]:
ds.to_target("file", "_tuv_pl_3.nc", earthkit_to_xarray_kwargs={"flatten_values": True})
ncdump("_tuv_pl_3.nc")
netcdf _tuv_pl_3 {
dimensions:
        level = 6 ;
        values = 84 ;
variables:
        double t(level, values) ;
                t:_FillValue = NaN ;
                t:standard_name = "air_temperature" ;
                t:long_name = "Temperature" ;
                t:units = "kelvin" ;
                t:level_type = "pressure" ;
                t:coordinates = "latitude longitude" ;
        int64 level(level) ;
                level:standard_name = "air_pressure" ;
                level:long_name = "pressure" ;
                level:units = "hectopascal" ;
                level:positive = "down" ;
        double latitude(values) ;
                latitude:_FillValue = NaN ;
                latitude:units = "degrees_north" ;
                latitude:standard_name = "latitude" ;
                latitude:long_name = "latitude" ;
        double longitude(values) ;
                longitude:_FillValue = NaN ;
                longitude:units = "degrees_east" ;
                longitude:standard_name = "longitude" ;
                longitude:long_name = "longitude" ;

// global attributes:
                :Conventions = "CF-1.8" ;
                :institution = "ECMWF" ;
}

[ ]: