# Implementing the Wilson Neuron

**URL:** <https://brian.discourse.group/t/implementing-the-wilson-neuron/1381>\
**Category:** Support\
**Created:** [27 January 2025 18:09 UTC](https://brian.discourse.group/t/implementing-the-wilson-neuron/1381 "2025-01-27T18:09:08Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![zain-altaf](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/zain-altaf/32/822_2.png) [@zain-altaf](https://brian.discourse.group/u/zain-altaf)\
**Post date:** [27 January 2025 18:09 UTC](https://brian.discourse.group/t/implementing-the-wilson-neuron/1381/1 "2025-01-27T18:09:08Z")

</div>

# Description of problem

I am trying to implement the Wilson Neuron model at the moment and seem to be running into an issue. Essentially what I want to do is inject an external current (I=3 for 0.1 ms). I am keeping all the equation definitions unitless for simplicity and as per instructions given to me by my professor. I have set:

- default\_clock.dt = 0.025\*ms
- v\_0 = -0.75
- r\_0 = 0.2
- tau\_v = 0.97\*ms
- tau\_r = 5.6\*ms
- tau\_h = 99.0\*ms
- dt = 0.05\*ms

And the equations for the differentials look like this:

 ![image](https://global.discourse-cdn.com/free1/uploads/brian/original/1X/c44b733733dcad73d963583c1122c22e1f169c8b.png)

The objective is to plot voltage vs time

# Minimal code to reproduce problem

```auto
start_scope()

tau_v = 0.97 * ms
tau_r = 5.6 * ms
tau_h = 99.0 * ms

v_0 = -0.75
r_0 = 0.2
h_0 = 0.0

defaultclock.dt = 0.025 * ms

eqn = '''
dv/dt = (-(17.81 + 47.58*v + 33.80*(v**2))*(v - 0.48) - (26*r*(v + 0.95)) - 13*h*(v + 0.95) + I_ext)/tau_v : 1
dr/dt = (-r + 1.29*v + 0.79 + 3.30*((v + 0.38)**2))/tau_r : 1
dh/dt = (-h + 11*(v + 0.754)*(v + 0.69))/tau_h : 1
I_ext : 1
'''

# Create the neuron group
neuron = NeuronGroup(1, eqn, method='euler')
neuron.v = v_0
neuron.r = r_0
neuron.h = h_0
neuron.I_ext = 0.0 # Initial external current

# Set up monitors
v_probe = StateMonitor(neuron, 'v', record=True)
r_probe = StateMonitor(neuron, 'r', record=True)
h_probe = StateMonitor(neuron, 'h', record=True)

# Run the simulation
run(5 * ms)
neuron.I_ext = 3.0
run(0.1 * ms)
neuron.I_ext = 0.0
run(20 * ms)

plt.figure(figsize=(10, 6))
plt.plot(v_probe.t / ms, v_probe.v[0], label='Voltage (v)')
plt.xlabel('Time (ms)')
plt.ylabel('State Variables (Unitless)')
plt.title('Wilson Neuron Dynamics')
plt.legend()
plt.grid()
plt.show()

```

# What you have already tried

The code above is pretty much all that I have tried, I just tried removing units, adding units back (for example adding and removing units on tau\_r, tau\_v and tau\_h) to see if that’d make it work. I tried different bracketing on the equations to see if that was causing some sort of syntax issue. I also tried different methods like euler, exact, rk4 but they all give the same output.

# Full traceback of error (if relevant)

* * *

AttributeError Traceback (most recent call last)  
File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:139, in BrianASTRenderer.render\_node(self, node)  
138 try:  
 → 139 return getattr(self, methname)(node)  
140 except AttributeError:

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:198, in BrianASTRenderer.render\_Call(self, node)  
197 node.scalar = False  
 → 198 if node.func.id in self.variables:  
199 funcvar = self.variables[node.func.id]

AttributeError: ‘Attribute’ object has no attribute ‘id’

During handling of the above exception, another exception occurred:

SyntaxError Traceback (most recent call last)  
File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/core/network.py:1002, in Network.before\_run(self, run\_namespace)  
1001 try:  
 → 1002 obj.before\_run(run\_namespace)  
1003 except Exception as ex:

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/groups/group.py:1266, in CodeRunner.before\_run(self, run\_namespace)  
1265 def before\_run(self, run\_namespace):  
 → 1266 self.create\_code\_objects(run\_namespace)  
1267 super().before\_run(run\_namespace)

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/groups/group.py:1259, in CodeRunner.create\_code\_objects(self, run\_namespace)  
1256 def create\_code\_objects(self, run\_namespace):  
1257 # By default, we only have one code object for each CodeRunner.  
1258 # Overwrite this function to use more than one.  
 → 1259 code\_object = self.create\_default\_code\_object(run\_namespace)  
1260 if code\_object:

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/groups/group.py:1240, in CodeRunner.create\_default\_code\_object(self, run\_namespace)  
1239 else:  
 → 1240 self.codeobj = create\_runner\_codeobj(  
1241 group=self.group,  
1242 code=self.abstract\_code,  
1243 user\_code=self.user\_code,  
1244 template\_name=self.template,  
1245 name=f"{self.name}\_codeobject\*",  
1246 check\_units=self.check\_units,  
1247 additional\_variables=additional\_variables,  
1248 needed\_variables=self.needed\_variables,  
1249 run\_namespace=run\_namespace,  
1250 template\_kwds=self.template\_kwds,  
1251 override\_conditional\_write=self.override\_conditional\_write,  
1252 codeobj\_class=self.codeobj\_class,  
1253 )  
1254 return self.codeobj

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/codegen/codeobject.py:484, in create\_runner\_codeobj(group, code, template\_name, run\_namespace, user\_code, variable\_indices, name, check\_units, needed\_variables, additional\_variables, template\_kwds, override\_conditional\_write, codeobj\_class)  
482 variables[var\_index] = all\_variables[var\_index]  
 → 484 return device.code\_object(  
485 owner=group,  
486 name=name,  
487 abstract\_code=code,  
488 variables=variables,  
489 template\_name=template\_name,  
490 variable\_indices=all\_variable\_indices,  
491 template\_kwds=template\_kwds,  
492 codeobj\_class=codeobj\_class,  
493 override\_conditional\_write=override\_conditional\_write,  
494 compiler\_kwds=compiler\_kwds,  
495 )

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/devices/device.py:324, in Device.code\_object(self, owner, name, abstract\_code, variables, template\_name, variable\_indices, codeobj\_class, template\_kwds, override\_conditional\_write, compiler\_kwds)  
320 logger.diagnostic(  
321 f"{name} abstract code:\n{indent(code\_representation(abstract\_code))}"  
322 )  
 → 324 scalar\_code, vector\_code, kwds = generator.translate(  
325 abstract\_code, dtype=prefs[“core.default\_float\_dtype”]  
326 )  
327 # Add the array names as keywords as well

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/codegen/generators/base.py:273, in CodeGenerator.translate(self, code, dtype)  
272 for ac\_name, ac\_code in code.items():  
 → 273 statements = make\_statements(  
274 ac\_code, self.variables, dtype, optimise=True, blockname=ac\_name  
275 )  
276 scalar\_statements[ac\_name], vector\_statements[ac\_name] = statements

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/utils/caching.py:107, in cached..cached\_func(\*args, \*\*kwds)  
106 func.\_cache\_statistics.misses += 1  
 → 107 func.\_cache[cache\_key] = func(\*args, \*\*kwds)  
108 return func.\_cache[cache\_key]

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/codegen/translation.py:429, in make\_statements(code, variables, dtype, optimise, blockname)  
428 if optimise and prefs.codegen.loop\_invariant\_optimisations:  
 → 429 scalar\_statements, vector\_statements = optimise\_statements(  
430 scalar\_statements, vector\_statements, variables, blockname=blockname  
431 )  
433 return scalar\_statements, vector\_statements

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/codegen/optimisation.py:117, in optimise\_statements(scalar\_statements, vector\_statements, variables, blockname)  
116 # Now check if boolean simplification can be carried out  
 → 117 complexity\_std = expression\_complexity(new\_expr, simplifier.variables)  
118 idents = get\_identifiers(new\_expr)

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/codegen/optimisation.py:60, in expression\_complexity(expr, variables)  
59 def expression\_complexity(expr, variables):  
—\> 60 return brian\_ast(expr, variables).complexity

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:121, in brian\_ast(expr, variables)  
120 renderer = BrianASTRenderer(variables)  
 → 121 return renderer.render\_node(node)

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:139, in BrianASTRenderer.render\_node(self, node)  
138 try:  
 → 139 return getattr(self, methname)(node)  
140 except AttributeError:

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:231, in BrianASTRenderer.render\_BinOp(self, node)  
230 node.right.parent = weakref.proxy(node)  
 → 231 node.left = self.render\_node(node.left)  
232 node.right = self.render\_node(node.right)

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:139, in BrianASTRenderer.render\_node(self, node)  
138 try:  
 → 139 return getattr(self, methname)(node)  
140 except AttributeError:

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:232, in BrianASTRenderer.render\_BinOp(self, node)  
231 node.left = self.render\_node(node.left)  
 → 232 node.right = self.render\_node(node.right)  
233 # TODO: we could capture some syntax errors here, e.g. bool+bool  
234 # captures, e.g. int+float-\>float

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:139, in BrianASTRenderer.render\_node(self, node)  
138 try:  
 → 139 return getattr(self, methname)(node)  
140 except AttributeError:

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:232, in BrianASTRenderer.render\_BinOp(self, node)  
231 node.left = self.render\_node(node.left)  
 → 232 node.right = self.render\_node(node.right)  
233 # TODO: we could capture some syntax errors here, e.g. bool+bool  
234 # captures, e.g. int+float-\>float

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:139, in BrianASTRenderer.render\_node(self, node)  
138 try:  
 → 139 return getattr(self, methname)(node)  
140 except AttributeError:

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:231, in BrianASTRenderer.render\_BinOp(self, node)  
230 node.right.parent = weakref.proxy(node)  
 → 231 node.left = self.render\_node(node.left)  
232 node.right = self.render\_node(node.right)

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:139, in BrianASTRenderer.render\_node(self, node)  
138 try:  
 → 139 return getattr(self, methname)(node)  
140 except AttributeError:

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:231, in BrianASTRenderer.render\_BinOp(self, node)  
230 node.right.parent = weakref.proxy(node)  
 → 231 node.left = self.render\_node(node.left)  
232 node.right = self.render\_node(node.right)

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/parsing/bast.py:141, in BrianASTRenderer.render\_node(self, node)  
140 except AttributeError:  
 → 141 raise SyntaxError(f"Unknown syntax: {nodename}")

SyntaxError: Unknown syntax: Call

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

BrianObjectException Traceback (most recent call last)  
Cell In[31], line 33  
30 h\_probe = StateMonitor(neuron, ‘h’, record=True)  
32 # Run the simulation  
—\> 33 run(5 \* ms)  
34 neuron.I\_ext = 3.0  
35 run(0.1 \* ms)

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/units/fundamentalunits.py:2652, in check\_units..do\_check\_units..new\_f(\*args, \*\*kwds)  
2642 error\_message = (  
2643 f"Function ‘{f. **name** }’ "  
2644 “expected a quantity with unit "  
2645 f”{unit} for argument ‘{k}’ but got "  
2646 f"‘{value}’"  
2647 )  
2648 raise DimensionMismatchError(  
2649 error\_message, get\_dimensions(newkeyset[k])  
2650 )  
 → 2652 result = f(\*args, \*\*kwds)  
2653 if “result” in au:  
2654 if isinstance(au[“result”], Callable) and au[“result”] not in (  
2655 bool,  
2656 np.bool\_,  
2657 ):

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/core/magic.py:407, in run(duration, report, report\_period, namespace, profile, level)  
334 @check\_units(duration=second, report\_period=second)  
335 def run(  
336 duration,  
(…)  
341 level=0,  
342 ):  
343 “”"  
344 run(duration, report=None, report\_period=10\*second, namespace=None, level=0)  
345  
(…)  
405 intended use. See `MagicNetwork` for more details.  
406 “”"  
 → 407 return magic\_network.run(  
408 duration,  
409 report=report,  
410 report\_period=report\_period,  
411 namespace=namespace,  
412 profile=profile,  
413 level=2 + level,  
414 )

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/core/magic.py:248, in MagicNetwork.run(self, duration, report, report\_period, namespace, profile, level)  
238 def run(  
239 self,  
240 duration,  
(…)  
245 level=0,  
246 ):  
247 self.\_update\_magic\_objects(level=level + 1)  
 → 248 Network.run(  
249 self,  
250 duration,  
251 report=report,  
252 report\_period=report\_period,  
253 namespace=namespace,  
254 profile=profile,  
255 level=level + 1,  
256 )

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/core/base.py:335, in device\_override..device\_override\_decorator..device\_override\_decorated\_function(\*args, \*\*kwds)  
333 return getattr(curdev, name)(\*args, \*\*kwds)  
334 else:  
 → 335 return func(\*args, \*\*kwds)

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/units/fundamentalunits.py:2652, in check\_units..do\_check\_units..new\_f(\*args, \*\*kwds)  
2642 error\_message = (  
2643 f"Function ‘{f. **name** }’ "  
2644 “expected a quantity with unit "  
2645 f”{unit} for argument ‘{k}’ but got "  
2646 f"‘{value}’"  
2647 )  
2648 raise DimensionMismatchError(  
2649 error\_message, get\_dimensions(newkeyset[k])  
2650 )  
 → 2652 result = f(\*args, \*\*kwds)  
2653 if “result” in au:  
2654 if isinstance(au[“result”], Callable) and au[“result”] not in (  
2655 bool,  
2656 np.bool\_,  
2657 ):

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/core/network.py:1138, in Network.run(self, duration, report, report\_period, namespace, profile, level)  
1135 if namespace is None:  
1136 namespace = get\_local\_namespace(level=level + 3)  
 → 1138 self.before\_run(namespace)  
1140 if len(all\_objects) == 0:  
1141 return # TODO: raise an error? warning?

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/core/base.py:335, in device\_override..device\_override\_decorator..device\_override\_decorated\_function(\*args, \*\*kwds)  
333 return getattr(curdev, name)(\*args, \*\*kwds)  
334 else:  
 → 335 return func(\*args, \*\*kwds)

File ~/anaconda3/envs/syde\_552/lib/python3.9/site-packages/brian2/core/network.py:1004, in Network.before\_run(self, run\_namespace)  
1002 obj.before\_run(run\_namespace)  
1003 except Exception as ex:  
 → 1004 raise BrianObjectException(  
1005 “An error occurred when preparing an object.”, obj  
1006 ) from ex  
1008 # Check that no object has been run as part of another network before  
1009 for obj in all\_objects:

BrianObjectException: Error encountered with object named ‘neurongroup\_1\_stateupdater’.  
Object was created here (most recent call only, full details in debug log):  
File ‘/tmp/ipykernel\_404216/754336726.py’, line 21, in   
neuron = NeuronGroup(1, eqn, method=‘euler’)

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

---

<div class="post-metadata">

**Author:** ![mstimberg](https://yyz2.discourse-cdn.com/free1/user_avatar/brian.discourse.group/mstimberg/32/11_2.png) [@mstimberg](https://brian.discourse.group/u/mstimberg)\
**Post date:** [28 January 2025 09:17 UTC](https://brian.discourse.group/t/implementing-the-wilson-neuron/1381/2 "2025-01-28T09:17:22Z")

</div>

Hi @zain-altaf. Actually, the model looks great, there does not seem to be anything wrong with it. I can run it and get

 ![Figure_1](https://global.discourse-cdn.com/free1/uploads/brian/original/1X/020f923408d68bc01a0a282d31131caa98cedf07.png)  
which looks like what you want, right?

I think the reason for your errors is a mismatch in versions. Are you using Brian’s latest version (i.e. 2.8.x)? If yes, you also have to use Python ≥ 3.10 and from your error message I can see that you are still on Python 3.9. We are following the policy of other scientific software packages for the versions of Python we support (see [NEP 29 — Recommend Python and NumPy version support as a community policy standard — NumPy Enhancement Proposals](https://numpy.org/neps/nep-0029-deprecation_policy.html)). Quite often, Brian will work fine with older versions as well, but it seems that in your case it doesn’t. If if is complicated to update the Python version, another option would be to downgrade Brian to version 2.6 which is still compatible with Python 3.9 – for your model, the old version should work just as well, I think.
