The European Data Format, almost always shortened to EDF, is the most widely used open file format for long physiological recordings. Sleep laboratories export polysomnographies in it, EEG systems use it for routine and ambulatory studies, and public research databases distribute thousands of hours of signals as EDF files. Its success comes from the same property that makes it easy to inspect: a very simple, fixed layout that has barely changed since 1992.
A Short History
EDF was published in 1992 by Bob Kemp and colleagues as a common format for exchanging digitised polygraphic recordings between laboratories that used incompatible equipment. In 2003 Kemp and Olivan published EDF+, a backward-compatible extension that adds standardised text annotations, structured patient and recording identification, and support for recordings with interruptions. Around the same time the electrophysiology manufacturer BioSemi introduced BDF, a variant with 24-bit samples for high-resolution EEG. All three share the same header structure, which is why a single viewer can read them all.
The Header: Plain Text With Fixed Widths
Every EDF file begins with a 256-byte header written in printable ASCII characters. Each field has a fixed width and is padded with spaces:
- Version (8 bytes): the text
0 for EDF, or the byte 255 followed by BIOSEMI for BDF.
- Local patient and recording identification (80 bytes each): free text in EDF, structured subfields in EDF+.
- Start date and start time (8 bytes each), written as
dd.mm.yy and hh.mm.ss. Two-digit years from 85 to 99 mean 1985–1999, and 00 to 84 mean 2000–2084.
- Number of bytes in the header, a reserved field that EDF+ uses for
EDF+C or EDF+D, the number of data records, the duration of one data record in seconds, and the number of signals.
After this fixed part comes another 256 bytes per signal. The signal fields are stored column by column: first all the labels, then all the transducer types, then all the physical dimensions, and so on. For each signal the header records a 16-character label such as EEG Fpz-Cz, the transducer, the physical unit, the physical minimum and maximum, the digital minimum and maximum, a prefiltering description such as HP:0.3Hz LP:35Hz, and the number of samples in each data record.
Data Records and Sample Rates
The signal data follows the header as a series of data records of equal length. Each record holds a fixed number of samples for each signal, one signal after another. Samples are 16-bit two's complement integers stored little-endian in EDF and 24-bit integers in BDF. Signals do not need to share a sample rate: a record lasting 30 seconds might contain 3,000 EEG samples at 100 Hz, 6,000 ECG samples at 200 Hz and just 30 oxygen saturation samples at 1 Hz. A signal's sample rate is simply its number of samples per record divided by the record duration.
Because every record has the same size, any moment of the recording can be found with arithmetic instead of scanning: the byte offset of record n is the header size plus n times the record size. That is what allows this viewer to open a recording of several gigabytes and show any ten-second window almost instantly.
From Digital Values to Physical Units
The integers in the file are not microvolts or percentages. They are converted with a straight-line mapping defined by the four range fields of each signal: the digital minimum corresponds to the physical minimum and the digital maximum to the physical maximum. The gain is the physical range divided by the digital range, and every value in between is scaled linearly. If a header declares a digital minimum that is not lower than the digital maximum, or equal physical limits, the conversion is undefined, and this tool reports it instead of silently plotting nonsense.
The digital limits usually describe the extreme values the amplifier and converter could produce. When many samples sit exactly on one of those limits, the input most likely exceeded the measuring range — a loose electrode, a movement artefact or a gain set too high. The clipped column in the signal table counts those samples so you can spot saturated channels at a glance.
What EDF+ Adds
EDF+ keeps the original layout and adds conventions on top of it. The patient field becomes four space-separated subfields — hospital code, sex, birthdate and name — where spaces inside a subfield are replaced with underscores and an unknown value is written as X. The recording field starts with the word Startdate, followed by the full date, an administration code, the technician and the equipment.
The most important addition is the EDF Annotations signal. It is stored as a normal signal but contains text rather than samples: Time-stamped Annotation Lists, or TALs. Each TAL starts with an onset in seconds relative to the start of the file, optionally a duration, and one or more texts, separated by the bytes 20 and 21 and terminated with a zero byte. Sleep stages, arousals, apnoea events, stimulus markers and technician notes all live here. The first TAL in each record is a time-keeping entry with an empty text that states when that record starts.
Continuous and Discontinuous Recordings
An EDF+C file is continuous: record n starts exactly n times the record duration after the file start. An EDF+D file is discontinuous, which suits event recorders or evoked-potential studies that only store selected stretches. In that case the time-keeping annotation is the only reliable source for the time of each record, so this viewer reads it for every record and draws a marker where the recording skips forward.
Common Problems in Real Files
Because EDF is simple, many programs write it, and not all of them get every detail right. The problems met most often in practice are:
- A record count of -1. The specification allows it while a recording is still running, but some files are never finalised. The real count can be recovered from the file size.
- Truncated files. An interrupted copy or a full disk leaves a partial last record. Readers that trust the header then fail or read past the end.
- Wrong header size. The declared number of header bytes must equal 256 times the number of signals plus one. When it does not, readers disagree about where the data starts.
- Invalid dates and non-ASCII characters. Local characters in patient names or labels break strict parsers, and impossible dates such as 31 February appear more often than one would expect.
Each of these produces a specific, readable warning in the tool, which is usually enough to explain why another program rejects the file.
When Not to Use This Tool
This viewer is designed for inspection, quality control and troubleshooting. It does not apply montages, digital filters or sleep scoring, and it deliberately shows the data as stored rather than as a clinical review system would present it. For diagnostic reading use certified clinical software. For batch conversion or analysis of many files, a scripting library such as MNE-Python or pyEDFlib is the better fit — this tool is the fast way to check, one file at a time, what those scripts will actually receive.