function [hdr, record] = edfread(fname, varargin)
% 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(...,'desiredSignals',desiredSignals)
% Allows user to specify the names (or position numbers) of the
% subset of signals to be read. |desiredSignals| may be either a
% string, a cell array of comma-separated strings, or a vector of
% numbers. (Default behavior is to read all signals.)
% E.g.:
% data = edfread(mydata.edf,'desiredSignals','Thoracic');
% data = edfread(mydata.edf,'desiredSignals',{'Thoracic1','Abdominal'});
% or
% data = edfread(mydata.edf,'desiredSignals',[,,:]);
%
% FORMAT SPEC: Source: http://www.edfplus.info/specs/edf.html SEE ALSO:
% http://www.dpmi.tu-graz.ac.at/~schloegl/matlab/eeg/edf_spec.htm
%
% The first bytes of the header record specify the version number of
% this format, local patient and recording identification, time information
% about the recording, the number of data records and finally the number of
% signals (ns) in each data record. Then for each signal another bytes
% follow in the header record, each specifying the type of signal (e.g.
% EEG, body temperature, etc.), amplitude calibration and the number of
% samples in each data record (from which the sampling frequency can be
% derived since the duration of a data record is also known). In this way,
% the format allows for different gains and sampling frequencies for each
% signal. The header record contains + (ns * ) bytes.
%
% Following the header record, each of the subsequent data records contains
% 'duration' seconds of 'ns' signals, with each signal being represented by
% the specified (in the header) number of samples. In order to reduce data
% size and adapt to commonly used software for acquisition, processing and
% graphical display of polygraphic signals, each sample value is
% represented as a -byte integer in 's complement format. Figure 1 shows
% the detailed format of each data record.
%
% DATA SOURCE: Signals of various types (including the sample signal used
% below) are available from PHYSIONET: http://www.physionet.org/
%
%
% % EXAMPLE :
% % Read all waveforms/data associated with file 'ecgca998.edf':
%
% [header, recorddata] = edfRead('ecgca998.edf');
%
% % EXAMPLE :
% % Read records and , associated with file 'ecgca998.edf':
%
% header = edfRead('ecgca998.edf','AssignToVariables',true);
% % Header file specifies data labels 'label_1'...'label_n'; these are
% % created as variables in the caller workspace.
%
% Coded // by Brett Shoelson, PhD
% brett.shoelson@mathworks.com
% Copyright - MathWorks, Inc.
%
% Modifications:
% // Fixed a problem with a poorly subscripted variable. (Under certain
% conditions, data were being improperly written to the 'records' variable.
% Thanks to Hisham El Moaqet for reporting the problem and for sharing a
% file that helped me track it down.)
%
% // Enabled import of a user-selected subset of signals. Thanks to
% Farid and Cindy for pointing out the deficiency. Also fixed the import of
% signals that had "bad" characters (spaces, etc) in their names. % HEADER RECORD
% ascii : version of this data format ()
% ascii : local patient identification
% ascii : local recording identification
% ascii : startdate of recording (dd.mm.yy)
% ascii : starttime of recording (hh.mm.ss)
% ascii : number of bytes in header record
% ascii : reserved
% ascii : number of data records (- if unknown)
% ascii : duration of a data record, in seconds
% ascii : number of signals (ns) in data record
% ns * ascii : ns * label (e.g. EEG FpzCz or Body temp)
% ns * ascii : ns * transducer type (e.g. AgAgCl electrode)
% ns * ascii : ns * physical dimension (e.g. uV or degreeC)
% ns * ascii : ns * physical minimum (e.g. - or )
% ns * ascii : ns * physical maximum (e.g. or )
% ns * ascii : ns * digital minimum (e.g. -)
% ns * ascii : ns * digital maximum (e.g. )
% ns * ascii : ns * prefiltering (e.g. HP:.1Hz LP:75Hz)
% ns * ascii : ns * nr of samples in each data record
% ns * ascii : ns * reserved % DATA RECORD
% nr of samples[] * integer : first signal in the data record
% nr of samples[] * integer : second signal
% ..
% ..
% nr of samples[ns] * integer : last signal if nargin >
error('EDFREAD: Too many input arguments.');
end if ~nargin
error('EDFREAD: Requires at least one input argument (filename to read).');
end [fid,msg] = fopen(fname,'r');
if fid == -
error(msg)
end assignToVariables = false; %Default
targetSignals = []; %Default
for ii = ::numel(varargin)
switch lower(varargin{ii})
case 'assigntovariables'
assignToVariables = varargin{ii+};
case 'targetsignals'
targetSignals = varargin{ii+};
otherwise
error('EDFREAD: Unrecognized parameter-value pair specified. Valid values are ''assignToVariables'' and ''targetSignals''.')
end
end % HEADER
hdr.ver = str2double(char(fread(fid,)'));
hdr.patientID = fread(fid,,'*char')';
hdr.recordID = fread(fid,,'*char')';
hdr.startdate = fread(fid,,'*char')';% (dd.mm.yy)
% hdr.startdate = datestr(datenum(fread(fid,,'*char')','dd.mm.yy'), 29); %'yyyy-mm-dd' (ISO 8601)
hdr.starttime = fread(fid,,'*char')';% (hh.mm.ss)
% hdr.starttime = datestr(datenum(fread(fid,,'*char')','hh.mm.ss'), 13); %'HH:MM:SS' (ISO 8601)
hdr.bytes = str2double(fread(fid,,'*char')');
reserved = fread(fid,);
hdr.records = str2double(fread(fid,,'*char')');
hdr.duration = str2double(fread(fid,,'*char')');
% Number of signals
hdr.ns = str2double(fread(fid,,'*char')');
for ii = :hdr.ns
hdr.label{ii} = regexprep(fread(fid,,'*char')','\W','');
end if isempty(targetSignals)
targetSignals = :numel(hdr.label);
elseif iscell(targetSignals)||ischar(targetSignals)
targetSignals = find(ismember(hdr.label,regexprep(targetSignals,'\W','')));
end
if isempty(targetSignals)
error('EDFREAD: The signal(s) you requested were not detected.')
end for ii = :hdr.ns
hdr.transducer{ii} = fread(fid,,'*char')';
end
% Physical dimension
for ii = :hdr.ns
hdr.units{ii} = fread(fid,,'*char')';
end
% Physical minimum
for ii = :hdr.ns
hdr.physicalMin(ii) = str2double(fread(fid,,'*char')');
end
% Physical maximum
for ii = :hdr.ns
hdr.physicalMax(ii) = str2double(fread(fid,,'*char')');
end
% Digital minimum
for ii = :hdr.ns
hdr.digitalMin(ii) = str2double(fread(fid,,'*char')');
end
% Digital maximum
for ii = :hdr.ns
hdr.digitalMax(ii) = str2double(fread(fid,,'*char')');
end
for ii = :hdr.ns
hdr.prefilter{ii} = fread(fid,,'*char')';
end
for ii = :hdr.ns
hdr.samples(ii) = str2double(fread(fid,,'*char')');
end
for ii = :hdr.ns
reserved = fread(fid,,'*char')';
end
hdr.label = hdr.label(targetSignals);
hdr.label = regexprep(hdr.label,'\W','');
hdr.units = regexprep(hdr.units,'\W','');
disp('Step 1 of 2: Reading requested records. (This may take a few minutes.)...');
if nargout > || assignToVariables
% Scale data (linear scaling)
scalefac = (hdr.physicalMax - hdr.physicalMin)./(hdr.digitalMax - hdr.digitalMin);
dc = hdr.physicalMax - scalefac .* hdr.digitalMax; % RECORD DATA REQUESTED
tmpdata = struct;
for recnum = :hdr.records
for ii = :hdr.ns
% Read or skip the appropriate number of data points
if ismember(ii,targetSignals)
% Use a cell array for DATA because number of samples may vary
% from sample to sample
tmpdata(recnum).data{ii} = fread(fid,hdr.samples(ii),'int16') * scalefac(ii) + dc(ii);
else
fseek(fid,hdr.samples(ii)*,);
end
end
end
hdr.units = hdr.units(targetSignals);
hdr.physicalMin = hdr.physicalMin(targetSignals);
hdr.physicalMax = hdr.physicalMax(targetSignals);
hdr.digitalMin = hdr.digitalMin(targetSignals);
hdr.digitalMax = hdr.digitalMax(targetSignals);
hdr.prefilter = hdr.prefilter(targetSignals);
hdr.transducer = hdr.transducer(targetSignals); record = zeros(numel(hdr.label), hdr.samples()*hdr.records);
% NOTE: // Modified for loop below to change instances of hdr.samples to
% hdr.samples(ii). I think this underscored a problem with the reader. disp('Step 2 of 2: Parsing data...');
recnum = ;
for ii = :hdr.ns
if ismember(ii,targetSignals)
ctr = ;
for jj = :hdr.records
try
record(recnum, ctr : ctr + hdr.samples(ii) - ) = tmpdata(jj).data{ii};
end
ctr = ctr + hdr.samples(ii);
end
recnum = recnum + ;
end
end
hdr.ns = numel(hdr.label);
hdr.samples = hdr.samples(targetSignals); if assignToVariables
for ii = :numel(hdr.label)
try
eval(['assignin(''caller'',''',hdr.label{ii},''',record(ii,:))'])
end
end
record = [];
end
end
fclose(fid);

edfread源码的更多相关文章

  1. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  2. C# ini文件操作【源码下载】

    介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...

  3. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  4. 从源码看Azkaban作业流下发过程

    上一篇零散地罗列了看源码时记录的一些类的信息,这篇完整介绍一个作业流在Azkaban中的执行过程,希望可以帮助刚刚接手Azkaban相关工作的开发.测试. 一.Azkaban简介 Azkaban作为开 ...

  5. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  6. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  7. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  8. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  9. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

随机推荐

  1. 错误处理:error(0) error portability:3 this xilinx application has run out of memory has encountered a memory conflict

    在FPGA侧提供了一个gp0,gp1各占1m内存的版本后.生成mcs版本,在下载版本时报错: error(0) error portability:3 this xilinx application ...

  2. 微信小程序<swiper-item>标签中传入多个数组型数据的方法(小程序交流群:604788754)

    在<swiper-item>中用for循环传入多个成对不同数据时的实现方法. 效果如下: 遍历实现方法:wxss省略: wxml中代码: <!--导航部分轮播图--> < ...

  3. vue做的第二个app

    用vue做应用最好的还是组件的复用上次做饿了吗的app封装了一个评分star的组件只要引入组件传入size大小和score分数就行了,这次做豆瓣直接就就用上了不用重复写代码.不过vue做单页应用全部挂 ...

  4. redis学习——数据持久化

    一.概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的.所以,我们需要将内存中的数据持久 ...

  5. Linux权限总结

    第1章 课前小拓展 虚拟机打不开原因 问题: 该虚拟机似乎正在使用中. 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权.否则,请按“取消(C)”按钮以防损坏. 配置文件: E:\vm ...

  6. Android向通讯录添加联系人的一般方法

    Android向通讯录添加联系人的一般方法 以一个简单的例子加以说明,记得需要相应的权限: 测试代码,关键的内容就在add函数里面. package zhangphil.demo; import an ...

  7. 【Alpha】事后分析

    Alpha阶段终于告一段落,我们的团队也完整经历了从提出设想.用户需求分析,到开发.测试,再到部署上线.推广的流程."葫芦娃不想写代码"团队还是较出色地完成了Alpha阶段的工作, ...

  8. 【webpack学习笔记】a06-生产环境和开发环境配置

    生产环境和开发环境的配置目标不一样,生产环境主要是让文件压缩得更小,更优化资源,改善加载时间. 而开发环境,主要是要开发更方便,更节省时间,比如调试比如自动刷新. 所以可以分开配置不同的开发环境,然后 ...

  9. react 表单受控和非受控

    参见:https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/ 非受控: onSubmit = ()=>{ const val ...

  10. DevExpress ASP.NET Core Controls 2019发展蓝图(No.3)

    本文主要为大家介绍DevExpress ASP.NET Core Controls 2019年的官方发展蓝图,更多精彩内容欢迎持续收藏关注哦~ [DevExpress ASP.NET Controls ...