### Install edfio Source: https://github.com/the-siesta-group/edfio/blob/main/README.md Use pip to install the package from PyPI. ```bash pip install edfio ``` -------------------------------- ### Install project dependencies with uv Source: https://github.com/the-siesta-group/edfio/blob/main/CONTRIBUTING.md Use 'uv sync' to create a virtual environment with Python 3.9 and install all project dependencies. Ensure commands are prefixed with 'uv run' when using uv. ```bash uv sync --python=3.9 ``` -------------------------------- ### Install pre-commit hooks Source: https://github.com/the-siesta-group/edfio/blob/main/CONTRIBUTING.md Install the git hooks configured in .pre-commit-config.yml. These hooks will automatically run code style and quality checks on staged files during commits. ```bash pre-commit install ``` -------------------------------- ### Get Annotations by Window Source: https://context7.com/the-siesta-group/edfio/llms.txt Retrieves annotations within a specific time range. ```python from edfio import read_edf edf = read_edf("long_recording.edf") # Get all annotations all_annotations = edf.annotations # Get annotations in a specific time window (seconds) window_annotations = edf.get_annotations(start_second=60, stop_second=120) for ann in window_annotations: print(f"{ann.onset}s: {ann.text}") ``` -------------------------------- ### Create EDF+ File with Optional Header Fields Source: https://github.com/the-siesta-group/edfio/blob/main/docs/source/examples.md Construct an EDF+ file, setting optional patient and recording header information. This example includes detailed signal properties and patient demographics. ```python import datetime import numpy as np from edfio import Edf, EdfSignal, Patient, Recording edf = Edf( [ EdfSignal( np.random.randn(30 * 256), sampling_frequency=256, label="EEG Fpz-Cz", transducer_type="AgAgCl electrode", physical_dimension="uV", prefiltering="HP:0.1Hz LP:75Hz", ), EdfSignal(np.random.randn(30), sampling_frequency=1, label="Body Temp"), ], patient=Patient( code="MCH-0234567", sex="F", birthdate=datetime.date(1951, 5, 2), name="Haagse_Harry", ), starttime=datetime.time(11, 25), ) edf.signals[1].transducer_type = "Thermistor" edf.signals[1].physical_dimension = "degC" edf.recording = Recording( startdate=datetime.date(2002, 2, 2), hospital_administration_code="EMG561", investigator_technician_code="BK/JOP", equipment_code="Sony", ) edf.write("example.edf") ``` -------------------------------- ### Edf.slice_between_seconds Source: https://context7.com/the-siesta-group/edfio/llms.txt Extracts a time segment from the recording by specifying the start and stop times in seconds. Optionally preserves all annotations. ```APIDOC ## Edf.slice_between_seconds ### Description Extracts a time segment from the recording by specifying start and stop times in seconds. ### Method ```python edf.slice_between_seconds(start, stop, keep_all_annotations=False) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **start** (float) - Required - The start time in seconds for the slice. - **stop** (float) - Required - The stop time in seconds for the slice. - **keep_all_annotations** (bool) - Optional - If True, all annotations are kept, even those outside the specified time slice. Defaults to False. ### Request Example ```python from edfio import read_edf edf = read_edf("recording.edf") # Extract segment from 10 to 60 seconds edf.slice_between_seconds(start=10, stop=60) # Keep annotations outside the slice edf_copy = read_edf("recording.edf") edf_copy.slice_between_seconds(start=10, stop=60, keep_all_annotations=True) ``` ### Response None (modifies the Edf object in-place) ### Response Example None ``` -------------------------------- ### Slice EDF Between Seconds Source: https://context7.com/the-siesta-group/edfio/llms.txt Extracts a segment of the EDF recording based on start and stop times in seconds. Optionally preserves all annotations. ```python from edfio import read_edf edf = read_edf("recording.edf") print(f"Original duration: {edf.duration} seconds") # Extract segment from 10 to 60 seconds edf.slice_between_seconds(start=10, stop=60) print(f"New duration: {edf.duration} seconds") # Keep annotations outside the slice edf_copy = read_edf("recording.edf") edf_copy.slice_between_seconds(start=10, stop=60, keep_all_annotations=True) edf.write("segment.edf") ``` -------------------------------- ### Recording Metadata Source: https://context7.com/the-siesta-group/edfio/llms.txt Represents and manages recording information according to EDF+ specifications, including start date, administrative codes, investigator details, equipment, and additional information. ```APIDOC ## Recording ### Description Represents recording information according to EDF+ specifications. ### Method ```python Recording(startdate, hospital_administration_code, investigator_technician_code, equipment_code, additional) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **startdate** (datetime.date) - Required - The date the recording started. - **hospital_administration_code** (str) - Optional - Code for hospital administration. - **investigator_technician_code** (str) - Optional - Code for the investigator or technician. - **equipment_code** (str) - Optional - Code for the recording equipment used. - **additional** (list[str]) - Optional - A list of additional recording-related information. ### Request Example ```python import datetime from edfio import Edf, EdfSignal, Recording import numpy as np # Create recording with full information recording = Recording( startdate=datetime.date(2024, 3, 15), hospital_administration_code="PSG-2024-001", investigator_technician_code="Dr_Smith", equipment_code="Nihon_Kohden", additional=["Room_101", "Night_Study"], ) # Create EDF with recording info edf = Edf( [EdfSignal(np.random.randn(256), sampling_frequency=256)], recording=recording, ) # Access recording information from edfio import read_edf edf = read_edf("recording.edf") print(f"Hospital code: {edf.recording.hospital_administration_code}") print(f"Equipment: {edf.recording.equipment_code}") try: print(f"Start date: {edf.recording.startdate}") except Exception: print("Start date anonymized") # Modify recording edf.recording = Recording( startdate=datetime.date(2024, 1, 1), hospital_administration_code="EEG-001", ) ``` ### Response None ### Response Example None ``` -------------------------------- ### Read EDF File Source: https://context7.com/the-siesta-group/edfio/llms.txt Reads an EDF file from various sources including file paths, Path objects, or raw bytes. Supports lazy loading by default and allows specifying header encoding. Access basic file information like duration, number of signals, labels, start time, and date. ```python from pathlib import Path from edfio import read_edf # Read from file path (lazy loading enabled by default) edf = read_edf("recording.edf") # Read from Path object edf = read_edf(Path("~/data/recording.edf")) # Read from bytes with open("recording.edf", "rb") as f: edf = read_edf(f.read()) # Disable lazy loading to load all data immediately edf = read_edf("recording.edf", lazy_load_data=False) # Read files with non-ASCII header encoding edf = read_edf("recording.edf", header_encoding="latin-1") # Access basic information print(f"Duration: {edf.duration} seconds") print(f"Number of signals: {edf.num_signals}") print(f"Signal labels: {edf.labels}") print(f"Start time: {edf.starttime}") print(f"Start date: {edf.startdate}") ``` -------------------------------- ### Slice EDF Between Annotations Source: https://context7.com/the-siesta-group/edfio/llms.txt Extracts a time segment from an EDF file defined by the start and end text of annotation markers. Annotations must be unique for reliable slicing. Optionally preserves all annotations. ```python from edfio import read_edf edf = read_edf("annotated_recording.edf") # Slice between annotation texts (must be unique) edf.slice_between_annotations( start_text="Trial Start", stop_text="Trial End", ) # Keep all annotations (including those outside the slice) edf.slice_between_annotations( start_text="Epoch Begin", stop_text="Epoch End", keep_all_annotations=True, ) edf.write("trial_segment.edf") ``` -------------------------------- ### Anonymize EDF Header Information Source: https://context7.com/the-siesta-group/edfio/llms.txt Removes or modifies identifying information in the EDF header for privacy. Supports full anonymization or partial preservation of specific fields like age, sex, and start time. ```python from edfio import read_edf edf = read_edf("recording.edf") # Full anonymization edf.anonymize() # Sets: patient identification to "X X X X" # Sets: recording identification to "Startdate X X X X" # Sets: startdate to 01.01.85 # Sets: starttime to 00.00.00 # Partial anonymization - keep some information edf_partial = read_edf("recording.edf") edf_partial.anonymize( keep_age=True, # Preserve age relative to anonymized date keep_sex=True, # Keep sex field keep_starttime=True # Keep original recording time ) edf.write("anonymized.edf") ``` -------------------------------- ### Create EDF+ File with Annotations Source: https://github.com/the-siesta-group/edfio/blob/main/docs/source/examples.md Create an EDF+ file with multiple signals and EDF+ annotations. Ensure all necessary imports are present. ```python import numpy as np from edfio import Edf, EdfAnnotation, EdfSignal edf = Edf( [ EdfSignal(np.random.randn(30 * 256), sampling_frequency=256, label="EEG Fpz"), EdfSignal(np.random.randn(30), sampling_frequency=1, label="Body Temp"), ], annotations=[ EdfAnnotation(1, None, "Trial start"), EdfAnnotation(1.5, None, "Stimulus"), EdfAnnotation(2.5, 2, "Movement"), EdfAnnotation(10, None, "Trial end"), ] ) edf.write("example.edf") ``` -------------------------------- ### Create BDF File Source: https://context7.com/the-siesta-group/edfio/llms.txt Initializes a BDF file with 24-bit resolution for high dynamic range signals. ```python import numpy as np from edfio import Bdf, BdfSignal # Create BDF signal with 24-bit resolution signal = BdfSignal( data=np.random.randn(30 * 2048), sampling_frequency=2048, label="EEG", physical_dimension="uV", digital_range=(-8388608, 8388607), # 24-bit range (default for BDF) ) # Create and write BDF file bdf = Bdf([signal]) bdf.write("recording.bdf") ``` -------------------------------- ### Create and write an EDF file Source: https://github.com/the-siesta-group/edfio/blob/main/README.md Construct an Edf object with signals and write it to a file. ```python import numpy as np from edfio import Edf, EdfSignal edf = Edf( [ EdfSignal(np.random.randn(30 * 256), sampling_frequency=256, label="EEG Fpz"), EdfSignal(np.random.randn(30), sampling_frequency=1, label="Body Temp"), ] ) edf.write("example.edf") ``` -------------------------------- ### Run tests with coverage Source: https://github.com/the-siesta-group/edfio/blob/main/CONTRIBUTING.md Run tests and generate a code coverage report. Ensure all lines of code are covered by tests. ```bash pytest --cov ``` -------------------------------- ### Creating EdfSignal Objects Source: https://context7.com/the-siesta-group/edfio/llms.txt Explains how to create individual signal objects using the `EdfSignal` class, including specifying data, sampling frequency, and various metadata. ```APIDOC ## EdfSignal Creates a single EDF signal with physical data, sampling frequency, and metadata. Signal data is stored as 16-bit integers internally. ### Method POST (conceptual, as it's a creation operation) ### Endpoint `EdfSignal(data, sampling_frequency, label, transducer_type=None, physical_dimension=None, physical_range=None, digital_range=None, prefiltering=None)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **data** (numpy.ndarray) - Required - The signal data (float or int). - **sampling_frequency** (float) - Required - The sampling frequency in Hz. - **label** (str) - Required - The label for the signal. - **transducer_type** (str) - Optional - The type of transducer used. - **physical_dimension** (str) - Optional - The physical unit of the signal (e.g., 'uV'). - **physical_range** (tuple[float, float]) - Optional - The minimum and maximum physical values. - **digital_range** (tuple[int, int]) - Optional - The minimum and maximum digital values (default is full 16-bit range). - **prefiltering** (str) - Optional - Description of the prefiltering applied. ### Request Example ```python import numpy as np from edfio import EdfSignal # Create basic signal signal = EdfSignal( data=np.random.randn(30 * 256), # 30 seconds at 256 Hz sampling_frequency=256, label="EEG Fpz", ) # Create signal with full metadata signal = EdfSignal( data=np.random.randn(60 * 512), sampling_frequency=512, label="EEG Cz-A1", transducer_type="AgAgCl electrode", physical_dimension="uV", physical_range=(-500, 500), # Explicit physical range digital_range=(-32768, 32767), # Full 16-bit range (default) prefiltering="HP:0.1Hz LP:75Hz N:50Hz", ) ``` ### Response #### Success Response (200) An `EdfSignal` object representing the created signal. #### Response Example ```python # Access signal properties print(f"Label: {signal.label}") print(f"Sampling frequency: {signal.sampling_frequency} Hz") print(f"Physical range: {signal.physical_range}") print(f"Digital range: {signal.digital_range}") # Access data physical_data = signal.data # Calibrated float values digital_data = signal.digital # Raw 16-bit integers # Update signal data new_data = signal.data * 2 # Example: double the amplitude signal.update_data(new_data) # Update with new sampling frequency (resampled data) resampled_data = np.interp( np.linspace(0, len(signal.data), len(signal.data) * 2), np.arange(len(signal.data)), signal.data ) signal.update_data(resampled_data, sampling_frequency=1024) ``` ``` -------------------------------- ### Clone the edfio repository Source: https://github.com/the-siesta-group/edfio/blob/main/CONTRIBUTING.md Clone the forked repository to your local machine to begin development. ```bash git clone https://github.com//edfio ``` -------------------------------- ### Edfio Project - Exception Documentation Source: https://github.com/the-siesta-group/edfio/blob/main/docs/source/_templates/autosummary/exception.rst Documentation for custom exceptions defined in the Edfio module. ```APIDOC ## Exception Documentation ### Description This section details the custom exceptions raised within the Edfio module. ### Method N/A (Documentation of exceptions) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (N/A) N/A #### Response Example N/A ## Custom Exception: {{ objname }} ### Description Represents a specific error condition within the Edfio module. Inherits from standard Python exceptions. ### Method N/A ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (N/A) N/A #### Response Example N/A ``` -------------------------------- ### Creating EDF Objects Source: https://context7.com/the-siesta-group/edfio/llms.txt Illustrates how to create new EDF objects from signal data and optional patient and recording metadata using the `Edf` class. ```APIDOC ## Edf Creates a new EDF object from signals and optional metadata. The main class for creating and manipulating EDF files. ### Method POST (conceptual, as it's a creation operation) ### Endpoint `Edf(signals, patient=None, recording=None, starttime=None)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **signals** (list[EdfSignal]) - Required - A list of `EdfSignal` objects. - **patient** (Patient) - Optional - Patient information. - **recording** (Recording) - Optional - Recording metadata. - **starttime** (datetime.time) - Optional - The start time of the recording. ### Request Example ```python import datetime import numpy as np from edfio import Edf, EdfSignal, Patient, Recording # Create basic EDF with signals edf = Edf([ EdfSignal(np.random.randn(30 * 256), sampling_frequency=256, label="EEG Fpz"), EdfSignal(np.random.randn(30 * 512), sampling_frequency=512, label="EEG Cz"), EdfSignal(np.random.randn(30), sampling_frequency=1, label="Body Temp"), ]) # Create EDF with full metadata edf = Edf( signals=[ EdfSignal( np.random.randn(30 * 256), sampling_frequency=256, label="EEG Fpz-Cz", transducer_type="AgAgCl electrode", physical_dimension="uV", prefiltering="HP:0.1Hz LP:75Hz", ), ], patient=Patient( code="MCH-0234567", sex="F", birthdate=datetime.date(1951, 5, 2), name="Haagse_Harry", ), recording=Recording( startdate=datetime.date(2002, 2, 2), hospital_administration_code="EMG561", investigator_technician_code="BK/JOP", equipment_code="Sony", ), starttime=datetime.time(11, 25, 30), ) # Write to file edf.write("output.edf") ``` ### Response #### Success Response (200) An `Edf` object representing the created EDF file. #### Response Example ```python # The 'write' method saves the EDF object to a file. # Accessing properties of the created object is similar to reading. print(f"Created EDF with {len(edf.signals)} signals.") ``` ``` -------------------------------- ### Write EDF to File Source: https://context7.com/the-siesta-group/edfio/llms.txt Demonstrates writing an EDF object to various destinations including paths and memory buffers. ```python import io from edfio import Edf, EdfSignal import numpy as np edf = Edf([EdfSignal(np.random.randn(256), sampling_frequency=256)]) # Write to file path edf.write("output.edf") # Write to Path object from pathlib import Path edf.write(Path("~/data/output.edf")) # Write to BytesIO buffer = io.BytesIO() edf.write(buffer) buffer.seek(0) edf_bytes = buffer.read() # Convert to bytes directly edf_bytes = edf.to_bytes() ``` -------------------------------- ### Reading EDF Files Source: https://context7.com/the-siesta-group/edfio/llms.txt Demonstrates how to read EDF files using the `read_edf` function, including options for file paths, bytes, lazy loading, and header encoding. ```APIDOC ## read_edf Reads an EDF file from a path or file-like object into an Edf object. Supports lazy loading for memory-efficient processing of large files. ### Method GET (conceptual, as it's a read operation) ### Endpoint `read_edf(file, lazy_load_data=True, header_encoding='ascii')` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from pathlib import Path from edfio import read_edf # Read from file path (lazy loading enabled by default) edf = read_edf("recording.edf") # Read from Path object edf = read_edf(Path("~/data/recording.edf")) # Read from bytes with open("recording.edf", "rb") as f: edf = read_edf(f.read()) # Disable lazy loading to load all data immediately edf = read_edf("recording.edf", lazy_load_data=False) # Read files with non-ASCII header encoding edf = read_edf("recording.edf", header_encoding="latin-1") ``` ### Response #### Success Response (200) An `Edf` object containing the signal data and metadata. #### Response Example ```python # Access basic information print(f"Duration: {edf.duration} seconds") print(f"Number of signals: {edf.num_signals}") print(f"Signal labels: {edf.labels}") print(f"Start time: {edf.starttime}") print(f"Start date: {edf.startdate}") ``` ``` -------------------------------- ### Manage EDF Annotations Source: https://context7.com/the-siesta-group/edfio/llms.txt Creates, writes, and reads EDF+ annotations. ```python import numpy as np from edfio import Edf, EdfAnnotation, EdfSignal # Create annotations annotations = [ EdfAnnotation(onset=0, duration=None, text="Recording Start"), EdfAnnotation(onset=1.5, duration=None, text="Stimulus A"), EdfAnnotation(onset=2.5, duration=2.0, text="Response"), # With duration EdfAnnotation(onset=10.0, duration=None, text="Recording End"), ] # Create EDF with annotations edf = Edf( signals=[EdfSignal(np.random.randn(30 * 256), sampling_frequency=256)], annotations=annotations, ) edf.write("annotated.edf") # Read and access annotations from edfio import read_edf edf = read_edf("annotated.edf") for ann in edf.annotations: print(f"At {ann.onset}s: {ann.text} (duration: {ann.duration})") ``` -------------------------------- ### Reading BDF Files Source: https://context7.com/the-siesta-group/edfio/llms.txt Shows how to read BDF files using the `read_bdf` function. BDF files use 24-bit integers, unlike EDF's 16-bit. ```APIDOC ## read_bdf Reads a BDF file (BioSemi Data Format) into a Bdf object. BDF uses 24-bit integers compared to 16-bit for EDF. ### Method GET (conceptual, as it's a read operation) ### Endpoint `read_bdf(file)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from edfio import read_bdf # Read BDF file bdf = read_bdf("recording.bdf") ``` ### Response #### Success Response (200) A `Bdf` object containing the signal data and metadata. #### Response Example ```python # Access signal data print(f"Duration: {bdf.duration} seconds") print(f"Signals: {bdf.labels}") for signal in bdf.signals: print(f" {signal.label}: {signal.sampling_frequency} Hz") ``` ``` -------------------------------- ### Class and Method Reference Source: https://github.com/the-siesta-group/edfio/blob/main/docs/source/_templates/autosummary/class.rst Documentation structure for classes, attributes, and methods within the EDFIO module. ```APIDOC ## Class Reference ### Description This documentation covers the structure of classes within the EDFIO module, including their associated attributes and methods. ### Structure - **Class**: {{ fullname }} - **Attributes**: Lists all public attributes associated with the class. - **Methods**: Lists all public methods associated with the class, excluding internal methods like __init__, count, and index. ``` -------------------------------- ### Run tests with pytest Source: https://github.com/the-siesta-group/edfio/blob/main/CONTRIBUTING.md Execute all tests in the project root directory using pytest. ```bash pytest ``` -------------------------------- ### Add release version to CHANGELOG.md Source: https://github.com/the-siesta-group/edfio/blob/main/CONTRIBUTING.md When preparing a new release, add a line to CHANGELOG.md indicating the version number and release date, following the format '## [version] - YYYY-MM-DD'. ```markdown ## [0.2.0] - 2023-11-22 ``` -------------------------------- ### Bdf and BdfSignal Source: https://context7.com/the-siesta-group/edfio/llms.txt Enables the creation of BDF files with 24-bit resolution, which is beneficial for signals requiring a high dynamic range. ```APIDOC ## Bdf and BdfSignal ### Description Creates BDF files with 24-bit resolution (compared to 16-bit for EDF). Useful for high dynamic range signals. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import numpy as np from edfio import Bdf, BdfSignal # Create BDF signal with 24-bit resolution signal = BdfSignal( data=np.random.randn(30 * 2048), sampling_frequency=2048, label="EEG", physical_dimension="uV", digital_range=(-8388608, 8388607), # 24-bit range (default for BDF) ) # Create and write BDF file bdf = Bdf([signal]) bdf.write("recording.bdf") ``` ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Data Structures Source: https://github.com/the-siesta-group/edfio/blob/main/docs/source/reference.rst Core classes representing the components of EDF/BDF files. ```APIDOC ## Classes - **Bdf**: Represents a BDF file structure. - **BdfSignal**: Represents a signal within a BDF file. - **Edf**: Represents an EDF file structure. - **EdfSignal**: Represents a signal within an EDF file. - **EdfAnnotation**: Represents annotations within an EDF file. - **Patient**: Represents patient metadata. - **Recording**: Represents recording metadata. ``` -------------------------------- ### Add upstream remote for edfio Source: https://github.com/the-siesta-group/edfio/blob/main/CONTRIBUTING.md Add the original edfio repository as a remote named 'upstream' to your local clone. This allows you to fetch changes from the main project. ```bash git remote add upstream git@github.com:the-siesta-group/edfio.git ``` -------------------------------- ### Exceptions Source: https://github.com/the-siesta-group/edfio/blob/main/docs/source/reference.rst Custom exceptions used within the library. ```APIDOC ## AnonymizedDateError ### Description Raised when an error occurs related to anonymized dates in the file metadata. ``` -------------------------------- ### Edf.add_annotations and Edf.set_annotations Source: https://context7.com/the-siesta-group/edfio/llms.txt Allows for the addition of new annotations to an existing EDF file or the complete replacement of all current annotations. ```APIDOC ## Edf.add_annotations and Edf.set_annotations ### Description Adds new annotations or replaces all existing annotations. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from edfio import read_edf, EdfAnnotation edf = read_edf("recording.edf") # Add new annotations to existing ones new_annotations = [ EdfAnnotation(5.0, None, "Event A"), EdfAnnotation(10.0, 2.5, "Event B"), ] edf.add_annotations(new_annotations) # Replace all annotations replacement_annotations = [ EdfAnnotation(0, None, "Start"), EdfAnnotation(30, None, "End"), ] edf.set_annotations(replacement_annotations) edf.write("modified.edf") ``` ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Edf.get_annotations Source: https://context7.com/the-siesta-group/edfio/llms.txt Retrieves annotations within a specified time window, optimizing memory usage by avoiding the need to load all annotations at once. ```APIDOC ## Edf.get_annotations ### Description Retrieves annotations from a specific time window without loading the entire file. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from edfio import read_edf # Assuming 'long_recording.edf' contains annotations edf = read_edf("long_recording.edf") # Get all annotations all_annotations = edf.annotations # Get annotations in a specific time window (seconds) window_annotations = edf.get_annotations(start_second=60, stop_second=120) for ann in window_annotations: print(f"{ann.onset}s: {ann.text}") ``` ### Response #### Success Response (200) - **window_annotations** (list[EdfAnnotation]) - A list of EdfAnnotation objects within the specified time window. #### Response Example ``` 65.5s: Event X 70.0s: Event Y 110.2s: Event Z ``` ``` -------------------------------- ### Create and Access Recording Metadata Source: https://context7.com/the-siesta-group/edfio/llms.txt Defines and manipulates recording information according to EDF+ specifications. Can be used to create new EDF files with recording data or access/modify it from existing files. ```python import datetime from edfio import Edf, EdfSignal, Recording import numpy as np # Create recording with full information recording = Recording( startdate=datetime.date(2024, 3, 15), hospital_administration_code="PSG-2024-001", investigator_technician_code="Dr_Smith", equipment_code="Nihon_Kohden", additional=["Room_101", "Night_Study"], ) # Create EDF with recording info edf = Edf( [EdfSignal(np.random.randn(256), sampling_frequency=256)], recording=recording, ) # Access recording information from edfio import read_edf edf = read_edf("recording.edf") print(f"Hospital code: {edf.recording.hospital_administration_code}") print(f"Equipment: {edf.recording.equipment_code}") try: print(f"Start date: {edf.recording.startdate}") except Exception: print("Start date anonymized") # Modify recording edf.recording = Recording( startdate=datetime.date(2024, 1, 1), hospital_administration_code="EEG-001", ) ``` -------------------------------- ### Read an EDF file Source: https://github.com/the-siesta-group/edfio/blob/main/README.md Read an EDF file from disk using the read_edf function. ```python from edfio import read_edf edf = read_edf("example.edf") ``` -------------------------------- ### EdfAnnotation Source: https://context7.com/the-siesta-group/edfio/llms.txt Represents EDF+ annotations, allowing for the creation of time-stamped events with optional durations and descriptive text. ```APIDOC ## EdfAnnotation ### Description Creates EDF+ annotations with onset time, optional duration, and text. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import numpy as np from edfio import Edf, EdfAnnotation, EdfSignal # Create annotations annotations = [ EdfAnnotation(onset=0, duration=None, text="Recording Start"), EdfAnnotation(onset=1.5, duration=None, text="Stimulus A"), EdfAnnotation(onset=2.5, duration=2.0, text="Response"), # With duration EdfAnnotation(onset=10.0, duration=None, text="Recording End"), ] # Create EDF with annotations edf = Edf( signals=[EdfSignal(np.random.randn(30 * 256), sampling_frequency=256)], annotations=annotations, ) edf.write("annotated.edf") # Read and access annotations from edfio import read_edf edf = read_edf("annotated.edf") for ann in edf.annotations: print(f"At {ann.onset}s: {ann.text} (duration: {ann.duration})") ``` ### Response #### Success Response (200) None #### Response Example ``` At 0.0s: Recording Start (duration: None) At 1.5s: Stimulus A (duration: None) At 2.5s: Response (duration: 2.0) At 10.0s: Recording End (duration: None) ``` ``` -------------------------------- ### File Reading Functions Source: https://github.com/the-siesta-group/edfio/blob/main/docs/source/reference.rst Functions for reading EDF and BDF files into memory. ```APIDOC ## read_edf ### Description Reads an EDF file. ## read_bdf ### Description Reads a BDF file. ``` -------------------------------- ### Edf.write Source: https://context7.com/the-siesta-group/edfio/llms.txt Writes an EDF object to a specified file path, a Path object, or a file-like object such as BytesIO. ```APIDOC ## Edf.write ### Description Writes an EDF object to a file or file-like object. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import io from edfio import Edf, EdfSignal import numpy as np edf = Edf([EdfSignal(np.random.randn(256), sampling_frequency=256)]) # Write to file path edf.write("output.edf") # Write to Path object from pathlib import Path edf.write(Path("~/data/output.edf")) # Write to BytesIO buffer = io.BytesIO() edf.write(buffer) buffer.seek(0) # Convert to bytes directly edf_bytes = edf.to_bytes() ``` ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Create EDF Signal Source: https://context7.com/the-siesta-group/edfio/llms.txt Creates an EdfSignal object representing a single signal channel within an EDF file. Supports defining signal data, sampling frequency, label, and detailed metadata such as transducer type, physical dimensions, ranges, and prefiltering. Signal data is internally stored as 16-bit integers. ```python import numpy as np from edfio import EdfSignal # Create basic signal signal = EdfSignal( data=np.random.randn(30 * 256), # 30 seconds at 256 Hz sampling_frequency=256, label="EEG Fpz", ) # Create signal with full metadata signal = EdfSignal( data=np.random.randn(60 * 512), sampling_frequency=512, label="EEG Cz-A1", transducer_type="AgAgCl electrode", physical_dimension="uV", physical_range=(-500, 500), # Explicit physical range digital_range=(-32768, 32767), # Full 16-bit range (default) prefiltering="HP:0.1Hz LP:75Hz N:50Hz", ) # Access signal properties print(f"Label: {signal.label}") print(f"Sampling frequency: {signal.sampling_frequency} Hz") print(f"Physical range: {signal.physical_range}") print(f"Digital range: {signal.digital_range}") # Access data physical_data = signal.data # Calibrated float values digital_data = signal.digital # Raw 16-bit integers # Update signal data new_data = signal.data * 2 # Example: double the amplitude signal.update_data(new_data) # Update with new sampling frequency (resampled data) resampled_data = np.interp( np.linspace(0, len(signal.data), len(signal.data) * 2), np.arange(len(signal.data)), signal.data ) signal.update_data(resampled_data, sampling_frequency=1024) ``` -------------------------------- ### Slice Recording by Seconds Source: https://github.com/the-siesta-group/edfio/blob/main/docs/source/examples.md Extract a portion of the recording between two specified time points in seconds. The upper limit is exclusive. ```python # by seconds edf.slice_between_seconds(5, 15) ``` -------------------------------- ### Create EDF from Hypnogram Source: https://context7.com/the-siesta-group/edfio/llms.txt Generates an EDF signal from sleep stage data using standard integer codes. ```python import numpy as np from edfio import Edf, EdfSignal # Sleep stages: W=0, N1=1, N2=2, N3=3, N4=4, REM=5, MT=6, Unscored=9 stages = np.array([0, 0, 1, 2, 2, 3, 3, 2, 2, 5, 5, 0]) # 12 epochs # Create hypnogram signal (default 30-second epochs) hypnogram = EdfSignal.from_hypnogram(stages, stage_duration=30, label="Sleep Stage") # Create EDF with hypnogram edf = Edf([hypnogram]) edf.write("hypnogram.edf") ``` -------------------------------- ### Read BDF File Source: https://context7.com/the-siesta-group/edfio/llms.txt Reads a BDF (BioSemi Data Format) file into a Bdf object. BDF files utilize 24-bit integers, distinguishing them from EDF's 16-bit integers. Access file duration, signal labels, and individual signal properties like sampling frequency. ```python from edfio import read_bdf # Read BDF file bdf = read_bdf("recording.bdf") # Access signal data print(f"Duration: {bdf.duration} seconds") print(f"Signals: {bdf.labels}") for signal in bdf.signals: print(f" {signal.label}: {signal.sampling_frequency} Hz") ``` -------------------------------- ### Create a deep copy of an EDF object Source: https://context7.com/the-siesta-group/edfio/llms.txt Generates a deep copy of an EDF object to allow for modifications without affecting the original file data. ```python from edfio import read_edf edf = read_edf("recording.edf") # Create deep copy edf_copy = edf.copy() # Modify copy without affecting original edf_copy.slice_between_seconds(10, 20) edf_copy.drop_signals([0, 1]) # Original is unchanged print(f"Original duration: {edf.duration}") print(f"Copy duration: {edf_copy.duration}") ``` -------------------------------- ### Retrieve and Modify Signal Source: https://context7.com/the-siesta-group/edfio/llms.txt Accesses a signal by label and updates its metadata properties. ```python from edfio import read_edf edf = read_edf("recording.edf") # Get signal by label eeg_signal = edf.get_signal("EEG Fpz-Cz") print(f"Sampling frequency: {eeg_signal.sampling_frequency} Hz") print(f"Data shape: {eeg_signal.data.shape}") # Modify signal properties eeg_signal.label = "EEG Fpz-Cz Modified" eeg_signal.transducer_type = "AgAgCl electrode" eeg_signal.physical_dimension = "uV" eeg_signal.prefiltering = "HP:0.1Hz LP:75Hz" ``` -------------------------------- ### EdfSignal.get_data_slice Source: https://context7.com/the-siesta-group/edfio/llms.txt Efficiently retrieves a portion of signal data for large files by loading only the requested segment into memory, supporting both calibrated and digital data slices. ```APIDOC ## EdfSignal.get_data_slice ### Description Retrieves a portion of signal data without loading the entire file into memory. Efficient for large files with lazy loading. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from edfio import read_edf # Read with lazy loading (default for file paths) edf = read_edf("large_recording.edf") # Get a 10-second slice starting at second 100 signal = edf.signals[0] data_slice = signal.get_data_slice(start_second=100, stop_second=110) print(f"Slice shape: {data_slice.shape}") # Get digital (uncalibrated) slice digital_slice = signal.get_digital_slice(start_second=100, stop_second=110) ``` ### Response #### Success Response (200) - **data_slice** (numpy.ndarray) - A numpy array containing the requested data segment. - **digital_slice** (numpy.ndarray) - A numpy array containing the raw digital values of the requested data segment. #### Response Example ``` Slice shape: (2560,) ``` ``` -------------------------------- ### Create and Access Patient Metadata Source: https://context7.com/the-siesta-group/edfio/llms.txt Defines and manipulates patient information according to EDF+ specifications. Can be used to create new EDF files with patient data or access/modify it from existing files. ```python import datetime from edfio import Edf, EdfSignal, Patient import numpy as np # Create patient with full information patient = Patient( code="MCH-0234567", sex="F", # "F", "M", or "X" (anonymized) birthdate=datetime.date(1990, 5, 15), name="Doe_Jane", additional=["Hospital_A", "Study_123"], # Optional fields ) # Create EDF with patient info edf = Edf( [EdfSignal(np.random.randn(256), sampling_frequency=256)], patient=patient, ) # Access patient information from existing file from edfio import read_edf edf = read_edf("recording.edf") print(f"Patient code: {edf.patient.code}") print(f"Patient sex: {edf.patient.sex}") try: print(f"Birthdate: {edf.patient.birthdate}") except Exception: print("Birthdate anonymized") # Modify patient information edf.patient = Patient(code="NEW-001", sex="M", name="Smith_John") ``` -------------------------------- ### Retrieve Signal Data Slice Source: https://context7.com/the-siesta-group/edfio/llms.txt Extracts specific time segments from a signal without loading the entire file into memory. ```python from edfio import read_edf # Read with lazy loading (default for file paths) edf = read_edf("large_recording.edf") # Get a 10-second slice starting at second 100 signal = edf.signals[0] data_slice = signal.get_data_slice(start_second=100, stop_second=110) print(f"Slice shape: {data_slice.shape}") # Get digital (uncalibrated) slice digital_slice = signal.get_digital_slice(start_second=100, stop_second=110) ``` -------------------------------- ### Append New Signals to EDF Source: https://context7.com/the-siesta-group/edfio/llms.txt Adds one or more new signals to an existing EDF recording. Ensure new signals have a duration that matches the recording's duration. ```python import numpy as np from edfio import read_edf, EdfSignal edf = read_edf("recording.edf") duration = edf.duration # Create new signal with matching duration new_signal = EdfSignal( data=np.random.randn(int(duration * 100)), # 100 Hz sampling_frequency=100, label="New Channel", ) # Append single signal edf.append_signals(new_signal) # Append multiple signals more_signals = [ EdfSignal(np.random.randn(int(duration * 50)), sampling_frequency=50, label="Ch1"), EdfSignal(np.random.randn(int(duration * 50)), sampling_frequency=50, label="Ch2"), ] edf.append_signals(more_signals) edf.write("extended.edf") ``` -------------------------------- ### Edf.copy Source: https://context7.com/the-siesta-group/edfio/llms.txt Creates a deep copy of an EDF object. This is useful for performing non-destructive operations on a copy of the data without altering the original object. ```APIDOC ## Edf.copy ### Description Creates a deep copy of an EDF object for non-destructive operations. ### Method ``` copy() ``` ### Parameters None ### Request Example ```python from edfio import read_edf edf = read_edf("recording.edf") # Create deep copy edf_copy = edf.copy() # Modify copy without affecting original edf_copy.slice_between_seconds(10, 20) edf_copy.drop_signals([0, 1]) # Original is unchanged print(f"Original duration: {edf.duration}") print(f"Copy duration: {edf_copy.duration}") ``` ### Response - **edf_copy** (Edf) - A deep copy of the original EDF object. #### Success Response (200) - **edf_copy** (Edf) - A deep copy of the original EDF object. #### Response Example ```json { "example": "edf_copy object" } ``` ``` -------------------------------- ### EdfSignal.from_hypnogram Source: https://context7.com/the-siesta-group/edfio/llms.txt Creates an EDF signal from sleep stage data, adhering to EDF specifications. It supports integer codes for various sleep stages. ```APIDOC ## EdfSignal.from_hypnogram ### Description Creates an EDF signal from sleep stage data following EDF specifications. Uses integer codes: 0=W, 1-4=N1-N4, 5=R, 6=MT, 9=unscored. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import numpy as np from edfio import Edf, EdfSignal # Sleep stages: W=0, N1=1, N2=2, N3=3, N4=4, REM=5, MT=6, Unscored=9 stages = np.array([0, 0, 1, 2, 2, 3, 3, 2, 2, 5, 5, 0]) # 12 epochs # Create hypnogram signal (default 30-second epochs) hypnogram = EdfSignal.from_hypnogram(stages, stage_duration=30, label="Sleep Stage") # Create EDF with hypnogram edf = Edf([hypnogram]) edf.write("hypnogram.edf") ``` ### Response #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Add or Replace Annotations Source: https://context7.com/the-siesta-group/edfio/llms.txt Modifies the annotation list of an EDF object. ```python from edfio import read_edf, EdfAnnotation edf = read_edf("recording.edf") # Add new annotations to existing ones new_annotations = [ EdfAnnotation(5.0, None, "Event A"), EdfAnnotation(10.0, 2.5, "Event B"), ] edf.add_annotations(new_annotations) # Replace all annotations replacement_annotations = [ EdfAnnotation(0, None, "Start"), EdfAnnotation(30, None, "End"), ] edf.set_annotations(replacement_annotations) edf.write("modified.edf") ``` -------------------------------- ### Slice Recording by Annotation Text Source: https://github.com/the-siesta-group/edfio/blob/main/docs/source/examples.md Extract a portion of the recording between two annotations identified by their text. The upper limit annotation is exclusive. ```python # by annotation texts edf.slice_between_annotations("Trial start", "Trial end") ```