-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgridScoreForActivity.m
131 lines (117 loc) · 4.55 KB
/
gridScoreForActivity.m
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
123
124
125
126
127
128
129
130
131
function gs = gridScoreForActivity(Activity, opt)
% gridScoreForActivity
% Activity - Acitvity pattern of a (simulated) cell.
% opt - Structure with fields:
% * minRadius -- Minimum radius for circular histogram
% computed from values within the disk
% defined by minRadius and maxRadius.
% * maxRadius -- Maximum radius.
%
% RETURN
% gs - Returns the grid score for the activity pattern.
%
% Copyright (C) 2015 Florian Raudies, 05/02/2015, Palo Alto, CA.
% License, GNU GPL, free software, without any warranty.
%
if isfield(opt, 'minRadius'), minRadius = opt.minRadius;
else minRadius = 0.05; end
if isfield(opt, 'maxRadius'), maxRadius = opt.maxRadius;
else maxRadius = 0.95; end
% Determine sizes and their ratio.
[nY nX] = size(Activity);
r = nX/nY;
[Y X] = ndgrid(linspace(-1, +1, nY), linspace(-r, +r, nX));
Radius = hypot(X, Y);
Phi = mod(atan2(Y, X) + 2*pi, 2*pi);
Selection = (minRadius < Radius) & (Radius < maxRadius);
% Calculate the product moment correlation coefficient of Pearson
AutoCorr = normAutoCorrWithFFT2D(Activity);
% Extract a circular disk of the auto-correlation
binNum = 12;
binNum2 = binNum/2;
dPhi = 2*pi/binNum;
dPsi = dPhi/2;
DiskSelection = AutoCorr(Selection);
PhiSelection = Phi(Selection);
% Define bins for circular distribution.
BinCenter = 0 : dPhi : (2*pi - dPhi);
DiskVoting = zeros(binNum, 1);
PhiVoting = zeros(binNum, 1);
% Select everything above and below adding an subtracting half of the bin
% distance, circular boundary condition.
IndexSelection = PhiSelection < BinCenter(1)+dPsi ...
| PhiSelection >= 2*pi-dPsi;
DiskVoting(1) = sum(DiskSelection(IndexSelection));
PhiVoting(1) = sum(IndexSelection);
% Do the remaining bins.
for iBin = 2:binNum,
IndexSelection = PhiSelection >= BinCenter(iBin)-dPsi ...
& PhiSelection < BinCenter(iBin)+dPsi;
DiskVoting(iBin) = sum(DiskSelection(IndexSelection));
PhiVoting(iBin) = sum(IndexSelection);
end
% Calculate the circular correlation
% In one group correlate rotations of 60° and 120° and in the other group
% correlate rotations of 30°, 90°, and 150°.
% Conversion into orientations.
Shift = [30 60 90 120 150]/180*pi;
GroupIndexOne = [2 4];
GroupIndexTwo = [1 3 5];
sNum = length(Shift);
% Use function pearsonCorr because it works for even number (unlike the fft solution)
DiskCorr = pearsonCorr(DiskVoting, 'circular');
ShiftCorr = zeros(sNum, 1);
for iShift = 1:sNum,
DiskCorrShift = vecShiftCyc(DiskCorr, -Shift(iShift)*binNum2/pi);
ShiftCorr(iShift) = DiskCorrShift(binNum2);
end
ValGroupOne = ShiftCorr(GroupIndexOne); % 60° and 120°
ValGroupTwo = ShiftCorr(GroupIndexTwo); % 30°, 90°, and 150°
gs = min(ValGroupOne) - max(ValGroupTwo);
function X = vecShiftCyc(X, s)
% vecShiftCyc
% X - Vector to shift for amount 's' with cyclic boundary
% condition.
% s - Amount to shift, which could be also a FRACTION of one pixel.
%
% RETURN
% X - Shifted version of the vector.
%
ds1 = s - floor(s);
ds0 = 1 - ds1;
s0 = floor(s);
s1 = ceil(s);
X0 = circshift(X(:), s0);
X1 = circshift(X(:), s1);
X = ds0 * X0 + ds1 * X1;
function X = pearsonCorr(X, boundary)
% personCorr
% X - Input data which could be a multi-dimensional array.
% boundary - Boundary condition for correlation.
%
% RETURN
% Y - Full correlation result for all shifts which data X
% provides, basicially determined by the dimensions of X.
%
% DESCRIPTION
% Pearson's product moment correlation coefficient.
%
n = numel(X);
I = ones(size(X));
A = n * imfilter(X, X, 'same', boundary);
B = sum(X(:)) * imfilter(X, I, 'same', boundary);
C = sqrt( n * sum(X(:).^2) - sum(X(:)).^2 );
D = sqrt( n * imfilter(X.^2, I, 'same', boundary) - imfilter(X, I, 'same', boundary).^2 );
X = (A - B) ./ (C.*D + eps);
function AC = normAutoCorrWithFFT2D(S)
% normAutoCorrWithFFT2D
% S - Signal one assumed to be a row-vector.
%
% RETURN
% NA - Normalized auto-correlation result.
%
F = fft2(S-mean(S(:)));
F = F .* conj(F);
AC = fftshift(ifft2(F));
AC = real(AC);
AC = AC/AC(1);