API reference#
- exception edfio.AnonymizedDateError[source]#
Raised when trying to access an anonymized startdate or birthdate.
- class edfio.Bdf(signals, *, patient=None, recording=None, starttime=None, data_record_duration=None, annotations=None)[source]#
Python representation of a BDF file.
See
Edffor information on the header fields and their types.Note
BDF uses 24-bit integers (compared to 16-bit for EDF) for the digital values. The default for
digital_range(and the supported depth) thus differs.- add_annotations(annotations)[source]#
Add annotations to the Bdf.
This removes all existing annotation signals and adds a new one containing the old and new annotations as the last signal in the file.
- Parameters:
- annotations
Iterable[EdfAnnotation] The annotations to add.
- annotations
- property annotations[source]#
All annotations contained in the Bdf, sorted chronologically.
Does not include timekeeping annotations.
- anonymize(*, keep_age=False, keep_sex=False, keep_starttime=False)[source]#
Anonymize a recording.
- By default, header fields are modified as follows:
local patient identification is set to
X X X Xlocal recording identification is set to
Startdate X X X Xstartdate is set to
01.01.85starttime is set to
00.00.00
For BDF+ files, subsecond starttimes specified via an annotations signal are removed.
Optionally, parts of the original information can be preserved by setting the corresponding parameters to True (see below).
- Parameters:
- keep_agebool, default:
False Whether to keep age information relative to the anonymized start date in the local patient identification. If True, the birthdate is set to January 1st of the year that preserves the age relative to
01.01.85. This implies that the local patient identification is set toX X 01-JAN-YYYY X, whereYYYYis the age-preserving year.- keep_sexbool, default:
False Whether to keep the sex field in the local patient identification.
- keep_starttimebool, default:
False Whether to keep the original start time.
- keep_agebool, default:
- append_signals(new_signals)[source]#
Append one or more signal(s) to the Bdf recording.
Every signal must be compatible with the current
data_record_durationand all signal durations must match the overall recording duration. For recordings containing BDF+ annotation signals, the new signals are inserted after the last ordinary (i.e. non-annotation) signal.
- drop_annotations(text)[source]#
Drop annotations with a given text.
- Parameters:
- text
str All annotations whose text exactly matches this parameter are removed.
- text
- drop_signals(drop)[source]#
Drop signals by index or label.
_Signal indices (int) and labels (str) can be provided in the same iterable. For ambiguous labels, all corresponding signals are dropped. Raises a ValueError if at least one of the provided identifiers does not correspond to a signal.
- get_annotations(start_second=None, stop_second=None)[source]#
All annotations defined (starting) in a specified time region of the Bdf, sorted chronologically.
Does not include timekeeping annotations. Will not include annotations that start within the specified time region but are defined in data records outside of that window.
- get_signal(label)[source]#
Retrieve a single signal by its label.
The label has to be unique - a ValueError is raised if it is ambiguous or does not exist.
- property local_patient_identification[source]#
Unparsed string representation of the legacy local patient identification.
- property local_recording_identification[source]#
Unparsed string representation of the legacy local recording identification.
- property patient[source]#
Parsed object representation of the local patient identification.
See
Patientfor information on its attributes.
- property recording[source]#
Parsed object representation of the local recording identification.
See
Recordingfor information on its attributes.
- set_annotations(annotations)[source]#
Overwrite all annotations with new ones.
This removes all existing annotation signals and adds a new one as the last signal in the file.
- Parameters:
- annotations
Iterable[EdfAnnotation] The annotations to set.
- annotations
- property signals[source]#
Ordinary signals contained in the recording.
Annotation signals are excluded. Individual signals can not be removed, added, or replaced by modifying this property. Use
Bdf.append_signals(),Bdf.drop_signals(), orBdfSignal.data, respectively.
- slice_between_annotations(start_text, stop_text, *, keep_all_annotations=False)[source]#
Slice to the interval between two BDF+ annotations.
The sample point corresponding to the onset of the annotation identified by
stop_textis excluded.start_textandstop_texteach have to uniquely identify a single annotation, whose onset corresponds exactly to a sample time in all non-annotation signals.
- slice_between_seconds(start, stop, *, keep_all_annotations=False)[source]#
Slice to the interval between two times.
The sample point corresponding to
stopis excluded.startandstopare given in seconds from recording start and have to correspond exactly to a sample time in all non-annotation signals.
- property startdate[source]#
Recording startdate.
If the
local_recording_identificationconforms to the BDF+ standard, the startdate provided there is used. If not, this falls back to the legacystartdatefield. If both differ, a warning is issued and the BDF+ field is preferred. Raises anAnonymizedDateErrorif the BDF+ field is anonymized (i.e., begins withStartdate X).
- to_bytes()[source]#
Convert an Bdf to a
bytesobject.- Returns:
bytesThe binary representation of the Bdf object (i.e., what a file created with
Bdf.writewould contain).
- update_data_record_duration(data_record_duration, method='strict')[source]#
Update the data record duration.
This operation will fail if the new duration is incompatible with the current sampling frequencies.
- Parameters:
- data_record_duration
float The new data record duration in seconds.
- method
{"strict", "pad", "truncate"}, default:"strict" How to handle the case where the new duration does not divide the Bdf duration evenly
“strict”: Raise a ValueError
“pad”: Pad the data with zeros to the next compatible duration. If zero is outside the physical range, data is padded with the physical minimum.
“truncate”: Truncate the data to the previous compatible duration (might lead to loss of data)
- data_record_duration
- write(target)[source]#
Write an Bdf to a file or file-like object.
- Parameters:
- target
Path|str|io.BufferedWriter|io.BytesIO The file location (path object or string) or file-like object to write to.
- target
- class edfio.BdfSignal(data, sampling_frequency, *, label='', transducer_type='', physical_dimension='', physical_range=None, digital_range=(-8388608, 8388607), prefiltering='')[source]#
A single BDF signal.
See
EdfSignalfor details on the parameters and attributes.Note
BDF uses 24-bit integers (compared to 16-bit for EDF) for the digital values. The default for
digital_range(and the supported depth) thus differs.- property data[source]#
Numpy array containing the physical signal values as floats.
To simplify avoiding inconsistencies between signal data and header fields, individual values in the returned array can not be modified. Use
BdfSignal.update_data()to overwrite with new physical data.
- property digital[source]#
Numpy array containing the digital (uncalibrated) signal values as integers.
The values of the array may be accessed and modified directly.
For EDF these are 16-bit integers, for BDF these are 32-bit integers.
- classmethod from_hypnogram(stages, stage_duration=30, *, label='')[source]#
Create an EDF signal from a hypnogram, with scaling according to EDF specs.
According to the EDF FAQ [1], use integer numbers 0, 1, 2, 3, 4, 5, 6, and 9 for sleep stages W, 1, 2, 3, 4, R, MT, und unscored, respectively. The digital range is set to
(0, 9).- Parameters:
- stages
npt.NDArray[np.float64] The sleep stages, coded as integer numbers.
- stage_duration
float, default:30 The duration of each sleep stage in seconds, used to set the sampling frequency to its inverse.
- label
str, default:"" The signal’s label.
- stages
- Returns:
References
[1]
- get_data_slice(start_second, stop_second)[source]#
Get a slice of the signal data.
If the signal has not been loaded into memory so far, only the requested slice will be read.
- get_digital_slice(start_second, stop_second)[source]#
Get a slice of the digital signal values.
If the signal has not been loaded into memory so far, only the requested slice will be read.
- property samples_per_data_record[source]#
Number of samples in each data record.
For newly instantiated
BdfSignalobjects, this is only set onceBdf.write()is called.
- update_data(data, *, keep_physical_range=False, sampling_frequency=None)[source]#
Overwrite physical signal values with an array of equal length.
- Parameters:
- data
npt.NDArray[np.float64] The new physical data.
- keep_physical_rangebool, default:
False If
True, thephysical_rangeis not modified to accomodate the new data.- sampling_frequency
float|None, default:None If not
None, thesampling_frequencyis updated to the new value. The new data must match the expected length for the new sampling frequency.
- data
- class edfio.Edf(signals, *, patient=None, recording=None, starttime=None, data_record_duration=None, annotations=None)[source]#
Python representation of an EDF file.
EDF header fields are exposed as properties with appropriate data types (i.e., string, numeric, date, or time objects). Fields that might break the file on modification (i.e.,
version,bytes_in_header_record,reserved,num_data_records,data_record_duration, andnum_signals) can not be set after instantiation.Note that the startdate has to be set via the parameter
recording.For writing an EDF file with a non-integer seconds duration, currently an appropriate value for
data_record_durationhas to be provided manually.- Parameters:
- signals
Sequence[EdfSignal] The (non-annotation) signals to be contained in the EDF file.
- patient
Patient|None, default:None The “local patient identification”, containing patient code, sex, birthdate, name, and optional additional fields. If
None, the field is set toX X X Xin accordance with EDF+ specs.- recording
Recording|None, default:None The “local recording identification”, containing recording startdate, hospital administration code, investigator/technical code, equipment code, and optional additional fields. If
None, the field is set toStartdate X X X Xin accordance with EDF+ specs.- starttime
datetime.time|None, default:None The starttime of the recording. If
None,00.00.00is used. Ifstarttimecontains microseconds, an EDF+C file is created.- data_record_duration
float|None, default:None The duration of each data record in seconds. If
None, an appropriate value is chosen automatically.- annotations
Iterable[EdfAnnotation] |None, default:None The annotations, consisting of onset, duration (optional), and text. If not
None, an EDF+C file is created.
- signals
- add_annotations(annotations)[source]#
Add annotations to the Edf.
This removes all existing annotation signals and adds a new one containing the old and new annotations as the last signal in the file.
- Parameters:
- annotations
Iterable[EdfAnnotation] The annotations to add.
- annotations
- property annotations[source]#
All annotations contained in the Edf, sorted chronologically.
Does not include timekeeping annotations.
- anonymize(*, keep_age=False, keep_sex=False, keep_starttime=False)[source]#
Anonymize a recording.
- By default, header fields are modified as follows:
local patient identification is set to
X X X Xlocal recording identification is set to
Startdate X X X Xstartdate is set to
01.01.85starttime is set to
00.00.00
For EDF+ files, subsecond starttimes specified via an annotations signal are removed.
Optionally, parts of the original information can be preserved by setting the corresponding parameters to True (see below).
- Parameters:
- keep_agebool, default:
False Whether to keep age information relative to the anonymized start date in the local patient identification. If True, the birthdate is set to January 1st of the year that preserves the age relative to
01.01.85. This implies that the local patient identification is set toX X 01-JAN-YYYY X, whereYYYYis the age-preserving year.- keep_sexbool, default:
False Whether to keep the sex field in the local patient identification.
- keep_starttimebool, default:
False Whether to keep the original start time.
- keep_agebool, default:
- append_signals(new_signals)[source]#
Append one or more signal(s) to the Edf recording.
Every signal must be compatible with the current
data_record_durationand all signal durations must match the overall recording duration. For recordings containing EDF+ annotation signals, the new signals are inserted after the last ordinary (i.e. non-annotation) signal.
- drop_annotations(text)[source]#
Drop annotations with a given text.
- Parameters:
- text
str All annotations whose text exactly matches this parameter are removed.
- text
- drop_signals(drop)[source]#
Drop signals by index or label.
_Signal indices (int) and labels (str) can be provided in the same iterable. For ambiguous labels, all corresponding signals are dropped. Raises a ValueError if at least one of the provided identifiers does not correspond to a signal.
- get_annotations(start_second=None, stop_second=None)[source]#
All annotations defined (starting) in a specified time region of the Edf, sorted chronologically.
Does not include timekeeping annotations. Will not include annotations that start within the specified time region but are defined in data records outside of that window.
- get_signal(label)[source]#
Retrieve a single signal by its label.
The label has to be unique - a ValueError is raised if it is ambiguous or does not exist.
- property local_patient_identification[source]#
Unparsed string representation of the legacy local patient identification.
- property local_recording_identification[source]#
Unparsed string representation of the legacy local recording identification.
- property patient[source]#
Parsed object representation of the local patient identification.
See
Patientfor information on its attributes.
- property recording[source]#
Parsed object representation of the local recording identification.
See
Recordingfor information on its attributes.
- set_annotations(annotations)[source]#
Overwrite all annotations with new ones.
This removes all existing annotation signals and adds a new one as the last signal in the file.
- Parameters:
- annotations
Iterable[EdfAnnotation] The annotations to set.
- annotations
- property signals[source]#
Ordinary signals contained in the recording.
Annotation signals are excluded. Individual signals can not be removed, added, or replaced by modifying this property. Use
Edf.append_signals(),Edf.drop_signals(), orEdfSignal.data, respectively.
- slice_between_annotations(start_text, stop_text, *, keep_all_annotations=False)[source]#
Slice to the interval between two EDF+ annotations.
The sample point corresponding to the onset of the annotation identified by
stop_textis excluded.start_textandstop_texteach have to uniquely identify a single annotation, whose onset corresponds exactly to a sample time in all non-annotation signals.
- slice_between_seconds(start, stop, *, keep_all_annotations=False)[source]#
Slice to the interval between two times.
The sample point corresponding to
stopis excluded.startandstopare given in seconds from recording start and have to correspond exactly to a sample time in all non-annotation signals.
- property startdate[source]#
Recording startdate.
If the
local_recording_identificationconforms to the EDF+ standard, the startdate provided there is used. If not, this falls back to the legacystartdatefield. If both differ, a warning is issued and the EDF+ field is preferred. Raises anAnonymizedDateErrorif the EDF+ field is anonymized (i.e., begins withStartdate X).
- to_bytes()[source]#
Convert an Edf to a
bytesobject.- Returns:
bytesThe binary representation of the Edf object (i.e., what a file created with
Edf.writewould contain).
- update_data_record_duration(data_record_duration, method='strict')[source]#
Update the data record duration.
This operation will fail if the new duration is incompatible with the current sampling frequencies.
- Parameters:
- data_record_duration
float The new data record duration in seconds.
- method
{"strict", "pad", "truncate"}, default:"strict" How to handle the case where the new duration does not divide the Edf duration evenly
“strict”: Raise a ValueError
“pad”: Pad the data with zeros to the next compatible duration. If zero is outside the physical range, data is padded with the physical minimum.
“truncate”: Truncate the data to the previous compatible duration (might lead to loss of data)
- data_record_duration
- write(target)[source]#
Write an Edf to a file or file-like object.
- Parameters:
- target
Path|str|io.BufferedWriter|io.BytesIO The file location (path object or string) or file-like object to write to.
- target
- class edfio.EdfAnnotation(onset, duration, text)[source]#
A single EDF+ annotation.
- Parameters:
- class edfio.EdfSignal(data, sampling_frequency, *, label='', transducer_type='', physical_dimension='', physical_range=None, digital_range=(-32768, 32767), prefiltering='')[source]#
A single EDF signal.
Attributes that might break the signal or file on modification (i.e.,
sampling_frequency,physical_range,digital_range,samples_per_data_record, andreserved) can not be set after instantiation.To reduce memory consumption, signal data is always stored as a 16-bit integer array containing the digital values that would be written to the corresponding EDF file. Therefore, it is expected that
EdfSignal.datadoes not match the physical values passed during instantiation exactly.- Parameters:
- data
npt.NDArray[np.float64] The signal data (physical values).
- sampling_frequency
float The sampling frequency in Hz.
- label
str, default:"" The signal’s label, e.g.,
"EEG Fpz-Cz"or"Body temp".- transducer_type
str, default:"" The transducer type, e.g.,
"AgAgCl electrode".- physical_dimension
str, default:"" The physical dimension, e.g.,
"uV"or"degreeC"- physical_range
tuple[float,float], default: (-32768, 32767) The physical range given as a tuple of
(physical_min, physical_max). IfNone, this is determined from the data.- digital_range
tuple[int,int] |None, default:None The digital range given as a tuple of
(digital_min, digital_max). Uses the maximum resolution of 16-bit integers.- prefiltering
str, default:"" The signal prefiltering, e.g.,
"HP:0.1Hz LP:75Hz".
- data
- property data[source]#
Numpy array containing the physical signal values as floats.
To simplify avoiding inconsistencies between signal data and header fields, individual values in the returned array can not be modified. Use
EdfSignal.update_data()to overwrite with new physical data.
- property digital[source]#
Numpy array containing the digital (uncalibrated) signal values as integers.
The values of the array may be accessed and modified directly.
For EDF these are 16-bit integers, for BDF these are 32-bit integers.
- classmethod from_hypnogram(stages, stage_duration=30, *, label='')[source]#
Create an EDF signal from a hypnogram, with scaling according to EDF specs.
According to the EDF FAQ [1], use integer numbers 0, 1, 2, 3, 4, 5, 6, and 9 for sleep stages W, 1, 2, 3, 4, R, MT, und unscored, respectively. The digital range is set to
(0, 9).- Parameters:
- stages
npt.NDArray[np.float64] The sleep stages, coded as integer numbers.
- stage_duration
float, default:30 The duration of each sleep stage in seconds, used to set the sampling frequency to its inverse.
- label
str, default:"" The signal’s label.
- stages
- Returns:
References
[1]
- get_data_slice(start_second, stop_second)[source]#
Get a slice of the signal data.
If the signal has not been loaded into memory so far, only the requested slice will be read.
- get_digital_slice(start_second, stop_second)[source]#
Get a slice of the digital signal values.
If the signal has not been loaded into memory so far, only the requested slice will be read.
- property samples_per_data_record[source]#
Number of samples in each data record.
For newly instantiated
EdfSignalobjects, this is only set onceEdf.write()is called.
- update_data(data, *, keep_physical_range=False, sampling_frequency=None)[source]#
Overwrite physical signal values with an array of equal length.
- Parameters:
- data
npt.NDArray[np.float64] The new physical data.
- keep_physical_rangebool, default:
False If
True, thephysical_rangeis not modified to accomodate the new data.- sampling_frequency
float|None, default:None If not
None, thesampling_frequencyis updated to the new value. The new data must match the expected length for the new sampling frequency.
- data
- class edfio.Patient(*, code='X', sex='X', birthdate=None, name='X', additional=())[source]#
Object representation of the local patient identification.
Parsing from/to the string containing the local_patient_identification header field is done according to the EDF+ specs. Subfields must be ASCII (32..126) and may not contain spaces.
- Parameters:
- code
str, default:"X" The code by which the patient is known in the hospital administration.
- sex
{"X", "F", "M"}, default:"X" Sex,
Ffor female,Mfor male,Xif anonymized.- birthdate
datetime.date|None, default:None Patient birthdate, stored as
XifNone.- name
str, default:"X" The patient’s name, stored as
XifNone.- additional
Sequence[str], default:() Optional additional subfields. Will be stored in the header field separated by spaces.
- code
- class edfio.Recording(*, startdate=None, hospital_administration_code='X', investigator_technician_code='X', equipment_code='X', additional=())[source]#
Object representation of the local recording identification.
Parsing from/to the string containing the local_recording_identification header field is done according to the EDF+ specs. Subfields must be ASCII (32..126) and may not contain spaces.
- Parameters:
- startdate
datetime.date|None, default:None The recording startdate.
- hospital_administration_code
str, default:"X" The hospital administration code of the investigation, e.g., EEG number or PSG number.
- investigator_technician_code
str, default:"X" A code specifying the responsible investigator or technician.
- equipment_code
str, default:"X" A code specifying the used equipment.
- additional
Sequence[str], default:() Optional additional subfields. Will be stored in the header field separated by spaces.
- startdate
- get_subfield(idx)[source]#
Access a subfield of the local recording identification field by index.
- Parameters:
- idx
int The index of the subfield to access. The first subfield (starting at index 0) should always be “Startdate” according to the EDF+ spedification.
- idx
- Returns:
strThe subfield at the specified index. If the index exceeds the actually available number of subfields, the return value is
"X".
- property hospital_administration_code[source]#
The hospital administration code of the investigation.
- edfio.read_bdf(bdf_file, *, header_encoding='ascii')[source]#
Read a BDF file into a
Bdfobject.If a file-like object is passed, its stream position is moved to EOF.
- Parameters:
- bdf_file
Path|str|io.BufferedReader|io.BytesIO The file location (path object or string) or file-like object to read from.
- header_encoding
str, default: “ascii” The character encoding to use when reading header fields.
- bdf_file
- Returns:
- edfio.read_edf(edf_file, lazy_load_data='auto', *, header_encoding='ascii')[source]#
Read an EDF file into an
Edfobject.If a file-like object is passed, its stream position is moved to EOF.
- Parameters:
- edf_file
Path|str|io.BufferedReader|io.BytesIO The file location (path object or string) or file-like object to read from.
- lazy_load_databool | {“auto”}, default: “auto”
If
True, the raw signal data is not loaded into memory until it is accessed. IfFalse, the data is loaded immediately. If"auto", the data is loaded lazily if the specified edf_file represents a local path and the extension is not “.bdf” and eagerly otherwise.- header_encoding
str, default: “ascii” The character encoding to use when reading header fields.
- edf_file
- Returns:
Read a BDF file into a |
|
Read an EDF file into an |
|
Python representation of a BDF file. |
|
A single BDF signal. |
|
Python representation of an EDF file. |
|
A single EDF signal. |
|
A single EDF+ annotation. |
|
Object representation of the local patient identification. |
|
Object representation of the local recording identification. |
|
Raised when trying to access an anonymized startdate or birthdate. |