File Exchange

image thumbnail


version (7.44 KB) by Brett Shoelson
A simple file reader for European Data Formatted (EDF-) files.


Updated 27 Feb 2018

View License

Editor's Note: This file was selected as MATLAB Central Pick of the Week

Read European Data Format file into MATLAB

[hdr, record] = edfread(fname)
Reads data from ALL RECORDS of file fname ('*.edf'). Header information is returned in structure hdr, and the signals (waveforms) are returned in structure record, with waveforms associated with the records returned as fields titled 'data' of structure record.

[...] = edfread(fname, 'assignToVariables', assignToVariables)
Triggers writing of individual output variables, as defined by field 'labels', into the caller workspace.
[...] = edfread(fname, 'targetSignals', targetSignals,...)
Allows the user to specify by name or index the subset of signals to import.

PLEASE NOTE: I have also uploaded on the File Exchange EDFReadUntilDone. If you have problems reading large files with EDFRead, please download and try that one!

Comments and Ratings (166)

@John Kablan (and others):
Thank you, John. For the record, I am working toward getting more active ("official") support for this file. It is widely used, and I haven't had the bandwidth necessary to address issues that some users have shared. Hopefully soon!

John Kablan

Hi Brett, thanks for sharing your code. One small fix. In edfread.m line 238 I added the following to filter the frequency field when reading a subset of the signals.

>> hdr.frequency = hdr.frequency(targetSignals);

Mark Duntz

Does it work for annotations too? I see that it is importing my annotations as a signal but I'm not sure how to interpret the result.

Ruiyi Tian

@Brett Shoelson
Hello Brett, I also has met the problem with line 156.
Array indices must be positive integers or logical values.
Error in edfread (line 156)
hdr.label{ii} = regexprep(fread(fid,16,'*char')','\W','’);
I noticed that the line before the error line is
hdr.ns = str2double(fread(fid,4,'*char')’);
for ii = 1:hdr.ns
It seems like the array index ‘ii’ can only be integer? I am not sure if this is the problem since I tried to use str2num to replace str2double and then there is an error in the next line showing "Reference to non-existent field 'label’.”
if isempty(targetSignals)
targetSignals = 1:numel(hdr.label);
Do you know how can I fix this problem?

Hello, Brett Shoelson, I recently used a physiological signal database called MAHNOB with a storage format of .BDF. I am very fortunate to have seen the matlab code you developed on the Internet, carefully studied and used it, but there is a very serious problem. The channel signal value of the record in matlab is completely different from the signal I opened in EDFbrowsers. In EDFbrowsers, it is a good ECG signal, and the plot out in matlab does not meet the rules at all. Can be charged, my BDF file is 47 channels, a file is about 20 trillion, is it because of the large amount of data? Or the code you developed has its own value conversion function. Since I am a newbie, I can't analyze your code to find the reason. Please answer your questions.

I'm sorry I don't understand your question. What is file.m? Your data file is 'ecdca200.edf', right? Your calling syntax for that file appears to be correct. Are you saying that you type:

[header, recorddata] = edfread('ecgca200.edf');

and you're getting a "Requires at least one input argument (filename to read)" error?

That would be puzzling.

Hey Brett, I am keep getting this error, please help me. ""Error using edfread (line 119)
EDFREAD: Requires at least one input argument (filename to read)."" And my other file I named it file.m and that's what's in it literally ""[header, recorddata] = edfread('ecgca200.edf');
% 'Thorax_1' 'Thorax_2' 'Abdomen_1'
% 'Abdomen_2' 'Abdomen_3' 'EDFAnnotations'""' Please help Brett

By default, EDFREAD is supposed to read all signals. If you're only getting one channel, perhaps there is something out-of-spec about your file. If you care to share it with me, I will take a look.

John Hock

@Brett Shoelson
I had the input data of EEG downloaded from CHB-MIT website.
Which have data from 26 channels.
Data from 1 channel can easily be read using this command
Will you please tell that what if I want to read the data of all channels at the same time using one EDF read command?

Is it possible for you to share a data file with me?

Hi, @Brett Shoelson,
I have a similar problem to some of the other commenters. when I input
[hdr,datastream] = edfreadUntilDone('13288010303_003.edf') or in the short format

the command window tells me:
[hdr,record] = edfreadUntilDone('')
Subscript indices must either be real positive integers or logicals.

Error in edfreadUntilDone (line 152)
hdr.label{ii} = regexprep(fread(fid,16,'*char')','\W','');
I am sure my data is 27 channels of EEG and 2 of ECG data about 1.3 million samples at 400hz. It is a sample of data from the epilepesia project. Im not sure if the problem is it is just too big, the data is over an hours worth.
Can you help me to fix this problem? Thank you very much in advance!


@Vikramaditya please use two output argument while calling edfread.

I tried to use both edfreadUntilDone and edfread,

When executed I am getting ''Step 1 of 2: Reading requested records. (This may take a few minutes.)...'' and terminated.

Any Idea why I am getting this kind of weird issue.

hi Brett
i would like to plot the recorded data which is obtained from [hdr,recorddata]=edfread(fname)
The recorddata contains the values which are in 7 by 62000 double.
will you please tell me how to plot it.
Thanks in advance

Sania Zahan

Hi Brett

It worked great. Thanks.

peng qin

I want to know how I can use edfread in matlab?I have downloaded this zip, and after the decompression, is the m file opened with matlab?After I opened it, I couldn't open the downloaded edf file matlab, which suggested that I should not be an expression for matlab.

I'm Sheldon Zhang.
I get the Edfread.m from your MathWorks.
I want to change edf to mat,but I'm new on Matlab.

When I type "hdr = edfread('SZ2-3.edf')"
It shows like this:
Step 1 of 2: Reading requested records. (This may take a few minutes.)...

hdr =

ver: 0
patientID: 'VEEG0118N_1 M 07-SEP-2006 ##_# '
recordID: 'Startdate 12-JUN-2017 X X Compact_2x64ch '
startdate: '12.06.17'
starttime: '04.37.36'
bytes: 29440
records: 2138
duration: 1
ns: 114
label: {1x114 cell}
transducer: {1x114 cell}
units: {1x114 cell}
physicalMin: [1x114 double]
physicalMax: [1x114 double]
digitalMin: [1x114 double]
digitalMax: [1x114 double]
prefilter: {1x114 cell}
samples: [1x114 double]
frequency: [1x114 double]

Some of variables like 'physicalMin','digitalMin','digitalMax','samples' and 'frequency' are 'NaN'.
I don't know how it happend.

And if I type [hdr,record] = edfread('SZ2-3.edf');
It shows like this:

Step 1 of 2: Reading requested records. (This may take a few minutes.)...
Error using fread
Invalid size.

Error in edfread (line 225)
tmpdata(recnum).data{ii} = fread(fid,hdr.samples(ii),'int16') * scalefac(ii) + dc(ii);

It seems the code can't run.
It means the formula cannot be calculated because of the wrong values of the above variables.

I would appreciate it if you can give me some advice!
Thank you very much!!!

Sheldon Zhang

@Sheldon: I didn't see an email from you. What is your question?

I have some questions of the code.And I send you an e-mail.Any advice will be appreciated!
Sheldon Zhang

@Positron: sounds like a for-loop to me. Figure out how many channels you want to plot, then the shape (m x n) of the rectangular array of axes in which you want to plot them. Then cycle over them, indexing to the channel/axes. In pseudo-code:

ax = gobjects(nChannels,1);
for index = 1:nChannels
ax(index) = subplot(m,n,index);

Then if m x n is large, consider calling expandAxes:

You'll be able to click-expand any of the axes. (expandAxes is also available on the File Exchange.)



Hi, how does one display all channels on multiple subplots?

thank you @brett
i'll be getting back to you if i have a doubt
Thank you again

The first output variable is the header information. (I wrote it that way because it's inexpensive to read the header, and if that's all you need, you can optimize the read by requesting a single output.) The signals are returned in the second output argument. So, for example:

[hdr,eeg] = edfread(...);


how to plot the signal after reading the data
[no1,eeg] = edfread('C:\Users\Pranav Kumar\Desktop\eeg data\SC4001E0-PSG.edf');
[signal] = edfread('C:\Users\Pranav Kumar\Desktop\eeg data\SC4001E0-PSG.edf', 'assignToVariables',x);
plot(eeg, no1, signal);
this is my code and how shall i plot

Error using plot
There is no ver property on the Line class.

Error in eegxlsplot (line 16)
plot(eeg, no1, signal);
thank you

@Pranav: not sure how to help you. Unzip the file, make sure it's on your MATLAB path, and use it as shown in the help.

please tell me how to use this function after downloading the zip file

ruan harry

Hi, @Brett Shoelson,
Thank you very much for your excellent help. But a similar problem as Marta Crisanti have stopped me . when I input
[hdr,datastream] = edfread('wy.edf')
edf1=edfread('wy.edf') ,
the command window told me:
Subscript indices must either be real positive integers or logicals.

Error in edfread (line 163)
hdr.label{ii} = regexprep(fread(fid,16,'*char')','\W','');
I am sure my data is 10-20 system EEG, not eye link file. when I download a short .edf format file from internet, it works well, However, when I use my own edf, it doesnot work. I think the problem may my .edf is too big for the script. my EEG lasts more than one hour.
could you help me to fix this problem? Thank you very much!

Yi Jui Lee

Yi Jui Lee

Hi Brett, I have similar problems with Vinit and Selin. Do you know what might have cause this?

cypson Rena

@Brett : hi

I try to compiled your code but come any this error : Error using edfread (line 120)
EDFREAD: Requires at least one input argument (filename to read). can you please help me oder somebody have a Idee. I suppose to convert edf file to another Matlab file(.m).

Dirk Cysarz

Hello, very useful code, thank you.
However, all assigned variables in the caller workspace have the size of the signal with the largest sampling rate.
Some minor changes are needed to get the size of the assigned variables according to the respective sampling rate:
line 239:
record = zeros(numel(hdr.label), hdr.samples(1)*hdr.records);
should be replaced by
for ii = 1:hdr.ns
buf=sprintf('record%d=zeros(hdr.samples(ii)*hdr.records, 1);', ii);
line 252:
record(recnum, ctr : ctr + hdr.samples(ii) - 1) = tmpdata(jj).data{ii};
should be replaced by
buf=sprintf('record%d(ctr : ctr + hdr.samples(ii) - 1) = tmpdata(jj).data{ii};', recnum);
line 265:
should be replaced by
buf=sprintf('assignin(''caller'',''%s'',record%d);', hdr.label{ii}, ii);

This way the function saves each signal in a unique variable with its size according to the sampling rate (record1, record2, ...).

can anyone show me how to use it.

Vinit Shah

I think, This function has issue with loading bigger files. After some number of datapoints, function just starts dropping bunch of zeros (or near zero values such as 0.004).I am getting this issue by loading 1 hour long file sampled at 250 Hz.

If this is the case then please make the code memory efficient.


Hello Brett, why doesn't results from this edf reader match physionet atm results? Is there some kind of conversion?

Thanks for the rating! Not sure how to steer you; that's a core MATLAB manipulation. Do you want the first 100 points? ( vec(1:100) ). The last? ( vec(end-99:end) ). Evenly spaced? ( vec(round(linspace(1,length(vec),100)) ).

John Hock

Hi Brett....
Your function is working awesome
I am working on EEG Recordings data from CHB-MIT
I am using your code
I just need a little help,while using your code i am enable to access the selected channels (total 23 channels i can select any one of them). Will you please tell me the code or way how to select some points(I means there are total 921600 points of each channel i just want to select 100 points out of 921600). Waiting for your reply

Hi Jennifer...thanks for the note. I am unable to access your data. Is the annotation a field of the header struct, by chance?


Great thanks for this function. Then, I have a question that in my EDF file, there is annotation information called Hypnogram on the top, does this function will also help to transfer the annotation into matlab as well?
My EDF file link is here, . Could you land me a hand?

Thanks for the rating! The default read syntax is just an interpretation of the EDF spec. However, I did implement a filter that allows you to specify the target signals you want to read. (Helpful for large files, when you don't need all channels.)


First, thank you for this function! It's been very useful in my work. Do you use any filters in this function, or is it based on the edf file?


Dear Brett,
I have been trying to convert eeg files from edf to matlab.

I have tried to use edfRead. The function call is
function [hdr, record] = edfread('aesa1.edf')
But I get the following error message:
Error: File: edfread.m Line: 1 Column: 34 Unexpected MATLAB expression.
I can view the file in edfbrowser so the file seems to be OK.

I can see that in the past other users have gotten the same error message but I cannot see that you have come up with an explanation.

Can you help me?

Oddur Bjarnason.

Thanks for the awesome solution! Definitely a super easy way to get EDF data into matlab.

Chunyan He


Please note that this reader is for "European Data Format" files, NOT for "Eyelink Data Files." For the latter, try Eydrian's File Exchange entry:


@Marta...Please see my comment below from March 15, 2016. Is yours an Eyelink file? (I'm guessing that if you put a breakpoint just before the offending line 163--at the line that reads

hdr.ns = str2double(fread(fid,4,'*char')')

you will see that hdr.ns == NaN...right?

The spec for both EDF and EDF+ says that the file should contain the number of samples in that location. If you're getting NaNs there, you might have an improper [Eyelink?] file format for this function.)


Hi Marta. Can you by chance send me a sample test file for which you receive this message?
(My email is encoded in this:

char(cumsum([98 16 -13 15 0 -70 69 -11 7 -10 7 7 -4 -1 -46 45 -12 19 -12 15 -8 3 -7 8 -69 53 12 -2]))


Hello Bret, I am working on some .edf files and I am not understanding the error messega I get.

Just to make sure I am working well: the edfread.m is in the folder I am working in and it is the same folder as my data. I have added its path with addpath, so I should have no problem in the reading part. The filenames are of the type 'scan_001_256.edf' and this is the string I am giving in input to edfread.

I am getting this error message:
'Subscript indices must either be real positive integers or logicals.

Error in edfread (line 163)
hdr.label{ii} = regexprep(fread(fid,16,'*char')','\W','');'

I tried to change the filename, getting rid of the "_" but the error message remains the same.

May you help me?

Thank you in advance and sorry for bothering you.



Thanks for your explaining. I understand the meaning of two formula.The edf file has been read successfully by using the proposed program in Matlab and display these signals in the figure simultaneously.

Sorry for the delay. The EDF spec indicates that the file header should report the actual min and max (range) of the physiological signal being recorded, along with the digital min and max (range) of the transduction of that signal by the transducer (which is also specified in the header), in the units specified. Those formulas simply scale the signals to their physiological ranges and shift them to their "true" locations (relative to their dc offset).


Hello,Brett.Could you help me to explain two formulas? The first one is" dc = hdr.physicalMax - scalefac .* hdr.digitalMax"; the second one is " tmpdata(recnum).data{ii} = fread(fid,hdr.samples(ii),'int16') * scalefac(ii) + dc(ii)".
In addition, what's the meaning of digital minum and digital maximum?

Kenny Kim

labels were missing at parts but the actual data is well intact.

Seb Olbrich

Thanks for the function! Works sound. Would be very nice to have it loading multiple edf-files from one directory and safe the records under the corresponding names. Guess I have to do this by myself, or do you already have some code available?
Anyhow, thanks for the function.

@ Susanne:
It looks like you modified my code, and broke it in doing so. I never used 'edf' as a variable; shouldn't that say:

[fid,msg] = fopen(fname,'r');

where fname is the first input argument?

Hello Brett, could you kindly give me a advice why I am getting this error message: "Undefined function or variable 'edf'.

Error in edfread (line 123)
[fid,msg] = fopen(edf,'r');". Thanks, Susanne

That's a path issue, not an edfread issue. It indicates that MATLAB can't find the file where you put it. Read the doc for pathtool, userpath, addpath,....

After saving the function edfread.m
i tried to load the S002R02.edf file using
:[hdr, record] = edfread('S002R02.edf');
but this gives me error :
Undefined function or variable 'edfread'.
I downloaded the data from
So help me in this regard
Thank you

The file was corrupted when MathWorks changed the license model on Sept 1. I have fixed it and reposted--would you please try again?


Some out-of-spec files return a value of -1 for numberOfFiles, causing an error in edfread. In the new version (9/12/2016), if that issue is detected the call to edfread() automatically attempts to re-read the file using edfreadUntiDone() instead.

I don't have an offending file, so I have a hard time reproducing this, but I think the new call should work. If anyone encounters the note that edfreadUntilDone() was called, PLEASE DROP ME A NOTE to let me know that it worked (or didn't)!



when I download it, the edfread-file has no extension. how do I call it? adding a .m does not solve anything.


Great solution for EDF annotation.

Hi there, I tried to make use of edfread to read a sample edf data, in workspace it showed records as 1. and when I used with swt function the output approximation n details plot was not seemed to be a single wave, rather it was like dense of signals. can anyone tell me how to identify the number of signals in the data and how to separate it individually... thanks in advance

I agree with Mahrukh...this sounds like a path issue. Whenever you attempt to call functionality in MATLAB, it has to be on your current path. (See doc for 'addpath' and 'pathtool' for more information.)

Hay samhitha,
Did you add the downloaded function edfread to the matlab directory? I was doing the same mistake. Just use 'add to path' option then try to run it.

hi there .when I try inputting an edf file I have , the following error pops up : "Undefined function 'edfread' for input arguments of type 'char'. " how do I rectify this ?
PS: I put my file name in single quotes and I use R2013b version of matlab. Thanks in advance

Dear Brett,
Thank you for your reply. Can you send that file at my email address.
My data might have some French accent word. Is this the cause of error in reading the data record?

what do this line suppose to mean? should i add it in the code?
char(cumsum([98 16 -13 15 0 -70 69 -11 7 -10 7 7 -4 -1 -46 45 -12 19 -12 15 -8 3 -7 8 -69 53 12 -2]))
Thank you,


For some reason, some edf files have an out-of-spec value of -1 for numberOfRecords. This triggers the error you received with my reader. I have another version (edfreadUntilDone) that I will send you if you email me directly at:

char(cumsum([98 16 -13 15 0 -70 69 -11 7 -10 7 7 -4 -1 -46 45 -12 19 -12 15 -8 3 -7 8 -69 53 12 -2]))


Hello Brett,
Thank you for your code. It is helping me a lot. I need to ask you a question. I am trying to read a PSG full night recording through this code. The number of data record is showing me -1 value. so what does it signifies? why is it unknown to it? Is it because its a lot of data?

I tried to give a value for data record by hdr.record=10;(or any other values) at line 196 and it showed me the data then. But how can read the whole data by itslef? How can I know the duration of the whole data.
Thank you

Hi everyone,
I have intented to run this script, but I have had some problem. I need to read and analize a edf file. Could somebody tell me how to put my data in this script (specific line)? Thank for your help.

Satoko M

Hello Brett

I am a beginner and was unable to run your script. Am I right to put my data in the 1st row by typing edfread('x.edf') if my file name is x.edf? I kept getting error saying 1st row, column 34 isn't right. Could you please tell me how I can put my data? I've read comments from others but couldn't find the answer to this. Do I need to put my data on the specific place on PC such as desktop? Thank you for sharing this script and for your support.

Pierre S.

@Brett. I noticed another issue with the function. Labels with apostrophe (') in the edf file are not converted faithfully. The apostrophe is missing in the output labels.

Solution: Implement #1 and #2.

#1. Replace line 149 by the following :
hdr.label{ii} = strtrim(fread(fid, [1 16], '*char'));
(old line 49: hdr.label{ii} = regexprep(fread(fid,16,'*char')','\W','');)

#2. Comment line 194.
(old line 194: hdr.label = regexprep(hdr.label,'\W','');)

xu han

@Matthias, Are you sure the EDF file is a valid "European Data Format" file, and not an Eyelink file? (This function doesn't support Eyelink, which is different a different, proprietary format.)

Mattias F

Okay thanks!
It still doesn't work though,

What i've tried:
- using only the commando in command window: [hdr, record] = edfread('03s0458a.edf')
- downloading the code and entering the filename (with single quotes)

without success! is it anything im missing here?

@Mattias: the name of the file needs to be in single quotes.

Mattias F

Do i need to define hdr or record before using them?
I have a simple edf file and i want to read it into matlab with edfread but what turns out is just:

>> edfread(03s0458a.edf)
Error: Unexpected MATLAB expression.

Did you mean:
>> edfread(03*s0458a.edf)
Undefined variable "s0458a" or function "s0458a.edf".

I don't really know what to do, all i want is to read my edf file(s) into matlab...!
Thanks in advance!

Anh Nguyen

Thanks's rare that I get such a detailed bug report--especially with not one, but two solutions proposed! :) I will address this in the short term.
Best regards,

Pierre S.

When an array of indices is used for the 'targetSignals', I think that the order of signals in the rows of 'record' doesn't follow the order of the targetSignals.

For example,

targetSignals = [2 3 1];
[hdr, record] = edfread(fname,'targetSignals',targetSignals);

Then the first row of 'record' is the signal in channel 1 and not the signal in channel 2. While the information in hdr fileds are ordered according to the targetSignals vector (see lines 216 to 222 in the code).


If this is not on purpose, this could be solve by changing the way you parse the data (line 230 to 241).

for kk = 1:length(targetSignals)
ii = targetSignals(kk);
ctr = 1;
for jj = 1:hdr.records
record(recnum, ctr : ctr + hdr.samples(ii) - 1) = tmpdata(jj).data{ii};
ctr = ctr + hdr.samples(ii);
recnum = recnum + 1;


This can also be solved by reordering the column after parsing the data:

[~,ind] = sort(targetSignals);
unsorted = 1:length(targetSignals);
newInd(ind) = unsorted;
record = record(newInd,:);


Hi Leila,
Thanks for the rating.
EDFRead doesn’t discard any information; your efforts to change the format string for date-reading are almost sure to offset the rest of the file read—perhaps disastrously. I wouldn’t recommend it.

If you take a look at the spec, you’ll see that the millisecond information is not captured as part of the EDF format; the information simply isn’t there.


Thank you very much for sharing this file. Very useful indeed. I have couple of comments,perhaps to improve the existing code.
1- To load the timing of the startTime in milli second precision. So far it gives us the hh:mm:ss .
2- When the edf files are large it goes out of memory. Unless I cut the data in small pieces, which is not the best way, is there a way to choose how much of the data I need to load?


thank you for your reply. I saw that this code can't open eyelink .edf files. Thanks!

By "Matt," do you mean "Max"? And by "Eyewink," do you mean "Eyelink"? See my note of 18 Sept,2015, below.


Hi, have you fixed the problem with Eyewink .edf file? As Matt, i am dealing with the same problem. Thanks a lot.

Hi Zara,
Thanks for the rating. If your data are bigger than can fit in memory, you might see that warning. Two suggestions: use a bigger (64-bit) computer, and try reading in only a portion of the file. With the 'targetSignals' variable, I facilitated partial reads. (Or rather, full reads of a subset of signals.)
Good luck!

Hi Brett

Im getting this error.
Out of memory. Type HELP MEMORY for your options.

Error in edfread (line 224)
record = zeros(numel(hdr.label), hdr.samples(1)*hdr.records);

Sumtimes my code runs but sometimes it shows this error.Can u plz suggest whats wrong here.

hello sir'



thanks for replying so quickly! Just sent you an Eyelink file via mail.
Thanks for your support!

I think (though I am not 100% certain) that the Eyelink EDF (Eyelink Data Format?) is their proprietary format, not related to the EDF (European Data Format) that this reader is intended for. If you care to send me an Eyelink file, I will be able to tell at a glance if that is the case.


Hi Brett,
I get the exact same error message (see below) as Yang did (reported here on 25 Jul 2015). I also got the edf file from an Eyelink eye tracking system. Could you solve Yang's problem?
Thanks in advance,

Subscript indices must either be
real positive integers or

Error in edfread (line 149)
hdr.label{ii} =

hi brett,
Thanks now edfread() is working.
Is there any function like edfread. For reading 10 secs epoch from the continous eeg signal(.edf+ format)

thanks in advance.

thankyou very much
i will try one of this version now.

iam using R13a

I just successfully read the file you sent in R14a, R14b, R15a, and even in R15b prerelease. No errors, very fast.

[hdr,datastream] = edfread('r01.edf');

I wonder if you have a corrupt version of edfread? What version of MATLAB are you using?

Actually i am matlab beginner.
I downloaded that file from this website as you mentioned in the previous comments

thankyou in advance

@Hari...can you send me a file that triggers the error? I'll do my best to figure out what's going on. (Line 13 is a comment, is it not?)

hi brett,
I am trying to use this function to read an edf file but I am getting the following error always
Error: File: edfread.m Line: 13 Column: 1
Unexpected MATLAB operator.
Even if I comment out Line: 13 the same error occurs on following lines. Is there anything I am missing to run the edf code.
thankyou in advance

Tran Hoang

Hello Brett
I have an x.edf file export from epoc emotiv device. Then I use the code
[hdr, record] = edfread('x.edf');
and it's return structure 'hdr' and 'record', as I understand my waveform are stored in 'record'
Could you please tell me how can I draw the signal?
Thank you in advance!

If you care to share with me a datafile that triggers that error, I will be happy to take a look. You can reach me at:

char(cumsum([98 16 -13 15 0 -70 69 -11 7 -10 7 7 -4 -1 -46 45 -12 19 -12 15 -8 3 -7 8 -69 53 12 -2]))

(I don't have your email address.)


Hi Brett

I met the error as follows:
Subscript indices must either be real positive integers or logicals.

Error in edfread (line 149)
hdr.label{ii} = regexprep(fread(fid,32,'*char')','\W','');

I record the EDF file with Eyelink, a eye tracing system.

Do you have any solution?


I was half way through making my own script when I found yours. It saved me a lot of time!! Thank you.

there you go, sorry for spamming :)well, you made my day, it was only fair XD

:) Thanks...that made my day. I'll take that as a five-star rating.

Oh my Lord Brett. I think I'm actually in love with you :P this saved me tonnes of time! My heart actually skipped a beat when I saw channel information just popping into my workspace. One word: brilliant.


Ji Sung

@Wendy: Execute in MATLAB:

char(cumsum([98 16 -13 15 0 -70 69 -11 7 -10 7 7 -4 -1 -46 45 -12 19 -12 15 -8 3 -7 8 -69 53 12 -2]))

I'll take a look at your file when I get it.

Wendy Xiao

I think something might be wrong with the reader, this has nothing to do with the electrodes. An EEG clip with a negative pulse is exported as an EDF. When the same clip is now positive. The actual sign of all the sample values is inverted. It could also be a problem in the export step from Neuroworks, but this is unlikely. Please provide me your email address and I will send you the clip with pictures.

Hi Wendy,
I haven't validated any individual fields of record--I simply read the data from the (hopefully) appropriate locations. If your data are inverted, I wonder if a pair of electrodes is backwards? If you think there's a problem with the reader, I'd appreciate it if you could send me a data sample and let me take a look.
Best regards,

Wendy Xiao

Hi we are having some confusion about the polarity of the output values in record.

1. Stereotyped event-related potentials such as the N200 related to face-specific processing appears to be the exact inverse in our signals extracted by edfread

2. We send a pulse to the EEG to mark behavioral events, and these events are negative deflections on the NATUS/Neuroworks EEG recording system, but they appear in the exact opposite polarity once the edf of the clip is exported and extracted with edfread.

Our question is, has the positive/negative polarity of the output from edfread been verified in any way? If so, can you please share with us? Since we are using intracranial electrodes the polarity has important implications on neuronal activity.


Your file is “corrupt” in that it contains an invalid records specification:

hdr.records = -1;

The EDF+ spec states in section 2.1.2 that:

10. The 'number of data records' can only be -1 during recording. As soon as the file is closed, the correct number is known and must be entered.

My code uses that value to read the data.

(NOTE: I wrote an alternate version that ignores hdr.records and reads data in a while loop until done. I shared that code with Alex and verified that it reads his data correctly. If anyone else encounters this issue and would like my "edfreadUntilDone" function, please email me; I'm happy to share it. I'm also curious to hear if anyone else is seeing the hdr.records == -1 issue, and in trying to figure out why.)

Dear Brett Shoelson,

I tried to use your file, it works partially. It opens only header part and do not see the data at all.
I run:
G1 = edfread('sample1.edf')

and I get:
Step 1 of 2: Reading requested records. (This may take a few minutes.)...

And after:

G1 =

ver: 0
patientID: 'Bentz James 13.01.1964 ...'
recordID: '????????????e ...'
startdate: '08.02.08'
starttime: '22.42.36'
bytes: 4608
records: -1
duration: 10
ns: 17
label: {1x17 cell}
transducer: {1x17 cell}
units: {1x17 cell}
physicalMin: [1x17 double]
physicalMax: [1x17 double]
digitalMin: [1x17 double]
digitalMax: [1x17 double]
prefilter: {1x17 cell}
samples: [1x17 double]

Could you help?
Thanks a lot

That section of the code should be run iff you a) specify more than one output (i.e., if you request that the data be returned, and not just the header info); or b) you pass in the optional PV pair: 'assignToVariables',true.

I wrote it that way so you can quickly (and inexpensively) capture the header information if that's all you need, or you can trigger a full data extraction.


Dear Brett Shoelson
i use this m.file to read my EDF.file but after running this m.file in my workspace there are some information just related to header not about the data( EEG signal)
and displays:

Step 1 of 2: Reading requested records. (This may take a few minutes.)...

ans = ....

its ok and right, but as you wrote in your m.file it should be display TOO "
disp('Step 2 of 2: Parsing data...');
but this part of codes seems to be not run.

what should i do to see the content of my signal not just information of header?

thanks a lot

What happens if you simply type
>>data = edfread('abc.edf');


Can somebody post the code to read .edf file.
I am not able to understand how it shud be done. Say, filename is abc.edf, how do i read in matlab R2014a?

@Olga and Clark:
Thanks for reporting these issues; I would like to address them and repost a new version. Do either of you you happen to have an edf datafile and reproduction steps that you can share with me?
Thanks in advance,


Hi Brett! Great function - very helpful. But here is what I came across while using it to load edf eeg data from different EEG data acquisition systems. In case of at least one system, your function did not read the correct sampling frequency and so also produced an incorrect duration of the EEG record. if you are interested, I would be happy to send you the EEG signal to check this.


Hi Brett,

thank you for this file.
I am trying to open an .edf file and I have an error message I do not know how to interpret it :

Subscript indices must either be real positive integers or logicals.

Error in edfread (line 149)
hdr.label{ii} = regexprep(fread(fid,16,'*char')','\W','');

Do you have an idea of how I could fix it ?

Thanks a lot


[...] = edfread(fname, 'targetSignals', 4)

Does that work for you?

Thanks for such a nice file reader. I have a EDF file and it has 64 channel data,I mean the hdr.label has 65 column in workspace. I want to know how I can extract only 4 channel data using this function?Thanks in advance.

I have no idea where your markers are; I just wanted to provide an edf-reading function. You might have more luck asking your question in a physiology-centric newsgroup.


I am recording my eeg signal through Emotiv. I have converted edf to mat but how can I identify my markers in the enormous data? Is there a specific column for that?

@Mahirah: Sorry...I don't understand your question.

hi.. i can read the edf file, but how i want to open my edf file for me to view..


Problem solved. Wasn't putting ' around the edf file name.


Hi Brett,

I am trying to use this to import a .edf file from physionet, but I keep getting an error that says "Undefined function or variable 'psgsleep'." Right now I'm just typing edfread(psgsleep) in MATLAB to try and read the file. Is this correct?

Once you read the file with edfread, you can modify the value in ML. Is that what you mean? (e.g., hdr.records = 1;) Or do you want to edit the edf file itself? (Sorry, I'm not able to support you on editing the edf file.)

Yes your reader is working fine.. the problem is with my file that it has -1 value in hdr.records. I just want to know that is there a possible way to change this value with a correct one?

I'm not sure what the issue is, Farhan. EDFREAD is just a reader. If you explore the header with a different environment/reader and the value of header.records is something other than -1, that would indicate that my function might have a problem. But if the value in that file is -1, then the reader is working correctly. Right?

Sounds like a pretty involved signal processing and classification/machine learning problem. I would suggest that you post your specific question (and what you've tried) on either CSSM or Answers.


When I read edf file that I took from it works fine but when I read my own edf file it displays the header like this:
header =

ver: 0
patientID: [1x80 char]
recordID: [1x80 char]
startdate: '09.11.13'
starttime: '10.25.39'
bytes: 6400
records: -1
duration: 1
ns: 24
label: {1x24 cell}
transducer: {1x24 cell}
units: {1x24 cell}
physicalMin: [1x24 double]
physicalMax: [1x24 double]
digitalMin: [1x24 double]
digitalMax: [1x24 double]
prefilter: {1x24 cell}
samples: [1x24 double]

Can anyone suggest me how to fix this issue? the main issue in my file is that the values of hdr.records is -1. How can I fix this issue?


I have edf files for EEG singnals. My aim is to give the particular signature(system function H(Z) )for the particular disease. I will differentiate the normal patient and defected patient EEG using DWT. I need some help from you.How can i proceed

Great work Brett. After reading edf file I want to draw signals from data I read. Can you help me with this?
I am new here and any help would be appreciated thank you :)


Foroogh, that messages suggests that you're trying to open for reading a file that doesn't exist, or for which you don't have permissions. Have you verified that you specified the filename (and path, if necessary) correctly? Can you check the permissions of the file?

Foroogh R.

hi. thank you for sharing this. I used to read edf files in earlier versions of Matlab and everything was fine. Now I get this error (with the new version of m.file of course):
Error using edfread (line 117)
No such file or directory

Error in Variance (line 19)
[hdr, record] = edfread(adr);
Can you tell me what is wrong?!




works great.
appreciate your help you saved us long long time.

thanks again.





Works great, thanks Brett!


Hi all,
Please note that the new version (5/23/13) supports reading of a user-specified subset of signals.


Hi Brett,

I think I'm getting somewhere by only reading the necessary info (instead of all channel data) into tmpdata. I'm not sure if I'm getting the syntax of fread right though, specifically the SKIP argument. e.g. if I only want one channel (i.e. channel #k):

tmpdata(recnum).data{1} = fread(fid,hdr.samples(k),'int16',hdr.ns*2) * scalefac(k) + dc(k);

which doesn't quite work. I'm probably missing something...

Hi Cindy,

Clearly I'm missing something...

If you can share a file with me and explicitly explain what you'd like to read (and what you'd like to skip), I will dig in and see if I can improve this reader.

char(cumsum([98 16 -13 15 0 -70 69 -11 7 -10 7 7 -4 -1 -46 45 -12 19 -12 15 -8 3 -7 8 -69 53 12 -2]))


Thanks for this, very handy indeed.

As a previous poster has noted though, if you're only after specific channels, the code uses up a great deal of memory.

for ii = 1:hdr.ns
for ii = 1:[1,3,5:7]

doesn't quite work at the point when tmpdata is being generated (where fread is used), nor does it reduce the size of the matrix being created. I run into Out of Memory problems at:

record = zeros(hdr.ns, hdr.samples(1)*hdr.records);

because tmpdata is already taking up too much memory space.

Any thoughts on overcoming these problems? I thought about deleting the irrelevant channels from tmpdata, but got a bit stuck with the syntax. Help would be appreciated!

Farid, I thought that's what I did. Perhaps if my response is unclear, or if I misunderstood your question, you can email me with a better explanation of what you would like to do with EDFREAD.
char(cumsum([98 16 -13 15 0 -70 69 -11 7 -10 7 7 -4 -1 -46 45 -12 19 -12 15 -8 3 -7 8 -69 53 12 -2]))


Thanks Brett for your quick and clear response. Could you please suggest a way to read segments of data (e.g specific signals in shorter segments).


Number of channels (signals?) is specified in line 124:
hdr.ns = str2double(fread(fid,4,'*char')');

In subsequent lines (125,128,132,...) the files reads 1:hdr.ns. If you wanted to, you could modify those calls to read (for example) signals [1,3,5,6,7] by changing instances of

for ii = 1:hdr


for ii = [1,3,5:7]



Thanks for useful code. I wonder to know how I can use the edfread to read specific channels? I have huge file of several channels and am interested on some of them. The comments on MATLAB code is not clear to me.

@Oleksandr (and Ibraheem):
Thanks for the reviews/comments. My goal in writing this was to facilitate using MATLAB to analyze data stored in EDF format.

I encourage you to share your EDFWrite function, if you write one; creating that capability is a bit outside of my job description. ;)

I'm curious, though: what is your rationale for exporting to EDF after you've brought data in to MATLAB for analysis? Is there something you need to do with them that you can't do with MathWorks' tools? (Or did you just want to share with non-MATLAB users?)

Brett (the MATLAB guy)

Hi Brett,
This is a great function, thank you very much for making and sharing it!
Sorry to repeat a question that already has been asked before but is there an edfWrite (or edfSave) by any chance? I'd love to save myself some time making one if at all possible.
Once again, thank you for your work!

Thanks Brett. I discovered the problem. For some reason when I was downloading the file into my Matlab directory The file got corrupted in some way that its much different than the original page. I just copied the text Matlab function into a blank m file in my Matlab directory and so I was able to run the function without errors. Thanks

Hisham, Would you either try to download the function again and re-try to read the file, or send me the file you downloaded. I'd like to understand what's going on.
char(cumsum([98 16 -13 15 0 -70 69 -11 7 -10 7 7 -4 -1 -46 45 -12 19 -12 15 -8 3 -7 8 -69 53 12 -2]))

Thanks Brett for your quick Reply. I am using Matlab R2012a and I am not sure where is the problem. I tried the r01.edf you recommended but the same thing happended. when I run the file I got the message 'Matlab unexpected operator' on every line when I comment out everything before it. I am not doing an coding else than invoking the file by edfread('r01.edf') is this right? Also I don't think line 13 is a comment (although it seems not doing anything in the code). I have downloaded the file edfread directly. So is there anything I am missing? Thanks alot for your help.

Hisham, line 13 is already a comment, isn't it? Can you tell me what platform you're using, and what version of MATLAB? And can you download a signal from Physionet and try to read it? (For instance:


If you can read that signal, it would suggest there's something in your data file that might be problematic.


I am trying to use this function to read an edf file but I am getting the following error always
Error: File: edfread.m Line: 13 Column: 1
Unexpected MATLAB operator.
Even if I comment out Line: 13 the same error occurs on following lines. Is there anything I am missing to run the edf code.

Thanks for sharing. It would be great if you make it two directions by adding export feature (write matlab variables to edf).
Best regards!



Excellent, and timing is perfect I just needed it now!

Great piece of work, thanks.

function [data,header] = edfread(filename)
% Read European Data Format file into MATLAB

fid = fopen(filename,'r','ieee-le');
hdr = char(fread(fid,256,'uchar')');

header.ver=str2num(hdr(1:8)); % 8 ascii : version of this data format (0)
header.patientID = char(hdr(9:88)); % 80 ascii : local patient identification
header.recordID = char(hdr(89:168)); % 80 ascii : local recording identification
header.startdate=char(hdr(169:176)); % 8 ascii : startdate of recording (
header.starttime = char(hdr(177:184)); % 8 ascii : starttime of recording (
header.length = str2num (hdr(185:192)); % 8 ascii : number of bytes in header record
reserved = hdr(193:236); % [EDF+C ] % 44 ascii : reserved
header.records = str2num (hdr(237:244)); % 8 ascii : number of data records (-1 if unknown)
header.duration = str2num (hdr(245:252)); % 8 ascii : duration of a data record, in seconds
header.channels = str2num (hdr(253:256));% 4 ascii : number of signals (ns) in data record

%%%% PART2

header.label=cellstr(char(fread(fid,[16,header.channels],'char')')); % ns * 16 ascii : ns * label (e.g. EEG FpzCz or Body temp)
header.transducer =cellstr(char(fread(fid,[80,header.channels],'char')')); % ns * 80 ascii : ns * transducer type (e.g. AgAgCl electrode)
header.units = cellstr(char(fread(fid,[8,header.channels],'char')')); % ns * 8 ascii : ns * physical dimension (e.g. uV or degreeC)
header.physmin = str2num(char(fread(fid,[8,header.channels],'char')')); % ns * 8 ascii : ns * physical minimum (e.g. -500 or 34)
header.physmax = str2num(char(fread(fid,[8,header.channels],'char')')); % ns * 8 ascii : ns * physical maximum (e.g. 500 or 40)
header.digimin = str2num(char(fread(fid,[8,header.channels],'char')')); % ns * 8 ascii : ns * digital minimum (e.g. -2048)
header.digimax = str2num(char(fread(fid,[8,header.channels],'char')')); % ns * 8 ascii : ns * digital maximum (e.g. 2047)
header.prefilt =cellstr(char(fread(fid,[80,header.channels],'char')')); % ns * 80 ascii : ns * prefiltering (e.g. HP:0.1Hz LP:75Hz)
header.samplerate = str2num(char(fread(fid,[8,header.channels],'char')')); % ns * 8 ascii : ns * nr of samples in each data record
reserved = char(fread(fid,[32,header.channels],'char')'); % ns * 32 ascii : ns * reserved

% DATA read

Ch_data = fread(fid,'int16');

if header.records<0, % number of data records (-1 if unknown)

% reshape data
Ch_data=reshape(Ch_data, [], header.records);

% scale set
sf = (header.physmax - header.physmin)./(header.digimax - header.digimin);
dc = header.physmax - sf.* header.digimax;

data=cell(1, header.channels);
Rs=cumsum([1; header.duration.*header.samplerate]); % index of block data -> Rs(k):Rs(k+1)-1

for k=1:header.channels
data{k}=reshape(Ch_data(Rs(k):Rs(k+1)-1, :), [], 1);
% scale data

% data=cell2mat(data);


Modified the description to cite EDFReadUntilDone. No code changes.

Same bug fix in name of file.

Minor bug fix in name of file.

Fixed a problem triggered by the license conversion on Sept.1, 2016.
Also, I have tried to address the out-of-spec value of -1 for numberOfFiles seen in some edf files.

Updated license

Enabled the import of a user-specified subset of signals. Also fixed a problem when signal labels include spaces or difficult-to-interpret characters.

Fixes a problem with incorrect reading of variable-length signals.

Added copyright.

MATLAB Release Compatibility
Created with R2011a
Compatible with any release
Platform Compatibility
Windows macOS Linux

Discover Live Editor

Create scripts with code, output, and formatted text in a single executable document.

Learn About Live Editor