Index: python/CONTROL_OD
===================================================================
--- python/CONTROL_OD	(revision ff99eae65dfaeec1221e06572d770ebd48feb3f4)
+++ python/CONTROL_OD	(revision ff99eae65dfaeec1221e06572d770ebd48feb3f4)
@@ -0,0 +1,35 @@
+DAY1 20151007
+DAY2 20151007
+DTIME 3
+M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 1000  
+M_LEFT -10000
+M_LOWER 30000
+M_UPPER 60000
+M_RIGHT 30000
+M_LEVEL 137
+M_LEVELIST 130/to/137
+M_RESOL 399
+M_GAUSS 0
+M_ACCURACY 16
+M_OMEGA 0
+M_OMEGADIFF 0
+M_ETA 1
+M_ETADIFF 0
+M_DPDETA 1
+M_SMOOTH 0
+M_FORMAT GRIB1
+M_ADDPAR 186/187/188/235/139/39
+PREFIX EO
+ECSTORAGE 0
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+EOF
Index: python/ControlFile.py
===================================================================
--- python/ControlFile.py	(revision 812283d029ad6bb1dcc03c7df966c08e9229dc70)
+++ python/ControlFile.py	(revision ff99eae65dfaeec1221e06572d770ebd48feb3f4)
@@ -2,5 +2,5 @@
 # -*- coding: utf-8 -*-
 #************************************************************************
-# TODO AP
+# ToDo AP
 # - write a test class
 #************************************************************************
@@ -37,5 +37,26 @@
 #    - __init__
 #    - __str__
-#    - tolist
+#    - to_list
+#
+# @Class Attributes:
+#    - start_date
+#    - end_date
+#    - accuracy
+#    - omega
+#    - cwc
+#    - omegadiff
+#    - etadiff
+#    - level
+#    - levelist
+#    - step
+#    - maxstep
+#    - prefix
+#    - makefile
+#    - basetime
+#    - date_chunk
+#    - grib2flexpart
+#    - exedir
+#    - flexpart_root_scripts
+#    - ecmwfdatadir
 #
 #*******************************************************************************
@@ -46,11 +67,12 @@
 import os
 import inspect
+
 # software specific module from flex_extract
-import Tools
+from tools import get_list_as_string, my_error
 
 # ------------------------------------------------------------------------------
 # CLASS
 # ------------------------------------------------------------------------------
-class ControlFile:
+class ControlFile(object):
     '''
     Class containing the information of the flex_extract CONTROL file.
@@ -114,5 +136,4 @@
                         for d in dd:
                             data.append(d)
-                    pass
                 if len(data) == 2:
                     if '$' in data[1]:
@@ -126,9 +147,7 @@
                                 data[1] = data[1][:i] + var + data[1][k+1:]
                             else:
-                                Tools.myerror(None,
-                                              'Could not find variable ' +
-                                              data[1][j+1:k] +
-                                              ' while reading ' +
-                                              filename)
+                                my_error(None, 'Could not find variable ' +
+                                         data[1][j+1:k] + ' while reading ' +
+                                         filename)
                         setattr(self, data[0].lower() + '_expanded', data[1])
                     else:
@@ -160,6 +179,6 @@
         if not hasattr(self, 'levelist'):
             if not hasattr(self, 'level'):
-                print('Warning: neither levelist nor level \
-                       specified in CONTROL file')
+                print 'Warning: neither levelist nor level \
+                       specified in CONTROL file'
             else:
                 self.levelist = '1/to/' + self.level
@@ -224,5 +243,5 @@
         return ', '.join("%s: %s" % item for item in attrs.items())
 
-    def tolist(self):
+    def to_list(self):
         '''
         @Description:
@@ -255,5 +274,5 @@
                 pass
             else:
-                if type(item[1]) is list:
+                if isinstance(item[1], list):
                     stot = ''
                     for s in item[1]:
@@ -265,2 +284,23 @@
 
         return sorted(l)
+
+    # def to_dict(self):
+        # '''
+
+        # '''
+        # parameters_dict = vars(self)
+
+        # # remove unneeded parameter
+        # parameters_dict.pop('_expanded', None)
+        # parameters_dict.pop('exedir', None)
+        # parameters_dict.pop('flexpart_root_scripts', None)
+        # parameters_dict.pop('ecmwfdatadir', None)
+
+        # parameters_dict_str = {}
+        # for key, value in parameters_dict.iteritems():
+            # if isinstance(value, list):
+                # parameters_dict_str[str(key)] = get_list_as_string(value, ' ')
+            # else:
+                # parameters_dict_str[str(key)] = str(value)
+
+        # return parameters_dict_str
Index: python/Disagg.py
===================================================================
--- python/Disagg.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ 	(revision )
@@ -1,155 +1,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-# - check alist of size 4 ?
-# - write a test, IMPORTANT
-#************************************************************************
-#*******************************************************************************
-# @Author: Anne Philipp (University of Vienna)
-#
-# @Date: March 2018
-#
-# @Change History:
-#    November 2015 - Leopold Haimberger (University of Vienna):
-#        - migration of the methods dapoly and darain from Fortran
-#          (flex_extract_v6 and earlier) to Python
-#
-#    April 2018 - Anne Philipp (University of Vienna):
-#        - applied PEP8 style guide
-#        - added structured documentation
-#        - outsourced the disaggregation functions dapoly and darain
-#          to a new module named Disagg
-#
-# @License:
-#    (C) Copyright 2015-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.
-#
-# @Module Description:
-#    Disaggregation of deaccumulated flux data from an ECMWF model FG field.
-#    Initially the flux data to be concerned are:
-#    - large-scale precipitation
-#    - convective precipitation
-#    - surface sensible heat flux
-#    - surface solar radiation
-#    - u stress
-#    - v stress
-#    Different versions of disaggregation is provided for rainfall
-#    data (darain, modified linear) and the surface fluxes and
-#    stress data (dapoly, cubic polynomial).
-#
-# @Module Content:
-#    - dapoly
-#    - darain
-#
-#*******************************************************************************
-
-# ------------------------------------------------------------------------------
-# MODULES
-# ------------------------------------------------------------------------------
-
-# ------------------------------------------------------------------------------
-# FUNCTIONS
-# ------------------------------------------------------------------------------
-def dapoly(alist):
-    '''
-    @Author: P. JAMES
-
-    @Date: 2000-03-29
-
-    @ChangeHistory:
-        June 2003     - A. BECK (2003-06-01)
-            adaptaions
-        November 2015 - Leopold Haimberger (University of Vienna)
-            migration from Fortran to Python
-
-    @Description:
-        Interpolation of deaccumulated fluxes of an ECMWF model FG field
-        using a cubic polynomial solution which conserves the integrals
-        of the fluxes within each timespan.
-        Disaggregation is done for 4 accumluated timespans which generates
-        a new, disaggregated value which is output at the central point
-        of the 4 accumulation timespans. This new point is used for linear
-        interpolation of the complete timeseries afterwards.
-
-    @Input:
-        alist: list of size 4, array(2D), type=float
-            List of 4 timespans as 2-dimensional, horizontal fields.
-            E.g. [[array_t1], [array_t2], [array_t3], [array_t4]]
-
-    @Return:
-        nfield: array(2D), type=float
-            New field which replaces the field at the second position
-            of the accumulation timespans.
-
-    '''
-    pya = (alist[3] - alist[0] + 3. * (alist[1] - alist[2])) / 6.
-    pyb = (alist[2] + alist[0]) / 2. - alist[1] - 9. * pya / 2.
-    pyc = alist[1] - alist[0] - 7. * pya / 2. - 2. * pyb
-    pyd = alist[0] - pya / 4. - pyb / 3. - pyc / 2.
-    nfield = 8. * pya + 4. * pyb + 2. * pyc + pyd
-
-    return nfield
-
-
-def darain(alist):
-    '''
-    @Author: P. JAMES
-
-    @Date: 2000-03-29
-
-    @ChangeHistory:
-        June 2003     - A. BECK (2003-06-01)
-            adaptaions
-        November 2015 - Leopold Haimberger (University of Vienna)
-            migration from Fortran to Python
-
-    @Description:
-        Interpolation of deaccumulated fluxes of an ECMWF model FG rainfall
-        field using a modified linear solution which conserves the integrals
-        of the fluxes within each timespan.
-        Disaggregation is done for 4 accumluated timespans which generates
-        a new, disaggregated value which is output at the central point
-        of the 4 accumulation timespans. This new point is used for linear
-        interpolation of the complete timeseries afterwards.
-
-    @Input:
-        alist: list of size 4, array(2D), type=float
-            List of 4 timespans as 2-dimensional, horizontal fields.
-            E.g. [[array_t1], [array_t2], [array_t3], [array_t4]]
-
-    @Return:
-        nfield: array(2D), type=float
-            New field which replaces the field at the second position
-            of the accumulation timespans.
-    '''
-    xa = alist[0]
-    xb = alist[1]
-    xc = alist[2]
-    xd = alist[3]
-    xa[xa < 0.] = 0.
-    xb[xb < 0.] = 0.
-    xc[xc < 0.] = 0.
-    xd[xd < 0.] = 0.
-
-    xac = 0.5 * xb
-    mask = xa + xc > 0.
-    xac[mask] = xb[mask] * xc[mask] / (xa[mask] + xc[mask])
-    xbd = 0.5 * xc
-    mask = xb + xd > 0.
-    xbd[mask] = xb[mask] * xc[mask] / (xb[mask] + xd[mask])
-    nfield = xac + xbd
-
-    return nfield
-
-
-
-
-
-
-
-
-
-
Index: python/ECFlexpart.py
===================================================================
--- python/ECFlexpart.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ 	(revision )
@@ -1,1252 +1,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-# - specifiy file header documentation
-# - add class description in header information
-# - apply classtests
-# - add references to ECMWF specific software packages
-# - add describtion of deacc_fluxes
-# - change name of func deacc ( weil disagg )
-# - add desc of retrieve function
-#************************************************************************
-#*******************************************************************************
-# @Author: Anne Fouilloux (University of Oslo)
-#
-# @Date: October 2014
-#
-# @Change History:
-#
-#    November 2015 - Leopold Haimberger (University of Vienna):
-#        - extended with class Control
-#        - removed functions mkdir_p, daterange, years_between, months_between
-#        - added functions darain, dapoly, toparamId, init128, normalexit,
-#          myerror, cleanup, install_args_and_control,
-#          interpret_args_and_control,
-#        - removed function __del__ in class EIFLexpart
-#        - added the following functions in EIFlexpart:
-#            - create_namelist
-#            - process_output
-#            - deacc_fluxes
-#        - modified existing EIFlexpart - functions for the use in
-#          flex_extract
-#        - retrieve also longer term forecasts, not only analyses and
-#          short term forecast data
-#        - added conversion into GRIB2
-#        - added conversion into .fp format for faster execution of FLEXPART
-#          (see https://www.flexpart.eu/wiki/FpCtbtoWo4FpFormat)
-#
-#    February 2018 - Anne Philipp (University of Vienna):
-#        - applied PEP8 style guide
-#        - added documentation
-#        - removed function getFlexpartTime in class ECFlexpart
-#        - outsourced class ControlFile
-#        - outsourced class MarsRetrieval
-#        - changed class name from EIFlexpart to ECFlexpart
-#        - applied minor code changes (style)
-#        - removed "dead code" , e.g. retrieval of Q since it is not needed
-#        - removed "times" parameter from retrieve-method since it is not used
-#
-# @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:
-#    FLEXPART needs grib files in a specifc format. All necessary data fields
-#    for one time step are stored in a single file. The class represents an
-#    instance with all the parameter and settings necessary for retrieving
-#    MARS data and modifing them so they are fitting FLEXPART need. The class
-#    is able to disaggregate the fluxes and convert grid types to the one needed
-#    by FLEXPART, therefore using the FORTRAN program.
-#
-# @Class Content:
-#    - __init__
-#    - write_namelist
-#    - retrieve
-#    - process_output
-#    - create
-#    - deacc_fluxes
-#
-#*******************************************************************************
-
-# ------------------------------------------------------------------------------
-# MODULES
-# ------------------------------------------------------------------------------
-import subprocess
-import shutil
-import os
-import sys
-import inspect
-import glob
-import datetime
-from numpy import *
-from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
-ecapi = True
-try:
-    import ecmwfapi
-except ImportError:
-    ecapi = False
-from gribapi import *
-
-# software specific classes and modules from flex_extract
-from GribTools import GribTools
-from Tools import init128, toparamId, silentremove, product
-from ControlFile import ControlFile
-from MARSretrieval import MARSretrieval
-import Disagg
-
-# ------------------------------------------------------------------------------
-# CLASS
-# ------------------------------------------------------------------------------
-class ECFlexpart:
-    '''
-    Class to retrieve FLEXPART specific ECMWF data.
-    '''
-    # --------------------------------------------------------------------------
-    # CLASS FUNCTIONS
-    # --------------------------------------------------------------------------
-    def __init__(self, c, fluxes=False):
-        '''
-        @Description:
-            Creates an object/instance of ECFlexpart with the
-            associated settings of its attributes for the retrieval.
-
-        @Input:
-            self: instance of ECFlexpart
-                The current object of the class.
-
-            c: instance of class ControlFile
-                Contains all the parameters of CONTROL file, which are e.g.:
-                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-                For more information about format and content of the parameter
-                see documentation.
-
-            fluxes: boolean, optional
-                Decides if a the flux parameter settings are stored or
-                the rest of the parameter list.
-                Default value is False.
-
-        @Return:
-            <nothing>
-        '''
-
-        # different mars types for retrieving data for flexpart
-        self.types = dict()
-        try:
-            if c.maxstep > len(c.type):    # Pure forecast mode
-                c.type = [c.type[1]]
-                c.step = ['{:0>3}'.format(int(c.step[0]))]
-                c.time = [c.time[0]]
-                for i in range(1, c.maxstep + 1):
-                    c.type.append(c.type[0])
-                    c.step.append('{:0>3}'.format(i))
-                    c.time.append(c.time[0])
-        except:
-            pass
-
-        self.inputdir = c.inputdir
-        self.basetime = c.basetime
-        self.dtime = c.dtime
-        i = 0
-        if fluxes is True and c.maxstep < 24:
-            # no forecast beyond one day is needed!
-            # Thus, prepare flux data manually as usual
-            # with only forecast fields with start times at 00/12
-            # (but without 00/12 fields since these are
-            # the initialisation times of the flux fields
-            # and therefore are zero all the time)
-            self.types[c.type[1]] = {'times': '00/12', 'steps':
-                                     '{}/to/12/by/{}'.format(c.dtime, c.dtime)}
-        else:
-            for ty, st, ti in zip(c.type, c.step, c.time):
-                btlist = range(24)
-                if c.basetime == '12':
-                    btlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
-                if c.basetime == '00':
-                    btlist = [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0]
-
-                if mod(i, int(c.dtime)) == 0 and \
-                    (c.maxstep > 24 or i in btlist):
-
-                    if ty not in self.types.keys():
-                        self.types[ty] = {'times': '', 'steps': ''}
-
-                    if ti not in self.types[ty]['times']:
-                        if len(self.types[ty]['times']) > 0:
-                            self.types[ty]['times'] += '/'
-                        self.types[ty]['times'] += ti
-
-                    if st not in self.types[ty]['steps']:
-                        if len(self.types[ty]['steps']) > 0:
-                            self.types[ty]['steps'] += '/'
-                        self.types[ty]['steps'] += st
-                i += 1
-
-        # Different grids need different retrievals
-        # SH = Spherical Harmonics, GG = Gaussian Grid,
-        # OG = Output Grid, ML = MultiLevel, SL = SingleLevel
-        self.params = {'SH__ML': '', 'SH__SL': '',
-                       'GG__ML': '', 'GG__SL': '',
-                       'OG__ML': '', 'OG__SL': '',
-                       'OG_OROLSM_SL': '', 'OG_acc_SL': ''}
-        self.marsclass = c.marsclass
-        self.stream = c.stream
-        self.number = c.number
-        self.resol = c.resol
-        self.accuracy = c.accuracy
-        self.level = c.level
-        try:
-            self.levelist = c.levelist
-        except:
-            self.levelist = '1/to/' + c.level
-
-        # for gaussian grid retrieval
-        self.glevelist = '1/to/' + c.level
-
-        try:
-            self.gaussian = c.gaussian
-        except:
-            self.gaussian = ''
-
-        try:
-            self.expver = c.expver
-        except:
-            self.expver = '1'
-
-        try:
-            self.number = c.number
-        except:
-            self.number = '0'
-
-        if 'N' in c.grid:  # Gaussian output grid
-            self.grid = c.grid
-            self.area = 'G'
-        else:
-            self.grid = '{}/{}'.format(int(c.grid) / 1000., int(c.grid) / 1000.)
-            self.area = '{}/{}/{}/{}'.format(int(c.upper) / 1000.,
-                                             int(c.left) / 1000.,
-                                             int(c.lower) / 1000.,
-                                             int(c.right) / 1000.)
-
-        self.outputfilelist = []
-
-
-        # Now comes the nasty part that deals with the different
-        # scenarios we have:
-        # 1) Calculation of etadot on
-        #    a) Gaussian grid
-        #    b) Output grid
-        #    c) Output grid using parameter 77 retrieved from MARS
-        # 3) Calculation/Retrieval of omega
-        # 4) Download also data for WRF
-
-        if fluxes is False:
-            self.params['SH__SL'] = ['LNSP', 'ML', '1', 'OFF']
-            #                        "SD/MSL/TCC/10U/10V/2T/2D/129/172"
-            self.params['OG__SL'] = ["141/151/164/165/166/167/168/129/172", \
-                                     'SFC', '1', self.grid]
-            if len(c.addpar) > 0:
-                if c.addpar[0] == '/':
-                    c.addpar = c.addpar[1:]
-                self.params['OG__SL'][0] += '/' + '/'.join(c.addpar)
-
-            self.params['OG_OROLSM__SL'] = ["160/27/28/173", \
-                                            'SFC', '1', self.grid]
-
-            self.params['OG__ML'] = ['T/Q', 'ML', self.levelist, self.grid]
-
-            if c.gauss == '0' and c.eta == '1':
-                # the simplest case
-                self.params['OG__ML'][0] += '/U/V/77'
-            elif c.gauss == '0' and c.eta == '0':
-            # this is not recommended (inaccurate)
-                self.params['OG__ML'][0] += '/U/V'
-            elif c.gauss == '1' and c.eta == '0':
-                # this is needed for data before 2008, or for reanalysis data
-                self.params['GG__SL'] = ['Q', 'ML', '1', \
-                                         '{}'.format((int(self.resol) + 1) / 2)]
-                self.params['SH__ML'] = ['U/V/D', 'ML', self.glevelist, 'OFF']
-            else:
-                print('Warning: This is a very costly parameter combination, \
-                       use only for debugging!')
-                self.params['GG__SL'] = ['Q', 'ML', '1', \
-                                         '{}'.format((int(self.resol) + 1) / 2)]
-                self.params['GG__ML'] = ['U/V/D/77', 'ML', self.glevelist, \
-                                         '{}'.format((int(self.resol) + 1) / 2)]
-
-            if c.omega == '1':
-                self.params['OG__ML'][0] += '/W'
-
-            try:
-                # add cloud water content if necessary
-                if c.cwc == '1':
-                    self.params['OG__ML'][0] += '/CLWC/CIWC'
-            except:
-                pass
-
-            try:
-                # add vorticity and geopotential height for WRF if necessary
-                if c.wrf == '1':
-                    self.params['OG__ML'][0] += '/Z/VO'
-                    if '/D' not in self.params['OG__ML'][0]:
-                        self.params['OG__ML'][0] += '/D'
-                    #wrf_sfc = 'sp/msl/skt/2t/10u/10v/2d/z/lsm/sst/ci/sd/stl1/ /
-                    #           stl2/stl3/stl4/swvl1/swvl2/swvl3/swvl4'.upper()
-                    wrf_sfc = '134/235/167/165/166/168/129/172/34/31/141/ \
-                               139/170/183/236/39/40/41/42'.upper()
-                    lwrt_sfc = wrf_sfc.split('/')
-                    for par in lwrt_sfc:
-                        if par not in self.params['OG__SL'][0]:
-                            self.params['OG__SL'][0] += '/' + par
-            except:
-                pass
-        else:
-            self.params['OG_acc_SL'] = ["LSP/CP/SSHF/EWSS/NSSS/SSR", \
-                                        'SFC', '1', self.grid]
-
-        # if needed, add additional WRF specific parameters here
-
-        return
-
-
-    def write_namelist(self, c, filename):
-        '''
-        @Description:
-            Creates a namelist file in the temporary directory and writes
-            the following values to it: maxl, maxb, mlevel,
-            mlevelist, mnauf, metapar, rlo0, rlo1, rla0, rla1,
-            momega, momegadiff, mgauss, msmooth, meta, metadiff, mdpdeta
-
-        @Input:
-            self: instance of ECFlexpart
-                The current object of the class.
-
-            c: instance of class ControlFile
-                Contains all the parameters of CONTROL files, which are e.g.:
-                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-                For more information about format and content of the parameter
-                see documentation.
-
-            filename: string
-                Name of the namelist file.
-
-        @Return:
-            <nothing>
-        '''
-
-        self.inputdir = c.inputdir
-        area = asarray(self.area.split('/')).astype(float)
-        grid = asarray(self.grid.split('/')).astype(float)
-
-        if area[1] > area[3]:
-            area[1] -= 360
-        zyk = abs((area[3] - area[1] - 360.) + grid[1]) < 1.e-6
-        maxl = int((area[3] - area[1]) / grid[1]) + 1
-        maxb = int((area[0] - area[2]) / grid[0]) + 1
-
-        with open(self.inputdir + '/' + filename, 'w') as f:
-            f.write('&NAMGEN\n')
-            f.write(',\n  '.join(['maxl = ' + str(maxl), 'maxb = ' + str(maxb),
-                    'mlevel = ' + self.level,
-                    'mlevelist = ' + '"' + self.levelist + '"',
-                    'mnauf = ' + self.resol, 'metapar = ' + '77',
-                    'rlo0 = ' + str(area[1]), 'rlo1 = ' + str(area[3]),
-                    'rla0 = ' + str(area[2]), 'rla1 = ' + str(area[0]),
-                    'momega = ' + c.omega, 'momegadiff = ' + c.omegadiff,
-                    'mgauss = ' + c.gauss, 'msmooth = ' + c.smooth,
-                    'meta = ' + c.eta, 'metadiff = ' + c.etadiff,
-                    'mdpdeta = ' + c.dpdeta]))
-
-            f.write('\n/\n')
-
-        return
-
-    def retrieve(self, server, dates, inputdir='.'):
-        '''
-        @Description:
-            Finalizing the retrieval information by setting final details
-            depending on grid type.
-            Prepares MARS retrievals per grid type and submits them.
-
-        @Input:
-            self: instance of ECFlexpart
-                The current object of the class.
-
-            server: instance of ECMWFService or ECMWFDataServer
-                The connection to the ECMWF server. This is different
-                for member state users which have full access and non
-                member state users which have only access to the public
-                data sets. The decision is made from command line argument
-                "public"; for public access its True (ECMWFDataServer)
-                for member state users its False (ECMWFService)
-
-            dates: string
-                Contains start and end date of the retrieval in the format
-                "YYYYMMDD/to/YYYYMMDD"
-
-            inputdir: string, optional
-                Path to the directory where the retrieved data is about
-                to be stored. The default is the current directory ('.').
-
-        @Return:
-            <nothing>
-        '''
-        self.dates = dates
-        self.server = server
-        self.inputdir = inputdir
-        oro = False
-
-        for ftype in self.types:
-            for pk, pv in self.params.iteritems():
-                if isinstance(pv, str):
-                    continue
-                mftype = '' + ftype
-                mftime = self.types[ftype]['times']
-                mfstep = self.types[ftype]['steps']
-                mfdate = self.dates
-                mfstream = self.stream
-                mftarget = self.inputdir + "/" + ftype + pk + '.' + \
-                           self.dates.split('/')[0] + '.' + str(os.getppid()) +\
-                           '.' + str(os.getpid()) + ".grb"
-                if pk == 'OG__SL':
-                    pass
-                if pk == 'OG_OROLSM__SL':
-                    if oro is False:
-                        mfstream = 'OPER'
-                        mftype = 'AN'
-                        mftime = '00'
-                        mfstep = '000'
-                        mfdate = self.dates.split('/')[0]
-                        mftarget = self.inputdir + "/" + pk + '.' + mfdate + \
-                                   '.' + str(os.getppid()) + '.' + \
-                                   str(os.getpid()) + ".grb"
-                        oro = True
-                    else:
-                        continue
-                if pk == 'GG__SL' and pv[0] == 'Q':
-                    area = ""
-                    gaussian = 'reduced'
-                else:
-                    area = self.area
-                    gaussian = self.gaussian
-
-    # ------  on demand path  --------------------------------------------------
-                if self.basetime is None:
-                    MR = MARSretrieval(self.server,
-                            marsclass=self.marsclass, stream=mfstream,
-                            type=mftype, levtype=pv[1], levelist=pv[2],
-                            resol=self.resol, gaussian=gaussian,
-                            accuracy=self.accuracy, grid=pv[3],
-                            target=mftarget, area=area, date=mfdate,
-                            time=mftime, number=self.number, step=mfstep,
-                            expver=self.expver, param=pv[0])
-
-                    MR.displayInfo()
-                    MR.dataRetrieve()
-    # ------  operational path  ------------------------------------------------
-                else:
-                    # check if mars job requests fields beyond basetime.
-                    # If yes eliminate those fields since they may not
-                    # be accessible with user's credentials
-                    if 'by' in mfstep:
-                        sm1 = 2
-                    else:
-                        sm1 = -1
-
-                    if 'by' in mftime:
-                        tm1 = 2
-                    else:
-                        tm1 = -1
-
-                    maxtime = datetime.datetime.strptime(
-                                mfdate.split('/')[-1] + mftime.split('/')[tm1],
-                                '%Y%m%d%H') + datetime.timedelta(
-                                hours=int(mfstep.split('/')[sm1]))
-                    elimit = datetime.datetime.strptime(
-                                mfdate.split('/')[-1] +
-                                self.basetime, '%Y%m%d%H')
-
-                    if self.basetime == '12':
-                        # --------------  flux data ----------------------------
-                        if 'acc' in pk:
-
-                        # Strategy:
-                        # if maxtime-elimit >= 24h reduce date by 1,
-                        # if 12h <= maxtime-elimit<12h reduce time for last date
-                        # if maxtime-elimit<12h reduce step for last time
-                        # A split of the MARS job into 2 is likely necessary.
-                            maxtime = elimit - datetime.timedelta(hours=24)
-                            mfdate = '/'.join(('/'.join(mfdate.split('/')[:-1]),
-                                                datetime.datetime.strftime(
-                                                maxtime, '%Y%m%d')))
-
-                            MR = MARSretrieval(self.server,
-                                            marsclass=self.marsclass,
-                                            stream=self.stream, type=mftype,
-                                            levtype=pv[1], levelist=pv[2],
-                                            resol=self.resol, gaussian=gaussian,
-                                            accuracy=self.accuracy, grid=pv[3],
-                                            target=mftarget, area=area,
-                                            date=mfdate, time=mftime,
-                                            number=self.number, step=mfstep,
-                                            expver=self.expver, param=pv[0])
-
-                            MR.displayInfo()
-                            MR.dataRetrieve()
-
-                            maxtime = elimit - datetime.timedelta(hours=12)
-                            mfdate = datetime.datetime.strftime(maxtime,
-                                                                '%Y%m%d')
-                            mftime = '00'
-                            mftarget = self.inputdir + "/" + ftype + pk + \
-                                       '.' + mfdate + '.' + str(os.getppid()) +\
-                                       '.' + str(os.getpid()) + ".grb"
-
-                            MR = MARSretrieval(self.server,
-                                            marsclass=self.marsclass,
-                                            stream=self.stream, type=mftype,
-                                            levtype=pv[1], levelist=pv[2],
-                                            resol=self.resol, gaussian=gaussian,
-                                            accuracy=self.accuracy, grid=pv[3],
-                                            target=mftarget, area=area,
-                                            date=mfdate, time=mftime,
-                                            number=self.number, step=mfstep,
-                                            expver=self.expver, param=pv[0])
-
-                            MR.displayInfo()
-                            MR.dataRetrieve()
-                        # --------------  non flux data ------------------------
-                        else:
-                            MR = MARSretrieval(self.server,
-                                            marsclass=self.marsclass,
-                                            stream=self.stream, type=mftype,
-                                            levtype=pv[1], levelist=pv[2],
-                                            resol=self.resol, gaussian=gaussian,
-                                            accuracy=self.accuracy, grid=pv[3],
-                                            target=mftarget, area=area,
-                                            date=mfdate, time=mftime,
-                                            number=self.number, step=mfstep,
-                                            expver=self.expver, param=pv[0])
-
-                            MR.displayInfo()
-                            MR.dataRetrieve()
-                    else: # basetime == 0 ??? #AP
-
-                        maxtime = elimit - datetime.timedelta(hours=24)
-                        mfdate = datetime.datetime.strftime(maxtime,'%Y%m%d')
-                        mftimesave = ''.join(mftime)
-
-                        if '/' in mftime:
-                            times = mftime.split('/')
-                            while ((int(times[0]) +
-                                   int(mfstep.split('/')[0]) <= 12) and
-                                  (pk != 'OG_OROLSM__SL') and 'acc' not in pk):
-                                times = times[1:]
-                            if len(times) > 1:
-                                mftime = '/'.join(times)
-                            else:
-                                mftime = times[0]
-
-                        MR = MARSretrieval(self.server,
-                                        marsclass=self.marsclass,
-                                        stream=self.stream, type=mftype,
-                                        levtype=pv[1], levelist=pv[2],
-                                        resol=self.resol, gaussian=gaussian,
-                                        accuracy=self.accuracy, grid=pv[3],
-                                        target=mftarget, area=area,
-                                        date=mfdate, time=mftime,
-                                        number=self.number, step=mfstep,
-                                        expver=self.expver, param=pv[0])
-
-                        MR.displayInfo()
-                        MR.dataRetrieve()
-
-                        if (int(mftimesave.split('/')[0]) == 0 and
-                            int(mfstep.split('/')[0]) == 0 and
-                            pk != 'OG_OROLSM__SL'):
-                            mfdate = datetime.datetime.strftime(elimit,'%Y%m%d')
-                            mftime = '00'
-                            mfstep = '000'
-                            mftarget = self.inputdir + "/" + ftype + pk + \
-                                       '.' + mfdate + '.' + str(os.getppid()) +\
-                                       '.' + str(os.getpid()) + ".grb"
-
-                            MR = MARSretrieval(self.server,
-                                        marsclass=self.marsclass,
-                                        stream=self.stream, type=mftype,
-                                        levtype=pv[1], levelist=pv[2],
-                                        resol=self.resol, gaussian=gaussian,
-                                        accuracy=self.accuracy, grid=pv[3],
-                                        target=mftarget, area=area,
-                                        date=mfdate, time=mftime,
-                                        number=self.number, step=mfstep,
-                                        expver=self.expver, param=pv[0])
-
-                            MR.displayInfo()
-                            MR.dataRetrieve()
-
-        print("MARS retrieve done... ")
-
-        return
-
-
-    def process_output(self, c):
-        '''
-        @Description:
-            The grib files are postprocessed depending on the selection in
-            CONTROL file. The resulting files are moved to the output
-            directory if its not equla to the input directory.
-            The following modifications might be done if
-            properly switched in CONTROL file:
-            GRIB2 - Conversion to GRIB2
-            ECTRANS - Transfer of files to gateway server
-            ECSTORAGE - Storage at ECMWF server
-            GRIB2FLEXPART - Conversion of GRIB files to FLEXPART binary format
-
-        @Input:
-            self: instance of ECFlexpart
-                The current object of the class.
-
-            c: instance of class ControlFile
-                Contains all the parameters of CONTROL file, which are e.g.:
-                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-                For more information about format and content of the parameter
-                see documentation.
-
-        @Return:
-            <nothing>
-
-        '''
-
-        print('\n\nPostprocessing:\n Format: {}\n'.format(c.format))
-
-        if c.ecapi is False:
-            print('ecstorage: {}\n ecfsdir: {}\n'.
-                  format(c.ecstorage, c.ecfsdir))
-            if not hasattr(c, 'gateway'):
-                c.gateway = os.getenv('GATEWAY')
-            if not hasattr(c, 'destination'):
-                c.destination = os.getenv('DESTINATION')
-            print('ectrans: {}\n gateway: {}\n destination: {}\n '
-                    .format(c.ectrans, c.gateway, c.destination))
-
-        print('Output filelist: \n')
-        print(self.outputfilelist)
-
-        if c.format.lower() == 'grib2':
-            for ofile in self.outputfilelist:
-                p = subprocess.check_call(['grib_set', '-s', 'edition=2, \
-                                            productDefinitionTemplateNumber=8',
-                                            ofile, ofile + '_2'])
-                p = subprocess.check_call(['mv', ofile + '_2', ofile])
-
-        if int(c.ectrans) == 1 and c.ecapi is False:
-            for ofile in self.outputfilelist:
-                p = subprocess.check_call(['ectrans', '-overwrite', '-gateway',
-                                            c.gateway, '-remote', c.destination,
-                                            '-source', ofile])
-                print('ectrans:', p)
-
-        if int(c.ecstorage) == 1 and c.ecapi is False:
-            for ofile in self.outputfilelist:
-                p = subprocess.check_call(['ecp', '-o', ofile,
-                                            os.path.expandvars(c.ecfsdir)])
-
-        if c.outputdir != c.inputdir:
-            for ofile in self.outputfilelist:
-                p = subprocess.check_call(['mv', ofile, c.outputdir])
-
-        # prepare environment for the grib2flexpart run
-        # to convert grib to flexpart binary
-        if c.grib2flexpart == '1':
-
-            # generate AVAILABLE file
-            # Example of AVAILABLE file data:
-            # 20131107 000000      EN13110700              ON DISC
-            clist = []
-            for ofile in self.outputfilelist:
-                fname = ofile.split('/')
-                if '.' in fname[-1]:
-                    l = fname[-1].split('.')
-                    timestamp = datetime.datetime.strptime(l[0][-6:] + l[1],
-                                                           '%y%m%d%H')
-                    timestamp += datetime.timedelta(hours=int(l[2]))
-                    cdate = datetime.datetime.strftime(timestamp, '%Y%m%d')
-                    chms = datetime.datetime.strftime(timestamp, '%H%M%S')
-                else:
-                    cdate = '20' + fname[-1][-8:-2]
-                    chms = fname[-1][-2:] + '0000'
-                clist.append(cdate + ' ' + chms + ' '*6 +
-                             fname[-1] + ' '*14 + 'ON DISC')
-            clist.sort()
-            with open(c.outputdir + '/' + 'AVAILABLE', 'w') as f:
-                f.write('\n'.join(clist) + '\n')
-
-            # generate pathnames file
-            pwd = os.path.abspath(c.outputdir)
-            with open(pwd + '/pathnames','w') as f:
-                f.write(pwd + '/Options/\n')
-                f.write(pwd + '/\n')
-                f.write(pwd + '/\n')
-                f.write(pwd + '/AVAILABLE\n')
-                f.write(' = == = == = == = == = == ==  = \n')
-
-            # create Options dir if necessary
-            if not os.path.exists(pwd + '/Options'):
-                os.makedirs(pwd+'/Options')
-
-            # read template COMMAND file
-            with open(os.path.expandvars(
-                     os.path.expanduser(c.flexpart_root_scripts)) +
-                     '/../Options/COMMAND', 'r') as f:
-                lflist = f.read().split('\n')
-
-            # find index of list where to put in the
-            # date and time information
-            # usually after the LDIRECT parameter
-            i = 0
-            for l in lflist:
-                if 'LDIRECT' in l.upper():
-                    break
-                i += 1
-
-            # insert the date and time information of run start and end
-            # into the list of lines of COMMAND file
-            lflist = lflist[:i+1] + \
-                     [clist[0][:16], clist[-1][:16]] + \
-                     lflist[i+3:]
-
-            # write the new COMMAND file
-            with open(pwd + '/Options/COMMAND', 'w') as g:
-                g.write('\n'.join(lflist) + '\n')
-
-            # change to outputdir and start the grib2flexpart run
-            # afterwards switch back to the working dir
-            os.chdir(c.outputdir)
-            p = subprocess.check_call([os.path.expandvars(
-                        os.path.expanduser(c.flexpart_root_scripts)) +
-                        '/../FLEXPART_PROGRAM/grib2flexpart',
-                        'useAvailable', '.'])
-            os.chdir(pwd)
-
-        return
-
-    def create(self, inputfiles, c):
-        '''
-        @Description:
-            This method is based on the ECMWF example index.py
-            https://software.ecmwf.int/wiki/display/GRIB/index.py
-
-            An index file will be created which depends on the combination
-            of "date", "time" and "stepRange" values. This is used to iterate
-            over all messages in each grib file which were passed through the
-            parameter "inputfiles" to seperate specific parameters into fort.*
-            files. Afterwards the FORTRAN program Convert2 is called to convert
-            the data fields all to the same grid and put them in one file
-            per unique time step (combination of "date", "time" and
-            "stepRange").
-
-        @Input:
-            self: instance of ECFlexpart
-                The current object of the class.
-
-            inputfiles: instance of UIOFiles
-                Contains a list of files.
-
-            c: instance of class ControlFile
-                Contains all the parameters of CONTROL files, which are e.g.:
-                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-                For more information about format and content of the parameter
-                see documentation.
-
-        @Return:
-            <nothing>
-        '''
-
-        table128 = init128(c.ecmwfdatadir +
-                           '/grib_templates/ecmwf_grib1_table_128')
-        wrfpars = toparamId('sp/mslp/skt/2t/10u/10v/2d/z/lsm/sst/ci/sd/\
-                            stl1/stl2/stl3/stl4/swvl1/swvl2/swvl3/swvl4',
-                            table128)
-
-        index_keys = ["date", "time", "step"]
-        indexfile = c.inputdir + "/date_time_stepRange.idx"
-        silentremove(indexfile)
-        grib = GribTools(inputfiles.files)
-        # creates new index file
-        iid = grib.index(index_keys=index_keys, index_file=indexfile)
-
-        # read values of index keys
-        index_vals = []
-        for key in index_keys:
-            index_vals.append(grib_index_get(iid, key))
-            print(index_vals[-1])
-            # index_vals looks for example like:
-            # index_vals[0]: ('20171106', '20171107', '20171108') ; date
-            # index_vals[1]: ('0', '1200', '1800', '600') ; time
-            # index_vals[2]: ('0', '12', '3', '6', '9') ; stepRange
-
-        fdict = {'10':None, '11':None, '12':None, '13':None, '16':None,
-                 '17':None, '19':None, '21':None, '22':None, '20':None}
-
-        for prod in product(*index_vals):
-            # flag for Fortran program CONVERT2, initially False
-            convertFlag = False
-            print 'current prod: ', prod
-            # e.g. prod = ('20170505', '0', '12')
-            #             (  date    ,time, step)
-            # per date e.g. time = 0, 600, 1200, 1800
-            # per time e.g. step = 0, 3, 6, 9, 12
-            for i in range(len(index_keys)):
-                grib_index_select(iid, index_keys[i], prod[i])
-
-            # get first id from current product
-            gid = grib_new_from_index(iid)
-
-            # if there is data for this product combination
-            # prepare some date and time parameter before reading the data
-            if gid is not None:
-                # Fortran program CONVERT2 is only done if gid at this time is
-                # not None, therefore save information in convertFlag
-                convertFlag = True
-                # remove old fort.* files and open new ones
-                for k, f in fdict.iteritems():
-                    silentremove(c.inputdir + "/fort." + k)
-                    fdict[k] = open(c.inputdir + '/fort.' + k, 'w')
-
-                cdate = str(grib_get(gid, 'date'))
-                time = grib_get(gid, 'time')
-                type = grib_get(gid, 'type')
-                step = grib_get(gid, 'step')
-                # create correct timestamp from the three time informations
-                # date, time, step
-                timestamp = datetime.datetime.strptime(
-                                cdate + '{:0>2}'.format(time/100), '%Y%m%d%H')
-                timestamp += datetime.timedelta(hours=int(step))
-
-                cdateH = datetime.datetime.strftime(timestamp, '%Y%m%d%H')
-                chms = datetime.datetime.strftime(timestamp, '%H%M%S')
-
-                if c.basetime is not None:
-                    slimit = datetime.datetime.strptime(
-                                c.start_date + '00', '%Y%m%d%H')
-                    bt = '23'
-                    if c.basetime == '00':
-                        bt = '00'
-                        slimit = datetime.datetime.strptime(
-                                    c.end_date + bt, '%Y%m%d%H') - \
-                                    datetime.timedelta(hours=12-int(c.dtime))
-                    if c.basetime == '12':
-                        bt = '12'
-                        slimit = datetime.datetime.strptime(
-                                    c.end_date + bt, '%Y%m%d%H') - \
-                                 datetime.timedelta(hours=12-int(c.dtime))
-
-                    elimit = datetime.datetime.strptime(
-                                c.end_date + bt, '%Y%m%d%H')
-
-                    if timestamp < slimit or timestamp > elimit:
-                        continue
-
-            try:
-                if c.wrf == '1':
-                    if 'olddate' not in locals():
-                        fwrf = open(c.outputdir + '/WRF' + cdate +
-                                    '.{:0>2}'.format(time) + '.000.grb2', 'w')
-                        olddate = cdate[:]
-                    else:
-                        if cdate != olddate:
-                            fwrf = open(c.outputdir + '/WRF' + cdate +
-                                        '.{:0>2}'.format(time) + '.000.grb2',
-                                        'w')
-                            olddate = cdate[:]
-            except AttributeError:
-                pass
-
-            # helper variable to remember which fields are already used.
-            savedfields = []
-            while 1:
-                if gid is None:
-                    break
-                paramId = grib_get(gid, 'paramId')
-                gridtype = grib_get(gid, 'gridType')
-                datatype = grib_get(gid, 'dataType')
-                levtype = grib_get(gid, 'typeOfLevel')
-                if paramId == 133 and gridtype == 'reduced_gg':
-                # Relative humidity (Q.grb) is used as a template only
-                # so we need the first we "meet"
-                    with open(c.inputdir + '/fort.18', 'w') as fout:
-                        grib_write(gid, fout)
-                elif paramId == 131 or paramId == 132:
-                    grib_write(gid, fdict['10'])
-                elif paramId == 130:
-                    grib_write(gid, fdict['11'])
-                elif paramId == 133 and gridtype != 'reduced_gg':
-                    grib_write(gid, fdict['17'])
-                elif paramId == 152:
-                    grib_write(gid, fdict['12'])
-                elif paramId == 155 and gridtype == 'sh':
-                    grib_write(gid, fdict['13'])
-                elif  paramId in [129, 138, 155] and levtype == 'hybrid' \
-                        and c.wrf == '1':
-                    pass
-                elif paramId == 246 or paramId == 247:
-                    # cloud liquid water and ice
-                    if paramId == 246:
-                        clwc = grib_get_values(gid)
-                    else:
-                        clwc += grib_get_values(gid)
-                        grib_set_values(gid, clwc)
-                        grib_set(gid, 'paramId', 201031)
-                        grib_write(gid, fdict['22'])
-                elif paramId == 135:
-                    grib_write(gid, fdict['19'])
-                elif paramId == 77:
-                    grib_write(gid, fdict['21'])
-                else:
-                    if paramId not in savedfields:
-                        grib_write(gid, fdict['16'])
-                        savedfields.append(paramId)
-                    else:
-                        print('duplicate ' + str(paramId) + ' not written')
-
-                try:
-                    if c.wrf == '1':
-                        if levtype == 'hybrid': # model layer
-                            if paramId in [129, 130, 131, 132, 133, 138, 155]:
-                                grib_write(gid, fwrf)
-                        else: # sfc layer
-                            if paramId in wrfpars:
-                                grib_write(gid, fwrf)
-                except AttributeError:
-                    pass
-
-                grib_release(gid)
-                gid = grib_new_from_index(iid)
-
-            for f in fdict.values():
-                f.close()
-
-            # call for CONVERT2 if flag is True
-            if convertFlag:
-                pwd = os.getcwd()
-                os.chdir(c.inputdir)
-                if os.stat('fort.21').st_size == 0 and int(c.eta) == 1:
-                    print('Parameter 77 (etadot) is missing, most likely it is \
-                           not available for this type or date/time\n')
-                    print('Check parameters CLASS, TYPE, STREAM, START_DATE\n')
-                    myerror(c, 'fort.21 is empty while parameter eta is set \
-                                to 1 in CONTROL file')
-
-                # create the corresponding output file fort.15
-                # (generated by CONVERT2) + fort.16 (paramId 167 and 168)
-                p = subprocess.check_call([os.path.expandvars(
-                        os.path.expanduser(c.exedir)) + '/CONVERT2'], shell=True)
-                os.chdir(pwd)
-
-                # create final output filename, e.g. EN13040500 (ENYYMMDDHH)
-                fnout = c.inputdir + '/' + c.prefix
-                if c.maxstep > 12:
-                    suffix = cdate[2:8] + '.{:0>2}'.format(time/100) + \
-                             '.{:0>3}'.format(step)
-                else:
-                    suffix = cdateH[2:10]
-                fnout += suffix
-                print("outputfile = " + fnout)
-                self.outputfilelist.append(fnout) # needed for final processing
-
-                # create outputfile and copy all data from intermediate files
-                # to the outputfile (final GRIB files)
-                orolsm = os.path.basename(glob.glob(
-                    c.inputdir + '/OG_OROLSM__SL.*.' + c.ppid + '*')[0])
-                fluxfile = 'flux' + cdate[0:2] + suffix
-                if c.cwc != '1':
-                    flist = ['fort.15', fluxfile, 'fort.16', orolsm]
-                else:
-                    flist = ['fort.15', 'fort.22', fluxfile, 'fort.16', orolsm]
-
-                with open(fnout, 'wb') as fout:
-                    for f in flist:
-                        shutil.copyfileobj(open(c.inputdir + '/' + f, 'rb'), fout)
-
-                if c.omega == '1':
-                    with open(c.outputdir + '/OMEGA', 'wb') as fout:
-                        shutil.copyfileobj(
-                            open(c.inputdir + '/fort.25', 'rb'), fout)
-
-        try:
-            if c.wrf == '1':
-                fwrf.close()
-        except:
-            pass
-
-        grib_index_release(iid)
-
-        return
-
-    def deacc_fluxes(self, inputfiles, c):
-        '''
-        @Description:
-            Goes through all flux fields in ordered time and de-accumulate
-            the fields. Afterwards the fields are disaggregated in time.
-            Different versions of disaggregation is provided for rainfall
-            data (darain, modified linear) and the surface fluxes and
-            stress data (dapoly, cubic polynomial).
-
-        @Input:
-            self: instance of ECFlexpart
-                The current object of the class.
-
-            inputfiles: instance of UIOFiles
-                Contains a list of files.
-
-            c: instance of class ControlFile
-                Contains all the parameters of CONTROL file, which are e.g.:
-                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-                For more information about format and content of the parameter
-                see documentation.
-
-        @Return:
-            <nothing>
-        '''
-
-        table128 = init128(c.ecmwfdatadir +
-                           '/grib_templates/ecmwf_grib1_table_128')
-        pars = toparamId(self.params['OG_acc_SL'][0], table128)
-        index_keys = ["date", "time", "step"]
-        indexfile = c.inputdir + "/date_time_stepRange.idx"
-        silentremove(indexfile)
-        grib = GribTools(inputfiles.files)
-        # creates new index file
-        iid = grib.index(index_keys=index_keys, index_file=indexfile)
-
-        # read values of index keys
-        index_vals = []
-        for key in index_keys:
-            key_vals = grib_index_get(iid,key)
-            print(key_vals)
-            # have to sort the steps for disaggregation,
-            # therefore convert to int first
-            if key == 'step':
-                key_vals = [int(k) for k in key_vals]
-                key_vals.sort()
-                key_vals = [str(k) for k in key_vals]
-            index_vals.append(key_vals)
-            # index_vals looks for example like:
-            # index_vals[0]: ('20171106', '20171107', '20171108') ; date
-            # index_vals[1]: ('0', '1200') ; time
-            # index_vals[2]: (3', '6', '9', '12') ; stepRange
-
-        valsdict = {}
-        svalsdict = {}
-        stepsdict = {}
-        for p in pars:
-            valsdict[str(p)] = []
-            svalsdict[str(p)] = []
-            stepsdict[str(p)] = []
-
-        for prod in product(*index_vals):
-            # e.g. prod = ('20170505', '0', '12')
-            #             (  date    ,time, step)
-            # per date e.g. time = 0, 1200
-            # per time e.g. step = 3, 6, 9, 12
-            for i in range(len(index_keys)):
-                grib_index_select(iid, index_keys[i], prod[i])
-
-            gid = grib_new_from_index(iid)
-            # do convert2 program if gid at this time is not None,
-            # therefore save in hid
-            hid = gid
-            if gid is not None:
-                cdate = grib_get(gid, 'date')
-                time = grib_get(gid, 'time')
-                type = grib_get(gid, 'type')
-                step = grib_get(gid, 'step')
-                # date+time+step-2*dtime
-                # (since interpolated value valid for step-2*dtime)
-                sdate = datetime.datetime(year=cdate/10000,
-                                          month=mod(cdate, 10000)/100,
-                                          day=mod(cdate, 100),
-                                          hour=time/100)
-                fdate = sdate + datetime.timedelta(
-                                    hours=step-2*int(c.dtime))
-                sdates = sdate + datetime.timedelta(hours=step)
-            else:
-                break
-
-            if c.maxstep > 12:
-                fnout = c.inputdir + '/flux' + \
-                    sdate.strftime('%Y%m%d') + '.{:0>2}'.format(time/100) + \
-                    '.{:0>3}'.format(step-2*int(c.dtime))
-                gnout = c.inputdir + '/flux' + \
-                    sdate.strftime('%Y%m%d') + '.{:0>2}'.format(time/100) + \
-                    '.{:0>3}'.format(step-int(c.dtime))
-                hnout = c.inputdir + '/flux' + \
-                    sdate.strftime('%Y%m%d') + '.{:0>2}'.format(time/100) + \
-                    '.{:0>3}'.format(step)
-                g = open(gnout, 'w')
-                h = open(hnout, 'w')
-            else:
-                fnout = c.inputdir + '/flux' + fdate.strftime('%Y%m%d%H')
-                gnout = c.inputdir + '/flux' + (fdate+datetime.timedelta(
-                    hours = int(c.dtime))).strftime('%Y%m%d%H')
-                hnout = c.inputdir + '/flux' + sdates.strftime('%Y%m%d%H')
-                g = open(gnout, 'w')
-                h = open(hnout, 'w')
-
-            print("outputfile = " + fnout)
-            f = open(fnout, 'w')
-
-            # read message for message and store relevant data fields
-            # data keywords are stored in pars
-            while 1:
-                if gid is None:
-                    break
-                cparamId = str(grib_get(gid, 'paramId'))
-                step = grib_get(gid, 'step')
-                atime = grib_get(gid, 'time')
-                ni = grib_get(gid, 'Ni')
-                nj = grib_get(gid, 'Nj')
-                if cparamId in valsdict.keys():
-                    values = grib_get_values(gid)
-                    vdp = valsdict[cparamId]
-                    svdp = svalsdict[cparamId]
-                    sd = stepsdict[cparamId]
-
-                    if cparamId == '142' or cparamId == '143':
-                        fak = 1. / 1000.
-                    else:
-                        fak = 3600.
-
-                    values = (reshape(values, (nj, ni))).flatten() / fak
-                    vdp.append(values[:])  # save the accumulated values
-                    if step <= int(c.dtime):
-                        svdp.append(values[:] / int(c.dtime))
-                    else:  # deaccumulate values
-                        svdp.append((vdp[-1] - vdp[-2]) / int(c.dtime))
-
-                    print(cparamId, atime, step, len(values),
-                          values[0], std(values))
-                    # save the 1/3-hourly or specific values
-                    # svdp.append(values[:])
-                    sd.append(step)
-                    # len(svdp) correspond to the time
-                    if len(svdp) >= 3:
-                        if len(svdp) > 3:
-                            if cparamId == '142' or cparamId == '143':
-                                values = Disagg.darain(svdp)
-                            else:
-                                values = Disagg.dapoly(svdp)
-
-                            if not (step == c.maxstep and c.maxstep > 12 \
-                                    or sdates == elimit):
-                                vdp.pop(0)
-                                svdp.pop(0)
-                        else:
-                            if c.maxstep > 12:
-                                values = svdp[1]
-                            else:
-                                values = svdp[0]
-
-                        grib_set_values(gid, values)
-                        if c.maxstep > 12:
-                            grib_set(gid, 'step', max(0, step-2*int(c.dtime)))
-                        else:
-                            grib_set(gid, 'step', 0)
-                            grib_set(gid, 'time', fdate.hour*100)
-                            grib_set(gid, 'date', fdate.year*10000 +
-                                     fdate.month*100+fdate.day)
-                        grib_write(gid, f)
-
-                        if c.basetime is not None:
-                            elimit = datetime.datetime.strptime(c.end_date +
-                                                                c.basetime,
-                                                                '%Y%m%d%H')
-                        else:
-                            elimit = sdate + datetime.timedelta(2*int(c.dtime))
-
-                        # squeeze out information of last two steps contained
-                        # in svdp
-                        # if step+int(c.dtime) == c.maxstep and c.maxstep>12
-                        # or sdates+datetime.timedelta(hours = int(c.dtime))
-                        # >= elimit:
-                        # Note that svdp[0] has not been popped in this case
-
-                        if (step == c.maxstep and c.maxstep > 12
-                            or sdates == elimit):
-
-                            values = svdp[3]
-                            grib_set_values(gid, values)
-                            grib_set(gid, 'step', 0)
-                            truedatetime = fdate + datetime.timedelta(
-                                     hours=2*int(c.dtime))
-                            grib_set(gid, 'time', truedatetime.hour * 100)
-                            grib_set(gid, 'date', truedatetime.year * 10000 +
-                                     truedatetime.month * 100 +
-                                     truedatetime.day)
-                            grib_write(gid, h)
-
-                            #values = (svdp[1]+svdp[2])/2.
-                            if cparamId == '142' or cparamId == '143':
-                                values = Disagg.darain(list(reversed(svdp)))
-                            else:
-                                values = Disagg.dapoly(list(reversed(svdp)))
-
-                            grib_set(gid, 'step',0)
-                            truedatetime = fdate + datetime.timedelta(
-                                     hours=int(c.dtime))
-                            grib_set(gid, 'time', truedatetime.hour * 100)
-                            grib_set(gid, 'date', truedatetime.year * 10000 +
-                                     truedatetime.month * 100 +
-                                     truedatetime.day)
-                            grib_set_values(gid, values)
-                            grib_write(gid, g)
-
-                    grib_release(gid)
-
-                    gid = grib_new_from_index(iid)
-
-            f.close()
-            g.close()
-            h.close()
-
-        grib_index_release(iid)
-
-        return
Index: python/EcFlexpart.py
===================================================================
--- python/EcFlexpart.py	(revision None)
+++ python/EcFlexpart.py	(revision None)
@@ -0,0 +1,1310 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#************************************************************************
+# ToDo AP
+# - specifiy file header documentation
+# - add class description in header information
+# - apply classtests
+# - add references to ECMWF specific software packages
+# - add describtion of deacc_fluxes
+# - change name of func deacc ( weil disagg )
+# - add desc of retrieve function
+#************************************************************************
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - extended with class Control
+#        - removed functions mkdir_p, daterange, years_between, months_between
+#        - added functions darain, dapoly, to_param_id, init128, normal_exit,
+#          my_error, clean_up, install_args_and_control,
+#          interpret_args_and_control,
+#        - removed function __del__ in class EIFLexpart
+#        - added the following functions in EIFlexpart:
+#            - create_namelist
+#            - process_output
+#            - deacc_fluxes
+#        - modified existing EIFlexpart - functions for the use in
+#          flex_extract
+#        - retrieve also longer term forecasts, not only analyses and
+#          short term forecast data
+#        - added conversion into GRIB2
+#        - added conversion into .fp format for faster execution of FLEXPART
+#          (see https://www.flexpart.eu/wiki/FpCtbtoWo4FpFormat)
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - removed function getFlexpartTime in class EcFlexpart
+#        - outsourced class ControlFile
+#        - outsourced class MarsRetrieval
+#        - changed class name from EIFlexpart to EcFlexpart
+#        - applied minor code changes (style)
+#        - removed "dead code" , e.g. retrieval of Q since it is not needed
+#        - removed "times" parameter from retrieve-method since it is not used
+#
+# @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:
+#    FLEXPART needs grib files in a specifc format. All necessary data fields
+#    for one time step are stored in a single file. The class represents an
+#    instance with all the parameter and settings necessary for retrieving
+#    MARS data and modifing them so they are fitting FLEXPART need. The class
+#    is able to disaggregate the fluxes and convert grid types to the one needed
+#    by FLEXPART, therefore using the FORTRAN program.
+#
+# @Class Content:
+#    - __init__
+#    - write_namelist
+#    - retrieve
+#    - process_output
+#    - create
+#    - deacc_fluxes
+#
+# @Class Attributes:
+#    - dtime
+#    - basetime
+#    - server
+#    - marsclass
+#    - stream
+#    - resol
+#    - accuracy
+#    - number
+#    - expver
+#    - glevelist
+#    - area
+#    - grid
+#    - level
+#    - levelist
+#    - types
+#    - dates
+#    - area
+#    - gaussian
+#    - params
+#    - inputdir
+#    - outputfilelist
+#
+#*******************************************************************************
+#pylint: disable=unsupported-assignment-operation
+# this is disabled because its an error in pylint for this specific case
+#pylint: disable=consider-using-enumerate
+# this is not useful in this case
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import subprocess
+import shutil
+import os
+import glob
+from datetime import datetime, timedelta
+import numpy as np
+from gribapi import grib_set, grib_index_select, grib_new_from_index, grib_get,\
+                    grib_write, grib_get_values, grib_set_values, grib_release,\
+                    grib_index_release, grib_index_get
+
+# software specific classes and modules from flex_extract
+from Gribtools import Gribtools
+from tools import init128, to_param_id, silent_remove, product, my_error
+from MarsRetrieval import MarsRetrieval
+import disaggregation
+
+# ------------------------------------------------------------------------------
+# CLASS
+# ------------------------------------------------------------------------------
+class EcFlexpart(object):
+    '''
+    Class to retrieve FLEXPART specific ECMWF data.
+    '''
+    # --------------------------------------------------------------------------
+    # CLASS FUNCTIONS
+    # --------------------------------------------------------------------------
+    def __init__(self, c, fluxes=False):
+        '''
+        @Description:
+            Creates an object/instance of EcFlexpart with the
+            associated settings of its attributes for the retrieval.
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL file, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+            fluxes: boolean, optional
+                Decides if a the flux parameter settings are stored or
+                the rest of the parameter list.
+                Default value is False.
+
+        @Return:
+            <nothing>
+        '''
+
+        # different mars types for retrieving data for flexpart
+        self.types = dict()
+
+        if c.maxstep > len(c.type):    # Pure forecast mode
+            c.type = [c.type[1]]
+            c.step = ['{:0>3}'.format(int(c.step[0]))]
+            c.time = [c.time[0]]
+            for i in range(1, c.maxstep + 1):
+                c.type.append(c.type[0])
+                c.step.append('{:0>3}'.format(i))
+                c.time.append(c.time[0])
+
+        self.inputdir = c.inputdir
+        self.basetime = c.basetime
+        self.dtime = c.dtime
+        i = 0
+        if fluxes is True and c.maxstep < 24:
+            # no forecast beyond one day is needed!
+            # Thus, prepare flux data manually as usual
+            # with only forecast fields with start times at 00/12
+            # (but without 00/12 fields since these are
+            # the initialisation times of the flux fields
+            # and therefore are zero all the time)
+            self.types[c.type[1]] = {'times': '00/12', 'steps':
+                                     '{}/to/12/by/{}'.format(c.dtime, c.dtime)}
+        else:
+            for ty, st, ti in zip(c.type, c.step, c.time):
+                btlist = range(24)
+                if c.basetime == '12':
+                    btlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+                if c.basetime == '00':
+                    btlist = [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0]
+
+                if i % int(c.dtime) == 0 and c.maxstep > 24 or i in btlist:
+
+                    if ty not in self.types.keys():
+                        self.types[ty] = {'times': '', 'steps': ''}
+
+                    if ti not in self.types[ty]['times']:
+                        if self.types[ty]['times']:
+                            self.types[ty]['times'] += '/'
+                        self.types[ty]['times'] += ti
+
+                    if st not in self.types[ty]['steps']:
+                        if self.types[ty]['steps']:
+                            self.types[ty]['steps'] += '/'
+                        self.types[ty]['steps'] += st
+                i += 1
+
+
+        self.marsclass = c.marsclass
+        self.stream = c.stream
+        self.number = c.number
+        self.resol = c.resol
+        self.accuracy = c.accuracy
+        self.level = c.level
+
+        if c.levelist:
+            self.levelist = c.levelist
+        else:
+            self.levelist = '1/to/' + c.level
+
+        # for gaussian grid retrieval
+        self.glevelist = '1/to/' + c.level
+
+        if c.gaussian:
+            self.gaussian = c.gaussian
+        else:
+            self.gaussian = ''
+
+        if c.expver:
+            self.expver = c.expver
+        else:
+            self.expver = '1'
+
+        if c.number:
+            self.number = c.number
+        else:
+            self.number = '0'
+
+        if 'N' in c.grid:  # Gaussian output grid
+            self.grid = c.grid
+            self.area = 'G'
+        else:
+            self.grid = '{}/{}'.format(int(c.grid) / 1000., int(c.grid) / 1000.)
+            self.area = '{}/{}/{}/{}'.format(int(c.upper) / 1000.,
+                                             int(c.left) / 1000.,
+                                             int(c.lower) / 1000.,
+                                             int(c.right) / 1000.)
+
+        self.outputfilelist = []
+
+
+        # Now comes the nasty part that deals with the different
+        # scenarios we have:
+        # 1) Calculation of etadot on
+        #    a) Gaussian grid
+        #    b) Output grid
+        #    c) Output grid using parameter 77 retrieved from MARS
+        # 3) Calculation/Retrieval of omega
+        # 4) Download also data for WRF
+
+
+        # Different grids need different retrievals
+        # SH = Spherical Harmonics, GG = Gaussian Grid,
+        # OG = Output Grid, ML = MultiLevel, SL = SingleLevel
+        self.params = {'SH__ML': '', 'SH__SL': '',
+                       'GG__ML': '', 'GG__SL': '',
+                       'OG__ML': '', 'OG__SL': '',
+                       'OG_OROLSM_SL': '', 'OG_acc_SL': ''}
+
+        if fluxes is False:
+            self.params['SH__SL'] = ['LNSP', 'ML', '1', 'OFF']
+            #                        "SD/MSL/TCC/10U/10V/2T/2D/129/172"
+            self.params['OG__SL'] = ["141/151/164/165/166/167/168/129/172", \
+                                     'SFC', '1', self.grid]
+            if c.addpar:
+                if c.addpar[0] == '/':
+                    c.addpar = c.addpar[1:]
+                self.params['OG__SL'][0] += '/' + '/'.join(c.addpar)
+
+            self.params['OG_OROLSM__SL'] = ["160/27/28/173", \
+                                            'SFC', '1', self.grid]
+
+            self.params['OG__ML'] = ['T/Q', 'ML', self.levelist, self.grid]
+
+            if c.gauss == '0' and c.eta == '1':
+                # the simplest case
+                self.params['OG__ML'][0] += '/U/V/77'
+            elif c.gauss == '0' and c.eta == '0':
+            # this is not recommended (inaccurate)
+                self.params['OG__ML'][0] += '/U/V'
+            elif c.gauss == '1' and c.eta == '0':
+                # this is needed for data before 2008, or for reanalysis data
+                self.params['GG__SL'] = ['Q', 'ML', '1', \
+                                         '{}'.format((int(self.resol) + 1) / 2)]
+                self.params['SH__ML'] = ['U/V/D', 'ML', self.glevelist, 'OFF']
+            else:
+                print 'Warning: This is a very costly parameter combination, \
+                       use only for debugging!'
+                self.params['GG__SL'] = ['Q', 'ML', '1', \
+                                         '{}'.format((int(self.resol) + 1) / 2)]
+                self.params['GG__ML'] = ['U/V/D/77', 'ML', self.glevelist, \
+                                         '{}'.format((int(self.resol) + 1) / 2)]
+
+            if c.omega == '1':
+                self.params['OG__ML'][0] += '/W'
+
+            # add cloud water content if necessary
+            if c.cwc == '1':
+                self.params['OG__ML'][0] += '/CLWC/CIWC'
+
+            # add vorticity and geopotential height for WRF if necessary
+            if c.wrf == '1':
+                self.params['OG__ML'][0] += '/Z/VO'
+                if '/D' not in self.params['OG__ML'][0]:
+                    self.params['OG__ML'][0] += '/D'
+                #wrf_sfc = 'sp/msl/skt/2t/10u/10v/2d/z/lsm/sst/ci/sd/stl1/ /
+                #           stl2/stl3/stl4/swvl1/swvl2/swvl3/swvl4'.upper()
+                wrf_sfc = '134/235/167/165/166/168/129/172/34/31/141/ \
+                           139/170/183/236/39/40/41/42'.upper()
+                lwrt_sfc = wrf_sfc.split('/')
+                for par in lwrt_sfc:
+                    if par not in self.params['OG__SL'][0]:
+                        self.params['OG__SL'][0] += '/' + par
+
+        else:
+            self.params['OG_acc_SL'] = ["LSP/CP/SSHF/EWSS/NSSS/SSR", \
+                                        'SFC', '1', self.grid]
+
+        # if needed, add additional WRF specific parameters here
+
+        return
+
+
+    def write_namelist(self, c, filename):
+        '''
+        @Description:
+            Creates a namelist file in the temporary directory and writes
+            the following values to it: maxl, maxb, mlevel,
+            mlevelist, mnauf, metapar, rlo0, rlo1, rla0, rla1,
+            momega, momegadiff, mgauss, msmooth, meta, metadiff, mdpdeta
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL files, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+            filename: string
+                Name of the namelist file.
+
+        @Return:
+            <nothing>
+        '''
+
+        self.inputdir = c.inputdir
+        area = np.asarray(self.area.split('/')).astype(float)
+        grid = np.asarray(self.grid.split('/')).astype(float)
+
+        if area[1] > area[3]:
+            area[1] -= 360
+        maxl = int((area[3] - area[1]) / grid[1]) + 1
+        maxb = int((area[0] - area[2]) / grid[0]) + 1
+
+        with open(self.inputdir + '/' + filename, 'w') as f:
+            f.write('&NAMGEN\n')
+            f.write(',\n  '.join(['maxl = ' + str(maxl), 'maxb = ' + str(maxb),
+                                  'mlevel = ' + self.level,
+                                  'mlevelist = ' + '"' + self.levelist + '"',
+                                  'mnauf = ' + self.resol,
+                                  'metapar = ' + '77',
+                                  'rlo0 = ' + str(area[1]),
+                                  'rlo1 = ' + str(area[3]),
+                                  'rla0 = ' + str(area[2]),
+                                  'rla1 = ' + str(area[0]),
+                                  'momega = ' + c.omega,
+                                  'momegadiff = ' + c.omegadiff,
+                                  'mgauss = ' + c.gauss,
+                                  'msmooth = ' + c.smooth,
+                                  'meta = ' + c.eta,
+                                  'metadiff = ' + c.etadiff,
+                                  'mdpdeta = ' + c.dpdeta]))
+
+            f.write('\n/\n')
+
+        return
+
+    def retrieve(self, server, dates, inputdir='.'):
+        '''
+        @Description:
+            Finalizing the retrieval information by setting final details
+            depending on grid type.
+            Prepares MARS retrievals per grid type and submits them.
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            server: instance of ECMWFService or ECMWFDataServer
+                The connection to the ECMWF server. This is different
+                for member state users which have full access and non
+                member state users which have only access to the public
+                data sets. The decision is made from command line argument
+                "public"; for public access its True (ECMWFDataServer)
+                for member state users its False (ECMWFService)
+
+            dates: string
+                Contains start and end date of the retrieval in the format
+                "YYYYMMDD/to/YYYYMMDD"
+
+            inputdir: string, optional
+                Path to the directory where the retrieved data is about
+                to be stored. The default is the current directory ('.').
+
+        @Return:
+            <nothing>
+        '''
+        self.dates = dates
+        self.server = server
+        self.inputdir = inputdir
+        oro = False
+
+        for ftype in self.types:
+            for pk, pv in self.params.iteritems():
+                if isinstance(pv, str):
+                    continue
+                mftype = '' + ftype
+                mftime = self.types[ftype]['times']
+                mfstep = self.types[ftype]['steps']
+                mfdate = self.dates
+                mfstream = self.stream
+                mftarget = self.inputdir + "/" + ftype + pk + '.' + \
+                           self.dates.split('/')[0] + '.' + str(os.getppid()) +\
+                           '.' + str(os.getpid()) + ".grb"
+                if pk == 'OG__SL':
+                    pass
+                if pk == 'OG_OROLSM__SL':
+                    if oro is False:
+                        mfstream = 'OPER'
+                        mftype = 'AN'
+                        mftime = '00'
+                        mfstep = '000'
+                        mfdate = self.dates.split('/')[0]
+                        mftarget = self.inputdir + "/" + pk + '.' + mfdate + \
+                                   '.' + str(os.getppid()) + '.' + \
+                                   str(os.getpid()) + ".grb"
+                        oro = True
+                    else:
+                        continue
+                if pk == 'GG__SL' and pv[0] == 'Q':
+                    area = ""
+                    gaussian = 'reduced'
+                else:
+                    area = self.area
+                    gaussian = self.gaussian
+
+    # ------  on demand path  --------------------------------------------------
+                if self.basetime is None:
+                    MR = MarsRetrieval(self.server,
+                                       marsclass=self.marsclass,
+                                       stream=mfstream,
+                                       type=mftype,
+                                       levtype=pv[1],
+                                       levelist=pv[2],
+                                       resol=self.resol,
+                                       gaussian=gaussian,
+                                       accuracy=self.accuracy,
+                                       grid=pv[3],
+                                       target=mftarget,
+                                       area=area,
+                                       date=mfdate,
+                                       time=mftime,
+                                       number=self.number,
+                                       step=mfstep,
+                                       expver=self.expver,
+                                       param=pv[0])
+
+                    MR.display_info()
+                    MR.data_retrieve()
+    # ------  operational path  ------------------------------------------------
+                else:
+                    # check if mars job requests fields beyond basetime.
+                    # If yes eliminate those fields since they may not
+                    # be accessible with user's credentials
+                    if 'by' in mfstep:
+                        sm1 = 2
+                    else:
+                        sm1 = -1
+
+                    if 'by' in mftime:
+                        tm1 = 2
+                    else:
+                        tm1 = -1
+
+                    maxdate = datetime.strptime(mfdate.split('/')[-1] +
+                                                mftime.split('/')[tm1],
+                                                '%Y%m%d%H')
+                    istep = int(mfstep.split('/')[sm1])
+                    maxtime = maxdate + timedelta(hours=istep)
+
+                    elimit = datetime.strptime(mfdate.split('/')[-1] +
+                                               self.basetime, '%Y%m%d%H')
+
+                    if self.basetime == '12':
+                        # --------------  flux data ----------------------------
+                        if 'acc' in pk:
+
+                        # Strategy:
+                        # if maxtime-elimit >= 24h reduce date by 1,
+                        # if 12h <= maxtime-elimit<12h reduce time for last date
+                        # if maxtime-elimit<12h reduce step for last time
+                        # A split of the MARS job into 2 is likely necessary.
+                            maxtime = elimit - timedelta(hours=24)
+                            mfdate = '/'.join(['/'.join(mfdate.split('/')[:-1]),
+                                               datetime.strftime(maxtime,
+                                                                 '%Y%m%d')])
+
+                            MR = MarsRetrieval(self.server,
+                                               marsclass=self.marsclass,
+                                               stream=self.stream,
+                                               type=mftype,
+                                               levtype=pv[1],
+                                               levelist=pv[2],
+                                               resol=self.resol,
+                                               gaussian=gaussian,
+                                               accuracy=self.accuracy,
+                                               grid=pv[3],
+                                               target=mftarget,
+                                               area=area,
+                                               date=mfdate,
+                                               time=mftime,
+                                               number=self.number,
+                                               step=mfstep,
+                                               expver=self.expver,
+                                               param=pv[0])
+
+                            MR.display_info()
+                            MR.data_retrieve()
+
+                            maxtime = elimit - timedelta(hours=12)
+                            mfdate = datetime.strftime(maxtime, '%Y%m%d')
+                            mftime = '00'
+                            mftarget = self.inputdir + "/" + ftype + pk + \
+                                       '.' + mfdate + '.' + str(os.getppid()) +\
+                                       '.' + str(os.getpid()) + ".grb"
+
+                            MR = MarsRetrieval(self.server,
+                                               marsclass=self.marsclass,
+                                               stream=self.stream,
+                                               type=mftype,
+                                               levtype=pv[1],
+                                               levelist=pv[2],
+                                               resol=self.resol,
+                                               gaussian=gaussian,
+                                               accuracy=self.accuracy,
+                                               grid=pv[3],
+                                               target=mftarget,
+                                               area=area,
+                                               date=mfdate,
+                                               time=mftime,
+                                               number=self.number,
+                                               step=mfstep,
+                                               expver=self.expver,
+                                               param=pv[0])
+
+                            MR.display_info()
+                            MR.data_retrieve()
+                        # --------------  non flux data ------------------------
+                        else:
+                            MR = MarsRetrieval(self.server,
+                                               marsclass=self.marsclass,
+                                               stream=self.stream,
+                                               type=mftype,
+                                               levtype=pv[1],
+                                               levelist=pv[2],
+                                               resol=self.resol,
+                                               gaussian=gaussian,
+                                               accuracy=self.accuracy,
+                                               grid=pv[3],
+                                               target=mftarget,
+                                               area=area,
+                                               date=mfdate,
+                                               time=mftime,
+                                               number=self.number,
+                                               step=mfstep,
+                                               expver=self.expver,
+                                               param=pv[0])
+
+                            MR.display_info()
+                            MR.data_retrieve()
+                    else: # basetime == 0 ??? #AP
+
+                        maxtime = elimit - timedelta(hours=24)
+                        mfdate = datetime.strftime(maxtime, '%Y%m%d')
+                        mftimesave = ''.join(mftime)
+
+                        if '/' in mftime:
+                            times = mftime.split('/')
+                            while ((int(times[0]) +
+                                    int(mfstep.split('/')[0]) <= 12) and
+                                   (pk != 'OG_OROLSM__SL') and 'acc' not in pk):
+                                times = times[1:]
+                            if len(times) > 1:
+                                mftime = '/'.join(times)
+                            else:
+                                mftime = times[0]
+
+                        MR = MarsRetrieval(self.server,
+                                           marsclass=self.marsclass,
+                                           stream=self.stream,
+                                           type=mftype,
+                                           levtype=pv[1],
+                                           levelist=pv[2],
+                                           resol=self.resol,
+                                           gaussian=gaussian,
+                                           accuracy=self.accuracy,
+                                           grid=pv[3],
+                                           target=mftarget,
+                                           area=area,
+                                           date=mfdate,
+                                           time=mftime,
+                                           number=self.number,
+                                           step=mfstep,
+                                           expver=self.expver,
+                                           param=pv[0])
+
+                        MR.display_info()
+                        MR.data_retrieve()
+
+                        if (int(mftimesave.split('/')[0]) == 0 and
+                                int(mfstep.split('/')[0]) == 0 and
+                                pk != 'OG_OROLSM__SL'):
+
+                            mfdate = datetime.strftime(elimit, '%Y%m%d')
+                            mftime = '00'
+                            mfstep = '000'
+                            mftarget = self.inputdir + "/" + ftype + pk + \
+                                       '.' + mfdate + '.' + str(os.getppid()) +\
+                                       '.' + str(os.getpid()) + ".grb"
+
+                            MR = MarsRetrieval(self.server,
+                                               marsclass=self.marsclass,
+                                               stream=self.stream,
+                                               type=mftype,
+                                               levtype=pv[1],
+                                               levelist=pv[2],
+                                               resol=self.resol,
+                                               gaussian=gaussian,
+                                               accuracy=self.accuracy,
+                                               grid=pv[3],
+                                               target=mftarget,
+                                               area=area,
+                                               date=mfdate,
+                                               time=mftime,
+                                               number=self.number,
+                                               step=mfstep,
+                                               expver=self.expver,
+                                               param=pv[0])
+
+                            MR.display_info()
+                            MR.data_retrieve()
+
+        print "MARS retrieve done... "
+
+        return
+
+
+    def process_output(self, c):
+        '''
+        @Description:
+            The grib files are postprocessed depending on the selection in
+            CONTROL file. The resulting files are moved to the output
+            directory if its not equla to the input directory.
+            The following modifications might be done if
+            properly switched in CONTROL file:
+            GRIB2 - Conversion to GRIB2
+            ECTRANS - Transfer of files to gateway server
+            ECSTORAGE - Storage at ECMWF server
+            GRIB2FLEXPART - Conversion of GRIB files to FLEXPART binary format
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL file, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+        @Return:
+            <nothing>
+
+        '''
+
+        print '\n\nPostprocessing:\n Format: {}\n'.format(c.format)
+
+        if c.ecapi is False:
+            print('ecstorage: {}\n ecfsdir: {}\n'.
+                  format(c.ecstorage, c.ecfsdir))
+            if not hasattr(c, 'gateway'):
+                c.gateway = os.getenv('GATEWAY')
+            if not hasattr(c, 'destination'):
+                c.destination = os.getenv('DESTINATION')
+            print('ectrans: {}\n gateway: {}\n destination: {}\n '
+                  .format(c.ectrans, c.gateway, c.destination))
+
+        print 'Output filelist: \n'
+        print self.outputfilelist
+
+        if c.format.lower() == 'grib2':
+            for ofile in self.outputfilelist:
+                p = subprocess.check_call(['grib_set', '-s', 'edition=2, \
+                                           productDefinitionTemplateNumber=8',
+                                           ofile, ofile + '_2'])
+                p = subprocess.check_call(['mv', ofile + '_2', ofile])
+
+        if int(c.ectrans) == 1 and c.ecapi is False:
+            for ofile in self.outputfilelist:
+                p = subprocess.check_call(['ectrans', '-overwrite', '-gateway',
+                                           c.gateway, '-remote', c.destination,
+                                           '-source', ofile])
+                print('ectrans:', p)
+
+        if int(c.ecstorage) == 1 and c.ecapi is False:
+            for ofile in self.outputfilelist:
+                p = subprocess.check_call(['ecp', '-o', ofile,
+                                           os.path.expandvars(c.ecfsdir)])
+
+        if c.outputdir != c.inputdir:
+            for ofile in self.outputfilelist:
+                p = subprocess.check_call(['mv', ofile, c.outputdir])
+
+        # prepare environment for the grib2flexpart run
+        # to convert grib to flexpart binary
+        if c.grib2flexpart == '1':
+
+            # generate AVAILABLE file
+            # Example of AVAILABLE file data:
+            # 20131107 000000      EN13110700              ON DISC
+            clist = []
+            for ofile in self.outputfilelist:
+                fname = ofile.split('/')
+                if '.' in fname[-1]:
+                    l = fname[-1].split('.')
+                    timestamp = datetime.strptime(l[0][-6:] + l[1],
+                                                  '%y%m%d%H')
+                    timestamp += timedelta(hours=int(l[2]))
+                    cdate = datetime.strftime(timestamp, '%Y%m%d')
+                    chms = datetime.strftime(timestamp, '%H%M%S')
+                else:
+                    cdate = '20' + fname[-1][-8:-2]
+                    chms = fname[-1][-2:] + '0000'
+                clist.append(cdate + ' ' + chms + ' '*6 +
+                             fname[-1] + ' '*14 + 'ON DISC')
+            clist.sort()
+            with open(c.outputdir + '/' + 'AVAILABLE', 'w') as f:
+                f.write('\n'.join(clist) + '\n')
+
+            # generate pathnames file
+            pwd = os.path.abspath(c.outputdir)
+            with open(pwd + '/pathnames', 'w') as f:
+                f.write(pwd + '/Options/\n')
+                f.write(pwd + '/\n')
+                f.write(pwd + '/\n')
+                f.write(pwd + '/AVAILABLE\n')
+                f.write(' = == = == = == = == = == ==  = \n')
+
+            # create Options dir if necessary
+            if not os.path.exists(pwd + '/Options'):
+                os.makedirs(pwd+'/Options')
+
+            # read template COMMAND file
+            with open(os.path.expandvars(os.path.expanduser(
+                c.flexpart_root_scripts)) + '/../Options/COMMAND', 'r') as f:
+                lflist = f.read().split('\n')
+
+            # find index of list where to put in the
+            # date and time information
+            # usually after the LDIRECT parameter
+            i = 0
+            for l in lflist:
+                if 'LDIRECT' in l.upper():
+                    break
+                i += 1
+
+            # insert the date and time information of run start and end
+            # into the list of lines of COMMAND file
+            lflist = lflist[:i+1] + \
+                     [clist[0][:16], clist[-1][:16]] + \
+                     lflist[i+3:]
+
+            # write the new COMMAND file
+            with open(pwd + '/Options/COMMAND', 'w') as g:
+                g.write('\n'.join(lflist) + '\n')
+
+            # change to outputdir and start the grib2flexpart run
+            # afterwards switch back to the working dir
+            os.chdir(c.outputdir)
+            p = subprocess.check_call([
+                os.path.expandvars(os.path.expanduser(c.flexpart_root_scripts))
+                + '/../FLEXPART_PROGRAM/grib2flexpart', 'useAvailable', '.'])
+            os.chdir(pwd)
+
+        return
+
+    def create(self, inputfiles, c):
+        '''
+        @Description:
+            This method is based on the ECMWF example index.py
+            https://software.ecmwf.int/wiki/display/GRIB/index.py
+
+            An index file will be created which depends on the combination
+            of "date", "time" and "stepRange" values. This is used to iterate
+            over all messages in each grib file which were passed through the
+            parameter "inputfiles" to seperate specific parameters into fort.*
+            files. Afterwards the FORTRAN program Convert2 is called to convert
+            the data fields all to the same grid and put them in one file
+            per unique time step (combination of "date", "time" and
+            "stepRange").
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            inputfiles: instance of UioFiles
+                Contains a list of files.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL files, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+        @Return:
+            <nothing>
+        '''
+
+        table128 = init128(c.ecmwfdatadir +
+                           '/grib_templates/ecmwf_grib1_table_128')
+        wrfpars = to_param_id('sp/mslp/skt/2t/10u/10v/2d/z/lsm/sst/ci/sd/\
+                            stl1/stl2/stl3/stl4/swvl1/swvl2/swvl3/swvl4',
+                            table128)
+
+        index_keys = ["date", "time", "step"]
+        indexfile = c.inputdir + "/date_time_stepRange.idx"
+        silent_remove(indexfile)
+        grib = Gribtools(inputfiles.files)
+        # creates new index file
+        iid = grib.index(index_keys=index_keys, index_file=indexfile)
+
+        # read values of index keys
+        index_vals = []
+        for key in index_keys:
+            index_vals.append(grib_index_get(iid, key))
+            print index_vals[-1]
+            # index_vals looks for example like:
+            # index_vals[0]: ('20171106', '20171107', '20171108') ; date
+            # index_vals[1]: ('0', '1200', '1800', '600') ; time
+            # index_vals[2]: ('0', '12', '3', '6', '9') ; stepRange
+
+        fdict = {'10':None, '11':None, '12':None, '13':None, '16':None,
+                 '17':None, '19':None, '21':None, '22':None, '20':None}
+
+        for prod in product(*index_vals):
+            # flag for Fortran program CONVERT2, initially False
+            convertFlag = False
+            print 'current prod: ', prod
+            # e.g. prod = ('20170505', '0', '12')
+            #             (  date    ,time, step)
+            # per date e.g. time = 0, 600, 1200, 1800
+            # per time e.g. step = 0, 3, 6, 9, 12
+            for i in range(len(index_keys)):
+                grib_index_select(iid, index_keys[i], prod[i])
+
+            # get first id from current product
+            gid = grib_new_from_index(iid)
+
+            # if there is data for this product combination
+            # prepare some date and time parameter before reading the data
+            if gid is not None:
+                # Fortran program CONVERT2 is only done if gid at this time is
+                # not None, therefore save information in convertFlag
+                convertFlag = True
+                # remove old fort.* files and open new ones
+                for k, f in fdict.iteritems():
+                    silent_remove(c.inputdir + "/fort." + k)
+                    fdict[k] = open(c.inputdir + '/fort.' + k, 'w')
+
+                cdate = str(grib_get(gid, 'date'))
+                time = grib_get(gid, 'time')
+                step = grib_get(gid, 'step')
+                # create correct timestamp from the three time informations
+                # date, time, step
+                timestamp = datetime.strptime(cdate + '{:0>2}'.format(time/100),
+                                              '%Y%m%d%H')
+                timestamp += timedelta(hours=int(step))
+
+                cdateH = datetime.strftime(timestamp, '%Y%m%d%H')
+
+                if c.basetime is not None:
+                    slimit = datetime.strptime(c.start_date + '00', '%Y%m%d%H')
+                    bt = '23'
+                    if c.basetime == '00':
+                        bt = '00'
+                        slimit = datetime.strptime(c.end_date + bt, '%Y%m%d%H')\
+                            - timedelta(hours=12-int(c.dtime))
+                    if c.basetime == '12':
+                        bt = '12'
+                        slimit = datetime.strptime(c.end_date + bt, '%Y%m%d%H')\
+                            - timedelta(hours=12-int(c.dtime))
+
+                    elimit = datetime.strptime(c.end_date + bt, '%Y%m%d%H')
+
+                    if timestamp < slimit or timestamp > elimit:
+                        continue
+
+            try:
+                if c.wrf == '1':
+                    if 'olddate' not in locals():
+                        fwrf = open(c.outputdir + '/WRF' + cdate +
+                                    '.{:0>2}'.format(time) + '.000.grb2', 'w')
+                        olddate = cdate[:]
+                    else:
+                        if cdate != olddate:
+                            fwrf = open(c.outputdir + '/WRF' + cdate +
+                                        '.{:0>2}'.format(time) + '.000.grb2',
+                                        'w')
+                            olddate = cdate[:]
+            except AttributeError:
+                pass
+
+            # helper variable to remember which fields are already used.
+            savedfields = []
+            while 1:
+                if gid is None:
+                    break
+                paramId = grib_get(gid, 'paramId')
+                gridtype = grib_get(gid, 'gridType')
+                levtype = grib_get(gid, 'typeOfLevel')
+                if paramId == 133 and gridtype == 'reduced_gg':
+                # Relative humidity (Q.grb) is used as a template only
+                # so we need the first we "meet"
+                    with open(c.inputdir + '/fort.18', 'w') as fout:
+                        grib_write(gid, fout)
+                elif paramId == 131 or paramId == 132:
+                    grib_write(gid, fdict['10'])
+                elif paramId == 130:
+                    grib_write(gid, fdict['11'])
+                elif paramId == 133 and gridtype != 'reduced_gg':
+                    grib_write(gid, fdict['17'])
+                elif paramId == 152:
+                    grib_write(gid, fdict['12'])
+                elif paramId == 155 and gridtype == 'sh':
+                    grib_write(gid, fdict['13'])
+                elif  paramId in [129, 138, 155] and levtype == 'hybrid' \
+                        and c.wrf == '1':
+                    pass
+                elif paramId == 246 or paramId == 247:
+                    # cloud liquid water and ice
+                    if paramId == 246:
+                        clwc = grib_get_values(gid)
+                    else:
+                        clwc += grib_get_values(gid)
+                        grib_set_values(gid, clwc)
+                        grib_set(gid, 'paramId', 201031)
+                        grib_write(gid, fdict['22'])
+                elif paramId == 135:
+                    grib_write(gid, fdict['19'])
+                elif paramId == 77:
+                    grib_write(gid, fdict['21'])
+                else:
+                    if paramId not in savedfields:
+                        grib_write(gid, fdict['16'])
+                        savedfields.append(paramId)
+                    else:
+                        print 'duplicate ' + str(paramId) + ' not written'
+
+                try:
+                    if c.wrf == '1':
+                        if levtype == 'hybrid': # model layer
+                            if paramId in [129, 130, 131, 132, 133, 138, 155]:
+                                grib_write(gid, fwrf)
+                        else: # sfc layer
+                            if paramId in wrfpars:
+                                grib_write(gid, fwrf)
+                except AttributeError:
+                    pass
+
+                grib_release(gid)
+                gid = grib_new_from_index(iid)
+
+            for f in fdict.values():
+                f.close()
+
+            # call for CONVERT2 if flag is True
+            if convertFlag:
+                pwd = os.getcwd()
+                os.chdir(c.inputdir)
+                if os.stat('fort.21').st_size == 0 and int(c.eta) == 1:
+                    print 'Parameter 77 (etadot) is missing, most likely it is \
+                           not available for this type or date/time\n'
+                    print 'Check parameters CLASS, TYPE, STREAM, START_DATE\n'
+                    my_error(c, 'fort.21 is empty while parameter eta is set \
+                                to 1 in CONTROL file')
+
+                # create the corresponding output file fort.15
+                # (generated by CONVERT2) + fort.16 (paramId 167 and 168)
+                p = subprocess.check_call(
+                    [os.path.expandvars(os.path.expanduser(c.exedir)) +
+                     '/CONVERT2'], shell=True)
+                os.chdir(pwd)
+
+                # create final output filename, e.g. EN13040500 (ENYYMMDDHH)
+                fnout = c.inputdir + '/' + c.prefix
+                if c.maxstep > 12:
+                    suffix = cdate[2:8] + '.{:0>2}'.format(time/100) + \
+                             '.{:0>3}'.format(step)
+                else:
+                    suffix = cdateH[2:10]
+                fnout += suffix
+                print "outputfile = " + fnout
+                self.outputfilelist.append(fnout) # needed for final processing
+
+                # create outputfile and copy all data from intermediate files
+                # to the outputfile (final GRIB files)
+                orolsm = os.path.basename(glob.glob(
+                    c.inputdir + '/OG_OROLSM__SL.*.' + c.ppid + '*')[0])
+                fluxfile = 'flux' + cdate[0:2] + suffix
+                if c.cwc != '1':
+                    flist = ['fort.15', fluxfile, 'fort.16', orolsm]
+                else:
+                    flist = ['fort.15', 'fort.22', fluxfile, 'fort.16', orolsm]
+
+                with open(fnout, 'wb') as fout:
+                    for f in flist:
+                        shutil.copyfileobj(open(c.inputdir + '/' + f, 'rb'), fout)
+
+                if c.omega == '1':
+                    with open(c.outputdir + '/OMEGA', 'wb') as fout:
+                        shutil.copyfileobj(
+                            open(c.inputdir + '/fort.25', 'rb'), fout)
+
+        if c.wrf == '1':
+            fwrf.close()
+
+        grib_index_release(iid)
+
+        return
+
+    def deacc_fluxes(self, inputfiles, c):
+        '''
+        @Description:
+            Goes through all flux fields in ordered time and de-accumulate
+            the fields. Afterwards the fields are disaggregated in time.
+            Different versions of disaggregation is provided for rainfall
+            data (darain, modified linear) and the surface fluxes and
+            stress data (dapoly, cubic polynomial).
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            inputfiles: instance of UioFiles
+                Contains a list of files.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL file, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+        @Return:
+            <nothing>
+        '''
+
+        table128 = init128(c.ecmwfdatadir +
+                           '/grib_templates/ecmwf_grib1_table_128')
+        pars = to_param_id(self.params['OG_acc_SL'][0], table128)
+        index_keys = ["date", "time", "step"]
+        indexfile = c.inputdir + "/date_time_stepRange.idx"
+        silent_remove(indexfile)
+        grib = Gribtools(inputfiles.files)
+        # creates new index file
+        iid = grib.index(index_keys=index_keys, index_file=indexfile)
+
+        # read values of index keys
+        index_vals = []
+        for key in index_keys:
+            key_vals = grib_index_get(iid, key)
+            print key_vals
+            # have to sort the steps for disaggregation,
+            # therefore convert to int first
+            if key == 'step':
+                key_vals = [int(k) for k in key_vals]
+                key_vals.sort()
+                key_vals = [str(k) for k in key_vals]
+            index_vals.append(key_vals)
+            # index_vals looks for example like:
+            # index_vals[0]: ('20171106', '20171107', '20171108') ; date
+            # index_vals[1]: ('0', '1200') ; time
+            # index_vals[2]: (3', '6', '9', '12') ; stepRange
+
+        valsdict = {}
+        svalsdict = {}
+        stepsdict = {}
+        for p in pars:
+            valsdict[str(p)] = []
+            svalsdict[str(p)] = []
+            stepsdict[str(p)] = []
+
+        print 'maxstep: ', c.maxstep
+
+        for prod in product(*index_vals):
+            # e.g. prod = ('20170505', '0', '12')
+            #             (  date    ,time, step)
+            # per date e.g. time = 0, 1200
+            # per time e.g. step = 3, 6, 9, 12
+            for i in range(len(index_keys)):
+                grib_index_select(iid, index_keys[i], prod[i])
+
+            gid = grib_new_from_index(iid)
+            if gid is not None:
+                cdate = grib_get(gid, 'date')
+                time = grib_get(gid, 'time')
+                step = grib_get(gid, 'step')
+                # date+time+step-2*dtime
+                # (since interpolated value valid for step-2*dtime)
+                sdate = datetime(year=cdate/10000,
+                                 month=(cdate % 10000)/100,
+                                 day=(cdate % 100),
+                                 hour=time/100)
+                fdate = sdate + timedelta(hours=step-2*int(c.dtime))
+                sdates = sdate + timedelta(hours=step)
+                elimit = None
+            else:
+                break
+
+            if c.maxstep > 12:
+                fnout = c.inputdir + '/flux' + \
+                    sdate.strftime('%Y%m%d') + '.{:0>2}'.format(time/100) + \
+                    '.{:0>3}'.format(step-2*int(c.dtime))
+                gnout = c.inputdir + '/flux' + \
+                    sdate.strftime('%Y%m%d') + '.{:0>2}'.format(time/100) + \
+                    '.{:0>3}'.format(step-int(c.dtime))
+                hnout = c.inputdir + '/flux' + \
+                    sdate.strftime('%Y%m%d') + '.{:0>2}'.format(time/100) + \
+                    '.{:0>3}'.format(step)
+                g = open(gnout, 'w')
+                h = open(hnout, 'w')
+            else:
+                fnout = c.inputdir + '/flux' + fdate.strftime('%Y%m%d%H')
+                gnout = c.inputdir + '/flux' + (fdate +
+                                                timedelta(hours=int(c.dtime))
+                                               ).strftime('%Y%m%d%H')
+                hnout = c.inputdir + '/flux' + sdates.strftime('%Y%m%d%H')
+                g = open(gnout, 'w')
+                h = open(hnout, 'w')
+
+            print "outputfile = " + fnout
+            f = open(fnout, 'w')
+
+            # read message for message and store relevant data fields
+            # data keywords are stored in pars
+            while 1:
+                if gid is None:
+                    break
+                cparamId = str(grib_get(gid, 'paramId'))
+                step = grib_get(gid, 'step')
+                atime = grib_get(gid, 'time')
+                ni = grib_get(gid, 'Ni')
+                nj = grib_get(gid, 'Nj')
+                if cparamId in valsdict.keys():
+                    values = grib_get_values(gid)
+                    vdp = valsdict[cparamId]
+                    svdp = svalsdict[cparamId]
+                    sd = stepsdict[cparamId]
+
+                    if cparamId == '142' or cparamId == '143':
+                        fak = 1. / 1000.
+                    else:
+                        fak = 3600.
+
+                    values = (np.reshape(values, (nj, ni))).flatten() / fak
+                    vdp.append(values[:])  # save the accumulated values
+                    if step <= int(c.dtime):
+                        svdp.append(values[:] / int(c.dtime))
+                    else:  # deaccumulate values
+                        svdp.append((vdp[-1] - vdp[-2]) / int(c.dtime))
+
+                    print(cparamId, atime, step, len(values),
+                          values[0], np.std(values))
+                    # save the 1/3-hourly or specific values
+                    # svdp.append(values[:])
+                    sd.append(step)
+                    # len(svdp) correspond to the time
+                    if len(svdp) >= 3:
+                        if len(svdp) > 3:
+                            if cparamId == '142' or cparamId == '143':
+                                values = disaggregation.darain(svdp)
+                            else:
+                                values = disaggregation.dapoly(svdp)
+
+                            if not (step == c.maxstep and c.maxstep > 12 \
+                                    or sdates == elimit):
+                                vdp.pop(0)
+                                svdp.pop(0)
+                        else:
+                            if c.maxstep > 12:
+                                values = svdp[1]
+                            else:
+                                values = svdp[0]
+
+                        grib_set_values(gid, values)
+                        if c.maxstep > 12:
+                            grib_set(gid, 'step', max(0, step-2*int(c.dtime)))
+                        else:
+                            grib_set(gid, 'step', 0)
+                            grib_set(gid, 'time', fdate.hour*100)
+                            grib_set(gid, 'date', fdate.year*10000 +
+                                     fdate.month*100+fdate.day)
+                        grib_write(gid, f)
+
+                        if c.basetime is not None:
+                            elimit = datetime.strptime(c.end_date +
+                                                       c.basetime, '%Y%m%d%H')
+                        else:
+                            elimit = sdate + timedelta(2*int(c.dtime))
+
+                        # squeeze out information of last two steps contained
+                        # in svdp
+                        # if step+int(c.dtime) == c.maxstep and c.maxstep>12
+                        # or sdates+timedelta(hours = int(c.dtime))
+                        # >= elimit:
+                        # Note that svdp[0] has not been popped in this case
+
+                        if step == c.maxstep and c.maxstep > 12 or \
+                           sdates == elimit:
+
+                            values = svdp[3]
+                            grib_set_values(gid, values)
+                            grib_set(gid, 'step', 0)
+                            truedatetime = fdate + timedelta(hours=
+                                                             2*int(c.dtime))
+                            grib_set(gid, 'time', truedatetime.hour * 100)
+                            grib_set(gid, 'date', truedatetime.year * 10000 +
+                                     truedatetime.month * 100 +
+                                     truedatetime.day)
+                            grib_write(gid, h)
+
+                            #values = (svdp[1]+svdp[2])/2.
+                            if cparamId == '142' or cparamId == '143':
+                                values = disaggregation.darain(list(reversed(svdp)))
+                            else:
+                                values = disaggregation.dapoly(list(reversed(svdp)))
+
+                            grib_set(gid, 'step', 0)
+                            truedatetime = fdate + timedelta(hours=int(c.dtime))
+                            grib_set(gid, 'time', truedatetime.hour * 100)
+                            grib_set(gid, 'date', truedatetime.year * 10000 +
+                                     truedatetime.month * 100 +
+                                     truedatetime.day)
+                            grib_set_values(gid, values)
+                            grib_write(gid, g)
+
+                    grib_release(gid)
+
+                    gid = grib_new_from_index(iid)
+
+            f.close()
+            g.close()
+            h.close()
+
+        grib_index_release(iid)
+
+        exit()
+        return
Index: python/GribTools.py
===================================================================
--- python/GribTools.py	(revision ccab8091e3f70844b2b6e73b9aa5e6b41aaf5ff5)
+++ python/GribTools.py	(revision ff99eae65dfaeec1221e06572d770ebd48feb3f4)
@@ -1,10 +1,4 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-# - GribTools name möglicherweise etwas verwirrend.
-# - change self.filename in self.filenames!!!
-# - bis auf --init-- und index wird keine Funktion verwendet!?
-#************************************************************************
 #*******************************************************************************
 # @Author: Anne Fouilloux (University of Oslo)
@@ -36,8 +30,11 @@
 # @Class Content:
 #    - __init__
-#    - getkeys
-#    - setkeys
+#    - get_keys
+#    - set_keys
 #    - copy
 #    - index
+#
+# @Class Attributes:
+#    - filenames
 #
 #*******************************************************************************
@@ -47,10 +44,13 @@
 # ------------------------------------------------------------------------------
 import os
-from gribapi import *
+from gribapi import grib_new_from_file, grib_is_defined, grib_get, \
+                    grib_release, grib_set, grib_write, grib_index_read, \
+                    grib_index_new_from_file, grib_index_add_file,  \
+                    grib_index_write
 
 # ------------------------------------------------------------------------------
 # CLASS
 # ------------------------------------------------------------------------------
-class GribTools:
+class Gribtools(object):
     '''
     Class for GRIB utilities (new methods) based on GRIB API
@@ -62,5 +62,5 @@
         '''
         @Description:
-            Initialise an object of GribTools and assign a list
+            Initialise an object of Gribtools and assign a list
             of filenames.
 
@@ -73,10 +73,10 @@
         '''
 
-        self.filename = filenames
+        self.filenames = filenames
 
         return
 
 
-    def getkeys(self, keynames, wherekeynames=[], wherekeyvalues=[]):
+    def get_keys(self, keynames, wherekeynames=[], wherekeyvalues=[]):
         '''
         @Description:
@@ -88,8 +88,8 @@
                 List of keynames.
 
-            wherekeynames: list of ???, optional
+            wherekeynames: list of strings, optional
                 Default value is an empty list.
 
-            wherekeyvalues: list of ???, optional
+            wherekeyvalues: list of strings, optional
                 Default value is an empty list.
 
@@ -99,5 +99,5 @@
         '''
 
-        fileid = open(self.filename, 'r')
+        fileid = open(self.filenames, 'r')
 
         return_list = []
@@ -136,6 +136,6 @@
 
 
-    def setkeys(self, fromfile, keynames, keyvalues, wherekeynames=[],
-                wherekeyvalues=[], strict=False, filemode='w'):
+    def set_keys(self, fromfile, keynames, keyvalues, wherekeynames=[],
+                 wherekeyvalues=[], strict=False, filemode='w'):
         '''
         @Description:
@@ -150,14 +150,14 @@
                 Filename of the input file to read the grib messages from.
 
-            keynames: list of ???
+            keynames: list of strings
                 List of keynames. Default is an empty list.
 
-            keyvalues: list of ???
+            keyvalues: list of strings
                 List of keynames. Default is an empty list.
 
-            wherekeynames: list of ???, optional
+            wherekeynames: list of strings, optional
                 Default value is an empty list.
 
-            wherekeyvalues: list of ???, optional
+            wherekeyvalues: list of strings, optional
                 Default value is an empty list.
 
@@ -174,5 +174,5 @@
 
         '''
-        fout = open(self.filename, filemode)
+        fout = open(self.filenames, filemode)
         fin = open(fromfile)
 
@@ -196,5 +196,4 @@
                 i += 1
 
-#AP is it secured that the order of keynames is equal to keyvalues?
             if select:
                 i = 0
@@ -203,15 +202,6 @@
                     i += 1
 
-#AP this is a redundant code section
-# delete the if/else :
-#
-#           grib_write(gid_in, fout)
-#
-            if strict:
-                if select:
-                    grib_write(gid_in, fout)
-            else:
-                grib_write(gid_in, fout)
-#AP end
+            grib_write(gid_in, fout)
+
             grib_release(gid_in)
 
@@ -238,8 +228,8 @@
                 function. Default is True.
 
-            keynames: list of ???, optional
+            keynames: list of strings, optional
                 List of keynames. Default is an empty list.
 
-            keyvalues: list of ???, optional
+            keyvalues: list of strings, optional
                 List of keynames. Default is an empty list.
 
@@ -252,5 +242,5 @@
 
         fin = open(filename_in)
-        fout = open(self.filename, filemode)
+        fout = open(self.filenames, filemode)
 
         while 1:
@@ -307,28 +297,23 @@
                 Grib index id.
         '''
-        print("... index will be done")
-        self.iid = None
-
-        if (os.path.exists(index_file)):
-            self.iid = grib_index_read(index_file)
-            print("Use existing index file: %s " % (index_file))
+        print "... index will be done"
+        iid = None
+
+        if os.path.exists(index_file):
+            iid = grib_index_read(index_file)
+            print "Use existing index file: %s " % (index_file)
         else:
-            for file in self.filename:
-                print("Inputfile: %s " % (file))
-                if self.iid is None:
-                    self.iid = grib_index_new_from_file(file, index_keys)
+            for filename in self.filenames:
+                print "Inputfile: %s " % (filename)
+                if iid is None:
+                    iid = grib_index_new_from_file(filename, index_keys)
                 else:
                     print 'in else zweig'
-                    grib_index_add_file(self.iid, file)
-
-            if self.iid is not None:
-                grib_index_write(self.iid, index_file)
-
-        print('... index done')
-
-        return self.iid
-
-
-
-
-
+                    grib_index_add_file(iid, filename)
+
+            if iid is not None:
+                grib_index_write(iid, index_file)
+
+        print '... index done'
+
+        return iid
Index: python/MARSretrieval.py
===================================================================
--- python/MARSretrieval.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ 	(revision )
@@ -1,385 +1,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-# -
-#************************************************************************
-#*******************************************************************************
-# @Author: Anne Fouilloux (University of Oslo)
-#
-# @Date: October 2014
-#
-# @Change History:
-#
-#   November 2015 - Leopold Haimberger (University of Vienna):
-#        - optimized displayInfo
-#        - optimized dataRetrieve and seperate between python and shell
-#          script call
-#
-#   February 2018 - Anne Philipp (University of Vienna):
-#        - applied PEP8 style guide
-#        - added documentation
-#        - applied some minor modifications in programming style/structure
-#
-# @License:
-#    (C) Copyright 2015-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:
-#    A MARS revtrieval has a specific syntax with a selection of keywords and
-#    their corresponding values. This class provides the necessary functions
-#    by displaying the selected parameters and their values and the actual
-#    retrievement of the data through a mars request or a Python web api
-#    interface. The initialization already expects all the keyword values.
-#
-# @Class Content:
-#    - __init__
-#    - displayInfo
-#    - dataRetrieve
-#
-#*******************************************************************************
-
-# ------------------------------------------------------------------------------
-# MODULES
-# ------------------------------------------------------------------------------
-import subprocess
-import os
-
-ecapi = True
-try:
-    import ecmwfapi
-except ImportError:
-    ecapi = False
-
-# ------------------------------------------------------------------------------
-# CLASS
-# ------------------------------------------------------------------------------
-class MARSretrieval:
-    '''
-    Class for submitting MARS retrievals.
-
-    A description of MARS keywords/arguments and examples of their
-    values can be found here:
-    https://software.ecmwf.int/wiki/display/UDOC/\
-                   Identification+keywords#Identificationkeywords-class
-
-    '''
-
-    def __init__(self, server, marsclass = "ei", type = "", levtype = "",
-                 levelist = "", repres = "", date = "", resol = "", stream = "",
-                 area = "", time = "", step = "", expver = "1", number = "",
-                 accuracy = "", grid = "", gaussian = "", target = "",
-                 param = ""):
-        '''
-        @Description:
-            Initialises the instance of the MARSretrieval class and
-            defines and assigns a set of the necessary retrieval parameters
-            for the FLEXPART input data.
-            A description of MARS keywords/arguments, their dependencies
-            on each other and examples of their values can be found here:
-
-            https://software.ecmwf.int/wiki/display/UDOC/MARS+keywords
-
-        @Input:
-            self: instance of MARSretrieval
-                For description see class documentation.
-
-            server: instance of ECMWFService (from ECMWF Web-API)
-                This is the connection to the ECMWF data servers.
-                It is needed for the pythonic access of ECMWF data.
-
-            marsclass: string, optional
-                Characterisation of dataset. E.g. EI (ERA-Interim),
-                E4 (ERA40), OD (Operational archive), ea (ERA5).
-                Default is the ERA-Interim dataset "ei".
-
-            type: string, optional
-                Determines the type of fields to be retrieved.
-                Selects between observations, images or fields.
-                Examples for fields: Analysis (an), Forecast (fc),
-                Perturbed Forecast (pf), Control Forecast (cf) and so on.
-                Default is an empty string.
-
-            levtype: string, optional
-                Denotes type of level. Has a direct implication on valid
-                levelist values!
-                E.g. model level (ml), pressure level (pl), surface (sfc),
-                potential vorticity (pv), potential temperature (pt)
-                and depth (dp).
-                Default is an empty string.
-
-            levelist: string, optional
-                Specifies the required levels. It has to have a valid
-                correspondence to the selected levtype.
-                Examples: model level: 1/to/137, pressure levels: 500/to/1000
-                Default is an empty string.
-
-            repres: string, optional
-                Selects the representation of the archived data.
-                E.g. sh - spherical harmonics, gg - Gaussian grid,
-                ll - latitude/longitude, ...
-                Default is an empty string.
-
-            date: string, optional
-                Specifies the Analysis date, the Forecast base date or
-                Observations date. Valid formats are:
-                Absolute as YYYY-MM-DD or YYYYMMDD.
-                Default is an empty string.
-
-            resol: string, optional
-                Specifies the desired triangular truncation of retrieved data,
-                before carrying out any other selected post-processing.
-                The default is automatic truncation (auto), by which the lowest
-                resolution compatible with the value specified in grid is
-                automatically selected for the retrieval.
-                Users wanting to perform post-processing from full spectral
-                resolution should specify Archived Value (av).
-                The following are examples of existing resolutions found in
-                the archive: 63, 106, 159, 213, 255, 319, 399, 511, 799 or 1279.
-                This keyword has no meaning/effect if the archived data is
-                not in spherical harmonics representation.
-                The best selection can be found here:
-                https://software.ecmwf.int/wiki/display/UDOC/\
-                      Retrieve#Retrieve-Truncationbeforeinterpolation
-                Default is an empty string.
-
-            stream: string, optional
-                Identifies the forecasting system used to generate the data.
-                E.g. oper (Atmospheric model), enfo (Ensemble forecats), ...
-                Default is an empty string.
-
-            area: string, optional
-                Specifies the desired sub-area of data to be extracted.
-                Areas can be defined to wrap around the globe.
-
-                Latitude values must be given as signed numbers, with:
-                    north latitudes (i.e. north of the equator)
-                        being positive (e.g: 40.5)
-                    south latitutes (i.e. south of the equator)
-                        being negative (e.g: -50.5)
-                Longtitude values must be given as signed numbers, with:
-                    east longitudes (i.e. east of the 0 degree meridian)
-                        being positive (e.g: 35.0)
-                    west longitudes (i.e. west of the 0 degree meridian)
-                        being negative (e.g: -20.5)
-
-                E.g.: North/West/South/East
-                Default is an empty string.
-
-            time: string, optional
-                Specifies the time of the data in hours and minutes.
-                Valid values depend on the type of data: Analysis time,
-                Forecast base time or First guess verification time
-                (all usually at synoptic hours: 00, 06, 12 and 18 ).
-                Observation time (any combination in hours and minutes is valid,
-                subject to data availability in the archive).
-                The syntax is HHMM or HH:MM. If MM is omitted it defaults to 00.
-                Default is an empty string.
-
-            step: string, optional
-                Specifies the forecast time step from forecast base time.
-                Valid values are hours (HH) from forecast base time. It also
-                specifies the length of the forecast which verifies at
-                First Guess time.
-                E.g. 1/3/6-hourly
-                Default is an empty string.
-
-            expver: string, optional
-                The version of the dataset. Each experiment is assigned a
-                unique code (version). Production data is assigned 1 or 2,
-                and experimental data in Operations 11, 12 ,...
-                Research or Member State's experiments have a four letter
-                experiment identifier.
-                Default is "1".
-
-            number: string, optional
-                Selects the member in ensemble forecast run. (Only then it
-                is necessary.) It has a different meaning depending on
-                the type of data.
-                E.g. Perturbed Forecasts: specifies the Ensemble forecast member
-                Default is an empty string.
-
-            accuracy: string, optional
-                Specifies the number of bits per value to be used in the
-                generated GRIB coded fields.
-                A positive integer may be given to specify the preferred number
-                of bits per packed value. This must not be greater than the
-                number of bits normally used for a Fortran integer on the
-                processor handling the request (typically 32 or 64 bit).
-                Within a compute request the accuracy of the original fields
-                can be passed to the result field by specifying accuracy=av.
-                Default is an empty string.
-
-            grid: string, optional
-                Specifies the output grid which can be either a Gaussian grid
-                or a Latitude/Longitude grid. MARS requests specifying
-                grid=av will return the archived model grid.
-
-                Lat/Lon grid: The grid spacing needs to be an integer
-                fraction of 90 degrees e.g. grid = 0.5/0.5
-
-                Gaussian grid: specified by a letter denoting the type of
-                Gaussian grid followed by an integer (the grid number)
-                representing the number of lines between the Pole and Equator,
-                e.g.
-                grid = F160 - full (or regular) Gaussian grid with
-                       160 latitude lines between the pole and equator
-                grid = N320 - ECMWF original reduced Gaussian grid with
-                       320 latitude lines between the pole and equator,
-                       see Reduced Gaussian Grids for grid numbers used at ECMWF
-                grid = O640 - ECMWF octahedral (reduced) Gaussian grid with
-                       640 latitude lines between the pole and equator
-                Default is an empty string.
-
-            gaussian: string, optional
-                This parameter is deprecated and should no longer be used.
-                Specifies the desired type of Gaussian grid for the output.
-                Valid Gaussian grids are quasi-regular (reduced) or regular.
-                Keyword gaussian can only be specified together with
-                keyword grid. Gaussian without grid has no effect.
-                Default is an empty string.
-
-            target: string, optional
-                Specifies a file into which data is to be written after
-                retrieval or manipulation. Path names should always be
-                enclosed in double quotes. The MARS client supports automatic
-                generation of multiple target files using MARS keywords
-                enclosed in square brackets [ ].  If the environment variable
-                MARS_MULTITARGET_STRICT_FORMAT is set to 1 before calling mars,
-                the keyword values will be used in the filename as shown by
-                the ecCodes GRIB tool grib_ls -m, e.g. with
-                MARS_MULTITARGET_STRICT_FORMAT set to 1 the keywords time,
-                expver and param will be formatted as 0600, 0001 and 129.128
-                rather than 600, 1 and 129.
-                Default is an empty string.
-
-            param: string, optional
-                Specifies the meteorological parameter.
-                The list of meteorological parameters in MARS is extensive.
-                Their availability is directly related to their meteorological
-                meaning and, therefore, the rest of directives specified
-                in the MARS request.
-                Meteorological parameters can be specified by their
-                GRIB code (param=130), their mnemonic (param=t) or
-                full name (param=temperature).
-                The list of parameter should be seperated by a "/"-sign.
-                E.g. 130/131/133
-                Default is an empty string.
-
-        @Return:
-            <nothing>
-        '''
-
-        self.server = server
-        self.marsclass = marsclass
-        self.type = type
-        self.levtype = levtype
-        self.levelist = levelist
-        self.repres = repres
-        self.date = date
-        self.resol = resol
-        self.stream = stream
-        self.area = area
-        self.time = time
-        self.step = step
-        self.expver = expver
-        self.number = number
-        self.accuracy = accuracy
-        self.grid = grid
-        self.gaussian = gaussian
-        self.target = target
-        self.param = param
-
-        return
-
-
-    def displayInfo(self):
-        '''
-        @Description:
-            Prints all class attributes and their values.
-
-        @Input:
-            self: instance of MARSretrieval
-                For description see class documentation.
-
-        @Return:
-            <nothing>
-        '''
-        # Get all class attributes and their values as a dictionary
-        attrs = vars(self)
-
-        # iterate through all attributes and print them
-        # with their corresponding values
-        for item in attrs.items():
-            if item[0] in ('server'):
-                pass
-            else:
-                print(item[0] + ': ' + str(item[1]))
-
-        return
-
-    def dataRetrieve(self):
-        '''
-        @Description:
-            Submits a MARS retrieval. Depending on the existence of
-            ECMWF Web-API it is submitted via Python or a
-            subprocess in the Shell. The parameter for the mars retrieval
-            are taken from the defined class attributes.
-
-        @Input:
-            self: instance of MARSretrieval
-                For description see class documentation.
-
-        @Return:
-            <nothing>
-        '''
-        # Get all class attributes and their values as a dictionary
-        attrs = vars(self)
-
-        # convert the dictionary of attributes into a comma
-        # seperated list of attributes with their values
-        # needed for the retrieval call
-        s = 'ret'
-        for k, v in attrs.iteritems():
-            if k in ('server'):
-                continue
-            if k == 'marsclass':
-                k = 'class'
-            if v == '':
-                continue
-            if k.lower() == 'target':
-                target = v
-            else:
-                s = s + ',' + k + '=' + str(v)
-
-        # MARS request via Python script
-        if self.server is not False:
-            try:
-                self.server.execute(s, target)
-            except:
-                print('MARS Request failed, \
-                    have you already registered at apps.ecmwf.int?')
-                raise IOError
-            if os.stat(target).st_size == 0:
-                print('MARS Request returned no data - please check request')
-                raise IOError
-        # MARS request via extra process in shell
-        else:
-            s += ',target = "' + target + '"'
-            p = subprocess.Popen(['mars'], stdin=subprocess.PIPE,
-                                 stdout=subprocess.PIPE,
-                                 stderr=subprocess.PIPE, bufsize=1)
-            pout = p.communicate(input=s)[0]
-            print(pout.decode())
-
-            if 'Some errors reported' in pout.decode():
-                print('MARS Request failed - please check request')
-                raise IOError
-
-            if os.stat(target).st_size == 0:
-                print('MARS Request returned no data - please check request')
-                raise IOError
-
-        return
Index: python/MarsRetrieval.py
===================================================================
--- python/MarsRetrieval.py	(revision None)
+++ python/MarsRetrieval.py	(revision None)
@@ -0,0 +1,396 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#   November 2015 - Leopold Haimberger (University of Vienna):
+#        - optimized display_info
+#        - optimized data_retrieve and seperate between python and shell
+#          script call
+#
+#   February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - applied some minor modifications in programming style/structure
+#
+# @License:
+#    (C) Copyright 2015-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:
+#    A MARS revtrieval has a specific syntax with a selection of keywords and
+#    their corresponding values. This class provides the necessary functions
+#    by displaying the selected parameters and their values and the actual
+#    retrievement of the data through a mars request or a Python web api
+#    interface. The initialization already expects all the keyword values.
+#
+# @Class Content:
+#    - __init__
+#    - display_info
+#    - data_retrieve
+#
+# @Class Attributes:
+#    - server
+#    - marsclass
+#    - dtype
+#    - levtype
+#    - levelist
+#    - repres
+#    - date
+#    - resol
+#    - stream
+#    - area
+#    - time
+#    - step
+#    - expver
+#    - number
+#    - accuracy
+#    - grid
+#    - gaussian
+#    - target
+#    - param
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import subprocess
+import os
+
+# ------------------------------------------------------------------------------
+# CLASS
+# ------------------------------------------------------------------------------
+class MarsRetrieval(object):
+    '''
+    Class for submitting MARS retrievals.
+
+    A description of MARS keywords/arguments and examples of their
+    values can be found here:
+    https://software.ecmwf.int/wiki/display/UDOC/\
+                   Identification+keywords#Identificationkeywords-class
+
+    '''
+
+    def __init__(self, server, marsclass="ei", dtype="", levtype="",
+                 levelist="", repres="", date="", resol="", stream="",
+                 area="", time="", step="", expver="1", number="",
+                 accuracy="", grid="", gaussian="", target="",
+                 param=""):
+        '''
+        @Description:
+            Initialises the instance of the MarsRetrieval class and
+            defines and assigns a set of the necessary retrieval parameters
+            for the FLEXPART input data.
+            A description of MARS keywords/arguments, their dependencies
+            on each other and examples of their values can be found here:
+
+            https://software.ecmwf.int/wiki/display/UDOC/MARS+keywords
+
+        @Input:
+            self: instance of MarsRetrieval
+                For description see class documentation.
+
+            server: instance of ECMWFService (from ECMWF Web-API)
+                This is the connection to the ECMWF data servers.
+                It is needed for the pythonic access of ECMWF data.
+
+            marsclass: string, optional
+                Characterisation of dataset. E.g. EI (ERA-Interim),
+                E4 (ERA40), OD (Operational archive), ea (ERA5).
+                Default is the ERA-Interim dataset "ei".
+
+            dtype: string, optional
+                Determines the type of fields to be retrieved.
+                Selects between observations, images or fields.
+                Examples for fields: Analysis (an), Forecast (fc),
+                Perturbed Forecast (pf), Control Forecast (cf) and so on.
+                Default is an empty string.
+
+            levtype: string, optional
+                Denotes type of level. Has a direct implication on valid
+                levelist values!
+                E.g. model level (ml), pressure level (pl), surface (sfc),
+                potential vorticity (pv), potential temperature (pt)
+                and depth (dp).
+                Default is an empty string.
+
+            levelist: string, optional
+                Specifies the required levels. It has to have a valid
+                correspondence to the selected levtype.
+                Examples: model level: 1/to/137, pressure levels: 500/to/1000
+                Default is an empty string.
+
+            repres: string, optional
+                Selects the representation of the archived data.
+                E.g. sh - spherical harmonics, gg - Gaussian grid,
+                ll - latitude/longitude, ...
+                Default is an empty string.
+
+            date: string, optional
+                Specifies the Analysis date, the Forecast base date or
+                Observations date. Valid formats are:
+                Absolute as YYYY-MM-DD or YYYYMMDD.
+                Default is an empty string.
+
+            resol: string, optional
+                Specifies the desired triangular truncation of retrieved data,
+                before carrying out any other selected post-processing.
+                The default is automatic truncation (auto), by which the lowest
+                resolution compatible with the value specified in grid is
+                automatically selected for the retrieval.
+                Users wanting to perform post-processing from full spectral
+                resolution should specify Archived Value (av).
+                The following are examples of existing resolutions found in
+                the archive: 63, 106, 159, 213, 255, 319, 399, 511, 799 or 1279.
+                This keyword has no meaning/effect if the archived data is
+                not in spherical harmonics representation.
+                The best selection can be found here:
+                https://software.ecmwf.int/wiki/display/UDOC/\
+                      Retrieve#Retrieve-Truncationbeforeinterpolation
+                Default is an empty string.
+
+            stream: string, optional
+                Identifies the forecasting system used to generate the data.
+                E.g. oper (Atmospheric model), enfo (Ensemble forecats), ...
+                Default is an empty string.
+
+            area: string, optional
+                Specifies the desired sub-area of data to be extracted.
+                Areas can be defined to wrap around the globe.
+
+                Latitude values must be given as signed numbers, with:
+                    north latitudes (i.e. north of the equator)
+                        being positive (e.g: 40.5)
+                    south latitutes (i.e. south of the equator)
+                        being negative (e.g: -50.5)
+                Longtitude values must be given as signed numbers, with:
+                    east longitudes (i.e. east of the 0 degree meridian)
+                        being positive (e.g: 35.0)
+                    west longitudes (i.e. west of the 0 degree meridian)
+                        being negative (e.g: -20.5)
+
+                E.g.: North/West/South/East
+                Default is an empty string.
+
+            time: string, optional
+                Specifies the time of the data in hours and minutes.
+                Valid values depend on the type of data: Analysis time,
+                Forecast base time or First guess verification time
+                (all usually at synoptic hours: 00, 06, 12 and 18 ).
+                Observation time (any combination in hours and minutes is valid,
+                subject to data availability in the archive).
+                The syntax is HHMM or HH:MM. If MM is omitted it defaults to 00.
+                Default is an empty string.
+
+            step: string, optional
+                Specifies the forecast time step from forecast base time.
+                Valid values are hours (HH) from forecast base time. It also
+                specifies the length of the forecast which verifies at
+                First Guess time.
+                E.g. 1/3/6-hourly
+                Default is an empty string.
+
+            expver: string, optional
+                The version of the dataset. Each experiment is assigned a
+                unique code (version). Production data is assigned 1 or 2,
+                and experimental data in Operations 11, 12 ,...
+                Research or Member State's experiments have a four letter
+                experiment identifier.
+                Default is "1".
+
+            number: string, optional
+                Selects the member in ensemble forecast run. (Only then it
+                is necessary.) It has a different meaning depending on
+                the type of data.
+                E.g. Perturbed Forecasts: specifies the Ensemble forecast member
+                Default is an empty string.
+
+            accuracy: string, optional
+                Specifies the number of bits per value to be used in the
+                generated GRIB coded fields.
+                A positive integer may be given to specify the preferred number
+                of bits per packed value. This must not be greater than the
+                number of bits normally used for a Fortran integer on the
+                processor handling the request (typically 32 or 64 bit).
+                Within a compute request the accuracy of the original fields
+                can be passed to the result field by specifying accuracy=av.
+                Default is an empty string.
+
+            grid: string, optional
+                Specifies the output grid which can be either a Gaussian grid
+                or a Latitude/Longitude grid. MARS requests specifying
+                grid=av will return the archived model grid.
+
+                Lat/Lon grid: The grid spacing needs to be an integer
+                fraction of 90 degrees e.g. grid = 0.5/0.5
+
+                Gaussian grid: specified by a letter denoting the type of
+                Gaussian grid followed by an integer (the grid number)
+                representing the number of lines between the Pole and Equator,
+                e.g.
+                grid = F160 - full (or regular) Gaussian grid with
+                       160 latitude lines between the pole and equator
+                grid = N320 - ECMWF original reduced Gaussian grid with
+                       320 latitude lines between the pole and equator,
+                       see Reduced Gaussian Grids for grid numbers used at ECMWF
+                grid = O640 - ECMWF octahedral (reduced) Gaussian grid with
+                       640 latitude lines between the pole and equator
+                Default is an empty string.
+
+            gaussian: string, optional
+                This parameter is deprecated and should no longer be used.
+                Specifies the desired type of Gaussian grid for the output.
+                Valid Gaussian grids are quasi-regular (reduced) or regular.
+                Keyword gaussian can only be specified together with
+                keyword grid. Gaussian without grid has no effect.
+                Default is an empty string.
+
+            target: string, optional
+                Specifies a file into which data is to be written after
+                retrieval or manipulation. Path names should always be
+                enclosed in double quotes. The MARS client supports automatic
+                generation of multiple target files using MARS keywords
+                enclosed in square brackets [ ].  If the environment variable
+                MARS_MULTITARGET_STRICT_FORMAT is set to 1 before calling mars,
+                the keyword values will be used in the filename as shown by
+                the ecCodes GRIB tool grib_ls -m, e.g. with
+                MARS_MULTITARGET_STRICT_FORMAT set to 1 the keywords time,
+                expver and param will be formatted as 0600, 0001 and 129.128
+                rather than 600, 1 and 129.
+                Default is an empty string.
+
+            param: string, optional
+                Specifies the meteorological parameter.
+                The list of meteorological parameters in MARS is extensive.
+                Their availability is directly related to their meteorological
+                meaning and, therefore, the rest of directives specified
+                in the MARS request.
+                Meteorological parameters can be specified by their
+                GRIB code (param=130), their mnemonic (param=t) or
+                full name (param=temperature).
+                The list of parameter should be seperated by a "/"-sign.
+                E.g. 130/131/133
+                Default is an empty string.
+
+        @Return:
+            <nothing>
+        '''
+
+        self.server = server
+        self.marsclass = marsclass
+        self.dtype = dtype
+        self.levtype = levtype
+        self.levelist = levelist
+        self.repres = repres
+        self.date = date
+        self.resol = resol
+        self.stream = stream
+        self.area = area
+        self.time = time
+        self.step = step
+        self.expver = expver
+        self.number = number
+        self.accuracy = accuracy
+        self.grid = grid
+        self.gaussian = gaussian
+        self.target = target
+        self.param = param
+
+        return
+
+
+    def display_info(self):
+        '''
+        @Description:
+            Prints all class attributes and their values.
+
+        @Input:
+            self: instance of MarsRetrieval
+                For description see class documentation.
+
+        @Return:
+            <nothing>
+        '''
+        # Get all class attributes and their values as a dictionary
+        attrs = vars(self)
+
+        # iterate through all attributes and print them
+        # with their corresponding values
+        for item in attrs.items():
+            if item[0] in 'server':
+                pass
+            else:
+                print item[0] + ': ' + str(item[1])
+
+        return
+
+    def data_retrieve(self):
+        '''
+        @Description:
+            Submits a MARS retrieval. Depending on the existence of
+            ECMWF Web-API it is submitted via Python or a
+            subprocess in the Shell. The parameter for the mars retrieval
+            are taken from the defined class attributes.
+
+        @Input:
+            self: instance of MarsRetrieval
+                For description see class documentation.
+
+        @Return:
+            <nothing>
+        '''
+        # Get all class attributes and their values as a dictionary
+        attrs = vars(self)
+
+        # convert the dictionary of attributes into a comma
+        # seperated list of attributes with their values
+        # needed for the retrieval call
+        s = 'ret'
+        for k, v in attrs.iteritems():
+            if k in 'server':
+                continue
+            if k == 'marsclass':
+                k = 'class'
+            if v == '':
+                continue
+            if k.lower() == 'target':
+                target = v
+            else:
+                s = s + ',' + k + '=' + str(v)
+
+        # MARS request via Python script
+        if self.server is not False:
+            try:
+                self.server.execute(s, target)
+            except:
+                print 'MARS Request failed, \
+                    have you already registered at apps.ecmwf.int?'
+                raise IOError
+            if os.stat(target).st_size == 0:
+                print 'MARS Request returned no data - please check request'
+                raise IOError
+        # MARS request via extra process in shell
+        else:
+            s += ',target = "' + target + '"'
+            p = subprocess.Popen(['mars'], stdin=subprocess.PIPE,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE, bufsize=1)
+            pout = p.communicate(input=s)[0]
+            print pout.decode()
+
+            if 'Some errors reported' in pout.decode():
+                print 'MARS Request failed - please check request'
+                raise IOError
+
+            if os.stat(target).st_size == 0:
+                print 'MARS Request returned no data - please check request'
+                raise IOError
+
+        return
Index: python/Tools.py
===================================================================
--- python/Tools.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ 	(revision )
@@ -1,515 +1,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-# - check myerror
-# - check normalexit
-# - check getListAsString
-# - seperate args and control interpretation
-#************************************************************************
-#*******************************************************************************
-# @Author: Anne Philipp (University of Vienna)
-#
-# @Date: May 2018
-#
-# @Change History:
-#    October 2014 - Anne Fouilloux (University of Oslo)
-#        - created functions silentremove and product (taken from ECMWF)
-#
-#    November 2015 - Leopold Haimberger (University of Vienna)
-#        - created functions: interpret_args_and_control, cleanup
-#          myerror, normalexit, init128, toparamId
-#
-#    April 2018 - Anne Philipp (University of Vienna):
-#        - applied PEP8 style guide
-#        - added documentation
-#        - moved all functions from file FlexpartTools to this file Tools
-#        - added function getListAsString
-#
-# @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.
-#
-# @Modul Description:
-#    This module contains a couple of helpful functions which are
-#    used in different places in flex_extract.
-#
-# @Module Content:
-#    - interpret_args_and_control
-#    - cleanup
-#    - myerror
-#    - normalexit
-#    - product
-#    - silentremove
-#    - init128
-#    - toparamId
-#    - getListAsString
-#
-#*******************************************************************************
-
-# ------------------------------------------------------------------------------
-# MODULES
-# ------------------------------------------------------------------------------
-import os
-import errno
-import sys
-import glob
-import traceback
-from numpy import *
-from gribapi import *
-from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
-
-# software specific class from flex_extract
-from ControlFile import ControlFile
-
-# ------------------------------------------------------------------------------
-# FUNCTIONS
-# ------------------------------------------------------------------------------
-
-def interpret_args_and_control():
-    '''
-    @Description:
-        Assigns the command line arguments and reads CONTROL file
-        content. Apply default values for non mentioned arguments.
-
-    @Input:
-        <nothing>
-
-    @Return:
-        args: instance of ArgumentParser
-            Contains the commandline arguments from script/program call.
-
-        c: instance of class ControlFile
-            Contains all necessary information of a CONTROL file. The parameters
-            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
-            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
-            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
-            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
-            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, DEBUG, INPUTDIR,
-            OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-            For more information about format and content of the parameter see
-            documentation.
-
-    '''
-    parser = ArgumentParser(description='Retrieve FLEXPART input from \
-                            ECMWF MARS archive',
-                            formatter_class=ArgumentDefaultsHelpFormatter)
-
-    # the most important arguments
-    parser.add_argument("--start_date", dest="start_date",
-                        help="start date YYYYMMDD")
-    parser.add_argument("--end_date", dest="end_date",
-                        help="end_date YYYYMMDD")
-    parser.add_argument("--date_chunk", dest="date_chunk", default=None,
-                        help="# of days to be retrieved at once")
-
-    # some arguments that override the default in the CONTROL file
-    parser.add_argument("--basetime", dest="basetime",
-                        help="base such as 00/12 (for half day retrievals)")
-    parser.add_argument("--step", dest="step",
-                        help="steps such as 00/to/48")
-    parser.add_argument("--levelist", dest="levelist",
-                        help="Vertical levels to be retrieved, e.g. 30/to/60")
-    parser.add_argument("--area", dest="area",
-                        help="area defined as north/west/south/east")
-
-    # set the working directories
-    parser.add_argument("--inputdir", dest="inputdir", default=None,
-                        help="root directory for storing intermediate files")
-    parser.add_argument("--outputdir", dest="outputdir", default=None,
-                        help="root directory for storing output files")
-    parser.add_argument("--flexpart_root_scripts", dest="flexpart_root_scripts",
-                        help="FLEXPART root directory (to find grib2flexpart \
-                        and COMMAND file)\n\ Normally ECMWFDATA resides in \
-                        the scripts directory of the FLEXPART distribution")
-
-    # this is only used by prepareFLEXPART.py to rerun a postprocessing step
-    parser.add_argument("--ppid", dest="ppid",
-                        help="Specify parent process id for \
-                        rerun of prepareFLEXPART")
-
-    # arguments for job submission to ECMWF, only needed by submit.py
-    parser.add_argument("--job_template", dest='job_template',
-                        default="job.temp",
-                        help="job template file for submission to ECMWF")
-    parser.add_argument("--queue", dest="queue",
-                        help="queue for submission to ECMWF \
-                        (e.g. ecgate or cca )")
-    parser.add_argument("--controlfile", dest="controlfile",
-                        default='CONTROL.temp',
-                        help="file with CONTROL parameters")
-    parser.add_argument("--debug", dest="debug", default=0,
-                        help="Debug mode - leave temporary files intact")
-
-    args = parser.parse_args()
-
-    # create instance of ControlFile for specified controlfile
-    # and assign the parameters (and default values if necessary)
-    try:
-        c = ControlFile(args.controlfile)
-    except IOError:
-        try:
-            c = ControlFile(localpythonpath + args.controlfile)
-        except:
-            print('Could not read CONTROL file "' + args.controlfile + '"')
-            print('Either it does not exist or its syntax is wrong.')
-            print('Try "' + sys.argv[0].split('/')[-1] +
-                  ' -h" to print usage information')
-            exit(1)
-
-    # check for having at least a starting date
-    if  args.start_date is None and getattr(c, 'start_date') is None:
-        print('start_date specified neither in command line nor \
-               in CONTROL file ' + args.controlfile)
-        print('Try "' + sys.argv[0].split('/')[-1] +
-              ' -h" to print usage information')
-        exit(1)
-
-    # save all existing command line parameter to the ControlFile instance
-    # if parameter is not specified through the command line or CONTROL file
-    # set default values
-    if args.start_date is not None:
-        c.start_date = args.start_date
-    if args.end_date is not None:
-        c.end_date = args.end_date
-    if c.end_date is None:
-        c.end_date = c.start_date
-    if args.date_chunk is not None:
-        c.date_chunk = args.date_chunk
-
-    if not hasattr(c, 'debug'):
-        c.debug = args.debug
-
-    if args.inputdir is None and args.outputdir is None:
-        c.inputdir = '../work'
-        c.outputdir = '../work'
-    else:
-        if args.inputdir is not None:
-            c.inputdir = args.inputdir
-        if args.outputdir is None:
-            c.outputdir = args.inputdir
-        if args.outputdir is not None:
-            c.outputdir = args.outputdir
-        if args.inputdir is None:
-            c.inputdir = args.outputdir
-
-    if hasattr(c, 'outputdir') is False and args.outputdir is None:
-        c.outputdir = c.inputdir
-    else:
-        if args.outputdir is not None:
-            c.outputdir = args.outputdir
-
-    if args.area is not None:
-        afloat = '.' in args.area
-        l = args.area.split('/')
-        if afloat:
-            for i in range(len(l)):
-                l[i] = str(int(float(l[i]) * 1000))
-        c.upper, c.left, c.lower, c.right = l
-
-    # NOTE: basetime activates the ''operational mode''
-    if args.basetime is not None:
-        c.basetime = args.basetime
-
-    if args.step is not None:
-        l = args.step.split('/')
-        if 'to' in args.step.lower():
-            if 'by' in args.step.lower():
-                ilist = arange(int(l[0]), int(l[2]) + 1, int(l[4]))
-                c.step = ['{:0>3}'.format(i) for i in ilist]
-            else:
-                myerror(None, args.step + ':\n' +
-                        'please use "by" as well if "to" is used')
-        else:
-            c.step = l
-
-    if args.levelist is not None:
-        c.levelist = args.levelist
-        if 'to' in c.levelist:
-            c.level = c.levelist.split('/')[2]
-        else:
-            c.level = c.levelist.split('/')[-1]
-
-    if args.flexpart_root_scripts is not None:
-        c.flexpart_root_scripts = args.flexpart_root_scripts
-
-    return args, c
-
-
-def cleanup(c):
-    '''
-    @Description:
-        Remove all files from intermediate directory
-        (inputdir from CONTROL file).
-
-    @Input:
-        c: instance of class ControlFile
-            Contains all the parameters of CONTROL file, which are e.g.:
-            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-            For more information about format and content of the parameter
-            see documentation.
-
-    @Return:
-        <nothing>
-    '''
-
-    print("cleanup")
-
-    cleanlist = glob.glob(c.inputdir + "/*")
-    for cl in cleanlist:
-        if c.prefix not in cl:
-            silentremove(cl)
-        if c.ecapi is False and (c.ectrans == '1' or c.ecstorage == '1'):
-            silentremove(cl)
-
-    print("Done")
-
-    return
-
-
-def myerror(c, message='ERROR'):
-    '''
-    @Description:
-        Prints a specified error message which can be passed to the function
-        before exiting the program.
-
-    @Input:
-        c: instance of class ControlFile
-            Contains all the parameters of CONTROL file, which are e.g.:
-            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-            For more information about format and content of the parameter
-            see documentation.
-
-        message: string, optional
-            Error message. Default value is "ERROR".
-
-    @Return:
-        <nothing>
-    '''
-    # uncomment if user wants email notification directly from python
-    #try:
-        #target = c.mailfail
-    #except AttributeError:
-        #target = os.getenv('USER')
-
-    #if(type(target) is not list):
-        #target = [target]
-
-    print(message)
-
-    # uncomment if user wants email notification directly from python
-    #for t in target:
-    #p = subprocess.Popen(['mail','-s ECMWFDATA v7.0 ERROR', os.path.expandvars(t)],
-    #                     stdin = subprocess.PIPE, stdout = subprocess.PIPE,
-    #                     stderr = subprocess.PIPE, bufsize = 1)
-    #tr = '\n'.join(traceback.format_stack())
-    #pout = p.communicate(input = message+'\n\n'+tr)[0]
-    #print 'Email sent to '+os.path.expandvars(t) # +' '+pout.decode()
-
-    exit(1)
-
-    return
-
-
-def normalexit(c, message='Done!'):
-    '''
-    @Description:
-        Prints a specific exit message which can be passed to the function.
-
-    @Input:
-        c: instance of class ControlFile
-            Contains all the parameters of CONTROL file, which are e.g.:
-            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-            For more information about format and content of the parameter
-            see documentation.
-
-        message: string, optional
-            Message for exiting program. Default value is "Done!".
-
-    @Return:
-        <nothing>
-
-    '''
-    # Uncomment if user wants notification directly from python
-    #try:
-        #target = c.mailops
-        #if(type(target) is not list):
-            #target = [target]
-        #for t in target:
-            #p = subprocess.Popen(['mail','-s ECMWFDATA v7.0 normal exit',
-            #                      os.path.expandvars(t)],
-            #                      stdin = subprocess.PIPE,
-            #                      stdout = subprocess.PIPE,
-            #                      stderr = subprocess.PIPE, bufsize = 1)
-            #pout = p.communicate(input = message+'\n\n')[0]
-            #print pout.decode()
-    #except:
-        #pass
-
-    print(message)
-
-    return
-
-
-def product(*args, **kwds):
-    '''
-    @Description:
-        This method is taken from an example at the ECMWF wiki website.
-        https://software.ecmwf.int/wiki/display/GRIB/index.py; 2018-03-16
-
-        This method combines the single characters of the passed arguments
-        with each other. So that each character of each argument value
-        will be combined with each character of the other arguments as a tuple.
-
-        Example:
-        product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
-        product(range(2), repeat = 3) --> 000 001 010 011 100 101 110 111
-
-    @Input:
-        *args: tuple
-            Positional arguments (arbitrary number).
-
-        **kwds: dictionary
-            Contains all the keyword arguments from *args.
-
-    @Return:
-        prod: tuple
-            Return will be done with "yield". A tuple of combined arguments.
-            See example in description above.
-    '''
-    pools = map(tuple, args) * kwds.get('repeat', 1)
-    result = [[]]
-    for pool in pools:
-        result = [x + [y] for x in result for y in pool]
-    for prod in result:
-        yield tuple(prod)
-
-    return
-
-
-def silentremove(filename):
-    '''
-    @Description:
-        If "filename" exists , it is removed.
-        The function does not fail if the file does not exist.
-
-    @Input:
-        filename: string
-            The name of the file to be removed without notification.
-
-    @Return:
-        <nothing>
-    '''
-    try:
-        os.remove(filename)
-    except OSError as e:
-        # this would be "except OSError, e:" before Python 2.6
-        if e.errno is not  errno.ENOENT:
-            # errno.ENOENT  =  no such file or directory
-            raise  # re-raise exception if a different error occured
-
-    return
-
-
-def init128(fn):
-    '''
-    @Description:
-        Opens and reads the grib file with table 128 information.
-
-    @Input:
-        fn: string
-            Path to file of ECMWF grib table number 128.
-
-    @Return:
-        table128: dictionary
-            Contains the ECMWF grib table 128 information.
-            The key is the parameter number and the value is the
-            short name of the parameter.
-    '''
-    table128 = dict()
-    with open(fn) as f:
-        fdata = f.read().split('\n')
-    for data in fdata:
-        if data[0] != '!':
-            table128[data[0:3]] = data[59:64].strip()
-
-    return table128
-
-
-def toparamId(pars, table):
-    '''
-    @Description:
-        Transform parameter names to parameter ids
-        with ECMWF grib table 128.
-
-    @Input:
-        pars: string
-            Addpar argument from CONTROL file in the format of
-            parameter names instead of ids. The parameter short
-            names are sepearted with "/" and they are passed as
-            one single string.
-
-        table: dictionary
-            Contains the ECMWF grib table 128 information.
-            The key is the parameter number and the value is the
-            short name of the parameter.
-
-    @Return:
-        ipar: list of integer
-            List of addpar parameters from CONTROL file transformed to
-            parameter ids in the format of integer.
-    '''
-    cpar = pars.upper().split('/')
-    ipar = []
-    for par in cpar:
-        found = False
-        for k, v in table.iteritems():
-            if par == k or par == v:
-                ipar.append(int(k))
-                found = True
-                break
-        if found is False:
-            print('Warning: par ' + par + ' not found in table 128')
-
-    return ipar
-
-def getListAsString(listObj):
-    '''
-    @Description:
-        Converts a list of arbitrary content into a single string.
-
-    @Input:
-        listObj: list
-            A list with arbitrary content.
-
-    @Return:
-        strOfList: string
-            The content of the list as a single string.
-    '''
-
-    strOfList = ", ".join( str(l) for l in listObj)
-
-    return strOfList
Index: python/UIOFiles.py
===================================================================
--- python/UIOFiles.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ 	(revision )
@@ -1,154 +1,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-# - checken welche regelmässigen methoden auf diese Files noch angewendet werden
-# und dann hier implementieren
-# cleanup hier rein
-#************************************************************************
-#*******************************************************************************
-# @Author: Anne Fouilloux (University of Oslo)
-#
-# @Date: October 2014
-#
-# @Change History:
-#
-#    November 2015 - Leopold Haimberger (University of Vienna):
-#        - modified method listFiles to work with glob instead of listdir
-#        - added pattern search in method listFiles
-#
-#    February 2018 - Anne Philipp (University of Vienna):
-#        - applied PEP8 style guide
-#        - added documentation
-#        - optimisation of method listFiles since it didn't work correctly
-#          for sub directories
-#        - additional speed up of method listFiles
-#        - modified the class so that it is initiated with a pattern instead
-#          of suffixes. Gives more precision in selection of files.
-#
-# @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 Decription:
-#    The class is for file manipulation. It is initiated with a regular
-#    expression pattern for this instance and can produce a list of Files
-#    from the given file pattern. These files can be deleted.
-#
-# @Class Content:
-#    - __init__
-#    - listFiles
-#    - deleteFiles
-#
-#*******************************************************************************
-
-# ------------------------------------------------------------------------------
-# MODULES
-# ------------------------------------------------------------------------------
-import os
-import glob
-import fnmatch
-import time
-
-# software specific module from flex_extract
-import profiling
-from Tools import silentremove
-
-# ------------------------------------------------------------------------------
-# CLASS
-# ------------------------------------------------------------------------------
-
-class UIOFiles:
-    '''
-    Class to manipulate files. At initialisation it has the attribute
-    pattern which stores a regular expression pattern for the files associated
-    with the instance of the class.
-    '''
-    # --------------------------------------------------------------------------
-    # CLASS FUNCTIONS
-    # --------------------------------------------------------------------------
-    def __init__(self, pattern):
-        '''
-        @Description:
-            Assignes a specific pattern for these files.
-
-        @Input:
-            self: instance of UIOFiles
-                Description see class documentation.
-
-            pattern: string
-                Regular expression pattern. For example: '*.grb'
-
-        @Return:
-            <nothing>
-        '''
-
-        self.pattern = pattern
-
-        return
-
-    #@profiling.timefn
-    def listFiles(self, path, callid=0):
-        '''
-        @Description:
-            Lists all files in the directory with the matching
-            regular expression pattern.
-
-        @Input:
-            self: instance of UIOFiles
-                Description see class documentation.
-
-            path: string
-                Directory where to list the files.
-
-            callid: integer
-                Id which tells the function if its the first call
-                or a recursive call. Default and first call is 0.
-                Everything different from 0 is ment to be a recursive case.
-
-        @Return:
-            <nothing>
-        '''
-
-        # initialize variable in first function call
-        if callid == 0:
-            self.files = []
-
-        # Get the absolute path
-        path = os.path.abspath(path)
-
-        # get the file list of the path if its not a directory and
-        # if it contains the pattern
-        self.files.extend([os.path.join(path, k) for k in os.listdir(path)
-                           if fnmatch.fnmatch(k, self.pattern)])
-
-        # find possible sub-directories in the path
-        subdirs = [s for s in os.listdir(path)
-                   if os.path.isdir(os.path.join(path, s))]
-
-        # do recursive calls for sub-direcorties
-        if subdirs:
-            for subdir in subdirs:
-                self.listFiles(os.path.join(path, subdir), callid=1)
-
-        return
-
-    def deleteFiles(self):
-        '''
-        @Description:
-            Deletes the files.
-
-        @Input:
-            self: instance of UIOFiles
-                Description see class documentation.
-
-        @Return:
-            <nothing>
-        '''
-
-        for f in self.files:
-            silentremove(f)
-
-        return
Index: python/UioFiles.py
===================================================================
--- python/UioFiles.py	(revision None)
+++ python/UioFiles.py	(revision None)
@@ -0,0 +1,151 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - modified method list_files to work with glob instead of listdir
+#        - added pattern search in method list_files
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - optimisation of method list_files since it didn't work correctly
+#          for sub directories
+#        - additional speed up of method list_files
+#        - modified the class so that it is initiated with a pattern instead
+#          of suffixes. Gives more precision in selection of files.
+#
+# @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 Decription:
+#    The class is for file manipulation. It is initiated with a regular
+#    expression pattern for this instance and can produce a list of Files
+#    from the given file pattern. These files can be deleted.
+#
+# @Class Content:
+#    - __init__
+#    - list_files
+#    - delete_files
+#
+# @Class Attributes:
+#    - pattern
+#    - files
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import fnmatch
+
+# software specific module from flex_extract
+#import profiling
+from tools import silent_remove
+
+# ------------------------------------------------------------------------------
+# CLASS
+# ------------------------------------------------------------------------------
+
+class UioFiles(object):
+    '''
+    Class to manipulate files. At initialisation it has the attribute
+    pattern which stores a regular expression pattern for the files associated
+    with the instance of the class.
+    '''
+    # --------------------------------------------------------------------------
+    # CLASS FUNCTIONS
+    # --------------------------------------------------------------------------
+    def __init__(self, pattern):
+        '''
+        @Description:
+            Assignes a specific pattern for these files.
+
+        @Input:
+            self: instance of UioFiles
+                Description see class documentation.
+
+            pattern: string
+                Regular expression pattern. For example: '*.grb'
+
+        @Return:
+            <nothing>
+        '''
+
+        self.pattern = pattern
+        self.files = None
+
+        return
+
+    #@profiling.timefn
+    def list_files(self, path, callid=0):
+        '''
+        @Description:
+            Lists all files in the directory with the matching
+            regular expression pattern.
+
+        @Input:
+            self: instance of UioFiles
+                Description see class documentation.
+
+            path: string
+                Directory where to list the files.
+
+            callid: integer
+                Id which tells the function if its the first call
+                or a recursive call. Default and first call is 0.
+                Everything different from 0 is ment to be a recursive case.
+
+        @Return:
+            <nothing>
+        '''
+
+        # initialize variable in first function call
+        if callid == 0:
+            self.files = []
+
+        # Get the absolute path
+        path = os.path.abspath(path)
+
+        # get the file list of the path if its not a directory and
+        # if it contains the pattern
+        self.files.extend([os.path.join(path, k) for k in os.listdir(path)
+                           if fnmatch.fnmatch(k, self.pattern)])
+
+        # find possible sub-directories in the path
+        subdirs = [s for s in os.listdir(path)
+                   if os.path.isdir(os.path.join(path, s))]
+
+        # do recursive calls for sub-direcorties
+        if subdirs:
+            for subdir in subdirs:
+                self.list_files(os.path.join(path, subdir), callid=1)
+
+        return
+
+    def delete_files(self):
+        '''
+        @Description:
+            Deletes the files.
+
+        @Input:
+            self: instance of UioFiles
+                Description see class documentation.
+
+        @Return:
+            <nothing>
+        '''
+
+        for old_file in self.files:
+            silent_remove(old_file)
+
+        return
Index: python/disaggregation.py
===================================================================
--- python/disaggregation.py	(revision None)
+++ python/disaggregation.py	(revision None)
@@ -0,0 +1,145 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#************************************************************************
+# ToDo AP
+# - check alist of size 4 ?
+# - write a test, IMPORTANT
+#************************************************************************
+#*******************************************************************************
+# @Author: Anne Philipp (University of Vienna)
+#
+# @Date: March 2018
+#
+# @Change History:
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - migration of the methods dapoly and darain from Fortran
+#          (flex_extract_v6 and earlier) to Python
+#
+#    April 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added structured documentation
+#        - outsourced the disaggregation functions dapoly and darain
+#          to a new module named disaggregation
+#
+# @License:
+#    (C) Copyright 2015-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.
+#
+# @Module Description:
+#    disaggregationregation of deaccumulated flux data from an ECMWF model FG field.
+#    Initially the flux data to be concerned are:
+#    - large-scale precipitation
+#    - convective precipitation
+#    - surface sensible heat flux
+#    - surface solar radiation
+#    - u stress
+#    - v stress
+#    Different versions of disaggregation is provided for rainfall
+#    data (darain, modified linear) and the surface fluxes and
+#    stress data (dapoly, cubic polynomial).
+#
+# @Module Content:
+#    - dapoly
+#    - darain
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+
+# ------------------------------------------------------------------------------
+# FUNCTIONS
+# ------------------------------------------------------------------------------
+def dapoly(alist):
+    '''
+    @Author: P. JAMES
+
+    @Date: 2000-03-29
+
+    @ChangeHistory:
+        June 2003     - A. BECK (2003-06-01)
+            adaptaions
+        November 2015 - Leopold Haimberger (University of Vienna)
+            migration from Fortran to Python
+
+    @Description:
+        Interpolation of deaccumulated fluxes of an ECMWF model FG field
+        using a cubic polynomial solution which conserves the integrals
+        of the fluxes within each timespan.
+        disaggregationregation is done for 4 accumluated timespans which generates
+        a new, disaggregated value which is output at the central point
+        of the 4 accumulation timespans. This new point is used for linear
+        interpolation of the complete timeseries afterwards.
+
+    @Input:
+        alist: list of size 4, array(2D), type=float
+            List of 4 timespans as 2-dimensional, horizontal fields.
+            E.g. [[array_t1], [array_t2], [array_t3], [array_t4]]
+
+    @Return:
+        nfield: array(2D), type=float
+            New field which replaces the field at the second position
+            of the accumulation timespans.
+
+    '''
+    pya = (alist[3] - alist[0] + 3. * (alist[1] - alist[2])) / 6.
+    pyb = (alist[2] + alist[0]) / 2. - alist[1] - 9. * pya / 2.
+    pyc = alist[1] - alist[0] - 7. * pya / 2. - 2. * pyb
+    pyd = alist[0] - pya / 4. - pyb / 3. - pyc / 2.
+    nfield = 8. * pya + 4. * pyb + 2. * pyc + pyd
+
+    return nfield
+
+
+def darain(alist):
+    '''
+    @Author: P. JAMES
+
+    @Date: 2000-03-29
+
+    @ChangeHistory:
+        June 2003     - A. BECK (2003-06-01)
+            adaptaions
+        November 2015 - Leopold Haimberger (University of Vienna)
+            migration from Fortran to Python
+
+    @Description:
+        Interpolation of deaccumulated fluxes of an ECMWF model FG rainfall
+        field using a modified linear solution which conserves the integrals
+        of the fluxes within each timespan.
+        disaggregationregation is done for 4 accumluated timespans which generates
+        a new, disaggregated value which is output at the central point
+        of the 4 accumulation timespans. This new point is used for linear
+        interpolation of the complete timeseries afterwards.
+
+    @Input:
+        alist: list of size 4, array(2D), type=float
+            List of 4 timespans as 2-dimensional, horizontal fields.
+            E.g. [[array_t1], [array_t2], [array_t3], [array_t4]]
+
+    @Return:
+        nfield: array(2D), type=float
+            New field which replaces the field at the second position
+            of the accumulation timespans.
+    '''
+    xa = alist[0]
+    xb = alist[1]
+    xc = alist[2]
+    xd = alist[3]
+    xa[xa < 0.] = 0.
+    xb[xb < 0.] = 0.
+    xc[xc < 0.] = 0.
+    xd[xd < 0.] = 0.
+
+    xac = 0.5 * xb
+    mask = xa + xc > 0.
+    xac[mask] = xb[mask] * xc[mask] / (xa[mask] + xc[mask])
+    xbd = 0.5 * xc
+    mask = xb + xd > 0.
+    xbd[mask] = xb[mask] * xc[mask] / (xb[mask] + xd[mask])
+    nfield = xac + xbd
+
+    return nfield
Index: python/getMARSdata.py
===================================================================
--- python/getMARSdata.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ 	(revision )
@@ -1,250 +1,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-# - add function docstrings!!!!
-#************************************************************************
-#*******************************************************************************
-# @Author: Anne Fouilloux (University of Oslo)
-#
-# @Date: October 2014
-#
-# @Change History:
-#
-#    November 2015 - Leopold Haimberger (University of Vienna):
-#        - moved the getEIdata program into a function "getMARSdata"
-#        - moved the AgurmentParser into a seperate function
-#        - adatpted the function for the use in flex_extract
-#        - renamed file to getMARSdata
-#
-#    February 2018 - Anne Philipp (University of Vienna):
-#        - applied PEP8 style guide
-#        - added structured documentation
-#        - minor changes in programming style for consistence
-#        - added function main and moved function calls vom __main__ there
-#          (necessary for better documentation with docstrings for later
-#          online documentation)
-#        - use of UIFiles class for file selection and deletion
-
-#
-# @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.
-#
-# @Program Functionality:
-#    This program can be used as a module in the whole flex_extract process
-#    or can be run by itself to just extract MARS data from ECMWF. To do so,
-#    a couple of necessary parameters has to be passed with the program call.
-#    See documentation for more details.
-#
-# @Program Content:
-#    - main
-#    - getMARSdata
-#
-#*******************************************************************************
-
-# ------------------------------------------------------------------------------
-# MODULES
-# ------------------------------------------------------------------------------
-import os
-import sys
-import datetime
-import inspect
-try:
-    ecapi=True
-    import ecmwfapi
-except ImportError:
-    ecapi=False
-
-# add path to pythonpath so that python finds its buddies
-localpythonpath = os.path.dirname(os.path.abspath(
-    inspect.getfile(inspect.currentframe())))
-if localpythonpath not in sys.path:
-    sys.path.append(localpythonpath)
-
-# software specific classes and modules from flex_extract
-from ControlFile import ControlFile
-from Tools import myerror, normalexit, \
-                          interpret_args_and_control
-from ECFlexpart import ECFlexpart
-from UIOFiles import UIOFiles
-
-# ------------------------------------------------------------------------------
-# FUNCTION
-# ------------------------------------------------------------------------------
-def main():
-    '''
-    @Description:
-        If getMARSdata is called from command line, this function controls
-        the program flow and calls the argumentparser function and
-        the getMARSdata function for retrieving EC data.
-
-    @Input:
-        <nothing>
-
-    @Return:
-        <nothing>
-    '''
-    args, c = interpret_args_and_control()
-    getMARSdata(args, c)
-    normalexit(c)
-
-    return
-
-def getMARSdata(args, c):
-    '''
-    @Description:
-        Retrieves the EC data needed for a FLEXPART simulation.
-        Start and end dates for retrieval period is set. Retrievals
-        are divided into smaller periods if necessary and datechunk parameter
-        is set.
-
-    @Input:
-        args: instance of ArgumentParser
-            Contains the commandline arguments from script/program call.
-
-        c: instance of class ControlFile
-            Contains all the parameters of CONTROL file, which are e.g.:
-            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-            For more information about format and content of the parameter
-            see documentation.
-
-    @Return:
-        <nothing>
-    '''
-
-    if not os.path.exists(c.inputdir):
-        os.makedirs(c.inputdir)
-
-    print("Retrieving EC data!")
-    print("start date %s " % (c.start_date))
-    print("end date %s " % (c.end_date))
-
-    if ecapi:
-        server = ecmwfapi.ECMWFService("mars")
-    else:
-        server = False
-
-    c.ecapi = ecapi
-    print 'ecapi: ', c.ecapi
-
-    # set start date of retrieval period
-    start = datetime.date(year=int(c.start_date[:4]),
-                          month=int(c.start_date[4:6]),
-                          day=int(c.start_date[6:]))
-    startm1 = start - datetime.timedelta(days=1)
-    if c.basetime == '00':
-        start = startm1
-
-    # set end date of retrieval period
-    end = datetime.date(year=int(c.end_date[:4]),
-                        month=int(c.end_date[4:6]),
-                        day=int(c.end_date[6:]))
-    if c.basetime == '00' or c.basetime == '12':
-        endp1 = end + datetime.timedelta(days=1)
-    else:
-        endp1 = end + datetime.timedelta(days=2)
-
-    # set time period of one single retrieval
-    datechunk = datetime.timedelta(days=int(c.date_chunk))
-
-    # --------------  flux data ------------------------------------------------
-    print 'removing old flux content of ' + c.inputdir
-    tobecleaned = UIOFiles('*_acc_*.' + str(os.getppid()) + '.*.grb')
-    tobecleaned.listFiles(c.inputdir)
-    tobecleaned.deleteFiles()
-
-    # if forecast for maximum one day (upto 23h) are to be retrieved,
-    # collect accumulation data (flux data)
-    # with additional days in the beginning and at the end
-    # (used for complete disaggregation of original period)
-    if c.maxstep < 24:
-        day = startm1
-        while day < endp1:
-            # retrieve MARS data for the whole period
-            flexpart = ECFlexpart(c, fluxes=True)
-            tmpday = day + datechunk - datetime.timedelta(days=1)
-            if tmpday < endp1:
-                dates = day.strftime("%Y%m%d") + "/to/" + \
-                        tmpday.strftime("%Y%m%d")
-            else:
-                dates = day.strftime("%Y%m%d") + "/to/" + \
-                        end.strftime("%Y%m%d")
-
-            print "retrieve " + dates + " in dir " + c.inputdir
-
-            try:
-                flexpart.retrieve(server, dates, c.inputdir)
-            except IOError:
-                myerror(c, 'MARS request failed')
-
-            day += datechunk
-
-    # if forecast data longer than 24h are to be retrieved,
-    # collect accumulation data (flux data)
-    # with the exact start and end date
-    # (disaggregation will be done for the
-    # exact time period with boundary conditions)
-    else:
-        day = start
-        while day <= end:
-            # retrieve MARS data for the whole period
-            flexpart = ECFlexpart(c, fluxes=True)
-            tmpday = day + datechunk - datetime.timedelta(days=1)
-            if tmpday < end:
-                dates = day.strftime("%Y%m%d") + "/to/" + \
-                        tmpday.trftime("%Y%m%d")
-            else:
-                dates = day.strftime("%Y%m%d") + "/to/" + \
-                        end.strftime("%Y%m%d")
-
-            print "retrieve " + dates + " in dir " + c.inputdir
-
-            try:
-                flexpart.retrieve(server, dates, c.inputdir)
-            except IOError:
-                myerror(c, 'MARS request failed')
-
-            day += datechunk
-
-    # --------------  non flux data --------------------------------------------
-    print 'removing old non flux content of ' + c.inputdir
-    tobecleaned = UIOFiles('*__*.' + str(os.getppid()) + '.*.grb')
-    tobecleaned.listFiles(c.inputdir)
-    tobecleaned.deleteFiles()
-
-    day = start
-    while day <= end:
-            # retrieve all non flux MARS data for the whole period
-            flexpart = ECFlexpart(c, fluxes=False)
-            tmpday = day + datechunk - datetime.timedelta(days=1)
-            if tmpday < end:
-                dates = day.strftime("%Y%m%d") + "/to/" + \
-                        tmpday.strftime("%Y%m%d")
-            else:
-                dates = day.strftime("%Y%m%d") + "/to/" + \
-                        end.strftime("%Y%m%d")
-
-            print "retrieve " + dates + " in dir " + c.inputdir
-
-            try:
-                flexpart.retrieve(server, dates, c.inputdir)
-            except IOError:
-                myerror(c, 'MARS request failed')
-
-            day += datechunk
-
-    return
-
-if __name__ == "__main__":
-    main()
-
Index: python/get_mars_data.py
===================================================================
--- python/get_mars_data.py	(revision None)
+++ python/get_mars_data.py	(revision None)
@@ -0,0 +1,240 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - moved the getEIdata program into a function "get_mars_data"
+#        - moved the AgurmentParser into a seperate function
+#        - adatpted the function for the use in flex_extract
+#        - renamed file to get_mars_data
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added structured documentation
+#        - minor changes in programming style for consistence
+#        - added function main and moved function calls vom __main__ there
+#          (necessary for better documentation with docstrings for later
+#          online documentation)
+#        - use of UIFiles class for file selection and deletion
+
+#
+# @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.
+#
+# @Program Functionality:
+#    This program can be used as a module in the whole flex_extract process
+#    or can be run by itself to just extract MARS data from ECMWF. To do so,
+#    a couple of necessary parameters has to be passed with the program call.
+#    See documentation for more details.
+#
+# @Program Content:
+#    - main
+#    - get_mars_data
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import sys
+import datetime
+import inspect
+try:
+    ecapi = True
+    import ecmwfapi
+except ImportError:
+    ecapi = False
+
+# software specific classes and modules from flex_extract
+from tools import my_error, normal_exit, interpret_args_and_control
+from EcFlexpart import EcFlexpart
+from UioFiles import UioFiles
+
+# add path to pythonpath so that python finds its buddies
+LOCAL_PYTHON_PATH = os.path.dirname(os.path.abspath(
+    inspect.getfile(inspect.currentframe())))
+if LOCAL_PYTHON_PATH not in sys.path:
+    sys.path.append(LOCAL_PYTHON_PATH)
+
+# ------------------------------------------------------------------------------
+# FUNCTION
+# ------------------------------------------------------------------------------
+def main():
+    '''
+    @Description:
+        If get_mars_data is called from command line, this function controls
+        the program flow and calls the argumentparser function and
+        the get_mars_data function for retrieving EC data.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        <nothing>
+    '''
+    args, c = interpret_args_and_control()
+    get_mars_data(c)
+    normal_exit(c)
+
+    return
+
+def get_mars_data(c):
+    '''
+    @Description:
+        Retrieves the EC data needed for a FLEXPART simulation.
+        Start and end dates for retrieval period is set. Retrievals
+        are divided into smaller periods if necessary and datechunk parameter
+        is set.
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+    @Return:
+        <nothing>
+    '''
+
+    if not os.path.exists(c.inputdir):
+        os.makedirs(c.inputdir)
+
+    print "Retrieving EC data!"
+    print "start date %s " % (c.start_date)
+    print "end date %s " % (c.end_date)
+
+    if ecapi:
+        server = ecmwfapi.ECMWFService("mars")
+    else:
+        server = False
+
+    c.ecapi = ecapi
+    print 'ecapi: ', c.ecapi
+
+    # set start date of retrieval period
+    start = datetime.date(year=int(c.start_date[:4]),
+                          month=int(c.start_date[4:6]),
+                          day=int(c.start_date[6:]))
+    startm1 = start - datetime.timedelta(days=1)
+    if c.basetime == '00':
+        start = startm1
+
+    # set end date of retrieval period
+    end = datetime.date(year=int(c.end_date[:4]),
+                        month=int(c.end_date[4:6]),
+                        day=int(c.end_date[6:]))
+    if c.basetime == '00' or c.basetime == '12':
+        endp1 = end + datetime.timedelta(days=1)
+    else:
+        endp1 = end + datetime.timedelta(days=2)
+
+    # set time period of one single retrieval
+    datechunk = datetime.timedelta(days=int(c.date_chunk))
+
+    # --------------  flux data ------------------------------------------------
+    print 'removing old flux content of ' + c.inputdir
+    tobecleaned = UioFiles('*_acc_*.' + str(os.getppid()) + '.*.grb')
+    tobecleaned.list_files(c.inputdir)
+    tobecleaned.delete_files()
+
+    # if forecast for maximum one day (upto 23h) are to be retrieved,
+    # collect accumulation data (flux data)
+    # with additional days in the beginning and at the end
+    # (used for complete disaggregation of original period)
+    if c.maxstep < 24:
+        day = startm1
+        while day < endp1:
+            # retrieve MARS data for the whole period
+            flexpart = EcFlexpart(c, fluxes=True)
+            tmpday = day + datechunk - datetime.timedelta(days=1)
+            if tmpday < endp1:
+                dates = day.strftime("%Y%m%d") + "/to/" + \
+                        tmpday.strftime("%Y%m%d")
+            else:
+                dates = day.strftime("%Y%m%d") + "/to/" + \
+                        end.strftime("%Y%m%d")
+
+            print "retrieve " + dates + " in dir " + c.inputdir
+
+            try:
+                flexpart.retrieve(server, dates, c.inputdir)
+            except IOError:
+                my_error(c, 'MARS request failed')
+
+            day += datechunk
+
+    # if forecast data longer than 24h are to be retrieved,
+    # collect accumulation data (flux data)
+    # with the exact start and end date
+    # (disaggregation will be done for the
+    # exact time period with boundary conditions)
+    else:
+        day = start
+        while day <= end:
+            # retrieve MARS data for the whole period
+            flexpart = EcFlexpart(c, fluxes=True)
+            tmpday = day + datechunk - datetime.timedelta(days=1)
+            if tmpday < end:
+                dates = day.strftime("%Y%m%d") + "/to/" + \
+                        tmpday.trftime("%Y%m%d")
+            else:
+                dates = day.strftime("%Y%m%d") + "/to/" + \
+                        end.strftime("%Y%m%d")
+
+            print "retrieve " + dates + " in dir " + c.inputdir
+
+            try:
+                flexpart.retrieve(server, dates, c.inputdir)
+            except IOError:
+                my_error(c, 'MARS request failed')
+
+            day += datechunk
+
+    # --------------  non flux data --------------------------------------------
+    print 'removing old non flux content of ' + c.inputdir
+    tobecleaned = UioFiles('*__*.' + str(os.getppid()) + '.*.grb')
+    tobecleaned.list_files(c.inputdir)
+    tobecleaned.delete_files()
+
+    day = start
+    while day <= end:
+        # retrieve all non flux MARS data for the whole period
+        flexpart = EcFlexpart(c, fluxes=False)
+        tmpday = day + datechunk - datetime.timedelta(days=1)
+        if tmpday < end:
+            dates = day.strftime("%Y%m%d") + "/to/" + \
+                    tmpday.strftime("%Y%m%d")
+        else:
+            dates = day.strftime("%Y%m%d") + "/to/" + \
+                    end.strftime("%Y%m%d")
+
+        print "retrieve " + dates + " in dir " + c.inputdir
+
+        try:
+            flexpart.retrieve(server, dates, c.inputdir)
+        except IOError:
+            my_error(c, 'MARS request failed')
+
+        day += datechunk
+
+    return
+
+if __name__ == "__main__":
+    main()
Index: python/install.py
===================================================================
--- python/install.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ python/install.py	(revision ff99eae65dfaeec1221e06572d770ebd48feb3f4)
@@ -2,6 +2,5 @@
 # -*- coding: utf-8 -*-
 #************************************************************************
-# TODO AP
-# - localpythonpath should not be set in module load section!
+# ToDo AP
 # - create a class Installation and divide installation in 3 subdefs for
 #   ecgate, local and cca seperatly
@@ -18,4 +17,5 @@
 #        - applied PEP8 style guide
 #        - added documentation
+#        - moved install_args_and_control in here
 #
 # @License:
@@ -45,5 +45,4 @@
 # MODULES
 # ------------------------------------------------------------------------------
-import datetime
 import os
 import sys
@@ -51,14 +50,14 @@
 import subprocess
 import inspect
-from argparse import ArgumentParser,ArgumentDefaultsHelpFormatter
-
-# add path to pythonpath so that python finds its buddies
-localpythonpath = os.path.dirname(os.path.abspath(
-    inspect.getfile(inspect.currentframe())))
-if localpythonpath not in sys.path:
-    sys.path.append(localpythonpath)
+from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
 
 # software specific classes and modules from flex_extract
 from ControlFile import ControlFile
+
+# add path to pythonpath so that python finds its buddies
+LOCAL_PYTHON_PATH = os.path.dirname(os.path.abspath(
+    inspect.getfile(inspect.currentframe())))
+if LOCAL_PYTHON_PATH not in sys.path:
+    sys.path.append(LOCAL_PYTHON_PATH)
 
 # ------------------------------------------------------------------------------
@@ -78,5 +77,5 @@
     '''
 
-    os.chdir(localpythonpath)
+    os.chdir(LOCAL_PYTHON_PATH)
     args, c = install_args_and_control()
 
@@ -84,6 +83,6 @@
         install_via_gateway(c, args.install_target)
     else:
-        print('Please specify installation target (local|ecgate|cca)')
-        print('use -h or --help for help')
+        print 'Please specify installation target (local|ecgate|cca)'
+        print 'use -h or --help for help'
 
     sys.exit()
@@ -152,23 +151,23 @@
     try:
         c = ControlFile(args.controlfile)
-    except:
-        print('Could not read CONTROL file "' + args.controlfile + '"')
-        print('Either it does not exist or its syntax is wrong.')
-        print('Try "' + sys.argv[0].split('/')[-1] +
-              ' -h" to print usage information')
+    except IOError:
+        print 'Could not read CONTROL file "' + args.controlfile + '"'
+        print 'Either it does not exist or its syntax is wrong.'
+        print 'Try "' + sys.argv[0].split('/')[-1] + \
+              ' -h" to print usage information'
         exit(1)
 
     if args.install_target != 'local':
-        if (args.ecgid is None or args.ecuid is None or args.gateway is None
-            or args.destination is None):
-            print('Please enter your ECMWF user id and group id as well as \
+        if args.ecgid is None or args.ecuid is None or args.gateway is None \
+           or args.destination is None:
+            print 'Please enter your ECMWF user id and group id as well as \
                    the \nname of the local gateway and the ectrans \
-                   destination ')
-            print('with command line options --ecuid --ecgid \
-                   --gateway --destination')
-            print('Try "' + sys.argv[0].split('/')[-1] +
-                  ' -h" to print usage information')
-            print('Please consult ecaccess documentation or ECMWF user support \
-                   for further details')
+                   destination '
+            print 'with command line options --ecuid --ecgid \
+                   --gateway --destination'
+            print 'Try "' + sys.argv[0].split('/')[-1] + \
+                  ' -h" to print usage information'
+            print 'Please consult ecaccess documentation or ECMWF user support \
+                   for further details'
             sys.exit(1)
         else:
@@ -178,8 +177,6 @@
             c.destination = args.destination
 
-    try:
+    if args.makefile:
         c.makefile = args.makefile
-    except:
-        pass
 
     if args.install_target == 'local':
@@ -240,5 +237,5 @@
                             c.flexpart_root_scripts
                 else:
-                    data='export FLEXPART_ROOT_SCRIPTS=$HOME'
+                    data = 'export FLEXPART_ROOT_SCRIPTS=$HOME'
             if target.lower() != 'local':
                 if '--workdir' in data:
@@ -292,14 +289,12 @@
         fo.close()
 
-
-
     if target.lower() == 'local':
         # compile CONVERT2
         if c.flexpart_root_scripts is None or c.flexpart_root_scripts == '../':
-            print('Warning: FLEXPART_ROOT_SCRIPTS has not been specified')
-            print('Only CONVERT2 will be compiled in ' + ecd + '/../src')
+            print 'Warning: FLEXPART_ROOT_SCRIPTS has not been specified'
+            print 'Only CONVERT2 will be compiled in ' + ecd + '/../src'
         else:
             c.flexpart_root_scripts = os.path.expandvars(os.path.expanduser(
-                                        c.flexpart_root_scripts))
+                c.flexpart_root_scripts))
             if os.path.abspath(ecd) != os.path.abspath(c.flexpart_root_scripts):
                 os.chdir('/')
@@ -311,5 +306,5 @@
                 try:
                     os.makedirs(c.flexpart_root_scripts + '/ECMWFDATA7.1')
-                except:
+                finally:
                     pass
                 os.chdir(c.flexpart_root_scripts + '/ECMWFDATA7.1')
@@ -329,15 +324,16 @@
             p = subprocess.check_call(['rm'] + flist)
         try:
-            print(('Using makefile: ' + makefile))
+            print 'Using makefile: ' + makefile
             p = subprocess.check_call(['make', '-f', makefile])
-            p = subprocess.check_call(['ls', '-l','CONVERT2'])
-        except:
-            print('compile failed - please edit ' + makefile +
-                  ' or try another Makefile in the src directory.')
-            print('most likely GRIB_API_INCLUDE_DIR, GRIB_API_LIB '
-                    'and EMOSLIB must be adapted.')
-            print('Available Makefiles:')
-            print(glob.glob('Makefile*'))
-
+            p = subprocess.check_call(['ls', '-l', 'CONVERT2'])
+        except subprocess.CalledProcessError as e:
+            print 'compile failed with the following error:'
+            print e.output
+            print 'please edit ' + makefile + \
+                  ' or try another Makefile in the src directory.'
+            print 'most likely GRIB_API_INCLUDE_DIR, GRIB_API_LIB  \
+                   and EMOSLIB must be adapted.'
+            print 'Available Makefiles:'
+            print glob.glob('Makefile*')
     elif target.lower() == 'ecgate':
         os.chdir('/')
@@ -352,16 +348,22 @@
                                        'ecgate:/home/ms/' + c.ecgid + '/' +
                                        c.ecuid + '/ECMWFDATA7.1.tar'])
-        except:
-            print('ecaccess-file-put failed! Probably the eccert key has expired.')
+        except subprocess.CalledProcessError as e:
+            print 'ecaccess-file-put failed! \
+                   Probably the eccert key has expired.'
             exit(1)
-        p = subprocess.check_call(['ecaccess-job-submit',
-                                   '-queueName',
-                                   target,
-                                   ecd + 'python/compilejob.ksh'])
-        print('compilejob.ksh has been submitted to ecgate for '
-                'installation in ' + c.ec_flexpart_root_scripts +
-                '/ECMWFDATA7.1')
-        print('You should get an email with subject flexcompile within '
-                'the next few minutes')
+
+        try:
+            p = subprocess.check_call(['ecaccess-job-submit',
+                                       '-queueName',
+                                       target,
+                                       ecd + 'python/compilejob.ksh'])
+            print 'compilejob.ksh has been submitted to ecgate for  \
+                   installation in ' + c.ec_flexpart_root_scripts + \
+                   '/ECMWFDATA7.1'
+            print 'You should get an email with subject flexcompile within  \
+                   the next few minutes'
+        except subprocess.CalledProcessError as e:
+            print 'ecaccess-job-submit failed!'
+            exit(1)
 
     elif target.lower() == 'cca':
@@ -377,21 +379,25 @@
                                        'cca:/home/ms/' + c.ecgid + '/' +
                                        c.ecuid + '/ECMWFDATA7.1.tar'])
-        except:
-            print('ecaccess-file-put failed! '
-                    'Probably the eccert key has expired.')
+        except subprocess.CalledProcessError as e:
+            print 'ecaccess-file-put failed! \
+                   Probably the eccert key has expired.'
             exit(1)
 
-        p=subprocess.check_call(['ecaccess-job-submit',
-                                '-queueName',
-                                target,
-                                ecd + 'python/compilejob.ksh'])
-        print('compilejob.ksh has been submitted to cca for installation in ' +
-              c.ec_flexpart_root_scripts + '/ECMWFDATA7.1')
-        print('You should get an email with subject flexcompile '
-                'within the next few minutes')
+        try:
+            p = subprocess.check_call(['ecaccess-job-submit',
+                                       '-queueName',
+                                       target,
+                                       ecd + 'python/compilejob.ksh'])
+            print 'compilejob.ksh has been submitted to cca for installation in ' +\
+                  c.ec_flexpart_root_scripts + '/ECMWFDATA7.1'
+            print 'You should get an email with subject flexcompile \
+                   within the next few minutes'
+        except subprocess.CalledProcessError as e:
+            print 'ecaccess-job-submit failed!'
+            exit(1)
 
     else:
-        print('ERROR: unknown installation target ', target)
-        print('Valid targets: ecgate, cca, local')
+        print 'ERROR: unknown installation target ', target
+        print 'Valid targets: ecgate, cca, local'
 
     return
Index: python/plot_retrieved.py
===================================================================
--- python/plot_retrieved.py	(revision ccab8091e3f70844b2b6e73b9aa5e6b41aaf5ff5)
+++ python/plot_retrieved.py	(revision ff99eae65dfaeec1221e06572d770ebd48feb3f4)
@@ -2,5 +2,5 @@
 # -*- coding: utf-8 -*-
 #************************************************************************
-# TODO AP
+# ToDo AP
 # - documentation der Funktionen
 # - docu der progam functionality
@@ -19,5 +19,5 @@
 #        - created function main and moved the two function calls for
 #          arguments and plotting into it
-#        - added function getBasics to extract the boundary conditions
+#        - added function get_basics to extract the boundary conditions
 #          of the data fields from the first grib file it gets.
 #
@@ -33,9 +33,9 @@
 # @Program Content:
 #    - main
-#    - getBasics
-#    - plotRetrieved
-#    - plotTS
-#    - plotMap
-#    - getPlotArgs
+#    - get_basics
+#    - plot_retrieved
+#    - plot_timeseries
+#    - plot_map
+#    - get_plot_args
 #
 #*******************************************************************************
@@ -49,37 +49,25 @@
 import inspect
 import sys
-import glob
 from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
-
-from matplotlib.pylab import *
-import matplotlib.patches as mpatches
-from mpl_toolkits.basemap import Basemap, addcyclic
-import matplotlib.colors as mcolors
-from matplotlib.font_manager import FontProperties
-from matplotlib.patches import Polygon
-import matplotlib.cm as cmx
-import matplotlib.colors as colors
-#from rasotools.utils import stats
+import matplotlib
+import matplotlib.pyplot as plt
+from mpl_toolkits.basemap import Basemap
+from eccodes import codes_grib_new_from_file, codes_get, codes_release, \
+                    codes_get_values
+import numpy as np
+
+# software specific classes and modules from flex_extract
+from ControlFile import ControlFile
+from UioFiles import UioFiles
+
+# add path to pythonpath so that python finds its buddies
+LOCAL_PYTHON_PATH = os.path.dirname(os.path.abspath(
+    inspect.getfile(inspect.currentframe())))
+if LOCAL_PYTHON_PATH not in sys.path:
+    sys.path.append(LOCAL_PYTHON_PATH)
 
 font = {'family': 'monospace', 'size': 12}
 matplotlib.rcParams['xtick.major.pad'] = '20'
-
 matplotlib.rc('font', **font)
-
-from eccodes import *
-import numpy as np
-
-# add path to pythonpath so that python finds its buddies
-localpythonpath = os.path.dirname(os.path.abspath(
-    inspect.getfile(inspect.currentframe())))
-if localpythonpath not in sys.path:
-    sys.path.append(localpythonpath)
-
-# software specific classes and modules from flex_extract
-from Tools import silentremove
-from ControlFile import ControlFile
-#from GribTools import GribTools
-from UIOFiles import UIOFiles
-
 # ------------------------------------------------------------------------------
 # FUNCTION
@@ -88,7 +76,7 @@
     '''
     @Description:
-        If plotRetrieved is called from command line, this function controls
+        If plot_retrieved is called from command line, this function controls
         the program flow and calls the argumentparser function and
-        the plotRetrieved function for plotting the retrieved GRIB data.
+        the plot_retrieved function for plotting the retrieved GRIB data.
 
     @Input:
@@ -98,10 +86,10 @@
         <nothing>
     '''
-    args, c = getPlotArgs()
-    plotRetrieved(args, c)
+    args, c = get_plot_args()
+    plot_retrieved(c)
 
     return
 
-def getBasics(ifile, verb=False):
+def get_basics(ifile, verb=False):
     """
     @Description:
@@ -113,4 +101,5 @@
         ifile: string
             Contains the full absolute path to the ECMWF grib file.
+
         verb (opt): bool
             Is True if there should be extra output in verbose mode.
@@ -127,5 +116,4 @@
             'iDirectionIncrementInDegrees'
     """
-    from eccodes import *
 
     data = {}
@@ -141,6 +129,5 @@
 
         # information needed from grib message
-        keys = [
-                'Ni',
+        keys = ['Ni',
                 'Nj',
                 'latitudeOfFirstGridPointInDegrees',
@@ -149,13 +136,15 @@
                 'longitudeOfLastGridPointInDegrees',
                 'jDirectionIncrementInDegrees',
-                'iDirectionIncrementInDegrees'
-               ]
-
-        if verb: print('\nInformations are: ')
+                'iDirectionIncrementInDegrees']
+
+        if verb:
+            print '\nInformations are: '
         for key in keys:
             # Get the value of the key in a grib message.
-            data[key] = codes_get(gid,key)
-            if verb: print "%s = %s" % (key,data[key])
-        if verb: print '\n'
+            data[key] = codes_get(gid, key)
+            if verb:
+                print "%s = %s" % (key, data[key])
+        if verb:
+            print '\n'
 
         # Free the memory for the message referred as gribid.
@@ -164,5 +153,5 @@
     return data
 
-def getFilesPerDate(files, datelist):
+def get_files_per_date(files, datelist):
     '''
     @Description:
@@ -171,5 +160,5 @@
 
     @Input:
-        files: instance of UIOFiles
+        files: instance of UioFiles
             For description see class documentation.
             It contains the attribute "files" which is a list of pathes
@@ -185,274 +174,17 @@
 
     filelist = []
-    for file in files:
-        fdate = file[-8:]
-        ddate = datetime.datetime.strptime(fdate, '%y%m%d%H')
+    for filename in files:
+        filedate = filename[-8:]
+        ddate = datetime.datetime.strptime(filedate, '%y%m%d%H')
         if ddate in datelist:
-            filelist.append(file)
+            filelist.append(filename)
 
     return filelist
 
-def plotRetrieved(args, c):
+def plot_retrieved(c):
     '''
     @Description:
         Reads GRIB data from a specified time period, a list of levels
         and a specified list of parameter.
-
-    @Input:
-        args: instance of ArgumentParser
-            Contains the commandline arguments from script/program call.
-
-        c: instance of class ControlFile
-            Contains all necessary information of a CONTROL file. The parameters
-            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
-            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
-            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
-            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
-            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, DEBUG, INPUTDIR,
-            OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-            For more information about format and content of the parameter see
-            documentation.
-
-    @Return:
-        <nothing>
-    '''
-    start = datetime.datetime.strptime(c.start_date, '%Y%m%d%H')
-    end = datetime.datetime.strptime(c.end_date, '%Y%m%d%H')
-
-    # create datelist between start and end date
-    datelist = [start] # initialise datelist with first date
-    run_date = start
-    while run_date < end:
-        run_date += datetime.timedelta(hours=int(c.dtime))
-        datelist.append(run_date)
-
-    print 'datelist: ', datelist
-
-    c.paramIds = asarray(c.paramIds, dtype='int')
-    c.levels = asarray(c.levels, dtype='int')
-    c.area = asarray(c.area)
-
-    # index_keys = ["date", "time", "step"]
-    # indexfile = c.inputdir + "/date_time_stepRange.idx"
-    # silentremove(indexfile)
-    # grib = GribTools(inputfiles.files)
-    # # creates new index file
-    # iid = grib.index(index_keys=index_keys, index_file=indexfile)
-
-    # # read values of index keys
-    # index_vals = []
-    # for key in index_keys:
-        # index_vals.append(grib_index_get(iid, key))
-        # print(index_vals[-1])
-        # # index_vals looks for example like:
-        # # index_vals[0]: ('20171106', '20171107', '20171108') ; date
-        # # index_vals[1]: ('0', '1200', '1800', '600') ; time
-        # # index_vals[2]: ('0', '12', '3', '6', '9') ; stepRange
-
-
-
-
-    #index_keys = ["date", "time", "step", "paramId"]
-    #indexfile = c.inputdir + "/date_time_stepRange.idx"
-    #silentremove(indexfile)
-
-    files = UIOFiles(c.prefix+'*')
-    files.listFiles(c.inputdir)
-    ifiles = getFilesPerDate(files.files, datelist)
-    ifiles.sort()
-
-    gdict = getBasics(ifiles[0], verb=False)
-
-    fdict = dict()
-    fmeta = dict()
-    fstamp = dict()
-    for p in c.paramIds:
-        for l in c.levels:
-            key = '{:0>3}_{:0>3}'.format(p, l)
-            fdict[key] = []
-            fmeta[key] = []
-            fstamp[key] = []
-
-    for file in ifiles:
-        f = open(file)
-        print( "Opening file for reading data --- %s" % file)
-        fdate = datetime.datetime.strptime(file[-8:], "%y%m%d%H")
-
-        # Load in memory a grib message from a file.
-        gid = codes_grib_new_from_file(f)
-        while(gid is not None):
-            gtype = codes_get(gid, 'type')
-            paramId = codes_get(gid, 'paramId')
-            parameterName = codes_get(gid, 'parameterName')
-            level = codes_get(gid, 'level')
-
-            if paramId in c.paramIds and level in c.levels:
-                key = '{:0>3}_{:0>3}'.format(paramId, level)
-                print 'key: ', key
-                if len(fstamp[key]) != 0 :
-                    for i in range(len(fstamp[key])):
-                        if fdate < fstamp[key][i]:
-                            fstamp[key].insert(i, fdate)
-                            fmeta[key].insert(i, [paramId, parameterName, gtype,
-                                                fdate, level])
-                            fdict[key].insert(i, flipud(reshape(
-                                            codes_get_values(gid),
-                                            [gdict['Nj'], gdict['Ni']])))
-                            break
-                        elif fdate > fstamp[key][i] and i == len(fstamp[key])-1:
-                            fstamp[key].append(fdate)
-                            fmeta[key].append([paramId, parameterName, gtype,
-                                                fdate, level])
-                            fdict[key].append(flipud(reshape(
-                                            codes_get_values(gid),
-                                            [gdict['Nj'], gdict['Ni']])))
-                            break
-                        elif fdate > fstamp[key][i] and i != len(fstamp[key])-1 \
-                             and fdate < fstamp[key][i+1]:
-                            fstamp[key].insert(i, fdate)
-                            fmeta[key].insert(i, [paramId, parameterName, gtype,
-                                                    fdate, level])
-                            fdict[key].insert(i, flipud(reshape(
-                                            codes_get_values(gid),
-                                            [gdict['Nj'], gdict['Ni']])))
-                            break
-                        else:
-                            pass
-                else:
-                    fstamp[key].append(fdate)
-                    fmeta[key].append((paramId, parameterName, gtype,
-                                       fdate, level))
-                    fdict[key].append(flipud(reshape(
-                        codes_get_values(gid), [gdict['Nj'], gdict['Ni']])))
-
-            codes_release(gid)
-
-            # Load in memory a grib message from a file.
-            gid = codes_grib_new_from_file(f)
-
-        f.close()
-    #print 'fstamp: ', fstamp
-    #exit()
-
-    for k in fdict.keys():
-        print 'fmeta: ', len(fmeta),fmeta
-        fml = fmeta[k]
-        fdl = fdict[k]
-        print 'fm1: ', len(fml), fml
-        #print 'fd1: ', fdl
-        #print zip(fdl, fml)
-        for fd, fm in zip(fdl, fml):
-            print fm
-            ftitle = fm[1] + ' {} '.format(fm[-1]) + \
-                datetime.datetime.strftime(fm[3], '%Y%m%d%H') #+ ' ' + stats(fd)
-            pname = '_'.join(fm[1].split()) + '_{}_'.format(fm[-1]) + \
-                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
-            plotMap(c, fd, fm, gdict, ftitle, pname, 'png')
-
-    for k in fdict.keys():
-        fml = fmeta[k]
-        fdl = fdict[k]
-        fsl = fstamp[k]
-        if fdl:
-            fm = fml[0]
-            fd = fdl[0]
-            ftitle = fm[1] + ' {} '.format(fm[-1]) + \
-                datetime.datetime.strftime(fm[3], '%Y%m%d%H') #+ ' ' + stats(fd)
-            pname = '_'.join(fm[1].split()) + '_{}_'.format(fm[-1]) + \
-                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
-            lat = -20
-            lon = 20
-            plotTS(c, fdl, fml, fsl, lat, lon,
-                           gdict, ftitle, pname, 'png')
-
-    return
-
-def plotTS(c, flist, fmetalist, ftimestamps, lat, lon,
-                   gdict, ftitle, filename, fending, show=False):
-    '''
-    @Description:
-
-    @Input:
-        c:
-
-        flist:
-            The actual data values to be plotted from the grib messages.
-
-        fmetalist: list of strings
-            Contains some meta date for the data field to be plotted:
-            parameter id, parameter Name, grid type, datetime, level
-
-        ftimestamps: list of datetime
-            Contains the time stamps.
-
-        lat:
-
-        lon:
-
-        gdict:
-
-        ftitle: string
-            The title of the timeseries.
-
-        filename: string
-            The time series is stored in a file with this name.
-
-        fending: string
-            Contains the type of plot, e.g. pdf or png
-
-        show: boolean
-            Decides if the plot is shown after plotting or hidden.
-
-    @Return:
-        <nothing>
-    '''
-    print 'plotting timeseries'
-
-    t1 = time.time()
-
-    llx = gdict['longitudeOfFirstGridPointInDegrees']
-    if llx > 180. :
-        llx -= 360.
-    lly = gdict['latitudeOfLastGridPointInDegrees']
-    dxout = gdict['iDirectionIncrementInDegrees']
-    dyout = gdict['jDirectionIncrementInDegrees']
-    urx = gdict['longitudeOfLastGridPointInDegrees']
-    ury = gdict['latitudeOfFirstGridPointInDegrees']
-    numxgrid = gdict['Ni']
-    numygrid = gdict['Nj']
-
-    farr = asarray(flist)
-    #(time, lat, lon)
-
-    lonindex = linspace(llx, urx, numxgrid)
-    latindex = linspace(lly, ury, numygrid)
-    #print len(lonindex), len(latindex), farr.shape
-
-    #latindex = (lat + 90) * 180 / (gdict['Nj'] - 1)
-    #lonindex = (lon + 179) * 360 / gdict['Ni']
-    #print latindex, lonindex
-
-
-    ts = farr[:, 0, 0]#latindex[0], lonindex[0]]
-
-    fig = plt.figure(figsize=(12, 6.7))
-
-    plt.plot(ftimestamps, ts)
-    plt.title(ftitle)
-
-    plt.savefig(c.outputdir+'/'+filename+'_TS.'+fending, facecolor=fig.get_facecolor(), edgecolor='none',format=fending)
-    print 'created ', c.outputdir + '/' + filename
-    if show == True:
-        plt.show()
-    fig.clf()
-    plt.close(fig)
-
-    print time.time() - t1, 's'
-
-    return
-
-def plotMap(c, flist, fmetalist, gdict, ftitle, filename, fending, show=False):
-    '''
-    @Description:
 
     @Input:
@@ -468,115 +200,137 @@
             documentation.
 
-        flist
-
-        fmetalist
-
-        gdict: dict
-            Contains basic informations of the ECMWF grib files, e.g.
-            'Ni', 'Nj', 'latitudeOfFirstGridPointInDegrees',
-            'longitudeOfFirstGridPointInDegrees',
-            'latitudeOfLastGridPointInDegrees',
-            'longitudeOfLastGridPointInDegrees',
-            'jDirectionIncrementInDegrees',
-            'iDirectionIncrementInDegrees'
-
-        ftitle: string
-            The titel of the plot.
-
-        filename: string
-            The plot is stored in a file with this name.
-
-        fending: string
-            Contains the type of plot, e.g. pdf or png
-
-        show: boolean
-            Decides if the plot is shown after plotting or hidden.
-
     @Return:
         <nothing>
     '''
-    print 'plotting map'
-
-    t1 = time.time()
-
-    fig = plt.figure(figsize=(12, 6.7))
-    #mbaxes = fig.add_axes([0.05, 0.15, 0.8, 0.7])
-
-    llx = gdict['longitudeOfFirstGridPointInDegrees'] #- 360
-    if llx > 180. :
-        llx -= 360.
-    lly = gdict['latitudeOfLastGridPointInDegrees']
-    dxout = gdict['iDirectionIncrementInDegrees']
-    dyout = gdict['jDirectionIncrementInDegrees']
-    urx = gdict['longitudeOfLastGridPointInDegrees']
-    ury = gdict['latitudeOfFirstGridPointInDegrees']
-    numxgrid = gdict['Ni']
-    numygrid = gdict['Nj']
-
-    m = Basemap(projection='cyl', llcrnrlon=llx, llcrnrlat=lly,
-                urcrnrlon=urx, urcrnrlat=ury,resolution='i')
-
-    lw = 0.5
-    m.drawmapboundary()
-    x = linspace(llx, urx, numxgrid)
-    y = linspace(lly, ury, numygrid)
-
-    xx, yy = m(*meshgrid(x, y))
-
-    #s = m.contourf(xx, yy, flist)
-
-    s = plt.imshow(flist.T,
-                    extent=(llx, urx, lly, ury),
-                    alpha=1.0,
-                    interpolation='nearest'
-                    #vmin=vn,
-                    #vmax=vx,
-                    #cmap=my_cmap,
-                    #levels=levels,
-                    #cmap=my_cmap,
-                    #norm=LogNorm(vn,vx)
-                    )
-
-    title(ftitle, y=1.08)
-    cb = m.colorbar(s, location="right", pad="10%")
-    #cb.set_label('Contribution per cell (ng m$^{-3}$)',size=14)
-
-    thickline = np.arange(lly,ury+1,10.)
-    thinline  = np.arange(lly,ury+1,5.)
-    m.drawparallels(thickline,color='gray',dashes=[1,1],linewidth=0.5,labels=[1,1,1,1], xoffset=1.) # draw parallels
-    m.drawparallels(np.setdiff1d(thinline,thickline),color='lightgray',dashes=[1,1],linewidth=0.5,labels=[0,0,0,0]) # draw parallels
-
-    thickline = np.arange(llx,urx+1,10.)
-    thinline  = np.arange(llx,urx+1,5.)
-    m.drawmeridians(thickline,color='gray',dashes=[1,1],linewidth=0.5,labels=[1,1,1,1],yoffset=1.) # draw meridians
-    m.drawmeridians(np.setdiff1d(thinline,thickline),color='lightgray',dashes=[1,1],linewidth=0.5,labels=[0,0,0,0]) # draw meridians
-
-    m.drawcoastlines()
-    m.drawcountries()
-
-    plt.savefig(c.outputdir+'/'+filename+'_MAP.'+fending, facecolor=fig.get_facecolor(), edgecolor='none',format=fending)
-    print 'created ', c.outputdir + '/' + filename
-    if show == True:
-        plt.show()
-    fig.clf()
-    plt.close(fig)
-
-    print time.time() - t1, 's'
+    start = datetime.datetime.strptime(c.start_date, '%Y%m%d%H')
+    end = datetime.datetime.strptime(c.end_date, '%Y%m%d%H')
+
+    # create datelist between start and end date
+    datelist = [start] # initialise datelist with first date
+    run_date = start
+    while run_date < end:
+        run_date += datetime.timedelta(hours=int(c.dtime))
+        datelist.append(run_date)
+
+    print 'datelist: ', datelist
+
+    c.paramIds = np.asarray(c.paramIds, dtype='int')
+    c.levels = np.asarray(c.levels, dtype='int')
+    c.area = np.asarray(c.area)
+
+    files = UioFiles(c.prefix+'*')
+    files.list_files(c.inputdir)
+    ifiles = get_files_per_date(files.files, datelist)
+    ifiles.sort()
+
+    gdict = get_basics(ifiles[0], verb=False)
+
+    fdict = dict()
+    fmeta = dict()
+    fstamp = dict()
+    for p in c.paramIds:
+        for l in c.levels:
+            key = '{:0>3}_{:0>3}'.format(p, l)
+            fdict[key] = []
+            fmeta[key] = []
+            fstamp[key] = []
+
+    for filename in ifiles:
+        f = open(filename)
+        print "Opening file for reading data --- %s" % filename
+        fdate = datetime.datetime.strptime(filename[-8:], "%y%m%d%H")
+
+        # Load in memory a grib message from a file.
+        gid = codes_grib_new_from_file(f)
+        while gid is not None:
+            gtype = codes_get(gid, 'type')
+            paramId = codes_get(gid, 'paramId')
+            parameterName = codes_get(gid, 'parameterName')
+            level = codes_get(gid, 'level')
+
+            if paramId in c.paramIds and level in c.levels:
+                key = '{:0>3}_{:0>3}'.format(paramId, level)
+                print 'key: ', key
+                if fstamp[key]:
+                    for i in range(len(fstamp[key])):
+                        if fdate < fstamp[key][i]:
+                            fstamp[key].insert(i, fdate)
+                            fmeta[key].insert(i, [paramId, parameterName, gtype,
+                                                  fdate, level])
+                            fdict[key].insert(i, np.flipud(np.reshape(
+                                codes_get_values(gid),
+                                [gdict['Nj'], gdict['Ni']])))
+                            break
+                        elif fdate > fstamp[key][i] and i == len(fstamp[key])-1:
+                            fstamp[key].append(fdate)
+                            fmeta[key].append([paramId, parameterName, gtype,
+                                               fdate, level])
+                            fdict[key].append(np.flipud(np.reshape(
+                                codes_get_values(gid),
+                                [gdict['Nj'], gdict['Ni']])))
+                            break
+                        elif fdate > fstamp[key][i] and i != len(fstamp[key])-1 \
+                             and fdate < fstamp[key][i+1]:
+                            fstamp[key].insert(i, fdate)
+                            fmeta[key].insert(i, [paramId, parameterName, gtype,
+                                                  fdate, level])
+                            fdict[key].insert(i, np.flipud(np.reshape(
+                                codes_get_values(gid),
+                                [gdict['Nj'], gdict['Ni']])))
+                            break
+                        else:
+                            pass
+                else:
+                    fstamp[key].append(fdate)
+                    fmeta[key].append((paramId, parameterName, gtype,
+                                       fdate, level))
+                    fdict[key].append(np.flipud(np.reshape(
+                        codes_get_values(gid), [gdict['Nj'], gdict['Ni']])))
+
+            codes_release(gid)
+
+            # Load in memory a grib message from a file.
+            gid = codes_grib_new_from_file(f)
+
+        f.close()
+
+    for k in fdict.iterkeys():
+        print 'fmeta: ', len(fmeta), fmeta
+        fml = fmeta[k]
+        fdl = fdict[k]
+        print 'fm1: ', len(fml), fml
+        for fd, fm in zip(fdl, fml):
+            print fm
+            ftitle = fm[1] + ' {} '.format(fm[-1]) + \
+                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
+            pname = '_'.join(fm[1].split()) + '_{}_'.format(fm[-1]) + \
+                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
+            plot_map(c, fd, fm, gdict, ftitle, pname, 'png')
+
+    for k in fdict.iterkeys():
+        fml = fmeta[k]
+        fdl = fdict[k]
+        fsl = fstamp[k]
+        if fdl:
+            fm = fml[0]
+            fd = fdl[0]
+            ftitle = fm[1] + ' {} '.format(fm[-1]) + \
+                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
+            pname = '_'.join(fm[1].split()) + '_{}_'.format(fm[-1]) + \
+                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
+            lat = -20.
+            lon = 20.
+            plot_timeseries(c, fdl, fml, fsl, lat, lon, gdict,
+                            ftitle, pname, 'png')
 
     return
 
-def getPlotArgs():
+def plot_timeseries(c, flist, fmetalist, ftimestamps, lat, lon,
+                    gdict, ftitle, filename, fending, show=False):
     '''
     @Description:
-        Assigns the command line arguments and reads CONTROL file
-        content. Apply default values for non mentioned arguments.
+        Creates a timeseries plot for a given lat/lon position.
 
     @Input:
-        <nothing>
-
-    @Return:
-        args: instance of ArgumentParser
-            Contains the commandline arguments from script/program call.
-
         c: instance of class ControlFile
             Contains all necessary information of a CONTROL file. The parameters
@@ -589,4 +343,249 @@
             For more information about format and content of the parameter see
             documentation.
+
+        flist: numpy array, 2d
+            The actual data values to be plotted from the grib messages.
+
+        fmetalist: list of strings
+            Contains some meta date for the data field to be plotted:
+            parameter id, parameter Name, grid type, datetime, level
+
+        ftimestamps: list of datetime
+            Contains the time stamps.
+
+        lat: float
+            The latitude for which the timeseries should be plotted.
+
+        lon: float
+            The longitude for which the timeseries should be plotted.
+
+        gdict: dict
+            Contains basic informations of the ECMWF grib files, e.g.
+            'Ni', 'Nj', 'latitudeOfFirstGridPointInDegrees',
+            'longitudeOfFirstGridPointInDegrees',
+            'latitudeOfLastGridPointInDegrees',
+            'longitudeOfLastGridPointInDegrees',
+            'jDirectionIncrementInDegrees',
+            'iDirectionIncrementInDegrees'
+
+        ftitle: string
+            The title of the timeseries.
+
+        filename: string
+            The time series is stored in a file with this name.
+
+        fending: string
+            Contains the type of plot, e.g. pdf or png
+
+        show: boolean
+            Decides if the plot is shown after plotting or hidden.
+
+    @Return:
+        <nothing>
+    '''
+    print 'plotting timeseries'
+
+    t1 = time.time()
+
+    #llx = gdict['longitudeOfFirstGridPointInDegrees']
+    #if llx > 180. :
+    #    llx -= 360.
+    #lly = gdict['latitudeOfLastGridPointInDegrees']
+    #dxout = gdict['iDirectionIncrementInDegrees']
+    #dyout = gdict['jDirectionIncrementInDegrees']
+    #urx = gdict['longitudeOfLastGridPointInDegrees']
+    #ury = gdict['latitudeOfFirstGridPointInDegrees']
+    #numxgrid = gdict['Ni']
+    #numygrid = gdict['Nj']
+
+    farr = np.asarray(flist)
+    #(time, lat, lon)
+
+    #lonindex = linspace(llx, urx, numxgrid)
+    #latindex = linspace(lly, ury, numygrid)
+
+    ts = farr[:, 0, 0]
+
+    fig = plt.figure(figsize=(12, 6.7))
+
+    plt.plot(ftimestamps, ts)
+    plt.title(ftitle)
+
+    plt.savefig(c.outputdir + '/' + filename + '_TS.' + fending,
+                facecolor=fig.get_facecolor(),
+                edgecolor='none',
+                format=fending)
+    print 'created ', c.outputdir + '/' + filename
+    if show:
+        plt.show()
+    fig.clf()
+    plt.close(fig)
+
+    print time.time() - t1, 's'
+
+    return
+
+def plot_map(c, flist, fmetalist, gdict, ftitle, filename, fending, show=False):
+    '''
+    @Description:
+        Creates a basemap plot with imshow for a given data field.
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all necessary information of a CONTROL file. The parameters
+            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
+            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
+            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
+            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
+            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, DEBUG, INPUTDIR,
+            OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+            For more information about format and content of the parameter see
+            documentation.
+
+        flist: numpy array, 2d
+            The actual data values to be plotted from the grib messages.
+
+        fmetalist: list of strings
+            Contains some meta date for the data field to be plotted:
+            parameter id, parameter Name, grid type, datetime, level
+
+        gdict: dict
+            Contains basic informations of the ECMWF grib files, e.g.
+            'Ni', 'Nj', 'latitudeOfFirstGridPointInDegrees',
+            'longitudeOfFirstGridPointInDegrees',
+            'latitudeOfLastGridPointInDegrees',
+            'longitudeOfLastGridPointInDegrees',
+            'jDirectionIncrementInDegrees',
+            'iDirectionIncrementInDegrees'
+
+        ftitle: string
+            The titel of the plot.
+
+        filename: string
+            The plot is stored in a file with this name.
+
+        fending: string
+            Contains the type of plot, e.g. pdf or png
+
+        show: boolean
+            Decides if the plot is shown after plotting or hidden.
+
+    @Return:
+        <nothing>
+    '''
+    print 'plotting map'
+
+    t1 = time.time()
+
+    fig = plt.figure(figsize=(12, 6.7))
+    #mbaxes = fig.add_axes([0.05, 0.15, 0.8, 0.7])
+
+    llx = gdict['longitudeOfFirstGridPointInDegrees'] #- 360
+    if llx > 180.:
+        llx -= 360.
+    lly = gdict['latitudeOfLastGridPointInDegrees']
+    #dxout = gdict['iDirectionIncrementInDegrees']
+    #dyout = gdict['jDirectionIncrementInDegrees']
+    urx = gdict['longitudeOfLastGridPointInDegrees']
+    ury = gdict['latitudeOfFirstGridPointInDegrees']
+    #numxgrid = gdict['Ni']
+    #numygrid = gdict['Nj']
+
+    m = Basemap(projection='cyl', llcrnrlon=llx, llcrnrlat=lly,
+                urcrnrlon=urx, urcrnrlat=ury, resolution='i')
+
+    #lw = 0.5
+    m.drawmapboundary()
+    #x = linspace(llx, urx, numxgrid)
+    #y = linspace(lly, ury, numygrid)
+
+    #xx, yy = m(*meshgrid(x, y))
+
+    #s = m.contourf(xx, yy, flist)
+
+    s = plt.imshow(flist.T,
+                   extent=(llx, urx, lly, ury),
+                   alpha=1.0,
+                   interpolation='nearest'
+                   #vmin=vn,
+                   #vmax=vx,
+                   #cmap=my_cmap,
+                   #levels=levels,
+                   #cmap=my_cmap,
+                   #norm=LogNorm(vn,vx)
+                  )
+
+    plt.title(ftitle, y=1.08)
+    cb = m.colorbar(s, location="right", pad="10%")
+    cb.set_label('label', size=14)
+
+    thickline = np.arange(lly, ury+1, 10.)
+    thinline = np.arange(lly, ury+1, 5.)
+    m.drawparallels(thickline,
+                    color='gray',
+                    dashes=[1, 1],
+                    linewidth=0.5,
+                    labels=[1, 1, 1, 1],
+                    xoffset=1.)
+    m.drawparallels(np.setdiff1d(thinline, thickline),
+                    color='lightgray',
+                    dashes=[1, 1],
+                    linewidth=0.5,
+                    labels=[0, 0, 0, 0])
+
+    thickline = np.arange(llx, urx+1, 10.)
+    thinline = np.arange(llx, urx+1, 5.)
+    m.drawmeridians(thickline,
+                    color='gray',
+                    dashes=[1, 1],
+                    linewidth=0.5,
+                    labels=[1, 1, 1, 1],
+                    yoffset=1.)
+    m.drawmeridians(np.setdiff1d(thinline, thickline),
+                    color='lightgray',
+                    dashes=[1, 1],
+                    linewidth=0.5,
+                    labels=[0, 0, 0, 0])
+
+    m.drawcoastlines()
+    m.drawcountries()
+
+    plt.savefig(c.outputdir + '/' + filename + '_MAP.' + fending,
+                facecolor=fig.get_facecolor(),
+                edgecolor='none',
+                format=fending)
+    print 'created ', c.outputdir + '/' + filename
+    if show:
+        plt.show()
+    fig.clf()
+    plt.close(fig)
+
+    print time.time() - t1, 's'
+
+    return
+
+def get_plot_args():
+    '''
+    @Description:
+        Assigns the command line arguments and reads CONTROL file
+        content. Apply default values for non mentioned arguments.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        args: instance of ArgumentParser
+            Contains the commandline arguments from script/program call.
+
+        c: instance of class ControlFile
+            Contains all necessary information of a CONTROL file. The parameters
+            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
+            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
+            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
+            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
+            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, DEBUG, INPUTDIR,
+            OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+            For more information about format and content of the parameter see
+            documentation.
     '''
     parser = ArgumentParser(description='Plot retrieved GRIB data from ' + \
@@ -597,11 +596,11 @@
     parser.add_argument("--start_date", dest="start_date",
                         help="start date YYYYMMDD")
-    parser.add_argument( "--end_date", dest="end_date",
-                         help="end_date YYYYMMDD")
+    parser.add_argument("--end_date", dest="end_date",
+                        help="end_date YYYYMMDD")
 
     parser.add_argument("--start_step", dest="start_step",
                         help="start step in hours")
-    parser.add_argument( "--end_step", dest="end_step",
-                         help="end step in hours")
+    parser.add_argument("--end_step", dest="end_step",
+                        help="end step in hours")
 
 # some arguments that override the default in the CONTROL file
@@ -635,7 +634,6 @@
     except IOError:
         try:
-            c = ControlFile(localpythonpath + args.controlfile)
-
-        except:
+            c = ControlFile(LOCAL_PYTHON_PATH + args.controlfile)
+        except IOError:
             print 'Could not read CONTROL file "' + args.controlfile + '"'
             print 'Either it does not exist or its syntax is wrong.'
@@ -682,3 +680,2 @@
 if __name__ == "__main__":
     main()
-
Index: python/prepareFLEXPART.py
===================================================================
--- python/prepareFLEXPART.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ 	(revision )
@@ -1,201 +1,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-# - wieso cleanup in main wenn es in prepareflexpart bereits abgefragt wurde?
-#   doppelt gemoppelt?
-# - wieso start=startm1 wenn basetime = 0 ?  wenn die fluxes nicht mehr
-#   relevant sind? verstehe ich nicht
-#************************************************************************
-#*******************************************************************************
-# @Author: Anne Fouilloux (University of Oslo)
-#
-# @Date: October 2014
-#
-# @Change History:
-#
-#    November 2015 - Leopold Haimberger (University of Vienna):
-#        - using the WebAPI also for general MARS retrievals
-#        - job submission on ecgate and cca
-#        - job templates suitable for twice daily operational dissemination
-#        - dividing retrievals of longer periods into digestable chunks
-#        - retrieve also longer term forecasts, not only analyses and
-#          short term forecast data
-#        - conversion into GRIB2
-#        - conversion into .fp format for faster execution of FLEXPART
-#
-#    February 2018 - Anne Philipp (University of Vienna):
-#        - applied PEP8 style guide
-#        - added documentation
-#        - minor changes in programming style for consistence
-#        - BUG: removed call of cleanup-Function after call of
-#               prepareFlexpart in main since it is already called in
-#               prepareFlexpart at the end!
-#        - created function main and moved the two function calls for
-#          arguments and prepareFLEXPART into it
-#
-# @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.
-#
-# @Program Functionality:
-#    This program prepares the final version of the grib files which are
-#    then used by FLEXPART. It converts the bunch of grib files extracted
-#    via getMARSdata by doing for example the necessary conversion to get
-#    consistent grids or the disaggregation of flux data. Finally, the
-#    program combines the data fields in files per available hour with the
-#    naming convention xxYYMMDDHH, where xx should be 2 arbitrary letters
-#    (mostly xx is chosen to be "EN").
-#
-# @Program Content:
-#    - main
-#    - prepareFLEXPART
-#
-#*******************************************************************************
-
-# ------------------------------------------------------------------------------
-# MODULES
-# ------------------------------------------------------------------------------
-import shutil
-import datetime
-#import time
-import os
-import inspect
-import sys
-import socket
-from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
-
-hostname = socket.gethostname()
-ecapi = 'ecmwf' not in hostname
-try:
-    if ecapi:
-        import ecmwfapi
-except ImportError:
-    ecapi = False
-
-# add path to pythonpath so that python finds its buddies
-localpythonpath = os.path.dirname(os.path.abspath(
-    inspect.getfile(inspect.currentframe())))
-if localpythonpath not in sys.path:
-    sys.path.append(localpythonpath)
-
-# software specific classes and modules from flex_extract
-from UIOFiles import UIOFiles
-from Tools import interpret_args_and_control, cleanup
-from ECFlexpart import ECFlexpart
-# ------------------------------------------------------------------------------
-# FUNCTION
-# ------------------------------------------------------------------------------
-def main():
-    '''
-    @Description:
-        If prepareFLEXPART is called from command line, this function controls
-        the program flow and calls the argumentparser function and
-        the prepareFLEXPART function for preparation of GRIB data for FLEXPART.
-
-    @Input:
-        <nothing>
-
-    @Return:
-        <nothing>
-    '''
-    args, c = interpret_args_and_control()
-    prepareFLEXPART(args, c)
-
-    return
-
-def prepareFLEXPART(args, c):
-    '''
-    @Description:
-        Lists all grib files retrieved from MARS with getMARSdata and
-        uses prepares data for the use in FLEXPART. Specific data fields
-        are converted to a different grid and the flux data are going to be
-        disaggregated. The data fields are collected by hour and stored in
-        a file with a specific FLEXPART relevant naming convention.
-
-    @Input:
-        args: instance of ArgumentParser
-            Contains the commandline arguments from script/program call.
-
-        c: instance of class ControlFile
-            Contains all the parameters of CONTROL file, which are e.g.:
-            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
-            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
-            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
-            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
-            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
-            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
-            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
-
-            For more information about format and content of the parameter
-            see documentation.
-
-    @Return:
-        <nothing>
-    '''
-
-    if not args.ppid:
-        c.ppid = str(os.getppid())
-    else:
-        c.ppid = args.ppid
-
-    c.ecapi = ecapi
-
-    # create the start and end date
-    start = datetime.date(year=int(c.start_date[:4]),
-                          month=int(c.start_date[4:6]),
-                          day=int(c.start_date[6:]))
-
-    end = datetime.date(year=int(c.end_date[:4]),
-                        month=int(c.end_date[4:6]),
-                        day=int(c.end_date[6:]))
-
-    # to deaccumulate the fluxes correctly
-    # one day ahead of the start date and
-    # one day after the end date is needed
-    startm1 = start - datetime.timedelta(days=1)
-    endp1 = end + datetime.timedelta(days=1)
-
-    # get all files with flux data to be deaccumulated
-    inputfiles = UIOFiles('*OG_acc_SL*.' + c.ppid + '.*')
-    inputfiles.listFiles(c.inputdir)
-
-    # create output dir if necessary
-    if not os.path.exists(c.outputdir):
-        os.makedirs(c.outputdir)
-
-    # deaccumulate the flux data
-    flexpart = ECFlexpart(c, fluxes=True)
-    flexpart.write_namelist(c, 'fort.4')
-    flexpart.deacc_fluxes(inputfiles, c)
-
-    print('Prepare ' + start.strftime("%Y%m%d") +
-          "/to/" + end.strftime("%Y%m%d"))
-
-    # get a list of all files from the root inputdir
-    inputfiles = UIOFiles('????__??.*' + c.ppid + '.*')
-    inputfiles.listFiles(c.inputdir)
-
-    # produce FLEXPART-ready GRIB files and
-    # process GRIB files -
-    # copy/transfer/interpolate them or make them GRIB2
-    if c.basetime == '00':
-        start = startm1
-
-    flexpart = ECFlexpart(c, fluxes=False)
-    flexpart.create(inputfiles, c)
-    flexpart.process_output(c)
-
-    # check if in debugging mode, then store all files
-    # otherwise delete temporary files
-    if int(c.debug) != 0:
-        print('Temporary files left intact')
-    else:
-        cleanup(c)
-
-    return
-
-if __name__ == "__main__":
-    main()
Index: python/prepare_flexpart.py
===================================================================
--- python/prepare_flexpart.py	(revision None)
+++ python/prepare_flexpart.py	(revision None)
@@ -0,0 +1,196 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#************************************************************************
+# ToDo AP
+# - wieso start=startm1 wenn basetime = 0 ?  wenn die fluxes nicht mehr
+#   relevant sind? verstehe ich nicht
+#************************************************************************
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - using the WebAPI also for general MARS retrievals
+#        - job submission on ecgate and cca
+#        - job templates suitable for twice daily operational dissemination
+#        - dividing retrievals of longer periods into digestable chunks
+#        - retrieve also longer term forecasts, not only analyses and
+#          short term forecast data
+#        - conversion into GRIB2
+#        - conversion into .fp format for faster execution of FLEXPART
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - minor changes in programming style for consistence
+#        - BUG: removed call of clean_up-Function after call of
+#               prepareFlexpart in main since it is already called in
+#               prepareFlexpart at the end!
+#        - created function main and moved the two function calls for
+#          arguments and prepare_flexpart into it
+#
+# @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.
+#
+# @Program Functionality:
+#    This program prepares the final version of the grib files which are
+#    then used by FLEXPART. It converts the bunch of grib files extracted
+#    via get_mars_data by doing for example the necessary conversion to get
+#    consistent grids or the disaggregation of flux data. Finally, the
+#    program combines the data fields in files per available hour with the
+#    naming convention xxYYMMDDHH, where xx should be 2 arbitrary letters
+#    (mostly xx is chosen to be "EN").
+#
+# @Program Content:
+#    - main
+#    - prepare_flexpart
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import datetime
+import os
+import inspect
+import sys
+import socket
+
+# software specific classes and modules from flex_extract
+from UioFiles import UioFiles
+from tools import interpret_args_and_control, clean_up
+from EcFlexpart import EcFlexpart
+
+ecapi = 'ecmwf' not in socket.gethostname()
+try:
+    if ecapi:
+        import ecmwfapi
+except ImportError:
+    ecapi = False
+
+# add path to pythonpath so that python finds its buddies
+LOCAL_PYTHON_PATH = os.path.dirname(os.path.abspath(
+    inspect.getfile(inspect.currentframe())))
+if LOCAL_PYTHON_PATH not in sys.path:
+    sys.path.append(LOCAL_PYTHON_PATH)
+
+# ------------------------------------------------------------------------------
+# FUNCTION
+# ------------------------------------------------------------------------------
+def main():
+    '''
+    @Description:
+        If prepare_flexpart is called from command line, this function controls
+        the program flow and calls the argumentparser function and
+        the prepare_flexpart function for preparation of GRIB data for FLEXPART.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        <nothing>
+    '''
+    args, c = interpret_args_and_control()
+    prepare_flexpart(args, c)
+
+    return
+
+def prepare_flexpart(args, c):
+    '''
+    @Description:
+        Lists all grib files retrieved from MARS with get_mars_data and
+        uses prepares data for the use in FLEXPART. Specific data fields
+        are converted to a different grid and the flux data are going to be
+        disaggregated. The data fields are collected by hour and stored in
+        a file with a specific FLEXPART relevant naming convention.
+
+    @Input:
+        args: instance of ArgumentParser
+            Contains the commandline arguments from script/program call.
+
+        c: instance of class ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+    @Return:
+        <nothing>
+    '''
+
+    if not args.ppid:
+        c.ppid = str(os.getppid())
+    else:
+        c.ppid = args.ppid
+
+    c.ecapi = ecapi
+
+    # create the start and end date
+    start = datetime.date(year=int(c.start_date[:4]),
+                          month=int(c.start_date[4:6]),
+                          day=int(c.start_date[6:]))
+
+    end = datetime.date(year=int(c.end_date[:4]),
+                        month=int(c.end_date[4:6]),
+                        day=int(c.end_date[6:]))
+
+    # to deaccumulate the fluxes correctly
+    # one day ahead of the start date and
+    # one day after the end date is needed
+    startm1 = start - datetime.timedelta(days=1)
+#    endp1 = end + datetime.timedelta(days=1)
+
+    # get all files with flux data to be deaccumulated
+    inputfiles = UioFiles('*OG_acc_SL*.' + c.ppid + '.*')
+    inputfiles.list_files(c.inputdir)
+
+    # create output dir if necessary
+    if not os.path.exists(c.outputdir):
+        os.makedirs(c.outputdir)
+
+    # deaccumulate the flux data
+    flexpart = EcFlexpart(c, fluxes=True)
+    flexpart.write_namelist(c, 'fort.4')
+    flexpart.deacc_fluxes(inputfiles, c)
+
+    print 'Prepare ' + start.strftime("%Y%m%d") + \
+          "/to/" + end.strftime("%Y%m%d")
+
+    # get a list of all files from the root inputdir
+    inputfiles = UioFiles('????__??.*' + c.ppid + '.*')
+    inputfiles.list_files(c.inputdir)
+
+    # produce FLEXPART-ready GRIB files and
+    # process GRIB files -
+    # copy/transfer/interpolate them or make them GRIB2
+    if c.basetime == '00':
+        start = startm1
+
+    flexpart = EcFlexpart(c, fluxes=False)
+    flexpart.create(inputfiles, c)
+    flexpart.process_output(c)
+
+    # check if in debugging mode, then store all files
+    # otherwise delete temporary files
+    if int(c.debug) != 0:
+        print 'Temporary files left intact'
+    else:
+        clean_up(c)
+
+    return
+
+if __name__ == "__main__":
+    main()
Index: python/profiling.py
===================================================================
--- python/profiling.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ python/profiling.py	(revision ff99eae65dfaeec1221e06572d770ebd48feb3f4)
@@ -2,5 +2,5 @@
 # -*- coding: utf-8 -*-
 #************************************************************************
-# TODO AP
+# ToDo AP
 # - check of license of book content
 #************************************************************************
@@ -66,5 +66,5 @@
         result = fn(*args, **kwargs)
         t2 = time.time()
-        print("@timefn:" + fn.func_name + " took " + str(t2 - t1) + " seconds")
+        print "@timefn:" + fn.func_name + " took " + str(t2 - t1) + " seconds"
 
         return result
Index: python/submit.py
===================================================================
--- python/submit.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ python/submit.py	(revision ff99eae65dfaeec1221e06572d770ebd48feb3f4)
@@ -1,14 +1,4 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-#
-# - Change History ist nicht angepasst ans File! Original geben lassen
-# - dead code ? what to do?
-# - seperate operational and reanlysis for clarification
-# - divide in two submits , ondemand und operational
-# -
-#************************************************************************
-
 #*******************************************************************************
 # @Author: Anne Fouilloux (University of Oslo)
@@ -37,5 +27,5 @@
 #    program flow.
 #    If it is supposed to work locally then it works through the necessary
-#    functions getMARSdata and prepareFlexpart. Otherwise it prepares
+#    functions get_mars_data and prepareFlexpart. Otherwise it prepares
 #    a shell job script which will do the necessary work on the
 #    ECMWF server and is submitted via ecaccess-job-submit.
@@ -52,17 +42,17 @@
 import os
 import sys
-import glob
 import subprocess
 import inspect
-# add path to pythonpath so that python finds its buddies
-localpythonpath = os.path.dirname(os.path.abspath(
-    inspect.getfile(inspect.currentframe())))
-if localpythonpath not in sys.path:
-    sys.path.append(localpythonpath)
 
 # software specific classes and modules from flex_extract
-from Tools import interpret_args_and_control, normalexit
-from getMARSdata import getMARSdata
-from prepareFLEXPART import prepareFLEXPART
+from tools import interpret_args_and_control, normal_exit
+from get_mars_data import get_mars_data
+from prepare_flexpart import prepare_flexpart
+
+# add path to pythonpath so that python finds its buddies
+LOCAL_PYTHON_PATH = os.path.dirname(os.path.abspath(
+    inspect.getfile(inspect.currentframe())))
+if LOCAL_PYTHON_PATH not in sys.path:
+    sys.path.append(LOCAL_PYTHON_PATH)
 
 # ------------------------------------------------------------------------------
@@ -84,15 +74,17 @@
         <nothing>
     '''
-    calledfromdir = os.getcwd()
+
+    called_from_dir = os.getcwd()
     args, c = interpret_args_and_control()
+
     # on local side
     if args.queue is None:
         if c.inputdir[0] != '/':
-            c.inputdir = os.path.join(calledfromdir, c.inputdir)
+            c.inputdir = os.path.join(called_from_dir, c.inputdir)
         if c.outputdir[0] != '/':
-            c.outputdir = os.path.join(calledfromdir, c.outputdir)
-        getMARSdata(args, c)
-        prepareFLEXPART(args, c)
-        normalexit(c)
+            c.outputdir = os.path.join(called_from_dir, c.outputdir)
+        get_mars_data(args, c)
+        prepare_flexpart(args, c)
+        normal_exit(c)
     # on ECMWF server
     else:
@@ -139,9 +131,8 @@
 
     # put all parameters of ControlFile instance into a list
-    clist = c.tolist()
+    clist = c.to_list() # ondemand
     colist = []  # operational
     mt = 0
 
-#AP wieso 2 for loops?
     for elem in clist:
         if 'maxstep' in elem:
@@ -152,6 +143,5 @@
             elem = 'start_date ' + '${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY}'
         if 'end_date' in elem:
-#AP Fehler?! Muss end_date heissen
-            elem = 'start_date ' + '${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY}'
+            elem = 'end_date ' + '${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY}'
         if 'base_time' in elem:
             elem = 'base_time ' + '${MSJ_BASETIME}'
@@ -173,9 +163,11 @@
         p = subprocess.check_call(['ecaccess-job-submit', '-queueName',
                                    queue, 'job.ksh'])
-    except:
-        print('ecaccess-job-submit failed, probably eccert has expired')
+    except subprocess.CalledProcessError as e:
+        print 'ecaccess-job-submit failed!'
+        print 'Error Message: '
+        print e.output
         exit(1)
 
-    print('You should get an email with subject flex.hostname.pid')
+    print 'You should get an email with subject flex.hostname.pid'
 
     return
Index: python/test_suite.py
===================================================================
--- python/test_suite.py	(revision None)
+++ python/test_suite.py	(revision None)
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#************************************************************************
+# ToDo AP
+# - provide more tests
+# - provide more documentation
+#************************************************************************
+
+#*******************************************************************************
+# @Author: Leopold Haimberger (University of Vienna)
+#
+# @Date: December 2015
+#
+# @Change History:
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#
+# @License:
+#    (C) Copyright 2015-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.
+#
+# @Program Functionality:
+#    This script triggers the ECMWFDATA test suite. Call with
+#    test_suite.py [test group]
+#
+# @Program Content:
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import sys
+import json
+import subprocess
+
+# ------------------------------------------------------------------------------
+# PROGRAM
+# ------------------------------------------------------------------------------
+try:
+    taskfile = open('test_suite.json')
+except IOError:
+    print 'could not open suite definition file test_suite.json'
+    exit()
+
+if not os.path.isfile('../src/CONVERT2'):
+    print '../src/CONVERT2 could not be found'
+    print 'please run "install.py --target=local" first'
+    exit()
+
+fprs = os.getenv('FLEXPART_ROOT_SCRIPTS')
+if fprs is None:
+    print 'FLEXPART_ROOT_SCRIPTS not set .. some test jobs may fail'
+
+tasks = json.load(taskfile, encoding='latin-1')
+taskfile.close()
+if not os.path.exists('../test'):
+    os.makedirs('../test')
+if len(sys.argv) > 1:
+    groups = sys.argv[1:]
+else:
+    groups = ['xinstall', 'default', 'ops', 'work', 'cv', 'fc']#,'hires']
+jobcounter = 0
+jobfailed = 0
+for g in groups:
+    try:
+        tk, tv = g, tasks[g]
+    finally:
+        pass
+    garglist = []
+    for ttk, ttv in tv.iteritems():
+        if isinstance(ttv, basestring):
+            if ttk != 'script':
+                garglist.append('--' + ttk)
+                if ttv[0] == '$':
+                    garglist.append(os.path.expandvars(ttv))
+                else:
+                    garglist.append(ttv)
+    for ttk, ttv in tv.iteritems():
+        if isinstance(ttv, dict):
+            arglist = []
+            for tttk, tttv in ttv.iteritems():
+                if isinstance(tttv, basestring):
+                    arglist.append('--' + tttk)
+                    if '$' in tttv[0]:
+                        arglist.append(os.path.expandvars(tttv))
+                    else:
+                        arglist.append(tttv)
+            print 'Command: ', ' '.join([tv['script']] + garglist + arglist)
+            o = '../test/' + tk + '_' + ttk + '_' + '_'.join(ttv.keys())
+            print 'Output will be sent to ', o
+            f = open(o, 'w')
+            try:
+                p = subprocess.check_call([tv['script']] + garglist + arglist,
+                                          stdout=f, stderr=f)
+            except subprocess.CalledProcessError as e:
+                f.write('\nFAILED\n')
+                print 'FAILED'
+                jobfailed += 1
+            jobcounter += 1
+            f.close()
+
+print 'Test suite tasks completed'
+print str(jobcounter-jobfailed) + ' successful, ' + str(jobfailed) + ' failed'
+print 'If tasks have been submitted via ECACCESS please check emails'
Index: python/testsuite.py
===================================================================
--- python/testsuite.py	(revision 991df6ad0a703d97e1e192a0a6106e1d9ba47e8e)
+++ 	(revision )
@@ -1,114 +1,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#************************************************************************
-# TODO AP
-#
-# - provide more tests
-# - provide more documentation
-# -
-#************************************************************************
-
-#*******************************************************************************
-# @Author: Leopold Haimberger (University of Vienna)
-#
-# @Date: December 2015
-#
-# @Change History:
-#
-#    February 2018 - Anne Philipp (University of Vienna):
-#        - applied PEP8 style guide
-#        - added documentation
-#
-# @License:
-#    (C) Copyright 2015-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.
-#
-# @Program Functionality:
-#    This script triggers the ECMWFDATA test suite. Call with
-#    testsuite.py [test group]
-#
-# @Program Content:
-#
-#*******************************************************************************
-
-# ------------------------------------------------------------------------------
-# MODULES
-# ------------------------------------------------------------------------------
-import os
-import sys
-import json
-import subprocess
-
-# ------------------------------------------------------------------------------
-# PROGRAM
-# ------------------------------------------------------------------------------
-try:
-    taskfile = open('testsuite.json')
-except:
-    print 'could not open suite definition file testsuite.json'
-    exit()
-
-if not os.path.isfile('../src/CONVERT2'):
-    print '../src/CONVERT2 could not be found'
-    print 'please run "install.py --target=local" first'
-    exit()
-
-fprs = os.getenv('FLEXPART_ROOT_SCRIPTS')
-if fprs is None:
-    print 'FLEXPART_ROOT_SCRIPTS not set .. some test jobs may fail'
-
-tasks = json.load(taskfile, encoding='latin-1')
-taskfile.close()
-if not os.path.exists('../test'):
-    os.makedirs('../test')
-if len(sys.argv) > 1:
-    groups = sys.argv[1:]
-else:
-    groups = ['xinstall', 'default', 'ops', 'work', 'cv', 'fc']#,'hires']
-jobcounter = 0
-jobfailed = 0
-for g in groups:
-    try:
-        tk, tv = g, tasks[g]
-    except:
-        continue
-    garglist = []
-    for ttk, ttv in tv.iteritems():
-        if isinstance(ttv, basestring):
-            if ttk != 'script':
-                garglist.append('--' + ttk)
-                if '$' == ttv[0]:
-                    garglist.append(os.path.expandvars(ttv))
-                else:
-                    garglist.append(ttv)
-    for ttk, ttv in tv.iteritems():
-        if isinstance(ttv, dict):
-            arglist = []
-            for tttk, tttv in ttv.iteritems():
-                if isinstance(tttv, basestring):
-                        arglist.append('--' + tttk)
-                        if '$' in tttv[0]:
-                            arglist.append(os.path.expandvars(tttv))
-                        else:
-                            arglist.append(tttv)
-            print 'Command: ', ' '.join([tv['script']] + garglist + arglist)
-            o = '../test/' + tk + '_' + ttk + '_' + '_'.join(ttv.keys())
-            print 'Output will be sent to ', o
-            f = open(o, 'w')
-            try:
-                p = subprocess.check_call([tv['script']] + garglist + arglist,
-                                          stdout=f, stderr=f)
-            except:
-                f.write('\nFAILED\n')
-                print 'FAILED'
-                jobfailed += 1
-            jobcounter += 1
-            f.close()
-
-print 'Test suite tasks completed'
-print str(jobcounter-jobfailed) + ' successful, ' + str(jobfailed) + ' failed'
-print 'If tasks have been submitted via ECACCESS please check emails'
-
-#print tasks
Index: python/tools.py
===================================================================
--- python/tools.py	(revision None)
+++ python/tools.py	(revision None)
@@ -0,0 +1,522 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#************************************************************************
+# ToDo AP
+# - check my_error
+# - check normal_exit
+# - check get_list_as_string
+# - seperate args and control interpretation
+#************************************************************************
+#*******************************************************************************
+# @Author: Anne Philipp (University of Vienna)
+#
+# @Date: May 2018
+#
+# @Change History:
+#    October 2014 - Anne Fouilloux (University of Oslo)
+#        - created functions silent_remove and product (taken from ECMWF)
+#
+#    November 2015 - Leopold Haimberger (University of Vienna)
+#        - created functions: interpret_args_and_control, clean_up
+#          my_error, normal_exit, init128, to_param_id
+#
+#    April 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - moved all functions from file Flexparttools to this file tools
+#        - added function get_list_as_string
+#
+# @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.
+#
+# @Modul Description:
+#    This module contains a couple of helpful functions which are
+#    used in different places in flex_extract.
+#
+# @Module Content:
+#    - interpret_args_and_control
+#    - clean_up
+#    - my_error
+#    - normal_exit
+#    - product
+#    - silent_remove
+#    - init128
+#    - to_param_id
+#    - get_list_as_string
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import errno
+import sys
+import glob
+import inspect
+import subprocess
+import traceback
+from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
+import numpy as np
+
+# software specific class from flex_extract
+from ControlFile import ControlFile
+
+# ------------------------------------------------------------------------------
+# FUNCTIONS
+# ------------------------------------------------------------------------------
+
+def interpret_args_and_control():
+    '''
+    @Description:
+        Assigns the command line arguments and reads CONTROL file
+        content. Apply default values for non mentioned arguments.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        args: instance of ArgumentParser
+            Contains the commandline arguments from script/program call.
+
+        c: instance of class ControlFile
+            Contains all necessary information of a CONTROL file. The parameters
+            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
+            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
+            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
+            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
+            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, DEBUG, INPUTDIR,
+            OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+            For more information about format and content of the parameter see
+            documentation.
+
+    '''
+    parser = ArgumentParser(description='Retrieve FLEXPART input from \
+                            ECMWF MARS archive',
+                            formatter_class=ArgumentDefaultsHelpFormatter)
+
+    # the most important arguments
+    parser.add_argument("--start_date", dest="start_date",
+                        help="start date YYYYMMDD")
+    parser.add_argument("--end_date", dest="end_date",
+                        help="end_date YYYYMMDD")
+    parser.add_argument("--date_chunk", dest="date_chunk", default=None,
+                        help="# of days to be retrieved at once")
+
+    # some arguments that override the default in the CONTROL file
+    parser.add_argument("--basetime", dest="basetime",
+                        help="base such as 00/12 (for half day retrievals)")
+    parser.add_argument("--step", dest="step",
+                        help="steps such as 00/to/48")
+    parser.add_argument("--levelist", dest="levelist",
+                        help="Vertical levels to be retrieved, e.g. 30/to/60")
+    parser.add_argument("--area", dest="area",
+                        help="area defined as north/west/south/east")
+
+    # set the working directories
+    parser.add_argument("--inputdir", dest="inputdir", default=None,
+                        help="root directory for storing intermediate files")
+    parser.add_argument("--outputdir", dest="outputdir", default=None,
+                        help="root directory for storing output files")
+    parser.add_argument("--flexpart_root_scripts", dest="flexpart_root_scripts",
+                        help="FLEXPART root directory (to find grib2flexpart \
+                        and COMMAND file)\n Normally ECMWFDATA resides in \
+                        the scripts directory of the FLEXPART distribution")
+
+    # this is only used by prepare_flexpart.py to rerun a postprocessing step
+    parser.add_argument("--ppid", dest="ppid",
+                        help="Specify parent process id for \
+                        rerun of prepare_flexpart")
+
+    # arguments for job submission to ECMWF, only needed by submit.py
+    parser.add_argument("--job_template", dest='job_template',
+                        default="job.temp",
+                        help="job template file for submission to ECMWF")
+    parser.add_argument("--queue", dest="queue",
+                        help="queue for submission to ECMWF \
+                        (e.g. ecgate or cca )")
+    parser.add_argument("--controlfile", dest="controlfile",
+                        default='CONTROL.temp',
+                        help="file with CONTROL parameters")
+    parser.add_argument("--debug", dest="debug", default=0,
+                        help="Debug mode - leave temporary files intact")
+
+    args = parser.parse_args()
+
+    # create instance of ControlFile for specified controlfile
+    # and assign the parameters (and default values if necessary)
+    try:
+        c = ControlFile(args.controlfile)
+    except IOError:
+        try:
+            LOCAL_PYTHON_PATH = os.path.dirname(os.path.abspath(
+                inspect.getfile(inspect.currentframe())))
+            c = ControlFile(LOCAL_PYTHON_PATH + args.controlfile)
+        except IOError:
+            print 'Could not read CONTROL file "' + args.controlfile + '"'
+            print 'Either it does not exist or its syntax is wrong.'
+            print 'Try "' + sys.argv[0].split('/')[-1] + \
+                  ' -h" to print usage information'
+            exit(1)
+
+    # check for having at least a starting date
+    if  args.start_date is None and getattr(c, 'start_date') is None:
+        print 'start_date specified neither in command line nor \
+               in CONTROL file ' + args.controlfile
+        print 'Try "' + sys.argv[0].split('/')[-1] + \
+              ' -h" to print usage information'
+        exit(1)
+
+    # save all existing command line parameter to the ControlFile instance
+    # if parameter is not specified through the command line or CONTROL file
+    # set default values
+    if args.start_date is not None:
+        c.start_date = args.start_date
+    if args.end_date is not None:
+        c.end_date = args.end_date
+    if c.end_date is None:
+        c.end_date = c.start_date
+    if args.date_chunk is not None:
+        c.date_chunk = args.date_chunk
+
+    if not hasattr(c, 'debug'):
+        c.debug = args.debug
+
+    if args.inputdir is None and args.outputdir is None:
+        c.inputdir = '../work'
+        c.outputdir = '../work'
+    else:
+        if args.inputdir is not None:
+            c.inputdir = args.inputdir
+        if args.outputdir is None:
+            c.outputdir = args.inputdir
+        if args.outputdir is not None:
+            c.outputdir = args.outputdir
+        if args.inputdir is None:
+            c.inputdir = args.outputdir
+
+    if hasattr(c, 'outputdir') is False and args.outputdir is None:
+        c.outputdir = c.inputdir
+    else:
+        if args.outputdir is not None:
+            c.outputdir = args.outputdir
+
+    if args.area is not None:
+        afloat = '.' in args.area
+        l = args.area.split('/')
+        if afloat:
+            for i, item in enumerate(l):
+                item = str(int(float(item) * 1000))
+        c.upper, c.left, c.lower, c.right = l
+
+    # NOTE: basetime activates the ''operational mode''
+    if args.basetime is not None:
+        c.basetime = args.basetime
+
+    if args.step is not None:
+        l = args.step.split('/')
+        if 'to' in args.step.lower():
+            if 'by' in args.step.lower():
+                ilist = np.arange(int(l[0]), int(l[2]) + 1, int(l[4]))
+                c.step = ['{:0>3}'.format(i) for i in ilist]
+            else:
+                my_error(None, args.step + ':\n' +
+                         'please use "by" as well if "to" is used')
+        else:
+            c.step = l
+
+    if args.levelist is not None:
+        c.levelist = args.levelist
+        if 'to' in c.levelist:
+            c.level = c.levelist.split('/')[2]
+        else:
+            c.level = c.levelist.split('/')[-1]
+
+    if args.flexpart_root_scripts is not None:
+        c.flexpart_root_scripts = args.flexpart_root_scripts
+
+    return args, c
+
+
+def clean_up(c):
+    '''
+    @Description:
+        Remove all files from intermediate directory
+        (inputdir from CONTROL file).
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+    @Return:
+        <nothing>
+    '''
+
+    print "clean_up"
+
+    cleanlist = glob.glob(c.inputdir + "/*")
+    for cl in cleanlist:
+        if c.prefix not in cl:
+            silent_remove(cl)
+        if c.ecapi is False and (c.ectrans == '1' or c.ecstorage == '1'):
+            silent_remove(cl)
+
+    print "Done"
+
+    return
+
+
+def my_error(c, message='ERROR'):
+    '''
+    @Description:
+        Prints a specified error message which can be passed to the function
+        before exiting the program.
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+        message: string, optional
+            Error message. Default value is "ERROR".
+
+    @Return:
+        <nothing>
+    '''
+
+    print message
+
+    # comment if user does not want email notification directly from python
+    try:
+        target = []
+        target.extend(c.mailfail)
+    except AttributeError:
+        target = []
+        target.extend(os.getenv('USER'))
+
+    for t in target:
+        p = subprocess.Popen(['mail', '-s ECMWFDATA v7.0 ERROR',
+                              os.path.expandvars(t)],
+                             stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE,
+                             bufsize=1)
+        tr = '\n'.join(traceback.format_stack())
+        pout = p.communicate(input=message + '\n\n' + tr)[0]
+        print 'Email sent to ' + os.path.expandvars(t) + ' ' + pout.decode()
+
+    exit(1)
+
+    return
+
+
+def normal_exit(c, message='Done!'):
+    '''
+    @Description:
+        Prints a specific exit message which can be passed to the function.
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+        message: string, optional
+            Message for exiting program. Default value is "Done!".
+
+    @Return:
+        <nothing>
+
+    '''
+    print message
+
+    # comment if user does not want notification directly from python
+    try:
+        target = []
+        target.extend(c.mailops)
+        for t in target:
+            p = subprocess.Popen(['mail', '-s ECMWFDATA v7.0 normal exit',
+                                  os.path.expandvars(t)],
+                                 stdin=subprocess.PIPE,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE,
+                                 bufsize=1)
+            pout = p.communicate(input=message+'\n\n')[0]
+            print 'Email sent to ' + os.path.expandvars(t) + ' ' + pout.decode()
+    finally:
+        pass
+
+    return
+
+
+def product(*args, **kwds):
+    '''
+    @Description:
+        This method is taken from an example at the ECMWF wiki website.
+        https://software.ecmwf.int/wiki/display/GRIB/index.py; 2018-03-16
+
+        This method combines the single characters of the passed arguments
+        with each other. So that each character of each argument value
+        will be combined with each character of the other arguments as a tuple.
+
+        Example:
+        product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
+        product(range(2), repeat = 3) --> 000 001 010 011 100 101 110 111
+
+    @Input:
+        *args: tuple
+            Positional arguments (arbitrary number).
+
+        **kwds: dictionary
+            Contains all the keyword arguments from *args.
+
+    @Return:
+        prod: tuple
+            Return will be done with "yield". A tuple of combined arguments.
+            See example in description above.
+    '''
+    pools = map(tuple, args) * kwds.get('repeat', 1)
+    result = [[]]
+    for pool in pools:
+        result = [x + [y] for x in result for y in pool]
+    for prod in result:
+        yield tuple(prod)
+
+    return
+
+
+def silent_remove(filename):
+    '''
+    @Description:
+        If "filename" exists , it is removed.
+        The function does not fail if the file does not exist.
+
+    @Input:
+        filename: string
+            The name of the file to be removed without notification.
+
+    @Return:
+        <nothing>
+    '''
+    try:
+        os.remove(filename)
+    except OSError as e:
+        # this would be "except OSError, e:" before Python 2.6
+        if e.errno is not  errno.ENOENT:
+            # errno.ENOENT  =  no such file or directory
+            raise  # re-raise exception if a different error occured
+
+    return
+
+
+def init128(filepath):
+    '''
+    @Description:
+        Opens and reads the grib file with table 128 information.
+
+    @Input:
+        filepath: string
+            Path to file of ECMWF grib table number 128.
+
+    @Return:
+        table128: dictionary
+            Contains the ECMWF grib table 128 information.
+            The key is the parameter number and the value is the
+            short name of the parameter.
+    '''
+    table128 = dict()
+    with open(filepath) as f:
+        fdata = f.read().split('\n')
+    for data in fdata:
+        if data[0] != '!':
+            table128[data[0:3]] = data[59:64].strip()
+
+    return table128
+
+
+def to_param_id(pars, table):
+    '''
+    @Description:
+        Transform parameter names to parameter ids
+        with ECMWF grib table 128.
+
+    @Input:
+        pars: string
+            Addpar argument from CONTROL file in the format of
+            parameter names instead of ids. The parameter short
+            names are sepearted with "/" and they are passed as
+            one single string.
+
+        table: dictionary
+            Contains the ECMWF grib table 128 information.
+            The key is the parameter number and the value is the
+            short name of the parameter.
+
+    @Return:
+        ipar: list of integer
+            List of addpar parameters from CONTROL file transformed to
+            parameter ids in the format of integer.
+    '''
+    cpar = pars.upper().split('/')
+    ipar = []
+    for par in cpar:
+        for k, v in table.iteritems():
+            if par == k or par == v:
+                ipar.append(int(k))
+                break
+        else:
+            print 'Warning: par ' + par + ' not found in table 128'
+
+    return ipar
+
+def get_list_as_string(list_obj, concatenate_sign=', '):
+    '''
+    @Description:
+        Converts a list of arbitrary content into a single string.
+
+    @Input:
+        list_obj: list
+            A list with arbitrary content.
+
+        concatenate_sign: string, optional
+            A string which is used to concatenate the single
+            list elements. Default value is ", ".
+
+    @Return:
+        str_of_list: string
+            The content of the list as a single string.
+    '''
+
+    str_of_list = concatenate_sign.join(str(l) for l in list_obj)
+
+    return str_of_list
