示例#1
0
def test_determine_space_group(space_group):

    sgi = sgtbx.space_group_info(symbol=space_group)
    sg = sgi.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()
    # needed to give vaguely sensible E_cc_true values
    intensities = intensities.customized_copy(sigmas=intensities.data() / 50)
    intensities.set_info(miller.array_info(source="fake", source_type="mtz"))
    result = LaueGroupAnalysis([intensities], normalisation=None)
    print(result)
    assert (
        result.best_solution.subgroup["best_subsym"].space_group()
        == sg.build_derived_patterson_group()
    )
    assert result.best_solution.likelihood > 0.8
    for score in result.subgroup_scores[1:]:
        assert score.likelihood < 0.1
示例#2
0
def test_determine_space_group(space_group):
    sgi = sgtbx.space_group_info(symbol=space_group)
    sg = sgi.group()
    cs = sgi.any_compatible_crystal_symmetry(volume=10000)
    cs = cs.best_cell()
    cs = cs.minimum_cell()

    intensities = generate_fake_intensities(cs)
    result = LaueGroupAnalysis([intensities], normalisation=None)
    print(result)
    assert (result.best_solution.subgroup["best_subsym"].space_group() ==
            sg.build_derived_patterson_group())
    assert result.best_solution.likelihood > 0.8
    for score in result.subgroup_scores[1:]:
        assert score.likelihood < 0.1
示例#3
0
def test_determine_space_group_best_monoclinic_beta():
    cs = crystal.symmetry(
        unit_cell=(44.66208171, 53.12629403, 62.53397661, 64.86329707,
                   78.27343894, 90),
        space_group_symbol="C 1 2/m 1 (z,x+y,-2*x)",
    )
    cs = cs.best_cell().primitive_setting()
    intensities = generate_fake_intensities(cs)
    result = LaueGroupAnalysis([intensities], normalisation=None)
    print(result)
    assert result.best_solution.subgroup["best_subsym"].is_similar_symmetry(
        crystal.symmetry(
            unit_cell=(44.66208171, 53.12629403, 111.9989451, 90, 99.89337396,
                       90),
            space_group_symbol="I 1 2/m 1",
        ))
    d = result.as_dict()
    assert cs.change_basis(
        sgtbx.change_of_basis_op(
            d["subgroup_scores"][0]["cb_op"])).is_similar_symmetry(
                result.best_solution.subgroup["best_subsym"])
    result = LaueGroupAnalysis([intensities],
                               best_monoclinic_beta=False,
                               normalisation=None)
    print(result)
    assert result.best_solution.subgroup["best_subsym"].is_similar_symmetry(
        crystal.symmetry(
            unit_cell=(113.2236274, 53.12629403, 44.66208171, 90, 102.9736126,
                       90),
            space_group_symbol="C 1 2/m 1",
        ))
    d = result.as_dict()
    assert cs.change_basis(
        sgtbx.change_of_basis_op(
            d["subgroup_scores"][0]["cb_op"])).is_similar_symmetry(
                result.best_solution.subgroup["best_subsym"])
示例#4
0
def symmetry(experiments, reflection_tables, params=None):
    """
    Run symmetry analysis

    Args:
        experiments: An experiment list.
        reflection_tables: A list of reflection tables.
        params: The dials.symmetry phil scope.
    """
    result = None
    if params is None:
        params = phil_scope.extract()
    refls_for_sym = []

    if params.laue_group is Auto:
        logger.info("=" * 80)
        logger.info("")
        logger.info("Performing Laue group analysis")
        logger.info("")

        # Transform models into miller arrays
        n_datasets = len(experiments)

        # Map experiments and reflections to minimum cell
        # Eliminate reflections that are systematically absent due to centring
        # of the lattice, otherwise they would lead to non-integer miller indices
        # when reindexing to a primitive setting
        cb_ops = change_of_basis_ops_to_minimum_cell(
            experiments,
            params.lattice_symmetry_max_delta,
            params.relative_length_tolerance,
            params.absolute_angle_tolerance,
        )
        reflection_tables = eliminate_sys_absent(experiments,
                                                 reflection_tables)
        experiments, reflection_tables = apply_change_of_basis_ops(
            experiments, reflection_tables, cb_ops)

        refls_for_sym = get_subset_for_symmetry(experiments, reflection_tables,
                                                params.exclude_images)

        datasets = filtered_arrays_from_experiments_reflections(
            experiments,
            refls_for_sym,
            outlier_rejection_after_filter=True,
            partiality_threshold=params.partiality_threshold,
        )
        if len(datasets) != n_datasets:
            raise ValueError(
                """Some datasets have no reflection after prefiltering, please check
    input data and filtering settings e.g partiality_threshold""")

        datasets = [
            ma.as_anomalous_array().merge_equivalents().array()
            for ma in datasets
        ]
        result = LaueGroupAnalysis(
            datasets,
            normalisation=params.normalisation,
            d_min=params.d_min,
            min_i_mean_over_sigma_mean=params.min_i_mean_over_sigma_mean,
            lattice_symmetry_max_delta=params.lattice_symmetry_max_delta,
            relative_length_tolerance=params.relative_length_tolerance,
            absolute_angle_tolerance=params.absolute_angle_tolerance,
            best_monoclinic_beta=params.best_monoclinic_beta,
        )
        logger.info("")
        logger.info(result)

        if params.output.json is not None:
            d = result.as_dict()
            d["cb_op_inp_min"] = [str(cb_op) for cb_op in cb_ops]
            # Copy the "input_symmetry" to "min_cell_symmetry" as it isn't technically
            # the input symmetry to dials.symmetry
            d["min_cell_symmetry"] = d["input_symmetry"]
            del d["input_symmetry"]
            json_str = json.dumps(d, indent=2)
            with open(params.output.json, "w") as f:
                f.write(json_str)

        # Change of basis operator from input unit cell to best unit cell
        cb_op_inp_best = result.best_solution.subgroup["cb_op_inp_best"]
        # Get the best space group.
        best_subsym = result.best_solution.subgroup["best_subsym"]
        best_space_group = best_subsym.space_group(
        ).build_derived_acentric_group()
        logger.info(
            tabulate(
                [[
                    str(best_subsym.space_group_info()),
                    str(best_space_group.info())
                ]],
                ["Patterson group", "Corresponding MX group"],
            ))
        # Reindex the input data
        experiments, reflection_tables = _reindex_experiments_reflections(
            experiments, reflection_tables, best_space_group, cb_op_inp_best)

    elif params.laue_group is not None:
        if params.change_of_basis_op is not None:
            cb_op = sgtbx.change_of_basis_op(params.change_of_basis_op)
        else:
            cb_op = sgtbx.change_of_basis_op()
        # Reindex the input data
        experiments, reflection_tables = _reindex_experiments_reflections(
            experiments, reflection_tables, params.laue_group.group(), cb_op)

    if params.systematic_absences.check:
        logger.info("=" * 80)
        logger.info("")
        logger.info("Analysing systematic absences")
        logger.info("")

        # Get the laue class from the current space group.
        space_group = experiments[0].crystal.get_space_group()
        laue_group = str(space_group.build_derived_patterson_group().info())
        logger.info("Laue group: %s", laue_group)
        if laue_group in ("I m -3", "I m m m"):
            if laue_group == "I m -3":
                logger.info(
                    """Space groups I 2 3 & I 21 3 cannot be distinguished with systematic absence
analysis, due to lattice centering.
Using space group I 2 3, space group I 21 3 is equally likely.\n""")
            if laue_group == "I m m m":
                logger.info(
                    """Space groups I 2 2 2 & I 21 21 21 cannot be distinguished with systematic absence
analysis, due to lattice centering.
Using space group I 2 2 2, space group I 21 21 21 is equally likely.\n""")
        elif laue_group not in laue_groups_for_absence_analysis:
            logger.info("No absences to check for this laue group\n")
        else:
            if not refls_for_sym:
                refls_for_sym = get_subset_for_symmetry(
                    experiments, reflection_tables, params.exclude_images)

            if (params.d_min is Auto) and (result is not None):
                d_min = result.intensities.resolution_range()[1]
            elif params.d_min is Auto:
                d_min = resolution_filter_from_reflections_experiments(
                    refls_for_sym,
                    experiments,
                    params.min_i_mean_over_sigma_mean,
                    params.min_cc_half,
                )
            else:
                d_min = params.d_min

            # combine before sys abs test - only triggers if laue_group=None and
            # multiple input files.
            if len(reflection_tables) > 1:
                joint_reflections = flex.reflection_table()
                for table in refls_for_sym:
                    joint_reflections.extend(table)
            else:
                joint_reflections = refls_for_sym[0]

            merged_reflections = prepare_merged_reflection_table(
                experiments, joint_reflections, d_min)
            run_systematic_absences_checks(
                experiments,
                merged_reflections,
                float(params.systematic_absences.significance_level),
            )

    logger.info(
        "Saving reindexed experiments to %s in space group %s",
        params.output.experiments,
        str(experiments[0].crystal.get_space_group().info()),
    )
    experiments.as_file(params.output.experiments)
    if params.output.reflections is not None:
        if len(reflection_tables) > 1:
            joint_reflections = flex.reflection_table()
            for table in reflection_tables:
                joint_reflections.extend(table)
        else:
            joint_reflections = reflection_tables[0]
        logger.info(
            "Saving %s reindexed reflections to %s",
            len(joint_reflections),
            params.output.reflections,
        )
        joint_reflections.as_file(params.output.reflections)

    if params.output.html and params.systematic_absences.check:
        ScrewAxisObserver().generate_html_report(params.output.html)