.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/evaluate_quantal_stp_synapse.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_evaluate_quantal_stp_synapse.py: Example for the quantal_stp_synapse ----------------------------------- .. only:: html ---- Run this example as a Jupyter notebook: .. card:: :width: 25% :margin: 2 :text-align: center :link: https://lab.ebrains.eu/hub/user-redirect/git-pull?repo=https%3A%2F%2Fgithub.com%2Fnest%2Fnest-simulator-examples&urlpath=lab%2Ftree%2Fnest-simulator-examples%2Fnotebooks%2Fnotebooks%2Fevaluate_quantal_stp_synapse.ipynb&branch=main :link-alt: JupyterHub service .. image:: https://nest-simulator.org/TryItOnEBRAINS.png .. grid:: 1 1 1 1 :padding: 0 0 2 0 .. grid-item:: :class: sd-text-muted :margin: 0 0 3 0 :padding: 0 0 3 0 :columns: 4 See :ref:`our guide ` for more information and troubleshooting. ---- The ``quantal_stp_synapse`` is a stochastic version of the Tsodys-Markram model for synaptic short term plasticity (STP). This script compares the two variants of the Tsodyks/Markram synapse in NEST. This synapse model implements synaptic short-term depression and short-term facilitation according to the quantal release model described by Fuhrmann et al. [1]_ and Loebel et al. [2]_. Each presynaptic spike will stochastically activate a fraction of the available release sites. This fraction is binomially distributed and the release probability per site is governed by the Fuhrmann et al. (2002) model. The solution of the differential equations is taken from Maass and Markram 2002 [3]_. The connection weight is interpreted as the maximal weight that can be obtained if all n release sites are activated. Parameters ~~~~~~~~~~ The following parameters can be set in the status dictionary: * U - Maximal fraction of available resources [0,1], default=0.5 * u - available fraction of resources [0,1], default=0.5 * p - probability that a vesicle is available, default = 1.0 * n - total number of release sites, default = 1 * a - number of available release sites, default = n * tau_rec - time constant for depression in ms, default=800 ms * tau_rec - time constant for facilitation in ms, default=0 (off) References ~~~~~~~~~~ .. [1] Fuhrmann G, Segev I, Markram H, and Tsodyks MV. (2002). Coding of temporal information by activity-dependent synapses. Journal of Neurophysiology, 8. https://doi.org/10.1152/jn.00258.2001 .. [2] Loebel, A., Silberberg, G., Helbig, D., Markram, H., Tsodyks, M. V, & Richardson, M. J. E. (2009). Multiquantal release underlies the distribution of synaptic efficacies in the neocortex. Frontiers in Computational Neuroscience, 3:27. doi:10.3389/neuro.10.027. .. [3] Maass W, and Markram H. (2002). Synapses as dynamic memory buffers. Neural Networks, 15(2), 155-161. http://dx.doi.org/10.1016/S0893-6080(01)00144-7 .. GENERATED FROM PYTHON SOURCE LINES 72-76 .. code-block:: Python import matplotlib.pyplot as plt import nest .. GENERATED FROM PYTHON SOURCE LINES 77-81 On average, the ``quantal_stp_synapse`` converges to the ``tsodyks2_synapse``, so we can compare the two by running multiple trials. First we define simulation time step and random seed .. GENERATED FROM PYTHON SOURCE LINES 81-99 .. code-block:: Python resolution = 0.1 # [ms] seed = 12345 # We define the number of trials as well as the number of release sites. n_sites = 10 # number of synaptic release sites n_trials = 500 # number of measurement trials # The pre-synaptic neuron is driven by an injected current for a part of each # simulation cycle. We define here the parameters for this stimulation cycle. I_stim = 376.0 # [pA] stimulation current T_on = 500.0 # [ms] stimulation is on T_off = 1000.0 # [ms] stimulation is off T_cycle = T_on + T_off # total duration of each stimulation cycle .. GENERATED FROM PYTHON SOURCE LINES 100-101 Next, we define parameter sets for facilitation and initial weight. .. GENERATED FROM PYTHON SOURCE LINES 101-104 .. code-block:: Python fac_params = {"U": 0.02, "u": 0.02, "tau_fac": 500.0, "tau_rec": 200.0, "weight": 1.0} .. GENERATED FROM PYTHON SOURCE LINES 105-106 Then, we assign the parameter set to the synapse models .. GENERATED FROM PYTHON SOURCE LINES 106-113 .. code-block:: Python tsyn_params = fac_params # for tsodyks2_synapse qsyn_params = tsyn_params.copy() # for quantal_stp_synapse tsyn_params["x"] = tsyn_params["U"] qsyn_params["n"] = n_sites .. GENERATED FROM PYTHON SOURCE LINES 114-116 To make the responses comparable, we have to scale the weight by the number of release sites. .. GENERATED FROM PYTHON SOURCE LINES 116-119 .. code-block:: Python qsyn_params["weight"] = 1.0 / n_sites .. GENERATED FROM PYTHON SOURCE LINES 120-122 We reset NEST to have a well-defined starting point, make NEST less verbose, and set some kernel attributes. .. GENERATED FROM PYTHON SOURCE LINES 122-128 .. code-block:: Python nest.ResetKernel() nest.set_verbosity("M_ERROR") nest.resolution = resolution nest.rng_seed = seed .. GENERATED FROM PYTHON SOURCE LINES 129-133 We create three different neurons. Neuron one is the sender, the two other neurons receive the synapses. We exploit Python's unpacking mechanism to assign the neurons to named variables directly. .. GENERATED FROM PYTHON SOURCE LINES 133-136 .. code-block:: Python pre_neuron, tsyn_neuron, qsyn_neuron = nest.Create("iaf_psc_exp", params={"tau_syn_ex": 3.0}, n=3) .. GENERATED FROM PYTHON SOURCE LINES 137-139 We create two voltmeters, one for each of the postsynaptic neurons. We start recording only after a first cycle, which is used for equilibration. .. GENERATED FROM PYTHON SOURCE LINES 139-142 .. code-block:: Python tsyn_voltmeter, qsyn_voltmeter = nest.Create("voltmeter", params={"start": T_cycle, "interval": resolution}, n=2) .. GENERATED FROM PYTHON SOURCE LINES 143-147 Connect one neuron with the deterministic tsodyks2 synapse and the other neuron with the stochastic quantal stp synapse; then, connect a voltmeter to each neuron. Here, ``**tsyn_params`` inserts the content of the ``tsyn_params`` dict into the dict passed to ``syn_spec``. .. GENERATED FROM PYTHON SOURCE LINES 147-159 .. code-block:: Python nest.Connect(pre_neuron, tsyn_neuron, syn_spec={"synapse_model": "tsodyks2_synapse", **tsyn_params}) # For technical reasons, we currently must set the parameters of the # quantal_stp_synapse via default values. This will change in a future version # of NEST. nest.SetDefaults("quantal_stp_synapse", qsyn_params) nest.Connect(pre_neuron, qsyn_neuron, syn_spec={"synapse_model": "quantal_stp_synapse"}) nest.Connect(tsyn_voltmeter, tsyn_neuron) nest.Connect(qsyn_voltmeter, qsyn_neuron) .. GENERATED FROM PYTHON SOURCE LINES 160-170 This loop runs over the `n_trials` trials and performs a standard protocol of a high-rate response, followed by a pause and then a recovery response. We actually run over ``n_trials + 1`` rounds, since the first trial is for equilibration and is not recorded (see voltmeter parameters above). We use the NEST ``:class:.RunManager`` to improve performance and call ``:func:.Run`` inside for each part of the simulation. We print a line of breadcrumbs to indicate progress. .. GENERATED FROM PYTHON SOURCE LINES 170-184 .. code-block:: Python print(f"Simulating {n_trials} times ", end="", flush=True) with nest.RunManager(): for t in range(n_trials + 1): pre_neuron.I_e = I_stim nest.Run(T_on) pre_neuron.I_e = 0.0 nest.Run(T_off) if t % 10 == 0: print(".", end="", flush=True) print() .. GENERATED FROM PYTHON SOURCE LINES 185-188 Simulate one additional time step. This ensures that the voltage traces for all trials, including the last, have the full length, so we can easily transform them into a matrix below. .. GENERATED FROM PYTHON SOURCE LINES 188-190 .. code-block:: Python nest.Simulate(nest.resolution) .. GENERATED FROM PYTHON SOURCE LINES 191-194 Extract voltage traces and reshape the matrix with one column per trial and one row per time step. NEST returns results as NumPy arrays. We extract times only once and keep only times for a single trial. .. GENERATED FROM PYTHON SOURCE LINES 194-204 .. code-block:: Python vm_tsyn = tsyn_voltmeter.get("events", "V_m") vm_qsyn = qsyn_voltmeter.get("events", "V_m") steps_per_trial = round(T_cycle / tsyn_voltmeter.get("interval")) vm_tsyn.shape = (n_trials, steps_per_trial) vm_qsyn.shape = (n_trials, steps_per_trial) t_vm = tsyn_voltmeter.get("events", "times") t_trial = t_vm[:steps_per_trial] .. GENERATED FROM PYTHON SOURCE LINES 205-206 Now compute the mean of all trials and plot against trials and references. .. GENERATED FROM PYTHON SOURCE LINES 206-226 .. code-block:: Python vm_tsyn_mean = vm_tsyn.mean(axis=0) vm_qsyn_mean = vm_qsyn.mean(axis=0) rms_error = ((vm_tsyn_mean - vm_qsyn_mean) ** 2).mean() ** 0.5 plt.plot(t_trial, vm_tsyn_mean, lw=2, alpha=0.7, label="Tsodyks-2 synapse (deterministic)") plt.plot(t_trial, vm_qsyn_mean, lw=2, alpha=0.7, label="Quantal STP synapse (stochastic)") plt.xlabel("Time [ms]") plt.ylabel("Membrane potential [mV]") plt.title("Comparison of deterministic and stochastic plasicity rules") plt.text( 0.95, 0.05, f"RMS error: {rms_error:.3g}", horizontalalignment="right", verticalalignment="bottom", transform=plt.gca().transAxes, ) # relative coordinates for text placement plt.legend() plt.show() .. _sphx_glr_download_auto_examples_evaluate_quantal_stp_synapse.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: evaluate_quantal_stp_synapse.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: evaluate_quantal_stp_synapse.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_