diff --git a/src/pages/dashboard.py b/src/pages/dashboard.py
index 97ffc9a35739a766ea028dd19cea84119488f75a..ff317a2499c7c15642e3ac637ce0d621e9c0fb3b 100644
--- a/src/pages/dashboard.py
+++ b/src/pages/dashboard.py
@@ -25,11 +25,12 @@ from deployment_settings import (
         UNICORE_BASE, UFTP_BASE,
         UNICORE_USER, UNICORE_PASSWORD
         )
-from utils import transfer_results_from_HPC
+from utils import transfer_results_from_HPC, get_filenames
 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()
 IMAGE_PATH = APP_HOME.joinpath("static", "images")
@@ -505,8 +506,9 @@ def generate_eurad_im_output_body(language_id, context, jobnr):
     dbc.Row([
         dbc.Col(html.Br(), width=12),
         dbc.Col([
-            dbc.Button(f"{guitr.ml_download_label[language_id]}", id="ml_downscaling_data_download",
-                       n_clicks=0, class_name="fzj_style_btn"),
+                 html.Div([dbc.Button(f"{guitr.ml_download_label[language_id]}", id="ml_downscaling_data_download",
+                                      n_clicks=0, class_name="fzj_style_btn"),
+                           dcc.Download(id="ml_downscaling_download_result")]),
         ], width=12),
         dbc.Col([
             dbc.Label(f"{guitr.ml_download_explanation[language_id]}", id="ml_download_explanation",
@@ -613,7 +615,7 @@ def generate_eurad_scen_output_body(language_id, context, jobnr):
         ], 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-em-{}'.format(context)), 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"{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"),
@@ -640,8 +642,9 @@ def generate_eurad_scen_output_body(language_id, context, jobnr):
         dbc.Row([
             dbc.Col(html.Br(), width=12),
             dbc.Col([
-                dbc.Button(f"{guitr.ml_download_label[language_id]}", id="ml_downscaling_em_data_download",
-                           n_clicks=0, class_name="fzj_style_btn"),
+                 html.Div([dbc.Button(f"{guitr.ml_download_label[language_id]}", id="ml_downscaling_data_download",
+                                      n_clicks=0, class_name="fzj_style_btn"),
+                           dcc.Download(id="ml_downscaling_download_result")]),
         ], width=12),
             dbc.Col([
                 dbc.Label(f"{guitr.ml_download_explanation[language_id]}",
@@ -650,16 +653,6 @@ def generate_eurad_scen_output_body(language_id, context, jobnr):
     ], class_name="row mt-3f"),
 ]
 
-@callback(
-    Output('ml_downscaling_em_data_download', 'disabled'),
-    [Input('variable-dropdown-em-output', 'value')]
-)
-def update_button_disabled(selected_option):
-    if selected_option == 'O3' or selected_option == 'NO2':
-        return False
-    else:
-        return True
-
 
 def generate_eurad_scen_body(language_id):
     disabled_days = [ dt.datetime.strptime('2017-01-27','%Y-%m-%d') + dt.timedelta(days=i) for i in range(14) ]
@@ -1307,6 +1300,50 @@ def mlair_plots_download(download_button, job_dict, plot_dict):
     )
 
 
+@callback(
+    Output("ml_downscaling_download_result", "data"),
+    Input("ml_downscaling_data_download", "n_clicks"),
+    [State("job-info", "data"),
+     State("plot-info", "data")],
+    prevent_initial_call=True
+)
+def ml_downscaling_output_download(download_button, job_dict, plot_dict):
+    jobnr = json.loads(job_dict)["jobnr"]
+    variable = json.loads(plot_dict)["variable"].lower()
+    variable = 'nox' if (variable == 'no2') else variable
+    infile = str(DATA_PATH.joinpath(f'downscaling_{variable}_{jobnr}.nc'))
+
+    # check, whether results for THIS job are already there
+    if not os.path.isfile(infile):
+
+        # check, whether results from ANOTHER job with the same parameters are already there
+        job_props = get_db_job_entry(jobnr)
+        start_date = job_props['start_date'][:10]
+        year, month, day = start_date.split('-')
+        iscen = job_props['emis_scen']
+        iscen = iscen if (iscen) else 0
+        fc_length = job_props['forecast_length']
+        out_filenames = get_filenames(jobnr, year, month, day, iscen, fc_length)
+        downscaling_fn = out_filenames["downscaling_filename"].format(variable=variable)
+        downscaling_filename = str(DATA_PATH.joinpath(f'{downscaling_fn}'))
+
+        if not os.path.isfile(downscaling_filename):
+
+            # submit downscaling job
+            base_url = f"{UNICORE_BASE}JURECA/rest/core"
+            credentials = uc_credentials.UsernamePassword(UNICORE_USER, UNICORE_PASSWORD)
+            client = uc_client.Client(credentials, base_url)
+            job_description = {'Executable': f"/p/project/deepacf/intelliaq/schroeder5/downscaling_maelstrom/HPC_batch_scripts/inference_destine_test_{variable}.sh",
+                               'Arguments': [ f"{jobnr.upper()}/CTM/", year, month, day ] }
+            job = client.new_job(job_description)
+        else:
+            os.symlink(downscaling_filename, infile)
+
+    return dcc.send_file(
+        infile
+    )
+
+
 @callback(
     Output("eurad_im_download_result", "data"),
     Input("eurad_im_output_download", "n_clicks"),
diff --git a/utils/utils.py b/utils/utils.py
index 89e04c3896b13f82da4df5bf67d2dc98ae1b8dd2..51ac43637bfe2e9dfe0d5c6e036acaf42156baaa 100644
--- a/utils/utils.py
+++ b/utils/utils.py
@@ -18,15 +18,17 @@ def get_filenames(jobnr, yy, mm, dd, iscen, fc_length):
     if iscen != 0:
         runid = f"digitwin{iscen:03}"
 
-    remote_filename = f"ctmout_{runid}_cutcropped_{timestep_date.strftime('%j')}_de3.nc"
-    download_filename = f"ctmout_{runid}_cutcropped_{fc_length*24}_{yy}_{timestep_date.strftime('%j')}_de3.nc"
-    base_remote_filename = f"ctmout_{baseid}_cutcropped_{timestep_date.strftime('%j')}_de3.nc"
-    base_download_filename = f"ctmout_{baseid}_cutcropped_{fc_length*24}_{yy}_{timestep_date.strftime('%j')}_de3.nc"
+    remote_filename = f"ctmout_{runid}_{timestep_date.strftime('%j')}_de3_cutcropped.nc"
+    download_filename = f"ctmout_{runid}_{fc_length*24}_{yy}_{timestep_date.strftime('%j')}_de3_cutcropped.nc"
+    base_remote_filename = f"ctmout_{baseid}_{timestep_date.strftime('%j')}_de3_cutcropped.nc"
+    base_download_filename = f"ctmout_{baseid}_{fc_length*24}_{yy}_{timestep_date.strftime('%j')}_de3_cutcropped.nc"
+    downscaling_filename = f"downscaling_{{variable}}_{runid}_{fc_length*24}_{yy}_{timestep_date.strftime('%j')}_de3.nc"
 
     filenames = { "remote_filename": remote_filename,
                   "download_filename": download_filename,
                   "base_remote_filename": base_remote_filename,
-                  "base_download_filename": base_download_filename }
+                  "base_download_filename": base_download_filename,
+                  "downscaling_filename": downscaling_filename }
     return filenames