# Understanding Annotations

    library(EGM)
    #>
    #> Attaching package: 'EGM'
    #> The following object is masked from 'package:stats':
    #>
    #>     window

# Electrocardiogram Annotations

## WFDB Annotation Standards

The WFDB (Waveform Database) software package provides a standardized system for annotating cardiac signals, predominately surface electrocardiogram (ECG) data. Annotations are polymorphic, meaning multiple annotation sets can be applied to a single signal dataset. The limitation is that these are constrained to physiological events associated with surface ECGs.

### Annotation Table Structure

All WFDB-compatible annotations in the `{EGM}` package are stored as `annotation_table` objects. The columns are type-specific, which allows them to be easily stored. These tables contain the following required columns:

- annotator: Name of the annotation function or creator (e.g., “sqrs”, “ecgpuwave”, “manual”)
- time: Time stamp constructed from sample number and sampling frequency (format: HH:MM:SS.mmm)
- sample: Integer index of the annotation position in the signal
- type: Single character symbol describing the annotation type (see annotation types below)
- subtype: Single character providing additional classification
- channel: Integer indicating which signal channel the annotation applies to
- number: Additional numeric qualifier providing context-specific information

    # Create annotations for detected R-peaks
    # Example
    ann <- annotation_table(
      annotator = "qrs",
      sample = c(100, 350, 600, 850),
      type = "N",
      frequency = 250,
      channel = 0
    )

    # Print
    ann
    #> <annotation_table: 4 `qrs` annotations>
    #>          time sample   type subtype channel number
    #>        <char>  <num> <char>  <char>   <num>  <int>
    #> 1: 00:00:00.4    100      N               0      0
    #> 2: 00:00:01.4    350      N               0      0
    #> 3: 00:00:02.4    600      N               0      0
    #> 4: 00:00:03.4    850      N               0      0

## Standard ECG Annotation Types

The WFDB standard defines 41 annotation types for surface electrocardiograms. These annotations can be broadly grouped into several categories:

### Beat Annotations

Beat annotations mark individual cardiac cycles and their characteristics:

    # Load internal annotation data
    beat_symbols <- c("N", "L", "R", "a", "V", "F", "J", "A", "S", "E", "j", "/", "Q", "~")
    beat_labels <- EGM:::.surface_annotations[EGM:::.surface_annotations$symbol %in% beat_symbols, ]

    knitr::kable(
      beat_labels[, c("symbol", "mnemonic", "description")],
      col.names = c("Symbol", "Mnemonic", "Description"),
      row.names = FALSE,
      caption = "Beat Annotation Types"
    )

Beat Annotation Types
Symbol | Mnemonic | Description
--- | --- | ---
N | NORMAL | Normal beat
L | LBBB | Left bundle branch block beat
R | RBBB | Right bundle branch block beat
a | ABERR | Aberrated atrial premature beat
V | PVC | Premature ventricular contraction
F | FUSION | Fusion of ventricular and normal beat
J | NPC | Nodal (junctional) premature beat
A | APC | Atrial premature contraction
S | SVPB | Premature or ectopic supraventricular beat
E | VESC | Ventricular escape beat
j | NESC | Nodal (junctional) escape beat
/ | PACE | Paced beat
Q | UNKNOWN | Unclassifiable beat
~ | NOISE | Signal quality change

Key beat types:

- N (NORMAL): Normal sinus beat
- V (PVC): Premature ventricular contraction
- A (APC): Atrial premature contraction
- L/R (LBBB/RBBB): Bundle branch block beats
- F (FUSION): Fusion of ventricular and normal beat
- / (PACE): Paced beat

### Waveform Boundary Annotations

These mark the beginning, peak, and end of ECG waveforms:

    wave_symbols <- c("p", "t", "u", "(", ")")
    wave_labels <- EGM:::.surface_annotations[EGM:::.surface_annotations$symbol %in% wave_symbols, ]

    knitr::kable(
      wave_labels[, c("symbol", "mnemonic", "description")],
      col.names = c("Symbol", "Mnemonic", "Description"),
      row.names = FALSE,
      caption = "Waveform Boundary Annotations"
    )

Waveform Boundary Annotations
Symbol | Mnemonic | Description
--- | --- | ---
p | PWAVE | P-wave peak
t | TWAVE | T-wave peak
u | UWAVE | U-wave peak
( | WFON | Waveform onset
) | WFOFF | Waveform end

### Rhythm and Signal Quality Annotations

    rhythm_symbols <- c("+", "|", "s", "T", "~", "x")
    rhythm_labels <- EGM:::.surface_annotations[EGM:::.surface_annotations$symbol %in% rhythm_symbols, ]

    knitr::kable(
      rhythm_labels[, c("symbol", "mnemonic", "description")],
      col.names = c("Symbol", "Mnemonic", "Description"),
      row.names = FALSE,
      caption = "Rhythm and Signal Quality Annotations"
    )

Rhythm and Signal Quality Annotations
Symbol | Mnemonic | Description
--- | --- | ---
~ | NOISE | Signal quality change
| | ARFCT | Isolated QRS-like artifact
s | STCH | ST change
T | TCH | T-wave change
+ | RHYTHM | Rhythm change
x | NAPC | Non-conducted P-wave (blocked APB)

### Specialized Annotations

    special_symbols <- c("*", "D", "\"", "=", "!", "[", "]", "@", "r", "^", "B", "e", "n", "f")
    special_labels <- EGM:::.surface_annotations[EGM:::.surface_annotations$symbol %in% special_symbols, ]

    knitr::kable(
      special_labels[, c("symbol", "mnemonic", "description")],
      col.names = c("Symbol", "Mnemonic", "Description"),
      row.names = FALSE,
      caption = "Specialized Annotations"
    )

Specialized Annotations
Symbol | Mnemonic | Description
--- | --- | ---
* | SYSTOLE | Systole
D | DIASTOLE | Diastole
” | NOTE | Comment annotation
= | MEASURE | Measurement annotation
B | BBB | Left or right bundle branch block
^ | PACESP | Non-conducted pacer spike
! | FLWAV | Ventricular flutter wave
[ | VFON | Start of ventricular flutter/fibrillation
] | VFOFF | End of ventricular flutter/fibrillation
e | AESC | Atrial escape beat
n | SVESC | Supraventricular escape beat
@ | LINK | Link to external data (aux_note contains URL)
f | PFUS | Fusion of paced and normal beat
r | RONT | R-on-T premature ventricular contraction

## Common Annotation File Types

When working with WFDB files, annotations are stored with specific file extensions that indicate the annotator used:

- `.atr`: Manually reviewed and corrected reference annotations
- `.ann`: General annotation file
- `.ecgpuwave`: Surface ECG wave boundaries (P, QRS, T waves) generated by the ecgpuwave algorithm
- `.sqrs`, `.wqrs`, `.gqrs`: R-peak detections from different QRS detection algorithms

## Accessing All Standard Annotations

The complete list of standard WFDB annotations can be accessed using:

    # View all standard ECG annotation types
    wfdb_annotation_labels()

    # Filter for specific symbols
    wfdb_annotation_labels(symbol = c("N", "V", "A"))

    # Decode annotations in an existing annotation table
    ann <- annotation_table(
      annotator = "example",
      sample = c(100, 200),
      type = c("N", "V")
    )

    # Add human-readable descriptions
    wfdb_annotation_decode(ann)

## Example: Working with ECG Annotations

Here’s a practical example of reading, interpreting, and visualizing ECG annotations:

    # Read an ECG with annotations
    record_path <- system.file('extdata', package = 'EGM')
    ecg <- read_wfdb(
      record = "muse-sinus",
      record_dir = record_path
    )

    # Read associated annotations (if they exist)
    ann <- read_annotation(
       record = "muse-sinus",
       annotator = "ecgpuwave",
       record_dir = record_path
    )

    # Decode annotation types
    ann_decoded <- wfdb_annotation_decode(ann)
    head(ann_decoded)

# Intracardiac Electrogram Annotations

This is a work in progress, where we aim to define and implement a comprehensive set of annotations for intracardiac electrograms that are compatible with the standard WFDB annotation system.

# Examples

## `ecgpuwave`

One of the common annotators used, called `ecgpuwave`, demonstrates how the annotation system is leveraged.

The standard labels are used:

- p (PWAVE): P-wave peak
- t (TWAVE): T-wave peak
- ( (WFON): Waveform onset
- ) (WFOFF): Waveform end

When using waveform boundary annotations like `(` and `)`, the number column specifies which waveform:

- 0 = P wave
- 1 = QRS complex
- 2 = T wave

For T-wave annotations (`t`), the number column describes morphology:

- 0 = Normal
- 1 = Inverted
- 2 = Positive
- 3 = Negative
- 4 = Biphasic (negative-positive)
- 5 = Biphasic (positive-negative)