Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tsodyks synapse model #917

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
100 changes: 100 additions & 0 deletions models/synapses/tsodyks_synapse.nestml
@@ -0,0 +1,100 @@
"""
tsodyks_synapse - Synapse type with short term plasticity
#########################################################

Description
+++++++++++

This synapse model implements synaptic short-term depression and short-term
facilitation according to [1]_. In particular it solves Eqs (3) and (4) from
this paper in an exact manner.

Synaptic depression is motivated by depletion of vesicles in the readily
releasable pool of synaptic vesicles (variable x in equation (3)). Synaptic
facilitation comes about by a presynaptic increase of release probability,
which is modeled by variable U in Eq (4).

The original interpretation of variable y is the amount of glutamate
concentration in the synaptic cleft. In [1]_ this variable is taken to be
directly proportional to the synaptic current caused in the postsynaptic
neuron (with the synaptic weight w as a proportionality constant). In order
to reproduce the results of [1]_ and to use this model of synaptic plasticity
in its original sense, the user therefore has to ensure the following
conditions:

1.) The postsynaptic neuron must be of type ``iaf_psc_exp`` or ``iaf_psc_exp_htum``,
because these neuron models have a postsynaptic current which decays
exponentially.

2.) The time constant of each ``tsodyks_synapse`` targeting a particular neuron
must be chosen equal to that neuron's synaptic time constant. In particular
that means that all synapses targeting a particular neuron have the same
parameter ``tau_psc``.

However, there are no technical restrictions using this model of synaptic
plasticity also in conjunction with neuron models that have a different
dynamics for their synaptic current or conductance. The effective synaptic
weight, which will be transmitted to the postsynaptic neuron upon occurrence
of a spike at time t is :math:`u(t) \cdot x(t) \cdot w`, where ``u(t)`` and ``x(t)``
are defined in Eq (3) and (4), w is the synaptic weight specified upon connection.
The interpretation is as follows: The quantity :math:`u(t) \cdot x(t)` is the release
probability times the amount of releasable synaptic vesicles at time t of the
presynaptic neuron's spike, so this equals the amount of transmitter expelled
into the synaptic cleft.

The amount of transmitter then relaxes back to 0 with time constant tau_psc
of the synapse's variable y. Since the dynamics of ``y(t)`` is linear, the
postsynaptic neuron can reconstruct from the amplitude of the synaptic
impulse :math:`u(t) \cdot x(t) \cdot w` the full shape of ``y(t)``. The postsynaptic
neuron, however, might choose to have a synaptic current that is not necessarily
identical to the concentration of transmitter ``y(t)`` in the synaptic cleft. It may
realize an arbitrary postsynaptic effect depending on ``y(t)``.


References
++++++++++

.. [1] Tsodyks M, Uziel A, Markram H (2000). Synchrony generation in recurrent
networks with frequency-dependent synapses. Journal of Neuroscience,
20 RC50. URL: http://infoscience.epfl.ch/record/183402
"""
model tsodyks_synapse:
state:
x real = 1
y real = 0
u real = 0

parameters:
w real = 1 @nest::weight # Synaptic weight
d ms = 1 ms @nest::delay # Synaptic transmission delay
tau_psc ms = 3 ms
tau_fac ms = 0 ms
tau_rec ms = 800 ms
U real = .5

input:
pre_spikes <- spike

output:
spike

onReceive(pre_spikes):
Puu real = tau_fac == 0 ? 0 : exp(-resolution() / tau_fac)
Pyy real = exp(-resolution() / tau_psc)
Pzz real = exp(-resolution() / tau_rec)
Pxy real = ((Pzz - 1) * tau_rec - (Pyy - 1) * tau_psc) / (tau_psc - tau_rec)
Pxz real = 1 - Pzz
z real = 1 - x - y

# depress synapse
u *= Puu
x += Pxy * y + Pxz * z
y *= Pyy
u += U * (1 - u)

delta_y_tsp real = u * x
x -= delta_y_tsp
y += delta_y_tsp

# deliver spike to postsynaptic partner
emit_spike(delta_y_tsp * w, d)
Expand Up @@ -671,14 +671,23 @@ public:
send( Event& e, const thread tid, const {{synapseName}}CommonSynapseProperties& cp )
{%- endif %}
{
const double __resolution = nest::Time::get_resolution().get_ms(); // do not remove, this is necessary for the resolution() function
const double __t_spike = e.get_stamp().get_ms();

double __resolution; // do not remove, this is necessary for the resolution() function
if (t_lastspike_ < 0.)
{
__resolution = __t_spike;
}
else
{
__resolution = __t_spike - t_lastspike_;
}

auto get_thread = [tid]()
{
return tid;
};

const double __t_spike = e.get_stamp().get_ms();
#ifdef DEBUG
std::cout << "{{synapseName}}::send(): handling pre spike at t = " << __t_spike << std::endl;
#endif
Expand Down