source: flex_extract.git/python/install.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 100755
File size: 15.1 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#************************************************************************
4# TODO AP
5#AP
6# - Functionality Provided is not correct for this file
7# - localpythonpath should not be set in module load section!
8# - create a class Installation and divide installation in 3 subdefs for
9#   ecgate, local and cca seperatly
10# - Change History ist nicht angepasst ans File! Original geben lassen
11#************************************************************************
12"""
13@Author: Anne Fouilloux (University of Oslo)
14
15@Date: October 2014
16
17@ChangeHistory:
18    November 2015 - Leopold Haimberger (University of Vienna):
19        - using the WebAPI also for general MARS retrievals
20        - job submission on ecgate and cca
21        - job templates suitable for twice daily operational dissemination
22        - dividing retrievals of longer periods into digestable chunks
23        - retrieve also longer term forecasts, not only analyses and
24          short term forecast data
25        - conversion into GRIB2
26        - conversion into .fp format for faster execution of FLEXPART
27
28    February 2018 - Anne Philipp (University of Vienna):
29        - applied PEP8 style guide
30        - added documentation
31
32@License:
33    (C) Copyright 2014 UIO.
34
35    This software is licensed under the terms of the Apache Licence Version 2.0
36    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
37
38@Requirements:
39    - A standard python 2.6 or 2.7 installation
40    - dateutils
41    - matplotlib (optional, for debugging)
42    - ECMWF specific packages, all available from https://software.ecmwf.int/
43        ECMWF WebMARS, gribAPI with python enabled, emoslib and
44        ecaccess web toolkit
45
46@Description:
47    Further documentation may be obtained from www.flexpart.eu.
48
49    Functionality provided:
50        Prepare input 3D-wind fields in hybrid coordinates +
51        surface fields for FLEXPART runs
52"""
53# ------------------------------------------------------------------------------
54# MODULES
55# ------------------------------------------------------------------------------
56import calendar
57import shutil
58import datetime
59import time
60import os,sys,glob
61import subprocess
62import inspect
63# add path to submit.py to pythonpath so that python finds its buddies
64localpythonpath=os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
65sys.path.append(localpythonpath)
66from UIOFiles import UIOFiles
67from string import strip
68from argparse import ArgumentParser,ArgumentDefaultsHelpFormatter
69from GribTools import GribTools
70from Control import Control
71from getMARSdata import getMARSdata
72from prepareFLEXPART import prepareFLEXPART
73from ECFlexpart import ECFlexpart
74
75# ------------------------------------------------------------------------------
76# FUNCTIONS
77# ------------------------------------------------------------------------------
78def install_args_and_control():
79    '''
80    @Description:
81        Assigns the command line arguments for installation and reads
82        control file content. Apply default values for non mentioned arguments.
83
84    @Input:
85        <nothing>
86
87    @Return:
88        args: instance of ArgumentParser
89            Contains the commandline arguments from script/program call.
90
91        c: instance of class Control
92            Contains all necessary information of a control file. The parameters
93            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
94            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
95            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
96            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
97            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR
98            For more information about format and content of the parameter see
99            documentation.
100    '''
101    parser = ArgumentParser(description='Install ECMWFDATA software locally or \
102                            on ECMWF machines',
103                            formatter_class=ArgumentDefaultsHelpFormatter)
104
105    parser.add_argument('--target', dest='install_target',
106                        help="Valid targets: local | ecgate | cca , \
107                        the latter two are at ECMWF")
108    parser.add_argument("--makefile", dest="makefile",
109                        help='Name of Makefile to use for compiling CONVERT2')
110    parser.add_argument("--ecuid", dest="ecuid",
111                        help='user id at ECMWF')
112    parser.add_argument("--ecgid", dest="ecgid",
113                        help='group id at ECMWF')
114    parser.add_argument("--gateway", dest="gateway",
115                        help='name of local gateway server')
116    parser.add_argument("--destination", dest="destination",
117                        help='ecaccess destination, e.g. leo@genericSftp')
118
119    parser.add_argument("--flexpart_root_scripts", dest="flexpart_root_scripts",
120                        help="FLEXPART root directory on ECMWF servers \
121                        (to find grib2flexpart and COMMAND file)\n\
122                        Normally ECMWFDATA resides in the scripts directory \
123                        of the FLEXPART distribution, thus the:")
124
125# arguments for job submission to ECMWF, only needed by submit.py
126    parser.add_argument("--job_template", dest='job_template',
127                        default="job.temp.o",
128                        help="job template file for submission to ECMWF")
129
130    parser.add_argument("--controlfile", dest="controlfile",
131                        default='CONTROL.temp',
132                        help="file with control parameters")
133
134    args = parser.parse_args()
135
136    try:
137        c = Control(args.controlfile)
138    except:
139        print('Could not read control file "' + args.controlfile + '"')
140        print('Either it does not exist or its syntax is wrong.')
141        print('Try "' + sys.argv[0].split('/')[-1] +
142              ' -h" to print usage information')
143        exit(1)
144
145    if args.install_target != 'local':
146        if (args.ecgid is None or args.ecuid is None or args.gateway is None
147            or args.destination is None):
148            print('Please enter your ECMWF user id and group id as well as \
149                   the \nname of the local gateway and the ectrans \
150                   destination ')
151            print('with command line options --ecuid --ecgid \
152                   --gateway --destination')
153            print('Try "' + sys.argv[0].split('/')[-1] +
154                  ' -h" to print usage information')
155            print('Please consult ecaccess documentation or ECMWF user support \
156                   for further details')
157            sys.exit(1)
158        else:
159            c.ecuid = args.ecuid
160            c.ecgid = args.ecgid
161            c.gateway = args.gateway
162            c.destination = args.destination
163
164    try:
165        c.makefile = args.makefile
166    except:
167        pass
168
169    if args.install_target == 'local':
170        if args.flexpart_root_scripts is None:
171            c.flexpart_root_scripts = '../'
172        else:
173            c.flexpart_root_scripts = args.flexpart_root_scripts
174
175    if args.install_target != 'local':
176        if args.flexpart_root_scripts is None:
177            c.ec_flexpart_root_scripts = '${HOME}'
178        else:
179            c.ec_flexpart_root_scripts = args.flexpart_root_scripts
180
181    return args, c
182
183
184def main():
185    '''
186    '''
187    os.chdir(localpythonpath)
188    args, c = install_args_and_control()
189    if args.install_target is not None:
190        install_via_gateway(c, args.install_target)
191    else:
192        print('Please specify installation target (local|ecgate|cca)')
193        print('use -h or --help for help')
194    sys.exit()
195
196def install_via_gateway(c, target):
197
198    ecd = c.ecmwfdatadir
199    template = ecd + 'python/compilejob.temp'
200    job = ecd + 'python/compilejob.ksh'
201    fo = open(job, 'w')
202#AP could do with open(template) as f, open(job, 'w') as fo:
203#AP or nested with statements
204    with open(template) as f:
205        fdata = f.read().split('\n')
206        for data in fdata:
207            if 'MAKEFILE=' in data:
208                if c.makefile is not None:
209                    data = 'export MAKEFILE=' + c.makefile
210            if 'FLEXPART_ROOT_SCRIPTS=' in data:
211                if c.flexpart_root_scripts != '../':
212                    data = 'export FLEXPART_ROOT_SCRIPTS=' + \
213                            c.flexpart_root_scripts
214                else:
215                    data='export FLEXPART_ROOT_SCRIPTS=$HOME'
216            if target.lower() != 'local':
217                if '--workdir' in data:
218                    data = '#SBATCH --workdir=/scratch/ms/' + c.ecgid + \
219                            '/' + c.ecuid
220                if '##PBS -o' in data:
221                    data = '##PBS -o /scratch/ms/' + c.ecgid + '/' + c.ecuid + \
222                            'flex_ecmwf.$Jobname.$Job_ID.out'
223                if 'FLEXPART_ROOT_SCRIPTS=' in data:
224                    if c.ec_flexpart_root_scripts != '../':
225                        data = 'export FLEXPART_ROOT_SCRIPTS=' + \
226                                c.ec_flexpart_root_scripts
227                    else:
228                        data = 'export FLEXPART_ROOT_SCRIPTS=$HOME'
229            fo.write(data + '\n')
230    f.close()
231    fo.close()
232
233    if target.lower() != 'local':
234        template = ecd + 'python/job.temp.o'
235#AP hier eventuell Zeile für Zeile lesen und dann if Entscheidung
236        with open(template) as f:
237            fdata = f.read().split('\n')
238        f.close()
239        fo = open(template[:-2], 'w')
240        for data in fdata:
241            if '--workdir' in data:
242                data = '#SBATCH --workdir=/scratch/ms/' + c.ecgid + \
243                        '/' + c.ecuid
244            if '##PBS -o' in data:
245                data = '##PBS -o /scratch/ms/' + c.ecgid + '/' + \
246                        c.ecuid + 'flex_ecmwf.$Jobname.$Job_ID.out'
247            if  'export PATH=${PATH}:' in data:
248                data += c.ec_flexpart_root_scripts + '/ECMWFDATA7.1/python'
249            if 'cat>>' in data or 'cat >>' in data:
250                i = data.index('>')
251                fo.write(data[:i] + data[i+1:] + '\n')
252                fo.write('GATEWAY ' + c.gateway + '\n')
253                fo.write('DESTINATION ' + c.destination + '\n')
254                fo.write('EOF\n')
255
256            fo.write(data + '\n')
257        fo.close()
258
259        job = ecd + 'python/ECMWF_ENV'
260        with open(job, 'w') as fo:
261            fo.write('ECUID ' + c.ecuid + '\n')
262            fo.write('ECGID ' + c.ecgid + '\n')
263            fo.write('GATEWAY ' + c.gateway + '\n')
264            fo.write('DESTINATION ' + c.destination + '\n')
265        fo.close()
266
267
268
269    if target.lower() == 'local':
270        # compile CONVERT2
271        if c.flexpart_root_scripts is None or c.flexpart_root_scripts == '../':
272            print('Warning: FLEXPART_ROOT_SCRIPTS has not been specified')
273            print('Only CONVERT2 will be compiled in ' + ecd + '/../src')
274        else:
275            c.flexpart_root_scripts = os.path.expandvars(os.path.expanduser(
276                                        c.flexpart_root_scripts))
277            if os.path.abspath(ecd) != os.path.abspath(c.flexpart_root_scripts):
278                os.chdir('/')
279                p = subprocess.check_call(['tar', '-cvf',
280                                           ecd + '../ECMWFDATA7.1.tar',
281                                           ecd + 'python',
282                                           ecd + 'grib_templates',
283                                           ecd + 'src'])
284                try:
285                    os.makedirs(c.flexpart_root_scripts + '/ECMWFDATA7.1')
286                except:
287                    pass
288                os.chdir(c.flexpart_root_scripts + '/ECMWFDATA7.1')
289                p = subprocess.check_call(['tar', '-xvf',
290                                           ecd + '../ECMWFDATA7.1.tar'])
291                os.chdir(c.flexpart_root_scripts + '/ECMWFDATA7.1/src')
292
293        os.chdir('../src')
294        print(('install ECMWFDATA7.1 software on ' + target + ' in directory '
295               + os.getcwd()))
296        if c.makefile is None:
297            makefile = 'Makefile.local.ifort'
298        else:
299            makefile = c.makefile
300        flist = glob.glob('*.mod') + glob.glob('*.o')
301        if flist:
302            p = subprocess.check_call(['rm'] + flist)
303        try:
304            print(('Using makefile: ' + makefile))
305            p = subprocess.check_call(['make', '-f', makefile])
306            p = subprocess.check_call(['ls', '-l','CONVERT2'])
307        except:
308            print('compile failed - please edit ' + makefile +
309                  ' or try another Makefile in the src directory.')
310            print('most likely GRIB_API_INCLUDE_DIR, GRIB_API_LIB '
311                    'and EMOSLIB must be adapted.')
312            print('Available Makefiles:')
313            print(glob.glob('Makefile*'))
314
315    elif target.lower() == 'ecgate':
316        os.chdir('/')
317        p = subprocess.check_call(['tar', '-cvf',
318                                   ecd + '../ECMWFDATA7.1.tar',
319                                   ecd + 'python',
320                                   ecd + 'grib_templates',
321                                   ecd + 'src'])
322        try:
323            p = subprocess.check_call(['ecaccess-file-put',
324                                       ecd + '../ECMWFDATA7.1.tar',
325                                       'ecgate:/home/ms/' + c.ecgid + '/' +
326                                       c.ecuid + '/ECMWFDATA7.1.tar'])
327        except:
328            print('ecaccess-file-put failed! Probably the eccert key has expired.')
329            exit(1)
330        p = subprocess.check_call(['ecaccess-job-submit',
331                                   '-queueName',
332                                   target,
333                                   ecd + 'python/compilejob.ksh'])
334        print('compilejob.ksh has been submitted to ecgate for '
335                'installation in ' + c.ec_flexpart_root_scripts +
336                '/ECMWFDATA7.1')
337        print('You should get an email with subject flexcompile within '
338                'the next few minutes')
339
340    elif target.lower() == 'cca':
341        os.chdir('/')
342        p = subprocess.check_call(['tar', '-cvf',
343                                   ecd + '../ECMWFDATA7.1.tar',
344                                   ecd + 'python',
345                                   ecd + 'grib_templates',
346                                   ecd + 'src'])
347        try:
348            p = subprocess.check_call(['ecaccess-file-put',
349                                       ecd + '../ECMWFDATA7.1.tar',
350                                       'cca:/home/ms/' + c.ecgid + '/' +
351                                       c.ecuid + '/ECMWFDATA7.1.tar'])
352        except:
353            print('ecaccess-file-put failed! '
354                    'Probably the eccert key has expired.')
355            exit(1)
356
357        p=subprocess.check_call(['ecaccess-job-submit',
358                                '-queueName',
359                                target,
360                                ecd + 'python/compilejob.ksh'])
361        print('compilejob.ksh has been submitted to cca for installation in ' +
362              c.ec_flexpart_root_scripts + '/ECMWFDATA7.1')
363        print('You should get an email with subject flexcompile '
364                'within the next few minutes')
365
366    else:
367        print('ERROR: unknown installation target ', target)
368        print('Valid targets: ecgate, cca, local')
369
370    return
371
372
373if __name__ == "__main__":
374    main()
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG