From 8acc4fe52b4826ea29dff526b8445055ae968c45 Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Fri, 28 Apr 2023 00:45:18 +0200 Subject: [PATCH 01/10] Fixed selection of 2 or 3 days of forecast in model maps and timeseries. Still missing in preproc --- data_handler.py | 6 ++++-- tabs/forecast.py | 14 +++----------- tools.py | 12 +++++++----- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/data_handler.py b/data_handler.py index f740719..fc68724 100644 --- a/data_handler.py +++ b/data_handler.py @@ -376,7 +376,8 @@ class TimeSeriesHandler(object): if DEBUG: print("----------", model) method = 'netcdf' - if not DELAY and MODELS[model]['start'] == 12: + if (MODELS[model]['start'] == 12 and not DELAY and DELAY_DATE and (datetime.strptime(self.currdate, "%Y%m%d") >= datetime.strptime(DELAY_DATE, "%Y%m%d"))) or \ + (MODELS[model]['start'] == 12 and not DELAY and not DELAY_DATE): mod_date = (datetime.strptime(self.currdate, "%Y%m%d") - timedelta(days=1)).strftime("%Y%m%d") else: @@ -418,7 +419,8 @@ class TimeSeriesHandler(object): if forecast: method = 'netcdf' - if not DELAY and MODELS[mod]['start'] == 12: + if (MODELS[mod]['start'] == 12 and not DELAY and DELAY_DATE and (datetime.strptime(self.currdate, "%Y%m%d") >= datetime.strptime(DELAY_DATE, "%Y%m%d"))) or \ + (MODELS[mod]['start'] == 12 and not DELAY and not DELAY_DATE): mod_date = (datetime.strptime(self.currdate, "%Y%m%d") - timedelta(days=1)).strftime("%Y%m%d") else: diff --git a/tabs/forecast.py b/tabs/forecast.py index 68ab1e6..c50f879 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -20,18 +20,10 @@ def get_forecast_days(curdate=END_DATE): """ Return forecast days according to configuration file """ delay = DELAY st_date = DELAY_DATE - if delay and st_date: - if dt.strptime(curdate, "%Y%m%d") >= dt.strptime(st_date, "%Y%m%d"): - days = 2 - else: - days = 3 - elif delay: + if (delay and st_date and (dt.strptime(curdate, "%Y%m%d") >= dt.strptime(st_date, "%Y%m%d"))) or \ + (not delay and st_date and dt.strptime(curdate, "%Y%m%d") < dt.strptime(st_date, "%Y%m%d")) or \ + (delay and not st_date): days = 2 - elif not delay and st_date: - if dt.strptime(curdate, "%Y%m%d") >= dt.strptime(st_date, "%Y%m%d"): - days = 3 - else: - days = 2 else: days = 3 diff --git a/tools.py b/tools.py index 56ab341..58da0d8 100644 --- a/tools.py +++ b/tools.py @@ -2,6 +2,10 @@ # -*- coding: utf-8 -*- """ Tools module with functions related to plots """ +from datetime import datetime as dt +from datetime import timedelta +import os + from data_handler import FigureHandler from data_handler import WasFigureHandler from data_handler import ProbFigureHandler @@ -14,10 +18,6 @@ from data_handler import DEBUG from data_handler import MODELS from data_handler import END_DATE, DELAY, DELAY_DATE -from datetime import datetime as dt -from datetime import timedelta -import os - def download_image_link(models, variable, curdate, tstep=0, anim=False): """ Generates links to animated gifs """ @@ -156,7 +156,9 @@ def get_figure(model=None, var=None, selected_date=END_DATE, tstep=0, if model: if DEBUG: print('SERVER: Figure init ... ') if model in MODELS and MODELS[model]['start'] == 12: - if DELAY: + if (DELAY and dt.strptime(selected_date, "%Y%m%d") >= dt.strptime(DELAY_DATE, "%Y%m%d")) or \ + (DELAY and not DELAY_DATE) or \ + (not DELAY and dt.strptime(selected_date, "%Y%m%d") < dt.strptime(DELAY_DATE, "%Y%m%d")): # OLD: for models that starts at 12h considering end_date = current_date - 1 if tstep < 4: selected_date = (dt.strptime(selected_date, -- GitLab From 1248af531dd13efc01668e3a19b06e71bdc2f201 Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Tue, 2 May 2023 18:57:40 +0200 Subject: [PATCH 02/10] Fixed date and tstep calculation in visualization, still missing in median calculation --- conf/models.json | 1 + preproc/median_calc.py | 3 +- tabs/forecast_callbacks.py | 15 ++--- tools.py | 131 ++++++++++++++++++++++--------------- utils.py | 32 ++++++++- 5 files changed, 118 insertions(+), 64 deletions(-) diff --git a/conf/models.json b/conf/models.json index 3f8ca50..f6f2046 100644 --- a/conf/models.json +++ b/conf/models.json @@ -5,6 +5,7 @@ "path": "/data/products/median", "color": "#303030", "start": 0, + "start_before": 12, "weight": 0 }, "monarch": { diff --git a/preproc/median_calc.py b/preproc/median_calc.py index 18d7778..55d7a78 100644 --- a/preproc/median_calc.py +++ b/preproc/median_calc.py @@ -29,13 +29,12 @@ NETCDF_TEMPLATE = "{}/archive/{}{}.nc" DEBUG = True DELAY = DATES['delay']['delayed'] +DELAY_DATE = DATES['delay']['date'] lonlat = "-27,65,0,65" main_output_path = "/data/products/median/" interpolated_path = os.path.join(main_output_path, "interpolated") -# archive_path = os.path.join(main_output_path, "tmp") archive_path = os.path.join(main_output_path, "archive") -# selected_date = "20220515" def generate_median_file(selected_date): diff --git a/tabs/forecast_callbacks.py b/tabs/forecast_callbacks.py index 97c73c5..299016d 100644 --- a/tabs/forecast_callbacks.py +++ b/tabs/forecast_callbacks.py @@ -219,7 +219,7 @@ def download_anim_link(models, variable, date, tstep): if variable is None or date is None or tstep is None: raise PreventUpdate - # from tools import get_figure + # from tools import get_models_figure from tools import download_image_link if DEBUG: print('GIF', models, variable, date) @@ -259,7 +259,6 @@ def update_was_timeslider(date): State({'tag': 'was-map', 'index': ALL}, 'center')], prevent_initial_call=False ) -@cache.memoize(timeout=cache_timeout) def update_was_figure(n_clicks, date, day, was, var, previous, view, zoom, center): """ Update Warning Advisory Systems maps """ if DEBUG: print('WAS', n_clicks, date, day, was, previous, view, zoom, center) @@ -269,7 +268,7 @@ def update_was_figure(n_clicks, date, day, was, var, previous, view, zoom, cente if button_id != 'was-apply' and date is None and day is None: raise PreventUpdate from tools import get_was_figure - from tools import get_figure + from tools import get_models_figure if not zoom or previous != was: zoom = WAS[was]['zoom'] else: @@ -299,7 +298,7 @@ def update_was_figure(n_clicks, date, day, was, var, previous, view, zoom, cente if was: view = list(STYLES.keys())[view.index(True)] geojson, legend, info = get_was_figure(was, day, selected_date=date) - fig = get_figure(model=None, var=var, layer=[geojson, legend, info], view=view, zoom=zoom, center=center, tag='was') + fig = get_models_figure(model=None, var=var, layer=[geojson, legend, info], view=view, zoom=zoom, center=center, tag='was') return fig, previous raise PreventUpdate @@ -334,7 +333,7 @@ def update_prob_timeslider(date): def update_prob_figure(n_clicks, date, day, prob, var, view, zoom, center): """ Update Probability maps """ from tools import get_prob_figure - from tools import get_figure + from tools import get_models_figure # if not prob in case user navigates to section via URL if not prob: @@ -369,7 +368,7 @@ def update_prob_figure(n_clicks, date, day, prob, var, view, zoom, center): prob = prob.replace('prob_', '') view = list(STYLES.keys())[view.index(True)] geojson, colorbar, info = get_prob_figure(var, prob, day, selected_date=date) - fig = get_figure(model=None, var=var, layer=[geojson, colorbar, info], view=view, zoom=zoom, center=center, tag='prob') + fig = get_models_figure(model=None, var=var, layer=[geojson, colorbar, info], view=view, zoom=zoom, center=center, tag='prob') if DEBUG: print("FIG", fig) return fig raise PreventUpdate @@ -817,7 +816,7 @@ def update_models_figure(n_clicks, tstep, date, model, variable, static, view, z elif tstep is None and date is None: raise PreventUpdate - from tools import get_figure + from tools import get_models_figure if DEBUG: print('SERVER: calling figure from picker callback') st_time = time.time() @@ -875,7 +874,7 @@ def update_models_figure(n_clicks, tstep, date, model, variable, static, view, z for mod, mod_zoom, mod_center in zip(model, zoom, center): if DEBUG: print("MOD", mod, "ZOOM", mod_zoom, "CENTER", mod_center, 'VIEW', view) - figure = get_figure(mod, variable, date, tstep, + figure = get_models_figure(mod, variable, date, tstep, static=static, aspect=(nrows, ncols), view=view, center=mod_center, zoom=mod_zoom) diff --git a/tools.py b/tools.py index 58da0d8..b5bfeab 100644 --- a/tools.py +++ b/tools.py @@ -17,27 +17,32 @@ from data_handler import Observations1dHandler from data_handler import DEBUG from data_handler import MODELS from data_handler import END_DATE, DELAY, DELAY_DATE - +from utils import get_currdate_tstep def download_image_link(models, variable, curdate, tstep=0, anim=False): """ Generates links to animated gifs """ - if DEBUG: print('CURRDIR', os.getcwd()) + if DEBUG: + print('CURRDIR', os.getcwd()) filepath = "assets/comparison/{model}/{variable}/{year}/{month}/{curdate}_{model}_{tstep}.{ext}" if len(models) == 1: model = models[0] - if DEBUG: print('DOWNLOAD MODELS', model) + if DEBUG: + print('DOWNLOAD MODELS', model) else: - if DEBUG: print('DOWNLOAD ALL MODELS') + if DEBUG: + print('DOWNLOAD ALL MODELS') model = "all" if anim: tstep = "loop" ext = "gif" - if DEBUG: print('DOWNLOAD LOOP') + if DEBUG: + print('DOWNLOAD LOOP') else: tstep = "%02d" % tstep ext = "png" - if DEBUG: print('DOWNLOAD PNG', tstep) + if DEBUG: + print('DOWNLOAD PNG', tstep) filename = filepath.format( model=model, @@ -48,31 +53,38 @@ def download_image_link(models, variable, curdate, tstep=0, anim=False): tstep=tstep, ext=ext ) - if DEBUG: print('DOWNLOAD FILENAME', filename) + if DEBUG: + print('DOWNLOAD FILENAME', filename) return filename def get_eval_timeseries(obs, start_date, end_date, var, idx, name, model): """ Retrieve timeseries """ - if DEBUG: print('SERVER: OBS TS init for obs {} ... '.format(str(obs))) + if DEBUG: + print('SERVER: OBS TS init for obs {} ... '.format(str(obs))) th = ObsTimeSeriesHandler(obs, start_date, end_date, var) - if DEBUG: print('SERVER: OBS TS generation ... ') + if DEBUG: + print('SERVER: OBS TS generation ... ') return th.retrieve_timeseries(idx, name, model) def get_timeseries(model, date, var, lat, lon, forecast=False): """ Retrieve timeseries """ - if DEBUG: print('SERVER: TS init for models {} ... '.format(str(model))) + if DEBUG: + print('SERVER: TS init for models {} ... '.format(str(model))) th = TimeSeriesHandler(model, date, var) - if DEBUG: print('SERVER: TS generation ... ') + if DEBUG: + print('SERVER: TS generation ... ') return th.retrieve_timeseries(lat, lon, method='feather', forecast=forecast) def get_single_point(model, date, tstep, var, lat, lon): """ Retrieve sigle point """ - if DEBUG: print('SERVER: SINGLE POINT init for models {} ... '.format(str(model))) + if DEBUG: + print('SERVER: SINGLE POINT init for models {} ... '.format(str(model))) th = TimeSeriesHandler(model, date, var) - if DEBUG: print('SERVER: SINGLE POINT generation ... ') + if DEBUG: + print('SERVER: SINGLE POINT generation ... ') return th.retrieve_single_point(tstep, lat, lon) @@ -90,94 +102,107 @@ def get_scores_figure(network, model, statistic, selection=END_DATE): def get_prob_figure(var, prob=None, day=0, selected_date=END_DATE): """ Retrieve figure """ - if DEBUG: print(prob, day, selected_date) + if DEBUG: + print(prob, day, selected_date) try: selected_date = dt.strptime( selected_date, "%Y-%m-%d").strftime("%Y%m%d") except: pass - if DEBUG: print(prob, day, selected_date) + if DEBUG: + print(prob, day, selected_date) if prob: - if DEBUG: print('SERVER: PROB Figure init ... ') + if DEBUG: + print('SERVER: PROB Figure init ... ') fh = ProbFigureHandler(var=var, prob=prob, selected_date=selected_date) - if DEBUG: print('SERVER: PROB Figure generation ... ') + if DEBUG: + print('SERVER: PROB Figure generation ... ') return fh.retrieve_var_tstep(day=day) - if DEBUG: print('SERVER: NO PROB Figure') + if DEBUG: + print('SERVER: NO PROB Figure') return ProbFigureHandler().retrieve_var_tstep() def get_was_figure(was=None, day=0, selected_date=END_DATE): """ Retrieve figure """ - if DEBUG: print(was, day, selected_date) + if DEBUG: + print(was, day, selected_date) try: selected_date = dt.strptime( selected_date, "%Y-%m-%d").strftime("%Y%m%d") except: pass - if DEBUG: print(was, day, selected_date) + if DEBUG: + print(was, day, selected_date) if was: - if DEBUG: print('SERVER: WAS Figure init ... ') + if DEBUG: + print('SERVER: WAS Figure init ... ') fh = WasFigureHandler(was=was, selected_date=selected_date) - if DEBUG: print('SERVER: WAS Figure generation ... ') + if DEBUG: + print('SERVER: WAS Figure generation ... ') return fh.retrieve_var_tstep(day=day) - if DEBUG: print('SERVER: NO WAS Figure') + if DEBUG: + print('SERVER: NO WAS Figure') return WasFigureHandler().retrieve_var_tstep() def get_vis_figure(tstep=0, selected_date=END_DATE): """ Retrieve figure """ - if DEBUG: print(tstep, selected_date) + if DEBUG: + print(tstep, selected_date) try: selected_date = dt.strptime( selected_date, "%Y-%m-%d").strftime("%Y%m%d") except: pass - if DEBUG: print(tstep, selected_date) + if DEBUG: + print(tstep, selected_date) if tstep is not None: - if DEBUG: print('SERVER: VIS Figure init ... ') + if DEBUG: + print('SERVER: VIS Figure init ... ') fh = VisFigureHandler(selected_date=selected_date) - if DEBUG: print('SERVER: VIS Figure generation ... ') + if DEBUG: + print('SERVER: VIS Figure generation ... ') return fh.retrieve_var_tstep(tstep=tstep) - if DEBUG: print('SERVER: NO VIS Figure') + if DEBUG: + print('SERVER: NO VIS Figure') return VisFigureHandler().retrieve_var_tstep() -def get_figure(model=None, var=None, selected_date=END_DATE, tstep=0, +def get_models_figure(model=None, var=None, selected_date=END_DATE, tstep=0, hour=None, static=True, aspect=(1, 1), center=None, view='carto-positron', zoom=None, layer=None, tag='empty'): """ Retrieve figure """ - if DEBUG: print("***", model, var, selected_date, tstep, hour, "***") + if DEBUG: + print("***", model, var, selected_date, tstep, hour, "***") try: selected_date = dt.strptime( selected_date, "%Y-%m-%d %H:%M:%S").strftime("%Y%m%d") except: pass - if model: - if DEBUG: print('SERVER: Figure init ... ') - if model in MODELS and MODELS[model]['start'] == 12: - if (DELAY and dt.strptime(selected_date, "%Y%m%d") >= dt.strptime(DELAY_DATE, "%Y%m%d")) or \ - (DELAY and not DELAY_DATE) or \ - (not DELAY and dt.strptime(selected_date, "%Y%m%d") < dt.strptime(DELAY_DATE, "%Y%m%d")): - # OLD: for models that starts at 12h considering end_date = current_date - 1 - if tstep < 4: - selected_date = (dt.strptime(selected_date, - "%Y%m%d") - - timedelta(days=1)).strftime("%Y%m%d") - tstep = int(tstep) + 4 - else: - tstep = int(tstep) - 4 - else: - # NEW: for models that starts at 12h considering end_date = current_date - selected_date = (dt.strptime(selected_date, - "%Y%m%d") - - timedelta(days=1)).strftime("%Y%m%d") - tstep = int(tstep) + 4 - - if DEBUG: print('SERVER: Figure generation ... ') + if model in MODELS: + model_start = MODELS[model]['start'] + model_start_before = ('start_before' in MODELS[model]) and MODELS[model]['start_before'] or False + current_time_before = (DELAY_DATE and dt.strptime(selected_date, "%Y%m%d") < dt.strptime(DELAY_DATE, "%Y%m%d")) + if DEBUG: + print(f""" +************************ SERVER: Figure init ********************* +* DELAY: {DELAY}, DELAY_DATE: {DELAY_DATE}, SELECTED DATE: {selected_date}, CURR_BEFORE: {current_time_before} * +* MODEL: {model}, MODEL_START: {model_start}, MODEL_START_DELAYED: {model_start_before} * +****************************************************************** + """) + # If current date is later than the delay date and the model_start is 12 + # or current date is before than the delay date and the model_start + selected_date, tstep, _, _ = get_currdate_tstep(model_start, model_start_before, current_time_before, DELAY, selected_date, tstep) + + if DEBUG: + print('***** SERVER: Figure generation: CURR_DATE', selected_date, 'TSTEP', tstep, '*****') + # return True fh = FigureHandler(model, selected_date) return fh.retrieve_var_tstep(var, tstep, hour, static, aspect, center, view, zoom, layer, tag) - if DEBUG: print('SERVER: No Figure') + if DEBUG: + print('SERVER: No Figure') return FigureHandler().retrieve_var_tstep(layer=layer, center=center, selected_tiles=view, zoom=zoom, tag=tag) diff --git a/utils.py b/utils.py index 13ddd31..da1567a 100644 --- a/utils.py +++ b/utils.py @@ -206,4 +206,34 @@ def get_vis_edate(end_date, hour=None): if curr is not None: return curr.strftime(fmt_date), curr.hour - return cdate, edate.hour + return cdate, edate.hour + +def get_currdate_tstep(model_start, model_start_before, current_time_before, delay, selected_date, tstep): + """ Returns date and timestep """ + + median_start_hour = "00" + cdo_tsteps = "1/25" + cdo_date = selected_date + + if (not current_time_before and model_start == 12) or \ + (current_time_before and (model_start_before == 12 or \ + (not model_start_before and model_start == 12))): + if (current_time_before and not delay): + print("DELAYED: 2 days forecast!") + # DELAYED (2 days): models that starts at 12h considering end_date = current_date - 1 + if tstep < 4: + selected_date = (datetime.strptime(selected_date, + "%Y%m%d") - + timedelta(days=1)).strftime("%Y%m%d") + tstep = int(tstep) + 4 + else: + tstep = int(tstep) - 4 + else: + print("NOT DELAYED: 3 days forecast!") + # NOT DELAYED (3 days): models that starts at 12h considering end_date = current_date + selected_date = (datetime.strptime(selected_date, + "%Y%m%d") - + timedelta(days=1)).strftime("%Y%m%d") + tstep = int(tstep) + 4 + + return selected_date, tstep, median_start_hour, cdo_tsteps -- GitLab From c659432046d5381b1d8c63a390047bdd10cd4d7d Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Wed, 3 May 2023 01:48:02 +0200 Subject: [PATCH 03/10] Added function get_currdate_tstep to generalize --- preproc/median_calc.py | 77 ++++++++++++++++++++++++------------------ utils.py | 24 ++++++++----- 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/preproc/median_calc.py b/preproc/median_calc.py index 55d7a78..8e4efcf 100644 --- a/preproc/median_calc.py +++ b/preproc/median_calc.py @@ -18,7 +18,6 @@ import subprocess import time from datetime import datetime from datetime import timedelta -from operator import itemgetter np.set_printoptions(precision=2) @@ -29,7 +28,7 @@ NETCDF_TEMPLATE = "{}/archive/{}{}.nc" DEBUG = True DELAY = DATES['delay']['delayed'] -DELAY_DATE = DATES['delay']['date'] +DELAY_DATE = DATES['delay']['start_date'] lonlat = "-27,65,0,65" main_output_path = "/data/products/median/" @@ -40,33 +39,35 @@ archive_path = os.path.join(main_output_path, "archive") def generate_median_file(selected_date): """ Generates the median of stored data models """ - model_conf = { - True: { - 0: { - 'tsteps': "5/25", - 'model_date': selected_date, - 'start_hour': "12" - }, - 12: { - 'tsteps': "1/21", - 'model_date': selected_date, - 'start_hour': "12" - }, - }, - False: { - 0: { - 'tsteps': "1/25", - 'model_date': selected_date, - 'start_hour': "00" - }, - 12: { - 'tsteps': "5/29", - 'model_date': (datetime.strptime(selected_date, "%Y%m%d") - - timedelta(days=1)).strftime("%Y%m%d"), - 'start_hour': "00" - }, - } - } +# model_conf = { +# True: { +# 0: { +# 'tsteps': "5/25", +# 'model_date': selected_date, +# 'start_hour': "12" +# }, +# 12: { +# 'tsteps': "1/21", +# 'model_date': selected_date, +# 'start_hour': "12" +# }, +# }, +# False: { +# 0: { +# 'tsteps': "1/25", +# 'model_date': selected_date, +# 'start_hour': "00" +# }, +# 12: { +# 'tsteps': "5/29", +# 'model_date': (datetime.strptime(selected_date, "%Y%m%d") - +# timedelta(days=1)).strftime("%Y%m%d"), +# 'start_hour': "00" +# }, +# } +# } + + from utils import get_currdate_tstep filepaths = [] cdo_date = datetime.strptime(selected_date, "%Y%m%d").strftime("%Y-%m-%d") @@ -74,10 +75,17 @@ def generate_median_file(selected_date): print("CDO DATE", cdo_date) for model in MODELS: + if DEBUG: + print("MODEL", model) model_start = MODELS[model]['start'] - cur_dict = model_conf[DELAY][model_start] - tsteps, model_date, start_hour = itemgetter(*cur_dict.keys())(cur_dict) + model_start_before = ('start_before' in MODELS[model]) and MODELS[model]['start_before'] or False + current_time_before = (DELAY_DATE and datetime.strptime(selected_date, "%Y%m%d") < datetime.strptime(DELAY_DATE, "%Y%m%d")) + model_date, _, start_hour, tsteps = get_currdate_tstep(model_start, model_start_before, current_time_before, DELAY, selected_date) + print(f""" + ******************************* + {model_date}, {start_hour}, {tsteps} + """) filepath_interp = NETCDF_TEMPLATE.format( MODELS[model]['path'], @@ -122,6 +130,7 @@ def generate_median_file(selected_date): filepaths.append(interp_filepath) + median_start_hour = "{:02d}".format(current_time_before and MODELS['median']['start_before'] or MODELS['median']['start']) sconc_ds = xr.open_mfdataset( "{}/{}*SCONC_DUST.nc".format(interpolated_path, selected_date), concat_dim='model', combine='nested') @@ -131,14 +140,14 @@ def generate_median_file(selected_date): sconc_dust = sconc_ds['SCONC_DUST'].median(dim='model', skipna=True, keep_attrs=True) od550_dust = od550_ds['OD550_DUST'].median(dim='model', skipna=True, keep_attrs=True) newds = xr.Dataset({ 'OD550_DUST': od550_dust, 'SCONC_DUST': sconc_dust }).astype(np.float32) - print(newds) + print(newds, median_start_hour) newds = newds.rename_dims( {'lon': 'longitude', 'lat': 'latitude'}).rename_vars( {'lon': 'longitude', 'lat': 'latitude'}) newds['longitude'] = newds['longitude'].astype(np.float32) newds['latitude'] = newds['latitude'].astype(np.float32) newds.to_netcdf('{}/{}_3H_MEDIAN.nc'.format(archive_path, selected_date), - encoding={ 'time' : { 'units' : 'hours since '+cdo_date+' 00:00:00' } }) + encoding={ 'time' : { 'units' : 'hours since '+cdo_date+' '+median_start_hour+':00:00' } }) # clean interpolated directory for fname in filepaths: @@ -148,6 +157,8 @@ def generate_median_file(selected_date): if __name__ == "__main__": import sys + from os import path + sys.path.append(os.path.dirname(os.path.abspath('.'))) if len(sys.argv) > 1: generate_median_file(sys.argv[1]) else: diff --git a/utils.py b/utils.py index da1567a..f71fe3b 100644 --- a/utils.py +++ b/utils.py @@ -208,32 +208,40 @@ def get_vis_edate(end_date, hour=None): return cdate, edate.hour -def get_currdate_tstep(model_start, model_start_before, current_time_before, delay, selected_date, tstep): + +def get_currdate_tstep(model_start, model_start_before, current_time_before, delay, selected_date, tstep=4): """ Returns date and timestep """ + # MODELS starting at 00 with 3 days of forecast median_start_hour = "00" cdo_tsteps = "1/25" - cdo_date = selected_date + # MODELS not starting at 00 if (not current_time_before and model_start == 12) or \ (current_time_before and (model_start_before == 12 or \ - (not model_start_before and model_start == 12))): - if (current_time_before and not delay): + (not model_start_before and model_start == 12))): + if (current_time_before and not delay) or (not current_time_before and delay): print("DELAYED: 2 days forecast!") # DELAYED (2 days): models that starts at 12h considering end_date = current_date - 1 if tstep < 4: - selected_date = (datetime.strptime(selected_date, - "%Y%m%d") - + selected_date = (datetime.strptime(selected_date, "%Y%m%d") - timedelta(days=1)).strftime("%Y%m%d") tstep = int(tstep) + 4 else: tstep = int(tstep) - 4 + median_start_hour = "12" + cdo_tsteps = "1/21" else: print("NOT DELAYED: 3 days forecast!") # NOT DELAYED (3 days): models that starts at 12h considering end_date = current_date - selected_date = (datetime.strptime(selected_date, - "%Y%m%d") - + selected_date = (datetime.strptime(selected_date, "%Y%m%d") - timedelta(days=1)).strftime("%Y%m%d") tstep = int(tstep) + 4 + median_start_hour = "00" + cdo_tsteps = "5/29" + # MODELS starting at 00 with 2 days of forecast + elif delay: + median_start_hour = "12" + cdo_tsteps = "5/25" return selected_date, tstep, median_start_hour, cdo_tsteps -- GitLab From 505e5d83f222fb8423b77b3e186976290ebda231 Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Wed, 3 May 2023 17:15:47 +0200 Subject: [PATCH 04/10] Fixed dates management for median calculation and forecast visualization. Missing checking dates of was and probability --- preproc/median_calc.py | 49 ++++++++++++------------------------------ tools.py | 2 +- utils.py | 22 +++++++++---------- 3 files changed, 25 insertions(+), 48 deletions(-) diff --git a/preproc/median_calc.py b/preproc/median_calc.py index 8e4efcf..48de4f2 100644 --- a/preproc/median_calc.py +++ b/preproc/median_calc.py @@ -39,38 +39,15 @@ archive_path = os.path.join(main_output_path, "archive") def generate_median_file(selected_date): """ Generates the median of stored data models """ -# model_conf = { -# True: { -# 0: { -# 'tsteps': "5/25", -# 'model_date': selected_date, -# 'start_hour': "12" -# }, -# 12: { -# 'tsteps': "1/21", -# 'model_date': selected_date, -# 'start_hour': "12" -# }, -# }, -# False: { -# 0: { -# 'tsteps': "1/25", -# 'model_date': selected_date, -# 'start_hour': "00" -# }, -# 12: { -# 'tsteps': "5/29", -# 'model_date': (datetime.strptime(selected_date, "%Y%m%d") - -# timedelta(days=1)).strftime("%Y%m%d"), -# 'start_hour': "00" -# }, -# } -# } - from utils import get_currdate_tstep filepaths = [] cdo_date = datetime.strptime(selected_date, "%Y%m%d").strftime("%Y-%m-%d") + current_time_before = (DELAY_DATE and datetime.strptime(selected_date, + "%Y%m%d") < datetime.strptime(DELAY_DATE, "%Y%m%d")) + start_hour = ((not current_time_before and DELAY) or (current_time_before + and not DELAY)) and '12' or '00' + if DEBUG: print("CDO DATE", cdo_date) @@ -80,8 +57,11 @@ def generate_median_file(selected_date): model_start = MODELS[model]['start'] model_start_before = ('start_before' in MODELS[model]) and MODELS[model]['start_before'] or False - current_time_before = (DELAY_DATE and datetime.strptime(selected_date, "%Y%m%d") < datetime.strptime(DELAY_DATE, "%Y%m%d")) - model_date, _, start_hour, tsteps = get_currdate_tstep(model_start, model_start_before, current_time_before, DELAY, selected_date) + print(f""" + ******************************* + START: {model_start}, BEFORE: {model_start_before}, CURR_BEFORE: {current_time_before} + """) + model_date, _, tsteps = get_currdate_tstep(model_start, model_start_before, current_time_before, DELAY, selected_date) print(f""" ******************************* {model_date}, {start_hour}, {tsteps} @@ -105,8 +85,7 @@ def generate_median_file(selected_date): continue if DEBUG: - print('MODEL', model, filepath, model_date, filepath_interp, selected_date) - + print('MODEL', model, filepath, filepath_interp, model_date, selected_date) remap_script = "cdo -L -r -settaxis," +\ cdo_date + "," + start_hour + ":00:00,3hours" +\ @@ -130,7 +109,7 @@ def generate_median_file(selected_date): filepaths.append(interp_filepath) - median_start_hour = "{:02d}".format(current_time_before and MODELS['median']['start_before'] or MODELS['median']['start']) + # median_start_hour = "{:02d}".format(current_time_before and MODELS['median']['start_before'] or MODELS['median']['start']) sconc_ds = xr.open_mfdataset( "{}/{}*SCONC_DUST.nc".format(interpolated_path, selected_date), concat_dim='model', combine='nested') @@ -140,14 +119,14 @@ def generate_median_file(selected_date): sconc_dust = sconc_ds['SCONC_DUST'].median(dim='model', skipna=True, keep_attrs=True) od550_dust = od550_ds['OD550_DUST'].median(dim='model', skipna=True, keep_attrs=True) newds = xr.Dataset({ 'OD550_DUST': od550_dust, 'SCONC_DUST': sconc_dust }).astype(np.float32) - print(newds, median_start_hour) + print(newds) newds = newds.rename_dims( {'lon': 'longitude', 'lat': 'latitude'}).rename_vars( {'lon': 'longitude', 'lat': 'latitude'}) newds['longitude'] = newds['longitude'].astype(np.float32) newds['latitude'] = newds['latitude'].astype(np.float32) newds.to_netcdf('{}/{}_3H_MEDIAN.nc'.format(archive_path, selected_date), - encoding={ 'time' : { 'units' : 'hours since '+cdo_date+' '+median_start_hour+':00:00' } }) + encoding={ 'time' : { 'units' : 'hours since '+cdo_date+' 00:00:00' } }) # clean interpolated directory for fname in filepaths: diff --git a/tools.py b/tools.py index b5bfeab..2df73cb 100644 --- a/tools.py +++ b/tools.py @@ -194,7 +194,7 @@ def get_models_figure(model=None, var=None, selected_date=END_DATE, tstep=0, """) # If current date is later than the delay date and the model_start is 12 # or current date is before than the delay date and the model_start - selected_date, tstep, _, _ = get_currdate_tstep(model_start, model_start_before, current_time_before, DELAY, selected_date, tstep) + selected_date, tstep, _ = get_currdate_tstep(model_start, model_start_before, current_time_before, DELAY, selected_date, tstep) if DEBUG: print('***** SERVER: Figure generation: CURR_DATE', selected_date, 'TSTEP', tstep, '*****') diff --git a/utils.py b/utils.py index f71fe3b..81aa703 100644 --- a/utils.py +++ b/utils.py @@ -213,15 +213,15 @@ def get_currdate_tstep(model_start, model_start_before, current_time_before, del """ Returns date and timestep """ # MODELS starting at 00 with 3 days of forecast - median_start_hour = "00" + print("Starting at 0 and NOT DELAYED: 3 days forecast!") cdo_tsteps = "1/25" + delayed = (current_time_before and not delay) or (not current_time_before and delay) # MODELS not starting at 00 - if (not current_time_before and model_start == 12) or \ - (current_time_before and (model_start_before == 12 or \ - (not model_start_before and model_start == 12))): - if (current_time_before and not delay) or (not current_time_before and delay): - print("DELAYED: 2 days forecast!") + if (model_start == 12 and not model_start_before) or \ + (current_time_before and model_start_before == 12): + if delayed: + print("Starting at 12 and DELAYED: 2 days forecast!") # DELAYED (2 days): models that starts at 12h considering end_date = current_date - 1 if tstep < 4: selected_date = (datetime.strptime(selected_date, "%Y%m%d") - @@ -229,19 +229,17 @@ def get_currdate_tstep(model_start, model_start_before, current_time_before, del tstep = int(tstep) + 4 else: tstep = int(tstep) - 4 - median_start_hour = "12" cdo_tsteps = "1/21" else: - print("NOT DELAYED: 3 days forecast!") + print("Starting at 12 and NOT DELAYED: 3 days forecast!") # NOT DELAYED (3 days): models that starts at 12h considering end_date = current_date selected_date = (datetime.strptime(selected_date, "%Y%m%d") - timedelta(days=1)).strftime("%Y%m%d") tstep = int(tstep) + 4 - median_start_hour = "00" cdo_tsteps = "5/29" # MODELS starting at 00 with 2 days of forecast - elif delay: - median_start_hour = "12" + elif delayed: + print("Starting at 0 and DELAYED: 2 days forecast!") cdo_tsteps = "5/25" - return selected_date, tstep, median_start_hour, cdo_tsteps + return selected_date, tstep, cdo_tsteps -- GitLab From ec0878de4088e816004fae564c95b8e5b91f56d6 Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Thu, 4 May 2023 12:30:44 +0200 Subject: [PATCH 05/10] Updated some get_figure function to the new get_models_function and tests --- tabs/evaluation_callbacks.py | 18 +++++++++--------- tabs/observations_callbacks.py | 4 ++-- tests/test_forecast_callbacks.py | 4 ++-- tests/test_tools.py | 16 +++++----------- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/tabs/evaluation_callbacks.py b/tabs/evaluation_callbacks.py index d70c6e4..7a5b116 100644 --- a/tabs/evaluation_callbacks.py +++ b/tabs/evaluation_callbacks.py @@ -698,7 +698,7 @@ def update_eval_aeronet(n_clicks, sdate, edate, obs): if sdate is None or edate is None or obs != 'aeronet': raise PreventUpdate - from tools import get_figure + from tools import get_models_figure from tools import get_obs1d if DEBUG: print('SERVER: calling figure from EVAL picker callback') if DEBUG: print('SERVER: SDATE', str(sdate)) @@ -726,7 +726,7 @@ def update_eval_aeronet(n_clicks, sdate, edate, obs): edate = END_DATE stations, points_layer = get_obs1d(sdate, edate, obs, DEFAULT_VAR) - fig = get_figure(model=None, var=DEFAULT_VAR, layer=points_layer) + fig = get_models_figure(model=None, var=DEFAULT_VAR, layer=points_layer) return stations.to_dict(), fig @@ -754,7 +754,7 @@ def update_eval_modis(n_clicks, date, mod, obs, mod_div): if date is None or mod is None or obs != 'modis': raise PreventUpdate - from tools import get_figure + from tools import get_models_figure if DEBUG: print('SERVER: calling figure from EVAL picker callback') if DEBUG: print(mod_div) mod_center = mod_div['props']['center'] @@ -778,9 +778,9 @@ def update_eval_modis(n_clicks, date, mod, obs, mod_div): tstep = 4 else: tstep = 0 - fig_mod = get_figure(model=mod, var=DEFAULT_VAR, selected_date=date, tstep=tstep, + fig_mod = get_models_figure(model=mod, var=DEFAULT_VAR, selected_date=date, tstep=tstep, hour=12, center=mod_center, zoom=mod_zoom) - fig_obs = get_figure(model=obs, var=DEFAULT_VAR, selected_date=date, tstep=0, + fig_obs = get_models_figure(model=obs, var=DEFAULT_VAR, selected_date=date, tstep=0, center=mod_center, zoom=mod_zoom, tag='modis') if DEBUG: print("MODIS", fig_obs) @@ -797,7 +797,7 @@ def update_eval_modis(n_clicks, date, mod, obs, mod_div): @cache.memoize(timeout=cache_timeout) def update_eval(obs): """ Update evaluation figure according to all parameters """ - from tools import get_figure + from tools import get_models_figure # from tools import get_obs1d if DEBUG: print('SERVER: calling figure from EVAL picker callback') # if DEBUG: print('SERVER: interval ' + str(n)) @@ -820,7 +820,7 @@ def update_eval(obs): eval_graph = html.Div([ html.Div( - get_figure(), + get_models_figure(), id='graph-eval-aeronet' ), html.Div( @@ -846,8 +846,8 @@ def update_eval(obs): # with_portal=True, )] - fig_mod = get_figure() - fig_obs = get_figure(tag='modis') + fig_mod = get_models_figure() + fig_obs = get_models_figure(tag='modis') graph_obs = html.Div([ html.Div( diff --git a/tabs/observations_callbacks.py b/tabs/observations_callbacks.py index 30b0500..a540e32 100644 --- a/tabs/observations_callbacks.py +++ b/tabs/observations_callbacks.py @@ -255,7 +255,7 @@ def update_obs_slider(n): @cache.memoize(timeout=cache_timeout) def update_vis_figure(date, tstep, zoom, center): from tools import get_vis_figure - from tools import get_figure + from tools import get_models_figure if DEBUG: print("*************", date, tstep, zoom, center) if date is not None: date = date.split(' ')[0] @@ -281,5 +281,5 @@ def update_vis_figure(date, tstep, zoom, center): if DEBUG: print('SERVER: VIS callback date {}, tstep {}'.format(date, tstep)) df, points_layer = get_vis_figure(tstep=tstep, selected_date=date) if DEBUG: print("POINTS LAYER", points_layer) - fig = get_figure(model=None, var=None, layer=points_layer, zoom=zoom, center=center, tag='obs-vis') + fig = get_models_figure(model=None, var=None, layer=points_layer, zoom=zoom, center=center, tag='obs-vis') return fig diff --git a/tests/test_forecast_callbacks.py b/tests/test_forecast_callbacks.py index 34fb246..bd60063 100644 --- a/tests/test_forecast_callbacks.py +++ b/tests/test_forecast_callbacks.py @@ -227,7 +227,7 @@ def test_update_slider(): def test_update_was_figure(): def run_callback(): context_value.set(AttributeDict(**{"triggered_inputs": [{"prop_id": "was-apply.n_clicks"},{"prop_id": "was-date-picker.date"},{"prop_id": "was-slider-graph.value"},{"prop_id": "was-dropdown.value"},{"prop_id": "variable-dropdown-forecast.value"},{"prop_id": "was-previous.data"},{"prop_id": "view-style.active"},{"prop_id": "was-map.zoom"},{"prop_id": "was-map.center"}]})) - return code.update_was_figure.uncached(1, '20230404', 1, 'burkinafaso', None, [True, False, False, False], [True], [], []) + return code.update_was_figure(1, '20230404', 1, 'burkinafaso', None, [True, False, False, False], [True], [], []) ctx = copy_context() output = ctx.run(run_callback) @@ -236,7 +236,7 @@ def test_update_was_figure(): def test_update_was_figure_zooms(): def run_callback(): context_value.set(AttributeDict(**{"triggered_inputs": [{"prop_id": "was-apply.n_clicks"},{"prop_id": "was-date-picker.date"},{"prop_id": "was-slider-graph.value"},{"prop_id": "was-dropdown.value"},{"prop_id": "variable-dropdown-forecast.value"},{"prop_id": "was-previous.data"},{"prop_id": "view-style.active"},{"prop_id": "was-map.zoom"},{"prop_id": "was-map.center"}]})) - return code.update_was_figure.uncached(2, '20230404', 1, 'cabo_verde', 'burkinafaso', [True, False, False, False],[True], [8], [[11.982397942974229, -2.6312255859375004]]) + return code.update_was_figure(2, '20230404', 1, 'cabo_verde', 'burkinafaso', [True, False, False, False],[True], [8], [[11.982397942974229, -2.6312255859375004]]) ctx = copy_context() output = ctx.run(run_callback) diff --git a/tests/test_tools.py b/tests/test_tools.py index bacf932..1bf7150 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -45,20 +45,14 @@ def test_get_vis_figure(): assert result in run1 assert result2 in run2 -def test_get_figure(): - result = "/dashboard/assets/geojsons/median/geojson/20220808/00_20220808_OD550_DUST.geojson" - run1 = str(code.get_figure(model='median', var='OD550_DUST', selected_date='20220808', tstep=0, - hour=3, static=True, aspect=(1, 1), center=None, - view='carto-positron', zoom=None, layer=None, tag='empty').children[2].url) +def test_get_models_figure(): + result = "/dashboard/assets/geojsons/median/geojson/20230408/00_20230408_OD550_DUST.geojson" + run1 = str(code.get_models_figure(model='median', var='OD550_DUST', + selected_date='20230408', tstep=0).children[2].url) assert result in run1 result2 = "{'tag': 'model-tile-layer', 'index': 'monarch'}" - run2 = str(code.get_figure(model='monarch', var='SCONC_DUST', selected_date='20220809', tstep=1, + run2 = str(code.get_models_figure(model='monarch', var='SCONC_DUST', selected_date='20220809', tstep=1, hour=3, static=True, aspect=(1, 1), center=None, view='carto-positron', zoom=None, layer=None, tag='empty').children[0].id) assert result2 in run2 - - - - - -- GitLab From a2f96dee1040d7c758845b14d3f2df6dee995cc9 Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Thu, 4 May 2023 15:51:25 +0200 Subject: [PATCH 06/10] Fixed was and prob time slider days --- tabs/forecast.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tabs/forecast.py b/tabs/forecast.py index c50f879..2fb62d0 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -23,14 +23,14 @@ def get_forecast_days(curdate=END_DATE): if (delay and st_date and (dt.strptime(curdate, "%Y%m%d") >= dt.strptime(st_date, "%Y%m%d"))) or \ (not delay and st_date and dt.strptime(curdate, "%Y%m%d") < dt.strptime(st_date, "%Y%m%d")) or \ (delay and not st_date): - days = 2 + st_day = 1 else: - days = 3 + st_day = 0 return [ (dt.strptime(curdate, "%Y%m%d") + timedelta(days=idx)).strftime("%a %d").upper() - for idx in range(days) + for idx in range(st_day, 3) ] def gen_ts_marks(ts_type, tstep, ts_min, curdate=END_DATE): -- GitLab From b090b1544fa738a2a75ebed6ca2884a68bbf6e61 Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Fri, 5 May 2023 16:52:15 +0200 Subject: [PATCH 07/10] Fixed values generation for was and prob time slider. Still missing to fix was and prob generation to cover all cases --- data_handler.py | 19 ++++---- preproc/nc2geojson_was.py | 3 +- preproc/probability_maps.py | 13 +++--- tabs/forecast.py | 86 +++++++++++++++++++------------------ 4 files changed, 63 insertions(+), 58 deletions(-) diff --git a/data_handler.py b/data_handler.py index fc68724..8f22775 100644 --- a/data_handler.py +++ b/data_handler.py @@ -200,7 +200,7 @@ class Observations1dHandler(object): ), hideout=dict( circleOptions=dict( - fillOpacity=0.7, + fillOpacity=OPACITY, stroke=False, fillColor='#f0b450', radius=8), @@ -712,7 +712,7 @@ class FigureHandler(object): varname))) if DEBUG: print("MODEL", self.model, "GEOJSON_URL", geojson_url) - style = dict(weight=0, opacity=0, color='white', dashArray='', fillOpacity=0.7) + style = dict(weight=0, opacity=0, color='white', dashArray='', fillOpacity=OPACITY) # Create colorbar. ctg = ["{:d}".format(int(cls)) if cls.as_integer_ratio()[1] == 1 else "{:.1f}".format(cls) for i, cls in enumerate(bounds[1:-1])] @@ -868,7 +868,7 @@ class FigureHandler(object): name=name, hovertemplate="lon: %{lon:.2f}
lat: %{lat:.2f}
" + "value: %{text:.2f}", - opacity=0.7, + opacity=OPACITY, showlegend=False, marker=dict( # autocolorscale=True, @@ -1307,7 +1307,8 @@ class VisFigureHandler(object): className="vis-legend" ) - if DEBUG: print('VIS ___', xlon, ylat, '\n*********', visibility, '\n*********', humidity) + if DEBUG: + print('VIS ___', xlon, ylat, '\n*********', visibility, '\n*********', humidity) df = pd.DataFrame({ 'lon': np.array(xlon).round(2), 'lat': np.array(ylat).round(2), @@ -1343,7 +1344,7 @@ class VisFigureHandler(object): colorProp='value', colorscale=self.colors, circleOptions=dict( - fillOpacity=0.7, + fillOpacity=OPACITY, stroke=False, #fillColor='#f0b450', radius=8), @@ -1389,7 +1390,7 @@ class ProbFigureHandler(object): """ Class to manage the figure creation """ def __init__(self, var=None, prob=None, selected_date=None): - """ """ + """ Initialization with variable, prob and date """ if var is None: var = DEFAULT_VAR @@ -1487,7 +1488,7 @@ class ProbFigureHandler(object): if DEBUG: print("GEOJSON_URL", geojson_url) - style = dict(weight=0, opacity=0, color='white', dashArray='', fillOpacity=0.7) + style = dict(weight=0, opacity=0, color='white', dashArray='', fillOpacity=OPACITY) # Create colorbar. ctg = ["{:.1f}".format(cls) if '.' in str(cls) else "{:d}".format(cls) @@ -1684,7 +1685,7 @@ class WasFigureHandler(object): names, colors, definitions = self.get_regions_data(day=day) colors = np.array(colors) if DEBUG: print("::::::::::", names, colors, definitions) - style = dict(weight=1, opacity=1, color='white', dashArray='3', fillOpacity=0.7) + style = dict(weight=1, opacity=1, color='white', dashArray='3', fillOpacity=OPACITY) # Create colorbar. colormap = WAS[self.was]['colors'] @@ -1723,7 +1724,7 @@ class WasFigureHandler(object): url=self.get_geojson_url(day=day), # data=geojson_data, # zoomToBounds=True, - hoverStyle=arrow_function(dict(weight=2, color='white', dashArray='', fillOpacity=0.7)), + hoverStyle=arrow_function(dict(weight=2, color='white', dashArray='', fillOpacity=OPACITY)), options=dict(style=style_handle), hideout=dict(colorscale=list(colormap.keys()), bounds=[i for i in range(len(colormap.keys()))], diff --git a/preproc/nc2geojson_was.py b/preproc/nc2geojson_was.py index 294a189..4c71c53 100755 --- a/preproc/nc2geojson_was.py +++ b/preproc/nc2geojson_was.py @@ -30,13 +30,14 @@ NETCDF_TEMPLATE = "{}/archive/{}{}.nc" DEBUG = True DELAY = DATES['delay']['delayed'] +DELAY_DATE = DATES['delay']['start_date'] if DELAY: DAYS = range(1, 3) else: DAYS = range(0, 3) -class WasTables(object): +class WasTables: """ Class to manage the figure creation """ def __init__(self, was=None, model='median', variable='SCONC_DUST', selected_date=None): diff --git a/preproc/probability_maps.py b/preproc/probability_maps.py index b703cf6..b284095 100644 --- a/preproc/probability_maps.py +++ b/preproc/probability_maps.py @@ -15,7 +15,6 @@ DEBUG = True PARAMS = ('SCONC_DUST', 'OD550_DUST') -# INPUT_DIR = "/data/daily_dashboard/prob/tmp/interpolated/" INPUT_DIR = "/data/products/median/interpolated/" DIR_PATH = os.path.abspath(os.path.dirname(__file__)) @@ -24,15 +23,14 @@ DATES = json.load(open(os.path.join(DIR_PATH, '../conf/dates.json'))) VARS = json.load(open(os.path.join(DIR_PATH, '../conf/vars.json'))) DELAY = DATES['delay']['delayed'] DELAY_DATE = DATES['delay']['start_date'] - TSTEPS = 8 if DELAY: - FIRST_STEPS_LEN = 2 + FIRST_STEP = 0 else: - FIRST_STEPS_LEN = 3 + FIRST_STEP = 1 +FIRST_STEPS_LEN = 3 -FIRST_STEP = 0 LON0 = 5 LON1 = -10 @@ -75,6 +73,8 @@ class ProbabilityMaps: lat = [] first_steps = [] for model in MODELS: + if model == 'median': + continue tpl = MODELS[model]['template'] ifile = os.path.join(self.input_dir, f'{self.curdate}{tpl}.nc') if DEBUG: @@ -95,7 +95,7 @@ class ProbabilityMaps: continue else: param_values = nc_file.variables[self.parameter_name][:,:,LON0:LON1] - first_steps = np.arange(FIRST_STEP, param_values[FIRST_STEP:,:,:].shape[0], TSTEPS)[:-1] + first_steps = np.arange(FIRST_STEP, param_values[FIRST_STEP:,:,:].shape[0], TSTEPS) # [:-1] if len(first_steps) < FIRST_STEPS_LEN: continue if DEBUG: @@ -210,6 +210,7 @@ if __name__ == "__main__": threshold_list = VARS[param_name]['threshold_list'] conv_factor = VARS[param_name]['mul']**-1 for thresh in threshold_list: + print(param_name, thresh) out_dir = f"/data/daily_dashboard/prob/{param_name.lower()}/{thresh}/netcdf/" ProbabilityMaps(cdate, INPUT_DIR, out_dir, param_name, diff --git a/tabs/forecast.py b/tabs/forecast.py index 2fb62d0..5ecaba5 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -20,64 +20,66 @@ def get_forecast_days(curdate=END_DATE): """ Return forecast days according to configuration file """ delay = DELAY st_date = DELAY_DATE - if (delay and st_date and (dt.strptime(curdate, "%Y%m%d") >= dt.strptime(st_date, "%Y%m%d"))) or \ - (not delay and st_date and dt.strptime(curdate, "%Y%m%d") < dt.strptime(st_date, "%Y%m%d")) or \ + if (delay and st_date \ + and (dt.strptime(curdate, "%Y%m%d") >= dt.strptime(st_date, "%Y%m%d"))) or \ + (not delay and st_date \ + and (dt.strptime(curdate, "%Y%m%d") < dt.strptime(st_date, "%Y%m%d"))) or \ (delay and not st_date): st_day = 1 else: st_day = 0 - return [ - (dt.strptime(curdate, "%Y%m%d") + + return dict([ + ( + idx, (dt.strptime(curdate, "%Y%m%d") + \ timedelta(days=idx)).strftime("%a %d").upper() - for idx in range(st_day, 3) - ] + ) for idx in range(st_day, 3) + ]) -def gen_ts_marks(ts_type, tstep, ts_min, curdate=END_DATE): +def gen_ts_marks(ts_type, curdate=END_DATE): """ Generate time slider marks """ - if DEBUG: print("TS MARKS", ts_type, tstep, ts_min) - + if DEBUG: print("TS MARKS", ts_type, curdate) if ts_type in ('prob', 'was'): - return get_forecast_days(curdate)[tstep-ts_min] - - if DEBUG: print("RET", f'{tstep:d}') - return f'{tstep:d}' + forecast_dict = get_forecast_days(curdate) + forecast_values = sorted(forecast_dict.keys()) + fcst_min = forecast_values[0] + fcst_max = forecast_values[-1] + play = False + freq = 1 + else: + fcst_min = 0 + fcst_max = 72 + forecast_values = range(fcst_min, fcst_max, FREQ) + forecast_dict = dict([ + (fcst_val, f'fcst_val') for fcst_val in forecast_values + ]) + + play = True + freq = FREQ + + return { + 'min': fcst_min, + 'max': fcst_max, + 'step': freq, + 'marks': forecast_dict, + 'play': play + } def gen_time_slider(ts_type='prob', end_date=END_DATE): """ Generate time slider """ - ts_dict = { - 'model': - { - 'min': 0, - 'max': 72, - 'step': FREQ, - 'play': True - }, - 'prob': - { - 'min': 0, - 'max': len(get_forecast_days(end_date))-1, - 'step': 1, - 'play': False - }, - 'was': - { - 'min': 0, - 'max': len(get_forecast_days(end_date))-1, - 'step': 1, - 'play': False - }, - } - ts_min = ts_dict[ts_type]['min'] - ts_max = ts_dict[ts_type]['max'] - ts_step = ts_dict[ts_type]['step'] - ts_play = ts_dict[ts_type]['play'] + ts_dict = gen_ts_marks(ts_type, end_date) + + ts_min = ts_dict['min'] + ts_max = ts_dict['max'] + ts_step = ts_dict['step'] + ts_play = ts_dict['play'] + ts_marks = ts_dict['marks'] marks = { - tstep: {'label': gen_ts_marks(ts_type, tstep, ts_min, end_date)} - for tstep in range(ts_min, ts_max+ts_step, ts_step) + tstep: {'label': ts_marks[tstep]} + for tstep in ts_marks } if DEBUG: print("FCST MARKS", marks[list(marks.keys())[-1]]) -- GitLab From 226fdbdacb83803cabcef51a7ea2a895f38844c9 Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Fri, 5 May 2023 16:55:12 +0200 Subject: [PATCH 08/10] Fixed string format for model comparison time slider labels --- tabs/forecast.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tabs/forecast.py b/tabs/forecast.py index 5ecaba5..e6e5341 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -50,9 +50,9 @@ def gen_ts_marks(ts_type, curdate=END_DATE): else: fcst_min = 0 fcst_max = 72 - forecast_values = range(fcst_min, fcst_max, FREQ) + forecast_values = range(fcst_min, fcst_max+FREQ, FREQ) forecast_dict = dict([ - (fcst_val, f'fcst_val') for fcst_val in forecast_values + (fcst_val, f'{fcst_val}') for fcst_val in forecast_values ]) play = True -- GitLab From b7ea3ed65ce79e095eaaf3c5ce6d80584e3185b8 Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Mon, 8 May 2023 10:01:11 +0200 Subject: [PATCH 09/10] Fixed tests --- data_handler.py | 4 ++-- tests/test_forecast.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data_handler.py b/data_handler.py index 8f22775..01a070f 100644 --- a/data_handler.py +++ b/data_handler.py @@ -157,10 +157,10 @@ class Observations1dHandler(object): # sites = pd.read_table(os.path.join('./conf/', # OBS[obs]['sites']), delimiter=r"\s+", engine='python') - idxs, self.station_names = np.array([[idx, st_name[~st_name.mask].tostring().decode('utf-8')] + idxs, self.station_names = np.array([[idx, st_name[~st_name.mask].tobytes().decode('utf-8')] for idx, st_name in enumerate(input_files[0].variables['station_name'][:]) - if st_name[~st_name.mask].tostring().decode('utf-8').upper() in map(str.upper, sites['SITE'])] + if st_name[~st_name.mask].tobytes().decode('utf-8').upper() in map(str.upper, sites['SITE'])] ).T if DEBUG: print('IDXS', idxs) diff --git a/tests/test_forecast.py b/tests/test_forecast.py index 8a15aae..a696200 100644 --- a/tests/test_forecast.py +++ b/tests/test_forecast.py @@ -16,29 +16,29 @@ def test_model_time_bar(): assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='model-date-picker'), className='timesliderline'), Span(children=[Button(id='btn-play', className='fa fa-play text-center', n_clicks=0, title='Play')], className='timesliderline anim-buttons'), Span(children=Slider(min=0, max=72, step=3, marks={0: {'label': '0'}, 3: {'label': '3'}, 6: {'label': '6'}, 9: {'label': '9'}, 12: {'label': '12'}, 15: {'label': '15'}, 18: {'label': '18'}, 21: {'label': '21'}, 24: {'label': '24'}, 27: {'label': '27'}, 30: {'label': '30'}, 33: {'label': '33'}, 36: {'label': '36'}, 39: {'label': '39'}, 42: {'label': '42'}, 45: {'label': '45'}, 48: {'label': '48'}, 51: {'label': '51'}, 54: {'label': '54'}, 57: {'label': '57'}, 60: {'label': '60'}, 63: {'label': '63'}, 66: {'label': '66'}, 69: {'label': '69'}, 72: {'label': '72'}}, value=0, id='model-slider-graph'), id='model-slider-container', className='timesliderline')], className='timeslider')" in str(code.gen_time_bar('model', '20120120', '20220808')) def test_prob_time_bar(): - assert "Div(children=[Span(children=DatePickerSingle(date='20220809', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 9, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 9, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: {'label': 'TUE 09'}, 1: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=0, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider')" in str(code.gen_time_bar('prob', '20120120', '20220809')) + assert "Div(children=[Span(children=DatePickerSingle(date='20220809', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 9, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 9, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'WED 10'}, 2: {'label': 'THU 11', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider')" in str(code.gen_time_bar('prob', '20120120', '20220809')) def test_was_time_bar(): - assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: {'label': 'MON 08'}, 1: {'label': 'TUE 09', 'style': {'left': '', 'right': '-40px'}}}, value=0, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider')" in str(code.gen_time_bar('was', '20120120', '20220808')) + assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider')" in str(code.gen_time_bar('was', '20120120', '20220808')) def test_models_children(): assert "[Div(id={'tag': 'tab-name', 'index': 'models'}), Alert(children='To explore the forecast, please select a variable and click on APPLY.', id='alert-forecast', color='primary', duration=6000, fade=True, is_open=True, style={'overflow': 'auto', 'marginBottom': 0}), Div(children=[Container(children=[], id='graph-collection', fluid=True), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer')], id='div-collection'), Div([Store(id='model-clicked-coords'), Store(id='current-popups-stored')]), Div(Interval(id='slider-interval', disabled=True, interval=1000, n_intervals=0))" in str(code.models_children('20120120', '20220808')) def test_prob_children(): - assert "[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: {'label': 'MON 08'}, 1: {'label': 'TUE 09', 'style': {'left': '', 'right': '-40px'}}}, value=0, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.prob_children('20120120', '20220808')) + assert "[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.prob_children('20120120', '20220808')) def test_was_children(): - assert "id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: {'label': 'MON 08'}, 1: {'label': 'TUE 09', 'style': {'left': '', 'right': '-40px'}}}, value=0, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.was_children('20120120', '20220808')) + assert """[Div(id={'tag': 'tab-name', 'index': 'was'}), Spinner(Div(children=[Div(id="{'index':'None', 'tag': 'empty-map'}")], id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]""" in str(code.was_children('20120120', '20220808')) def test_tab_forecast(): #TEST MODELS assert "Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div'), Div(children=[Spinner(children=[Modal(children=[], id='ts-modal', centered=True, is_open=False, size='xl')], id='loading-ts-modal', fullscreen=True, fullscreen_style={'opacity': '0.5', 'zIndex': '200000'}, show_initially=False)], id='open-timeseries')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('models', '20120120', '20220808')) #TEST WAS - assert "id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: {'label': 'MON 08'}, 1: {'label': 'TUE 09', 'style': {'left': '', 'right': '-40px'}}}, value=0, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('was', '20120120', '20220808')) + assert """Tab(children=[Div(id={'tag': 'tab-name', 'index': 'was'}), Spinner(Div(children=[Div(id="{'index':'None', 'tag': 'empty-map'}")], id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')""" in str(code.tab_forecast('was', '20120120', '20220808')) #TEST PROB - assert "Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: {'label': 'MON 08'}, 1: {'label': 'TUE 09', 'style': {'left': '', 'right': '-40px'}}}, value=0, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('prob', '20120120', '20220808')) + assert "Tab(children=[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('prob', '20120120', '20220808')) def test_expand_dropdown(): assert "{'models': True, 'prob': False, 'was': False}" in str(code.expand_dropdown('models')) -- GitLab From a9d19fdfb62e85a84fe92aca7e52ee688f4514e6 Mon Sep 17 00:00:00 2001 From: Francesco Benincasa Date: Mon, 8 May 2023 10:58:07 +0200 Subject: [PATCH 10/10] Fixed tests --- tests/test_forecast.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_forecast.py b/tests/test_forecast.py index a65b600..ae24b6e 100644 --- a/tests/test_forecast.py +++ b/tests/test_forecast.py @@ -17,29 +17,29 @@ def test_model_time_bar(): assert str(code.gen_time_bar('model', '20120120', '20220808').children[1]) == "Span(children=[Button(id='btn-play', className='fa fa-play text-center', n_clicks=0, title='Play')], className='timesliderline anim-buttons')" def test_prob_time_bar(): - assert "Div(children=[Span(children=DatePickerSingle(date='20220809', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 9, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 9, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'WED 10'}, 2: {'label': 'THU 11', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider')" in str(code.gen_time_bar('prob', '20120120', '20220809')) + assert "Div(children=[Span(children=[DatePickerSingle(date='20220809', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 9, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 9, 0, 0), display_format='DD MMM YYYY', id='prob-date-picker'), Button(id='clear_button')], className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'WED 10'}, 2: {'label': 'THU 11', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider')" in str(code.gen_time_bar('prob', '20120120', '20220809')) def test_was_time_bar(): - assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider')" in str(code.gen_time_bar('was', '20120120', '20220808')) + assert "Div(children=[Span(children=[DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), display_format='DD MMM YYYY', id='was-date-picker'), Button(id='clear_button')], className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider')" in str(code.gen_time_bar('was', '20120120', '20220808')) def test_models_children(): assert "[Div(id={'tag': 'tab-name', 'index': 'models'}), Alert(children='To explore the forecast, please select a variable and click on APPLY.', id='alert-forecast', color='primary', duration=6000, fade=True, is_open=True, style={'overflow': 'auto', 'marginBottom': 0}), Div(children=[Container(children=[], id='graph-collection', fluid=True), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer')], id='div-collection'), Div([Store(id='model-clicked-coords'), Store(id='current-popups-stored')]), Div(Interval(id='slider-interval', disabled=True, interval=1000, n_intervals=0))" in str(code.models_children('20120120', '20220808')) def test_prob_children(): - assert "[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.prob_children('20120120', '20220808')) + assert "[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=[DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), display_format='DD MMM YYYY', id='prob-date-picker'), Button(id='clear_button')], className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.prob_children('20120120', '20220808')) def test_was_children(): - assert """[Div(id={'tag': 'tab-name', 'index': 'was'}), Spinner(Div(children=[Div(id="{'index':'None', 'tag': 'empty-map'}")], id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]""" in str(code.was_children('20120120', '20220808')) + assert """[Div(id={'tag': 'tab-name', 'index': 'was'}), Spinner(Div(children=[Div(id="{'index':'None', 'tag': 'empty-map'}")], id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=[DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), display_format='DD MMM YYYY', id='was-date-picker'), Button(id='clear_button')], className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]""" in str(code.was_children('20120120', '20220808')) def test_tab_forecast(): #TEST MODELS assert "Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div'), Div(children=[Spinner(children=[Modal(children=[], id='ts-modal', centered=True, is_open=False, size='xl')], id='loading-ts-modal', fullscreen=True, fullscreen_style={'opacity': '0.5', 'zIndex': '200000'}, show_initially=False)], id='open-timeseries')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('models', '20120120', '20220808')) #TEST WAS - assert """Tab(children=[Div(id={'tag': 'tab-name', 'index': 'was'}), Spinner(Div(children=[Div(id="{'index':'None', 'tag': 'empty-map'}")], id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')""" in str(code.tab_forecast('was', '20120120', '20220808')) + assert """Tab(children=[Div(id={'tag': 'tab-name', 'index': 'was'}), Spinner(Div(children=[Div(id="{'index':'None', 'tag': 'empty-map'}")], id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=[DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), display_format='DD MMM YYYY', id='was-date-picker'), Button(id='clear_button')], className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='was-slider-graph'), id='was-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')""" in str(code.tab_forecast('was', '20120120', '20220808')) #TEST PROB - assert "Tab(children=[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('prob', '20120120', '20220808')) + assert "Tab(children=[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=[DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), display_format='DD MMM YYYY', id='prob-date-picker'), Button(id='clear_button')], className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: {'label': 'TUE 09'}, 2: {'label': 'WED 10', 'style': {'left': '', 'right': '-40px'}}}, value=1, id='prob-slider-graph'), id='prob-slider-container', className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('prob', '20120120', '20220808')) def test_expand_dropdown(): assert "{'models': True, 'prob': False, 'was': False}" in str(code.expand_dropdown('models')) -- GitLab