Code covered by the BSD License  

Highlights from
edfRead

4.75

4.8 | 17 ratings Rate this file 193 Downloads (last 30 days) File Size: 4.35 KB File ID: #31900
image thumbnail

edfRead

by

 

21 Jun 2011 (Updated )

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

| Watch this File

File Information
Description

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

Acknowledgements

This file inspired Edfread2 and Block Edf Load.

MATLAB release MATLAB 7.12 (R2011a)
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (45)
23 Jun 2014 Brett Shoelson

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

Does that work for you?
Brett

19 Jun 2014 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.

12 May 2014 Brett Shoelson

@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

12 May 2014 Dabira

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?

14 Mar 2014 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

08 Dec 2013 Brett Shoelson

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

07 Dec 2013 Mahirah Hamdan

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

07 Dec 2013 Casey

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

07 Dec 2013 Casey

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?

26 Nov 2013 Nisha Jangra  
21 Nov 2013 Brett Shoelson

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

21 Nov 2013 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?

21 Nov 2013 Brett Shoelson

@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

21 Nov 2013 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?

20 Nov 2013 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

20 Nov 2013 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 :)

13 Nov 2013 Tomas  
04 Oct 2013 Brett Shoelson

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

03 Oct 2013 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?!

09 Sep 2013 Romesh  
06 Aug 2013 ziv

Thanks,

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

thanks again.

ZS

15 Jul 2013 Alexander

Thanks!

25 Jun 2013 Pelle Kr√łgholt  
31 May 2013 Cindy

Works great, thanks Brett!

31 May 2013 Cindy  
24 May 2013 Brett Shoelson

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

18 May 2013 Cindy

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

17 May 2013 Brett Shoelson

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

17 May 2013 Cindy

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!

01 May 2013 Brett Shoelson

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

01 May 2013 Farid

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

01 May 2013 Brett Shoelson

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

01 May 2013 Farid

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

29 Apr 2013 Brett Shoelson

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

29 Apr 2013 Oleksandr Makeyev

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,

28 Apr 2013 Hisham Elmoaqet

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

26 Apr 2013 Brett Shoelson

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

25 Apr 2013 Hisham Elmoaqet

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.

25 Apr 2013 Brett Shoelson

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

25 Apr 2013 Hisham Elmoaqet

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.

24 Jan 2013 Ibraheem Al-Dhamari

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

28 Sep 2012 Behnaz  
28 Sep 2012 Behnaz  
29 Feb 2012 Joseph Isler

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

28 Jan 2012 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
23 Jan 2012

Added copyright.

08 May 2013

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

23 May 2013

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

Contact us