or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

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

0

# WFDB Python Package

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: wfdb

7

- **Language**: Python

8

- **Installation**: `pip install wfdb`

9

- **Documentation**: https://wfdb.readthedocs.io/

10

- **Repository**: https://github.com/MIT-LCP/wfdb-python

11

12

## Core Imports

13

14

```python

15

import wfdb

16

```

17

18

Common patterns for specific functionality:

19

20

```python

21

# Core I/O operations

22

from wfdb import rdrecord, rdann, wrsamp, wrann

23

24

# Signal processing (must use module path)

25

import wfdb.processing

26

# Then use: wfdb.processing.xqrs_detect, wfdb.processing.find_peaks

27

28

# Plotting

29

from wfdb.plot import plot_wfdb, plot_items

30

31

# Format conversion (must use module path)

32

import wfdb.io.convert

33

# Then use: wfdb.io.convert.read_edf, wfdb.io.convert.wfdb_to_mat

34

```

35

36

## Basic Usage

37

38

```python

39

import wfdb

40

import numpy as np

41

42

# Read a WFDB record from PhysioNet

43

record = wfdb.rdrecord('100', pn_dir='mitdb')

44

print(f"Record: {record.record_name}")

45

print(f"Signals: {record.sig_name}")

46

print(f"Length: {record.sig_len} samples at {record.fs} Hz")

47

48

# Read annotations

49

annotation = wfdb.rdann('100', 'atr', pn_dir='mitdb')

50

print(f"Found {len(annotation.sample)} annotations")

51

52

# Plot the first 3600 samples (10 seconds at 360 Hz)

53

wfdb.plot_wfdb(record=record, annotation=annotation,

54

time_units='seconds', title='ECG Record 100')

55

56

# Detect QRS complexes

57

qrs_inds = wfdb.processing.xqrs_detect(record.p_signal[:, 0], fs=record.fs)

58

print(f"Detected {len(qrs_inds)} QRS complexes")

59

60

# Calculate heart rate

61

hr = wfdb.processing.compute_hr(record.sig_len, qrs_inds, record.fs)

62

print(f"Mean heart rate: {np.mean(hr):.1f} BPM")

63

```

64

65

## Architecture

66

67

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

68

69

- **I/O Module**: Core data structures (Record, MultiRecord, Annotation) and functions for reading/writing WFDB files, database access, and data source management

70

- **Processing Module**: Signal processing algorithms including resampling, filtering, peak detection, QRS detection, and heart rate analysis

71

- **Plotting Module**: Visualization tools for signals and annotations with matplotlib integration

72

- **Conversion Module**: Format conversion utilities for EDF, MATLAB, CSV, WAV, and other common biomedical data formats

73

74

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

75

76

## Capabilities

77

78

### I/O Operations

79

80

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

81

82

```python { .api }

83

def rdrecord(record_name: str, sampfrom: int = 0, sampto: Union[int, str] = None,

84

channels: List[int] = None, physical: bool = True,

85

pn_dir: str = None) -> Union[Record, MultiRecord]: ...

86

87

def rdann(record_name: str, extension: str, sampfrom: int = 0,

88

sampto: Union[int, str] = 'end', pn_dir: str = None) -> Annotation: ...

89

90

def wrsamp(record_name: str, fs: float, units: List[str], sig_name: List[str],

91

p_signal: np.ndarray = None, **kwargs) -> None: ...

92

93

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

94

95

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

96

97

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

98

99

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

100

101

def show_ann_labels() -> None: ...

102

103

def show_ann_classes() -> None: ...

104

105

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

106

107

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

108

109

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

110

111

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

112

113

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

114

115

def show_data_sources() -> None: ...

116

117

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

118

119

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

120

121

def reset_data_sources() -> None: ...

122

123

class Record:

124

record_name: str

125

n_sig: int

126

fs: float

127

sig_len: int

128

p_signal: np.ndarray

129

sig_name: List[str]

130

units: List[str]

131

132

class Annotation:

133

record_name: str

134

sample: np.ndarray

135

symbol: List[str]

136

fs: float

137

```

138

139

[I/O Operations](./io-operations.md)

140

141

### Signal Processing

142

143

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

144

145

```python { .api }

146

def xqrs_detect(sig: np.ndarray, fs: float, sampfrom: int = 0, sampto: str = "end",

147

conf: str = None, learn: bool = True, verbose: bool = True) -> np.ndarray: ...

148

149

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

150

151

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

152

153

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

154

155

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

156

157

class XQRS:

158

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

159

```

160

161

[Signal Processing](./signal-processing.md)

162

163

### Plotting and Visualization

164

165

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

166

167

```python { .api }

168

def plot_wfdb(record: Record = None, annotation: Annotation = None,

169

plot_sym: bool = False, time_units: str = 'seconds', **kwargs) -> None: ...

170

171

def plot_items(signal: np.ndarray = None, ann_samp: List[int] = None,

172

fs: float = None, time_units: str = "samples", **kwargs) -> None: ...

173

174

def plot_all_records(records: List[str], annotation: List[str] = None,

175

**kwargs) -> None: ...

176

```

177

178

[Plotting](./plotting.md)

179

180

### Format Conversion

181

182

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

183

184

```python { .api }

185

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

186

187

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

188

189

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

190

191

def csv_to_wfdb(file_name: str, fs: float, units: List[str],

192

sig_name: List[str], **kwargs) -> None: ...

193

```

194

195

[Format Conversion](./format-conversion.md)

196

197

## Types

198

199

```python { .api }

200

class Record:

201

"""Single-segment WFDB record representation."""

202

record_name: str

203

n_sig: int

204

fs: float

205

sig_len: int

206

p_signal: np.ndarray # Physical signal values (MxN array)

207

d_signal: np.ndarray # Digital signal values (MxN array)

208

sig_name: List[str] # Signal names for each channel

209

units: List[str] # Units for each channel

210

comments: List[str] # Header comments

211

base_time: datetime.time

212

base_date: datetime.date

213

214

def wrsamp(self, expanded: bool = False, write_dir: str = "") -> None: ...

215

def to_dataframe(self) -> pd.DataFrame: ...

216

217

class MultiRecord:

218

"""Multi-segment WFDB record representation."""

219

segments: List[Union[Record, None]]

220

layout: str # "fixed" or "variable"

221

seg_name: List[str]

222

seg_len: List[int]

223

224

def multi_to_single(self, physical: bool, return_res: int = 64) -> Record: ...

225

226

class Annotation:

227

"""WFDB annotation representation."""

228

record_name: str

229

extension: str

230

sample: np.ndarray # Annotation sample locations

231

symbol: List[str] # Annotation symbols

232

fs: float # Sampling frequency

233

aux_note: List[str] # Auxiliary notes

234

235

def wrann(self, write_fs: bool = False, write_dir: str = "") -> None: ...

236

237

class DataSource:

238

"""Data source configuration."""

239

name: str

240

ds_type: DataSourceType # LOCAL or HTTP

241

uri: str

242

243

class XQRS:

244

"""Configurable QRS detector."""

245

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

246

247

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

248

```