Newer
Older
%_______________________________________________________________________
%
% Run random dot motion experiment defined in createDotInfo
%_______________________________________________________________________
%
% Input
%
% expInfo | experiment configuration (struct)
% setup.subj | identifier of subject (string)
% condSet | conditions (cell array of strings)
%_______________________________________________________________________
%
% adapted from dotsExperiment_JQK_170327
% 170704 | cleanup, adapted
% 170707 | removed saving for each trial; instead save in catch part
% | now saves DisplayInfo
% 170809 | adapted to state space version
% 170814 | added triggers (MR, EEG, ET); turned into run version
% 170816 | adapted to multiple task variants
% 170816 | included RT feedback + reward at end of each block
% 171023 | removed peripheral word cues during presentation
function StateSwitch_experiment_171023(expInfo, setup)
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
%%
%% sanitize function parameters
%%
if nargin == 0
eval('help dotsExperiment')
return
end
if not(exist('expInfo','var'))
error('Missing input: expInfo')
elseif isempty(expInfo) || not(isstruct(expInfo))
error('Invalid input: expInfo (requires non-empty struct)')
end
if not(isfield(expInfo,'deployed'))
expInfo.deployed = true;
end
%% for EEG: set up parallel port triggers
if setup.EEG.useEEG
if setup.EEG.DIO.parallelTrigger == 1
daqreset;
rehash toolboxcache
dio = digitalio('parallel');
addline(dio,0:7,0,'out');
% check triggers
% for indTrig = 1:255; putvalue(dio,indTrig);pause(.5);end
end
else
dio = [];
end
%% prepare MR
if setup.MR.useMR
try
outportb(890,32) % sets pin for tristate in base+2 to up state. This allows to read from the port
catch
disp('outportb(890,32) unsuccessful');
end
end
if setup.MR.useMR == 1
textSizeLow = 15;
textSizeHigh = 30;
else
textSizeLow = 30;
textSizeHigh = 30;
end
if setup.MR.useMR == 1
sessionFile = [setup.subjectsPath, setup.subj, '_StateSwitchMR_',setup.task,'_', datestr(now, 'yymmdd_HHMM'), '.mat'];
else
sessionFile = [setup.subjectsPath, setup.subj, '_StateSwitch_',setup.task,'_', datestr(now, 'yymmdd_HHMM'), '.mat'];
end
%% set up PTB
displayList = Screen('screens');
displayIdx = displayList(setup.disp);
KbName('UnifyKeyNames'); % Make sure keyboard mapping is the same on all supported operating systems
oldVerbosityLevel = Screen('Preference', 'Verbosity', 2); % show errors and warnings
if setup.DEBUG == 1
Screen('Preference', 'SkipSyncTests', 1);
PsychDebugWindowConfiguration(0, setup.opacity);
else
clear Screen; %PsychDebugWindowConfiguration([], 1);
end
try
%% prepare canvas
screenInfo = openExperiment(50,50,displayIdx); clc; % open drawing canvas
if numel(Screen('screens')) == 1 || expInfo.deployed
HideCursor(screenInfo.curWindow);
end
Screen('TextFont', screenInfo.curWindow, 'Helvetica');
Screen('TextSize', screenInfo.curWindow, textSizeLow);
Screen('TextStyle', screenInfo.curWindow, 0); % regular
Screen('TextColor', screenInfo.curWindow, 255); % white
ifi = Screen('GetFlipInterval', screenInfo.curWindow); % Query the frame duration
% set up experimenter and subject keyboards
keyboardIndices = GetKeyboardIndices;
if setup.keyB == 1 % use primary keyboard for subject and experimenter
screenInfo.keyboard_sub = keyboardIndices(1);
screenInfo.keyboard_exp = keyboardIndices(1);
elseif setup.keyB == 2
screenInfo.keyboard_sub = min(keyboardIndices);
screenInfo.keyboard_exp = max(keyboardIndices);
else disp('Check setup: only 1 or 2 keyboards supported.');
end
% Do dummy calls to GetSecs, WaitSecs, KbCheck(-1) to make sure
% they are loaded and ready when we need them - without delays
% in the wrong moment:
KbCheck(-1);
WaitSecs(0.1);
GetSecs;
%% startup ET
if setup.ET.useET
% Initialize eyelink defaults and control code structure
el=EyelinkInitDefaults(screenInfo.curWindow);
el.wRect = screenInfo.screenRect;
[winWidth, winHeight] = WindowSize(screenInfo.curWindow);
el.winWidth = winWidth;
el.winHeight = winHeight;
else el = [];
end
%% session start info
Timing.sessStartTime = GetSecs;
ResultMat = NaN(expInfo.totalTrials,4);
DisplayInfo = [];
ExperimentProtocol = cell(0);
ExperimentProtocol = [ExperimentProtocol; {'SessionOnset'}, {Timing.sessStartTime}, {[]}, {[]},{[]},{[]},{[]},{NaN},{[]}];
%% run loop
for indRun = setup.StartRunOn:expInfo.runAmount
Screen('TextSize', screenInfo.curWindow, textSizeLow);
'Wir werden nun den Eyetracker konfigurieren. \n\n Bitte fixieren Sie zunchst die grauen Kreise, \n\n die auf dem Bildschirm auftauchen.', ...
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
'center', 'center', [255 255 255 255]);
Screen('Flip',screenInfo.curWindow);
while true
[exitSession, resumeSession] = checkKeys_byKeyB(expInfo, screenInfo.keyboard_sub);
if resumeSession
break
elseif exitSession
shutdownStudy(el);
return
end
end
subNo = setup.subj(1:4); % extract first four characters for subject ID
phase = 1;
el = ET_setup_JQK(setup, el, subNo, phase, indRun); % initialize the eye tracker and start recording
% The protocol should have the following format:
% [subject, time, run, block, trial, event]
Eyelink('Message', sprintf('Subj%s Time%d %Run%d Block%d Trial%d Start', ...
setup.subj, ...
GetSecs(),...
indRun, ...
0, ...
0));
end
if setup.EEG.useEEG
%% send START parallelTrigger
if setup.EEG.DIO.parallelTrigger == 1
% first trigger (1)
putvalue(dio,0); % set to 0 (trigger off); ~20us (undocumented use demo in @dioline\putvalue.m and @digitalio\putvalue.m - args are: uddobj, vals [, lineInds])
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.StartTrigger_1_01 = getvalue(dio); % read out values
putvalue(dio,1); % on
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.StartTrigger_1_11 = getvalue(dio); % read out values
putvalue(dio,0); % off
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.StartTrigger_1_02 = getvalue(dio); % read out values
% second trigger (2)
putvalue(dio,0); % set to 0 (trigger off); ~20us (undocumented use demo in @dioline\putvalue.m and @digitalio\putvalue.m - args are: uddobj, vals [, lineInds])
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.StartTrigger_2_01 = getvalue(dio); % read out values
putvalue(dio,2); % on
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.StartTrigger_2_11 = getvalue(dio); % read out values
putvalue(dio,0); % off
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.StartTrigger_2_02 = getvalue(dio); % read out values
end
end
% initiate black background (necessary if eyetracker changed it)
Screen('FillRect', screenInfo.curWindow, [0 0 0])
% change textcolor to white
Screen('TextColor', screenInfo.curWindow, [255 255 255]);
% put Ready... on the screen and wait for user presses Return
DrawFormattedText(screenInfo.curWindow, 'Bereit? \n\n Das Experiment startet in Krze ...!', 'center', 'center');
Screen('Flip', screenInfo.curWindow);
while true
[exitSession, resumeSession] = checkKeys_byKeyB(expInfo, screenInfo.keyboard_sub);
if resumeSession
if setup.ET.useET
Eyelink('Message', sprintf('Run %d Ready screen onset', indRun));
end
disp('Subject input required: ready for presentation? --> State switch start');
break
elseif exitSession
shutdownStudy(el);
return
end
end
if setup.MR.useMR==1 && setup.MR.dummy==0 % wait for scanner pulse to start exp
DrawFormattedText(screenInfo.curWindow, 'Waiting for scanner pulse','center','center', [255 255 255])
Screen('Flip', screenInfo.curWindow);
try
scannerPort = 888;
triggerSwitches = 17; % TR of experiment onset; wait for 17th TR (at TR of .625s, this should allow for 10s of equilibration)
[SCAN t0] = fMRI_waitScannerTriggers(scannerPort, indRun, triggerSwitches, []);
Eyelink('Message', sprintf('Run%d fMRI scanning Start time %g', indRun, t0));
catch
warning('MR Triggers not working!!')
end
else
t0 = GetSecs;
end
%%%%%%%%%%% START RUN %%%%%%%%%%%%%%%%%
Timing.RunInitiation = t0; Timing.lastTiming = 'NaN';
tic; % from now on scanning
ExperimentProtocol = [ExperimentProtocol; {'RunInitiation'}, {Timing.RunInitiation}, {[]}, {[]}, {[]}, {indRun}, {[]}, {[]}, {[]}];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% block loop
for indBlock = 1:expInfo.blocksPerRun
% initialize state cues of current condition
if strcmp(setup.task, 'dynamic')
StateSwitch_addSurroundingCues_dynamic_170911(expInfo, screenInfo, indRun, indBlock, 1);
elseif strcmp(setup.task, 'words')
StateSwitch_addSurroundingCues_words_171023(expInfo, screenInfo, indRun, indBlock, 1);
elseif strcmp(setup.task, 'visual')
StateSwitch_addSurroundingCues_visual(expInfo, screenInfo, indRun, indBlock, 1);
end
oldTextSize = Screen('TextSize', screenInfo.curWindow, textSizeLow);
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
DrawFormattedText(screenInfo.curWindow, ['relevante Attribute: ', num2str(expInfo.StateOrderRun{indRun}(indBlock,1))], 'center', 'center');
Screen('TextSize', screenInfo.curWindow, oldTextSize); clear oldTextSize;
% ####### Block cue onset #####
if strcmp(expInfo.timing, 'absolute') || strcmp(expInfo.timing, 'relativeITI')
flipWhen = Timing.RunInitiation+(indBlock-1)*expInfo.durBlockOnset+(indBlock-1)*expInfo.blockLengthDim*expInfo.trialDuration.all+(indBlock-1)*expInfo.durReward-(ifi/2);
elseif strcmp(expInfo.timing, 'relative')
if strcmp(Timing.lastTiming, 'NaN')
flipWhen = 0;
elseif strcmp(Timing.lastTiming, 'ITI')
flipWhen = Timing.ITIOnset+expInfo.durITI-(ifi/2);
elseif strcmp(Timing.lastTiming, 'feedback')
flipWhen = Timing.FeedbackOnset+expInfo.durReward-(ifi/2);
end
end
Timing.BlockInitiation = Screen('Flip', screenInfo.curWindow, flipWhen);
Timing.lastTiming = 'BlockCue';
ExperimentProtocol = [ExperimentProtocol; {'BlockInitiation'}, {Timing.BlockInitiation}, {[]}, {[]}, {[]}, {indRun}, {indBlock}, {[]}, {[]}];
if setup.ET.useET
Eyelink('Message', sprintf('Block %d BlockCueOnset', indBlock));
end
if setup.EEG.useEEG
if setup.EEG.DIO.parallelTrigger == 1
% set to off state
putvalue(dio,0);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.BlockTrigger_16_01(indRun,indBlock,:) = getvalue(dio);
% set to on state
putvalue(dio,16);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.BlockTrigger_16_11(indRun,indBlock,:) = getvalue(dio);
% set to off state
putvalue(dio,0);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.BlockTrigger_16_02(indRun,indBlock,:) = getvalue(dio);
end
end
% #############################
for indTrial = 1:expInfo.blockLengthDim
if setup.ET.useET
% Sending a 'TRIALID' message to mark the start of a trial in Data
% Viewer. This is different than the start of recording message
% START that is logged when the trial recording begins. The viewer
% will not parse any messages, events, or samples, that exist in
% the data file prior to this message.
Eyelink('Message', 'BLOCKID %d TRIALID %d', indBlock, indTrial);
Eyelink('command', 'record_status_message "RUN%d BLOCK%d / %d TRIAL %d / %d"', ...
indRun, indBlock, expInfo.blocksPerRun, indTrial, expInfo.blockLengthDim); % This supplies the title at the bottom of the eyetracker display
end
fprintf('Run %i of %i; Block %i of %i; Trial %i of %i\n', ...
[indRun, expInfo.runAmount, indBlock, expInfo.blocksPerRun, indTrial, expInfo.blockLengthDim])
Timing.TrialInitiation = GetSecs;
ExperimentProtocol = [ExperimentProtocol; {'TrialInitiation'}, {Timing.TrialInitiation}, {[]}, {[]}, {[]}, {indRun},{indBlock}, {indTrial}, {[]}];
% ------------------------------------------------------------------------------
% ------------------------------------------------------------------------------
if strcmp(setup.task, 'dynamic')
% create fixation
targets = makeDotTargets(screenInfo, expInfo); % initialize targets
%showTargets(screenInfo, targets, 1);
[~, expInfo, ExperimentProtocol,ResultMat,DisplayInfo,Timing] = ...
StateSwitch_trialPresentation_dynamic_170911(screenInfo, expInfo, targets, indRun, indBlock, indTrial, ...
ExperimentProtocol,ResultMat,DisplayInfo,Timing,setup, dio);
elseif strcmp(setup.task, 'words') || strcmp(setup.task, 'visual')
[~, expInfo, ExperimentProtocol,ResultMat,DisplayInfo,Timing] = ...
StateSwitch_trialPresentation_words_visual_171023(screenInfo, expInfo, [], indRun, indBlock, indTrial, ...
ExperimentProtocol,ResultMat,DisplayInfo,Timing,setup, dio);
end
% ------------------------------------------------------------------------------
% ------------------------------------------------------------------------------
% clear remaining on-screen content
Screen('Close');
end % trial presentation
% present feedback regarding RT if requested
if expInfo.durReward ~=0
% present peripheral state cues
if strcmp(setup.task, 'words')
StateSwitch_addSurroundingCues_words(expInfo, screenInfo, indRun, indBlock, indTrial);
elseif strcmp(setup.task, 'visual')
StateSwitch_addSurroundingCues_visual(expInfo, screenInfo, indRun, indBlock, indTrial);
elseif strcmp(setup.task, 'dynamic')
% StateSwitch_addSurroundingCues_dynamic(expInfo, screenInfo, indRun, indBlock, indTrial);
end
if strcmp(expInfo.RTfeedback.type, 'RT')
RTfeedb.curMdRT = nanmedian(ResultMat(:,3)); % current median rt
RTfeedb.endTrial = (indRun-1)*expInfo.blocksPerRun*expInfo.blockLengthDim+(indBlock-1)*expInfo.blockLengthDim+indTrial;
RTfeedb.begTrial = RTfeedb.endTrial-expInfo.blockLengthDim+1;
RTfeedb.lastRTs = ResultMat(RTfeedb.begTrial:RTfeedb.endTrial,3); % rts during last block
% select random trial to be compared
RTfeedb.rndChoice = RTfeedb.lastRTs(randperm(expInfo.blockLengthDim,1));
if ~isnan(RTfeedb.rndChoice) & RTfeedb.rndChoice >= RTfeedb.curMdRT-expInfo.RTfeedback.slack
oldTextSize = Screen('TextSize', screenInfo.curWindow, textSizeHigh);
DrawFormattedText(screenInfo.curWindow, ['Schnell genug! \n\n +', num2str(expInfo.RTfeedback.reward), ' cent'], 'center', 'center', [0 255 0]);
else
oldTextSize = Screen('TextSize', screenInfo.curWindow, textSizeHigh);
DrawFormattedText(screenInfo.curWindow, ['Nicht schnell genug! \n\n ', num2str(expInfo.RTfeedback.loss), ' cent'], 'center', 'center', [255 0 0]);
end
elseif strcmp(expInfo.RTfeedback.type, 'fixed')
if expInfo.RTfeedback.fixedFeedback(indRun,indBlock) == 1
oldTextSize = Screen('TextSize', screenInfo.curWindow, textSizeHigh);
DrawFormattedText(screenInfo.curWindow, ['Schnell genug! \n\n +', num2str(expInfo.RTfeedback.reward), ' cent'], 'center', 'center', [0 255 0]);
elseif expInfo.RTfeedback.fixedFeedback(indRun,indBlock) == 0
oldTextSize = Screen('TextSize', screenInfo.curWindow, textSizeHigh);
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
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
DrawFormattedText(screenInfo.curWindow, ['Nicht schnell genug! \n\n ', num2str(expInfo.RTfeedback.loss), ' cent'], 'center', 'center', [255 0 0]);
end
end
Screen('TextSize', screenInfo.curWindow, oldTextSize); clear oldTextSize;
Screen('TextColor', screenInfo.curWindow, [255 255 255]);
if strcmp(expInfo.timing, 'absolute')
flipWhen = Timing.RunInitiation+(indBlock)*expInfo.durBlockOnset+(indBlock-1)*expInfo.blockLengthDim*expInfo.trialDuration.all+(indBlock-1)*expInfo.durReward+(indTrial)*expInfo.trialDuration.all-(ifi/2);
elseif strcmp(expInfo.timing, 'relative') || strcmp(expInfo.timing, 'relativeITI')
flipWhen = Timing.ITIOnset+expInfo.durITI-(ifi/2);
end
Timing.FeedbackOnset = Screen('Flip', screenInfo.curWindow, flipWhen);
Timing.lastTiming = 'feedback';
ExperimentProtocol = [ExperimentProtocol; {'Feedback'}, {Timing.FeedbackOnset}, {[]}, {[]}, {[]}, {indRun}, {indBlock}, {[]}, {[]}];
if setup.ET.useET
Eyelink('Message', sprintf('Block %d Feedback', indBlock));
end
end % reward presentation
end % block presentation
%% do a break following the end of the run
Timing.PauseStart = GetSecs(); isterminated = 0;
ExperimentProtocol = [ExperimentProtocol; {'PauseStart'}, {Timing.PauseStart}, {[]}, {[]}, {[]}, {indRun},{indBlock}, {indTrial}, {[]}];
PauseInitiated = 0;
% save files to be safe
save(sessionFile, 'ExperimentProtocol', 'expInfo', 'ResultMat', 'DisplayInfo', 'setup');
if setup.EEG.useEEG
if setup.EEG.DIO.parallelTrigger == 1
% set to off state
putvalue(dio,0);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.PauseTrigger_128_01(indRun,:) = getvalue(dio);
% set to on state
putvalue(dio,128);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.PauseTrigger_128_11(indRun,:) = getvalue(dio);
% set to off state
putvalue(dio,0);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.PauseTrigger_128_02(indRun,:) = getvalue(dio);
end
end
while (GetSecs()-Timing.PauseStart) < expInfo.breakTime
if setup.ET.useET | setup.EEG.useEEG
%% ############### stop ET & EEG after 10 s ####################
if (GetSecs()-Timing.PauseStart) >= 10 && isterminated == 0
ExperimentProtocol = [ExperimentProtocol; {'RunEnd'}, {GetSecs()}, {[]}, {[]}, {[]},{indRun}, {indBlock}, {indTrial}, {[]}];
toc % end scanning
if setup.ET.useET && isfield(el,'vsn')
ET_terminate(el, setup.subjectsPath); % Save et data after each run
end
if setup.EEG.useEEG
%% send END parallelTrigger
if setup.EEG.DIO.parallelTrigger == 1
% first trigger
% set to off state
putvalue(dio,0);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.EndTrigger_6_01 = getvalue(dio);
% set to on state
putvalue(dio,6);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.EndTrigger_6_11 = getvalue(dio);
% set to off state
putvalue(dio,0);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.EndTrigger_6_02 = getvalue(dio);
% second trigger
% set to off state
putvalue(dio,0);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.EndTrigger_8_01 = getvalue(dio);
% set to on state
putvalue(dio,8);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.EndTrigger_8_11 = getvalue(dio);
% set to off state
putvalue(dio,0);
WaitSecs(setup.EEG.waitTrigEnc);
setup.EEG.DIO.EndTrigger_8_02 = getvalue(dio);
end
end
isterminated = 1;
end
% ####################################################################
end
% have the subject get ready for the next condition
pause(.1);
remain = expInfo.breakTime-round(GetSecs - Timing.PauseStart);
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
if indRun == expInfo.runAmount
DrawFormattedText(screenInfo.curWindow, ['Sie haben das Experiment beendet. \n\n Wir speichern nun Ihre Antworten.'], 'center', 'center');
if (GetSecs()-Timing.PauseStart) >= 15
break
end
elseif indRun<expInfo.runAmount & (setup.ET.useET | setup.EEG.useEEG) & (GetSecs()-Timing.PauseStart) >= 20
DrawFormattedText(screenInfo.curWindow, ['Pause: Es geht in ',num2str(remain),' Sekunden mit dem nchsten Block weiter. \n\n Sie knnen sich nun etwas ausruhen.'], 'center', 'center');
elseif indRun<expInfo.runAmount & (setup.ET.useET | setup.EEG.useEEG) & (GetSecs()-Timing.PauseStart)<20
DrawFormattedText(screenInfo.curWindow, ['Sie haben die Pause erreicht. \n\n Sie knnen sich nun etwas ausruhen.'], 'center', 'center');
else
DrawFormattedText(screenInfo.curWindow, ['Es geht in ',num2str(remain),' Sekunden mit dem nchsten Block weiter.'], 'center', 'center');
end
if PauseInitiated == 0 & strcmp(Timing.lastTiming, 'ITI')
flipWhen = Timing.ITIOnset+expInfo.durITI-(ifi/2);
elseif PauseInitiated == 0 & strcmp(Timing.lastTiming, 'feedback')
flipWhen = Timing.FeedbackOnset+expInfo.durReward-(ifi/2);
else
flipWhen = 0;
end
Screen('Flip', screenInfo.curWindow, flipWhen);
PauseInitiated = 1;
end
end % run presentation
Timing.sessEndTime = GetSecs;
ExperimentProtocol = [ExperimentProtocol; {'SessionEnd'}, {Timing.sessEndTime}, {[]}, {[]}, {[]},{[]}, {[]}, {[]}, {[]}];
save(sessionFile, 'ExperimentProtocol', 'expInfo', 'ResultMat', 'DisplayInfo', 'setup');
% % inform the subject that the experiment is over
% DrawFormattedText(screenInfo.curWindow, 'task complete!', 'center', 'center');
% Screen('Flip', screenInfo.curWindow);
% disp('Experimenter input required: MAT complete --> presentation offset');
% % wait for experimenter to close screen
% while true
% [exitKeyPressed, resumeKeyPressed] = checkKeys_byKeyB(expInfo, screenInfo.keyboard_exp);
% if exitKeyPressed || resumeKeyPressed
% break
% end
% end
shutdownStudy(el); % close drawing canvas
Screen('Preference', 'Verbosity', oldVerbosityLevel); % restore verbosity
catch exception
getReport(exception) % show stack trace
save(sessionFile);
shutdownStudy(el); % close drawing canvas
Priority(0);
end % TRY...CATCH
end % function
function shutdownStudy(el)
% if isfield(el,'vsn')
% ET_terminate(el);
% end
Screen('CloseAll');
ShowCursor;
Screen('Preference', 'SkipSyncTests', 0);
Screen('Preference', 'Verbosity', 3);
fprintf('\n');
end