ECG-Kit 1.0
(35,991 bytes)
function [position,timeqrs,lastqrs,intervalo,numlatdet,time,messages]= fiducialf(position,firstnewsamp,samp,heasig,w,eps,nlead,lastqrs,timeqrs,numlatdet,ultimo_anot,messages)
% [position,timeqrs,lastqrs,intervalo,numlatdet,time,messages]= fiducialf(position,firstnewsamp,samp,heasig,w,eps,nlead,lastqrs,timeqrs,numlatdet,messages)
%
% This script performs the QRS fiducial point detection of ECG
% In this version the thresholds eps(x) are not beat to beat actualized.
%
%Input Parameters:
% position: struct vector with the detected points
% firstnewsamp: last sample analyzed in the previous excerpt
% samp: samples included in the current excerpt (borders excluded)
% heasig: struct vector with header information
% w: matrix with WT scales 1 to 5
% eps: thresholds
% nlead: lead to be delineated
% lastqrs: last detecter QRS time (shoud be timeqrs(end))
% timeqrs: QRS times
% numlatdet: Number of detected beats until now
% ultimo_anot: last annotation in the previous segment
%Output Parameters:
% intervalo: numeration of the beats processed in this segment
% time: beats processed in this segment
% Actualized parameters: position,timeqrs,lastqrs,numlatdet,timeqrs
%
% Last update: Rute Almeida 07FEB2012
%
% Designed for MATLAB Version R12; tested with MATLAB Version R13
if nargin<12 || ~isfield(messages.setup,'wavedet')
messages.setup.wavedet=[];
end
if isfield(messages.setup.wavedet,'auxff') && messages.setup.wavedet.auxff==1
ff=1;
if isfield(messages.setup.wavedet,'aux_aa')
aa=messages.setup.wavedet.aux_aa;
else
aa=[1 1500];
end
else
ff=0;
end
if isempty(heasig)
end
if ff==1
figure
plot(w(:,1),'k')
fig1=gca;
set(gca,'xlim',aa)
hold on
ylabel('W_{2^1}')
figure
plot(messages.sig,'k')
fig2=gca;
hold on
set(gca,'xlim',aa)
ylabel('ECG')
figure
plot(w(:,3),'k')
fig3=gca;
set(gca,'xlim',aa)
hold on
ylabel('W_{2^3}')
figure
subplot(4,1,1)
plot(w(:,4),'k')
ylabel('W_{2^4}')
hold on
figWT4=gca;
set(gca,'xlim',aa)
subplot(4,1,2)
plot(w(:,3),'k')
ylabel('W_{2^3}')
hold on
figWT3=gca;
set(gca,'xlim',aa)
subplot(4,1,3)
plot(w(:,2),'k')
hold on
ylabel('W_{2^2}')
figWT2=gca;
set(gca,'xlim',aa)
subplot(4,1,4)
plot(w(:,1),'k')
hold on
ylabel('W_{2^1}')
figWT1=gca;
set(gca,'xlim',aa)
figure
subplot(4,1,1)
plot(messages.sig,'k')
ylabel('ECG')
hold on
% figECG=gca;
set(gca,'xlim',aa)
subplot(4,1,2)
plot(w(:,3),'k')
ylabel('W_{2^3}')
hold on
figECGWT3=gca;
set(gca,'xlim',aa)
subplot(4,1,3)
plot(w(:,2),'k')
hold on
ylabel('W_{2^2}')
figECGWT2=gca;
set(gca,'xlim',aa)
subplot(4,1,4)
plot(w(:,1),'k')
hold on
ylabel('W_{2^1}')
figECGWT1=gca;
set(gca,'xlim',aa)
end
if~isfield(messages.setup.wavedet,'firstmin')
messages.setup.wavedet.firstmin=0.050; % minimum time in sec to discart at the beggining
end
if ~isfield(messages.setup.wavedet,'nghbhd')
messages.setup.wavedet.nghbhd=0.025; % neighbourwood for maximum across scales in sec
end
if ~isfield(messages.setup.wavedet,'peakcriteria')
messages.setup.wavedet.peakcriteria=1.2; % If a modulus is more than peakcriteria times greater than others in the sane scale the greatest is chosen
end
if ~isfield(messages.setup.wavedet,'thmax')
messages.setup.wavedet.thmax=5+log(5); %maximum value for log(abs(W_3)) in a maximun line
end
if ~isfield(messages.setup.wavedet,'th_schb')
messages.setup.wavedet.th_schb=5+log(5); %maximum value for log(abs(W_3)) in a maximun line
end
if ~isfield(messages.setup.wavedet,'thfraction')
messages.setup.wavedet.thfraction=0.5; % tolerance below the average log(abs(W_3)) in a maximun line
end
if ~isfield(messages.setup.wavedet,'intvlthr2')
messages.setup.wavedet.intvlthr2=0.15;%threshold interval to consider isolated maximum lines
end
if ~isfield(messages.setup.wavedet,'intvlthr1')
messages.setup.wavedet.intvlthr1=0.12;%threshold interval for considering redundancy
end
if ~isfield(messages.setup.wavedet,'intvlthr1_2')
messages.setup.wavedet.intvlthr1_2=1.5;%reduction on threshold interval for considering redundancy if it subsists
end
if ~isfield(messages.setup.wavedet,'pictime')
messages.setup.wavedet.pictime=0.1;%length of the search window for associated maximumlines in extra verification step
end
if ~isfield(messages.setup.wavedet,'timelapthr')
messages.setup.wavedet.timelapthr=0.125;% maximum interval between two assiciated maximumlines in sec
end
if ~isfield(messages.setup.wavedet,'refrper')
messages.setup.wavedet.refrper=0.275;% Refractary period after a QRS detection in sec
end
if ~isfield(messages.setup.wavedet,'refrper_reduc')% 22NOV2011
messages.setup.wavedet.refrper_reduc=0;% 22NOV2011
end
if ~isfield(messages.setup.wavedet,'rrmaxmaxlim')
messages.setup.wavedet.rrmaxmaxlim=0.3; % search back criteria: searchback if RR>wavedet.rrmaxmaxlim sec
end
if ~isfield(messages.setup.wavedet,'rrmaxlim')
messages.setup.wavedet.rrmaxlim=1.5;% search back criteria: searchback if RR>wavedet.rrmaxlim * median(RR)
end
if ~isfield(messages.setup.wavedet,'rrmaxlimsec')
messages.setup.wavedet.rrmaxlimsec=1.5;% search back criteria: searchback if RR>wavedet.rrmaxlimsec
end
if ~isfield(messages.setup.wavedet,'rrmax_rbt')
messages.setup.wavedet.rrmax_rbt=0.1; % search back criteria only if >wavedet.rrmax_rbt sec o
end
if ~isfield(messages.setup.wavedet,'gapthrs')
messages.setup.wavedet.gapthrs=2; % fraction of mean(rr) to decide if there are a final "gap"
end
if ~isfield(messages.setup.wavedet,'pwaveout')
messages.setup.wavedet.pwaveout=0.2;% mimimum time in sec before each beat in order to ensure a complete beat
end
if ~isfield(messages.setup.wavedet,'twaveout')
messages.setup.wavedet.twaveout=0.45; % mimimum time in sec after each beat in order to ensure a complete beat
end
if ~isfield(messages.setup.wavedet,'refrperdef')
messages.setup.wavedet.refrperdef=messages.setup.wavedet.refrper;%
end
if messages.setup.wavedet.refrper_reduc>=1 % 22NOV2011
messages.setup.wavedet.refrper_reduc=0.9;% 22NOV2011
end
refrper=messages.setup.wavedet.refrper(end);
peakcriteria=messages.setup.wavedet.peakcriteria;
%global regularity
intervalo=[];
first = firstnewsamp-round(samp(1))+1;
first = max(ceil(messages.setup.wavedet.freq*messages.setup.wavedet.firstmin), first - ceil(1*messages.setup.wavedet.freq));
n = modmax(w(:,4),first,eps(4,nlead),0); % Maximum moduli at scale 4 % Rute 02.Dec.04
if ~isempty(n),
signo = sign(w(n,4))'; % Maximum or minimum?
neighb = ceil(messages.setup.wavedet.freq*messages.setup.wavedet.nghbhd); % Definition of neighborhood 25 ms.
%it makes sence to verify if all m(4,:) diffre at least neighb....
m = zeros(4,length(n));
m(4,:) = n'; % Positions of maximum moduli
for k = 1:size(m,2), % For each maximum at scale 4
n3 = modmax(w(max(1,n(k)-neighb):min(n(k)+neighb,size(w,1)),3),2,eps(3,nlead),signo(k));% Rute 02.Dec.04
n3 =n(k)-neighb-1+n3; % Check the neighborhood at scale 3
num = length(n3);
if num>0,
if num==1, % If only one neighbour maximum
m(3,k)= n3; % at scale 3
elseif num>1 % If more than one
if ~isempty(find(max(abs(w(n3,3))./(abs(w(n3,3)))<peakcriteria))==1),
% If a modulus is more than peakcriteria times greater than others
[aux1,ind]=max(abs(w(n3,3))); %#ok<ASGLU> % the greatest is chosen
m(3,k)= n3(ind);
else % Choose the one with minimum distance
[aux1,ind]=min(abs(m(4,k)-n3)); %#ok<ASGLU>
m(3,k)= n3(ind);
end
end
end
end
ind = find(m(3,:)==0); % Discard all maximum lines with no
if ff==1
axes(figWT4);
plot(figWT4,m(4,:),w(m(4,:),4),'ob')
plot(figWT4,[aa(1) aa(2)],[eps(4,nlead) eps(4,nlead)],':b')
plot(figWT4,[aa(1) aa(2)],-[eps(4,nlead) eps(4,nlead)],':b')
if ~isempty(ind)
plot(figWT4,m(4,ind),w(m(4,ind),4),'xr')
plot(figWT4,[m(4,ind(1))-neighb m(4,ind(1))-neighb],[-5000 5000],':r')
plot(figWT4,[m(4,ind(1))+neighb m(4,ind(1))+neighb],[-5000 5000],':r')
axes(figWT3);
plot(figWT3,[m(4,ind(1))-neighb m(4,ind(1))-neighb],[-5000 5000],':r')
plot(figWT3,[m(4,ind(1))+neighb m(3,ind(1))+neighb],[-5000 5000],':r')
end
plot(figWT3,m(3,m(3,:)~=0),w(m(3,m(3,:)~=0),3),'ob')
plot(figWT3,[aa(1) aa(2)],[eps(3,nlead) eps(3,nlead)],':b')
plot(figWT3,[aa(1) aa(2)],-[eps(3,nlead) eps(3,nlead)],':b')
end
m(:,ind) = []; % associated maximum at scale 3
signo(ind)= [];
% Search for maximum modula in the neighborhood at scale 2
for k = 1:size(m,2),
n2 =modmax(w(max(1,m(3,k)-neighb):min(m(3,k)+neighb,size(w,1)),2),2,eps(2,nlead),signo(k));% Rute 02.Dec.04
n2 =m(3,k)-neighb-1+n2;
num = length(n2);
if num>0,
if num==1, % If only one neighbour maximum
m(2,k)= n2; % at scale 2
elseif num>1 % If more than one
if ~isempty(find(max(abs(w(n2,2))./(abs(w(n2,2)))<peakcriteria))==1),
[aux1,ind]=max(abs(w(n2,2))); %#ok<ASGLU> % greatest modulus
m(2,k)= n2(ind);
else % shortest distance
[aux1,ind]=min(abs(m(3,k)-n2)); %#ok<ASGLU>
m(2,k)= n2(ind);
end
end
end
end
ind = find(m(2,:)==0); % Discard all maximum lines with no
if ff==1
% axes(figWT3);
if ~isempty(ind)
plot(figWT3,[m(3,ind(1))-neighb m(3,ind(1))-neighb],[-5000 5000],':r')
plot(figWT3,[m(3,ind(1))+neighb m(3,ind(1))+neighb],[-5000 5000],':r')
plot(figWT3,m(3,ind),w(m(3,ind),3),'xr')
axes(figWT2);
plot(figWT2,[m(3,ind(1))-neighb m(3,ind(1))-neighb],[-5000 5000],':r')
plot(figWT2,[m(3,ind(1))+neighb m(3,ind(1))+neighb],[-5000 5000],':r')
end
plot(figWT2,m(2,m(2,:)~=0),w(m(2,m(2,:)~=0),2),'ob')
plot(figWT2,[aa(1) aa(2)],[eps(2,nlead) eps(2,nlead)],':b')
plot(figWT2,[aa(1) aa(2)],-[eps(2,nlead) eps(2,nlead)],':b')
end
m(:,ind) = []; % associated maximum at scale 2
signo(ind)=[];
for k = 1:size(m,2),
n1 = modmax(w(max(1,m(2,k)-neighb):min(m(2,k)+neighb,size(w,1)),1),2,eps(1,nlead),signo(k)); % Rute 02.Dec.04
n1 =m(2,k)-neighb-1+n1;
n1 = n1(n1 > 0 & n1 <= size(w,1) );
num = length(n1);
if num>0,
if num==1, % If only one neighbour maximum
m(1,k)= n1; % at scale 1
elseif num>1 % If more than one
if ~isempty(find(max(abs(w(n1,1))./(abs(w(n1,1)))<peakcriteria))==1),
[aux1,ind]=max(abs(w(n1,1))); %#ok<ASGLU> % greatest modulus
m(1,k)= n1(ind);
else % shortest distance
[aux1,ind]=min(abs(m(2,k)-n1)); %#ok<ASGLU>
m(1,k)= n1(ind);
end
end
end
end
ind = find(m(1,:)==0); %Discard all maximum lines with no
if ff==1
% axes(figWT2);
if ~isempty(ind)
plot(figWT2,m(2,ind),w(m(2,ind),2),'xr')
end
plot(figWT1,m(1,m(1,:)~=0),w(m(1,m(1,:)~=0),1),'ob')
plot(figWT1,[aa(1) aa(2)],[eps(1,nlead) eps(1,nlead)],':b')
plot(figWT1,[aa(1) aa(2)],-[eps(1,nlead) eps(1,nlead)],':b')
end
m(:,ind) = []; % associated maximum at scale 1
signo(ind)=[];
%%% Regularity Exponent Validation %%%%%%%%%
% alpha is proportional to log(a3(nk3))-log(a1(nk1))
alpha = log(abs(w(m(3,:),3))); % !!!!
% alphalinha = log(abs(w(m(3,:),3))) - log (abs(w(m(1,:),1))); % !!! (1) % cometario na versao original%%%%%% Rute 24/04/02
%
% %%%% SO
% alpha1 = log(abs(w(m(2,:),2))./abs(w(m(1,:),1)));
% alpha2 = log(abs(w(m(3,:),3))./abs(w(m(2,:),2)));
% alpha3 = log(abs(w(m(4,:),4))./abs(w(m(3,:),3)));
% %%%% SO: you are right alpha=alpha1+alpha2 is calculated acording to (1)
% %%%% SO: por ahorro computacional se puede eliminar el log, y en el
% %%%% SO: valor del threshold si queremos.
%
% th was not being using at all in many cases, because thmax < min(alpha)
% th=min(messages.setup.wavedet.thmax,mean(alpha)-messages.setup.wavedet.thfraction);
th=mean(alpha)-messages.setup.wavedet.thfraction;
% thlinha=min(5+log(5),mean(alphalinha)-.5); %%%%%% Rute 24/04/02
ind = find(alpha<=th); % always empty?????!????1
% ind=find(alpha3>=1 || alpha1<=0.9 || alpha2<=0.9);% elimination of large T waves
if ff==1
plot(fig1,m(1,:),w(m(1,:)),'ob')
legend(fig1,{'WT_1','mm lines'},'Location','NorthEastOutside')
plot(m(1,ind),w(m(1,ind)),'xr')
if ~isempty(ind)
ll={'mm lines','rejected mm lines'};
else
ll={'mm lines'};
end
plot(figECGWT1,m(1,:),w(m(1,:),1),'ob')
plot(figECGWT1,m(1,ind),w(m(1,ind),1),'xr')
plot(figECGWT2,m(2,:),w(m(2,:),2),'ob')
plot(figECGWT2,m(2,ind),w(m(2,ind),2),'xr')
plot(figECGWT3,m(3,:),w(m(3,:),3),'ob')
plot(figECGWT3,m(3,ind),w(m(3,ind),3),'xr')
plot(fig3,m(3,:),w(m(3,:),3),'ob')
legend(fig3,{'WT_3','mm lines'},'Location','NorthEastOutside')
plot(m(3,ind),w(m(3,ind),3),'xr')
% axes(fig1);
legend(fig1,['WT_1',ll],'Location','NorthEastOutside')
% axes(fig3);
legend(fig3,['WT_3',ll],'Location','NorthEastOutside')
figure;
hs = subplot(3,1,1);
plot(hs,w(:,3),'k')
ylabel(hs,'W_{2^3}')
hold on
plot(hs,m(3,:),w(m(3,:),3),'ob')
plot(hs,m(3,ind),w(m(3,ind),3),'xr')
set(hs,'xlim',aa)
hs3 = subplot(3,1,3);
plot(hs3,messages.sig,'k')
hold on
set(hs3,'xlim',aa)
ylabel(hs3,'ECG')
set(hs3,'xlim',aa)
hs2 = subplot(3,1,2);
plot(hs2,m(3,:),alpha,'k')
hold on
plot(hs2,m(3,:),alpha,'ob')
plot(hs2,[0 261770],[mean(alpha)-messages.setup.wavedet.thfraction mean(alpha)-messages.setup.wavedet.thfraction],':g')
plot(hs2,[0 261770],[th th],':r'),
plot(hs2,m(3,ind),alpha(ind),'xr')
set(hs2,'xlim',aa)
ylabel(hs2,'\alpha')
%legend('alpha','alpha','mean alpha-thfraction','th','Location','NorthEastOutside')
end
if ~isempty(ind) % and high frequency noise peaks
m(:,ind) = [];
signo(ind)=[];
end
thresinterval = ceil(messages.setup.wavedet.intvlthr2* messages.setup.wavedet.freq);
% threshold interval to consider isolated maximum lines
ind = find( ((m(1,2:end-1)-m(1,1:end-2))>thresinterval) ...
& (m(1,3:end)- m(1,2:end-1))>thresinterval)+1;
if size(m,2)<2 && ~isempty(ind), ind=1; end % when only one maximum %16DEZ08
if ff==1
% axes(fig1);
plot(fig1,m(1,ind),w(m(1,ind)),'+r')
if ~isempty(ind)
ll=[ll {'isolated mm lines'}];
end
% axes(fig1);
legend(fig1,['WT_1',ll],'Location','NorthEastOutside')
% axes(fig3);
plot(fig3,m(3,ind),w(m(3,ind),3),'+r')
legend(['WT_3',ll],'Location','NorthEastOutside')
try
% axes(figECGWT1);
plot(figECGWT1,m(1,ind),w(m(1,ind),1),'+r')
plot(figECGWT1,[m(1,ind(1))-thresinterval m(1,ind(1))-thresinterval],[-5000 5000],':r')
plot(figECGWT1,[m(1,ind(1))+thresinterval m(1,ind(1))+thresinterval],[-5000 5000],':r')
% axes(figECGWT2);
plot(figECGWT2,m(2,ind),w(m(2,ind),2),'+r')
% axes(figECGWT3);
plot(figECGWT3,m(3,ind),w(m(3,ind),3),'+r')
catch me
me.message = 'Error plotting WT signal';
end
end
m(:,ind) = []; %Discard isolated maximum lines
signo(ind)=[];
% Threshold interval for considering redundancy
redundant= [];
thresinterval = ceil(messages.setup.wavedet.intvlthr1*messages.setup.wavedet.freq); % 120 ms. (li)
for l = find(signo>0), % For each positive maximum line
if ~any(redundant ==l), % If it has not been declared redundant yet
ind=find((m(3,:)>m(3,l)-messages.setup.wavedet.intvlthr1_2*thresinterval)&(m(3,:)<m(3,l)+messages.setup.wavedet.intvlthr1_2*thresinterval)&signo>0);
% index of positive lines near the present one (including it)
if length(ind)>1, % If more than one --> redundancy
[mx,ind2]= max(abs(w(m(3,ind),3))); %#ok<ASGLU>
ind(ind2)=[];
redundant = [redundant ind]; %#ok<AGROW> % All but the greatest are redundant
end
end
end
if ff==1
% axes(fig1);
plot(fig1,m(1,redundant),w(m(1,redundant)),'sm')
% axes(fig3);
plot(fig3,m(3,redundant),w(m(3,redundant),3),'sm')
if ~isempty(redundant)
ll=[ll {'redundant mm lines'}];
end
% axes(figECGWT1);
plot(figECGWT1,m(1,redundant),w(m(1,redundant)),'sm')
% axes(figECGWT2);
plot(figECGWT2,m(2,redundant),w(m(2,redundant),2),'sm')
% axes(figECGWT3);
plot(figECGWT3,m(3,redundant),w(m(3,redundant),3),'sm')
plot(figECGWT3,[m(3,206)-messages.setup.wavedet.intvlthr1_2*thresinterval m(3,206)-messages.setup.wavedet.intvlthr1_2*thresinterval],[-5000 5000],':r')
plot(figECGWT3,[m(3,206)+messages.setup.wavedet.intvlthr1_2*thresinterval m(3,206)+messages.setup.wavedet.intvlthr1_2*thresinterval],[-5000 5000],':r')
end
m(:,redundant)=[]; % Discard redundant lines
signo(redundant)=[];
redundant =[];
for l = find(signo>0), % For each remaining positive maximum line
ind=find((m(3,:)>m(3,l)-thresinterval)&(m(3,:)<m(3,l)+thresinterval)&signo<0);
% Search for negative minima near it
if length(ind)>1, % If more than one ---> redundancy
aux = abs(w(m(3,ind),3)./(m(3,ind)'-m(3,l)));
% auxiliary variable: height over distance
[mx,indmx]=max(aux);
ind2=ind;
aux(indmx)=[]; ind2(indmx)=[];
if all((mx./aux)>peakcriteria), % RULE 2 (see PFC or Li's paper)
redundant = [redundant ind2]; %#ok<AGROW>
else
[aux,aux2]=min(abs(m(3,l)-m(3,ind))); %#ok<ASGLU>
ind(aux2)=[]; % RULE 1 (see PFC or Li's paper)
redundant = [redundant ind]; %#ok<AGROW>
end
end
end
if ff==1
% axes(fig1);
plot(fig1,m(1,redundant),w(m(1,redundant)),'*r')
% axes(fig3);
plot(fig3,m(3,redundant),w(m(3,redundant),3),'*r')
if ~isempty(redundant)
ll=[ll {'redundant mm lines'}];
end
try
% axes(figECGWT1);
plot(figECGWT1,m(1,redundant(end)),w(m(1,redundant(end))),'sm')
% axes(figECGWT2);
plot(figECGWT2,m(2,redundant(end)),w(m(2,redundant(end)),2),'sm')
% axes(figECGWT3);
plot(figECGWT3,m(3,redundant(end)),w(m(3,redundant),3),'sm')
plot(figECGWT3,[m(3,182)-messages.setup.wavedet.intvlthr1_2*thresinterval m(3,182)-messages.setup.wavedet.intvlthr1_2*thresinterval],[-5000 5000],':r')
plot(figECGWT3,[m(3,182)+messages.setup.wavedet.intvlthr1_2*thresinterval m(3,182)+messages.setup.wavedet.intvlthr1_2*thresinterval],[-5000 5000],':r')
catch me
me.message = 'Error plotting WT signal';
end
end
m(:,redundant)=[]; % Discard redundant lines
signo(redundant)=[];
redundant =[];
for l = find(signo<0), % For each remaining negative minimum line
ind = find((m(3,:)>m(3,l)-thresinterval)&(m(3,:)<m(3,l)+thresinterval)&signo>0);
% Search for positive maxima near it
if length(ind)>1, % If more than one ----> redundancy
aux = abs(w(m(3,ind),3)./(m(3,ind)'-m(3,l)));
% auxiliary variable: height over distance
[mx,indmx]=max(aux);
ind2=ind;
aux(indmx)=[]; ind2(indmx)=[];
if all((mx./aux)>peakcriteria),
redundant = [redundant ind2]; %#ok<AGROW> % RULE 2
else
[aux,aux2]=min(abs(m(3,l)-m(3,ind))); %#ok<ASGLU>
ind(aux2)=[]; % RULE 1
redundant = [redundant ind]; %#ok<AGROW>
end
end
end
if ff==1
% axes(fig1);
plot(fig1,m(1,redundant),w(m(1,redundant)),'*r')
% axes(fig3);
plot(fig3,m(3,redundant),w(m(3,redundant),3),'*r')
if ~isempty(redundant)
ll=[ll {'redundant mm lines'}];
end
end
m(:,redundant)=[]; % Discard redundant lines
signo(redundant)=[];
%%%% isolated maximum lines resulting from Discarded redundant
ind = find( ((m(1,2:end-1)-m(1,1:end-2))>thresinterval) ...
& (m(1,3:end)- m(1,2:end-1))>thresinterval)+1;
if size(m,2)<2 && ~isempty(ind), ind=1; end % when only one maximum %16DEZ08
if ff==1
% axes(fig1);
legend(fig1,['WT_1',ll],'Location','NorthEastOutside')
% axes(fig3);
legend(fig3,['WT_3',ll],'Location','NorthEastOutside')
% axes(fig1);
plot(fig1,m(1,ind),w(m(1,ind)),'+m')
% axes(fig3);
plot(fig3,m(3,ind),w(m(3,ind),3),'+m')
if ~isempty(ind)
ll=[ll {'isolated mm lines'}];
end
% axes(fig1);
legend(fig1,['WT_1',ll],'Location','NorthEastOutside')
% axes(fig3);
legend(fig3,['WT_3',ll],'Location','NorthEastOutside')
end
m(:,ind) = []; %Discard isolated maximum lines
signo(ind)=[];
if size(m,2)<2
m=[];
signo=[];
end
eliminar=[];
%%%%extra protection% 23MAR09
% discard if no peak before and after messages.setup.wavedet.pictime ms
for ii=1:size(m,2)
pa = picant(w(max(1,m(2,ii)-round(messages.setup.wavedet.pictime*messages.setup.wavedet.freq)):m(2,ii),2),m(2,ii));
% first peak before detected qrs position at scale 2
pp = picpost(w(m(2,ii):min(size(w,1),m(2,ii)+round(messages.setup.wavedet.pictime*messages.setup.wavedet.freq)),2),m(2,ii));
%if isempty(pa) || isempty(pp)
if isempty(pa) && isempty(pp) %NOV2011
eliminar=[eliminar ii]; %#ok<AGROW>
end
end
if ff==1
% axes(fig1);
plot(fig1,m(1,eliminar),w(m(1,eliminar)),'.r')
% axes(fig3);
plot(fig3,m(3,eliminar),w(m(3,eliminar),3),'.r')
if ~isempty(eliminar)
ll=[ll {'extra protection'}];
end
% axes(fig1);
legend(fig1,['WT_1',ll],'Location','NorthEastOutside')
% axes(fig3);
legend(fig3,['WT_3',ll],'Location','NorthEastOutside')
end
m(:,eliminar)=[];
signo(eliminar)=[];
% QRS peak detection / wavelet Zero cross detection
timelap = ceil(messages.setup.wavedet.timelapthr*messages.setup.wavedet.freq); % the two maximum lines defining a QRS
% should not be separated more than timelapthr
time = [];
aux=[];
auxm=[];
if size(m,2)>1 % 18 OUT2011
for l = find(signo>0), % For each positive maximum line
if (l==1) % Special case: first line
if (signo(2)<0)&&(m(1,2)-m(1,1)<thresinterval),
ind = zerocros(w(m(1,l):min(m(1,l)+timelap,size(w,1)),1));
% Zero crossing at scale 1
time = [time ind+m(1,l)-1]; %#ok<AGROW>
aux=[aux abs(w(m(1,l))-w(m(1,l+1)))]; %#ok<AGROW>
auxm=[auxm; [m(1,l) m(1,l+1)]]; %#ok<AGROW>
end
elseif (l==size(m,2)) % Special case: last line
if (signo(l-1)<0)&&(m(1,end)-m(1,end-1)<thresinterval),
ind = zerocros(w(m(1,l-1):min(m(1,l-1)+timelap,size(w,1)),1));
time = [time ind+m(1,l-1)-1]; %#ok<AGROW>
aux=[aux abs(w(m(1,l-1))-w(m(1,l)))]; %#ok<AGROW>
auxm=[auxm ; [m(1,l-1) m(1,l)]]; %#ok<AGROW>
end
elseif signo(l+1)<0 && ((signo(l-1)>0) ...
|| ((m(1,l+1)-m(1,l))<(m(1,l)-m(1,l-1))))
ind = zerocros(w(m(1,l):min(m(1,l)+timelap,size(w,1)),1));
time = [time ind+m(1,l)-1]; %#ok<AGROW>
aux=[aux abs(w(m(1,l))-w(m(1,l+1)))]; %#ok<AGROW>
auxm=[auxm;[ m(1,l) m(1,l+1)]]; %#ok<AGROW>
elseif signo(l-1)<0,
ind = zerocros(w(m(1,l-1):min(m(1,l-1)+timelap,size(w,1)),1));
time = [time ind+m(1,l-1)-1]; %#ok<AGROW>
aux=[aux abs(w(m(1,l-1))-w(m(1,l)))]; %#ok<AGROW>
auxm=[auxm;[ m(1,l-1) m(1,l)]]; %#ok<AGROW>
end
end
end
if ff==1
plot(fig2,time,messages.sig(time),'ob')
ll_ECG={'ECG','QRS candidates'};
legend(fig2,ll_ECG,'Location','NorthEastOutside')
end
% Refractary period after a QRS detection. Retain only the waves with
% more energy within the refractary period.
if ~isempty(time),
rr = (time(2:end)-time(1:end-1));
ind = find(rr<ceil(refrper*messages.setup.wavedet.freq));
for auxi=1:length(ind) %RUTE 27Jun11
[M,ii]=min([aux(ind(auxi)) aux(ind(auxi)+1)]); %#ok<ASGLU> % 18JUL2011
if ii==2, ind(auxi)=ind(auxi)+1; end
end
% ind=ind+1; % olde version % always the second one is eliminated!!!
if ff==1
% axes(fig2);
plot(fig2,time(ind),messages.sig(time(ind)),'xr')
% axes(fig1);
plot(fig1,m(1,ind),w(m(1,ind)),'xr')
% axes(fig3);
plot(fig3,m(3,ind),w(m(3,ind),3),'xr')
if ~isempty(ind)
ll=[ll {'rejected by the refractary period'}];
ll_ECG=[ll_ECG {'rejected by the refractary period'}];
end
% axes(fig2);
legend(fig2,ll_ECG,'Location','NorthEastOutside')
% axes(fig1);
legend(fig1,['WT_1',ll],'Location','NorthEastOutside')
% axes(fig3);
legend(fig3,['WT_3',ll],'Location','NorthEastOutside')
end
time(ind)=[]; %RUTE 27Jun11
aux(ind)=[];
if abs(samp(time(1)) - lastqrs)< refrper*messages.setup.wavedet.freq, % Refractory period for
time(1)=[];
aux(1)=[];%#ok<NASGU> % last beat of previous
end % fragment
end
% search back if no detection in messages.setup.wavedet.rrmaxlim RR median
if ~isempty(time),
%%%%%%%%%%%%%%%% caso em que rr tem dimensao inferior ao necessario
if length(time)>1 %%%%%%%%%%%%%%%%introduzido a 17/05/02 Rute
rr = ([max(samp(time(1))-lastqrs,time(1)) time(2:end)-time(1:end-1)]); %rr = ([samp(time(1))-lastqrs, time(2:end)-time(1:end-1)]);
rrmed = [rr(1) 0.5*(rr(1)+rr(2)) median([rr(3:end);rr(2:end-1);rr(1:end-2)])];
ind = find((rr(2:end)>messages.setup.wavedet.rrmaxlim*rrmed(1:end-1)) & (rr(1:end-1)>messages.setup.wavedet.rrmaxmaxlim*messages.setup.wavedet.freq) | rr(2:end)>messages.setup.wavedet.rrmaxlimsec*messages.setup.wavedet.freq);
%%%% 22NOV2011
if messages.setup.wavedet.refrper_reduc>0 && refrper>0.250 % 22NOV2011
while sum(rrmed<refrper*messages.setup.wavedet.freq*4/3)/length(rrmed)>0.6
refrper=refrper*messages.setup.wavedet.refrper_reduc;
end % 22NOV2011
if messages.setup.wavedet.refrper(end)~=refrper
messages.setup.wavedet.refrper(end+1)=refrper;
messages.setup.wavedet.refrperdef(end+1)=samp(time(1));
end
end
if ff==1
if ~isempty(ind)
ll=[ll {'searchback'}];
ll_ECG=[ll_ECG {'searchback'}];
% axes(fig2);
plot(fig2,time(ind),messages.sig(time(ind))+50,'vc')
legend(ll_ECG,'Location','NorthEastOutside')
% axes(fig1);
plot(fig1,time(ind),w(time(ind),1)+200,'vc')
% axes(fig3);
plot(fig3,time(ind),w(time(ind),3)+200,'vc')
% axes(fig1);
legend(fig1,'WT_1',ll,'Location','NorthEastOutside')
% axes(fig3);
legend(fig3,'WT_3',ll,'Location','NorthEastOutside')
end
end
for l = ind, % For all rr intervals greater than 1.5RR
interv = (time(l)+ceil(refrper*messages.setup.wavedet.freq)) : (time(l+1)-ceil(refrper*messages.setup.wavedet.freq));
if length(interv)>messages.setup.wavedet.rrmax_rbt*messages.setup.wavedet.freq, % for robustness
% [nuevo, messages] = searchbk(w(interv,:),interv(1),eps(:,nlead)',messages.setup.wavedet.freq,messages.setup.wavedet.th_schb,messages);
[nuevo, messages] = searchbk(w(interv,:),interv(1),eps(:,nlead)',messages.setup.wavedet.freq,th,messages); %FEB16_2012
% searchbk returns the new time of occurrence of a QRS
time = [time nuevo]; %#ok<AGROW> % New times are added
% time = sort(time); % and sorted
if ff==1
% axes(fig2);
plot(fig2,nuevo,messages.sig(nuevo),'oc')
if ~isempty(nuevo)
ll_ECG=[ll_ECG {'new candidates by searchback'}]; %#ok<AGROW>
end
legend(fig2,ll_ECG,'Location','NorthEastOutside')
end
end
end %%%%%%%%%%%%%%%%introduzido a 17/05/02 Rute
else % only one detection DEZ2011
if time > max(messages.setup.wavedet.gapthrs,ceil(refrper*messages.setup.wavedet.freq))%initial gap % 24ABRIL2010
% if time > messages.setup.wavedet.gapthrs %initial gap
if (~exist('th','var') || isnan(th)), th = messages.setup.wavedet.thmax ; end
[nuevo, messages]= searchbk(w(1:(time-ceil(refrper*messages.setup.wavedet.freq))),1,eps(:,nlead)',messages.setup.wavedet.freq,th,messages);
time = [time nuevo];
end
end
else % in case there is no detection, searchback anyway
if (~exist('th','var') || isnan(th)), th = messages.setup.wavedet.thmax ; end
%nuevo = searchbk(w,1,eps,messages.setup.wavedet.freq, messages.setup.wavedet.th_schb); %Rute 02.Dec.04
[nuevo, messages]= searchbk(w,1,eps(:,nlead)',messages.setup.wavedet.freq, th,messages);
time = nuevo;
if ff==1
% axes(fig2);
plot(fig2,nuevo,messages.sig(nuevo),'oc')
if ~isempty(nuevo)
ll_ECG=[ll_ECG {'new candidates by searchback'}];
end
legend(fig2,ll_ECG,'Location','NorthEastOutside')
end
end
if ~isempty(time),
time = sort(time); % Rute 14DEz
if length(time)>1
rr = ([samp(time(1))-lastqrs, time(2:end)-time(1:end-1)]);
rrmed = [rr(1) 0.5*(rr(1)+rr(2)) median([rr(3:end);rr(2:end-1);rr(1:end-2)])]; %RUTE OUT2011
else
rrmed =1;
end
if length(w)-time(end) > messages.setup.wavedet.gapthrs*rrmed, % If there is a final "gap"
interv= (time(end)+ceil(refrper*messages.setup.wavedet.freq) : length(w)); %RUTE OUT2011
if length(interv)>messages.setup.wavedet.rrmax_rbt*messages.setup.wavedet.freq,
[nuevo, messages] = searchbk(w(interv,:),interv(1),eps(:,nlead)',messages.setup.wavedet.freq, th,messages);
time = [time nuevo];
if ff==1
% axes(fig2);
plot(fig2,nuevo,messages.sig(nuevo),'oc')
if ~isempty(nuevo)
ll_ECG=[ll_ECG {'new candidates by searchback'}];
end
legend(fig2,ll_ECG,'Location','NorthEastOutside')
end
end
end
%%% The first and last beats must be complete, to detect P-wave and T-wave %%%
%%% We use an overlap that assures that the beat will be complete always in
%%% one of the segments.
if (time(1) <= messages.setup.wavedet.pwaveout*messages.setup.wavedet.freq),
time(1)=[];
end
% If the P-wave is not in the present segment, discard the beat, because the
% the beat should have been detected in the last segment.
if ~isempty(lastqrs)
time(samp(time)<= lastqrs + refrper*messages.setup.wavedet.freq)=[];
end
if ~isempty(time) %%%%%%% Rute 06/05/02 caso time(indrep)=time
% if beat before ultimo_anot in the previous segment %6AGO2007
if samp(time(1))<=ultimo_anot
time(1)=[];
end
if ~isempty(time) && (length(w)-time(end) < messages.setup.wavedet.twaveout*messages.setup.wavedet.freq), % si no ye a onda T drento
time(end)=[]; % de sig
end
% If last beat's T-wave is not in 'sig', the beat is detected in next one
if ~isempty(time) %Rute 10.04.05
timeqrs = [timeqrs samp(time)]; % QRS times
lastqrs = samp(time(end));
end
end
intervalo = [numlatdet+1 numlatdet+length(time)];
% numeration of the beats processed in this segment
numlatdet = intervalo(2);
position.qrs(intervalo(1):intervalo(2)) = samp(time); % Fill QRS position
end
if ff==1
% axes(fig2);
plot(fig2,time,messages.sig(time),'.g')
ll_ECG=[ll_ECG {'final SL marks'}];
legend(fig2,ll_ECG,'Location','NorthEastOutside')
% axes(fig1);
legend(fig1,['WT_1',ll],'Location','NorthEastOutside')
% axes(fig3);
legend(fig3,['WT_3',ll],'Location','NorthEastOutside')
end
else
intervalo=[];time=[]; %Rute 13Set06
end