0
$\begingroup$

First of all I have to say I am very new to these matters. I am trying to apply FFT algorithm to some values obtained by EEG bands. I found the following code but I am unable to make it work correctly. import numpy as np

fs = 200                                
#data = np.random.uniform(0, 100, 1024)  # 2 sec of data b/w 0.0-100.0

data = np.array([(-0.27,-0.09,0.16,0.01,0.67,0.65,-1.59,0.11,-0.36,0.69,0.94,0.43,-0.53,-0.57,0.98,-0.97),(-0.74,-0.56,0.76,0.58,1.79,2.22,-4.96,-0.25,-1.19,1.57,2.95,1.47,-1.00,-1.06,2.97,-3.43),
(-0.89,-1.50,1.76,1.72,2.09,4.04,-7.97,-1.30,-2.09,1.11,4.82,2.57,-0.01,0.05,4.64,-6.44),
(-0.84,-2.78,3.00,2.88,2.00,6.36,-11.46,-2.36,-3.22,-0.01,6.96,3.84,1.85,2.11,6.64,-10.31),
(-0.39,-4.27,4.26,4.57,1.09,8.77,-14.78,-4.09,-4.40,-1.87,9.03,5.12,4.86,5.31,8.76,-14.77)])

print("After data")
# Get real amplitudes of FFT (only in postive frequencies)
fft_vals = np.absolute(np.fft.rfft(data))
print("After fft_vales")
print(fft_vals)
# Get frequencies for amplitudes in Hz
fft_freq = np.fft.rfftfreq(len(data), 1.0/fs)
print("After fft_freq")
print(fft_freq)
# Define EEG bands
eeg_bands = {'Delta': (0, 4),
         'Theta': (4, 8),
         'Alpha': (8, 12),
         'Beta': (12, 30),
         'Gamma': (30, 45)}

# Take the mean of the fft amplitude for each EEG band
eeg_band_fft = dict()
for band in eeg_bands:  
   freq_ix = np.where((fft_freq >= eeg_bands[band][0]) & 
                   (fft_freq <= eeg_bands[band][1]))[0]
   eeg_band_fft[band] = np.mean(fft_vals[freq_ix])

print(eeg_band_fft)

I am getting the following errors when it goes into the for.

/home/xxxx/.local/lib/python3.8/site-packages/numpy/core/fromnumeric.py:3372: RuntimeWarning: Mean of empty slice.
return _methods._mean(a, axis=axis, dtype=dtype,
/home/xxxx/.local/lib/python3.8/site-packages/numpy/core/_methods.py:170: RuntimeWarning: invalid value encountered in double_scalars
ret = ret.dtype.type(ret / rcount)

What am I missing or what's wrong?

As I said above, I am very new to this matter so please, try to explain everything as simple as possible.

This is the result I get:

band        val
0  Delta  64.642945
1  Theta        NaN
2  Alpha        NaN
3   Beta        NaN
4  Gamma  25.851368

This is how the file I am reading looks like. It is a file from a 16 electrodes reading with nearly 200k entries. I have only taken the first entries of the file in order to test this code snippet.

EEG-file

$\endgroup$
0
$\begingroup$

There are a few things going on:

1.) Your data is actually only length 5 (made up of 5 longer components). This means when you call fft_freq = np.fft.rfftfreq(len(data), 1.0/fs) your array containing the frequencies of the FFT is only length 3! I think the main issue I'm having is that I'm not sure what your data actually represents: multiple electrodes?

2.) I think you're using np.where wrong. Basically it's not returning a slice which appears to be what you're trying to get.

3.) Even if a single array in your data represents an FFT of a single channel, the length is not nearly long enough to get anything useful. If we take the frequencies of data[0] we get [ 0. 12.5 25. 37.5 50. 62.5 75. 87.5 100. ]. Not even one bin per band so you need to increase the length of your data. This is probably why freq_ix returns an empty array sometimes.

I was basically doing the same thing here in lines 45-68. A little different but more or less the same idea.

Also highly recommend using the MNE package. :)

$\endgroup$
  • $\begingroup$ I have a huge file with nearly 200k entries. It's a reading from 16 electrodes so it is composed of 16 columns. The data I am using is just the first rows of this file, each array inside np.array is one row from this file. I am very new to this so I am totally lost. Can you help me get a working solution? Because probably I am messing things up here. I will add anything necessary to my post in order to assist. $\endgroup$ – NeoChiri Sep 24 '20 at 7:20
  • $\begingroup$ I have added a screenshot of the file so you can see how it is. $\endgroup$ – NeoChiri Sep 24 '20 at 7:58
  • $\begingroup$ I would just start by working on a single electrode. Then when that works, you can scale easily. If you don't know how Fourier Transforms work, read on that first. I assume each electrode data you have is many, many samples long? Feel free to contact me directly. $\endgroup$ – Jacob Sundstrom Sep 24 '20 at 15:42
  • $\begingroup$ Sorry to clarify: each column is an electrode? If so, then you want to get that into a np.array in a single row, then operate on that. $\endgroup$ – Jacob Sundstrom Sep 24 '20 at 15:53
  • $\begingroup$ I think I have made that mistake at first. Each column in the array is one reading of the 16 electrodes, but as far as I have been reading I guess each column in the array must be an electrode. Correct? $\endgroup$ – NeoChiri Sep 24 '20 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.