Index: source/python/classes/GribUtil.py
===================================================================
--- source/python/classes/GribUtil.py	(revision 702cbb7ba93360a42cad4176cd61e2dc61d1e991)
+++ source/python/classes/GribUtil.py	(revision 702cbb7ba93360a42cad4176cd61e2dc61d1e991)
@@ -0,0 +1,318 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: July 2014
+#
+# @Change History:
+#   February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - changed some naming
+#
+# @License:
+#    (C) Copyright 2014-2018.
+#
+#    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.
+#
+# @Class Description:
+#    The GRIB API provides all necessary tools to work directly with the
+#    grib files. Nevertheless, the GRIB API tools are very basic and are in
+#    direct connection with the grib files. This class provides some higher
+#    functions which apply a set of GRIB API tools together in the respective
+#    context. So, the class initially contains a list of grib files (their
+#    names) and the using program then applies the methods directly on the
+#    class objects without having to think about how the actual GRIB API
+#    tools have to be arranged.
+#
+# @Class Content:
+#    - __init__
+#    - get_keys
+#    - set_keys
+#    - copy
+#    - index
+#
+# @Class Attributes:
+#    - filenames
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+
+from eccodes import (codes_grib_new_from_file, codes_is_defined, codes_get,
+                     codes_release, codes_set, codes_write, codes_index_read,
+                     codes_index_new_from_file, codes_index_add_file,
+                     codes_index_write)
+
+# ------------------------------------------------------------------------------
+# CLASS
+# ------------------------------------------------------------------------------
+class GribTools(object):
+    '''
+    Class for GRIB utilities (new methods) based on GRIB API
+    '''
+    # --------------------------------------------------------------------------
+    # CLASS FUNCTIONS
+    # --------------------------------------------------------------------------
+    def __init__(self, filenames):
+        '''Initialise an object of GribTools and assign a list of filenames.
+
+        Parameters
+        ----------
+        filenames : :obj:`list` of :obj:`strings`
+             A list of filenames.
+
+        Return
+        ------
+
+        '''
+
+        self.filenames = filenames
+
+        return
+
+
+    def get_keys(self, keynames, wherekeynames=[], wherekeyvalues=[]):
+        '''Get keyvalues for a given list of keynames a where statement
+        can be given (list of key and list of values)
+
+        Parameters
+        ----------
+        keynames : :obj:`list` of :obj:`string`
+            List of keynames.
+
+        wherekeynames : :obj:`list` of :obj:`string`, optional
+            Default value is an empty list.
+
+        wherekeyvalues : :obj:`list` of :obj:`string`, optional
+            Default value is an empty list.
+
+        Return
+        ------
+        return_list : :obj:`list` of :obj:`string`
+            List of keyvalues for given keynames.
+        '''
+
+        fileid = open(self.filenames, 'r')
+
+        return_list = []
+
+        while 1:
+            gid = codes_new_from_file(fileid)
+
+            if gid is None:
+                break
+
+            if len(wherekeynames) != len(wherekeyvalues):
+                raise Exception("Number of key values and key names must be \
+                                 the same. Give a value for each keyname!")
+
+            select = True
+            i = 0
+            for wherekey in wherekeynames:
+                if not codes_is_defined(gid, wherekey):
+                    raise Exception("where key was not defined")
+
+                select = (select and (str(wherekeyvalues[i]) ==
+                                      str(codes_get(gid, wherekey))))
+                i += 1
+
+            if select:
+                llist = []
+                for key in keynames:
+                    llist.extend([str(codes_get(gid, key))])
+                return_list.append(llist)
+
+            codes_release(gid)
+
+        fileid.close()
+
+        return return_list
+
+
+    def set_keys(self, fromfile, keynames, keyvalues, wherekeynames=[],
+                 wherekeyvalues=[], strict=False, filemode='w'):
+        '''Opens the file to read the grib messages and then write
+        them to a new output file. By default all messages are
+        written out. Also, the keyvalues of the passed list of
+        keynames are set or only those meeting the where statement.
+        (list of key and list of values).
+
+        Parameters
+        ----------
+        fromfile : :obj:`string`
+            Filename of the input file to read the grib messages from.
+
+        keynames : :obj:`list` of :obj:`string`
+            List of keynames. Default is an empty list.
+
+        keyvalues : :obj:`list` of :obj:`string`
+            List of keynames. Default is an empty list.
+
+        wherekeynames : :obj:`list` of :obj:`string`, optional
+            Default value is an empty list.
+
+        wherekeyvalues : :obj:`list` of :obj:`string`, optional
+            Default value is an empty list.
+
+        strict : :obj:`boolean`, optional
+            Decides if everything from keynames and keyvalues
+            is written out the grib file (False) or only those
+            meeting the where statement (True). Default is False.
+
+        filemode : :obj:`string`, optional
+            Sets the mode for the output file. Default is "w".
+
+        Return
+        ------
+
+        '''
+        fout = open(self.filenames, filemode)
+        fin = open(fromfile)
+
+        while 1:
+            gid = codes_new_from_file(fin)
+
+            if gid is None:
+                break
+
+            if len(wherekeynames) != len(wherekeyvalues):
+                raise Exception("Give a value for each keyname!")
+
+            select = True
+            i = 0
+            for wherekey in wherekeynames:
+                if not codes_is_defined(gid, wherekey):
+                    raise Exception("where Key was not defined")
+
+                select = (select and (str(wherekeyvalues[i]) ==
+                                      str(codes_get(gid, wherekey))))
+                i += 1
+
+            if select:
+                i = 0
+                for key in keynames:
+                    codes_set(gid, key, keyvalues[i])
+                    i += 1
+
+            codes_write(gid, fout)
+
+            codes_release(gid)
+
+        fin.close()
+        fout.close()
+
+        return
+
+    def copy(self, filename_in, selectWhere=True,
+             keynames=[], keyvalues=[], filemode='w'):
+        '''Add the content of another input grib file to the objects file but
+        only messages corresponding to keys/values passed to the function.
+        The selectWhere switch decides if to copy the keys equal to (True) or
+        different to (False) the keynames/keyvalues list passed to the function.
+
+        Parameters
+        ----------
+        filename_in : :obj:`string`
+            Filename of the input file to read the grib messages from.
+
+        selectWhere : :obj:`boolean`, optional
+            Decides if to copy the keynames and values equal to (True) or
+            different to (False) the keynames/keyvalues list passed to the
+            function. Default is True.
+
+        keynames : :obj:`list` of :obj:`string`, optional
+            List of keynames. Default is an empty list.
+
+        keyvalues : :obj:`list` of :obj:`string`, optional
+            List of keynames. Default is an empty list.
+
+        filemode : :obj:`string`, optional
+            Sets the mode for the output file. Default is "w".
+
+        Return
+        ------
+
+        '''
+
+        fin = open(filename_in)
+        fout = open(self.filenames, filemode)
+
+        while 1:
+            gid = codes_new_from_file(fin)
+
+            if gid is None:
+                break
+
+            if len(keynames) != len(keyvalues):
+                raise Exception("Give a value for each keyname!")
+
+            select = True
+            i = 0
+            for key in keynames:
+                if not codes_is_defined(gid, key):
+                    raise Exception("Key was not defined")
+
+                if selectWhere:
+                    select = (select and (str(keyvalues[i]) ==
+                                          str(codes_get(gid, key))))
+                else:
+                    select = (select and (str(keyvalues[i]) !=
+                                          str(codes_get(gid, key))))
+                i += 1
+
+            if select:
+                codes_write(gid, fout)
+
+            codes_release(gid)
+
+        fin.close()
+        fout.close()
+
+        return
+
+    def index(self, index_keys=["mars"], index_file="my.idx"):
+        '''Create index file from a list of files if it does not exist or
+        read an index file.
+
+        Parameters
+        ----------
+        index_keys: :obj:`list` of :obj:`string`, optional
+            Contains the list of key parameter names from
+            which the index is to be created.
+            Default is a list with a single entry string "mars".
+
+        index_file: :obj:`string`, optional
+            Filename where the indices are stored.
+            Default is "my.idx".
+
+        Return
+        ------
+        iid: :obj:`integer`
+            Grib index id.
+        '''
+        print("... index will be done")
+        iid = None
+
+        if os.path.exists(index_file):
+            iid = codes_index_read(index_file)
+            print("Use existing index file: %s " % (index_file))
+        else:
+            for filename in self.filenames:
+                print("Inputfile: %s " % (filename))
+                if iid is None:
+                    iid = codes_index_new_from_file(filename, index_keys)
+                else:
+                    codes_index_add_file(iid, filename)
+
+            if iid is not None:
+                codes_index_write(iid, index_file)
+
+        print('... index done')
+
+        return iid
