source: flex_extract.git/source/python/mods/get_mars_data.py @ 274f9ef

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

Converted docstrings to numpy style and build first structure for sphinxdocumentation (incl API)

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