Skip to content
intermediatescience

Sleep-EDF Sleep Stage Scoring in 30-Second Epochs

Score ten real overnight polysomnogram excerpts one 30-second epoch at a time with Rechtschaffen and Kales stages, using epoch-mode intervals and signal-cnn.

Get This Design

View on GitHub(opens in a new tab)

Clone or download from the repository

Quick start:

bash
git clone https://github.com/davidjurgens/potato-showcase.git
cd potato-showcase/science/physiology/sleep-edf-hypnogram-epochs
potato start config.yaml

About this dataset

The Sleep-EDF Database Expanded holds 197 whole-night polysomnographic recordings with EEG, EOG, chin EMG, and event markers, and some records add respiration and body temperature. Kemp and colleagues collected the Sleep Cassette part (153 files) in a 1987 to 1991 study of age effects on sleep in healthy people aged 25 to 101, recorded at home on a cassette-tape recorder. The recordings and the hypnograms are on PhysioNet under the Open Data Commons Attribution License.

The hypnograms were scored by trained technicians according to the 1968 Rechtschaffen and Kales manual, using the Fpz-Cz and Pz-Oz EEG channels. Each 30-second epoch gets one of W, R, 1, 2, 3, 4, M (movement time), or ? (not scored). The design offers the eight labels exactly. The labels are the R&K stages, not the AASM stages, which merge stages 3 and 4 into N3 and name the rest N1, N2, and REM. Ten 5-minute excerpts (10 epochs each) are cut from one night of one subject (recording SC4001E0). Annotators score the excerpts from scratch with the keyboard. The reference stages for the excerpts are in media/reference-stages.csv, for checking afterward. All ten excerpts keep five channels, and the EMG channel is a 1 Hz envelope in the source files.

The model_training block enables the signal-cnn trainer, which in epoch mode learns to classify each annotated epoch from the channels and writes proposed stages back as dashed pre-annotations on recordings nobody has finished. The trainer needs at least three annotated recordings in the training split, and ten excerpts from one subject exercise the loop without teaching a model that generalizes across people.

Whole-night recordings (full database)
197
Sleep Cassette recordings
153
Stage labels
W, R, 1, 2, 3, 4, M, ?
Epoch length
30 seconds
Excerpts in this design
10 (5 minutes each)

Configuration File

This Potato config reproduces the annotation task. Save it as config.yaml and run potato start config.yaml to try it.

yaml
# yaml-language-server: $schema=https://potatoannotator.readthedocs.io/en/latest/schemas/potato-config.schema.json
#
# Sleep-EDF Database Expanded (Sleep Cassette study): sleep staging in
# 30-second epochs, with the Rechtschaffen and Kales stage labels.
#
# Dataset: The Sleep-EDF Database [Expanded]
# Paper (the citation PhysioNet asks for):
#   @article{Kemp_2000,
#     title   = {Analysis of a sleep-dependent neuronal feedback loop: the slow-wave microcontinuity of the EEG},
#     author  = {Kemp, B. and Zwinderman, A.H. and Tuk, B. and Kamphuisen, H.A.C. and Oberye, J.J.L.},
#     journal = {IEEE Transactions on Biomedical Engineering},
#     volume  = {47}, number = {9}, pages = {1185--1194}, year = {2000},
#     doi     = {10.1109/10.867928}
#   }
# DOI: 10.1109/10.867928
# Dataset DOI: 10.13026/C2X676
# Dataset URL: https://physionet.org/content/sleep-edfx/1.0.0/
# Licence: Open Data Commons Attribution License v1.0. The ten excerpts in
# media/ are cut from recording SC4001E0-PSG.edf; see media/LICENSE-media.txt.
#
# Label glossary, quoted from the PhysioNet Data Description:
#   "These patterns (hypnograms) consist of sleep stages W, R, 1, 2, 3, 4,
#   M (Movement time) and ? (not scored)."
#   "All hypnograms were manually scored by well-trained technicians ...
#   according to the 1968 Rechtschaffen and Kales manual, but based on
#   Fpz-Cz/Pz-Oz EEGs instead of C4-A1/C3-A2 EEGs."
#
# Adaptations:
#   - The labels are the Rechtschaffen and Kales (R&K, 1968) stages the
#     Sleep-EDF hypnograms use, with separate stages 3 and 4. They are NOT
#     the AASM stages (N1, N2, N3), which merge 3 and 4. Do not mix the two
#     vocabularies in one study.
#   - Each item is a 5-minute excerpt (10 epochs) cut from one night, not a
#     whole recording, and is annotated from scratch. The reference
#     hypnogram is not loaded as pre-annotations. The reference stages for
#     the excerpts are in media/reference-stages.csv, for checking afterward.
#   - Each excerpt keeps five of the seven channels (EEG Fpz-Cz, EEG Pz-Oz,
#     EOG horizontal, oro-nasal respiration, submental EMG). The EMG channel
#     is a 1 Hz rectified envelope in the source files, not raw EMG. The
#     rectal temperature and event marker channels are left out.
#   - The ten excerpts come from a single subject and night. They show the
#     interface; they are not a sample of the dataset. No excerpt contains M
#     or ? epochs, although both labels are offered.
#
# Model-assisted staging (signal-cnn). Open /admin/training, pick
# signal-cnn for the "stage" scheme, and train. In epoch mode it classifies
# each annotated epoch from the five channels, resampled to 100 Hz, and
# reports macro-F1. With writeback on, it proposes stages for the epochs of
# recordings nobody has finished, shown dashed as pre-annotations. It needs
# at least 3 annotated recordings in its training split (min_instances) and
# the extras from `pip install "potato-annotation[train-vision,signals]"`.
# It does not score against media/reference-stages.csv and does not serve or
# deploy a model. Ten 5-minute excerpts from one subject are enough to exercise the
# loop, not to learn sleep staging that generalizes.
#
# Run: potato start config.yaml -p 8000

port: 8000
annotation_task_name: "Sleep-EDF: score 30-second epochs (Rechtschaffen and Kales)"
task_dir: "."
media_directory: media

data_files:
  - sample-data.json

item_properties:
  id_key: id
  text_key: note

output_annotation_dir: annotation_output
export_annotation_format: jsonl

require_password: false
admin_api_key: "demo-admin-key"

user_config:
  allow_all_users: true

instance_display:
  fields:
    - key: signal
      type: time_series
      label: "Polysomnogram excerpt"
      display_options:
        window: 30
        channels:
          - name: "EEG Fpz-Cz"
            range: [-150, 150]
          - name: "EEG Pz-Oz"
            range: [-150, 150]
          - name: "EOG horizontal"
            range: [-250, 250]
          - name: "Resp oro-nasal"
          - name: "EMG submental"

annotation_schemes:
  - annotation_type: interval_label
    name: stage
    description: "Sleep stage of each 30-second epoch (Rechtschaffen and Kales, 1968). Press a stage key to label the epoch and move to the next; [ and ] move without labelling."
    signal_field: signal
    mode: epoch
    epoch_length: 30
    auto_advance: true
    pre_annotations: false
    # Next stays blocked until every epoch has a stage. Both keys are needed:
    # require_all_epochs only counts while the scheme is required.
    require_all_epochs: true
    label_requirement: {required: true}
    labels:
      - {name: "W", key_value: "w", tooltip: "Wake"}
      - {name: "1", key_value: "1", tooltip: "Stage 1"}
      - {name: "2", key_value: "2", tooltip: "Stage 2"}
      - {name: "3", key_value: "3", tooltip: "Stage 3 (slow-wave sleep)"}
      - {name: "4", key_value: "4", tooltip: "Stage 4 (slow-wave sleep)"}
      - {name: "R", key_value: "r", tooltip: "REM sleep"}
      - {name: "M", key_value: "m", tooltip: "Movement time"}
      - {name: "?", key_value: "u", tooltip: "Not scored"}

model_training:
  enabled: true
  writeback:
    # Show this scheme's predictions to annotators as pre-annotations.
    schemas: ["stage"]
    include_unlabeled: true
    min_confidence: 0.6

annotation_instructions: |
  Each item is a 5-minute excerpt of an overnight recording, shown one
  30-second epoch at a time. Score every epoch with one stage from the
  Rechtschaffen and Kales manual (1968), the manual the Sleep-EDF
  hypnograms follow. Stages 3 and 4 are separate here. Use M for movement
  time and ? for an epoch you cannot score. The strip under the plot shows
  which epochs have a stage; click it to jump.

Sample Data

json
[
  {
    "id": "sleepedf_001",
    "note": "Sleep Cassette recording SC4001E0, 5-minute excerpt 1 of 10 (excerpt starts at epoch 1016 of the night)",
    "signal": "sleepedf_001.edf"
  },
  {
    "id": "sleepedf_002",
    "note": "Sleep Cassette recording SC4001E0, 5-minute excerpt 2 of 10 (excerpt starts at epoch 1054 of the night)",
    "signal": "sleepedf_002.edf"
  }
]

// ... and 8 more items

Dataset & paper

Kemp et al., IEEE Transactions on Biomedical Engineering 2000

Paper DOI
10.1109/10.867928
Dataset DOI
10.13026/C2X676

Citation (BibTeX)

bibtex
@article{Kemp_2000,
  title={Analysis of a sleep-dependent neuronal feedback loop: the slow-wave microcontinuity of the EEG},
  volume={47},
  ISSN={0018-9294},
  url={http://dx.doi.org/10.1109/10.867928},
  DOI={10.1109/10.867928},
  number={9},
  journal={IEEE Transactions on Biomedical Engineering},
  publisher={Institute of Electrical and Electronics Engineers (IEEE)},
  author={Kemp, B. and Zwinderman, A.H. and Tuk, B. and Kamphuisen, H.A.C. and Oberye, J.J.L.},
  year={2000},
  pages={1185--1194}
}

Details

Annotation Types

interval_label

Domain

Sleep medicineNeurosciencePhysiology

Use Cases

Sleep stagingPolysomnography scoringPhysiological signal annotation

Tags

sleep-edfsleep-edfxpolysomnographyhypnogrameegsleep stagingrechtschaffen and kalestime seriesphysionet

Found an issue or want to improve this design?

Open an Issue(opens in a new tab)