# 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 class`NeuronX`

and`NeuronY`

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()))
```