Model parameters and initial values

As was discussed in Building networks, PyNN deals with neurons, and with the synaptic connections between them, principally at the level of groups: with Population and Assembly for neurons and Projection for connections.

Setting the parameters of neurons and connections is also done principally at the group level, either when creating the group, or after creation using the set() method. Sometimes, all the neurons in a Population or all the connections in a Projection should have the same value. Other times, different individual cells or connections should have different parameter values. To handle both of these situations, parameter values may be of four different types:

  • a single number - sets the same value for all cells in the Population or connections in the Projection

  • a RandomDistribution object (see Random numbers) - each item in the group will have the parameter set to a value drawn from the distribution

  • a list or 1D NumPy array - of the same size as the Population or the number of connections in the Projection

  • a function - for a Population or Assembly the function should take a single integer argument, and will be called with the index of every neuron in the Population to return the parameter value for that neuron. For a Projection, the function should take two integer arguments, and for every connection will be called with the indices of the pre- and post-synaptic neurons.


Setting the same value for all neurons in a population

>>> p = Population(5, IF_cond_exp(tau_m=15.0))

or, equivalently:

>>> p = Population(5, IF_cond_exp())
>>> p.set(tau_m=15.0)

To set values for a subset of the population, use a view:

>>> p[0,2,4].set(tau_m=10.0)
>>> p.get('tau_m')
array([ 10.,  15.,  10.,  15.,  10.])

Setting parameters to random values

>>> from pyNN.random import RandomDistribution, NumpyRNG
>>> gbar_na_distr = RandomDistribution('normal', (20.0, 2.0), rng=NumpyRNG(seed=85524))
>>> p = Population(7, HH_cond_exp(gbar_Na=gbar_na_distr))
>>> p.get('gbar_Na')
array([ 20.03132455,  20.09777627,  16.97079318,  17.44786923,
        19.4928947 ,  20.80321881,  19.97246906])
>>> p[0].gbar_Na

Setting parameters from an array

>>> import numpy as np
>>> p = Population(6, SpikeSourcePoisson(rate=np.linspace(10.0, 20.0, num=6)))
>>> p.get('rate')
array([ 10.,  12.,  14.,  16.,  18.,  20.])

The array of course has to have the same size as the population:

>>> p = Population(6, SpikeSourcePoisson(rate=np.linspace(10.0, 20.0, num=7)))

Using a function to calculate parameter values

>>> from numpy import sin, pi
>>> p = Population(8, IF_cond_exp(i_offset=lambda i: sin(i*pi/8)))
>>> p.get('i_offset')
array([ 0.        ,  0.38268343,  0.70710678,  0.92387953,  1.        ,
        0.92387953,  0.70710678,  0.38268343])

Setting parameters as a function of spatial position

>>> from import Grid2D
>>> grid = Grid2D(dx=10.0, dy=10.0)
>>> p = Population(16, IF_cond_alpha(), structure=grid)
>>> def f_v_thresh(pos):
...     x, y, z = pos.T
...     return -50 + 0.5*x - 0.2*y
>>> p.set(v_thresh=lambda i: f_v_thresh(p.position_generator(i)))
>>> p.get('v_thresh').reshape((4,4))
array([[-50., -52., -54., -56.],
       [-45., -47., -49., -51.],
       [-40., -42., -44., -46.],
       [-35., -37., -39., -41.]])

For more on spatial structure, see Representing spatial structure and calculating distances.

Using multiple parameter types

It is perfectly possible to use multiple different types of parameter value at the same time:

>>> n = 1000
>>> parameters = {
...     'tau_m': RandomDistribution('uniform', (10.0, 15.0)),
...     'cm':    0.85,
...     'v_rest': lambda i: np.cos(i*pi*10/n),
...     'v_reset': np.linspace(-75.0, -65.0, num=n)}
>>> p = Population(n, IF_cond_alpha(**parameters))
>>> p.set(v_thresh=lambda i: -65 + i/n, tau_refrac=5.0)


in the above, give current source examples, and Projection examples

Time series and array-valued parameters

For certain neuron models (SpikeSourceArray, GIF_cond_exp) and current sources, the individual parameter values are not single numbers (with physical units), but arrays, e.g.:

celltype = SpikeSourceArray(np.array([5.0, 15.0, 45.0, 99.0]))

to set the same spike times for the entire population. To set different spike times for each cell in the population requires an array of arrays. To avoid ambiguities in this situation, the inner arrays should be wrapped by the Sequence class, e.g.:

celltype = SpikeSourceArray([Sequence([5.0, 15.0, 45.0, 99.0]),
                             Sequence([2.0, 5.3, 18.9]),
                             Sequence([17.8, 88.2, 100.1])

Such an array-of-Sequences can also be provided by a generator function, e.g.:

number = int(2 * simtime * input_rate / 1000.0)

def generate_spike_times(i):
    gen = lambda: Sequence(numpy.add.accumulate(numpy.random.exponential(1000.0 / input_rate, size=number)))
    if hasattr(i, "__len__"):
        return [gen() for j in i]
        return gen()

celltype = SpikeSourceArray(spike_times=generate_spike_times)

As a generalization of Sequence, some models require array-valued parameters, expressed as tuples or ArrayParameter instances, e.g.:

cell_type = GIF_cond_exp(
    # this parameter has the same value in all neurons in the population
    tau_gamma=(1.0, 10.0, 100.0),  # Time constants for spike-frequency adaptation in ms.
    # the following parameter has different values for each neuron
    a_eta=[(0.1, 0.1, 0.1),        # Post-spike increments for spike-triggered current in nA
           (0.0, 0.0, 0.0),
           (0.0, 0.0, 0.0),
           (0.0, 0.0, 0.0)]


The reason for defining Sequence and ArrayParameter rather than just using a plain NumPy array is to avoid the ambiguity of “is a given array a single parameter value (e.g. a spike train for one cell) or an array of parameter values (e.g. one number per cell)?”.

Setting initial values




For most neuron types, the default initial value for the membrane potential is the same as the default value for the resting membrane potential parameter. However, be aware that changing the value of the resting membrane potential will not automatically change the initial value.