|
| 1 | +function [expParameters] = expDesign(expParameters, displayFigs) |
| 2 | +% Creates the sequence of blocks and the events in them |
| 3 | +% |
| 4 | +% The conditions are consecutive static and motion blocks (Gives better results than randomised). |
| 5 | +% |
| 6 | +% It can be run as a stand alone without inputs to display a visual example of possible design. |
| 7 | +% |
| 8 | +% EVENTS |
| 9 | +% The numEventsPerBlock should be a multiple of the number of "base" |
| 10 | +% listed in the motionDirections and staticDirections (4 at the moment). |
| 11 | +% |
| 12 | +% |
| 13 | +% TARGETS: |
| 14 | +% If there are 2 targets per block we make sure that they are at least 2 |
| 15 | +% events apart. |
| 16 | +% Targets cannot be on the first or last event of a block |
| 17 | +% |
| 18 | +% Input: |
| 19 | +% - ExpParameters: parameters returned by SetParameters |
| 20 | +% - displayFigs: a boolean to decide whether to show the basic design |
| 21 | +% matrix of the design |
| 22 | +% |
| 23 | +% Output: |
| 24 | +% - ExpParameters.designBlockNames = cell array (nr_blocks, 1) with the |
| 25 | +% name for each block |
| 26 | +% |
| 27 | +% - ExpParameters.designDirections = array (nr_blocks, numEventsPerBlock) |
| 28 | +% with the direction to present in a given block |
| 29 | +% - 0 90 180 270 indicate the angle |
| 30 | +% - -1 indicates static |
| 31 | +% |
| 32 | +% - ExpParameters.designSpeeds = array (nr_blocks, numEventsPerBlock) * speedEvent |
| 33 | +% |
| 34 | +% - ExpParameters.designFixationTargets = array (nr_blocks, numEventsPerBlock) |
| 35 | +% showing for each event if it should be accompanied by a target |
| 36 | +% |
| 37 | + |
| 38 | +% needed to use the randsample function in octave |
| 39 | +if IsOctave |
| 40 | + pkg load statistics |
| 41 | +end |
| 42 | + |
| 43 | +% Set directions for static and motion condition |
| 44 | +motionDirections = [0 90 180 270]; |
| 45 | +staticDirections = [-1 -1 -1 -1]; |
| 46 | + |
| 47 | + |
| 48 | +%% Check inputs |
| 49 | + |
| 50 | +% Set variables here for a dummy test of this function |
| 51 | +if nargin < 1 || isempty(expParameters) |
| 52 | + expParameters.names = {'static', 'motion'}; |
| 53 | + expParameters.numRepetitions = 4; |
| 54 | + expParameters.speedEvent = 4; |
| 55 | + expParameters.numEventsPerBlock = 12; |
| 56 | + expParameters.maxNumFixationTargetPerBlock = 2; |
| 57 | +end |
| 58 | + |
| 59 | +% Set to 1 for a visualtion of the trials design order |
| 60 | +if nargin < 2 || isempty(displayFigs) |
| 61 | + displayFigs = 0; |
| 62 | +end |
| 63 | + |
| 64 | +% Get the parameters |
| 65 | +names = expParameters.names; |
| 66 | +numRepetitions = expParameters.numRepetitions; |
| 67 | +speedEvent = expParameters.speedEvent; |
| 68 | +numEventsPerBlock = expParameters.numEventsPerBlock; |
| 69 | +maxNumFixTargPerBlock = expParameters.maxNumFixationTargetPerBlock; |
| 70 | + |
| 71 | +if mod(numEventsPerBlock, length(motionDirections))~=0 |
| 72 | + warning('the number of events per block is not a multiple of the number of motion/static diection') |
| 73 | +end |
| 74 | + |
| 75 | + |
| 76 | +%% Adapt some variables according to input |
| 77 | + |
| 78 | +% Set directions for static and motion condition |
| 79 | +motionDirections = repmat(motionDirections, 1, numEventsPerBlock/length(motionDirections)); |
| 80 | +staticDirections = repmat(staticDirections, 1, numEventsPerBlock/length(staticDirections)); |
| 81 | + |
| 82 | +% Assign the conditions |
| 83 | +condition = repmat(names, 1, numRepetitions); |
| 84 | +nrBlocks = length(condition); |
| 85 | +% Get the index of each condition |
| 86 | +staticIndex = find( strcmp(condition, 'static') ); |
| 87 | +motionIndex = find( strcmp(condition, 'motion') ); |
| 88 | + |
| 89 | + |
| 90 | +% Assign the targets for each condition |
| 91 | +rangeTargets = [1 maxNumFixTargPerBlock]; |
| 92 | +% Get random number of targets for one condition |
| 93 | +targetPerCondition = randi(rangeTargets, 1, numRepetitions); |
| 94 | +% Assign the number of targets for each condition after shuffling |
| 95 | +numTargets = zeros(1, nrBlocks); |
| 96 | +numTargets(staticIndex) = Shuffle(targetPerCondition); |
| 97 | +numTargets(motionIndex) = Shuffle(targetPerCondition); |
| 98 | + |
| 99 | + |
| 100 | +%% Give the blocks the names with condition |
| 101 | + |
| 102 | +expParameters.designBlockNames = cell(nrBlocks, 1); |
| 103 | +expParameters.designDirections = zeros(nrBlocks, numEventsPerBlock); |
| 104 | +expParameters.designSpeeds = ones(nrBlocks, numEventsPerBlock) * speedEvent; |
| 105 | +expParameters.designFixationTargets = zeros(nrBlocks, numEventsPerBlock); |
| 106 | + |
| 107 | +for iMotionBlock = 1:numRepetitions |
| 108 | + |
| 109 | + expParameters.designDirections( motionIndex(iMotionBlock), :) = Shuffle(motionDirections); |
| 110 | + expParameters.designDirections( staticIndex(iMotionBlock), :) = Shuffle(staticDirections); |
| 111 | + |
| 112 | +end |
| 113 | + |
| 114 | +for iBlock = 1:nrBlocks |
| 115 | + |
| 116 | + % Set block name |
| 117 | + switch condition{iBlock} |
| 118 | + case 'static' |
| 119 | + thisBlockName = {'static'}; |
| 120 | + case 'motion' |
| 121 | + thisBlockName = {'motion'}; |
| 122 | + end |
| 123 | + expParameters.designBlockNames(iBlock) = thisBlockName; |
| 124 | + |
| 125 | + |
| 126 | + % set target |
| 127 | + % if there are 2 targets per block we make sure that they are at least |
| 128 | + % 2 events apart |
| 129 | + % targets cannot be on the first or last event of a block |
| 130 | + |
| 131 | + chosenTarget = []; |
| 132 | + |
| 133 | + tmpTarget = numTargets(iBlock); |
| 134 | + |
| 135 | + switch tmpTarget |
| 136 | + |
| 137 | + case 1 |
| 138 | + |
| 139 | + chosenTarget = randsample(2:numEventsPerBlock-1, tmpTarget, false); |
| 140 | + |
| 141 | + case 2 |
| 142 | + |
| 143 | + targetDifference = 0; |
| 144 | + |
| 145 | + while targetDifference <= 2 |
| 146 | + chosenTarget = randsample(2:numEventsPerBlock-1, tmpTarget, false); |
| 147 | + targetDifference = (max(chosenTarget) - min(chosenTarget)); |
| 148 | + end |
| 149 | + |
| 150 | + end |
| 151 | + |
| 152 | + expParameters.designFixationTargets(iBlock, chosenTarget) = 1; |
| 153 | + |
| 154 | +end |
| 155 | + |
| 156 | + |
| 157 | +%% Visualize the design matrix |
| 158 | +if displayFigs |
| 159 | + |
| 160 | + uniqueNames = unique(expParameters.designBlockNames) ; |
| 161 | + |
| 162 | + Ind = zeros(length(expParameters.designBlockNames), length(uniqueNames)) ; |
| 163 | + |
| 164 | + for i = 1:length(uniqueNames) |
| 165 | + CondInd(:,i) = find(strcmp(expParameters.designBlockNames, uniqueNames{i})) ; %#ok<*AGROW> |
| 166 | + Ind(CondInd(:,i), i) = 1 ; |
| 167 | + end |
| 168 | + |
| 169 | + imagesc(Ind) |
| 170 | + |
| 171 | + set(gca, ... |
| 172 | + 'XTick',1:length(uniqueNames),... |
| 173 | + 'XTickLabel', uniqueNames) |
| 174 | + |
| 175 | +end |
0 commit comments