Building Synapse Models#

@Chaoming Wang

In BrainPy, synapse models can be created by several ways. In this section, we will talk about a structural building process with brainpy.dyn.TwoEndConn, which is used to create models with pre- and post-synaptic neuron groups. A synapse model is decomposed into several components in brainpy.dyn.TwoEndConn. In such a way, building a synapse model can follow a modular and composable programming interface. Fore more details of defining a general synapse model, please refer to brainpy.dyn.SynConn in Tutorial: Customizing Synapse Models.

import brainpy as bp

# bp.math.set_platform('cpu')

bp.__version__
'2.3.1'

Synaptic models with brainpy.dyn.TwoEndConn#

In general, brainpy.dyn.TwoEndConn is used to model synaptic models with the following form:

\[\begin{split} \frac{dg}{dt} = f_{\mathrm{dyn}}(g, t)& \,\, \to \, &\text{dyanmics of the synaptic conductance} \\ g_{\mathrm{max}} = f_{\mathrm{LTP}}(g_{\mathrm{max}}, t) & \,\, \to \, &\text{long-term plasticity on synaptic weights }\\ g = f_{\mathrm{STP}}(g, t) & \,\, \to \, &\text{short-term plasticity on synaptic conductance}\\ I_{\mathrm{post}} = f_{\mathrm{out}}(g_{\mathrm{max}} * g, t) & \,\, \to \, &\text{synaptic output onto post-synpatic neurons}\\ \end{split}\]

where each synapse model has its dynamical conductance \(g\), synaptic weight \(g_{\mathrm{max}}\), and

  • \(I_{\mathrm{post}}\) is the synaptic current onto the post-synaptic neurons,

  • \(f_{\mathrm{dyn}}\) is the function to compute synaptic dynamics,

  • \(f_{\mathrm{LTP}}\) is the function for computing synaptic long-term plasticity,

  • \(f_{\mathrm{STP}}\) is the function for computing synaptic short-term plasticity,

  • \(f_{\mathrm{out}}\) is the way to output synaptic currents on post-synaptic neurons.

Example 1: Exponential synapse model#

For a exponential synapse model,

\[\begin{split} \frac{d g}{d t} = -\frac{g}{\tau_{decay}}+\sum_{k} \delta(t-t_{j}^{k}), \, (1) \\ I_{\mathrm{post}}(t) = g_{\mathrm{max}} * g * (V_{\mathrm{post}}(t)-E), \end{split}\]

where its \(f_{\mathrm{dyn}}\) is defined as equation (1), its \(f_{\mathrm{LTP}}\) and \(f_{\mathrm{STP}}\) is the identity function \(x = f(x)\), \(f_{\mathrm{out}}\) is defined as a conductance-based form with \((V_{\mathrm{post}}(t)-E)\).

Therefore, in BrainPy, we can define this model as the following form:

# a pre-synaptic neuron which generate spike at 1 ms, 11 ms, 21 ms.
pre = bp.neurons.SpikeTimeGroup(1, [1., 11., 21.], [0, 0, 0])

# a post-synaptic integrator which integrate synaptic inputs
post = bp.neurons.LeakyIntegrator(1)

# the synaptic model we want, whose output function is defined with `bp.synouts.COBA`
bp.synapses.Exponential(pre, post, bp.conn.All2All(),
                        output=bp.synouts.COBA(E=0.))
Exponential(name=Exponential0, mode=NonBatchingMode, 
            pre=SpikeTimeGroup(name=SpikeTimeGroup0, mode=NonBatchingMode, size=(1,)), 
            post=LeakyIntegrator(name=LeakyIntegrator0, mode=NonBatchingMode, size=(1,)))

Similarly, an Exponential synapse model with the current-based output can be defined as:

bp.synapses.Exponential(pre, post, bp.conn.All2All(),
                        output=bp.synouts.CUBA())
Exponential(name=Exponential1, mode=NonBatchingMode, 
            pre=SpikeTimeGroup(name=SpikeTimeGroup0, mode=NonBatchingMode, size=(1,)), 
            post=LeakyIntegrator(name=LeakyIntegrator0, mode=NonBatchingMode, size=(1,)))

Example 2: NMDA synapse model#

NMDA synapse model is different from other models, since its currents onto post-synaptic groups are regulated by magnesium. Specifically, the net NMDA receptor-mediated synaptic current is given by

\[ I_{\mathrm{post}} = g_{\mathrm{max}} \cdot g(t) \cdot (V(t)-E) \cdot g_{\infty} \]

where \(g_{\infty}\) represents the fraction of channels that are not blocked by magnesium.

\[ g_{\infty} = (1+{e}^{-\alpha V} \frac{[{Mg}^{2+}]_{o}} {\beta})^{-1} \]

Here \([{Mg}^{2+}]_{o}\) is the extracellular magnesium concentration, usually 1 mM.

In BrainPy, we provide this kind of magnesium-mediated synaptic output with brainpy.synouts.MgBlock. Therefore, a NMDA synapse can be defined with:

bp.synapses.NMDA(pre, post, bp.conn.All2All(),
                 output=bp.synouts.MgBlock(E=0., cc_Mg=1.2))
NMDA(name=NMDA0, mode=NonBatchingMode, 
     pre=SpikeTimeGroup(name=SpikeTimeGroup0, mode=NonBatchingMode, size=(1,)), 
     post=LeakyIntegrator(name=LeakyIntegrator0, mode=NonBatchingMode, size=(1,)))

Example 3: Synapse models with short-term plasticity#

Short-term synaptic plasticity is ambitious in synapse dynamics. BrainPy provides brainpy.synplast.STD for short-term depression and brainpy.synplast.STP for general short-term plasticity. Short-term synaptic plasticity can be added onto most of synaptic models in BrainPy. For instance, here we define AMPA, GABA, and NMDA synapse models used in (Guoshi Li, et, al., 2017) [1].

  • [1] Li, Guoshi, Craig S. Henriquez, and Flavio Fröhlich. “Unified thalamic model generates multiple distinct oscillations with state-dependent entrainment by stimulation.” PLoS computational biology 13.10 (2017): e1005797.

# AMPA synapse model with STD

bp.synapses.AMPA(pre, post, bp.conn.FixedProb(0.3),
                 stp=bp.synplast.STD(tau=700, U=0.07),
                 output=bp.synouts.COBA(E=0.),
                 alpha=0.94, beta=0.18, g_max=6e-3)
AMPA(name=AMPA0, mode=NonBatchingMode, 
     pre=SpikeTimeGroup(name=SpikeTimeGroup0, mode=NonBatchingMode, size=(1,)), 
     post=LeakyIntegrator(name=LeakyIntegrator0, mode=NonBatchingMode, size=(1,)))
# GABA synapse model with STD

bp.synapses.GABAa(pre, post, bp.conn.FixedProb(0.3),
                  stp=bp.synplast.STD(tau=700, U=0.07),
                  output=bp.synouts.COBA(E=-80),
                  alpha=10.5, beta=0.166, g_max=3e-3)
GABAa(name=GABAa0, mode=NonBatchingMode, 
      pre=SpikeTimeGroup(name=SpikeTimeGroup0, mode=NonBatchingMode, size=(1,)), 
      post=LeakyIntegrator(name=LeakyIntegrator0, mode=NonBatchingMode, size=(1,)))
# NMDA synapse model with STD

bp.synapses.NMDA(pre, post, bp.conn.FixedProb(0.3),
                 stp=bp.synplast.STD(tau=700, U=0.07),
                 output=bp.synouts.MgBlock(E=0., cc_Mg=1.2))
NMDA(name=NMDA1, mode=NonBatchingMode, 
     pre=SpikeTimeGroup(name=SpikeTimeGroup0, mode=NonBatchingMode, size=(1,)), 
     post=LeakyIntegrator(name=LeakyIntegrator0, mode=NonBatchingMode, size=(1,)))

Example 4: synapse models with long-term plasticity#

TODO.