From d2b565c2f56987ac5837c6596b200ceec83a7d14 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Tue, 21 Apr 2015 15:15:36 +0200 Subject: [PATCH 1/4] Improve dipy TrackDensityMap --- nipype/interfaces/dipy/tracks.py | 134 +++++++++++++++++++------------ 1 file changed, 81 insertions(+), 53 deletions(-) diff --git a/nipype/interfaces/dipy/tracks.py b/nipype/interfaces/dipy/tracks.py index 1b820d1c89..74613465c5 100644 --- a/nipype/interfaces/dipy/tracks.py +++ b/nipype/interfaces/dipy/tracks.py @@ -1,15 +1,18 @@ # -*- coding: utf-8 -*- -"""Change directory to provide relative paths for doctests +""" +Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ -from nipype.interfaces.base import (TraitedSpec, BaseInterface, BaseInterfaceInputSpec, - File, isdefined, traits) +from nipype.interfaces.base import ( + TraitedSpec, BaseInterface, BaseInterfaceInputSpec, + File, isdefined, traits) from nipype.utils.filemanip import split_filename import os.path as op -import nibabel as nb, nibabel.trackvis as trk +import nibabel as nb +import nibabel.trackvis as trk from nipype.utils.misc import package_check import warnings @@ -27,60 +30,85 @@ class TrackDensityMapInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, - desc='The input TrackVis track file') + desc='The input TrackVis track file') + reference = File(exists=True, + desc='A reference file to define RAS coordinates space') + points_space = traits.Enum('rasmm', 'voxel', None, usedefault=True, + desc='coordinates of trk file') + voxel_dims = traits.List(traits.Float, minlen=3, maxlen=3, - desc='The size of each voxel in mm.') + desc='The size of each voxel in mm.') data_dims = traits.List(traits.Int, minlen=3, maxlen=3, - desc='The size of the image in voxels.') - out_filename = File('tdi.nii', usedefault=True, desc='The output filename for the tracks in TrackVis (.trk) format') + desc='The size of the image in voxels.') + out_filename = File('tdi.nii', usedefault=True, + desc=('The output filename for the tracks in TrackVis ' + '(.trk) format')) + class TrackDensityMapOutputSpec(TraitedSpec): out_file = File(exists=True) + class TrackDensityMap(BaseInterface): - """ - Creates a tract density image from a TrackVis track file using functions from dipy - - Example - ------- - - >>> import nipype.interfaces.dipy as dipy - >>> trk2tdi = dipy.TrackDensityMap() - >>> trk2tdi.inputs.in_file = 'converted.trk' - >>> trk2tdi.run() # doctest: +SKIP - """ - input_spec = TrackDensityMapInputSpec - output_spec = TrackDensityMapOutputSpec - - def _run_interface(self, runtime): - tracks, header = trk.read(self.inputs.in_file) - if not isdefined(self.inputs.data_dims): - data_dims = header['dim'] - else: - data_dims = self.inputs.data_dims - - if not isdefined(self.inputs.voxel_dims): - voxel_size = header['voxel_size'] - else: - voxel_size = self.inputs.voxel_dims - - affine = header['vox_to_ras'] - - streams = ((ii[0]) for ii in tracks) - data = density_map(streams, data_dims, voxel_size) - if data.max() < 2**15: - data = data.astype('int16') - - img = nb.Nifti1Image(data,affine) - out_file = op.abspath(self.inputs.out_filename) - nb.save(img, out_file) - iflogger.info('Track density map saved as {i}'.format(i=out_file)) - iflogger.info('Data Dimensions {d}'.format(d=data_dims)) - iflogger.info('Voxel Dimensions {v}'.format(v=voxel_size)) - return runtime - - def _list_outputs(self): - outputs = self._outputs().get() - outputs['out_file'] = op.abspath(self.inputs.out_filename) - return outputs + """ + Creates a tract density image from a TrackVis track file using functions + from dipy + + + Example + ------- + + >>> import nipype.interfaces.dipy as dipy + >>> trk2tdi = dipy.TrackDensityMap() + >>> trk2tdi.inputs.in_file = 'converted.trk' + >>> trk2tdi.run() # doctest: +SKIP + + """ + input_spec = TrackDensityMapInputSpec + output_spec = TrackDensityMapOutputSpec + + def _run_interface(self, runtime): + tracks, header = nbt.read(self.inputs.in_file) + streams = ((ii[0]) for ii in tracks) + + if isdefined(self.inputs.reference): + refnii = nb.load(self.inputs.reference) + affine = refnii.get_affine() + data_dims = refnii.get_shape()[:3] + kwargs = dict(affine=affine) + else: + iflogger.warn(('voxel_dims and data_dims are deprecated' + 'as of dipy 0.7.1. Please use reference ' + 'input instead')) + + if not isdefined(self.inputs.data_dims): + data_dims = header['dim'] + else: + data_dims = self.inputs.data_dims + if not isdefined(self.inputs.voxel_dims): + voxel_size = header['voxel_size'] + else: + voxel_size = self.inputs.voxel_dims + + affine = header['vox_to_ras'] + kwargs = dict(voxel_size=voxel_size) + + data = density_map(streams, data_dims, **kwargs) + data = data.astype(np.min_scalar_type(data.max())) + img = nb.Nifti1Image(data, affine) + out_file = op.abspath(self.inputs.out_filename) + nb.save(img, out_file) + + iflogger.info( + ('Track density map saved as {i}, size={d}, ' + 'dimensions={v}').format( + i=out_file, + d=img.get_shape(), + v=img.get_header().get_zooms())) + return runtime + + def _list_outputs(self): + outputs = self._outputs().get() + outputs['out_file'] = op.abspath(self.inputs.out_filename) + return outputs From edcd040bc166022578dbf90561a9376123f91ad6 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Tue, 21 Apr 2015 15:26:34 +0200 Subject: [PATCH 2/4] update auto test --- nipype/interfaces/dipy/tests/test_auto_TrackDensityMap.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nipype/interfaces/dipy/tests/test_auto_TrackDensityMap.py b/nipype/interfaces/dipy/tests/test_auto_TrackDensityMap.py index 763929ca5d..b58637b211 100644 --- a/nipype/interfaces/dipy/tests/test_auto_TrackDensityMap.py +++ b/nipype/interfaces/dipy/tests/test_auto_TrackDensityMap.py @@ -8,6 +8,9 @@ def test_TrackDensityMap_inputs(): ), out_filename=dict(usedefault=True, ), + points_space=dict(usedefault=True, + ), + reference=dict(), voxel_dims=dict(), ) inputs = TrackDensityMap.input_spec() From 0c7072fa3fc871c16fa96d9b5484a363349d7921 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Tue, 21 Apr 2015 15:29:05 +0200 Subject: [PATCH 3/4] update CHANGES --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 6ea2883c72..938b7103d8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ Next release ============ +* ENH: Improved TrackDensityMap of dipy (https://github.com/nipy/nipype/pull/1091) * ENH: New mesh.MeshWarpMaths to operate on surface-defined warpings (https://github.com/nipy/nipype/pull/1016) * FIX: Refactor P2PDistance, change name to ComputeMeshWarp, add regression tests, From 3c072e88b892c388764f8b413cf5df61121495b0 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Tue, 21 Apr 2015 15:39:44 +0200 Subject: [PATCH 4/4] Fix import --- nipype/interfaces/dipy/tracks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/dipy/tracks.py b/nipype/interfaces/dipy/tracks.py index 74613465c5..245d25f0a1 100644 --- a/nipype/interfaces/dipy/tracks.py +++ b/nipype/interfaces/dipy/tracks.py @@ -12,7 +12,7 @@ from nipype.utils.filemanip import split_filename import os.path as op import nibabel as nb -import nibabel.trackvis as trk +import nibabel.trackvis as nbt from nipype.utils.misc import package_check import warnings