How to Open and Read an EDF File: Header, Channels and Annotations
Biosignal Tools

How to Open and Read an EDF File: Header, Channels and Annotations

Sooner or later, anyone who works with sleep studies, EEG or long ECG recordings receives a file ending in .edf and needs to know what is inside it. Maybe a research partner sent a dataset, maybe a new amplifier exports its recordings that way, or maybe an analysis script refuses to load a file that looks perfectly normal. The European Data Format was designed to be simple, and that simplicity means you can answer most questions about a file in a few minutes โ€” if you know where to look.

This guide walks through that process in the order that saves the most time: identify the variant, read the header, understand the channels, check the annotations and, finally, look for the errors that make other programs reject a file. You can follow along with any recording in our EDF Viewer, which runs entirely in your browser, or with the built-in examples if you do not have a file at hand.

Step 1: Identify Which Variant You Have

The file extension tells you little. EDF, EDF+ and BDF files share the same header layout, and some systems even use the .rec extension for EDF data. What really identifies the variant are two header fields.

The first eight bytes are the version. An EDF or EDF+ file stores the character 0 followed by spaces. A BDF file, the 24-bit variant introduced by BioSemi, starts with the byte value 255 followed by the letters BIOSEMI. If neither appears, the file is not in this family at all โ€” a common surprise when a file has been renamed from another format.

The second is the 44-byte reserved field. In plain EDF it is empty. EDF+ writes EDF+C for a continuous recording or EDF+D for a discontinuous one, and BDF files usually carry 24BIT. The distinction matters because EDF+ files have extra structure โ€” standardised patient fields and an annotation channel โ€” that a plain EDF reader will ignore or, worse, show as a meaningless signal.

Step 2: Read the Fixed Header

Once you know the variant, read the rest of the 256-byte fixed header. Every field is plain ASCII text padded with spaces, so a header is readable even in a hex editor. Five fields deserve particular attention.

Start date and time

These are stored as dd.mm.yy and hh.mm.ss. The two-digit year uses a clipping rule: 85 to 99 means 1985 to 1999, and 00 to 84 means 2000 to 2084. EDF+ files also write the full four-digit year inside the recording identification field, after the word Startdate, and that value should agree with the short one. Note that the time is the local clock time of the recording device; the format has no time zone field.

Number of data records and record duration

A recording is divided into data records of equal length, very often one second or thirty seconds. Multiplying the number of records by the record duration gives the total length. A value of -1 in the record count means the recording was never finalised โ€” the specification allows it only while acquisition is still in progress.

Number of header bytes and number of signals

These two must be consistent: the header size is always 256 bytes multiplied by the number of signals plus one. A file with 20 signals has a 5,376-byte header. When the declared size disagrees, different programs may start reading the data at different places, which is one of the more confusing ways a file can appear to be corrupt.

Step 3: Understand the Channels

After the fixed header comes one 256-byte block per signal, with the fields arranged column by column. For each channel you get a label, the transducer type, the physical unit, four range values, a prefiltering description and the number of samples per data record. Together they answer the practical questions researchers ask most often.

What is the sample rate?

EDF does not store sample rates directly. Divide the number of samples per record by the record duration. A channel with 256 samples per one-second record runs at 256 Hz; a channel with 3,000 samples per 30-second record runs at 100 Hz. Channels in the same file frequently have different rates: in a typical polysomnography, EEG and ECG are sampled far faster than respiratory effort or oxygen saturation. Scripts that assume a single rate for the whole file are a frequent source of misaligned or stretched signals.

What units are the values in?

The integers in the file are converted to physical values using the physical minimum and maximum and the digital minimum and maximum. The mapping is linear: the digital minimum becomes the physical minimum, the digital maximum becomes the physical maximum. The unit comes from the physical dimension field โ€” uV, mV, %, degC and so on. If the unit is blank, as it often is for respiratory belts, the values are in arbitrary units and only their shape is meaningful.

How was the signal filtered?

The prefiltering field is free text, but most systems follow the convention of the specification: HP:0.3Hz LP:35Hz N:50Hz for a high-pass, low-pass and notch filter. Reading it before analysis prevents a classic mistake: applying a second high-pass filter to data that was already filtered by the amplifier, or looking for slow waves in a channel that was high-passed above the frequencies you care about.

Is any channel saturated?

The digital limits normally describe the extreme values the converter could produce. When a large share of samples sits exactly at one of those limits, the input most likely went out of range โ€” a detached electrode, a movement artefact or a gain set too high. The EDF Viewer counts those samples for every channel in its signal table, which makes a flat-topped channel obvious before you even look at a waveform.

How to Open and Read an EDF File: Header, Channels and Annotations

Step 4: Check the Annotations

In EDF+ and BDF+ files, one or more channels labelled EDF Annotations (or BDF Annotations) contain text instead of samples. They hold Time-stamped Annotation Lists: an onset in seconds from the start of the file, an optional duration, and one or more texts. This is where scored sleep stages, arousals, respiratory events, stimulus markers and technician notes are stored.

Three details regularly confuse people:

  • Hypnograms may live in a separate file. Several public sleep databases distribute the signals in one EDF file and the scored stages in a second EDF+ file that contains only an annotation channel. Opening the signal file alone shows no sleep stages at all.
  • Every record has a time-keeping annotation. The first annotation of each data record has an empty text and simply states when the record starts. Readers hide it, but it is what makes discontinuous files work.
  • Annotation text is UTF-8. Unlike the header, which must be plain ASCII, annotation texts may contain accented or non-Latin characters, so a note written in Spanish or Japanese should display correctly.

Step 5: Continuous or Discontinuous?

For an EDF+C or plain EDF file, time is implicit: record number n starts n times the record duration after the start of the file. For an EDF+D file that is not true. Event recorders and some evoked-potential systems only store selected stretches, and the start time of each record comes from its time-keeping annotation. If you convert such a file to a plain array of samples and assume uniform timing, the events in it will appear at the wrong moments. When you page through an EDF+D file in the viewer, a marker shows each place where the recording skips forward and how large the gap is.

Troubleshooting: Why Won't My EDF File Open?

When a program rejects a file or shows garbage, the cause is almost always one of a handful of header problems. Checking for them in order resolves most cases.

  1. The file is truncated. Compare the size the header implies โ€” header bytes plus records multiplied by record size โ€” with the actual file size. A shortfall means the last record is incomplete, typically after an interrupted copy or a full disk during recording. Readers that trust the header then fail at the end of the file. The data before the break is usually intact.
  2. The record count is -1 or wrong. The true number of complete records can be computed from the file size, and a tolerant reader will use that. A strict reader will refuse the file.
  3. The header size does not match the number of signals. Some writers put an incorrect value in this field. Because the signal headers have a fixed size, the data still begins at 256 multiplied by the number of signals plus one.
  4. Invalid ranges. A digital minimum that is not smaller than the digital maximum, or identical physical limits, make the conversion to physical units undefined. This often affects a single auxiliary channel.
  5. Non-ASCII characters or impossible dates. Accented patient names or labels, and dates such as 31.02, break parsers that follow the specification strictly.

The EDF Viewer checks every one of these and describes each problem in a readable warning, so you can tell a colleague exactly what is wrong with a file rather than just that it "does not open".

A Note on Privacy Before Sharing Files

The 80-character local patient identification field is part of every EDF header, and in clinical exports it frequently contains a name, a birthdate or a hospital number. EDF+ even defines it as structured subfields for exactly that information. Before you send a recording outside your organisation, look at this field and at the recording identification field, which may include a technician's name. EDF+ uses the letter X for unknown subfields, so an anonymised file can still be valid.

This is also why the choice of tool matters. Uploading an unknown file to an online converter to find out what it contains can itself be a disclosure of health information. A viewer that reads the file locally lets you inspect the header, including its identifying fields, without that risk.

A Quick Checklist

When a new EDF file arrives, these questions cover almost everything you need to know before analysis:

  • Is it EDF, EDF+C, EDF+D or BDF?
  • Does the start date make sense, and what is the total duration?
  • How many channels are there, what are their labels, units and sample rates?
  • What prefiltering was applied by the acquisition system?
  • Are there annotations, and if you expected sleep stages, are they in this file or a separate one?
  • Does the file size agree with the header, and are any channels saturated?
  • Does the patient field contain identifying information that must be removed before sharing?

Answering them takes a couple of minutes with the EDF Viewer, and it prevents the much longer debugging session that follows when an analysis quietly uses the wrong sample rate, the wrong time base or a truncated file.

← Back to Blog