def test_SimpleBeforeAfterRPT(reference, moving): """ the SimpleBeforeAfterRPT report capable test """ flirt_rpt = FLIRTRPT(generate_report=False, in_file=moving, reference=reference) ba_rpt = SimpleBeforeAfterRPT( generate_report=True, before=reference, after=flirt_rpt.run().outputs.out_file ) _smoke_test_report(ba_rpt, 'test_SimpleBeforeAfterRPT.svg')
def test_ApplyXFMRPT(reference, moving): """ the ApplyXFM report capable test """ flirt_rpt = FLIRTRPT(generate_report=False, in_file=moving, reference=reference) applyxfm_rpt = ApplyXFMRPT( generate_report=True, in_file=moving, in_matrix_file=flirt_rpt.run().outputs.out_matrix_file, reference=reference, apply_xfm=True ) _smoke_test_report(applyxfm_rpt, 'testApplyXFM.svg')
def test_FLIRTRPT_w_BBR(reference, reference_mask, moving): """ test FLIRTRPT with input `wm_seg` set. For the sake of testing ONLY, `wm_seg` is set to the filename of a brain mask """ flirt_rpt = FLIRTRPT(generate_report=True, in_file=moving, reference=reference, wm_seg=reference_mask) _smoke_test_report(flirt_rpt, 'testFLIRTRPTBBR.svg')
def test_FLIRTRPT(self): """ the FLIRT report capable test """ flirt_rpt = FLIRTRPT(generate_report=True, in_file=self.moving, reference=self.reference) _smoke_test_report(flirt_rpt, 'testFLIRT.svg')
def init_fsl_bbr_wf(use_bbr, bold2t1w_dof, bold2t1w_init, sloppy=False, name='fsl_bbr_wf'): """ Build a workflow to run FSL's ``flirt``. This workflow uses FSL FLIRT to register a BOLD image to a T1-weighted structural image, using a boundary-based registration (BBR) cost function. It is a counterpart to :py:func:`~fmriprep.workflows.bold.registration.init_bbreg_wf`, which performs the same task using FreeSurfer's ``bbregister``. The ``use_bbr`` option permits a high degree of control over registration. If ``False``, standard, rigid coregistration will be performed by FLIRT. If ``True``, FLIRT-BBR will be seeded with the initial transform found by the rigid coregistration. If ``None``, after FLIRT-BBR is run, the resulting affine transform will be compared to the initial transform found by FLIRT. Excessive deviation will result in rejecting the BBR refinement and accepting the original, affine registration. Workflow Graph .. workflow :: :graph2use: orig :simple_form: yes from fmriprep.workflows.bold.registration import init_fsl_bbr_wf wf = init_fsl_bbr_wf(use_bbr=True, bold2t1w_dof=9, bold2t1w_init='register') Parameters ---------- use_bbr : :obj:`bool` or None Enable/disable boundary-based registration refinement. If ``None``, test BBR result for distortion before accepting. bold2t1w_dof : 6, 9 or 12 Degrees-of-freedom for BOLD-T1w registration bold2t1w_init : str, 'header' or 'register' If ``'header'``, use header information for initialization of BOLD and T1 images. If ``'register'``, align volumes by their centers. name : :obj:`str`, optional Workflow name (default: fsl_bbr_wf) Inputs ------ in_file Reference BOLD image to be registered t1w_brain Skull-stripped T1-weighted structural image t1w_dseg FAST segmentation of ``t1w_brain`` fsnative2t1w_xfm Unused (see :py:func:`~fmriprep.workflows.bold.registration.init_bbreg_wf`) subjects_dir Unused (see :py:func:`~fmriprep.workflows.bold.registration.init_bbreg_wf`) subject_id Unused (see :py:func:`~fmriprep.workflows.bold.registration.init_bbreg_wf`) Outputs ------- itk_bold_to_t1 Affine transform from ``ref_bold_brain`` to T1w space (ITK format) itk_t1_to_bold Affine transform from T1 space to BOLD space (ITK format) out_report Reportlet for assessing registration quality fallback Boolean indicating whether BBR was rejected (rigid FLIRT registration returned) """ from niworkflows.engine.workflows import LiterateWorkflow as Workflow from niworkflows.utils.images import dseg_label as _dseg_label from niworkflows.interfaces.freesurfer import PatchedLTAConvert as LTAConvert from niworkflows.interfaces.registration import FLIRTRPT workflow = Workflow(name=name) workflow.__desc__ = """\ The BOLD reference was then co-registered to the T1w reference using `flirt` [FSL {fsl_ver}, @flirt] with the boundary-based registration [@bbr] cost-function. Co-registration was configured with nine degrees of freedom to account for distortions remaining in the BOLD reference. """.format(fsl_ver=FLIRTRPT().version or '<ver>') inputnode = pe.Node( niu.IdentityInterface([ 'in_file', 'fsnative2t1w_xfm', 'subjects_dir', 'subject_id', # BBRegister 't1w_dseg', 't1w_brain' ]), # FLIRT BBR name='inputnode') outputnode = pe.Node(niu.IdentityInterface( ['itk_bold_to_t1', 'itk_t1_to_bold', 'out_report', 'fallback']), name='outputnode') wm_mask = pe.Node(niu.Function(function=_dseg_label), name='wm_mask') wm_mask.inputs.label = 2 # BIDS default is WM=2 flt_bbr_init = pe.Node(FLIRTRPT(dof=6, generate_report=not use_bbr, uses_qform=True), name='flt_bbr_init') if bold2t1w_init not in ("register", "header"): raise ValueError( f"Unknown BOLD-T1w initialization option: {bold2t1w_init}") if bold2t1w_init == "header": raise NotImplementedError( "Header-based registration initialization not supported for FSL") invt_bbr = pe.Node(fsl.ConvertXFM(invert_xfm=True), name='invt_bbr', mem_gb=DEFAULT_MEMORY_MIN_GB) # BOLD to T1 transform matrix is from fsl, using c3 tools to convert to # something ANTs will like. fsl2itk_fwd = pe.Node(c3.C3dAffineTool(fsl2ras=True, itk_transform=True), name='fsl2itk_fwd', mem_gb=DEFAULT_MEMORY_MIN_GB) fsl2itk_inv = pe.Node(c3.C3dAffineTool(fsl2ras=True, itk_transform=True), name='fsl2itk_inv', mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, flt_bbr_init, [('in_file', 'in_file'), ('t1w_brain', 'reference')]), (inputnode, fsl2itk_fwd, [('t1w_brain', 'reference_file'), ('in_file', 'source_file')]), (inputnode, fsl2itk_inv, [('in_file', 'reference_file'), ('t1w_brain', 'source_file')]), (invt_bbr, fsl2itk_inv, [('out_file', 'transform_file')]), (fsl2itk_fwd, outputnode, [('itk_transform', 'itk_bold_to_t1')]), (fsl2itk_inv, outputnode, [('itk_transform', 'itk_t1_to_bold')]), ]) # Short-circuit workflow building, use rigid registration if use_bbr is False: workflow.connect([ (flt_bbr_init, invt_bbr, [('out_matrix_file', 'in_file')]), (flt_bbr_init, fsl2itk_fwd, [('out_matrix_file', 'transform_file') ]), (flt_bbr_init, outputnode, [('out_report', 'out_report')]), ]) outputnode.inputs.fallback = True return workflow flt_bbr = pe.Node(FLIRTRPT(cost_func='bbr', dof=bold2t1w_dof, generate_report=True), name='flt_bbr') FSLDIR = os.getenv('FSLDIR') if FSLDIR: flt_bbr.inputs.schedule = op.join(FSLDIR, 'etc/flirtsch/bbr.sch') else: # Should mostly be hit while building docs LOGGER.warning("FSLDIR unset - using packaged BBR schedule") flt_bbr.inputs.schedule = pkgr.resource_filename( 'fmriprep', 'data/flirtsch/bbr.sch') workflow.connect([ (inputnode, wm_mask, [('t1w_dseg', 'in_seg')]), (inputnode, flt_bbr, [('in_file', 'in_file')]), (flt_bbr_init, flt_bbr, [('out_matrix_file', 'in_matrix_file')]), ]) if sloppy is True: downsample = pe.Node(niu.Function( function=_conditional_downsampling, output_names=["out_file", "out_mask"]), name='downsample') workflow.connect([ (inputnode, downsample, [("t1w_brain", "in_file")]), (wm_mask, downsample, [("out", "in_mask")]), (downsample, flt_bbr, [('out_file', 'reference'), ('out_mask', 'wm_seg')]), ]) else: workflow.connect([ (inputnode, flt_bbr, [('t1w_brain', 'reference')]), (wm_mask, flt_bbr, [('out', 'wm_seg')]), ]) # Short-circuit workflow building, use boundary-based registration if use_bbr is True: workflow.connect([ (flt_bbr, invt_bbr, [('out_matrix_file', 'in_file')]), (flt_bbr, fsl2itk_fwd, [('out_matrix_file', 'transform_file')]), (flt_bbr, outputnode, [('out_report', 'out_report')]), ]) outputnode.inputs.fallback = False return workflow transforms = pe.Node(niu.Merge(2), run_without_submitting=True, name='transforms') reports = pe.Node(niu.Merge(2), run_without_submitting=True, name='reports') compare_transforms = pe.Node(niu.Function(function=compare_xforms), name='compare_transforms') select_transform = pe.Node(niu.Select(), run_without_submitting=True, name='select_transform') select_report = pe.Node(niu.Select(), run_without_submitting=True, name='select_report') fsl_to_lta = pe.MapNode(LTAConvert(out_lta=True), iterfield=['in_fsl'], name='fsl_to_lta') workflow.connect([ (flt_bbr, transforms, [('out_matrix_file', 'in1')]), (flt_bbr_init, transforms, [('out_matrix_file', 'in2')]), # Convert FSL transforms to LTA (RAS2RAS) transforms and compare (inputnode, fsl_to_lta, [('in_file', 'source_file'), ('t1w_brain', 'target_file')]), (transforms, fsl_to_lta, [('out', 'in_fsl')]), (fsl_to_lta, compare_transforms, [('out_lta', 'lta_list')]), (compare_transforms, outputnode, [('out', 'fallback')]), # Select output transform (transforms, select_transform, [('out', 'inlist')]), (compare_transforms, select_transform, [('out', 'index')]), (select_transform, invt_bbr, [('out', 'in_file')]), (select_transform, fsl2itk_fwd, [('out', 'transform_file')]), (flt_bbr, reports, [('out_report', 'in1')]), (flt_bbr_init, reports, [('out_report', 'in2')]), (reports, select_report, [('out', 'inlist')]), (compare_transforms, select_report, [('out', 'index')]), (select_report, outputnode, [('out', 'out_report')]), ]) return workflow
def init_fsl_bbr_wf(use_bbr, bold2t1w_dof, name='fsl_bbr_wf'): """ This workflow uses FSL FLIRT to register a BOLD image to a T1-weighted structural image, using a boundary-based registration (BBR) cost function. It is a counterpart to :py:func:`~fmriprep.workflows.bold.registration.init_bbreg_wf`, which performs the same task using FreeSurfer's ``bbregister``. The ``use_bbr`` option permits a high degree of control over registration. If ``False``, standard, rigid coregistration will be performed by FLIRT. If ``True``, FLIRT-BBR will be seeded with the initial transform found by the rigid coregistration. If ``None``, after FLIRT-BBR is run, the resulting affine transform will be compared to the initial transform found by FLIRT. Excessive deviation will result in rejecting the BBR refinement and accepting the original, affine registration. .. workflow :: :graph2use: orig :simple_form: yes from fmriprep.workflows.bold.registration import init_fsl_bbr_wf wf = init_fsl_bbr_wf(use_bbr=True, bold2t1w_dof=9) Parameters use_bbr : bool or None Enable/disable boundary-based registration refinement. If ``None``, test BBR result for distortion before accepting. bold2t1w_dof : 6, 9 or 12 Degrees-of-freedom for BOLD-T1w registration name : str, optional Workflow name (default: fsl_bbr_wf) Inputs in_file Reference BOLD image to be registered t1_brain Skull-stripped T1-weighted structural image t1_seg FAST segmentation of ``t1_brain`` t1_2_fsnative_reverse_transform Unused (see :py:func:`~fmriprep.workflows.util.init_bbreg_wf`) subjects_dir Unused (see :py:func:`~fmriprep.workflows.util.init_bbreg_wf`) subject_id Unused (see :py:func:`~fmriprep.workflows.util.init_bbreg_wf`) Outputs itk_bold_to_t1 Affine transform from ``ref_bold_brain`` to T1 space (ITK format) itk_t1_to_bold Affine transform from T1 space to BOLD space (ITK format) out_report Reportlet for assessing registration quality fallback Boolean indicating whether BBR was rejected (rigid FLIRT registration returned) """ workflow = Workflow(name=name) workflow.__desc__ = """\ The BOLD reference was then co-registered to the T1w reference using `flirt` [FSL {fsl_ver}, @flirt] with the boundary-based registration [@bbr] cost-function. Co-registration was configured with nine degrees of freedom to account for distortions remaining in the BOLD reference. """.format(fsl_ver=FLIRTRPT().version or '<ver>') inputnode = pe.Node( niu.IdentityInterface([ 'in_file', 't1_2_fsnative_reverse_transform', 'subjects_dir', 'subject_id', # BBRegister 't1_seg', 't1_brain' ]), # FLIRT BBR name='inputnode') outputnode = pe.Node(niu.IdentityInterface( ['itk_bold_to_t1', 'itk_t1_to_bold', 'out_report', 'fallback']), name='outputnode') wm_mask = pe.Node(niu.Function(function=extract_wm), name='wm_mask') flt_bbr_init = pe.Node(FLIRTRPT(dof=6, generate_report=not use_bbr, uses_qform=True), name='flt_bbr_init') invt_bbr = pe.Node(fsl.ConvertXFM(invert_xfm=True), name='invt_bbr', mem_gb=DEFAULT_MEMORY_MIN_GB) # BOLD to T1 transform matrix is from fsl, using c3 tools to convert to # something ANTs will like. fsl2itk_fwd = pe.Node(c3.C3dAffineTool(fsl2ras=True, itk_transform=True), name='fsl2itk_fwd', mem_gb=DEFAULT_MEMORY_MIN_GB) fsl2itk_inv = pe.Node(c3.C3dAffineTool(fsl2ras=True, itk_transform=True), name='fsl2itk_inv', mem_gb=DEFAULT_MEMORY_MIN_GB) workflow.connect([ (inputnode, flt_bbr_init, [('in_file', 'in_file'), ('t1_brain', 'reference')]), (inputnode, fsl2itk_fwd, [('t1_brain', 'reference_file'), ('in_file', 'source_file')]), (inputnode, fsl2itk_inv, [('in_file', 'reference_file'), ('t1_brain', 'source_file')]), (invt_bbr, fsl2itk_inv, [('out_file', 'transform_file')]), (fsl2itk_fwd, outputnode, [('itk_transform', 'itk_bold_to_t1')]), (fsl2itk_inv, outputnode, [('itk_transform', 'itk_t1_to_bold')]), ]) # Short-circuit workflow building, use rigid registration if use_bbr is False: workflow.connect([ (flt_bbr_init, invt_bbr, [('out_matrix_file', 'in_file')]), (flt_bbr_init, fsl2itk_fwd, [('out_matrix_file', 'transform_file') ]), (flt_bbr_init, outputnode, [('out_report', 'out_report')]), ]) outputnode.inputs.fallback = True return workflow flt_bbr = pe.Node(FLIRTRPT(cost_func='bbr', dof=bold2t1w_dof, generate_report=True, schedule=op.join(os.getenv('FSLDIR'), 'etc/flirtsch/bbr.sch')), name='flt_bbr') workflow.connect([ (inputnode, wm_mask, [('t1_seg', 'in_seg')]), (inputnode, flt_bbr, [('in_file', 'in_file'), ('t1_brain', 'reference')]), (flt_bbr_init, flt_bbr, [('out_matrix_file', 'in_matrix_file')]), (wm_mask, flt_bbr, [('out', 'wm_seg')]), ]) # Short-circuit workflow building, use boundary-based registration if use_bbr is True: workflow.connect([ (flt_bbr, invt_bbr, [('out_matrix_file', 'in_file')]), (flt_bbr, fsl2itk_fwd, [('out_matrix_file', 'transform_file')]), (flt_bbr, outputnode, [('out_report', 'out_report')]), ]) outputnode.inputs.fallback = False return workflow transforms = pe.Node(niu.Merge(2), run_without_submitting=True, name='transforms') reports = pe.Node(niu.Merge(2), run_without_submitting=True, name='reports') compare_transforms = pe.Node(niu.Function(function=compare_xforms), name='compare_transforms') select_transform = pe.Node(niu.Select(), run_without_submitting=True, name='select_transform') select_report = pe.Node(niu.Select(), run_without_submitting=True, name='select_report') fsl_to_lta = pe.MapNode(fs.utils.LTAConvert(out_lta=True), iterfield=['in_fsl'], name='fsl_to_lta') workflow.connect([ (flt_bbr, transforms, [('out_matrix_file', 'in1')]), (flt_bbr_init, transforms, [('out_matrix_file', 'in2')]), # Convert FSL transforms to LTA (RAS2RAS) transforms and compare (inputnode, fsl_to_lta, [('in_file', 'source_file'), ('t1_brain', 'target_file')]), (transforms, fsl_to_lta, [('out', 'in_fsl')]), (fsl_to_lta, compare_transforms, [('out_lta', 'lta_list')]), (compare_transforms, outputnode, [('out', 'fallback')]), # Select output transform (transforms, select_transform, [('out', 'inlist')]), (compare_transforms, select_transform, [('out', 'index')]), (select_transform, invt_bbr, [('out', 'in_file')]), (select_transform, fsl2itk_fwd, [('out', 'transform_file')]), (flt_bbr, reports, [('out_report', 'in1')]), (flt_bbr_init, reports, [('out_report', 'in2')]), (reports, select_report, [('out', 'inlist')]), (compare_transforms, select_report, [('out', 'index')]), (select_report, outputnode, [('out', 'out_report')]), ]) return workflow
def test_FLIRTRPT(reference, moving): """ the FLIRT report capable test """ flirt_rpt = FLIRTRPT(generate_report=True, in_file=moving, reference=reference) _smoke_test_report(flirt_rpt, "testFLIRT.svg")
def init_epi_reg_wf(freesurfer, bold2t1w_dof, bold_file_size_gb, output_spaces, output_dir, name='epi_reg_wf', use_fieldwarp=False): """ Uses FSL FLIRT with the BBR cost function to find the transform that maps the EPI space into the T1-space """ workflow = pe.Workflow(name=name) inputnode = pe.Node( niu.IdentityInterface(fields=['name_source', 'ref_epi_brain', 'ref_epi_mask', 't1_preproc', 't1_brain', 't1_mask', 't1_seg', 'epi_split', 'hmc_xforms', 'subjects_dir', 'subject_id', 'fs_2_t1_transform', 'fieldwarp']), name='inputnode' ) outputnode = pe.Node( niu.IdentityInterface(fields=['mat_epi_to_t1', 'mat_t1_to_epi', 'itk_epi_to_t1', 'itk_t1_to_epi', 'epi_t1', 'epi_mask_t1', 'fs_reg_file', 'out_report']), name='outputnode' ) if freesurfer: bbregister = pe.Node( BBRegisterRPT( dof=bold2t1w_dof, contrast_type='t2', init='coreg', registered_file=True, out_fsl_file=True, generate_report=True), name='bbregister' ) def apply_fs_transform(fs_2_t1_transform, bbreg_transform): import os import numpy as np out_file = os.path.abspath('transform.mat') fs_xfm = np.loadtxt(fs_2_t1_transform) bbrxfm = np.loadtxt(bbreg_transform) out_xfm = fs_xfm.dot(bbrxfm) assert np.allclose(out_xfm[3], [0, 0, 0, 1]) out_xfm[3] = [0, 0, 0, 1] np.savetxt(out_file, out_xfm, fmt='%.12g') return out_file transformer = pe.Node(niu.Function(function=apply_fs_transform), name='transformer', run_without_submitting=True) else: wm_mask = pe.Node(niu.Function(function=_extract_wm), name='wm_mask') flt_bbr_init = pe.Node(FLIRTRPT(generate_report=True, dof=6), name='flt_bbr_init') flt_bbr = pe.Node( FLIRTRPT(generate_report=True, cost_func='bbr', dof=bold2t1w_dof), name='flt_bbr') flt_bbr.inputs.schedule = op.join(os.getenv('FSLDIR'), 'etc/flirtsch/bbr.sch') # make equivalent warp fields invt_bbr = pe.Node(fsl.ConvertXFM(invert_xfm=True), name='invt_bbr') # EPI to T1 transform matrix is from fsl, using c3 tools to convert to # something ANTs will like. fsl2itk_fwd = pe.Node(c3.C3dAffineTool(fsl2ras=True, itk_transform=True), name='fsl2itk_fwd') fsl2itk_inv = pe.Node(c3.C3dAffineTool(fsl2ras=True, itk_transform=True), name='fsl2itk_inv') workflow.connect([ (inputnode, fsl2itk_fwd, [('t1_preproc', 'reference_file'), ('ref_epi_brain', 'source_file')]), (inputnode, fsl2itk_inv, [('ref_epi_brain', 'reference_file'), ('t1_preproc', 'source_file')]), (invt_bbr, outputnode, [('out_file', 'mat_t1_to_epi')]), (invt_bbr, fsl2itk_inv, [('out_file', 'transform_file')]), (fsl2itk_fwd, outputnode, [('itk_transform', 'itk_epi_to_t1')]), (fsl2itk_inv, outputnode, [('itk_transform', 'itk_t1_to_epi')]), ]) gen_ref = pe.Node(GenerateSamplingReference(), name='gen_ref') mask_t1w_tfm = pe.Node( ants.ApplyTransforms(interpolation='NearestNeighbor', float=True), name='mask_t1w_tfm' ) workflow.connect([ (inputnode, gen_ref, [('ref_epi_brain', 'moving_image'), ('t1_brain', 'fixed_image')]), (gen_ref, mask_t1w_tfm, [('out_file', 'reference_image')]), (fsl2itk_fwd, mask_t1w_tfm, [('itk_transform', 'transforms')]), (inputnode, mask_t1w_tfm, [('ref_epi_mask', 'input_image')]), (mask_t1w_tfm, outputnode, [('output_image', 'epi_mask_t1')]) ]) if use_fieldwarp: merge_transforms = pe.MapNode(niu.Merge(3), iterfield=['in3'], name='merge_transforms', run_without_submitting=True) workflow.connect([ (inputnode, merge_transforms, [('fieldwarp', 'in2'), ('hmc_xforms', 'in3')]) ]) else: merge_transforms = pe.MapNode(niu.Merge(2), iterfield=['in2'], name='merge_transforms', run_without_submitting=True) workflow.connect([ (inputnode, merge_transforms, [('hmc_xforms', 'in2')]) ]) merge = pe.Node(Merge(), name='merge') merge.interface.estimated_memory_gb = bold_file_size_gb * 3 epi_to_t1w_transform = pe.MapNode( ants.ApplyTransforms(interpolation="LanczosWindowedSinc", float=True), iterfield=['input_image', 'transforms'], name='epi_to_t1w_transform') epi_to_t1w_transform.terminal_output = 'file' workflow.connect([ (fsl2itk_fwd, merge_transforms, [('itk_transform', 'in1')]), (merge_transforms, epi_to_t1w_transform, [('out', 'transforms')]), (epi_to_t1w_transform, merge, [('output_image', 'in_files')]), (inputnode, merge, [('name_source', 'header_source')]), (merge, outputnode, [('out_file', 'epi_t1')]), (inputnode, epi_to_t1w_transform, [('epi_split', 'input_image')]), (gen_ref, epi_to_t1w_transform, [('out_file', 'reference_image')]), ]) if freesurfer: workflow.connect([ (inputnode, bbregister, [('subjects_dir', 'subjects_dir'), ('subject_id', 'subject_id')]), (inputnode, bbregister, [('ref_epi_brain', 'source_file')]), (inputnode, transformer, [('fs_2_t1_transform', 'fs_2_t1_transform')]), (bbregister, transformer, [('out_fsl_file', 'bbreg_transform')]), (transformer, invt_bbr, [('out', 'in_file')]), (transformer, fsl2itk_fwd, [('out', 'transform_file')]), (transformer, outputnode, [('out', 'mat_epi_to_t1')]), (bbregister, outputnode, [('out_reg_file', 'fs_reg_file'), ('out_report', 'out_report')]), ]) else: workflow.connect([ (inputnode, wm_mask, [('t1_seg', 'in_file')]), (inputnode, flt_bbr_init, [('ref_epi_brain', 'in_file')]), (inputnode, flt_bbr_init, [('t1_brain', 'reference')]), (flt_bbr_init, flt_bbr, [('out_matrix_file', 'in_matrix_file')]), (inputnode, flt_bbr, [('t1_brain', 'reference')]), (inputnode, flt_bbr, [('ref_epi_brain', 'in_file')]), (wm_mask, flt_bbr, [('out', 'wm_seg')]), (flt_bbr, invt_bbr, [('out_matrix_file', 'in_file')]), (flt_bbr, fsl2itk_fwd, [('out_matrix_file', 'transform_file')]), (flt_bbr, outputnode, [('out_matrix_file', 'mat_epi_to_t1'), ('out_report', 'out_report')]), ]) return workflow