spm_eeg_review.m 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. function spm_eeg_review(D,flag,inv)
  2. % General review (display) of SPM meeg object
  3. % FORMAT spm_eeg_review(D,flags,inv)
  4. %
  5. % INPUT:
  6. % D - meeg object
  7. % flag - switch to any of the displays (optional)
  8. % inv - which source reconstruction to display (when called from
  9. % spm_eeg_inv_imag_api.m)
  10. %__________________________________________________________________________
  11. % Copyright (C) 2008 Wellcome Trust Centre for Neuroimaging
  12. % Jean Daunizeau
  13. % $Id: spm_eeg_review.m 7221 2017-11-16 14:25:37Z vladimir $
  14. if nargin == 0
  15. [D, sts] = spm_select(1, 'mat$', 'Select M/EEG mat file');
  16. if ~sts, return; end
  17. D = spm_eeg_load(D);
  18. end
  19. %-- Initialize SPM figure
  20. D.PSD.handles.hfig = spm_figure('GetWin','Graphics');
  21. spm_clf(D.PSD.handles.hfig);
  22. % Get default SPM graphics options --> revert back to defaults
  23. D.PSD.SPMdefaults.col = get(D.PSD.handles.hfig,'colormap');
  24. D.PSD.SPMdefaults.renderer = get(D.PSD.handles.hfig,'renderer');
  25. %-- Create default userdata structure
  26. try
  27. D.PSD.source.VIZU.current = inv;
  28. end
  29. [D] = PSD_initUD(D);
  30. if ~strcmp(transformtype(D),'time') %
  31. D.PSD.type = 'epoched';
  32. D.PSD.trials.current = 1;
  33. D.PSD.VIZU.type = 2;
  34. end
  35. %-- Create figure uitabs
  36. labels = {'EEG', 'MEG', 'MPLANAR', 'MCOMB', 'OTHER','info','source'};
  37. callbacks = {'spm_eeg_review_callbacks(''visu'',''main'',''eeg'')',...
  38. 'spm_eeg_review_callbacks(''visu'',''main'',''meg'')',...
  39. 'spm_eeg_review_callbacks(''visu'',''main'',''megplanar'')',...
  40. 'spm_eeg_review_callbacks(''visu'',''main'',''megcomb'')',...
  41. 'spm_eeg_review_callbacks(''visu'',''main'',''other'')',...
  42. 'spm_eeg_review_callbacks(''visu'',''main'',''info'')',...
  43. 'spm_eeg_review_callbacks(''visu'',''main'',''source'')'};
  44. try
  45. [h] = spm_uitab(D.PSD.handles.hfig,labels,callbacks,[],flag);
  46. catch
  47. [h] = spm_uitab(D.PSD.handles.hfig,labels,callbacks,[],6);
  48. end
  49. D.PSD.handles.tabs = h;
  50. % Add prepare and SAVE buttons
  51. object.type = 'buttons';
  52. object.list = 1;
  53. D = spm_eeg_review_uis(D,object);
  54. set(D.PSD.handles.BUTTONS.pop1,...
  55. 'deletefcn',@back2defaults)
  56. %-- Attach userdata to SPM graphics window
  57. Dtmp = rmfield(D,'PSD');
  58. D.PSD.D0 = Dtmp;
  59. %CP, some how, removing and adding a field in the object doesn't work directly...
  60. set(D.PSD.handles.hfig,...
  61. 'units','normalized',...
  62. 'color',[1 1 1],...
  63. 'userdata',D);
  64. try
  65. if ismac
  66. set(D.PSD.handles.hfig,'renderer','zbuffer');
  67. else
  68. set(D.PSD.handles.hfig,'renderer','OpenGL');
  69. end
  70. catch
  71. set(D.PSD.handles.hfig,'renderer','OpenGL');
  72. end
  73. try
  74. switch flag
  75. case 1
  76. spm_eeg_review_callbacks('visu','main','eeg')
  77. case 2
  78. spm_eeg_review_callbacks('visu','main','meg')
  79. case 3
  80. spm_eeg_review_callbacks('visu','main','megplanar')
  81. case 4
  82. spm_eeg_review_callbacks('visu','main','megcomb')
  83. case 5
  84. spm_eeg_review_callbacks('visu','main','other')
  85. case 6
  86. spm_eeg_review_callbacks('visu','main','info')
  87. case 7
  88. spm_eeg_review_callbacks('visu','main','source')
  89. end
  90. catch
  91. % Initilize display on 'info'
  92. spm_eeg_review_callbacks('visu','main','info')
  93. end
  94. %% Revert graphical properties of SPM figure back to normal
  95. function back2defaults(e1,e2)
  96. hf = spm_figure('FindWin','Graphics');
  97. D = get(hf,'userdata');
  98. try
  99. set(D.PSD.handles.hfig,'colormap',D.PSD.SPMdefaults.col);
  100. set(D.PSD.handles.hfig,'renderer',D.PSD.SPMdefaults.renderer);
  101. end
  102. %% initialization of the userdata structure
  103. function [D] = PSD_initUD(D)
  104. % This function initializes the userdata structure.
  105. %-- Check spm_uitable capability (JAVA compatibility) --%
  106. D.PSD.VIZU.uitable = spm_uitable;
  107. %-- Initialize time window basic info --%
  108. D.PSD.VIZU.xlim = [1,min([5e2,nsamples(D)])];
  109. D.PSD.VIZU.info = 4; % show history
  110. D.PSD.VIZU.fromTab = [];
  111. %-- Initialize trials info --%
  112. switch D.type
  113. %------ before epoching -----%
  114. case 'continuous'
  115. D.PSD.type = 'continuous';
  116. if ntrials(D) && ~isempty(events(D,1))
  117. Events = events(D);
  118. Nevents = length(Events);
  119. for i =1:Nevents
  120. if isempty(Events(i).duration)
  121. Events(i).duration = 0;
  122. end
  123. if isempty(Events(i).value)
  124. Events(i).value = '0';
  125. end
  126. if isempty(Events(i).type)
  127. Events(i).type = '0';
  128. end
  129. if ~ischar(Events(i).value)
  130. Events(i).value = num2str(Events(i).value);
  131. end
  132. if ~ischar(Events(i).type)
  133. Events(i).type = num2str(Events(i).type);
  134. end
  135. end
  136. %D = events(D,1,Events);
  137. end
  138. D.PSD.VIZU.type = 1;
  139. %------ after epoching -----%
  140. case 'single'
  141. D.PSD.type = 'epoched';
  142. nTrials = D.ntrials;
  143. D.PSD.trials.TrLabels = cell(nTrials,1);
  144. bTrials = badtrials(D);
  145. for i = 1:nTrials
  146. if any(i==bTrials)
  147. str = ' (bad)';
  148. else
  149. str = ' (not bad)';
  150. end
  151. D.PSD.trials.TrLabels{i} = [...
  152. 'Trial ',num2str(i),': ',char(conditions(D,i)) ,str];
  153. end
  154. D.PSD.trials.current = 1;
  155. D.PSD.VIZU.type = 1;
  156. case {'evoked','grandmean'}
  157. D.PSD.type = 'epoched';
  158. nTrials = D.ntrials;
  159. D.PSD.trials.TrLabels = cell(nTrials,1);
  160. for i = 1:nTrials
  161. D.PSD.trials.TrLabels{i} = [...
  162. 'Trial ',num2str(i),' (average of ',...
  163. num2str(repl(D,i)),' events): ',...
  164. char(conditions(D,i))];
  165. D = events(D,i,[]);
  166. end
  167. D.PSD.trials.current = 1;
  168. D.PSD.VIZU.type = 1;
  169. end
  170. %-- Initialize channel info --%
  171. nc = D.nchannels;
  172. D.PSD.EEG.I = indchantype(D,'EEG');
  173. D.PSD.MEG.I = sort(indchantype(D,'MEG'));
  174. D.PSD.MEGPLANAR.I = indchantype(D,'MEGPLANAR');
  175. D.PSD.MEGCOMB.I = indchantype(D,'MEGCOMB');
  176. D.PSD.other.I = setdiff(1:nc, ...
  177. [D.PSD.EEG.I(:);D.PSD.MEG.I(:);D.PSD.MEGPLANAR.I(:);D.PSD.MEGCOMB.I(:)]);
  178. %-- Get basic display variables (data range, offset,...)
  179. if ~isempty(D.PSD.EEG.I)
  180. set(D.PSD.handles.hfig,'userdata',D);
  181. figure(D.PSD.handles.hfig)
  182. [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.EEG.I);
  183. D.PSD.EEG.VIZU = out;
  184. else
  185. D.PSD.EEG.VIZU = [];
  186. end
  187. if ~isempty(D.PSD.MEG.I)
  188. set(D.PSD.handles.hfig,'userdata',D);
  189. figure(D.PSD.handles.hfig)
  190. [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.MEG.I);
  191. D.PSD.MEG.VIZU = out;
  192. else
  193. D.PSD.MEG.VIZU = [];
  194. end
  195. if ~isempty(D.PSD.MEGPLANAR.I)
  196. set(D.PSD.handles.hfig,'userdata',D);
  197. figure(D.PSD.handles.hfig)
  198. [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.MEGPLANAR.I);
  199. D.PSD.MEGPLANAR.VIZU = out;
  200. else
  201. D.PSD.MEGPLANAR.VIZU = [];
  202. end
  203. if ~isempty(D.PSD.MEGCOMB.I)
  204. set(D.PSD.handles.hfig,'userdata',D);
  205. figure(D.PSD.handles.hfig)
  206. [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.MEGCOMB.I);
  207. D.PSD.MEGCOMB.VIZU = out;
  208. else
  209. D.PSD.MEGCOMB.VIZU = [];
  210. end
  211. if ~isempty(D.PSD.other.I)
  212. set(D.PSD.handles.hfig,'userdata',D);
  213. figure(D.PSD.handles.hfig)
  214. [out] = spm_eeg_review_callbacks('get','VIZU',D.PSD.other.I);
  215. D.PSD.other.VIZU = out;
  216. else
  217. D.PSD.other.VIZU = [];
  218. end
  219. %-- Initialize inverse field info --%
  220. if isfield(D,'inv') && ~isempty(D.inv)
  221. isInv = zeros(length(D.inv),1);
  222. for i=1:length(D.inv)
  223. if isfield(D.inv{i},'inverse') && ...
  224. isfield(D.inv{i}, 'method') && ...
  225. strcmp(D.inv{i}.method,'Imaging')
  226. isInv(i) = 1;
  227. end
  228. end
  229. isInv = find(isInv);
  230. Ninv = length(isInv);
  231. if Ninv>=1
  232. labels = cell(Ninv,1);
  233. callbacks = cell(Ninv,1);
  234. F = zeros(Ninv,1);
  235. ID = zeros(Ninv,1);
  236. pst = [];
  237. for i=1:Ninv
  238. if ~isfield(D.inv{isInv(i)},'comment')
  239. D.inv{isInv(i)}.comment{1} = num2str(i);
  240. end
  241. if ~isfield(D.inv{isInv(i)},'date')
  242. D.inv{isInv(i)}.date(1,:) = '?';
  243. D.inv{isInv(i)}.date(2,:) = ' ';
  244. end
  245. if isfield(D.inv{isInv(i)}.inverse,'R2') ...
  246. && isnan(D.inv{isInv(i)}.inverse.R2)
  247. D.inv{isInv(i)}.inverse.R2 = [];
  248. end
  249. if isfield(D.inv{isInv(i)}.inverse, 'ID')
  250. ID(i) = D.inv{isInv(i)}.inverse.ID;
  251. else
  252. ID(i) = nan;
  253. end
  254. labels{i} = [D.inv{isInv(i)}.comment{1}];
  255. callbacks{i} = ['spm_eeg_review_callbacks(''visu'',''inv'',',num2str(i),')'];
  256. try
  257. F(i) = D.inv{isInv(i)}.inverse.F;
  258. pst = [pst;D.inv{isInv(i)}.inverse.pst(:)];
  259. catch
  260. continue
  261. end
  262. end
  263. if isempty(pst)
  264. Ninv = 0;
  265. else
  266. pst = unique(pst);
  267. end
  268. end
  269. else
  270. Ninv = 0;
  271. end
  272. if Ninv >= 1
  273. try
  274. if D.PSD.source.VIZU.current > Ninv
  275. D.PSD.source.VIZU.current = 1;
  276. end
  277. catch
  278. D.PSD.source.VIZU.current = 1;
  279. end
  280. D.PSD.source.VIZU.isInv = isInv;
  281. D.PSD.source.VIZU.pst = pst;
  282. D.PSD.source.VIZU.F = F;
  283. D.PSD.source.VIZU.ID = ID;
  284. D.PSD.source.VIZU.labels = labels;
  285. D.PSD.source.VIZU.callbacks = callbacks;
  286. D.PSD.source.VIZU.timeCourses = 1;
  287. else
  288. D.PSD.source.VIZU.current = 0;
  289. D.PSD.source.VIZU.isInv = [];
  290. D.PSD.source.VIZU.pst = [];
  291. D.PSD.source.VIZU.F = [];
  292. D.PSD.source.VIZU.labels = [];
  293. D.PSD.source.VIZU.callbacks = [];
  294. D.PSD.source.VIZU.timeCourses = [];
  295. end