Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

corner cases of Transform class #543

Open
wjiang opened this issue Feb 18, 2022 · 7 comments
Open

corner cases of Transform class #543

wjiang opened this issue Feb 18, 2022 · 7 comments

Comments

@wjiang
Copy link

wjiang commented Feb 18, 2022

The following code demonstrates that the Transform class does not properly handle the conversion to spin/quaternion for some Euler angles. The two distinct Euler angles with phi and 360-phi will produce identical spin/quaternion. The scipy.spatial.transform.Rotation class is fine for these angles.

import EMAN2
t = EMAN2.Transform()
for alt in [179.9, 180]:	# 179 works but 180 fails
	for phi in [37, 360-37]:	# 37 or any angle here will reproduce the issue
		t.set_rotation(dict(type='eman', az=0, alt=alt, phi=phi))
		print(t.get_rotation('eman'))
		#print("\t%s" % (t.get_rotation('matrix')))	# ok
		#print("\t%s" % (t.get_rotation('spin')))	# problematic
		print("\t%s" % (t.get_rotation('quaternion')))	# problematic

@ghost
Copy link

ghost commented Feb 18, 2022 via email

@wjiang
Copy link
Author

wjiang commented Feb 18, 2022

I should have included the outputs:

{'alt': 179.0000000534512, 'az': 0.0, 'phi': 37.00000140230337, 'type': 'eman'}
	{'e0': 0.00827471061039176, 'e1': 0.9483871831915285, 'e2': -0.31732592276992155, 'e3': 0.0027696419845010937, 'type': 'quaternion'}
{'alt': 179.0000000534512, 'az': 0.0, 'phi': 322.9999985976966, 'type': 'eman'}
	{'e0': 0.00827471061039176, 'e1': 0.9483871831915285, 'e2': 0.31732592276992155, 'e3': -0.0027696419845010937, 'type': 'quaternion'}
{'alt': 180.0, 'az': 0.0, 'phi': 37.00000193417059, 'type': 'eman'}
	{'e0': 0.0, 'e1': 0.9483236480200433, 'e2': 0.3173046778822478, 'e3': 0.0, 'type': 'quaternion'}
{'alt': 180.0, 'az': 0.0, 'phi': 322.9999980658294, 'type': 'eman'}
	{'e0': 0.0, 'e1': 0.9483236480200433, 'e2': 0.3173046778822478, 'e3': 0.0, 'type': 'quaternion'}

The quaternions are different for the two Eulers (alt=179, az=0, phi=37) and (alt=179, az=0, phi=323) as expected, but are identical for Eulers (alt=180, az=0, phi=37) and Eulers (alt=180, az=0, phi=37) that should not.

@ghost
Copy link

ghost commented Feb 18, 2022 via email

@ghost
Copy link

ghost commented Feb 20, 2022 via email

@wjiang
Copy link
Author

wjiang commented Feb 22, 2022

a few more tests with the follow code suggest that the quaternions are not self consistent as setting rotation with the returned quaternions would result in a different Transform as measured by the rotation matrix (v2.91). Interestingly, the same tests are fine with an older version (2.23).

import EMAN2
import numpy as np

phi = np.random.random()*360
theta = np.random.random()*180 
psi = np.random.random()*360 

def get_matrix_numpy(transform):
	m = transform.get_rotation('matrix')		
	m = np.array([
		[ m['m11'], m['m12'], m['m13'] ],
		[ m['m21'], m['m22'], m['m23'] ],
		[ m['m31'], m['m32'], m['m33'] ]
		])
	return m
	
t = EMAN2.Transform(dict(type='spider', phi=phi, theta=theta, psi=psi))
print(t.get_rotation('spider'))

m = get_matrix_numpy(t)

t.set_rotation(t.get_rotation('spider'))
m2 = get_matrix_numpy(t)
print("m spider\n", m)
print("m2 spider\n", m2)
assert(np.allclose(m, m2, atol=1e-6))	# always pass

t.set_rotation(t.get_rotation('matrix'))
m2 = get_matrix_numpy(t)
print("m2 matrix\n", m2)
assert(np.allclose(m, m2, atol=1e-6))	# always pass

t.set_rotation(t.get_rotation('quaternion'))
m2 = get_matrix_numpy(t)
print("m2 quaternion\n", m2)
assert(np.allclose(m, m2, atol=1e-6))	# pass (v2.23) but fail (v2.91)

Outputs for v2.23:

{'theta': 20.821667151647016, 'phi': 74.98372483565657, 'psi': 336.0864770394823, 'type': 'spider'}
('m spider\n', array([[ 0.61289924,  0.72025269, -0.32494712],
       [-0.7847755 ,  0.6027984 , -0.14408851],
       [ 0.09209748,  0.34332228,  0.93469131]]))
('m2 spider\n', array([[ 0.61289918,  0.72025269, -0.32494712],
       [-0.78477556,  0.60279834, -0.14408851],
       [ 0.09209746,  0.34332228,  0.93469131]]))
('m2 matrix\n', array([[ 0.61289918,  0.72025269, -0.32494712],
       [-0.78477556,  0.60279834, -0.14408851],
       [ 0.09209746,  0.34332228,  0.93469131]]))
('m2 quaternion\n', array([[ 0.61289912,  0.72025269, -0.32494712],
       [-0.78477556,  0.60279828, -0.14408849],
       [ 0.09209745,  0.34332228,  0.93469131]]))

Outputs for v.2.91:

{'phi': 262.6421402967897, 'psi': 264.7865592745186, 'theta': 92.20078133895466, 'type': 'spider'}
m spider
 [[-0.98810965  0.12407576  0.09079918]
 [-0.08522039  0.04956456 -0.99512857]
 [-0.12797174 -0.99103409 -0.03840144]]
m2 spider
 [[-0.98810965  0.12407575  0.09079918]
 [-0.08522039  0.04956456 -0.99512857]
 [-0.12797174 -0.99103409 -0.03840144]]
m2 matrix
 [[-0.98810965  0.12407575  0.09079918]
 [-0.08522039  0.04956456 -0.99512857]
 [-0.12797174 -0.99103409 -0.03840144]]
m2 quaternion
 [[-0.99863003 -0.04771598  0.02147503]
 [ 0.05219268 -0.87907547  0.47381665]
 [-0.00373045  0.4742884   0.88036157]]

@ghost
Copy link

ghost commented Feb 22, 2022 via email

@prbprb2
Copy link
Contributor

prbprb2 commented Mar 5, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants