-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRunSubject.m
executable file
·370 lines (327 loc) · 12.4 KB
/
RunSubject.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
function [ output_args ] = RunSubject( subjID, allOptions, neighborAmt, runs, blockLength, w, input)
%Edited by: Spencer Brown 2015 [email protected]
%*******Function Args*******
%subjID - the id of the current subject
%allItems - an array containing all the objects that can be used. The array
% size is variable
%neighborAmt - the number of neighbors to test the items against i.e. every
% fifth neighbor
%runs - how many times to run through the arrays
%w - I think this is the frame
%input - tells you if the subject will be using a keyboard('k'), a mouse ('m'), or a windows 8 tablet('t')
%***********f****************
%% Defaults
% Default for subjID is 1. This only kicks in if no subject ID is given.
if exist('subjID','var') == 0;
subjID = 1;
end
if exist('allOptions','var') == 0;
allOptions = {
% [30,30],[30,29],30,[29,29],[29,28],29,[28,28],[28,27],28,[27,27],[27,26],27,...
% [26,26],[26,25],26,[25,25],[25,24],25,[24,24],[24,23],24,[23,23],[23,22],23,...
% [22,22],[22,21],22,[21,21],[21,20],21,[20,20],[20,19],20,[19,19],[19,18],19,...
% [18,18],[18,17],18,[17,17],[17,16],17,[16,16],[16,15],16,[15,15],[15,14],15,...
% [14,14],[14,13],14,[13,13],[13,12],13,[12,12],[12,11],12,[11,11],[11,10],11,...
% [10,10],[10, 9],10,[ 9, 9],[ 9, 8], 9,[ 8, 8],[ 8, 7], 8,[ 7, 7],[ 7, 6], 7,...
[ 6, 6],[ 6, 5], 6,[ 5, 5],[ 5, 4], 5,[ 4, 4],[ 4, 3], 4,[ 3, 3],[ 3, 2], 3,...
[ 2, 2],[ 2, 1], 2,[ 1, 1], 1};
end
if exist('neightborAmt','var') == 0;
neighborAmt = 5;
end
if exist('runs','var') == 0;
runs = 2;
end
if exist('blockLength','var') == 0;
blockLength = 50;
end
if exist('input','var') == 0;
input = 't'; %tablet
Screen('Preference', 'SkipSyncTests', 1 );
end
if input == 't'; % on a tablet we need to disable the screen synch test becuase . . . who knows
Screen('preference', 'SkipSyncTests',1);
addpath(genpath('D:/BehavioralValueMeasurements'))
end
%rng(subjID);
%% **Create the pairs
%set the item to new variable
initItems = allOptions;
initLength = numel(initItems);
%determine the new array length
pairedLength = (initLength * neighborAmt)-((neighborAmt * (neighborAmt + 1))/2);
%create the new array
pairedIndex = 1;
%iterate through all the items in initItems
for i = 1: initLength
for n = 1: neighborAmt
if i+n <= initLength
tempArray = {};
tempArray{1,1} = initItems{i};
tempArray{1,2} = initItems(i+n);
pairedArray{pairedIndex} = {tempArray};
pairedIndex = pairedIndex + 1;
end
end
end
%% **Create all the trials and trial order**
allTrialsLength = pairedLength * runs; %The total number of trials that will be performed
%add the paired array as many times as there are runs
allTrialsIndex = 1;
for i = 1: runs
for n = 1: pairedLength
allTrialsArray{allTrialsIndex} = pairedArray{n};
allTrialsIndex = allTrialsIndex + 1;
end
end
%Trial order
trialOrder = randperm(allTrialsLength);
%Block Length
rewardTrial = randi(blockLength);
%Add the new array in random order
for i = 1: allTrialsLength
orderedTrialsArray{i} = allTrialsArray{trialOrder(i)};
end
%Invert left and right
%Some times the "LEFT" basket should show up on the right so that the
%suject doesn't get used to seeing the "best" basket on one side of the
%other. flipLR determins when this flipping happens
switchLR = [zeros(1,ceil(allTrialsLength/2)), ones(1,floor(allTrialsLength/2))];
switchLR = switchLR(randperm(allTrialsLength));
%Invert top and bottom
%Flip the item that's one top and the item that's on bottom
switchTop = [zeros(1,ceil(allTrialsLength/2)), ones(1,floor(allTrialsLength/2))];
switchTop = switchTop(randperm(allTrialsLength));
switchBottom = [zeros(1,ceil(allTrialsLength/2)), ones(1,floor(allTrialsLength/2))];
switchBottom = switchBottom(randperm(allTrialsLength));
switchTB = cat(1, switchTop, switchBottom);
%% Set up the screen
%No Warnings
Screen('Preference', 'VisualDebuglevel', 3);
screenNumber = max(Screen('Screens'));
[width height] = Screen('WindowSize', screenNumber);
if exist('w','var') == 0;
w = Screen('OpenWindow', screenNumber,[],[],[],[]);
end
%% Saving the settings
settings.recordfolder = 'records';
settings.subjID = subjID;
settings.switchLR = switchLR; %if '0', don't flip. If '1' flip the left basker for the right basket
settings.switchTB = switchTB; %if '0', don't flip. If '1' the order of the basket
settings.neighbors = neighborAmt;
settings.runs = runs;
settings.allOptions = allOptions;
settings.taskCombiniations = pairedArray;
settings.taskOrder = trialOrder;
settings.taskAll = orderedTrialsArray;
settings.blockLength = blockLength;
settings.screenNumber = screenNumber;
settings.width = width;
settings.height = height;
% if the records folder doesn't exist, create it.
if settings.recordfolder
mkdir(settings.recordfolder);
end
% creat the file name for this run of this subject
recordname = [settings.recordfolder '/' num2str(subjID) '_' datestr(now,'yyyymmddTHHMMSS') '.mat'];
% Save the settings (the results are saved later)
save (recordname, 'settings');
% Restrict the keys that can be used for the Kb commands [ALL KEYS ARE
% ENABLED AFTER A cear all command]
if (ismac)
RestrictKeysForKbCheck([9, 13, 41]) %These are the Mac key codes for f, j, and ESCSAPE respectively
escKey = KbName('ESCAPE');
else
RestrictKeysForKbCheck([70, 74, 81]) %THese are the PC keys for f, j and q
escKey = KbName('Esc');
end
%% Visuals start
% Display "READY"
drawStart(w);
Screen('Flip',w);
WaitSecs(10);
if input == 'k';
KbWait([], 3);
elseif input == 'm';
GetClicks(w,0);
elseif input == 't';
SetMouse(width/2, height/2 ,w);
while true;
[x,y] = GetMouse(w);
if x ~= width/2 && y ~= height/2;
break;
end
end
end
%% during the experiment
% Be mindfull that only the "behavioral." data structure will be saved.
% Set all of the indexs equal to 1
trialIndex = 1;
block = 1;
while trialIndex <= allTrialsLength;
%%For all the first group of items load the images into an array
itemsLeft = {};
%trial = orderedTrialsArray{trialIndex}{1};
%left = orderedTrialsArray{trialIndex}{1}{1};
%%if there is only one item on the side, then the other box is grey
if numel(orderedTrialsArray{trialIndex}{1}{1}) < 2
firstItem = imread(strcat('Image', num2str(orderedTrialsArray{trialIndex}{1}{1}(1)), '.jpg'));
secondItem = imread('grey.jpg');
else
firstItem = imread(strcat('Image', num2str(orderedTrialsArray{trialIndex}{1}{1}(1)), '.jpg'));
secondItem = imread(strcat('Image', num2str(orderedTrialsArray{trialIndex}{1}{1}(2)), '.jpg'));
end
%Switch the top and the bottom
if switchTB(1, trialIndex) == 0
itemsLeft{1} = firstItem;
itemsLeft{2} = secondItem;
else
itemsLeft{1} = secondItem;
itemsLeft{2} = firstItem;
end
itemsRight = {};
%trial = orderedTrialsArray{trialIndex}{1};
%right = orderedTrialsArray{trialIndex}{1}{2}{1};
%%if there is only one item on the side, then the other box is grey
test = orderedTrialsArray{trialIndex}{1}{2}{1}(1);
numb = numel(orderedTrialsArray{trialIndex}{1}{2});
if numel(orderedTrialsArray{trialIndex}{1}{2}{1}) < 2
firstItem = imread(strcat('Image', num2str(orderedTrialsArray{trialIndex}{1}{2}{1}(1)), '.jpg'));
secondItem = imread('grey.jpg');
else
firstItem = imread(strcat('Image', num2str(orderedTrialsArray{trialIndex}{1}{2}{1}(1)), '.jpg'));
secondItem = imread(strcat('Image', num2str(orderedTrialsArray{trialIndex}{1}{2}{1}(2)), '.jpg'));
end
if switchTB(2,trialIndex) == 0
itemsRight{1} = firstItem;
itemsRight{2} = secondItem;
else
itemsRight{1} = secondItem;
itemsRight{2} = firstItem;
end
%%Switch left and right side
if switchLR(trialIndex) == 0;
drawChoice(itemsLeft, itemsRight,w);
elseif switchLR(trialIndex) == 1;
drawChoice(itemsRight, itemsLeft,w);
end
% Draw aka "flip"
% wait till the time is right ------ Then flip
if trialIndex > 1; % So don't wait on the first lap through
% first wiat .2 secons so that they have time to stop pressing the button.
WaitSecs(0.25);
end
[VBLTimestamp StimulusOnsetTime FlipTimestamp] = Screen('Flip',w);
if input == 'k';% 'k' for for Keyboard
[pressTime, keyCode, behavioral.deltaSecs] = KbWait([], 3);
%drawFixation
drawFixation(w);
%If a key is pressed, record that key press in the behavioral record.
if sum(keyCode) == 1;
behavioral.key(trialIndex,1) = KbName(keyCode);
behavioral.secs(trialIndex,1) = GetSecs - StimulusOnsetTime;
end
elseif input == 'm'; % 'm' is for mouse
[clicks,x,y,whichButton] = GetClicks(w,0);
%drawFixation
drawFixation(w);
%Record where the click happened and which side it was on
if x <= width/2;
behavioral.key(trialIndex,1) = 'f';
elseif x > width/2;
behavioral.key(trialIndex,1) = 'j';
end
elseif input == 't'; % 't' is for tablet
SetMouse(width/2, height/2 ,w);
while true;
[x,y] = GetMouse(w);
if x ~= width/2 && y ~= height/2;
break;
end
end
behavioral.secs(trialIndex,1) = GetSecs - StimulusOnsetTime;
%drawFixation
drawFixation(w);
if x <= width/2;
behavioral.key(trialIndex,1) = 'f';
elseif x > width/2
behavioral.key(trialIndex,1) = 'j';
end
end
%%STILL IN THE WHILE LOOP
%% All of this is just of outputting the reward
if trialIndex == rewardTrial;
left.Item = orderedTrialsArray{trialIndex}{1}{1};
right.Item = orderedTrialsArray{trialIndex}{1}{2}{1};
if behavioral.key(trialIndex) == 'f';
if switchLR(trialIndex) == 0; %%if the display was flipped, this conditional flips the reward
reward.Item = left.Item;
reward.Not = right.Item;
elseif switchLR(trialIndex) == 1;
reward.Item = right.Item;
reward.Not = left.Item;
end
elseif behavioral.key(trialIndex) == 'j';
if switchLR(trialIndex) == 0;
reward.Item = right.Item;
reward.Not = left.Item;
elseif switchLR(trialIndex) == 1;
reward.Item = left.Item;
reward.Not = right.Item;
end
end
rewardrecordname = [settings.recordfolder '/' 'reward_' num2str(subjID) '_' datestr(now,'yyyymmddTHHMMSS') '.mat'];
save (rewardrecordname, 'reward');
end
%%STILL IN WHILL LOOP
if mod(trialIndex,blockLength) == 0; %This throws up the "break" screen between trials.
drawBreak(w);
Screen('Flip',w);
WaitSecs(2);
if input == 'k';
KbWait([], 2);
elseif input == 'm';
GetClicks(w,0);
elseif input == 't';
SetMouse(width/2, height/2 ,w);
while true;
[x,y] = GetMouse(w);
if x ~= width/2 && y ~= height/2;
break;
end
end
end
Screen('CloseAll');
w1 = Screen('OpenWindow', screenNumber,[],[],[],[]);
w = w1;
recordname = [settings.recordfolder '/' num2str(subjID) '_' datestr(now,'yyyymmddTHHMMSS') '.mat'];
% Save the settings (the results are saved later)
save (recordname, 'settings');
save (recordname, 'behavioral', '-append')
block = block + 1;
end
%%increment the trial order
trialIndex = trialIndex + 1;
end%%END OF WHILE LOOP
%% at the end
% up at the end of setings we created a file to hold all of our important data
% Now we will save all of the behavioural data in the same -.mat file
save (recordname, 'behavioral', '-append')
drawStop(w);
Screen('Flip',w);
% WaitSecs(20);
if input == 'k';
KbWait([], 3);
elseif input == 'm';
GetClicks(w,0);
elseif input == 't';
SetMouse(width/2, height/2 ,w);
while true;
[x,y] = GetMouse(w);
if x ~= width/2 && y ~= height/2;
break;
end
end
end
Screen('CloseAll');
end