Skip to content
advancedscience

MIT-BIH Arrhythmia Rhythm Episode and Beat Review on ECG

Review rhythm episodes and beat labels on ten real two-channel ECG excerpts, using the time_series display, WFDB files, and signal-cnn rhythm labeling.

Get This Design

View on GitHub(opens in a new tab)

Clone or download from the repository

Quick start:

bash
git clone https://github.com/davidjurgens/potato-showcase.git
cd potato-showcase/science/physiology/mit-bih-arrhythmia-rhythm-episodes
potato start config.yaml

About this dataset

The MIT-BIH Arrhythmia Database holds 48 approximately half-hour, two-channel ambulatory ECG recordings from 47 subjects, collected at Boston's Beth Israel Hospital between 1975 and 1979 and digitized at 360 samples per second. Records 100 to 124 were chosen at random from over 4000 Holter recordings, and records 200 to 234 were chosen to include rare but clinically important arrhythmias. George Moody and Roger Mark's group at MIT and Beth Israel distributes the database on PhysioNet under the Open Data Commons Attribution License.

An automatic QRS detector produced the first beat marks. Two cardiologists then worked independently on paper charts, adding missed beats, deleting false detections, changing the labels of abnormal beats, and adding rhythm labels, signal quality labels, and comments. Each discrepancy between the two sets was resolved by consensus. The design loads the released reference labels for ten excerpts of 90 to 120 seconds as pre-annotations, so annotators review and correct the labels rather than label from scratch. Rhythm episodes (15 codes such as N, AFIB, VT, and VFL) are intervals in one scheme, and beats (20 symbols such as N, V, A, and the paced beat) are point events in a second scheme, because N is both a beat symbol and a rhythm code. The excerpts come from nine records. Nine of the ten start with an added rhythm label at 0 seconds that the original records do not carry, and mitdb_001 keeps record 100's own label 0.05 seconds in. Signal quality changes and comments are not offered.

The model_training block turns on training and writeback. The signal-cnn trainer is chosen for the rhythm scheme on the /admin/training page. In free mode the trainer labels each recording sample by sample from both channels, trains on random 30-second crops, merges runs of one label into intervals, and trains on saved labels. Potato never writes a prediction onto an item the model trained on, and the signal display shows a model's intervals only for a recording whose annotation file supplies none. Every excerpt here carries an annotation file, so no dashed proposal appears. The trainer ignores the beat events, so beat labels stay a review task, and the trainer needs at least three annotated recordings in the training split. Ten short excerpts exercise the loop and do not support a model that generalizes.

Recordings
48 (about half an hour each)
Subjects
47
Beat annotations
approximately 110,000
Sampling rate
360 Hz, two channels
Rhythm codes offered
15
Beat symbols offered
20
Excerpts in this design
10 (90 to 120 seconds each)

Configuration File

This Potato config reproduces the annotation task. Save it as config.yaml and run potato start config.yaml to try it.

yaml
# yaml-language-server: $schema=https://potatoannotator.readthedocs.io/en/latest/schemas/potato-config.schema.json
#
# MIT-BIH Arrhythmia Database: review rhythm episodes and beat labels on
# two-channel ambulatory ECG.
#
# Dataset: MIT-BIH Arrhythmia Database (PhysioNet, version 1.0.0)
# Paper:
#   @article{Moody_2001,
#     title     = {The impact of the MIT-BIH Arrhythmia Database},
#     volume    = {20},
#     ISSN      = {0739-5175},
#     url       = {http://dx.doi.org/10.1109/51.932724},
#     DOI       = {10.1109/51.932724},
#     number    = {3},
#     journal   = {IEEE Engineering in Medicine and Biology Magazine},
#     publisher = {Institute of Electrical and Electronics Engineers (IEEE)},
#     author    = {Moody, G.B. and Mark, R.G.},
#     year      = {2001},
#     pages     = {45--50}
#   }
# DOI: 10.1109/51.932724
# Dataset DOI: 10.13026/C2F305
# Dataset URL: https://physionet.org/content/mitdb/1.0.0/
# Licence: Open Data Commons Attribution License v1.0. The ten excerpts in
# media/ are cut from records 100, 106, 119, 201, 202, 203, 207, 217 and 222;
# see media/LICENSE-media.txt.
#
# Annotation protocol, quoted from the MIT-BIH Arrhythmia Database Directory
# (Introduction, section "Annotations",
# https://archive.physionet.org/physiobank/database/html/mitdbdir/intro.htm):
#   "For each record, the two charts were given to two cardiologists, who
#   worked on them independently. The cardiologists added additional beat
#   labels where the detector missed beats, deleted false detections as
#   necessary, and changed the labels for all abnormal beats. They also added
#   rhythm labels, signal quality labels, and comments."
#   "Each discrepancy was reviewed and resolved by consensus."
#
# Beat symbols, quoted from the same page ("Symbols used in plots"):
#   · or N  Normal beat
#   L       Left bundle branch block beat
#   R       Right bundle branch block beat
#   A       Atrial premature beat
#   a       Aberrated atrial premature beat
#   J       Nodal (junctional) premature beat
#   S       Supraventricular premature beat
#   V       Premature ventricular contraction
#   F       Fusion of ventricular and normal beat
#   [       Start of ventricular flutter/fibrillation
#   !       Ventricular flutter wave
#   ]       End of ventricular flutter/fibrillation
#   e       Atrial escape beat
#   j       Nodal (junctional) escape beat
#   E       Ventricular escape beat
#   /       Paced beat
#   f       Fusion of paced and normal beat
#   x       Non-conducted P-wave (blocked APB)
#   Q       Unclassifiable beat
#   |       Isolated QRS-like artifact
#
# Rhythm annotations, quoted from the same page ("Rhythm annotations appear
# below the level used for beat annotations"):
#   (AB    Atrial bigeminy
#   (AFIB  Atrial fibrillation
#   (AFL   Atrial flutter
#   (B     Ventricular bigeminy
#   (BII   2° heart block
#   (IVR   Idioventricular rhythm
#   (N     Normal sinus rhythm
#   (NOD   Nodal (A-V junctional) rhythm
#   (P     Paced rhythm
#   (PREX  Pre-excitation (WPW)
#   (SBR   Sinus bradycardia
#   (SVTA  Supraventricular tachyarrhythmia
#   (T     Ventricular trigeminy
#   (VFL   Ventricular flutter
#   (VT    Ventricular tachycardia
#
# How this design works. Each item is a 90 to 120 second excerpt of one
# record, shown 10 seconds at a time. The excerpt's own reference annotation
# file (.atr) loads as pre-annotations: rhythm episodes become intervals in
# the "rhythm" scheme, and beat labels become point events in the "beats"
# scheme. Review them, move or delete what you disagree with, add what is
# missing, and press "Keep these" (or make any edit) to save them as your
# answer. The two schemes are separate because "N" is both a beat symbol and
# a rhythm code, and Potato does not allow one label name twice in a scheme.
#
# Adaptations:
#   - The items are excerpts, not whole half-hour records. Nine of the ten
#     excerpt annotation files start with an added rhythm label at 0 s that
#     carries the rhythm in force when the excerpt begins; the original
#     records have no such label at that time. mitdb_001 starts at the
#     beginning of record 100, whose own rhythm label falls 0.05 s in. Beat and rhythm labels inside the excerpt
#     keep their original positions, shifted by the excerpt's start time.
#   - The reference labels are shown as pre-annotations. The original
#     protocol started from a detector's beat marks, and the cardiologists
#     worked on paper charts. This design is a review-and-correct task over
#     the released reference labels, so agreement with the reference is not
#     a measure of annotator accuracy for blind labeling.
#   - The "beats" scheme offers the 20 beat symbols above. The reference
#     files also hold signal quality changes (~) and comments ("), which
#     this scheme does not offer, so they are not shown and not saved.
#   - The "rhythm" scheme offers all 15 rhythm codes. The ten excerpts
#     contain N, B, T, VT, VFL, IVR, AFIB, AFL, NOD, AB, SVTA and P. They
#     contain no SBR, BII or PREX.
#   - Both ECG channels are drawn, as the records carry them (MLII and one
#     of V1 or V5).
#
# Model-assisted rhythm labeling (signal-cnn). The model_training block turns
# on training and writeback and names no trainer. Open /admin/training, pick
# signal-cnn for the "rhythm" scheme, and train. In free mode it labels the
# recording sample by sample from both channels, resampled to 100 Hz, trains
# on random 30-second crops, and merges runs of one label into intervals.
# Potato never writes a prediction onto an item the model trained on, and the
# signal display shows a model's intervals only for a recording whose file
# and item supply none of their own (signal_routes.signal_preannotations).
# Every excerpt here carries a .atr annotation file, so no dashed model
# proposal appears; the loop shows training and held-out scoring on
# /admin/training. To see a proposal, use an excerpt without its .atr file.
# It learns from the "rhythm"
# intervals only. It ignores the "beats" point events (kind: event), so
# beat labels are never trained or predicted. The reference labels count as
# training labels only after an annotator saves them (press "Keep these" or
# edit), because they otherwise stay pre-annotations. It needs at least 3 annotated
# recordings in its training split (min_instances) and the extras from
# `pip install "potato-annotation[train-vision,signals]"`. It does not serve
# or deploy a model. Ten short excerpts from nine records are enough to
# exercise the loop, not to learn arrhythmia classification that generalizes.
#
# Run: potato start config.yaml -p 8000

port: 8000
annotation_task_name: "MIT-BIH Arrhythmia: review rhythm episodes and beats"
task_dir: "."
media_directory: media

data_files:
  - sample-data.json

item_properties:
  id_key: id
  text_key: note

output_annotation_dir: annotation_output
export_annotation_format: jsonl

require_password: false
admin_api_key: "demo-admin-key"

user_config:
  allow_all_users: true

instance_display:
  fields:
    - key: note
      type: text
      label: "Excerpt"
    - key: signal
      type: time_series
      label: "Two-channel ECG (360 Hz)"
      display_options:
        window: 10
        lane_height: 130
        annotation_extension: atr

annotation_schemes:
  - annotation_type: interval_label
    name: rhythm
    description: "Rhythm episodes. Pick a rhythm, then drag across the plot to mark where it starts and ends. Loaded episodes are the reference labels; adjust them."
    signal_field: signal
    mode: free
    allow_overlap: false
    labels:
      - {name: "N", key_value: "1", tooltip: "(N Normal sinus rhythm"}
      - {name: "SBR", key_value: "2", tooltip: "(SBR Sinus bradycardia"}
      - {name: "AB", key_value: "3", tooltip: "(AB Atrial bigeminy"}
      - {name: "AFIB", key_value: "4", tooltip: "(AFIB Atrial fibrillation"}
      - {name: "AFL", key_value: "5", tooltip: "(AFL Atrial flutter"}
      - {name: "B", key_value: "6", tooltip: "(B Ventricular bigeminy"}
      - {name: "BII", key_value: "7", tooltip: "(BII 2° heart block"}
      - {name: "IVR", key_value: "8", tooltip: "(IVR Idioventricular rhythm"}
      - {name: "NOD", key_value: "9", tooltip: "(NOD Nodal (A-V junctional) rhythm"}
      - {name: "P", key_value: "0", tooltip: "(P Paced rhythm"}
      - {name: "PREX", key_value: "p", tooltip: "(PREX Pre-excitation (WPW)"}
      - {name: "SVTA", key_value: "s", tooltip: "(SVTA Supraventricular tachyarrhythmia"}
      - {name: "T", key_value: "t", tooltip: "(T Ventricular trigeminy"}
      - {name: "VFL", key_value: "f", tooltip: "(VFL Ventricular flutter"}
      - {name: "VT", key_value: "v", tooltip: "(VT Ventricular tachycardia"}

  - annotation_type: interval_label
    name: beats
    description: "Beat labels. Pick a beat symbol, then click the R wave to mark one beat. Loaded beats are the reference labels; correct any you disagree with."
    signal_field: signal
    mode: free
    labels:
      - {name: "N", key_value: "n", kind: event, tooltip: "Normal beat"}
      - {name: "L", key_value: "l", kind: event, tooltip: "Left bundle branch block beat"}
      - {name: "R", key_value: "r", kind: event, tooltip: "Right bundle branch block beat"}
      - {name: "A", key_value: "a", kind: event, tooltip: "Atrial premature beat"}
      - {name: "a", key_value: "b", kind: event, tooltip: "Aberrated atrial premature beat"}
      - {name: "J", key_value: "j", kind: event, tooltip: "Nodal (junctional) premature beat"}
      - {name: "S", key_value: "u", kind: event, tooltip: "Supraventricular premature beat"}
      - {name: "V", key_value: "w", kind: event, tooltip: "Premature ventricular contraction"}
      - {name: "F", key_value: "x", kind: event, tooltip: "Fusion of ventricular and normal beat"}
      - {name: "[", key_value: "c", kind: event, tooltip: "Start of ventricular flutter/fibrillation"}
      - {name: "!", key_value: "g", kind: event, tooltip: "Ventricular flutter wave"}
      - {name: "]", key_value: "h", kind: event, tooltip: "End of ventricular flutter/fibrillation"}
      - {name: "e", key_value: "e", kind: event, tooltip: "Atrial escape beat"}
      - {name: "j", key_value: "k", kind: event, tooltip: "Nodal (junctional) escape beat"}
      - {name: "E", key_value: "d", kind: event, tooltip: "Ventricular escape beat"}
      - {name: "/", key_value: "o", kind: event, tooltip: "Paced beat"}
      - {name: "f", key_value: "i", kind: event, tooltip: "Fusion of paced and normal beat"}
      - {name: "x", key_value: "y", kind: event, tooltip: "Non-conducted P-wave (blocked APB)"}
      - {name: "Q", key_value: "q", kind: event, tooltip: "Unclassifiable beat"}
      - {name: "|", key_value: "z", kind: event, tooltip: "Isolated QRS-like artifact"}

model_training:
  enabled: true
  writeback:
    # Show the rhythm scheme's predictions to annotators as pre-annotations.
    # Beat events are not predicted by signal-cnn.
    schemas: ["rhythm"]
    include_unlabeled: true
    min_confidence: 0.6

annotation_instructions: |
  Each item is a 90 to 120 second excerpt from a two-channel ambulatory ECG
  (MIT-BIH Arrhythmia Database), shown 10 seconds at a time. The reference
  labels load as a starting point. In "rhythm", each episode runs from one
  rhythm change to the next. In "beats", each point sits on one beat.
  Correct what you disagree with, add what is missing, and press "Keep
  these" to save the labels. The two-letter and longer codes are the
  database's own rhythm abbreviations, and the single characters are its
  beat symbols; hover a button for the meaning.

Sample Data

json
[
  {
    "id": "mitdb_001",
    "note": "Record 100, 0 to 90 s of the original recording (from the randomly selected group, normal sinus rhythm with one atrial premature beat)",
    "signal": "mitdb_001.hea"
  },
  {
    "id": "mitdb_002",
    "note": "Record 106, 150 to 240 s (ventricular bigeminy and a short ventricular tachycardia)",
    "signal": "mitdb_002.hea"
  }
]

// ... and 8 more items

Dataset & paper

Moody and Mark, IEEE Engineering in Medicine and Biology Magazine 2001

Paper DOI
10.1109/51.932724
Dataset DOI
10.13026/C2F305

Citation (BibTeX)

bibtex
@article{Moody_2001,
  title={The impact of the MIT-BIH Arrhythmia Database},
  volume={20},
  ISSN={0739-5175},
  url={http://dx.doi.org/10.1109/51.932724},
  DOI={10.1109/51.932724},
  number={3},
  journal={IEEE Engineering in Medicine and Biology Magazine},
  publisher={Institute of Electrical and Electronics Engineers (IEEE)},
  author={Moody, G.B. and Mark, R.G.},
  year={2001},
  pages={45--50}
}

Details

Annotation Types

interval_label

Domain

CardiologyPhysiologyBiomedical signal processing

Use Cases

Arrhythmia annotationECG rhythm reviewPhysiological signal annotation

Tags

mit-bih arrhythmia databasemit-bihmitdbecgarrhythmiarhythm episodesbeat annotationwfdbtime seriesphysionet

Found an issue or want to improve this design?

Open an Issue(opens in a new tab)