Use a Published Sleep Study

Run inference with a pre-trained model from HuggingFace

SleePyPhases supports published, pre-trained sleep staging models distributed as HuggingFace repositories. This guide shows how to load and run inference with SPPPPG-Net — a PPG-based sleep stager trained with SleePyPhases and published at sleep-is-all-you-need/SPPPPG-Net.

The model implements SleepPPG-Net (Kotzen et al., IEEE JBHI 2022): a deep learning algorithm for robust, 4-class sleep staging from a single photoplethysmography (PPG) channel — no EEG required.


Installation

pip install SleePyPhases pyPhasesRecordloaderMESA SPPPPGNet

Predict from an EDF file

The simplest path: point the project at an EDF and get a hypnodensity back.

from SleePyPhases import SleePyPhases

project = SleePyPhases.create(plugins=["pyPhasesRecordloaderMESA", "SPPPPGNet"])

# Optional: remap your channel name to "Pleth" if it differs
# project.setConfig("predict.channelMapping", {"myChannel": "Pleth"})

fileName = "export/Example.edf"
prediction = project.predictFromFile(fileName)

prediction is a list of probability arrays with shape (T, 4) — one row per 30-second epoch, four columns for Wake / REM / Light / Deep.


Predict from a custom in-memory signal

If you already have the raw PPG array (e.g. loaded with pyedflib), build a RecordSignal directly:

import pyedflib
from SleePyPhases import SleePyPhases
from pyPhasesRecordloader import RecordSignal, Signal

project = SleePyPhases.create(plugins=["pyPhasesRecordloaderMESA", "SPPPPGNet"])

with pyedflib.EdfReader(fileName) as edf:
    signal_labels = edf.getSignalLabels()
    fs = edf.getSampleFrequency(signal_labels.index("Pleth"))
    pleth_signal = edf.readSignal(signal_labels.index("Pleth"))

rs = RecordSignal()
rs.addSignal(Signal("Pleth", pleth_signal, fs, typeStr="ppg"))  # typeStr required for preprocessing

prediction = project.predictRecordSignal(rs)
Tip

typeStr="ppg" triggers PPG-specific preprocessing steps (bandpass filter, resampling to 32 Hz).


Predict via a registered record loader

If you have a MESA dataset on disk, register the loader once and use record IDs directly:

from SleePyPhases import SleePyPhases
from pyPhasesRecordloader import RecordLoader

project = SleePyPhases.create(plugins=["pyPhasesRecordloaderMESA", "SPPPPGNet"])

project.setConfig("mesa-path", "/datasets/mesa")
project.setConfig("useLoader", "mesa")
rl = RecordLoader.get()

recordSignal, events = rl.loadRecord("mesa-sleep-0001")
prediction = project.predictRecordSignal(recordSignal)

Visualise the hypnogram

from matplotlib import pyplot as plt
import numpy as np

hypno = prediction[0]          # shape (T, 4)
T = hypno.shape[0]
time = np.arange(T)

labels = ['Wake', 'REM', 'Light', 'Deep']
colors = ['#f94144', '#f3722c', '#90dbf4', '#577590']

plt.figure(figsize=(12, 4))
plt.stackplot(time, hypno.T, labels=labels, colors=colors)
plt.ylim(0, 1)
plt.xlim(0, T - 1)
plt.ylabel('Probability')
plt.xlabel('Epoch (30 s)')
plt.title('Hypnodensity Plot — SleepPPG-Net')
plt.legend(loc='upper right', ncol=4)
plt.tight_layout()
plt.show()

The stacked area plot shows the model’s per-epoch class probabilities (a hypnodensity), giving a richer view than a discrete hypnogram.


Model details

Property Value
HuggingFace repo sleep-is-all-you-need/SPPPPG-Net
Input channel PPG (“Pleth”) at 32 Hz
Output classes Wake · REM · Light · Deep (4-class)
Output shape (T, 4) probabilities per 30-second epoch
Plugin name SPPPPGNet
License fair-noncommercial-research-license

Citation

Kotzen, Kevin, et al. “SleepPPG-Net: A deep learning algorithm for robust sleep staging from continuous photoplethysmography.” IEEE Journal of Biomedical and Health Informatics 27.2 (2022): 924–932. https://doi.org/10.1109/JBHI.2022.3225363