From dc92359f0940defac5ce815e56faf8b333bcfdaf Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Fri, 9 Oct 2026 09:13:43 +0200 Subject: [PATCH] Revert "rugnux: the first pass takes the larger of two domains of one lattice" This reverts commit c5a13d212. The second-domain test fixed its target (a low-ISa insulin set) but was evaluated 1132 times on 212 battery sets and adopted a "second domain" on 50 of them; three sets that passed went to fail (5j23, 9qw2 and one private set: F432 -> P432). It never asks whether the other domain is a different orientation, so near-ties at 54:46 decide it. A narrowed version (regr2-domain) still costs about 120-200 s battery-wide for one difficult set. It is parked for rc176, where near-tie domains are to be carried as two hypotheses and decided late. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01SVmAWnzCmRKAXVUCdc4iNi --- rugnux/RugnuxFirstPass.cpp | 61 -------------------------------------- 1 file changed, 61 deletions(-) diff --git a/rugnux/RugnuxFirstPass.cpp b/rugnux/RugnuxFirstPass.cpp index daac51a31..b0fc41f99 100644 --- a/rugnux/RugnuxFirstPass.cpp +++ b/rugnux/RugnuxFirstPass.cpp @@ -2407,67 +2407,6 @@ bool Rugnux::FirstPassRotationIndexing(PipelineLocals &p) { best = *rescued; } - // A second domain of the same lattice. Two twin domains, or two crystals of one cell, each - // index every validation frame, so the frame count cannot say which of them is the crystal, - // and the FFT returns whichever its sample happens to favour. On the first part of a sweep - // that can be the domain there is less of (measured: an I-centred cubic crystal with a second - // domain at 60 deg about [111] took the smaller one; integrated, it carried the larger one's - // intensity on every reflection the two share, which broke the cubic 2-folds and merged in - // R3). So the spots the lattice leaves on the spread frames are indexed again, as the - // leftover-lattice census below does, and where they give the same lattice in another - // orientation, the two are judged on the validation spots each puts on itself. - if (!cancelled_ && best.result.has_value()) { - indexer->ForceRotationIndexerResult(*best.result); - prefetch_spots(spread_ordinals); - std::vector> left(spread_ordinals.size()); - ParallelFor(static_cast(spread_ordinals.size()), - std::min(spread_ordinals.size(), config_.nthreads), [&](int i) { - const auto &sp = spot_cache.at(spread_ordinals[i]); - DataMessage m{}; - m.number = spread_ordinals[i]; - m.spots = sp; - indexer->CountSpotsOnLattice(m, validation_settings); - for (size_t k = 0; k < sp.size(); k++) - if (m.spots.size() != sp.size() || !(m.spots[k].indexed && m.spots[k].lattice == 0)) - left[i].push_back(sp[k]); - }); - RotationIndexer leftover(experiment_, *indexer_pool); - leftover.MaxSpotsPerImage(first_pass_spots_per_image); - leftover.VerifyMemo(config_.verify_first_pass_memo); - for (size_t i = 0; i < spread_ordinals.size() && !leftover.AccumulationFull(); i++) - leftover.ProcessImage(spread_ordinals[i], left[i], rot_angle(spread_ordinals[i])); - leftover.RunIndexing(); - const auto reduced_edges = [](const RotationIndexerResult &r) { - const auto uc = r.lattice.ToPrimitive(r.search_result.centering).NiggliReduce().GetUnitCell(); - std::array e = {uc.a, uc.b, uc.c}; - std::sort(e.begin(), e.end()); - return e; - }; - if (auto other = leftover.GetLattice()) { - const auto e1 = reduced_edges(*best.result); - const auto e2 = reduced_edges(*other); - bool same_lattice = true; - for (int i = 0; i < 3; i++) - same_lattice = same_lattice && std::abs(e2[i] - e1[i]) <= 0.02 * e1[i]; - if (same_lattice) { - const PooledEvidence e_best = pooled_evidence(*indexer, *best.result); - const PooledEvidence e_other = pooled_evidence(*indexer, *other); - const bool adopt = ValidationEvidencePrefers(e_best, e_other); - logger.Info("Second domain: the spots the lattice leaves give the same lattice in " - "another orientation, which puts {}/{} validation spots on itself ({} at " - "a wrong spindle angle) against the lattice's {}/{} ({}) - {}", - e_other.on_lattice, e_other.spots, e_other.by_chance, e_best.on_lattice, - e_best.spots, e_best.by_chance, - adopt ? "it is the crystal, adopting it" : "keeping the lattice"); - if (adopt) { - best.result = std::move(*other); - best.score = count_indexed(*indexer, *best.result); - best.name += " (second domain)"; - } - } - } - } - // Whether the run has a lattice at all is decided here, on the pooled spots rather than on // the frame count the rescues above are steered by. A frame count asks each frame to clear // a bar of its own and then counts the frames that did, which measures the spots per frame