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
61 changes: 59 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,66 @@ press the keys necessary to start or abort the experiment.

Using empty vectors (ie `[]`) or a negative value for those means that you will let PTB find and use the default device.

## Structure and function details
## Structure

```matlab

cfg.testingDevice = 'pc';

% cfg.color
cfg.keyboard.keyboard = [];
cfg.keyboard.responseBox = [];
cfg.keyboard.responseKey = {};
cfg.keyboard.escapeKey = 'ESCAPE';

% cfg.debug
cfg.debug.do = true;
cfg.debug.transpWin = true;
cfg.debug.smallWin = true;

% cfg.text
cfg.text.font
cfg.text.size
cfg.text.style

% cfg.color
cfg.color.background

% cfg.screen
cfg.screen.monitorWidth
cfg.screen.monitorDistance
cfg.screen.idx
cfg.screen.win
cfg.screen.winRect
cfg.screen.winWidth
cfg.screen.winHeight
cfg.screen.center
cfg.screen.FOV
cfg.screen.ppd
cfg.screen.ifi
cfg.screen.monRefresh

% cfg.audio
cfg.audio.do
cfg.audio.pahandle
cfg.audio.devIdx
cfg.audio.playbackMode
cfg.audio.requestedLatency
cfg.audio.fs
cfg.audio.channels
cfg.audio.initVolume
cfg.audio.pushSize
cfg.audio.requestOffsetTime
cfg.audio.reqsSampleOffset

% cfg.mri
cfg.mri.repetitionTime
cfg.mri.triggerNb
cfg.mri.triggerKey
```

## function details

<!-- ### setParameters -->

### initPTB

Expand Down
2 changes: 2 additions & 0 deletions checkAbort.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
function checkAbort(cfg, deviceNumber)
% checkAbort(cfg, deviceNumber)
%
% Check for experiment abortion from operator
% When no deviceNumber is set then it will check the default device
% When an abort key s detected this will set a global variable and throw a
Expand Down
4 changes: 3 additions & 1 deletion cleanUp.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
function cleanUp
function cleanUp()
% cleanUp()
%
% A wrapper function to close all windows, ports, show mouse cursor, close keyboard queues
% and give access back to the keyboards.

Expand Down
16 changes: 8 additions & 8 deletions collectAndSaveResponses.m
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
function responseEvents = collectAndSaveResponses(cfg, expParameters, logFile, experimentStart)
function responseEvents = collectAndSaveResponses(cfg, logFile, experimentStart)

responseEvents = getResponse('check', cfg.keyboard.responseBox, cfg);

if isfield(responseEvents(1), 'onset') && ~isempty(responseEvents(1).onset)

for iResp = 1:size(responseEvents, 1)
responseEvents(iResp).onset = ...
responseEvents(iResp).onset - experimentStart;
end

responseEvents.fileID = logFile.fileID;
responseEvents.extraColumns = logFile.extraColumns;
saveEventsFile('save', expParameters, responseEvents);
saveEventsFile('save', cfg, responseEvents);

end
end
end
10 changes: 10 additions & 0 deletions computeFOV.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function FOV = computeFOV(cfg)
% FOV = computeFOV(cfg)
%
% computes the number of degrees of visual angle in the whole field of view
%

FOV = 2 * ...
(180 * (atan(cfg.screen.monitorWidth / (2 * cfg.screen.monitorDistance)) / pi));

end
4 changes: 3 additions & 1 deletion degToPix.m
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
function structure = degToPix(fieldName, structure, cfg)
% structure = degToPix(fieldName, structure, cfg)
%
% For a given field value in degrees of visual angle in the structure,
% this computes its value in pixel using the pixel per degree value of the cfg structure
% and returns a structure with an additional field with Pix suffix holding that new value.

deg = getfield(structure, fieldName); %#ok<GFLD>

structure = setfield(structure, [fieldName 'Pix'], ...
floor(cfg.ppd * deg)) ; %#ok<SFLD>
floor(cfg.screen.ppd * deg)) ; %#ok<SFLD>

end
4 changes: 2 additions & 2 deletions demos/CPP_waitForTriggerDemo.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

cfg.testingDevice = 'mri';

cfg.numTriggers = 4;
cfg.mri.triggerNb = 4;

cfg.triggerKey = 'space';
cfg.mri.triggerKey = 'space';

KbName('UnifyKeyNames');

Expand Down
38 changes: 15 additions & 23 deletions devSandbox.m → dev/devSandbox.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,8 @@
% Init the structure that will contain PTB setup
cfg = struct;

% Set some colors to be choosen as background
cfg.white = [255 255 255];
cfg.black = [0 0 0];
cfg.grey = mean([cfg.black; cfg.white]);

% Set the PTB window background manually
cfg.backgroundColor = cfg.grey;
cfg.color.background = [127 127 27];

% Init PTB, see the Sub-Functions below
cfg = devSandbox_initPTB(cfg);
Expand All @@ -40,7 +35,7 @@
% -------------------------------------------------------------------------

% Define black and white
white = WhiteIndex(cfg.screen);
white = WhiteIndex(cfg.screen.idx);
grey = white / 2;
inc = white - grey;

Expand Down Expand Up @@ -95,7 +90,7 @@
mask(:, :, 2) = grating .* contrast;

% Make our grating mask texture
gratingMaskTex = Screen('MakeTexture', cfg.win, mask);
gratingMaskTex = Screen('MakeTexture', cfg.screen.win, mask);

% Make a black and white noise mask half the size of our grating. This will
% be scaled upon drawing to make a "chunky" noise texture which our grating
Expand All @@ -104,15 +99,15 @@
noise = rand(round(visibleSize / 2)) .* white;

% Make our noise texture
noiseTexture = Screen('MakeTexture', cfg.win, noise);
noiseTexture = Screen('MakeTexture', cfg.screen.win, noise);

% Make a destination rectangle for our textures and center this on the
% screen
dstRect = [0 0 visibleSize visibleSize];
dstRect = CenterRect(dstRect, cfg.winRect);
dstRect = CenterRect(dstRect, cfg.screen.winRect);

% Calculate the wait duration
waitDuration = waitframes * cfg.ifi;
waitDuration = waitframes * cfg.screen.ifi;

% Recompute pixPerCycle, this time without the ceil() operation from above.
% Otherwise we will get wrong drift speed due to rounding errors
Expand All @@ -123,7 +118,7 @@
shiftPerFrame = cyclesPerSecond * pixPerCycle * waitDuration;

% Sync us to the vertical retrace
vbl = Screen('Flip', cfg.win);
vbl = Screen('Flip', cfg.screen.win);

% Set the frame counter to zero, we need this to 'drift' our grating
frameCounter = 0;
Expand All @@ -142,13 +137,13 @@
srcRect = [xoffset 0 xoffset + visibleSize visibleSize];

% Draw noise texture to the screen
Screen('DrawTexture', cfg.win, noiseTexture, [], dstRect, []);
Screen('DrawTexture', cfg.screen.win, noiseTexture, [], dstRect, []);

% Draw grating mask
Screen('DrawTexture', cfg.win, gratingMaskTex, srcRect, dstRect, []);
Screen('DrawTexture', cfg.screen.win, gratingMaskTex, srcRect, dstRect, []);

% Flip to the screen on the next vertical retrace
vbl = Screen('Flip', cfg.win, vbl + (waitframes - 0.5) * cfg.ifi);
vbl = Screen('Flip', cfg.screen.win, vbl + (waitframes - 0.5) * cfg.screen.ifi);

end

Expand Down Expand Up @@ -182,22 +177,19 @@
PsychDefaultSetup(2);

% Get the screen numbers and draw to the external screen if avaliable
cfg.screen = max(Screen('Screens'));
cfg.screen.idx = max(Screen('Screens'));

% Open an on screen window
[cfg.win, cfg.winRect] = Screen('OpenWindow', cfg.screen, cfg.backgroundColor);
[cfg.screen.win, cfg.screen.winRect] = Screen('OpenWindow', cfg.screen.idx, cfg.color.background);

% Get the size of the on screen window
[cfg.winWidth, cfg.winHeight] = WindowSize(cfg.win);
[cfg.screen.winWidth, cfg.screen.winHeight] = WindowSize(cfg.screen.win);

% Query the frame duration
cfg.ifi = Screen('GetFlipInterval', cfg.win);

% Get the Center of the Screen
cfg.center = [cfg.winRect(3), cfg.winRect(4)] / 2;
cfg.screen.ifi = Screen('GetFlipInterval', cfg.screen.win);

% Set up alpha-blending for smooth (anti-aliased) lines
Screen('BlendFunction', cfg.win, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');
Screen('BlendFunction', cfg.screen.win, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');

end

Expand Down
3 changes: 3 additions & 0 deletions dev/miss_hit.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
line_length: 120
suppress_rule: "copyright_notice"
suppress_rule: "naming_functions"
8 changes: 4 additions & 4 deletions drawFixationCross.m
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
function drawFixationCross(cfg, expParameters, color)
function drawFixationCross(cfg, color)
% Define the parameters of the fixation cross in `cfg` and `expParameters`

Screen('DrawLines', ...
cfg.win, ...
cfg.screen.win, ...
cfg.allCoords, ...
expParameters.lineWidthPix, ...
cfg.lineWidthPix, ...
color, ...
[cfg.center(1) cfg.center(2)], 1);
[cfg.screen.center(1) cfg.screen.center(2)], 1);

end
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading