Skip to content

Commit 984895c

Browse files
committed
RBF parameter handler with read method and tests
1 parent 9ddf930 commit 984895c

File tree

8 files changed

+295
-7
lines changed

8 files changed

+295
-7
lines changed

docs/source/params.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ Params
66
.. autoclass:: FFDParameters
77
:members:
88
:private-members:
9+
10+
.. autoclass:: RBFParameters
11+
:members:
12+
:private-members:

pygem/params.py

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Utilities for reading and writing parameters files to perform the Free Form Deformation (FFD)
2+
Utilities for reading and writing parameters files to perform the desired geometrical morphing.
33
"""
44
import os
55
import ConfigParser
@@ -268,13 +268,11 @@ def print_info(self):
268268
"""
269269
print 'conversion_unit = ' + str(self.conversion_unit) + '\n'
270270
print '(lenght_box_x, lenght_box_y, lenght_box_z) = (' + str(self.lenght_box_x) + \
271-
', ' + str(self.lenght_box_y) + ', ' + \
272-
str(self.lenght_box_z) + ')'
271+
', ' + str(self.lenght_box_y) + ', ' + str(self.lenght_box_z) + ')'
273272
print 'origin_box = ' + str(self.origin_box)
274273
print 'n_control_points = ' + str(self.n_control_points)
275274
print '(rot_angle_x, rot_angle_y, rot_angle_z) = (' + str(self.rot_angle_x) + \
276-
', ' + str(self.rot_angle_y) + ', ' + \
277-
str(self.rot_angle_z) + ')'
275+
', ' + str(self.rot_angle_y) + ', ' + str(self.rot_angle_z) + ')'
278276
print '\narray_mu_x ='
279277
print self.array_mu_x
280278
print '\narray_mu_y ='
@@ -297,3 +295,94 @@ def print_info(self):
297295
print self.position_vertex_3
298296

299297

298+
299+
class RBFParameters(object):
300+
"""
301+
Class that handles the Radial Basis Functions parameters in terms of RBF control points and
302+
basis functions.
303+
304+
:cvar string basis: name of the basis functions to use in the transformation. The functions
305+
implemented so far are: gaussian spline, multi quadratic biharmonic spline,
306+
inv multi quadratic biharmonic spline, thin plate spline, beckert wendland c2 basis.
307+
For a comprehensive list with details see the class :class:`~pygem.radialbasis.RBF`.
308+
The default value is None.
309+
:cvar float radius: is the scaling parameter r that affects the shape of the basis functions.
310+
For details see the class :class:`~pygem.radialbasis.RBF`. The default value is None.
311+
:cvar int n_control_points: total number of control points.
312+
:cvar numpy.ndarray original_control_points: it is an `n_control_points`-by-3 array with the
313+
coordinates of the original interpolation control points before the deformation. The
314+
default value is None.
315+
:cvar numpy.ndarray deformed_control_points: it is an `n_control_points`-by-3 array with the
316+
coordinates of the interpolation control points after the deformation. The default value
317+
is None.
318+
"""
319+
def __init__(self):
320+
self.basis = None
321+
self.radius = None
322+
self.n_control_points = None
323+
self.original_control_points = None
324+
self.deformed_control_points = None
325+
326+
327+
def read_parameters(self, filename='parameters.prm'):
328+
"""
329+
Reads in the parameters file and fill the self structure.
330+
331+
:param string filename: parameters file to be read in.
332+
"""
333+
if not isinstance(filename, basestring):
334+
raise TypeError('filename must be a string')
335+
336+
# Checks if the parameters file exists. If not it writes the default class into filename.
337+
# It consists in the vetices of a cube of side one with a vertex in (0, 0, 0) and opposite one
338+
# in (1, 1, 1).
339+
if not os.path.isfile(filename):
340+
self.basis = 'gaussian_spline'
341+
self.radius = 0.5
342+
self.n_control_points = 8
343+
self.original_control_points = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
344+
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
345+
self.deformed_control_points = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
346+
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
347+
#self.write_parameters(filename)
348+
return
349+
350+
config = ConfigParser.RawConfigParser()
351+
config.read(filename)
352+
353+
self.basis = config.get('Radial Basis Functions', 'basis function')
354+
self.radius = config.getfloat('Radial Basis Functions', 'radius')
355+
356+
ctrl_points = config.get('Control points', 'original control points')
357+
lines = ctrl_points.split('\n')
358+
self.n_control_points = len(lines)
359+
self.original_control_points = np.zeros((self.n_control_points, 3))
360+
for line, i in zip(lines, range(0, self.n_control_points)):
361+
values = line.split()
362+
self.original_control_points[i] = np.array([float(values[0]), float(values[1]), float(values[2])])
363+
364+
mod_points = config.get('Control points', 'deformed control points')
365+
lines = mod_points.split('\n')
366+
367+
if len(lines) != self.n_control_points:
368+
raise TypeError("The number of control points must be equal both in the 'original control points'" + \
369+
" and in the 'deformed control points' section of the parameters file ({0!s})".format(filename))
370+
371+
self.deformed_control_points = np.zeros((self.n_control_points, 3))
372+
for line, i in zip(lines, range(0, self.n_control_points)):
373+
values = line.split()
374+
self.deformed_control_points[i] = np.array([float(values[0]), float(values[1]), float(values[2])])
375+
376+
377+
def print_info(self):
378+
"""
379+
This method prints all the RBF parameters on the screen. Its purpose is for debugging.
380+
"""
381+
print 'basis function = ' + str(self.basis)
382+
print 'radius = ' + str(self.radius)
383+
print 'n_control_points = ' + str(self.n_control_points)
384+
print '\noriginal_control_points ='
385+
print self.original_control_points
386+
print '\ndeformed_control_points ='
387+
print self.deformed_control_points
388+

pygem/stlhandler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ def parse(self, filename):
4949

5050
def write(self, mesh_points, filename, write_bin=False):
5151
"""
52-
Writes a unv file, called filename, copying all the lines from self.filename but
52+
Writes a stl file, called filename, copying all the lines from self.filename but
5353
the coordinates. mesh_points is a matrix that contains the new coordinates to
54-
write in the unv file.
54+
write in the stl file.
5555
5656
:param numpy.ndarray mesh_points: it is a `n_points`-by-3 matrix containing
5757
the coordinates of the points of the mesh.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
[Radial Basis Functions]
3+
# This section describes the radial basis functions shape.
4+
5+
# basis funtion is the name of the basis functions to use in the transformation. The functions
6+
# implemented so far are: gaussian_spline, multi_quadratic_biharmonic_spline,
7+
# inv_multi_quadratic_biharmonic_spline, thin_plate_spline, beckert_wendland_c2_basis.
8+
# For a comprehensive list with details see the class RBF.
9+
basis function: gaussian_spline
10+
11+
# radius is the scaling parameter r that affects the shape of the basis functions. See the documentation
12+
# of the class RBF for details.
13+
radius: 0.5
14+
15+
[Control points]
16+
# This section describes the RBF control points.
17+
18+
# original control points collects the coordinates of the interpolation control points before the deformation.
19+
original control points: 0.0 0.0 0.0
20+
0.0 0.0 1.0
21+
0.0 1.0 0.0
22+
1.0 0.0 0.0
23+
0.0 1.0 1.0
24+
1.0 0.0 1.0
25+
1.0 1.0 0.0
26+
1.0 1.0 1.0
27+
28+
# deformed control points collects the coordinates of the interpolation control points after the deformation.
29+
deformed control points: 0.0 0.0 0.0
30+
0.0 0.0 1.0
31+
0.0 1.0 0.0
32+
1.0 0.0 0.0
33+
0.0 1.0 1.0
34+
1.0 0.0 1.0
35+
1.0 1.0 0.0
36+
1.0 1.0 1.0
37+
0.5 0.5 0.5
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
[Radial Basis Functions]
3+
# This section describes the radial basis functions shape.
4+
5+
# basis funtion is the name of the basis functions to use in the transformation. The functions
6+
# implemented so far are: gaussian_spline, multi_quadratic_biharmonic_spline,
7+
# inv_multi_quadratic_biharmonic_spline, thin_plate_spline, beckert_wendland_c2_basis.
8+
# For a comprehensive list with details see the class RBF.
9+
basis function: gaussian_splines
10+
11+
# radius is the scaling parameter r that affects the shape of the basis functions. See the documentation
12+
# of the class RBF for details.
13+
radius: 0.5
14+
15+
[Control points]
16+
# This section describes the RBF control points.
17+
18+
# original control points collects the coordinates of the interpolation control points before the deformation.
19+
original control points: 0.0 0.0 0.0
20+
0.0 0.0 1.0
21+
0.0 1.0 0.0
22+
1.0 0.0 0.0
23+
0.0 1.0 1.0
24+
1.0 0.0 1.0
25+
1.0 1.0 0.0
26+
1.0 1.0 1.0
27+
28+
# deformed control points collects the coordinates of the interpolation control points after the deformation.
29+
deformed control points: 0.0 0.0 0.0
30+
0.0 0.0 1.0
31+
0.0 1.0 0.0
32+
1.0 0.0 0.0
33+
0.0 1.0 1.0
34+
1.0 0.0 1.0
35+
1.0 1.0 0.0
36+
1.0 1.0 1.0
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
[Radial Basis Functions]
3+
# This section describes the radial basis functions shape.
4+
5+
# basis funtion is the name of the basis functions to use in the transformation. The functions
6+
# implemented so far are: gaussian_spline, multi_quadratic_biharmonic_spline,
7+
# inv_multi_quadratic_biharmonic_spline, thin_plate_spline, beckert_wendland_c2_basis.
8+
# For a comprehensive list with details see the class RBF.
9+
basis function: gaussian_spline
10+
11+
# radius is the scaling parameter r that affects the shape of the basis functions. See the documentation
12+
# of the class RBF for details.
13+
radius: 0.5
14+
15+
[Control points]
16+
# This section describes the RBF control points.
17+
18+
# original control points collects the coordinates of the interpolation control points before the deformation.
19+
original control points: 0.0 0.0 0.0
20+
0.0 0.0 1.0
21+
0.0 1.0 0.0
22+
1.0 0.0 0.0
23+
0.0 1.0 1.0
24+
1.0 0.0 1.0
25+
1.0 1.0 0.0
26+
1.0 1.0 1.0
27+
28+
# deformed control points collects the coordinates of the interpolation control points after the deformation.
29+
deformed control points: 0.0 0.0 0.0
30+
0.0 0.0 1.0
31+
0.0 1.0 0.0
32+
1.0 0.0 0.0
33+
0.0 1.0 1.0
34+
1.0 0.0 1.0
35+
1.0 1.0 0.0
36+
1.0 1.0 1.0

tests/test_rbfparams.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
2+
from unittest import TestCase
3+
import unittest
4+
import pygem.params as rbfp
5+
import numpy as np
6+
import filecmp
7+
import os
8+
9+
10+
class TestFFDParameters(TestCase):
11+
12+
13+
def test_class_members_default_basis(self):
14+
params = rbfp.RBFParameters()
15+
assert params.basis == None
16+
17+
18+
def test_class_members_default_radius(self):
19+
params = rbfp.RBFParameters()
20+
assert params.radius == None
21+
22+
23+
def test_class_members_default_n_control_points(self):
24+
params = rbfp.RBFParameters()
25+
assert params.n_control_points == None
26+
27+
28+
def test_class_members_default_original_control_points(self):
29+
params = rbfp.RBFParameters()
30+
assert params.original_control_points == None
31+
32+
33+
def test_class_members_default_deformed_control_points(self):
34+
params = rbfp.RBFParameters()
35+
assert params.deformed_control_points == None
36+
37+
38+
def test_read_parameters_basis(self):
39+
params = rbfp.RBFParameters()
40+
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
41+
assert params.basis == 'gaussian_spline'
42+
43+
44+
def test_read_parameters_radius(self):
45+
params = rbfp.RBFParameters()
46+
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
47+
assert params.radius == 0.5
48+
49+
50+
def test_read_parameters_n_control_points(self):
51+
params = rbfp.RBFParameters()
52+
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
53+
assert params.n_control_points == 8
54+
55+
56+
def test_read_parameters_original_control_points(self):
57+
params = rbfp.RBFParameters()
58+
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
59+
original_control_points_exact = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
60+
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
61+
np.testing.assert_array_almost_equal(params.original_control_points, original_control_points_exact)
62+
63+
64+
def test_read_parameters_deformed_control_points(self):
65+
params = rbfp.RBFParameters()
66+
params.read_parameters('tests/test_datasets/parameters_rbf_default.prm')
67+
deformed_control_points_exact = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
68+
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
69+
np.testing.assert_array_almost_equal(params.deformed_control_points, deformed_control_points_exact)
70+
71+
72+
def test_read_parameters_failing_filename_type(self):
73+
params = rbfp.RBFParameters()
74+
with self.assertRaises(TypeError):
75+
params.read_parameters(3)
76+
77+
78+
def test_read_parameters_failing_number_deformed_control_points(self):
79+
params = rbfp.RBFParameters()
80+
with self.assertRaises(TypeError):
81+
params.read_parameters('tests/test_datasets/parameters_rbf_bugged_01.prm')
82+
83+
84+
def test_print_info(self):
85+
params = rbfp.RBFParameters()
86+
params.print_info()

0 commit comments

Comments
 (0)