diff --git a/.test_data/heavy/mni_152/t1_brain_probability_map.nii.gz b/.test_data/heavy/mni_152/t1_brain_probability_map.nii.gz new file mode 100755 index 00000000..ab568e81 --- /dev/null +++ b/.test_data/heavy/mni_152/t1_brain_probability_map.nii.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:352dffed36235d31b3307e53a91b013059de17956d79efe94bd3437677354f4c +size 5454097 diff --git a/.test_data/heavy/mni_152/t1_template.nii.gz b/.test_data/heavy/mni_152/t1_template.nii.gz new file mode 100755 index 00000000..6ab3d05c --- /dev/null +++ b/.test_data/heavy/mni_152/t1_template.nii.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e5a6ed70508568b70088fdec6a9dae5d03b72907ee3132e186e944805481d908 +size 15490739 diff --git a/modules/nf-scil/betcrop/antsbet/main.nf b/modules/nf-scil/betcrop/antsbet/main.nf new file mode 100644 index 00000000..b9f2d00d --- /dev/null +++ b/modules/nf-scil/betcrop/antsbet/main.nf @@ -0,0 +1,62 @@ + +process BETCROP_ANTSBET { + tag "$meta.id" + label 'process_single' + + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://scil.usherbrooke.ca/containers/scilus_1.6.0.sif': + 'scilus/scilus:1.6.0' }" + + input: + tuple val(meta), path(t1), path(template), path(tissues_probabilities) + + output: + tuple val(meta), path("*t1_bet.nii.gz") , emit: t1 + tuple val(meta), path("*t1_bet_mask.nii.gz"), emit: mask + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + export ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=1 + export OMP_NUM_THREADS=1 + export OPENBLAS_NUM_THREADS=1 + export ANTS_RANDOM_SEED=1234 + + antsBrainExtraction.sh -d 3 -a $t1 -e $template -o bet/ -m $tissues_probabilities -u 0 + scil_image_math.py convert bet/BrainExtractionMask.nii.gz ${prefix}__t1_bet_mask.nii.gz --data_type uint8 + mrcalc $t1 ${prefix}__t1_bet_mask.nii.gz -mult ${prefix}__t1_bet.nii.gz -nthreads 1 + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + scilpy: 1.6.0 + mrtrix: \$(mrcalc -version 2>&1 | sed -n 's/== mrcalc \\([0-9.]\\+\\).*/\\1/p') + ants: 2.4.3 + END_VERSIONS + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + antsBrainExtraction.sh -h + scil_image_math.py -h + mrcalc -h + + touch ${prefix}__t1_bet.nii.gz + touch ${prefix}__t1_bet_mask.nii.gz + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + scilpy: 1.6.0 + mrtrix: \$(mrcalc -version 2>&1 | sed -n 's/== mrcalc \\([0-9.]\\+\\).*/\\1/p') + ants: 2.4.3 + END_VERSIONS + """ +} diff --git a/modules/nf-scil/betcrop/antsbet/meta.yml b/modules/nf-scil/betcrop/antsbet/meta.yml new file mode 100644 index 00000000..e073120f --- /dev/null +++ b/modules/nf-scil/betcrop/antsbet/meta.yml @@ -0,0 +1,65 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/yaml-schema.json +name: "betcrop_antsbet" +description: Perform Brain extraction using antsBrainExtraction.sh on T1 image. +keywords: + - T1 + - BET + - ants +tools: + - "Scilpy": + description: "The Sherbrooke Connectivity Imaging Lab (SCIL) Python dMRI processing toolbox." + homepage: "https://github.com/scilus/scilpy.git" + - "MRtrix3": + description: "Toolbox for image processing, analysis and visualisation of dMRI." + homepage: "https://mrtrix.readthedocs.io/en/latest/" + - "ants": + description: "Advanced Normalization Tools." + homepage: "https://github.com/ANTsX/ANTs" + +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + + - t1: + type: file + description: Nifti t1 volume to perform BET. + pattern: "*.{nii,nii.gz}" + + - template: + type: file + description: Nifti Anatomical template to perform BET. + pattern: "*.{nii,nii.gz}" + + - tissues_probabilities: + type: file + description: Brain probability mask, with intensity range 1 (definitely brain) to 0 (definitely background). + pattern: "*.{nii,nii.gz}" + +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test', single_end:false ]` + + - t1: + type: file + description: Nifti T1 volume brain-extracted. + pattern: "*t1_bet.{nii,nii.gz}" + + - mask: + type: file + description: T1 mask brain-extracted and cropped. + pattern: "*t1_bet_mask.{nii,nii.gz}" + + - versions: + type: file + description: File containing software versions + pattern: "versions.yml" + +authors: + - "@ThoumyreStanislas" diff --git a/tests/config/pytest_modules.yml b/tests/config/pytest_modules.yml index 8a072eb7..19ca3204 100755 --- a/tests/config/pytest_modules.yml +++ b/tests/config/pytest_modules.yml @@ -1,3 +1,7 @@ +betcrop/antsbet: + - modules/nf-scil/betcrop/antsbet/** + - tests/modules/nf-scil/betcrop/antsbet/** + betcrop/cropvolume: - modules/nf-scil/betcrop/cropvolume/** - tests/modules/nf-scil/betcrop/cropvolume/** diff --git a/tests/config/test_data.config b/tests/config/test_data.config index 26adb506..f34a7443 100755 --- a/tests/config/test_data.config +++ b/tests/config/test_data.config @@ -18,6 +18,11 @@ params { bval = "${params.test_data_base}/heavy/dwi/dwi.bval" bvec = "${params.test_data_base}/heavy/dwi/dwi.bvec" } + "antsbet" { + t1 = "${params.test_data_base}/heavy/anat/anat_image.nii.gz" + template = "${params.test_data_base}/heavy/mni_152/t1_template.nii.gz" + map = "${params.test_data_base}/heavy/mni_152/t1_brain_probability_map.nii.gz" + } } "denoising" { "nlmeans" { diff --git a/tests/modules/nf-scil/betcrop/antsbet/main.nf b/tests/modules/nf-scil/betcrop/antsbet/main.nf new file mode 100644 index 00000000..36ee81a6 --- /dev/null +++ b/tests/modules/nf-scil/betcrop/antsbet/main.nf @@ -0,0 +1,24 @@ +#!/usr/bin/env nextflow + +nextflow.enable.dsl = 2 + +include { BETCROP_ANTSBET } from '../../../../../modules/nf-scil/betcrop/antsbet/main.nf' +include { LOAD_TEST_DATA } from '../../../../../subworkflows/nf-scil/load_test_data/main' + +workflow test_betcrop_antsbet { + + input_fetch = Channel.from( [ "antsbet.zip" ] ) + + LOAD_TEST_DATA ( input_fetch, "test.test_betcrop_antsbet" ) + + input = LOAD_TEST_DATA.out.test_data_directory + .map{ test_data_directory -> [ + [ id:'test', single_end:false ], // meta map + file("${test_data_directory}/t1_unaligned.nii.gz"), + file("${test_data_directory}/t1_template.nii.gz"), + file("${test_data_directory}/t1_brain_probability_map.nii.gz") + + ]} + + BETCROP_ANTSBET ( input ) +} diff --git a/tests/modules/nf-scil/betcrop/antsbet/nextflow.config b/tests/modules/nf-scil/betcrop/antsbet/nextflow.config new file mode 100644 index 00000000..b850d5dd --- /dev/null +++ b/tests/modules/nf-scil/betcrop/antsbet/nextflow.config @@ -0,0 +1,6 @@ +process { + + withName: "BETCROP_ANTSBET" { + publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } + } +} \ No newline at end of file diff --git a/tests/modules/nf-scil/betcrop/antsbet/test.yml b/tests/modules/nf-scil/betcrop/antsbet/test.yml new file mode 100644 index 00000000..bcf422d7 --- /dev/null +++ b/tests/modules/nf-scil/betcrop/antsbet/test.yml @@ -0,0 +1,11 @@ +- name: betcrop antsbet test_betcrop_antsbet + command: nextflow run ./tests/modules/nf-scil/betcrop/antsbet -entry test_betcrop_antsbet -c ./tests/config/nextflow.config + tags: + - betcrop/antsbet + - betcrop + files: + - path: output/betcrop/test__t1_bet.nii.gz + md5sum: e88c7e63cf220562a97f16c92be0d87b + - path: output/betcrop/test__t1_bet_mask.nii.gz + md5sum: 846bd8fc8a212dcffcd728a0846a711c + - path: output/betcrop/versions.yml