Skip to content

Commit fce7479

Browse files
authored
Merge pull request #60 from cpp-lln-lab/remi-localizer_update
localizer update: several things on the dot motion functions
2 parents 08ffaef + ad07055 commit fce7479

16 files changed

+403
-128
lines changed

apertureTexture.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
Screen('FillOval', cfg.aperture.texture, transparent, ...
4141
CenterRectOnPoint([0 0 repmat(diameter, 1, 2)], ...
4242
xPos, yPos));
43+
44+
otherwise
45+
46+
error('unknown aperture type: %s.', cfg.aperture.type);
4347

4448
end
4549

initializeDots.m

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

src/dot/computeCartCoord.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function cartesianCoordinates = computeCartCoord(positions, cfg)
2+
cartesianCoordinates = ...
3+
[positions(:,1) + cfg.dot.matrixWidth, ... % x coordinate
4+
positions(:,2) + cfg.dot.matrixWidth]; % y coordinate
5+
6+
% cartesianCoordinates = positions;
7+
end
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function angleMotion = computeRadialMotionDirection(cfg, dots)
2+
3+
cartesianCoordinates = computeCartCoord(dots.positions, cfg);
4+
5+
[angleMotion, ~] = cart2pol(cartesianCoordinates(:, 1), cartesianCoordinates(:, 2));
6+
angleMotion = angleMotion / pi * 180;
7+
8+
if dots.direction == -666
9+
angleMotion = angleMotion - 180;
10+
end
11+
12+
end
13+

decompMotion.m renamed to src/dot/decomposeMotion.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function [horVector, vertVector] = decompMotion(angleMotion)
1+
function [horVector, vertVector] = decomposeMotion(angleMotion)
22
% decompose angle of start motion into horizontal and vertical vector
33
horVector = cos(pi * angleMotion / 180);
44
vertVector = -sin(pi * angleMotion / 180);
File renamed without changes.

src/dot/generateNewDotPositions.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function newPositions = generateNewDotPositions(cfg, dotNumber)
2+
3+
newPositions = rand(dotNumber, 2) * cfg.dot.matrixWidth;
4+
5+
end

src/dot/initDots.m

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
function [dots] = initDots(cfg, thisEvent)
2+
% [dots] = initDots(cfg, thisEvent)
3+
%
4+
% % Dot life time in seconds
5+
% cfg.dot.lifeTime
6+
% % Number of dots
7+
% cfg.dot.number
8+
% Proportion of coherent dots.
9+
% cfg.dot.coherence
10+
%
11+
% % Direction (an angle in degrees)
12+
% thisEvent.direction
13+
% % Speed expressed in pixels per frame
14+
% thisEvent.speed
15+
%
16+
%
17+
18+
% TODO
19+
% bound direction between 0 and 360 ??
20+
21+
dots.direction = thisEvent.direction(1);
22+
23+
speedPixPerFrame = thisEvent.speed(1);
24+
25+
lifeTime = cfg.dot.lifeTime;
26+
27+
% decide which dots are signal dots (1) and those are noise dots (0)
28+
dots.isSignal = rand(cfg.dot.number, 1) < cfg.dot.coherence;
29+
30+
% for static dots
31+
if dots.direction == -1
32+
speedPixPerFrame = 0;
33+
lifeTime = Inf;
34+
dots.isSignal = true(cfg.dot.number, 1);
35+
end
36+
37+
%% Set an array of dot positions [xposition, yposition]
38+
% These can never be bigger than 1 or lower than 0
39+
% [0,0] is the top / left of the square
40+
% [1,1] is the bottom / right of the square
41+
dots.positions = generateNewDotPositions(cfg, cfg.dot.number);
42+
43+
%% Set vertical and horizontal speed for all dots
44+
dots = setDotDirection(cfg, dots);
45+
46+
[horVector, vertVector] = decomposeMotion(dots.directionAllDots);
47+
speeds = [horVector, vertVector];
48+
49+
% we were working with unit vectors. we now switch to pixels
50+
speeds = speeds * speedPixPerFrame;
51+
52+
%% Create a vector to update to dotlife time of each dot
53+
% Not all set to 1 so the dots will die at different times
54+
% The maximum value is the duraion of the event in frames
55+
time = floor(rand(cfg.dot.number, 1) * cfg.eventDuration / cfg.screen.ifi);
56+
57+
%% Convert from seconds to frames
58+
lifeTime = ceil(lifeTime / cfg.screen.ifi);
59+
60+
%%
61+
dots.lifeTime = lifeTime;
62+
dots.time = time;
63+
dots.speeds = speeds;
64+
dots.speedPixPerFrame = speedPixPerFrame;
65+
66+
end
67+
68+

src/dot/reseedDots.m

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
function dots = reseedDots(dots, cfg)
2+
3+
fixationWidthPix = 0;
4+
if isfield(cfg.fixation, 'widthPix')
5+
fixationWidthPix = cfg.fixation.widthPix;
6+
end
7+
8+
cartesianCoordinates = computeCartCoord(dots.positions, cfg);
9+
[~, radius] = cart2pol(cartesianCoordinates(:, 1), cartesianCoordinates(:, 2));
10+
11+
12+
13+
% Create a logical vector to detect any dot that has:
14+
% - an xy position inferior to 0
15+
% - an xy position superior to winWidth
16+
% - has exceeded its liftime
17+
% - is on the fixation cross
18+
% - has been been picked to be killed
19+
20+
N = any([ ...
21+
dots.positions > cfg.dot.matrixWidth, ...
22+
dots.positions < 0, ...
23+
dots.time > dots.lifeTime, ...
24+
radius - cfg.dot.sizePix < fixationWidthPix / 2, ...
25+
rand(cfg.dot.number, 1) < cfg.dot.proportionKilledPerFrame, ...
26+
], 2) ;
27+
28+
% If there is any such dot we relocate it to a new random position
29+
% and change its lifetime to 1
30+
if any(N)
31+
32+
dots.positions(N, :) = generateNewDotPositions(cfg, sum(N));
33+
34+
dots = setDotDirection(cfg, dots);
35+
36+
[horVector, vertVector] = decomposeMotion(dots.directionAllDots);
37+
dots.speeds = [horVector, vertVector] * dots.speedPixPerFrame;
38+
39+
dots.time(N, 1) = 1;
40+
41+
end
42+
43+
end

src/dot/setDotDirection.m

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function dots = setDotDirection(cfg, dots)
2+
3+
directionAllDots = nan(cfg.dot.number, 1);
4+
5+
% Coherent dots
6+
directionAllDots(dots.isSignal) = dots.direction;
7+
8+
if strcmp(cfg.design.motionType, 'radial')
9+
angleMotion = computeRadialMotionDirection(cfg, dots);
10+
directionAllDots(dots.isSignal) = angleMotion;
11+
end
12+
13+
% Random direction for the non coherent dots
14+
directionAllDots(~dots.isSignal) = rand(sum(~dots.isSignal), 1) * 360;
15+
directionAllDots = rem(directionAllDots, 360);
16+
17+
dots.directionAllDots = directionAllDots;
18+
19+
end

0 commit comments

Comments
 (0)