{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Using CSA with spatial populations\n\nThis example shows a brute-force way of specifying connections between\nNEST populations with spatial data using Connection Set Algebra instead of\nthe built-in connection routines.\n\nUsing the CSA requires NEST to be compiled with support for\nlibneurosim. For details, see [1]_.\n\n## See Also\n\n:doc:`csa_example`\n\n## References\n\n.. [1] Djurfeldt M, Davison AP and Eppler JM (2014). Efficient generation of\n       connectivity in neuronal networks from simulator-independent\n       descriptions. Front. Neuroinform.\n       https://doi.org/10.3389/fninf.2014.00043\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First, we import all necessary modules.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import nest\nimport matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Next, we check for the availability of the CSA Python module. If it does\nnot import, we exit with an error message.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "try:\n    import csa\n    haveCSA = True\nexcept ImportError:\n    print(\"This example requires CSA to be installed in order to run.\\n\" +\n          \"Please make sure you compiled NEST using\\n\" +\n          \"  -Dwith-libneurosim=[OFF|ON|</path/to/libneurosim>]\\n\" +\n          \"and CSA and libneurosim are available.\")\n    import sys\n    sys.exit(1)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We define a factory that returns a CSA-style geometry function for\nthe given layer. The function returned will return for each CSA-index\nthe position in space of the given neuron as a 2- or 3-element list.\n\nThis function stores a copy of the neuron positions internally, entailing\nmemory overhead.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def geometryFunction(population):\n\n    positions = nest.GetPosition(population)\n\n    def geometry_function(idx):\n        return positions[idx]\n\n    return geometry_function"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We create two spatial populations that have 20x20 neurons of type\n``iaf_psc_alpha``.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "pop1 = nest.Create('iaf_psc_alpha', positions=nest.spatial.grid([20, 20]))\npop2 = nest.Create('iaf_psc_alpha', positions=nest.spatial.grid([20, 20]))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "For each population, we create a CSA-style geometry function and a CSA metric\nbased on them.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "g1 = geometryFunction(pop1)\ng2 = geometryFunction(pop2)\nd = csa.euclidMetric2d(g1, g2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The connection set `cg` describes a Gaussian connectivity profile with\n``sigma = 0.2`` and cutoff at 0.5, and two values (10000.0 and 1.0) used as\n``weight`` and ``delay``, respectively.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "cg = csa.cset(csa.random * (csa.gaussian(0.2, 0.5) * d), 10000.0, 1.0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We can now connect the populations using the ``Connect`` function\nwith the ``conngen`` rule. It takes the IDs of pre- and postsynaptic\nneurons (``pop1`` and ``pop2``), the connection set (``cg``) and a\ndictionary that map the parameters weight and delay to positions in\nthe value set associated with the connection set (``params_map``).\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "params_map = {\"weight\": 0, \"delay\": 1}\nconnspec = {\"rule\": \"conngen\", \"cg\": cg, \"params_map\": params_map}\nnest.Connect(pop1, pop2, connspec)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, we use the ``PlotTargets`` function to show all targets in `pop2`\nstarting at the center neuron of `pop1`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "cntr = nest.FindCenterElement(pop1)\nnest.PlotTargets(cntr, pop2)\nplt.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.8.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}