Esempio n. 1
0
def dRq_de(theta, e, q):
  '''Calculate derivative of rotated vector r = R*q with respect to the elements
  of the rotation axis e, where the angle of rotation is theta.

  Implementation of Equation (8) from Gallego & Yezzi.

  NB a C++ version exists in gallego_yezzi.h.'''

  from scitbx import matrix

  # ensure e is unit vector
  e = e.normalize()

  # rotation matrix
  R = e.axis_and_angle_as_r3_rotation_matrix(theta, deg=False)

  # rotation vector v
  v = theta * e

  qx = skew_symm(q)
  vx = skew_symm(v)
  vvt = v*v.transpose()
  Rt = R.transpose()
  I3 = matrix.identity(3)

  return (-1./theta) * R * qx * (vvt + (Rt - I3) * vx)
Esempio n. 2
0
def align_reference_frame(primary_axis, primary_target,
                          secondary_axis, secondary_target):
  """Compute a rotation matrix R: R x primary_axis = primary_target and
  R x secondary_axis places the secondary_axis in the plane perpendicular
  to the primary_target, as close as possible to the secondary_target.
  Require: primary_target orthogonal to secondary_target, primary axis
  not colinear with secondary axis."""

  from scitbx import matrix
  import math

  if type(primary_axis) == type(()) or type(primary_axis) == type([]):
    primary_axis = matrix.col(primary_axis).normalize()
  else:
    primary_axis = primary_axis.normalize()

  if type(primary_target) == type(()) or type(primary_target) == type([]):
    primary_target = matrix.col(primary_target).normalize()
  else:
    primary_target = primary_target.normalize()

  if type(secondary_axis) == type(()) or type(secondary_axis) == type([]):
    secondary_axis = matrix.col(secondary_axis).normalize()
  else:
    secondary_axis = secondary_axis.normalize()

  if type(secondary_target) == type(()) or \
         type(secondary_target) == type([]):
    secondary_target = matrix.col(secondary_target).normalize()
  else:
    secondary_target = secondary_target.normalize()

  # check properties of input axes

  assert(math.fabs(primary_axis.angle(secondary_axis) % math.pi) > 0.001)
  assert(primary_target.dot(secondary_target) < 0.001)

  if primary_target.angle(primary_axis) % math.pi:
    axis_p = primary_target.cross(primary_axis)
    angle_p = - primary_target.angle(primary_axis)
    Rprimary = axis_p.axis_and_angle_as_r3_rotation_matrix(angle_p)
  elif primary_target.angle(primary_axis) < 0:
    axis_p = primary_axis.ortho().normalize()
    angle_p = math.pi
    Rprimary = axis_p.axis_and_angle_as_r3_rotation_matrix(angle_p)
  else:
    Rprimary = matrix.identity(3)

  axis_r = secondary_target.cross(Rprimary * secondary_axis)
  axis_s = primary_target
  if (axis_r.angle(primary_target) > 0.5 * math.pi):
    angle_s = orthogonal_component(axis_s, secondary_target).angle(
        orthogonal_component(axis_s, Rprimary * secondary_axis))
  else:
    angle_s = - orthogonal_component(axis_s, secondary_target).angle(
        orthogonal_component(axis_s, Rprimary * secondary_axis))

  Rsecondary = axis_s.axis_and_angle_as_r3_rotation_matrix(angle_s)

  return Rsecondary * Rprimary
Esempio n. 3
0
  def exercise_ls_cycles(self):
    xs = self.xray_structure.deep_copy_scatterers()
    connectivity_table = smtbx.utils.connectivity_table(xs)
    emma_ref = xs.as_emma_model()
    # shaking must happen before the reparametrisation is constructed,
    # otherwise the original values will prevail
    xs.shake_sites_in_place(rms_difference=0.1)
    reparametrisation = constraints.reparametrisation(
      structure=xs,
      constraints=[],
      connectivity_table=connectivity_table)
    ls = least_squares.crystallographic_ls(
      self.fo_sq.as_xray_observations(), reparametrisation,
      weighting_scheme=least_squares.unit_weighting(),
      origin_fixing_restraints_type=
      origin_fixing_restraints.atomic_number_weighting)

    cycles = normal_eqns_solving.naive_iterations(
      ls,
      n_max_iterations=5,
      track_all=True)

    assert approx_equal(ls.scale_factor(), 1, eps=1e-5)
    assert approx_equal(ls.objective(), 0)
    # skip next-to-last one to allow for no progress and rounding error
    assert (
      cycles.objective_history[0]
      >= cycles.objective_history[1]
      >= cycles.objective_history[3]), numstr(cycles.objective_history)
    assert approx_equal(cycles.gradient_norm_history[-1], 0, eps=5e-8)

    match = emma.model_matches(emma_ref, xs.as_emma_model()).refined_matches[0]
    assert match.rt.r == matrix.identity(3)
    for pair in match.pairs:
      assert approx_equal(match.calculate_shortest_dist(pair), 0, eps=1e-4)
  def exercise_ls_cycles(self):
    xs = self.xray_structure.deep_copy_scatterers()
    connectivity_table = smtbx.utils.connectivity_table(xs)
    emma_ref = xs.as_emma_model()
    # shaking must happen before the reparametrisation is constructed,
    # otherwise the original values will prevail
    xs.shake_sites_in_place(rms_difference=0.1)
    reparametrisation = constraints.reparametrisation(
      structure=xs,
      constraints=[],
      connectivity_table=connectivity_table)
    ls = least_squares.crystallographic_ls(
      self.fo_sq.as_xray_observations(), reparametrisation,
      weighting_scheme=least_squares.mainstream_shelx_weighting(a=0),
      origin_fixing_restraints_type=
      origin_fixing_restraints.atomic_number_weighting)

    cycles = normal_eqns_solving.naive_iterations(
      ls,
      gradient_threshold=1e-12,
      step_threshold=1e-7,
      track_all=True)

    assert approx_equal(ls.scale_factor(), 1, eps=1e-5), ls.scale_factor()
    assert approx_equal(ls.objective(), 0), ls.objective()

    match = emma.model_matches(emma_ref, xs.as_emma_model()).refined_matches[0]
    assert match.rt.r == matrix.identity(3)
    for pair in match.pairs:
      assert approx_equal(match.calculate_shortest_dist(pair), 0, eps=1e-4)
Esempio n. 5
0
def dRq_de(theta, e, q):
    '''Calculate derivative of rotated vector r = R*q with respect to the elements
  of the rotation axis e, where the angle of rotation is theta.

  Implementation of Equation (8) from Gallego & Yezzi.

  NB a C++ version exists in gallego_yezzi.h.'''

    from scitbx import matrix

    # ensure e is unit vector
    e = e.normalize()

    # rotation matrix
    R = e.axis_and_angle_as_r3_rotation_matrix(theta, deg=False)

    # rotation vector v
    v = theta * e

    qx = skew_symm(q)
    vx = skew_symm(v)
    vvt = v * v.transpose()
    Rt = R.transpose()
    I3 = matrix.identity(3)

    return (-1. / theta) * R * qx * (vvt + (Rt - I3) * vx)
Esempio n. 6
0
  def __init__(self, r, d, symmetry_agreement, status):
    assert r.den() == 1
    self.r = r
    order = r.order()
    self.r_info = sgtbx.rot_mx_info(r)
    type = self.r_info.type()
    axis = self.r_info.ev()

    self.symmetry_agreement = symmetry_agreement
    self.status = status

    # compute intrinsic and location part of d, using p, which is
    # the order times the projector onto r's invariant space
    p = mat.sqr(r.accumulate().as_double())
    t_i_num = (p*d).as_int()
    t_l = d - t_i_num/order
    t_i = sgtbx.tr_vec(sg_t_den//order*t_i_num, tr_den=sg_t_den)

    # compute the origin corresponding to t_l by solving
    # (1 - r) o = t_l
    one_minus_r = -mat.sqr(self.r.minus_unit_mx().num())
    one_minus_r_row_echelon = one_minus_r.as_flex_int_matrix()
    q = mat.identity(3).as_flex_int_matrix()
    rank = scitbx.math.row_echelon_form_t(one_minus_r_row_echelon, q)
    qd = flex.double(mat.sqr(q)*t_l)[:rank]
    o = flex.double((0,0,0))
    scitbx.math.row_echelon_back_substitution_float(
      one_minus_r_row_echelon, qd, o)

    # construct object state
    self.t_i, self.raw_origin = t_i, mat.col(o)
    self.origin = None
    self.one_minus_r = one_minus_r
  def exercise_ls_cycles(self):
    xs = self.xray_structure.deep_copy_scatterers()
    connectivity_table = smtbx.utils.connectivity_table(xs)
    emma_ref = xs.as_emma_model()
    # shaking must happen before the reparametrisation is constructed,
    # otherwise the original values will prevail
    xs.shake_sites_in_place(rms_difference=0.1)
    reparametrisation = constraints.reparametrisation(
      structure=xs,
      constraints=[],
      connectivity_table=connectivity_table)
    ls = least_squares.crystallographic_ls(
      self.fo_sq.as_xray_observations(), reparametrisation,
      weighting_scheme=least_squares.mainstream_shelx_weighting(a=0),
      origin_fixing_restraints_type=
      origin_fixing_restraints.atomic_number_weighting)

    cycles = normal_eqns_solving.naive_iterations(
      ls,
      gradient_threshold=1e-12,
      step_threshold=1e-7,
      track_all=True)

    assert approx_equal(ls.scale_factor(), 1, eps=1e-5), ls.scale_factor()
    assert approx_equal(ls.objective(), 0), ls.objective()

    match = emma.model_matches(emma_ref, xs.as_emma_model()).refined_matches[0]
    assert match.rt.r == matrix.identity(3)
    for pair in match.pairs:
      assert approx_equal(match.calculate_shortest_dist(pair), 0, eps=1e-4)
Esempio n. 8
0
    def __init__(self, r, d, symmetry_agreement, status):
        assert r.den() == 1
        self.r = r
        order = r.order()
        self.r_info = sgtbx.rot_mx_info(r)
        type = self.r_info.type()
        axis = self.r_info.ev()

        self.symmetry_agreement = symmetry_agreement
        self.status = status

        # compute intrinsic and location part of d, using p, which is
        # the order times the projector onto r's invariant space
        p = mat.sqr(r.accumulate().as_double())
        t_i_num = (p * d).as_int()
        t_l = d - t_i_num / order
        t_i = sgtbx.tr_vec(sg_t_den // order * t_i_num, tr_den=sg_t_den)

        # compute the origin corresponding to t_l by solving
        # (1 - r) o = t_l
        one_minus_r = -mat.sqr(self.r.minus_unit_mx().num())
        one_minus_r_row_echelon = one_minus_r.as_flex_int_matrix()
        q = mat.identity(3).as_flex_int_matrix()
        rank = scitbx.math.row_echelon_form_t(one_minus_r_row_echelon, q)
        qd = flex.double(mat.sqr(q) * t_l)[:rank]
        o = flex.double((0, 0, 0))
        scitbx.math.row_echelon_back_substitution_float(
            one_minus_r_row_echelon, qd, o)

        # construct object state
        self.t_i, self.raw_origin = t_i, mat.col(o)
        self.origin = None
        self.one_minus_r = one_minus_r
def test_align_reference_frame():

    _i = (1, 0, 0)
    _j = (0, 1, 0)
    _k = (0, 0, 1)

    primary_axis = _i
    primary_target = _i
    secondary_axis = _k
    secondary_target = _k

    m = align_reference_frame(primary_axis, primary_target,
                              secondary_axis, secondary_target)

    i = matrix.identity(3)

    for j in range(9):
        assert(math.fabs(m.elems[j] - i.elems[j]) < 0.001)

    primary_axis = _j
    primary_target = _i
    secondary_axis = _k
    secondary_target = _k

    m = align_reference_frame(primary_axis, primary_target,
                              secondary_axis, secondary_target)

    for j in range(3):
        assert(math.fabs((m * primary_axis).elems[j] -
                         matrix.col(primary_target).elems[j]) < 0.001)
Esempio n. 10
0
    def align_reference_frame(
        primary_axis, primary_target, secondary_axis, secondary_target
    ):
        """Compute a rotation matrix R: R x primary_axis = primary_target and
        R x secondary_axis places the secondary_axis in the plane perpendicular
        to the primary_target, as close as possible to the secondary_target.
        Require: primary_target orthogonal to secondary_target, primary axis
        not colinear with secondary axis."""

        from scitbx import matrix

        if type(primary_axis) == type(()) or type(primary_axis) == type([]):
            primary_axis = matrix.col(primary_axis).normalize()
        else:
            primary_axis = primary_axis.normalize()

        if type(primary_target) == type(()) or type(primary_target) == type([]):
            primary_target = matrix.col(primary_target).normalize()
        else:
            primary_target = primary_target.normalize()

        if type(secondary_axis) == type(()) or type(secondary_axis) == type([]):
            secondary_axis = matrix.col(secondary_axis).normalize()
        else:
            secondary_axis = secondary_axis.normalize()

        if type(secondary_target) == type(()) or type(secondary_target) == type([]):
            secondary_target = matrix.col(secondary_target).normalize()
        else:
            secondary_target = secondary_target.normalize()

        # check properties of input axes

        assert fabs(primary_axis.angle(secondary_axis) % pi) > 0.001
        assert primary_target.dot(secondary_target) < 0.001

        if primary_target.angle(primary_axis) % pi:
            axis_p = primary_target.cross(primary_axis)
            angle_p = -primary_target.angle(primary_axis)
            Rprimary = axis_p.axis_and_angle_as_r3_rotation_matrix(angle_p)
        elif primary_target.angle(primary_axis) < 0:
            axis_p = primary_axis.ortho().normalize()
            angle_p = pi
            Rprimary = axis_p.axis_and_angle_as_r3_rotation_matrix(angle_p)
        else:
            Rprimary = matrix.identity(3)

        Rpsa = Rprimary * secondary_axis
        axis_r = secondary_target.cross(Rpsa)
        axis_s = primary_target
        oc = AnglePredictor_rstbx.orthogonal_component
        angle_s = oc(axis_s, secondary_target).angle(oc(axis_s, Rpsa))
        if axis_r.angle(primary_target) <= 0.5 * pi:
            angle_s *= -1.0

        Rsecondary = axis_s.axis_and_angle_as_r3_rotation_matrix(angle_s)

        return Rsecondary * Rprimary
Esempio n. 11
0
    def exercise(self, fixed_twin_fraction):
        # Create a shaken structure xs ready for refinement
        xs0 = self.structure
        emma_ref = xs0.as_emma_model()
        xs = xs0.deep_copy_scatterers()
        xs.shake_sites_in_place(rms_difference=0.15)
        xs.shake_adp()
        for sc in xs.scatterers():
            sc.flags.set_use_u_iso(False).set_use_u_aniso(True)
            sc.flags.set_grad_site(True).set_grad_u_aniso(True)

        # Setup L.S. problem
        connectivity_table = smtbx.utils.connectivity_table(xs)
        shaken_twin_fraction = (self.twin_fraction if fixed_twin_fraction else
                                self.twin_fraction +
                                0.1 * flex.random_double())
        # 2nd domain in __init__
        twin_components = (xray.twin_component(twin_law=self.twin_law.r(),
                                               value=shaken_twin_fraction,
                                               grad=not fixed_twin_fraction), )
        reparametrisation = constraints.reparametrisation(
            structure=xs,
            constraints=[],
            connectivity_table=connectivity_table,
            twin_fractions=twin_components)
        obs = self.fo_sq.as_xray_observations(twin_components=twin_components)
        ls = least_squares.crystallographic_ls(
            obs,
            reparametrisation,
            weighting_scheme=least_squares.unit_weighting(),
            origin_fixing_restraints_type=origin_fixing_restraints.
            atomic_number_weighting)

        # Refine till we get back the original structure (so we hope)
        cycles = normal_eqns_solving.levenberg_marquardt_iterations(
            ls, gradient_threshold=1e-12, step_threshold=1e-6, track_all=True)

        # Now let's start to check it all worked
        assert ls.n_parameters == 63 if fixed_twin_fraction else 64

        match = emma.model_matches(emma_ref,
                                   xs.as_emma_model()).refined_matches[0]
        assert match.rt.r == matrix.identity(3)
        for pair in match.pairs:
            assert approx_equal(match.calculate_shortest_dist(pair),
                                0,
                                eps=1e-4), pair

        if fixed_twin_fraction:
            assert ls.twin_fractions[0].value == self.twin_fraction
        else:
            assert approx_equal(ls.twin_fractions[0].value,
                                self.twin_fraction,
                                eps=1e-2)

        assert approx_equal(ls.scale_factor(), 1, eps=1e-5)
        assert approx_equal(ls.objective(), 0)
Esempio n. 12
0
def test_matrix(s,eps=1e-3):
    # s is a list of 9 float numbers
    R = matrix.sqr(s)
    t1 = R*R.transpose()
    t2 = matrix.identity(3)
    det_is = R.determinant()
    det_tet = abs(det_is - 1) < eps
    inv_test = abs(t1 - t2) < eps
    return  det_is, det_tet, inv_test
Esempio n. 13
0
  def exercise(self, fixed_twin_fraction):
    # Create a shaken structure xs ready for refinement
    xs0 = self.structure
    emma_ref = xs0.as_emma_model()
    xs = xs0.deep_copy_scatterers()
    xs.shake_sites_in_place(rms_difference=0.15)
    xs.shake_adp()
    for sc in xs.scatterers():
      sc.flags.set_use_u_iso(False).set_use_u_aniso(True)
      sc.flags.set_grad_site(True).set_grad_u_aniso(True)

    # Setup L.S. problem
    connectivity_table = smtbx.utils.connectivity_table(xs)
    shaken_twin_fraction = (
      self.twin_fraction if fixed_twin_fraction else
      self.twin_fraction + 0.1*flex.random_double())
    # 2nd domain in __init__
    twin_components = (xray.twin_component(
        twin_law=self.twin_law.r(), value=shaken_twin_fraction,
        grad=not fixed_twin_fraction),)
    reparametrisation = constraints.reparametrisation(
      structure=xs,
      constraints=[],
      connectivity_table=connectivity_table,
      twin_fractions=twin_components)
    obs = self.fo_sq.as_xray_observations(twin_components=twin_components)
    ls = least_squares.crystallographic_ls(
      obs, reparametrisation,
      weighting_scheme=least_squares.unit_weighting(),
      origin_fixing_restraints_type=
      origin_fixing_restraints.atomic_number_weighting)

    # Refine till we get back the original structure (so we hope)
    cycles = normal_eqns_solving.levenberg_marquardt_iterations(
      ls,
      gradient_threshold=1e-12,
      step_threshold=1e-6,
      track_all=True)

    # Now let's start to check it all worked
    assert ls.n_parameters == 63 if fixed_twin_fraction else 64

    match = emma.model_matches(emma_ref, xs.as_emma_model()).refined_matches[0]
    assert match.rt.r == matrix.identity(3)
    for pair in match.pairs:
      assert approx_equal(match.calculate_shortest_dist(pair), 0, eps=1e-4), pair

    if fixed_twin_fraction:
      assert ls.twin_fractions[0].value == self.twin_fraction
    else:
      assert approx_equal(ls.twin_fractions[0].value, self.twin_fraction,
                          eps=1e-2)

    assert approx_equal(ls.scale_factor(), 1, eps=1e-5)
    assert approx_equal(ls.objective(), 0)
Esempio n. 14
0
def mcI(m, c, I):
    """
% mcI  spatial rigid-body inertia from mass, CoM and rotational inertia.
% mcI(m,c,I) calculates the spatial inertia matrix of a rigid body from its
% mass, centre of mass (3D vector) and rotational inertia (3x3 matrix)
% about its centre of mass.
  """
    c1, c2, c3 = c
    C = matrix.sqr((0, -c3, c2, c3, 0, -c1, -c2, c1, 0))
    return matrix.sqr((I + m * C * C.transpose(), m * C, m * C.transpose(),
                       m * matrix.identity(3))).resolve_partitions()
Esempio n. 15
0
 def DrawGL(self):
   wx_viewer.show_points_and_lines_mixin.DrawGL(self)
   gonio = self.parent.imageset.get_goniometer()
   beam = self.parent.imageset.get_beam()
   from scitbx import matrix
   R = matrix.identity(3)
   names = reversed(gonio.get_names())
   axes = reversed(gonio.get_axes())
   angles = reversed(gonio.get_angles())
   for name, axis, angle in zip(names, axes, angles):
     axis = R * matrix.col(axis)
     self.draw_axis(axis.elems, name)
     R = axis.axis_and_angle_as_r3_rotation_matrix(angle, deg=True) * R
   self.draw_axis(beam.get_s0(), "beam")
def find_closest_matrix(moving, target):
    '''Work through lattice permutations to try to align moving with target,
    with the metric of trace(inverse(moving) * target).'''

    trace = 0.0
    reindex = matrix.identity(3)

    for op in sgtbx.space_group_info('P422').type().group().all_ops():
        moved = matrix.sqr(op.r().as_double()) * moving
        if (moved.inverse() * target).trace() > trace:
            trace = (moved.inverse() * target).trace()
            reindex = matrix.sqr(op.r().as_double())

    return reindex
Esempio n. 17
0
def mcI(m, c, I):
  """
% mcI  spatial rigid-body inertia from mass, CoM and rotational inertia.
% mcI(m,c,I) calculates the spatial inertia matrix of a rigid body from its
% mass, centre of mass (3D vector) and rotational inertia (3x3 matrix)
% about its centre of mass.
  """
  c1,c2,c3 = c
  C = matrix.sqr((
      0, -c3,  c2,
     c3,   0, -c1,
    -c2,  c1,  0))
  return matrix.sqr((
    I + m*C*C.transpose(), m*C,
    m*C.transpose(), m*matrix.identity(3))).resolve_partitions()
Esempio n. 18
0
def gallego_yezzi_eqn9(t, k):
    """This is equation (9) from Gallego & Yezzi"""

    from scitbx import matrix
    from math import sin, cos

    v = t * k
    R = k.axis_and_angle_as_r3_rotation_matrix(t, deg=False)
    I3 = matrix.identity(3)

    V = skew_symm(v)

    e = (matrix.col((1, 0, 0)), matrix.col((0, 1, 0)), matrix.col((0, 0, 1)))

    term1 = [skew_symm(v.cross((I3 - R) * e[i])) for i in range(3)]

    return [(1.0 / t) * (v[i] * V + term1[i]) * R for i in range(3)]
Esempio n. 19
0
def gallego_yezzi_eqn9(t, k):
    """This is equation (9) from Gallego & Yezzi"""

    from scitbx import matrix
    from math import sin, cos

    v = t * k
    R = k.axis_and_angle_as_r3_rotation_matrix(t, deg=False)
    I3 = matrix.identity(3)

    V = skew_symm(v)

    e = (matrix.col((1, 0, 0)), matrix.col((0, 1, 0)), matrix.col((0, 0, 1)))

    term1 = [skew_symm(v.cross((I3 - R) * e[i])) for i in range(3)]

    return [(1.0 / t) * (v[i] * V + term1[i]) * R for i in range(3)]
Esempio n. 20
0
def p_matrix_from(a_sites, b_sites, weights):

    # Diamond, Acta Cryst A44, 211-216 (1988)
    assert len(a_sites) == len(b_sites) and len(a_sites) == len(weights)

    (xa, ya, za) = component_arrays(a_sites)
    (xb, yb, zb) = component_arrays(b_sites)

    m = matrix.sqr([
        flex.sum(weights * xa * xb),
        flex.sum(weights * xa * yb),
        flex.sum(weights * xa * zb),
        flex.sum(weights * ya * xb),
        flex.sum(weights * ya * yb),
        flex.sum(weights * ya * zb),
        flex.sum(weights * za * xb),
        flex.sum(weights * za * yb),
        flex.sum(weights * za * zb),
    ])

    q = m + m.transpose() - 2 * matrix.identity(3) * m.trace()

    # Application of Sum(j, k)[ epsilon( i, j, k ) * m( j, k ) ]
    # where i,j,k = [ 0, 1, 2 ] and epsilon is the Levi-Civitta symbol
    v = (m[5] - m[7], m[6] - m[2], m[1] - m[3])

    return matrix.sqr([
        q[0],
        q[1],
        q[2],
        v[0],
        q[3],
        q[4],
        q[5],
        v[1],
        q[6],
        q[7],
        q[8],
        v[2],
        v[0],
        v[1],
        v[2],
        0,
    ])
Esempio n. 21
0
def test_UnitCellAnalysisObserver():
    # generate some random unit cells
    sgi = sgtbx.space_group_info("P1")
    unit_cells = [
        sgi.any_compatible_unit_cell(volume=random.uniform(990, 1010))
        for i in range(10)
    ]

    # generate experiment list
    experiments = ExperimentList()
    U = matrix.identity(3)
    for uc in unit_cells:
        B = matrix.sqr(uc.fractionalization_matrix()).transpose()
        direct_matrix = (U * B).inverse()
        experiments.append(
            Experiment(crystal=Crystal(
                direct_matrix[:3],
                direct_matrix[3:6],
                direct_matrix[6:9],
                space_group=sgi.group(),
            )))

    # generate dendrogram
    crystal_symmetries = [
        expt.crystal.get_crystal_symmetry() for expt in experiments
    ]
    lattice_ids = experiments.identifiers()
    ucs = UnitCellCluster.from_crystal_symmetries(crystal_symmetries,
                                                  lattice_ids=lattice_ids)
    _, dendrogram, _ = ucs.ab_cluster(write_file_lists=False, doplot=False)

    # setup script
    script = mock.Mock()
    script._experiments = experiments
    script.unit_cell_dendrogram = dendrogram

    # test the observer
    observer = observers.UnitCellAnalysisObserver()
    observer.update(script)
    assert set(observer.data) == {"experiments", "dendrogram"}
    d = observer.make_plots()
    assert "unit_cell_graphs" in d
def run(args):
  import libtbx.load_env
  from dials.util.options import OptionParser
  from dials.util.options import flatten_experiments

  # The script usage
  usage = "usage: %s [options] [param.phil] experiments.json" %libtbx.env.dispatcher_name

  parser = OptionParser(
    usage=usage,
    phil=phil_scope,
    read_experiments=True,
    check_format=False,
    epilog=help_message)

  params, options = parser.parse_args(show_diff_phil=True)
  experiments = flatten_experiments(params.input.experiments)

  if len(experiments) == 0:
    parser.print_help()
    return

  if len(params.hkl) == 0 and params.hkl_limit is None:
    from libtbx.utils import Sorry
    raise Sorry("Please provide hkl or hkl_limit parameters.")

  if params.hkl is not None and len(params.hkl):
    miller_indices = flex.miller_index(params.hkl)
  elif params.hkl_limit is not None:
    limit = params.hkl_limit
    miller_indices = flex.miller_index()
    for h in range(-limit, limit+1):
      for k in range(-limit, limit+1):
        for l in range(-limit, limit+1):
          if (h,k,l) == (0,0,0): continue
          miller_indices.append((h,k,l))

  crystals = experiments.crystals()

  symmetry = crystal.symmetry(
    unit_cell=crystals[0].get_unit_cell(),
    space_group=crystals[0].get_space_group())
  miller_set = miller.set(symmetry, miller_indices)
  d_spacings = miller_set.d_spacings()
  if params.eliminate_sys_absent:
    d_spacings = d_spacings.eliminate_sys_absent()
  if params.expand_to_p1:
    d_spacings = d_spacings.as_non_anomalous_array().expand_to_p1()
    d_spacings = d_spacings.generate_bijvoet_mates()
  miller_indices = d_spacings.indices()

  # find the greatest common factor (divisor) between miller indices
  miller_indices_unique = flex.miller_index()
  for hkl in miller_indices:
    gcd = gcd_list(hkl)
    if gcd > 1:
      miller_indices_unique.append(tuple(int(h/gcd) for h in hkl))
    elif gcd < 1:
      pass
    else:
      miller_indices_unique.append(hkl)
  miller_indices = miller_indices_unique
  miller_indices = flex.miller_index(list(set(miller_indices)))

  ref_crystal = crystals[0]
  A = ref_crystal.get_A()
  U = ref_crystal.get_U()
  B = ref_crystal.get_B()
  R = matrix.identity(3)

  if params.frame == 'laboratory':
    reference_poles = reference_poles_perpendicular_to_beam(
      experiments[0].beam, experiments[0].goniometer)
    if params.use_starting_angle:
      rotation_axis = matrix.col(
        experiments[0].goniometer.get_rotation_axis())
      R = rotation_axis.axis_and_angle_as_r3_rotation_matrix(
        experiments[0].scan.get_oscillation()[0], deg=True)
    elif params.phi_angle != 0:
      rotation_axis = matrix.col(
        experiments[0].goniometer.get_rotation_axis())
      R = rotation_axis.axis_and_angle_as_r3_rotation_matrix(
        params.phi_angle, deg=True)
  else:
    if params.plane_normal is not None:
      plane_normal = params.plane_normal
    else:
      plane_normal = (0,0,1)
    reference_poles = reference_poles_crystal(
      ref_crystal, plane_normal=plane_normal)

  if params.frame == 'crystal':
    U = matrix.identity(3)

  reciprocal_space_points = list(R * U * B) * miller_indices.as_vec3_double()
  projections_ref = stereographic_projection(
    reciprocal_space_points, reference_poles)

  projections_all = [projections_ref]

  if len(experiments) > 0:
    from dials.algorithms.indexing.compare_orientation_matrices import \
        difference_rotation_matrix_and_euler_angles

    for expt in experiments[1:]:
      cryst = expt.crystal
      if params.frame == 'crystal':
        R_ij, euler_angles, cb_op = difference_rotation_matrix_and_euler_angles(
          ref_crystal, cryst)
        U = R_ij
      elif params.use_starting_angle:
        if params.use_starting_angle:
          rotation_axis = matrix.col(
            expt.goniometer.get_rotation_axis())
          R = rotation_axis.axis_and_angle_as_r3_rotation_matrix(
            expt.scan.get_oscillation()[0], deg=True)
      else:
        U = cryst.get_U()
      reciprocal_space_points = list(R * U * cryst.get_B()) * miller_indices.as_vec3_double()
      projections = stereographic_projection(
        reciprocal_space_points, reference_poles)
      projections_all.append(projections)

  if params.save_coordinates:
    with open('projections.txt', 'wb') as f:
      print >> f, "crystal h k l x y"
      for i_cryst, projections in enumerate(projections_all):
        for hkl, proj in zip(miller_indices, projections):
          print >> f, "%i" %(i_cryst+1),
          print >> f, "%i %i %i" %hkl,
          print >> f, "%f %f" %proj

  if params.plot.show or params.plot.filename:
    plot_projections(
      projections_all, filename=params.plot.filename, show=params.plot.show,
      colours=params.plot.colours, marker_size=params.plot.marker_size,
      font_size=params.plot.font_size, label_indices=params.plot.label_indices)
Esempio n. 23
0
  def DrawGL(self):
    wx_viewer.show_points_and_lines_mixin.DrawGL(self)
    gonio = self.parent.imageset.get_goniometer()
    beam = self.parent.imageset.get_beam()
    detector = self.parent.imageset.get_detector()
    if self.settings.show_panel_axes and detector is not None:
      for p in detector:
        image_size = p.get_image_size_mm()
        from scitbx import matrix
        o = matrix.col(p.get_lab_coord((0,0)))
        f = matrix.col(p.get_lab_coord((image_size[0],0)))
        _f = (f - o).normalize()
        s = matrix.col(p.get_lab_coord((0,image_size[1])))
        _s = (s - o).normalize()
        _n = _f.cross(_s)
        n = _n * (0.25 * (f.length() + s.length())) + o
        self.draw_lab_axis(o.elems, f.elems, 'FAST')
        self.draw_lab_axis(o.elems, s.elems, 'SLOW')
        self.draw_lab_axis(o.elems, n.elems, 'NORM')

    from scitbx import matrix
    if isinstance(gonio, MultiAxisGoniometer):
      R = matrix.identity(3)
      names = reversed(gonio.get_names())
      axes = reversed(gonio.get_axes())
      angles = reversed(gonio.get_angles())
      for name, axis, angle in zip(names, axes, angles):
        axis = R * matrix.col(axis)
        self.draw_axis(axis.elems, name)
        R = axis.axis_and_angle_as_r3_rotation_matrix(angle, deg=True) * R
    elif gonio is not None:
      axis = matrix.col(gonio.get_rotation_axis())
      self.draw_axis(axis.elems, "phi")
    self.draw_axis(beam.get_s0(), "beam")
    crystal = self.parent.crystal
    if crystal is not None:
      crystal = copy.deepcopy(crystal)
      scan = self.parent.imageset.get_scan()
      fixed_rotation = matrix.sqr(gonio.get_fixed_rotation())
      setting_rotation = matrix.sqr(gonio.get_setting_rotation())
      rotation_axis = matrix.col(gonio.get_rotation_axis_datum())
      if isinstance(gonio, MultiAxisGoniometer):
        angle = gonio.get_angles()[gonio.get_scan_axis()]
      else:
        angle = scan.get_oscillation()[0]
      rotation_matrix = rotation_axis.axis_and_angle_as_r3_rotation_matrix(
        angle, deg=True)
      U0 = matrix.sqr(crystal.get_U())

      # Goniometer datum setting [D] at which the orientation was determined
      D = (setting_rotation * rotation_matrix * fixed_rotation).inverse()

      U = D.inverse() * U0
      B = matrix.sqr(crystal.get_B())
      a_star = U * B * matrix.col((1,0,0))
      b_star = U * B * matrix.col((0,1,0))
      c_star = U * B * matrix.col((0,0,1))
      color = (1.0, 0.0, 0.0) # red
      self.draw_axis(a_star.normalize() * 0.5, "a*", color=color)
      self.draw_axis(b_star.normalize() * 0.5, "b*", color=color)
      self.draw_axis(c_star.normalize() * 0.5, "c*", color=color)
Esempio n. 24
0
 def __init__(model, m, I, J):
     model.NB = 1
     model.pitch = [J]
     model.parent = [-1]
     model.Xtree = [matrix.identity(n=6)]
     model.I = [featherstone.mcI(m, (0, 0, 0), I)]
Esempio n. 25
0
def exercise_one_structure(
    target_structure,
    flipping_type,
    anomalous_flag,
    d_min,
    grid_resolution_factor=1.0 / 2,
    verbose=False,
    amplitude_type="F",
):
    assert amplitude_type in ("F", "E", "quasi-E")

    # Generate its structure factors
    f_target = (
        miller.build_set(
            crystal_symmetry=target_structure,
            anomalous_flag=target_structure.scatterers().count_anomalous() != 0,
            d_min=d_min,
        )
        .structure_factors_from_scatterers(xray_structure=target_structure, algorithm="direct")
        .f_calc()
    )

    f_target_in_p1 = f_target.expand_to_p1().as_non_anomalous_array().merge_equivalents().array()
    f_obs = f_target.as_amplitude_array()

    # Unleash charge flipping on the amplitudes
    flipping = flipping_type(delta=None)
    extra = group_args()
    if amplitude_type == "E":
        extra.normalisations_for = lambda f: f.amplitude_normalisations(
            target_structure.unit_cell_content(omit=("H", "D"))
        )
    elif amplitude_type == "quasi-E":
        extra.normalisations_for = charge_flipping.amplitude_quasi_normalisations
    solving = charge_flipping.solving_iterator(
        flipping, f_obs, yield_during_delta_guessing=True, yield_solving_interval=1, **extra.__dict__
    )
    s = StringIO()
    charge_flipping.loop(solving, verbose="highly", out=s)
    if verbose:
        print s.getvalue()

    # check whether a phase transition has occured
    assert solving.had_phase_transition

    flipping = solving.flipping_iterator
    f_result_in_p1 = solving.flipping_iterator.f_calc

    # Euclidean matching of the peaks from the obtained map
    # against those of the correct structure (in P1)
    target_structure = target_structure.select(target_structure.scattering_types() == "H", negate=True)
    target_structure_in_p1 = target_structure.expand_to_p1()
    search_parameters = maptbx.peak_search_parameters(
        interpolate=True, min_distance_sym_equiv=1.0, max_clusters=int(target_structure_in_p1.scatterers().size() * 1.2)
    )
    peak_search_outcome = flipping.rho_map.peak_search(search_parameters)
    peak_structure = emma.model(
        target_structure_in_p1.crystal_symmetry().special_position_settings(),
        positions=[emma.position("Q%i" % i, x) for i, x in enumerate(peak_search_outcome.all().sites())],
    )
    refined_matches = emma.model_matches(
        target_structure_in_p1.as_emma_model(), peak_structure, tolerance=0.5, break_if_match_with_no_singles=False
    ).refined_matches
    m = refined_matches[0]
    assert m.rms < 0.2, m.rms  # no farther than that
    assert m.rt.r in (mat.identity(3), mat.inversion(3))

    reference_shift = -refined_matches[0].rt.t

    # Find the translation to bring back the structure to the same space-group
    # setting as the starting f_obs from correlation map analysis
    is_allowed = lambda x: f_target.space_group_info().is_allowed_origin_shift(x, tolerance=0.1)
    first_correct_correlation_peak = None
    for i, (f_calc, shift, cc_peak_height) in enumerate(solving.f_calc_solutions):
        if is_allowed(shift - reference_shift) or is_allowed(shift + reference_shift):
            first_correct_correlation_peak = i
            break
        else:
            if verbose == "more":
                print "++ Incorrect peak: shift=(%.3f, %.3f, %.3f), height=%.2f" % (tuple(shift) + (cc_peak_height,))
                print "   Reference shift=(%.3f, %.3f, %.3f)" % tuple(reference_shift)
    assert first_correct_correlation_peak is not None
    if verbose and first_correct_correlation_peak != 0:
        print "** First correct correlation peak: #%i (%.3f) **" % (first_correct_correlation_peak, cc_peak_height)

    # check Euclidean matching in the original space-group
    search_parameters = maptbx.peak_search_parameters(
        interpolate=True, min_distance_sym_equiv=1.0, max_clusters=int(1.5 * target_structure.scatterers().size())
    )
    solution_fft_map = f_calc.fft_map(symmetry_flags=maptbx.use_space_group_symmetry)
    solution_peaks = solution_fft_map.peak_search(search_parameters, verify_symmetry=False)
    solution_peak_structure = emma.model(
        target_structure.crystal_symmetry().special_position_settings(),
        positions=[emma.position("Q%i" % i, x) for i, x in enumerate(solution_peaks.all().sites())],
    )
    refined_matches = emma.model_matches(
        target_structure.as_emma_model(), solution_peak_structure, break_if_match_with_no_singles=False
    ).refined_matches
    assert refined_matches
    m = refined_matches[0]
    assert not m.singles1, m.show()  # all sites match a peak
    assert m.rms < 0.15, m.rms  # no farther than that
    assert m.rt.r in (mat.identity(3), mat.inversion(3))

    # success!
    if verbose:
        print "@@ Success @@"
Esempio n. 26
0
def run(args):
    from dials.util.options import OptionParser
    from dials.util.options import flatten_experiments

    # The script usage
    usage = "dials.stereographic_projection [options] [param.phil] experiments.json"

    parser = OptionParser(
        usage=usage,
        phil=phil_scope,
        read_experiments=True,
        check_format=False,
        epilog=help_message,
    )

    params, options = parser.parse_args(show_diff_phil=True)
    experiments = flatten_experiments(params.input.experiments)

    if not experiments:
        parser.print_help()
        return

    if not params.hkl and params.hkl_limit is None:
        sys.exit("Please provide hkl or hkl_limit parameters.")

    if params.hkl is not None and len(params.hkl):
        miller_indices = flex.miller_index(params.hkl)
    elif params.hkl_limit is not None:
        limit = params.hkl_limit
        miller_indices = flex.miller_index()
        for h in range(-limit, limit + 1):
            for k in range(-limit, limit + 1):
                for l in range(-limit, limit + 1):
                    if (h, k, l) == (0, 0, 0):
                        continue
                    miller_indices.append((h, k, l))

    crystals = experiments.crystals()

    symmetry = crystal.symmetry(
        unit_cell=crystals[0].get_unit_cell(), space_group=crystals[0].get_space_group()
    )
    miller_set = miller.set(symmetry, miller_indices)
    d_spacings = miller_set.d_spacings()
    if params.eliminate_sys_absent:
        d_spacings = d_spacings.eliminate_sys_absent()
    if params.expand_to_p1:
        d_spacings = d_spacings.as_non_anomalous_array().expand_to_p1()
        d_spacings = d_spacings.generate_bijvoet_mates()
    miller_indices = d_spacings.indices()

    # find the greatest common factor (divisor) between miller indices
    miller_indices_unique = flex.miller_index()
    for hkl in miller_indices:
        gcd = gcd_list(hkl)
        if gcd > 1:
            miller_indices_unique.append(tuple(int(h / gcd) for h in hkl))
        elif gcd < 1:
            pass
        else:
            miller_indices_unique.append(hkl)
    miller_indices = miller_indices_unique
    miller_indices = flex.miller_index(list(set(miller_indices)))

    ref_crystal = crystals[0]
    U = matrix.sqr(ref_crystal.get_U())
    B = matrix.sqr(ref_crystal.get_B())
    R = matrix.identity(3)

    if params.frame == "laboratory":
        reference_poles = reference_poles_perpendicular_to_beam(
            experiments[0].beam, experiments[0].goniometer
        )
        if params.use_starting_angle:
            rotation_axis = matrix.col(experiments[0].goniometer.get_rotation_axis())
            R = rotation_axis.axis_and_angle_as_r3_rotation_matrix(
                experiments[0].scan.get_oscillation()[0], deg=True
            )
        elif params.phi_angle != 0:
            rotation_axis = matrix.col(experiments[0].goniometer.get_rotation_axis())
            R = rotation_axis.axis_and_angle_as_r3_rotation_matrix(
                params.phi_angle, deg=True
            )
    else:
        if params.plane_normal is not None:
            plane_normal = params.plane_normal
        else:
            plane_normal = (0, 0, 1)
        reference_poles = reference_poles_crystal(
            ref_crystal, plane_normal=plane_normal
        )

    if params.frame == "crystal":
        U = matrix.identity(3)

    reciprocal_space_points = list(R * U * B) * miller_indices.as_vec3_double()
    projections_ref = stereographic_projection(reciprocal_space_points, reference_poles)

    projections_all = [projections_ref]

    if experiments:
        from dials.algorithms.indexing.compare_orientation_matrices import (
            difference_rotation_matrix_axis_angle,
        )

        for expt in experiments[1:]:
            cryst = expt.crystal
            if params.frame == "crystal":
                R_ij, axis, angle, cb_op = difference_rotation_matrix_axis_angle(
                    ref_crystal, cryst
                )
                U = R_ij
            elif params.use_starting_angle:
                if params.use_starting_angle:
                    rotation_axis = matrix.col(expt.goniometer.get_rotation_axis())
                    R = rotation_axis.axis_and_angle_as_r3_rotation_matrix(
                        expt.scan.get_oscillation()[0], deg=True
                    )
            else:
                U = matrix.sqr(cryst.get_U())
            reciprocal_space_points = (
                list(R * U * matrix.sqr(cryst.get_B()))
                * miller_indices.as_vec3_double()
            )
            projections = stereographic_projection(
                reciprocal_space_points, reference_poles
            )
            projections_all.append(projections)

    if params.save_coordinates:
        with open("projections.txt", "w") as f:
            f.write("crystal h k l x y" + os.linesep)
            for i_cryst, projections in enumerate(projections_all):
                for hkl, proj in zip(miller_indices, projections):
                    f.write("%i " % (i_cryst + 1))
                    f.write("%i %i %i " % hkl)
                    f.write(("%f %f" + os.linesep) % proj)

    if params.plot.show or params.plot.filename:
        epochs = None
        if params.plot.colour_map is not None:
            if experiments[0].scan is not None:
                epochs = [expt.scan.get_epochs()[0] for expt in experiments]
            else:
                epochs = [i for i, expt in enumerate(experiments)]
        plot_projections(
            projections_all,
            filename=params.plot.filename,
            show=params.plot.show,
            colours=params.plot.colours,
            marker_size=params.plot.marker_size,
            font_size=params.plot.font_size,
            gridsize=params.plot.gridsize,
            label_indices=params.plot.label_indices,
            epochs=epochs,
            colour_map=params.plot.colour_map,
        )

    if params.json.filename:
        projections_as_json(projections_all, filename=params.json.filename)
Esempio n. 27
0
  def exercise(self):
    xs0 = self.structure
    xs = xs0.deep_copy_scatterers()
    k1, s1, li1, o1, o2 = xs.scatterers()
    self.shake_point_group_3(k1)
    self.shake_point_group_3(s1)
    self.shake_point_group_3(li1)
    self.shake_point_group_3(o1)
    o2.site = tuple(
      [ x*(1 + random.uniform(-self.delta_site, self.delta_site))
        for x in o2.site])
    o2.u_star = tuple(
      [ u*(1 + random.uniform(-self.delta_u_star, self.delta_u_star))
        for u in o2.u_star])

    for sc in xs.scatterers():
      sc.flags.set_use_u_iso(False).set_use_u_aniso(True)
      sc.flags.set_grad_site(True).set_grad_u_aniso(True)
      connectivity_table = smtbx.utils.connectivity_table(xs)
    reparametrisation = constraints.reparametrisation(
      structure=xs,
      constraints=[],
      connectivity_table=connectivity_table)
    ls = least_squares.crystallographic_ls(
      self.fo_sq.as_xray_observations(), reparametrisation,
      weighting_scheme=least_squares.unit_weighting(),
      origin_fixing_restraints_type=
      origin_fixing_restraints.atomic_number_weighting)

    cycles = normal_eqns_solving.naive_iterations(
      ls,
      gradient_threshold=1e-6,
      step_threshold=1e-6,
      track_all=True)

    ## Test whether refinement brought back the shaked structure to its
    ## original state
    match = emma.model_matches(xs0.as_emma_model(),
                               xs.as_emma_model()).refined_matches[0]
    assert match.rt.r == matrix.identity(3)
    assert not match.singles1 and not match.singles2
    assert match.rms < 1e-6

    delta_u_carts= (   xs.scatterers().extract_u_cart(xs.unit_cell())
                    - xs0.scatterers().extract_u_cart(xs.unit_cell())).norms()
    assert flex.abs(delta_u_carts) < 1e-6

    assert approx_equal(ls.scale_factor(), 1, eps=1e-4)

    ## Test covariance matrix
    jac_tr = reparametrisation.jacobian_transpose_matching_grad_fc()
    cov = ls.covariance_matrix(
      jacobian_transpose=jac_tr, normalised_by_goof=False)\
        .matrix_packed_u_as_symmetric()
    m, n = cov.accessor().focus()
    # x,y for point group 3 sites are fixed: no variance or correlation
    for i in (0, 9, 18, 27,):
      assert cov.matrix_copy_block(i, 0, 2, n) == 0

    # u_star coefficients u13 and u23 for point group 3 sites are fixed
    # to 0: again no variance or correlation with any other param
    for i in (7, 16, 25, 34,):
      assert cov.matrix_copy_block(i, 0, 2, n).as_1d()\
             .all_approx_equal(0., 1e-20)

    # u_star coefficients u11, u22 and u12 for point group 3 sites
    # are totally correlated, with variances in ratios 1:1:1/2
    for i in (3, 12, 21, 30,):
      assert cov[i, i] != 0
      assert approx_equal(cov[i, i], cov[i+1, i+1], eps=1e-15)
      assert approx_equal(cov[i, i+1]/cov[i, i], 1, eps=1e-12)
      assert approx_equal(cov[i, i+3]/cov[i, i], 0.5, eps=1e-12)
Esempio n. 28
0
def exercise_basics():
    # construct a simple structure whose sites and u_iso's are to be refined
    xs = xray.structure(crystal_symmetry=crystal.symmetry(
        unit_cell=(10, 10, 10, 90, 90, 90), space_group_symbol='hall: P 1'),
                        scatterers=flex.xray_scatterer((
                            xray.scatterer('C0', site=(0, -1 / 2, 0), u=0.1),
                            xray.scatterer('C1', site=(0, 1 / 2, 0), u=0.2),
                            xray.scatterer('C0a', site=(1 / 2, 0, 0), u=0.1),
                            xray.scatterer('C1a', site=(-1 / 2, 0, 0), u=0.2),
                        )))
    for sc in xs.scatterers():
        sc.flags.set_grad_site(True)
        sc.flags.set_grad_u_iso(True)

    # copy the original structure as a reference to test against later
    xs_ref = xs.deep_copy_scatterers()

    # mess up the symmetries that the forthcoming constraints shall impose
    c0, c1, c0a, c1a = xs.scatterers()
    c0a.site = (0, 0, 0)
    c1a.site = (1 / 2, 1 / 2, 1 / 2)
    c0a.u_iso = 0.5
    c1a.u_iso = 0.6

    # construct a reparametrisation for the following constraints:
    # (C0a, C1a) is the image of (C0, C1) through a rotation of 90 degrees
    # about the z-axis
    r = constraints.ext.reparametrisation(xs.unit_cell())
    sc_params = constraints.shared_scatterer_parameters(xs.scatterers())
    c0_site_param = r.add(constraints.independent_site_parameter, c0)
    sc_params[0].site = c0_site_param
    c1_site_param = r.add(constraints.independent_site_parameter, c1)
    sc_params[1].site = c1_site_param
    move_param = r.add(constraints.independent_small_6_vector_parameter,
                       (0, 0, 0, 0, 0, math.pi / 2))
    c0a_c1a_site_param = r.add(constraints.same_group_xyz,
                               scatterers=(c0a, c1a),
                               sites=(c0_site_param, c1_site_param),
                               alignment_matrix=matrix.identity(3),
                               shifts_and_angles=move_param)
    sc_params[2].site = sc_params[3].site = c0a_c1a_site_param
    c0_u_iso_param = r.add(constraints.independent_u_iso_parameter, c0)
    sc_params[0].u = c0_u_iso_param
    c1_u_iso_param = r.add(constraints.independent_u_iso_parameter, c1)
    sc_params[1].u = c1_u_iso_param
    c0a_c1a_u_iso_param = r.add(constraints.same_group_u_iso,
                                scatterers=(c0a, c1a),
                                u_isos=(c0_u_iso_param, c1_u_iso_param))
    sc_params[2].u = sc_params[3].u = c0a_c1a_u_iso_param
    r.finalise()

    # put the reparametrisation to work
    r.linearise()
    r.store()
    c0_ref, c1_ref, c0a_ref, c1a_ref = xs_ref.scatterers()
    assert approx_equal(c0a.site, c0a_ref.site, eps=1e-12)
    assert approx_equal(c1a.site, c1a_ref.site, eps=1e-12)
    assert approx_equal(c0a.u_iso, c0a_ref.u_iso, eps=1e-12)
    assert approx_equal(c1a.u_iso, c1a_ref.u_iso, eps=1e-12)

    # check that origin fixing restraints work in the presence of
    # that reparametrisation
    # this is a regression test as they used not to (bug reported by Oleg)
    from smtbx.refinement.restraints import origin_fixing_restraints
    from scitbx import lstbx
    orig_fixing = origin_fixing_restraints.homogeneous_weighting(
        xs.space_group())
    normal_eqn = lstbx.normal_eqns.ext.linear_ls(n_parameters=(3 + 1) * 2 + 6)
    jacobian_transpose_matching_grad_fc = r.jacobian_transpose_matching(
        sc_params.mapping_to_grad_fc())
    orig_fixing.add_to(normal_eqn, jacobian_transpose_matching_grad_fc,
                       sc_params)
def align_reference_frame(primary_axis, primary_target,
                          secondary_axis, secondary_target):
    '''Compute a rotation matrix R: R x primary_axis = primary_target and
    R x secondary_axis places the secondary_axis in the plane perpendicular
    to the primary_target, as close as possible to the secondary_target.
    Require: primary_target orthogonal to secondary_target, primary axis
    not colinear with secondary axis.'''

    if type(primary_axis) == type(()) or type(primary_axis) == type([]):
        primary_axis = matrix.col(primary_axis).normalize()
    else:
        primary_axis = primary_axis.normalize()

    if type(primary_target) == type(()) or type(primary_target) == type([]):
        primary_target = matrix.col(primary_target).normalize()
    else:
        primary_target = primary_target.normalize()

    if type(secondary_axis) == type(()) or type(secondary_axis) == type([]):
        secondary_axis = matrix.col(secondary_axis).normalize()
    else:
        secondary_axis = secondary_axis.normalize()

    if type(secondary_target) == type(()) or \
           type(secondary_target) == type([]):
        secondary_target = matrix.col(secondary_target).normalize()
    else:
        secondary_target = secondary_target.normalize()

    # check properties of input axes

    assert(math.fabs(primary_axis.angle(secondary_axis) % math.pi) > 0.001)
    assert(primary_target.dot(secondary_target) < 0.001)

    if primary_target.angle(primary_axis) % math.pi:
      axis_p = primary_target.cross(primary_axis)
      angle_p = - primary_target.angle(primary_axis)
      Rprimary = axis_p.axis_and_angle_as_r3_rotation_matrix(angle_p)
    elif primary_target.dot(primary_axis) < 0:
      axis_p = primary_axis.ortho().normalize()
      angle_p = math.pi
      Rprimary = axis_p.axis_and_angle_as_r3_rotation_matrix(angle_p)
    else:
      Rprimary = matrix.identity(3)

    if math.fabs(secondary_target.angle(Rprimary * secondary_axis)) < 1.0e-6:
      Rsecondary = matrix.identity(3)
    else:
      axis_r = secondary_target.cross(Rprimary * secondary_axis)
      axis_s = primary_target

      if (axis_r.angle(primary_target) > 0.5 * math.pi):
        angle_s = orthogonal_component(axis_s, secondary_target).angle(
          orthogonal_component(axis_s, Rprimary * secondary_axis))
      else:
        angle_s = - orthogonal_component(axis_s, secondary_target).angle(
          orthogonal_component(axis_s, Rprimary * secondary_axis))

      Rsecondary = axis_s.axis_and_angle_as_r3_rotation_matrix(angle_s)

    return Rsecondary * Rprimary
  def exercise(self):
    xs0 = self.structure
    xs = xs0.deep_copy_scatterers()
    k1, s1, li1, o1, o2 = xs.scatterers()
    self.shake_point_group_3(k1)
    self.shake_point_group_3(s1)
    self.shake_point_group_3(li1)
    self.shake_point_group_3(o1)
    o2.site = tuple(
      [ x*(1 + random.uniform(-self.delta_site, self.delta_site))
        for x in o2.site])
    o2.u_star = tuple(
      [ u*(1 + random.uniform(-self.delta_u_star, self.delta_u_star))
        for u in o2.u_star])

    for sc in xs.scatterers():
      sc.flags.set_use_u_iso(False).set_use_u_aniso(True)
      sc.flags.set_grad_site(True).set_grad_u_aniso(True)
      connectivity_table = smtbx.utils.connectivity_table(xs)
    reparametrisation = constraints.reparametrisation(
      structure=xs,
      constraints=[],
      connectivity_table=connectivity_table)
    ls = least_squares.crystallographic_ls(
      self.fo_sq.as_xray_observations(), reparametrisation,
      weighting_scheme=least_squares.unit_weighting(),
      origin_fixing_restraints_type=
      origin_fixing_restraints.atomic_number_weighting)

    cycles = normal_eqns_solving.levenberg_marquardt_iterations(
      ls,
      gradient_threshold=1e-12,
      step_threshold=1e-7,
      track_all=True)

    ## Test whether refinement brought back the shaked structure to its
    ## original state
    match = emma.model_matches(xs0.as_emma_model(),
                               xs.as_emma_model()).refined_matches[0]
    assert match.rt.r == matrix.identity(3)
    assert not match.singles1 and not match.singles2
    assert match.rms < 1e-6

    delta_u_carts= (   xs.scatterers().extract_u_cart(xs.unit_cell())
                    - xs0.scatterers().extract_u_cart(xs.unit_cell())).norms()
    assert flex.abs(delta_u_carts) < 1e-6

    assert approx_equal(ls.scale_factor(), 1, eps=1e-4)

    ## Test covariance matrix
    jac_tr = reparametrisation.jacobian_transpose_matching_grad_fc()
    cov = ls.covariance_matrix(
      jacobian_transpose=jac_tr, normalised_by_goof=False)\
        .matrix_packed_u_as_symmetric()
    m, n = cov.accessor().focus()
    # x,y for point group 3 sites are fixed: no variance or correlation
    for i in (0, 9, 18, 27,):
      assert cov.matrix_copy_block(i, 0, 2, n) == 0

    # u_star coefficients u13 and u23 for point group 3 sites are fixed
    # to 0: again no variance or correlation with any other param
    for i in (7, 16, 25, 34,):
      assert cov.matrix_copy_block(i, 0, 2, n).as_1d()\
             .all_approx_equal(0., 1e-20)

    # u_star coefficients u11, u22 and u12 for point group 3 sites
    # are totally correlated, with variances in ratios 1:1:1/2
    for i in (3, 12, 21, 30,):
      assert cov[i, i] != 0
      assert approx_equal(cov[i, i], cov[i+1, i+1], eps=1e-15)
      assert approx_equal(cov[i, i+1]/cov[i, i], 1, eps=1e-12)
      assert approx_equal(cov[i, i+3]/cov[i, i], 0.5, eps=1e-12)
Esempio n. 31
0
def exercise_one_structure(
    target_structure,
    flipping_type,
    anomalous_flag,
    d_min,
    grid_resolution_factor=1. / 2,
    verbose=False,
    amplitude_type="F",
):
    assert amplitude_type in ('F', 'E', 'quasi-E')

    # Generate its structure factors
    f_target = miller.build_set(
        crystal_symmetry=target_structure,
        anomalous_flag=target_structure.scatterers().count_anomalous() != 0,
        d_min=d_min).structure_factors_from_scatterers(
            xray_structure=target_structure, algorithm="direct").f_calc()

    f_target_in_p1 = f_target.expand_to_p1()\
                             .as_non_anomalous_array()\
                             .merge_equivalents().array()
    f_obs = f_target.as_amplitude_array()

    # Unleash charge flipping on the amplitudes
    flipping = flipping_type(delta=None)
    extra = group_args()
    if amplitude_type == 'E':
        extra.normalisations_for = lambda f: f.amplitude_normalisations(
            target_structure.unit_cell_content(omit=('H', 'D')))
    elif amplitude_type == 'quasi-E':
        extra.normalisations_for = charge_flipping.amplitude_quasi_normalisations
    solving = charge_flipping.solving_iterator(
        flipping,
        f_obs,
        yield_during_delta_guessing=True,
        yield_solving_interval=1,
        **extra.__dict__)
    s = StringIO()
    charge_flipping.loop(solving, verbose="highly", out=s)
    if verbose:
        print s.getvalue()

    # check whether a phase transition has occured
    assert solving.had_phase_transition

    flipping = solving.flipping_iterator
    f_result_in_p1 = solving.flipping_iterator.f_calc

    # Euclidean matching of the peaks from the obtained map
    # against those of the correct structure (in P1)
    target_structure = target_structure.select(
        target_structure.scattering_types() == "H", negate=True)
    target_structure_in_p1 = target_structure.expand_to_p1()
    search_parameters = maptbx.peak_search_parameters(
        interpolate=True,
        min_distance_sym_equiv=1.,
        max_clusters=int(target_structure_in_p1.scatterers().size() * 1.2))
    peak_search_outcome = flipping.rho_map.peak_search(search_parameters)
    peak_structure = emma.model(
        target_structure_in_p1.crystal_symmetry().special_position_settings(),
        positions=[
            emma.position('Q%i' % i, x)
            for i, x in enumerate(peak_search_outcome.all().sites())
        ])
    refined_matches = emma.model_matches(
        target_structure_in_p1.as_emma_model(),
        peak_structure,
        tolerance=0.5,
        break_if_match_with_no_singles=False).refined_matches
    m = refined_matches[0]
    assert m.rms < 0.2, m.rms  # no farther than that
    assert m.rt.r in (mat.identity(3), mat.inversion(3))

    reference_shift = -refined_matches[0].rt.t

    # Find the translation to bring back the structure to the same space-group
    # setting as the starting f_obs from correlation map analysis
    is_allowed = lambda x: f_target.space_group_info().is_allowed_origin_shift(
        x, tolerance=0.1)
    first_correct_correlation_peak = None
    for i, (f_calc, shift,
            cc_peak_height) in enumerate(solving.f_calc_solutions):
        if (is_allowed(shift - reference_shift)
                or is_allowed(shift + reference_shift)):
            first_correct_correlation_peak = i
            break
        else:
            if verbose == "more":
                print "++ Incorrect peak: shift=(%.3f, %.3f, %.3f), height=%.2f"\
                      % (tuple(shift)+(cc_peak_height,))
                print "   Reference shift=(%.3f, %.3f, %.3f)" % tuple(
                    reference_shift)
    assert first_correct_correlation_peak is not None
    if verbose and first_correct_correlation_peak != 0:
        print "** First correct correlation peak: #%i (%.3f) **"\
              % (first_correct_correlation_peak, cc_peak_height)

    # check Euclidean matching in the original space-group
    search_parameters = maptbx.peak_search_parameters(
        interpolate=True,
        min_distance_sym_equiv=1.,
        max_clusters=int(1.5 * target_structure.scatterers().size()))
    solution_fft_map = f_calc.fft_map(
        symmetry_flags=maptbx.use_space_group_symmetry)
    solution_peaks = solution_fft_map.peak_search(search_parameters,
                                                  verify_symmetry=False)
    solution_peak_structure = emma.model(
        target_structure.crystal_symmetry().special_position_settings(),
        positions=[
            emma.position('Q%i' % i, x)
            for i, x in enumerate(solution_peaks.all().sites())
        ])
    refined_matches = emma.model_matches(
        target_structure.as_emma_model(),
        solution_peak_structure,
        break_if_match_with_no_singles=False).refined_matches
    assert refined_matches
    m = refined_matches[0]
    assert not m.singles1, m.show()  # all sites match a peak
    assert m.rms < 0.15, m.rms  # no farther than that
    assert m.rt.r in (mat.identity(3), mat.inversion(3))

    # success!
    if verbose:
        print "@@ Success @@"
Esempio n. 32
0
 def __init__(model, m, I, J):
     model.NB = 1
     model.pitch = [J]
     model.parent = [-1]
     model.Xtree = [matrix.identity(n=6)]
     model.I = [featherstone.mcI(m, (0, 0, 0), I)]
Esempio n. 33
0
def exercise_basics():
  # construct a simple structure whose sites and u_iso's are to be refined
  xs = xray.structure(
    crystal_symmetry=crystal.symmetry(
      unit_cell=(10, 10, 10, 90, 90, 90),
      space_group_symbol='hall: P 1'),
    scatterers=flex.xray_scatterer((
      xray.scatterer('C0', site=(0, -1/2, 0), u=0.1),
      xray.scatterer('C1', site=(0,  1/2, 0), u=0.2),
      xray.scatterer('C0a', site=( 1/2, 0, 0), u=0.1),
      xray.scatterer('C1a', site=(-1/2, 0, 0), u=0.2),
    )))
  for sc in xs.scatterers():
    sc.flags.set_grad_site(True)
    sc.flags.set_grad_u_iso(True)

  # copy the original structure as a reference to test against later
  xs_ref = xs.deep_copy_scatterers()

  # mess up the symmetries that the forthcoming constraints shall impose
  c0, c1, c0a, c1a = xs.scatterers()
  c0a.site = (0, 0, 0)
  c1a.site = (1/2, 1/2, 1/2)
  c0a.u_iso = 0.5
  c1a.u_iso = 0.6

  # construct a reparametrisation for the following constraints:
  # (C0a, C1a) is the image of (C0, C1) through a rotation of 90 degrees
  # about the z-axis
  r = constraints.ext.reparametrisation(xs.unit_cell())
  sc_params = constraints.shared_scatterer_parameters(xs.scatterers())
  c0_site_param  = r.add(constraints.independent_site_parameter, c0)
  sc_params[0].site = c0_site_param
  c1_site_param = r.add(constraints.independent_site_parameter, c1)
  sc_params[1].site = c1_site_param
  move_param = r.add(
    constraints.independent_small_6_vector_parameter,
    (0,0,0, 0, 0, math.pi/2))
  c0a_c1a_site_param = r.add(
    constraints.same_group_xyz,
    scatterers=(c0a, c1a),
    sites=(c0_site_param, c1_site_param),
    alignment_matrix=matrix.identity(3),
    shifts_and_angles=move_param)
  sc_params[2].site = sc_params[3].site = c0a_c1a_site_param
  c0_u_iso_param = r.add(constraints.independent_u_iso_parameter, c0)
  sc_params[0].u = c0_u_iso_param
  c1_u_iso_param = r.add(constraints.independent_u_iso_parameter, c1)
  sc_params[1].u = c1_u_iso_param
  c0a_c1a_u_iso_param = r.add(
    constraints.same_group_u_iso,
    scatterers=(c0a, c1a),
    u_isos=(c0_u_iso_param, c1_u_iso_param))
  sc_params[2].u = sc_params[3].u = c0a_c1a_u_iso_param
  r.finalise()

  # put the reparametrisation to work
  r.linearise()
  r.store()
  c0_ref, c1_ref, c0a_ref, c1a_ref = xs_ref.scatterers()
  assert approx_equal(c0a.site, c0a_ref.site, eps=1e-12)
  assert approx_equal(c1a.site, c1a_ref.site, eps=1e-12)
  assert approx_equal(c0a.u_iso, c0a_ref.u_iso, eps=1e-12)
  assert approx_equal(c1a.u_iso, c1a_ref.u_iso, eps=1e-12)

  # check that origin fixing restraints work in the presence of
  # that reparametrisation
  # this is a regression test as they used not to (bug reported by Oleg)
  from smtbx.refinement.restraints import origin_fixing_restraints
  from scitbx import lstbx
  orig_fixing = origin_fixing_restraints.homogeneous_weighting(xs.space_group())
  normal_eqn = lstbx.normal_eqns.ext.linear_ls(n_parameters=(3 + 1)*2 + 6)
  jacobian_transpose_matching_grad_fc = r.jacobian_transpose_matching(
    sc_params.mapping_to_grad_fc())
  orig_fixing.add_to(normal_eqn,
                     jacobian_transpose_matching_grad_fc,
                     sc_params)