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

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

changed Control to ControlFile? class

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