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
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
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
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
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
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