function [TO, TS,nPVCs, TOsingle, TSsingle , avgTachogram,PVCidxs] = HRT_Analysis(RRInts,Labels,BeatsBefore, BeatsAfter, filtMethod, GraphOn) % [TO, TS, TOsingle, TSsingle,avgTachogram] = HRT_Analysis(RRInts,Labels,BeatsBefore, BeatsAfter, GraphOn) % OVERVIEW: % This function return TO and TS, i.e., the basic parameters of % heart rate turbulence (HRT) used to quantify the return to % equilibrium of heart rate after a premature ventricular % contraction (PVC). % TO is the Turbulence Onset, and it is defined as the percentage % difference between average value of the first two normal RR % following the PVC and the last two normal intervals preciding the % PVC % TS is the Turbulence Slope, and it is calculated by constructing an % average ectopy-centered time series and determining the steepest % slope each possible five consecutive normal intervals in the % post-PVC % % INPUTS: % RRInts : Vector containing RR intervals data (in seconds) % Labels : Vector containing annotations of the RR data at % each point indicating the type of the beat (see % https://www.physionet.org/physiobank/annotations.shtml) % BeatsBefore : number of RR intervals to consider before the PVC % (default 5) % BeatsBefore : number of RR intervals to consider after the PVC % (default 16) % filtMethod : (optional) select 'mean5before' to filter RR intervals % that change by more than 20% with respect to the % mean of the 5 last sinus intervals (the reference interval) % otherwise it will only filter intervals 15% shorter or % longer than the preceding interval % GraphOn : (optional) set GraphOn = 1 for a plot of the HRT analys % % OUTPUTS: % TO : average turbulence onset (TO) % TS : turbulence slop (TS) of the average tachogram % nPVCs : number of PVCs used to compute the average tachogram and average TO % TOsingle : a vector containing the turbulence onset (TO) of each PVC % TSsingle : a vector containing the turbulence slop (TS) of each PVC % avgTachogram : average PVC tachogram % PVCidxs : indexes of the PVCs used in the analysis (relative to the RR position) % % DEPENDENCIES & LIBRARIES: % PhysioNet Cardiovascular Signal Toolbox % https://github.com/cliffordlab/PhysioNet-Cardiovascular-Signal-Toolbox % % REFERENCE: % Vest et al. "An Open Source Benchmarked HRV Toolbox for Cardiovascular % Waveform and Interval Analysis" Physiological Measurement (In Press), 2018. % % REPO: % https://github.com/cliffordlab/PhysioNet-Cardiovascular-Signal-Toolbox % ORIGINAL SOURCE AND AUTHORS: % Giulia Da Poian % COPYRIGHT (C) 2018 % LICENSE: % This software is offered freely and without warranty under % the GNU (v3 or later) public license. See license file for % more information if nargin<2 error('') end if nargin<3 BeatsBefore = 5; end if nargin<4 BeatsAfter = 16; end if nargin<5 filtMethod = 'other'; end if nargin<6 GraphOn = 0; end % Convert to ms RRInts = RRInts *1000; % Find PVcs PVCs = find(Labels=='V'); % Only single ventricular beats are considered PVCs(diff(PVCs)<=BeatsAfter) = []; TO = NaN; TS = NaN; TOsingle = NaN; TSsingle = NaN; avgTachogram = nan(1,2+BeatsBefore+BeatsAfter); PVCidxs = NaN; nPVCs = 0; % Pre-process the original RR intervals to get tachograms time series from % which unphysiological beats and not Normal 'N' beats are remove, also % computes the average tachogram if isempty(PVCs) return; end [tachograms, avgTachogram,PVCidxs, nPVCs] = HRT_preprocessing(RRInts,Labels, PVCs, BeatsBefore, BeatsAfter,filtMethod); % Analyze tachograms and avgTachogram to get HRT values [TO, TS, TOsingle, TSsingle] = computeHRT(tachograms, avgTachogram,BeatsBefore); % Plots if GraphOn if isempty(avgTachogram) return; end PlotHRT(tachograms, avgTachogram, BeatsBefore,TO,TS) end end % end of Eval_HRT function function [CleanTachos, AvgTacho,out_idxs_pvcs,nPVCs] = HRT_preprocessing(RRInts,Labels, PVCs, BeatsBefore, BeatsAfter,filtMethod) % Function that performs a complete HRT preprocessing steps that includes: % 1. Find all VPC-tachograms (pre_pvc_beats+PVC+CP+post_pvc_beats) % 2. Filter all VPC-tachograms; i.e. find all the availables VPC-tachograms % to be used on the HRT analysis % REFERENCE: Clifford et al. 'Advanced Methods and Tools for ECG Data % Analysis' (pp. 89-92) % Initialize variables for: Tachos = []; % all possible tachograms TachoLabels = []; % and their labels CleanTachos = []; idxPVC = BeatsBefore+1; idxCP = idxPVC+1; % Mark all beats after a PVC as C (temporary variable) tmpLab = Labels; tmpLab(find(Labels == 'V')+1) = 'C'; tmpLab = tmpLab(1:length(Labels)); % Do not consider RR intervals < 300ms or > 2000ms, unless they are % PVCs RRInts( (RRInts<300 | RRInts>2000) & tmpLab~='V' & tmpLab~='C') = NaN; Labels( (RRInts<300 | RRInts>2000) & tmpLab~='V' & tmpLab~='C') = 'r'; % Mark all RR interval related to 'N' beats that change by more % than 20% with respect to the median of the five last sinus intervals % If a PVC tachogrm will have a NaN marked beat it will not be used idxN = find(tmpLab == 'N'); % use tmpLab to exclude also the CP if strcmp(filtMethod,'mean5before') B = 1/5*[1 1 1 1 1]; avgNN = filter(B,1,RRInts(idxN)); refNNinterval = avgNN(5:end-1); rri_avg = [nan(5,1);RRInts(idxN(6:end))./refNNinterval]; % nan(1,5) for alignment with RRInts indexes notUse = find(( rri_avg> 1.2) | (rri_avg< 0.8)); else tmpRR = RRInts(idxN); rri_rel = [NaN ; tmpRR(2:end)./tmpRR(1:end-1)]; notUse = find((rri_rel < 0.85)| (rri_rel > 1.15) ); end RRInts(idxN(notUse)) = NaN; % Guarantee last VPC position allows post_pvc_beats beats after it. if PVCs(end) +1 + BeatsAfter > length(RRInts) % +1 for the CP after the pvc PVCs(end) = []; end idxs_pvcs = []; for m = 1: length(PVCs) idxTachos = PVCs(m)-BeatsBefore : PVCs(m)+1+BeatsAfter; if idxTachos(end) >= length(RRInts) || idxTachos(1) <= 0 || idxTachos(2) <= 0 continue end Tachos = [Tachos RRInts(idxTachos)]; TachoLabels = [TachoLabels Labels(idxTachos)]; idxs_pvcs = [idxs_pvcs PVCs(m)]; end % Every possible tachogram is going to be "filtered" to determine % if it is a valid tachogram to be used in HRT analysis % Indices used to check condition (excluding the PVC and the one after the PVC) idxSinus = [1:BeatsBefore idxCP+1:idxCP+BeatsAfter]; out_idxs_pvcs = []; for idx = 1:size(Tachos,2) tmpTacho = Tachos(:,idx); tmpLabs = TachoLabels(:,idx); % compute all the conditions that a VPC tachogram must fulfill % All beats, except for VPC, must be 'N' if ~CheckForNormalBeats(tmpLabs, BeatsBefore) continue; end % Do not consider RR intervals where || RR(n-1) - RR(n)|| > 200ms if ~isempty(find(abs(diff(tmpTacho(1:BeatsBefore)))>=200,1)) || ... ~isempty(find(abs(diff(tmpTacho(BeatsBefore+3:end)))>=200,1)) continue; end % Remove tacho with RR intervals that change by more than 20% with % respect to the mean of the 5 last sinus intervals (the reference interval) % and also do not consider RR intervals < 300ms or > 2000ms % Look at RRInts mark as NaN (PVC and CP after PVC can be NaN) if isnan(sum(tmpTacho(idxSinus))) continue; end % Only use PVCs with a minimum prematurity of 20% if tmpTacho(BeatsBefore+1) >= 0.8*tmpTacho(BeatsBefore) continue; end % Exclude extrasystolic pause which is at least 20% longer than the normal interval if tmpTacho(BeatsBefore+2) <= 1.2*tmpTacho(BeatsBefore) continue; end CleanTachos = [CleanTachos tmpTacho]; out_idxs_pvcs = [out_idxs_pvcs idxs_pvcs(idx)]; end if isempty(CleanTachos) % there is no tachograms that fulfill all conditions AvgTacho = []; nPVCs = 0; else AvgTacho = mean(CleanTachos,2); nPVCs = length(out_idxs_pvcs); end end function validTach = CheckForNormalBeats(tachLab, rri_before) aux = tachLab([1:rri_before rri_before+2:end]); cond1 = tachLab(rri_before+1) == 'V'; OtherBeats = find(aux ~= 'N',1); if isempty(OtherBeats) && cond1 validTach = 1; else validTach = 0; end end function [TS, iTS, p]= TurbulenceSlope(Tach,BeatsBefore) % make sure Tach is an Nx1 vector if size(Tach,1)