Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 120 additions & 112 deletions src/aperture/apertureTexture.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,128 +10,29 @@
cfg = apertureInit(cfg);

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

case 'make'

TRANSPARENT = [0, 0, 0, 0];
cfg = apertureTextureMake(cfg, thisEvent);

xCenter = cfg.screen.center(1);
yCenter = cfg.screen.center(2);

switch cfg.aperture.type

case 'none'

Screen('Fillrect', cfg.aperture.texture, TRANSPARENT);

case 'circle'

diameter = cfg.aperture.widthPix;

if isfield(cfg.aperture, 'xPosPix')
xCenter = cfg.screen.center(1) + cfg.aperture.xPosPix;
end
if isfield(cfg.aperture, 'yPosPix')
yCenter = cfg.screen.center(2) + cfg.aperture.yPosPix;
end

Screen('FillOval', cfg.aperture.texture, TRANSPARENT, ...
CenterRectOnPoint([0, 0, repmat(diameter, 1, 2)], ...
xCenter, yCenter));

case 'ring'

% expansion speed is log over eccentricity
[cfg] = eccenLogSpeed(cfg, thisEvent.time);

Screen('Fillrect', cfg.aperture.texture, cfg.color.background);

Screen('FillOval', cfg.aperture.texture, TRANSPARENT, ...
CenterRectOnPoint( ...
[0, 0, repmat(cfg.ring.outerRimPix, 1, 2)], ...
xCenter, yCenter));

Screen('FillOval', cfg.aperture.texture, [cfg.color.background 255], ...
CenterRectOnPoint( ...
[0, 0, repmat(cfg.ring.innerRimPix, 1, 2)], ...
xCenter, yCenter));

case 'wedge'

cycleDuration = cfg.mri.repetitionTime * cfg.volsPerCycle;

% Update angle for rotation of background and for apperture for wedge
switch cfg.direction

case '+'
thisEvent.angle = 90 - ...
cfg.aperture.width / 2 + ...
(thisEvent.time / cycleDuration) * 360;
case '-'
thisEvent.angle = 90 - ...
cfg.aperture.width / 2 - ...
(thisEvent.time / cycleDuration) * 360;

end

Screen('Fillrect', cfg.aperture.texture, cfg.color.background);

Screen('FillArc', cfg.aperture.texture, TRANSPARENT, ...
CenterRect( ...
[0, 0, repmat(cfg.stimRect(4), 1, 2)], ...
cfg.screen.winRect), ...
thisEvent.angle, ... % start angle
cfg.aperture.width); % arc angle

case 'bar'

% aperture is the color of the background
Screen('FillRect', cfg.aperture.texture, cfg.color.background);

% We let the stimulus through
Screen('FillOval', cfg.aperture.texture, TRANSPARENT, ...
CenterRect([0, 0, repmat(cfg.stimRect(3), 1, 2)], cfg.screen.winRect));

% Then we add the position of the bar aperture

% which one is the right and which one is the left??

Screen('FillRect', cfg.aperture.texture, cfg.color.background, ...
[0, ...
0, ...
thisEvent.barPosPix - cfg.aperture.barWidthPix / 2, ...
cfg.screen.winRect(4)]);

Screen('FillRect', cfg.aperture.texture, cfg.color.background, ...
[thisEvent.barPosPix + cfg.aperture.barWidthPix / 2, ...
0, ...
cfg.screen.winRect(3), ...
cfg.screen.winRect(4)]);

otherwise

error('unknown aperture type: %s.', cfg.aperture.type);
case 'draw'

scalingFactor = 1;
if isfield(cfg, 'scalingFactor') && ~isempty(cfg.scalingFactor)
scalingFactor = cfg.scalingFactor;
end

case 'draw'

rotationAngle = [];
if strcmp(cfg.aperture.type, 'bar')

% Draw aperture and we rotate to match the required condition
Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture, ...
cfg.screen.winRect, ...
CenterRect( ...
cfg.screen.winRect, ...
cfg.screen.winRect), ...
thisEvent.condition - 90);
else

Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture);

rotationAngle = thisEvent.condition - 90;
end

Screen('DrawTexture', cfg.screen.win, cfg.aperture.texture, ...
cfg.screen.winRect, ...
CenterRect(cfg.screen.winRect * scalingFactor, cfg.screen.winRect), ...
rotationAngle);

end

end
Expand Down Expand Up @@ -188,3 +89,110 @@
end

end

function cfg = apertureTextureMake(cfg, thisEvent)

TRANSPARENT = [0, 0, 0, 0];

xCenter = cfg.screen.center(1);
yCenter = cfg.screen.center(2);

switch cfg.aperture.type

case 'none'

Screen('Fillrect', cfg.aperture.texture, TRANSPARENT);

case 'circle'

diameter = cfg.aperture.widthPix;

if isfield(cfg.aperture, 'xPosPix')
xCenter = xCenter + cfg.aperture.xPosPix;
end
if isfield(cfg.aperture, 'yPosPix')
yCenter = yCenter + cfg.aperture.yPosPix;
end

Screen('FillOval', cfg.aperture.texture, TRANSPARENT, ...
CenterRectOnPoint([0, 0, repmat(diameter, 1, 2)], ...
xCenter, yCenter));

case 'ring'

% expansion speed is log over eccentricity
[cfg] = eccenLogSpeed(cfg, thisEvent.time);

Screen('Fillrect', cfg.aperture.texture, cfg.color.background);

Screen('FillOval', cfg.aperture.texture, TRANSPARENT, ...
CenterRectOnPoint( ...
[0, 0, repmat(cfg.ring.outerRimPix, 1, 2)], ...
xCenter, yCenter));

Screen('FillOval', cfg.aperture.texture, [cfg.color.background 255], ...
CenterRectOnPoint( ...
[0, 0, repmat(cfg.ring.innerRimPix, 1, 2)], ...
xCenter, yCenter));

case 'wedge'

cycleDuration = cfg.mri.repetitionTime * cfg.volsPerCycle;

% Update angle for rotation of background and for apperture for wedge
switch cfg.direction

case '+'
thisEvent.angle = 90 - ...
cfg.aperture.width / 2 + ...
(thisEvent.time / cycleDuration) * 360;
case '-'
thisEvent.angle = 90 - ...
cfg.aperture.width / 2 - ...
(thisEvent.time / cycleDuration) * 360;

end

Screen('Fillrect', cfg.aperture.texture, cfg.color.background);

Screen('FillArc', cfg.aperture.texture, TRANSPARENT, ...
CenterRect( ...
cfg.destinationRect, ...
cfg.screen.winRect), ...
thisEvent.angle, ... % start angle
cfg.aperture.width); % arc angle

case 'bar'

% aperture is the color of the background
Screen('FillRect', cfg.aperture.texture, cfg.color.background);

% We let the stimulus through
Screen('FillOval', cfg.aperture.texture, TRANSPARENT, ...
CenterRect( ...
[0, 0, repmat(cfg.screen.winRect(4), 1, 2)], ...
cfg.screen.winRect));

% Then we add the position of the bar aperture

% which one is the right and which one is the left??

Screen('FillRect', cfg.aperture.texture, cfg.color.background, ...
[0, ...
0, ...
thisEvent.barPosPix - cfg.aperture.barWidthPix / 2, ...
cfg.screen.winRect(4)]);

Screen('FillRect', cfg.aperture.texture, cfg.color.background, ...
[thisEvent.barPosPix + cfg.aperture.barWidthPix / 2, ...
0, ...
cfg.screen.winRect(3), ...
cfg.screen.winRect(4)]);

otherwise

error('unknown aperture type: %s.', cfg.aperture.type);

end

end
7 changes: 5 additions & 2 deletions src/initPTB.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@

cfg = setDefaultsPTB(cfg);

Screen('Preference', 'SkipSyncTests', cfg.skipSyncTests);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! Thank you, @Remi-Gau


initKeyboard;
initDebug(cfg);

Expand Down Expand Up @@ -120,10 +122,11 @@
function initDebug(cfg)

% init PTB with different options in concordance to the debug Parameters
Screen('Preference', 'SkipSyncTests', 0);

if cfg.debug.do

Screen('Preference', 'SkipSyncTests', 2);
cfg.skipSyncTests = 2;
Screen('Preference', 'SkipSyncTests', cfg.skipSyncTests);
Screen('Preference', 'Verbosity', 0);
Screen('Preference', 'SuppressAllWarnings', 1);

Expand Down
2 changes: 2 additions & 0 deletions src/utils/setDefaultsPTB.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
%% list the default values
fieldsToSet.testingDevice = 'pc';

fieldsToSet.skipSyncTests = 0;

% keyboard defaults
fieldsToSet.keyboard.keyboard = [];
fieldsToSet.keyboard.responseBox = [];
Expand Down
2 changes: 2 additions & 0 deletions tests/test_setDefaultsPTB.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ function test_setDefaultsPtbAudio()
expectedCFG.screen.monitorDistance = 134;
expectedCFG.screen.resolution = {[], [], []};

expectedCFG.skipSyncTests = 0;

% fixation cross or dot
expectedCFG.fixation.type = 'cross';
expectedCFG.fixation.xDisplacement = 0;
Expand Down