analysis¶
Functions that handle computation of heart rate (HR) and heart rate variability (HRV) measures.

heartpy.analysis.
calc_rr
(peaklist, sample_rate, working_data={})[source]¶ calculates peakpeak intervals
Function that calculates the peakpeak data required for further analysis. Stores results in the working_data{} dict.
Parameters:  peaklist (1d list or array) – list or array containing detected peak positions
 sample_rate (int or float) – the sample rate with which the heart rate signal is collected
 working_data (dict) – dictionary object that contains all heartpy’s working data (temp) objects. will be created if not passed to function
Returns: working_data – working_data dictionary object containing all of heartpy’s temp objects
Return type: dict
Examples
Let’s assume we detected peaks at these positions in the signal:
>>> peaklist = [200, 280, 405, 501, 615]
It is then easy to call calc_rr to compute what we need:
>>> wd = calc_rr(peaklist, sample_rate = 100.0) >>> wd['RR_list'] array([ 800., 1250., 960., 1140.]) >>> wd['RR_diff'] array([450., 290., 180.]) >>> wd['RR_sqdiff'] array([202500., 84100., 32400.])
Note that the list of peakpeak intervals is of length len(peaks)  1 the length of the differences is of length len(peaks)  2

heartpy.analysis.
update_rr
(working_data={})[source]¶ updates differences between adjacent peakpeak distances
Function that updates RR differences and RR squared differences based on corrected RR list
Parameters: working_data (dict) – dictionary object that contains all heartpy’s working data (temp) objects will be created if not passed to function Returns: out – working_data dictionary object containing all of heartpy’s temp objects Return type: dict Examples
Let’s assume we detected peaks at these positions in the signal:
>>> peaklist = [200, 280, 405, 410, 501, 615]
And we subsequently ran further analysis:
>>> wd = calc_rr(peaklist, sample_rate = 100.0)
The peak at position 410 is likely an incorrect detection and will be marked as such by other heartpy functions. This is indicated by an array ‘binary_peaklist’ in working_data. Binary peaklist is of the same length as peaklist, and is formatted as a mask:
For now let’s set it manually, normally this is done by the check_peaks() function from HeartPy’s peakdetection module.
>>> wd['binary_peaklist'] = [1, 1, 1, 0, 1, 1]
Rejected peaks are marked with a zero and accepted with a 1.
By now running update_rr(), heartpy will update all associated measures and will only compute peakpeak intervals between two accepted peaks.
>>> wd = update_rr(wd)
This will have generated a corrected RR_list object in the dictionary:
>>> wd['RR_list_cor'] array([ 800., 1250., 1140.])
As well as updated the lists RR_diff (differences between adjacent peakpeak intervals) and RR_sqdiff (squared differences between adjacent peakpeak intervals).

heartpy.analysis.
calc_rr_segment
(rr_source, b_peaklist)[source]¶ calculates peakpeak differences for segmentwise processing
Function that calculates rrmeasures when analysing segmentwise in the ‘fast’ mode.
Parameters:  rr_source (1d list or array) – list or array containing peakpeak intervals.
 b_peaklist (1d list or array) – list or array containing mask for peaklist.
Returns:  rr_list (array) – array containing peakpeak intervals.
 rr_diff (array) – array containing differences between adjacent peakpeak intervals
 rr_sqdiff (array) – array containing squared differences between adjacent peakpeak intervals
Examples
The function works in the same way as update_rr, except it returns three separate objects. It’s used by process_segmentwise. Revert to doc on update_rr for more information.
>>> rr, rrd, rrsd = calc_rr_segment(rr_source = [ 800., 1250., 50., 910., 1140., 1002., 1142.], ... b_peaklist = [1, 1, 1, 0, 1, 1, 1, 1]) >>> print(rr) [800.0, 1250.0, 1140.0, 1002.0, 1142.0] >>> print(rrd) [450.0 138.0 140.0] >>> print(rrsd) [202500. 19044. 19600.]

heartpy.analysis.
clean_rr_intervals
(working_data, method='quotientfilter')[source]¶ detects and rejects outliers in peakpeak intervals
Function that detects and rejects outliers in the peakpeak intervals. It updates the RR_list_cor in the working data dict
Parameters:  working_data (dict) – dictionary object that contains all heartpy’s working data (temp) objects. Needs to contain RR_list_cor, meaning one analysis cycle has already completed.
 method (str) – which method to use for outlier rejection, included are:  ‘quotientfilter’, based on the work in “Piskorki, J., Guzik, P. (2005), Filtering Poincare plots”,  ‘iqr’, which uses the interquartile range,  ‘zscore’, which uses the modified zscore method. default : quotientfilter
Returns: working_data – dictionary object that contains all heartpy’s working data (temp) objects. will be created if not passed to function
Return type: dict
Examples
Let’s load some data
>>> import heartpy as hp >>> data, timer = hp.load_exampledata(1) >>> sample_rate = hp.get_samplerate_mstimer(timer)
Run at least one analysis cycle first so that the dicts are populated
>>> wd, m = hp.process(data, sample_rate) >>> wd = clean_rr_intervals(working_data = wd) >>> ['%.3f' %x for x in wd['RR_list_cor'][0:5]] ['897.470', '811.997', '829.091', '777.807', '803.449']
You can also specify the outlier rejection method to be used, for example using the zscore method:
>>> wd = clean_rr_intervals(working_data = wd, method = 'zscore') >>> ['%.3f' %x for x in wd['RR_list_cor'][0:5]] ['897.470', '811.997', '829.091', '777.807', '803.449']
Or the interquartile range (iqr) based method:
>>> wd = clean_rr_intervals(working_data = wd, method = 'iqr') >>> ['%.3f' %x for x in wd['RR_list_cor'][0:5]] ['897.470', '811.997', '829.091', '965.849', '803.449']

heartpy.analysis.
calc_ts_measures
(rr_list, rr_diff, rr_sqdiff, measures={}, working_data={})[source]¶ calculates standard timeseries measurements.
Function that calculates the timeseries measurements for HeartPy.
Parameters:  rr_list (1d list or array) – list or array containing peakpeak intervals
 rr_diff (1d list or array) – list or array containing differences between adjacent peakpeak intervals
 rr_sqdiff (1d list or array) – squared rr_diff
 measures (dict) – dictionary object used by heartpy to store computed measures. Will be created if not passed to function.
 working_data (dict) – dictionary object that contains all heartpy’s working data (temp) objects. will be created if not passed to function
Returns:  working_data (dict) – dictionary object that contains all heartpy’s working data (temp) objects.
 measures (dict) – dictionary object used by heartpy to store computed measures.
Examples
Normally this function is called during the process pipeline of HeartPy. It can of course also be used separately.
Assuming we have the following peakpeak distances:
>>> import numpy as np >>> rr_list = [1020.0, 990.0, 960.0, 1000.0, 1050.0, 1090.0, 990.0, 900.0, 900.0, 950.0, 1080.0]
we can then compute the other two required lists by hand for now:
>>> rr_diff = np.diff(rr_list) >>> rr_sqdiff = np.power(rr_diff, 2) >>> wd, m = calc_ts_measures(rr_list, rr_diff, rr_sqdiff)
All output measures are then accessible from the measures object through their respective keys:
>>> print('%.3f' %m['bpm']) 60.384 >>> print('%.3f' %m['rmssd']) 67.082

heartpy.analysis.
calc_fd_measures
(method='welch', welch_wsize=240, square_spectrum=False, measures={}, working_data={}, degree_smoothing_spline=3)[source]¶ calculates the frequencydomain measurements.
Function that calculates the frequencydomain measurements for HeartPy.
 method : str
 method used to compute the spectrogram of the heart rate. available methods: fft, periodogram, and welch default : welch
 welch_wsize : float
Size of window (in sec) when welch method used to compute the spectrogram. This choice is based on a tradeoff btw temporal res and freq res of the resulting spectrum 60 sec may seem reasonable, but this would greatly limit frequency resolution!
1/60 s = 0.017 Hz, so you would only have 2 points in the VLF bandTherefore, the default is 4 min (9 points in the VLF band) default : 240
 square_spectrum : bool
 whether to square the power spectrum returned. default : False
 measures : dict
 dictionary object used by heartpy to store computed measures. Will be created if not passed to function.
 working_data : dict
 dictionary object that contains all heartpy’s working data (temp) objects. will be created if not passed to function
 degree_smoothing_spline : int, optional
 Degree of the smoothing spline for UnivariateSpline function in fitpack2. Must be 1 <= k <= 5. Default is k = 3, a cubic spline.
 working_data : dict
 dictionary object that contains all heartpy’s working data (temp) objects.
 measures : dict
 dictionary object used by heartpy to store computed measures.
Normally this function is called during the process pipeline of HeartPy. It can of course also be used separately.
Let’s load an example and get a list of peakpeak intervals
>>> import heartpy as hp >>> data, timer = hp.load_exampledata(2) >>> sample_rate = hp.get_samplerate_datetime(timer, timeformat='%Y%m%d %H:%M:%S.%f') >>> wd, m = hp.process(data, sample_rate)
wd now contains a list of peakpeak intervals that has been cleaned of outliers (‘RR_list_cor’). Calling the function then is easy
>>> wd, m = calc_fd_measures(method = 'periodogram', measures = m, working_data = wd) >>> print('%.3f' %m['lf/hf']) 5.198
Available methods are ‘fft’, ‘welch’ and ‘periodogram’. To set another method, do:
>>> wd, m = calc_fd_measures(method = 'fft', measures = m, working_data = wd) >>> print('%.3f' %m['lf/hf']) 5.198
If there are no valid peakpeak intervals specified, returned measures are NaN: >>> wd[‘RR_list_cor’] = [] >>> wd, m = calc_fd_measures(working_data = wd) >>> np.isnan(m[‘lf/hf’]) True
If there are rrintervals but not enough to reliably compute frequency measures, a warning is raised:
RuntimeWarning: Short signal. ———Warning:——— too few peakpeak intervals for (reliable) frequency domain measure computation, frequency output measures are still computed but treat them with caution!
HF is usually computed over a minimum of 1 minute of good signal. LF is usually computed over a minimum of 2 minutes of good signal. VLF is usually computed over a minimum of 5 minutes of good signal. The LF/HF ratio is usually computed over minimum 24 hours, although an absolute minimum of 5 min has also been suggested.
For more info see:
 Shaffer, F., Ginsberg, J.P. (2017).
An Overview of Heart Rate Variability Metrics and Norms.
Task Force of Pacing and Electrophysiology (1996), Heart Rate Variability in: European Heart Journal, vol.17, issue 3, pp354381

heartpy.analysis.
calc_breathing
(rrlist, method='welch', filter_breathing=True, bw_cutoff=[0.1, 0.4], measures={}, working_data={})[source]¶ estimates breathing rate
Function that estimates breathing rate from heart rate signal. Upsamples the list of detected rr_intervals by interpolation then tries to extract breathing peaks in the signal.
Parameters:  rr_list (1d list or array) – list or array containing peakpeak intervals
 method (str) – method to use to get the spectrogram, must be ‘fft’ or ‘welch’ default : fft
 filter_breathing (bool) – whether to filter the breathing signal derived from the peakpeak intervals default : True
 bw_cutoff (list or tuple) – breathing frequency range expected default : [0.1, 0.4], meaning between 6 and 24 breaths per minute
 measures (dict) – dictionary object used by heartpy to store computed measures. Will be created if not passed to function.
 working_data (dict) – dictionary object that contains all heartpy’s working data (temp) objects. will be created if not passed to function
Returns: measures – dictionary object used by heartpy to store computed measures.
Return type: dict
Examples
Normally this function is called during the process pipeline of HeartPy. It can of course also be used separately.
Let’s load an example and get a list of peakpeak intervals
>>> import heartpy as hp >>> data, _ = hp.load_exampledata(0) >>> wd, m = hp.process(data, 100.0)
Breathing is then computed with the function
>>> m, wd = calc_breathing(wd['RR_list_cor'], measures = m, working_data = wd) >>> round(m['breathingrate'], 3) 0.171
There we have it, .17Hz, or about one breathing cycle in 6.25 seconds.