Skip to content

Commit a84abb3

Browse files
committed
add expDesign.m
1 parent 028ee6d commit a84abb3

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed

subfun/expDesign.m

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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

Comments
 (0)