From b864036e4eb344631143fe0813ec11515bbd49cb Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 3 Jul 2024 19:18:30 -0400 Subject: [PATCH 01/26] ENH: Modified connectivity tab to contain two additional tabs --- hnn_core/gui/gui.py | 237 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 218 insertions(+), 19 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 914c4a4f4..9ac85770d 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -32,6 +32,81 @@ import numpy as np from copy import deepcopy +cell_parameters_dic = { + + "Geometry": + [ + ('Soma lenght', 'micron'), + ('Soma diameter', 'micron'), + ('Soma capacitive density', 'F/cm2'), + ('Soma resistivity', 'ohm-cm'), + ('Dendrite capacitive density', 'F/cm2'), + ('Dendrite resistivity', 'ohm-cm'), + ('Apical Dendrite Trunk lenght', 'micron'), + ('Apical Dendrite 1 lenght', 'micron'), + ('Apical Dendrite 1 diameter', 'micron'), + ('Apical Dendrite Tuft lenght', 'micron'), + ('Apical Dendrite Tuft diameter', 'micron'), + ('Oblique Apical Dendrite lenght', 'micron'), + ('Oblique Apical Dendrite diameter', 'micron'), + ('Basal Dendrite 1 lenght', 'micron'), + ('Basal Dendrite 1 diameter', 'micron'), + ('Basal Dendrite 2 lenght', 'micron'), + ('Basal Dendrite 2 diameter', 'micron'), + ('Basal Dendrite 3 lenght', 'micron'), + ('Basal Dendrite 3 diameter', 'micron') + ], + "Synapses": + [ + ('AMPA reversal', 'mV'), + ('AMPA rise time', 'ms'), + ('AMPA decay time', 'ms'), + ('NMDA reversal', 'mV'), + ('NMDA rise time', 'ms'), + ('NMDA decay time', 'ms'), + ('GABAA reversal', 'mV'), + ('GABAA rise time', 'ms'), + ('GABAA decay time', 'ms'), + ('GABAB reversal', 'mV'), + ('GABAB rise time', 'ms'), + ('GABAB decay time', 'ms') + ], + "Biophysics L2": + [ + ('Soma Kv channel density', 'S/cm2'), + ('Soma Na channel density', 'S/cm2'), + ('Soma leak reversal', 'mV'), + ('Soma leak channel density', 'S/cm2'), + ('Soma Km channel density', 'pS/micron2'), + ('Dendrite Kv channel density', 'S/cm2'), + ('Dendrite Na channel density', 'S/cm2'), + ('Dendrite leak reversal', 'mV'), + ('Dendrite leak channel density', 'S/cm2'), + ('Dendrite Km channel density', 'pS/micron2') + ], + "Biophysics L5": + [ + ('Soma Kv channel density', 'S/cm2'), + ('Soma Na channel density', 'S/cm2'), + ('Soma leak reversal', 'mV'), + ('Soma leak channel density', 'S/cm2'), + ('Soma Ca channel density', 'pS/micron2'), + ('Soma Ca decay time', 'ms'), + ('Soma Kca channel density', 'pS/micron2'), + ('Soma Km channel density', 'pS/micron2'), + ('Soma CaT channel density', 'S/cm2'), + ('Soma HCN channel density', 'S/cm2'), + ('Dendrite Kv channel density', 'S/cm2'), + ('Dendrite Na channel density', 'S/cm2'), + ('Dendrite leak reversal', 'mV'), + ('Dendrite leak channel density', 'S/cm2'), + ('Dendrite KCa channel density', 'pS/micron2'), + ('Dendrite Km channel density', 'pS/micron2'), + ('Dendrite CaT channel density', 'S/cm2'), + ('Dendrite HCN channel density', 'S/cm2') + ] +} + class _OutputWidgetHandler(logging.Handler): def __init__(self, output_widget, *args, **kwargs): @@ -284,6 +359,13 @@ def __init__(self, theme_color="#8A2BE2", 'Delete drives', 'success', layout=self.layout['btn'], button_color=self.layout['theme_color']) + self.cell_type_radio_button = RadioButtons( + options=['L2', 'L5'], + description='Cell type:') + self.cell_layer_radio_button = RadioButtons( + options=['Geometry', 'Synapses', 'Biophysics'], + description='Layer:') + # Plotting window # Visualization figure related dicts @@ -298,6 +380,9 @@ def __init__(self, theme_color="#8A2BE2", # Connectivity list self.connectivity_widgets = list() + # Cell parameter list + self.cell_pameters = dict() + self._init_ui_components() self.add_logging_window_logger() @@ -337,6 +422,7 @@ def _init_ui_components(self): # dynamic larger components self._drives_out = Output() # tab to add new drives self._connectivity_out = Output() # tab to tune connectivity. + self._cell_params_out = Output() self._log_out = Output() @@ -464,6 +550,16 @@ def _driver_type_change(value): self.widget_location_selection.disabled = ( True if value.new == "Tonic" else False) + def _cell_type_radio_change(value): + _update_cell_params_vbox(self._cell_params_out, self.cell_pameters, + value.new, + self.cell_layer_radio_button.value) + + def _cell_layer_radio_change(value): + _update_cell_params_vbox(self._cell_params_out, self.cell_pameters, + self.cell_type_radio_button.value, + value.new) + self.widget_backend_selection.observe(_handle_backend_change, 'value') self.add_drive_button.on_click(_add_drive_button_clicked) self.delete_drive_button.on_click(_delete_drives_clicked) @@ -475,6 +571,9 @@ def _driver_type_change(value): self.simulation_list_widget.observe(_simulation_list_change, 'value') self.widget_drive_type_selection.observe(_driver_type_change, 'value') + self.cell_type_radio_button.observe(_cell_type_radio_change, 'value') + self.cell_layer_radio_button.observe(_cell_layer_radio_change, 'value') + def compose(self, return_layout=True): """Compose widgets. @@ -491,19 +590,31 @@ def compose(self, return_layout=True): self._backend_config_out]), ], layout=self.layout['config_box']) + connectivity_configuration = Tab() + connectivity_box = VBox([ HBox([self.load_connectivity_button, ]), self._connectivity_out, ]) + cell_parameters = VBox([ + HBox([self.cell_type_radio_button, self.cell_layer_radio_button]), + self._cell_params_out + ]) + + connectivity_configuration.children = [connectivity_box, + cell_parameters] + connectivity_configuration.titles = ['Network connectivity', + 'Cell Parameters'] + # accordions to group local-connectivity by cell type - connectivity_boxes = [ - VBox(slider) for slider in self.connectivity_widgets] - connectivity_names = ( - 'Layer 2/3 Pyramidal', 'Layer 5 Pyramidal', 'Layer 2 Basket', - 'Layer 5 Basket') - cell_connectivity = Accordion(children=connectivity_boxes) - cell_connectivity.titles = [s for s in connectivity_names] + # connectivity_boxes = [ + # VBox(slider) for slider in self.connectivity_widgets] + # connectivity_names = ( + # 'Layer 2/3 Pyramidal', 'Layer 5 Pyramidal', 'Layer 2 Basket', + # 'Layer 5 Basket') + # cell_connectivity = Accordion(children=connectivity_boxes) + # cell_connectivity.titles = [s for s in connectivity_names] drive_selections = VBox([ self.add_drive_button, self.widget_drive_type_selection, @@ -523,10 +634,10 @@ def compose(self, return_layout=True): # Tabs for left pane left_tab = Tab() left_tab.children = [ - simulation_box, connectivity_box, drives_options, + simulation_box, connectivity_configuration, drives_options, config_panel, ] - titles = ('Simulation', 'Network connectivity', 'External drives', + titles = ('Simulation', 'Connectivity', 'External drives', 'Visualization') for idx, title in enumerate(titles): left_tab.set_title(idx, title) @@ -558,6 +669,10 @@ def compose(self, return_layout=True): self._drives_out, self.drive_widgets, self.drive_boxes, self._connectivity_out, self.connectivity_widgets, + self._cell_params_out, + self.cell_pameters, + self.cell_layer_radio_button, + self.cell_type_radio_button, self.widget_tstop, self.layout) if not return_layout: @@ -1167,11 +1282,25 @@ def add_drive_widget(drive_type, drive_boxes, drive_widgets, drives_out, display(accordion) -def add_connectivity_tab(params, connectivity_out, - connectivity_textfields): +def add_connectivity_tab(params, connectivity_out, connectivity_textfields, + cell_params_out, cell_pameters_vboxes, + cell_layer_radio_button, cell_type_radio_button): """Add all possible connectivity boxes to connectivity tab.""" net = jones_2009_model(params) - cell_types = [ct for ct in net.cell_types.keys()] + + # build network connectivity tab + add_network_connectivity_tab(net, connectivity_out, + connectivity_textfields) + + # build cell parameters tab + add_cell_parameters_tab(net, cell_params_out, cell_pameters_vboxes, + cell_layer_radio_button, cell_type_radio_button) + return net + + +def add_network_connectivity_tab(network, connectivity_out, + connectivity_textfields): + cell_types = [ct for ct in network.cell_types.keys()] receptors = ('ampa', 'nmda', 'gabaa', 'gabab') locations = ('proximal', 'distal', 'soma') @@ -1187,7 +1316,7 @@ def add_connectivity_tab(params, connectivity_out, # the connectivity list should be built on this level receptor_related_conn = {} for receptor in receptors: - conn_indices = pick_connection(net=net, + conn_indices = pick_connection(net=network, src_gids=src_gids, target_gids=target_gids, loc=location, @@ -1195,9 +1324,9 @@ def add_connectivity_tab(params, connectivity_out, if len(conn_indices) > 0: assert len(conn_indices) == 1 conn_idx = conn_indices[0] - current_w = net.connectivity[ + current_w = network.connectivity[ conn_idx]['nc_dict']['A_weight'] - current_p = net.connectivity[ + current_p = network.connectivity[ conn_idx]['probability'] # valid connection receptor_related_conn[receptor] = { @@ -1223,7 +1352,57 @@ def add_connectivity_tab(params, connectivity_out, with connectivity_out: display(cell_connectivity) - return net + return network + + +def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, + cell_layer_radio_button, cell_type_radio_button): + + cell_types = ["L2", "L5"] + # get_cell_params_dic_values(network.cell_types) + for cell_type in cell_types: + layer_parameters = list() + for layer in cell_parameters_dic.keys(): + if layer == 'Biophysics' and cell_type not in layer: + continue + + for parameter in cell_parameters_dic[layer]: + param_name = parameter[0] + param_units = parameter[1] + descrption = f"{param_name} ({param_units})" + text_field = BoundedFloatText(value=0.0, + min=0, + max=10.0, + step=0.1, + description=descrption, + disabled=False) + layer_parameters.append(text_field) + cell_pameters_key = cell_type + "_" + layer + cell_pameters_vboxes[cell_pameters_key] = VBox(layer_parameters) + layer_parameters.clear() + + # clear existing connectivity + cell_params_out.clear_output() + # while len(cell_params_out) > 0: + # cell_params_out.pop() + # cell_params_out.pop() + + # Add cell parameters + display(_update_cell_params_vbox(cell_params_out, + cell_pameters_vboxes, + cell_type_radio_button.value, + cell_layer_radio_button.value)) + + +def get_cell_params_dic_values(network_cell_types): + # cell_types = [ct for ct in network_cell_types.keys() + # if "pyramidal" in ct] + ... + # for type in cell_types: + # cell_type = network_cell_types[type] + # # get geometry params + + # cell_types.sections['soma'] def add_drive_tab(params, log_out, drives_out, drive_widgets, drive_boxes, @@ -1270,12 +1449,16 @@ def add_drive_tab(params, log_out, drives_out, drive_widgets, drive_boxes, def load_drive_and_connectivity(params, log_out, drives_out, drive_widgets, drive_boxes, connectivity_out, - connectivity_textfields, tstop, layout): + connectivity_textfields, cell_params_out, + cell_pameters_vboxes, cell_layer_radio_button, + cell_type_radio_button, tstop, layout): """Add drive and connectivity ipywidgets from params.""" with log_out: # Add connectivity - add_connectivity_tab(params, connectivity_out, - connectivity_textfields) + add_connectivity_tab(params, connectivity_out, connectivity_textfields, + cell_params_out, cell_pameters_vboxes, + cell_layer_radio_button, cell_type_radio_button) + # Add drives add_drive_tab(params, log_out, drives_out, drive_widgets, drive_boxes, tstop, layout) @@ -1516,6 +1699,18 @@ def run_button_clicked(widget_simulation_name, log_out, drive_widgets, plot_type, {}, "plot") +def _update_cell_params_vbox(cell_type_out, cell_parameters_list, + cell_type, cell_layer): + cell_parameters_key = f"{cell_type}_{cell_layer}" + if "Biophysics" in cell_layer: + cell_parameters_key += f" {cell_type}" + + if cell_parameters_key in cell_parameters_key: + cell_type_out.clear_output() + with cell_type_out: + display(cell_parameters_list[cell_parameters_key]) + + def _serialize_simulation(log_out, sim_data, simulation_list_widget): # Only download if there is there is at least one simulation sim_name = simulation_list_widget.value @@ -1594,5 +1789,9 @@ def launch(): You can pass voila commandline parameters as usual. """ from voila.app import main + import debugpy + debugpy.listen(5678) + print("Waiting for debugger attach") + debugpy.wait_for_client() notebook_path = Path(__file__).parent / 'hnn_widget.ipynb' main([str(notebook_path.resolve()), *sys.argv[1:]]) From 8eb339bc85ace287a1c122015e8949f16c9864e2 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Sun, 7 Jul 2024 15:42:04 -0400 Subject: [PATCH 02/26] MAINT: Fixed spellcheck and linkcheck erros in gui.py --- hnn_core/gui/gui.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 9ac85770d..89b6a4322 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -502,7 +502,9 @@ def _on_upload_connectivity(change): change, self.widget_tstop, self.widget_dt, self._log_out, self.drive_boxes, self.drive_widgets, self._drives_out, self._connectivity_out, - self.connectivity_widgets, self.layout['drive_textbox'], + self.connectivity_widgets, self._cell_params_out, + self.cell_pameters_vboxes, self.cell_layer_radio_button, + self.cell_type_radio_button, self.layout['drive_textbox'], "connectivity") def _on_upload_drives(change): @@ -510,7 +512,9 @@ def _on_upload_drives(change): change, self.widget_tstop, self.widget_dt, self._log_out, self.drive_boxes, self.drive_widgets, self._drives_out, self._connectivity_out, - self.connectivity_widgets, self.layout['drive_textbox'], + self.connectivity_widgets, self._cell_params_out, + self.cell_pameters_vboxes, self.cell_layer_radio_button, + self.cell_type_radio_button, self.layout['drive_textbox'], "drives") def _on_upload_data(change): @@ -1369,12 +1373,12 @@ def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, for parameter in cell_parameters_dic[layer]: param_name = parameter[0] param_units = parameter[1] - descrption = f"{param_name} ({param_units})" + description = f"{param_name} ({param_units})" text_field = BoundedFloatText(value=0.0, min=0, max=10.0, step=0.1, - description=descrption, + description=description, disabled=False) layer_parameters.append(text_field) cell_pameters_key = cell_type + "_" + layer @@ -1500,7 +1504,9 @@ def on_upload_data_change(change, data, viz_manager, log_out): def on_upload_params_change(change, tstop, dt, log_out, drive_boxes, drive_widgets, drives_out, connectivity_out, - connectivity_textfields, layout, load_type): + connectivity_textfields, cell_params_out, + cell_pameters_vboxes, cell_layer_radio_button, + cell_type_radio_button, layout, load_type): if len(change['owner'].value) == 0: return param_dict = change['new'][0] @@ -1519,7 +1525,10 @@ def on_upload_params_change(change, tstop, dt, log_out, drive_boxes, # init network, add drives & connectivity if load_type == 'connectivity': - add_connectivity_tab(params, connectivity_out, connectivity_textfields) + add_connectivity_tab(params, connectivity_out, + connectivity_textfields, cell_params_out, + cell_pameters_vboxes, cell_layer_radio_button, + cell_type_radio_button) elif load_type == 'drives': with log_out: add_drive_tab(params, log_out, drives_out, drive_widgets, From 2231a4ca810d99c6e58751647e2a023faa3d38ec Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Sun, 7 Jul 2024 16:15:21 -0400 Subject: [PATCH 03/26] MAINT: Fixed bad argument in on_upload_params_change --- hnn_core/gui/gui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 89b6a4322..f018d89a0 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -503,7 +503,7 @@ def _on_upload_connectivity(change): self._log_out, self.drive_boxes, self.drive_widgets, self._drives_out, self._connectivity_out, self.connectivity_widgets, self._cell_params_out, - self.cell_pameters_vboxes, self.cell_layer_radio_button, + self.cell_pameters, self.cell_layer_radio_button, self.cell_type_radio_button, self.layout['drive_textbox'], "connectivity") From ff78e98d6b9f0c23f21b6340721986cf2e3ea750 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Sun, 7 Jul 2024 16:21:01 -0400 Subject: [PATCH 04/26] MAINT: Fixed bad argument in on_upload_params_change --- hnn_core/gui/gui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index f018d89a0..fe985491a 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -513,7 +513,7 @@ def _on_upload_drives(change): self._log_out, self.drive_boxes, self.drive_widgets, self._drives_out, self._connectivity_out, self.connectivity_widgets, self._cell_params_out, - self.cell_pameters_vboxes, self.cell_layer_radio_button, + self.cell_pameters, self.cell_layer_radio_button, self.cell_type_radio_button, self.layout['drive_textbox'], "drives") From 525efbbf08cb97b6fa8db95954ca988e57ea0b52 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Sun, 7 Jul 2024 16:33:17 -0400 Subject: [PATCH 05/26] MAINT: Fixed notebook tutorial that looks up tabs by name --- doc/gui/tutorial_erp.ipynb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/gui/tutorial_erp.ipynb b/doc/gui/tutorial_erp.ipynb index 27d5fea74..7c2642d57 100644 --- a/doc/gui/tutorial_erp.ipynb +++ b/doc/gui/tutorial_erp.ipynb @@ -11,6 +11,20 @@ "%autoreload 2" ] }, + { + "cell_type": "markdown", + "id": "b446910e", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "82e9a552", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "id": "a0dd997d", @@ -220,7 +234,7 @@ "metadata": {}, "outputs": [], "source": [ - "gui._simulate_left_tab_click(\"Network connectivity\")" + "gui._simulate_left_tab_click(\"Connectivity\")" ] }, { From 21f048c3537984476eb9877932c201b475725195 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Sun, 7 Jul 2024 21:26:36 -0400 Subject: [PATCH 06/26] MAINT: Fixed description width in cell parameters gui tab --- hnn_core/gui/gui.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index fe985491a..1a13a1679 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1288,7 +1288,8 @@ def add_drive_widget(drive_type, drive_boxes, drive_widgets, drives_out, def add_connectivity_tab(params, connectivity_out, connectivity_textfields, cell_params_out, cell_pameters_vboxes, - cell_layer_radio_button, cell_type_radio_button): + cell_layer_radio_button, cell_type_radio_button, + layout): """Add all possible connectivity boxes to connectivity tab.""" net = jones_2009_model(params) @@ -1298,7 +1299,8 @@ def add_connectivity_tab(params, connectivity_out, connectivity_textfields, # build cell parameters tab add_cell_parameters_tab(net, cell_params_out, cell_pameters_vboxes, - cell_layer_radio_button, cell_type_radio_button) + cell_layer_radio_button, cell_type_radio_button, + layout) return net @@ -1360,14 +1362,18 @@ def add_network_connectivity_tab(network, connectivity_out, def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, - cell_layer_radio_button, cell_type_radio_button): + cell_layer_radio_button, cell_type_radio_button, + layout): cell_types = ["L2", "L5"] + style = {'description_width': '235px'} + kwargs = dict(layout=layout, style=style) + # get_cell_params_dic_values(network.cell_types) for cell_type in cell_types: layer_parameters = list() for layer in cell_parameters_dic.keys(): - if layer == 'Biophysics' and cell_type not in layer: + if f'Biophysic' in layer and cell_type not in layer: continue for parameter in cell_parameters_dic[layer]: @@ -1379,7 +1385,8 @@ def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, max=10.0, step=0.1, description=description, - disabled=False) + disabled=False, + **kwargs) layer_parameters.append(text_field) cell_pameters_key = cell_type + "_" + layer cell_pameters_vboxes[cell_pameters_key] = VBox(layer_parameters) @@ -1461,7 +1468,8 @@ def load_drive_and_connectivity(params, log_out, drives_out, # Add connectivity add_connectivity_tab(params, connectivity_out, connectivity_textfields, cell_params_out, cell_pameters_vboxes, - cell_layer_radio_button, cell_type_radio_button) + cell_layer_radio_button, cell_type_radio_button, + layout) # Add drives add_drive_tab(params, log_out, drives_out, drive_widgets, drive_boxes, @@ -1528,7 +1536,7 @@ def on_upload_params_change(change, tstop, dt, log_out, drive_boxes, add_connectivity_tab(params, connectivity_out, connectivity_textfields, cell_params_out, cell_pameters_vboxes, cell_layer_radio_button, - cell_type_radio_button) + cell_type_radio_button, layout) elif load_type == 'drives': with log_out: add_drive_tab(params, log_out, drives_out, drive_widgets, From 8d1545db45c5aabcbe96cddfd7f0d4b48c6dc495 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Sun, 7 Jul 2024 21:32:14 -0400 Subject: [PATCH 07/26] STY: Fixed flake8 errors --- hnn_core/gui/gui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 1a13a1679..ccb05282f 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1373,7 +1373,7 @@ def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, for cell_type in cell_types: layer_parameters = list() for layer in cell_parameters_dic.keys(): - if f'Biophysic' in layer and cell_type not in layer: + if 'Biophysic' in layer and cell_type not in layer: continue for parameter in cell_parameters_dic[layer]: From 41e74bbc0bafe22a06003168b825716c115c5a0c Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Tue, 9 Jul 2024 14:04:35 -0400 Subject: [PATCH 08/26] MAINT: Adding cell types keys to gui cell params map --- hnn_core/gui/gui.py | 126 ++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index ccb05282f..2d3df767d 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -32,78 +32,80 @@ import numpy as np from copy import deepcopy -cell_parameters_dic = { +cell_parameters_dict = { "Geometry": [ - ('Soma lenght', 'micron'), - ('Soma diameter', 'micron'), - ('Soma capacitive density', 'F/cm2'), - ('Soma resistivity', 'ohm-cm'), - ('Dendrite capacitive density', 'F/cm2'), - ('Dendrite resistivity', 'ohm-cm'), - ('Apical Dendrite Trunk lenght', 'micron'), - ('Apical Dendrite 1 lenght', 'micron'), - ('Apical Dendrite 1 diameter', 'micron'), - ('Apical Dendrite Tuft lenght', 'micron'), - ('Apical Dendrite Tuft diameter', 'micron'), - ('Oblique Apical Dendrite lenght', 'micron'), - ('Oblique Apical Dendrite diameter', 'micron'), - ('Basal Dendrite 1 lenght', 'micron'), - ('Basal Dendrite 1 diameter', 'micron'), - ('Basal Dendrite 2 lenght', 'micron'), - ('Basal Dendrite 2 diameter', 'micron'), - ('Basal Dendrite 3 lenght', 'micron'), - ('Basal Dendrite 3 diameter', 'micron') + ('Soma length', 'micron', 'soma_L'), + ('Soma diameter', 'micron', 'soma_diam'), + ('Soma capacitive density', 'F/cm2', 'soma_cm'), + ('Soma resistivity', 'ohm-cm', 'soma_Ra'), + ('Dendrite capacitive density', 'F/cm2', 'dend_cm'), + ('Dendrite resistivity', 'ohm-cm', 'dend_Ra'), + ('Apical Dendrite Trunk length', 'micron', 'apicaltrunk_L'), + ('Apical Dendrite 1 length', 'micron', 'apicaltrunk_diam'), + ('Apical Dendrite 1 diameter', 'micron', 'apical1_L'), + ('Apical Dendrite Tuft length', 'micron', 'apicaltuft_L'), + ('Apical Dendrite Tuft diameter', 'micron', 'apicaltuft_diam'), + ('Oblique Apical Dendrite length', 'micron', 'apicaloblique_L'), + ('Oblique Apical Dendrite diameter', 'micron', 'apicaloblique_diam'), + ('Basal Dendrite 1 length', 'micron', 'basal1_L'), + ('Basal Dendrite 1 diameter', 'micron', 'basal1_diam'), + ('Basal Dendrite 2 length', 'micron', 'basal2_L'), + ('Basal Dendrite 2 diameter', 'micron', 'basal2_diam'), + ('Basal Dendrite 3 length', 'micron', 'basal3_L'), + ('Basal Dendrite 3 diameter', 'micron', 'basal3_diam') ], "Synapses": [ - ('AMPA reversal', 'mV'), - ('AMPA rise time', 'ms'), - ('AMPA decay time', 'ms'), - ('NMDA reversal', 'mV'), - ('NMDA rise time', 'ms'), - ('NMDA decay time', 'ms'), - ('GABAA reversal', 'mV'), - ('GABAA rise time', 'ms'), - ('GABAA decay time', 'ms'), - ('GABAB reversal', 'mV'), - ('GABAB rise time', 'ms'), - ('GABAB decay time', 'ms') + ('AMPA reversal', 'mV', 'ampa_e'), + ('AMPA rise time', 'ms', 'ampa_tau1'), + ('AMPA decay time', 'ms', 'ampa_tau2'), + ('NMDA reversal', 'mV', 'nmda_e'), + ('NMDA rise time', 'ms', 'nmda_tau1'), + ('NMDA decay time', 'ms', 'nmda_tau2'), + ('GABAA reversal', 'mV', 'gabaa_e'), + ('GABAA rise time', 'ms', 'gabaa_tau1'), + ('GABAA decay time', 'ms', 'gabaa_tau2'), + ('GABAB reversal', 'mV', 'gabab_e'), + ('GABAB rise time', 'ms', 'gabab_tau1'), + ('GABAB decay time', 'ms', 'gabab_tau2') ], "Biophysics L2": [ - ('Soma Kv channel density', 'S/cm2'), - ('Soma Na channel density', 'S/cm2'), - ('Soma leak reversal', 'mV'), - ('Soma leak channel density', 'S/cm2'), - ('Soma Km channel density', 'pS/micron2'), - ('Dendrite Kv channel density', 'S/cm2'), - ('Dendrite Na channel density', 'S/cm2'), - ('Dendrite leak reversal', 'mV'), - ('Dendrite leak channel density', 'S/cm2'), - ('Dendrite Km channel density', 'pS/micron2') + ('Soma Kv channel density', 'S/cm2', 'soma_gkbar_hh2'), + ('Soma Na channel density', 'S/cm2', 'soma_gnabar_hh2'), + ('Soma leak reversal', 'mV', 'soma_el_hh2'), + ('Soma leak channel density', 'S/cm2', 'soma_gl_hh2'), + ('Soma Km channel density', 'pS/micron2', 'soma_gbar_km'), + ('Dendrite Kv channel density', 'S/cm2', 'dend_gkbar_hh2'), + ('Dendrite Na channel density', 'S/cm2', 'dend_gnabar_hh2'), + ('Dendrite leak reversal', 'mV', 'dend_el_hh2'), + ('Dendrite leak channel density', 'S/cm2', 'dend_gl_hh2'), + ('Dendrite Km channel density', 'pS/micron2', 'dend_gbar_km') ], "Biophysics L5": [ - ('Soma Kv channel density', 'S/cm2'), - ('Soma Na channel density', 'S/cm2'), - ('Soma leak reversal', 'mV'), - ('Soma leak channel density', 'S/cm2'), - ('Soma Ca channel density', 'pS/micron2'), - ('Soma Ca decay time', 'ms'), - ('Soma Kca channel density', 'pS/micron2'), - ('Soma Km channel density', 'pS/micron2'), - ('Soma CaT channel density', 'S/cm2'), - ('Soma HCN channel density', 'S/cm2'), - ('Dendrite Kv channel density', 'S/cm2'), - ('Dendrite Na channel density', 'S/cm2'), - ('Dendrite leak reversal', 'mV'), - ('Dendrite leak channel density', 'S/cm2'), - ('Dendrite KCa channel density', 'pS/micron2'), - ('Dendrite Km channel density', 'pS/micron2'), - ('Dendrite CaT channel density', 'S/cm2'), - ('Dendrite HCN channel density', 'S/cm2') + ('Soma Kv channel density', 'S/cm2', 'soma_gkbar_hh2'), + ('Soma Na channel density', 'S/cm2', 'soma_gnabar_hh2'), + ('Soma leak reversal', 'mV', 'soma_el_hh2'), + ('Soma leak channel density', 'S/cm2', 'soma_gl_hh2'), + ('Soma Ca channel density', 'pS/micron2', 'soma_gbar_ca'), + ('Soma Ca decay time', 'ms', 'soma_taur_cad'), + ('Soma Kca channel density', 'pS/micron2', 'soma_gbar_kca'), + ('Soma Km channel density', 'pS/micron2', 'soma_gbar_km'), + ('Soma CaT channel density', 'S/cm2', 'soma_gbar_cat'), + ('Soma HCN channel density', 'S/cm2', 'soma_gbar_ar'), + ('Dendrite Kv channel density', 'S/cm2', 'dend_gkbar_hh2'), + ('Dendrite Na channel density', 'S/cm2', 'dend_gnabar_hh2'), + ('Dendrite leak reversal', 'mV', 'dend_el_hh2'), + ('Dendrite leak channel density', 'S/cm2', 'dend_gl_hh2'), + ('Dendrite Ca channel density', 'pS/micron2', 'dend_gbar_ca'), + ('Dendrite Ca decay time', 'ms', 'dend_taur_cad'), + ('Dendrite KCa channel density', 'pS/micron2', 'dend_gbar_kca'), + ('Dendrite Km channel density', 'pS/micron2', 'dend_gbar_km'), + ('Dendrite CaT channel density', 'S/cm2', 'dend_gbar_cat'), + ('Dendrite HCN channel density', 'S/cm2', 'dend_gbar_ar') ] } @@ -1372,11 +1374,11 @@ def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, # get_cell_params_dic_values(network.cell_types) for cell_type in cell_types: layer_parameters = list() - for layer in cell_parameters_dic.keys(): + for layer in cell_parameters_dict.keys(): if 'Biophysic' in layer and cell_type not in layer: continue - for parameter in cell_parameters_dic[layer]: + for parameter in cell_parameters_dict[layer]: param_name = parameter[0] param_units = parameter[1] description = f"{param_name} ({param_units})" From 56f758f1bf949072188362417cba94c7a57d3a33 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Tue, 9 Jul 2024 14:37:24 -0400 Subject: [PATCH 09/26] MAINT: Added default values for gui cell params floatfields --- hnn_core/gui/gui.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 2d3df767d..3f8a17914 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -26,6 +26,8 @@ from hnn_core.network import pick_connection from hnn_core.params import _extract_drive_specs_from_hnn_params from hnn_core.dipole import _read_dipole_txt +from hnn_core.params_default import (get_L2Pyr_params_default, + get_L5Pyr_params_default) import base64 import zipfile @@ -1366,8 +1368,9 @@ def add_network_connectivity_tab(network, connectivity_out, def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, cell_layer_radio_button, cell_type_radio_button, layout): - - cell_types = ["L2", "L5"] + L2_defautl_values = get_L2Pyr_params_default() + L5_default_values = get_L5Pyr_params_default() + cell_types = [("L2", L2_defautl_values), ("L5", L5_default_values)] style = {'description_width': '235px'} kwargs = dict(layout=layout, style=style) @@ -1375,22 +1378,26 @@ def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, for cell_type in cell_types: layer_parameters = list() for layer in cell_parameters_dict.keys(): - if 'Biophysic' in layer and cell_type not in layer: + if 'Biophysic' in layer and cell_type[0] not in layer: continue for parameter in cell_parameters_dict[layer]: - param_name = parameter[0] - param_units = parameter[1] + param_name, param_units, params_key = (parameter[0], + parameter[1], + parameter[2]) + default_value = get_cell_param_default_value( + f'{cell_type[0]}Pyr_{params_key}', cell_type[1]) description = f"{param_name} ({param_units})" - text_field = BoundedFloatText(value=0.0, - min=0, - max=10.0, + min_value = -1000.0 if param_units not in 'ms' else 0 + text_field = BoundedFloatText(value=default_value, + min=min_value, + max=1000.0, step=0.1, description=description, disabled=False, **kwargs) layer_parameters.append(text_field) - cell_pameters_key = cell_type + "_" + layer + cell_pameters_key = f'{cell_type[0]}_{layer}' cell_pameters_vboxes[cell_pameters_key] = VBox(layer_parameters) layer_parameters.clear() @@ -1407,6 +1414,10 @@ def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, cell_layer_radio_button.value)) +def get_cell_param_default_value(cell_type_key, param_dict): + return param_dict[cell_type_key] + + def get_cell_params_dic_values(network_cell_types): # cell_types = [ct for ct in network_cell_types.keys() # if "pyramidal" in ct] From 6a9a8610e492a2af4bf82cf3fc05112616419f71 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 09:59:26 -0400 Subject: [PATCH 10/26] MAINT: Setting up cell params on run simulation button clicked --- hnn_core/gui/gui.py | 204 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 183 insertions(+), 21 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 3f8a17914..27912ea38 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -45,8 +45,9 @@ ('Dendrite capacitive density', 'F/cm2', 'dend_cm'), ('Dendrite resistivity', 'ohm-cm', 'dend_Ra'), ('Apical Dendrite Trunk length', 'micron', 'apicaltrunk_L'), - ('Apical Dendrite 1 length', 'micron', 'apicaltrunk_diam'), - ('Apical Dendrite 1 diameter', 'micron', 'apical1_L'), + ('Apical Dendrite Trunk diameter', 'micron', 'apicaltrunk_diam'), + ('Apical Dendrite 1 length', 'micron', 'apical1_L'), + ('Apical Dendrite 1 diameter', 'micron', 'apical1_diam'), ('Apical Dendrite Tuft length', 'micron', 'apicaltuft_L'), ('Apical Dendrite Tuft diameter', 'micron', 'apicaltuft_diam'), ('Oblique Apical Dendrite length', 'micron', 'apicaloblique_L'), @@ -385,7 +386,7 @@ def __init__(self, theme_color="#8A2BE2", self.connectivity_widgets = list() # Cell parameter list - self.cell_pameters = dict() + self.cell_pameters_widgets = dict() self._init_ui_components() self.add_logging_window_logger() @@ -507,7 +508,7 @@ def _on_upload_connectivity(change): self._log_out, self.drive_boxes, self.drive_widgets, self._drives_out, self._connectivity_out, self.connectivity_widgets, self._cell_params_out, - self.cell_pameters, self.cell_layer_radio_button, + self.cell_pameters_widgets, self.cell_layer_radio_button, self.cell_type_radio_button, self.layout['drive_textbox'], "connectivity") @@ -517,7 +518,7 @@ def _on_upload_drives(change): self._log_out, self.drive_boxes, self.drive_widgets, self._drives_out, self._connectivity_out, self.connectivity_widgets, self._cell_params_out, - self.cell_pameters, self.cell_layer_radio_button, + self.cell_pameters_widgets, self.cell_layer_radio_button, self.cell_type_radio_button, self.layout['drive_textbox'], "drives") @@ -533,7 +534,7 @@ def _run_button_clicked(b): self.widget_mpi_cmd, self.widget_n_jobs, self.params, self._simulation_status_bar, self._simulation_status_contents, self.connectivity_widgets, self.viz_manager, - self.simulation_list_widget) + self.simulation_list_widget, self.cell_pameters_widgets) def _simulation_list_change(value): _simulation_data, file_extension = ( @@ -559,12 +560,14 @@ def _driver_type_change(value): True if value.new == "Tonic" else False) def _cell_type_radio_change(value): - _update_cell_params_vbox(self._cell_params_out, self.cell_pameters, + _update_cell_params_vbox(self._cell_params_out, + self.cell_pameters_widgets, value.new, self.cell_layer_radio_button.value) def _cell_layer_radio_change(value): - _update_cell_params_vbox(self._cell_params_out, self.cell_pameters, + _update_cell_params_vbox(self._cell_params_out, + self.cell_pameters_widgets, self.cell_type_radio_button.value, value.new) @@ -678,7 +681,7 @@ def compose(self, return_layout=True): self.drive_boxes, self._connectivity_out, self.connectivity_widgets, self._cell_params_out, - self.cell_pameters, + self.cell_pameters_widgets, self.cell_layer_radio_button, self.cell_type_radio_button, self.widget_tstop, self.layout) @@ -1403,9 +1406,6 @@ def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, # clear existing connectivity cell_params_out.clear_output() - # while len(cell_params_out) > 0: - # cell_params_out.pop() - # cell_params_out.pop() # Add cell parameters display(_update_cell_params_vbox(cell_params_out, @@ -1562,6 +1562,7 @@ def on_upload_params_change(change, tstop, dt, log_out, drive_boxes, def _init_network_from_widgets(params, dt, tstop, single_simulation_data, drive_widgets, connectivity_textfields, + cell_params_vboxes, add_drive=True): """Construct network and add drives.""" print("init network") @@ -1573,21 +1574,38 @@ def _init_network_from_widgets(params, dt, tstop, single_simulation_data, ) # adjust connectivity according to the connectivity_tab for connectivity_slider in connectivity_textfields: - for vbox in connectivity_slider: + for vbox_key in connectivity_slider: conn_indices = pick_connection( net=single_simulation_data['net'], - src_gids=vbox._belongsto['src_gids'], - target_gids=vbox._belongsto['target_gids'], - loc=vbox._belongsto['location'], - receptor=vbox._belongsto['receptor']) + src_gids=vbox_key._belongsto['src_gids'], + target_gids=vbox_key._belongsto['target_gids'], + loc=vbox_key._belongsto['location'], + receptor=vbox_key._belongsto['receptor']) if len(conn_indices) > 0: assert len(conn_indices) == 1 conn_idx = conn_indices[0] single_simulation_data['net'].connectivity[conn_idx][ - 'nc_dict']['A_weight'] = vbox.children[1].value + 'nc_dict']['A_weight'] = vbox_key.children[1].value single_simulation_data['net'].connectivity[conn_idx][ - 'probability'] = vbox.children[2].value + 'probability'] = vbox_key.children[2].value + + # Update cell params + + update_functions = { + 'Geometry': update_geometry_cell_params, + 'Synapses': update_synapse_cell_params, + 'L2_Biophysics': update_L2_biophysics_cell_params, + 'L5_Biophysics': update_L5_biophysics_cell_params + } + + # Update cell params + for vbox_key, cell_param_list in cell_params_vboxes.items(): + for key, update_function in update_functions.items(): + if key in vbox_key: + update_function(single_simulation_data['net'], vbox_key, + cell_param_list.children) + break if add_drive is False: return @@ -1677,7 +1695,8 @@ def run_button_clicked(widget_simulation_name, log_out, drive_widgets, all_data, dt, tstop, ntrials, backend_selection, mpi_cmd, n_jobs, params, simulation_status_bar, simulation_status_contents, connectivity_textfields, - viz_manager, simulations_list_widget): + viz_manager, simulations_list_widget, + cell_pameters_widgets): """Run the simulation and plot outputs.""" simulation_data = all_data["simulation_data"] with log_out: @@ -1695,7 +1714,8 @@ def run_button_clicked(widget_simulation_name, log_out, drive_widgets, _init_network_from_widgets(params, dt, tstop, simulation_data[_sim_name], drive_widgets, - connectivity_textfields) + connectivity_textfields, + cell_pameters_widgets) print("start simulation") if backend_selection.value == "MPI": @@ -1741,6 +1761,148 @@ def _update_cell_params_vbox(cell_type_out, cell_parameters_list, display(cell_parameters_list[cell_parameters_key]) +def update_geometry_cell_params(net, cell_param_key, param_list): + cell_params = param_list + cell_type = f'{cell_param_key.split("_")[0]}_pyramidal' + + sections = net.cell_types[cell_type].sections + # Soma + sections['soma']._L = cell_params[0].value + sections['soma']._diam = cell_params[1].value + sections['soma']._cm = cell_params[2].value + sections['soma']._Ra = cell_params[3].value + + # Dendrite common parameters + dendrite_cm = cell_params[4].value + dendrite_Ra = cell_params[5].value + + dendrite_sections = [ + 'apical_trunk', 'apical_1', 'apical_tuft', 'apical_oblique', + 'basal_1', 'basal_2', 'basal_3' + ] + + param_indices = [ + (6, 7), (8, 9), (10, 11), (12, 13), (14, 15), (16, 17), (18, 19)] + + # Dentrite + for section, indices in zip(dendrite_sections, param_indices): + sections[section]._L = cell_params[indices[0]].value + sections[section]._diam = cell_params[indices[1]].value + sections[section]._cm = dendrite_cm + sections[section]._Ra = dendrite_Ra + + +def update_synapse_cell_params(net, cell_param_key, param_list): + cell_params = param_list + cell_type = f'{cell_param_key.split("_")[0]}_pyramidal' + network_synapses = net.cell_types[cell_type].synapses + synapse_sections = ['ampa', 'nmda', 'gabaa', 'gabab'] + + param_indices = [ + (0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)] + + # Update Dentrite + for section, indices in zip(synapse_sections, param_indices): + network_synapses[section]['e'] = cell_params[indices[0]].value + network_synapses[section]['tau1'] = cell_params[indices[1]].value + network_synapses[section]['tau2'] = cell_params[indices[2]].value + + +def update_L2_biophysics_cell_params(net, cell_param_key, param_list): + + cell_type = f'{cell_param_key.split("_")[0]}_pyramidal' + sections = net.cell_types[cell_type].sections + # Soma + mechs_params = { + 'hh2': { + 'gkbar_hh2': param_list[0].value, + 'gnabar_hh2': param_list[1].value, + 'el_hh2': param_list[2].value, + 'gl_hh2': param_list[3].value}, + 'km': { + 'gbar_km': param_list[4].value} + } + + sections['soma'].mechs.update(mechs_params) + + # dendrites + mechs_params['hh2'] = { + 'gkbar_hh2': param_list[5].value, + 'gnabar_hh2': param_list[6].value, + 'el_hh2': param_list[7].value, + 'gl_hh2': param_list[8].value} + mechs_params['km'] = { + 'gbar_km': param_list[9].value} + + update_common_dendrite_sections(sections, mechs_params) + + +def update_L5_biophysics_cell_params(net, cell_param_key, param_list): + cell_type = f'{cell_param_key.split("_")[0]}_pyramidal' + sections = net.cell_types[cell_type].sections + # Soma + mechs_params = { + 'hh2': + { + 'gkbar_hh2': param_list[0].value, + 'gnabar_hh2': param_list[1].value, + 'el_hh2': param_list[2].value, + 'gl_hh2': param_list[3].value + }, + 'ca': + { + 'gbar_ca': param_list[4].value + }, + 'cad': + { + 'taur_cad': param_list[5].value + }, + 'kca': + { + 'gbar_kca': param_list[6].value + }, + 'km': + { + 'gbar_km': param_list[7].value + }, + 'cat': + { + 'gbar_cat': param_list[8].value + }, + 'ar': + { + 'gbar_ar': param_list[9].value + } + } + + sections['soma'].mechs.update(mechs_params) + + # dendrites + mechs_params['hh2'] = { + 'gkbar_hh2': param_list[9].value, + 'gnabar_hh2': param_list[10].value, + 'el_hh2': param_list[11].value, + 'gl_hh2': param_list[12].value} + + mechs_params['ca'] = {'gbar_ca': param_list[13].value} + mechs_params['cad'] = {'taur_cad': param_list[14].value} + mechs_params['kca'] = {'gbar_kca': param_list[15].value} + mechs_params['km'] = {'gbar_km': param_list[16].value} + mechs_params['cat'] = {'gbar_cat': param_list[17].value} + mechs_params['ar'] = {'gbar_ar': param_list[18].value} + + update_common_dendrite_sections(sections, mechs_params) + + +def update_common_dendrite_sections(sections, mechs_params): + dendrite_sections = [ + 'apical_trunk', 'apical_1', 'apical_tuft', 'apical_oblique', + 'basal_1', 'basal_2', 'basal_3' + ] + for section in dendrite_sections: + sections[section].mechs.update(mechs_params) + + def _serialize_simulation(log_out, sim_data, simulation_list_widget): # Only download if there is there is at least one simulation sim_name = simulation_list_widget.value From 9f69ac4eb3c6c7720b42c5e2d9dba50165beca00 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 11:10:30 -0400 Subject: [PATCH 11/26] MAINT: Fixing L5 Biophysics cell params input and gui test cases --- hnn_core/gui/gui.py | 22 +++++++++++----------- hnn_core/tests/test_gui.py | 7 +++++-- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 27912ea38..7bc0fc806 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1879,17 +1879,17 @@ def update_L5_biophysics_cell_params(net, cell_param_key, param_list): # dendrites mechs_params['hh2'] = { - 'gkbar_hh2': param_list[9].value, - 'gnabar_hh2': param_list[10].value, - 'el_hh2': param_list[11].value, - 'gl_hh2': param_list[12].value} - - mechs_params['ca'] = {'gbar_ca': param_list[13].value} - mechs_params['cad'] = {'taur_cad': param_list[14].value} - mechs_params['kca'] = {'gbar_kca': param_list[15].value} - mechs_params['km'] = {'gbar_km': param_list[16].value} - mechs_params['cat'] = {'gbar_cat': param_list[17].value} - mechs_params['ar'] = {'gbar_ar': param_list[18].value} + 'gkbar_hh2': param_list[10].value, + 'gnabar_hh2': param_list[11].value, + 'el_hh2': param_list[12].value, + 'gl_hh2': param_list[13].value} + + mechs_params['ca'] = {'gbar_ca': param_list[14].value} + mechs_params['cad'] = {'taur_cad': param_list[15].value} + mechs_params['kca'] = {'gbar_kca': param_list[16].value} + mechs_params['km'] = {'gbar_km': param_list[17].value} + mechs_params['cat'] = {'gbar_cat': param_list[18].value} + mechs_params['ar'] = {'gbar_ar': param_list[19].value} update_common_dendrite_sections(sections, mechs_params) diff --git a/hnn_core/tests/test_gui.py b/hnn_core/tests/test_gui.py index 2488f5bc9..be815fde5 100644 --- a/hnn_core/tests/test_gui.py +++ b/hnn_core/tests/test_gui.py @@ -165,6 +165,7 @@ def test_gui_change_connectivity(): _single_simulation, gui.drive_widgets, gui.connectivity_widgets, + gui.cell_pameters_widgets, add_drive=False) # test if the new value is reflected in the network @@ -203,7 +204,8 @@ def test_gui_init_network(): _single_simulation['net'] = jones_2009_model(gui.params) _init_network_from_widgets(gui.params, gui.widget_dt, gui.widget_tstop, _single_simulation, gui.drive_widgets, - gui.connectivity_widgets) + gui.connectivity_widgets, + gui.cell_pameters_widgets) plt.close('all') # copied from test_network.py @@ -657,6 +659,7 @@ def test_gui_add_tonic_input(setup_gui): # Add tonic bias to the simulation _init_network_from_widgets(gui.params, gui.widget_dt, gui.widget_tstop, _single_simulation, gui.drive_widgets, - gui.connectivity_widgets) + gui.connectivity_widgets, + gui.cell_pameters_widgets) assert _single_simulation['net'].external_biases['tonic'] is not None From 6b5575851d4fb591595c77b2c938b24c59a95bf6 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 13:00:58 -0400 Subject: [PATCH 12/26] TST: Adding test for gui cell params --- hnn_core/gui/gui.py | 36 +++++++++++++++++++++++------------- hnn_core/tests/test_gui.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 7bc0fc806..46bd9562c 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -364,10 +364,11 @@ def __init__(self, theme_color="#8A2BE2", 'Delete drives', 'success', layout=self.layout['btn'], button_color=self.layout['theme_color']) - self.cell_type_radio_button = RadioButtons( + self.cell_type_radio_buttons = RadioButtons( options=['L2', 'L5'], description='Cell type:') - self.cell_layer_radio_button = RadioButtons( + + self.cell_layer_radio_buttons = RadioButtons( options=['Geometry', 'Synapses', 'Biophysics'], description='Layer:') @@ -391,6 +392,12 @@ def __init__(self, theme_color="#8A2BE2", self._init_ui_components() self.add_logging_window_logger() + def get_cell_parameters_dict(self): + """Returns the number of elements in the + cell_parameters_dict dictionary. + This is for testing purposes """ + return cell_parameters_dict + def _init_html_download_button(self): b64 = base64.b64encode("".encode()) payload = b64.decode() @@ -508,8 +515,8 @@ def _on_upload_connectivity(change): self._log_out, self.drive_boxes, self.drive_widgets, self._drives_out, self._connectivity_out, self.connectivity_widgets, self._cell_params_out, - self.cell_pameters_widgets, self.cell_layer_radio_button, - self.cell_type_radio_button, self.layout['drive_textbox'], + self.cell_pameters_widgets, self.cell_layer_radio_buttons, + self.cell_type_radio_buttons, self.layout['drive_textbox'], "connectivity") def _on_upload_drives(change): @@ -518,8 +525,8 @@ def _on_upload_drives(change): self._log_out, self.drive_boxes, self.drive_widgets, self._drives_out, self._connectivity_out, self.connectivity_widgets, self._cell_params_out, - self.cell_pameters_widgets, self.cell_layer_radio_button, - self.cell_type_radio_button, self.layout['drive_textbox'], + self.cell_pameters_widgets, self.cell_layer_radio_buttons, + self.cell_type_radio_buttons, self.layout['drive_textbox'], "drives") def _on_upload_data(change): @@ -563,12 +570,12 @@ def _cell_type_radio_change(value): _update_cell_params_vbox(self._cell_params_out, self.cell_pameters_widgets, value.new, - self.cell_layer_radio_button.value) + self.cell_layer_radio_buttons.value) def _cell_layer_radio_change(value): _update_cell_params_vbox(self._cell_params_out, self.cell_pameters_widgets, - self.cell_type_radio_button.value, + self.cell_type_radio_buttons.value, value.new) self.widget_backend_selection.observe(_handle_backend_change, 'value') @@ -582,8 +589,10 @@ def _cell_layer_radio_change(value): self.simulation_list_widget.observe(_simulation_list_change, 'value') self.widget_drive_type_selection.observe(_driver_type_change, 'value') - self.cell_type_radio_button.observe(_cell_type_radio_change, 'value') - self.cell_layer_radio_button.observe(_cell_layer_radio_change, 'value') + self.cell_type_radio_buttons.observe(_cell_type_radio_change, + 'value') + self.cell_layer_radio_buttons.observe(_cell_layer_radio_change, + 'value') def compose(self, return_layout=True): """Compose widgets. @@ -609,7 +618,8 @@ def compose(self, return_layout=True): ]) cell_parameters = VBox([ - HBox([self.cell_type_radio_button, self.cell_layer_radio_button]), + HBox([self.cell_type_radio_buttons, + self.cell_layer_radio_buttons]), self._cell_params_out ]) @@ -682,8 +692,8 @@ def compose(self, return_layout=True): self.connectivity_widgets, self._cell_params_out, self.cell_pameters_widgets, - self.cell_layer_radio_button, - self.cell_type_radio_button, + self.cell_layer_radio_buttons, + self.cell_type_radio_buttons, self.widget_tstop, self.layout) if not return_layout: diff --git a/hnn_core/tests/test_gui.py b/hnn_core/tests/test_gui.py index be815fde5..648550c30 100644 --- a/hnn_core/tests/test_gui.py +++ b/hnn_core/tests/test_gui.py @@ -663,3 +663,37 @@ def test_gui_add_tonic_input(setup_gui): gui.cell_pameters_widgets) assert _single_simulation['net'].external_biases['tonic'] is not None + + +def test_gui_cell_params_widgets(setup_gui): + """Test if gui add different type of drives.""" + gui = setup_gui + _single_simulation = {} + _single_simulation['net'] = jones_2009_model(gui.params) + _single_simulation['net'].cell_types + pyramid_cell_types = [cell_type for cell_type + in _single_simulation['net'].cell_types + if "pyramidal" in cell_type] + assert (len(pyramid_cell_types) == 2) + + # Check cell types map directly to the gui widgets + layers = gui.cell_layer_radio_buttons.options + assert (len(layers) == 3) + + keys = gui.cell_pameters_widgets.keys() + num_cell_params = 0 + for pyramid_cell_type in pyramid_cell_types: + cell_type = pyramid_cell_type.split('_')[0] + for cell_layer in layers: + key = f'{cell_type}_{cell_layer}' + assert (any(key in k for k in keys)) + num_cell_params = num_cell_params + 1 + + assert (len(keys) == num_cell_params) + + # Check the if the cell params dictionary has been updated + cell_params = gui.get_cell_parameters_dict() + assert (len(cell_params['Geometry']) == 20) + assert (len(cell_params['Synapses']) == 12) + assert (len(cell_params['Biophysics L2']) == 10) + assert (len(cell_params['Biophysics L5']) == 20) From 0c6b30a67c5467c4cb2c1952400d57ef2f6f767a Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 15:14:22 -0400 Subject: [PATCH 13/26] MAINT: Removing commented code and debuggy dev import --- hnn_core/gui/gui.py | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 46bd9562c..c8747ab49 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -628,15 +628,6 @@ def compose(self, return_layout=True): connectivity_configuration.titles = ['Network connectivity', 'Cell Parameters'] - # accordions to group local-connectivity by cell type - # connectivity_boxes = [ - # VBox(slider) for slider in self.connectivity_widgets] - # connectivity_names = ( - # 'Layer 2/3 Pyramidal', 'Layer 5 Pyramidal', 'Layer 2 Basket', - # 'Layer 5 Basket') - # cell_connectivity = Accordion(children=connectivity_boxes) - # cell_connectivity.titles = [s for s in connectivity_names] - drive_selections = VBox([ self.add_drive_button, self.widget_drive_type_selection, self.widget_location_selection], @@ -1315,7 +1306,7 @@ def add_connectivity_tab(params, connectivity_out, connectivity_textfields, connectivity_textfields) # build cell parameters tab - add_cell_parameters_tab(net, cell_params_out, cell_pameters_vboxes, + add_cell_parameters_tab(cell_params_out, cell_pameters_vboxes, cell_layer_radio_button, cell_type_radio_button, layout) return net @@ -1378,7 +1369,7 @@ def add_network_connectivity_tab(network, connectivity_out, return network -def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, +def add_cell_parameters_tab(cell_params_out, cell_pameters_vboxes, cell_layer_radio_button, cell_type_radio_button, layout): L2_defautl_values = get_L2Pyr_params_default() @@ -1387,7 +1378,6 @@ def add_cell_parameters_tab(network, cell_params_out, cell_pameters_vboxes, style = {'description_width': '235px'} kwargs = dict(layout=layout, style=style) - # get_cell_params_dic_values(network.cell_types) for cell_type in cell_types: layer_parameters = list() for layer in cell_parameters_dict.keys(): @@ -1991,9 +1981,5 @@ def launch(): You can pass voila commandline parameters as usual. """ from voila.app import main - import debugpy - debugpy.listen(5678) - print("Waiting for debugger attach") - debugpy.wait_for_client() notebook_path = Path(__file__).parent / 'hnn_widget.ipynb' main([str(notebook_path.resolve()), *sys.argv[1:]]) From 5ed331784756bab01dca6251f4fdf1c01a2d4053 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 15:21:21 -0400 Subject: [PATCH 14/26] MAINT: Removing unsued code --- hnn_core/gui/gui.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index c8747ab49..c212399d8 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1418,17 +1418,6 @@ def get_cell_param_default_value(cell_type_key, param_dict): return param_dict[cell_type_key] -def get_cell_params_dic_values(network_cell_types): - # cell_types = [ct for ct in network_cell_types.keys() - # if "pyramidal" in ct] - ... - # for type in cell_types: - # cell_type = network_cell_types[type] - # # get geometry params - - # cell_types.sections['soma'] - - def add_drive_tab(params, log_out, drives_out, drive_widgets, drive_boxes, tstop, layout): net = jones_2009_model(params) From c70f920c04164b63775885ff7ad23be8d920e871 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 16:35:30 -0400 Subject: [PATCH 15/26] MAINT: increase cell params textfields --- hnn_core/gui/gui.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index c212399d8..de1e48fca 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1399,6 +1399,7 @@ def add_cell_parameters_tab(cell_params_out, cell_pameters_vboxes, description=description, disabled=False, **kwargs) + text_field.layout.width = "350px" layer_parameters.append(text_field) cell_pameters_key = f'{cell_type[0]}_{layer}' cell_pameters_vboxes[cell_pameters_key] = VBox(layer_parameters) From 70aae46a8c2c5ffc7ad6e0f5cba67cc79d443803 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 16:48:24 -0400 Subject: [PATCH 16/26] MAINT: increased gui cell params description width to fix large label --- hnn_core/gui/gui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index de1e48fca..b01b92c85 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1375,7 +1375,7 @@ def add_cell_parameters_tab(cell_params_out, cell_pameters_vboxes, L2_defautl_values = get_L2Pyr_params_default() L5_default_values = get_L5Pyr_params_default() cell_types = [("L2", L2_defautl_values), ("L5", L5_default_values)] - style = {'description_width': '235px'} + style = {'description_width': '255px'} kwargs = dict(layout=layout, style=style) for cell_type in cell_types: From d646b74312c1354fe248ae93d956268753c878f1 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 17:16:32 -0400 Subject: [PATCH 17/26] STY: Added the word pyramidal to the cell types radio buttons --- doc/gui/tutorial_erp.ipynb | 2 +- hnn_core/gui/gui.py | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/doc/gui/tutorial_erp.ipynb b/doc/gui/tutorial_erp.ipynb index 7c2642d57..d952ca6c6 100644 --- a/doc/gui/tutorial_erp.ipynb +++ b/doc/gui/tutorial_erp.ipynb @@ -234,7 +234,7 @@ "metadata": {}, "outputs": [], "source": [ - "gui._simulate_left_tab_click(\"Connectivity\")" + "gui._simulate_left_tab_click(\"Network\")" ] }, { diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index b01b92c85..e9525e207 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -365,7 +365,7 @@ def __init__(self, theme_color="#8A2BE2", button_color=self.layout['theme_color']) self.cell_type_radio_buttons = RadioButtons( - options=['L2', 'L5'], + options=['L2 Pyramidal', 'L5 Pyramidal'], description='Cell type:') self.cell_layer_radio_buttons = RadioButtons( @@ -567,15 +567,17 @@ def _driver_type_change(value): True if value.new == "Tonic" else False) def _cell_type_radio_change(value): + cell_type = value.new.split(' ')[0] _update_cell_params_vbox(self._cell_params_out, self.cell_pameters_widgets, - value.new, + cell_type, self.cell_layer_radio_buttons.value) def _cell_layer_radio_change(value): + cell_type = self.cell_type_radio_buttons.value.split(' ')[0] _update_cell_params_vbox(self._cell_params_out, self.cell_pameters_widgets, - self.cell_type_radio_buttons.value, + cell_type, value.new) self.widget_backend_selection.observe(_handle_backend_change, 'value') @@ -625,8 +627,8 @@ def compose(self, return_layout=True): connectivity_configuration.children = [connectivity_box, cell_parameters] - connectivity_configuration.titles = ['Network connectivity', - 'Cell Parameters'] + connectivity_configuration.titles = ['Connectivity', + 'Cell parameters'] drive_selections = VBox([ self.add_drive_button, self.widget_drive_type_selection, @@ -649,7 +651,7 @@ def compose(self, return_layout=True): simulation_box, connectivity_configuration, drives_options, config_panel, ] - titles = ('Simulation', 'Connectivity', 'External drives', + titles = ('Simulation', 'Network', 'External drives', 'Visualization') for idx, title in enumerate(titles): left_tab.set_title(idx, title) @@ -1409,9 +1411,10 @@ def add_cell_parameters_tab(cell_params_out, cell_pameters_vboxes, cell_params_out.clear_output() # Add cell parameters + cell_type = cell_type_radio_button.value.split(' ')[0] display(_update_cell_params_vbox(cell_params_out, cell_pameters_vboxes, - cell_type_radio_button.value, + cell_type, cell_layer_radio_button.value)) @@ -1971,5 +1974,9 @@ def launch(): You can pass voila commandline parameters as usual. """ from voila.app import main + import debugpy + debugpy.listen(5678) + print("Waiting for debugger attach") + debugpy.wait_for_client() notebook_path = Path(__file__).parent / 'hnn_widget.ipynb' main([str(notebook_path.resolve()), *sys.argv[1:]]) From 39b33c94baff2e0ef8cff657653496813bd2b6e6 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 17:19:49 -0400 Subject: [PATCH 18/26] STY: Fixed typo in variable --- hnn_core/gui/gui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index e9525e207..5d8279300 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1374,9 +1374,9 @@ def add_network_connectivity_tab(network, connectivity_out, def add_cell_parameters_tab(cell_params_out, cell_pameters_vboxes, cell_layer_radio_button, cell_type_radio_button, layout): - L2_defautl_values = get_L2Pyr_params_default() + L2_default_values = get_L2Pyr_params_default() L5_default_values = get_L5Pyr_params_default() - cell_types = [("L2", L2_defautl_values), ("L5", L5_default_values)] + cell_types = [("L2", L2_default_values), ("L5", L5_default_values)] style = {'description_width': '255px'} kwargs = dict(layout=layout, style=style) From e4f7cbd95d94b430959211bbd0f8008b8abf792b Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 18:00:15 -0400 Subject: [PATCH 19/26] MAINT: Removed debuggy init code --- hnn_core/gui/gui.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 5d8279300..b0f6b72df 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1974,9 +1974,5 @@ def launch(): You can pass voila commandline parameters as usual. """ from voila.app import main - import debugpy - debugpy.listen(5678) - print("Waiting for debugger attach") - debugpy.wait_for_client() notebook_path = Path(__file__).parent / 'hnn_widget.ipynb' main([str(notebook_path.resolve()), *sys.argv[1:]]) From e9bc7ffcc9a9f1930e9101391e0734ee9121f391 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Wed, 10 Jul 2024 18:35:33 -0400 Subject: [PATCH 20/26] MAINT: Applied comments in review --- hnn_core/gui/gui.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index b0f6b72df..e5b644de9 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -370,7 +370,7 @@ def __init__(self, theme_color="#8A2BE2", self.cell_layer_radio_buttons = RadioButtons( options=['Geometry', 'Synapses', 'Biophysics'], - description='Layer:') + description='Cell Properties:') # Plotting window @@ -1314,9 +1314,9 @@ def add_connectivity_tab(params, connectivity_out, connectivity_textfields, return net -def add_network_connectivity_tab(network, connectivity_out, +def add_network_connectivity_tab(net, connectivity_out, connectivity_textfields): - cell_types = [ct for ct in network.cell_types.keys()] + cell_types = [ct for ct in net.cell_types.keys()] receptors = ('ampa', 'nmda', 'gabaa', 'gabab') locations = ('proximal', 'distal', 'soma') @@ -1332,7 +1332,7 @@ def add_network_connectivity_tab(network, connectivity_out, # the connectivity list should be built on this level receptor_related_conn = {} for receptor in receptors: - conn_indices = pick_connection(net=network, + conn_indices = pick_connection(net=net, src_gids=src_gids, target_gids=target_gids, loc=location, @@ -1340,9 +1340,9 @@ def add_network_connectivity_tab(network, connectivity_out, if len(conn_indices) > 0: assert len(conn_indices) == 1 conn_idx = conn_indices[0] - current_w = network.connectivity[ + current_w = net.connectivity[ conn_idx]['nc_dict']['A_weight'] - current_p = network.connectivity[ + current_p = net.connectivity[ conn_idx]['probability'] # valid connection receptor_related_conn[receptor] = { @@ -1368,7 +1368,7 @@ def add_network_connectivity_tab(network, connectivity_out, with connectivity_out: display(cell_connectivity) - return network + return net def add_cell_parameters_tab(cell_params_out, cell_pameters_vboxes, @@ -1586,10 +1586,10 @@ def _init_network_from_widgets(params, dt, tstop, single_simulation_data, # Update cell params update_functions = { - 'Geometry': update_geometry_cell_params, - 'Synapses': update_synapse_cell_params, - 'L2_Biophysics': update_L2_biophysics_cell_params, - 'L5_Biophysics': update_L5_biophysics_cell_params + 'Geometry': _update_geometry_cell_params, + 'Synapses': _update_synapse_cell_params, + 'L2_Biophysics': _update_L2_biophysics_cell_params, + 'L5_Biophysics': _update_L5_biophysics_cell_params } # Update cell params @@ -1754,7 +1754,7 @@ def _update_cell_params_vbox(cell_type_out, cell_parameters_list, display(cell_parameters_list[cell_parameters_key]) -def update_geometry_cell_params(net, cell_param_key, param_list): +def _update_geometry_cell_params(net, cell_param_key, param_list): cell_params = param_list cell_type = f'{cell_param_key.split("_")[0]}_pyramidal' @@ -1785,7 +1785,7 @@ def update_geometry_cell_params(net, cell_param_key, param_list): sections[section]._Ra = dendrite_Ra -def update_synapse_cell_params(net, cell_param_key, param_list): +def _update_synapse_cell_params(net, cell_param_key, param_list): cell_params = param_list cell_type = f'{cell_param_key.split("_")[0]}_pyramidal' network_synapses = net.cell_types[cell_type].synapses @@ -1801,7 +1801,7 @@ def update_synapse_cell_params(net, cell_param_key, param_list): network_synapses[section]['tau2'] = cell_params[indices[2]].value -def update_L2_biophysics_cell_params(net, cell_param_key, param_list): +def _update_L2_biophysics_cell_params(net, cell_param_key, param_list): cell_type = f'{cell_param_key.split("_")[0]}_pyramidal' sections = net.cell_types[cell_type].sections @@ -1830,7 +1830,7 @@ def update_L2_biophysics_cell_params(net, cell_param_key, param_list): update_common_dendrite_sections(sections, mechs_params) -def update_L5_biophysics_cell_params(net, cell_param_key, param_list): +def _update_L5_biophysics_cell_params(net, cell_param_key, param_list): cell_type = f'{cell_param_key.split("_")[0]}_pyramidal' sections = net.cell_types[cell_type].sections # Soma From 114dcfc02462ebed69621b90be33c3c937401e92 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Thu, 11 Jul 2024 11:46:06 -0400 Subject: [PATCH 21/26] MAINT: Refactoing code due to the change in cell type radio buttons label --- hnn_core/gui/gui.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index e5b644de9..fc539cd04 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -567,17 +567,15 @@ def _driver_type_change(value): True if value.new == "Tonic" else False) def _cell_type_radio_change(value): - cell_type = value.new.split(' ')[0] _update_cell_params_vbox(self._cell_params_out, self.cell_pameters_widgets, - cell_type, + value.new, self.cell_layer_radio_buttons.value) def _cell_layer_radio_change(value): - cell_type = self.cell_type_radio_buttons.value.split(' ')[0] _update_cell_params_vbox(self._cell_params_out, self.cell_pameters_widgets, - cell_type, + self.cell_type_radio_buttons.value, value.new) self.widget_backend_selection.observe(_handle_backend_change, 'value') @@ -1403,7 +1401,7 @@ def add_cell_parameters_tab(cell_params_out, cell_pameters_vboxes, **kwargs) text_field.layout.width = "350px" layer_parameters.append(text_field) - cell_pameters_key = f'{cell_type[0]}_{layer}' + cell_pameters_key = f'{cell_type[0]} Pyramidal_{layer}' cell_pameters_vboxes[cell_pameters_key] = VBox(layer_parameters) layer_parameters.clear() @@ -1411,10 +1409,9 @@ def add_cell_parameters_tab(cell_params_out, cell_pameters_vboxes, cell_params_out.clear_output() # Add cell parameters - cell_type = cell_type_radio_button.value.split(' ')[0] display(_update_cell_params_vbox(cell_params_out, cell_pameters_vboxes, - cell_type, + cell_type_radio_button.value, cell_layer_radio_button.value)) @@ -1588,15 +1585,17 @@ def _init_network_from_widgets(params, dt, tstop, single_simulation_data, update_functions = { 'Geometry': _update_geometry_cell_params, 'Synapses': _update_synapse_cell_params, - 'L2_Biophysics': _update_L2_biophysics_cell_params, - 'L5_Biophysics': _update_L5_biophysics_cell_params + 'L2 Pyramidal_Biophysics': _update_L2_biophysics_cell_params, + 'L5 Pyramidal_Biophysics': _update_L5_biophysics_cell_params } # Update cell params for vbox_key, cell_param_list in cell_params_vboxes.items(): for key, update_function in update_functions.items(): if key in vbox_key: - update_function(single_simulation_data['net'], vbox_key, + # Remove 'Pyramidal' keyword + cell_type = vbox_key.split()[0] + update_function(single_simulation_data['net'], cell_type, cell_param_list.children) break @@ -1746,9 +1745,9 @@ def _update_cell_params_vbox(cell_type_out, cell_parameters_list, cell_type, cell_layer): cell_parameters_key = f"{cell_type}_{cell_layer}" if "Biophysics" in cell_layer: - cell_parameters_key += f" {cell_type}" + cell_parameters_key += f" {cell_type.split(' ')[0]}" - if cell_parameters_key in cell_parameters_key: + if cell_parameters_key in cell_parameters_list: cell_type_out.clear_output() with cell_type_out: display(cell_parameters_list[cell_parameters_key]) From 94b61b8041b3ef4ea588e711122a544d1253bfc2 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Thu, 11 Jul 2024 14:26:12 -0400 Subject: [PATCH 22/26] TST: Fixing gui cell params pytest --- hnn_core/tests/test_gui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hnn_core/tests/test_gui.py b/hnn_core/tests/test_gui.py index 648550c30..c5b984b49 100644 --- a/hnn_core/tests/test_gui.py +++ b/hnn_core/tests/test_gui.py @@ -685,7 +685,7 @@ def test_gui_cell_params_widgets(setup_gui): for pyramid_cell_type in pyramid_cell_types: cell_type = pyramid_cell_type.split('_')[0] for cell_layer in layers: - key = f'{cell_type}_{cell_layer}' + key = f'{cell_type} Pyramidal_{cell_layer}' assert (any(key in k for k in keys)) num_cell_params = num_cell_params + 1 From 62b880e37af052057ed33fb6206dde0b1f235a99 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Thu, 11 Jul 2024 14:47:26 -0400 Subject: [PATCH 23/26] MAINT: Updating dendrite sections using properties loop instead of harcoded array --- hnn_core/gui/gui.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index fc539cd04..1cef4af09 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1768,10 +1768,9 @@ def _update_geometry_cell_params(net, cell_param_key, param_list): dendrite_cm = cell_params[4].value dendrite_Ra = cell_params[5].value - dendrite_sections = [ - 'apical_trunk', 'apical_1', 'apical_tuft', 'apical_oblique', - 'basal_1', 'basal_2', 'basal_3' - ] + dendrite_sections = [name for name in sections.keys() + if name != 'soma' + ] param_indices = [ (6, 7), (8, 9), (10, 11), (12, 13), (14, 15), (16, 17), (18, 19)] @@ -1888,8 +1887,7 @@ def _update_L5_biophysics_cell_params(net, cell_param_key, param_list): def update_common_dendrite_sections(sections, mechs_params): dendrite_sections = [ - 'apical_trunk', 'apical_1', 'apical_tuft', 'apical_oblique', - 'basal_1', 'basal_2', 'basal_3' + name for name in sections.keys() if name != 'soma' ] for section in dendrite_sections: sections[section].mechs.update(mechs_params) From 3f1abf54291c7bda1c089970b38d535bacad6e55 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Fri, 12 Jul 2024 10:48:08 -0400 Subject: [PATCH 24/26] DOC: Added cell params feature entry in whats_new.rst --- doc/whats_new.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/whats_new.rst b/doc/whats_new.rst index 057865782..07c43a5e9 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -82,6 +82,10 @@ Changelog - Updated `plot_spikes_raster` logic to include all neurons in network model. Removed GUI exclusion from build, by `Abdul Samad Siddiqui`_ in :gh:`754`. +- Added GUI feature to read and modify cell parameters, + by `Camilo Diaz`_ in :gh:`806`. + + Bug ~~~ - Fix inconsistent connection mapping from drive gids to cell gids, by From 1274677a65b4efc264692c01942d0d5008bd9e68 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Fri, 12 Jul 2024 17:41:29 -0400 Subject: [PATCH 25/26] MAINT: Fixing python code in test_gui.py --- hnn_core/gui/gui.py | 1 - hnn_core/tests/test_gui.py | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py index 1cef4af09..bae6870d3 100644 --- a/hnn_core/gui/gui.py +++ b/hnn_core/gui/gui.py @@ -1593,7 +1593,6 @@ def _init_network_from_widgets(params, dt, tstop, single_simulation_data, for vbox_key, cell_param_list in cell_params_vboxes.items(): for key, update_function in update_functions.items(): if key in vbox_key: - # Remove 'Pyramidal' keyword cell_type = vbox_key.split()[0] update_function(single_simulation_data['net'], cell_type, cell_param_list.children) diff --git a/hnn_core/tests/test_gui.py b/hnn_core/tests/test_gui.py index c5b984b49..b08161f0c 100644 --- a/hnn_core/tests/test_gui.py +++ b/hnn_core/tests/test_gui.py @@ -676,7 +676,11 @@ def test_gui_cell_params_widgets(setup_gui): if "pyramidal" in cell_type] assert (len(pyramid_cell_types) == 2) - # Check cell types map directly to the gui widgets + # Check the if the cell params dictionary has been updated + # Security check for if parameters have been added or removed from the cell + # params dict. Any additions will need mappings added to the + # update_{*}_cell_params functions + layers = gui.cell_layer_radio_buttons.options assert (len(layers) == 3) @@ -687,7 +691,7 @@ def test_gui_cell_params_widgets(setup_gui): for cell_layer in layers: key = f'{cell_type} Pyramidal_{cell_layer}' assert (any(key in k for k in keys)) - num_cell_params = num_cell_params + 1 + num_cell_params += 1 assert (len(keys) == num_cell_params) From fd78a3635a0cd35797d812d39151f13b1be20fb9 Mon Sep 17 00:00:00 2001 From: Camilo Diaz Date: Fri, 12 Jul 2024 17:43:03 -0400 Subject: [PATCH 26/26] MAINT: Fixing python code in test_gui.py --- hnn_core/tests/test_gui.py | 1 - 1 file changed, 1 deletion(-) diff --git a/hnn_core/tests/test_gui.py b/hnn_core/tests/test_gui.py index b08161f0c..93c4cddcf 100644 --- a/hnn_core/tests/test_gui.py +++ b/hnn_core/tests/test_gui.py @@ -676,7 +676,6 @@ def test_gui_cell_params_widgets(setup_gui): if "pyramidal" in cell_type] assert (len(pyramid_cell_types) == 2) - # Check the if the cell params dictionary has been updated # Security check for if parameters have been added or removed from the cell # params dict. Any additions will need mappings added to the # update_{*}_cell_params functions