This file is indexed.

/usr/share/psychtoolbox-3/PsychDemos/PsychRTBoxDemo.m is in psychtoolbox-3-common 3.0.9+svn2579.dfsg1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
function PsychRTBoxDemo
% A demonstration of basic usage and functionality of the RTBox reaction time box.
%
% Usage: PsychRTBoxDemo
%
% This demo shows the basics of using the PsychRTBox function to control
% and use the "USTC - RTBox" reaction time box, a response button box for
% response collection from subjects with high timing accuracy.
%
% You must have a compatible box attached to one of the USB ports of your
% computer and the FTDI Serial-Over-USB drivers must be properly installed
% and configured on your machine. Otherwise the demo will fail to start.
%
% Only the most basic operations of the box are demonstrated with the most
% basic parameter settings to get you started. Other demos will provide
% more detailed introduction into more advanced features.
%
% First the demo tests & shows basic live button queries.
% Then a fake reaction time experiment is run for four trials. You have to
% press a button on the box in response to a beep sound as fast as possible
% and your reaction time is measured. A post-hoc method for retrieving the
% timestamps of the button events is shown. This method is fast and
% accurate, but only provides results after a session is finished, so
% programming may appear a bit awkward to some users.
%
% Then the same reaction time experiment is run again, this time
% implementing a different method to retrieve button timestamps "live"
% during the experiment session within each trial. This method is also
% accurate, but involves a calibration procedure which takes about 0.5
% seconds in each trial and therefore slows down the progress of each trial
% a bit.
%
% See the "help PsychRTBox" online help of the PsychRTBox driver for
% detailed explanation of all commands and more commands.
%

% History:
% 02/15/09  mk  Initial version written.

% Psychtoolbox properly installed?
AssertOpenGL;

% Open connection to the first RTBox connected to any USB port on the
% computer. Find the box by scanning all serial-over-usb ports for a
% compatible device. Initialize the driver and return a unique device
% handle 'rtbox' for the box:
rtbox = PsychRTBox('Open');

% After the box is opened, it will immediately start recording button
% responses and other external trigger events and store them in its
% internal event buffer, so your code can retrieve those timestamped events
% later on at a time that is convenient for you. By default the box will
% only report pushbutton presses, not release of buttons or external
% trigger signals on the light- or TTL trigger input.
% If you wanted to enable additional events to be reported, you could
% select the events to be reported via PsychRTBox('Enable', rtbox, eventname);
%
% E.g., this...
% PsychRTBox('Enable', rtbox, 'pulse');
% ... would enable reporting of TTL input pulse trigger signals as well.
%
% this...
% PsychRTBox('Enable', rtbox, 'release');
% ... would enable reporting of button release actions as well.
%
% You can disable reporting of selected events via PsychRTBox('Disable');
%
% E.g., this...
% PsychRTBox('Disable', rtbox, 'press');
% ... would disable reporting of button press actions.
%
% You can also set multiple events at once, e.g.:
% PsychRTBox('Enable', rtbox,{'release', 'pulse'});
%
% Anyway, for now we are happy with the default press events only...


% Btw. as long as your script only uses one RTBox device at a time, you
% don't really need to pass the 'rtbox' handle to all PsychRTBox functions.
% Instead of the handle you could either leave the argument away, or pass
% in the default argument []. In that case, the driver will assume that you
% want to operate on the first opened RTBox. E.g., as long as you only want
% to access the first open RTBox, PsychRTBox('GetBoxInfo'); is the same as
% PsychRTBox('GetBoxInfo', []); and PsychRTBox('GetBoxInfo', rtbox);
%
% However, we love clean coding for the sake of clean coding, so we will
% pass the 'rtbox' handle here just to demonstrate good coding style ;-)

% Query and print all box settings inside the returned struct 'boxinfo':
boxinfo = PsychRTBox('BoxInfo', rtbox);
disp(boxinfo);

% Wait for at least one button to be pressed:
fprintf('\n\nPlease press any button on the box.\n');
PsychRTBox('WaitButtonDown', rtbox);

% Test live button queries: This is the equivalent to KbCheck for the
% keyboard. It queries the current state of the box buttons. This method is
% simple, but not very exact in timing, as some delay is involved in live
% query of button state over the USB bus:

% Wait for all buttons to be released:
fprintf('Please release all buttons on the box.\n');
PsychRTBox('WaitButtonUp', rtbox);

% This loop will show the state of all buttons in an infinite loop until
% all buttons are pressed simultaneously:
while 1
    % Get 4-element bState button state vector: Each element corresponds to
    % a button on the box. A 1 means button pressed, a 0 means button
    % released:
    bState = PsychRTBox('ButtonDown', rtbox);
    clc;
    fprintf('Press and release buttons randomly. I will report buttonstate,\nuntil you press all 4 buttons simultaneously.\n');
    fprintf('ButtonState is '); disp(bState);
    
    if all(bState)
        % All buttons pressed. Break out of loop.
        break;
    end
end

drawnow;

% Wait for all button to be released:
fprintf('\n\nPlease release all buttons on the box.\n');
PsychRTBox('WaitButtonUp', rtbox);

fprintf('Thanks!\n\n');

% Now for a little fake RT experiment to demonstrate how to collect button
% responses with accurate timestamps:
%
% This is a very minimalistic experiment. In a loop the suject has to press
% a button on the box as fast as possible as soon as she hears a beep
% sound. For the sake of simplicity we will use the simple Beeper()
% function for sound generation. Albeit simple, this is not how you'd do it
% in a real auditory RT study! For a real study you'd use our
% PsychPortAudio sound driver (help PsychPortAudio for more info), which is
% optimized for high quality sound with accurate and reliable timing.
% However, we don't want to distract you here with sound related stuff, so
% we go for the simple solution.

% Start response collection and recording by the box:
% This is not strictly needed here, as the box is already "started" after
% opening the connection, but it doesn't hurt to use it. If the box is
% already started, this command will get automatically ignored:
PsychRTBox('Start', rtbox);

tBeep = [];
t = [];
b = [];

% Run 4 trials:
for trial = 1:4
    % Clear Matlab window:
    clc;
    
    % Give a "attention" signal:
    fprintf('Ready? Push a button on the box as fast as possible when you hear the beep noise.\n');
    drawnow;
    WaitSecs(2);
    
    % Now we clear the input buffer of the RTBox to get rid of any button
    % press events from previous trials or activities:
    PsychRTBox('Clear', rtbox);
    
    % From now on, the box is waiting for responses and recording them into
    % its internal buffer for later retrieval...
    
    % Wait a random amount of time within the interval 0 - 3 seconds. Take
    % a tOnset timestamp after waiting. We define tOnset as stimulus onset
    % time for the sake of simplicity here:
    tOnset = WaitSecs(rand * 3);
    
    % Emit standardized beep noise: Normally one would use the
    % PsychPortAudio driver here for good timing precision:
    Beeper(400, 0.8, 0.15);
    
    % Now we wait for some button response from the box, but not forever.
    % We wait until either exactly one button response has been received
    % (that is the 1 in the function), or until 5 seconds of time have
    % elapsed, with or without a reponse. The function will return 'tPress'
    % and 'evt', which are either empty (i.e. == []) if no button was
    % pressed within the 5 seconds, or they contain the id of the button in
    % 'evt' and the timestamp in seconds of the button press in 'tPress'.
    % Please note that 'tPress' is expressed in time of the builtin clock
    % of the box, not in GetSecs time! That means you can't directly
    % compare the tOnset timestamp from above with the tPress timestamp
    % from here. For a way to do that we'll show you examples further down
    % the code...
    [tPress, evt] = PsychRTBox('BoxSecs', rtbox, 5, [], 1);
    
    % Store result of this trial:
    if isempty(evt)
        fprintf('No response given within 5 seconds :-( Invalid trial.\n');
        WaitSecs(5);
    else
        fprintf('Good boy!\n');
        WaitSecs(3);
        t(end+1) = tPress; %#ok<AGROW>
        b(end+1) = evt; %#ok<AGROW>
        tBeep(end+1) = tOnset; %#ok<AGROW>
    end
    
    % Next trial...
end

% Ok, our experiment is finished. We'd like to have our button timestamps
% (stored in vector 't') mapped to normal computer GetSecs time, so we can
% calculate RT's post-hoc. This is accomplished by the following mapping
% function. It will perform some calibration and then convert the
% timestamps in 't' to computer timestamps and return them in the vector
% 'tResponse'. This function will stop response collection on the box, so
% you'll need to call the 'Start' method again. This function should be
% only called once during an experiment session at the end of all response
% collection for best accuracy:
tResponse = PsychRTBox('BoxsecsToGetsecs', rtbox, t);

% Calculate RT's:
RT = tResponse - tBeep;

% Show results for all trials:
for i = 1:length(RT)
    fprintf('In trial %i: Button %s pressed. RT = %f msecs.\n', i, char(b(i)), RT(i) * 1000);
end

% Close down connections to all open boxes, ie., to our only one ;-)
% Shutdown driver as well. A call to PsychRTBox('Close', rtbox); would have
% closed only the connection to the box 'rtbox' if there would have been
% multiple boxes open for uses:
PsychRTBox('CloseAll');

fprintf('Experiment I Done.\n\n');


% Ok, now we'll show you a second approach to button timestamp collection.
% This time we will retrieve timestamps in the computers GetSecs clock time
% already during the experiment. This has the advantage that you can
% immediately work with timestamps. The disadvantage is that the driver has
% to perform a clock synchronization procedure frequently - in this example
% at the start of each new trial - in order to achieve the same accuracy as
% in the example above. Therefore each trial will last about 0.5 seconds
% longer. Also, an initial calibration procedure is needed at start of the
% experiment, which takes about 60 seconds.

% Reopen the box:
rtbox = PsychRTBox('Open');

% Perform the special clock calibration procedure. This will take about 60
% seconds. You could select a different duration, e.g., 30 seconds via the
% call PsychRTBox('ClockRatio', rtbox, 30); if you wanted. However, shorter
% calibration duration means less accurate timestamps...
PsychRTBox('ClockRatio', rtbox);

% Wait for all button to be released:
clc;
fprintf('\n\nPlease release all buttons on the box.\n');
PsychRTBox('WaitButtonUp', rtbox);

tBeep = [];
t = [];
b = [];

% Run 4 trials:
for trial = 1:4
    % Clear Matlab window:
    clc;
    
    % Give a "attention" signal:
    fprintf('Ready? Push a button on the box as fast as possible when you hear the beep noise.\n');
    drawnow;
    WaitSecs(2);
    
    % Now we clear the input buffer of the RTBox to get rid of any button
    % press events from previous trials or activities. Additionally we set
    % the optional syncClocks flag to 1. This will resynchronize the clock
    % of the computer and the box for optimum accuracy of timestamps. The
    % procedure takes about 0.5 seconds extra time.
    PsychRTBox('Clear', rtbox, 1);
    
    % From now on, the box is waiting for responses and recording them into
    % its internal buffer for later retrieval...
    
    % Wait a random amount of time within the interval 0 - 3 seconds. Take
    % a tOnset timestamp after waiting. We define tOnset as stimulus onset
    % time for the sake of simplicity here:
    tOnset = WaitSecs(rand * 3);
    
    % Emit standardized beep noise: Normally one would use the
    % PsychPortAudio driver here for good timing precision:
    Beeper(400, 0.8, 0.15);
    
    % Now we wait for some button response from the box, but not forever.
    % We wait until either exactly one button response has been received
    % (that is the 1 in the function), or until 5 seconds of time have
    % elapsed, with or without a reponse. The function will return 'tResponse'
    % and 'evt', which are either empty (i.e. == []) if no button was
    % pressed within the 5 seconds, or they contain the id of the button in
    % 'evt' and the timestamp in seconds of the button press in 'tPress'.
    % Please note that 'tPress' is expressed this time in GetSecs time
    % units. That means you can directly compare the tOnset timestamp from
    % above with the tPress timestamp from here.
    % For the fun of it, we also return the times in box clock times in the
    % optional return argument 'tBox', so we can later remap the tBox times
    % into GetSecs times post-hoc, although this isn't neccessary here.
    % Anyway, just to show you it is possible to do that.
    [tResponse, evt, tBox] = PsychRTBox('GetSecs', rtbox, 5, [], 1);
    
    % Store result of this trial:
    if isempty(evt)
        fprintf('No response given within 5 seconds :-( Invalid trial.\n');
        WaitSecs(5);
    else        
        % We calculate the RT immediately this time:
        RT = tResponse - tOnset;
        fprintf('In trial %i: Button %s pressed. RT = %f msecs.\n', trial, char(evt), RT * 1000);
        WaitSecs(3);
        t(end+1) = tBox; %#ok<AGROW>
        b(end+1) = evt; %#ok<AGROW>
        tBeep(end+1) = tOnset; %#ok<AGROW>
    end
    
    % Next trial...
end

% Ok, our experiment is finished. We can perform a post-hoc remapping of
% box clock timestamps to computer timestamps again if we want, although
% this wouldn't be neccessary here, as it has been done already "live"
% within the trial loop via the PsychRTBox('GetSecs') function...
tResponse = PsychRTBox('BoxsecsToGetsecs', rtbox, t);

% Calculate RT's:
RT = tResponse - tBeep;

clc;

% Show results for all trials:
for i = 1:length(RT)
    fprintf('In trial %i: Button %s pressed. RT = %f msecs.\n', i, char(b(i)), RT(i) * 1000);
end

% Close down connections to all open boxes, ie., to our only one ;-)
% Shutdown driver as well. A call to PsychRTBox('Close', rtbox); would have
% closed only the connection to the box 'rtbox' if there would have been
% multiple boxes open for uses:
PsychRTBox('CloseAll');

fprintf('\nExperiment II Done. Bye!\n\n');

return;