source: flex_extract.git/source/python/mods/prepare_flexpart.py @ 295ff45

dev
Last change on this file since 295ff45 was 295ff45, checked in by Anne Philipp <anne.philipp@…>, 11 months ago

added request output option also for basetime requests; changed output to csv format

  • Property mode set to 100755
File size: 6.4 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
59
60# software specific classes and modules from flex_extract
61import _config
62from classes.UioFiles import UioFiles
63from tools import clean_up, get_cmdline_arguments, read_ecenv
64from classes.EcFlexpart import EcFlexpart
65
66ecapi = 'ecmwf' not in socket.gethostname()
67try:
68    if ecapi:
69        import ecmwfapi
70except ImportError:
71    ecapi = False
72
73# ------------------------------------------------------------------------------
74# FUNCTION
75# ------------------------------------------------------------------------------
76def main():
77    '''
78    @Description:
79        If prepare_flexpart is called from command line, this function controls
80        the program flow and calls the argumentparser function and
81        the prepare_flexpart function for preparation of GRIB data for FLEXPART.
82
83    @Input:
84        <nothing>
85
86    @Return:
87        <nothing>
88    '''
89
90    args = get_cmdline_arguments()
91    c = ControlFile(args.controlfile)
92
93    env_parameter = read_ecenv(_config.PATH_ECMWF_ENV)
94    c.assign_args_to_control(args)
95    c.assign_envs_to_control(env_parameter)
96    c.check_conditions(args.queue)
97
98    prepare_flexpart(args.ppid, c)
99
100    return
101
102def prepare_flexpart(ppid, c):
103    '''
104    @Description:
105        Lists all grib files retrieved from MARS with get_mars_data and
106        uses prepares data for the use in FLEXPART. Specific data fields
107        are converted to a different grid and the flux data are going to be
108        disaggregated. The data fields are collected by hour and stored in
109        a file with a specific FLEXPART relevant naming convention.
110
111    @Input:
112        ppid: int
113            Contains the ppid number of the current ECMWF job. If it is called
114            from this script, it is "None".
115
116        c: instance of class ControlFile
117            Contains all the parameters of CONTROL file, which are e.g.:
118            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
119            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
120            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
121            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
122            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
123            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
124            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
125
126            For more information about format and content of the parameter
127            see documentation.
128
129    @Return:
130        <nothing>
131    '''
132
133    if not ppid:
134        c.ppid = str(os.getppid())
135    else:
136        c.ppid = ppid
137
138    c.ecapi = ecapi
139
140    # create the start and end date
141    start = datetime.date(year=int(c.start_date[:4]),
142                          month=int(c.start_date[4:6]),
143                          day=int(c.start_date[6:]))
144
145    end = datetime.date(year=int(c.end_date[:4]),
146                        month=int(c.end_date[4:6]),
147                        day=int(c.end_date[6:]))
148
149    # assign starting date minus 1 day
150    # since for basetime 00 we need the 12 hours upfront
151    # (the day before from 12 UTC to current day 00 UTC)
152    if c.basetime == '00':
153        start = start - datetime.timedelta(days=1)
154
155    print('Prepare ' + start.strftime("%Y%m%d") +
156           "/to/" + end.strftime("%Y%m%d"))
157
158    # create output dir if necessary
159    if not os.path.exists(c.outputdir):
160        os.makedirs(c.outputdir)
161
162    # get all files with flux data to be deaccumulated
163    inputfiles = UioFiles(c.inputdir, '*OG_acc_SL*.' + c.ppid + '.*')
164
165    # deaccumulate the flux data
166    flexpart = EcFlexpart(c, fluxes=True)
167    flexpart.write_namelist(c, _config.FILE_NAMELIST)
168    flexpart.deacc_fluxes(inputfiles, c)
169
170    # get a list of all files from the root inputdir
171    inputfiles = UioFiles(c.inputdir, '????__??.*' + c.ppid + '.*')
172
173    # produce FLEXPART-ready GRIB files and process them -
174    # copy/transfer/interpolate them or make them GRIB2
175    flexpart = EcFlexpart(c, fluxes=False)
176    flexpart.create(inputfiles, c)
177    flexpart.process_output(c)
178
179    # check if in debugging mode, then store all files
180    # otherwise delete temporary files
181    if int(c.debug) != 0:
182        print('\nTemporary files left intact')
183    else:
184        clean_up(c)
185
186    return
187
188if __name__ == "__main__":
189    main()
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG