def test_erpac(): """Test the ERPAC.""" data = np.random.rand(2, 1024) p = Pac(idpac=(4, 0, 0)) pha = p.filter(1024, data, axis=1, ftype='phase') amp = p.filter(1024, data, axis=1, ftype='amplitude') p.erpac(pha, amp, traxis=1)
def test_preferred_phase(): """Test the prefered phase.""" data = np.random.rand(2, 1024) p = Pac(idpac=(4, 0, 0)) pha = p.filter(1024, data, axis=1, ftype='phase') amp = p.filter(1024, data, axis=1, ftype='amplitude') p.pp(pha, amp, axis=2)
def test_spectral(self): """Test filtering using the provided filters.""" data = np.random.rand(3, 1000) p = Pac() dcomplex = ['hilbert', 'wavelet'] for k in dcomplex: p.dcomplex = k p.filter(1024, data, n_jobs=1)
def test_filterfit(self): """Test filtering test computing PAC.""" data = np.random.rand(2, 1024) p = Pac(idpac=(4, 0, 0)) p.filterfit(1024, data, n_jobs=1) p.idpac = (1, 1, 1) p.filterfit(1024, data, data, n_jobs=1, n_perm=2) p.dcomplex = 'wavelet' p.filter(1024, data, n_jobs=1)
def test_spectral(): """Test filtering using the provided filters.""" data = np.random.rand(3, 1000) p = Pac() dcomplex = ['hilbert', 'wavelet'] filt = ['butter', 'fir1', 'bessel'] for k in dcomplex: for i in filt: p.dcomplex = k p.filt = i p.filter(1024, data, axis=1, njobs=1)
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_filter(self): """Test filter method.""" data = np.random.rand(2, 1000) p = Pac() p.filter(256, data, 'phase') p.filter(256, data, 'phase', edges=2) p.filter(256, data, 'amplitude')
from tensorpac import pac_signals_wavelet, Pac plt.style.use('seaborn-poster') # Generate 100 datasets with a 6<->100hz coupling : sf = 1024. ntrials = 100 data, time = pac_signals_wavelet(fpha=6, famp=100, ntrials=ntrials, sf=sf, noise=.7, npts=2000, pp=np.pi/2) # Define a Pac object. Here, we are not going to use the idpac variable : p = Pac(fpha=[5, 7], famp=(60, 200, 10, 1)) # Extract the phase and the amplitude : pha = p.filter(sf, data, axis=1, ftype='phase') amp = p.filter(sf, data, axis=1, ftype='amplitude') # Now, compute the PP : ambin, pp, vecbin = p.pp(pha, amp, axis=2, nbins=72) # Reshape the PP to be (ntrials, namp) : pp = np.squeeze(pp).T # Reshape the amplitude to be (nbins, namp, ntrials) and take the mean across # datasets : ambin = np.squeeze(ambin).mean(-1) plt.figure(figsize=(20, 35)) # Plot the prefered phase : plt.subplot(221)
n_epochs = 1 n_times = 100000 n_bins = 30 ############################################################################### data, time = pac_signals_wavelet(sf=sf, f_pha=10, f_amp=100, noise=2., n_epochs=n_epochs, n_times=n_times, rnd_state=0) # extract the phase and the amplitude p = Pac(idpac=(1, 0, 0), f_pha=[8, 12], f_amp=[60, 140]) pha = p.filter(sf, data, ftype='phase', n_jobs=1).squeeze() amp = p.filter(sf, data, ftype='amplitude', n_jobs=1).squeeze() # z-score normalize the amplitude amp_n = (amp - amp.mean()) / amp.std() plt.figure(figsize=(18, 5)) plt.subplot(131) plt.hist(pha, n_bins, color='blue') plt.title('Binned phase') plt.subplot(132) plt.hist(amp, n_bins, color='red') plt.title('Binned amplitude')
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()
f_amp=f_amp, noise=.8, n_epochs=n_epochs, n_times=n_times) ############################################################################### # Extract phases and amplitudes ############################################################################### # Since we're going to compute PAC using several methods, we're first going # 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
sf = 1024 n_epochs = 1 n_times = 100000 ########################################################################### data, time = pac_signals_wavelet(sf=sf, f_pha=10, f_amp=100, noise=2., n_epochs=n_epochs, 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,
# in [40, 120]Hz. this confirm that indeed, there is the presence of # alpha <-> gamma PAC occurring during the planning phase ############################################################################### # Compute and compare PAC that is occurring during rest, planning and execution ############################################################################### # we now know that an alpha [8, 12]Hz <-> gamma (~90Hz) should occur # specifically during the planning phase. An other way to inspect this result # is to compute the PAC, across time-points, during the rest, motor planning # and motor execution periods. Bellow, we first extract several phases and # amplitudes, then we compute the Gaussian-Copula PAC inside the three motor # 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) ##############################################################################
def savefig(save_as): """Save the figure.""" plt.savefig(f"{save_as}.pdf", dpi=600, bbox_inches='tight') # random signals data, time = pac_signals_tort(n_epochs=1, f_pha=10, f_amp=100, sf=1024, n_times=1025) data = normalize(data, -1, 1) # extract phase / amplitude p = Pac(idpac=(1, 2, 3), f_pha=[9, 11], f_amp=[90, 110]) phase = p.filter(1024, data, ftype='phase') x10hz = p.filter(1024, data, ftype='phase', keepfilt=True) amplitude = p.filter( 1024, data, ftype='amplitude', ) x100hz = p.filter(1024, data, ftype='amplitude', keepfilt=True) ############################################################################### # Raw time-series ############################################################################### plt.figure(1, figsize=(8.5, 2.5)) plt.plot(time, np.squeeze(data), color=color_raw, linewidth=.7) plt.yticks([-1, 0, 1]) plt.xlabel('Time'), plt.ylabel('mV')
# Generate a 10<->100hz coupling : ntrials = 300 npts = 1000 sf = 1024. x1, tvec = pac_signals_tort(fpha=10, famp=100, ntrials=ntrials, noise=2, npts=npts, dpha=10, damp=10, sf=sf) # Generate noise and concatenate the coupling and the noise : x2 = np.random.rand(ntrials, 700) x = np.concatenate((x1, x2), axis=1) # Shape : (ntrials, npts) time = np.arange(x.shape[1]) / sf # Define a PAC object : p = Pac(fpha=[9, 11], famp=(60, 140, 5, 1), dcomplex='wavelet', width=12) # Extract the phase and the amplitude : pha = p.filter(sf, x, axis=1, ftype='phase') # Shape (npha, ntrials, npts) amp = p.filter(sf, x, axis=1, ftype='amplitude') # Shape (namp, ntrials, npts) # Compute the ERPAC and use the traxis to specify that the trial axis is the # first one : erpac, pval = p.erpac(pha, amp, traxis=1) # Remove unused dimensions : erpac, pval = np.squeeze(erpac), np.squeeze(pval) # Plot without p-values : p.pacplot(erpac, time, p.yvec, xlabel='Time (second)', cmap='Spectral_r', ylabel='Amplitude frequency', title=str(p), cblabel='ERPAC', vmin=0., rmaxis=True) # Plot with every non-significant values masked in gray :