Beispiel #1
0
def test_determine_reindex_operator_against_reference():
    """Test that the correct reindex operator is returned by the function."""

    # create a test dataset of random intensities
    data, _ = generate_test_data(
        space_group=sgtbx.space_group_info(symbol="P4").group(), sample_size=1)

    # reindexing operator is a,-b,-c
    op = "a,-b,-c"
    # reindex the data into a new array, so that the function should determine
    # that the same change of basis operator should be applied to give consistent
    # indexing back to the original data.
    reindexed_data = data[0].change_basis(op)

    cb_op = determine_reindex_operator_against_reference(
        data[0], reindexed_data)
    assert cb_op.as_abc() == "a,-b,-c"

    # Repeat but with no reindexing
    cb_op = determine_reindex_operator_against_reference(data[0], data[0])
    assert cb_op.as_abc() == "a,b,c"

    # Test that a Sorry is raised if inconsistent indexing
    data_2, _ = generate_test_data(
        space_group=sgtbx.space_group_info(symbol="P1").group(), sample_size=1)
    with pytest.raises(Sorry):
        cb_op = determine_reindex_operator_against_reference(
            data[0], data_2[0])

    # Test case for a simple space group with no ambiguity
    data, _ = generate_test_data(
        space_group=sgtbx.space_group_info(symbol="P1").group(), sample_size=1)
    cb_op = determine_reindex_operator_against_reference(data[0], data[0])
    assert cb_op.as_abc() == "a,b,c"
Beispiel #2
0
def test_cosym_target(space_group):
    datasets, expected_reindexing_ops = generate_test_data(
        space_group=sgtbx.space_group_info(symbol=space_group).group(),
        sample_size=50)

    intensities = datasets[0]
    dataset_ids = np.zeros(intensities.size() * len(datasets))
    for i, d in enumerate(datasets[1:]):
        i += 1
        intensities = intensities.concatenate(d,
                                              assert_is_similar_symmetry=False)
        dataset_ids[i * d.size():(i + 1) * d.size()] = np.full(d.size(),
                                                               i,
                                                               dtype=int)

    for weights in [None, "count", "standard_error"]:
        print(weights)
        t = target.Target(intensities, dataset_ids, weights=weights)
        m = len(t.sym_ops)
        n = len(datasets)
        assert t.dim == m
        assert t.rij_matrix.shape == (n * m, n * m)
        # x = np.random.rand(n * m * t.dim)
        x = flex.random_double(n * m * t.dim).as_numpy_array()
        f0 = t.compute_functional(x)
        g = t.compute_gradients(x)
        g_fd = t.compute_gradients_fd(x)
        np.testing.assert_allclose(g, g_fd, rtol=2e-3)
        c = t.curvatures(x)
        c_fd = t.curvatures_fd(x, eps=1e-3)
        assert list(c) == pytest.approx(c_fd, rel=0.8e-1)

        if weights == "count":
            # Absolute upper limit on weights
            assert t.wij_matrix.max() <= datasets[0].size()

        minimizer = engine.lbfgs_with_curvs(target=t, coords=x)
        # check functional has decreased and gradients are approximately zero
        f = t.compute_functional(minimizer.coords)
        g = t.compute_gradients(minimizer.coords)
        g_fd = t.compute_gradients_fd(minimizer.coords)
        assert f < f0
        assert pytest.approx(g, abs=1e-3) == [0] * len(g)
        assert pytest.approx(g_fd, abs=1e-3) == [0] * len(g)
Beispiel #3
0
def test_cosym_target(space_group):
    datasets, expected_reindexing_ops = generate_test_data(
        space_group=sgtbx.space_group_info(symbol=space_group).group(),
        sample_size=50)

    intensities = datasets[0]
    dataset_ids = flex.double(intensities.size(), 0)
    for i, d in enumerate(datasets[1:]):
        intensities = intensities.concatenate(d,
                                              assert_is_similar_symmetry=False)
        dataset_ids.extend(flex.double(d.size(), i + 1))

    for weights in [None, "count", "standard_error"]:
        print(weights)
        t = target.Target(intensities, dataset_ids, weights=weights)
        m = len(t.get_sym_ops())
        n = len(datasets)
        assert t.dim == m
        assert t.rij_matrix.all() == (n * m, n * m)
        x = flex.random_double(n * m * t.dim)
        f0, g = t.compute_functional_and_gradients(x)
        g_fd = t.compute_gradients_fd(x)
        for n, value in enumerate(zip(g, g_fd)):
            assert value[0] == pytest.approx(value[1], rel=2e-3), n

        c = t.curvatures(x)
        c_fd = t.curvatures_fd(x, eps=1e-3)
        assert list(c) == pytest.approx(c_fd, rel=0.8e-1)

        assert engine.lbfgs_with_curvs(target=t, coords=x)
        t.compute_functional(x)
        # check functional has decreased and gradients are approximately zero
        f, g = t.compute_functional_and_gradients(x)
        g_fd = t.compute_gradients_fd(x)
        assert f < f0
        assert pytest.approx(g, abs=1e-3) == [0] * len(g)
        assert pytest.approx(g_fd, abs=1e-3) == [0] * len(g)
def test_cosym(
    space_group,
    unit_cell,
    dimensions,
    sample_size,
    use_known_space_group,
    use_known_lattice_group,
    best_monoclinic_beta,
    run_in_tmpdir,
):
    import matplotlib

    matplotlib.use("Agg")

    datasets, expected_reindexing_ops = generate_test_data(
        space_group=sgtbx.space_group_info(symbol=space_group).group(),
        unit_cell=unit_cell,
        unit_cell_volume=10000,
        d_min=1.5,
        map_to_p1=True,
        sample_size=sample_size,
        seed=1,
    )
    expected_space_group = sgtbx.space_group_info(symbol=space_group).group()

    params = phil_scope.extract()
    params.dimensions = dimensions
    params.best_monoclinic_beta = best_monoclinic_beta
    if use_known_space_group:
        params.space_group = expected_space_group.info()
    if use_known_lattice_group:
        params.lattice_group = expected_space_group.info()

    params.normalisation = None
    cosym = CosymAnalysis(datasets, params)
    cosym.run()
    d = cosym.as_dict()
    if not use_known_space_group:
        assert d["subgroup_scores"][0]["likelihood"] > 0.89
        assert (sgtbx.space_group(d["subgroup_scores"][0]["patterson_group"])
                == sgtbx.space_group_info(
                    space_group).group().build_derived_patterson_group())
        expected_sg = (sgtbx.space_group_info(
            space_group).group().build_derived_patterson_group())
    else:
        expected_sg = sgtbx.space_group_info(space_group).group()
    assert cosym.best_subgroup["best_subsym"].space_group() == expected_sg
    assert len(cosym.reindexing_ops) == len(expected_reindexing_ops)

    space_group_info = cosym.best_subgroup["subsym"].space_group_info()
    reference = None
    for d_id, cb_op in enumerate(cosym.reindexing_ops):
        reindexed = (datasets[d_id].change_basis(
            sgtbx.change_of_basis_op(cb_op)).customized_copy(
                space_group_info=space_group_info.change_basis(
                    cosym.cb_op_inp_min.inverse())))
        assert reindexed.is_compatible_unit_cell(), str(
            reindexed.crystal_symmetry())
        if reference:
            assert (reindexed.correlation(
                reference, assert_is_similar_symmetry=False).coefficient() >
                    0.99)
        else:
            reference = reindexed
def test_cosym(
    space_group,
    unit_cell,
    dimensions,
    sample_size,
    use_known_space_group,
    use_known_lattice_group,
    best_monoclinic_beta,
    run_in_tmpdir,
):
    import matplotlib

    matplotlib.use("Agg")

    datasets, expected_reindexing_ops = generate_test_data(
        space_group=sgtbx.space_group_info(symbol=space_group).group(),
        unit_cell=unit_cell,
        unit_cell_volume=10000,
        d_min=1.5,
        map_to_p1=True,
        sample_size=sample_size,
        seed=1,
    )
    expected_space_group = sgtbx.space_group_info(symbol=space_group).group()

    params = phil_scope.extract()
    params.cluster.n_clusters = len(expected_reindexing_ops)
    params.dimensions = dimensions
    params.best_monoclinic_beta = best_monoclinic_beta
    if use_known_space_group:
        params.space_group = expected_space_group.info()
    if use_known_lattice_group:
        params.lattice_group = expected_space_group.info()

    params.normalisation = None
    cosym = CosymAnalysis(datasets, params)
    cosym.run()
    d = cosym.as_dict()
    if not use_known_space_group:
        assert d["subgroup_scores"][0]["likelihood"] > 0.89
        assert (sgtbx.space_group(d["subgroup_scores"][0]["patterson_group"])
                == sgtbx.space_group_info(
                    space_group).group().build_derived_patterson_group())

    reindexing_ops = {}
    for dataset_id in cosym.reindexing_ops.keys():
        if 0 in cosym.reindexing_ops[dataset_id]:
            cb_op = cosym.reindexing_ops[dataset_id][0]
            reindexing_ops.setdefault(cb_op, set())
            reindexing_ops[cb_op].add(dataset_id)

    assert len(reindexing_ops) == len(expected_reindexing_ops)

    if use_known_space_group:
        expected_sg = sgtbx.space_group_info(space_group).group()
    else:
        expected_sg = (sgtbx.space_group_info(
            space_group).group().build_derived_patterson_group())
    assert cosym.best_subgroup["best_subsym"].space_group() == expected_sg

    space_group_info = cosym.best_subgroup["subsym"].space_group_info()
    for cb_op, ridx_set in reindexing_ops.items():
        for expected_set in expected_reindexing_ops.values():
            assert (len(ridx_set.symmetric_difference(expected_set))
                    == 0) or (len(ridx_set.intersection(expected_set)) == 0)
        for d_id in ridx_set:
            reindexed = (datasets[d_id].change_basis(
                sgtbx.change_of_basis_op(cb_op)).customized_copy(
                    space_group_info=space_group_info.change_basis(
                        cosym.cb_op_inp_min.inverse())))
            assert reindexed.is_compatible_unit_cell(), str(
                reindexed.crystal_symmetry())
Beispiel #6
0
def test_cosym(
    space_group,
    unit_cell,
    dimensions,
    sample_size,
    use_known_space_group,
    use_known_lattice_group,
    run_in_tmpdir,
):
    import matplotlib

    matplotlib.use("Agg")

    datasets, expected_reindexing_ops = generate_test_data(
        space_group=sgtbx.space_group_info(symbol=space_group).group(),
        unit_cell=unit_cell,
        unit_cell_volume=10000,
        d_min=1.5,
        map_to_p1=True,
        sample_size=sample_size,
    )
    expected_space_group = sgtbx.space_group_info(symbol=space_group).group()

    # Workaround fact that the minimum cell reduction can occassionally be unstable
    # The input *should* be already the minimum cell, but for some combinations of unit
    # cell parameters the change_of_basis_op_to_minimum_cell is never the identity.
    # Therefore apply this cb_op to the expected_reindexing_ops prior to the comparison.
    cb_op_inp_min = datasets[0].crystal_symmetry(
    ).change_of_basis_op_to_minimum_cell()
    expected_reindexing_ops = {
        (cb_op_inp_min.inverse() * sgtbx.change_of_basis_op(cb_op) *
         cb_op_inp_min).as_xyz(): dataset_ids
        for cb_op, dataset_ids in expected_reindexing_ops.items()
    }

    params = phil_scope.extract()
    params.cluster.n_clusters = len(expected_reindexing_ops)
    params.dimensions = dimensions
    if use_known_space_group:
        params.space_group = expected_space_group.info()
    if use_known_lattice_group:
        params.lattice_group = expected_space_group.info()

    cosym = CosymAnalysis(datasets, params)
    cosym.run()
    d = cosym.as_dict()
    if not use_known_space_group:
        assert d["subgroup_scores"][0]["likelihood"] > 0.89
        assert (sgtbx.space_group(d["subgroup_scores"][0]["patterson_group"])
                == sgtbx.space_group_info(
                    space_group).group().build_derived_patterson_group())

    space_groups = {}
    reindexing_ops = {}
    for dataset_id in cosym.reindexing_ops.keys():
        if 0 in cosym.reindexing_ops[dataset_id]:
            cb_op = cosym.reindexing_ops[dataset_id][0]
            reindexing_ops.setdefault(cb_op, set())
            reindexing_ops[cb_op].add(dataset_id)
        if dataset_id in cosym.space_groups:
            space_groups.setdefault(cosym.space_groups[dataset_id], set())
            space_groups[cosym.space_groups[dataset_id]].add(dataset_id)

    assert len(reindexing_ops) == len(expected_reindexing_ops)
    assert sorted(reindexing_ops.keys()) == sorted(
        expected_reindexing_ops.keys())
    assert len(space_groups) == 1

    if use_known_space_group:
        expected_sg = sgtbx.space_group_info(space_group).group()
    else:
        expected_sg = (sgtbx.space_group_info(
            space_group).group().build_derived_patterson_group())
    assert cosym.best_subgroup["best_subsym"].space_group() == expected_sg

    for cb_op, ridx_set in reindexing_ops.items():
        for expected_set in expected_reindexing_ops.values():
            assert (len(ridx_set.symmetric_difference(expected_set))
                    == 0) or (len(ridx_set.intersection(expected_set)) == 0)
        for d_id in ridx_set:
            reindexed = (datasets[d_id].change_basis(cb_op).customized_copy(
                space_group_info=space_groups.keys()[0].info()))
            assert reindexed.is_compatible_unit_cell(), str(
                reindexed.crystal_symmetry())