{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Quickstart\n",
"To run the code below:\n",
"\n",
"1. Click on the cell to select it.\n",
"2. Press `SHIFT+ENTER` on your keyboard or press the play button\n",
" () in the toolbar above.\n",
"\n",
"Feel free to create new cells using the plus button\n",
"(), or pressing `SHIFT+ENTER` while this cell\n",
"is selected."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Appendix 4: parameter exploration\n",
"\n",
"In this example, we show how Brian can be used to do a parameter exploration. The most efficient way to implement this is to consider a group of neurons, where each of the neurons is described by the same model, but one or several model parameters systematically change across neurons."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib notebook\n",
"from brian2 import *"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can speed up this \"embarassingly parallel\" problem by parallelizing it over CPUs, making use of the OpenMP interface for multithreading:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"set_device('cpp_standalone')\n",
"prefs.devices.cpp_standalone.openmp_threads = 4"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the [Brian2GeNN](https://brian2genn.readthedocs.io) interface, this simulation could also run on a GPU (needs a [CUDA](https://developer.nvidia.com/cuda-zone)-enabled NVIDIA GPU, and an installation of `brian2genn`): "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# These two lines would replace the above two lines:\n",
"# import brian2genn\n",
"# set_device('genn')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will first set some general constants for our model (a HH-type model with an injected current):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"area = 20000*umetre**2\n",
"Cm = (1*ufarad*cm**-2) * area\n",
"gl = (5e-5*siemens*cm**-2) * area\n",
"\n",
"El = -60*mV\n",
"EK = -90*mV\n",
"ENa = 50*mV\n",
"g_kd = (30*msiemens*cm**-2) * area\n",
"VT = -63*mV"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will explore the effect of the $g_{Na}$ conductance, and the effect of the injected current $I$, varying each over 100 values:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"g_na_values = np.linspace(10, 100, num=100)*msiemens*cm**-2 * area\n",
"I_values = np.linspace(0, 20, num=100)*pA"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We now define the model, with $g_{Na}$ and $I$ as parameters, set independently for each neuron, and create one neuron for each combination of parameters:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"eqs = Equations('''\n",
"dv/dt = (gl*(El-v)-\n",
" g_na*(m*m*m)*h*(v-ENa)-\n",
" g_kd*(n*n*n*n)*(v-EK) + I)/Cm : volt\n",
"dm/dt = alpha_m*(1-m)-beta_m*m : 1\n",
"dn/dt = alpha_n*(1-n)-beta_n*n : 1\n",
"dh/dt = alpha_h*(1-h)-beta_h*h : 1\n",
"alpha_m = 0.32*(mV**-1)*(13*mV-v+VT)/\n",
" (exp((13*mV-v+VT)/(4*mV))-1.)/ms : Hz\n",
"beta_m = 0.28*(mV**-1)*(v-VT-40*mV)/\n",
" (exp((v-VT-40*mV)/(5*mV))-1)/ms : Hz\n",
"alpha_h = 0.128*exp((17*mV-v+VT)/(18*mV))/ms : Hz\n",
"beta_h = 4./(1+exp((40*mV-v+VT)/(5*mV)))/ms : Hz\n",
"alpha_n = 0.032*(mV**-1)*(15*mV-v+VT)/\n",
" (exp((15*mV-v+VT)/(5*mV))-1.)/ms : Hz\n",
"beta_n = .5*exp((10*mV-v+VT)/(40*mV))/ms : Hz\n",
"I : amp (constant)\n",
"g_na : siemens (constant)\n",
"''')\n",
"neuron = NeuronGroup(len(g_na_values)*len(I_values), eqs,\n",
" method='exponential_euler',\n",
" threshold='v>-20*mV', refractory='v>-20*mV')\n",
"neuron.v = El\n",
"spike_mon = SpikeMonitor(neuron)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We now create all combinations of the explored parameters, and assign them to the individual neurons. Running the \"network\" of neurons will then explore all the parameter combinations."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"all_g_na_values, all_I_values = np.meshgrid(g_na_values, I_values)\n",
"all_g_na_values = all_g_na_values.flat[:]\n",
"all_I_values = all_I_values.flat[:]\n",
"neuron.g_na = all_g_na_values\n",
"neuron.I = all_I_values"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We start the run and determine the firing rate for each neuron:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run(10*second)\n",
"rates = spike_mon.count/(10*second)/Hz"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can now plot the firing rate as a function of the two explored parameters (in this example here, vertical slices of the graph can also be interpreted as the f/I curve of the neuron for varying values of $g_{Na}$):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"I_index = ((neuron.I - np.min(I_values)) / np.diff(I_values)[0]).round().astype('int')\n",
"Na_index = ((neuron.g_na - np.min(g_na_values)) / np.diff(g_na_values)[0]).round().astype('int')\n",
"matrix = np.full((len(I_values), len(g_na_values)), np.nan)\n",
"matrix[I_index, Na_index] = rates\n",
"norm = mpl.colors.BoundaryNorm(np.arange(0, 19), plt.cm.viridis.N)\n",
"fig, ax = plt.subplots()\n",
"m = ax.imshow(matrix, norm=norm)\n",
"# We do manual ticks, easier than using extent and getting the scaling right\n",
"ticks = [0, 49, 99]\n",
"ax.set(xticks=ticks, xticklabels=['%.1f' % (g_na_values[i]/(mS*cm**-2 * area)) for i in ticks],\n",
" yticks=ticks, yticklabels=['%.1f' % (I_values[i]/pA) for i in ticks],\n",
" xlabel='$g_{Na}$ (mS/cm²)', ylabel='$I$ (nA)')\n",
"ax.axes.invert_yaxis()\n",
"cbar = fig.colorbar(m)\n",
"cbar.set_label('number of spikes')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}