Noninvasive Fetal ECG: The PhysioNet/Computing in Cardiology Challenge 2013 1.0.0
(3,775 bytes)
function [fetal_QRSAnn_est,QT_Interval,best_index] = physionet2013(tm,ECG)
% Template algorithm for Physionet/CinC competition 2013. This function can
% be used for events 1 and 2. Participants are free to modify any
% components of the code. However the function prototype must stay the
% same:
%
% [fetal_QRSAnn_est,QT_Interval] = physionet2013(tm,ECG) where the inputs and outputs are specified
% below.
%
% inputs:
% ECG: 4x60000 (4 channels and 1min of signal at 1000Hz) matrix of
% abdominal ECG channels.
% tm : Nx1 vector of time in milliseconds
% output:
% FQRS: FQRS markers in seconds. Each marker indicates the position of one
% of the FQRS detected by the algorithm.
% QT_Interval: 1x1 estimated fetal QT duration (enter NaN or 0 if you do wish to calculate)
%
%
% Author: Joachim Behar - IPMG Oxford (joachim.behar@eng.ox.ac.uk)
% Last updated: March 3, 2013 Ikaro Silva
warning off;
% ---- code constants and parameters----
fs = 1000; % sampling frequency
blocksize = 2000;
sample = load('samplewaves.mat');
% ---- preprocessing and maternal peak detection----
[nleads,nsamples]=size(ECG);
if nleads>nsamples % make sure ECG is a row matrix
ECG = ECG';
[nleads,nsamples]=size(ECG);
end
I=MissedValCheck(ECG);
Y=preprocessing(I,fs,0.05); % filtered ECG
[Y,accY,peaks,goodint] = MECGPeakDetect(Y,blocksize,sample.m,fs);
ind1=find(peaks==1);
if length(ind1)<20 || median(abs(accY(ind1)))<=50
Y=preprocessing(I,fs,0.2);
[Y,accY,peaks,goodint] = MECGPeakDetect(Y,blocksize,sample.m,fs);
end
%----- finding principal componenets-----
[pcM, Ucomp] = findPrinComp(Y,blocksize);
% ---- MECG cancellation ----
L=1;
mcount=1;
[Mout,Fout,corrcoef]=FECG_extract_multichan(Y,fs,peaks,L);
while (max(corrcoef)>=0.2 && mcount<4)
[Mout,Fout,corrcoef]=FECG_extract_multichan(Fout,fs,peaks,L);
mcount=mcount+1;
end
% ---- Post processing and channel selection ----
[FECG,post_order] = postFilterSelect(Fout,blocksize);
% ---- FQRS detection ----
avg_power=median(abs(FECG'))';
FECG_norm=FECG./repmat(avg_power,1,nsamples);
[factorcheat,best_choice]=SigMerge(FECG_norm,sample.f,goodint,fs);
if any(factorcheat)
[fpr1,Ftest_round1,fsample,findnc1,findc1]=Fetal_Peakdetection2(FECG_norm,sample.f,fs,factorcheat,0);
if sum(sample.f.*fsample)<0
[fpr1,Ftest_round1,fsample,findnc1,findc1]=Fetal_Peakdetection2(FECG_norm,sample.f,fs,-factorcheat,0);
end
else
findc1=0;
fsample=zeros(size(sample.f));
end
% comparing the detected peaks with those detected from principal
% components
best_index = 1;
if (length(findc1)<85)
fkurt=zeros(1,3);
fkurt(1)=3; % this is to avoid canceling fpr1 in the competition at this level.
p_order = SetSelect(pcM(1:3,:),fs);
[Ftest,fpr2,findc2,psample2] = PCMPeakDetect(pcM(p_order(1),:),peaks,sample.f,goodint,fs,blocksize);
fkurt(2) = kurtosis(psample2);
u_order = SetSelect(Ucomp,fs);
% [Ftest,fpr3,findc3,psample3] = PCMPeakDetect(Ucomp(u_order(1),:),peaks,sample.f,goodint,fs,blocksize);
% fkurt(3) = kurtosis(psample3);
[Ftest,fpr3,findc3,psample3] = PCMPeakDetect(Ucomp(u_order(2),:),peaks,sample.f,goodint,fs,blocksize);
fkurt(3) = kurtosis(psample3);
ll=[length(findc1) length(findc2) length(findc3)];
% selecting the best answer
[fkurt_max, best_index] = max(ll.*(ll<140).*(fkurt>2.8));
end
switch best_index
case 1
fpr=fpr1;
findc=findc1;
case 2
fpr=fpr2;
findc=findc2;
case 3
fpr=fpr3;
findc=findc3;
end
fetal_QRSAnn_est = fpr-1;
QT_Interval = 0;
end