@@ -1628,22 +1628,34 @@ def _list_outputs(self):
16281628
16291629
16301630class NewSegmentInputSpec (SPMCommandInputSpec ):
1631- channel_files = InputMultiPath (
1632- ImageFileSPM (exists = True ),
1633- mandatory = True ,
1634- desc = "A list of files to be segmented" ,
1635- field = "channel" ,
1636- copyfile = False ,
1637- )
1638- channel_info = traits .Tuple (
1639- traits .Float (),
1640- traits .Float (),
1641- traits .Tuple (traits .Bool , traits .Bool ),
1642- desc = """A tuple with the following fields:
1643- - bias reguralisation (0-10)
1644- - FWHM of Gaussian smoothness of bias
1645- - which maps to save (Field, Corrected) - a tuple of two boolean values""" ,
1646- field = "channel" ,
1631+ channels = traits .List (
1632+ traits .Tuple (
1633+ InputMultiPath (
1634+ ImageFileSPM (exists = True ),
1635+ mandatory = True ,
1636+ desc = "A list of files to be segmented" ,
1637+ field = "channel" ,
1638+ copyfile = False ,
1639+ ),
1640+ traits .Tuple (
1641+ traits .Float (),
1642+ traits .Float (),
1643+ traits .Tuple (traits .Bool , traits .Bool ),
1644+ desc = """A tuple with the following fields:
1645+ - bias reguralisation (0-10)
1646+ - FWHM of Gaussian smoothness of bias
1647+ - which maps to save (Field, Corrected) - a tuple of two boolean values""" ,
1648+ field = "channel" ,
1649+ )
1650+ ),
1651+ desc = """A list of tuples (one per each channel)
1652+ with the following fields:
1653+ - a list of channel files (only 1rst channel files will be segmented)
1654+ - a tuple with the following channel-specific info fields:
1655+ - bias reguralisation (0-10)
1656+ - FWHM of Gaussian smoothness of bias
1657+ - which maps to save (Field, Corrected) - a tuple of two boolean values""" ,
1658+ field = "channel" ,
16471659 )
16481660 tissues = traits .List (
16491661 traits .Tuple (
@@ -1719,23 +1731,24 @@ class NewSegment(SPMCommand):
17191731 """Use spm_preproc8 (New Segment) to separate structural images into
17201732 different tissue classes. Supports multiple modalities.
17211733
1722- NOTE: This interface currently supports single channel input only
1734+ NOTE: This interface supports multi- channel inputs
17231735
17241736 http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=43
17251737
17261738 Examples
17271739 --------
17281740 >>> import nipype.interfaces.spm as spm
17291741 >>> seg = spm.NewSegment()
1730- >>> seg.inputs.channel_files = 'structural.nii'
1731- >>> seg.inputs.channel_info = (0.0001, 60, (True, True))
1742+ >>> seg.inputs.channels = [('structural.nii',(0.0001, 60, (True, True)))]
17321743 >>> seg.run() # doctest: +SKIP
17331744
17341745 For VBM pre-processing [http://www.fil.ion.ucl.ac.uk/~john/misc/VBMclass10.pdf],
17351746 TPM.nii should be replaced by /path/to/spm8/toolbox/Seg/TPM.nii
17361747
17371748 >>> seg = NewSegment()
1738- >>> seg.inputs.channel_files = 'structural.nii'
1749+ >>> channel1= ('t1w.nii',(0.0001, 60, (True, True)))
1750+ >>> channel2= ('t2w.nii',(0.0001, 60, (True, True)))
1751+ >>> seg.inputs.channels = [channel1, channel2]
17391752 >>> tissue1 = (('TPM.nii', 1), 2, (True,True), (False, False))
17401753 >>> tissue2 = (('TPM.nii', 2), 2, (True,True), (False, False))
17411754 >>> tissue3 = (('TPM.nii', 3), 2, (True,False), (False, False))
@@ -1764,16 +1777,20 @@ def _format_arg(self, opt, spec, val):
17641777 """Convert input to appropriate format for spm
17651778 """
17661779
1767- if opt in ["channel_files" , "channel_info" ]:
1780+ #if opt in ["channel_files", "channel_info"]:
1781+ if opt == "channels" :
17681782 # structure have to be recreated because of some weird traits error
1769- new_channel = {}
1770- new_channel ["vols" ] = scans_for_fnames (self .inputs .channel_files )
1771- if isdefined (self .inputs .channel_info ):
1772- info = self .inputs .channel_info
1773- new_channel ["biasreg" ] = info [0 ]
1774- new_channel ["biasfwhm" ] = info [1 ]
1775- new_channel ["write" ] = [int (info [2 ][0 ]), int (info [2 ][1 ])]
1776- return [new_channel ]
1783+ new_channels = []
1784+ for channel in val :
1785+ new_channel = {}
1786+ new_channel ["vols" ] = scans_for_fnames (channel [0 ])
1787+ if isdefined (channel [1 ]):
1788+ info = channel [1 ]
1789+ new_channel ["biasreg" ] = info [0 ]
1790+ new_channel ["biasfwhm" ] = info [1 ]
1791+ new_channel ["write" ] = [int (info [2 ][0 ]), int (info [2 ][1 ])]
1792+ new_channels .append (new_channel )
1793+ return new_channels
17771794 elif opt == "tissues" :
17781795 new_tissues = []
17791796 for tissue in val :
@@ -1814,7 +1831,8 @@ def _list_outputs(self):
18141831 outputs ["normalized_class_images" ].append ([])
18151832 outputs ["modulated_class_images" ].append ([])
18161833
1817- for filename in self .inputs .channel_files :
1834+ # main outputs are generated for the first channel images only
1835+ for filename in self .inputs .channels [0 ][0 ]:
18181836 pth , base , ext = split_filename (filename )
18191837 if isdefined (self .inputs .tissues ):
18201838 for i , tissue in enumerate (self .inputs .tissues ):
@@ -1853,15 +1871,19 @@ def _list_outputs(self):
18531871 os .path .join (pth , "y_%s.nii" % base )
18541872 )
18551873
1856- if isdefined (self .inputs .channel_info ):
1857- if self .inputs .channel_info [2 ][0 ]:
1858- outputs ["bias_field_images" ].append (
1859- os .path .join (pth , "BiasField_%s.nii" % (base ))
1860- )
1861- if self .inputs .channel_info [2 ][1 ]:
1862- outputs ["bias_corrected_images" ].append (
1863- os .path .join (pth , "m%s.nii" % (base ))
1864- )
1874+ # bias field related images are generated for images in all channels
1875+ for channel in self .inputs .channels :
1876+ for filename in channel [0 ]:
1877+ pth , base , ext = split_filename (filename )
1878+ if isdefined (channel [1 ]):
1879+ if channel [1 ][2 ][0 ]:
1880+ outputs ["bias_field_images" ].append (
1881+ os .path .join (pth , "BiasField_%s.nii" % (base ))
1882+ )
1883+ if channel [1 ][2 ][1 ]:
1884+ outputs ["bias_corrected_images" ].append (
1885+ os .path .join (pth , "m%s.nii" % (base ))
1886+ )
18651887 return outputs
18661888
18671889
0 commit comments