Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 4d83b318 authored by NADAL Morgane's avatar NADAL Morgane
Browse files

handle singular matrices

parent 685f23fe
No related branches found
No related tags found
No related merge requests found
...@@ -42,17 +42,22 @@ def ls_ellipsoid(xx: array_t, yy: array_t, zz: array_t) -> array_t: # finds the ...@@ -42,17 +42,22 @@ def ls_ellipsoid(xx: array_t, yy: array_t, zz: array_t) -> array_t: # finds the
JT = J.transpose() JT = J.transpose()
JTJ = np_.dot(JT, J) JTJ = np_.dot(JT, J)
InvJTJ = np_.linalg.inv(JTJ); try:
ABC = np_.dot(InvJTJ, np_.dot(JT, K)) InvJTJ = np_.linalg.inv(JTJ);
ABC = np_.dot(InvJTJ, np_.dot(JT, K))
# Rearrange, move the 1 to the other side # Rearrange, move the 1 to the other side
# Ax^2 + By^2 + Cz^2 + Dxy + Exz + Fyz + Gx + Hy + Iz - 1 = 0 # Ax^2 + By^2 + Cz^2 + Dxy + Exz + Fyz + Gx + Hy + Iz - 1 = 0
# or # or
# Ax^2 + By^2 + Cz^2 + Dxy + Exz + Fyz + Gx + Hy + Iz + J = 0 # Ax^2 + By^2 + Cz^2 + Dxy + Exz + Fyz + Gx + Hy + Iz + J = 0
# where J = -1 # where J = -1
ellipsoid_coef = np_.append(ABC, -1) ellipsoid_coef = np_.append(ABC, -1)
return (ellipsoid_coef) return (ellipsoid_coef)
except:
print("Singular matrix, cannot find the best fitting ellipsoid.")
return (np_.zeros(9))
def polyToParams3D(ellipsoid_coef: array_t, printMe: bool = False) -> tuple: def polyToParams3D(ellipsoid_coef: array_t, printMe: bool = False) -> tuple:
...@@ -70,74 +75,78 @@ def polyToParams3D(ellipsoid_coef: array_t, printMe: bool = False) -> tuple: ...@@ -70,74 +75,78 @@ def polyToParams3D(ellipsoid_coef: array_t, printMe: bool = False) -> tuple:
if printMe: if printMe:
print('\npolynomial\n', ellipsoid_coef) print('\npolynomial\n', ellipsoid_coef)
Amat = np_.array( if ellipsoid_coef == (np_.zeros(9)):
[ return "NaN", "NaN", "NaN", "NaN"
[ellipsoid_coef[0], ellipsoid_coef[3] / 2.0, ellipsoid_coef[4] / 2.0, ellipsoid_coef[6] / 2.0],
[ellipsoid_coef[3] / 2.0, ellipsoid_coef[1], ellipsoid_coef[5] / 2.0, ellipsoid_coef[7] / 2.0], else:
[ellipsoid_coef[4] / 2.0, ellipsoid_coef[5] / 2.0, ellipsoid_coef[2], ellipsoid_coef[8] / 2.0], Amat = np_.array(
[ellipsoid_coef[6] / 2.0, ellipsoid_coef[7] / 2.0, ellipsoid_coef[8] / 2.0, ellipsoid_coef[9]] [
]) [ellipsoid_coef[0], ellipsoid_coef[3] / 2.0, ellipsoid_coef[4] / 2.0, ellipsoid_coef[6] / 2.0],
[ellipsoid_coef[3] / 2.0, ellipsoid_coef[1], ellipsoid_coef[5] / 2.0, ellipsoid_coef[7] / 2.0],
if printMe: [ellipsoid_coef[4] / 2.0, ellipsoid_coef[5] / 2.0, ellipsoid_coef[2], ellipsoid_coef[8] / 2.0],
print('\nAlgebraic form of polynomial\n', Amat) [ellipsoid_coef[6] / 2.0, ellipsoid_coef[7] / 2.0, ellipsoid_coef[8] / 2.0, ellipsoid_coef[9]]
])
# See B.Bartoni, Preprint SMU-HEP-10-14 Multi-dimensional Ellipsoidal Fitting
# equation 20 for the following method for finding the center if printMe:
A3 = Amat[0:3, 0:3] print('\nAlgebraic form of polynomial\n', Amat)
A3inv = inv(A3)
ofs = ellipsoid_coef[6:9] / 2.0 # See B.Bartoni, Preprint SMU-HEP-10-14 Multi-dimensional Ellipsoidal Fitting
center = -np_.dot(A3inv, ofs) # equation 20 for the following method for finding the center
if printMe: A3 = Amat[0:3, 0:3]
print('\nCenter at:', center) A3inv = inv(A3)
ofs = ellipsoid_coef[6:9] / 2.0
# Center the ellipsoid at the origin center = -np_.dot(A3inv, ofs)
Tofs = np_.eye(4) if printMe:
Tofs[3, 0:3] = center print('\nCenter at:', center)
R = np_.dot(Tofs, np_.dot(Amat, Tofs.T))
if printMe: # Center the ellipsoid at the origin
print('\nAlgebraic form translated to center\n', R, '\n') Tofs = np_.eye(4)
Tofs[3, 0:3] = center
R3 = R[0:3, 0:3] R = np_.dot(Tofs, np_.dot(Amat, Tofs.T))
s1 = -R[3, 3] if printMe:
R3S = R3 / s1 print('\nAlgebraic form translated to center\n', R, '\n')
(el, ec) = eig(R3S) R3 = R[0:3, 0:3]
el = np_.abs(el) s1 = -R[3, 3]
R3S = R3 / s1
# Sorting in descending order of the eigenvalues and eigenvectors
sorting_vec = np_.argsort(-el) (el, ec) = eig(R3S)
el = el[sorting_vec] el = np_.abs(el)
ec = ec[:, sorting_vec]
# Sorting in descending order of the eigenvalues and eigenvectors
# Calculating cartesian axes sorting_vec = np_.argsort(-el)
recip = 1.0 / el el = el[sorting_vec]
axes = np_.sqrt(recip) # axes are in ascending order ec = ec[:, sorting_vec]
if printMe:
print('\nAxes are\n', axes, '\n') # Calculating cartesian axes
recip = 1.0 / el
# Calculating the orientation axes = np_.sqrt(recip) # axes are in ascending order
inverse = inv(ec) # inverse is actually the transpose here if printMe:
if printMe: print('\nAxes are\n', axes, '\n')
print('\nRotation matrix\n', inverse)
# Calculating the orientation
# Calculating spherical axes inverse = inv(ec) # inverse is actually the transpose here
# # eigenvector 1 if printMe:
r1 = np_.sqrt(sum(axe**2 for axe in ec[:, 0])) print('\nRotation matrix\n', inverse)
phi1 = np_.arctan2(ec[1, 0], ec[0, 0])
theta1 = np_.arccos(ec[2, 0] / r1) # Calculating spherical axes
spherical_axes1 = (r1, theta1, phi1) # # eigenvector 1
# # eigenvector 2 r1 = np_.sqrt(sum(axe**2 for axe in ec[:, 0]))
r2 = np_.sqrt(sum(axe**2 for axe in ec[:, 1])) phi1 = np_.arctan2(ec[1, 0], ec[0, 0])
phi2 = np_.arctan2(ec[1, 1], ec[0, 1]) theta1 = np_.arccos(ec[2, 0] / r1)
theta2 = np_.arccos(ec[2, 1] / r2) spherical_axes1 = (r1, theta1, phi1)
spherical_axes2 = (r2, theta2, phi2) # # eigenvector 2
r2 = np_.sqrt(sum(axe**2 for axe in ec[:, 1]))
spherical_axes = (spherical_axes1, spherical_axes2) phi2 = np_.arctan2(ec[1, 1], ec[0, 1])
theta2 = np_.arccos(ec[2, 1] / r2)
if printMe: spherical_axes2 = (r2, theta2, phi2)
print('\nAxes in spherical coord are\n', spherical_axes, '\n')
spherical_axes = (spherical_axes1, spherical_axes2)
return center, axes, inverse, spherical_axes
if printMe:
print('\nAxes in spherical coord are\n', spherical_axes, '\n')
return center, axes, inverse, spherical_axes
def GetConvexHull3D(soma_sites: site_h) -> tuple: def GetConvexHull3D(soma_sites: site_h) -> tuple:
...@@ -169,7 +178,12 @@ def FindBestFittingEllipsoid3D(soma: soma_t) -> tuple: ...@@ -169,7 +178,12 @@ def FindBestFittingEllipsoid3D(soma: soma_t) -> tuple:
# fit ellipsoid on the convex hull # fit ellipsoid on the convex hull
# # get ellipsoid polynomial coefficients # # get ellipsoid polynomial coefficients
ellipsoid_coef = ls_ellipsoid(convex_hull[0], convex_hull[1], convex_hull[2]) ellipsoid_coef = ls_ellipsoid(convex_hull[0], convex_hull[1], convex_hull[2])
# # get ellipsoid 3D parameters
center, axes, orientation, spherical_coor = polyToParams3D(ellipsoid_coef, False)
return ellipsoid_coef, center, axes, orientation, spherical_coor, convex_hull, volume_hull if ellipsoid_coef == (np_.zeros(9)):
return ellipsoid_coef, "NaN", "NaN", "NaN", "NaN", "NaN", "NaN"
else:
# # get ellipsoid 3D parameters
center, axes, orientation, spherical_coor = polyToParams3D(ellipsoid_coef, False)
return ellipsoid_coef, center, axes, orientation, spherical_coor, convex_hull, volume_hull
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment