Problem
I’m encountering a persistent KeyError when trying to use a state variable from one NeuronGroup to dynamically modulate the rates of a PoissonGroup. I’ve tried providing the necessary objects in the namespace both at object creation and at runtime, but the error persists, and I’m struggling to understand what I’m missing.
I want to avoid using a TimedArray, since my simulations are long and if I pre-allocate a TimedArray I run out of memory. Any help would be appreciated!
Minimal code to reproduce the problem
#!/usr/bin/env python
from brian2 import *
import matplotlib.pyplot as plt
# 1. --- Parameters ---
duration = 10*second
track_length = 100*cm
speed = 20*cm/second
N_inputs = 50
# 2. --- Define the Brian2 Objects ---
# This group provides the dynamic variables
animal_eqs = '''
pos = (speed * t) % track_length : meter (constant over dt)
is_on : 1 (constant)
'''
animal = NeuronGroup(1, animal_eqs, name='animal')
# The rates string links to 'pos' and 'is_on'
rates_eq = '''
is_on * (200*Hz * (1 + sin(2*pi*i/N_inputs + 2*pi*pos/track_length))/2) + 2*Hz
'''
# Create a dedicated namespace that points to the other objects
input_namespace = {
'animal': animal,
'N_inputs': N_inputs
}
# Provide this namespace during the object's creation
inputs = PoissonGroup(N_inputs, rates=rates_eq,
namespace=input_namespace, name='inputs')
# 3. --- Set up Monitors and Network ---
spike_mon = SpikeMonitor(inputs)
pos_mon = StateMonitor(animal, 'pos', record=True)
net = Network(collect())
# 4. --- Run the Simulation in Phases ---
print("Running Phase 1: Spatial input is OFF...")
animal.is_on = 0.
net.run(duration/2, namespace=locals())
print("Running Phase 2: Spatial input is ON...")
animal.is_on = 1.
net.run(duration/2, namespace=locals())
# 5. --- Plot the Results ---
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 7), sharex=True,
gridspec_kw={'height_ratios': [3, 1]})
ax1.plot(spike_mon.t/second, spike_mon.i, '.k', ms=3)
ax1.axvline(5.0, ls='--', color='red', lw=2, label='is_on = 1')
ax1.set_title("Input Neuron Firing (Gated by 'is_on')")
ax1.set_ylabel("Neuron Index")
ax1.legend()
ax1.grid(axis='y', alpha=0.2)
ax2.plot(pos_mon.t/second, pos_mon.pos[0]/cm)
ax2.set_title("Animal Position on Track")
ax2.set_xlabel("Time (s)")
ax2.set_ylabel("Position (cm)")
plt.tight_layout()
plt.show()
Full traceback of error
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
File ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/core/network.py:1003, in Network.before_run(self, run_namespace)
1002 try:
-> 1003 obj.before_run(run_namespace)
1004 except Exception as ex:
File ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/input/poissongroup.py:132, in PoissonGroup.before_run(self, run_namespace)
131 identifiers = get_identifiers(expr)
--> 132 variables = self.resolve_all(
133 identifiers, run_namespace, user_identifiers=identifiers
134 )
135 unit = parse_expression_dimensions(rates_var.expr, variables)
File ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/groups/group.py:801, in Group.resolve_all(self, identifiers, run_namespace, user_identifiers, additional_variables)
800 for identifier in identifiers:
--> 801 resolved[identifier] = self._resolve(
802 identifier,
803 user_identifier=identifier in user_identifiers,
804 additional_variables=additional_variables,
805 run_namespace=run_namespace,
806 )
807 return resolved
File ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/groups/group.py:756, in Group._resolve(self, identifier, run_namespace, user_identifier, additional_variables)
754 # We did not find the name internally, try to resolve it in the external
755 # namespace
--> 756 return self._resolve_external(identifier, run_namespace=run_namespace)
File ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/groups/group.py:890, in Group._resolve_external(self, identifier, run_namespace, user_identifier, internal_variable)
889 error_msg = f'The identifier "{identifier}" could not be resolved.'
--> 890 raise KeyError(error_msg)
892 elif len(matches) > 1:
893 # Possibly, all matches refer to the same object
KeyError: 'The identifier "pos" could not be resolved.'
The above exception was the direct cause of the following exception:
BrianObjectException Traceback (most recent call last)
Cell In[2], line 44
42 print("Running Phase 1: Spatial input is OFF...")
43 animal.is_on = 0.
---> 44 net.run(duration/2, namespace=locals())
46 print("Running Phase 2: Spatial input is ON...")
47 animal.is_on = 1.
File ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/core/base.py:346, in device_override.<locals>.device_override_decorator.<locals>.device_override_decorated_function(*args, **kwds)
344 return getattr(curdev, name)(*args, **kwds)
345 else:
--> 346 return func(*args, **kwds)
File ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/units/fundamentalunits.py:2652, in check_units.<locals>.do_check_units.<locals>.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 ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/core/network.py:1141, in Network.run(self, duration, report, report_period, namespace, profile, level)
1138 if namespace is None:
1139 namespace = get_local_namespace(level=level + 3)
-> 1141 self.before_run(namespace)
1143 if len(all_objects) == 0:
1144 return # TODO: raise an error? warning?
File ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/core/base.py:346, in device_override.<locals>.device_override_decorator.<locals>.device_override_decorated_function(*args, **kwds)
344 return getattr(curdev, name)(*args, **kwds)
345 else:
--> 346 return func(*args, **kwds)
File ~/miniconda3/envs/brian/lib/python3.13/site-packages/brian2/core/network.py:1005, in Network.before_run(self, run_namespace)
1003 obj.before_run(run_namespace)
1004 except Exception as ex:
-> 1005 raise BrianObjectException(
1006 "An error occurred when preparing an object.", obj
1007 ) from ex
1009 # Check that no object has been run as part of another network before
1010 for obj in all_objects:
BrianObjectException: Error encountered with object named 'inputs'.
Object was created here (most recent call only, full details in debug log):
File '<ipython-input-2-c4adc19fee79>', line 32, in <module>
inputs = PoissonGroup(N_inputs, rates=rates_eq,
An error occurred when preparing an object. (See above for original error message and traceback.)
Environment info:
-
Python 3.13.2
-
Brian2 2.8.0
-
Linux OS