cross frequency coupling

交叉频率耦合

针对EEG的交叉频率耦合测试

方法1(method 1)

%% multivariate cross-frequency coupling, based on generalized eigendecomposition (gedCFC)
% Method 1: covariance matrix at a low-frequency phase value, 
% relative to covariance from entire time period.

% You will need the following files in the current directory or Matlab path:
%   - emptyEEG.mat 
%   - filterFGx.m
%   - topoplotIndie.m

% mikexcohen@gmail.com

%% preliminaries

clear

% mat file containing EEG, leadfield and channel locations
load emptyEEG
origEEG = EEG;

% indices of dipole locations
thetaDipole =  94;
gam1Dipole  = 109;
gam2Dipole  = 111;

whichOri = 1; % 1 for "EEG" and 2 for "MEG"

% plot dipole projections
figure(1), clf
clim = [-45 45];

subplot(231), topoplotIndie(-lf.Gain(:,whichOri,thetaDipole),EEG.chanlocs,'maplimits',clim,'numcontour',0,'electrodes','off','shading','interp');
subplot(232), topoplotIndie(-lf.Gain(:,whichOri,gam1Dipole), EEG.chanlocs,'maplimits',clim,'numcontour',0,'electrodes','off','shading','interp');
subplot(233), topoplotIndie(-lf.Gain(:,whichOri,gam2Dipole), EEG.chanlocs,'maplimits',clim,'numcontour',0,'electrodes','off','shading','interp');

%% create correlated 1/f noise time series

% correlation matrix
cormat = rand(size(lf.Gain,3));
cormat = cormat*cormat';
% cormat = cormat-min(cormat(:));
cormat = .8*( cormat./max(cormat(:)) );
cormat(1:size(lf.Gain,3)+1:end) = 1;

% eigdecomp and create correlated random data
[evecs,evals] = eig(cormat);

% 1/f random data
ps   = bsxfun(@times, exp(1i*2*pi*rand(size(lf.Gain,3),floor(EEG.pnts/2))) , .1+exp(-(1:floor(EEG.pnts/2))/200) );
ps   = [ps zeros(size(lf.Gain,3),1) ps(:,end:-1:1)];
data = 100* real(ifft(ps,[],2))' * (evecs*sqrt(evals))';

%% replace one dipole with nonstationary theta oscillation

thetafreq = 6;

% create data time series
ampl1     = 5+10*filterFGx(randn(1,EEG.pnts),EEG.srate,1,30);
freqmod1  = detrend(10*filterFGx(randn(1,EEG.pnts),EEG.srate,1,30));
thetawave = ampl1 .* sin(2*pi.*thetafreq.*EEG.times + 2*pi/EEG.srate*cumsum(freqmod1));

%% (optional) theta rhythm is provided by repeated Gaussians 
% This causes non-uniform phase distributions, which in turn cause
% artifacts in univariate CFC measures (van Driel et al., 2015, JNM).
% But GED-CFC is robust to these artifacts

% centTimes = 0:1/thetafreq:EEG.xmax; % center times for 'oscillatory' peaks
% gausWidth = .0165;

% cmd = 'thetawave = detrend(';
% for i=1:length(centTimes)
%     cmd = [cmd 'exp(-((EEG.times-' num2str(centTimes(i)) ').^2)/(2*' num2str(gausWidth) '^2)) + '];
% end
% cmd = [cmd '0);'];
% eval(cmd)

%% (optional) theta rhythm is provided by a van der Pol oscillator
% This also causes artifacts in univariate CFC measure (https://arxiv.org/pdf/1405.7965.pdf)
% Again, GED-CFC is robust to these artifacts.

% tspan = [0 395];
% y0 = [2; 0];
% Mu = 1;
% ode = @(t,y) vanderpoldemo(t,y,Mu);
% [t,y] = ode45(ode, tspan, y0);

% thetawave = interp1(linspace(EEG.xmin,EEG.xmax,length(y)),y(:,1),EEG.times);

%% simulate gamma bursts locked (or not) to theta troughs

gammafreq = 40; % Hz

mod1 = .1+.9*(1+real(exp(1i*angle(hilbert(thetawave)))))/2;
gamma1wave = mod1 .* sin(2*pi*gammafreq*EEG.times);

ampl2      = 2+5*filterFGx(randn(1,EEG.pnts),EEG.srate,1,30);
freqmod2   = detrend(10*filterFGx(randn(1,EEG.pnts),EEG.srate,1,30));
gamma2wave = ampl2 .* sin(2*pi.*50.*EEG.times + 2*pi/EEG.srate*cumsum(freqmod2));

%% replace key dipole time series with simulated data

data(:,thetaDipole) = thetawave*10;
data(:,gam1Dipole)  = gamma1wave*10;
data(:,gam2Dipole)  = gamma2wave*20;

% project dipole data to scalp
EEG.data = detrend( data*squeeze(lf.Gain(:,whichOri,:))' )';

%% GED to identify theta component

% theta covariance
thetafilt = filterFGx(EEG.data,EEG.srate,thetafreq,5);
thetafilt = bsxfun(@minus,thetafilt,mean(thetafilt,2));
thetacov  = (thetafilt*thetafilt')/EEG.pnts;

% broadband covariance
tmpdat = bsxfun(@minus,EEG.data,mean(EEG.data,2));
bbcov  = (tmpdat*tmpdat')/EEG.pnts;

% GED
[evecsT,evals] = eig(thetacov,bbcov);

% find best component and compute filter projection
[~,maxcomp] = sort(diag(evals));
thetamap    = thetacov*evecsT;
thetamap    = thetamap(:,maxcomp(end));

% fix sign of map (max is positive)
[~,maxe] = max(abs(thetamap));
thetamap = thetamap * sign(thetamap(maxe));

% theta time series component
thetacomp = thetafilt' * evecsT(:,maxcomp(end));

% fix sign of time series according to sign of correlation with EEG
thetacomp = thetacomp * sign(corr(thetacomp,filterFGx(EEG.data(maxe,:),EEG.srate,thetafreq,9)'));

%% identify troughs and get surrounding covariance matrices

nwin = ceil(EEG.srate/thetafreq/8); % window size is 1/4 cycle (1/8 of either side)

% find troughs
troughs = find(diff(sign(diff( thetacomp )))>0)+1;
troughs(troughs<nwin+1) = [];
troughs(troughs>EEG.pnts-nwin-1) = [];


covT = zeros(EEG.nbchan);

% trough-locked covariance
for ti=1:length(troughs)
    tmpdat = EEG.data(:,troughs(ti)-nwin:troughs(ti)+nwin);
    tmpdat = bsxfun(@minus,tmpdat,mean(tmpdat,2));
    covT   = covT + (tmpdat*tmpdat')/nwin;
end
covT = covT./ti;

%% GED to get gamma peak/trough networks

[evecs,evals] = eig(covT,bbcov);
[~,compidx]   = sort(diag(evals)); % max component

maps    = covT*evecs; % forward model of filter
gamnet1 = maps(:,compidx(end));

% fix sign
[~,idx] = max(abs(gamnet1));
gamnet1 = gamnet1 * sign(gamnet1(idx));

% plot component maps for comparison with dipole projections
figure(1)
subplot(234), topoplotIndie(thetamap, EEG.chanlocs,'numcontour',0,'electrodes','off','shading','interp');
subplot(235), topoplotIndie(gamnet1,  EEG.chanlocs,'numcontour',0,'electrodes','off','shading','interp');

%% get time course and reconstruct topography and sources

frex    = linspace(10,190,70);
mvarpac = zeros(size(frex));

for fi=1:length(frex)
    
    % bandpass filter trough component
    gam1comp = filterFGx(EEG.data,EEG.srate,frex(fi),15)' * evecs(:,compidx(end));
    
    % find peaks and troughs and get distances
    troughs  = find(diff(sign(diff( gam1comp )))>0)+1;
    peeks    = find(diff(sign(diff( gam1comp )))<0)+1;
    mvarpac(fi) = mean(gam1comp(peeks)) - mean(gam1comp(troughs));
end

%% more plotting

figure(2), clf

% vector of frequencies
hz = linspace(0,EEG.srate,EEG.pnts);


% plot components power spectra
subplot(331)
plot(hz,abs(fft(EEG.data'*evecsT(:,end))/EEG.pnts)), hold on
plot(hz,abs(fft(EEG.data'*evecs(:,compidx(end)))/EEG.pnts))
set(gca,'xlim',[0 90],'xtick',10:20:90), axis square
xlabel('Frequency (Hz)'), ylabel('Power (a.u.)')


% plot channel power spectra (hard-coded for POz)
subplot(332)
plot(hz,abs(fft(EEG.data(30,:))/EEG.pnts),'k')
set(gca,'xlim',[0 90],'xtick',10:20:90), axis square
xlabel('Frequency (Hz)'), ylabel('Power (a.u.)')

% plot CFC modulation
subplot(333)
plot(frex,mvarpac,'k','linew',2)
set(gca,'xlim',[0 90],'xtick',10:20:90), axis square
xlabel('Frequency (Hz)'), ylabel('CFC strength')

% sample time courses
subplot(312)
plot(EEG.times,zscore(thetacomp), EEG.times,zscore(abs(hilbert(filterFGx(EEG.data,EEG.srate,40,25)' * evecs(:,compidx(end))))),'linew',2);
set(gca,'xlim',[2 4])
legend({'theta component';'gamma'})
xlabel('Time (s)'), ylabel('EEG activity (a.u.)')

subplot(313)
plot(EEG.times,zscore(filterFGx(EEG.data(30,:),EEG.srate,thetafreq,5)'), EEG.times,zscore(abs(hilbert(filterFGx(EEG.data(30,:),EEG.srate,40,25)'))),'linew',1);
set(gca,'xlim',[2 4],'ylim',[-2.5 3.5])
legend({'theta filtered';'gamma filtered'})

%% now for normal Euler-based univariate PAC (note: takes a while to run for all channels!)

pacz = zeros(EEG.nbchan,length(frex));

nperm     = 1000;
cutpoints = randsample(10:EEG.pnts-10,nperm);
permpac   = zeros(1,nperm);

% can also run only for POz (channel 30)
for chani=30%1:EEG.nbchan
    
    % filter for 6 Hz
    phase = angle(hilbert(filterFGx(EEG.data(chani,:),EEG.srate,thetafreq,5)));
    
    % filter at a higher frequency
    for fi=1:length(frex)
        pow = abs(hilbert(filterFGx(EEG.data(chani,:),EEG.srate,frex(fi),5)));
        
        % zPACd
        obspac = abs(mean( pow.*( exp(1i*phase) ) ));
        for permi=1:nperm
            permpac(permi) = abs(mean( pow([cutpoints(permi):end 1:cutpoints(permi)-1]).*( exp(1i*phase) ) ));
        end
        
        pacz(chani,fi) = (obspac-mean(permpac))/std(permpac);
    end
end


% now plot
figure(3), clf
clim = [-2.5 2.5];

subplot(221)
imagesc(1:64,frex,pacz')
xlabel('Channel'), ylabel('Frequency (Hz)')
set(gca,'clim',clim)

subplot(222), topoplotIndie(pacz(:,dsearchn(frex',40)),EEG.chanlocs,'maplimits',clim);
subplot(223), topoplotIndie(pacz(:,dsearchn(frex',65)),EEG.chanlocs,'maplimits',clim);

subplot(224)
plot(frex,pacz(30,:),'k','linew',2)
set(gca,'xlim',[0 90],'xtick',10:20:90), axis square
xlabel('Frequency (Hz)'), ylabel('CFC strength')

%% end.
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值