Description
This example shows: How to create and use an index to access GRIB messages from a file. Demo also loading and writing an index from a file.
Source code
grib_index.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 create and use an index to access GRIB messages from a file. ! Demo also loading and writing an index from a file. ! ! ! program index use eccodes implicit none integer :: iret integer,dimension(:),allocatable :: step,level,number character(len=20),dimension(:),allocatable :: shortName integer :: ostep,olevel,onumber character(len=20) :: oshortName integer :: shortNameSize,numberSize,levelSize,stepSize integer :: i,j,k,l integer :: idx,igrib,count1 character(len=10) :: index_file='index.idx' ! uncomment following line to load index from file !call codes_index_read(idx,index_file) ! create an index from a grib file using some keys call codes_index_create(idx,'../../data/index.grib','shortName,number,level,step') ! get the number of distinct values of shortName in the index call codes_index_get_size(idx,'shortName',shortNameSize) ! allocate the array to contain the list of distinct shortName allocate(shortName(shortNameSize)) ! get the list of distinct shortName from the index call codes_index_get(idx,'shortName',shortName) write(*,'(a,i3)') 'shortNameSize=',shortNameSize ! get the number of distinct values of number in the index call codes_index_get_size(idx,'number',numberSize) ! allocate the array to contain the list of distinct numbers allocate(number(numberSize)) ! get the list of distinct numbers from the index call codes_index_get(idx,'number',number) write(*,'(a,i3)') 'numberSize=',numberSize ! get the number of distinct values of level in the index call codes_index_get_size(idx,'level',levelSize) ! allocate the array to contain the list of distinct levels allocate(level(levelSize)) ! get the list of distinct levels from the index call codes_index_get(idx,'level',level) write(*,'(a,i3)') 'levelSize=',levelSize ! get the number of distinct values of step in the index call codes_index_get_size(idx,'step',stepSize) ! allocate the array to contain the list of distinct steps allocate(step(stepSize)) ! get the list of distinct steps from the index call codes_index_get(idx,'step',step) write(*,'(a,i3)') 'stepSize=',stepSize count1=0 do l=1,stepSize ! loop on step ! select step=step(l) call codes_index_select(idx,'step',step(l)) do j=1,numberSize ! loop on number ! select number=number(j) call codes_index_select(idx,'number',number(j)) do k=1,levelSize ! loop on level ! select level=level(k) call codes_index_select(idx,'level',level(k)) do i=1,shortNameSize ! loop on shortName ! select shortName=shortName(i) call codes_index_select(idx,'shortName',shortName(i)) call codes_new_from_index(idx,igrib, iret) do while (iret /= CODES_END_OF_INDEX) count1=count1+1 call codes_get(igrib,'shortName',oshortName) call codes_get(igrib,'number',onumber) call codes_get(igrib,'level',olevel) call codes_get(igrib,'step',ostep) write(*,'(A,A,A,i3,A,i4,A,i3)') 'shortName=',trim(oshortName),& ' number=',onumber,& ' level=' ,olevel, & ' step=' ,ostep call codes_release(igrib) call codes_new_from_index(idx,igrib, iret) end do call codes_release(igrib) end do ! loop on step end do ! loop on level end do ! loop on number end do ! loop on shortName write(*,'(i4,a)') count1,' messages selected' ! save the index to a file for later reuse call codes_index_write(idx,index_file) call codes_index_release(idx) deallocate(level) deallocate(shortName) deallocate(step) deallocate(number) end program index
grib_index.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. # # Description: How to create and use an index to access GRIB messages from # a file import traceback import sys import os from eccodes import * INPUT = '../../data/index.grib' VERBOSE = 1 # verbose error reporting def product(*args, **kwds): # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 pools = list(map(tuple, args)) * kwds.get('repeat', 1) result = [[]] for pool in pools: result = [x + [y] for x in result for y in pool] for prod in result: yield tuple(prod) def example(): index_keys = ["shortName", "level", "number", "step"] index_file = "my.idx" iid = None if os.path.exists(index_file): iid = codes_index_read(index_file) else: iid = codes_index_new_from_file(INPUT, index_keys) # multiple files can be added to an index: # codes_index_add_file(iid,"grib file to add") codes_index_write(iid, index_file) index_vals = [] for key in index_keys: print("%sSize=%d" % ( key, codes_index_get_size(iid, key) )) key_vals = codes_index_get(iid, key) print(" ".join(key_vals)) index_vals.append(key_vals) for prod in product(*index_vals): for i in range(len(index_keys)): codes_index_select(iid, index_keys[i], prod[i]) while 1: gid = codes_new_from_index(iid) if gid is None: break print(" ".join(["%s=%s" % (key, codes_get(gid, key)) for key in index_keys])) codes_release(gid) codes_index_release(iid) def main(): try: example() 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())
grib_index.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: grib_index * * Description: How to create and use an index to access GRIB messages from a file * */ #include "eccodes.h" static void usage(const char* prog) { printf("usage: %s infile\n",prog); exit(1); } int main(int argc,char* argv[]) { codes_index* index=NULL; codes_handle* h=NULL; char* infile=NULL; long *steps,*levels,*numbers; /* arrays */ char** shortName=NULL; int i,j,k,l; size_t stepSize,levelSize,shortNameSize,numberSize; long ostep,olevel,onumber; char oshortName[200]; size_t lenshortName=200; int ret=0,count=0; if (argc != 2) usage(argv[0]); infile=argv[1]; printf("indexing...\n"); /* Create an index given set of keys*/ index=codes_index_new(0,"shortName,level,number,step",&ret); if (ret) {printf("error: %s\n",codes_get_error_message(ret)); exit(ret);} /* Indexes a file */ ret=codes_index_add_file(index,infile); if (ret) {printf("error: %s\n",codes_get_error_message(ret)); exit(ret);} printf("end indexing...\n"); /* get the number of distinct values of "step" in the index */ CODES_CHECK(codes_index_get_size(index,"step",&stepSize),0); steps=(long*)malloc(sizeof(long)*stepSize); if (!steps) exit(1); /* get the list of distinct steps from the index */ /* the list is in ascending order */ CODES_CHECK(codes_index_get_long(index,"step",steps,&stepSize),0); printf("stepSize=%ld\n",(long)stepSize); for (i=0;i<stepSize;i++) printf("%ld ",steps[i]); printf("\n"); /*same as for "step"*/ CODES_CHECK(codes_index_get_size(index,"level",&levelSize),0); levels=(long*)malloc(sizeof(long)*levelSize); if (!levels) exit(1); /*same as for "step"*/ CODES_CHECK(codes_index_get_long(index,"level",levels,&levelSize),0); printf("levelSize=%ld\n",(long)levelSize); for (i=0;i<levelSize;i++) printf("%ld ",levels[i]); printf("\n"); /*same as for "step"*/ CODES_CHECK(codes_index_get_size(index,"number",&numberSize),0); numbers=(long*)malloc(sizeof(long)*numberSize); if (!numbers) exit(1); /*same as for "step"*/ CODES_CHECK(codes_index_get_long(index,"number",numbers,&numberSize),0); printf("numberSize=%ld\n",(long)numberSize); for (i=0;i<numberSize;i++) printf("%ld ",numbers[i]); printf("\n"); /*same as for "step"*/ CODES_CHECK(codes_index_get_size(index,"shortName",&shortNameSize),0); shortName=(char**)malloc(sizeof(char*)*shortNameSize); if (!shortName) exit(1); /*same as for "step"*/ CODES_CHECK(codes_index_get_string(index,"shortName",shortName,&shortNameSize),0); printf("shortNameSize=%ld\n",(long)shortNameSize); for (i=0;i<shortNameSize;i++) printf("%s ",shortName[i]); printf("\n"); count=0; /* nested loops on the keys values of the index */ /* different order of the nested loops doesn't affect performance*/ for (i=0;i<shortNameSize;i++) { /* select the GRIB with shortName=shortName[i] */ codes_index_select_string(index,"shortName",shortName[i]); for (l=0;l<levelSize;l++) { /* select the GRIB with level=levels[l] */ codes_index_select_long(index,"level",levels[l]); for (j=0;j<numberSize;j++) { /* select the GRIB with number=numbers[j] */ codes_index_select_long(index,"number",numbers[j]); for (k=0;k<stepSize;k++) { /* select the GRIB with step=steps[k] */ codes_index_select_long(index,"step",steps[k]); /* create a new codes_handle from the index with the constraints imposed by the select statements. It is a loop because in the index there could be more than one GRIB with those constraints */ while ((h=codes_handle_new_from_index(index,&ret))!=NULL){ count++; if (ret) {printf("error: %d\n",ret); exit(ret);} lenshortName=200; codes_get_string(h,"shortName",oshortName,&lenshortName); codes_get_long(h,"level",&olevel); codes_get_long(h,"number",&onumber); codes_get_long(h,"step",&ostep); printf("shortName=%s ",oshortName); printf("level=%ld ",olevel); printf("number=%ld ",onumber); printf("step=%ld \n",ostep); codes_handle_delete(h); } if (ret && ret!=GRIB_END_OF_INDEX ) {printf("error: %s\n",codes_get_error_message(ret)); exit(ret);} } } } } printf(" %d messages selected\n",count); codes_index_write(index,"out.gribidx"); codes_index_delete(index); return 0; }