80 lines
3.0 KiB
Python
80 lines
3.0 KiB
Python
"""Проверки диагностических вычислений Lab067 без raw IQ и оборудования."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import numpy as np
|
|
|
|
from experiments import lab067_header_failure_analysis as lab067
|
|
|
|
|
|
def test_header_diagnostics_repeats_strict_soft_combining() -> None:
|
|
expected = lab067.lab066.plans()[0].plan.phy_header_bits.astype(np.uint8)
|
|
soft = 2.0 * expected.astype(float) - 1.0
|
|
# Две копии одного бита имеют неверный знак, но малы по модулю. Третья
|
|
# правильная копия сильнее, поэтому штатная мягкая сумма сохраняет бит.
|
|
soft[:2] *= -0.1
|
|
result = lab067.header_diagnostics(soft, expected)
|
|
assert result["raw_header_errors"] == 2
|
|
assert result["voted_header_errors"] == 0
|
|
assert result["accepted"] is True
|
|
|
|
|
|
def test_header_diagnostics_reports_field_and_copy_errors() -> None:
|
|
expected = lab067.lab066.plans()[0].plan.phy_header_bits.astype(np.uint8)
|
|
received = expected.copy()
|
|
received[24:26] ^= 1
|
|
result = lab067.header_diagnostics(
|
|
2.0 * received.astype(float) - 1.0,
|
|
expected,
|
|
)
|
|
assert result["raw_header_errors"] == 2
|
|
assert result["copy_errors"] == [1, 1, 0]
|
|
assert result["voted_header_errors"] == 1
|
|
assert result["magic_errors"] == 1
|
|
assert result["accepted"] is False
|
|
|
|
|
|
def test_strict_candidate_selection_uses_nearest_expected_position() -> None:
|
|
rows = [
|
|
{"absolute_refined": 980, "packet_output": False, "crc": False, "fec": False, "header": False},
|
|
{"absolute_refined": 1003, "packet_output": False, "crc": False, "fec": False, "header": True},
|
|
]
|
|
selected = lab067.strict_candidate_for_packet(rows, 1000)
|
|
assert selected is rows[1]
|
|
|
|
|
|
def test_strict_candidate_selection_never_prefers_farther_success() -> None:
|
|
exact_failure = {
|
|
"absolute_refined": 1000, "packet_output": False,
|
|
"crc": False, "fec": False, "header": False,
|
|
}
|
|
farther_success = {
|
|
"absolute_refined": 1064, "packet_output": True,
|
|
"crc": True, "fec": True, "header": True,
|
|
}
|
|
selected = lab067.strict_candidate_for_packet(
|
|
[farther_success, exact_failure], 1000
|
|
)
|
|
assert selected is exact_failure
|
|
|
|
|
|
def test_strict_candidate_tie_break_does_not_use_verdict() -> None:
|
|
lower_failure = {
|
|
"absolute_refined": 999, "packet_output": False,
|
|
"crc": False, "fec": False, "header": False,
|
|
}
|
|
upper_success = {
|
|
"absolute_refined": 1001, "packet_output": True,
|
|
"crc": True, "fec": True, "header": True,
|
|
}
|
|
selected = lab067.strict_candidate_for_packet(
|
|
[upper_success, lower_failure], 1000
|
|
)
|
|
assert selected is lower_failure
|
|
|
|
|
|
def test_lab067_has_no_rf_entry_point() -> None:
|
|
assert not hasattr(lab067, "capture_once")
|
|
assert lab067.RX_PATH.name == "rx_stream.cs8"
|
|
assert lab067.FAILED_PACKETS == {1, 2, 3, 9, 15, 16}
|