# Description of problem

I am hoping to build a small-worlds network of Izhikevich neurons. I already have a function that defines a connectivity matrix and I have a separate function that creates the network. However, I am running into a problem and I am unsure how to debug this. Apologies if this is blatantly obvious, I am very new to Brian2

# Minimal code to reproduce problem

``````# create a network of izhikevich  neurons in brian2
def create_network(connectivity_matrix):
start_scope()

N = len(connectivity_matrix)

# params
a = 0.02
b = 0.2
c = -65
d = 8

izhikevich_eqs = '''
dv/dt = (0.04 * v**2 + 5 * v + 140 - u + I)/ms : 1 (unless refractory)
du/dt = a * (b * v - u)/ms : 1
I_syn : 1
'''

# define neuron group
G = NeuronGroup(N, model=izhikevich_eqs, threshold='v >= 30', reset='v = c; u = u + d', refractory=2*ms)

# set initial conditions
G.v = -65
G.u = b * G.v

# define synaptic connections
S = Synapses(G, G, 'w : 1', on_pre='I_syn_post += w')
S.connect(i=np.where(connectivity_matrix)[0],
j=np.where(connectivity_matrix)[1])

S.w = 'rand() * 2 - 1'

return G, S

def run_simulation(G, S, duration=100*ms):
# Start a new scope for the simulation
start_scope()

state_monitor = StateMonitor(G, 'v', record=True)

# Include the StateMonitor in the network
net = Network(G, S, state_monitor)

net.run(duration)

for i in range(len(G)):
plt.plot(state_monitor.t, state_monitor.v[i], label=f'Neuron {i}')

plt.xlabel('Time (ms)')
plt.ylabel('Membrane Potential')
plt.legend()
plt.show()
``````

# What you have aready tried

I have tried defining the parameter values (a,b,c,d) in the variable izhikevich_eqs, such that:
izhikevich_eqs = ‘’’
dv/dt = (0.04 * v**2 + 5 * v + 140 - u + I)/ms : 1 (unless refractory)
du/dt = a * (b * v - u)/ms : 1
I_syn : 1
a = 0.02
b = 0.2
c = -65
d = 8
‘’’

# Full traceback of error (if relevant)

``````ERROR      Brian 2 encountered an unexpected error. If you think this is a bug in Brian 2, please report this issue either to the discourse forum at <http://brian.discourse.group/>, or to the issue tracker at <https://github.com/brian-team/brian2/issues>. Please include this file with debug information in your report: /tmp/brian_debug_i547thrf.log  Additionally, you can also include a copy of the script that was run, available at: /tmp/brian_script_yo2y24s2.py You can also include a copy of the redirected std stream outputs, available at '/tmp/brian_stdout_1k7jo7rx.log' and '/tmp/brian_stderr_9gmfcjmm.log'. Thanks! [brian2]
Traceback (most recent call last):
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/core/network.py", line 996, in before_run
obj.before_run(run_namespace)
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/groups/neurongroup.py", line 990, in before_run
self.equations.check_units(self, run_namespace=run_namespace)
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/equations/equations.py", line 1164, in check_units
resolved_namespace = group.resolve_all(
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/groups/group.py", line 800, in resolve_all
resolved[identifier] = self._resolve(
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/groups/group.py", line 755, in _resolve
return self._resolve_external(identifier, run_namespace=run_namespace)
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/groups/group.py", line 889, in _resolve_external
raise KeyError(error_msg)
KeyError: 'The identifier "a" could not be resolved.'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/home/fiach/Documents/test.py", line 140, in <module>
main()
File "/home/fiach/Documents/test.py", line 134, in main
run_simulation(G, S)
File "/home/fiach/Documents/test.py", line 91, in run_simulation
net.run(duration)
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/core/base.py", line 335, in device_override_decorated_function
return func(*args, **kwds)
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/units/fundamentalunits.py", line 2780, in new_f
result = f(*args, **kwds)
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/core/network.py", line 1132, in run
self.before_run(namespace)
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/core/base.py", line 335, in device_override_decorated_function
return func(*args, **kwds)
File "/home/fiach/.local/lib/python3.10/site-packages/brian2/core/network.py", line 998, in before_run
raise BrianObjectException(
brian2.core.base.BrianObjectException: Error encountered with object named 'neurongroup'.
Object was created here (most recent call only, full details in debug log):
File '/home/fiach/Documents/test.py', line 64, in create_network
G = NeuronGroup(N, model=izhikevich_eqs, threshold='v >= 30', reset='v = c; u = u + d', refractory=2*ms)

An error occurred when preparing an object. (See above for original error message and traceback.)
``````

Hi @foneill. This is unfortunately not as obvious as it should be… Constants that are defined outside the equations (`a`, `b`, etc. in your example), need to be “visible” at the point where `run` (or `net.run`) is called. In your case, these variables are only available within the scope of `create_network`, but not within `run_simulation` where you call `net.run`.

One solution would be to move your definition of these variables to `run_simulation`, but I think you’d agree that this feels wrong in the sense that these variables are tied to the model itself and not to running the simulation (e.g., you might want to swap out the model later). A better solution would therefore be to either

### Include the values in the equation

Directly include the parameter values in the equation. One way that keeps the flexibility of changing these values as arguments of the `create_network` function would be to use:

``````izhikevich_eqs = '''...'''
izhikevich_eqs = Equations(izhikevich_eqs, a=0.02, b=0.2, c=-65, d=8)
``````

Note that this is equivalent to simply replacing the values by hand (i.e. writing `du/dt = 0.02 * (0.2 * v - u)/ms`, etc.), but it is more readable and nicer to adapt to other values.

### Use the `namespace` argument

Instead of getting the values of parameters from the surrounding context, you can also explicitly provide them to a `Network` or to individual groups such as `NeuronGroup`. The parameters are then “bundled” with the object, and there is no need to “resolve” them from the context surrounding the `net.run` call. In your example, you’d keep the `create_network` function as it is, but provide the `namespace` argument to the `NeuronGroup` initializer:

``````    G = NeuronGroup(N, model=izhikevich_eqs,
threshold='v >= 30', reset='v = c; u = u + d', refractory=2*ms,
namespace={'a': a, 'b': b, 'c': c, 'd': d})
``````

We document this feature here: Namespaces — Brian 2 2.5.4 documentation

Hope that clears things up!

Hi @mstimberg,

Thank you, this is very helpful!

1 Like