You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
fft function error while extracting EEG signals in EDF file
2 views (last 30 days)
Show older comments
I want to extract different waves in EEG signals and quantilize their absolute power. However, some errors impeded my way of further exploration.
[header,data] = edfread("preprocessedEEG.edf");
S = data;
y=fft(S);
Then, an error came as "Error using fft Invalid data type. First argument must be double, single, int8, uint8, int16, uint16, int32, uint32, or logical."
Totally have no idea of the error. Is that because of my EDF file had some "NaN" data? or I just misused the fft function? How can I move on my analysing? I really need your help.
Accepted Answer
Star Strider
on 12 Aug 2022
The assignments should probably be:
[data,header] = edfread("preprocessedEEG.edf");
instead. (I cannot test this since I do not have the file.)
.
25 Comments
Jessica
on 13 Aug 2022
Thank you,Star Strider. But I feel sorry that it still doesn't work after changing the sequence, still the same error. Besides, I tried using another syntax in edfread and the same error appeared, too.(And I took a reference on another user's code, I thought it was probably the fft function that went wrong.How to load a specific channel from EEG into MATLAB - Help Center Answers - MATLAB & Simulink (mathworks.cn) )
data=edfread(“preprocessedEEG.edf”)
Invalid text character. Check for unsupported symbol, invisible character, or pasting of non-ASCII characters.
Error in connector.internal.fevalMatlab
Error in connector.internal.fevalJSON
S = data;
y=fft(S)
Star Strider
on 13 Aug 2022
Edited: Star Strider
on 13 Aug 2022
I did not look closely at the argument and so I thought initially that you were referencing it as a string with double quotes (") rather than a character array with single quotes (') so I did not change that. Note that the actual double quotes (") is not the same as double single quotes ('') and not the same as quotes created as char(0145) (‘) and char(0146) (’). Only single quotes (') defining a character vector or double quotes defining a string (") will work.
Aside from that, it is necessary to assign the outputs correctly and then refer to the correct outputs in the fft call.
Try this instead —
data=edfread('preprocessedEEG.edf')
EDIT — (13 Aug 2022 at 16:42)
Added corrected edfread call.
.
Walter Roberson
on 13 Aug 2022
Unicode Left Double Quotation Mark https://www.compart.com/en/unicode/U+201C
char(0x201c)
ans = '“'
data=edfread("preprocessedEEG.edf")
Jessica
on 14 Aug 2022
Thank you, Star Strider and Roberson. I do learn some knowledge from your answers, though it still didn't work when I ran the fft code.Anyway, thank you all!!!I will try to find other solutions to my problem.
Star Strider
on 14 Aug 2022
Our pleasure!
For help with the fft calculation and plotting, see for example FFT from .csv voltage and current data file although having the file you are working with would be helpful since I have no idea what is in it or how to prepare it properly as input to the fft function. If you can attach it or use zip first it is too large to upload directly, I might be able to help with it.
Jessica
on 14 Aug 2022
Okay. Because my raw data is too large to upload even after zipping, so I cut down a part of it and only upload an incomplete part.
Star Strider
on 14 Aug 2022
I cannot do anything with this file. It does not have an .edf suffix, and when I try to correct for that by concatenating '.edf' onto the end of it, the edfread function throws an error. Using the type function reveals it to apparently be a binary file, and assuming that it might be a .mat file, the load function also fails.
Uz = unzip('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1097880/trial1.zip')
Uz = 1×1 cell array
{'trial1'}
type(Uz{1})
0 X X 13-May-1951 Anonymous Startdate 14-Aug-2022 14.08.2220.15.261024 1 2 3 Fp1 Fp2 Status uV uV uV -140.554-383.5650 120.18 165.131 1 -32768 -32768 -32768 32767 32767 32767 LP: NaN Hz; HP: NaN Hz; Notch: NaN LP: NaN Hz; HP: NaN Hz; Notch: NaN LP: NaN Hz; HP: NaN Hz; Notch: NaN 512 512 512 5S( j¯& ¦§©ª¨¥Ç¤§¬
²ü¶¹¹;¸·Ô¹IÀòÉüÓyÛWßéànâôäçÄèèæRæçõèÆè¡æïãqâyâyâoàÝÛeÖsÒ%ÑuÑeÑÐ×μÏÓ¸ØÜùÛ7ÙÏÖr׺ÛâQè³ìî!îÝë éåçÿéîïDøKʹáýúúû®ýßþþ¼ûÞù{ú# . ß?X/æþß0 Lñsÿ±ýüüÒý²þ[þ#ý>üyüýþÿ¯þAýgú[öò"ñóèöúú)ùtøúøþ5¢±ÿüÉúÛû½ú|ú3ûDý=^P«D"z#\$A&-).,.b023e4ß4í5v8%<e?Û@Å@¸@ïAD¿EMFpF9GHùHWG6D AVAyCñFÑJñN S$V0V°RM<J5KP@V"^¹_É`¬`^:[ÀX>Y\`<ap_\ìZZ!Z2XlU¬STUÇVWW$WVìQìJC>f<:611÷-É/ó5³< @:AH@V?_>Í<ð:Ö9È9ª9Q8;6`5ô6Ç9G;W:Ì8Ú9ã>þEKuMPLÃJKþMRsWb[]^]D]å]^_Ë`Fa`&_Ä]ú\ë\I]]!]H\ë[^]hagnìru§tVsårjt²w{~ÿÐN~±{9xt¦q'p¦oôn7mÊjèhhii½jÂkZllYlwkmjOjækÆnqÊrsrEq)pogozo:oÕmÎjÍf¤ccødÜgÒiKjýiihÃfÉd@déeHhheeÕ_¦ZnWpUÞROáJÔG4FPEDÆC/C[BØ@?h>ª?öAC@AË<R72-(M#~ ·"%&¨%y$¶"á·k"ý(,>,)m&ä#¦!:rWª#<vÆ׿?
µû(ªàXf3'a-ù.1,¨&û
:÷Xïý
û¾øPøEúýJÁôþVü»ú)ûhýLPüþ~ùNólîÚëÝê½égçzä§â÷â ä¢åäáSÞÜiÜãÜÜ~Ú×{Ó³Ð>ϸÎ[ÎÉÍQÍ[ÍÍÌUÉ)Ä˾»§¹T¹¯¸·_´ð°®¬¨=¤ø¢®¤/¨£«®°7²r´ÔµÒµú´O´!´Î³æ®èV5Eºµ¢D¤U¥â¥¢¦ ¨¥ª+®Q²g¶³¹Í»Û¼w½[¾þ¿nÂkÅ¢ÈâË)ÏÒöÕAÙÜÞqßaàcá¶â5ä}åBææªæ×æ,çç:èéBêëìVíKîëïmòõ³øVû0ý@þ½þ'ÿ3m½< ¶ g¶e
&N7vðÔÝ$!"y#$¯$²%'D*<-²/E1923«3Ú3k3û235/8V:b;Þ;²<>L? ?2?ó>±?ZA7C»DèEG+H&IßIyJK|KK;K1KÓKýLNNÊNOôO0Q~R¨S¢TSUUwU@U<UgUUÒU¨V|X[n]_=`¨aªcÂeFgFhiËkynpxqqÌq-rRrrrsBu(wwWvuuwv0x1yXy$yåxsx³ww#wxNyzæyEyrxsw/vâttWtuu÷vkx´yæzö{¦|Â|S|¤{{{Í{}k~>A²~~Ó}Ñ}Ê}}?}ê|| |y{zyw¯tr%q®ppCpÿolpÝq¸sïtuwtt2t5t¤s©rÖq^qÂpoÐmlblål=m
mål¡m{oÑqËsu£uôu4v¬v®wAyÕz{C{ezâyz2zÒyÿxxåx¶yýy2yÁwsvuÑtâs(sgsët#wynzd{|~vÿF~á|Æ{9{L{á{¤|}â|Ñ{zxUv#u¥tµtuBuHu÷t2tërDq ojnÂmemàlækxjÅhõfeLc´a}`µ_=_ã^^^Ë]µ]Ñ]Ü]]·\Ô[y[è[£\¯\[[ÖX÷UpSFQOÃLÝJJHJæJþJ<JúH·G§F¾EöDgDDbCB@¹=d;9g6R3B0á-n,+*J)û'÷&7&n%z$¦#o#$û$¬%%j$"z tѱùiÊ ¸ò*Íì<s
N
H§íË0~H
v¬w² ,ÎùÎû©ÿ\ÿÞÿáÿaþ_ü<úeø÷Dölõ7ôÆòñ'ñ;ñHñàðð|ï;ï ï¹îÓí³ì¿ëëxêpéÛçæäñãÿãäoãÜáøß·ÞÞÈÞÞKÝÛeÚÚ9ÚÚ_Ù§ÙÛ¤ÜÝäÝúÝÞÝÝ[ÛÚØqÖÛÔÿ
If you can import and load the data, attaching at least a representative section of it by saving it to a file using writetable or writematrix to write it to a file and then upload that file or a zip of it could work. If reading the file is the problem, I need the actual file or a link to it. (Since you want to do signal processing on it, I would need a corresponding time vector or a sampling frequency as well as the data.)
I have nothing else to suggest at this point.
.
Jessica
on 15 Aug 2022
I'm sorry for my mistake and I tried to put the file into my mailbox link, with blue button meaning "download". And the sampling frequency(or sampling rate?) of my data is 256Hz(see the attached figure).
Here's the data link:
Fig 1.
Star Strider
on 15 Aug 2022
No worries! I just want to get this working if I can.
I’ll look though the file in the morning. It’s the end of my day here (UTC-6 summer time).
Walter Roberson
on 15 Aug 2022
[header,data] = edfread("preprocessedEEG.edf");
That is not the output for edfread(). The first output is always the data, and the second (optional) output is annotations.
data = edfread("preprocessedEEG.edf");
returns a 43197x3 timetable, in which each entry is a cell array of 256 x 1 double.
I have lost track of what the question is, beyond the problem of reading the data in, which edfread() is doing.
Jessica
on 15 Aug 2022
It's so nice of you two, Strider and Roberson, to focus on my problems. My initial question is that I can't use fft function to process my EDF file("Error using fft Invalid data type. First argument must be double, single, int8, uint8, int16, uint16, int32, uint32, or logical.") And you two corrected some other errors which was the base of my further steps. Now I understand where my initial problem generated. It was because that fft() can only read vector, matrix or other sequence of actual numbers instead of my timetable from the EDF file. I’ll try to find solutions of transforming my data type(Or, if you know the answer?:-) .
Thank you again,
Sincerely,
A novice to matlab.
Star Strider
on 15 Aug 2022
That is a huge file!
I do not understand what is in it. For example, the first row, labeled ‘0 sec’ has three columns labelled ‘Fp1’ , ‘Fp2’ and ‘Status’ the first 10 rows of which are:
-1.9966 1.9966 0
-1.3043 1.3043 0
-183.4407 183.4407 1.0000
-188.0245 188.0245 0
-184.4323 184.4323 0
-179.7175 179.7175 0
-182.0936 182.0936 0
-177.6221 177.6221 0
-181.7569 181.7569 0
-180.2414 180.2414 0
The ‘Status’ variable has one value in row 3 and is otherwise zero.
What do you want to do with it? (The entire file apparently contains about 12 hours of data.)
Walter Roberson
on 15 Aug 2022
Are you wanting to put together all of the corresponding locations by time, forming something like a 256 x 3 x 43197 or (better) 43197 x 256 x 3 numeric array, that you would then fft() along the 43197 dimension ?
Jessica
on 16 Aug 2022
To Strider: Fp1 along with Fp2 means two electrodes and status represents the mark of artifact rejection, a step of pre-processing. Since my data was in time domain, I want to transform it to frequency domain and extract absolute power of certain waves(e.g. α wave is 8-13Hz and absolute power of ot is 10uZ2). But it went wrong at the first step.Whether I use fft function or wavedec toolbox, the error went as that I can't use timetable to run the code. So, as Roberson has pointed out, I just want to transform the data to a numeric array.
To Roberson: Yes. That's exactly what I want to do with the data.
Star Strider
on 16 Aug 2022
Try this —
tic
data = edfread('preprocessedEEG.edf');
% Sample = data(1:10,[1 2]);
Fs = 256;
Fn = Fs/2;
datamtx = cell2mat(data{:,[1 2]});
L = size(datamtx,1);
tv = linspace(0, L-1, L)/Fs; % Time Vector (seconds)
datamtxfilt_8_13 = bandpass(datamtx, [8 13], Fs, 'ImpulseResponse','iir');
figure
subplot(2,1,1)
plot(tv, datamtx(:,1))
grid
ylabel('Amplitude')
title('Fp1')
subplot(2,1,2)
plot(tv, datamtx(:,2))
grid
title('Fp2')
xlabel('Time (s)')
ylabel('Amplitude')
sgtitle('Original')
figure
subplot(2,1,1)
plot(tv, datamtxfilt_8_13(:,1))
grid
ylabel('Amplitude')
title('Fp1')
subplot(2,1,2)
plot(tv, datamtxfilt_8_13(:,2))
grid
title('Fp2')
xlabel('Time (s)')
ylabel('Amplitude')
sgtitle('Filtered 8-13 Hz')
NFFT = 2^nextpow2(L);
FTs = fft([datamtx datamtxfilt_8_13],NFFT)/L;
Fv = linspace(0, 1, NFFT/2+1)*Fn;
Iv = 1:numel(Fv);
figure
subplot(2,1,1)
semilogy(Fv, abs(FTs(Iv,1))*2)
grid
title('Fp1)')
ylabel('Amplitude')
subplot(2,1,2)
semilogy(Fv, abs(FTs(Iv,2))*2)
grid
title('Fp2')
xlabel('Frequency (Hz)')
ylabel('Amplitude')
sgtitle('Original')
figure
subplot(2,1,1)
semilogy(Fv, abs(FTs(Iv,3))*2)
grid
ylabel('Amplitude')
title('Fp1')
subplot(2,1,2)
semilogy(Fv, abs(FTs(Iv,4))*2)
grid
title('Fp2)')
xlabel('Frequency (Hz)')
ylabel('Amplitude')
sgtitle('8-13 Hz Filtered')
toc
I do not entirely understand the artefacts above 100 Hz in the fft of the original (unfiltered) signal. I will let you solve that.
The fft of the filtered signal is simply to demonstrate that the filters work. To filter other frequency bands, simply change the numbers in the square brackets in the bandpass call. They all have to be in ascending order, greater than 0 and less than 128.
On my reasonably fast Ryzen 9 9300 desktop, this takes about 8.69 seconds.
.
Jessica
on 16 Aug 2022
I’m so moved about your code and don’t know how to express my appreciation. I spent quite a long time reading your code. But I am still a little confused about the code:
1) You labeled Y axis as “amplitude” in FFT Filtered 8-13Hz figure while using the equation “abs (FTs (Iv,1))*2” to calculate it. I guess that maybe you mean “EEG power (unit=uv2)” rather than “amplitude (unit=uv)”. Is that right?
2) why did the third “Original” figure differ from the fourth “8-13Hz Filtered” as they both went through FFT? What's the meaning of number in “(lv,1)” in the code “semilogy(Fv, abs(FTs(Iv,1))*2)”?
Plus: I’ve already bandpass-filtered this data from 0.01Hz to 100 Hz using EEGLAB toolbox before, so the artefact above 100Hz may be the result of my former process.
Star Strider
on 16 Aug 2022
I am happy it works for you! I had to figure out what was in the file and how it was organised, then the rest was straightforward. That is an unusual way to store data and I have not previously encountered it, however it definitely makes sense if the objective is to examine each second or group of consecutive seconds easily.
I plotted amplitude (or magnitude). To get power, simply square it, so for the first subplot —
semilogy(Fv, (abs(FTs(Iv,1))*2).^2)
to get power, and similarly for the others. Another way to do all of them at once is:
FTs2 = abs(FTs*2).^2;
Then the first subplot would be —
semilogy(Fv, FTs2(Iv,1)))
‘why did the third “Original” figure differ from the fourth “8-13Hz Filtered” as they both went through FFT?’
I filtered the signals first, and then did the fft on all of them together since they otherwise all have the same characteristics. That is simply more efficient. I then plotted the various columns.
‘so the artefact above 100Hz may be the result of my former process.’
That definitely explains it! (I don’t remember seeing that mentioned anywhere previously.)
.
Jessica
on 17 Aug 2022
Strider, for the question 'why did the third “Original” figure differ from the fourth “8-13Hz Filtered” as they both went through FFT?', I just simply can't understand the meaning of index(=1,2,3,4) in the code 'semilogy(Fv, abs(FTs(Iv,index))*2)'. What does it mean?
(e.g. Index=1 or 3 both mean the filtered FFT fp1 electrode, but why does their plots seem so different?)
Star Strider
on 17 Aug 2022
The first two columns of the argument to fft are the original vectors, and the last two are the filtered vectors. This is also reflected in the output. So column 1 is ‘Fp1’ and column 3 is ‘Fp1_filtered’. Columns 2 and 4 are the same for ‘Fp2’. The plots are different because the first is the original and the second is filtered. The fft plots of the filtered signal demonstrate the effect of the filtering.
Jessica
on 17 Aug 2022
Alright,I get it now! Thank you so much for your patient and timely guidance and instructions! I nearly lost hope before asking questions in this forum, but now I gain a lot of motivations and basic knowledges to continue my learning. Many thanks to Strider, and also, Roberson!
Jessica
on 21 Aug 2022
Strider, I came across another question. How can I perform a 'window' to fft in order to reducee the frequency leaking problem?
ps: I saw someone claiming that a rectangle window was added to your signals even when you did nothing on fft settings. Is that true?
Star Strider
on 21 Aug 2022
Edited: Star Strider
on 21 Aug 2022
The easiest way to do a windowed Fourier transform is to use the Signal Processing Toolbox stft function. That’s what I do when I want to do windowed Fourier transforms. There are other ways, however it’s been so long since I‘ve used them, that I¹ve forgotten how to code it.
I don’t believe that performing the fft automatically selects any kind of window, since the transform is done on the entire vector. The purpose of windowing is to correct for the discrete Foirier transform not being infinite.
EDIT — (21 Aug 2022 at 15:06)
With respect to automatically windowing a Fourier transforom with a rectangular window, thinking about it further that’s correct, with the window being the length of the time-domain signal. (I don’t generally consdier that, however it is technically correct.)
I’ve not done a wondowed fft in a while, so I had to go back through the archives (finding it in a code example from six years ago).
The window must be the same size as the vector, so for example:
FTs = fft(hamming(L).*[datamtx datamtxfilt_8_13],NFFT)/L;
This should probably work. (Choose the window of your choice. The window functions I looked at all produce column vectors, so the multiplication is straightforward.)
I did not test this particular example.
.
Jessica
on 22 Aug 2022
Thanks, Strider! It really helps! The different windowed fft figures are as follow. And I decide to adopt hann/hanning window since it is reccommended by many people and articles.
More Answers (0)
See Also
Categories
Find more on Transforms in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)