Пример #1
0
    def tensor_metrics_pipeline(self, **name_maps):  # @UnusedVariable
        """
        Fits the apparrent diffusion tensor (DT) to each voxel of the image
        """

#             inputs=[FilesetSpec('tensor', nifti_gz_format),
#                     FilesetSpec('brain_mask', nifti_gz_format)],
#             outputs=[FilesetSpec('fa', nifti_gz_format),
#                      FilesetSpec('adc', nifti_gz_format)],
        pipeline = self.new_pipeline(
            name='fa',
            desc=("Calculates the FA and ADC from a tensor image"),
            references=[],
            name_maps=name_maps)
        # Create tensor fit node
        metrics = pipeline.add(
            'metrics',
            TensorMetrics(),
            requirements=[mrtrix_req.v('3.0rc3')])
        metrics.inputs.out_fa = 'fa.nii.gz'
        metrics.inputs.out_adc = 'adc.nii.gz'
        # Connect to inputs
        pipeline.connect_input('tensor', metrics, 'in_file')
        pipeline.connect_input('brain_mask', metrics, 'in_mask')
        # Connect to outputs
        pipeline.connect_output('fa', metrics, 'out_fa')
        pipeline.connect_output('adc', metrics, 'out_adc')
        # Check inputs/output are connected
        return pipeline
Пример #2
0
 def fa_pipeline(self, **kwargs):  # @UnusedVariable
     """
     Fits the apparrent diffusion tensor (DT) to each voxel of the image
     """
     pipeline = self.create_pipeline(
         name='fa',
         inputs=[
             DatasetSpec('tensor', nifti_gz_format),
             DatasetSpec('brain_mask', nifti_gz_format)
         ],
         outputs=[
             DatasetSpec('fa', nifti_gz_format),
             DatasetSpec('adc', nifti_gz_format)
         ],
         desc=("Calculates the FA and ADC from a tensor image"),
         version=1,
         citations=[],
         **kwargs)
     # Create tensor fit node
     metrics = pipeline.create_node(TensorMetrics(),
                                    name='metrics',
                                    requirements=[mrtrix3_req])
     metrics.inputs.out_fa = 'fa.nii.gz'
     metrics.inputs.out_adc = 'adc.nii.gz'
     # Connect to inputs
     pipeline.connect_input('tensor', metrics, 'in_file')
     pipeline.connect_input('brain_mask', metrics, 'in_mask')
     # Connect to outputs
     pipeline.connect_output('fa', metrics, 'out_fa')
     pipeline.connect_output('adc', metrics, 'out_adc')
     # Check inputs/output are connected
     return pipeline
Пример #3
0
    def tensor_metrics_pipeline(self, **name_maps):
        """
        Fits the apparrent diffusion tensor (DT) to each voxel of the image
        """

        pipeline = self.new_pipeline(
            name='fa',
            desc=("Calculates the FA and ADC from a tensor image"),
            citations=[],
            name_maps=name_maps)

        # Create tensor fit node
        pipeline.add(
            'metrics',
            TensorMetrics(
                out_fa='fa.nii.gz',
                out_adc='adc.nii.gz'),
            inputs={
                'in_file': ('tensor', nifti_gz_format),
                'in_mask': (self.brain_mask_spec_name, nifti_gz_format)},
            outputs={
                'fa': ('out_fa', nifti_gz_format),
                'adc': ('out_adc', nifti_gz_format)},
            requirements=[mrtrix_req.v('3.0rc3')])

        return pipeline
Пример #4
0
def test_TensorMetrics_outputs():
    output_map = dict(out_adc=dict(),
    out_eval=dict(),
    out_evec=dict(),
    out_fa=dict(),
    )
    outputs = TensorMetrics.output_spec()

    for key, metadata in output_map.items():
        for metakey, value in metadata.items():
            yield assert_equal, getattr(outputs.traits()[key], metakey), value
Пример #5
0
def test_TensorMetrics_inputs():
    input_map = dict(args=dict(argstr='%s',
    ),
    component=dict(argstr='-num %s',
    sep=',',
    ),
    environ=dict(nohash=True,
    usedefault=True,
    ),
    ignore_exception=dict(nohash=True,
    usedefault=True,
    ),
    in_file=dict(argstr='%s',
    mandatory=True,
    position=-1,
    ),
    in_mask=dict(argstr='-mask %s',
    ),
    modulate=dict(argstr='-modulate %s',
    ),
    out_adc=dict(argstr='-adc %s',
    ),
    out_eval=dict(argstr='-value %s',
    ),
    out_evec=dict(argstr='-vector %s',
    ),
    out_fa=dict(argstr='-fa %s',
    ),
    terminal_output=dict(nohash=True,
    ),
    )
    inputs = TensorMetrics.input_spec()

    for key, metadata in input_map.items():
        for metakey, value in metadata.items():
            yield assert_equal, getattr(inputs.traits()[key], metakey), value
Пример #6
0
def create_mrtrix_recon_flow(config):
    '''Create the diffusion reconstruction workflow.

    It estimates the tensors or the fiber orientation distribution functions.

    Parameters
    ----------
    config '''

    # TODO: Add AD and RD maps
    flow = pe.Workflow(name="reconstruction")
    inputnode = pe.Node(
        interface=util.IdentityInterface(
            fields=["diffusion", "diffusion_resampled", "wm_mask_resampled", "grad"]),
        name="inputnode")
    outputnode = pe.Node(interface=util.IdentityInterface(fields=["DWI", "FA", "ADC", "tensor", "eigVec", "RF", "grad"],
                                                          mandatory_inputs=True), name="outputnode")

    # Flip gradient table
    flip_table = pe.Node(interface=flipTable(), name='flip_table')

    flip_table.inputs.flipping_axis = config.flip_table_axis
    flip_table.inputs.delimiter = ' '
    flip_table.inputs.header_lines = 0
    flip_table.inputs.orientation = 'v'
    flow.connect([
        (inputnode, flip_table, [("grad", "table")]),
        (flip_table, outputnode, [("table", "grad")])
    ])
    # flow.connect([
    #             (inputnode,outputnode,[("grad","grad")])
    #             ])

    # Tensor
    mrtrix_tensor = pe.Node(interface=DWI2Tensor(), name='mrtrix_make_tensor')

    flow.connect([
        (inputnode, mrtrix_tensor, [('diffusion_resampled', 'in_file')]),
        (flip_table, mrtrix_tensor, [("table", "encoding_file")]),
    ])

    # Tensor -> FA map
    mrtrix_tensor_metrics = pe.Node(interface=TensorMetrics(out_fa='FA.mif', out_adc='ADC.mif'),
                                    name='mrtrix_tensor_metrics')
    convert_Tensor = pe.Node(interface=MRConvert(
        out_filename="dwi_tensor.nii.gz"), name='convert_tensor')
    convert_FA = pe.Node(interface=MRConvert(
        out_filename="FA.nii.gz"), name='convert_FA')
    convert_ADC = pe.Node(interface=MRConvert(
        out_filename="ADC.nii.gz"), name='convert_ADC')

    flow.connect([
        (mrtrix_tensor, convert_Tensor, [('tensor', 'in_file')]),
        (mrtrix_tensor, mrtrix_tensor_metrics, [('tensor', 'in_file')]),
        (mrtrix_tensor_metrics, convert_FA, [('out_fa', 'in_file')]),
        (mrtrix_tensor_metrics, convert_ADC, [('out_adc', 'in_file')]),
        (convert_Tensor, outputnode, [("converted", "tensor")]),
        (convert_FA, outputnode, [("converted", "FA")]),
        (convert_ADC, outputnode, [("converted", "ADC")])
    ])

    # Tensor -> Eigenvectors
    mrtrix_eigVectors = pe.Node(
        interface=Tensor2Vector(), name='mrtrix_eigenvectors')

    flow.connect([
        (mrtrix_tensor, mrtrix_eigVectors, [('tensor', 'in_file')]),
        (mrtrix_eigVectors, outputnode, [('vector', 'eigVec')])
    ])

    # Constrained Spherical Deconvolution
    if config.local_model:
        print("CSD true")
        # Compute single fiber voxel mask
        mrtrix_erode = pe.Node(interface=Erode(
            out_filename='wm_mask_res_eroded.nii.gz'), name='mrtrix_erode')
        mrtrix_erode.inputs.number_of_passes = 1
        mrtrix_erode.inputs.filtertype = 'erode'
        mrtrix_mul_eroded_FA = pe.Node(
            interface=MRtrix_mul(), name='mrtrix_mul_eroded_FA')
        mrtrix_mul_eroded_FA.inputs.out_filename = "diffusion_resampled_tensor_FA_masked.mif"
        mrtrix_thr_FA = pe.Node(interface=MRThreshold(
            out_file='FA_th.mif'), name='mrtrix_thr')
        mrtrix_thr_FA.inputs.abs_value = config.single_fib_thr

        flow.connect([
            (inputnode, mrtrix_erode, [("wm_mask_resampled", 'in_file')]),
            (mrtrix_erode, mrtrix_mul_eroded_FA, [('out_file', 'input2')]),
            (mrtrix_tensor_metrics, mrtrix_mul_eroded_FA,
             [('out_fa', 'input1')]),
            (mrtrix_mul_eroded_FA, mrtrix_thr_FA, [('out_file', 'in_file')])
        ])
        # Compute single fiber response function
        mrtrix_rf = pe.Node(
            interface=EstimateResponseForSH(), name='mrtrix_rf')
        # if config.lmax_order != 'Auto':
        mrtrix_rf.inputs.maximum_harmonic_order = int(config.lmax_order)

        mrtrix_rf.inputs.algorithm = 'tournier'
        # mrtrix_rf.inputs.normalise = config.normalize_to_B0
        flow.connect([
            (inputnode, mrtrix_rf, [("diffusion_resampled", "in_file")]),
            (mrtrix_thr_FA, mrtrix_rf, [("thresholded", "mask_image")]),
            (flip_table, mrtrix_rf, [("table", "encoding_file")]),
        ])

        # Perform spherical deconvolution
        mrtrix_CSD = pe.Node(
            interface=ConstrainedSphericalDeconvolution(), name='mrtrix_CSD')
        mrtrix_CSD.inputs.algorithm = 'csd'
        mrtrix_CSD.inputs.maximum_harmonic_order = int(config.lmax_order)
        # mrtrix_CSD.inputs.normalise = config.normalize_to_B0

        convert_CSD = pe.Node(interface=MRConvert(
            out_filename="spherical_harmonics_image.nii.gz"), name='convert_CSD')

        flow.connect([
            (inputnode, mrtrix_CSD, [('diffusion_resampled', 'in_file')]),
            (mrtrix_rf, mrtrix_CSD, [('response', 'response_file')]),
            (mrtrix_rf, outputnode, [('response', 'RF')]),
            (inputnode, mrtrix_CSD, [("wm_mask_resampled", 'mask_image')]),
            (flip_table, mrtrix_CSD, [("table", "encoding_file")]),
            (mrtrix_CSD, convert_CSD, [('spherical_harmonics_image', 'in_file')]),
            (convert_CSD, outputnode, [("converted", "DWI")])
            # (mrtrix_CSD,outputnode,[('spherical_harmonics_image','DWI')])
        ])
    else:
        flow.connect([
            (inputnode, outputnode, [('diffusion_resampled', 'DWI')])
        ])

    return flow
def create_mrtrix_recon_flow(config):
    """Create the reconstruction sub-workflow of the `DiffusionStage` using MRtrix3.

    Parameters
    ----------
    config : DipyReconConfig
        Workflow configuration

    Returns
    -------
    flow : nipype.pipeline.engine.Workflow
        Built reconstruction sub-workflow
    """

    # TODO: Add AD and RD maps
    flow = pe.Workflow(name="reconstruction")
    inputnode = pe.Node(
        interface=util.IdentityInterface(fields=[
            "diffusion", "diffusion_resampled", "wm_mask_resampled", "grad"
        ]),
        name="inputnode",
    )
    outputnode = pe.Node(
        interface=util.IdentityInterface(
            fields=["DWI", "FA", "ADC", "tensor", "eigVec", "RF", "grad"],
            mandatory_inputs=True,
        ),
        name="outputnode",
    )

    # Flip gradient table
    flip_table = pe.Node(interface=FlipTable(), name="flip_table")

    flip_table.inputs.flipping_axis = config.flip_table_axis
    flip_table.inputs.delimiter = " "
    flip_table.inputs.header_lines = 0
    flip_table.inputs.orientation = "v"
    # fmt:off
    flow.connect([
        (inputnode, flip_table, [("grad", "table")]),
        (flip_table, outputnode, [("table", "grad")]),
    ])
    # fmt:on

    # Tensor
    mrtrix_tensor = pe.Node(interface=DWI2Tensor(), name="mrtrix_make_tensor")
    # fmt:off
    flow.connect([
        (inputnode, mrtrix_tensor, [("diffusion_resampled", "in_file")]),
        (flip_table, mrtrix_tensor, [("table", "encoding_file")]),
    ])
    # fmt:on

    # Tensor -> FA map
    mrtrix_tensor_metrics = pe.Node(
        interface=TensorMetrics(out_fa="FA.mif", out_adc="ADC.mif"),
        name="mrtrix_tensor_metrics",
    )
    convert_Tensor = pe.Node(
        interface=MRConvert(out_filename="dwi_tensor.nii.gz"),
        name="convert_tensor")
    convert_FA = pe.Node(interface=MRConvert(out_filename="FA.nii.gz"),
                         name="convert_FA")
    convert_ADC = pe.Node(interface=MRConvert(out_filename="ADC.nii.gz"),
                          name="convert_ADC")
    # fmt:off
    flow.connect([
        (mrtrix_tensor, convert_Tensor, [("tensor", "in_file")]),
        (mrtrix_tensor, mrtrix_tensor_metrics, [("tensor", "in_file")]),
        (mrtrix_tensor_metrics, convert_FA, [("out_fa", "in_file")]),
        (mrtrix_tensor_metrics, convert_ADC, [("out_adc", "in_file")]),
        (convert_Tensor, outputnode, [("converted", "tensor")]),
        (convert_FA, outputnode, [("converted", "FA")]),
        (convert_ADC, outputnode, [("converted", "ADC")]),
    ])
    # fmt:on

    # Tensor -> Eigenvectors
    mrtrix_eigVectors = pe.Node(interface=Tensor2Vector(),
                                name="mrtrix_eigenvectors")
    # fmt:off
    flow.connect([
        (mrtrix_tensor, mrtrix_eigVectors, [("tensor", "in_file")]),
        (mrtrix_eigVectors, outputnode, [("vector", "eigVec")]),
    ])
    # fmt:on

    # Constrained Spherical Deconvolution
    if config.local_model:
        print("CSD true")
        # Compute single fiber voxel mask
        mrtrix_erode = pe.Node(
            interface=Erode(out_filename="wm_mask_res_eroded.nii.gz"),
            name="mrtrix_erode",
        )
        mrtrix_erode.inputs.number_of_passes = 1
        mrtrix_erode.inputs.filtertype = "erode"
        mrtrix_mul_eroded_FA = pe.Node(interface=MRtrix_mul(),
                                       name="mrtrix_mul_eroded_FA")
        mrtrix_mul_eroded_FA.inputs.out_filename = "diffusion_resampled_tensor_FA_masked.mif"
        mrtrix_thr_FA = pe.Node(interface=MRThreshold(out_file="FA_th.mif"),
                                name="mrtrix_thr")
        mrtrix_thr_FA.inputs.abs_value = config.single_fib_thr
        # fmt:off
        flow.connect([
            (inputnode, mrtrix_erode, [("wm_mask_resampled", "in_file")]),
            (mrtrix_erode, mrtrix_mul_eroded_FA, [("out_file", "input2")]),
            (mrtrix_tensor_metrics, mrtrix_mul_eroded_FA, [("out_fa", "input1")
                                                           ]),
            (mrtrix_mul_eroded_FA, mrtrix_thr_FA, [("out_file", "in_file")]),
        ])
        # fmt:on

        # Compute single fiber response function
        mrtrix_rf = pe.Node(interface=EstimateResponseForSH(),
                            name="mrtrix_rf")
        mrtrix_rf.inputs.maximum_harmonic_order = int(config.lmax_order)
        mrtrix_rf.inputs.algorithm = "tournier"
        # mrtrix_rf.inputs.normalise = config.normalize_to_B0
        # fmt:off
        flow.connect([
            (inputnode, mrtrix_rf, [("diffusion_resampled", "in_file")]),
            (mrtrix_thr_FA, mrtrix_rf, [("thresholded", "mask_image")]),
            (flip_table, mrtrix_rf, [("table", "encoding_file")]),
        ])
        # fmt:on

        # Perform spherical deconvolution
        mrtrix_CSD = pe.Node(interface=ConstrainedSphericalDeconvolution(),
                             name="mrtrix_CSD")
        mrtrix_CSD.inputs.algorithm = "csd"
        mrtrix_CSD.inputs.maximum_harmonic_order = int(config.lmax_order)
        # mrtrix_CSD.inputs.normalise = config.normalize_to_B0

        convert_CSD = pe.Node(
            interface=MRConvert(
                out_filename="spherical_harmonics_image.nii.gz"),
            name="convert_CSD",
        )
        # fmt:off
        flow.connect([
            (inputnode, mrtrix_CSD, [("diffusion_resampled", "in_file")]),
            (mrtrix_rf, mrtrix_CSD, [("response", "response_file")]),
            (mrtrix_rf, outputnode, [("response", "RF")]),
            (inputnode, mrtrix_CSD, [("wm_mask_resampled", "mask_image")]),
            (flip_table, mrtrix_CSD, [("table", "encoding_file")]),
            (mrtrix_CSD, convert_CSD, [("spherical_harmonics_image", "in_file")
                                       ]),
            (convert_CSD, outputnode, [("converted", "DWI")])
            # (mrtrix_CSD,outputnode,[('spherical_harmonics_image','DWI')])
        ])
        # fmt:on
    else:
        # fmt:off
        flow.connect([(inputnode, outputnode, [("diffusion_resampled", "DWI")])
                      ])
        # fmt:on
    return flow