Skip to content

Commit ad7129c

Browse files
authored
Merge pull request #11 from Hiyeri/master
GUI implementation of visualization improvements + plotting of seed voxel
2 parents 28ac20d + 5181efb commit ad7129c

File tree

3 files changed

+122
-59
lines changed

3 files changed

+122
-59
lines changed

libs/haufe/allplots_cortex_BS.m

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ function allplots_cortex_BS(cortex, data_in, colorlimits, cm, unit, smooth, prin
2525
end
2626
end
2727

28-
cortex.Vertices = cortex.Vertices(:, [2 1 3]);
29-
cortex.Vertices(:, 1) = -cortex.Vertices(:, 1);
28+
% coordinate transformation
29+
% cortex.Vertices = cortex.Vertices(:, [2 1 3]);
30+
% cortex.Vertices(:, 1) = -cortex.Vertices(:, 1);
3031

3132

3233
for iatl = 1:length(cortex.Atlas)

pop_roi_connectplot.m

Lines changed: 117 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,28 @@
1111
% 'sourcemodel' - [string] source model file
1212
%
1313
% Optional inputs:
14-
% 'measure' - ['psd'|'roipsd'|'trgc'|'crossspecimag'|'crossspecpow'|'mic'|'mim']
15-
% 'psd' : Source power spectrum
16-
% 'psdroi': ROI based power spectrum
17-
% 'trgc' : Time-reversed granger causality
18-
% 'crossspecimag': Imaginary part of coherence from cross-spectrum
19-
% 'crossspecpow' : Average cross-spectrum power for each ROI
20-
% 'mic' : Maximized Imaginary Coherency for each ROI
21-
% 'mim' : Multivariate Interaction Measure for each ROI
22-
% 'freqrange' - [min max] frequency range in Hz. Default is to plot
23-
% broadband power.
24-
% 'smooth' - [float] smoothing factor for cortex surface plotting
25-
% 'plotcortex' - ['on'|'off'] plot results on smooth cortex. Default is 'on'
26-
% 'plotmatrix' - ['on'|'off'] plot results on smooth cortex. Default is 'off'
27-
% 'plotpsd' - ['on'|'off'] plot PSD (for 'crossspecpow' only). Default is 'off'
14+
% 'measure' - ['psd'|'roipsd'|'trgc'|'crossspecimag'|'crossspecpow'|'mic'|'mim']
15+
% 'psd' : Source power spectrum
16+
% 'psdroi': ROI based power spectrum
17+
% 'trgc' : Time-reversed granger causality
18+
% 'gc' : Granger causality
19+
% 'crossspecimag': Imaginary part of coherence from cross-spectrum
20+
% 'crossspecpow' : Average cross-spectrum power for each ROI
21+
% 'mic' : Maximized Imaginary Coherency for each ROI
22+
% 'mim' : Multivariate Interaction Measure for each ROI
23+
% 'freqrange' - [min max] frequency range in Hz. Default is to plot broadband power.
24+
% 'smooth' - [float] smoothing factor for cortex surface plotting
25+
% 'plotcortex' - ['on'|'off'] plot results on smooth cortex. Default is 'on'
26+
% 'plotcortexparams' - [cell] ...
27+
% 'plotcortexseedregion' - [string] plot seed voxel on cortex. Takes name of seed region as input.
28+
% 'plot3d' - ['on'|'off'] ... Default is 'off'
29+
% 'plot3dparams' - [cell] ...
30+
% 'plotmatrix' - ['on'|'off'] plot results as ROI to ROI matrix. Default is 'off'
31+
% 'plotbarplot' - ['on'|'off'] plot ROI based power spectrum as barplot. Default is 'off'
32+
% 'hemisphere' - ['all'|'left'|'right'] hemisphere options for ROI to ROI matrix. Default is 'all'
33+
% 'region' - ['all'|'cingulate'|'prefrontal'|'frontal'|'temporal'|'parietal'|'central'|'occipital'] region selection for ROI to ROI matrix. Default is 'all'
34+
% 'largeplot' - ['on'|'off'] plot MIM, TRGC and Power in a single large plot. Default is 'off'
35+
% 'plotpsd' - ['on'|'off'] plot PSD (for 'crossspecpow' only). Default is 'off'
2836
%
2937
% Author: Stefan Haufe and Arnaud Delorme, 2019
3038
%
@@ -179,6 +187,7 @@
179187
splot(end ).matrix = -1;
180188
splot(end ).psd = 0;
181189
end
190+
182191

183192
if nargin < 2
184193

@@ -195,9 +204,10 @@
195204
' end;' ...
196205
'end;' ...
197206
'clear iField fieldTmp usrdat;' ];
198-
207+
208+
fcregions = {'all', 'cingulate', 'prefrontal', 'frontal', 'temporal', 'parietal', 'central', 'occipital'};
199209
plotrow = [1 1];
200-
uigeom = { [1 1] [1 1] 1 [1 1] plotrow plotrow plotrow plotrow };
210+
uigeom = { [1 1] [1 1] 1 [1 1] plotrow [5 3 2] [3.5 1.5 1 1] plotrow };
201211
uilist = {{ 'style' 'text' 'string' 'Select a measure to plot' 'fontweight' 'bold'} ...
202212
{ 'style' 'popupmenu' 'string' {splot.label} 'callback' cb_select 'value' 4 'tag' 'selection' } ...
203213
{ 'style' 'text' 'string' 'Frequency range in Hz [min max]:'} ...
@@ -210,9 +220,13 @@
210220
{ 'style' 'edit' 'string' '''thresholdper'', 0.8' 'tag' 'plot3dparams' } ...
211221
...
212222
{ 'style' 'checkbox' 'string' 'Connectivity of each area' 'tag' 'cortex' 'value' 1 } ...
213-
{ 'style' 'text' 'string' '' 'tag' 'cortexparams' } ...
223+
{ 'style' 'text' 'string' 'Index of seed region:' 'fontweight' 'bold' } ...
224+
{ 'style' 'edit' 'string' '' 'tag' 'seed_region'} ...
214225
...
215-
{ 'style' 'checkbox' 'string' 'Matrix representation' 'tag' 'matrix' 'enable' 'off' } {} ...
226+
{ 'style' 'checkbox' 'string' 'Matrix representation' 'tag' 'matrix' 'enable' 'off' } ...
227+
{ 'style' 'popupmenu' 'string' fcregions 'callback' cb_select 'value' 3 'tag' 'region' } ....
228+
{ 'style' 'checkbox' 'string' 'left' 'tag' 'hemisphere_left' 'value' 1 } ...
229+
{ 'style' 'checkbox' 'string' 'right' 'tag' 'hemisphere_right' 'value' 1 } ...
216230
...
217231
{ 'style' 'checkbox' 'string' 'Power spectral density' 'tag' 'psd' 'enable' 'off' } {} ...
218232
};
@@ -226,29 +240,40 @@
226240
options = { options{:} 'freqrange' eval( [ '[' result{2} ']' ] ) };
227241
options = { options{:} 'plotcortex' fastif(outs.cortex, 'on', 'off') };
228242
options = { options{:} 'plotcortexparams' {} };
243+
options = { options{:} 'plotcortexseedregion' str2num(result{6}) };
229244
options = { options{:} 'plotmatrix' fastif(outs.matrix, 'on', 'off') };
230245
options = { options{:} 'plotpsd' fastif(outs.psd , 'on', 'off') };
231246
options = { options{:} 'plot3d' fastif(outs.plot3d, 'on', 'off') };
232247
options = { options{:} 'plot3dparams' eval( [ '{' outs.plot3dparams '}' ] ) };
248+
options = { options{:} 'region' fcregions{result{8}} };
249+
% choose which hemisphere to plot
250+
if outs.hemisphere_left == 1 && outs.hemisphere_right == 0
251+
options = { options{:} 'hemisphere' 'left' };
252+
elseif outs.hemisphere_left == 0 && outs.hemisphere_right == 1
253+
options = { options{:} 'hemisphere' 'right' };
254+
else
255+
options = { options{:} 'hemisphere' 'all' };
256+
end
233257
else
234258
options = varargin;
235259
end
236260

237261
% decode input parameters
238262
% -----------------------
239263
g = finputcheck(options, { 'measure' 'string' {splot.acronym} '';
240-
'freqrange' 'real' { } [];
241-
'smooth' 'real' { } 0.35;
242-
'plotcortex' 'string' { 'on' 'off' } 'on';
243-
'plotcortexparams' 'cell' { } {};
244-
'plot3d' 'string' { 'on' 'off' } 'off';
245-
'plot3dparams' 'cell' { } {};
246-
'plotmatrix' 'string' { 'on' 'off' } 'off';
247-
'plotbarplot' 'string' { 'on' 'off'} 'off';
248-
'hemisphere' 'string' {'all' 'left' 'right'} 'all';
249-
'region' 'string' { 'all', 'cingulate', 'prefrontal', 'frontal', 'temporal', 'parietal', 'central', 'occipital' } 'all';
250-
'largeplot', 'string' { 'on' 'off' } 'off';
251-
'plotpsd', 'string' { 'on' 'off' } 'off' }, 'pop_roi_connectplot');
264+
'freqrange' 'real' { } [];
265+
'smooth' 'real' { } 0.35;
266+
'plotcortex' 'string' { 'on' 'off' } 'on';
267+
'plotcortexparams' 'cell' { } {};
268+
'plotcortexseedregion' 'integer' { } [];
269+
'plot3d' 'string' { 'on' 'off' } 'off';
270+
'plot3dparams' 'cell' { } {};
271+
'plotmatrix' 'string' { 'on' 'off' } 'off';
272+
'plotbarplot' 'string' { 'on' 'off'} 'off';
273+
'hemisphere' 'string' {'all' 'left' 'right'} 'all';
274+
'region' 'string' { 'all', 'cingulate', 'prefrontal', 'frontal', 'temporal', 'parietal', 'central', 'occipital' } 'all';
275+
'largeplot', 'string' { 'on' 'off' } 'off';
276+
'plotpsd', 'string' { 'on' 'off' } 'off' }, 'pop_roi_connectplot');
252277
if ischar(g), error(g); end
253278
S = EEG.roi;
254279

@@ -285,7 +310,7 @@
285310
MI = get_connect_mat( MI, S.nROI, +1);
286311
MIM_matrix = squeeze(mean(MI(frq_inds, :, :)));
287312

288-
pltlarge(EEG, MIM_matrix, TRGC_matrix, source_roi_power_norm_dB, titleStr)
313+
roi_largeplot(EEG, MIM_matrix, TRGC_matrix, source_roi_power_norm_dB, titleStr)
289314
else
290315
switch lower(g.measure)
291316
case { 'psd' 'roipsd' }
@@ -307,28 +332,28 @@
307332

308333
if strcmpi(g.plotbarplot, 'on')
309334
source_roi_power_norm_dB = 10*log10( mean(EEG.roi.source_roi_power(frq_inds,:)) );
310-
pltmatrix(EEG, source_roi_power_norm_dB, titleStr, g.measure, g.hemisphere, g.region);
335+
roi_plotcoloredlobes(EEG, source_roi_power_norm_dB, titleStr, g.measure, g.hemisphere, g.region);
311336
end
312337

313338
case { 'trgc' 'gc' }
314339
% calculation of net TRGC scores (i->j minus j->i), recommended procedure
315340
% TRGCnet = TRGC_(:, 1:2:end)-TRGC_(:, 2:2:end);
316341
% new way to compute net scores
317342
if strcmpi(g.measure, 'GC')
318-
% TRGCnet = S.GC;
343+
% TRGCnet = S.GC;
319344
TRGCnet = S.GC(:, :, 1) - S.GC(:, :, 2);
320345
else
321-
% TRGCnet = S.TRGC;
346+
% TRGCnet = S.TRGC;
322347
TRGCnet = S.TRGC(:, :, 1) - S.TRGC(:, :, 2);
323348
end
324349
% TRGCnet = TRGCnet - permute(TRGCnet, [1 3 2]);
325350
% TRGCnet = TRGCnet(:,:);
326-
% TRGCnet = S.GC(:, :, 1) - S.GC(:, :, 2);
351+
% TRGCnet = S.GC(:, :, 1) - S.GC(:, :, 2);
327352
TRGC = get_connect_mat( TRGCnet, S.nROI, -1);
328353

329354
if strcmpi(g.plotmatrix, 'on')
330355
matrix = squeeze(mean(TRGC(frq_inds, :, :)));
331-
pltmatrix(EEG, matrix, titleStr, g.measure, g.hemisphere, g.region);
356+
roi_plotcoloredlobes(EEG, matrix, titleStr, g.measure, g.hemisphere, g.region);
332357
end
333358

334359
if strcmpi(g.plot3d, 'on')
@@ -337,8 +362,16 @@
337362
end
338363

339364
if strcmpi(g.plotcortex, 'on')
340-
atrgc = mean(squeeze(mean(TRGC(frq_inds, :, :))), 2);
341-
allplots_cortex_BS(S.cortex, atrgc, [-max(abs(atrgc)) max(abs(atrgc))], cm17, upper(g.measure), g.smooth);
365+
if isempty(g.plotcortexseedregion)
366+
atrgc = mean(squeeze(mean(TRGC(frq_inds, :, :))), 2);
367+
allplots_cortex_BS(S.cortex, atrgc, [-max(abs(atrgc)) max(abs(atrgc))], cm17, upper(g.measure), g.smooth);
368+
movegui(gcf, 'south')
369+
else
370+
[coordinate, seed_idx] = get_seedregion_coordinate(EEG.roi.atlas.Scouts, g.plotcortexseedregion, EEG.roi.cortex.Vertices);
371+
atrgc = squeeze(mean(TRGC(frq_inds, seed_idx, :)));
372+
allplots_cortex_BS(S.cortex, atrgc, [-max(abs(atrgc)) max(abs(atrgc))], cm17, upper(g.measure), g.smooth, [], {coordinate});
373+
movegui(gcf, 'south')
374+
end
342375
h = textsc([ upper(g.measure) ' (' titleStr '); Red = net sender; Blue = net receiver' ], 'title');
343376
set(h, 'fontsize', 20);
344377
end
@@ -353,13 +386,19 @@
353386

354387
if strcmpi(g.plotmatrix, 'on')
355388
matrix = squeeze(mean(MI(frq_inds, :, :)));
356-
pltmatrix(EEG, matrix, titleStr, g.measure, g.hemisphere, g.region);
389+
roi_plotcoloredlobes(EEG, matrix, titleStr, g.measure, g.hemisphere, g.region);
357390
end
358391

359392
if strcmpi(g.plotcortex, 'on')
360-
ami = mean(squeeze(mean(MI(frq_inds, :, :))), 2);
361-
allplots_cortex_BS(S.cortex, ami, [min(ami) max(ami)], cm17, upper(g.measure), g.smooth);
362-
h = textsc([ upper(g.measure) ' (' titleStr '); Red = net sender; Blue = net receiver' ], 'title');
393+
if isempty(g.plotcortexseedregion)
394+
ami = mean(squeeze(mean(MI(frq_inds, :, :))), 2);
395+
allplots_cortex_BS(S.cortex, ami, [min(ami) max(ami)], cm17a, upper(g.measure), g.smooth);
396+
else
397+
[coordinate, seed_idx] = get_seedregion_coordinate(EEG.roi.atlas.Scouts, g.plotcortexseedregion, EEG.roi.cortex.Vertices);
398+
ami = squeeze(mean(MI(frq_inds, seed_idx,:)));
399+
allplots_cortex_BS(S.cortex, ami, [min(ami) max(ami)], cm17a, upper(g.measure), g.smooth, [], {coordinate});
400+
end
401+
h = textsc([ upper(g.measure) ' (' titleStr ') '], 'title');
363402
set(h, 'fontsize', 20);
364403
end
365404

@@ -427,9 +466,32 @@
427466
end
428467
end
429468
end
469+
470+
function [coordinate, seed_idx] = get_seedregion_coordinate(scouts, seed_idx, vc)
471+
% determine voxel of selected seed region, if needed
472+
% assign region index to selected seed region (passed as index)
473+
if ~isempty(seed_idx)
474+
% ball not visible for these regions when plotting the mean voxel
475+
manual_region_idxs = [2, 16, 18, 25, 26, 31, 32, 45, 49, 50, 55, 56, 59, 60, 61, 64];
476+
pos_idx = scouts(seed_idx).Vertices;
477+
pos = vc(pos_idx,:);
478+
if seed_idx == 1
479+
coordinate = vc(736,:);
480+
elseif ismember(seed_idx, manual_region_idxs)
481+
pos_sorted = sortrows(pos, 3, 'descend'); % sort by descending Z-coordinate
482+
coordinate = pos_sorted(1,:);
483+
else
484+
mid_point = mean(pos,1);
485+
[~,closest_pos_idx] = min(eucl(mid_point, pos)); % determine mean voxel
486+
coordinate = pos(closest_pos_idx,:);
487+
end
488+
else
489+
error('Selected region not in cortex')
490+
end
491+
end
430492

431-
function pltmatrix( EEG, matrix, titleStr, measure, hemisphere, region)
432-
% plot individual ROI to ROI matrix with colored labels (corresponding lobes/regions)
493+
function roi_plotcoloredlobes( EEG, matrix, titleStr, measure, hemisphere, region)
494+
% plot matrix with colored labels sorted by region according to the Desikan-Killiany atlas
433495
load cm17
434496
switch lower(measure)
435497
case {'mim', 'mic', 'coh'}
@@ -438,7 +500,7 @@ function pltmatrix( EEG, matrix, titleStr, measure, hemisphere, region)
438500
cmap = cm17;
439501
end
440502

441-
% plot matrix with colored labels sorted by region according to the Desikan-Killiany atlas
503+
% retrieve labels from atlas
442504
labels = strings(1,length(EEG.roi.atlas.Scouts));
443505
for i = 1:length(labels)
444506
scout = struct2cell(EEG.roi.atlas.Scouts(i));
@@ -514,6 +576,15 @@ function pltmatrix( EEG, matrix, titleStr, measure, hemisphere, region)
514576
color_idxx = color_idxx(start_idx:end_idx);
515577
end
516578
n_roi_labels = size(matrix, 1); % only 68 if no region is selected
579+
580+
% hemisphere parameters to determine which labels to use
581+
if strcmpi(hemisphere, 'left')
582+
hem_idx = {1 2 2}; % use labels 1:2:68 (first two values), only use 1/2 of the labels (3rd value)
583+
elseif strcmpi(hemisphere, 'right')
584+
hem_idx = {2 2 2}; % use labels 2:2:68 (first two values), only use 1/2 of the labels (3rd value)
585+
else
586+
hem_idx = {1 1 1}; % use labels 1:1:68 (first two values, all labels), use 1/1 of the labels (3rd value, all labels)
587+
end
517588

518589
% create dummy plot and add custom legend
519590
f = figure();
@@ -525,15 +596,6 @@ function pltmatrix( EEG, matrix, titleStr, measure, hemisphere, region)
525596
plot(x, x*k, '-', 'LineWidth', 9, 'Color', colors{k});
526597
end
527598

528-
% hemisphere parameters to determine which labels to use
529-
if strcmpi(hemisphere, 'left')
530-
hem_idx = {1 2 2}; % use labels 1:2:68 (first two values), only use 1/2 of the labels (3rd value)
531-
elseif strcmpi(hemisphere, 'right')
532-
hem_idx = {2 2 2}; % use labels 2:2:68 (first two values), only use 1/2 of the labels (3rd value)
533-
else
534-
hem_idx = {1 1 1}; % use labels 1:1:68 (first two values, all labels), use 1/1 of the labels (3rd value, all labels)
535-
end
536-
537599
% labels on dummy plot for positioning
538600
xlim([0 n_roi_labels])
539601
ylim([0 n_roi_labels])
@@ -575,7 +637,7 @@ function pltmatrix( EEG, matrix, titleStr, measure, hemisphere, region)
575637
end
576638
end
577639

578-
function pltlarge(EEG, mim, trgc, roipsd, titleStr)
640+
function roi_largeplot(EEG, mim, trgc, roipsd, titleStr)
579641
% plot MIM, TRGC and power (barplot) in a single large figure
580642
load cm17
581643

roi_connect.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@
8787
end
8888
end
8989

90-
% MIC and MIM use a different function
91-
if ismember(g.methods, 'MIC') || ismember(g.methods, 'MIM')
90+
% % MIC and MIM use a different function
91+
if any(ismember(g.methods, 'MIC')) || any(ismember(g.methods, 'MIM'))
9292
tmpMethods = setdiff(g.methods, { 'CS' 'COH' 'PSD' 'PSDROI' 'GC' 'TRGC' 'wPLI' 'PDC' 'TRPDC' 'DTF' 'TRDTF' });
9393
conn_mult = data2sctrgcmim(source_roi_data, EEG.srate, g.morder, 0, g.naccu, [], inds, tmpMethods);
9494
fields = fieldnames(conn_mult);

0 commit comments

Comments
 (0)