Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NeuroCode

See inside every step of your EEG & fNIRS analysis.

Running a script gives you a figure at the end and no clue which step caused what. NeuroCode runs your MNE-Python script one step at a time in a real Jupyter kernel, then hands each step — and the real state of your data after it — to an LLM that explains what changed and why that step belongs there. The model writes with the actual result in front of it, not a guess at what the code probably did.

It also writes code from plain language and translates legacy EEGLAB / Homer3 (MATLAB) pipelines into MNE-Python.

A teaching tool for people learning EEG & fNIRS analysis. Bring your own Claude or Gemini key — everything else stays on your machine.

🌐 Project page · MIT licensed · Python 3.9+ · EEG · MEG · fNIRS


Quick start

git clone https://github.com/ruixip/NeuroCode.git
cd NeuroCode
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
neurocode                 # opens http://127.0.0.1:8765

The bundled examples use synthetic data, so they run instantly with nothing to download. Pick one from Load example…, hit Annotate & run, and click through the pipeline.

To turn the written explanations on, copy .env.example to .env and paste in an ANTHROPIC_API_KEY or a GEMINI_API_KEY. It's optional — see About the LLM for what runs without one.

CLI flags
neurocode --host 127.0.0.1   # bind address (default 127.0.0.1)
neurocode --port 8765        # port (default 8765)
neurocode --no-browser       # don't open a browser window
neurocode --clear-cache      # delete cached explanations and exit

What it does

1. Understand code (annotate)

Point it at a script — one you wrote, or one you inherited from a labmate who has since graduated — and find out what it actually does.

  • Runs each step in a real Jupyter kernel, capturing stdout and matplotlib figures.
  • Reports the data's real state after each step by introspecting the live objects (Raw / Epochs / Evoked; EEG, MEG and fNIRS channel types, tagged by modality).
  • Semantic step grouping — an LLM groups statements by what they accomplish and labels each step, using blank-line and comment boundaries as hints. Falls back to structural grouping offline. Cached per script.
  • Level-adaptive explanations: Novice / Intermediate / Expert.
  • Ask follow-up questions on any step (multi-turn, scoped to that step).
  • Click a step to highlight its source lines; a progress bar tracks the run.

2. Generate and edit code (natural language)

  • Write a new MNE script from a prompt, or tweak the current one in place.
  • Diff view highlights exactly what was added and removed.
  • One-click undo.
  • Suggest next steps — research-goal-aware suggestions as clickable chips, for when you don't know what comes next.

3. Translate legacy code (EEGLAB / Homer3 → MNE)

  • Paste or open a .m script. Recognised pop_* / hmrR_* calls are detected by regex and shown as confidence-coloured chips before translation.
  • The translation is grounded in a curated function-mapping knowledge base (neurocode/knowledge/*.json) rather than free improvisation, and flags calls it can't map instead of guessing.
  • An in-app reference viewer (📚 button) browses the EEGLAB↔MNE and Homer3↔MNE tables with confidence badges, caveats and workarounds.

Local file import: 📂 opens a local .py / .m file, read client-side by the browser — no upload. Legacy .m files open pre-filled in the translator.


About the LLM

The explanations, the code generation and the legacy translation are all LLM-driven, but the model is kept on a short leash and you own the key.

Grounded in a real run. Every explanation is generated after the step executes, with the introspected data state in the prompt. Translation is anchored to the mapping tables above.

Bring your own key. NeuroCode auto-detects whichever is present:

Env var Provider Default model
ANTHROPIC_API_KEY Claude claude-haiku-4-5
GEMINI_API_KEY / GOOGLE_API_KEY Google Gemini gemini-2.5-flash

If both are set, Anthropic wins. The active provider is printed to the terminal on startup.

Override the model with NEUROCODE_MODEL — it is applied only when the model name matches the active provider (claude* for Anthropic, gemini* for Gemini), so a stale override left over from the other provider is ignored rather than sent to the wrong API. Note that free Gemini tiers have low per-minute limits, so a multi-step annotate run can rate-limit; the cache fills in the remaining steps across re-runs.

Exactly what leaves your machine. Your source code, plus a short JSON summary of the data's shape — sampling rate, channel count and the first few channel names, channel types, filter band, duration, epoch count. The recordings themselves are never sent. There is no NeuroCode server, no account, and no other network destination.

No key? It still works. Without one, NeuroCode runs every step, plots every figure and reports the real data state — you just get templated text instead of written explanations. The kernel half needs no LLM at all.

Cached, so you don't pay twice. Explanations and step segmentations are cached on disk keyed by (model, level, code, data state), so a re-run — or re-viewing a step — costs no API call and is instant.

  • Location: ~/.neurocode/cache.json (override with NEUROCODE_CACHE)
  • Size: ~1–2 KB per entry, hard-capped at 500 entries LRU (NEUROCODE_CACHE_MAX)
  • Clear it: neurocode --clear-cache

Errors and offline fallback text are never cached.


Architecture

neurocode/
  cli.py         neurocode command → launches the local server + browser
  server.py      FastAPI + /ws WebSocket (annotate / generate / ask / suggest /
                 translate actions) and /api/examples, /api/mapping
  chunker.py     split a script into statements / structural steps (AST-based)
  kernel.py      Jupyter kernel wrapper: run steps, capture stdout + figures
  introspect.py  in-kernel report of EEG/MEG/fNIRS object state as JSON
  llm.py         provider-thin LLM layer: explain_step, generate_code,
                 answer_question, suggest_next_steps, segment_steps,
                 detect_legacy_calls, translate_legacy_code (BYO key)
  cache.py       on-disk LRU cache of explanations + segmentations
  knowledge/     curated EEGLAB↔MNE and Homer3↔MNE mapping tables (JSON)
  static/        vanilla-JS UI: pipeline, AI bar, translate + mapping modals
examples/        synthetic demos: preprocessing, epoching, evoked, TFR, fNIRS
docs/            project page + mapping methodology notes

Three design choices keep it cheap, private and hackable:

  • No hosted compute — everything runs on localhost.
  • Bring your own key — and it runs offline, with templated text, without one.
  • Reuses the scientific Python display stack via a real Jupyter kernel, rather than reimplementing plotting or object introspection.

The LLM layer is deliberately thin — the raw Anthropic and Google SDKs behind a shared streaming helper, not an agent framework — so adding a provider (or a local model) means writing one function.

Bundled examples

Example Covers
preprocessing.py filtering, re-referencing, resampling
epoching.py events → trials
evoked_erp.py averaging + topomap
time_frequency.py Morlet power
fnirs_preprocessing.py optical density, Beer–Lambert, scalp coupling index

All synthetic — no downloads, instant to run.


Scope and roadmap

NeuroCode is a working MVP under active development. Where it stands today:

  • Modalities. EEG and MEG object introspection is solid. fNIRS covers the standard preprocessing chain (OD → SCI → Beer–Lambert → filter); GLM-based HRF estimation and short-channel regression, which need the separate mne-nirs package, are not wired in yet.
  • Time-frequency objects run and plot, but don't yet get a state badge — introspection currently covers Raw / Epochs / Evoked.
  • Translation is v0. It has been exercised on short hand-written EEGLAB / Homer3 snippets rather than full lab pipelines. The mapping tables (12 EEGLAB entries, 10 Homer3/fNIRS entries) are documented starting hypotheses with explicit confidence levels — see docs/eeglab_mne_mapping_methodology.md for how they were built and how to extend them. Domain-expert review is actively wanted here.

Next up: data grounding — reading your real .fif / .edf / .set / .snirf so that explanations and generated code use your actual sampling rate, channels, montage and events.

See CHANGELOG.md for the detailed history.


Feedback and contributing

This is early enough that feedback genuinely changes what gets built next. What's confusing, what's missing, and what would make you reach for it while working with your own data?

Particularly useful: EEGLAB / Homer3 users willing to check the mapping tables, and anyone teaching EEG or fNIRS analysis who can say where the explanations land wrong.

Development setup:

pip install -e ".[dev]"    # adds ruff + pytest

License

MIT — see LICENSE.

Built on MNE-Python.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages