0
# EDF File Reading
1
2
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.
3
4
## Capabilities
5
6
### File Opening and Closing
7
8
Open EDF files with various reading options and automatic resource management through context managers.
9
10
```python { .api }
11
class EdfReader:
12
def __init__(self, file_name: str, annotations_mode: int = READ_ALL_ANNOTATIONS,
13
check_file_size: int = CHECK_FILE_SIZE):
14
"""
15
Initialize EDF reader.
16
17
Parameters:
18
- file_name: str, path to EDF/BDF file
19
- annotations_mode: int, annotation reading mode (DO_NOT_READ_ANNOTATIONS, READ_ANNOTATIONS, READ_ALL_ANNOTATIONS)
20
- check_file_size: int, file size checking mode (CHECK_FILE_SIZE, DO_NOT_CHECK_FILE_SIZE, REPAIR_FILE_SIZE_IF_WRONG)
21
"""
22
23
def __enter__(self) -> EdfReader:
24
"""Context manager entry."""
25
26
def __exit__(self, exc_type, exc_val, exc_tb):
27
"""Context manager exit with automatic cleanup."""
28
29
def close(self):
30
"""Close file handler and release resources."""
31
```
32
33
Usage example:
34
35
```python
36
# Using context manager (recommended)
37
with pyedflib.EdfReader('data.edf') as f:
38
# Work with file
39
signals = f.readSignal(0)
40
41
# Manual management
42
f = pyedflib.EdfReader('data.edf')
43
try:
44
signals = f.readSignal(0)
45
finally:
46
f.close()
47
```
48
49
### Signal Data Reading
50
51
Read signal data from individual channels with support for partial reading, digital/physical values, and numpy array output.
52
53
```python { .api }
54
def readSignal(self, chn: int, start: int = 0, n: Optional[int] = None,
55
digital: bool = False) -> np.ndarray:
56
"""
57
Read signal data from specified channel.
58
59
Parameters:
60
- chn: int, channel number (0-based)
61
- start: int, starting sample index
62
- n: int or None, number of samples to read (None = all remaining)
63
- digital: bool, return digital values if True, physical values if False
64
65
Returns:
66
numpy.ndarray: Signal data
67
"""
68
69
def getNSamples(self) -> np.ndarray:
70
"""
71
Get number of samples for each signal.
72
73
Returns:
74
numpy.ndarray: Array of sample counts per channel
75
"""
76
```
77
78
Usage example:
79
80
```python
81
with pyedflib.EdfReader('recording.edf') as f:
82
# Read entire signal from channel 0
83
signal = f.readSignal(0)
84
85
# Read partial signal (samples 1000-2000)
86
partial = f.readSignal(0, start=1000, n=1000)
87
88
# Read digital values instead of physical
89
digital_signal = f.readSignal(0, digital=True)
90
91
# Get sample counts for all channels
92
sample_counts = f.getNSamples()
93
```
94
95
### Annotation Reading
96
97
Extract annotations (events, markers) from EDF+ and BDF+ files with timing information and descriptions.
98
99
```python { .api }
100
def readAnnotations(self) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
101
"""
102
Read all annotations from file.
103
104
Returns:
105
Tuple containing:
106
- onset_times: numpy.ndarray, annotation start times in seconds
107
- durations: numpy.ndarray, annotation durations in seconds
108
- descriptions: numpy.ndarray, annotation text descriptions
109
"""
110
```
111
112
Usage example:
113
114
```python
115
with pyedflib.EdfReader('annotated.edf') as f:
116
onsets, durations, descriptions = f.readAnnotations()
117
118
# Process annotations
119
for i in range(len(onsets)):
120
print(f"Event at {onsets[i]}s, duration {durations[i]}s: {descriptions[i]}")
121
```
122
123
### Header Information Access
124
125
Retrieve comprehensive file and signal header information including patient data, recording details, and signal parameters.
126
127
```python { .api }
128
def getHeader(self) -> Dict:
129
"""
130
Get complete file header as dictionary.
131
132
Returns:
133
dict: File header with patient info, recording details, technical data
134
"""
135
136
def getSignalHeader(self, chn: int) -> Dict:
137
"""
138
Get header information for specific signal.
139
140
Parameters:
141
- chn: int, channel number
142
143
Returns:
144
dict: Signal header with label, units, sampling rate, calibration
145
"""
146
147
def getSignalHeaders(self) -> List[Dict]:
148
"""
149
Get headers for all signals.
150
151
Returns:
152
List[dict]: List of signal headers
153
"""
154
```
155
156
### Patient and Recording Information
157
158
Access patient demographics, recording metadata, and technical details.
159
160
```python { .api }
161
def getPatientName(self) -> str:
162
"""Get patient name."""
163
164
def getPatientCode(self) -> str:
165
"""Get patient identification code."""
166
167
def getPatientAdditional(self) -> str:
168
"""Get additional patient information."""
169
170
def getSex(self) -> str:
171
"""Get patient sex/gender."""
172
173
def getBirthdate(self, string: bool = True) -> Union[str, datetime]:
174
"""
175
Get patient birthdate.
176
177
Parameters:
178
- string: bool, return as string if True, datetime object if False
179
180
Returns:
181
str or datetime: Patient birthdate
182
"""
183
184
def getTechnician(self) -> str:
185
"""Get technician name."""
186
187
def getEquipment(self) -> str:
188
"""Get recording equipment information."""
189
190
def getAdmincode(self) -> str:
191
"""Get administration code."""
192
193
def getRecordingAdditional(self) -> str:
194
"""Get additional recording information."""
195
196
def getStartdatetime(self) -> datetime:
197
"""Get recording start date and time."""
198
199
def getFileDuration(self) -> float:
200
"""
201
Get total file duration in seconds.
202
203
Returns:
204
float: Duration in seconds
205
"""
206
```
207
208
### Signal Properties
209
210
Access signal-specific properties including labels, sampling rates, and calibration parameters.
211
212
```python { .api }
213
def getSignalLabels(self) -> List[str]:
214
"""
215
Get labels for all signals.
216
217
Returns:
218
List[str]: Signal labels
219
"""
220
221
def getLabel(self, chn: int) -> str:
222
"""
223
Get label for specific channel.
224
225
Parameters:
226
- chn: int, channel number
227
228
Returns:
229
str: Signal label
230
"""
231
232
def getSampleFrequencies(self) -> np.ndarray:
233
"""
234
Get sampling frequencies for all signals.
235
236
Returns:
237
numpy.ndarray: Sample rates in Hz
238
"""
239
240
def getSampleFrequency(self, chn: int) -> float:
241
"""
242
Get sampling frequency for specific channel.
243
244
Parameters:
245
- chn: int, channel number
246
247
Returns:
248
float: Sample rate in Hz
249
"""
250
251
def getPhysicalMaximum(self, chn: Optional[int] = None) -> Union[float, np.ndarray]:
252
"""
253
Get physical maximum values.
254
255
Parameters:
256
- chn: int or None, channel number (None = all channels)
257
258
Returns:
259
float or numpy.ndarray: Physical maximum value(s)
260
"""
261
262
def getPhysicalMinimum(self, chn: Optional[int] = None) -> Union[float, np.ndarray]:
263
"""
264
Get physical minimum values.
265
266
Parameters:
267
- chn: int or None, channel number (None = all channels)
268
269
Returns:
270
float or numpy.ndarray: Physical minimum value(s)
271
"""
272
273
def getDigitalMaximum(self, chn: Optional[int] = None) -> Union[int, np.ndarray]:
274
"""
275
Get digital maximum values.
276
277
Parameters:
278
- chn: int or None, channel number (None = all channels)
279
280
Returns:
281
int or numpy.ndarray: Digital maximum value(s)
282
"""
283
284
def getDigitalMinimum(self, chn: Optional[int] = None) -> Union[int, np.ndarray]:
285
"""
286
Get digital minimum values.
287
288
Parameters:
289
- chn: int or None, channel number (None = all channels)
290
291
Returns:
292
int or numpy.ndarray: Digital minimum value(s)
293
"""
294
295
def getPhysicalDimension(self, chn: int) -> str:
296
"""
297
Get physical dimension (units) for channel.
298
299
Parameters:
300
- chn: int, channel number
301
302
Returns:
303
str: Physical dimension (e.g., 'uV', 'mV')
304
"""
305
306
def getTransducer(self, chn: int) -> str:
307
"""
308
Get transducer information for channel.
309
310
Parameters:
311
- chn: int, channel number
312
313
Returns:
314
str: Transducer description
315
"""
316
317
def getPrefilter(self, chn: int) -> str:
318
"""
319
Get prefilter information for channel.
320
321
Parameters:
322
- chn: int, channel number
323
324
Returns:
325
str: Prefilter description
326
"""
327
```
328
329
### File Properties
330
331
Access file-level properties for quick information retrieval.
332
333
```python { .api }
334
@property
335
def signals_in_file(self) -> int:
336
"""Number of signals in the file."""
337
338
@property
339
def datarecords_in_file(self) -> int:
340
"""Number of data records in the file."""
341
342
@property
343
def file_duration(self) -> float:
344
"""File duration in seconds."""
345
346
@property
347
def filetype(self) -> int:
348
"""File type (EDF=0, EDF+=1, BDF=2, BDF+=3)."""
349
350
@property
351
def datarecord_duration(self) -> float:
352
"""Duration of each data record in seconds."""
353
354
@property
355
def annotations_in_file(self) -> int:
356
"""Number of annotations in the file."""
357
```
358
359
Usage example:
360
361
```python
362
with pyedflib.EdfReader('data.edf') as f:
363
# Access file properties
364
print(f"Signals: {f.signals_in_file}")
365
print(f"Duration: {f.file_duration} seconds")
366
print(f"File type: {f.filetype}")
367
print(f"Data records: {f.datarecords_in_file}")
368
print(f"Annotations: {f.annotations_in_file}")
369
```
370
371
### Information Display
372
373
Convenient methods for displaying file information.
374
375
```python { .api }
376
def file_info(self):
377
"""Print basic file information to console."""
378
379
def file_info_long(self):
380
"""Print detailed file information to console."""
381
```
382
383
Usage example:
384
385
```python
386
with pyedflib.EdfReader('data.edf') as f:
387
# Display file info
388
f.file_info()
389
390
# Get detailed properties
391
header = f.getHeader()
392
labels = f.getSignalLabels()
393
sample_rates = f.getSampleFrequencies()
394
395
print(f"Patient: {f.getPatientName()}")
396
print(f"Recording duration: {f.getFileDuration()} seconds")
397
print(f"Channels: {labels}")
398
print(f"Sample rates: {sample_rates}")
399
```
400
401
## Constants
402
403
```python { .api }
404
# Annotation reading modes
405
DO_NOT_READ_ANNOTATIONS: int = 0
406
READ_ANNOTATIONS: int = 1
407
READ_ALL_ANNOTATIONS: int = 2
408
409
# File size checking modes
410
CHECK_FILE_SIZE: int = 0
411
DO_NOT_CHECK_FILE_SIZE: int = 1
412
REPAIR_FILE_SIZE_IF_WRONG: int = 2
413
```