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
RevLine 
[d69b677]1#!/usr/bin/env python
[efdb01a]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):
[ff99eae]11#        - moved the getEIdata program into a function "get_mars_data"
[991df6a]12#        - moved the AgurmentParser into a seperate function
13#        - adatpted the function for the use in flex_extract
[ff99eae]14#        - renamed file to get_mars_data
[991df6a]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
[54a8a01]24#
[991df6a]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
[ff99eae]40#    - get_mars_data
[54a8a01]41#    - do_retrievement
[991df6a]42#
43#*******************************************************************************
44
[efdb01a]45# ------------------------------------------------------------------------------
46# MODULES
47# ------------------------------------------------------------------------------
[991df6a]48import os
49import sys
50import datetime
51import inspect
[d69b677]52try:
[ff99eae]53    ecapi = True
[d69b677]54    import ecmwfapi
55except ImportError:
[ff99eae]56    ecapi = False
57
58# software specific classes and modules from flex_extract
[2fb99de]59import _config
[54a8a01]60from tools import my_error, normal_exit, get_cmdline_arguments, read_ecenv
[25b14be]61from classes.EcFlexpart import EcFlexpart
62from classes.UioFiles import UioFiles
[efdb01a]63# ------------------------------------------------------------------------------
64# FUNCTION
65# ------------------------------------------------------------------------------
[991df6a]66def main():
67    '''
68    @Description:
[295ff45]69        If get_mars_data is called directly from command line,
70
[991df6a]71        the program flow and calls the argumentparser function and
[ff99eae]72        the get_mars_data function for retrieving EC data.
[991df6a]73
74    @Input:
75        <nothing>
76
77    @Return:
78        <nothing>
79    '''
[54a8a01]80
81    args = get_cmdline_arguments()
[4971f63]82    c = ControlFile(args.controlfile)
[54a8a01]83
[2fb99de]84    env_parameter = read_ecenv(_config.PATH_ECMWF_ENV)
[295ff45]85    c.assign_args_to_control(args)
[54a8a01]86    c.assign_envs_to_control(env_parameter)
[2fb99de]87    c.check_conditions(args.queue)
[54a8a01]88
[ff99eae]89    get_mars_data(c)
[54a8a01]90    normal_exit(c.mailfail, 'Done!')
[d69b677]91
[991df6a]92    return
93
[ff99eae]94def get_mars_data(c):
[991df6a]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
[27fe969]104            Contains all the parameters of CONTROL file and
105            command line.
[991df6a]106            For more information about format and content of the parameter
107            see documentation.
108
109    @Return:
110        <nothing>
111    '''
[d69b677]112
113    if not os.path.exists(c.inputdir):
114        os.makedirs(c.inputdir)
[991df6a]115
[2fb99de]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))
[d69b677]123
124    if ecapi:
125        server = ecmwfapi.ECMWFService("mars")
126    else:
127        server = False
128
[64cf353]129    c.ecapi = ecapi
[2fb99de]130    print('Using ECMWF WebAPI: ' + str(c.ecapi))
[991df6a]131
[54a8a01]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
[991df6a]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:]))
[64cf353]154    startm1 = start - datetime.timedelta(days=1)
[efdb01a]155
[991df6a]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:]))
[64cf353]160
[54a8a01]161    # set time period for one single retrieval
[64cf353]162    datechunk = datetime.timedelta(days=int(c.date_chunk))
[efdb01a]163
[54a8a01]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
[991df6a]174    # --------------  flux data ------------------------------------------------
[2fb99de]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()
[64cf353]180
[54a8a01]181    # if forecast for maximum one day (upto 24h) are to be retrieved,
[efdb01a]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)
[54a8a01]185    if c.maxstep <= 24:
186        do_retrievement(c, server, startm1, endp1, datechunk, fluxes=True)
[efdb01a]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)
[d69b677]193    else:
[54a8a01]194        do_retrievement(c, server, start, end, datechunk, fluxes=True)
[991df6a]195
196    # --------------  non flux data --------------------------------------------
[2fb99de]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()
[991df6a]202
[54a8a01]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:
[27fe969]214        c: instance of class ControlFile
215            Contains all the parameters of CONTROL file and
216            command line.
[54a8a01]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
[efdb01a]247    day = start
248    while day <= end:
[54a8a01]249        flexpart = EcFlexpart(c, fluxes)
250        tmpday = day + delta_t_m1
[ff99eae]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")
[efdb01a]257
[2fb99de]258        print("... retrieve " + dates + " in dir " + c.inputdir)
[64cf353]259
[ff99eae]260        try:
[2fb99de]261            flexpart.retrieve(server, dates, c.request, c.inputdir)
[ff99eae]262        except IOError:
[54a8a01]263            my_error(c.mailfail, 'MARS request failed')
[efdb01a]264
[54a8a01]265        day += delta_t
[64cf353]266
[efdb01a]267    return
[d69b677]268
269if __name__ == "__main__":
[991df6a]270    main()
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG