Commit eb306911 authored by Stephen Thompson's avatar Stephen Thompson

Merge branch '1-get-working'

parents fc9d1406 3e9f9cb0
Pipeline #2169 passed with stages
in 11 minutes and 18 seconds
......@@ -24,6 +24,15 @@ Requirements
+------------+--------------------------------------------------------+-------------------------------------+
| 0002 | Package has a version number | No test yet, handled by git. |
+------------+--------------------------------------------------------+-------------------------------------+
| 0003 | Provides a function to fit a sphere to a list of | |
| | 3 dimensional points | |
+------------+--------------------------------------------------------+-------------------------------------+
| 0004 | Allows for configuration via a python dictionary | |
+------------+--------------------------------------------------------+-------------------------------------+
| 0005 | Provides a command line application | |
+------------+--------------------------------------------------------+-------------------------------------+
| 0006 | What else ?? | |
+------------+--------------------------------------------------------+-------------------------------------+
......
......@@ -3,3 +3,4 @@
# confused with the software requirements, which are listed in
# doc/requirements.rst
numpy
scipy
# coding=utf-8
""" Module for adding numbers. """
def add_two_numbers(input_x, input_y):
""" Add two numbers """
return input_x + input_y
# coding=utf-8
""" Module for multiplying numbers. """
def multiply_two_numbers(input_x, input_y):
""" Multiply two numbers """
return input_x * input_y
# coding=utf-8
""" Module for fitting a sphere to a list of 3D points """
#scipy has a nice least squares optimisor
from scipy.optimize import leastsq
import numpy
def fit_sphere_least_squares(x_values, y_values, z_values, initial_parameters):
"""
Uses scipy's least squares optimisor to fit a sphere to a set
of 3D Points
:return: x: an array containing the four fitted parameters
:return: ier: int An integer flag. If it is equal to 1, 2, 3 or 4, the
solution was found.
:param: (x,y,z) three arrays of equal length containing the x, y, and z
coordinates.
:param: an array containing four initial values (centre, and radius)
"""
return leastsq(_calculate_residual_sphere, initial_parameters,
args=(x_values, y_values, z_values))
def _calculate_residual_sphere(parameters, x_values, y_values, z_values):
"""
Calculates the residual error for an x,y,z coordinates, fitted
to a sphere with centre and radius defined by the parameters tuple
:return: The residual error
:param: A tuple of the parameters to be optimised, should contain
[x_centre, y_centre, z_centre, radius]
:param: arrays containing the x,y, and z coordinates.
"""
#extract the parameters
x_centre, y_centre, z_centre, radius = parameters
#use numpy's sqrt function here, which works by element on arrays
distance_from_centre = numpy.sqrt((x_values - x_centre)**2 +
(y_values - y_centre)**2 +
(z_values - z_centre)**2)
return distance_from_centre - radius
......@@ -9,7 +9,7 @@
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
ignore=CVS, ui
# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
......
......@@ -2,26 +2,57 @@
"""scikit-surgery-sphere-fitting tests"""
from sksurgeryspherefitting.ui.sksurgeryspherefitting_demo import run_demo
from sksurgeryspherefitting.algorithms import addition, multiplication
import numpy
#from sksurgeryspherefitting.ui.sksurgeryspherefitting_demo import run_demo
from sksurgeryspherefitting.algorithms import sphere_fitting
import six
# Pytest style
def test_using_pytest_sksurgeryspherefitting():
x = 1
y = 2
verbose = False
multiply = False
expected_answer = 3
assert run_demo(x, y, multiply, verbose) == expected_answer
def test_addition():
assert addition.add_two_numbers(1, 2) == 3
def test_multiplication():
assert multiplication.multiply_two_numbers(2, 2) == 4
#def test_using_pytest_sksurgeryspherefitting():
# x = 1
# y = 2
# verbose = False
# multiply = False
# expected_answer = 3
# assert run_demo(x, y, multiply, verbose) == expected_answer
def test_fit_sphere_least_squares():
x_centre = 1.0
y_centre = 167.0
z_centre = 200.0
radius = 7.5
#some arrays to fit data to
xs=numpy.ndarray(shape=(1000,),dtype=float )
ys=numpy.ndarray(shape=(1000,),dtype=float )
zs=numpy.ndarray(shape=(1000,),dtype=float )
#fill the arrays with points uniformly spread on
#a sphere centred at x,y,z with radius radius
#first seed the random generator so we get consistent test behaviour
numpy.random.seed(seed=0)
for i in range(1000):
#make a random vector
x=numpy.random.uniform(-1.0, 1.0)
y=numpy.random.uniform(-1.0, 1.0)
z=numpy.random.uniform(-1.0, 1.0)
#scale it to length radius
length=numpy.sqrt( (x)**2 + (y)**2 + (z)**2 )
factor = radius / length
xs[i] = x*factor + x_centre
ys[i] = y*factor + y_centre
zs[i] = z*factor + z_centre
parameters = [0.0, 0.0, 0.0, 0.0]
result = sphere_fitting.fit_sphere_least_squares (xs, ys, zs, parameters)
numpy.testing.assert_approx_equal (result[0][0], x_centre, significant = 10)
numpy.testing.assert_approx_equal (result[0][1], y_centre, significant = 10)
numpy.testing.assert_approx_equal (result[0][2], z_centre, significant = 10)
numpy.testing.assert_approx_equal (result[0][3], radius, significant = 10)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment