source: flex_extract.git/python/prepare_flexpart.py @ 97e09f4

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

restructuring, documentations and bug fixes

  • Property mode set to 100755
File size: 7.1 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
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#        - using the WebAPI also for general MARS retrievals
12#        - job submission on ecgate and cca
13#        - job templates suitable for twice daily operational dissemination
14#        - dividing retrievals of longer periods into digestable chunks
15#        - retrieve also longer term forecasts, not only analyses and
16#          short term forecast data
17#        - conversion into GRIB2
18#        - conversion into .fp format for faster execution of FLEXPART
19#
20#    February 2018 - Anne Philipp (University of Vienna):
21#        - applied PEP8 style guide
22#        - added documentation
23#        - minor changes in programming style for consistence
24#        - BUG: removed call of clean_up-Function after call of
25#               prepareFlexpart in main since it is already called in
26#               prepareFlexpart at the end!
27#        - created function main and moved the two function calls for
28#          arguments and prepare_flexpart into it
29#
30# @License:
31#    (C) Copyright 2014-2018.
32#
33#    This software is licensed under the terms of the Apache Licence Version 2.0
34#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
35#
36# @Program Functionality:
37#    This program prepares the final version of the grib files which are
38#    then used by FLEXPART. It converts the bunch of grib files extracted
39#    via get_mars_data by doing for example the necessary conversion to get
40#    consistent grids or the disaggregation of flux data. Finally, the
41#    program combines the data fields in files per available hour with the
42#    naming convention xxYYMMDDHH, where xx should be 2 arbitrary letters
43#    (mostly xx is chosen to be "EN").
44#
45# @Program Content:
46#    - main
47#    - prepare_flexpart
48#
49#*******************************************************************************
50
51# ------------------------------------------------------------------------------
52# MODULES
53# ------------------------------------------------------------------------------
54import datetime
55import os
56import inspect
57import sys
58import socket
59import _config
60
61# software specific classes and modules from flex_extract
62from UioFiles import UioFiles
63from tools import clean_up, get_cmdline_arguments, read_ecenv
64from EcFlexpart import EcFlexpart
65
66ecapi = 'ecmwf' not in socket.gethostname()
67try:
68    if ecapi:
69        import ecmwfapi
70except ImportError:
71    ecapi = False
72
73# add path to pythonpath so that python finds its buddies
74LOCAL_PYTHON_PATH = os.path.dirname(os.path.abspath(
75    inspect.getfile(inspect.currentframe())))
76if LOCAL_PYTHON_PATH not in sys.path:
77    sys.path.append(LOCAL_PYTHON_PATH)
78
79
80# ------------------------------------------------------------------------------
81# FUNCTION
82# ------------------------------------------------------------------------------
83def main():
84    '''
85    @Description:
86        If prepare_flexpart is called from command line, this function controls
87        the program flow and calls the argumentparser function and
88        the prepare_flexpart function for preparation of GRIB data for FLEXPART.
89
90    @Input:
91        <nothing>
92
93    @Return:
94        <nothing>
95    '''
96
97    args = get_cmdline_arguments()
98
99    try:
100        c = ControlFile(args.controlfile)
101    except IOError:
102        try:
103            c = ControlFile(LOCAL_PYTHON_PATH + args.controlfile)
104        except IOError:
105            print 'Could not read CONTROL file "' + args.controlfile + '"'
106            print 'Either it does not exist or its syntax is wrong.'
107            print 'Try "' + sys.argv[0].split('/')[-1] + \
108                  ' -h" to print usage information'
109            sys.exit(1)
110
111    env_parameter = read_ecenv(c.ecmwfdatadir + 'python/ECMWF_ENV')
112    c.assign_args_to_control(args, env_parameter)
113    c.assign_envs_to_control(env_parameter)
114    c.check_conditions()
115    prepare_flexpart(args.ppid, c)
116
117    return
118
119def prepare_flexpart(ppid, c):
120    '''
121    @Description:
122        Lists all grib files retrieved from MARS with get_mars_data and
123        uses prepares data for the use in FLEXPART. Specific data fields
124        are converted to a different grid and the flux data are going to be
125        disaggregated. The data fields are collected by hour and stored in
126        a file with a specific FLEXPART relevant naming convention.
127
128    @Input:
129        ppid: int
130            Contains the ppid number of the current ECMWF job. If it is called
131            from this script, it is "None".
132
133        c: instance of class ControlFile
134            Contains all the parameters of CONTROL file, which are e.g.:
135            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
136            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
137            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
138            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
139            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
140            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
141            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
142
143            For more information about format and content of the parameter
144            see documentation.
145
146    @Return:
147        <nothing>
148    '''
149
150    if not ppid:
151        c.ppid = str(os.getppid())
152    else:
153        c.ppid = ppid
154
155    c.ecapi = ecapi
156
157    # create the start and end date
158    start = datetime.date(year=int(c.start_date[:4]),
159                          month=int(c.start_date[4:6]),
160                          day=int(c.start_date[6:]))
161
162    end = datetime.date(year=int(c.end_date[:4]),
163                        month=int(c.end_date[4:6]),
164                        day=int(c.end_date[6:]))
165
166    # assign starting date minus 1 day
167    # since for basetime 00 we need the 12 hours upfront
168    # (the day before from 12 UTC to current day 00 UTC)
169    if c.basetime == '00':
170        start = start - datetime.timedelta(days=1)
171
172    print 'Prepare ' + start.strftime("%Y%m%d") + \
173           "/to/" + end.strftime("%Y%m%d")
174
175    # create output dir if necessary
176    if not os.path.exists(c.outputdir):
177        os.makedirs(c.outputdir)
178
179    # get all files with flux data to be deaccumulated
180    inputfiles = UioFiles(c.inputdir, '*OG_acc_SL*.' + c.ppid + '.*')
181
182    # deaccumulate the flux data
183    flexpart = EcFlexpart(c, fluxes=True)
184    flexpart.write_namelist(c, 'fort.4')
185    flexpart.deacc_fluxes(inputfiles, c)
186
187    # get a list of all files from the root inputdir
188    inputfiles = UioFiles(c.inputdir, '????__??.*' + c.ppid + '.*')
189
190    # produce FLEXPART-ready GRIB files and process them -
191    # copy/transfer/interpolate them or make them GRIB2
192    flexpart = EcFlexpart(c, fluxes=False)
193    flexpart.create(inputfiles, c)
194    flexpart.process_output(c)
195
196    # check if in debugging mode, then store all files
197    # otherwise delete temporary files
198    if int(c.debug) != 0:
199        print '\nTemporary files left intact'
200    else:
201        clean_up(c)
202
203    return
204
205if __name__ == "__main__":
206    main()
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG