source: flex_extract.git/python/Control.py @ efdb01a

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

whole bunch of modifications due to new structure of ECMWFDATA, added basics of documentation, minor programming corrections

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