Skip to content

AI4HealthUOL/s4ecg

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

S4ECG — Structured State Spaces for ECG Arrhythmia Detection

Official code for Multi-Window Temporal Analysis for Enhanced Arrhythmia Classification: Leveraging Long-Range Dependencies in Electrocardiogram Signals (Physiological Measurement, 2026).

Overview

S4ECG applies hierarchical Structured State Space (S4) models to beat-level arrhythmia detection from long, single-lead ECG recordings. By jointly analyzing multiple consecutive 30-second ECG windows (up to 15 minutes), the architecture captures long-range temporal dependencies that isolated-window approaches miss. This multi-window strategy improves macro-averaged AUROC by 1.0–11.6 percentage points and reduces false positive rates for atrial fibrillation detection by 3–10×.

Architecture

Raw ECG (128 Hz, 1ch)
  └── EpochEncoder (CNN + S4)   → epoch-level features
       └── S4 Predictor         → sequence-level features
            └── MLP Head        → per-epoch arrhythmia labels (N / AFIB / AFL)

Installation

conda env create -f environment.yml
conda activate s4ecg

If the S4 layer requires custom CUDA kernels for the Cauchy operation:

cd extensions/cauchy && python setup.py install

Data Preparation

The model expects data in the memmap format produced by preprocessing/:

Dataset Use Records Source
LTAFDB In-distribution train/val/test 84 PhysioNet
Icentia11k In-distribution train/val/test 11,000 PhysioNet
MIT-BIH Out-of-distribution test 48 PhysioNet
AFDB Out-of-distribution test 25 PhysioNet

Each dataset folder should contain:

memmap.npy          # signal data  (samples × channels)
memmap_meta.npz     # memmap index
memmap_label.npy    # annotation labels
memmap_label_meta.npz
df_memmap.pkl       # DataFrame with fold assignments
lbl_itos.npy        # label names ['(N', '(AFIB', '(AFL', ...]
mean.npy / std.npy  # signal statistics

Quick Start

Training (in-distribution on LTAFDB)

python main.py --config-name=config_id_ltafdb trainer.gpus=1

Training (in-distribution on Icentia11k)

python main.py --config-name=config_id_icentia trainer.gpus=1

Out-of-distribution evaluation (MIT-BIH)

python main.py --config-name=config_ood_mitdb trainer.gpus=1 \
    trainer.eval_only=path/to/best_model.ckpt

Override parameters via CLI

python main.py --config-name=config_id_ltafdb \
    base.batch_size=32 \
    trainer.epochs=100 \
    trainer.gpus=1

Configuration

All experiment configs live under conf/. The main configs are:

Config Dataset Scenario
config_id_ltafdb LTAFDB In-distribution
config_id_icentia Icentia11k In-distribution
config_ood_mitdb MIT-BIH OOD evaluation

Key parameters:

Parameter Value Description
base.fs 128 Sampling frequency (Hz)
base.input_size 115200 Input window = 30s × 30 windows × 128 Hz (15 min)
base.input_channels 1 Single-lead ECG
label_aggregation_epoch_length 3840 30s epoch = 30 × 128
stride_valtest 3840 Evaluation stride (one 30s epoch)
loss bce Binary cross-entropy (multi-label)
metric auroc Area under ROC curve

Project Structure

s4ecg/
├── main.py                  # Hydra entry point
├── clinical_ts/             # Core library
│   ├── config.py            # Hydra ConfigStore registration
│   ├── template_model.py    # BaseModel / SSLModel (Lightning)
│   ├── template_modules.py  # Config dataclasses, encoder wiring
│   ├── task/ecg.py          # ECG-specific task class
│   ├── loss/supervised.py   # CE, BCE, focal losses
│   ├── metric/base.py       # AUROC, F1, accuracy, etc.
│   ├── data/                # Dataset loading & transforms
│   ├── ts/                  # Encoder, predictor, head modules
│   └── utils/               # Callbacks, schedulers, evaluation
├── conf/                    # Hydra configs
│   ├── config_id_ltafdb.yaml
│   ├── config_id_icentia.yaml
│   ├── config_ood_mitdb.yaml
│   ├── data/                # Per-dataset configs
│   ├── trainer/             # Training configs
│   └── ts/                  # Model component configs
├── extensions/cauchy/       # Custom CUDA kernel for S4
├── preprocessing/           # Data preprocessing scripts
├── datasplit/               # Cross-validation fold assignments
└── environment.yml          # Conda environment

Citation

@article{wang2026s4ecg,
  title={Multi-Window Temporal Analysis for Enhanced Arrhythmia Classification: Leveraging Long-Range Dependencies in Electrocardiogram Signals},
  author={Wang, Tiezhi and Haverkamp, Wilhelm and Strodthoff, Nils},
  journal={Physiological Measurement},
  volume={47},
  number={1},
  year={2026},
  publisher={IOP Publishing},
  doi={10.1088/1361-6579/ae3937},
  pmid={41539004}
}

License

MIT License — see LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages