Skip to content

Commit

Permalink
Merge pull request #14 from gagnonanthony/feat/mcribs
Browse files Browse the repository at this point in the history
New infant segmentation pipeline.
New module to format labels from the Desikan-Killiany atlas.
Tissue-specific fodf outputs.
Infant surface reconstruction.
New docker image for M-CRIB-S and InfantFS.
  • Loading branch information
gagnonanthony authored Jan 21, 2025
2 parents 5c31c02 + a5e8f90 commit 85bab01
Show file tree
Hide file tree
Showing 53 changed files with 3,082 additions and 1,464 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
matrix:
NXF_VER:
- "24.10.0"
- "latest-everything"
- "latest"
nf-test-version:
- "0.9.0"
profile:
Expand All @@ -40,6 +40,7 @@ jobs:
- "connectomics.nf.test"
- "tracking.nf.test"
- "freesurfer.nf.test"
- "infantseg.nf.test"
- "multisubjects.nf.test"
isMaster:
- ${{ github.base_ref == 'master' }}
Expand Down
2 changes: 1 addition & 1 deletion .nf-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ lint:
- manifest.name
- manifest.homePage
template_strings: False
nf_core_version: 3.1.1
nf_core_version: 3.1.2
org_path: null
repository_type: pipeline
template:
Expand Down
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,34 @@
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased] - [2025-01-08]
## [Unreleased]

### `Added`

- New testing file for anatomical preprocessing and surface reconstruction of infant data.
- New module for formatting of Desikan-Killiany atlas (for infant).
- Output of tissue-specific `fodf` maps in BIDS output.
- Anatomical preprocessing pipeline for infant data using M-CRIB-S and Infant FS.
- Coregistration of T2w and T1w if both available for the infant profile.
- New docker image for infant anatomical segmentation and surface reconstruction (M-CRIB-S and Infant FS)
- Required --dti_shells and --fodf_shells parameters.

### `Fixed`

- Structural segmentation pipeline for infant data. (#3)

### `Changed`

- Bump `nf-core` version to `3.1.2`.
- Refactored `-profile freesurfer` to `-profile segmentation`.
- Config files have been moved from the `modules.config` into themed config files for easier maintainability.
- Fastsurfer and freesurfer outputs are now in their own dedicated output folder.

### `Removed`

- Custom atlas name parameter until the use of custom atlas is enabled.
- White matter mask and labels files as required inputs since they can now be computed for all ages.

## [Unreleased] - [2024-12-23]

### `Added`
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Introduction

**nf-pediatric** is an end-to-end connectomics pipeline for pediatric (0-18y) dMRI and sMRI brain scans. It performs tractography, t1 reconstruction, cortical and subcortical segmentation, and connectomics. Final outputs are connectivity matrices for a variety of diffusion (or not) related metrics.
**nf-pediatric** is an end-to-end connectomics pipeline for pediatric (0-18y) dMRI and sMRI brain scans. It performs tractography, t1 reconstruction, cortical and subcortical segmentation, and connectomics.

![nf-pediatric-schema](/assets/nf-pediatric-schema.svg)

Expand All @@ -17,22 +17,22 @@

**Processing profiles**:

1. `-profile freesurfer`: By selecting this profile, [FreeSurfer `recon-all`](https://surfer.nmr.mgh.harvard.edu/) or [FastSurfer](https://deep-mi.org/research/fastsurfer/) will be used to process the T1w images and the Brainnetome Child Atlas ([Li et al., 2022](https://doi.org/10.1093/cercor/bhac415)) will be registered using surface-based methods in the native subject space.
1. `-profile tracking`: This is the core profile behind `nf-pediatric`. By selecting it, DWI data will be preprocessed (denoised, corrected for distortion, normalized, resampled, ...). In parallel, T1 will be preprocessed (if `-profile freesurfer` is not selected), registered into diffusion space, and segmented to extract tissue masks. Preprocessed DWI data will be used to fit both the DTI and fODF models. As the final step, whole-brain tractography will be performed using either local tracking or particle filter tracking (PFT).
1. `-profile segmentation`: By selecting this profile, [FreeSurfer `recon-all`](https://surfer.nmr.mgh.harvard.edu/), [FastSurfer](https://deep-mi.org/research/fastsurfer/) or MCRIBS/InfantFS will be used to process the T1w/T2w images and the Brainnetome Child Atlas ([Li et al., 2022](https://doi.org/10.1093/cercor/bhac415)) or Desikan-Killiany (for infant) will be registered using surface-based methods in the native subject space.
1. `-profile tracking`: This is the core profile behind `nf-pediatric`. By selecting it, DWI data will be preprocessed (denoised, corrected for distortion, normalized, resampled, ...). In parallel, T1w will be preprocessed (if `-profile segmentation` is not selected), registered into diffusion space, and segmented to extract tissue masks. Preprocessed DWI data will be used to fit both the DTI and fODF models. As the final step, whole-brain tractography will be performed using either local tracking or particle filter tracking (PFT).
1. `-profile connectomics`: By selecting this profiles, the whole-brain tractogram will be filtered to remove false positive streamlines, labels will be registered in diffusion space and used to segment the tractogram into individual connections. Following segmentation, connectivity matrices will be computed for a variety of metrics and outputted as numpy arrays usable for further statistical analysis.
1. `-profile infant`: As opposed to the other profiles, the `infant` profile does not enable a specific block of processing steps, but will change various configs and parameters to adapt the existing profile for infant data (<2 years). This profile is made to be used in conjunction with the others (with the exception of `-profile freesurfer` which is unavailable for infant data for now).
1. `-profile infant`: As opposed to the other profiles, the `infant` profile does not enable a specific block of processing steps (although various steps are changed compared to the default pipeline), but will change various configs and parameters to adapt the existing profile for infant data (<2 years). This profile is made to be used in conjunction with the others.

**Configuration profiles**:

1. `-profile docker`: Each process will be run using docker containers.
1. `-profile apptainer` or `-profile singularity`: Each process will be run using apptainer/singularity images.
1. `-profile arm`: Made to be use on computers with an ARM architecture.
1. `-profile arm`: Made to be use on computers with an ARM architecture. **This is still experimental, depending on which profile you select, some containers might not be built for the ARM architecture. Feel free to open an issue if needed.**
1. `-profile no_symlink`: By default, the results directory contains symlink to files within the `work` directory. By selecting this profile, results will be copied from the work directory without the use of symlinks.
1. `-profile slurm`: If selected, the SLURM job scheduler will be used to dispatch jobs.

**Using either `-profile docker` or `-profile apptainer` is highly recommended, as it controls the version of the software used and avoids the installation of all the required softwares.**

For example, to perform the end-to-end connectomics pipeline, users should select `-profile tracking,freesurfer,connectomics` for pediatric data and `-profile infant,tracking,connectomics` for infant data. Once you selected your profile, you can check which input files are mandatory [here](/docs/usage.md). In addition to profile selection, users can change default parameters using command line arguments at runtime. To view a list of the parameters that can be customized, use the `--help` argument as follow:
For example, to perform the end-to-end connectomics pipeline, users should select `-profile tracking,segmentation,connectomics` for pediatric data and `-profile infant,tracking,segmentation,connectomics` for infant data. Once you selected your profile, you can check which input files are mandatory [here](/docs/usage.md). In addition to profile selection, users can change default parameters using command line arguments at runtime. To view a list of the parameters that can be customized, use the `--help` argument as follow:

```bash
nextflow run scilus/nf-pediatric -r main --help
Expand Down
25 changes: 25 additions & 0 deletions assets/Docker/mcribs/fsl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: fsl
channels:
- https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/
- conda-forge
dependencies:
- python =3.11
- mkl=2023.2.0
- mkl-service=2.4.0
# Base scientific python stack; required by FSL, so pinned here
- numpy=1.26
- scipy=1.11
- matplotlib=3.8
- pandas=2.2
- h5py=3.10
- nitime=0.10
- scikit-image=0.22
- scikit-learn=1.4
# FSL dependencies.
- fsl-bet2=2111.4
- fsl-flirt=2111.2
- fsl-fast4=2111.3
- fsl-fugue=2201.4
- fsl-mcflirt=2111.0
- fsl-miscmaths=2203.2
- fsl-topup=2203.2
122 changes: 122 additions & 0 deletions assets/Docker/mcribs/nf-pediatric_mcribs.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
ARG BASE_IMAGE=ubuntu:jammy-20240405

# Older Python to support legacy MCRIBS (taken from nibabies Dockerfile)
FROM python:3.6.15-slim AS pyenv
RUN pip install --no-cache-dir numpy nibabel scipy pandas numexpr contextlib2 imageio \
&& cp /usr/lib/x86_64-linux-gnu/libffi.so.7* /usr/local/lib

# Download FSL.
FROM ${BASE_IMAGE} AS build-fsl

RUN apt-get update && \
apt-get install -y --no-install-recommends \
build-essential \
binutils \
bzip2 \
ca-certificates \
curl \
unzip \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

WORKDIR /
RUN echo "2024.04.25" && curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj
ENV MAMBA_ROOT_PREFIX="/opt/conda"

# Fetch the FSL environment
COPY fsl.yml fsl.yml
RUN micromamba create -y -f fsl.yml && \
micromamba clean --all --yes
ENV PATH="/opt/conda/envs/fsl/bin:$PATH"

# Set a stage for the build
FROM ${BASE_IMAGE} AS runtime

ENV DEBIAN_FRONTEND="noninteractive" \
LANG="en_US.UTF-8" \
LC_ALL="en_US.UTF-8"

RUN apt-get update && \
apt-get install -y --no-install-recommends \
apt-utils \
bc \
build-essential \
ca-certificates \
curl \
git \
gnupg \
libtool \
locales \
lsb-release \
tcsh \
netbase \
unzip \
xvfb \
# MCRIBS-required
libboost-dev \
libeigen3-dev \
libflann-dev \
libgl1-mesa-dev \
libglu1-mesa-dev \
libssl-dev \
libxt-dev \
zlib1g-dev && \
locale-gen en_US.UTF-8 && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Configure PPAs for libpng12 and libxp6
RUN GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/linuxuprising.gpg --recv 0xEA8CACC073C3DB2A \
&& GNUPGHOME=/tmp gpg --keyserver hkps://keyserver.ubuntu.com --no-default-keyring --keyring /usr/share/keyrings/zeehio.gpg --recv 0xA1301338A3A48C4A \
&& echo "deb [signed-by=/usr/share/keyrings/linuxuprising.gpg] https://ppa.launchpadcontent.net/linuxuprising/libpng12/ubuntu jammy main" > /etc/apt/sources.list.d/linuxuprising.list \
&& echo "deb [signed-by=/usr/share/keyrings/zeehio.gpg] https://ppa.launchpadcontent.net/zeehio/libxp/ubuntu jammy main" > /etc/apt/sources.list.d/zeehio.list

# Install ANTs
COPY --from=gagnonanthony/ants@sha256:0abd03bc59c10ea4a93e399d07c5e4019cf8eb89963a54e050f209ed73722dce /opt/ants /opt/ants
ENV PATH="/opt/ants/bin:$PATH" \
ANTSPATH="/opt/ants" \
LD_LIBRARY_PATH="/opt/ants/lib:$LD_LIBRARY_PATH"

# Install FreeSurfer (with Infant Module)
COPY --from=nipreps/freesurfer@sha256:3b895fc732a7080374a15c4f976510f39c0c48dc76c030ab27316febd5e419ee /opt/freesurfer /opt/freesurfer
ENV FREESURFER_HOME="/opt/freesurfer"
ENV SUBJECTS_DIR="$FREESURFER_HOME/subjects" \
FUNCTIONALS_DIR="$FREESURFER_HOME/sessions" \
MNI_DIR="$FREESURFER_HOME/mni" \
LOCAL_DIR="$FREESURFER_HOME/local" \
MINC_BIN_DIR="$FREESURFER_HOME/mni/bin" \
MINC_LIB_DIR="$FREESURFER_HOME/mni/lib" \
MNI_DATAPATH="$FREESURFER_HOME/mni/data" \
FSL_DIR=${FSLDIR} \
FREESURFER="/opt/freesurfer"
ENV PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
MNI_PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \
PATH="$FREESURFER_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH"

# Install MCRIBS from nipreps (with legacy Python)
COPY --from=gagnonanthony/mcribs@sha256:12ddd74a0d47f055bea4bb19cc0df5b39d0b3ee2aa76d4276d4bfea6f169b2b5 /opt/MCRIBS/ /opt/MCRIBS
COPY --from=pyenv /usr/local/lib/ /usr/local/lib/
COPY --from=pyenv /usr/local/bin/python3 /opt/MCRIBS/bin/python
ENV PATH="/opt/MCRIBS/bin:/opt/MCRIBS/MIRTK/MIRTK-install/bin:/opt/MCRIBS/MIRTK/MIRTK-install/lib/tools:${PATH}" \
LD_LIBRARY_PATH="/opt/MCRIBS/lib:/opt/MCRIBS/ITK/ITK-install/lib:/opt/MCRIBS/VTK/VTK-install/lib:/opt/MCRIBS/MIRTK/MIRTK-install/lib:/usr/local/lib:${LD_LIBRARY_PATH}" \
MCRIBS_HOME="/opt/MCRIBS" \
PYTHONPATH="/opt/MCRIBS/lib/python:/usr/local/lib/python3.6/site-packages/:${PYTHONPATH}"

# Install FSL
COPY --from=build-fsl /bin/micromamba /bin/micromamba
COPY --from=build-fsl /opt/conda/envs/fsl /opt/conda/envs/fsl
ENV MAMBA_ROOT_PREFIX="/opt/conda" \
PATH="${PATH}:/opt/conda/envs/fsl/bin" \
CPATH="/opt/conda/envs/fsl/include:${CPATH}" \
LD_LIBRARY_PATH="/opt/conda/envs/fsl/lib:${LD_LIBRARY_PATH}" \
CONDA_PYTHON="/opt/conda/envs/fsl/bin/python"

# FSL environment.
ENV LANG="C.UTF-8" \
LC_ALL="C.UTF-8" \
PYTHONNOUSERSITE=1 \
FSLDIR="/opt/conda/envs/fsl" \
FSLOUTPUTTYPE="NIFTI_GZ" \
FSLMULTIFILEQUIT="TRUE" \
FSLLOCKDIR="" \
FSLMACHINELIST="" \
FSLREMOTECALL="" \
FSLGECUDAQ="cuda.q"
56 changes: 56 additions & 0 deletions assets/FS_BN_GL_SF_utils/convert_fs_stats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/python

import argparse
import logging

import pandas as pd

def _build_arg_parser():
p = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawTextHelpFormatter)

p.add_argument('-i', '--input', required=True,
help='Input freesurfer stats file (.stats)')
p.add_argument('-o', '--output', required=True,
help='Output tsv file')

p.add_argument('-m', '--measure', required=True,
help='Measure to extract from stats file',
choices=['GrayVol', 'SurfArea', 'ThickAvg'])
p.add_argument('-s', '--subject', required=True,
help='Subject ID')

return p


def main():
parser = _build_arg_parser()
args = parser.parse_args()
logging.getLogger().setLevel(logging.INFO)

# Load stats file.
df = pd.read_csv(args.input)

# Freesurfer stats file have regions as rows and measures as columns,
# need to transpose it with the desired measure.
df_m = df.loc[:, ["StructName", args.measure]].T

# Setting the first row as the column names.
df_m.columns = df_m.iloc[0]

# Dropping the first row.
df_m = df_m[1:]

# Replace first column name with "Sample" and add subject ID.
df_m.columns.name = "Sample"
df_m.index = [args.subject]

# Dropping the medial wall column.
df_m = df_m.drop(columns="Medial_Wall")

# Save to tsv.
df_m.to_csv(args.output, sep='\t', index=True, header=True)


if __name__ == '__main__':
main()
1 change: 1 addition & 0 deletions assets/methods_description_template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ data: |
<li>Tustison, N. J., Cook, P. A., Holbrook, A. J., Johnson, H. J., Muschelli, J., Devenyi, G. A., Duda, J. T., Das, S. R., Cullen, N. C., Gillen, D. L., Yassa, M. A., Stone, J. R., Gee, J. C., & Avants, B. B. (2021). The ANTsX ecosystem for quantitative biological and medical imaging. Scientific Reports, 11(1), 9068. doi: <a href="https://doi.org/10.1038/s41598-021-87564-6">10.1038/s41598-021-87564-6</a></li>
<li>Henschel, L., Conjeti, S., Estrada, S., Diers, K., Fischl, B., & Reuter, M. (2020). FastSurfer—A fast and accurate deep learning based neuroimaging pipeline. NeuroImage, 219, 117012. doi: <a href="https://doi.org/10.1016/j.neuroimage.2020.117012">10.1016/j.neuroimage.2020.117012</a></li>
<li>Fischl, B. (2012). FreeSurfer. NeuroImage, 62(2), 774–781. doi: <a href="https://doi.org/10.1016/j.neuroimage.2012.01.021">10.1016/j.neuroimage.2012.01.021</a></li>
<li>Adamson C. L., Alexander B., Ball G., Beare R., Cheong J. L. Y., Spittle A. J., Doyle L. W., Anderson P. J., Seal M. L., Thompson D. K. (2020). Parcellation of the neonatal cortex using Surface-based Melbourne Children's Regional Infant Brain atlases (M-CRIB-S). Scientific Reports, 10(1), 4359. doi: <a href="https://doi.org/10.1038/s41598-020-61326-2">10.1038/s41598-020-61326-2</a></li>
${tool_bibliography}
</ul>
<div class="alert alert-info">
Expand Down
Loading

0 comments on commit 85bab01

Please sign in to comment.