Exemple #1
0
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)
Exemple #2
0
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)
Exemple #3
0
 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)
Exemple #4
0
 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)
Exemple #5
0
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)
Exemple #6
0
    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
Exemple #7
0
 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')
Exemple #15
0
# 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 :