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:
The objective is to plot voltage vs time
Minimal code to reproduce problem
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.)