diff --git a/Source/Python/Classes/ControlFile.py b/Source/Python/Classes/ControlFile.py index 6b143835e30f5499e4278b95ceaf8440272ca99f..abd9b52df377df6d679d4dfe0466a5d549629313 100644 --- a/Source/Python/Classes/ControlFile.py +++ b/Source/Python/Classes/ControlFile.py @@ -623,8 +623,6 @@ class ControlFile(object): self.start_date, self.end_date = check_dates(self.start_date, self.end_date) - self.basetime = check_basetime(self.basetime) - self.levelist, self.level = check_levels(self.levelist, self.level) self.step = check_step(self.step) @@ -638,10 +636,12 @@ class ControlFile(object): self.type = check_type(self.type, self.step) - self.time = check_time(self.time) - self.purefc = check_purefc(self.type) + self.basetime, self.time = check_basetime(self.basetime, self.time, self.purefc) + + self.time = check_time(self.time) + self.type, self.time, self.step = check_len_type_time_step(self.type, self.time, self.step, @@ -651,7 +651,8 @@ class ControlFile(object): self.acctype = check_acctype(self.acctype, self.type) self.acctime = check_acctime(self.acctime, self.marsclass, - self.purefc, self.time) + self.purefc, self.time, + self.basetime, self.oper) self.accmaxstep = check_accmaxstep(self.accmaxstep, self.marsclass, self.purefc, self.maxstep) diff --git a/Source/Python/Classes/EcFlexpart.py b/Source/Python/Classes/EcFlexpart.py index a7dda984e8bf8e0babc74b967ca68128d9e288e3..488b72dd1933d07cd13aa83152dd40a96dc3e43d 100644 --- a/Source/Python/Classes/EcFlexpart.py +++ b/Source/Python/Classes/EcFlexpart.py @@ -614,7 +614,7 @@ class EcFlexpart(object): return iid, index_vals - def retrieve(self, server, dates, public, request, inputdir='.'): + def retrieve(self, server, dates, public, purefc, request, inputdir='.'): '''Finalizing the retrieval information by setting final details depending on grid type. Prepares MARS retrievals per grid type and submits them. @@ -633,6 +633,14 @@ class EcFlexpart(object): Contains start and end date of the retrieval in the format "YYYYMMDD/to/YYYYMMDD" + public : int + Switch to select kind of ECMWF Web API access and the possible data sets. + Public data sets (1) and Member states data sets (0). + + purefc : int + Switch to decide whether the job is a pure forecast retrieval or + coupled with analysis data. + request : int Selects the mode of retrieval. 0: Retrieves the data from ECMWF. @@ -651,6 +659,7 @@ class EcFlexpart(object): self.server = server self.public = public self.inputdir = inputdir + self.purefc = purefc oro = False # define times with datetime module @@ -738,7 +747,7 @@ class EcFlexpart(object): print('CHANGED FC start date to ' + sdate.strftime("%Y%m%d") + - ' to accomodate TIME=' + + ' to accommodate TIME=' + retr_param_dict['time'][0] + ', STEP=' + retr_param_dict['time'][0]) @@ -752,26 +761,25 @@ class EcFlexpart(object): # check if mars job requests fields beyond basetime. # if yes eliminate those fields since they may not # be accessible with user's credentials - + dates = retr_param_dict['date'].split('/') enddate = retr_param_dict['date'].split('/')[-1] - elimit = datetime.strptime(enddate + str(self.basetime), - '%Y%m%d%H') + elimit = datetime.strptime(enddate, '%Y%m%d') if self.basetime == 12: # -------------- flux data ---------------------------- - if 'acc' in pk: - startdate = retr_param_dict['date'].split('/')[0] - enddate = datetime.strftime(elimit - t24h, '%Y%m%d') - retr_param_dict['date'] = '/'.join([startdate, - 'to', - enddate]) + if 'acc' in pk and not self.purefc: + + retr_param_dict['date'] = dates[0] + retr_param_dict['time'] = '12' + retr_param_dict['target'] = \ + self._mk_targetname(ftype, pk, + retr_param_dict['date']) # ******* start retrievement self._start_retrievement(request, retr_param_dict) - retr_param_dict['date'] = \ - datetime.strftime(elimit - t12h, '%Y%m%d') - retr_param_dict['time'] = '00' + retr_param_dict['date'] = dates[-1] + retr_param_dict['time'] = '00/12' retr_param_dict['target'] = \ self._mk_targetname(ftype, pk, retr_param_dict['date']) @@ -785,42 +793,64 @@ class EcFlexpart(object): self._start_retrievement(request, retr_param_dict) elif self.basetime == 0: + # -------------- flux data ---------------------------- + if 'acc' in pk and not self.purefc: - timesave = ''.join(retr_param_dict['time']) - - if all(['/' in retr_param_dict['time'], - pk != 'OG_OROLSM__SL', - 'acc' not in pk]): - times = retr_param_dict['time'].split('/') - steps = retr_param_dict['step'].split('/') - - while int(times[0]) + int(steps[0]) <= 12: - times = times[1:] - if len(times) > 1: - retr_param_dict['time'] = '/'.join(times) - else: - retr_param_dict['time'] = times[0] + retr_param_dict['date'] = dates[0] + retr_param_dict['time'] = '00/12' + retr_param_dict['target'] = \ + self._mk_targetname(ftype, pk, + retr_param_dict['date']) - if all([pk != 'OG_OROLSM__SL', - int(retr_param_dict['step'].split('/')[0]) == 0, - int(timesave.split('/')[0]) == 0]): + # ******* start retrievement + self._start_retrievement(request, retr_param_dict) - retr_param_dict['date'] = \ - datetime.strftime(elimit, '%Y%m%d') + retr_param_dict['date'] = dates[-1] retr_param_dict['time'] = '00' - retr_param_dict['step'] = '000' retr_param_dict['target'] = \ self._mk_targetname(ftype, pk, retr_param_dict['date']) - if ftype.upper() == 'FC' and \ - 'acc' not in retr_param_dict['target']: - - retr_param_dict['date'] = \ - datetime.strftime(elimit - t24h, '%Y%m%d') + # ******* start retrievement + self._start_retrievement(request, retr_param_dict) + elif 'acc' in pk and self.purefc: + # ******* start retrievement + self._start_retrievement(request, retr_param_dict) + # -------------- non flux data ------------------------ + else: # 'acc' not in pk + timesave = ''.join(retr_param_dict['time']) + + if all(['/' in retr_param_dict['time'], + pk != 'OG_OROLSM__SL']): + times = retr_param_dict['time'].split('/') + steps = retr_param_dict['step'].split('/') + + while int(times[0]) + int(steps[0]) <= 12: + times = times[1:] + if len(times) > 1: + retr_param_dict['time'] = '/'.join(times) + else: + retr_param_dict['time'] = times[0] + + if all([pk != 'OG_OROLSM__SL', + int(retr_param_dict['step'].split('/')[0]) == 0, + int(timesave.split('/')[0]) == 0]): + + retr_param_dict['date'] = \ + datetime.strftime(elimit, '%Y%m%d') + retr_param_dict['time'] = '00' + retr_param_dict['step'] = '000' + retr_param_dict['target'] = \ + self._mk_targetname(ftype, pk, + retr_param_dict['date']) + + if ftype.upper() == 'FC' and not self.purefc: + + retr_param_dict['date'] = \ + datetime.strftime(elimit - t24h, '%Y%m%d') - # ******* start retrievement - self._start_retrievement(request, retr_param_dict) + # ******* start retrievement + self._start_retrievement(request, retr_param_dict) else: raise ValueError('ERROR: Basetime has an invalid value ' '-> {}'.format(str(self.basetime))) diff --git a/Source/Python/Mods/checks.py b/Source/Python/Mods/checks.py index 27c02e08e919e3774f55ba07016c133fc370ddd1..227f36f48472a5c455dbd446ea7504c222455900 100644 --- a/Source/Python/Mods/checks.py +++ b/Source/Python/Mods/checks.py @@ -92,7 +92,7 @@ def check_grid(grid): grid = gridx else: raise ValueError('GRID parameter contains two ' - 'different values: %s' (grid)) + 'different values: %s', grid) # # determine grid format # if float(grid) / 100. >= 0.5: # # grid is defined in 1/1000 degrees; old format @@ -235,7 +235,6 @@ def check_levels(levelist, level): return levelist, level - def check_ppid(c, ppid): '''Sets the current PPID. @@ -261,7 +260,6 @@ def check_ppid(c, ppid): return - def check_purefc(ftype): '''Check for a pure forecast mode. @@ -283,7 +281,6 @@ def check_purefc(ftype): return 0 - def check_step(step): '''Checks on step format and convert into a list of steps. @@ -403,14 +400,9 @@ def check_len_type_time_step(ftype, ftime, steps, maxstep, purefc): Specifies the forecast time step from forecast base time. Valid values are hours (HH) from forecast base time. ''' - if not len(ftype) == len(ftime) == len(steps): - raise ValueError('ERROR: The number of field types, times and steps ' - 'are not the same! Please check the settings in the ' - 'CONTROL file!') - # if pure forecast is selected and only one field type/time is set # prepare a complete list of type/time/step combination upto maxstep - if len(ftype) == 1 and purefc: + if len(ftime) == 1 and purefc: nftype = [] nsteps = [] nftime = [] @@ -420,6 +412,10 @@ def check_len_type_time_step(ftype, ftime, steps, maxstep, purefc): nftime.append(ftime[0]) return nftype, nftime, nsteps + if not len(ftype) == len(ftime) == len(steps): + raise ValueError('ERROR: The number of field types, times and steps ' + 'are not the same! Please check the settings in the ' + 'CONTROL file!') return ftype, ftime, steps def check_mail(mail): @@ -604,7 +600,7 @@ def check_maxstep(maxstep, steps): return maxstep -def check_basetime(basetime): +def check_basetime(basetime, time, purefc): '''Check if basetime is set and contains one of the two possible values (0, 12). @@ -614,18 +610,30 @@ def check_basetime(basetime): The time for a half day retrieval. The 12 hours upfront are to be retrieved. + time : str + The time in hours of the field. + + purefc : int + 1 if pure forecasts are to be retrieved. 0 if there are + analysis fields in between. + Return ------ basetime : int or None The time for a half day retrieval. The 12 hours upfront are to be retrieved. + + time : str or list of str + The time in hours of the field. ''' if basetime is not None: basetime = int(basetime) if basetime != 0 and basetime != 12: raise ValueError('ERROR: Basetime has an invalid value ' '-> {}'.format(str(basetime))) - return basetime + if purefc: + time = str(basetime) + return basetime, time def check_request(request, marsfile): '''Check if there is an old MARS request file; if so, remove it. @@ -706,8 +714,7 @@ def check_acctype(acctype, ftype): 'of type "analysis"!') return acctype - -def check_acctime(acctime, marsclass, purefc, time): +def check_acctime(acctime, marsclass, purefc, time, basetime, oper): '''Guarantees that the accumulation forecast times were set. If not set, setting the value to some of the most commonly used data sets @@ -724,12 +731,23 @@ def check_acctime(acctime, marsclass, purefc, time): purefc : int Switch for definition of pure forecast mode or not. + basetime : int + The time for a half day retrieval. The 12 hours upfront are to be + retrieved. + + oper : int + Switch to prepare the operational job script. Start date, end date and + basetime will be prepared with environment variables. + Return ------ acctime : str The starting time for the accumulated forecasts. ''' + if acctime and basetime and oper: + return basetime + if not acctime: print('... Control parameter ACCTIME was not set.') print('... Value will be set depending on field type:\n ' @@ -816,7 +834,7 @@ def check_addpar(addpar): if addpar and isinstance(addpar, str): if '/' in addpar: parlist = addpar.split('/') - parlist = [p for p in parlist if p is not ''] + parlist = [p for p in parlist if p != ''] else: parlist = [addpar] @@ -824,7 +842,6 @@ def check_addpar(addpar): return addpar - def check_job_chunk(job_chunk): '''Checks that if job chunk is set, the number is positive and nonzero. @@ -853,7 +870,6 @@ def check_job_chunk(job_chunk): return job_chunk - def check_number(number): '''Check for correct string format of ensemble member numbers. diff --git a/Source/Python/Mods/get_mars_data.py b/Source/Python/Mods/get_mars_data.py index 722eeb461569099f0c14cf87792e1cf5b31a780a..a91233f4026ea3c6d4513ce1d97a92acdb160979 100755 --- a/Source/Python/Mods/get_mars_data.py +++ b/Source/Python/Mods/get_mars_data.py @@ -159,7 +159,7 @@ def get_mars_data(c): # -------------- flux data ------------------------------------------------ start, end, datechunk = mk_dates(c, fluxes=True) do_retrievement(c, server, start, end, datechunk, fluxes=True) - + # -------------- non flux data -------------------------------------------- start, end, datechunk = mk_dates(c, fluxes=False) do_retrievement(c, server, start, end, datechunk, fluxes=False) @@ -292,20 +292,20 @@ def mk_dates(c, fluxes): end = datetime.strptime(c.end_date, '%Y%m%d') chunk = timedelta(days=int(c.date_chunk)) - if c.basetime == 0 and not fluxes: # non-fluxes + if c.basetime == 0 and not fluxes and not c.purefc: # non-fluxes start = start - timedelta(days=1) if c.purefc and fluxes and c.maxstep < 24: start = start - timedelta(days=1) - if not c.oper: - end = end + timedelta(days=1) +# if not c.oper: +# end = end + timedelta(days=1) if not c.purefc and fluxes: start = start - timedelta(days=1) if not c.oper: end = end + timedelta(days=1) - elif c.oper and c.basetime == 0: - end = end - timedelta(days=1) +# elif c.oper and c.basetime == 0: +# end = end - timedelta(days=1) # if we have non-flux forecast data starting at 18 UTC # we need to start retrieving data one day in advance @@ -388,7 +388,7 @@ def do_retrievement(c, server, start, end, delta_t, fluxes=False): print("... retrieve " + dates + " in dir " + c.inputdir) try: - flexpart.retrieve(server, dates, c.public, c.request, c.inputdir) + flexpart.retrieve(server, dates, c.public, c.purefc, c.request, c.inputdir) except IOError: my_error('MARS request failed')