Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Fix/hotfixes into master #1

Merged
merged 12 commits into from
Aug 14, 2023
6 changes: 3 additions & 3 deletions .base/manifest.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
manifest {
author = "Alex Valcourt Caron"
description = """
versaflow : a pipeline for robust, reproducible and adaptive preprocessing
versaFlow : a pipeline for robust, reproducible and adaptive preprocessing
and modelisation of the axonal structure in primate brain diffusion MRI data
""".stripMargin()
doi = "https://doi.org/10.1101/2021.11.22.469616"
homePage = "https://github.com/AlexVCaron/versaflow"
name = "versaflow"
homePage = "https://github.com/AlexVCaron/versaFlow"
name = "versaFlow"
version = "0.9"
}
4 changes: 4 additions & 0 deletions .config/t1_to_b0_registration_affine_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
# AntsConfiguration(mrHARDIConfigurable) configuration
# -----------------------------------------------------------------------------

c.AntsConfiguration.coarse_angular_split = 3

c.AntsConfiguration.coarse_linear_split = 3

c.AntsConfiguration.accross_modalities = True

c.AntsConfiguration.dimension = 3
Expand Down
6 changes: 6 additions & 0 deletions .config/t1_to_template_affine_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

c.AntsRegistration.log_level = 30

c.AntsRegistration.init_with_ants_ai = True

c.AntsRegistration.base_config_file = ""

c.AntsRegistration.init_with_ants_ai = True
Expand All @@ -24,6 +26,10 @@
# AntsConfiguration(mrHARDIConfigurable) configuration
# -----------------------------------------------------------------------------

c.AntsConfiguration.coarse_angular_split = 3

c.AntsConfiguration.coarse_linear_split = 3

c.AntsConfiguration.accross_modalities = False

c.AntsConfiguration.dimension = 3
Expand Down
6 changes: 6 additions & 0 deletions .config/t1_to_template_affine_quick_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
# AntsConfiguration(mrHARDIConfigurable) configuration
# -----------------------------------------------------------------------------

c.AntsConfiguration.coarse_angular_split = 2

c.AntsConfiguration.coarse_linear_split = 3

c.AntsConfiguration.fine_angular_split = 5

c.AntsConfiguration.accross_modalities = False

c.AntsConfiguration.dimension = 3
Expand Down
18 changes: 6 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
[![Docker containers](https://img.shields.io/badge/Docker%20images-dockerhub-blue?style=plaflat&logo=docker&labelColor=2e343b)](https://hub.docker.com/repository/docker/avcaron/versa)
[![DOI](https://zenodo.org/badge/430873937.svg)](https://zenodo.org/badge/latestdoi/430873937)

**versaFlow and its images are moving here ! This repository is still being deployed, there might be some errors running versaFlow right now, we are actively working on it**
# versaFlow

# versaflow

versaflow is a diffusion MRI processing pipeline configured to handle high
versaFlow is a diffusion MRI processing pipeline configured to handle high
angular and spatial resolution data. By default it is configured to process
Maccaca Mulatta brain images; profiles to handle other types of primates, as
well as the human brain are being developped. The pipeline's pre-processing
Expand All @@ -19,10 +17,9 @@ If you use this tool for your research, **please cite the following**

```
Valcourt Caron A., Shmuel A., Hao Z., Descoteaux M.,
“versaflow : A pipeline tailored for the preprocessing and analysis of
Multi-Resolution High Angular diffusion MRI and its application to a
variability study of the PRIME-DE database”,
bioRxiv, 2021.11.22.469616, doi.org/10.1101/2021.11.22.469616.
“versaFlow: a versatile pipeline for resolution adapted diffusion MRI processing
and its application to studying the variability of the PRIME-DE database”,
Frontiers in Neuroinformatics, 10.3389/fninf.2023.1191200, doi.org/10.3389/fninf.2023.1191200.
```

## Requirements
Expand All @@ -40,8 +37,7 @@ and require a Nvidia GPU to execute. For usage on a machine without a Nvidia GPU
use the images tagged `nogpu`.

- Docker : [Docker Hub](https://hub.docker.com/r/avcaron/versa)
- Nvidia GPU : `docker pull avcaron/versa:latest`
- Without GPU : `docker pull avcaron/versa:nogpu`
- `docker pull avcaron/versa:latest`
- Singularity :
- Singularity images are no longer produced in house. To build your singularity,
use a docker tag and the following command : `singularity build <image.sif> docker://avcaron/versa:<tag>`.
Expand All @@ -50,8 +46,6 @@ use the images tagged `nogpu`.
- Nvidia GPU : `singularity pull oras://mrhardi.azurecr.io/mrHARDI/mrhardi:latest`
- Without GPU : `singularity pull oras://mrhardi.azurecr.io/mrHARDI/mrhardi:nogpu`



# Data input format

**\*\* All images must be in the compressed Nifti format (.nii.gz) \*\***
Expand Down
4 changes: 2 additions & 2 deletions USAGE
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
versaflow
versaFlow
===========


Usage

nextflow run [-resume] [-with-singularity <sif> | -with-docker [<docker_image> | avcaron/versa:<latest|nogpu>]] [-w <workdir>] [-profile <profile>] -dsl2 main.nf --data_root <root> [ additional parameters ... ]
nextflow run [-resume] [-with-singularity <sif> | -with-docker [<docker_image> | avcaron/versa:<latest|v*.*.*>]] [-w <workdir>] [-profile <profile>] -dsl2 main.nf --data_root <root> [ additional parameters ... ]

DESCRIPTION

Expand Down
2 changes: 1 addition & 1 deletion main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def validate_required_parameters () {
}

def display_run_info () {
log.info "versaflow pipeline"
log.info "versaFlow pipeline"
log.info "==================="
log.info ""
log.info "Start time : $workflow.start"
Expand Down
2 changes: 1 addition & 1 deletion modules/functions.nf
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def separate_b0_from_dwi( data_channel ) {
return [exclude_missing_datapoints(data_channel, 2, ""), filter_datapoints(data_channel, { it[2] == "" })]
}

LIBRARY_ROOT_NAME = "versaflow"
LIBRARY_ROOT_NAME = "versaFlow"

def get_data_path () {
def current_dir = file("$projectDir")
Expand Down
16 changes: 15 additions & 1 deletion modules/processes/denoise.nf
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ process n4_denoise {
tuple val(sid), path("${image.simpleName}__n4denoised_metadata.*"), optional: true, emit: metadata
tuple val(sid), path("${image.simpleName}_n4_bias_field.nii.gz"), emit: bias_field
script:
def before_denoise =""
def after_denoise = ""
def args = ""
if ( anat.empty() ) {
Expand All @@ -142,14 +143,25 @@ process n4_denoise {
}
after_denoise += "fslmaths n4denoise.nii.gz -thr 0 ${image.simpleName}__n4denoised.nii.gz\n"

if ( !mask.empty() )
if ( !mask.empty() ) {
args += " --mask $mask"
if ( !anat.empty() ) {
before_denoise += "antsApplyTransforms -n NearestNeighbor -e 0 -r $anat -t identity -i $mask -o $mask\n"
before_denoise += "scil_image_math.py convert $mask $mask -f --data_type uint8\n"
}
else {
before_denoise += "antsApplyTransforms -n NearestNeighbor -e 0 -r $image -t identity -i $mask -o $mask\n"
before_denoise += "scil_image_math.py convert $mask $mask -f --data_type uint8\n"
}
}

"""
export OMP_NUM_THREADS=$task.cpus
export ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=$task.cpus
export OPENBLAS_NUM_THREADS=1
export ANTS_RANDOM_SEED=$params.random_seed

$before_denoise
mrhardi n4 $args \
--out n4denoise \
--config $config
Expand Down Expand Up @@ -248,6 +260,7 @@ process prepare_epi_correction {
tuple val(sid), path("${b0s.simpleName}__${algo}_config.cnf"), optional: true, emit: config
tuple val(sid), val("${sid}__${algo}_results"), emit: awaited_out_name
tuple val(sid), path("${b0s.simpleName}__${algo}_metadata.*"), emit: metadata
tuple val(sid), path("${sid}__${algo}_metadata.*"), emit: metadata_for_corrected_dwi
tuple val(sid), path("{${dwi_bval.collect{ it.simpleName }.join(",")},${rev_bval.collect{ it.simpleName }.join(",")}}_topup_indexes_metadata.*"), optional: true, emit : in_metadata_w_epi_correction
script:
"""
Expand All @@ -259,6 +272,7 @@ process prepare_epi_correction {
--b0-thr ${params.b0_threshold ? params.b0_threshold : "0"} \
--config $config \
--verbose
cp ${b0s.simpleName}__${algo}_metadata.py ${sid}__${algo}_metadata.py
"""
}

Expand Down
1 change: 1 addition & 0 deletions modules/workflows/t1_registration.nf
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ workflow t12b0_registration {
reference = extract_b0.out.b0
resampling_reference = registration_reference
template_to_t1_transform = template_to_t1_transform
template_to_b0_transform = template_to_b0_transform
}

workflow t1_to_b0_affine {
Expand Down
2 changes: 1 addition & 1 deletion nextflow.config
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ params.max_safe_csf_pvf_threshold = 0.05
params.max_safe_gm_pvf_threshold = 0.01
params.safe_csf_mask_dilation = 1
params.safe_gm_mask_dilation = 0
params.atropos_prior_weight = 0.0
params.atropos_prior_weight = 0.3

// Diffusion modeling
params.strict_parameters = true
Expand Down
50 changes: 22 additions & 28 deletions workflows/preprocess.nf
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,23 @@ workflow preprocess_wkf {
.map{ [it[0], it[1].find{m -> m.simpleName.contains("_rev")}, "rev__ec_input_rev_metadata"] }
).map{ it.flatten() }


apply_transform_epi_rev(
ec_input_rev_channel.map{ it[0..1] }
.join(epi_correction_wkf.out.transform_reference)
.join(epi_correction_wkf.out.forward_transform)
.join(epi_correction_wkf.out.reverse_transform)
.map{ it[0..-3] + [it[-2] + it[-1]] }
.map{ it + [["true", "false"], "", ""] },
"preprocess",
"",
"false",
"",
params.ants_transform_base_config
)
rev_channel = replace_dwi_file(rev_channel, apply_transform_epi_rev.out.image)

// Applied estimated susceptibility correction to DWI
ec2eddy_channel = Channel.empty()
epi_fieldmap_channel = Channel.empty()
epi_displacement_field_channel = Channel.empty()
Expand All @@ -405,7 +422,7 @@ workflow preprocess_wkf {
// Applied estimated susceptibility correction to DWI
apply_topup_wkf(
ec_input_dwi_channel,
ec_input_rev_channel,
apply_transform_epi_rev.out.image,
ec2eddy_channel,
ec_input_dwi_meta_channel
.join(ec_input_rev_meta_channel)
Expand All @@ -426,31 +443,8 @@ workflow preprocess_wkf {
epi_displacement_field_channel = epi_correction_wkf.out.field
epi_fieldmap_channel = epi_correction_wkf.out.fieldmap

// Applied estimated susceptibility correction to DWI
apply_transform_epi_dwi(
ec_input_dwi_channel.map{ it[0..1] }
.join(epi_correction_wkf.out.transform_reference)
.join(epi_correction_wkf.out.forward_transform)
.map{ it + [it[-1].collect{ "false" }, "", ""] },
"preprocess",
"",
"false",
"",
params.ants_transform_base_config
)
apply_transform_epi_rev(
ec_input_rev_channel.map{ it[0..1] }
.join(epi_correction_wkf.out.transform_reference)
.join(epi_correction_wkf.out.reverse_transform)
.map{ it + [it[-1].collect{ "false" }, "", ""] },
"preprocess",
"",
"false",
"",
params.ants_transform_base_config
)
apply_epi_field_wkf(
apply_transform_epi_dwi.out.image,
ec_input_dwi_channel.map{ it[0..1] },
apply_transform_epi_rev.out.image,
epi_displacement_field_channel,
ec_input_dwi_meta_channel,
Expand Down Expand Up @@ -873,7 +867,7 @@ workflow preprocess_wkf {

// Register T1 to diffusion space (DWI) with masks and segmentations
template_resampling_reference = null
template_to_t1_transform = null
template_to_b0_transform = null
if ( params.register_t1_to_dwi ) {
t1_registration_wkf(
dwi_channel,
Expand All @@ -888,7 +882,7 @@ workflow preprocess_wkf {
)

template_resampling_reference = t1_registration_wkf.out.resampling_reference
template_to_t1_transform = t1_registration_wkf.out.template_to_t1_transform
template_to_b0_transform = t1_registration_wkf.out.template_to_b0_transform

t1_channel = t1_registration_wkf.out.t1
t1_mask_channel = t1_registration_wkf.out.mask
Expand Down Expand Up @@ -1026,7 +1020,7 @@ workflow preprocess_wkf {
absent_pvf_id_channel.join(t1_channel),
absent_pvf_id_channel.join(t1_mask_channel),
template_resampling_reference,
template_to_t1_transform
template_to_b0_transform
)

pvf_channel = segment_nmt_wkf.out.volume_fractions
Expand Down