{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "tags": [ "hide_input" ] }, "outputs": [], "source": [ "from IPython.core.display import HTML, Markdown, display\n", "\n", "import numpy as np\n", "import numpy.random as npr\n", "import pandas as pd\n", "import seaborn as sns\n", "import matplotlib.pyplot as plt\n", "import scipy.stats as stats\n", "import statsmodels.formula.api as smf\n", "import pingouin as pg\n", "import math\n", "\n", "import ipywidgets as widgets\n", "\n", "import ipywidgets as widgets\n", "from IPython.display import display, Markdown, clear_output\n", "import numpy as np\n", "import pandas as pd\n", "import os\n", "from datetime import datetime\n", "from ipycanvas import Canvas, hold_canvas\n", "\n", "from sdt_exp import *\n", "\n", "# Enable plots inside the Jupyter Notebook\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Signal detection: Part 2" ] }, { "cell_type": "markdown", "metadata": { "tags": [ "popout" ] }, "source": [ "Authored by *Todd Gureckis*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the previous lab you learned some of the basic analysis steps involved in signal detection analysis. In particular, we learned how to compute a statistic we called d' (dprime) and c (bias/criterion). These variables are commonly used in studies of perception to understand the performance of a subject on a task independent of their response bias (here meaning tendency to give a particular response). \n", "\n", "In the second part of the lab we will analyze data from a simple detection experiment you will have just conducted on yourselves. You will get to put your python knowledge into practice by reading in the data analyzing it. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Experiment Instructions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this experiment you job will be similar to that of a doctor. There are going to be small \"clusters\" of points which we might think of as a tumor or some other biological measurement. You can use the interaction element below to examine a few of these \"clusters\".\n", "\n", "Try using the widget below to slide between a lot of dots within a cluster and a small number. Sweep back and forth and get an idea of what a \"cluster\" could look like. The dots are spread out to a certain degree as you can see more clearly with the large number of dots. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "cf233898cd984ee59a899376ec154617", "version_major": 2, "version_minor": 0 }, "text/plain": [ "interactive(children=(IntSlider(value=36, description='dots', max=75, min=1, step=5), Output()), _dom_classes=…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "@widgets.interact(dots=(1,75, 5))\n", "def draw(dots):\n", " return draw_stimulus(include_source=True, n_background_dots=0, n_source_dots=dots, source_sd=10, source_border=20, width=400, height=400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The challenge is that these dots are going to be hidden in a background of \"noise\" which is other dots unrelated to the cluster. Here is an example of the background with no cluster present:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "9fd75a4ba3f24ab0a49e4dec3b0dd5ed", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Canvas(height=425, layout=Layout(grid_area='canvas'), width=425)" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "draw_stimulus(include_source=False, n_background_dots=30*30, n_source_dots=0, source_sd=10, source_border=20, width=400, height=400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can run the above cell many times to see different example patterns when the cluster is absent.\n", "\n", "Next here is an example of a very large cluster hidden in the background noise:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "5ac6e759393c4f94bbb4994d782594b8", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Canvas(height=425, layout=Layout(grid_area='canvas'), width=425)" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "draw_stimulus(include_source=True, n_background_dots=30*30, n_source_dots=60, source_sd=10, source_border=20, width=400, height=400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From this example you can see a very clear \"cluster\" or tumor in the stimulus. Here is one where there is a cluster/tumor but it is a little less obvious:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e19c073a2f1d4f698be16dbb311bc4ad", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Canvas(height=425, layout=Layout(grid_area='canvas'), width=425)" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "draw_stimulus(include_source=True, n_background_dots=30*30, n_source_dots=50, source_sd=10, source_border=20, width=400, height=400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, here is one where it is pretty hard to tell that there is a cluster at all (oh but there is one involving only 20 dots!):" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "940b9669d0514fceb3a8451f4385b1b2", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Canvas(height=425, layout=Layout(grid_area='canvas'), width=425)" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "draw_stimulus(include_source=True, n_background_dots=30*30, n_source_dots=20, source_sd=10, source_border=20, width=400, height=400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Your job in the experiment will be to view stimuli such as the ones above and judge if you think there is a cluster/tumor present in the image. It can often be hard to tell because even in the random dots there can be little clusters of dots that group together. Just try to do your best. Notice that there is a red \"absent\" button and a green \"present\" button. You should press \"absent\" if you think the cluster/tumor is not there, and press \"present\" if you think it is there. There are 100 trials overall.\n", "\n", "Before running the next cell set the subject number to your NYU netid (I will anonymize this later but will let me check that everyone has done the experiment)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Run the Experiment!" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "df7fd6f194e34af28c26f18b52c7c0b1", "version_major": 2, "version_minor": 0 }, "text/plain": [ "GridBox(children=(Button(description='Present', layout=Layout(grid_area='button0', width='auto'), style=Button…" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "subject_number = 'bl1611' # set your subject number here\n", "exp = Detection_Experiment(subject_number)\n", "exp.start_experiment()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Getting the data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After you run the experiment, the data will be output to a .csv file tied to your subject number. Also it is available as as pandas data frame in the current kernel environment as `exp.trials`:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | signal_present | \n", "signal_type | \n", "trial_num | \n", "button_position | \n", "subject_number | \n", "
---|---|---|---|---|---|
0 | \n", "1 | \n", "60 | \n", "0 | \n", "left | \n", "bl1611 | \n", "
1 | \n", "1 | \n", "10 | \n", "1 | \n", "left | \n", "bl1611 | \n", "
2 | \n", "1 | \n", "10 | \n", "2 | \n", "left | \n", "bl1611 | \n", "
3 | \n", "1 | \n", "15 | \n", "3 | \n", "left | \n", "bl1611 | \n", "
4 | \n", "0 | \n", "0 | \n", "4 | \n", "left | \n", "bl1611 | \n", "