-
Notifications
You must be signed in to change notification settings - Fork 27
/
limo_contrast_checking.m
134 lines (117 loc) · 3.84 KB
/
limo_contrast_checking.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
132
133
134
function go = limo_contrast_checking(varargin)
% Routine to check contrasts are valid
%
% FORMAT
% go = limo_contrast_checking(C,X); % <-- check the statistical validity of C
% go = limo_contrast_checking(LIMO.dir); % <-- add zeros to the last coded contrast
% go = limo_contrast_checking(LIMO.dir, LIMO.design.X, C);
%
% INPUT
% C a vector or matrix of contrasts
% X the design matrix (also LIMO.design.X)
% LIMO.dir the directory where LIMO.mat is
%
% OUTPUT
% if input C and X; go=1 if valid contrast or 0 if invalid
% if input dir, X and C, go = C corrected with extra 0s
%
% Cyril Pernet, v5. 2019
% Valid constrasts are a sum (ones), a weighted sum (ones/N)
% or projection invariant (orthogonal usually).
% -----------------------------------------------------------
% Copyright (C) LIMO Team 2019
if nargin == 0
help limo_contrast_checking
return
else
warning on
end
%% update the contrast with 0s
% ----------------------------------------
diagonalize = 0;
if nargin == 1 || nargin == 3
limo_path = varargin{:,1};
if ~exist(limo_path,'dir')
warning('%s doesn''t exist, updating to local dir',limo_path)
limo_path = pwd;
end
if nargin == 1
LIMO = load(fullfile(limo_path,'LIMO.mat'));
X = LIMO.LIMO.design.X;
C = LIMO.LIMO.contrast{end}.C;
else
X = varargin{:,2};
C = varargin{:,3};
end
[l,w]=size(C);
if w ~= size(X,2)
% could be that need transpose
if l == size(X,2)
C = C';
disp('C has been transposed')
[l,w]=size(C);
end
if l == w
diagonalize = 1;
C = diag(C)';
[l,w] = size(C);
end
% could be that cst term not coded
if w < size(X,2)
tmp = zeros(size(C,1),size(X,2));
tmp(:,1:(size(C,2))) = C;
C = tmp; clear tmp;
disp('zeros added for the constant term')
[~,w]=size(C);
end
if w ~= size(X,2)
disp('c must have the same number of columns as X')
error('dimensions must agree')
end
if diagonalize
C = diag(C);
end
end
go = C;
if nargin == 1
LIMO = LIMO.LIMO;
LIMO.LIMO.contrast{end}.C = C;
save(fullfile(limo_path,'LIMO.mat'),'LIMO','-v7.3')
end
%% check if contrast is valid
% --------------------------------------
elseif nargin == 2
X = varargin{2};
% check input is correct size
if size(varargin{1},2) ~= size(X,2)
error('the length of the contrast must be equal to the number of regressors in the design')
end
% check this is invariant
for s=1:size(varargin{1},1)
C = varargin{1}(s,:);
N = sum(X(:,C~=0)); % N per condition
if sum(C) == length(find(C))
go = 1; % if contrast with ones only to add parameters
elseif ~all(int16(C(C~=0) - N/sum(N)))
go =1; % also a sum but equal 0 weighted by total number of observations
else
P = X*pinv(X); % projection
lambda = X*C'; % contrast
check = int16(P*lambda); % contrast onto X
check = (check == int16(lambda)); % it is invariant
if sum(check) ~= size(X,1)
go = 0; % if contrast invariant
else
go = 1;
end
end
% check if the contrast includes the constant
% if could results into lambda = P*lambda, but still
% no real life test include this term
if C(end) ~= 0
error('the contrast requested include the constant term, which is not possible')
end
end
else
error('the number of arguments must be 2 or 3 ; error in limo_contrast_checking')
end