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
Example #2
0
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)
Example #4
0
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)