Make C, Fortran and Python examples ECC-15

This commit is contained in:
Sandor Kertesz 2015-03-20 10:41:01 +00:00
parent d7da1828a6
commit 4297cd350d
12 changed files with 345 additions and 41 deletions

View File

@ -41,6 +41,7 @@ list( APPEND test_bins
bufr_keys_iterator
bufr_missing
bufr_read_header
bufr_read_scatterometer
bufr_read_synop
bufr_read_temp
bufr_set_keys
@ -80,6 +81,7 @@ list( APPEND tests
bufr_keys_iterator
bufr_missing
bufr_read_header
bufr_read_scatterometer
bufr_read_synop
bufr_read_temp
bufr_set_keys

View File

@ -22,6 +22,7 @@ TESTS = grib_iterator.sh \
bufr_expanded.sh \
bufr_get_keys.sh \
bufr_read_header.sh \
bufr_read_scatterometer.sh \
bufr_read_synop.sh \
bufr_set_keys.sh \
bufr_subset.sh \
@ -63,6 +64,7 @@ noinst_PROGRAMS = c_grib_nearest \
c_bufr_expanded \
c_bufr_get_keys \
c_bufr_read_header \
c_bufr_read_scatterometer \
c_bufr_read_synop \
c_bufr_get_keys \
c_bufr_subset \
@ -109,6 +111,7 @@ c_bufr_get_keys_SOURCES = bufr_get_keys.c
c_bufr_keys_iterator_SOURCES = bufr_keys_iterator.c
c_bufr_missing_SOURCES = bufr_missing.c
c_bufr_read_header_SOURCES = bufr_read_header.c
c_bufr_read_scatterometer_SOURCES = bufr_read_scatterometer.c
c_bufr_read_synop_SOURCES = bufr_read_synop.c
c_bufr_read_temp_SOURCES = bufr_read_temp.c
c_bufr_set_keys_SOURCES = bufr_set_keys.c

View File

@ -0,0 +1,146 @@
/*
* 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_read_scatterometer
*
* Description: how to read data for a given beam from scatterometer BUFR messages.
*
*/
/*
* Please note that scatterometer data can be encoded in various ways in BUFR. Therefore the code
* below might not work directly for other types of SYNOP messages than the one used in the
* example. It is advised to use bufr_dump to understand the structure of the messages.
*/
#include "eccodes.h"
int main(int argc,char* argv[])
{
FILE* in = NULL;
/* Message handle. Required in all the eccodes calls acting on a message.*/
codes_handle* h=NULL;
double *lat=NULL, *lon=NULL, *bscatter=NULL;
long longVal;
double doubleVal;
size_t numObs,len;
int i, err=0;
int cnt=0;
char* infile = "../../data/bufr/asca_139.bufr";
char key_name[128];
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 = codes_handle_new_from_file(NULL,in,PRODUCT_BUFR,&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 the descriptors
* i.e. unpack the data values */
CODES_CHECK(codes_set_long(h,"unpack",1),0);
/* The BUFR file contains a single message with 2016 subsets in a compressed form.
* It means each subset has exactly the same structure: they store one location with
* several beams and one backscatter value in each beam.
*
* To print the backScatter values for beamIdentifier=2 from all the subsets
* we will simply access the key by condition (see below) */
/* Get the total number of subsets. */
CODES_CHECK(codes_get_long(h,"numberOfSubsets",&numObs),0);
printf("Number of values: %ld\n",numObs);
/* Allocate memory for the values to be read. Each
* parameter must have the same number of values. */
lat = malloc(numObs*sizeof(double));
lon = malloc(numObs*sizeof(double));
bscatter = malloc(numObs*sizeof(double));
/* Get latitude */
sprintf(key_name,"latitude");
/* Check the size (including all the subsets) */
CODES_CHECK(codes_get_size(h,key_name,&len),0);
if(len != numObs)
{
printf("inconsistent number of %s values found!\n",key_name);
return 1;
}
/* Get the values (from all the subsets) */
CODES_CHECK(codes_get_double_array(h,key_name,lat,&len),0);
/* Get longitude */
sprintf(key_name,"longitude");
/* Check the size (including all the subsets) */
CODES_CHECK(codes_get_size(h,key_name,&len),0);
if(len != numObs)
{
printf("inconsistent number of %s values found!\n",key_name);
return 1;
}
/* Get the values (from all the subsets) */
CODES_CHECK(codes_get_double_array(h,key_name,lon,&len),0);
/* Get backScatter for beam two. We use an access by condition for this key. */
sprintf(key_name,"/beamIdentifier=2/backscatter");
/* Check the size (including all the subsets) */
CODES_CHECK(codes_get_size(h,key_name,&len),0);
if(len != numObs)
{
printf("inconsistent number of %s values found!\n",key_name);
return 1;
}
/* Get the values (from all the subsets) */
CODES_CHECK(codes_get_double_array(h,key_name,bscatter,&len),0);
/* Print the values */
printf("pixel lat lon backscatter \n");
printf("-------------------------------\n");
for(i=0; i < numObs; i++)
{
printf("%4d %.3f %.3f %.3f \n",
i+1,lat[i],lon[i],bscatter[i]);
}
/* Delete handle */
codes_handle_delete(h);
/* Release memory */
free(lat);
free(lon);
free(bscatter);
cnt++;
}
fclose(in);
return 0;
}

View File

@ -0,0 +1,34 @@
#!/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
#Define a common label for all the tmp files
label="bufr_read_scatterometer_c"
#Define tmp file
fTmp=${label}.tmp.txt
rm -f $fTmp | true
#We check "asca_139.bufr". The path is
#hardcoded in the example
REDIRECT=/dev/null
#Write the key values into a file
${examples_dir}c_bufr_read_scatterometer #2> $REDIRECT > $fTmp
#TODO: check the results
#cat $fTmp
#Clean up
rm -f $fTmp | true

View File

@ -18,7 +18,7 @@
/*
* Please note that SYNOP reports can be encoded in various ways in BUFR. Therefore the code
* below might not work directly for other types of SYNOP messages than the one used in the
* example.
* example. It is advised to use bufr_dump to understand the structure of the messages.
*/
@ -78,18 +78,46 @@ int main(int argc,char* argv[])
/* 2m temperature */
CODES_CHECK(codes_get_double(h,"airTemperatureAt2M",&doubleVal),0);
printf(" airTemperatureAt2M %f\n",doubleVal);
printf(" airTemperatureAt2M: %f\n",doubleVal);
/* 2m dewpoint temperature */
CODES_CHECK(codes_get_double(h,"dewpointTemperatureAt2M",&doubleVal),0);
printf(" dewpointTemperatureAt2M %f\n",doubleVal);
printf(" dewpointTemperatureAt2M: %f\n",doubleVal);
/* 10 wind */
CODES_CHECK(codes_get_double(h,"windSpeedAt10M",&doubleVal),0);
printf(" windSpeedAt10M %f\n",doubleVal);
printf(" windSpeedAt10M: %f\n",doubleVal);
CODES_CHECK(codes_get_double(h,"windDirectionAt10M",&doubleVal),0);
printf(" windDirectionAt10M %f\n",doubleVal);
printf(" windDirectionAt10M: %f\n",doubleVal);
/* The cloud information is stored in several blocks in the
* SYNOP message and the same key means a different thing in different
* parts of the message. In this example we will read the first
* cloud block introduced by the key
* verticalSignificanceSurfaceObservations=1.
* We know that this is the first occurrence of the keys we want to
* read so we will use the # (occurrence) operator accordingly. */
/* Cloud amount (low and middleclouds) */
CODES_CHECK(codes_get_long(h,"cloudAmount#1",&longVal),0);
printf(" cloudAmount (low and middle): %ld\n",longVal);
/* Height of cloud base */
CODES_CHECK(codes_get_long(h,"heightOfBaseOfCloud#1",&longVal),0);
printf(" heightOfBaseOfCloud: %ld\n",longVal);
/* Cloud type (low clouds) */
CODES_CHECK(codes_get_long(h,"cloudType#1",&longVal),0);
printf(" cloudType (low): %ld\n",longVal);
/* Cloud type (middle clouds) */
CODES_CHECK(codes_get_long(h,"cloudType#2",&longVal),0);
printf(" cloudType (middle): %ld\n",longVal);
/* Cloud type (high clouds) */
CODES_CHECK(codes_get_long(h,"cloudType#3",&longVal),0);
printf(" cloudType (high): %ld\n",longVal);
/* delete handle */
codes_handle_delete(h);

View File

@ -24,7 +24,7 @@ rm -f $fTmp | true
REDIRECT=/dev/null
#Write the values into a file and compare with reference
${examples_dir}c_bufr_read_synop 2> $REDIRECT > $fTmp
${examples_dir}c_bufr_read_synop #2> $REDIRECT > $fTmp
#TODO: check the output

View File

@ -14,6 +14,12 @@
* Description: how to read temperature significant levels from TEMP BUFR messages.
*
*/
/*
* Please note that TEMP reports can be encoded in various ways in BUFR. Therefore the code
* below might not work directly for other types of SYNOP messages than the one used in the
* example. It is advised to use bufr_dump to understand the structure of the messages.
*/
#include "eccodes.h"
@ -21,11 +27,9 @@ int main(int argc,char* argv[])
{
FILE* in = NULL;
/* message handle. Required in all the eccodes calls acting on a message.*/
/* Message handle. Required in all the eccodes calls acting on a message.*/
codes_handle* h=NULL;
char* units= NULL;
char* unitsPercent= NULL;
double *sigt_pres=NULL, *sigt_geo=NULL, *sigt_t=NULL;
double *sigt_td=NULL;
long longVal;
@ -42,7 +46,7 @@ int main(int argc,char* argv[])
return 1;
}
/* loop over the messages in the bufr file */
/* Loop over the messages in the bufr file */
while ((h = codes_handle_new_from_file(NULL,in,PRODUCT_BUFR,&err)) != NULL || err != CODES_SUCCESS)
{
if (h == NULL) {
@ -53,23 +57,25 @@ int main(int argc,char* argv[])
printf("message: %d\n",cnt);
/* we need to instruct ecCodes to expand the descriptors
/* We need to instruct ecCodes to expand the descriptors
i.e. unpack the data values */
CODES_CHECK(codes_set_long(h,"unpack",1),0);
/* In what follows we rely on the fact that for
temperature significant levels the value of key
verticalSoundingSignificance is 4 (see flag table 8001 for details).
We also make use of the fact that in our BUFR message
verticalSoundingSignificance is always followed by geopotential,
airTemperature, dewpointTemperature,
windDirection, windSpeed and pressure. */
* temperature significant levels the value of key
* verticalSoundingSignificance is 4 (see flag table 8001 for details).
*
* In our BUFR message verticalSoundingSignificance is always followed by
* geopotential, airTemperature, dewpointTemperature,
* windDirection, windSpeed and pressure.
* So in order to access any of these keys we need to use the
* condition: verticalSoundingSignificance=4.
*
/* Get the number of the temperature significant levels.*/
/* We find out the number of temperature significant levels by
counting how many pressure values we have on these levels. */
* counting how many pressure values we have on these levels.*/
sprintf(key_name,"/verticalSoundingSignificance=4/pressure");
CODES_CHECK(codes_get_size(h,key_name,&sigt_len),0);
@ -77,7 +83,7 @@ int main(int argc,char* argv[])
printf("Number of T significant levels: %ld\n",sigt_len);
/* Allocate memory for the values to be read. Each
parameter must have the same number of values. */
* parameter must have the same number of values. */
sigt_pres = malloc(sigt_len*sizeof(double));
sigt_geo = malloc(sigt_len*sizeof(double));
sigt_t = malloc(sigt_len*sizeof(double));
@ -86,14 +92,14 @@ int main(int argc,char* argv[])
/* Get pressure */
sprintf(key_name,"/verticalSoundingSignificance=4/pressure");
/* get the values */
/* Get the values */
len=sigt_len;
CODES_CHECK(codes_get_double_array(h,key_name,sigt_pres,&len),0);
/* Get geopotential */
sprintf(key_name,"/verticalSoundingSignificance=4/geopotential");
/* check the size*/
/* Check the size*/
CODES_CHECK(codes_get_size(h,key_name,&len),0);
if(len != sigt_len)
{
@ -101,33 +107,33 @@ int main(int argc,char* argv[])
return 1;
}
/* get the values */
/* Get the values */
CODES_CHECK(codes_get_double_array(h,key_name,sigt_geo,&len),0);
/* Get temperature */
sprintf(key_name,"/verticalSoundingSignificance=4/airTemperature");
/* check the size*/
/* Check the size*/
if(len != sigt_len)
{
printf("inconsistent number of temperature values found!\n");
return 1;
}
/* get the values */
/* Get the values */
CODES_CHECK(codes_get_double_array(h,key_name,sigt_t,&len),0);
/* Get dew point */
sprintf(key_name,"/verticalSoundingSignificance=4/dewpointTemperature");
/* check the size*/
/* Check the size*/
if(len != sigt_len)
{
printf("inconsistent number of dewpoint temperature values found!\n");
return 1;
}
/* get the values */
/* Get the values */
CODES_CHECK(codes_get_double_array(h,key_name,sigt_td,&len),0);
/* Print the values */
@ -140,10 +146,10 @@ int main(int argc,char* argv[])
i+1,sigt_pres[i],sigt_geo[i],sigt_t[i],sigt_td[i]);
}
/* delete handle */
/* Delete handle */
codes_handle_delete(h);
/*Release memory*/
/* Release memory */
free(sigt_pres);
free(sigt_geo);
free(sigt_t);

View File

@ -14,8 +14,7 @@
! Please note that SYNOP reports can be encoded in various ways in BUFR. Therefore the code
! below might not work directly for other types of SYNOP messages than the one used in the
! example.
! example. It is advised to bufr_dump to understand the structure of the messages.
!
!
@ -28,6 +27,7 @@ integer :: ibufr
integer :: count=0
integer(kind=4) :: blockNumber,stationNumber
real(kind=8) :: lat,lon,t2m,td2m,ws,wdir
integer(kind=4) :: cloudAmount,cloudBaseHeight,lowCloud,midCloud,highCloud
call codes_open_file(ifile,'../../data/bufr/syno_multi.bufr','r')
@ -74,8 +74,35 @@ real(kind=8) :: lat,lon,t2m,td2m,ws,wdir
write(*,*) ' windSpeedAt10M:',ws
call codes_get(ibufr,'windDirectionAt10M',wdir);
write(*,*) ' windDirectionAt10M',wdir
write(*,*) ' windDirectionAt10M:',wdir
! The cloud information is stored in several blocks in the
! SYNOP message and the same key means a different thing in different
! parts of the message. In this example we will read the first
! cloud block introduced by the key
! verticalSignificanceSurfaceObservations=1.
! We know that this is the first occurrence of the keys we want to
! read so we will use the # (occurrence) operator accordingly.
! Cloud amount (low and middleclouds)
call codes_get(ibufr,'cloudAmount#1',cloudAmount)
write(*,*) ' cloudAmount (low and middle):',cloudAmount
! Height of cloud base
call codes_get(ibufr,'heightOfBaseOfCloud#1',cloudBaseHeight)
write(*,*) ' heightOfBaseOfCloud:',cloudBaseHeight
! Cloud type (low clouds)
call codes_get(ibufr,'cloudType#1',lowCloud)
write(*,*) ' cloudType (low):',lowCloud
! Cloud type (middle clouds)
call codes_get(ibufr,'cloudType#2',midCloud)
write(*,*) ' cloudType (middle):',midCloud
! Cloud type (high clouds)
call codes_get(ibufr,'cloudType#3',highCloud)
write(*,*) ' cloudType (high):',highCloud
! release the bufr message
call codes_release(ibufr)

View File

@ -12,7 +12,10 @@
!
! Description: how to read temperature significant levels from TEMP BUFR messages.
!
!
! Please note that SYNOP reports can be encoded in various ways in BUFR. Therefore the code
! below might not work directly for other types of SYNOP messages than the one used in the
! example. It is advised to bufr_dump to understand the structure of the messages.
program bufr_read_temp
use eccodes
implicit none
@ -42,11 +45,13 @@ character(len=128) :: keyName
! In what follows we rely on the fact that for
! temperature significant levels the value of key
! verticalSoundingSignificance is 4 (see flag table 8001 for details).
! We also make use of the fact that in our BUFR message
! verticalSoundingSignificance is always followed by geopotential,
! airTemperature, dewpointTemperature,
! windDirection, windSpeed and pressure.
!
! In our BUFR message verticalSoundingSignificance is always followed by
! geopotential, airTemperature, dewpointTemperature,
! windDirection, windSpeed and pressure.
!
! So in order to access any of these keys we need to use the
! condition: verticalSoundingSignificance=4.
! ---- Get the number of the temperature significant levels ----

View File

@ -15,7 +15,7 @@
#
# Please note that SYNOP reports can be encoded in various ways in BUFR. Therefore the code
# below might not work directly for other types of SYNOP messages than the one used in the
# example.
# example. It is advised to use bufr_dump to understand the structure of the messages.
#
import traceback
@ -40,9 +40,22 @@ def example():
'airTemperatureAt2M',
'dewpointTemperatureAt2M',
'windSpeedAt10M',
'windDirectionAt10M'
'windDirectionAt10M',
'cloudAmount#1', #cloud amount (low and mid level)
'heightOfBaseOfCloud#1',
'cloudType#1', #cloud type (low clouds)
'cloudType#2', #cloud type (middle clouds)
'cloudType#3' #cloud type (highclouds)
]
# The cloud information is stored in several blocks in the
# SYNOP message and the same key means a different thing in different
# parts of the message. In this example we will read the first
# cloud block introduced by the key
# verticalSignificanceSurfaceObservations=1.
# We know that this is the first occurrence of the keys we want to
# read so in the list above we used the # (occurrence) operator accordingly.
cnt=0
# loop for the messages in the file

View File

@ -12,6 +12,10 @@
# Description: how to read temperature significant levels from TEMP BUFR messages.
#
#
# Please note that TEMP reports can be encoded in various ways in BUFR. Therefore the code
# below might not work directly for other types of SYNOP messages than the one used in the
# example. It is advised to use bufr_dump to understand the structure of the messages.
#
import traceback
import sys

View File

@ -19,6 +19,9 @@ else
mkdir ../data/split
fi
cat ../data/bufr/syno_1.bufr ../data/bufr/goes_87.bufr ../data/bufr/gosat.bufr > ../data/split/multitype.bufr
cat > rules_file <<EOF
write "../data/split/[bufrHeaderCentre:l]_[dataCategory].bufr[editionNumber]";
EOF
@ -26,7 +29,7 @@ EOF
echo ">bufr_filter rules_file ../data/bufr/multitype.bufr"
echo ">ls ../data/split"
./bufr_filter rules_file ../data/bufr/multitype.bufr
./bufr_filter rules_file ../data/split/multitype.bufr
ls ../data/split
echo "\\endverbatim\\n"
@ -233,4 +236,37 @@ echo ">bufr_filter rules_file ../data/bufr/temp_101.bufr"
echo "\\endverbatim\\n"
# Access by condition 2
echo "-# Another example for accessing keys by condition is to read scatterometer data."
echo "File asca_139.bufr contains a single message with 2016 subsets in a compressed form."
echo "In this case each subset has exactly the same structure: they store one location with"
echo "several beams and one backscatter value in each beam. To print the backScatter values for beamIdentifier=2 from all the subsets"
echo "we can simply define the condition like this: \\n"
echo "\\verbatim"
echo "set unpack=1;"
echo "print \"/beamIdentifier=2/backscatter=[/beamIdentifier=2/backscatter]\";"
echo "\\endverbatim\\n"
echo "The result is:"
echo "\\verbatim"
cat > rules_file <<EOF
set unpack=1;
print "/beamIdentifier=2/backscatter=[/beamIdentifier=2/backscatter]";
EOF
echo ">bufr_filter rules_file ../data/bufr/asca_139.bufr"
./bufr_filter rules_file ../data/bufr/asca_139.bufr > tmp_file
head tmp_file
echo " and many more values ......"
echo "\\endverbatim\\n"
rm -f rules_file || true
rm -f tmp_file || true