Skip to main content

nimbus-bci

Nimbus Personalizer — Bayesian personalization head for frozen neural EEG embeddings.
Plug any frozen trunk that emits encode(X) → Z, adapt online with a Nimbus head, ship apps on BrainState — without owning or retraining the encoder.

0.6 product shape: the Personalizer surface — cheap online adaptation (~8–10× cheaper than batch refit, ~22–131× cheaper than trunk retraining at matched n), portable profiles, and paradigm recipes (MI · P300 · Riemannian).

Also ships sklearn-compatible heads for classical feature pipelines (CSP, Riemann, …): Bayesian LDA / QDA / Softmax, plus NimbusSTS (EKF latent state + point-estimated emissions). Those heads power Personalizer and can be used alone.

Docs · Personalizer · API reference · PyPI · Contact

Install

pip install nimbus-bci
# optional: pip install nimbus-bci[softmax]   # JAX Softmax head
# optional: pip install nimbus-bci[riemann]   # pyRiemann pipelines
# optional: pip install nimbus-bci[mne]       # MNE helpers
# optional: pip install nimbus-bci[train]     # torch trunk-arm trainers (LoRA / FT)
# optional: pip install nimbus-bci[viz]       # matplotlib plotting helpers
# optional: pip install nimbus-bci[all]       # everything above

From source: pip install -e ".[all]" after cloning.

Upgrading from 0.5? See Migration notes in CHANGELOG.md (ships in the sdist; also linked from docs.nimbusbci.com).

5-minute quickstart

Run the example (no external data needed):

python examples/quickstart.py

Or follow along:

import numpy as np
from nimbus_bci import Personalizer, wrap

# 1. Wrap any frozen trunk (EEGNet, REVE, ...) — here a random projection.
rng = np.random.default_rng(42)
proj = rng.standard_normal((6, 16))
enc = wrap(lambda X: X @ proj, model_id="toy", embedding_dim=16)

# 2. Fit a Bayesian head on ~30 calibration trials.
#    for_deployment = strict gating + LDA + minimal params (the common case).
#    For research/experimentation: Personalizer.for_research(enc, classes, ...).
#    For classical features (no encoder): Personalizer.for_features(classes).
#    To PIN the accept rate for your trunk (default-gate accept rates span
#    7-78% across trunks), fit + calibrate the gate in one call:
#    adapter.fit_calibrated(X_cal, y_cal, X_val, y_val, target_accept=0.7)
adapter = Personalizer.for_deployment(enc, ["left_hand", "right_hand"],
                                       paradigm="motor_imagery")
adapter.fit(X_cal, y_cal)

# 3. Predict → BrainState with trial rejection.
states = adapter.predict(X_test)         # list[BrainState]
accepted = [s for s in states if not s.rejected]  # confident trials
# s.intent, s.confidence, s.uncertainty, s.rejected, s.rejection_reason

# 4. Adapt online (exact conjugate update — no retraining).
adapter.partial_fit(X_new, y_new)

# 5. Save / load.
adapter.save("profile"); loaded = Personalizer.load("profile", encoder=enc)

The three regimes

# A. Classical features (CSP log-variance, tangent space, hand-crafted) —
#    no encoder, features go straight to the Bayesian head.
p = Personalizer.for_features(["left", "right"]).fit(X_csp, y)

# B. Frozen deep trunk (EEGNet, foundation model) — embeddings → head,
#    strict trial gating out of the box.
p = Personalizer.for_deployment(enc, ["left", "right"]).fit(X_cal, y_cal)
states = p.predict(X_test)          # BrainState per trial, rejected flagged

# C. Riemannian geometry & P300 (OAS / xDAWN tangent space) —
#    weak-trunk / raw epochs; for_riemann defaults to label-free geodesic
#    tracking (tracking_alpha=0.05). Opt out with tracking_alpha=0.0.
p = Personalizer.for_riemann(["left", "right"]).fit(X_cal, y_cal)
# Or for P300 spellers (tracking opt-in; recommend α=0.05 when enabling):
# Personalizer.for_p300(["NonTarget", "Target"], tracking_alpha=0.05)
p.adapt(epoch)                      # label-free reference update (0 labels needed!)

# D. Streaming adaptation loop — predict, optionally partial_fit on new
#    labels; the conjugate head update is exact and cheap (no retraining).
#    Reference: examples/middleware_streaming_adaptation.py
for trial in stream:
    state = p.predict(trial)                # BrainState
    if label_available(state):
        p.partial_fit(trial, label)         # ~1/30-1/131 the wall cost of retraining

Regime A/B/C are the shipped surface. A governed session runtime (drift gates, attribution, label budgets, quarantine) with subconscious error-potential self-supervision is in research and will ship separately.

The full parameter surface (user=, preset=, head choice) via direct construction — anything that maps inputs to embeddings (n, d) plugs in; Nimbus does not own DL architectures:

adapter = Personalizer(
    encoder=enc, head="lda", user="subject_001",
    classes=["left", "right"], preset="strict",
)

Full walkthrough with copy-paste synthetic data: Quickstart.

Optional shortcuts for common external trunks: wrap_eegnet, and from nimbus_bci.middleware.adapters import wrap_braindecode (see encoder contract).

Examples in this repo: middleware_personalizer.py, middleware_streaming_adaptation.py, middleware_geometry_gateway.py, middleware_mi_session.py, middleware_braindecode.py, middleware_reve.py, middleware_recommend_adapt.py.
Bench EEGNet demo (repo-only, needs nimbusbench[dl]): nimbusbench/scripts/middleware_eegnet.py.

When to adapt (thin helper)

Optional mean-shift check before spending labels on partial_fit. You choose the threshold tau.

dec = adapter.recommend_adapt(X_stream, tau=your_tau)  # stay vs stream update
if dec.should_adapt:
    adapter.partial_fit(X_lab, y_lab)

Trial rejection (BrainState.rejected / need_more_data) is a different gate — accept/reject the intent for the app.
Details: BrainState · recipe: examples/middleware_recommend_adapt.py.

A governed adaptation session — drift gates, label budgets, quarantine, and rollback — is under research and will ship as a separate release once its evidence matures.

Classical heads (CSP / features)

Same Bayesian heads without an encoder — inputs are already features:

from nimbus_bci import NimbusLDA

clf = NimbusLDA()
clf.fit(X_train, y_train)
proba = clf.predict_proba(X_test)
clf.partial_fit(X_new, y_new)

Also: streaming (StreamingSession), active learning (CalibrationSession), MNE helpers, optional Riemann pipelines. See docs.nimbusbci.com and examples/e2e_mne_csp_nimbus.py.

Head Role
NimbusLDA / NimbusQDA Conjugate Bayesian LDA/QDA
NimbusSoftmax Polya–Gamma VI (optional JAX)
NimbusSTS EKF latent-state / drift (EKF on z; point W/H/b)

Evidence

Public Personalizer story (heads, cost vs fine-tune, multi-trunk / REVE):
Evidence · Overview.

License

Two-track proprietary license — see the LICENSE.txt shipped with the package (and on PyPI). Non-commercial use is free under the Non-Commercial terms; commercial use requires a paid license. Contact: hello@nimbusbci.com.

Contributing & security

Licensees with source access: follow the repository CONTRIBUTING.md and SECURITY.md. Report vulnerabilities privately to hello@nimbusbci.comdo not open a public issue.

Download files

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

Source Distribution

nimbus_bci-0.6.0.tar.gz (1.3 MB view details)

Uploaded Source

Built Distributions

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

nimbus_bci-0.6.0-cp313-cp313-win_amd64.whl (820.8 kB view details)

Uploaded CPython 3.13Windows x86-64

nimbus_bci-0.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (3.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

nimbus_bci-0.6.0-cp313-cp313-macosx_11_0_arm64.whl (897.3 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

nimbus_bci-0.6.0-cp313-cp313-macosx_10_13_x86_64.whl (905.9 kB view details)

Uploaded CPython 3.13macOS 10.13+ x86-64

nimbus_bci-0.6.0-cp312-cp312-win_amd64.whl (824.8 kB view details)

Uploaded CPython 3.12Windows x86-64

nimbus_bci-0.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (3.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

nimbus_bci-0.6.0-cp312-cp312-macosx_11_0_arm64.whl (901.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

nimbus_bci-0.6.0-cp312-cp312-macosx_10_13_x86_64.whl (909.1 kB view details)

Uploaded CPython 3.12macOS 10.13+ x86-64

nimbus_bci-0.6.0-cp311-cp311-win_amd64.whl (845.1 kB view details)

Uploaded CPython 3.11Windows x86-64

nimbus_bci-0.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (3.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

nimbus_bci-0.6.0-cp311-cp311-macosx_11_0_arm64.whl (901.2 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

nimbus_bci-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl (927.6 kB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

File details

Details for the file nimbus_bci-0.6.0.tar.gz.

File metadata

  • Download URL: nimbus_bci-0.6.0.tar.gz
  • Upload date:
  • Size: 1.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for nimbus_bci-0.6.0.tar.gz
Algorithm Hash digest
SHA256 98a6e6dad8d660ef59199f444691f9c8fd08f58f7cb679ae6cc40be7216a278f
MD5 606d944ba199ee332bc8b8ac154399c8
BLAKE2b-256 106768667ce29fb6ed5fa53210af090dd4e2496d0b70235a8c38de877e2be3fe

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: nimbus_bci-0.6.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 820.8 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for nimbus_bci-0.6.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 91700f13d8dc68ff52959c23d4e9b65ac6c0f1349150972d99075d198e9316ba
MD5 33b20788702b94ef37ad0ed740108de2
BLAKE2b-256 9129cd7280d326402741f1bae55c85e9ded8d2196300d38c3267875aacc27e15

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nimbus_bci-0.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 af6c7fed2f8e6d464ce1c7e4686772a0b3e73c6f26d5f9dd88e9b53dde49012f
MD5 b2f2ef5dbc708fd22754befcc63cc876
BLAKE2b-256 3e0b89a86167b227b2ae0cad9dcacb9c7e09762cad6cdc926ed7b130e7823abd

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nimbus_bci-0.6.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 28e8bc7a264832cfc94116e84eb990bf0a4890c37f73fbd2067897a12c89ad86
MD5 268b992f5e038790a06b2572afdbab4a
BLAKE2b-256 265eb0093eaabcf51463fc261a762bc1565f71fb1c13d878bb8794c80326914b

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp313-cp313-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for nimbus_bci-0.6.0-cp313-cp313-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 84a866789e81dd9e7b6c499c5be4837bc5cea8ef812355c5b2ad2b5f8cc5d1e9
MD5 5071c0b6702a5cc89898386e0135a310
BLAKE2b-256 4f43fb98c285dc05699a0381b82506bba29c51f235279fc488bc19d24bedcdc5

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: nimbus_bci-0.6.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 824.8 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for nimbus_bci-0.6.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 13c8af32b3b4d8b854c5b66d86720c4cb33a03ae1ca967df6c3997d1b95fcd73
MD5 ce90566b9f349c020e7a97870cd7fd60
BLAKE2b-256 2f15ae28542520f8c03a8e15195777f0d0c82faebe134d1e55c812959db862c1

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nimbus_bci-0.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 60f4380b43954ebfa336caa5a1af60f89e9d2762c0566af4b53537c3761f334c
MD5 af771c6faac9d0f51e6110e762d8c50a
BLAKE2b-256 8571d44e70622a210e09ec72ff4b6e0b117e16f008bec1e8ae560d8c158976d5

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nimbus_bci-0.6.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d0fa15fdb6a926b6e3e4b45fb35f08a2ca9b370f469d4f04ed7583c56df310d9
MD5 2c3bb91ac7b957efe8b372b1481e4eb1
BLAKE2b-256 0002a6f9090934f4f5b5b8a6b7c8bce44e4ae908fe8485791de2eb6552431aee

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp312-cp312-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for nimbus_bci-0.6.0-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 6b96b4961e782c7124c09feb563c742fe5560bca5f673cfbbb938dba36c911b0
MD5 5e4ba4e8ff35bcf66e0a14d1c5bc1bc5
BLAKE2b-256 df39b9cd2b0955ce76bacf41f633cf88e1a16bfb313c29cbe028cd9ab2c800fe

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: nimbus_bci-0.6.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 845.1 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for nimbus_bci-0.6.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 81ccb434a54225c67dde8a08fac1200abeec33c52f5da37c8598e2b44e92c40c
MD5 fbd7f593312ea9d0c6c3592ad3dbc189
BLAKE2b-256 b01cfd17c940f8aedad71e3a43adde9951c510d56b92b51b83b3757770e869ca

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for nimbus_bci-0.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7b77c4d20d1513d477b784aec82f1603c3171b6d541c9c4d32c7e74a4a84994f
MD5 45c123e43332d81ba4b3d181425e2575
BLAKE2b-256 1ffea5ac7262d1173923823032f59395eb85cf52db395502e47267c4c1c3f78c

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nimbus_bci-0.6.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 272f8f424d06bf5fb15fa2ff94da880411add6d4c60e5f33dc4c7aedfc3aebad
MD5 a9c0636dac5afaa1ae7aae0cdaf6920e
BLAKE2b-256 60c87ce8460c564a67157a192c10caabb3bfc0bafe0039016a7f198ddbedecd1

See more details on using hashes here.

File details

Details for the file nimbus_bci-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for nimbus_bci-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 0192a5f61643fefa1b7580a79c7b7e1033d07a94901f16db9b7acd06f5bf5ee2
MD5 e50a83e7c292f893a58ac505e5c7c167
BLAKE2b-256 26110145939a33505de7fb255857c7d465fd5bbb78269cc828a1bea5359c067f

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.6.0 This release

13 files

0.5.0

13 files

0.4.2

13 files

0.4.1

13 files

0.4.0

9 files

0.3.0

13 files

0.2.8

13 files

0.2.7

13 files

0.2.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page