diff --git a/doc/gui/tutorial_gamma.ipynb b/doc/gui/tutorial_gamma.ipynb new file mode 100644 index 000000000..aa3d8fe30 --- /dev/null +++ b/doc/gui/tutorial_gamma.ipynb @@ -0,0 +1,857 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "e12a66a7", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2" + ] + }, + { + "cell_type": "markdown", + "id": "2b8ad740", + "metadata": {}, + "source": [ + "# Gamma rhythms (30-80 Hz)" + ] + }, + { + "cell_type": "markdown", + "id": "7369753b", + "metadata": {}, + "source": [ + "## Getting Started\n", + "\n", + "In order to understand the workflow and initial parameter sets provided with this tutorial, we must first briefly describe prior studies on the mechanistic origin of gamma rhythms, including our prior modeling work that led to the creation of the parameter sets you will work with [1].\n", + "\n", + "Gamma rhythms can encompass a wide band of frequencies from 30-150 Hz. Here, we will focus on the generation of so called low gamma rhythms in the 30-80 Hz range. It has been well established through experiments and computational modeling that these rhythms can emerge in local spiking networks through interactions of excitatory cell and inhibitory cell interactions, with the period of the oscillation set by the time constant of decay of GABAA-mediated inhibitory currents [2–4], a mechanism that has been referred to as pyramidal-interneuronal gamma (PING). In normal regimes, the decay time constant of GABAA-mediated synapses (around 25 ms) bounds oscillations to the low gamma frequency band (around 40 Hz).\n", + "\n", + "In general, PING rhythms are initiated by “excitation” to the excitatory (E) cells that causes spiking, which in turn synaptically activates a spiking population of inhibitory (I) cells. In turn, these I cells inhibit the E cells, preventing further E cell activity until the E cells can overcome the effects of the inhibition (~25 ms later). The pattern is repeated, creating a gamma frequency oscillation (around 40 Hz, 40 spikes/second). This general principle is schematically described in Figure 1 below. The frequency of the rhythm is paced by this time constant of decay of inhibition, which is mediated by strong GABA-A currents, as well as the excitability of the E cells (if the E cells are very excitable, they can fire before the inhibition has completely worn off, and the oscillation will be faster).\n", + "\n", + "\n", + "\n", + "
Schematic illustration of the circuit mechanisms underlying PING rhythms.
\n", + "\n", + "In this tutorial, we will explore the generation of PING rhythms in the HNN model. We will provide example parameter files and walk through simulations that generate low-frequency gamma activity in both Layers 2/3 and Layer 5, as in [1]. This tutorial relies on a different type of exogenous drive to “activate” the local network than the other tutorials. Here, the necessary excitation to generate spiking in the pyramidal neurons (E cells) that initiates the rhythm (see PING description above) is provided by a continuous train of action potentials with a Poisson distribution (Poisson Input) that activate post-synaptic excitatory AMPA synapses on the pyramidal neurons. This Poisson drive causes the pyramidal neurons to fire, dependent on the chosen conductance of the AMPA currents. The inhibition in the network is strong enough to overcome the Poisson drive and entrain the network spiking into a gamma frequency rhythm.\n", + "\n", + "Of note, gamma rhythms can be generated by circuit mechanisms other than PING, including subthreshold rhythmic exogenous drive. Lee and Jones (2013) examined various mechanisms of generation of gamma activity and described ways to distinguish the mechanisms of generation based on features of current dipole signal [1]. After completing this tutorial, we encourage you to explore alternate mechanisms of gamma generation and to compare to your own gamma data." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2eba55b1-2ab7-4f07-a76c-34f5a184da4d", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Warning: no DISPLAY environment variable.\n", + "--No graphics will be displayed.\n" + ] + } + ], + "source": [ + "import time\n", + "from hnn_core.gui.gui import HNNGUI\n", + "from ipywidgets import Output\n", + "from IPython.display import Javascript\n", + "\n", + "# do not mix this with GUI operations\n", + "gui = HNNGUI()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "norwegian-angola", + "metadata": { + "require": [ + "html2canvas" + ], + "scrolled": true + }, + "outputs": [], + "source": [ + "# In practice, set return_layout to false to show the dashboard\n", + "# gui.compose()\n", + "gui.compose(return_layout=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "612eb831", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "gui.capture()" + ] + }, + { + "cell_type": "markdown", + "id": "b2f48fa3", + "metadata": {}, + "source": [ + "\n", + "\n", + "## Load/view parameters to define network structure & to “activate” the network\n", + "\n", + "An initial parameter set that will simulate PING rhythms as described in the Getting Started section above can be downloaded via the following hyperlink: [gamma_L5weak_L2weak.param](https://github.com/jonescompneurolab/hnn/blob/master/param/gamma_L5weak_L2weak.param). This file can also be found in the HNN param subfolder.\n", + "\n", + "The template cortical column networks structure for this simulation is described in the Overview and What’s Under the Hood sections of the HNN webpage. Several of the network parameter (i.e., local excitatory and inhibitory connection strengths) will be adjusted in this tutorial, but we will begin by describing the inputs the “activate” the network.\n", + "\n", + "To load the initial parameter set, navigate to the HNN GUI and click:\n", + "\n", + " Load network" + ] + }, + { + "cell_type": "markdown", + "id": "061faff2", + "metadata": {}, + "source": [ + "Once you have this param file downloaded and existing drive deleted, upload the file to the GUI through the `Load network` button." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "9e078bf6", + "metadata": {}, + "outputs": [], + "source": [ + "param_url = \"https://raw.githubusercontent.com/jonescompneurolab/hnn/master/param/gamma_L5weak_L2weak.param\"\n", + "gui._simulate_upload_connectivity(param_url)\n", + "gui._simulate_upload_drives(param_url)" + ] + }, + { + "cell_type": "markdown", + "id": "0039c446", + "metadata": {}, + "source": [ + "In this simulation, the network will be “activated” with excitatory AMPA synaptic input, distributed in time as a Poisson process and given to somas of the pyramidal neurons in Layer 2/3 and Layer 5. This noisy input will generate spiking activity in the pyramidal neurons that can initiate the PING rhythm.\n", + "\n", + "To view the parameters that “activate” the network and initiate a gamma rhythm, return to the main GUI window and click:\n", + "\n", + " External drives" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "27f3897d", + "metadata": {}, + "outputs": [], + "source": [ + "gui._simulate_left_tab_click(\"External drives\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "95462496", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "gui.capture()" + ] + }, + { + "cell_type": "markdown", + "id": "a30315d3", + "metadata": {}, + "source": [ + "In this parameter file, all synaptic connections within the network are turned off (weight = 0 ), except for reciprocal connections between the excitatory (AMPA only) and inhibitory (GABAA only) cells within the same layer. In other words, the Layer 2/3 and Layer 5 networks are not connected to each other (see the Under the Hood section of the HNN website for further details on connectivity structure). This is not biologically realistic, but was done for illustration purposes and to prevent pyramidal-to-pyramidal interactions from disrupting the gamma rhythm.\n", + "\n", + "To view the local network connection parameters, click::\n", + "\n", + " Network connectivity\n", + " \n", + "You should see the values of adjustable parameters displayed as in the dialog boxes below. Notice that the Layer 2/3 and Layer 5 are not connected to each other, the inhibitory conductance weights within layers are stronger than the excitatory conductances, and there are also strong inhibitory-to-inhibitory connections (i.e., basket-to-basket). This strong autonomous inhibition will cause synchrony among the basket cells, and hence strong inhibition onto the pyramidal neurons (note: this synapse was not depicted in Figure 1)." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "8a5db7b5", + "metadata": {}, + "outputs": [], + "source": [ + "gui._simulate_left_tab_click(\"Network connectivity\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "cb8b6a74", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "gui.capture()" + ] + }, + { + "cell_type": "markdown", + "id": "1863124e", + "metadata": {}, + "source": [ + "## 2. Run the simulation and visualize net current dipole" + ] + }, + { + "cell_type": "markdown", + "id": "48a0af55", + "metadata": {}, + "source": [ + "To run this simulation, click:\n", + "\n", + " Run" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "66448a54", + "metadata": {}, + "outputs": [], + "source": [ + "gui.run_button.click()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "8e73e1df", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "gui.capture()" + ] + }, + { + "cell_type": "markdown", + "id": "94114ab2", + "metadata": {}, + "source": [ + "In this simulation, a single histogram displaying the Poisson drive to the excitatory cells is shown in the top panel, displaying no clear rhythmicity at the gamma frequency. The Poisson drive provided causes pyramidal cells to fire, which in-turn cause the inhibitory neurons to fire, and feedback inhibition from the interneurons to the pyramidal cells generates a regular gamma rhythm via the PING mechanism described above (the process to view the spiking activity is described in Section 3 below). In this example, the rhythmic dipole displays sharp downward deflections, reflective of the strong inhibition onto the pyramidal neuron somas, which pulls current flow down the dendrites. The corresponding spectrogram confirms that, for this parameter set, the dipole signal contains strong oscillatory components in the gamma range (~50 Hz)." + ] + }, + { + "cell_type": "markdown", + "id": "9fb70da1", + "metadata": {}, + "source": [ + "## 3. Calculating and Viewing Spiking Activity and Power Spectral Density (PSD)" + ] + }, + { + "cell_type": "markdown", + "id": "bd675179", + "metadata": {}, + "source": [ + "To view the spiking activity generated by the different neuron populations in the network, select \"spikes\" from the dropdown menu in the visualization window:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "67a08b9d", + "metadata": {}, + "outputs": [], + "source": [ + "gui._simulate_viz_action(\"edit_figure\", \"Figure 1\", \"ax1\", \"default\", \"spikes\", {}, \"plot\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "93c58948", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "gui.capture()" + ] + }, + { + "cell_type": "markdown", + "id": "1157f067", + "metadata": {}, + "source": [ + "Notice that the excitatory pyramidal neurons in each layer (green and red dots / lines) fire before the inhibitory basket cells in each layer (white, blue dots / lines). The pyramidal neuron firing drives the basket cells to fire. The basket cells are highly synchronous due to the strong inhibitory-to-inhibitory connections. The basket cells then prevent the pyramidal neurons from firing for ~25 ms, generating the PING rhythms. The line-plots, which show spike counts over time, also demonstrate rhythmicity. The pyramidal neurons are firing periodically, but with lower synchrony due to the Poisson drive (orange histogram at top), which creates randomized spike times across the populations (once the inhibition sufficiently wears off). This type of dispersed pyramidal neuron firing is considered “weak” PING - hence the parameter file name including weak.\n", + "\n", + "We can further confirm that this oscillation is in the gamma frequency range by viewing the power spectral density of the current dipole signal (average spectrogram across time)." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d35b38b7", + "metadata": {}, + "outputs": [], + "source": [ + "gui._simulate_viz_action(\"switch_fig_template\", \"single figure\")\n", + "gui._simulate_viz_action(\"add_fig\")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "67564796", + "metadata": {}, + "outputs": [], + "source": [ + "gui._simulate_viz_action(\"edit_figure\", \"Figure 2\", \"ax0\", \"default\", \"PSD\", {}, \"plot\")" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "e539bbf4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "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)