1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! A-priori hypotheses for the WSJT 77-bit family: which configurations
//! to try, and what bits each one locks.
//!
//! **This module used to own a decoder as well**, and that was the
//! problem. `decode_sniper_ap` ran its own per-candidate ladder —
//! refine, spectra, a plain-BP staircase, then AP passes with OSD at
//! depth 2 — parallel to the one `engine::pipeline` runs and shallower
//! than it, with no depth-3/4 escalation and no Top-K rescue. Because
//! AP lived there, reaching AP meant leaving the real ladder: routing a
//! wide-band FT4 decode through it returned 4 decodes where the
//! wide-band engine returns 11 on the WSJT-X golden.
//!
//! AP is now a rung at the end of the wide-band ladder
//! (`engine::pipeline::process_candidate_basic_impl`), which is where
//! WSJT-X has it too — `ft4_decode.f90`'s `npasses = 3 + nappasses(…)`
//! continues the same pass loop rather than starting a second decoder.
//! What remains here is the part that was always this module's own: the
//! hypothesis set, and the mapping from an `ApHint` to locked bits.
//!
//! Typical threshold improvement is 2–4 dB when both call1 and call2 are
//! known (CQ + DX scenario) and can exceed that when a specific response
//! token (RRR / RR73 / 73) is also locked. The blind CQ hypothesis,
//! which needs nothing, is worth about 1.1 dB on FT4's AWGN sweep
//! (`docs/notes/FT4_BENCHMARK.md` §48).
use Vec;
use crate;
use ;
/// Build one AP configuration: derive the mask/values bit vectors from a
/// hint for this protocol's codeword length. Convenience for callers that
/// want to try several hint shapes (full lock, partial lock, …).
///
/// Bound on [`WsjtApCompatible`] keeps callers honest: the hint encodes
/// callsign / grid / report at fixed Wsjt77 bit positions and is meaningless
/// for protocols whose info layout differs (e.g. byte-oriented codecs).
pub
/// Enumerate the multi-pass AP configurations WSJT-X cycles through in
/// sniper mode — the `u8` is a pass-id tag for diagnostics.
///
/// - 9/10/11: full 77-bit lock with `RRR` / `RR73` / `73` (QSO in progress).
/// - 7: CQ + DX call (expected "CQ DXCALL GRID").
/// - 8: my-call + DX call (directed message).
/// - 6: DX call only (partial lock, fallback).
///
/// **FT8 analog for pass 7**: `ft8::decode_block::process_candidates`'s
/// own blind-CQ `Pass 12` (gated by `BLIND_CQ_MIN_NSYNC`) is FT8's
/// bespoke equivalent, independently implemented and tuned — review
/// both when adjusting either (issue #285, split from #192). Unlike
/// the OSD-escalation pair (`osd_escalation_gates` /
/// `Q_NDEEP3_THRESHOLD`), this pass has no single paired numeric
/// threshold to ratchet-test against — `ap_passes` doesn't gate pass 7
/// on an nsync value of its own, so there's nothing here for
/// `BLIND_CQ_MIN_NSYNC` to be asserted equal to. Prose cross-reference
/// only; a future retune of either still needs a human to remember
/// this comment.
pub