diff --git a/modules/nf-scil/segmentation/synthseg/main.nf b/modules/nf-scil/segmentation/synthseg/main.nf index 04ded65b..f74c4365 100644 --- a/modules/nf-scil/segmentation/synthseg/main.nf +++ b/modules/nf-scil/segmentation/synthseg/main.nf @@ -12,6 +12,9 @@ process SEGMENTATION_SYNTHSEG { tuple val(meta), path("*__mask_wm.nii.gz") , emit: wm_mask tuple val(meta), path("*__mask_gm.nii.gz") , emit: gm_mask tuple val(meta), path("*__mask_csf.nii.gz") , emit: csf_mask + tuple val(meta), path("*__vol.csv") , emit: vol, optional: true + tuple val(meta), path("*__qc.csv") , emit: qc, optional: true + tuple val(meta), path("*__resampled_image.nii.gz") , emit: resample, optional: true path "versions.yml" , emit: versions when: @@ -26,7 +29,10 @@ process SEGMENTATION_SYNTHSEG { def robust = task.ext.robust ? "--robust" : "" def fast = task.ext.fast ? "--fast" : "" def ct = task.ext.ct ? "--ct" : "" - //TODO add all the others parameter with the corresponding optional outputs + def output_vol = task.ext.output_vol ? "--vol ${prefix}__vol.csv" : "" + def output_qc = task.ext.output_qc ? "--qc ${prefix}__qc.csv" : "" + def output_resample = task.ext.output_resample ? "--resample ${prefix}__resampled_image.nii.gz": "" + def crop = task.ext.crop ? "--crop " + task.ext.crop: "" """ export ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=1 @@ -35,7 +41,7 @@ process SEGMENTATION_SYNTHSEG { cp $fs_license \$FREESURFER_HOME/license.txt - mri_synthseg --i $image --o t1.nii.gz --threads 1 $gpu $parc $robust $fast $ct + mri_synthseg --i $image --threads $task.cpus --o t1.nii.gz $gpu $parc $robust $fast $ct $output_vol $output_qc $output_resample $crop # WM Mask mri_binarize --i t1.nii.gz \ diff --git a/modules/nf-scil/segmentation/synthseg/meta.yml b/modules/nf-scil/segmentation/synthseg/meta.yml index 10de35ba..3995d7b5 100644 --- a/modules/nf-scil/segmentation/synthseg/meta.yml +++ b/modules/nf-scil/segmentation/synthseg/meta.yml @@ -53,6 +53,21 @@ output: description: Nifti CSF mask volume. pattern: "*.{nii,nii.gz}" + - vol: + type: file + description: (optional) Output CSV file with volumes for all structures and subjects. + pattern: "*.csv" + + - qc: + type: file + description: (optional) Output CSV file with qc scores for all subjects. + pattern: "*.csv" + + - resample: + type: file + description: (optional) in order to return segmentations at 1mm resolution, the input images are internally resampled (except if they already are at 1mm). Use this optional flag to save the resampled images. This must be the same type as --i. + pattern: "*.{nii,nii.gz}" + - versions: type: file description: File containing software versions diff --git a/modules/nf-scil/segmentation/synthseg/tests/main.nf.test b/modules/nf-scil/segmentation/synthseg/tests/main.nf.test index 2a068975..03fe9c10 100644 --- a/modules/nf-scil/segmentation/synthseg/tests/main.nf.test +++ b/modules/nf-scil/segmentation/synthseg/tests/main.nf.test @@ -24,7 +24,7 @@ nextflow_process { } } - test("segmentation - synthseg") { + test("segmentation - synthseg - basic") { config "./nextflow_basic.config" when { process { @@ -35,7 +35,6 @@ nextflow_process { file("\${test_data_directory}/t1.nii.gz", checkIfExists: true,), [], file("\${test_data_directory}/license.txt", checkIfExists: true,) - ] } """ @@ -51,8 +50,33 @@ nextflow_process { } } + test("segmentation - synthseg - options") { + config "./nextflow_options.config" + when { + process { + """ + input[0] = LOAD_DATA.out.test_data_directory.map{ + test_data_directory -> [ + [ id:'test', single_end:false ], // meta map + file("\${test_data_directory}/t1.nii.gz", checkIfExists: true,), + [], + file("\${test_data_directory}/license.txt", checkIfExists: true,) + ] + } + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + + ) + } + } - // test("segmentation - synthseg") { + // test("segmentation - synthseg - lesion") { // config "./nextflow_lesion.config" // when { // process { diff --git a/modules/nf-scil/segmentation/synthseg/tests/main.nf.test.snap b/modules/nf-scil/segmentation/synthseg/tests/main.nf.test.snap index fa96f7cd..f4973488 100644 --- a/modules/nf-scil/segmentation/synthseg/tests/main.nf.test.snap +++ b/modules/nf-scil/segmentation/synthseg/tests/main.nf.test.snap @@ -1,5 +1,118 @@ { - "segmentation - synthseg": { + "segmentation - synthseg - options": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test__mask_wm.nii.gz:md5,8ca305b46341552159e15e6974274358" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test__mask_gm.nii.gz:md5,c8c4f3027132011d98cf4a351230f519" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test__mask_csf.nii.gz:md5,1deff8b0b3d9f883b75bcd5c9f52f2c5" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test__vol.csv:md5,fe0078439655e81ab5777c73b4bd1edf" + ] + ], + "4": [ + [ + { + "id": "test", + "single_end": false + }, + "test__qc.csv:md5,ede51ac9221945293200793a46c15afa" + ] + ], + "5": [ + + ], + "6": [ + "versions.yml:md5,b65418e9ce2ab1cce590b1f659e18c1d" + ], + "csf_mask": [ + [ + { + "id": "test", + "single_end": false + }, + "test__mask_csf.nii.gz:md5,1deff8b0b3d9f883b75bcd5c9f52f2c5" + ] + ], + "gm_mask": [ + [ + { + "id": "test", + "single_end": false + }, + "test__mask_gm.nii.gz:md5,c8c4f3027132011d98cf4a351230f519" + ] + ], + "qc": [ + [ + { + "id": "test", + "single_end": false + }, + "test__qc.csv:md5,ede51ac9221945293200793a46c15afa" + ] + ], + "resample": [ + + ], + "versions": [ + "versions.yml:md5,b65418e9ce2ab1cce590b1f659e18c1d" + ], + "vol": [ + [ + { + "id": "test", + "single_end": false + }, + "test__vol.csv:md5,fe0078439655e81ab5777c73b4bd1edf" + ] + ], + "wm_mask": [ + [ + { + "id": "test", + "single_end": false + }, + "test__mask_wm.nii.gz:md5,8ca305b46341552159e15e6974274358" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.0-rc1", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-07T20:11:56.005332" + }, + "segmentation - synthseg - basic": { "content": [ { "0": [ @@ -26,10 +139,19 @@ "id": "test", "single_end": false }, - "test__mask_csf.nii.gz:md5,e60ff1b5847502a1e3f8c4a590d4a73c" + "test__mask_csf.nii.gz:md5,1307c8aeae9064d9a5108a01e918ffba" ] ], "3": [ + + ], + "4": [ + + ], + "5": [ + + ], + "6": [ "versions.yml:md5,b65418e9ce2ab1cce590b1f659e18c1d" ], "csf_mask": [ @@ -38,7 +160,7 @@ "id": "test", "single_end": false }, - "test__mask_csf.nii.gz:md5,e60ff1b5847502a1e3f8c4a590d4a73c" + "test__mask_csf.nii.gz:md5,1307c8aeae9064d9a5108a01e918ffba" ] ], "gm_mask": [ @@ -49,9 +171,18 @@ }, "test__mask_gm.nii.gz:md5,432d6a28a10823c0ca5b2f40d2353e2f" ] + ], + "qc": [ + + ], + "resample": [ + ], "versions": [ "versions.yml:md5,b65418e9ce2ab1cce590b1f659e18c1d" + ], + "vol": [ + ], "wm_mask": [ [ @@ -68,6 +199,6 @@ "nf-test": "0.9.0-rc1", "nextflow": "24.04.4" }, - "timestamp": "2024-08-06T19:27:40.416183" + "timestamp": "2024-08-07T20:11:18.859041" } } \ No newline at end of file diff --git a/modules/nf-scil/segmentation/synthseg/tests/nextflow_options.config b/modules/nf-scil/segmentation/synthseg/tests/nextflow_options.config new file mode 100644 index 00000000..25cec894 --- /dev/null +++ b/modules/nf-scil/segmentation/synthseg/tests/nextflow_options.config @@ -0,0 +1,9 @@ +process { + publishDir = { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" } + ext.robust = true + ext.fast = true + ext.output_vol = true + ext.output_qc = true + ext.resample = true + ext.crop = 64 +}