source: flex_extract.git/source/python/submit.py @ a4531f1

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

exchanged all if conditions for pure fc from 'maxstep > < 12/24' into purefc(==True)

  • Property mode set to 100755
File size: 7.2 KB
RevLine 
[d69b677]1#!/usr/bin/env python
[64cf353]2# -*- coding: utf-8 -*-
[991df6a]3#*******************************************************************************
4# @Author: Anne Fouilloux (University of Oslo)
5#
6# @Date: October 2014
7#
8# @Change History:
9#
10#    November 2015 - Leopold Haimberger (University of Vienna):
11#        - job submission on ecgate and cca
12#        - job templates suitable for twice daily operational dissemination
13#
14#    February 2018 - Anne Philipp (University of Vienna):
15#        - applied PEP8 style guide
16#        - added documentation
17#        - minor changes in programming style (for consistence)
[2fb99de]18#        - changed path names to variables from config file
19#        - added option for writing mars requests to extra file
20#          additionally,as option without submitting the mars jobs
[991df6a]21#
22# @License:
23#    (C) Copyright 2014-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# @Program Functionality:
29#    This program is the main program of flex_extract and controls the
30#    program flow.
31#    If it is supposed to work locally then it works through the necessary
[ff99eae]32#    functions get_mars_data and prepareFlexpart. Otherwise it prepares
[991df6a]33#    a shell job script which will do the necessary work on the
34#    ECMWF server and is submitted via ecaccess-job-submit.
35#
36# @Program Content:
37#    - main
38#    - submit
39#
40#*******************************************************************************
[efdb01a]41
[64cf353]42# ------------------------------------------------------------------------------
43# MODULES
44# ------------------------------------------------------------------------------
[efdb01a]45import os
46import sys
[d69b677]47import subprocess
48import inspect
[54a8a01]49import collections
[efdb01a]50
51# software specific classes and modules from flex_extract
[54a8a01]52import _config
[25b14be]53from mods.tools import (normal_exit, get_cmdline_arguments,
54                        submit_job_to_ecserver, read_ecenv)
55from mods.get_mars_data import get_mars_data
56from mods.prepare_flexpart import prepare_flexpart
57from classes.ControlFile import ControlFile
[991df6a]58
[64cf353]59# ------------------------------------------------------------------------------
60# FUNCTIONS
61# ------------------------------------------------------------------------------
[991df6a]62
[d69b677]63def main():
[274f9ef]64    '''Get the arguments from script call and from CONTROL file.
65    Decides from the argument "queue" if the local version
66    is done "queue=None" or the gateway version with "queue=ecgate"
67    or "queue=cca".
68
69    Parameters
70    ----------
[d69b677]71
[274f9ef]72    Return
73    ------
[64cf353]74
75    '''
[ff99eae]76
[54a8a01]77    args = get_cmdline_arguments()
[4971f63]78    c = ControlFile(args.controlfile)
[2fb99de]79
80    env_parameter = read_ecenv(_config.PATH_ECMWF_ENV)
[54a8a01]81    c.assign_args_to_control(args)
82    c.assign_envs_to_control(env_parameter)
[2fb99de]83    c.check_conditions(args.queue)
[ff99eae]84
[efdb01a]85    # on local side
[2fb99de]86    # on ECMWF server this would also be the local side
87    called_from_dir = os.getcwd()
[295ff45]88    if args.queue is None:
[64cf353]89        if c.inputdir[0] != '/':
[ff99eae]90            c.inputdir = os.path.join(called_from_dir, c.inputdir)
[64cf353]91        if c.outputdir[0] != '/':
[ff99eae]92            c.outputdir = os.path.join(called_from_dir, c.outputdir)
[54a8a01]93        get_mars_data(c)
[2fb99de]94        if c.request == 0 or c.request == 2:
95            prepare_flexpart(args.ppid, c)
[96e1533]96            exit_message = 'FLEX_EXTRACT IS DONE!'
[2fb99de]97        else:
[96e1533]98            exit_message = 'PRINTING MARS_REQUESTS DONE!'
99    # send files to ECMWF server
[d69b677]100    else:
[64cf353]101        submit(args.job_template, c, args.queue)
[e0e99a5]102        exit_message = 'FLEX_EXTRACT JOB SCRIPT IS SUBMITED!'
[64cf353]103
[403cbf1]104    normal_exit(exit_message)
[96e1533]105
[64cf353]106    return
107
108def submit(jtemplate, c, queue):
[ff2a11c]109    '''Prepares the job script and submits it to the specified queue.
[274f9ef]110
111    Parameters
112    ----------
113    jtemplate : :obj:`string`
114        Job template file from sub-directory "_templates" for
115        submission to ECMWF. It contains all necessary
116        module and variable settings for the ECMWF environment as well as
117        the job call and mail report instructions.
118        Default is "job.temp".
119
120    c : :obj:`ControlFile`
121        Contains all the parameters of CONTROL file and
122        command line.
123
124    queue : :obj:`string`
125        Name of queue for submission to ECMWF (e.g. ecgate or cca )
126
127    Return
128    ------
129
[64cf353]130    '''
131
[54a8a01]132    if not c.basetime:
133    # --------- create on demand job script ------------------------------------
[a4531f1]134        if c.purefc:
[2fb99de]135            print('---- Pure forecast mode! ----')
[54a8a01]136        else:
[2fb99de]137            print('---- On-demand mode! ----')
[54a8a01]138
[ff2a11c]139        job_file = os.path.join(_config.PATH_JOBSCRIPTS,
140                                jtemplate[:-5] + '.ksh')
[54a8a01]141
[ff2a11c]142        clist = c.to_list()
[54a8a01]143
[ff2a11c]144        mk_jobscript(jtemplate, job_file, clist)
[54a8a01]145
146    else:
147    # --------- create operational job script ----------------------------------
[2fb99de]148        print('---- Operational mode! ----')
[ff2a11c]149
[2fb99de]150        job_file = os.path.join(_config.PATH_JOBSCRIPTS,
151                                jtemplate[:-5] + 'oper.ksh')
[54a8a01]152
153        c.start_date = '${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY}'
154        c.end_date = '${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY}'
155        c.base_time = '${MSJ_BASETIME}'
[ff2a11c]156        if c.maxstep > 24:
[54a8a01]157            c.time = '${MSJ_BASETIME} {MSJ_BASETIME}'
158
[ff2a11c]159        clist = c.to_list()
[54a8a01]160
[ff2a11c]161        mk_jobscript(jtemplate, job_file, clist)
[d69b677]162
[ff2a11c]163    # --------- submit the job_script to the ECMWF server
164    job_id = submit_job_to_ecserver(queue, job_file)
[96e1533]165    print('The job id is: ' + str(job_id.strip()))
[2fb99de]166    print('You should get an email with subject flex.hostname.pid')
[d69b677]167
[64cf353]168    return
[d69b677]169
[ff2a11c]170def mk_jobscript(jtemplate, job_file, clist):
171    '''Creates the job script from template.
172
173    Parameters
174    ----------
175    jtemplate : :obj:`string`
176        Job template file from sub-directory "_templates" for
177        submission to ECMWF. It contains all necessary
178        module and variable settings for the ECMWF environment as well as
179        the job call and mail report instructions.
180        Default is "job.temp".
181
182    job_file : :obj:`string`
183        Path to the job script file.
184
185    clist : :obj:`list` of :obj:`string`
186        Contains all necessary parameters for ECMWF CONTROL file.
187
188    Return
189    ------
190
191    '''
192    from genshi.template.text import NewTextTemplate
193    from genshi.template import  TemplateLoader
194    from genshi.template.eval import UndefinedError
195
196    # load template and insert control content as list
197    try:
198        loader = TemplateLoader(_config.PATH_TEMPLATES, auto_reload=False)
199        control_template = loader.load(jtemplate,
200                                       cls=NewTextTemplate)
201
202        stream = control_template.generate(control_content=clist)
203    except UndefinedError as e:
204        print('... ERROR ' + str(e))
205
206        sys.exit('\n... error occured while trying to generate jobscript')
207    except OSError as e:
208        print('... ERROR CODE: ' + str(e.errno))
209        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
210
211        sys.exit('\n... error occured while trying to generate jobscript')
212
213    # create jobscript file
214    try:
215        with open(job_file, 'w') as f:
216            f.write(stream.render('text'))
217    except OSError as e:
218        print('... ERROR CODE: ' + str(e.errno))
219        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
220
221        sys.exit('\n... error occured while trying to write ' + job_file)
222
223    return
224
[d69b677]225if __name__ == "__main__":
226    main()
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG