From 7a7175fec86548ae2a0448d9d74984103413457c Mon Sep 17 00:00:00 2001 From: Nicola Demo Date: Tue, 3 Apr 2018 10:54:15 +0200 Subject: [PATCH 1/2] Changes in `FFDParameters` and `RBFParameters` - less ambiguous method names (`save` -> `save_points`) - move method for rbf control points plot in `RBFParameters` class --- ...em.params.ffdparams.FFDParameters.save.rst | 6 --- ...ms.ffdparams.FFDParameters.save_points.rst | 6 +++ ...ms.rbfparams.RBFParameters.plot_points.rst | 6 +++ ...em.params.rbfparams.RBFParameters.save.rst | 6 --- ...ms.rbfparams.RBFParameters.save_points.rst | 6 +++ docs/source/ffdparams.rst | 2 +- docs/source/rbfparams.rst | 3 +- pygem/params/ffdparams.py | 28 +++++----- pygem/params/rbfparams.py | 51 ++++++++++++++++++- 9 files changed, 86 insertions(+), 28 deletions(-) delete mode 100644 docs/source/_summaries/pygem.params.ffdparams.FFDParameters.save.rst create mode 100644 docs/source/_summaries/pygem.params.ffdparams.FFDParameters.save_points.rst create mode 100644 docs/source/_summaries/pygem.params.rbfparams.RBFParameters.plot_points.rst delete mode 100644 docs/source/_summaries/pygem.params.rbfparams.RBFParameters.save.rst create mode 100644 docs/source/_summaries/pygem.params.rbfparams.RBFParameters.save_points.rst diff --git a/docs/source/_summaries/pygem.params.ffdparams.FFDParameters.save.rst b/docs/source/_summaries/pygem.params.ffdparams.FFDParameters.save.rst deleted file mode 100644 index dbb0cda..0000000 --- a/docs/source/_summaries/pygem.params.ffdparams.FFDParameters.save.rst +++ /dev/null @@ -1,6 +0,0 @@ -pygem.params.ffdparams.FFDParameters.save -========================================= - -.. currentmodule:: pygem.params.ffdparams - -.. automethod:: FFDParameters.save \ No newline at end of file diff --git a/docs/source/_summaries/pygem.params.ffdparams.FFDParameters.save_points.rst b/docs/source/_summaries/pygem.params.ffdparams.FFDParameters.save_points.rst new file mode 100644 index 0000000..2ecffdf --- /dev/null +++ b/docs/source/_summaries/pygem.params.ffdparams.FFDParameters.save_points.rst @@ -0,0 +1,6 @@ +pygem.params.ffdparams.FFDParameters.save_points +================================================ + +.. currentmodule:: pygem.params.ffdparams + +.. automethod:: FFDParameters.save_points \ No newline at end of file diff --git a/docs/source/_summaries/pygem.params.rbfparams.RBFParameters.plot_points.rst b/docs/source/_summaries/pygem.params.rbfparams.RBFParameters.plot_points.rst new file mode 100644 index 0000000..d7d6ea2 --- /dev/null +++ b/docs/source/_summaries/pygem.params.rbfparams.RBFParameters.plot_points.rst @@ -0,0 +1,6 @@ +pygem.params.rbfparams.RBFParameters.plot_points +================================================ + +.. currentmodule:: pygem.params.rbfparams + +.. automethod:: RBFParameters.plot_points \ No newline at end of file diff --git a/docs/source/_summaries/pygem.params.rbfparams.RBFParameters.save.rst b/docs/source/_summaries/pygem.params.rbfparams.RBFParameters.save.rst deleted file mode 100644 index 94557ce..0000000 --- a/docs/source/_summaries/pygem.params.rbfparams.RBFParameters.save.rst +++ /dev/null @@ -1,6 +0,0 @@ -pygem.params.rbfparams.RBFParameters.save -========================================= - -.. currentmodule:: pygem.params.rbfparams - -.. automethod:: RBFParameters.save \ No newline at end of file diff --git a/docs/source/_summaries/pygem.params.rbfparams.RBFParameters.save_points.rst b/docs/source/_summaries/pygem.params.rbfparams.RBFParameters.save_points.rst new file mode 100644 index 0000000..26e42cb --- /dev/null +++ b/docs/source/_summaries/pygem.params.rbfparams.RBFParameters.save_points.rst @@ -0,0 +1,6 @@ +pygem.params.rbfparams.RBFParameters.save_points +================================================ + +.. currentmodule:: pygem.params.rbfparams + +.. automethod:: RBFParameters.save_points \ No newline at end of file diff --git a/docs/source/ffdparams.rst b/docs/source/ffdparams.rst index 52919cc..106603c 100644 --- a/docs/source/ffdparams.rst +++ b/docs/source/ffdparams.rst @@ -15,7 +15,7 @@ FFDParameters FFDParameters.position_vertices FFDParameters.read_parameters FFDParameters.write_parameters - FFDParameters.save + FFDParameters.save_points FFDParameters.build_bounding_box FFDParameters.reset_deformation diff --git a/docs/source/rbfparams.rst b/docs/source/rbfparams.rst index cbffdcd..3f5ade1 100644 --- a/docs/source/rbfparams.rst +++ b/docs/source/rbfparams.rst @@ -12,7 +12,8 @@ RBFParameters RBFParameters.n_control_points RBFParameters.read_parameters RBFParameters.write_parameters - RBFParameters.save + RBFParameters.save_points + RBFParameters.plot_points .. autoclass:: RBFParameters :members: diff --git a/pygem/params/ffdparams.py b/pygem/params/ffdparams.py index 457c3bf..bbbf38a 100644 --- a/pygem/params/ffdparams.py +++ b/pygem/params/ffdparams.py @@ -334,7 +334,7 @@ def __str__(self): string += '\nposition_vertices = {}\n'.format(self.position_vertices) return string - def save(self, filename, write_deformed=True): + def save_points(self, filename, write_deformed=True): """ Method that writes a vtk file containing the FFD lattice. This method allows to visualize where the FFD control points are located before the @@ -354,34 +354,38 @@ def save(self, filename, write_deformed=True): >>> params.read_parameters( >>> filename='tests/test_datasets/parameters_test_ffd_sphere.prm') >>> params.save('tests/test_datasets/box_test_sphere.vtk') + + .. note:: + In order to visualize the points in Paraview, please select the + **Point Gaussian** representation. + """ x = np.linspace(0, self.lenght_box[0], self.n_control_points[0]) y = np.linspace(0, self.lenght_box[1], self.n_control_points[1]) z = np.linspace(0, self.lenght_box[2], self.n_control_points[2]) - lattice_y_coords, lattice_x_coords, lattice_z_coords = np.meshgrid( - y, x, z) + lattice_y_coords, lattice_x_coords, lattice_z_coords = np.meshgrid(y, x, + z) if write_deformed: box_points = np.array([ - lattice_x_coords.ravel() + - self.array_mu_x.ravel() * self.lenght_box[0], - lattice_y_coords.ravel() + + lattice_x_coords.ravel() + self.array_mu_x.ravel() * + self.lenght_box[0], lattice_y_coords.ravel() + self.array_mu_y.ravel() * self.lenght_box[1], - lattice_z_coords.ravel() + - self.array_mu_z.ravel() * self.lenght_box[2] + lattice_z_coords.ravel() + self.array_mu_z.ravel() * + self.lenght_box[2] ]) else: box_points = np.array([ - lattice_x_coords.ravel(), - lattice_y_coords.ravel(), + lattice_x_coords.ravel(), lattice_y_coords.ravel(), lattice_z_coords.ravel() ]) n_rows = box_points.shape[1] - box_points = np.dot(self.rotation_matrix, box_points) + np.transpose( - np.tile(self.origin_box, (n_rows, 1))) + box_points = np.dot( + self.rotation_matrix, + box_points) + np.transpose(np.tile(self.origin_box, (n_rows, 1))) points = vtk.vtkPoints() diff --git a/pygem/params/rbfparams.py b/pygem/params/rbfparams.py index 63f25f2..10a3d95 100644 --- a/pygem/params/rbfparams.py +++ b/pygem/params/rbfparams.py @@ -9,6 +9,7 @@ import os import numpy as np import vtk +import matplotlib.pyplot as plt class RBFParameters(object): @@ -193,7 +194,7 @@ def __str__(self): string += '{}\n'.format(self.deformed_control_points) return string - def save(self, filename, write_deformed=True): + def save_points(self, filename, write_deformed=True): """ Method that writes a vtk file containing the control points. This method allows to visualize where the RBF control points are located before the @@ -212,7 +213,12 @@ def save(self, filename, write_deformed=True): >>> params = RBFParameters() >>> params.read_parameters( >>> filename='tests/test_datasets/parameters_rbf_cube.prm') - >>> params.save('tests/test_datasets/box_cube.vtk') + >>> params.save_points('tests/test_datasets/box_cube.vtk') + + .. note:: + In order to visualize the points in Paraview, please select the + **Point Gaussian** representation. + """ box_points = self.deformed_control_points if write_deformed else self.original_control_points points = vtk.vtkPoints() @@ -227,3 +233,44 @@ def save(self, filename, write_deformed=True): writer.SetFileName(filename) writer.SetInputData(data) writer.Write() + + + def plot_points(self, filename=None): + """ + Method to plot the control points. It is possible to save the resulting + figure. + + :param str filename: if None the figure is shown, otherwise it is saved + on the specified `filename`. Default is None. + """ + fig = plt.figure(1) + axes = fig.add_subplot(111, projection='3d') + orig = axes.scatter( + self.original_control_points[:, 0], + self.original_control_points[:, 1], + self.original_control_points[:, 2], + c='blue', + marker='o') + defor = axes.scatter( + self.deformed_control_points[:, 0], + self.deformed_control_points[:, 1], + self.deformed_control_points[:, 2], + c='red', + marker='x') + + axes.set_xlabel('X axis') + axes.set_ylabel('Y axis') + axes.set_zlabel('Z axis') + + plt.legend( + (orig, defor), ('Original', 'Deformed'), + scatterpoints=1, + loc='lower left', + ncol=2, + fontsize=10) + + # Show the plot to the screen + if filename is None: + plt.show() + else: + fig.savefig(filename) From 81d4332025dffd6e6872d151c73c79d893a221b8 Mon Sep 17 00:00:00 2001 From: Nicola Demo Date: Wed, 4 Apr 2018 10:04:06 +0200 Subject: [PATCH 2/2] Remove utils and test --- pygem/utils.py | 205 -------------------------------------------- tests/test_utils.py | 95 -------------------- 2 files changed, 300 deletions(-) delete mode 100644 pygem/utils.py delete mode 100644 tests/test_utils.py diff --git a/pygem/utils.py b/pygem/utils.py deleted file mode 100644 index 5df2314..0000000 --- a/pygem/utils.py +++ /dev/null @@ -1,205 +0,0 @@ -""" -Auxiliary utilities for PyGeM. -""" -import vtk -import numpy as np -import matplotlib.pyplot as plt - - -def write_bounding_box(parameters, outfile, write_deformed=True): - """ - Method that writes a vtk file containing the FFD lattice. This method allows - to visualize where the FFD control points are located before the geometrical - morphing. If the `write_deformed` flag is set to True the method writes out - the deformed lattice, otherwise it writes one the original undeformed - lattice. - - :param FFDParameters parameters: parameters of the Free Form Deformation. - :param string outfile: name of the output file. - :param bool write_deformed: flag to write the original or modified FFD - control lattice. The default is set to True. - - :Example: - - >>> import pygem.utils as ut - >>> import pygem.params as pars - >>> import numpy as np - >>> - >>> params = pars.FFDParameters() - >>> fname = 'tests/test_datasets/parameters_test_ffd_sphere.prm' - >>> params.read_parameters(filename=fname) - >>> ut.write_bounding_box(params, 'tests/test_datasets/box_test_sphere.vtk') - """ - aux_x = np.linspace(0, parameters.lenght_box[0], - parameters.n_control_points[0]) - aux_y = np.linspace(0, parameters.lenght_box[1], - parameters.n_control_points[1]) - aux_z = np.linspace(0, parameters.lenght_box[2], - parameters.n_control_points[2]) - lattice_y_coords, lattice_x_coords, lattice_z_coords = np.meshgrid( - aux_y, aux_x, aux_z) - - if write_deformed: - box_points = np.array([ - lattice_x_coords.ravel() + - parameters.array_mu_x.ravel() * parameters.lenght_box[0], - lattice_y_coords.ravel() + - parameters.array_mu_y.ravel() * parameters.lenght_box[1], - lattice_z_coords.ravel() + - parameters.array_mu_z.ravel() * parameters.lenght_box[2] - ]) - else: - box_points = np.array([ - lattice_x_coords.ravel(), - lattice_y_coords.ravel(), - lattice_z_coords.ravel() - ]) - - n_rows = box_points.shape[1] - - box_points = np.dot(parameters.rotation_matrix, box_points) + np.transpose( - np.tile(parameters.origin_box, (n_rows, 1))) - - # step necessary to set the correct order to the box points for - # vtkStructuredGrid. Data in vtkStructuredGrid are ordered with - # x increasing fastest, then y, then z - dims = lattice_y_coords.shape - aux_xx = box_points[0, :].reshape(dims).ravel(order='f') - aux_yy = box_points[1, :].reshape(dims).ravel(order='f') - aux_zz = box_points[2, :].reshape(dims).ravel(order='f') - reordered_box_points = np.array((aux_xx, aux_yy, aux_zz)) - - _write_vtk_box(reordered_box_points, outfile, parameters.n_control_points) - - -def _write_vtk_box(box_points, filename, dimensions): - """ - Private method that writes a vtk file containing FFD control points. - - :param numpy.ndarray box_points: coordinates of the FFD control points. - :param string filename: name of the output file. - :param list dimensions: dimension of the lattice in (x, y, z) directions. - - .. warning:: - - If you want to visualize in paraview the inner points, - you have to slice the lattice because paraview does not visualize them - automatically even in the wireframe visualization. - """ - # setup points and vertices - points = vtk.vtkPoints() - - for index in range(0, box_points.shape[1]): - points.InsertNextPoint(box_points[0, index], box_points[1, index], - box_points[2, index]) - - grid = vtk.vtkStructuredGrid() - - grid.SetPoints(points) - grid.SetDimensions(dimensions) - grid.Modified() - - writer = vtk.vtkStructuredGridWriter() - writer.SetFileName(filename) - - if vtk.VTK_MAJOR_VERSION <= 5: - grid.Update() - writer.SetInput(grid) - else: - writer.SetInputData(grid) - - writer.Write() - - -def plot_rbf_control_points(parameters, save_fig=False): - """ - Method to plot the control points of a RBFParameters class. It is possible - to save the resulting figure. - - :param RBFParameters parameters: parameters of the Radial Basis Functions - interpolation. - :param bool save_fig: a flag to save the figure in png or not. If True the - plot is not shown and the figure is saved with the name - 'RBF_control_points.png'. The default value is False. - """ - fig = plt.figure(1) - axes = fig.add_subplot(111, projection='3d') - orig = axes.scatter( - parameters.original_control_points[:, 0], - parameters.original_control_points[:, 1], - parameters.original_control_points[:, 2], - c='blue', - marker='o') - defor = axes.scatter( - parameters.deformed_control_points[:, 0], - parameters.deformed_control_points[:, 1], - parameters.deformed_control_points[:, 2], - c='red', - marker='x') - - axes.set_xlabel('X axis') - axes.set_ylabel('Y axis') - axes.set_zlabel('Z axis') - - plt.legend( - (orig, defor), ('Original', 'Deformed'), - scatterpoints=1, - loc='lower left', - ncol=2, - fontsize=10) - - # Show the plot to the screen - if not save_fig: - plt.show() - else: - fig.savefig('RBF_control_points.png') - - -def write_points_in_vtp(points, outfile='points.vtp', color=None): - """ - Method that writes a vtp file containing the given points. It can be - used for any set of 3D points. Useful to visualize control points together - with mesh points in the same window. - - :param numpy.ndarray points: coordinates of the points. The shape has to - be (n_points, 3). - :param string outfile: name of the output file. The extension has to be - .vtp. Default is 'points.vtp'. - :param tuple color: tuple defining the RGB color to assign to all the - points. Default is blue: (0, 0, 255). - - :Example: - - >>> import pygem.utils as ut - >>> import numpy as np - >>> - >>> ctrl_points = np.arange(9).reshape(3, 3) - >>> outfile = 'example_points.vtp' - >>> ut.write_points_in_vtp(ctrl_points, outfile, color=(255, 0, 0)) - """ - if color is None: - color = (0, 0, 255) - # setup points and vertices - Points = vtk.vtkPoints() - Vertices = vtk.vtkCellArray() - - Colors = vtk.vtkUnsignedCharArray() - Colors.SetNumberOfComponents(3) - Colors.SetName("Colors") - - for i in range(points.shape[0]): - ind = Points.InsertNextPoint(points[i][0], points[i][1], points[i][2]) - Vertices.InsertNextCell(1) - Vertices.InsertCellPoint(ind) - Colors.InsertNextTuple3(color[0], color[1], color[2]) - - polydata = vtk.vtkPolyData() - polydata.SetPoints(Points) - polydata.SetVerts(Vertices) - polydata.GetPointData().SetScalars(Colors) - polydata.Modified() - - writer = vtk.vtkXMLPolyDataWriter() - writer.SetFileName(outfile) - writer.SetInputData(polydata) - writer.Write() diff --git a/tests/test_utils.py b/tests/test_utils.py deleted file mode 100644 index 2b75433..0000000 --- a/tests/test_utils.py +++ /dev/null @@ -1,95 +0,0 @@ -from unittest import TestCase -import unittest -import pygem.utils as ut -import pygem.params as pars -import numpy as np -import filecmp -import os -import vtk - - -class TestUtils(TestCase): - def cmp(self, f1, f2): - """ - Check if the two files have the same content, skipping comment lines - """ - content1 = [line for line in open(f1) if not line.startswith('#')] - content2 = [line for line in open(f1) if not line.startswith('#')] - return content1 == content2 - - def test_utils_write_original_box(self): - params = pars.FFDParameters() - params.read_parameters( - filename='tests/test_datasets/parameters_test_ffd_sphere.prm') - - outfilename = 'tests/test_datasets/box_test_sphere.vtk' - - ut.write_bounding_box(params, outfilename, write_deformed=False) - os.remove(outfilename) - - def test_utils_write_modified_box(self): - params = pars.FFDParameters() - params.read_parameters( - filename='tests/test_datasets/parameters_test_ffd_sphere.prm') - - outfilename = 'tests/test_datasets/box_test_sphere.vtk' - - ut.write_bounding_box(params, outfilename) - os.remove(outfilename) - - def test_utils_check_vtk_original_box(self): - params = pars.FFDParameters() - params.read_parameters( - filename='tests/test_datasets/parameters_test_ffd_sphere.prm') - - outfilename = 'tests/test_datasets/box_test_sphere.vtk' - if vtk.VTK_MAJOR_VERSION <= 5: - outfilename_expected = 'tests/test_datasets/box_test_sphere_true_version5.vtk' - else: - outfilename_expected = 'tests/test_datasets/box_test_sphere_true_version6.vtk' - - ut.write_bounding_box(params, outfilename, write_deformed=False) - - self.assertTrue(self.cmp(outfilename, outfilename_expected)) - os.remove(outfilename) - - def test_utils_check_vtk_modified_box(self): - params = pars.FFDParameters() - params.read_parameters( - filename='tests/test_datasets/parameters_test_ffd_sphere.prm') - - outfilename = 'tests/test_datasets/box_test_sphere.vtk' - if vtk.VTK_MAJOR_VERSION <= 5: - outfilename_expected = 'tests/test_datasets/box_modified_test_sphere_true_version5.vtk' - else: - outfilename_expected = 'tests/test_datasets/box_modified_test_sphere_true_version6.vtk' - - ut.write_bounding_box(params, outfilename) - - self.assertTrue(self.cmp(outfilename, outfilename_expected)) - os.remove(outfilename) - - def test_utils_plot_rbf_control_points(self): - params = pars.RBFParameters() - params.read_parameters( - filename='tests/test_datasets/parameters_rbf_cube.prm') - ut.plot_rbf_control_points(params, save_fig=False) - - def test_utils_plot_rbf_control_points_save_fig(self): - params = pars.RBFParameters() - params.read_parameters( - filename='tests/test_datasets/parameters_rbf_cube.prm') - ut.plot_rbf_control_points(params, save_fig=True) - self.assertTrue(os.path.isfile('RBF_control_points.png')) - os.remove('RBF_control_points.png') - - def test_utils_check_write_points_in_vtp(self): - ctrl_points = np.arange(12).reshape(4, 3) - - outfilename = 'tests/test_datasets/points_test.vtp' - if vtk.VTK_MAJOR_VERSION >= 6: - outfilename_expected = 'tests/test_datasets/points_test_true_version6.vtp' - - ut.write_points_in_vtp(ctrl_points, outfile=outfilename) - self.assertTrue(self.cmp(outfilename, outfilename_expected)) - os.remove(outfilename)