source: flex_extract.git/Source/Python/Classes/GribUtil.py @ 8463d78

ctbtodev
Last change on this file since 8463d78 was 8463d78, checked in by Anne Philipp <anne.philipp@…>, 5 years ago

made python3 again, now working

  • Property mode set to 100644
File size: 10.6 KB
RevLine 
[8463d78]1#!/usr/bin/env python3
[64cf353]2# -*- coding: utf-8 -*-
[991df6a]3#*******************************************************************************
4# @Author: Anne Fouilloux (University of Oslo)
5#
6# @Date: July 2014
7#
8# @Change History:
9#   February 2018 - Anne Philipp (University of Vienna):
10#        - applied PEP8 style guide
11#        - added documentation
12#        - changed some naming
13#
14# @License:
15#    (C) Copyright 2014-2018.
16#
17#    This software is licensed under the terms of the Apache Licence Version 2.0
18#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
19#
20# @Class Description:
21#    The GRIB API provides all necessary tools to work directly with the
22#    grib files. Nevertheless, the GRIB API tools are very basic and are in
23#    direct connection with the grib files. This class provides some higher
24#    functions which apply a set of GRIB API tools together in the respective
25#    context. So, the class initially contains a list of grib files (their
26#    names) and the using program then applies the methods directly on the
27#    class objects without having to think about how the actual GRIB API
28#    tools have to be arranged.
29#
30# @Class Content:
31#    - __init__
[ff99eae]32#    - get_keys
33#    - set_keys
[268ee86]34#    - copy_dummy_msg
[991df6a]35#    - index
36#
[ff99eae]37# @Class Attributes:
38#    - filenames
39#
[991df6a]40#*******************************************************************************
[64cf353]41
42# ------------------------------------------------------------------------------
43# MODULES
44# ------------------------------------------------------------------------------
[4ef5ba9]45from __future__ import print_function
[aa275fc]46
[4ef5ba9]47import os
[991df6a]48
[64cf353]49# ------------------------------------------------------------------------------
50# CLASS
51# ------------------------------------------------------------------------------
[268ee86]52class GribUtil(object):
[64cf353]53    '''
54    Class for GRIB utilities (new methods) based on GRIB API
55    '''
56    # --------------------------------------------------------------------------
[efdb01a]57    # CLASS FUNCTIONS
[64cf353]58    # --------------------------------------------------------------------------
59    def __init__(self, filenames):
[268ee86]60        '''Initialise an object of GribUtil and assign a list of filenames.
[274f9ef]61
62        Parameters
63        ----------
64        filenames : :obj:`list` of :obj:`strings`
65             A list of filenames.
[64cf353]66
[274f9ef]67        Return
68        ------
[64cf353]69
70        '''
71
[ff99eae]72        self.filenames = filenames
[64cf353]73
74        return
75
76
[ff99eae]77    def get_keys(self, keynames, wherekeynames=[], wherekeyvalues=[]):
[274f9ef]78        '''Get keyvalues for a given list of keynames a where statement
79        can be given (list of key and list of values)
[64cf353]80
[274f9ef]81        Parameters
82        ----------
83        keynames : :obj:`list` of :obj:`string`
84            List of keynames.
[64cf353]85
[274f9ef]86        wherekeynames : :obj:`list` of :obj:`string`, optional
87            Default value is an empty list.
[64cf353]88
[274f9ef]89        wherekeyvalues : :obj:`list` of :obj:`string`, optional
90            Default value is an empty list.
[64cf353]91
[274f9ef]92        Return
93        ------
94        return_list : :obj:`list` of :obj:`string`
95            List of keyvalues for given keynames.
[64cf353]96        '''
[4ef5ba9]97        from eccodes import (codes_new_from_file, codes_is_defined, codes_get,
98                             codes_release)
[64cf353]99
[ff99eae]100        fileid = open(self.filenames, 'r')
[64cf353]101
102        return_list = []
103
[d69b677]104        while 1:
[2e62398]105            gid = codes_new_from_file(fileid)
[d69b677]106
[aa275fc]107            if gid is None:
[64cf353]108                break
109
110            if len(wherekeynames) != len(wherekeyvalues):
111                raise Exception("Number of key values and key names must be \
112                                 the same. Give a value for each keyname!")
113
114            select = True
115            i = 0
[d69b677]116            for wherekey in wherekeynames:
[2e62398]117                if not codes_is_defined(gid, wherekey):
[64cf353]118                    raise Exception("where key was not defined")
119
120                select = (select and (str(wherekeyvalues[i]) ==
[2e62398]121                                      str(codes_get(gid, wherekey))))
[64cf353]122                i += 1
123
[d69b677]124            if select:
125                llist = []
126                for key in keynames:
[2e62398]127                    llist.extend([str(codes_get(gid, key))])
[d69b677]128                return_list.append(llist)
[64cf353]129
[2e62398]130            codes_release(gid)
[64cf353]131
[d69b677]132        fileid.close()
[64cf353]133
[d69b677]134        return return_list
[64cf353]135
136
[ff99eae]137    def set_keys(self, fromfile, keynames, keyvalues, wherekeynames=[],
138                 wherekeyvalues=[], strict=False, filemode='w'):
[274f9ef]139        '''Opens the file to read the grib messages and then write
[268ee86]140        the selected messages (with wherekeys) to a new output file.
141        Also, the keyvalues of the passed list of keynames are set.
[64cf353]142
[274f9ef]143        Parameters
144        ----------
145        fromfile : :obj:`string`
146            Filename of the input file to read the grib messages from.
[64cf353]147
[274f9ef]148        keynames : :obj:`list` of :obj:`string`
[268ee86]149            List of keynames to set in the selected messages.
150            Default is an empty list.
[64cf353]151
[274f9ef]152        keyvalues : :obj:`list` of :obj:`string`
[268ee86]153            List of keyvalues to set in the selected messages.
154            Default is an empty list.
[64cf353]155
[274f9ef]156        wherekeynames : :obj:`list` of :obj:`string`, optional
[268ee86]157            List of keynames to select correct message.
[274f9ef]158            Default value is an empty list.
[64cf353]159
[274f9ef]160        wherekeyvalues : :obj:`list` of :obj:`string`, optional
[268ee86]161            List of keyvalues for keynames to select correct message.
[274f9ef]162            Default value is an empty list.
[64cf353]163
[274f9ef]164        strict : :obj:`boolean`, optional
165            Decides if everything from keynames and keyvalues
166            is written out the grib file (False) or only those
167            meeting the where statement (True). Default is False.
[64cf353]168
[274f9ef]169        filemode : :obj:`string`, optional
170            Sets the mode for the output file. Default is "w".
[64cf353]171
[274f9ef]172        Return
173        ------
[64cf353]174
175        '''
[4ef5ba9]176        from eccodes import (codes_grib_new_from_file, codes_is_defined,
177                             codes_get, codes_set, codes_write,
178                             codes_set_values, codes_release)
179
[268ee86]180        if len(wherekeynames) != len(wherekeyvalues):
181            raise Exception("Give a value for each keyname!")
182
[ff99eae]183        fout = open(self.filenames, filemode)
[64cf353]184        fin = open(fromfile)
185
[d69b677]186        while 1:
[268ee86]187            gid = codes_grib_new_from_file(fin)
[64cf353]188
[aa275fc]189            if gid is None:
[64cf353]190                break
[d69b677]191
[64cf353]192            select = True
193            i = 0
[d69b677]194            for wherekey in wherekeynames:
[2e62398]195                if not codes_is_defined(gid, wherekey):
[268ee86]196                    raise Exception("wherekey was not defined")
[64cf353]197
198                select = (select and (str(wherekeyvalues[i]) ==
[2e62398]199                                      str(codes_get(gid, wherekey))))
[64cf353]200                i += 1
201
[d69b677]202            if select:
[64cf353]203                i = 0
[d69b677]204                for key in keynames:
[268ee86]205                    if key == 'values':
206                        codes_set_values(gid, keyvalues[i])
207                    else:
208                        codes_set(gid, key, keyvalues[i])
[64cf353]209                    i += 1
210
[268ee86]211                codes_write(gid, fout)
[ff99eae]212
[2e62398]213            codes_release(gid)
[64cf353]214
[d69b677]215        fin.close()
216        fout.close()
217
[64cf353]218        return
219
[268ee86]220    def copy_dummy_msg(self, filename_in, selectWhere=True,
221                 keynames=[], keyvalues=[], filemode='w'):
[274f9ef]222        '''Add the content of another input grib file to the objects file but
[64cf353]223        only messages corresponding to keys/values passed to the function.
224        The selectWhere switch decides if to copy the keys equal to (True) or
225        different to (False) the keynames/keyvalues list passed to the function.
226
[274f9ef]227        Parameters
228        ----------
229        filename_in : :obj:`string`
230            Filename of the input file to read the grib messages from.
231
232        selectWhere : :obj:`boolean`, optional
233            Decides if to copy the keynames and values equal to (True) or
234            different to (False) the keynames/keyvalues list passed to the
235            function. Default is True.
[64cf353]236
[274f9ef]237        keynames : :obj:`list` of :obj:`string`, optional
238            List of keynames. Default is an empty list.
[64cf353]239
[274f9ef]240        keyvalues : :obj:`list` of :obj:`string`, optional
[268ee86]241            List of keyvalues. Default is an empty list.
[64cf353]242
[274f9ef]243        filemode : :obj:`string`, optional
244            Sets the mode for the output file. Default is "w".
[64cf353]245
[274f9ef]246        Return
247        ------
[64cf353]248
249        '''
[4ef5ba9]250        from eccodes import (codes_grib_new_from_file, codes_is_defined,
251                             codes_get, codes_release, codes_write)
252
[268ee86]253        if len(keynames) != len(keyvalues):
254            raise Exception("Give a value for each keyname!")
[64cf353]255
[4ef5ba9]256        fin = open(filename_in, 'rb')
[ff99eae]257        fout = open(self.filenames, filemode)
[64cf353]258
[268ee86]259        fields = 0
260
261        while fields < 1:
262            gid = codes_grib_new_from_file(fin)
[d69b677]263
[aa275fc]264            if gid is None:
[64cf353]265                break
266
267            select = True
268            i = 0
[d69b677]269            for key in keynames:
[2e62398]270                if not codes_is_defined(gid, key):
[64cf353]271                    raise Exception("Key was not defined")
272
[d69b677]273                if selectWhere:
[64cf353]274                    select = (select and (str(keyvalues[i]) ==
[2e62398]275                                          str(codes_get(gid, key))))
[d69b677]276                else:
[64cf353]277                    select = (select and (str(keyvalues[i]) !=
[2e62398]278                                          str(codes_get(gid, key))))
[64cf353]279                i += 1
280
[d69b677]281            if select:
[268ee86]282                fields = fields + 1
[2e62398]283                codes_write(gid, fout)
[64cf353]284
[2e62398]285            codes_release(gid)
[64cf353]286
[d69b677]287        fin.close()
288        fout.close()
289
[64cf353]290        return
291
292    def index(self, index_keys=["mars"], index_file="my.idx"):
[274f9ef]293        '''Create index file from a list of files if it does not exist or
294        read an index file.
295
296        Parameters
297        ----------
298        index_keys: :obj:`list` of :obj:`string`, optional
299            Contains the list of key parameter names from
300            which the index is to be created.
301            Default is a list with a single entry string "mars".
302
303        index_file: :obj:`string`, optional
304            Filename where the indices are stored.
305            Default is "my.idx".
306
307        Return
308        ------
309        iid: :obj:`integer`
310            Grib index id.
[64cf353]311        '''
[4ef5ba9]312        from eccodes import (codes_index_read, codes_index_new_from_file,
313                             codes_index_add_file, codes_index_write)
314
[2fb99de]315        print("... index will be done")
[ff99eae]316        iid = None
[64cf353]317
[ff99eae]318        if os.path.exists(index_file):
[2e62398]319            iid = codes_index_read(index_file)
[2fb99de]320            print("Use existing index file: %s " % (index_file))
[d69b677]321        else:
[ff99eae]322            for filename in self.filenames:
[2fb99de]323                print("Inputfile: %s " % (filename))
[ff99eae]324                if iid is None:
[2e62398]325                    iid = codes_index_new_from_file(filename, index_keys)
[d69b677]326                else:
[2e62398]327                    codes_index_add_file(iid, filename)
[d69b677]328
[ff99eae]329            if iid is not None:
[2e62398]330                codes_index_write(iid, index_file)
[d69b677]331
[2fb99de]332        print('... index done')
[d69b677]333
[ff99eae]334        return iid
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG