Skip to content

Commit c02eaa0

Browse files
committed
Merge remote-tracking branch 'cpp-lln-lab/master'
2 parents 451d1ad + 536fdd8 commit c02eaa0

File tree

7 files changed

+114
-96
lines changed

7 files changed

+114
-96
lines changed

collectAndSaveResponses.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
responseEvents(iResp).onset - experimentStart;
1010
end
1111

12-
responseEvents.fileID = logFile.fileID;
13-
responseEvents.extraColumns = logFile.extraColumns;
12+
responseEvents(1).fileID = logFile.fileID;
13+
responseEvents(1).extraColumns = logFile.extraColumns;
1414
saveEventsFile('save', cfg, responseEvents);
1515

1616
end

getExperimentStart.m

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
function cfg = getExperimentStart(cfg)
2-
% Show the fixation cross
2+
% cfg = getExperimentStart(cfg)
3+
%
4+
% Stores the onset time in cfg.experimentStart
5+
36
drawFixation(cfg);
47
vbl = Screen('Flip', cfg.screen.win);
58
cfg.experimentStart = vbl;
9+
610
end

src/aperture/apertureTexture.m

Lines changed: 93 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,21 @@
11
function [cfg, thisEvent] = apertureTexture(action, cfg, thisEvent)
2-
3-
transparent = [0 0 0 0];
2+
% [cfg, thisEvent] = apertureTexture(action, cfg, thisEvent)
3+
%
4+
%
45

56
switch action
67

78
case 'init'
89

9-
switch cfg.aperture.type
10-
11-
case 'circle'
12-
% we take the screen height as maximum aperture width if not
13-
% specified.
14-
if ~isfield(cfg.aperture, 'width') || isempty(cfg.aperture.width)
15-
cfg.aperture.width = cfg.screen.winRect(4) / cfg.screen.ppd;
16-
end
17-
cfg.aperture = degToPix('width', cfg.aperture, cfg);
18-
19-
case 'ring'
20-
21-
% Set parameters for rings
22-
if strcmp(cfg.aperture.type, 'ring')
23-
% scale of outer ring (exceeding screen until
24-
% inner ring reaches window boarder)
25-
cfg.ring.maxEcc = ...
26-
cfg.screen.FOV / 2 + ...
27-
cfg.aperture.width + ...
28-
log(cfg.screen.FOV / 2 + 1) ;
29-
% ring.CsFuncFact is used to expand with log increasing speed so
30-
% that ring is at ring.maxEcc at end of cycle
31-
cfg.ring.csFuncFact = ...
32-
1 / ...
33-
((cfg.ring.maxEcc + exp(1)) * ...
34-
log(cfg.ring.maxEcc + exp(1)) - ...
35-
(cfg.ring.maxEcc + exp(1))) ;
36-
end
37-
end
10+
cfg = apertureInit(cfg);
3811

3912
cfg.aperture.texture = Screen('MakeTexture', cfg.screen.win, ...
4013
cfg.color.background(1) * ones(cfg.screen.winRect([4 3])));
4114

4215
case 'make'
4316

17+
transparent = [0, 0, 0, 0];
18+
4419
xCenter = cfg.screen.center(1);
4520
yCenter = cfg.screen.center(2);
4621

@@ -62,7 +37,7 @@
6237
end
6338

6439
Screen('FillOval', cfg.aperture.texture, transparent, ...
65-
CenterRectOnPoint([0 0 repmat(diameter, 1, 2)], ...
40+
CenterRectOnPoint([0, 0, repmat(diameter, 1, 2)], ...
6641
xCenter, yCenter));
6742

6843
case 'ring'
@@ -74,12 +49,12 @@
7449

7550
Screen('FillOval', cfg.aperture.texture, transparent, ...
7651
CenterRectOnPoint( ...
77-
[0 0 repmat(cfg.ring.outerRimPix, 1, 2)], ...
52+
[0, 0, repmat(cfg.ring.outerRimPix, 1, 2)], ...
7853
xCenter, yCenter));
7954

8055
Screen('FillOval', cfg.aperture.texture, [cfg.color.background 255], ...
8156
CenterRectOnPoint( ...
82-
[0 0 repmat(cfg.ring.innerRimPix, 1, 2)], ...
57+
[0, 0, repmat(cfg.ring.innerRimPix, 1, 2)], ...
8358
xCenter, yCenter));
8459

8560
case 'wedge'
@@ -104,11 +79,33 @@
10479

10580
Screen('FillArc', cfg.aperture.texture, transparent, ...
10681
CenterRect( ...
107-
[0 0 repmat(cfg.stimRect(4), 1, 2)], ...
82+
[0, 0, repmat(cfg.stimRect(4), 1, 2)], ...
10883
cfg.screen.winRect), ...
10984
thisEvent.angle, ... % start angle
11085
cfg.aperture.width); % arc angle
11186

87+
case 'bar'
88+
89+
% aperture is the color of the background
90+
Screen('FillRect', cfg.aperture.texture, cfg.color.background);
91+
92+
% We let the stimulus through
93+
Screen('FillOval', cfg.aperture.texture, transparent, ...
94+
CenterRect([0, 0, repmat(cfg.stimRect(3), 1, 2)], cfg.screen.winRect));
95+
96+
% Then we add the position of the bar aperture
97+
Screen('FillRect', cfg.aperture.texture, cfg.color.background, ...
98+
[0, ...
99+
0, ...
100+
thisEvent.barPosPix - cfg.aperture.barWidthPix / 2, ...
101+
cfg.screen.winRect(4)]);
102+
103+
Screen('FillRect', cfg.aperture.texture, cfg.color.background, ...
104+
[thisEvent.barPosPix + cfg.aperture.barWidthPix / 2, ...
105+
0, ...
106+
cfg.screen.winRect(3), ...
107+
cfg.screen.winRect(4)]);
108+
112109
otherwise
113110

114111
error('unknown aperture type: %s.', cfg.aperture.type);
@@ -117,10 +114,68 @@
117114

118115
case 'draw'
119116

120-
Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture);
117+
if strcmp(cfg.aperture.type, 'bar')
118+
119+
% Draw aperture and we rotate to match the required condition
120+
Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture, ...
121+
cfg.screen.winRect, ...
122+
cfg.screen.winRect, ...
123+
thisEvent.condition - 90);
124+
else
125+
126+
Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture);
127+
128+
end
129+
130+
end
131+
132+
end
133+
134+
function cfg = apertureInit(cfg)
135+
136+
switch cfg.aperture.type
137+
138+
case 'circle'
139+
% we take the screen height as maximum aperture width if not
140+
% specified.
141+
if ~isfield(cfg.aperture, 'width') || isempty(cfg.aperture.width)
142+
cfg.aperture.width = cfg.screen.winRect(4) / cfg.screen.ppd;
143+
end
144+
cfg.aperture = degToPix('width', cfg.aperture, cfg);
145+
146+
case 'ring'
147+
148+
% Set parameters for rings
149+
if strcmp(cfg.aperture.type, 'ring')
150+
% scale of outer ring (exceeding screen until
151+
% inner ring reaches window boarder)
152+
cfg.ring.maxEcc = ...
153+
cfg.screen.FOV / 2 + ...
154+
cfg.aperture.width + ...
155+
log(cfg.screen.FOV / 2 + 1) ;
156+
% ring.CsFuncFact is used to expand with log increasing speed so
157+
% that ring is at ring.maxEcc at end of cycle
158+
cfg.ring.csFuncFact = ...
159+
1 / ...
160+
((cfg.ring.maxEcc + exp(1)) * ...
161+
log(cfg.ring.maxEcc + exp(1)) - ...
162+
(cfg.ring.maxEcc + exp(1))) ;
163+
end
164+
165+
case 'bar'
166+
167+
% Set parameters drifting bars
168+
cfg.aperture.barWidthPix = cfg.stimRect(3) / cfg.volsPerCycle;
169+
cfg.aperture.barPosPix = ...
170+
[0:cfg.aperture.barWidthPix:cfg.stimRect(3) - cfg.aperture.barWidthPix] + ...
171+
(cfg.screen.winRect(3) / 2 - cfg.stimRect(3) / 2) + ...
172+
cfg.aperture.barWidthPix / 2; %#ok<NBRAK>
121173

122-
% Screen('DrawTexture', cfg.screen.win, apertureTexture, ...
123-
% cfg.screen.winRect, cfg.screen.winRect, current.apertureAngle - 90);
174+
% Width of bar in degrees of VA (needed for saving)
175+
cfg.aperture.width = cfg.aperture.barWidthPix / cfg.screen.ppd;
176+
cfg.aperture.barPos = ...
177+
(cfg.aperture.barPosPix - cfg.screen.center(1)) / ...
178+
cfg.screen.ppd;
124179

125180
end
126181

tests/runTests.m

Lines changed: 0 additions & 53 deletions
This file was deleted.

tests/test_computeRadialMotionDirection.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ function test_computeRadialMotionDirectionBasic()
1111
%% set up
1212

1313
cfg.design.motionType = 'radial';
14+
cfg.dot.matrixWidth = 50; % in pixels
1415
cfg.screen.winWidth = 100; % in pixels
1516
direction = 666;
1617

tests/test_initDots.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ function test_initDotsBasic()
2626
cfg.dot.number = 10;
2727
cfg.dot.coherence = 1; % proportion
2828
cfg.dot.lifeTime = 0.250; % in seconds
29+
cfg.dot.matrixWidth = 50; % in pixels
2930
cfg.screen.winWidth = 2000; % in pixels
3031
cfg.eventDuration = 1; % in seconds
3132
cfg.screen.ifi = 0.01; % in seconds
@@ -61,6 +62,7 @@ function test_initDotsStatic()
6162
cfg.dot.number = 10;
6263
cfg.dot.coherence = 1; % proportion
6364
cfg.dot.lifeTime = 0.250; % in seconds
65+
cfg.dot.matrixWidth = 50; % in pixels
6466
cfg.screen.winWidth = 2000; % in pixels
6567
cfg.eventDuration = 1; % in seconds
6668
cfg.screen.ifi = 0.01; % in seconds
@@ -90,6 +92,7 @@ function test_initDotsRadial()
9092
cfg.dot.number = 10;
9193
cfg.dot.coherence = 1; % proportion
9294
cfg.dot.lifeTime = 0.250; % in seconds
95+
cfg.dot.matrixWidth = 50; % in pixels
9396
cfg.screen.winWidth = 2000; % in pixels
9497
cfg.eventDuration = 1; % in seconds
9598
cfg.screen.ifi = 0.01; % in seconds

tests/test_reseedDots.m

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,24 @@
88

99
function test_reseedDotsBasic()
1010

11-
dots.lifeTime = 100;
1211
cfg.screen.winWidth = 2000;
12+
13+
cfg.design.motionType = 'radial';
14+
15+
cfg.dot.matrixWidth = 50; % in pixels
1316
cfg.dot.number = 5;
1417
cfg.dot.sizePix = 20;
1518
cfg.dot.proportionKilledPerFrame = 0;
1619

1720
cfg.fixation.widthPix = 20;
1821

22+
dots.lifeTime = 100;
23+
dots.speedPixPerFrame = 3;
24+
dots.direction = 90;
25+
dots.isSignal = true(5, 1);
26+
1927
dots.positions = [ ...
20-
694, 100; % OK
28+
49, 1; % OK
2129
490, 2043; % out of frame
2230
-104, 392; % out of frame
2331
492, 402; % OK

0 commit comments

Comments
 (0)