Skip to content

Commit 87ccdb1

Browse files
committed
Clean params classes
1 parent c487ad5 commit 87ccdb1

File tree

5 files changed

+342
-341
lines changed

5 files changed

+342
-341
lines changed

pygem/__init__.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
"""
22
"""
33
__all__ = [
4-
'affine', 'filehandler', 'freeform', 'radial', 'openfhandler', 'params',
4+
'affine', 'filehandler', 'freeform', 'radial', 'openfhandler',
55
'stlhandler', 'unvhandler', 'vtkhandler', 'nurbshandler', 'stephandler',
6-
'igeshandler', 'utils', 'gui', 'khandler', 'idw', 'params_idw'
6+
'igeshandler', 'utils', 'gui', 'khandler', 'idw', 'params_idw',
7+
'params_rbf', 'params_ffd'
78
]
89

910
from . import affine
1011
from . import filehandler
1112
from . import freeform
1213
from . import radial
1314
from . import openfhandler
14-
from . import params
1515
from . import stlhandler
1616
from . import unvhandler
1717
from . import vtkhandler
@@ -23,3 +23,5 @@
2323
from . import khandler
2424
from . import idw
2525
from . import params_idw
26+
from . import params_rbf
27+
from . import params_ffd

pygem/params.py renamed to pygem/params_ffd.py

Lines changed: 51 additions & 232 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,14 @@ class FFDParameters(object):
2525
:param list n_control_points: number of control points in the x, y, and z
2626
direction. If not provided it is set to [2, 2, 2].
2727
28-
:cvar float length_box_x: length of the FFD bounding box in the x direction
29-
(local coordinate system).
30-
:cvar float length_box_y: length of the FFD bounding box in the y direction
31-
(local coordinate system).
32-
:cvar float length_box_z: length of the FFD bounding box in the z direction
33-
(local coordinate system).
34-
35-
:cvar numpy.ndarray origin_box: a 3-by-1 vector of float numbers
36-
representing the x, y and z coordinates of the origin of the FFD
37-
bounding box.
38-
39-
:cvar float rot_angle_x: rotation angle around x axis of the FFD bounding
40-
box.
41-
:cvar float rot_angle_y: rotation angle around y axis of the FFD bounding
42-
box.
43-
:cvar float rot_angle_z: rotation angle around z axis of the FFD bounding
44-
box.
45-
46-
:cvar list n_control_points: list of 3 int representing the number of
47-
control points in the x, y, and z direction.
48-
28+
:cvar numpy.ndarray length_box: dimension of the FFD bounding box, in the
29+
x, y and z direction (local coordinate system).
30+
:cvar numpy.ndarray origin_box: the x, y and z coordinates of the origin of
31+
the FFD bounding box.
32+
:cvar numpy.ndarray rot_angle: rotation angle around x, y and z axis of the
33+
FFD bounding box.
34+
:cvar numpy.ndarray n_control_points: the number of control points in the
35+
x, y, and z direction.
4936
:cvar numpy.ndarray array_mu_x: collects the displacements (weights) along
5037
x, normalized with the box lenght x.
5138
:cvar numpy.ndarray array_mu_y: collects the displacements (weights) along
@@ -73,16 +60,18 @@ class FFDParameters(object):
7360
:Example: from file
7461
7562
>>> import pygem.params as ffdp
76-
63+
>>>
7764
>>> # Reading an existing file
7865
>>> params1 = ffdp.FFDParameters()
79-
>>> params1.read_parameters(filename='tests/test_datasets/parameters_test_ffd_identity.prm')
80-
81-
>>> # Creating a default parameters file with the right dimensions (if the file does not exists
82-
>>> # it is created with that name). So it is possible to manually edit it and read it again.
66+
>>> params1.read_parameters(
67+
>>> filename='tests/test_datasets/parameters_test_ffd_identity.prm')
68+
>>>
69+
>>> # Creating a default parameters file with the right dimensions (if the
70+
>>> # file does not exists it is created with that name). So it is possible
71+
>>> # to manually edit it and read it again.
8372
>>> params2 = ffdp.FFDParameters(n_control_points=[2, 3, 2])
8473
>>> params2.read_parameters(filename='parameters_test.prm')
85-
74+
>>>
8675
>>> # Creating bounding box of the given shape
8776
>>> from OCC.IGESControl import IGESControl_Reader
8877
>>> params3 = ffdp.FFDParameters()
@@ -115,15 +104,42 @@ def __init__(self, n_control_points=None):
115104
self.array_mu_y = np.zeros(self.n_control_points)
116105
self.array_mu_z = np.zeros(self.n_control_points)
117106

118-
self.psi_mapping = np.diag(1. / self.lenght_box)
119-
self.inv_psi_mapping = np.diag(self.lenght_box)
120-
121-
self.rotation_matrix = np.eye(3)
122107
self.position_vertex_0 = self.origin_box
123108
self.position_vertex_1 = np.array([1., 0., 0.])
124109
self.position_vertex_2 = np.array([0., 1., 0.])
125110
self.position_vertex_3 = np.array([0., 0., 1.])
126111

112+
@property
113+
def psi_mapping(self):
114+
"""
115+
Map from the physical domain to the reference domain.
116+
117+
:return: map from the pysical domain to the reference domain.
118+
:rtype: numpy.ndarray
119+
"""
120+
return np.diag(np.reciprocal(self.lenght_box))
121+
122+
@property
123+
def inv_psi_mapping(self):
124+
"""
125+
Map from the reference domain to the physical domain.
126+
127+
:return: map from the reference domain to domain.
128+
:rtype: numpy.ndarray
129+
"""
130+
return np.diag(self.lenght_box)
131+
132+
@property
133+
def rotation_matrix(self):
134+
"""
135+
:cvar numpy.ndarray rotation_matrix: rotation matrix (according to
136+
rot_angle_x, rot_angle_y, rot_angle_z).
137+
"""
138+
return at.angles2matrix(
139+
radians(self.rot_angle[2]), radians(self.rot_angle[1]),
140+
radians(self.rot_angle[0]))
141+
142+
127143
def read_parameters(self, filename='parameters.prm'):
128144
"""
129145
Reads in the parameters file and fill the self structure.
@@ -181,10 +197,6 @@ def read_parameters(self, filename='parameters.prm'):
181197
values = line.split()
182198
self.array_mu_z[tuple(map(int, values[0:3]))] = float(values[3])
183199

184-
self.rotation_matrix = at.angles2matrix(
185-
radians(self.rot_angle[2]), radians(self.rot_angle[1]),
186-
radians(self.rot_angle[0]))
187-
188200
self.position_vertex_0 = self.origin_box
189201
self.position_vertex_1 = self.position_vertex_0 + \
190202
np.dot(self.rotation_matrix, [self.lenght_box[0], 0, 0])
@@ -193,9 +205,6 @@ def read_parameters(self, filename='parameters.prm'):
193205
self.position_vertex_3 = self.position_vertex_0 + \
194206
np.dot(self.rotation_matrix, [0, 0, self.lenght_box[2]])
195207

196-
self.psi_mapping = np.diag(1. / self.lenght_box)
197-
self.inv_psi_mapping = np.diag(self.lenght_box)
198-
199208
def write_parameters(self, filename='parameters.prm'):
200209
"""
201210
This method writes a parameters file (.prm) called `filename` and fills
@@ -343,24 +352,10 @@ def build_bounding_box(self,
343352
min_xyz, max_xyz = self._calculate_bb_dimension(shape, tol, triangulate,
344353
triangulate_tol)
345354
self.origin_box = min_xyz
346-
self._set_box_dimensions(min_xyz, max_xyz)
355+
self.lenght_box = max_xyz - min_xyz
347356
self._set_position_of_vertices()
348-
self._set_mapping()
349357
self._set_transformation_params_to_zero()
350358

351-
def _set_box_dimensions(self, min_xyz, max_xyz):
352-
"""
353-
Dimensions of the cage are set as distance from the origin (minimum) of
354-
the cage to the maximal point in each dimension.
355-
356-
:param iterable min_xyz: three values representing the minimal values of
357-
the bounding box in XYZ respectively
358-
:param iterable max_xyz: three values representing the maximal values of
359-
the bounding box in XYZ respectively
360-
"""
361-
dims = [max_xyz[i] - min_xyz[i] for i in range(3)]
362-
self.lenght_box = np.asarray(dims)
363-
364359
def _set_position_of_vertices(self):
365360
"""
366361
Vertices of the control box around the object are set in this method.
@@ -376,24 +371,15 @@ def _set_position_of_vertices(self):
376371
self.position_vertex_3 = self.origin_box + np.array(
377372
[.0, .0, self.lenght_box[2]])
378373

379-
def _set_mapping(self):
380-
"""
381-
This method sets mapping from physcial domain to the reference domain
382-
(``psi_mapping``) as well as inverse mapping (``inv_psi_mapping``).
383-
"""
384-
self.psi_mapping = np.diag([1. / self.lenght_box[i] for i in range(3)])
385-
self.inv_psi_mapping = np.diag(self.lenght_box)
386-
387374
def _set_transformation_params_to_zero(self):
388375
"""
389376
Sets transfomration parameters (``array_mu_x, array_mu_y, array_mu_z``)
390377
to arrays of zeros (``numpy.zeros``). The shape of arrays corresponds to
391378
the number of control points in each dimension.
392379
"""
393-
ctrl_pnts = self.n_control_points
394-
self.array_mu_x = np.zeros(ctrl_pnts)
395-
self.array_mu_y = np.zeros(ctrl_pnts)
396-
self.array_mu_z = np.zeros(ctrl_pnts)
380+
self.array_mu_x.fill(0.0)
381+
self.array_mu_y.fill(0.0)
382+
self.array_mu_z.fill(0.0)
397383

398384
@staticmethod
399385
def _calculate_bb_dimension(shape,
@@ -428,170 +414,3 @@ def _calculate_bb_dimension(shape,
428414
xyz_min = np.array([xmin, ymin, zmin])
429415
xyz_max = np.array([xmax, ymax, zmax])
430416
return xyz_min, xyz_max
431-
432-
433-
class RBFParameters(object):
434-
"""
435-
Class that handles the Radial Basis Functions parameters in terms of RBF
436-
control points and basis functions.
437-
438-
:cvar string basis: name of the basis functions to use in the
439-
transformation. The functions implemented so far are: gaussian spline,
440-
multi quadratic biharmonic spline, inv multi quadratic biharmonic
441-
spline, thin plate spline, beckert wendland c2 basis, polyharmonic
442-
splines. For a comprehensive list with details see the class
443-
:class:`~pygem.radialbasis.RBF`. The default value is None.
444-
:cvar float radius: is the scaling parameter r that affects the shape of the
445-
basis functions. For details see the class
446-
:class:`~pygem.radialbasis.RBF`. The default value is None.
447-
:cvar int n_control_points: total number of control points.
448-
:cvar numpy.ndarray original_control_points: it is an
449-
`n_control_points`-by-3 array with the coordinates of the original
450-
interpolation control points before the deformation. The default value
451-
is None.
452-
:cvar numpy.ndarray deformed_control_points: it is an
453-
`n_control_points`-by-3 array with the coordinates of the
454-
interpolation control points after the deformation. The default value is
455-
None.
456-
"""
457-
458-
def __init__(self):
459-
self.basis = None
460-
self.radius = None
461-
self.power = 2
462-
self.n_control_points = None
463-
self.original_control_points = None
464-
self.deformed_control_points = None
465-
466-
def read_parameters(self, filename='parameters_rbf.prm'):
467-
"""
468-
Reads in the parameters file and fill the self structure.
469-
470-
:param string filename: parameters file to be read in. Default value is
471-
parameters_rbf.prm.
472-
"""
473-
if not isinstance(filename, str):
474-
raise TypeError('filename must be a string')
475-
476-
# Checks if the parameters file exists. If not it writes the default
477-
# class into filename. It consists in the vetices of a cube of side one
478-
# with a vertex in (0, 0, 0) and opposite one in (1, 1, 1).
479-
if not os.path.isfile(filename):
480-
self.basis = 'gaussian_spline'
481-
self.radius = 0.5
482-
self.n_control_points = 8
483-
self.original_control_points = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
484-
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
485-
self.deformed_control_points = np.array([0., 0., 0., 0., 0., 1., 0., 1., 0., 1., 0., 0., \
486-
0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1., 1.]).reshape((8, 3))
487-
self.write_parameters(filename)
488-
return
489-
490-
config = configparser.RawConfigParser()
491-
config.read(filename)
492-
493-
self.basis = config.get('Radial Basis Functions', 'basis function')
494-
self.radius = config.getfloat('Radial Basis Functions', 'radius')
495-
self.power = config.getint('Radial Basis Functions', 'power')
496-
497-
ctrl_points = config.get('Control points', 'original control points')
498-
lines = ctrl_points.split('\n')
499-
self.n_control_points = len(lines)
500-
self.original_control_points = np.zeros((self.n_control_points, 3))
501-
for line, i in zip(lines, list(range(0, self.n_control_points))):
502-
values = line.split()
503-
self.original_control_points[i] = np.array(
504-
[float(values[0]),
505-
float(values[1]),
506-
float(values[2])])
507-
508-
mod_points = config.get('Control points', 'deformed control points')
509-
lines = mod_points.split('\n')
510-
511-
if len(lines) != self.n_control_points:
512-
raise TypeError("The number of control points must be equal both in the 'original control points'" + \
513-
" and in the 'deformed control points' section of the parameters file ({0!s})".format(filename))
514-
515-
self.deformed_control_points = np.zeros((self.n_control_points, 3))
516-
for line, i in zip(lines, list(range(0, self.n_control_points))):
517-
values = line.split()
518-
self.deformed_control_points[i] = np.array(
519-
[float(values[0]),
520-
float(values[1]),
521-
float(values[2])])
522-
523-
def write_parameters(self, filename='parameters_rbf.prm'):
524-
"""
525-
This method writes a parameters file (.prm) called `filename` and fills
526-
it with all the parameters class members. Default value is
527-
parameters_rbf.prm.
528-
529-
:param string filename: parameters file to be written out.
530-
"""
531-
if not isinstance(filename, str):
532-
raise TypeError("filename must be a string")
533-
534-
with open(filename, 'w') as output_file:
535-
output_file.write('\n[Radial Basis Functions]\n')
536-
output_file.write(
537-
'# This section describes the radial basis functions shape.\n')
538-
539-
output_file.write('\n# basis funtion is the name of the basis functions to use in the transformation. ' + \
540-
'The functions\n')
541-
output_file.write(
542-
'# implemented so far are: gaussian_spline, multi_quadratic_biharmonic_spline,\n'
543-
)
544-
output_file.write(
545-
'# inv_multi_quadratic_biharmonic_spline, thin_plate_spline, beckert_wendland_c2_basis, polyharmonic_spline.\n'
546-
)
547-
output_file.write(
548-
'# For a comprehensive list with details see the class RBF.\n')
549-
output_file.write('basis function: ' + str(self.basis) + '\n')
550-
551-
output_file.write('\n# radius is the scaling parameter r that affects the shape of the basis functions. ' + \
552-
'See the documentation\n')
553-
output_file.write('# of the class RBF for details.\n')
554-
output_file.write('radius: ' + str(self.radius) + '\n')
555-
output_file.write(
556-
'\n# The power parameter k for polyharmonic spline')
557-
output_file.write('\n# See the documentation for details\n')
558-
output_file.write('power: ' + str(self.power) + '\n')
559-
560-
output_file.write('\n\n[Control points]\n')
561-
output_file.write(
562-
'# This section describes the RBF control points.\n')
563-
564-
output_file.write('\n# original control points collects the coordinates of the interpolation ' + \
565-
'control points before the deformation.\n')
566-
output_file.write('original control points:')
567-
offset = 1
568-
for i in range(0, self.n_control_points):
569-
output_file.write(offset * ' ' + str(self.original_control_points[i][0]) + ' ' + \
570-
str(self.original_control_points[i][1]) + ' ' + \
571-
str(self.original_control_points[i][2]) + '\n')
572-
offset = 25
573-
574-
output_file.write('\n# deformed control points collects the coordinates of the interpolation ' + \
575-
'control points after the deformation.\n')
576-
output_file.write('deformed control points:')
577-
offset = 1
578-
for i in range(0, self.n_control_points):
579-
output_file.write(offset * ' ' + str(self.deformed_control_points[i][0]) + ' ' + \
580-
str(self.deformed_control_points[i][1]) + ' ' + \
581-
str(self.deformed_control_points[i][2]) + '\n')
582-
offset = 25
583-
584-
def __str__(self):
585-
"""
586-
This method prints all the RBF parameters on the screen. Its purpose is
587-
for debugging.
588-
"""
589-
string = ''
590-
string += 'basis function = {}\n'.format(self.basis)
591-
string += 'radius = {}\n'.format(self.radius)
592-
string += 'power = {}\n'.format(self.power)
593-
string += '\noriginal control points =\n'
594-
string += '{}\n'.format(self.original_control_points)
595-
string += '\ndeformed control points =\n'
596-
string += '{}\n'.format(self.deformed_control_points)
597-
return string

0 commit comments

Comments
 (0)