Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 49 additions & 6 deletions subworkflows/nf-scil/registration/main.nf
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
include { REGISTRATION_ANATTODWI } from '../../../modules/nf-scil/registration/anattodwi/main'
include { REGISTRATION_ANTS } from '../../../modules/nf-scil/registration/ants/main'
include { REGISTRATION_EASYREG } from '../../../modules/nf-scil/registration/easyreg/main'

params.run_surgery = false

workflow REGISTRATION {

// ** The subworkflow requires at least ch_image and ch_ref as inputs to ** //
// ** The subworkflow requires at least ch_image and ch_ref as inputs to ** //
// ** properly perform the registration. Supplying a ch_metric will select ** //
// ** the REGISTRATION_ANATTODWI module meanwhile NOT supplying a ch_metric ** //
// ** will select the REGISTRATION_ANTS (SyN or SyNQuick) module. ** //
// ** the REGISTRATION_ANATTODWI module meanwhile NOT supplying a ch_metric ** //
// ** will select the REGISTRATION_ANTS (SyN or SyNQuick) module. Alternatively, ** //
// ** NOT supplying ch_metric and activating run_surgery flag with select REGISTRATION_EASYREG ** //

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
ch_segmentation // channel: [ val(meta), [ flo_segmentation ] ], optional
ch_ref_segmentation // channel: [ val(meta), [ ref_segmentation ] ], optional


main:

image_warped = Channel.empty()
ref_warped = Channel.empty()
transfo_image = Channel.empty()
transfo_trk = Channel.empty()
out_segmentation = Channel.empty()
out_ref_segmentation = Channel.empty()

ch_versions = Channel.empty()

if ( ch_metric ) {
Expand All @@ -31,6 +45,31 @@ workflow REGISTRATION {
image_warped = REGISTRATION_ANATTODWI.out.t1_warped
transfo_image = REGISTRATION_ANATTODWI.out.transfo_image
transfo_trk = REGISTRATION_ANATTODWI.out.transfo_trk
}
else if ( params.run_surgery ) {
// ** Set up input channel ** //
ch_register = ch_ref.combine(ch_image, by: 0)
.combine(ch_ref_segmentation, by: 0)
.combine(ch_segmentation, by: 0)

// ** Registration using Easyreg ** //
REGISTRATION_EASYREG ( ch_register )
ch_versions = ch_versions.mix(REGISTRATION_EASYREG.out.versions.first())

// ** Setting outputs ** //
image_warped = REGISTRATION_EASYREG.out.flo_reg
transfo_image = REGISTRATION_EASYREG.out.fwd_field
.map{ it + [[]] }
transfo_trk = REGISTRATION_EASYREG.out.bak_field
.map{ [[]] + it }
ref_warped - REGISTRATION_EASYREG.out.ref_reg

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what this line is doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you referring to ".map{ [[]] + it } or ref_warped output declaration?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact it is not a = but a -. So I think you have a bug here.


// ** Setting optional outputs. If segmentations are not provided as inputs, ** //
// ** easyreg will outputs synthseg segmentations ** //
out_segmentation = ch_segmentation ? Channel.empty() : REGISTRATION_EASYREG.out.flo_seg
out_ref_segmentation = ch_ref_segmentation ? Channel.empty() : REGISTRATION_EASYREG.out.ref_seg


}
else {
// ** Set up input channel, input are inverted compared to REGISTRATION_ANATTODWI. ** //
Expand All @@ -56,9 +95,13 @@ workflow REGISTRATION {
}

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 ] ]
image_warped = image_warped // channel: [ val(meta), [ image ] ]
ref_warped = ref_warped // channel: [ val(meta), [ ref ] ]
transfo_image = transfo_image // channel: [ val(meta), [ warp, affine ] ]
transfo_trk = transfo_trk // channel: [ val(meta), [ inverseAffine, inverseWarp ] ]
segmentation = out_segmentation // channel: [ val(meta), [ segmentation ] ]
ref_segmentation = out_ref_segmentation // channel: [ val(meta), [ ref_segmentation ] ]


versions = ch_versions // channel: [ versions.yml ]
}
37 changes: 36 additions & 1 deletion subworkflows/nf-scil/registration/meta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ 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:
perform registration. Three 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.
3) alternatively, if the run_synth parameter is activated, the subworkflow will use the REGISTRATION_EASYREG module
calling mri_easyreg.
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
Expand All @@ -18,6 +20,7 @@ keywords:
- Anatomical
components:
- registration/anattodwi
- registration/easyreg
- registration/ants
input:
- ch_image:
Expand Down Expand Up @@ -50,13 +53,35 @@ input:
REGISTRATION_ANTS, see the description section above for more details.
Structure: [ val(meta), path(mask) ]
pattern: "*.{nii,nii.gz}"
- ch_segmentation:
type: file
description: |
The input channel containing the the SynthSeg v2 (non-robust) segmentation + parcellation of the moving (floating in Easyreg naming convention) image.
If it does not exist, Easyreg will create it. If it already exists (e.g., from a previous EasyReg run),
then EasyReg will read it from disk (which is faster than segmenting).
pattern: "*.{nii,nii.gz}"
- ch_ref_segmentation:
type: file
description: |
The input channel containing the SynthSeg v2 (non-robust) segmentation + parcellation of the fixed (reference in Easyreg naming convention) image.
If it does not exist, Easyreg will create it. If it already exists (e.g., from a previous EasyReg run),
then EasyReg will read it from disk (which is faster than segmenting).
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}"
- ref_warped:
type: file
description: |
Channel containing warped reference 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: |
Expand All @@ -73,6 +98,16 @@ output:
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}"
- out_segmentation:
type: file
description: |
Channel containing the file with the SynthSeg v2 (non-robust) segmentation + parcellation of the moving (floating in Easyreg naming convention) image.
pattern: "*.{nii,nii.gz}"
- out_ref_segmentation:
type: file
description: |
Channel containing the file with the SynthSeg v2 (non-robust) segmentation + parcellation of the fixed (reference in Easyreg naming convention) image.
pattern: "*.{nii,nii.gz}"
- versions:
type: file
description: |
Expand Down
61 changes: 57 additions & 4 deletions subworkflows/nf-scil/registration/tests/main.nf.test
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ nextflow_workflow {
name "Test Subworkflow REGISTRATION"
script "../main.nf"
workflow "REGISTRATION"
config "./nextflow.config"

tag "subworkflows"
tag "subworkflows_nfcore"
Expand All @@ -13,6 +12,7 @@ nextflow_workflow {
tag "registration/anattodwi"
tag "registration"
tag "registration/ants"
tag "registration/easyreg"

tag "load_test_data"

Expand All @@ -29,7 +29,7 @@ nextflow_workflow {
}

test("registration - antsRegistration") {

config "./nextflow.config"
when {
workflow {
"""
Expand All @@ -49,20 +49,63 @@ nextflow_workflow {
file("\${test_data_directory}/fa.nii.gz")
]}
input[3] = []
input[4] = []
input[5] = []
"""
}
}

then {
assertAll(
{ assert workflow.success},
{ assert snapshot(workflow.out).match()}
{ assert snapshot(
niftiMD5SUM(workflow.out.image_warped.get(0).get(1)),
workflow.out.transfo_image,
workflow.out.transfo_trk,
workflow.out.versions
).match()}
)
}
}

test("registration - SyNQuick") {
config "./nextflow.config"
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] = []
input[4] = []
input[5] = []
"""
}
}

then {
assertAll(
{ assert workflow.success},
{ assert snapshot(
niftiMD5SUM(workflow.out.image_warped.get(0).get(1)),
workflow.out.transfo_image,
workflow.out.transfo_trk,
workflow.out.versions
).match()}
)
}
}

test("registration - surgery") {
config "./nextflow_surgery.config"
when {
workflow {
"""
Expand All @@ -78,14 +121,24 @@ nextflow_workflow {
]}
input[2] = []
input[3] = []
input[4] = []
input[5] = []
"""
}
}

then {
assertAll(
{ assert workflow.success},
{ assert snapshot(workflow.out).match()}
{ assert snapshot(
niftiMD5SUM(workflow.out.image_warped.get(0).get(1)),
niftiMD5SUM(workflow.out.ref_warped.get(0).get(1)),
workflow.out.transfo_image,
workflow.out.transfo_trk,
niftiMD5SUM(workflow.out.segmentation.get(0).get(1)),
niftiMD5SUM(workflow.out.ref_segmentation.get(0).get(1)),
workflow.out.versions
).match()}
)
}
}
Expand Down
Loading