Hi @orbitalhybrid When you go away from the “flat script” structure, you need to manually add all objects to a Network
object (see e.g. Running a simulation — Brian 2 2.5.1 documentation). In general, this object is the only thing that you’d need to store, since you can access all objects stored in the Network
object like in a dictionary, using their name. Note that this is much more convenient, if you set explicit names for the objects, since otherwise they have default names such as neurongroup
, neurongroup_1
, etc.:
group = NeuronGroup(..., name='my_name')
group2 = NeuronGroup(..., name='other_name')
self.network = Network(group, group2)
self.network['my_name'].v = ... # same effect as group.v = ...
If you prefer, you can of course also keep storing the NeuronGroup
objects as attributes of the class in addition to adding them to the Network
object. The only thing that is important is that all objects that are part of your simulation (neurons, synapses, monitors, …) have been added to the Network
at some point.
You’ll then need to call run
on the network object (e.g. self.network.run
).
Note that there is a second change that is most likely necessary: the run
/Network.run
command needs to “see” the external constants that are used in the equations. E.g. the following works:
tau = 10*ms
group = NeuronGroup(1, 'dv/dt = -v/tau : 1')
net = Network(group)
net.run(100*ms) # ← can "see" tau
but the following will fail, complaining that it does not know “tau”:
class MySim:
def __init__(self):
self.tau = 10*ms
group = NeuronGroup(1, 'dv/dt = -v/tau : 1')
self.net = Network(group)
sim = MySim()
sim.net.run(100*ms) # ← does not "see" tau
One solution is to use the namespace
argument, that can be used to explicitly pass a dictionary with the external parameters (Namespaces — Brian 2 2.5.1 documentation). If you already store all constants in attributes of your object, the easiest would be to use it like this:
sim = MySim()
sim.net.run(100*ms, namespace=vars(sim))
Hope that helps!