PhysioNet Cardiovascular Signal Toolbox 1.0.0
(7,467 bytes)
function [ac_results, dc_results, prsa_ac, prsa_dc] = prsa(rr, rri, HRVparams, sqi, WinStarIdxs)
% [ac_results, dc_results] = prsa(rr, rri, sqi, windows_all, HRVparams )
%
% OVERVIEW:
% Calculates acceleration and deceleration capacity values
% INPUT
% rr - rr intervals
% rri - index of rr intervals
% HRVparams - struct of settings for hrv_toolbox analysis
% sqi - Signal Quality Index; Requires a matrix with
% at least two columns. Column 1 should be
% timestamps of each sqi measure, and Column 2
% should be SQI on a scale from 0 to 1.
% WinStarIdxs - Starting index of each windows to analyze
%
% OUTPUT
% ac_results - Acceleration Capacity value
% dc_results - Deceleration Capacity value
% prsa_ac - PRSA signal for AC anchor points
% prsa_dc - PRSA signal for DC anchor points
%
% AUTHORS
% L. Campana
% G. Clifford
% REFERENCE
% http://adsabs.harvard.edu/abs/2007Chaos..17a5112K
% http://h-r-t.org/prsa/en/
% REPO:
% https://github.com/cliffordlab/PhysioNet-Cardiovascular-Signal-Toolbox
% DEPENDENCIES & LIBRARIES
% COPYRIGHT (C) 2016 AUTHORS (see above)
% This code (and all others in this repository) are under the GNU General Public License v3
% See LICENSE in this repo for details.
% Feb 13, 2017
% Code altered by Adriana N Vest for the HRV Toolbox. Most of code
% unchanged except for HRVparams and Initializations Section and the
% inclusion of windowing options.
% Oct 13, 2017
% Code altered by Giulia Da Poian to compute AC and DC value at different
% scale s
%
% These default parameters were a part of the original PRSA code developed
% by the authors above.
% tp = 20; thresh_per
% wl = 30; prsa_win_length
% fsd = 512; fs
%%
% Make vector a column
rr = rr(:);
if nargin < 5
error('no data provided')
end
if isempty(sqi)
sqi(:,1) = rri;
sqi(:,2) = ones(length(rri),1);
end
time_stamp = rri;
prsaWinLength = HRVparams.prsa.win_length;
s = HRVparams.prsa.scale;
PRSA_th = HRVparams.prsa.thresh_per;
plot_results = HRVparams.prsa.plot_results;
windowlength = HRVparams.windowlength;
SQI_th = HRVparams.sqi.LowQualityThreshold; % SQI threshold
WinQuality_th = HRVparams.RejectionThreshold; % Low quality windows threshold
Anchor_Low_th = 1-PRSA_th/100-.0001; % The lower limit for the AC anchor selection
Anchor_High_th = 1+PRSA_th/100; % The upper limit for the DC anchor selection
% Preallocation
ac_results = nan(length(WinStarIdxs),1);
dc_results = nan(length(WinStarIdxs),1);
prsa_ac = [];
prsa_dc = [];
% Run PRSA by Window
% Loop through each window of RR data
for i_win = 1:length(WinStarIdxs)
% Check window for sufficient data
if isnan(WinStarIdxs(i_win))
end
if ~isnan(WinStarIdxs(i_win))
% Isolate data in this window
% idx_NN_in_win = find(rri >= windows_all(i_win) & rri < windows_all(i_win) + windowlength);
% idx_sqi_win = find(sqi(:,1) >= windows_all(i_win) & sqi(:,1) < windows_all(i_win) + windowlength);
sqi_win = sqi( sqi(:,1) >= WinStarIdxs(i_win) & sqi(:,1) < WinStarIdxs(i_win) + windowlength,:);
nn_win = rr( rri >= WinStarIdxs(i_win) & rri < WinStarIdxs(i_win) + windowlength );
% Analysis of SQI for the window
lowqual_idx = find(sqi_win(:,2) < SQI_th);
% If enough data has an adequate SQI, perform the calculations
if numel(lowqual_idx)/length(sqi_win(:,2)) < WinQuality_th
% intialize
acm = [];
dcm = [];
drr_per = nn_win(2:end)./nn_win(1:end-1);
ac_anchor = (drr_per > Anchor_Low_th) & (drr_per <= .9999); % defines ac anchors, no changes greater then 5%
dc_anchor = (drr_per > 1) & (drr_per <= Anchor_High_th);
ac_anchor = [0; ac_anchor(:)];
dc_anchor = [0; dc_anchor(:)];
ac_anchor(1:prsaWinLength) = 0; % sets first window to 0
ac_anchor(length(ac_anchor)-prsaWinLength+1:length(ac_anchor)) = 0; % sets last window to 0
dc_anchor(1:prsaWinLength) = 0; % sets first window to 0
dc_anchor(length(dc_anchor)-prsaWinLength+1:length(dc_anchor)) = 0; % sets last window to 0
ac_ind = find(ac_anchor);
dc_ind = find(dc_anchor);
for i = 1:length(dc_ind)
dcm(i,:) = 1000*nn_win(dc_ind(i)-prsaWinLength:dc_ind(i)+prsaWinLength-1); % convert from sec to msec
end
for i = 1:length(ac_ind)
acm(i,:) = 1000*nn_win(ac_ind(i)-prsaWinLength:ac_ind(i)+prsaWinLength-1); % convert from sec to msec
end
prsa_ac = mean(acm);
prsa_dc = mean(dcm);
% Edited by Adriana Vest: Added the following if statements to
% deal with scenarios when ac or dc is not computable for a
% particular window. An example scenario is when the RR
% intervals are flat.
if ~isnan(prsa_dc) % Edited by Giulia Da Poian
dc = (sum(prsa_dc(prsaWinLength+1:prsaWinLength+s)) - sum(prsa_dc(prsaWinLength-(s-1):prsaWinLength))) ./ (2*s);
dc_results(i_win,1) = dc; % assign output of window
end
if ~isnan(prsa_ac) % Edited by Giulia Da Poian
ac = (sum(prsa_ac(prsaWinLength+1:prsaWinLength+s)) - sum(prsa_ac(prsaWinLength-(s-1):prsaWinLength))) ./ (2*s);
ac_results(i_win,1) = ac; % assign output of window
end
% Load custom colors
custom_colors.red = [72 11 11] / 100;
custom_colors.green = [30 69 31] / 100;
% Plot results
if plot_results == 1
figure(1);
plot(time_stamp,nn_win,'k+');
hold on;
figure(2)
subplot(2,1,2)
plot(dcm,'k--');
legend('Deceleration');
hold on;
figure(2)
subplot(2,1,1)
plot(acm,'k--');
legend('Acceleration');
hold on;
figure(3)
plot(time_stamp,nn_win,'k-+');
hold on;
plot(time_stamp(ac_ind),nn_win(ac_ind), 'color', custom_colors.green, 'marker', '+');
plot(time_stamp(dc_ind),nn_win(dc_ind), 'color', custom_colors.red, 'marker', '+');
legend('non-anchor','ac anchor','dc anchor');
title('RR anchors');
figure(4);
subplot(2,1,1)
plot([-2:2*prsaWinLength-2],dcm,'k--')
title('dc matrix')
hold on
plot([-2:2*prsaWinLength-2],prsa_dc,'r');
subplot(2,1,2)
plot([-2:2*prsaWinLength-2],acm,'k--')
hold on
plot([-2:2*prsaWinLength-2],prsa_ac,'r');
title('ac matrix')
end % end of plotting condition
else % else, if SQI is not adequate
end % end of conditional statements run when SQI is adequate
else % else, if window is NaN
end % end of check for sufficient data
end % end of loop through windows
end % end of function