-
Notifications
You must be signed in to change notification settings - Fork 0
/
GoNoGo_avstamp.m
402 lines (316 loc) · 13.9 KB
/
GoNoGo_avstamp.m
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
clear all; close all; clc
% filename
% filename = 'C:\Users\Grid Lab\Documents\MATLAB\GoNoGo\'; % small computer
filename = 'C:\Users\sunh20\Documents\Projects\gonogo\'; % sam's comupter
% filename = 'C:\Users\eblab\Documents\Projects\gonogo\'; % nlx computer
imgbasepath = filename; % base path for images
addpath(genpath(filename)) % add psychtoolbox things
subjectID = input('subject ID? ','s');
electrodeside = input('Electrode side? ', 's'); %electrode side of brain - use keyboard with other hand
handedness = input('Hand used? ', 's');
trialno = input('Trial number? '); %how many times have we run task
filename = strcat(filename,subjectID, num2str(trialno));
%which hand are we working with?
% hand = input('Which hand are we working with? 0 for left, 1 for right: ');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% % Open connection with TDT and begin program
% DA = actxcontrol('TDevAcc.X');
%
% %initiates a connection with an OpenWorkbench server. The connection adds a client to the server
% DA.ConnectServer('Local');
%
% %throws error if there was a problem connecting
% if DA.CheckServerConnection==0
% error('Client application not connect to server')
% end
%
% % DA.SetTankName('GIVEMETHEPATH');
%
% tdt_datafile = DA.GetTankName;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Setup PTB with some default values
PsychDefaultSetup(2);
% give praise to rngesus and show our faith by seeding
% may not be used but what the hey
% lol did james write this
rng('shuffle')
%set screen num to secondary monitor if one is connected
screenNumber = max(Screen('Screens'));
% screenNumber = 1; %weirdness with how tms task computer assigns window numbers
%define black, white and grey
white = WhiteIndex(screenNumber);
grey = white/2;
black = BlackIndex(screenNumber);
red = [1 0 0];
%Open the screen
[window, windowRect] = PsychImaging('OpenWindow', screenNumber, black, [], 32, 2);
%Flip to clear
Screen('Flip', window);
% Get the size of the on screen window
[screenXpixels, screenYpixels] = Screen('WindowSize', window);
% Get the centre coordinate of the window
[xCenter, yCenter] = RectCenter(windowRect);
%Query frame duration
ifi = Screen('GetFlipInterval', window);
%Set text size and font
Screen('TextSize', window, 60);
Screen('TextFont', window, 'Ariel');
%Query max priority level
topPriorityLevel = MaxPriority(window);
%Get center coordinates of window
[xcenter, ycenter] = RectCenter(windowRect);
%Set blend function for the screen
Screen('BlendFunction',window,'GL_SRC_ALPHA','GL_ONE_MINUS_SRC_ALPHA');
% Init audio for timestamping
% InitializePsychSound
% InitializePsychSound(1) %for really low latency
% soundfilename = 'C:\Users\gridlab\Documents\MATLAB\GoNoGo\1volt.wav';
% [sounddata,soundfreq] = audioread(soundfilename);
% nrchannels = 1; %file is mono, not stereo
% reps = 1; %only play the sound once each time it is called
% pahandle = PsychPortAudio('Open', [], [], 1, soundfreq, nrchannels);
% PsychPortAudio('FillBuffer', pahandle, sounddata');
HideCursor
%load images
bear_imgloc = strcat(imgbasepath,'bear.jpg');
lion_imgloc = strcat(imgbasepath,'lion.jpg');
bear_img = imread(bear_imgloc);
lion_img = imread(lion_imgloc);
% Make images into textures
bear_texture = Screen('MakeTexture', window, bear_img);
lion_texture = Screen('MakeTexture', window, lion_img);
% Get the size of the image (all should be same size)
[s1, s2, s3] = size(bear_img);
%define the destination rectangle for the images
dstRect = [0 0 s1 s2];
dstRect = CenterRectOnPointd(dstRect, xCenter, yCenter);
%define timestamping rectangle
ts_s1 = round(screenXpixels/20);
tsdstRect = [0 0 ts_s1 ts_s1];
tsdstRect = CenterRectOnPointd(tsdstRect, screenXpixels-round(ts_s1/2), screenYpixels-round(ts_s1/2));
% Here we check if the image is too big to fit on the screen and abort if
% it is
if s1 > screenYpixels || s2 > screenYpixels
disp('ERROR! Image is too big to fit on the screen');
sca;
return;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%----------------------------------------------------------------------
% Trial information
%----------------------------------------------------------------------
numtrials = 7;
numblocks = 7;
% init data matrices
timestamps = nan(numtrials,5,numblocks);
% soundstamps = nan(numtrials,5,numblocks); % not using this rn
subj_resp = cell(numtrials,numblocks);
% randomize presentation
% code considers each column of stim_inds to be index of trials for a block
stim_inds = ones(numtrials,numblocks);
% pick [numblocks] random integers from interval of [numtrials]
% chooses random no-go indices - TODO make this adjustable
chosen = randi(numtrials,1,numblocks);
% will only work for square stim_inds because I'm tired and lazy
for i = 1:length(chosen)
stim_inds(chosen(i),i) = 0;
end
%1 in stim_ind is go trial, 0 is NoGo trial
%----------------------------------------------------------------------
% Timing Information
%----------------------------------------------------------------------
%hold time, rule presentation, ISD, and stimulus presentation time in seconds and frames
%hold time
holdTimeSecs = 1.0;
holdTimeFrames = round(holdTimeSecs/ifi);
%maximum rule and stimulus/response presentation length
spTimeSecs = 1.0;
spTimeFrames = round(spTimeSecs/ifi);
%Number of frames to wait before re-drawing
waitframes = 1.0;
%----------------------------------------------------------------------
% Keyboard information
%----------------------------------------------------------------------
%Defined keyboard keys that are listened for.
escapeKey = KbName('ESCAPE');
spaceKey = KbName('space');
%----------------------------------------------------------------------
% Fixation Cross
%----------------------------------------------------------------------
% Here we set the size of the arms of our fixation cross
fixCrossDimPix = 40;
% Now we set the coordinates (these are all relative to zero we will let
% the drawing routine center the cross in the center of our monitor for us)
%fixation cross coordinates
xCoords = [-fixCrossDimPix fixCrossDimPix 0 0];
yCoords = [0 0 -fixCrossDimPix fixCrossDimPix];
fixCoords = [xCoords; yCoords];
% Set the line width for our fixation cross
lineWidthPix = 4;
%----------------------------------------------------------------------
% Task Loop
%----------------------------------------------------------------------
%wait until recording has started
DrawFormattedText(window, 'Please wait',...
'center', 'center', white);
Screen('Flip', window);
%if OpenWorkbench is not in Record mode, then this will set it to record
%then stores the time of recording start relative to the rest of the events
%that occur
% if DA.GetSysMode ~= 3
%
% DA.SetSysMode(3);
%
% while DA.GetSysMode ~= 3
% pause(.1)
% end
%
% TDT_recording_start = GetSecs;
%
% % % Disarm the stim - MAY NOT NEED TO DO THIS!
% % DA.SetTargetVal('RZ5D.ArmSystem', 0);
%
% end
%Instructions
DrawFormattedText(window, 'You will either see a picture of a \n\n lion or a bear.\n\n If you see the lion, press spacebar.\n\n If you see the bear, do nothing!\n\n Press spacebar to continue',...
'center', 'center', white);
Screen('Flip', window);
KbStrokeWait;
%present until subject is ready; press any key to continue
DrawFormattedText(window, 'Press spacebar to begin',...
'center', 'center', white);
Screen('Flip', window);
KbStrokeWait;
%try a couple of different timestamping methods
streamstart_time = GetSecs;
tic
for block = 1:numblocks
for trial = 1:numtrials
%timestamp trial start
% timestamps(trial,1,block) = GetSecs;
Screen('FillRect',window,black);
Screen('FillRect', window, white, tsdstRect);
[timestamps(trial,1,block),~,~,~,~] = Screen('Flip', window);
%send the "sound" as event timestamp
% soundstamps(trial,1,block) = PsychPortAudio('Start', pahandle, reps, 0, 1);
% PsychPortAudio('Stop', pahandle);
%Cue to determine whether a response has been made
respToBeMade = true;
%Flip again to sync to vertical retrace at same time as drawing
%fixation cross
%timestamp fix presentation
Screen('DrawLines', window, fixCoords,...
lineWidthPix, white, [xCenter yCenter], 2);
Screen('FillRect', window, white, tsdstRect);
[timestamps(trial,2,block),~,~,~,~] = Screen('Flip', window);
% soundstamps(trial,2,block) = PsychPortAudio('Start', pahandle, reps, 0, 1);
% PsychPortAudio('Stop', pahandle);
% Now we present the hold interval with fixation point minus one frame
% because we presented the fixation point once already when getting a
% time stamp
for frame = 1:holdTimeFrames - 1
% Draw the fixation point
Screen('DrawLines', window, fixCoords,...
lineWidthPix, white, [xCenter yCenter], 2);
%Flip to the screen
Screen('Flip', window);
end
if stim_inds(trial,block)==1 %Go trial - lions are go
Screen('DrawTexture', window, lion_texture, [], dstRect, 0);
Screen('FillRect', window, white, tsdstRect);
[timestamps(trial,3,block),~,~,~,~] = Screen('Flip', window);
% soundstamps(trial,3,block) = PsychPortAudio('Start', pahandle, reps, 0, 1);
% PsychPortAudio('Stop', pahandle);
spTimeFramescheck = 1;
while spTimeFramescheck<spTimeFrames
[keyIsDown,secs, keyCode] = KbCheck;
if keyCode(escapeKey)
subj_resp{trial,block} = 'Esc';
ShowCursor;
sca;
return
elseif keyCode(spaceKey)
subj_resp{trial,block} = 'G';
timestamps(trial,4,block) = secs;
Screen('DrawTexture', window, lion_texture, [], dstRect, 0);
Screen('FillRect', window, white, tsdstRect);
Screen('Flip', window);
% soundstamps(trial,4,block) = PsychPortAudio('Start', pahandle, reps, 0, 1);
% PsychPortAudio('Stop', pahandle);
respToBeMade = false;
end
Screen('DrawTexture', window, lion_texture, [], dstRect, 0);
Screen('Flip', window);
spTimeFramescheck = spTimeFramescheck + 1;
end
else % NoGo trial - bears are NoGo
Screen('DrawTexture', window, bear_texture, [], dstRect, 0);
Screen('FillRect', window, white, tsdstRect);
[timestamps(trial,3,block),~,~,~,~] = Screen('Flip', window);
% soundstamps(trial,3,block) = PsychPortAudio('Start', pahandle, reps, 0, 1);
% PsychPortAudio('Stop', pahandle);
spTimeFramescheck = 1;
while spTimeFramescheck<spTimeFrames
[keyIsDown,secs, keyCode] = KbCheck;
if keyCode(escapeKey)
subj_resp{trial,block} = 'Esc';
ShowCursor;
sca;
return
elseif keyCode(spaceKey)
subj_resp{trial,block} = 'G';
timestamps(trial,4,block) = secs;
Screen('DrawTexture', window, bear_texture, [], dstRect, 0);
Screen('FillRect', window, white, tsdstRect);
Screen('Flip', window);
% soundstamps(trial,4,block) = PsychPortAudio('Start', pahandle, reps, 0, 1);
% PsychPortAudio('Stop', pahandle);
respToBeMade = false;
end
Screen('DrawTexture', window, bear_texture, [], dstRect, 0);
Screen('Flip', window);
spTimeFramescheck = spTimeFramescheck + 1;
end
end
%timestamp trial end, display trial number
% timestamps(trial,5,block) = GetSecs;
Screen('FillRect',window,black);
Screen('FillRect', window, white, tsdstRect);
[timestamps(trial,5,block),~,~,~,~] = Screen('Flip', window);
% soundstamps(trial,5,block) = PsychPortAudio('Start', pahandle, reps, 0, 1);
% PsychPortAudio('Stop', pahandle);
disp(trial)
end
end
% PsychPortAudio('Close');
DrawFormattedText(window, 'Thanks for playing!',...
'center', 'center', white);
Screen('Flip', window);
% %if OpenWorkbench is in Record mode, then this will set it to Standby
% %then stores the time of recording stop relative to the rest of the events
% %that occur
% if DA.GetSysMode ~= 1
%
% DA.SetSysMode(1);
%
% while DA.GetSysMode ~= 1
% pause(.1)
% end
%
% TDT_recording_stop = GetSecs;
%
% % % Disarm the stim - MAY NOT NEED TO DO THIS!
% % DA.SetTargetVal('RZ5D.ArmSystem', 0);
%
% end
%
% % Close ActiveX connection:
% DA.CloseConnection
% if DA.CheckServerConnection == 0
% display('Server was disconnected');
% end
% clear DA
KbStrokeWait;
ShowCursor;
sca;
save(filename)