Network

The Network object stores simulation objects and runs simulations. Usage is described in detail below. For simple scripts, you don’t even need to use the Network object itself, just directly use the ‘’magic’’ functions run() and reinit() described below.

class brian.Network(*args, **kwds)

Contains simulation objects and runs simulations

Initialised as:

Network(...)

with ... any collection of objects that should be added to the Network. You can also pass lists of objects, lists of lists of objects, etc. Objects that need to passed to the Network object are:

Models, equations, etc. do not need to be passed to the Network object.

The most important method is the run(duration) method which runs the simulation for the given length of time (see below for details about what happens when you do this).

Example usage:

G = NeuronGroup(...)
C = Connection(...)
net = Network(G,C)
net.run(1*second)

Methods

add(...)
Add additional objects after initialisation, works the same way as initialisation.
remove(...)
Remove objects from the Network.
run(duration[, report[, report_period]])
Runs the network for the given duration. See below for details about what happens when you do this. See documentation for run() for an explanation of the report and report_period keywords.
reinit(states=True)
Reinitialises the network, runs each object’s reinit() and each clock’s reinit() method (resetting them to 0). If states=False then it will not reinitialise the NeuronGroup state variables.
stop()
Can be called from a network_operation() for example to stop the network from running.
__len__()
Returns the number of neurons in the network.
__call__(obj)

Similar to add, but you can only pass one object and that object is returned. You would only need this in obscure circumstances where objects needed to be added to the network but were either not stored elsewhere or were stored in a way that made them difficult to extract, for example below the NeuronGroup object is only added to the network if certain conditions hold:

net = Network(...)
if some_condition:
    x = net(NeuronGroup(...))

What happens when you run

For an overview, see the Concepts chapter of the main documentation.

When you run the network, the first thing that happens is that it checks if it has been prepared and calls the prepare() method if not. This just does various housekeeping tasks and optimisations to make the simulation run faster. Also, an update schedule is built at this point (see below).

Now the update() method is repeatedly called until every clock has run for the given length of time. After each call of the update() method, the clock is advanced by one tick, and if multiple clocks are being used, the next clock is determined (this is the clock whose value of t is minimal amongst all the clocks). For example, if you had two clocks in operation, say clock1 with dt=3*ms and clock2 with dt=5*ms then this will happen:

  1. update() for clock1, tick clock1 to t=3*ms, next clock is clock2 with t=0*ms.
  2. update() for clock2, tick clock2 to t=5*ms, next clock is clock1 with t=3*ms.
  3. update() for clock1, tick clock1 to t=6*ms, next clock is clock2 with t=5*ms.
  4. update() for clock2, tick clock2 to t=10*ms, next clock is clock1 with t=6*ms.
  5. update() for clock1, tick clock1 to t=9*ms, next clock is clock1 with t=9*ms.
  6. update() for clock1, tick clock1 to t=12*ms, next clock is clock2 with t=10*ms. etc.

The update() method simply runs each operation in the current clock’s update schedule. See below for details on the update schedule.

Update schedules

An update schedule is the sequence of operations that are called for each update() step. The standard update schedule is:

  • Network operations with when = 'start'
  • Network operations with when = 'before_groups'
  • Call update() method for each NeuronGroup, this typically performs an integration time step for the differential equations defining the neuron model.
  • Network operations with when = 'after_groups'
  • Network operations with when = 'middle'
  • Network operations with when = 'before_connections'
  • Call do_propagate() method for each Connection, this typically adds a value to the target state variable of each neuron that a neuron that has fired is connected to. See Tutorial 2: Connections for a more detailed explanation of this.
  • Network operations with when = 'after_connections'
  • Network operations with when = 'before_resets'
  • Call reset() method for each NeuronGroup, typically resets a given state variable to a given reset value for each neuron that fired in this update step.
  • Network operations with when = 'after_resets'
  • Network operations with when = 'end'

There is one predefined alternative schedule, which you can choose by calling the update_schedule_groups_resets_connections() method before running the network for the first time. As the name suggests, the reset operations are done before connections (and the appropriately named network operations are called relative to this rearrangement). You can also define your own update schedule with the set_update_schedule method (see that method’s API documentation for details). This might be useful for example if you have a sequence of network operations which need to be run in a given order.

brian.network_operation(*args, **kwds)

Decorator to make a function into a NetworkOperation

A NetworkOperation is a callable class which is called every time step by the Network run method. Sometimes it is useful to just define a function which is to be run every update step. This decorator can be used to turn a function into a NetworkOperation to be added to a Network object.

Example usages

Operation doesn’t need a clock:

@network_operation
def f():
    ...

Automagically detect clock:

@network_operation
def f(clock):
    ...

Specify a clock:

@network_operation(specifiedclock)
def f(clock):
    ...

Specify when the network operation is run (default is 'end'):

@network_operation(when='start')
def f():
    ...

Then add to a network as follows:

net = Network(f,...)
class brian.NetworkOperation(function=None, clock=None, when='end')

Callable class for operations that should be called every update step

Typically, you should just use the network_operation() decorator, but if you can’t for whatever reason, use this. Note: current implementation only works for functions, not any callable object.

Initialisation:

NetworkOperation(function[,clock])

If your function takes an argument, the clock will be passed as that argument.

The ‘’magic’’ functions run() and reinit() work by searching for objects which could be added to a network, constructing a network with all these objects, and working with that. They are suitable for simple scripts only. If you have problems where objects are unexpectedly not being added to the network, the best thing to do would probably be to just use an explicit Network object as above rather than trying to tweak your program to make the magic functions work. However, details are available in the brian/magic.py source code.

brian.run(duration, threads=1, report=None, report_period=10.0 * second)

Run a network created from any suitable objects that can be found

Arguments:

duration
the length of time to run the network for.
report

How to report progress, the default None doesn’t report the progress. Some standard values for report:

text, stdout
Prints progress to the standard output.
stderr
Prints progress to the standard error output stderr.
graphical, tkinter
Uses the Tkinter module to show a graphical progress bar, this may interfere with any other GUI code you have.

Alternatively, you can provide your own callback function by setting report to be a function report(elapsed, complete) of two variables elapsed, the amount of time elapsed in seconds, and complete the proportion of the run duration simulated (between 0 and 1). The report function is guaranteed to be called at the end of the run with complete=1.0 so this can be used as a condition for reporting that the computation is finished.

report_period
How often the progress is reported (by default, every 10s).

Works by constructing a MagicNetwork object from all the suitable objects that could be found (NeuronGroup, Connection, etc.) and then running that network. Not suitable for repeated runs or situations in which you need precise control.

brian.reinit(states=True)

Reinitialises any suitable objects that can be found

Usage:

reinit(states=True)

Works by constructing a MagicNetwork object from all the suitable objects that could be found (NeuronGroup, Connection, etc.) and then calling reinit() for each of them. Not suitable for repeated runs or situations in which you need precise control.

If states=False then NeuronGroup state variables will not be reinitialised.

brian.stop()

Globally stops any running network, this is reset the next time a network is run

brian.clear(erase=True, all=False)

Clears all Brian objects.

Specifically, it stops all existing Brian objects from being collected by MagicNetwork (objects created after clearing will still be collected). If erase is True then it will also delete all data from these objects. This is useful in, for example, ipython which stores persistent references to objects in any given session, stopping the data and memory from being freed up. If all=True then all Brian objects will be cleared. See also forget().

brian.forget(*objs)

Forgets the list of objects passed

Forgetting means that MagicNetwork will not pick up these objects, but all data is retained. You can pass objects or lists of objects. Forgotten objects can be recalled with recall(). See also clear().

brian.recall(*objs)

Recalls previously forgotten objects

See forget() and clear().

class brian.MagicNetwork(verbose=False, level=1)

Creates a Network object from any suitable objects

Initialised as:

MagicNetwork()

The object returned can then be used just as a regular Network object. It works by finding any object in the ‘’execution frame’’ (i.e. in the same function, script or section of module code where the MagicNetwork was created) derived from NeuronGroup, Connection or NetworkOperation.

Sample usage:

G = NeuronGroup(...)
C = Connection(...)
@network_operation
def f():
    ...
net = MagicNetwork()

Each of the objects G, C and f are added to net.

Advanced usage:

MagicNetwork([verbose=False[,level=1]])

with arguments:

verbose
Set to True to print out a list of objects that were added to the network, for debugging purposes.
level
Where to find objects. level=1 means look for objects where the MagicNetwork object was created. The level argument says how many steps back in the stack to look.