diff --git a/modules/nf-neuro/image/applymask/main.nf b/modules/nf-neuro/image/applymask/main.nf index c5604110..aaee32bd 100644 --- a/modules/nf-neuro/image/applymask/main.nf +++ b/modules/nf-neuro/image/applymask/main.nf @@ -16,12 +16,14 @@ process IMAGE_APPLYMASK { script: def prefix = task.ext.prefix ?: "${meta.id}" + def suffix = task.ext.first_suffix ? task.ext.first_suffix + "_masked" : "masked" def nthreads_mrtrix = task.ext.single_thread ? "-nthreads 0" : "-nthreads ${task.cpus}" + def data_type = task.ext.data_type ? "-datatype ${task.ext.data_type}" : "-datatype float32" """ export OMP_NUM_THREADS=${task.ext.single_thread ? 1 : task.cpus} - mrcalc $image $mask -mult ${prefix}_masked.nii.gz -force -quiet ${nthreads_mrtrix} + mrcalc $image $mask -mult ${prefix}_${suffix}.nii.gz -force -quiet ${nthreads_mrtrix} ${data_type} cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -31,9 +33,9 @@ process IMAGE_APPLYMASK { stub: def prefix = task.ext.prefix ?: "${meta.id}" - + def suffix = task.ext.first_suffix ? task.ext.first_suffix + "_masked" : "masked" """ - touch ${prefix}_masked.nii.gz + touch ${prefix}_${suffix}.nii.gz mrcalc -h diff --git a/modules/nf-neuro/image/applymask/meta.yml b/modules/nf-neuro/image/applymask/meta.yml index 4a39a89c..fec98b23 100644 --- a/modules/nf-neuro/image/applymask/meta.yml +++ b/modules/nf-neuro/image/applymask/meta.yml @@ -32,10 +32,20 @@ input: ontologies: - edam: http://edamontology.org/format_3989 # GZIP format args: + - first_suffix: + type: string + description: Suffix for the output image file. This will be used as the first part of the suffix, followed by "_masked". + default: "" - single_thread: type: boolean description: If true, the command will be run in single-threaded mode. By default, the command will use multiple threads based on the number of CPUs allocated to the task. default: false + - data_type: + type: string + description: | + Data type for the output image. Use the following format: + uint8, int16, int32, int64, float16, float32 or float64. + default: "float32" output: image: - - meta: diff --git a/modules/nf-neuro/registration/anattodwi/main.nf b/modules/nf-neuro/registration/anattodwi/main.nf index 0e136738..dd919abd 100644 --- a/modules/nf-neuro/registration/anattodwi/main.nf +++ b/modules/nf-neuro/registration/anattodwi/main.nf @@ -5,10 +5,11 @@ process REGISTRATION_ANATTODWI { container "scilus/scilus:2.2.2" input: - tuple val(meta), path(fixed_reference), path(moving_anat), path(metric) + tuple val(meta), path(fixed_reference), path(moving_anat), path(metric), path(fixed_mask), path(moving_mask) output: tuple val(meta), path("*_warped.nii.gz") , emit: anat_warped + tuple val(meta), path("*_warped_reference.nii.gz") , emit: fixed_warped tuple val(meta), path("*_forward1_affine.mat") , emit: forward_affine tuple val(meta), path("*_forward0_warp.nii.gz") , emit: forward_warp tuple val(meta), path("*_backward1_warp.nii.gz") , emit: backward_warp @@ -25,15 +26,18 @@ process REGISTRATION_ANATTODWI { script: def prefix = task.ext.prefix ?: "${meta.id}" + def suffix = task.ext.suffix ? "${task.ext.suffix}_warped" : "warped" def run_qc = task.ext.run_qc as Boolean || false + def args = task.ext.args ?: '' + if (( task.ext.masking_strategy == "both" || task.ext.masking_strategy == "internal" ) && (fixed_mask || moving_mask)) args += " -x \"${fixed_mask ?: 'NULL'},${moving_mask ?: 'NULL'}\"" """ export ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=${task.ext.single_thread ? 1 : task.cpus} export OMP_NUM_THREADS=${task.ext.single_thread ? 1 : task.cpus} export ANTS_RANDOM_SEED=${task.ext.ants_rng_seed ? task.ext.ants_rng_seed : "1234"} antsRegistration --dimensionality 3 --float 0\ - --output [forward,warped.nii.gz]\ + --output [forward,warped.nii.gz,InverseWarped.nii.gz]\ --interpolation Linear --use-histogram-matching 0\ --winsorize-image-intensities [0.005,0.995]\ --initial-moving-transform [$fixed_reference,$moving_anat,1]\ @@ -49,14 +53,16 @@ process REGISTRATION_ANATTODWI { --metric MI[$fixed_reference,$moving_anat,1,32]\ --metric CC[$metric,$moving_anat,1,4]\ --convergence [50x25x10,1e-6,10] --shrink-factors 4x2x1\ - --smoothing-sigmas 3x2x1 + --smoothing-sigmas 3x2x1\ + $args - moving_base=\$(basename "${moving_anat}") + moving_base=\$(basename $moving_anat .nii.gz) ext=\${moving_base#*.} moving_id=\${moving_base%.\${ext}} moving_id=\${moving_id#${prefix}_*} - mv warped.nii.gz ${prefix}_\${moving_id}_warped.nii.gz + mv warped.nii.gz ${prefix}_\${moving_id}_${suffix}.nii.gz + mv InverseWarped.nii.gz ${prefix}_warped_reference.nii.gz mv forward0GenericAffine.mat ${prefix}_forward1_affine.mat mv forward1Warp.nii.gz ${prefix}_forward0_warp.nii.gz mv forward1InverseWarp.nii.gz ${prefix}_backward1_warp.nii.gz @@ -67,7 +73,7 @@ process REGISTRATION_ANATTODWI { ### ** QC ** ### if $run_qc; then # Extract dimensions. - dim=\$(mrinfo ${prefix}_\${moving_id}_warped.nii.gz -size) + dim=\$(mrinfo ${prefix}_\${moving_id}_${suffix}.nii.gz -size) read sagittal_dim coronal_dim axial_dim <<< "\${dim}" # Get middle slices. @@ -83,7 +89,7 @@ process REGISTRATION_ANATTODWI { fixed_id=\${fixed_id#${prefix}_*} # Iterate over images. - for image in \${moving_id}_warped \${fixed_id}; do + for image in \${moving_id}_${suffix} \${fixed_id}; do mrconvert *\${image}.nii.gz \${image}_viz.nii.gz -stride -1,2,3 scil_viz_volume_screenshot \${image}_viz.nii.gz \${image}_coronal.png \ --slices \$coronal_mid --axis coronal \$viz_params @@ -109,11 +115,11 @@ process REGISTRATION_ANATTODWI { # Create GIF. convert -delay 10 -loop 0 -morph 10 \ - \${moving_id}_warped_mosaic.png \${fixed_id}_mosaic.png \${moving_id}_warped_mosaic.png \ + \${moving_id}_${suffix}_mosaic.png \${fixed_id}_mosaic.png \${moving_id}_${suffix}_mosaic.png \ ${prefix}_registration_anattodwi_mqc.gif # Clean up. - rm \${moving_id}_warped_mosaic.png \${fixed_id}_mosaic.png + rm \${moving_id}_${suffix}_mosaic.png \${fixed_id}_mosaic.png fi cat <<-END_VERSIONS > versions.yml @@ -128,7 +134,7 @@ process REGISTRATION_ANATTODWI { stub: def prefix = task.ext.prefix ?: "${meta.id}" def run_qc = task.ext.run_qc as Boolean || false - + def suffix = task.ext.suffix ? "${task.ext.suffix}_warped" : "warped" """ antsRegistration -h antsApplyTransforms -h @@ -136,10 +142,13 @@ process REGISTRATION_ANATTODWI { scil_viz_volume_screenshot -h convert -help . - moving_id=\$(basename $moving_anat .nii.gz) + moving_base=\$(basename $moving_anat .nii.gz) + ext=\${moving_base#*.} + moving_id=\${moving_base%.\${ext}} moving_id=\${moving_id#${prefix}_*} - touch ${prefix}_\${moving_id}_warped.nii.gz + touch ${prefix}_\${moving_id}_${suffix}.nii.gz + touch ${prefix}_warped_reference.nii.gz touch ${prefix}_forward1_affine.mat touch ${prefix}_forward0_warp.nii.gz touch ${prefix}_backward1_warp.nii.gz diff --git a/modules/nf-neuro/registration/anattodwi/meta.yml b/modules/nf-neuro/registration/anattodwi/meta.yml index eba51fcc..92afa732 100644 --- a/modules/nf-neuro/registration/anattodwi/meta.yml +++ b/modules/nf-neuro/registration/anattodwi/meta.yml @@ -43,6 +43,15 @@ args: type: integer description: Random seed for ANTs registration. Setting a fixed seed can help with reproducibility of results. default: 1234 + - masking_strategy: + type: string + choices: + - none + - apriori + - internal + - both + description: Masking strategy to use for registration. Options are 'none', 'apriori', 'internal' or 'both'. + default: "none" input: - - meta: type: map @@ -70,6 +79,20 @@ input: mandatory: true ontologies: - edam: http://edamontology.org/format_4001 # NIFTI format + - fixed_mask: + type: file + description: Fixed image mask + pattern: "*.{nii,nii.gz}" + mandatory: false + ontologies: + - edam: http://edamontology.org/format_4001 # NIFTI format + - moving_mask: + type: file + description: Moving image mask + pattern: "*.{nii,nii.gz}" + mandatory: false + ontologies: + - edam: http://edamontology.org/format_4001 # NIFTI format output: anat_warped: - - meta: @@ -83,6 +106,18 @@ output: pattern: "*_warped.nii.gz" ontologies: - edam: http://edamontology.org/format_4001 # NIFTI format + fixed_warped: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - "*_warped_reference.nii.gz": + type: file + description: B0 warped to T1 space + pattern: "*_warped_reference.nii.gz" + ontologies: + - edam: http://edamontology.org/format_4001 # NIFTI format forward_affine: - - meta: type: map diff --git a/modules/nf-neuro/registration/anattodwi/tests/main.nf.test b/modules/nf-neuro/registration/anattodwi/tests/main.nf.test index fb85ca46..65279e9d 100644 --- a/modules/nf-neuro/registration/anattodwi/tests/main.nf.test +++ b/modules/nf-neuro/registration/anattodwi/tests/main.nf.test @@ -56,6 +56,59 @@ nextflow_process { input[0] = ch_b0 .join(ch_t1w) .join(ch_fa) + .map{ meta, fixed, moving, fixed_metric -> [meta, fixed, moving, fixed_metric, [], []] } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("registration - anattodwi - fixed mask") { + config "./nextflow.config" + when { + process { + """ + ch_split_test_data = LOAD_DATA.out.test_data_directory + .branch{ + t1w: it.simpleName == "T1w" + b0: it.simpleName == "b0" + dti: it.simpleName == "dti" + } + ch_t1w = ch_split_test_data.t1w.map{ + test_data_directory -> [ + [ id:'test', single_end:false ], + file("\${test_data_directory}/T1w.nii.gz") + ] + } + ch_b0 = ch_split_test_data.b0.map{ + test_data_directory -> [ + [ id:'test', single_end:false ], + file("\${test_data_directory}/b0.nii.gz") + ] + } + ch_fa = ch_split_test_data.dti.map{ + test_data_directory -> [ + [ id:'test', single_end:false ], + file("\${test_data_directory}/fa.nii.gz") + ] + } + ch_fixed_mask = ch_split_test_data.t1w.map{ + test_data_directory -> [ + [ id:'test', single_end:false ], + file("\${test_data_directory}/T1w_mask.nii.gz") + ] + } + input[0] = ch_b0 + .join(ch_t1w) + .join(ch_fa) + .join(ch_fixed_mask) + .map{ meta, fixed, moving, fixed_metric, fixed_mask -> [meta, fixed, moving, fixed_metric, fixed_mask, []] } """ } } @@ -101,6 +154,7 @@ nextflow_process { input[0] = ch_b0 .join(ch_t1w) .join(ch_fa) + .map{ meta, fixed, moving, fixed_metric -> [meta, fixed, moving, fixed_metric, [], []] } """ } } diff --git a/modules/nf-neuro/registration/anattodwi/tests/main.nf.test.snap b/modules/nf-neuro/registration/anattodwi/tests/main.nf.test.snap index 395e9958..0c7183cd 100644 --- a/modules/nf-neuro/registration/anattodwi/tests/main.nf.test.snap +++ b/modules/nf-neuro/registration/anattodwi/tests/main.nf.test.snap @@ -17,10 +17,19 @@ "id": "test", "single_end": false }, - "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" + "test_warped_reference.nii.gz:md5,f6969de8c75d8e4a5a6d264c3ac50ab1" ] ], "10": [ + [ + { + "id": "test", + "single_end": false + }, + "test_registration_anattodwi_mqc.gif:md5,9cbc1ce8755821996dae18080cf0a23c" + ] + ], + "11": [ "versions.yml:md5,37249bcc3b9ecbaf310960d876fd802d" ], "2": [ @@ -29,7 +38,7 @@ "id": "test", "single_end": false }, - "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693" + "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" ] ], "3": [ @@ -38,7 +47,7 @@ "id": "test", "single_end": false }, - "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" + "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693" ] ], "4": [ @@ -47,7 +56,7 @@ "id": "test", "single_end": false }, - "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9" + "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" ] ], "5": [ @@ -56,10 +65,7 @@ "id": "test", "single_end": false }, - [ - "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693", - "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" - ] + "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9" ] ], "6": [ @@ -69,8 +75,8 @@ "single_end": false }, [ - "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9", - "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" + "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693", + "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" ] ] ], @@ -93,8 +99,8 @@ "single_end": false }, [ - "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693", - "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" + "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9", + "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" ] ] ], @@ -104,7 +110,10 @@ "id": "test", "single_end": false }, - "test_registration_anattodwi_mqc.gif:md5,9cbc1ce8755821996dae18080cf0a23c" + [ + "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693", + "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" + ] ] ], "anat_warped": [ @@ -158,6 +167,15 @@ "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" ] ], + "fixed_warped": [ + [ + { + "id": "test", + "single_end": false + }, + "test_warped_reference.nii.gz:md5,f6969de8c75d8e4a5a6d264c3ac50ab1" + ] + ], "forward_affine": [ [ { @@ -218,7 +236,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-05-02T12:00:04.565708322" + "timestamp": "2026-07-13T17:10:55.4552583" }, "registration - anattodwi -stub-run": { "content": [ @@ -231,5 +249,244 @@ "nextflow": "25.10.2" }, "timestamp": "2026-02-26T22:30:03.859914189" + }, + "registration - anattodwi - fixed mask": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test_T1w_warped.nii.gz:md5,9f2eda1485017da83b5fcd6871cdcb74" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test_warped_reference.nii.gz:md5,f6969de8c75d8e4a5a6d264c3ac50ab1" + ] + ], + "10": [ + [ + { + "id": "test", + "single_end": false + }, + "test_registration_anattodwi_mqc.gif:md5,9cbc1ce8755821996dae18080cf0a23c" + ] + ], + "11": [ + "versions.yml:md5,37249bcc3b9ecbaf310960d876fd802d" + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" + ] + ], + "5": [ + [ + { + "id": "test", + "single_end": false + }, + "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9" + ] + ], + "6": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693", + "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" + ] + ] + ], + "7": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9", + "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" + ] + ] + ], + "8": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9", + "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" + ] + ] + ], + "9": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693", + "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" + ] + ] + ], + "anat_warped": [ + [ + { + "id": "test", + "single_end": false + }, + "test_T1w_warped.nii.gz:md5,9f2eda1485017da83b5fcd6871cdcb74" + ] + ], + "backward_affine": [ + [ + { + "id": "test", + "single_end": false + }, + "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9" + ] + ], + "backward_image_transform": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9", + "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" + ] + ] + ], + "backward_tractogram_transform": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693", + "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" + ] + ] + ], + "backward_warp": [ + [ + { + "id": "test", + "single_end": false + }, + "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" + ] + ], + "fixed_warped": [ + [ + { + "id": "test", + "single_end": false + }, + "test_warped_reference.nii.gz:md5,f6969de8c75d8e4a5a6d264c3ac50ab1" + ] + ], + "forward_affine": [ + [ + { + "id": "test", + "single_end": false + }, + "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" + ] + ], + "forward_image_transform": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693", + "test_forward1_affine.mat:md5,984ac5023aca49f513af811d0f1e3e89" + ] + ] + ], + "forward_tractogram_transform": [ + [ + { + "id": "test", + "single_end": false + }, + [ + "test_backward0_affine.mat:md5,177325d18b5a5fa457bd3a2e052463d9", + "test_backward1_warp.nii.gz:md5,4ea6f41a8246f3cb0b1ad39c94028c1f" + ] + ] + ], + "forward_warp": [ + [ + { + "id": "test", + "single_end": false + }, + "test_forward0_warp.nii.gz:md5,464d7b291ab9c9aaead7ecbfec6a6693" + ] + ], + "mqc": [ + [ + { + "id": "test", + "single_end": false + }, + "test_registration_anattodwi_mqc.gif:md5,9cbc1ce8755821996dae18080cf0a23c" + ] + ], + "versions": [ + "versions.yml:md5,37249bcc3b9ecbaf310960d876fd802d" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-07-13T10:04:42.169706966" } } \ No newline at end of file diff --git a/modules/nf-neuro/registration/anattodwi/tests/nextflow.config b/modules/nf-neuro/registration/anattodwi/tests/nextflow.config index 68043db3..19215bf7 100644 --- a/modules/nf-neuro/registration/anattodwi/tests/nextflow.config +++ b/modules/nf-neuro/registration/anattodwi/tests/nextflow.config @@ -2,5 +2,6 @@ process { withName: "REGISTRATION_ANATTODWI" { ext.cpus = 1 ext.run_qc = true + ext.masking_strategy = "internal" } } diff --git a/modules/nf-neuro/registration/ants/main.nf b/modules/nf-neuro/registration/ants/main.nf index 611d412e..437af490 100644 --- a/modules/nf-neuro/registration/ants/main.nf +++ b/modules/nf-neuro/registration/ants/main.nf @@ -6,10 +6,11 @@ process REGISTRATION_ANTS { container "scilus/scilus:2.2.2" input: - tuple val(meta), path(fixed_image), path(moving_image), path(fixed_mask), path(moving_mask) //** optional, input = [] **// + tuple val(meta), path(fixed_image), path(moving_image), path(fixed_mask), path(moving_mask) output: tuple val(meta), path("*_warped.nii.gz") , emit: image_warped + tuple val(meta), path("*_warped_reference.nii.gz") , emit: fixed_warped tuple val(meta), path("*_forward1_affine.mat") , emit: forward_affine, optional: true tuple val(meta), path("*_forward0_warp.nii.gz") , emit: forward_warp, optional: true tuple val(meta), path("*_backward1_warp.nii.gz") , emit: backward_warp, optional: true @@ -18,8 +19,8 @@ process REGISTRATION_ANTS { tuple val(meta), path("*_backward*.{nii.gz,mat}", arity: '1..2') , emit: backward_image_transform tuple val(meta), path("*_backward*.{nii.gz,mat}", arity: '1..2') , emit: forward_tractogram_transform tuple val(meta), path("*_forward*.{nii.gz,mat}", arity: '1..2') , emit: backward_tractogram_transform - tuple val(meta), path("*_registration_ants_mqc.gif") , emit: mqc, optional: true - path "versions.yml" , emit: versions + tuple val(meta), path("*_registration_ants_mqc.gif") , emit: mqc, optional: true + path "versions.yml" , emit: versions when: task.ext.when == null || task.ext.when @@ -37,10 +38,6 @@ process REGISTRATION_ANTS { def nthreads = task.ext.single_thread ? 1 : task.cpus args += " -n $nthreads" - if ( fixed_mask || moving_mask ) { - args += " -x \"${fixed_mask ?: 'NULL'},${moving_mask ?: 'NULL'}\"" - } - if ( task.ext.initial_transform ) args += " -i [$fixed_image,$moving_image,${initialization_types[task.ext.initial_transform]}]" if ( task.ext.histogram_bins ) args += " -r $task.ext.histogram_bins" if ( task.ext.spline_distance ) args += " -s $task.ext.spline_distance" @@ -49,6 +46,7 @@ process REGISTRATION_ANTS { if ( task.ext.histogram_matching ) args += " -j $task.ext.histogram_matching" if ( task.ext.repro_mode ) args += " -y $task.ext.repro_mode" if ( task.ext.collapse_output ) args += " -z $task.ext.collapse_output" + if ( (task.ext.masking_strategy == "both" || task.ext.masking_strategy == "internal") && (fixed_mask || moving_mask) ) args += " -x \"${fixed_mask ?: 'NULL'},${moving_mask ?: 'NULL'}\"" """ export ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=${task.ext.single_thread ? 1 : task.cpus} @@ -63,6 +61,7 @@ process REGISTRATION_ANTS { moving_id=\${moving_id#${prefix}_*} mv outputWarped.nii.gz ${prefix}_\${moving_id}_${suffix}.nii.gz + mv outputInverseWarped.nii.gz ${prefix}_warped_reference.nii.gz if [ $transform != "bo" ] && [ $transform != "so" ]; then mv output0GenericAffine.mat ${prefix}_forward1_affine.mat @@ -156,16 +155,17 @@ process REGISTRATION_ANTS { antsRegistrationSyNQuick.sh -h } - antsApplyTransforms -h - convert -help . - scil_viz_volume_screenshot -h - moving_base=\$(basename "${moving_image}") ext=\${moving_base#*.} moving_id=\${moving_base%.\${ext}} moving_id=\${moving_id#${prefix}_*} + antsApplyTransforms -h + convert -help . + scil_viz_volume_screenshot -h + touch ${prefix}_\${moving_id}_${suffix}.nii.gz + touch ${prefix}_warped_reference.nii.gz touch ${prefix}_forward1_affine.mat touch ${prefix}_forward0_warp.nii.gz touch ${prefix}_backward1_warp.nii.gz diff --git a/modules/nf-neuro/registration/ants/meta.yml b/modules/nf-neuro/registration/ants/meta.yml index 8b8f5755..ba9e6363 100644 --- a/modules/nf-neuro/registration/ants/meta.yml +++ b/modules/nf-neuro/registration/ants/meta.yml @@ -131,6 +131,15 @@ args: type: boolean description: If true, the command will be run in single-threaded mode. By default, the command will use multiple threads based on the number of CPUs allocated to the task. default: false + - masking_strategy: + type: string + choices: + - none + - apriori + - internal + - both + description: Masking strategy to use for registration. Options are 'none', 'apriori', 'internal' or 'both'. + default: "none" input: - - meta: type: map @@ -153,14 +162,14 @@ input: - edam: http://edamontology.org/format_4001 # NIFTI format - fixed_mask: type: file - description: Mask(s) for the fixed image space + description: Fixed image mask pattern: "*.{nii,nii.gz}" mandatory: false ontologies: - edam: http://edamontology.org/format_4001 # NIFTI format - moving_mask: type: file - description: Mask(s) for the moving image space + description: Moving image mask pattern: "*.{nii,nii.gz}" mandatory: false ontologies: @@ -178,6 +187,18 @@ output: pattern: "*_warped.nii.gz" ontologies: - edam: http://edamontology.org/format_3989 # GZIP format + fixed_warped: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - "*_warped_reference.nii.gz": + type: file + description: Reference warped to moving space. + pattern: "*_warped_reference.nii.gz" + ontologies: + - edam: http://edamontology.org/format_3989 # GZIP format forward_affine: - - meta: type: map diff --git a/modules/nf-neuro/registration/ants/tests/main.nf.test b/modules/nf-neuro/registration/ants/tests/main.nf.test index f11029fb..a8b8370f 100644 --- a/modules/nf-neuro/registration/ants/tests/main.nf.test +++ b/modules/nf-neuro/registration/ants/tests/main.nf.test @@ -46,16 +46,45 @@ nextflow_process { file("\${test_data_directory}/t1.nii.gz") ] } - ch_T1w_mask = ch_split_test_data.T1w.map{ + input[0] = ch_T1w + .join(ch_moving) + .map{ meta, fixed, moving -> [meta, fixed, moving, [], []] } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("registration - ants - SyN quick") { + config "./nextflow_quick.config" + when { + process { + """ + ch_split_test_data = LOAD_DATA.out.test_data_directory + .branch{ + T1w: it.simpleName == "T1w" + moving: it.simpleName == "others" + } + ch_T1w = ch_split_test_data.T1w.map{ test_data_directory -> [ [ id:'test' ], - file("\${test_data_directory}/T1w_mask.nii.gz") + file("\${test_data_directory}/T1w.nii.gz") + ] + } + ch_moving = ch_split_test_data.moving.map{ + test_data_directory -> [ + [ id:'test' ], + file("\${test_data_directory}/t1.nii.gz") ] } input[0] = ch_T1w .join(ch_moving) - .join(ch_T1w_mask) - .map{ meta, T1w, t1, T1w_mask -> [meta, T1w, t1, T1w_mask, []] } + .map{ meta, fixed, moving -> [meta, fixed, moving, [], []] } """ } } @@ -67,8 +96,8 @@ nextflow_process { } } - test("registration - ants - SyN quick") { - config "./nextflow_quick.config" + test("registration - ants - no warps") { + config "./nextflow_no_warp.config" when { process { """ @@ -89,16 +118,52 @@ nextflow_process { file("\${test_data_directory}/t1.nii.gz") ] } - ch_T1w_mask = ch_split_test_data.T1w.map{ + input[0] = ch_T1w + .join(ch_moving) + .map{ meta, fixed, moving -> [meta, fixed, moving, [], []] } + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("registration - ants - both - moving mask") { + config "./nextflow_both_moving_mask.config" + when { + process { + """ + ch_split_test_data = LOAD_DATA.out.test_data_directory + .branch{ + T1w: it.simpleName == "T1w" + moving: it.simpleName == "others" + } + ch_fixed = ch_split_test_data.moving.map{ + test_data_directory -> [ + [ id:'test' ], + file("\${test_data_directory}/t1.nii.gz") + ] + } + ch_moving = ch_split_test_data.T1w.map{ + test_data_directory -> [ + [ id:'test' ], + file("\${test_data_directory}/T1w.nii.gz") + ] + } + ch_moving_mask = ch_split_test_data.T1w.map{ test_data_directory -> [ [ id:'test' ], file("\${test_data_directory}/T1w_mask.nii.gz") ] } - input[0] = ch_T1w + input[0] = ch_fixed .join(ch_moving) - .join(ch_T1w_mask) - .map{ meta, T1w, t1, T1w_mask -> [meta, T1w, t1, T1w_mask, []] } + .join(ch_moving_mask) + .map{ meta, fixed, moving, moving_mask -> [meta, fixed, moving, [], moving_mask] } """ } } @@ -110,8 +175,8 @@ nextflow_process { } } - test("registration - ants - no warps") { - config "./nextflow_no_warp.config" + test("registration - ants - both - fixed mask") { + config "./nextflow_both_moving_mask.config" when { process { """ @@ -132,7 +197,7 @@ nextflow_process { file("\${test_data_directory}/t1.nii.gz") ] } - ch_T1w_mask = ch_split_test_data.T1w.map{ + ch_fixed_mask = ch_split_test_data.T1w.map{ test_data_directory -> [ [ id:'test' ], file("\${test_data_directory}/T1w_mask.nii.gz") @@ -140,8 +205,8 @@ nextflow_process { } input[0] = ch_T1w .join(ch_moving) - .join(ch_T1w_mask) - .map{ meta, T1w, t1, T1w_mask -> [meta, T1w, t1, T1w_mask, []] } + .join(ch_fixed_mask) + .map{ meta, fixed, moving, fixed_mask -> [meta, fixed, moving, fixed_mask, []] } """ } } @@ -176,16 +241,9 @@ nextflow_process { file("\${test_data_directory}/t1.nii.gz") ] } - ch_T1w_mask = ch_split_test_data.T1w.map{ - test_data_directory -> [ - [ id:'test' ], - file("\${test_data_directory}/T1w_mask.nii.gz") - ] - } input[0] = ch_T1w .join(ch_moving) - .join(ch_T1w_mask) - .map{ meta, T1w, t1, T1w_mask -> [meta, T1w, t1, T1w_mask, []] } + .map{ meta, fixed, moving -> [meta, fixed, moving, [], []] } """ } } diff --git a/modules/nf-neuro/registration/ants/tests/main.nf.test.snap b/modules/nf-neuro/registration/ants/tests/main.nf.test.snap index a439947c..27b7c59e 100644 --- a/modules/nf-neuro/registration/ants/tests/main.nf.test.snap +++ b/modules/nf-neuro/registration/ants/tests/main.nf.test.snap @@ -1,4 +1,221 @@ { + "registration - ants - both - moving mask": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test_T1w_warped.nii.gz:md5,f815f83fcc5ad70b0b6630b9e57835c8" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test_warped_reference.nii.gz:md5,aecd2a8b83026219078af73aaa0fdeb7" + ] + ], + "10": [ + [ + { + "id": "test" + }, + "test_T1_to_T1_slab_registration_ants_mqc.gif:md5,6cb6f9efc4910087b32943da4f579ee4" + ] + ], + "11": [ + "versions.yml:md5,0b121e44c28b1c3efb04ae0dfc9ec76c" + ], + "2": [ + [ + { + "id": "test" + }, + "test_forward1_affine.mat:md5,3bc315e13074f374dda32e29e13f201a" + ] + ], + "3": [ + [ + { + "id": "test" + }, + "test_forward0_warp.nii.gz:md5,384082f9f4c14f3235abc5d572dc8336" + ] + ], + "4": [ + [ + { + "id": "test" + }, + "test_backward1_warp.nii.gz:md5,06e37e91eb8b489cb41e8f8501e9ecc8" + ] + ], + "5": [ + [ + { + "id": "test" + }, + "test_backward0_affine.mat:md5,9344bac7ae2d83e4e45367377bc37455" + ] + ], + "6": [ + [ + { + "id": "test" + }, + [ + "test_forward0_warp.nii.gz:md5,384082f9f4c14f3235abc5d572dc8336", + "test_forward1_affine.mat:md5,3bc315e13074f374dda32e29e13f201a" + ] + ] + ], + "7": [ + [ + { + "id": "test" + }, + [ + "test_backward0_affine.mat:md5,9344bac7ae2d83e4e45367377bc37455", + "test_backward1_warp.nii.gz:md5,06e37e91eb8b489cb41e8f8501e9ecc8" + ] + ] + ], + "8": [ + [ + { + "id": "test" + }, + [ + "test_backward0_affine.mat:md5,9344bac7ae2d83e4e45367377bc37455", + "test_backward1_warp.nii.gz:md5,06e37e91eb8b489cb41e8f8501e9ecc8" + ] + ] + ], + "9": [ + [ + { + "id": "test" + }, + [ + "test_forward0_warp.nii.gz:md5,384082f9f4c14f3235abc5d572dc8336", + "test_forward1_affine.mat:md5,3bc315e13074f374dda32e29e13f201a" + ] + ] + ], + "backward_affine": [ + [ + { + "id": "test" + }, + "test_backward0_affine.mat:md5,9344bac7ae2d83e4e45367377bc37455" + ] + ], + "backward_image_transform": [ + [ + { + "id": "test" + }, + [ + "test_backward0_affine.mat:md5,9344bac7ae2d83e4e45367377bc37455", + "test_backward1_warp.nii.gz:md5,06e37e91eb8b489cb41e8f8501e9ecc8" + ] + ] + ], + "backward_tractogram_transform": [ + [ + { + "id": "test" + }, + [ + "test_forward0_warp.nii.gz:md5,384082f9f4c14f3235abc5d572dc8336", + "test_forward1_affine.mat:md5,3bc315e13074f374dda32e29e13f201a" + ] + ] + ], + "backward_warp": [ + [ + { + "id": "test" + }, + "test_backward1_warp.nii.gz:md5,06e37e91eb8b489cb41e8f8501e9ecc8" + ] + ], + "fixed_warped": [ + [ + { + "id": "test" + }, + "test_warped_reference.nii.gz:md5,aecd2a8b83026219078af73aaa0fdeb7" + ] + ], + "forward_affine": [ + [ + { + "id": "test" + }, + "test_forward1_affine.mat:md5,3bc315e13074f374dda32e29e13f201a" + ] + ], + "forward_image_transform": [ + [ + { + "id": "test" + }, + [ + "test_forward0_warp.nii.gz:md5,384082f9f4c14f3235abc5d572dc8336", + "test_forward1_affine.mat:md5,3bc315e13074f374dda32e29e13f201a" + ] + ] + ], + "forward_tractogram_transform": [ + [ + { + "id": "test" + }, + [ + "test_backward0_affine.mat:md5,9344bac7ae2d83e4e45367377bc37455", + "test_backward1_warp.nii.gz:md5,06e37e91eb8b489cb41e8f8501e9ecc8" + ] + ] + ], + "forward_warp": [ + [ + { + "id": "test" + }, + "test_forward0_warp.nii.gz:md5,384082f9f4c14f3235abc5d572dc8336" + ] + ], + "image_warped": [ + [ + { + "id": "test" + }, + "test_T1w_warped.nii.gz:md5,f815f83fcc5ad70b0b6630b9e57835c8" + ] + ], + "mqc": [ + [ + { + "id": "test" + }, + "test_T1_to_T1_slab_registration_ants_mqc.gif:md5,6cb6f9efc4910087b32943da4f579ee4" + ] + ], + "versions": [ + "versions.yml:md5,0b121e44c28b1c3efb04ae0dfc9ec76c" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-07-13T09:01:12.623392808" + }, "registration - ants - stub": { "content": [ [ @@ -9,7 +226,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-02-26T22:31:18.974318044" + "timestamp": "2026-07-13T11:47:17.039146496" }, "registration - ants - SyN quick": { "content": [ @@ -19,7 +236,7 @@ { "id": "test" }, - "test_t1_warped.nii.gz:md5,8089d84a4f511207f26307ce92353bbb" + "test_t1_warped.nii.gz:md5,c74eb8a596f1f6959f8db828d0d9ddc1" ] ], "1": [ @@ -27,10 +244,18 @@ { "id": "test" }, - "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + "test_warped_reference.nii.gz:md5,3cbad0d0163e9bd59b3f6b865e464ffb" ] ], "10": [ + [ + { + "id": "test" + }, + "test_T1_to_T1_slab_registration_ants_mqc.gif:md5,b685aa586e6b61196b442740c1056eb5" + ] + ], + "11": [ "versions.yml:md5,0b121e44c28b1c3efb04ae0dfc9ec76c" ], "2": [ @@ -38,7 +263,7 @@ { "id": "test" }, - "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d" + "test_forward1_affine.mat:md5,41afa6fa72a013820a3d3d8ce4986002" ] ], "3": [ @@ -46,7 +271,7 @@ { "id": "test" }, - "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + "test_forward0_warp.nii.gz:md5,806c26fdf31077d4b035a2009db54c95" ] ], "4": [ @@ -54,7 +279,7 @@ { "id": "test" }, - "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95" + "test_backward1_warp.nii.gz:md5,4cca843970b2ed3d02ecf43a31502857" ] ], "5": [ @@ -62,10 +287,7 @@ { "id": "test" }, - [ - "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d", - "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" - ] + "test_backward0_affine.mat:md5,9b6845301aaeaf43a1cf9da4e4cb671f" ] ], "6": [ @@ -74,8 +296,8 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95", - "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + "test_forward0_warp.nii.gz:md5,806c26fdf31077d4b035a2009db54c95", + "test_forward1_affine.mat:md5,41afa6fa72a013820a3d3d8ce4986002" ] ] ], @@ -85,8 +307,8 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95", - "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + "test_backward0_affine.mat:md5,9b6845301aaeaf43a1cf9da4e4cb671f", + "test_backward1_warp.nii.gz:md5,4cca843970b2ed3d02ecf43a31502857" ] ] ], @@ -96,8 +318,8 @@ "id": "test" }, [ - "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d", - "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + "test_backward0_affine.mat:md5,9b6845301aaeaf43a1cf9da4e4cb671f", + "test_backward1_warp.nii.gz:md5,4cca843970b2ed3d02ecf43a31502857" ] ] ], @@ -106,7 +328,10 @@ { "id": "test" }, - "test_T1_to_T1_slab_registration_ants_mqc.gif:md5,fba29c34dd2cebde98e9c72e5c991550" + [ + "test_forward0_warp.nii.gz:md5,806c26fdf31077d4b035a2009db54c95", + "test_forward1_affine.mat:md5,41afa6fa72a013820a3d3d8ce4986002" + ] ] ], "backward_affine": [ @@ -114,7 +339,7 @@ { "id": "test" }, - "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95" + "test_backward0_affine.mat:md5,9b6845301aaeaf43a1cf9da4e4cb671f" ] ], "backward_image_transform": [ @@ -123,8 +348,8 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95", - "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + "test_backward0_affine.mat:md5,9b6845301aaeaf43a1cf9da4e4cb671f", + "test_backward1_warp.nii.gz:md5,4cca843970b2ed3d02ecf43a31502857" ] ] ], @@ -134,8 +359,8 @@ "id": "test" }, [ - "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d", - "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + "test_forward0_warp.nii.gz:md5,806c26fdf31077d4b035a2009db54c95", + "test_forward1_affine.mat:md5,41afa6fa72a013820a3d3d8ce4986002" ] ] ], @@ -144,7 +369,15 @@ { "id": "test" }, - "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + "test_backward1_warp.nii.gz:md5,4cca843970b2ed3d02ecf43a31502857" + ] + ], + "fixed_warped": [ + [ + { + "id": "test" + }, + "test_warped_reference.nii.gz:md5,3cbad0d0163e9bd59b3f6b865e464ffb" ] ], "forward_affine": [ @@ -152,7 +385,7 @@ { "id": "test" }, - "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + "test_forward1_affine.mat:md5,41afa6fa72a013820a3d3d8ce4986002" ] ], "forward_image_transform": [ @@ -161,8 +394,8 @@ "id": "test" }, [ - "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d", - "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + "test_forward0_warp.nii.gz:md5,806c26fdf31077d4b035a2009db54c95", + "test_forward1_affine.mat:md5,41afa6fa72a013820a3d3d8ce4986002" ] ] ], @@ -172,8 +405,8 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95", - "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + "test_backward0_affine.mat:md5,9b6845301aaeaf43a1cf9da4e4cb671f", + "test_backward1_warp.nii.gz:md5,4cca843970b2ed3d02ecf43a31502857" ] ] ], @@ -182,7 +415,7 @@ { "id": "test" }, - "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d" + "test_forward0_warp.nii.gz:md5,806c26fdf31077d4b035a2009db54c95" ] ], "image_warped": [ @@ -190,7 +423,7 @@ { "id": "test" }, - "test_t1_warped.nii.gz:md5,8089d84a4f511207f26307ce92353bbb" + "test_t1_warped.nii.gz:md5,c74eb8a596f1f6959f8db828d0d9ddc1" ] ], "mqc": [ @@ -198,7 +431,7 @@ { "id": "test" }, - "test_T1_to_T1_slab_registration_ants_mqc.gif:md5,fba29c34dd2cebde98e9c72e5c991550" + "test_T1_to_T1_slab_registration_ants_mqc.gif:md5,b685aa586e6b61196b442740c1056eb5" ] ], "versions": [ @@ -210,7 +443,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-06-03T22:41:08.268383497" + "timestamp": "2026-07-13T08:57:44.546094663" }, "registration - ants - SyN": { "content": [ @@ -220,7 +453,7 @@ { "id": "test" }, - "test_t1_warped.nii.gz:md5,02ff01272aadd0acca8672c444678a7b" + "test_t1_warped.nii.gz:md5,7c5756d1bdcf72eac1541e9c5d98f9db" ] ], "1": [ @@ -228,10 +461,13 @@ { "id": "test" }, - "test_forward1_affine.mat:md5,872eb964ad5deaeea7f492924b404cb8" + "test_warped_reference.nii.gz:md5,8d9d3bd39214d9b4fd0cedfc2458d093" ] ], "10": [ + + ], + "11": [ "versions.yml:md5,0b121e44c28b1c3efb04ae0dfc9ec76c" ], "2": [ @@ -239,7 +475,7 @@ { "id": "test" }, - "test_forward0_warp.nii.gz:md5,439c1de9d275d39a203e2806ada000c7" + "test_forward1_affine.mat:md5,0fb5879b315f32bb8e06aa2993009115" ] ], "3": [ @@ -247,7 +483,7 @@ { "id": "test" }, - "test_backward1_warp.nii.gz:md5,cd5d6021085ac029614fa525ceaf9847" + "test_forward0_warp.nii.gz:md5,a32206a00e93b79054e9b8fa0f7c8015" ] ], "4": [ @@ -255,7 +491,7 @@ { "id": "test" }, - "test_backward0_affine.mat:md5,e92fa10025dc221232530b0b23f9ed4b" + "test_backward1_warp.nii.gz:md5,4e85fa2257f7364fde205adfa1b3c8d3" ] ], "5": [ @@ -263,10 +499,7 @@ { "id": "test" }, - [ - "test_forward0_warp.nii.gz:md5,439c1de9d275d39a203e2806ada000c7", - "test_forward1_affine.mat:md5,872eb964ad5deaeea7f492924b404cb8" - ] + "test_backward0_affine.mat:md5,ff00be1483698e5478bfa94abf2b42b2" ] ], "6": [ @@ -275,8 +508,8 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,e92fa10025dc221232530b0b23f9ed4b", - "test_backward1_warp.nii.gz:md5,cd5d6021085ac029614fa525ceaf9847" + "test_forward0_warp.nii.gz:md5,a32206a00e93b79054e9b8fa0f7c8015", + "test_forward1_affine.mat:md5,0fb5879b315f32bb8e06aa2993009115" ] ] ], @@ -286,8 +519,8 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,e92fa10025dc221232530b0b23f9ed4b", - "test_backward1_warp.nii.gz:md5,cd5d6021085ac029614fa525ceaf9847" + "test_backward0_affine.mat:md5,ff00be1483698e5478bfa94abf2b42b2", + "test_backward1_warp.nii.gz:md5,4e85fa2257f7364fde205adfa1b3c8d3" ] ] ], @@ -297,20 +530,28 @@ "id": "test" }, [ - "test_forward0_warp.nii.gz:md5,439c1de9d275d39a203e2806ada000c7", - "test_forward1_affine.mat:md5,872eb964ad5deaeea7f492924b404cb8" + "test_backward0_affine.mat:md5,ff00be1483698e5478bfa94abf2b42b2", + "test_backward1_warp.nii.gz:md5,4e85fa2257f7364fde205adfa1b3c8d3" ] ] ], "9": [ - + [ + { + "id": "test" + }, + [ + "test_forward0_warp.nii.gz:md5,a32206a00e93b79054e9b8fa0f7c8015", + "test_forward1_affine.mat:md5,0fb5879b315f32bb8e06aa2993009115" + ] + ] ], "backward_affine": [ [ { "id": "test" }, - "test_backward0_affine.mat:md5,e92fa10025dc221232530b0b23f9ed4b" + "test_backward0_affine.mat:md5,ff00be1483698e5478bfa94abf2b42b2" ] ], "backward_image_transform": [ @@ -319,8 +560,8 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,e92fa10025dc221232530b0b23f9ed4b", - "test_backward1_warp.nii.gz:md5,cd5d6021085ac029614fa525ceaf9847" + "test_backward0_affine.mat:md5,ff00be1483698e5478bfa94abf2b42b2", + "test_backward1_warp.nii.gz:md5,4e85fa2257f7364fde205adfa1b3c8d3" ] ] ], @@ -330,8 +571,8 @@ "id": "test" }, [ - "test_forward0_warp.nii.gz:md5,439c1de9d275d39a203e2806ada000c7", - "test_forward1_affine.mat:md5,872eb964ad5deaeea7f492924b404cb8" + "test_forward0_warp.nii.gz:md5,a32206a00e93b79054e9b8fa0f7c8015", + "test_forward1_affine.mat:md5,0fb5879b315f32bb8e06aa2993009115" ] ] ], @@ -340,7 +581,15 @@ { "id": "test" }, - "test_backward1_warp.nii.gz:md5,cd5d6021085ac029614fa525ceaf9847" + "test_backward1_warp.nii.gz:md5,4e85fa2257f7364fde205adfa1b3c8d3" + ] + ], + "fixed_warped": [ + [ + { + "id": "test" + }, + "test_warped_reference.nii.gz:md5,8d9d3bd39214d9b4fd0cedfc2458d093" ] ], "forward_affine": [ @@ -348,7 +597,7 @@ { "id": "test" }, - "test_forward1_affine.mat:md5,872eb964ad5deaeea7f492924b404cb8" + "test_forward1_affine.mat:md5,0fb5879b315f32bb8e06aa2993009115" ] ], "forward_image_transform": [ @@ -357,8 +606,8 @@ "id": "test" }, [ - "test_forward0_warp.nii.gz:md5,439c1de9d275d39a203e2806ada000c7", - "test_forward1_affine.mat:md5,872eb964ad5deaeea7f492924b404cb8" + "test_forward0_warp.nii.gz:md5,a32206a00e93b79054e9b8fa0f7c8015", + "test_forward1_affine.mat:md5,0fb5879b315f32bb8e06aa2993009115" ] ] ], @@ -368,8 +617,8 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,e92fa10025dc221232530b0b23f9ed4b", - "test_backward1_warp.nii.gz:md5,cd5d6021085ac029614fa525ceaf9847" + "test_backward0_affine.mat:md5,ff00be1483698e5478bfa94abf2b42b2", + "test_backward1_warp.nii.gz:md5,4e85fa2257f7364fde205adfa1b3c8d3" ] ] ], @@ -378,7 +627,7 @@ { "id": "test" }, - "test_forward0_warp.nii.gz:md5,439c1de9d275d39a203e2806ada000c7" + "test_forward0_warp.nii.gz:md5,a32206a00e93b79054e9b8fa0f7c8015" ] ], "image_warped": [ @@ -386,7 +635,7 @@ { "id": "test" }, - "test_t1_warped.nii.gz:md5,02ff01272aadd0acca8672c444678a7b" + "test_t1_warped.nii.gz:md5,7c5756d1bdcf72eac1541e9c5d98f9db" ] ], "mqc": [ @@ -401,9 +650,9 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-06-04T09:14:11.394213705" + "timestamp": "2026-07-13T08:56:23.888876135" }, - "registration - ants - no warps": { + "registration - ants - both - fixed mask": { "content": [ { "0": [ @@ -411,7 +660,7 @@ { "id": "test" }, - "test_t1_warped.nii.gz:md5,938a3906d8d2ca9f500ab34c25b5dae7" + "test_t1_warped.nii.gz:md5,8089d84a4f511207f26307ce92353bbb" ] ], "1": [ @@ -419,43 +668,261 @@ { "id": "test" }, - "test_forward1_affine.mat:md5,562def074e1973a35b5e16bd8b1515d9" + "test_warped_reference.nii.gz:md5,e29b6d5f67b52afa7ab5b6ae90afd375" ] ], "10": [ + [ + { + "id": "test" + }, + "test_T1_to_T1_slab_registration_ants_mqc.gif:md5,fba29c34dd2cebde98e9c72e5c991550" + ] + ], + "11": [ "versions.yml:md5,0b121e44c28b1c3efb04ae0dfc9ec76c" ], "2": [ - + [ + { + "id": "test" + }, + "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + ] ], "3": [ - + [ + { + "id": "test" + }, + "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d" + ] ], "4": [ [ { "id": "test" }, - "test_backward0_affine.mat:md5,44b80fe9baf645d16299395959793d65" + "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" ] ], "5": [ + [ + { + "id": "test" + }, + "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95" + ] + ], + "6": [ + [ + { + "id": "test" + }, + [ + "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d", + "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + ] + ] + ], + "7": [ + [ + { + "id": "test" + }, + [ + "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95", + "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + ] + ] + ], + "8": [ + [ + { + "id": "test" + }, + [ + "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95", + "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + ] + ] + ], + "9": [ + [ + { + "id": "test" + }, + [ + "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d", + "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + ] + ] + ], + "backward_affine": [ + [ + { + "id": "test" + }, + "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95" + ] + ], + "backward_image_transform": [ + [ + { + "id": "test" + }, + [ + "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95", + "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + ] + ] + ], + "backward_tractogram_transform": [ + [ + { + "id": "test" + }, + [ + "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d", + "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + ] + ] + ], + "backward_warp": [ + [ + { + "id": "test" + }, + "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + ] + ], + "fixed_warped": [ + [ + { + "id": "test" + }, + "test_warped_reference.nii.gz:md5,e29b6d5f67b52afa7ab5b6ae90afd375" + ] + ], + "forward_affine": [ + [ + { + "id": "test" + }, + "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" + ] + ], + "forward_image_transform": [ [ { "id": "test" }, [ - "test_forward1_affine.mat:md5,562def074e1973a35b5e16bd8b1515d9" + "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d", + "test_forward1_affine.mat:md5,18c2ec8b5cf3fb4e038cce665eb53e7c" ] ] ], + "forward_tractogram_transform": [ + [ + { + "id": "test" + }, + [ + "test_backward0_affine.mat:md5,ba4cdd24110970c8d08b8df39ee4fd95", + "test_backward1_warp.nii.gz:md5,e5324ab5af8cceda46e0bb642dfc02aa" + ] + ] + ], + "forward_warp": [ + [ + { + "id": "test" + }, + "test_forward0_warp.nii.gz:md5,d1f0ce951610683042aab377c665295d" + ] + ], + "image_warped": [ + [ + { + "id": "test" + }, + "test_t1_warped.nii.gz:md5,8089d84a4f511207f26307ce92353bbb" + ] + ], + "mqc": [ + [ + { + "id": "test" + }, + "test_T1_to_T1_slab_registration_ants_mqc.gif:md5,fba29c34dd2cebde98e9c72e5c991550" + ] + ], + "versions": [ + "versions.yml:md5,0b121e44c28b1c3efb04ae0dfc9ec76c" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-07-13T09:02:40.930435009" + }, + "registration - ants - no warps": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test_t1_warped.nii.gz:md5,9f4d57c0e9cde3da4ab4718f360abce6" + ] + ], + "1": [ + [ + { + "id": "test" + }, + "test_warped_reference.nii.gz:md5,0636f939cf940ac053f86286797c0982" + ] + ], + "10": [ + + ], + "11": [ + "versions.yml:md5,0b121e44c28b1c3efb04ae0dfc9ec76c" + ], + "2": [ + [ + { + "id": "test" + }, + "test_forward1_affine.mat:md5,72aee9284d5e624be5dbc15cfce8151c" + ] + ], + "3": [ + + ], + "4": [ + + ], + "5": [ + [ + { + "id": "test" + }, + "test_backward0_affine.mat:md5,862976c1966b1af64acd7b40d0f922e4" + ] + ], "6": [ [ { "id": "test" }, [ - "test_backward0_affine.mat:md5,44b80fe9baf645d16299395959793d65" + "test_forward1_affine.mat:md5,72aee9284d5e624be5dbc15cfce8151c" ] ] ], @@ -465,7 +932,7 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,44b80fe9baf645d16299395959793d65" + "test_backward0_affine.mat:md5,862976c1966b1af64acd7b40d0f922e4" ] ] ], @@ -475,19 +942,26 @@ "id": "test" }, [ - "test_forward1_affine.mat:md5,562def074e1973a35b5e16bd8b1515d9" + "test_backward0_affine.mat:md5,862976c1966b1af64acd7b40d0f922e4" ] ] ], "9": [ - + [ + { + "id": "test" + }, + [ + "test_forward1_affine.mat:md5,72aee9284d5e624be5dbc15cfce8151c" + ] + ] ], "backward_affine": [ [ { "id": "test" }, - "test_backward0_affine.mat:md5,44b80fe9baf645d16299395959793d65" + "test_backward0_affine.mat:md5,862976c1966b1af64acd7b40d0f922e4" ] ], "backward_image_transform": [ @@ -496,7 +970,7 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,44b80fe9baf645d16299395959793d65" + "test_backward0_affine.mat:md5,862976c1966b1af64acd7b40d0f922e4" ] ] ], @@ -506,19 +980,27 @@ "id": "test" }, [ - "test_forward1_affine.mat:md5,562def074e1973a35b5e16bd8b1515d9" + "test_forward1_affine.mat:md5,72aee9284d5e624be5dbc15cfce8151c" ] ] ], "backward_warp": [ + ], + "fixed_warped": [ + [ + { + "id": "test" + }, + "test_warped_reference.nii.gz:md5,0636f939cf940ac053f86286797c0982" + ] ], "forward_affine": [ [ { "id": "test" }, - "test_forward1_affine.mat:md5,562def074e1973a35b5e16bd8b1515d9" + "test_forward1_affine.mat:md5,72aee9284d5e624be5dbc15cfce8151c" ] ], "forward_image_transform": [ @@ -527,7 +1009,7 @@ "id": "test" }, [ - "test_forward1_affine.mat:md5,562def074e1973a35b5e16bd8b1515d9" + "test_forward1_affine.mat:md5,72aee9284d5e624be5dbc15cfce8151c" ] ] ], @@ -537,7 +1019,7 @@ "id": "test" }, [ - "test_backward0_affine.mat:md5,44b80fe9baf645d16299395959793d65" + "test_backward0_affine.mat:md5,862976c1966b1af64acd7b40d0f922e4" ] ] ], @@ -549,7 +1031,7 @@ { "id": "test" }, - "test_t1_warped.nii.gz:md5,938a3906d8d2ca9f500ab34c25b5dae7" + "test_t1_warped.nii.gz:md5,9f4d57c0e9cde3da4ab4718f360abce6" ] ], "mqc": [ @@ -564,6 +1046,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-06-03T22:41:19.541042931" + "timestamp": "2026-07-13T08:58:13.291148166" } } \ No newline at end of file diff --git a/modules/nf-neuro/registration/ants/tests/nextflow_both_moving_mask.config b/modules/nf-neuro/registration/ants/tests/nextflow_both_moving_mask.config new file mode 100644 index 00000000..aed85d5b --- /dev/null +++ b/modules/nf-neuro/registration/ants/tests/nextflow_both_moving_mask.config @@ -0,0 +1,9 @@ +process { + withName: "REGISTRATION_ANTS" { + publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } + ext.quick = true + ext.run_qc = true + ext.suffix_qc = "T1_to_T1_slab" + ext.masking_strategy = "both" + } +} diff --git a/modules/nf-neuro/registration/easyreg/main.nf b/modules/nf-neuro/registration/easyreg/main.nf index c6cc5815..ad83b6cc 100644 --- a/modules/nf-neuro/registration/easyreg/main.nf +++ b/modules/nf-neuro/registration/easyreg/main.nf @@ -30,9 +30,14 @@ process REGISTRATION_EASYREG { """ export OMP_NUM_THREADS=${task.ext.single_thread ? 1 : task.cpus} + moving_base=\$(basename "${moving_image}") + ext=\${moving_base#*.} + moving_id=\${moving_base%.\${ext}} + moving_id=\${moving_id#${prefix}_*} + mri_easyreg --ref $fixed_image \ --flo $moving_image \ - --flo_reg ${prefix}_warped.nii.gz \ + --flo_reg ${prefix}_\${moving_id}_warped.nii.gz \ --ref_reg ${prefix}_warped_reference.nii.gz \ --fwd_field ${prefix}_forward0_warp.nii.gz \ --bak_field ${prefix}_backward0_warp.nii.gz \ @@ -51,7 +56,12 @@ process REGISTRATION_EASYREG { """ mri_easyreg -h - touch ${prefix}_warped.nii.gz + moving_base=\$(basename "${moving_image}") + ext=\${moving_base#*.} + moving_id=\${moving_base%.\${ext}} + moving_id=\${moving_id#${prefix}_*} + + touch ${prefix}_\${moving_id}_warped.nii.gz touch ${prefix}_warped_reference.nii.gz touch ${prefix}_warped_segmentation.nii.gz touch ${prefix}_warped_reference_segmentation.nii.gz diff --git a/modules/nf-neuro/registration/easyreg/tests/main.nf.test.snap b/modules/nf-neuro/registration/easyreg/tests/main.nf.test.snap index d9c53e2f..6fd2f38f 100644 --- a/modules/nf-neuro/registration/easyreg/tests/main.nf.test.snap +++ b/modules/nf-neuro/registration/easyreg/tests/main.nf.test.snap @@ -4,7 +4,7 @@ "test_warped_reference_segmentation.nii.gz", "test_warped_segmentation.nii.gz", "test_warped_reference.nii.gz:md5:header,c5e41f89848f91c53a9a7be44970d4b1,data,1501221fe23cd62bfdafb33367cadf4d", - "test_warped.nii.gz:md5:header,ec5893cd9ea024e630c4444bd914c331,data,d75ae3fc935cd5cc70ea6797a4c70775", + "test_b0_warped.nii.gz:md5:header,ec5893cd9ea024e630c4444bd914c331,data,d75ae3fc935cd5cc70ea6797a4c70775", "test_forward0_warp.nii.gz:md5:header,0db0a80786ff39864cc17506ed1a0146,data,e4fa6c626729cbf236c34680e5c76df4", "test_backward0_warp.nii.gz:md5:header,74c92ee4cd3c4abfecf3da6cdb1d4650,data,8f26afa5c3de21469466213498542486", [ @@ -12,10 +12,10 @@ ] ], "meta": { - "nf-test": "0.9.0", - "nextflow": "25.04.8" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-16T15:11:21.026914183" + "timestamp": "2026-07-13T10:18:12.32065037" }, "registration - easyreg - stub-run": { "content": [ diff --git a/modules/nf-neuro/registration/synthmorph/main.nf b/modules/nf-neuro/registration/synthmorph/main.nf index 72573dc1..4333d90f 100644 --- a/modules/nf-neuro/registration/synthmorph/main.nf +++ b/modules/nf-neuro/registration/synthmorph/main.nf @@ -10,6 +10,7 @@ process REGISTRATION_SYNTHMORPH { output: tuple val(meta), path("*_warped.nii.gz") , emit: image_warped + tuple val(meta), path("*_warped_reference.nii.gz") , emit: fixed_warped tuple val(meta), path("*_forward{0,1,_standalone}_affine.lta") , emit: forward_affine, optional: true tuple val(meta), path("*_forward0_deform.nii.gz") , emit: forward_warp, optional: true tuple val(meta), path("*_backward1_deform.nii.gz") , emit: backward_warp, optional: true @@ -39,6 +40,11 @@ process REGISTRATION_SYNTHMORPH { export OMP_NUM_THREADS=${task.ext.single_thread ? 1 : task.cpus} export CUDA_VISIBLE_DEVICES="-1" + moving_base=\$(basename "${moving_image}") + ext=\${moving_base#*.} + moving_id=\${moving_base%.\${ext}} + moving_id=\${moving_id#${prefix}_*} + echo "Available memory : ${task.memory}" moving=$moving_image @@ -91,7 +97,9 @@ process REGISTRATION_SYNTHMORPH { mri_synthmorph register \$moving fixed.nii.gz -v -m \$model \$weight \$args \ -t ${prefix}_forward\${j}_\$model.\${extension[\$model]} \ -T ${prefix}_backward\${i}_\$model.\${extension[\$model]} \ - -o warped.nii.gz -j ${nthreads} $extent $use_gpu + -o warped.nii.gz \ + -O fixed_warped.nii.gz \ + -j ${nthreads} $extent $use_gpu if [ \$initializer ]; then # Retag initializer file to standalone using sed @@ -112,7 +120,8 @@ process REGISTRATION_SYNTHMORPH { done - mv warped.nii.gz ${prefix}_warped.nii.gz + mv warped.nii.gz ${prefix}_\${moving_id}_warped.nii.gz + mv fixed_warped.nii.gz ${prefix}_warped_reference.nii.gz cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -126,7 +135,13 @@ process REGISTRATION_SYNTHMORPH { """ mri_synthmorph -h - touch ${prefix}_warped.nii.gz + moving_base=\$(basename "${moving_image}") + ext=\${moving_base#*.} + moving_id=\${moving_base%.\${ext}} + moving_id=\${moving_id#${prefix}_*} + + touch ${prefix}_\${moving_id}_warped.nii.gz + touch ${prefix}_warped_reference.nii.gz touch ${prefix}_forward1_affine.lta touch ${prefix}_forward0_warp.nii.gz touch ${prefix}_backward1_warp.nii.gz diff --git a/modules/nf-neuro/registration/synthmorph/meta.yml b/modules/nf-neuro/registration/synthmorph/meta.yml index 03d47d27..35591f3f 100644 --- a/modules/nf-neuro/registration/synthmorph/meta.yml +++ b/modules/nf-neuro/registration/synthmorph/meta.yml @@ -103,6 +103,18 @@ output: pattern: "*_warped.nii.gz" ontologies: - edam: http://edamontology.org/format_4001 # NIFTI format + fixed_warped: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + - "*_warped_reference.nii.gz": + type: file + description: Fixed/Reference warped image + pattern: "*_warped_reference.nii.gz" + ontologies: + - edam: http://edamontology.org/format_4001 # NIFTI format forward_affine: - - meta: type: map diff --git a/modules/nf-neuro/registration/synthmorph/tests/main.nf.test.snap b/modules/nf-neuro/registration/synthmorph/tests/main.nf.test.snap index 2f86a41a..cc18805b 100644 --- a/modules/nf-neuro/registration/synthmorph/tests/main.nf.test.snap +++ b/modules/nf-neuro/registration/synthmorph/tests/main.nf.test.snap @@ -38,6 +38,15 @@ "test_backward1_deform.nii.gz" ] ], + "fixed_warped": [ + [ + { + "id": "test", + "single_end": false + }, + "test_warped_reference.nii.gz" + ] + ], "forward_affine": [ [ { @@ -80,7 +89,7 @@ "id": "test", "single_end": false }, - "test_warped.nii.gz" + "test_b0_mean_warped.nii.gz" ] ], "versions": [ @@ -89,10 +98,10 @@ } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "25.04.8" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-16T19:51:21.67628815" + "timestamp": "2026-07-13T10:27:23.471066239" }, "registration - synthmorph - stub-run": { "content": [ diff --git a/subworkflows/nf-neuro/bundle_seg/tests/main.nf.test.snap b/subworkflows/nf-neuro/bundle_seg/tests/main.nf.test.snap index debb01cf..bf141c06 100644 --- a/subworkflows/nf-neuro/bundle_seg/tests/main.nf.test.snap +++ b/subworkflows/nf-neuro/bundle_seg/tests/main.nf.test.snap @@ -36,7 +36,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-02-26T14:26:41.784029405" + "timestamp": "2026-06-04T13:38:16.327628109" }, "rbx - download atlas - ants registration": { "content": [ @@ -75,6 +75,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-06-02T20:03:03.095138057" + "timestamp": "2026-06-04T13:37:11.622705415" } } \ No newline at end of file diff --git a/subworkflows/nf-neuro/output_template_space/main.nf b/subworkflows/nf-neuro/output_template_space/main.nf index 1d9558a2..97189442 100644 --- a/subworkflows/nf-neuro/output_template_space/main.nf +++ b/subworkflows/nf-neuro/output_template_space/main.nf @@ -161,6 +161,7 @@ workflow OUTPUT_TEMPLATE_SPACE { [ "run_easyreg": options.run_easyreg, "run_synthmorph": options.run_synthmorph, + "masking_strategy": options.masking_strategy ] ) ch_versions = ch_versions.mix(REGISTRATION.out.versions) diff --git a/subworkflows/nf-neuro/output_template_space/tests/main.nf.test.snap b/subworkflows/nf-neuro/output_template_space/tests/main.nf.test.snap index 9edc894c..2a89eef0 100644 --- a/subworkflows/nf-neuro/output_template_space/tests/main.nf.test.snap +++ b/subworkflows/nf-neuro/output_template_space/tests/main.nf.test.snap @@ -7,7 +7,7 @@ { "id": "test" }, - "test_t1_warped.nii.gz" + "test_mni_masked_warped.nii.gz" ] ], "ch_registered_labels_files": [ @@ -77,7 +77,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-06-02T20:04:53.696301982" + "timestamp": "2026-07-11T00:51:58.045151125" }, "Template MNI152NLin2009aAsym - using synthmorph registration": { "content": [ @@ -87,7 +87,7 @@ { "id": "test" }, - "test_warped.nii.gz" + "test_mni_masked_warped.nii.gz" ] ], "ch_registered_labels_files": [ @@ -152,7 +152,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-02-26T22:42:44.929412455" + "timestamp": "2026-07-13T14:12:45.301916755" }, "Template MNI152NLin2009cAsym - local templates": { "content": [ @@ -162,7 +162,7 @@ { "id": "test" }, - "test_t1_warped.nii.gz" + "test_mni_masked_warped.nii.gz" ] ], "ch_registered_labels_files": [ @@ -232,6 +232,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-06-02T20:04:18.303384843" + "timestamp": "2026-07-11T00:51:24.259893277" } } \ No newline at end of file diff --git a/subworkflows/nf-neuro/output_template_space/tests/nextflow.config b/subworkflows/nf-neuro/output_template_space/tests/nextflow.config index 805dfe50..7b8ba1ff 100644 --- a/subworkflows/nf-neuro/output_template_space/tests/nextflow.config +++ b/subworkflows/nf-neuro/output_template_space/tests/nextflow.config @@ -3,6 +3,7 @@ process { cpus = 1 withName: "REGISTRATION_ANTS" { + ext.masking_strategy = "internal" ext.repro_mode = 1 ext.transform = "s" ext.quick = true @@ -57,7 +58,7 @@ process { ext.bet_f = 0.6 ext.crop = false ext.dilate = false - } + } } params.templateflow_home = "./" @@ -65,3 +66,4 @@ params.template = "MNI152NLin2009aAsym" params.templateflow_res = 1 params.templateflow_cohort = null params.use_template_t2w = false +params.masking_strategy = "internal" diff --git a/subworkflows/nf-neuro/registration/main.nf b/subworkflows/nf-neuro/registration/main.nf index 01a6582a..64056e9e 100644 --- a/subworkflows/nf-neuro/registration/main.nf +++ b/subworkflows/nf-neuro/registration/main.nf @@ -4,7 +4,11 @@ include { REGISTRATION_EASYREG } from '../../../modules/nf-neuro/registration/ include { REGISTRATION_SYNTHMORPH } from '../../../modules/nf-neuro/registration/synthmorph/main' include { REGISTRATION_CONVERT } from '../../../modules/nf-neuro/registration/convert/main' include { UTILS_OPTIONS } from '../utils_options/main' - +include { IMAGE_APPLYMASK as MASK_FIXED_IMAGE} from '../../../modules/nf-neuro/image/applymask/main' +include { IMAGE_APPLYMASK as MASK_FIXED_METRIC} from '../../../modules/nf-neuro/image/applymask/main' +include { IMAGE_APPLYMASK as MASK_MOVING_IMAGE} from '../../../modules/nf-neuro/image/applymask/main' +include { REGISTRATION_ANTSAPPLYTRANSFORMS as WARP_IMAGE_TO_FIXED } from '../../../modules/nf-neuro/registration/antsapplytransforms/main' +include { REGISTRATION_ANTSAPPLYTRANSFORMS as WARP_IMAGE_TO_MOVING } from '../../../modules/nf-neuro/registration/antsapplytransforms/main' workflow REGISTRATION { @@ -34,6 +38,47 @@ workflow REGISTRATION { UTILS_OPTIONS("${moduleDir}/meta.yml", options, true) options = UTILS_OPTIONS.out.options.value + if ( ( options.masking_strategy == "apriori" || options.masking_strategy == "both" ) && ( ch_fixed_mask || ch_moving_mask || ch_metric ) ) { + if ( ch_fixed_mask ) { + MASK_FIXED_IMAGE ( ch_fixed_image.join(ch_fixed_mask) ) + ch_fixed_image_ready = ch_fixed_image.join(MASK_FIXED_IMAGE.out.image, remainder: true) + .map({ meta, orig, masked -> [meta, masked?: orig] }) + ch_versions = ch_versions.mix(MASK_FIXED_IMAGE.out.versions.first()) + + if ( ch_metric ) { + MASK_FIXED_METRIC ( ch_metric.join(ch_fixed_mask) ) + ch_fixed_metric_ready = ch_metric.join(MASK_FIXED_METRIC.out.image, remainder: true) + .map({ meta, orig, masked -> [meta, masked?: orig] }) + ch_versions = ch_versions.mix(MASK_FIXED_METRIC.out.versions.first()) + } + else { + ch_fixed_metric_ready = ch_metric + } + } + else { + ch_fixed_metric_ready = ch_metric + ch_fixed_image_ready = ch_fixed_image + } + if ( ch_moving_mask ) { + MASK_MOVING_IMAGE ( ch_moving_image.join(ch_moving_mask) ) + ch_moving_image_ready = ch_moving_image.join(MASK_MOVING_IMAGE.out.image, remainder: true) + .map({ meta, orig, masked -> [meta, masked?: orig] }) + ch_versions = ch_versions.mix(MASK_MOVING_IMAGE.out.versions.first()) + } + else { + ch_moving_image_ready = ch_moving_image + } + } + else { + ch_fixed_image_ready = ch_fixed_image + ch_moving_image_ready = ch_moving_image + ch_fixed_metric_ready = ch_metric + } + + if ( ( options.masking_strategy == "both" || options.masking_strategy == "internal" ) && ( options.run_easyreg || options.run_synthmorph ) ) { + error "The \${options.masking_strategy} masking strategy is not compatible with the easyreg or synthmorph registration methods." + } + if ( options.run_easyreg ) { // ** Registration using Easyreg ** // // Result : [ meta, reference, image | [], ref-segmentation | [], segmentation | [] ] @@ -42,8 +87,8 @@ workflow REGISTRATION { // - join [ meta, reference, image | null, ref-segmentation | null ] // - join [ meta, reference, image | null, ref-segmentation | null, segmentation | null ] // - map [ meta, reference, image | [], ref-segmentation | [], segmentation | [] ] - ch_register = ch_moving_image - .join(ch_fixed_image, remainder: true) + ch_register = ch_moving_image_ready + .join(ch_fixed_image_ready, remainder: true) .join(ch_moving_segmentation, remainder: true) .join(ch_segmentation, remainder: true) .map{ it[0..1] + [it[2] ?: [], it[3] ?: [], it[4] ?: []] } @@ -71,8 +116,8 @@ workflow REGISTRATION { } else if ( options.run_synthmorph ) { // ** Registration using synthmorph ** // - ch_register = ch_fixed_image - .join(ch_moving_image) + ch_register = ch_fixed_image_ready + .join(ch_moving_image_ready) REGISTRATION_SYNTHMORPH ( ch_register ) ch_versions = ch_versions.mix(REGISTRATION_SYNTHMORPH.out.versions.first()) @@ -139,6 +184,7 @@ workflow REGISTRATION { // ** Set compulsory outputs ** // out_image_warped = REGISTRATION_SYNTHMORPH.out.image_warped + out_ref_warped = REGISTRATION_SYNTHMORPH.out.fixed_warped out_forward_affine = ch_conversion_outputs.forward_affine out_forward_warp = ch_conversion_outputs.forward_warp out_backward_affine = ch_conversion_outputs.backward_affine @@ -152,7 +198,6 @@ workflow REGISTRATION { out_forward_tractogram_transform = out_backward_image_transform out_backward_tractogram_transform = out_forward_image_transform // ** and optional outputs. ** // - out_ref_warped = channel.empty() out_segmentation = channel.empty() out_ref_segmentation = channel.empty() } @@ -166,13 +211,16 @@ workflow REGISTRATION { // Branches : // - anat_to_dwi : has a metric at index 3 // - ants_syn : doesn't have a metric at index 3 ( [] or null ) - ch_register = ch_fixed_image - .join(ch_moving_image) - .join(ch_metric, remainder: true) - .map{ it[0..2] + [it[3] ?: []] } + ch_register = ch_fixed_image_ready + .join(ch_moving_image_ready) + .join(ch_fixed_metric_ready, remainder: true) + .join(ch_fixed_mask, remainder: true) + .join(ch_moving_mask, remainder: true) + .map{ it[0..2] + [it[3] ?: []] + [it[4] ?: [], it[5] ?: []] } .branch{ anat_to_dwi : it[3] ants_syn: true + return it[0..2] + it[4..5] } // ** Registration using ANAT TO DWI ** // @@ -182,6 +230,7 @@ workflow REGISTRATION { // ** Set compulsory outputs ** // out_image_warped = REGISTRATION_ANATTODWI.out.anat_warped + out_ref_warped = REGISTRATION_ANATTODWI.out.fixed_warped out_forward_affine = REGISTRATION_ANATTODWI.out.forward_affine out_forward_warp = REGISTRATION_ANATTODWI.out.forward_warp out_backward_affine = REGISTRATION_ANATTODWI.out.backward_affine @@ -197,18 +246,15 @@ workflow REGISTRATION { // Result : [ meta, image, mask | [] ] // Steps : // - join [ meta, image, metric | [], mask | null ] - // - map [ meta, image, mask | [] ] - ch_register = ch_register.ants_syn - .join(ch_fixed_mask, remainder: true) - .join(ch_moving_mask, remainder: true) - .map{ it[0..2] + [it[4] ?: []] + [it[5] ?: []] } + // - map [ meta, image ] - REGISTRATION_ANTS ( ch_register ) + REGISTRATION_ANTS ( ch_register.ants_syn ) ch_versions = ch_versions.mix(REGISTRATION_ANTS.out.versions.first()) ch_mqc = ch_mqc.mix(REGISTRATION_ANTS.out.mqc) // ** Set compulsory outputs ** // out_image_warped = out_image_warped.mix(REGISTRATION_ANTS.out.image_warped) + out_ref_warped = out_ref_warped.mix(REGISTRATION_ANTS.out.fixed_warped) out_forward_affine = out_forward_affine.mix(REGISTRATION_ANTS.out.forward_affine) out_forward_warp = out_forward_warp.mix(REGISTRATION_ANTS.out.forward_warp) out_backward_affine = out_backward_affine.mix(REGISTRATION_ANTS.out.backward_affine) @@ -219,13 +265,49 @@ workflow REGISTRATION { out_backward_tractogram_transform = out_backward_tractogram_transform.mix(REGISTRATION_ANTS.out.backward_tractogram_transform) // **and optional outputs **// - out_ref_warped = channel.empty() out_segmentation = channel.empty() out_ref_segmentation = channel.empty() } + + out_image_warped_masked = out_image_warped + .join(ch_moving_mask) + .filter{ _meta, _warped, mask -> options.masking_strategy in ["both", "apriori"] && mask } + .map{ meta, warped, _mask -> [meta, warped] } + + out_ref_warped_masked = out_ref_warped + .join(ch_fixed_mask) + .filter{ _meta, _warped, mask -> options.masking_strategy in ["both", "apriori"] && mask } + .map{ meta, warped, _mask -> [meta, warped] } + + // Register original moving image + WARP_IMAGE_TO_FIXED ( ch_moving_image + .join(ch_fixed_image) + .join(out_forward_image_transform) + .join(ch_moving_mask) + .filter{ _meta, _moving, _fixed, _transform, mask -> mask } + .map{ meta, moving, fixed, transform, _mask -> [meta, moving, fixed, transform] } ) + out_image_warped = out_image_warped + .join(WARP_IMAGE_TO_FIXED.out.warped_image, remainder: true) + .map{ meta, warped, warped_from_mask -> [meta, (warped_from_mask ?: warped)] } + ch_versions = ch_versions.mix(WARP_IMAGE_TO_FIXED.out.versions.first()) + + // Register original ref image + WARP_IMAGE_TO_MOVING ( ch_fixed_image + .join(ch_moving_image) + .join(out_backward_image_transform) + .join(ch_fixed_mask) + .filter{ _meta, _moving, _fixed, _transform, mask -> mask } + .map{ meta, moving, fixed, transform, _mask -> [meta, moving, fixed, transform] } ) + out_ref_warped = out_ref_warped + .join(WARP_IMAGE_TO_MOVING.out.warped_image, remainder: true) + .map{ meta, warped, warped_from_mask -> [meta, (warped_from_mask ?: warped)] } + ch_versions = ch_versions.mix(WARP_IMAGE_TO_MOVING.out.versions.first()) + emit: image_warped = out_image_warped // channel: [ val(meta), image ] reference_warped = out_ref_warped // channel: [ val(meta), ref ] + image_warped_masked = out_image_warped_masked // channel: [ val(meta), image ] + reference_warped_masked = out_ref_warped_masked // channel: [ val(meta), ref ] // Individual transforms forward_affine = out_forward_affine // channel: [ val(meta), ] forward_warp = out_forward_warp // channel: [ val(meta), ] diff --git a/subworkflows/nf-neuro/registration/meta.yml b/subworkflows/nf-neuro/registration/meta.yml index 29923bf8..5addc162 100644 --- a/subworkflows/nf-neuro/registration/meta.yml +++ b/subworkflows/nf-neuro/registration/meta.yml @@ -44,9 +44,11 @@ keywords: components: - registration/anattodwi - registration/ants + - registration/antsapplytransforms - registration/convert - registration/easyreg - registration/synthmorph + - image/applymask - utils_options input: - ch_fixed_image: @@ -93,7 +95,7 @@ input: - ch_fixed_mask: type: file description: | - FOR USE WITH ANTS SYN REGISTRATION ONLY. The input channel containing the mask file in fixed image space. + Fixed mask will be used to mask the fixed image during registration. structure: - meta: type: map @@ -106,7 +108,7 @@ input: - ch_moving_mask: type: file description: | - FOR USE WITH ANTS SYN REGISTRATION ONLY. The input channel containing the mask file in moving image space. + Moving mask will be used to mask the moving image during registration. structure: - meta: type: map @@ -135,6 +137,15 @@ input: description: Map of options for the registration subworkflow. mandatory: false entries: + masking_strategy: + type: string + choices: + - none + - apriori + - internal + - both + description: Masking strategy to use for registration. Options are 'none', 'apriori', 'internal' or 'both'. + default: "none" run_easyreg: type: boolean description: Run EasyReg for registration. If false, SynthMorph will be used if `run_synthmorph` is true, and ANTs SyN will be used if `run_synthmorph` is false. @@ -159,7 +170,7 @@ output: - reference_warped: type: file description: | - ONLY PROVIDED BY REGISTRATION_EASYREG. Channel containing the reference image warped in moving space. + Channel containing the reference image warped in moving space. structure: - meta: type: map @@ -169,6 +180,31 @@ output: description: Warped reference image in moving space. pattern: "*.{nii,nii.gz}" mandatory: false + - image_warped_masked: + type: file + description: | + Channel containing images warped in fixed space. + structure: + - meta: + type: map + description: Metadata map. + - image: + type: file + description: Warped image masked in fixed space. + pattern: "*.{nii,nii.gz}" + - reference_warped_masked: + type: file + description: | + Channel containing the reference image warped in moving space. + structure: + - meta: + type: map + description: Metadata map. + - image: + type: file + description: Warped reference image masked in moving space. + pattern: "*.{nii,nii.gz}" + mandatory: false - forward_affine: type: file description: | diff --git a/subworkflows/nf-neuro/registration/tests/main.nf.test b/subworkflows/nf-neuro/registration/tests/main.nf.test index 20f5dec8..eb675d6d 100644 --- a/subworkflows/nf-neuro/registration/tests/main.nf.test +++ b/subworkflows/nf-neuro/registration/tests/main.nf.test @@ -11,11 +11,12 @@ nextflow_workflow { tag "registration" tag "registration/anattodwi" - tag "registration" tag "registration/ants" + tag "registration/antsapplytransforms" tag "registration/convert" tag "registration/easyreg" tag "registration/synthmorph" + tag "image/applymask" tag "subworkflows/utils_options" diff --git a/subworkflows/nf-neuro/registration/tests/main.nf.test.snap b/subworkflows/nf-neuro/registration/tests/main.nf.test.snap index 510ea20c..29f0e724 100644 --- a/subworkflows/nf-neuro/registration/tests/main.nf.test.snap +++ b/subworkflows/nf-neuro/registration/tests/main.nf.test.snap @@ -59,7 +59,15 @@ { "id": "test" }, - "test_warped.nii.gz" + "test_b0_warped.nii.gz" + ] + ], + "reference_warped": [ + [ + { + "id": "test" + }, + "test_warped_reference.nii.gz" ] ], "versions": [ @@ -69,10 +77,10 @@ } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "25.04.8" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-16T20:51:47.326447932" + "timestamp": "2026-07-13T10:29:59.551538877" }, "registration - easyreg": { "content": [ @@ -130,7 +138,7 @@ { "id": "test" }, - "test_warped.nii.gz" + "test_T1w_warped.nii.gz" ] ], "reference_segmentation": [ @@ -163,10 +171,10 @@ } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "25.04.8" + "nf-test": "0.9.3", + "nextflow": "25.10.2" }, - "timestamp": "2025-10-15T18:55:55.830874285" + "timestamp": "2026-07-13T10:29:45.268529864" }, "registration - ANTs - SyNQuick": { "content": [ @@ -255,7 +263,16 @@ "test__registration_ants_mqc.gif" ] ], + "reference_warped": [ + [ + { + "id": "test" + }, + "test_T1w_warped.nii.gz" + ] + ], "versions": [ + "versions.yml:md5,3764dd2f067db355da3536c1b0c94619", "versions.yml:md5,a338911f46f2c623d87eab600c524ffb" ] } @@ -264,7 +281,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-06-02T20:05:53.555032692" + "timestamp": "2026-07-13T16:59:05.118623545" }, "registration - ANTs - Anat to DWI": { "content": [ @@ -353,6 +370,14 @@ "test_registration_anattodwi_mqc.gif" ] ], + "reference_warped": [ + [ + { + "id": "test" + }, + "test_warped_reference.nii.gz" + ] + ], "versions": [ "versions.yml:md5,03b958f14a890b541bb76c73f7a72847" ] @@ -362,6 +387,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-02-26T22:46:42.344818522" + "timestamp": "2026-07-13T17:02:40.341565686" } } \ No newline at end of file diff --git a/subworkflows/nf-neuro/registration/tests/nextflow.config b/subworkflows/nf-neuro/registration/tests/nextflow.config index bf293e61..1e36e35a 100644 --- a/subworkflows/nf-neuro/registration/tests/nextflow.config +++ b/subworkflows/nf-neuro/registration/tests/nextflow.config @@ -15,6 +15,7 @@ process { } withName: "REGISTRATION_ANTS" { + ext.masking_strategy = "apriori" ext.quick = true ext.repro_mode = true ext.transform = "a" diff --git a/subworkflows/nf-neuro/tractoflow/main.nf b/subworkflows/nf-neuro/tractoflow/main.nf index 149b3835..32596993 100644 --- a/subworkflows/nf-neuro/tractoflow/main.nf +++ b/subworkflows/nf-neuro/tractoflow/main.nf @@ -14,7 +14,7 @@ include { RECONST_MEANFRF } from '../../../modules/nf-neuro/reconst/meanfrf/m include { RECONST_DTIMETRICS } from '../../../modules/nf-neuro/reconst/dtimetrics/main' include { RECONST_FODF } from '../../../modules/nf-neuro/reconst/fodf/main' include { RECONST_QBALL } from '../../../modules/nf-neuro/reconst/qball/main' -include { IMAGE_MATH } from '../../../modules/nf-neuro/image/math/main' +include { IMAGE_APPLYMASK } from '../../../modules/nf-neuro/image/applymask/main' // TRACKING include { TRACKING_PFTTRACKING } from '../../../modules/nf-neuro/tracking/pfttracking/main' @@ -179,9 +179,9 @@ workflow TRACTOFLOW { // SUBWORKFLOW: Run REGISTRATION // if ( options.preproc_dwi_keep_dwi_with_skull ) { - IMAGE_MATH(RECONST_DTIMETRICS.out.fa.join(PREPROC_DWI.out.b0_mask)) - ch_fa_for_registration = IMAGE_MATH.out.image - ch_versions = ch_versions.mix(IMAGE_MATH.out.versions.first()) + IMAGE_APPLYMASK(RECONST_DTIMETRICS.out.fa.join(PREPROC_DWI.out.b0_mask)) + ch_fa_for_registration = IMAGE_APPLYMASK.out.image + ch_versions = ch_versions.mix(IMAGE_APPLYMASK.out.versions.first()) } else { ch_fa_for_registration = RECONST_DTIMETRICS.out.fa diff --git a/subworkflows/nf-neuro/tractoflow/meta.yml b/subworkflows/nf-neuro/tractoflow/meta.yml index 5ac7a143..9561f087 100644 --- a/subworkflows/nf-neuro/tractoflow/meta.yml +++ b/subworkflows/nf-neuro/tractoflow/meta.yml @@ -44,7 +44,7 @@ keywords: components: - image/convertdwi - image/convert - - image/math + - image/applymask - anatomical_segmentation - preproc_dwi - preproc_t1 diff --git a/subworkflows/nf-neuro/tractoflow/modules.config b/subworkflows/nf-neuro/tractoflow/modules.config index b8d8b8b2..bd968b5e 100644 --- a/subworkflows/nf-neuro/tractoflow/modules.config +++ b/subworkflows/nf-neuro/tractoflow/modules.config @@ -96,10 +96,9 @@ process { ext.first_suffix = "t1" } - withName: "TRACTOFLOW:IMAGE:MATH" { - ext.operation = "multiplication" + withName: "TRACTOFLOW:IMAGE_APPLYMASK" { ext.data_type = "float32" - ext.suffix = "fa_masked" + ext.first_suffix = "fa" } //withName: "TRACTOFLOW:T1_REGISTRATION:REGISTER_ANATTODWI" { diff --git a/subworkflows/nf-neuro/tractoflow/tests/main.nf.test b/subworkflows/nf-neuro/tractoflow/tests/main.nf.test index 1af9e337..fbe462c8 100644 --- a/subworkflows/nf-neuro/tractoflow/tests/main.nf.test +++ b/subworkflows/nf-neuro/tractoflow/tests/main.nf.test @@ -18,7 +18,7 @@ nextflow_workflow { tag "image/convert" tag "image/convertdwi" - tag "image/math" + tag "image/applymask" tag "reconst/dtimetrics" tag "reconst/frf" tag "reconst/fodf" diff --git a/subworkflows/nf-neuro/tractoflow/tests/main.nf.test.snap b/subworkflows/nf-neuro/tractoflow/tests/main.nf.test.snap index 550a1ef8..15177c9e 100644 --- a/subworkflows/nf-neuro/tractoflow/tests/main.nf.test.snap +++ b/subworkflows/nf-neuro/tractoflow/tests/main.nf.test.snap @@ -393,7 +393,6 @@ "versions": [ "versions.yml:md5,229b67add04c70923f1bca378b7b2187", "versions.yml:md5,68aaff09474ed3ae149c1cffb0651f0d", - "versions.yml:md5,7c2302570358741fd2c8a9c5f9df41cb", "versions.yml:md5,7cabc91ec64b5e824e9b8f60d7dcf930", "versions.yml:md5,7fae1f6758d48901013496c0a680b81b", "versions.yml:md5,85cf18214259841972e1ea51961dc19d", @@ -401,6 +400,7 @@ "versions.yml:md5,b1f30072384bba1505d84f60281dfc24", "versions.yml:md5,cdfc3f4153b62c413e2fc6e948f2ef21", "versions.yml:md5,e808fc7967f50aad087f14c8cbcdc7e1", + "versions.yml:md5,f63f0d3dff7878bb46899a6b96ac2497", "versions.yml:md5,fee3d07623cc095a898f0a1de534a05b" ], "volume_fraction": [ @@ -441,7 +441,7 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-06-03T15:18:39.539666595" + "timestamp": "2026-07-10T22:29:38.90763159" }, "tractoflow - no rev": { "content": [ @@ -941,6 +941,6 @@ "nf-test": "0.9.3", "nextflow": "25.10.2" }, - "timestamp": "2026-06-03T15:16:19.494671141" + "timestamp": "2026-07-10T22:27:22.059261717" } } \ No newline at end of file