-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathLayout.m
More file actions
122 lines (111 loc) · 4.49 KB
/
Layout.m
File metadata and controls
122 lines (111 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
classdef Layout
properties %#ok<*PROP>
name % name of the probe
x % x coordinates of the channels (top is zero, positive values go down)
y % y coordinates
n % number of electrodes
end
methods
function self = Layout(in)
% Create Layout object.
% layout = Layout(file) creates a Layout object from the
% given config file. The n^th row of the config file contains
% the x and y coordinates for the n^th channel, separated by
% a tab.
%
% layout = Layout(coords) creates a Layout object using the
% given matrix of coordinates. The first column contains the
% x coordinates, the second column the y coordinates. The
% n^th row contains the coordinates for the n^th channel.
assert(isnumeric(in) || ischar(in), 'Input must be either a config file name or an N-by-2 matrix!')
if ischar(in)
file = in;
fid = fopen(file);
if fid
data = fscanf(fid, '%g\t%g\n');
self.name = file;
self.x = data(1 : 2 : end);
self.y = data(2 : 2 : end);
fclose(fid);
else
error('Could not open config file %s!', file)
end
else
assert(size(in, 2) == 2, 'Numeric input must be N-by-2 matrix!')
xy = in;
self.x = xy(:, 1);
self.y = xy(:, 2);
end
self.n = numel(self.x);
end
function order = channelOrder(self, coord)
% Sort channels
% order = layout.channelOrder('x') returns the channel
% indices ordered by their x coordinate (analogous for y).
%
% order = layout.channelOrder('yx') orders first by y, then
% by x.
assert(all(ismember(coord, 'xy')), 'Input must specify combination of x and y!')
m = max(max(self.x), max(self.y));
k = 0;
nc = numel(coord);
for i = 1 : nc
k = k + m ^ (nc - i) * eval(['self.' coord(i)]);
end
[~, order] = sort(k);
end
function k = neighbors(self, i, d)
% Return list of neighbors
% k = neighbors(self, i, d) returns a list of neighbors for
% channel i, defined as those channels with a distance less
% than d (excluding channel i itself).
x = self.x;
y = self.y;
k = find((x - x(i)) .^ 2 + (y - y(i)) .^ 2 < d ^ 2);
k = setdiff(k, i);
end
function b = isNeighbor(self, i, k, d)
% Test if channel i is neighbor of channel k.
% b = neighbors(self, i, k, d) returns a true if channel i is
% a neighbor of channel k. If either i or k is a vector a
% vector of logicals is returned.
x = self.x;
y = self.y;
b = (x(i) - x(k)) .^ 2 + (y(i) - y(k)) .^ 2 < d ^ 2;
end
function plot(self, hdl)
% Plot layout.
% layout.plot() plots the layout of the probe.
%
% layout.plot(handle) uses the given figure or axes handle to
% produce the plot.
if nargin < 2
hdl = 0;
end
switch get(hdl, 'type')
case 'figure'
figure(hdl)
case 'axes'
axes(hdl)
otherwise
figure
end
plot(self.x, self.y, 'ok', 'markersize', 20)
title(self.name)
hold on
for i = 1 : self.n
text(self.x(i), self.y(i), sprintf('%d', i), ...
'horizontalalignment', 'center', ...
'verticalalignment', 'middle')
end
d = round(min(pdist([self.x self.y])));
plot(min(self.x) - d * [1 2], [0 0], 'k', 'linewidth', 4)
text(min(self.x) - 2 * d, 0, sprintf('\n%d \\mum', d))
axis equal ij tight off
ax = axis;
dx = (ax(2) - ax(1)) / 10;
dy = (ax(4) - ax(3)) / 10;
axis(ax + [-dx dx -dy dy])
end
end
end