예제 #1
0
파일: symmetry.py 프로젝트: dwpaley/dials
def change_of_basis_ops_to_minimum_cell(
    experiments, max_delta, relative_length_tolerance, absolute_angle_tolerance
):
    """
    Compute change of basis ops to map experiments to the minimum cell

    Map to the minimum cell via the best cell, which appears to guarantee that the
    resulting minimum cells are consistent.

    Args:
        experiments (ExperimentList): a list of experiments.
        reflections (list): a list of reflection tables

    Returns: The experiments and reflections mapped to the minimum cell
    """

    median_cell = median_unit_cell(experiments)
    unit_cells_are_similar = unit_cells_are_similar_to(
        experiments, median_cell, relative_length_tolerance, absolute_angle_tolerance
    )
    centring_symbols = [
        bravais_lattice(group=expt.crystal.get_space_group()).centring_symbol
        for expt in experiments
    ]
    if unit_cells_are_similar and len(set(centring_symbols)) == 1:
        groups = metric_subgroups(
            experiments[0]
            .crystal.get_crystal_symmetry()
            .customized_copy(unit_cell=median_cell),
            max_delta,
            enforce_max_delta_for_generated_two_folds=True,
        )
        group = groups.result_groups[0]
        cb_op_best_to_min = group["best_subsym"].change_of_basis_op_to_minimum_cell()
        cb_ops = [cb_op_best_to_min * group["cb_op_inp_best"]] * len(experiments)
    else:
        cb_ops = []
        for expt in experiments:
            groups = metric_subgroups(
                expt.crystal.get_crystal_symmetry(),
                max_delta,
                best_monoclinic_beta=False,
                enforce_max_delta_for_generated_two_folds=True,
            )
            group = groups.result_groups[0]
            cb_ops.append(group["cb_op_inp_best"])
        ref_expts = experiments.change_basis(cb_ops)
        cb_op_ref_min = (
            ref_expts[0]
            .crystal.get_crystal_symmetry()
            .customized_copy(unit_cell=median_unit_cell(ref_expts))
            .change_of_basis_op_to_minimum_cell()
        )
        cb_ops = [cb_op_ref_min * cb_op for cb_op in cb_ops]
    return cb_ops
def tst_instability_on_the_lepage_tolerance():
  """Basic idea:  we introduced the Lepage tolerance to solve the problem
     that numerically-determined or experimentally-determined twofolds do
     not fall at exact positions.  However, when the input is exact, we
     expect to be able to reduce the tolerance to zero."""

  def give_cases():
    from cctbx import crystal
    from cctbx.uctbx import unit_cell
    from cctbx.sgtbx import space_group_info
    pdb =["1vjg/P 32 2 1/(56.192, 56.192, 129.318, 90, 90, 120)/16",
          "1vjz/P 43 21 2/(64.684, 64.684, 202.189, 90, 90, 90)/10",
          "1vl6/P 65/(143.963, 143.963, 163.428, 90, 90, 120)/16",
          "1vlc/P 3 2 1/(118.78, 118.78, 56.699, 90, 90, 120)/16",
          "2ash/C 1 2 1/(169.467, 99.422, 124.163, 90, 123.8, 90)/2",
          "2etj/P 31/(51.821, 51.821, 76.293, 90, 90, 120)/16",
          "2qyv/P 21 21 2/(173.922, 84.293, 123.204, 90, 90, 90)/5"]
    for header in pdb:
      tokens=header.split("/")
      case = {"pdb_code":tokens[0],"centring_type":tokens[1][0],
              "unit_cell":unit_cell(eval(tokens[2])),
              "expected_centrosymmetric_subgroups_of_metric":int(tokens[3])}
      case["symmetry"]=crystal.symmetry(space_group_info=
                         space_group_info(tokens[1]),
                         unit_cell=case["unit_cell"])
      yield case

  from cctbx.sgtbx.lattice_symmetry import metric_subgroups
  for small_max_delta in [1.E-6, 0.0]:
    for case in give_cases():
      G = metric_subgroups(case["symmetry"],
                         max_delta=small_max_delta,bravais_types_only=False)
    assert len(G.result_groups)==case["expected_centrosymmetric_subgroups_of_metric"]

  return True
예제 #3
0
def run(args):
    command_line = (option_parser(
        usage="iotbx.lattice_symmetry [options] [centring_type_symbol]",
        description="Example: iotbx.lattice_symmetry" +
        " --unit_cell=12,12,12.1,89,90,92 F").enable_symmetry_comprehensive(
        ).option(None,
                 "--delta",
                 action="store",
                 type="float",
                 default=3.,
                 help="angular tolerance in degrees")).process(args=args,
                                                               max_nargs=1)
    # Pick up symmetry object
    input_symmetry = command_line.symmetry
    # Check that we have what we need
    if (input_symmetry.unit_cell() is None):
        print()
        print("***********************************")
        print("Please specify unit cell parameters")
        print("***********************************")
        print()
        command_line.parser.show_help()
        return
    if (len(command_line.args) > 0):
        input_symmetry = crystal.symmetry(unit_cell=input_symmetry.unit_cell(),
                                          space_group_symbol="Hall: %s 1" %
                                          command_line.args[0])
    elif (input_symmetry.space_group_info() is None):
        input_symmetry = crystal.symmetry(unit_cell=input_symmetry.unit_cell(),
                                          space_group_symbol="P 1")
    # Do it
    groups = metric_subgroups(input_symmetry,
                              command_line.options.delta,
                              enforce_max_delta_for_generated_two_folds=True)
    groups.show()
예제 #4
0
def run(args):
  command_line = (option_parser(
    usage="iotbx.lattice_symmetry [options] [centring_type_symbol]",
    description="Example: iotbx.lattice_symmetry"
               +" --unit_cell=12,12,12.1,89,90,92 F")
    .enable_symmetry_comprehensive()
    .option(None, "--delta",
      action="store",
      type="float",
      default=3.,
      help="angular tolerance in degrees")
  ).process(args=args, max_nargs=1)
  # Pick up symmetry object
  input_symmetry = command_line.symmetry
  # Check that we have what we need
  if (input_symmetry.unit_cell() is None):
    print
    print "***********************************"
    print "Please specify unit cell parameters"
    print "***********************************"
    print
    command_line.parser.show_help()
    return
  if (len(command_line.args) > 0):
    input_symmetry = crystal.symmetry(
      unit_cell=input_symmetry.unit_cell(),
      space_group_symbol="Hall: %s 1" % command_line.args[0])
  elif (input_symmetry.space_group_info() is None):
    input_symmetry = crystal.symmetry(
      unit_cell=input_symmetry.unit_cell(),
      space_group_symbol="P 1")
  # Do it
  groups = metric_subgroups(input_symmetry, command_line.options.delta,
    enforce_max_delta_for_generated_two_folds=True)
  groups.show()
예제 #5
0
    def get_metric_symmetry_subgroups(self):
        subgroup_list = lattice_symmetry.metric_subgroups(
            self.symmetry,
            3.0,
            bravais_types_only=False,
            best_monoclinic_beta=False).result_groups

        return subgroup_list
예제 #6
0
def test_combinations(setup_rlp):
    max_cell = 1.3 * max(
        setup_rlp["crystal_symmetry"].unit_cell().parameters()[:3])
    strategy = FFT1D(max_cell)
    basis_vectors, used = strategy.find_basis_vectors(setup_rlp["rlp"])

    target_symmetry_primitive = (
        setup_rlp["crystal_symmetry"].primitive_setting().customized_copy(
            space_group_info=sgtbx.space_group().info()))
    target_symmetry_sg_only = (
        setup_rlp["crystal_symmetry"].primitive_setting().customized_copy(
            unit_cell=None))
    target_symmetry_ref = setup_rlp["crystal_symmetry"].as_reference_setting()

    for target_symmetry in (
            setup_rlp["crystal_symmetry"],
            target_symmetry_primitive,
            target_symmetry_sg_only,
            target_symmetry_ref,
    ):

        crystal_models = combinations.candidate_orientation_matrices(
            basis_vectors, max_combinations=50)
        crystal_models = list(crystal_models)
        filtered_crystal_models = combinations.filter_known_symmetry(
            crystal_models, target_symmetry=target_symmetry)
        filtered_crystal_models = list(filtered_crystal_models)

        assert filtered_crystal_models
        for model in filtered_crystal_models:
            best_subgroup = find_matching_symmetry(
                model.get_unit_cell(), target_symmetry.space_group())
            if target_symmetry.unit_cell() is not None:
                assert best_subgroup["best_subsym"].unit_cell().is_similar_to(
                    setup_rlp["crystal_symmetry"].as_reference_setting().
                    best_cell().unit_cell(),
                    relative_length_tolerance=0.1,
                    absolute_angle_tolerance=5,
                ) or best_subgroup["best_subsym"].minimum_cell().unit_cell(
                ).is_similar_to(
                    setup_rlp["crystal_symmetry"].as_reference_setting().
                    best_cell().minimum_cell().unit_cell(),
                    relative_length_tolerance=0.1,
                    absolute_angle_tolerance=5,
                )
            else:
                target_sg = (target_symmetry.space_group_info().
                             reference_setting().group())
                from cctbx.sgtbx.lattice_symmetry import metric_subgroups

                subgroups = metric_subgroups(model.get_crystal_symmetry(),
                                             max_delta=5,
                                             bravais_types_only=False)
                if not target_sg.build_derived_patterson_group() in [
                        g["ref_subsym"].space_group()
                        for g in subgroups.result_groups
                ]:
                    assert 0
예제 #7
0
    def _setup_target_unit_cell_and_space_group(self, target_unit_cell,
                                                target_space_group):

        target_bravais_t = bravais_lattice(
            group=target_space_group.info().reference_setting().group())
        best_subgroup = None
        best_angular_difference = 1e8

        space_groups = [target_space_group]
        if target_space_group.conventional_centring_type_symbol() != "P":
            space_groups.append(sgtbx.space_group())
        for target in space_groups:
            cs = crystal.symmetry(
                unit_cell=target_unit_cell,
                space_group=target,
                assert_is_compatible_unit_cell=False,
            )
            target_best_cell = cs.best_cell().unit_cell()
            subgroups = lattice_symmetry.metric_subgroups(cs, max_delta=0.1)
            for subgroup in subgroups.result_groups:
                bravais_t = bravais_lattice(
                    group=subgroup["ref_subsym"].space_group())
                if bravais_t == target_bravais_t:
                    # allow for the cell to be given as best cell, reference setting
                    # primitive settings, or minimum cell
                    best_subsym = subgroup["best_subsym"]
                    ref_subsym = best_subsym.as_reference_setting()
                    if not (best_subsym.unit_cell().is_similar_to(
                            target_unit_cell) or ref_subsym.unit_cell(
                            ).is_similar_to(target_unit_cell)
                            or ref_subsym.primitive_setting().unit_cell(
                            ).is_similar_to(target_unit_cell)
                            or best_subsym.primitive_setting().unit_cell(
                            ).is_similar_to(target_unit_cell)
                            or best_subsym.minimum_cell().unit_cell(
                            ).is_similar_to(target_unit_cell.minimum_cell())
                            or best_subsym.unit_cell().is_similar_to(
                                target_best_cell)):
                        continue
                    if subgroup[
                            "max_angular_difference"] < best_angular_difference:
                        best_subgroup = subgroup
                        best_angular_difference = subgroup[
                            "max_angular_difference"]

        if best_subgroup is None:
            raise DialsIndexError("Unit cell incompatible with space group")

        cb_op_inp_best = best_subgroup["cb_op_inp_best"]
        best_subsym = best_subgroup["best_subsym"]
        cb_op_best_ref = best_subsym.change_of_basis_op_to_reference_setting()
        self.cb_op_inp_ref = cb_op_best_ref * cb_op_inp_best
        self.target_symmetry_reference_setting = crystal.symmetry(
            unit_cell=target_unit_cell.change_basis(self.cb_op_inp_ref),
            space_group=target_space_group.info().as_reference_setting().group(
            ),
        )
예제 #8
0
def test_score_symmetry_element_subgroup(space_group):
    sgi = sgtbx.space_group_info(symbol=space_group)
    cs = sgi.any_compatible_crystal_symmetry(volume=10000)
    cs = cs.best_cell()
    cs = cs.minimum_cell()
    intensities = (
        generate_intensities(cs, d_min=1.0)
        .generate_bijvoet_mates()
        .set_observation_type_xray_intensity()
    )
    intensities = intensities.expand_to_p1()

    subgroups = metric_subgroups(
        intensities.crystal_symmetry(), max_delta=2.0, bravais_types_only=False
    )
    intensities = intensities.change_basis(subgroups.cb_op_inp_minimum)
    cs = cs.change_basis(subgroups.cb_op_inp_minimum)

    cb_op_inp_best = subgroups.result_groups[0]["cb_op_inp_best"]
    lattice_group = subgroups.result_groups[0]["best_subsym"].space_group()
    lattice_group = lattice_group.change_basis(cb_op_inp_best.inverse())

    lattice_group = subgroups.result_groups[0]["subsym"].space_group()

    sym_op_scores = []
    for sym_op in lattice_group.smx():
        if sym_op.r().info().sense() < 0:
            continue
        score = ScoreSymmetryElement(intensities, sym_op, 1.0, 1.0)
        sym_op_scores.append(score)
        if sym_op in cs.space_group():
            assert score.likelihood > 0.9
            assert score.cc.coefficient() > 0.9
        else:
            assert score.likelihood < 0.2
            assert score.cc.coefficient() < 0.3

    subgroup_scores = [
        ScoreSubGroup(subgrp, sym_op_scores) for subgrp in subgroups.result_groups
    ]
    total_likelihood = sum(score.likelihood for score in subgroup_scores)
    for score in subgroup_scores:
        score.likelihood /= total_likelihood
    true_patterson_group = (
        cs.space_group_info()
        .as_reference_setting()
        .group()
        .build_derived_patterson_group()
    )
    for score in subgroup_scores:
        if score.subgroup["best_subsym"].space_group() == true_patterson_group:
            assert score.likelihood > 0.8
        else:
            assert score.likelihood < 0.1
예제 #9
0
  def __init__(self,input_index_engine,input_dictionary,horizon_phil,
    opt_rawframes=None,opt_target=False,reduce_target=True):

    from libtbx import adopt_init_args
    adopt_init_args(self,locals())

    if self.horizon_phil.target_cell!=None:

      # change target to primitive centering type
      from cctbx import crystal
      input_symmetry = crystal.symmetry(
        unit_cell=self.horizon_phil.target_cell,
        space_group_symbol="Hall: %s 1" % self.horizon_phil.target_cell_centring_type)
      from cctbx.sgtbx.lattice_symmetry import metric_subgroups
      groups = metric_subgroups(input_symmetry, 0.0,
        enforce_max_delta_for_generated_two_folds=True)
      #groups.show()
      primitive_target_cell = groups.result_groups[-1]["best_subsym"].unit_cell()

      from rstbx.indexing_api.force_cell import force_cell
      best = force_cell(self.input_index_engine,primitive_target_cell)
      try:
        #print "Best score %.1f, triangle %12s"%(best["score"],str(best["triangle"])),best["orientation"].unit_cell()
        self.input_index_engine.setOrientation(best["orientation"])
      except Exception:
        raise Sorry("""Cannot index with the target_cell.  It is possible the target cell is wrong; try indexing
       without one.  It may be necessary to change the beam position, distance, or two theta angle on the
       command line.  See the http://cci.lbl.gov/labelit usage primer.""")
      # originally implemented with default conversion to niggli cell (reduce_target=True).
      # Added this as a configurable option in the context of indexing for sparse
      # nanocrystal stills, since we want to restrain to the originally-input target
      # setting, not necessarily the reduced cell:
      if reduce_target: self.input_index_engine.niggli()
      return

    #initial search
    all_sol = select_best_combo_of(input_index_engine,
                                      better_than=0.36,
                                      candidates=25,
                                      opt_inputs=(self.input_dictionary,opt_rawframes))

    best_combo = all_sol.best_combo()
    if best_combo!=None:
      self.evaluate_combo(best_combo)
      # XXX revisit the question of codecamp maxcell and whether this test should be functional
      #if self.horizon_phil.codecamp.maxcell != None: return
      if opt_rawframes == None or best_combo['lattice_likelihood'] > 3.0:
        return # quick abort to test out indexing 10/16/13

    raise Exception("""No autoindexing solution.
           Possible: incorrect beam center; multiple lattices; too few spots.""")
예제 #10
0
  def __init__(self,input_index_engine,input_dictionary,horizon_phil,
    opt_rawframes=None,opt_target=False,reduce_target=True):

    from libtbx import adopt_init_args
    adopt_init_args(self,locals())

    if self.horizon_phil.target_cell!=None:

      # change target to primitive centering type
      from cctbx import crystal
      input_symmetry = crystal.symmetry(
        unit_cell=self.horizon_phil.target_cell,
        space_group_symbol="Hall: %s 1" % self.horizon_phil.target_cell_centring_type)
      from cctbx.sgtbx.lattice_symmetry import metric_subgroups
      groups = metric_subgroups(input_symmetry, 0.0,
        enforce_max_delta_for_generated_two_folds=True)
      #groups.show()
      primitive_target_cell = groups.result_groups[-1]["best_subsym"].unit_cell()

      from rstbx.indexing_api.force_cell import force_cell
      best = force_cell(self.input_index_engine,primitive_target_cell)
      try:
        #print "Best score %.1f, triangle %12s"%(best["score"],str(best["triangle"])),best["orientation"].unit_cell()
        self.input_index_engine.setOrientation(best["orientation"])
      except Exception:
        raise Sorry("""Cannot index with the target_cell.  It is possible the target cell is wrong; try indexing
       without one.  It may be necessary to change the beam position, distance, or two theta angle on the
       command line.  See the http://cci.lbl.gov/labelit usage primer.""")
      # originally implemented with default conversion to niggli cell (reduce_target=True).
      # Added this as a configurable option in the context of indexing for sparse
      # nanocrystal stills, since we want to restrain to the originally-input target
      # setting, not necessarily the reduced cell:
      if reduce_target: self.input_index_engine.niggli()
      return

    #initial search
    all_sol = select_best_combo_of(input_index_engine,
                                      better_than=0.36,
                                      candidates=25,
                                      opt_inputs=(self.input_dictionary,opt_rawframes))

    best_combo = all_sol.best_combo()
    if best_combo!=None:
      self.evaluate_combo(best_combo)
      # XXX revisit the question of codecamp maxcell and whether this test should be functional
      #if self.horizon_phil.codecamp.maxcell != None: return
      if opt_rawframes == None or best_combo['lattice_likelihood'] > 3.0:
        return # quick abort to test out indexing 10/16/13

    raise Exception("""No autoindexing solution.
           Possible: incorrect beam center; multiple lattices; too few spots.""")
예제 #11
0
  def __init__(self, intensities,
               normalisation='ml_aniso',
               lattice_symmetry_max_delta=2.0,
               d_min=libtbx.Auto,
               min_i_mean_over_sigma_mean=4,
               min_cc_half=0.6):

    self.intensities = intensities
    self.input_intensities = intensities.deep_copy()
    self.lattice_symmetry_max_delta = lattice_symmetry_max_delta

    self.cb_op_inp_min = self.intensities.change_of_basis_op_to_niggli_cell()
    self.intensities = self.intensities.change_basis(
      self.cb_op_inp_min).customized_copy(
        space_group_info=sgtbx.space_group_info('P1')).map_to_asu().set_info(
          self.intensities.info())

    self.subgroups = metric_subgroups(
      self.intensities.crystal_symmetry(),
      max_delta=self.lattice_symmetry_max_delta,
      bravais_types_only=False)
    self.cb_op_min_best = self.subgroups.result_groups[0]['cb_op_inp_best']
    self.lattice_group = self.subgroups.result_groups[0]['best_subsym'].space_group()
    self.lattice_group = self.lattice_group.change_basis(self.cb_op_min_best.inverse())

    self.patterson_group = self.lattice_group.build_derived_patterson_group()
    sel = self.patterson_group.epsilon(self.intensities.indices()) == 1
    self.intensities = self.intensities.select(sel).set_info(
      self.intensities.info())

    if d_min is not None or d_min is libtbx.Auto:
      self.resolution_filter(d_min, min_i_mean_over_sigma_mean, min_cc_half)

    # Correct SDs by "typical" SD factors
    self.correct_sigmas(sd_fac=2.0, sd_b=0.0, sd_add=0.03)

    if normalisation == 'kernel':
      self.kernel_normalisation()
    elif normalisation == 'quasi':
      self.quasi_normalisation()
    elif normalisation == 'ml_iso':
      self.ml_normalisation(aniso=False)
    elif normalisation == 'ml_aniso':
      self.ml_normalisation(aniso=True)

    self.estimate_cc_sig_fac()
    self.estimate_cc_true()
    self.score_symmetry_elements()
    self.score_laue_groups()
    self.show()
예제 #12
0
    def run(self, iterable):

        # with Capturing() as junk_output:
        errors = []
        try:
            ucs = Cluster.from_iterable(iterable=iterable)
            clusters, _ = ucs.ab_cluster(5000,
                                         log=False,
                                         write_file_lists=False,
                                         schnell=True,
                                         doplot=False)
        except Exception as e:
            print("IOTA ERROR (CLUSTERING): ", e)
            clusters = []
            errors.append(str(e))

        info = []
        if clusters:
            for cluster in clusters:
                uc_init = unit_cell(cluster.medians)
                symmetry = crystal.symmetry(unit_cell=uc_init,
                                            space_group_symbol="P1")
                groups = lattice_symmetry.metric_subgroups(
                    input_symmetry=symmetry, max_delta=3)
                top_group = groups.result_groups[0]
                best_sg = str(groups.lattice_group_info()).split("(")[0]
                best_uc = top_group["best_subsym"].unit_cell().parameters()
                uc_no_stdev = ("{:<6.2f} {:<6.2f} {:<6.2f} "
                               "{:<6.2f} {:<6.2f} {:<6.2f} "
                               "".format(
                                   best_uc[0],
                                   best_uc[1],
                                   best_uc[2],
                                   best_uc[3],
                                   best_uc[4],
                                   best_uc[5],
                               ))
                cluster_info = {
                    "number": len(cluster.members),
                    "pg": str(best_sg),
                    "uc": uc_no_stdev,
                }
                info.append(cluster_info)

        return info, errors
예제 #13
0
def generate_lattice_options(unit_cell, space_group_name):
    cs = crystal.symmetry(
        unit_cell = unit_cell,
        space_group_symbol = space_group_name)

    original_reindex = cs.change_of_basis_op_to_minimum_cell()

    groups = metric_subgroups(input_symmetry = cs, max_delta = 0.0)

    result = []

    for item in groups.result_groups:

        cs = item['ref_subsym']

        convert_to_best_cell = True

        if convert_to_best_cell:
            cb = cs.change_of_basis_op_to_best_cell(
                best_monoclinic_beta = False)
            cs_best = cs.change_basis(cb)

            o_unit_cell = cs_best.unit_cell().parameters()
            sg = cs_best.space_group().build_derived_acentric_group()

            o_space_group_name = sg.type().universal_hermann_mauguin_symbol()
            reindex = (cb * item['subsym'].space_group_info().type().cb_op(
                ) * original_reindex).c().r().as_double()

            result.append((o_space_group_name, o_unit_cell, reindex))

        else:

            o_unit_cell = cs.unit_cell().parameters()
            sg = cs.space_group().build_derived_acentric_group()

            o_space_group_name = sg.type().universal_hermann_mauguin_symbol()
            reindex = (item['subsym'].space_group_info().type().cb_op(
                ) * original_reindex).c().r().as_double()

            result.append((o_space_group_name, o_unit_cell, reindex))

    return result
예제 #14
0
    def run(self, iterable):

        with Capturing() as junk_output:
            try:
                ucs = Cluster.from_iterable(iterable=iterable)
                clusters, _ = ucs.ab_cluster(5000,
                                             log=False,
                                             write_file_lists=False,
                                             schnell=True,
                                             doplot=False)
            except Exception:
                clusters = []

        if len(clusters) > 0:
            info = []
            for cluster in clusters:
                uc_init = unit_cell(cluster.medians)
                symmetry = crystal.symmetry(unit_cell=uc_init,
                                            space_group_symbol='P1')
                groups = lattice_symmetry.metric_subgroups(
                    input_symmetry=symmetry, max_delta=3)
                top_group = groups.result_groups[0]
                best_uc = top_group['best_subsym'].unit_cell().parameters()
                best_sg = top_group['best_subsym'].space_group_info()

                uc_no_stdev = "{:<6.2f} {:<6.2f} {:<6.2f} " \
                              "{:<6.2f} {:<6.2f} {:<6.2f} " \
                              "".format(best_uc[0], best_uc[1], best_uc[2],
                                        best_uc[3], best_uc[4], best_uc[5])
                cluster_info = {
                    'number': len(cluster.members),
                    'pg': str(best_sg),
                    'uc': uc_no_stdev
                }

                info.append(cluster_info)

        else:
            info = None

        return info
예제 #15
0
def counterexamples():

    for example in [
            # Stated example known to be hR, Table lookup gives mC
        (143.11386252141878, 143.60212158695211, 191.65636462983394,
         90.01331794194698, 111.85072371897915, 119.88503851099796),

            # Stated examples known to be oC, Table lookup gives mP
            # ...but applying sign correction produces oC.
        (121.48, 122.45, 144.06, 89.94, 65.09, 89.99),
        (121.39, 122.16, 143.98, 89.94, 65.24, 89.97),

            # Stated examples known to be hP, Table lookup gives oC
            # ...but applying sign correction produces hP
        (81.003144781582421, 81.130355147032134, 169.50959209067071,
         89.896542797449115, 89.999041351249176, 60.10397864241261),
        (81.88, 81.92, 170.38, 89.95, 89.98, 60.04),
        (81.84, 81.85, 169.28, 89.94, 89.97, 60.02),
        (149.74, 149.89, 154.90, 89.96, 89.77, 60.10),

            # Stated example known to be tP, Table lookup gives oP
        (64.5259, 65.5211, 140.646, 90.0599, 90.0254, 90.0023),

            # Stated example known to be tI, Table lookup gives oI
        (100.66, 100.78, 101.00, 116.96, 95.54, 116.63),
    ]:

        uc = unit_cell(example)
        assert uc.is_niggli_cell()
        print "Input Niggli cell:", uc
        print "BZW Table lookup:"
        LatticeCharacter(uc, 3.0).show_summary()

        input_symmetry = crystal.symmetry(unit_cell=uc,
                                          space_group_symbol="P 1")
        Groups = metric_subgroups(input_symmetry, 3.0)
        Groups.show()
        print
        print
예제 #16
0
    def run_once(crystal_symmetry):
        cs = crystal_symmetry
        #print
        cs.show_summary()

        from cctbx.sgtbx import lattice_symmetry
        subgroups = lattice_symmetry.metric_subgroups(cs, max_delta=5)

        for op in ('x,y,z', 'z,x,y', 'y,z,x', '-x,z,y', 'y,x,-z', 'z,-y,x')[:]:
            cb_op = sgtbx.change_of_basis_op(op)

            uc_inp = cs.unit_cell().change_basis(cb_op)

            for ref_uc, ref_sg in [(cs.unit_cell(), cs.space_group()),
                                   (None, cs.space_group())][:]:

                best_subgroup = symmetry.find_matching_symmetry(
                    uc_inp, target_space_group=ref_sg)
                cb_op_inp_best = best_subgroup['cb_op_inp_best']

                assert uc_inp.change_basis(cb_op_inp_best).is_similar_to(
                    cs.as_reference_setting().best_cell().unit_cell())
예제 #17
0
def test_reindex_experiments():
    # See also https://github.com/cctbx/cctbx_project/issues/424
    cs = sgtbx.space_group_info("I23").any_compatible_crystal_symmetry(
        volume=100000)
    B = scitbx.matrix.sqr(
        cs.unit_cell().fractionalization_matrix()).transpose()
    cryst = Crystal(B, cs.space_group())
    n_scan_points = 10
    A_at_scan_points = [(1, 0, 0, 0, 1, 0, 0, 0, 1)] * n_scan_points
    cryst.set_A_at_scan_points(A_at_scan_points)
    groups = metric_subgroups(cs, max_delta=5)
    for group in groups.result_groups:
        best_subsym = group["best_subsym"]
        cb_op = group["cb_op_inp_best"]
        expts = ExperimentList([Experiment(crystal=cryst)])
        reindexed_expts = reindex_experiments(
            experiments=expts,
            cb_op=cb_op,
            space_group=best_subsym.space_group())
        assert (reindexed_expts[0].crystal.get_crystal_symmetry().
                is_similar_symmetry(best_subsym))
        # Check that the scan-varying A matrices have been copied as well
        assert cryst.num_scan_points == n_scan_points
예제 #18
0
  def run_once(crystal_symmetry):
    cs = crystal_symmetry
    #print
    cs.show_summary()

    from cctbx.sgtbx import lattice_symmetry
    subgroups = lattice_symmetry.metric_subgroups(cs, max_delta=5)

    for op in ('x,y,z', 'z,x,y', 'y,z,x', '-x,z,y', 'y,x,-z', 'z,-y,x')[:]:
      cb_op = sgtbx.change_of_basis_op(op)

      uc_inp = cs.unit_cell().change_basis(cb_op)

      for ref_uc, ref_sg in [(cs.unit_cell(), cs.space_group()),
                             (None, cs.space_group())][:]:

        best_subgroup = symmetry.find_matching_symmetry(
          uc_inp,
          target_space_group=ref_sg)
        cb_op_inp_best = best_subgroup['cb_op_inp_best']

        assert uc_inp.change_basis(cb_op_inp_best).is_similar_to(
          cs.as_reference_setting().best_cell().unit_cell())
def counterexamples():

  for example in [
    # Stated example known to be hR, Table lookup gives mC
    (143.11386252141878, 143.60212158695211, 191.65636462983394,
     90.01331794194698, 111.85072371897915, 119.88503851099796),

    # Stated examples known to be oC, Table lookup gives mP
    # ...but applying sign correction produces oC.
    (121.48, 122.45, 144.06,  89.94,  65.09,  89.99),
    (121.39, 122.16, 143.98,  89.94,  65.24,  89.97),

    # Stated examples known to be hP, Table lookup gives oC
    # ...but applying sign correction produces hP
    (81.003144781582421, 81.130355147032134, 169.50959209067071,
     89.896542797449115, 89.999041351249176, 60.10397864241261),
    (81.88,  81.92, 170.38,  89.95,  89.98,  60.04),
    (81.84,  81.85, 169.28,  89.94,  89.97,  60.02),
    (149.74, 149.89, 154.90, 89.96,  89.77,  60.10),

    # Stated example known to be tP, Table lookup gives oP
    (64.5259, 65.5211, 140.646,  90.0599,  90.0254,  90.0023),

    # Stated example known to be tI, Table lookup gives oI
    (100.66, 100.78, 101.00, 116.96,  95.54, 116.63), ]:

    uc = unit_cell(example)
    assert uc.is_niggli_cell()
    print "Input Niggli cell:",uc
    print "BZW Table lookup:"
    LatticeCharacter(uc,3.0).show_summary()

    input_symmetry = crystal.symmetry(
      unit_cell=uc,space_group_symbol="P 1")
    Groups = metric_subgroups(input_symmetry, 3.0)
    Groups.show()
    print;print
예제 #20
0
print "Best cell -> niggli cell"
cs.best_cell().niggli_cell().show_summary()
print "Reference setting -> minimum cell"
cs.as_reference_setting().minimum_cell().show_summary()
print "Reference setting -> niggli cell"
cs.as_reference_setting().niggli_cell().show_summary()
print

print "Reference settings (via minimum/niggli cell):"
print "Input -> minimum cell -> reference setting"
cs.minimum_cell().as_reference_setting().show_summary()
print "Input -> niggli cell -> reference setting"
cs.niggli_cell().as_reference_setting().show_summary()
print "Best cell -> minimum cell -> reference setting"
cs.best_cell().minimum_cell().as_reference_setting().show_summary()
print "Best cell -> niggli cell -> reference setting"
cs.best_cell().niggli_cell().as_reference_setting().show_summary()
print "Reference setting -> minimum cell -> reference setting"
cs.as_reference_setting().minimum_cell().as_reference_setting().show_summary()
print "Reference setting -> niggli cell -> reference setting"
cs.as_reference_setting().niggli_cell().as_reference_setting().show_summary()
print

subgroups = lattice_symmetry.metric_subgroups(cs, max_delta=0.1)
for subgroup in subgroups.result_groups:
  bravais_t = bravais_lattice(
    group=subgroup['ref_subsym'].space_group())
  if bravais_t == 'mC':
    print subgroup['ref_subsym'].unit_cell()
    print subgroup['best_subsym'].as_reference_setting().unit_cell()
예제 #21
0
    def __init__(
        self,
        intensities,
        normalisation="ml_aniso",
        lattice_symmetry_max_delta=2.0,
        d_min=libtbx.Auto,
        min_i_mean_over_sigma_mean=4,
        min_cc_half=0.6,
        relative_length_tolerance=None,
        absolute_angle_tolerance=None,
    ):
        """Initialise a symmetry_base object.

        Args:
          intensities (cctbx.miller.array): The intensities on which to perform
            symmetry anaylsis.
          normalisation (str): The normalisation method to use. Possible choices are
            'kernel', 'quasi', 'ml_iso' and 'ml_aniso'. Set to None to switch off
            normalisation altogether.
          lattice_symmetry_max_delta (float): The maximum value of delta for
            determining the lattice symmetry using the algorithm of Le Page (1982).
          d_min (float): Optional resolution cutoff to be applied to the input
            intensities. If set to :data:`libtbx.Auto` then d_min will be
            automatically determined according to the parameters
            ``min_i_mean_over_sigma_mean`` and ``min_cc_half``.
          min_i_mean_over_sigma_mean (float): minimum value of |I|/|sigma(I)| for
            automatic determination of resolution cutoff.
          min_cc_half (float): minimum value of CC1/2 for automatic determination of
            resolution cutoff.
          relative_length_tolerance (float): Relative length tolerance in checking
            consistency of input unit cells against the median unit cell.
          absolute_angle_tolerance (float): Absolute angle tolerance in checking
            consistency of input unit cells against the median unit cell.
        """
        self.input_intensities = intensities

        uc_params = [flex.double() for i in range(6)]
        for d in self.input_intensities:
            for i, p in enumerate(d.unit_cell().parameters()):
                uc_params[i].append(p)
        self.median_unit_cell = uctbx.unit_cell(
            parameters=[flex.median(p) for p in uc_params])
        self._check_unit_cell_consistency(relative_length_tolerance,
                                          absolute_angle_tolerance)

        self.intensities = self.input_intensities[0]
        self.dataset_ids = flex.double(self.intensities.size(), 0)
        for i, d in enumerate(self.input_intensities[1:]):
            self.intensities = self.intensities.concatenate(
                d, assert_is_similar_symmetry=False)
            self.dataset_ids.extend(flex.double(d.size(), i + 1))
        self.intensities = self.intensities.customized_copy(
            unit_cell=self.median_unit_cell)
        self.intensities.set_observation_type_xray_intensity()
        sys_absent_flags = self.intensities.sys_absent_flags(
            integral_only=True).data()
        self.intensities = self.intensities.select(~sys_absent_flags)
        self.dataset_ids = self.dataset_ids.select(~sys_absent_flags)

        self.lattice_symmetry_max_delta = lattice_symmetry_max_delta
        self.subgroups = metric_subgroups(
            self.intensities.crystal_symmetry(),
            max_delta=self.lattice_symmetry_max_delta,
            bravais_types_only=False,
        )

        self.cb_op_inp_min = self.subgroups.cb_op_inp_minimum
        self.intensities = (self.intensities.change_basis(
            self.cb_op_inp_min).customized_copy(
                space_group_info=sgtbx.space_group_info(
                    "P1")).map_to_asu().set_info(self.intensities.info()))

        self.lattice_group = (self.subgroups.result_groups[0]
                              ["subsym"].space_group().make_tidy())
        self.patterson_group = (
            self.lattice_group.build_derived_patterson_group().make_tidy())
        logger.info("Patterson group: %s" % self.patterson_group.info())

        sel = self.patterson_group.epsilon(self.intensities.indices()) == 1
        self.intensities = self.intensities.select(sel)
        self.dataset_ids = self.dataset_ids.select(sel)

        # Correct SDs by "typical" SD factors
        self._correct_sigmas(sd_fac=2.0, sd_b=0.0, sd_add=0.03)
        self._normalise(normalisation)
        self._resolution_filter(d_min, min_i_mean_over_sigma_mean, min_cc_half)
예제 #22
0
def change_of_basis_ops_to_minimum_cell(experiments, max_delta,
                                        relative_length_tolerance,
                                        absolute_angle_tolerance):
    """
    Compute change of basis ops to map experiments to the minimum cell

    Map to the minimum cell via the best cell, which appears to guarantee that the
    resulting minimum cells are consistent.

    Args:
        experiments (ExperimentList): a list of experiments.
        reflections (list): a list of reflection tables

    Returns: The experiments and reflections mapped to the minimum cell
    """

    median_cell = median_unit_cell(experiments)
    unit_cells_are_similar = unit_cells_are_similar_to(
        experiments, median_cell, relative_length_tolerance,
        absolute_angle_tolerance)
    centring_symbols = [
        bravais_lattice(group=expt.crystal.get_space_group()).centring_symbol
        for expt in experiments
    ]
    if unit_cells_are_similar and len(set(centring_symbols)) == 1:
        groups = metric_subgroups(
            experiments[0].crystal.get_crystal_symmetry().customized_copy(
                unit_cell=median_cell),
            max_delta,
            enforce_max_delta_for_generated_two_folds=True,
        )
        group = groups.result_groups[0]
        cb_op_best_to_min = group[
            "best_subsym"].change_of_basis_op_to_minimum_cell()
        cb_ops = [cb_op_best_to_min * group["cb_op_inp_best"]
                  ] * len(experiments)
    else:
        groups = [
            metric_subgroups(
                expt.crystal.get_crystal_symmetry(),
                max_delta,
                best_monoclinic_beta=False,
                enforce_max_delta_for_generated_two_folds=True,
            ) for expt in experiments
        ]
        counter = collections.Counter(
            g.result_groups[0]["best_subsym"].space_group() for g in groups)
        target_group = counter.most_common()[0][0]
        cb_ops = []
        for expt in experiments:
            groups = metric_subgroups(
                expt.crystal.get_crystal_symmetry(),
                max_delta,
                best_monoclinic_beta=False,
                enforce_max_delta_for_generated_two_folds=True,
            )
            group = None
            for g in groups.result_groups:
                if g["best_subsym"].space_group() == target_group:
                    group = g
            if group:
                cb_ops.append(group["cb_op_inp_best"])
            else:
                cb_ops.append(None)
                logger.info(f"Couldn't match unit cell to target symmetry:\n"
                            f"{expt.crystal.get_crystal_symmetry()}\n"
                            f"{target_group}")
        ref_expts = ExperimentList([
            expt for expt, cb_op in zip(experiments, cb_ops) if cb_op
        ]).change_basis(list(filter(None, cb_ops)))
        cb_op_ref_min = (
            ref_expts[0].crystal.get_crystal_symmetry().customized_copy(
                unit_cell=median_unit_cell(
                    ref_expts)).change_of_basis_op_to_minimum_cell())
        cb_ops = [cb_op_ref_min * cb_op if cb_op else None for cb_op in cb_ops]
    return cb_ops
예제 #23
0
def unit_cell_info(sub_clusters):
    """
  Print unit cell information for a list of clusters.

  :param sub_clusters: a list of cluster objects
  :return: a string containing median unit cells, standard deviations and
   point group composition of each cluster.
  """
    from libtbx.utils import plural_s
    # 3. print out some information that is useful.
    out_str = "\n\n{:<16} {:<8} {:<13} {:<13} {:<13} {:<12} {:<12} {:<12}{:<8}\n".format(
        "Cluster_id", "N_xtals", "Med_a", "Med_b", "Med_c", "Med_alpha",
        "Med_beta", "Med_gamma", "Delta(deg)")
    singletons = []
    for cluster in sub_clusters:
        if len(cluster.members) != 1:
            # New approach, takes niggli setting of the cluster median and converts
            # back to reference setting for cluster report. Fixes cctbx#97.
            from cctbx import crystal
            from cctbx.uctbx import unit_cell
            from cctbx.sgtbx.lattice_symmetry import metric_subgroups

            input_symmetry = crystal.symmetry(unit_cell=unit_cell(
                cluster.medians[0:6]),
                                              space_group_symbol="P 1")
            groups = metric_subgroups(
                input_symmetry,
                3.00,
                enforce_max_delta_for_generated_two_folds=True)
            group = groups.result_groups[0]
            # suppress stdout output for now
            from StringIO import StringIO
            SS = StringIO()
            import sys
            sys.stdout = SS
            group['best_subsym'].space_group_info().show_summary()
            sys.stdout = sys.__stdout__
            print "                       Unit cell:", group[
                'best_subsym'].unit_cell()
            uc_params_conv = group['best_subsym'].unit_cell().parameters()

            sorted_pg_comp = sorted(cluster.pg_composition.items(),
                                    key=lambda x: -1 * x[1])
            pg_strings = [
                "{} in {}".format(pg[1], pg[0]) for pg in sorted_pg_comp
            ]
            point_group_string = ", ".join(pg_strings) + "."
            out_str += point_group_string
            out_str += ("\n{:<16} {:<8} {:<6.2f}({:<5.2f}) {:<6.2f}({:<5.2f})"
                        " {:<6.2f}({:<5.2f}) {:<6.2f}({:<4.2f}) {:<6.2f}"
                        "({:<4.2f}) {:<6.2f}({:<4.2f})").format(
                            cluster.cname, len(cluster.members),
                            cluster.medians[0], cluster.stdevs[0],
                            cluster.medians[1], cluster.stdevs[1],
                            cluster.medians[2], cluster.stdevs[2],
                            cluster.medians[3], cluster.stdevs[3],
                            cluster.medians[4], cluster.stdevs[4],
                            cluster.medians[5], cluster.stdevs[5])
            out_str += ("\n{:>24}  {:<6.2f}{:<7} {:<6.2f}{:<7}"
                        " {:<6.2f}{:<7} {:<6.2f}{:<6} {:<6.2f}"
                        "{:<6} {:<6.2f}{:<6}  {:<6.2}").format(
                            SS.getvalue().strip()[13:], uc_params_conv[0], "",
                            uc_params_conv[1], "", uc_params_conv[2], "",
                            uc_params_conv[3], "", uc_params_conv[4], "",
                            uc_params_conv[5], "",
                            group["max_angular_difference"]) + "\n\n"

        else:
            singletons.append("".join([
                ("{:<14} {:<11.2f} {:<11.2f} {:<11.2f}"
                 "{:<12.1f} {:<12.1f} {:<12.1f}").format(
                     cluster.pg_composition.keys()[0],
                     cluster.members[0].uc[0], cluster.members[0].uc[1],
                     cluster.members[0].uc[2], cluster.members[0].uc[3],
                     cluster.members[0].uc[4], cluster.members[0].uc[5]), '\n'
            ]))
    out_str += "\nStandard deviations are in brackets."
    explanation = """\nEach cluster:
Input lattice count, with integration Bravais setting space group.
Cluster median with Niggli cell parameters (std dev in brackets).
Highest possible metric symmetry and unit cell using LePage (J Appl Cryst 1982, 15:255) method, maximum delta 3deg."""
    out_str += explanation
    singleton_str = "\n%i singleton%s:" % plural_s(len(singletons))
    singleton_str += "\n\n{:<14} {:<11} {:<11} {:<11}{:<12} {:<12} {:<12}\n".format(
        "Point group", "a", "b", "c", "alpha", "beta", "gamma")
    singleton_str += "".join(singletons)
    n_clusters = len(sub_clusters) - len(singletons)
    out_str = "\n%i cluster%s:" % plural_s(n_clusters) + out_str
    return singleton_str + out_str
예제 #24
0
class TrackerWindow(wx.Frame):
  def __init__(self, parent, id, title):
    wx.Frame.__init__(self, parent, id, title, size=(1500, 600))
    self.parent = parent
    self.term_file = os.path.join(os.curdir, '.terminate_image_tracker')
    self.spf_backend = 'mosflm'
    self.run_indexing = False
    self.run_integration = False

    self.reset_spotfinder()

    # Status bar
    self.sb = self.CreateStatusBar()
    self.sb.SetFieldsCount(2)
    self.sb.SetStatusWidths([100, -1])

    # Setup main sizer
    self.main_sizer = wx.BoxSizer(wx.VERTICAL)

    # Setup toolbar
    self.toolbar = self.CreateToolBar(style=wx.TB_3DBUTTONS | wx.TB_TEXT)
    quit_bmp = bitmaps.fetch_icon_bitmap('actions', 'exit')
    self.tb_btn_quit = self.toolbar.AddLabelTool(wx.ID_EXIT, label='Quit',
                                                 bitmap=quit_bmp,
                                                 shortHelp='Quit',
                                                 longHelp='Quit image tracker')
    self.toolbar.AddSeparator()
    # pref_bmp = bitmaps.fetch_icon_bitmap('apps', 'advancedsettings')
    # self.tb_btn_prefs = self.toolbar.AddLabelTool(wx.ID_ANY,
    #                                               label='Preferences',
    #                                               bitmap=pref_bmp,
    #                                               shortHelp='Preferences',
    #                                               longHelp='IOTA image tracker preferences')
    # self.toolbar.AddSeparator()
    open_bmp = bitmaps.fetch_icon_bitmap('actions', 'open')
    self.tb_btn_open = self.toolbar.AddLabelTool(wx.ID_ANY, label='Open',
                                                bitmap=open_bmp,
                                                shortHelp='Open',
                                                longHelp='Open folder')
    run_bmp = bitmaps.fetch_icon_bitmap('actions', 'run')
    self.tb_btn_run = self.toolbar.AddLabelTool(wx.ID_ANY, label='Run',
                                                bitmap=run_bmp,
                                                shortHelp='Run',
                                                longHelp='Run Spotfinding')
    stop_bmp = bitmaps.fetch_icon_bitmap('actions', 'stop')
    self.tb_btn_stop = self.toolbar.AddLabelTool(wx.ID_ANY, label='Stop',
                                                bitmap=stop_bmp,
                                                shortHelp='Stop',
                                                longHelp='Stop Spotfinding')
    self.toolbar.AddSeparator()
    span_view = bitmaps.fetch_custom_icon_bitmap('zoom_list')
    self.tb_btn_view = self.toolbar.AddLabelTool(wx.ID_ANY, label='View',
                                                 bitmap=span_view,
                                                 kind=wx.ITEM_RADIO,
                                                 shortHelp='Select to View',
                                                 longHelp='Select images to view')
    span_zoom = bitmaps.fetch_custom_icon_bitmap('zoom_view')
    self.tb_btn_zoom = self.toolbar.AddLabelTool(wx.ID_ANY, label='Zoom In',
                                                 bitmap=span_zoom,
                                                 kind=wx.ITEM_RADIO,
                                                 shortHelp='Zoom In',
                                                 longHelp='Zoom in on chart')
    self.toolbar.ToggleTool(self.tb_btn_zoom.GetId(), True)
    self.toolbar.EnableTool(self.tb_btn_run.GetId(), False)
    self.toolbar.EnableTool(self.tb_btn_stop.GetId(), False)
    self.toolbar.Realize()

    # Setup timers
    self.spf_timer = wx.Timer(self)
    self.uc_timer = wx.Timer(self)
    self.ff_timer = wx.Timer(self)

    self.tracker_panel = TrackerPanel(self)
    self.data_dict = self.tracker_panel.image_list.image_list.ctr.data.copy()
    self.img_list_initialized = False

    self.main_sizer.Add(self.tracker_panel, 1, wx.EXPAND)

    # Bindings
    self.Bind(wx.EVT_TOOL, self.onQuit, self.tb_btn_quit)
    self.Bind(wx.EVT_TOOL, self.onGetImages, self.tb_btn_open)
    self.Bind(wx.EVT_TOOL, self.onRunSpotfinding, self.tb_btn_run)
    self.Bind(wx.EVT_TOOL, self.onStop, self.tb_btn_stop)
    self.Bind(wx.EVT_BUTTON, self.onSelView, self.tracker_panel.btn_view_sel)
    self.Bind(wx.EVT_BUTTON, self.onWrtFile, self.tracker_panel.btn_wrt_file)
    self.Bind(wx.EVT_BUTTON, self.onAllView, self.tracker_panel.btn_view_all)
    self.Bind(wx.EVT_TOOL, self.onZoom, self.tb_btn_zoom)
    self.Bind(wx.EVT_TOOL, self.onList, self.tb_btn_view)

    # Spotfinder / timer bindings
    self.Bind(thr.EVT_SPFDONE, self.onSpfOneDone)
    self.Bind(thr.EVT_SPFALLDONE, self.onSpfAllDone)
    self.Bind(thr.EVT_SPFTERM, self.onSpfTerminated)
    self.Bind(wx.EVT_TIMER, self.onSpfTimer, id=self.spf_timer.GetId())
    self.Bind(wx.EVT_TIMER, self.onUCTimer, id=self.uc_timer.GetId())
    self.Bind(wx.EVT_TIMER, self.onPlotOnlyTimer, id=self.ff_timer.GetId())

    # Settings bindings
    self.Bind(wx.EVT_SPINCTRL, self.onMinBragg,
              self.tracker_panel.min_bragg.ctr)
    self.Bind(wx.EVT_SPINCTRL, self.onChartRange,
              self.tracker_panel.chart_window.ctr)
    self.Bind(wx.EVT_CHECKBOX, self.onChartRange,
              self.tracker_panel.chart_window.toggle)

    # Read arguments if any
    self.args, self.phil_args = parse_command_args('').parse_known_args()

    # Generate DIALS PHIL file
    if self.args.paramfile is None:
      default_phil = ip.parse(default_target)
      self.phil = phil_scope.fetch(source=default_phil)
    else:
      with open(self.args.paramfile, 'r') as phil_file:
        phil_string = phil_file.read()
      user_phil = ip.parse(phil_string)
      self.phil = phil_scope.fetch(source=user_phil)
    self.params = self.phil.extract()

    # Set backend
    self.spf_backend = self.args.backend

    # Determine how far the DIALS processing will go
    if 'index' in self.args.action:
      self.run_indexing = True
    elif 'int' in self.args.action:
      self.run_indexing = True
      self.run_integration = True
    self.tracker_panel.min_bragg.ctr.SetValue(self.args.bragg)

    # Determine how the tracker will track images: from file output by
    # iota.single_image, or by turning over actual files. If the latter,
    # determine at what point the tracker will start the tracking
    if self.args.file is not None:
      self.results_file = self.args.file
      self.start_spotfinding(from_file=True)
    elif self.args.path is not None:
      path = os.path.abspath(self.args.path)
      self.open_images_and_get_ready(path=path)
      if self.args.start:
        print 'IMAGE_TRACKER: STARTING FROM FIRST RECORDED IMAGE'
        self.start_spotfinding()
      elif self.args.proceed:
        print 'IMAGE_TRACKER: STARTING FROM IMAGE RECORDED 1 MIN AGO'
        self.start_spotfinding(min_back=-1)
      elif self.args.time > 0:
        min_back = -self.args.time[0]
        print 'IMAGE_TRACKER: STARTING FROM IMAGE RECORDED {} MIN AGO' \
              ''.format(min_back)
        self.start_spotfinding(min_back=min_back)

  def onZoom(self, e):
    if self.tb_btn_zoom.IsToggled():
      self.toolbar.ToggleTool(self.tb_btn_view.GetId(), False)

  def onList(self, e):
    if self.tb_btn_view.IsToggled():
      self.toolbar.ToggleTool(self.tb_btn_zoom.GetId(), False)

  def reset_spotfinder(self):
    self.done_list = []
    self.data_list = []
    self.spotfinding_info = []
    self.plot_idx = 0
    self.bookmark = 0
    self.all_info = []
    self.current_min_bragg = 0
    self.waiting = False
    self.submit_new_images = False
    self.terminated = False


  def onWrtFile(self, e):
    idxs = []
    listctrl = self.tracker_panel.image_list.image_list.ctr
    if listctrl.GetSelectedItemCount() == 0:
      for index in range(listctrl.GetItemCount()):
        idxs.append(index)
    else:
      index = listctrl.GetFirstSelected()
      idxs.append(index)
      while len(idxs) != listctrl.GetSelectedItemCount():
        index = listctrl.GetNextSelected(index)
        idxs.append(index)
    self.write_images_to_file(idxs=idxs)

  def onSelView(self, e):
    idxs = []
    listctrl = self.tracker_panel.image_list.image_list.ctr
    if listctrl.GetSelectedItemCount() == 0:
      return

    index = listctrl.GetFirstSelected()
    idxs.append(index)
    while len(idxs) != listctrl.GetSelectedItemCount():
      index = listctrl.GetNextSelected(index)
      idxs.append(index)
    self.view_images(idxs=idxs)

  def onAllView(self, e):
    listctrl = self.tracker_panel.image_list.image_list.ctr
    idxs = range(listctrl.GetItemCount())
    self.view_images(idxs=idxs)

  def write_images_to_file(self, idxs):
    # Determine param filepath
    save_dlg = wx.FileDialog(self,
                             message="Save Image Paths to File",
                             defaultDir=os.curdir,
                             defaultFile="*.lst",
                             wildcard="*",
                             style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
                             )
    if save_dlg.ShowModal() == wx.ID_OK:
      script_filepath = save_dlg.GetPath()
      file_list = [self.data_dict[idx][1] for idx in idxs]
      with open(script_filepath, 'w') as img_file:
        file_list_string = '\n'.join(file_list)
        img_file.write(file_list_string)

  def view_images(self, idxs):
    file_list = [self.data_dict[idx][1] for idx in idxs]
    file_string = ' '.join(file_list)

    viewer = thr.ImageViewerThread(self,
                                   file_string=file_string)
    viewer.start()

  def onStop(self, e):
    self.terminated = True
    self.toolbar.EnableTool(self.tb_btn_run.GetId(), False)
    self.toolbar.EnableTool(self.tb_btn_stop.GetId(), False)
    with open(self.term_file, 'w') as tf:
      tf.write('')
    self.msg = 'Stopping...'

  def remove_term_file(self):
    try:
      os.remove(self.term_file)
    except Exception:
      pass

  def onGetImages(self, e):
    ''' Select folder to watch for incoming images '''
    open_dlg = wx.DirDialog(self, "Choose the data folder:",
                            style=wx.DD_DEFAULT_STYLE)
    if open_dlg.ShowModal() == wx.ID_OK:
      self.data_folder = open_dlg.GetPath()
      open_dlg.Destroy()
      self.open_images_and_get_ready()
    else:
      open_dlg.Destroy()
      return

  def open_images_and_get_ready(self, path=None):
    if path is not None:
      self.data_folder = path

    self.remove_term_file()
    self.reset_spotfinder()

    self.tracker_panel.chart.reset_chart()
    self.toolbar.EnableTool(self.tb_btn_run.GetId(), True)
    timer_txt = '[ ------ ]'
    self.msg = 'Ready to track images in {}'.format(self.data_folder)
    self.sb.SetStatusText('{} {}'.format(timer_txt, self.msg), 1)

  def onMinBragg(self, e):
    self.tracker_panel.chart.draw_bragg_line()

  def onChartRange(self, e):
    if self.tracker_panel.chart_window.toggle.GetValue():
      chart_range = self.tracker_panel.chart_window.ctr.GetValue()
      self.tracker_panel.chart.plot_zoom = True
      self.tracker_panel.chart.chart_range = chart_range
      self.tracker_panel.chart.max_lock = True
    else:
      self.tracker_panel.chart.plot_zoom = False
    self.tracker_panel.chart.draw_plot()

  def onSpfOptions(self, e):
    spf_dlg = DIALSSpfDialog(self,
                             phil=self.phil,
                             title='DIALS Spotfinding Options')
    if (spf_dlg.ShowModal() == wx.ID_OK):
      self.phil = self.phil.fetch(source=spf_dlg.spf_phil)
    spf_dlg.Destroy()


  def onRunSpotfinding(self, e):
    self.start_spotfinding()

  def start_spotfinding(self, min_back=None, from_file=False):
    ''' Start timer and perform spotfinding on found images '''
    self.terminated = False
    self.tracker_panel.chart.draw_bragg_line()
    self.tracker_panel.chart.select_span.set_active(True)
    self.tracker_panel.chart.zoom_span.set_active(True)
    self.toolbar.EnableTool(self.tb_btn_stop.GetId(), True)
    self.toolbar.EnableTool(self.tb_btn_run.GetId(), False)
    self.toolbar.EnableTool(self.tb_btn_open.GetId(), False)
    self.params = self.phil.extract()

    self.spin_update = 0
    if self.args.file is not None:
      self.sb.SetStatusText('{}'.format('FILE'), 0)
    else:
      self.sb.SetStatusText('{}'.format(self.spf_backend.upper()), 0)

    if from_file:
      self.ff_timer.Start(1000)
      self.uc_timer.Start(15000)
    else:
      self.submit_new_images = True
      self.spf_timer.Start(1000)
      self.uc_timer.Start(15000)

  def stop_run(self):
    timer_txt = '[ xxxxxx ]'
    self.msg = 'STOPPED SPOTFINDING!'
    self.sb.SetStatusText('{} {}'.format(timer_txt, self.msg), 1)
    if self.spf_timer.IsRunning():
      self.spf_timer.Stop()
    if self.ff_timer.IsRunning():
      self.ff_timer.Stop()
    if self.uc_timer.IsRunning():
      self.uc_timer.Stop()

  def run_spotfinding(self, submit_list=None):
    ''' Generate the spot-finder thread and run it '''
    if submit_list is not None and len(submit_list) > 0:
      self.spf_thread = thr.SpotFinderThread(self,
                                             data_list=submit_list,
                                             term_file=self.term_file,
                                             proc_params=self.params,
                                             backend=self.spf_backend,
                                             n_proc=self.args.nproc,
                                             run_indexing=self.run_indexing,
                                             run_integration=self.run_integration)
      self.spf_thread.start()


  def onSpfOneDone(self, e):
    ''' Occurs on every wx.PostEvent instance; updates lists of images with
    spotfinding results '''
    if not self.terminated:
      info = e.GetValue()
      if info is not None:
        idx = int(info[0]) + len(self.done_list)
        obs_count = info[1]
        img_path = info[2]
        self.spotfinding_info.append([idx, obs_count, img_path,
                                      info[3], info[4]])
        self.all_info.append([idx, obs_count, img_path])


  def onSpfAllDone(self, e):
    self.done_list.extend(e.GetValue())
    self.submit_new_images = True

  def onSpfTerminated(self, e):
    self.stop_run()
    self.toolbar.EnableTool(self.tb_btn_open.GetId(), True)

  def find_new_images(self, min_back=None, last_file=None):
    found_files = ginp.make_input_list([self.data_folder],
                                       filter=True,
                                       filter_type='image',
                                       last=last_file,
                                       min_back=min_back)

    # Sometimes duplicate files are found anyway; clean that up
    found_files = list(set(found_files) - set(self.data_list))

    # Add new files to the data list & clean up
    self.data_list.extend(found_files)
    self.data_list = sorted(self.data_list, key=lambda i:i)

    if self.waiting:
      if len(found_files) > 0:
        self.waiting = False
        self.msg = 'Tracking new images in {} ...'.format(self.data_folder)
        self.start_spotfinding()
    else:
      if len(found_files) == 0:
        self.msg = 'Waiting for new images in {} ...'.format(self.data_folder)
        self.waiting = True

  def update_spinner(self):
    ''' Update spotfinding chart '''
    if self.spin_update == 4:
      self.spin_update = 0
    else:
      self.spin_update += 1
    tick = ['-o-----', '--o----', '---o---', '----o--', '-----o-']
    timer_txt = '[ {0} ]'.format(tick[self.spin_update])
    self.sb.SetStatusText('{} {}'.format(timer_txt, self.msg), 1)

  def onPlotOnlyTimer(self, e):
    if self.terminated:
      self.stop_run()
    else:
      if self.results_file is not None and os.path.isfile(self.results_file):
        st = time.time()
        with open(self.results_file, 'r') as rf:
          rf.seek(self.bookmark)
          split_info = [i.replace('\n','').split(' ') for i in rf.readlines()]
          self.bookmark = rf.tell()

        if self.args.reorder:
          idx_offset = len(self.spotfinding_info)
          new_info = [
            [split_info.index(i) + idx_offset,
             int(i[1]), i[2], i[3], tuple(i[4:10])] if len(i) > 5  else
            [split_info.index(i) + idx_offset,
             int(i[1]), i[2], misc.makenone(i[3]), misc.makenone(i[4])]
             for i in split_info]
        else:
          new_info = [
            [int(i[0]), int(i[1]), i[2], i[3], tuple(i[4:10])] if len(i) > 5 else
            [int(i[0]), int(i[1]), i[2], misc.makenone(i[3]), misc.makenone(i[4])]
             for i in split_info]

        if len(new_info) > 0:
          self.msg = 'Tracking new images in {} ...'.format(self.results_file)
          self.spotfinding_info.extend(new_info)
          if len(self.spotfinding_info) > 0:
            indexed = [i for i in self.spotfinding_info if i[4] is not None]
            self.tracker_panel.idx_count_txt.SetLabel(str(len(indexed)))
          self.plot_results()
        else:
          self.msg = 'Waiting for new images in {} ...'.format(self.results_file)

      else:
        self.msg = 'Waiting for new run to initiate...'

      self.update_spinner()


  def onSpfTimer(self, e):
    self.update_spinner()

    if not self.terminated:
      if len(self.spotfinding_info) > 0:
        indexed = [i for i in self.spotfinding_info if i[3] is not None]
        self.tracker_panel.idx_count_txt.SetLabel(str(len(indexed)))
        self.plot_results()

      if self.data_list != []:
        last_file = self.data_list[-1]
      else:
        last_file = None
      self.find_new_images(last_file=last_file)

      if self.submit_new_images:
        unproc_images = list(set(self.data_list) - set(self.done_list))
        unproc_images = sorted(unproc_images, key=lambda i:i)
        if len(unproc_images) > 0:
          self.submit_new_images = False
          self.run_spotfinding(submit_list=unproc_images)

    else:
      self.stop_run()

  def update_image_list(self):
    listctrl = self.tracker_panel.image_list.image_list.ctr
    if self.tracker_panel.chart.bracket_set:
      try:
        first_img = self.tracker_panel.chart.patch_x
        last_img = self.tracker_panel.chart.patch_x_last

        new_data_dict = {}
        sel_img_list = self.spotfinding_info[first_img:last_img]
        for img in sel_img_list:
          idx = sel_img_list.index(img)
          if img[3] is not None:
            idxd = 'X'
          else:
            idxd = ''
          new_data_dict[idx] = (img[0], img[2], img[1], idxd)
        self.data_dict = new_data_dict
        listctrl.InitializeDataMap(self.data_dict)
        self.tracker_panel.btn_view_all.Enable()
        self.tracker_panel.btn_wrt_file.Enable()

      except TypeError:
        pass

    else:
      self.data_dict = {}
      self.tracker_panel.btn_view_all.Disable()
      self.tracker_panel.btn_view_sel.Disable()
      listctrl.InitializeDataMap(self.data_dict)

  def plot_results(self):

    if self.plot_idx <= len(self.spotfinding_info):
      new_frames = [i[0] for i in self.spotfinding_info[self.plot_idx:]]
      new_counts = [i[1] for i in self.spotfinding_info[self.plot_idx:]]
      idx_counts = [i[1] if i[3] is not None else np.nan
                         for i in self.spotfinding_info[self.plot_idx:]]

      # Try finding where data comes from a new folder
      new_paths = []
      for info in self.spotfinding_info[self.plot_idx:]:
        cur_dir = os.path.dirname(info[2])
        cur_idx = self.spotfinding_info.index(info)
        if cur_idx > 0:
          prev_idx = cur_idx - 1
          prev_dir = os.path.dirname(self.spotfinding_info[prev_idx][2])
          if cur_dir != prev_dir:
            new_paths.append((info[0], cur_dir))
        else:
          new_paths.append((info[0], cur_dir))

      self.tracker_panel.chart.draw_plot(new_x=new_frames,
                                         new_y=new_counts,
                                         new_i=idx_counts,
                                         new_p=new_paths)
      self.plot_idx = self.spotfinding_info.index(self.spotfinding_info[-1]) + 1


  def onUCTimer(self, e):
    self.cluster_unit_cells()

  def cluster_unit_cells(self):
    input = []
    for item in self.spotfinding_info:
      if item[4] is not None:
        try:
          if type(item[4]) in (tuple, list):
            uc = item[4]
          else:
            uc = item[4].rsplit()
          info_line = [float(i) for i in uc]
          info_line.append(item[3])
          input.append(info_line)
        except ValueError:
          pass

    with misc.Capturing() as junk_output:
      try:
        ucs = Cluster.from_iterable(iterable=input)
        clusters, _ = ucs.ab_cluster(5000,
                                     log=False, write_file_lists=False,
                                     schnell=True, doplot=False)
      except Exception, e:
        print e
        clusters = []

    if len(clusters) > 0:
      uc_summary = []
      for cluster in clusters:
        sorted_pg_comp = sorted(cluster.pg_composition.items(),
                                key=lambda x: -1 * x[1])
        pg_nums = [pg[1] for pg in sorted_pg_comp]
        cons_pg = sorted_pg_comp[np.argmax(pg_nums)]

        uc_info = [len(cluster.members), cons_pg[0], cluster.medians,
                   cluster.stdevs]
        uc_summary.append(uc_info)

      # select the most prevalent unit cell (most members in cluster)
      uc_freqs = [i[0] for i in uc_summary]
      uc_pick = uc_summary[np.argmax(uc_freqs)]
      cons_uc = uc_pick[2]

      # Here will determine the best symmetry for the given unit cell (better
      # than previous method of picking the "consensus" point group from list)
      uc_init = unit_cell(cons_uc)
      symmetry = crystal.symmetry(unit_cell=uc_init, space_group_symbol='P1')
      groups = lattice_symmetry.metric_subgroups(input_symmetry=symmetry,
                                                 max_delta=3)
      top_group = groups.result_groups[0]
      best_uc = top_group['best_subsym'].unit_cell().parameters()
      best_sg = top_group['best_subsym'].space_group_info()

      uchr = misc.UnicodeCharacters()

      uc_line = "a = {:<6.2f}, b = {:<6.2f}, c ={:<6.2f}, " \
                "{} = {:<6.2f}, {} = {:<6.2f}, {} = {:<6.2f}" \
                "".format(best_uc[0], best_uc[1], best_uc[2],
                          uchr.alpha,  best_uc[3], uchr.beta,
                          best_uc[4], uchr.gamma,  best_uc[5])
      sg_line = str(best_sg)

      self.tracker_panel.pg_txt.SetLabel(sg_line)
      self.tracker_panel.uc_txt.SetLabel(uc_line)
      self.tracker_panel.chart.draw_plot()
예제 #25
0
    (
        4.807294085194974,
        12.822386757910516,
        16.560411742466663,
        106.43185845358086,
        90.02067929544215,
        100.79522302759383,
    ),
]
sgs_1 = ["P1"] * 4

print("Test case 1:")
for uc, sg in zip(ucs_1, sgs_1):
    cs = crystal.symmetry(unit_cell=uc, space_group_symbol=sg)
    groups = metric_subgroups(cs,
                              max_delta=5,
                              enforce_max_delta_for_generated_two_folds=True)
    group = groups.result_groups[0]
    print(cs)
    print("Minimum cell:", cs.minimum_cell().unit_cell())
    print("Best cell:", group["best_subsym"].unit_cell())
    print("Minimum cell (via best):",
          group["best_subsym"].minimum_cell().unit_cell())
    print()

ucs_2 = [
    (39.7413, 183.767, 140.649, 90, 90, 90),
    (40.16, 142.899, 92.4167, 90, 102.48, 90),
    (180.613, 40.1558, 142.737, 90, 90.0174, 90),
]
sgs_2 = ["C 2 2 21", "P 1 2 1", "C 1 2 1"]
예제 #26
0
cs.best_cell().minimum_cell().show_summary()
print("Best cell -> niggli cell")
cs.best_cell().niggli_cell().show_summary()
print("Reference setting -> minimum cell")
cs.as_reference_setting().minimum_cell().show_summary()
print("Reference setting -> niggli cell")
cs.as_reference_setting().niggli_cell().show_summary()
print()

print("Reference settings (via minimum/niggli cell):")
print("Input -> minimum cell -> reference setting")
cs.minimum_cell().as_reference_setting().show_summary()
print("Input -> niggli cell -> reference setting")
cs.niggli_cell().as_reference_setting().show_summary()
print("Best cell -> minimum cell -> reference setting")
cs.best_cell().minimum_cell().as_reference_setting().show_summary()
print("Best cell -> niggli cell -> reference setting")
cs.best_cell().niggli_cell().as_reference_setting().show_summary()
print("Reference setting -> minimum cell -> reference setting")
cs.as_reference_setting().minimum_cell().as_reference_setting().show_summary()
print("Reference setting -> niggli cell -> reference setting")
cs.as_reference_setting().niggli_cell().as_reference_setting().show_summary()
print()

subgroups = lattice_symmetry.metric_subgroups(cs, max_delta=0.1)
for subgroup in subgroups.result_groups:
    bravais_t = bravais_lattice(group=subgroup["ref_subsym"].space_group())
    if bravais_t == "mC":
        print(subgroup["ref_subsym"].unit_cell())
        print(subgroup["best_subsym"].as_reference_setting().unit_cell())
def test_symmetry_analysis():
    coords = flex.double([
        [0.835, 0.158],
        [0.772, 0.104],
        [0.108, 0.907],
        [0.058, 0.76],
        [0.926, 0.189],
        [0.221, 0.888],
        [0.957, 0.137],
        [0.958, 0.143],
        [-0.015, 0.726],
        [-0.066, 0.29],
        [0.135, 0.848],
        [0.085, 0.788],
        [0.897, 0.126],
        [0.749, 0.073],
        [0.166, 0.943],
        [0.871, 0.248],
        [0.116, 0.968],
        [0.116, 0.973],
        [0.706, 0.007],
        [0.288, -0.055],
        [0.137, 0.848],
        [0.089, 0.78],
        [0.893, 0.122],
        [0.749, 0.077],
        [0.165, 0.941],
        [0.877, 0.242],
        [0.114, 0.968],
        [0.12, 0.971],
        [0.716, 0.002],
        [0.292, -0.062],
        [0.841, 0.162],
        [0.774, 0.104],
        [0.1, 0.909],
        [0.054, 0.761],
        [0.927, 0.184],
        [0.227, 0.88],
        [0.957, 0.137],
        [0.961, 0.143],
        [-0.007, 0.716],
        [-0.061, 0.287],
        [0.13, 0.848],
        [0.084, 0.783],
        [0.898, 0.124],
        [0.749, 0.075],
        [0.169, 0.94],
        [0.871, 0.247],
        [0.114, 0.969],
        [0.12, 0.969],
        [0.717, 0.0],
        [0.296, -0.066],
        [0.84, 0.154],
        [0.776, 0.103],
        [0.104, 0.908],
        [0.057, 0.755],
        [0.925, 0.19],
        [0.227, 0.883],
        [0.958, 0.136],
        [0.962, 0.143],
        [-0.017, 0.724],
        [-0.067, 0.295],
    ])

    sym_ops = [
        sgtbx.rt_mx(s) for s in ("-z,-y,-x", "y,z,x", "x,y,z", "-x,-z,-y",
                                 "z,x,y", "-y,-x,-z")
    ]

    crystal_symmetry = crystal.symmetry(
        unit_cell=uctbx.unit_cell((98.33, 98.33, 135.99, 90, 90, 120)),
        space_group_info=sgtbx.space_group_info("R3:H"),
    ).minimum_cell()

    from cctbx.sgtbx.lattice_symmetry import metric_subgroups

    subgroups = metric_subgroups(crystal_symmetry,
                                 max_delta=5,
                                 bravais_types_only=False)

    cb_op_inp_min = sgtbx.change_of_basis_op()

    from dials.algorithms.symmetry.cosym import SymmetryAnalysis

    analysis = SymmetryAnalysis(coords, sym_ops, subgroups, cb_op_inp_min)

    assert analysis.best_solution.likelihood > 0.99
    assert analysis.best_solution.confidence > 0.98
    assert (analysis.best_solution.subgroup["best_subsym"].space_group().type(
    ).number() == 148)  # R -3 :H
    assert (str(analysis) == """\
Scoring individual symmetry elements
----------------------------------------------
likelihood  Z-CC   CC         Operator
----------------------------------------------
0.087       1.96   0.20        2 |(0, -1, 1)
0.087       1.96   0.20        2 |(-1, 0, 1)
0.949       10.00  1.00  ***   3^-1 |(1, 1, 1)
0.087       1.96   0.20        2 |(-1, 1, 0)
0.949       10.00  1.00  ***   3 |(1, 1, 1)
----------------------------------------------
Scoring all possible sub-groups
--------------------------------------------------------------------------------
Patterson group       Likelihood  NetZcc  Zcc+    Zcc-   delta  Reindex operator
--------------------------------------------------------------------------------
R -3 :H          ***  0.995        8.04    10.00   1.96  0.0    b-c,-a+c,a+b+c
P -1                  0.003       -6.50    0.00    6.50  0.0    a,b,c
R -3 m :H             0.001        6.50    6.50    0.00  0.0    b-c,-a+c,a+b+c
C 1 2/m 1             0.000       -5.24    1.96    7.21  0.0    -a-b,a-b,c
C 1 2/m 1             0.000       -5.24    1.96    7.21  0.0    -b-c,b-c,a
C 1 2/m 1             0.000       -5.24    1.96    7.21  0.0    -a-c,-a+c,b
--------------------------------------------------------------------------------
Best solution: R -3 :H
Unit cell: (98.33, 98.33, 135.99, 90, 90, 120)
Reindex operator: b-c,-a+c,a+b+c
Laue group probability: 0.995
Laue group confidence: 0.994""")

    d = analysis.as_dict()
    assert d["sym_op_scores"][0] == {
        "cc": pytest.approx(0.19620531091685714),
        "operator": "-x,-z,-y",
        "likelihood": pytest.approx(0.08665625555575088),
        "stars": "",
        "z_cc": pytest.approx(1.9620531091685713),
    }
    assert d["subgroup_scores"][0] == {
        "confidence":
        pytest.approx(0.9940687431995551),
        "z_cc_for":
        pytest.approx(9.999725360190128),
        "stars":
        "***",
        "patterson_group":
        "-R 3",
        "max_angular_difference":
        0.0,
        "likelihood":
        pytest.approx(0.995493024305035),
        "cb_op":
        "-1/3*x+2/3*y-1/3*z,-2/3*x+1/3*y+1/3*z,1/3*x+1/3*y+1/3*z",
        "z_cc_against":
        pytest.approx(1.9620621986200772),
        "unit_cell":
        pytest.approx((
            98.32999999999998,
            98.32999999999998,
            135.99,
            90.0,
            90.0,
            119.99999999999999,
        )),
        "z_cc_net":
        pytest.approx(8.037663161570052),
    }
예제 #28
0
  def get_metric_symmetry_subgroups(self):
    subgroup_list = lattice_symmetry.metric_subgroups(
      self.symmetry,3.0,bravais_types_only=False,
      best_monoclinic_beta=False).result_groups

    return subgroup_list
예제 #29
0
    def unit_cell_analysis(self):
        """ Calls unit cell analysis module, which uses hierarchical clustering
        (Zeldin, et al, Acta D, 2015) to split integration results according to
        detected morphological groupings (if any). Most useful with preliminary
        integration without target unit cell specified. """

        # Will not run clustering if only one integration result found or if turned off
        if not self.info.categories['integrated']:
            util.main_log(self.info.logfile,
                          "\n\n{:-^80}\n".format(' UNIT CELL ANALYSIS '), True)
            util.main_log(self.info.logfile,
                          '\n UNIT CELL CANNOT BE DETERMINED!', True)

        elif len(self.info.categories['integrated']) == 1:
            unit_cell = (self.info.cluster_iterable[0][:5])
            point_group = self.info.cluster_iterable[0][6]
            util.main_log(self.info.logfile,
                          "\n\n{:-^80}\n".format(' UNIT CELL ANALYSIS '), True)
            uc_line = "{:<6} {:^4}:  {:<6.2f}, {:<6.2f}, {:<6.2f}, {:<6.2f}, " \
                      "{:<6.2f}, {:<6.2f}".format('(1)', point_group,
                                                  unit_cell[0], unit_cell[1],
                                                  unit_cell[2],
                                                  unit_cell[3], unit_cell[4],
                                                  unit_cell[5])
            util.main_log(self.info.logfile, uc_line, True)

            self.info.best_pg = str(point_group)
            self.info.best_uc = unit_cell

        else:
            uc_table = []
            uc_summary = []

            if self.params.analysis.clustering.flag_on:
                # run hierarchical clustering analysis
                from xfel.clustering.cluster import Cluster

                counter = 0
                self.info.clusters = []

                threshold = self.params.analysis.clustering.threshold
                cluster_limit = self.params.analysis.clustering.limit
                final_pickles = self.info.categories['integrated'][0]

                pickles = []
                if self.params.analysis.clustering.n_images > 0:
                    import random

                    for i in range(
                            len(self.params.analysis.clustering.n_images)):
                        random_number = random.randrange(0, len(final_pickles))
                        if final_pickles[random_number] in pickles:
                            while final_pickles[random_number] in pickles:
                                random_number = random.randrange(
                                    0, len(final_pickles))
                            pickles.append(final_pickles[random_number])
                else:
                    pickles = final_pickles

                # Cluster from files (slow, but will keep for now)
                ucs = Cluster.from_files(pickle_list=pickles)

                # Do clustering
                clusters, _ = ucs.ab_cluster(threshold=threshold,
                                             log=False,
                                             write_file_lists=False,
                                             schnell=False,
                                             doplot=False)
                uc_table.append("\n\n{:-^80}\n" \
                                "".format(' UNIT CELL ANALYSIS '))

                # extract clustering info and add to summary output list
                if cluster_limit is None:
                    if len(pickles) / 10 >= 10:
                        cluster_limit = 10
                    else:
                        cluster_limit = len(pickles) / 10

                for cluster in clusters:
                    sorted_pg_comp = sorted(cluster.pg_composition.items(),
                                            key=lambda x: -1 * x[1])
                    pg_nums = [pg[1] for pg in sorted_pg_comp]
                    cons_pg = sorted_pg_comp[np.argmax(pg_nums)]

                    if len(cluster.members) > cluster_limit:
                        counter += 1

                        # Write to file
                        cluster_filenames = [j.path for j in cluster.members]
                        if self.params.analysis.clustering.write_files:
                            output_file = os.path.join(
                                self.info.int_base,
                                "uc_cluster_{}.lst".format(counter))
                            for fn in cluster_filenames:
                                with open(output_file, 'a') as scf:
                                    scf.write('{}\n'.format(fn))

                            mark_output = os.path.basename(output_file)
                        else:
                            mark_output = '*'
                            output_file = None

                    else:
                        mark_output = ''
                        output_file = None

                    # Populate clustering info for GUI display
                    uc_init = uctbx.unit_cell(cluster.medians)
                    symmetry = crystal.symmetry(unit_cell=uc_init,
                                                space_group_symbol='P1')
                    groups = metric_subgroups(input_symmetry=symmetry,
                                              max_delta=3)
                    top_group = groups.result_groups[0]
                    best_sg = str(groups.lattice_group_info()).split('(')[0]
                    best_uc = top_group['best_subsym'].unit_cell().parameters()
                    # best_sg = str(top_group['best_subsym'].space_group_info())

                    uc_no_stdev = "{:<6.2f} {:<6.2f} {:<6.2f} " \
                                  "{:<6.2f} {:<6.2f} {:<6.2f} " \
                                  "".format(best_uc[0], best_uc[1], best_uc[2],
                                            best_uc[3], best_uc[4], best_uc[5])
                    cluster_info = {
                        'number': len(cluster.members),
                        'pg': best_sg,
                        'uc': uc_no_stdev,
                        'filename': mark_output
                    }
                    self.info.clusters.append(cluster_info)

                    # format and record output
                    # TODO: How to propagate stdevs after conversion from Niggli?
                    # uc_line = "{:<6} {:^4}:  {:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}), "\
                    #           "{:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}), "\
                    #           "{:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f})   "\
                    #           "{}".format('({})'.format(len(cluster.members)), cons_pg[0],
                    #                                 cluster.medians[0], cluster.stdevs[0],
                    #                                 cluster.medians[1], cluster.stdevs[1],
                    #                                 cluster.medians[2], cluster.stdevs[2],
                    #                                 cluster.medians[3], cluster.stdevs[3],
                    #                                 cluster.medians[4], cluster.stdevs[4],
                    #                                 cluster.medians[5], cluster.stdevs[5],
                    #                                 mark_output)
                    # uc_table.append(uc_line)
                    uc_table.append("{:<6}:  {} {}".format(
                        len(cluster.members), uc_no_stdev, mark_output))
                    lattices = ', '.join(
                        ['{} ({})'.format(i[0], i[1]) for i in sorted_pg_comp])
                    # uc_info = [len(cluster.members), cons_pg[0], cluster.medians,
                    #            output_file, uc_line, lattices]
                    uc_info = [
                        len(cluster.members), best_sg, best_uc, output_file,
                        uc_no_stdev, lattices
                    ]
                    uc_summary.append(uc_info)

            else:
                # generate average unit cell
                uc_table.append("\n\n{:-^80}\n" \
                                "".format(' UNIT CELL AVERAGING (no clustering) '))
                uc_a, uc_b, uc_c, uc_alpha, \
                uc_beta, uc_gamma, uc_sg = list(zip(*self.info.cluster_iterable))
                cons_pg = Counter(uc_sg).most_common(1)[0][0]
                all_pgs = Counter(uc_sg).most_common()
                unit_cell = (np.median(uc_a), np.median(uc_b), np.median(uc_c),
                             np.median(uc_alpha), np.median(uc_beta),
                             np.median(uc_gamma))

                # Populate clustering info for GUI display
                uc_init = uctbx.unit_cell(unit_cell)
                symmetry = crystal.symmetry(unit_cell=uc_init,
                                            space_group_symbol='P1')
                groups = metric_subgroups(input_symmetry=symmetry, max_delta=3)
                top_group = groups.result_groups[0]
                best_sg = str(groups.lattice_group_info()).split('(')[0]
                best_uc = top_group['best_subsym'].unit_cell().parameters()
                # best_sg = str(top_group['best_subsym'].space_group_info())

                uc_no_stdev = "{:<6.2f} {:<6.2f} {:<6.2f} " \
                              "{:<6.2f} {:<6.2f} {:<6.2f} " \
                              "".format(best_uc[0], best_uc[1], best_uc[2],
                                        best_uc[3], best_uc[4], best_uc[5])
                cluster_info = {
                    'number': len(self.info.cluster_iterable),
                    'pg': best_sg,
                    'uc': uc_no_stdev,
                    'filename': None
                }
                self.info.clusters.append(cluster_info)

                # uc_line = "{:<6} {:^4}:  {:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}), " \
                #           "{:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f}), " \
                #           "{:<6.2f} ({:>5.2f}), {:<6.2f} ({:>5.2f})   " \
                #           "{}".format('({})'.format(len(self.final_objects)), cons_pg,
                #                       np.median(uc_a), np.std(uc_a),
                #                       np.median(uc_b), np.std(uc_b),
                #                       np.median(uc_c), np.std(uc_c),
                #                       np.median(uc_alpha), np.std(uc_alpha),
                #                       np.median(uc_beta), np.std(uc_beta),
                #                       np.median(uc_gamma), np.std(uc_gamma), '')
                #
                # uc_table.append(uc_line)
                uc_table.append(uc_no_stdev)
                lattices = ', '.join(
                    ['{} ({})'.format(i[0], i[1]) for i in all_pgs])
                # uc_info = [len(self.final_objects), cons_pg, unit_cell, None,
                #            uc_line, lattices]
                uc_info = [
                    len(self.info.cluster_iterable), best_sg, best_uc, None,
                    uc_no_stdev, lattices
                ]
                uc_summary.append(uc_info)

            uc_table.append('\nMost common unit cell:\n')

            # select the most prevalent unit cell (most members in cluster)
            uc_freqs = [i[0] for i in uc_summary]
            uc_pick = uc_summary[np.argmax(uc_freqs)]
            uc_table.append(uc_pick[4])
            uc_table.append('\nBravais Lattices in Biggest Cluster: {}'
                            ''.format(uc_pick[5]))
            self.info.best_pg = str(uc_pick[1])
            self.info.best_uc = uc_pick[2]

            if uc_pick[3] is not None:
                self.prime_data_path = uc_pick[3]

            for item in uc_table:
                util.main_log(self.info.logfile, item, False)
            self.info.update(uc_table=uc_table)

            if self.gui_mode:
                return self.info.clusters
예제 #30
0

if __name__ == "__main__":
    uc_min = uctbx.unit_cell((
        44.66208170999999,
        53.12629402999999,
        62.53397660267584,
        115.13670293012744,
        101.7265610491002,
        90.0,
    ))
    cs_min = crystal.symmetry(unit_cell=uc_min,
                              space_group=sgtbx.space_group())
    from cctbx.sgtbx.lattice_symmetry import metric_subgroups

    subgroups = metric_subgroups(cs_min, max_delta=5)
    best_subgroup = subgroups.result_groups[0]
    print(f"best_sybsym {best_subgroup['best_subsym']}\n")
    print(f"ref_sybsym {best_subgroup['ref_subsym']}\n")

    cs_ref = crystal.symmetry(
        # unit_cell=(113.2236274, 53.12629403, 44.66208171, 90, 102.9736126, 90),
        unit_cell=(112.90, 53.14, 44.39, 90.00, 103.04, 90.00),
        space_group_symbol="C 1 2/m 1",
    )

    cs_best = cs_ref.best_cell()
    cb_ref_best = cs_ref.change_of_basis_op_to_best_cell()
    cb_ref_primitive = cs_ref.change_of_basis_op_to_primitive_setting()
    cb_best_primitive = cs_best.change_of_basis_op_to_primitive_setting()
    cb_best_ref = cs_best.change_of_basis_op_to_reference_setting()
예제 #31
0
from cctbx.sgtbx.lattice_symmetry import metric_subgroups
from cctbx import crystal
input_symmetry = crystal.symmetry(
    unit_cell=(20, 20, 20, 90, 90, 90),
    space_group_symbol = "P23")
groups = metric_subgroups(input_symmetry=input_symmetry, max_delta = 0.0)
for item in groups.result_groups:
    cell = item['ref_subsym'].unit_cell().parameters()
    spacegroup_name = item['ref_subsym'].space_group().type(
        ).universal_hermann_mauguin_symbol()
    reindex = item['cb_op_inp_best'].as_hkl()

    print '%20s' % spacegroup_name, '%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f' % \
          cell, reindex

    print '%6.3f %6.3f %6.3f\n%6.3f %6.3f %6.3f\n%6.3f %6.3f %6.3f' % \
          item['cb_op_inp_best'].c().r().as_double()