Diff of /rddata.m [000000] .. [e6b7a4]

Switch to unified view

a b/rddata.m
1
% This programm reads ECG data which are saved in format 212.
2
% (e.g., 100.dat from MIT-BIH-DB, cu01.dat from CU-DB,...)
3
% The data are displayed in a figure together with the annotations.
4
% The annotations are saved in the vector ANNOT, the corresponding
5
% times (in seconds) are saved in the vector ATRTIME.
6
% The annotations are saved as numbers, the meaning of the numbers can
7
% be found in the codetable "ecgcodes.h" available at www.physionet.org.
8
%
9
% ANNOT only contains the most important information, which is displayed
10
% with the program rdann (available on www.physionet.org) in the 3rd row.
11
% The 4th to 6th row are not saved in ANNOT.
12
%
13
%
14
%      created on Feb. 27, 2003 by
15
%      Robert Tratnig (Vorarlberg University of Applied Sciences)
16
%      (email: rtratnig@gmx.at),
17
%
18
%      algorithm is based on a program written by
19
%      Klaus Rheinberger (University of Innsbruck)
20
%      (email: klaus.rheinberger@uibk.ac.at)
21
%
22
%-------------------------------------------------------------------------
23
clc; clear all;
24
25
%------ SPECIFY DATA ------------------------------------------------------
26
%------ 指定数据文件 -------------------------------------------------------
27
PATH= 'F:\MATLAB\MIT-BIH'; % 指定数据的储存路径
28
HEADERFILE= '100.hea';      % .hea 格式,头文件,可用记事本打开
29
ATRFILE= '100.atr';         % .atr 格式,属性文件,数据格式为二进制数
30
DATAFILE='100.dat';         % .dat ¸ñʽ£¬ECG Êý¾Ý
31
SAMPLES2READ=1800;          % 指定需要读入的样本数
32
                            % 若.dat文件中存储有两个通道的信号:
33
                            % 则读入 2*SAMPLES2READ 个数据 
34
35
%------ LOAD HEADER DATA --------------------------------------------------
36
%------ 读入头文件数据 -----------------------------------------------------
37
%
38
% 示例:用记事本打开的117.hea 文件的数据
39
%
40
%      117 2 360 650000
41
%      117.dat 212 200 11 1024 839 31170 0 MLII
42
%      117.dat 212 200 11 1024 930 28083 0 V2
43
%      # 69 M 950 654 x2
44
%      # None
45
%
46
%-------------------------------------------------------------------------
47
fprintf(1,'\\n$> WORKING ON %s ...\n', HEADERFILE); % 在Matlab命令行窗口提示当前工作状态
48
% 
49
% 【注】函数 fprintf 的功能将格式化的数据写入到指定文件中。
50
% ±í´ïʽ£ºcount = fprintf(fid,format,A,...)
51
% 在字符串'format'的控制下,将矩阵A的实数数据进行格式化,并写入到文件对象fid中。该函数返回所写入数据的字节数 count。
52
% fid 是通过函数 fopen 获得的整型文件标识符。fid=1,表示标准输出(即输出到屏幕显示);fid=2,表示标准偏差。
53
%
54
signalh= fullfile(PATH, HEADERFILE);    % 通过函数 fullfile 获得头文件的完整路径
55
fid1=fopen(signalh,'r');    % 打开头文件,其标识符为 fid1 ,属性为'r'--“只读”
56
z= fgetl(fid1);             % 读取头文件的第一行数据,字符串格式
57
A= sscanf(z, '%*s %d %d %d',[1,3]); % 按照格式 '%*s %d %d %d' 转换数据并存入矩阵 A 中
58
nosig= A(1);    % 信号通道数目
59
sfreq=A(2);     % 数据采样频率
60
clear A;        % 清空矩阵 A ,准备获取下一行数据
61
for k=1:nosig           % 读取每个通道信号的数据信息
62
    z= fgetl(fid1);
63
    A= sscanf(z, '%*s %d %d %d %d %d',[1,5]);
64
    dformat(k)= A(1);           % 信号格式; 这里只允许为 212 格式
65
    gain(k)= A(2);              % 每 mV 包含的整数个数
66
    bitres(k)= A(3);            % 采样精度(位分辨率)
67
    zerovalue(k)= A(4);         % ECG 信号零点相应的整数值
68
    firstvalue(k)= A(5);        % 信号的第一个整数值 (用于偏差测试)
69
end;
70
fclose(fid1);
71
clear A;
72
73
%------ LOAD BINARY DATA --------------------------------------------------
74
%------ 读取 ECG 信号二值数据 ----------------------------------------------
75
%
76
if dformat~= [212,212], error('this script does not apply binary formats different to 212.'); end;
77
signald= fullfile(PATH, DATAFILE);            % 读入 212 格式的 ECG 信号数据
78
fid2=fopen(signald,'r');
79
A= fread(fid2, [3, SAMPLES2READ], 'uint8')';  % matrix with 3 rows, each 8 bits long, = 2*12bit
80
fclose(fid2);
81
% 通过一系列的移位(bitshift)、位与(bitand)运算,将信号由二值数据转换为十进制数
82
M2H= bitshift(A(:,2), -4);        %字节向右移四位,即取字节的高四位
83
M1H= bitand(A(:,2), 15);          %取字节的低四位
84
PRL=bitshift(bitand(A(:,2),8),9);     % sign-bit   取出字节低四位中最高位,向右移九位
85
PRR=bitshift(bitand(A(:,2),128),5);   % sign-bit   取出字节高四位中最高位,向右移五位
86
M( : , 1)= bitshift(M1H,8)+ A(:,1)-PRL;
87
M( : , 2)= bitshift(M2H,8)+ A(:,3)-PRR;
88
if M(1,:) ~= firstvalue, error('inconsistency in the first bit values'); end;
89
switch nosig
90
case 2
91
    M( : , 1)= (M( : , 1)- zerovalue(1))/gain(1);
92
    M( : , 2)= (M( : , 2)- zerovalue(2))/gain(2);
93
    TIME=(0:(SAMPLES2READ-1))/sfreq;
94
case 1
95
    M( : , 1)= (M( : , 1)- zerovalue(1));
96
    M( : , 2)= (M( : , 2)- zerovalue(1));
97
    M=M';
98
    M(1)=[];
99
    sM=size(M);
100
    sM=sM(2)+1;
101
    M(sM)=0;
102
    M=M';
103
    M=M/gain(1);
104
    TIME=(0:2*(SAMPLES2READ)-1)/sfreq;
105
otherwise  % this case did not appear up to now!
106
    % here M has to be sorted!!!
107
    disp('Sorting algorithm for more than 2 signals not programmed yet!');
108
end;
109
clear A M1H M2H PRR PRL;
110
fprintf(1,'\\n$> LOADING DATA FINISHED \n');
111
112
%------ LOAD ATTRIBUTES DATA ----------------------------------------------
113
atrd= fullfile(PATH, ATRFILE);      % attribute file with annotation data
114
fid3=fopen(atrd,'r');
115
A= fread(fid3, [2, inf], 'uint8')';
116
fclose(fid3);
117
ATRTIME=[];
118
ANNOT=[];
119
sa=size(A);
120
saa=sa(1);
121
i=1;
122
while i<=saa
123
    annoth=bitshift(A(i,2),-2);
124
    if annoth==59
125
        ANNOT=[ANNOT;bitshift(A(i+3,2),-2)];
126
        ATRTIME=[ATRTIME;A(i+2,1)+bitshift(A(i+2,2),8)+...
127
                bitshift(A(i+1,1),16)+bitshift(A(i+1,2),24)];
128
        i=i+3;
129
    elseif annoth==60
130
        % nothing to do!
131
    elseif annoth==61
132
        % nothing to do!
133
    elseif annoth==62
134
        % nothing to do!
135
    elseif annoth==63
136
        hilfe=bitshift(bitand(A(i,2),3),8)+A(i,1);
137
        hilfe=hilfe+mod(hilfe,2);
138
        i=i+hilfe/2;
139
    else
140
        ATRTIME=[ATRTIME;bitshift(bitand(A(i,2),3),8)+A(i,1)];
141
        ANNOT=[ANNOT;bitshift(A(i,2),-2)];
142
   end;
143
   i=i+1;
144
end;
145
ANNOT(length(ANNOT))=[];       % last line = EOF (=0)
146
ATRTIME(length(ATRTIME))=[];   % last line = EOF
147
clear A;
148
ATRTIME= (cumsum(ATRTIME))/sfreq;
149
ind= find(ATRTIME <= TIME(end));
150
ATRTIMED= ATRTIME(ind);
151
ANNOT=round(ANNOT);
152
ANNOTD= ANNOT(ind);
153
154
%------ DISPLAY DATA ------------------------------------------------------
155
figure(1); clf, box on, hold on
156
plot(TIME, M(:,1),'r');
157
if nosig==2
158
    plot(TIME, M(:,2),'b');
159
end;
160
for k=1:length(ATRTIMED)
161
    text(ATRTIMED(k),0,num2str(ANNOTD(k)));
162
end;
163
xlim([TIME(1), TIME(end)]);
164
xlabel('Time / s'); ylabel('Voltage / mV');
165
string=['ECG signal ',DATAFILE];
166
title(string);
167
fprintf(1,'\\n$> DISPLAYING DATA FINISHED \n');
168
169
% -------------------------------------------------------------------------
170
fprintf(1,'\\n$> ALL FINISHED \n');