QRS detection

This document describes how to perform QRS detection.

Description

Heartbeat detection is probably one of the first and most important tasks when you process cardiovascular recordings. The ECGkit has several algorithms implemented:

You can use any or all the algorithms as you will see below or you can even add your own algorithms if you follow an easy interface, as described below. The results are stored in a single file, that you can use to perform other subsequent tasks, such as ECG delineation or even the visual inspection or correction of the algorithms results. For a quick reference about heartbeat detection you may want to check this example

Input Arguments

The properties that this task uses are the following:

progress_handle — Used to track the progress within your function. [] (default)

progress_handle, is a handle to a progress_bar object, that can be used to track the progress within your function.

tmp_path — The path to store temporary data. tempdir() (default)

Full path to a directory with write privileges.

detectors — The QRS detection algorithms to use. 'all-detectors' (default)

This property controls which algorithms are used. A cell string or char array with any of the following names

only_ECG_leads — Process only ECG signals. true (default)

Boolean value. Find out which signals are ECG based on their header description.

gqrs_config_filename — A configuration filename for the gqrs algorithm. [] (default)

A full filename with the configuration for the gqrs algorithm. See the algorithm web page for details.

detection_threshold — A threshold to control the sensitivity of the detector. 1 (default)

Use higher values to reduce false detections, or lower values to reduce the number of missed beats.

payload — An arbitrary format variable to be passed to your user-defined algorithm. [] (default)

This variable can be useful for passing data to your own function, in addition to the interface described below.

CalculatePerformance — Calculate algorithm performances based on gold standard reference detections. false (default)

Boolean value. Calculate the algorithm performance based on the reference annotations found by the ECGwrapper object in the same folder where the signals are. This reference annotations are loaded, if detected, in the ECG_annotations property.

bRecalcQualityAndPerformance — Recalculate algorithm performances without performing heartbeat detection. false (default)

Boolean value. Recalculate algorithm performances without performing heartbeat detection. This feature is useful for BIG jobs where only a small change in performance calculation methodology was changed. . The cached result is passed to the task via the payload property as in the example:
% If only recaclulate performance is needed.
ECGw.ECGtaskHandle.bRecalcQualityAndPerformance = true;
% in order to avoid skiping the task
ECGw.cacheResults = false;
%payload has the current detections
cached_filenames = ECGw.GetCahchedFileName('QRS_detection');
ECGw.ECGtaskHandle.payload = load(cached_filenames{1});

bRecalculateNewDetections — Calculate only heartbeat detections not performed before. false (default)

Boolean value. The heartbeat detection is only performed in the algorithms not executed in a previous cached result. The cached result is passed to the task via the payload property as in the example:
% this is needed in order to recalculate tasks.
    % Useful if a new detector is added
    ECGw.ECGtaskHandle.bRecalculateNewDetections = true;
    % in order to avoid skiping the task
    ECGw.cacheResults = false;
    %payload has the current detections
    cached_filenames = ECGw.GetCahchedFileName('QRS_detection');
    ECGw.ECGtaskHandle.payload = load(cached_filenames{1});

Adding a custom detection algorithm

Adding your own QRS detectors to the kit is very simple. Ensure that your function implements this interface:

function [positions_single_lead, position_multilead] =

                    your_QRS_detector( ECG_matrix, ECG_header, progress_handle, payload_in)

where the arguments are:

ECG_matrix, is a matrix size [ECG\_header.nsamp ECG\_header.nsig]

ECG_header, is a struct with info about the ECG signal, see ECG header for details.

progress_handle, is a handle to a progress_bar object, that can be used to track the progress within your function.

payload_in, is a user variable, of arbitrary format, allowed to be sent to your function. It is sent via the payload property of this class, for example:

% One variable
this_ECG_wrapper.ECGtaskHandle.payload = your_variable;

% Several variables with a cell container
this_ECG_wrapper.ECGtaskHandle.payload = {your_var1 your_var2};

% Or the result of a previous task, in this case QRS manual correction (if available)
% or the automatic detection if not.
cached_filenames = this_ECG_wrapper.GetCahchedFileName({'QRS_corrector' 'QRS_detection'});
this_ECG_wrapper.ECGtaskHandle.payload = load(cached_filenames);

and the output of your function must be:

positions_single_lead, a cell array size ECG_header.nsig with the QRS sample locations found in each lead.

position_multilead, a numeric vector with the QRS locations calculated using multilead rules.

Examples

Create the ECGtask_QRS_detection object.

% with the task name
ECG_w.ECGtaskHandle = 'QRS_detection';

    % or create an specific handle to have more control
ECGt_QRSd = ECGtask_QRS_detection();

and then you are ready to set the algorithms to use. In the following example you have several possible set-ups.

% select an specific algorithm. Default: Run all detectors
ECGt_QRSd.detectors = 'wavedet'; % Wavedet algorithm based on
ECGt_QRSd.detectors = 'pantom';  % Pan-Tompkins alg.
ECGt_QRSd.detectors = 'gqrs';    % WFDB gqrs algorithm.
% Example of how you can add your own QRS detector.
ECGt_QRSd.detectors = 'user:example_worst_ever_QRS_detector';
% "your_QRS_detector_func_name" can be your own detector.
ECGt_QRSd.detectors = 'user:your_QRS_detector_func_name';
ECGt_QRSd.detectors = {'wavedet' 'gqrs' 'user:example_worst_ever_QRS_detector'};

Finally set the task to the wrapper object, and execute the task.

ECG_w.ECGtaskHandle= ECGt_QRSd; % set the ECG task
ECG_w.Run();

You can check the result of this task, with either the detection corrector or the visualization functions.

Also check this example for further information.

Results format

The result file will have ECG_header.nsig x algorithms_used variables, which can later be recovered as a struct variable, with fields named according to [ 'algorithm_name' '_' 'lead_name' ]. Each of this fields is a struct itself with a single field called time, where the actual QRS detections are. In addition, another struct variable called series_quality is stored in order to provide a quality metric of the detections created. This metric is found in the ratios field, a higher ratio means better detections. Each ratio corresponds with a name in the AnnNames field.

More About

Here are some external references about heartbeat detection: