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

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

resolved loop import between controlfile and tools

  • Property mode set to 100644
File size: 10.3 KB
RevLine 
[812283d]1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#************************************************************************
[ff99eae]4# ToDo AP
[812283d]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__
[ff99eae]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
[812283d]61#
62#*******************************************************************************
63
64# ------------------------------------------------------------------------------
65# MODULES
66# ------------------------------------------------------------------------------
67import os
68import inspect
[ff99eae]69
[812283d]70# ------------------------------------------------------------------------------
71# CLASS
72# ------------------------------------------------------------------------------
[ff99eae]73class ControlFile(object):
[812283d]74    '''
75    Class containing the information of the flex_extract CONTROL file.
76
77    Contains all the parameters of CONTROL file, which are e.g.:
78    DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
79    STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
80    LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
81    OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
82    ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
83    MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR,
84    BASETIME, DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
85
86    For more information about format and content of the parameter
87    see documentation.
88
89    '''
90
91    def __init__(self, filename):
92        '''
93        @Description:
94            Initialises the instance of ControlFile class and defines and
95            assign all CONTROL file variables. Set default values if
96            parameter was not in CONTROL file.
97
98        @Input:
99            self: instance of ControlFile class
100                Description see class documentation.
101
102            filename: string
103                Name of CONTROL file.
104
105        @Return:
106            <nothing>
107        '''
[e1228f3]108        from tools import my_error
[812283d]109
110        # read whole CONTROL file
111        with open(filename) as f:
112            fdata = f.read().split('\n')
113
114        # go through every line and store parameter
115        # as class variable
116        for ldata in fdata:
117            data = ldata.split()
118            if len(data) > 1:
119                if 'm_' in data[0].lower():
120                    data[0] = data[0][2:]
121                if data[0].lower() == 'class':
122                    data[0] = 'marsclass'
123                if data[0].lower() == 'day1':
124                    data[0] = 'start_date'
125                if data[0].lower() == 'day2':
126                    data[0] = 'end_date'
127                if data[0].lower() == 'addpar':
128                    if '/' in data[1]:
129                        # remove leading '/' sign from addpar content
130                        if data[1][0] == '/':
131                            data[1] = data[1][1:]
132                        dd = data[1].split('/')
133                        data = [data[0]]
134                        for d in dd:
135                            data.append(d)
136                if len(data) == 2:
137                    if '$' in data[1]:
138                        setattr(self, data[0].lower(), data[1])
139                        while '$' in data[1]:
140                            i = data[1].index('$')
141                            j = data[1].find('{')
142                            k = data[1].find('}')
143                            var = os.getenv(data[1][j+1:k])
144                            if var is not None:
145                                data[1] = data[1][:i] + var + data[1][k+1:]
146                            else:
[ff99eae]147                                my_error(None, 'Could not find variable ' +
148                                         data[1][j+1:k] + ' while reading ' +
149                                         filename)
[812283d]150                        setattr(self, data[0].lower() + '_expanded', data[1])
151                    else:
152                        if data[1].lower() != 'none':
153                            setattr(self, data[0].lower(), data[1])
154                        else:
155                            setattr(self, data[0].lower(), None)
156                elif len(data) > 2:
157                    setattr(self, data[0].lower(), (data[1:]))
158            else:
159                pass
160
161        # check a couple of necessary attributes if they contain values
162        # otherwise set default values
163        if not hasattr(self, 'start_date'):
164            self.start_date = None
165        if not hasattr(self, 'end_date'):
166            self.end_date = self.start_date
167        if not hasattr(self, 'accuracy'):
168            self.accuracy = 24
169        if not hasattr(self, 'omega'):
170            self.omega = '0'
171        if not hasattr(self, 'cwc'):
172            self.cwc = '0'
173        if not hasattr(self, 'omegadiff'):
174            self.omegadiff = '0'
175        if not hasattr(self, 'etadiff'):
176            self.etadiff = '0'
177        if not hasattr(self, 'levelist'):
178            if not hasattr(self, 'level'):
[ff99eae]179                print 'Warning: neither levelist nor level \
180                       specified in CONTROL file'
[812283d]181            else:
182                self.levelist = '1/to/' + self.level
183        else:
184            if 'to' in self.levelist:
185                self.level = self.levelist.split('/')[2]
186            else:
187                self.level = self.levelist.split('/')[-1]
188
189        if not hasattr(self, 'maxstep'):
190            # find out maximum step
191            self.maxstep = 0
192            for s in self.step:
193                if int(s) > self.maxstep:
194                    self.maxstep = int(s)
195        else:
196            self.maxstep = int(self.maxstep)
197
198        if not hasattr(self, 'prefix'):
199            self.prefix = 'EN'
200        if not hasattr(self, 'makefile'):
201            self.makefile = None
202        if not hasattr(self, 'basetime'):
203            self.basetime = None
204        if not hasattr(self, 'date_chunk'):
205            self.date_chunk = '3'
206        if not hasattr(self, 'grib2flexpart'):
207            self.grib2flexpart = '0'
208
209        # script directory
210        self.ecmwfdatadir = os.path.dirname(os.path.abspath(inspect.getfile(
211            inspect.currentframe()))) + '/../'
212        # Fortran source directory
213        self.exedir = self.ecmwfdatadir + 'src/'
214
215        # FLEXPART directory
216        if not hasattr(self, 'flexpart_root_scripts'):
217            self.flexpart_root_scripts = self.ecmwfdatadir
218
219        return
220
221    def __str__(self):
222        '''
223        @Description:
224            Prepares a single string with all the comma seperated ControlFile
225            class attributes including their values.
226
227            Example:
228            {'kids': 0, 'name': 'Dog', 'color': 'Spotted',
229             'age': 10, 'legs': 2, 'smell': 'Alot'}
230
231        @Input:
232            self: instance of ControlFile class
233                Description see class documentation.
234
235        @Return:
236            string of ControlFile class attributes with their values
237        '''
238
239        attrs = vars(self)
240
241        return ', '.join("%s: %s" % item for item in attrs.items())
242
[ff99eae]243    def to_list(self):
[812283d]244        '''
245        @Description:
246            Just generates a list of strings containing the attributes and
247            assigned values except the attributes "_expanded", "exedir",
248            "ecmwfdatadir" and "flexpart_root_scripts".
249
250        @Input:
251            self: instance of ControlFile class
252                Description see class documentation.
253
254        @Return:
255            l: list
256                A sorted list of the all ControlFile class attributes with
257                their values except the attributes "_expanded", "exedir",
258                "ecmwfdatadir" and "flexpart_root_scripts".
259        '''
260
261        attrs = vars(self)
262        l = list()
263
264        for item in attrs.items():
265            if '_expanded' in item[0]:
266                pass
267            elif 'exedir' in item[0]:
268                pass
269            elif 'flexpart_root_scripts' in item[0]:
270                pass
271            elif 'ecmwfdatadir' in item[0]:
272                pass
273            else:
[ff99eae]274                if isinstance(item[1], list):
[812283d]275                    stot = ''
276                    for s in item[1]:
277                        stot += s + ' '
278
279                    l.append("%s %s" % (item[0], stot))
280                else:
281                    l.append("%s %s" % item)
282
283        return sorted(l)
[ff99eae]284
285    # def to_dict(self):
286        # '''
287
288        # '''
289        # parameters_dict = vars(self)
290
291        # # remove unneeded parameter
292        # parameters_dict.pop('_expanded', None)
293        # parameters_dict.pop('exedir', None)
294        # parameters_dict.pop('flexpart_root_scripts', None)
295        # parameters_dict.pop('ecmwfdatadir', None)
296
297        # parameters_dict_str = {}
298        # for key, value in parameters_dict.iteritems():
299            # if isinstance(value, list):
300                # parameters_dict_str[str(key)] = get_list_as_string(value, ' ')
301            # else:
302                # parameters_dict_str[str(key)] = str(value)
303
304        # return parameters_dict_str
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG