RESULT-CHANGING: post-refinement fits the lattice in the fixed space group's setting

With -S (or a group taken from --model / -z), ScaleMergeAndSymmetry re-seats the integrated
reflections into the fixed group's Bravais setting when the indexed lattice's centring or metric
does not carry it - but the rotation geometry post-refinement was then handed the indexer's lattice
in the OLD setting beside the re-seated indices. Every Miller index was predicted against the wrong
basis: the held-out residual started ~5 orders of magnitude above a de-novo run's, the joint fit used
every step and "never settled", the rotation scale ran to its 0.95 bound, the detector geometry
(including a ~6 px header beam-centre error) was left at the header, and the end of the sweep was
then rejected as radiation damage.

The lattice now goes across with the reflections (the same composed change of basis the reflections
received), and the fit is parameterised in the class it is now held to. Runs without a fixed group
never re-seat before the post-refinement and are unchanged.

Measured on a split-domain C2 crystal with a ~6 px header beam-centre error: -S, -S -C and
--model -z now commit the post-refinement, move the centre as the de-novo run does, reject no
frames and reach ISa ~15 (was ~12.3), matching the de-novo run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVeDQqN9qRD57vnShzTC37
This commit is contained in:
leonarski_fandClaude Opus 5.5 committed 2026-10-28 11:01:15 +01:00
1 parent 4b9ef226ef
commit 56216050bf
1 file changed
+10 -1
+10 -1
View File
@@ -975,13 +975,22 @@ bool Rugnux::ScaleMergeAndSymmetry(PipelineLocals &p) {
}
}
if (result.consensus_cell.has_value()) {
const auto rot = indexer->FinalizeRotationIndexing();
auto rot = indexer->FinalizeRotationIndexing();
indexer->RethrowIndexerError();
if (rot && rot->axis) {
if (geometry_prepass)
prepass_result_ = *rot; // full result (lattice+geom+axis), for the supercell fallback
PostRefineSettings prs;
prs.crystal_system = rot->search_result.system;
// The reflections were re-seated into the fixed space group's setting above, so the
// lattice they are fitted against has to go across with them, in the class it is now
// held to. Left in the indexer's setting, every index was another reflection's: on a
// P-indexed lattice reseated into C2 the held-out residual started 5 orders of magnitude
// above the bare run's, the fit never settled and the header's centre error stayed.
if (end_msg.reindex_matrix) {
rot->lattice = rot->lattice.Multiply(stored_to_final);
prs.crystal_system = end_msg.rotation_lattice_type->crystal_system;
}
prs.num_threads = static_cast<int>(config_.nthreads);
prs.refine_geometry = true;
// Only a pass still at the file's distance can hold it as a hypothesis; a pass