Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Description

This example shows: how How to read levels and print radiosonde data from TEMP BUFR messages. If available this version also lists the position information from the WMO list (now OSCAR/Surface) appended to the reports by ECMWF

Source code

Tabs Container
directionhorizontal


Tabs Page
titleFortran 90


Code Block
languagenonetext
titlebufr_read_temptempf.f90linenumbersfalse
! (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: read and print radiosonde data from TEMP BUFR messages.
! If available this version also lists the position information from the WMO list
! (now OSCAR/Surface) appended to the reports by ECMWF
!
! Author: Bruce Ingleby
!
! 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 TEMP messages than the one used in the
! example. It is advised to use bufr_dump first to understand the structure of these messages.
!
program bufr_read_tempf
  use eccodes
  implicit none
  integer            :: ifile
  integer            :: iret
  integer            :: ibufr
  integer            :: i, count = 0
  integer            :: iflag
  integer            :: status_id, status_bl, status_num, status_ht, status_time = 0, status_p
  integer            :: status_airt, status_dewt, status_wdir, status_wsp
  integer            :: status_rsno, status_rssoft, status_balloonwt, statid_missing
  integer(kind=4)    :: sizews
  integer(kind=4)    :: blockNumber, stationNumber
  integer(kind=4)    :: ymd, hms
  logical            :: llstdonly = .True.  ! Set True to list standard levels only
  logical            :: llskip
  real(kind=8)       :: year, month, day, hour, minute, second
  real(kind=8)       :: htg, htp, htec = 0, sondeType, balloonwt
  ! real(kind=8), dimension(:), allocatable :: descriptors
  real(kind=8), dimension(:), allocatable :: lat, lon
  real(kind=8), dimension(:), allocatable :: timeVal, dlatVal, dlonVal, vssVal
  real(kind=8), dimension(:), allocatable :: presVal, zVal, tVal, tdVal, wdirVal, wspVal
  character(len=128) :: statid, dropid
  character(len=16)  :: rsnumber
  character(len=16)  :: rssoftware

  call codes_open_file(ifile, '../../data/bufr/PraticaTemp.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)

  ! loop through all messages in the file
  do while (iret /= CODES_END_OF_FILE)

 .AND. status_time == CODES_SUCCESS)

    !  ! Can check the template used
    ! call codes_get(ibufr,'unexpandedDescriptors',descriptors)
    ! write(0,*) 'Template: ', descriptors
    ! IF (descriptors(1) /= 309056.0) GOTO 999 ! only list descent profiles

    ! we need to instruct ecCodes to expand all the descriptors
    ! i.e. unpack the data values
    call codes_set(ibufr, "unpack", 1); 
    ! In our BUFR message verticalSoundingSignificance is always followed by
    !      geopotential, airTemperature, dewpointTemperature,
    !      windDirection, windSpeed and pressure.

    count = count + 1
    llskip = .False.

    ! Metadata:
    call codes_get(ibufr, 'aircraftRegistrationNumberOrOtherIdentification', dropid, status_id)
    IF (status_id /= CODES_SUCCESS) dropid = "UNKNOWN "
    call codes_get(ibufr, 'shipOrMobileLandStationIdentifier', statid, status_id)
    IF (status_id /= CODES_SUCCESS) statid = "UNKNOWN"dropid
    ! call codes_is_missing(ibufr, 'shipOrMobileLandStationIdentifier', statid_missing)
    ! IF (statid_missing == 1) statid = "MISSING"
    blockNumber = 9999
    call codes_get(ibufr, 'blockNumber', blockNumber, status_bl)
    call codes_get(ibufr, 'stationNumber', stationNumber, status_num)
    IF (blockNumber <= 99.0 .AND. stationNumber <= 1000) write (statid, '(I2.2,I3.3,3X)') blockNumber, stationNumber

    call codes_get(ibufr, 'year', year)
    call codes_get(ibufr, 'month', month)
    call codes_get(ibufr, 'day', day)
    call codes_get(ibufr, 'hour', hour)
    call codes_get(ibufr, 'minute', minute)
    call codes_get(ibufr, 'second', second, status_time)
    IF (status_time /= CODES_SUCCESS) second = 0.0
    call codes_get(ibufr, 'latitude', lat)
    call codes_get(ibufr, 'longitude', lon)
    call codes_get(ibufr, 'heightOfStationGroundAboveMeanSeaLevel', htg, status_ht)
    IF (status_ht /= CODES_SUCCESS) htg = -999.0
    call codes_get(ibufr, 'heightOfBarometerAboveMeanSeaLevel', htp, status_ht)
    IF (status_ht /= CODES_SUCCESS) htp = -999.0
    call codes_get(ibufr, 'radiosondeType', sondeType)
    call codes_get(ibufr, 'heightOfStation', htec, status_ht) ! Height from WMO list (BUFR)
    IF (status_ht == CODES_SUCCESS .AND. htg == -999.0) htg = htec
    ymd = INT(year)*10000 + INT(month)*100 + INT(day)
    hms = INT(hour)*10000 + INT(minute)*100 + INT(second)
    call codes_get(ibufr, 'radiosondeSerialNumber', rsnumber, status_rsno)
    call codes_get(ibufr, 'softwareVersionNumber', rssoftware, status_rssoft)
    call codes_get(ibufr, 'weightOfBalloon', balloonwt, status_balloonwt)
    IF (status_balloonwt /= CODES_SUCCESS) balloonwt = 0.0

    ! Ascent (skip reports without incompletedtime reportsarray for now)
    call codes_get(ibufr, 'timePeriod', timeVal, status_time)
    IF (status_time /= CODES_SUCCESS) THEN
      write (*, '(A,I7,A,A8,I9,I7.6,F9.3,F10.3,2F7.1,I4)') 'Ob: ', count, &
        ' ', statid, ymd, hms, lat(1), lon(1), htg, htp, INT(sondeType)
      write (*, '(A)') 'Missing times - skip'
      llskip = .True.
    END IF
    call codes_get(ibufr, 'pressure', presVal, status_p)
    IFcall codes_get(status_p /= CODES_SUCCESSibufr, 'nonCoordinateGeopotentialHeight', zVal, status_ht)

    IF (.NOT. llskip) THEN
      writecall codes_get(*ibufr, '(A,I7,A,A8,I9,I7.6,F9.3,F10.3,2F7.1,I4)') 'Ob: ', count, &latitudeDisplacement', dlatVal)
      call codes_get(ibufr, ' longitudeDisplacement', dlonVal)
 statid, ymd, hms, lat(1), lon(1), htg, htp, INT(sondeType   call codes_get(ibufr, 'extendedVerticalSoundingSignificance', vssVal)
      writecall codes_get(*ibufr, '(A)airTemperature'), 'Missing pressures - skip'
tVal, status_airt)
      call  llskip = .True.codes_get(ibufr, 'dewpointTemperature', tdVal, status_dewt)
    END IF
    call codes_get(ibufr, 'nonCoordinateGeopotentialHeightwindDirection', zValwdirVal, status_htwdir)
    IF (status_ht /= CODES_SUCCESS) THEN
      write (*, '(A,I7,A,A8,I9,I7.6,F9.3,F10.3,2F7.1,I4)') 'Ob: ', count, & call codes_get(ibufr, 'windSpeed', wspVal, status_wsp)

      ! ---- Array 'sizes ', statid, ymd, hms, lat(1), lon(1), htg, htp, INT(sondeType(pressure size can be larger - wind shear levels)
      writesizews (*,= 'size(A)') 'Missing heights - skip'
      llskip = .True.
wspVal)

      IF (status_p /= CODES_SUCCESS) THEN
       END IF allocate(presVal(sizews))
    !   IF presVal(blockNumber:) /= 17 .OR. stationNumber /= 196) llskip=.True.  ! FIX-999999999.0
      END IF
    !  IF (blockNumberstatus_ht /= 17.0) llskip=.True.  ! FIX

CODES_SUCCESS) THEN
        IF (.NOT. llskip) THEN
allocate(zVal(sizews))
       call codes_get(ibufr, 'latitudeDisplacement', dlatVal)zVal(:) = -999999999.0
      call codes_get(ibufr, 'longitudeDisplacement', dlonVal)END IF
      callIF codes_get(ibufr, 'extendedVerticalSoundingSignificance', vssVal)(status_airt /= CODES_SUCCESS) THEN
      call  codes_get(ibufr, 'airTemperature', tVal)
allocate(tVal(sizews))
       call codes_get(ibufr, 'dewpointTemperature', tdVal)tVal(:) = -999999999.0
      call codes_get(ibufr, 'windDirection', wdirVal)END IF
      callIF codes_get(ibufr, 'windSpeed', wspVal)

(status_dewt /= CODES_SUCCESS) THEN
      ! ---- Array sizes (pressure size can be larger - wind shear levels) allocate(tdVal(sizews))
        tdVal(:) = -999999999.0
      sizews = size(wspVal)

END IF
      ! ---- Print the values --------------------------------
IF (status_wdir /= CODES_SUCCESS) THEN
       write allocate(*, '(A,I7,A,A8,I9,I7.6,F9.3,F10.3,2F7.1,I4,I5)') 'Ob: ', count, &
wdirVal(sizews))
        wdirVal(:)    ' ', statid, ymd, hms, lat(1), lon(1), htg, htp, INT(sondeType), sizews= -999999999.0
      END IF
      IF (status_rsnowsp =/= CODES_SUCCESS) write (*, '(A,A,A,F7.3)') &THEN
        allocate(wspVal(sizews))
        'RS number/software/balloonwt: ', rsnumber, rssoftware, balloonwt
wspVal(:) = -999999999.0
      END IF

  IF (status_ht == CODES_SUCCESS .AND. SIZE(lat) > 1)    ! ---- Print the values --------------------------------
      write (*, '(A,I7,A,A8,I9,I7.6,F9.3,F10.3,F72F7.1,I4,I5)') 'Ob: ', count, &
        'WMO list', latstatid, lonymd, ht: 'hms, lat(21), lon(2(1), htg, htp, INT(sondeType), htecsizews
      IF (status_rsno == CODES_SUCCESS) write (*, '(A,A,A,F7.3)') 'level&
  dtime   dlat   dlon pressure geopotH airTemp  dewPtT windDir  windSp  signif'
      do i = 1, sizews
        iflag = vssVal(i)
        IF (.NOT. llstdonly .OR. BTEST(iflag, 16)'RS number/software/balloonwt: ', rsnumber, rssoftware, balloonwt
      IF (status_ht == CODES_SUCCESS .AND. SIZE(lat) > 1) write (*, '(A,A10,F9.3,F10.3,F7.1)') &
        'WMO list writelat, (*lon, ht: '(I5,F7.1,2F7.3,F9.1,F8.1,4F8.2,I8)') i, timeVal(i), &, statid, lat(2), lon(2), htec
      write    dlatVal(i)(*, dlonVal'(i), presVal(i), zVal(i), tVal(i), tdVal(i), &
          wdirVal(i), wspVal(i), INT(vssVal(i))A)') 'level  dtime   dlat   dlon pressure geopotH airTemp  dewPtT windDir  windSp  signif'
      end do

 i = 1, END IFsizews
    ! free allocated arrays
 iflag =  IF (ALLOCATED(timeVal)) deallocate (timeVal)
vssVal(i)
      IF (ALLOCATED(dlatVal)) deallocate (dlatVal)
    IF (ALLOCATED(dlonVal)) deallocate (dlonVal) IF (.NOT. llstdonly .OR. BTEST(iflag, 16)) &
    IF (ALLOCATED(vssVal)) deallocate (vssVal)
   write IF(*, (ALLOCATED(presVal)) deallocate (presVal)'(I5,F7.1,2F7.3,F9.1,F8.1,4F8.2,I8)') i, timeVal(i), &
    IF (ALLOCATED(zVal)) deallocate (zVal)
    IFdlatVal(i), dlonVal(ALLOCATED(tVal)) deallocate (tVal)
    IF (ALLOCATED(tdVal)) deallocate (tdVal)i), presVal(i), zVal(i), tVal(i), tdVal(i), &
          wdirVal(i), wspVal(i), INT(vssVal(i))
      end do

    END IF
    ! free allocated arrays
    IF (ALLOCATED(wdirValtimeVal)) deallocate (wdirValtimeVal)
    IF (ALLOCATED(wspValdlatVal)) deallocate (wspValdlatVal)
    IF (ALLOCATED(latdlonVal)) deallocate (latdlonVal)
    IF (ALLOCATED(lonvssVal)) deallocate (lonvssVal)

     ! 999 CONTINUEIF (ALLOCATED(presVal)) deallocate (presVal)
    ! release the BUFR messageIF (ALLOCATED(zVal)) deallocate (zVal)
    call codes_release(ibufr)

    ! load the next BUFR messageIF (ALLOCATED(tVal)) deallocate (tVal)
    IF (ALLOCATED(tdVal)) deallocate (tdVal)
    call codes_bufr_new_from_file(ifile, ibufr, iret)

  end do

  call codes_close_file(ifile)

end program bufr_read_tempf
IF (ALLOCATED(wdirVal)) deallocate (wdirVal)
    IF (ALLOCATED(wspVal)) deallocate (wspVal)
    IF (ALLOCATED(lat)) deallocate (lat)
    IF (ALLOCATED(lon)) deallocate (lon)

    ! release the BUFR message
    call codes_release(ibufr)

    ! load the next BUFR message
    call codes_bufr_new_from_file(ifile, ibufr, iret)

  end do

  call codes_close_file(ifile)
  print*, 'Finishing normally. Number of BUFR records read: ', count

end program bufr_read_tempf



Tabs Page
titleC


Code Block
languagecpp
titlebufr_read_tempf.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_read_tempf
 *
 * Description: read and print radiosonde data from TEMP BUFR messages.
 * If available this version also lists the position information from the WMO list
 * (now OSCAR/Surface) appended to the reports by ECMWF
 * 
 * Author: Bruce Ingleby
 */

/*
 * 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 TEMP 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"

/* Returns 1 if the bit at 'pos' in 'var' is set. The counting starts at 0 */
#define BTEST(var, pos) ((var) & (1 << (pos)))

/* Helper function to fill a double array with values of 'key'. Client must free memory */
static int get_double_array(codes_handle* h, const char* key, double** arr, size_t* size)
{
    CODES_CHECK(codes_get_size(h, key, size), 0);
    *arr = (double*)malloc(*size * sizeof(double));
    return codes_get_double_array(h, key, *arr, size);
}

/* Helper function to fill an integer (=long) array with values of 'key'. Client must free memory */
static int get_long_array(codes_handle* h, const char* key, long** arr, size_t* size)
{
    CODES_CHECK(codes_get_size(h, key, size), 0);
    *arr = (long*)malloc(*size * sizeof(long));
    return codes_get_long_array(h, key, *arr, size);
}

/* Reset dimension of input array to 'newsize' and fill with 'fillValue' */
static void realloc_and_fill(double** arr, size_t newsize, double fillValue)
{
    size_t i;
    free(*arr);
    *arr = (double*)malloc(newsize * sizeof(double));
    for(i=0; i<newsize; ++i) *arr[i] = fillValue;
}

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, *presVal = NULL, *zVal = NULL;
    double *dlatVal = NULL, *dlonVal = NULL;
    double *tVal = NULL, *tdVal = NULL, *wspVal = NULL, *wdirVal = NULL;
    double htg, htp, htec = 0, balloonwt;
    int err         = 0;
    int status_rsno = 0, status_ht = 0, status_airt = 0, status_dewt = 0, status_p = 0;
    int count     = 0;
    int llskip    = 0;
    int llstdonly = 1; /* Set True to list standard levels only */
    size_t i = 0, size = 0, sizews = 0, sizelats = 0;
    long blockNumber, stationNumber;
    long year, month, day, hour, minute, second, ymd, hms, sondeType;
    long *timeVal = NULL, *vssVal = NULL;
    const char* infile = "../../data/bufr/PraticaTemp.bufr";
    char statid[128]   = {0,};
    char dropid[128]   = {0,};
    char rsnumber[16] = {0,};
    char rssoftware[16] = {0,};

    in = fopen(infile, "rb");
    if (!in) {
        fprintf(stderr, "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) {
        count++;
        if (h == NULL) {
            fprintf(stderr, "Error: unable to create handle for message %d\n", count);
            continue;
        }

        /* 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 our BUFR message verticalSoundingSignificance is always followed by
         *    geopotential, airTemperature, dewpointTemperature,
         *    windDirection, windSpeed and pressure */
        llskip = 0;

        size = 1024;
        err  = codes_get_string(h, "aircraftRegistrationNumberOrOtherIdentification", dropid, &size);
        if (err) strcpy(dropid, "UNKNOWN");
        size = 1024;
        err  = codes_get_string(h, "shipOrMobileLandStationIdentifier", statid, &size);
        if (err) strcpy(statid, dropid);

        CODES_CHECK(codes_get_long(h, "blockNumber", &blockNumber), 0);
        CODES_CHECK(codes_get_long(h, "stationNumber", &stationNumber), 0);
        if (blockNumber < 99 && stationNumber < 1000)
            sprintf(statid, "%ld%ld", blockNumber, stationNumber);
        CODES_CHECK(codes_get_long(h, "year", &year), 0);
        CODES_CHECK(codes_get_long(h, "month", &month), 0);
        CODES_CHECK(codes_get_long(h, "day", &day), 0);
        CODES_CHECK(codes_get_long(h, "hour", &hour), 0);
        CODES_CHECK(codes_get_long(h, "minute", &minute), 0);
        err = codes_get_long(h, "second", &second);
        if (err) second = 0;

        err = get_double_array(h, "latitude", &lat, &sizelats);

        err = get_double_array(h, "longitude", &lon, &size);

        status_ht = codes_get_double(h, "heightOfStationGroundAboveMeanSeaLevel", &htg);
        if (status_ht) htg = -999.0;
        status_ht = codes_get_double(h, "heightOfBarometerAboveMeanSeaLevel", &htp);
        if (status_ht) htp = -999.0;

        CODES_CHECK(codes_get_long(h, "radiosondeType", &sondeType), 0);
        err = codes_get_double(h, "heightOfStation", &htec); /* Height from WMO list (BUFR) */
        if (!err && htg == -999.0) htg = htec;

        ymd = year * 10000 + month * 100 + day;
        hms = hour * 10000 + minute * 100 + second;

        size        = 16;
        status_rsno = codes_get_string(h, "radiosondeSerialNumber", rsnumber, &size);
        size        = 16;
        codes_get_string(h, "softwareVersionNumber", rssoftware, &size);

        err = codes_get_double(h, "weightOfBalloon", &balloonwt);
        if (err) balloonwt = 0;

        /* Ascent (skip reports without dtime array for now) */
        err     = get_long_array(h, "timePeriod", &timeVal, &size);
        if (err) {
            printf("Ob: %d %s %ld %ld %g %g %g %g %ld\n",
                   count, statid, ymd, hms, lat[0], lon[0], htg, htp, sondeType);
            printf("Missing times - skip\n");
            llskip = 1;
        }
        status_p = get_double_array(h, "pressure", &presVal, &size);
        status_ht = get_double_array(h, "nonCoordinateGeopotentialHeight", &zVal, &size);

        if (!llskip) {
            err = get_double_array(h, "latitudeDisplacement", &dlatVal, &size);
            err = get_double_array(h, "longitudeDisplacement", &dlonVal, &size);
            err = get_long_array(h, "extendedVerticalSoundingSignificance", &vssVal, &size);
            status_airt = get_double_array(h, "airTemperature", &tVal, &size);
            status_dewt = get_double_array(h, "dewpointTemperature", &tdVal, &size);
            err = get_double_array(h, "windDirection", &wdirVal, &size);
            err = get_double_array(h, "windSpeed", &wspVal, &sizews);

            if (status_p != CODES_SUCCESS) {
                realloc_and_fill(&presVal, sizews, -999999999.0);
            }
            if (status_ht != CODES_SUCCESS) {
                realloc_and_fill(&zVal, sizews, -999999999.0);
            }
            if (status_airt != CODES_SUCCESS) {
                realloc_and_fill(&tVal, sizews, -999999999.0);
            }
            if (status_dewt != CODES_SUCCESS) {
                realloc_and_fill(&tdVal, sizews, -999999999.0);
            }
            /* Print the values */
            printf("Ob: %7d %s %ld %ld %7.3f %7.3f %7.1f %7.1f %4ld %5lu\n",
                   count, statid, ymd, hms, lat[0], lon[0], htg, htp, sondeType, sizews);
            if (status_rsno == CODES_SUCCESS) {
                printf("RS number/software/balloonwt: %s %s %7.3f\n", rsnumber, rssoftware, balloonwt);
            }
            if (status_ht == CODES_SUCCESS && sizelats > 1) {
                printf("WMO list lat, lon, ht: %s %g %g %g\n", statid, lat[1], lon[1], htec);
            }
            printf("level  dtime    dlat   dlon   pressure  geopotH  airTemp   dewPtT  windDir   windSp   signif\n");
            for (i = 0; i < sizews; ++i) {
                long iflag = vssVal[i];
                if (!llstdonly || BTEST(iflag, 16)) {
                    printf("%5lu %6ld %7.3f %7.3f %9.1f %8.1f %8.2f %8.2f %8.2f %8.2f %8ld\n",
                           i + 1, timeVal[i],
                           dlatVal[i], dlonVal[i],
                           presVal[i], zVal[i], tVal[i], tdVal[i],
                           wdirVal[i], wspVal[i], vssVal[i]);
                }
            }
        }

        /* Release memory */
        free(lat);
        free(lon);
        free(timeVal);
        free(dlatVal);
        free(dlonVal);
        free(presVal);
        free(zVal);
        free(tVal);
        free(tdVal);
        free(wdirVal);
        free(wspVal);
        free(vssVal);
        codes_handle_delete(h);
    }

    fclose(in);
    printf("Finishing normally. Number of BUFR records read: %d\n", count);
    return 0;
}




Tabs Page
titlePython


Code Block
languagepy
titlebufr_read_tempf.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_read_tempf
#
#
# Description: read and print radiosonde data from TEMP BUFR messages.
# If available this version also lists the position information from the WMO list
# (now OSCAR/Surface) appended to the reports by ECMWF
#
# Author: Bruce Ingleby
#
# 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 TEMP
# messages than the one used in the example. It is advised to use bufr_dump to
# understand the structure of the messages.
#

import sys
import traceback

import numpy as np

from eccodes import *

INPUT = "../../data/bufr/PraticaTemp.bufr"
VERBOSE = 1  # verbose error reporting


def example():
    # open BUFR file
    f = open(INPUT, "rb")
    llstdonly = 1  # If 1 then list standard levels only, 0 list all levels
    cnt = 0
    # loop over the messages in the file
    while 1:
        # get handle for message
        bufr = codes_bufr_new_from_file(f)
        if bufr is None:
            break
        cnt += 1

        # desc = codes_get_array(bufr, 'unexpandedDescriptors')
        # if all(desc != 309056):    # descent reports
        #     codes_release(bufr)
        #     continue   # Skip other templates

        # we need to instruct ecCodes to expand all the descriptors
        # i.e. unpack the data section
        codes_set(bufr, "unpack", 1)
        # get header information from the message
        try:
            dropid = codes_get(bufr, "aircraftRegistrationNumberOrOtherIdentification")
        except Exception:
            dropid = "UNKNOWN "
        try:
            shipid = codes_get(bufr, "shipOrMobileLandStationIdentifier")
        except Exception:
            shipid = "UNKNOWN "

        statid = "00000   "
        try:
            block = codes_get(bufr, "blockNumber"
Tabs Page
titlePython
Code Block
languagepython
titlebufr_read_temp.py
linenumbersfalse
#
# 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_read_tempf
#
#
# Description: read and print radiosonde data from TEMP BUFR messages.
# If available this version also lists the position information from the WMO list
# (now OSCAR/Surface) appended to the reports by ECMWF
#
# Author: Bruce Ingleby
#
# 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 TEMP
# messages than the one used in the example. It is advised to use bufr_dump to
# understand the structure of the messages.
#
from __future__ import print_function
import traceback
import sys
import numpy as np
from eccodes import *

INPUT = "../../data/bufr/PraticaTemp.bufr"
VERBOSE = 1  # verbose error reporting


def example():
    # open BUFR file
    f = open(INPUT, "rb")
    llstdonly = 1
    cnt = 0
    # loop over the messages in the file
    while 1:
        # get handle for message
        bufr = codes_bufr_new_from_file(f)
        if bufr is None:
            break
        cnt += 1

        # desc = codes_get_array(bufr, 'unexpandedDescriptors')
        # if all(desc != 309056):    # descent reports
        #     codes_release(bufr)
        #    stnum continue   # Skip other templates

= codes_get(bufr, "stationNumber")
        # we need to instructif ecCodes(block to> expand0) alland the(block descriptors
    < 100):    # i.e. unpack the data sectionor block != CODES_MISSING_LONG
        codes_set(bufr, "unpack", 1)
      statid  # get header information from the message= str.format("%.2i%.3i   " % (block, stnum))
        tryexcept Exception:
            sidstatid = codes_get(bufr, "aircraftRegistrationNumberOrOtherIdentification")
"00000   "
        if  except Exceptionstatid == "00000   ":
            sidstatid = "UNKNOWN"

shipid[0:8]
        if statid == "UNKNOWN "00000:
      "
      statid = try:dropid[0:8]

        #    blocksubtype = codes_get(bufr, "blockNumber"'rdbSubtype')
            stnumsondetype = codes_get(bufr, "stationNumberradiosondeType")
            if (block > 0) and (block < 100):  # or block !sondetype == CODES_MISSING_LONG:
              sondetype  statid = str.format("%.2i%.3i   " % (block, stnum))= 0
        except Exception:
    slat = codes_get_array(bufr, "latitude")
        statidslon = "00000   "codes_get_array(bufr, "longitude")
        if statid == "00000   ":slat = np.where(slat != CODES_MISSING_DOUBLE, slat, np.nan)
        slon = np.where(slon  statid = sid[0:8]

!= CODES_MISSING_DOUBLE, slon, np.nan)
        # subtype = codes_get(bufr,'rdbSubtype')try:
        sondetype    htg = codes_get(bufr, "radiosondeTypeheightOfStationGroundAboveMeanSeaLevel")
           slat if htg == codesCODES_get_array(bufr, "latitude")
MISSING_DOUBLE:
                slonhtg = codes_get_array(bufr, "longitude")
np.nan
        except tryException:
            htg = codes_get(bufr, "heightOfStationGroundAboveMeanSeaLevel")np.nan
        try:
        except Exception:
     htp = codes_get(bufr, "heightOfBarometerAboveMeanSeaLevel")
            if htghtp == -999.0
  CODES_MISSING_DOUBLE:
      try:
            htp = codes_get(bufr, "heightOfBarometerAboveMeanSeaLevel")np.nan
        except Exception:
            htp = -999np.0nan
        year = codes_get(bufr, "year")
        month = codes_get(bufr, "month")
        day = codes_get(bufr, "day")
        hour = codes_get(bufr, "hour")
        minute = codes_get(bufr, "minute")
        try:
            second = codes_get(bufr, "second")
            if second == CODES_MISSING_LONG:
    try:
            second = codes_get(bufr, "second")0
        except Exception:
            second = 0.0
        date = str.format("%i%.2i%.2i" % (year, month, day))
        time = str.format("%.2i%.2i%.2i" % (hour, minute, second))
        try:
            windsp = codes_get_array(bufr, "windSpeed")
        except Exception:
            codes_release(bufr)
            continue
        print(
            "Ob: %7i %s%8s %s %s %7.3f %8.3f %6.1f %6.1f %3i %4i"
            % (
                cnt,
                statid,
                date,
                time,
                slat[0],
                slon[0],
                htg,
                htp,
                sondetype,
                len(windsp),
            )
        )

        try:
            rsnumber = codes_get(bufr, "radiosondeSerialNumber")
            rssoftware = codes_get(bufr, "softwareVersionNumber")
            balloonwt = codes_get(bufr, "weightOfBalloon")
            print("RS number/software/balloonwt ", rsnumber, rssoftware, balloonwt)
        except Exception:
            rsnumber = 0
        try:
            htec = codes_get(
                bufr, "heightOfStation"
, "heightOfStation"
            )  # Height from WMO list (appended by ECMWF)
            if htec == CODES_MISSING_LONG:
                htec = np.nan
     )  # Height from WMO list print(appended
   by ECMWF)
            print("WMO list lat, lon, ht: %s %7.3f %8.3f %6.1f"
                % (statid, slat[1], slon[1], htec)
            )
        except Exception:
            htec = 0np.nan

        # get all the timePeriods
        dtime = codes_get_array(bufr, "timePeriod")
        try:
            pressure = codes_get_array(bufr, "pressure")
        except Exception:
            codes_release(bufr)
            continue
        vsSignif = codes_get_array(bufr, "extendedVerticalSoundingSignificance")
        try:
            geopoth = codes_get_array(bufr, "nonCoordinateGeopotentialHeight")
        except Exception:
            codes_release(bufr)
            continue
        dlat = codes_get_array(bufr, "latitudeDisplacement")
        dlon = codes_get_array(bufr, "longitudeDisplacement")
        airt = codes_get_array(bufr, "airTemperature")
        dewt = codes_get_array(bufr, "dewpointTemperature")
        windd = codes_get_array(bufr, "windDirection")
        dtime = np.where(dtime != CODES_MISSING_LONG, dtime, np.nan)
        dlat = np.where(dlat != CODES_MISSING_DOUBLE, dlat, np.nan)
        dlon = np.where(dlon != CODES_MISSING_DOUBLE, dlon, np.nan)
        airt = np.where(airt != CODES_MISSING_DOUBLE, airt, np.nan)
        dewt = np.where(dewt != CODES_MISSING_DOUBLE, dewt, np.nan)
        windd = np.where(windd != CODES_MISSING_LONG, windd, np.nan)
        windsp = np.where(windsp != CODES_MISSING_DOUBLE, windsp, np.nan)
        geopoth = np.where(geopoth != CODES_MISSING_DOUBLELONG, geopoth, np.nan)
        pressure = np.where(pressure != CODES_MISSING_DOUBLE, pressure, np.nan)
        # pressure = np.where(pressure > -1e10, pressure, np.nan)
        print(
            "level  dtime   dlat   dlon pressure geopotH airTemp  dewPtT windDir  windSp  signif"
        )
        for i in range(0, len(windsp)):
            if (not llstdonly) orand vsSignif[i] != 65536:
                continue
            print(
                "%5i %6.1f %6.3f %6.3f %8.1f %7.1f %7.2f %7.2f %7.2f %7.2f %7i"
                % (
                    i + 1,
                    dtime[i],
                    dlat[i],
                    dlon[i],
                    pressure[i],
                    geopoth[i],
                    airt[i],
                    dewt[i],
                    windd[i],
                    windsp[i],
                    vsSignif[i],
                )
            )
        # delete handle
        codes_release(bufr)
    # close the file
    f.close()
    print("Finishing normally. Number of BUFR records read: ", cnt)


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())




...