From 9665c3305917364a60007c160a1712eed8886244 Mon Sep 17 00:00:00 2001 From: David Meunier Date: Thu, 23 Nov 2023 11:04:50 +0100 Subject: [PATCH 1/6] adding stereo to spm_native pipeline --- macapype/pipelines/full_pipelines.py | 110 +++++++++++++++++++++- workflows/params_segment_macaque_spm.json | 16 ++++ workflows/segment_pnh.py | 1 + 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/macapype/pipelines/full_pipelines.py b/macapype/pipelines/full_pipelines.py index 5bc7d18dc..6d3809b40 100644 --- a/macapype/pipelines/full_pipelines.py +++ b/macapype/pipelines/full_pipelines.py @@ -52,6 +52,7 @@ def create_full_spm_subpipes( params_template, params_template_aladin, + params_template_stereo, params={}, name='full_spm_subpipes', pad=False, space='template'): """ Description: SPM based segmentation pipeline from T1w and T2w images @@ -130,7 +131,10 @@ def create_full_spm_subpipes( niu.IdentityInterface(fields=['brain_mask', 'segmented_brain_mask', 'debiased_T1', 'debiased_brain', "wmgm_stl", - 'prob_wm', 'prob_gm', 'prob_csf']), + 'prob_wm', 'prob_gm', 'prob_csf', + 'stereo_native_T1', 'stereo_debiased_T1', + 'stereo_brain_mask', 'stereo_segmented_brain_mask', + "native_to_stereo_trans"]), name='outputnode') # preprocessing if 'long_single_preparation_pipe' in params.keys(): @@ -234,6 +238,27 @@ def create_full_spm_subpipes( seg_pipe.connect(pad_debiased_T1, "padded_img_file", outputnode, "debiased_T1") + print("Padding debiased_T2 in native space") + pad_debiased_T2 = pe.Node( + niu.Function( + input_names=['cropped_img_file', 'orig_img_file', + 'indiv_crop'], + output_names=['padded_img_file'], + function=padding_cropped_img), + name="pad_debiased_T2") + + seg_pipe.connect(debias, 't2_debiased_file', + pad_debiased_T2, "cropped_img_file") + + seg_pipe.connect(data_preparation_pipe, "outputnode.native_T2", + pad_debiased_T2, "orig_img_file") + + seg_pipe.connect(inputnode, "indiv_params", + pad_debiased_T2, "indiv_crop") + + seg_pipe.connect(pad_debiased_T2, "padded_img_file", + outputnode, "debiased_T2") + print("Padding debiased_brain in native space") pad_debiased_brain = pe.Node( niu.Function( @@ -381,6 +406,68 @@ def create_full_spm_subpipes( seg_pipe.connect(debias, 't1_debiased_file', outputnode, "debiased_T1") + if "native_to_stereo_pipe" in params.keys(): + + native_to_stereo_pipe = create_native_to_stereo_pipe( + "native_to_stereo_pipe", + params=parse_key(params, "native_to_stereo_pipe")) + + seg_pipe.connect(native_to_stereo_pipe, + 'outputnode.native_to_stereo_trans', + outputnode, 'native_to_stereo_trans') + + # full head version + seg_pipe.connect(data_preparation_pipe, "outputnode.native_T1", + native_to_stereo_pipe, 'inputnode.native_T1') + + native_to_stereo_pipe.inputs.inputnode.stereo_T1 = \ + params_template_stereo["template_head"] + + seg_pipe.connect(native_to_stereo_pipe, + "outputnode.stereo_native_T1", + outputnode, "stereo_native_T1") + + seg_pipe.connect(native_to_stereo_pipe, + "outputnode.native_to_stereo_trans", + outputnode, "native_to_stereo_trans") + + if pad: + + # apply transfo to list + apply_stereo_mask = pe.Node(RegResample(inter_val="NN"), + name='apply_stereo_mask') + + seg_pipe.connect(pad_mask, 'out_file', + apply_stereo_mask, "flo_file") + seg_pipe.connect(native_to_stereo_pipe, + 'outputnode.native_to_stereo_trans', + apply_stereo_mask, "trans_file") + + seg_pipe.connect(native_to_stereo_pipe, + 'outputnode.padded_stereo_T1', + apply_stereo_mask, "ref_file") + + seg_pipe.connect(apply_stereo_mask, "out_file", + outputnode, "stereo_brain_mask") + + # apply transfo to list + apply_stereo_debiased_T1 = pe.Node(RegResample(), + name='apply_stereo_debiased_T1') + + seg_pipe.connect(pad_debiased_T1, 'out_file', + apply_stereo_debiased_T1, "flo_file") + + seg_pipe.connect(native_to_stereo_pipe, + 'outputnode.native_to_stereo_trans', + apply_stereo_debiased_T1, "trans_file") + + seg_pipe.connect(native_to_stereo_pipe, + 'outputnode.padded_stereo_T1', + apply_stereo_debiased_T1, "ref_file") + + seg_pipe.connect(apply_stereo_debiased_T1, "out_file", + outputnode, "stereo_debiased_T1") + # Iterative registration to the INIA19 template reg = NodeParams(IterREGBET(), params=parse_key(params, "reg"), @@ -755,11 +842,32 @@ def create_full_spm_subpipes( seg_pipe.connect(pad_seg_mask, "padded_img_file", outputnode, "segmented_brain_mask") + if "native_to_stereo_pipe" in params: + + # apply transfo to seg_mask + apply_stereo_seg_mask = pe.Node(RegResample(inter_val="NN"), + name='apply_stereo_seg_mask') + + seg_pipe.connect(pad_seg_mask, 'out_file', + apply_stereo_seg_mask, "flo_file") + seg_pipe.connect(native_to_stereo_pipe, + 'outputnode.native_to_stereo_trans', + apply_stereo_seg_mask, "trans_file") + seg_pipe.connect(native_to_stereo_pipe, + 'outputnode.padded_stereo_T1', + apply_stereo_seg_mask, "ref_file") + + seg_pipe.connect(apply_stereo_seg_mask, "out_file", + outputnode, "stereo_segmented_brain_mask") + else: seg_pipe.connect(mask_from_seg_pipe, 'merge_indexed_mask.indexed_mask', outputnode, 'segmented_brain_mask') +'stereo_segmented_brain_mask' + + # LEGACY if space == 'template': # not mandatory diff --git a/workflows/params_segment_macaque_spm.json b/workflows/params_segment_macaque_spm.json index 4c57c522e..da35aa30a 100644 --- a/workflows/params_segment_macaque_spm.json +++ b/workflows/params_segment_macaque_spm.json @@ -63,6 +63,22 @@ "kernel_size": 2 } }, + "native_to_stereo_pipe": + { + "pad_template_T1": + { + "pad_val": 20 + }, + "reg_T1_on_template": + { + "nac_flag": true, + "rig_only_flag":true, + "nosym_flag": true, + "ln_val" : 12, + "lp_val": 10, + "smoo_r_val" : 1.0 + } + }, "regex_subs": { "FLAIR_flirt": "preproc-coreg_FLAIR" diff --git a/workflows/segment_pnh.py b/workflows/segment_pnh.py index ef02442fb..8b6c50a2d 100644 --- a/workflows/segment_pnh.py +++ b/workflows/segment_pnh.py @@ -367,6 +367,7 @@ def create_main_workflow(data_dir, process_dir, soft, species, subjects, segment_pnh_pipe = create_full_spm_subpipes( params_template=params_template, params_template_aladin=params_template_aladin, + params_template_stereo=params_template_stereo, params=params, pad=pad, space=space) elif "ants" in ssoft: From e75ad6d990e0481094bec1e85d66410c3e4412ec Mon Sep 17 00:00:00 2001 From: David Meunier Date: Thu, 23 Nov 2023 11:13:58 +0100 Subject: [PATCH 2/6] typo --- macapype/pipelines/full_pipelines.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/macapype/pipelines/full_pipelines.py b/macapype/pipelines/full_pipelines.py index 6d3809b40..74b9d8350 100644 --- a/macapype/pipelines/full_pipelines.py +++ b/macapype/pipelines/full_pipelines.py @@ -859,14 +859,11 @@ def create_full_spm_subpipes( seg_pipe.connect(apply_stereo_seg_mask, "out_file", outputnode, "stereo_segmented_brain_mask") - else: seg_pipe.connect(mask_from_seg_pipe, 'merge_indexed_mask.indexed_mask', outputnode, 'segmented_brain_mask') -'stereo_segmented_brain_mask' - # LEGACY if space == 'template': From 0fbfc4fe96aab09405dec6c2ae1eb5d19e106b6d Mon Sep 17 00:00:00 2001 From: David Meunier Date: Thu, 23 Nov 2023 11:15:29 +0100 Subject: [PATCH 3/6] doublon --- macapype/pipelines/full_pipelines.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/macapype/pipelines/full_pipelines.py b/macapype/pipelines/full_pipelines.py index 74b9d8350..9a63d7fd7 100644 --- a/macapype/pipelines/full_pipelines.py +++ b/macapype/pipelines/full_pipelines.py @@ -427,10 +427,6 @@ def create_full_spm_subpipes( "outputnode.stereo_native_T1", outputnode, "stereo_native_T1") - seg_pipe.connect(native_to_stereo_pipe, - "outputnode.native_to_stereo_trans", - outputnode, "native_to_stereo_trans") - if pad: # apply transfo to list From 94902f4fd234e4308151153f3aa27be6a173ee63 Mon Sep 17 00:00:00 2001 From: David Meunier Date: Thu, 23 Nov 2023 11:29:34 +0100 Subject: [PATCH 4/6] rename stereo spm --- macapype/pipelines/rename.py | 118 ++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 31 deletions(-) diff --git a/macapype/pipelines/rename.py b/macapype/pipelines/rename.py index 7abd8af24..b6eb1f57b 100644 --- a/macapype/pipelines/rename.py +++ b/macapype/pipelines/rename.py @@ -315,6 +315,42 @@ def rename_all_derivatives(params, main_workflow, segment_pnh_pipe, rename_prob_csf, 'out_file', datasink, '@prob_csf') + if "mask_from_seg_pipe" in params.keys(): + + # rename segmented_brain_mask + rename_segmented_brain_mask = pe.Node( + niu.Rename(), + name="rename_segmented_brain_mask") + rename_segmented_brain_mask.inputs.format_string = \ + pref_deriv + "_space-{}_desc-brain_dseg".format(space) + rename_segmented_brain_mask.inputs.parse_string = parse_str + rename_segmented_brain_mask.inputs.keep_ext = True + + main_workflow.connect( + segment_pnh_pipe, 'outputnode.segmented_brain_mask', + rename_segmented_brain_mask, 'in_file') + + main_workflow.connect( + rename_segmented_brain_mask, 'out_file', + datasink, '@segmented_brain_mask') + + print("Renaming wmgm_stl file") + + rename_wmgm_stl = pe.Node(niu.Rename(), + name="rename_wmgm_stl") + rename_wmgm_stl.inputs.format_string = \ + pref_deriv + "_space-{}_desc-wmgm_mask".format(space) + rename_wmgm_stl.inputs.parse_string = parse_str + rename_wmgm_stl.inputs.keep_ext = True + + main_workflow.connect( + segment_pnh_pipe, 'outputnode.wmgm_stl', + rename_wmgm_stl, 'in_file') + + main_workflow.connect( + rename_wmgm_stl, 'out_file', + datasink, '@wmgm_stl') + if "native_to_stereo_pipe" in params.keys(): # rename stereo_native_T1 @@ -368,6 +404,41 @@ def rename_all_derivatives(params, main_workflow, segment_pnh_pipe, rename_stereo_debiased_T1, 'out_file', datasink, '@stereo_debiased_T1') + elif "debias" in params.keys(): + # rename stereo_brain_mask + rename_stereo_brain_mask = pe.Node( + niu.Rename(), + name="rename_stereo_brain_mask") + rename_stereo_brain_mask.inputs.format_string = \ + pref_deriv + "_space-stereo_desc-brain_mask" + rename_stereo_brain_mask.inputs.parse_string = parse_str + rename_stereo_brain_mask.inputs.keep_ext = True + + main_workflow.connect( + segment_pnh_pipe, 'outputnode.stereo_brain_mask', + rename_stereo_brain_mask, 'in_file') + + main_workflow.connect( + rename_stereo_brain_mask, 'out_file', + datasink, '@stereo_brain_mask') + + # rename stereo_debiased_T1 + rename_stereo_debiased_T1 = pe.Node( + niu.Rename(), + name="rename_stereo_debiased_T1") + rename_stereo_debiased_T1.inputs.format_string = \ + pref_deriv + "_space-stereo_desc-debiased_T1w" + rename_stereo_debiased_T1.inputs.parse_string = parse_str + rename_stereo_debiased_T1.inputs.keep_ext = True + + main_workflow.connect( + segment_pnh_pipe, 'outputnode.stereo_debiased_T1', + rename_stereo_debiased_T1, 'in_file') + + main_workflow.connect( + rename_stereo_debiased_T1, 'out_file', + datasink, '@stereo_debiased_T1') + if "brain_segment_pipe" in params.keys(): # rename stereo_segmented_brain_mask @@ -440,38 +511,23 @@ def rename_all_derivatives(params, main_workflow, segment_pnh_pipe, rename_stereo_prob_csf, 'out_file', datasink, '@stereo_prob_csf') - if "mask_from_seg_pipe" in params.keys(): - - # rename segmented_brain_mask - rename_segmented_brain_mask = pe.Node( - niu.Rename(), - name="rename_segmented_brain_mask") - rename_segmented_brain_mask.inputs.format_string = \ - pref_deriv + "_space-{}_desc-brain_dseg".format(space) - rename_segmented_brain_mask.inputs.parse_string = parse_str - rename_segmented_brain_mask.inputs.keep_ext = True - - main_workflow.connect( - segment_pnh_pipe, 'outputnode.segmented_brain_mask', - rename_segmented_brain_mask, 'in_file') - - main_workflow.connect( - rename_segmented_brain_mask, 'out_file', - datasink, '@segmented_brain_mask') + elif "mask_from_seg_pipe" in params: + # rename stereo_segmented_brain_mask + rename_stereo_segmented_brain_mask = pe.Node( + niu.Rename(), + name="rename_stereo_segmented_brain_mask") - print("Renaming wmgm_stl file") + rename_stereo_segmented_brain_mask.inputs.format_string =\ + pref_deriv + "_space-stereo_desc-brain_dseg" + rename_stereo_segmented_brain_mask.inputs.parse_string = \ + parse_str + rename_stereo_segmented_brain_mask.inputs.keep_ext = True - rename_wmgm_stl = pe.Node(niu.Rename(), - name="rename_wmgm_stl") - rename_wmgm_stl.inputs.format_string = \ - pref_deriv + "_space-{}_desc-wmgm_mask".format(space) - rename_wmgm_stl.inputs.parse_string = parse_str - rename_wmgm_stl.inputs.keep_ext = True + main_workflow.connect( + segment_pnh_pipe, 'outputnode.stereo_segmented_brain_mask', + rename_stereo_segmented_brain_mask, 'in_file') - main_workflow.connect( - segment_pnh_pipe, 'outputnode.wmgm_stl', - rename_wmgm_stl, 'in_file') + main_workflow.connect( + rename_stereo_segmented_brain_mask, 'out_file', + datasink, '@stereo_segmented_brain_mask') - main_workflow.connect( - rename_wmgm_stl, 'out_file', - datasink, '@wmgm_stl') From 0056ff7fafdbd9479734a6aca8ebe789eb1cbacd Mon Sep 17 00:00:00 2001 From: David Meunier Date: Thu, 23 Nov 2023 11:36:28 +0100 Subject: [PATCH 5/6] flake8 --- macapype/pipelines/full_pipelines.py | 3 ++- macapype/pipelines/rename.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/macapype/pipelines/full_pipelines.py b/macapype/pipelines/full_pipelines.py index 9a63d7fd7..ee06d4d28 100644 --- a/macapype/pipelines/full_pipelines.py +++ b/macapype/pipelines/full_pipelines.py @@ -133,7 +133,8 @@ def create_full_spm_subpipes( "wmgm_stl", 'prob_wm', 'prob_gm', 'prob_csf', 'stereo_native_T1', 'stereo_debiased_T1', - 'stereo_brain_mask', 'stereo_segmented_brain_mask', + 'stereo_brain_mask', + 'stereo_segmented_brain_mask', "native_to_stereo_trans"]), name='outputnode') # preprocessing diff --git a/macapype/pipelines/rename.py b/macapype/pipelines/rename.py index b6eb1f57b..1c9dc86da 100644 --- a/macapype/pipelines/rename.py +++ b/macapype/pipelines/rename.py @@ -530,4 +530,3 @@ def rename_all_derivatives(params, main_workflow, segment_pnh_pipe, main_workflow.connect( rename_stereo_segmented_brain_mask, 'out_file', datasink, '@stereo_segmented_brain_mask') - From 29773247c723bdf8bf9f6ef35f7cacadafaee3af Mon Sep 17 00:00:00 2001 From: David Meunier Date: Thu, 23 Nov 2023 11:43:09 +0100 Subject: [PATCH 6/6] params_template_stereo in spm pipeline --- macapype/pipelines/tests/test_full_pipelines.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/macapype/pipelines/tests/test_full_pipelines.py b/macapype/pipelines/tests/test_full_pipelines.py index f923bfb3f..db7a1d5eb 100644 --- a/macapype/pipelines/tests/test_full_pipelines.py +++ b/macapype/pipelines/tests/test_full_pipelines.py @@ -181,7 +181,8 @@ def test_create_full_spm_subpipes_all_default_params(): # running workflow segment_pnh = create_full_spm_subpipes( params=params, params_template=params_template, - params_template_aladin=params_template, space=space, + params_template_aladin=params_template, + params_template_stereo=params_template, space=space, name="test_create_full_ants_subpipes_all_default_params") segment_pnh.base_dir = data_path