Hi. Great question, I am sure you are not the first one struggling with this. There is a misunderstanding about what add_attribute
does – I’ll give some more information on it below for those that are interested. What you need is a parameter defined as part of equations. PoissonGroup
does not allow you to specify its equations, so you cannot use it for this task and have to use NeuronGroup
instead. This is not as complicated as it seems, since PoissonGroup
is mostly a convenient wrapper around NeuronGroup
setting the threshold condition to rand() < rates*dt
(if your rate is 100Hz, and dt is 0.1ms, you have a 0.01 or 1% chance of a spike in each time step). So in your example, the definition should be (assuming you are using dimensionless attributes)
Inputs = NeuronGroup(N_Poisson,'''rates : Hz
x_distant : 1 (constant)
y_distant : 1 (constant)''',
threshold='rand()<rates*dt')
If you have a single rate for all neurons, you should also add (shared)
after the definition of rates
to make clear that it is a single value.
Background for add_attribute
In Brian, parameters of a NeuronGroup
are available as attributes of the object. So after the above definition you are allowed to write:
Inputs.rates = 100*Hz
Now if you make a mistake and write for example:
Inputs.rate = 100*Hz
Brian will raise an error, assuming you made a typo. This is different from standard Python behaviour. For most objects, assigning to an attribute that does not exist will create this attribute:
>>> class C:
... def __init__(self, value):
... self.value = value
>>> obj = C(23)
>>> obj.valu = 17 # valu instead of value, no error is raised!
>>> print(obj.value)
23
>>> print(obj.valu)
17
There might be legitimate use cases for this even in Brian. E.g. in a complex model you might want to store additional information in a NeuronGroup
that is not relevant for the simulation code as such, say store a reference to the paper that proposed a model. Since we want to protect users from making errors that are hard to detect (e.g. the rates
→ rate
typo above), we raise an error if an attribute does not exist:
>>> Inputs.reference = 'Someone et al. (2019), Some paper'
Traceback (most recent call last):
...
Could not find a state variable with name "reference". Use the add_attribute method if you intend to add a new attribute to the object.
Ass the error message suggests, if you are really sure that you want to add a new attribute (and that you did not just misspell an existing one), you can do this with the add_attribute
function:
>>> Inputs.add_attribute('reference')
>>> Inputs.reference = 'Someone et al. (2019), Some paper'
>>> print(Inputs.reference)
Someone et al. (2019), Some paper
But such an attribute will not be accessible to Brian code (e.g. in connect
statements), for this is has to be defined as part of equations.