"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "gui.capture()\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d6efb437",
+ "metadata": {},
+ "source": [
+ "Notice that the power in the gamma band is much smaller in Layer 2/3 than in Layer 5. This is reflective, in part, of the fact that the length of the Layer 2/3 pyramidal neurons is smaller than Layer 5, and hence Layer 2/3 cells produce smaller current dipole moments that can be masked by activity in Layer 5 (see [1] for further discussion)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4872802a",
+ "metadata": {},
+ "source": [
+ "## 4. Adjusting parameters\n",
+ "\n",
+ "In the following simulations, we explore parameter alterations influencing the generation of gamma rhythms.\n",
+ "\n",
+ "Also note that before running/loading new simulations, we first remove the prior simulation by pressing the “Remove Simulation” button at the bottom of the GUI. If we do not do this, both simulation dipoles are displayed (old simulation with dotted line, new simulation with solid line; see “Tour of the GUI” for more details on simulation control).\n",
+ "\n",
+ "### 4.1 Two key parameters controlling gamma rhythmicity are cell “excitability” and network connectivity\n",
+ "\n",
+ "In this exercise, HNN will be used to explore the impact of changing several key parameters that control gamma rhythmicity in networks, including cell excitabilityand network connectivity. Cell “excitability” can be adjusted in many ways reflecting the intrinsic properties of a neuron (e.g. membrane resting potential) and/or the influence of external factors such as noisy background inputs or tonic drive via neuromodulation. Parameters controlling network connectivity include the synaptic connection strengths between cells and/or the time constants of synaptic activation. Here, we explore the influence of a few of these factors on gamma rhythmicity. To do so, we will examine activity in only one of the layers, namely Layer 5, by setting all inputs and connectivity in Layer 2/3 to zero.\n",
+ "\n",
+ "First, reload the parameter file gamma_L5weak_L2weak.param (see step 1 above). To turn off all off the Layer 2/3 activity, load the network parameters with:\n",
+ "\n",
+ " Load network\n",
+ "\n",
+ "Adjust parameters so that all Layer 2/3 weights are set to 0.0 as shown in the dialog boxes below."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "3d9b2a44",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c93dee8cb9874444a92fc90360a473c5",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "AppLayout(children=(HTML(value=\"\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# how do I do this?\u001b[39;00m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;66;03m# gui.drive_boxes[0]\u001b[39;00m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;66;03m#gui.connectivity_widgets \u001b[39;00m\n\u001b[0;32m----> 4\u001b[0m \u001b[38;5;28mdir\u001b[39m(\u001b[43mgui\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_connectivity_tab\u001b[49m)\n",
+ "\u001b[0;31mAttributeError\u001b[0m: 'HNNGUI' object has no attribute '_connectivity_tab'"
+ ]
+ }
+ ],
+ "source": [
+ "# how do I do this?\n",
+ "for key, title in gui._connectivity_tab['content']._titles.items():\n",
+ " soure_targets = title.split(\" \")[0].split(\"→\")\n",
+ " l2inst = all(['L2' in st for st in soure_targets])\n",
+ " if l2inst is True:\n",
+ " for widget_combined in gui.connectivity_widgets[int(key)]:\n",
+ " for widget in widget_combined.children:\n",
+ " if type(widget.value) in [float, int]:\n",
+ " widget.value = 0"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "81206631",
+ "metadata": {},
+ "source": [
+ "Next, load the Poisson input parameters by selecting:\n",
+ "\n",
+ " Drives > Poisson"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "4bef584f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gui._simulate_left_tab_click(\"External drives\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "id": "cd6dc1e0",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "gui.capture()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "fccf2408",
+ "metadata": {},
+ "source": [
+ "Adjust the strength of the Layer 2/3 Pyr AMPA weight to 0.0 as shown below."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6a708c69",
+ "metadata": {},
+ "source": [
+ "Save the simulation with a new “Simulation Name” in the Set Parameters dialog box: “gamma_L5weak_only” and run the simulation by clicking Start Simulation in the main HNN GUI window. The main HNN GUI will show a gamma rhythm similar to that observed in Step 2, that looks as follows:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "c7a47ab6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gui.run_button.click()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "d9f80701",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "gui.capture()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "898191c9",
+ "metadata": {},
+ "source": [
+ "However, if you now view the Simulation Spiking Activity and PSD (see step 3 above) you will see activity from only Layer 5 that looks as follows."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "id": "b862cd9e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gui._simulate_switch_plot_type(0, \"spikes\")\n",
+ "gui._simulate_switch_plot_type(1, \"PSD\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "e61202d6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "gui.capture()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "5a52e3fa",
+ "metadata": {},
+ "source": [
+ "Notice the weak PING rhythm in Layer 5 consisting of weakly synchronous pyramidal neuron firing, followed by synchronous inhibitory neuron firing, that gates the network dipole rhythm to ~50 Hz.\n",
+ "\n",
+ "To examine the impact of cell excitability on gamma expression, we can increase the excitability of the Layer 5 pyramidal neurons by adding a tonic applied current that might represent a neuromodulatory influence. Load the Tonic Input parameters with Set Parameters> Tonic Inputs.\n",
+ "\n",
+ "As in the Tonic Inputs dialog box below, click on Layer 5, and adjust the amplitude of the tonic drive to the L5 Pyr to be 6.0 nA. This level of injected current will be applied to the soma of the L5 Pyramidal neurons starting at time 0.0 ms and remaining on throughout the simulation (stop time = -1.0 ms)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "id": "25ce539f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# how to show this?"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c2f39ebb",
+ "metadata": {},
+ "source": [
+ "Save the simulation with a new simulation name (e.g., “gamma_L5weak_only_tonic”) in the Set Parameters dialog box and run the simulation by clicking Start Simulation in the main HNN GUI window. The simulation will yield the following output."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4bd489cf",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "gui.run_button.click()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "720b5d98",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "gui.capture()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "919c498a",
+ "metadata": {},
+ "source": [
+ "Notice that the oscillation waveform is now more regular with less noise due to the fact that the tonic drive is strong and outweighs the influence of the Poisson drive.\n",
+ "\n",
+ "Notice that the Layer 5 pyramidal neurons are now firing nearly synchronously. They in turn synchronously activate the inhibitory basket neurons, which then inhibit the pyramidal neurons for ~20 ms, when the tonic drive outweighs the inhibition and the pyramidal neurons firing again creating a ~50 Hz PING rhythm. This type of synchronous rhythm is sometimes referred to as “strong” PING. Notice that there is also a ~90 Hz component to the dipole spectrogram. Inspection of the dipole waveform shows that this 90 Hz activity does not represent a separate rhythm, but rather reflects the dipole waveform shape which has a fast oscillation on each cycle of the slower rhythm, due to the strong downward currents induced by strong somatic inhibition on the pyramidal neurons."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0ff48e15",
+ "metadata": {},
+ "source": [
+ "### 4.1.1 Exercises for further exploration\n",
+ "\n",
+ "- How else might the excitability of the cells be adjusted? What happens to the network dynamics? Can you make the oscillation faster or slower?\n",
+ "\n",
+ "- How else might the synaptic connections in the network be adjusted to impact gamma? What happens to the network dynamics? Can you make the oscillation faster or slower?\n",
+ "\n",
+ "- Gamma rhythms can be created in neworks where the pyramidal neurons do not fire on their own but their activity is still regulated by interneuron firing (interneuron mediated gamma: ING). Can you adjust parameters to create such an oscillation in the network?\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7d42dcad",
+ "metadata": {},
+ "source": [
+ "## 5. Have fun exploring your own data!\n",
+ "\n",
+ "We have not observed strong gamma activity in our SI dipole data, and as such have not provided an example data set to compare simulation results to, as in the other tutorials. However, simulation results can be compared to recorded data, as described in the ERP and Alpha/Beta tutorials. Follow steps 1-4 above using your data and parameter adjustments based on your own hypotheses.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a5516d94",
+ "metadata": {},
+ "source": [
+ "## References\n",
+ "\n",
+ "- Lee, S. & Jones, S. R. Distinguishing mechanisms of gamma frequency oscillations in human current source signals using a computational model of a laminar neocortical network. Front. Hum. Neurosci. 7, 869 (2013).\n",
+ "\n",
+ "- Cardin, J. A. et al. Driving fast-spiking cells induces gamma rhythm and controls sensory responses. Nature 459, 663–667 (2009).\n",
+ "\n",
+ "- Vierling-Claassen, D., Cardin, J. A., Moore, C. I. & Jones, S. R. Computational modeling of distinct neocortical oscillations driven by cell-type selective optogenetic drive: separable resonant circuits controlled by low-threshold spiking and fast-spiking interneurons. Front. Hum. Neurosci. 4, 198 (2010).\n",
+ "\n",
+ "- Buzsáki, G. & Wang, X.-J. Mechanisms of gamma oscillations. Annu. Rev. Neurosci. 35, 203–225 (2012).\n"
+ ]
+ }
+ ],
+ "metadata": {
+ "finalized": {
+ "timestamp": 1659923297915,
+ "trusted": false
+ },
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.12"
+ },
+ "require": {
+ "paths": {
+ "html2canvas": "https://html2canvas.hertzen.com/dist/html2canvas"
+ },
+ "shim": {}
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "43b52e66020a3206304124443c3dbfb478b19fdebbaacdf952e81bd31b11f0ba"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/hnn_core/gui/gui.py b/hnn_core/gui/gui.py
index da71a2b09..1cf153f4a 100644
--- a/hnn_core/gui/gui.py
+++ b/hnn_core/gui/gui.py
@@ -316,6 +316,8 @@ def _init_ui_components(self):
style='background:{self.layout['theme_color']};
text-align:center;color:white;'>
HUMAN NEOCORTICAL NEUROSOLVER
""")
+
+ self._connectivity_tab = {}
@property
def analysis_config(self):
@@ -370,7 +372,8 @@ def _on_upload_connectivity(change):
return on_upload_change(change, self.params, self.widget_tstop,
self.widget_dt, self._log_out,
self.drive_boxes, self.drive_widgets,
- self._drives_out, self._connectivity_out,
+ self._drives_out, self._connectivity_tab,
+ self._connectivity_out,
self.connectivity_widgets,
self.layout['drive_textbox'],
"connectivity")
@@ -379,7 +382,8 @@ def _on_upload_drives(change):
return on_upload_change(change, self.params, self.widget_tstop,
self.widget_dt, self._log_out,
self.drive_boxes, self.drive_widgets,
- self._drives_out, self._connectivity_out,
+ self._drives_out, self._connectivity_tab,
+ self._connectivity_out,
self.connectivity_widgets,
self.layout['drive_textbox'],
"drives")
@@ -484,11 +488,10 @@ def compose(self, return_layout=True):
# self.simulation_data[self.widget_simulation_name.value]
# initialize drive and connectivity ipywidgets
- load_drive_and_connectivity(self.params, self._log_out,
- self._drives_out, self.drive_widgets,
- self.drive_boxes, self._connectivity_out,
- self.connectivity_widgets,
- self.widget_tstop, self.layout)
+ self._connectivity_tab['content'] = load_drive_and_connectivity(
+ self.params, self._log_out, self._drives_out, self.drive_widgets,
+ self.drive_boxes, self._connectivity_out,
+ self.connectivity_widgets, self.widget_tstop, self.layout)
if not return_layout:
return
@@ -1081,7 +1084,7 @@ def add_connectivity_tab(params, connectivity_out,
with connectivity_out:
display(cell_connectivity)
- return net
+ return net, cell_connectivity
def add_drive_tab(params, drives_out, drive_widgets, drive_boxes, tstop,
@@ -1128,15 +1131,19 @@ def load_drive_and_connectivity(params, log_out, drives_out,
log_out.clear_output()
with log_out:
# Add connectivity
- add_connectivity_tab(params, connectivity_out, connectivity_sliders)
+ _, connectivity_tab = add_connectivity_tab(params, connectivity_out,
+ connectivity_sliders)
# Add drives
add_drive_tab(params, drives_out, drive_widgets, drive_boxes, tstop,
layout)
+ return connectivity_tab
+
def on_upload_change(change, params, tstop, dt, log_out, drive_boxes,
- drive_widgets, drives_out, connectivity_out,
- connectivity_sliders, layout, load_type):
+ drive_widgets, drives_out, connectivity_tab,
+ connectivity_out, connectivity_sliders, layout,
+ load_type):
if len(change['owner'].value) == 0:
logger.info("Empty change")
return
@@ -1163,7 +1170,9 @@ def on_upload_change(change, params, tstop, dt, log_out, drive_boxes,
params.update(params_network)
# init network, add drives & connectivity
if load_type == 'connectivity':
- add_connectivity_tab(params, connectivity_out, connectivity_sliders)
+ _, _connectivity_tab = add_connectivity_tab(params, connectivity_out,
+ connectivity_sliders)
+ connectivity_tab['content'] = _connectivity_tab
elif load_type == 'drives':
add_drive_tab(params, drives_out, drive_widgets, drive_boxes, tstop,
layout)