or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

edf-reading.mdedf-writing.mdhigh-level-functions.mdindex.mdlow-level-interface.md
tile.json

tessl/pypi-pyedflib

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

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/pyedflib@0.1.x

To install, run

npx @tessl/cli install tessl/pypi-pyedflib@0.1.0

index.mddocs/

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."""