Exemplo n.º 1
0
def get_norm_wf(name="norm_wf"):
    wf = Workflow(name=name)

    inputnode = pe.Node(niu.IdentityInterface(fields=['t1w', 't1w_brain']),
                        name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(
        fields=['t1w_2_MNI_mat', 't1w_2_MNI_warp', 't1w_MNIspace']),
                         name='outputnode')
    # otherwise fnirt is trying to write to the sourcedata dir
    t1w_dummy = pe.Node(fsl.ImageMaths(), name="t1w_dummy")
    wf.connect(inputnode, "t1w", t1w_dummy, "in_file")

    t1w_2_MNI_flirt = pe.Node(fsl.FLIRT(dof=12), name='t1w_2_MNI_flirt')
    t1w_2_MNI_flirt.inputs.reference = fsl.Info.standard_image(
        'MNI152_T1_1mm_brain.nii.gz')
    wf.connect(inputnode, 't1w_brain', t1w_2_MNI_flirt, 'in_file')
    wf.connect(t1w_2_MNI_flirt, 'out_matrix_file', outputnode, 't1w_2_MNI_mat')

    # 2. CALC. WARP STRUCT -> MNI with FNIRT
    # cf. wrt. 2mm
    # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1311&L=FSL&P=R86108&1=FSL&9=A&J=on&d=No+Match%3BMatch%3BMatches&z=4
    t1w_2_MNI_fnirt = pe.Node(fsl.FNIRT(), name='t1w_2_MNI_fnirt')
    t1w_2_MNI_fnirt.inputs.config_file = 'T1_2_MNI152_2mm'
    t1w_2_MNI_fnirt.inputs.ref_file = fsl.Info.standard_image(
        'MNI152_T1_2mm.nii.gz')
    t1w_2_MNI_fnirt.inputs.field_file = True
    t1w_2_MNI_fnirt.plugin_args = {'submit_specs': 'request_memory = 4000'}
    wf.connect(t1w_dummy, 'out_file', t1w_2_MNI_fnirt, 'in_file')
    wf.connect(t1w_2_MNI_flirt, 'out_matrix_file', t1w_2_MNI_fnirt,
               'affine_file')

    wf.connect(t1w_2_MNI_fnirt, 'field_file', outputnode, 't1w_2_MNI_warp')
    wf.connect(t1w_2_MNI_fnirt, 'warped_file', outputnode, 't1w_MNIspace')
    return wf
Exemplo n.º 2
0
def register(ref_img, in_img, cmd=None):
    """Find the 4D affine transform that registers in_img to ref_img
    Args:
        ref_img -- (type: ndarray) reference image
        in_img  -- (type: ndarray) input image to be registered
        cmd     -- (default: None) override default flirt parameters
                   an instance of nipype.interfaces.fsl.FLIRT

    Returns: warped input image
    """
    assert in_img.ndim == ref_img.ndim, 'Input and reference images must have the same '\
                                        'number of dimensions'
    in_file = _ndarray_to_nifti(in_img)
    ref_file = _ndarray_to_nifti(ref_img)
    out_file = NamedTemporaryFile(suffix='.nii.gz')
    log_file = NamedTemporaryFile(suffix='.txt')

    cmd = cmd or fsl.FNIRT()
    cmd.inputs.in_file = in_file.name
    cmd.inputs.ref_file = ref_file.name
    cmd.inputs.output_type = 'NIFTI_GZ'
    cmd.inputs.log_file = log_file.name
    cmd.inputs.warped_file = out_file.name
    log.debug('cmdline: {}'.format(cmd.cmdline))
    res = cmd.run()
    out_img = nib.load(out_file.name).get_data()
    return out_img
Exemplo n.º 3
0
 def FNIRT(self, in_file: str, ref: str, out_dir: str, type: int, aff: str):
     """
     FNIRT non-linear transformation
     @param in_file: image to be transformed
     @param ref: image to transform into
     @param out_dir: directory for outputs
     @param type: 0 for highres2lowres, 1 for atlasHighres2highres, 2 for atlasLabels2highres
     @return:
     """
     fnt = fsl.FNIRT()
     fnt.inputs.in_file = in_file
     fnt.inputs.ref_file = ref
     fnt.inputs.affine_file = aff
     if type == 0:
         fnt.inputs.warped_file = f"{out_dir}/Highres2Lowres.nii"
         print("Running non-linear transformation from Highres to Lowres:")
     elif type == 1:
         fnt.inputs.warped_file = f"{out_dir}/HighresAtlas2Highres.nii"
         print("Running non-linear transformation from Atlas to Highres:")
     elif type == 2:
         fnt.inputs.warped_file = f"{out_dir}/LabelsAtlas2Highres.nii"
         print("Running nonlinear transformation from Atlas to Highres:")
     fnt.inputs.output_type = "NIFTI"
     print(fnt.cmdline)
     fnt.run()
     return fnt.inputs.warped_file
Exemplo n.º 4
0
 def __init__(self, in_file='path', ref_file='path', **options):
     from nipype.interfaces import fsl
     fnt = fsl.FNIRT()
     fnt.inputs.in_file = in_file
     fnt.inputs.ref_file = ref_file
     for ef in options:
         setattr(fnt.inputs, ef, options[ef])
     self.res = fnt.run()
Exemplo n.º 5
0
 def init_fsl(self):
     fnt = fsl.FNIRT()
     fnt.inputs.in_file = self.atlas
     fnt.inputs.affine_file = self.aff
     fnt.inputs.ref_file = self.highres
     fnt.inputs.warped_file = str(self.out_dir / "atlas2highres.nii")
     fnt.inputs.fieldcoeff_file = str(self.out_dir / "atlas2highres_fieldcoeff.nii")
     fnt.inputs.field_file = str(self.out_dir / "atlas2highres_field.nii")
     return fnt
Exemplo n.º 6
0
def create_workflow(config: AttrDict, resource_pool: ResourcePool,
                    context: Context):
    for _, rp in resource_pool[['brain', 'label-reorient_T1w']]:
        # TODO: disable skullstrip
        linear_reg = NipypeJob(interface=fsl.FLIRT(cost='corratio'),
                               reference='linear_reg_0')
        inv_flirt_xfm = NipypeJob(
            interface=fsl.utils.ConvertXFM(invert_xfm=True),
            reference='inv_linear_reg0_xfm')

        linear_reg.in_file = rp[R('brain')]
        linear_reg.reference = config.template_brain
        linear_reg.interp = config.interpolation

        inv_flirt_xfm.in_file = linear_reg.out_matrix_file

        if config.linear_only:
            rp[R('brain', space='MNI')] = linear_reg.out_file
            # other xfm
            return
        else:
            nonlinear_reg = NipypeJob(interface=fsl.FNIRT(fieldcoeff_file=True,
                                                          jacobian_file=True),
                                      reference='nonlinear_reg_1')
            brain_warp = NipypeJob(interface=fsl.ApplyWarp(),
                                   reference='brain_warp')

            nonlinear_reg.in_file = rp[R('T1w', label='reorient')]
            nonlinear_reg.ref_file = config.template_skull
            nonlinear_reg.refmask_file = config.ref_mask
            nonlinear_reg.config_file = config.fnirt_config
            nonlinear_reg.affine_file = linear_reg.out_matrix_file

            brain_warp.interp = config.interpolation
            brain_warp.in_file = rp[R('brain')]
            brain_warp.field_file = nonlinear_reg.fieldcoeff_file
            brain_warp.ref_file = config.template_brain
            rp[R('brain', space='MNI')] = brain_warp.out_file
Exemplo n.º 7
0
def register_atlas(atlas_file, reference_file, output_dir, recalculate=True):
    """Registers the atlas to your reference image.

    This uses FNIRT to register the atlas to your reference image (for example the mean FA of the TBSS results).

    Args:
        atlas_file (str): the location of the atlas file we will register to the reference image.
        reference_file (str): the location of the reference image.
        output_dir (str): where to write the output
        recalculate (boolean): if we recalculate if the output already exists. Set this to False to easily get the
            results dictionary.

    Returns:
        dict: a dictionary with the filenames of the results. All files are in the output dir. Dir content:
            fieldcoeff_file: the path to the field coefficients file. To be used input to the 'warp' parameter of
                'applywarp'.
            warped_image: the warped image.
    """
    fieldcoeff_file = os.path.join(output_dir, 'fieldcoeff.nii.gz')
    warped_image = os.path.join(output_dir, 'warped.nii.gz')
    results_dict = {
        'fieldcoeff_file': fieldcoeff_file,
        'warped_image': warped_image
    }

    if not recalculate:
        if all(os.path.isfile(f) for f in [fieldcoeff_file, warped_image]):
            return results_dict

    fnirt = pe.Node(fsl.FNIRT(ref_file=reference_file,
                              in_file=atlas_file,
                              fieldcoeff_file=fieldcoeff_file,
                              warped_file=warped_image),
                    name='fnirt')
    fnirt.base_dir = os.path.join(output_dir, '_nipype_work_dir')
    fnirt.run()

    return results_dict
Exemplo n.º 8
0
def create_register_func_to_epi(name='register_func_to_epi',
                                reg_option='ANTS'):

    register_func_to_epi = pe.Workflow(name=name)

    inputspec = pe.Node(
        util.IdentityInterface(fields=['func_4d', 'func_3d', 'epi']),
        name='inputspec')

    outputspec = pe.Node(util.IdentityInterface(fields=[
        'ants_initial_xfm', 'ants_rigid_xfm', 'ants_affine_xfm',
        'ants_nonlinear_xfm', 'fsl_flirt_xfm', 'fsl_fnirt_xfm',
        'invlinear_xfm', 'func_in_epi'
    ]),
                         name='outputspec')

    if reg_option == 'ANTS':
        # linear + non-linear registration
        func_to_epi_ants = create_wf_calculate_ants_warp(
            name='func_to_epi_ants')
        func_to_epi_ants.inputs.inputspec.interp = 'LanczosWindowedSinc'

        register_func_to_epi.connect([
            (inputspec, func_to_epi_ants, [
                ('func_3d', 'inputspec.anatomical_brain'),
                ('epi', 'inputspec.reference_brain'),
                ('func_3d', 'inputspec.anatomical_skull'),
                ('epi', 'inputspec.reference_skull'),
            ]),
        ])

        func_to_epi_ants.inputs.inputspec.set(
            dimension=3,
            use_histogram_matching=True,
            winsorize_lower_quantile=0.01,
            winsorize_upper_quantile=0.99,
            metric=['MI', 'MI', 'CC'],
            metric_weight=[[1, 32], [1, 32], [1, 5]],
            radius_or_number_of_bins=[32, 32, 4],
            sampling_strategy=['Regular', 'Regular', None],
            sampling_percentage=[0.25, 0.25, None],
            number_of_iterations=[[1000, 500, 250, 100], [1000, 500, 250, 100],
                                  [100, 100, 70, 20]],
            convergence_threshold=[1e-8, 1e-8, 1e-9],
            convergence_window_size=[10, 10, 15],
            transforms=['Rigid', 'Affine', 'SyN'],
            transform_parameters=[[0.1], [0.1], [0.1, 3, 0]],
            shrink_factors=[[8, 4, 2, 1], [8, 4, 2, 1], [4, 2, 1]],
            smoothing_sigmas=[[3, 2, 1, 0], [3, 2, 1, 0], [0.6, 0.2, 0.0]])

        register_func_to_epi.connect([
            (func_to_epi_ants, outputspec, [
                ('outputspec.ants_initial_xfm', 'ants_initial_xfm'),
                ('outputspec.ants_rigid_xfm', 'ants_rigid_xfm'),
                ('outputspec.ants_affine_xfm', 'ants_affine_xfm'),
                ('outputspec.warp_field', 'ants_nonlinear_xfm'),
            ]),
        ])

        # combine transforms
        collect_transforms = pe.Node(util.Merge(4),
                                     name='collect_transforms_ants')
        register_func_to_epi.connect([
            (func_to_epi_ants, collect_transforms, [
                ('outputspec.ants_initial_xfm', 'in1'),
                ('outputspec.ants_rigid_xfm', 'in2'),
                ('outputspec.ants_affine_xfm', 'in3'),
                ('outputspec.warp_field', 'in4'),
            ]),
        ])

        # apply transform
        func_in_epi = pe.Node(interface=ants.ApplyTransforms(),
                              name='func_in_epi_ants')
        func_in_epi.inputs.input_image_type = 3
        func_in_epi.inputs.interpolation = 'LanczosWindowedSinc'

        register_func_to_epi.connect(inputspec, 'func_4d', func_in_epi,
                                     'input_image')
        register_func_to_epi.connect(inputspec, 'epi', func_in_epi,
                                     'reference_image')
        register_func_to_epi.connect(collect_transforms, 'out', func_in_epi,
                                     'transforms')
        register_func_to_epi.connect(func_in_epi, 'output_image', outputspec,
                                     'func_in_epi')

    elif reg_option == 'FSL':
        # flirt linear registration
        func_to_epi_linear = pe.Node(interface=fsl.FLIRT(),
                                     name='func_to_epi_linear_fsl')
        func_to_epi_linear.inputs.dof = 6

        register_func_to_epi.connect(inputspec, 'func_3d', func_to_epi_linear,
                                     'in_file')
        register_func_to_epi.connect(inputspec, 'epi', func_to_epi_linear,
                                     'reference')
        register_func_to_epi.connect(func_to_epi_linear, 'out_matrix_file',
                                     outputspec, 'fsl_flirt_xfm')

        inv_flirt_xfm = pe.Node(interface=fsl.utils.ConvertXFM(),
                                name='inv_linear_reg0_xfm')
        inv_flirt_xfm.inputs.invert_xfm = True

        # fnirt non-linear registration
        func_to_epi_nonlinear = pe.Node(interface=fsl.FNIRT(),
                                        name='func_to_epi_nonlinear_fsl')
        func_to_epi_nonlinear.inputs.fieldcoeff_file = True

        register_func_to_epi.connect(inputspec, 'func_3d',
                                     func_to_epi_nonlinear, 'in_file')
        register_func_to_epi.connect(inputspec, 'epi', func_to_epi_nonlinear,
                                     'ref_file')
        register_func_to_epi.connect(func_to_epi_linear, 'out_matrix_file',
                                     func_to_epi_nonlinear, 'affine_file')
        register_func_to_epi.connect(func_to_epi_nonlinear, 'fieldcoeff_file',
                                     outputspec, 'fsl_fnirt_xfm')

        register_func_to_epi.connect(func_to_epi_linear, 'out_matrix_file',
                                     inv_flirt_xfm, 'in_file')
        register_func_to_epi.connect(inv_flirt_xfm, 'out_file', outputspec,
                                     'invlinear_xfm')

        # apply warp
        func_in_epi = pe.Node(interface=fsl.ApplyWarp(),
                              name='func_in_epi_fsl')
        func_in_epi.inputs.interp = 'sinc'

        register_func_to_epi.connect(inputspec, 'func_4d', func_in_epi,
                                     'in_file')
        register_func_to_epi.connect(inputspec, 'epi', func_in_epi, 'ref_file')

        # --premat input disabled because it was throwing off the transform
        # application quality --- why, though?
        #register_func_to_epi.connect(func_to_epi_linear, 'out_matrix_file', func_in_epi, 'premat')

        register_func_to_epi.connect(func_to_epi_nonlinear, 'fieldcoeff_file',
                                     func_in_epi, 'field_file')
        register_func_to_epi.connect(func_in_epi, 'out_file', outputspec,
                                     'func_in_epi')

    return register_func_to_epi
Exemplo n.º 9
0
def create_tbss_2_reg(name="tbss_2_reg"):
    """TBSS nonlinear registration:
    A pipeline that does the same as 'tbss_2_reg -t' script in FSL. '-n' option
    is not supported at the moment.

    Example
    -------

    >>> from nipype.workflows.dmri.fsl import tbss
    >>> tbss2 = create_tbss_2_reg(name="tbss2")
    >>> tbss2.inputs.inputnode.target = fsl.Info.standard_image("FMRIB58_FA_1mm.nii.gz")  # doctest: +SKIP
    >>> tbss2.inputs.inputnode.fa_list = ['s1_FA.nii', 's2_FA.nii', 's3_FA.nii']
    >>> tbss2.inputs.inputnode.mask_list = ['s1_mask.nii', 's2_mask.nii', 's3_mask.nii']

    Inputs::

        inputnode.fa_list
        inputnode.mask_list
        inputnode.target

    Outputs::

        outputnode.field_list

    """

    # Define the inputnode
    inputnode = pe.Node(interface=util.IdentityInterface(
        fields=["fa_list", "mask_list", "target"]),
                        name="inputnode")

    # Flirt the FA image to the target
    flirt = pe.MapNode(interface=fsl.FLIRT(dof=12),
                       iterfield=['in_file', 'in_weight'],
                       name="flirt")

    fnirt = pe.MapNode(interface=fsl.FNIRT(fieldcoeff_file=True),
                       iterfield=['in_file', 'inmask_file', 'affine_file'],
                       name="fnirt")
    # Fnirt the FA image to the target
    if fsl.no_fsl():
        warn('NO FSL found')
    else:
        config_file = os.path.join(os.environ["FSLDIR"],
                                   "etc/flirtsch/FA_2_FMRIB58_1mm.cnf")
        fnirt.inputs.config_file = config_file

    # Define the registration workflow
    tbss2 = pe.Workflow(name=name)

    # Connect up the registration workflow
    tbss2.connect([
        (inputnode, flirt, [("fa_list", "in_file"), ("target", "reference"),
                            ("mask_list", "in_weight")]),
        (inputnode, fnirt, [("fa_list", "in_file"),
                            ("mask_list", "inmask_file"),
                            ("target", "ref_file")]),
        (flirt, fnirt, [("out_matrix_file", "affine_file")]),
    ])

    # Define the outputnode
    outputnode = pe.Node(
        interface=util.IdentityInterface(fields=['field_list']),
        name="outputnode")

    tbss2.connect([(fnirt, outputnode, [('fieldcoeff_file', 'field_list')])])
    return tbss2
Exemplo n.º 10
0
def img2img_register(
        img_file,
        ref_file,
        wf_base_dir,
        wf_name,
        input_reorient2std=False,
        ref_reorient2std=False,
        method='linear',
        flirt_out_reg_file='linear_reg.mat',
        flirt_out_file='img2img_linear.nii.gz',
        fnirt_out_file='img2img_nonlinear.nii.gz',
        fnirt_fieldcoeff_file='img2img_nonlinear_fieldcoeff.nii.gz'):

    img_file = os.path.abspath(img_file)
    ref_file = os.path.abspath(ref_file)
    wf_base_dir = os.path.abspath(wf_base_dir)

    if not img_file.endswith(('.nii', '.nii.gz')):
        raise ("input file should be in nifti format (.nii or .nii.gz)!")
    if not ref_file.endswith(('.nii', '.nii.gz')):
        raise (
            "destination file (ref_file) should be in nifti format (.nii or .nii.gz)!"
        )

    ### reorient2std

    ### reorient img_file
    if input_reorient2std:
        reorient = fsl.Reorient2Std()
        reorient.inputs.in_file = img_file
        reorient.inputs.out_file = 'input_img_reorient2std.nii.gz'
        reorient_Node = pe.Node(reorient, 'input_file')
        wf = pe.Workflow(name='reorient2std', base_dir=wf_base_dir)
        wf.add_nodes([reorient_Node])
        wf.run()
        img_file = os.path.join(wf_base_dir, 'reorient2std', 'input_file',
                                'input_img_reorient2std.nii.gz')

    ### reorient ref_file if config is not MNI
    if ref_reorient2std and config != 'MNI':
        reorient = fsl.Reorient2Std()
        reorient.inputs.in_file = ref_file
        reorient.inputs.out_file = 'ref_img_reorient2std.nii.gz'
        reorient_Node = pe.Node(reorient, 'ref_file')
        wf = pe.Workflow(name='reorient2std', base_dir=wf_base_dir)
        wf.add_nodes([reorient_Node])
        wf.run()
        ref_file = os.path.join(wf_base_dir, 'reorient2std', 'ref_file',
                                'ref_img_reorient2std.nii.gz')

    if method == 'linear':

        flirt = pe.Node(interface=fsl.FLIRT(in_file=img_file,
                                            reference=ref_file,
                                            out_matrix_file=flirt_out_reg_file,
                                            out_file=flirt_out_file),
                        name='linear')

        wf = pe.Workflow(name=wf_name, base_dir=wf_base_dir)

        wf.add_nodes([flirt])
        wf.run()

    if method == 'nonlinear':
        flirt = pe.Node(interface=fsl.FLIRT(in_file=img_file,
                                            reference=ref_file,
                                            out_matrix_file=flirt_out_reg_file,
                                            out_file=flirt_out_file),
                        name='linear')

        fnirt = pe.Node(interface=fsl.FNIRT(
            in_file=img_file,
            ref_file=ref_file,
            warped_file=fnirt_out_file,
            fieldcoeff_file=fnirt_fieldcoeff_file),
                        name='nonlinear')

        wf = pe.Workflow(name=wf_name, base_dir=wf_base_dir)

        ## adding nodes to workflows
        wf.add_nodes([flirt, fnirt])
        wf.connect([(flirt, fnirt, [('out_matrix_file', 'affine_file')])])
        wf.run()

    linear_reg_file = os.path.join(wf_base_dir, wf_name, method,
                                   flirt_out_reg_file)
    nonlinear_warp_field_file = os.path.join(wf_base_dir, wf_name, method,
                                             fnirt_fieldcoeff_file)

    return {
        'img_file': img_file,
        'ref_file': ref_file,
        'linear_reg_file': linear_reg_file,
        'warp_field_file': nonlinear_warp_field_file
    }
Exemplo n.º 11
0
	# Segment with FSL FAST
	#tissue priors
	#tissue_path = '/usr/share/fsl/5.0/data/standard/tissuepriors/2mm/'
	#csf_prior = tissue_path + 'avg152T1_csf_bin.nii.gz'
	#white_prior = tissue_path + 'avg152T1_white_bin.nii.gz'
	#gray_prior = tissue_path + 'avg152T1_gray_bin.nii.gz'

	#segmentation = pe.Node(interface=fsl.FAST(number_classes=3, use_priors=True, img_type=1), name='segmentation')
	#workflow.connect(skullstrip, 'out_file', segmentation, 'in_files')

	# Register to standard MNI template
	#1. linear
	linear_reg = pe.Node(interface=fsl.FLIRT(cost='corratio', reference=ref_brain), name='linear_reg')

	#2.nonlinear
	nonlinear_reg = pe.Node(interface=fsl.FNIRT(fieldcoeff_file=True, jacobian_file=True, ref_file=ref_brain, refmask_file=ref_mask), name='nonlinear_reg')

	inv_flirt_xfm = pe.Node(interface=fsl.utils.ConvertXFM(invert_xfm=True), name='inv_linear_xfm')

	workflow.connect(reorient, 'out_file', linear_reg, 'in_file')
	workflow.connect(linear_reg, 'out_matrix_file', nonlinear_reg, 'affine_file')
	workflow.connect(reorient, 'out_file', nonlinear_reg, 'in_file')
	workflow.connect(linear_reg, 'out_matrix_file', inv_flirt_xfm, 'in_file')

	# Run workflow
	workflow.write_graph()
	workflow.run()

	print "ANATOMICAL PREPROCESSING DONE! Results in ", results_path+subj
Exemplo n.º 12
0
def create_register_func_to_epi(name='register_func_to_epi', reg_option='ANTS', reg_ants_skull=1):

    register_func_to_epi = pe.Workflow(name=name)
    
    inputspec = pe.Node(util.IdentityInterface(fields=['func_4d',
                                                       'func_3d',
                                                       'func_3d_mask',
                                                       'epi',
                                                       'interp',
                                                       'ants_para']),
                        name='inputspec')

    outputspec = pe.Node(util.IdentityInterface(fields=['ants_initial_xfm',
                                                        'ants_rigid_xfm',
                                                        'ants_affine_xfm',
                                                        'warp_field', 
                                                        'inverse_warp_field', 
                                                        'fsl_flirt_xfm',
                                                        'fsl_fnirt_xfm',
                                                        'invlinear_xfm',
                                                        'func_in_epi']),
                                                        # 'func_mask_in_epi']),
                         name='outputspec')

    if reg_option == 'ANTS':
        # linear + non-linear registration
        func_to_epi_ants = \
            create_wf_calculate_ants_warp(
                name='func_to_epi_ants', 
                num_threads=1, 
                reg_ants_skull=1)

        register_func_to_epi.connect([
            (inputspec, func_to_epi_ants, [
                ('func_3d', 'inputspec.moving_brain'),
                ('epi', 'inputspec.reference_brain'),
                ('func_3d', 'inputspec.moving_skull'),
                ('epi', 'inputspec.reference_skull'),
                ('interp', 'inputspec.interp'),
                ('ants_para', 'inputspec.ants_para')
            ]),
        ])

        register_func_to_epi.connect([
            (func_to_epi_ants, outputspec, [
                ('outputspec.ants_initial_xfm', 'ants_initial_xfm'),
                ('outputspec.ants_rigid_xfm', 'ants_rigid_xfm'),
                ('outputspec.ants_affine_xfm', 'ants_affine_xfm'),
                ('outputspec.warp_field', 'warp_field'),  
                ('outputspec.inverse_warp_field', 'inverse_warp_field'),
            ]),
        ])

        # combine transforms
        collect_transforms = pe.Node(util.Merge(4), name='collect_transforms_ants')
        register_func_to_epi.connect([
            (func_to_epi_ants, collect_transforms, [
                ('outputspec.ants_initial_xfm', 'in1'),
                ('outputspec.ants_rigid_xfm', 'in2'),
                ('outputspec.ants_affine_xfm', 'in3'),
                ('outputspec.warp_field', 'in4'),
            ]),
        ])

        # check transform list to exclude Nonetype (missing) init/rig/affine
        check_transform = pe.Node(util.Function(input_names=['transform_list'], 
                                                output_names=['checked_transform_list', 'list_length'],
                                                function=check_transforms), name='{0}_check_transforms'.format(name))
        
        register_func_to_epi.connect(collect_transforms, 'out', check_transform, 'transform_list')


        # apply transform to func 
        func_in_epi = pe.Node(interface=ants.ApplyTransforms(), name='func_in_epi_ants')
        func_in_epi.inputs.dimension = 3
        func_in_epi.inputs.input_image_type = 3
        register_func_to_epi.connect(inputspec, 'func_4d', func_in_epi, 'input_image')
        register_func_to_epi.connect(inputspec, 'epi', func_in_epi, 'reference_image')
        register_func_to_epi.connect(check_transform, 'checked_transform_list', func_in_epi, 'transforms')
        register_func_to_epi.connect(func_in_epi, 'output_image', outputspec, 'func_in_epi')

        # # apply transform to functional mask
        # func_mask_in_epi = pe.Node(interface=ants.ApplyTransforms(), name='func_mask_in_epi_ants')
        # func_mask_in_epi.inputs.dimension = 3
        # func_mask_in_epi.inputs.input_image_type = 0
        # register_func_to_epi.connect(inputspec, 'func_3d_mask', func_mask_in_epi, 'input_image')
        # register_func_to_epi.connect(inputspec, 'epi', func_mask_in_epi, 'reference_image')
        # register_func_to_epi.connect(check_transform, 'checked_transform_list', func_mask_in_epi, 'transforms')
        # register_func_to_epi.connect(func_mask_in_epi, 'output_image', outputspec, 'func_mask_in_epi')

    elif reg_option == 'FSL':
        # flirt linear registration 
        func_to_epi_linear = pe.Node(interface=fsl.FLIRT(), name='func_to_epi_linear_fsl')
        func_to_epi_linear.inputs.dof = 6

        register_func_to_epi.connect(inputspec, 'func_3d', func_to_epi_linear, 'in_file')
        register_func_to_epi.connect(inputspec, 'epi', func_to_epi_linear, 'reference')
        register_func_to_epi.connect(func_to_epi_linear, 'out_matrix_file', outputspec, 'fsl_flirt_xfm')
        
        inv_flirt_xfm = pe.Node(interface=fsl.utils.ConvertXFM(), name='inv_linear_reg0_xfm')
        inv_flirt_xfm.inputs.invert_xfm = True

        # fnirt non-linear registration
        func_to_epi_nonlinear = pe.Node(interface=fsl.FNIRT(), name='func_to_epi_nonlinear_fsl')
        func_to_epi_nonlinear.inputs.fieldcoeff_file = True

        register_func_to_epi.connect(inputspec, 'func_3d', func_to_epi_nonlinear, 'in_file')
        register_func_to_epi.connect(inputspec, 'epi', func_to_epi_nonlinear, 'ref_file')
        register_func_to_epi.connect(func_to_epi_linear, 'out_matrix_file', func_to_epi_nonlinear, 'affine_file')
        register_func_to_epi.connect(func_to_epi_nonlinear, 'fieldcoeff_file', outputspec, 'fsl_fnirt_xfm')

        register_func_to_epi.connect(func_to_epi_linear, 'out_matrix_file', inv_flirt_xfm, 'in_file')
        register_func_to_epi.connect(inv_flirt_xfm, 'out_file', outputspec, 'invlinear_xfm')

        # apply warp
        func_in_epi = pe.Node(interface=fsl.ApplyWarp(), name='func_in_epi_fsl')
        func_in_epi.inputs.interp = 'sinc'

        register_func_to_epi.connect(inputspec, 'func_4d', func_in_epi, 'in_file')
        register_func_to_epi.connect(inputspec, 'epi', func_in_epi, 'ref_file')

        # --premat input disabled because it was throwing off the transform
        # application quality --- why, though?
        #register_func_to_epi.connect(func_to_epi_linear, 'out_matrix_file', func_in_epi, 'premat')

        register_func_to_epi.connect(func_to_epi_nonlinear, 'fieldcoeff_file', func_in_epi, 'field_file')
        register_func_to_epi.connect(func_in_epi, 'out_file', outputspec, 'func_in_epi')

    return register_func_to_epi
Exemplo n.º 13
0
def create_reg_workflow(name='registration'):
    """Create a FEAT preprocessing workflow together with freesurfer

    Parameters
    ----------

    ::

        name : name of workflow (default: 'registration')

    Inputs::

        inputspec.source_files : files (filename or list of filenames to register)
        inputspec.mean_image : reference image to use
        inputspec.anatomical_image : anatomical image to coregister to
        inputspec.target_image : registration target

    Outputs::

        outputspec.func2anat_transform : FLIRT transform
        outputspec.anat2target_transform : FLIRT+FNIRT transform
        outputspec.transformed_files : transformed files in target space
        outputspec.transformed_mean : mean image in target space

    Example
    -------

    """

    register = pe.Workflow(name=name)

    inputnode = pe.Node(interface=util.IdentityInterface(fields=['source_files',
                                                                 'mean_image',
                                                                 'anatomical_image',
                                                                 'target_image']),
                        name='inputspec')
    outputnode = pe.Node(interface=util.IdentityInterface(fields=['func2anat_transform',
                                                              'anat2target_transform',
                                                              'transformed_files',
                                                              'transformed_mean',
                                                              ]),
                     name='outputspec')

    """
    Estimate the tissue classes from the anatomical image. But use spm's segment
    as FSL appears to be breaking.
    """

    #fast = pe.Node(fsl.FAST(), name='fast')
    #fast.config = {'execution': {'keep_unncessary_outputs': True}}
    #register.connect(inputnode, 'anatomical_image', fast, 'in_files')

    convert = pe.Node(fs.MRIConvert(out_type='nii'), name='convert')
    register.connect(inputnode, 'anatomical_image', convert, 'in_file')

    segment = pe.Node(spm.Segment(), name='segment')
    segment.inputs.wm_output_type = [False, False, True]
    segment.config = {'execution': {'keep_unnecessary_outputs': 'true'}}
    register.connect(convert, 'out_file', segment, 'data')

    """
    Binarize the segmentation
    """

    binarize = pe.Node(fsl.ImageMaths(op_string='-nan -thr 0.5 -bin'),
                       name='binarize')
    #pickindex = lambda x, i: x[i]
    #register.connect(fast, ('partial_volume_files', pickindex, 1),
    #                 binarize, 'in_file')
    register.connect(segment, 'native_wm_image', binarize, 'in_file')

    """
    Calculate rigid transform from mean image to anatomical image
    """

    mean2anat = pe.Node(fsl.FLIRT(), name='mean2anat')
    mean2anat.inputs.dof = 6
    register.connect(inputnode, 'mean_image', mean2anat, 'in_file')
    register.connect(inputnode, 'anatomical_image', mean2anat, 'reference')

    """
    Now use bbr cost function to improve the transform
    """

    mean2anatbbr = pe.Node(fsl.FLIRT(), name='mean2anatbbr')
    mean2anatbbr.inputs.dof = 6
    mean2anatbbr.inputs.cost = 'bbr'
    os.environ['FSLDIR']
    mean2anatbbr.inputs.schedule = os.path.join(os.environ['FSLDIR'],'etc/flirtsch/bbr.sch')
    register.connect(inputnode, 'mean_image', mean2anatbbr, 'in_file')
    register.connect(binarize, 'out_file', mean2anatbbr, 'wm_seg')
    register.connect(inputnode, 'anatomical_image', mean2anatbbr, 'reference')
    register.connect(mean2anat, 'out_matrix_file', mean2anatbbr, 'in_matrix_file')

    """
    Calculate affine transform from anatomical to target
    """

    anat2target_affine = pe.Node(fsl.FLIRT(), name='anat2target_linear')
    register.connect(inputnode, 'anatomical_image', anat2target_affine, 'in_file')
    register.connect(inputnode, 'target_image', anat2target_affine, 'reference')

    """
    Calculate nonlinear transform from anatomical to target
    """

    anat2target_nonlinear = pe.Node(fsl.FNIRT(), name='anat2target_nonlinear')
    register.connect(anat2target_affine, 'out_matrix_file',
                     anat2target_nonlinear, 'affine_file')
    #anat2target_nonlinear.inputs.in_fwhm = [8, 4, 2, 2]
    #anat2target_nonlinear.inputs.subsampling_scheme = [4, 2, 1, 1]
    anat2target_nonlinear.inputs.warp_resolution = (8, 8, 8)
    register.connect(inputnode, 'anatomical_image', anat2target_nonlinear, 'in_file')
    register.connect(inputnode, 'target_image',
                     anat2target_nonlinear, 'ref_file')

    """
    Transform the mean image. First to anatomical and then to target
    """

    warp2anat = pe.Node(fsl.ApplyWarp(interp='spline'), name='warp2anat')
    register.connect(inputnode, 'mean_image', warp2anat, 'in_file')
    register.connect(inputnode, 'anatomical_image', warp2anat, 'ref_file')
    register.connect(mean2anatbbr, 'out_matrix_file', warp2anat, 'premat')

    warpmean = pe.Node(fsl.ApplyWarp(interp='spline'), name='warpmean')
    register.connect(warp2anat, 'out_file', warpmean, 'in_file')
    register.connect(inputnode, 'target_image', warpmean, 'ref_file')
    register.connect(anat2target_affine, 'out_matrix_file', warpmean, 'premat')
    register.connect(anat2target_nonlinear, 'field_file',
                     warpmean, 'field_file')

    """
    Transform the remaining images. First to anatomical and then to target
    """

    warpall2anat = pe.MapNode(fsl.ApplyWarp(interp='spline'),
                              iterfield=['in_file'],
                              name='warpall2anat')
    register.connect(inputnode, 'source_files', warpall2anat, 'in_file')
    register.connect(inputnode, 'anatomical_image', warpall2anat, 'ref_file')
    register.connect(mean2anatbbr, 'out_matrix_file', warpall2anat, 'premat')

    warpall = pe.MapNode(fsl.ApplyWarp(interp='spline'), name='warpall',
                         iterfield=['in_file'])
    register.connect(warpall2anat, 'out_file', warpall, 'in_file')
    register.connect(inputnode, 'target_image', warpall, 'ref_file')
    register.connect(anat2target_affine, 'out_matrix_file', warpall, 'premat')
    register.connect(anat2target_nonlinear, 'field_file',
                     warpall, 'field_file')

    """
    Assign all the output files
    """

    register.connect(warpmean, 'out_file', outputnode, 'transformed_mean')
    register.connect(warpall, 'out_file', outputnode, 'transformed_files')
    register.connect(mean2anatbbr, 'out_matrix_file',
                     outputnode, 'func2anat_transform')
    register.connect(anat2target_nonlinear, 'field_file',
                     outputnode, 'anat2target_transform')

    return register
Exemplo n.º 14
0
def create_reg_workflow(name='registration'):
    """Create a FEAT preprocessing workflow together with freesurfer

    Parameters
    ----------

    ::

        name : name of workflow (default: 'registration')

    Inputs::

        inputspec.source_files : files (filename or list of filenames to register)
        inputspec.mean_image : reference image to use
        inputspec.anatomical_image : anatomical image to coregister to
        inputspec.target_image : registration target

    Outputs::

        outputspec.func2anat_transform : FLIRT transform
        outputspec.anat2target_transform : FLIRT+FNIRT transform
        outputspec.transformed_files : transformed files in target space
        outputspec.transformed_mean : mean image in target space

    Example
    -------

    """

    register = pe.Workflow(name=name)

    inputnode = pe.Node(interface=util.IdentityInterface(fields=['source_files',
                                                                 'mean_image',
                                                                 'anatomical_image',
                                                                 'target_image']),
                        name='inputspec')
    outputnode = pe.Node(interface=util.IdentityInterface(fields=['func2anat_transform',
                                                              'anat2target_transform',
                                                              'transformed_files',
                                                              'transformed_mean',
                                                              ]),
                     name='outputspec')

    """
    Estimate the tissue classes from the anatomical image. But use spm's segment
    as FSL appears to be breaking.
    """

    stripper = pe.Node(fsl.BET(), name='stripper')
    register.connect(inputnode, 'anatomical_image', stripper, 'in_file')
    fast = pe.Node(fsl.FAST(), name='fast')
    register.connect(stripper, 'out_file', fast, 'in_files')

    """
    Binarize the segmentation
    """

    binarize = pe.Node(fsl.ImageMaths(op_string='-nan -thr 0.5 -bin'),
                       name='binarize')
    pickindex = lambda x, i: x[i]
    register.connect(fast, ('partial_volume_files', pickindex, 2),
                     binarize, 'in_file')

    """
    Calculate rigid transform from mean image to anatomical image
    """

    mean2anat = pe.Node(fsl.FLIRT(), name='mean2anat')
    mean2anat.inputs.dof = 6
    register.connect(inputnode, 'mean_image', mean2anat, 'in_file')
    register.connect(stripper, 'out_file', mean2anat, 'reference')

    """
    Now use bbr cost function to improve the transform
    """

    mean2anatbbr = pe.Node(fsl.FLIRT(), name='mean2anatbbr')
    mean2anatbbr.inputs.dof = 6
    mean2anatbbr.inputs.cost = 'bbr'
    mean2anatbbr.inputs.schedule = os.path.join(os.getenv('FSLDIR'),
                                                'etc/flirtsch/bbr.sch')
    register.connect(inputnode, 'mean_image', mean2anatbbr, 'in_file')
    register.connect(binarize, 'out_file', mean2anatbbr, 'wm_seg')
    register.connect(inputnode, 'anatomical_image', mean2anatbbr, 'reference')
    register.connect(mean2anat, 'out_matrix_file', mean2anatbbr, 'in_matrix_file')

    """
    Calculate affine transform from anatomical to target
    """

    anat2target_affine = pe.Node(fsl.FLIRT(), name='anat2target_linear')
    register.connect(inputnode, 'anatomical_image', anat2target_affine, 'in_file')
    register.connect(inputnode, 'target_image', anat2target_affine, 'reference')

    """
    Calculate nonlinear transform from anatomical to target
    """

    anat2target_nonlinear = pe.Node(fsl.FNIRT(), name='anat2target_nonlinear')
    anat2target_nonlinear.inputs.fieldcoeff_file=True
    register.connect(anat2target_affine, 'out_matrix_file',
                     anat2target_nonlinear, 'affine_file')
    anat2target_nonlinear.inputs.warp_resolution = (8, 8, 8)
    register.connect(inputnode, 'anatomical_image', anat2target_nonlinear, 'in_file')
    register.connect(inputnode, 'target_image',
                     anat2target_nonlinear, 'ref_file')

    """
    Transform the mean image. First to anatomical and then to target
    """

    warp2anat = pe.Node(fsl.ApplyWarp(interp='spline'), name='warp2anat')
    register.connect(inputnode, 'mean_image', warp2anat, 'in_file')
    register.connect(inputnode, 'anatomical_image', warp2anat, 'ref_file')
    register.connect(mean2anatbbr, 'out_matrix_file', warp2anat, 'premat')

    warpmean = warp2anat.clone(name='warpmean')
    register.connect(warp2anat, 'out_file', warpmean, 'in_file')
    register.connect(inputnode, 'target_image', warpmean, 'ref_file')
    register.connect(anat2target_nonlinear, 'fieldcoeff_file',
                     warpmean, 'field_file')

    """
    Transform the remaining images. First to anatomical and then to target
    """

    warpall2anat = pe.MapNode(fsl.ApplyWarp(interp='spline'),
                              iterfield=['in_file'],
                              name='warpall2anat')
    register.connect(inputnode, 'source_files', warpall2anat, 'in_file')
    register.connect(inputnode, 'anatomical_image', warpall2anat, 'ref_file')
    register.connect(mean2anatbbr, 'out_matrix_file', warpall2anat, 'premat')

    warpall = warpall2anat.clone(name='warpall')
    register.connect(warpall2anat, 'out_file', warpall, 'in_file')
    register.connect(inputnode, 'target_image', warpall, 'ref_file')
    register.connect(anat2target_nonlinear, 'fieldcoeff_file',
                     warpall, 'field_file')

    """
    Assign all the output files
    """

    register.connect(warpmean, 'out_file', outputnode, 'transformed_mean')
    register.connect(warpall, 'out_file', outputnode, 'transformed_files')
    register.connect(mean2anatbbr, 'out_matrix_file',
                     outputnode, 'func2anat_transform')
    register.connect(anat2target_nonlinear, 'fieldcoeff_file',
                     outputnode, 'anat2target_transform')

    return register
Exemplo n.º 15
0
def create_nonlinear_register(name='nonlinear_register'):
    """
    Performs non-linear registration of an input file to a reference file.

    Parameters
    ----------
    name : string, optional
        Name of the workflow.

    Returns
    -------
    nonlinear_register : nipype.pipeline.engine.Workflow

    Notes
    -----
    
    Workflow Inputs::
    
        inputspec.input_brain : string (nifti file)
            File of brain to be normalized (registered)
        inputspec.input_skull : string (nifti file)
            File of input brain with skull
        inputspec.reference_brain : string (nifti file)
            Target brain file to normalize to
        inputspec.reference_skull : string (nifti file)
            Target brain with skull to normalize to
        inputspec.fnirt_config : string (fsl fnirt config file)
            Configuration file containing parameters that can be specified in fnirt
            
    Workflow Outputs::
    
        outputspec.output_brain : string (nifti file)
            Normalizion of input brain file
        outputspec.linear_xfm : string (.mat file)
            Affine matrix of linear transformation of brain file
        outputspec.invlinear_xfm : string
            Inverse of affine matrix of linear transformation of brain file
        outputspec.nonlinear_xfm : string
            Nonlinear field coefficients file of nonlinear transformation
            
    Registration Procedure:
    
    1. Perform a linear registration to get affine transformation matrix.
    2. Perform a nonlinear registration on an input file to the reference file utilizing affine
       transformation from the previous step as a starting point.
    3. Invert the affine transformation to provide the user a transformation (affine only) from the
       space of the reference file to the input file.
       
    Workflow Graph:
    
    .. image:: ../images/nonlinear_register.dot.png
        :width: 500
    
    Detailed Workflow Graph:
    
    .. image:: ../images/nonlinear_register_detailed.dot.png
        :width: 500    
       
    """
    nonlinear_register = pe.Workflow(name=name)

    inputspec = pe.Node(util.IdentityInterface(fields=[
        'input_brain', 'input_skull', 'reference_brain', 'reference_skull',
        'fnirt_config'
    ]),
                        name='inputspec')

    outputspec = pe.Node(util.IdentityInterface(fields=[
        'output_brain', 'linear_xfm', 'invlinear_xfm', 'nonlinear_xfm'
    ]),
                         name='outputspec')

    linear_reg = pe.Node(interface=fsl.FLIRT(), name='linear_reg_0')
    linear_reg.inputs.cost = 'corratio'

    nonlinear_reg = pe.Node(interface=fsl.FNIRT(), name='nonlinear_reg_1')
    nonlinear_reg.inputs.fieldcoeff_file = True
    nonlinear_reg.inputs.jacobian_file = True

    brain_warp = pe.Node(interface=fsl.ApplyWarp(), name='brain_warp')

    inv_flirt_xfm = pe.Node(interface=fsl.utils.ConvertXFM(),
                            name='inv_linear_reg0_xfm')
    inv_flirt_xfm.inputs.invert_xfm = True

    nonlinear_register.connect(inputspec, 'input_brain', linear_reg, 'in_file')

    nonlinear_register.connect(inputspec, 'reference_brain', linear_reg,
                               'reference')

    nonlinear_register.connect(inputspec, 'input_skull', nonlinear_reg,
                               'in_file')

    nonlinear_register.connect(inputspec, 'reference_skull', nonlinear_reg,
                               'ref_file')

    # FNIRT parameters are specified by FSL config file
    # ${FSLDIR}/etc/flirtsch/TI_2_MNI152_2mm.cnf (or user-specified)
    nonlinear_register.connect(inputspec, 'fnirt_config', nonlinear_reg,
                               'config_file')

    nonlinear_register.connect(linear_reg, 'out_matrix_file', nonlinear_reg,
                               'affine_file')

    nonlinear_register.connect(nonlinear_reg, 'fieldcoeff_file', outputspec,
                               'nonlinear_xfm')

    nonlinear_register.connect(inputspec, 'input_brain', brain_warp, 'in_file')

    nonlinear_register.connect(nonlinear_reg, 'fieldcoeff_file', brain_warp,
                               'field_file')

    nonlinear_register.connect(inputspec, 'reference_brain', brain_warp,
                               'ref_file')

    nonlinear_register.connect(brain_warp, 'out_file', outputspec,
                               'output_brain')

    nonlinear_register.connect(linear_reg, 'out_matrix_file', inv_flirt_xfm,
                               'in_file')

    nonlinear_register.connect(inv_flirt_xfm, 'out_file', outputspec,
                               'invlinear_xfm')

    nonlinear_register.connect(linear_reg, 'out_matrix_file', outputspec,
                               'linear_xfm')

    return nonlinear_register
Exemplo n.º 16
0
def create_tbss_2_reg(name="tbss_2_reg"):
    """TBSS nonlinear registration: 
    A pipeline that does the same as tbss_2_reg script in FSL.
        
    Example
    ------
    
    >>> tbss2 = create_tbss_2_reg(name="tbss2")
    >>> tbss2.inputs.inputnode.target = fsl.Info.standard_image("FMRIB58_FA_1mm.nii.gz")
    >>> ...
    
    Inputs::

        inputnode.fa_list
        inputnode.mask_list
        inputnode.target

    Outputs::
    
        outputnode.field_list

    """
   
    # Define the inputnode
    inputnode = pe.Node(interface = util.IdentityInterface(fields=["fa_list",
                                                                   "mask_list",
                                                                   "target"]),
                        name="inputnode")
    
    # Flirt the FA image to the target
    flirt = pe.MapNode(interface=fsl.FLIRT(dof=12),
                    iterfield=['in_file','in_weight'],
                    name="flirt")
    
    # Fnirt the FA image to the target
    config_file = os.path.join(os.environ["FSLDIR"],
                                "etc/flirtsch/FA_2_FMRIB58_1mm.cnf")
    fnirt = pe.MapNode(interface=fsl.FNIRT(config_file=config_file,
                                        fieldcoeff_file=True),
                    iterfield=['in_file', 'inmask_file', 'affine_file'],
                    name="fnirt")
    
    # Define the registration workflow
    tbss2 = pe.Workflow(name=name)
    
    # Connect up the registration workflow
    tbss2.connect([
        (inputnode,flirt,[("fa_list", "in_file"),
                         ("target","reference"),
                         ("mask_list","in_weight")]),
        (inputnode,fnirt,[("fa_list", "in_file"),
                         ("mask_list","inmask_file"),
                         ("target","ref_file")]),
        (flirt,fnirt,[("out_matrix_file", "affine_file")]),
        ])

    # Define the outputnode
    outputnode = pe.Node(interface = util.IdentityInterface(fields=['field_list']),
                         name="outputnode")
    
    tbss2.connect([
        (fnirt,outputnode, [('fieldcoeff_file','field_list')])
        ])
    return tbss2
Exemplo n.º 17
0
    def modulation_( self ):
        """Modulation funcion is a correction of the volume change multiplying the voxel by the Jacobian determinant derived from the normalization process."""
        try:
            #
            # Use the non-linear template built in the non-linear_registration_ funstion
            temp_T1_brain_nlin  = os.path.join(self.ana_dir_, "temp_T1_brain_nlin.nii.gz")

            #
            # Loop on the tasks
            while True:
                # get the item
                item = self.queue_[2].get()
                # registration estimation
                flt = fsl.FLIRT()
                flt.inputs.in_file         = os.path.join(self.T1_brain_dir_, item )
                flt.inputs.reference       = temp_T1_brain_nlin
                flt.inputs.out_file        = os.path.join( self.template_dir_, "%s_li_template.nii.gz"%item[:-7] )
                flt.inputs.out_matrix_file = os.path.join( self.template_dir_, "%s_li_template.mat"%item[:-7] )
                flt.inputs.dof             = 12
                res = flt.run()
 
                #
                # Find the matching T1 image
                PIDN    = [int(s) for s in item.split("_") if s.isdigit()]
                #
                T1_item = [ s for s in self.list_T1_ if str(PIDN[0]) in s]

                #
                # apply registration using T1_2_MNI152_2mm configuration file
                T1_2_MNI152_2mm = ""
                if os.environ.get('FSLDIR'):
                    T1_2_MNI152_2mm = os.path.join( os.environ.get('FSLDIR'), 
                                                    "etc","flirtsch","T1_2_MNI152_2mm.cnf" )
                #
                fnt = fsl.FNIRT()
                fnt.inputs.in_file         = os.path.join(self.T1_dir_, T1_item[0])
                fnt.inputs.ref_file        = self.template_
                fnt.inputs.warped_file     = os.path.join( self.template_dir_, 
                                                           "%s_non_li_template_fnirt.nii.gz"%item[:-7] )
                fnt.inputs.affine_file     = os.path.join( self.template_dir_, 
                                                           "%s_li_template.mat"%item[:-7] )
                fnt.inputs.config_file     = T1_2_MNI152_2mm
                fnt.inputs.fieldcoeff_file = os.path.join( self.template_dir_, 
                                                           "%s_non_li_template_coeff.nii.gz"%item[:-7] )
                fnt.inputs.jacobian_file   = os.path.join( self.template_dir_, 
                                                           "%s_non_li_template_jac.nii.gz"%item[:-7] )
                res = fnt.run()
                # apply warp
                aw = fsl.ApplyWarp()
                aw.inputs.in_file    = os.path.join(self.T1_dir_, T1_item[0])
                aw.inputs.ref_file   = self.template_
                aw.inputs.out_file   = os.path.join( self.template_dir_, 
                                                     "%s_non_li_template_warped.nii.gz"%item[:-7] )
                aw.inputs.field_file = os.path.join( self.template_dir_, 
                                                     "%s_non_li_template_coeff.nii.gz"%item[:-7] )
                res = aw.run()
                # modulation
                maths = fsl.ImageMaths()
                maths.inputs.in_file       =  os.path.join(self.template_dir_,
                                                           "%s_non_li_template_warped.nii.gz"%item[:-7])
                maths.inputs.op_string     = '-mul %s'%(os.path.join(self.template_dir_,
                                                                     "%s_non_li_template_jac.nii.gz"%item[:-7]))
                maths.inputs.out_file      =  os.path.join( self.template_dir_, 
                                                            "%s_modulated.nii.gz"%item[:-7] )
                maths.inputs.out_data_type = "float"
                maths.run();
                # lock and add the file
                singlelock.acquire()
                self.warped_template_.append( aw.inputs.out_file )
                self.modulated_template_.append(  os.path.join(self.template_dir_, 
                                                               "%s_modulated.nii.gz"%item[:-7]) )
                singlelock.release()
                # job is done
                self.queue_[2].task_done()
        #
        #
        except Exception as inst:
            print inst
            _log.error(inst)
            quit(-1)
        except IOError as e:
            print "I/O error({0}): {1}".format(e.errno, e.strerror)
            quit(-1)
        except:
            print "Unexpected error:", sys.exc_info()[0]
            quit(-1)
Exemplo n.º 18
0
def create_vmhc(use_ants):

    """
    Compute the map of brain functional homotopy, the high degree of synchrony in spontaneous activity between geometrically corresponding interhemispheric (i.e., homotopic) regions.



    Parameters
    ----------

    None

    Returns
    -------

    vmhc_workflow : workflow

        Voxel Mirrored Homotopic Connectivity Analysis Workflow



    Notes
    -----

    `Source <https://github.com/FCP-INDI/C-PAC/blob/master/CPAC/vmhc/vmhc.py>`_ 

    Workflow Inputs::

        inputspec.brain : string (existing nifti file)
            Anatomical image(without skull)

        inputspec.symmetric_brain : string (existing nifti file)
            MNI152_T1_2mm_brain_symmetric.nii.gz
 
        inputspec.rest_res_filt : string (existing nifti file)
            Band passed Image with nuisance signal regressed out(and optionally scrubbed). Recommended bandpass filter (0.001,0.1) )

        inputspec.reorient : string (existing nifti file)
            RPI oriented anatomical data

        inputspec.example_func2highres_mat : string (existing affine transformation .mat file)
            Specifies an affine transform that should be applied to the example_func before non linear warping

        inputspec.standard_for_func : string (existing nifti file)
            MNI152_T1_standard_resolution_brain.nii.gz

        inputspec.symmetric_skull : string (existing nifti file)
            MNI152_T1_2mm_symmetric.nii.gz

        inputspec.twomm_brain_mask_dil : string (existing nifti file)
            MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz

        inputspec.config_file_twomm_symmetric : string (existing .cnf file)
            T1_2_MNI152_2mm_symmetric.cnf

        inputspec.rest_mask : string (existing nifti file)
            A mask functional volume(derived by dilation from motion corrected functional volume)

        fwhm_input.fwhm : list (float) 
            For spatial smoothing the Z-transformed correlations in MNI space.
            Generally the value of this parameter is 1.5 or 2 times the voxel size of the input Image.

        inputspec.mean_functional : string (existing nifti file)
            The mean functional image for use in the func-to-anat registration matrix conversion
            to ITK (ANTS) format, if the user selects to use ANTS.

        
    Workflow Outputs::

        outputspec.highres2symmstandard : string (nifti file)
            Linear registration of T1 image to symmetric standard image

        outputspec.highres2symmstandard_mat : string (affine transformation .mat file)
            An affine transformation .mat file from linear registration and used in non linear registration

        outputspec.highres2symmstandard_warp : string (nifti file)
            warp file from Non Linear registration of T1 to symmetrical standard brain

        outputspec.fnirt_highres2symmstandard : string (nifti file)
            Non Linear registration of T1 to symmetrical standard brain

        outputspec.highres2symmstandard_jac : string (nifti file)
            jacobian determinant image from Non Linear registration of T1 to symmetrical standard brain

        outputspec.rest_res_2symmstandard : string (nifti file)
            nonlinear registration (func to standard) image

        outputspec.VMHC_FWHM_img : string (nifti file)
            pearson correlation between res2standard and flipped res2standard

        outputspec.VMHC_Z_FWHM_img : string (nifti file)
            Fisher Z transform map

        outputspec.VMHC_Z_stat_FWHM_img : string (nifti file)
            Z statistic map

    Order of commands:

    - Perform linear registration of Anatomical brain in T1 space to symmetric standard space. For details see `flirt <http://www.fmrib.ox.ac.uk/fsl/flirt/index.html>`_::

        flirt
        -ref MNI152_T1_2mm_brain_symmetric.nii.gz
        -in mprage_brain.nii.gz
        -out highres2symmstandard.nii.gz
        -omat highres2symmstandard.mat
        -cost corratio
        -searchcost corratio
        -dof 12
        -interp trilinear    
        
    - Perform nonlinear registration (higres to standard) to symmetric standard brain. For details see `fnirt <http://fsl.fmrib.ox.ac.uk/fsl/fnirt/>`_::
    
        fnirt
        --in=head.nii.gz
        --aff=highres2symmstandard.mat
        --cout=highres2symmstandard_warp.nii.gz
        --iout=fnirt_highres2symmstandard.nii.gz
        --jout=highres2symmstandard_jac.nii.gz
        --config=T1_2_MNI152_2mm_symmetric.cnf
        --ref=MNI152_T1_2mm_symmetric.nii.gz
        --refmask=MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz
        --warpres=10,10,10 

    - Perform spatial smoothing on the input functional image(inputspec.rest_res_filt).  For details see `PrinciplesSmoothing <http://imaging.mrc-cbu.cam.ac.uk/imaging/PrinciplesSmoothing>`_ `fslmaths <http://www.fmrib.ox.ac.uk/fslcourse/lectures/practicals/intro/index.htm>`_::

        fslmaths rest_res_filt.nii.gz
        -kernel gauss FWHM/ sqrt(8-ln(2))
        -fmean -mas rest_mask.nii.gz
        rest_res_filt_FWHM.nii.gz
        
    - Apply nonlinear registration (func to standard). For details see  `applywarp <http://www.fmrib.ox.ac.uk/fsl/fnirt/warp_utils.html#applywarp>`_::
        
        applywarp
        --ref=MNI152_T1_2mm_symmetric.nii.gz
        --in=rest_res_filt_FWHM.nii.gz
        --out=rest_res_2symmstandard.nii.gz
        --warp=highres2symmstandard_warp.nii.gz
        --premat=example_func2highres.mat
        
        
    - Copy and L/R swap the output of applywarp command (rest_res_2symmstandard.nii.gz). For details see  `fslswapdim <http://fsl.fmrib.ox.ac.uk/fsl/fsl4.0/avwutils/index.html>`_::

        fslswapdim
        rest_res_2symmstandard.nii.gz
        -x y z
        tmp_LRflipped.nii.gz


    - Calculate pearson correlation between rest_res_2symmstandard.nii.gz and flipped rest_res_2symmstandard.nii.gz(tmp_LRflipped.nii.gz). For details see  `3dTcorrelate <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dTcorrelate.html>`_::
        
        3dTcorrelate
        -pearson
        -polort -1
        -prefix VMHC_FWHM.nii.gz
        rest_res_2symmstandard.nii.gz
        tmp_LRflipped.nii.gz
    
    
    - Fisher Z Transform the correlation. For details see `3dcalc <http://afni.nimh.nih.gov/pub/dist/doc/program_help/3dcalc.html>`_::
        
        3dcalc
        -a VMHC_FWHM.nii.gz
        -expr 'log((a+1)/(1-a))/2'
        -prefix VMHC_FWHM_Z.nii.gz
    
        
    - Calculate the number of volumes(nvols) in flipped rest_res_2symmstandard.nii.gz(tmp_LRflipped.nii.gz) ::
        
        -Use Nibabel to do this
        
        
    - Compute the Z statistic map ::
        
        3dcalc
        -a VMHC_FWHM_Z.nii.gz
        -expr 'a*sqrt('${nvols}'-3)'
        -prefix VMHC_FWHM_Z_stat.nii.gz
    
    
    Workflow:
    
    .. image:: ../images/vmhc_graph.dot.png
        :width: 500 
    
    Workflow Detailed:
    
    .. image:: ../images/vmhc_detailed_graph.dot.png
        :width: 500 
    

    References
    ----------
    
    .. [1] Zuo, X.-N., Kelly, C., Di Martino, A., Mennes, M., Margulies, D. S., Bangaru, S., Grzadzinski, R., et al. (2010). Growing together and growing apart: regional and sex differences in the lifespan developmental trajectories of functional homotopy. The Journal of neuroscience : the official journal of the Society for Neuroscience, 30(45), 15034-43. doi:10.1523/JNEUROSCI.2612-10.2010


    Examples
    --------
    
    >>> vmhc_w = create_vmhc()
    >>> vmhc_w.inputs.inputspec.symmetric_brain = 'MNI152_T1_2mm_brain_symmetric.nii.gz'
    >>> vmhc_w.inputs.inputspec.symmetric_skull = 'MNI152_T1_2mm_symmetric.nii.gz'
    >>> vmhc_w.inputs.inputspec.twomm_brain_mask_dil = 'MNI152_T1_2mm_brain_mask_symmetric_dil.nii.gz'
    >>> vmhc_w.inputs.inputspec.config_file_twomm = 'T1_2_MNI152_2mm_symmetric.cnf'
    >>> vmhc_w.inputs.inputspec.standard_for_func = 'MNI152_T1_2mm.nii.gz'
    >>> vmhc_w.inputs.fwhm_input.fwhm = [4.5, 6]
    >>> vmhc_w.get_node('fwhm_input').iterables = ('fwhm', [4.5, 6])
    >>> vmhc_w.inputs.inputspec.rest_res = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/func/original/rest_res_filt.nii.gz')
    >>> vmhc_w.inputs.inputspec.reorient = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/anat/mprage_RPI.nii.gz')
    >>> vmhc_w.inputs.inputspec.brain = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/anat/mprage_brain.nii.gz')
    >>> vmhc_w.inputs.inputspec.example_func2highres_mat = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/func/original/reg/example_func2highres.mat')
    >>> vmhc_w.inputs.inputspec.rest_mask = os.path.abspath('/home/data/Projects/Pipelines_testing/Dickstein/subjects/s1001/func/original/rest_mask.nii.gz')
    >>> vmhc_w.run() # doctest: +SKIP

    """

    vmhc = pe.Workflow(name='vmhc_workflow')
    inputNode = pe.Node(util.IdentityInterface(fields=['brain',
                                                'symmetric_brain',
                                                'rest_res',
                                                'reorient',
                                                'example_func2highres_mat',
                                                'symmetric_skull',
                                                'twomm_brain_mask_dil',
                                                'config_file_twomm',
                                                'rest_mask',
                                                'standard_for_func',
                                                'mean_functional']),
                        name='inputspec')

    outputNode = pe.Node(util.IdentityInterface(fields=['highres2symmstandard',
                                                'highres2symmstandard_mat',
                                                'highres2symmstandard_warp',
                                                'fnirt_highres2symmstandard',
                                                'highres2symmstandard_jac',
                                                'rest_res_2symmstandard',
                                                'VMHC_FWHM_img',
                                                'VMHC_Z_FWHM_img',
                                                'VMHC_Z_stat_FWHM_img'
                                                ]),
                        name='outputspec')


    inputnode_fwhm = pe.Node(util.IdentityInterface(fields=['fwhm']),
                             name='fwhm_input')


    if use_ants == False:

        ## Linear registration of T1 --> symmetric standard
        linear_T1_to_symmetric_standard = pe.Node(interface=fsl.FLIRT(),
                        name='linear_T1_to_symmetric_standard')
        linear_T1_to_symmetric_standard.inputs.cost = 'corratio'
        linear_T1_to_symmetric_standard.inputs.cost_func = 'corratio'
        linear_T1_to_symmetric_standard.inputs.dof = 12
        linear_T1_to_symmetric_standard.inputs.interp = 'trilinear'

        ## Perform nonlinear registration
        ##(higres to standard) to symmetric standard brain
        nonlinear_highres_to_symmetric_standard = pe.Node(interface=fsl.FNIRT(),
                      name='nonlinear_highres_to_symmetric_standard')
        nonlinear_highres_to_symmetric_standard.inputs.fieldcoeff_file = True
        nonlinear_highres_to_symmetric_standard.inputs.jacobian_file = True
        nonlinear_highres_to_symmetric_standard.inputs.warp_resolution = (10, 10, 10)

        # needs new inputs. needs input from resources for the field coeff of the template->symmetric.
        # and needs the field coeff of the anatomical-to-template registration

        ## Apply nonlinear registration (func to standard)
        nonlinear_func_to_standard = pe.Node(interface=fsl.ApplyWarp(),
                          name='nonlinear_func_to_standard')

    elif use_ants == True:

        # ANTS warp image etc.

        calculate_ants_xfm_vmhc = create_wf_calculate_ants_warp(name='calculate_ants_xfm_vmhc')

        fsl_to_itk_vmhc = create_wf_c3d_fsl_to_itk(0, name='fsl_to_itk_vmhc')

        collect_transforms_vmhc = create_wf_collect_transforms(0, name='collect_transforms_vmhc')

        apply_ants_xfm_vmhc = create_wf_apply_ants_warp(0,name='apply_ants_xfm_vmhc')


        calculate_ants_xfm_vmhc.inputs.inputspec.dimension = 3

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            use_histogram_matching = True

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            winsorize_lower_quantile = 0.01

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            winsorize_upper_quantile = 0.99

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            metric = ['MI','MI','CC']

        calculate_ants_xfm_vmhc.inputs.inputspec.metric_weight = [1,1,1]

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            radius_or_number_of_bins = [32,32,4]

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            sampling_strategy = ['Regular','Regular',None]

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            sampling_percentage = [0.25,0.25,None]

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            number_of_iterations = [[1000,500,250,100], \
            [1000,500,250,100], [100,100,70,20]]

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            convergence_threshold = [1e-8,1e-8,1e-9]

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            convergence_window_size = [10,10,15]

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            transforms = ['Rigid','Affine','SyN']

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            transform_parameters = [[0.1],[0.1],[0.1,3,0]]

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            shrink_factors = [[8,4,2,1],[8,4,2,1],[6,4,2,1]]

        calculate_ants_xfm_vmhc.inputs.inputspec. \
            smoothing_sigmas = [[3,2,1,0],[3,2,1,0],[3,2,1,0]]


        apply_ants_xfm_vmhc.inputs.inputspec.interpolation = 'Linear'
        apply_ants_xfm_vmhc.inputs.inputspec.input_image_type = 3


    ## copy and L/R swap file
    copy_and_L_R_swap = pe.Node(interface=fsl.SwapDimensions(),
                      name='copy_and_L_R_swap')
    copy_and_L_R_swap.inputs.new_dims = ('-x', 'y', 'z')

    ## caculate vmhc
    pearson_correlation = pe.Node(interface=preprocess.TCorrelate(),
                      name='pearson_correlation')
    pearson_correlation.inputs.pearson = True
    pearson_correlation.inputs.polort = -1
    pearson_correlation.inputs.outputtype = 'NIFTI_GZ'

    z_trans = pe.Node(interface=preprocess.Calc(),
                         name='z_trans')
    z_trans.inputs.expr = 'log((1+a)/(1-a))/2'
    z_trans.inputs.outputtype = 'NIFTI_GZ'

    z_stat = pe.Node(interface=preprocess.Calc(),
                        name='z_stat')
    z_stat.inputs.outputtype = 'NIFTI_GZ'

    NVOLS = pe.Node(util.Function(input_names=['in_files'],
                                  output_names=['nvols'],
                    function=get_img_nvols),
                    name='NVOLS')

    generateEXP = pe.Node(util.Function(input_names=['nvols'],
                                        output_names=['expr'],
                          function=get_operand_expression),
                          name='generateEXP')


    smooth = pe.Node(interface=fsl.MultiImageMaths(),
                        name='smooth')


    if use_ants == False:

        vmhc.connect(inputNode, 'brain',
                     linear_T1_to_symmetric_standard, 'in_file')
        vmhc.connect(inputNode, 'symmetric_brain',
                     linear_T1_to_symmetric_standard, 'reference')
        vmhc.connect(inputNode, 'reorient',
                     nonlinear_highres_to_symmetric_standard, 'in_file')
        vmhc.connect(linear_T1_to_symmetric_standard, 'out_matrix_file',
                     nonlinear_highres_to_symmetric_standard, 'affine_file')
        vmhc.connect(inputNode, 'symmetric_skull',
                     nonlinear_highres_to_symmetric_standard, 'ref_file')
        vmhc.connect(inputNode, 'twomm_brain_mask_dil',
                     nonlinear_highres_to_symmetric_standard, 'refmask_file')
        vmhc.connect(inputNode, 'config_file_twomm',
                     nonlinear_highres_to_symmetric_standard, 'config_file')


        vmhc.connect(inputNode, 'rest_res',
                     smooth, 'in_file')
        vmhc.connect(inputnode_fwhm, ('fwhm', set_gauss),
                     smooth, 'op_string')
        vmhc.connect(inputNode, 'rest_mask',
                     smooth, 'operand_files')
        vmhc.connect(smooth, 'out_file',
                     nonlinear_func_to_standard, 'in_file')
        vmhc.connect(inputNode, 'standard_for_func',
                     nonlinear_func_to_standard, 'ref_file')
        vmhc.connect(nonlinear_highres_to_symmetric_standard, 'fieldcoeff_file',
                     nonlinear_func_to_standard, 'field_file')
        ## func->anat matrix (bbreg)
        vmhc.connect(inputNode, 'example_func2highres_mat',
                     nonlinear_func_to_standard, 'premat')
        vmhc.connect(nonlinear_func_to_standard, 'out_file',
                     copy_and_L_R_swap, 'in_file')
        vmhc.connect(nonlinear_func_to_standard, 'out_file',
                     pearson_correlation, 'xset')

    elif use_ants == True:

        # connections for ANTS stuff

        # registration calculation stuff -- might go out the window
        vmhc.connect(inputNode, 'brain',
                     calculate_ants_xfm_vmhc, 'inputspec.anatomical_brain')
        vmhc.connect(inputNode, 'symmetric_brain',
                     calculate_ants_xfm_vmhc, 'inputspec.reference_brain')

        # functional apply warp stuff
        vmhc.connect(inputNode, 'rest_res',
                     smooth, 'in_file')
        vmhc.connect(inputnode_fwhm, ('fwhm', set_gauss),
                     smooth, 'op_string')
        vmhc.connect(inputNode, 'rest_mask',
                     smooth, 'operand_files')

        vmhc.connect(smooth, 'out_file',
                     apply_ants_xfm_vmhc, 'inputspec.input_image')

        vmhc.connect(calculate_ants_xfm_vmhc, 'outputspec.ants_rigid_xfm',
                     collect_transforms_vmhc, 'inputspec.linear_rigid')

        vmhc.connect(calculate_ants_xfm_vmhc, 'outputspec.ants_affine_xfm',
                     collect_transforms_vmhc, 'inputspec.linear_affine')

        vmhc.connect(calculate_ants_xfm_vmhc, 'outputspec.warp_field',
                     collect_transforms_vmhc, 'inputspec.warp_file')

        ## func->anat matrix (bbreg)
        vmhc.connect(inputNode, 'example_func2highres_mat',
                     fsl_to_itk_vmhc, 'inputspec.affine_file')

        vmhc.connect(inputNode, 'brain', fsl_to_itk_vmhc,
                     'inputspec.reference_file')

        vmhc.connect(inputNode, 'mean_functional', fsl_to_itk_vmhc,
                     'inputspec.source_file')

        vmhc.connect(fsl_to_itk_vmhc, 'outputspec.itk_transform', 
                     collect_transforms_vmhc, 'inputspec.fsl_to_itk_affine')

        '''
        vmhc.connect(inputNode, 'brain',
                     apply_ants_xfm_vmhc, 'inputspec.conversion_reference')
        vmhc.connect(inputNode, 'mean_functional',
                     apply_ants_xfm_vmhc, 'inputspec.conversion_source')
        '''

        vmhc.connect(inputNode, 'standard_for_func',
                     apply_ants_xfm_vmhc, 'inputspec.reference_image')

        vmhc.connect(collect_transforms_vmhc, \
                     'outputspec.transformation_series', \
                     apply_ants_xfm_vmhc, 'inputspec.transforms')

        vmhc.connect(apply_ants_xfm_vmhc, 'outputspec.output_image',
                     copy_and_L_R_swap, 'in_file')

        vmhc.connect(apply_ants_xfm_vmhc, 'outputspec.output_image',
                     pearson_correlation, 'xset')



    vmhc.connect(copy_and_L_R_swap, 'out_file',
                 pearson_correlation, 'yset')
    vmhc.connect(pearson_correlation, 'out_file',
                 z_trans, 'in_file_a')
    vmhc.connect(copy_and_L_R_swap, 'out_file',
                 NVOLS, 'in_files')
    vmhc.connect(NVOLS, 'nvols',
                 generateEXP, 'nvols')
    vmhc.connect(z_trans, 'out_file',
                 z_stat, 'in_file_a')
    vmhc.connect(generateEXP, 'expr',
                 z_stat, 'expr')

    if use_ants == False:

        vmhc.connect(linear_T1_to_symmetric_standard, 'out_file',
                     outputNode, 'highres2symmstandard')
        vmhc.connect(linear_T1_to_symmetric_standard, 'out_matrix_file',
                     outputNode, 'highres2symmstandard_mat')
        vmhc.connect(nonlinear_highres_to_symmetric_standard, 'jacobian_file',
                     outputNode, 'highres2symmstandard_jac')
        vmhc.connect(nonlinear_highres_to_symmetric_standard, 'fieldcoeff_file',
                     outputNode, 'highres2symmstandard_warp')
        vmhc.connect(nonlinear_highres_to_symmetric_standard, 'warped_file',
                     outputNode, 'fnirt_highres2symmstandard')
        vmhc.connect(nonlinear_func_to_standard, 'out_file',
                     outputNode, 'rest_res_2symmstandard')

    elif use_ants == True:

        # ANTS warp outputs to outputnode

        vmhc.connect(calculate_ants_xfm_vmhc, 'outputspec.ants_affine_xfm',
                     outputNode, 'highres2symmstandard_mat')
        vmhc.connect(calculate_ants_xfm_vmhc, 'outputspec.warp_field',
                     outputNode, 'highres2symmstandard_warp')
        vmhc.connect(calculate_ants_xfm_vmhc, 'outputspec.normalized_output_brain',
                     outputNode, 'fnirt_highres2symmstandard')
        vmhc.connect(apply_ants_xfm_vmhc, 'outputspec.output_image',
                     outputNode, 'rest_res_2symmstandard')


    vmhc.connect(pearson_correlation, 'out_file',
                 outputNode, 'VMHC_FWHM_img')
    vmhc.connect(z_trans, 'out_file',
                 outputNode, 'VMHC_Z_FWHM_img')
    vmhc.connect(z_stat, 'out_file',
                 outputNode, 'VMHC_Z_stat_FWHM_img')


    return vmhc
Exemplo n.º 19
0
                                             parameter_source = 'FSL',
                                             mask_type = 'file'),
                 iterfield=['realigned_files', 'realignment_parameters'],
                 name="art")
                
# Register structurals to a mni reference brain
# Use FLIRT first without skulls

mniFLIRT = pe.Node(interface=fsl.FLIRT(reference = strippedmfxTemplateBrain),
                   name = 'mniFLIRT')
                   
                
# THen leave the skulls on both brains 
# But apply the trasnformation to striped functionals later                                  
mniFNIRT = pe.Node(interface=fsl.FNIRT(ref_file=mfxTemplateBrain,
                                     config_file = mniConfig,
                                     field_file = True,
                                     fieldcoeff_file = True),
                 name = 'mniFNIRT')                 
                 
                         
func2MNI = pe.MapNode(interface = fsl.ApplyWarp(ref_file = mfxTemplateBrain),
                         iterfield=['in_file','premat'],
                         name = 'func2MNI')
                         
#Generate a mean functional (it's quicker to check a mean then a timesearies)
meanfunc3 = pe.MapNode(interface=fsl.ImageMaths(op_string='-Tmean',
                                                suffix='_mean'),
                       iterfield=['in_file'],
                       name='meanfunc3')
                       
#Generate a mean functional (it's quicker to check a mean then a timesearies)
Exemplo n.º 20
0
def create_registration_pipeline(working_dir,
                                 freesurfer_dir,
                                 ds_dir,
                                 name='registration'):
    """
    find transformations between struct, funct, and MNI
    """

    # initiate workflow
    reg_wf = Workflow(name=name)
    reg_wf.base_dir = os.path.join(working_dir, 'LeiCA_resting',
                                   'rsfMRI_preprocessing')

    # set fsl output
    fsl.FSLCommand.set_default_output_type('NIFTI_GZ')
    freesurfer.FSCommand.set_default_subjects_dir(freesurfer_dir)

    # inputnode
    inputnode = Node(util.IdentityInterface(fields=[
        'initial_mean_epi_moco', 't1w', 't1w_brain', 'subject_id',
        'wm_mask_4_bbr', 'struct_brain_mask'
    ]),
                     name='inputnode')

    outputnode = Node(util.IdentityInterface(fields=[
        'struct_2_MNI_warp', 'epi_2_struct_mat', 'struct_2_epi_mat',
        'epi_2_MNI_warp', 'MNI_2_epi_warp', 'fs_2_struct_mat',
        'mean_epi_structSpace', 'mean_epi_MNIspace', 'struct_MNIspace'
    ]),
                      name='outputnode')

    ds = Node(nio.DataSink(base_directory=ds_dir), name='ds')
    ds.inputs.substitutions = [('_TR_id_', 'TR_')]

    ##########################################
    # TOC REGISTRATION MATS AND WARPS
    ##########################################
    # I. STRUCT -> MNI
    ## 1. STRUCT -> MNI with FLIRT
    ## 2. CALC. WARP STRUCT -> MNI with FNIRT

    # II.EPI -> STRUCT
    ## 3. calc EPI->STRUCT initial registration
    ## 4. run EPI->STRUCT via bbr
    ## 5. INVERT to get: STRUCT -> EPI

    # III. COMBINE I. & II.: EPI -> MNI
    ## 6. COMBINE MATS: EPI -> MNI
    ## 7. MNI -> EPI

    ##########################################
    # CREATE REGISTRATION MATS AND WARPS
    ##########################################

    # I. STRUCT -> MNI
    ##########################################
    # 1. REGISTER STRUCT -> MNI with FLIRT
    struct_2_MNI_mat = Node(fsl.FLIRT(dof=12), name='struct_2_MNI_mat')
    struct_2_MNI_mat.inputs.reference = fsl.Info.standard_image(
        'MNI152_T1_2mm_brain.nii.gz')

    reg_wf.connect(inputnode, 't1w_brain', struct_2_MNI_mat, 'in_file')
    reg_wf.connect(struct_2_MNI_mat, 'out_matrix_file', outputnode,
                   'struct_2_MNI_mat_flirt')

    # 2. CALC. WARP STRUCT -> MNI with FNIRT
    # cf. wrt. 2mm
    # https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=ind1311&L=FSL&P=R86108&1=FSL&9=A&J=on&d=No+Match%3BMatch%3BMatches&z=4
    struct_2_MNI_warp = Node(fsl.FNIRT(), name='struct_2_MNI_warp')
    struct_2_MNI_warp.inputs.config_file = 'T1_2_MNI152_2mm'
    struct_2_MNI_warp.inputs.ref_file = fsl.Info.standard_image(
        'MNI152_T1_2mm.nii.gz')
    struct_2_MNI_warp.inputs.field_file = 'struct_2_MNI_warp.nii.gz'
    struct_2_MNI_warp.plugin_args = {'submit_specs': 'request_memory = 4000'}

    reg_wf.connect(inputnode, 't1w', struct_2_MNI_warp, 'in_file')
    reg_wf.connect(struct_2_MNI_mat, 'out_matrix_file', struct_2_MNI_warp,
                   'affine_file')
    reg_wf.connect(struct_2_MNI_warp, 'field_file', ds,
                   'registration.struct_2_MNI_warp')
    reg_wf.connect(struct_2_MNI_warp, 'field_file', outputnode,
                   'struct_2_MNI_warp')
    reg_wf.connect(struct_2_MNI_warp, 'warped_file', outputnode,
                   'struct_MNIspace')
    reg_wf.connect(struct_2_MNI_warp, 'warped_file', ds,
                   'registration.struct_MNIspace')

    # II.EPI -> STRUCT (via bbr)
    ##########################################

    # 3. calc EPI->STRUCT initial registration with flirt dof=6 and corratio
    epi_2_struct_flirt6_mat = Node(fsl.FLIRT(dof=6, cost='corratio'),
                                   name='epi_2_struct_flirt6_mat')
    epi_2_struct_flirt6_mat.inputs.out_file = 'epi_structSpace_flirt6.nii.gz'
    reg_wf.connect(inputnode, 't1w_brain', epi_2_struct_flirt6_mat,
                   'reference')
    reg_wf.connect(inputnode, 'initial_mean_epi_moco', epi_2_struct_flirt6_mat,
                   'in_file')

    # 4. run EPI->STRUCT via bbr
    bbr_shedule = os.path.join(os.getenv('FSLDIR'), 'etc/flirtsch/bbr.sch')
    epi_2_struct_bbr_mat = Node(interface=fsl.FLIRT(dof=6, cost='bbr'),
                                name='epi_2_struct_bbr_mat')
    epi_2_struct_bbr_mat.inputs.schedule = bbr_shedule
    epi_2_struct_bbr_mat.inputs.out_file = 'epi_structSpace.nii.gz'
    reg_wf.connect(inputnode, 'initial_mean_epi_moco', epi_2_struct_bbr_mat,
                   'in_file')
    reg_wf.connect(inputnode, 't1w_brain', epi_2_struct_bbr_mat, 'reference')
    reg_wf.connect(epi_2_struct_flirt6_mat, 'out_matrix_file',
                   epi_2_struct_bbr_mat, 'in_matrix_file')
    reg_wf.connect(inputnode, 'wm_mask_4_bbr', epi_2_struct_bbr_mat, 'wm_seg')
    reg_wf.connect(epi_2_struct_bbr_mat, 'out_matrix_file', ds,
                   'registration.epi_2_struct_mat')
    reg_wf.connect(epi_2_struct_bbr_mat, 'out_file', outputnode,
                   'mean_epi_structSpace')

    # 5. INVERT to get: STRUCT -> EPI
    struct_2_epi_mat = Node(fsl.ConvertXFM(invert_xfm=True),
                            name='struct_2_epi_mat')
    reg_wf.connect(epi_2_struct_bbr_mat, 'out_matrix_file', struct_2_epi_mat,
                   'in_file')
    reg_wf.connect(struct_2_epi_mat, 'out_file', outputnode,
                   'struct_2_epi_mat')

    # III. COMBINE I. & II.: EPI -> MNI
    ##########################################
    # 6. COMBINE MATS: EPI -> MNI
    epi_2_MNI_warp = Node(fsl.ConvertWarp(), name='epi_2_MNI_warp')
    epi_2_MNI_warp.inputs.reference = fsl.Info.standard_image(
        'MNI152_T1_2mm.nii.gz')
    reg_wf.connect(epi_2_struct_bbr_mat, 'out_matrix_file', epi_2_MNI_warp,
                   'premat')  # epi2struct
    reg_wf.connect(struct_2_MNI_warp, 'field_file', epi_2_MNI_warp,
                   'warp1')  # struct2mni
    reg_wf.connect(epi_2_MNI_warp, 'out_file', outputnode, 'epi_2_MNI_warp')
    reg_wf.connect(epi_2_MNI_warp, 'out_file', ds,
                   'registration.epi_2_MNI_warp')

    # output: out_file

    # 7. MNI -> EPI
    MNI_2_epi_warp = Node(fsl.InvWarp(), name='MNI_2_epi_warp')
    MNI_2_epi_warp.inputs.reference = fsl.Info.standard_image(
        'MNI152_T1_2mm.nii.gz')
    reg_wf.connect(epi_2_MNI_warp, 'out_file', MNI_2_epi_warp, 'warp')
    reg_wf.connect(inputnode, 'initial_mean_epi_moco', MNI_2_epi_warp,
                   'reference')
    reg_wf.connect(MNI_2_epi_warp, 'inverse_warp', outputnode,
                   'MNI_2_epi_warp')
    # output: inverse_warp

    ##########################################
    # TRANSFORM VOLUMES
    ##########################################

    # CREATE STRUCT IN EPI SPACE FOR DEBUGGING
    struct_epiSpace = Node(fsl.ApplyXfm(), name='struct_epiSpace')
    struct_epiSpace.inputs.out_file = 'struct_brain_epiSpace.nii.gz'
    reg_wf.connect(inputnode, 't1w_brain', struct_epiSpace, 'in_file')
    reg_wf.connect(inputnode, 'initial_mean_epi_moco', struct_epiSpace,
                   'reference')
    reg_wf.connect(struct_2_epi_mat, 'out_file', struct_epiSpace,
                   'in_matrix_file')
    reg_wf.connect(struct_epiSpace, 'out_file', ds, 'QC.struct_brain_epiSpace')

    # CREATE EPI IN MNI SPACE
    mean_epi_MNIspace = Node(fsl.ApplyWarp(), name='mean_epi_MNIspace')
    mean_epi_MNIspace.inputs.ref_file = fsl.Info.standard_image(
        'MNI152_T1_2mm_brain.nii.gz')
    mean_epi_MNIspace.inputs.out_file = 'mean_epi_MNIspace.nii.gz'
    reg_wf.connect(inputnode, 'initial_mean_epi_moco', mean_epi_MNIspace,
                   'in_file')
    reg_wf.connect(epi_2_MNI_warp, 'out_file', mean_epi_MNIspace, 'field_file')
    reg_wf.connect(mean_epi_MNIspace, 'out_file', ds,
                   'registration.mean_epi_MNIspace')
    reg_wf.connect(mean_epi_MNIspace, 'out_file', outputnode,
                   'mean_epi_MNIspace')

    # CREATE MNI IN EPI SPACE FOR DEBUGGING
    MNI_epiSpace = Node(fsl.ApplyWarp(), name='MNI_epiSpace')
    MNI_epiSpace.inputs.in_file = fsl.Info.standard_image(
        'MNI152_T1_2mm_brain.nii.gz')
    MNI_epiSpace.inputs.out_file = 'MNI_epiSpace.nii.gz'
    reg_wf.connect(inputnode, 'initial_mean_epi_moco', MNI_epiSpace,
                   'ref_file')
    reg_wf.connect(MNI_2_epi_warp, 'inverse_warp', MNI_epiSpace, 'field_file')
    reg_wf.connect(MNI_epiSpace, 'out_file', ds, 'registration.MNI_epiSpace')

    reg_wf.write_graph(dotfilename=reg_wf.name, graph2use='flat', format='pdf')

    return reg_wf
Exemplo n.º 21
0
def create_fsl_workflow(data_dir=None, subjects=None, name="fslwarp"):
    """Set up the anatomical normalzation workflow using FNIRT.

    Your anatomical data must have been processed in Freesurfer.
    Unlike most lyman workflows, the DataGrabber and DataSink
    nodes are hardwired within the returned workflow, as this
    tightly integrates with the Freesurfer subjects directory
    structure.

    Parameters
    ----------
    data_dir : path
        top level of data hierarchy/FS subjects directory
    subjects : list of strings
        list of subject IDs
    name : alphanumeric string, optional
        workflow name

    """
    if data_dir is None:
        data_dir = os.environ["SUBJECTS_DIR"]
    if subjects is None:
        subjects = []

    # Get target images
    target_brain = fsl.Info.standard_image("avg152T1_brain.nii.gz")
    target_head = fsl.Info.standard_image("avg152T1.nii.gz")
    hires_head = fsl.Info.standard_image("MNI152_T1_1mm.nii.gz")
    target_mask = fsl.Info.standard_image(
        "MNI152_T1_2mm_brain_mask_dil.nii.gz")
    fnirt_cfg = os.path.join(os.environ["FSLDIR"],
                             "etc/flirtsch/T1_2_MNI152_2mm.cnf")

    # Subject source node
    subjectsource = Node(IdentityInterface(fields=["subject_id"]),
                         iterables=("subject_id", subjects),
                         name="subjectsource")

    # Grab recon-all outputs
    head_image = "T1"
    templates = dict(aseg="{subject_id}/mri/aparc+aseg.mgz",
                     head="{subject_id}/mri/" + head_image + ".mgz")
    datasource = Node(SelectFiles(templates, base_directory=data_dir),
                      "datasource")

    # Convert images to nifti storage and float representation
    cvtaseg = Node(fs.MRIConvert(out_type="niigz"), "convertaseg")

    cvthead = Node(fs.MRIConvert(out_type="niigz", out_datatype="float"),
                   "converthead")

    # Turn the aparc+aseg into a brainmask
    makemask = Node(fs.Binarize(dilate=1, min=0.5), "makemask")

    # Extract the brain from the orig.mgz using the mask
    skullstrip = Node(fsl.ApplyMask(), "skullstrip")

    # FLIRT brain to MNI152_brain
    flirt = Node(fsl.FLIRT(reference=target_brain), "flirt")

    sw = [-180, 180]
    for dim in ["x", "y", "z"]:
        setattr(flirt.inputs, "searchr_%s" % dim, sw)

    # FNIRT head to MNI152
    fnirt = Node(
        fsl.FNIRT(ref_file=target_head,
                  refmask_file=target_mask,
                  config_file=fnirt_cfg,
                  fieldcoeff_file=True), "fnirt")

    # Warp and rename the images
    warpbrain = Node(
        fsl.ApplyWarp(ref_file=target_head,
                      interp="spline",
                      out_file="brain_warp.nii.gz"), "warpbrain")

    warpbrainhr = Node(
        fsl.ApplyWarp(ref_file=hires_head,
                      interp="spline",
                      out_file="brain_warp_hires.nii.gz"), "warpbrainhr")

    # Generate a png summarizing the registration
    warpreport = Node(WarpReport(), "warpreport")

    # Save relevant files to the data directory
    fnirt_subs = [(head_image + "_out_masked_flirt.mat", "affine.mat"),
                  (head_image + "_out_fieldwarp", "warpfield"),
                  (head_image + "_out_masked", "brain"),
                  (head_image + "_out", "T1")]
    datasink = Node(
        DataSink(base_directory=data_dir,
                 parameterization=False,
                 substitutions=fnirt_subs), "datasink")

    # Define and connect the workflow
    # -------------------------------

    normalize = Workflow(name=name)

    normalize.connect([
        (subjectsource, datasource, [("subject_id", "subject_id")]),
        (datasource, cvtaseg, [("aseg", "in_file")]),
        (datasource, cvthead, [("head", "in_file")]),
        (cvtaseg, makemask, [("out_file", "in_file")]),
        (cvthead, skullstrip, [("out_file", "in_file")]),
        (makemask, skullstrip, [("binary_file", "mask_file")]),
        (skullstrip, flirt, [("out_file", "in_file")]),
        (flirt, fnirt, [("out_matrix_file", "affine_file")]),
        (cvthead, fnirt, [("out_file", "in_file")]),
        (skullstrip, warpbrain, [("out_file", "in_file")]),
        (fnirt, warpbrain, [("fieldcoeff_file", "field_file")]),
        (skullstrip, warpbrainhr, [("out_file", "in_file")]),
        (fnirt, warpbrainhr, [("fieldcoeff_file", "field_file")]),
        (warpbrain, warpreport, [("out_file", "in_file")]),
        (subjectsource, datasink, [("subject_id", "container")]),
        (skullstrip, datasink, [("out_file", "normalization.@brain")]),
        (cvthead, datasink, [("out_file", "normalization.@t1")]),
        (flirt, datasink, [("out_file", "normalization.@brain_flirted")]),
        (flirt, datasink, [("out_matrix_file", "normalization.@affine")]),
        (warpbrain, datasink, [("out_file", "normalization.@brain_warped")]),
        (warpbrainhr, datasink, [("out_file", "normalization.@brain_hires")]),
        (fnirt, datasink, [("fieldcoeff_file", "normalization.@warpfield")]),
        (warpreport, datasink, [("out_file", "normalization.@report")]),
    ])

    return normalize
Exemplo n.º 22
0
    def non_linear_registration_( self ):
        """Non-linear registration. Second part in the study template creation. Estimation of the registration parameters of brain to study oriented standard brain template."""
        try:
        #
        #
            #
            # Use the linear template built in the linear_registration_ funstion
            template_linear        = os.path.join(self.ana_dir_, "temp_T1_lin.nii.gz")
            template_T1_brain_lin  = os.path.join(self.ana_dir_, "temp_T1_brain_lin.nii.gz")
            # check if it has been built
            if not os.path.exists(template_linear):
                raise Exception( "Template %s has not been built yet. User has to process the linear step first"%template_linear )

            #
            # Loop on the tasks
            while True:
                # get the item
                item = self.queue_[1].get()
                # registration estimation
                flt = fsl.FLIRT()
                flt.inputs.in_file         = os.path.join(self.T1_brain_dir_, item )
                flt.inputs.reference       = template_T1_brain_lin
                flt.inputs.out_file        = os.path.join( self.template_dir_, "%s_non_li_MNI.nii.gz"%item[:-7] )
                flt.inputs.out_matrix_file = os.path.join( self.template_dir_, "%s_non_li_MNI.mat"%item[:-7] )
                flt.inputs.dof             = 12
                res = flt.run()

                #
                # Find the matching T1 image
                PIDN    = [int(s) for s in item.split("_") if s.isdigit()]
                #
                T1_item = [ s for s in self.list_T1_ if str(PIDN[0]) in s]

                #
                # apply registration using T1_2_MNI152_2mm.cnf configuration file
                T1_2_MNI152_2mm = ""
                if os.environ.get('FSLDIR'):
                    T1_2_MNI152_2mm = os.path.join( os.environ.get('FSLDIR'), 
                                                    "etc","flirtsch","T1_2_MNI152_2mm.cnf" )
                #
                fnt = fsl.FNIRT()
                fnt.inputs.in_file         = os.path.join( self.T1_dir_,  T1_item[0] )
                fnt.inputs.ref_file        = template_linear
                fnt.inputs.warped_file     = os.path.join( self.template_dir_, "%s_non_li_MNI_fnirt.nii.gz"%item[:-7] )
                fnt.inputs.affine_file     = os.path.join( self.template_dir_, "%s_non_li_MNI.mat"%item[:-7] )
                fnt.inputs.config_file     = T1_2_MNI152_2mm
                fnt.inputs.fieldcoeff_file = os.path.join( self.template_dir_, "%s_non_li_MNI_coeff.nii.gz"%item[:-7] )
                res = fnt.run()
                # apply warp
                aw = fsl.ApplyWarp()
                aw.inputs.in_file    = os.path.join( self.T1_dir_, T1_item[0] )
                aw.inputs.ref_file   = template_linear
                aw.inputs.out_file   = os.path.join( self.template_dir_, "%s_non_li_MNI_warped.nii.gz"%item[:-7] )
                aw.inputs.field_file = os.path.join( self.template_dir_, "%s_non_li_MNI_coeff.nii.gz"%item[:-7] )
                res = aw.run()
                # lock and add the file
                singlelock.acquire()
                self.non_linear_MNI_.append( aw.inputs.out_file )
                singlelock.release()
                # job is done
                self.queue_[1].task_done()
        #
        #
        except Exception as inst:
            print inst
            _log.error(inst)
            quit(-1)
        except IOError as e:
            print "I/O error({0}): {1}".format(e.errno, e.strerror)
            quit(-1)
        except:
            print "Unexpected error:", sys.exc_info()[0]
            quit(-1)
Exemplo n.º 23
0
def create_resting():

    # main workflow
    func_preproc = Workflow(name='resting')

    inputnode = Node(util.IdentityInterface(fields=[
        'subject_id', 'out_dir', 'freesurfer_dir', 'func', 'rs_mag', 'rs_ph',
        'anat_head', 'anat_brain', 'anat_brain_mask', 'wmseg', 'csfseg',
        'vol_to_remove', 'TR', 'highpass_freq', 'epi_resolution', 'echo_space',
        'te_diff', 'fwhm', 'pe_dir', 'composite_transform', 'standard_brain',
        'standard_downsampled'
    ]),
                     name='inputnode')

    #Use correct subject ID from long timepoint for bbregister
    def change_subject_id(subject):
        import re
        [subj, ses] = re.split("_", subject)

        new_subject_id = subject + '.long.' + subj
        return new_subject_id

    change_subject_id = Node(util.Function(input_names=["subject"],
                                           output_names=["new_subject_id"],
                                           function=change_subject_id),
                             name="change_subject_id")

    outputnode = Node(util.IdentityInterface(fields=[
        'brain', 'brainmask', 'anat2std_transforms', 'std2anat_transforms',
        'anat2std', 'anat_head', 'wmseg', 'csfseg', 'wmedge', 'subject_id'
    ]),
                      name='outputnode')

    ##PREPROCESSING FOR AROMA (Steps 1 - 7)
    def merge_if_list(in_file):
        if type(in_file) == list:
            import numpy as np
            import nibabel as nb
            import os
            from nipype.utils.filemanip import split_filename
            nii1 = nb.load(in_file[0])
            nii1d = nii1.get_data()
            nii2 = nb.load(in_file[1])
            nii2d = nii2.get_data()
            x = np.concatenate((nii1d, nii2d), axis=3)
            new_nii = nb.Nifti1Image(x, nii1.get_affine(), nii1.get_header())
            new_nii.set_data_dtype(np.float32)
            _, base, _ = split_filename(in_file[0])
            nb.save(new_nii, base + "_merged.nii.gz")
            return os.path.abspath(base + "_merged.nii.gz")
        else:
            return in_file

    #if rsfmri is a list -> merge files, otherwise return single list.
    merge_rs = Node(util.Function(input_names=['in_file'],
                                  output_names=["out_file"],
                                  function=merge_if_list),
                    name='merge_rs')

    # node to remove first volumes
    remove_vol = Node(util.Function(input_names=['in_file', 't_min'],
                                    output_names=["out_file"],
                                    function=strip_rois_func),
                      name='remove_vol')

    # workflow for motion correction
    moco = create_moco_pipeline()

    # workflow for fieldmap correction and coregistration
    fmap_coreg = create_fmap_coreg_pipeline()

    # workflow for applying transformations to timeseries
    transform_ts = create_transform_pipeline()

    #mean intensity normalization
    meanintensnorm = Node(fsl.ImageMaths(op_string='-ing 10000'),
                          name='meanintensnorm')

    smoothing = create_smoothing_pipeline()

    # connections
    func_preproc.connect([
        (inputnode, merge_rs, [('func', 'in_file')]),
        (merge_rs, remove_vol, [('out_file', 'in_file')]),
        (inputnode, remove_vol, [('vol_to_remove', 't_min')]),
        (inputnode, moco, [('anat_brain_mask', 'inputnode.brainmask')]),
        (remove_vol, moco, [('out_file', 'inputnode.epi')]),
        (inputnode, change_subject_id, [('subject_id', 'subject')]),
        (change_subject_id, fmap_coreg, [('new_subject_id',
                                          'inputnode.fs_subject_id')]),
        (inputnode, fmap_coreg, [('rs_mag', 'inputnode.mag'),
                                 ('rs_ph', 'inputnode.phase'),
                                 ('freesurfer_dir',
                                  'inputnode.fs_subjects_dir'),
                                 ('echo_space', 'inputnode.echo_space'),
                                 ('te_diff', 'inputnode.te_diff'),
                                 ('pe_dir', 'inputnode.pe_dir'),
                                 ('anat_head', 'inputnode.anat_head'),
                                 ('anat_brain', 'inputnode.anat_brain')]),
        (moco, fmap_coreg, [('outputnode.epi_mean', 'inputnode.epi_mean')]),
        (remove_vol, transform_ts, [('out_file', 'inputnode.orig_ts')]),
        (inputnode, transform_ts, [('anat_head', 'inputnode.anat_head')]),
        (inputnode, transform_ts, [('anat_brain_mask', 'inputnode.brain_mask')
                                   ]),
        (inputnode, transform_ts, [('epi_resolution', 'inputnode.resolution')
                                   ]),
        (moco, transform_ts, [('outputnode.mat_moco', 'inputnode.mat_moco')]),
        (fmap_coreg, transform_ts, [('outputnode.fmap_fullwarp',
                                     'inputnode.fullwarp')]),
        (transform_ts, meanintensnorm, [('outputnode.trans_ts', 'in_file')]),
        (meanintensnorm, smoothing, [('out_file', 'inputnode.ts_transformed')
                                     ]),
        (inputnode, smoothing, [('fwhm', 'inputnode.fwhm')])
    ])

    ##CALCULATE TRANSFORM from anatomical to standard space with FSL tools
    # Anat > Standard
    # register high-resolution to standard template with non-linear transform
    # flirt serves as preparation for fnirt)

    #reorient brain to standard (because Freesurfer space can cause problems)
    reorient2std = Node(fsl.Reorient2Std(), name="reorient2std")

    reorient2std_rs = Node(fsl.Reorient2Std(), name="reorient2std_rs")
    reorient2std_mask = Node(fsl.Reorient2Std(), name="reorient2std_mask")

    flirt_prep = Node(fsl.FLIRT(cost_func='mutualinfo', interp='trilinear'),
                      name='flirt_prep')
    flirt_prep.inputs.interp = 'trilinear'
    flirt_prep.inputs.dof = 12

    fnirt = Node(fsl.FNIRT(), name='fnirt')
    fnirt.inputs.field_file = True
    fnirt.inputs.fieldcoeff_file = True

    func_preproc.connect([
        (inputnode, reorient2std, [('anat_brain', 'in_file')]),
        (reorient2std, flirt_prep, [('out_file', 'in_file')]),
        #(inputnode, flirt_prep,  [('anat_brain', 'in_file')]),
        (inputnode, flirt_prep, [('standard_brain', 'reference')]),
        (flirt_prep, fnirt, [('out_matrix_file', 'affine_file')]),
        (reorient2std, fnirt, [('out_file', 'in_file')]),
        (inputnode, fnirt, [('standard_brain', 'ref_file')]),
    ])

    def getcwd(subject_id):
        import os
        tmp = os.getcwd()
        tmp = tmp[:-6]
        tmp = tmp + 'ica_aroma/out'  #%(subject_id)
        return tmp

    get_wd = Node(util.Function(input_names=['subject_id'],
                                output_names=["d"],
                                function=getcwd),
                  name='get_wd')

    ica_aroma = Node(ICA_AROMA(), name="ica_aroma")
    ica_aroma.inputs.denoise_type = 'both'
    #ica_aroma.inputs.out_dir = os.getcwd()

    func_preproc.connect([
        (moco, ica_aroma, [('outputnode.par_moco', 'motion_parameters')]),
        (smoothing, reorient2std_rs, [('outputnode.ts_smoothed', 'in_file')]),
        (reorient2std_rs, ica_aroma, [('out_file', 'in_file')]),
        (fnirt, ica_aroma, [('field_file', 'fnirt_warp_file')]),
        (transform_ts, reorient2std_mask, [('outputnode.comb_mask_resamp',
                                            'in_file')]),
        (reorient2std_mask, ica_aroma, [('out_file', 'mask')]),
        (inputnode, get_wd, [('subject_id', 'subject_id')]),
        (get_wd, ica_aroma, [('d', 'out_dir')])
    ])

    ##POSTPROCESSING
    postprocess = create_denoise_pipeline()

    func_preproc.connect([
        (reorient2std_mask, postprocess, [
            ('out_file', 'inputnode.brain_mask')
        ]),  #use the correctly oriented mask                           
        (ica_aroma, postprocess, [
            ('nonaggr_denoised_file', 'inputnode.epi_coreg')
        ]),  #use the nonaggr_denoised_file
        (inputnode, postprocess, [('TR', 'inputnode.tr')]),
        (inputnode, postprocess, [('highpass_freq', 'inputnode.highpass_freq')
                                  ]),
        (inputnode, postprocess, [('wmseg', 'inputnode.wmseg')]),
        (inputnode, postprocess, [('csfseg', 'inputnode.csfseg')]),
    ])

    #outputnode
    outputnode = Node(util.IdentityInterface(fields=[
        'par', 'rms', 'mean_epi', 'tsnr', 'stddev_file', 'realigned_ts',
        'fmap', 'unwarped_mean_epi2fmap', 'coregistered_epi2fmap',
        'fmap_fullwarp', 'epi2anat', 'epi2anat_mat', 'epi2anat_dat',
        'epi2anat_mincost', 'full_transform_ts', 'full_transform_mean',
        'resamp_t1', 'comb_mask_resamp', 'dvars_file', 'out_flirt_prep',
        'out_matrix_flirt_prep', 'out_warped', 'out_warp_field',
        'aggr_denoised_file', 'nonaggr_denoised_file', 'out_dir', 'wmcsf_mask',
        'combined_motion', 'comp_regressor', 'comp_F', 'comp_pF', 'out_betas',
        'ts_fullspectrum', 'ts_filtered'
    ]),
                      name='outputnode')

    # connections
    func_preproc.connect([
        (
            moco,
            outputnode,
            [  #('outputnode.epi_moco', 'realign.@realigned_ts'),
                ('outputnode.par_moco', 'par'),
                ('outputnode.rms_moco', 'rms'),
                ('outputnode.epi_moco', 'realigned_ts'),
                ('outputnode.epi_mean', 'mean_epi'),
                ('outputnode.tsnr_file', 'tsnr'),
                ('outputnode.stddev_file', 'stddev'),
            ]),
        (fmap_coreg, outputnode,
         [('outputnode.fmap', 'fmap'),
          ('outputnode.unwarped_mean_epi2fmap', 'unwarped_mean_epi2fmap'),
          ('outputnode.epi2fmap', 'coregistered_epi2fmap'),
          ('outputnode.fmap_fullwarp', 'fmap_fullwarp'),
          ('outputnode.epi2anat', 'epi2anat'),
          ('outputnode.epi2anat_mat', 'epi2anat_mat'),
          ('outputnode.epi2anat_dat', 'epi2anat_dat'),
          ('outputnode.epi2anat_mincost', 'epi2anat_mincost')]),
        (transform_ts, outputnode,
         [('outputnode.trans_ts', 'full_transform_ts'),
          ('outputnode.trans_ts_mean', 'full_transform_mean'),
          ('outputnode.resamp_t1', 'resamp_t1'),
          ('outputnode.comb_mask_resamp', 'comb_mask_resamp'),
          ('outputnode.out_dvars', 'dvars_file')]),
        (flirt_prep, outputnode, [('out_file', 'out_flirt_prep'),
                                  ('out_matrix_file', 'out_matrix_flirt_prep')
                                  ]),
        (fnirt, outputnode, [('warped_file', 'out_warped'),
                             ('field_file', 'out_warp_field')]),
        (ica_aroma, outputnode, [('aggr_denoised_file', 'aggr_denoised_file'),
                                 ('nonaggr_denoised_file',
                                  'nonaggr_denoised_file'),
                                 ('out_dir', 'out_dir')]),
        (postprocess, outputnode,
         [('outputnode.wmcsf_mask', 'wmcsf_mask'),
          ('outputnode.combined_motion', 'combined_motion'),
          ('outputnode.comp_regressor', 'comp_regressor'),
          ('outputnode.comp_F', 'comp_F'), ('outputnode.comp_pF', 'comp_pF'),
          ('outputnode.out_betas', 'out_betas'),
          ('outputnode.ts_fullspectrum', 'ts_fullspectrum'),
          ('outputnode.ts_filtered', 'ts_filtered')])
    ])

    return func_preproc
Exemplo n.º 24
0
    def get_ADC(LinADC):
        """
        in the future, users will be able to specify which time point
        to use as reference
        """
        return LinADC[0]

    get_Ref = pe.JoinNode(interface=util.Function(input_names=['LinADC'],
                                                  output_names=['REF'],
                                                  function=get_ADC),
                          name='get_Ref',
                          joinsource='data',
                          joinfield='LinADC')

    ADCwarpHighRes = pe.Node(interface=fsl.FNIRT(), name='ADCwarpHighRes')
    ADCwarpHighRes.inputs.field_file = True
    ADCwarpHighRes.inputs.config_file = fnirt_config

    TumorwarpHighRes = pe.Node(interface=fsl.ApplyWarp(),
                               name='TumorwarpHighRes')

    REFwarpHighRes = pe.Node(interface=fsl.ApplyWarp(), name='REFwarpHighRes')

    NormalwarpHighRes = pe.Node(interface=fsl.ApplyWarp(),
                                name='NormalwarpHighRes')

    Warp = pe.Workflow(name='Warp')
    Warp.base_dir = parent_dir + '/FDM'
    Warp.connect([
        (get_Ref, ADCwarpHighRes, [('REF', 'ref_file')]),
Exemplo n.º 25
0
    def anatomical_registration(self, subject, standard_image_name='MNI152_T1_2mm_brain.nii.gz' ):
        """
            Anatomical Registration

            1) Runs FLIRT on the brain extracted anatomy image with MNI152_T1_2mm_brain.nii.gz as reference
            2) Runs FNIRT on the anatomy image

            Outputs:
                 anatomy/reg/highres2standard.nii.gz
                 anatomy/reg/highres2standard.mat
                 anatomy/reg/highres2highres_jac
                 anatomy/reg/highres2standard_warp.nii.gz

            Parameters
                subject = Subject Dir object
                standard_image_name = The anatomy reference image

        """
        print ">>> Anatomical registration"

        brain_image = subject.anatomical_nii('brain')

        reg_dir = os.path.join(subject.anatomical_dir(), 'reg')
        out_file = os.path.join(reg_dir, 'highres2standard.nii.gz')
        out_mat_file = os.path.join(reg_dir, 'highres2standard.mat')

        standard_image = fsl.Info.standard_image(standard_image_name)

        if not os.path.isfile(out_mat_file):
            print ">>>> FLIRT"
            os.mkdir(reg_dir)
            flirt = fsl.FLIRT(in_file=brain_image,
                              reference=standard_image,
                              out_file=out_file,
                              out_matrix_file=out_mat_file,
                              cost='corratio', # ('mutualinfo' or 'corratio' or 'normcorr' or 'normmi' or 'leastsq' or 'labeldiff' or 'bbr')
                              dof=12, # number of transform degrees of freedom
                              searchr_x=[-90, 90], # search angles along x-axis, in degrees
                              searchr_y=[-90, 90], # search angles along y-axis, in degrees
                              searchr_z=[-90, 90], # search angles along z-axis, in degrees
                              interp='trilinear') # 'trilinear' or 'nearestneighbour' or 'sinc' or 'spline'
            flirt.run()
        else:
            print(">>>> FLIRT has already been performed")

        anatomical_head = subject.anatomical_nii()

        output_fielf_coeff = os.path.join(
            reg_dir, 'highres2standard_warp.nii.gz')
        output_jacobian = os.path.join(reg_dir, 'highres2highres_jac')

        standard_head = fsl.Info.standard_image('MNI152_T1_2mm.nii.gz')
        standard_mask = fsl.Info.standard_image(
            'MNI152_T1_2mm_brain_mask_dil.nii.gz')

        if not os.path.isfile(output_fielf_coeff):
            print ">>>> FNIRT"
            # non-linear registration.
            fnirt = fsl.FNIRT(warped_file=out_file, # warped image
                              in_file=anatomical_head,
                              affine_file=out_mat_file, # Affine matrix to use
                              fieldcoeff_file=output_fielf_coeff, # name of output file with field coefficients or true
                              jacobian_file=output_jacobian, #  name of file for writing out the Jacobianof the field (for diagnostic or VBM purposes)
                              config_file='T1_2_MNI152_2mm', # 'T1_2_MNI152_2mm' or 'FA_2_FMRIB58_1mm'
                              ref_file=standard_head, # name of reference image
                              refmask_file=standard_mask) # name of file with mask in reference space
            fnirt.run()
            cmd = 'fslview {} {} -t 0.5 '.format(standard_image, out_file)
            pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                   shell=True, preexec_fn=os.setsid)
        else:
            print(">>>> FNIRT has already been performed")
Exemplo n.º 26
0
                      'reference')
register_flow.connect(func2highres, 'out_matrix_file', func2highres_bbr,
                      'in_matrix_file')

# Calculate affine transform from anatomical to target (default interpolation is trilinear)
highres2standard = Node(fsl.FLIRT(), name='highres2standard_affine')
highres2standard.inputs.dof = 12
highres2standard.inputs.searchr_x = [-90, 90]
highres2standard.inputs.searchr_y = [-90, 90]
highres2standard.inputs.searchr_z = [-90, 90]
register_flow.connect(stripper, 'out_file', highres2standard, 'in_file')
register_flow.connect(reg_inputnode, 'target_image_brain', highres2standard,
                      'reference')

# Calculate nonlinear transform from anatomical to target (default warp resolution is 10,10,10)
highres2standard_warp = Node(fsl.FNIRT(), name='highres2standard_nonlinear')
highres2standard_warp.inputs.fieldcoeff_file = True
register_flow.connect(highres2standard, 'out_matrix_file',
                      highres2standard_warp, 'affine_file')
register_flow.connect(reg_inputnode, 'anatomical_image', highres2standard_warp,
                      'in_file')
register_flow.connect(reg_inputnode, 'config_file', highres2standard_warp,
                      'config_file')
register_flow.connect(reg_inputnode, 'target_image', highres2standard_warp,
                      'ref_file')
register_flow.connect(reg_inputnode, 'target_mask', highres2standard_warp,
                      'refmask_file')

# Combine linear FLIRT transformations into one to create a transformation matrix from functional to target
func2standard = Node(fsl.ConvertXFM(concat_xfm=True),
                     name='func2standard_linear')
Exemplo n.º 27
0
def FNIRT(in_file: str, ref: str, out_file: str, aff: str = None):
    fnt = fsl.FNIRT()
    fnt.inputs.in_file = in_file
    fnt.inputs.ref_file = ref
Exemplo n.º 28
0
#extract_b0.inputs.t_min = 0
get_T1_template.inputs.t_size = 1
get_T1_template.inputs.in_file = T1_Template


T1linTemplate = pe.Node(interface=fsl.FLIRT(), name='T1linTemplate')
#T1linTemplate.inputs.reference=Template
T1linTemplate.inputs.dof = 12
T1linTemplate.inputs.searchr_x = [-180, 180]
T1linTemplate.inputs.searchr_y = [-180, 180]
T1linTemplate.inputs.searchr_z = [-180, 180]

inverse_T1_matrix = pe.Node(interface=fsl.ConvertXFM(), name='inverse_T1_matrix')
inverse_T1_matrix.inputs.invert_xfm = True

T1warpTemplate=pe.Node(interface=fsl.FNIRT(), name='T1warpTemplate')
T1warpTemplate.inputs.field_file=True
T1warpTemplate.inputs.config_file=configfile

inverse_T1_warp=pe.Node(interface=tools.InvWarp(), name='inverse_T1_warp')


apply_T1_warp=pe.MapNode(interface=fsl.ApplyWarp(), name='apply_T1_warp',
                         iterfield=['in_file'])
apply_T1_warp.inputs.interp='nn'


get_masks = pe.MapNode(interface=fsl.ExtractROI(), name = 'get_masks',
                              iterfield=['in_file'])
get_masks.inputs.t_size = 1
get_masks.inputs.in_file = TissueList
Exemplo n.º 29
0
def reg2std(name='standardization'):
	

	"""
		Linear and non-linear standardization for structural rat MRI images
		Input: upscaled data
	
	"""
	
	reg = pe.Workflow(name=name)

	"""
    	Set up a node to define all inputs required for the preprocessing workflow

   	"""

	inputnode = pe.Node(interface=util.IdentityInterface(fields=['in_file_head', 'in_file_brain'], mandatory_inputs=True),
                            name='inputspec')

	"""
    	Set up a node to define outputs for the preprocessing workflow

    	"""


        outputnode = pe.Node(interface=util.IdentityInterface(fields=['out_nonlin_head', 'out_nonlin_brain', 'out_warpfield', 'out_lin_brain'], mandatory_inputs=True),
                         name='outputspec')



	"""
		Node for linear (12-param) reg
		flirt -in $in -ref $std -dof 12 -omat $omat -bins 256 -cost $type -searchrx -90 90 -searchry -90 90 -searchrz -90 90 -interp trilinear
	"""
	flirt=pe.MapNode(interface=fsl.FLIRT(reference='/opt/shared/etc/std/new/standard-wistar_2mm_brain.nii.gz',
										 dof=12,
										 bins=256,
										 cost='corratio',
										 interp='trilinear'),
					 name='linear_standardization',
					 iterfield=['in_file']) #out_matrix_file?, searchr?

	"""
		Non-linear reg
		fnirt --in=$in --ref=$std --aff=$init --iout=$out --miter=2,3 --infwhm=4,1 --reffwhm=2,0 --subsamp=8,1 --estint=1,1 --applyrefmask=1,1 --applyinmask=0,0 --lambda=200,500 --warpres=10,10,10 --intmod=global_non_linear --refmask=$refmask --fout=$warpingfield --interp=spline
	"""
	#TODO: parametrize standard template
	fnirt=pe.MapNode(interface=fsl.FNIRT( \
			ref_file='/opt/shared/etc/std/new/standard-wistar_2mm_brain.nii.gz', \
			refmask_file='/opt/shared/etc/std/new/standard-wistar_2mm_brain_mask.nii.gz', \
			max_nonlin_iter=[2,3], \
			in_fwhm=[2,0], \
			ref_fwhm=[2,0], \
			subsampling_scheme=[8,1],\
			apply_intensity_mapping=[1,1],\
			apply_refmask=[1,1],\
			apply_inmask=[0,0],\
			regularization_lambda=[200,500],\
			warp_resolution=(10,10,10),\
			intensity_mapping_model='global_non_linear_with_bias',\
			field_file=True),
		name='nonlinear_standardization',
	iterfield=['in_file', 'affine_file' ])
	
	"""
		Non-linear reg
		fnirt --in=$in --ref=$std --aff=$init --iout=$out --miter=2,3 --infwhm=4,1 --reffwhm=2,0 --subsamp=8,1 --estint=1,1 --applyrefmask=1,1 --applyinmask=0,0 --lambda=200,500 --warpres=10,10,10 --intmod=global_non_linear --refmask=$refmask --fout=$warpingfield --interp=spline
	"""

	applyWarp=pe.MapNode(interface=fsl.ApplyWarp(), name="warp_brain",
						 iterfield=['in_file', 'ref_file', 'field_file'])
	

	# TODO applywarp: brain

	reg.connect(inputnode, "in_file_brain", flirt, "in_file")
	reg.connect(flirt, "out_file", outputnode, "out_lin_brain")

	reg.connect(inputnode, "in_file_head", fnirt, "in_file")
	reg.connect(flirt, "out_matrix_file", fnirt, "affine_file")

	reg.connect(inputnode, "in_file_brain", applyWarp, "in_file")
	reg.connect(fnirt, "warped_file", applyWarp, "ref_file")
	reg.connect(fnirt, "field_file", applyWarp, "field_file")

	reg.connect(fnirt, "warped_file", outputnode, "out_nonlin_head")
	reg.connect(applyWarp, "out_file", outputnode, "out_nonlin_brain")
	reg.connect(fnirt, "field_file", outputnode, "out_warpfield")

	return reg
Exemplo n.º 30
0
def create_iterative_register_pipe(template_file,
                                   template_brain_file,
                                   template_mask_file,
                                   gm_prob_file,
                                   wm_prob_file,
                                   csf_prob_file,
                                   n_iter,
                                   name="register_pipe"):
    """
    Registration of template (NMT or other) according to Regis:
    - The iterative FLIRT is between NMT_SS and subject's anat after a quick
    skull-stripping but the anat is more and more refined to corresponds to the
    brain
    - there is also a FNIRT done once, for comparison of the quality of the
    template on the subject's brain

    Not used anymore: corresponds to the IterREGBET provided by Regis in bash
    and wrapped node IterREGBET in nodes/register.py

    #TODO: test if gives the same results as IterREGBET
    """
    register_pipe = pe.Workflow(name=name)

    # creating inputnode
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['anat_file_BET', 'anat_file']),
        name='inputnode')

    # register node
    register = pe.Node(niu.Function(
        input_names=[
            "anat_file", "anat_file_BET", "template_brain_file",
            "template_mask_file", 'n_iter'
        ],
        output_names=["anat_file_brain", "template_to_anat_file"],
        function=interative_flirt),
                       name="register")

    register.inputs.template_brain_file = template_brain_file
    register.inputs.template_mask_file = template_mask_file
    register.inputs.n_iter = n_iter

    register_pipe.connect(inputnode, 'anat_file', register, 'anat_file')
    register_pipe.connect(inputnode, 'anat_file_BET', register,
                          "anat_file_BET")

    # apply transfo over the 3 tissues:
    # gm
    register_gm = pe.Node(fsl.ApplyXFM(), name="register_gm")

    register_gm.inputs.in_file = gm_prob_file
    register_gm.inputs.apply_xfm = True
    register_gm.inputs.interp = "nearestneighbour"
    register_gm.inputs.output_type = "NIFTI"  # for SPM segment

    register_pipe.connect(register, 'anat_file_brain', register_gm,
                          'reference')
    register_pipe.connect(register, 'template_to_anat_file', register_gm,
                          "in_matrix_file")

    # wm
    register_wm = pe.Node(fsl.ApplyXFM(), name="register_wm")

    register_wm.inputs.in_file = wm_prob_file
    register_wm.inputs.apply_xfm = True
    register_wm.inputs.interp = "nearestneighbour"
    register_wm.inputs.output_type = "NIFTI"  # for SPM segment

    register_pipe.connect(register, 'anat_file_brain', register_wm,
                          'reference')
    register_pipe.connect(register, 'template_to_anat_file', register_wm,
                          "in_matrix_file")

    # csf
    register_csf = pe.Node(fsl.ApplyXFM(), name="register_csf")

    register_csf.inputs.in_file = csf_prob_file
    register_csf.inputs.apply_xfm = True
    register_csf.inputs.interp = "nearestneighbour"
    register_csf.inputs.output_type = "NIFTI"  # for SPM segment

    register_pipe.connect(register, 'anat_file_brain', register_csf,
                          'reference')
    register_pipe.connect(register, 'template_to_anat_file', register_csf,
                          "in_matrix_file")

    def return_list(file1, file2, file3):
        return [file1, file2, file3]

    # merge 3 outputs to a list (...)
    merge_3_files = pe.Node(niu.Function(
        input_names=["file1", "file2", "file3"],
        output_names=["list3files"],
        function=return_list),
                            name="merge_3_files")

    register_pipe.connect(register_gm, 'out_file', merge_3_files, "file1")
    register_pipe.connect(register_wm, 'out_file', merge_3_files, "file2")
    register_pipe.connect(register_csf, 'out_file', merge_3_files, "file3")

    # same with non linear
    # non linear register between anat and head
    # (FNIRT work directly on head?
    # I thought FLIRT was only skull-stripped brain, is it different? )

    nl_register = pe.Node(fsl.FNIRT(), name="nl_register")
    nl_register.inputs.in_file = template_file

    register_pipe.connect(inputnode, 'anat_file', nl_register, 'ref_file')
    register_pipe.connect(register, 'template_to_anat_file', nl_register,
                          'affine_file')

    # apply non linear warp to NMT_SS
    nl_apply = pe.Node(fsl.ApplyWarp(), name="nl_apply")
    nl_apply.inputs.in_file = template_brain_file
    register_pipe.connect(inputnode, 'anat_file', nl_apply, 'ref_file')
    register_pipe.connect(nl_register, 'fieldcoeff_file', nl_apply,
                          'field_file')  # iout from fnirt

    return register_pipe