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
Clone or download from the repository
Quick start:
git clone https://github.com/davidjurgens/potato-showcase.git
cd potato-showcase/science/physiology/mit-bih-arrhythmia-rhythm-episodes
potato start config.yamlAbout 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-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
[
{
"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 itemsGet This Design
Clone or download from the repository
Quick start:
git clone https://github.com/davidjurgens/potato-showcase.git
cd potato-showcase/science/physiology/mit-bih-arrhythmia-rhythm-episodes
potato start config.yamlDataset & 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)
@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
Domain
Use Cases
Tags
Found an issue or want to improve this design?
Open an Issue(opens in a new tab)Related Designs
PAMAP2 Activity Interval Labels on Wearable Sensor Signals
Review and correct activity intervals on ten real wrist IMU and heart-rate excerpts, with interval_label pre-annotations from the dataset and signal-cnn.
PhysioNet 2018 AASM Sleep Stage and Typed Arousal Scoring
Score two-minute polysomnogram excerpts with AASM sleep stages in 30-second epochs, then mark typed arousal and respiratory events, using ten real excerpts.
Sleep-EDF Sleep Stage Scoring in 30-Second Epochs
Score ten real overnight polysomnogram excerpts one 30-second epoch at a time with Rechtschaffen and Kales stages, using epoch-mode intervals and signal-cnn.