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