Versions Compared

Key

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

...

Expand


Code Block
languagepy
titlewigosMultisubset.py
#!/usr/bin/env python
from eccodes import *
import argparse
import pandas as pd

'''
# Copyright 2005-2018 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

This is a test program to encode Wigos Synop. Requires:

1) ecCodes version 2.8 or above (available at https://confluence.ecmwf.int/display/ECC/Releases)
2) python2.7

To run the program:
   ./wigosMultisubset.py  -i synop_multi_subset.bufr -o out_synop_multisubset.bufr  -w WIGOS_IDENTIFIERS.csv

Uses BUFR version 4 template  and adds the WIGOS Identifier 301150
REQUIRES TablesVersionNumber above 28
'''

def read_cmdline():
    '''
    Reads the command line to get the input ascii filename and the output bufr file
    Usage:
          prog  -i <input_bufr_file> -o <output_bufr_file> -w <wigos_csv_info>
    '''
    p = argparse.ArgumentParser()
    p.add_argument('-i', '--input', help = 'input BUFR filename')
    p.add_argument('-o', '--output', help = 'output BUFR filename')
    p.add_argument("-w", "--wigoscodes",help="csv with the station codes")
    args = p.parse_args()
    return args


def read_wigosInfo(wigosCSVFile):
    '''
    dtype={"wigosLocalIdentifierCharacter":object} forces the column to be string compatible
    with the wigosLocalIdentifierCharacter key in bufr. This column in the  CSV must be created as a TEXT
    '''
    df=pd.read_csv(wigosCSVFile,sep=",",dtype={"wigosLocalIdentifierCharacter":object})
    return df

def main():
    '''
    reads the arguments from the command line
     -i  input bufr file
     -o  output bufr file
    -w   wigos information ( csv containing the station Name and wigos information ( wigosLocalIdentifierCharacter etc)
    '''
    args=read_cmdline()
    inputFileName=args.input
    outputFilename=args.output
    wigosFile=args.wigoscodes
    '''
    reads the wigos information into a pandas dataframe that is queried
    for each station to retrieve the station's wigos information
    '''
    dfWigosInfo=read_wigosInfo(wigosFile)
     
    fin=open(inputFileName,"rb")
    ibid=codes_bufr_new_from_file(fin)
     
    codes_set(ibid,"unpack",1)
    inUE=codes_get_array(ibid,"unexpandedDescriptors")
    nsubsets=codes_get(ibid,"numberOfSubsets")
     
    masterTablesVN=codes_get(ibid,"masterTablesVersionNumber")
    # change the masterTablesVersionNumber if is below 29 ( otherwise the WIGOS sequence is not present)
    if masterTablesVN<28:
        masterTablesVN=28
    outUE=inUE.tolist()
    # update the unexpandedDescriptors ( BUFR sequence) to add the WIGOS data
    outUE.insert(0,301150)
    fout=open(outputFilename,"wb")
    obid=codes_bufr_new_from_samples("BUFR4")
    ### important, use master tables version number above 28 as they contain WIGOS keys
    # otherwise it won't work
    codes_set(obid, 'masterTablesVersionNumber', masterTablesVN)
    # set the unexpandedDescriptors of the output file with the new sequence 301150 (WIGOS) + synop sequence
    #from Input message
    # IMPORTANT, read the number of subsets
    codes_set(obid,"numberOfSubsets",nsubsets)
    codes_set_array(obid,"unexpandedDescriptors",outUE)
    # here wigos information is added, the stationName is used
    # to query the dfWigosInfo dataframe and retrieve the station Wigos information (wigosLocalIdentifierCharacter etc)
    for i in range(0,nsubsets):
        stationKey="#{0}#stationOrSiteName".format(i+1)
        stationName=codes_get(ibid,stationKey)
        dfo=dfWigosInfo.query("station=='{0}'".format(stationName))
        key="#{0}#wigosIdentifierSeries".format(i+1)
        codes_set(obid, key,int(dfo["wigosIdentifierSeries"].values[0]) )
        key="#{0}#wigosIssuerOfIdentifier".format(i+1)
        codes_set(obid, key, int(dfo["wigosIssuerOfIdentifier"].values[0]))
        key="#{0}#wigosIssueNumber".format(i+1)
        value=dfo["wigosIssueNumber"].values[0]
        codes_set(obid, key, value)
        key="#{0}#wigosLocalIdentifierCharacter".format(i+1)
        value=dfo["wigosLocalIdentifierCharacter"].values[0]
        codes_set(obid,key,str(value))

    # copies the data from the input message ( ibid) to the output message obid
    codes_bufr_copy_data(ibid,obid)
    # write to output file ( packing is not needed here as copy_data does it implicitly)
    codes_write(obid,fout)
    # release the obid and ibid bufr handles
    codes_release(obid)
    codes_release(ibid)
    fout.close()
    fin.close()
     
if __name__=="__main__":
    main()


Warning

DISCLAIMER: This example script is intended for illustrative purposes only. It has not been thoroughly tested under all conditions.


...