File: OldNewRecogExp.m

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (352 lines) | stat: -rw-r--r-- 13,321 bytes parent folder | download | duplicates (5)
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 ...  :)