source: flex_extract.git/python/ControlFile.py @ ff99eae

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

completed application of pep8 style guide and pylint investigations. added documentation almost everywhere

  • Property mode set to 100644
File size: 10.4 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#************************************************************************
4# ToDo AP
5# - write a test class
6#************************************************************************
7#*******************************************************************************
8# @Author: Leopold Haimberger (University of Vienna)
9#
10# @Date: November 2015
11#
12# @Change History:
13#
14#   February 2018 - Anne Philipp (University of Vienna):
15#        - applied PEP8 style guide
16#        - added documentation
17#        - applied some minor modifications in programming style/structure
18#        - changed name of class Control to ControlFile for more
19#          self-explanation naming
20#        - outsource of class ControlFile
21#
22# @License:
23#    (C) Copyright 2015-2018.
24#
25#    This software is licensed under the terms of the Apache Licence Version 2.0
26#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
27#
28# @Class Description:
29#    The CONTROL file is the steering part of the FLEXPART extraction
30#    software. All necessary parameters needed to retrieve the data fields
31#    from the MARS archive for driving FLEXPART are set in a CONTROL file.
32#    Some specific parameters like the start and end dates can be overwritten
33#    by the command line parameters, but in generel all parameters needed
34#    for a complete set of fields for FLEXPART can be set in the CONTROL file.
35#
36# @Class Content:
37#    - __init__
38#    - __str__
39#    - to_list
40#
41# @Class Attributes:
42#    - start_date
43#    - end_date
44#    - accuracy
45#    - omega
46#    - cwc
47#    - omegadiff
48#    - etadiff
49#    - level
50#    - levelist
51#    - step
52#    - maxstep
53#    - prefix
54#    - makefile
55#    - basetime
56#    - date_chunk
57#    - grib2flexpart
58#    - exedir
59#    - flexpart_root_scripts
60#    - ecmwfdatadir
61#
62#*******************************************************************************
63
64# ------------------------------------------------------------------------------
65# MODULES
66# ------------------------------------------------------------------------------
67import os
68import inspect
69
70# software specific module from flex_extract
71from tools import get_list_as_string, my_error
72
73# ------------------------------------------------------------------------------
74# CLASS
75# ------------------------------------------------------------------------------
76class ControlFile(object):
77    '''
78    Class containing the information of the flex_extract CONTROL file.
79
80    Contains all the parameters of CONTROL file, which are e.g.:
81    DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
82    STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
83    LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
84    OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
85    ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
86    MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR,
87    BASETIME, DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
88
89    For more information about format and content of the parameter
90    see documentation.
91
92    '''
93
94    def __init__(self, filename):
95        '''
96        @Description:
97            Initialises the instance of ControlFile class and defines and
98            assign all CONTROL file variables. Set default values if
99            parameter was not in CONTROL file.
100
101        @Input:
102            self: instance of ControlFile class
103                Description see class documentation.
104
105            filename: string
106                Name of CONTROL file.
107
108        @Return:
109            <nothing>
110        '''
111
112        # read whole CONTROL file
113        with open(filename) as f:
114            fdata = f.read().split('\n')
115
116        # go through every line and store parameter
117        # as class variable
118        for ldata in fdata:
119            data = ldata.split()
120            if len(data) > 1:
121                if 'm_' in data[0].lower():
122                    data[0] = data[0][2:]
123                if data[0].lower() == 'class':
124                    data[0] = 'marsclass'
125                if data[0].lower() == 'day1':
126                    data[0] = 'start_date'
127                if data[0].lower() == 'day2':
128                    data[0] = 'end_date'
129                if data[0].lower() == 'addpar':
130                    if '/' in data[1]:
131                        # remove leading '/' sign from addpar content
132                        if data[1][0] == '/':
133                            data[1] = data[1][1:]
134                        dd = data[1].split('/')
135                        data = [data[0]]
136                        for d in dd:
137                            data.append(d)
138                if len(data) == 2:
139                    if '$' in data[1]:
140                        setattr(self, data[0].lower(), data[1])
141                        while '$' in data[1]:
142                            i = data[1].index('$')
143                            j = data[1].find('{')
144                            k = data[1].find('}')
145                            var = os.getenv(data[1][j+1:k])
146                            if var is not None:
147                                data[1] = data[1][:i] + var + data[1][k+1:]
148                            else:
149                                my_error(None, 'Could not find variable ' +
150                                         data[1][j+1:k] + ' while reading ' +
151                                         filename)
152                        setattr(self, data[0].lower() + '_expanded', data[1])
153                    else:
154                        if data[1].lower() != 'none':
155                            setattr(self, data[0].lower(), data[1])
156                        else:
157                            setattr(self, data[0].lower(), None)
158                elif len(data) > 2:
159                    setattr(self, data[0].lower(), (data[1:]))
160            else:
161                pass
162
163        # check a couple of necessary attributes if they contain values
164        # otherwise set default values
165        if not hasattr(self, 'start_date'):
166            self.start_date = None
167        if not hasattr(self, 'end_date'):
168            self.end_date = self.start_date
169        if not hasattr(self, 'accuracy'):
170            self.accuracy = 24
171        if not hasattr(self, 'omega'):
172            self.omega = '0'
173        if not hasattr(self, 'cwc'):
174            self.cwc = '0'
175        if not hasattr(self, 'omegadiff'):
176            self.omegadiff = '0'
177        if not hasattr(self, 'etadiff'):
178            self.etadiff = '0'
179        if not hasattr(self, 'levelist'):
180            if not hasattr(self, 'level'):
181                print 'Warning: neither levelist nor level \
182                       specified in CONTROL file'
183            else:
184                self.levelist = '1/to/' + self.level
185        else:
186            if 'to' in self.levelist:
187                self.level = self.levelist.split('/')[2]
188            else:
189                self.level = self.levelist.split('/')[-1]
190
191        if not hasattr(self, 'maxstep'):
192            # find out maximum step
193            self.maxstep = 0
194            for s in self.step:
195                if int(s) > self.maxstep:
196                    self.maxstep = int(s)
197        else:
198            self.maxstep = int(self.maxstep)
199
200        if not hasattr(self, 'prefix'):
201            self.prefix = 'EN'
202        if not hasattr(self, 'makefile'):
203            self.makefile = None
204        if not hasattr(self, 'basetime'):
205            self.basetime = None
206        if not hasattr(self, 'date_chunk'):
207            self.date_chunk = '3'
208        if not hasattr(self, 'grib2flexpart'):
209            self.grib2flexpart = '0'
210
211        # script directory
212        self.ecmwfdatadir = os.path.dirname(os.path.abspath(inspect.getfile(
213            inspect.currentframe()))) + '/../'
214        # Fortran source directory
215        self.exedir = self.ecmwfdatadir + 'src/'
216
217        # FLEXPART directory
218        if not hasattr(self, 'flexpart_root_scripts'):
219            self.flexpart_root_scripts = self.ecmwfdatadir
220
221        return
222
223    def __str__(self):
224        '''
225        @Description:
226            Prepares a single string with all the comma seperated ControlFile
227            class attributes including their values.
228
229            Example:
230            {'kids': 0, 'name': 'Dog', 'color': 'Spotted',
231             'age': 10, 'legs': 2, 'smell': 'Alot'}
232
233        @Input:
234            self: instance of ControlFile class
235                Description see class documentation.
236
237        @Return:
238            string of ControlFile class attributes with their values
239        '''
240
241        attrs = vars(self)
242
243        return ', '.join("%s: %s" % item for item in attrs.items())
244
245    def to_list(self):
246        '''
247        @Description:
248            Just generates a list of strings containing the attributes and
249            assigned values except the attributes "_expanded", "exedir",
250            "ecmwfdatadir" and "flexpart_root_scripts".
251
252        @Input:
253            self: instance of ControlFile class
254                Description see class documentation.
255
256        @Return:
257            l: list
258                A sorted list of the all ControlFile class attributes with
259                their values except the attributes "_expanded", "exedir",
260                "ecmwfdatadir" and "flexpart_root_scripts".
261        '''
262
263        attrs = vars(self)
264        l = list()
265
266        for item in attrs.items():
267            if '_expanded' in item[0]:
268                pass
269            elif 'exedir' in item[0]:
270                pass
271            elif 'flexpart_root_scripts' in item[0]:
272                pass
273            elif 'ecmwfdatadir' in item[0]:
274                pass
275            else:
276                if isinstance(item[1], list):
277                    stot = ''
278                    for s in item[1]:
279                        stot += s + ' '
280
281                    l.append("%s %s" % (item[0], stot))
282                else:
283                    l.append("%s %s" % item)
284
285        return sorted(l)
286
287    # def to_dict(self):
288        # '''
289
290        # '''
291        # parameters_dict = vars(self)
292
293        # # remove unneeded parameter
294        # parameters_dict.pop('_expanded', None)
295        # parameters_dict.pop('exedir', None)
296        # parameters_dict.pop('flexpart_root_scripts', None)
297        # parameters_dict.pop('ecmwfdatadir', None)
298
299        # parameters_dict_str = {}
300        # for key, value in parameters_dict.iteritems():
301            # if isinstance(value, list):
302                # parameters_dict_str[str(key)] = get_list_as_string(value, ' ')
303            # else:
304                # parameters_dict_str[str(key)] = str(value)
305
306        # return parameters_dict_str
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG