spm_eeg_invert.m 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. function [D] = spm_eeg_invert(D, val)
  2. % ReML inversion of multiple forward models for EEG-MEG
  3. % FORMAT [D] = spm_eeg_invert(D, val)
  4. % ReML estimation of regularisation hyperparameters using the
  5. % spatiotemporal hierarchy implicit in EEG/MEG data
  6. %
  7. % Requires:
  8. % D{i}.inv{val}.inverse:
  9. %
  10. % inverse.modality - modality to use in case of multimodal datasets
  11. %
  12. % inverse.trials - D.events.types to invert
  13. % inverse.type - 'GS' Greedy search on MSPs
  14. % 'ARD' ARD search on MSPs
  15. % 'MSP' GS and ARD multiple sparse priors
  16. % 'LOR' LORETA-like model
  17. % 'IID' minimum norm
  18. % inverse.woi - time window of interest ([start stop] in ms)
  19. % inverse.lpf - band-pass filter - low frequency cut-off (Hz)
  20. % inverse.hpf - band-pass filter - high frequency cut-off (Hz)
  21. % inverse.Han - switch for Hanning window
  22. % inverse.xyz - (n x 3) locations of spherical VOIs
  23. % inverse.rad - radius (mm) of VOIs
  24. %
  25. % inverse.Nm - maximum number of channel modes
  26. % inverse.Nr - maximum number of temporal modes
  27. % inverse.Np - number of sparse priors per hemisphere
  28. % inverse.smooth - smoothness of source priors (0 to 1)
  29. % inverse.Na - number of most energetic dipoles
  30. % inverse.sdv - standard deviations of Gaussian temporal correlation
  31. % inverse.pQ - any source priors (e.g. from fMRI); vector or matrix
  32. % inverse.Qe - any sensor error components (e.g. empty-room data)
  33. % inverse.dplot - make diagnostics plots (0 or 1)
  34. % inverse.STAT - flag for stationarity assumption, which invokes a
  35. % full DCT temporal projector (from lpf to hpf Hz)
  36. %
  37. % Evaluates:
  38. %
  39. % inverse.M - MAP projector (reduced)
  40. % inverse.J{i} - Conditional expectation (i conditions) J = M*U*Y
  41. % inverse.L - Lead field (reduced UL := U*L)
  42. % inverse.qC - spatial covariance
  43. % inverse.qV - temporal correlations
  44. % inverse.T - temporal projector
  45. % inverse.U(j) - spatial projector (j modalities)
  46. % inverse.Y{i} - reduced data (i conditions) UY = UL*J + UE
  47. % inverse.Is - Indices of active dipoles
  48. % inverse.It - Indices of time bins
  49. % inverse.Ic{j} - Indices of good channels (j modalities)
  50. % inverse.Nd - number of dipoles
  51. % inverse.pst - peristimulus time
  52. % inverse.dct - frequency range
  53. % inverse.F - log-evidence
  54. % inverse.VE - variance explained in spatial/temporal subspaces (%)
  55. % inverse.R2 - variance in subspaces accounted for by model (%)
  56. % inverse.scale - scaling of data for each of j modalities
  57. %__________________________________________________________________________
  58. %
  59. % 1. This routine implements "group-based" inversion, corresponding to
  60. % ill-posed linear models of the following form:
  61. %
  62. % [AY{1}...AY{n}] = L(1} * [J{1}...J{n}] + [e{1}...e{n}]
  63. %
  64. % where AY{i} are the spatially normalized or adjusted data from subject i
  65. % that would have been seen if the lead-field L{i} = L{1}. The ensuing
  66. % Gaussian process priors on sources are then used to estimate subject-
  67. % specific MAP estimates of J{i} using
  68. %
  69. % AY{i} = L(1} * J{i} + e{i}
  70. %
  71. % using spatial priors from the group model above.
  72. %
  73. % Here, A{i} = L{1}*pinv(L{i}) =>
  74. % AY{i} = A(i}*L(i}*J{i}
  75. % = L(1}*J{i}
  76. %
  77. % Potential scaling differences between the lead-fields are handled by
  78. % scaling L{1} such that trace(L{1}*L{1}') = constant (number of spatial
  79. % modes or channels), while scaling the data such that trace(AY{n}*AY{n}') =
  80. % constant over subjects (and modalities; see below).
  81. %
  82. % See: Electromagnetic source reconstruction for group studies.
  83. % Litvak V, Friston K.
  84. % NeuroImage. 2008 Oct 1;42(4):1490-8.
  85. %
  86. %__________________________________________________________________________
  87. %
  88. % 2. It also implements "fusion" of different types of MEG and EEG data,
  89. % corresponding to ill-posed linear models of the following form:
  90. %
  91. % AY{1}{1,...,t} = L(1} * J{1,...,t} + e{{1,...,t}}
  92. % AY{2}{1,...,t} = L(2} e{{2,...,t}}
  93. % .
  94. % .
  95. % .
  96. % AY{m}{1,...,t} = L(n} e{{n,...,t}}
  97. %
  98. % Under empirical priors on J{1,...,t} for m modalities with t trial types.
  99. %
  100. % See: MEG and EEG data fusion: Simultaneous localisation of face-evoked
  101. % responses.
  102. % Henson R, Mouchlianitis E & Friston K.
  103. % Neuroimage. 2009. 47:581-9.
  104. %__________________________________________________________________________
  105. %
  106. % 3. It also allows incorporation of spatial source priors, eg, from fMRI
  107. % (see spm_eeg_inv_fmripriors.m). Note that if a vector is passed in
  108. % inverse.pQ, then variance components used (pass a matrix if a covariance
  109. % component is desired).
  110. %
  111. % See: A Parametric Empirical Bayesian framework for fMRI-constrained
  112. % MEG/EEG source reconstruction.
  113. % Henson R, Flandin G, Friston K & Mattout J.
  114. % Human Brain Mapping. 2010. 1(10):1512-31.
  115. %__________________________________________________________________________
  116. %
  117. % The routine essentially consists of two steps:
  118. %
  119. % 1. Optimisation of spatial source priors over subjects
  120. % 2. Re-inversion of each subject, fusing across all modalities
  121. %__________________________________________________________________________
  122. % Copyright (C) 2006-2017 Wellcome Trust Centre for Neuroimaging
  123. % Karl Friston
  124. % $Id: spm_eeg_invert.m 7118 2017-06-20 10:33:27Z guillaume $
  125. SVNid = '$Rev: 7118 $';
  126. %-Say hello
  127. %--------------------------------------------------------------------------
  128. spm('FnBanner',mfilename,SVNid);
  129. % check whether this is a group inversion for (Nl) number of subjects
  130. %--------------------------------------------------------------------------
  131. if ~iscell(D), D = {D}; end
  132. Nl = length(D);
  133. % D - SPM data structure
  134. %==========================================================================
  135. if nargin > 1
  136. D{1}.val = val;
  137. elseif ~isfield(D{1}, 'val')
  138. D{1}.val = 1;
  139. end
  140. for i = 2:Nl
  141. D{i}.val = D{1}.val;
  142. end
  143. % forward model
  144. %--------------------------------------------------------------------------
  145. inverse = D{1}.inv{D{1}.val}.inverse;
  146. % defaults
  147. %--------------------------------------------------------------------------
  148. try, STAT = inverse.STAT; catch, STAT = 0; end
  149. try, type = inverse.type; catch, type = 'GS'; end
  150. try, s = inverse.smooth; catch, s = 0.6; end
  151. try, Np = inverse.Np; catch, Np = 256; end
  152. try, Nr = inverse.Nr; catch, Nr = 16; end
  153. try, xyz = inverse.xyz; catch, xyz = [0 0 0]; end
  154. try, rad = inverse.rad; catch, rad = 128; end
  155. try, mask = inverse.mask; catch, mask = []; end
  156. try, lpf = inverse.lpf; catch, lpf = 0; end
  157. try, hpf = inverse.hpf; catch, hpf = 48; end
  158. try, sdv = inverse.sdv; catch, sdv = 4; end
  159. try, Han = inverse.Han; catch, Han = 1; end
  160. try, woi = inverse.woi; catch, woi = []; end
  161. try, pQ = inverse.pQ; catch, pQ = []; end
  162. try, dp = inverse.dplot; catch, dp = 0; end
  163. % get specified modalities to invert (default to all)
  164. %--------------------------------------------------------------------------
  165. try
  166. modalities = inverse.modality;
  167. if ~iscell(modalities)
  168. modalities = {modalities};
  169. end
  170. catch
  171. for m = 1:length(D{1}.inv{D{1}.val}.forward)
  172. modalities{m} = D{1}.inv{D{1}.val}.forward(m).modality;
  173. end
  174. end
  175. Nmod = numel(modalities); % number of modalities
  176. Nmax = Nr; % max number of temporal modes
  177. % check lead fields and get number of dipoles (Nd) and channels (Nc)
  178. %==========================================================================
  179. for i = 1:Nl
  180. fprintf('Checking lead fields for subject %i\n',i)
  181. [L,D{i}] = spm_eeg_lgainmat(D{i});
  182. for m = 1:Nmod
  183. % Check gain or lead-field matrices
  184. %------------------------------------------------------------------
  185. Ic{i,m} = indchantype(D{i}, modalities{m}, 'GOOD');
  186. Nd(i) = size(L,2);
  187. Nc(i,m) = length(Ic{i,m});
  188. if isempty(Ic{i,m})
  189. errordlg(['Modality ' modalities{m} ' is missing from file ' D{i}.fname]);
  190. return
  191. end
  192. if any(diff(Nd))
  193. errordlg('Please ensure subjects have the same number of dipoles.')
  194. return
  195. end
  196. % Check for null space over sensors (SX) and remove it
  197. %------------------------------------------------------------------
  198. try
  199. SX = D{i}.sconfounds{m};
  200. R{i,m} = speye(Nc(i,m),Nc(i,m)) - SX*spm_pinv(SX);
  201. catch
  202. R{i,m} = speye(Nc(i,m),Nc(i,m));
  203. end
  204. end
  205. end
  206. fprintf(' - done\n')
  207. % Compute spatial coherence: Diffusion on a normalised graph Laplacian GL
  208. %==========================================================================
  209. fprintf('%-40s: %30s','Green function from graph Laplacian','...computing'); %-#
  210. Nd = Nd(1); % number of dipoles
  211. vert = D{1}.inv{D{1}.val}.mesh.tess_mni.vert;
  212. face = D{1}.inv{D{1}.val}.mesh.tess_mni.face;
  213. A = spm_mesh_distmtx(struct('vertices',vert,'faces',face),0);
  214. GL = A - spdiags(sum(A,2),0,Nd,Nd);
  215. GL = GL*s/2;
  216. Qi = speye(Nd,Nd);
  217. QG = sparse(Nd,Nd);
  218. for i = 1:8
  219. QG = QG + Qi;
  220. Qi = Qi*GL/i;
  221. end
  222. QG = QG.*(QG > exp(-8));
  223. QG = QG*QG;
  224. clear Qi A GL
  225. fprintf('%s%30s\n',repmat(sprintf('\b'),1,30),'...done') %-#
  226. % Check for (e.g., empty-room) sensor components (in Qe{1})
  227. %==========================================================================
  228. QE = cell(Nl,Nmod);
  229. for i = 1:Nl
  230. for m = 1:Nmod
  231. try
  232. QE{i,m} = D{i}.inv{D{i}.val}.inverse.Qe{m};
  233. QE{i,m} = Nc(i,m)*QE{i,m}/trace(QE{i,m});
  234. if length(QE{i,m}) ~= Nc(i,m)
  235. errordlg('error component (modality %s; subject %d) does not match number of channels (%d)\n',modalities{m},i,Nc(i,m))
  236. return
  237. end
  238. fprintf('Using sensor error component provided...\n');
  239. % assume i.i.d. if not specified
  240. %------------------------------------------------------------------
  241. catch
  242. QE{i,m} = 1;
  243. end
  244. end
  245. end
  246. %==========================================================================
  247. % Spatial projectors (adjusting for different Lead-fields)
  248. %==========================================================================
  249. fprintf('Optimising and aligning spatial modes ...\n')
  250. % Use recursive (regularised) least squares to find average lead-field
  251. %--------------------------------------------------------------------------
  252. Is = 1:Nd;
  253. UL = cell(Nmod,1);
  254. for m = 1:Nmod
  255. % Initialise average lead-field with L{1}
  256. %----------------------------------------------------------------------
  257. UL{m} = R{1,m}*spm_eeg_lgainmat(D{1},Is,D{1}.chanlabels(Ic{1,m}));
  258. AA = 1;
  259. % pre-compute regularised inverses (for speed)
  260. %----------------------------------------------------------------------
  261. for i = 1:Nl
  262. L = R{i,m}*spm_eeg_lgainmat(D{i},Is,D{i}.chanlabels(Ic{i,m}));
  263. iL{i} = spm_inv(L*L');
  264. end
  265. % Optimise alignment matrices A such that A{m}*L{m} = <A{m}*L{m}>m
  266. %----------------------------------------------------------------------
  267. for j = 1:8
  268. % eliminate redundant virtual channels
  269. %------------------------------------------------------------------
  270. fprintf('Aligning - iteration: %i\n',j)
  271. UL{m} = spm_sqrtm(spm_inv(AA))*UL{m};
  272. % eliminate low SNR spatial modes
  273. %------------------------------------------------------------------
  274. U = spm_svd((UL{m}*UL{m}'));
  275. UL{m} = U'*UL{m};
  276. Nm(m) = size(UL{m},1);
  277. % normalise lead-field
  278. %------------------------------------------------------------------
  279. Scale = sqrt(trace(UL{m}*UL{m}')/Nm(m));
  280. UL{m} = UL{m}/Scale;
  281. % spatial projectors A{i,m) for i = 1,...,Nl subjects
  282. %------------------------------------------------------------------
  283. AL = 0;
  284. AA = 0;
  285. for i = 1:Nl
  286. L = R{i,m}*spm_eeg_lgainmat(D{i},Is,D{i}.chanlabels(Ic{i,m}));
  287. A{i,m} = UL{m}*L'*iL{i};
  288. AL = AL + A{i,m}*L;
  289. AA = AA + A{i,m}*A{i,m}';
  290. end
  291. % re-compute average
  292. %------------------------------------------------------------------
  293. UL{m} = AL/Nl;
  294. if Nl == 1, break, end
  295. end
  296. % Report
  297. %----------------------------------------------------------------------
  298. fprintf('Using %d spatial modes for modality %s\n',Nm(m),modalities{m})
  299. if dp
  300. spm_figure('GetWin','Lead fields');
  301. for i = 1:Nl
  302. L = R{i,m}*spm_eeg_lgainmat(D{i},Is(1:8:end),D{i}.chanlabels(Ic{i,m}));
  303. subplot(Nl,4,(i - 1)*4 + 1)
  304. imagesc(A{i,m}*A{i,m}'), axis square
  305. subplot(Nl,4,(i - 1)*4 + 2)
  306. imagesc(A{i,m}'*A{i,m}), axis square
  307. subplot(Nl,4,(i - 1)*4 + 3)
  308. plot(sum(A{i,m}.^2,2)), axis square
  309. subplot(Nl,4,(i - 1)*4 + 4)
  310. plot(L'*A{i,m}'), axis square tight
  311. end
  312. drawnow
  313. end
  314. end
  315. % check restriction: assume radii are the same for all (Nv) VOI
  316. %==========================================================================
  317. Nv = size(xyz,1);
  318. if length(rad) ~= Nv
  319. rad = rad(1)*ones(Nv,1);
  320. else
  321. rad = rad(:);
  322. end
  323. % Restrict source space to Ns sources by eliminating dipoles
  324. %--------------------------------------------------------------------------
  325. if any(any(xyz)) || ~isempty(mask)
  326. Is = sparse(Nd,1);
  327. if any(any(xyz))
  328. for i = 1:Nv
  329. Iv = sum([vert(:,1) - xyz(i,1), ...
  330. vert(:,2) - xyz(i,2), ...
  331. vert(:,3) - xyz(i,3)].^2,2) < rad(i)^2;
  332. Is = Is | Iv;
  333. end
  334. end
  335. if ~isempty(mask)
  336. Iv = spm_mesh_project(struct('vertices',vert,'faces',face), mask);
  337. Is = Is | Iv(:);
  338. end
  339. Is = find(Is);
  340. else
  341. Is = 1:Nd;
  342. end
  343. vert = vert(Is,:);
  344. QG = QG(Is,Is);
  345. for m = 1:Nmod
  346. UL{m} = UL{m}(:,Is);
  347. end
  348. Ns = length(Is);
  349. %==========================================================================
  350. % Temporal projector
  351. %==========================================================================
  352. % loop over Nl lead-fields (subjects)
  353. %--------------------------------------------------------------------------
  354. Nn = zeros(1,Nl); % number of samples
  355. AY = {}; % pooled response for MVB
  356. AYYA = 0; % pooled response for ReML
  357. for i = 1:Nl
  358. % Time-window of interest
  359. %----------------------------------------------------------------------
  360. if isempty(woi)
  361. w{i} = 1000*[min(D{i}.time) max(D{i}.time)];
  362. else
  363. w{i} = woi;
  364. end
  365. It{i} = (w{i}/1000 - D{i}.timeonset)*D{i}.fsample + 1;
  366. It{i} = max(1,It{i}(1)):min(It{i}(end), length(D{i}.time));
  367. It{i} = fix(It{i});
  368. % Peristimulus time
  369. %----------------------------------------------------------------------
  370. pst{i} = 1000*D{i}.time; % peristimulus time (ms)
  371. pst{i} = pst{i}(It{i}); % windowed time (ms)
  372. dur = (pst{i}(end) - pst{i}(1))/1000; % duration (s)
  373. dct{i} = (It{i} - It{i}(1))/2/dur; % DCT frequencies (Hz)
  374. Nb(i) = length(It{i}); % number of time bins
  375. % Serial correlations
  376. %----------------------------------------------------------------------
  377. K = exp(-(pst{i} - pst{i}(1)).^2/(2*sdv^2));
  378. K = toeplitz(K);
  379. qV{i} = sparse(K*K');
  380. % Confounds and temporal subspace
  381. %----------------------------------------------------------------------
  382. T = spm_dctmtx(Nb(i),Nb(i));
  383. j = find( (dct{i} >= lpf) & (dct{i} <= hpf) );
  384. T = T(:,j);
  385. dct{i} = dct{i}(j);
  386. % notch filter nf (Hz)
  387. %----------------------------------------------------------------------
  388. % nf = 10.2/1000;
  389. try
  390. T0 = [sin(2*pi*nf*pst{i}(:)) cos(2*pi*nf*pst{i}(:))];
  391. T = T - T0*pinv(T0)*T;
  392. end
  393. % Hanning operator (if requested)
  394. %----------------------------------------------------------------------
  395. if Han
  396. W = sparse(1:Nb(i),1:Nb(i),spm_hanning(Nb(i)));
  397. else
  398. W = 1;
  399. end
  400. % get trials or conditions
  401. %----------------------------------------------------------------------
  402. try
  403. trial = D{i}.inv{D{i}.val}.inverse.trials;
  404. catch
  405. trial = D{i}.condlist;
  406. end
  407. Nt(i) = length(trial);
  408. % get temporal covariance (Y'*Y) to find temporal modes
  409. %======================================================================
  410. MY = cell(Nmod,1); % mean response
  411. YTY = sparse(0); % accumulator
  412. for m = 1:Nmod % loop over modalities
  413. % get (spatially aligned) data
  414. %------------------------------------------------------------------
  415. N = 0;
  416. YY = 0;
  417. MY{m} = 0;
  418. for j = 1:Nt(i) % pool over conditions
  419. c = D{i}.indtrial(trial{j}); % and trials
  420. Nk = length(c);
  421. for k = 1:Nk
  422. Y = A{i,m}*D{i}(Ic{i,m},It{i},c(k));
  423. MY{m} = MY{m} + Y;
  424. YY = YY + Y'*Y;
  425. N = N + Nb(i);
  426. end
  427. end
  428. % Apply any Hanning and filtering
  429. %------------------------------------------------------------------
  430. YY = W'*YY*W;
  431. YY = T'*YY*T;
  432. % Scale data (to remove subject and modality scaling differences)
  433. %------------------------------------------------------------------
  434. scale(i,m) = sign(trace(MY{m}'*(UL{m}*UL{1}')*MY{1}));
  435. scale(i,m) = scale(i,m)/sqrt(trace(YY)/(Nm(m)*N));
  436. YTY = YTY + YY*(scale(i,m)^2);
  437. end
  438. % temporal projector (at most Nmax modes) S = T*V
  439. %======================================================================
  440. if STAT % Stationarity assumption
  441. S{i} = T; % temporal modes
  442. Nr(i) = size(T,2); % number of temporal modes
  443. VE(i) = 1; % variance explained
  444. else
  445. [U,E] = spm_svd(YTY,exp(-8)); % get temporal modes
  446. E = diag(E)/trace(YTY); % normalise variance
  447. Nr(i) = min(length(E),Nmax); % number of temporal modes
  448. S{i} = T*U(:,1:Nr(i)); % temporal modes
  449. VE(i) = sum(E(1:Nr(i))); % variance explained
  450. end
  451. fprintf('Using %i temporal modes for subject %i, ',Nr(i),i)
  452. fprintf('accounting for %0.2f percent average variance\n',full(100*VE(i)))
  453. % whitening
  454. %----------------------------------------------------------------------
  455. Vq{i} = S{i}*inv(S{i}'*qV{i}*S{i})*S{i}'; % temporal precision
  456. % get spatial covariance (Y*Y') for Gaussian process model.
  457. %======================================================================
  458. % loop over Nt trial types
  459. %----------------------------------------------------------------------
  460. UYYU{i} = 0;
  461. for j = 1:Nt(i)
  462. UY{i,j} = sparse(0);
  463. c = D{i}.indtrial(trial{j});
  464. Nk = length(c);
  465. % loop over epochs
  466. %------------------------------------------------------------------
  467. for k = 1:Nk
  468. % stack (scaled aligned data) over modalities
  469. %--------------------------------------------------------------
  470. for m = 1:Nmod
  471. Y = D{i}(Ic{i,m},It{i},c(k))*S{i};
  472. MY{m} = A{i,m}*Y*scale(i,m)/Nk;
  473. end
  474. % accumulate first & second-order responses
  475. %--------------------------------------------------------------
  476. Nn(i) = Nn(i) + Nr(i); % number of samples
  477. Y = spm_cat(MY); % contribution to ERP
  478. YY = Y*Y'; % and covariance
  479. % accumulate statistics (subject-specific)
  480. %--------------------------------------------------------------
  481. UY{i,j} = UY{i,j} + Y; % condition-specific ERP
  482. UYYU{i} = UYYU{i} + YY; % subject-specific covariance
  483. % and pool for optimisation of spatial priors over subjects
  484. %--------------------------------------------------------------
  485. AY{end + 1} = Y; % pooled response for MVB
  486. AYYA = AYYA + YY; % pooled response for ReML
  487. end
  488. end
  489. end
  490. % and concatenate for optimisation of spatial priors over subjects
  491. %--------------------------------------------------------------------------
  492. AY = spm_cat(AY); % pooled response for MVB
  493. UL = spm_cat(UL); % pooled lead fields
  494. % generate sensor error components (Qe)
  495. %==========================================================================
  496. AQ{1} = sparse(0);
  497. for m = 1:Nmod
  498. Qe{m} = sparse(0);
  499. end
  500. % assuming equal noise over subjects (Qe{m}) and modalities AQ
  501. %--------------------------------------------------------------------------
  502. N = cell(Nmod,Nmod);
  503. for i = 1:Nl
  504. for m = 1:Nmod
  505. N{m,m} = sparse(Nm(m),Nm(m));
  506. end
  507. for m = 1:Nmod
  508. Q = N;
  509. AQeA = A{i,m}*QE{i,m}*A{i,m}';
  510. Q{m,m} = AQeA/(trace(AQeA)/Nm(m));
  511. Q = spm_cat(Q)/Nl;
  512. Qe{m} = Qe{m} + Q;
  513. AQ{1} = AQ{1} + Q;
  514. end
  515. end
  516. %==========================================================================
  517. % Step 1: Optimise spatial priors over subjects
  518. %==========================================================================
  519. % create source components (Qp)
  520. %==========================================================================
  521. switch(type)
  522. case {'MSP','GS','ARD','BMR'}
  523. % create MSP spatial basis set in source space
  524. %------------------------------------------------------------------
  525. Qp = {};
  526. LQpL = {};
  527. LQL = {};
  528. Ip = ceil([1:Np]*Ns/Np);
  529. for i = 1:Np
  530. % left hemisphere
  531. %--------------------------------------------------------------
  532. q = QG(:,Ip(i));
  533. Qp{end + 1}.q = q;
  534. LQpL{end + 1}.q = UL*q;
  535. % right hemisphere
  536. %--------------------------------------------------------------
  537. [d j] = min(sum([vert(:,1) + vert(Ip(i),1), ...
  538. vert(:,2) - vert(Ip(i),2), ...
  539. vert(:,3) - vert(Ip(i),3)].^2,2));
  540. q = QG(:,j);
  541. Qp{end + 1}.q = q;
  542. LQpL{end + 1}.q = UL*q;
  543. % bilateral
  544. %--------------------------------------------------------------
  545. q = QG(:,Ip(i)) + QG(:,j);
  546. Qp{end + 1}.q = q;
  547. LQpL{end + 1}.q = UL*q;
  548. end
  549. case {'LOR','COH'}
  550. % create minimum norm prior
  551. %------------------------------------------------------------------
  552. Qp{1} = speye(Ns,Ns);
  553. LQpL{1} = UL*UL';
  554. % add smoothness component in source space
  555. %------------------------------------------------------------------
  556. Qp{2} = QG;
  557. LQpL{2} = UL*Qp{2}*UL';
  558. case {'IID','MMN'}
  559. % create minimum norm prior
  560. %------------------------------------------------------------------
  561. Qp{1} = speye(Ns,Ns);
  562. LQpL{1} = UL*UL';
  563. case {'EBB'}
  564. % create beamforming prior. See:
  565. % Source reconstruction accuracy of MEG and EEG Bayesian inversion approaches.
  566. % Belardinelli P, Ortiz E, Barnes G, Noppeney U, Preissl H. PLoS One. 2012;7(12):e51985.
  567. %------------------------------------------------------------------
  568. InvCov = spm_inv(YY);
  569. allsource = zeros(Ns,1);
  570. Sourcepower = zeros(Ns,1);
  571. for bk = 1:Ns
  572. normpower = 1/(UL(:,bk)'*UL(:,bk));
  573. Sourcepower(bk) = 1/(UL(:,bk)'*InvCov*UL(:,bk));
  574. allsource(bk) = Sourcepower(bk)./normpower;
  575. end
  576. allsource = allsource/max(allsource); % Normalise
  577. Qp{1} = diag(allsource);
  578. LQpL{1} = UL*diag(allsource)*UL';
  579. end
  580. % augment with exogenous (e.g., fMRI) source priors in pQ
  581. %==========================================================================
  582. for i = 1:length(pQ)
  583. switch(type)
  584. case {'MSP','GS','ARD','BMR'}
  585. %--------------------------------------------------------------
  586. if isvector(pQ{i}) && length(pQ{i}) == Ns
  587. Qp{end + 1}.q = pQ{i}(:);
  588. LQpL{end + 1}.q = UL*Qp{end}.q;
  589. else
  590. errordlg('Using MSP(GS/ARD) please supply spatial priors as vectors')
  591. return
  592. end
  593. case {'LOR','COH','IID','MMN'}
  594. %--------------------------------------------------------------
  595. if isvector(pQ{i}) && length(pQ{i}) == Ns
  596. pQ{i} = pQ{i}(:);
  597. Qp{end + 1} = sparse(diag(pQ{i}.^2));
  598. LQpL{end + 1} = UL*Qp{end}*UL';
  599. elseif size(pQ{i},1) == Ns && size(pQ{i},2) == Ns
  600. Qp{end + 1} = pQ{i};
  601. LQpL{end + 1} = UL*Qp{end}*UL';
  602. else
  603. errordlg('spatial priors are the wrong size')
  604. return
  605. end
  606. end
  607. end
  608. if ~isempty(pQ)
  609. fprintf('Using %d spatial source priors provided...\n',length(pQ));
  610. end
  611. % Inverse solution
  612. %==========================================================================
  613. QP = {};
  614. LQP = {};
  615. LQPL = {};
  616. % Get source-level priors (using all subjects)
  617. %--------------------------------------------------------------------------
  618. switch(type)
  619. case {'MSP','GS'}
  620. % Greedy search over MSPs
  621. %------------------------------------------------------------------
  622. Np = length(Qp);
  623. Q = sparse(Ns,Np);
  624. for i = 1:Np
  625. Q(:,i) = Qp{i}.q;
  626. end
  627. % Multivariate Bayes
  628. %------------------------------------------------------------------
  629. MVB = spm_mvb(AY,UL,[],Q,AQ,16);
  630. % Accumulate empirical priors
  631. %------------------------------------------------------------------
  632. Qcp = Q*MVB.cp;
  633. QP{end + 1} = sum(Qcp.*Q,2);
  634. LQP{end + 1} = (UL*Qcp)*Q';
  635. LQPL{end + 1} = LQP{end}*UL';
  636. end
  637. switch(type)
  638. case {'BMR'}
  639. % convert patterns into covariance components
  640. %------------------------------------------------------------------
  641. Np = length(Qp);
  642. for i = 1:Np
  643. LQpL{i} = LQpL{i}.q*LQpL{i}.q';
  644. end
  645. % hyperparameter estimation
  646. %------------------------------------------------------------------
  647. [C,h,Ph,F,Fa,Fc,Eh,Ch,hE,hC] = spm_reml_sc(AYYA,[],[Qe LQpL],sum(Nn),-16,32);
  648. % Bayesian model reduction
  649. %------------------------------------------------------------------
  650. DCM.M.pE = hE;
  651. DCM.M.pC = hC;
  652. DCM.Ep = Eh;
  653. DCM.Cp = Ch;
  654. h = spm_dcm_sparse(DCM);
  655. % Spatial priors (QP)
  656. %------------------------------------------------------------------
  657. Ne = length(Qe);
  658. Np = length(Qp);
  659. hp = h((1:Np) + Ne);
  660. qp = sparse(0);
  661. for i = 1:Np
  662. qp = qp + hp(i)*Qp{i}.q*Qp{i}.q';
  663. end
  664. % Accumulate empirical priors
  665. %------------------------------------------------------------------
  666. QP{end + 1} = diag(qp);
  667. LQP{end + 1} = UL*qp;
  668. LQPL{end + 1} = LQP{end}*UL';
  669. end
  670. switch(type)
  671. case {'MSP','ARD'}
  672. % ReML - ARD
  673. %------------------------------------------------------------------
  674. [C,h] = spm_sp_reml(AYYA,[],[Qe LQpL],sum(Nn));
  675. % Spatial priors (QP)
  676. %------------------------------------------------------------------
  677. Ne = length(Qe);
  678. Np = length(Qp);
  679. hp = h((1:Np) + Ne);
  680. qp = sparse(0);
  681. for i = 1:Np
  682. if hp(i) > max(hp)/128;
  683. qp = qp + hp(i)*Qp{i}.q*Qp{i}.q';
  684. end
  685. end
  686. % Accumulate empirical priors
  687. %------------------------------------------------------------------
  688. QP{end + 1} = diag(qp);
  689. LQP{end + 1} = UL*qp;
  690. LQPL{end + 1} = LQP{end}*UL';
  691. end
  692. switch(type)
  693. case {'IID','MMN','LOR','COH','EBB'}
  694. % or ReML - ARD
  695. %------------------------------------------------------------------
  696. Q0 = exp(-2)*trace(AYYA)/sum(Nn)*AQ{1}/trace(AQ{1});
  697. [C,h] = spm_reml_sc(AYYA,[],[Qe LQpL],sum(Nn),-4,16,Q0);
  698. % Spatial priors (QP)
  699. %------------------------------------------------------------------
  700. Ne = length(Qe);
  701. Np = length(Qp);
  702. hp = h((1:Np) + Ne);
  703. qp = sparse(0);
  704. for i = 1:Np
  705. qp = qp + hp(i)*Qp{i};
  706. end
  707. % Accumulate empirical priors
  708. %------------------------------------------------------------------
  709. QP{end + 1} = diag(qp);
  710. LQP{end + 1} = UL*qp;
  711. LQPL{end + 1} = LQP{end}*UL';
  712. end
  713. %==========================================================================
  714. % Step 2: Re-estimate for each subject separately (fusing all modalities)
  715. %==========================================================================
  716. for i = 1:Nl
  717. fprintf('Inverting subject %i\n',i)
  718. % generate sensor component (Qe) per modality
  719. %----------------------------------------------------------------------
  720. AQ = 0;
  721. Qe = {};
  722. for m = 1:Nmod
  723. N{m,m} = sparse(Nm(m),Nm(m));
  724. end
  725. for m = 1:Nmod
  726. Q = N;
  727. AQeA = A{i,m}*QE{i,m}*A{i,m}';
  728. Q{m,m} = AQeA/(trace(AQeA)/Nm(m));
  729. Qe{m} = spm_cat(Q);
  730. AQ = AQ + Qe{m};
  731. end
  732. % using spatial priors from group analysis
  733. %----------------------------------------------------------------------
  734. Np = length(LQPL);
  735. Ne = length(Qe);
  736. Q = [Qe LQPL];
  737. % re-do ReML (with informative hyperpriors)
  738. %======================================================================
  739. Q0 = exp(-2)*trace(UYYU{i})/Nn(i)*AQ/trace(AQ);
  740. [Cy,h,Ph,F] = spm_reml_sc(UYYU{i},[],Q,Nn(i),-4,16,Q0);
  741. % Data ID
  742. %----------------------------------------------------------------------
  743. ID = spm_data_id(AYYA);
  744. % Covariance: sensor space - Ce and source space - L*Cp
  745. %----------------------------------------------------------------------
  746. Cp = sparse(0);
  747. LCp = sparse(0);
  748. hp = h(Ne + (1:Np));
  749. for j = 1:Np
  750. Cp = Cp + hp(j)*QP{j};
  751. LCp = LCp + hp(j)*LQP{j};
  752. end
  753. % MAP estimates of instantaneous sources
  754. %======================================================================
  755. M = LCp'/Cy;
  756. % conditional variance (leading diagonal)
  757. % Cq = Cp - Cp*L'*iC*L*Cp;
  758. %----------------------------------------------------------------------
  759. Cq = Cp - sum(LCp.*M')';
  760. % evaluate conditional expectation (of the sum over trials)
  761. %----------------------------------------------------------------------
  762. SSR = 0;
  763. SST = 0;
  764. J = {};
  765. for j = 1:Nt(i)
  766. % trial-type specific source reconstruction
  767. %------------------------------------------------------------------
  768. J{j} = M*UY{i,j};
  769. % sum of squares
  770. %------------------------------------------------------------------
  771. SSR = SSR + sum(var(full(UY{i,j} - UL*J{j}),0,2));
  772. SST = SST + sum(var(full(UY{i,j}),0,2));
  773. end
  774. % accuracy; signal to noise (over sources)
  775. %======================================================================
  776. R2 = 100*(SST - SSR)/SST;
  777. fprintf('Percent variance explained %.2f (%.2f)\n',full(R2),full(R2*VE(i)));
  778. % Save results (for first modality)
  779. %======================================================================
  780. inverse.type = type; % inverse model
  781. inverse.smooth = s; % smoothness (0 - 1)
  782. inverse.xyz = xyz; % VOI (XYZ)
  783. inverse.rad = rad; % VOI (radius)
  784. inverse.scale = scale(i,:); % data scale-factor
  785. inverse.M = M; % MAP projector (reduced)
  786. inverse.J = J; % Conditional expectation
  787. inverse.Y = UY(i,:); % ERP data (reduced)
  788. inverse.L = UL; % Lead-field (reduced)
  789. inverse.qC = Cq; % spatial covariance
  790. inverse.qV = Vq{i}; % temporal correlations
  791. inverse.T = S{i}; % temporal projector
  792. inverse.U = A(i,:); % spatial projector
  793. inverse.Is = Is; % Indices of active dipoles
  794. inverse.It = It{i}; % Indices of time bins
  795. inverse.Ic = Ic(i,:); % Indices of good channels
  796. inverse.Nd = Nd; % number of dipoles
  797. inverse.pst = pst{i}; % peristimulus time
  798. inverse.dct = dct{i}; % frequency range
  799. inverse.F = F; % log-evidence
  800. inverse.ID = ID; % data ID
  801. inverse.R2 = R2; % variance explained (reduced)
  802. inverse.VE = R2*VE(i); % variance explained
  803. inverse.woi = w{i}; % time-window inverted
  804. inverse.modality = modalities; % modalities inverted
  805. % save in struct
  806. %----------------------------------------------------------------------
  807. D{i}.inv{D{i}.val}.inverse = inverse;
  808. D{i}.inv{D{i}.val}.method = 'Imaging';
  809. % and delete old contrasts
  810. %----------------------------------------------------------------------
  811. try
  812. D{i}.inv{D{i}.val} = rmfield(D{i}.inv{D{i}.val},'contrast');
  813. end
  814. % Display
  815. %======================================================================
  816. if ~spm('CmdLine'), spm_eeg_invert_display(D{i}); end
  817. end
  818. if length(D) == 1, D = D{1}; end
  819. fprintf('%-40s: %30s\n','Completed',spm('time')) %-#