source: flex_extract.git/source/python/mods/get_mars_data.py @ 27fe969

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

put grib2flexpart part of code into its own function; changed function documentation of input controlfile parameter

  • Property mode set to 100755
File size: 8.5 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#        - moved the getEIdata program into a function "get_mars_data"
12#        - moved the AgurmentParser into a seperate function
13#        - adatpted the function for the use in flex_extract
14#        - renamed file to get_mars_data
15#
16#    February 2018 - Anne Philipp (University of Vienna):
17#        - applied PEP8 style guide
18#        - added structured documentation
19#        - minor changes in programming style for consistence
20#        - added function main and moved function calls vom __main__ there
21#          (necessary for better documentation with docstrings for later
22#          online documentation)
23#        - use of UIFiles class for file selection and deletion
24#
25#
26# @License:
27#    (C) Copyright 2014-2018.
28#
29#    This software is licensed under the terms of the Apache Licence Version 2.0
30#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
31#
32# @Program Functionality:
33#    This program can be used as a module in the whole flex_extract process
34#    or can be run by itself to just extract MARS data from ECMWF. To do so,
35#    a couple of necessary parameters has to be passed with the program call.
36#    See documentation for more details.
37#
38# @Program Content:
39#    - main
40#    - get_mars_data
41#    - do_retrievement
42#
43#*******************************************************************************
44
45# ------------------------------------------------------------------------------
46# MODULES
47# ------------------------------------------------------------------------------
48import os
49import sys
50import datetime
51import inspect
52try:
53    ecapi = True
54    import ecmwfapi
55except ImportError:
56    ecapi = False
57
58# software specific classes and modules from flex_extract
59import _config
60from tools import my_error, normal_exit, get_cmdline_arguments, read_ecenv
61from classes.EcFlexpart import EcFlexpart
62from classes.UioFiles import UioFiles
63# ------------------------------------------------------------------------------
64# FUNCTION
65# ------------------------------------------------------------------------------
66def main():
67    '''
68    @Description:
69        If get_mars_data is called directly from command line,
70
71        the program flow and calls the argumentparser function and
72        the get_mars_data function for retrieving EC data.
73
74    @Input:
75        <nothing>
76
77    @Return:
78        <nothing>
79    '''
80
81    args = get_cmdline_arguments()
82    c = ControlFile(args.controlfile)
83
84    env_parameter = read_ecenv(_config.PATH_ECMWF_ENV)
85    c.assign_args_to_control(args)
86    c.assign_envs_to_control(env_parameter)
87    c.check_conditions(args.queue)
88
89    get_mars_data(c)
90    normal_exit(c.mailfail, 'Done!')
91
92    return
93
94def get_mars_data(c):
95    '''
96    @Description:
97        Retrieves the EC data needed for a FLEXPART simulation.
98        Start and end dates for retrieval period is set. Retrievals
99        are divided into smaller periods if necessary and datechunk parameter
100        is set.
101
102    @Input:
103        c: instance of class ControlFile
104            Contains all the parameters of CONTROL file and
105            command line.
106            For more information about format and content of the parameter
107            see documentation.
108
109    @Return:
110        <nothing>
111    '''
112
113    if not os.path.exists(c.inputdir):
114        os.makedirs(c.inputdir)
115
116    if c.request == 0 or c.request == 2:
117        print("Retrieving EC data!")
118    elif c.request == 1:
119        print("Printing mars requests!")
120
121    print("start date %s " % (c.start_date))
122    print("end date %s " % (c.end_date))
123
124    if ecapi:
125        server = ecmwfapi.ECMWFService("mars")
126    else:
127        server = False
128
129    c.ecapi = ecapi
130    print('Using ECMWF WebAPI: ' + str(c.ecapi))
131
132    # basetime geht rückwärts
133
134    # if basetime 00
135    # dann wird von 12 am vortag bis 00 am start tag geholt
136    # aber ohne 12 selbst sondern 12 + step
137
138    # if basetime 12
139    # dann wird von 00 + step bis 12 am start tag geholt
140
141    # purer forecast wird vorwärts bestimmt.
142    # purer forecast mode ist dann wenn  größer 24 stunden
143    # wie kann das noch festgestellt werden ????
144    # nur FC und steps mehr als 24 ?
145    # die einzige problematik beim reinen forecast ist die benennung der files!
146    # also sobald es Tagesüberschneidungen gibt
147    # allerdings ist das relevant und ersichtlich an den NICHT FLUSS DATEN
148
149
150    # set start date of retrieval period
151    start = datetime.date(year=int(c.start_date[:4]),
152                          month=int(c.start_date[4:6]),
153                          day=int(c.start_date[6:]))
154    startm1 = start - datetime.timedelta(days=1)
155
156    # set end date of retrieval period
157    end = datetime.date(year=int(c.end_date[:4]),
158                        month=int(c.end_date[4:6]),
159                        day=int(c.end_date[6:]))
160
161    # set time period for one single retrieval
162    datechunk = datetime.timedelta(days=int(c.date_chunk))
163
164    if c.basetime == '00':
165        start = startm1
166
167    if c.basetime == '00' or c.basetime == '12':
168        # endp1 = end + datetime.timedelta(days=1)
169        endp1 = end
170    else:
171        # endp1 = end + datetime.timedelta(days=2)
172        endp1 = end + datetime.timedelta(days=1)
173
174    # --------------  flux data ------------------------------------------------
175    if c.request == 0 or c.request == 2:
176        print('... removing old flux content of ' + c.inputdir)
177        tobecleaned = UioFiles(c.inputdir,
178                               '*_acc_*.' + str(os.getppid()) + '.*.grb')
179        tobecleaned.delete_files()
180
181    # if forecast for maximum one day (upto 24h) are to be retrieved,
182    # collect accumulation data (flux data)
183    # with additional days in the beginning and at the end
184    # (used for complete disaggregation of original period)
185    if c.maxstep <= 24:
186        do_retrievement(c, server, startm1, endp1, datechunk, fluxes=True)
187
188    # if forecast data longer than 24h are to be retrieved,
189    # collect accumulation data (flux data)
190    # with the exact start and end date
191    # (disaggregation will be done for the
192    # exact time period with boundary conditions)
193    else:
194        do_retrievement(c, server, start, end, datechunk, fluxes=True)
195
196    # --------------  non flux data --------------------------------------------
197    if c.request == 0 or c.request == 2:
198        print('... removing old non flux content of ' + c.inputdir)
199        tobecleaned = UioFiles(c.inputdir,
200                               '*__*.' + str(os.getppid()) + '.*.grb')
201        tobecleaned.delete_files()
202
203    do_retrievement(c, server, start, end, datechunk, fluxes=False)
204
205    return
206
207def do_retrievement(c, server, start, end, delta_t, fluxes=False):
208    '''
209    @Description:
210        Divides the complete retrieval period in smaller chunks and
211        retrieves the data from MARS.
212
213    @Input:
214        c: instance of class ControlFile
215            Contains all the parameters of CONTROL file and
216            command line.
217            For more information about format and content of the parameter
218            see documentation.
219
220        server: instance of ECMWFService
221            The server connection to ECMWF
222
223        start: instance of datetime
224            The start date of the retrieval.
225
226        end: instance of datetime
227            The end date of the retrieval.
228
229        delta_t: instance of datetime
230            Delta_t +1 is the maximal time period of a single
231            retrieval.
232
233        fluxes: boolean, optional
234            Decides if the flux parameters are to be retrieved or
235            the rest of the parameter list.
236            Default value is False.
237
238    @Return:
239        <nothing>
240    '''
241
242    # since actual day also counts as one day,
243    # we only need to add datechunk - 1 days to retrieval
244    # for a period
245    delta_t_m1 = delta_t - datetime.timedelta(days=1)
246
247    day = start
248    while day <= end:
249        flexpart = EcFlexpart(c, fluxes)
250        tmpday = day + delta_t_m1
251        if tmpday < end:
252            dates = day.strftime("%Y%m%d") + "/to/" + \
253                    tmpday.strftime("%Y%m%d")
254        else:
255            dates = day.strftime("%Y%m%d") + "/to/" + \
256                    end.strftime("%Y%m%d")
257
258        print("... retrieve " + dates + " in dir " + c.inputdir)
259
260        try:
261            flexpart.retrieve(server, dates, c.request, c.inputdir)
262        except IOError:
263            my_error(c.mailfail, 'MARS request failed')
264
265        day += delta_t
266
267    return
268
269if __name__ == "__main__":
270    main()
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG