Skip to content

Commit

Permalink
Merge pull request #40 from KVSlab/release-v0.3-and-refactor
Browse files Browse the repository at this point in the history
Release v0.3 and minor refactoring
  • Loading branch information
hkjeldsberg authored May 14, 2019
2 parents f0e8f66 + 82809a2 commit 0fcab38
Show file tree
Hide file tree
Showing 19 changed files with 66 additions and 71 deletions.
2 changes: 1 addition & 1 deletion demo/demo_manipulate_area_inflation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# --method area --percentage -20 --region-of-interest first_line --poly-ball-size 250 250 250
# $ morphman-area --ifile C0002/surface/model.vtp --ofile C0002/surface/area_inflated.vtp \
# --method area --percentage 20 --region-of-interest first_line --poly-ball-size 250 250 250

#
# and a more detailed explenation could be found here:
# https://morphman.readthedocs.io/en/latest/manipulate_area.html#inflation-deflation-of-an-arterial-segment

Expand Down
10 changes: 5 additions & 5 deletions demo/get_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,27 @@
def download_case(case):
abs_path = path.dirname(path.abspath(__file__))
output_file = path.join(abs_path, "{}_models.tar.gz".format(case))
adress = "http://ecm2.mathcs.emory.edu/aneuriskdata/download/{}/{}_models.tar.gz".format(case, case)
url = "http://ecm2.mathcs.emory.edu/aneuriskdata/download/{}/{}_models.tar.gz".format(case, case)

try:
if platform == "darwin":
system("curl {} --output {}".format(adress, output_file))
system("curl {} --output {}".format(url, output_file))
system("tar -zxvf {}".format(output_file))
system("rm {}".format(output_file))

elif platform == "linux" or platform == "linux2":
system("wget {}".format(adress))
system("wget {}".format(url))
system("tar -zxvf {}".format(output_file))
system("rm {}".format(output_file))

elif platform == "win32":
system("bitsadmin /transfer download_model /download /priority high {} {}".format(adress, output_file))
system("bitsadmin /transfer download_model /download /priority high {} {}".format(url, output_file))
system("tar -zxvf {}".format(output_file))
system("del /f {}".format(output_file))

except:
raise RuntimeError("Problem downloading the testdata, please do it manually from "
+ adress + " and extract the compressed tarball in the"
+ url + " and extract the compressed tarball in the"
+ " test folder")


Expand Down
11 changes: 6 additions & 5 deletions docs/source/Miscellaneous.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,15 @@ For a more detailed description of the method, please see [3]_.

Common
======
In ``common.py`` we have collected generic functions used by multiple scripts.
Many of the functions wrap existing vtk and vmtk functions in a more pythonic syntax.
In the folder ``common`` we have collected utility scripts containing generic functions used by multiple scripts.
Many of the functions wrap existing vtk and vmtk functions in a more pythonic syntax,
collected in ``vtk_wrapper.py`` and ``vmtk_wrapper.py``, respectively.
Instead of writing 6-7 lines of code to initiate a vtk-object, and set each parameter,
and the input surface, one can call one function with multiple arguments instead,
see for instance :meth:`common.threshold`.
and the input surface, one may call one function with multiple arguments instead,
see for instance :meth:`vtk_wrapper.vtk_compute_threshold`.

In addition to wrapping vtk and vmtk functionality, there is also new methods for
manipulating centerlines and Voronoi diagrams.
manipulating centerlines, surface models and Voronoi diagrams, collected in their respective scripts.

.. [1] Piccinelli, M., Bacigaluppi, S., Boccardi, E., Ene-Iordache, B., Remuzzi, A., Veneziani, A. and Antiga, L., 2011. Geometry of the internal carotid artery and recurrent patterns in location, orientation, and rupture status of lateral aneurysms: an image-based computational study. Neurosurgery, 68(5), pp.1270-1285.
.. [2] Bogunović, H., Pozo, J.M., Cárdenes, R., Villa-Uriol, M.C., Blanc, R., Piotin, M. and Frangi, A.F., 2012. Automated landmarking and geometric characterization of the carotid siphon. Medical image analysis, 16(4), pp.889-903.
Expand Down
4 changes: 2 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@
# built documents.
#
# The short X.Y version.
version = u'0.2'
version = u'0.3'
# The full version, including alpha/beta/rc tags.
release = u'0.2'
release = u'0.3'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The general dependencies of morphMan are
Basic Installation
==================
We recommend that you can install morphMan through Anaconda.
First, install Anaconda or Miniconda (preferably the python 3.6 version).
First, install Anaconda or Miniconda (preferably the Python 3.6 version).
Then execute the following command in a terminal window::

$ conda create -n your_environment -c vmtk -c morphman morphman
Expand Down
2 changes: 1 addition & 1 deletion docs/source/manipulate_area.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Tutorial: Manipulate area
Manipulation of the cross-sectional area is performed by running ``morphman-area`` in the terminal, followed by the
respective command line arguments. Alternatively, you can execute the Python script directly,
located in the ``morphman`` subfolder, by typing ``python manipulate_area.py``. We have also created a
demo folder where we show how to run this tutorial from a Python script, please checkout the code from GitHub to
demo folder where we show how to run this tutorial from a Python script, please check out the code from GitHub to
run the demos.

In this tutorial, we are using the model with
Expand Down
2 changes: 1 addition & 1 deletion docs/source/manipulate_bend.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The goal of ``morphman-bend``, is to alter one specific bend in the
vasculature, like shown in Figure 1. This can be performed by running ``morphman-bend`` in the terminal,
followed by the respective command line arguments. Alternatively, you can execute the Python script directly,
located in the ``morphman`` subfolder, by typing ``python manipulate_bend.py``. We have also created a
demo folder where we show how to run this tutorial from a Python script, please checkout the code from GitHub to
demo folder where we show how to run this tutorial from a Python script, please check out the code from GitHub to
run the demos.

.. figure:: Bend_moving.png
Expand Down
2 changes: 1 addition & 1 deletion docs/source/manipulate_bifurcation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ is a file `./C0005/surface/model.vtp`, relative to where you execute the command
Performing the manipulation can be achieved by running ``morphman-bifurcation`` in the terminal, followed by the
respective command line arguments. Alternatively, you can execute the Python script directly,
located in the ``morphman`` subfolder, by typing ``python manipulate_bifurcation.py``. We have also created a
demo folder where we show how to run this tutorial from a Python script, please checkout the code from GitHub to
demo folder where we show how to run this tutorial from a Python script, please check out the code from GitHub to
run the demos.

Shown in Figure 2 is the result of rotating the two daughter branches with both
Expand Down
4 changes: 2 additions & 2 deletions docs/source/manipulate_branch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ Tutorial: Manipulate branch
===========================

The goal of ``manipulate_branch.py`` is to manipulate a specific branch of a
vascular model, either through pure tranlation and rotation, or by completely removing it, as depicted in Figure 1.
vascular model, either through pure tranlsation and rotation, or by completely removing it, as depicted in Figure 1.
In particular, we have defined a branch as any branch branching out of the longest tubular structure,
defined by the physical length of the tube.
The manipulation can be achieved by running ``morphman-branch`` in the terminal, followed by the
respective command line arguments. Alternatively, you can execute the Python script directly,
located in the ``morphman`` subfolder, by typing ``python manipulate_branch.py``. We have also created a
demo folder where we show how to run this tutorial from a Python script, please checkout the code from GitHub to
demo folder where we show how to run this tutorial from a Python script, please check out the code from GitHub to
run the demos.

.. figure:: Branch.png
Expand Down
2 changes: 1 addition & 1 deletion docs/source/manipulate_curvature.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ total curvature/torsion in a vascular segment, see Figure 1 for an example.
The manipulation can be achieved by running ``morphman-curvature`` in the terminal, followed by the
respective command line arguments. Alternatively, you can execute the Python script directly,
located in the ``morphman`` subfolder, by typing ``python manipulate_curvature.py``. We have also created a
demo folder where we show how to run this tutorial from a Python script, please checkout the code from GitHub to
demo folder where we show how to run this tutorial from a Python script, please check out the code from GitHub to
run the demos.

.. figure:: Curvature.png
Expand Down
2 changes: 1 addition & 1 deletion docs/source/manipulate_surface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ is a file `./C0005/surface/model.vtp`, relative to where you execute the command
Performing the manipulation can be achieved by running ``morphman-surface`` in the terminal, followed by the
respective command line arguments. Alternatively, you can execute the Python script directly,
located in the ``morphman`` subfolder, by typing ``python manipulate_surface.py``. We have also created a
demo folder where we show how to run this tutorial from a Python script, please checkout the code from GitHub to
demo folder where we show how to run this tutorial from a Python script, please check out the code from GitHub to
run the demos.

Shown in Figure 2 is the result of smoothing the surface.
Expand Down
3 changes: 1 addition & 2 deletions morphman/common/centerline_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,7 @@ def get_clipped_diverging_centerline(centerline, clip_start_point, clip_end_id):
return patch_cl


def get_line_to_change(surface, centerline, region_of_interest, method, region_points,
stenosis_length):
def get_line_to_change(surface, centerline, region_of_interest, method, region_points, stenosis_length):
"""
Extract and spline part of centerline
within the geometry where
Expand Down
2 changes: 1 addition & 1 deletion morphman/common/vtk_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ def create_vtk_array(values, name, k=1):
"""Given a set of numpy values, and a name of the array create vtk array
Args:
values (numpy.ndarray): List of the values.
values (list, ndarray): List of the values.
name (str): Name of the array.
k (int): Length of tuple.
Expand Down
13 changes: 5 additions & 8 deletions morphman/manipulate_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,7 @@ def get_asymmetric_displacement(A, angle_asymmetric, factor_, frenet_normals_arr

def update_factor(A, AB_length, B, P_mid, factor, tmp_id1, tmp_id2):
"""
Update values in Factor based on midpoint between
A and B.
Update values in Factor based on midpoint between A and B.
Args:
P_mid (ndarray): Midpoint
Expand Down Expand Up @@ -521,21 +520,19 @@ def read_command_line_area(input_path=None, output_path=None):
args = parser.parse_args(["-i" + input_path, "-o" + output_path])

if args.method in ["stenosis", "bulge", "linear"] and args.region_of_interest == "first_line":
raise ValueError("Can not set region of interest to 'first_line' for 'stenosis'," + \
" 'bulge', or 'linear'")
raise ValueError("Can not set region of interest to 'first_line' for 'stenosis', 'bulge', or 'linear'")

if args.method == "variation" and args.ratio is not None and args.beta != 0.5:
print("WARNING: The beta value you provided will be ignored, using ratio instead.")

if args.region_points is not None:
if len(args.region_points) % 3 != 0 or len(args.region_points) > 6:
raise ValueError("ERROR: Please provide region point(s) as a multiple of 3, and maximum" +
" two points.")
raise ValueError("ERROR: Please provide region point(s) as a multiple of 3, and maximum two points.")

if args.no_smooth_point is not None and len(args.no_smooth_point):
if len(args.no_smooth_point) % 3 != 0:
raise ValueError("ERROR: Please provide the no smooth point(s) as a multiple" +
" of 3.")
raise ValueError("ERROR: Please provide the no smooth point(s) as a multiple of 3.")

if args.angle_asymmetric is not None:
angle_radians = args.angle_asymmetric * np.pi / 180 # Convert from deg to rad
else:
Expand Down
16 changes: 7 additions & 9 deletions morphman/manipulate_bifurcation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
from morphman.common.vessel_reconstruction_tools import *


def manipulate_bifurcation(input_filepath, output_filepath, smooth, smooth_factor, angle,
keep_fixed_1, keep_fixed_2, bif, lower, no_smooth, no_smooth_point,
poly_ball_size, cylinder_factor, resampling_step,
def manipulate_bifurcation(input_filepath, output_filepath, smooth, smooth_factor, angle, keep_fixed_1, keep_fixed_2,
bif, lower, no_smooth, no_smooth_point, poly_ball_size, cylinder_factor, resampling_step,
region_of_interest, region_points, tension, continuity):
"""
Objective rotation of daughter branches, by rotating
Expand All @@ -27,6 +26,8 @@ def manipulate_bifurcation(input_filepath, output_filepath, smooth, smooth_facto
Includes the option to rotate only one of the daughter branches.
Args:
tension (float): Tension parameter of Kochanek splines
continuity (float): Continuity parameter of Kochanek splines
input_filepath (str): Path to input surface.
output_filepath (str): Path to output surface.
smooth (bool): Determine if the voronoi diagram should be smoothed.
Expand Down Expand Up @@ -144,8 +145,7 @@ def manipulate_bifurcation(input_filepath, output_filepath, smooth, smooth_facto

# Clip the voronoi diagram
print("-- Clipping Voronoi diagram")
voronoi_clipped, voronoi_bifurcation = get_split_voronoi_diagram(voronoi, [patch_cl,
clipped_centerline])
voronoi_clipped, voronoi_bifurcation = get_split_voronoi_diagram(voronoi, [patch_cl, clipped_centerline])
write_polydata(voronoi_clipped, voronoi_clipped_path)
write_polydata(voronoi_bifurcation, voronoi_bifurcation_path)

Expand Down Expand Up @@ -284,7 +284,7 @@ def rotate_voronoi(clipped_voronoi, patch_cl, div_points, m, R):
for i in range(1, patch_cl.GetNumberOfCells()):
pnt = cell_line[i].GetPoints().GetPoint(0)
new = cell_line[0].GetPoints().GetPoint(locator[0].FindClosestPoint(pnt))
if get_distance(pnt, new) < tolerance*10:
if get_distance(pnt, new) < tolerance * 10:
not_rotate.append(i)

def check_rotate(point):
Expand Down Expand Up @@ -369,7 +369,7 @@ def rotate_cl(patch_cl, div_points, rotation_matrices, R):

start = cell.GetPoint(0)
dist = line0.GetPoint(locator0.FindClosestPoint(start))
test = get_distance(start, dist) > tolerance*10
test = get_distance(start, dist) > tolerance * 10

if test or len(div_points) == 2:
locator = get_vtk_point_locator(cell)
Expand Down Expand Up @@ -615,7 +615,6 @@ def read_command_line_bifurcation(input_path=None, output_path=None):
parser.add_argument("-c", "--continuity", type=float, default=0.8,
help="Set continuity of the KochanekSpline from -1 to 1")


# Bifurcation reconstruction arguments
parser.add_argument("--bif", type=str2bool, default=False,
help="interpolate bif as well")
Expand All @@ -638,7 +637,6 @@ def read_command_line_bifurcation(input_path=None, output_path=None):
if not (-1 <= args.continuity <= 1):
raise ValueError("Tension has to be between -1 and 1, not {}".format(args.continuity))


return dict(input_filepath=args.ifile, smooth=args.smooth, output_filepath=args.ofile,
smooth_factor=args.smooth_factor, angle=ang_,
keep_fixed_1=args.keep_fixed_1, keep_fixed_2=args.keep_fixed_2,
Expand Down
16 changes: 8 additions & 8 deletions morphman/manipulate_branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,26 +572,26 @@ def get_exact_surface_normal(capped_surface, new_branch_pos_id):
return new_normal


def get_estimated_surface_normal(diverging_centerline_branch):
def get_estimated_surface_normal(centerline):
"""
Estimate the surface normal at initial diverging centerline branch.
Args:
diverging_centerline_branch (vtkPolyData): Diverging centerline to be moved.
centerline (vtkPolyData): Diverging centerline to be moved.
Returns:
normal_vector (ndarray): Estimated normal vector at diverging centerline
"""
line = vmtk_compute_geometric_features(diverging_centerline_branch, True)
curvature = get_point_data_array("Curvature", line)
centerline = vmtk_compute_geometric_features(centerline, True)
curvature = get_point_data_array("Curvature", centerline)
first_local_maxima_id = argrelextrema(curvature, np.greater)[0][0]

# TODO: Generalize choice of end point factor
factor = 0.6
start_point = 0
end_point = int(first_local_maxima_id * factor)
normal_vector = np.asarray(diverging_centerline_branch.GetPoint(end_point)) - np.asarray(
diverging_centerline_branch.GetPoint(start_point))
normal_vector = np.asarray(centerline.GetPoint(end_point)) - np.asarray(
centerline.GetPoint(start_point))

normal_vector /= la.norm(normal_vector)

Expand All @@ -605,7 +605,7 @@ def manipulate_centerline_branch(centerline_branch, origin, R, dx, normal, angle
Args:
manipulation (str): Type of manipulation, either 'rotate' or 'translate'
centerline_branch (vtkPolyData): Centerline through surface
centerline_branch (vtkPolyData): Centerline branch to be manipulated
dx (float): Distance to translate branch
R (ndarray): Rotation matrix, rotation from old to new surface normal or around new surface normal
origin (ndarray): Adjusted origin / position of new branch position
Expand Down Expand Up @@ -681,7 +681,6 @@ def get_rotation_axis_and_angle(new_normal, old_normal):
return u, angle



def manipulate_voronoi_branch(voronoi, dx, R, origin, centerline, normal, angle, manipulation):
"""
Depending on manipulation method, either translates or
Expand Down Expand Up @@ -745,6 +744,7 @@ def manipulate_voronoi_branch(voronoi, dx, R, origin, centerline, normal, angle,
new_voronoi.SetPoints(voronoi_points)
new_voronoi.SetVerts(cell_array)
new_voronoi.GetPointData().AddArray(radius_array)

return new_voronoi


Expand Down
Loading

0 comments on commit 0fcab38

Please sign in to comment.