Source code for PUMI.pipelines.anat.func_to_anat

from nipype.interfaces.utility import Function
from PUMI.engine import NestedNode as Node, AnatPipeline
from PUMI.pipelines.multimodal.image_manipulation import pick_volume, vol2png
from nipype.interfaces import fsl


[docs]@AnatPipeline(inputspec_fields=['func', 'head', 'anat_wm_segmentation', 'anat_gm_segmentation', 'anat_csf_segmentation', 'anat_ventricle_segmentation'], outputspec_fields=['func_sample2anat', 'example_func', 'func_to_anat_linear_xfm', 'anat_to_func_linear_xfm', 'csf_mask_in_funcspace', 'csf_mask_in_funcspace', 'csf_mask_in_funcspace', 'ventricle_mask_in_funcspace', 'wm_mask_in_funcspace', 'gm_mask_in_funcspace']) def bbr(wf, **kwargs): """ BBR registration of functional image to anat. Inputs: func (str): One volume of the 4D fMRI (The one which is the closest to the fieldmap recording in time should be chosen e.g: if fieldmap was recorded after the fMRI the last volume of it should be chosen) head (str): The oriented T1w image. anat_wm_segmentation (str): WM probability mask anat_gm_segmentation (str): GM probability mask anat_csf_segmentation (str): CSF probability mask Acknowledgements: Adapted from Balint Kincses (2018) code. Modified version of CPAC.registration.registration (https://github.com/FCP-INDI/C-PAC/blob/main/CPAC/registration/registration.py) """ myonevol = pick_volume('myonevol') # trilinear interpolation is used by default in linear registration for func to anat linear_func_to_anat = Node(interface=fsl.FLIRT(), name='linear_func_to_anat') linear_func_to_anat.inputs.cost = 'corratio' linear_func_to_anat.inputs.dof = 6 linear_func_to_anat.inputs.out_matrix_file = "lin_mat" # WM probability map is thresholded and masked wm_bb_mask = Node(interface=fsl.ImageMaths(), name='wm_bb_mask') wm_bb_mask.inputs.op_string = '-thr 0.5 -bin' # CSf probability map is thresholded and masked csf_bb_mask = Node(interface=fsl.ImageMaths(), name='csf_bb_mask') csf_bb_mask.inputs.op_string = '-thr 0.5 -bin' # GM probability map is thresholded and masked gm_bb_mask = Node(interface=fsl.ImageMaths(), name='gm_bb_mask') gm_bb_mask.inputs.op_string = '-thr 0.1 -bin' # liberal mask to capture all gm signal # ventricle probability map is thresholded and masked vent_bb_mask = Node(interface=fsl.ImageMaths(), name='vent_bb_mask') vent_bb_mask.inputs.op_string = '-thr 0.8 -bin -ero -dilM' # stricter threshold and some morphology for compcor def bbreg_args(bbreg_target): """ A function is defined for define bbr argument which says flirt to perform bbr registration for each element of the list, due to MapNode Parameter: """ return '-cost bbr -wmseg ' + bbreg_target bbreg_arg_convert = Node(interface=Function(input_names=["bbreg_target"], output_names=["arg"], function=bbreg_args), name="bbr_arg_converter") # BBR registration within the FLIRT node bbreg_func_to_anat = Node(interface=fsl.FLIRT(), name='bbreg_func_to_anat') bbreg_func_to_anat.inputs.dof = 6 # calculate the inverse of the transformation matrix (of func to anat) convertmatrix = Node(interface=fsl.ConvertXFM(), name="convertmatrix") convertmatrix.inputs.invert_xfm = True # use the invers registration (anat to func) to transform anatomical csf mask reg_anatmask_to_func1 = Node(interface=fsl.FLIRT(apply_xfm=True, interp='nearestneighbour'), name='anatmasks_to_func1') # use the invers registration (anat to func) to transform anatomical wm mask reg_anatmask_to_func2 = Node(interface=fsl.FLIRT(apply_xfm=True, interp='nearestneighbour'), name='anatmasks_to_func2') # use the invers registration (anat to func) to transform anatomical gm mask reg_anatmask_to_func3 = Node(interface=fsl.FLIRT(apply_xfm=True, interp='nearestneighbour'), name='anatmasks_to_func3') # use the invers registration (anat to func) to transform anatomical gm mask reg_anatmask_to_func4 = Node(interface=fsl.FLIRT(apply_xfm=True, interp='nearestneighbour'), name='anatmasks_to_func4') # Create png images for quality check func2anat_qc = vol2png("func2anat_qc") wf.connect('inputspec', 'func', myonevol, 'in_file') wf.connect(myonevol, 'out_file', linear_func_to_anat, 'in_file') wf.connect('inputspec', 'head', linear_func_to_anat, 'reference') wf.connect(linear_func_to_anat, 'out_matrix_file', bbreg_func_to_anat, 'in_matrix_file') wf.connect(myonevol, 'out_file', bbreg_func_to_anat, 'in_file') wf.connect('inputspec', 'anat_wm_segmentation', bbreg_arg_convert, 'bbreg_target') wf.connect(bbreg_arg_convert, 'arg', bbreg_func_to_anat, 'args') wf.connect('inputspec', 'head', bbreg_func_to_anat, 'reference') wf.connect(bbreg_func_to_anat, 'out_matrix_file', convertmatrix, 'in_file') wf.connect(convertmatrix, 'out_file', reg_anatmask_to_func1, 'in_matrix_file') wf.connect(myonevol, 'out_file', reg_anatmask_to_func1, 'reference') wf.connect(csf_bb_mask,'out_file', reg_anatmask_to_func1, 'in_file') wf.connect(convertmatrix, 'out_file', reg_anatmask_to_func2, 'in_matrix_file') wf.connect(myonevol, 'out_file', reg_anatmask_to_func2, 'reference') wf.connect(wm_bb_mask, 'out_file', reg_anatmask_to_func2, 'in_file') wf.connect(convertmatrix, 'out_file', reg_anatmask_to_func3, 'in_matrix_file') wf.connect(myonevol, 'out_file', reg_anatmask_to_func3, 'reference') wf.connect(gm_bb_mask, 'out_file', reg_anatmask_to_func3, 'in_file') wf.connect(convertmatrix, 'out_file', reg_anatmask_to_func4, 'in_matrix_file') wf.connect(myonevol, 'out_file', reg_anatmask_to_func4, 'reference') wf.connect(vent_bb_mask, 'out_file', reg_anatmask_to_func4, 'in_file') wf.connect('inputspec', 'anat_wm_segmentation', wm_bb_mask, 'in_file') wf.connect('inputspec', 'anat_csf_segmentation', csf_bb_mask, 'in_file') wf.connect('inputspec', 'anat_gm_segmentation', gm_bb_mask, 'in_file') wf.connect('inputspec', 'anat_ventricle_segmentation', vent_bb_mask, 'in_file') wf.connect(myonevol, 'out_file', 'outputspec', 'example_func') wf.connect(bbreg_func_to_anat, 'out_file', func2anat_qc, 'bg_image') wf.connect(wm_bb_mask, 'out_file', func2anat_qc, 'overlay_image') wf.connect(reg_anatmask_to_func1, 'out_file', 'outputspec', 'csf_mask_in_funcspace') wf.connect(reg_anatmask_to_func2, 'out_file', 'outputspec', 'wm_mask_in_funcspace') wf.connect(reg_anatmask_to_func3, 'out_file', 'outputspec', 'gm_mask_in_funcspace') wf.connect(reg_anatmask_to_func4, 'out_file', 'outputspec', 'ventricle_mask_in_funcspace') wf.connect(bbreg_func_to_anat, 'out_file', 'outputspec', 'func_sample2anat') wf.connect(bbreg_func_to_anat, 'out_matrix_file', 'outputspec', 'func_to_anat_linear_xfm') wf.connect(convertmatrix, 'out_file', 'outputspec', 'anat_to_func_linear_xfm') wf.connect(bbreg_func_to_anat, 'out_file', 'sinker', "func2anat_qc")