From dc10064c37249e3f5f6f039e54a8c409d5e46739 Mon Sep 17 00:00:00 2001 From: Sandor Kertesz Date: Thu, 5 Feb 2015 16:29:49 +0000 Subject: [PATCH] Add bufr_exapnded and bufr_subset examples ECC-15 --- examples/C/CMakeLists.txt | 4 ++ examples/C/Makefile.am | 9 +++- examples/C/bufr_expanded.c | 86 +++++++++++++++++++++++++++++++++ examples/C/bufr_expanded.sh | 42 ++++++++++++++++ examples/C/bufr_print_data.c | 8 ++-- examples/C/bufr_subset.c | 92 ++++++++++++++++++++++++++++++++++++ examples/C/bufr_subset.sh | 31 ++++++++++++ examples/F90/bufr_clone.sh | 4 +- tests/bufr_set.sh | 4 +- 9 files changed, 272 insertions(+), 8 deletions(-) create mode 100644 examples/C/bufr_expanded.c create mode 100755 examples/C/bufr_expanded.sh create mode 100644 examples/C/bufr_subset.c create mode 100755 examples/C/bufr_subset.sh diff --git a/examples/C/CMakeLists.txt b/examples/C/CMakeLists.txt index 0304e63c3..0315c911d 100644 --- a/examples/C/CMakeLists.txt +++ b/examples/C/CMakeLists.txt @@ -33,8 +33,10 @@ list( APPEND test_bins check_gaussian_grid ensemble_index bufr_clone + bufr_expanded bufr_print_header bufr_print_data + bufr_subset ) foreach( tool ${test_bins} ) ecbuild_add_executable( TARGET ${tool} @@ -64,8 +66,10 @@ list( APPEND tests set_pv check_gaussian_grids bufr_clone + bufr_expanded bufr_print_header bufr_print_data + bufr_subset ) foreach( test ${tests} ) ecbuild_add_test( TARGET c_${test} diff --git a/examples/C/Makefile.am b/examples/C/Makefile.am index 0da02d7ec..299bc5b2a 100644 --- a/examples/C/Makefile.am +++ b/examples/C/Makefile.am @@ -3,12 +3,15 @@ AM_CFLAGS = @WARN_PEDANTIC@ @WERROR@ TESTS = iterator.sh get.sh print_data.sh set.sh keys_iterator.sh multi.sh multi_write.sh \ precision.sh list.sh large_grib1.sh get_data.sh sections_copy.sh set_missing.sh clone.sh set_pv.sh \ - check_gaussian_grids.sh bufr_clone.sh bufr_print_header.sh bufr_print_data.sh + check_gaussian_grids.sh \ + bufr_clone.sh bufr_expanded.sh bufr_print_header.sh bufr_print_data.sh bufr_subset.sh noinst_PROGRAMS = nearest set_bitmap iterator get print_data set set_missing keys_iterator \ set_data mars_param values_check box multi multi2 multi_write precision \ set_pv list sections_copy large_grib1 get_data iterator_bitmap clone new_sample \ - check_gaussian_grid ensemble_index points bufr_clone bufr_print_header bufr_print_data + check_gaussian_grid ensemble_index points \ + bufr_clone bufr_expanded bufr_print_header bufr_print_data \ + bufr_subset #bin_PROGRAMS = points box_SOURCES = box.c @@ -38,8 +41,10 @@ new_sample_SOURCES = new_sample.c check_gaussian_grid_SOURCES = check_gaussian_grid.c ensemble_index_SOURCES = ensemble_index.c bufr_clone_SOURCES = bufr_clone.c +bufr_expanded_SOURCES = bufr_expanded.c bufr_print_header_SOURCES = bufr_print_header.c bufr_print_data_SOURCES = bufr_print_data.c +bufr_subset_SOURCES = bufr_subset.c INCLUDES = -I$(top_builddir)/src diff --git a/examples/C/bufr_expanded.c b/examples/C/bufr_expanded.c new file mode 100644 index 000000000..bc081f072 --- /dev/null +++ b/examples/C/bufr_expanded.c @@ -0,0 +1,86 @@ +/* + * Copyright 2005-2015 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_expanded + * + * Description: how to read all the exapanded data values from BUFR messages. + * + */ + +#include "eccodes.h" + +void usage(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; + + double *values = NULL; + long longVal; + double doubleVal; + size_t values_len=0; + int i, err=0; + int cnt=0; + + if (argc!=2) usage(argv[0]); + + filename=argv[1]; + + in=fopen(filename,"r"); + if (!in) { + printf("ERROR: unable to open file %s\n", filename); + return 1; + } + + /* loop over the messages in the bufr file */ + while ((h = bufr_new_from_file(NULL,in,&err)) != NULL || err != CODES_SUCCESS) + { + if (h == NULL) { + printf("Error: unable to create handle for message %d\n",cnt); + cnt++; + continue; + } + + /* we need to instruct ecCodes to unpack the data values */ + CODES_CHECK(codes_set_long(h,"unpack",1),0); + + /* get the size of the values array*/ + CODES_CHECK(codes_get_size(h,"numericValues",&values_len),0); + + /* allocate array for data values */ + values = malloc(values_len*sizeof(double)); + + /* get the exapanded data values*/ + CODES_CHECK(codes_get_double_array(h,"numericValues",values,&values_len),0); + + for(i = 0; i < values_len; i++) + { + printf("%.10e\n",values[i]); + } + + free(values); + + /* delete handle */ + codes_handle_delete(h); + + cnt++; + } + + fclose(in); + return 0; +} diff --git a/examples/C/bufr_expanded.sh b/examples/C/bufr_expanded.sh new file mode 100755 index 000000000..dbfa3732f --- /dev/null +++ b/examples/C/bufr_expanded.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# Copyright 2005-2015 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. + +. ./include.sh + +#set -x + +#Define a common label for all the tmp files +label="bufr_expanded_test.c" + +f=${data_dir}/bufr/syno_1.bufr + +#Prepare tmp file +fTmp=${label}.tmp.txt +rm -f $fTmp | true + +#Reference file +ref_num=${f}.num.ref + +REDIRECT=/dev/null + +#Write the values into a file and compare with reference +${examples_dir}/bufr_expanded $f > $fTmp 2> $REDIRECT + +[ `wc -l ${fTmp}` -gt 100 ] + +#kdiff3 $ref_num $fTmp + +# Cannot use plain diff. We need to compare FLOAT NUMBERS with a tolerance +#perl /tmp/cgr/build/grib_api/eccodes/tests/number_compare.pl $ref_num $fTmp #>$REDIRECT 2> $REDIRECT + + +#cat $fTmp + +#Clean up +rm -f $fTmp diff --git a/examples/C/bufr_print_data.c b/examples/C/bufr_print_data.c index bdcdfbe1a..837214ac4 100644 --- a/examples/C/bufr_print_data.c +++ b/examples/C/bufr_print_data.c @@ -61,13 +61,15 @@ int main(int argc,char* argv[]) /* read and print some data values */ CODES_CHECK(codes_get_long(h,"blockNumber",&longVal),0); - printf("\tblockNumber: %ld\n",longVal); + printf(" blockNumber: %ld\n",longVal); CODES_CHECK(codes_get_long(h,"stationNumber",&longVal),0); - printf("\tstationNumber: %ld\n",longVal); + printf(" stationNumber: %ld\n",longVal); + /* in the current BUFR message this key represents the 2m temperature. + it might not be availabel in other type of SYNOP messages */ CODES_CHECK(codes_get_double(h,"airTemperatureAt2M",&doubleVal),0); - printf("\tairTemperatureAt2M %f\n",doubleVal); + printf(" airTemperatureAt2M %f\n",doubleVal); /* delete handle */ codes_handle_delete(h); diff --git a/examples/C/bufr_subset.c b/examples/C/bufr_subset.c new file mode 100644 index 000000000..a96fb0fd1 --- /dev/null +++ b/examples/C/bufr_subset.c @@ -0,0 +1,92 @@ +/* + * Copyright 2005-2015 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_subset + * + * Description: how to read data values from a given subset of a BUFR message. + * + */ + +#include "eccodes.h" + +void usage(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; + + double *values = NULL; + long numberOfSubsets=0; + long longVal; + double doubleVal; + size_t values_len=0; + int i,err=0; + int cnt=0; + char* infile = "../../data/bufr/synop_multi_subset.bufr"; + + + in=fopen(infile,"r"); + if (!in) { + printf("ERROR: unable to open file %s\n", infile); + return 1; + } + + /* loop over the messages in the bufr file */ + while ((h = bufr_new_from_file(NULL,in,&err)) != NULL || err != CODES_SUCCESS) + { + if (h == NULL) { + printf("Error: unable to create handle for message %d\n",cnt); + cnt++; + continue; + } + + printf("message: %d\n",cnt); + + /* we need to instruct ecCodes to expand all the descriptors i.e. unpack the data values */ + CODES_CHECK(codes_set_long(h,"unpack",1),0); + + /* find ou the number of subsets */ + CODES_CHECK(codes_get_long(h,"numberOfSubsets",&numberOfSubsets),0); + printf(" numberOfSubsets: %ld\n",numberOfSubsets); + + /* loop over the subsets */ + for(i=0; i < numberOfSubsets; i++) + { + /* specify the subset number */ + CODES_CHECK(codes_set_long(h,"subsetNumber",0),0); + + /* read and print some data values */ + CODES_CHECK(codes_get_long(h,"blockNumber",&longVal),0); + printf(" blockNumber: %ld\n",longVal); + + CODES_CHECK(codes_get_long(h,"stationNumber",&longVal),0); + printf(" stationNumber: %ld\n",longVal); + + /* CODES_CHECK(codes_get_double(h,"airTemperatureAt2M",&doubleVal),0); + printf(" airTemperatureAt2M %f\n",doubleVal);*/ + } + + /* delete handle */ + codes_handle_delete(h); + + cnt++; + } + + fclose(in); + return 0; +} diff --git a/examples/C/bufr_subset.sh b/examples/C/bufr_subset.sh new file mode 100755 index 000000000..d65bbf0b5 --- /dev/null +++ b/examples/C/bufr_subset.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# Copyright 2005-2015 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. +# + +. ./include.sh + +#----------------------------------------------------- +# Test reading the header only from a BUFR +# file with multiple messages +#---------------------------------------------------- +f=${data_dir}"/bufr/syno_multi.bufr" +fRef=$f".header.ref" +fRes=$f".header.test.c" +REDIRECT=/dev/null + +#Write the values into a file and compare with reference +${examples_dir}/bufr_subset #2> $REDIRECT > $fRes + +#We compare output to the reference by ignoring the whitespaces +#diff -w $fRef $fRes >$REDIRECT 2> $REDIRECT + +#cat $fRes + +#Clean up +rm -f $fRes diff --git a/examples/F90/bufr_clone.sh b/examples/F90/bufr_clone.sh index d7b75a2e0..d37777425 100755 --- a/examples/F90/bufr_clone.sh +++ b/examples/F90/bufr_clone.sh @@ -10,8 +10,8 @@ . ./include.sh #These files are hardcoded in the f90 example -f=${data_dir}/bufr/syno_multi.bufr #input -fTmp=out.clone.f.bufr #output +f=${data_dir}/bufr/syno_multi.bufr #input +fTmp=out.clone.f.bufr #output REDIRECT=/dev/null diff --git a/tests/bufr_set.sh b/tests/bufr_set.sh index e7c0997ab..55fe4c205 100755 --- a/tests/bufr_set.sh +++ b/tests/bufr_set.sh @@ -119,7 +119,7 @@ ${tools_dir}/bufr_set -f -s center=98 $f $fBufrTmp 2>>$fLog 1>>$fLog # Test: with not allowed key values #----------------------------------------------------------- -#Here 1024 is out of range for centre (it is 8-bit only for edition=4 files) +#Here 1024 is out of range for centre (it is 8-bit only for edition=3 files) # Invoke without -f i.e. should fail if error encountered set +e @@ -140,7 +140,9 @@ ${tools_dir}/bufr_set -f -s centre=1024 -f $f $fBufrTmp 2>>$fLog 1>>$fLog #----------------------------------------------------------- # Test: key values out of range #----------------------------------------------------------- + f=aaen_55.bufr + # The correction1 key is of type "bits" and only 6 bits wide # So its range is 0 -> 63 inclusive ${tools_dir}/bufr_set -s correction1=63 $f $fBufrTmp 2>>$fLog 1>>$fLog