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
Overview
Eval results
Files

edf-reading.mddocs/

EDF File Reading

High-level interface for reading EDF, EDF+, BDF, and BDF+ files with comprehensive support for signal data extraction, annotation reading, and header information access. The EdfReader class provides Python-friendly methods with automatic resource management.

Capabilities

File Opening and Closing

Open EDF files with various reading options and automatic resource management through context managers.

class EdfReader:
    def __init__(self, file_name: str, annotations_mode: int = READ_ALL_ANNOTATIONS, 
                 check_file_size: int = CHECK_FILE_SIZE):
        """
        Initialize EDF reader.
        
        Parameters:
        - file_name: str, path to EDF/BDF file
        - annotations_mode: int, annotation reading mode (DO_NOT_READ_ANNOTATIONS, READ_ANNOTATIONS, READ_ALL_ANNOTATIONS)
        - check_file_size: int, file size checking mode (CHECK_FILE_SIZE, DO_NOT_CHECK_FILE_SIZE, REPAIR_FILE_SIZE_IF_WRONG)
        """

    def __enter__(self) -> EdfReader:
        """Context manager entry."""

    def __exit__(self, exc_type, exc_val, exc_tb):
        """Context manager exit with automatic cleanup."""

    def close(self):
        """Close file handler and release resources."""

Usage example:

# Using context manager (recommended)
with pyedflib.EdfReader('data.edf') as f:
    # Work with file
    signals = f.readSignal(0)

# Manual management
f = pyedflib.EdfReader('data.edf')
try:
    signals = f.readSignal(0)
finally:
    f.close()

Signal Data Reading

Read signal data from individual channels with support for partial reading, digital/physical values, and numpy array output.

def readSignal(self, chn: int, start: int = 0, n: Optional[int] = None, 
               digital: bool = False) -> np.ndarray:
    """
    Read signal data from specified channel.
    
    Parameters:
    - chn: int, channel number (0-based)
    - start: int, starting sample index
    - n: int or None, number of samples to read (None = all remaining)
    - digital: bool, return digital values if True, physical values if False
    
    Returns:
    numpy.ndarray: Signal data
    """

def getNSamples(self) -> np.ndarray:
    """
    Get number of samples for each signal.
    
    Returns:
    numpy.ndarray: Array of sample counts per channel
    """

Usage example:

with pyedflib.EdfReader('recording.edf') as f:
    # Read entire signal from channel 0
    signal = f.readSignal(0)
    
    # Read partial signal (samples 1000-2000)
    partial = f.readSignal(0, start=1000, n=1000)
    
    # Read digital values instead of physical
    digital_signal = f.readSignal(0, digital=True)
    
    # Get sample counts for all channels
    sample_counts = f.getNSamples()

Annotation Reading

Extract annotations (events, markers) from EDF+ and BDF+ files with timing information and descriptions.

def readAnnotations(self) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
    """
    Read all annotations from file.
    
    Returns:
    Tuple containing:
    - onset_times: numpy.ndarray, annotation start times in seconds
    - durations: numpy.ndarray, annotation durations in seconds  
    - descriptions: numpy.ndarray, annotation text descriptions
    """

Usage example:

with pyedflib.EdfReader('annotated.edf') as f:
    onsets, durations, descriptions = f.readAnnotations()
    
    # Process annotations
    for i in range(len(onsets)):
        print(f"Event at {onsets[i]}s, duration {durations[i]}s: {descriptions[i]}")

Header Information Access

Retrieve comprehensive file and signal header information including patient data, recording details, and signal parameters.

def getHeader(self) -> Dict:
    """
    Get complete file header as dictionary.
    
    Returns:
    dict: File header with patient info, recording details, technical data
    """

def getSignalHeader(self, chn: int) -> Dict:
    """
    Get header information for specific signal.
    
    Parameters:
    - chn: int, channel number
    
    Returns:
    dict: Signal header with label, units, sampling rate, calibration
    """

def getSignalHeaders(self) -> List[Dict]:
    """
    Get headers for all signals.
    
    Returns:
    List[dict]: List of signal headers
    """

Patient and Recording Information

Access patient demographics, recording metadata, and technical details.

def getPatientName(self) -> str:
    """Get patient name."""

def getPatientCode(self) -> str:
    """Get patient identification code."""

def getPatientAdditional(self) -> str:
    """Get additional patient information."""

def getSex(self) -> str:
    """Get patient sex/gender."""

def getBirthdate(self, string: bool = True) -> Union[str, datetime]:
    """
    Get patient birthdate.
    
    Parameters:
    - string: bool, return as string if True, datetime object if False
    
    Returns:
    str or datetime: Patient birthdate
    """

def getTechnician(self) -> str:
    """Get technician name."""

def getEquipment(self) -> str:
    """Get recording equipment information."""

def getAdmincode(self) -> str:
    """Get administration code."""

def getRecordingAdditional(self) -> str:
    """Get additional recording information."""

def getStartdatetime(self) -> datetime:
    """Get recording start date and time."""

def getFileDuration(self) -> float:
    """
    Get total file duration in seconds.
    
    Returns:
    float: Duration in seconds
    """

Signal Properties

Access signal-specific properties including labels, sampling rates, and calibration parameters.

def getSignalLabels(self) -> List[str]:
    """
    Get labels for all signals.
    
    Returns:
    List[str]: Signal labels
    """

def getLabel(self, chn: int) -> str:
    """
    Get label for specific channel.
    
    Parameters:
    - chn: int, channel number
    
    Returns:
    str: Signal label
    """

def getSampleFrequencies(self) -> np.ndarray:
    """
    Get sampling frequencies for all signals.
    
    Returns:
    numpy.ndarray: Sample rates in Hz
    """

def getSampleFrequency(self, chn: int) -> float:
    """
    Get sampling frequency for specific channel.
    
    Parameters:
    - chn: int, channel number
    
    Returns:
    float: Sample rate in Hz
    """

def getPhysicalMaximum(self, chn: Optional[int] = None) -> Union[float, np.ndarray]:
    """
    Get physical maximum values.
    
    Parameters:
    - chn: int or None, channel number (None = all channels)
    
    Returns:
    float or numpy.ndarray: Physical maximum value(s)
    """

def getPhysicalMinimum(self, chn: Optional[int] = None) -> Union[float, np.ndarray]:
    """
    Get physical minimum values.
    
    Parameters:
    - chn: int or None, channel number (None = all channels)
    
    Returns:
    float or numpy.ndarray: Physical minimum value(s)
    """

def getDigitalMaximum(self, chn: Optional[int] = None) -> Union[int, np.ndarray]:
    """
    Get digital maximum values.
    
    Parameters:
    - chn: int or None, channel number (None = all channels)
    
    Returns:
    int or numpy.ndarray: Digital maximum value(s)
    """

def getDigitalMinimum(self, chn: Optional[int] = None) -> Union[int, np.ndarray]:
    """
    Get digital minimum values.
    
    Parameters:
    - chn: int or None, channel number (None = all channels)
    
    Returns:
    int or numpy.ndarray: Digital minimum value(s)
    """

def getPhysicalDimension(self, chn: int) -> str:
    """
    Get physical dimension (units) for channel.
    
    Parameters:
    - chn: int, channel number
    
    Returns:
    str: Physical dimension (e.g., 'uV', 'mV')
    """

def getTransducer(self, chn: int) -> str:
    """
    Get transducer information for channel.
    
    Parameters:
    - chn: int, channel number
    
    Returns:
    str: Transducer description
    """

def getPrefilter(self, chn: int) -> str:
    """
    Get prefilter information for channel.
    
    Parameters:
    - chn: int, channel number
    
    Returns:
    str: Prefilter description
    """

File Properties

Access file-level properties for quick information retrieval.

@property
def signals_in_file(self) -> int:
    """Number of signals in the file."""

@property
def datarecords_in_file(self) -> int:
    """Number of data records in the file."""

@property
def file_duration(self) -> float:
    """File duration in seconds."""

@property
def filetype(self) -> int:
    """File type (EDF=0, EDF+=1, BDF=2, BDF+=3)."""

@property
def datarecord_duration(self) -> float:
    """Duration of each data record in seconds."""

@property
def annotations_in_file(self) -> int:
    """Number of annotations in the file."""

Usage example:

with pyedflib.EdfReader('data.edf') as f:
    # Access file properties
    print(f"Signals: {f.signals_in_file}")
    print(f"Duration: {f.file_duration} seconds")
    print(f"File type: {f.filetype}")
    print(f"Data records: {f.datarecords_in_file}")
    print(f"Annotations: {f.annotations_in_file}")

Information Display

Convenient methods for displaying file information.

def file_info(self):
    """Print basic file information to console."""

def file_info_long(self):
    """Print detailed file information to console."""

Usage example:

with pyedflib.EdfReader('data.edf') as f:
    # Display file info
    f.file_info()
    
    # Get detailed properties
    header = f.getHeader()
    labels = f.getSignalLabels()
    sample_rates = f.getSampleFrequencies()
    
    print(f"Patient: {f.getPatientName()}")
    print(f"Recording duration: {f.getFileDuration()} seconds")
    print(f"Channels: {labels}")
    print(f"Sample rates: {sample_rates}")

Constants

# Annotation reading modes
DO_NOT_READ_ANNOTATIONS: int = 0
READ_ANNOTATIONS: int = 1  
READ_ALL_ANNOTATIONS: int = 2

# File size checking modes  
CHECK_FILE_SIZE: int = 0
DO_NOT_CHECK_FILE_SIZE: int = 1
REPAIR_FILE_SIZE_IF_WRONG: int = 2

Install with Tessl CLI

npx tessl i tessl/pypi-pyedflib

docs

edf-reading.md

edf-writing.md

high-level-functions.md

index.md

low-level-interface.md

tile.json