diff --git a/macapype/nodes/correct_bias.py b/macapype/nodes/correct_bias.py index e9f459758..48ada0a53 100644 --- a/macapype/nodes/correct_bias.py +++ b/macapype/nodes/correct_bias.py @@ -258,4 +258,4 @@ def itk_debias(img_file): mask_img_file = os.path.abspath(fname + "_mask" + ext) sitk.WriteImage(input_image_mask, mask_img_file) - return cor_img_file, bias_img_file + return cor_img_file, bias_img_file, mask_img_file diff --git a/macapype/nodes/prepare.py b/macapype/nodes/prepare.py index 1c7d7ee7b..904836f41 100644 --- a/macapype/nodes/prepare.py +++ b/macapype/nodes/prepare.py @@ -273,7 +273,7 @@ def _list_outputs(self): ############################################################################### # Equivalent of flirt_average in FSL -def average_align(list_img, reorient=False): +def average_align(list_img, reorient=False, max_index=None): import os import nibabel as nib @@ -299,7 +299,16 @@ def average_align(list_img, reorient=False): data_0_shape = data_0.shape list_data = [data_0] - for i, img in enumerate(list_img[1:]): + if max_index is not None: + assert max_index < len(list_img), f"Error with {max_index=}" + + for i, img in enumerate(list_img[1:], 1): + + if max_index is not None: + if i > max_index: + print(f"Iter {i=} higher than {max_index=}") + continue + data_orig_shape = nib.load(img).get_fdata().shape if data_orig_shape != data_0_shape: print(f"**** Warning , original image shape \ diff --git a/macapype/pipelines/prepare.py b/macapype/pipelines/prepare.py index bf40dcfdb..0c6c154ca 100644 --- a/macapype/pipelines/prepare.py +++ b/macapype/pipelines/prepare.py @@ -588,13 +588,25 @@ def create_short_preparation_pipe(params, params_template={}, N4debias_T2, "indiv_params") # outputnode - data_preparation_pipe.connect( - N4debias_T1, "output_image", - outputnode, "stereo_debiased_T1") + if "use_T2" in params.keys(): - data_preparation_pipe.connect( - N4debias_T2, "output_image", - outputnode, "stereo_debiased_T2") + data_preparation_pipe.connect( + N4debias_T1, "output_image", + outputnode, "stereo_debiased_T2") + + data_preparation_pipe.connect( + N4debias_T2, "output_image", + outputnode, "stereo_debiased_T1") + + else: + + data_preparation_pipe.connect( + N4debias_T1, "output_image", + outputnode, "stereo_debiased_T1") + + data_preparation_pipe.connect( + N4debias_T2, "output_image", + outputnode, "stereo_debiased_T2") elif "fast" in params.keys(): @@ -647,13 +659,26 @@ def create_short_preparation_pipe(params, params_template={}, fast_T2, "indiv_params") # outputnode - data_preparation_pipe.connect( - fast_T1, "restored_image", - outputnode, "stereo_debiased_T1") - data_preparation_pipe.connect( - fast_T2, "restored_image", - outputnode, "stereo_debiased_T2") + if "use_T2" in params.keys(): + + data_preparation_pipe.connect( + fast_T1, "restored_image", + outputnode, "stereo_debiased_T2") + + data_preparation_pipe.connect( + fast_T2, "restored_image", + outputnode, "stereo_debiased_T1") + + else: + + data_preparation_pipe.connect( + fast_T1, "restored_image", + outputnode, "stereo_debiased_T1") + + data_preparation_pipe.connect( + fast_T2, "restored_image", + outputnode, "stereo_debiased_T2") elif "itk_debias" in params: @@ -663,7 +688,7 @@ def create_short_preparation_pipe(params, params_template={}, itk_debias_T1 = NodeParams( interface=niu.Function( input_names=["img_file"], - output_names=["cor_img_file", "bias_img_file"], + output_names=["cor_img_file", "bias_img_file", "mask_file"], function=itk_debias), params=parse_key(params, "itk_debias"), name='itk_debias_T1') @@ -681,7 +706,7 @@ def create_short_preparation_pipe(params, params_template={}, itk_debias_T2 = NodeParams( interface=niu.Function( input_names=["img_file"], - output_names=["cor_img_file", "bias_img_file"], + output_names=["cor_img_file", "bias_img_file", "mask_file"], function=itk_debias), params=parse_key(params, "itk_debias"), name='itk_debias_T2') @@ -696,34 +721,72 @@ def create_short_preparation_pipe(params, params_template={}, itk_debias_T2, "img_file") # outputnode - data_preparation_pipe.connect( - itk_debias_T1, "cor_img_file", - outputnode, "stereo_debiased_T1") - data_preparation_pipe.connect( - itk_debias_T2, "cor_img_file", - outputnode, "stereo_debiased_T2") + if "use_T2" in params.keys(): - else: - print("No debias will be performed before extract_pipe") + data_preparation_pipe.connect( + itk_debias_T1, "cor_img_file", + outputnode, "stereo_debiased_T2") - if "denoise" in params.keys(): data_preparation_pipe.connect( - denoise_T1, "output_image", + itk_debias_T2, "cor_img_file", outputnode, "stereo_debiased_T1") - data_preparation_pipe.connect( - denoise_T2, "output_image", - outputnode, "stereo_debiased_T2") else: + data_preparation_pipe.connect( - crop_aladin_pipe, "outputnode.stereo_T1", + itk_debias_T1, "cor_img_file", outputnode, "stereo_debiased_T1") data_preparation_pipe.connect( - apply_crop_aladin_T2, 'out_file', + itk_debias_T2, "cor_img_file", outputnode, "stereo_debiased_T2") + else: + print("No debias will be performed before extract_pipe") + + if "denoise" in params.keys(): + + if "use_T2" in params.keys(): + + data_preparation_pipe.connect( + denoise_T1, "output_image", + outputnode, "stereo_debiased_T2") + + data_preparation_pipe.connect( + denoise_T2, "output_image", + outputnode, "stereo_debiased_T1") + else: + + data_preparation_pipe.connect( + denoise_T1, "output_image", + outputnode, "stereo_debiased_T1") + + data_preparation_pipe.connect( + denoise_T2, "output_image", + outputnode, "stereo_debiased_T2") + + else: + + if "use_T2" in params.keys(): + + data_preparation_pipe.connect( + crop_aladin_pipe, "outputnode.stereo_T1", + outputnode, "stereo_debiased_T2") + + data_preparation_pipe.connect( + apply_crop_aladin_T2, 'out_file', + outputnode, "stereo_debiased_T1") + else: + + data_preparation_pipe.connect( + crop_aladin_pipe, "outputnode.stereo_T1", + outputnode, "stereo_debiased_T1") + + data_preparation_pipe.connect( + apply_crop_aladin_T2, 'out_file', + outputnode, "stereo_debiased_T2") + # resample T1 to higher dimension if "pad_template" in params.keys(): diff --git a/macapype/pipelines/segment.py b/macapype/pipelines/segment.py index 4b12e1a72..b6ac190f5 100644 --- a/macapype/pipelines/segment.py +++ b/macapype/pipelines/segment.py @@ -375,16 +375,6 @@ def create_segment_atropos_pipe(params={}, name="segment_atropos_pipe"): seg_at.inputs.prior_weight = params["use_priors"] - # split dseg_mask - split_dseg_mask = pe.Node( - interface=niu.Function(input_names=["nii_file"], - output_names=["list_split_files"], - function=split_indexed_mask), - name="split_dseg_mask") - - segment_pipe.connect(seg_at, 'segmented_file', - split_dseg_mask, "nii_file") - # on segmentation indexed mask (with labels) outputnode = pe.Node( niu.IdentityInterface( @@ -396,6 +386,16 @@ def create_segment_atropos_pipe(params={}, name="segment_atropos_pipe"): segment_pipe.connect(seg_at, 'segmented_file', outputnode, 'segmented_file') + # split dseg_mask + split_dseg_mask = pe.Node( + interface=niu.Function(input_names=["nii_file"], + output_names=["list_split_files"], + function=split_indexed_mask), + name="split_dseg_mask") + + segment_pipe.connect(seg_at, 'segmented_file', + split_dseg_mask, "nii_file") + if "tissue_dict" in params.keys(): tissue_dict = params["tissue_dict"] diff --git a/macapype/pipelines/surface.py b/macapype/pipelines/surface.py index 8883de127..fdc7f795b 100644 --- a/macapype/pipelines/surface.py +++ b/macapype/pipelines/surface.py @@ -944,35 +944,52 @@ def create_open_IsoSurface_tissues_pipe(params={}, IsoSurface_tissues_pipe.connect(inputnode, 'threshold_wm', bin_wm, 'in_file') - # wm_dilate - wm_dilate = NodeParams( - interface=DilateImage(), - params=parse_key(params, "wm_dilate"), - name="wm_dilate") + if "wm_dilate" in params and "wm_erode" in params: - IsoSurface_tissues_pipe.connect( - bin_wm, 'out_file', - wm_dilate, "in_file") + # wm_erode + wm_erode = NodeParams( + interface=ErodeImage(), + params=parse_key(params, "wm_erode"), + name="wm_erode") - # keep_gcc_wm_mask - keep_gcc_wm_mask = pe.Node( - interface=niu.Function(input_names=["nii_file"], - output_names=["gcc_nii_file"], - function=keep_gcc), - name="keep_gcc_wm_mask") + IsoSurface_tissues_pipe.connect( + bin_wm, 'out_file', + wm_erode, "in_file") - IsoSurface_tissues_pipe.connect(wm_dilate, 'out_file', - keep_gcc_wm_mask, "nii_file") + # wm_keep_gcc + wm_keep_gcc = pe.Node( + interface=niu.Function( + input_names=["nii_file"], + output_names=["gcc_nii_file"], + function=keep_gcc), + name="wm_keep_gcc") - # wm_erode - wm_erode = NodeParams( - interface=ErodeImage(), - params=parse_key(params, "wm_erode"), - name="wm_erode") + IsoSurface_tissues_pipe.connect( + wm_erode, 'out_file', + wm_keep_gcc, "nii_file") - IsoSurface_tissues_pipe.connect( - keep_gcc_wm_mask, "gcc_nii_file", - wm_erode, "in_file") + # wm_dilate + wm_dilate = NodeParams( + interface=DilateImage(), + params=parse_key(params, "wm_dilate"), + name="wm_dilate") + + IsoSurface_tissues_pipe.connect( + wm_keep_gcc, 'gcc_nii_file', + wm_dilate, "in_file") + else: + + # wm_keep_gcc + wm_keep_gcc = pe.Node( + interface=niu.Function( + input_names=["nii_file"], + output_names=["gcc_nii_file"], + function=keep_gcc), + name="wm_keep_gcc") + + IsoSurface_tissues_pipe.connect( + bin_wm, 'out_file', + wm_keep_gcc, "nii_file") # wm2mesh wm2mesh = NodeParams( @@ -980,8 +997,15 @@ def create_open_IsoSurface_tissues_pipe(params={}, params=parse_key(params, "wm2mesh"), name="wm2mesh") - IsoSurface_tissues_pipe.connect(wm_erode, 'out_file', - wm2mesh, "nii_file") + if "wm_dilate" in params and "wm_erode" in params: + IsoSurface_tissues_pipe.connect( + wm_dilate, "out_file", + wm2mesh, "nii_file") + + else: + IsoSurface_tissues_pipe.connect( + wm_keep_gcc, 'gcc_nii_file', + wm2mesh, "nii_file") # ######### csf mesh # bin_csf @@ -991,35 +1015,52 @@ def create_open_IsoSurface_tissues_pipe(params={}, IsoSurface_tissues_pipe.connect(inputnode, 'threshold_csf', bin_csf, 'in_file') - # csf_dilate - csf_dilate = NodeParams( - interface=DilateImage(), - params=parse_key(params, "csf_dilate"), - name="csf_dilate") + if "csf_dilate" in params and "csf_erode" in params: - IsoSurface_tissues_pipe.connect( - bin_csf, 'out_file', - csf_dilate, "in_file") + # csf_erode + csf_erode = NodeParams( + interface=ErodeImage(), + params=parse_key(params, "csf_erode"), + name="csf_erode") - # keep_gcc_csf_mask - keep_gcc_csf_mask = pe.Node( - interface=niu.Function(input_names=["nii_file"], - output_names=["gcc_nii_file"], - function=keep_gcc), - name="keep_gcc_csf_mask") + IsoSurface_tissues_pipe.connect( + bin_csf, 'out_file', + csf_erode, "in_file") - IsoSurface_tissues_pipe.connect(csf_dilate, 'out_file', - keep_gcc_csf_mask, "nii_file") + # csf_keep_gcc + csf_keep_gcc = pe.Node( + interface=niu.Function( + input_names=["nii_file"], + output_names=["gcc_nii_file"], + function=keep_gcc), + name="csf_keep_gcc") - # csf_erode - csf_erode = NodeParams( - interface=ErodeImage(), - params=parse_key(params, "csf_erode"), - name="csf_erode") + IsoSurface_tissues_pipe.connect( + csf_erode, 'out_file', + csf_keep_gcc, "nii_file") - IsoSurface_tissues_pipe.connect( - keep_gcc_csf_mask, "gcc_nii_file", - csf_erode, "in_file") + # csf_dilate + csf_dilate = NodeParams( + interface=DilateImage(), + params=parse_key(params, "csf_dilate"), + name="csf_dilate") + + IsoSurface_tissues_pipe.connect( + csf_keep_gcc, 'gcc_nii_file', + csf_dilate, "in_file") + else: + + # csf_keep_gcc + csf_keep_gcc = pe.Node( + interface=niu.Function( + input_names=["nii_file"], + output_names=["gcc_nii_file"], + function=keep_gcc), + name="csf_keep_gcc") + + IsoSurface_tissues_pipe.connect( + bin_csf, 'out_file', + csf_keep_gcc, "nii_file") # csf2mesh csf2mesh = NodeParams( @@ -1027,8 +1068,15 @@ def create_open_IsoSurface_tissues_pipe(params={}, params=parse_key(params, "csf2mesh"), name="csf2mesh") - IsoSurface_tissues_pipe.connect(csf_erode, 'out_file', - csf2mesh, "nii_file") + if "csf_dilate" in params and "csf_erode" in params: + IsoSurface_tissues_pipe.connect( + csf_dilate, "out_file", + csf2mesh, "nii_file") + + else: + IsoSurface_tissues_pipe.connect( + csf_keep_gcc, 'gcc_nii_file', + csf2mesh, "nii_file") # ######### gm mesh # bin_gm @@ -1038,35 +1086,52 @@ def create_open_IsoSurface_tissues_pipe(params={}, IsoSurface_tissues_pipe.connect(inputnode, 'threshold_gm', bin_gm, 'in_file') - # gm_dilate - gm_dilate = NodeParams( - interface=DilateImage(), - params=parse_key(params, "gm_dilate"), - name="gm_dilate") + if "gm_dilate" in params and "gm_erode" in params: - IsoSurface_tissues_pipe.connect( - bin_gm, 'out_file', - gm_dilate, "in_file") + # gm_erode + gm_erode = NodeParams( + interface=ErodeImage(), + params=parse_key(params, "gm_erode"), + name="gm_erode") - # keep_gcc_gm_mask - keep_gcc_gm_mask = pe.Node( - interface=niu.Function(input_names=["nii_file"], - output_names=["gcc_nii_file"], - function=keep_gcc), - name="keep_gcc_gm_mask") + IsoSurface_tissues_pipe.connect( + bin_gm, 'out_file', + gm_erode, "in_file") - IsoSurface_tissues_pipe.connect(gm_dilate, 'out_file', - keep_gcc_gm_mask, "nii_file") + # keep_gcc_bin_mask + gm_keep_gcc = pe.Node( + interface=niu.Function( + input_names=["nii_file"], + output_names=["gcc_nii_file"], + function=keep_gcc), + name="gm_keep_gcc") - # gm_erode - gm_erode = NodeParams( - interface=ErodeImage(), - params=parse_key(params, "gm_erode"), - name="gm_erode") + IsoSurface_tissues_pipe.connect( + gm_erode, 'out_file', + gm_keep_gcc, "nii_file") - IsoSurface_tissues_pipe.connect( - keep_gcc_gm_mask, "gcc_nii_file", - gm_erode, "in_file") + # gm_dilate + gm_dilate = NodeParams( + interface=DilateImage(), + params=parse_key(params, "gm_dilate"), + name="gm_dilate") + + IsoSurface_tissues_pipe.connect( + gm_keep_gcc, 'gcc_nii_file', + gm_dilate, "in_file") + else: + + # gm_keep_gcc + gm_keep_gcc = pe.Node( + interface=niu.Function( + input_names=["nii_file"], + output_names=["gcc_nii_file"], + function=keep_gcc), + name="gm_keep_gcc") + + IsoSurface_tissues_pipe.connect( + bin_gm, 'out_file', + gm_keep_gcc, "nii_file") # gm2mesh gm2mesh = NodeParams( @@ -1074,8 +1139,15 @@ def create_open_IsoSurface_tissues_pipe(params={}, params=parse_key(params, "gm2mesh"), name="gm2mesh") - IsoSurface_tissues_pipe.connect(gm_erode, 'out_file', - gm2mesh, "nii_file") + if "gm_dilate" in params and "gm_erode" in params: + IsoSurface_tissues_pipe.connect( + gm_dilate, "out_file", + gm2mesh, "nii_file") + + else: + IsoSurface_tissues_pipe.connect( + gm_keep_gcc, 'gcc_nii_file', + gm2mesh, "nii_file") # ####outputnode outputnode = pe.Node( diff --git a/macapype/utils/utils_params.py b/macapype/utils/utils_params.py index 8612a3545..000bb1d8a 100644 --- a/macapype/utils/utils_params.py +++ b/macapype/utils/utils_params.py @@ -190,70 +190,73 @@ def update_params(ssoft=[], subjects=None, sessions=None, params["short_preparation_pipe"]["N4debias"] = params["N4debias"] del params["N4debias"] - # ANTS - if "ants" in ssoft: - print("Found ants in soft") - - if "noseg" in ssoft: - print("Found noseg in soft") - if "brain_segment_pipe" in params.keys(): - del params["brain_segment_pipe"] - print("Deleting brain_segment_pipe") - - if "prep" in ssoft: - print("Found prep in soft") - - # brain mask - if "extract_pipe" in params.keys(): - del params["extract_pipe"] - print("Deleting extract_pipe") - - # masked debias - if "masked_correct_bias_pipe" in params.keys(): - del params["masked_correct_bias_pipe"] - print("Deleting masked_correct_bias_pipe") - - if "debias" in params.keys(): - del params["debias"] - print("Deleting debias") - - # segment - if "brain_segment_pipe" in params.keys(): - del params["brain_segment_pipe"] - print("Deleting brain_segment_pipe") - - # SPM - if "spm" in ssoft: - print("Found spm in soft") - - if "noseg" in ssoft: - print("Found noseg in soft") - if "old_segment_pipe" in params.keys(): - del params["old_segment_pipe"] - print("Deleting old_segment_pipe") - - if "mask_from_seg_pipe" in params.keys(): - del params["mask_from_seg_pipe"] - print("Deleting mask_from_seg_pipe") - - if "prep" in ssoft: - print("Found prep in soft") - - if "debias" in params.keys(): - del params["debias"] - print("Deleting debias") - - if "reg" in params.keys(): - del params["reg"] - print("Deleting debias") - - if "old_segment_pipe" in params.keys(): - del params["old_segment_pipe"] - print("Deleting old_segment_pipe") - - if "mask_from_seg_pipe" in params.keys(): - del params["mask_from_seg_pipe"] - print("Deleting mask_from_seg_pipe") + if "noseg" in ssoft: + print("Found noseg in soft") + if "brain_segment_pipe" in params.keys(): + del params["brain_segment_pipe"] + print("Deleting brain_segment_pipe") + + if "old_segment_pipe" in params.keys(): + del params["old_segment_pipe"] + print("Deleting old_segment_pipe") + + if "mask_from_seg_pipe" in params.keys(): + del params["mask_from_seg_pipe"] + print("Deleting mask_from_seg_pipe") + + if "IsoSurface_brain_pipe" in params.keys(): + del params["IsoSurface_brain_pipe"] + print("Deleting IsoSurface_brain_pipe") + + if "IsoSurface_tissues_pipe" in params.keys(): + del params["IsoSurface_tissues_pipe"] + print("Deleting IsoSurface_tissues_pipe") + + if "export_5tt_pipe" in params.keys(): + del params["export_5tt_pipe"] + print("Deleting export_5tt_pipe") + + if "prep" in ssoft: + print("Found prep in soft") + + # brain mask + if "extract_pipe" in params.keys(): + del params["extract_pipe"] + print("Deleting extract_pipe") + + # masked debias + if "masked_correct_bias_pipe" in params.keys(): + del params["masked_correct_bias_pipe"] + print("Deleting masked_correct_bias_pipe") + + if "debias" in params.keys(): + del params["debias"] + print("Deleting debias") + + # segment + if "brain_segment_pipe" in params.keys(): + del params["brain_segment_pipe"] + print("Deleting brain_segment_pipe") + + if "old_segment_pipe" in params.keys(): + del params["old_segment_pipe"] + print("Deleting old_segment_pipe") + + if "mask_from_seg_pipe" in params.keys(): + del params["mask_from_seg_pipe"] + print("Deleting mask_from_seg_pipe") + + if "IsoSurface_brain_pipe" in params.keys(): + del params["IsoSurface_brain_pipe"] + print("Deleting IsoSurface_brain_pipe") + + if "IsoSurface_tissues_pipe" in params.keys(): + del params["IsoSurface_tissues_pipe"] + print("Deleting IsoSurface_tissues_pipe") + + if "export_5tt_pipe" in params.keys(): + del params["export_5tt_pipe"] + print("Deleting export_5tt_pipe") print("After modif, running with params:") pprint.pprint(params) diff --git a/workflows/params_segment_marmo_ants.json b/workflows/params_segment_marmo_ants.json index 28c76b18c..b7a9e63c7 100644 --- a/workflows/params_segment_marmo_ants.json +++ b/workflows/params_segment_marmo_ants.json @@ -1,7 +1,7 @@ { "general": { - "template_name": "MBM_v3.0.1_6seg" + "template_name": "MBM_v3.0.1_6seg_stereoINT" }, "short_preparation_pipe": { @@ -73,5 +73,8 @@ { "keep_indexes": [1,2,3] } + }, + "IsoSurface_tissues_pipe": + { } } diff --git a/workflows/params_segment_marmo_ants_4animal.json b/workflows/params_segment_marmo_ants_4animal.json index 28affbcd8..b96d603f4 100644 --- a/workflows/params_segment_marmo_ants_4animal.json +++ b/workflows/params_segment_marmo_ants_4animal.json @@ -1,7 +1,7 @@ { "general": { - "template_name": "MBM_v3.0.1_6seg" + "template_name": "MBM_v3.0.1_6seg_stereoINT" }, "short_preparation_pipe": { diff --git a/workflows/params_segment_marmot2_ants_4animal.json b/workflows/params_segment_marmot2_ants_4animal.json new file mode 100644 index 000000000..6219923db --- /dev/null +++ b/workflows/params_segment_marmot2_ants_4animal.json @@ -0,0 +1,77 @@ +{ + "general": + { + "template_name": "MBM_v3.0.1_6seg", + "template_stereo_name": "bma-1_0p2mm" + }, + "short_preparation_pipe": + { + "use_T2": {}, + "crop_aladin_pipe": + { + "remove_capsule_pipe":{}, + + "reg_T1_on_template": + { + "rig_only_flag":true + }, + "reg_T1_on_template2": + { + "rig_only_flag":true + } + }, + "denoise": + { + }, + "fast": + { + "args": "-l 3" + } + }, + "extract_pipe": + { + "bet4animal": + { + "label": 3, + "f": 0.25, + "robust": false + } + }, + "debias": + { + "s": 4 + }, + "brain_segment_pipe": + { + "reg": + { + "n": 2, + "m": "ref", + "dof": 12 + }, + "segment_atropos_pipe": + { + "use_priors": 0.0, + "Atropos": + { + "dimension": 3 + }, + "tissue_dict": + { + "gm": [1,2], + "wm": 3, + "csf": 4 + } + } + }, + "export_5tt_pipe": + { + }, + "IsoSurface_brain_pipe": + { + "merge_brain_tissues": + { + "keep_indexes": [1,2,3] + } + } +}