From 36b0e5ff8f8a3fa8298ef9b9c1d412c1dbaff031 Mon Sep 17 00:00:00 2001 From: Greg Conan Date: Thu, 8 Dec 2022 18:29:59 -0600 Subject: [PATCH 1/4] ENH: Anat wf saves T2 out file even without precomp mask --- nibabies/workflows/anatomical/base.py | 95 +++++++++++++----------- nibabies/workflows/anatomical/outputs.py | 14 ++++ 2 files changed, 67 insertions(+), 42 deletions(-) diff --git a/nibabies/workflows/anatomical/base.py b/nibabies/workflows/anatomical/base.py index aeb1fbed..ac16473d 100644 --- a/nibabies/workflows/anatomical/base.py +++ b/nibabies/workflows/anatomical/base.py @@ -214,24 +214,24 @@ def init_infant_anat_wf( precomp_mask_wf = init_precomputed_mask_wf(omp_nthreads=omp_nthreads) precomp_mask_wf.inputs.inputnode.t1w_mask = precomp_mask - else: - brain_extraction_wf = init_infant_brain_extraction_wf( - age_months=age_months, - ants_affine_init=ants_affine_init, - skull_strip_template=skull_strip_template.space, - template_specs=skull_strip_template.spec, - omp_nthreads=omp_nthreads, - sloppy=sloppy, - debug="registration" in config.execution.debug, - ) - coregistration_wf = init_coregistration_wf( - omp_nthreads=omp_nthreads, - sloppy=sloppy, - debug="registration" in config.execution.debug, - ) - coreg_report_wf = init_coreg_report_wf( - output_dir=output_dir, - ) + # else: brain_extraction_wf = ... + brain_extraction_wf = init_infant_brain_extraction_wf( + age_months=age_months, + ants_affine_init=ants_affine_init, + skull_strip_template=skull_strip_template.space, + template_specs=skull_strip_template.spec, + omp_nthreads=omp_nthreads, + sloppy=sloppy, + debug="registration" in config.execution.debug, + ) + coregistration_wf = init_coregistration_wf( + omp_nthreads=omp_nthreads, + sloppy=sloppy, + debug="registration" in config.execution.debug, + ) + coreg_report_wf = init_coreg_report_wf( + output_dir=output_dir, + ) t1w_preproc_wf = precomp_mask_wf if precomp_mask else coregistration_wf # Segmentation - initial implementation should be simple: JLF @@ -284,6 +284,9 @@ def init_infant_anat_wf( ("outputnode.t1w_mask", "inputnode.t1w_mask"), ("outputnode.t1w_preproc", "inputnode.t1w_preproc"), ]), + (coregistration_wf, anat_derivatives_wf, [ + ("outputnode.t2w_preproc", "inputnode.t2w_preproc") + ]), (t1w_preproc_wf, outputnode, [ ("outputnode.t1w_preproc", "anat_preproc"), ("outputnode.t1w_brain", "anat_brain"), @@ -295,36 +298,41 @@ def init_infant_anat_wf( wf.connect([ (t1w_preproc_wf, anat_seg_wf, [("outputnode.t1w_brain", "inputnode.anat_brain")]), ]) - + wf.connect([ + (inputnode, t2w_template_wf, [("t2w", "inputnode.in_files")]), + ]) if precomp_mask: wf.connect([ (t1w_template_wf, precomp_mask_wf, [ ("outputnode.out_file", "inputnode.t1w"), ]), ]) - else: - wf.connect([ - (inputnode, t2w_template_wf, [("t2w", "inputnode.in_files")]), - (t2w_template_wf, brain_extraction_wf, [ - ("outputnode.out_file", "inputnode.in_t2w"), - ]), - (t1w_template_wf, coregistration_wf, [ - ("outputnode.out_file", "inputnode.in_t1w"), - ]), - (brain_extraction_wf, coregistration_wf, [ - ("outputnode.t2w_preproc", "inputnode.in_t2w_preproc"), - ("outputnode.out_mask", "inputnode.in_mask"), - ("outputnode.out_probmap", "inputnode.in_probmap"), - ]), - (inputnode, coreg_report_wf, [ - ("t1w", "inputnode.source_file"), - ]), - (t1w_preproc_wf, coreg_report_wf, [ - ("outputnode.t1w_preproc", "inputnode.t1w_preproc"), - ("outputnode.t2w_preproc", "inputnode.t2w_preproc"), - ("outputnode.t1w_mask", "inputnode.in_mask"), - ]), - ]) + + wf.connect([ + (t2w_template_wf, brain_extraction_wf, [ + ("outputnode.out_file", "inputnode.in_t2w"), + ]), + ]) + wf.connect([ + (t1w_template_wf, coregistration_wf, [ + ("outputnode.out_file", "inputnode.in_t1w"), + ]), + (brain_extraction_wf, coregistration_wf, [ + ("outputnode.t2w_preproc", "inputnode.in_t2w_preproc"), + ("outputnode.out_mask", "inputnode.in_mask"), + ("outputnode.out_probmap", "inputnode.in_probmap"), + ]), + (inputnode, coreg_report_wf, [ + ("t1w", "inputnode.source_file"), + ]), + (t1w_preproc_wf, coreg_report_wf, [ + ("outputnode.t1w_preproc", "inputnode.t1w_preproc"), + ("outputnode.t1w_mask", "inputnode.in_mask"), + ]), + (coregistration_wf, coreg_report_wf, [ + ("outputnode.t2w_preproc", "inputnode.t2w_preproc") + ]), + ]) wf.connect([ # reports @@ -349,6 +357,9 @@ def init_infant_anat_wf( ("outputnode.valid_list", "inputnode.source_files"), ("outputnode.realign_xfms", "inputnode.t1w_ref_xfms"), ]), + (t2w_template_wf, anat_derivatives_wf, [ + ("outputnode.valid_list", "inputnode.t2w_source_files"), + ]), (anat_norm_wf, anat_derivatives_wf, [ ("outputnode.template", "inputnode.template"), ("outputnode.anat2std_xfm", "inputnode.anat2std_xfm"), diff --git a/nibabies/workflows/anatomical/outputs.py b/nibabies/workflows/anatomical/outputs.py index 5020f197..712a62da 100644 --- a/nibabies/workflows/anatomical/outputs.py +++ b/nibabies/workflows/anatomical/outputs.py @@ -308,6 +308,10 @@ def init_anat_derivatives_wf( FreeSurfer's aseg segmentation, in native T1w space t1w_fs_aparc FreeSurfer's aparc+aseg segmentation, in native T1w space + t2w_source_files + List of input T2w images + t2w_preproc + The T2w image in T1w space. """ from niworkflows.interfaces.nibabel import ApplyMask from niworkflows.interfaces.utility import KeySelect @@ -338,6 +342,8 @@ def init_anat_derivatives_wf( "surfaces", "t1w_fs_aseg", "t1w_fs_aparc", + "t2w_source_files", + "t2w_preproc", ] ), name="inputnode", @@ -366,6 +372,12 @@ def init_anat_derivatives_wf( run_without_submitting=True, ) + ds_t2w_preproc = pe.Node( + DerivativesDataSink(base_directory=output_dir, space="T1w", desc="preproc", compress=True), + name="ds_t2w_preproc", + run_without_submitting=True, + ) + ds_t1w_tpms = pe.Node( DerivativesDataSink(base_directory=output_dir, suffix="probseg", compress=True), name="ds_t1w_tpms", @@ -378,6 +390,8 @@ def init_anat_derivatives_wf( (inputnode, raw_sources, [('source_files', 'in_files')]), (inputnode, ds_t1w_preproc, [('t1w_preproc', 'in_file'), ('source_files', 'source_file')]), + (inputnode, ds_t2w_preproc, [('t2w_preproc', 'in_file'), + ('t2w_source_files', 'source_file')]), (inputnode, ds_t1w_mask, [('t1w_mask', 'in_file'), ('source_files', 'source_file')]), (inputnode, ds_t1w_tpms, [('t1w_tpms', 'in_file'), From 2e204add5f2ca96c6f8388361d1b9022dbf72f06 Mon Sep 17 00:00:00 2001 From: Greg Conan Date: Fri, 9 Dec 2022 17:14:51 -0600 Subject: [PATCH 2/4] Added T2w vol in T1w space to .circleci expected output list files --- .circleci/bcp_anat_outputs.txt | 1 + .circleci/bcp_full_outputs.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/.circleci/bcp_anat_outputs.txt b/.circleci/bcp_anat_outputs.txt index 10b5bb15..5593c49c 100644 --- a/.circleci/bcp_anat_outputs.txt +++ b/.circleci/bcp_anat_outputs.txt @@ -41,3 +41,4 @@ sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-MNIInfant_cohort-1_dseg.nii.gz sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-MNIInfant_cohort-1_label-CSF_probseg.nii.gz sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-MNIInfant_cohort-1_label-GM_probseg.nii.gz sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-MNIInfant_cohort-1_label-WM_probseg.nii.gz +sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-T1w_desc-preproc_T2w.nii.gz diff --git a/.circleci/bcp_full_outputs.txt b/.circleci/bcp_full_outputs.txt index 9a253c1a..ab8b55d4 100644 --- a/.circleci/bcp_full_outputs.txt +++ b/.circleci/bcp_full_outputs.txt @@ -41,6 +41,7 @@ sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-MNIInfant_cohort-1_dseg.nii.gz sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-MNIInfant_cohort-1_label-CSF_probseg.nii.gz sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-MNIInfant_cohort-1_label-GM_probseg.nii.gz sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-MNIInfant_cohort-1_label-WM_probseg.nii.gz +sub-01/ses-1mo/anat/sub-01_ses-1mo_run-001_space-T1w_desc-preproc_T2w.nii.gz sub-01/ses-1mo/fmap sub-01/ses-1mo/fmap/sub-01_ses-1mo_run-001_fmapid-auto00000_desc-coeff_fieldmap.nii.gz sub-01/ses-1mo/fmap/sub-01_ses-1mo_run-001_fmapid-auto00000_desc-epi_fieldmap.nii.gz From d139112d041ea0a02f9cc617bb6d09cc3474df78 Mon Sep 17 00:00:00 2001 From: madisoth Date: Mon, 9 Jan 2023 15:43:11 -0600 Subject: [PATCH 3/4] use SDCFlows brain extraction workflow for T2w when T1w has precomputed mask --- nibabies/workflows/anatomical/base.py | 38 ++++++++++++++++-------- nibabies/workflows/anatomical/outputs.py | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/nibabies/workflows/anatomical/base.py b/nibabies/workflows/anatomical/base.py index 7dc13b9c..475f1b29 100644 --- a/nibabies/workflows/anatomical/base.py +++ b/nibabies/workflows/anatomical/base.py @@ -78,6 +78,8 @@ def init_infant_anat_wf( from nipype.interfaces.ants.base import Info as ANTsInfo from niworkflows.engine.workflows import LiterateWorkflow as Workflow + from sdcflows.workflows.ancillary import init_brainextraction_wf as init_sdc_brain_extraction_wf + from ...utils.misc import fix_multi_source_name from .brain_extraction import ( init_infant_brain_extraction_wf, @@ -214,8 +216,9 @@ def init_infant_anat_wf( if precomp_mask: precomp_mask_wf = init_precomputed_mask_wf(omp_nthreads=omp_nthreads) precomp_mask_wf.inputs.inputnode.t1w_mask = precomp_mask - - # else: brain_extraction_wf = ... + sdc_brain_extraction_wf = init_sdc_brain_extraction_wf( + name="sdc_brain_extraction_wf", + ) brain_extraction_wf = init_infant_brain_extraction_wf( age_months=age_months, ants_affine_init=ants_affine_init, @@ -307,22 +310,31 @@ def init_infant_anat_wf( (t1w_template_wf, precomp_mask_wf, [ ("outputnode.out_file", "inputnode.t1w"), ]), + (t2w_template_wf, sdc_brain_extraction_wf, [ + ("outputnode.out_file", "inputnode.in_file"), + ]), + (sdc_brain_extraction_wf, coregistration_wf, [ + ("outputnode.out_file", "inputnode.in_t2w_preproc"), + ("outputnode.out_mask", "inputnode.in_mask"), + ("outputnode.out_probseg", "inputnode.in_probmap"), + ]), + ]) + else: + wf.connect([ + (t2w_template_wf, brain_extraction_wf, [ + ("outputnode.out_file", "inputnode.in_t2w"), + ]), + (brain_extraction_wf, coregistration_wf, [ + ("outputnode.t2w_preproc", "inputnode.in_t2w_preproc"), + ("outputnode.out_mask", "inputnode.in_mask"), + ("outputnode.out_probmap", "inputnode.in_probmap"), + ]), ]) - - wf.connect([ - (t2w_template_wf, brain_extraction_wf, [ - ("outputnode.out_file", "inputnode.in_t2w"), - ]), - ]) wf.connect([ (t1w_template_wf, coregistration_wf, [ ("outputnode.out_file", "inputnode.in_t1w"), ]), - (brain_extraction_wf, coregistration_wf, [ - ("outputnode.t2w_preproc", "inputnode.in_t2w_preproc"), - ("outputnode.out_mask", "inputnode.in_mask"), - ("outputnode.out_probmap", "inputnode.in_probmap"), - ]), + (inputnode, coreg_report_wf, [ ("t1w", "inputnode.source_file"), ]), diff --git a/nibabies/workflows/anatomical/outputs.py b/nibabies/workflows/anatomical/outputs.py index 593ccab6..019fd51d 100644 --- a/nibabies/workflows/anatomical/outputs.py +++ b/nibabies/workflows/anatomical/outputs.py @@ -376,7 +376,7 @@ def init_anat_derivatives_wf( ) ds_t2w_preproc = pe.Node( - DerivativesDataSink(base_directory=output_dir, space="T1w", desc="preproc", compress=True), + DerivativesDataSink(data_dtype="i2", base_directory=output_dir, space="T1w", desc="preproc", compress=True), name="ds_t2w_preproc", run_without_submitting=True, ) From 0e2861f8d2b34d69aae731d58ed3151b94fd974a Mon Sep 17 00:00:00 2001 From: madisoth Date: Mon, 9 Jan 2023 15:45:21 -0600 Subject: [PATCH 4/4] use SDCFlows brain extraction workflow for T2w when T1w has precomputed mask --- nibabies/workflows/anatomical/base.py | 5 +++-- nibabies/workflows/anatomical/outputs.py | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/nibabies/workflows/anatomical/base.py b/nibabies/workflows/anatomical/base.py index 475f1b29..b05dc4ba 100644 --- a/nibabies/workflows/anatomical/base.py +++ b/nibabies/workflows/anatomical/base.py @@ -77,8 +77,9 @@ def init_infant_anat_wf( """ from nipype.interfaces.ants.base import Info as ANTsInfo from niworkflows.engine.workflows import LiterateWorkflow as Workflow - - from sdcflows.workflows.ancillary import init_brainextraction_wf as init_sdc_brain_extraction_wf + from sdcflows.workflows.ancillary import ( + init_brainextraction_wf as init_sdc_brain_extraction_wf, + ) from ...utils.misc import fix_multi_source_name from .brain_extraction import ( diff --git a/nibabies/workflows/anatomical/outputs.py b/nibabies/workflows/anatomical/outputs.py index 019fd51d..2931508a 100644 --- a/nibabies/workflows/anatomical/outputs.py +++ b/nibabies/workflows/anatomical/outputs.py @@ -313,7 +313,7 @@ def init_anat_derivatives_wf( t2w_source_files List of input T2w images t2w_preproc - The T2w image in T1w space. + The T2w image in T1w space. """ from niworkflows.interfaces.nibabel import ApplyMask from niworkflows.interfaces.utility import KeySelect @@ -376,7 +376,9 @@ def init_anat_derivatives_wf( ) ds_t2w_preproc = pe.Node( - DerivativesDataSink(data_dtype="i2", base_directory=output_dir, space="T1w", desc="preproc", compress=True), + DerivativesDataSink( + data_dtype="i2", base_directory=output_dir, space="T1w", desc="preproc", compress=True + ), name="ds_t2w_preproc", run_without_submitting=True, )