import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import fft, ifft
from scipy.stats import pearsonr
Chapter 25
Chapter 25
Analyzing Neural Time Series Data
Python code for Chapter 25 – 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
Setup for figure 25.3
# generate a random signal of 3 seconds
= 1000
srate
= np.random.randn(3*srate) # 3 seconds, with this sampling rate
randsig1 = np.random.randn(3*srate)
randsig2
# now filter at 5 Hz
= 5 # frequency of wavelet in Hz
f = np.arange(-1, 1+1/srate, 1/srate) # time for wavelet, from -1 to 1 second in steps of 1/sampling-rate
time = 6/(2*np.pi*f) # width of Gaussian
s = np.exp(2*np.pi*1j*f*time) * np.exp(-time**2/(2*s**2))
wavelet
# FFT parameters
= len(wavelet)
n_wavelet = len(randsig1)
n_data = n_wavelet + n_data - 1
n_convolution = (len(wavelet) - 1) // 2
half_of_wavelet_size
# FFT of wavelet and EEG data
= ifft(fft(wavelet, n_convolution) * fft(randsig1, n_convolution), n_convolution) * np.sqrt(s)/10
convolution_result_fft = np.real(convolution_result_fft[half_of_wavelet_size:-half_of_wavelet_size])
filtsig1 = np.angle(convolution_result_fft[half_of_wavelet_size:-half_of_wavelet_size])
anglesig1
= ifft(fft(wavelet, n_convolution) * fft(randsig2, n_convolution), n_convolution) * np.sqrt(s)/10
convolution_result_fft = np.real(convolution_result_fft[half_of_wavelet_size:-half_of_wavelet_size])
filtsig2 = np.angle(convolution_result_fft[half_of_wavelet_size:-half_of_wavelet_size])
anglesig2
# Plot the random signals and their filtered versions
=(12, 6))
plt.figure(figsize
for i in range(2):
2, 1, i+1)
plt.subplot(if i == 0:
='Random Signal 1')
plt.plot(randsig1, label'r', label='Filtered Signal 1')
plt.plot(filtsig1, 0, 3000])
plt.xlim([-3, 4])
plt.ylim([else:
='Random Signal 2')
plt.plot(randsig2, label'r', label='Filtered Signal 2')
plt.plot(filtsig2, 0, 3000])
plt.xlim([-4, 6])
plt.ylim([
plt.legend()
plt.show()
Figure 25.3
# initialize output correlation matrix
= np.zeros((5, round(1000/f)))
correlations
for i in range(round(1000/f)):
# correlation of unfiltered random signal
= pearsonr(randsig1[:-i or None], randsig1[i:])
temp, _ 0, i] = temp
correlations[
# correlation of filtered signal
= pearsonr(filtsig1[:-i or None], filtsig1[i:])
temp, _ 1, i] = temp
correlations[
# phase clustering
= np.angle(anglesig1[:-i or None] - anglesig1[i:])
phase_diff1 2, i] = np.abs(np.mean(np.exp(1j*phase_diff1)))
correlations[
# difference of correlations of filtered signal
= pearsonr(filtsig2[:-i or None], filtsig2[i:])
temp, _ 3, i] = temp - correlations[1, i]
correlations[
# difference of phase clusterings
= np.angle(anglesig2[:-i or None] - anglesig2[i:])
phase_diff2 4, i] = np.abs(np.mean(np.exp(1j*phase_diff2))) - correlations[2, i]
correlations[
# Plot the correlations
=(12, 6))
plt.figure(figsize
plt.plot(correlations.T)0, 200])
plt.xlim([-1, 1])
plt.ylim(['Lag (ms)')
plt.xlabel('Connectivity strength')
plt.ylabel('unfiltered', 'power corr', 'ISPC', 'corr diffs', 'ISPC diffs'])
plt.legend([ plt.show()