Skip to content

Commit 4c69210

Browse files
committed
A bunch of bugfixes and improvements
1 parent 9da6ebb commit 4c69210

File tree

1 file changed

+33
-20
lines changed

1 file changed

+33
-20
lines changed

nipype/algorithms/mesh.py

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414

1515
import numpy as np
16+
import os.path as op
1617
from scipy.spatial.distance import euclidean
1718

1819
from .. import logging
@@ -29,14 +30,19 @@ class P2PDistanceInputSpec(BaseInterfaceInputSpec):
2930
surface2 = File(exists=True, mandatory=True,
3031
desc=("Test surface (vtk format) from which compute "
3132
"distance."))
32-
weighting = traits.Enum("none", "surface", usedefault=True,
33-
desc=('"none": no weighting is performed, '
34-
'"surface": edge distance is weighted by the '
35-
'corresponding surface area'))
33+
weighting = traits.Enum(
34+
"none", "area", usedefault=True,
35+
desc=('"none": no weighting is performed, "area": vertex distances are'
36+
'weighted by the total area of faces corresponding to the '
37+
'vertex'))
38+
out_file = File('distance.npy', usedefault=True,
39+
desc='numpy file keeping computed distances and weights')
3640

3741

3842
class P2PDistanceOutputSpec(TraitedSpec):
3943
distance = traits.Float(desc="computed distance")
44+
out_file = File(exists=True,
45+
desc='numpy file keeping computed distances and weights')
4046

4147

4248
class P2PDistance(BaseInterface):
@@ -78,6 +84,9 @@ def _run_interface(self, runtime):
7884
except ImportError:
7985
iflogger.warn(('ETS toolkit could not be imported'))
8086
pass
87+
except ValueError:
88+
iflogger.warn(('ETS toolkit is already set'))
89+
pass
8190

8291
r1 = tvtk.PolyDataReader(file_name=self.inputs.surface1)
8392
r2 = tvtk.PolyDataReader(file_name=self.inputs.surface2)
@@ -86,32 +95,36 @@ def _run_interface(self, runtime):
8695
r1.update()
8796
r2.update()
8897
assert(len(vtk1.points) == len(vtk2.points))
89-
d = 0.0
90-
totalWeight = 0.0
9198

92-
points = vtk1.points
93-
faces = vtk1.polys.to_array().reshape(-1, 4).astype(int)[:, 1:]
99+
points1 = np.array(vtk1.points)
100+
points2 = np.array(vtk2.points)
101+
102+
diff = np.linalg.norm(points1 - points2, axis=1)
103+
weights = np.ones(len(diff))
104+
105+
if (self.inputs.weighting == 'area'):
106+
faces = vtk1.polys.to_array().reshape(-1, 4).astype(int)[:, 1:]
94107

95-
for p1, p2 in zip(points, vtk2.points):
96-
weight = 1.0
97-
if (self.inputs.weighting == 'surface'):
108+
for i, p1 in enumerate(points2):
98109
# compute surfaces, set in weight
99-
weight = 0.0
100-
point_faces = faces[(faces[:, :] == 0).any(axis=1)]
110+
w = 0.0
111+
point_faces = faces[(faces[:, :] == i).any(axis=1)]
101112

102113
for idset in point_faces:
103-
p1 = points[int(idset[0])]
104-
p2 = points[int(idset[1])]
105-
p3 = points[int(idset[2])]
106-
weight = weight + self._triangle_area(p1, p2, p3)
114+
fp1 = points1[int(idset[0])]
115+
fp2 = points1[int(idset[1])]
116+
fp3 = points1[int(idset[2])]
117+
w += self._triangle_area(fp1, fp2, fp3)
118+
weights[i] = w
107119

108-
d += weight * euclidean(p1, p2)
109-
totalWeight = totalWeight + weight
120+
result = np.vstack([diff, weights])
121+
np.save(op.abspath(self.inputs.out_file), result.transpose())
110122

111-
self._distance = d / totalWeight
123+
self._distance = np.average(diff, weights=weights)
112124
return runtime
113125

114126
def _list_outputs(self):
115127
outputs = self._outputs().get()
128+
outputs['out_file'] = op.abspath(self.inputs.out_file)
116129
outputs['distance'] = self._distance
117130
return outputs

0 commit comments

Comments
 (0)