Skip to content

Commit e80177f

Browse files
authored
Merge pull request #78 from nguyen-td/master
GUI update, PAC p-value plots
2 parents 7721a73 + a8f19db commit e80177f

5 files changed

Lines changed: 81 additions & 45 deletions

File tree

pop_roi_connect.m

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,24 +125,28 @@
125125

126126
rowg = [0.1 0.6 1 0.2];
127127
% uigeom = { 1 1 rowg rowg 1 rowg rowg [0.1 0.6 0.9 0.3] 1 rowg 1 [0.5 1 0.35 0.5] [0.5 1 0.35 0.5] [0.5 1 0.35 0.5] [1] [0.9 1.2 1] };
128-
uigeom = { [1] [1.2 1] [1.2 1] [1.2 1] [1.2 1] [1.2 1] [1.2 1] [1.2 1] [1] [0.2 1 0.35 0.8] [0.2 1 0.35 0.8] };
128+
uigeom = { [1] [1.2 1] [1.2 1] [1.2 1] [1.2 1] [1.2 1] [1.2 1] [1.2 1] [1.2 1] [1] [0.2 1 0.35 0.8] [0.2 1 0.35 0.8] [0.2 1 0.35 0.8] [0.2 1 0.35 0.8]};
129129
uilist = { { 'style' 'text' 'string' 'Select connectivity measures' 'fontweight' 'bold' } ...
130-
{ 'style' 'checkbox' 'string' 'Cross-spectrum' 'tag' 'cs' 'value' 1 } {} ...
131-
{'style' 'checkbox' 'string' '(Complex-valued) Coherency' 'tag' 'ccoh' 'value' 0 } ...
132-
{ 'style' 'checkbox' 'string' 'Coherence' 'tag' 'acoh' 'value' 0 } ...
133-
{ 'style' 'checkbox' 'string' 'Imaginary Coherency' 'tag' 'icoh' 'value' 0 } ...
134-
{ 'style' 'checkbox' 'string' 'Weighted Phase Lag Index' 'tag' 'wpli' 'value' 0 } ...
130+
{ 'style' 'checkbox' 'string' 'Cross-spectrum (CS)' 'tag' 'cs' 'value' 1 } {} ...
131+
{'style' 'checkbox' 'string' '(Complex-valued) Coherency (cCOH)' 'tag' 'ccoh' 'value' 0 } ...
132+
{ 'style' 'checkbox' 'string' 'Coherence (aCOH)' 'tag' 'acoh' 'value' 0 } ...
133+
{ 'style' 'checkbox' 'string' 'Imaginary Coherency (iCOH)' 'tag' 'icoh' 'value' 0 } ...
134+
{ 'style' 'checkbox' 'string' 'Weighted Phase Lag Index (wPLI)' 'tag' 'wpli' 'value' 0 } ...
135135
{ 'style' 'checkbox' 'string' 'Granger Causality (GC)' 'tag' 'gc' 'value' 0 } ...
136136
{ 'style' 'checkbox' 'string' 'Time-reversed GC' 'tag' 'trgc' 'value' 0 } ...
137137
{ 'style' 'checkbox' 'string' 'Partial Directed Coherence (PDC)' 'tag' 'pdc' 'value' 0 } ...
138138
{ 'style' 'checkbox' 'string' 'Time-reversed PDC' 'tag' 'trpdc' 'value' 0 } ...
139139
{ 'style' 'checkbox' 'string' 'Directed Transfer Entropy (DTF)' 'tag' 'dtf' 'value' 0 } ...
140140
{ 'style' 'checkbox' 'string' 'Time-reversed DTF' 'tag' 'trdtf' 'value' 0 } ...
141-
{ 'style' 'checkbox' 'string' 'Multivariate Interaction Measure' 'tag' 'mim' 'value' 0 } ...
142-
{ 'style' 'checkbox' 'string' 'Maximized Imaginary Coherency' 'tag' 'mic' 'value' 0 } ...
141+
{ 'style' 'checkbox' 'string' 'Multivariate Interaction Measure (MIM)' 'tag' 'mim' 'value' 0 } ...
142+
{ 'style' 'checkbox' 'string' 'Maximized Imaginary Coherency (MIC)' 'tag' 'mic' 'value' 0 } ...
143+
{ 'style' 'checkbox' 'string' 'Phase-Amplitude Coupling (PAC)' 'tag' 'pac' 'value' 0 } ...
144+
{ 'style' 'checkbox' 'string' 'Time Delay Estimation (TDE)' 'tag' 'tde' 'value' 0 } ...
143145
{} ...
144146
{} { 'style' 'text' 'string' 'Autoregressive model order' } { 'style' 'edit' 'string' '20' 'tag' 'morder' } {} ...
145-
{} { 'style' 'text' 'string' 'Bootstrap if any (n)' } { 'style' 'edit' 'string' '' 'tag' 'naccu2' } {} };
147+
{} { 'style' 'text' 'string' 'Bootstrap if any (n)' } { 'style' 'edit' 'string' '' 'tag' 'naccu2' } {} ...
148+
{} { 'style' 'text' 'string' 'Frequency combination in Hz (for PAC) [f1 f2]' } { 'style' 'edit' 'string' '' 'tag' 'fcomb' } {} ...
149+
{} { 'style' 'text' 'string' 'Region selection by index (for TDE) [region1 region2]' } { 'style' 'edit' 'string' '' 'tag' 'tde_regions' } {} };
146150
...
147151
[result,~,~,out] = inputgui('geometry', uigeom, 'uilist', uilist, 'helpcom', 'pophelp(''pop_roi_connect'')', 'title', 'pop_roiconnect - connectivity');
148152
if isempty(result), return, end
@@ -163,10 +167,19 @@
163167
if out.trdtf, methods = [ methods { 'TRDTF' } ]; end
164168
if out.mim , methods = [ methods { 'MIM' } ]; end
165169
if out.mic, methods = [ methods { 'MIC' } ]; end
170+
if out.pac, methods = [ methods { 'PAC' } ]; end
171+
if out.tde, methods = [ methods { 'TDE' } ]; end
166172
options = { ...
167173
'morder' str2num(out.morder) ...
168174
'naccu' str2num(out.naccu2) ...
169-
'methods' methods };
175+
'methods' methods ...
176+
'tde_regions' eval( [ '[' out.tde_regions ']' ] )};
177+
if ~isempty(eval( [ '[' out.fcomb ']' ] ))
178+
out_fcomb = eval( [ '[' out.fcomb ']' ] );
179+
fcomb.low = out_fcomb(1);
180+
fcomb.high = out_fcomb(2);
181+
options = [options {'fcomb' fcomb}];
182+
end
170183
else
171184
options = varargin;
172185
end

pop_roi_connectplot.m

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@
158158
splot(end ).unit = 'aCOH';
159159
splot(end ).cortex = cortexFlag;
160160
splot(end ).matrix = 1;
161-
splot(end ).psd = 0;
161+
splot(end ).psd = -1;
162162
splot(end ).plot3d = plot3dFlag;
163163
end
164164

@@ -169,7 +169,7 @@
169169
splot(end ).unit = 'cCOH';
170170
splot(end ).cortex = cortexFlag;
171171
splot(end ).matrix = 1;
172-
splot(end ).psd = 0;
172+
splot(end ).psd = -1;
173173
splot(end ).plot3d = plot3dFlag;
174174
end
175175

@@ -180,7 +180,7 @@
180180
splot(end ).unit = 'iCOH';
181181
splot(end ).cortex = cortexFlag;
182182
splot(end ).matrix = 1;
183-
splot(end ).psd = 0;
183+
splot(end ).psd = -1;
184184
splot(end ).plot3d = plot3dFlag;
185185
end
186186

@@ -191,7 +191,7 @@
191191
splot(end ).unit = 'GC';
192192
splot(end ).cortex = cortexFlag;
193193
splot(end ).matrix = 1;
194-
splot(end ).psd = 0;
194+
splot(end ).psd = -1;
195195
splot(end ).plot3d = plot3dFlag;
196196
end
197197

@@ -202,7 +202,7 @@
202202
splot(end ).unit = 'TRGC'; % not used yet
203203
splot(end ).cortex = cortexFlag;
204204
splot(end ).matrix = 1;
205-
splot(end ).psd = 0;
205+
splot(end ).psd = -1;
206206
splot(end ).plot3d = plot3dFlag;
207207
end
208208

@@ -213,7 +213,7 @@
213213
splot(end ).unit = 'MIC'; % not used yet
214214
splot(end ).cortex = cortexFlag;
215215
splot(end ).matrix = -1;
216-
splot(end ).psd = 0;
216+
splot(end ).psd = -1;
217217
splot(end ).plot3d = plot3dFlag;
218218
end
219219

@@ -224,7 +224,7 @@
224224
splot(end ).unit = 'MIM'; % not used yet
225225
splot(end ).cortex = cortexFlag;
226226
splot(end ).matrix = 1;
227-
splot(end ).psd = 0;
227+
splot(end ).psd = -1;
228228
splot(end ).plot3d = plot3dFlag;
229229
end
230230

@@ -235,18 +235,18 @@
235235
splot(end ).unit = 'PAC'; % not used yet
236236
splot(end ).cortex = cortexFlag;
237237
splot(end ).matrix = 1;
238-
splot(end ).psd = 0;
238+
splot(end ).psd = -1;
239239
splot(end ).plot3d = plot3dFlag;
240240
end
241241

242242
if isfield(EEG.roi, 'PAC')
243-
splot(end+1).label = 'ROI to ROI Phase-amplitude coupling';
243+
splot(end+1).label = 'ROI to ROI Phase-amplitude coupling (antisymmetrized)';
244244
splot(end ).labelshort = 'Phase-amplitude coupling';
245245
splot(end ).acronym = 'PAC_anti'; % PAC based on antisymmetrized bicoherence
246246
splot(end ).unit = 'PAC'; % not used yet
247247
splot(end ).cortex = cortexFlag;
248248
splot(end ).matrix = 1;
249-
splot(end ).psd = 0;
249+
splot(end ).psd = -1;
250250
splot(end ).plot3d = plot3dFlag;
251251
end
252252

@@ -262,7 +262,7 @@
262262
end
263263

264264
if isfield(EEG.roi, 'TDE')
265-
splot(end+1).label = 'ROI to ROI Time-delay estimation';
265+
splot(end+1).label = 'ROI to ROI Time-delay estimation (antisymmetrized)';
266266
splot(end ).labelshort = 'Time-delay estimation';
267267
splot(end ).acronym = 'TDE_anti'; % TDE based on antisymmetrized bispectrum
268268
splot(end ).unit = 'TDE'; % not used yet
@@ -508,6 +508,7 @@
508508
error('PAC (original bicoherence) cannot be plotted, field is missing.')
509509
end
510510
cortexPlot = mean(matrix, 2);
511+
titleStr = sprintf('f1 = %1.1f Hz, f2 = %1.1f Hz', S.PAC.fcomb.low, S.PAC.fcomb.high);
511512

512513
case {'pac_anti'}
513514
if isfield(S.PAC, 'b_anti_norm')
@@ -518,6 +519,7 @@
518519
error('PAC (antisymmetrized bicoherence) cannot be plotted, field is missing.')
519520
end
520521
cortexPlot = mean(matrix, 2);
522+
titleStr = sprintf('f1 = %1.1f Hz, f2 = %1.1f Hz', S.PAC.fcomb.low, S.PAC.fcomb.high);
521523

522524
case {'tde' 'tde_anti'}
523525
if strcmpi(g.measure, 'tde')
@@ -591,7 +593,7 @@
591593
warning('Butterfly plots (frequency x connectivity) cannot be computed for PAC because frequencies have already been specified for the computation.')
592594
else
593595
figure; plot(EEG.roi.freqs, butterflyplot, 'LineWidth', 1)
594-
h = title([ 'ROI to ROI ' replace_underscores(g.measure) ' (' titleStr ')' ]);
596+
h = title([ 'ROI to ROI ' replace_underscores(g.measure)]);
595597
set(h, 'fontsize', 16);
596598
xlabel('Frequency (Hz)')
597599
ylabel([replace_underscores(g.measure) ' (a.u.)'])
@@ -970,8 +972,8 @@ function plot_tde(T, shift, region_X, region_Y, method)
970972
[~, peak_idx] = max(T);
971973
est_delay = shift(peak_idx); % in Hz
972974

973-
figure; plot(shift, T, 'LineWidth', 1)
974-
xline(est_delay, '--r')
975+
figure; plot(shift, T, 'black', 'LineWidth', 1)
976+
xline(est_delay, '--r', 'LineWidth', 1)
975977
xlabel('Time (s)')
976978
ylabel('a.u.')
977979
h = title(sprintf('%s -> %s TDE | Method %d', region_X, region_Y, method));

pop_roi_statsplot.m

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
% 'TRDTF' : Time-reversed directed transfer entropy
1818
% 'MIM' : Multivariate Interaction Measure for each ROI
1919
% 'MIC' : Maximized Imaginary Coherency for each ROI
20+
% 'PAC' : Phase Amplitude Coupling for each ROI
2021
% 'freqrange' - [min max] frequency range or [integer] single frequency in Hz. Default is to plot broadband power.
2122
% 'alpha' - [integer] Significance level. Default is 0.05.
23+
% 'bispec' - ['b_anti'|'b_orig'] Option to compute antisymmetric or original bispectrum.
2224
%
2325
% Author: Franziska Pellegrini, franziska.pellegrini@charite.de
2426
% Tien Dung Nguyen, tien-dung.nguyen@charite.de
27+
% Zixuan Liu, zixuan.liu@campus.tu-berlin.de
2528

2629
function EEG = pop_roi_statsplot(EEG, varargin)
2730

@@ -39,36 +42,51 @@
3942
g = finputcheck(varargin, {
4043
'measure' 'string' { } '';
4144
'freqrange' 'real' { } []; ...
42-
'alpha' 'integer' { } 0.05}, 'pop_roi_statsplot');
45+
'alpha' 'integer' { } 0.05; ...
46+
'bispec' 'string' {'b_orig', 'b_anti'} 'b_anti'}, 'pop_roi_statsplot');
4347
if ischar(g), error(g); end
44-
S = EEG.roi;
4548

49+
% check if measure is defined.
4650
if isempty(g.measure)
4751
error('You must define a measure to plot');
4852
end
49-
50-
% extract frequency indices
51-
if ~isempty(g.freqrange)
52-
if length(g.freqrange) == 1
53-
frq_inds = find(S.freqs == g.freqrange(1));
54-
title = sprintf('%1.1f Hz', g.freqrange(1));
53+
54+
% adjust based on measure, PAC has one less dimension.
55+
if strcmp(g.measure, 'PAC') % check if measure is PAC
56+
% for PAC, check the bispectrum parameter
57+
if isfield(EEG.roi.(g.measure), g.bispec)
58+
matrix = EEG.roi.(g.measure).(g.bispec); % use specified bispectrum field
5559
else
56-
frq_inds = find(S.freqs >= g.freqrange(1) & S.freqs < g.freqrange(2));
57-
title = sprintf('%1.1f-%1.1f Hz frequency band', g.freqrange(1), g.freqrange(2));
60+
error(['The specified bispectrum field (' g.bispec ') does not exist in EEG.roi.']);
5861
end
62+
5963
else
60-
frq_inds = 1:length(S.freqs);
61-
title = 'broadband';
62-
end
63-
64-
% select frequency or frequency band
65-
if length(frq_inds) > 1
66-
matrix = squeeze(mean(S.(g.measure)(frq_inds, :, :, :)));
67-
else
68-
matrix = squeeze(S.(g.measure)(frq_inds, :, :, :));
69-
end
64+
% if measure is not PAC, use the EEG.roi
65+
S = EEG.roi;
66+
67+
% extract frequency indices
68+
if ~isempty(g.freqrange)
69+
if length(g.freqrange) == 1
70+
frq_inds = find(S.freqs == g.freqrange(1));
71+
title = sprintf('%1.1f Hz', g.freqrange(1));
72+
else
73+
frq_inds = find(S.freqs >= g.freqrange(1) & S.freqs < g.freqrange(2));
74+
title = sprintf('%1.1f-%1.1f Hz frequency band', g.freqrange(1), g.freqrange(2));
75+
end
76+
else
77+
frq_inds = 1:length(S.freqs);
78+
title = 'broadband';
79+
end
7080

71-
% average over one dimension to obtain net FC, then generate p-values by comparing the true FC (first shuffle) to null distribution
81+
% select frequency or frequency band
82+
if length(frq_inds) > 1
83+
matrix = squeeze(mean(S.(g.measure)(frq_inds, :, :, :)));
84+
else
85+
matrix = squeeze(S.(g.measure)(frq_inds, :, :, :));
86+
end
87+
end
88+
89+
% generate p-values by comparing the true FC (first shuffle) to null distribution
7290
netFC = squeeze(mean(matrix, 2));
7391
FC_pn = sum(netFC(:, 1) < netFC(:, 2:end), 2)./(size(matrix, 3) - 1);
7492

roi_pac.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
[b_orig, b_anti, b_orig_norm, b_anti_norm] = data2bs_pac(data, params);
8585

8686
% options which bispectral tensors to store
87+
EEG.roi.PAC.fcomb = fcomb;
8788
switch bs_outopts
8889
case 2
8990
EEG.roi.PAC.b_orig = b_orig;

test_pipes/test_pac.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,5 @@
8585
pop_roi_connectplot(EEG1, 'measure', 'MIM', 'plotmatrix', 'on');
8686
pop_roi_connectplot(EEG1, 'measure', 'aCOH', 'plotmatrix', 'on');
8787

88+
% Statistic test plot
89+
pop_roi_statsplot(EEG2, 'measure', 'PAC', 'bispec', 'b_anti');

0 commit comments

Comments
 (0)