Episode 5: Visual Categorization
Learn how to perform and analyze a visual categorization experiment with g.Pype. This episode demonstrates how to run a paradigm presenting visual stimuli such as faces and patterns while recording and analyzing corresponding brain responses.
Note
This page is still under development. Until we have the step-by-step instructions ready, please refer to the code example below.
File example_paradigm_checkerboard_face.py – View file on GitHub
1from pathlib import Path
2import os
3
4import gpype as gp
5
6parent_dir = os.path.dirname(os.path.abspath(__file__))
7paradigm = os.path.join(parent_dir, "paradigms", "CheckerboardFace.xml")
8sampling_rate = 250
9channel_count = 8
10id_low_freq = 1
11id_high_freq = 2
12id_face = 3
13t_pre = 0.2
14t_post = 0.7
15
16if __name__ == "__main__":
17
18 # Create main application & pipeline
19 app = gp.MainApp()
20 p = gp.Pipeline()
21
22 # Amplifier: BCI Core-8 (uncomment if you want to use it)
23 # amp = gp.BCICore8()
24
25 # Amplifier: g.Nautilus (uncomment if you want to use it)
26 # amp = gp.GNautilus(sampling_rate=sampling_rate,
27 # channel_count=channel_count)
28
29 # Signal generator (uncomment if you want to use it)
30 amp = gp.Generator(
31 sampling_rate=sampling_rate,
32 channel_count=channel_count,
33 signal_frequency=10,
34 signal_amplitude=15,
35 signal_shape="sine",
36 noise_amplitude=10,
37 )
38
39 # Bandpass from 1 to 30 Hz
40 bandpass = gp.Bandpass(f_lo=1, f_hi=30)
41
42 # Bandstop (notch) filter for 50 and 60 Hz
43 notch50 = gp.Bandstop(f_lo=48, f_hi=52)
44 notch60 = gp.Bandstop(f_lo=58, f_hi=62)
45
46 # Presenter trigger receiver
47 trig_receiver = gp.UDPReceiver()
48
49 # Trigger data
50 trig_node_checkerboard = gp.Trigger(
51 time_pre=t_pre, time_post=t_post, target=[id_low_freq, id_high_freq]
52 )
53 trig_node_face = gp.Trigger(
54 time_pre=t_pre, time_post=t_post, target=id_face
55 )
56
57 # Keyboard capture
58 key_capture = gp.Keyboard()
59
60 # Time series scope
61 mk = gp.TimeSeriesScope.Markers
62 markers = [
63 mk(
64 color="#00aa00",
65 label="Low SF",
66 channel=channel_count,
67 value=id_low_freq,
68 ),
69 mk(
70 color="#ff0000",
71 label="High SF",
72 channel=channel_count,
73 value=id_high_freq,
74 ),
75 mk(
76 color="#0000ff", label="Face", channel=channel_count, value=id_face
77 ),
78 mk(color="m", label="M Key", channel=channel_count + 1, value=77),
79 ]
80 scope = gp.TimeSeriesScope(
81 amplitude_limit=50, time_window=10, markers=markers
82 )
83
84 # Trigger scope
85 trig_scope = gp.TriggerScope(
86 amplitude_limit=5, plots=["face", "checkerboard", "face-checkerboard"]
87 )
88
89 # Merge signals for scope and data saving
90 router_scope = gp.Router(
91 input_channels=[gp.Router.ALL, gp.Router.ALL, gp.Router.ALL]
92 )
93 router_raw = gp.Router(
94 input_channels=[gp.Router.ALL, gp.Router.ALL, gp.Router.ALL]
95 )
96
97 # File writer
98 filename = Path(paradigm).stem
99 writer = gp.CsvWriter(file_name=f"{filename}.csv")
100
101 # connect amplifier to filter nodes
102 p.connect(amp, bandpass)
103 p.connect(bandpass, notch50)
104 p.connect(notch50, notch60)
105
106 # merge scope data
107 p.connect(notch60, router_scope["in1"])
108 p.connect(trig_receiver, router_scope["in2"])
109 p.connect(key_capture, router_scope["in3"])
110
111 # merge raw data
112 p.connect(amp, router_raw["in1"])
113 p.connect(trig_receiver, router_raw["in2"])
114 p.connect(key_capture, router_raw["in3"])
115
116 # connect inputs of time series scope and file writer
117 p.connect(router_scope, scope)
118 p.connect(router_raw, writer)
119
120 # connect trigger node and scope
121 p.connect(notch60, trig_node_checkerboard[gp.Constants.Defaults.PORT_IN])
122 p.connect(trig_receiver, trig_node_checkerboard[gp.Trigger.PORT_TRIGGER])
123 p.connect(notch60, trig_node_face[gp.Constants.Defaults.PORT_IN])
124 p.connect(trig_receiver, trig_node_face[gp.Trigger.PORT_TRIGGER])
125 p.connect(trig_node_checkerboard, trig_scope["checkerboard"])
126 p.connect(trig_node_face, trig_scope["face"])
127
128 # Create main app and add widgets
129 presenter = gp.ParadigmPresenter(paradigm)
130 app.add_widget(presenter)
131 app.add_widget(scope)
132 app.add_widget(trig_scope)
133
134 # start pipeline and main app
135 p.start()
136 app.run()
137 p.stop()