Skip to content

[WIP] Major refactor of input/output specs and autonaming #1240

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 61 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
882b32d
name_source now supported at BaseInterface level
oesteban Oct 9, 2015
8fbe7bd
remove call to _filename_from_source
oesteban Oct 9, 2015
90daeea
adding keep_extension=False to failing afni interfaces
oesteban Oct 9, 2015
148529c
update CHANGES
oesteban Oct 9, 2015
f8dfe7f
re-enable _overload_extension
oesteban Oct 9, 2015
f591295
run _gen_filename only when value is not set
oesteban Oct 9, 2015
3cffec0
fixing doctests
oesteban Oct 9, 2015
304fa3a
fix fsl.utils.WarpUtils name_source input
oesteban Oct 9, 2015
9ea4fe1
make specs
oesteban Oct 9, 2015
530abd2
fix doctest of Copy in afni
oesteban Oct 9, 2015
748439a
make-before-commit done
oesteban Oct 9, 2015
b85245b
Merge branch 'master' into enh/NameSourceInBaseInterface
oesteban Feb 4, 2016
70808df
added implementation of _list_outputs to BaseInterface
oesteban Feb 5, 2016
95c5292
Merge branch 'master' into enh/NameSourceInBaseInterface
Feb 11, 2016
779485c
add pylint disable
Feb 12, 2016
26a67fe
fix NotImplementedError in BaseInterface._list_outputs
Feb 12, 2016
45bcf99
Merge branch 'master' into enh/NameSourceInBaseInterface
Feb 12, 2016
aa3b244
update branch, although it is still failing
Feb 12, 2016
87ea1ea
separate specs and interfaces
Feb 13, 2016
28226e7
Merge branch 'enh/NameSourceInBaseInterface' of github.com:oesteban/n…
oesteban Feb 14, 2016
2829791
refactoring inputs...
oesteban Feb 15, 2016
be44a2d
Fixing problems with new inputs system
Feb 15, 2016
99ef50c
refactoring ongoing...
oesteban Feb 16, 2016
d69724a
refactoring in progress...
Feb 16, 2016
9b1212b
fixing errors, updating deprecations....
Feb 17, 2016
8d8826f
fixing errors
Feb 17, 2016
945fc3b
replace old outputs references
Feb 17, 2016
84d4347
replace all outputs getters
Feb 17, 2016
17b3ece
removing all output_spec().get()
Feb 17, 2016
96cd799
finishing with preprocess
Feb 17, 2016
b070b06
revert base, update preprocess
Feb 17, 2016
feb784c
Merge branch 'master' into enh/NameSourceInBaseInterface
Feb 17, 2016
8525c1e
replace all docstrings with single quotes
Feb 17, 2016
2d16732
fixing errors generated with autoreplacement
Feb 17, 2016
303945d
revert back changes in utils
Feb 17, 2016
cd828e7
correct wrongly indented _list_outputs
Feb 17, 2016
84801d0
fix syntax errors
Feb 17, 2016
e90f52c
fix syntax errors
Feb 17, 2016
198e13b
fix syntax errors
Feb 17, 2016
bb8d396
replace all remaining list_outputs
Feb 17, 2016
40a6773
remove all return outputs
Feb 17, 2016
0e3e29c
fix syntax errors
Feb 17, 2016
838940c
fixing AFNI
Feb 18, 2016
97d4c3e
AFNI passing tests
Feb 18, 2016
8cca288
ants almost passing
Feb 18, 2016
ce6eb1e
added new trait GenFile
oesteban Feb 18, 2016
99225be
adapted some interfaces to the new GenFile trait
oesteban Feb 18, 2016
39c309c
removed namesource code from specs, update BET
oesteban Feb 18, 2016
e94a700
use new template parameter
Feb 18, 2016
9f059ee
added new GenMultiFile
Feb 18, 2016
5657fbd
finished the automated generation of multipaths
Feb 18, 2016
4c58ad7
updated specs, algorithms updated
Feb 18, 2016
507af7c
minor fixes afni
Feb 18, 2016
a5859a3
fix test that generated files in-place
Feb 18, 2016
88d4bec
fixed afni (except for one test of copy3d)
oesteban Feb 19, 2016
c17c343
investigating the extension stripping problem
Feb 20, 2016
933cc40
advancing in refactoring fsl
Feb 20, 2016
cac167a
fix Cluster
Feb 20, 2016
95e9734
minor fixes in fsl.model
oesteban Feb 20, 2016
ef0caf5
added complex substring indexing in replacement
oesteban Feb 20, 2016
5f1df92
first use of the first optional substitution pattern
oesteban Feb 20, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Next release
============

* ENH: The name_source feature now available for all Interfaces derived from BaseInterface
(https://github.com/nipy/nipype/pull/1240)
* ENH: New interfaces in dipy: RESTORE, EstimateResponseSH, CSD and StreamlineTractography
(https://github.com/nipy/nipype/pull/1090)
* ENH: Added interfaces of AFNI (https://github.com/nipy/nipype/pull/1360,
Expand Down
82 changes: 49 additions & 33 deletions nipype/algorithms/icc.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,52 @@
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""
Algorithms to compute the Interclass Correlation Coefficient

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 __future__ import division
from builtins import range
import os
import numpy as np
from numpy import ones, kron, mean, eye, hstack, dot, tile
from scipy.linalg import pinv
from ..interfaces.base import BaseInterfaceInputSpec, TraitedSpec, \
BaseInterface, traits, File
import nibabel as nb
import numpy as np
import os

from builtins import range
from ..interfaces.base import (traits, File, BaseInterface, BaseInterfaceInputSpec,
TraitedSpec)

class ICCInputSpec(BaseInterfaceInputSpec):
subjects_sessions = traits.List(traits.List(File(exists=True)),
desc="n subjects m sessions 3D stat files",
mandatory=True)
mask = File(exists=True, mandatory=True)
icc_map = File('icc_map.nii', desc='name of output ICC map')
session_var_map = File('session_var_map.nii', desc="variance between sessions")
session_F_map = File('session_F_map.nii', desc="F map of sessions")
subject_var_map = File('subject_var_map.nii', desc="variance between subjects")


class ICCOutputSpec(TraitedSpec):
icc_map = File(exists=True)
session_var_map = File(exists=True, desc="variance between sessions")
session_F_map = File(exists=True, desc="variance between sessions")
subject_var_map = File(exists=True, desc="variance between subjects")


class ICC(BaseInterface):
'''
"""
Calculates Interclass Correlation Coefficient (3,1) as defined in
P. E. Shrout & Joseph L. Fleiss (1979). "Intraclass Correlations: Uses in
Assessing Rater Reliability". Psychological Bulletin 86 (2): 420-428. This
particular implementation is aimed at relaibility (test-retest) studies.
'''
"""
input_spec = ICCInputSpec
output_spec = ICCOutputSpec

Expand All @@ -44,48 +62,46 @@ def _run_interface(self, runtime):
session_var = np.zeros(session_datas[0][0].shape)
subject_var = np.zeros(session_datas[0][0].shape)

for x in range(icc.shape[0]):
Y = all_data[x, :, :]
icc[x], subject_var[x], session_var[x], session_F[x], _, _ = ICC_rep_anova(Y)
for i in range(icc.shape[0]):
data = all_data[i, :, :]
icc[i], subject_var[i], session_var[i], session_F[i], _, _ = ICC_rep_anova(data)

nim = nb.load(self.inputs.subjects_sessions[0][0])
new_data = np.zeros(nim.shape)
new_data[maskdata] = icc.reshape(-1,)
new_img = nb.Nifti1Image(new_data, nim.affine, nim.header)
nb.save(new_img, 'icc_map.nii')
nb.save(new_img, self.inputs.icc_map)

new_data = np.zeros(nim.shape)
new_data[maskdata] = session_var.reshape(-1,)
new_img = nb.Nifti1Image(new_data, nim.affine, nim.header)
nb.save(new_img, 'session_var_map.nii')
nb.save(new_img, self.inputs.session_var_map)

new_data = np.zeros(nim.shape)
new_data[maskdata] = subject_var.reshape(-1,)
new_img = nb.Nifti1Image(new_data, nim.affine, nim.header)
nb.save(new_img, 'subject_var_map.nii')
nb.save(new_img, self.inputs.subject_var_map.nii)

new_data = np.zeros(nim.shape)
new_data[maskdata] = session_F.reshape(-1,)
new_img = nb.Nifti1Image(new_data, nim.affine, nim.header)
nb.save(new_img, self.inputs.session_F_map)
return runtime

def _list_outputs(self):
outputs = self._outputs().get()
outputs['icc_map'] = os.path.abspath('icc_map.nii')
outputs['sessions_F_map'] = os.path.abspath('sessions_F_map.nii')
outputs['session_var_map'] = os.path.abspath('session_var_map.nii')
outputs['subject_var_map'] = os.path.abspath('subject_var_map.nii')
return outputs


def ICC_rep_anova(Y):
'''
the data Y are entered as a 'table' ie subjects are in rows and repeated
def ICC_rep_anova(data):
"""
the data (Y) are entered as a 'table' ie subjects are in rows and repeated
measures in columns

One Sample Repeated measure ANOVA

Y = XB + E with X = [FaTor / Subjects]
'''
.. math::

Y = XB + E with X = [FaTor / Subjects]
"""

[nb_subjects, nb_conditions] = Y.shape
[nb_subjects, nb_conditions] = data.shape
dfc = nb_conditions - 1
dfe = (nb_subjects - 1) * dfc
dfr = nb_subjects - 1
Expand All @@ -94,25 +110,25 @@ def ICC_rep_anova(Y):
# ------------------------------------

# Sum Square Total
mean_Y = mean(Y)
SST = ((Y - mean_Y) ** 2).sum()
mean_Y = mean(data)
SST = ((data - mean_Y) ** 2).sum()

# create the design matrix for the different levels
x = kron(eye(nb_conditions), ones((nb_subjects, 1))) # sessions
x0 = tile(eye(nb_subjects), (nb_conditions, 1)) # subjects
X = hstack([x, x0])

# Sum Square Error
predicted_Y = dot(dot(dot(X, pinv(dot(X.T, X))), X.T), Y.flatten('F'))
residuals = Y.flatten('F') - predicted_Y
predicted_Y = dot(dot(dot(X, pinv(dot(X.T, X))), X.T), data.flatten('F'))
residuals = data.flatten('F') - predicted_Y
SSE = (residuals ** 2).sum()

residuals.shape = Y.shape
residuals.shape = data.shape

MSE = SSE / dfe

# Sum square session effect - between colums/sessions
SSC = ((mean(Y, 0) - mean_Y) ** 2).sum() * nb_subjects
SSC = ((mean(data, 0) - mean_Y) ** 2).sum() * nb_subjects
MSC = SSC / dfc / nb_subjects

session_effect_F = MSC / MSE
Expand Down
80 changes: 20 additions & 60 deletions nipype/algorithms/mesh.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
'''
"""
Miscellaneous algorithms for 2D contours and 3D triangularized meshes handling

Change directory to provide relative paths for doctests
Expand All @@ -9,21 +9,19 @@
>>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data'))
>>> os.chdir(datadir)

'''
"""
from __future__ import division
from builtins import zip

import os.path as op
from warnings import warn

import numpy as np
from numpy import linalg as nla

from .. import logging
from ..external.six import string_types
from ..interfaces.base import (BaseInterface, traits, TraitedSpec, File,
BaseInterfaceInputSpec)
iflogger = logging.getLogger('interface')
from ..interfaces.base import traits, File, GenFile, BaseInterface, BaseInterfaceInputSpec, TraitedSpec

IFLOGGER = logging.getLogger('interface')


class TVTKBaseInterface(BaseInterface):
Expand All @@ -35,7 +33,7 @@ def __init__(self, **inputs):
from tvtk.tvtk_classes.vtk_version import vtk_build_version
self._vtk_major = int(vtk_build_version[0])
except ImportError:
iflogger.warning('VTK version-major inspection using tvtk failed.')
IFLOGGER.warning('VTK version-major inspection using tvtk failed.')

super(TVTKBaseInterface, self).__init__(**inputs)

Expand All @@ -47,9 +45,8 @@ class WarpPointsInputSpec(BaseInterfaceInputSpec):
desc=('dense deformation field to be applied'))
interp = traits.Enum('cubic', 'nearest', 'linear', usedefault=True,
mandatory=True, desc='interpolation')
out_points = File(name_source='points', name_template='%s_warped',
output_name='out_points', keep_extension=True,
desc='the warped point set')
out_points = GenFile(template='{points}_warped', keep_extension=True,
desc='the warped point set')


class WarpPointsOutputSpec(TraitedSpec):
Expand Down Expand Up @@ -77,22 +74,6 @@ class WarpPoints(TVTKBaseInterface):
input_spec = WarpPointsInputSpec
output_spec = WarpPointsOutputSpec

def _gen_fname(self, in_file, suffix='generated', ext=None):
import os.path as op

fname, fext = op.splitext(op.basename(in_file))

if fext == '.gz':
fname, fext2 = op.splitext(fname)
fext = fext2 + fext

if ext is None:
ext = fext

if ext[0] == '.':
ext = ext[1:]
return op.abspath('%s_%s.%s' % (fname, suffix, ext))

def _run_interface(self, runtime):
import nibabel as nb
import numpy as np
Expand Down Expand Up @@ -137,19 +118,10 @@ def _run_interface(self, runtime):
else:
w.set_input_data_object(mesh)

w.file_name = self._gen_fname(self.inputs.points,
suffix='warped',
ext='.vtk')
w.file_name = self.inputs.out_points
w.write()
return runtime

def _list_outputs(self):
outputs = self._outputs().get()
outputs['out_points'] = self._gen_fname(self.inputs.points,
suffix='warped',
ext='.vtk')
return outputs


class ComputeMeshWarpInputSpec(BaseInterfaceInputSpec):
surface1 = File(exists=True, mandatory=True,
Expand Down Expand Up @@ -277,15 +249,12 @@ def _run_interface(self, runtime):

writer.write()

self._distance = np.average(errvector, weights=weights)
return runtime
_distance = np.average(errvector, weights=weights)

def _list_outputs(self):
outputs = self._outputs().get()
outputs['out_file'] = op.abspath(self.inputs.out_file)
outputs['out_warp'] = op.abspath(self.inputs.out_warp)
outputs['distance'] = self._distance
return outputs
self.outputs.out_file = op.abspath(self.inputs.out_file)
self.outputs.out_warp = op.abspath(self.inputs.out_warp)
self.outputs.distance = _distance
return runtime


class MeshWarpMathsInputSpec(BaseInterfaceInputSpec):
Expand All @@ -302,18 +271,16 @@ class MeshWarpMathsInputSpec(BaseInterfaceInputSpec):
operation = traits.Enum('sum', 'sub', 'mul', 'div', usedefault=True,
desc=('operation to be performed'))

out_warp = File('warp_maths.vtk', usedefault=True,
desc='vtk file based on in_surf and warpings mapping it '
'to out_file')
out_file = File('warped_surf.vtk', usedefault=True,
out_warp = GenFile(template='{in_surf}_warping', keep_extension=True,
desc='vtk file based on in_surf and warpings mapping it to out_file')
out_file = File(template='{in_surf}_warped', keep_extension=True,
desc='vtk with surface warped')


class MeshWarpMathsOutputSpec(TraitedSpec):
out_warp = File(exists=True, desc=('vtk file with the vertex-wise '
'mapping of surface1 to surface2'))
out_file = File(exists=True,
desc='vtk with surface warped')
out_file = File(exists=True, desc='vtk with surface warped')


class MeshWarpMaths(TVTKBaseInterface):
Expand Down Expand Up @@ -416,12 +383,6 @@ def _run_interface(self, runtime):

return runtime

def _list_outputs(self):
outputs = self._outputs().get()
outputs['out_file'] = op.abspath(self.inputs.out_file)
outputs['out_warp'] = op.abspath(self.inputs.out_warp)
return outputs


class P2PDistance(ComputeMeshWarp):

Expand All @@ -437,6 +398,5 @@ class P2PDistance(ComputeMeshWarp):

def __init__(self, **inputs):
super(P2PDistance, self).__init__(**inputs)
warn(('This interface has been deprecated since 1.0, please use '
'ComputeMeshWarp'),
DeprecationWarning)
IFLOGGER.warn('This interface has been deprecated since 1.0, please use '
'ComputeMeshWarp')
Loading