GitHunt
PH

Matlab toolbox for calculating Heart-Rate Variability metrics on ECG signals

mhrv

Documentation Status

mhrv is a matlab toolbox for calculating Heart-Rate Variability (HRV) metrics
from both ECG signals and RR-interval time series. The toolbox works with ECG
data in the PhysioNet [1] WFDB data format.

Features

  • WFDB wrappers and helpers. A small subset of the PhysioNet WFDB tools are
    wrapped with matlab functions, to allow using them directly from matlab. For
    example,

    • mhrv.wfdb.gqrs - A QRS detection algorithm.
    • mhrv.wfdb.rdsamp - For reading PhysioNet signal data into matlab.
    • mhrv.wfdb.rdann - For reading PhysioNet annotation data into matlab.
    • mhrv.wfdb.wrann - For writing PhysioNet annotation data from matlab datatypes.
    • mhrv.wfdb.wfdb_header - Read record metadata from a WFDB header file (.hea).
  • ECG signal processing. Peak detection and RR interval extraction from ECG data
    in PhysioNet format. For example,

    • mhrv.wfdb.rqrs - Detection of R-peaks in ECG signals (based on PhysioNet's
      gqrs). Configurable for use with both human and animal ECGs.
    • mhrv.ecg.jqrs/mhrv.ecg.wjqrs - An ECG peak-detector based on a modified Pan & Tompkins
      algorithm and a windowed version.
    • mhrv.ecg.bpfilt- Bandpass filtering for removing noise artifacts from ECG
      signals.
    • mhrv.wfdb.ecgrr - Construction of RR intervals from ECG data in PhysioNet format.
    • mhrv.wfdb.qrs_compare - Comparison of QRS detections to reference annotations and
      calculation of quality measures like Sensitivity, PPV.
  • RR-intervals signal processing. Ectopic beat rejection, frequency filtering,
    nonlinear dynamic and fractal analysis. For example,

    • mhrv.rri.filtrr - Filtering of RR interval time series to detect ectopic (out of
      place) beats.
    • mhrv.rri.dfa - Detrended Fluctuation Analysis, a method of estimating the fractal
      scaling exponent of a signal [3].
    • mhrv.rri.mse - Multiscale Sample Entropy, a measure of the complexity of the
      signal computed on multiple time scales [4].
    • mhrv.rri.sample_entropy - Sample Entropy, a measure of the irregularity of a signal.
  • HRV Metrics: Calculating quantitative measures that indicate the activity of
    the heart based on RR intervals using all standard HRV metrics defined in
    the literature (see e.g. [2]).

    • mhrv.hrv.hrv_time - Time Domain: AVNN, SDNN, RMSSD, pNNx.
    • mhrv.hrv.hrv_freq - Frequency Domain:
      • Total and normalized power in (configurable) VLF, LF, HF and custom
        user-defined bands.
      • Spectral power estimation using Lomb, Auto Regressive, Welch and FFT methods.
      • Additional frequency-domain features: LF/HF ratio, LF and HF peak
        frequencies, power-law scaling exponent (beta).
    • mhrv.hrv.hrv_nonlinear - Nonlinear methods:
      • Short- and long-term scaling exponents (alpha1, alpha2) based on DFA.
      • Sample Entropy and Multiscale sample entropy (MSE).
      • Poincaré plot metrics (SD1, SD2).
    • mhrv.hrv.hrv_fragmentation - Time-domain RR interval fragmentation analysis [5].
  • Configuration: The toolbox is fully configurable with many user-adjustable
    parameters.

    • The configuration files are in human-readable YAML format which
      is easy to edit and extend.
    • The user can create custom configurations files based on the
      defatuls.yml file (only overriding what's required).
    • Custom configuration files can be loaded with a single call which updates
      the defaults for the entire toolbox. This allows simple, reproducible
      analysis of different datasets that require different analysis
      configurations. See the mhrv.defaults package.
    • The settings for any of the functions can either be configured globally
      with configuration yml files or on a per-call basis with matlab-style
      key-value argument pairs.
  • Plotting: All toolbox functions support plotting their output for data
    visualization. The plotting code is separated from the algorithmic code in
    order to simplify embedding this toolbox in other matlab applications.
    See the mhrv.plots package.

  • Top-level analysis functions: These functions work with PhysioNet records and
    allow streamlined HRV analysis by composing the functions of this toolbox.

    • mhrv.mhrv - Analyzes a single PhysioNet record (ECG data or annotations),
      optionally split into multiple analysis windows. Extracts all
      supported HRV features and optionally generates plots.
    • mhrv.mhrv_batch - Analyzes many PhysioNet records (ECG data or annotations) which
      can be further separated into user-defined groups (e.g. Control, Test).
      Automatically computes HRV metrics per group and generates a comparative
      summary of the HRV features in each group.

Requirements

  • Matlab with Signal Processing toolbox. Should work on Matlab R2014b or newer.
  • The PhysioNet WFDB tools.
    The toolbox can install this for you.

Installation

  1. Clone the repo or download the source code.

  2. From matlab, run the mhrv_init function from the root of the repo. This
    function will:

    • Check for the presence of the WFDB tools in your system PATH.
    • If WFDB tools are not detected, it will attempt to automatically download
      them for you into the folder bin/wfdb under the repository root.
    • Set up your MATLAB path to include the code from this toolbox.

Notes about matlab's pwd and path

Matlab maintains a PWD, or "present working directory". It's the folder you see
at the top of the interface, containing the files you see in the file explorer
pane. Type pwd at the matlab command prompt to see it's value.

Additionally, matlab maintains a PATH variable, containing a list of folders in
which it searches for function definitions (similar to the shell PATH concept).
Type path at the matlab command prompt to see it's value.

You don't need to change your pwd to the root of the repo folder for the
toolbox to work. You can simple run the mhrv_init function from your current
pwd, and it will take care of updating matlab's path. For example, if you
cloned or downloaded the toolbox in the folder /Users/myname/mhrv/, you can
run the following command from the matlab prompt:

run /Users/myname/mhrv/mhrv_init.m

After this the toolbox will be ready to use, regardless of your pwd.

Manual WFDB Installation

The above steps should be enough to get most users started.
In some cases mhrv_init may fail to download the correct binaries for you, or
you may want to install them yourself.

  • On macOS, you can use homebrew. First install homebrew,
    then install wfdb with brew tap brewsci/science && brew install -s wfdb.
  • On any OS (including macOS), you can compile the WFDB binaries from
    source

    using the instructions on their website.

Once you have the binaries, place them in some folder on your $PATH or
somewhere under the repo's root folder (bin/wfdb would be a good choice as it's
.gitignored) and they will be found and used automatically.
You can replace the binaries that were automatically downloaded with your
compiled ones. If you used homebrew, they should already be on your $PATH.

If you would like to manually specify a path outside the repo which contains the
WFDB binaries (e.g. /usr/local/bin for a homebrew install), you can edit
cfg/defaults.yml
and set the mhrv.paths.wfdb_path variable to the desired path.

For macOS users it's recommended to install with homebrew, and
for linux users it's recommended to install from source, as the binaries provided
on the PhysioNet website are very outdated.

Documentation

Documentation is available on
readthedocs.

Usage

Exaple of calculating HRV measures for a PhysioNet record downloaded from
PhysioNet (in this case from
mitdb):

% Download the mitdb/111 record from PhysioNet to local folder named 'db'
>> mhrv.wfdb.download_wfdb_records('mitdb', '111', 'db');
[0.210] >> mitdb: Found 48 records
[0.300] >> mitdb: Found 1 annotators
[0.400] >> mitdb: Downloaded: 111.hea -> db/mitdb/111.hea
[0.500] >> mitdb: Downloaded: 111.atr -> db/mitdb/111.atr
[1.030] >> mitdb: Downloaded: 111.dat -> db/mitdb/111.dat
[1.040] >> mitdb: Done, 1 records downloaded.
% Run HRV analysis
>> mhrv.mhrv('db/mitdb/111', 'window_minutes', 15, 'plot', true);
[0.010] >> mhrv: Processing record db/mitdb/111 (ch. 1)...
[0.010] >> mhrv: Signal duration: 00:30:05.555 [HH:mm:ss.ms]
[0.020] >> mhrv: Analyzing window 1 of 2...
[0.020] >> mhrv: [1/2] Detecting RR intervals from ECG... 1046 intervals detected.
[0.280] >> mhrv: [1/2] Removing ectopic intervals... 13 intervals removed.
[0.300] >> mhrv: [1/2] Calculating time-domain metrics...
[0.310] >> mhrv: [1/2] Calculating frequency-domain metrics...
[0.580] >> mhrv: [1/2] Calculating nonlinear metrics...
[0.660] >> mhrv: [1/2] Calculating fragmentation metrics...
[0.680] >> mhrv: Analyzing window 2 of 2...
[0.680] >> mhrv: [2/2] Detecting RR intervals from ECG... 1065 intervals detected.
[0.930] >> mhrv: [2/2] Removing ectopic intervals... 4 intervals removed.
[0.950] >> mhrv: [2/2] Calculating time-domain metrics...
[0.960] >> mhrv: [2/2] Calculating frequency-domain metrics...
[1.110] >> mhrv: [2/2] Calculating nonlinear metrics...
[1.180] >> mhrv: [2/2] Calculating fragmentation metrics...
[1.190] >> mhrv: Building statistics table...
[1.200] >> mhrv: Displaying Results...
                RR       NN      AVNN      SDNN      RMSSD      pNN50       SEM      BETA_LOMB    HF_NORM_LOMB    HF_PEAK_LOMB    HF_POWER_LOMB    LF_NORM_LOMB    LF_PEAK_LOMB    LF_POWER_LOMB    LF_TO_HF_LOMB    TOTAL_POWER_LOMB    VLF_NORM_LOMB    VLF_POWER_LOMB      SD1       SD2       alpha1     alpha2      SampEn        PIP        IALS        PSS       PAS  
              ______    ____    ______    ______    _______    _______    _______    _________    ____________    ____________    _____________    ____________    ____________    _____________    _____________    ________________    _____________    ______________    _______    ______    ________    _______    _________    _______    _________    ______    ______

    1           1046    1033    858.95    30.958     33.598      14.05    0.96322     -1.1881        63.899         0.16744          443.95            6.6518        0.056809         46.214            0.1041            694.76            25.832            179.47         23.769     36.77     0.64751    0.69834       1.8402     52.662       0.5281    60.213     11.81
    2           1065    1061    841.79    40.042     31.725     12.075     1.2293     -1.4542        51.529         0.16744          394.82            6.7584        0.044849         51.783           0.13116            766.21            35.367            270.99         22.444     51.96     0.70254    0.93526       1.8466     51.555      0.51698    55.702    14.138
    Mean      1055.5    1047    850.37      35.5     32.662     13.063     1.0963     -1.3212        57.714         0.16744          419.38            6.7051        0.050829         48.999           0.11763            730.48              30.6            225.23         23.106    44.365     0.67502     0.8168       1.8434     52.109      0.52254    57.958    12.974
    SE           9.5      14     8.581    4.5421    0.93663    0.98746    0.13305     0.13306        6.1852               0          24.564          0.053267       0.0059799         2.7844          0.013529            35.724            4.7674            45.757        0.66276    7.5954    0.027515    0.11846    0.0032216    0.55351    0.0055598    2.2554    1.1637
    Median    1055.5    1047    850.37      35.5     32.662     13.063     1.0963     -1.3212        57.714         0.16744          419.38            6.7051        0.050829         48.999           0.11763            730.48              30.6            225.23         23.106    44.365     0.67502     0.8168       1.8434     52.109      0.52254    57.958    12.974

[1.220] >> mhrv: Generating plots...
[3.260] >> mhrv: Finished processing record db/mitdb/111.

The window_minutes parameter allow splitting the signal into windows and
calculating all metrics per window. You can pass in an empty array [] to
disable spliting.

Example plots (generated by the example above):

  • ECG R-peak detection Example Peak Detection
  • RR interval time series filtering Example RR filtering
  • Time-domain HRV Metrics Example time domain metrics
  • Spectrum of interval time series Example NN spectrum
  • Nonlinear HRV Metrics Example nonlinear metrics
  • Poincaré plot and ellipse fitting Example poincaré plot

Citing

This toolbox, initially called rhrv, was created as part of my MSc research
thesis. It was then renamed and updated to be used as the basis of the
PhysioZoo platform for HRV analysis of human and
animal data.

To use it in you own research, please cite:

  • Rosenberg, A. A. (2018) ‘Non-invasive in-vivo analysis of intrinsic clock-like
    pacemaker mechanisms: Decoupling neural input using heart rate variability
    measurements.’ MSc Thesis. Technion, Israel Institute of Technology.

  • Behar J. A., Rosenberg A. A. et al. (2018) ‘PhysioZoo: a novel open access
    platform for heart rate variability analysis of mammalian
    electrocardiographic data.’ Frontiers in Physiology.

Similar projects

Several other projects exist with various levels of overlapping functionality and
purpose.

Attribution

Some of the code in lib/ was created by others, used here as dependencies.
Original author attribution exists in the source files.

Contribution

Feel free to send pull requests or open issues via GitHub.

References

  1. Goldberger, A. L. et al. (2000) ‘PhysioBank, PhysioToolkit, and PhysioNet’,
    Circulation, 101(23), pp. E215-20.
  2. Task Force of the European Society of Cardiology and the North American
    Society of Pacing and Electrophysiology. (1996) ‘Heart rate variability.
    Standards of measurement, physiological interpretation, and clinical use.’,
    European Heart Journal, 17(3), pp. 354–81.
  3. Peng, C.-K., Hausdorff, J. M. and Goldberger, A. L. (2000) ‘Fractal mechanisms
    in neuronal control: human heartbeat and gait dynamics in health and disease,
    Self-organized biological dynamics and nonlinear control.’ Cambridge:
    Cambridge University Press.
  4. Costa, M. D., Goldberger, A. L. and Peng, C.-K. (2005) ‘Multiscale entropy
    analysis of biological signals’, Physical Review E - Statistical, Nonlinear,
    and Soft Matter Physics, 71(2), pp. 1–18.
  5. Costa, M. D., Davis, R. B. and Goldberger, A. L. (2017) ‘Heart Rate
    Fragmentation : A New Approach to the Analysis of Cardiac Interbeat Interval
    Dynamics’, Frontiers in Physiology, 8(May), pp. 1–13.

Languages

MATLAB94.2%C4.2%HTML1.6%

Contributors

GNU General Public License v3.0
Created October 21, 2016
Updated January 8, 2026
physiozoo/mhrv | GitHunt