Skip to main content

Replay PhysioNet EEG motor imagery as a simulated 4-command brain-computer interface.

Project description

NeuralSim

Replay real PhysioNet EEG motor-imagery recordings as a simulated brain-computer interface (BCI) and watch them get decoded into 4 commands in your terminal, in real time.

LEFT   <--      RIGHT  -->      SELECT  [OK]      IDLE  ...

NeuralSim is a small, readable teaching/prototyping library. It loads recorded brain signals with MNE-Python, streams them as if they were arriving live from a headset, and classifies each window with a transparent NumPy decoder.


What it actually does

  1. Loads the PhysioNet EEG Motor Movement/Imagery dataset via mne.datasets.eegbci (downloads on first use, then caches).
  2. Replays recorded trials through a real-time streamer (BCIStream) that paces output to mimic live acquisition.
  3. Decodes each trial into one of four commands: LEFT, RIGHT, SELECT, IDLE.
  4. Demo: a terminal app shows each incoming signal window, the true label, the decoded command, a confidence bar, and a running accuracy.

Honest caveats (read these)

  • This is a simulator and learning tool, not a production BCI. It replays recorded data; it does not read a live brain.
  • The default decoder is a deliberately simple NumPy band-power nearest-centroid classifier. On real EEG it lands roughly in the 50-70% range for 4 classes (chance is 25%). That is normal for a lightweight motor-imagery decoder and far below clinical systems.
  • For meaningfully better accuracy, install the sklearn extra and switch to CSPDecoder (Common Spatial Patterns + LDA), the standard baseline for this dataset.
  • The SELECT command is mapped from "imagine both fists" trials (runs 6/10/14). It is the weakest-separated class.

Install

pip install -e .                 # core: MNE + NumPy
pip install -e ".[sklearn]"      # + scikit-learn for the CSP+LDA decoder

Python 3.9+.


Quickstart

Run the live demo. First run downloads ~50 MB from PhysioNet:

neuralsim-demo --subject 1 --speed 8

No network or just want to see it run instantly? Use the synthetic stand-in:

neuralsim-demo --synthetic --speed 8

Use the stronger decoder (needs the sklearn extra):

neuralsim-demo --subject 1 --csp

CLI flags: --subject (1-109), --synthetic, --speed (1 = real time), --train-frac, --csp, --seed.

Sample output

NeuralSim :: PhysioNet EEG motor-imagery -> simulated BCI

  120 trials | 64 ch @ 160 Hz | 480 samples/trial | LEFT=30, RIGHT=30, SELECT=30, IDLE=30

  Decoder: NumPy band-power nearest-centroid | trained on 84 trials, streaming 36 live
  ----------------------------------------------------------------
  t=  1 | signal in [64ch x 480] | true LEFT   -> pred <-- LEFT   OK  conf #########--- 74% | acc 100%
  t=  2 | signal in [64ch x 480] | true RIGHT  -> pred ... IDLE   XX  conf ######------ 52% | acc  50%
  ...

Use it as a library

from neuralsim import load_eegbci, make_synthetic, BandPowerDecoder, BCIStream

# Real data (downloads on first call). Or: ds = make_synthetic()
ds = load_eegbci(subject=1)
print(ds.summary())

# Train a decoder
dec = BandPowerDecoder(ch_indices=ds.motor_indices, sfreq=ds.sfreq)
dec.fit(ds.signals, ds.commands)

# Stream trials in "real time" and classify them
for idx, signal, true_cmd in BCIStream(ds.signals, ds.commands, ds.sfreq, speed=8):
    pred, confidence, scores = dec.predict_one(signal)
    print(true_cmd, "->", pred, f"({confidence:.0%})")

Command mapping

PhysioNet annotations (T0/T1/T2) mean different things per run. NeuralSim maps them like this:

Command Source runs Annotation Meaning
LEFT 4, 8, 12 T1 Imagine left fist
RIGHT 4, 8, 12 T2 Imagine right fist
SELECT 6, 10, 14 T1 Imagine both fists
IDLE 4, 8, 12 T0 Rest

How it works

PhysioNet EDF  ->  MNE load + standardize + 7-30 Hz filter  ->  epoch into trials
       |                                                              |
       |                                                       relabel to commands
       v                                                              v
   BCIStream (paced replay)  ----per trial---->  BandPowerDecoder / CSPDecoder
                                                          |
                                                  LEFT / RIGHT / SELECT / IDLE
  • Features (default): log power in the mu (8-12 Hz) and beta (13-30 Hz) bands over motor-cortex channels (C3/Cz/C4 and neighbours), via FFT. Pure NumPy.
  • Classifier (default): z-score features, then nearest class centroid; softmax over negative distance gives a confidence.
  • Classifier (optional): CSPDecoder = MNE CSP + scikit-learn LDA.

Package layout

neuralsim/
├── neuralsim/
│   ├── __init__.py      public API
│   ├── commands.py      Command enum + label mapping
│   ├── data.py          PhysioNet loader (MNE) + synthetic generator
│   ├── decoder.py       band-power decoder (NumPy) + CSP decoder (optional)
│   ├── stream.py        real-time replay
│   └── demo.py          terminal demo + CLI
├── tests/test_smoke.py
├── setup.py
├── pyproject.toml
├── requirements.txt
└── README.md

Run tests with pip install -e ".[dev]" && pytest.


Dependencies

  • MNE-Python (EEG loading and processing)
  • NumPy
  • scikit-learn (optional, only for CSPDecoder)

License

MIT. The PhysioNet EEGBCI dataset has its own terms; see the PhysioNet EEG Motor Movement/Imagery Dataset.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

neuralsim-0.3.0.tar.gz (20.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

neuralsim-0.3.0-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file neuralsim-0.3.0.tar.gz.

File metadata

  • Download URL: neuralsim-0.3.0.tar.gz
  • Upload date:
  • Size: 20.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.1

File hashes

Hashes for neuralsim-0.3.0.tar.gz
Algorithm Hash digest
SHA256 562ce5ab6e3418c00a6d93fe2f03d1de5a635af169e890d84ef071a0179ec233
MD5 ecd8ead92f691d28a57e4f3b7a4755ac
BLAKE2b-256 f9d4558b0a7809d88a64ab845c0b66a203b036d3809cf2a97e142fdfd7178273

See more details on using hashes here.

File details

Details for the file neuralsim-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: neuralsim-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 20.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.1

File hashes

Hashes for neuralsim-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5861f83294189f181cbf2e79afecaac731c7691de9f49bd4e8e93f8263dc0d63
MD5 760b30ca8a9f4df513f945410d321191
BLAKE2b-256 4927cf1d994fc3ec814a6b82ece02d728d5a0ed4d3919f241a59cb03ae722d6e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page