-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspm_eeg_invertiter.m
170 lines (110 loc) · 4.57 KB
/
spm_eeg_invertiter.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
function [Dtest,modelF,allF]=spm_eeg_invertiter(Dtest,Npatchiter,funcname,patchind)
% Function to perform several MSP type inversions with different
% pseudo-randomly selected priors- in this case single cortical patches
%
% Npatchiter: number of iterations
% funcname is name of MSP alogorithm: current (spm_eeg_invert) or classic (spm_eeg_invert_classic)
% patchind is an optional list of indices of vertices which will be patch
% centres. patchind will have size Npatchiter*Np (where Np is number of patches set in
% inverse.Np )
% if Dtest{1}.inv{val}.inverse.mergeflag==1 then merges Npatchiter posterior current
% distributions, else replaces posterior with best of the iterations.
% __________________________________________________________________________
% Copyright (C) 2010 Wellcome Trust Centre for Neuroimaging
%
% Gareth Barnes
% $Id: spm_eeg_invertiter.m 6367 2015-03-09 15:02:25Z gareth $
if nargin<2,
Npatchiter=[];
end;
if nargin<3,
error('No function call specified');
end;
if nargin<4,
patchind=[];
end;
if isempty(Npatchiter),
Npatchiter=16;
end;
if numel(Dtest)>1,
error('only works with single datasets at the moment');
end;
val=Dtest{1}.val;
Nvert=size(Dtest{1}.inv{val}.mesh.tess_mni.vert,1);
Np=Dtest{1}.inv{val}.inverse.Np;
allF=zeros(Npatchiter,1);
fprintf('Checking leadfields');
[L Dtest{1}] = spm_eeg_lgainmat(Dtest{1}); % Generate/load lead field- this stops it being done at each iteration
if isempty(patchind),
disp('Reseting random number seed ! and then generating random patch centres ');
rand('state',0);
%% make random patch centers, except on the first iteration when we keep to a fixed stepsize
for f=1:Npatchiter,
tmp=randperm(Nvert);
allIp(f).Ip=tmp(1:Np);
end;
allIp(1).Ip=[]; %% fix the step size of the first patch set (uses default MSP indices)
else
for f=1:Npatchiter,
allIp(f).Ip=patchind(f,:);
end;
end;
modelF=[];
bestF=-Inf;
for patchiter=1:Npatchiter,
%Din=Dtest{1};
%Dout=Din;
Ip=allIp(patchiter).Ip;
disp(sprintf('patchiter %d/%d',patchiter,Npatchiter));
switch funcname,
case 'Classic',
Dtest{1}.inv{val}.inverse.Ip=Ip;
Dtest{1} = spm_eeg_invert_classic(Dtest{1});
case 'Current',
warning('Patch centres are currently fixed for this algorithm (iteration will have no effect!)');
Dtest{1} = spm_eeg_invert(Dtest{1}); %
%Dout.inv{val}.inverse.Ip=Ip;
otherwise
error('unknown function');
end;
if (Dtest{1}.inv{val}.inverse.mergeflag==1), %% will need all posteriors to merge them (could consider getting rid of worst ones here to save memory
modelF(patchiter).inverse=Dtest{1}.inv{val}.inverse;
else %% just keep track of best inversion
if Dtest{1}.inv{val}.inverse.F>bestF,
modelF(1).inverse=Dtest{1}.inv{val}.inverse;
bestF=Dtest{1}.inv{val}.inverse.F;
end;
end;
allF(patchiter)=Dtest{1}.inv{val}.inverse.F;
end; % for patchiter
%% will use these to merge posteriors or take best one
[bestF,bestind]=max(allF);
disp('model evidences relative to maximum:')
sort(allF-bestF)
%% for 1 iteration or for best solution
Dtest{1}.inv{val}.inverse=modelF(1).inverse; %% return best model (only 1 model saved in this option)
Dtest{1}.inv{val}.inverse.allF=allF;
if Npatchiter>1, %% keep iterations if more than 1
if (Dtest{1}.inv{val}.inverse.mergeflag==1)
Dtest{1}.inv{val}.inverse=modelF(bestind).inverse; % start with best model so far
Qpriors=sparse(zeros(Npatchiter,size(modelF(1).inverse.qC,1)));
for patchiter=1:Npatchiter,
Qpriors(patchiter,:)=modelF(patchiter).inverse.qC;
end;
disp('Merging posterior distributions..');
ugainfiles=Dtest{1}.inv{val}.gainmat;
surfind=ones(Npatchiter,1);
%% now mix the posteriors
[Dtest{1}] = spm_eeg_invert_classic_mix(Dtest{1},val,Qpriors,surfind,ugainfiles);
Dtest{1}.inv{val}.comment{1}=sprintf('Merged posterior of %d solutions',Npatchiter);
mixF=Dtest{1}.inv{val}.inverse.F;
if mixF-bestF<0
warning('Merged solution is worse than the best');
end;
disp(sprintf('Improvement (when +ve) over best iteration %3.2f',mixF-bestF));
else % NO merge - just take the best
disp('Using best patch set to current estimate');
Dtest{1}.inv{val}.comment{1}=sprintf('Best F of %d solutions',Npatchiter);
end; % if BMA
end;
spm_eeg_invert_display(Dtest{1});