# Custom events¶

## Overview¶

In most simulations, a NeuronGroup defines a threshold on its membrane potential that triggers a spike event. This event can be monitored by a SpikeMonitor, it is used in synaptic interactions, and in integrate-and-fire models it also leads to the execution of one or more reset statements.

Sometimes, it can be useful to define additional events, e.g. when an ion concentration in the cell crosses a certain threshold. This can be done with the custom events system in Brian, which is illustrated in this diagram.

You can see in this diagram that the source NeuronGroup has four types of events, called spike, evt_other, evt_mon and evt_run. The event spike is the default event. It is triggered when you you include threshold='...' in a NeuronGroup, and has two potential effects. Firstly, when the event is triggered it causes the reset code to run, specified by reset='...'. Secondly, if there are Synapses connected, it causes the on_pre on on_post code to run (depending if the NeuronGroup is presynaptic or postsynaptic for those Synapses).

In the diagram though, we have three additional event types. We’ve included several event types here to make it clearer, but you could use the same event for different purposes. Let’s start with the first one, evt_other. To understand this, we need to look at the Synapses object in a bit more detail. A Synapses object has multiple pathways associated to it. By default, there are just two, called pre and post. The pre pathway is activated by presynaptic spikes, and the post pathway by postsynaptic spikes. Specifically, the spike event on the presynaptic NeuronGroup triggers the pre pathway, and the spike event on the postsynaptic NeuronGroup triggers the post pathway. In the example in the diagram, we have created a new pathway called other, and the evt_other event in the presynaptic NeuronGroup triggers this pathway. Note that we can arrange this however we want. We could have spike trigger the other pathway if we wanted to, or allow it to trigger both the pre and other pathways. We could also allow evt_other to trigger the pre pathway. See below for details on the syntax for this.

The third type of event in the example is named evt_mon and this is connected to an EventMonitor which works exactly the same way as SpikeMonitor (which is just an EventMonitor attached by default to the event spike).

Finally, the fourth type of event in the example is named evt_run, and this causes some code to be run in the NeuronGroup triggered by the event. To add this code, we call NeuronGroup.run_on_event(). So, when you set reset='...', this is equivalent to calling NeuronGroup.run_on_event() with the spike event.

## Details¶

### Defining an event¶

This can be done with the events keyword in the NeuronGroup initializer:

group = NeuronGroup(N, '...', threshold='...', reset='...',
events={'custom_event': 'x > x_th'})


In this example, we define an event with the name custom_event that is triggered when the x variable crosses the threshold x_th. Note that you can define any number of custom events. Each event is defined by its name as the key, and its condition as the value of the dictionary.

### Recording events¶

Custom events can be recorded with an EventMonitor:

event_mon = EventMonitor(group, 'custom_event')


Such an EventMonitor can be used in the same way as a SpikeMonitor – in fact, creating the SpikeMonitor is basically identical to recording the spike event with an EventMonitor. An EventMonitor is not limited to record the event time/neuron index, it can also record other variables of the model at the time of the event:

event_mon = EventMonitor(group, 'custom_event', variables['var1', 'var2'])


### Triggering NeuronGroup code¶

If the event should trigger a series of statements (i.e. the equivalent of reset statements), this can be added by calling run_on_event:

group.run_on_event('custom_event', 'x=0')


### Triggering synaptic pathways¶

When neurons are connected by Synapses, the pre and post pathways are triggered by spike events on the presynaptic and postsynaptic NeuronGroup by default. It is possible to change which pathway is triggered by which event by providing an on_event keyword that either specifies which event to use for all pathways, or a specific event for each pathway (where non-specified pathways use the default spike event):

synapse_1 = Synapses(group, another_group, '...', on_pre='...', on_event='custom_event')


The code above causes all pathways to be triggered by an event named custom_event instead of the default spike.

synapse_2 = Synapses(group, another_group, '...', on_pre='...', on_post='...',
on_event={'pre': 'custom_event'})


In the code above, only the pre pathway is triggered by the custom_event event.

We can also create new pathways and have them be triggered by custom events. For example:

synapse_3 = Synapses(group, another_group, '...',
on_pre={'pre': '....',
'custom_pathway': '...'},
on_event={'pre': 'spike',
'custom_pathway': 'custom_event'})


In this code, the default pre pathway is still triggered by the spike event, but there is a new pathway called custom_pathway that is triggered by the custom_event event.

### Scheduling¶

By default, custom events are checked after the spiking threshold (in the after_thresholds slots) and statements are executed after the reset (in the after_resets slots). The slot for the execution of custom event-triggered statements can be changed when it is added with the usual when and order keyword arguments (see Scheduling for details). To change the time when the condition is checked, use NeuronGroup.set_event_schedule().