Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Updated for 2025

...

The file tz_an_pl.grib1 contains parameters T and Z on six pressure levels.

How could you use grib_copy to create two files, one containing all of the pressure levels for parameter T, the other for parameter

...

Q ?  Check the content of the new files with grib_ls.

Expand
titleClick here to see solution...

To copy only those messages for parameter T from the GRIB file tztq_an_pl.grib1 grib2 use grib_copy with the -w option to specify a shortName=t:

No Format
$>  grib_copy -w shortName=t tztq_an_pl.grib1grib2 t_an_pl.grib1grib2

Similarly to copy only those messages for parameter ZQ, use:

No Format
$> grib_copy -w shortName=zq tztq_an_pl.grib1grib2 zq_an_pl.grib1grib2

Or, more simply,  and and because the file contains only parameters T and ZQ, one can use:

No Format
$> grib_copy tztq_an_pl.grib1grib2 "[shortName]_an_pl.grib1grib2"

Using grib_ls of the two files confirms that the contents are correct. For example:

No Format
$> grib_ls -p centre,paramId,typeOfLevel,level,date,dataType,time,shortName t_an_pl.grib1grib2
t_an_pl.grib1grib2
centre       paramId      typeOfLevel  level        date         dataType     time         shortName    
ecmf         130          isobaricInhPa  850    1000      20251013   20170219  fc   an        0   1200         t           
ecmf         130          isobaricInhPa  300  850        20251013  20170219   fc  an         0  1200          t           
ecmf         130          isobaricInhPa  7001000         20251013   20170219  fc   an        0   1200         t           
ecmf         130          isobaricInhPa  700  500        20251013  20170219   fc  an         0   1200         t           
ecmf         130          isobaricInhPa  500  400        20251013   20170219  fc   an        0   1200         t           
ecmf         130          isobaricInhPa  400   300       20251013   20170219  fc   an        0   1200         t           
6 of 6 messages in t_an_pl.grib1grib2
  
6 of 6 total messages in 1 files  


You can take this further and split the file tztq_an_pl.grib1 into separate files for each parameter/pressure level combination with:

No Format
$> grib_copy tztq_an_pl.grib1grib2 "[shortName]_[level].grib[edition]"

$> ls ?_*0.grib1grib?
tq_1000.grib1grib2  tq_400.grib1grib2  tq_700.grib1.grib2	q_an_pl.grib2  zt_1000300.grib1grib2  zt_400500.grib1grib2  zt_700850.grib1grib2
tq_300.grib1grib2   tq_500.grib1grib2  tq_850.grib1  z_300.grib1grib2	t_1000.grib2   zt_500400.grib1grib2  zt_850700.grib1grib2

Each file contains one message only, e.g.:

No Format
$> grib_ls -p centre,paramId,typeOfLevel,level,date,dataType,time,shortName t_1000.grib1grib2
t_1000.grib1grib2
centre       paramId      typeOfLevel  level        date         dataType     time         shortName    
ecmf         130          isobaricInhPa  1000         20251013  20170219   fc  an         0  1200          t           
1 of 1 messages in t_1000.grib1grib2

1 of 1 total messages in 1 files 


...

Info
iconfalse

Using grib_set to change key values

The field in the file tp.grib is supposed to contain total precipitation, created using MARS compute to sum the convective and large-scale (stratiform) precipitation.

What is the parameter set to in the file tp.

...

grib2 ?   How could you use grib_set to change it is set correctly to total precipitation (shortName=tp, paramId=228) ?

Expand
titleClick here to see solution...

Use grib_ls to inspect the contents of the file tp.grib1grib2, printing also the paramId with the –P option:

No Format
$> grib_ls -P paramId tp.grib1grib2
tp.grib1grib2
paramId      edition      centre       date    typeOfLevel  level   dataType     dataDategridType     stepRangetypeOfLevel  level  dataType     shortName stepRange   packingType shortName gridType   packingType  
142          12            ecmf         surface20241216     fc 0          regular_ll  20170221 surface    24  0         fc   0-24         lsp          grid_simple  regular_ll  
1 of 1 messages in tp.grib1grib2

1 of 1 total messages in 1 files 

Alternatively, you could inspect the parameter namespace with grib_ls:

No Format
$> grib_ls -n parameter tp.grib1grib2
tp.grib1grib2
centre      paramId     unitsshortName   units    name   name     shortName   
ecmf        142         mlsp         m  Large-scale precipitation  lsp      Large-scale precipitation 
1 of 1 messages in tp.grib1grib2

1 of 1 total messages in 1 files

The shortName is set to lsp and paramId to 142, i.e., large-scale precipitation.

Info

The field was created using MARS compute to sum the convective and large-scale (stratiform) precipitation. When using MARS compute, the output field maintains the information from the GRIB header of the first input field so, in this case, we see that the field has paramId 142 even though the message is now supposed to contain the total precipitation.

To change the parameter to total precipitation, use grib_set as follows:

No Format
$> grib_set -s shortName=tp tp.grib1grib2 tp_new.grib1grib2

Check with grib_ls:

No Format
$> grib_ls -n parameter tp_new.grib2 
tp_new.grib2
centre      paramId
No Format
$> grib_ls -P paramId tp_new.grib1               
tp_new.grib1
paramId      edition      centre       typeOfLevel  level        dataDate     stepRange    dataType     shortName    packingType  gridType     
228          1            ecmf       shortName  surface units     0  name        
ecmf  20170221     24 228         tp fc         m  tp         Total  grid_simple  regular_ll  precipitation 
1 of 1 messages in tp_new.grib1grib2
   
1 of 1 total messages in 1 files


Tip

Note that changing the shortName has also changed the value of paramId. The same could be achieved by setting paramId=228:

No Format
$> grib_set -s paramId=228 tp.gribgrib2 tp_new.gribgrib2



...

Info
iconfalse

Converting GRIB data to netCDF with grib_to_netcdf

...

Expand
titleClick here to see solution...


To convert the GRIB messages in file.grib1grib2 to netCDF with data type NC_SHORT and store in a file named out1.nc use:

No Format
$> grib_to_netcdf -o out1.nc file1.grib1grib2
grib_to_netcdf: Version 2.3044.20
grib_to_netcdf: Processing input file 'file1.grib1grib2'.
grib_to_netcdf: Found 45 GRIB fields in 1 file.
grib_to_netcdf: Ignoring key(s): method, type, stream, refdate, hdate
grib_to_netcdf: Creating netCDF file 'out1.nc'
grib_to_netcdf: NetCDF library version: 4.9.13 of FebMar 14 92025 2023 1307:5427:0922 $
grib_to_netcdf: Creating large (64 bit) file format.
grib_to_netcdf: Defining variable 't2m'.
grib_to_netcdf: Done.


...

Expand
titleClick here to see solution...

Using ncdump to print the values for the variable t2m shows:

No Format
$> module load netcdf4

$> ncdump -v t2m out1.nc 
netcdf out1 {
...
data:

 t2m =
  20497-29628, -80928125,
  21957, 21552,
  -1631215905, -32766,
  23701, 21176,
  3276728426, 704232767,
  -131225246, -1804123499,
  1716810705, -122074529,
  -414827955, -2839229374,
  19382-32625, -1082732683,
  -250630518, -2540629616 ;
}


Tip

The data values appear as integers because of the NC_SHORT data format. These values need to be unpacked using the scale_factor and add_offset NetCDF netCDF attributes.


How could you change the the grib_to_netcdf command to create a netCDF output with the values stored as floating point numbers ?

Expand
titleClick here to see solution...

To store the values in the netCDF file as floating point numbers, use the grib_to_netcdf tool with the data format to NC_FLOAT or NC_DOUBLE with the -D option.  For example:

No Format
$> grib_to_netcdf -D NC_FLOAT -o out2.nc file1.grib1grib2
grib_to_netcdf: Version 2.3044.20
grib_to_netcdf: Processing input file 'file1.grib1grib2'.
grib_to_netcdf: Found 45 GRIB fields in 1 file.
grib_to_netcdf: Ignoring key(s): method, type, stream, refdate, hdate
grib_to_netcdf: Creating netCDF file 'out2.nc'
grib_to_netcdf: NetCDF library version: 4.9.13 of FebMar 14 92025 2023 1307:5427:0922 $
grib_to_netcdf: Creating large (64 bit) file format.
grib_to_netcdf: Defining variable 't2m'.
grib_to_netcdf: Done.

Checking with ncdump, we see the values are now stored as floating point values:

No Format
ncdump -v t2m out2.nc                            
netcdf out2 {
...
data:

 t2m = t2m =
  282.9801, 283.1394,
  288.4472, 288.4043,
  281284.16664345, 277282.99436475,
  275288.6859632, 273288.2363644,
  282289.99371328, 279289.16325929,
  277288.91947958, 275288.42856107,
  280287.6712547, 276286.29716001,
  277289.49710829, 273289.88722333,
  281282.00076624, 276282.50266563,
  277289.74163545, 274289.33182589 ;
}

In this case, the data values do not need further processing.

Try using grib_to_netcdf to convert the GRIB messages in file2.grib to netCDF.   What happens....and why ?  

...

How would you fix it ?

Expand
titleClick here to see solution...

Converting file2.grib grib2 to netCDF gives the following error:

No Format
$> grib_to_netcdf -o out2.nc file2.grib1grib2                   
grib_to_netcdf: Version 2.3044.20
grib_to_netcdf: Processing input file 'file2.grib1grib2'.
grib_to_netcdf: Found 15 GRIB fieldfields in 1 file.
grib_to_netcdf: Ignoring key(s): method, type, stream, refdate, hdate
grib_to_netcdf: Creating netCDF file 'out2out3.nc'
grib_to_netcdf: NetCDF library version: 4.9.13 of FebMar 14 92025 2023 1307:5427:0922 $
grib_to_netcdf: Creating large (64 bit) file format.
ECCODES ERROR   :  Grid type = reduced_gg
ECCODES ERROR   :  First GRIB is not on a regular lat/lon grid or on a regular Gaussian grid. Exiting.

The conversion fails because the GRIB data is represented on a reduced Gaussian grid (gridType=reduced_gg). Conversion to NetCDF netCDF is possible only for GRIB data with gridType=regular_ll or gridType=regular_gg

To fix this it would be necessary to re-retrieve the data on a regular grid or interpolate to a regular grid.

...