source: flex_extract.git/source/python/classes/GribUtil.py @ 79729d5

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

switched from python2 to python3

  • Property mode set to 100644
File size: 10.3 KB
RevLine 
[79729d5]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# ------------------------------------------------------------------------------
[efdb01a]45import os
[aa275fc]46
[2e62398]47from eccodes import (codes_grib_new_from_file, codes_is_defined, codes_get,
48                     codes_release, codes_set, codes_write, codes_index_read,
49                     codes_index_new_from_file, codes_index_add_file,
[268ee86]50                     codes_index_write, codes_set_values)
[991df6a]51
[64cf353]52# ------------------------------------------------------------------------------
53# CLASS
54# ------------------------------------------------------------------------------
[268ee86]55class GribUtil(object):
[64cf353]56    '''
57    Class for GRIB utilities (new methods) based on GRIB API
58    '''
59    # --------------------------------------------------------------------------
[efdb01a]60    # CLASS FUNCTIONS
[64cf353]61    # --------------------------------------------------------------------------
62    def __init__(self, filenames):
[268ee86]63        '''Initialise an object of GribUtil and assign a list of filenames.
[274f9ef]64
65        Parameters
66        ----------
67        filenames : :obj:`list` of :obj:`strings`
68             A list of filenames.
[64cf353]69
[274f9ef]70        Return
71        ------
[64cf353]72
73        '''
74
[ff99eae]75        self.filenames = filenames
[64cf353]76
77        return
78
79
[ff99eae]80    def get_keys(self, keynames, wherekeynames=[], wherekeyvalues=[]):
[274f9ef]81        '''Get keyvalues for a given list of keynames a where statement
82        can be given (list of key and list of values)
[64cf353]83
[274f9ef]84        Parameters
85        ----------
86        keynames : :obj:`list` of :obj:`string`
87            List of keynames.
[64cf353]88
[274f9ef]89        wherekeynames : :obj:`list` of :obj:`string`, optional
90            Default value is an empty list.
[64cf353]91
[274f9ef]92        wherekeyvalues : :obj:`list` of :obj:`string`, optional
93            Default value is an empty list.
[64cf353]94
[274f9ef]95        Return
96        ------
97        return_list : :obj:`list` of :obj:`string`
98            List of keyvalues for given keynames.
[64cf353]99        '''
100
[ff99eae]101        fileid = open(self.filenames, 'r')
[64cf353]102
103        return_list = []
104
[d69b677]105        while 1:
[2e62398]106            gid = codes_new_from_file(fileid)
[d69b677]107
[aa275fc]108            if gid is None:
[64cf353]109                break
110
111            if len(wherekeynames) != len(wherekeyvalues):
112                raise Exception("Number of key values and key names must be \
113                                 the same. Give a value for each keyname!")
114
115            select = True
116            i = 0
[d69b677]117            for wherekey in wherekeynames:
[2e62398]118                if not codes_is_defined(gid, wherekey):
[64cf353]119                    raise Exception("where key was not defined")
120
121                select = (select and (str(wherekeyvalues[i]) ==
[2e62398]122                                      str(codes_get(gid, wherekey))))
[64cf353]123                i += 1
124
[d69b677]125            if select:
126                llist = []
127                for key in keynames:
[2e62398]128                    llist.extend([str(codes_get(gid, key))])
[d69b677]129                return_list.append(llist)
[64cf353]130
[2e62398]131            codes_release(gid)
[64cf353]132
[d69b677]133        fileid.close()
[64cf353]134
[d69b677]135        return return_list
[64cf353]136
137
[ff99eae]138    def set_keys(self, fromfile, keynames, keyvalues, wherekeynames=[],
139                 wherekeyvalues=[], strict=False, filemode='w'):
[274f9ef]140        '''Opens the file to read the grib messages and then write
[268ee86]141        the selected messages (with wherekeys) to a new output file.
142        Also, the keyvalues of the passed list of keynames are set.
[64cf353]143
[274f9ef]144        Parameters
145        ----------
146        fromfile : :obj:`string`
147            Filename of the input file to read the grib messages from.
[64cf353]148
[274f9ef]149        keynames : :obj:`list` of :obj:`string`
[268ee86]150            List of keynames to set in the selected messages.
151            Default is an empty list.
[64cf353]152
[274f9ef]153        keyvalues : :obj:`list` of :obj:`string`
[268ee86]154            List of keyvalues to set in the selected messages.
155            Default is an empty list.
[64cf353]156
[274f9ef]157        wherekeynames : :obj:`list` of :obj:`string`, optional
[268ee86]158            List of keynames to select correct message.
[274f9ef]159            Default value is an empty list.
[64cf353]160
[274f9ef]161        wherekeyvalues : :obj:`list` of :obj:`string`, optional
[268ee86]162            List of keyvalues for keynames to select correct message.
[274f9ef]163            Default value is an empty list.
[64cf353]164
[274f9ef]165        strict : :obj:`boolean`, optional
166            Decides if everything from keynames and keyvalues
167            is written out the grib file (False) or only those
168            meeting the where statement (True). Default is False.
[64cf353]169
[274f9ef]170        filemode : :obj:`string`, optional
171            Sets the mode for the output file. Default is "w".
[64cf353]172
[274f9ef]173        Return
174        ------
[64cf353]175
176        '''
[268ee86]177        if len(wherekeynames) != len(wherekeyvalues):
178            raise Exception("Give a value for each keyname!")
179
[ff99eae]180        fout = open(self.filenames, filemode)
[64cf353]181        fin = open(fromfile)
182
[d69b677]183        while 1:
[268ee86]184            gid = codes_grib_new_from_file(fin)
[64cf353]185
[aa275fc]186            if gid is None:
[64cf353]187                break
[d69b677]188
[64cf353]189            select = True
190            i = 0
[d69b677]191            for wherekey in wherekeynames:
[2e62398]192                if not codes_is_defined(gid, wherekey):
[268ee86]193                    raise Exception("wherekey was not defined")
[64cf353]194
195                select = (select and (str(wherekeyvalues[i]) ==
[2e62398]196                                      str(codes_get(gid, wherekey))))
[64cf353]197                i += 1
198
[d69b677]199            if select:
[64cf353]200                i = 0
[d69b677]201                for key in keynames:
[268ee86]202                    if key == 'values':
203                        codes_set_values(gid, keyvalues[i])
204                    else:
205                        codes_set(gid, key, keyvalues[i])
[64cf353]206                    i += 1
207
[268ee86]208                codes_write(gid, fout)
[ff99eae]209
[2e62398]210            codes_release(gid)
[64cf353]211
[d69b677]212        fin.close()
213        fout.close()
214
[64cf353]215        return
216
[268ee86]217    def copy_dummy_msg(self, filename_in, selectWhere=True,
218                 keynames=[], keyvalues=[], filemode='w'):
[274f9ef]219        '''Add the content of another input grib file to the objects file but
[64cf353]220        only messages corresponding to keys/values passed to the function.
221        The selectWhere switch decides if to copy the keys equal to (True) or
222        different to (False) the keynames/keyvalues list passed to the function.
223
[274f9ef]224        Parameters
225        ----------
226        filename_in : :obj:`string`
227            Filename of the input file to read the grib messages from.
228
229        selectWhere : :obj:`boolean`, optional
230            Decides if to copy the keynames and values equal to (True) or
231            different to (False) the keynames/keyvalues list passed to the
232            function. Default is True.
[64cf353]233
[274f9ef]234        keynames : :obj:`list` of :obj:`string`, optional
235            List of keynames. Default is an empty list.
[64cf353]236
[274f9ef]237        keyvalues : :obj:`list` of :obj:`string`, optional
[268ee86]238            List of keyvalues. Default is an empty list.
[64cf353]239
[274f9ef]240        filemode : :obj:`string`, optional
241            Sets the mode for the output file. Default is "w".
[64cf353]242
[274f9ef]243        Return
244        ------
[64cf353]245
246        '''
[268ee86]247        if len(keynames) != len(keyvalues):
248            raise Exception("Give a value for each keyname!")
[64cf353]249
250        fin = open(filename_in)
[ff99eae]251        fout = open(self.filenames, filemode)
[64cf353]252
[268ee86]253        fields = 0
254
255        while fields < 1:
256            gid = codes_grib_new_from_file(fin)
[d69b677]257
[aa275fc]258            if gid is None:
[64cf353]259                break
260
261            select = True
262            i = 0
[d69b677]263            for key in keynames:
[2e62398]264                if not codes_is_defined(gid, key):
[64cf353]265                    raise Exception("Key was not defined")
266
[d69b677]267                if selectWhere:
[64cf353]268                    select = (select and (str(keyvalues[i]) ==
[2e62398]269                                          str(codes_get(gid, key))))
[d69b677]270                else:
[64cf353]271                    select = (select and (str(keyvalues[i]) !=
[2e62398]272                                          str(codes_get(gid, key))))
[64cf353]273                i += 1
274
[d69b677]275            if select:
[268ee86]276                fields = fields + 1
[2e62398]277                codes_write(gid, fout)
[64cf353]278
[2e62398]279            codes_release(gid)
[64cf353]280
[d69b677]281        fin.close()
282        fout.close()
283
[64cf353]284        return
285
286    def index(self, index_keys=["mars"], index_file="my.idx"):
[274f9ef]287        '''Create index file from a list of files if it does not exist or
288        read an index file.
289
290        Parameters
291        ----------
292        index_keys: :obj:`list` of :obj:`string`, optional
293            Contains the list of key parameter names from
294            which the index is to be created.
295            Default is a list with a single entry string "mars".
296
297        index_file: :obj:`string`, optional
298            Filename where the indices are stored.
299            Default is "my.idx".
300
301        Return
302        ------
303        iid: :obj:`integer`
304            Grib index id.
[64cf353]305        '''
[2fb99de]306        print("... index will be done")
[ff99eae]307        iid = None
[64cf353]308
[ff99eae]309        if os.path.exists(index_file):
[2e62398]310            iid = codes_index_read(index_file)
[2fb99de]311            print("Use existing index file: %s " % (index_file))
[d69b677]312        else:
[ff99eae]313            for filename in self.filenames:
[2fb99de]314                print("Inputfile: %s " % (filename))
[ff99eae]315                if iid is None:
[2e62398]316                    iid = codes_index_new_from_file(filename, index_keys)
[d69b677]317                else:
[2e62398]318                    codes_index_add_file(iid, filename)
[d69b677]319
[ff99eae]320            if iid is not None:
[2e62398]321                codes_index_write(iid, index_file)
[d69b677]322
[2fb99de]323        print('... index done')
[d69b677]324
[ff99eae]325        return iid
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG