|
a |
|
b/data preprocessing_Matlab/qsPeaks.m |
|
|
1 |
function [ECGpeaks] = QSpeaks( ECG,Rposition,fs ) |
|
|
2 |
%Q,S peaks detection |
|
|
3 |
% point to point time duration is determined by sampling frequency: 1/fs |
|
|
4 |
% the duration of QRS complex varies from 0.1s to 0.2s |
|
|
5 |
% complex--fs*0.2 |
|
|
6 |
aveHB = length(ECG)/length(Rposition); |
|
|
7 |
fid_pks = zeros(length(Rposition),7); |
|
|
8 |
% P QRSon Q R S QRSoff |
|
|
9 |
%% set up searching windows |
|
|
10 |
windowS = round(fs*0.1); windowQ = round(fs*0.05); |
|
|
11 |
windowP = round(aveHB/3); windowT = round(aveHB*2/3); |
|
|
12 |
windowOF = round(fs*0.04); |
|
|
13 |
% initialization |
|
|
14 |
for i = 1:length(Rposition) |
|
|
15 |
thisR = Rposition(i); |
|
|
16 |
if i==1 |
|
|
17 |
fid_pks(i,4) = thisR; |
|
|
18 |
fid_pks(i,6) = thisR+windowS; |
|
|
19 |
elseif i==length(Rposition) |
|
|
20 |
fid_pks(i,4) = thisR; |
|
|
21 |
%(thisR+windowT) < length(ECG) && (thisR - windowP) >=1 |
|
|
22 |
fid_pks(i,2) = thisR-windowQ; |
|
|
23 |
else |
|
|
24 |
|
|
|
25 |
if (thisR+windowT) < length(ECG) && (thisR - windowP) >=1 |
|
|
26 |
% Q S peaks |
|
|
27 |
fid_pks(i,4) = thisR; |
|
|
28 |
[Sv,Sp] = min(ECG(thisR:thisR+windowS)); |
|
|
29 |
thisS = Sp + thisR-1; |
|
|
30 |
fid_pks(i,5) = thisS; |
|
|
31 |
[Qv,Qp] = min(ECG(thisR-windowQ:thisR)); |
|
|
32 |
thisQ = thisR-(windowQ+1) + Qp; |
|
|
33 |
fid_pks(i,3)=thisQ; |
|
|
34 |
% onset and offset detection |
|
|
35 |
interval_q = ECG(thisQ-windowOF:thisQ); |
|
|
36 |
[ ind ] = onoffset(interval_q,'on' ); |
|
|
37 |
thisON = thisQ - (windowOF+1) + ind; |
|
|
38 |
interval_s = ECG(thisS:thisS+windowOF); |
|
|
39 |
[ ind ] = onoffset( interval_s,'off' ); |
|
|
40 |
thisOFF = thisS + ind-1; |
|
|
41 |
fid_pks(i,2) = thisON; |
|
|
42 |
fid_pks(i,6) = thisOFF; |
|
|
43 |
% % T and P waves detection |
|
|
44 |
% lastOFF = fid_pks(i-1,6); |
|
|
45 |
% nextON = |
|
|
46 |
end |
|
|
47 |
end |
|
|
48 |
end |
|
|
49 |
%% |
|
|
50 |
% P,T detection |
|
|
51 |
% Detection T waves first and distinguish the type of T waves |
|
|
52 |
for i = 2:length(Rposition)-1 |
|
|
53 |
lastOFF = fid_pks(i-1,6); |
|
|
54 |
thisON = fid_pks(i,2); |
|
|
55 |
thisOFF = fid_pks(i,6); |
|
|
56 |
nextON = fid_pks(i+1,2); |
|
|
57 |
if thisON>lastOFF && thisOFF<nextON |
|
|
58 |
Tzone = (thisOFF:(nextON-round((nextON-thisOFF)/3))); |
|
|
59 |
Pzone = ((lastOFF+round(2*(thisON-lastOFF)/3)):thisON); |
|
|
60 |
[Tpks,thisT] = max(ECG(Tzone)); |
|
|
61 |
[Ppks,thisP] = max(ECG(Pzone)); |
|
|
62 |
fid_pks(i,1) = (lastOFF+round(2*(thisON-lastOFF)/3)) + thisP -1; |
|
|
63 |
fid_pks(i,7) = thisOFF + thisT -1; |
|
|
64 |
end |
|
|
65 |
end |
|
|
66 |
ECGpeaks = []; |
|
|
67 |
Ind = zeros(length(Rposition),1); |
|
|
68 |
for i = 1:length(Rposition) |
|
|
69 |
Ind(i) = prod(fid_pks(i,:)); |
|
|
70 |
if Ind(i) ~= 0 |
|
|
71 |
ECGpeaks = [ECGpeaks;fid_pks(i,:)]; |
|
|
72 |
end |
|
|
73 |
end |
|
|
74 |
|
|
|
75 |
|
|
|
76 |
end |
|
|
77 |
% Tpks = []; |
|
|
78 |
% Tposition =[]; |
|
|
79 |
% Ttype = []; |
|
|
80 |
% Ppks = []; |
|
|
81 |
% Pposition =[]; |
|
|
82 |
% if length(QRS_OFF) <= length(QRS_ON) |
|
|
83 |
% for i = 1:length(QRS_OFF)-1 |
|
|
84 |
% lengthTzone = int64((QRS_ON(i+1)-QRS_OFF(i))*2/3); |
|
|
85 |
% if lengthTzone <= 0 |
|
|
86 |
% lengthTzone = abs(lengthTzone); |
|
|
87 |
% disp('abnormal heart beat'); |
|
|
88 |
% end |
|
|
89 |
% if QRS_OFF(i)+lengthTzone-1 > length(ECG) |
|
|
90 |
% Tzone = ECG(QRS_OFF(i):length(ECG)); |
|
|
91 |
% else |
|
|
92 |
% Tzone = ECG(QRS_OFF(i):QRS_OFF(i)+lengthTzone-1); |
|
|
93 |
% end |
|
|
94 |
% % if length(max(Tzone))~=1 |
|
|
95 |
% % deb = 1; |
|
|
96 |
% % end |
|
|
97 |
% [Tpks(end+1),Tind] = max(Tzone); |
|
|
98 |
% Tposition(end+1) = QRS_OFF(i)+Tind-1; |
|
|
99 |
% lengthPzone = int64((-QRS_OFF(i)+QRS_ON(i+1))/3); |
|
|
100 |
% if lengthPzone <= 0 |
|
|
101 |
% lengthPzone = abs(lengthPzone); |
|
|
102 |
% disp('abnormal heart beat'); |
|
|
103 |
% end |
|
|
104 |
% Pzone = ECG(QRS_ON(i+1)-lengthPzone-1:QRS_ON(i+1)); |
|
|
105 |
% [Ppks(end+1),Pind] = max(Pzone); |
|
|
106 |
% Pposition(end+1) = QRS_ON(i+1)+Pind-lengthPzone; |
|
|
107 |
% end |
|
|
108 |
% else |
|
|
109 |
% for i = 1:length(QRS_ON)-1 |
|
|
110 |
% lengthTzone = int64((QRS_ON(i+1)-QRS_OFF(i))*2/3); |
|
|
111 |
% if QRS_OFF(i)+lengthTzone-1 > length(ECG) |
|
|
112 |
% Tzone = ECG(QRS_OFF(i):length(ECG)); |
|
|
113 |
% else |
|
|
114 |
% Tzone = ECG(QRS_OFF(i):QRS_OFF(i)+lengthTzone-1); |
|
|
115 |
% end |
|
|
116 |
% [Tpks(end+1),Tind] = max(abs(Tzone)); |
|
|
117 |
% Tposition(end+1) = QRS_OFF(i)+Tind-1; |
|
|
118 |
% lengthPzone = int64((-QRS_OFF(i)+QRS_ON(i+1))/3); |
|
|
119 |
% Pzone = ECG(QRS_ON(i+1)-lengthPzone-1:QRS_ON(i+1)); |
|
|
120 |
% [Ppks(end+1),Pind] = max(Pzone); |
|
|
121 |
% Pposition(end+1) = QRS_ON(i+1)+Pind-lengthPzone; |
|
|
122 |
% end |
|
|
123 |
% end |
|
|
124 |
% for i = 1:length(Tpks) |
|
|
125 |
% if Tpks(i)>0 |
|
|
126 |
% display('T Upright'); |
|
|
127 |
% else |
|
|
128 |
% display('T Inverted'); |
|
|
129 |
% end |
|
|
130 |
% end |
|
|
131 |
% hold on;plot(Tposition,Tpks,'o'); |
|
|
132 |
% hold on;plot(Pposition,Ppks,'*'); |
|
|
133 |
%% |
|
|
134 |
% [pks,locs] = findpeaks(A5);hold on; plot(locs,pks,'*'); |
|
|
135 |
% |
|
|
136 |
% for i = 1:length(S) |
|
|
137 |
% SearchArea = []; |
|
|
138 |
% for j = 1:length(locs) |
|
|
139 |
% if locs(j) > S(i) |
|
|
140 |
% SearchArea(end+1) = locs(j); |
|
|
141 |
% end |
|
|
142 |
% end |
|
|
143 |
% su = []; |
|
|
144 |
% for k = 1:length(SearchArea) |
|
|
145 |
% su(end+1) = SearchArea(k)-S(i); |
|
|
146 |
% end |
|
|
147 |
% if ~isempty(su) |
|
|
148 |
% Tpks(end+1) = S(i) + min(su); |
|
|
149 |
% end |
|
|
150 |
% end |
|
|
151 |
% |
|
|
152 |
% % P detection |
|
|
153 |
% |
|
|
154 |
% |
|
|
155 |
% for i = 1:length(Q) |
|
|
156 |
% SearchArea = []; |
|
|
157 |
% for j = 1:length(locs) |
|
|
158 |
% if locs(j) < Q(i) |
|
|
159 |
% SearchArea(end+1) = locs(j); |
|
|
160 |
% end |
|
|
161 |
% end |
|
|
162 |
% su = []; |
|
|
163 |
% for k = 1:length(SearchArea) |
|
|
164 |
% su(end+1) = Q(i)-SearchArea(k); |
|
|
165 |
% end |
|
|
166 |
% if ~isempty(su) |
|
|
167 |
% Ppks(end+1) = Q(i) - min(su); |
|
|
168 |
% end |
|
|
169 |
% end |
|
|
170 |
% % check the result |
|
|
171 |
% for i = 1:length(Tpks) |
|
|
172 |
% T(i) = A5(Tpks(i)); |
|
|
173 |
% end |
|
|
174 |
% for i = 1:length(Ppks) |
|
|
175 |
% P(i) = A5(Ppks(i)); |
|
|
176 |
% end |
|
|
177 |
% figure(5);plot(A5); |
|
|
178 |
% hold on;plot(Tpks,T,'*'); |
|
|
179 |
% hold on;plot(Ppks,P,'+'); |
|
|
180 |
|
|
|
181 |
%% |
|
|
182 |
%Oops after interpolation, we slightly deviate from the true value |
|
|
183 |
%Thus we need to search for the local minimum in the whole signal again |
|
|
184 |
% Qposition = int64(Q.*Scale); |
|
|
185 |
% Sposition = int64(S.*Scale); |
|
|
186 |
% |
|
|
187 |
% for i = 1:length(R) |
|
|
188 |
% [Sv,Sp] = min(ECG(Sposition(i):Sposition(i)+20)); |
|
|
189 |
% Sposition(i) = Sp + Sposition(i)-1; |
|
|
190 |
% [Qv,Qp] = min(ECG(Qposition(i)-20:Qposition(i))); |
|
|
191 |
% Qposition(i) = Qposition(i)-21 + Qp; |
|
|
192 |
% end |
|
|
193 |
% |
|
|
194 |
% Pposition = int64(Ppks.*Scale); |
|
|
195 |
% Tposition = int64(Tpks.*Scale); |
|
|
196 |
% |
|
|
197 |
% for i = length(Pposition) |
|
|
198 |
% [Pv,Pp] = max(ECG(Pposition(i)-20:Pposition(i))); |
|
|
199 |
% Pposition(i) = Pposition(i)-21 + Pp; |
|
|
200 |
% end |
|
|
201 |
% |
|
|
202 |
% for i = length(Tposition) |
|
|
203 |
% [Tv,Tp] = max(ECG(Tposition(i):Tposition(i)+20)); |
|
|
204 |
% Tposition(i) = Tp + Tposition(i)-1; |
|
|
205 |
% end |
|
|
206 |
% ecgS = []; |
|
|
207 |
% for i = 1:2271 |
|
|
208 |
% ecgS(end+1) = issorted(ECGpeaks(1,:)); |
|
|
209 |
% end |
|
|
210 |
% prod(ecgS) |