diff --git a/rugnux/RugnuxFirstPass.cpp b/rugnux/RugnuxFirstPass.cpp index b0fc41f99..0feb426d9 100644 --- a/rugnux/RugnuxFirstPass.cpp +++ b/rugnux/RugnuxFirstPass.cpp @@ -746,8 +746,8 @@ bool Rugnux::FirstPassRotationIndexing(PipelineLocals &p) { {"spread", spread_ordinals}, {"wedge", all_consecutive}, }; - // A third sample of the same frames, asked only when the two above index no majority (see - // pick_best): the wedge read back from the END of the first part. Which orientations a sweep + // A third sample of the same frames, asked only when nothing else indexes a majority (see + // add_end_wedge): the wedge read back from the END of the first part. Which orientations a sweep // passes through first is chance, and the first part can open on frames that see the long axis // badly - measured on a sparse crystal with a ~390 A axis, the spread and the wedge over its // first 120 deg returned wrong cells (5/60 and 0/60 validation frames) at every spread density @@ -982,9 +982,14 @@ bool Rugnux::FirstPassRotationIndexing(PipelineLocals &p) { return bp; }; - // Where the schemes index no majority of the validation frames, the end wedge is asked too and - // judged against them as any later scheme is. Only then: on a run the schemes index it would be - // one more lattice for the axis-harmonic arbiter, which is not decided on frame counts. + // Where the first pass indexes no majority of the validation frames, the end wedge is asked too + // and judged against the standing pass as any later scheme is. Only then: on a run the schemes + // index it would be one more lattice for the axis-harmonic arbiter, which is not decided on + // frame counts. Asked once, after the axis-sign, beam-centre and long-axis rescues (below), not + // inside every pass they run: a consecutive wedge indexes part of the validation frames at the + // WRONG axis sign too (measured: 33/60 where the spread at the right sign indexes 60/60), and + // counted in the pass a rescue is gated on, it lifts that pass past the gate and the rescue + // that would have indexed every frame is never asked. auto add_end_wedge = [&](FirstPass bp, IndexerThreadPool &pool, IndexAndRefine &idx) -> FirstPass { if (cancelled_ || bp.score > static_cast(validation.size()) / 2) return bp; @@ -994,7 +999,7 @@ bool Rugnux::FirstPassRotationIndexing(PipelineLocals &p) { return score_schemes(ris, idx, &end_wedge, std::move(bp)); }; - // Feed the schemes, index them concurrently, and keep the best (score_schemes, add_end_wedge). + // Feed the schemes, index them concurrently, and keep the best (score_schemes). // alongside: started once the schemes are fed and before they are indexed, to run beside them. auto pick_best = [&](IndexerThreadPool &pool, IndexAndRefine &idx, const std::function &alongside = {}) -> FirstPass { @@ -1005,7 +1010,7 @@ bool Rugnux::FirstPassRotationIndexing(PipelineLocals &p) { for (const auto &ri : ris) rp.push_back(ri.get()); run_indexing(rp); - return add_end_wedge(score_schemes(ris, idx), pool, idx); + return score_schemes(ris, idx); }; // Powder-ring rescue - and, with it, the lean seed the rotation first pass never had. @@ -1677,7 +1682,7 @@ bool Rugnux::FirstPassRotationIndexing(PipelineLocals &p) { entries.emplace_back(centre_spec->key, centre_spec->spots); } } - alt = add_end_wedge(score_schemes(centre_spec->ris, *indexer), *indexer_pool, *indexer); + alt = score_schemes(centre_spec->ris, *indexer); } else alt = pick_best(*indexer_pool, *indexer); centre_spec.reset(); @@ -2044,6 +2049,8 @@ bool Rugnux::FirstPassRotationIndexing(PipelineLocals &p) { if (!long_axis_asked) if (auto rescued = long_axis_rescue(best)) best = *rescued; + // The end wedge (above), at the geometry the rescues settled on. + best = add_end_wedge(std::move(best), *indexer_pool, *indexer); release_spot_engines(); // no more frames to read; give the cards their memory back if (!cancelled_) {