The Operating System for
BCI Research
Built with the open research and AI stack.
Design BCI paradigms
by connecting blocks.
Sequence tasks, loops, and triggers on a visual canvas, no scripting.
Pictures, sound and words
on the recording’s clock.
Trial 3 never bound. It leaves media, X and Y together, from one index vector — never three lookups that agree until something drops.
- 1designed ← your paradigmcompile emits it — no dialog
- 2declared ← events.tsv / csv / xlsxBIDS maps with zero clicks
- 3derived ← a marker channelhistogram shown before the mapping
- 4streamed ← one file + one anchordrift measured, or "unmeasured"
Encoding Model (TRF)
Both directions, one block. Scored against a circular-shift null — a permutation destroys an envelope’s autocorrelation, and then everything looks significant.
From raw signal to activation map.
Preprocess with MNE, add your own custom filters in Python, and generate 2D activation maps and 3D cortical renders, all from the same pipeline.
Preprocessing with MNE
Standard filtering and preprocessing pipelines on MNE foundations.
Custom filters in Python
Drop in your own filters and transforms with plain Python.
2D & 3D activation maps
Generate topographic maps and 3D cortical renders from the results.
Whole-brain activation map
Reconstructed activity projected onto a 3D cortical mesh for spatial localization of the response, built on the same MNE-derived source estimates as the 2D views.


Time-resolved scalp maps
Channel-wise concentration changes plotted across the epoch, from baseline to peak response.

Per-channel waveform overlay
All channels overlaid against a synchronized topographic snapshot at the selected timepoint.
Every analysis step, one workspace.
Preview any step on one file, then batch-apply across the whole dataset, every output drops straight into ML Flow.

- 1Apply to one file
- 2Check the result
- 3Batch-apply to all
- 4Import into ML Flow
Build model pipelines
block by block.
Drag, connect, and run from raw signal to a scored model.
Get unstuck
while you work.
AI that understands your project.
From logistic regression to EEG transformers.
The desktop Components Library, mirrored. Every ecosystem, model family and pipeline stage on one palette — drag it onto the ML Flow canvas, or rewire it by hand.
Classical ML
Fast, interpretable baselines. Every serious BCI result starts by beating these.
scikit-learn
Pipelines, CV, the classics
XGBoost
Gradient-boosted trees
Drops into ML Linear, ML Ensemble, ML Neighbors & ML Clustering blocks
Preprocessing
109StandardScaler · RobustScaler · SimpleImputer · KNNImputer
Signal Processing
621MNE Epochs · ICA · wavelets · band-pass filters
Feature Selection
35SelectKBest · RFE · RFECV · SelectFromModel
Dimensionality Reduction
94PCA · FastICA · KernelPCA · NMF
Optimization
41Adam · AdamW · SGD · RMSprop · Muon · LBFGS
Cross Validation
54KFold · StratifiedKFold · GridSearchCV · TimeSeriesSplit
Evaluation
89accuracy · F1 · ROC-AUC · confusion matrix
Model Interpretation
123SHAP · DeepExplainer · TreeExplainer · KernelExplainer
Computer Vision
421OpenCV · torchvision · feature detectors
Data Manipulation
356reshape · concat · merge · groupby · window
Math Operations
381linear algebra · statistics · FFT · elementwise
BCI Augmentation
26MixUp · time shift · channel dropout · SMOTE
Classical & probabilistic
- Linear & logistic models
- SVM & kernel methods
- Random forest · bagging · boosting
- HMM · probabilistic · Bayesian
Convolutional & recurrent
- CNN · ResNet · Inception · EfficientNet
- EEGNet · ShallowConvNet · DeepConvNet
- LSTM · GRU · BiLSTM
- Autoencoders · VAE
Attention & transformers
- Transformers & attention models
- EEGConformer · Conformer
- BrainBERT · EEGTransformer
- PatchTST · ViTEEG
Sequence & state-space
- TCN · temporal ConvNets
- Mamba SSM
- MiniGPT · TinyGPT · LargeGPT
- BioGPTBCI · LaBraMBCI · GPT2BCI
Riemannian & spatial
- CSP · SPoC · Xdawn · SSD
- Covariances · ERPCovariances
- Tangent space projection
- MDM · FgMDM · TSClassifier
Edge & compressed
- MobileEEGNet · TinyEEGNet
- QuantizedEEGNet · INT8
- ONNX export
- Quantization-aware training
Choosing the model is the easy part.
119 blocks we write and maintain ourselves — the distance between a model and a result you can defend.
Indexed
11,337
third-party catalog
Owned
119
written by us
“It worked on subject 1”
Domain Adaptation
A decoder rarely survives a new head, or a new day.
“Session 6 broke session 1”
Domain Incremental Learning
Training on new data quietly erases what the model already knew.
“94% accurate, on what?”
Uncertainty & Evaluation
An accuracy number cannot say when the decoder should decline to answer.
- 1Name constant
- 2Schema & ports
- 3Executor branch
- 4Palette row
- 5A test that runs it
A contract test probes the running server — the real executor, the real palette — so a block that is declared but cannot be placed or cannot run fails the build. Every one of the 119 is reachable today, and 118 of them are free on every plan. Block reference
Not on the palette? Install it.
Any Python package becomes typed blocks on the ML Flow canvas — sandboxed in its own process, introspected automatically, no code.
01Install
A name from the shelf, or any pip spec.
02Isolate
Own env, own process, own server.
03Introspect
Functions become typed blocks. No code.
in
path: str
out
rec: Recording
cedalion.io.read_snirf
fNIRS
Cedalion
EEG / MEG
Autoreject · PyPREP
BCI decoding
Braindecode · MOABB
Biosignals
NeuroKit2 · YASA
Dimensionality reduction
UMAP · openTSNE
Acquisition
BrainFlow · pylsl
Neuroimaging
NiBabel · Nilearn
Every experiment is a versioned workspace.
Create, save, duplicate, and compare experiments inside a project, each with its own version, run history, and lineage.
“Highest mean” is not a finding.
Pick a metric and an axis. A second tab on the Results page runs the test the design calls for, checks its assumptions, and writes the result up for a methods section.
Results tab · what you see
5.5 points over 12 subjects.
Real effect, or twelve people?
Results Validation tab · what it answers
worked exampleVerdict
Different
Effect
Large
Design
Paired
F(2, 22.0) = 168.74, p < .001, partial η² = 0.939 RM-ANOVA · 12 subjects · α = 0.05 Friedman cross-check: p < .001 (agrees)
Every subject moves the same way — which the table on the left cannot show.
Compare along any axis
Or any combination of two.
- SessionIs performance stable across days?
- ExperimentDid v2 actually improve on v1?
- PipelineWhich model really wins?
- WorkflowDoes the preprocessing route matter?
- SubjectHow much does it vary between people?
- RunIs run-to-run noise bigger than the effect?
The test follows the design
Recommended by default; every valid alternative stays selectable.
| Design | Parametric | Rank-based |
|---|---|---|
| Independent · 3+ levels | One-way ANOVA · Welch’s ANOVA | Kruskal-Wallis H |
| Independent · 2 levels | Welch’s t · Student’s t | Mann-Whitney U |
| Paired · 3+ levels | Repeated-measures ANOVA | Friedman test |
| Paired · 2 levels | Paired t-test | Wilcoxon signed-rank |
Both columns run — the rank-based one as a labelled cross-check.
On every result
Not switches to remember.
Assumptions checked
Reported, not assumed.
Shapiro-Wilk · Levene
Effect size, always
With a bootstrap interval.
Hedges’ g · η² · W
Family corrected
Raw and corrected p, side by side.
Tukey · BH · Holm
Two-factor models
Interaction says if the winner holds.
A × B
The analysis we did not build.
No tool draws every chart a reviewer asks for. Take every table out as CSV or Excel, or write the analysis in the app with the results already loaded.
per_subject = (results[results.metric == "accuracy"]
.groupby(["pipeline", "subject"])["value"].mean())
summary = per_subject.groupby("pipeline").agg(["mean", "std"])
fig, ax = plt.subplots()
ax.bar(summary.index, summary["mean"], yerr=summary["std"], capsize=5)Right-click: PNG at 300 or 600 dpi, SVG, PDF, copy, zoom — the same menu as every other chart in the app.
Already loaded in every cell
Data opens a reference onto your own study: every name, every column, and a real value out of it. validation is the same module the Results Validation tab runs on.
Nine tables, one join key
Every row carries experiment_id, so the tables rejoin anywhere.
- observationsone row per every stored score
- parametersone row per every configuration value
- runsone row per training run
- experimentsone row per experiment
- metricsone row per experiment × metric
- modelsone row per trained model
- reproducibilityone row per hashes, seeds, versions
- versionsone row per version-history entry
- studyone row per the study itself
Written as
The starter notebook already runs: it loads the CSVs, plots them, and runs a paired test across your subjects.
.ipynb stays free.Export & notebook docs 98.8% of what, and how sure are you?
A number with no interval, no sample size and no baseline can be believed, but not evaluated. Every reported number arrives with what it rests on.
A point estimate
98.8%
Selected over every run, quoted alone. Nothing says how many observations it rests on, or what guessing would have scored.
A result
84.2% (95% CI 79.1–89.3%, n = 20 scores, chance 50.0%)
- The mean, not the best runacross every participant measured
- An interval that names its nand what the n counts
- The baselinechance, and the majority class when they differ
Two intervals, never mixed: a t interval on the scores a study measured, a Wilson interval on the trials a classifier was tested on. A single score gets no interval rather than a fabricated width, and a per-class table shows whether one class is failing.
- ProblemA linked value no longer resolvesResults ▸ paragraph 2
- ProblemSection “Discussion” is emptypage 9
- Check“CSP+LDA” reports Accuracy with no confidence intervalthe record holds 1 score
- CheckA reference is never citedVidaurre 2011
- CheckThe document carries no confidentiality markingLayout ▸ Marking
- NoteSign-off is incompletenot yet signed: Approver
It blocks nothing and edits nothing — the other button is always Export anyway. A clean document shows no dialog at all.
Freeze the document with the results digest it was written against. Never refreshed, never edited.
Author, reviewer and approver, each with a name and a date, frozen into every release.
Draft, Internal, Confidential, Released — in the running head, as a page watermark, and in the exported file’s name.
The report syncs with a shared study, records who typed in it, and asks before a save replaces a teammate’s newer one.
Train locally,
share when the work is ready.
Analysis stays on your machine. Publish and reuse through BCINexus only when collaboration matters.
Sync when needed
Cloud storage and sharing when local-only isn’t enough.
Coordinate your team
Assign tasks by module and track them to done.
…
Contributors
9+
Paradigm types
…
Published studies
8+
AI architectures
7
Signal modalities
16+
Signal measures
Get BCILattice free
and run your first experiment
Start free with local data import, preprocessing, visual workflows, model training, reports, and optional publishing.