or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

format-conversion.mdindex.mdio-operations.mdplotting.mdsignal-processing.md
tile.json

tessl/pypi-wfdb

Python package for reading, writing, and processing physiologic signals and annotations in WFDB format.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/wfdb@4.3.x

To install, run

npx @tessl/cli install tessl/pypi-wfdb@4.3.0

index.mddocs/

WFDB Python Package

A comprehensive Python-native package for reading, writing, processing, and plotting physiologic signals and annotations based on the Waveform Database (WFDB) specifications. This package provides complete tooling for biomedical signal analysis, including integration with NumPy, SciPy, Pandas, and Matplotlib for the Python scientific ecosystem.

Package Information

  • Package Name: wfdb
  • Language: Python
  • Installation: pip install wfdb
  • Documentation: https://wfdb.readthedocs.io/
  • Repository: https://github.com/MIT-LCP/wfdb-python

Core Imports

import wfdb

Common patterns for specific functionality:

# Core I/O operations
from wfdb import rdrecord, rdann, wrsamp, wrann

# Signal processing (must use module path)
import wfdb.processing
# Then use: wfdb.processing.xqrs_detect, wfdb.processing.find_peaks

# Plotting
from wfdb.plot import plot_wfdb, plot_items

# Format conversion (must use module path)
import wfdb.io.convert
# Then use: wfdb.io.convert.read_edf, wfdb.io.convert.wfdb_to_mat

Basic Usage

import wfdb
import numpy as np

# Read a WFDB record from PhysioNet
record = wfdb.rdrecord('100', pn_dir='mitdb')
print(f"Record: {record.record_name}")
print(f"Signals: {record.sig_name}")
print(f"Length: {record.sig_len} samples at {record.fs} Hz")

# Read annotations
annotation = wfdb.rdann('100', 'atr', pn_dir='mitdb')
print(f"Found {len(annotation.sample)} annotations")

# Plot the first 3600 samples (10 seconds at 360 Hz)
wfdb.plot_wfdb(record=record, annotation=annotation, 
               time_units='seconds', title='ECG Record 100')

# Detect QRS complexes
qrs_inds = wfdb.processing.xqrs_detect(record.p_signal[:, 0], fs=record.fs)
print(f"Detected {len(qrs_inds)} QRS complexes")

# Calculate heart rate
hr = wfdb.processing.compute_hr(record.sig_len, qrs_inds, record.fs)
print(f"Mean heart rate: {np.mean(hr):.1f} BPM")

Architecture

The WFDB package is organized into four main modules that handle different aspects of physiological signal processing:

  • I/O Module: Core data structures (Record, MultiRecord, Annotation) and functions for reading/writing WFDB files, database access, and data source management
  • Processing Module: Signal processing algorithms including resampling, filtering, peak detection, QRS detection, and heart rate analysis
  • Plotting Module: Visualization tools for signals and annotations with matplotlib integration
  • Conversion Module: Format conversion utilities for EDF, MATLAB, CSV, WAV, and other common biomedical data formats

This modular design enables efficient handling of large-scale physiological databases while maintaining compatibility with the original WFDB specifications and PhysioNet infrastructure.

Capabilities

I/O Operations

Core functionality for reading and writing WFDB records and annotations, including database access and data source management.

def rdrecord(record_name: str, sampfrom: int = 0, sampto: Union[int, str] = None, 
             channels: List[int] = None, physical: bool = True, 
             pn_dir: str = None) -> Union[Record, MultiRecord]: ...

def rdann(record_name: str, extension: str, sampfrom: int = 0, 
          sampto: Union[int, str] = 'end', pn_dir: str = None) -> Annotation: ...

def wrsamp(record_name: str, fs: float, units: List[str], sig_name: List[str],
           p_signal: np.ndarray = None, **kwargs) -> None: ...

def sampfreq(record_name: str, pn_dir: str = None) -> float: ...

def signame(record_name: str, pn_dir: str = None, sig_nums: List[int] = []) -> List[str]: ...

def wfdbdesc(record_name: str, pn_dir: str = None) -> List[str]: ...

def wfdbtime(record_name: str, input_times: Union[List, np.ndarray], pn_dir: str = None) -> List[str]: ...

def show_ann_labels() -> None: ...

def show_ann_classes() -> None: ...

def mrgann(record_name: str, extensions: List[str], pn_dir: str = None) -> None: ...

def dl_files(db: str, dl_dir: str, files: List[str], keep_subdirs: bool = True, overwrite: bool = False) -> None: ...

def get_dbs() -> List[str]: ...

def get_record_list(db_dir: str, records: str = "all") -> List[str]: ...

def set_db_index_url(db_index_url: str = None) -> None: ...

def show_data_sources() -> None: ...

def add_data_source(data_source: DataSource) -> None: ...

def remove_data_source(name: str) -> None: ...

def reset_data_sources() -> None: ...

class Record:
    record_name: str
    n_sig: int
    fs: float
    sig_len: int
    p_signal: np.ndarray
    sig_name: List[str]
    units: List[str]

class Annotation:
    record_name: str
    sample: np.ndarray
    symbol: List[str]
    fs: float

I/O Operations

Signal Processing

Comprehensive signal processing tools including resampling, filtering, peak detection, QRS detection, and heart rate analysis.

def xqrs_detect(sig: np.ndarray, fs: float, sampfrom: int = 0, sampto: str = "end", 
                conf: str = None, learn: bool = True, verbose: bool = True) -> np.ndarray: ...

def gqrs_detect(sig: np.ndarray, fs: float, **kwargs) -> np.ndarray: ...

def find_peaks(sig: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: ...

def compute_hr(sig_len: int, qrs_inds: np.ndarray, fs: float) -> np.ndarray: ...

def resample_sig(x: np.ndarray, fs: float, fs_target: float) -> Tuple[np.ndarray, np.ndarray]: ...

class XQRS:
    def detect(self, sig: np.ndarray, verbose: bool = False) -> np.ndarray: ...

Signal Processing

Plotting and Visualization

Tools for plotting physiological signals and annotations with customizable styling and multiple display options.

def plot_wfdb(record: Record = None, annotation: Annotation = None, 
              plot_sym: bool = False, time_units: str = 'seconds', **kwargs) -> None: ...

def plot_items(signal: np.ndarray = None, ann_samp: List[int] = None, 
               fs: float = None, time_units: str = "samples", **kwargs) -> None: ...

def plot_all_records(records: List[str], annotation: List[str] = None, 
                     **kwargs) -> None: ...

Plotting

Format Conversion

Utilities for converting between WFDB and other common biomedical data formats including EDF, MATLAB, CSV, and WAV.

def read_edf(file_name: str, pn_dir: str = None, **kwargs) -> Record: ...

def wfdb_to_edf(record_name: str, pn_dir: str = None, **kwargs) -> None: ...

def wfdb_to_mat(record_name: str, pn_dir: str = None, **kwargs) -> None: ...

def csv_to_wfdb(file_name: str, fs: float, units: List[str], 
                sig_name: List[str], **kwargs) -> None: ...

Format Conversion

Types

class Record:
    """Single-segment WFDB record representation."""
    record_name: str
    n_sig: int
    fs: float
    sig_len: int
    p_signal: np.ndarray  # Physical signal values (MxN array)
    d_signal: np.ndarray  # Digital signal values (MxN array)
    sig_name: List[str]   # Signal names for each channel
    units: List[str]      # Units for each channel
    comments: List[str]   # Header comments
    base_time: datetime.time
    base_date: datetime.date
    
    def wrsamp(self, expanded: bool = False, write_dir: str = "") -> None: ...
    def to_dataframe(self) -> pd.DataFrame: ...

class MultiRecord:
    """Multi-segment WFDB record representation."""
    segments: List[Union[Record, None]]
    layout: str  # "fixed" or "variable"
    seg_name: List[str]
    seg_len: List[int]
    
    def multi_to_single(self, physical: bool, return_res: int = 64) -> Record: ...

class Annotation:
    """WFDB annotation representation."""
    record_name: str
    extension: str
    sample: np.ndarray      # Annotation sample locations
    symbol: List[str]       # Annotation symbols
    fs: float              # Sampling frequency
    aux_note: List[str]    # Auxiliary notes
    
    def wrann(self, write_fs: bool = False, write_dir: str = "") -> None: ...

class DataSource:
    """Data source configuration."""
    name: str
    ds_type: DataSourceType  # LOCAL or HTTP
    uri: str

class XQRS:
    """Configurable QRS detector."""
    def detect(self, sig: np.ndarray, verbose: bool = False) -> np.ndarray: ...

DataSourceType = Literal["LOCAL", "HTTP"]