Skip to content

Commit

Permalink
Merge pull request #1 from frheault/code_transfert_alpha
Browse files Browse the repository at this point in the history
Not tested but LGTM and since it's a first PR let's go give it a try !
  • Loading branch information
arnaudbore authored Jun 27, 2020
2 parents 03326ff + 0e719b8 commit bb81603
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 2 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 Sherbrooke Connectivity Imaging Lab
Copyright (c) 2019 Sherbrooke Connectivity Imaging Lab

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,32 @@
# rbx-flow
# RecobundlesX pipeline
===================

Run the RecobundlesX pipeline.

If you use this pipeline, please cite:

```
Garyfallidis, Eleftherios, et al. Recognition of white matter bundles using
local and global streamline-based registration and clustering.
NeuroImage 170 (2018) https://doi.org/10.1016/j.neuroimage.2017.07.015
Kurtzer GM, Sochat V, Bauer MW Singularity: Scientific containers for
mobility of compute. PLoS ONE 12(5): e0177459 (2017)
https://doi.org/10.1371/journal.pone.0177459
P. Di Tommaso, et al. Nextflow enables reproducible computational workflows.
Nature Biotechnology 35, 316–319 (2017) https://doi.org/10.1038/nbt.3820
```

Requirements
------------

- [Nextflow](https://www.nextflow.io)
- [scilpy](https://github.com/scilus/scilpy)
- [ants](https://github.com/ANTsX/ANTs)

Usage
-----

See *USAGE* or run `nextflow run main.nf --help`

40 changes: 40 additions & 0 deletions USAGE
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Pipeline for RecobundlesX tractography
======================================

USAGE

nextflow run main.nf --root ... [OPTIONAL_ARGUMENTS]

DESCRIPTION

--root=/path/to/[root] Root folder containing multiple subjects

[root]
├── S1
│ ├── *anat.nii.gz
│ └── *tracking.trk
└── S2
└── *

--atlas_config Path to json config file
--atlas_anat Path to reference anatomy of the atlas
--atlas_directory Path of the folder containing all atlases

NOTES

OPTIONAL ARGUMENTS (current value)
--atlas_centroids Folder containing centroids (trk) for future tractometry (Must have the same filename as in the atlas_config)

--multi_parameters Number of executions for the multi-parameters ($multi_parameters)
--minimal_vote_ratio Percentage of the vote to obtain in order to be considered valid ($minimal_vote_ratio)
--wb_clustering_thr List of distance (mm) for QBx whole brain clustreing ($wb_clustering_thr)
--seeds List of random seeds values for the rng ($seeds)
--outlier_alpha Remove spurious streamlines based on shape ($outlier_alpha)

--register_processes Number of processes for registration task ($register_processes).
--rbx_processes Number of processes for bundle recognition task ($rbx_processes).

Use '-C config_file.config' to specify a non-default configuration file.
The '-C config_file.config' must be inserted after the nextflow call
like 'nextflow -C config_file.config run ...'.

159 changes: 159 additions & 0 deletions main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#!/usr/bin/env nextflow

if(params.help) {
usage = file("$baseDir/USAGE")
cpu_count = Runtime.runtime.availableProcessors()

bindings = ["atlas_config":"$params.atlas_config",
"atlas_directory":"$params.atlas_directory",
"atlas_centroids":"$params.atlas_centroids",
"multi_parameters":"$params.multi_parameters",
"minimal_vote_ratio":"$params.minimal_vote_ratio",
"wb_clustering_thr":"$params.wb_clustering_thr",
"seeds":"$params.seeds",
"outlier_alpha":"$params.outlier_alpha",
"register_processes":"$params.register_processes",
"rbx_processes":"$params.rbx_processes"]

engine = new groovy.text.SimpleTemplateEngine()
template = engine.createTemplate(usage.text).make(bindings)
print template.toString()
return
}

log.info "SCIL RecobundlesX pipeline"
log.info "=========================="
log.info ""
log.info "Start time: $workflow.start"
log.info ""

log.debug "[Command-line]"
log.debug "$workflow.commandLine"
log.debug ""

log.info "[Git Info]"
log.info "$workflow.repository - $workflow.revision [$workflow.commitId]"
log.info ""

log.info "Options"
log.info "======="
log.info ""
log.info "[Atlas]"
log.info "Atlas Config: $params.atlas_config"
log.info "Atlas Anat: $params.atlas_anat"
log.info "Atlas Directory: $params.atlas_directory"
log.info "Atlas Centroids: $params.atlas_centroids"
log.info ""
log.info "[Recobundles options]"
log.info "Multi-Parameters Executions: $params.multi_parameters"
log.info "Minimal Vote Percentage: $params.minimal_vote_ratio"
log.info "Whole Brain Clustering Threshold: $params.wb_clustering_thr"
log.info "Random Seeds: $params.seeds"
log.info "Outlier Removal Alpha: $params.outlier_alpha"
log.info ""
log.info ""

log.info "Input: $params.root"
root = file(params.root)
/* Watch out, files are ordered alphabetically in channel */
in_data = Channel
.fromFilePairs("$root/**/{*tracking.trk,*anat.nii.gz}",
size: 2,
maxDepth:2,
flat: true) {it.parent.name}

atlas_anat = Channel.fromPath("$params.atlas_anat")
atlas_config = Channel.fromPath("$params.atlas_config")
atlas_directory = Channel.fromPath("$params.atlas_directory")

if (params.atlas_centroids) {
atlas_centroids = Channel.fromPath("$params.atlas_centroids/*.trk")
}
else {
atlas_centroids = Channel.empty()
}

(anat_for_registration, anat_for_reference, tractogram_for_recognition) = in_data
.map{sid, anat, tractogram ->
[tuple(sid, anat),
tuple(sid, anat),
tuple(sid, tractogram)]}
.separate(3)

workflow.onComplete {
log.info "Pipeline completed at: $workflow.complete"
log.info "Execution status: ${ workflow.success ? 'OK' : 'failed' }"
log.info "Execution duration: $workflow.duration"
}

anat_for_registration
.combine(atlas_anat)
.set{anats_for_registration}
process Register_Anat {
cpus params.register_processes
input:
set sid, file(native_anat), file(atlas) from anats_for_registration

output:
set sid, "${sid}__output0GenericAffine.txt" into transformation_for_recognition, transformation_for_centroids
file "${sid}__outputWarped.nii.gz"
script:
"""
antsRegistrationSyNQuick.sh -d 3 -f ${native_anat} -m ${atlas} -n ${params.register_processes} -o ${sid}__output -t a
ConvertTransformFile 3 ${sid}__output0GenericAffine.mat ${sid}__output0GenericAffine.txt --hm --ras
"""
}


anat_for_reference
.join(transformation_for_centroids, by: 0)
.set{anat_and_transformation}
process Transform_Centroids {
input:
set sid, file(anat), file(transfo) from anat_and_transformation
each file(centroid) from atlas_centroids
output:
file "${sid}__${centroid.baseName}.trk"
script:
"""
scil_apply_transform_to_tractogram.py ${centroid} ${anat} ${transfo} ${sid}__${centroid.baseName}.trk --inverse --remove_invalid
"""
}

tractogram_for_recognition
.combine(transformation_for_recognition, by: 0)
.combine(atlas_config)
.combine(atlas_directory)
.set{tractogram_and_transformation}
process Recognize_Bundles {
cpus params.rbx_processes
input:
set sid, file(tractogram), file(transfo), file(config), file(directory) from tractogram_and_transformation
output:
set sid, "*.trk" into bundles_for_cleaning
file "results.json"
file "logfile.txt"
script:
"""
mkdir tmp/
scil_recognize_multi_bundles.py ${tractogram} ${config} ${directory}/*/ ${transfo} --inverse --output tmp/ \
--log_level DEBUG --multi_parameters $params.multi_parameters --minimal_vote_ratio $params.minimal_vote_ratio \
--tractogram_clustering_thr $params.wb_clustering_thr --seeds $params.seeds --processes $params.rbx_processes
mv tmp/* ./
"""
}

bundles_for_cleaning
.transpose()
.set{all_bundles_for_cleaning}
process Clean_Bundles {
input:
set sid, file(bundle) from all_bundles_for_cleaning
output:
file "${sid}__*_cleaned.trk"
script:
bname = bundle.name.take(bundle.name.lastIndexOf('.'))
"""
scil_outlier_rejection.py ${bundle} "${sid}__${bname}_cleaned.trk" --alpha $params.outlier_alpha
"""
}
41 changes: 41 additions & 0 deletions nextflow.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
process {
publishDir = {"./results_rbx/$sid/$task.process"}
scratch = true
stageInMode = 'copy'
stageOutMode = 'rsync'
tag = { "$sid" }
afterScript = 'sleep 1'
}

params {
help=false
root=false
atlas_centroids=false
atlas_directory=false
atlas_anat=false
atlas_config=false

//**Recobundle segmentation**//
multi_parameters=18
minimal_vote_ratio=0.5
wb_clustering_thr="15 12"
seeds="0"
outlier_alpha=0.5

//**Number of processes per tasks**//
register_processes=4
rbx_processes=4
}

singularity.autoMounts = true

profiles {
fully_reproducible {
params.register_processes=1
params.rbx_processes=1
}

macos {
process.scratch="/tmp"
}
}

0 comments on commit bb81603

Please sign in to comment.