Beispiel #1
0
def get_spacegroup(facet, parent_sg, O):
    """
    Get reduced symmetry spacegroup for crystal aligned on `facet`.
    """
    e_field_direction = np.linalg.inv(O) @ (np.linalg.inv(O).T @ facet)
    e_field_unit_vector = np.array(e_field_direction) / np.linalg.norm(
        e_field_direction)

    parent = sgtbx.space_group_info(parent_sg)
    subgrs = subgroups.subgroups(parent).groups_parent_setting()

    possible = []
    for subgroup in subgrs:
        subgroup_info = sgtbx.space_group_info(group=subgroup)
        valid = True
        for op in subgroup.smx():
            rot_mat = np.array(op.r().as_double()).reshape((3, 3))
            valid &= np.allclose(rot_mat @ e_field_unit_vector,
                                 e_field_unit_vector)

        if valid:
            possible.append([
                subgroup.n_smx(),
                subgroup_info.symbol_and_number(), subgroup
            ])

    possible = sorted(possible)
    return possible[-1][1], possible[-1][0]
def generate_mtz_files(space_group_info, anomalous_flag):
    crystal_symmetry = crystal.symmetry(
        unit_cell=space_group_info.any_compatible_unit_cell(volume=1000),
        space_group_info=space_group_info)
    miller_set = miller.build_set(crystal_symmetry=crystal_symmetry,
                                  anomalous_flag=anomalous_flag,
                                  d_min=1)
    miller_array = miller.array(
        miller_set=miller_set,
        data=flex.random_double(size=miller_set.indices().size()))
    miller_array_p1 = miller_array.expand_to_p1()
    miller_arrays = []
    file_names = []
    subgrs = subgroups.subgroups(space_group_info).groups_parent_setting()
    for i_subgroup, subgroup in enumerate(subgrs):
        subgroup_miller_array = miller_array_p1.customized_copy(
          space_group_info=sgtbx.space_group_info(group=subgroup)) \
            .merge_equivalents() \
            .array() \
            .as_reference_setting() \
            .set_observation_type_xray_intensity()
        file_name = "tmp_refl_stats%d.mtz" % i_subgroup
        mtz_object = subgroup_miller_array.as_mtz_dataset(
            column_root_label="FOBS").mtz_object().write(file_name=file_name)
        miller_arrays.append(
            subgroup_miller_array.f_sq_as_f().expand_to_p1().map_to_asu())
        file_names.append(file_name)
    return miller_arrays, file_names
def generate_mtz_files(space_group_info, anomalous_flag):
  crystal_symmetry = crystal.symmetry(
    unit_cell=space_group_info.any_compatible_unit_cell(volume=1000),
    space_group_info=space_group_info)
  miller_set = miller.build_set(
    crystal_symmetry=crystal_symmetry,
    anomalous_flag=anomalous_flag,
    d_min=1)
  miller_array = miller.array(
    miller_set=miller_set,
    data=flex.random_double(size=miller_set.indices().size()))
  miller_array_p1 = miller_array.expand_to_p1()
  miller_arrays = []
  file_names = []
  subgrs = subgroups.subgroups(space_group_info).groups_parent_setting()
  for i_subgroup, subgroup in enumerate(subgrs):
    subgroup_miller_array = miller_array_p1.customized_copy(
      space_group_info=sgtbx.space_group_info(group=subgroup)) \
        .merge_equivalents() \
        .array() \
        .as_reference_setting() \
        .set_observation_type_xray_intensity()
    file_name = "tmp_refl_stats%d.mtz" % i_subgroup
    mtz_object = subgroup_miller_array.as_mtz_dataset(
      column_root_label="FOBS").mtz_object().write(file_name=file_name)
    miller_arrays.append(
      subgroup_miller_array.f_sq_as_f().expand_to_p1().map_to_asu())
    file_names.append(file_name)
  return miller_arrays, file_names
Beispiel #4
0
 def update_space_group_choices(self):
     if self.viewer.miller_array is None or \
       self.params.NGL_HKLviewer.using_space_subgroup:
         return
     current_miller_array_idx = self.viewer.hkl_scenes_info[
         self.viewer.scene_id][1]
     matching_valid_array = self.valid_arrays[current_miller_array_idx]
     from cctbx.sgtbx.subgroups import subgroups
     from cctbx import sgtbx
     sg_info = matching_valid_array.space_group_info()
     subgrs = subgroups(sg_info).groups_parent_setting()
     self.spacegroup_choices = []
     for i, subgroup in enumerate(subgrs):
         subgroup_info = sgtbx.space_group_info(group=subgroup)
         self.spacegroup_choices.append(subgroup_info)
     if (sg_info in self.spacegroup_choices):
         self.current_spacegroup = self.spacegroup_choices.index(sg_info)
     else:
         self.spacegroup_choices.insert(0, sg_info)
         self.current_spacegroup = sg_info
     mydict = {
         "spacegroups":
         [e.symbol_and_number() for e in self.spacegroup_choices]
     }
     self.SendInfoToGUI(mydict)
 def update_space_group_choices(self, col=None) :
   if (self.viewer.miller_array is None and col is None) or \
     self.params.using_space_subgroup:
     return
   if col is None:
     current_miller_array_idx = self.viewer.HKLInfo_from_dict()[1]
   else:
     current_miller_array_idx = col
   matching_valid_array = self.procarrays[ current_miller_array_idx ]
   from cctbx.sgtbx.subgroups import subgroups
   from cctbx import sgtbx
   sg_info = matching_valid_array.space_group_info()
   subgrs = subgroups(sg_info).groups_parent_setting()
   self.spacegroup_choices = []
   for i,subgroup in enumerate(subgrs) :
     subgroup_info = sgtbx.space_group_info(group=subgroup)
     self.spacegroup_choices.append(subgroup_info)
   for i,e in enumerate(self.spacegroup_choices):
     c = None
     if str(sg_info) == str(e):
       self.current_spacegroup = self.spacegroup_choices[i]
       c = i
       break
   if c is None:
     c = 0
     self.spacegroup_choices.insert(c, sg_info)
     self.current_spacegroup = sg_info
   self.params.spacegroup_choice = c
   spglst = [e.symbol_and_number() for e in self.spacegroup_choices] + ["original spacegroup"]
   mydict = { "spacegroups": spglst }
   self.SendInfoToGUI(mydict)
Beispiel #6
0
 def __init__(self, parent_group_info):
   self.subgroups = subgroups.subgroups(
     parent_group_info).groups_parent_setting()
   self.n_non_centric = 0
   self.n_chiral = 0
   for subgroup in self.subgroups:
     if (not subgroup.is_centric()): self.n_non_centric += 1
     if (subgroup.is_chiral()): self.n_chiral += 1
Beispiel #7
0
def test_double_coset_decomposition():
    from cctbx.sgtbx import subgroups
    for space_group_number in xrange(17, 44):
        parent_group_info = sgtbx.space_group_info(space_group_number)
        subgrs = subgroups.subgroups(parent_group_info).groups_parent_setting()
        g = parent_group_info.group()
        for h1 in subgrs:
            for h2 in subgrs:
                tmp_new = double_cosets(g, h1, h2)
                assert not tmp_new.have_duplicates()
Beispiel #8
0
def test_double_coset_decomposition():
  from  cctbx.sgtbx import subgroups
  for space_group_number in xrange(17,44):
    parent_group_info = sgtbx.space_group_info(space_group_number)
    subgrs = subgroups.subgroups(parent_group_info).groups_parent_setting()
    g = parent_group_info.group()
    for h1 in subgrs:
      for h2 in subgrs:
        tmp_new = double_cosets(g, h1, h2)
        assert not tmp_new.have_duplicates()
def exercise_quick():
  for space_group_symbol in ("P-1",
                             "P2/m",
                             "C2/m",
                             "Pmmm",
                             "Cmmm",
                             "Fmmm",
                             "Immm",
                             "P4/mmm",
                             "I4/mmm",
                             "R-3m",
                             "P6/mmm",
                             "Pm-3m",
                             "Im-3m",
                             "Fm-3m"):
    parent_group_info = sgtbx.space_group_info(space_group_symbol)
    non_centric = sgtbx.space_group()
    for i_ltr in xrange(parent_group_info.group().n_ltr()):
      for i_smx in xrange(parent_group_info.group().n_smx()):
        s = parent_group_info.group()(i_ltr,0,i_smx)
        non_centric.expand_smx(s)
    assert non_centric.f_inv() == 1
    assert non_centric.order_z() * 2 == parent_group_info.group().order_z()
    non_centric_info = sgtbx.space_group_info(group=non_centric)
    unit_cell = non_centric_info.any_compatible_unit_cell(volume=1000)
    crystal_symmetry = crystal.symmetry(
      unit_cell=unit_cell,
      space_group_info=non_centric_info)
    minimum_symmetry = crystal_symmetry.minimum_cell()
    lattice_group = lattice_symmetry.group(
      minimum_symmetry.unit_cell(), max_delta=0.5)
    lattice_group_info = sgtbx.space_group_info(group=lattice_group)
    assert lattice_group_info.group() == minimum_symmetry.space_group()
    subgrs = subgroups.subgroups(lattice_group_info).groups_parent_setting()
    for group in subgrs:
      subsym = crystal.symmetry(
        unit_cell=minimum_symmetry.unit_cell(),
        space_group=group,
        assert_is_compatible_unit_cell=False)
      assert subsym.unit_cell().is_similar_to(minimum_symmetry.unit_cell())
      assert lattice_symmetry.find_max_delta(
        reduced_cell=minimum_symmetry.unit_cell(),
        space_group=group) < 0.6
  minimum_symmetry = crystal.symmetry(
    unit_cell="106.04, 181.78, 110.12, 90, 90, 90",
    space_group_symbol="P 1").minimum_cell()
  for max_delta in xrange(10,100,10):
    lattice_group = lattice_symmetry.group(
      minimum_symmetry.unit_cell(), max_delta=max_delta)
    lattice_group_info = sgtbx.space_group_info(group=lattice_group)
    assert str(lattice_group_info) == "P 4 2 2"
 def update_space_group_choices(self):
     from cctbx.sgtbx.subgroups import subgroups
     from cctbx import sgtbx
     sg_info = self.miller_array.space_group_info()
     subgrs = subgroups(sg_info).groups_parent_setting()
     self.spacegroup_choices = []
     for i, subgroup in enumerate(subgrs):
         subgroup_info = sgtbx.space_group_info(group=subgroup)
         self.spacegroup_choices.append(subgroup_info)
         self.mprint("%d, %s" % (i, subgroup_info.symbol_and_number()))
     if (sg_info in self.spacegroup_choices):
         self.current_spacegroup = self.spacegroup_choices.index(sg_info)
     else:
         self.spacegroup_choices.insert(0, sg_info)
         self.current_spacegroup = sg_info
Beispiel #11
0
 def update_space_group_choices(self, miller_array):
     from cctbx.sgtbx.subgroups import subgroups
     from cctbx import sgtbx
     sg_info = miller_array.space_group_info()
     subgrs = subgroups(sg_info).groups_parent_setting()
     choices = []
     for subgroup in subgrs:
         subgroup_info = sgtbx.space_group_info(group=subgroup)
         choices.append(str(subgroup_info))
     if (str(sg_info) in choices):
         current = choices.index(str(sg_info))
     else:
         choices.insert(0, str(sg_info))
         current = 0
     self.sg_ctrl.SetItems(choices)
     self.sg_ctrl.SetSelection(current)
     self._last_sg_sel = str(sg_info)
Beispiel #12
0
 def update_space_group_choices (self, miller_array) :
   from cctbx.sgtbx.subgroups import subgroups
   from cctbx import sgtbx
   sg_info  = miller_array.space_group_info()
   subgrs = subgroups(sg_info).groups_parent_setting()
   choices = []
   for subgroup in subgrs :
     subgroup_info = sgtbx.space_group_info(group=subgroup)
     choices.append(str(subgroup_info))
   if (str(sg_info) in choices) :
     current = choices.index(str(sg_info))
   else :
     choices.insert(0, str(sg_info))
     current = 0
   self.sg_ctrl.SetItems(choices)
   self.sg_ctrl.SetSelection(current)
   self._last_sg_sel = str(sg_info)
Beispiel #13
0
def exercise_quick():
    for space_group_symbol in ("P-1", "P2/m", "C2/m", "Pmmm", "Cmmm", "Fmmm",
                               "Immm", "P4/mmm", "I4/mmm", "R-3m", "P6/mmm",
                               "Pm-3m", "Im-3m", "Fm-3m"):
        parent_group_info = sgtbx.space_group_info(space_group_symbol)
        non_centric = sgtbx.space_group()
        for i_ltr in range(parent_group_info.group().n_ltr()):
            for i_smx in range(parent_group_info.group().n_smx()):
                s = parent_group_info.group()(i_ltr, 0, i_smx)
                non_centric.expand_smx(s)
        assert non_centric.f_inv() == 1
        assert non_centric.order_z() * 2 == parent_group_info.group().order_z()
        non_centric_info = sgtbx.space_group_info(group=non_centric)
        unit_cell = non_centric_info.any_compatible_unit_cell(volume=1000)
        crystal_symmetry = crystal.symmetry(unit_cell=unit_cell,
                                            space_group_info=non_centric_info)
        minimum_symmetry = crystal_symmetry.minimum_cell()
        lattice_group = lattice_symmetry.group(minimum_symmetry.unit_cell(),
                                               max_delta=0.5)
        lattice_group_info = sgtbx.space_group_info(group=lattice_group)
        assert lattice_group_info.group() == minimum_symmetry.space_group()
        subgrs = subgroups.subgroups(
            lattice_group_info).groups_parent_setting()
        for group in subgrs:
            subsym = crystal.symmetry(unit_cell=minimum_symmetry.unit_cell(),
                                      space_group=group,
                                      assert_is_compatible_unit_cell=False)
            assert subsym.unit_cell().is_similar_to(
                minimum_symmetry.unit_cell())
            assert lattice_symmetry.find_max_delta(
                reduced_cell=minimum_symmetry.unit_cell(),
                space_group=group) < 0.6
    minimum_symmetry = crystal.symmetry(
        unit_cell="106.04, 181.78, 110.12, 90, 90, 90",
        space_group_symbol="P 1").minimum_cell()
    for max_delta in range(10, 100, 10):
        lattice_group = lattice_symmetry.group(minimum_symmetry.unit_cell(),
                                               max_delta=max_delta)
        lattice_group_info = sgtbx.space_group_info(group=lattice_group)
        assert str(lattice_group_info) == "P 4 2 2"
Beispiel #14
0
def tst_bravais_types(verbose):
  from cctbx import sgtbx
  from cctbx.sgtbx.subgroups import subgroups

  bravais_types_reference = {"aP":2,"mP":8,"mC":5,"mA":0,"mI":0,"mB":0,"oP":30,"oC":11,
                             "oA":4,"oB":0,"oI":9,"oF":5,"tP":49,"tI":19,"hP":45,"hR":7,
                             "cP":15,"cI":10,"cF":11}

  bravais_types_tally = {}
  for key in bravais_types_reference: bravais_types_tally[key]=0

  crystal_systems_reference = {"Triclinic":2,"Monoclinic":13,"Orthorhombic":59,"Tetragonal":68,
                               "Trigonal":25,"Hexagonal":27,"Cubic":36}
  crystal_systems_tally = {}
  for key in crystal_systems_reference: crystal_systems_tally[key]=0

  for space_group_number in xrange(1,231):
    space_group_info = sgtbx.space_group_info(number=space_group_number)
    GC = bravais_lattice(number=space_group_number)
    GC_1 = bravais_lattice(group=space_group_info.group())
    GC_2 = bravais_lattice(symbol=str(space_group_info))
    assert GC == GC_1
    assert GC == GC_2
    bravais_types_tally[str(GC)]+=1
    crystal_systems_tally[GC.crystal_system]+=1
    if verbose:
      GC.space_group_info.show_summary()
      print str(GC), GC.crystal_system

    # idea, not fully implemented--more extensive testing by generating all subgroups
    if False:
      subgrs = subgroups(parent_group_info).groups_parent_setting()
      for subgroup in subgrs:
        subgroup_info = sgtbx.space_group_info(group=subgroup)
        subgroup_info.show_summary()
        bravais_lattice(subgroup_info.type().lookup_symbol())

  return (bravais_types_tally==bravais_types_reference and
          crystal_systems_tally==crystal_systems_reference)
Beispiel #15
0
def tst_bravais_types(verbose):
    from cctbx import sgtbx
    from cctbx.sgtbx.subgroups import subgroups

    bravais_types_reference = {
        "aP": 2,
        "mP": 8,
        "mC": 5,
        "mA": 0,
        "mI": 0,
        "mB": 0,
        "oP": 30,
        "oC": 11,
        "oA": 4,
        "oB": 0,
        "oI": 9,
        "oF": 5,
        "tP": 49,
        "tI": 19,
        "hP": 45,
        "hR": 7,
        "cP": 15,
        "cI": 10,
        "cF": 11
    }

    bravais_types_tally = {}
    for key in bravais_types_reference:
        bravais_types_tally[key] = 0

    crystal_systems_reference = {
        "Triclinic": 2,
        "Monoclinic": 13,
        "Orthorhombic": 59,
        "Tetragonal": 68,
        "Trigonal": 25,
        "Hexagonal": 27,
        "Cubic": 36
    }
    crystal_systems_tally = {}
    for key in crystal_systems_reference:
        crystal_systems_tally[key] = 0

    for space_group_number in xrange(1, 231):
        space_group_info = sgtbx.space_group_info(number=space_group_number)
        GC = bravais_lattice(number=space_group_number)
        GC_1 = bravais_lattice(group=space_group_info.group())
        GC_2 = bravais_lattice(symbol=str(space_group_info))
        assert GC == GC_1
        assert GC == GC_2
        bravais_types_tally[str(GC)] += 1
        crystal_systems_tally[GC.crystal_system] += 1
        if verbose:
            GC.space_group_info.show_summary()
            print str(GC), GC.crystal_system

        # idea, not fully implemented--more extensive testing by generating all subgroups
        if False:
            subgrs = subgroups(parent_group_info).groups_parent_setting()
            for subgroup in subgrs:
                subgroup_info = sgtbx.space_group_info(group=subgroup)
                subgroup_info.show_summary()
                bravais_lattice(subgroup_info.type().lookup_symbol())

    return (bravais_types_tally == bravais_types_reference
            and crystal_systems_tally == crystal_systems_reference)
Beispiel #16
0
def generate_test_data(
    space_group,
    lattice_group=None,
    unit_cell=None,
    unit_cell_volume=1000,
    seed=0,
    d_min=1,
    sigma=0.1,
    sample_size=100,
    map_to_p1=False,
    twin_fractions=None,
    map_to_minimum=True,
):

    import random

    if seed is not None:
        flex.set_random_seed(seed)
        random.seed(seed)

    assert [unit_cell, lattice_group].count(None) > 0

    sgi = space_group.info()

    if unit_cell is not None:
        cs = crystal.symmetry(unit_cell=unit_cell, space_group_info=sgi)
    elif lattice_group is not None:
        subgrps = subgroups(lattice_group).groups_parent_setting()
        assert space_group in subgrps
        cs = lattice_group.any_compatible_crystal_symmetry(
            volume=unit_cell_volume).customized_copy(space_group_info=sgi)
    else:
        cs = sgi.any_compatible_crystal_symmetry(volume=unit_cell_volume)

    if map_to_minimum:
        cs = cs.minimum_cell()
    intensities = generate_intensities(cs, d_min=d_min)
    intensities.show_summary()

    twin_ops = generate_twin_operators(intensities)
    twin_ops = [
        sgtbx.change_of_basis_op(op.operator.as_xyz()) for op in twin_ops
    ]

    if twin_fractions is not None:
        assert len(twin_fractions) == len(twin_ops)
        assert len(
            twin_fractions) == 1, "Only 1 twin component currently supported"
        twin_op = twin_ops[0]
        twin_fraction = twin_fractions[0]
        intensities, intensities_twin = intensities.common_sets(
            intensities.change_basis(twin_op).map_to_asu())
        twinned_miller = intensities.customized_copy(
            data=(1.0 - twin_fraction) * intensities.data() +
            twin_fraction * intensities_twin.data(),
            sigmas=flex.sqrt(
                flex.pow2((1.0 - twin_fraction) * intensities.sigmas()) +
                flex.pow2(twin_fraction * intensities_twin.sigmas())),
        )
        intensities = twinned_miller

    cb_ops = twin_ops
    cb_ops.insert(0, sgtbx.change_of_basis_op())

    reindexing_ops = {}

    datasets = []
    rand_norm = scitbx.random.normal_distribution(mean=0, sigma=sigma)
    g = scitbx.random.variate(rand_norm)
    for i in range(sample_size):
        cb_op = random.choice(cb_ops)
        if cb_op.as_xyz() not in reindexing_ops:
            reindexing_ops[cb_op.as_xyz()] = set()
        reindexing_ops[cb_op.as_xyz()].add(i)
        d = intensities.change_basis(cb_op).customized_copy(
            crystal_symmetry=intensities.crystal_symmetry())

        if map_to_p1:
            cb_op_to_primitive = d.change_of_basis_op_to_primitive_setting()
            d = d.change_basis(cb_op_to_primitive)
            d = d.expand_to_p1()

        d = d.customized_copy(data=d.data() + g(d.size()))
        datasets.append(d)

    return datasets, reindexing_ops
  def derive_result_group_list_original_input(self,group_of_interest):
    # more-or-less a capitulation to code duplication.  Don't want to copy code
    # from cctbx.sgtbx.lattice_symmetry but can't figure out a quick way around it.

    # Get list of sub-spacegroups
    subgrs = subgroups.subgroups(group_of_interest).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)
      # 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=self.minimum_symmetry.unit_cell(),
        space_group=centric_group,
        assert_is_compatible_unit_cell=False)
      supersym = crystal.symmetry(
        unit_cell=self.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
      if (self.bravais_types_only and
          not str(ref_subsym.space_group_info()) in bravais_types.centric):
        continue
      # Choose best setting for monoclinic and orthorhombic systems
      cb_op_best_cell = self.change_of_basis_op_to_best_cell(ref_subsym)
      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)
      self.cb_op_inp_minimum=change_of_basis_op(str(self.cb_op_inp_minimum),stop_chars='',r_den=144,t_den=144)
      cb_op_inp_best = cb_op_best_cell * (cb_op_minimum_ref * self.cb_op_inp_minimum)
      # Use identity change-of-basis operator if possible
      if (best_subsym.unit_cell().is_similar_to(self.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
      """Note:  The following call does not work if n_ltr >1 for the space group"""
      if acentric_subgroup.n_ltr() == 1:
        m_a_d = find_max_delta(
                                  reduced_cell=self.minimum_symmetry.unit_cell(),
                                  space_group=acentric_subgroup)
      else:
        m_a_d = 0.0
      self.result_groups.append({'subsym':subsym,
                                 'supersym':supersym,
                                 'ref_subsym':ref_subsym,
                                 'best_subsym':best_subsym,
                                 'cb_op_inp_best':cb_op_inp_best,
                                 'max_angular_difference':m_a_d
                                })
Beispiel #18
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
    def derive_result_group_list(self, group_of_interest):

        # Get list of sub-spacegroups
        subgrs = subgroups.subgroups(group_of_interest).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=self.minimum_symmetry.unit_cell(),
                space_group=centric_group,
                assert_is_compatible_unit_cell=False)
            supersym = crystal.symmetry(
                unit_cell=self.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
            if (self.bravais_types_only and not str(
                    ref_subsym.space_group_info()) in bravais_types.centric):
                continue
            # Choose best setting for monoclinic and orthorhombic systems
            cb_op_best_cell = self.change_of_basis_op_to_best_cell(ref_subsym)
            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)
            self.cb_op_inp_minimum = change_of_basis_op(str(
                self.cb_op_inp_minimum),
                                                        stop_chars='',
                                                        r_den=144,
                                                        t_den=144)
            cb_op_inp_best = cb_op_best_cell * cb_op_minimum_ref * self.cb_op_inp_minimum
            # Use identity change-of-basis operator if possible
            if (best_subsym.unit_cell().is_similar_to(
                    self.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
            self.result_groups.append({
                'subsym':
                subsym,
                'supersym':
                supersym,
                'ref_subsym':
                ref_subsym,
                'best_subsym':
                best_subsym,
                'cb_op_inp_best':
                cb_op_inp_best,
                'max_angular_difference':
                find_max_delta(reduced_cell=self.minimum_symmetry.unit_cell(),
                               space_group=acentric_supergroup)
            })
Beispiel #20
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
                       }