CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyedflib

Python library for reading and writing EDF+/BDF+ files used for storing biomedical signal data

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

pyEDFlib

A Python library for reading and writing EDF+/BDF+ (European Data Format) files used for storing biomedical signal data such as EEG, ECG, and other physiological measurements. pyEDFlib provides both high-level Python interfaces and low-level C extensions for efficient file operations, making it essential for researchers and developers working with biomedical time-series data.

Package Information

  • Package Name: pyEDFlib
  • Language: Python
  • Installation: pip install pyEDFlib

Core Imports

import pyedflib

For high-level functions:

from pyedflib import highlevel
# or
import pyedflib.highlevel as hl

For data utilities:

from pyedflib import data
# or
import pyedflib.data

For specific classes and functions:

from pyedflib import EdfReader, EdfWriter
from pyedflib.highlevel import read_edf, write_edf

Basic Usage

import pyedflib
import numpy as np
from pyedflib import highlevel

# Reading an EDF file (low-level)
with pyedflib.EdfReader('sample.edf') as f:
    # Get basic file info
    n_channels = f.signals_in_file
    sample_freqs = f.getSampleFrequencies()
    signal_labels = f.getSignalLabels()
    
    # Read signal data
    signal_data = []
    for i in range(n_channels):
        signal_data.append(f.readSignal(i))

# Reading an EDF file (high-level)
signals, signal_headers, header = highlevel.read_edf('sample.edf')

# Writing an EDF file (low-level)
channel_info = [
    {'label': 'EEG Fp1', 'dimension': 'uV', 'sample_frequency': 100, 
     'physical_min': -500.0, 'physical_max': 500.0, 
     'digital_min': -2048, 'digital_max': 2047},
    {'label': 'EEG Fp2', 'dimension': 'uV', 'sample_frequency': 100,
     'physical_min': -500.0, 'physical_max': 500.0,
     'digital_min': -2048, 'digital_max': 2047}
]

with pyedflib.EdfWriter('output.edf', 2, file_type=pyedflib.FILETYPE_EDFPLUS) as f:
    f.setSignalHeaders(channel_info)
    
    # Write sample data
    data_ch1 = np.random.normal(0, 50, 1000)  # 10 seconds at 100 Hz
    data_ch2 = np.random.normal(0, 50, 1000)
    
    f.writeSamples([data_ch1, data_ch2])

# Writing an EDF file (high-level)
signals = np.random.normal(0, 50, (2, 1000))  # 2 channels, 1000 samples
signal_headers = highlevel.make_signal_headers(['EEG Fp1', 'EEG Fp2'], sample_frequency=100)
highlevel.write_edf('output.edf', signals, signal_headers)

Architecture

pyEDFlib is built on a layered architecture:

  • High-level Classes: EdfReader and EdfWriter provide Python-friendly interfaces with context managers, automatic resource management, and convenient methods
  • Low-level Extensions: Cython-based CyEdfReader and C extension functions offer direct access to the underlying EDFlib C library for maximum performance
  • High-level Functions: Convenience functions in pyedflib.highlevel for common operations like reading/writing entire files, file manipulation, and data conversion
  • Data Utilities: Test data and sample files in pyedflib.data for development and testing

This design enables both ease of use for common tasks and fine-grained control for performance-critical applications, while maintaining compatibility with the established EDF/BDF standards used in biomedical research.

Capabilities

EDF File Reading

High-level interface for reading EDF, EDF+, BDF, and BDF+ files with support for signal data extraction, annotation reading, and comprehensive header information access.

class EdfReader:
    def __enter__(self) -> EdfReader: ...
    def __exit__(self, exc_type, exc_val, exc_tb): ...
    def readSignal(self, chn: int, start: int = 0, n: Optional[int] = None, digital: bool = False) -> np.ndarray: ...
    def readAnnotations(self) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: ...
    def getHeader(self) -> Dict: ...
    def getSignalHeaders(self) -> List[Dict]: ...

EDF Reading

EDF File Writing

Interface for creating and writing EDF, EDF+, BDF, and BDF+ files with comprehensive header configuration, signal data writing, and annotation support.

class EdfWriter:
    def __init__(self, file_name: str, n_channels: int, file_type: int = FILETYPE_EDFPLUS): ...
    def __enter__(self) -> EdfWriter: ...
    def __exit__(self, exc_type, exc_val, exc_tb): ...
    def setSignalHeaders(self, signalHeaders: List[Dict]): ...
    def writeSamples(self, data_list: Union[List[np.ndarray], np.ndarray], digital: bool = False): ...
    def writeAnnotation(self, onset_in_seconds: Union[int, float], duration_in_seconds: Union[int, float], description: str): ...

EDF Writing

High-Level Operations

Convenience functions for complete file operations, data conversion, file manipulation, and batch processing tasks.

def read_edf(edf_file: str, ch_nrs: Optional[Union[List[int], int]] = None, 
             ch_names: Optional[Union[List[str], str]] = None, digital: bool = False, 
             verbose: bool = False) -> Tuple[Union[np.ndarray, List[np.ndarray]], List[dict], dict]: ...
def write_edf(edf_file: str, signals: Union[np.ndarray, List[np.ndarray]], signal_headers: List[Dict], 
              header: Optional[Dict] = None, digital: bool = False, 
              file_type: int = -1) -> bool: ...
def make_header(technician: str = '', recording_additional: str = '', patientname: str = '', 
                patient_additional: str = '', patientcode: str = '', equipment: str = '', 
                admincode: str = '', sex: str = '', startdate: Optional[datetime] = None, 
                birthdate: Union[str, datetime] = '') -> dict: ...
def make_signal_headers(list_of_labels: List[str], dimension: str = 'uV', 
                       sample_frequency: Optional[Union[int, float]] = 256, 
                       physical_min: float = -200.0, physical_max: float = 200.0) -> List[dict]: ...

High-level Functions

Low-Level Operations

Direct access to underlying C library functions for maximum performance and fine-grained control over file operations and data handling.

class CyEdfReader:
    def __init__(self, file_name: str, annotations_mode: int = READ_ANNOTATIONS, 
                 check_file_size: int = CHECK_FILE_SIZE): ...
    def read_digital_signal(self, signalnum: int, start: int, n: int, sigbuf: np.ndarray): ...
    def readsignal(self, signalnum: int, start: int, n: int, sigbuf: np.ndarray): ...

def open_file_writeonly(path: str, filetype: int, number_of_signals: int) -> int: ...
def write_physical_samples(handle: int, buf: np.ndarray) -> int: ...
def close_file(handle: int) -> int: ...

Low-level Interface

Data Utilities

Test data and sample files for development and testing.

def test_generator() -> EdfReader:
    """Get sample EDF file for testing."""

def get_generator_filename() -> str:
    """Get path to test EDF file."""

Constants

File Types

FILETYPE_EDF: int = 0        # Standard EDF format
FILETYPE_EDFPLUS: int = 1    # EDF+ format with annotations
FILETYPE_BDF: int = 2        # BDF format (24-bit)
FILETYPE_BDFPLUS: int = 3    # BDF+ format with annotations

Annotation Reading Options

DO_NOT_READ_ANNOTATIONS: int = 0    # Skip annotation reading
READ_ANNOTATIONS: int = 1           # Read some annotations
READ_ALL_ANNOTATIONS: int = 2       # Read all annotations

File Size Check Options

CHECK_FILE_SIZE: int = 0              # Verify file size
DO_NOT_CHECK_FILE_SIZE: int = 1       # Skip file size check
REPAIR_FILE_SIZE_IF_WRONG: int = 2    # Auto-repair incorrect file size

Error Dictionaries

open_errors: Dict[int, str]     # Error codes for file opening
write_errors: Dict[int, str]    # Error codes for file writing

Utility Functions

def lib_version() -> str:
    """Get underlying edflib C library version."""
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/pyedflib@0.1.x
Publish Source
CLI
Badge
tessl/pypi-pyedflib badge