0001 function [ result ] = hrvDetect( params )
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 ensembleFilterWindowSize = 200;
0023 smoothingSplinesCoefficient = 0.5;
0024
0025
0026 [ sig, fs ] = loadFromFile( params.ecgFile );
0027
0028
0029 [ sig, detrended ] = preprocessingNew(sig, fs);
0030
0031
0032 [ R_locs ] = kota(sig, detrended, fs);
0033
0034 if(params.postProcessing.ensembleFilter.isOn == 1)
0035 errors = ensembleNonCorrelatedDetector( detrended, R_locs, params.postProcessing.ensembleFilter.threshold, ensembleFilterWindowSize );
0036 else
0037 errors = zeros(1,length(R_locs));
0038 end
0039
0040
0041
0042 interval = diff(R_locs);
0043 noisy = zeros(1,length(interval));
0044 for i = 1:length(R_locs)-1
0045
0046 if(errors(i) == 1)
0047 if(i > 1)
0048 noisy(i-1) = 1;
0049 noisy(i) = 1;
0050 else
0051 noisy(i) = 1;
0052 end
0053 end
0054 end
0055
0056
0057
0058 if(params.postProcessing.missedBeats.isOn == 1)
0059 missedBeatErrors = missedBeatDetector( interval, params.postProcessing.missedBeats.threshold );
0060 else
0061 missedBeatErrors = zeros(1, length(interval));
0062 end
0063
0064
0065 if(params.postProcessing.madFilter.isOn == 1)
0066 outliers = medFilter( interval, params.postProcessing.madFilter.threshold );
0067 else
0068 outliers = zeros(1, length(interval));
0069 end
0070
0071 totalNoisyIntervals = noisy | missedBeatErrors | outliers;
0072
0073 noisyIntervals = logical(totalNoisyIntervals);
0074
0075 BPM = 60*fs./(interval);
0076 intervalLocs = R_locs(1:end-1);
0077 time = 0:(1/fs):((length(detrended)-1)/fs);
0078 switch (params.tachoProcessing.interpolationMethod)
0079 case 'spline'
0080 [f,gof,~] = fit(transpose(time(intervalLocs(~noisyIntervals))),transpose(BPM(~noisyIntervals)),'smoothingspline','SmoothingParam',smoothingSplinesCoefficient);
0081 smoothSignal = f(time(intervalLocs(~noisyIntervals)));
0082 r_squarred = gof.rsquare;
0083 case 'direct'
0084 smoothSignal = BPM(~noisyIntervals);
0085 r_squarred = 0;
0086 end
0087 if(params.tachoProcessing.medianFilter.isOn == 1)
0088 smoothSignal = medfilt1(smoothSignal,params.tachoProcessing.medianFilter.windowSize);
0089 end
0090
0091 percentNoisy = sum(noisyIntervals) / ( length(R_locs)-1 ) * 100;
0092 switch (params.tachoProcessing.interpolationMethod)
0093 case 'spline'
0094 [f,~,~] = fit(transpose(time(intervalLocs(~noisyIntervals))),transpose(smoothSignal),'smoothingspline','SmoothingParam',smoothingSplinesCoefficient);
0095 heartRate = f(time);
0096 case 'direct'
0097 heartRate = interp1(transpose(time(intervalLocs(~noisyIntervals))),transpose(smoothSignal),time,'direct');
0098 r_squarred = 0;
0099 end
0100
0101 result = {};
0102 result.fs = fs;
0103 result.tachogram = smoothSignal;
0104 result.R_locs = intervalLocs(~noisyIntervals);
0105 result.heartRate = heartRate;
0106 result.noisyIntervals = intervalLocs(noisyIntervals);
0107 result.interpolatedFlag = [0];
0108 result.evaluation = struct('totalNumBeats', length(R_locs),'percentInvalid', percentNoisy,'splineRSquare', r_squarred, 'numRemovedEnsemble', sum(noisy), 'numRemovedMAD', sum(outliers), 'missedBeatsNum', missedBeatsErrors);
0109
0110 end
0111