diff --git a/docs/RUGNUX_TUTORIAL.md b/docs/RUGNUX_TUTORIAL.md index 56c6e0977..bfdb25d02 100644 --- a/docs/RUGNUX_TUTORIAL.md +++ b/docs/RUGNUX_TUTORIAL.md @@ -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`. diff --git a/rugnux/RugnuxScaleMerge.cpp b/rugnux/RugnuxScaleMerge.cpp index 6478ebcd9..dbf89d206 100644 --- a/rugnux/RugnuxScaleMerge.cpp +++ b/rugnux/RugnuxScaleMerge.cpp @@ -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) {