Skip to main content

nxr-convert

Converts a Brainstorm protocol (MEG/EEG recordings, cortical surfaces, MRI volumes, head models, inverse kernels, source maps, fibres and connectomes) into an nxr datastore: a folder that the Cortical Flow desktop app opens.

Version 0.2.3, which writes database schema 49. Each dataset's dataset.sqlite carries the schema number as PRAGMA user_version. The app opens only databases with the version it was built for, and the converter opens only its own version and refuses any other. Use a converter release that matches your desktop app (0.2.x for Cortical Flow 0.2).

What it writes

<datastore>/
  <dataset>/
    dataset.sqlite          the dataset's database: one row per subject, surface, recording, kernel, …
    <subject>.nxr.zarr/     one Zarr v3 store per subject; the bytes (positions, faces, timeseries, kernels …)

The rows are written first, and every zarr.json is then rewritten from the rows, so the store describes itself. A Brainstorm condition becomes a session of the subject. The protocol's default anatomy (@default_subject) becomes the dataset's template subject, and Group_analysis becomes its group subject.

Install

Python 3.12 or newer. With uv:

uv tool install nxr-convert

or with pipx:

pipx install nxr-convert

Check the install:

nxr-convert --version        # nxr-convert 0.2.3 (database schema 49)

The atlas commands also need the atlas extra (nibabel), plus Node.js and the nxr-compute Node binding (NXR_COMPUTE). Install the extra with uv tool install "nxr-convert[atlas]". The conversion commands below need neither.

Use with the Cortical Flow desktop app

The desktop app's Import runs this converter. It looks for one in this order:

  1. NXR_CONVERT_CMD, an explicit command (for example uv run --project /path/to/nxr-convert nxr-convert);
  2. a development checkout of the app's monorepo, run through uv;
  3. nxr-convert on PATH;
  4. ~/.local/bin/nxr-convert (nxr-convert.exe on Windows), where uv tool install and pipx install put it — found even when the app was started from the Dock or Finder and did not inherit your shell's PATH.

If none is found, the Import page shows a setup card. For an install elsewhere, set NXR_CONVERT_CMD to its full path.

Commands

Every command prints its progress as JSON lines on stdout, one object per event keyed by stage. The app parses this output. A failure ends with a {"stage": "error", "message": …} line and exit status 1.

Datasets

nxr-convert dataset create <datastore> <name> [--source-tool brainstorm] [--source-protocol P] [--source-path S]
nxr-convert dataset delete <datastore> <name>
nxr-convert dataset recover <datastore>/<name>    # roll back unfinished writes, finish deletions, rewrite the store

dataset create makes <datastore>/<name>/dataset.sqlite from the schema. It also creates the datastore folder if it does not exist yet.

Reading a protocol

nxr-convert list <protocol>                       # its subjects and conditions, as JSON
nxr-convert scan <protocol> [--prefer protocol.mat|walk] [--out view.json] [--summary]

Converting

# one whole subject as one composition: every session, MRI volumes, source maps, fibres, connectomes
nxr-convert subject <protocol> --subject <name> --dataset <datastore>/<dataset>

# one condition as a session of a subject (the subject is created if it is absent)
nxr-convert convert <protocol> --subject <name> --condition <condition> --dataset <datastore>/<dataset> \
    [--surface tess_*.mat] [--extra-surface tess_*.mat …] [--recording data_*.mat] [--channel-file F] \
    [--no-gain] [--all-surfaces] [--include-imported] [--no-raw]

# the protocol's default anatomy as the TEMPLATE subject, and its group results as the GROUP subject
nxr-convert template <protocol> --dataset <datastore>/<dataset> [--surface tess_*.mat …]
nxr-convert group    <protocol> --dataset <datastore>/<dataset>

<protocol> is the Brainstorm protocol folder, the one that holds anat/ and data/.

Adding to or removing from a subject

nxr-convert surface --dataset D --subject S --file tess_*.mat [tess_*.mat …] [--bst-root <protocol>]
nxr-convert mri     --dataset D --subject S --anat <protocol>/anat/<subject> [--only NAME …]
nxr-convert inverse --dataset D --subject S --file results_*KERNEL*.mat --session C --bst-root <protocol> \
    [--channels-id ID] [--surface-id ID] [--forward-id ID] [--name N] [--channel-file F]
nxr-convert remove  --dataset D --subject S [--node <store path>]   # the subject, or one node of it

The atlas (optional)

nxr-convert atlas default-subject <datastore>/<dataset> --templates <FreeSurfer subjects dir> […]
nxr-convert atlas build  <datastore>/<dataset> --subject S [--replace] [--kernels …] […]
nxr-convert atlas reduce <datastore>/<dataset> [--from <datastore>/<other dataset> …] [--kernels …]   # members of other datasets too
nxr-convert atlas info   <datastore>/<dataset>

--kernels chooses the inverse kernels, in build and in reduce: comma tokens, tokens of one kind OR and kinds AND — all · constrained | free · latest (per recording, method and orientation, the newest Brainstorm stamp) · a kernel's method (MN_MEG), stamp (261005_2149), name, or a glob over its name. dSPM-unscaled_MEG,constrained,latest is one kernel a recording. The group atlas sums one kernel per member recording, method and orientation: a member left with two (two inverse solutions of one method) is refused, never pooled. Stamps are per subject (when Brainstorm made the kernel), so across subjects choose by latest or a glob, not by one stamp.

Run nxr-convert <command> --help for every flag.

One writer per dataset

Each command that writes a dataset first takes its writer lock, <datastore>/<dataset>/.writer.lock. The lock is a small JSON file (pid, host, program, started_utc) created atomically. If another live process holds the lock (the desktop app, or a second conversion), the command is refused, and the error names the holder. A lock left by a process that has died on the same machine is taken over. A lock held by another host is never broken; remove it by hand if that host is gone. When the desktop app runs the converter during its own import, it already holds the lock and passes it on through NXR_WRITER_LOCK_HELD. The lock is advisory, so do not edit a dataset by other means while a conversion runs.

Development

uv sync
uv run pytest -q

Tests that need a real Brainstorm protocol skip unless NXR_TEST_PROTOCOL points at one (Brainstorm's TutorialAuditory).

This repository is a published snapshot. The converter is developed inside the Cortical Flow monorepo, and its database schema (src/nxr_convert/model.sql) is a copy of the app's schema.

License

MIT. See LICENSE.

Metadata

Release files for nxr-convert 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nxr-convert 0.2.3
File Size Uploaded
nxr_convert-0.2.3.tar.gz 183.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nxr-convert 0.2.3
File Interpreter ABI Platform
nxr_convert-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 395.7 kB

Release files / nxr_convert-0.2.3.tar.gz

Download URL nxr_convert-0.2.3.tar.gz
Size 183.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c68507c5ead00f4cf4f176cc6709365d252de05088fe7b509cff8039b64288ea
BLAKE2b-256 checksum
How to use checksums
dc9868caf970c2ff30424e004512e252cba28ae69fc4dfd770598e36bf119c20
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / nxr_convert-0.2.3-py3-none-any.whl

Download URL nxr_convert-0.2.3-py3-none-any.whl
Size 212.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
94d4865fe9f9521267e44081f4a977a59e52fa290c7e74470a57acda1c8cc663
BLAKE2b-256 checksum
How to use checksums
3b79b75fce58b1b537e0faf0012fc613378a112fe9f6be9d2855be90fe21049a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.2.3 This release

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

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