sensotwin.temperature_selection.ui
1import ipywidgets as widgets 2from . import configuration 3from . import style 4from .. import global_style 5from .. import store_connection 6import matplotlib.pyplot as plt 7import numpy as np 8 9class TemperatureSelectionUIElements: 10 """Contains all UI functionality of material curing process configuration UI (Step 1). 11 12 In order to use, show the top level widget 'self.dashboard' in one cell of a notebook 13 and the apply css styling calling 'self.apply_styling()' an another cell 14 """ 15 def __init__(self): 16 """Initialize UI objects and associated UI functionality.""" 17 self.dashboard = widgets.Tab().add_class("global_tab_container") 18 self.dashboard.children = [ 19 self.init_data_source_box(), 20 self.init_graph_input_box()] 21 tab_titles = ['Input', 'Simulation'] 22 for i in range(len(tab_titles)): 23 self.dashboard.set_title(i, tab_titles[i]) 24 25 def init_data_source_box(self) -> widgets.Box: 26 """Initialize first tab of dashboard, choosing data source.""" 27 local_database_label = widgets.Label(value="Use local owlready2 database:").add_class("global_headline") 28 use_local_data_button = widgets.Button( 29 description='Use local database', 30 disabled=False, 31 tooltip='Use local database', 32 icon='play', 33 ).add_class("global_load_data_button").add_class("global_basic_button") 34 use_local_data_button.on_click(self.load_local_data) 35 36 remote_database_label = widgets.Label(value="Use remote Apache Jena Fuseki database:").add_class("global_headline") 37 self.remote_database_input = widgets.Text( 38 value=None, 39 placeholder="insert SPARQL url here", 40 description="SPARQL Endpoint:", 41 disabled=False 42 ).add_class("global_url_input").add_class("global_basic_input") 43 use_remote_data_button = widgets.Button( 44 description='Use remote database', 45 disabled=False, 46 tooltip='Use remote database', 47 icon='play', 48 ).add_class("global_load_data_button").add_class("global_basic_button") 49 use_remote_data_button.on_click(self.load_remote_data) 50 51 remote_data_box = widgets.VBox([ 52 remote_database_label, 53 self.remote_database_input, 54 use_remote_data_button 55 ]) 56 local_data_box = widgets.VBox([ 57 local_database_label, 58 use_local_data_button 59 ]) 60 data_source_box = widgets.VBox([ 61 local_data_box, 62 remote_data_box 63 ]).add_class("global_data_tab_container") 64 65 return data_source_box 66 67 def init_graph_input_box(self) -> widgets.Box: 68 """Initialize second tab of dashboard, configuring material curing behaviour.""" 69 with plt.ioff(): 70 fig, self.ax = plt.subplots() 71 fig.canvas.toolbar_visible = False 72 fig.canvas.header_visible = False 73 fig.canvas.footer_visible = False 74 fig.canvas.resizable = False 75 fig.set_facecolor((0.0, 0.0, 0.0, 0.0)) 76 self.ax.set_facecolor((0.0, 0.0, 0.0, 0.0)) 77 78 choose_timeline_label = widgets.Label(value="Choose temperature curve:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 79 def on_selection_change(change): 80 new_data_set = self.graph_data[change['new']] 81 self.update_plot(new_data_set.get_time_data(),new_data_set.get_temperature_data()) 82 self.curve_selection = widgets.Dropdown( 83 options=['No data loaded'], 84 value='No data loaded', 85 description='Name:', 86 disabled=False 87 ).add_class("temp_sel_basic_input").add_class("global_basic_input") 88 self.curve_selection.observe(on_selection_change, names="value") 89 90 fibre_volume_content_label = widgets.Label(value="Choose FVC:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 91 self.fibre_volume_content_input = widgets.Dropdown( 92 options=['No data loaded'], 93 value='No data loaded', 94 description='Fibre Volume Content (%):', 95 disabled=False 96 ).add_class("temp_sel_basic_input").add_class("global_basic_input") 97 98 fvc_creation_label = widgets.Label(value="Create new fibre volume content:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 99 self.creation_fvc_input = widgets.FloatText( 100 value=0, 101 disabled=False, 102 description="Create new FVC entry (%)" 103 ).add_class("temp_sel_basic_input").add_class("global_basic_input") 104 save_fvc_button = widgets.Button( 105 description='Save FVC', 106 disabled=False, 107 tooltip='Save FVC', 108 icon='save', 109 ).add_class("temp_sel_curve_creation_button").add_class("global_basic_button") 110 save_fvc_button.on_click(self.save_new_fibre_volume_content) 111 112 creation_label = widgets.Label(value="Create new temperature curve:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 113 self.creation_time_input = widgets.Text( 114 value="", 115 placeholder="comma seperated values", 116 description="Time values (h):", 117 disabled=False 118 ).add_class("temp_sel_timeline_input").add_class("global_basic_input") 119 self.creation_temperature_input = widgets.Text( 120 value="", 121 placeholder="comma seperated values", 122 description="Temperature values (°C):", 123 disabled=False 124 ).add_class("temp_sel_timeline_input").add_class("global_basic_input") 125 self.creation_name_input = widgets.Text( 126 value="", 127 placeholder="enter name", 128 description="Name:", 129 disabled=False 130 ).add_class("temp_sel_timeline_input").add_class("global_basic_input") 131 plot_curve_button = widgets.Button( 132 description='Plot Curve', 133 disabled=False, 134 tooltip='Plot Curve', 135 icon='play' 136 ).add_class("temp_sel_curve_creation_button").add_class("global_basic_button") 137 plot_curve_button.on_click(self.preview_new_timeline) 138 save_curve_button = widgets.Button( 139 description='Save Curve', 140 disabled=False, 141 tooltip='Save Curve', 142 icon='save', 143 ).add_class("temp_sel_curve_creation_button").add_class("global_basic_button") 144 save_curve_button.on_click(self.save_new_timeline) 145 146 input_set_selection_label = widgets.Label(value="Select Input Set:").add_class("global_headline") 147 self.input_set_selection = widgets.Select( 148 options=['No data loaded'], 149 value='No data loaded', 150 rows=10, 151 description='Input sets:', 152 disabled=False 153 ).add_class("global_input_set_selection").add_class("global_basic_input") 154 display_input_set_button = widgets.Button( 155 description='Load Input Set', 156 disabled=False, 157 tooltip='Load Input Set', 158 icon='play', 159 ).add_class("global_basic_button") 160 display_input_set_button.on_click(self.display_input_set) 161 input_set_box = widgets.VBox([ 162 input_set_selection_label, 163 self.input_set_selection, 164 display_input_set_button 165 ]) 166 167 save_input_set_button = widgets.Button( 168 description='Save selected temperature graph and fibre volume content as new input set', 169 disabled=False, 170 tooltip='Save selected temperature graph and fibre volume content as new input set', 171 icon='save', 172 ).add_class("global_save_input_set_button").add_class("global_basic_button") 173 save_input_set_button.on_click(self.save_new_input_set) 174 curve_creation_button_box = widgets.HBox([ 175 plot_curve_button, 176 save_curve_button 177 ]).add_class("temp_sel_curve_creation_button_container") 178 fvc_creation_button_box = widgets.HBox([ 179 save_fvc_button 180 ]).add_class("temp_sel_curve_creation_button_container") 181 temperature_selection_box = widgets.VBox([ 182 choose_timeline_label, 183 self.curve_selection, 184 creation_label, 185 self.creation_time_input, 186 self.creation_temperature_input, 187 self.creation_name_input, 188 curve_creation_button_box 189 ]).add_class("temp_sel_curve_selection_container") 190 fvc_selection_box = widgets.VBox([ 191 fibre_volume_content_label, 192 self.fibre_volume_content_input, 193 fvc_creation_label, 194 self.creation_fvc_input, 195 fvc_creation_button_box 196 ]).add_class("temp_sel_curve_creation_container") 197 data_input_box = widgets.VBox([ 198 temperature_selection_box, 199 fvc_selection_box 200 ]).add_class("temp_sel_data_input_container") 201 matplot_box = widgets.VBox([ 202 fig.canvas 203 ]).add_class("temp_sel_matplot_box") 204 205 graph_input_box = widgets.VBox([ 206 widgets.HBox([ 207 input_set_box, 208 matplot_box, 209 data_input_box 210 ]).add_class("temp_sel_graph_tab_container"), 211 save_input_set_button 212 ]) 213 214 return graph_input_box 215 216 def update_plot(self, time_data: list, temperature_data: list): 217 """Update central plot with new data. 218 219 Args: 220 time_data: list of floats (hour) 221 temperature_data: list of floats (°C) 222 """ 223 self.ax.clear() 224 self.ax.plot(np.array(time_data), np.array(temperature_data), label='_Temp?') 225 self.ax.set_xlabel('Time (h)') 226 self.ax.set_ylabel('Temperature (°C)') 227 228 def load_local_data(self, ui_element=None): 229 """Use locally stored data for UI. 230 231 Args: 232 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 233 """ 234 self.conn = store_connection.LocalStoreConnection("sensotwin_world") 235 self.load_temperature_data() 236 self.load_fvc_data() 237 self.load_input_set_data() 238 239 def load_remote_data(self, ui_element=None): 240 """Use remotely stored data for UI. 241 242 Args: 243 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 244 """ 245 self.conn = store_connection.FusekiConnection(self.remote_database_input.value) 246 self.load_temperature_data() 247 self.load_fvc_data() 248 self.load_input_set_data() 249 250 def load_input_set_data(self): 251 """Load data from previously set input source and populate UI.""" 252 self.input_set_data = configuration.MaterialHardeningInputDataSet.get_all_entries_from_store(self.conn) 253 if self.input_set_data: 254 options = [] 255 for key, input_set in self.input_set_data.items(): 256 temperature_graph = self.graph_data[input_set.get_temperature_graph_id()] 257 fibre_volume_content = self.fvc_data[input_set.get_fibre_volume_content_id()] 258 label = input_set.generate_input_set_display_label() 259 options.append((label, key)) 260 self.input_set_selection.options = options 261 self.input_set_selection.value = list(self.input_set_data.keys())[0] 262 263 def display_input_set(self, ui_element=None): 264 """Display data for currently selected input set in UI. 265 266 Args: 267 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 268 """ 269 selected_set = self.input_set_data[self.input_set_selection.value] 270 temperature_graph = self.graph_data[selected_set.get_temperature_graph_id()] 271 fibre_volume_content = self.fvc_data[selected_set.get_fibre_volume_content_id()] 272 self.load_temperature_data(pre_select=temperature_graph.get_id()) 273 self.load_fvc_data(pre_select=fibre_volume_content.get_id()) 274 275 def load_temperature_data(self, pre_select=None): 276 """Refresh list for available temperature graphs. 277 278 Args: 279 pre_select: optional int id of a temperature set to be pre-selected after refresh 280 """ 281 self.graph_data = configuration.TemperatureGraph.get_all_entries_from_store(self.conn) 282 if self.graph_data: 283 if pre_select: 284 initial_dict_key = pre_select 285 else: 286 initial_dict_key = list(self.graph_data.keys())[0] 287 time_data = self.graph_data[initial_dict_key].get_time_data() 288 temperature_data = self.graph_data[initial_dict_key].get_temperature_data() 289 self.curve_selection.options = [(value.get_name(), key) for key, value in self.graph_data.items()] 290 self.curve_selection.value = initial_dict_key 291 self.update_plot(time_data, temperature_data) 292 293 def load_fvc_data(self, pre_select=None): 294 """Refresh list for available fibre volume content values. 295 296 Args: 297 pre_select: optional int id of a fibre volume content to be pre-selected after refresh 298 """ 299 self.fvc_data = configuration.FibreVolumeContent.get_all_entries_from_store(self.conn) 300 if self.fvc_data: 301 if pre_select: 302 initial_dict_key = pre_select 303 else: 304 initial_dict_key = list(self.fvc_data.keys())[0] 305 self.fibre_volume_content_input.options = [(value.get_value(), key) for key, value in self.fvc_data.items()] 306 self.fibre_volume_content_input.value = initial_dict_key 307 308 def preview_new_timeline(self, ui_element=None): 309 """Display new timeline currently defined in input fields without saving to store. 310 311 Args: 312 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 313 """ 314 self.update_plot(self.get_creation_time_values(), self.get_creation_temperature_values()) 315 316 def get_creation_time_values(self) -> list: 317 """Parse current input of time value input.""" 318 time_string = self.creation_time_input.value 319 time_values = list(map(float, time_string.split(","))) 320 return time_values 321 322 def get_creation_temperature_values(self) -> list: 323 """Parse current input of temperature value input.""" 324 temperature_string = self.creation_temperature_input.value 325 temperature_values = list(map(int, temperature_string.split(","))) 326 return temperature_values 327 328 def save_new_fibre_volume_content(self, ui_element=None): 329 """Save currently defined value of fibre volume content to store as new entry. 330 331 Args: 332 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 333 """ 334 new_id = max(self.fvc_data.keys()) + 1 if self.fvc_data else 1 335 new_fvc = configuration.FibreVolumeContent( 336 uniq_id = new_id, 337 value = self.creation_fvc_input.value, 338 conn = self.conn) 339 new_fvc.save_entry_to_store() 340 self.load_fvc_data(pre_select=new_id) 341 342 def save_new_timeline(self, ui_element=None): 343 """Save currently defined values of temperature graph to store as new entry. 344 345 Args: 346 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 347 """ 348 new_id = max(self.graph_data.keys()) + 1 if self.graph_data else 1 349 new_graph = configuration.TemperatureGraph( 350 uniq_id = new_id, 351 name = self.creation_name_input.value, 352 time_data = self.get_creation_time_values(), 353 temperature_data = self.get_creation_temperature_values(), 354 conn = self.conn) 355 new_graph.save_entry_to_store() 356 self.load_temperature_data(pre_select=new_id) 357 358 def save_new_input_set(self, ui_element=None): 359 """Save currently defined selections of temperature graph and fibre volume content to store as new entry. 360 361 Args: 362 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 363 """ 364 new_id = max(self.input_set_data.keys()) + 1 if self.input_set_data else 1 365 new_set = configuration.MaterialHardeningInputDataSet( 366 uniq_id = new_id, 367 temperature_graph = self.graph_data[self.curve_selection.value], 368 fibre_volume_content = self.fvc_data[self.fibre_volume_content_input.value], 369 conn = self.conn) 370 self.graph_data[self.curve_selection.value].save_entry_to_store() 371 self.fvc_data[self.fibre_volume_content_input.value].save_entry_to_store() 372 new_set.save_entry_to_store() 373 self.load_input_set_data() 374 375 def apply_styling(self): 376 """Apply CSS hack to notebook for better styling than native Jupyter Widget styles.""" 377 css = """ 378 <style> 379 {} 380 {} 381 </style> 382 """.format(global_style.global_css, style.local_css) 383 return widgets.HTML(css)
10class TemperatureSelectionUIElements: 11 """Contains all UI functionality of material curing process configuration UI (Step 1). 12 13 In order to use, show the top level widget 'self.dashboard' in one cell of a notebook 14 and the apply css styling calling 'self.apply_styling()' an another cell 15 """ 16 def __init__(self): 17 """Initialize UI objects and associated UI functionality.""" 18 self.dashboard = widgets.Tab().add_class("global_tab_container") 19 self.dashboard.children = [ 20 self.init_data_source_box(), 21 self.init_graph_input_box()] 22 tab_titles = ['Input', 'Simulation'] 23 for i in range(len(tab_titles)): 24 self.dashboard.set_title(i, tab_titles[i]) 25 26 def init_data_source_box(self) -> widgets.Box: 27 """Initialize first tab of dashboard, choosing data source.""" 28 local_database_label = widgets.Label(value="Use local owlready2 database:").add_class("global_headline") 29 use_local_data_button = widgets.Button( 30 description='Use local database', 31 disabled=False, 32 tooltip='Use local database', 33 icon='play', 34 ).add_class("global_load_data_button").add_class("global_basic_button") 35 use_local_data_button.on_click(self.load_local_data) 36 37 remote_database_label = widgets.Label(value="Use remote Apache Jena Fuseki database:").add_class("global_headline") 38 self.remote_database_input = widgets.Text( 39 value=None, 40 placeholder="insert SPARQL url here", 41 description="SPARQL Endpoint:", 42 disabled=False 43 ).add_class("global_url_input").add_class("global_basic_input") 44 use_remote_data_button = widgets.Button( 45 description='Use remote database', 46 disabled=False, 47 tooltip='Use remote database', 48 icon='play', 49 ).add_class("global_load_data_button").add_class("global_basic_button") 50 use_remote_data_button.on_click(self.load_remote_data) 51 52 remote_data_box = widgets.VBox([ 53 remote_database_label, 54 self.remote_database_input, 55 use_remote_data_button 56 ]) 57 local_data_box = widgets.VBox([ 58 local_database_label, 59 use_local_data_button 60 ]) 61 data_source_box = widgets.VBox([ 62 local_data_box, 63 remote_data_box 64 ]).add_class("global_data_tab_container") 65 66 return data_source_box 67 68 def init_graph_input_box(self) -> widgets.Box: 69 """Initialize second tab of dashboard, configuring material curing behaviour.""" 70 with plt.ioff(): 71 fig, self.ax = plt.subplots() 72 fig.canvas.toolbar_visible = False 73 fig.canvas.header_visible = False 74 fig.canvas.footer_visible = False 75 fig.canvas.resizable = False 76 fig.set_facecolor((0.0, 0.0, 0.0, 0.0)) 77 self.ax.set_facecolor((0.0, 0.0, 0.0, 0.0)) 78 79 choose_timeline_label = widgets.Label(value="Choose temperature curve:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 80 def on_selection_change(change): 81 new_data_set = self.graph_data[change['new']] 82 self.update_plot(new_data_set.get_time_data(),new_data_set.get_temperature_data()) 83 self.curve_selection = widgets.Dropdown( 84 options=['No data loaded'], 85 value='No data loaded', 86 description='Name:', 87 disabled=False 88 ).add_class("temp_sel_basic_input").add_class("global_basic_input") 89 self.curve_selection.observe(on_selection_change, names="value") 90 91 fibre_volume_content_label = widgets.Label(value="Choose FVC:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 92 self.fibre_volume_content_input = widgets.Dropdown( 93 options=['No data loaded'], 94 value='No data loaded', 95 description='Fibre Volume Content (%):', 96 disabled=False 97 ).add_class("temp_sel_basic_input").add_class("global_basic_input") 98 99 fvc_creation_label = widgets.Label(value="Create new fibre volume content:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 100 self.creation_fvc_input = widgets.FloatText( 101 value=0, 102 disabled=False, 103 description="Create new FVC entry (%)" 104 ).add_class("temp_sel_basic_input").add_class("global_basic_input") 105 save_fvc_button = widgets.Button( 106 description='Save FVC', 107 disabled=False, 108 tooltip='Save FVC', 109 icon='save', 110 ).add_class("temp_sel_curve_creation_button").add_class("global_basic_button") 111 save_fvc_button.on_click(self.save_new_fibre_volume_content) 112 113 creation_label = widgets.Label(value="Create new temperature curve:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 114 self.creation_time_input = widgets.Text( 115 value="", 116 placeholder="comma seperated values", 117 description="Time values (h):", 118 disabled=False 119 ).add_class("temp_sel_timeline_input").add_class("global_basic_input") 120 self.creation_temperature_input = widgets.Text( 121 value="", 122 placeholder="comma seperated values", 123 description="Temperature values (°C):", 124 disabled=False 125 ).add_class("temp_sel_timeline_input").add_class("global_basic_input") 126 self.creation_name_input = widgets.Text( 127 value="", 128 placeholder="enter name", 129 description="Name:", 130 disabled=False 131 ).add_class("temp_sel_timeline_input").add_class("global_basic_input") 132 plot_curve_button = widgets.Button( 133 description='Plot Curve', 134 disabled=False, 135 tooltip='Plot Curve', 136 icon='play' 137 ).add_class("temp_sel_curve_creation_button").add_class("global_basic_button") 138 plot_curve_button.on_click(self.preview_new_timeline) 139 save_curve_button = widgets.Button( 140 description='Save Curve', 141 disabled=False, 142 tooltip='Save Curve', 143 icon='save', 144 ).add_class("temp_sel_curve_creation_button").add_class("global_basic_button") 145 save_curve_button.on_click(self.save_new_timeline) 146 147 input_set_selection_label = widgets.Label(value="Select Input Set:").add_class("global_headline") 148 self.input_set_selection = widgets.Select( 149 options=['No data loaded'], 150 value='No data loaded', 151 rows=10, 152 description='Input sets:', 153 disabled=False 154 ).add_class("global_input_set_selection").add_class("global_basic_input") 155 display_input_set_button = widgets.Button( 156 description='Load Input Set', 157 disabled=False, 158 tooltip='Load Input Set', 159 icon='play', 160 ).add_class("global_basic_button") 161 display_input_set_button.on_click(self.display_input_set) 162 input_set_box = widgets.VBox([ 163 input_set_selection_label, 164 self.input_set_selection, 165 display_input_set_button 166 ]) 167 168 save_input_set_button = widgets.Button( 169 description='Save selected temperature graph and fibre volume content as new input set', 170 disabled=False, 171 tooltip='Save selected temperature graph and fibre volume content as new input set', 172 icon='save', 173 ).add_class("global_save_input_set_button").add_class("global_basic_button") 174 save_input_set_button.on_click(self.save_new_input_set) 175 curve_creation_button_box = widgets.HBox([ 176 plot_curve_button, 177 save_curve_button 178 ]).add_class("temp_sel_curve_creation_button_container") 179 fvc_creation_button_box = widgets.HBox([ 180 save_fvc_button 181 ]).add_class("temp_sel_curve_creation_button_container") 182 temperature_selection_box = widgets.VBox([ 183 choose_timeline_label, 184 self.curve_selection, 185 creation_label, 186 self.creation_time_input, 187 self.creation_temperature_input, 188 self.creation_name_input, 189 curve_creation_button_box 190 ]).add_class("temp_sel_curve_selection_container") 191 fvc_selection_box = widgets.VBox([ 192 fibre_volume_content_label, 193 self.fibre_volume_content_input, 194 fvc_creation_label, 195 self.creation_fvc_input, 196 fvc_creation_button_box 197 ]).add_class("temp_sel_curve_creation_container") 198 data_input_box = widgets.VBox([ 199 temperature_selection_box, 200 fvc_selection_box 201 ]).add_class("temp_sel_data_input_container") 202 matplot_box = widgets.VBox([ 203 fig.canvas 204 ]).add_class("temp_sel_matplot_box") 205 206 graph_input_box = widgets.VBox([ 207 widgets.HBox([ 208 input_set_box, 209 matplot_box, 210 data_input_box 211 ]).add_class("temp_sel_graph_tab_container"), 212 save_input_set_button 213 ]) 214 215 return graph_input_box 216 217 def update_plot(self, time_data: list, temperature_data: list): 218 """Update central plot with new data. 219 220 Args: 221 time_data: list of floats (hour) 222 temperature_data: list of floats (°C) 223 """ 224 self.ax.clear() 225 self.ax.plot(np.array(time_data), np.array(temperature_data), label='_Temp?') 226 self.ax.set_xlabel('Time (h)') 227 self.ax.set_ylabel('Temperature (°C)') 228 229 def load_local_data(self, ui_element=None): 230 """Use locally stored data for UI. 231 232 Args: 233 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 234 """ 235 self.conn = store_connection.LocalStoreConnection("sensotwin_world") 236 self.load_temperature_data() 237 self.load_fvc_data() 238 self.load_input_set_data() 239 240 def load_remote_data(self, ui_element=None): 241 """Use remotely stored data for UI. 242 243 Args: 244 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 245 """ 246 self.conn = store_connection.FusekiConnection(self.remote_database_input.value) 247 self.load_temperature_data() 248 self.load_fvc_data() 249 self.load_input_set_data() 250 251 def load_input_set_data(self): 252 """Load data from previously set input source and populate UI.""" 253 self.input_set_data = configuration.MaterialHardeningInputDataSet.get_all_entries_from_store(self.conn) 254 if self.input_set_data: 255 options = [] 256 for key, input_set in self.input_set_data.items(): 257 temperature_graph = self.graph_data[input_set.get_temperature_graph_id()] 258 fibre_volume_content = self.fvc_data[input_set.get_fibre_volume_content_id()] 259 label = input_set.generate_input_set_display_label() 260 options.append((label, key)) 261 self.input_set_selection.options = options 262 self.input_set_selection.value = list(self.input_set_data.keys())[0] 263 264 def display_input_set(self, ui_element=None): 265 """Display data for currently selected input set in UI. 266 267 Args: 268 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 269 """ 270 selected_set = self.input_set_data[self.input_set_selection.value] 271 temperature_graph = self.graph_data[selected_set.get_temperature_graph_id()] 272 fibre_volume_content = self.fvc_data[selected_set.get_fibre_volume_content_id()] 273 self.load_temperature_data(pre_select=temperature_graph.get_id()) 274 self.load_fvc_data(pre_select=fibre_volume_content.get_id()) 275 276 def load_temperature_data(self, pre_select=None): 277 """Refresh list for available temperature graphs. 278 279 Args: 280 pre_select: optional int id of a temperature set to be pre-selected after refresh 281 """ 282 self.graph_data = configuration.TemperatureGraph.get_all_entries_from_store(self.conn) 283 if self.graph_data: 284 if pre_select: 285 initial_dict_key = pre_select 286 else: 287 initial_dict_key = list(self.graph_data.keys())[0] 288 time_data = self.graph_data[initial_dict_key].get_time_data() 289 temperature_data = self.graph_data[initial_dict_key].get_temperature_data() 290 self.curve_selection.options = [(value.get_name(), key) for key, value in self.graph_data.items()] 291 self.curve_selection.value = initial_dict_key 292 self.update_plot(time_data, temperature_data) 293 294 def load_fvc_data(self, pre_select=None): 295 """Refresh list for available fibre volume content values. 296 297 Args: 298 pre_select: optional int id of a fibre volume content to be pre-selected after refresh 299 """ 300 self.fvc_data = configuration.FibreVolumeContent.get_all_entries_from_store(self.conn) 301 if self.fvc_data: 302 if pre_select: 303 initial_dict_key = pre_select 304 else: 305 initial_dict_key = list(self.fvc_data.keys())[0] 306 self.fibre_volume_content_input.options = [(value.get_value(), key) for key, value in self.fvc_data.items()] 307 self.fibre_volume_content_input.value = initial_dict_key 308 309 def preview_new_timeline(self, ui_element=None): 310 """Display new timeline currently defined in input fields without saving to store. 311 312 Args: 313 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 314 """ 315 self.update_plot(self.get_creation_time_values(), self.get_creation_temperature_values()) 316 317 def get_creation_time_values(self) -> list: 318 """Parse current input of time value input.""" 319 time_string = self.creation_time_input.value 320 time_values = list(map(float, time_string.split(","))) 321 return time_values 322 323 def get_creation_temperature_values(self) -> list: 324 """Parse current input of temperature value input.""" 325 temperature_string = self.creation_temperature_input.value 326 temperature_values = list(map(int, temperature_string.split(","))) 327 return temperature_values 328 329 def save_new_fibre_volume_content(self, ui_element=None): 330 """Save currently defined value of fibre volume content to store as new entry. 331 332 Args: 333 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 334 """ 335 new_id = max(self.fvc_data.keys()) + 1 if self.fvc_data else 1 336 new_fvc = configuration.FibreVolumeContent( 337 uniq_id = new_id, 338 value = self.creation_fvc_input.value, 339 conn = self.conn) 340 new_fvc.save_entry_to_store() 341 self.load_fvc_data(pre_select=new_id) 342 343 def save_new_timeline(self, ui_element=None): 344 """Save currently defined values of temperature graph to store as new entry. 345 346 Args: 347 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 348 """ 349 new_id = max(self.graph_data.keys()) + 1 if self.graph_data else 1 350 new_graph = configuration.TemperatureGraph( 351 uniq_id = new_id, 352 name = self.creation_name_input.value, 353 time_data = self.get_creation_time_values(), 354 temperature_data = self.get_creation_temperature_values(), 355 conn = self.conn) 356 new_graph.save_entry_to_store() 357 self.load_temperature_data(pre_select=new_id) 358 359 def save_new_input_set(self, ui_element=None): 360 """Save currently defined selections of temperature graph and fibre volume content to store as new entry. 361 362 Args: 363 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 364 """ 365 new_id = max(self.input_set_data.keys()) + 1 if self.input_set_data else 1 366 new_set = configuration.MaterialHardeningInputDataSet( 367 uniq_id = new_id, 368 temperature_graph = self.graph_data[self.curve_selection.value], 369 fibre_volume_content = self.fvc_data[self.fibre_volume_content_input.value], 370 conn = self.conn) 371 self.graph_data[self.curve_selection.value].save_entry_to_store() 372 self.fvc_data[self.fibre_volume_content_input.value].save_entry_to_store() 373 new_set.save_entry_to_store() 374 self.load_input_set_data() 375 376 def apply_styling(self): 377 """Apply CSS hack to notebook for better styling than native Jupyter Widget styles.""" 378 css = """ 379 <style> 380 {} 381 {} 382 </style> 383 """.format(global_style.global_css, style.local_css) 384 return widgets.HTML(css)
Contains all UI functionality of material curing process configuration UI (Step 1).
In order to use, show the top level widget 'self.dashboard' in one cell of a notebook and the apply css styling calling 'self.apply_styling()' an another cell
16 def __init__(self): 17 """Initialize UI objects and associated UI functionality.""" 18 self.dashboard = widgets.Tab().add_class("global_tab_container") 19 self.dashboard.children = [ 20 self.init_data_source_box(), 21 self.init_graph_input_box()] 22 tab_titles = ['Input', 'Simulation'] 23 for i in range(len(tab_titles)): 24 self.dashboard.set_title(i, tab_titles[i])
Initialize UI objects and associated UI functionality.
26 def init_data_source_box(self) -> widgets.Box: 27 """Initialize first tab of dashboard, choosing data source.""" 28 local_database_label = widgets.Label(value="Use local owlready2 database:").add_class("global_headline") 29 use_local_data_button = widgets.Button( 30 description='Use local database', 31 disabled=False, 32 tooltip='Use local database', 33 icon='play', 34 ).add_class("global_load_data_button").add_class("global_basic_button") 35 use_local_data_button.on_click(self.load_local_data) 36 37 remote_database_label = widgets.Label(value="Use remote Apache Jena Fuseki database:").add_class("global_headline") 38 self.remote_database_input = widgets.Text( 39 value=None, 40 placeholder="insert SPARQL url here", 41 description="SPARQL Endpoint:", 42 disabled=False 43 ).add_class("global_url_input").add_class("global_basic_input") 44 use_remote_data_button = widgets.Button( 45 description='Use remote database', 46 disabled=False, 47 tooltip='Use remote database', 48 icon='play', 49 ).add_class("global_load_data_button").add_class("global_basic_button") 50 use_remote_data_button.on_click(self.load_remote_data) 51 52 remote_data_box = widgets.VBox([ 53 remote_database_label, 54 self.remote_database_input, 55 use_remote_data_button 56 ]) 57 local_data_box = widgets.VBox([ 58 local_database_label, 59 use_local_data_button 60 ]) 61 data_source_box = widgets.VBox([ 62 local_data_box, 63 remote_data_box 64 ]).add_class("global_data_tab_container") 65 66 return data_source_box
Initialize first tab of dashboard, choosing data source.
68 def init_graph_input_box(self) -> widgets.Box: 69 """Initialize second tab of dashboard, configuring material curing behaviour.""" 70 with plt.ioff(): 71 fig, self.ax = plt.subplots() 72 fig.canvas.toolbar_visible = False 73 fig.canvas.header_visible = False 74 fig.canvas.footer_visible = False 75 fig.canvas.resizable = False 76 fig.set_facecolor((0.0, 0.0, 0.0, 0.0)) 77 self.ax.set_facecolor((0.0, 0.0, 0.0, 0.0)) 78 79 choose_timeline_label = widgets.Label(value="Choose temperature curve:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 80 def on_selection_change(change): 81 new_data_set = self.graph_data[change['new']] 82 self.update_plot(new_data_set.get_time_data(),new_data_set.get_temperature_data()) 83 self.curve_selection = widgets.Dropdown( 84 options=['No data loaded'], 85 value='No data loaded', 86 description='Name:', 87 disabled=False 88 ).add_class("temp_sel_basic_input").add_class("global_basic_input") 89 self.curve_selection.observe(on_selection_change, names="value") 90 91 fibre_volume_content_label = widgets.Label(value="Choose FVC:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 92 self.fibre_volume_content_input = widgets.Dropdown( 93 options=['No data loaded'], 94 value='No data loaded', 95 description='Fibre Volume Content (%):', 96 disabled=False 97 ).add_class("temp_sel_basic_input").add_class("global_basic_input") 98 99 fvc_creation_label = widgets.Label(value="Create new fibre volume content:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 100 self.creation_fvc_input = widgets.FloatText( 101 value=0, 102 disabled=False, 103 description="Create new FVC entry (%)" 104 ).add_class("temp_sel_basic_input").add_class("global_basic_input") 105 save_fvc_button = widgets.Button( 106 description='Save FVC', 107 disabled=False, 108 tooltip='Save FVC', 109 icon='save', 110 ).add_class("temp_sel_curve_creation_button").add_class("global_basic_button") 111 save_fvc_button.on_click(self.save_new_fibre_volume_content) 112 113 creation_label = widgets.Label(value="Create new temperature curve:").add_class("temp_sel_timeline_input_headline").add_class("global_headline") 114 self.creation_time_input = widgets.Text( 115 value="", 116 placeholder="comma seperated values", 117 description="Time values (h):", 118 disabled=False 119 ).add_class("temp_sel_timeline_input").add_class("global_basic_input") 120 self.creation_temperature_input = widgets.Text( 121 value="", 122 placeholder="comma seperated values", 123 description="Temperature values (°C):", 124 disabled=False 125 ).add_class("temp_sel_timeline_input").add_class("global_basic_input") 126 self.creation_name_input = widgets.Text( 127 value="", 128 placeholder="enter name", 129 description="Name:", 130 disabled=False 131 ).add_class("temp_sel_timeline_input").add_class("global_basic_input") 132 plot_curve_button = widgets.Button( 133 description='Plot Curve', 134 disabled=False, 135 tooltip='Plot Curve', 136 icon='play' 137 ).add_class("temp_sel_curve_creation_button").add_class("global_basic_button") 138 plot_curve_button.on_click(self.preview_new_timeline) 139 save_curve_button = widgets.Button( 140 description='Save Curve', 141 disabled=False, 142 tooltip='Save Curve', 143 icon='save', 144 ).add_class("temp_sel_curve_creation_button").add_class("global_basic_button") 145 save_curve_button.on_click(self.save_new_timeline) 146 147 input_set_selection_label = widgets.Label(value="Select Input Set:").add_class("global_headline") 148 self.input_set_selection = widgets.Select( 149 options=['No data loaded'], 150 value='No data loaded', 151 rows=10, 152 description='Input sets:', 153 disabled=False 154 ).add_class("global_input_set_selection").add_class("global_basic_input") 155 display_input_set_button = widgets.Button( 156 description='Load Input Set', 157 disabled=False, 158 tooltip='Load Input Set', 159 icon='play', 160 ).add_class("global_basic_button") 161 display_input_set_button.on_click(self.display_input_set) 162 input_set_box = widgets.VBox([ 163 input_set_selection_label, 164 self.input_set_selection, 165 display_input_set_button 166 ]) 167 168 save_input_set_button = widgets.Button( 169 description='Save selected temperature graph and fibre volume content as new input set', 170 disabled=False, 171 tooltip='Save selected temperature graph and fibre volume content as new input set', 172 icon='save', 173 ).add_class("global_save_input_set_button").add_class("global_basic_button") 174 save_input_set_button.on_click(self.save_new_input_set) 175 curve_creation_button_box = widgets.HBox([ 176 plot_curve_button, 177 save_curve_button 178 ]).add_class("temp_sel_curve_creation_button_container") 179 fvc_creation_button_box = widgets.HBox([ 180 save_fvc_button 181 ]).add_class("temp_sel_curve_creation_button_container") 182 temperature_selection_box = widgets.VBox([ 183 choose_timeline_label, 184 self.curve_selection, 185 creation_label, 186 self.creation_time_input, 187 self.creation_temperature_input, 188 self.creation_name_input, 189 curve_creation_button_box 190 ]).add_class("temp_sel_curve_selection_container") 191 fvc_selection_box = widgets.VBox([ 192 fibre_volume_content_label, 193 self.fibre_volume_content_input, 194 fvc_creation_label, 195 self.creation_fvc_input, 196 fvc_creation_button_box 197 ]).add_class("temp_sel_curve_creation_container") 198 data_input_box = widgets.VBox([ 199 temperature_selection_box, 200 fvc_selection_box 201 ]).add_class("temp_sel_data_input_container") 202 matplot_box = widgets.VBox([ 203 fig.canvas 204 ]).add_class("temp_sel_matplot_box") 205 206 graph_input_box = widgets.VBox([ 207 widgets.HBox([ 208 input_set_box, 209 matplot_box, 210 data_input_box 211 ]).add_class("temp_sel_graph_tab_container"), 212 save_input_set_button 213 ]) 214 215 return graph_input_box
Initialize second tab of dashboard, configuring material curing behaviour.
217 def update_plot(self, time_data: list, temperature_data: list): 218 """Update central plot with new data. 219 220 Args: 221 time_data: list of floats (hour) 222 temperature_data: list of floats (°C) 223 """ 224 self.ax.clear() 225 self.ax.plot(np.array(time_data), np.array(temperature_data), label='_Temp?') 226 self.ax.set_xlabel('Time (h)') 227 self.ax.set_ylabel('Temperature (°C)')
Update central plot with new data.
Args: time_data: list of floats (hour) temperature_data: list of floats (°C)
229 def load_local_data(self, ui_element=None): 230 """Use locally stored data for UI. 231 232 Args: 233 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 234 """ 235 self.conn = store_connection.LocalStoreConnection("sensotwin_world") 236 self.load_temperature_data() 237 self.load_fvc_data() 238 self.load_input_set_data()
Use locally stored data for UI.
Args: ui_element: Override for ipywidgets to not pass the UI element that triggered the event
240 def load_remote_data(self, ui_element=None): 241 """Use remotely stored data for UI. 242 243 Args: 244 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 245 """ 246 self.conn = store_connection.FusekiConnection(self.remote_database_input.value) 247 self.load_temperature_data() 248 self.load_fvc_data() 249 self.load_input_set_data()
Use remotely stored data for UI.
Args: ui_element: Override for ipywidgets to not pass the UI element that triggered the event
251 def load_input_set_data(self): 252 """Load data from previously set input source and populate UI.""" 253 self.input_set_data = configuration.MaterialHardeningInputDataSet.get_all_entries_from_store(self.conn) 254 if self.input_set_data: 255 options = [] 256 for key, input_set in self.input_set_data.items(): 257 temperature_graph = self.graph_data[input_set.get_temperature_graph_id()] 258 fibre_volume_content = self.fvc_data[input_set.get_fibre_volume_content_id()] 259 label = input_set.generate_input_set_display_label() 260 options.append((label, key)) 261 self.input_set_selection.options = options 262 self.input_set_selection.value = list(self.input_set_data.keys())[0]
Load data from previously set input source and populate UI.
264 def display_input_set(self, ui_element=None): 265 """Display data for currently selected input set in UI. 266 267 Args: 268 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 269 """ 270 selected_set = self.input_set_data[self.input_set_selection.value] 271 temperature_graph = self.graph_data[selected_set.get_temperature_graph_id()] 272 fibre_volume_content = self.fvc_data[selected_set.get_fibre_volume_content_id()] 273 self.load_temperature_data(pre_select=temperature_graph.get_id()) 274 self.load_fvc_data(pre_select=fibre_volume_content.get_id())
Display data for currently selected input set in UI.
Args: ui_element: Override for ipywidgets to not pass the UI element that triggered the event
276 def load_temperature_data(self, pre_select=None): 277 """Refresh list for available temperature graphs. 278 279 Args: 280 pre_select: optional int id of a temperature set to be pre-selected after refresh 281 """ 282 self.graph_data = configuration.TemperatureGraph.get_all_entries_from_store(self.conn) 283 if self.graph_data: 284 if pre_select: 285 initial_dict_key = pre_select 286 else: 287 initial_dict_key = list(self.graph_data.keys())[0] 288 time_data = self.graph_data[initial_dict_key].get_time_data() 289 temperature_data = self.graph_data[initial_dict_key].get_temperature_data() 290 self.curve_selection.options = [(value.get_name(), key) for key, value in self.graph_data.items()] 291 self.curve_selection.value = initial_dict_key 292 self.update_plot(time_data, temperature_data)
Refresh list for available temperature graphs.
Args: pre_select: optional int id of a temperature set to be pre-selected after refresh
294 def load_fvc_data(self, pre_select=None): 295 """Refresh list for available fibre volume content values. 296 297 Args: 298 pre_select: optional int id of a fibre volume content to be pre-selected after refresh 299 """ 300 self.fvc_data = configuration.FibreVolumeContent.get_all_entries_from_store(self.conn) 301 if self.fvc_data: 302 if pre_select: 303 initial_dict_key = pre_select 304 else: 305 initial_dict_key = list(self.fvc_data.keys())[0] 306 self.fibre_volume_content_input.options = [(value.get_value(), key) for key, value in self.fvc_data.items()] 307 self.fibre_volume_content_input.value = initial_dict_key
Refresh list for available fibre volume content values.
Args: pre_select: optional int id of a fibre volume content to be pre-selected after refresh
309 def preview_new_timeline(self, ui_element=None): 310 """Display new timeline currently defined in input fields without saving to store. 311 312 Args: 313 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 314 """ 315 self.update_plot(self.get_creation_time_values(), self.get_creation_temperature_values())
Display new timeline currently defined in input fields without saving to store.
Args: ui_element: Override for ipywidgets to not pass the UI element that triggered the event
317 def get_creation_time_values(self) -> list: 318 """Parse current input of time value input.""" 319 time_string = self.creation_time_input.value 320 time_values = list(map(float, time_string.split(","))) 321 return time_values
Parse current input of time value input.
323 def get_creation_temperature_values(self) -> list: 324 """Parse current input of temperature value input.""" 325 temperature_string = self.creation_temperature_input.value 326 temperature_values = list(map(int, temperature_string.split(","))) 327 return temperature_values
Parse current input of temperature value input.
329 def save_new_fibre_volume_content(self, ui_element=None): 330 """Save currently defined value of fibre volume content to store as new entry. 331 332 Args: 333 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 334 """ 335 new_id = max(self.fvc_data.keys()) + 1 if self.fvc_data else 1 336 new_fvc = configuration.FibreVolumeContent( 337 uniq_id = new_id, 338 value = self.creation_fvc_input.value, 339 conn = self.conn) 340 new_fvc.save_entry_to_store() 341 self.load_fvc_data(pre_select=new_id)
Save currently defined value of fibre volume content to store as new entry.
Args: ui_element: Override for ipywidgets to not pass the UI element that triggered the event
343 def save_new_timeline(self, ui_element=None): 344 """Save currently defined values of temperature graph to store as new entry. 345 346 Args: 347 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 348 """ 349 new_id = max(self.graph_data.keys()) + 1 if self.graph_data else 1 350 new_graph = configuration.TemperatureGraph( 351 uniq_id = new_id, 352 name = self.creation_name_input.value, 353 time_data = self.get_creation_time_values(), 354 temperature_data = self.get_creation_temperature_values(), 355 conn = self.conn) 356 new_graph.save_entry_to_store() 357 self.load_temperature_data(pre_select=new_id)
Save currently defined values of temperature graph to store as new entry.
Args: ui_element: Override for ipywidgets to not pass the UI element that triggered the event
359 def save_new_input_set(self, ui_element=None): 360 """Save currently defined selections of temperature graph and fibre volume content to store as new entry. 361 362 Args: 363 ui_element: Override for ipywidgets to not pass the UI element that triggered the event 364 """ 365 new_id = max(self.input_set_data.keys()) + 1 if self.input_set_data else 1 366 new_set = configuration.MaterialHardeningInputDataSet( 367 uniq_id = new_id, 368 temperature_graph = self.graph_data[self.curve_selection.value], 369 fibre_volume_content = self.fvc_data[self.fibre_volume_content_input.value], 370 conn = self.conn) 371 self.graph_data[self.curve_selection.value].save_entry_to_store() 372 self.fvc_data[self.fibre_volume_content_input.value].save_entry_to_store() 373 new_set.save_entry_to_store() 374 self.load_input_set_data()
Save currently defined selections of temperature graph and fibre volume content to store as new entry.
Args: ui_element: Override for ipywidgets to not pass the UI element that triggered the event
376 def apply_styling(self): 377 """Apply CSS hack to notebook for better styling than native Jupyter Widget styles.""" 378 css = """ 379 <style> 380 {} 381 {} 382 </style> 383 """.format(global_style.global_css, style.local_css) 384 return widgets.HTML(css)
Apply CSS hack to notebook for better styling than native Jupyter Widget styles.