rugnux: carry the point-group promotion into the second pass

The two-pass rotation run reinstates pass-1's space group for pass 2's merge, so
pass 2 skips the search block entirely - and with it the flag that records that
the Laue class was CHOSEN by the search rather than given. The canonical output
therefore printed the plain "no twinning: the Laue class is holohedral, so no
merohedral twin law exists", which is exactly the circular conclusion the flag
was added to replace; only the throwaway _01 output carried the caveat.

The text is written per pass, inside RunPipeline, so the flag has to travel with
prepass_merge_sg_ rather than being patched onto the returned result.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-30 10:54:53 +02:00
co-authored by Claude Opus 5
parent 64c8117a96
commit e123755c7d
2 changed files with 11 additions and 1 deletions
+5 -1
View File
@@ -235,6 +235,7 @@ ProcessResult Rugnux::Run(RugnuxObserver *observer) {
force_rotation_result_.reset();
prepass_sg_reindexed_ = false;
prepass_merge_sg_.reset();
prepass_promoted_point_group_ = false;
logger.Info("Rotation two-pass geometry post-refinement: first pass (header geometry) -> {}_01_*",
base_prefix);
@@ -258,6 +259,7 @@ ProcessResult Rugnux::Run(RugnuxObserver *observer) {
// setting the de-novo primitive frame does not share, which is left to re-search.
experiment_.SpaceGroupNumber(std::nullopt);
prepass_merge_sg_ = prepass_sg_reindexed_ ? std::nullopt : pass1.space_group_number;
prepass_promoted_point_group_ = pass1.twinning.laue_class_was_chosen_by_promotion;
logger.Info("Rotation two-pass geometry post-refinement: second pass (refined geometry, canonical) -> {}_*",
base_prefix);
@@ -1206,7 +1208,9 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
// True when the point group below was chosen BY THE SEARCH (rather than given by the user) and is
// above triclinic - i.e. a promotion was made, which is what makes a later "the Laue class is
// holohedral so there is no twin law" conclusion circular.
bool promoted_point_group = false;
// Pass 2 reuses pass-1's group instead of searching, so the promotion it needs to report was
// made there; a first / single pass has no carried-over group and decides this below.
bool promoted_point_group = prepass_merge_sg_.has_value() && prepass_promoted_point_group_;
if (!experiment_.GetGemmiSpaceGroup().has_value()) {
SearchSpaceGroupOptions sg_opts;
sg_opts.merge_friedel = experiment_.GetScalingSettings().GetMergeFriedel();
+6
View File
@@ -179,6 +179,12 @@ class Rugnux {
// the second pass, and for a reindex-derived group (left to re-search).
std::optional<int64_t> prepass_merge_sg_;
// Whether the group in prepass_merge_sg_ was PROMOTED by pass-1's search rather than given. Pass 2
// reuses the group without searching, so it cannot work this out for itself - and without it the
// canonical output reports "the Laue class is holohedral, so no twin law exists" about a Laue class
// the search chose, which is the circular claim that reasoning exists to flag.
bool prepass_promoted_point_group_ = false;
// Stills global geometry-refinement first pass (config_.refine_geometry): index a spread sample of
// frames, bundle-adjust the shared beam/distance/cell from the strongest ones, and apply the result
// to experiment_ so the main pass re-indexes with it. No-op (leaves experiment_ unchanged) if it