Skip to content
Snippets Groups Projects
Commit 35424baf authored by Maryshca's avatar Maryshca
Browse files

fix and add map to config

parent 7b54db99
No related branches found
No related tags found
No related merge requests found
......@@ -235,7 +235,11 @@ def write_namespace(file, ns, ns_name, indent):
if isinstance(ns[key], dict):
write_namespace(file, ns[key], key, indent + 4)
else:
file.write(" " * (indent + 4) + f"{key} = {get_str_from_value(ns[key].value, ns[key].value_type)};\n")
if ns[key].comment:
line = " " * (indent + 4) + f"{key} = {get_str_from_value(ns[key].value, ns[key].value_type)}; # {ns[key].comment}\n"
else:
line = " " * (indent + 4) + f"{key} = {get_str_from_value(ns[key].value, ns[key].value_type)};\n"
file.write(line)
file.write(" " * indent + "}\n")
file.write("\n")
......@@ -248,7 +252,11 @@ def dump_config(config, file_path):
if isinstance(config_nested[key], dict):
write_namespace(file, config_nested[key], key, indent)
else:
file.write(f"{key} = {get_str_from_value(config_nested[key].value, config_nested[key].value_type)};\n")
if config_nested[key].comment:
line = f"{key} = {get_str_from_value(config_nested[key].value, config_nested[key].value_type)}; # {config_nested[key].comment}\n"
else:
line = f"{key} = {get_str_from_value(config_nested[key].value, config_nested[key].value_type)};\n"
file.write(line)
if __name__ == '__main__':
......
......@@ -6,6 +6,15 @@ from style_constants import SPACE, COLLAPSING_HEADERS_UI
from style import get_accent_color, apply_theme
from config import load_config, dump_config, ConfigParserError
from dynamic_ui import construct_config_ui, construct_model_output_structure_ui
from map_edit_callbacks import open_map
def show_map_window_clb(s, a, u):
if get_config_file_path():
config = get_config()
if 'topography.filename' in config:
filename = config['topography.filename'].value
open_map(filename)
dpg.show_item('map_window')
def set_file_path_clb(s, a, u):
file_path = a['file_path_name']
......
......@@ -14,7 +14,7 @@ def construct_main_window_ui():
dpg.add_menu_item(label='save\t\t', shortcut='ctrl+s', callback=config_save_clb, tag='save_config')
dpg.add_menu_item(label='save as\t\t', shortcut='ctrl+shift+s', callback=open_config_save_as_dialog_clb, tag='open_config_save_as_dialog')
dpg.add_menu_item(label='map', callback=lambda: dpg.show_item('map_window'))
dpg.add_menu_item(label='map', callback=show_map_window_clb)
dpg.add_menu_item(label='run', callback=lambda: dpg.show_item('run_window'))
with dpg.menu(label='view'):
......
import os
from config import CfgVar
ROAD_COLOR = (221, 161, 94, 255)
TREE_COLOR = (96, 108, 56, 255)
BUILDING_COLOR = (188, 108, 37, 255)
EMISSION_POINT_COLOR = (255, 0, 0, 255)
TABS_UI = 'tabs_ui'
COLLAPSING_HEADERS_UI = 'collapsing_headers_ui'
WIDGET_WIDTH = 300
XOFFSET = 300
LCZS = ['compact_high_rise', 'compact_low_rise', 'compact_mid_rise', 'heavy_industry', 'large_low_rise', 'lightweight_low_rise', 'open_high_rise', 'open_low_rise', 'open_mid_rise', 'sparsley_build']
MAX_MAP_WIDTH = 2000
MAX_MAP_HEIGHT = 2000
EMISSION_POINT_CONFIG_VARIABLES = {
'value': CfgVar(key='value', value=28481176.531511, value_type='DOUBLE', comment=''),
'begin': CfgVar(key='begin', value=25200.0, value_type='DOUBLE', comment='[s]'),
'xpos': CfgVar(key='xpos', value=200.0, value_type='DOUBLE', comment='[m]'),
'ypos': CfgVar(key='ypos', value=200.0, value_type='DOUBLE', comment='[m]'),
'zpos': CfgVar(key='zpos', value=60.0, value_type='DOUBLE', comment='[m]'),
'sx': CfgVar(key='sx', value=20.0, value_type='DOUBLE', comment='[m]'),
'sy': CfgVar(key='sy', value=20.0, value_type='DOUBLE', comment='[m]'),
'sz': CfgVar(key='sz', value=10.0, value_type='DOUBLE', comment='[m]')
}
UIS = [TABS_UI, COLLAPSING_HEADERS_UI]
FONT_PATH = os.path.join('fonts', 'Montserrat-Medium.ttf')
ICON_PATH = os.path.join('icons', 'icon.ico')
FONT_SIZE = 24
ACCENT_COLOR = (0, 119, 200, 100)
ROUNDING = 10
SPACE = 10
INDENT = 40
BORDER = 3
TEXT = (0, 1)
ACCENT = (5, 18, 19, 20, 15, 16, 35, 37, 34, 23, 22, 25, 26, 27, 28, 29, 10, 11, 12, 30, 31, 32, 49, 50)
PRIMARY = (2, 3, 39)
SECONDARY = (36, 33, 21, 24, 4, 7, 8, 9, 13, 14)
APPLY_ALPHA = (22, 25, 31, 34, 16)
COLOR_TYPE_TO_DPG_ITEM = {
'TEXT': (0, 1),
'PRIMARY': (2, 3, 39),
'SECONDARY': (36, 33, 21, 24, 4, 7, 8, 9, 13, 14),
'ACCENT': (5, 18, 19, 20, 15, 16, 35, 37, 34, 23, 22, 25, 26, 27, 28, 29, 10, 11, 12, 30, 31, 32, 49, 50)}
COLOR_TO_COLOR_TYPE = {0: 'TEXT', 1: 'TEXT', 2: 'PRIMARY', 3: 'PRIMARY', 39: 'PRIMARY', 36: 'SECONDARY', 21: 'SECONDARY', 24: 'SECONDARY', 4: 'SECONDARY', 7: 'SECONDARY', 8: 'SECONDARY', 9: 'SECONDARY', 13: 'SECONDARY', 33: 'SECONDARY', 14: 'SECONDARY', 35: 'ACCENT', 20: 'ACCENT', 37: 'ACCENT', 22: 'ACCENT', 23: 'ACCENT', 5: 'ACCENT', 25: 'ACCENT', 26: 'ACCENT', 27: 'ACCENT', 28: 'ACCENT', 29: 'ACCENT', 10: 'ACCENT', 30: 'ACCENT', 11: 'ACCENT', 31: 'ACCENT', 12: 'ACCENT', 32: 'ACCENT', 49: 'ACCENT', 34: 'ACCENT', 15: 'ACCENT', 50: 'ACCENT', 16: 'ACCENT', 18: 'ACCENT', 19: 'ACCENT', 1: 'TEXT'}
BLUE = {
'enabled': {
'TEXT': (255, 255, 255, 255),
'PRIMARY': (37, 37, 38, 255),
'SECONDARY': (51, 51, 55, 255),
'ACCENT': (0, 119, 200, 153)
},
'disabled': {
'TEXT': (255, 255, 255, 150),
'PRIMARY': (37, 37, 38, 255),
'SECONDARY': (51, 51, 55, 255),
'ACCENT': (0, 119, 200, 153)
},
}
ORANGE = {
'enabled': {
'TEXT': (255, 255, 255, 255),
'PRIMARY': (37, 37, 38, 255),
'SECONDARY': (51, 51, 55, 255),
'ACCENT': (251, 133, 0, 153)
},
'disabled': {
'TEXT': (255, 255, 255, 150),
'PRIMARY': (37, 37, 38, 255),
'SECONDARY': (51, 51, 55, 255),
'ACCENT': (251, 133, 0, 153)
},
}
THEMES = {
'blue': BLUE,
'orange': ORANGE
}
\ No newline at end of file
......@@ -55,7 +55,7 @@ def construct_config_ui(config_file_path, config):
else:
construct_config_ui_collapsing_headers(config_file_path, config)
def add_item_to_config_ui(full_path):
def add_item_to_config_ui(full_path, before=None):
config_file_path = get_config_file_path()
config = get_config()
if get_current_ui_type() == TABS_UI:
......@@ -83,6 +83,9 @@ def add_item_to_config_ui(full_path):
path = config_file_path + '.' + '.'.join(namespaces[:level+1])
if not dpg.does_item_exist(path):
if before:
dpg.add_collapsing_header(label=namespaces[level], parent=parent, tag=path, indent=INDENT, before=before)
else:
dpg.add_collapsing_header(label=namespaces[level], parent=parent, tag=path, indent=INDENT)
parent = path
......
......@@ -9,6 +9,43 @@ from map_edit import dump_height_map, load_height_map, update_texture
from generator import LCZ
from paths import BASE_PATH
from utils import show_message, set_main_window_value, get_config, get_config_file_path, delete_item_and_clear_alias, delete_item_children_and_clear_aliases, set_map_window_value, get_map_window_value, get_height_map_file_path
from dynamic_ui import add_item_to_config_ui
from config import CfgVar
def add_map_to_config_clb(s, a, u):
if not get_config_file_path():
return
config = get_config()
keys = []
prev_key = ''
before = None
for key in config:
if 'topography' in key:
keys.append(key)
elif 'topography' in prev_key:
before = key.split('.')[0]
break
prev_key = key
for key in keys:
del config[key]
set_main_window_value('config', config)
delete_item_children_and_clear_aliases(f'{get_config_file_path()}.topography')
config['topography.mode'] = CfgVar(key='mode', value='ascii-mask')
config['topography.filename'] = CfgVar(key='filename', value=get_height_map_file_path())
add_item_to_config_ui('topography.mode', before=f'{get_config_file_path()}.{before}')
add_item_to_config_ui('topography.filename', before=dpg.last_item())
dump_height_map(get_map_window_value('buildings_map'), get_height_map_file_path())
def delete_emission_point_clb(s, a, u):
n = dpg.get_item_user_data('emission_settings_window')
......@@ -66,7 +103,7 @@ def clear_map():
dpg.set_item_user_data('map_window', settings)
def map_window_on_close_clb(s, a, u):
clear_map()
pass
def construct_map_layers(w, h):
dpg.set_item_width('map_child_window', w)
......@@ -121,13 +158,15 @@ def map_open_layer_clb(s, a, u):
dpg.draw_image(f'map_{layer}_texture', color=LAYER_TO_COLOR[layer], tag=f'map_{layer}_image', pmin=(0, 0), pmax=(w, h), parent=f'map_drawlist')
layer_old = dpg.get_value('layer')
dpg.set_value('layer', layer)
update_texture()
def map_open_clb(s, a, u):
height_map_file_path = a['file_path_name']
dpg.set_value('layer', layer_old)
def open_map(height_map_file_path):
if height_map_file_path.endswith('txt'):
try:
height_map = load_height_map(height_map_file_path)
......@@ -156,10 +195,14 @@ def map_open_clb(s, a, u):
construct_map_layers(w, h)
dpg.set_value('layer', 'buildings')
dpg.set_item_label('map_window', f'editing map {height_map_file_path}')
update_texture()
dpg.show_item('map_window')
def map_open_clb(s, a, u):
height_map_file_path = a['file_path_name']
open_map(height_map_file_path)
def generate_map_clb(s, a, u):
height_map = LCZ(config_path=os.path.join(BASE_PATH, 'configs', f'{s}.json')).to_height_map(dtype=np.float64)
......@@ -177,14 +220,14 @@ def generate_map_clb(s, a, u):
set_map_window_value('height_map_file_path', 'map.txt')
set_map_window_value('max_height', max_height)
dpg.set_item_label('map_window', f'editing map map.txt')
construct_map_layers(w, h)
dpg.set_value('layer', 'buildings')
update_texture()
dpg.show_item('map_window')
def save_map(file_path):
if file_path.endswith('.tif') or file_path.endswith('.tiff'):
with TiffWriter(file_path) as tif:
......
......@@ -69,7 +69,7 @@ def construct_map_edit_window():
dpg.add_menu_item(label=lcz_type, check=False, callback=combo_menu(generate_map_clb), tag=lcz_type)
dpg.add_menu_item(label='save', callback=map_save_clb, tag='map_save')
dpg.add_menu_item(label='save as', callback=open_map_save_as_dialog_clb, tag='open_map_save_as_dialog')
dpg.add_menu_item(label='add map to config', tag='add_map_to_config')
dpg.add_menu_item(label='add map to config', tag='add_map_to_config', callback=add_map_to_config_clb)
with dpg.group(horizontal=True):
with dpg.group(width=200, tag='tools'):
......
......@@ -81,7 +81,7 @@ class BuildingSession:
return ''
class RunningSession:
def __init__(self, connection, config_file_path, run_commands, executable_file_path, uuid=None):
def __init__(self, connection, config_file_path, run_commands, executable_file_path, uuid=None, upload_paths=dict()):
self.conn = connection
if uuid is not None:
self.uuid = uuid
......@@ -93,6 +93,10 @@ class RunningSession:
self.conn.exec_command(f'mkdir {self.uuid}; cp {self.executable_file_path} {self.uuid}/nsenx')
self.conn.upload(self.config_file_path, f'{self.uuid}/config.txt')
for path in upload_paths:
self.conn.upload(path, f'{self.uuid}/{upload_paths[path]}')
commands = [f'cd {self.uuid}'] + self.run_commands
self.stdout = self.conn.exec_command('; '.join(commands))
......
......@@ -13,7 +13,7 @@ from remote_run import Connection, BuildingSession, RunningSession
from remote_run_constants import *
from style_constants import FONT_SIZE
from dynamic_ui import construct_model_output_structure_ui
from config import dump_config
from config import dump_config, load_config
from style import get_accent_color
def update_run_model_window():
......@@ -78,6 +78,23 @@ def make_execute_command():
return command
def make_run_commands(running_session_id, executable_file_path, machine, model):
run_commands = []
folders = ['chem-forcing', 'chem-init', 'drag-configs', 'drag-forcing', 'meteo-forcing', 'meteo-init']
prefix = executable_file_path.split('/')[0] + '/nse-gabls1-urban-les'
for folder in folders:
path = f'{prefix}/{folder}'
run_commands.append(f'cp -r ../{path} {folder}')
if machine == LOMONOSOV:
run_commands += RUN_COMMANDS[(machine, model)] # + make_run_sh_for_slurm() + ['sbatch ./run.sh']
else:
run_commands += RUN_COMMANDS[(machine, model)] + [make_execute_command()]
return run_commands
def update_progress(running_session_id, output):
if not re.findall(r'([0-9]+)%', output):
progress = dpg.get_value(f'{running_session_id}_progress_bar')
......@@ -169,12 +186,25 @@ def run_model():
dpg.set_value(f'{running_session_id}_status', 'running')
if machine == LOMONOSOV:
run_commands = RUN_COMMANDS[(machine, model)] # + make_run_sh_for_slurm() + ['sbatch ./run.sh']
run_commands = make_run_commands(running_session_id, executable_file_path, machine, model)
upload_paths = dict()
if get_config_file_path():
config = get_config()
if 'topography.filename' in config:
upload_paths = {config['topography.filename'].value: config['topography.filename'].value}
else:
run_commands = RUN_COMMANDS[(machine, model)] + [make_execute_command()]
try:
config = load_config(config_file_path)
if 'topography.filename' in config:
upload_paths = {config['topography.filename'].value: config['topography.filename'].value}
except Exception as e:
show_message('bad file format')
return
running_session = RunningSession(conn, config_file_path, run_commands, executable_file_path, running_session_id)
running_session = RunningSession(conn, config_file_path, run_commands, executable_file_path, running_session_id, upload_paths=upload_paths)
if machine == LOMONOSOV:
output = running_session.output()
......@@ -223,10 +253,12 @@ def download_output():
dpg.hide_item('model_output_window')
dirs, filepaths, running_session_id = dpg.get_item_user_data('model_output_window')
download = []
download = set()
download_folders = set()
for filepath in filepaths:
if dpg.get_value(filepath):
download.append(filepath)
download.add(filepath)
download_folders.add('/'.join(filepath.split('/')[:-1]))
machine = LABEL_TO_MACHINE[dpg.get_value(f'{running_session_id}_machine')]
......@@ -236,7 +268,7 @@ def download_output():
prefix = os.path.join(download_to_folder)
construct_folder_structure(dirs, prefix=prefix)
construct_folder_structure(download_folders, prefix=prefix)
conn = get_run_window_value('connections')[machine]
......
......@@ -7,6 +7,20 @@ from remote_run_callbacks import *
from remote_run import *
def construct_remote_run_window():
if 'USE_BUILDS' in os.environ:
conn = {
LAB: Connection(LAB_HOST, os.getenv('SERVER_LOGIN', ''), os.getenv('SERVER_PASS', '')),
# LOMONOSOV: Connection(LOMONOSOV_HOST, os.getenv('LOMONOSOV_LOGIN'), id_rsa_path=os.getenv('ID_RSA_PATH', ''))
}
builds = {
(LAB, URBAN_LES): 'prebuild/code/nsenx',
# (LOMONOSOV, URBAN_LES): '6e094bc0-a5f6-4474-8c71-a2e3a90d8e85/build/nse-gabls1-urban-les'
}
user_data = {
'connections': conn,
'builds': builds
}
else:
user_data = {
'connections': dict(),
'builds': dict()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment