Ejemplo n.º 1
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
Ejemplo n.º 2
0
    def test_functional_erpac(self):
        """Test function test_functional_pac."""
        # erpac simultation
        n_epochs, n_times, sf, edges = 400, 1000, 512., 50
        x, times = pac_signals_wavelet(f_pha=10,
                                       f_amp=100,
                                       n_epochs=n_epochs,
                                       noise=.1,
                                       n_times=n_times,
                                       sf=sf)
        times = times[edges:-edges]
        # phase / amplitude extraction (single time)
        p = EventRelatedPac(f_pha=[8, 12],
                            f_amp=(30, 200, 5, 5),
                            dcomplex='wavelet',
                            width=12)
        kw = dict(n_jobs=1, edges=edges)
        phases = p.filter(sf, x, ftype='phase', **kw)
        amplitudes = p.filter(sf, x, ftype='amplitude', **kw)
        n_amp = len(p.yvec)
        # generate a normal distribution
        gt = np.zeros((n_amp, n_times - 2 * edges))
        b_amp = np.abs(p.yvec.reshape(-1, 1) - np.array([[80, 120]])).argmin(0)
        gt[b_amp[0]:b_amp[1] + 1, :] = True

        plt.figure(figsize=(16, 5))
        plt.subplot(131)
        p.pacplot(gt, times, p.yvec, title='Ground truth', cmap='magma')

        for n_meth, meth in enumerate(['circular', 'gc']):
            # compute erpac + p-values
            erpac = p.fit(phases,
                          amplitudes,
                          method=meth,
                          mcp='bonferroni',
                          n_perm=30).squeeze()
            pvalues = p.pvalues.squeeze()
            # find everywhere erpac is significant + compare to ground truth
            is_signi = pvalues < .05
            erpac[~is_signi] = np.nan
            # computes accuracy
            acc = 100 * (is_signi == gt).sum() / (n_amp * n_times)
            assert acc > 80.
            # plot the result
            title = f"Method={p.method}\nAccuracy={np.around(acc, 2)}%"
            plt.subplot(1, 3, n_meth + 2)
            p.pacplot(erpac, times, p.yvec, title=title)
        plt.tight_layout()
        plt.show()
Ejemplo n.º 3
0
 def test_pac_signals_bandwidth(self):
     """Definition of artificially coupled signals using bandwidth."""
     assert pac_signals_tort(f_pha=[5, 7],
                             f_amp=[30, 60],
                             sf=200.,
                             n_epochs=100,
                             chi=0.5,
                             noise=3.,
                             n_times=1000)
     assert pac_signals_wavelet(f_pha=10,
                                f_amp=57.,
                                n_times=1240,
                                sf=256,
                                noise=.7,
                                n_epochs=33,
                                pp=np.pi / 4,
                                rnd_state=23)
Ejemplo n.º 4
0
import matplotlib.pyplot as plt

###############################################################################
# Generate a synthetic signal
###############################################################################
# in order to illustrate how the ERPAC does works, we are going to concatenate
# two signals. A first one with an alpha <-> gamma coupling during one second
# and then a second one which is going to be a one second random noise

# First signal consisting of a one second 10 <-> 100hz coupling
n_epochs = 300
n_times = 1000
sf = 1000.
x1, tvec = pac_signals_wavelet(f_pha=10,
                               f_amp=100,
                               n_epochs=n_epochs,
                               noise=.8,
                               n_times=n_times,
                               sf=sf)

# Second signal : one second of random noise
x2 = np.random.rand(n_epochs, 1000)

# now, concatenate the two signals across the time axis
x = np.concatenate((x1, x2), axis=1)
time = np.arange(x.shape[1]) / sf

###############################################################################
# Define an ERPAC object and extract the phase and the amplitude
###############################################################################
# use :class:`tensorpac.EventRelatedPac.filter` method to extract phases and
# amplitudes
import matplotlib.pyplot as plt

###############################################################################
# Simulate artificial coupling
###############################################################################
# first, we generate a several trials that contains a coupling between a 4z
# phase and a 100hz amplitude. By default, the returned dataset is organized as
# (n_epochs, n_times) where n_times is the number of time points and n_epochs
# is the number of trials

f_pha = 4.      # frequency for phase
f_amp = 100.    # frequency for amplitude
sf = 1024.      # sampling frequency
n_epochs = 40   # number of epochs
n_times = 2000  # number of time-points
x, _ = pac_signals_wavelet(sf=sf, f_pha=4, f_amp=100, noise=1.,
                           n_epochs=n_epochs, n_times=n_times)
times = np.linspace(-1, 1, n_times)

###############################################################################
# Define the peak-locking object and realign TF representations
###############################################################################
# then, we define an instance of :class:`tensorpac.utils.PeakLockedTF`. This
# is assessed by using a reference time-point (here we used a cue at 0 second),
# a single phase interval and several amplitudes

cue = 0.                 # time-point of reference (in seconds)
f_pha = [3, 5]           # single frequency phase interval
f_amp = (60, 140, 3, 1)  # amplitude frequencies
p_obj = PeakLockedTF(x, sf, cue, times=times, f_pha=f_pha, f_amp=f_amp)

###############################################################################
Ejemplo n.º 6
0
plt.style.use('seaborn-poster')
sns.set_style("white")
plt.rc('font', family=cfg["font"])

###############################################################################
sf = 1024
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)
Ejemplo n.º 7
0
###############################################################################
# Simulate artificial coupling
###############################################################################
# first, we generate several trials that contains a coupling between a 10hz
# phase and a 100hz amplitude. By default, the returned dataset is organized as
# (n_epochs, n_times) where n_times is the number of time points and n_epochs
# is the number of trials

f_pha = 10  # frequency phase for the coupling
f_amp = 100  # frequency amplitude for the coupling
n_epochs = 20  # number of trials
n_times = 4000  # number of time points
sf = 512.  # sampling frequency
data, time = pac_signals_wavelet(sf=sf,
                                 f_pha=f_pha,
                                 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)
Ejemplo n.º 8
0
import matplotlib.pyplot as plt

plt.style.use('seaborn-poster')
sns.set_style("white")
plt.rc('font', family=cfg["font"])

###############################################################################
sf = 1024
n_epochs = 50
n_times = 3000
n_perm = 20
###############################################################################

data, time = pac_signals_wavelet(sf=sf,
                                 f_pha=10,
                                 f_amp=100,
                                 noise=3.,
                                 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='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)
Ejemplo n.º 9
0
plt.style.use('seaborn-poster')

###############################################################################
# Generate synthetic signals (sake of illustration)
###############################################################################
# to illustrate how does the preferred phase works, we generate synthetic
# signals where a 6hz phase is coupled with a 100hz amplitude. We also
# define a maximum amplitude at pi / 2
sf = 1024.
n_epochs = 100
n_times = 2000
pp = np.pi / 2
data, time = pac_signals_wavelet(f_pha=6,
                                 f_amp=100,
                                 n_epochs=n_epochs,
                                 sf=sf,
                                 noise=1,
                                 n_times=n_times,
                                 pp=pp)

###############################################################################
# Extract phases, amplitudes and compute the preferred phase
###############################################################################
p = PreferredPhase(f_pha=[5, 7], f_amp=(60, 200, 10, 1))

# Extract the phase and the amplitude :
pha = p.filter(sf, data, ftype='phase', n_jobs=1)
amp = p.filter(sf, data, ftype='amplitude', n_jobs=1)

# Now, compute the PP :
ampbin, pp, vecbin = p.fit(pha, amp, n_bins=72)
Ejemplo n.º 10
0
    * The evolution of coupling across time for several frequency amplitude
"""
import numpy as np

from tensorpac.signals import pac_signals_wavelet

from visbrain.objects import PacmapObj, SceneObj

"""Generate artificillly coupled signals :
- First coupling between 10hz phase with a 80hz amplitude
- Second coupling between 5hz phase with a 100hz amplitude

The final signal is the concatenation of both
"""
sf = 1024.
s_1 = pac_signals_wavelet(sf=sf, f_pha=10., f_amp=80., n_epochs=1,
                          n_times=5000)[0]
s_2 = pac_signals_wavelet(sf=sf, f_pha=5., f_amp=100., n_epochs=1,
                          n_times=5000)[0]
sig = np.c_[s_1, s_2]

sc = SceneObj(size=(1200, 600))

print("""
# =============================================================================
#                              Comodulogram
# =============================================================================
""")
pac_obj_como = PacmapObj('como', sig, sf=sf, f_pha=(2, 30, 1, .5),
                         f_amp=(60, 150, 10, 1), interpolation='bicubic')
sc.add_to_subplot(pac_obj_como, row=0, col=0, zoom=.9, title='Comodulogram')
Ejemplo n.º 11
0
"""
from tensorpac import Pac
from tensorpac.signals import pac_signals_wavelet

import matplotlib.pyplot as plt

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)
"""
from __future__ import print_function
import matplotlib.pyplot as plt

from tensorpac import Pac
from tensorpac.signals import pac_signals_wavelet
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))
import matplotlib.pyplot as plt

###############################################################################
# Simulate the data coming from two experimental conditions
###############################################################################
# Let's start by simulating data coming from two experimental conditions. The
# first dataset is going to simulate a 10hz phase <-> 120hz amplitude
# coupling while the second dataset will not include any coupling (random data)

# create the first dataset with a 10hz <-> 100hz coupling
n_epochs = 30  # number of datasets
sf = 512.  # sampling frequency
n_times = 4000  # Number of time points
x_1, time = pac_signals_wavelet(sf=sf,
                                f_pha=10,
                                f_amp=120,
                                noise=2.,
                                n_epochs=n_epochs,
                                n_times=n_times)
# create a second random dataset without any coupling
x_2 = np.random.rand(n_epochs, n_times)

###############################################################################
# Compute the single trial PAC on both datasets
###############################################################################
# once the datasets created, we can now extract the PAC, computed across
# time-points for each trials and across several phase and amplitude
# frequencies

# create the pac object. Use the Gaussian-Copula PAC
p = Pac(idpac=(6, 0, 0), f_pha='hres', f_amp='hres', dcomplex='wavelet')
# compute pac for both dataset