You want to take your existing BUFR message and add the WIGOS station identifiers to it. See here.
Step-by-step guide
Let us assume you have the station identifiers already stored somewhere e.g. in a CSV file.
- First of all get the handles for the input and output messages:
fin
=
open
(inputFileName,
"rb"
)
ibid
=
codes_bufr_new_from_file(fin)
obid
=
codes_bufr_new_from_samples(
"BUFR4")
- Get the
unexpandedDescriptors
of the input message - Ensure the master tables version number >= 28. This is necessary because only in this version have the WMO provided the new sequence
- Now add the special WIGOS sequence (
301150
) at the beginning of your new set of descriptors - Set the new descriptors
- Fill in the values of the new keys for the wigos identifiers e.g.
wigosIdentifierSeries
,wigosIssuerOfIdentifier
,wigosIssueNumber
andwigosLocalIdentifierCharacter
- Call the function:
codes_bufr_copy_data(ibid, obid)
This will copy all the values in the data section that are present in the same position in the data tree and with the same number of values to the output handle
- Write out the output
Here is a sample Python program:
#!/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 Author : Roberto Ribas Garcia ECMWF 09/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}#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()
DISCLAIMER: This software is intended for testing purposes only