Merge branch 'c-screw-undetermined' into pool-C

This commit is contained in:
leonarski_f committed 2026-09-20 18:45:17 +02:00
commit 508fcfb400
8 files changed
+281 -2

No files matched your search

+48
View File
@@ -446,6 +446,54 @@ TEST_CASE("SearchSpaceGroup names an orthorhombic screw pair on the axes it lies
}
}
// A screw on a row the sweep never recorded is not a group the data refused, it is a question
// nobody asked: the run writes the member claiming no screw because a reflection file must carry
// one group, and without this the only trace of the ambiguity is a list of names that does not say
// which axis is open. Modelled on a real hexagonal set whose 00l row lies in the spindle's blind
// cone and which is reported as P 6 against a deposited P 63.
TEST_CASE("SearchSpaceGroup says which axis a missing row left the screw open on",
"[SearchSpaceGroup]") {
const gemmi::SpaceGroup& sg = gemmi::get_spacegroup_by_name("P 21 21 21");
const auto merged = GenerateMergedReflectionsForSpaceGroup(sg, 14);
SearchSpaceGroupOptions opt;
opt.merge_friedel = true;
opt.lattice_system = gemmi::CrystalSystem::Orthorhombic;
SECTION("every row measured - nothing is open") {
const auto result = SearchSpaceGroup(merged, opt);
INFO(SearchSpaceGroupResultToText(result));
REQUIRE(result.best_space_group.has_value());
CHECK(result.best_space_group->xhm() == "P 21 21 21");
CHECK(result.undetermined_screws.empty());
}
SECTION("the 00l row removed - the c screw is undetermined") {
std::vector<MergedReflection> without_00l;
for (const auto& r : merged)
if (r.h != 0 || r.k != 0)
without_00l.push_back(r);
const auto result = SearchSpaceGroup(without_00l, opt);
INFO(SearchSpaceGroupResultToText(result));
REQUIRE(result.best_space_group.has_value());
REQUIRE(result.undetermined_screws.size() == 1);
CHECK(result.undetermined_screws[0].axis == 'c');
CHECK(result.undetermined_screws[0].row_label == "00l");
CHECK(result.undetermined_screws[0].n_observed == 0);
// The a and b screws were measured and are unaffected: what the missing row costs is the
// third condition, not the two the data still carry.
CHECK(result.best_space_group->operations().is_systematically_absent({{1, 0, 0}}));
CHECK(result.best_space_group->operations().is_systematically_absent({{0, 1, 0}}));
// ...and the group the c row would have decided between is offered, not silently dropped.
bool offers_a_group_without_the_c_screw = false;
for (const auto& alt : result.alternatives)
if (!alt.operations().is_systematically_absent({{0, 0, 1}}))
offers_a_group_without_the_c_screw = true;
CHECK((offers_a_group_without_the_c_screw
|| !result.best_space_group->operations().is_systematically_absent({{0, 0, 1}})));
}
}
// The centring half of the same widening. A, B and C centring on one orthorhombic cell are three
// different lattices, and only C is a reference setting, so an A-centred crystal used to have its
// centring refused (its absent class is not the one C predicts) and came out primitive. The