{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Tsodyks facilitating example\n\nThis scripts simulates two neurons. One is driven with dc-input and\nconnected to the other one with a facilitating Tsodyks synapse. The\nmembrane potential trace of the second neuron is recorded.\n\nThis example reproduces figure 1B of [1]_\nThis example is analog to ``tsodyks_depressing.py``, except that\ndifferent synapse parameters are used. Here, a small facilitation\nparameter ``U`` causes a slow saturation of the synaptic efficacy\n(Eq. 2.2), enabling a facilitating behavior.\n\n## References\n\n.. [1] Tsodyks M, Pawelzik K, Markram H (1998). Neural networks with dynamic synapses. Neural\n       computation, http://dx.doi.org/10.1162/089976698300017502\n\n## See Also\n\n:doc:`tsodyks_depressing`\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First, we import all necessary modules for simulation and plotting.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import nest\nimport nest.voltage_trace\nfrom numpy import exp"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Second, the simulation parameters are assigned to variables. The neuron\nand synapse parameters are stored into a dictionary.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "h = 0.1    # simulation step size (ms)\nTau = 40.    # membrane time constant\nTheta = 15.    # threshold\nE_L = 0.     # reset potential of membrane potential\nR = 1.     # membrane resistance (GOhm)\nC = Tau / R  # Tau (ms)/R in NEST units\nTauR = 2.     # refractory time\nTau_psc = 1.5    # time constant of PSC (= Tau_inact)\nTau_rec = 130.   # recovery time\nTau_fac = 530.   # facilitation time\nU = 0.03   # facilitation parameter U\nA = 1540.  # PSC weight in pA\nf = 20. / 1000.  # frequency in Hz converted to 1/ms\nTend = 1200.  # simulation time\nTIstart = 50.    # start time of dc\nTIend = 1050.  # end time of dc\nI0 = Theta * C / Tau / (1 - exp(-(1 / f - TauR) / Tau))  # dc amplitude\n\nneuron_param = {\"tau_m\": Tau,\n                \"t_ref\": TauR,\n                \"tau_syn_ex\": Tau_psc,\n                \"tau_syn_in\": Tau_psc,\n                \"C_m\": C,\n                \"V_reset\": E_L,\n                \"E_L\": E_L,\n                \"V_m\": E_L,\n                \"V_th\": Theta}\n\nsyn_param = {\"tau_psc\": Tau_psc,\n             \"tau_rec\": Tau_rec,\n             \"tau_fac\": Tau_fac,\n             \"U\": U,\n             \"delay\": 0.1,\n             \"weight\": A,\n             \"u\": 0.0,\n             \"x\": 1.0}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Third, we reset the kernel and set the resolution using ``SetKernelStatus``.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.ResetKernel()\nnest.SetKernelStatus({\"resolution\": h})"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Fourth, the nodes are created using ``Create``. We store the returned\nhandles in variables for later reference.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "neurons = nest.Create(\"iaf_psc_exp\", 2)\ndc_gen = nest.Create(\"dc_generator\")\nvolts = nest.Create(\"voltmeter\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Fifth, the ``iaf_psc_exp`` neurons, the ``dc_generator`` and the ``voltmeter``\nare configured using ``SetStatus``, which expects a list of node handles and\na parameter dictionary or a list of parameter dictionaries.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "neurons.set(neuron_param)\ndc_gen.set(amplitude=I0, start=TIstart, stop=TIend)\nvolts.set(label=\"voltmeter\", interval=1.)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Sixth, the ``dc_generator`` is connected to the first neuron\n(`neurons[0]`) and the `voltmeter` is connected to the second neuron\n(`neurons[1]`). The command `Connect` has different variants. Plain\n``Connect`` just takes the handles of pre- and post-synaptic nodes and\nuses the default values for weight and delay. Note that the connection\ndirection for the ``voltmeter`` reflects the signal flow in the simulation\nkernel, because it observes the neuron instead of receiving events from it.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Connect(dc_gen, neurons[0])\nnest.Connect(volts, neurons[1])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Seventh, the first neuron (`neurons[0]`) is connected to the second\nneuron (`neurons[1]`).  The command ``CopyModel`` copies the\n``tsodyks_synapse`` model to the new name ``syn`` with parameters\n``syn_param``.  The manually defined model ``syn`` is used in the\nconnection routine via the ``syn_spec`` parameter.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.CopyModel(\"tsodyks_synapse\", \"syn\", syn_param)\nnest.Connect(neurons[0], neurons[1], syn_spec=\"syn\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, we simulate the configuration using the command ``Simulate``,\nwhere the simulation time `Tend` is passed as the argument.  We plot the\ntarget neuron's membrane potential as function of time.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "nest.Simulate(Tend)\nnest.voltage_trace.from_device(volts)\nnest.voltage_trace.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.12"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}