{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Perlin spontaneous\n",
    "\n",
    "Author: Sebastian Spreizer\n",
    "\n",
    "The MIT License"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib notebook\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import nest\n",
    "import noise\n",
    "import numpy as np\n",
    "\n",
    "import lib.connectivity_map as cm\n",
    "import lib.lcrn_network as lcrn\n",
    "import lib.animation as animation\n",
    "import lib.plot3d as pl3d\n",
    "import lib.colormap as cmap"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Perlin landscape for connectivity"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Network size\n",
    "nrowE = ncolE = 120\n",
    "nrowI = ncolI = 60\n",
    "npopE = nrowE * ncolE\n",
    "npopI = nrowI * ncolI\n",
    "\n",
    "nrow = nrowE\n",
    "landscape = np.round(cm.Perlin_uniform(nrow, size=3, base=1) * 7).astype(int)\n",
    "move = cm.move(nrow)\n",
    "\n",
    "fig,ax = plt.subplots(1,1)\n",
    "im = ax.matshow(landscape.reshape(nrow,-1), cmap=cmap.virno())\n",
    "plt.colorbar(im, ax=ax)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Set Kernel Status"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.random.seed(0)\n",
    "nest.ResetKernel()\n",
    "nest.SetKernelStatus({\n",
    "    'local_num_threads': 4,\n",
    "    'resolution': 0.1,\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Create nodes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "params = {\n",
    "    \"C_m\":      250.0,\n",
    "    \"E_L\":      -70.0,\n",
    "    \"V_reset\":  -70.0,\n",
    "    \"V_th\":     -55.0,\n",
    "    \"t_ref\":      2.0,\n",
    "    \"tau_m\":     10.0,\n",
    "    \"tau_minus\": 20.0,\n",
    "    \"tau_syn_ex\": 5.0,\n",
    "    \"tau_syn_in\": 5.0,\n",
    "}\n",
    "\n",
    "popE = nest.Create('iaf_psc_alpha', npopE, params=params)\n",
    "popI = nest.Create('iaf_psc_alpha', npopI, params=params)\n",
    "pop = popE + popI\n",
    "\n",
    "# Create devices\n",
    "ngE = nest.Create('noise_generator')\n",
    "ngI = nest.Create('noise_generator')\n",
    "ng = ngE + ngI\n",
    "sd = nest.Create('spike_detector', params={'start':500.})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Connect nodes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "offsetE = popE[0]\n",
    "offsetI = popI[0]\n",
    "\n",
    "p = 0.05\n",
    "stdE = 9\n",
    "stdI = 12\n",
    "g = 8\n",
    "shift = 1\n",
    "\n",
    "\n",
    "for idx in range(npopE):\n",
    "    # E-> E\n",
    "    source = idx, nrowE, ncolE, nrowE, ncolE, int(p * npopE), stdE, False\n",
    "    targets, delay = lcrn.lcrn_gauss_targets(*source)\n",
    "    targets = (targets + shift * move[landscape[idx] % len(move)]) % npopE\n",
    "    targets = targets[targets != idx] \n",
    "    nest.Connect([popE[idx]], (targets + offsetE).tolist(), syn_spec={'weight': 10.0})\n",
    "\n",
    "    # E-> I\n",
    "    source = idx, nrowE, ncolE, nrowI, ncolI, int(p * npopI), stdE / 2, False\n",
    "    targets, delay = lcrn.lcrn_gauss_targets(*source)\n",
    "    nest.Connect([popE[idx]], (targets + offsetI).tolist(), syn_spec={'weight': 10.0})\n",
    "\n",
    "for idx in range(npopI):\n",
    "    # I-> E\n",
    "    source = idx, nrowI, ncolI, nrowE, ncolE, int(p * npopE), stdI, False\n",
    "    targets, delay = lcrn.lcrn_gauss_targets(*source)\n",
    "    nest.Connect([popI[idx]], (targets + offsetE).tolist(), syn_spec={'weight': g * -10.0})\n",
    "\n",
    "    # I-> I\n",
    "    source = idx, nrowI, ncolI, nrowI, ncolI, int(p * npopI), stdI / 2, False\n",
    "    targets, delay = lcrn.lcrn_gauss_targets(*source)\n",
    "    targets = targets[targets != idx]\n",
    "    nest.Connect([popI[idx]], (targets + offsetI).tolist(), syn_spec={'weight': g * -10.0})\n",
    "\n",
    "# Connect noise input device to all neurons\n",
    "nest.Connect(ngE, popE, syn_spec={'weight': 10.0})\n",
    "nest.Connect(ngI, popI, syn_spec={'weight': 10.0})\n",
    "\n",
    "nest.Connect(pop, sd)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Warming up"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "nest.SetStatus(ng, params={'std': 50.})\n",
    "nest.Simulate(250.)\n",
    "nest.SetStatus(ng, params={'mean': 35., 'std': 10.})\n",
    "nest.Simulate(250.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Start simulation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "nest.SetStatus(ng, params={'mean': 35., 'std': 10.})\n",
    "nest.Simulate(1000.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Plot spiking activity"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sdE = nest.GetStatus(sd, 'events')[0]\n",
    "ts, gids = sdE['times'], sdE['senders']\n",
    "fig, ax = plt.subplots(1)\n",
    "ax.plot(ts, gids, 'k|')\n",
    "ax.set_xlabel('Time [ms]')\n",
    "ax.set_ylabel('Neuron')\n",
    "ax.set_ylim(200,400)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "idx = gids - offsetE < npopE\n",
    "gids, ts = gids[idx] - offsetE, ts[idx]\n",
    "time = nest.GetKernelStatus('time')\n",
    "\n",
    "ts_bins = np.arange(time-1000., time, 10.)\n",
    "h = np.histogram2d(ts, gids, bins=[ts_bins, range(npopE + 1)])[0]\n",
    "hh = h.reshape(-1, nrowE, ncolE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig,ax = plt.subplots(1)\n",
    "im = ax.imshow(hh.sum(0) / 1., cmap='binary')\n",
    "ax.set_xlabel('x')\n",
    "ax.set_ylabel('y')\n",
    "plt.colorbar(im,ax=ax)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Animation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(1)\n",
    "im2 = ax.imshow(landscape.reshape(nrow,-1), cmap=cmap.virno())\n",
    "im1 = ax.imshow(hh[0], vmin=0, vmax=np.max(hh), cmap='binary_r', alpha=.5)\n",
    "anim = animation.imshow(fig, ax, im1, hh, ts_bins)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#anim.save('EI_networks-spontaneous.mp4', fps=10., extra_args=['-vcodec', 'libx264'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Interactive animation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "animation.HTML(anim.to_jshtml())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 3D plotting of spike activity"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fig,ax = pl3d.scatter(ts,gids%nrow,gids//nrow)\n",
    "ax.set_xlabel('Time [ms]')\n",
    "ax.set_ylabel('y position')\n",
    "ax.set_zlabel('x position')\n",
    "ax.set_xlim(500,1500)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}