Documentation

The ecCodes Python API is documented at:

There are examples of how to use it at:

Other useful resources:

Preliminaries

Login to ecs-login and work in your $SCRATCH

$> cd $SCRATCH

Make a copy of the practicals directory in your $SCRATCH to Atos:

$> tar –xvf /home/trx/grib_practicals.tar

This will create a directory in your $SCRATCH called grib_practicals containing the GRIB data files for this tutorial.

There are sub-directories for each practical:

$> ls $SCRATCH/grib_practicals

inspect  modify  python

For this tutorial cd to the python directory:

$> cd $SCRATCH/grib_practicals/python


Remember to load the ecmwf-toolbox and python3 !

$> module load ecmwf-toolbox
$> module load python3

This tutorial covers the following topics:


Using the Python API to decode messages in a GRIB file

The directory contains an example Python script called eccodes_demo.py which decodes data via a call to a function called grib_dump and some GRIB messages to be decoded in a file called grib_file.grib

Run the Python script unchanged and redirect the output to a file using:

$> ./eccodes_demo.py > output

Look at the text information written to the file called output.  Compare with the output obtained with the grib_ls and grib_dump commands:

$> grib_ls grib_file.grib
...

$> grib_dump grib_file.grib

Your challenge is to change the Python script eccodes_demo.py to replace the call to the function codes_dump with several calls to codes_get or codes_get_array to decode the values for the edition, date, time, paramId (or shortName) and level keys.  Add your own print statements to output this information.

The part of the script to change is in the example function, specifically line 47 should be commented (add a '#' to the start of the line containing "codes_dump(gid)") and replaced with calls to codes_get for each key value needed:

def example():
    f = open(INPUT,'rb')

    count = 1
    while 1:
        gid = codes_grib_new_from_file(f)
        if gid is None: break
        print("\n\n-- GRIB %d --" % count)

        #   codes_dump should only be used for diagnostic purposes.
        #
        #   To process the data and grib headers, you will have to use
        #   codes_get and request the decoding of the keys you need,
        #   e.g. the date, the time, the parameter, the "level".

        codes_dump(gid)

        # Replace this call to codes_dump with calls to codes_get
        # for each key/value pair needed, e.g.:
        #
        #   date = codes _get(gid,'date')

        codes_release(gid)
        count += 1

    f.close()


A possible solution is:

def example():
    f = open(INPUT,'rb')

    count = 1 
    while 1:
        gid = codes_grib_new_from_file(f)
        if gid is None: break
        print ("\n\n-- GRIB %d --" % (count))
        # codes_dump should only be used for diagnostic purposes.
        #   
        #   To process the data and grib headers, you will have to use 
        #   codes_get and request the decoding of the keys you need,
        #   e.g. the date, the time, the parameter, the "level".
        #   

        # codes_dump(gid)

        #   
        # Replace this call to codes_dump with calls to codes_get
        # for each key/value pair needed, e.g.:
        #    
        #   idate = codes_get(gid,'date')

        edition = codes_get(gid,'edition')
        shortName = codes_get(gid,'shortName')
        date = codes_get(gid,'date')
        time = codes_get(gid,'time')
        levType = codes_get(gid,'typeOfLevel')
        level = codes_get(gid,'level')

        print("Edition=%d Parameter=%s typeOfLevel=%s level=%d date=%d time=%d\n" % 
              (edition, shortName, levType, level, date, time))
        #print (edition, shortName, levType, level, date, time)

        values = codes_get_array(gid,'values')

        print("First 20 values:\n----------------\n")
        for i in range(20):
            print("%.4f" % (values[i]))

        maximum = codes_get(gid,'max')
        minimum = codes_get(gid,'min')
        average = codes_get(gid,'average')

        print("max = %.4f  min = %.4f  average = %.4f\n" % (maximum, minimum, average))

        codes_release(gid)
        count += 1

    f.close()

This example solution goes a little further than needed and also decodes and prints the first 20 data values for each message as well as the maximum, minimum and average of all the data values.