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"
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)
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())
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())