source: flex_extract.git/source/python/mods/get_mars_data.py @ 5827ff6

ctbtodev
Last change on this file since 5827ff6 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
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 inspect
[ca867de]51from datetime import datetime, timedelta
[ff99eae]52
53# software specific classes and modules from flex_extract
[ca867de]54sys.path.append('../')
[2fb99de]55import _config
[5bad6ec]56from tools import (my_error, normal_exit, get_cmdline_arguments,
57                   read_ecenv, make_dir)
[25b14be]58from classes.EcFlexpart import EcFlexpart
59from classes.UioFiles import UioFiles
[ca867de]60
61try:
62    ecapi = True
63    import ecmwfapi
64except ImportError:
65    ecapi = False
[efdb01a]66# ------------------------------------------------------------------------------
67# FUNCTION
68# ------------------------------------------------------------------------------
[991df6a]69def main():
70    '''
71    @Description:
[295ff45]72        If get_mars_data is called directly from command line,
73
[991df6a]74        the program flow and calls the argumentparser function and
[ff99eae]75        the get_mars_data function for retrieving EC data.
[991df6a]76
77    @Input:
78        <nothing>
79
80    @Return:
81        <nothing>
82    '''
[54a8a01]83
84    args = get_cmdline_arguments()
[4971f63]85    c = ControlFile(args.controlfile)
[54a8a01]86
[2fb99de]87    env_parameter = read_ecenv(_config.PATH_ECMWF_ENV)
[295ff45]88    c.assign_args_to_control(args)
[54a8a01]89    c.assign_envs_to_control(env_parameter)
[2fb99de]90    c.check_conditions(args.queue)
[54a8a01]91
[ff99eae]92    get_mars_data(c)
[54a8a01]93    normal_exit(c.mailfail, 'Done!')
[d69b677]94
[991df6a]95    return
96
[ff99eae]97def get_mars_data(c):
[991df6a]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
[27fe969]107            Contains all the parameters of CONTROL file and
108            command line.
[991df6a]109            For more information about format and content of the parameter
110            see documentation.
111
112    @Return:
113        <nothing>
114    '''
[d69b677]115
116    if not os.path.exists(c.inputdir):
[5bad6ec]117        make_dir(c.inputdir)
[991df6a]118
[2fb99de]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))
[d69b677]126
127    if ecapi:
[5bad6ec]128        if c.public:
129            server = ecmwfapi.ECMWFDataServer()
130        else:
131            server = ecmwfapi.ECMWFService("mars")
[d69b677]132    else:
133        server = False
134
[64cf353]135    c.ecapi = ecapi
[2fb99de]136    print('Using ECMWF WebAPI: ' + str(c.ecapi))
[991df6a]137
[54a8a01]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
[ca867de]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))
[efdb01a]159
[54a8a01]160    if c.basetime == '00':
[ca867de]161        start = start - timedelta(days=1)
162
163    if c.maxstep <= 24:
164        startm1 = start - timedelta(days=1)
[54a8a01]165
166    if c.basetime == '00' or c.basetime == '12':
[ca867de]167        # endp1 = end + timedelta(days=1)
[54a8a01]168        endp1 = end
169    else:
[ca867de]170        # endp1 = end + timedelta(days=2)
171        endp1 = end + timedelta(days=1)
[54a8a01]172
[991df6a]173    # --------------  flux data ------------------------------------------------
[2fb99de]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()
[64cf353]179
[54a8a01]180    # if forecast for maximum one day (upto 24h) are to be retrieved,
[efdb01a]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)
[54a8a01]184    if c.maxstep <= 24:
185        do_retrievement(c, server, startm1, endp1, datechunk, fluxes=True)
[efdb01a]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)
[d69b677]192    else:
[54a8a01]193        do_retrievement(c, server, start, end, datechunk, fluxes=True)
[991df6a]194
195    # --------------  non flux data --------------------------------------------
[2fb99de]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()
[991df6a]201
[54a8a01]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:
[27fe969]213        c: instance of class ControlFile
214            Contains all the parameters of CONTROL file and
215            command line.
[54a8a01]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
[ca867de]244    delta_t_m1 = delta_t - timedelta(days=1)
[54a8a01]245
[efdb01a]246    day = start
247    while day <= end:
[54a8a01]248        flexpart = EcFlexpart(c, fluxes)
249        tmpday = day + delta_t_m1
[ff99eae]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")
[efdb01a]256
[2fb99de]257        print("... retrieve " + dates + " in dir " + c.inputdir)
[64cf353]258
[ff99eae]259        try:
[5bad6ec]260            flexpart.retrieve(server, dates, c.public, c.request, c.inputdir)
[ff99eae]261        except IOError:
[54a8a01]262            my_error(c.mailfail, 'MARS request failed')
[efdb01a]263
[54a8a01]264        day += delta_t
[64cf353]265
[efdb01a]266    return
[d69b677]267
268if __name__ == "__main__":
[991df6a]269    main()
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG