Repository: nipy/nipype

Issue:
AttributeError: 'PolyDataWriter' object has no attribute 'set_input_data'
```
> DISPLAY= PYTHONPATH=/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages MPLCONFIGDIR=/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/build xvfb-run -s "-screen 0 1024x768x24 -ac  +render -noreset" nosetests nipype.algorithms.tests.test_mesh_ops
Xlib:  extension "RANDR" missing on display ":99".
EE
======================================================================
ERROR: Failure: AttributeError ('PolyDataWriter' object has no attribute 'set_input_data'
Interface ComputeMeshWarp failed to run. )
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/nose/loader.py", line 251, in generate
    for test in g():
  File "/usr/lib/python2.7/dist-packages/numpy/testing/decorators.py", line 153, in skipper_gen
    for x in f(*args, **kwargs):
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/algorithms/tests/test_mesh_ops.py", line 35, in test_ident_distances
    res = dist_ident.run()
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/interfaces/base.py", line 1033, in run
    runtime = self._run_wrapper(runtime)
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/interfaces/base.py", line 983, in _run_wrapper
    runtime = self._run_interface(runtime)
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/algorithms/mesh.py", line 283, in _run_interface
    writer.set_input_data(out_mesh)
AttributeError: 'PolyDataWriter' object has no attribute 'set_input_data'
Interface ComputeMeshWarp failed to run. 
-------------------- >> begin captured logging << --------------------
rdflib: INFO: RDFLib Version: 4.1.2
interface: INFO: Redirecting X to :1099
--------------------- >> end captured logging << ---------------------

======================================================================
ERROR: Failure: AttributeError ('PolyDataWriter' object has no attribute 'set_input_data')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/nose/loader.py", line 251, in generate
    for test in g():
  File "/usr/lib/python2.7/dist-packages/numpy/testing/decorators.py", line 153, in skipper_gen
    for x in f(*args, **kwargs):
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/algorithms/tests/test_mesh_ops.py", line 62, in test_trans_distances
    writer.set_input_data(vtk1)
AttributeError: 'PolyDataWriter' object has no attribute 'set_input_data'

----------------------------------------------------------------------
Ran 2 tests in 0.626s

FAILED (errors=2)
```

which version of tvtk (mayavi2) do you need? we have 4.3.1-4.1 on debian sid/stretch atm

AttributeError: 'PolyDataWriter' object has no attribute 'set_input_data'
```
> DISPLAY= PYTHONPATH=/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages MPLCONFIGDIR=/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/build xvfb-run -s "-screen 0 1024x768x24 -ac  +render -noreset" nosetests nipype.algorithms.tests.test_mesh_ops
Xlib:  extension "RANDR" missing on display ":99".
EE
======================================================================
ERROR: Failure: AttributeError ('PolyDataWriter' object has no attribute 'set_input_data'
Interface ComputeMeshWarp failed to run. )
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/nose/loader.py", line 251, in generate
    for test in g():
  File "/usr/lib/python2.7/dist-packages/numpy/testing/decorators.py", line 153, in skipper_gen
    for x in f(*args, **kwargs):
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/algorithms/tests/test_mesh_ops.py", line 35, in test_ident_distances
    res = dist_ident.run()
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/interfaces/base.py", line 1033, in run
    runtime = self._run_wrapper(runtime)
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/interfaces/base.py", line 983, in _run_wrapper
    runtime = self._run_interface(runtime)
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/algorithms/mesh.py", line 283, in _run_interface
    writer.set_input_data(out_mesh)
AttributeError: 'PolyDataWriter' object has no attribute 'set_input_data'
Interface ComputeMeshWarp failed to run. 
-------------------- >> begin captured logging << --------------------
rdflib: INFO: RDFLib Version: 4.1.2
interface: INFO: Redirecting X to :1099
--------------------- >> end captured logging << ---------------------

======================================================================
ERROR: Failure: AttributeError ('PolyDataWriter' object has no attribute 'set_input_data')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/nose/loader.py", line 251, in generate
    for test in g():
  File "/usr/lib/python2.7/dist-packages/numpy/testing/decorators.py", line 153, in skipper_gen
    for x in f(*args, **kwargs):
  File "/home/yoh/proj/nipy/nipy-suite/build-area/nipype-0.11.0/debian/python-nipype/usr/lib/python2.7/site-packages/nipype/algorithms/tests/test_mesh_ops.py", line 62, in test_trans_distances
    writer.set_input_data(vtk1)
AttributeError: 'PolyDataWriter' object has no attribute 'set_input_data'

----------------------------------------------------------------------
Ran 2 tests in 0.626s

FAILED (errors=2)
```

which version of tvtk (mayavi2) do you need? we have 4.3.1-4.1 on debian sid/stretch atm



Discussion:
What version of vtk is installed? (<6.0 I assume). Since 6.0, VTK stopped using set_input in favor of set_input_data and set_input_port (or similar). Then, tvtk is compiled depending on VTK version.

I will add a detection of VTK version major.

What version of vtk is installed? (<6.0 I assume). Since 6.0, VTK stopped using set_input in favor of set_input_data and set_input_port (or similar). Then, tvtk is compiled depending on VTK version.

I will add a detection of VTK version major.


Resolving patch:
diff --git a/nipype/algorithms/mesh.py b/nipype/algorithms/mesh.py
--- a/nipype/algorithms/mesh.py
+++ b/nipype/algorithms/mesh.py
@@ -26,6 +26,20 @@
 iflogger = logging.getLogger('interface')
 
 
+class TVTKBaseInterface(BaseInterface):
+    _redirect_x = True
+    _vtk_major = 6
+
+    def __init__(self, **inputs):
+        try:
+            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.')
+
+        super(TVTKBaseInterface, self).__init__(**inputs)
+
+
 class WarpPointsInputSpec(BaseInterfaceInputSpec):
     points = File(exists=True, mandatory=True,
                   desc=('file containing the point set'))
@@ -42,7 +56,7 @@ class WarpPointsOutputSpec(TraitedSpec):
     out_points = File(desc='the warped point set')
 
 
-class WarpPoints(BaseInterface):
+class WarpPoints(TVTKBaseInterface):
 
     """
     Applies a displacement field to a point set given in vtk format.
@@ -62,7 +76,6 @@ class WarpPoints(BaseInterface):
     """
     input_spec = WarpPointsInputSpec
     output_spec = WarpPointsOutputSpec
-    _redirect_x = True
 
     def _gen_fname(self, in_file, suffix='generated', ext=None):
         import os.path as op
@@ -81,30 +94,15 @@ def _gen_fname(self, in_file, suffix='generated', ext=None):
         return op.abspath('%s_%s.%s' % (fname, suffix, ext))
 
     def _run_interface(self, runtime):
-        vtk_major = 6
-        try:
-            import vtk
-            vtk_major = vtk.VTK_MAJOR_VERSION
-        except ImportError:
-            iflogger.warn(('python-vtk could not be imported'))
+        import nibabel as nb
+        import numpy as np
+        from scipy import ndimage
 
         try:
             from tvtk.api import tvtk
         except ImportError:
             raise ImportError('Interface requires tvtk')
 
-        try:
-            from enthought.etsconfig.api import ETSConfig
-            ETSConfig.toolkit = 'null'
-        except ImportError:
-            iflogger.warn(('ETS toolkit could not be imported'))
-        except ValueError:
-            iflogger.warn(('ETS toolkit could not be set to null'))
-
-        import nibabel as nb
-        import numpy as np
-        from scipy import ndimage
-
         r = tvtk.PolyDataReader(file_name=self.inputs.points)
         r.update()
         mesh = r.output
@@ -134,7 +132,7 @@ def _run_interface(self, runtime):
         newpoints = [p + d for p, d in zip(points, disps)]
         mesh.points = newpoints
         w = tvtk.PolyDataWriter()
-        if vtk_major <= 5:
+        if self._vtk_major <= 5:
             w.input = mesh
         else:
             w.set_input_data_object(mesh)
@@ -182,7 +180,7 @@ class ComputeMeshWarpOutputSpec(TraitedSpec):
                     desc='numpy file keeping computed distances and weights')
 
 
-class ComputeMeshWarp(BaseInterface):
+class ComputeMeshWarp(TVTKBaseInterface):
 
     """
     Calculates a the vertex-wise warping to get surface2 from surface1.
@@ -207,7 +205,6 @@ class ComputeMeshWarp(BaseInterface):
 
     input_spec = ComputeMeshWarpInputSpec
     output_spec = ComputeMeshWarpOutputSpec
-    _redirect_x = True
 
     def _triangle_area(self, A, B, C):
         A = np.array(A)
@@ -223,15 +220,7 @@ def _run_interface(self, runtime):
         try:
             from tvtk.api import tvtk
         except ImportError:
-            raise ImportError('Interface ComputeMeshWarp requires tvtk')
-
-        try:
-            from enthought.etsconfig.api import ETSConfig
-            ETSConfig.toolkit = 'null'
-        except ImportError:
-            iflogger.warn(('ETS toolkit could not be imported'))
-        except ValueError:
-            iflogger.warn(('ETS toolkit is already set'))
+            raise ImportError('Interface requires tvtk')
 
         r1 = tvtk.PolyDataReader(file_name=self.inputs.surface1)
         r2 = tvtk.PolyDataReader(file_name=self.inputs.surface2)
@@ -280,7 +269,12 @@ def _run_interface(self, runtime):
         out_mesh.point_data.vectors.name = 'warpings'
         writer = tvtk.PolyDataWriter(
             file_name=op.abspath(self.inputs.out_warp))
-        writer.set_input_data(out_mesh)
+
+        if self._vtk_major <= 5:
+            writer.input = mesh
+        else:
+            writer.set_input_data_object(mesh)
+
         writer.write()
 
         self._distance = np.average(errvector, weights=weights)
@@ -322,7 +316,7 @@ class MeshWarpMathsOutputSpec(TraitedSpec):
                     desc='vtk with surface warped')
 
 
-class MeshWarpMaths(BaseInterface):
+class MeshWarpMaths(TVTKBaseInterface):
 
     """
     Performs the most basic mathematical operations on the warping field
@@ -348,21 +342,12 @@ class MeshWarpMaths(BaseInterface):
 
     input_spec = MeshWarpMathsInputSpec
     output_spec = MeshWarpMathsOutputSpec
-    _redirect_x = True
 
     def _run_interface(self, runtime):
         try:
             from tvtk.api import tvtk
         except ImportError:
-            raise ImportError('Interface ComputeMeshWarp requires tvtk')
-
-        try:
-            from enthought.etsconfig.api import ETSConfig
-            ETSConfig.toolkit = 'null'
-        except ImportError:
-            iflogger.warn(('ETS toolkit could not be imported'))
-        except ValueError:
-            iflogger.warn(('ETS toolkit is already set'))
+            raise ImportError('Interface requires tvtk')
 
         r1 = tvtk.PolyDataReader(file_name=self.inputs.in_surf)
         vtk1 = r1.output
@@ -412,14 +397,21 @@ def _run_interface(self, runtime):
         vtk1.point_data.vectors = warping
         writer = tvtk.PolyDataWriter(
             file_name=op.abspath(self.inputs.out_warp))
-        writer.set_input_data(vtk1)
+        if self._vtk_major <= 5:
+            writer.input = vtk1
+        else:
+            writer.set_input_data_object(vtk1)
         writer.write()
 
         vtk1.point_data.vectors = None
         vtk1.points = points1 + warping
         writer = tvtk.PolyDataWriter(
             file_name=op.abspath(self.inputs.out_file))
-        writer.set_input_data(vtk1)
+
+        if self._vtk_major <= 5:
+            writer.input = vtk1
+        else:
+            writer.set_input_data_object(vtk1)
         writer.write()
 
         return runtime
diff --git a/nipype/interfaces/fsl/utils.py b/nipype/interfaces/fsl/utils.py
--- a/nipype/interfaces/fsl/utils.py
+++ b/nipype/interfaces/fsl/utils.py
@@ -1870,9 +1870,18 @@ def _vtk_to_coords(self, in_file, out_file=None):
         except ImportError:
             raise ImportError('This interface requires tvtk to run.')
 
+        vtk_major = 5
+        try:
+            from tvtk.tvtk_classes.vtk_version import vtk_build_version
+            vtk_major = int(vtk_build_version[0])
+        except ImportError:
+            iflogger.warning('VTK version-major inspection using tvtk failed.')
+
         reader = tvtk.PolyDataReader(file_name=in_file + '.vtk')
         reader.update()
-        points = reader.output.points
+
+        mesh = reader.output if vtk_major < 6 else reader.get_output()
+        points = mesh.points
 
         if out_file is None:
             out_file, _ = op.splitext(in_file) + '.txt'
@@ -1887,12 +1896,24 @@ def _coords_to_vtk(self, points, out_file):
         except ImportError:
             raise ImportError('This interface requires tvtk to run.')
 
+        vtk_major = 5
+        try:
+            from tvtk.tvtk_classes.vtk_version import vtk_build_version
+            vtk_major = int(vtk_build_version[0])
+        except ImportError:
+            iflogger.warning('VTK version-major inspection using tvtk failed.')
+
         reader = tvtk.PolyDataReader(file_name=self.inputs.in_file)
         reader.update()
-        mesh = reader.output
+
+        mesh = reader.output if vtk_major < 6 else reader.get_output()
         mesh.points = points
 
-        writer = tvtk.PolyDataWriter(file_name=out_file, input=mesh)
+        writer = tvtk.PolyDataWriter(file_name=out_file)
+        if vtk_major < 6:
+            writer.input = mesh
+        else:
+            writer.set_input_data_object(mesh)
         writer.write()
 
     def _trk_to_coords(self, in_file, out_file=None):


Test patch: