# Two Neurons

In this example we are going to define one of the most simple networks possible: one with three elements. This will allow us to introduce a couple of fundamental concepts in PyNN.

As in our past example we start by importing PyNN and the necessary libraries. Also we declare some initialization variables and we start the simulator:

``` import pyNN.nest as simulator import pyNN.nest.standardmodels.electrodes as elect import matplotlib.pyplot as plt import numpy as np N = 3 # Number of neurons t = 150.0 # Simulation time # Has to be called at the beginning of the simulation simulator.setup(timestep=0.1, min_delay=0.1, max_delay=10) ```

Now we have to declare our cell modell. But before to so, let's check which parameters of it we can play with. In order to do so we can consult the available parameters for each model class with the method default_parameters. In our case of example we are interested in the integrate and fire model with current based synapses. We can call the following code to see the parameters available:

``` simulator.IF_curr_exp.default_parameters ```

After this we are going to get a list of the available parameters, we set them and the declare our model with the following instructions:

``` # Neuron Model's parameters i_offset = 0 R = 20 tau_m = 20.0 tau_refractory = 50 v_thresh = 0 v_rest = -60 tau_syn_E = 5.0 tau_syn_I = 5.0 cm = tau_m / R # Declare our cell model model = simulator.IF_curr_exp(cm=cm, i_offset=i_offset, tau_m=tau_m, tau_refrac=tau_refractory, tau_syn_E=tau_syn_E, tau_syn_I=tau_syn_I, v_reset=v_rest, v_thresh=v_thresh) # Declare a population neurons = simulator.Population(N, model) ```

In order to modify a specific subset of a given population in PyNN we use the concept of View. Views allow us to use Python array notation to access a given subset of a population and modify it for our purposes. In this particular case we are going select two sub-populations (neurons 1 and 2) to modify the parameters and a create a connection to them from the reminder neuron. In order to modify parameters from a given population we use the method set_parameters that each population posses:

``` # Create views neuron1 = neurons[] neuron2 = neurons[1, 2] # Modify second neuron tau_m2 = 10.0 cm2 = tau_m2 / R neurons.set_parameters(cm=cm2, tau_m=tau_m2) tau_m3 = 5.0 cm3 = tau_m3 / R neurons.set_parameters(cm=cm3, tau_m=tau_m3) ```

Now, in order to create connections in PyNN we need the concept of projection. As stated in the tutorial of PyNN a project needs the following elements to be declared:

• The pre-synaptic population
• The post-synaptic population
• A connection algorithm
• A synapse type

The general form of the Projection method is given by

``` Projection(presynaptic population, posynaptic population, connection algorithm, synapase type) ```

In our example the pre-synaptic population is going to be the neuron 0 and the post-synaptic population is going to be composed of the neurons 1 and 2 as declared in the views above. As a connection algorithm we are going to use the AllToAllConnector method which connects every member of the presynaptic population to the post-synaptic population. Finally we can define a static syanpse with the method StaticSynapse, it requires two attributes a value that determines the size (weight) and a delay that determines how long after the spike in the pre-synaptic neuron the pos-synaptic neuron elicits a response. Our code bellow is:

``` # Synapses syn = simulator.StaticSynapse(weight=10, delay=0.5) # Projections connections = simulator.Projection(neuron1, neuron2, simulator.AllToAllConnector(), syn, receptor_type='excitatory') ```

Finally we set the current for the neuron 1 and the recorder as in the previous example:

``` # DC source current = elect.DCSource(amplitude=3.5, start=20.0, stop=100.0) current.inject_into(neuron1) #neurons.inject(current) # Record the voltage neurons.record('v') simulator.run(t) # Run the simulations for t ms simulator.end() ```

Finally we extract the data and plot the function

``` # Extracts the data data = neurons.get_data() # Creates a Neo Block segment = data.segments # Takes the first segment vm = segment.analogsignalarrays # Take the arrays # Extract the data for neuron 1 vm1 = vm[:, 0] vm2 = vm[:, 1] vm3 = vm[:, 2] # Plot the data plt.plot(vm.times, vm1, label='pre-neuron') plt.hold('on') plt.plot(vm.times, vm2, label='post-neuron 1') plt.plot(vm.times, vm3, label= 'post-neuron 2') plt.xlabel('time') plt.ylabel('Voltage') plt.legend() plt.show() ```

A particular example of the simulation running is attached next. Playing with the parameters in this example can provide a clear idea of how the models and synapsis' parameters work: