|
22 | 22 | % TARGETS |
23 | 23 | % |
24 | 24 | % Pseudorandomization rules: |
25 | | - % (1) If there are 2 targets per block we make sure that they are at least 2 |
| 25 | + % (1) If there are more than 1 target per block we make sure that they are at least 2 |
26 | 26 | % events apart. |
27 | 27 | % (2) Targets cannot be on the first or last event of a block. |
28 | | - % (3) Targets can not be present more than 2 times in the same event |
| 28 | + % (3) Targets can not be present more than NB_REPETITIONS - 1 times in the same event |
29 | 29 | % position across blocks. |
30 | 30 | % |
31 | 31 | % Input: |
|
57 | 57 |
|
58 | 58 | % Set variables here for a dummy test of this function |
59 | 59 | if nargin < 1 || isempty(cfg) |
60 | | - error('give me something to work with') |
| 60 | + error('give me something to work with'); |
61 | 61 | end |
62 | | - |
63 | | - fprintf('\n\nCreating design.\n\n') |
| 62 | + |
| 63 | + fprintf('\n\nCreating design.\n\n'); |
64 | 64 |
|
65 | 65 | [NB_BLOCKS, NB_REPETITIONS, NB_EVENTS_PER_BLOCK, MAX_TARGET_PER_BLOCK] = getInput(cfg); |
66 | 66 | [~, STATIC_INDEX, MOTION_INDEX] = assignConditions(cfg); |
67 | 67 |
|
68 | | - RANGE_TARGETS = [1 MAX_TARGET_PER_BLOCK]; |
69 | | - targetPerCondition = repmat(RANGE_TARGETS, 1, NB_REPETITIONS / 2); |
| 68 | + if mod(NB_REPETITIONS, MAX_TARGET_PER_BLOCK) ~= 0 |
| 69 | + error('number of repetitions must be a multiple of max number of targets'); |
| 70 | + end |
| 71 | + |
| 72 | + RANGE_TARGETS = 1:MAX_TARGET_PER_BLOCK; |
| 73 | + targetPerCondition = repmat(RANGE_TARGETS, 1, NB_REPETITIONS / MAX_TARGET_PER_BLOCK); |
70 | 74 |
|
71 | 75 | numTargetsForEachBlock = zeros(1, NB_BLOCKS); |
72 | 76 | numTargetsForEachBlock(STATIC_INDEX) = shuffle(targetPerCondition); |
|
85 | 89 | % - targets cannot be on the first or last event of a block |
86 | 90 | % - no more than 2 target in the same event order |
87 | 91 |
|
88 | | - chosenTarget = []; |
89 | | - |
90 | | - tmpTarget = numTargetsForEachBlock(iBlock); |
91 | | - |
92 | | - switch tmpTarget |
93 | | - |
94 | | - case 1 |
95 | | - |
96 | | - chosenTarget = randsample(2:NB_EVENTS_PER_BLOCK - 1, tmpTarget, false); |
97 | | - |
98 | | - case 2 |
99 | | - |
100 | | - targetDifference = 0; |
101 | | - |
102 | | - while abs(targetDifference) <= 2 |
103 | | - chosenTarget = randsample(2:NB_EVENTS_PER_BLOCK - 1, tmpTarget, false); |
104 | | - targetDifference = diff(chosenTarget); |
105 | | - end |
| 92 | + nbTarget = numTargetsForEachBlock(iBlock); |
106 | 93 |
|
107 | | - end |
| 94 | + chosenPosition = setTargetPositionInSequence( ... |
| 95 | + NB_EVENTS_PER_BLOCK, ... |
| 96 | + nbTarget, ... |
| 97 | + [1 NB_EVENTS_PER_BLOCK]); |
108 | 98 |
|
109 | | - fixationTargets(iBlock, chosenTarget) = 1; |
| 99 | + fixationTargets(iBlock, chosenPosition) = 1; |
110 | 100 |
|
111 | 101 | end |
112 | 102 |
|
113 | 103 | % Check rule 3 |
114 | | - if max(sum(fixationTargets)) < 3 |
| 104 | + if max(sum(fixationTargets)) < NB_REPETITIONS - 1 |
115 | 105 | break |
116 | 106 | end |
117 | 107 |
|
|
150 | 140 | directions = zeros(NB_BLOCKS, NB_EVENTS_PER_BLOCK); |
151 | 141 |
|
152 | 142 | % Create a vector for the static condition |
| 143 | + NB_REPEATS_BASE_VECTOR = NB_EVENTS_PER_BLOCK / length(STATIC_DIRECTIONS); |
| 144 | + |
153 | 145 | static_directions = repmat( ... |
154 | 146 | STATIC_DIRECTIONS, ... |
155 | | - 1, NB_EVENTS_PER_BLOCK / length(STATIC_DIRECTIONS)); |
| 147 | + 1, NB_REPEATS_BASE_VECTOR); |
156 | 148 |
|
157 | 149 | for iMotionBlock = 1:NB_REPETITIONS |
158 | 150 |
|
159 | | - % Check that we never have twice the same direction |
160 | | - while 1 |
161 | | - tmp = [ ... |
162 | | - shuffle(MOTION_DIRECTIONS), ... |
163 | | - shuffle(MOTION_DIRECTIONS), ... |
164 | | - shuffle(MOTION_DIRECTIONS)]; |
165 | | - |
166 | | - if ~any(diff(tmp, [], 2) == 0) |
167 | | - break |
168 | | - end |
169 | | - end |
170 | | - |
171 | 151 | % Set motion direction and static order |
172 | | - directions(MOTION_INDEX(iMotionBlock), :) = tmp; |
| 152 | + directions(MOTION_INDEX(iMotionBlock), :) = ... |
| 153 | + repeatShuffleConditions(MOTION_DIRECTIONS, NB_REPEATS_BASE_VECTOR); |
173 | 154 | directions(STATIC_INDEX(iMotionBlock), :) = static_directions; |
174 | 155 |
|
175 | 156 | end |
|
183 | 164 | % CONSTANTS |
184 | 165 | % Set directions for static and motion condition |
185 | 166 |
|
186 | | - STATIC_DIRECTIONS = [-1 -1 -1 -1]; |
187 | | - |
188 | | - switch cfg.design.motionType |
189 | | - case 'translation' |
190 | | - MOTION_DIRECTIONS = [0 0 180 180]; |
191 | | - case 'radial' |
192 | | - STATIC_DIRECTIONS = [666 -666 666 -666]; |
193 | | - MOTION_DIRECTIONS = [666 -666 666 -666]; |
194 | | - end |
| 167 | + MOTION_DIRECTIONS = cfg.design.motionDirections; |
| 168 | + STATIC_DIRECTIONS = repmat(-1, size(MOTION_DIRECTIONS)); |
195 | 169 |
|
196 | 170 | end |
197 | 171 |
|
|
202 | 176 | nbBlocks = length(cfg.design.names) * nbRepet; |
203 | 177 | end |
204 | 178 |
|
205 | | -function [condition, STATIC_INDEX, MOTION_INDEX] = assignConditions(cfg) |
| 179 | +function [conditionNamesVector, STATIC_INDEX, MOTION_INDEX] = assignConditions(cfg) |
206 | 180 |
|
207 | 181 | [~, nbRepet] = getInput(cfg); |
208 | 182 |
|
209 | | - condition = repmat(cfg.design.names, nbRepet, 1); |
| 183 | + conditionNamesVector = repmat(cfg.design.names, nbRepet, 1); |
210 | 184 |
|
211 | 185 | % Get the index of each condition |
212 | | - STATIC_INDEX = find(strcmp(condition, 'static')); |
213 | | - MOTION_INDEX = find(strcmp(condition, 'motion')); |
214 | | - |
215 | | -end |
| 186 | + STATIC_INDEX = find(strcmp(conditionNamesVector, 'static')); |
| 187 | + MOTION_INDEX = find(strcmp(conditionNamesVector, 'motion')); |
216 | 188 |
|
217 | | -function shuffled = shuffle(unshuffled) |
218 | | - % in case PTB is not in the path |
219 | | - try |
220 | | - shuffled = Shuffle(unshuffled); |
221 | | - catch |
222 | | - shuffled = unshuffled(randperm(length(unshuffled))); |
223 | | - end |
224 | 189 | end |
225 | 190 |
|
226 | 191 | function diplayDesign(cfg, displayFigs) |
|
0 commit comments