Commit 7793d825 authored by Julian Kosciessa's avatar Julian Kosciessa
Browse files

updates for final EEG acquision YA; timestamp 170922

parent 3ce62a9f
......@@ -14,7 +14,9 @@
**/tmp*
**/study_information
**/raw
**/old
*.mat
*.zip
*.m~
*.xlsx
*.png
......
%_______________________________________________________________________
%
% Configuration for running dotsExperiment
%_______________________________________________________________________
%
% Output
%
% expInfo | configuration for state switch MAT (struct)
% Written by Julian Kosciessa (kosciessa@mpib-berlin.mpg.de)
% 170704 - incorporated thresholds
% 170809 - incorporated state dimensionality & accompanying
% randomization changes
% 170814 - introduce run format; adapted timing
% 170816 - changed to expInfo format; fixed randomization
% 170823 - changed randomization to account for switch probability
% 170829 - included RT feedback
% 170911 - altered timing, added postcuefix
% 170922 - changed difficulty
function expInfo = StateSwitch_createExpInfo_dynamic_170922
expInfo.trialsPerAtt = 16; % number of trials within state order & attribute (half of this for each choice)
expInfo.numOfAtt = 4; % number of attributes to be included
expInfo.numOrders = 4;
expInfo.totalTrials = expInfo.trialsPerAtt*expInfo.numOfAtt*expInfo.numOrders;
%expInfo.runAmount = 4; % number of runs; each run should have each category x times
expInfo.durBlockOnset = 5; % duration of block onset
expInfo.durFixCue = 1; % duration of fixcross with cues
expInfo.durCue = 0; % duration of cue
expInfo.durPostCueFix = 2; % duration of postcue fixation interval
expInfo.durPres = 3; % duration of presentation
expInfo.durResp = 2; % duration of question
expInfo.durConf = 0; % duration of confidence
expInfo.durITI = 1.5; % duration of ITI
expInfo.durReward = 3; % duration of reward
%expInfo.timing = 'relativeITI';
expInfo.timing = 'absolute';
expInfo.cuetype = 'woWord';
expInfo.trialDuration.all = expInfo.durFixCue+expInfo.durPostCueFix+expInfo.durPres+expInfo.durResp+expInfo.durConf+expInfo.durITI;
expInfo.trialDuration.FixCue = expInfo.durFixCue;
expInfo.trialDuration.PostCueFix = expInfo.durFixCue+expInfo.durPostCueFix;
expInfo.trialDuration.Pres = expInfo.durFixCue+expInfo.durPostCueFix+expInfo.durPres;
expInfo.trialDuration.Resp = expInfo.durFixCue+expInfo.durPostCueFix+expInfo.durPres+expInfo.durResp;
expInfo.trialDuration.Conf = expInfo.durFixCue+expInfo.durPostCueFix+expInfo.durPres+expInfo.durResp+expInfo.durConf;
expInfo.confOptions = '2'; % 2 or 4 confidence options
expInfo.highlightChoice = 1; % highlight choice by retaining only chosen option?
expInfo.feedback = 0; % no feedback
expInfo.dirSet = [180, 0]; % dots in left or right direction
expInfo.numDotField = 1; % show a single dot patches on screen
expInfo.apXYD = [0 0 130]; % coordinates and diameter of aperture
expInfo.speed = [50]; % speed of dot motion
expInfo.trialtype = [2 1 1]; % reaction time, not relevant, keyboard
expInfo.dotSize = 3; % dot size in pixels
expInfo.maxDotTime = 2; % maximum duration of moving dots
expInfo.fixXY = [0 0]; % fixation coordinates
expInfo.fixDiam = 2; % fixation diameter
expInfo.fixColor = [0 150 200]; % blue fixation dot
expInfo.fixMinTime = 0.75; % minimum fixation
expInfo.fixMaxTime = 1.25; % maximum fixation
%expInfo.maxDotsPerFrame = 300; % depends on graphics card
expInfo.fixTime = 2; % JQK: fixed onset fixation time
expInfo.DotsPerFrame = 48*3;
expInfo.breakTime = 60; % pause for 60 seconds between runs
% update frequency of on-screen content
expInfo.Hz_RDM = 30; % kinematogram updates in Hz
% multi-attribute task
expInfo.MAT.percAtt1H = .60;
expInfo.MAT.percAtt2H = .20;
expInfo.MAT.percAtt3H = .65;
expInfo.MAT.percAtt4H = .60;
expInfo.MAT.percAtt1L = 1-expInfo.MAT.percAtt1H;
expInfo.MAT.percAtt2L = 1-expInfo.MAT.percAtt2H;
expInfo.MAT.percAtt3L = 1-expInfo.MAT.percAtt3H;
expInfo.MAT.percAtt4L = 1-expInfo.MAT.percAtt4H;
%expInfo.MAT.color = [255 255 255; 255 0 0]; % define dot color
%expInfo.MAT.color = [177,213,57; 234,35,93]; % define dot color
% saturated & muted
% expInfo.MAT.color = [174,205,96; 203,117,143];
% expInfo.MAT.color1 = [174,205,96; 203,117,143]; % define dot color
% expInfo.MAT.color2 = [177,213,57; 234,35,93]; % green first, then red
expInfo.MAT.color = [192,255,128; 255,128,149];
expInfo.MAT.color1 = [192,255,128; 255,128,149]; % low luminance % green first, then red (H:350, S:40%, V:100%);% define dot color (H:350, S:80%, V:100%; green: H:90)
expInfo.MAT.color2 = [128,255,0; 255,0,43]; % high luminance
% % light & dark
% expInfo.MAT.color = [222,235,151; 241,147,186];
% expInfo.MAT.color1 = [222,235,151; 241,147,186]; % define dot color
% expInfo.MAT.color2 = [125,155,64; 160,26,67];
%
expInfo.MAT.coherence = expInfo.MAT.percAtt2H; % define dot movement (coherence)
expInfo.MAT.direction = [180 0]; % left and right
expInfo.MAT.size = [5 8]; % define dot size
expInfo.MAT.saturation = [1,2]; % define dot luminance
expInfo.MAT.attNames = {'color'; 'direction'; 'size'; 'saturation'};
expInfo.MAT.attNamesDE = {'Farbe'; 'Richtung'; 'Gre'; 'Sttigung'};
%% feedback
expInfo.RTfeedback.reward = 20;
expInfo.RTfeedback.loss = 0;
expInfo.RTfeedback.slack = .2; % seconds allowed below median RT
expInfo.RTfeedback.type = 'fixed'; % 'fixed' vs. 'RT'
expInfo.RTfeedback.fixedFeedback = [ones(1,25), zeros(1,7)];
expInfo.RTfeedback.fixedFeedback = expInfo.RTfeedback.fixedFeedback(randperm(32));
expInfo.RTfeedback.fixedFeedback = reshape(expInfo.RTfeedback.fixedFeedback, [], 4)';
%% specify keys
% Use OS X keyboard naming scheme across all plattforms
% Otherwise LeftControl/RightControl are not recognized
KbName('UnifyKeyNames');
expInfo.keyLeft = [KbName('LeftControl'), KbName('LeftAlt'), KbName('LeftArrow'), KbName('1!'),KbName('2@')]; % left response
expInfo.keyRight = [KbName('RightControl'), KbName('RightAlt'), KbName('RightArrow'),KbName('6^'),KbName('7&')]; % right response
expInfo.keyConf1 = [KbName('LeftControl'), KbName('LeftArrow'), KbName('1!')]; % lowest confidence
expInfo.keyConf2 = [KbName('LeftAlt'), KbName('2@')]; % intermediate confidence low
expInfo.keyConf3 = [KbName('RightAlt'),KbName('6^')]; % intermediate confidence high
expInfo.keyConf4 = [KbName('RightControl'), KbName('RightArrow'),KbName('7&')]; % highest confidence
expInfo.keyModifier = KbName('LeftAlt'); % to prevent accidental input
expInfo.keyEscape = KbName('Escape'); %
expInfo.keyReturn = [KbName('Return'), KbName('7&')]; % continue experiment
expInfo.keyPause = KbName('p');
%% randomize stimuli and non-target duration
% set random seed
rseed = sum(100*clock);
rng(rseed,'twister');
[expInfo.rngSetting] = rng;
%% Here we need to decide the following settings:
% 1. How many attribute dimensions (i.e. state manipulation)? [block-wise to avoid 'meta-four state']
% 2. Which attributes to be chosen? Same in each block?
% 3. Which target in each trial?
% 4. Which option of the attribute is winning?
%% decide cueing state order (1/2/3/4) & higher probability choice (within attribute)
expInfo.blockLengthDim = 8; % amount of consecutive trials belonging to the same state dimension block; needs to be a multiple of 4
expInfo.blockAmount = (expInfo.trialsPerAtt*expInfo.numOfAtt*expInfo.numOrders)/expInfo.blockLengthDim; % amount of blocks (i.e. determined by total trial count and block length)
expInfo.blocksPerOrd = expInfo.blockAmount/expInfo.numOrders; % amount of blocks per state dimension
expInfo.StateOrder = NaN(expInfo.blockAmount, expInfo.blockLengthDim); % prelim. matrix for state dimension order
expInfo.AttCues = cell(expInfo.blockAmount, expInfo.blockLengthDim); % prelim. cell struc for attribute cues
expInfo.targetAtt = NaN(expInfo.blockAmount, expInfo.blockLengthDim); % prelim. matrix for target attribute
expInfo.targetOption = NaN(expInfo.blockAmount, expInfo.blockLengthDim); % prelim. matrix for target option
expInfo.HighProbChoice = cell(expInfo.blockAmount, expInfo.blockLengthDim); % prelim. cell struc for winning options
expInfo.blockTime = expInfo.durBlockOnset+expInfo.blockLengthDim*...
(expInfo.durCue+expInfo.durPres+expInfo.durResp+expInfo.durConf+expInfo.durReward+expInfo.durITI);
% get amounts of runs to achieve approx. 10 min per run
%expInfo.runAmount = ceil(expInfo.blockAmount*expInfo.blockTime/60/10);
expInfo.runAmount = expInfo.blocksPerOrd/2; % now 4 runs! rather go for many runs vs. not including many breaks
expInfo.blocksPerRun = 8;
% Pseudo-randomize the block order, i.e. allowing for repeting dimension blocks.
% This is performed run-wise, such that each run contains a single
% block of each state order. We also make sure that there are no
% adjacent repeats of dimension blocks.
criterion = 0;
while criterion == 0
allCombsBlocks = perms([1,2,3,4]);
chosenBlockOrders = randperm(size(allCombsBlocks,1),expInfo.blocksPerRun); % have two dimension blocks each iteration
blockDimOrder = reshape(allCombsBlocks(chosenBlockOrders,:)',[],1);
if min(abs(diff(blockDimOrder))) ~= 0 % check that there are no repeats
criterion = 1;
end
end
expInfo.StateOrder = repmat(blockDimOrder,1,expInfo.blockLengthDim); % final state order output for presentation
% blockDimOrder = repmat(1:4,1,16); tmp_rand = randperm(expInfo.blockAmount);
% blockDimOrder = blockDimOrder(tmp_rand);
% expInfo.StateOrder = repmat(blockDimOrder', 1, expInfo.blockLengthDim); % final state order output for presentation
% get combinatorials for attribute cues for each dimension order
for indOrd = 1:expInfo.numOrders
combsDim{indOrd} = nchoosek([1:expInfo.numOfAtt], indOrd); % 4, 6, 4, 1
end
for indOrd = 1:expInfo.numOrders
tmp_blocks = find(blockDimOrder == indOrd);
tmp_blockCues = repmat(combsDim{indOrd},floor(numel(tmp_blocks)/size(combsDim{indOrd},1)),1);
if indOrd == 2 % there are 6 options, hence add two more; important: add all attributes 1-4!
tmp_blockCues = [tmp_blockCues; combsDim{indOrd}(1,:); combsDim{indOrd}(end,:)];
end
rand.blockCues(indOrd,:) = randperm(size(tmp_blockCues,1));
for indBlock = 1:numel(tmp_blocks)
expInfo.AttCues(tmp_blocks(indBlock),:) = {tmp_blockCues(rand.blockCues(indOrd,indBlock),:)}; % encode attribute cues
end
end
%% determine target attribute
% The logic here is the following: We now have blocks, in which the
% same state order and the same attribute targets are presented. Now,
% wihtin those attribute options, but across blocks, we choose trials
% such that each target attribute will occur the same number of times
% within-order (but not necessarily within-cue combination or block).
% Then we also choose half of the target attribute trials randomly and
% allocate them to the target option (i.e. red/white), such that these
% are also matched in amount within-attribute. The target attribute
% matching is done based on the groups of cue conjunctions.
% Note that the current procedure does no make sure, that e.g. every
% option occurs within each cue block.
indCatch = [];
for indOrd = 1:4
disp(num2str(indOrd));
Splits = [];
% for all attributes, get location of the dimension trials among all trials
% trial attributes are assigned among these
for indAtt = 1:4
index = cellfun(@(x) ismember(indAtt,x), expInfo.AttCues(blockDimOrder==indOrd,:), 'UniformOutput', 0);
indCatch{indOrd, indAtt} = find(cell2mat(index));
end
if indOrd == 1
idxCurrentOrder = find(expInfo.StateOrder == indOrd); % indexes trials of current state order
[row, ~] = ind2sub(size(expInfo.targetAtt),idxCurrentOrder); row = unique(row);
expInfo.targetAtt(row,:) = repmat(cell2mat(expInfo.AttCues(row,1)),1,8);
end
if indOrd == 2
Splits{1} = intersect(indCatch{indOrd, 1}, indCatch{indOrd, 2}); % 1 1 0 0
Splits{2} = intersect(indCatch{indOrd, 2}, indCatch{indOrd, 3}); % 0 1 1 0
Splits{3} = intersect(indCatch{indOrd, 2}, indCatch{indOrd, 4}); % 0 1 0 1
Splits{4} = intersect(indCatch{indOrd, 3}, indCatch{indOrd, 4}); % 0 0 1 1
Splits{5} = intersect(indCatch{indOrd, 1}, indCatch{indOrd, 3}); % 1 0 1 0
Splits{6} = intersect(indCatch{indOrd, 1}, indCatch{indOrd, 4}); % 1 0 0 1
extractMat = [1 1 0 0; 0 1 1 0; 0 1 0 1; 0 0 1 1; 1 0 1 0; 1 0 0 1];
end
if indOrd == 3
Splits{1} = intersect(intersect(indCatch{indOrd, 1}, indCatch{indOrd, 2}), indCatch{indOrd, 3}); % 1 2 1 0
Splits{2} = intersect(intersect(indCatch{indOrd, 2}, indCatch{indOrd, 3}), indCatch{indOrd, 4}); % 0 1 2 1
Splits{3} = intersect(intersect(indCatch{indOrd, 1}, indCatch{indOrd, 3}), indCatch{indOrd, 4}); % 1 0 1 2
Splits{4} = intersect(intersect(indCatch{indOrd, 1}, indCatch{indOrd, 2}), indCatch{indOrd, 4}); % 2 1 0 1
% split into four groups to distribute (unequally)
extractMat = [1,2,1,0; 0,1,2,1; 1,0,1,2; 2,1,0,1]; % amount of quartets to be extracted; row: triplet, column: attribute
% Note that due to the fixed allocation, there will always be
% an imbalance of the attributes within each cue condition.
end % 3 state dimension
if indOrd == 4
splitVec = [1:64/4:numel(indCatch{indOrd, 1}), 65]; % create artificial splits to help pseudo-randomisation
for indSplit = 1:4
selectTrials = sub2ind(size(expInfo.AttCues(blockDimOrder==indOrd,:)), ...
[repmat(((indSplit-1)*2+1),8,1); repmat(((indSplit-1)*2+2),8,1)], [1:8, 1:8]');
Splits{indSplit} = selectTrials;
extractMat = [1,1,1,1; 1,1,1,1; 1,1,1,1; 1,1,1,1];
end;
end
%% fix switch probability & select attribute targets
if ismember(indOrd, [2:4])
for indSplit = 1:numel(Splits)
check = 0;
while check == 0 % try to find pseudo-randomization that works
try
% pseudo-randomize to start block with no-switch
% have a maximum of 3 repetitions (i.e. 4 identical trials)
while check == 0
switchVec = [zeros(1,.5*numel(Splits{indSplit})),ones(1,.5*numel(Splits{indSplit}))];
switchVec_rand = randperm(numel(switchVec));
switchVec = switchVec(switchVec_rand);
% check for repetitions
A = switchVec';
J = find(diff([A(1)-1; A]));
if max(diff([J; numel(A)+1])) <= 3 & A(1:8:end)==0
check = 1;
end
end
% fill with attributes:
% sequential allocation without replacement
% start with most numerous option
if indOrd == 4
availableOptions = repelem([1:4], 4.*extractMat(indSplit,:));
mostCommon = find(extractMat(indSplit,:)==1);
mostCommon = mostCommon(1);
elseif indOrd == 3
availableOptions = repelem([1:4], 4.*extractMat(indSplit,:));
mostCommon = find(extractMat(indSplit,:)==2);
elseif indOrd == 2
availableOptions = repelem([1:4], numel(Splits{indSplit})/2.*extractMat(indSplit,:));
mostCommon = find(extractMat(indSplit,:)==1);
mostCommon = mostCommon(1);
end
tmp_availableCats = unique(availableOptions);
switchVec_atts = NaN(1,numel(availableOptions));
for indTrial = 1:numel(switchVec)
if switchVec(indTrial) == 0 & indTrial == 1
switchVec_atts(indTrial) = mostCommon;
elseif switchVec(indTrial) == 0
switchVec_atts(indTrial) = switchVec_atts(indTrial-1);
elseif switchVec(indTrial) == 1
lastAnwer = switchVec_atts(indTrial-1);
nextItem = find(tmp_availableCats>lastAnwer);
if isempty(nextItem)
nextItem = tmp_availableCats(1);
else nextItem = tmp_availableCats(nextItem(1));
end
switchVec_atts(indTrial) = nextItem;
end
% remove last encoded from list (i.e. choose without replacement)
tmp_cur = find(availableOptions == switchVec_atts(indTrial));
availableOptions(tmp_cur(1)) = [];
end
catch % if randomization does not work out, start again ...
check = 0;
end % try
end % while
% randomize order of chunks within each block
tmp_randBlocks = reshape(switchVec_atts,8,[])';
for rowInd = 1:size(tmp_randBlocks,1)
tmp_split = SplitVec(tmp_randBlocks(rowInd,:));
tmp_split_length = sort(SplitVec(tmp_randBlocks(rowInd,:), 'equal','length'),'ascend');
check = 0;
while check == 0 % make sure nothing changes to the number of chunks
tmp_split2 = tmp_split(randperm(numel(tmp_split)));
tmp_split2_length = sort(SplitVec([cell2mat(tmp_split2)], 'equal','length'),'ascend');
if isequal(tmp_split_length, tmp_split2_length)
check = 1;
tmp_randBlocks(rowInd,:) = [cell2mat(tmp_split2)];
end
end
end
% allocate attributes to trials
idxCurrentOrder = find(expInfo.StateOrder == indOrd); % indexes trials of current state order
[row, ~] = ind2sub(size(expInfo.targetAtt),idxCurrentOrder(Splits{indSplit}));
row = unique(row);
expInfo.targetAtt(row,:) = tmp_randBlocks;
end % split loop
end
%% determine target choice
% for each attribute, randomize within-order, which option will be the winner
for indAttribute = 1:4
idxCurrentOrder = find(expInfo.StateOrder == indOrd);
tmp_curTrials = find(expInfo.targetAtt(idxCurrentOrder) == indAttribute);
tmp_curTrialsPerm = reshape(tmp_curTrials(randperm(numel(tmp_curTrials))),2,[]);
expInfo.targetOption(idxCurrentOrder(tmp_curTrialsPerm(1,:))) = 1;
expInfo.targetOption(idxCurrentOrder(tmp_curTrialsPerm(2,:))) = 2;
end; clear tmp*
end % state order loop
%% make sure that each block has all cue options occuring
% This would mess up the transition probability slightly, but it is
% rare that a correction is necessary anyways.
check = zeros(size(expInfo.targetAtt,1),2); % index, whether block fulfills requirements
while min(check(:,1)) == 0 % while matching is not done, go through all blocks again
for indBlock = 1:size(expInfo.targetAtt,1)
% check whether all cued trials are available
TransProb.cuedOptions = expInfo.AttCues{indBlock,1};
while check(indBlock,1) == 0
TransProb.availOptions = unique(expInfo.targetAtt(indBlock,:));
TransProb.missingOptions = setdiff(TransProb.cuedOptions, TransProb.availOptions);
if isempty(TransProb.missingOptions) % all options available
check(indBlock,1) = 1;
else % not all options available
disp('Not all options occur. Readjusting ...')
warning('You should re-check transition probabilities.')
check(indBlock,1) = 0;
% exchange most frequent option with another trial
% sort available options in their order of frequency
[tmp_histn,~]=histcounts(expInfo.targetAtt(indBlock,:));
[~, tmp_sort_histn] = sort(tmp_histn(tmp_histn~=0), 'descend');
TransProb.availOptions = TransProb.availOptions(tmp_sort_histn);
% get trials of current state order (only exchange within
% order!!!) & missing attribute
TransProb.relevantTrials = expInfo.StateOrder == expInfo.StateOrder(indBlock,1) & expInfo.targetAtt == TransProb.missingOptions(1);
% buffer targetAtt & targetOption of the to-be-swapped trials
TransProb.tAttGo_avail = find(expInfo.targetAtt(indBlock,:)==TransProb.availOptions(1));
TransProb.tAttGoIdx = TransProb.tAttGo_avail(randperm(numel(TransProb.tAttGo_avail),1));
TransProb.tAttGoIdx = sub2ind(size(expInfo.targetAtt), indBlock, TransProb.tAttGoIdx); % convert to linear index
TransProb.tAttGoAtt = expInfo.targetAtt(TransProb.tAttGoIdx);
TransProb.tAttGoOpt = expInfo.targetOption(TransProb.tAttGoIdx);
TransProb.tAttGet_avail = find(TransProb.relevantTrials);
TransProb.tAttGetIdx = TransProb.tAttGet_avail(randperm(numel(TransProb.tAttGet_avail),1));
TransProb.tAttGetAtt = expInfo.targetAtt(TransProb.tAttGetIdx);
TransProb.tAttGetOpt = expInfo.targetOption(TransProb.tAttGetIdx);
% do the switch
expInfo.targetAtt(TransProb.tAttGoIdx) = TransProb.tAttGetAtt;
expInfo.targetAtt(TransProb.tAttGetIdx) = TransProb.tAttGoAtt;
expInfo.targetOption(TransProb.tAttGoIdx) = TransProb.tAttGetOpt;
expInfo.targetOption(TransProb.tAttGetIdx) = TransProb.tAttGoOpt;
end
end
end
end; clear TransProb tmp*;
% figure; subplot(1,2,1); imagesc(expInfo.targetAtt); subplot(1,2,2); imagesc(expInfo.StateOrder);
%% sanity check transition probability, number of presented attributes
for indDim = 1:4
idxCurrentOrder = find(expInfo.StateOrder(:,1) == indDim);
idxCurrentOrder_mat = find(expInfo.StateOrder == indDim);
% check number of presented attributes
for indAtt = 1:4
PresentedAttNum(indDim, indAtt) = numel(find(expInfo.targetAtt(idxCurrentOrder,:)==indAtt));
PresentedAttNum_low(indDim, indAtt) = numel(find(expInfo.targetOption(idxCurrentOrder_mat(expInfo.targetAtt(idxCurrentOrder,:)==indAtt))==1));
PresentedAttNum_high(indDim, indAtt) = numel(find(expInfo.targetOption(idxCurrentOrder_mat(expInfo.targetAtt(idxCurrentOrder,:)==indAtt))==2));
end
% check switching probability
SwitchProb_no(indDim) = numel(find(abs(diff([expInfo.targetAtt(idxCurrentOrder,1), expInfo.targetAtt(idxCurrentOrder,:)],[],2))==0));
SwitchProb_yes(indDim) = numel(find(abs(diff([expInfo.targetAtt(idxCurrentOrder,1), expInfo.targetAtt(idxCurrentOrder,:)],[],2))> 0));
end
[PresentedAttNum, [NaN; NaN; NaN; NaN], PresentedAttNum_low,[NaN; NaN; NaN; NaN], PresentedAttNum_high, [NaN; NaN; NaN; NaN], SwitchProb_no', SwitchProb_yes']
%% select parameters of remaining attributes one each trial
% these are chosen such that within each dimension and attribute, all
% other parameter constellations are presented (i.e. the 16 combinations
% should be presented in each category of the design)
combs = allcomb([1,2],[1,2],[1,2],[1,2]); % Note that 1 & 2 refer to the higher/lower prob option here.
% The target option is always already fixed as done above. This leaves
% eight remaining combinations for each multi-attribute display that
% should be allocated within-order, within-target-attribute.
% 1. get current state dim order
% 2. get current attribute
% 3. get high/low option
% 4. distribute the remaining categories
for indOrd = 1:4
for indAtt = 1:4
for indChoice = 1:2
idxCurrentOrder_l1 = find(expInfo.StateOrder == indOrd); % indexes trials of current state order
idxCurrentAtt_l2 = find(expInfo.targetAtt(idxCurrentOrder_l1) == indAtt);
indCurrentChoice_l3 = find(expInfo.targetOption(idxCurrentOrder_l1(idxCurrentAtt_l2)) == indChoice);
indCombined = idxCurrentOrder_l1(idxCurrentAtt_l2(indCurrentChoice_l3));
% get combinations with current parameters (regarding target attribute & choice)
curCombs = combs(combs(:,indAtt)==indChoice,:);
% randomize trials
indRecomb = indCombined(randperm(numel(indCombined)));
% repeat to match amount of trials
curCombs = repmat(curCombs, numel(indRecomb)/size(curCombs,1),1);
for indTrial = 1:numel(indRecomb)
indTargetTrial = indRecomb(indTrial);
expInfo.HighProbChoice{indTargetTrial} = curCombs(indTrial,:);
end
end % choice
end % attribute
end % order
% %% get random ITIs
% % range from 1.5s to 3s
%
% ITIoptions = [1.5, 1.75, 2.25, 2.5];
% ITIoptions = [.645*2, .645*3, .645*4];
%
% runITIs = repmat(ITIoptions,64/numel(ITIoptions),1);
%
%% put everything into block wrappers
edges = 1:expInfo.blocksPerRun:32+1;
for indRun = 1:expInfo.runAmount
expInfo.StateOrderRun{indRun} = expInfo.StateOrder(edges(indRun):edges(indRun+1)-1,:);
expInfo.AttCuesRun{indRun} = expInfo.AttCues(edges(indRun):edges(indRun+1)-1,:);
expInfo.targetAttRun{indRun} = expInfo.targetAtt(edges(indRun):edges(indRun+1)-1,:);
expInfo.targetOptionRun{indRun} = expInfo.targetOption(edges(indRun):edges(indRun+1)-1,:);
expInfo.HighProbChoiceRun{indRun} = expInfo.HighProbChoice(edges(indRun):edges(indRun+1)-1,:);
end
end
%_______________________________________________________________________
%
% Configuration for running dotsExperiment
% Note that this is the configuration script for a single attribute during
% the training/psychophysics phase of the experiment.
% JQK July 2017 (kosciessa@mpib-berlin.mpg.de)
%_______________________________________________________________________
%
% Output
%
% expInfo | configuration for random dots experiment (struct)
%
% Input
%
% PM - palmenides structure for adaptive psychophysics
%_______________________________________________________________________
%
% 170706 - added fixation color to blue
% - added fields required by presentation
% 170823 - changed randomization to account for switch probability
% 170829 - included RT feedback
% 170911 - altered timing, added postcuefix
function expInfo = StateSwitch_createExpInfo_dynamic_TEST_170922(dim)
expInfo.trialsPerAtt = 16; % number of trials within state order & attribute (half of this for each choice)
expInfo.numOfAtt = 4; % number of attributes to be included
expInfo.numOrders = 4;
expInfo.totalTrials = expInfo.trialsPerAtt*expInfo.numOfAtt*expInfo.numOrders;
expInfo.durBlockOnset = 5; % duration of block onset
expInfo.durFixCue = 1; % duration of fixcross with cues
expInfo.durCue = 0; % duration of cue
expInfo.durPostCueFix = 2; % duration of postcue fixation interval
expInfo.durPres = 3; % duration of presentation
expInfo.durResp = 2; % duration of question
if dim == 5
expInfo.durConf = 0;
else
expInfo.durConf = 0; % duration of confidence
end
expInfo.durReward = 0; % duration of reward [has to be zero during confidence for now]
expInfo.durITI = 1.5; % duration of ITI
if dim ~= 5
expInfo.feedback = 1;
expInfo.cuetype = '';
else expInfo.feedback = 0;
expInfo.cuetype = 'woWord';
end
expInfo.timing = 'relativeITI';
expInfo.trialDuration.all = expInfo.durFixCue+expInfo.durPostCueFix+expInfo.durPres+expInfo.durResp+expInfo.durConf+expInfo.durITI;
expInfo.trialDuration