In this test case, we add the WIGOS station identifier to a TEMP message. The logic is very similar to the previous synop program. It can also work for any other template for which block/station number are defined.
#!/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
./wigosTemp.py -i synop_multi_subset.bufr -o out_synop_multisubset.bufr -w WIGOS_TEMP_IDENT.csv
Uses BUFR version 4 template and adds the WIGOS Identifier 301150
REQUIRES TablesVersionNumber above 28
Author : Roberto Ribas Garcia ECMWF 12/09/2019
'''
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}#stationNumber".format(i+1)
stationNumber=codes_get(ibid,stationKey)
dfo=dfWigosInfo.query("station=='{0}'".format(stationNumber))
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)
# pack and write to output file
#codes_set(obid,"pack",1)
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()
To run the program
./wigosTemp.py -i temp.bufr -o outTemp.bufr -w WIGOS_TEMP_IDENT.csv
The input file is
The CSV with some fake WIGOS Ids
And the output BUFR with the WIGOS identifiers is
The output BUFR file outTemp.bufr contains the WIGOS identifiers
{
"key" : "wigosIdentifierSeries",
"value" : 0,
"units" : "Numeric"
},
[
{
"key" : "wigosIssuerOfIdentifier",
"value" : 20000,
"units" : "Numeric"
},
[
{
"key" : "wigosIssueNumber",
"value" : 0,
"units" : "Numeric"
},
[
{
"key" : "wigosLocalIdentifierCharacter",
"value" : "01027",
"units" : "CCITT IA5"
},
[
{
"key" : "blockNumber",
"value" : 16,
"units" : "Numeric"
},
[
DISCLAIMER: This software is intended for testing purposes only. Feedback would be appreciated but technical support can only be given if our workload permits.

1 Comment
David Cruz
Hello.
I'm testing this script to add the WIGOS codes to a BUFR file; I tested it with the shared files; however, the output file with the codes added is incomplete in the data section. The original file has 62 records of "timePeriod," and the output file only has 2 records of "timePeriod."
How could I modify the script to generate the entire output file?
Add Comment