rugnux: a fixed primitive space group on a lattice indexed as centred is merged as asked, with a warning
Build Packages / Create release (push) Successful in 8s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Canceled after 10m17s
Build Packages / Validation Battery (push) Canceled after 0s
Build Packages / build:jfjoch:rocky8:cuda (push) Canceled after 0s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Canceled after 10m33s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Canceled after 0s
Build Packages / Build documentation (push) Successful in 45s
Build Packages / build:portable:macos-arm64:nocuda (push) Successful in 5m47s
Build Packages / build:portable:linux-x86_64:cuda (push) Canceled after 10m19s
Build Packages / build:portable:linux-x86_64:nocuda (push) Canceled after 10m21s
Build Packages / Unit tests (push) Canceled after 10m35s
Build Packages / build:jfjoch:rocky9:cuda (push) Canceled after 0s
Build Packages / build:jfjoch:rocky9:nocuda (push) Canceled after 9m38s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Canceled after 0s
Build Packages / build:jfjoch:rocky8:nocuda (push) Canceled after 10m15s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Canceled after 0s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Canceled after 0s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Canceled after 0s
Build Packages / Generate python client (push) Canceled after 0s
Build Packages / build:portable:windows-x86_64:cuda (push) Canceled after 10m10s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Canceled after 0s
Build Packages / build:portable:windows-x86_64:nocuda (push) Canceled after 10m10s

The check that a user-fixed space group fits the indexed lattice refused every centring mismatch. A
primitive group on a centred lattice is not a frame conflict: with a fixed group prediction runs in
that group's centring, so the reflections the lattice centring would extinguish are integrated on the
conventional cell and the merge in the group's frame is well defined. The group is the user's choice,
so the run now warns - naming the centred lattice and cell the indexing found - and merges in it.
A centred group on a lattice that does not carry it, and a cell the group's operators do not leave
invariant, still stop the run: there the reflections are not in the group's frame (completeness above
100 % is the measured symptom).

Measured: a monoclinic P crystal whose first pass was labelled C (without the indexer fix) now merges in
P 1 21 1, 100 % complete; a genuinely C-centred monoclinic crystal run with -S P2 warns and merges in P2,
95 % complete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK
This commit is contained in:
leonarski_fandClaude Opus 5.5 committed 2026-11-10 18:07:57 +01:00
1 parent 35f49a295d
commit a7adff181a
2 files changed
+23 -3

No files matched your search

+3 -1
View File
@@ -138,7 +138,9 @@ into the merged files.
Run **fully de novo** (no `-C`/`-S`) for the best result — supplying a cell or space group up front
tends to *degrade* low-symmetry cases. A `-S` group whose Bravais lattice the crystal turns out not to
have stops the run and names the cell that was indexed, rather than merging in a frame the reflections
are not in; where the lattice does have that group's setting, the reflections are reindexed into it. `--scaling-high-resolution` (set it to your expected
are not in; where the lattice does have that group's setting, the reflections are reindexed into it.
A primitive `-S` group on a lattice indexed as centred is the exception: it is merged as asked, with a
warning. `--scaling-high-resolution` (set it to your expected
resolution) sharpens both the space-group search and the error model. To tune the first pass use
`--two-pass-rotation=100` (or `-R100` — the first-pass image count); to force the sweep to be
treated as independent stills use `--force-still`.
+20 -2
View File
@@ -1223,8 +1223,26 @@ bool Rugnux::ScaleMergeAndSymmetry(PipelineLocals &p) {
// question that was not asked. Name the cell that WAS indexed so the user can act on it.
if (user_fixed_sg_ && end_msg.rotation_lattice_type.has_value() && end_msg.unit_cell.has_value()) {
const gemmi::SpaceGroup &fixed_sg = *user_fixed_sg_;
const bool centring_wrong =
end_msg.rotation_lattice_type->centering != fixed_sg.centring_type();
// A PRIMITIVE group on a lattice indexed as centred is not that conflict: the reflections are
// integrated on the conventional cell, so the group's frame is theirs and its arithmetic holds;
// it only keeps the reflections the centring would extinguish. Whether those are absent is the
// data's to say, and the user chose the group - so warn, and merge in it.
const bool primitive_on_centred = fixed_sg.centring_type() == 'P'
&& end_msg.rotation_lattice_type->centering != 'P';
if (primitive_on_centred) {
const auto &uc = *end_msg.unit_cell;
logger.Warning("The space group {} was fixed for this run and is primitive, but the indexing "
"found a {}-centred {} lattice (a={:.3f} b={:.3f} c={:.3f} alpha={:.2f} "
"beta={:.2f} gamma={:.2f}): merging in {} as asked. If the centring is real, "
"the reflections it extinguishes merge to noise; if they are only weak, a "
"pseudo-translation is the likely reason. Without -S the space-group search "
"decides it from the intensities",
fixed_sg.xhm(), end_msg.rotation_lattice_type->centering,
gemmi::crystal_system_str(end_msg.rotation_lattice_type->crystal_system),
uc.a, uc.b, uc.c, uc.alpha, uc.beta, uc.gamma, fixed_sg.xhm());
}
const bool centring_wrong = !primitive_on_centred
&& end_msg.rotation_lattice_type->centering != fixed_sg.centring_type();
// The same two tests as the re-seating above, asked again now that it has had its chance.
const double violation = MetricViolation(*end_msg.unit_cell, fixed_sg);
if (centring_wrong || violation > MAX_METRIC_VIOLATION) {