From 84a1f8e27d5b5c4cbab1df2104f850bd91a82a7c Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Mon, 3 Aug 2020 07:55:55 +0200 Subject: [PATCH 1/5] mh autofix --- setParameters.m | 8 +-- subfun/expDesign.m | 165 ++++++++++++++++++++++----------------------- 2 files changed, 86 insertions(+), 87 deletions(-) diff --git a/setParameters.m b/setParameters.m index b4b031d..2d6133b 100644 --- a/setParameters.m +++ b/setParameters.m @@ -11,7 +11,7 @@ 'output'); %% Debug mode settings - + cfg.debug.do = true; % To test the script out of the scanner, skip PTB sync cfg.debug.smallWin = false; % To test on a part of the screen, change to 1 cfg.debug.transpWin = true; % To test with trasparent full size screen @@ -39,7 +39,7 @@ cfg.design.nbEventsPerBlock = 12; % DO NOT CHANGE %% Timing - + % Time between blocs in secs cfg.IBI = .5; % 8; % Time between events in secs @@ -50,7 +50,7 @@ cfg.endDelay = .1; cfg.eventDuration = 1; % second - + %% Visual Stimulation % Speed in visual angles / second @@ -92,7 +92,7 @@ cfg.target.duration = 0.05; % In secs cfg.extraColumns = {'direction', 'speed', 'target', 'event', 'block'}; - + end function cfg = setKeyboards(cfg) diff --git a/subfun/expDesign.m b/subfun/expDesign.m index fec3ffd..46dd1fb 100644 --- a/subfun/expDesign.m +++ b/subfun/expDesign.m @@ -1,11 +1,14 @@ function [cfg] = expDesign(cfg, displayFigs) % Creates the sequence of blocks and the events in them % - % The conditions are consecutive static and motion blocks (Gives better results than randomised). + % The conditions are consecutive static and motion blocks + % (Gives better results than randomised). % % EVENTS % The numEventsPerBlock should be a multiple of the number of "base" - % listed in the motionDirections and staticDirections (4 at the moment). + % listed in the MOTION_DIRECTIONS and STATIC_DIRECTIONS (4 at the moment). + % MOTION_DIRECTIONS = [0 90 180 270]; + % STATIC_DIRECTIONS = [-1 -1 -1 -1]; % % Pseudorandomization rules: % (1) Directions are all present in random orders in `numEventsPerBlock/nDirections` @@ -42,15 +45,14 @@ % - cfg.designFixationTargets = array (nr_blocks, numEventsPerBlock) % showing for each event if it should be accompanied by a target % - - + %% Check inputs - + % Set to 1 for a visualtion of the trials design order if nargin < 2 || isempty(displayFigs) displayFigs = 0; end - + % Set variables here for a dummy test of this function if nargin < 1 || isempty(cfg) cfg.design.names = {'static'; 'motion'}; @@ -60,125 +62,124 @@ cfg.target.maxNbPerBlock = 2; displayFigs = 1; end - + [NB_BLOCKS, NB_REPETITIONS, NB_EVENTS_PER_BLOCK, MAX_TARGET_PER_BLOCK] = getInput(cfg); - [~, staticIndex, motionIndex] = assignConditions(cfg); - + [~, STATIC_INDEX, motionIndex] = assignConditions(cfg); + RANGE_TARGETS = [1 MAX_TARGET_PER_BLOCK]; - targetPerCondition = repmat(RANGE_TARGETS, 1, NB_REPETITIONS/2); - + targetPerCondition = repmat(RANGE_TARGETS, 1, NB_REPETITIONS / 2); + numTargetsForEachBlock = zeros(1, NB_BLOCKS); - numTargetsForEachBlock(staticIndex) = shuffle(targetPerCondition); - numTargetsForEachBlock(motionIndex) = shuffle(targetPerCondition); - + numTargetsForEachBlock(STATIC_INDEX) = shuffle(targetPerCondition); + numTargetsForEachBlock(MOTION_INDEX) = shuffle(targetPerCondition); + %% Give the blocks the names with condition and design the task in each event while 1 - + fixationTargets = zeros(NB_BLOCKS, NB_EVENTS_PER_BLOCK); - + for iBlock = 1:NB_BLOCKS - + % Set target % - if there are 2 targets per block we make sure that they are at least % 2 events apart % - targets cannot be on the first or last event of a block % - no more than 2 target in the same event order - + chosenTarget = []; - + tmpTarget = numTargetsForEachBlock(iBlock); - + switch tmpTarget - + case 1 - + chosenTarget = randsample(2:NB_EVENTS_PER_BLOCK - 1, tmpTarget, false); - + case 2 - + targetDifference = 0; - + while any(targetDifference <= 2) chosenTarget = randsample(2:NB_EVENTS_PER_BLOCK - 1, tmpTarget, false); targetDifference = diff(chosenTarget); end - + end - + fixationTargets(iBlock, chosenTarget) = 1; - + end - + % Check rule 3 if max(sum(fixationTargets)) < 3 break end - + end - + %% Now we do the easy stuff cfg.design.blockNames = assignConditions(cfg); - + cfg.design.nbBlocks = NB_BLOCKS; - + cfg = setDirections(cfg); - + speeds = ones(NB_BLOCKS, NB_EVENTS_PER_BLOCK) * cfg.dot.speedPixPerFrame; cfg.design.speeds = speeds; - + cfg.design.fixationTargets = fixationTargets; - %% Plot - diplayDesign(cfg, displayFigs) - + diplayDesign(cfg, displayFigs); + end function cfg = setDirections(cfg) - + % CONSTANTS % Set directions for static and motion condition MOTION_DIRECTIONS = [0 90 180 270]; STATIC_DIRECTIONS = [-1 -1 -1 -1]; - + [NB_BLOCKS, NB_REPETITIONS, NB_EVENTS_PER_BLOCK] = getInput(cfg); - - [~, staticIndex, motionIndex] = assignConditions(cfg); - + + [~, STATIC_INDEX, MOTION_INDEX] = assignConditions(cfg); + if mod(NB_EVENTS_PER_BLOCK, length(MOTION_DIRECTIONS)) ~= 0 error('Number of events/block not a multiple of number of motion/static direction'); end - + % initialize directions = zeros(NB_BLOCKS, NB_EVENTS_PER_BLOCK); - + % Create a vector for the static condition static_directions = repmat( ... STATIC_DIRECTIONS, ... 1, NB_EVENTS_PER_BLOCK / length(STATIC_DIRECTIONS)); - + for iMotionBlock = 1:NB_REPETITIONS - + % Check that we never have twice the same direction while 1 tmp = [ ... shuffle(MOTION_DIRECTIONS), ... shuffle(MOTION_DIRECTIONS), ... shuffle(MOTION_DIRECTIONS)]; - - if ~any(diff(tmp,[],2)==0) + + if ~any(diff(tmp, [], 2) == 0) break end end - + % Set motion direction and static order - directions(motionIndex(iMotionBlock), :) = tmp; - directions(staticIndex(iMotionBlock), :) = static_directions; - + directions(MOTION_INDEX(iMotionBlock), :) = tmp; + directions(STATIC_INDEX(iMotionBlock), :) = static_directions; + end - + cfg.design.directions = directions; - + end function [nbBlocks, nbRepet, nbEventsBlock, maxTargBlock] = getInput(cfg) @@ -188,16 +189,16 @@ nbBlocks = length(cfg.design.names) * nbRepet; end -function [condition, staticIndex, motionIndex] = assignConditions(cfg) - +function [condition, STATIC_INDEX, MOTION_INDEX] = assignConditions(cfg) + [~, nbRepet] = getInput(cfg); - + condition = repmat(cfg.design.names, nbRepet, 1); - + % Get the index of each condition - staticIndex = find(strcmp(condition, 'static')); - motionIndex = find(strcmp(condition, 'motion')); - + STATIC_INDEX = find(strcmp(condition, 'static')); + MOTION_INDEX = find(strcmp(condition, 'motion')); + end function shuffled = shuffle(unshuffled) @@ -210,67 +211,65 @@ end function diplayDesign(cfg, displayFigs) - + %% Visualize the design matrix if displayFigs - - close all + + close all; figure(1); - + % Shows blocks (static and motion) and events (motion direction) order directions = cfg.design.directions; directions(directions == -1) = -90; - + subplot(3, 1, 1); imagesc(directions); - + labelAxesBlock(); - + caxis([-90 - 37, 270 + 37]); myColorMap = lines(5); colormap(myColorMap); - + title('Block (static and motion) & Events (motion direction)'); - + % Shows the fixation targets design in each event (1 or 0) fixationTargets = cfg.design.fixationTargets; - + subplot(3, 1, 2); imagesc(fixationTargets); labelAxesBlock(); title('Fixation Targets design'); colormap(gray); - + % Shows the fixation targets position distribution in the block across % the experimet [~, itargetPosition] = find(fixationTargets == 1); - + subplot(3, 1, 3); hist(itargetPosition); labelAxesFreq(); title('Fixation Targets position distribution'); - - + figure(2); - + MOTION_DIRECTIONS = [0 90 180 270]; - + for iMotion = 1:length(MOTION_DIRECTIONS) - + [~, position] = find(directions == MOTION_DIRECTIONS(iMotion)); - + subplot(2, 2, iMotion); hist(position); scaleAxes(); labelAxesFreq(); title(num2str(MOTION_DIRECTIONS(iMotion))); - + end - end - + end function labelAxesBlock() From 4347a32d2ee2be0c298a3df40cad0e950e94273b Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Mon, 3 Aug 2020 17:06:37 +0200 Subject: [PATCH 2/5] prepare for radial motion --- initEnv.m | 1 + lib/CPP_BIDS | 2 +- lib/CPP_PTB | 2 +- setParameters.m | 11 +++++++---- subfun/expDesign.m | 39 +++++++++++++++++++++++++++++---------- 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/initEnv.m b/initEnv.m index 90560f8..e135df6 100644 --- a/initEnv.m +++ b/initEnv.m @@ -88,6 +88,7 @@ function addDependencies() pth = fileparts(mfilename('fullpath')); addpath(fullfile(pth, 'lib', 'CPP_BIDS', 'src')); addpath(fullfile(pth, 'lib', 'CPP_PTB')); + addpath(genpath(fullfile(pth, 'lib', 'CPP_PTB', 'src'))); addpath(fullfile(pth, 'subfun')); end diff --git a/lib/CPP_BIDS b/lib/CPP_BIDS index a17e12a..644689a 160000 --- a/lib/CPP_BIDS +++ b/lib/CPP_BIDS @@ -1 +1 @@ -Subproject commit a17e12a53c0063e36fb017b7a545d605e2c2ef8e +Subproject commit 644689aafba550721353194018746a6febc19374 diff --git a/lib/CPP_PTB b/lib/CPP_PTB index a8bc6b5..9578e80 160000 --- a/lib/CPP_PTB +++ b/lib/CPP_PTB @@ -1 +1 @@ -Subproject commit a8bc6b5a1457ad78b496fa89037c07f0e548e0c8 +Subproject commit 9578e80a8f281bee30dcbe2f2a30c48e50ecd416 diff --git a/setParameters.m b/setParameters.m index 2d6133b..b4a3a9b 100644 --- a/setParameters.m +++ b/setParameters.m @@ -34,6 +34,9 @@ %% Experiment Design +% cfg.design.motionType = 'translation'; +% cfg.design.motionType = 'radial'; + cfg.design.motionType = 'translation'; cfg.design.names = {'static'; 'motion'}; cfg.design.nbRepetitions = 4; cfg.design.nbEventsPerBlock = 12; % DO NOT CHANGE @@ -41,15 +44,15 @@ %% Timing % Time between blocs in secs - cfg.IBI = .5; % 8; + cfg.IBI = .1; % 8; % Time between events in secs - cfg.ISI = 0.5; + cfg.ISI = 0.1; % Number of seconds before the motion stimuli are presented cfg.onsetDelay = .1; % Number of seconds after the end all the stimuli before ending the run cfg.endDelay = .1; - cfg.eventDuration = 1; % second + cfg.eventDuration = 3; % second %% Visual Stimulation @@ -68,7 +71,7 @@ cfg.dot.color = cfg.color.white; % Diameter/length of side of aperture in Visual angles - cfg.aperture.type = 'circle'; + cfg.aperture.type = 'none'; cfg.aperture.width = []; % if left empty it will take the screen height cfg.aperture.xPos = 0; diff --git a/subfun/expDesign.m b/subfun/expDesign.m index 46dd1fb..4e4d0c9 100644 --- a/subfun/expDesign.m +++ b/subfun/expDesign.m @@ -4,6 +4,8 @@ % The conditions are consecutive static and motion blocks % (Gives better results than randomised). % + % Style guide: constants are in SNAKE_UPPER_CASE + % % EVENTS % The numEventsPerBlock should be a multiple of the number of "base" % listed in the MOTION_DIRECTIONS and STATIC_DIRECTIONS (4 at the moment). @@ -55,6 +57,8 @@ % Set variables here for a dummy test of this function if nargin < 1 || isempty(cfg) +% cfg.design.motionType = 'translation'; + cfg.design.motionType = 'radial'; cfg.design.names = {'static'; 'motion'}; cfg.design.nbRepetitions = 4; cfg.design.nbEventsPerBlock = 12; @@ -64,7 +68,7 @@ end [NB_BLOCKS, NB_REPETITIONS, NB_EVENTS_PER_BLOCK, MAX_TARGET_PER_BLOCK] = getInput(cfg); - [~, STATIC_INDEX, motionIndex] = assignConditions(cfg); + [~, STATIC_INDEX, MOTION_INDEX] = assignConditions(cfg); RANGE_TARGETS = [1 MAX_TARGET_PER_BLOCK]; targetPerCondition = repmat(RANGE_TARGETS, 1, NB_REPETITIONS / 2); @@ -137,10 +141,7 @@ function cfg = setDirections(cfg) - % CONSTANTS - % Set directions for static and motion condition - MOTION_DIRECTIONS = [0 90 180 270]; - STATIC_DIRECTIONS = [-1 -1 -1 -1]; + [MOTION_DIRECTIONS, STATIC_DIRECTIONS] = getDirectionBaseVectors(cfg); [NB_BLOCKS, NB_REPETITIONS, NB_EVENTS_PER_BLOCK] = getInput(cfg); @@ -182,6 +183,23 @@ end +function [MOTION_DIRECTIONS, STATIC_DIRECTIONS] = getDirectionBaseVectors(cfg) + + % CONSTANTS + % Set directions for static and motion condition + + STATIC_DIRECTIONS = [-1 -1 -1 -1]; + + switch cfg.design.motionType + case 'translation' + MOTION_DIRECTIONS = [0 90 180 270]; + case 'radial' + STATIC_DIRECTIONS = [666 -666 666 -666]; + MOTION_DIRECTIONS = [666 -666 666 -666]; + end + +end + function [nbBlocks, nbRepet, nbEventsBlock, maxTargBlock] = getInput(cfg) nbRepet = cfg.design.nbRepetitions; nbEventsBlock = cfg.design.nbEventsPerBlock; @@ -253,18 +271,19 @@ function diplayDesign(cfg, displayFigs) title('Fixation Targets position distribution'); figure(2); + + [motionDirections] = getDirectionBaseVectors(cfg); + motionDirections = unique(motionDirections); - MOTION_DIRECTIONS = [0 90 180 270]; - - for iMotion = 1:length(MOTION_DIRECTIONS) + for iMotion = 1:length(motionDirections) - [~, position] = find(directions == MOTION_DIRECTIONS(iMotion)); + [~, position] = find(directions == motionDirections(iMotion)); subplot(2, 2, iMotion); hist(position); scaleAxes(); labelAxesFreq(); - title(num2str(MOTION_DIRECTIONS(iMotion))); + title(num2str(motionDirections(iMotion))); end From d2cfcc7d468e026aee10a663fe51a76208933571 Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Mon, 3 Aug 2020 18:59:50 +0200 Subject: [PATCH 3/5] add submodule update and make it easier to decide on dot matix size --- lib/CPP_PTB | 2 +- subfun/doDotMo.m | 2 +- visualLocTanslational.m | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/CPP_PTB b/lib/CPP_PTB index 9578e80..ad07055 160000 --- a/lib/CPP_PTB +++ b/lib/CPP_PTB @@ -1 +1 @@ -Subproject commit 9578e80a8f281bee30dcbe2f2a30c48e50ecd416 +Subproject commit ad070555d15e0ff827bac72d094c1aeb2475a84d diff --git a/subfun/doDotMo.m b/subfun/doDotMo.m index 487741f..29b2067 100644 --- a/subfun/doDotMo.m +++ b/subfun/doDotMo.m @@ -33,7 +33,7 @@ % We assumed that zero is at the top left, but we want it to be % in the center, so shift the dots up and left, which just means % adding half of the screen width in pixel to both the x and y direction. - thisEvent.dot.positions = (dots.positions - cfg.screen.winWidth / 2)'; + thisEvent.dot.positions = (dots.positions - cfg.dot.matrixWidth / 2)'; %% make textures dotTexture('make', cfg, thisEvent); diff --git a/visualLocTanslational.m b/visualLocTanslational.m index 0c17f6a..e2d31f1 100644 --- a/visualLocTanslational.m +++ b/visualLocTanslational.m @@ -33,6 +33,8 @@ %% Init the experiment [cfg] = initPTB(cfg); + cfg.dot.matrixWidth = cfg.screen.winHeight; + % Convert some values from degrees to pixels cfg.dot = degToPix('size', cfg.dot, cfg); cfg.dot = degToPix('speed', cfg.dot, cfg); From cdd152866ad1452d7fa583dd62f39b26114afa8b Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Wed, 5 Aug 2020 13:00:31 +0200 Subject: [PATCH 4/5] update submodule and save info in json not .mat --- lib/CPP_BIDS | 2 +- setParameters.m | 2 +- visualLocTanslational.m | 12 ++---------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/CPP_BIDS b/lib/CPP_BIDS index 644689a..0c03781 160000 --- a/lib/CPP_BIDS +++ b/lib/CPP_BIDS @@ -1 +1 @@ -Subproject commit 644689aafba550721353194018746a6febc19374 +Subproject commit 0c03781dfc8190e1047530dd1a105f0f7e3a62c6 diff --git a/setParameters.m b/setParameters.m index b4a3a9b..1f69aeb 100644 --- a/setParameters.m +++ b/setParameters.m @@ -71,7 +71,7 @@ cfg.dot.color = cfg.color.white; % Diameter/length of side of aperture in Visual angles - cfg.aperture.type = 'none'; + cfg.aperture.type = 'circle'; cfg.aperture.width = []; % if left empty it will take the screen height cfg.aperture.xPos = 0; diff --git a/visualLocTanslational.m b/visualLocTanslational.m index e2d31f1..5f4881f 100644 --- a/visualLocTanslational.m +++ b/visualLocTanslational.m @@ -156,16 +156,8 @@ getResponse('release', cfg.keyboard.responseBox); eyeTracker('Shutdown', cfg); - - % save the whole workspace - matFile = fullfile( ... - cfg.dir.output, ... - strrep(cfg.fileName.events, 'tsv', 'mat')); - if IsOctave - save(matFile, '-mat7-binary'); - else - save(matFile, '-v7.3'); - end + + createBoldJson(cfg, cfg) farewellScreen(cfg); From e47b8d6a1e5563f8ef0891cdbd00919dff4b54ae Mon Sep 17 00:00:00 2001 From: Remi Gau Date: Wed, 5 Aug 2020 15:55:41 +0200 Subject: [PATCH 5/5] collect trigger in the same file as responses --- lib/CPP_BIDS | 2 +- lib/CPP_PTB | 2 +- setParameters.m | 18 +++++++---- visualLocTanslational.m | 68 ++++++++++++++++++++++++++++++----------- 4 files changed, 65 insertions(+), 25 deletions(-) diff --git a/lib/CPP_BIDS b/lib/CPP_BIDS index 0c03781..d2a4c43 160000 --- a/lib/CPP_BIDS +++ b/lib/CPP_BIDS @@ -1 +1 @@ -Subproject commit 0c03781dfc8190e1047530dd1a105f0f7e3a62c6 +Subproject commit d2a4c43725ec69a87afccd4a0ec39d800c5968a8 diff --git a/lib/CPP_PTB b/lib/CPP_PTB index ad07055..a0c8874 160000 --- a/lib/CPP_PTB +++ b/lib/CPP_PTB @@ -1 +1 @@ -Subproject commit ad070555d15e0ff827bac72d094c1aeb2475a84d +Subproject commit a0c8874fd7894a748758624d94d7b74f7e5c0252 diff --git a/setParameters.m b/setParameters.m index 1f69aeb..413ac19 100644 --- a/setParameters.m +++ b/setParameters.m @@ -42,9 +42,15 @@ cfg.design.nbEventsPerBlock = 12; % DO NOT CHANGE %% Timing + + % FOR 7T: if you want to create localizers on the fly, the following must be + % multiples of the scanneryour sequence TR + % + % IBI + % block length = (cfg.eventDuration + cfg.ISI) * cfg.design.nbEventsPerBlock % Time between blocs in secs - cfg.IBI = .1; % 8; + cfg.IBI = 1.8*3; % 8; % Time between events in secs cfg.ISI = 0.1; % Number of seconds before the motion stimuli are presented @@ -52,8 +58,8 @@ % Number of seconds after the end all the stimuli before ending the run cfg.endDelay = .1; - cfg.eventDuration = 3; % second - + cfg.eventDuration = 0.8; % second + %% Visual Stimulation % Speed in visual angles / second @@ -94,13 +100,13 @@ cfg.target.maxNbPerBlock = 2; cfg.target.duration = 0.05; % In secs - cfg.extraColumns = {'direction', 'speed', 'target', 'event', 'block'}; + cfg.extraColumns = {'direction', 'speed', 'target', 'event', 'block', 'keyName'}; end function cfg = setKeyboards(cfg) cfg.keyboard.escapeKey = 'ESCAPE'; - cfg.keyboard.responseKey = {'space'}; + cfg.keyboard.responseKey = {'space', 't'}; cfg.keyboard.keyboard = []; cfg.keyboard.responseBox = []; @@ -115,7 +121,7 @@ cfg.mri.triggerKey = 't'; cfg.mri.triggerNb = 4; - cfg.mri.repetitionTime = 2; + cfg.mri.repetitionTime = 1.8; cfg.bids.MRI.Instructions = 'Detect the RED fixation cross'; cfg.bids.MRI.TaskDescription = []; diff --git a/visualLocTanslational.m b/visualLocTanslational.m index 5f4881f..d50228a 100644 --- a/visualLocTanslational.m +++ b/visualLocTanslational.m @@ -46,7 +46,8 @@ % dots are displayed on a square with a length in visual angle equal to the % field of view - cfg.dot.number = round(cfg.dot.density * (cfg.screen.winWidth / cfg.screen.ppd)^2); + cfg.dot.number = round(cfg.dot.density * ... + (cfg.dot.matrixWidth / cfg.screen.ppd)^2); [el] = eyeTracker('Calibration', cfg); @@ -55,7 +56,7 @@ % Prepare for the output logfiles with all logFile.extraColumns = cfg.extraColumns; logFile = saveEventsFile('open', cfg, logFile); - + % prepare textures cfg = apertureTexture('init', cfg); cfg = dotTexture('init', cfg); @@ -101,6 +102,7 @@ thisEvent.event = iEvent; thisEvent.block = iBlock; + thisEvent.keyName = 'n/a'; thisEvent.duration = duration; thisEvent.onset = onset - cfg.experimentStart; @@ -115,32 +117,64 @@ % collect the responses and appends to the event structure for % saving in the tsv file - responseEvents = collectAndSaveResponses(cfg, logFile, cfg.experimentStart); - - responseEvents = getResponse('check', cfg.keyboard.responseBox, cfg, getOnlyPress); - + responseEvents = getResponse('check', cfg.keyboard.responseBox, cfg, ... + getOnlyPress); + if isfield(responseEvents(1), 'onset') && ~isempty(responseEvents(1).onset) - + for iResp = 1:size(responseEvents, 1) - - responseEvents(iResp).event = iEvent; - responseEvents(iResp).block = iBlock; + responseEvents(iResp).onset = ... + responseEvents(iResp).onset - cfg.experimentStart; + responseEvents(iResp).event = 'n/a'; + responseEvents(iResp).block = 'n/a'; + responseEvents(iResp).direction = 'n/a'; + responseEvents(iResp).speed = 'n/a'; + responseEvents(iResp).target = 'n/a'; + if strcmp(responseEvents(iResp).keyName, 't') + responseEvents(iResp).trial_type = 'trigger'; + end end - + + responseEvents(1).fileID = logFile.fileID; + responseEvents(1).extraColumns = logFile.extraColumns; saveEventsFile('save', cfg, responseEvents); - + end - + % wait for the inter-stimulus interval WaitSecs(cfg.ISI); - getResponse('flush', cfg.keyboard.responseBox); - end - + eyeTracker('StopRecordings', cfg); - + WaitSecs(cfg.IBI); + + % trigger monitoring + triggerEvents = getResponse('check', cfg.keyboard.responseBox, cfg, ... + getOnlyPress); + + if isfield(triggerEvents(1), 'onset') && ~isempty(triggerEvents(1).onset) + + for iResp = 1:size(triggerEvents, 1) + triggerEvents(iResp).onset = ... + triggerEvents(iResp).onset - cfg.experimentStart; + triggerEvents(iResp).event = 'n/a'; + triggerEvents(iResp).block = 'n/a'; + triggerEvents(iResp).direction = 'n/a'; + triggerEvents(iResp).speed = 'n/a'; + triggerEvents(iResp).target = 'n/a'; + if strcmp(triggerEvents(iResp).keyName, 't') + triggerEvents(iResp).trial_type = 'trigger-baseline'; + end + end + + triggerEvents(1).fileID = logFile.fileID; + triggerEvents(1).extraColumns = logFile.extraColumns; + saveEventsFile('save', cfg, triggerEvents); + + end + end