Skip to content

Commit 6634223

Browse files
committed
Merge pull request #672 from beOn/spm_dicom
Spm dicom
2 parents 8b7a6d7 + 79bca5e commit 6634223

File tree

6 files changed

+99
-4
lines changed

6 files changed

+99
-4
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Next release
33

44
* ENH: SelectFiles: a streamlined version of DataGrabber
55
* ENH: New interfaces: spm.ResliceToReference, FuzzyOverlap, afni.AFNItoNIFTI
6+
spm.DicomImport
67
* ENH: W3C PROV support with optional RDF export built into Nipype
78

89
* FIX: Deals properly with 3d files in SPM Realign

nipype/interfaces/spm/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@
1010
from .model import (Level1Design, EstimateModel, EstimateContrast, Threshold,
1111
OneSampleTTestDesign, TwoSampleTTestDesign,
1212
PairedTTestDesign, MultipleRegressionDesign)
13-
from .utils import Analyze2nii, CalcCoregAffine, ApplyTransform, Reslice, ApplyInverseDeformation,ResliceToReference
13+
from .utils import (Analyze2nii, CalcCoregAffine, ApplyTransform, Reslice,
14+
ApplyInverseDeformation,ResliceToReference,DicomImport)
1415

nipype/interfaces/spm/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ def _make_matlab_command(self, contents, postscript=None):
413413
if self.mlab.inputs.mfile:
414414
if self.jobname in ['st', 'smooth', 'preproc', 'preproc8',
415415
'fmri_spec', 'fmri_est', 'factorial_design',
416-
'defs']:
416+
'defs', 'dicom']:
417417
# parentheses
418418
mscript += self._generate_job('jobs{1}.%s{1}.%s(1)' %
419419
(self.jobtype, self.jobname),

nipype/interfaces/spm/preprocess.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,9 @@ class CoregisterInputSpec(SPMCommandInputSpec):
264264
'nmi' - Normalised Mutual Information,
265265
'ecc' - Entropy Correlation Coefficient,
266266
'ncc' - Normalised Cross Correlation""")
267-
fwhm = traits.Float(field='eoptions.fwhm',
268-
desc='gaussian smoothing kernel width (mm)')
267+
fwhm = traits.List(traits.Float(), minlen=2, maxlen=2,
268+
field='eoptions.fwhm',
269+
desc='gaussian smoothing kernel width (mm)')
269270
separation = traits.List(traits.Float(), field='eoptions.sep',
270271
desc='sampling separation in mm')
271272
tolerance = traits.List(traits.Float(), field='eoptions.tol',

nipype/interfaces/spm/tests/test_utils.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,17 @@ def test_reslice():
5959
expected_interp = 'flags.interp = 1;\n'
6060
assert_equal(expected_interp in script, True)
6161
assert_equal('spm_reslice(invols, flags);' in script, True)
62+
63+
def test_dicom_import():
64+
dicom = example_data(infile = 'dicomdir/123456-1-1.dcm')
65+
di = spmu.DicomImport(matlab_cmd = 'mymatlab')
66+
assert_equal(di.inputs.matlab_cmd, 'mymatlab')
67+
assert_equal(di.inputs.output_dir_struct, 'flat')
68+
assert_equal(di.inputs.output_dir, './converted_dicom/')
69+
assert_equal(di.inputs.format, 'nii')
70+
assert_equal(di.inputs.icedims, False)
71+
assert_raises(TraitError,di.inputs.trait_set,output_dir_struct = 'wrong')
72+
assert_raises(TraitError,di.inputs.trait_set,format = 'FAT')
73+
assert_raises(TraitError,di.inputs.trait_set,in_files = ['does_sfd_not_32fn_exist.dcm'])
74+
di.inputs.in_files = [dicom]
75+
assert_equal(di.inputs.in_files, [dicom])

nipype/interfaces/spm/utils.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,3 +359,81 @@ def _list_outputs(self):
359359
_, fname = os.path.split(filename)
360360
outputs['out_files'].append(os.path.realpath('w%s' % fname))
361361
return outputs
362+
363+
class DicomImportInputSpec(SPMCommandInputSpec):
364+
in_files = InputMultiPath(
365+
File(exists=True),
366+
mandatory=True,
367+
field='data',
368+
desc='dicom files to be converted')
369+
output_dir_struct = traits.Enum(
370+
'flat', 'series', 'patname', 'patid_date', 'patid', 'date_time',
371+
field='root',
372+
usedefault=True,
373+
desc='directory structure for the output.')
374+
output_dir = traits.Str('./',
375+
field='outdir',
376+
usedefault=True,
377+
desc='output directory.')
378+
format = traits.Enum(
379+
'nii', 'img',
380+
field='convopts.format',
381+
usedefault=True,
382+
desc='output format.')
383+
icedims = traits.Bool(False,
384+
field='convopts.icedims',
385+
usedefault=True,
386+
desc='If image sorting fails, one can try using the additional\
387+
SIEMENS ICEDims information to create unique filenames.\
388+
Use this only if there would be multiple volumes with\
389+
exactly the same file names.')
390+
391+
class DicomImportOutputSpec(TraitedSpec):
392+
out_files = OutputMultiPath(File(exists=True),
393+
desc='converted files')
394+
395+
class DicomImport(SPMCommand):
396+
""" Uses spm to comvert DICOM files to nii or img+hdr.
397+
398+
Examples
399+
--------
400+
401+
>>> import nipype.interfaces.spm.utils as spmu
402+
>>> di = spmu.DicomImport()
403+
>>> di.inputs.in_files = ['functional_1.dcm', 'functional_2.dcm']
404+
>>> di.run() # doctest: +SKIP
405+
"""
406+
407+
input_spec = DicomImportInputSpec
408+
output_spec = DicomImportOutputSpec
409+
410+
_jobtype = 'util'
411+
_jobname = 'dicom'
412+
413+
def _format_arg(self, opt, spec, val):
414+
"""Convert input to appropriate format for spm
415+
"""
416+
if opt == 'in_files':
417+
return np.array(val, dtype=object)
418+
if opt == 'output_dir':
419+
return np.array([val], dtype=object)
420+
if opt == 'output_dir':
421+
return os.path.abspath(val)
422+
if opt == 'icedims':
423+
if val:
424+
return 1
425+
return 0
426+
return super(DicomImport, self)._format_arg(opt, spec, val)
427+
428+
def _run_interface(self, runtime):
429+
od = os.path.abspath(self.inputs.output_dir)
430+
if not os.path.isdir(od):
431+
os.mkdir(od)
432+
return super(DicomImport, self)._run_interface(runtime)
433+
434+
def _list_outputs(self):
435+
from glob import glob
436+
outputs = self._outputs().get()
437+
od = os.path.abspath(self.inputs.output_dir)
438+
outputs['out_files'] = glob(os.path.join(od, '*'))
439+
return outputs

0 commit comments

Comments
 (0)