# 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:

- Wavedet
- gqrs
- wqrs
- Pan and Tompkins
- ECGpuwave
- EP limited
- Aristotle (not distributed with the kit)

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

> - all-detectors
> - wavedet
> - pantom
> - aristotle
> - gqrs
> - sqrs
> - wqrs
> - ecgpuwave
> - epltdqrs1 or epltdqrs2

`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.

## 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:

- PhysioNet/Computing in Cardiology Challenge 2014
- Physionet
- A video demo in Youtube

## See Also

> ECGtask | ECG delineation | examples