diff --git a/prepare_userdb.py b/prepare_userdb.py index c338a9affb25284b0fb3296513ebf8ac1f3df890..21ce0685c86a1bb09b104890769970ed722e523a 100644 --- a/prepare_userdb.py +++ b/prepare_userdb.py @@ -59,8 +59,8 @@ conn.execute("INSERT INTO convoc_status (id,job_status) \ conn.commit() # There is the need for controlled_vocabulary for regions of interest -# 0: finished -# 1: active +# 0: NRW +# 1: BB conn.execute('''CREATE TABLE convoc_region (id INT PRIMARY KEY NOT NULL, region_name TEXT NOT NULL);''') @@ -72,6 +72,65 @@ conn.execute("INSERT INTO convoc_region (id,region_name) \ conn.commit() +# There is the need for controlled_vocabulary for species of interest +# 0: ozone +# 1: no +# 2: no2 +# 3: pm2p5 +conn.execute('''CREATE TABLE convoc_species + (id INT PRIMARY KEY NOT NULL, + species_name TEXT NOT NULL);''') + +conn.execute("INSERT INTO convoc_species(id,species_name) \ + VALUES (0, 'ozone')") +conn.execute("INSERT INTO convoc_species(id,species_name) \ + VALUES (1, 'no')") +conn.execute("INSERT INTO convoc_species(id,species_name) \ + VALUES (2, 'no2')") +conn.execute("INSERT INTO convoc_species (id,species_name) \ + VALUES (3, 'pm2p5')") + +conn.commit() + +# There is the need for controlled_vocabulary for output metrics (MLAir) +# 0: dma8eu +# 1: mean +conn.execute('''CREATE TABLE convoc_metric + (id INT PRIMARY KEY NOT NULL, + metric_name TEXT NOT NULL);''') + +conn.execute("INSERT INTO convoc_metric (id,metric_name) \ + VALUES (0, 'dma8eu')") +conn.execute("INSERT INTO convoc_metric (id,metric_name) \ + VALUES (1, 'mean')") + +conn.commit() + +# There is the need for controlled_vocabulary for emission scenarios +# 0: standard +# 1: no-emission +# 2: home-office and energy saving +# 3: industry +# 4: e-traffic +# 5: fireplace +conn.execute('''CREATE TABLE convoc_emis_scen + (id INT PRIMARY KEY NOT NULL, + emis_name TEXT NOT NULL);''') + +conn.execute("INSERT INTO convoc_emis_scen (id, emis_name) \ + VALUES (0, 'standard')") +conn.execute("INSERT INTO convoc_emis_scen (id, emis_name) \ + VALUES (1, 'no-emission')") +conn.execute("INSERT INTO convoc_emis_scen (id, emis_name) \ + VALUES (2, 'home-office and energy saving')") +conn.execute("INSERT INTO convoc_emis_scen (id, emis_name) \ + VALUES (3, 'industry')") +conn.execute("INSERT INTO convoc_emis_scen (id, emis_name) \ + VALUES (4, 'e-traffic')") +conn.execute("INSERT INTO convoc_emis_scen (id, emis_name) \ + VALUES (5, 'fireplace')") + +conn.commit() # Second, create the dashboard tables conn.execute('''CREATE TABLE users @@ -99,40 +158,46 @@ conn.execute('''CREATE TABLE jobs start_date datetime NOT NULL, forecast_length INT NOT NULL, region INT NOT NULL, + species INT , + metric INT , + emis_scen INT , creation_date datetime NOT NULL, FOREIGN KEY(user_id) REFERENCES user(id), FOREIGN KEY(status) REFERENCES convoc_status(id), FOREIGN KEY(application) REFERENCES convoc_application(id), - FOREIGN KEY(region) REFERENCES convoc_region(id));''') - -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('832tgjhingj1', 1, 0, 1, '2018-07-18 00:00', 4, 1, '2024-01-12 16:03')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('jjkl7t3li97m', 1, 1, 0, '2017-01-25 00:00', 3, 0, '2024-01-09 10:14')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('7zhtglaza8ah', 1, 2, 1, '2018-07-18 00:00', 4, 1, '2024-01-15 08:01')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('ji54Fdr0z99m', 1, 0, 0, '2018-07-18 00:00', 1, 0, '2023-12-18 13:57')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('7zknt6702rx5', 1, 0, 3, '2017-01-25 00:00', 3, 0, '2023-12-12 11:27')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('klj836kahg2l', 1, 2, 0, '2018-07-18 00:00', 1, 0, '2023-12-21 17:59')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('a89uj20gxybb', 1, 2, 2, '2017-01-25 00:00', 4, 0, '2024-01-02 14:35')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('832tgjhingj1', 2, 0, 1, '2018-07-18 00:00', 4, 1, '2024-01-12 16:03')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('jjkl7t3li97m', 2, 1, 0, '2017-01-25 00:00', 3, 0, '2024-01-09 10:14')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('7zhtglaza8ah', 2, 2, 1, '2018-07-18 00:00', 4, 1, '2024-01-15 08:01')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('ji54Fdr0z99m', 2, 0, 0, '2018-07-18 00:00', 1, 0, '2023-12-18 13:57')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('7zknt6702rx5', 2, 0, 3, '2017-01-25 00:00', 3, 0, '2023-12-12 11:27')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('klj836kahg2l', 2, 2, 0, '2018-07-18 00:00', 1, 0, '2023-12-21 17:59')") -conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, creation_date) \ - VALUES ('a89uj20gxybb', 2, 2, 2, '2017-01-25 00:00', 4, 0, '2024-01-02 14:35')") + FOREIGN KEY(region) REFERENCES convoc_region(id), + FOREIGN KEY(species) REFERENCES convoc_species(id), + FOREIGN KEY(metric) REFERENCES convoc_metric(id), + FOREIGN KEY(emis_scen) REFERENCES convoc_emis_scen(id));''') + +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('832tgjhingj1', 1, 0, 1, '2018-07-18 00:00', 4, 1, Null, Null, Null, '2024-01-12 16:03')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('jjkl7t3li97m', 1, 1, 0, '2017-01-25 00:00', 3, 0, 0, 0, Null, '2024-01-09 10:14')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('7zhtglaza8ah', 1, 2, 1, '2018-07-18 00:00', 4, 1, Null, Null, 1, '2024-01-15 08:01')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('ji54Fdr0z99m', 1, 0, 0, '2018-07-18 00:00', 1, 0, Null, Null, Null, '2023-12-18 13:57')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('7zknt6702rx5', 1, 0, 3, '2017-01-25 00:00', 3, 0, Null, Null, Null, '2023-12-12 11:27')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('klj836kahg2l', 1, 2, 0, '2018-07-18 00:00', 1, 0, Null, Null, 2, '2023-12-21 17:59')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('a89uj20gxybb', 1, 2, 2, '2017-01-25 00:00', 4, 0, Null, Null, 5, '2024-01-02 14:35')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('832tgjhingj1', 2, 0, 1, '2018-07-18 00:00', 4, 1, Null, Null, Null, '2024-01-12 16:03')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('jjkl7t3li97m', 2, 1, 0, '2017-01-25 00:00', 3, 0, 0, 0, Null, '2024-01-09 10:14')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('7zhtglaza8ah', 2, 2, 1, '2018-07-18 00:00', 4, 1, Null, Null, 1, '2024-01-15 08:01')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('ji54Fdr0z99m', 2, 0, 0, '2018-07-18 00:00', 1, 0, Null, Null, Null, '2023-12-18 13:57')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('7zknt6702rx5', 2, 0, 3, '2017-01-25 00:00', 3, 0, Null, Null, Null, '2023-12-12 11:27')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('klj836kahg2l', 2, 2, 0, '2018-07-18 00:00', 1, 0, Null, Null, 2, '2023-12-21 17:59')") +conn.execute("INSERT INTO jobs (id,user_id,application,status,start_date,forecast_length, region, species, metric, emis_scen, creation_date) \ + VALUES ('a89uj20gxybb', 2, 2, 2, '2017-01-25 00:00', 4, 0, Null, Null, 5, '2024-01-02 14:35')") conn.commit() diff --git a/src/pages/dashboard.py b/src/pages/dashboard.py index 37840732f3bc6eb3f107161afb86b28144ea1f60..20fc981ce97da1347a9aeff503212a62fefcd840 100644 --- a/src/pages/dashboard.py +++ b/src/pages/dashboard.py @@ -22,6 +22,8 @@ from deployment_settings import ( UNICORE_USER, UNICORE_PASSWORD ) from mlair.time_series import plot as plot_ml_time_series +import pages.dashboard_translations as guitr +import pages.dashboard_constants as guiconst # the following should be done with static files! APP_HOME = Path.cwd() @@ -31,133 +33,6 @@ ASSETS_PATH = APP_HOME.joinpath("assets", "generated_plots") dash.register_page(__name__, title="DestinE Air Quality Use Case", path="/") -# settings (can of course better be read from file!) -layout_cards = [["Description", "Create Forecasts", "My Model Runs", "My Results"], - ["Beschreibung", "Erstelle Vorhersagen", "Meine Modellläufe", "Meine Auswertungen"]] -description = [["The DestinE Air Quality Use Case demonstrates interactive triggering of advanced forecasting " - "and analysis workflows for air quality.", - html.Br(), - "The workflows are triggered by clicking on the buttons in the second tab.", - html.Br(), - "The results of the workflows are displayed in the third tab.", - html.Br(), - "The documentation of the use case can be found ", - html.A("here", href="https://www.fz-juelich.de/de/iek/iek-8/projekte/" - + "destination-earth-use-case-fuer-luftqualitaet-de370c")], - ["Der 'DestinE Air Quality Use Case' (Anwendungsfall) demonstriert die interaktive Auslösung " - "fortgeschrittener Vorhersage- und Analyse-Workflows für die Luftqualität.", - html.Br(), - "Die Workflows werden durch Klicken auf die Schaltflächen im zweiten Reiter ausgelöst.", - html.Br(), - "Die Ergebnisse der Workflows werden auf der dritten Registerkarte angezeigt.", - html.Br(), - "Die Dokumentation des Anwendungsfalls finden Sie ", - html.A("hier", href="https://www.fz-juelich.de/de/iek/iek-8/projekte/" - + "destination-earth-use-case-fuer-luftqualitaet-de370c")]] -jobs_columns = [["Application", "Status", "Start date", "Forecast Length", "Region", "Creation Date", "Jobnr"], - ["Anwendung", "Status", "Startdatum", "Vorhersagedauer", "Region", "Erstellungsdatum", "Jobnr"]] -results_columns = [["Result_ID", "Jobnr", "Application", "Used Options"], - ["Resultats_ID", "Jobnr", "Anwendung", "Verwendete Optionen"]] -eurad_scenarios = ["avoid all anthropogenic emissions", - "home office", - "industry", - "traffic"] - -# The following lists should be created once from the controlled vocabulary -status_text = [["finished", "active", "waiting", "aborted"], - ["beendet", "aktiv", "in der Warteschlange", "abgebrochen"]] -application_text = [["Field forecasting with EURAD-IM", "Point forecasting with MLAir", "EURAD-IM emission scenarios"], - ["Gebietsvorhersage mit EURAD-IM", "Stationsvorhersage mit MLAir", "EURAD-IM Emissionsszenarien"]] -region_text = [["North Rhine-Westphalia", "Berlin-Brandenburg"], - ["Nordrhein-Westfalen", "Berlin-Brandenburg"]] -description_text = [["This application produces high-resolution, i.e. 1 km or less, on-demand results over a " - + "user-selected area for a forecast period of up to 4 days. Here, users can select the forecast " - + "start date (default today) and the forecast length (shorter runs require less time and " - + "resources), and the regional domain of the simulation. There are two EURAD-IM model " - + "configurations applied in the background of this application: i) the default 9 km resolution " - + "model covering all of Europe, and ii) region-specific 1 km configurations, initially limited " - + "to North Rhine-Westphalia and Brandenburg. Users can select whether they wish to perform a " - + "dedicated 1 km EURAD-IM simulation, or whether the 1 km results shall be obtained with ML " - + "downscaling from the results of a 9 km simulation. For more information about EURAD-IM and ML " - + "downscaling, please refer to the description tab.", - "This application concerns point forecasts of air quality at (German) measurement stations " - + "with the MLAir tool. This workflow makes use of the TOAR database infrastructure that is " - + "operated at JSC (https://toar-data.fz-juelich.de) and uses data from the continuous Digital " - + "Twin (DT) as meteorological inputs. Users can select a forecast a start time and a region, and " - + "the tool will then generate forecasts for all stations in the given region. Users can also " - + "select the species of interest and the air quality metric that shall be computed. Initial " - + "settings for these parameters are ozone and 'MDA8', i.e. the maximum daily 8-hour average " - + "value. For more information about MLAir, please refer to the description tab.", - "This application, which can be directly applied for decision making, triggers an EURAD-IM " - + "ensemble simulation with modified emission scenarios. This allows for the assessment of the " - + "effectiveness of different air pollution mitigation strategies. User choices are similar to " - + "the field forecast application, except that users will also have to choose the scenario they " - + "wish to employ. For more information about EURAD-IM emissions, please refer to the description " - + "tab."], - ["Diese Anwendung erzeugt hochauflösende, d.h. 1 km oder weniger, On-Demand-Ergebnisse über ein " - + "vom Benutzer ausgewähltes Gebiet für einen Vorhersagezeitraum von bis zu 4 Tagen. Dabei können " - + "die Nutzer das Startdatum der Vorhersage (standardmäßig heute) und die Vorhersagelänge " - + "(kürzere Läufe erfordern weniger Zeit und Ressourcen) sowie den regionalen Bereich der " - + "Simulation auswählen. Im Hintergrund dieser Anwendung werden zwei " - + "EURAD-IM-Modellkonfigurationen verwendet: i) das Standardmodell mit 9 km Auflösung, das ganz " - + "Europa abdeckt, und ii) regionalspezifische 1 km-Konfigurationen, die zunächst auf " - + "Nordrhein-Westfalen und Brandenburg beschränkt sind. Der Benutzer kann dann wählen, ob er eine " - + "eigene 1 km EURAD-IM-Simulation durchführen möchte oder ob die 1 km-Ergebnisse durch " - + "ML-Downscaling aus den Ergebnissen einer 9 km-Simulation gewonnen werden sollen. Weitere Details " - + "über EURAD-IM finden sich unter 'Beschreibung'.", - "Diese Anwendung betrifft Punktvorhersagen der Luftqualität an (deutschen) Messstationen mit dem " - + "MLAir-Tool. Sie nutzt die TOAR-Datenbankinfrastruktur, die beim JSC " - + "(https://toar-data.fz-juelich.de) betrieben wird, und verwendet Daten aus dem kontinuierlichen " - + "digitalen Zwilling (Digital Twin -- DT) als meteorologische Eingaben. Der Benutzer kann eine " - + "Startzeit für die Vorhersage und eine Region auswählen, woraufhin das Tool Vorhersagen für " - + "alle Stationen in der jeweiligen Region erstellt. Die Benutzer können auch die interessierende " - + "Spezies und die zu berechnende Luftqualitätsmetrik auswählen. Die Grundeinstellungen für diese " - + "Parameter sind Ozon und 'MDA8', d. h. der maximale 8-Stunden-Tagesmittelwert. Weitere " - + "Informationen über MLAir finden sich im Beschreibungs-Tab.", - "Diese Anwendung löst eine " - + "EURAD-IM-Ensemblesimulation mit veränderten Emissionsszenarien aus. Dies ermöglicht die " - + "Bewertung der Wirksamkeit verschiedener Strategien zur Verringerung der Luftverschmutzung. Die " - + "Auswahlmöglichkeiten des Benutzers sind ähnlich wie bei der Feldvorhersageanwendung, außer " - + "dass der Benutzer auch das Szenario auswählen muss, das er verwenden möchte. Weitere " - + "Informationen über EURAD-IM Emissionen finden sich im Beschreibungs-Tab."]] -user_label = ["user:", "Benutzer:"] -run_label = ["run", "Starten"] -run2_label = ["Run", "Lauf"] -close_label = ["close", "Schließen"] -date_label = ["date:", "Datum:"] -date_format = ["M/D/Y", "D.M.Y"] -date_format2 = ['%Y-%m-%d %H:%M', '%d.%m.%Y %H:%M'] -first_day_of_week = [0, 1] -min_date_allowed = "2017-02-20" -max_date_allowed = "2018-08-09" -initial_visible_month = "2017-02-01" -forecast_length_label = ["forecast length", "Vorhersagedauer"] -region_label = ["region:", "Region:"] -forecast_length_options = [["4 days", "3 days", "2 days", "1 day"], - ["4 Tage", "3 Tage", "2 Tage", "1 Tag"]] -output_format_options = [["raw model output", "2D plots", "time series"], - ["Rohmodellausgabe", "2D-Diagramme", "Zeitreihen"]] -state_label = ["state:", "Bundesland:"] -species_label = ["species:", "Spezies:"] -output_metrics_label = ["output metrics:", "Ausgabemetrik:"] -species_options = [["ozone", "NOx", "PM2.5"], - ["Ozon", "Stickoxide", "Feinstaub (PM2.5)"]] -emis_scen_label = ["emission scenario:", "Emissionsszenario:"] -help_metrics_label = ["Help on metrics", "Hilfe zu Ausgabemetriken"] -help_emissions_label = ["Help on emission scenarios", "Hilfe zu Emissions-Szenarien"] -map_select_label = ["Select on map", "auf Karte auswählen"] -time_step_label = ["Time step", "Zeitschritt"] -start_date_label = ["Start date", "Startdatum"] -location_label = ["Location", "Ort"] -day_label = ["day", "Tag"] -day_plural_label = ["s", "e"] -save_label = ["Save Results", "Ergebnisse sichern"] -download_label = ["Download Data", "Daten herunterladen"] -im_download_label = ["Download Plots", "Plots herunterladen"] -downscaling_label = ["Postprocessing with ML-Downscaling", "Postprocessing mit ML-Downscaling"] -show_downscaling_label = ["Show results with ML downscaling", "Ergebnisse mit ML-Downscaling anzeigen"] -out_option_label = ["output option", "Ausgabe-Option"] - # placeholder for time series and map image_path = IMAGE_PATH.joinpath('placeholder_timeseries.png') pil_series = Image.open(image_path) @@ -248,7 +123,7 @@ aai_login = dbc.Row([ def generate_ml_fcast_body(language_id=0): return [ dbc.Row([ - dbc.Col(dbc.Label(state_label[language_id]), width=3), + dbc.Col(dbc.Label(guitr.state_label[language_id]), width=3), dbc.Col( dcc.Dropdown(value="Nordrhein Westfalen", options=["Baden Württemberg", "Bayern", "Berlin", "Brandenburg", "Bremen", "Hamburg", "Hessen", @@ -257,29 +132,29 @@ def generate_ml_fcast_body(language_id=0): ), ], class_name="row mt-3"), dbc.Row([ - dbc.Col(dbc.Label(date_label[language_id]), width=3), + dbc.Col(dbc.Label(guitr.date_label[language_id]), width=3), dbc.Col(dcc.DatePickerSingle(date=dt.date.today(), - display_format=date_format[language_id], - first_day_of_week=first_day_of_week[language_id])) + display_format=guitr.date_format[language_id], + first_day_of_week=guitr.first_day_of_week[language_id])) ], class_name="row mt-3"), dbc.Row([ - dbc.Col(dbc.Label(species_label[language_id]), width=3), + dbc.Col(dbc.Label(guitr.species_label[language_id]), width=3), dbc.Col( - dcc.Dropdown(value=species_options[language_id][0], options=species_options[language_id]), width=6 + dcc.Dropdown(value=guitr.species_options[language_id][0], options=guitr.species_options[language_id]), width=6 ) ], class_name="row mt-3"), dbc.Row([ - dbc.Col(dbc.Label(output_metrics_label[language_id]), width=3), + dbc.Col(dbc.Label(guitr.output_metrics_label[language_id]), width=3), dbc.Col(dcc.Dropdown(value=metrics_info[language_id][' Name'][0], options=metrics_info[language_id][' Name'])), - dbc.Col(dbc.Button(f"{help_metrics_label[language_id]}", id="help_metrics_open", class_name="fzj_style_btn"), width=3), + dbc.Col(dbc.Button(f"{guitr.help_metrics_label[language_id]}", id="help_metrics_open", class_name="fzj_style_btn"), width=3), dbc.Modal([ - dbc.ModalHeader(f"{help_metrics_label[language_id]}"), + dbc.ModalHeader(f"{guitr.help_metrics_label[language_id]}"), dbc.ModalBody(dash_table.DataTable(metrics_info[language_id].to_dict('records'), [{"name": i, "id": i} for i in metrics_info[language_id].columns], style_table={"width": "100%"}, style_cell={"textAlign": "left", "whiteSpace": "pre-line"})), - dbc.ModalFooter([dbc.Button(f"{close_label[language_id]}", id=f"help_metrics_close", class_name="fzj_style_btn", n_clicks=0)]), + dbc.ModalFooter([dbc.Button(f"{guitr.close_label[language_id]}", id=f"help_metrics_close", class_name="fzj_style_btn", n_clicks=0)]), ], id="help_metrics_modal", is_open=False, @@ -292,7 +167,7 @@ def generate_ml_fcast_output_body(language_id): ts_plot_path = str(APP_HOME.joinpath("assets", "generated_plots", ts_plot_name)) return [ - dbc.Row(dbc.Label(f"{start_date_label[language_id]}: 18.07.2018, Ozon, Nordrhein Westfalen")), + dbc.Row(dbc.Label(f"{guitr.start_date_label[language_id]}: 18.07.2018, Ozon, Nordrhein Westfalen")), dbc.Row([ dbc.Col(dbc.Label("station:"), width=3), dbc.Col( @@ -300,13 +175,13 @@ def generate_ml_fcast_output_body(language_id): options=station_info, ), width=6 ), - dbc.Col(dbc.Button(f"{map_select_label[language_id]}", class_name="fzj_style_btn"), width=2) + dbc.Col(dbc.Button(f"{guitr.map_select_label[language_id]}", class_name="fzj_style_btn"), width=2) ], class_name="row mt-3"), dbc.Row([ dbc.Col([html.Img(src=pil_pure_series, width=550), - dbc.Col(dbc.Button(f"{save_label[language_id]}", class_name="fzj_style_btn"), width=6), + dbc.Col(dbc.Button(f"{guitr.save_label[language_id]}", class_name="fzj_style_btn"), width=6), dbc.Col(html.Td([])), - dbc.Button(f"{download_label[language_id]}", class_name="fzj_style_btn")], width=6), + dbc.Button(f"{guitr.download_label[language_id]}", class_name="fzj_style_btn")], width=6), ], class_name="row mt-3"), ] @@ -315,10 +190,10 @@ def generate_ml_fcast_output_modal(jobnr=None, lisopen=False, language_id=0): return html.Div([ dbc.Modal( [ - dbc.ModalTitle(f"{run2_label[language_id]} {jobnr}", style={"fontSize": 15}), - dbc.ModalHeader(dbc.ModalTitle(application_text[language_id][1])), + dbc.ModalTitle(f"{guitr.run2_label[language_id]} {jobnr}", style={"fontSize": 15}), + dbc.ModalHeader(dbc.ModalTitle(guitr.application_text[language_id][1])), dbc.ModalBody(generate_ml_fcast_output_body(language_id)), - dbc.ModalFooter([dbc.Button(f"{close_label[language_id]}", id="ml_fcast_output_close", + dbc.ModalFooter([dbc.Button(f"{guitr.close_label[language_id]}", id="ml_fcast_output_close", class_name="fzj_style_btn", n_clicks=0) ]), ], @@ -332,10 +207,10 @@ def generate_ml_fcast_output_modal(jobnr=None, lisopen=False, language_id=0): def generate_ml_fcast_result_modal(jobnr=None, lisopen=False, language_id=0): return dbc.Modal( [ - dbc.ModalTitle(f"{run2_label[language_id]} {jobnr}", style={"fontSize": 15}), - dbc.ModalHeader(dbc.ModalTitle(application_text[language_id][1])), + dbc.ModalTitle(f"{guitr.run2_label[language_id]} {jobnr}", style={"fontSize": 15}), + dbc.ModalHeader(dbc.ModalTitle(guitr.application_text[language_id][1])), dbc.ModalBody(generate_ml_fcast_output_body(language_id)), - dbc.ModalFooter(dbc.Button(f"{close_label[language_id]}", id="ml_fcast_result_close", + dbc.ModalFooter(dbc.Button(f"{guitr.close_label[language_id]}", id="ml_fcast_result_close", class_name="fzj_style_btn", n_clicks=0)), ], id="ml_fcast_result_modal", @@ -352,19 +227,19 @@ def generate_eurad_im_body(language_id=0): disabled_days = [ dt.datetime.strptime('2017-02-21','%Y-%m-%d') + dt.timedelta(days=i) for i in range(510) ] return [ dbc.Row([ - dbc.Col(dbc.Label(date_label[language_id]), width=3), + dbc.Col(dbc.Label(guitr.date_label[language_id]), width=3), dbc.Col(dcc.DatePickerSingle(date=dt.date(2017, 1, 1), - display_format=date_format[language_id], - first_day_of_week=first_day_of_week[language_id], - min_date_allowed=dt.date(2017, 1, 1), - max_date_allowed=dt.date(2018, 9, 1), + display_format=guitr.date_format[language_id], + first_day_of_week=guitr.first_day_of_week[language_id], + min_date_allowed=guiconst.min_date_allowed, + max_date_allowed=guiconst.max_date_allowed, disabled_days=disabled_days, - initial_visible_month=dt.date(2017, 1, 1))), - dbc.Col(dbc.Label(f"{forecast_length_label[language_id]}:")), - dbc.Col(dcc.Dropdown(value=forecast_length_options[language_id][0], options=forecast_length_options[language_id])) + initial_visible_month=guiconst.initial_visible_month)), + dbc.Col(dbc.Label(f"{guitr.forecast_length_label[language_id]}:")), + dbc.Col(dcc.Dropdown(value=guitr.forecast_length_options[language_id][0], options=guitr.forecast_length_options[language_id])) ], class_name="row mt-3"), dbc.Row([ - dbc.Col(dbc.Label(region_label[language_id]), width=3), + dbc.Col(dbc.Label(guitr.region_label[language_id]), width=3), dbc.Col(dcc.RadioItems(['NRW', 'Berlin-Brandenburg'], 'NRW')), ], class_name="row mt-3"), ] @@ -417,43 +292,43 @@ def generate_eurad_im_output_body(language_id, context): timestep_strings = [np.datetime_as_string(ts, unit="m") for ts in timestep_list] # TODO: Zeit in Stunden seit Start - start_date = pd.to_datetime(timestep_list[0]).strftime(date_format2[language_id]) + start_date = pd.to_datetime(timestep_list[0]).strftime(guitr.date_format2[language_id]) fc_length = (len(timestep_list)-1) // 24 - fc_length_str = "{} {}{}".format(fc_length, day_label[language_id], day_plural_label[language_id] if fc_length > 1 else "") + fc_length_str = "{} {}{}".format(fc_length, guitr.day_label[language_id], guitr.day_plural_label[language_id] if fc_length > 1 else "") variables_list = info.get_available_variables(infile) stations_list = info.get_available_stations() stations_list = sorted(stations_list) return [ - dbc.Row([dbc.Label(f"{start_date_label[language_id]}: {start_date}, {forecast_length_label[language_id]}: {fc_length_str}")]), + dbc.Row([dbc.Label(f"{guitr.start_date_label[language_id]}: {start_date}, {guitr.forecast_length_label[language_id]}: {fc_length_str}")]), dbc.Row([ - dbc.Col(dbc.Label(f"{time_step_label[language_id]}:"), width=3), + dbc.Col(dbc.Label(f"{guitr.time_step_label[language_id]}:"), width=3), dbc.Col(dcc.Dropdown(value=timestep_strings[0], options=timestep_strings, id='time-step-dropdown-{}'.format(context)), width=3) ], class_name="row mt-3"), dbc.Row([ dbc.Col(dbc.Label("Variable:"), width=3), dbc.Col(dcc.Dropdown(value=variables_list[0], options=variables_list, id='variable-dropdown-{}'.format(context)), width=3), - dbc.Col(dbc.Label(f"{location_label[language_id]}:"), width=1), + dbc.Col(dbc.Label(f"{guitr.location_label[language_id]}:"), width=1), dbc.Col(dcc.Dropdown(value=stations_list[0], options=stations_list, id='station-dropdown-{}'.format(context)), width=5) ], class_name="row mt-3"), dbc.Row([ dbc.Col(html.Div(id='image-container-{}'.format(context)), width=6), dbc.Col([html.Div(id='image-container-timeseries-{}'.format(context)), - dbc.Col(dbc.Button(f"{save_label[language_id]}", class_name="fzj_style_btn"), width=6), + dbc.Col(dbc.Button(f"{guitr.save_label[language_id]}", class_name="fzj_style_btn"), width=6), dbc.Col(html.Br()), - html.Div([dbc.Button(f"{download_label[language_id]}", id="eurad_im_output_download", + html.Div([dbc.Button(f"{guitr.download_label[language_id]}", id="eurad_im_output_download", class_name="fzj_style_btn"), dcc.Download(id="eurad_im_download_result")]), dbc.Col(html.Br()), - html.Div([dbc.Button(f"{im_download_label[language_id]}", id="eurad_im_plots_download", + html.Div([dbc.Button(f"{guitr.im_download_label[language_id]}", id="eurad_im_plots_download", class_name="fzj_style_btn"), dcc.Download(id="eurad_im_download_plots")])], width=6), ], class_name="row mt-3"), dbc.Row([ dbc.Col(html.Br(), width=12), dbc.Col([ - dbc.Checkbox(label=f"{show_downscaling_label[language_id]}", value=0) + dbc.Checkbox(label=f"{guitr.show_downscaling_label[language_id]}", value=0) ], style={"display": "flex"}), ], class_name="row mt-3f"), ] @@ -463,10 +338,10 @@ def generate_eurad_im_output_modal(jobnr=None, lisopen=False, language_id=0): return html.Div([ dbc.Modal( [ - dbc.ModalTitle(f"{run2_label[language_id]} {jobnr}", style={"fontSize": 15}, id="eurad_im_output_modal_title"), - dbc.ModalHeader(dbc.ModalTitle(application_text[language_id][0])), + dbc.ModalTitle(f"{guitr.run2_label[language_id]} {jobnr}", style={"fontSize": 15}, id="eurad_im_output_modal_title"), + dbc.ModalHeader(dbc.ModalTitle(guitr.application_text[language_id][0])), dbc.ModalBody(generate_eurad_im_output_body(language_id, "output")), - dbc.ModalFooter([dbc.Button(f"{close_label[language_id]}", id="eurad_im_output_close", + dbc.ModalFooter([dbc.Button(f"{guitr.close_label[language_id]}", id="eurad_im_output_close", class_name="fzj_style_btn", n_clicks=0) ]), ], @@ -480,10 +355,10 @@ def generate_eurad_im_output_modal(jobnr=None, lisopen=False, language_id=0): def generate_eurad_im_result_modal(jobnr=None, lisopen=False, language_id=0): return dbc.Modal( [ - dbc.ModalTitle(f"{run2_label[language_id]} {jobnr}", style={"fontSize": 15}), - dbc.ModalHeader(dbc.ModalTitle(application_text[language_id][0])), + dbc.ModalTitle(f"{guitr.run2_label[language_id]} {jobnr}", style={"fontSize": 15}), + dbc.ModalHeader(dbc.ModalTitle(guitr.application_text[language_id][0])), dbc.ModalBody(generate_eurad_im_output_body(language_id, "result")), - dbc.ModalFooter(dbc.Button(f"{close_label[language_id]}", id="eurad_im_result_close", + dbc.ModalFooter(dbc.Button(f"{guitr.close_label[language_id]}", id="eurad_im_result_close", class_name="fzj_style_btn", n_clicks=0)), ], id="eurad_im_result_modal", @@ -501,44 +376,44 @@ def generate_eurad_scen_output_body(language_id): dbc.Row([ dbc.Col([ dbc.Checklist(options=[ - {"label": f"{downscaling_label[language_id]}", "value": 1}, + {"label": f"{guitr.downscaling_label[language_id]}", "value": 1}, ]) ], style={"display": "flex"}), ], class_name="row mt-3"), dbc.Row([ - dbc.Col(dbc.Label(f"{out_option_label[language_id]}"), width=3), - dbc.Col(dcc.Dropdown(value=output_format_options[language_id][0], - options=output_format_options[language_id]), width=6) + dbc.Col(dbc.Label(f"{guitr.out_option_label[language_id]}"), width=3), + dbc.Col(dcc.Dropdown(value=guitr.output_format_options[language_id][0], + options=guitr.output_format_options[language_id]), width=6) ], class_name="row mt-3"), ] def generate_eurad_scen_body(language_id): return [ dbc.Row([ - dbc.Col(dbc.Label(f"{date_label[language_id]}"), width=3), + dbc.Col(dbc.Label(f"{guitr.date_label[language_id]}"), width=3), dbc.Col(dcc.DatePickerSingle(date=dt.date.today(), - display_format=date_format[language_id], - first_day_of_week=first_day_of_week[language_id])), - dbc.Col(dbc.Label(f"{forecast_length_label[language_id]}:")), - dbc.Col(dcc.Dropdown(value=forecast_length_options[language_id][0], options=forecast_length_options[language_id])) + display_format=guitr.date_format[language_id], + first_day_of_week=guitr.first_day_of_week[language_id])), + dbc.Col(dbc.Label(f"{guitr.forecast_length_label[language_id]}:")), + dbc.Col(dcc.Dropdown(value=guitr.forecast_length_options[language_id][0], options=guitr.forecast_length_options[language_id])) ], class_name="row mt-3"), dbc.Row([ - dbc.Col(dbc.Label(f"{region_label[language_id]}"), width=3), + dbc.Col(dbc.Label(f"{guitr.region_label[language_id]}"), width=3), dbc.Col(dcc.RadioItems(['NRW', 'Berlin-Brandenburg'], 'NRW')), ], class_name="row mt-3"), dbc.Row([ - dbc.Col(dbc.Label(f"{emis_scen_label[language_id]}"), width=3), + dbc.Col(dbc.Label(f"{guitr.emis_scen_label[language_id]}"), width=3), dbc.Col(dcc.Dropdown(value=emis_info[language_id][" Name"][0], options=emis_info[language_id][" Name"])), - dbc.Col(dbc.Button(f"{help_emissions_label[language_id]}", id="help_emis_open", class_name="fzj_style_btn"), width=3), + dbc.Col(dbc.Button(f"{guitr.help_emissions_label[language_id]}", id="help_emis_open", class_name="fzj_style_btn"), width=3), dbc.Modal([ - dbc.ModalHeader(f"{help_emissions_label[language_id]}"), + dbc.ModalHeader(f"{guitr.help_emissions_label[language_id]}"), dbc.ModalBody(dash_table.DataTable(emis_info[language_id].to_dict('records'), [{"name": i, "id": i} for i in emis_info[language_id].columns], style_table={"width": "100%"}, style_cell={"textAlign": "left", "whiteSpace": "pre-line" })), - dbc.ModalFooter([dbc.Button(f"{close_label[language_id]}", id=f"help_emis_close", class_name="fzj_style_btn", n_clicks=0)]), + dbc.ModalFooter([dbc.Button(f"{guitr.close_label[language_id]}", id=f"help_emis_close", class_name="fzj_style_btn", n_clicks=0)]), ], id="help_emis_modal", is_open=False, @@ -552,10 +427,10 @@ def generate_eurad_scen_output_modal(container_id="eurad_scen_output_modal_conta return html.Div([ dbc.Modal( [ - dbc.ModalTitle(f"{run2_label[language_id]} {jobnr}", style={"fontSize": 15}), - dbc.ModalHeader(dbc.ModalTitle(application_text[language_id][2])), + dbc.ModalTitle(f"{guitr.run2_label[language_id]} {jobnr}", style={"fontSize": 15}), + dbc.ModalHeader(dbc.ModalTitle(guitr.application_text[language_id][2])), dbc.ModalBody(generate_eurad_scen_output_body(language_id)), - dbc.ModalFooter([dbc.Button(f"{close_label[language_id]}", id="eurad_scen_output_close", + dbc.ModalFooter([dbc.Button(f"{guitr.close_label[language_id]}", id="eurad_scen_output_close", class_name="fzj_style_btn", n_clicks=0) ]), ], @@ -570,10 +445,10 @@ def generate_eurad_scen_result_modal(container_id="eurad_scen_result_modal_conta return html.Div([ dbc.Modal( [ - dbc.ModalTitle(f"{run2_label[language_id]} {jobnr}", style={"fontSize": 15}), - dbc.ModalHeader(dbc.ModalTitle(application_text[language_id][2])), + dbc.ModalTitle(f"{guitr.run2_label[language_id]} {jobnr}", style={"fontSize": 15}), + dbc.ModalHeader(dbc.ModalTitle(guitr.application_text[language_id][2])), dbc.ModalBody(generate_eurad_scen_output_body(language_id)), - dbc.ModalFooter([dbc.Button(f"{close_label[language_id]}", id="eurad_scen_result_modal_close", + dbc.ModalFooter([dbc.Button(f"{guitr.close_label[language_id]}", id="eurad_scen_result_modal_close", class_name="fzj_style_btn", n_clicks=0) ]), ], @@ -586,12 +461,12 @@ def generate_eurad_scen_result_modal(container_id="eurad_scen_result_modal_conta def create_jobs_tab(language_id=0): modal_list = [ - {"name": application_text[language_id][0], "id": "eurad_im", "body": generate_eurad_im_body(language_id), - "description": description_text[language_id][0], "icon": "Icon1_FieldForecasting_small.png"}, - {"name": application_text[language_id][1], "id": "ml_fcast", "body": generate_ml_fcast_body(language_id), - "description": description_text[language_id][1], "icon": "Icon2_PointForecasting_small.png"}, - {"name": application_text[language_id][2], "id": "eurad_scen", "body": generate_eurad_scen_body(language_id), - "description": description_text[language_id][2], "icon": "Icon3_EmissionScenarios_small.png"}, + {"name": guitr.application_text[language_id][0], "id": "eurad_im", "body": generate_eurad_im_body(language_id), + "description": guitr.description_text[language_id][0], "icon": "Icon1_FieldForecasting_small.png"}, + {"name": guitr.application_text[language_id][1], "id": "ml_fcast", "body": generate_ml_fcast_body(language_id), + "description": guitr.description_text[language_id][1], "icon": "Icon2_PointForecasting_small.png"}, + {"name": guitr.application_text[language_id][2], "id": "eurad_scen", "body": generate_eurad_scen_body(language_id), + "description": guitr.description_text[language_id][2], "icon": "Icon3_EmissionScenarios_small.png"}, ] return html.Div([ @@ -627,10 +502,10 @@ def create_jobs_tab(language_id=0): ), dbc.ModalFooter([ dbc.Button( - f"{run_label[language_id]}", id=f"{modal['id']}_run", class_name="fzj_style_btn", n_clicks=0 + f"{guitr.run_label[language_id]}", id=f"{modal['id']}_run", class_name="fzj_style_btn", n_clicks=0 ), dbc.Button( - f"{close_label[language_id]}", id=f"{modal['id']}_close", class_name="fzj_style_btn", n_clicks=0 + f"{guitr.close_label[language_id]}", id=f"{modal['id']}_close", class_name="fzj_style_btn", n_clicks=0 ) ]), ], @@ -651,7 +526,7 @@ def create_jobs_tab(language_id=0): def create_description_content(language_id): return dbc.Card( dbc.CardBody( - description[language_id] + guitr.description[language_id] ), class_name="mt-3", ) @@ -662,17 +537,20 @@ def get_my_jobs_from_db(user_id=None, language_id=0): if user_id: conn = sqlite3.connect(DATA_PATH.joinpath('destine_de370c_users.db')) cur = conn.cursor() - cur.execute(f"SELECT application, status, start_date, forecast_length, region, creation_date, id FROM jobs WHERE user_id={user_id}") + cur.execute(f"SELECT application, status, start_date, forecast_length, region, species, metric, emis_scen, creation_date, id FROM jobs WHERE user_id={user_id}") data_rows_from_db = cur.fetchall() for job in data_rows_from_db: - data_from_db.append({jobs_columns[language_id][0]: application_text[language_id][job[0]], - jobs_columns[language_id][1]: status_text[language_id][job[1]], - jobs_columns[language_id][2]: dt.datetime.strptime(job[2],'%Y-%m-%d %H:%M').strftime(date_format2[language_id]), - jobs_columns[language_id][3]: "{} {}{}".format(job[3], day_label[language_id], day_plural_label[language_id] if job[3] > 1 else ""), - jobs_columns[language_id][4]: region_text[language_id][job[4]], - jobs_columns[language_id][5]: dt.datetime.strptime(job[5],'%Y-%m-%d %H:%M').strftime(date_format2[language_id]), - jobs_columns[language_id][6]: job[6]}) + data_from_db.append({guitr.jobs_columns[language_id][0]: guitr.application_text[language_id][job[0]], + guitr.jobs_columns[language_id][1]: guitr.status_text[language_id][job[1]], + guitr.jobs_columns[language_id][2]: dt.datetime.strptime(job[2],'%Y-%m-%d %H:%M').strftime(guitr.date_format2[language_id]), + guitr.jobs_columns[language_id][3]: "{} {}{}".format(job[3], guitr.day_label[language_id], guitr.day_plural_label[language_id] if job[3] > 1 else ""), + guitr.jobs_columns[language_id][4]: guitr.region_text[language_id][job[4]], + guitr.jobs_columns[language_id][5]: "{}".format(guitr.species_options[language_id][job[5]] if job[5] is not None else ""), + guitr.jobs_columns[language_id][6]: "{}".format(guitr.metrics_options[language_id][job[6]] if job[6] is not None else ""), + guitr.jobs_columns[language_id][7]: "{}".format(emis_info[language_id][" Name"][job[7]] if job[7] is not None else ""), + guitr.jobs_columns[language_id][8]: dt.datetime.strptime(job[8],'%Y-%m-%d %H:%M').strftime(guitr.date_format2[language_id]), + guitr.jobs_columns[language_id][9]: job[9]}) conn.close() return data_from_db @@ -684,7 +562,7 @@ def generate_jobs_table(user_id=None, language_id=0): dash_table.DataTable( id='tbl-interactive', columns=[ - {"name": i, "id": i} for i in jobs_columns[language_id] + {"name": i, "id": i} for i in guitr.jobs_columns[language_id] ], data=data_from_db, filter_action="native", @@ -726,10 +604,10 @@ def get_results_from_db(user_id=None, language_id=0): data_rows_from_db = cur.fetchall() for result in data_rows_from_db: - data_from_db.append({results_columns[language_id][0]: result[0], - results_columns[language_id][1]: result[2], - results_columns[language_id][2]: application_text[language_id][result[3]], - results_columns[language_id][3]: result[4]}) + data_from_db.append({guitr.results_columns[language_id][0]: result[0], + guitr.results_columns[language_id][1]: result[2], + guitr.results_columns[language_id][2]: guitr.application_text[language_id][result[3]], + guitr.results_columns[language_id][3]: result[4]}) conn.close() return data_from_db @@ -741,7 +619,7 @@ def generate_results_table(user_id=None, language_id=0): dash_table.DataTable( id='results-tbl-interactive', columns=[ - {"name": i, "id": i} for i in results_columns[language_id]], + {"name": i, "id": i} for i in guitr.results_columns[language_id]], data=data_from_db, style_header={"fontWeight": "bold"}, filter_action="native", @@ -759,22 +637,22 @@ def create_tabs_layout(user_id=None, language_id=0): lhide = False return dbc.Tabs([ # tab for "Description" - dbc.Tab(label=layout_cards[language_id][0], id="description_tab", children=[ + dbc.Tab(label=guitr.layout_cards[language_id][0], id="description_tab", children=[ create_description_content(language_id) ], tab_style={"font-size":"40px"}), # tab for "Create Jobs" - dbc.Tab(label=layout_cards[language_id][1], id="create_jobs_tab", children=[ + dbc.Tab(label=guitr.layout_cards[language_id][1], id="create_jobs_tab", children=[ create_jobs_tab(language_id) ], tab_style={"font-size":"40px"}, disabled=lhide), # tab for "My Jobs" - dbc.Tab(label=layout_cards[language_id][2], id="my_jobs_tab", children=[ + dbc.Tab(label=guitr.layout_cards[language_id][2], id="my_jobs_tab", children=[ generate_jobs_table(user_id=user_id, language_id=language_id), generate_eurad_im_output_modal(language_id=language_id), generate_ml_fcast_output_modal(language_id=language_id), generate_eurad_scen_output_modal(container_id="eurad_scen_output_modal_container", language_id=language_id) ], tab_style={"font-size":"40px"}, disabled=lhide), # tab for "Results" - dbc.Tab(label=layout_cards[language_id][3], id="results_tab", children=[ + dbc.Tab(label=guitr.layout_cards[language_id][3], id="results_tab", children=[ generate_results_table(user_id=user_id, language_id=language_id), eurad_im_result_modal, ml_fcast_result_modal, @@ -824,7 +702,7 @@ def login_open(lb_click, lc_click, name, password): db_password = fernet.decrypt(user[1]).decode() if db_password == password: language_id=user[2] - return create_login_button(f"{user_label[language_id]} {name}"), \ + return create_login_button(f"{guitr.user_label[language_id]} {name}"), \ '{"user_id": ' + f'{user[0]}, "language_id": {user[2]}' +'}', \ create_tabs_layout(user_id=user[0], language_id=language_id),\ False, no_update @@ -1035,13 +913,13 @@ def postprocess_job(rows, derived_virtual_selected_rows, users_dict): ml_fcast_output_modal_isopen = False eurad_scen_output_modal_isopen = False if derived_virtual_selected_rows != []: - status = rows[derived_virtual_selected_rows[0]][jobs_columns[language_id][1]] - application = rows[derived_virtual_selected_rows[0]][jobs_columns[language_id][0]] - jobnr = rows[derived_virtual_selected_rows[0]][jobs_columns[language_id][6]] - if status == status_text[language_id][0]: - eurad_im_output_modal_isopen = (application == application_text[language_id][0]) - ml_fcast_output_modal_isopen = (application == application_text[language_id][1]) - eurad_scen_output_modal_isopen = (application == application_text[language_id][2]) + status = rows[derived_virtual_selected_rows[0]][guitr.jobs_columns[language_id][1]] + application = rows[derived_virtual_selected_rows[0]][guitr.jobs_columns[language_id][0]] + jobnr = rows[derived_virtual_selected_rows[0]][guitr.jobs_columns[language_id][9]] + if status == guitr.status_text[language_id][0]: + eurad_im_output_modal_isopen = (application == guitr.application_text[language_id][0]) + ml_fcast_output_modal_isopen = (application == guitr.application_text[language_id][1]) + eurad_scen_output_modal_isopen = (application == guitr.application_text[language_id][2]) jobinfo_dict["jobnr"] = jobnr jobinfo_dict["eurad_im_output_modal_isopen"] = eurad_im_output_modal_isopen jobinfo_dict["ml_fcast_output_modal_isopen"] = ml_fcast_output_modal_isopen @@ -1120,11 +998,11 @@ def postprocess_result(rows, derived_virtual_selected_rows, user_dict): eurad_scen_output_modal_isopen = False jobnr = "bla" if derived_virtual_selected_rows != []: - application = rows[derived_virtual_selected_rows[0]][results_columns[language_id][2]] + application = rows[derived_virtual_selected_rows[0]][guitr.results_columns[language_id][2]] jobnr = rows[derived_virtual_selected_rows[0]]["Jobnr"] - eurad_im_output_modal_isopen = (application == application_text[language_id][0]) - ml_fcast_output_modal_isopen = (application == application_text[language_id][1]) - eurad_scen_output_modal_isopen = (application == application_text[language_id][2]) + eurad_im_output_modal_isopen = (application == guitr.application_text[language_id][0]) + ml_fcast_output_modal_isopen = (application == guitr.application_text[language_id][1]) + eurad_scen_output_modal_isopen = (application == guitr.application_text[language_id][2]) resultinfo_dict["jobnr"] = jobnr resultinfo_dict["eurad_im_output_modal_isopen"] = eurad_im_output_modal_isopen resultinfo_dict["ml_fcast_output_modal_isopen"] = ml_fcast_output_modal_isopen diff --git a/src/pages/dashboard_constants.py b/src/pages/dashboard_constants.py new file mode 100644 index 0000000000000000000000000000000000000000..5bf027e9b84aa32cbb42e8ab94a1d006e7ea1146 --- /dev/null +++ b/src/pages/dashboard_constants.py @@ -0,0 +1,5 @@ +import datetime as dt + +min_date_allowed=dt.date(2017, 1, 1) +max_date_allowed=dt.date(2018, 9, 1) +initial_visible_month=dt.date(2017, 1, 1) diff --git a/src/pages/dashboard_translations.py b/src/pages/dashboard_translations.py new file mode 100644 index 0000000000000000000000000000000000000000..0f3ad926c64b4cfc8ea2278ccb698749647d05b9 --- /dev/null +++ b/src/pages/dashboard_translations.py @@ -0,0 +1,123 @@ +from dash import html + +layout_cards = [["Description", "Create Forecasts", "My Model Runs", "My Results"], + ["Beschreibung", "Erstelle Vorhersagen", "Meine Modellläufe", "Meine Auswertungen"]] +description = [["The DestinE Air Quality Use Case demonstrates interactive triggering of advanced forecasting " + "and analysis workflows for air quality.", + html.Br(), + "The workflows are triggered by clicking on the buttons in the second tab.", + html.Br(), + "The results of the workflows are displayed in the third tab.", + html.Br(), + "The documentation of the use case can be found ", + html.A("here", href="https://www.fz-juelich.de/de/iek/iek-8/projekte/" + + "destination-earth-use-case-fuer-luftqualitaet-de370c")], + ["Der 'DestinE Air Quality Use Case' (Anwendungsfall) demonstriert die interaktive Auslösung " + "fortgeschrittener Vorhersage- und Analyse-Workflows für die Luftqualität.", + html.Br(), + "Die Workflows werden durch Klicken auf die Schaltflächen im zweiten Reiter ausgelöst.", + html.Br(), + "Die Ergebnisse der Workflows werden auf der dritten Registerkarte angezeigt.", + html.Br(), + "Die Dokumentation des Anwendungsfalls finden Sie ", + html.A("hier", href="https://www.fz-juelich.de/de/iek/iek-8/projekte/" + + "destination-earth-use-case-fuer-luftqualitaet-de370c")]] +jobs_columns = [["Application", "Status", "Start date", "Forecast Length", "Region", "Species", "Metric", "Emission Scenario", "Creation Date", "Jobnr"], + ["Anwendung", "Status", "Startdatum", "Vorhersagedauer", "Region", "Spezies", "Metrik", "Emissionsszenario", "Erstellungsdatum", "Jobnr"]] +results_columns = [["Result_ID", "Jobnr", "Application", "Used Options"], + ["Resultats_ID", "Jobnr", "Anwendung", "Verwendete Optionen"]] + +# The following lists should be created once from the controlled vocabulary +status_text = [["finished", "active", "waiting", "aborted"], + ["beendet", "aktiv", "in der Warteschlange", "abgebrochen"]] +application_text = [["Field forecasting with EURAD-IM", "Point forecasting with MLAir", "EURAD-IM emission scenarios"], + ["Gebietsvorhersage mit EURAD-IM", "Stationsvorhersage mit MLAir", "EURAD-IM Emissionsszenarien"]] +region_text = [["North Rhine-Westphalia", "Berlin-Brandenburg"], + ["Nordrhein-Westfalen", "Berlin-Brandenburg"]] +description_text = [["This application produces high-resolution, i.e. 1 km or less, on-demand results over a " + + "user-selected area for a forecast period of up to 4 days. Here, users can select the forecast " + + "start date (default today) and the forecast length (shorter runs require less time and " + + "resources), and the regional domain of the simulation. There are two EURAD-IM model " + + "configurations applied in the background of this application: i) the default 9 km resolution " + + "model covering all of Europe, and ii) region-specific 1 km configurations, initially limited " + + "to North Rhine-Westphalia and Brandenburg. Users can select whether they wish to perform a " + + "dedicated 1 km EURAD-IM simulation, or whether the 1 km results shall be obtained with ML " + + "downscaling from the results of a 9 km simulation. For more information about EURAD-IM and ML " + + "downscaling, please refer to the description tab.", + "This application concerns point forecasts of air quality at (German) measurement stations " + + "with the MLAir tool. This workflow makes use of the TOAR database infrastructure that is " + + "operated at JSC (https://toar-data.fz-juelich.de) and uses data from the continuous Digital " + + "Twin (DT) as meteorological inputs. Users can select a forecast a start time and a region, and " + + "the tool will then generate forecasts for all stations in the given region. Users can also " + + "select the species of interest and the air quality metric that shall be computed. Initial " + + "settings for these parameters are ozone and 'MDA8', i.e. the maximum daily 8-hour average " + + "value. For more information about MLAir, please refer to the description tab.", + "This application, which can be directly applied for decision making, triggers an EURAD-IM " + + "ensemble simulation with modified emission scenarios. This allows for the assessment of the " + + "effectiveness of different air pollution mitigation strategies. User choices are similar to " + + "the field forecast application, except that users will also have to choose the scenario they " + + "wish to employ. For more information about EURAD-IM emissions, please refer to the description " + + "tab."], + ["Diese Anwendung erzeugt hochauflösende, d.h. 1 km oder weniger, On-Demand-Ergebnisse über ein " + + "vom Benutzer ausgewähltes Gebiet für einen Vorhersagezeitraum von bis zu 4 Tagen. Dabei können " + + "die Nutzer das Startdatum der Vorhersage (standardmäßig heute) und die Vorhersagelänge " + + "(kürzere Läufe erfordern weniger Zeit und Ressourcen) sowie den regionalen Bereich der " + + "Simulation auswählen. Im Hintergrund dieser Anwendung werden zwei " + + "EURAD-IM-Modellkonfigurationen verwendet: i) das Standardmodell mit 9 km Auflösung, das ganz " + + "Europa abdeckt, und ii) regionalspezifische 1 km-Konfigurationen, die zunächst auf " + + "Nordrhein-Westfalen und Brandenburg beschränkt sind. Der Benutzer kann dann wählen, ob er eine " + + "eigene 1 km EURAD-IM-Simulation durchführen möchte oder ob die 1 km-Ergebnisse durch " + + "ML-Downscaling aus den Ergebnissen einer 9 km-Simulation gewonnen werden sollen. Weitere Details " + + "über EURAD-IM finden sich unter 'Beschreibung'.", + "Diese Anwendung betrifft Punktvorhersagen der Luftqualität an (deutschen) Messstationen mit dem " + + "MLAir-Tool. Sie nutzt die TOAR-Datenbankinfrastruktur, die beim JSC " + + "(https://toar-data.fz-juelich.de) betrieben wird, und verwendet Daten aus dem kontinuierlichen " + + "digitalen Zwilling (Digital Twin -- DT) als meteorologische Eingaben. Der Benutzer kann eine " + + "Startzeit für die Vorhersage und eine Region auswählen, woraufhin das Tool Vorhersagen für " + + "alle Stationen in der jeweiligen Region erstellt. Die Benutzer können auch die interessierende " + + "Spezies und die zu berechnende Luftqualitätsmetrik auswählen. Die Grundeinstellungen für diese " + + "Parameter sind Ozon und 'MDA8', d. h. der maximale 8-Stunden-Tagesmittelwert. Weitere " + + "Informationen über MLAir finden sich im Beschreibungs-Tab.", + "Diese Anwendung löst eine " + + "EURAD-IM-Ensemblesimulation mit veränderten Emissionsszenarien aus. Dies ermöglicht die " + + "Bewertung der Wirksamkeit verschiedener Strategien zur Verringerung der Luftverschmutzung. Die " + + "Auswahlmöglichkeiten des Benutzers sind ähnlich wie bei der Feldvorhersageanwendung, außer " + + "dass der Benutzer auch das Szenario auswählen muss, das er verwenden möchte. Weitere " + + "Informationen über EURAD-IM Emissionen finden sich im Beschreibungs-Tab."]] +user_label = ["user:", "Benutzer:"] +run_label = ["run", "Starten"] +run2_label = ["Run", "Lauf"] +close_label = ["close", "Schließen"] +date_label = ["date:", "Datum:"] +date_format = ["M/D/Y", "D.M.Y"] +date_format2 = ['%Y-%m-%d %H:%M', '%d.%m.%Y %H:%M'] +first_day_of_week = [0, 1] +forecast_length_label = ["forecast length", "Vorhersagedauer"] +region_label = ["region:", "Region:"] +forecast_length_options = [["4 days", "3 days", "2 days", "1 day"], + ["4 Tage", "3 Tage", "2 Tage", "1 Tag"]] +output_format_options = [["raw model output", "2D plots", "time series"], + ["Rohmodellausgabe", "2D-Diagramme", "Zeitreihen"]] +state_label = ["state:", "Bundesland:"] +species_label = ["species:", "Spezies:"] +output_metrics_label = ["output metrics:", "Ausgabemetrik:"] +species_options = [["ozone", "NO", "NO2", "PM2.5"], + ["Ozon", "Stickstoffmonoxid", "Stickstoffdioxid", "Feinstaub (PM2.5)"]] +metrics_options = [["dma8eu", "mean"], + ["dma8eu", "Mittelwert"]] +emis_scen_label = ["emission scenario:", "Emissionsszenario:"] +help_metrics_label = ["Help on metrics", "Hilfe zu Ausgabemetriken"] +help_emissions_label = ["Help on emission scenarios", "Hilfe zu Emissions-Szenarien"] +map_select_label = ["Select on map", "auf Karte auswählen"] +time_step_label = ["Time step", "Zeitschritt"] +start_date_label = ["Start date", "Startdatum"] +location_label = ["Location", "Ort"] +day_label = ["day", "Tag"] +day_plural_label = ["s", "e"] +save_label = ["Save Results", "Ergebnisse sichern"] +download_label = ["Download Data", "Daten herunterladen"] +im_download_label = ["Download Plots", "Plots herunterladen"] +downscaling_label = ["Postprocessing with ML-Downscaling", "Postprocessing mit ML-Downscaling"] +show_downscaling_label = ["Show results with ML downscaling", "Ergebnisse mit ML-Downscaling anzeigen"] +out_option_label = ["output option", "Ausgabe-Option"] +