Description
This example shows: how to use keys_iterator functions and the codes_bufr_keys_iterator structure to get all the available keys in a BUFR message.
Source code
bufr_keys_iterator.f90
! (C) Copyright 2005- ECMWF. ! ! This software is licensed under the terms of the Apache Licence Version 2.0 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. ! ! In applying this licence, ECMWF does not waive the privileges and immunities granted to it by ! virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. ! ! ! ! Description: How to use keys_iterator functions and the ! codes_bufr_keys_iterator structure to get all the available ! keys in a BUFR message. ! program bufr_keys_iterator use eccodes implicit none integer :: ifile integer :: iret integer :: ibufr integer :: count = 0 character(len=256) :: key integer :: kiter integer :: subset = 1 call codes_open_file(ifile, '../../data/bufr/syno_1.bufr', 'r') ! The first BUFR message is loaded from file, ! ibufr is the BUFR id to be used in subsequent calls call codes_bufr_new_from_file(ifile, ibufr, iret) do while (iret /= CODES_END_OF_FILE) ! Get and print some keys from the BUFR header write (*, *) 'message: ', count ! We need to instruct ecCodes to expand all the descriptors ! i.e. unpack the data values call codes_set(ibufr, "unpack", 1); ! Create BUFR keys iterator call codes_bufr_keys_iterator_new(ibufr, kiter, iret) if (iret .ne. 0) then write (*, *) 'ERROR: Unable to create BUFR keys iterator' call exit(1) end if ! Get first key call codes_bufr_keys_iterator_next(kiter, iret) ! Loop over keys do while (iret == CODES_SUCCESS) ! Print key name call codes_bufr_keys_iterator_get_name(kiter, key) if (key == 'subsetNumber') then write (*, *) ' Subset ', subset subset = subset + 1 else write (*, *) ' ', trim(key) end if ! Get next key call codes_bufr_keys_iterator_next(kiter, iret) end do ! Delete key iterator call codes_bufr_keys_iterator_delete(kiter) ! Release the BUFR message call codes_release(ibufr) ! Load the next BUFR message call codes_bufr_new_from_file(ifile, ibufr, iret) count = count + 1 end do ! Close file call codes_close_file(ifile) end program bufr_keys_iterator
bufr_keys_iterator.py
# (C) Copyright 2005- ECMWF. # # This software is licensed under the terms of the Apache Licence Version 2.0 # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. # # In applying this licence, ECMWF does not waive the privileges and immunities # granted to it by virtue of its status as an intergovernmental organisation # nor does it submit to any jurisdiction. # # Python implementation: bufr_keys_iterator # # Description: Example on how to use keys_iterator functions and the # codes_bufr_keys_iterator structure to get all the available # keys in a BUFR message. import sys import traceback from eccodes import * VERBOSE = 1 # verbose error reporting def example(INPUT): # open bufr file f = open(INPUT, "rb") cnt = 0 subset = 0 # loop for the messages in the file while 1: # get handle for message bufr = codes_bufr_new_from_file(f) if bufr is None: break print("message: %s" % cnt) # we need to instruct ecCodes to expand all the descriptors # i.e. unpack the data values codes_set(bufr, "unpack", 1) # get BUFR key iterator iterid = codes_bufr_keys_iterator_new(bufr) # loop over the keys while codes_bufr_keys_iterator_next(iterid): # print key name keyname = codes_bufr_keys_iterator_get_name(iterid) if keyname == "subsetNumber": subset += 1 print(" Subset: %d" % subset) else: print(" %s" % keyname) # delete the key iterator codes_bufr_keys_iterator_delete(iterid) cnt += 1 # delete handle codes_release(bufr) # close the file f.close() def main(): try: example(sys.argv[1]) except CodesInternalError as err: if VERBOSE: traceback.print_exc(file=sys.stderr) else: sys.stderr.write(err.msg + "\n") return 1 if __name__ == "__main__": sys.exit(main())
bufr_keys_iterator.c
/* * (C) Copyright 2005- ECMWF. * * This software is licensed under the terms of the Apache Licence Version 2.0 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. * * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. */ /* * C Implementation: bufr_keys_iterator * * Description: how to use keys_iterator functions and the * codes_bufr_keys_iterator structure to get all the available * keys in a BUFR message. * */ #include "eccodes.h" #define MAX_VAL_LEN 1024 static void usage(const char* prog) { printf("usage: %s infile\n", prog); exit(1); } int main(int argc, char* argv[]) { char* filename = NULL; FILE* in = NULL; /* message handle. Required in all the eccodes calls acting on a message.*/ codes_handle* h = NULL; int err = 0, cnt = 0; int keyType = 0; int subsetNumber = 0; char value[MAX_VAL_LEN]; size_t vlen = MAX_VAL_LEN; size_t klen = 0; if (argc != 2) usage(argv[0]); filename = argv[1]; in = fopen(filename, "rb"); if (!in) { fprintf(stderr, "Error: unable to open file %s\n", filename); return 1; } /* loop over the messages in the BUFR file */ while ((h = codes_handle_new_from_file(NULL, in, PRODUCT_BUFR, &err)) != NULL || err != CODES_SUCCESS) { codes_bufr_keys_iterator* kiter = NULL; if (h == NULL) { fprintf(stderr, "Error: unable to create handle for message %d\n", cnt); cnt++; continue; } printf("message: %d\n", cnt); /* we need to instruct ecCodes to unpack the data values */ CODES_CHECK(codes_set_long(h, "unpack", 1), 0); /* get BUFR key iterator */ kiter = codes_bufr_keys_iterator_new(h, 0); if (!kiter) { fprintf(stderr, "Error: Unable to create BUFR keys iterator\n"); exit(1); } /* loop over the keys */ while (codes_bufr_keys_iterator_next(kiter)) { /* get key name */ char* name = codes_bufr_keys_iterator_get_name(kiter); if (strcmp(name, "subsetNumber") == 0) { subsetNumber++; printf("\n Subset %d:\n", subsetNumber); continue; } printf(" %s=", name); CODES_CHECK(codes_get_native_type(h, name, &keyType), 0); /* get key size to see if it is an array */ CODES_CHECK(codes_get_size(h, name, &klen), 0); if (klen == 1) { /* not array */ vlen = MAX_VAL_LEN; memset(value, 0, vlen); codes_get_string(h, name, value, &vlen); printf("%s\n", value); } else { /* for arrays */ printf("(array of %lu)\n", (unsigned long)klen); } } /* delete key iterator */ codes_bufr_keys_iterator_delete(kiter); /* delete handle */ codes_handle_delete(h); cnt++; } fclose(in); return 0; }