Skip to content

Commit 4df6b55

Browse files
committed
test for FFD lattice reflection
1 parent 469de0d commit 4df6b55

File tree

2 files changed

+149
-53
lines changed

2 files changed

+149
-53
lines changed

pygem/params/ffdparams.py

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,10 @@ def position_vertices(self):
123123
:rtype: numpy.ndarray
124124
"""
125125
return self.origin_box + np.vstack([
126-
np.zeros((1, 3)),
127-
self.rotation_matrix.dot(np.diag(self.lenght_box)).T
126+
np.zeros(
127+
(1, 3)), self.rotation_matrix.dot(np.diag(self.lenght_box)).T
128128
])
129129

130-
131130
def reflect(self, axis=0):
132131
"""
133132
Reflect the lattice of control points along the direction defined
@@ -146,44 +145,44 @@ def reflect(self, axis=0):
146145
"""
147146
# check axis value
148147
if axis not in (0, 1, 2):
149-
raise ValueError("The axis has to be 0, 1, or 2. " + \
150-
"Current value {}.".format(axis))
148+
raise ValueError(
149+
"The axis has to be 0, 1, or 2. Current value {}.".format(axis))
151150

152151
# check that the plane of symmetry is undeformed
153-
if (axis == 0 and np.sum(self.array_mu_x[-1, :, :]) != 0) or \
154-
(axis == 1 and np.sum(self.array_mu_y[:, -1, :]) != 0) or \
155-
(axis == 2 and np.sum(self.array_mu_z[:, :, -1]) != 0):
156-
raise RuntimeError("If you want to reflect the FFD " + \
157-
"bounding box along axis {} ".format(axis) + \
158-
"you can not diplace the control points in the " + \
159-
"symmetry plane along that axis.")
160-
161-
# double the control points in the given axis minus 1 (the symmetry plane)
152+
if (axis == 0 and np.count_nonzero(self.array_mu_x[-1, :, :]) != 0) or (
153+
axis == 1 and np.count_nonzero(self.array_mu_y[:, -1, :]) != 0
154+
) or (axis == 2 and np.count_nonzero(self.array_mu_z[:, :, -1]) != 0):
155+
raise RuntimeError(
156+
"If you want to reflect the FFD bounding box along axis " + \
157+
"{} you can not diplace the control ".format(axis) + \
158+
"points in the symmetry plane along that axis."
159+
)
160+
161+
# double the control points in the given axis -1 (the symmetry plane)
162162
self.n_control_points[axis] = 2 * self.n_control_points[axis] - 1
163163
# double the box length
164164
self.lenght_box[axis] *= 2
165-
165+
166166
# we have to reflect the dispacements only along the correct axis
167167
reflection = np.ones(3)
168168
reflection[axis] = -1
169169

170-
# we need to select all the indeces but the ones in the plane of symmetry
171-
indeces = [slice(None), slice(None), slice(None)] # = [:, :, :]
172-
indeces[axis] = slice(1, None) # = [1:]
170+
# we select all the indeces but the ones in the plane of symmetry
171+
indeces = [slice(None), slice(None), slice(None)] # = [:, :, :]
172+
indeces[axis] = slice(1, None) # = [1:]
173173
indeces = tuple(indeces)
174-
174+
175175
# we append along the given axis all the displacements reflected
176176
# and in the reverse order
177-
self.array_mu_x = np.append(self.array_mu_x,
178-
reflection[0] * np.flip(self.array_mu_x, axis)[indeces],
179-
axis=axis)
180-
self.array_mu_y = np.append(self.array_mu_y,
181-
reflection[1] * np.flip(self.array_mu_y, axis)[indeces],
182-
axis=axis)
183-
self.array_mu_z = np.append(self.array_mu_z,
184-
reflection[2] * np.flip(self.array_mu_z, axis)[indeces],
185-
axis=axis)
186-
177+
self.array_mu_x = np.append(
178+
self.array_mu_x,
179+
reflection[0] * np.flip(self.array_mu_x, axis)[indeces], axis=axis)
180+
self.array_mu_y = np.append(
181+
self.array_mu_y,
182+
reflection[1] * np.flip(self.array_mu_y, axis)[indeces], axis=axis)
183+
self.array_mu_z = np.append(
184+
self.array_mu_z,
185+
reflection[2] * np.flip(self.array_mu_z, axis)[indeces], axis=axis)
187186

188187
def read_parameters(self, filename='parameters.prm'):
189188
"""
@@ -261,12 +260,12 @@ def write_parameters(self, filename='parameters.prm'):
261260
output_string += ' points in each direction (x, y, z).\n'
262261
output_string += '# For example, to create a 2 x 3 x 2 grid, use the'
263262
output_string += ' following: n control points: 2, 3, 2\n'
264-
output_string += 'n control points x: ' + str(
265-
self.n_control_points[0]) + '\n'
266-
output_string += 'n control points y: ' + str(
267-
self.n_control_points[1]) + '\n'
268-
output_string += 'n control points z: ' + str(
269-
self.n_control_points[2]) + '\n'
263+
output_string += 'n control points x: ' + str(self.n_control_points[
264+
0]) + '\n'
265+
output_string += 'n control points y: ' + str(self.n_control_points[
266+
1]) + '\n'
267+
output_string += 'n control points z: ' + str(self.n_control_points[
268+
2]) + '\n'
270269

271270
output_string += '\n# box lenght indicates the length of the FFD '
272271
output_string += 'bounding box along the three canonical directions '
@@ -340,8 +339,8 @@ def write_parameters(self, filename='parameters.prm'):
340339
for j in range(0, self.n_control_points[1]):
341340
for k in range(0, self.n_control_points[2]):
342341
output_string += offset * ' ' + str(i) + ' ' + str(
343-
j) + ' ' + str(k) + ' ' + str(
344-
self.array_mu_x[i][j][k]) + '\n'
342+
j) + ' ' + str(k) + ' ' + str(self.array_mu_x[i][j][
343+
k]) + '\n'
345344
offset = 13
346345

347346
output_string += '\n# parameter y collects the displacements along y, '
@@ -353,8 +352,8 @@ def write_parameters(self, filename='parameters.prm'):
353352
for j in range(0, self.n_control_points[1]):
354353
for k in range(0, self.n_control_points[2]):
355354
output_string += offset * ' ' + str(i) + ' ' + str(
356-
j) + ' ' + str(k) + ' ' + str(
357-
self.array_mu_y[i][j][k]) + '\n'
355+
j) + ' ' + str(k) + ' ' + str(self.array_mu_y[i][j][
356+
k]) + '\n'
358357
offset = 13
359358

360359
output_string += '\n# parameter z collects the displacements along z, '
@@ -366,8 +365,8 @@ def write_parameters(self, filename='parameters.prm'):
366365
for j in range(0, self.n_control_points[1]):
367366
for k in range(0, self.n_control_points[2]):
368367
output_string += offset * ' ' + str(i) + ' ' + str(
369-
j) + ' ' + str(k) + ' ' + str(
370-
self.array_mu_z[i][j][k]) + '\n'
368+
j) + ' ' + str(k) + ' ' + str(self.array_mu_z[i][j][
369+
k]) + '\n'
371370
offset = 13
372371

373372
with open(filename, 'w') as f:
@@ -422,29 +421,28 @@ def save_points(self, filename, write_deformed=True):
422421
y = np.linspace(0, self.lenght_box[1], self.n_control_points[1])
423422
z = np.linspace(0, self.lenght_box[2], self.n_control_points[2])
424423

425-
lattice_y_coords, lattice_x_coords, lattice_z_coords = np.meshgrid(
426-
y, x, z)
424+
lattice_y_coords, lattice_x_coords, lattice_z_coords = np.meshgrid(y, x,
425+
z)
427426

428427
if write_deformed:
429428
box_points = np.array([
430-
lattice_x_coords.ravel() +
431-
self.array_mu_x.ravel() * self.lenght_box[0],
432-
lattice_y_coords.ravel() +
429+
lattice_x_coords.ravel() + self.array_mu_x.ravel() *
430+
self.lenght_box[0], lattice_y_coords.ravel() +
433431
self.array_mu_y.ravel() * self.lenght_box[1],
434-
lattice_z_coords.ravel() +
435-
self.array_mu_z.ravel() * self.lenght_box[2]
432+
lattice_z_coords.ravel() + self.array_mu_z.ravel() *
433+
self.lenght_box[2]
436434
])
437435
else:
438436
box_points = np.array([
439-
lattice_x_coords.ravel(),
440-
lattice_y_coords.ravel(),
437+
lattice_x_coords.ravel(), lattice_y_coords.ravel(),
441438
lattice_z_coords.ravel()
442439
])
443440

444441
n_rows = box_points.shape[1]
445442

446-
box_points = np.dot(self.rotation_matrix, box_points) + np.transpose(
447-
np.tile(self.origin_box, (n_rows, 1)))
443+
box_points = np.dot(
444+
self.rotation_matrix,
445+
box_points) + np.transpose(np.tile(self.origin_box, (n_rows, 1)))
448446

449447
points = vtk.vtkPoints()
450448

tests/test_ffdparams.py

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,105 @@ def test_class_members_generic_array_mu_z(self):
8686
np.testing.assert_array_almost_equal(params.array_mu_z,
8787
np.zeros((2, 3, 5)))
8888

89+
def test_reflect_n_control_points_1(self):
90+
params = FFDParameters([2, 3, 5])
91+
params.reflect(axis=0)
92+
assert np.array_equal(params.n_control_points, [3, 3, 5])
93+
94+
def test_reflect_n_control_points_2(self):
95+
params = FFDParameters([2, 3, 5])
96+
params.reflect(axis=1)
97+
assert np.array_equal(params.n_control_points, [2, 5, 5])
98+
99+
def test_reflect_n_control_points_3(self):
100+
params = FFDParameters([2, 3, 5])
101+
params.reflect(axis=2)
102+
assert np.array_equal(params.n_control_points, [2, 3, 9])
103+
104+
def test_reflect_box_length_1(self):
105+
params = FFDParameters([2, 3, 5])
106+
params.reflect(axis=0)
107+
assert params.lenght_box[0] == 2
108+
109+
def test_reflect_box_length_2(self):
110+
params = FFDParameters([2, 3, 5])
111+
params.reflect(axis=1)
112+
assert params.lenght_box[1] == 2
113+
114+
def test_reflect_box_length_3(self):
115+
params = FFDParameters([2, 3, 5])
116+
params.reflect(axis=2)
117+
assert params.lenght_box[2] == 2
118+
119+
def test_reflect_wrong_axis(self):
120+
params = FFDParameters([2, 3, 5])
121+
with self.assertRaises(ValueError):
122+
params.reflect(axis=4)
123+
124+
def test_reflect_wrong_symmetry_plane_1(self):
125+
params = FFDParameters([3, 2, 2])
126+
params.read_parameters('tests/test_datasets/parameters_sphere.prm')
127+
params.array_mu_x = np.array(
128+
[0.2, 0., 0., 0., 0.5, 0., 0., 0., 1., 0., 0.3, 0.]).reshape((3, 2,
129+
2))
130+
with self.assertRaises(RuntimeError):
131+
params.reflect(axis=0)
132+
133+
def test_reflect_wrong_symmetry_plane_2(self):
134+
params = FFDParameters([3, 2, 2])
135+
params.read_parameters('tests/test_datasets/parameters_sphere.prm')
136+
params.array_mu_y = np.array(
137+
[0.2, 0., 0., 0., 0.5, 0., 0., 0., 1., 0., 0.3, 0.]).reshape((3, 2,
138+
2))
139+
with self.assertRaises(RuntimeError):
140+
params.reflect(axis=1)
141+
142+
def test_reflect_wrong_symmetry_plane_3(self):
143+
params = FFDParameters([3, 2, 2])
144+
params.read_parameters('tests/test_datasets/parameters_sphere.prm')
145+
params.array_mu_z = np.array(
146+
[0.2, 0., 0., 0., 0.5, 0., 0., 0., 1., 0., 0.3, 0.1]).reshape((3, 2,
147+
2))
148+
with self.assertRaises(RuntimeError):
149+
params.reflect(axis=2)
150+
151+
def test_reflect_axis_0(self):
152+
params = FFDParameters([3, 2, 2])
153+
params.read_parameters('tests/test_datasets/parameters_sphere.prm')
154+
params.array_mu_x = np.array(
155+
[0.2, 0., 0., 0., 0.5, 0., 0., .2, 0., 0., 0., 0.]).reshape((3, 2,
156+
2))
157+
params.reflect(axis=0)
158+
array_mu_x_exact = np.array([0.2, 0., 0., 0., 0.5, 0., 0., 0.2, 0.,
159+
0., 0., 0., -0.5, -0., -0., -0.2, -0.2, -0., -0., -0.]).reshape((5, 2,
160+
2))
161+
np.testing.assert_array_almost_equal(params.array_mu_x,
162+
array_mu_x_exact)
163+
164+
def test_reflect_axis_1(self):
165+
params = FFDParameters([3, 2, 2])
166+
params.read_parameters('tests/test_datasets/parameters_sphere.prm')
167+
params.array_mu_y = np.array(
168+
[0.2, 0., 0., 0., 0.5, 0., 0., 0., 0., 0., 0., 0.]).reshape((3, 2,
169+
2))
170+
params.reflect(axis=1)
171+
array_mu_y_exact = np.array([0.2, 0., 0., 0., -0.2, -0., 0.5, 0., 0., 0.,
172+
-0.5, -0., 0., 0., 0., 0., 0., 0.]).reshape((3, 3, 2))
173+
np.testing.assert_array_almost_equal(params.array_mu_y,
174+
array_mu_y_exact)
175+
176+
def test_reflect_axis_2(self):
177+
params = FFDParameters([3, 2, 2])
178+
params.read_parameters('tests/test_datasets/parameters_sphere.prm')
179+
params.array_mu_z = np.array(
180+
[0.2, 0., 0., 0., 0.5, 0., 0., 0., 0., 0., 0., 0.]).reshape((3, 2,
181+
2))
182+
params.reflect(axis=2)
183+
array_mu_z_exact = np.array([0.2, 0., -0.2, 0., 0., 0., 0.5, 0., -0.5,
184+
0., 0., -0., 0., 0., -0., 0., 0., -0.]).reshape((3, 2, 3))
185+
np.testing.assert_array_almost_equal(params.array_mu_z,
186+
array_mu_z_exact)
187+
89188
def test_read_parameters_conversion_unit(self):
90189
params = FFDParameters(n_control_points=[3, 2, 2])
91190
params.read_parameters('tests/test_datasets/parameters_sphere.prm')
@@ -119,7 +218,6 @@ def test_read_parameters_array_mu_x(self):
119218
array_mu_x_exact = np.array(
120219
[0.2, 0., 0., 0., 0.5, 0., 0., 0., 1., 0., 0., 0.]).reshape((3, 2,
121220
2))
122-
print(params.array_mu_x)
123221
np.testing.assert_array_almost_equal(params.array_mu_x,
124222
array_mu_x_exact)
125223

0 commit comments

Comments
 (0)