Source code for simpa.utils.deformation_manager
# SPDX-FileCopyrightText: 2021 Division of Intelligent Medical Systems, DKFZ
# SPDX-FileCopyrightText: 2021 Janek Groehl
# SPDX-License-Identifier: MIT
import matplotlib.pyplot as plt
from simpa.utils import Tags
from scipy.interpolate import RegularGridInterpolator
from scipy.ndimage import gaussian_filter
import numpy as np
[docs]def create_deformation_settings(bounds_mm, maximum_z_elevation_mm=1, filter_sigma=1, cosine_scaling_factor=4):
"""
FIXME
"""
deformation_settings = dict()
number_of_boundary_points = np.random.randint(4, 6, size=2)
surface_elevations = np.random.random(size=(number_of_boundary_points[0],
number_of_boundary_points[1]))
surface_elevations = gaussian_filter(surface_elevations, sigma=filter_sigma)
surface_elevations = surface_elevations / np.max(surface_elevations)
x_positions_vector = np.linspace(bounds_mm[0][0], bounds_mm[0][1], number_of_boundary_points[0])
y_positions_vector = np.linspace(bounds_mm[1][0], bounds_mm[1][1], number_of_boundary_points[1])
# Add random permutations to the y-axis of the division knots
all_scaling_value = np.multiply.outer(
np.cos(x_positions_vector / (bounds_mm[0][1] * (cosine_scaling_factor /
np.pi)) - np.pi / (cosine_scaling_factor * 2)) ** 2,
np.cos(y_positions_vector / (bounds_mm[1][1] * (cosine_scaling_factor / np.pi)) - np.pi / (cosine_scaling_factor * 2)) ** 2)
surface_elevations *= all_scaling_value
# This rescales and sets the maximum to 0.
surface_elevations = surface_elevations * maximum_z_elevation_mm
de_facto_max_elevation = np.max(surface_elevations)
surface_elevations = surface_elevations - de_facto_max_elevation
deformation_settings[Tags.DEFORMATION_X_COORDINATES_MM] = x_positions_vector
deformation_settings[Tags.DEFORMATION_Y_COORDINATES_MM] = y_positions_vector
deformation_settings[Tags.DEFORMATION_Z_ELEVATIONS_MM] = surface_elevations
deformation_settings[Tags.MAX_DEFORMATION_MM] = de_facto_max_elevation
return deformation_settings
[docs]def get_functional_from_deformation_settings(deformation_settings: dict):
"""
FIXME
"""
if Tags.DEFORMATION_X_COORDINATES_MM not in deformation_settings:
raise KeyError("x coordinates not defined in deformation settings")
if Tags.DEFORMATION_Y_COORDINATES_MM not in deformation_settings:
raise KeyError("y coordinates not defined in deformation settings")
if Tags.DEFORMATION_Z_ELEVATIONS_MM not in deformation_settings:
raise KeyError("z elevations not defined in deformation settings")
x_coordinates_mm = deformation_settings[Tags.DEFORMATION_X_COORDINATES_MM]
y_coordinates_mm = deformation_settings[Tags.DEFORMATION_Y_COORDINATES_MM]
z_elevations_mm = deformation_settings[Tags.DEFORMATION_Z_ELEVATIONS_MM]
order = "cubic"
functional_mm = RegularGridInterpolator(
points=[x_coordinates_mm, y_coordinates_mm], values=z_elevations_mm, method=order)
return functional_mm
if __name__ == "__main__":
x_bounds = [0, 9]
y_bounds = [0, 9]
max_elevation = 3
settings = create_deformation_settings([x_bounds, y_bounds], maximum_z_elevation_mm=max_elevation,
filter_sigma=1, cosine_scaling_factor=4)
functional = get_functional_from_deformation_settings(settings)
x_pos_vector = np.linspace(x_bounds[0], x_bounds[1], 100)
y_pos_vector = np.linspace(y_bounds[0], y_bounds[1], 100)
eval_points = tuple(np.meshgrid(x_pos_vector, y_pos_vector, indexing='ij'))
values = functional(eval_points)
max_elevation = -np.min(values)
ax = plt.figure().add_subplot(projection='3d')
ax.plot_surface(eval_points[0], eval_points[1], values, cmap="viridis")
ax.set_zlim(-max_elevation, 0)
plt.show()