Ejemplo n.º 1
0
 def get_UBlattsymm_from_sweep_info(self, sweep_info):
     """Calculate U, B and lattice symmetry from experiment."""
     expt = load.experiment_list(sweep_info.get_experiments())[0]
     uc = expt.crystal.get_unit_cell()
     umatrix = expt.crystal.get_U()
     lattice_symm = lattice_symmetry_group(uc, max_delta=0.0)
     return tuple(umatrix), mosflm_B_matrix(uc), lattice_symm
Ejemplo n.º 2
0
 def lattice_group_info(self):
     # Get highest symmetry compatible with lattice
     lattice_group = sgtbx.lattice_symmetry_group(
         self.minimum_symmetry.unit_cell(),
         max_delta=self.max_delta,
         enforce_max_delta_for_generated_two_folds=self.
         enforce_max_delta_for_generated_two_folds)
     return sgtbx.space_group_info(group=lattice_group)
Ejemplo n.º 3
0
 def lattice_group_info(self):
   # Get highest symmetry compatible with lattice
   lattice_group = sgtbx.lattice_symmetry_group(
     self.minimum_symmetry.unit_cell(),
     max_delta=self.max_delta,
     enforce_max_delta_for_generated_two_folds
       =self.enforce_max_delta_for_generated_two_folds)
   return sgtbx.space_group_info(group=lattice_group)
Ejemplo n.º 4
0
 def lattice_symmetry_group(self,
       max_delta=3,
       enforce_max_delta_for_generated_two_folds=True):
   from cctbx import sgtbx
   return sgtbx.lattice_symmetry_group(
     reduced_cell=self,
     max_delta=max_delta,
     enforce_max_delta_for_generated_two_folds
       =enforce_max_delta_for_generated_two_folds)
Ejemplo n.º 5
0
 def lattice_symmetry_group(self,
       max_delta=3,
       enforce_max_delta_for_generated_two_folds=True):
   from cctbx import sgtbx
   return sgtbx.lattice_symmetry_group(
     reduced_cell=self,
     max_delta=max_delta,
     enforce_max_delta_for_generated_two_folds
       =enforce_max_delta_for_generated_two_folds)
Ejemplo n.º 6
0
def get_umat_bmat_lattice_symmetry_from_mtz(mtz_file):
    """Get the U matrix and lattice symmetry derived from the unit cell
    constants from an MTZ file."""
    m = mtz.object(mtz_file)
    # assert first U matrix from batches is OK
    uc = m.crystals()[0].unit_cell()

    lattice_symm = lattice_symmetry_group(uc, max_delta=0.0)
    return tuple(m.batches()[0].umat()), mosflm_B_matrix(uc), lattice_symm
Ejemplo n.º 7
0
def get_umat_bmat_lattice_symmetry_from_mtz(mtz_file):
  '''Get the U matrix and lattice symmetry derived from the unit cell
    constants from an MTZ file.'''
  from iotbx import mtz
  m = mtz.object(mtz_file)
  # assert first U matrix from batches is OK
  uc = m.crystals()[0].unit_cell()
  from cctbx.sgtbx import lattice_symmetry_group
  lattice_symm = lattice_symmetry_group(uc, max_delta=0.0)
  return tuple(m.batches()[0].umat()), mosflm_B_matrix(uc), lattice_symm
Ejemplo n.º 8
0
def run(args):
    import libtbx.load_env
    from scitbx import matrix
    from cctbx.sgtbx import lattice_symmetry_group
    from scitbx.math import r3_rotation_axis_and_angle_from_matrix

    usage = "%s [options] experiment_0.expt ..." % 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 = params.input.experiments

    # check input
    space_group = None
    for experiment in experiments:
        assert len(experiment.data.goniometers()) == 1
        assert len(experiment.data.crystals()) == 1
        crystal = experiment.data.crystals()[0]
        if space_group is None:
            space_group = crystal.get_space_group()
        else:
            assert crystal.get_space_group() == space_group

    reference_U = None
    reference_space_group = None

    for j, experiment in enumerate(experiments):
        goniometer = experiment.data.goniometers()[0]
        F = matrix.sqr(goniometer.get_fixed_rotation())
        crystal = experiment.data.crystals()[0]
        U = matrix.sqr(crystal.get_U())
        B = matrix.sqr(crystal.get_B())
        UB = F * U * B
        UBt = UB.transpose().elems
        a, b, c = matrix.col(UBt[0:3]), matrix.col(UBt[3:6]), matrix.col(
            UBt[6:9])
        axis = matrix.col(goniometer.get_rotation_axis())
        from math import pi

        r2d = 180 / pi
        abc = [a, b, c]
        abc_names = "abc"
        distances = [(r2d * (min(axis.angle(_a), pi - axis.angle(_a))), k)
                     for k, _a in enumerate(abc)]
        close = sorted(distances)[0]
        if reference_U is None:
            reference_U = U
            reference_space_group = lattice_symmetry_group(
                crystal.get_unit_cell(), max_delta=0.0)
            print("%s possible lattice ops" %
                  len(reference_space_group.all_ops()))

        print("Experiment %d" % j)
        print("Closest (original) axis: %s* %.2f" %
              (abc_names[close[1]], close[0]))

        results = []
        for op in reference_space_group.all_ops():
            R = B * matrix.sqr(op.r().as_double()).transpose() * B.inverse()
            relative = (U * R).inverse() * reference_U
            rot = r3_rotation_axis_and_angle_from_matrix(relative)
            results.append((abs(rot.angle()), op.r().as_hkl(), rot))
        results.sort()
        print("Best reindex op for experiment %d: %12s (%.3f)" %
              (j, results[0][1], 180.0 * results[0][2].angle() / pi))

        if results[0][0] > (5 * pi / 180.0):
            print("Rotation: axis: %.4f %.4f %.4f" % results[0][2].axis)
            print("          angle: %.4f degrees" %
                  (180.0 * results[0][2].angle() / pi))
Ejemplo n.º 9
0
def find_matching_symmetry(unit_cell, target_space_group, max_delta=5):
    cs = crystal.symmetry(unit_cell=unit_cell, space_group=sgtbx.space_group())
    target_bravais_t = bravais_types.bravais_lattice(
        group=target_space_group.info().reference_setting().group())
    best_subgroup = None
    best_angular_difference = 1e8

    # code based on cctbx/sgtbx/lattice_symmetry.py but optimised to only
    # look at subgroups with the correct bravais type

    input_symmetry = cs
    # Get cell reduction operator
    cb_op_inp_minimum = input_symmetry.change_of_basis_op_to_minimum_cell()

    # New symmetry object with changed basis
    minimum_symmetry = input_symmetry.change_basis(cb_op_inp_minimum)

    # Get highest symmetry compatible with lattice
    lattice_group = sgtbx.lattice_symmetry_group(
        minimum_symmetry.unit_cell(),
        max_delta=max_delta,
        enforce_max_delta_for_generated_two_folds=True)

    # Get list of sub-spacegroups
    subgrs = subgroups.subgroups(lattice_group.info()).groups_parent_setting()

    # Order sub-groups
    sort_values = flex.double()
    for group in subgrs:
        order_z = group.order_z()
        space_group_number = sgtbx.space_group_type(group, False).number()
        assert 1 <= space_group_number <= 230
        sort_values.append(order_z * 1000 + space_group_number)
    perm = flex.sort_permutation(sort_values, True)

    for i_subgr in perm:
        acentric_subgroup = subgrs[i_subgr]
        acentric_supergroup = metric_supergroup(acentric_subgroup)
        ## Add centre of inversion to acentric lattice symmetry
        #centric_group = sgtbx.space_group(acentric_subgroup)
        #centric_group.expand_inv(sgtbx.tr_vec((0,0,0)))
        # Make symmetry object: unit-cell + space-group
        # The unit cell is potentially modified to be exactly compatible
        # with the space group symmetry.
        subsym = crystal.symmetry(unit_cell=minimum_symmetry.unit_cell(),
                                  space_group=acentric_subgroup,
                                  assert_is_compatible_unit_cell=False)
        #supersym = crystal.symmetry(
        #unit_cell=minimum_symmetry.unit_cell(),
        #space_group=acentric_supergroup,
        #assert_is_compatible_unit_cell=False)
        # Convert subgroup to reference setting
        cb_op_minimum_ref = subsym.space_group_info().type().cb_op()
        ref_subsym = subsym.change_basis(cb_op_minimum_ref)
        # Ignore unwanted groups
        bravais_t = bravais_types.bravais_lattice(
            group=ref_subsym.space_group())
        if bravais_t != target_bravais_t:
            continue

        # Choose best setting for monoclinic and orthorhombic systems
        cb_op_best_cell = ref_subsym.change_of_basis_op_to_best_cell(
            best_monoclinic_beta=True)

        best_subsym = ref_subsym.change_basis(cb_op_best_cell)
        # Total basis transformation
        cb_op_best_cell = change_of_basis_op(str(cb_op_best_cell),
                                             stop_chars='',
                                             r_den=144,
                                             t_den=144)
        cb_op_minimum_ref = change_of_basis_op(str(cb_op_minimum_ref),
                                               stop_chars='',
                                               r_den=144,
                                               t_den=144)
        cb_op_inp_minimum = change_of_basis_op(str(cb_op_inp_minimum),
                                               stop_chars='',
                                               r_den=144,
                                               t_den=144)
        cb_op_inp_best = cb_op_best_cell * cb_op_minimum_ref * cb_op_inp_minimum
        # Use identity change-of-basis operator if possible
        if best_subsym.unit_cell().is_similar_to(input_symmetry.unit_cell()):
            cb_op_corr = cb_op_inp_best.inverse()
            try:
                best_subsym_corr = best_subsym.change_basis(cb_op_corr)
            except RuntimeError as e:
                if str(e).find(
                        "Unsuitable value for rational rotation matrix.") < 0:
                    raise
            else:
                if best_subsym_corr.space_group() == best_subsym.space_group():
                    cb_op_inp_best = cb_op_corr * cb_op_inp_best

        max_angular_difference = find_max_delta(
            reduced_cell=minimum_symmetry.unit_cell(),
            space_group=acentric_supergroup)

        if max_angular_difference < best_angular_difference:
            #best_subgroup = subgroup
            best_angular_difference = max_angular_difference
            best_subgroup = {
                'subsym': subsym,
                #'supersym':supersym,
                'ref_subsym': ref_subsym,
                'best_subsym': best_subsym,
                'cb_op_inp_best': cb_op_inp_best,
                'max_angular_difference': max_angular_difference
            }

    if best_subgroup is not None:
        return best_subgroup
Ejemplo n.º 10
0
def find_matching_symmetry(unit_cell, target_space_group, max_delta=5):
  cs = crystal.symmetry(unit_cell=unit_cell, space_group=sgtbx.space_group())
  target_bravais_t = bravais_types.bravais_lattice(
    group=target_space_group.info().reference_setting().group())
  best_subgroup = None
  best_angular_difference = 1e8

  # code based on cctbx/sgtbx/lattice_symmetry.py but optimised to only
  # look at subgroups with the correct bravais type

  input_symmetry = cs
  # Get cell reduction operator
  cb_op_inp_minimum = input_symmetry.change_of_basis_op_to_minimum_cell()

  # New symmetry object with changed basis
  minimum_symmetry = input_symmetry.change_basis(cb_op_inp_minimum)

  # Get highest symmetry compatible with lattice
  lattice_group = sgtbx.lattice_symmetry_group(
    minimum_symmetry.unit_cell(),
    max_delta=max_delta,
    enforce_max_delta_for_generated_two_folds=True)

  # Get list of sub-spacegroups
  subgrs = subgroups.subgroups(lattice_group.info()).groups_parent_setting()

  # Order sub-groups
  sort_values = flex.double()
  for group in subgrs:
    order_z = group.order_z()
    space_group_number = sgtbx.space_group_type(group, False).number()
    assert 1 <= space_group_number <= 230
    sort_values.append(order_z*1000+space_group_number)
  perm = flex.sort_permutation(sort_values, True)

  for i_subgr in perm:
    acentric_subgroup = subgrs[i_subgr]
    acentric_supergroup = metric_supergroup(acentric_subgroup)
    ## Add centre of inversion to acentric lattice symmetry
    #centric_group = sgtbx.space_group(acentric_subgroup)
    #centric_group.expand_inv(sgtbx.tr_vec((0,0,0)))
    # Make symmetry object: unit-cell + space-group
    # The unit cell is potentially modified to be exactly compatible
    # with the space group symmetry.
    subsym = crystal.symmetry(
      unit_cell=minimum_symmetry.unit_cell(),
      space_group=acentric_subgroup,
      assert_is_compatible_unit_cell=False)
    #supersym = crystal.symmetry(
      #unit_cell=minimum_symmetry.unit_cell(),
      #space_group=acentric_supergroup,
      #assert_is_compatible_unit_cell=False)
    # Convert subgroup to reference setting
    cb_op_minimum_ref = subsym.space_group_info().type().cb_op()
    ref_subsym = subsym.change_basis(cb_op_minimum_ref)
    # Ignore unwanted groups
    bravais_t = bravais_types.bravais_lattice(
      group=ref_subsym.space_group())
    if bravais_t != target_bravais_t:
      continue

    # Choose best setting for monoclinic and orthorhombic systems
    cb_op_best_cell = ref_subsym.change_of_basis_op_to_best_cell(
      best_monoclinic_beta=True)

    best_subsym = ref_subsym.change_basis(cb_op_best_cell)
    # Total basis transformation
    cb_op_best_cell = change_of_basis_op(str(cb_op_best_cell),stop_chars='',r_den=144,t_den=144)
    cb_op_minimum_ref=change_of_basis_op(str(cb_op_minimum_ref),stop_chars='',r_den=144,t_den=144)
    cb_op_inp_minimum=change_of_basis_op(str(cb_op_inp_minimum),stop_chars='',r_den=144,t_den=144)
    cb_op_inp_best = cb_op_best_cell * cb_op_minimum_ref * cb_op_inp_minimum
    # Use identity change-of-basis operator if possible
    if (best_subsym.unit_cell().is_similar_to(input_symmetry.unit_cell())):
      cb_op_corr = cb_op_inp_best.inverse()
      try:
        best_subsym_corr = best_subsym.change_basis(cb_op_corr)
      except RuntimeError, e:
        if (str(e).find("Unsuitable value for rational rotation matrix.") < 0):
          raise
      else:
        if (best_subsym_corr.space_group() == best_subsym.space_group()):
          cb_op_inp_best = cb_op_corr * cb_op_inp_best

    max_angular_difference = find_max_delta(
      reduced_cell=minimum_symmetry.unit_cell(),
      space_group=acentric_supergroup)

    if max_angular_difference < best_angular_difference:
      #best_subgroup = subgroup
      best_angular_difference = max_angular_difference
      best_subgroup = {'subsym':subsym,
                       #'supersym':supersym,
                       'ref_subsym':ref_subsym,
                       'best_subsym':best_subsym,
                       'cb_op_inp_best':cb_op_inp_best,
                       'max_angular_difference':max_angular_difference
                       }
Ejemplo n.º 11
0
def run(args):
  import libtbx.load_env
  from scitbx import matrix
  from cctbx.sgtbx import lattice_symmetry_group
  from scitbx.math import r3_rotation_axis_and_angle_from_matrix

  usage = "%s [options] experiment_0.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 = params.input.experiments

  # check input
  space_group = None
  for experiment in experiments:
    assert(len(experiment.data.goniometers()) == 1)
    assert(len(experiment.data.crystals()) == 1)
    crystal = experiment.data.crystals()[0]
    if space_group is None:
      space_group = crystal.get_space_group()
    else:
      assert(crystal.get_space_group() == space_group)

  reference_U = None
  reference_space_group = None

  for j, experiment in enumerate(experiments):
    goniometer = experiment.data.goniometers()[0]
    F = matrix.sqr(goniometer.get_fixed_rotation())
    crystal = experiment.data.crystals()[0]
    U = matrix.sqr(crystal.get_U())
    B = matrix.sqr(crystal.get_B())
    UB = F * U * B
    UBt = UB.transpose().elems
    a, b, c = matrix.col(UBt[0:3]), matrix.col(UBt[3:6]), matrix.col(UBt[6:9])
    axis = matrix.col(goniometer.get_rotation_axis())
    from math import pi
    r2d = 180 / pi
    abc = [a, b, c]
    abc_names = 'abc'
    distances = [(r2d * (min(axis.angle(_a), pi - axis.angle(_a))), k)
                 for k, _a in enumerate(abc)]
    close = sorted(distances)[0]
    if reference_U is None:
      reference_U = U
      reference_space_group = lattice_symmetry_group(crystal.get_unit_cell(),
                                                     max_delta=0.0)
      print '%s possible lattice ops' % len(reference_space_group.all_ops())

    print 'Experiment %d' % j
    print 'Closest (original) axis: %s* %.2f' % \
      (abc_names[close[1]], close[0])

    results = []
    for op in reference_space_group.all_ops():
      R = B * matrix.sqr(op.r().as_double()).transpose() * B.inverse()
      relative = (U * R).inverse() * reference_U
      rot = r3_rotation_axis_and_angle_from_matrix(relative)
      results.append((abs(rot.angle()), op.r().as_hkl(), rot))
    results.sort()
    print 'Best reindex op for experiment %d: %12s (%.3f)' % \
      (j, results[0][1], 180.0 * results[0][2].angle() / pi)

    if results[0][0] > (5 * pi / 180.0):
      print 'Rotation: axis: %.4f %.4f %.4f' % results[0][2].axis
      print '          angle: %.4f degrees' % \
        (180.0 * results[0][2].angle() / pi)