{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Thompson et al. (2003): Circular phosphenes\n\nThis example shows how to use the\n:py:class:`~pulse2percept.models.Thompson2003Model`.\n\nThe model introduced in [Thompson2003]_ assumes that electrical stimulation\nleads to circular percepts with discrete gray levels.\nThe model also allows for a fraction of phosphenes to be omitted at random\n(dropout rate).\n\nThe model can be loaded as follows (using 10% dropout rate):\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt\nimport numpy as np\nimport pulse2percept as p2p\nmodel = p2p.models.Thompson2003Model(xystep=0.2, dropout=0.1)\nmodel.build()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "After building the model, we are ready to predict percepts.\nHere we will use an :py:class:`~pulse2percept.implants.ArgusII` implant.\n\nOne way to assign a stimulus is to pass a NumPy array with the same number of\nelements as there are electrodes in the array (i.e., 60).\nChoosing values from ``np.arange(60)`` will assign a different number to\nevery electrode. We should thus expect to see 60 circular phosphenes that get\ngradually brighter from one electrode to the next:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "implant = p2p.implants.ArgusII(stim=np.arange(60))\npercept = model.predict_percept(implant)\npercept.plot()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Setting a nonzero dropout rate will randomly choose a fraction of phosphenes\nto disappear:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fig, axes = plt.subplots(ncols=4, figsize=(15, 6))\nfor ax, drop in zip(axes, [0, 0.25, 0.5, 0.75]):\n    model.build(dropout=drop)\n    model.predict_percept(implant).plot(ax=ax)\n    ax.set_title(f\"{100*drop}% dropout\")\nfig.tight_layout()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, the model can also be applied to\n:py:class:`~pulse2percept.stimuli.VideoStimulus` objects, where every frame\nof the video will be encoded with circular phosphenes and a given dropout\nrate:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "implant.stim = p2p.stimuli.BostonTrain()\nmodel.build(dropout=0.2)\nmodel.predict_percept(implant).play()"
      ]
    }
  ],
  "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.7.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}