Skip to content

Commit 087b488

Browse files
committed
Merge branch 'pr/662'
2 parents a7fd06c + ce88698 commit 087b488

File tree

23 files changed

+1547
-888
lines changed

23 files changed

+1547
-888
lines changed

CHANGES

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ Next release
3131
* API: 'name' is now a positional argument for Workflow, Node, and MapNode constructors
3232
* API: SPM now defaults to SPM8 or SPM12b job format
3333

34+
* ENH: New FSL interfaces: fsl.PrepareFieldmap, fsl.TOPUP, fsl.ApplyTOPUP, fsl.Eddy
35+
* ENH: New workflows: nipype.workflows.dmri.fsl.epi.[fieldmap_correction&topup_correction]
36+
3437
Release 0.8.0 (May 8, 2013)
3538
===========================
3639

nipype/algorithms/misc.py

Lines changed: 61 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ class PickAtlasOutputSpec(TraitedSpec):
6161

6262

6363
class PickAtlas(BaseInterface):
64-
6564
'''
6665
Returns ROI masks given an atlas and a list of labels. Supports dilation
6766
and left right masking (assuming the atlas is properly aligned).
@@ -180,7 +179,6 @@ class ModifyAffineOutputSpec(TraitedSpec):
180179

181180

182181
class ModifyAffine(BaseInterface):
183-
184182
'''
185183
Left multiplies the affine matrix with a specified values. Saves the volume
186184
as a nifti file.
@@ -245,7 +243,6 @@ class DistanceOutputSpec(TraitedSpec):
245243

246244

247245
class Distance(BaseInterface):
248-
249246
'''
250247
Calculates distance between two volumes.
251248
'''
@@ -281,13 +278,7 @@ def _eucl_min(self, nii1, nii2):
281278
dist_matrix = cdist(set1_coordinates.T, set2_coordinates.T)
282279
(point1, point2) = np.unravel_index(
283280
np.argmin(dist_matrix), dist_matrix.shape)
284-
return (
285-
euclidean(
286-
set1_coordinates.T[point1, :],
287-
set2_coordinates.T[point2, :]
288-
),
289-
set1_coordinates.T[point1, :], set2_coordinates.T[point2, :]
290-
)
281+
return (euclidean(set1_coordinates.T[point1, :], set2_coordinates.T[point2, :]), set1_coordinates.T[point1, :], set2_coordinates.T[point2, :])
291282

292283
def _eucl_cog(self, nii1, nii2):
293284
origdata1 = nii1.get_data().astype(np.bool)
@@ -415,7 +406,6 @@ class OverlapOutputSpec(TraitedSpec):
415406

416407

417408
class Overlap(BaseInterface):
418-
419409
"""
420410
Calculates various overlap measures between two maps.
421411
@@ -478,47 +468,25 @@ def _list_outputs(self):
478468

479469

480470
class FuzzyOverlapInputSpec(BaseInterfaceInputSpec):
481-
in_ref = InputMultiPath(
482-
File(exists=True), mandatory=True,
483-
desc="Reference image. Requires the same dimensions as in_tst."
484-
)
485-
in_tst = InputMultiPath(
486-
File(exists=True), mandatory=True,
487-
desc="Test image. Requires the same dimensions as in_ref."
488-
)
489-
weighting = traits.Enum(
490-
"none", "volume", "squared_vol",
491-
desc='""none": no class-overlap weighting is performed\
492-
"volume": computed class-overlaps are weighted by class volume\
493-
"squared_vol": computed class-overlaps are weighted by the squared\
494-
volume of the class', usedefault=True
495-
)
496-
out_file = File(
497-
"diff.nii",
498-
desc="alternative name for resulting difference-map",
499-
usedefault=True
500-
)
471+
in_ref = InputMultiPath( File(exists=True), mandatory=True,
472+
desc="Reference image. Requires the same dimensions as in_tst.")
473+
in_tst = InputMultiPath( File(exists=True), mandatory=True,
474+
desc="Test image. Requires the same dimensions as in_ref.")
475+
weighting = traits.Enum("none", "volume", "squared_vol", desc='""none": no class-overlap weighting is performed\
476+
"volume": computed class-overlaps are weighted by class volume\
477+
"squared_vol": computed class-overlaps are weighted by the squared volume of the class',usedefault=True)
478+
out_file = File("diff.nii", desc="alternative name for resulting difference-map", usedefault=True)
501479

502480

503481
class FuzzyOverlapOutputSpec(TraitedSpec):
504-
jaccard = traits.Float(desc="Fuzzy Jaccard Index (fJI), all the classes")
505-
dice = traits.Float(desc="Fuzzy Dice Index (fDI), all the classes")
506-
diff_file = File(
507-
exists=True, desc="resulting difference-map of all classes,\
508-
using the chosen weighting"
509-
)
510-
class_fji = traits.List(
511-
traits.Float(),
512-
desc="Array containing the fJIs of each computed class"
513-
)
514-
class_fdi = traits.List(
515-
traits.Float(),
516-
desc="Array containing the fDIs of each computed class"
517-
)
482+
jaccard = traits.Float( desc="Fuzzy Jaccard Index (fJI), all the classes" )
483+
dice = traits.Float( desc="Fuzzy Dice Index (fDI), all the classes" )
484+
diff_file = File(exists=True, desc="resulting difference-map of all classes, using the chosen weighting" )
485+
class_fji = traits.List( traits.Float(), desc="Array containing the fJIs of each computed class" )
486+
class_fdi = traits.List( traits.Float(), desc="Array containing the fDIs of each computed class" )
518487

519488

520489
class FuzzyOverlap(BaseInterface):
521-
522490
"""
523491
Calculates various overlap measures between two maps, using the fuzzy
524492
definition proposed in: Crum et al., Generalized Overlap Measures for
@@ -539,77 +507,76 @@ class FuzzyOverlap(BaseInterface):
539507
>>> res = overlap.run() # doctest: +SKIP
540508
"""
541509

542-
input_spec = FuzzyOverlapInputSpec
510+
input_spec = FuzzyOverlapInputSpec
543511
output_spec = FuzzyOverlapOutputSpec
544512

545513
def _run_interface(self, runtime):
546514
ncomp = len(self.inputs.in_ref)
547-
assert(ncomp == len(self.inputs.in_tst))
548-
weights = np.ones(shape=ncomp)
515+
assert( ncomp == len(self.inputs.in_tst) )
516+
weights = np.ones( shape=ncomp )
517+
518+
img_ref = np.array( [ nb.load( fname ).get_data() for fname in self.inputs.in_ref ] )
519+
img_tst = np.array( [ nb.load( fname ).get_data() for fname in self.inputs.in_tst ] )
549520

550-
img_ref = np.array([nb.load(fname).get_data()
551-
for fname in self.inputs.in_ref])
552-
img_tst = np.array([nb.load(fname).get_data()
553-
for fname in self.inputs.in_tst])
554521

555522
msk = np.sum(img_ref, axis=0)
556-
msk[msk > 0] = 1.0
523+
msk[msk>0] = 1.0
557524
tst_msk = np.sum(img_tst, axis=0)
558-
tst_msk[tst_msk > 0] = 1.0
525+
tst_msk[tst_msk>0] = 1.0
526+
527+
#check that volumes are normalized
528+
#img_ref[:][msk>0] = img_ref[:][msk>0] / (np.sum( img_ref, axis=0 ))[msk>0]
529+
#img_tst[tst_msk>0] = img_tst[tst_msk>0] / np.sum( img_tst, axis=0 )[tst_msk>0]
559530

560531
self._jaccards = []
561532
volumes = []
562533

563-
diff_im = np.zeros(img_ref.shape)
534+
diff_im = np.zeros( img_ref.shape )
564535

565-
for ref_comp, tst_comp, diff_comp in zip(img_ref, img_tst, diff_im):
566-
num = np.minimum(ref_comp, tst_comp)
567-
ddr = np.maximum(ref_comp, tst_comp)
568-
diff_comp[ddr > 0] += 1.0 - (num[ddr > 0] / ddr[ddr > 0])
569-
self._jaccards.append(np.sum(num) / np.sum(ddr))
570-
volumes.append(np.sum(ref_comp))
536+
for ref_comp, tst_comp, diff_comp in zip( img_ref, img_tst, diff_im ):
537+
num = np.minimum( ref_comp, tst_comp )
538+
ddr = np.maximum( ref_comp, tst_comp )
539+
diff_comp[ddr>0]+= 1.0-(num[ddr>0]/ddr[ddr>0])
540+
self._jaccards.append( np.sum( num ) / np.sum( ddr ) )
541+
volumes.append( np.sum( ref_comp ) )
571542

572-
self._dices = 2.0 * \
573-
np.array(self._jaccards) / (np.array(self._jaccards) + 1.0)
543+
self._dices = 2.0*np.array(self._jaccards) / (np.array(self._jaccards) +1.0 )
574544

575545
if self.inputs.weighting != "none":
576546
weights = 1.0 / np.array(volumes)
577547
if self.inputs.weighting == "squared_vol":
578-
weights = weights ** 2
548+
weights = weights**2
579549

580-
weights = weights / np.sum(weights)
550+
weights = weights / np.sum( weights )
581551

582-
setattr(self, '_jaccard', np.sum(weights * self._jaccards))
583-
setattr(self, '_dice', np.sum(weights * self._dices))
552+
setattr( self, '_jaccard', np.sum( weights * self._jaccards ) )
553+
setattr( self, '_dice', np.sum( weights * self._dices ) )
584554

585-
diff = np.zeros(diff_im[0].shape)
586555

587-
for w, ch in zip(weights, diff_im):
588-
ch[msk == 0] = 0
589-
diff += w * ch
556+
diff = np.zeros( diff_im[0].shape )
590557

591-
nb.save(
592-
nb.Nifti1Image(
593-
diff,
594-
nb.load(self.inputs.in_ref[0]).get_affine(),
595-
nb.load(self.inputs.in_ref[0]).get_header()
596-
),
597-
self.inputs.out_file
598-
)
558+
for w,ch in zip(weights,diff_im):
559+
ch[msk==0] = 0
560+
diff+= w* ch
561+
562+
nb.save(nb.Nifti1Image(diff, nb.load( self.inputs.in_ref[0]).get_affine(),
563+
nb.load( self.inputs.in_ref[0]).get_header()), self.inputs.out_file )
599564

565+
600566
return runtime
601567

602568
def _list_outputs(self):
603569
outputs = self._outputs().get()
604570
for method in ("dice", "jaccard"):
605571
outputs[method] = getattr(self, '_' + method)
572+
#outputs['volume_difference'] = self._volume
606573
outputs['diff_file'] = os.path.abspath(self.inputs.out_file)
607-
outputs['class_fji'] = np.array(
608-
self._jaccards).astype(float).tolist()
609-
outputs['class_fdi'] = self._dices.astype(float).tolist()
574+
outputs['class_fji'] = np.array(self._jaccards).astype(float).tolist();
575+
outputs['class_fdi']= self._dices.astype(float).tolist();
610576
return outputs
611577

612578

579+
613580
class CreateNiftiInputSpec(BaseInterfaceInputSpec):
614581
data_file = File(exists=True, mandatory=True, desc="ANALYZE img file")
615582
header_file = File(
@@ -664,7 +631,6 @@ class TSNROutputSpec(TraitedSpec):
664631

665632

666633
class TSNR(BaseInterface):
667-
668634
"""Computes the time-course SNR for a time series
669635
670636
Typically you want to run this on a realigned time-series.
@@ -742,7 +708,6 @@ class GunzipOutputSpec(TraitedSpec):
742708

743709

744710
class Gunzip(BaseInterface):
745-
746711
"""
747712
748713
"""
@@ -784,7 +749,7 @@ def matlab2csv(in_array, name, reshape):
784749
if reshape:
785750
if len(np.shape(output_array)) > 1:
786751
output_array = np.reshape(output_array, (
787-
np.shape(output_array)[0] * np.shape(output_array)[1], 1))
752+
np.shape(output_array)[0]*np.shape(output_array)[1], 1))
788753
iflogger.info(np.shape(output_array))
789754
output_name = op.abspath(name + '.csv')
790755
np.savetxt(output_name, output_array, delimiter=',')
@@ -808,7 +773,6 @@ class Matlab2CSVOutputSpec(TraitedSpec):
808773

809774

810775
class Matlab2CSV(BaseInterface):
811-
812776
"""
813777
Simple interface to save the components of a MATLAB .mat file as a text
814778
file with comma-separated values (CSVs).
@@ -841,10 +805,7 @@ def _run_interface(self, runtime):
841805
if isinstance(in_dict[key][0], np.ndarray):
842806
saved_variables.append(key)
843807
else:
844-
iflogger.info(
845-
'One of the keys in the input file, {k},\
846-
is not a Numpy array'.format(k=key)
847-
)
808+
iflogger.info('One of the keys in the input file, {k}, is not a Numpy array'.format(k=key))
848809

849810
if len(saved_variables) > 1:
850811
iflogger.info(
@@ -910,9 +871,7 @@ def merge_csvs(in_list):
910871
)
911872
except ValueError, ex:
912873
in_array = np.loadtxt(
913-
in_file, delimiter=',', skiprows=1,
914-
usecols=range(1, n_cols - 1)
915-
)
874+
in_file, delimiter=',', skiprows=1, usecols=range(1, n_cols-1))
916875
if idx == 0:
917876
out_array = in_array
918877
else:
@@ -930,7 +889,7 @@ def remove_identical_paths(in_files):
930889
out_names = list()
931890
commonprefix = op.commonprefix(in_files)
932891
lastslash = commonprefix.rfind('/')
933-
commonpath = commonprefix[0:(lastslash + 1)]
892+
commonpath = commonprefix[0:(lastslash+1)]
934893
for fileidx, in_file in enumerate(in_files):
935894
path, name, ext = split_filename(in_file)
936895
in_file = op.join(path, name)
@@ -948,10 +907,10 @@ def maketypelist(rowheadings, shape, extraheadingBool, extraheading):
948907
if rowheadings:
949908
typelist.append(('heading', 'a40'))
950909
if len(shape) > 1:
951-
for idx in range(1, (min(shape) + 1)):
910+
for idx in range(1, (min(shape)+1)):
952911
typelist.append((str(idx), float))
953912
else:
954-
for idx in range(1, (shape[0] + 1)):
913+
for idx in range(1, (shape[0]+1)):
955914
typelist.append((str(idx), float))
956915
if extraheadingBool:
957916
typelist.append((extraheading, 'a40'))
@@ -966,13 +925,13 @@ def makefmtlist(output_array, typelist, rowheadingsBool,
966925
fmtlist.append('%s')
967926
if len(shape) > 1:
968927
output = np.zeros(max(shape), typelist)
969-
for idx in range(1, min(shape) + 1):
970-
output[str(idx)] = output_array[:, idx - 1]
928+
for idx in range(1, min(shape)+1):
929+
output[str(idx)] = output_array[:, idx-1]
971930
fmtlist.append('%f')
972931
else:
973932
output = np.zeros(1, typelist)
974-
for idx in range(1, len(output_array) + 1):
975-
output[str(idx)] = output_array[idx - 1]
933+
for idx in range(1, len(output_array)+1):
934+
output[str(idx)] = output_array[idx-1]
976935
fmtlist.append('%f')
977936
if extraheadingBool:
978937
fmtlist.append('%s')
@@ -1007,7 +966,6 @@ class MergeCSVFilesOutputSpec(TraitedSpec):
1007966

1008967

1009968
class MergeCSVFiles(BaseInterface):
1010-
1011969
"""
1012970
This interface is designed to facilitate data loading in the R environment.
1013971
It takes input CSV files and merges them into a single CSV file.
@@ -1144,7 +1102,6 @@ class AddCSVColumnOutputSpec(TraitedSpec):
11441102

11451103

11461104
class AddCSVColumn(BaseInterface):
1147-
11481105
"""
11491106
Short interface to add an extra column and field to a text file
11501107
@@ -1206,7 +1163,6 @@ class CalculateNormalizedMomentsOutputSpec(TraitedSpec):
12061163

12071164

12081165
class CalculateNormalizedMoments(BaseInterface):
1209-
12101166
"""
12111167
Calculates moments of timeseries.
12121168
@@ -1248,4 +1204,4 @@ def calc_moments(timeseries_file, moment):
12481204
m2 = stats.moment(timeseries, 2, axis=0)
12491205
m3 = stats.moment(timeseries, moment, axis=0)
12501206
zero = (m2 == 0)
1251-
return np.where(zero, 0, m3 / m2 ** (moment / 2.0))
1207+
return np.where(zero, 0, m3 / m2**(moment/2.0))

nipype/interfaces/fsl/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@
1515
from .utils import (Smooth, Merge, ExtractROI, Split, ImageMaths, ImageMeants,
1616
ImageStats, FilterRegressor, Overlay, Slicer,
1717
PlotTimeSeries, PlotMotionParams, ConvertXFM,
18-
SwapDimensions, PowerSpectrum, SigLoss, Reorient2Std,
18+
SwapDimensions, PowerSpectrum, Reorient2Std,
1919
Complex, InvWarp)
20-
from .dti import (EddyCorrect, BEDPOSTX, DTIFit, ProbTrackX, VecReg, ProjThresh,
20+
21+
from .epi import (PrepareFieldmap, TOPUP, ApplyTOPUP, Eddy, EPIDeWarp,
22+
SigLoss, EddyCorrect)
23+
24+
from .dti import (BEDPOSTX, DTIFit, ProbTrackX, VecReg, ProjThresh,
2125
FindTheBiggest, DistanceMap, TractSkeleton, XFibres,
2226
MakeDyadicVectors)
2327
from .maths import (ChangeDataType, Threshold, MeanImage, ApplyMask,

0 commit comments

Comments
 (0)