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
|
function OldNewRecogExp(subNo,hand)
% OldNewRecogExp(subNo,hand);
%
% Example of an old/new recognition experiment.
%
% This is an example of a simple old/new recognition experiment. It is split
% into two phases, a study phase and a test phase:
%
% Study phase:
%
% In the study phase, the subject is presented with 3 images of objects in
% randomized presentation order and has to learn/memorize them. Each image
% is presented for a 'duration' of 2 seconds, then the image disappears and
% the subject has to advance to the next presentation by pressing the 'n'
% key on the keyboard. The list of 'study' objects is read from the file
% 'studylist.txt'.
%
% Test phase:
%
% In the test phase, the subject is presented with test images defined in
% the file 'testlist.txt', again in randomized order. Test images are
% presented for a 'duration' of 0.5 seconds or until the subjects responds
% with a keypress. The subject has to press one of two keys, telling if the
% test image is an "old" image - previously presented in the study phase,
% or a "new" image - not seen in the study phase. The keys used are 'c' and
% 'm', the mapping of keys to response ("old" or "new") is selected by the
% input argument "hand" -- allowing to balance for handedness of subjects /
% response bias.
%
% At the end of a session (when all images in the 'testlist.txt' have been
% presented and tested), the results - both response of the subject and its
% reaction time - are stored to a file 'OldNewRecogExp_xx.dat', where 'xx'
% is the subject number given as input argument "subNo" to this script.
%
% Input parameters:
%
% subNo subject number; use subNo>99 to skip check for existing file
% hand response mapping for test phase
%
% e.g.: OldNewRecogExp(99,1);
%
% Example DESIGN:
%
% STUDY PHASE: study 3 objects
% TEST PHASE: shown 6 objects, decide whether the object is old or new
%
% This script demonstrates:
%
% - reading from files to get condition on each trial
% - randomizing conditions (for the study and test phase)
% - showing image/collecting response (response time, accuracy)
% - writing data to file "OldNewRecogExp_<subNo>.dat
%
% Please refer to other included demos for new functions of Psychtoolbox-3
% vs. the old Psychtoolbox-2.
%
% Other than a few changes how to call the Screen function,
% and the try ... catch statements, this code replicates a
% typical OS9 experiment
%
% NOTE to previous MacOS-9 users: OSX is case sensitive!!!
%
% History:
%
% 05/24/05 Quoc Vuong, PhD, University of NewCastle wrote and contributed
% it, as an example for usage of Psychtoolbox-3, Version 1.0.6.
% 03/01/08 Mario Kleiner modified the code to make use of new functionality
% added in Psychtoolbox 3.0.8.
%%%%%%%%%%%%%%%%%%%%%%%%%
% any preliminary stuff
%%%%%%%%%%%%%%%%%%%%%%%%%
% Clear Matlab/Octave window:
clc;
% check for Opengl compatibility, abort otherwise:
AssertOpenGL;
% Check if all needed parameters given:
if nargin < 2
error('Must provide required input parameters "subNo" and "hand"!');
end
% Reseed the random-number generator for each expt.
rand('state',sum(100*clock));
% Make sure keyboard mapping is the same on all supported operating systems
% Apple MacOS/X, MS-Windows and GNU/Linux:
KbName('UnifyKeyNames');
% Init keyboard responses (caps doesn't matter)
advancestudytrial=KbName('n');
% Use input variable "hand" to determine response mapping for this session.
if (hand==1)
oldresp=KbName('c'); % "old" response via key 'c'
newresp=KbName('m'); % "new" response via key 'm'
else
oldresp=KbName('m'); % Keys are switched in this case.
newresp=KbName('c');
end
%%%%%%%%%%%%%%%%%%%%%%
% file handling
%%%%%%%%%%%%%%%%%%%%%%
% Define filenames of input files and result file:
datafilename = strcat('OldNewRecogExp_',num2str(subNo),'.dat'); % name of data file to write to
studyfilename = 'studylist.txt'; % study list
testfilename = 'testlist.txt'; % test list
% check for existing result file to prevent accidentally overwriting
% files from a previous subject/session (except for subject numbers > 99):
if subNo<99 && fopen(datafilename, 'rt')~=-1
fclose('all');
error('Result data file already exists! Choose a different subject number.');
else
datafilepointer = fopen(datafilename,'wt'); % open ASCII file for writing
end
%%%%%%%%%%%%%%%%%%%%%%
% experiment
%%%%%%%%%%%%%%%%%%%%%%
% Embed core of code in try ... catch statement. If anything goes wrong
% inside the 'try' block (Matlab error), the 'catch' block is executed to
% clean up, save results, close the onscreen window etc.
try
% Get screenNumber of stimulation display. We choose the display with
% the maximum index, which is usually the right one, e.g., the external
% display on a Laptop:
screens=Screen('Screens');
screenNumber=max(screens);
% Hide the mouse cursor:
HideCursor;
% Returns as default the mean gray value of screen:
gray=GrayIndex(screenNumber);
% Open a double buffered fullscreen window on the stimulation screen
% 'screenNumber' and choose/draw a gray background. 'w' is the handle
% used to direct all drawing commands to that window - the "Name" of
% the window. 'wRect' is a rectangle defining the size of the window.
% See "help PsychRects" for help on such rectangles and useful helper
% functions:
[w, wRect]=Screen('OpenWindow',screenNumber, gray);
% Set text size (Most Screen functions must be called after
% opening an onscreen window, as they only take window handles 'w' as
% input:
Screen('TextSize', w, 32);
% Do dummy calls to GetSecs, WaitSecs, KbCheck to make sure
% they are loaded and ready when we need them - without delays
% in the wrong moment:
KbCheck;
WaitSecs(0.1);
GetSecs;
% Set priority for script execution to realtime priority:
priorityLevel=MaxPriority(w);
Priority(priorityLevel);
% run through study and test phase
for phase=1:2 % 1 is study phase, 2 is test phase
% Setup experiment variables etc. depending on phase:
if phase==1 % study phase
% define variables for current phase
phaselabel='study';
duration=2.000; % Duration of study image presentation in secs.
trialfilename=studyfilename;
message = 'study phase ...\nstudy each picture ... press _n_ when it disappears ...\n... press mouse button to begin ...';
% Screen('DrawText', w, , 10, 10, 255);
% Screen('DrawText', w, , 10, 40, 255);
% Screen('DrawText', w, , 10, 70, 255);
else % test phase
% define variables
phaselabel='test';
duration=0.500; %sec
trialfilename=testfilename;
% write message to subject
str=sprintf('Press _%s_ for OLD and _%s_ for NEW\n',KbName(oldresp),KbName(newresp));
message = ['test phase ...\n' str '... press mouse button to begin ...'];
% Screen('DrawText', w, 'test phase ...', 10, 10, 255);
% Screen('DrawText', w, str, 10, 40, 255);
% Screen('DrawText', w, '... press mouse to begin ...', 10, 70,
% 255);
end
% Write instruction message for subject, nicely centered in the
% middle of the display, in white color. As usual, the special
% character '\n' introduces a line-break:
DrawFormattedText(w, message, 'center', 'center', WhiteIndex(w));
% Update the display to show the instruction text:
Screen('Flip', w);
% Wait for mouse click:
GetClicks(w);
% Clear screen to background color (our 'gray' as set at the
% beginning):
Screen('Flip', w);
% Wait a second before starting trial
WaitSecs(1.000);
% read list of conditions/stimulus images -- textread() is a matlab function
% objnumber arbitrary number of stimulus
% objname stimulus filename
% objtype 1=old stimulus, 2=new stimulus
% for study list, stimulus coded as "old"
[ objnumber, objname, objtype ] = textread(trialfilename,'%d %s %d');
% Randomize order of list
ntrials=length(objnumber); % get number of trials
randomorder=randperm(ntrials); % randperm() is a matlab function
objnumber=objnumber(randomorder); % need to randomize each list!
objname=objname(randomorder); %
objtype=objtype(randomorder); %
% loop through trials
for trial=1:ntrials
% wait a bit between trials
WaitSecs(0.500);
% initialize KbCheck and variables to make sure they're
% properly initialized/allocted by Matlab - this to avoid time
% delays in the critical reaction time measurement part of the
% script:
[KeyIsDown, endrt, KeyCode]=KbCheck;
% read stimulus image into matlab matrix 'imdata':
stimfilename=strcat('stims/',char(objname(trial))); % assume stims are in subfolder "stims"
imdata=imread(char(stimfilename));
% make texture image out of image matrix 'imdata'
tex=Screen('MakeTexture', w, imdata);
% Draw texture image to backbuffer. It will be automatically
% centered in the middle of the display if you don't specify a
% different destination:
Screen('DrawTexture', w, tex);
% Show stimulus on screen at next possible display refresh cycle,
% and record stimulus onset time in 'startrt':
[VBLTimestamp startrt]=Screen('Flip', w);
% while loop to show stimulus until subjects response or until
% "duration" seconds elapsed.
while (GetSecs - startrt)<=duration
% poll for a resp
% during test phase, subjects can response
% before stimulus terminates
if ( phase==2 ) % if test phase
if ( KeyCode(oldresp)==1 || KeyCode(newresp)==1 )
break;
end
[KeyIsDown, endrt, KeyCode]=KbCheck;
end
% Wait 1 ms before checking the keyboard again to prevent
% overload of the machine at elevated Priority():
WaitSecs(0.001);
end
% Clear screen to background color after fixed 'duration'
% or after subjects response (on test phase)
Screen('Flip', w);
% loop until valid key is pressed
% if a response is made already, then this loop will be skipped
if ( phase==1 ) % study phase
while (KeyCode(advancestudytrial)==0)
[KeyIsDown, endrt, KeyCode]=KbCheck;
WaitSecs(0.001);
end
end
if ( phase==2 ) % test phase
while ( KeyCode(oldresp)==0 && KeyCode(newresp)==0 )
[KeyIsDown, endrt, KeyCode]=KbCheck;
WaitSecs(0.001);
end
end
% compute response time
rt=round(1000*(endrt-startrt));
% compute accuracy
if (phase==1 ) % study phase
ac=1;
else % test phase
ac=0;
% code correct if old-response with old stimulus,
% new-response with new stimulus, or study phase
if ( (KeyCode(oldresp)==1 && objtype(trial)==1) || (KeyCode(newresp)==1 && objtype(trial)==2) )
ac=1;
end
end
resp=KbName(KeyCode); % get key pressed by subject
% Write trial result to file:
fprintf(datafilepointer,'%i %i %s %i %s %i %s %i %i %i\n', ...
subNo, ...
hand, ...
phaselabel, ...
trial, ...
resp, ...
objnumber(trial), ...
char(objname(trial)), ...
objtype(trial), ...
ac, ...
rt);
end % for trial loop
end % phase loop
% Cleanup at end of experiment - Close window, show mouse cursor, close
% result file, switch Matlab/Octave back to priority 0 -- normal
% priority:
sca;
ShowCursor;
fclose('all');
Priority(0);
% End of experiment:
return;
catch
% catch error: This is executed in case something goes wrong in the
% 'try' part due to programming error etc.:
% Do same cleanup as at the end of a regular session...
sca;
ShowCursor;
fclose('all');
Priority(0);
% Output the error message that describes the error:
psychrethrow(psychlasterror);
end % try ... catch %
% only 352 lines of codes ... :)
|