예제 #1
0
def smoothIMG(input_file, outputPath):
    data = nii.load(input_file)

    vol = data.get_data()
    ImgSmooth = np.min(vol, 3)

    unscaledNiiData = nii.Nifti1Image(ImgSmooth, data.affine)
    hdrOut = unscaledNiiData.header
    hdrOut.set_xyzt_units('mm')
    output_file = os.path.join(
        os.path.dirname(input_file),
        os.path.basename(input_file).split('.')[0] + 'DN.nii.gz')
    # hdrOut['sform_code'] = 1
    nii.save(unscaledNiiData, output_file)
    input_file = output_file
    #output_file =  os.path.join(os.path.dirname(input_file),os.path.basename(input_file).split('.')[0] + 'Smooth.nii.gz')
    output_file = os.path.join(
        outputPath,
        os.path.basename(inputFile).split('.')[0] + 'Smooth.nii.gz')
    myGauss = fsl.SpatialFilter(in_file=input_file,
                                out_file=output_file,
                                operation='median',
                                kernel_shape='box',
                                kernel_size=0.1)
    myGauss.run()
    print('Smoothing DONE!')
    return output_file
예제 #2
0
파일: phdiff.py 프로젝트: badamifs/qsiprep
def init_phdiff_wf(omp_nthreads, phasetype='phasediff', name='phdiff_wf'):
    """
    Estimates the fieldmap using a phase-difference image and one or more
    magnitude images corresponding to two or more :abbr:`GRE (Gradient Echo sequence)`
    acquisitions. The `original code was taken from nipype
    <https://github.com/nipy/nipype/blob/master/nipype/workflows/dmri/fsl/artifacts.py#L514>`_.

    .. workflow ::
        :graph2use: orig
        :simple_form: yes

        from qsiprep.workflows.fieldmap.phdiff import init_phdiff_wf
        wf = init_phdiff_wf(omp_nthreads=1)


    Outputs::

      outputnode.fmap_ref - The average magnitude image, skull-stripped
      outputnode.fmap_mask - The brain mask applied to the fieldmap
      outputnode.fmap - The estimated fieldmap in Hz


    """

    workflow = Workflow(name=name)
    workflow.__desc__ = """\
A deformation field to correct for susceptibility distortions was estimated
based on a field map that was co-registered to the BOLD reference,
using a custom workflow of *fMRIPrep* derived from D. Greve's `epidewarp.fsl`
[script](http://www.nmr.mgh.harvard.edu/~greve/fbirn/b0/epidewarp.fsl) and
further improvements of HCP Pipelines [@hcppipelines].
"""

    inputnode = pe.Node(
        niu.IdentityInterface(fields=['magnitude', 'phasediff']),
        name='inputnode')

    outputnode = pe.Node(
        niu.IdentityInterface(fields=['fmap', 'fmap_ref', 'fmap_mask']),
        name='outputnode')

    # Merge input magnitude images
    magmrg = pe.Node(IntraModalMerge(), name='magmrg')

    # de-gradient the fields ("bias/illumination artifact")
    n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3, copy_header=True),
                 name='n4',
                 n_procs=omp_nthreads)
    bet = pe.Node(BETRPT(generate_report=True, frac=0.6, mask=True),
                  name='bet')
    ds_report_fmap_mask = pe.Node(DerivativesDataSink(desc='brain',
                                                      suffix='mask'),
                                  name='ds_report_fmap_mask',
                                  mem_gb=0.01,
                                  run_without_submitting=True)
    # uses mask from bet; outputs a mask
    # dilate = pe.Node(fsl.maths.MathsCommand(
    #     nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate')

    # FSL PRELUDE will perform phase-unwrapping
    prelude = pe.Node(fsl.PRELUDE(), name='prelude')

    denoise = pe.Node(fsl.SpatialFilter(operation='median',
                                        kernel_shape='sphere',
                                        kernel_size=5),
                      name='denoise')

    demean = pe.Node(niu.Function(function=demean_image), name='demean')

    cleanup_wf = cleanup_edge_pipeline(name="cleanup_wf")

    compfmap = pe.Node(Phasediff2Fieldmap(), name='compfmap')

    # The phdiff2fmap interface is equivalent to:
    # rad2rsec (using rads2radsec from nipype.workflows.dmri.fsl.utils)
    # pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='ComputeFieldmapFUGUE')
    # rsec2hz (divide by 2pi)

    if phasetype == "phasediff":
        # Read phasediff echo times
        meta = pe.Node(ReadSidecarJSON(), name='meta', mem_gb=0.01)

        # phase diff -> radians
        pha2rads = pe.Node(niu.Function(function=siemens2rads),
                           name='pha2rads')
        # Read phasediff echo times
        meta = pe.Node(ReadSidecarJSON(),
                       name='meta',
                       mem_gb=0.01,
                       run_without_submitting=True)
        workflow.connect([
            (meta, compfmap, [('out_dict', 'metadata')]),
            (inputnode, pha2rads, [('phasediff', 'in_file')]),
            (pha2rads, prelude, [('out', 'phase_file')]),
            (inputnode, ds_report_fmap_mask, [('phasediff', 'source_file')]),
        ])

    elif phasetype == "phase":
        workflow.__desc__ += """\
The phase difference used for unwarping was calculated using two separate phase measurements
 [@pncprocessing].
    """
        # Special case for phase1, phase2 images
        meta = pe.MapNode(ReadSidecarJSON(),
                          name='meta',
                          mem_gb=0.01,
                          run_without_submitting=True,
                          iterfield=['in_file'])
        phases2fmap = pe.Node(Phases2Fieldmap(), name='phases2fmap')
        workflow.connect([
            (meta, phases2fmap, [('out_dict', 'metadatas')]),
            (inputnode, phases2fmap, [('phasediff', 'phase_files')]),
            (phases2fmap, prelude, [('out_file', 'phase_file')]),
            (phases2fmap, compfmap, [('phasediff_metadata', 'metadata')]),
            (phases2fmap, ds_report_fmap_mask, [('out_file', 'source_file')])
        ])

    workflow.connect([
        (inputnode, meta, [('phasediff', 'in_file')]),
        (inputnode, magmrg, [('magnitude', 'in_files')]),
        (magmrg, n4, [('out_avg', 'input_image')]),
        (n4, prelude, [('output_image', 'magnitude_file')]),
        (n4, bet, [('output_image', 'in_file')]),
        (bet, prelude, [('mask_file', 'mask_file')]),
        (prelude, denoise, [('unwrapped_phase_file', 'in_file')]),
        (denoise, demean, [('out_file', 'in_file')]),
        (demean, cleanup_wf, [('out', 'inputnode.in_file')]),
        (bet, cleanup_wf, [('mask_file', 'inputnode.in_mask')]),
        (cleanup_wf, compfmap, [('outputnode.out_file', 'in_file')]),
        (compfmap, outputnode, [('out_file', 'fmap')]),
        (bet, outputnode, [('mask_file', 'fmap_mask'),
                           ('out_file', 'fmap_ref')]),
        (bet, ds_report_fmap_mask, [('out_report', 'in_file')]),
    ])

    return workflow
예제 #3
0
def init_fmap_wf(omp_nthreads, fmap_bspline, name='fmap_wf'):
    """
    Fieldmap workflow - when we have a sequence that directly measures the fieldmap
    we just need to mask it (using the corresponding magnitude image) to remove the
    noise in the surrounding air region, and ensure that units are Hz.

    .. workflow ::
        :graph2use: orig
        :simple_form: yes

        from fmriprep.workflows.fieldmap.fmap import init_fmap_wf
        wf = init_fmap_wf(omp_nthreads=6, fmap_bspline=False)

    """

    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['magnitude', 'fieldmap']),
        name='inputnode')
    outputnode = pe.Node(
        niu.IdentityInterface(fields=['fmap', 'fmap_ref', 'fmap_mask']),
        name='outputnode')

    # Merge input magnitude images
    magmrg = pe.Node(IntraModalMerge(), name='magmrg')
    # Merge input fieldmap images
    fmapmrg = pe.Node(IntraModalMerge(zero_based_avg=False, hmc=False),
                      name='fmapmrg')

    # de-gradient the fields ("bias/illumination artifact")
    n4_correct = pe.Node(ants.N4BiasFieldCorrection(dimension=3,
                                                    copy_header=True),
                         name='n4_correct',
                         n_procs=omp_nthreads)
    bet = pe.Node(BETRPT(generate_report=True, frac=0.6, mask=True),
                  name='bet')
    ds_fmap_mask = pe.Node(DerivativesDataSink(suffix='fmap_mask'),
                           name='ds_report_fmap_mask',
                           run_without_submitting=True)

    workflow.connect([
        (inputnode, magmrg, [('magnitude', 'in_files')]),
        (inputnode, fmapmrg, [('fieldmap', 'in_files')]),
        (magmrg, n4_correct, [('out_file', 'input_image')]),
        (n4_correct, bet, [('output_image', 'in_file')]),
        (bet, outputnode, [('mask_file', 'fmap_mask'),
                           ('out_file', 'fmap_ref')]),
        (inputnode, ds_fmap_mask, [('fieldmap', 'source_file')]),
        (bet, ds_fmap_mask, [('out_report', 'in_file')]),
    ])

    if fmap_bspline:
        # despike_threshold=1.0, mask_erode=1),
        fmapenh = pe.Node(FieldEnhance(unwrap=False, despike=False),
                          name='fmapenh',
                          mem_gb=4,
                          n_procs=omp_nthreads)

        workflow.connect([
            (bet, fmapenh, [('mask_file', 'in_mask'),
                            ('out_file', 'in_magnitude')]),
            (fmapmrg, fmapenh, [('out_file', 'in_file')]),
            (fmapenh, outputnode, [('out_file', 'fmap')]),
        ])

    else:
        torads = pe.Node(FieldToRadS(), name='torads')
        prelude = pe.Node(fsl.PRELUDE(), name='prelude')
        tohz = pe.Node(FieldToHz(), name='tohz')

        denoise = pe.Node(fsl.SpatialFilter(operation='median',
                                            kernel_shape='sphere',
                                            kernel_size=3),
                          name='denoise')
        demean = pe.Node(niu.Function(function=demean_image), name='demean')
        cleanup_wf = cleanup_edge_pipeline(name='cleanup_wf')

        applymsk = pe.Node(fsl.ApplyMask(), name='applymsk')

        workflow.connect([
            (bet, prelude, [('mask_file', 'mask_file'),
                            ('out_file', 'magnitude_file')]),
            (fmapmrg, torads, [('out_file', 'in_file')]),
            (torads, tohz, [('fmap_range', 'range_hz')]),
            (torads, prelude, [('out_file', 'phase_file')]),
            (prelude, tohz, [('unwrapped_phase_file', 'in_file')]),
            (tohz, denoise, [('out_file', 'in_file')]),
            (denoise, demean, [('out_file', 'in_file')]),
            (demean, cleanup_wf, [('out', 'inputnode.in_file')]),
            (bet, cleanup_wf, [('mask_file', 'inputnode.in_mask')]),
            (cleanup_wf, applymsk, [('outputnode.out_file', 'in_file')]),
            (bet, applymsk, [('mask_file', 'mask_file')]),
            (applymsk, outputnode, [('out_file', 'fmap')]),
        ])

    return workflow
예제 #4
0
def init_fmap_postproc_wf(omp_nthreads, fmap_bspline, median_kernel_size=5,
                          name='fmap_postproc_wf'):
    """
    Postprocess a B0 map estimated elsewhere.

    This workflow denoises (mostly via smoothing) a B0 fieldmap.

    Workflow Graph
        .. workflow ::
            :graph2use: orig
            :simple_form: yes

            from sdcflows.workflows.fmap import init_fmap_postproc_wf
            wf = init_fmap_postproc_wf(omp_nthreads=6, fmap_bspline=False)

    Parameters
    ----------
    omp_nthreads : int
        Maximum number of threads an individual process may use
    fmap_bspline : bool
        Whether the fieldmap should be smoothed and extrapolated to off-brain regions
        using B-Spline basis.
    median_kernel_size : int
        Size of the kernel when smoothing is done with a median filter.
    name : str
        Name of workflow (default: ``fmap_postproc_wf``)

    Inputs
    ------
    fmap_mask : pathlike
        A brain binary mask corresponding to this fieldmap.
    fmap_ref : pathlike
        A preprocessed magnitude/reference image for the fieldmap.
    fmap : pathlike
        A B0-field nonuniformity map (aka fieldmap) estimated elsewhere.

    Outputs
    -------
    out_fmap : pathlike
        Postprocessed fieldmap.

    """
    workflow = Workflow(name=name)
    inputnode = pe.Node(niu.IdentityInterface(
        fields=['fmap_mask', 'fmap_ref', 'fmap', 'metadata']), name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(fields=['out_fmap', 'metadata']),
                         name='outputnode')
    if fmap_bspline:
        from ..interfaces.fmap import FieldEnhance
        # despike_threshold=1.0, mask_erode=1),
        fmapenh = pe.Node(
            FieldEnhance(unwrap=False, despike=False),
            name='fmapenh', mem_gb=4, n_procs=omp_nthreads)

        workflow.connect([
            (inputnode, fmapenh, [('fmap_mask', 'in_mask'),
                                  ('fmap_ref', 'in_magnitude'),
                                  ('fmap_hz', 'in_file')]),
            (fmapenh, outputnode, [('out_file', 'out_fmap')]),
        ])

    else:
        recenter = pe.Node(niu.Function(function=_recenter),
                           name='recenter', run_without_submitting=True)
        denoise = pe.Node(fsl.SpatialFilter(
                          operation='median', kernel_shape='sphere',
                          kernel_size=median_kernel_size), name='denoise')
        demean = pe.Node(niu.Function(function=_demean), name='demean')
        cleanup_wf = cleanup_edge_pipeline(name="cleanup_wf")

        workflow.connect([
            (inputnode, cleanup_wf, [('fmap_mask', 'inputnode.in_mask')]),
            (inputnode, recenter, [(('fmap', _pop), 'in_file')]),
            (recenter, denoise, [('out', 'in_file')]),
            (denoise, demean, [('out_file', 'in_file')]),
            (demean, cleanup_wf, [('out', 'inputnode.in_file')]),
            (cleanup_wf, outputnode, [('outputnode.out_file', 'out_fmap')]),
            (inputnode, outputnode, [(('metadata', _pop), 'metadata')]),
        ])

    return workflow
예제 #5
0
def init_phdiff_wf(omp_nthreads, name='phdiff_wf'):
    """
    Distortion correction of EPI sequences using phase-difference maps.

    Estimates the fieldmap using a phase-difference image and one or more
    magnitude images corresponding to two or more :abbr:`GRE (Gradient Echo sequence)`
    acquisitions. The `original code was taken from nipype
    <https://github.com/nipy/nipype/blob/master/nipype/workflows/dmri/fsl/artifacts.py#L514>`_.

    .. workflow ::
        :graph2use: orig
        :simple_form: yes

        from sdcflows.workflows.phdiff import init_phdiff_wf
        wf = init_phdiff_wf(omp_nthreads=1)

    **Parameters**:

        omp_nthreads : int
            Maximum number of threads an individual process may use

    **Inputs**:

        magnitude : pathlike
            Path to the corresponding magnitude path(s).
        phasediff : pathlike
            Path to the corresponding phase-difference file.
        metadata : dict
            Metadata dictionary corresponding to the phasediff input

    **Outputs**:

        fmap_ref : pathlike
            The average magnitude image, skull-stripped
        fmap_mask : pathlike
            The brain mask applied to the fieldmap
        fmap : pathlike
            The estimated fieldmap in Hz

    """
    workflow = Workflow(name=name)
    workflow.__desc__ = """\
A deformation field to correct for susceptibility distortions was estimated
based on a field map that was co-registered to the BOLD reference,
using a custom workflow of *fMRIPrep* derived from D. Greve's `epidewarp.fsl`
[script](http://www.nmr.mgh.harvard.edu/~greve/fbirn/b0/epidewarp.fsl) and
further improvements of HCP Pipelines [@hcppipelines].
"""

    inputnode = pe.Node(
        niu.IdentityInterface(fields=['magnitude', 'phasediff', 'metadata']),
        name='inputnode')

    outputnode = pe.Node(
        niu.IdentityInterface(fields=['fmap', 'fmap_ref', 'fmap_mask']),
        name='outputnode')

    # Merge input magnitude images
    magmrg = pe.Node(IntraModalMerge(), name='magmrg')

    # de-gradient the fields ("bias/illumination artifact")
    n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3, copy_header=True),
                 name='n4',
                 n_procs=omp_nthreads)
    bet = pe.Node(BETRPT(generate_report=True, frac=0.6, mask=True),
                  name='bet')

    # uses mask from bet; outputs a mask
    # dilate = pe.Node(fsl.maths.MathsCommand(
    #     nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate')

    # phase diff -> radians
    pha2rads = pe.Node(niu.Function(function=siemens2rads), name='pha2rads')

    # FSL PRELUDE will perform phase-unwrapping
    prelude = pe.Node(fsl.PRELUDE(), name='prelude')

    denoise = pe.Node(fsl.SpatialFilter(operation='median',
                                        kernel_shape='sphere',
                                        kernel_size=3),
                      name='denoise')

    demean = pe.Node(niu.Function(function=demean_image), name='demean')

    cleanup_wf = cleanup_edge_pipeline(name="cleanup_wf")

    compfmap = pe.Node(Phasediff2Fieldmap(), name='compfmap')

    # The phdiff2fmap interface is equivalent to:
    # rad2rsec (using rads2radsec from nipype.workflows.dmri.fsl.utils)
    # pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='ComputeFieldmapFUGUE')
    # rsec2hz (divide by 2pi)

    workflow.connect([
        (inputnode, compfmap, [('metadata', 'metadata')]),
        (inputnode, magmrg, [('magnitude', 'in_files')]),
        (magmrg, n4, [('out_avg', 'input_image')]),
        (n4, prelude, [('output_image', 'magnitude_file')]),
        (n4, bet, [('output_image', 'in_file')]),
        (bet, prelude, [('mask_file', 'mask_file')]),
        (inputnode, pha2rads, [('phasediff', 'in_file')]),
        (pha2rads, prelude, [('out', 'phase_file')]),
        (prelude, denoise, [('unwrapped_phase_file', 'in_file')]),
        (denoise, demean, [('out_file', 'in_file')]),
        (demean, cleanup_wf, [('out', 'inputnode.in_file')]),
        (bet, cleanup_wf, [('mask_file', 'inputnode.in_mask')]),
        (cleanup_wf, compfmap, [('outputnode.out_file', 'in_file')]),
        (compfmap, outputnode, [('out_file', 'fmap')]),
        (bet, outputnode, [('mask_file', 'fmap_mask'),
                           ('out_file', 'fmap_ref')]),
    ])

    return workflow
예제 #6
0
    def create_workflow(self, flow, inputnode, outputnode):

        smoothing_output = pe.Node(interface=util.IdentityInterface(fields=["smoothing_output"]),name="smoothing_output")
        if self.config.smoothing > 0.0:
            smoothing = pe.Node(interface=fsl.SpatialFilter(operation='mean',kernel_shape = 'gauss'),name="smoothing")
            smoothing.inputs.kernel_size = self.config.smoothing
            flow.connect([
                        (inputnode,smoothing,[("preproc_file","in_file")]),
                        (smoothing,smoothing_output,[("out_file","smoothing_output")])
                        ])
        else:
            flow.connect([
                        (inputnode,smoothing_output,[("preproc_file","smoothing_output")])
                        ])
        
        discard_output = pe.Node(interface=util.IdentityInterface(fields=["discard_output"]),name="discard_output")   
        if self.config.discard_n_volumes > 0:
            discard = pe.Node(interface=discard_tp(n_discard=self.config.discard_n_volumes),name='discard_volumes')
            flow.connect([
                        (smoothing_output,discard,[("smoothing_output","in_file")]),
                        (discard,discard_output,[("out_file","discard_output")])
                        ])
        else:
            flow.connect([
                        (smoothing_output,discard_output,[("smoothing_output","discard_output")])
                        ])
        
        nuisance_output = pe.Node(interface=util.IdentityInterface(fields=["nuisance_output"]),name="nuisance_output")      
        if self.config.wm or self.config.global_nuisance or self.config.csf or self.config.motion:
            nuisance = pe.Node(interface=nuisance_regression(),name="nuisance_regression")
            nuisance.inputs.global_nuisance=self.config.global_nuisance
            nuisance.inputs.csf_nuisance=self.config.csf
            nuisance.inputs.wm_nuisance=self.config.wm
            nuisance.inputs.motion_nuisance=self.config.motion
            nuisance.inputs.n_discard=self.config.discard_n_volumes
            flow.connect([
                        (discard_output,nuisance,[("discard_output","in_file")]),
                        (inputnode,nuisance,[("eroded_brain","brainfile")]),
                        (inputnode,nuisance,[("eroded_csf","csf_file")]),
                        (inputnode,nuisance,[("eroded_wm","wm_file")]),
                        (inputnode,nuisance,[("motion_par_file","motion_file")]),
                        (inputnode,nuisance,[("registered_roi_volumes","gm_file")]),
                        (nuisance,nuisance_output,[("out_file","nuisance_output")])
                        ])
        else:
            flow.connect([
                        (discard_output,nuisance_output,[("discard_output","nuisance_output")])
                        ])
        
        detrending_output = pe.Node(interface=util.IdentityInterface(fields=["detrending_output"]),name="detrending_output")
        if self.config.detrending:
            detrending = pe.Node(interface=Detrending(),name='detrending')
            flow.connect([
                        (nuisance_output,detrending,[("nuisance_output","in_file")]),
                        (inputnode,detrending,[("registered_roi_volumes","gm_file")]),
                        (detrending,detrending_output,[("out_file","detrending_output")])
                        ])
        else:
            flow.connect([
                        (nuisance_output,detrending_output,[("nuisance_output","detrending_output")])
                        ])
        
        filter_output = pe.Node(interface=util.IdentityInterface(fields=["filter_output"]),name="filter_output")
        if self.config.lowpass_filter > 0 or self.config.highpass_filter > 0:
            filtering = pe.Node(interface=fsl.TemporalFilter(),name='temporal_filter')
            filtering.inputs.lowpass_sigma = self.config.lowpass_filter
            filtering.inputs.highpass_sigma = self.config.highpass_filter
            flow.connect([
                        (detrending_output,filtering,[("detrending_output","in_file")]),
                        (filtering,filter_output,[("out_file","filter_output")])
                        ])
        else:
            flow.connect([
                        (detrending_output,filter_output,[("detrending_output","filter_output")])
                        ])
                            
        if self.config.scrubbing:
            scrubbing = pe.Node(interface=Scrubbing(),name='scrubbing')
            flow.connect([
                        (filter_output,scrubbing,[("filter_output","in_file")]),
                        (inputnode,scrubbing,[("registered_wm","wm_mask")]),
                        (inputnode,scrubbing,[("registered_roi_volumes","gm_file")]),
                        (inputnode,scrubbing,[("motion_par_file","motion_parameters")]),
                        (scrubbing,outputnode,[("fd_npy","FD")]),
                        (scrubbing,outputnode,[("dvars_npy","DVARS")])
                        ])
        
        flow.connect([
                        (filter_output,outputnode,[("filter_output","func_file")])
                        ])
예제 #7
0
def init_phdiff_wf(omp_nthreads, name='phdiff_wf'):
    """
    Estimates the fieldmap using a phase-difference image and one or more
    magnitude images corresponding to two or more :abbr:`GRE (Gradient Echo sequence)`
    acquisitions. The `original code was taken from nipype
    <https://github.com/nipy/nipype/blob/master/nipype/workflows/dmri/fsl/artifacts.py#L514>`_.

    .. workflow ::
        :graph2use: orig
        :simple_form: yes

        from fmriprep.workflows.fieldmap.phdiff import init_phdiff_wf
        wf = init_phdiff_wf(omp_nthreads=1)


    Outputs::

      outputnode.fmap_ref - The average magnitude image, skull-stripped
      outputnode.fmap_mask - The brain mask applied to the fieldmap
      outputnode.fmap - The estimated fieldmap in Hz


    """

    inputnode = pe.Node(
        niu.IdentityInterface(fields=['magnitude', 'phasediff']),
        name='inputnode')

    outputnode = pe.Node(
        niu.IdentityInterface(fields=['fmap', 'fmap_ref', 'fmap_mask']),
        name='outputnode')

    def _pick1st(inlist):
        return inlist[0]

    # Read phasediff echo times
    meta = pe.Node(ReadSidecarJSON(),
                   name='meta',
                   mem_gb=0.01,
                   run_without_submitting=True)

    # Merge input magnitude images
    magmrg = pe.Node(IntraModalMerge(), name='magmrg')

    # de-gradient the fields ("bias/illumination artifact")
    n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3, copy_header=True),
                 name='n4',
                 n_procs=omp_nthreads)
    bet = pe.Node(BETRPT(generate_report=True, frac=0.6, mask=True),
                  name='bet')
    ds_fmap_mask = pe.Node(DerivativesDataSink(suffix='fmap_mask'),
                           name='ds_report_fmap_mask',
                           mem_gb=0.01,
                           run_without_submitting=True)
    # uses mask from bet; outputs a mask
    # dilate = pe.Node(fsl.maths.MathsCommand(
    #     nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate')

    # phase diff -> radians
    pha2rads = pe.Node(niu.Function(function=siemens2rads), name='pha2rads')

    # FSL PRELUDE will perform phase-unwrapping
    prelude = pe.Node(fsl.PRELUDE(), name='prelude')

    denoise = pe.Node(fsl.SpatialFilter(operation='median',
                                        kernel_shape='sphere',
                                        kernel_size=3),
                      name='denoise')

    demean = pe.Node(niu.Function(function=demean_image), name='demean')

    cleanup_wf = cleanup_edge_pipeline(name="cleanup_wf")

    compfmap = pe.Node(Phasediff2Fieldmap(), name='compfmap')

    # The phdiff2fmap interface is equivalent to:
    # rad2rsec (using rads2radsec from nipype.workflows.dmri.fsl.utils)
    # pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='ComputeFieldmapFUGUE')
    # rsec2hz (divide by 2pi)

    workflow = pe.Workflow(name=name)
    workflow.connect([
        (inputnode, meta, [('phasediff', 'in_file')]),
        (inputnode, magmrg, [('magnitude', 'in_files')]),
        (magmrg, n4, [('out_avg', 'input_image')]),
        (n4, prelude, [('output_image', 'magnitude_file')]),
        (n4, bet, [('output_image', 'in_file')]),
        (bet, prelude, [('mask_file', 'mask_file')]),
        (inputnode, pha2rads, [('phasediff', 'in_file')]),
        (pha2rads, prelude, [('out', 'phase_file')]),
        (meta, compfmap, [('out_dict', 'metadata')]),
        (prelude, denoise, [('unwrapped_phase_file', 'in_file')]),
        (denoise, demean, [('out_file', 'in_file')]),
        (demean, cleanup_wf, [('out', 'inputnode.in_file')]),
        (bet, cleanup_wf, [('mask_file', 'inputnode.in_mask')]),
        (cleanup_wf, compfmap, [('outputnode.out_file', 'in_file')]),
        (compfmap, outputnode, [('out_file', 'fmap')]),
        (bet, outputnode, [('mask_file', 'fmap_mask'),
                           ('out_file', 'fmap_ref')]),
        (inputnode, ds_fmap_mask, [('phasediff', 'source_file')]),
        (bet, ds_fmap_mask, [('out_report', 'in_file')]),
    ])

    return workflow
def phase_diff_and_magnitudes(name='phase_diff_and_magnitudes'):
    """
    Estimates the fieldmap using a phase-difference image and one or more
    magnitude images corresponding to two or more :abbr:`GRE (Gradient Echo sequence)`
    acquisitions. The `original code was taken from nipype
    <https://github.com/nipy/nipype/blob/master/nipype/workflows/dmri/fsl/artifacts.py#L514>`_.

    Outputs::

      outputnode.fmap_ref - The average magnitude image, skull-stripped
      outputnode.fmap_mask - The brain mask applied to the fieldmap
      outputnode.fmap - The estimated fieldmap in Hz


    """
    inputnode = pe.Node(niu.IdentityInterface(fields=['input_images']),
                        name='inputnode')

    outputnode = pe.Node(
        niu.IdentityInterface(fields=['fmap_ref', 'fmap_mask', 'fmap']),
        name='outputnode')

    sortfmaps = pe.Node(niu.Function(function=_sort_fmaps,
                                     input_names=['input_images'],
                                     output_names=['magnitude', 'phasediff']),
                        name='SortFmaps')

    def _pick1st(inlist):
        return inlist[0]

    # Read phasediff echo times
    meta = pe.Node(ReadSidecarJSON(fields=['EchoTime1', 'EchoTime2']),
                   name='metadata')
    dte = pe.Node(niu.Function(input_names=['in_values'],
                               output_names=['delta_te'],
                               function=_delta_te),
                  name='ComputeDeltaTE')

    # Merge input magnitude images
    magmrg = pe.Node(IntraModalMerge(), name='MagnitudeFuse')

    # de-gradient the fields ("bias/illumination artifact")
    n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='MagnitudeBias')
    bet = pe.Node(fsl.BET(frac=0.6, mask=True), name='MagnitudeBET')
    # uses mask from bet; outputs a mask
    # dilate = pe.Node(fsl.maths.MathsCommand(
    #     nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate')

    # phase diff -> radians
    pha2rads = pe.Node(niu.Function(input_names=['in_file'],
                                    output_names=['out_file'],
                                    function=siemens2rads),
                       name='PreparePhase')

    # FSL PRELUDE will perform phase-unwrapping
    prelude = pe.Node(fsl.PRELUDE(process3d=True), name='PhaseUnwrap')

    denoise = pe.Node(fsl.SpatialFilter(operation='median',
                                        kernel_shape='sphere',
                                        kernel_size=3),
                      name='PhaseDenoise')

    demean = pe.Node(niu.Function(input_names=['in_file', 'in_mask'],
                                  output_names=['out_file'],
                                  function=demean_image),
                     name='DemeanFmap')

    cleanup = cleanup_edge_pipeline()

    compfmap = pe.Node(niu.Function(input_names=['in_file', 'delta_te'],
                                    output_names=['out_file'],
                                    function=phdiff2fmap),
                       name='ComputeFieldmap')

    # The phdiff2fmap interface is equivalent to:
    # rad2rsec (using rads2radsec from nipype.workflows.dmri.fsl.utils)
    # pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='ComputeFieldmapFUGUE')
    # rsec2hz (divide by 2pi)

    workflow = pe.Workflow(name=name)
    workflow.connect([
        (inputnode, sortfmaps, [('input_images', 'input_images')]),
        (sortfmaps, meta, [(('phasediff', _pick1st), 'in_file')]),
        (sortfmaps, magmrg, [('magnitude', 'in_files')]),
        (magmrg, n4, [('out_avg', 'input_image')]),
        (n4, prelude, [('output_image', 'magnitude_file')]),
        (n4, bet, [('output_image', 'in_file')]),
        (bet, prelude, [('mask_file', 'mask_file')]),
        (sortfmaps, pha2rads, [(('phasediff', _pick1st), 'in_file')]),
        (pha2rads, prelude, [('out_file', 'phase_file')]),
        (meta, dte, [('out_dict', 'in_values')]),
        (dte, compfmap, [('delta_te', 'delta_te')]),
        (prelude, denoise, [('unwrapped_phase_file', 'in_file')]),
        (denoise, demean, [('out_file', 'in_file')]),
        (demean, cleanup, [('out_file', 'inputnode.in_file')]),
        (bet, cleanup, [('mask_file', 'inputnode.in_mask')]),
        (cleanup, compfmap, [('outputnode.out_file', 'in_file')]),
        (compfmap, outputnode, [('out_file', 'fmap')]),
        (bet, outputnode, [('mask_file', 'fmap_mask'),
                           ('out_file', 'fmap_ref')])
    ])

    return workflow
예제 #9
0
maskdata(magbrain_warped, mag_mask)

#unwarp withe predule
unwrapped = outdir + '/unwrapped.nii.gz'
prefsl = fsl.PRELUDE()
prefsl.inputs.magnitude_file = magbrain_warped
prefsl.inputs.phase_file = phasediff[0]
prefsl.inputs.mask_file = mag_mask
prefsl.inputs.unwrapped_phase_file = unwrapped
prefsl.run()
#denoise demean recenter the fieldmap and
#recentre
recentered = _recenter(unwrapped, newpath=outdir + '/')
# denoise with fsl spatial filter
denoised = outdir + '/unwrapped_denoise.nii.gz'
denoise = fsl.SpatialFilter()
denoise.inputs.in_file = recentered
denoise.inputs.kernel_shape = 'sphere'
denoise.inputs.kernel_size = 3
denoise.inputs.operation = 'median'
denoise.inputs.out_file = denoised
denoise.run()

demeamed = _demean(in_file=denoised, newpath=outdir + '/')

# get delta te
if os.path.isfile(phasedifc[0]):
    with open(glob.glob(fmapdir + '/*phasediff.json')[0], 'r') as jsonfile:
        obj = jsonfile.read()
    dpdat = json.loads(obj)
    delta_te = np.abs(dpdat['EchoTime2'] - dpdat['EchoTime1'])