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 to_netcdf() directly¶
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(). The earthkit attributes (_earthkit) attached to each DataArray are encoded as JSON strings, so they are fully compatible with NetCDF. We can simply call to_netcdf() directly on the dataset.
[2]:
ds.to_xarray().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" ;
t:_earthkit = "{\"message\": {\"__bytes_b64__\": \"R1JJQgAAbAEAADSAYpX/gIJkASwSCAEMAAEAAAAAAAAVAAAAAAAAAAAAAAAAAAAAAQECBAEwMDAxAAAAAAAgAP8AAAwABwFfkAAAAICBX5AFCRB1MHUwAAAAAAAAAAwAgAJEuX1uAAA3Nzc3\"}, \"bitsPerValue\": 4}" ;
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¶
If you prefer not to include the earthkit attributes in the NetCDF file at all, you can use the add_earthkit_attrs=False option in to_xarray(). Note that without these attributes, converting the Xarray dataset back to GRIB will not be possible.
[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.
[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" ;
t:_earthkit = "{\"message\": {\"__bytes_b64__\": \"R1JJQgAAbAEAADSAYpX/gIJkASwSCAEMAAEAAAAAAAAVAAAAAAAAAAAAAAAAAAAAAQECBAEwMDAxAAAAAAAgAP8AAAwABwFfkAAAAICBX5AFCRB1MHUwAAAAAAAAAAwAgAJEuX1uAAA3Nzc3\"}, \"bitsPerValue\": 4}" ;
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:_earthkit = "{\"message\": {\"__bytes_b64__\": \"R1JJQgAAbAEAADSAYpX/gIJkASwSCAEMAAEAAAAAAAAVAAAAAAAAAAAAAAAAAAAAAQECBAEwMDAxAAAAAAAgAP8AAAwABwFfkAAAAICBX5AFCRB1MHUwAAAAAAAAAAwAgAJEuX1uAAA3Nzc3\"}, \"bitsPerValue\": 4}" ;
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" ;
}
[ ]: