File Exchange

image thumbnail

edfRead

version 2.10 (7.44 KB) by

A simple file reader for European Data Formatted (EDF-) files.

4.80645
40 Ratings

221 Downloads

Updated

View License

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.
 
FORMAT SPEC: Source: http://www.edfplus.info/specs/edf.html

Comments and Ratings (125)

Chunyan He

Brett Shoelson

Brett Shoelson (view profile)

IMPORTANT:

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:

https://www.mathworks.com/matlabcentral/fileexchange/54925-uzh-edf-converter

Cheers,
Brett

Brett Shoelson

Brett Shoelson (view profile)

@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.)

Brett

Brett Shoelson

Brett Shoelson (view profile)

@Marta:
Hi Marta. Can you by chance send me a sample test file for which you receive this message?
Thanks,
Brett
(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.

Marta.

Aiva

Aiva (view profile)

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.

Brett Shoelson

Brett Shoelson (view profile)

@Aiva:
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).
HTH,
Brett

Aiva

Aiva (view profile)

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

Brett
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.

Brett Shoelson

Brett Shoelson (view profile)

@ 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?
Brett

Susanne Roos

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

Brett Shoelson

Brett Shoelson (view profile)

@SHARANABASAVARA:
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,....
Brett

Hi
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 physionet.org
So help me in this regard
Thank you

Brett Shoelson

Brett Shoelson (view profile)

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

Brett Shoelson

Brett Shoelson (view profile)

NOTE:

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)!

Thanks,
Brett

kaare

kaare (view profile)

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

imu931

imu931 (view profile)

Great solution for EDF annotation.

Kalai Chelvi

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

Brett Shoelson

Brett Shoelson (view profile)

@samhitha:
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.)
Brett

mahrukh jamil

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

mahrukh jamil

Dear Brett,
Thank you for your reply. Can you send that file at my email address.
mahrukh.jamil@mail.mcgill.ca
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,
Mahrukh

Brett Shoelson

Brett Shoelson (view profile)

@mahrukh:

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]))

Regards,
Brett

mahrukh jamil

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
Mahrukh

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.
Sashi

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

xu han (view profile)

Mariam Zabihi

Brett Shoelson

Brett Shoelson (view profile)

@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.)
Brett

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?

Brett Shoelson

Brett Shoelson (view profile)

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

Mattias F

Hi!
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)
 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

Brett Shoelson

Brett Shoelson (view profile)

@Pierre,
Thanks much...it'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,
Brett

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).

SOLUTION 1

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
                try
                    record(recnum, ctr : ctr + hdr.samples(ii) - 1) = tmpdata(jj).data{ii};
                end
                ctr = ctr + hdr.samples(ii);
            end
            recnum = recnum + 1;
    end

SOLUTION 2

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,:);

Best,
Pierre

Brett Shoelson

Brett Shoelson (view profile)

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.

Sorry.
Brett

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?
Thanks

Ivan

Ivan (view profile)

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

Brett Shoelson

Brett Shoelson (view profile)

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

Ivan

Ivan (view profile)

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

Brett Shoelson

Brett Shoelson (view profile)

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!
Brett

zara mansoor

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.

sonali jadhav

hello sir'
IM TRYING TO WORK ON MATERNAL-FETAL ECG SIGNALS DOWNLOADED FROM PHYSIONET DATABASE. ITS FINE WITH READING RECORDS. BUT THE
STEP 2 OF 2:PARSING DATA...
IS NOT GETTING EXECUTED.IM UNABLE TO PLOT THE SIGNAL.KINDY HELP

Brett Shoelson

Brett Shoelson (view profile)

PLEASE NOTE THAT EDF FILES FROM EYELINK ARE NOT "EUROPEAN DATA FORMAT" FILES, AND ARE NOT SUPPORTED BY THIS READER. SORRY!

Max

Max (view profile)

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

Brett Shoelson

Brett Shoelson (view profile)

@Max,
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.
Regards,
Brett

Max

Max (view profile)

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,
Max

Subscript indices must either be
real positive integers or
logicals.

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

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.

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

@brett
 iam using R13a

Brett Shoelson

Brett Shoelson (view profile)

@Hari,
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?
Brett

@brett
Actually i am matlab beginner.
I downloaded that file from this website as you mentioned in the previous comments
http://www.physionet.org/physiobank/database/adfecgdb/r01.edf

thankyou in advance

Brett Shoelson

Brett Shoelson (view profile)

@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?)
Brett

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!

Brett Shoelson

Brett Shoelson (view profile)

@Yang:
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.)
Brett

YANG XIE

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?

Jennifer

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

Rebecca Galea

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

Brett Shoelson

Brett Shoelson (view profile)

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

Rebecca Galea

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.

Rebecca

Ji Sung

Brett Shoelson

Brett Shoelson (view profile)

@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.
Regards,
Brett

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.

Brett Shoelson

Brett Shoelson (view profile)

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,
Brett

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.

Brett Shoelson

Brett Shoelson (view profile)

@Alexander,

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

Brett Shoelson

Brett Shoelson (view profile)

@bahareh:
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.

Cheers,
Brett

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

Brett Shoelson

Brett Shoelson (view profile)

@Arathi:
What happens if you simply type
>>data = edfread('abc.edf');
?
Brett

Arathi

Arathi (view profile)

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?

Brett Shoelson

Brett Shoelson (view profile)

@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,
Brett

olga

olga (view profile)

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.

olga

olga (view profile)

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
Clark

Elisa

Elisa (view profile)

Brett Shoelson

Brett Shoelson (view profile)

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

Does that work for you?
Brett

SALEHA KHATUN

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.

Brett Shoelson

Brett Shoelson (view profile)

@Dabira:
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.
Cheers,
Brett

Dabira

Dabira (view profile)

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?

Nick Palmius

Hi Brett,

Thank you for posting this function. The issue raised by Farhan Masood below (hdr.records = -1) is actually within the EDF spec for an unknown record count. I also found that this showed up in a physionet file (file n14.edf in http://physionet.org/pn6/capslpdb/).

I have created a patch for this issue here: https://dl.dropboxusercontent.com/u/945924/edfread.patch.

Best,
Nick

Brett Shoelson

Brett Shoelson (view profile)

@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..

Casey

Casey (view profile)

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

Casey

Casey (view profile)

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?

Nisha Jangra

Brett Shoelson

Brett Shoelson (view profile)

Farhan,
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.)
Brett

Farhan Masood

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?

Brett Shoelson

Brett Shoelson (view profile)

@Farhan:
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?

@Dayanand:
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.

Cheers!
Brett

Farhan Masood

When I read edf file that I took from physionet.org 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?

Dayanand

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

Farhan Masood

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 :)

Tomas

Tomas (view profile)

Brett Shoelson

Brett Shoelson (view profile)

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?
Brett

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?!

Romesh

Romesh (view profile)

ziv

ziv (view profile)

Thanks,

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

thanks again.

ZS

Alexander

Thanks!

Cindy

Cindy (view profile)

Works great, thanks Brett!

Cindy

Cindy (view profile)

Brett Shoelson

Brett Shoelson (view profile)

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

Cindy

Cindy (view profile)

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...

Brett Shoelson

Brett Shoelson (view profile)

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.

Thanks!
Brett
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]))

Cindy

Cindy (view profile)

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.

Replacing
     for ii = 1:hdr.ns
with
     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!

Brett Shoelson

Brett Shoelson (view profile)

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.
Cheers,
Brett
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]))

Farid

Farid (view profile)

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).
Thanks

Farid

Brett Shoelson

Brett Shoelson (view profile)

Farid,
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

to

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

HTH,
Brett

Farid

Farid (view profile)

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.
Thanks

Brett Shoelson

Brett Shoelson (view profile)

@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!
Regards,

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

Brett Shoelson

Brett Shoelson (view profile)

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.
Thanks,
Brett
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.

Brett Shoelson

Brett Shoelson (view profile)

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:

http://www.physionet.org/physiobank/database/adfecgdb/r01.edf

).

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

Thanks,
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.

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

Behnaz

Behnaz (view profile)

Behnaz

Behnaz (view profile)

Joseph Isler

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

Andrey Shapkin

Great piece of work, thanks.

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

fid = fopen(filename,'r','ieee-le');
% PART1
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 (dd.mm.yy)
header.starttime = char(hdr(177:184)); % 8 ascii : starttime of recording (hh.mm.ss)
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)
R=sum(header.duration*header.samplerate);
header.records=fix(length(Ch_data)./R);
end

% 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{k}=data{k}.*sf(k)+dc(k);
end

% data=cell2mat(data);

Updates

2.10

Same bug fix in name of file.

2.1

Minor bug fix in name of file.

2.0

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.

1.6.0.1

Updated license

1.6

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

1.3

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

1.1

Added copyright.

MATLAB Release
MATLAB 7.12 (R2011a)
Acknowledgements

Inspired: blockEdfLoad, Read Persyst lay-dat files, edfread2

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video