diff --git a/README.md b/README.md
index 1dd2559e..190cd879 100644
--- a/README.md
+++ b/README.md
@@ -8,36 +8,27 @@
> [!WARNING]
> This software is under active development and not yet intended for production use. APIs, outputs, and behavior may change without notice. Use at your own risk.
-Reference implementation of the [Reproducible Brain Charts (RBC)](https://doi.org/10.1016/j.neuron.2024.08.026) preprocessing protocol for structural and functional MRI. Built on [NiWrap](https://github.com/styx-api/niwrap).
+Reference implementation of the [Reproducible Brain Charts (RBC)](https://reprobrainchart.github.io/) preprocessing protocol for structural and functional MRI, built on [NiWrap](https://github.com/styx-api/niwrap). Handles brain extraction, tissue segmentation, registration, motion correction, nuisance regression, and resting-state metrics, with optional longitudinal (multi-session) support. See [Shafiei et al. (2025)](https://doi.org/10.1016/j.neuron.2024.08.026) for the full protocol description.
-## Installation
-
-```bash
-pip install git+https://github.com/childmindresearch/rbc.git
-```
-
-Requires Python 3.12+. Neuroimaging tools (AFNI, FSL, ANTs) are needed at runtime. Pass `--runner docker` to pull and run them automatically via containers. See the [NiWrap docs](https://github.com/styx-api/niwrap) for runner configuration.
-
## Quick start
-```bash
-# Usage: rbc {workflow} INPUT_DIR [INPUT_DIR ...] -o OUTPUT_DIR [options]
+Input must be a [BIDS-organized](https://bids-specification.readthedocs.io/) dataset. Neuroimaging tools (AFNI, FSL, ANTs, FreeSurfer) run automatically via Docker by default.
-# Run the full pipeline
-rbc all /data -o /data/derivatives --runner docker
+```bash
+pip install git+https://github.com/childmindresearch/rbc.git
-# Or run a single stage for specific subjects
-rbc functional /data -o /data/derivatives --task rest --participant-label 01 02 --runner docker
+# Run the full cross-sectional pipeline
+rbc all /data -o /data/derivatives
-# Multiple input directories (e.g., raw BIDS + prior derivatives)
-rbc functional /data /data/derivatives -o /data/derivatives --runner docker
+# Run a single stage for specific subjects
+rbc functional /data -o /data/derivatives --task rest --participant-label 01 02
```
-Run any command with `--help` for full options.
+Run any command with `--help` for full options (e.g., `rbc functional --help`). Requires Python 3.12+. Pass `--runner docker` explicitly if auto-detection doesn't find your container runtime, or see the [NiWrap docs](https://github.com/styx-api/niwrap) for other runners (Podman, Singularity, local installs).
## Workflows
@@ -48,75 +39,46 @@ Run any command with `--help` for full options.
| `rbc metrics` | ALFF/fALFF, ReHo, smoothing, z-scoring, atlas-based timeseries and correlation matrices |
| `rbc qc` | XCP-D format quality metrics, framewise displacement, DVARS, RBC pass/fail thresholds |
| `rbc all` | Runs all four stages in sequence, passing results in memory between stages |
-| `rbc longitudinal …` | Multi-session workflows: `template`, `anatomical`, `functional`, `metrics`, `qc`, `all` |
-Workflows must be run in order: `anatomical` → `functional` → `metrics` / `qc`. The `all` command handles this automatically.
+Stages must be run in order: `anatomical` -> `functional` -> `metrics` / `qc`. The `all` command handles this automatically.
-Longitudinal workflows consume cross-sectional derivatives. Typical flow:
+Multiple input directories are supported when raw data and derivatives live in separate trees:
```bash
-rbc all /data -o /data/derivatives --runner docker
-rbc longitudinal template /data/derivatives -o /data/derivatives --runner docker
-rbc longitudinal anatomical /data/derivatives -o /data/derivatives --runner docker
+rbc functional /data /pipelines/rbc -o /pipelines/rbc
```
-`rbc long` is an alias for `rbc longitudinal`. The `metrics`, `qc`, and `all`
-longitudinal stages are registered but raise `NotImplementedError` until
-Stage 6 of the longitudinal refactor lands (tracker: #301).
-
-## Outputs
-
-See the [data dictionary](docs/data_dictionary.md) for a complete description of every output file, including format details and the processing step that produces each one.
+### Longitudinal
-
-Example BIDS derivative tree
+For multi-session datasets, longitudinal workflows build a within-subject template and reprocess derivatives in that common space. Run the cross-sectional pipeline first:
-```
-derivatives/rbc/
- sub-01/
- ses-01/
- anat/
- sub-01_ses-01_desc-brain_T1w.nii.gz
- sub-01_ses-01_desc-T1w_mask.nii.gz
- sub-01_ses-01_desc-{csf,gm,wm}_mask.nii.gz
- sub-01_ses-01_from-T1w_to-template_mode-image_xfm.nii.gz
- sub-01_ses-01_from-template_to-T1w_mode-image_xfm.nii.gz
- func/
- sub-01_ses-01_task-rest_desc-preproc_bold.nii.gz
- sub-01_ses-01_task-rest_space-MNI152NLin6ASym_desc-preproc_bold.nii.gz
- sub-01_ses-01_task-rest_space-MNI152NLin6ASym_reg-36parameter_desc-preproc_bold.nii.gz
- sub-01_ses-01_task-rest_desc-motionParams_motion.1D
- sub-01_ses-01_task-rest_space-MNI152NLin6ASym_reg-36parameter_desc-xcp_quality.tsv
- sub-01_ses-01_task-rest_space-MNI152NLin6ASym_reg-36parameter_alff.nii.gz
- sub-01_ses-01_task-rest_space-MNI152NLin6ASym_reg-36parameter_reho.nii.gz
- sub-01_ses-01_task-rest_space-MNI152NLin6ASym_atlas-schaefer200_reg-36parameter_desc-mean_timeseries.tsv
- sub-01_ses-01_task-rest_space-MNI152NLin6ASym_atlas-schaefer200_reg-36parameter_desc-pearson_correlations.tsv
+```bash
+rbc all /data -o /data/derivatives
+rbc longitudinal all /data/derivatives -o /data/derivatives
```
-
+`rbc long` is an alias for `rbc longitudinal`.
-## Testing
+
+Individual longitudinal stages
```bash
-# Unit tests (fast, no runner needed)
-uv run pytest -m unit
-
-# Integration tests (requires Docker)
-uv run pytest -m "integration and not slow" --runner docker
-
-# Full pipeline (~30+ min)
-uv run pytest -m full_pipeline --runner docker
+rbc longitudinal template /data/derivatives -o /data/derivatives
+rbc longitudinal anatomical /data/derivatives -o /data/derivatives
+rbc longitudinal functional /data/derivatives -o /data/derivatives --regressor 36-parameter
+rbc longitudinal metrics /data/derivatives -o /data/derivatives --atlas schaefer_200
+rbc longitudinal qc /data/derivatives -o /data/derivatives
```
-See [tests/README.md](tests/README.md) for the full testing strategy.
+
-## Contributing
+## Outputs
-```bash
-uv sync && uv run pre-commit install
-```
+See the [data dictionary](docs/data_dictionary.md) for a complete description of every output file.
-See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
+
+
+
## Citation
@@ -136,20 +98,22 @@ If you use this pipeline, please cite:
}
```
-## About RBC
+## Development
-[Reproducible Brain Charts (RBC)](https://reprobrainchart.github.io/) is an open resource integrating data from 5 large studies of brain development in youth from three continents (N = 6,346). The resource provides:
+```bash
+uv sync && uv run pre-commit install
+```
-- Harmonized psychiatric phenotypes using bifactor models
-- Quality-assured neuroimaging data processed with consistent pipelines
-- All data openly shared via the International Neuroimaging Data-sharing Initiative (INDI)
+```bash
+uv run pytest -m unit # fast, no runner needed
+uv run pytest -m "integration and not slow" # integration tests
+uv run pytest -m full_pipeline # full pipeline (~30+ min)
+```
-RBC facilitates large-scale, reproducible, and generalizable research in developmental and psychiatric neuroscience. The RBC pipeline was developed originally in the [Configurable Pipeline for the Analysis of Connectomes](https://github.com/FCP-INDI/C-PAC/), and has been remade here using NiWrap to increase readability, portability, and runtime efficiency.
+See [tests/README.md](tests/README.md) for the full testing strategy and [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
## License
-[MIT License](LICENSE)
-
-## Acknowledgments
+[LGPL-3.0-or-later](LICENSE)
-This implementation is based on the RBC protocol described in Shafiei et al. (2025) and originally implemented in [C-PAC](https://fcp-indi.github.io/). Development is supported by the [Child Mind Institute](https://childmind.org).
+This implementation is based on the RBC protocol originally implemented in [C-PAC](https://fcp-indi.github.io/). Development is supported by the [Child Mind Institute](https://childmind.org). All data are openly shared via the [International Neuroimaging Data-sharing Initiative (INDI)](https://fcon_1000.projects.nitrc.org/).
diff --git a/docs/data_dictionary.md b/docs/data_dictionary.md
index 080764f1..dd4ba726 100644
--- a/docs/data_dictionary.md
+++ b/docs/data_dictionary.md
@@ -37,6 +37,7 @@ Produced by `rbc anatomical`. These are structural (T1-weighted) processing resu
| `*_desc-wmBBR_mask.nii.gz` | `mask` | White matter boundary used for boundary-based registration (BBR) of functional data to anatomy | FSL WM boundary extraction | 3D NIfTI, binary mask |
| `*_from-T1w_to-MNI152NLin6Asym_mode-image_xfm.nii.gz` | `xfm` | Nonlinear warp field mapping subject anatomy to MNI152NLin6Asym template space | ANTs registration | 3D NIfTI, displacement field |
| `*_from-MNI152NLin6Asym_to-T1w_mode-image_xfm.nii.gz` | `xfm` | Inverse warp field mapping MNI152NLin6Asym template space back to subject anatomy | ANTs registration | 3D NIfTI, displacement field |
+| `*_space-MNI152NLin6Asym_desc-brain_T1w.nii.gz` | `T1w` | Skull-stripped brain image warped to MNI152NLin6Asym template space | ANTs resampling | 3D NIfTI |
---
@@ -52,10 +53,12 @@ Produced by `rbc functional`. These are functional MRI (BOLD) processing results
| `*_desc-relsDisplacement_motion.rms` | `motion` | Frame-to-frame relative root-mean-square displacement over time | FSL MCFLIRT | Text, single-column RMS file |
| `*_desc-maxDisplacement_motion.rms` | `motion` | Absolute root-mean-square displacement of each volume relative to the reference | FSL MCFLIRT | Text, single-column RMS file |
| `*_desc-brain_mask.nii.gz` | `mask` | Binary brain mask in native BOLD space | FSL BET | 3D NIfTI, binary mask |
-| `*_from-bold_to-T1w_mode-image_desc-linear_xfm.mat` | `xfm` | Affine transformation matrix aligning BOLD to the T1w anatomical image | ANTs boundary-based registration | 4x4 affine matrix |
+| `*_from-bold_to-T1w_mode-image_desc-linear_xfm.mat` | `xfm` | Affine transformation matrix aligning BOLD to the T1w anatomical image (FSL format) | ANTs boundary-based registration | 4x4 affine matrix |
+| `*_from-bold_to-T1w_mode-image_desc-linearITK_xfm.txt` | `xfm` | Same BOLD-to-T1w affine in ITK format, used by ANTs for composing longitudinal transforms | Converted from FSL via `rbc.core.fsl2itk` | ITK affine text |
| `*_space-MNI152NLin6Asym_desc-preproc_bold.nii.gz` | `bold` | BOLD timeseries resampled to MNI152NLin6Asym template space in a single interpolation step (before denoising) | ANTs resampling | 4D NIfTI |
| `*_space-MNI152NLin6Asym_desc-bold_mask.nii.gz` | `mask` | Brain mask warped to template space at the BOLD resolution | ANTs resampling | 3D NIfTI, binary mask |
-| `*_space-MNI152NLin6Asym_reg-{regressor}_desc-preproc_bold.nii.gz` | `bold` | Denoised BOLD timeseries in template space after nuisance regression and bandpass filtering. `{regressor}` is `36parameter` or `aCompCor` | Nuisance regression | 4D NIfTI |
+| `*_space-MNI152NLin6Asym_reg-{regressor}_desc-regressed_bold.nii.gz` | `bold` | Nuisance-regressed BOLD in template space (no bandpass filtering). `{regressor}` is `36parameter` or `aCompCor` | AFNI 3dTproject | 4D NIfTI |
+| `*_space-MNI152NLin6Asym_reg-{regressor}_desc-preproc_bold.nii.gz` | `bold` | Denoised BOLD timeseries in template space after nuisance regression and bandpass filtering. `{regressor}` is `36parameter` or `aCompCor` | AFNI 3dTproject -bandpass | 4D NIfTI |
| `*_desc-{regressor}_regressors.1D` | `regressors` | Raw (unfiltered) nuisance regressor matrix. `{regressor}` is `36parameter` or `aCompCor`. Carried forward for longitudinal regression reuse | Computed from motion parameters and tissue masks | Text, multi-column 1D file |
| `*_desc-{regressor}Filtered_regressors.1D` | `regressors` | Bandpass-filtered nuisance regressor matrix matching what `3dTproject -bandpass` applied. For provenance only | FFT-based bandpass filter | Text, multi-column 1D file |
@@ -126,17 +129,77 @@ Produced by `rbc qc`. A single summary file per functional run containing qualit
## Longitudinal outputs
-Produced by the `rbc longitudinal` subcommand group (`template`, `anatomical`, `functional`, `metrics`, `qc`, `all`). Anatomical outputs aligned to a subject-specific longitudinal template built from multiple sessions. Note: longitudinal metrics, QC, and the combined `all` stage are not yet implemented (tracker: #301).
-
-| File | Suffix | Description | Created by | Format |
-| -------------------------------------------------- | ------ | ------------------------------------------------------------------------- | ------------------------------------------ | ---------------------------- |
-| `*_space-longitudinal_desc-brain_T1w.nii.gz` | `T1w` | Skull-stripped brain image aligned to the subject's longitudinal template | ANTs registration to longitudinal template | 3D NIfTI |
-| `*_space-longitudinal_desc-T1w_mask.nii.gz` | `mask` | Brain mask in longitudinal template space | ANTs registration to longitudinal template | 3D NIfTI, binary mask |
-| `*_from-T1w_to-longitudinal_mode-image_xfm.nii.gz` | `xfm` | Warp field mapping subject anatomy to the longitudinal template | ANTs registration | 3D NIfTI, displacement field |
-| `*_from-longitudinal_to-T1w_mode-image_xfm.nii.gz` | `xfm` | Inverse warp field mapping longitudinal template back to subject anatomy | ANTs registration | 3D NIfTI, displacement field |
-| `*_space-longitudinal_sbref.nii.gz` | `sbref` | Motion reference volume warped to longitudinal template space | ANTs warping (composed BOLD-to-longitudinal) | 3D NIfTI |
-| `*_space-longitudinal_desc-preproc_bold.nii.gz` | `bold` | Preprocessed BOLD warped to longitudinal template space | ANTs warping (composed BOLD-to-longitudinal) | 4D NIfTI |
-| `*_space-longitudinal_desc-brain_mask.nii.gz` | `mask` | BOLD brain mask in longitudinal template space | ANTs warping (nearest-neighbor) | 3D NIfTI, binary mask |
-| `*_from-bold_to-longitudinal_...xfm.nii.gz` | `xfm` | Composite BOLD-to-longitudinal-template warp field | ANTs compose transforms | 3D NIfTI, displacement field |
-| `*_space-longitudinal_desc-regressed_reg-_bold.nii.gz` | `bold` | Nuisance-regressed BOLD (no bandpass) in longitudinal space, per regressor strategy | AFNI 3dTproject | 4D NIfTI |
-| `*_space-longitudinal_desc-preproc_reg-_bold.nii.gz` | `bold` | Nuisance-regressed + bandpass-filtered BOLD in longitudinal space, per regressor strategy | AFNI 3dTproject -bandpass | 4D NIfTI |
+Produced by the `rbc longitudinal` subcommand group (`template`, `anatomical`, `functional`, `metrics`, `qc`, `all`). These workflows consume cross-sectional derivatives and align them to a subject-specific longitudinal template built from multiple sessions. `rbc long` is a shorthand alias.
+
+### Template
+
+Produced by `rbc longitudinal template`. One template per subject, one transform per session.
+
+| File | Suffix | Description | Created by | Format |
+| --- | --- | --- | --- | --- |
+| `*_ses-longitudinal_T1w.nii.gz` | `T1w` | Unbiased within-subject T1w template built from all sessions | FreeSurfer `mri_robust_template` | 3D NIfTI |
+| `*_ses-longitudinal_from-{ses}_to-longitudinal_mode-image_xfm.txt` | `xfm` | Affine transform mapping a single session's T1w to the longitudinal template. One file per session, identified by the `from-` entity | FreeSurfer LTA, converted to ITK via `rbc.core.fsl2itk` | ITK affine text |
+
+### Anatomical
+
+Produced by `rbc longitudinal anatomical`.
+
+| File | Suffix | Description | Created by | Format |
+| --- | --- | --- | --- | --- |
+| `*_space-longitudinal_desc-brain_T1w.nii.gz` | `T1w` | Skull-stripped brain image aligned to the subject's longitudinal template | ANTs registration to longitudinal template | 3D NIfTI |
+| `*_space-longitudinal_desc-T1w_mask.nii.gz` | `mask` | Brain mask in longitudinal template space | ANTs registration to longitudinal template | 3D NIfTI, binary mask |
+| `*_from-longitudinal_to-MNI152NLin6Asym_mode-image_xfm.nii.gz` | `xfm` | Warp field mapping longitudinal template space to MNI152NLin6Asym | ANTs registration | 3D NIfTI, displacement field |
+| `*_from-MNI152NLin6Asym_to-longitudinal_mode-image_xfm.nii.gz` | `xfm` | Inverse warp field mapping MNI152NLin6Asym back to longitudinal template space | ANTs registration | 3D NIfTI, displacement field |
+
+### Functional
+
+Produced by `rbc longitudinal functional`.
+
+| File | Suffix | Description | Created by | Format |
+| --- | --- | --- | --- | --- |
+| `*_space-longitudinal_sbref.nii.gz` | `sbref` | Motion reference volume warped to longitudinal template space | ANTs warping (composed BOLD-to-longitudinal) | 3D NIfTI |
+| `*_space-longitudinal_desc-preproc_bold.nii.gz` | `bold` | Preprocessed BOLD warped to longitudinal template space | ANTs warping (composed BOLD-to-longitudinal) | 4D NIfTI |
+| `*_space-longitudinal_desc-brain_mask.nii.gz` | `mask` | BOLD brain mask in longitudinal template space | ANTs warping (nearest-neighbor) | 3D NIfTI, binary mask |
+| `*_from-bold_to-longitudinal_mode-image_xfm.nii.gz` | `xfm` | Composite BOLD-to-longitudinal-template warp field | ANTs compose transforms | 3D NIfTI, displacement field |
+| `*_space-longitudinal_reg-{regressor}_desc-regressed_bold.nii.gz` | `bold` | Nuisance-regressed BOLD (no bandpass) in longitudinal space, per regressor strategy | AFNI 3dTproject | 4D NIfTI |
+| `*_space-longitudinal_reg-{regressor}_desc-preproc_bold.nii.gz` | `bold` | Nuisance-regressed + bandpass-filtered BOLD in longitudinal space, per regressor strategy | AFNI 3dTproject -bandpass | 4D NIfTI |
+
+### Metrics
+
+Produced by `rbc longitudinal metrics`. Identical to the cross-sectional metrics structure, but computed in `space-longitudinal` from the longitudinal-space denoised BOLD.
+
+| File | Suffix | Description | Created by | Format |
+| --- | --- | --- | --- | --- |
+| `*_space-longitudinal_reg-{regressor}_alff.nii.gz` | `alff` | Amplitude of Low-Frequency Fluctuations (0.01-0.1 Hz) | Frequency-domain analysis | 3D NIfTI |
+| `*_space-longitudinal_reg-{regressor}_desc-smooth_alff.nii.gz` | `alff` | Spatially smoothed ALFF map | Gaussian kernel smoothing | 3D NIfTI |
+| `*_space-longitudinal_reg-{regressor}_desc-smoothZstd_alff.nii.gz` | `alff` | Z-scored smoothed ALFF, normalized within the brain mask | Z-score normalization | 3D NIfTI |
+| `*_space-longitudinal_reg-{regressor}_falff.nii.gz` | `falff` | Fractional ALFF (ratio of low-frequency to total power) | Frequency-domain analysis | 3D NIfTI |
+| `*_space-longitudinal_reg-{regressor}_desc-smooth_falff.nii.gz` | `falff` | Spatially smoothed fALFF map | Gaussian kernel smoothing | 3D NIfTI |
+| `*_space-longitudinal_reg-{regressor}_desc-smoothZstd_falff.nii.gz` | `falff` | Z-scored smoothed fALFF | Z-score normalization | 3D NIfTI |
+| `*_space-longitudinal_reg-{regressor}_reho.nii.gz` | `reho` | Regional Homogeneity (Kendall's W, 26-voxel neighborhood) | AFNI 3dReHo | 3D NIfTI |
+| `*_space-longitudinal_reg-{regressor}_desc-smooth_reho.nii.gz` | `reho` | Spatially smoothed ReHo map | Gaussian kernel smoothing | 3D NIfTI |
+| `*_space-longitudinal_reg-{regressor}_desc-smoothZstd_reho.nii.gz` | `reho` | Z-scored smoothed ReHo | Z-score normalization | 3D NIfTI |
+| `*_space-longitudinal_atlas-{atlas}_reg-{regressor}_desc-mean_timeseries.tsv` | `timeseries` | Mean BOLD signal per atlas region | Region-wise averaging | TSV, regions x timepoints |
+| `*_space-longitudinal_atlas-{atlas}_reg-{regressor}_desc-pearson_correlations.tsv` | `correlations` | Pairwise Pearson correlation matrix between atlas regions | Pearson correlation | TSV, regions x regions |
+
+### QC
+
+Produced by `rbc longitudinal qc`. Evaluates registration quality by measuring overlap between the anatomical brain mask and the BOLD brain mask in longitudinal template space.
+
+| File | Suffix | Description | Created by | Format |
+| --- | --- | --- | --- | --- |
+| `*_space-longitudinal_desc-registration_quality.tsv` | `quality` | Single-row TSV with mask overlap metrics (see columns below) | Registration QC | TSV, 1 row |
+
+#### Longitudinal QC columns
+
+| Column | Type | Description |
+| --- | --- | --- |
+| `sub` | string | Subject identifier |
+| `ses` | string | Session label |
+| `task` | string | Task label |
+| `run` | integer | Run number |
+| `dice` | float | Dice coefficient between anat and BOLD masks in longitudinal space |
+| `jaccard` | float | Jaccard index between anat and BOLD masks in longitudinal space |
+| `coverage` | float | Coverage of the smaller mask by the overlap region |
+| `cross_corr` | float | Pearson correlation between flattened binary masks |
+| `passed` | boolean | Whether the run passes the Dice threshold (>= 0.85) |
diff --git a/docs/output_tree.svg b/docs/output_tree.svg
new file mode 100644
index 00000000..e8ef8f82
--- /dev/null
+++ b/docs/output_tree.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/src/rbc/bids/query.py b/src/rbc/bids/query.py
index 7fe74ba8..c5616db2 100644
--- a/src/rbc/bids/query.py
+++ b/src/rbc/bids/query.py
@@ -57,6 +57,11 @@ def load_table(
for d in dirs:
all_roots.extend(b2t.find_bids_datasets(d))
+ # Deduplicate: when one input dir is a subdirectory of another (e.g.
+ # /data and /data/derivatives), find_bids_datasets discovers the nested
+ # dataset from both roots. Use dict.fromkeys to preserve discovery order.
+ all_roots = list(dict.fromkeys(r.resolve() for r in all_roots))
+
tables = b2t.batch_index_dataset(
all_roots,
max_workers=max_workers,