Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions dashboard/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ def update(
opt_manager = OptimizationManager(mod_manager)
# reset parameters
if reset_parameters:
par_manager = ParametersManager(mod_manager, input_variables)
par_manager = ParametersManager(
mod_manager, input_variables, simulation_calibration
)
elif reset_model:
# if resetting only model, model attribute must be updated
par_manager.model = mod_manager
Expand Down Expand Up @@ -105,11 +107,11 @@ def update(
ctrl.figure_update(fig)


@state.change("experiment")
@state.change("experiment", "displayed_inputs")
def update_on_change_experiment(**kwargs):
# skip if triggered on server ready (all state variables marked as modified)
if len(state.modified_keys) == 1:
print("Experiment changed...")
print("Reacting on state change...")
update(
reset_model=True,
reset_output=True,
Expand All @@ -127,7 +129,7 @@ def update_on_change_experiment(**kwargs):
def update_on_change_model(**kwargs):
# skip if triggered on server ready (all state variables marked as modified)
if len(state.modified_keys) == 1:
print("Model type changed...")
print("Reacting on state change...")
update(
reset_model=True,
reset_output=False,
Expand All @@ -154,7 +156,7 @@ def update_on_change_model(**kwargs):
def update_on_change_others(**kwargs):
# skip if triggered on server ready (all state variables marked as modified)
if len(state.modified_keys) == 1:
print("Parameters, opacity changed...")
print("Reacting on state change...")
update(
reset_model=False,
reset_output=False,
Expand All @@ -177,7 +179,7 @@ def find_simulation(event, db):
if len(documents) == 1:
this_point_parameters = {
parameter: documents[0][parameter]
for parameter in state.parameters.keys()
for parameter in state.parameters["exp"].keys()
if parameter in documents[0]
}
print(f"Clicked on data point ({this_point_parameters})")
Expand Down Expand Up @@ -286,10 +288,6 @@ def home_route():
vuetify.VTab("ML", value="ml_tab")
with vuetify.VWindow(v_model=("active_tab",), mandatory=True):
with vuetify.VWindowItem(value="parameters_tab"):
# output control panel
with vuetify.VRow():
with vuetify.VCol():
out_manager.panel()
# parameters control panel
with vuetify.VRow():
with vuetify.VCol():
Expand All @@ -316,8 +314,11 @@ def home_route():
with vuetify.VCol(cols=8):
with vuetify.VCard():
with vuetify.VCardTitle("Plots"):
param_family = (
"exp" if state.displayed_inputs == "Experiment" else "sim"
)
with vuetify.VContainer(
style=f"height: {400 * len(state.parameters)}px;"
style=f"height: {400 * len(state.parameters[param_family])}px;"
):
figure = plotly.Figure(
display_mode_bar="true",
Expand Down
21 changes: 11 additions & 10 deletions dashboard/calibration_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,17 @@ def convert(value, alpha, beta):
for value in state.simulation_calibration.values():
sim_name = value["name"]
exp_name = value["depends_on"]
# strip characters after '[' parenthesis to remove units, strip
# leading/trailing white spaces, replace white spaces and '-' with '_',
# and convert to lower case
sim_name = (
sim_name.split("[")[0]
.strip()
.replace(" ", "_")
.replace("-", "_")
.lower()
)
# FIXME
## strip characters after '[' parenthesis to remove units, strip
## leading/trailing white spaces, replace white spaces and '-' with '_',
## and convert to lower case
# sim_name = (
# sim_name.split("[")[0]
# .strip()
# .replace(" ", "_")
# .replace("-", "_")
# .lower()
# )
# fill the dictionary
if exp_name in exp_dict:
sim_dict[sim_name] = convert(
Expand Down
10 changes: 5 additions & 5 deletions dashboard/optimization_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def __init__(self, model):
def model_wrapper(self, parameters_array):
print("Wrapping model...")
# convert array of parameters to dictionary
parameters_dict = dict(zip(state.parameters.keys(), parameters_array))
parameters_dict = dict(zip(state.parameters["exp"].keys(), parameters_array))
# change sign to the result in order to maximize when optimizing
mean, lower, upper = self.__model.evaluate(
parameters_dict, state.optimization_target
Expand All @@ -28,12 +28,12 @@ def optimize(self):
# info print statement skipped to avoid redundancy
if self.__model is not None:
# get array of current parameters from state
parameters_values = np.array(list(state.parameters.values()))
parameters_values = np.array(list(state.parameters["exp"].values()))
# define parameters bounds for optimization
parameters_bounds = []
for key in state.parameters.keys():
for key in state.parameters["exp"].keys():
parameters_bounds.append(
(state.parameters_min[key], state.parameters_max[key])
(state.parameters_min["exp"][key], state.parameters_max["exp"][key])
)
# optimize model (maximize output value)
res = minimize(
Expand All @@ -44,7 +44,7 @@ def optimize(self):
)
print(f"Optimization result:\n{res}")
# update parameters in state with optimal values
state.parameters = dict(zip(state.parameters.keys(), res.x))
state.parameters["exp"] = dict(zip(state.parameters["exp"].keys(), res.x))
# push again at flush time
state.dirty("parameters")
# Force flush now (TODO fix state change listeners, remove workaround)
Expand Down
17 changes: 0 additions & 17 deletions dashboard/outputs_manager.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from trame.widgets import vuetify3 as vuetify

from state_manager import state


Expand All @@ -9,18 +7,3 @@ def __init__(self, output_variables):
# define state variables
state.output_variables = [v["name"] for v in output_variables.values()]
state.displayed_output = state.output_variables[0]

def panel(self):
print("Setting output card...")
with vuetify.VExpansionPanels(v_model=("expand_panel_control_output", 0)):
with vuetify.VExpansionPanel(
title="Control: Displayed Output",
style="font-size: 20px; font-weight: 500;",
):
with vuetify.VExpansionPanelText():
with vuetify.VRow():
vuetify.VSelect(
v_model=("displayed_output",),
items=(state.output_variables,),
dense=True,
)
98 changes: 74 additions & 24 deletions dashboard/parameters_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@


class ParametersManager:
def __init__(self, model, input_variables):
def __init__(self, model, input_variables, simulation_calibration):
print("Initializing parameters manager...")
# save model
self.__model = model
# define state variables
state.parameters = dict()
state.parameters_min = dict()
state.parameters_max = dict()
state.parameters_show_all = dict()
self.parameters_step = dict()
state.parameters = {"exp": {}, "sim": {}}
state.parameters_min = {"exp": {}, "sim": {}}
state.parameters_max = {"exp": {}, "sim": {}}
state.parameters_show_all = {"exp": {}, "sim": {}}
self.parameters_step = {"exp": {}, "sim": {}}
state.simulatable = (
self.simulation_scripts_base_path / "submission_script_single"
).is_file()
Expand All @@ -33,11 +33,29 @@ def __init__(self, model, input_variables):
pmin = float(parameter_dict["value_range"][0])
pmax = float(parameter_dict["value_range"][1])
pval = float(parameter_dict["default"])
state.parameters[key] = pval
state.parameters_min[key] = pmin
state.parameters_max[key] = pmax
state.parameters_show_all[key] = False
self.parameters_step[key] = (pmax - pmin) / 100
state.parameters["exp"][key] = pval
state.parameters_min["exp"][key] = pmin
state.parameters_max["exp"][key] = pmax
state.parameters_show_all["exp"][key] = False
self.parameters_step["exp"][key] = (pmax - pmin) / 100
# store simulation parameters converted from experimental ones
sim_cal = SimulationCalibrationManager(simulation_calibration)
state.parameters["sim"] = sim_cal.convert_exp_to_sim(state.parameters["exp"])
state.parameters_min["sim"] = sim_cal.convert_exp_to_sim(
state.parameters_min["exp"]
)
state.parameters_max["sim"] = sim_cal.convert_exp_to_sim(
state.parameters_max["exp"]
)
state.parameters_show_all["sim"] = {
key: False for key in state.parameters["sim"].keys()
}
self.parameters_step["sim"] = {
key: (state.parameters_max["sim"][key] - state.parameters_min["sim"][key])
/ 100
for key in state.parameters["sim"].keys()
}
# save initial parameters for reset
state.parameters_init = copy.deepcopy(state.parameters)

@property
Expand Down Expand Up @@ -77,7 +95,7 @@ async def simulation_kernel(self):
)
_, _, simulation_calibration = load_variables(state.experiment)
sim_cal = SimulationCalibrationManager(simulation_calibration)
sim_dict = sim_cal.convert_exp_to_sim(state.parameters)
sim_dict = sim_cal.convert_exp_to_sim(state.parameters["exp"])
with open(temp_file_path, "w") as temp_file:
yaml.dump(sim_dict, temp_file)
temp_file.flush()
Expand Down Expand Up @@ -155,8 +173,28 @@ def panel(self):
style="font-size: 20px; font-weight: 500;",
):
with vuetify.VExpansionPanelText():
with vuetify.VRow():
with vuetify.VCol():
vuetify.VSelect(
v_model=("displayed_inputs",),
items=(["Experiment", "Simulation"],),
dense=True,
label="Displayed inputs",
)
with vuetify.VCol():
vuetify.VSelect(
v_model=("displayed_output",),
items=(state.output_variables,),
dense=True,
label="Displayed output",
)
with client.DeepReactive("parameters"):
for count, key in enumerate(state.parameters.keys()):
param_family = (
"exp" if state.displayed_inputs == "Experiment" else "sim"
)
for count, key in enumerate(
state.parameters[param_family].keys()
):
# create a row for the parameter label
with vuetify.VRow():
vuetify.VListSubheader(
Expand All @@ -169,35 +207,43 @@ def panel(self):
)
with vuetify.VRow(no_gutters=True):
with vuetify.VSlider(
v_model_number=(f"parameters['{key}']",),
v_model_number=(
f"parameters['{param_family}']['{key}']",
),
change="flushState('parameters')",
hide_details=True,
min=(f"parameters_min['{key}']",),
max=(f"parameters_max['{key}']",),
min=(f"parameters_min['{param_family}']['{key}']",),
max=(f"parameters_max['{param_family}']['{key}']",),
step=(
f"(parameters_max['{key}'] - parameters_min['{key}']) / 100",
f"(parameters_max['{param_family}']['{key}'] - parameters_min['{param_family}']['{key}']) / 100",
),
style="align-items: center;",
):
with vuetify.Template(v_slot_append=True):
vuetify.VTextField(
v_model_number=(f"parameters['{key}']",),
v_model_number=(
f"parameters['{param_family}']['{key}']",
),
density="compact",
hide_details=True,
readonly=True,
single_line=True,
style="margin-top: 0px; padding-top: 0px; width: 100px;",
type="number",
)
step = self.parameters_step[key]
step = self.parameters_step[param_family][key]
with vuetify.VRow(no_gutters=True):
with vuetify.VCol():
vuetify.VTextField(
v_model_number=(f"parameters_min['{key}']",),
v_model_number=(
f"parameters_min['{param_family}']['{key}']",
),
change="flushState('parameters_min')",
density="compact",
hide_details=True,
disabled=(f"parameters_show_all['{key}']",),
disabled=(
f"parameters_show_all['{param_family}']['{key}']",
),
step=step,
__properties=["step"],
style="width: 100px;",
Expand All @@ -206,11 +252,15 @@ def panel(self):
)
with vuetify.VCol():
vuetify.VTextField(
v_model_number=(f"parameters_max['{key}']",),
v_model_number=(
f"parameters_max['{param_family}']['{key}']",
),
change="flushState('parameters_max')",
density="compact",
hide_details=True,
disabled=(f"parameters_show_all['{key}']",),
disabled=(
f"parameters_show_all['{param_family}']['{key}']",
),
step=step,
__properties=["step"],
style="width: 100px;",
Expand All @@ -220,7 +270,7 @@ def panel(self):
with vuetify.VCol(style="min-width: 100px;"):
vuetify.VCheckbox(
v_model=(
f"parameters_show_all['{key}']",
f"parameters_show_all['{param_family}']['{key}']",
False,
),
density="compact",
Expand Down
4 changes: 3 additions & 1 deletion dashboard/state_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,7 @@ def initialize_state():
# Errors management
state.errors = []
state.error_counter = 0
# Calibration toggles
# Calibration option
state.use_inferred_calibration = False
# Displayed inputs
state.displayed_inputs = "Experiment"
Loading