def random_gonio(): # make a random rotation axis with a random setting matrix axis = matrix.col(flex.random_double_point_on_sphere()) fixed_rotation = matrix.sqr((1, 0, 0, 0, 1, 0, 0, 0, 1)) setting_rotation = matrix.sqr(flex.random_double_r3_rotation_matrix()) goniometer = Goniometer(axis, fixed_rotation, setting_rotation) return goniometer
def test_uniform_rotation_matrix(N=10000, choice=2, verbose=False): """ The surface integral of a spherical harmonic function with its conjugate should be 1. (http://mathworld.wolfram.com/SphericalHarmonic.html, Eq 7) From Mathematica, l = 10; m = 10; y = SphericalHarmonicY[l, m, \[Theta], \[Phi]]; Integrate[y*Conjugate[y]*Sin[\[Theta]], {\[Theta], 0, Pi}, {\[Phi], 0, 2*Pi}] should yield 1. By picking uniformly random points on a sphere, the surface integral can be numerically approximated. The results in the comments below are for N = 1 000 000. """ if (choice == 0): # l=1, m=1 # result = (0.883199394206+0j) (0.883824001444+0j) lm = 1 c = -0.5 * math.sqrt(1.5 / math.pi) elif (choice == 1): # l = 5, m = 5 # result = (0.959557841214+0j) (0.959331535539+0j) lm = 5 c = -(3 / 32) * math.sqrt(77 / math.pi) else: # l = 10, m = 10 # result = (0.977753926603+0j) (0.97686871766+0j) lm = 10 c = (1 / 1024) * math.sqrt(969969 / math.pi) result = [0.0, 0.0] for i in range(N): R = [ matrix.sqr(flex.random_double_r3_rotation_matrix()), matrix.sqr(flex.random_double_r3_rotation_matrix_arvo_1992()) ] for j in xrange(len(result)): result[j] += add_point(lm, c, R[j]) # multipy by area at the end, each point has an area of 4pi/N point_area = 4.0 * math.pi / N # surface area of unit sphere / number of points for i in xrange(len(result)): result[i] = point_area * result[i] if (verbose): print result[i], if (verbose): print assert (result[0].real > 0.85) assert (result[0].real < 1.15) assert (result[1].real > 0.85) assert (result[1].real < 1.15)
def test_uniform_rotation_matrix(N=10000,choice=2,verbose=False): """ The surface integral of a spherical harmonic function with its conjugate should be 1. (http://mathworld.wolfram.com/SphericalHarmonic.html, Eq 7) From Mathematica, l = 10; m = 10; y = SphericalHarmonicY[l, m, \[Theta], \[Phi]]; Integrate[y*Conjugate[y]*Sin[\[Theta]], {\[Theta], 0, Pi}, {\[Phi], 0, 2*Pi}] should yield 1. By picking uniformly random points on a sphere, the surface integral can be numerically approximated. The results in the comments below are for N = 1 000 000. """ if (choice == 0): # l=1, m=1 # result = (0.883199394206+0j) (0.883824001444+0j) lm = 1 c = -0.5 * math.sqrt(1.5/math.pi) elif (choice == 1): # l = 5, m = 5 # result = (0.959557841214+0j) (0.959331535539+0j) lm = 5 c = -(3/32) * math.sqrt(77/math.pi) else: # l = 10, m = 10 # result = (0.977753926603+0j) (0.97686871766+0j) lm = 10 c = (1/1024) * math.sqrt(969969/math.pi) result = [ 0.0, 0.0 ] for i in range(N): R = [ matrix.sqr(flex.random_double_r3_rotation_matrix()), matrix.sqr(flex.random_double_r3_rotation_matrix_arvo_1992()) ] for j in xrange(len(result)): result[j] += add_point(lm,c,R[j]) # multipy by area at the end, each point has an area of 4pi/N point_area = 4.0*math.pi/N # surface area of unit sphere / number of points for i in xrange(len(result)): result[i] = point_area * result[i] if (verbose): print result[i], if (verbose): print assert(result[0].real > 0.85) assert(result[0].real < 1.15) assert(result[1].real > 0.85) assert(result[1].real < 1.15)
def exercise_axis_and_angle(axis_range=2, angle_max_division=12, angle_min_power=-30): from_matrix = scitbx.math.r3_rotation_axis_and_angle_from_matrix( r=[1, 0, 0, 0, 1, 0, 0, 0, 1]) assert approx_equal(from_matrix.axis, [1 / 3**0.5] * 3) assert approx_equal(from_matrix.angle(deg=True), 0) assert approx_equal(from_matrix.angle(deg=False), 0) from_matrix = scitbx.math.r3_rotation_axis_and_angle_from_matrix(r=[0] * 9) assert approx_equal(from_matrix.axis, [0, 0, 1]) assert approx_equal(from_matrix.angle(deg=True), 90) assert approx_equal(from_matrix.angle(deg=False), math.pi / 2) # angles = [] for d in range(1, angle_max_division + 1): angles.append(360 / d) angles.append(-360 / d) for p in range(-angle_min_power + 1): angles.append(10**(-p)) angles.append(-10**(-p)) hex_orth = matrix.sqr([ 8.7903631196301042, -4.3951815598150503, 0, 0, 7.6126777700894994, 0, 0, 0, 14.943617303371177 ]) for u in range(-axis_range, axis_range + 1): for v in range(-axis_range, axis_range + 1): for w in range(axis_range + 1): for axis in [(u, v, w), (hex_orth * matrix.col( (u, v, w))).elems]: for angle in angles: try: r = scitbx.math.r3_rotation_axis_and_angle_as_matrix( axis=axis, angle=angle, deg=True) except RuntimeError: assert axis == (0, 0, 0) try: scitbx.math.r3_rotation_axis_and_angle_as_unit_quaternion( axis=axis, angle=angle, deg=True) except RuntimeError: pass else: raise Exception_expected else: q = scitbx.math.r3_rotation_axis_and_angle_as_unit_quaternion( axis=axis, angle=angle, deg=True) assert approx_equal(abs(matrix.col(q)), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix( q=q) assert approx_equal(rq, r) from_matrix = scitbx.math.r3_rotation_axis_and_angle_from_matrix( r=r) rr = from_matrix.as_matrix() assert approx_equal(rr, r) qq = from_matrix.as_unit_quaternion() assert approx_equal(abs(matrix.col(qq)), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix( q=qq) assert approx_equal(rq, r) qq = scitbx.math.r3_rotation_matrix_as_unit_quaternion( r=r) assert approx_equal(abs(matrix.col(qq)), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix( q=qq) assert approx_equal(rq, r) rm = matrix.sqr(r) assert rm.is_r3_rotation_matrix() qm = rm.r3_rotation_matrix_as_unit_quaternion() assert approx_equal(abs(qm), 1) assert approx_equal(qm, qq) rqmm = qm.unit_quaternion_as_r3_rotation_matrix() assert approx_equal(rqmm, r) for deg in [False, True]: rr = scitbx.math.r3_rotation_axis_and_angle_as_matrix( axis=from_matrix.axis, angle=from_matrix.angle(deg=deg), deg=deg, min_axis_length=1 - 1.e-5) assert approx_equal(rr, r) qq = scitbx.math.r3_rotation_axis_and_angle_as_unit_quaternion( axis=from_matrix.axis, angle=from_matrix.angle(deg=deg), deg=deg, min_axis_length=1 - 1.e-5) qq = from_matrix.as_unit_quaternion() assert approx_equal(abs(matrix.col(qq)), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix( q=qq) assert approx_equal(rq, r) for conv in [ scitbx.math. r3_rotation_axis_and_angle_as_matrix, scitbx.math. r3_rotation_axis_and_angle_as_unit_quaternion ]: try: conv(axis=from_matrix.axis, angle=from_matrix.angle(deg=deg), deg=deg, min_axis_length=1 + 1.e-5) except RuntimeError: pass else: raise Exception_expected # for i_trial in range(100): r = flex.random_double_r3_rotation_matrix() from_matrix = scitbx.math.r3_rotation_axis_and_angle_from_matrix(r=r) rr = from_matrix.as_matrix() assert approx_equal(rr, r) assert approx_equal(math.cos(from_matrix.angle()), (r[0] + r[4] + r[8] - 1) / 2) q = matrix.col(from_matrix.as_unit_quaternion()) assert approx_equal(abs(q), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix(q=q) assert approx_equal(rq, r) rq = matrix.col(q).unit_quaternion_as_r3_rotation_matrix() assert approx_equal(rq, r)
def exercise_axis_and_angle( axis_range=2, angle_max_division=12, angle_min_power=-30): from_matrix = scitbx.math.r3_rotation_axis_and_angle_from_matrix( r=[1,0,0,0,1,0,0,0,1]) assert approx_equal(from_matrix.axis, [1/3**0.5]*3) assert approx_equal(from_matrix.angle(deg=True), 0) assert approx_equal(from_matrix.angle(deg=False), 0) from_matrix = scitbx.math.r3_rotation_axis_and_angle_from_matrix(r=[0]*9) assert approx_equal(from_matrix.axis, [0,0,1]) assert approx_equal(from_matrix.angle(deg=True), 90) assert approx_equal(from_matrix.angle(deg=False), math.pi/2) # angles = [] for d in xrange(1,angle_max_division+1): angles.append(360/d) angles.append(-360/d) for p in xrange(-angle_min_power+1): angles.append(10**(-p)) angles.append(-10**(-p)) hex_orth = matrix.sqr([ 8.7903631196301042, -4.3951815598150503, 0, 0, 7.6126777700894994, 0, 0, 0, 14.943617303371177]) for u in xrange(-axis_range, axis_range+1): for v in xrange(-axis_range, axis_range+1): for w in xrange(axis_range+1): for axis in [(u,v,w), (hex_orth*matrix.col((u,v,w))).elems]: for angle in angles: try: r = scitbx.math.r3_rotation_axis_and_angle_as_matrix( axis=axis, angle=angle, deg=True) except RuntimeError: assert axis == (0,0,0) try: scitbx.math.r3_rotation_axis_and_angle_as_unit_quaternion( axis=axis, angle=angle, deg=True) except RuntimeError: pass else: raise Exception_expected else: q = scitbx.math.r3_rotation_axis_and_angle_as_unit_quaternion( axis=axis, angle=angle, deg=True) assert approx_equal(abs(matrix.col(q)), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix(q=q) assert approx_equal(rq, r) from_matrix = scitbx.math.r3_rotation_axis_and_angle_from_matrix( r=r) rr = from_matrix.as_matrix() assert approx_equal(rr, r) qq = from_matrix.as_unit_quaternion() assert approx_equal(abs(matrix.col(qq)), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix(q=qq) assert approx_equal(rq, r) qq = scitbx.math.r3_rotation_matrix_as_unit_quaternion(r=r) assert approx_equal(abs(matrix.col(qq)), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix(q=qq) assert approx_equal(rq, r) rm = matrix.sqr(r) assert rm.is_r3_rotation_matrix() qm = rm.r3_rotation_matrix_as_unit_quaternion() assert approx_equal(abs(qm), 1) assert approx_equal(qm, qq) rqmm = qm.unit_quaternion_as_r3_rotation_matrix() assert approx_equal(rqmm, r) for deg in [False, True]: rr = scitbx.math.r3_rotation_axis_and_angle_as_matrix( axis=from_matrix.axis, angle=from_matrix.angle(deg=deg), deg=deg, min_axis_length=1-1.e-5) assert approx_equal(rr, r) qq = scitbx.math.r3_rotation_axis_and_angle_as_unit_quaternion( axis=from_matrix.axis, angle=from_matrix.angle(deg=deg), deg=deg, min_axis_length=1-1.e-5) qq = from_matrix.as_unit_quaternion() assert approx_equal(abs(matrix.col(qq)), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix(q=qq) assert approx_equal(rq, r) for conv in [ scitbx.math.r3_rotation_axis_and_angle_as_matrix, scitbx.math.r3_rotation_axis_and_angle_as_unit_quaternion]: try: conv( axis=from_matrix.axis, angle=from_matrix.angle(deg=deg), deg=deg, min_axis_length=1+1.e-5) except RuntimeError: pass else: raise Exception_expected # for i_trial in xrange(100): r = flex.random_double_r3_rotation_matrix() from_matrix = scitbx.math.r3_rotation_axis_and_angle_from_matrix(r=r) rr = from_matrix.as_matrix() assert approx_equal(rr, r) assert approx_equal(math.cos(from_matrix.angle()), (r[0]+r[4]+r[8]-1)/2) q = matrix.col(from_matrix.as_unit_quaternion()) assert approx_equal(abs(q), 1) rq = scitbx.math.r3_rotation_unit_quaternion_as_matrix(q=q) assert approx_equal(rq, r) rq = matrix.col(q).unit_quaternion_as_r3_rotation_matrix() assert approx_equal(rq, r)