9. Type I and type II neuron models¶
Book chapters
See Chapter 4 and especially Chapter 4 Section 4 for background knowledge on Type I and Type II neuron models.
Python classes
The neurodynex.neuron_type.neurons
module contains all classes required for this exercise. To get started, call getting_started
or copy the following code into your Jupyter notebook:
%matplotlib inline # needed in Notebooks, not in Python scripts
import brian2 as b2
import matplotlib.pyplot as plt
import numpy as np
from neurodynex.tools import input_factory, plot_tools, spike_tools
from neurodynex.neuron_type import neurons
# create an input current
input_current = input_factory.get_step_current(50, 150, 1.*b2.ms, 0.5*b2.pA)
# get one instance of class NeuronX and save that object in the variable 'a_neuron_of_type_X'
a_neuron_of_type_X = neurons.NeuronX() # we do not know if it's type I or II
# simulate it and get the state variables
state_monitor = a_neuron_of_type_X.run(input_current, 200*b2.ms)
# plot state vs. time
neurons.plot_data(state_monitor, title="Neuron of Type X")
# get an instance of class NeuronY
a_neuron_of_type_Y = neurons.NeuronY() # we do not know if it's type I or II
state_monitor = a_neuron_of_type_Y.run(input_current, 200*b2.ms)
neurons.plot_data(state_monitor, title="Neuron of Type Y")
Note
For those who are interested, here is more about classes and inheritance in Python.
9.1. Exercise: Probing Type I and Type II neuron models¶
This exercise deals not only with Python functions, but with python objects. The classes NeuronX
and NeuronY
both are neurons, that have different dynamics: one is Type I and one is Type II. Finding out which class implements which dynamics is the goal of the exercise.
The types get randomly assigned each time you load the module or you call the function neurons.neurontype_random_reassignment()
.
9.1.1. Question: Estimating the threshold¶
What is the threshold current for repetitive firing for NeuronX
and NeuronY
?
Exploring various values of I_amp
, find the range in which the threshold occurs, to a precision of 0.01.
Plot the responses to step current which starts after 100ms (to let the system equilibrate) and lasting at least 1000ms (to detect repetitive firing with a long period). You can do this by modifying the code example given above. Make sure to check the documentation of the functions you use: input_factory.get_step_current()
, neuron_type.neurons.run()
and neuron_type.neurons.plot_data()
.
Already from the voltage response near threshold you might have an idea which is type I or II, but let’s investigate further.
9.2. Exercise: f-I curves¶
In this exercise you will write a python script that plots the f-I curve for type I and type II neuron models.
9.2.1. Get firing rates from simulations¶
We provide you with a function spike_tools.get_spike_time()
to determine the spike times from a StateMonitor. The following code shows how to use that function. Note that the return value is a Brian Quantity: it has units. If you write code using units, you’ll get consistency checks done by Brian.
input_current = input_factory.get_step_current(100, 110, b2.ms, 0.5*b2.pA)
state_monitor = a_neuron_of_type_X.run(input_current, ...)
spike_times = spike_tools.get_spike_time(state_monitor, ...)
print(spike_times)
print(type(spike_times)) # it's a Quantity
Now write a new function (in your own .py file or in your Jupyter Notebook) that calculates an estimate of the firing rate. In your function use spike_tools.get_spike_time()
def get_firing_rate(neuron, input_current, spike_threshold):
# inject a test current into the neuron and call it's run() function.
# get the spike times using spike_tools.get_spike_times
# from the spike times, calculate the firing rate f
return f
Note
To calculate the firing rate, first calculate the inter-spike intervals (time difference between spikes) from the spike times using this elegant indexing idiom
isi = st[1:]-st[:-1]
Then find the mean isi and take the reciprocal to yield the firing-rate. As these are standard operations, you can expect that someone else has already implemented it. Have a look at the numpy package and look up the functions diff and mean. Once you have implemented your function, you should verify it’s correctness: inject a few currents into your neuron, plot the voltage response and compare the plot with the firing rate computed by your function.
Note
You can check your results by calling:
spike_tools.pretty_print_spike_train_stats(...)
9.2.2. Plot the f-I curve¶
Now let’s use your function get_firing_rate
to plot an f-vs-I curve for both neuron classes.
Add the following function skeleton to your code and complete it to plot the f-I curve, given the neuron class as an argument:
import matplotlib.pyplot as plt
import numpy as np
def plot_fI_curve(NeuronClass):
plt.figure() # new figure
neuron = NeuronClass() # instantiate the neuron class
I = np.arange(0.0,1.1,0.1) # a range of current inputs
f = []
# loop over current values
for I_amp in I:
firing_rate = # insert here a call to your function get_firing_rate( ... )
f.append(firing_rate)
plt.plot(I, f)
plt.xlabel('Amplitude of Injecting step current (pA)')
plt.ylabel('Firing rate (Hz)')
plt.grid()
plt.show()
- Call your
plot_fI_curve
function with each classNeuronX
andNeuronY
as argument. - Change the
I
range (and reduce the step size) to zoom in near the threshold, and try running it again for both classes.
Which class is Type I and which is Type II? Check your result:
print("a_neuron_of_type_X is : {}".format(a_neuron_of_type_X.get_neuron_type()))
print("a_neuron_of_type_Y is : {}".format(a_neuron_of_type_Y.get_neuron_type()))