import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hilbert
from scipy.io import loadmat
from scipy.fftpack import fft, ifft
from numpy.random import rand, randn, choice
Chapter 19
Chapter 19
Analyzing Neural Time Series Data
Python code for Chapter 19 – converted from original Matlab by AE Studio (and ChatGPT)
Original Matlab code by Mike X Cohen
This code accompanies the book, titled “Analyzing Neural Time Series Data” (MIT Press).
Using the code without following the book may lead to confusion, incorrect data analyses, and misinterpretations of results.
Mike X Cohen and AE Studio assume no responsibility for inappropriate or incorrect use of this code.
Import necessary libraries
# Define a function to more easily plot multiple polar vectors
def plot_polar_vectors(ax, angles, lengths=None, average_angle=None, average_length=None):
if lengths is None:
= np.ones_like(angles)
lengths for angle, length in zip(angles, lengths):
0, angle], [0, length])
ax.plot([if average_angle is not None and average_length is not None:
0, average_angle], [0, average_length]) ax.plot([
Figure 19.1
# Define angles
= [0.2, 2*np.pi-.2]
a
# Plot unit vectors defined by those angles
= plt.subplots(subplot_kw={'polar': True})
fig, ax
plot_polar_vectors(ax, a)# Plot a unit vector with the average angle
1])
plot_polar_vectors(ax, [np.mean(a)], [# Plot the average vector
= np.mean(np.exp(1j*np.array(a)))
mean_vector abs(mean_vector)])
plot_polar_vectors(ax, [np.angle(mean_vector)], [np. plt.show()
Figure 19.2
# Load sample scalp EEG data
= loadmat('../data/sampleEEGdata.mat')['EEG'][0, 0]
EEG
# Center frequency
= 12 # in Hz
centerfreq = 'Pz'
chan2plot = [200, 800] # in ms, from stimulus onset
times2plot
# Define convolution parameters
= EEG['pnts'][0][0]
n_wavelet = EEG['pnts'][0][0] * EEG['trials'][0][0]
n_data = n_wavelet + n_data - 1
n_convolution = int(2**np.ceil(np.log2(n_convolution)))
n_conv_pow2
# Create wavelet
= np.arange(-(n_wavelet/EEG['srate'][0][0]/2), n_wavelet/EEG['srate'][0][0]/2, 1/EEG['srate'][0][0])
time = np.exp(2*1j*np.pi*centerfreq*time) * np.exp(-time**2 / (2 * ((4 / (2 * np.pi * centerfreq))**2))) / centerfreq
wavelet
# Get FFT of data
= fft(EEG['data'][EEG['chanlocs'][0]['labels']==chan2plot, :, :].flatten('F'), n_conv_pow2)
eegfft
# Convolution
= ifft(fft(wavelet, n_conv_pow2) * eegfft)
eegconv = eegconv[:n_convolution]
eegconv = np.reshape(eegconv[int(np.floor((EEG['pnts'][0][0]-1)/2))-1:-int(np.ceil((EEG['pnts'][0][0]-1)/2))-1], (EEG['pnts'][0][0], EEG['trials'][0][0]), 'F')
eegconv
# Plot
plt.figure()for subploti, timepoint in enumerate(times2plot):
= np.argmin(np.abs(EEG['times'][0] - timepoint))
idx = plt.subplot(2, 2, subploti+1, polar=True)
ax 'trials'][0][0]))
plot_polar_vectors(ax, np.angle(eegconv[idx,:]), np.ones(EEG[f'ITPC at {timepoint} ms = {np.round(np.abs(np.mean(np.exp(1j*np.angle(eegconv[idx,:])))), 3)}')
ax.set_title(
= plt.subplot(2, 2, subploti+3)
ax =20)
ax.hist(np.angle(eegconv[idx,:]), bins0, 20])
ax.set_ylim([-np.pi, -np.pi/2, 0, np.pi/2, np.pi], ['-pi', '-pi/2', '0', 'pi/2', 'pi'])
ax.set_xticks([
plt.tight_layout() plt.show()
Figure 19.3
= [[0, np.pi/3], [0, np.pi/2], [0, 2*np.pi/3], [0, np.pi*.9]]
vectors
=(12, 3))
plt.figure(figsizefor i, vec in enumerate(vectors):
= plt.subplot(1, 4, i+1, polar=True)
ax # Plot individual unit vectors
plot_polar_vectors(ax, vec)# Plot mean vector
= np.mean(np.exp(1j*np.array(vec)))
meanvect abs(meanvect)])
plot_polar_vectors(ax, [np.angle(meanvect)], [np.f'Mean vector length: {np.abs(meanvect):.5f}')
ax.set_title(
plt.tight_layout() plt.show()
Figure 19.4
# Get FFT of data
= 'Pz'
chan2plot = 12 # in Hz
centerfreq = fft(EEG['data'][EEG['chanlocs'][0]['labels']==chan2plot, :, :].flatten('F'), n_conv_pow2)
eegfft
# ITPC at one frequency band
= np.exp(2*1j*np.pi*centerfreq*time) * np.exp(-time**2 / (2 * ((4 / (2 * np.pi * centerfreq))**2))) / centerfreq
wavelet # Convolution
= ifft(fft(wavelet, n_conv_pow2) * eegfft)
eegconv = eegconv[:n_convolution]
eegconv = np.reshape(eegconv[int(np.floor((EEG['pnts'][0][0]-1)/2))-1:-int(np.ceil((EEG['pnts'][0][0]-1)/2))-1], (EEG['pnts'][0][0], EEG['trials'][0][0]), 'F')
eegconv
plt.figure()'times'][0], np.abs(np.mean(np.exp(1j*np.angle(eegconv)), axis=1)))
plt.plot(EEG[-200, 1000])
plt.xlim([0, 0.7])
plt.ylim(['Time (ms)')
plt.xlabel('ITPC')
plt.ylabel(
plt.show()
# TF plot of ITPC
= np.logspace(np.log10(4), np.log10(40), 20)
frequencies = np.logspace(np.log10(3), np.log10(10), len(frequencies)) / (2 * np.pi * frequencies)
s = np.zeros((len(frequencies), EEG['pnts'][0][0]))
itpc
for fi, freq in enumerate(frequencies):
# Create wavelet
= np.exp(2*1j*np.pi*freq*time) * np.exp(-time**2 / (2 * (s[fi]**2))) / freq
wavelet
# Convolution
= ifft(fft(wavelet, n_conv_pow2) * eegfft)
eegconv = eegconv[:n_convolution]
eegconv = np.reshape(eegconv[int(np.floor((EEG['pnts'][0][0]-1)/2))-1:-int(np.ceil((EEG['pnts'][0][0]-1)/2))-1], (EEG['pnts'][0][0], EEG['trials'][0][0]), 'F')
eegconv
# Extract ITPC
= np.abs(np.mean(np.exp(1j*np.angle(eegconv)), axis=1))
itpc[fi, :]
plt.figure()'times'][0], frequencies, itpc, 40, cmap='viridis')
plt.contourf(EEG[0, 0.6])
plt.clim([-200, 1000])
plt.xlim(['Time (ms)')
plt.xlabel('Frequencies (Hz)')
plt.ylabel( plt.show()
Figure 19.5
= 500
n_trials = np.zeros(n_trials)
itpcByNFake
for n in range(n_trials):
for iteri in range(50):
+= np.abs(np.mean(np.exp(1j*(rand(n+1)*2*np.pi-np.pi))))
itpcByNFake[n] /= 50
itpcByNFake
# Z and P
= np.arange(1, n_trials+1) * (itpcByNFake**2)
itpcByNFakeZ = np.exp(np.sqrt(1 + 4*np.arange(1, n_trials+1) + 4*((np.arange(1, n_trials+1)**2) - (np.arange(1, n_trials+1)*itpcByNFake)**2)) - (1 + 2*np.arange(1, n_trials+1)))
itpcByNFakeP = np.sqrt(-np.log(0.01) / np.arange(1, n_trials+1))
itpcFakeCrit
plt.figure()1, n_trials+1), itpcByNFake)
plt.plot(np.arange(1, n_trials+1), itpcFakeCrit, 'r')
plt.plot(np.arange(0, 500])
plt.xlim([0, 1])
plt.ylim(['ITPC_raw', 'ITPC_Crit'])
plt.legend([ plt.show()
Figure 19.6
# Center frequency
= 6 # Hz
centerfreq = 'FCz'
chan2plot
# Define convolution parameters
= EEG['pnts'][0][0]
n_wavelet = EEG['pnts'][0][0] * EEG['trials'][0][0]
n_data = n_wavelet + n_data - 1
n_convolution = int(2**np.ceil(np.log2(n_convolution)))
n_conv_pow2
# Create wavelet
= np.arange(-(n_wavelet/EEG['srate'][0][0]/2), n_wavelet/EEG['srate'][0][0]/2, 1/EEG['srate'][0][0])
time = np.exp(2*1j*np.pi*centerfreq*time) * np.exp(-time**2 / (2 * ((4 / (2 * np.pi * centerfreq))**2))) / centerfreq
wavelet
# Get FFT of data
= fft(EEG['data'][EEG['chanlocs'][0]['labels']==chan2plot, :, :].flatten('F'), n_conv_pow2)
eegfft
# Convolution
= ifft(fft(wavelet, n_conv_pow2) * eegfft)
eegconv = eegconv[:n_convolution]
eegconv = np.reshape(eegconv[int(np.floor((EEG['pnts'][0][0]-1)/2))-1:-int(np.ceil((EEG['pnts'][0][0]-1)/2))-1], (EEG['pnts'][0][0], EEG['trials'][0][0]), 'F')
eegconv
plt.figure()
# Compute ITPC as function of N
= np.zeros(EEG['trials'][0][0])
itpcByN for n in range(EEG['trials'][0][0]):
for iteri in range(50):
= choice(EEG['trials'][0][0], n+1, replace=False)
trials2use += np.mean(np.abs(np.mean(np.exp(1j*np.angle(eegconv[281:372, trials2use])), axis=1)))
itpcByN[n] /= 50
itpcByN
# Z and P
= np.arange(1, EEG['trials'][0][0]+1) * (itpcByN**2)
itpcByNZ = np.exp(np.sqrt(1 + 4*np.arange(1, EEG['trials'][0][0]+1) + 4*((np.arange(1, EEG['trials'][0][0]+1)**2) - (np.arange(1, EEG['trials'][0][0]+1)*itpcByN)**2)) - (1 + 2*np.arange(1, EEG['trials'][0][0]+1)))
itpcByNP = np.sqrt(-np.log(0.01) / np.arange(1, EEG['trials'][0][0]+1))
itpcCrit
211)
plt.subplot(
plt.plot(itpcByN)'r')
plt.plot(itpcCrit, 0, 100])
plt.xlim(['Number of trials in analysis')
plt.xlabel('ITPC')
plt.ylabel(0.2, 1])
plt.ylim([
# Note that this figure will look different than that in the book because trials are randomly selected.
212)
plt.subplot('times'][0], np.abs(np.mean(np.exp(1j*np.angle(eegconv)), axis=1)))
plt.plot(EEG[= np.random.permutation(EEG['trials'][0][0])
randomtrials2plot 'times'][0], np.abs(np.mean(np.exp(1j*np.angle(eegconv[:, randomtrials2plot[:20]])), axis=1)), ':')
plt.plot(EEG[-1000, 1500])
plt.xlim(['Time (ms)')
plt.xlabel('ITPC')
plt.ylabel('99 trials', '20 trials'])
plt.legend([
plt.tight_layout() plt.show()
Figure 34.8: Statistical evaluation of ITPC values
This cell concerns statistical evaluation of ITPC values. It will be discussed in depth in chapter 34, but the code is presented here because it relies on calculations from the previous two figures.
# p-values under assumption of von Mises distribution
= np.exp(-itpcByNFakeZ)
approx_pval_fake = np.exp(-itpcByNZ)
approx_pval_real
= 10
ncutoff
=(12, 6))
plt.figure(figsize
# Plot p-values from fake data
121)
plt.subplot('mo', markersize=8)
plt.plot(itpcByNFakeP[ncutoff:], approx_pval_fake[ncutoff:], 'k.')
plt.plot(itpcByNFakeP[:ncutoff], approx_pval_fake[:ncutoff], 0, 1], [0, 1], 'k')
plt.plot([0, 1])
plt.xlim([0, 1])
plt.ylim([0, 1.25, 0.25))
plt.xticks(np.arange(0, 1.25, 0.25))
plt.yticks(np.arange('approximate p')
plt.ylabel('exact p')
plt.xlabel('P-values from fake data')
plt.title(
# Plot p-values from real data
122)
plt.subplot('mo', markersize=8)
plt.plot(itpcByNP[ncutoff:], approx_pval_real[ncutoff:], 'k.')
plt.plot(itpcByNP[:ncutoff], approx_pval_real[:ncutoff], 0.00001, 1], [0.00001, 1], 'k')
plt.plot([.0001, 1])
plt.xlim([.0001, 1])
plt.ylim(['log')
plt.xscale('log')
plt.yscale('approximate p')
plt.ylabel('exact p')
plt.xlabel('P-values from real data')
plt.title(
plt.tight_layout() plt.show()
Figure 19.7
This figure takes a while to generate. You could also reduce the number of iterations to speed it up.
Data for this cell are from figure 19.6. If you want to plot results from a different channel, change the electrode in 19.6.
# Center frequencies
= np.arange(1, 41)
frequencies
= 50
niterations
# Initialize
= np.zeros((len(frequencies), EEG['trials'][0][0]))
itpcByNandF
for fi, centerfreq in enumerate(frequencies):
= np.exp(2*1j*np.pi*centerfreq*time) * np.exp(-time**2 / (2 * ((4 / (2 * np.pi * centerfreq))**2))) / centerfreq
wavelet
# Convolution
= ifft(fft(wavelet, n_conv_pow2) * eegfft)
eegconv = eegconv[:n_convolution]
eegconv = np.reshape(eegconv[int(np.floor((EEG['pnts'][0][0]-1)/2))-1:-int(np.ceil((EEG['pnts'][0][0]-1)/2))-1], (EEG['pnts'][0][0], EEG['trials'][0][0]), 'F')
eegconv
for n in range(EEG['trials'][0][0]):
for iteri in range(niterations):
= choice(EEG['trials'][0][0], n+1, replace=False)
trials2use += np.mean(np.abs(np.mean(np.exp(1j*np.angle(eegconv[281:372, trials2use])), axis=1)))
itpcByNandF[fi, n]
plt.figure()1, EEG['trials'][0][0]+1), frequencies, itpcByNandF / (iteri+1), 40, cmap='gray')
plt.contourf(np.arange(0.1, 0.5])
plt.clim(['Trials')
plt.xlabel('Frequency (Hz)')
plt.ylabel( plt.show()
Figure 19.8
=(12, 6))
plt.figure(figsize"Rayleigh's Z")
plt.suptitle(
121)
plt.subplot(
plt.plot(itpcByN)99], 'r')
plt.plot(itpcByNFake[:0, 100])
plt.xlim([0, 1])
plt.ylim(['Trial count')
plt.xlabel('ITPC')
plt.ylabel(
122)
plt.subplot(
plt.plot(itpcByNZ)99], 'r')
plt.plot(itpcByNFakeZ[:0, 100])
plt.xlim([0, 12])
plt.ylim(['Trial count')
plt.xlabel('ITPC_Z')
plt.ylabel('real data', 'fake data'])
plt.legend([
plt.tight_layout() plt.show()
Figure 19.9
# Pick electrode and frequencies
= 'FCz'
chan2plot = np.arange(1, 41)
frequencies
# Define convolution parameters
= np.arange(-(EEG['pnts'][0][0]/EEG['srate'][0][0]/2), EEG['pnts'][0][0]/EEG['srate'][0][0]/2, 1/EEG['srate'][0][0])
time = EEG['pnts'][0][0]
n_wavelet = EEG['pnts'][0][0] * EEG['trials'][0][0]
n_data = n_wavelet + n_data - 1
n_convolution = int(2**np.ceil(np.log2(n_convolution)))
n_conv_pow2
= ['without jitter', 'with jitter']
plotlegends
=(10, 8))
plt.figure(figsize
= [-300, -100]
baselinetime = [np.argmin(np.abs(EEG['times'][0] - t)) for t in baselinetime]
baseidx
for simuli in range(1, 3):
# Add time jitter (or not)
= np.squeeze(EEG['data'][EEG['chanlocs'][0]['labels']==chan2plot, :, :])
tempdat if simuli == 2:
for ti in range(tempdat.shape[1]):
= int(np.ceil(rand() * 10))*(simuli-1)
timejitter = np.roll(tempdat[:, ti], timejitter)
tempdat[:, ti]
# Get FFT of data
= fft(tempdat.flatten('F'), n_conv_pow2)
eegfft
# Initialize
= np.zeros((len(frequencies), EEG['pnts'][0][0]))
itpc = np.zeros((len(frequencies), EEG['pnts'][0][0]))
powr
for fi, centerfreq in enumerate(frequencies):
= np.exp(2*1j*np.pi*centerfreq*time) * np.exp(-time**2 / (2 * ((4 / (2 * np.pi * centerfreq))**2))) / centerfreq
wavelet
# Convolution
= ifft(fft(wavelet, n_conv_pow2) * eegfft)
eegconv = eegconv[:n_convolution]
eegconv = np.reshape(eegconv[int(np.floor((n_wavelet-1)/2))-1:-int(np.ceil((n_wavelet-1)/2))-1], (EEG['pnts'][0][0], EEG['trials'][0][0]), 'F')
eegconv
# Compute and store ITPC and power
= np.abs(np.mean(np.exp(1j*np.angle(eegconv)), axis=1))
itpc[fi, :] = np.mean(np.abs(eegconv)**2, axis=1)
powr[fi, :] = 10 * np.log10(powr[fi, :] / np.mean(powr[fi, baseidx]))
powr[fi, :]
2, 2, simuli)
plt.subplot('times'][0], frequencies, itpc, 40, cmap='viridis')
plt.contourf(EEG[0.1, 0.5])
plt.clim([-200, 1000])
plt.xlim(['Time (ms)')
plt.xlabel('Frequency (Hz)')
plt.ylabel(f'ITPC {plotlegends[simuli-1]}')
plt.title(
2, 2, simuli+2)
plt.subplot('times'][0], frequencies, powr, 40, cmap='viridis')
plt.contourf(EEG[-3, 3])
plt.clim([-200, 1000])
plt.xlim(['Time (ms)')
plt.xlabel('Frequency (Hz)')
plt.ylabel(f'DB-power {plotlegends[simuli-1]}')
plt.title(
plt.tight_layout() plt.show()
Figure 19.10
# Initialize
= np.zeros((2, len(time), EEG['trials'][0][0]))
data4test = 'P7'
sensor2use
# Amplitude modulation (modulate power by 1 Hz sine wave)
= np.arange(-(EEG['pnts'][0][0]/EEG['srate'][0][0]/2), EEG['pnts'][0][0]/EEG['srate'][0][0]/2, 1/EEG['srate'][0][0])
time = (np.sin(2*np.pi*1.*time) + 2) - 1
amp_mod
for triali in range(EEG['trials'][0][0]):
# Each trial is a random channel and trial
= EEG['data'][EEG['chanlocs'][0]['labels']==sensor2use, :, triali]
trialdata
# Uncomment the next line of code for band-pass filtered data.
# This uses the eegfilt function, which is part of the eeglab toolbox.
# trialdata = eegfilt(double(trialdata), EEG['srate'][0][0], 10, 20)
0, :, triali] = trialdata * amp_mod
data4test[1, :, triali] = trialdata
data4test[
# Compute ITPC
= np.abs(np.mean(np.exp(1j*np.angle(np.reshape(hilbert(data4test[0, :, :].flatten('F')), (EEG['pnts'][0][0], EEG['trials'][0][0]), 'F'))), axis=1))
itpc_mod = np.abs(np.mean(np.exp(1j*np.angle(hilbert(data4test[1, :, :]))), axis=1))
itpc_nomod
# Plot!
=(10, 8))
plt.figure(figsize
311)
plt.subplot('times'][0], amp_mod)
plt.plot(EEG[-1000, 1500])
plt.xlim([-.2, 2.2])
plt.ylim(['Amplitude modulator')
plt.title(
312)
plt.subplot('times'][0], data4test[0, :, 9])
plt.plot(EEG['times'][0], data4test[1, :, 9], 'r')
plt.plot(EEG[=True, axis='both', tight=True)
plt.gca().autoscale(enable'Example trials')
plt.title(
313)
plt.subplot('times'][0], itpc_mod)
plt.plot(EEG['times'][0], itpc_nomod, 'r')
plt.plot(EEG['amplitude modulation', 'no amp mod'])
plt.legend([-1000, 1500])
plt.xlim([0, 1])
plt.ylim(['Time (ms)')
plt.xlabel('ITPC')
plt.ylabel('ITPC')
plt.title(
plt.tight_layout()
plt.show()
plt.figure()'.')
plt.plot(amp_mod, itpc_mod, 0, 2])
plt.xlim(['Power modulation')
plt.xlabel('ITPC')
plt.ylabel( plt.show()
Figure 19.11
= rand(50) * 2 * np.pi - np.pi
randvects = (randvects + randn(len(randvects)))**2
vectormod = vectormod - np.min(vectormod) + 1 # make sure no negative values
vectormod2
# ITPC
plt.figure()= plt.subplot(2, 2, 1, polar=True)
ax
plot_polar_vectors(ax, randvects, np.ones_like(randvects))f'ITPC = {np.abs(np.mean(np.exp(1j*randvects)))}')
ax.set_title(
# wITPC
= plt.subplot(2, 2, 2, polar=True)
ax
plot_polar_vectors(ax, randvects, vectormod)
= np.abs(np.mean(vectormod * np.exp(1j*randvects)))
witpc = np.zeros(1000)
perm_witpc
for i in range(1000):
= np.abs(np.mean(vectormod[np.random.permutation(len(vectormod))] * np.exp(1j*randvects)))
perm_witpc[i]
= (witpc - np.mean(perm_witpc)) / np.std(perm_witpc)
witpc_z f'_wITPC_z = {witpc_z}')
ax.set_title(
# Example of one permutation
= plt.subplot(2, 2, 3, polar=True)
ax len(vectormod))])
plot_polar_vectors(ax, randvects, vectormod[np.random.permutation('One null hypothesis iteration')
ax.set_title(
# Histogram of null-hypothesis WITPC
= plt.subplot(2, 2, 4)
ax = np.histogram(perm_witpc, bins=50)
y, x -1], y, width=np.diff(x), edgecolor='none')
ax.bar(x[:'m')
ax.plot([witpc, witpc], plt.gca().get_ylim(), 'Histogram of null hypothesis wITPC')
ax.set_title(
plt.tight_layout() plt.show()
Figure 19.12
= 6
centerfreq = 'PO7'
channel2use = np.arange(-200, 1250, 50)
times2save
# Initialize matrix to store RTs
= np.zeros(EEG['trials'][0][0])
rts
for ei in range(EEG['trials'][0][0]):
# Find which event is time=0, and take the latency of the event thereafter.
= np.where(np.array(EEG['epoch'][0][ei]['eventlatency'][0]) == 0)[0][0]
time0event
# Use try-except in case of no response
try:
= EEG['epoch'][0][ei]['eventlatency'][0][time0event + 1]
rts[ei] except IndexError:
= np.nan
rts[ei]
# Define convolution parameters
= np.arange(-(EEG['pnts'][0][0]/EEG['srate'][0][0]/2), EEG['pnts'][0][0]/EEG['srate'][0][0]/2, 1/EEG['srate'][0][0])
time = EEG['pnts'][0][0]
n_wavelet = EEG['pnts'][0][0] * EEG['trials'][0][0]
n_data = n_wavelet + n_data - 1
n_convolution = int(2**np.ceil(np.log2(n_convolution)))
n_conv_pow2
# Get FFT of data and wavelet
= fft(EEG['data'][EEG['chanlocs'][0]['labels']==channel2use, :, :].flatten('F'), n_conv_pow2)
eegfft = fft(np.exp(2*1j*np.pi*centerfreq*time) * np.exp(-time**2 / (2 * ((4 / (2 * np.pi * centerfreq))**2))), n_conv_pow2)
wavefft
# Convolution
= ifft(wavefft * eegfft)
eegconv = eegconv[:n_convolution]
eegconv = np.reshape(eegconv[int(np.floor((n_wavelet-1)/2))-1:-int(np.ceil((n_wavelet-1)/2))-1], (EEG['pnts'][0][0], EEG['trials'][0][0]), 'F')
eegconv
= np.angle(eegconv)
phase_angles
# Initialize
= np.zeros(len(times2save))
itpc = np.zeros(len(times2save))
witpc = np.zeros(len(times2save))
witpc_z
for ti, timepoint in enumerate(times2save):
# Find index for this time point
= np.argmin(np.abs(EEG['times'][0] - timepoint))
timeidx
# ITPC is unmodulated phase clustering
= np.abs(np.mean(np.exp(1j*phase_angles[timeidx,:])))
itpc[ti]
# wITPC is rts modulating the length of phase angles
= np.abs(np.mean(rts * np.exp(1j*phase_angles[timeidx,:])))
witpc[ti]
# Permutation testing
= np.zeros(1000)
perm_witpc for i in range(1000):
= np.abs(np.mean(rts[np.random.permutation(EEG['trials'][0][0])] * np.exp(1j*phase_angles[timeidx,:])))
perm_witpc[i]
= (witpc[ti] - np.mean(perm_witpc)) / np.std(perm_witpc)
witpc_z[ti]
plt.figure()
# Plot ITPC
= plt.subplot(311)
ax1 'times'][0], np.abs(np.mean(np.exp(1j*phase_angles), axis=1)), label='ITPC')
ax1.plot(EEG[= ax1.twinx()
ax2 ='wITPC', color='orange')
ax2.plot(times2save, witpc, label='y', labelcolor='b')
ax1.tick_params(axis='y', labelcolor='orange')
ax2.tick_params(axis0, 0.8])
ax1.set_ylim([0, 400])
ax2.set_ylim([0], times2save[-1]])
plt.xlim([times2save[f'ITPC and wITPC at {channel2use}')
plt.title(
plt.legend()
# Plot wITPCz
312)
plt.subplot(
plt.plot(times2save, witpc_z)0], times2save[-1]], [0, 0], 'k')
plt.plot([times2save[0], times2save[-1]])
plt.xlim([times2save['Time (ms)')
plt.xlabel('wITPCz')
plt.ylabel(f'wITPCz at {channel2use}')
plt.title(
325)
plt.subplot('.')
plt.plot(itpc, witpc, 'ITPC')
plt.xlabel('wITPC')
plt.ylabel(
326)
plt.subplot('.')
plt.plot(itpc, witpc_z, 'ITPC')
plt.xlabel('wITPCz')
plt.ylabel(
plt.show()