def allineate(self,
                  in_file,
                  out_file=None,
                  suffix=None,
                  final="nearestneighbor",
                  mat=None,
                  base=None,
                  args=""):

        in_file, out_file = self.FuncHandler(in_file, out_file, suffix)

        myalline = afni.Allineate(in_file=in_file, out_file=out_file)
        #https://nipype.readthedocs.io/en/latest/interfaces/generated/interfaces.afni/preprocess.html#allineate

        myalline.inputs.args = args
        #myalline.inputs.num_threads = cpu_count()
        if mat is not None:
            mat, _ = self.FuncHandler(mat, out_file, suffix)
            myalline.inputs.in_matrix = mat
        if base is not None:
            myalline.inputs.reference = base
        myalline.run()

        #remove temp files
        if type(in_file) == models.BIDSImageFile:
            in_file = os.path.join(self._output_dir, in_file.filename)
        if "_desc-temp" in in_file:
            os.remove(in_file)
Ejemplo n.º 2
0
def alllineate_afni_template_space(in_file, ref_img_file, transfo_file):

    # align_NMT
    align_NMT = afni.Allineate()
    align_NMT.inputs.final_interpolation = "nearestneighbour"
    align_NMT.inputs.overwrite = True
    align_NMT.inputs.outputtype = "NIFTI_GZ"

    align_NMT.inputs.in_file = in_file
    align_NMT.inputs.reference = ref_img_file
    align_NMT.inputs.in_matrix = transfo_file

    output_file = align_NMT.run().outputs.out_file
    print(output_file)
    return output_file
Ejemplo n.º 3
0
def create_reg_seg_pipe(name="reg_seg_pipe"):

    reg_seg_pipe = pe.Workflow(name=name)

    # creating inputnode
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['native_segmented_file',
                                      'transfo_file', 'ref_image']),
        name='inputnode')

    # align_seg
    align_seg = pe.Node(
        afni.Allineate(), name="align_seg", iterfield=['in_file'])
    align_seg.inputs.final_interpolation = "nearestneighbour"
    align_seg.inputs.overwrite = True
    align_seg.inputs.outputtype = "NIFTI_GZ"

    reg_seg_pipe.connect(inputnode, 'native_segmented_file',
                         align_seg, "in_file")
    reg_seg_pipe.connect(inputnode, 'ref_image', align_seg, "reference")
    reg_seg_pipe.connect(inputnode, 'transfo_file', align_seg, "in_matrix")

    # align_gm
    split_seg_mask = pe.Node(
        niu.Function(input_names=['nii_file'],
                     output_names=['list_binary_masks'],
                     function=split_indexed_mask),
        name="split_seg_mask")

    reg_seg_pipe.connect(align_seg, 'out_file',
                         split_seg_mask, "nii_file")

    outputnode = pe.Node(
        niu.IdentityInterface(fields=['norm_seg', 'norm_gm',
                                      'norm_wm', 'norm_csf']),
        name='outputnode')

    reg_seg_pipe.connect(align_seg, 'out_file', outputnode, "norm_seg")
    reg_seg_pipe.connect(split_seg_mask, ('out_file', get_elem, 0),
                         outputnode, "norm_gm")
    reg_seg_pipe.connect(split_seg_mask, ('out_file', get_elem, 1),
                         outputnode, "norm_wm")
    reg_seg_pipe.connect(split_seg_mask, ('out_file', get_elem, 2),
                         outputnode, "norm_csf")

    return reg_seg_pipe
Ejemplo n.º 4
0
def test_allineate():
    input_map = dict(
        args=dict(argstr='%s', ),
        environ=dict(usedefault=True, ),
        ignore_exception=dict(usedefault=True, ),
        in_file=dict(
            argstr='-source %s',
            mandatory=True,
        ),
        in_matrix=dict(argstr='-1Dmatrix_apply %s', ),
        out_file=dict(argstr='-prefix %s'),
        outputtype=dict(),
    )
    instance = afni.Allineate()
    for key, metadata in input_map.items():
        for metakey, value in metadata.items():
            yield assert_equal, getattr(instance.inputs.traits()[key],
                                        metakey), value
Ejemplo n.º 5
0
def _realign(func_filename,
             write_dir,
             caching=False,
             terminal_output='allatonce',
             environ=None):
    if environ is None:
        environ = {'AFNI_DECONFLICT': 'OVERWRITE'}

    if caching:
        memory = Memory(write_dir)
        clip_level = memory.cache(afni.ClipLevel)
        threshold = memory.cache(fsl.Threshold)
        volreg = memory.cache(afni.Volreg)
        allineate = memory.cache(afni.Allineate)
        copy = memory.cache(afni.Copy)
        copy_geom = memory.cache(fsl.CopyGeom)
        tstat = memory.cache(afni.TStat)
        for step in [threshold, volreg, allineate, tstat, copy, copy_geom]:
            step.interface().set_default_terminal_output(terminal_output)
    else:
        clip_level = afni.ClipLevel().run
        threshold = fsl.Threshold(terminal_output=terminal_output).run
        volreg = afni.Volreg(terminal_output=terminal_output).run
        allineate = afni.Allineate(terminal_output=terminal_output).run
        copy = afni.Copy(terminal_output=terminal_output).run
        copy_geom = fsl.CopyGeom(terminal_output=terminal_output).run
        tstat = afni.TStat(terminal_output=terminal_output).run

    out_clip_level = clip_level(in_file=func_filename)

    out_threshold = threshold(in_file=func_filename,
                              thresh=out_clip_level.outputs.clip_val,
                              out_file=fname_presuffix(func_filename,
                                                       suffix='_thresholded',
                                                       newpath=write_dir))
    thresholded_filename = out_threshold.outputs.out_file

    out_volreg = volreg(  # XXX dfile not saved
        in_file=thresholded_filename,
        out_file=fname_presuffix(thresholded_filename,
                                 suffix='_volreg',
                                 newpath=write_dir),
        environ=environ,
        oned_file=fname_presuffix(thresholded_filename,
                                  suffix='_volreg.1Dfile.1D',
                                  use_ext=False,
                                  newpath=write_dir),
        oned_matrix_save=fname_presuffix(thresholded_filename,
                                         suffix='_volreg.aff12.1D',
                                         use_ext=False,
                                         newpath=write_dir))

    # Apply the registration to the whole head
    out_allineate = allineate(in_file=func_filename,
                              master=func_filename,
                              in_matrix=out_volreg.outputs.oned_matrix_save,
                              out_file=fname_presuffix(func_filename,
                                                       suffix='_volreg',
                                                       newpath=write_dir),
                              environ=environ)

    # 3dAllineate removes the obliquity. This is not a good way to readd it as
    # removes motion correction info in the header if it were an AFNI file...as
    # it happens it's NIfTI which does not store that so irrelevant!
    out_copy = copy(in_file=out_allineate.outputs.out_file,
                    out_file=fname_presuffix(out_allineate.outputs.out_file,
                                             suffix='_oblique',
                                             newpath=write_dir),
                    environ=environ)
    out_copy_geom = copy_geom(dest_file=out_copy.outputs.out_file,
                              in_file=out_volreg.outputs.out_file)

    oblique_allineated_filename = out_copy_geom.outputs.out_file

    # Create a (hopefully) nice mean image for use in the registration
    out_tstat = tstat(in_file=oblique_allineated_filename,
                      args='-mean',
                      out_file=fname_presuffix(oblique_allineated_filename,
                                               suffix='_tstat',
                                               newpath=write_dir),
                      environ=environ)

    # Remove intermediate outputs
    if not caching:
        for output_file in [
                thresholded_filename, out_volreg.outputs.oned_matrix_save,
                out_volreg.outputs.out_file, out_volreg.outputs.md1d_file,
                out_allineate.outputs.out_file
        ]:
            os.remove(output_file)
    return (oblique_allineated_filename, out_tstat.outputs.out_file,
            out_volreg.outputs.oned_file)
Ejemplo n.º 6
0
def create_pipeline_graph(pipeline_name, graph_file,
                          graph_kind='hierarchical'):
    """Creates pipeline graph for a given piepline.

    Parameters
    ----------
    pipeline_name : one of {'anat_to_common_rigid', 'anat_to_common_affine',
        'anat_to_common_nonlinear'}
        Pipeline name.

    graph_file : str.
        Path to save the graph image to.

    graph_kind : one of {'orig', 'hierarchical', 'flat', 'exec', 'colored'}, optional.
        The kind of the graph, passed to
        nipype.pipeline.workflows.Workflow().write_graph
    """
    pipeline_names = ['anats_to_common_rigid', 'anats_to_common_affine',
                      'anats_to_common_nonlinear']
    if pipeline_name not in pipeline_names:
        raise NotImplementedError(
            'Pipeline name must be one of {0}, you entered {1}'.format(
                pipeline_names, pipeline_name))
    graph_kinds = ['orig', 'hierarchical', 'flat', 'exec', 'colored']
    if graph_kind not in graph_kinds:
        raise ValueError(
            'Graph kind must be one of {0}, you entered {1}'.format(
                graph_kinds, graph_kind))

    workflow = pe.Workflow(name=pipeline_name)

    #######################################################################
    # Specify rigid body registration pipeline steps
    unifize = pe.Node(interface=afni.Unifize(), name='bias_correct')
    clip_level = pe.Node(interface=afni.ClipLevel(),
                         name='compute_mask_threshold')
    compute_mask = pe.Node(interface=interfaces.MathMorphoMask(),
                           name='compute_brain_mask')
    apply_mask = pe.Node(interface=afni.Calc(), name='apply_brain_mask')
    center_mass = pe.Node(interface=afni.CenterMass(),
                          name='compute_and_set_cm_in_header')
    refit_copy = pe.Node(afni.Refit(), name='copy_cm_in_header')
    tcat1 = pe.Node(afni.TCat(), name='concatenate_across_individuals1')
    tstat1 = pe.Node(afni.TStat(), name='compute_average1')
    undump = pe.Node(afni.Undump(), name='create_empty_template')
    refit_set = pe.Node(afni.Refit(), name='set_cm_in_header')
    resample1 = pe.Node(afni.Resample(), name='resample1')
    resample2 = pe.Node(afni.Resample(), name='resample2')
    shift_rotate = pe.Node(afni.Allineate(), name='shift_rotate')
    apply_allineate1 = pe.Node(afni.Allineate(), name='apply_transform1')
    tcat2 = pe.Node(afni.TCat(), name='concatenate_across_individuals2')
    tstat2 = pe.Node(afni.TStat(), name='compute_average2')
    tcat3 = pe.Node(afni.TCat(), name='concatenate_across_individuals3')
    tstat3 = pe.Node(afni.TStat(), name='compute_average3')

    workflow.add_nodes([unifize, clip_level, compute_mask, apply_mask,
                        center_mass,
                        refit_copy, tcat1, tstat1, undump, refit_set,
                        resample1, resample2, shift_rotate, apply_allineate1,
                        tcat2, tstat2, tcat3, tstat3])

    #######################################################################
    # and connections
    workflow.connect(unifize, 'out_file', clip_level, 'in_file')
    workflow.connect(clip_level, 'clip_val',
                     compute_mask, 'intensity_threshold')
    workflow.connect(unifize, 'out_file', compute_mask, 'in_file')
    workflow.connect(compute_mask, 'out_file', apply_mask, 'in_file_a')
    workflow.connect(unifize, 'out_file', apply_mask, 'in_file_b')
    workflow.connect(apply_mask, 'out_file',
                     center_mass, 'in_file')
    workflow.connect(unifize, 'out_file', refit_copy, 'in_file')
    workflow.connect(center_mass, 'out_file',
                     refit_copy, 'duporigin_file')
    workflow.connect(center_mass, 'out_file', tcat1, 'in_files')
    workflow.connect(tcat1, 'out_file', tstat1, 'in_file')
    workflow.connect(tstat1, 'out_file', undump, 'in_file')
    workflow.connect(undump, 'out_file', refit_set, 'in_file')
    workflow.connect(refit_set, 'out_file', resample1, 'master')
    workflow.connect(refit_copy, 'out_file', resample1, 'in_file')
    workflow.connect(refit_set, 'out_file', resample2, 'master')
    workflow.connect(center_mass, 'out_file', resample2, 'in_file')
    workflow.connect(resample2, 'out_file', tcat2, 'in_files')
    workflow.connect(tcat2, 'out_file', tstat2, 'in_file')
    workflow.connect(tstat2, 'out_file', shift_rotate, 'reference')
    workflow.connect(resample2, 'out_file', shift_rotate, 'in_file')
    workflow.connect(tstat2, 'out_file', apply_allineate1, 'master')
    workflow.connect(resample1, 'out_file',
                     apply_allineate1, 'in_file')
    workflow.connect(shift_rotate, 'out_matrix',
                     apply_allineate1, 'in_matrix')
    workflow.connect(apply_allineate1, 'out_file', tcat3, 'in_files')
    workflow.connect(tcat3, 'out_file', tstat3, 'in_file')
    if pipeline_name in ['anats_to_common_affine',
                         'anat_to_common_nonlinear']:
        mask = pe.Node(afni.MaskTool(), name='generate_count_mask')
        allineate = pe.Node(afni.Allineate(), name='allineate')
        catmatvec = pe.Node(afni.CatMatvec(), name='concatenate_transforms')
        apply_allineate2 = pe.Node(afni.Allineate(), name='apply_transform2')
        tcat3 = pe.Node(
            afni.TCat(), name='concatenate_across_individuals4')
        tstat3 = pe.Node(afni.TStat(), name='compute_average4')

        workflow.add_nodes([mask, allineate, catmatvec, apply_allineate2,
                            tcat3, tstat3])

        workflow.connect(tcat2, 'out_file', mask, 'in_file')
        workflow.connect(mask, 'out_file', allineate, 'weight')
        workflow.connect(apply_allineate1, 'out_file',
                         allineate, 'in_file')
        workflow.connect(allineate, 'out_matrix',
                         catmatvec, 'in_file')
        #XXX how can we enter multiple files ? 
        workflow.connect(catmatvec, 'out_file',
                         apply_allineate2, 'in_matrix')
        workflow.connect(resample1, 'out_file',
                         apply_allineate2, 'in_file')
        workflow.connect(apply_allineate2, 'out_file', tcat3, 'in_files')
        workflow.connect(tcat3, 'out_file', tstat3, 'in_file')

    if pipeline_name == 'anats_to_common_nonlinear':
        pass

    graph_file_root, graph_file_ext = os.path.splitext(graph_file)
    if graph_file_ext:
        _ = workflow.write_graph(graph2use=graph_kind,
                                 format=graph_file_ext[1:],
                                 dotfilename=graph_file_root)
    else:
        _ = workflow.write_graph(graph2use=graph_kind,
                                 dotfilename=graph_file_root)
Ejemplo n.º 7
0
def create_register_NMT_pipe(params_template,
                             params={},
                             name="register_NMT_pipe"):
    """
    Description: Register template to anat with the script NMT_subject_align,
        and then apply it to tissues list_priors

    Inputs:

        inputnode:
            T1: T1 file name
            indiv_params: dict with individuals parameters for some nodes

        arguments:
            params_template: dictionary of info about template

            params: dictionary of node sub-parameters (from a json file)

            name: pipeline name (default = "register_NMT_pipe")

    Outputs:

        norm_intensity.output_image:
            filled mask after erode
        align_seg_csf.out_file:
            csf template tissue in subject space
        align_seg_gm.out_file:
            grey matter template tissue in subject space
        align_seg_wm.out_file:
            white matter template tissue in subject space
    """

    register_NMT_pipe = pe.Workflow(name=name)

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

    # N4 intensity normalization over brain
    norm_intensity = NodeParams(ants.N4BiasFieldCorrection(),
                                params=parse_key(params, "norm_intensity"),
                                name='norm_intensity')

    register_NMT_pipe.connect(inputnode, 'T1', norm_intensity, "input_image")

    register_NMT_pipe.connect(inputnode,
                              ('indiv_params', parse_key, "norm_intensity"),
                              norm_intensity, "indiv_params")

    deoblique = pe.Node(afni.Refit(deoblique=True), name="deoblique")
    register_NMT_pipe.connect(norm_intensity, 'output_image', deoblique,
                              "in_file")

    # align subj to nmt (with NMT_subject_align, wrapped version with nodes)
    NMT_subject_align = pe.Node(NMTSubjectAlign(), name='NMT_subject_align')

    register_NMT_pipe.connect(deoblique, 'out_file', NMT_subject_align,
                              "T1_file")

    NMT_subject_align.inputs.NMT_SS_file = params_template["template_brain"]

    # align_masks
    # "overwrap" of NwarpApply, with specifying the outputs as wished
    list_priors = [
        params_template["template_head"], params_template["template_csf"],
        params_template["template_gm"], params_template["template_wm"]
    ]

    align_masks = pe.Node(NwarpApplyPriors(), name='align_masks')
    align_masks.inputs.in_file = list_priors
    align_masks.inputs.out_file = list_priors
    align_masks.inputs.interp = "NN"
    align_masks.inputs.args = "-overwrite"

    register_NMT_pipe.connect(NMT_subject_align, 'shft_aff_file', align_masks,
                              'master')
    register_NMT_pipe.connect(NMT_subject_align, 'warpinv_file', align_masks,
                              "warp")

    # align_NMT
    align_NMT = pe.Node(afni.Allineate(),
                        name="align_NMT",
                        iterfield=['in_file'])
    align_NMT.inputs.final_interpolation = "nearestneighbour"
    align_NMT.inputs.overwrite = True
    align_NMT.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 0),
                              align_NMT, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image', align_NMT,
                              "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file', align_NMT,
                              "in_matrix")  # -1Dmatrix_apply

    # seg_csf
    align_seg_csf = pe.Node(afni.Allineate(),
                            name="align_seg_csf",
                            iterfield=['in_file'])
    align_seg_csf.inputs.final_interpolation = "nearestneighbour"
    align_seg_csf.inputs.overwrite = True
    align_seg_csf.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 1),
                              align_seg_csf, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image', align_seg_csf,
                              "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                              align_seg_csf, "in_matrix")  # -1Dmatrix_apply

    # seg_gm
    align_seg_gm = pe.Node(afni.Allineate(),
                           name="align_seg_gm",
                           iterfield=['in_file'])
    align_seg_gm.inputs.final_interpolation = "nearestneighbour"
    align_seg_gm.inputs.overwrite = True
    align_seg_gm.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 2),
                              align_seg_gm, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image', align_seg_gm,
                              "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                              align_seg_gm, "in_matrix")  # -1Dmatrix_apply

    # seg_wm
    align_seg_wm = pe.Node(afni.Allineate(),
                           name="align_seg_wm",
                           iterfield=['in_file'])
    align_seg_wm.inputs.final_interpolation = "nearestneighbour"
    align_seg_wm.inputs.overwrite = True
    align_seg_wm.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 3),
                              align_seg_wm, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image', align_seg_wm,
                              "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                              align_seg_wm, "in_matrix")  # -1Dmatrix_apply

    return register_NMT_pipe
Ejemplo n.º 8
0
    def __init__(self, settings):
        # call base constructor
        super().__init__(settings)

        # define input/output node
        self.set_input(['T1', 'orig', 'brainmask'])
        self.set_output(['T1_skullstrip', 'allineate_freesurfer2anat'])

        # define datasink substitutions
        self.set_subs([('_maskop40', ''), ('_calc_calc_calc_calc_calc', '')])

        # 3dAllineate (FSorig)
        self.allineate_orig = MapNode(afni.Allineate(
            out_matrix='FSorig2MPR.aff12.1D',
            overwrite=True,
            outputtype='NIFTI_GZ'),
                                      iterfield=['in_file', 'reference'],
                                      name='3dallineate_orig')
        # 3dAllineate (FSbrainmask)
        self.allineate_bm = MapNode(
            afni.Allineate(overwrite=True, no_pad=True, outputtype='NIFTI_GZ'),
            iterfield=['in_file', 'reference', 'in_matrix'],
            name='3dallineate_brainmask')

        # skullstrip mprage (afni)
        self.afni_skullstrip = MapNode(afni.SkullStrip(args="-orig_vol",
                                                       outputtype="NIFTI_GZ"),
                                       iterfield=['in_file'],
                                       name='afni_skullstrip')
        # 3dcalc operations for achieving final mask
        self.maskop1 = MapNode(afni.Calc(expr='step(a)',
                                         overwrite=True,
                                         outputtype='NIFTI_GZ'),
                               iterfield=['in_file_a'],
                               name='maskop1')
        self.maskop2 = []
        for n in range(3):
            self.maskop2.append(
                MapNode(afni.Calc(
                    args='-b a+i -c a-i -d a+j -e a-j -f a+k -g a-k',
                    expr='ispositive(a+b+c+d+e+f+g)',
                    overwrite=True,
                    outputtype='NIFTI_GZ'),
                        iterfield=['in_file_a'],
                        name='maskop2_{}'.format(n)))
        # Inline function for setting up to copy IJK_TO_DICOM_REAL file attribute
        self.refit_setup = MapNode(Function(input_names=['noskull_T1'],
                                            output_names=['refit_input'],
                                            function=lambda noskull_T1:
                                            (noskull_T1, 'IJK_TO_DICOM_REAL')),
                                   iterfield=['noskull_T1'],
                                   name='refitsetup')
        # 3dRefit
        self.refit = MapNode(afni.Refit(),
                             iterfield=['in_file', 'atrcopy'],
                             name='3drefit')
        # 3dcalc for uniform intensity
        self.uniform = MapNode(afni.Calc(expr='a*and(b,b)',
                                         overwrite=True,
                                         outputtype='NIFTI_GZ'),
                               iterfield=['in_file_a', 'in_file_b'],
                               name='uniformintensity')

        # skullstrip mprage (fsl)
        self.fsl_skullstrip = MapNode(fsl.BET(),
                                      iterfield=['in_file'],
                                      name='fsl_skullstrip')
        self.maskop3 = MapNode(
            afni.Calc(expr='or(a,b,c)', overwrite=True, outputtype='NIFTI_GZ'),
            iterfield=['in_file_a', 'in_file_b', 'in_file_c'],
            name='maskop3')
        self.maskop4 = MapNode(
            afni.Calc(expr='c*and(a,b)', overwrite=True,
                      outputtype='NIFTI_GZ'),
            iterfield=['in_file_a', 'in_file_b', 'in_file_c'],
            name='maskop4')

        # Convert from list to string input
        self.select0T1 = Node(Function(input_names=['T1_list'],
                                       output_names=['T1_0'],
                                       function=lambda T1_list: T1_list[0]),
                              name='select0T1')

        # apply bias field correction
        self.biasfieldcorrect = Node(ants.N4BiasFieldCorrection(
            num_threads=settings['num_threads'], copy_header=True),
                                     name='biasfieldcorrect')
Ejemplo n.º 9
0
io_S3DataGrabber.inputs.template = 'sub-01/anat/sub-01_T1w.nii.gz'
io_S3DataGrabber.inputs.anon = True
io_S3DataGrabber.inputs.bucket_path = 'ds000101/ds000101_R2.0.0/uncompressed/'
io_S3DataGrabber.inputs.local_directory = '/tmp'

#Wraps command **bet**
fsl_BET = pe.Node(interface=fsl.BET(), name='fsl_BET', iterfield=[''])

#Generic datasink module to store structured outputs
io_DataSink = pe.Node(interface=io.DataSink(),
                      name='io_DataSink',
                      iterfield=[''])
io_DataSink.inputs.base_directory = '/tmp'

#Wraps command **3dAllineate**
afni_Allineate = pe.Node(interface=afni.Allineate(),
                         name='afni_Allineate',
                         iterfield=[''])

#Create a workflow to connect all those nodes
analysisflow = nipype.Workflow('MyWorkflow')
analysisflow.connect(io_S3DataGrabber, "outfiles", fsl_BET, "in_file")
analysisflow.connect(fsl_BET, "out_file", afni_Allineate, "in_file")
analysisflow.connect(afni_Allineate, "out_file", io_DataSink, "BET_results")

#Run the workflow
plugin = 'MultiProc'  #adjust your desired plugin here
plugin_args = {'n_procs': 1}  #adjust to your number of cores
analysisflow.write_graph(graph2use='flat', format='png', simple_form=False)
analysisflow.run(plugin=plugin, plugin_args=plugin_args)
Ejemplo n.º 10
0
def _rigid_body_register(moving_head_file,
                         reference_head_file,
                         moving_brain_file,
                         reference_brain_file,
                         write_dir=None,
                         verbose=True,
                         caching=False,
                         terminal_output='allatonce',
                         environ=None):
    # XXX: add verbosity
    if write_dir is None:
        write_dir = os.path.dirname(moving_head_file)

    if environ is None:
        environ = {'AFNI_DECONFLICT': 'OVERWRITE'}

    if caching:
        memory = Memory(write_dir)
        allineate = memory.cache(afni.Allineate)
        allineate2 = memory.cache(afni.Allineate)
        catmatvec = memory.cache(afni.CatMatvec)
        for step in [allineate, allineate2]:
            step.interface().set_default_terminal_output(terminal_output)
    else:
        allineate = afni.Allineate(terminal_output=terminal_output).run
        allineate2 = afni.Allineate(terminal_output=terminal_output).run
        catmatvec = afni.CatMatvec().run

    output_files = [moving_brain_file, reference_brain_file]

    # Compute the transformation from functional to anatomical brain
    # XXX: why in this sense
    # XXX: caching does not work if out_matrix
    # path is absolute
    out_matrix = fname_presuffix(reference_brain_file,
                                 suffix='_shr.aff12.1D',
                                 use_ext=False)
    if caching:
        out_matrix = os.path.basename(out_matrix)

    out_allineate = allineate2(in_file=reference_brain_file,
                               reference=moving_brain_file,
                               out_matrix=out_matrix,
                               center_of_mass='',
                               warp_type='shift_rotate',
                               out_file='%s_shr',
                               environ=environ,
                               verbose=verbose,
                               outputtype='NIFTI_GZ')
    rigid_transform_file = out_allineate.outputs.out_matrix
    output_files.append(out_allineate.outputs.out_file)

    # apply the inverse transform to register the anatomical to the func
    out_catmatvec = catmatvec(in_file=[(rigid_transform_file, 'I')],
                              oneline=True,
                              out_file=fname_presuffix(rigid_transform_file,
                                                       suffix='INV',
                                                       newpath=write_dir),
                              environ=environ)
    output_files.append(out_catmatvec.outputs.out_file)
    out_allineate_apply = allineate(in_file=moving_head_file,
                                    master=reference_head_file,
                                    in_matrix=out_catmatvec.outputs.out_file,
                                    out_file=fname_presuffix(
                                        moving_head_file,
                                        suffix='_shr',
                                        newpath=write_dir),
                                    environ=environ)

    # Remove intermediate output
    if not caching:
        for output_file in output_files:
            os.remove(output_file)

    return out_allineate_apply.outputs.out_file, rigid_transform_file
Ejemplo n.º 11
0
def _apply_transforms(to_register_filename,
                      target_filename,
                      write_dir,
                      transforms,
                      transformed_filename=None,
                      transforms_kind='nonlinear',
                      interpolation=None,
                      voxel_size=None,
                      inverse=False,
                      caching=False,
                      verbose=True):
    """ Applies successive transforms to a given image to put it in
    template space.

    Parameters
    ----------
    to_register_filename : str
        Path to the source file to register.

    target_filename : str
        Reference file to register to.

    transforms : list
        List of transforms in order of 3dNWarpApply application: first must
        one must be in the target space and last one must be in
        the source space.

    transformed_filename : str, optional
        Path to the output registered file

    inverse : bool, optional
        If True, after the transforms composition is computed, invert it.
        If the input transforms would take a dataset from space A to B,
        then the inverted transform will do the reverse.

    interpolation : one of {'nearestneighbour', 'linear', 'cubic', 'quintic',
                            'wsinc5'} or None, optional
        Interpolation type. If None, AFNI defaults are used.

    voxel_size : 3-tuple of floats, optional
        Voxel size of the registered functional, in mm.

    caching : bool, optional
        Wether or not to use caching.

    verbose : bool, optional
        If True, all steps are verbose. Note that caching implies some
        verbosity in any case.
    """
    environ = {'AFNI_DECONFLICT': 'OVERWRITE'}
    if verbose:
        terminal_output = 'allatonce'
    else:
        terminal_output = 'none'

    if caching:
        memory = Memory(write_dir)
        catmatvec = memory.cache(afni.CatMatvec)
        allineate = memory.cache(afni.Allineate)
        warp_apply = memory.cache(afni.NwarpApply)
        resample = memory.cache(afni.Resample)
        for step in [resample, allineate, warp_apply]:
            step.interface().set_default_terminal_output(terminal_output)
    else:
        resample = afni.Resample(terminal_output=terminal_output).run
        catmatvec = afni.CatMatvec().run
        allineate = afni.Allineate(terminal_output=terminal_output).run
        warp_apply = afni.NwarpApply(terminal_output=terminal_output).run

    if transformed_filename is None:
        target_basename = os.path.basename(target_filename)
        target_basename = os.path.splitext(target_basename)[0]
        target_basename = os.path.splitext(target_basename)[0]
        transformed_filename = fname_presuffix(to_register_filename,
                                               suffix='_to_' + target_basename,
                                               newpath=write_dir)

    if voxel_size is None:
        resampled_target_filename = target_filename
    else:
        out_resample = resample(in_file=target_filename,
                                voxel_size=voxel_size,
                                out_file=fname_presuffix(target_filename,
                                                         suffix='_resampled',
                                                         newpath=write_dir),
                                environ=environ)
        resampled_target_filename = out_resample.outputs.out_file
    if transforms_kind is not 'nonlinear':
        affine_transform_filename = fname_presuffix(transformed_filename,
                                                    suffix='.aff12.1D',
                                                    use_ext=False)
        out_catmatvec = catmatvec(in_file=[(transform, 'ONELINE')
                                           for transform in transforms],
                                  oneline=True,
                                  out_file=affine_transform_filename,
                                  environ=environ)
        if inverse:
            affine_transform_filename = fname_presuffix(transformed_filename,
                                                        suffix='_INV.aff12.1D',
                                                        use_ext=False)
            _ = catmatvec(in_file=[(out_catmatvec.outputs.out_file, 'I')],
                          oneline=True,
                          out_file=affine_transform_filename,
                          environ=environ)
        if interpolation is None:
            _ = allineate(in_file=to_register_filename,
                          master=resampled_target_filename,
                          in_matrix=affine_transform_filename,
                          out_file=transformed_filename,
                          environ=environ)
        else:
            _ = allineate(in_file=to_register_filename,
                          master=resampled_target_filename,
                          in_matrix=affine_transform_filename,
                          final_interpolation=interpolation,
                          out_file=transformed_filename,
                          environ=environ)
    else:
        warp = "'"
        warp += " ".join(transforms)
        warp += "'"
        if interpolation is None:
            _ = warp_apply(in_file=to_register_filename,
                           master=resampled_target_filename,
                           warp=warp,
                           inv_warp=inverse,
                           out_file=transformed_filename,
                           environ=environ)
        else:
            _ = warp_apply(in_file=to_register_filename,
                           master=resampled_target_filename,
                           warp=warp,
                           inv_warp=inverse,
                           interp=interpolation,
                           out_file=transformed_filename,
                           environ=environ)

    # XXX obliquity information is lost if resampling is done
    transformed_filename = fix_obliquity(transformed_filename,
                                         resampled_target_filename,
                                         verbose=verbose,
                                         caching=caching,
                                         caching_dir=write_dir,
                                         environ=environ)
    return transformed_filename
Ejemplo n.º 12
0
def init_single_subject_wf(
    name,
    output_dir,
    layout,
    bold_mag_files,
    bold_mag_metadata,
    bold_phase_files,
    bold_phase_metadata,
    sbref_mag_files,
    sbref_mag_metadata,
    sbref_phase_files,
    sbref_phase_metadata,
    t1w_files,
    t1w_metadata,
    t2w_files,
    t2w_metadata,
):

    workflow = pe.Workflow(name=name)

    # name the nodes
    inputnode = pe.Node(
        niu.IdentityInterface(fields=[
            'bold_mag_files',
            'bold_mag_metadata',
            'bold_phase_files',
            'bold_phase_metadata',
            'sbref_mag_files',
            'sbref_mag_metadata',
            'sbref_phase_files',
            'sbref_phase_metadata',
            't1w_files',
            't1w_metadata',
            't2w_files',
            't2w_metadata',
        ]),
        name='inputnode',
        iterables=[
            ('bold_mag_files', bold_mag_files),
            ('bold_mag_metadata', bold_mag_metadata),
            ('bold_phase_files', bold_phase_files),
            ('bold_phase_metadata', bold_phase_metadata),
            ('sbref_mag_files', sbref_mag_files),
            ('sbref_mag_metadata', sbref_mag_metadata),
            ('sbref_phase_files', sbref_phase_files),
            ('sbref_phase_metadata', sbref_phase_metadata),
        ],
        synchronize=True,
    )
    inputnode.inputs.t1w_files = t1w_files
    inputnode.inputs.t1w_metadata = t1w_metadata
    inputnode.inputs.t2w_files = t2w_files
    inputnode.inputs.t2w_metadata = t2w_metadata

    outputnode = pe.Node(
        niu.IdentityInterface(fields=[
            'preproc_bold_files', 'preproc_phase_files', 'motion_parameters'
        ]),
        name='outputnode',
    )

    # Generate single-band reference image-based field maps
    sbref_phdiff_wf = init_phdiff_wf(name='sbref_phdiff_wf',
                                     create_phasediff=True,
                                     omp_nthreads=1,
                                     fmap_bspline=None)
    workflow.connect(
        inputnode,
        ('sbref_phase_files', pick_first),
        sbref_phdiff_wf,
        'inputnode.phase1',
    )
    workflow.connect(
        inputnode,
        ('sbref_phase_files', pick_second),
        sbref_phdiff_wf,
        'inputnode.phase2',
    )
    workflow.connect(
        inputnode,
        ('sbref_mag_files', pick_first),
        sbref_phdiff_wf,
        'inputnode.magnitude',
    )
    workflow.connect(
        inputnode,
        ('sbref_phase_metadata', pick_first),
        sbref_phdiff_wf,
        'inputnode.phase1_metadata',
    )
    workflow.connect(
        inputnode,
        ('sbref_phase_metadata', pick_second),
        sbref_phdiff_wf,
        'inputnode.phase2_metadata',
    )

    # Generate dynamic field maps
    # Somehow select the first two echoes
    docma_wf = init_docma_wf(omp_nthreads=1, name='docma_wf')

    bold_mag_splitter = pe.MapNode(
        interface=fsl.Split(dimension='t'),
        name='bold_mag_splitter',
        iterfield=['in_file'],
    )
    bold_phase_splitter = pe.MapNode(
        interface=fsl.Split(dimension='t'),
        name='bold_phase_splitter',
        iterfield=['in_file'],
    )
    workflow.connect(inputnode, 'bold_mag_files', bold_mag_splitter, 'in_file')
    workflow.connect(inputnode, 'bold_phase_files', bold_phase_splitter,
                     'in_file')
    """
    bold_phdiff_wf = init_phdiff_wf(name='bold_phdiff_wf',
                                    create_phasediff=True,
                                    omp_nthreads=1,
                                    fmap_bspline=None)
    workflow.connect(inputnode, ('bold_phase_files', pick_first),
                     bold_phdiff_wf, 'inputnode.phase1')
    workflow.connect(inputnode, ('bold_phase_files', pick_second),
                     bold_phdiff_wf, 'inputnode.phase2')
    workflow.connect(inputnode, ('bold_mag_files', pick_first),
                     bold_phdiff_wf, 'inputnode.magnitude')
    workflow.connect(inputnode, ('bold_phase_metadata', pick_first),
                     bold_phdiff_wf, 'inputnode.phase1_metadata')
    workflow.connect(inputnode, ('bold_phase_metadata', pick_second),
                     bold_phdiff_wf, 'inputnode.phase2_metadata')

    """
    """
    # Skullstrip BOLD files on a volume-wise basis
    # Need to feed in 3D files from first echo
    bold_mag_buffer = pe.Node(
        interface=niu.IdentityInterface(fields=['bold_mag_files']),
        name='bold_mag_buffer')
    bold_mag_buffer.iterables = ('bold_mag_files', (bold_mag_splitter.outputs.out_files, pick_first))

    bold_skullstrip_wf = init_skullstrip_bold_wf(name='bold_skullstrip_wf')
    workflow.connect(bold_mag_buffer, 'bold_mag_files',
                     bold_skullstrip_wf, 'inputnode.in_file')

    # Apply volume-wise brain masks to corresponding volumes from all echoes
    bold_skullstrip_apply = pe.MapNode(
        fsl.ApplyMask(),
        name='bold_skullstrip_apply',
        iterfield=['in_file'],
    )
    workflow.connect(inputnode, 'bold_mag_files',
                     bold_skullstrip_apply, 'in_file')
    workflow.connect(bold_skullstrip_wf, 'outputnode.mask_file',
                     bold_skullstrip_apply, 'mask_file')
    """
    """
    # Unwarp BOLD data
    # Must be applied to each volume and each echo independently
    # Will also need to be done to the phase data, post preproc but pre-MC
    bold_unwarp_wf = init_sdc_unwarp_wf(name='bold_unwarp_wf',
                                        debug=False,
                                        omp_nthreads=1,
                                        fmap_demean=True)
    first_echo_metadata = pe.Node(interface=Function(['input'], ['output'], pick_first),
                                  name='first_echo_metadata')
    workflow.connect(bold_phdiff_wf, 'outputnode.fmap',
                     bold_unwarp_wf, 'inputnode.fmap')
    workflow.connect(bold_phdiff_wf, 'outputnode.fmap_mask',
                     bold_unwarp_wf, 'inputnode.fmap_mask')
    workflow.connect(bold_phdiff_wf, 'outputnode.fmap_ref',
                     bold_unwarp_wf, 'inputnode.fmap_ref')
    workflow.connect(inputnode, ('bold_mag_files', pick_first),
                     bold_unwarp_wf, 'inputnode.in_reference')
    workflow.connect(bold_skullstrip_apply, ('out_file', pick_first),
                     bold_unwarp_wf, 'inputnode.in_reference_brain')
    workflow.connect(bold_skullstrip_wf, ('outputnode.mask_file', pick_first),
                     bold_unwarp_wf, 'inputnode.in_mask')
    workflow.connect(inputnode, 'bold_mag_metadata',
                     first_echo_metadata, 'input')
    workflow.connect(first_echo_metadata, 'output',
                     bold_unwarp_wf, 'inputnode.metadata')
    """

    # Process BOLD phase data for distortion correction
    bold_phase_wf = init_phase_processing_wf(name='phase_processing_wf')
    workflow.connect(inputnode, 'bold_phase_files', bold_phase_wf,
                     'inputnode.phase_files')
    workflow.connect(inputnode, 'bold_mag_files', bold_phase_wf,
                     'inputnode.magnitude_files')

    # Phaseprep preprocessing workflow to prepare phase data for phase-denoising
    reference_wf = init_bold_reference_wf(name='reference_wf')
    workflow.connect(
        bold_motionCorrection_applyMag,
        ('out_file', pick_first),
        reference_wf,
        'inputnode.bold_file',
    )
    workflow.connect(inputnode, ('sbref_mag_files', pick_first), reference_wf,
                     'inputnode.sbref_file')

    # This workflow is set up for single-echo data, so we need to
    # split or iterate over echoes here
    phaseprep_wf = create_preprocess_phase_wf(name='phaseprep_wf')
    workflow.connect(inputnode, 'bold_phase_files', phaseprep_wf,
                     'inputnode.input_phase')
    workflow.connect(inputnode, 'bold_mag_files', phaseprep_wf,
                     'inputnode.input_mag')

    # These ones are constant across echoes
    workflow.connect(
        bold_motionCorrection_estimate,
        'oned_matrix_save',
        phaseprep_wf,
        'inputnode.motion_par',
    )
    workflow.connect(reference_wf, 'outputnode.bold_mask', phaseprep_wf,
                     'inputnode.mask_file')

    # Perform motion correction for first echo only
    bold_motionCorrection_estimate = pe.Node(
        interface=afni.Volreg(outputtype='NIFTI_GZ'),
        name='bold_motionCorrection_estimate',
    )

    get_motpar_name_node = pe.Node(
        interface=Function(['source_file'], ['out_file'], get_motpar_name),
        name='get_motpar_name',
    )
    workflow.connect(
        inputnode,
        ('bold_mag_files', pick_first),
        bold_motionCorrection_estimate,
        'in_file',
    )
    workflow.connect(inputnode, ('bold_mag_files', pick_first),
                     get_motpar_name_node, 'source_file')
    workflow.connect(
        get_motpar_name_node,
        'out_file',
        bold_motionCorrection_estimate,
        'oned_matrix_save',
    )
    workflow.connect(
        inputnode,
        ('sbref_mag_files', pick_first),
        bold_motionCorrection_estimate,
        'basefile',
    )

    # Apply motion parameters to all echoes, for both magnitude and phase data
    bold_motionCorrection_applyMag = pe.MapNode(
        interface=afni.Allineate(outputtype='NIFTI_GZ'),
        name='bold_motionCorrection_applyMag',
        iterfield=['in_file'],
    )
    workflow.connect(
        bold_motionCorrection_estimate,
        'oned_matrix_save',
        bold_motionCorrection_applyMag,
        'in_matrix',
    )
    workflow.connect(inputnode, 'bold_mag_files',
                     bold_motionCorrection_applyMag, 'in_file')
    workflow.connect(
        inputnode,
        ('sbref_mag_files', pick_first),
        bold_motionCorrection_applyMag,
        'reference',
    )

    # Perform slice timing correction on magnitude and phase data
    bold_stc_getParams = pe.MapNode(
        interface=Function(['metadata'], ['slice_timing'], get_slice_timing),
        name='bold_stc_getParams',
        iterfield=['metadata'],
    )
    workflow.connect(inputnode, 'bold_mag_metadata', bold_stc_getParams,
                     'metadata')

    bold_magnitude_stc = pe.MapNode(
        interface=afni.TShift(outputtype='NIFTI_GZ'),
        name='bold_magnitude_stc',
        iterfield=['in_file', 'slice_timing'],
    )
    workflow.connect(bold_motionCorrection_applyMag, 'out_file',
                     bold_magnitude_stc, 'in_file')
    workflow.connect(bold_stc_getParams, 'slice_timing', bold_magnitude_stc,
                     'slice_timing')

    # Use SBRef from first echo as reference image.
    # No need to coregister functional data to SBRef because it was used for
    # the motion correction.
    # Coregister reference image to structural
    coreg_est = pe.Node(interface=afni.Allineate(out_matrix='sbref2anat.1D'),
                        name='sbref2anat_estimate')
    workflow.connect(inputnode, ('sbref_mag_files', pick_first), coreg_est,
                     'in_file')
    workflow.connect(inputnode, ('t1w_files', pick_first), coreg_est,
                     'reference')

    # Apply xform to mag data
    coreg_apply_mag = pe.MapNode(
        interface=afni.Allineate(outputtype='NIFTI_GZ'),
        name='sbref2anat_apply_mag',
        iterfield=['in_file'],
    )
    workflow.connect(coreg_est, 'out_matrix', coreg_apply_mag, 'in_matrix')
    workflow.connect(bold_magnitude_stc, 'out_file', coreg_apply_mag,
                     'in_file')
    workflow.connect(inputnode, ('sbref_mag_files', pick_first),
                     coreg_apply_mag, 'reference')

    # Apply xform to phase data
    coreg_apply_phase = pe.MapNode(
        interface=afni.Allineate(outputtype='NIFTI_GZ'),
        name='sbref2anat_apply_phase',
        iterfield=['in_file'],
    )
    workflow.connect(coreg_est, 'out_matrix', coreg_apply_phase, 'in_matrix')
    workflow.connect(phaseprep_wf, 'outputnode.uw_phase', coreg_apply_phase,
                     'in_file')
    workflow.connect(inputnode, ('sbref_mag_files', pick_first),
                     coreg_apply_phase, 'reference')

    # Apply xform to magnitude sbref data
    coreg_apply_sbref = pe.MapNode(
        interface=afni.Allineate(outputtype='NIFTI_GZ'),
        name='sbref2anat_apply_sbref',
        iterfield=['in_file'],
    )
    workflow.connect(coreg_est, 'out_matrix', coreg_apply_sbref, 'in_matrix')
    workflow.connect(inputnode, 'sbref_mag_files', coreg_apply_sbref,
                     'in_file')
    workflow.connect(inputnode, ('sbref_mag_files', pick_first),
                     coreg_apply_sbref, 'reference')

    # Collect outputs
    workflow.connect(bold_motionCorrection_estimate, 'oned_file', outputnode,
                     'motion_parameters')
    workflow.connect(coreg_apply_mag, 'out_file', outputnode,
                     'preproc_bold_files')
    workflow.connect(coreg_apply_phase, 'out_file', outputnode,
                     'preproc_phase_files')

    # Output BOLD mag files
    derivativesnode1 = pe.MapNode(
        interface=Function(['in_file', 'output_dir'], ['out_file'],
                           copy_files),
        name='derivativesnode_bold_mag',
        iterfield=['in_file'],
    )
    derivativesnode1.inputs.output_dir = output_dir
    workflow.connect(outputnode, 'preproc_bold_files', derivativesnode1,
                     'in_file')
    # Output BOLD phase files
    derivativesnode2 = pe.MapNode(
        interface=Function(['in_file', 'output_dir'], ['out_file'],
                           copy_files),
        name='derivativesnode_bold_phase',
        iterfield=['in_file'],
    )
    derivativesnode2.inputs.output_dir = output_dir
    workflow.connect(outputnode, 'preproc_phase_files', derivativesnode2,
                     'in_file')
    # Output motion parameters
    derivativesnode3 = pe.Node(
        interface=Function(['in_file', 'output_dir'], ['out_file'],
                           copy_files),
        name='derivativesnode_motpars',
    )
    derivativesnode3.inputs.output_dir = output_dir
    workflow.connect(outputnode, 'motion_parameters', derivativesnode3,
                     'in_file')
    return workflow
Ejemplo n.º 13
0
def base_preproc(trim_realign=True,name='rsfmri_base_preproc'):

    inputnode = pe.Node(
        utility.IdentityInterface(
            fields=['fmri','t1','t1_mask']),
        name='inputspec')
    outputnode = pe.Node(
        utility.IdentityInterface(
            fields=['preprocessed','mask','mean','motion']),
        name='outputspec')

#    n_trim = pe.Node(
#        interface=nipypp.Trim(begin_index=3),
#        name='trim')
    
    n_realign = pe.Node(
        fsl.MCFLIRT(ref_vol=0,
                    mean_vol=True,
                    save_plots=True,
                    save_rms=True,
                    save_mats=True,
                    stats_imgs=True,),
        name='realign')

    n_mean = pe.Node(fsl.MeanImage(),name='mean')

    n_mask = pe.Node(
        interface=afni.Automask(
            out_file='%s_mask.nii',
#            brain_file=Undefined,
            outputtype='NIFTI'),
        name='mask')

    n_mask_mean = pe.Node(
        interface=fsl.ImageMaths(op_string='-mul', suffix='_brain',
                                 output_type='NIFTI'),
        name='mask_mean')

    n_segment_epi = pe.Node(
        fsl.FAST(
            img_type=2,
            number_classes=3,
            probability_maps=True,
            segments=True),
        name='segment_epi')

    #linear with shear/scale in phase direction
    n_coregister_linear = pe.Node(
        afni.Allineate(epi=True, args='-float',cost='nmi',
                       out_param_file='params.1D',
                       out_matrix='coregister.mat'),
        name='coregister_linear')

    n_coregister_gray_linear = pe.Node(
        afni.Allineate(epi=True, args='-float',cost='nmi',
                       out_param_file='params.1D',
                       out_matrix='coregister.mat'),
        name='coregister_gray_linear')

    n_smooth = pe.Node(
        afni.BlurInMask(fwhm=5.0, out_file='%s_smooth', float_out=True),
        name = 'smooth')    

    n_bandpass_smooth = pe.Node(
        afni.Bandpass(highpass=0.005, lowpass=999999,
                      despike=True,
                      blur=5.0, normalize=False, out_file='%s_filt.nii.gz'),
        name='bandpass_smooth')

    n_motion_filter = pe.Node(
        interface = nipypp.RegressOutMotion(
            motion_source='fsl',
            regressors_type='voxelwise_translation',
            global_signal = False,
            prefix = 'mfilt_',
            regressors_transform='original+bw_derivatives'),
        name = 'motion_filter')


#    spm_path = spm.Info().version()['path']
#    epi_tpl = os.path.join(spm_path, 'templates/EPI.nii')
    """
    n_normalize = pe.Node(
        spm.Normalize(template=epi_tpl,
                      source_image_smoothing=8,
                      template_image_smoothing=0,
                      DCT_period_cutoff=25,
                      affine_regularization_type='mni',
                      jobtype='est'),
        name='normalize')
        """

    n_motion_estimates = pe.Node(
        nipyutils.MotionEstimate(motion_source='fsl'),
        name='motion_estimates')    

    w=pe.Workflow(name=name)

    if trim_realign:
        w.connect([
#                (inputnode, n_trim, [('fmri','in_file')]),
#                (inputnode, n_trim, [('fmri','in_file_a'),
#                                     (('fmri',n_volumes,-1),'stop_idx')]),
#                (n_trim, n_realign, [('out_file','in_file')]),
                (inputnode, n_realign, [('fmri','in_file')]),
#                (inputnode, n_realign, [('fmri','in_file')]),
                (n_realign, n_motion_filter, [('out_file','in_file'),
                                              ('par_file','motion')]),
                (n_mask, n_motion_filter,[('out_file','mask')]),
                (n_motion_filter, n_bandpass_smooth, [('out_file','in_file')]),
                (n_realign, n_mask, [('out_file','in_file')]),                
                (n_realign, n_mask_mean,  [('mean_img', 'in_file')]),
                (n_realign, n_motion_estimates,[('par_file','motion')]),
                (n_mask, n_motion_estimates,[('out_file','mask')]),
                (n_realign, outputnode, [('par_file','motion')]),
                ])
    else:
        w.connect([
                (inputnode, n_bandpass_smooth, [('fmri','in_file')]),
                (inputnode, n_mean, [('fmri','in_file')]),
                (inputnode, n_mask, [('fmri','in_file')]),                
                (n_mean, n_mask_mean, [('out_file', 'in_file')]),
                ])

    w.connect([
        (n_mask, n_mask_mean,  [('out_file', 'in_file2')]),
        (n_mask, n_bandpass_smooth, [('out_file','mask')]),
#        (n_mask_mean, n_segment_epi, [('out_file','in_files')]),
#        (n_mask_mean, n_normalize, [('out_file','source')]),
        
#        (n_detrend, n_smooth, [('out_file','in_file')]),
#        (n_mask, n_smooth,  [('out_file', 'mask')]),


#        (n_smooth, outputnode, [('out_file','preprocessed')]),
        (n_bandpass_smooth, outputnode, [('out_file','preprocessed')]),
        (n_mask, outputnode, [('out_file','mask')]),
        (n_mask_mean, outputnode, [('out_file','mean')]),

      ])
    return w
Ejemplo n.º 14
0
def create_preprocess_mag_wf():
    preprocmag = pe.Workflow(name="preprocmag")
    preprocmag.config['execution']['remove_unnecessary_outputs'] = False

    # define inputs
    inputspec = pe.Node(ul.IdentityInterface(fields=['input_mag', # raw phase data
                                                     'frac', # BET franction (-f parameter)
                                                     'rest', # volumes of rest in block design
                                                     'task', # volumes of task in block design
                                                     ]),
                        name='inputspec')

    # convert image to float
    img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float', op_string='', suffix='_dtype'),
                           iterfield=['in_file'],
                           name='img2float')

    # motion correct each run
    volreg = pe.MapNode(interface=afni.Volreg(), name='volreg', iterfield='in_file')
    volreg.inputs.outputtype = 'NIFTI_GZ'

    # calculate relative motions
    calcrel = pe.MapNode(ul.Function(['in_file'], ['out_file'], calcrelmotion),
        name='calcrel', iterfield=['in_file'])

    #generate motion plots
    plotmc = pe.MapNode(interface=fsl.PlotMotionParams(), name='plotmc', iterfield='in_file')
    plotmc.inputs.in_source = 'fsl'
    plotmc.iterables = ("plot_type", ['rotations', 'translations', 'displacement'])

    # register each run to first volume of first run
    # A) extract the first volume of the first run
    extract_ref = pe.MapNode(interface=fsl.ExtractROI(t_size=1, t_min=0), name='extract_ref', iterfield=['in_file'])

    # B) registration
    align2first = pe.MapNode(interface=afni.Allineate(), name='align2first', iterfield=['in_file'])
    align2first.inputs.num_threads = 2
    align2first.inputs.out_matrix = 'align2first'

    # merge xfm from moco and first run alignment
    merge_xfm = pe.MapNode(interface=ul.Merge(2), name='merge_xfm', iterfield=['in1', 'in2'])

    # concatenate moco and alignment to run 1
    cat_xfm = pe.MapNode(interface=afni.CatMatvec(oneline=True), name='cat_xfm', iterfield=['in_file'])
    cat_xfm.inputs.out_file = 'concated_xfm.aff12.1D'

    # apply first volume registration and motion correction in a single step
    applyalign = pe.MapNode(interface=afni.Allineate(), name='applyalign', iterfield=['in_file', 'in_matrix'])
    applyalign.inputs.num_threads = 2
    applyalign.inputs.final_interpolation = 'nearestneighbour'
    applyalign.inputs.outputtype = 'NIFTI_GZ'

    # afni messes with the header (unobliques the data) this puts it back
    cpgeommoco = pe.MapNode(interface=fsl.CopyGeom(), name='cpgeommoco', iterfield=['dest_file', 'in_file'])

    # linear detrending prior to SNR calculation
    detrend = pe.MapNode(interface=pp.DetrendMag(), name='detrend', iterfield=['mag'])

    # get the mean functional of run 1 for brain extraction
    meanfunc = pe.MapNode(interface=fsl.ImageMaths(op_string='-Tmean',
                                                suffix='_mean'),
                       name='meanfunc', iterfield=['in_file'])

    # calculate the phase noise (takes in volume of activation, if none provided them assumes resting state)
    calcSNR = pe.MapNode(interface=pp.RestAverage(), name='calcSNR', iterfield=['func', 'rest', 'task'])

    # extract brain with fsl and save the mask
    extractor = pe.Node(interface=fsl.BET(), name="extractor")
    extractor.inputs.mask = True

    # apply the mask to all runs
    maskfunc = pe.MapNode(interface=fsl.ImageMaths(suffix='_bet',
                                                   op_string='-mas'),
                          iterfield=['in_file'],
                          name='maskfunc')

    # outputspec
    outputspec = pe.Node(ul.IdentityInterface(fields=['proc_mag','motion_par',
                                                      'motion_data', 'maxdisp_data' ,
                                                      'motion_plot', 'run_txfm',
                                                      'mask_file','mean_file','snr']),
                        name='outputspec')

    preprocmag = pe.Workflow(name='preprocmag')
    preprocmag.connect([(inputspec, img2float, [('input_mag', 'in_file')]),
                        (img2float, volreg, [('out_file', 'in_file')]),
                        (volreg, extract_ref, [('out_file', 'in_file')]),
                        (extract_ref, align2first, [('roi_file', 'in_file')]),
                        (extract_ref, align2first, [(('roi_file', pickfirst), 'reference')]),
                        (extract_ref, applyalign, [(('roi_file', pickfirst), 'reference')]),
                        (volreg, merge_xfm, [('oned_matrix_save', 'in2')]),
                        (align2first, merge_xfm, [('out_matrix', 'in1')]),
                        (merge_xfm, cat_xfm, [(('out', wraptuple), 'in_file')]),
                        (volreg,applyalign, [('out_file', 'in_file')]),
                        (volreg, calcrel, [('md1d_file', 'in_file')]),
                        (volreg, plotmc, [('oned_file', 'in_file')]),
                        (cat_xfm, applyalign, [('out_file', 'in_matrix')]),
                        (img2float, cpgeommoco, [('out_file', 'in_file')]),
                        (applyalign, cpgeommoco, [('out_file', 'dest_file')]),
                        (cpgeommoco, detrend, [('out_file', 'mag')]),
                        (detrend, meanfunc, [('detrended_mag', 'in_file')]),
                        (inputspec, calcSNR, [('rest', 'rest'),
                                              ('task', 'task')]),
                        (detrend, calcSNR, [('detrended_mag', 'func')]),
                        (inputspec, extractor, [('frac', 'frac')]),
                        (meanfunc, extractor, [(('out_file', pickfirst), 'in_file')]),
                        (cpgeommoco, maskfunc, [('out_file', 'in_file')]),
                        (extractor, maskfunc, [('mask_file', 'in_file2')]),
                        (maskfunc, outputspec, [('out_file', 'proc_mag')]),
                        (volreg, outputspec, [('oned_matrix_save', 'motion_par')]),
                        (volreg, outputspec, [('oned_file', 'motion_data')]),
                        (volreg, outputspec, [('md1d_file', 'maxdisp_data')]),
                        (plotmc, outputspec, [('out_file', 'motion_plot')]),
                        (cat_xfm, outputspec, [('out_file', 'run_txfm')]),
                        (extractor, outputspec, [('mask_file', 'mask_file')]),
                        (extractor, outputspec, [('out_file', 'mean_file')]),
                        (calcSNR, outputspec, [('tsnr', 'snr')]),
                        ])

    return preprocmag
Ejemplo n.º 15
0
def coregister_fmri_session(session_data,
                            t_r,
                            write_dir,
                            brain_volume,
                            use_rats_tool=True,
                            slice_timing=True,
                            prior_rigid_body_registration=False,
                            caching=False,
                            voxel_size_x=.1,
                            voxel_size_y=.1,
                            verbose=True,
                            **environ_kwargs):
    """
    Coregistration of the subject's functional and anatomical images.
    The functional volume is aligned to the anatomical, first with a rigid body
    registration and then on a per-slice basis (only a fine correction, this is
    mostly for correction of EPI distortion).


    Parameters
    ----------
    session_data : sammba.registration.SessionData
        Single animal data, giving paths to its functional and anatomical
        image, as well as it identifier.

    t_r : float
        Repetition time for the EPI, in seconds.

    write_dir : str
        Directory to save the output and temporary images.

    brain_volume : int
        Volume of the brain in mm3 used for brain extraction.
        Typically 400 for mouse and 1800 for rat.

    use_rats_tool : bool, optional
        If True, brain mask is computed using RATS Mathematical Morphology.
        Otherwise, a histogram-based brain segmentation is used.

    prior_rigid_body_registration : bool, optional
        If True, a rigid-body registration of the anat to the func is performed
        prior to the warp. Useful if the images headers have missing/wrong
        information.

    voxel_size_x : float, optional
        Resampling resolution for the x-axis, in mm.

    voxel_size_y : float, optional
        Resampling resolution for the y-axis, in mm.

    caching : bool, optional
        Wether or not to use caching.

    verbose : bool, optional
        If True, all steps are verbose. Note that caching implies some
        verbosity in any case.

    environ_kwargs : extra arguments keywords
        Extra arguments keywords, passed to interfaces environ variable.

    Returns
    -------
    the same sequence with each animal_data updated: the following attributes
    are added
        - `output_dir_` : str
                          Path to the output directory.
        - `coreg_func_` : str
                          Path to paths to the coregistered functional image.
        - `coreg_anat_` : str
                          Path to paths to the coregistered functional image.
        - `coreg_transform_` : str
                               Path to the transform from anat to func.

    Notes
    -----
    If `use_rats_tool` is turned on, RATS tool is used for brain extraction
    and has to be cited. For more information, see
    `RATS <http://www.iibi.uiowa.edu/content/rats-overview/>`_
    """
    func_filename = session_data.func
    anat_filename = session_data.anat

    environ = {'AFNI_DECONFLICT': 'OVERWRITE'}
    for (key, value) in environ_kwargs.items():
        environ[key] = value

    if verbose:
        terminal_output = 'allatonce'
    else:
        terminal_output = 'none'

    if use_rats_tool:
        if segmentation.interfaces.Info().version() is None:
            raise ValueError('Can not locate RATS')
        else:
            ComputeMask = segmentation.MathMorphoMask
    else:
        ComputeMask = segmentation.HistogramMask

    if ants.base.Info().version is None:
        raise ValueError('Can not locate ANTS')

    if caching:
        memory = Memory(write_dir)
        tshift = memory.cache(afni.TShift)
        clip_level = memory.cache(afni.ClipLevel)
        volreg = memory.cache(afni.Volreg)
        allineate = memory.cache(afni.Allineate)
        tstat = memory.cache(afni.TStat)
        compute_mask = memory.cache(ComputeMask)
        calc = memory.cache(afni.Calc)
        allineate = memory.cache(afni.Allineate)
        allineate2 = memory.cache(afni.Allineate)
        unifize = memory.cache(afni.Unifize)
        bias_correct = memory.cache(ants.N4BiasFieldCorrection)
        catmatvec = memory.cache(afni.CatMatvec)
        warp = memory.cache(afni.Warp)
        resample = memory.cache(afni.Resample)
        slicer = memory.cache(afni.ZCutUp)
        warp_apply = memory.cache(afni.NwarpApply)
        qwarp = memory.cache(afni.Qwarp)
        merge = memory.cache(afni.Zcat)
        copy_geom = memory.cache(fsl.CopyGeom)
        overwrite = False
        for step in [
                tshift, volreg, allineate, allineate2, tstat, compute_mask,
                calc, unifize, resample, slicer, warp_apply, qwarp, merge
        ]:
            step.interface().set_default_terminal_output(terminal_output)
    else:
        tshift = afni.TShift(terminal_output=terminal_output).run
        clip_level = afni.ClipLevel().run
        volreg = afni.Volreg(terminal_output=terminal_output).run
        allineate = afni.Allineate(terminal_output=terminal_output).run
        allineate2 = afni.Allineate(terminal_output=terminal_output
                                    ).run  # TODO: remove after fixed bug
        tstat = afni.TStat(terminal_output=terminal_output).run
        compute_mask = ComputeMask().run
        calc = afni.Calc(terminal_output=terminal_output).run
        unifize = afni.Unifize(terminal_output=terminal_output).run
        bias_correct = ants.N4BiasFieldCorrection(
            terminal_output=terminal_output).run
        catmatvec = afni.CatMatvec().run
        warp = afni.Warp().run
        resample = afni.Resample(terminal_output=terminal_output).run
        slicer = afni.ZCutUp(terminal_output=terminal_output).run
        warp_apply = afni.NwarpApply(terminal_output=terminal_output).run
        qwarp = afni.Qwarp(terminal_output=terminal_output).run
        merge = afni.Zcat(terminal_output=terminal_output).run
        copy_geom = fsl.CopyGeom(terminal_output=terminal_output).run
        overwrite = True

    session_data._check_inputs()
    output_dir = os.path.join(os.path.abspath(write_dir),
                              session_data.animal_id)
    session_data._set_output_dir_(output_dir)
    current_dir = os.getcwd()
    os.chdir(output_dir)
    output_files = []

    #######################################
    # Correct functional for slice timing #
    #######################################
    if slice_timing:
        out_tshift = tshift(in_file=func_filename,
                            outputtype='NIFTI_GZ',
                            tpattern='altplus',
                            tr=str(t_r),
                            environ=environ)
        func_filename = out_tshift.outputs.out_file
        output_files.append(func_filename)

    ################################################
    # Register functional volumes to the first one #
    ################################################
    # XXX why do you need a thresholded image ?
    out_clip_level = clip_level(in_file=func_filename)
    out_calc_threshold = calc(in_file_a=func_filename,
                              expr='ispositive(a-{0}) * a'.format(
                                  out_clip_level.outputs.clip_val),
                              outputtype='NIFTI_GZ')
    thresholded_filename = out_calc_threshold.outputs.out_file

    out_volreg = volreg(  # XXX dfile not saved
        in_file=thresholded_filename,
        outputtype='NIFTI_GZ',
        environ=environ,
        oned_file=fname_presuffix(thresholded_filename,
                                  suffix='Vr.1Dfile.1D',
                                  use_ext=False),
        oned_matrix_save=fname_presuffix(thresholded_filename,
                                         suffix='Vr.aff12.1D',
                                         use_ext=False))

    # Apply the registration to the whole head
    out_allineate = allineate(in_file=func_filename,
                              master=func_filename,
                              in_matrix=out_volreg.outputs.oned_matrix_save,
                              out_file=fname_presuffix(func_filename,
                                                       suffix='Av'),
                              environ=environ)

    # 3dAllineate removes the obliquity. This is not a good way to readd it as
    # removes motion correction info in the header if it were an AFNI file...as
    # it happens it's NIfTI which does not store that so irrelevant!
    out_copy_geom = copy_geom(dest_file=out_allineate.outputs.out_file,
                              in_file=out_volreg.outputs.out_file)

    allineated_filename = out_copy_geom.outputs.out_file

    # Create a (hopefully) nice mean image for use in the registration
    out_tstat = tstat(in_file=allineated_filename,
                      args='-mean',
                      outputtype='NIFTI_GZ',
                      environ=environ)

    # Update outputs
    output_files.extend([
        thresholded_filename, out_volreg.outputs.oned_matrix_save,
        out_volreg.outputs.out_file, out_volreg.outputs.md1d_file,
        allineated_filename, out_tstat.outputs.out_file
    ])

    ###########################################
    # Corret anat and func for intensity bias #
    ###########################################
    # Correct the functional average for intensities bias
    out_bias_correct = bias_correct(input_image=out_tstat.outputs.out_file)
    unbiased_func_filename = out_bias_correct.outputs.output_image

    # Bias correct the antomical image
    out_unifize = unifize(in_file=anat_filename,
                          outputtype='NIFTI_GZ',
                          environ=environ)
    unbiased_anat_filename = out_unifize.outputs.out_file

    # Update outputs
    output_files.extend([unbiased_func_filename, unbiased_anat_filename])

    #############################################
    # Rigid-body registration anat -> mean func #
    #############################################
    if prior_rigid_body_registration:
        # Mask the mean functional volume outside the brain.
        out_clip_level = clip_level(in_file=unbiased_func_filename)
        out_compute_mask_func = compute_mask(
            in_file=unbiased_func_filename,
            volume_threshold=brain_volume,
            intensity_threshold=int(out_clip_level.outputs.clip_val))
        out_cacl_func = calc(in_file_a=unbiased_func_filename,
                             in_file_b=out_compute_mask_func.outputs.out_file,
                             expr='a*b',
                             outputtype='NIFTI_GZ',
                             environ=environ)

        # Mask the anatomical volume outside the brain.
        out_clip_level = clip_level(in_file=unbiased_anat_filename)
        out_compute_mask_anat = compute_mask(
            in_file=unbiased_anat_filename,
            volume_threshold=brain_volume,
            intensity_threshold=int(out_clip_level.outputs.clip_val))
        out_cacl_anat = calc(in_file_a=unbiased_anat_filename,
                             in_file_b=out_compute_mask_anat.outputs.out_file,
                             expr='a*b',
                             outputtype='NIFTI_GZ',
                             environ=environ)

        # Compute the transformation from functional to anatomical brain
        # XXX: why in this sense
        out_allineate = allineate2(
            in_file=out_cacl_func.outputs.out_file,
            reference=out_cacl_anat.outputs.out_file,
            out_matrix=fname_presuffix(out_cacl_func.outputs.out_file,
                                       suffix='_shr.aff12.1D',
                                       use_ext=False),
            center_of_mass='',
            warp_type='shift_rotate',
            out_file=fname_presuffix(out_cacl_func.outputs.out_file,
                                     suffix='_shr'),
            environ=environ)
        rigid_transform_file = out_allineate.outputs.out_matrix
        output_files.extend([
            out_compute_mask_func.outputs.out_file,
            out_cacl_func.outputs.out_file,
            out_compute_mask_anat.outputs.out_file,
            out_cacl_anat.outputs.out_file, rigid_transform_file,
            out_allineate.outputs.out_file
        ])

        # apply the inverse transform to register the anatomical to the func
        catmatvec_out_file = fname_presuffix(rigid_transform_file,
                                             suffix='INV')
        out_catmatvec = catmatvec(in_file=[(rigid_transform_file, 'I')],
                                  oneline=True,
                                  out_file=catmatvec_out_file)
        output_files.append(out_catmatvec.outputs.out_file)
        out_allineate = allineate(in_file=unbiased_anat_filename,
                                  master=unbiased_func_filename,
                                  in_matrix=out_catmatvec.outputs.out_file,
                                  out_file=fname_presuffix(
                                      unbiased_anat_filename,
                                      suffix='_shr_in_func_space'),
                                  environ=environ)
        allineated_anat_filename = out_allineate.outputs.out_file
        output_files.append(allineated_anat_filename)
    else:
        allineated_anat_filename = unbiased_anat_filename

    ############################################
    # Nonlinear registration anat -> mean func #
    ############################################
    # 3dWarp doesn't put the obliquity in the header, so do it manually
    # This step generates one file per slice and per time point, so we are
    # making sure they are removed at the end
    out_warp = warp(in_file=allineated_anat_filename,
                    oblique_parent=unbiased_func_filename,
                    interp='quintic',
                    gridset=unbiased_func_filename,
                    outputtype='NIFTI_GZ',
                    verbose=True,
                    environ=environ)
    registered_anat_filename = out_warp.outputs.out_file
    registered_anat_oblique_filename = fix_obliquity(registered_anat_filename,
                                                     unbiased_func_filename,
                                                     verbose=verbose)

    # Concatenate all the anat to func tranforms
    mat_filename = fname_presuffix(registered_anat_filename,
                                   suffix='_warp.mat',
                                   use_ext=False)
    # XXX Handle this correctly according to caching
    if not os.path.isfile(mat_filename):
        np.savetxt(mat_filename, [out_warp.runtime.stdout], fmt='%s')
        output_files.append(mat_filename)

    transform_filename = fname_presuffix(registered_anat_filename,
                                         suffix='_anat_to_func.aff12.1D',
                                         use_ext=False)
    if prior_rigid_body_registration:
        _ = catmatvec(in_file=[(mat_filename, 'ONELINE'),
                               (rigid_transform_file, 'ONELINE')],
                      oneline=True,
                      out_file=transform_filename)
    else:
        _ = catmatvec(in_file=[(mat_filename, 'ONELINE')],
                      oneline=True,
                      out_file=transform_filename)

    ##################################################
    # Per-slice non-linear registration func -> anat #
    ##################################################
    # Slice anatomical image
    anat_img = nibabel.load(registered_anat_oblique_filename)
    anat_n_slices = anat_img.header.get_data_shape()[2]
    sliced_registered_anat_filenames = []
    for slice_n in range(anat_n_slices):
        out_slicer = slicer(in_file=registered_anat_oblique_filename,
                            keep='{0} {0}'.format(slice_n),
                            out_file=fname_presuffix(
                                registered_anat_oblique_filename,
                                suffix='Sl%d' % slice_n),
                            environ=environ)
        oblique_slice = fix_obliquity(out_slicer.outputs.out_file,
                                      registered_anat_oblique_filename,
                                      verbose=verbose)
        sliced_registered_anat_filenames.append(oblique_slice)

    # Slice mean functional
    sliced_bias_corrected_filenames = []
    img = nibabel.load(func_filename)
    n_slices = img.header.get_data_shape()[2]
    for slice_n in range(n_slices):
        out_slicer = slicer(in_file=unbiased_func_filename,
                            keep='{0} {0}'.format(slice_n),
                            out_file=fname_presuffix(unbiased_func_filename,
                                                     suffix='Sl%d' % slice_n),
                            environ=environ)
        oblique_slice = fix_obliquity(out_slicer.outputs.out_file,
                                      unbiased_func_filename,
                                      verbose=verbose)
        sliced_bias_corrected_filenames.append(oblique_slice)

    # Below line is to deal with slices where there is no signal (for example
    # rostral end of some anatomicals)

    # The inverse warp frequently fails, Resampling can help it work better
    # XXX why specifically .1 in voxel_size ?
    voxel_size_z = anat_img.header.get_zooms()[2]
    resampled_registered_anat_filenames = []
    for sliced_registered_anat_filename in sliced_registered_anat_filenames:
        out_resample = resample(in_file=sliced_registered_anat_filename,
                                voxel_size=(voxel_size_x, voxel_size_y,
                                            voxel_size_z),
                                outputtype='NIFTI_GZ',
                                environ=environ)
        resampled_registered_anat_filenames.append(
            out_resample.outputs.out_file)

    resampled_bias_corrected_filenames = []
    for sliced_bias_corrected_filename in sliced_bias_corrected_filenames:
        out_resample = resample(in_file=sliced_bias_corrected_filename,
                                voxel_size=(voxel_size_x, voxel_size_y,
                                            voxel_size_z),
                                outputtype='NIFTI_GZ',
                                environ=environ)
        resampled_bias_corrected_filenames.append(
            out_resample.outputs.out_file)

    # single slice non-linear functional to anatomical registration
    warped_slices = []
    warp_filenames = []
    for (resampled_bias_corrected_filename,
         resampled_registered_anat_filename) in zip(
             resampled_bias_corrected_filenames,
             resampled_registered_anat_filenames):
        warped_slice = fname_presuffix(resampled_bias_corrected_filename,
                                       suffix='_qw')
        out_qwarp = qwarp(
            in_file=resampled_bias_corrected_filename,
            base_file=resampled_registered_anat_filename,
            iwarp=True,  # XXX: is this necessary
            noneg=True,
            blur=[0],
            nmi=True,
            noXdis=True,
            allineate=True,
            allineate_opts='-parfix 1 0 -parfix 2 0 -parfix 3 0 '
            '-parfix 4 0 -parfix 5 0 -parfix 6 0 '
            '-parfix 7 0 -parfix 9 0 '
            '-parfix 10 0 -parfix 12 0',
            out_file=warped_slice,
            environ=environ)
        warped_slices.append(out_qwarp.outputs.warped_source)
        warp_filenames.append(out_qwarp.outputs.source_warp)
        output_files.append(out_qwarp.outputs.base_warp)
        # There are files geenrated by the allineate option
        output_files.extend([
            fname_presuffix(out_qwarp.outputs.warped_source, suffix='_Allin'),
            fname_presuffix(out_qwarp.outputs.warped_source,
                            suffix='_Allin.nii',
                            use_ext=False),
            fname_presuffix(out_qwarp.outputs.warped_source,
                            suffix='_Allin.aff12.1D',
                            use_ext=False)
        ])

    # Resample the mean volume back to the initial resolution,
    voxel_size = nibabel.load(unbiased_func_filename).header.get_zooms()
    resampled_warped_slices = []
    for warped_slice in warped_slices:
        out_resample = resample(in_file=warped_slice,
                                voxel_size=voxel_size,
                                outputtype='NIFTI_GZ',
                                environ=environ)
        resampled_warped_slices.append(out_resample.outputs.out_file)

    # fix the obliquity
    resampled_warped_slices_oblique = []
    for (sliced_registered_anat_filename,
         resampled_warped_slice) in zip(sliced_registered_anat_filenames,
                                        resampled_warped_slices):
        oblique_slice = fix_obliquity(resampled_warped_slice,
                                      sliced_registered_anat_filename,
                                      verbose=verbose)
        resampled_warped_slices_oblique.append(oblique_slice)

    # slice functional
    sliced_func_filenames = []
    for slice_n in range(n_slices):
        out_slicer = slicer(in_file=allineated_filename,
                            keep='{0} {0}'.format(slice_n),
                            out_file=fname_presuffix(allineated_filename,
                                                     suffix='Sl%d' % slice_n),
                            environ=environ)
        oblique_slice = fix_obliquity(out_slicer.outputs.out_file,
                                      allineated_filename,
                                      verbose=verbose)
        sliced_func_filenames.append(oblique_slice)

    # Apply the precomputed warp slice by slice
    warped_func_slices = []
    for (sliced_func_filename, warp_filename) in zip(sliced_func_filenames,
                                                     warp_filenames):
        out_warp_apply = warp_apply(in_file=sliced_func_filename,
                                    master=sliced_func_filename,
                                    warp=warp_filename,
                                    out_file=fname_presuffix(
                                        sliced_func_filename, suffix='_qw'),
                                    environ=environ)
        warped_func_slices.append(out_warp_apply.outputs.out_file)

    # Finally, merge all slices !
    out_merge_func = merge(in_files=warped_func_slices,
                           outputtype='NIFTI_GZ',
                           environ=environ)

    # Fix the obliquity
    merged_oblique = fix_obliquity(out_merge_func.outputs.out_file,
                                   allineated_filename,
                                   verbose=verbose)

    # Update the fmri data
    setattr(session_data, "coreg_func_", merged_oblique)
    setattr(session_data, "coreg_anat_", registered_anat_oblique_filename)
    setattr(session_data, "coreg_transform_", transform_filename)
    os.chdir(current_dir)

    # Collect the outputs
    output_files.extend(sliced_registered_anat_filenames +
                        sliced_bias_corrected_filenames +
                        resampled_registered_anat_filenames +
                        resampled_bias_corrected_filenames + warped_slices +
                        warp_filenames + resampled_warped_slices_oblique +
                        sliced_func_filenames + warped_func_slices)
    if not caching:
        for out_file in output_files:
            if os.path.isfile(out_file):
                os.remove(out_file)
Ejemplo n.º 16
0
    def __init__(self,settings):
        # call base constructor
        super().__init__(settings)

        # check files being processed
        check_query(settings['bids_query'],settings['bids_dir'])

        # define output node
        self.set_input(['subject'])
        self.set_output(['anat','func','subject'])

        # define datasink substitutions
        self.set_resubs([
            ('_alignanattoanat\d{1,3}',''),
            ('bidsselector/sub-(?P<subject>\w+)_','bidsselector/sub-\g<subject>/sub-\g<subject>_') # put raw files under subject
        ])

        # parametrize subject for multiple subject processing
        self.inputnode.iterables = ('subject',settings['subject'])

        # Get BIDs dataset and organize data for input
        self.bidsselection = Node(
            BIDSDataGrabber(
                base_dir=settings['bids_dir'],
                output_query=settings['bids_query']
            ),
            name='bidsselection'
        )

        # select anat to align to
        self.selectanat = Node(
            Function(
                input_names=['anat','refnum'],
                output_names=['anat_reference','anat_align'],
                function=lambda anat,refnum: (anat[refnum],[img for idx,img in enumerate(anat) if idx!=refnum])
            ),
            name='selectanat'
        )
        self.selectanat.inputs.refnum = settings['anat_reference']

        # create node for aligning multiple T1 images to T1 reference
        self.alignanattoanat = MapNode(
            afni.Allineate(
                outputtype='NIFTI_GZ',
            ),
            iterfield=['in_file'],
            name='alignanattoanat'
        )

        # merge anats into single list
        self.mergeanatlist = Node(
            Merge(
                numinputs=2,
                ravel_inputs=True
            ),
            name='mergeanatlist'
        )

        # avg all anats
        self.avganat = Node(
            Function(
                input_names=['anat_list'],
                output_names=['avg_anat'],
                function=avganats
            ),
            name='avganat'
        )
Ejemplo n.º 17
0
def _func_to_template(func_coreg_filename,
                      template_filename,
                      write_dir,
                      func_to_anat_oned_filename,
                      anat_to_template_oned_filename,
                      anat_to_template_warp_filename,
                      voxel_size=None,
                      caching=False,
                      verbose=True):
    """ Applies successive transforms to coregistered functional to put it in
    template space.

    Parameters
    ----------
    coreg_func_filename : str
        Path to functional volume, coregistered to a common space with the
        anatomical volume.

    template_filename : str
        Template to register the functional to.

    func_to_anat_oned_filename : str
        Path to the affine 1D transform from functional to coregistration
        space.

    anat_to_template_oned_filename : str
        Path to the affine 1D transform from anatomical to template space.

    anat_to_template_warp_filename : str
        Path to the warp transform from anatomical to template space.

    voxel_size : 3-tuple of floats, optional
        Voxel size of the registered functional, in mm.

    caching : bool, optional
        Wether or not to use caching.

    verbose : bool, optional
        If True, all steps are verbose. Note that caching implies some
        verbosity in any case.
    """
    environ = {}
    if verbose:
        terminal_output = 'allatonce'
    else:
        terminal_output = 'none'

    if caching:
        memory = Memory(write_dir)
        resample = memory.cache(afni.Resample)
        catmatvec = memory.cache(afni.CatMatvec)
        allineate = memory.cache(afni.Allineate)
        warp_apply = memory.cache(afni.NwarpApply)
        for step in [resample, allineate, warp_apply]:
            step.interface().set_default_terminal_output(terminal_output)
    else:
        resample = afni.Resample(terminal_output=terminal_output).run
        catmatvec = afni.CatMatvec().run
        allineate = afni.Allineate(terminal_output=terminal_output).run
        warp_apply = afni.NwarpApply(terminal_output=terminal_output).run
        environ['AFNI_DECONFLICT'] = 'OVERWRITE'

    current_dir = os.getcwd()
    os.chdir(write_dir)  # XXX to remove
    normalized_filename = fname_presuffix(func_coreg_filename,
                                          suffix='_normalized')
    if voxel_size is None:
        func_template_filename = template_filename
    else:
        out_resample = resample(in_file=template_filename,
                                voxel_size=voxel_size,
                                outputtype='NIFTI_GZ',
                                environ=environ)
        func_template_filename = out_resample.outputs.out_file

    if anat_to_template_warp_filename is None:
        affine_transform_filename = fname_presuffix(func_to_anat_oned_filename,
                                                    suffix='_to_template')
        _ = catmatvec(in_file=[(anat_to_template_oned_filename, 'ONELINE'),
                               (func_to_anat_oned_filename, 'ONELINE')],
                      oneline=True,
                      out_file=affine_transform_filename,
                      environ=environ)
        _ = allineate(in_file=func_coreg_filename,
                      master=func_template_filename,
                      in_matrix=affine_transform_filename,
                      out_file=normalized_filename,
                      environ=environ)
    else:
        warp = "'{0} {1} {2}'".format(anat_to_template_warp_filename,
                                      anat_to_template_oned_filename,
                                      func_to_anat_oned_filename)

        _ = warp_apply(in_file=func_coreg_filename,
                       master=func_template_filename,
                       warp=warp,
                       out_file=normalized_filename,
                       environ=environ)
    os.chdir(current_dir)
    return normalized_filename
Ejemplo n.º 18
0
def _create_split_hemi_pipe(params, params_template, name="split_hemi_pipe"):
    """Description: Split segmentated tissus according hemisheres after \
    removal of cortical structure

    Processing steps:

    - TODO

    Params:

        - None so far

    Inputs:

        inputnode:

            warpinv_file:
                non-linear transformation (from NMT_subject_align)

            inv_transfo_file:
                inverse transformation

            aff_file:
                affine transformation file

            t1_ref_file:
                preprocessd T1

            segmented_file:
                from atropos segmentation, with all the tissues segmented

        arguments:

            params:
                dictionary of node sub-parameters (from a json file)

            name:
                pipeline name (default = "split_hemi_pipe")

    Outputs:
    """
    split_hemi_pipe = pe.Workflow(name=name)

    # creating inputnode
    inputnode = pe.Node(niu.IdentityInterface(fields=[
        'warpinv_file', 'inv_transfo_file', 'aff_file', 't1_ref_file',
        'segmented_file'
    ]),
                        name='inputnode')

    # get values

    if "cereb_template" in params_template.keys():
        cereb_template_file = params_template["cereb_template"]

        # ### cereb
        # Binarize cerebellum
        bin_cereb = pe.Node(interface=fsl.UnaryMaths(), name='bin_cereb')
        bin_cereb.inputs.operation = "bin"

        bin_cereb.inputs.in_file = cereb_template_file

        # Warp cereb brainmask to subject space
        warp_cereb = pe.Node(interface=reg.NwarpApplyPriors(),
                             name='warp_cereb')

        warp_cereb.inputs.in_file = cereb_template_file
        warp_cereb.inputs.out_file = cereb_template_file
        warp_cereb.inputs.interp = "NN"
        warp_cereb.inputs.args = "-overwrite"

        split_hemi_pipe.connect(bin_cereb, 'out_file', warp_cereb, 'in_file')
        split_hemi_pipe.connect(inputnode, 'aff_file', warp_cereb, 'master')
        split_hemi_pipe.connect(inputnode, 'warpinv_file', warp_cereb, "warp")

        # Align cereb template
        align_cereb = pe.Node(interface=afni.Allineate(), name='align_cereb')

        align_cereb.inputs.final_interpolation = "nearestneighbour"
        align_cereb.inputs.overwrite = True
        align_cereb.inputs.outputtype = "NIFTI_GZ"

        split_hemi_pipe.connect(warp_cereb, 'out_file', align_cereb,
                                "in_file")  # -source
        split_hemi_pipe.connect(inputnode, 't1_ref_file', align_cereb,
                                "reference")  # -base
        split_hemi_pipe.connect(inputnode, 'inv_transfo_file', align_cereb,
                                "in_matrix")  # -1Dmatrix_apply

    if "L_hemi_template" in params_template.keys() and \
            "R_hemi_template" in params_template.keys():

        L_hemi_template_file = params_template["L_hemi_template"]
        R_hemi_template_file = params_template["R_hemi_template"]

        # Warp L hemi template brainmask to subject space
        warp_L_hemi = pe.Node(interface=reg.NwarpApplyPriors(),
                              name='warp_L_hemi')

        warp_L_hemi.inputs.in_file = L_hemi_template_file
        warp_L_hemi.inputs.out_file = L_hemi_template_file
        warp_L_hemi.inputs.interp = "NN"
        warp_L_hemi.inputs.args = "-overwrite"

        split_hemi_pipe.connect(inputnode, 'aff_file', warp_L_hemi, 'master')
        split_hemi_pipe.connect(inputnode, 'warpinv_file', warp_L_hemi, "warp")

        # Align L hemi template
        align_L_hemi = pe.Node(interface=afni.Allineate(), name='align_L_hemi')

        align_L_hemi.inputs.final_interpolation = "nearestneighbour"
        align_L_hemi.inputs.overwrite = True
        align_L_hemi.inputs.outputtype = "NIFTI_GZ"

        split_hemi_pipe.connect(warp_L_hemi, 'out_file', align_L_hemi,
                                "in_file")  # -source
        split_hemi_pipe.connect(inputnode, 't1_ref_file', align_L_hemi,
                                "reference")  # -base
        split_hemi_pipe.connect(inputnode, 'inv_transfo_file', align_L_hemi,
                                "in_matrix")  # -1Dmatrix_apply

        # Warp R hemi template brainmask to subject space
        warp_R_hemi = pe.Node(interface=reg.NwarpApplyPriors(),
                              name='warp_R_hemi')

        warp_R_hemi.inputs.in_file = R_hemi_template_file
        warp_R_hemi.inputs.out_file = R_hemi_template_file
        warp_R_hemi.inputs.interp = "NN"
        warp_R_hemi.inputs.args = "-overwrite"

        split_hemi_pipe.connect(inputnode, 'aff_file', warp_R_hemi, 'master')
        split_hemi_pipe.connect(inputnode, 'warpinv_file', warp_R_hemi, "warp")

        # Align R hemi template
        align_R_hemi = pe.Node(interface=afni.Allineate(), name='align_R_hemi')

        align_R_hemi.inputs.final_interpolation = "nearestneighbour"
        align_R_hemi.inputs.overwrite = True
        align_R_hemi.inputs.outputtype = "NIFTI_GZ"

        split_hemi_pipe.connect(warp_R_hemi, 'out_file', align_R_hemi,
                                "in_file")  # -source
        split_hemi_pipe.connect(inputnode, 't1_ref_file', align_R_hemi,
                                "reference")  # -base
        split_hemi_pipe.connect(inputnode, 'inv_transfo_file', align_R_hemi,
                                "in_matrix")  # -1Dmatrix_apply

    elif "LR_hemi_template" in params_template.keys():

        LR_hemi_template_file = params_template["LR_hemi_template"]

        # Warp LR hemi template brainmask to subject space
        warp_LR_hemi = pe.Node(interface=reg.NwarpApplyPriors(),
                               name='warp_LR_hemi')

        warp_LR_hemi.inputs.in_file = LR_hemi_template_file
        warp_LR_hemi.inputs.out_file = LR_hemi_template_file
        warp_LR_hemi.inputs.interp = "NN"
        warp_LR_hemi.inputs.args = "-overwrite"

        split_hemi_pipe.connect(inputnode, 'aff_file', warp_LR_hemi, 'master')
        split_hemi_pipe.connect(inputnode, 'warpinv_file', warp_LR_hemi,
                                "warp")

        # Align LR hemi template
        align_LR_hemi = pe.Node(interface=afni.Allineate(),
                                name='align_LR_hemi')

        align_LR_hemi.inputs.final_interpolation = "nearestneighbour"
        align_LR_hemi.inputs.overwrite = True
        align_LR_hemi.inputs.outputtype = "NIFTI_GZ"

        split_hemi_pipe.connect(warp_LR_hemi, 'out_file', align_LR_hemi,
                                "in_file")  # -source
        split_hemi_pipe.connect(inputnode, 't1_ref_file', align_LR_hemi,
                                "reference")  # -base
        split_hemi_pipe.connect(inputnode, 'inv_transfo_file', align_LR_hemi,
                                "in_matrix")  # -1Dmatrix_apply

        split_LR = pe.Node(interface=niu.Function(
            input_names=["LR_mask_file"],
            output_names=["L_mask_file", "R_mask_file"],
            function=split_LR_mask),
                           name="split_LR")

        split_hemi_pipe.connect(align_LR_hemi, "out_file", split_LR,
                                'LR_mask_file')

    else:
        print("Error, could not find LR_hemi_template or L_hemi_template and \
            R_hemi_template, skipping")
        print(params_template.keys())

        exit()

    # Using LH and RH masks to obtain hemisphere segmentation masks
    calc_L_hemi = pe.Node(interface=afni.Calc(), name='calc_L_hemi')
    calc_L_hemi.inputs.expr = 'a*b/b'
    calc_L_hemi.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(inputnode, 'segmented_file', calc_L_hemi,
                            "in_file_a")

    if "LR_hemi_template" in params_template.keys():
        split_hemi_pipe.connect(split_LR, 'L_mask_file', calc_L_hemi,
                                "in_file_b")
    else:
        split_hemi_pipe.connect(align_L_hemi, 'out_file', calc_L_hemi,
                                "in_file_b")

    # R_hemi
    calc_R_hemi = pe.Node(interface=afni.Calc(), name='calc_R_hemi')
    calc_R_hemi.inputs.expr = 'a*b/b'
    calc_R_hemi.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(inputnode, 'segmented_file', calc_R_hemi,
                            "in_file_a")

    if "LR_hemi_template" in params_template.keys():

        split_hemi_pipe.connect(split_LR, 'R_mask_file', calc_R_hemi,
                                "in_file_b")
    else:
        split_hemi_pipe.connect(align_R_hemi, 'out_file', calc_R_hemi,
                                "in_file_b")

    # remove cerebellum from left and right brain segmentations
    calc_nocb_L_hemi = pe.Node(interface=afni.Calc(), name='calc_nocb_L_hemi')
    calc_nocb_L_hemi.inputs.expr = '(a*(not (b)))'
    calc_nocb_L_hemi.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(calc_L_hemi, 'out_file', calc_nocb_L_hemi,
                            "in_file_a")
    split_hemi_pipe.connect(align_cereb, 'out_file', calc_nocb_L_hemi,
                            "in_file_b")

    calc_nocb_R_hemi = pe.Node(interface=afni.Calc(), name='calc_nocb_R_hemi')
    calc_nocb_R_hemi.inputs.expr = '(a*(not (b)))'
    calc_nocb_R_hemi.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(calc_R_hemi, 'out_file', calc_nocb_R_hemi,
                            "in_file_a")
    split_hemi_pipe.connect(align_cereb, 'out_file', calc_nocb_R_hemi,
                            "in_file_b")

    # create L/R GM and WM no-cerebellum masks from subject brain segmentation
    calc_GM_nocb_L_hemi = pe.Node(interface=afni.Calc(),
                                  name='calc_GM_nocb_L_hemi')
    calc_GM_nocb_L_hemi.inputs.expr = 'iszero(a-2)'
    calc_GM_nocb_L_hemi.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(calc_nocb_L_hemi, 'out_file', calc_GM_nocb_L_hemi,
                            "in_file_a")

    calc_WM_nocb_L_hemi = pe.Node(interface=afni.Calc(),
                                  name='calc_WM_nocb_L_hemi')
    calc_WM_nocb_L_hemi.inputs.expr = 'iszero(a-3)'
    calc_WM_nocb_L_hemi.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(calc_nocb_L_hemi, 'out_file', calc_WM_nocb_L_hemi,
                            "in_file_a")

    calc_GM_nocb_R_hemi = pe.Node(interface=afni.Calc(),
                                  name='calc_GM_nocb_R_hemi')
    calc_GM_nocb_R_hemi.inputs.expr = 'iszero(a-2)'
    calc_GM_nocb_R_hemi.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(calc_nocb_R_hemi, 'out_file', calc_GM_nocb_R_hemi,
                            "in_file_a")

    calc_WM_nocb_R_hemi = pe.Node(interface=afni.Calc(),
                                  name='calc_WM_nocb_R_hemi')
    calc_WM_nocb_R_hemi.inputs.expr = 'iszero(a-3)'
    calc_WM_nocb_R_hemi.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(calc_nocb_R_hemi, 'out_file', calc_WM_nocb_R_hemi,
                            "in_file_a")

    # Extract Cerebellum using template mask transformed to subject space
    extract_cereb = pe.Node(interface=afni.Calc(), name='extract_cereb')
    extract_cereb.inputs.expr = 'a*b/b'
    extract_cereb.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_cereb,
                            "in_file_a")
    split_hemi_pipe.connect(align_cereb, 'out_file', extract_cereb,
                            "in_file_b")

    # Extract L.GM using template mask transformed to subject space
    extract_L_GM = pe.Node(interface=afni.Calc(), name='extract_L_GM')
    extract_L_GM.inputs.expr = 'a*b/b'
    extract_L_GM.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_L_GM,
                            "in_file_a")
    split_hemi_pipe.connect(calc_GM_nocb_L_hemi, 'out_file', extract_L_GM,
                            "in_file_b")

    # Extract L.WM using template mask transformed to subject space
    extract_L_WM = pe.Node(interface=afni.Calc(), name='extract_L_WM')
    extract_L_WM.inputs.expr = 'a*b/b'
    extract_L_WM.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_L_WM,
                            "in_file_a")
    split_hemi_pipe.connect(calc_WM_nocb_L_hemi, 'out_file', extract_L_WM,
                            "in_file_b")

    # Extract L.GM using template mask transformed to subject space
    extract_R_GM = pe.Node(interface=afni.Calc(), name='extract_R_GM')
    extract_R_GM.inputs.expr = 'a*b/b'
    extract_R_GM.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_R_GM,
                            "in_file_a")
    split_hemi_pipe.connect(calc_GM_nocb_R_hemi, 'out_file', extract_R_GM,
                            "in_file_b")

    # Extract L.WM using template mask transformed to subject space
    extract_R_WM = pe.Node(interface=afni.Calc(), name='extract_R_WM')
    extract_R_WM.inputs.expr = 'a*b/b'
    extract_R_WM.inputs.outputtype = 'NIFTI_GZ'

    split_hemi_pipe.connect(inputnode, 't1_ref_file', extract_R_WM,
                            "in_file_a")
    split_hemi_pipe.connect(calc_WM_nocb_R_hemi, 'out_file', extract_R_WM,
                            "in_file_b")

    return split_hemi_pipe
Ejemplo n.º 19
0
def create_preprocess_phase_wf():
    """Create's phase preprocessing workflow with the following steps:

    1) Convert data to float
    2) Determine scaling required for radians
    3) Apply radian scaling
    4) Convert to real and imaginary
    5) Apply magnitude motion correction parameters
    6) Correct geometry changes (AFNI issue)
    7) Convert back to phase
    8) Unwrap and detrend data
    9) Mask data using magnitude mask
    10) Calculate noise from data

    """
    preprocphase = pe.Workflow(name="preprocphase")
    preprocphase.config['execution']['remove_unnecessary_outputs'] = False

    # define inputs
    inputspec = pe.Node(
        ul.IdentityInterface(fields=[
            'input_phase',  # raw phase data
            'input_mag',  # raw mag data
            'motion_par',  # afni transform concatenated from magnitude data
            'mask_file',  # bet mask from magnitude data
            'rest',  # volumes of rest in block design
            'task',  # volumes of task in block design
        ]),
        name='inputspec')

    # 1) Convert data to float
    img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float',
                                                    op_string='',
                                                    suffix='_dtype'),
                           iterfield=['in_file'],
                           name='img2float')

    # 2) Determine radian scaling required
    findscaling = pe.MapNode(interface=ul.Function(
        input_names=['in_file'],
        output_names=['scaling_arg'],
        function=findscalingarg),
                             name='findscaling',
                             iterfield=['in_file'])

    # 3) Apply radian scaling
    convert2rad = pe.MapNode(interface=fsl.maths.MathsCommand(),
                             name='convert2rad',
                             iterfield=['in_file', 'args'])

    # 4) Convert to real and imaginary (2 step process)
    makecomplex = pe.MapNode(interface=fsl.Complex(complex_polar=True),
                             name='makecomplex',
                             iterfield=['magnitude_in_file', 'phase_in_file'])

    splitcomplex = pe.MapNode(interface=fsl.Complex(real_cartesian=True),
                              name='splitcomplex',
                              iterfield=['complex_in_file'])

    # 5) Apply magnitude motion correction parameters
    mocoreal = pe.MapNode(interface=afni.Allineate(),
                          name='mocoreal',
                          iterfield=['in_file', 'in_matrix'])
    mocoreal.inputs.outputtype = 'NIFTI_GZ'
    mocoreal.inputs.out_file = 'mocophase.nii.gz'
    mocoreal.inputs.num_threads = 2
    mocoimag = mocoreal.clone('mocoimag')

    # 6) Correct geometry changes (AFNI issue)
    cpgeommocoreal = pe.MapNode(interface=fsl.CopyGeom(),
                                name='cpgeommoco',
                                iterfield=['dest_file', 'in_file'])
    cpgeommocoimag = cpgeommocoreal.clone('cpgeommocoimag')
    cpgeommocophase = cpgeommocoreal.clone('cpgeommocophase')

    # 7) Convert back to phase (2 step process)
    makecomplexmoco = pe.MapNode(
        interface=fsl.Complex(complex_cartesian=True),
        name='makecomplexmoco',
        iterfield=['real_in_file', 'imaginary_in_file'])

    splitcomplexmoco = pe.MapNode(interface=fsl.Complex(real_polar=True),
                                  name='splitcomplexmoco',
                                  iterfield=['complex_in_file'])

    # 8) Remove first volume, unwrap and detrend phase data
    prepphase = pe.MapNode(interface=pp.PreprocessPhase(),
                           name='prepphase',
                           iterfield=['phase'])

    # 9) Mask data using magnitude mask
    maskfunc = pe.MapNode(interface=fsl.ImageMaths(suffix='_bet',
                                                   op_string='-mas'),
                          iterfield=['in_file'],
                          name='maskfunc')
    # 10) Calculate noise from data
    calcSNR = pe.MapNode(interface=pp.RestAverage(),
                         name='calcSNR',
                         iterfield=['func', 'rest', 'task'])

    # outputspec
    outputspec = pe.Node(ul.IdentityInterface(
        fields=['proc_phase', 'uw_phase', 'delta_phase', 'std_phase']),
                         name='outputspec')

    preprocphase = pe.Workflow(name='preprocphase')
    preprocphase.connect([
        (inputspec, img2float, [('input_phase', 'in_file')]),  # 1
        (inputspec, findscaling, [('input_phase', 'in_file')]),  # 2
        (findscaling, convert2rad, [('scaling_arg', 'args')]),
        (img2float, convert2rad, [('out_file', 'in_file')]),
        (convert2rad, makecomplex, [('out_file', 'phase_in_file')]),  # 3
        (inputspec, makecomplex, [('input_mag', 'magnitude_in_file')]),
        (makecomplex, splitcomplex, [('complex_out_file', 'complex_in_file')
                                     ]),  # 4
        (inputspec, mocoreal, [('motion_par', 'in_matrix')]),  # 5 real
        (splitcomplex, mocoreal, [('real_out_file', 'in_file')]),
        (mocoreal, cpgeommocoreal, [('out_file', 'dest_file')]),  #6 real
        (img2float, cpgeommocoreal, [('out_file', 'in_file')]),
        (inputspec, mocoimag, [('motion_par', 'in_matrix')]),  # 5 imag
        (splitcomplex, mocoimag, [('imaginary_out_file', 'in_file')]),
        (mocoimag, cpgeommocoimag, [('out_file', 'dest_file')]),  # 6 imag
        (img2float, cpgeommocoimag, [('out_file', 'in_file')]),
        (cpgeommocoreal, makecomplexmoco, [('out_file', 'real_in_file')]),  # 7
        (cpgeommocoimag, makecomplexmoco, [('out_file', 'imaginary_in_file')]),
        (makecomplexmoco, splitcomplexmoco, [('complex_out_file',
                                              'complex_in_file')]),
        (splitcomplexmoco, cpgeommocophase, [('phase_out_file', 'dest_file')]),
        (img2float, cpgeommocophase, [('out_file', 'in_file')]),
        (cpgeommocophase, prepphase, [('out_file', 'phase')]),  # 8
        (prepphase, maskfunc, [('detrended_phase', 'in_file')]),  # 9
        (inputspec, maskfunc, [('mask_file', 'in_file2')]),
        (maskfunc, outputspec, [('out_file', 'proc_phase')]),
        (prepphase, outputspec, [('uw_phase', 'uw_phase')]),
        (prepphase, outputspec, [('delta_phase', 'delta_phase')]),
        (
            inputspec,
            calcSNR,
            [
                ('rest', 'rest'),  # 10
                ('task', 'task')
            ]),
        (prepphase, calcSNR, [('detrended_phase', 'func')]),
        (calcSNR, outputspec, [('noise', 'std_phase')])
    ])

    return preprocphase
Ejemplo n.º 20
0
def create_register_NMT_pipe(params_template, params={},
                             name="register_NMT_pipe", NMT_version="v1.3"):
    """Description: Register template to anat with the script NMT_subject_align

    Processing steps:

    - Bias correction (norm_intensity)
    - Deoblique (Refit with deoblique option)
    - NMT_subject_align (see :class:`NMTSubjectAlign \
    <macapype.nodes.register.NMTSubjectAlign>` and :class:`NMTSubjectAlign2 \
    <macapype.nodes.register.NMTSubjectAlign2>` for explanations)
    - apply it to tissues list_priors (NwarpApplyPriors and Allineate)

    Params:
        - norm_intensity (see `N4BiasFieldCorrection <https://\
        nipype.readthedocs.io/en/0.12.1/interfaces/generated/nipype.interfaces\
        .ants.segmentation.html#n4biasfieldcorrection>`_ for arguments)) - \
        also available as :ref:`indiv_params <indiv_params>`
        - NMT_version (default = 1.2; 1.3 is also accepted)

    Inputs:

        inputnode:

            T1:
                T1 file name

            indiv_params:
                dict with individuals parameters for some nodes

        arguments:

            params_template:
                dictionary of info about template

            params:
                dictionary of node sub-parameters (from a json file)

            name:
                pipeline name (default = "register_NMT_pipe")

            NMT_version:
                NMT version (default = 1.2); can be overwritten in params json

    Outputs:

        norm_intensity.output_image:
            filled mask after erode

        align_seg_csf.out_file:
            csf template tissue in subject space

        align_seg_gm.out_file:
            grey matter template tissue in subject space

        align_seg_wm.out_file:
            white matter template tissue in subject space
    """

    register_NMT_pipe = pe.Workflow(name=name)

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

    if "NMT_version" in params.keys():
        NMT_version = params['NMT_version']

        print("*** Overriding NMT_version with parmas {}".format(
            params['NMT_version']))

    # N4 intensity normalization over brain
    norm_intensity = NodeParams(ants.N4BiasFieldCorrection(),
                                params=parse_key(params, "norm_intensity"),
                                name='norm_intensity')

    register_NMT_pipe.connect(inputnode, 'T1',
                              norm_intensity, "input_image")

    register_NMT_pipe.connect(
        inputnode, ('indiv_params', parse_key, "norm_intensity"),
        norm_intensity, "indiv_params")

    deoblique = pe.Node(afni.Refit(deoblique=True), name="deoblique")
    register_NMT_pipe.connect(norm_intensity, 'output_image',
                              deoblique, "in_file")

    print("*** Found NMT_version {}".format(NMT_version))

    if NMT_version == "v1.2":
        # align subj to nmt
        NMT_subject_align = NodeParams(
            NMTSubjectAlign(), params=parse_key(params, "NMT_subject_align"),
            name='NMT_subject_align')

    elif NMT_version == "v1.3" or NMT_version == "v2.0":
        # align subj to nmt
        NMT_subject_align = NodeParams(
            NMTSubjectAlign2(), params=parse_key(params, "NMT_subject_align"),
            name='NMT_subject_align')

    else:
        print("NMT_version {} is not implemented".format(NMT_version))
        exit()

    NMT_subject_align.inputs.NMT_SS_file = params_template["template_brain"]

    register_NMT_pipe.connect(deoblique, 'out_file',
                              NMT_subject_align, "T1_file")

    if NMT_version.split(".")[0] == "v1":

        # align_masks
        # "overwrap" of NwarpApply, with specifying the outputs as wished
        list_priors = [params_template["template_head"],
                       params_template["template_csf"],
                       params_template["template_gm"],
                       params_template["template_wm"]]

    elif NMT_version.split(".")[0] == "v2":

        # align_masks
        # "overwrap" of NwarpApply, with specifying the outputs as wished
        list_priors = [params_template["template_head"],
                       params_template["template_seg"]]

    align_masks = pe.Node(NwarpApplyPriors(), name='align_masks')
    align_masks.inputs.in_file = list_priors
    align_masks.inputs.out_file = list_priors
    align_masks.inputs.interp = "NN"
    align_masks.inputs.args = "-overwrite"

    register_NMT_pipe.connect(NMT_subject_align, 'aff_file',
                              align_masks, 'master')
    register_NMT_pipe.connect(NMT_subject_align, 'warpinv_file',
                              align_masks, "warp")

    # align_NMT
    align_NMT = pe.Node(
        afni.Allineate(), name="align_NMT", iterfield=['in_file'])
    align_NMT.inputs.final_interpolation = "nearestneighbour"
    align_NMT.inputs.overwrite = True
    align_NMT.inputs.outputtype = "NIFTI_GZ"

    register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 0),
                              align_NMT, "in_file")  # -source
    register_NMT_pipe.connect(norm_intensity, 'output_image',
                              align_NMT, "reference")  # -base
    register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                              align_NMT, "in_matrix")  # -1Dmatrix_apply

    if NMT_version.split(".")[0] == "v1":

        # seg_csf
        align_seg_csf = pe.Node(
            afni.Allineate(), name="align_seg_csf", iterfield=['in_file'])
        align_seg_csf.inputs.final_interpolation = "nearestneighbour"
        align_seg_csf.inputs.overwrite = True
        align_seg_csf.inputs.outputtype = "NIFTI_GZ"

        register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 1),
                                  align_seg_csf, "in_file")  # -source
        register_NMT_pipe.connect(norm_intensity, 'output_image',
                                  align_seg_csf, "reference")  # -base
        register_NMT_pipe.connect(
            NMT_subject_align, 'inv_transfo_file', align_seg_csf,
            "in_matrix")  # -1Dmatrix_apply

        # seg_gm
        align_seg_gm = pe.Node(
            afni.Allineate(), name="align_seg_gm", iterfield=['in_file'])
        align_seg_gm.inputs.final_interpolation = "nearestneighbour"
        align_seg_gm.inputs.overwrite = True
        align_seg_gm.inputs.outputtype = "NIFTI_GZ"

        register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 2),
                                  align_seg_gm, "in_file")  # -source
        register_NMT_pipe.connect(norm_intensity, 'output_image',
                                  align_seg_gm, "reference")  # -base
        register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                                  align_seg_gm, "in_matrix")  # -1Dmatrix_apply

        # seg_wm
        align_seg_wm = pe.Node(afni.Allineate(), name="align_seg_wm",
                               iterfield=['in_file'])
        align_seg_wm.inputs.final_interpolation = "nearestneighbour"
        align_seg_wm.inputs.overwrite = True
        align_seg_wm.inputs.outputtype = "NIFTI_GZ"

        register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 3),
                                  align_seg_wm, "in_file")  # -source
        register_NMT_pipe.connect(norm_intensity, 'output_image',
                                  align_seg_wm, "reference")  # -base
        register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                                  align_seg_wm, "in_matrix")  # -1Dmatrix_apply

    elif NMT_version.split(".")[0] == "v2":

        # seg
        align_seg = pe.Node(
            afni.Allineate(), name="align_seg", iterfield=['in_file'])
        align_seg.inputs.final_interpolation = "nearestneighbour"
        align_seg.inputs.overwrite = True
        align_seg.inputs.outputtype = "NIFTI_GZ"

        register_NMT_pipe.connect(align_masks, ('out_file', get_elem, 1),
                                  align_seg, "in_file")  # -source
        register_NMT_pipe.connect(norm_intensity, 'output_image',
                                  align_seg, "reference")  # -base
        register_NMT_pipe.connect(NMT_subject_align, 'inv_transfo_file',
                                  align_seg, "in_matrix")  # -1Dmatrix_apply

    return register_NMT_pipe
def afni_anatomical_linear_registration(workflow, resource_pool, \
    config, name="_"):
    """Build Nipype workflow to calculate the linear registration (participant
    to template) of an anatomical image using AFNI's 3dAllineate.

    - If any resources/outputs required by this workflow are not in the
      resource pool, this workflow will call pre-requisite workflow builder
      functions to further populate the pipeline with workflows which will
      calculate/generate these necessary pre-requisites.

    Expected Settings in Configuration
      - skull_on_registration: (optional- default: True) Whether or not to
                               accept anatomical_reorient or anatomical_brain
                               as the input for registration.
      - template_head_for_anat: (for skull-on registration) The reference
                                template of the whole head.
      - template_brain_for_anat: (for skull-off registration) The reference
                                 template of the brain without skull.

    Expected Resources in Resource Pool
      - anatomical_reorient: The deobliqued, reoriented anatomical scan.
        OR
      - anatomical_brain: The skull-stripped anatomical image (brain only).

    New Resources Added to Resource Pool
      - afni_linear_warped_image: The anatomical image transformed to the
                                  template (using linear warps).
      - allineate_linear_xfm: The text file containing the linear warp matrix
                              produced by AFNI's 3dAllineate.

    Workflow Steps
      1. AFNI's 3dAllineate to calculate the linear registration.

    :type workflow: Nipype workflow object
    :param workflow: A Nipype workflow object which can already contain other
                     connected nodes; this function will insert the following
                     workflow into this one provided.
    :type resource_pool: dict
    :param resource_pool: A dictionary defining input files and pointers to
                          Nipype node outputs / workflow connections; the keys
                          are the resource names.
    :type config: dict
    :param config: A dictionary defining the configuration settings for the
                   workflow, such as directory paths or toggled options.
    :type name: str
    :param name: (default: "_") A string to append to the end of each node
                 name.
    :rtype: Nipype workflow object
    :return: The Nipype workflow originally provided, but with this function's
              sub-workflow connected into it.
    :rtype: dict
    :return: The resource pool originally provided, but updated (if
             applicable) with the newest outputs and connections.
    """

    import copy
    import nipype.pipeline.engine as pe
    import nipype.interfaces.afni as afni

    if "skull_on_registration" not in config.keys():
        config["skull_on_registration"] = True

    calc_allineate_warp = pe.Node(interface=afni.Allineate(),
                                    name='calc_3dAllineate_warp%s' % name)
    calc_allineate_warp.inputs.outputtype = "NIFTI_GZ"

    if config["skull_on_registration"]:

        if "anatomical_reorient" not in resource_pool.keys():

            from anatomical_preproc import anatomical_reorient_workflow
            old_rp = copy.copy(resource_pool)
            workflow, new_resource_pool = \
                anatomical_reorient_workflow(workflow, resource_pool,
                                             config, name)

            if resource_pool == old_rp:
                return workflow, resource_pool

        if len(resource_pool["anatomical_reorient"]) == 2:
            node, out_file = resource_pool["anatomical_reorient"]
            workflow.connect(node, out_file, calc_allineate_warp, 'in_file')
        else:
            calc_allineate_warp.inputs.in_file = \
                resource_pool["anatomical_reorient"]

        calc_allineate_warp.inputs.reference = \
            config["template_head_for_anat"]

        calc_allineate_warp.inputs.out_file = "allineate_warped_head.nii.gz"

    else:

        if "anatomical_brain" not in resource_pool.keys():

            from anatomical_preproc import anatomical_skullstrip_workflow
            old_rp = copy.copy(resource_pool)
            workflow, new_resource_pool = \
                anatomical_skullstrip_workflow(workflow, resource_pool, \
                                               config, name)

            if resource_pool == old_rp:
                return workflow, resource_pool

        if len(resource_pool["anatomical_brain"]) == 2:
            node, out_file = resource_pool["anatomical_brain"]
            workflow.connect(node, out_file, calc_allineate_warp, 'in_file')
        else:
            calc_allineate_warp.inputs.in_file = \
                resource_pool["anatomical_brain"]

        calc_allineate_warp.inputs.reference = \
            config["template_brain_for_anat"]

        calc_allineate_warp.inputs.out_file = \
            "allineate_warped_brain.nii.gz"

    calc_allineate_warp.inputs.out_matrix = "3dallineate_warp"

    resource_pool["allineate_linear_xfm"] = \
        (calc_allineate_warp, 'matrix')

    resource_pool["afni_linear_warped_image"] = \
        (calc_allineate_warp, 'out_file')

    return workflow, resource_pool
Ejemplo n.º 22
0
                                tv_scale=0.5,
                                save_data=False,
                                overwrite=False,
                                output_dir=False,
                                file_name=False)

    phase_array2[:, :, :, i] = temp_out["result"].get_fdata()

# save unwrapped time series
name_phase = name_phase + "_unwrap"
output = nb.Nifti1Image(phase_array2, magn_img.affine, magn_img.header)
nb.save(output, os.path.join(path_phase, name_phase + ext_phase))
"""
apply motion correction to unwrapped phase time series
"""
allineate = afni.Allineate()
allineate.inputs.in_file = os.path.join(path_phase, name_phase + ext_phase)
allineate.inputs.out_file = os.path.join(path_phase,
                                         "u" + name_phase + ext_phase)
allineate.inputs.in_matrix = os.path.join(path_moco, 'moco_matrix.1D')
allineate.inputs.outputtype = 'NIFTI'
allineate.inputs.final_interpolation = 'linear'
allineate.inputs.no_pad = True  # do not use zero-padding on the base image
allineate.run()
"""
set new basenames to target realigned and temporary timeseries
"""
name_magn = "u" + name_magn
name_phase = "u" + name_phase
name_magn_temp = name_magn + "_temp"
name_phase_temp = name_phase + "_temp"