def test_pac_meth(): """Test all Pac methods.""" pha = np.random.rand(2, 7, 1024) amp = np.random.rand(3, 7, 1024) nmeth, nsuro, nnorm = 5, 5, 5 p = Pac() for k in range(nmeth): for i in range(nsuro): for j in range(nnorm): p.idpac = (k + 1, i, j) p.fit(pha, amp, axis=2, traxis=1, njobs=1, nperm=2)
def test_fit(self): """Test all Pac methods.""" pha = np.random.rand(2, 7, 1024) amp = np.random.rand(3, 7, 1024) nmeth, nsuro, nnorm = 5, 4, 5 p = Pac() for k in range(nmeth): for i in range(nsuro): for j in range(nnorm): p.idpac = (k + 1, i, j) p.fit(pha, amp, n_jobs=1, n_perm=10)
def test_fit(self): """Test all Pac methods.""" pha = np.random.rand(2, 7, 1024) amp = np.random.rand(3, 7, 1024) nmeth, nsuro, nnorm = 5, 4, 5 p = Pac(verbose=False) for k in range(nmeth): for i in range(nsuro): for j in range(nnorm): p.idpac = (k + 1, i, j) p.fit(pha, amp, n_jobs=1, n_perm=10) if (i >= 1) and (k + 1 != 4): for mcp in ['maxstat', 'fdr', 'bonferroni']: p.infer_pvalues(mcp=mcp)
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
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()
# periods p_obj = Pac(idpac=(6, 0, 0), f_pha=(6, 14, 4, .2), f_amp=(60, 120, 20, 2)) # extract all of the phases and amplitudes pha_p = p_obj.filter(sf, data, ftype='phase') amp_p = p_obj.filter(sf, data, ftype='amplitude') # define time indices where rest, planning and execution are defined time_rest = slice(0, 1000) time_prep = slice(1000, 2500) time_exec = slice(2500, 4000) # define phase / amplitude during rest / planning / execution 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)
# 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 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)
n_epochs=n_epochs, n_times=n_times) alphabet = string.ascii_uppercase p = Pac(idpac=(1, 2, 3), f_pha='hres', f_amp='hres') 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(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
plt.plot(time, np.squeeze(x100hz), color='lightgray', linewidth=1) plt.plot(time, np.squeeze(amplitude), color=color_amp, linewidth=3) plt.xticks([]), plt.yticks([]) plt.title("100hz amplitude") rmaxis(plt.gca()) savefig('100hz_amp') ############################################################################### # surrogates ############################################################################### data, time = pac_signals_tort(n_epochs=10, f_pha=10, f_amp=100, sf=1024, n_times=1000, rnd_state=1) p = Pac(idpac=(1, 2, 3), f_pha=[9, 11], f_amp=[90, 110]) pha = p.filter(1024, data, ftype='phase') amp = p.filter(1024, data, ftype='amplitude') pac = p.fit(pha, amp, n_perm=n_perm).squeeze() surro = p.surrogates.squeeze().max(-1) plt.figure(figsize=(6, 4.5)) plt.hist(surro, bins=10, color=color_perm) plt.title("Distribution of surrogates") rmaxis(plt.gca()) plt.autoscale(axis='both', tight=True) plt.xticks([]), plt.yticks([]) plt.tight_layout() savefig('perm')
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()
# 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()
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, random_state=0) # 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()
############################################################################### data, time = pac_signals_wavelet(f_pha=6, f_amp=70, n_epochs=n_epochs, noise=1, n_times=n_times, sf=sf) psd = PSD(data, sf) trif, tridx = pac_trivec(f_start=40, f_end=100, f_width=3) p = Pac(idpac=(6, 0, 0), f_pha=[5, 7], f_amp=trif) pha = p.filter(sf, data, ftype='phase') amp = p.filter(sf, data, ftype='amplitude') pac = p.fit(pha, amp, n_jobs=-1).mean(-1).squeeze() best_f = trif[pac.argmax()] plt.figure(figsize=(16, 7)) plt.subplot(121) ax = psd.plot(confidence=None, f_min=2, f_max=30, log=False, grid=True) plt.ylim(0, .15) plt.title("Power Spectrum Density (PSD)") # plt.autoscale(enable=True, axis='y', tight=True) ax = plt.gca() ax.text(*tuple(cfg["nb_pos"]), 'A', transform=ax.transAxes, **cfg["nb_cfg"]) plt.subplot(122) p.triplot(pac, trif,
npts = 3000 # Number of time points data, time = pac_signals_tort(sf=sf, fpha=[4, 6], famp=[90, 110], noise=3, ntrials=n, dpha=10, damp=10, npts=npts) # First, let's use the MVL, without any further correction by surrogates : p = Pac(fpha=(1, 10, 1, .1), famp=(60, 140, 1, 1), dcomplex='wavelet', width=6) # 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([1, 2, 3, 4, 5]): # 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, axis=2) # Plot : plt.subplot(2, 3, k) p.comodulogram(xpac.mean(-1), title=p.method, cmap='Spectral_r') plt.show()