Skip to content

Commit

Permalink
Merge pull request scilus#115 from gagnonanthony/registrationworkflow
Browse files Browse the repository at this point in the history
[Subworkflow] Registration subworkflow.
  • Loading branch information
AlexVCaron authored Apr 18, 2024
2 parents 7dcce60 + 4b4adbc commit 7fb9c3a
Show file tree
Hide file tree
Showing 6 changed files with 414 additions and 0 deletions.
65 changes: 65 additions & 0 deletions subworkflows/nf-scil/registration/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
include { REGISTER_ANATTODWI } from '../../../modules/nf-scil/register/anattodwi/main'
include { REGISTRATION_ANTS } from '../../../modules/nf-scil/registration/ants/main'

workflow REGISTRATION {

// ** The subworkflow requires at least ch_image and ch_ref as inputs to ** //
// ** properly perform the registration. Supplying a ch_metric will select ** //
// ** the REGISTER_ANATTODWI module meanwhile NOT supplying a ch_metric ** //
// ** will select the REGISTRATION_ANTS (SyN or SyNQuick) module. ** //

take:
ch_image // channel: [ val(meta), [ image ] ]
ch_ref // channel: [ val(meta), [ ref ] ]
ch_metric // channel: [ val(meta), [ metric ] ], optional
ch_mask // channel: [ val(meta), [ mask ] ], optional

main:

ch_versions = Channel.empty()

if ( ch_metric ) {
// ** Set up input channel ** //
ch_register = ch_image.combine(ch_ref, by: 0)
.combine(ch_metric, by: 0)

// ** Registration using AntsRegistration ** //
REGISTER_ANATTODWI ( ch_register )
ch_versions = ch_versions.mix(REGISTER_ANATTODWI.out.versions.first())

// ** Setting outputs ** //
image_warped = REGISTER_ANATTODWI.out.t1_warped
transfo_image = REGISTER_ANATTODWI.out.transfo_image
transfo_trk = REGISTER_ANATTODWI.out.transfo_trk
}
else {
// ** Set up input channel, input are inverted compared to REGISTER_ANATTODWI. ** //
if ( ch_mask ) {
ch_register = ch_ref.combine(ch_image, by: 0)
.combine(ch_mask, by: 0)
}
else {
ch_register = ch_ref.combine(ch_image, by: 0)
.map{ it + [[]] }
}

// ** Registration using antsRegistrationSyN.sh or antsRegistrationSyNQuick.sh. ** //
// ** Has to be defined in the config file or else the default (SyN) will be ** //
// ** used. ** //
REGISTRATION_ANTS ( ch_register )
ch_versions = ch_versions.mix(REGISTRATION_ANTS.out.versions.first())

// ** Setting outputs ** //
image_warped = REGISTRATION_ANTS.out.image
transfo_image = REGISTRATION_ANTS.out.transfo_image
transfo_trk = REGISTRATION_ANTS.out.transfo_trk
}

emit:
image_warped = image_warped // channel: [ val(meta), [ image ] ]
transfo_image = transfo_image // channel: [ val(meta), [ warp, affine ] ]
transfo_trk = transfo_trk // channel: [ val(meta), [ inverseAffine, inverseWarp ] ]

versions = ch_versions // channel: [ versions.yml ]
}

83 changes: 83 additions & 0 deletions subworkflows/nf-scil/registration/meta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: "registration"
description: |
Subworkflow to perform registration between a moving and a fixed image (e.g. T1 -> DWI).
It requires as input at least a moving (ch_image) and a reference (ch_ref) image to properly
perform registration. Two modes are available:
1) if a metric file is supplied (ch_metric), the subworkflow will use the REGISTER_ANATTODWI
module calling AntsRegistration, with the metric as additional target.
2) if NO metric file is supplied, the subworkflow will use the REGISTRATION_ANTS module calling
antsRegistrationSyN.sh or antsRegistrationSyNQuick.sh.
This subworkflow outputs transformation files that can be used with the ANTSAPPLYTRANSFORMS module
to warp any new image. Simply provide your moving image, reference image, and transformations files
to the module to register a new image in the current space. Similar steps can be used to register
bundles/tractograms using the BUNDLEREGISTRATION module.
keywords:
- Registration
- Transformation
- DWI
- Anatomical
components:
- register/anattodwi
- registration/ants
input:
- ch_image:
type: file
description: |
The input channel containing the moving image files. Typically your anatomical image to be
registered to dwi space.
Structure: [ val(meta), path(image) ]
pattern: "*.{nii,nii.gz}"
- ch_ref:
type: file
description: |
The input channel containing the fixed image files. Typically a reference image from the dwi
space (e.g. b0 image, etc.).
Structure: [ val(meta), path(ref) ]
pattern: "*.{nii,nii.gz}"
- ch_metric:
type: file
description: |
The input channel containing the metric files. Supplying this channel will make the subworkflow
use the module REGISTER_ANATTODWI calling AntsRegistration using the moving, reference and metric
image. For a T1 -> DWI registration, this is typically a FA map.
Structure: [ val(meta), path(metric) ]
pattern: "*.{nii,nii.gz}"
- ch_mask:
type: file
description: |
The input channel containing the mask files. Supplying this channel only affect the subworkflow
if the ch_metric is NOT supplied. This channel is only being used if the module called is
REGISTRATION_ANTS, see the description section above for more details.
Structure: [ val(meta), path(mask) ]
pattern: "*.{nii,nii.gz}"
output:
- image_warped:
type: file
description: |
Channel containing warped moving images. Typically, this would be the warped T1 in DWI space.
Structure: [ val(meta), path(image) ]
pattern: "*.{nii,nii.gz}"
- transfo_image:
type: file
description: |
Channel containing the image transformation files. This channel contains the necessary transformation
files (warp and affine) to perform the anatomical -> dwi space registration. Those files could be
used in the future to bring anatomical labels into DWI space for connectomics.
Structure: [ val(meta), [ path(warp), path(affine) ] ]
pattern: "*.{nii,nii.gz,mat}"
- transfo_trk:
type: file
description: |
Channel containing the tractogram transformation files. This channel contains the necessary transformation
files (inverseAffine, inverseWarp) to perform the dwi -> anatomical space registration. Those files could
be used to register tractograms or bundle in the subject's anatomical space.
Structure: [ val(meta), [ path(inverseAffine), path(inverseWarp) ]
pattern: "*.{nii,nii.gz,mat}"
- versions:
type: file
description: |
File containing software versions used.
Structure: [ path(versions.yml) ]
pattern: "versions.yml"
authors:
- "@gagnonanthony"
92 changes: 92 additions & 0 deletions subworkflows/nf-scil/registration/tests/main.nf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
nextflow_workflow {

name "Test Subworkflow REGISTRATION"
script "../main.nf"
workflow "REGISTRATION"
config "./nextflow.config"

tag "subworkflows"
tag "subworkflows_nfcore"
tag "subworkflows/registration"

tag "register"
tag "register/anattodwi"
tag "registration"
tag "registration/ants"

tag "load_test_data"

setup {
run("LOAD_TEST_DATA", alias: "LOAD_DATA") {
script "../../load_test_data/main.nf"
process {
"""
input[0] = Channel.from( [ "processing.zip" ] )
input[1] = "test.load-test-data"
"""
}
}
}

test("registration - antsRegistration") {

when {
workflow {
"""
input[0] = LOAD_DATA.out.test_data_directory.map{
test_data_directory -> [
[ id:'test', single_end:false ],
file("\${test_data_directory}/mni_masked_2x2x2.nii.gz")
]}
input[1] = LOAD_DATA.out.test_data_directory.map{
test_data_directory -> [
[ id:'test', single_end:false ],
file("\${test_data_directory}/b0_mean.nii.gz")
]}
input[2] = LOAD_DATA.out.test_data_directory.map{
test_data_directory -> [
[ id:'test', single_end:false ],
file("\${test_data_directory}/fa.nii.gz")
]}
input[3] = []
"""
}
}

then {
assertAll(
{ assert workflow.success},
{ assert snapshot(workflow.out).match()}
)
}
}

test("registration - SyNQuick") {

when {
workflow {
"""
input[0] = LOAD_DATA.out.test_data_directory.map{
test_data_directory -> [
[ id:'test', single_end:false ],
file("\${test_data_directory}/mni_masked_2x2x2.nii.gz")
]}
input[1] = LOAD_DATA.out.test_data_directory.map{
test_data_directory -> [
[ id:'test', single_end:false ],
file("\${test_data_directory}/b0_mean.nii.gz")
]}
input[2] = []
input[3] = []
"""
}
}

then {
assertAll(
{ assert workflow.success},
{ assert snapshot(workflow.out).match()}
)
}
}
}
Loading

0 comments on commit 7fb9c3a

Please sign in to comment.