Dominique Lucas Xavier Abellan Ecija User Support

Similar documents
eccodes GRIB Fortran 90 - Python APIs Part 1 Dominique Lucas and Xavi Abellan ECMWF March 1, 2016

GRIB API Fortran 90 - C - Python interfaces part 2

grib_api.h File Reference

COM INTRO 2016: GRIB Decoding - Solutions to practicals. Solution to Practical 1: using grib_dump and grib_ls

COM INTRO 2017: GRIB Decoding - Solutions to practicals. Solution to Practical 1: using grib_dump and grib_ls

eccodes GRIB Fortran 90 - Python APIs Practicals 2 Dominique Lucas and Xavi Abellan

eccodes GRIB Fortran 90 - Python APIs Practicals 2 Dominique Lucas and Xavi Abellan

Compiling environment

Compiling environment

eccodes BUFR decoding

5.3 Install grib_api for OpenIFS

Technical Report on further interoperability with C

ECMWF Environment on the CRAY practical solutions

BUFR decoding. Dominique Lucas User Support. February Intro Bufr decoding

C interfaces to HSL routines. J. D. Hogg. Version 1.0 5th December Numerical Analysis Group Internal Report

GRIB API advanced tools

Interpolation. Introduction and basic concepts. Computer User Training Course Paul Dando. User Support Section.

AMath 483/583 Lecture 8

Armide Documentation. Release Kyle Mayes

A Fast Review of C Essentials Part I

eccodes BUFR encoding

Scientific Programming in C VI. Common errors

Interfacing With Other Programming Languages Using Cython

INDEX. A SIMPLE JAVA PROGRAM Class Declaration The Main Line. The Line Contains Three Keywords The Output Line

Computers Programming Course 5. Iulian Năstac

Interpolation. Computer User Training Course Paul Dando. User Support. ECMWF 25 February 2016

Surprising behaviour of Fortran (90/95)

INF 212 ANALYSIS OF PROG. LANGS PROCEDURES & FUNCTIONS. Instructors: Kaj Dreef Copyright Instructors.

3.Constructors and Destructors. Develop cpp program to implement constructor and destructor.

C Language Part 1 Digital Computer Concept and Practice Copyright 2012 by Jaejin Lee

CS 220: Introduction to Parallel Computing. Arrays. Lecture 4

redis-lua Documentation

C - Basics, Bitwise Operator. Zhaoguo Wang

Scientific Programming in C X. More features & Fortran interface

3/7/2018. Sometimes, Knowing Which Thing is Enough. ECE 220: Computer Systems & Programming. Often Want to Group Data Together Conceptually

ENERGY 211 / CME 211. Functions

Welcome. Modern Fortran (F77 to F90 and beyond) Virtual tutorial starts at BST

python-unrar Documentation

An Introduction to F2Py

gfortran - Linux Command

CSE 351, Spring 2010 Lab 7: Writing a Dynamic Storage Allocator Due: Thursday May 27, 11:59PM

Metview 4 ECMWF s latest generation meteorological workstation

COMP 250: Java Programming I. Carlos G. Oliver, Jérôme Waldispühl January 17-18, 2018 Slides adapted from M. Blanchette

Administrivia. Introduction to Computer Systems. Pointers, cont. Pointer example, again POINTERS. Project 2 posted, due October 6

CS Programming In C

Slide Set 8. for ENCM 339 Fall 2017 Section 01. Steve Norman, PhD, PEng

Introduction to Metview

Programming in C++ 5. Integral data types

Introduction to Modern Fortran

Metview 4 ECMWF s latest generation meteorological workstation

Migration GRIB1 -> GRIB2: Short summary of important modifications

Introduction to Fortran Programming. -Internal subprograms (1)-

Programming Languages

PACKAGE SPECIFICATION HSL 2013

NDK Integration (JNI)

Review: Exam 1. Your First C++ Program. Declaration Statements. Tells the compiler. Examples of declaration statements

Personal SE. Functions, Arrays, Strings & Command Line Arguments

Programming refresher and intro to C programming

Lecture Topics. Administrivia

Short Notes of CS201

Pointers (continued), arrays and strings

Metview Introduction

Vector and Free Store (Pointers and Memory Allocation)

Zoltan: Parallel Partitioning, Load Balancing and Data-Management Services User's Guide

UPIC Framework designed to help construct Plasma PIC calculations by student programmers.

CS201 - Introduction to Programming Glossary By

At this time we have all the pieces necessary to allocate memory for an array dynamically. Following our example, we allocate N integers as follows:

PDF Document structure, that need for managing of PDF file. It uses in all functions from EMF2PDF SDK.

libsegy Programmer s Reference Manual

Communications API. TEAM A : Communications and Integration Group. April 15, 1995

Lecture V: Introduction to parallel programming with Fortran coarrays

Fortran Bill Long, Cray Inc. 21-May Cray Proprietary

Numerical Modelling in Fortran: day 2. Paul Tackley, 2017

SECURE PROGRAMMING A.A. 2018/2019

Professor Terje Haukaas University of British Columbia, Vancouver C++ Programming

cast.c /* Program illustrates the use of a cast to coerce a function argument to be of the correct form. */

Distributed Systems. How do regular procedure calls work in programming languages? Problems with sockets RPC. Regular procedure calls

Creating a C++ Program

Computational Astrophysics AS 3013

Using ODB at ECMWF. Piotr Kuchta Sándor Kertész. Development Section ECMWF. Slide 1. MOS Workshop, 2013 November 18-20, ECMWF

Pointers (continued), arrays and strings

Course May 18, Advanced Computational Physics. Course Hartmut Ruhl, LMU, Munich. People involved. SP in Python: 3 basic points

HW1 due Monday by 9:30am Assignment online, submission details to come

CSI33 Data Structures

Introduction to the Message Passing Interface (MPI)

25.2 Opening and Closing a File

AN OVERVIEW OF C, PART 3. CSE 130: Introduction to Programming in C Stony Brook University

Midterm Exam Nov 8th, COMS W3157 Advanced Programming Columbia University Fall Instructor: Jae Woo Lee.

C, C++, Fortran: Basics

The Nifty Way to Call Hell from Heaven ANDREAS LÖSCHER AND KONSTANTINOS SAGONAS UPPSAL A UNIVERSIT Y

Chapter 5. Section 5.4 The Common String Library Functions. CS 50 Hathairat Rattanasook

7. Procedures and Structured Programming

IMPORTANT QUESTIONS IN C FOR THE INTERVIEW

Annotation Annotation or block comments Provide high-level description and documentation of section of code More detail than simple comments

Technical Specification on further interoperability with C

Metview 4 ECMWF s next generation meteorological workstation

EL2310 Scientific Programming

Subroutines and Functions

BLM2031 Structured Programming. Zeyneb KURT

>B<82. 2Soft ware. C Language manual. Copyright COSMIC Software 1999, 2001 All rights reserved.

Transcription:

GRIB APIs Fortran 90 - C - Python interfaces part 1 Dominique Lucas Xavier Abellan Ecija User Support COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 1

Content Introduction The GRIB API library Fortran 90 interface Migration from GRIBEX to GRIB API C interface Python interface References COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 2

Introduction Do you really need to write a program to decode GRIB data? Before converting/writing a (Fortran, C or Python) code, you should evaluate whether you could use some grib tools instead Grib tools are optimized and fully supported Grib tools are intended to cover the usual processing of GRIB data Writing programs will remain necessary: Encoding/decoding GRIB messages within a meteorological model or within some postprocessing (e.g. MAGICS code). Writing a program will usually be more efficient than trying to achieve the same with tools/scripts. COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 3

The GRIB API library - installation Written in ANSI C 99 The only required package is jasper which enables the jpeg2000 packing/unpacking algorithm (GRIB-2). It is however possible to build GRIB API without jasper, by using the --disable-jpeg option at configuration (not recommended). The GRIB API also needs a version of netcdf (3) for the tool grib_to_netcdf. Classical installation based on autotools (configure, make, ) and new experimental installation based on CMake, from version 1.13.0. The GRIB API has been ported and tested on all platforms available at ECMWF. We receive and welcome feedback from external sites and will include requested changes, fixes, etc where possible. COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 4

The GRIB API library The IFS is using the GRIB API. Metview, magics use the grib_api. We have started producing GRIB-2 data (on model levels) on 18 May 2011. Some GRIB API tools used operationally. New data types (not only on Model levels) are also produced in GRIB-2 format, e.g. some MACC chemical data. Support: Installation issues: software.support@ecmwf.int Usage problems/questions: software.support@ecmwf.int or advisory@ecmwf.int. COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 5

Usage at ECMWF The GRIB API library is available on all ECMWF platforms. One library for single and double precision. Within the library, everything is done in double precision. In Fortran 90, the GRIB API will return/use the precision of the data variables defined in your program. Three user interfaces supported: Fortran (90), C and Python Fortran 90 interface: use grib_api (At ECMWF) Two environment variables GRIB_API_INCLUDE and GRIB_API_LIB are defined to ease the usage of GRIB API. On our platforms: ecgate: gfortran myprogram.f90 $GRIB_API_INCLUDE $GRIB_API_LIB cca/ccb: ftn myprogram.f90 COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 6

Usage at ECMWF changing version On HPCs and ecgate: module switch grib_api grib_api/<version> This year, we will use version 1.13.0, the default version at ECMWF still being version 1.12.3. See change history https://software.ecmwf.int/wiki/display/grib/history+of+changes COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 7

General framework A (Fortran/C/Python) code will include the following steps: Open one or more GRIB files (to read or write) You cannot use the standard Fortran calls to open or close a GRIB file. You have to call grib_open_file/grib_close_file Calls to load one or more GRIB messages into memory These subroutines will return a unique grib identifier which you can use to manipulate the loaded GRIB messages Calls to encode/decode the loaded GRIB messages You can only encode/decode loaded GRIB messages You should only encode/decode what you need (not the full message) Calls to write one or more GRIB messages into a file (encoding only) Release the loaded GRIB messages Close the opened GRIB files COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 8

Particulars of the F90 GRIB API interface All routines have an optional argument for error handling: subroutine grib_new_from_samples(igrib, samplename, status) integer, intent(out) :: igrib character(len=*), intent(in) :: samplename integer,optional, intent(out) :: status If status is not present and an error occurs, the program stops and returns the error code to the shell. COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 9

Particulars of the F90 GRIB API interface Use status to handle error yourself, e.g. necessary for MPI parallel codes) call grib_new_from_samples(igrib, samplename, status) if (status /= 0) then call grib_get_error_string(status,err_msg) print*, GRIB_API Error:,trim(err_msg), (err=,status, ) call mpi_finalize(ierr) stop end if The exit codes and their meanings are available under: https://software.ecmwf.int/wiki/display/grib/error+codes Input arguments Output arguments COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 10

Loading/Releasing a GRIB message (1/2) It is absolutely necessary to load a message because the GRIB API can only encode/decode loaded GRIB messages. 3 main subroutines to load a GRIB message grib_new_from_file(ifile, igrib) Loads a GRIB message from a file already opened with grib_open_file (use grib_close_file to close this file) grib_new_from_samples(igrib, GRIB1 ) Loads a GRIB message from a sample. Used for encoding. See further grib_new_from_index(indexid, igrib) Input arguments Output arguments Name of an existing GRIB sample Loads a GRIB message from an index. This index will first have to be built. See further... COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 11

Loading/releasing a GRIB message (2/2) The above 3 subroutines will return a unique grib identifier (igrib). You will manipulate the loaded GRIB message through this identifier. You do not have access to the buffer containing the loaded GRIB message. This buffer is internal to the GRIB API library. The buffer occupied by any GRIB message is kept in memory. Therefore, the routine grib_release(igrib) should always be used to free the buffer containing a loaded GRIB message. Input arguments Output arguments COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 12

Example Load from file Input arguments Output arguments 1 PROGRAM load_message 2 USE grib_api 3 implicit none 4 5 INTEGER :: rfile, igrib 6 CHARACTER(LEN=256), PARAMETER :: input_file='input.grb 7 CHARACTER(LEN=10), PARAMETER :: open_mode='r 8 9! 10! Open GRIB data file for reading. 11! 12 call grib_open_file(rfile, input_file, open_mode) 13 14 call grib_new_from_file(rfile, igrib) 15 16 17 call grib_release(igrib) 18 call grib_close_file (rfile) 19 END PROGRAM load_message r to read, w to write, a to append (C naming convention) Unique link to the buffer loaded in memory. Calls to grib_get/grib_set subroutines are necessary to access and decode/encode this message GRIB message COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 13

Decoding a loaded GRIB message The idea is to decode as little as possible! You will never decode the whole loaded GRIB message. (use grib_dump D <grib_file> to see how many GRIB API keys there are!) One main subroutine to decode: grib_get(igrib, keyname, keyvalues, status) integer, intent(in) :: igrib character(len=*), intent(in) :: keyname <type>,[dimension(:),] intent(out) :: keyvalues integer, optional, intent(out) :: status Input arguments Output arguments Where <type> is integer or single/double real precision or string COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 14

Decoding a GRIB message helper routines Get the size of an [array] key: grib_get_size(igrib, keyname, size, status) Dump the content of a grib_message: grib_dump(igrib, status) Check if a key is defined (exists) or not: grib_is_defined(igrib, keyname, exists, status) Check if a key is missing or not: grib_is_missing(igrib, keyname, missing, status) Count messages in file: grib_count_in_file(ifile, count, status) Input arguments Output arguments COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 15

Example grib_get! Load all the GRIB messages contained in file.grib1 call grib_open_file(ifile, 'file.grib1','r') n=1 call grib_new_from_file(ifile,igrib(n), iret) LOOP: do while (iret /= GRIB_END_OF_FILE) n=n+1; call grib_new_from_file(ifile,igrib(n), iret) end do LOOP! Decode/encode data from the loaded message read*, indx call grib_get( igrib(indx), datadate, date) call grib_get(igrib(indx), typeoflevel, typeoflevel) call grib_get(igrib(indx), level, level)! Choose one loaded GRIB message to decode call grib_get_size(igrib(indx), values, nb_values); allocate(values(nb_values)) call grib_get(igrib(indx), values, values) print*, date, leveltype, level, values(1), values(nb_values)! Release do i=1,n call grib_release(igrib(i)) end do deallocate(values) call grib_close_file(ifile) Input arguments Output arguments Loop on all the messages in a file. A new grib message is loaded from file. igrib(n) is the grib id to be used in subsequent calls Values is declared as real, dimension(:), allocatable:: values COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 16

GRIB API can do more The idea is to provide a set of high-level keys or subroutines to derive/compute extra information from a loaded GRIB message For instance: keys (READ-ONLY) to return average, min, max of values, distinct latitudes or longitudes Subroutines to compute the latitude, longitude and values: call grib_get_data(igrib,lats,lons,values,status) Subroutines to extract values closest to given geographical points: call grib_find_nearest(igrib, is_lsm, inlat, inlon, outlat, outlon, value, distance, index, status) Subroutine to extract values from a list of indexes: call grib_get_element(igrib, key, index, value, status) Input arguments Output arguments COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 17

How to migrate from GRIBEX to GRIB API? All your new GRIB related developments should be made with the GRIB API library. For existing codes, the most difficult task is to find a correspondence between GRIBEX ksec0(*),, ksec4(*), psec2(*), psec4(*), and GRIB API keys. See conversion tables under: https://software.ecmwf.int/wiki/display/grib/gribex+keys Try to use the recommended keys, i.e. keys that are valid for both GRIB-1 and GRIB-2 (for instance datadate instead of YearOfCentury, month, day ). See edition independent keys under: https://software.ecmwf.int/wiki/display/grib/gribex+keys COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 18

C API - Specifics #include grib_api.h module load grib_api to set GRIB_API paths gcc o myprogram myprogram.c $GRIB_API_INCLUDE $GRIB_API_LIB Main differences: C-Interface is more explicit than FORTRAN, e.g. type specific functions such as grib_get_double() Some helper functions do not exist, e.g. grib_open_file() COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 19

C API Error checking Built-in error checking for a call to a GRIB API function can be achieved with GRIB_CHECK: GRIB_CHECK(grib_get_long(h, Ni,&Ni),0); Or if error code is passed as function argument: h = grib_handle_new_from_file(0,in,&err); GRIB_CHECK(err,0); Alternatively, one can check the status: err = grib_get_long(h, Ni,&Ni); if (err!= 0) { printf("error: %s \n unable to get long variable\n, grib_get_error_message(err)); exit(1); } COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 20

C API Loading/Releasing a GRIB message grib_handle *h; structure giving access to parsed grib values. grib_handle* grib_handle_new_from_file(grib_context *c, FILE *fp, int *error) Create handle from a file. requires the input file to be opened with fp=fopen(filename, r ) and fclose(fp) to release the file pointer at the end of the program. grib_context *c should usually be set to 0. grib_handle * grib_handle_new_from_... samples (grib_context *c, const char *res_name) a message contained in a samples directory. message (grib_context *c, void *data, size_t length) a user message in memory. grib_handle_delete(h); Releases the handle. COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 21

C API - Decoding int grib_get_double(grib_handle *h, const char *key, double *value) Gets a double value from a key, if several keys of the same name are present, the last one is returned. Similar function for long exists. int grib_get_string(grib_handle *h, const char *key, char *message, size_t *length) Gets a string value from a key, if several keys of the same name are present, the last one is returned. String will be stored in pre-allocated memory message of size length. Similar function for bytes exists. int grib_get_double_array(grib_handle *h, const char *key, double *values, size_t *length) Gets double array values from a key. Use int grib_get_size(grib_handle *h, const char *key, size_t *length) to get the number of coded values (length) from a key (if several keys of the same name are present, the total sum is returned). Similar function for long array exists. COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 22

C API - Decoding int grib_nearest_find(grib_nearest * nearest, grib_handle * h, double inlat, double inlon, unsigned long flags, double * outlats, double * outlons, double * values, double * distances, int * indexes, size_t * len) Finds the 4 nearest points and their distance of a given latitude longitude point. flags should be set to 0, or can be set to GRIB_NEAREST_SAME_POINT GRIB_NEAREST_SAME_GRID outlats, outlons, values, distances and indexes have to be allocated and len should be set to 4 COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 23

Python API - Specifics To import, use: import gribapi module load grib_api Low level, procedural Provides almost 1 to 1 mappings to the C API functions Uses the NumPy module to efficiently handle data values COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 24

Python API Loading/Releasing a GRIB message gid = grib_new_from_file(file, headers_only=false) - Returns a handle to a GRIB message in a file - Requires the input file to be a Python file object - The use of the headers_only option is not recommended at the moment gid = grib_new_from_samples(samplename) - Returns a handle to a message contained in the samples directory gid = grib_new_from_message(message) - Returns a handle to a message in memory grib_release(gid) - Releases the handle COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 25

Python API - Decoding value = grib_get(gid, key, type=none) Returns the value of the requested key in the message gid is pointing to in its native format. Alternatively, one could choose what format to return the value in (int, str or float) by using the type keyword. values = grib_get_array(gid, key, type=none) Returns the contents of an array key as a NumPy ndarray or Python array. type can only be int or float. values = grib_get_values(gid) Gets data values as 1D array On error, a GribInternalError exception (which wraps errors coming from the C API) is thrown. COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 26

Python API - Utilities [outlat, outlon, value, distance, index] = grib_find_nearest(gid, inlat, inlon, is_lsm=false, npoints=1) - Find the nearest point for a given lat/lon - (Other possibility is npoints=4 which returns a list of the 4 nearest points) iter_id = grib_iterator_new(gid,mode) [lat,lon,value] = grib_iterator_next(iterid) grib_iterator_delete(iter_id) COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 27

References GRIB-1, GRIB-2: http://www.wmo.int/pages/prog/www/wmocodes.html GRIB API: https://software.ecmwf.int/wiki/display/grib/grib+api/ GRIB API Fortran, C or Python interfaces: f90: https://software.ecmwf.int/wiki/display/grib/fortran+package+grib_api C: https://software.ecmwf.int/wiki/display/grib/module+index Python: https://software.ecmwf.int/wiki/display/grib/python+package+gribapi GRIB API examples: https://software.ecmwf.int/wiki/display/grib/grib+api+examples GRIBEX GRIB API conversion: https://software.ecmwf.int/wiki/display/grib/gribex+keys COM GRIB: GRIB APIs Fortran 90 - C - Python interfaces ECMWF 2015 Slide 28