{ "nbformat_minor": 0, "nbformat": 4, "cells": [ { "execution_count": null, "cell_type": "code", "source": [ "%matplotlib inline" ], "outputs": [], "metadata": { "collapsed": false } }, { "source": [ "\n==============================================\nReal-time feedback for decoding :: Client Side\n==============================================\n\nThis example demonstrates how to setup a real-time feedback\nmechanism using StimServer and StimClient.\n\nThe idea here is to display future stimuli for the class which\nis predicted less accurately. This allows on-demand adaptation\nof the stimuli depending on the needs of the classifier.\n\nTo run this example, open ipython in two separate terminals.\nIn the first, run rt_feedback_server.py and then wait for the\nmessage\n\n RtServer: Start\n\nOnce that appears, run rt_feedback_client.py in the other terminal\nand the feedback script should start.\n\nAll brain responses are simulated from a fiff file to make it easy\nto test. However, it should be possible to adapt this script\nfor a real experiment.\n\n\n" ], "cell_type": "markdown", "metadata": {} }, { "execution_count": null, "cell_type": "code", "source": [ "# Author: Mainak Jas \n#\n# License: BSD (3-clause)\n\nfrom mne.realtime import StimClient\nfrom psychopy import visual, core\n\nprint(__doc__)\n\n# Instantiating stimulation client\n\n# Port number must match port number used to instantiate\n# StimServer. Any port number above 1000 should be fine\n# because they do not require root permission.\nstim_client = StimClient('localhost', port=4218)\n\n# create a window\nmywin = visual.Window([800, 600], monitor=\"testMonitor\", units=\"deg\")\n\n# create the stimuli\n\n# right checkerboard stimuli\nright_cb = visual.RadialStim(mywin, tex='sqrXsqr', color=1, size=5,\n visibleWedge=[0, 180], radialCycles=4,\n angularCycles=8, interpolate=False,\n autoLog=False)\n\n# left checkerboard stimuli\nleft_cb = visual.RadialStim(mywin, tex='sqrXsqr', color=1, size=5,\n visibleWedge=[180, 360], radialCycles=4,\n angularCycles=8, interpolate=False,\n autoLog=False)\n\n# fixation dot\nfixation = visual.PatchStim(mywin, color=-1, colorSpace='rgb', tex=None,\n mask='circle', size=0.2)\n\n# the most accurate method is using frame refresh periods\n# however, since the actual refresh rate is not known\n# we use the Clock\ntimer1 = core.Clock()\ntimer2 = core.Clock()\n\nev_list = list() # list of events displayed\n\n# start with right checkerboard stimuli. This is required\n# because the ev_list.append(ev_list[-1]) will not work\n# if ev_list is empty.\ntrig = 4\n\n# iterating over 50 epochs\nfor ii in range(50):\n\n if trig is not None:\n ev_list.append(trig) # use the last trigger received\n else:\n ev_list.append(ev_list[-1]) # use the last stimuli\n\n # draw left or right checkerboard according to ev_list\n if ev_list[ii] == 3:\n left_cb.draw()\n else:\n right_cb.draw()\n\n fixation.draw() # draw fixation\n mywin.flip() # show the stimuli\n\n timer1.reset() # reset timer\n timer1.add(0.75) # display stimuli for 0.75 sec\n\n # return within 0.2 seconds (< 0.75 seconds) to ensure good timing\n trig = stim_client.get_trigger(timeout=0.2)\n\n # wait till 0.75 sec elapses\n while timer1.getTime() < 0:\n pass\n\n fixation.draw() # draw fixation\n mywin.flip() # show fixation dot\n\n timer2.reset() # reset timer\n timer2.add(0.25) # display stimuli for 0.25 sec\n\n # display fixation cross for 0.25 seconds\n while timer2.getTime() < 0:\n pass\n\nmywin.close() # close the window\ncore.quit()" ], "outputs": [], "metadata": { "collapsed": false } } ], "metadata": { "kernelspec": { "display_name": "Python 2", "name": "python2", "language": "python" }, "language_info": { "mimetype": "text/x-python", "nbconvert_exporter": "python", "name": "python", "file_extension": ".py", "version": "2.7.13", "pygments_lexer": "ipython2", "codemirror_mode": { "version": 2, "name": "ipython" } } } }