source: flex_extract.git/source/python/mods/get_mars_data.py @ 5bad6ec

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

added possibility to extract public datasets via an logical public parameter

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