def test_functional_pac(self): """Test functionnal pac.""" # generate a 10<->100hz ground truth coupling n_epochs, sf, n_times = 1, 512., 4000 data, time = pac_signals_wavelet(f_pha=10, f_amp=100, noise=.8, n_epochs=n_epochs, n_times=n_times, sf=sf) # phase / amplitude extraction (single time) p = Pac(f_pha='lres', f_amp='lres', dcomplex='wavelet', width=12) phases = p.filter(sf, data, ftype='phase', n_jobs=1) amplitudes = p.filter(sf, data, ftype='amplitude', n_jobs=1) # ground truth array construction n_pha, n_amp = len(p.xvec), len(p.yvec) n_pix = int(n_pha * n_amp) gt = np.zeros((n_amp, n_pha), dtype=bool) b_pha = np.abs(p.xvec.reshape(-1, 1) - np.array([[9, 11]])).argmin(0) b_amp = np.abs(p.yvec.reshape(-1, 1) - np.array([[95, 105]])).argmin(0) gt[b_amp[0]:b_amp[1] + 1, b_pha[0]:b_pha[1] + 1] = True plt.figure(figsize=(12, 9)) plt.subplot(2, 3, 1) p.comodulogram(gt, title='Gound truth', cmap='magma', colorbar=False) # loop over implemented methods for i, k in enumerate([1, 2, 3, 5, 6]): # compute only the pac p.idpac = (k, 2, 3) xpac = p.fit(phases, amplitudes, n_perm=200).squeeze() pval = p.pvalues.squeeze() is_coupling = pval <= .05 # count the number of correct pixels. This includes both true # positives and true negatives acc = 100 * (is_coupling == gt).sum() / n_pix assert acc > 95. # build title of the figure (for sanity check) meth = p.method.replace(' (', '\n(') title = f"Method={meth}\nAccuracy={np.around(acc, 2)}%" # set to nan everywhere it's not significant xpac[~is_coupling] = np.nan vmin, vmax = np.nanmin(xpac), np.nanmax(xpac) # plot the results plt.subplot(2, 3, i + 2) p.comodulogram(xpac, colorbar=False, vmin=vmin, vmax=vmax, title=title) plt.ylabel(''), plt.xlabel('') plt.tight_layout() plt.show() # show on demand
def test_pac_comodulogram(self): """Test Pac object definition. This test works locally but failed on travis... """ matplotlib.use('agg') f, tridx = pac_trivec() pac = np.random.rand(20, 10) pval = np.random.rand(20, 10) p = Pac(f_pha=np.arange(11), f_amp=np.arange(21)) p.comodulogram(np.random.rand(10, 10, 20)) p.comodulogram(pac, rmaxis=True, dpaxis=True, interp=(.1, .1)) p.comodulogram(pac, plotas='contour', pvalues=pval) p.comodulogram(pac, plotas='pcolor', pvalues=pval, levels=[.5, .7], under='gray', over='red', bad='orange') p = Pac(f_pha=np.arange(11), f_amp=f) pac = np.random.rand(len(f)) p.triplot(pac, f, tridx) p.savefig('test_savefig.png') p.show() matplotlib.pyplot.close('all')
def test_pac_comodulogram(): """Test Pac object definition. This test works locally but failed on travis... """ matplotlib.use('agg') f, tridx = pac_trivec() pac = np.random.rand(20, 10) pval = np.random.rand(20, 10) p = Pac(fpha=np.arange(11), famp=np.arange(21)) print(len(p.xvec), len(p.yvec)) p.comodulogram(pac, rmaxis=True, dpaxis=True) p.comodulogram(pac, plotas='contour', pvalues=pval) p.comodulogram(pac, plotas='pcolor', pvalues=pval, levels=[.5, .7], under='gray', over='red', bad='orange') p = Pac(fpha=np.arange(11), famp=f) p.polar(pac, np.arange(10), np.arange(20), interp=.8) pac = np.random.rand(len(f)) p.triplot(pac, f, tridx) matplotlib.pyplot.close('all')
# ----------------------------------------- Tort et al. 2010 plt.subplot(221) plt.plot(time, sig_t[0, :], color='black', lw=.8) plt.ylabel("Amplitude (V)") plt.title("pac_signals_tort (Tort et al. 2010)") plt.autoscale(axis='both', tight=True) plt.tick_params(axis='x', which='both', labelbottom=False) ax = plt.gca() ax.text(*tuple(cfg["nb_pos"]), 'A', transform=ax.transAxes, **cfg["nb_cfg"]) plt.subplot(222) p.comodulogram(xpac_t, title='Comodulogram', cmap=cfg['cmap'], plotas='contour', ncontours=5, fz_labels=18, fz_title=20, fz_cblabel=18) plt.axvline(5, lw=1, color='white') plt.axhline(120, lw=1, color='white') plt.xlabel("") plt.tick_params(axis='x', which='both', labelbottom=False) ax = plt.gca() # ----------------------------------------- La Tour et al. 2017 plt.subplot(223) plt.plot(time, sig_w[0, :], color='black', lw=.8) plt.xlabel("Time (secondes)"), plt.ylabel("Amplitude (V)") plt.title("pac_signals_wavelet (La Tour et al. 2017)") plt.autoscale(axis='both', tight=True)
# npts is the number of time points. n = 10 # number of datasets npts = 4000 # number of time points data, time = pac_signals_tort(fpha=10, famp=100, noise=3., ntrials=n, npts=npts, dpha=10, damp=5, chi=.8) # First, let's use the MVL, without any further correction by surrogates : p = Pac(idpac=(1, 0, 0), fpha=(2, 30, 1, .5), famp=(60, 150, 10, 1)) xpac = p.filterfit(1024, data, axis=1) t1 = p.method + '\n' + p.surro + '\n' + p.norm # Now, we still use the MVL method, but in addition we shuffle amplitude time # series and then, subtract then divide by the mean of surrogates : p.idpac = (1, 1, 1) xpac_corr = p.filterfit(1024, data, data, axis=1, nperm=10) t2 = p.method + '\n' + p.surro + '\n' + p.norm # Now, we plot the result by taking the mean across the dataset dimension. plt.figure(figsize=(20, 7)) plt.subplot(1, 2, 1) p.comodulogram(xpac.mean(-1), title=t1) plt.subplot(1, 2, 2) p.comodulogram(xpac_corr.mean(-1), title=t2) plt.show()
plt.style.use('seaborn-paper') # First, we generate a delta <-> low-gamma coupling. By default, this dataset # is organized as (n_epochs, n_times) where n_times is the number of time # points. n_epochs = 20 # number of datasets sf = 512. # sampling frequency data, time = pac_signals_wavelet(sf=sf, f_pha=6, f_amp=70, noise=3., n_epochs=n_epochs, n_times=4000) # First, let's use the MVL, without any further correction by surrogates : p = Pac(f_pha=(3, 10, 1, .2), f_amp=(50, 90, 5, 1), dcomplex='wavelet', width=12) # Now, we want to compare PAC methods, hence it's useless to systematically # filter the data. So we extract the phase and the amplitude only once : phases = p.filter(sf, data, ftype='phase') amplitudes = p.filter(sf, data, ftype='amplitude') plt.figure(figsize=(16, 12)) for i, k in enumerate(range(4)): # Change the pac method : p.idpac = (5, k, 1) # Compute only the PAC without filtering : xpac = p.fit(phases, amplitudes, n_perm=10) # Plot : plt.subplot(2, 2, k + 1) p.comodulogram(xpac.mean(-1), title=p.str_surro, cmap='Reds', vmin=0) plt.show()
# to extract all of the phases and amplitudes only once # define a pac object and extract high-resolution phases and amplitudes using # Morlet's wavelets p = Pac(f_pha='hres', f_amp='hres', dcomplex='wavelet') # etract all of the phases and amplitudes phases = p.filter(sf, data, ftype='phase', n_jobs=1) amplitudes = p.filter(sf, data, ftype='amplitude', n_jobs=1) ############################################################################### # Compute, plot and compare PAC ############################################################################### # Once all of the phases and amplitudes extracted we can compute PAC by # ietrating over the implemented methods. plt.figure(figsize=(14, 8)) for i, k in enumerate([1, 2, 3, 4, 5, 6]): # switch method of PAC p.idpac = (k, 0, 0) # compute only the pac without filtering xpac = p.fit(phases, amplitudes) # plot plt.subplot(2, 3, k) title = p.method.replace(' (', f' ({k})\n(') p.comodulogram(xpac.mean(-1), title=title, cmap='viridis') if k <= 3: plt.xlabel('') plt.tight_layout() plt.show()
n_epochs = 10 # number of datasets sf = 512. # sampling frequency n_times = 4000 # Number of time points data, time = pac_signals_tort(sf=sf, f_pha=5, f_amp=100, noise=2., n_epochs=n_epochs, n_times=n_times) # First, let's use the MVL, without any further correction by surrogates : p = Pac(f_pha=(2, 20, 1, 1), f_amp=(60, 150, 5, 5)) # Now, we want to compare PAC methods, hence it's useless to systematically # filter the data. So we extract the phase and the amplitude only once : phases = p.filter(sf, data, ftype='phase') amplitudes = p.filter(sf, data, ftype='amplitude') plt.figure(figsize=(18, 9)) for i, k in enumerate([1, 2, 3, 4, 5, 6]): # Change the pac method : p.idpac = (k, 0, 0) print('-> PAC using ' + str(p)) # Compute only the PAC without filtering : xpac = p.fit(phases, amplitudes) # Plot : plt.subplot(2, 3, k) p.comodulogram(xpac.mean(-1), title=p.method, cmap='Spectral_r') plt.show()
from tensorpac.signals import pac_signals_tort # Dataset of signals artificially coupled between 10hz and 100hz : n_epochs = 20 n_times = 4000 sf = 512. # sampling frequency # Create artificially coupled signals using Tort method : data, time = pac_signals_tort(f_pha=10, f_amp=100, noise=2, n_epochs=n_epochs, dpha=10, damp=10, sf=sf, n_times=n_times) # Define a PAC object : p = Pac(idpac=(6, 0, 0), f_pha=(2, 20, 1, 1), f_amp=(60, 150, 5, 5)) # Filter the data and extract PAC : xpac = p.filterfit(sf, data) # Plot your Phase-Amplitude Coupling : p.comodulogram(xpac.mean(-1), title='Contour plot with 5 regions', cmap='Spectral_r', plotas='contour', ncontours=5) p.show()
n_times=n_times, rnd_state=0) # extract the phase and the amplitude p_obj = Pac(idpac=(1, 0, 0), f_pha='hres', f_amp='hres') pha = p_obj.filter(sf, data, ftype='phase', n_jobs=1) amp = p_obj.filter(sf, data, ftype='amplitude', n_jobs=1) # compute PAC (outside of the PAC object) pac_nt, pac, s = custom_ndpac(pha, amp, p=p) plt.figure(figsize=(22, 6)) plt.subplot(131) p_obj.comodulogram(pac_nt, cblabel="", title='Non-thresholded PAC', cmap=cfg["cmap"], vmin=0, colorbar=True) plt.subplot(132) p_obj.comodulogram(s, cblabel="", title='Threshold', cmap=cfg["cmap"], vmin=0, colorbar=True) plt.ylabel('') plt.subplot(133) p_obj.comodulogram(pac, cblabel="", title='Thresholded PAC', cmap=cfg["cmap"],
xpac_w = p.filterfit(sf, sig_w, n_jobs=1).mean(-1) plt.figure(figsize=(17, 14)) # ----------------------------------------- Tort et al. 2010 plt.subplot(221) plt.plot(time, sig_t[0, :], color='black', lw=.8) plt.ylabel("Amplitude (V)") plt.title("pac_signals_tort (Tort et al. 2010)") plt.autoscale(axis='both', tight=True) plt.tick_params(axis='x', which='both', labelbottom=False) ax = plt.gca() ax.text(*tuple(cfg["nb_pos"]), 'A', transform=ax.transAxes, **cfg["nb_cfg"]) plt.subplot(222) p.comodulogram(xpac_t, title='Comodulogram', cmap=cfg['cmap'], plotas='contour', ncontours=5) plt.axvline(5, lw=1, color='white') plt.axhline(120, lw=1, color='white') plt.xlabel("") plt.tick_params(axis='x', which='both', labelbottom=False) ax = plt.gca() # ----------------------------------------- La Tour et al. 2017 plt.subplot(223) plt.plot(time, sig_w[0, :], color='black', lw=.8) plt.xlabel("Time (secondes)"), plt.ylabel("Amplitude (V)") plt.title("pac_signals_wavelet (La Tour et al. 2017)") plt.autoscale(axis='both', tight=True) ax = plt.gca() ax.text(*tuple(cfg["nb_pos"]), 'B', transform=ax.transAxes, **cfg["nb_cfg"])
# n_times is the number of time points. n_epochs = 10 # number of datasets sf = 512. # sampling frequency data, time = pac_signals_wavelet(sf=sf, f_pha=10, f_amp=100, noise=1., n_epochs=n_epochs, n_times=2000) # First, let's use the MVL, without any further correction by surrogates : p = Pac(f_pha=(5, 16, 1, .1), f_amp=(80, 130, 5, 2)) # Now, we want to compare PAC methods, hence it's useless to systematically # filter the data. So we extract the phase and the amplitude only once : phases = p.filter(sf, data, ftype='phase') amplitudes = p.filter(sf, data, ftype='amplitude') plt.figure(figsize=(18, 9)) for i, k in enumerate(range(5)): # Change the pac method : p.idpac = (1, 2, k) print('-> Normalization using ' + p.str_norm) # Compute only the PAC without filtering : xpac = p.fit(phases, amplitudes, n_perm=20) # Plot : plt.subplot(2, 3, k + 1) p.comodulogram(xpac.mean(-1), title=p.str_norm, cmap='Spectral_r') plt.show()
coupling. """ import numpy as np import matplotlib.pyplot as plt from tensorpac.utils import pac_signals_tort from tensorpac import Pac data, time = pac_signals_tort(fpha=[5, 7], famp=[60, 80], chi=0.5, ntrials=10, noise=3., npts=2000) p = Pac(idpac=(3, 1, 1), fpha=(1, 15, 1, .2), famp=(40, 100, 5, 2), dcomplex='wavelet', width=6) pac = np.squeeze(p.filterfit(1024, data, axis=1, nperm=10)) plt.figure(figsize=(12, 9)) p.comodulogram(pac.mean(-1), title=str(p), plotas='contour', ncontours=10, cmap='plasma', vmin=0) plt.show()
sf=sf) # phase / amplitude extraction (single time) p = Pac(f_pha='lres', f_amp='lres', dcomplex='wavelet', width=12) phases = p.filter(sf, data, ftype='phase', n_jobs=1) amplitudes = p.filter(sf, data, ftype='amplitude', n_jobs=1) # ground truth array construction n_pha, n_amp = len(p.xvec), len(p.yvec) n_pix = int(n_pha * n_amp) gt = np.zeros((n_amp, n_pha), dtype=bool) b_pha = np.abs(p.xvec.reshape(-1, 1) - np.array([[9, 11]])).argmin(0) b_amp = np.abs(p.yvec.reshape(-1, 1) - np.array([[95, 105]])).argmin(0) gt[b_amp[0]:b_amp[1] + 1, b_pha[0]:b_pha[1] + 1] = True plt.figure(figsize=(12, 9)) plt.subplot(2, 3, 1) p.comodulogram(gt, title='Gound truth', cmap='magma', colorbar=False) # loop over implemented methods for i, k in enumerate([1, 2, 3, 5, 6]): # compute only the pac p.idpac = (k, 2, 3) xpac = p.fit(phases, amplitudes, n_perm=200).squeeze() pval = p.pvalues.squeeze() is_coupling = pval <= .05 # count the number of correct pixels. This includes both true # positives and true negatives trpr = (is_coupling == gt).sum() / n_pix assert trpr > .95 # build title of the figure (for sanity check) meth = p.method.replace(' (', '\n(') title = f"Method={meth}\nAccuracy={np.around(trpr * 100, 2)}%" # set to nan everywhere it's not significant
# is organized as (ntrials, npts) where npts is the number of time points. n = 30 # number of datasets sf = 512. # sampling frequency data, time = pac_signals_wavelet(sf=sf, fpha=6, famp=70, noise=2., ntrials=n, npts=4000) # First, let's use the MVL, without any further correction by surrogates : p = Pac(fpha=(3, 10, 1, .2), famp=(50, 90, 5, 1), dcomplex='wavelet', width=12) # Now, we want to compare PAC methods, hence it's useless to systematically # filter the data. So we extract the phase and the amplitude only once : phases = p.filter(sf, data, axis=1, ftype='phase') amplitudes = p.filter(sf, data, axis=1, ftype='amplitude') plt.figure(figsize=(18, 9)) for i, k in enumerate(range(5)): # Change the pac method : p.idpac = (5, k, 1) print('-> Surrogates using ' + p.surro) # Compute only the PAC without filtering : xpac = p.fit(phases, amplitudes, axis=2, nperm=5) # Plot : plt.subplot(2, 3, k + 1) p.comodulogram(xpac.mean(-1), title=p.surro, cmap='Spectral_r') plt.show()
pha_rest, amp_rest = pha_p[..., time_rest], amp_p[..., time_rest] pha_prep, amp_prep = pha_p[..., time_prep], amp_p[..., time_prep] pha_exec, amp_exec = pha_p[..., time_exec], amp_p[..., time_exec] # compute PAC inside rest, planning, and execution pac_rest = p_obj.fit(pha_rest, amp_rest).mean(-1) pac_prep = p_obj.fit(pha_prep, amp_prep).mean(-1) pac_exec = p_obj.fit(pha_exec, amp_exec).mean(-1) ############################################################################## # plot the comodulograms inside the rest, planning and execution period vmax = np.max([pac_rest.max(), pac_prep.max(), pac_exec.max()]) kw = dict(vmax=vmax, vmin=.04, cmap='viridis') plt.figure(figsize=(14, 4)) plt.subplot(131) p_obj.comodulogram(pac_rest, title="PAC Rest [-1, 0]s", **kw) plt.subplot(132) p_obj.comodulogram(pac_prep, title="PAC Planning [0, 1.5]s", **kw) plt.ylabel('') plt.subplot(133) p_obj.comodulogram(pac_exec, title="PAC Execution [1.5, 3]s", **kw) plt.ylabel('') plt.tight_layout() plt.show() ############################################################################### # From the three comodulograms above, you can see that, during the planning # period there is an alpha [8, 12]Hz <-> gamma [80, 100]Hz that is not # present during the rest and execution periods ###############################################################################
n_epochs = 20 # number of trials n_times = 4000 # number of time points sf = 512. # sampling frequency # Create artificially coupled signals using Tort method : data, time = pac_signals_tort(f_pha=10, f_amp=100, noise=2, n_epochs=n_epochs, dpha=10, damp=10, sf=sf, n_times=n_times) # Define a Pac object p = Pac(idpac=(6, 0, 0), f_pha='hres', f_amp='hres') # Filter the data and extract pac xpac = p.filterfit(sf, data) # plot your Phase-Amplitude Coupling : p.comodulogram(xpac.mean(-1), cmap='Spectral_r', plotas='contour', ncontours=5, title=r'10hz phase$\Leftrightarrow$100Hz amplitude coupling', fz_title=14, fz_labels=13) # export the figure # plt.savefig('readme.png', bbox_inches='tight', dpi=300) p.show()
p = Pac(idpac=(1, 2, 3), f_pha=cfg["phres"], f_amp=cfg["ahres"]) # p = Pac(idpac=(1, 2, 3), f_pha=(1, 30, 1, 1), f_amp=(60, 160, 5, 5)) # p = Pac(idpac=(1, 2, 3), f_pha='lres', f_amp='lres') xpac = p.filterfit(sf, data, n_perm=n_perm, p=.05, n_jobs=-1) pacn = p.pac.mean(-1) pac = xpac.mean(-1) surro = p.surrogates.mean(0).max(-1) # mean(perm).max(epochs) plt.figure(figsize=(22, 6)) plt.subplot(1, 3, 1) p.comodulogram(pacn, cblabel="", title="Uncorrected PAC", cmap=cfg["cmap"], vmin=0) ax = plt.gca() ax.text(*tuple(cfg["nb_pos"]), 'A', transform=ax.transAxes, **cfg["nb_cfg"]) plt.subplot(1, 3, 2) p.comodulogram(surro, cblabel="", title="Mean of the surrogate distribution", cmap=cfg["cmap"], vmin=0) plt.ylabel("") plt.tick_params(axis='y', which='both', labelleft=False) ax = plt.gca() ax.text(*tuple(cfg["nb_pos"]), 'B', transform=ax.transAxes, **cfg["nb_cfg"])
data, time = pac_signals_wavelet(sf=sf, f_pha=10, f_amp=100, noise=2., n_epochs=n_epochs, n_times=n_times) p = Pac(idpac=(1, 2, 3), f_pha=cfg["phres"], f_amp=cfg["ahres"]) # p = Pac(idpac=(1, 2, 3), f_pha=(1, 30, 1, 1), f_amp=(60, 160, 5, 5)) # p = Pac(idpac=(1, 2, 3), f_pha='mres', f_amp='mres') pha = p.filter(sf, data, ftype='phase', n_jobs=1) amp = p.filter(sf, data, ftype='amplitude', n_jobs=1) plt.figure(figsize=(18, 10)) gs = GridSpec(2, 7) for k in range(5): p.idpac = (k + 1, 2, 3) xpac = p.fit(pha.copy(), amp.copy(), n_perm=n_perm, p=.05, n_jobs=-1).mean(-1) sq = methods[titles[k]] plt.subplot(gs[sq[0], sq[1]]) p.comodulogram(xpac, cblabel="", title=titles[k], cmap=cfg["cmap"], vmin=0, colorbar=True) if k > 0: plt.ylabel("") # plt.tick_params(axis='y', which='both', labelleft=False) plt.tight_layout() plt.savefig(f"{cfg['path']}/Fig3.png", dpi=300, bbox_inches='tight') p.show()
xpac21 = p.filterfit(1024, d2, d1) # Plot signals and PAC : plt.figure(figsize=(18, 12)) plt.subplot(2, 2, 1) plt.plot(time, d1.mean(0), color='k') plt.xlabel('Time') plt.ylabel('Amplitude [uV]') plt.title('Mean across trials of the first dataset') plt.axis('tight') plt.subplot(2, 2, 2) plt.plot(time, d2.mean(0), color='k') plt.xlabel('Time') plt.ylabel('Amplitude [uV]') plt.title('Mean across trials of the second dataset') plt.axis('tight') plt.subplot(2, 2, 3) p.comodulogram(xpac12.mean(-1), title="Phase of the first dataset and " "amplitude of the second", cmap='Reds') plt.subplot(2, 2, 4) p.comodulogram(xpac21.mean(-1), title="Phase of the second dataset and " "amplitde of the second", cmap='Reds') plt.show()
phases = p.filter(sf, data, ftype='phase') amplitudes = p.filter(sf, data, ftype='amplitude') ############################################################################### # Compute PAC and surrogates ############################################################################### # now the phases and amplitudes are extracted, we can compute the true PAC such # as the surrogates. Then the true value of PAC is going to be normalized using # a z-score normalization and using the distribution of surrogates plt.figure(figsize=(16, 12)) for i, k in enumerate(range(4)): # change the pac method p.idpac = (5, k, 1) # compute only the pac without filtering xpac = p.fit(phases, amplitudes, n_perm=20) # plot title = p.str_surro.replace(' (', '\n(') plt.subplot(2, 2, k + 1) p.comodulogram(xpac.mean(-1), title=title, cmap='Reds', vmin=0, fz_labels=18, fz_title=20, fz_cblabel=18) plt.tight_layout() plt.show()
pval = p.infer_pvalues(p=0.05) # get the mean pac values where it's detected as significant xpac_smean = xpac[pval < .05].mean() # if you want to see how the surrogates looks like, you can have to access # using :class:`tensorpac.Pac.surrogates` surro = p.surrogates.squeeze() print(f"Surrogates shape (n_perm, n_amp, n_pha) : {surro.shape}") # get the maximum of the surrogates across (phase, amplitude) pairs surro_max = surro.max(axis=(1, 2)) plt.figure(figsize=(16, 5)) plt.subplot(131) p.comodulogram(xpac, title=str(p), cmap='Spectral_r', vmin=0., pvalues=pval, levels=.05) plt.subplot(132) p.comodulogram(pval, title='P-values', cmap='bwr_r', vmin=1. / n_perm, vmax=.05, over='lightgray') plt.subplot(133) plt.hist(surro_max, bins=20) plt.title('Corrected distribution of surrogates') plt.axvline(xpac_smean, lw=2, color='red')
# Tort et al. 2010 :cite:`tort2010measuring`. This method consists in swapping # phase and amplitude trials. Then, we used the method # :class:`tensorpac.Pac.infer_pvalues` in order to get the corrected p-values # across all possible (phase, amplitude) frequency pairs. # define the Pac object p = Pac(idpac=(1, 1, 0), f_pha='mres', f_amp='mres') # compute true pac and surrogates n_perm = 200 # number of permutations xpac = p.filterfit(sf, data, n_perm=n_perm, n_jobs=-1).squeeze() plt.figure(figsize=(16, 5)) for n_mcp, mcp in enumerate(['maxstat', 'fdr', 'bonferroni']): # get the corrected p-values pval = p.infer_pvalues(p=0.05, mcp=mcp) # set to gray non significant p-values and in color significant values pac_ns = xpac.copy() pac_ns[pval <= .05] = np.nan pac_s = xpac.copy() pac_s[pval > .05] = np.nan plt.subplot(1, 3, n_mcp + 1) p.comodulogram(pac_ns, cmap='gray', colorbar=False, vmin=np.nanmin(pac_ns), vmax=np.nanmax(pac_ns)) p.comodulogram(pac_s, title=f'MCP={mcp}', cmap='viridis', vmin=np.nanmin(pac_s), vmax=np.nanmax(pac_s)) plt.gca().invert_yaxis() plt.tight_layout() p.show()
import numpy as np import matplotlib.pyplot as plt from tensorpac import Pac, pac_signals_wavelet plt.style.use('seaborn-poster') # First, we generate a dataset of signals artificially coupled between 10hz # and 100hz. By default, this dataset is organized as (n_epochs, n_times) where # n_times is the number of time points. n_epochs = 1 # number of datasets sf = 512. # sampling frequency data, time = pac_signals_wavelet(f_pha=6, f_amp=90, noise=.8, n_epochs=n_epochs, n_times=4000, sf=sf) # First, let's use the MVL, without any further correction by surrogates : p = Pac(idpac=(1, 2, 0), f_pha=(2, 15, 2, .2), f_amp=(60, 120, 10, 1)) xpac = p.filterfit(sf, data, n_perm=200, p=.05) pval = p.pvalues p.comodulogram(xpac.mean(-1), title=str(p), cmap='Spectral_r', vmin=0., pvalues=pval, levels=.05) p.show()
for k in range(6): p.idpac = (k + 1, 2, 3) xpac = p.fit(pha.copy(), amp.copy(), n_perm=n_perm, p=.05, n_jobs=-1, random_state=k).mean(-1) sq = methods[titles[k]] plt.subplot(gs[sq[0], sq[1]]) p.comodulogram(xpac, cblabel="", title=p.method.replace(' (', '\n('), cmap=cfg["cmap"], vmin=0, colorbar=True, fz_labels=15, fz_title=16) # clean up x-y labels if k % 3 != 0: plt.ylabel("") # noqa if k in [0, 1, 2]: plt.xlabel('') # noqa # adding letter for better reference ax = plt.gca() ax.text(*tuple(cfg["nb_pos"]), alphabet[k], transform=ax.transAxes, **cfg["nb_cfg"]) plt.tight_layout() plt.savefig(f"../figures/Fig3.png", dpi=300, bbox_inches='tight')
n=str(noise)) info.append(inf) # Generate coupling : data[i, k, ...], time = pac_signals_wavelet(fpha=fpha, famp=famp, noise=noise, npts=n_pts, ntrials=n_trials, sf=sf) # ----------------- Compute PAC ----------------- # Define the PAC object : p = Pac(idpac=(4, 0, 0), fpha=(1, 15, 1, .3), famp=(25, 130, 5, 1), dcomplex='wavelet', width=12) # Compute PAC along the time axis and take the mean across trials : pac = p.filterfit(sf, data, axis=3).mean(-1) # ----------------- Visualization ----------------- q = 1 plt.figure(figsize=(20, 19)) for i in range(n_subject): for k in range(n_elec): plt.subplot(n_subject, n_elec, q) p.comodulogram(pac[:, :, i, k], title=info[q - 1], interp=(.2, .2)) q += 1 p.show()
noise=1., ntrials=n, npts=4000) # First, let's use the MVL, without any further correction by surrogates : p = Pac(idpac=(5, 3, 3), fpha=(4, 18, 1, .3), famp=(60, 150, 5, 2), dcomplex='wavelet', width=7) xpac, pval = p.filterfit(1024, data, axis=1, nperm=110, get_pval=True) # Now, we plot the result by taking the mean across the dataset dimension. plt.figure(figsize=(20, 15)) plt.subplot(3, 3, 1) p.comodulogram(xpac.mean(-1), title='Default plotting') plt.subplot(3, 3, 2) p.comodulogram(xpac.mean(-1), title='Peaking between [5, 20]', vmin=5, vmax=20, cmap='gnuplot2_r') plt.subplot(3, 3, 3) # Ideally, the p-values should be corrected across trials because taking the # mean is not correct. This is only illustrative. p.comodulogram(xpac.mean(-1), title='p>=.05 in black', cmap='Spectral_r', pvalues=pval.mean(-1),
noise=1., n_epochs=n_epochs, n_times=n_times) # First, let's use the MVL, without any further correction by surrogates : p = Pac(idpac=(4, 0, 0), f_pha=(5, 14, 2, .3), f_amp=(80, 120, 2, 1), verbose=False) plt.figure(figsize=(18, 9)) # Define several cycle options for the fir1 (eegfilt like) filter : p.filt = 'fir1' print('Filtering with fir1 filter') for i, k in enumerate([(1, 3), (2, 4), (3, 6)]): p.cycle = k xpac = p.filterfit(1024, data) plt.subplot(2, 3, i + 1) p.comodulogram(xpac.mean(-1), title='Fir1 - cycle ' + str(k)) # Define several wavelet width : p.dcomplex = 'wavelet' print('Filtering with wavelets') for i, k in enumerate([7, 9, 12]): p.width = k xpac = p.filterfit(1024, data) plt.subplot(2, 3, i + 4) p.comodulogram(xpac.mean(-1), title='Wavelet - width ' + str(k)) plt.show()
# mne requires that the first is represented by the number of trials (n_epochs) # Therefore, we transpose the output PACs of both conditions pac_r1 = np.transpose(pac_1, (2, 0, 1)) pac_r2 = np.transpose(pac_2, (2, 0, 1)) n_perm = 1000 # number of permutations tail = 1 # only inspect the upper tail of the distribution # perform the correction t_obs, clusters, cluster_p_values, h0 = permutation_cluster_test( [pac_r1, pac_r2], n_permutations=n_perm, tail=tail) ############################################################################### # Plot the significant clusters ############################################################################### # Finally, we plot the significant clusters. To this end, we used an elegant # solution proposed by MNE where the non significant part appears using a # gray scale colormap while significant clusters are going to be color coded. # create new stats image with only significant clusters t_obs_plot = np.nan * np.ones_like(t_obs) for c, p_val in zip(clusters, cluster_p_values): if p_val <= 0.001: t_obs_plot[c] = t_obs[c] t_obs[c] = np.nan title = 'Cluster-based corrected differences\nbetween cond 1 and 2' p.comodulogram(t_obs, cmap='gray', colorbar=False) p.comodulogram(t_obs_plot, cmap='viridis', title=title) plt.gca().invert_yaxis() plt.show()