KIT general pipeline: environment setup and running
Author: Hadi Zaatiti <hadi.zaatiti@nyu.edu>
This page is the entry point for the NeuroWaves KIT general pipeline, the
YAML-driven set of numbered scripts under
pipeline/mne_pipelines/kit_general_pipelines/. It explains how to create the
Python environment, how to run each stage, and where the outputs land. The
following pages describe individual stages in more detail.
Preparing the BIDS dataset and its YAML config is described in
Starting a project with the general MNE-KIT pipeline. The KidLang study is the worked
example used throughout (pipeline_config_files/kidlang_config.yml).
Important
Everything in this section is derived from the scripts currently in the
repository. If a command here disagrees with --help of a script, trust
the script and open an issue.
What the pipeline does
Each numbered script is one stage. Stages 1 to 6 operate on the MEG recordings, stage 7 reconstructs the anatomy with FreeSurfer and builds the scalp surface, stage 7-a puts every reconstruction in front of a reviewer, and stage 8 performs the manual MEG-MRI coregistration.
# |
Script |
Reads |
Writes (under |
|---|---|---|---|
1 |
|
raw |
|
2 |
|
|
|
2-a |
|
stage-2 |
|
3-a |
|
stage-2 |
|
3-b |
|
stage-2 |
|
4 |
|
stage-2 |
|
5 |
|
raw |
|
6 |
|
stage-4 |
|
7 |
|
|
|
7-a |
|
stage-7 reconstructions |
MNE scalp surfaces |
8 |
|
stage-2 |
manual GUI; |
Run stages 1 to 6 in order against the same YAML. For the anatomy run 7, then
7-a, then 8: coregistration needs the reconstruction and its scalp surface, and
stage 8 uses an individual MRI only after a pass or pass_with_note
verdict in 7-a. Stage 8 falls back to the fsaverage template for subjects
without a T1w image (or with a use_fsaverage verdict). After every successful stage the pipeline
re-renders an incremental Quarto report under
<bids_root>/derivatives/pipeline_report/_output/report.html.
Prerequisites
Git and access to the private repository (neurowaves-lab-documentation). Email
nyuad.meg@nyu.eduto request access.Conda. If you do not have one, install Miniforge (conda-forge first, all platforms). Check with
conda --version.A desktop session with working OpenGL for the manual GUIs (stage 2 manual mode, stages 7-a and 8) and the 3-D plots of stage 2-a.
Disk space: several GB for the environment plus space for the datasets, their
derivatives/and FreeSurfer outputs.
Create the neurowaves environment
The dependency recipe is
pipeline/mne_pipelines/kit_general_pipelines/environment.yml. It is the
only environment file you need for the pipeline. (The environment.yml at
the repository root is the Windows export used to build this documentation
site and does not contain the MEG stack.)
From the repository root:
conda env create -f pipeline/mne_pipelines/kit_general_pipelines/environment.yml
conda activate neurowaves
The recipe installs, from conda-forge only:
Layer |
Packages |
|---|---|
Interpreter |
Python 3.11 or 3.12 (KIT GUI 2.x needs 3.11+) |
MEG / BIDS |
|
Numerics |
|
GUIs and plots |
|
Config and tables |
|
Reports |
Quarto CLI (bundles Pandoc), |
The environment also sets QT_API=pyside6 on activation so MNE and the KIT
GUI pick the installed Qt binding.
To update an existing environment after the recipe changed:
conda env update -f pipeline/mne_pipelines/kit_general_pipelines/environment.yml --prune
--prune removes packages that are no longer in the recipe, so keep this
environment dedicated to the pipeline. Before updating an environment that was
used for a published analysis, record it with
conda env export -n neurowaves > neurowaves-resolved.yml.
Verify the installation
With neurowaves activated, from the repository root:
# (1) Python dependencies import
python -c "import mne, mne_bids, mne_kit_gui, nibabel, pandas, pyvista, pyvistaqt, qtpy, yaml, joblib, tabulate, IPython, ipykernel, nbclient, nbformat; print('Python deps OK'); mne.sys_info()"
# (2) Quarto is on PATH (1.4 or newer)
quarto --version
# (3) Report toolchain self-check (kernel, LaTeX)
quarto check
Optional: PDF reports
HTML reports work out of the box. PDF rendering needs a LaTeX distribution. Let Quarto install a small one, once per machine:
quarto install tinytex
Optional: FreeSurfer for stage 7
FreeSurfer is not installed by Conda. Install it on the Linux host that will run
recon-all (Linux workstation, HPC node, or WSL Ubuntu-22.04 on Windows),
following FreeSurfer on WSL,
and provide its license (FS_LICENSE or freesurfer.license_file in the
YAML).
On Windows, 7-freesurfer_reconstruction.py is launched with the
Windows neurowaves interpreter and forwards the work into WSL, where
python3 and PyYAML must exist:
# inside the WSL distribution
sudo apt update && sudo apt install python3 python3-yaml
python3 -c "import sys, yaml; print(sys.version)"
Set FREESURFER_WSL_DISTRO before starting VS Code if FreeSurfer lives in a
distribution other than Ubuntu-22.04. The distribution’s files are
reachable from the Windows explorer at \\wsl$\<distribution>.
Stage 7 runs recon-all for every selected subject, plans jobs and threads
from the available CPUs and RAM, resumes incomplete subjects, creates the
scalp surface with mkheadsurf and records an audit CSV. freeview (part of
FreeSurfer) can be opened from the stage 7-a review window through WSLg.
IDE setup
In VS Code select the neurowaves interpreter with Python: Select
Interpreter. The repository ships .vscode/launch.json entries for every
stage (including the KidLang-specific ones) and .vscode/tasks.json tasks
that refresh the Quarto report. All launch entries set
PYTHONPATH=${workspaceFolder} so the pipeline package is importable.
Run the stages
Every stage takes the dataset’s YAML config with -c / --config (see
Starting a project with the general MNE-KIT pipeline for creating it).
Run the scripts as modules from the repository root so that the local
pipeline package is importable (no pip install of the repository is
required):
conda activate neurowaves
MODULE=pipeline.mne_pipelines.kit_general_pipelines
CONFIG=pipeline/mne_pipelines/kit_general_pipelines/pipeline_config_files/kidlang_config.yml
python -m $MODULE.1-kit_count_sanity_check_single_channel -c $CONFIG
python -m $MODULE.2-kit_con_to_fif -c $CONFIG
python -m $MODULE.2-a-kit_fif_plot_headshape_sensor_alignment -c $CONFIG
python -m $MODULE.3-a-kit_detect_bad_channels -c $CONFIG
python -m $MODULE.3-b-kit_ica -c $CONFIG
python -m $MODULE.4-kit_apply_filters -c $CONFIG
python -m $MODULE.5-a-kit_compute_events_STI014 -c $CONFIG
python -m $MODULE.6-kit_evoked_response_single_channel -c $CONFIG
# Anatomy (Linux/WSL/HPC), reconstruction QC, manual MEG-MRI coregistration
python -m $MODULE.7-freesurfer_reconstruction -c $CONFIG
python -m $MODULE.7-a-freesurfer_qc -c $CONFIG
python -m $MODULE.8-kit_mri_coreg -c $CONFIG
The variable assignments are Bash syntax; in PowerShell spell out the module
and config paths. Running a script by file path also works when
PYTHONPATH contains the repository root (this is what the VS Code launch
entries do).
Common options:
--overwrite(stages 2, 4, 5, 6): rebuild outputs that already exist. Without it, existing outputs are skipped and reported as such.--desc <label>(stage 5 variants): overrideevents.desc.--show(stage 2-a): open the interactive 3-D alignment plots instead of only saving PNGs.--no-gui,--review-all,--reset-review,--overwrite,--no-plots,--save-cleaned(stage 3-b): fit and propose without reviewing, redo or discard reviews, refit, skip figures, also write the cleaned recording. Details on the ICA page.--no-gui(stage 3-a): compute the automatic candidates only and label nothing (review_status: pending); the default run opens the inspection and confirmation browsers for every recording not yet reviewed.--review-allredoes the review of reviewed recordings,--reset-reviewdiscards the saved reviews,--no-plotsskips the audit figures. Rerunning stage 3-a with unchanged input and detection settings reuses the saved metrics. Details on the bad channel page.--dry-run,--force,--jobs,--threads(stage 7).--no-gui,--review-all,--reset-review,--overwrite,--no-plots(stage 7-a): as in stage 3-a;--no-guicomputes metrics, flags and figures and leaves the verdictspending.--redo,--qa-only,--no-plots(stage 8): reopen the GUI for verified transforms, or only recompute the distance QA.
Each Python stage writes a timestamped copy of the YAML it used into
<stage>/configs/config_<timestamp>.yml (the report reads the newest one
to show the parameters of the run; copies that older runs left in the stage
root are moved into configs/ on the next run).
The KidLang configuration
kidlang_config.yml differs from the template in a few deliberate ways:
kit2fiff.slope: "+"(triggers are 0 to 5 V peaks) andkit2fiff.coreg.mode: manual: stage 2 opens the KIT-to-FIFF GUI once per recording so the head-shape alignment can be checked by eye.Events come from the STI 014 channel, so the stage-5 variant is
5-a-kit_compute_events_STI014.pywithevents.desc: sti014,events.source: sti014andevents.find_eventskwargs (stim_channel: "STI 014",shortest_event: 1,min_duration: 0.002).freesurfer.auto_cw256: trueretries subjects whose field of view exceeds 256 with-cw256(stage 7-a checks the crop);missing_anat: fsaveragelets stage 8 use the template for subjects without a T1w.reports.formats: ["html"]so no LaTeX is needed.There is no
filtersorepochingblock, so stages 4 and 6 use their built-in defaults (notch at 50 Hz harmonics, band-pass 1 to 40 Hz, epochs from -0.2 s to 0.8 s with a baseline of -0.2 to 0 s). Add those blocks to the config to change them.
Where the outputs land
The scripts write only under <bids_root>/derivatives/; the source tree is
never modified.
<bids_root>/derivatives/
1-kit_count_sanity_check_single_channel/
sanity_check_overview.csv
sub-*/sub-*_..._desc-sanitycheck_log.txt
2-kit_con_to_fif/ # or 2-kit_con_to_fif_manual/
kit2fiff_summary.csv
sub-*/[ses-*/]
sub-*_..._desc-rawkit_raw.fif
sub-*_..._desc-coreg.png # automatic mode
*_edited.txt # digitizer points without the last 3 columns
kit2fiff_log.txt
2-a-kit_fif_plot_headshape_sensor_alignment/
alignment_summary.csv
sub-*/...png (+ .json)
3-a-kit_detect_bad_channels/
bad_channels_summary.csv
sub-*/sub-*_..._desc-badchannels.json # final bad-channel list + settings
sub-*/sub-*_..._desc-badchannels_metrics.tsv # one row per channel
sub-*/figures/*.png # PSD, metrics, sensor map, traces
3-b-kit_ica/
ica_summary.csv
sub-*/sub-*_..._desc-ica_ica.fif # ICA solution incl. reviewed exclusions
sub-*/sub-*_..._desc-ica.json # proposals, review, settings
sub-*/sub-*_..._desc-ica_scores.tsv # one row per component
sub-*/figures/*.png # components, scores, properties, overlays
4-kit_apply_filters/
filter_summary.csv # bad_channels, ica_excluded columns
sub-*/sub-*_..._desc-filtered_raw.fif (+ .json provenance; info['bads'] from 3-a, ICA from 3-b applied)
5-a-kit_compute_events_STI014/ # or 5-kit_compute_events_<mode>/
events_summary.csv # auto_events_index.csv for the analog variants
sub-*/sub-*_..._desc-sti014_events.eve
sub-*/sub-*_..._desc-sti014_events_detail.tsv
6-kit_evoked_response_single_channel/
epochs_evoked_summary.csv
sub-*/sub-*_..._desc-epo_raw_ev<code>_epo.fif # one epochs file per event code
sub-*/sub-*_..._desc-evk_raw_ave.fif # all evoked responses of the recording
7-freesurfer_reconstruction/
subjects/sub-*/ # SUBJECTS_DIR (surf/lh.seghead, bem/*-head-*.fif)
freesurfer_summary.csv
runs/<run-id>/{freesurfer_summary.csv, run_metadata.txt, config.yml, logs/}
7-a-freesurfer_qc/
freesurfer_qc_summary.csv
freesurfer_qc_metrics.tsv
sub-*/sub-*_desc-reconqc.json # metrics, flags, verdict
sub-*/figures/*.png
8-kit_mri_coreg/
coreg_summary.csv
sub-*/sub-*-trans.fif # saved from the GUI
sub-*/sub-*-trans.json # provenance and QA distances
subjects/fsaverage/ # template copy when needed
pipeline_report/
_output/report.html [report.pdf] # + source/report.qmd, _quarto.yml
logs/render_log_<timestamp>.txt # newest 30 kept
state/render.lock, report_refresh.json
staging/ # transient, empty between renders
Report
The report (report_generation/report.qmd) is rendered with Quarto after
each stage when reports.enabled: true. Quarto is found on PATH, through
reports.quarto_path, or via conda run -n <reports.quarto_env>. To
re-render without re-running any processing (for example after pulling a new
report template, or on a workstation after stage 7 ran on a compute node):
python -m pipeline.mne_pipelines.kit_general_pipelines.report_generation.refresh --config $CONFIG
# keep watching the inputs and refresh on change
python -m pipeline.mne_pipelines.kit_general_pipelines.report_generation.refresh --watch
Only one render runs per report at a time. A stage that finds another render
in progress (for example the VS Code task Watch Quarto reports, which
starts with the workspace) waits at most reports.lock_wait_s seconds
(default 30), then continues without waiting: the running render re-checks
the inputs when it finishes and renders again if the stage added outputs. A
render that runs longer than reports.render_timeout_s seconds (default
600) is killed, the previous report is kept, and the next stage or the
watcher renders again. A stage whose outputs were already rendered by the
watcher reports report already up to date and skips.
Troubleshooting
Symptom |
Cause |
Fix |
|---|---|---|
|
Script launched without the repository on the import path |
Run with |
|
Dataset parent folder unknown |
Export |
|
Backslash in a double-quoted Windows path |
Use forward slashes or single quotes |
Quarto cannot be found |
Not on PATH and not in the configured Conda env |
|
|
No LaTeX |
|
GUI cannot initialise Qt / OpenGL |
No desktop session or wrong interpreter |
Select the |
Stage 7 cannot import |
PyYAML installed on Windows only |
|
Stage 4 reports |
Input, settings or output changed since the FIF was filtered |
Rerun stage 4 with |
Report shows old data |
Not refreshed after the inputs changed |
Run the |
|
The watcher task or another stage holds the render lock |
Nothing to do; that render includes this stage’s outputs |
|
Quarto or its Jupyter kernel hung, often on a slow or syncing drive |
Check the latest |
If a render fails, the Quarto stderr is in
<bids_root>/derivatives/pipeline_report/logs/render_log_<timestamp>.txt. The
stages continue after a failed render unless reports.fail_on_error: true.
Further reading in the repository
pipeline/mne_pipelines/kit_general_pipelines/README.md: stage-by-stage behaviour, manual coregistration details, FreeSurfer resource planning.pipeline/mne_pipelines/kit_general_pipelines/SETUP.md: the installation walkthrough this page summarises.pipeline/mne_pipelines/kit_general_pipelines/report_generation/README.md: how the Quarto report is built and refreshed.