File: rt_feedback_client.py

package info (click to toggle)
python-mne 0.8.6%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 87,892 kB
  • ctags: 6,639
  • sloc: python: 54,697; makefile: 165; sh: 15
file content (116 lines) | stat: -rw-r--r-- 3,437 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""
==============================================
Real-time feedback for decoding :: Client Side
==============================================

This example demonstrates how to setup a real-time feedback
mechanism using StimServer and StimClient.

The idea here is to display future stimuli for the class which
is predicted less accurately. This allows on-demand adaptation
of the stimuli depending on the needs of the classifier.

To run this example, open ipython in two separate terminals.
In the first, run rt_feedback_server.py and then wait for the
message

    RtServer: Start

Once that appears, run rt_feedback_client.py in the other terminal
and the feedback script should start.

All brain responses are simulated from a fiff file to make it easy
to test. However, it should be possible to adapt this script
for a real experiment.

"""

print(__doc__)

# Author: Mainak Jas <mainak@neuro.hut.fi>
#
# License: BSD (3-clause)

from mne.realtime import StimClient
from psychopy import visual, core

# Instantiating stimulation client

# Port number must match port number used to instantiate
# StimServer. Any port number above 1000 should be fine
# because they do not require root permission.
stim_client = StimClient('localhost', port=4218)

# create a window
mywin = visual.Window([800, 600], monitor="testMonitor", units="deg")

# create the stimuli

# right checkerboard stimuli
right_cb = visual.RadialStim(mywin, tex='sqrXsqr', color=1, size=5,
                             visibleWedge=[0, 180], radialCycles=4,
                             angularCycles=8, interpolate=False,
                             autoLog=False)

# left checkerboard stimuli
left_cb = visual.RadialStim(mywin, tex='sqrXsqr', color=1, size=5,
                            visibleWedge=[180, 360], radialCycles=4,
                            angularCycles=8, interpolate=False,
                            autoLog=False)

# fixation dot
fixation = visual.PatchStim(mywin, color=-1, colorSpace='rgb', tex=None,
                            mask='circle', size=0.2)

# the most accurate method is using frame refresh periods
# however, since the actual refresh rate is not known
# we use the Clock
timer1 = core.Clock()
timer2 = core.Clock()

ev_list = list()  # list of events displayed

# start with right checkerboard stimuli. This is required
# because the ev_list.append(ev_list[-1]) will not work
# if ev_list is empty.
trig = 4

# iterating over 50 epochs
for ii in range(50):

    if trig is not None:
        ev_list.append(trig)  # use the last trigger received
    else:
        ev_list.append(ev_list[-1])  # use the last stimuli

    # draw left or right checkerboard according to ev_list
    if ev_list[ii] == 3:
        left_cb.draw()
    else:
        right_cb.draw()

    fixation.draw()  # draw fixation
    mywin.flip()  # show the stimuli

    timer1.reset()  # reset timer
    timer1.add(0.75)  # display stimuli for 0.75 sec

    # return within 0.2 seconds (< 0.75 seconds) to ensure good timing
    trig = stim_client.get_trigger(timeout=0.2)

    # wait till 0.75 sec elapses
    while timer1.getTime() < 0:
        pass

    fixation.draw()  # draw fixation
    mywin.flip()  # show fixation dot

    timer2.reset()  # reset timer
    timer2.add(0.25)  # display stimuli for 0.25 sec

    # display fixation cross for 0.25 seconds
    while timer2.getTime() < 0:
        pass

mywin.close()  # close the window
core.quit()