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
RevLine 
[d69b677]1#!/usr/bin/env python
[64cf353]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# ------------------------------------------------------------------------------
[d69b677]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)
[efdb01a]66from UIOFiles import UIOFiles
[d69b677]67from string import strip
68from argparse import ArgumentParser,ArgumentDefaultsHelpFormatter
69from GribTools import GribTools
[efdb01a]70from Control import Control
[d69b677]71from getMARSdata import getMARSdata
72from prepareFLEXPART import prepareFLEXPART
[efdb01a]73from ECFlexpart import ECFlexpart
[d69b677]74
[64cf353]75# ------------------------------------------------------------------------------
76# FUNCTIONS
77# ------------------------------------------------------------------------------
[efdb01a]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
[d69b677]184def main():
[a4b6cef]185    '''
186    '''
[d69b677]187    os.chdir(localpythonpath)
[a4b6cef]188    args, c = install_args_and_control()
189    if args.install_target is not None:
190        install_via_gateway(c, args.install_target)
[d69b677]191    else:
[a4b6cef]192        print('Please specify installation target (local|ecgate|cca)')
193        print('use -h or --help for help')
[d69b677]194    sys.exit()
[a4b6cef]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
[d69b677]204    with open(template) as f:
[a4b6cef]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')
[d69b677]230    f.close()
231    fo.close()
[a4b6cef]232
233    if target.lower() != 'local':
234        template = ecd + 'python/job.temp.o'
[64cf353]235#AP hier eventuell Zeile für Zeile lesen und dann if Entscheidung
[a4b6cef]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:
[efdb01a]248                data += c.ec_flexpart_root_scripts + '/ECMWFDATA7.1/python'
[a4b6cef]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':
[d69b677]270        # compile CONVERT2
[a4b6cef]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',
[efdb01a]280                                           ecd + '../ECMWFDATA7.1.tar',
[a4b6cef]281                                           ecd + 'python',
282                                           ecd + 'grib_templates',
283                                           ecd + 'src'])
284                try:
[efdb01a]285                    os.makedirs(c.flexpart_root_scripts + '/ECMWFDATA7.1')
[a4b6cef]286                except:
287                    pass
[efdb01a]288                os.chdir(c.flexpart_root_scripts + '/ECMWFDATA7.1')
[a4b6cef]289                p = subprocess.check_call(['tar', '-xvf',
[efdb01a]290                                           ecd + '../ECMWFDATA7.1.tar'])
291                os.chdir(c.flexpart_root_scripts + '/ECMWFDATA7.1/src')
[a4b6cef]292
293        os.chdir('../src')
[efdb01a]294        print(('install ECMWFDATA7.1 software on ' + target + ' in directory '
[a4b6cef]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)
[d69b677]303        try:
[a4b6cef]304            print(('Using makefile: ' + makefile))
305            p = subprocess.check_call(['make', '-f', makefile])
[efdb01a]306            p = subprocess.check_call(['ls', '-l','CONVERT2'])
[a4b6cef]307        except:
308            print('compile failed - please edit ' + makefile +
309                  ' or try another Makefile in the src directory.')
[efdb01a]310            print('most likely GRIB_API_INCLUDE_DIR, GRIB_API_LIB '
311                    'and EMOSLIB must be adapted.')
[a4b6cef]312            print('Available Makefiles:')
313            print(glob.glob('Makefile*'))
314
315    elif target.lower() == 'ecgate':
[d69b677]316        os.chdir('/')
[a4b6cef]317        p = subprocess.check_call(['tar', '-cvf',
[efdb01a]318                                   ecd + '../ECMWFDATA7.1.tar',
[a4b6cef]319                                   ecd + 'python',
320                                   ecd + 'grib_templates',
321                                   ecd + 'src'])
322        try:
323            p = subprocess.check_call(['ecaccess-file-put',
[efdb01a]324                                       ecd + '../ECMWFDATA7.1.tar',
325                                       'ecgate:/home/ms/' + c.ecgid + '/' +
326                                       c.ecuid + '/ECMWFDATA7.1.tar'])
[a4b6cef]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'])
[efdb01a]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')
[a4b6cef]339
340    elif target.lower() == 'cca':
[d69b677]341        os.chdir('/')
[a4b6cef]342        p = subprocess.check_call(['tar', '-cvf',
[efdb01a]343                                   ecd + '../ECMWFDATA7.1.tar',
[a4b6cef]344                                   ecd + 'python',
345                                   ecd + 'grib_templates',
346                                   ecd + 'src'])
347        try:
348            p = subprocess.check_call(['ecaccess-file-put',
[efdb01a]349                                       ecd + '../ECMWFDATA7.1.tar',
350                                       'cca:/home/ms/' + c.ecgid + '/' +
351                                       c.ecuid + '/ECMWFDATA7.1.tar'])
[a4b6cef]352        except:
[efdb01a]353            print('ecaccess-file-put failed! '
354                    'Probably the eccert key has expired.')
[a4b6cef]355            exit(1)
356
357        p=subprocess.check_call(['ecaccess-job-submit',
358                                '-queueName',
359                                target,
[efdb01a]360                                ecd + 'python/compilejob.ksh'])
[a4b6cef]361        print('compilejob.ksh has been submitted to cca for installation in ' +
[efdb01a]362              c.ec_flexpart_root_scripts + '/ECMWFDATA7.1')
363        print('You should get an email with subject flexcompile '
364                'within the next few minutes')
[64cf353]365
[d69b677]366    else:
[a4b6cef]367        print('ERROR: unknown installation target ', target)
368        print('Valid targets: ecgate, cca, local')
369
[d69b677]370    return
371
[a4b6cef]372
[d69b677]373if __name__ == "__main__":
374    main()
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG