function windows_output = FindLowestHRwin(t_win, t, rr, num_segs, HRVparams) % % windows_output = FindLowestHRwin(t_win, t, rr, num_segs, HRVparams) % % OVERVIEW % Given time series data, calculate and return median HR within window % satisfying condition (e.g. lowest or highest median HR) % % INPUT % t_win - % t - time stamps for 'hr'; in units of seconds % rr - input time series of RR intervals from QRS file % num_segs - number of windows to find; % i.e. if this == 3 and 'condition' == 'lowest', then return % windows with three lowest median HR in order of % lowest to highest % HRVparams - struct of settings for hrv_toolbox analysis % % OUTPUT % windows_output.t - vector of start times for windows % windows_output.hr - vector of median HR values for windows % REPO: % https://github.com/cliffordlab/PhysioNet-Cardiovascular-Signal-Toolbox % AUTHORS % Erik Reinertsen % (Adapted for use in HRV Toolbox) % 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. % Convert RR intervals into HR hr = 60 ./ rr; % Set value of increment window (sec) increment = HRVparams.increment; windowlength = HRVparams.windowlength; % Initialize struct to hold t and hr of each window windows = []; % Initialize start time t_window_start = 0; % Initialize index counter for storing results ii = 1; % Loop through time series until we reach the end % NOTE: vectorizing is non-trivial because the data is not evenly % sampled. Otherwise I'd just stagger the matrix and calculate % medians down each column containing each window of data. while t_window_start <= t(end) - windowlength + increment % Find indices of HR values in this window idx_window = find(t > t_window_start & t < t_window_start + windowlength); % Store the time windows(ii).t = t_window_start; % Calculate the median of these HR values windows(ii).hr = median(hr(idx_window)); % Increment time by sliding window length (sec) t_window_start = t_window_start + increment; % Increment struct index ii = ii + 1; end % Find indices for top non-overlapping windows that meet conditions [~, idx_sorted] = sort([windows.hr]'); % Remove indexes where the data is disqualified from analysis, ie t_win = % NaN idxN = find(isnan(t_win)); idx_sorted(idxN) = []; % The first non-NaN sorted index is the window with the lowest median HR, % so we definitely return that one, as long as it's corresponding t_win is % not a NaN value windows_output(1).t = []; while isempty(windows_output(1).t) windows_output(1).t = windows(idx_sorted(1)).t; windows_output(1).hr = windows(idx_sorted(1)).hr; % Erase the first entry from 'idx_sorted' idx_sorted(1) = []; end % Until we've found all of the lowest median HR windows, % go to the next ordered window, check if overlaps with any other % windows; if not, add. If yes, erase it. while length(windows_output) < num_segs % Check dt between all best windows and the next sorted window dt = [windows_output.t] - windows(idx_sorted(1)).t; % Check if any dt's are less than the window length; % any that are suggests new window overlaps with a best window bool_overlaps = abs(dt) < windowlength; % If all bools are zero, the candidate window doesn't overlap if sum(bool_overlaps) == 0 % Append t and hr windows_output(end + 1).t = windows(idx_sorted(1)).t; windows_output(end).hr = windows(idx_sorted(1)).hr; % note 'end' is +1 compared to the line before end % If there exist any bools == 1, the candidate window does % overlap, so don't append t and hr % Erase candidate window from 'idx_sorted' idx_sorted(1) = []; end end % end function