6 Commits

Author SHA1 Message Date
LittleSam129
af7c05f2da Lab067: localize remaining PHY header failures 2026-09-15 17:45:38 +03:00
LittleSam129
b27a5cf00e Lab066: validate 500 ksymbol/s full-packet OTA reception 2026-09-15 15:51:57 +03:00
LittleSam129
dacf04f2d0 Lab065: validate OTA gain improvement at TX VGA 20 dB 2026-09-15 13:42:08 +03:00
LittleSam129
cff226e0bf Lab064: measure OTA level linearity at TX VGA 10 dB 2026-09-15 12:03:48 +03:00
LittleSam129
4437917465 Lab063: localize Lab062 RF quality degradation offline 2026-09-14 15:11:46 +03:00
LittleSam129
f8ae6c6bfc Lab062: record invalidated 500 ksymbol/s RF packet trial 2026-09-14 13:58:42 +03:00
81 changed files with 67037 additions and 0 deletions

View File

@@ -2661,3 +2661,343 @@ READY_BEHIND_EXPLICIT_MODE до отдельного контролируемо
500K-пакетами. Оборудование не опрашивалось, RF TX=0. Lab061 фиксируется этим 500K-пакетами. Оборудование не опрашивалось, RF TX=0. Lab061 фиксируется этим
отдельным коммитом; push выполняется пользователем отдельно. Следующий этап: отдельным коммитом; push выполняется пользователем отдельно. Следующий этап:
STOP; Lab062 автоматически не начинать. STOP; Lab062 автоматически не начинать.
# Запись 056
## Дата
14 сентября 2026 года
## Тема
Lab062 — подготовка полного пакета 500K и аппаратный RX-only preflight
## Выполнено
От HEAD 25cc89f0c734f77141632d19dbcdb6b2f066d60b подготовлен один waveform
из16 полных PHY-пакетов по256 байт payload:1476096 отсчётов,0,184512с,
SHA-256 e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5.
Строгий программный roundtrip legacy/T2 дал16/16 HEADER/FEC/CRC и точных
payload в исходном порядке. Quick gate:962 теста ядра,35 функциональных
проверок,13 пропусков; pytest:962 passed,0 failed.
Фактическая схема:1400МГц,500ксимв/с, Fs8Мвыб/с, расстояние примерно1,2м,
LOS в помещении; TX возле окна, RX на столе, одинаковая поляризация. Антенны,
кабели и USB-схема неподвижны. Усиления сохранены: TX VGA10дБ, RX LNA/VGA
24/24дБ, RF amplifier и Bias-Tee OFF. Общая опора:10МГц TCXO → MASTER →
MASTER CLKOUT → SLAVE CLKIN, длинный кабель сохранён.
Один аппаратный RX-only preflight подтвердил MASTER/SLAVE reg29=0x26 и SLAVE
CLKIN=DETECTED на втором опросе через133,5795мс. Записано800000 отсчётов фона:
полный RMS2,314058, AC RMS0,985483 кода, max|I|/|Q|=6/8, clipping0/800000,
RX overruns0, неожиданно сильного сигнала нет. Отсутствие аналоговой компрессии
этим не доказано. CLKOUT выключены без ошибок, процессы до/после CLEAR.
RF TX=0, TX-команд не было, усиления не менялись, preflight не повторялся.
Lab062 не коммитировалась, push не выполнялся. Следующий этап: STOP и ожидание
отдельного явного разрешения на единственный Lab062 TX; Lab063 не начинать.
# Запись 057
## Дата
14 сентября 2026 года
## Тема
Lab062 — единственный RF-сеанс полного пакета 500K и сравнение legacy/T2
## Выполнено
После отдельного разрешения пользователя выполнен один TX-сеанс подготовленного потока из 16
полных PHY-пакетов. Перед TX повторная проверка подтвердила MASTER/SLAVE reg29=0x26 и SLAVE
CLKIN=DETECTED. Автоматических и ручных повторов не было. RX сохранил 24 000 000 комплексных
отсчётов за 3,000 с, 48 000 000 байт, SHA-256
ce0bd603e4ca356af67d504ee11c9e9f38171f31c7427fbe61216a28126b2b32; overruns0 и clipping0.
В промежуточной строке TX-журнала зарегистрирован один underrun длиной до16672 байт, хотя
итоговая строка утилиты сообщила0. Ненулевое наблюдение сохранено, сеанс признан
`INVALID_TX_UNDERRUN`, повтор запрещён и не выполнялся. Cleanup прошёл без ошибок, SDR-процессы
после сеанса CLEAR, RF TX=0.
Одна и та же RX-запись независимо обработана строгими режимами legacy и T2 без fallback. Оба
получили144 строгих кандидата,3 прохода PHY header,3 запуска и прохода FEC,3 запуска CRC,0 CRC
PASS и0/16 пакетов. T2 gain равен0. Диагностические границы всех16 пакетов найдены только после
строгого вердикта и не передавались приёмнику. По сопоставимой методике Lab058 средняя доля
ошибочных символов равна0,099287, EVM1,220401, matched/residual−1,730051дБ, медианная
неравномерность полосы p95–p05 равна6,660341дБ. Эти значения хуже Lab056 B, но их нельзя
отделить от TX underrun.
Lab062 не коммитировалась, push не выполнялся, Lab063 не создана. Следующий этап: RF TX=0 и
отдельно согласовать только офлайн-локализацию underrun относительно границ пакетов.
# Запись 058
## Дата
14 сентября 2026 года
## Тема
Lab063: офлайн-локализация TX underrun и глобального ухудшения Lab062
## Выполнено
Lab062 зафиксирована отдельным коммитом
f8ae6c6bfceaa21b6c08dcf55d2bff996dd0dae5 с сообщением
`Lab062: record invalidated 500 ksymbol/s RF packet trial`; push не выполнялся. Статус
`RF_SESSION_INVALID_TX_UNDERRUN`, результаты legacy/T2 0/16 и запрет повтора сохранены.
По сохранённым TX/RX без аппаратных команд установлено, что 16 waveform по 92 256 отсчётов
записаны вплотную: 92 256 × 16 = 1 476 096. Дополнительная межпакетная пауза равна нулю.
`prepare()` не передаёт параметр паузы и не пишет нули между packet waveform, поэтому отсутствие
обещанных 5 мс признано ошибкой реализации подготовки Lab062. Внутренние защитные участки и
хвосты RRC каждого пакета сохранены.
Строка `longest 16672 bytes` пересчитана в 8 336 комплексных отсчётов, 1,042 мс, 521 символ и
9,035727% одного packet waveform. Это масштаб сообщения, а не доказанное число потерянных или
повторённых RF-отсчётов. Локальное сопоставление 512-символьными окнами с шагом 256 символов
дало 221 надёжное окно из 359. Задержка в них равна 0…1 отсчёту, скачков нет; место underrun по
RX не локализовано. В 22 дополнительных внутренних окнах пакетов3,4,12,13 корреляция ниже0,15,
поэтому задержка там не установлена. Края, повторяющаяся PRBS-преамбула и низкокорреляционные
окна исключены из delay-verdict, но сохранены в CSV. Корреляционные копии преамбулы имеют период
2 032 отсчёта.
Все 16 пакетов хуже Lab056 B по SER, EVM и matched/residual. SER составляет
7,580920…16,013629%, EVM 1,063657…1,663418, matched/residual от −4,420028 до
−0,536031дБ. Пакеты 3,4,12,13 выделяются всплесками AC-мощности и остатка при стабильной
медиане локального |h| 0,004488…0,004805. Пакет14 не имеет общего с ними физического признака.
Результат классифицирован как `GLOBAL_RF_DEGRADATION`; один локальный underrun недостаточен для
объяснения качества всего сеанса.
AC RMS по пакетам равен0,760816…2,032438 кода, max|I|/|Q| лежат в диапазонах3…6/4…7,
DC стабилен. Сильная аналоговая перегрузка по цифровым уровням менее вероятна, но без прибора не
исключена. Локального исходного файла или документации, объясняющей расхождение промежуточного и
итогового счётчиков `hackrf_transfer`, не найдено; `COUNTER SEMANTICS=NOT_ESTABLISHED`.
Созданы постановка, отчёт, JSON, два CSV, восемь графиков, анализатор и тесты. Lab063 выполнена
полностью офлайн, RF TX=0, оборудование не опрашивалось. Lab063 не коммитировалась, push не
выполнялся. Следующий этап: STOP и отдельно согласовать исследование уровня RX, усилений,
геометрии и возможной аналоговой компрессии или слабого полезного сигнала; Lab064 автоматически
не создавать.
# Запись 059
## Дата
14 сентября 2026 года
## Тема
Lab064: подготовка измерения уровня и линейности, RX-only preflight
## Выполнено
После фиксации Lab063 коммитом 4437917465274257ff0ca5d3c269029da45de3ec
подготовлен один измерительный PRBS7/BPSK/RRC waveform без полного PHY-пакета.
Параметры: 1400 МГц, 20000 символов/с, Fs 8000000 комплексных отсчётов/с,
цифровая несущая +50000 Гц, TX VGA 10 дБ, RX LNA/VGA 24/24 дБ, RF amplifier и
Bias-Tee выключены. Геометрия сохранена: примерно 1,2 м, LOS в помещении, TX
возле окна, RX на столе, одинаковая поляризация.
TX-файл содержит 100 мс начальных нулей, четыре одинаковых 100-мс участка с
цифровыми уровнями −18/−12/−6/0 дБ, три нулевых промежутка по 50 мс и 100 мс
конечных нулей. Полная длина равна 6000000 отсчётов и 0,75 с. RMS участков:
5,556137/11,056978/22,056892/44,000457 кода; фактические шаги мощности:
+5,977270/+5,998157/+5,998257 дБ. Максимумы |I|/|Q| не превышают 69/69,
цифрового clipping нет. SHA-256 TX:
fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9.
Подготовлены RX-first runner и офлайн-анализатор согласованной составляющей,
остатка, комплексного h и линейности. Полные stdout/stderr и все промежуточные
и финальные счётчики потерь сохраняются. Независимая read-only проверка нашла
и помогла закрыть fail-closed ошибку: промежуточный underrun с финальным нулём
теперь всегда даёт `INVALID_CAPTURE`, диагностические метрики не превращаются
в A/B/C. Целевые тесты:13 passed. Quick gate:984 теста ядра,37 функциональных
проверок,13 пропусков; pytest:984 passed,0 failed; diff-check PASS.
Один разрешённый RX-only preflight подтвердил MASTER/SLAVE reg29=0x26 и SLAVE
CLKIN=DETECTED при первом опросе через66,793мс. Записано800000 отсчётов фона:
полный RMS2,193193, AC RMS0,832038 кода, средние I/Q 0,933738/1,801650,
max|I|/|Q|=4/5, clipping0, overruns0, неожиданно сильного сигнала нет. SHA-256
RX-only записи:02d87adcbb621027290a77d5f8fd3190c299d13e89f887cd294d4af352a6ef52.
CLKOUT выключены без ошибок, процессы до и после CLEAR.
Вызовов TX не было, `RF TX=0`. Lab064 не коммитируется до аппаратного
результата, push не выполняется. Следующий этап: STOP и ожидание отдельного
явного разрешения на единственный Lab064 TX; Lab065 не начинать.
После отдельного прямого разрешения пользователя выполнен ровно один RF-сеанс
подготовленного Lab064 waveform. Перед TX MASTER/SLAVE reg29 равнялись0x26,
SLAVE CLKIN был обнаружен при втором опросе через139,042мс. RX стартовал раньше
TX. Автоматических и ручных повторов не было. Все две строки TX underrun и все
четыре строки RX overrun равны нулю. RX clipping отсутствует. Записано16000000
комплексных отсчётов за2,000000с, SHA-256
02015891948aaee52ff81e60fdfeb391bb9b76cd9192b75972b8fedbc8690d86.
После отключения CLKOUT процессы CLEAR, ошибок очистки нет, RF TX=0.
Пять окон цифрового нуля дали AC RMS0,718264…0,728217 кода; разброс фоновой
AC-мощности равен0,119530дБ, фон стабилен. Согласованная мощность L0/L1/L2/L3
равна0,000750751/0,002961235/0,011333436/0,045331864код². Ошибки трёх ступеней
относительно цифрового TX равны−0,017501/−0,169270/+0,022162дБ. Общий рост
L3/L0 равен17,809077дБ при цифровых17,973685дБ; ошибка−0,164609дБ. |h|
составляет0,004882853/0,004872939/0,004778930/0,004791153. Верхняя ступень не
показывает компрессии.
Matched/residual для L0…L3 равен−32,086493/−25,577463/−16,691669/−12,133336дБ.
По заранее заданным критериям результат `LINEAR_BUT_WEAK`: тракт линейно
следует цифровому уровню, но полезная согласованная составляющая даже на L3
слабее остатка. Абсолютная RF-мощность и разделение вклада TX/эфира/RX без
измерительного прибора не установлены.
Quick gate после сеанса прошёл:986 тестов ядра,37 функциональных проверок,13
пропусков. Полный pytest:986 passed,0 failed. Lab064 не коммитировалась, push
не выполнялся. Следующий отдельный шаг рекомендуется только после согласования:
повтор той же лестницы при TX VGA20дБ и остальных неизменных условиях. Lab065
не создана.
Независимая read-only проверка повторно вычислила SHA, положение сегментов,
пять окон фона, matched/residual, комплексные h, ступени мощности и амплитуды,
полное сравнение L3/L0 и двенадцать спектральных значений непосредственно из
CS8. Расхождений нет, вердикт `чисто`. Оборудование при проверке не опрашивалось,
RF TX остаётся равным нулю.
# Запись 060
## Дата
15 сентября 2026 года
## Тема
Lab064 зафиксирована; подготовка Lab065 при TX VGA 20 дБ и RX-only preflight
## Выполнено
После проверки уже подготовленного индекса по прямому разрешению пользователя
создан коммит `cff226e0bf9e36a627829ea11a4ca3292ae20953` с сообщением
`Lab064: measure OTA level linearity at TX VGA 10 dB`. В коммит вошли только
12 файлов и фрагментов Lab064; изменения Lab054 и Lab058 и сырые IQ не вошли.
Push не выполнялся.
Пользователь подтвердил неизменность геометрии, антенн, поляризации, USB,
clock-кабеля и RF-кабелей. Для Lab065 TX VGA изменён с 10 до 20 дБ. Частота
1400000000 Гц, RX LNA/VGA 24/24 дБ, RF amplifier и Bias-Tee OFF, PRBS7/BPSK/RRC,
20000 символов/с, Fs 8000000 отсчётов/с, несущая +50000 Гц и лестница
−18/−12/−6/0 дБ сохранены. TX-файл побайтово совпадает с Lab064: 6000000
отсчётов, 12000000 байт, 0,75 с, SHA-256
fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9.
Подготовлены RX-first runner без повторов, fail-closed проверка максимальных
счётчиков и анализ двух видов линейности: внутри Lab065 и для одинаковых
уровней Lab064/Lab065. До RF численно заданы границы пяти классификаций.
Software gate и 12 целевых тестов прошли.
RX-only preflight прошёл. Обе HackRF One r9 и роли подтверждены,
MASTER/SLAVE reg29=0x26, SLAVE CLKIN=DETECTED на третьем опросе через201,986мс.
RX записал800000 отсчётов фона: полный RMS2,333068, AC RMS1,056565 кода,
max|I|/|Q|=6/8, clipping0, overruns0, неожиданно сильного сигнала нет.
Процессы до и после CLEAR, cleanup без ошибок.
После отдельного прямого разрешения выполнен ровно один OTA-сеанс Lab065.
Перед TX MASTER/SLAVE reg29=0x26, SLAVE CLKIN=DETECTED на втором опросе через
136,897мс. RX стартовал раньше TX. TX underrun maximum0, RX overrun maximum0,
clipping0, cleanup без ошибок; процессы после CLEAR. RX:16000000 отсчётов,
2,0с, SHA-256 845d7b7dcaef70e179ab69e6ba0041601859630786d2f4d51c16a8c1c7869d7e.
Автоматических и ручных повторов не было.
Внутренние ошибки ступеней Lab065 равны−0,077363/+0,034934/−0,013858дБ;
компрессии L2/L3 нет. Относительно Lab064 matched power вырос на
11,179328/11,119466/11,323670/11,287650дБ. Медианный прирост+11,233489дБ,
медианное изменение остатка+0,517004дБ, улучшение matched/residual+10,734495дБ.
Фон стабилен: разброс1,002840дБ при границе3дБ. Остаточные полосы50/100/150кГц
на L3 выросли на7,304593/6,432281/4,996232дБ, то есть слабее matched power.
Классификация `LINEAR_GAIN_IMPROVEMENT`.
Независимая read-only проверка пересчитала RX SHA и размер, все счётчики,
локализацию, фон, matched/residual, комплексный h, CFO, внутренние ступени,
сравнение с Lab064 и полосы50/100/150кГц. Расхождений нет. Adversary подтвердил
одноразовость runner и нашёл неоднозначную подпись текущего состояния RF после
сеанса; она исправлена на `RF TX NOW=0` и закрыта отдельным тестом. Финальные
шлюзы: quick gate1000/38/13 PASS, pytest1000 passed, diff check PASS.
RF TX=0. Lab065 не коммитировалась, push не выполнялся, Lab066 не создана.
Следующий этап: STOP, рассмотрение результата и отдельное разрешение на коммит
Lab065; повторная передача или изменение усилений запрещены.
# Запись 061
## Дата
15 сентября 2026 года
## Тема
Lab065 зафиксирована; подготовка исправленного Lab066 и RX-only preflight
## Выполнено
По прямому разрешению пользователя создан локальный коммит Lab065
`dacf04f2d0a15c0c1b56a7fb527db61fc2e38462` с сообщением
`Lab065: validate OTA gain improvement at TX VGA 20 dB`. Push не выполнялся.
Lab066 подготовлена как исправленный повтор цели Lab062. Исторический результат
Lab062 сохранён: `RF_SESSION_INVALID_TX_UNDERRUN`, legacy/T2 0/16. В Lab066
использованы16 штатных полных PHY-пакетов по256 байт при500ксимв/с, Fs8Мвыб/с,
цифровой несущей+50кГц, RF1400МГц, TX VGA20дБ и RX LNA/VGA24/24дБ. RF amplifier
и Bias-Tee выключены; геометрия около1,2м, LOS, антенны и поляризация прежние.
Каждый packet waveform содержит92256 отсчётов. Между пакетами записаны15
фактических нулевых пауз по40000 отсчётов, то есть по5мс. Добавлены начальный и
конечный guards по800000 отсчётов, или по100мс. Длина без guards равна2076096,
полная длина3676096 отсчётов,7352192 байта,0,459512с. SHA-256 TX:
621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199.
Весь конечный TX-файл независимо обработан legacy и T2. Оба режима дали16/16
HEADER, FEC, CRC, packet output и точных payload в правильном порядке. Позиции
пакетов совпали с разметкой пауз. Между режимами fallback отсутствует; T2 для
каждого пакета заново оценивает состояние по его собственной преамбуле.
Программные шлюзы: quick gate1013 тестов ядра/39 функциональных/13 аппаратных
пропусков PASS; pytest1013 passed; diff check PASS. Затем выполнен один RX-only
preflight. Обе HackRF One r9 и роли подтверждены. MASTER/SLAVE reg29=0x26,
SLAVE CLKIN=DETECTED на втором опросе через132,113мс. Фон:800000 отсчётов,
полный RMS2,225641, AC RMS0,827637, max|I|/|Q|=4/5, clipping0, maximum
overruns0, сильного сигнала нет. Cleanup без ошибок, процессы после CLEAR.
Независимый verifier пересчитал SHA, длину,15 нулевых пауз, оба guards,
16 канонических packet waveform, payload и RX-only метрики; расхождений нет.
Read-only adversary проверил запрет TX, одноразовость, связь preflight/capture
с конфигурацией, максимум счётчиков, live-фон перед TX и границу диагностик;
после исправлений открытых замечаний нет.
RF TX=0. Lab066 не коммитировалась, push не выполнялся, Lab067 не создавалась.
Следующий этап: STOP и ожидание отдельного прямого разрешения на один TX Lab066.
После отдельного прямого разрешения выполнен ровно один OTA RF-сеанс Lab066.
Передача всего потока запущена одним вызовом, автоматических повторов не было.
Перед TX MASTER/SLAVE reg29=0x26, SLAVE CLKIN=DETECTED на втором опросе через
131,291мс. Live RX-фон: AC RMS1,173567, max|I|/|Q|=4/5, clipping0. TX underrun
observations0/0, RX overrun observations0/0/0/0; максимумы0/0. RX записал
16000000 отсчётов за2,0с, SHA-256
72ff7ddd8b30baa4a5c066361ca1f8dfa664f1da37f65c0c373b211ce6cf00f0.
Cleanup без ошибок, процессы после CLEAR; аппаратная запись валидна.
Одна RX-запись независимо обработана legacy и T2 без fallback. Оба режима дали
145 кандидатов,10 HEADER/FEC/CRC PASS,10 packet output и10 точных payload.
Оба приняли пакеты4–8 и10–14; пакеты1–3,9,15,16 остановились на PHY header.
Выигрыш T2 равен нулю.
Диагностика всех16 пакетов после строгого результата дала SER0,0110466,
RMS-отклонение0,528374, matched/residual+5,542117дБ и медианную неравномерность
полосы2,870070дБ. Это лучше Lab056 B на0,0239123 SER,0,316976 RMS,
4,077271дБ matched/residual и2,601312дБ неравномерности. Относительно Lab062
улучшения составляют0,0882400 SER,0,692027 RMS,7,272168дБ matched/residual и
3,790271дБ неравномерности; сравнение с Lab062 контекстное из-за её underrun.
Классификация `PARTIAL_PACKET_RECOVERY_NO_T2_GAIN`: аппаратно чистый сеанс
существенно улучшил физическое качество, но не достиг16/16, а T2 не изменил
строгий результат. RF TX=0, повтор не выполнялся. Lab066 не коммитировалась,
push не выполнялся, Lab067 не создавалась. Следующий возможный одиночный шаг —
отдельно разрешённый офлайн-анализ PHY header не прошедших пакетов по сохранённой
IQ-записи; новый TX не нужен.

View File

@@ -0,0 +1,130 @@
{
"lab": "Lab062",
"stage": "SINGLE_RF_CAPTURE",
"passed": false,
"rf_tx_count": 1,
"automatic_tx_repeats": 0,
"point": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 500000,
"samples_per_symbol": 16,
"digital_carrier_hz": 50000.0,
"packets": 16,
"payload_bytes": 256,
"tx_vga_db": 10,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN"
},
"tx_sha256": "e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5",
"process_before": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 304,
"errors": []
}
]
},
"inventory": {
"passed": true,
"serials": [
"000000000000000097c063dc2e5327d3",
"000000000000000097c063dc323b97d3"
],
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3",
"raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One"
},
"clock": {
"passed": true,
"master_reg29": 38,
"slave_reg29": 38,
"slave_clkin_status": "DETECTED",
"slave_clock_wait": {
"state": "DETECTED",
"queries": 2,
"time_to_detect_ms": 140.9547000657767,
"elapsed_ms": 140.9547000657767,
"polls": [
{
"query": 1,
"start_ms": 50.31830002553761,
"end_ms": 67.1174000017345,
"raw": "CLKIN status: no clock signal detected",
"state": "NOT_DETECTED",
"exit_code": 0
},
{
"query": 2,
"start_ms": 117.15810000896454,
"end_ms": 140.9547000657767,
"raw": "CLKIN status: clock signal detected",
"state": "DETECTED",
"exit_code": 0
}
]
},
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3"
},
"rx_level_before_tx": {
"samples": 65536,
"mean_i": 0.957977294921875,
"mean_q": 1.857269287109375,
"power_code2": 4.886199951171875,
"ac_power_code2": 0.5190302487462768,
"rms_code": 2.2104750510177387,
"peak_magnitude_code": 4.123105625617661,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 5.414776863475277,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION"
},
"rx_samples": 24000000,
"rx_bytes": 48000000,
"rx_duration_seconds": 3.0,
"error": "TX underrun или неоднозначный счётчик; повтор запрещён",
"process_after": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 304,
"errors": []
}
]
},
"cleanup_errors": []
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
packet_index,legacy_header,legacy_fec,legacy_crc,legacy_output,t2_header,t2_fec,t2_crc,t2_output,preamble_errors_t2,header_errors_t2,payload_errors_before_fec_t2,initial_frequency_hz_t2,t2_final_frequency_hz,t2_lock_status
1,False,False,False,False,False,False,False,False,108,20,367,-2.511306789128502,1.938828000443245,NOT_DEFINED_BY_IMPLEMENTATION
2,False,False,False,False,False,False,False,False,135,11,377,16.850274814266026,-2.223133252684196,NOT_DEFINED_BY_IMPLEMENTATION
3,False,False,False,False,False,False,False,False,466,115,2229,-266.23811405950204,-265.79617151697045,NOT_DEFINED_BY_IMPLEMENTATION
4,False,False,False,False,False,False,False,False,515,104,2266,297.2495839963796,293.7996556301242,NOT_DEFINED_BY_IMPLEMENTATION
5,False,False,False,False,False,False,False,False,108,27,369,-1.7121731230326125,-0.8347122576256625,NOT_DEFINED_BY_IMPLEMENTATION
6,True,True,False,False,True,True,False,False,112,10,345,4.67554618043703,-3.16390424095876,NOT_DEFINED_BY_IMPLEMENTATION
7,False,False,False,False,False,False,False,False,113,7,344,2.1125086049646824,1.0944814837028547,NOT_DEFINED_BY_IMPLEMENTATION
8,False,False,False,False,False,False,False,False,91,19,368,0.9638879273500407,0.35355297825700155,NOT_DEFINED_BY_IMPLEMENTATION
9,False,False,False,False,False,False,False,False,105,21,367,-2.6793109690685877,0.19088110622128074,NOT_DEFINED_BY_IMPLEMENTATION
10,False,False,False,False,False,False,False,False,116,7,345,-0.29035656707501434,0.9472030503555074,NOT_DEFINED_BY_IMPLEMENTATION
11,False,False,False,False,True,True,False,False,109,9,392,0.7573187277726318,-0.14196556023732618,NOT_DEFINED_BY_IMPLEMENTATION
12,False,False,False,False,False,False,False,False,297,110,2181,-223.04966205995262,-222.38930722105994,NOT_DEFINED_BY_IMPLEMENTATION
13,False,False,False,False,False,False,False,False,304,36,524,-0.16099769754669116,-2.081420319755734,NOT_DEFINED_BY_IMPLEMENTATION
14,True,True,False,False,False,False,False,False,314,127,2091,228.20916012396785,224.92813768839025,NOT_DEFINED_BY_IMPLEMENTATION
15,True,True,False,False,True,True,False,False,131,7,395,-9.95965988857566,2.2844456653638283,NOT_DEFINED_BY_IMPLEMENTATION
16,False,False,False,False,False,False,False,False,100,23,355,13.156526986310709,-0.8684121381823278,NOT_DEFINED_BY_IMPLEMENTATION
1 packet_index legacy_header legacy_fec legacy_crc legacy_output t2_header t2_fec t2_crc t2_output preamble_errors_t2 header_errors_t2 payload_errors_before_fec_t2 initial_frequency_hz_t2 t2_final_frequency_hz t2_lock_status
2 1 False False False False False False False False 108 20 367 -2.511306789128502 1.938828000443245 NOT_DEFINED_BY_IMPLEMENTATION
3 2 False False False False False False False False 135 11 377 16.850274814266026 -2.223133252684196 NOT_DEFINED_BY_IMPLEMENTATION
4 3 False False False False False False False False 466 115 2229 -266.23811405950204 -265.79617151697045 NOT_DEFINED_BY_IMPLEMENTATION
5 4 False False False False False False False False 515 104 2266 297.2495839963796 293.7996556301242 NOT_DEFINED_BY_IMPLEMENTATION
6 5 False False False False False False False False 108 27 369 -1.7121731230326125 -0.8347122576256625 NOT_DEFINED_BY_IMPLEMENTATION
7 6 True True False False True True False False 112 10 345 4.67554618043703 -3.16390424095876 NOT_DEFINED_BY_IMPLEMENTATION
8 7 False False False False False False False False 113 7 344 2.1125086049646824 1.0944814837028547 NOT_DEFINED_BY_IMPLEMENTATION
9 8 False False False False False False False False 91 19 368 0.9638879273500407 0.35355297825700155 NOT_DEFINED_BY_IMPLEMENTATION
10 9 False False False False False False False False 105 21 367 -2.6793109690685877 0.19088110622128074 NOT_DEFINED_BY_IMPLEMENTATION
11 10 False False False False False False False False 116 7 345 -0.29035656707501434 0.9472030503555074 NOT_DEFINED_BY_IMPLEMENTATION
12 11 False False False False True True False False 109 9 392 0.7573187277726318 -0.14196556023732618 NOT_DEFINED_BY_IMPLEMENTATION
13 12 False False False False False False False False 297 110 2181 -223.04966205995262 -222.38930722105994 NOT_DEFINED_BY_IMPLEMENTATION
14 13 False False False False False False False False 304 36 524 -0.16099769754669116 -2.081420319755734 NOT_DEFINED_BY_IMPLEMENTATION
15 14 True True False False False False False False 314 127 2091 228.20916012396785 224.92813768839025 NOT_DEFINED_BY_IMPLEMENTATION
16 15 True True False False True True False False 131 7 395 -9.95965988857566 2.2844456653638283 NOT_DEFINED_BY_IMPLEMENTATION
17 16 False False False False False False False False 100 23 355 13.156526986310709 -0.8684121381823278 NOT_DEFINED_BY_IMPLEMENTATION

View File

@@ -0,0 +1,144 @@
{
"lab": "Lab062",
"stage": "RX_ONLY_PREFLIGHT",
"passed": true,
"rf_tx_count": 0,
"point": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 500000,
"samples_per_symbol": 16,
"digital_carrier_hz": 50000.0,
"packets": 16,
"payload_bytes": 256,
"tx_vga_db": 10,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN"
},
"tx_sha256": "e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5",
"stop_before_tx": true,
"process_before": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 308,
"errors": []
}
]
},
"inventory": {
"passed": true,
"serials": [
"000000000000000097c063dc2e5327d3",
"000000000000000097c063dc323b97d3"
],
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3",
"raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One"
},
"clock": {
"passed": true,
"master_reg29": 38,
"slave_reg29": 38,
"slave_clkin_status": "DETECTED",
"slave_clock_wait": {
"state": "DETECTED",
"queries": 2,
"time_to_detect_ms": 133.57950001955032,
"elapsed_ms": 133.57950001955032,
"polls": [
{
"query": 1,
"start_ms": 50.528000108897686,
"end_ms": 67.34060007147491,
"raw": "CLKIN status: no clock signal detected",
"state": "NOT_DETECTED",
"exit_code": 0
},
{
"query": 2,
"start_ms": 117.69610014744103,
"end_ms": 133.57950001955032,
"raw": "CLKIN status: clock signal detected",
"state": "DETECTED",
"exit_code": 0
}
]
},
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3"
},
"rx_process": {
"returncode": 0,
"stdout": "",
"stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 800000/0Mio\nStop with Ctrl-C\n 1.8 MiB / 0.115 sec = 15.9 MiB/second, average power -34.5 dBfs, 9120 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.11549 s\nhackrf_stop_rx() done\nTransfer statistics:\n1847680 bytes transferred by M0\n1835008 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n"
},
"rx_level": {
"samples": 800000,
"mean_i": 0.9660625,
"mean_q": 1.85752875,
"power_code2": 5.35486625,
"ac_power_code2": 0.9711764390171878,
"rms_code": 2.3140583938180987,
"peak_magnitude_code": 8.246211251235321,
"max_abs_i": 6.0,
"max_abs_q": 8.0,
"papr_db": 11.037602848982825,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION",
"ac_rms_code": 0.9854828456229909,
"unexpected_strong_signal": false,
"strong_signal_rule": "AC RMS >= 20.0 code or max |I|/|Q| >= 100.0 code",
"symbol_energy": "NOT_APPLICABLE_TO_BACKGROUND"
},
"rx_sha256": "4cc0ceef5a95f84e5aa0c232d14ff1123efd307494b5c8a5646854be912fdbca",
"rx_overruns": 0,
"process_after": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 308,
"errors": []
}
]
},
"cleanup_errors": [],
"processed_correction": {
"source": "data/raw/lab062/preflight_result.json",
"removed_field": "rx_level.symbol_energy_code2_seconds",
"removed_value": 0.00026774331249999997,
"reason": "inherited Lab056 20 ksymbol/s normalization is not applicable to RX-only background",
"preflight_pass_affected": false
}
}

View File

@@ -0,0 +1,80 @@
{
"lab": "Lab062",
"stage": "PREPARATION_ONLY",
"rf_tx_count": 0,
"head": "25cc89f0c734f77141632d19dbcdb6b2f066d60b",
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 500000,
"samples_per_symbol": 16,
"digital_carrier_hz": 50000.0,
"packets": 16,
"payload_bytes": 256,
"tx_vga_db": 10,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN"
},
"tx_samples": 1476096,
"tx_bytes": 2952192,
"tx_duration_seconds": 0.184512,
"tx_sha256": "e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5",
"rx_samples": 24000000,
"rx_duration_seconds": 3,
"automatic_retry": false,
"tx_command_prepared_not_run": [
"C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe",
"-d",
"000000000000000097c063dc323b97d3",
"-t",
"C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab062\\tx_stream.cs8",
"-f",
"1400000000",
"-s",
"8000000",
"-n",
"1476096",
"-x",
"10",
"-a",
"0",
"-p",
"0",
"-B"
],
"rx_command_prepared_not_run": [
"C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe",
"-d",
"000000000000000097c063dc2e5327d3",
"-r",
"C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab062\\rx_stream.cs8",
"-f",
"1400000000",
"-s",
"8000000",
"-n",
"24000000",
"-l",
"24",
"-g",
"24",
"-a",
"0",
"-p",
"0",
"-B"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
{
"lab": "Lab062",
"stage": "SOFTWARE_GATE",
"rf_tx_count": 0,
"tx_sha256": "e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5",
"legacy": {
"mode": "legacy",
"packets": 16,
"header_pass": 16,
"fec_pass": 16,
"crc_pass": 16,
"exact_ordered_payloads": true,
"passed": true
},
"t2": {
"mode": "t2",
"packets": 16,
"header_pass": 16,
"fec_pass": 16,
"crc_pass": 16,
"exact_ordered_payloads": true,
"passed": true
},
"passed": true
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -0,0 +1,360 @@
window_index,tx_sample,rx_sample,time_seconds,local_delay_samples,packet_index,position_inside_packet_samples,inside_reliable_region,correlation_above_threshold,reliable_for_delay,normalized_correlation,gain,gain_amplitude,phase_rad,residual_power,rx_ac_power
0,0,4256092,0.0,1,1,0,False,True,False,0.2723983005613592,(0.0014400764308659896+0.004547916824745963j),0.004770468275918322,1.264139438138503,0.5320521433901737,0.5746949911117554
1,4096,4258156,0.000512,-2031,1,4096,False,True,False,0.2729793659247979,(-0.004663053599288344+0.00040199323732778125j),0.004680349071671177,3.0555971153877457,0.5307691750552395,0.5735055059194565
2,8192,4258188,0.001024,-6095,1,8192,False,True,False,0.2744171645442273,(0.004046229816782595+0.0023981760914401954j),0.004703533171539868,0.5350301142527935,0.5298967126207345,0.5730501264333725
3,12288,4258220,0.001536,-10159,1,12288,False,True,False,0.2745940021638059,(-0.001877375284743114-0.004308549206226646j),0.004699801508812957,-1.9817223367149237,0.5290641319544691,0.572209820151329
4,16384,4272476,0.002048,1,1,16384,False,True,False,0.26655475961180447,(0.0015909658512084958+0.0043219233704984905j),0.004605452633582567,1.2180752315139343,0.5385030300563245,0.5796909034252167
5,20480,4276572,0.00256,1,1,20480,False,True,False,0.2704674132861876,(0.0015020188131524086+0.004503663352078344j),0.004747530316271536,1.2488863714827263,0.5517759339741067,0.5953255593776703
6,24576,4280667,0.003072,0,1,24576,True,True,True,0.2779743002913568,(0.001574055297828197+0.004628794269849324j),0.004889108965160313,1.2430064552849862,0.5566272125305693,0.6032393425703049
7,28672,4284763,0.003584,0,1,28672,True,True,True,0.2720544529364392,(0.0016932309240155242+0.004457847887134059j),0.004768588758413548,1.2077965884614033,0.5530613403203055,0.5972672551870346
8,32768,4288859,0.004096,0,1,32768,True,True,True,0.2649913203278537,(0.0018990710284393965+0.004188594569993716j),0.004598999374085488,1.1451260339739677,0.5459171758273589,0.5871468633413315
9,36864,4292955,0.004608,0,1,36864,True,True,True,0.2721722386513534,(0.0018268451981139167+0.004317763275913575j),0.004688330522126165,1.1705361837258939,0.5365336736680916,0.5794586539268494
10,40960,4297051,0.00512,0,1,40960,True,True,True,0.2721968822811185,(0.001724738414167657+0.004364487642303184j),0.004692917533594935,1.1944559420309822,0.5372551467224218,0.5802462548017502
11,45056,4301147,0.005632,0,1,45056,True,True,True,0.27115565572908557,(0.0018536312646620433+0.0043132285698386785j),0.004694666075559072,1.1649051100363104,0.5411645818582298,0.5841116160154343
12,49152,4305244,0.006144,1,1,49152,True,True,True,0.26695565820866574,(0.0015749959490531304+0.004372541401953098j),0.004647551027296822,1.2250623805453835,0.5459189026441111,0.5878093242645264
13,53248,4309339,0.006656,0,1,53248,True,True,True,0.2556440262627536,(0.0016446481954502357+0.004141139532609057j),0.0044557720223700045,1.1927503782494664,0.5527965436310334,0.5914500951766968
14,57344,4313435,0.007168,0,1,57344,True,True,True,0.2654944778350678,(0.001579553863468991+0.004353550882949614j),0.004631241269684746,1.2227468320256794,0.551303941123149,0.5931107252836227
15,61440,4317531,0.00768,0,1,61440,True,True,True,0.2819287365366617,(0.0016676229288336369+0.0046224170689160154j),0.004914031521243816,1.2245604961967766,0.5432338343896431,0.5901404470205307
16,65536,4321628,0.008192,1,1,65536,True,True,True,0.2849343081441107,(0.0015551300976373065+0.004760709738123959j),0.005008271840789566,1.255064382840333,0.5515766203313819,0.6003147065639496
17,69632,4325724,0.008704,1,1,69632,True,True,True,0.2668779433455796,(0.0015400349773235437+0.0044066605083271275j),0.004668015056427071,1.234585792156039,0.5544426689160701,0.5969604849815369
18,73728,4329819,0.009216,0,1,73728,True,True,True,0.26731850919222144,(0.0015998970853807015+0.004351612962721423j),0.004636400118748897,1.2184796304589962,0.544979127072188,0.5869199484586716
19,77824,4333915,0.009728,0,1,77824,True,True,True,0.2757493751671597,(0.0015028961676935508+0.0045326408799782995j),0.004775304203683616,1.2506319351828965,0.5405722579331813,0.58505879342556
20,81920,4338011,0.01024,0,1,81920,True,True,True,0.2747031051630683,(0.001434360817300166+0.004554302124498627j),0.004774835996703836,1.2656843127617807,0.5449793922392892,0.5894611924886703
21,86016,4342106,0.010752,-1,1,86016,False,True,False,0.262832641274786,(0.0017063341695680602+0.004412668558523586j),0.004731090794480502,1.201816607513573,0.5405771973365503,0.5806919783353806
22,90112,4346203,0.011264,0,1,90112,False,True,False,0.24463720210977444,(0.001540875532155414+0.004130615883847389j),0.004408660225679404,1.2137471203289174,0.5462349738883019,0.5810066908597946
23,94208,4360459,0.011776,10160,2,1952,False,True,False,0.2716641040460329,(-0.0013022645358288175-0.004525075678879153j),0.00470873686043944,-1.8510125610584165,0.5428179407596163,0.5860707759857178
24,98304,4360491,0.012288,6096,2,6048,False,True,False,0.2718898121257277,(-0.0016149804689081098+0.004431209064076905j),0.0047163307437574796,1.920291000004672,0.5434848560970025,0.5868685692548752
25,102400,4360523,0.0128,2032,2,10144,False,True,False,0.2725240587031942,(0.00391949046182433-0.0026463739117019856j),0.004729238877543486,-0.5938754774412633,0.5434089720090052,0.5870054960250854
26,106496,4362587,0.013312,0,2,14240,False,True,False,0.2760592697755412,(0.0013920156722528913+0.004580095816437278j),0.0047869599245809365,1.2757405072063803,0.5415059501043626,0.5861778110265732
27,110592,4366683,0.013824,0,2,18336,False,True,False,0.2724376874597982,(0.0014133537140496781+0.0045130584690135705j),0.004729192897921709,1.2673013462261535,0.5413853024567086,0.5847897380590439
28,114688,4370780,0.014336,1,2,22432,False,True,False,0.2719029335917029,(0.0011697644964912767+0.004560116010595991j),0.0047077602962922165,1.3196899415543735,0.5406078471906972,0.5837664008140564
29,118784,4374876,0.014848,1,2,26528,True,True,True,0.2700707220369181,(0.0013350388080086953+0.004474286128071312j),0.004669214599345446,1.2808261632328335,0.5394193308566163,0.5818590819835663
30,122880,4378971,0.01536,0,2,30624,True,True,True,0.2686195464655446,(0.0012246606908276484+0.0044642820496554455j),0.004629212462885483,1.3030584917227905,0.5373847039400281,0.5791759938001633
31,126976,4383067,0.015872,0,2,34720,True,True,True,0.2633530926845802,(0.0011406041785767163+0.004404294536372791j),0.004549592097684131,1.3173881793080358,0.5396795929719889,0.5798983573913574
32,131072,4387163,0.016384,0,2,38816,True,True,True,0.25637788480815954,(0.0012829050950408745+0.004270558977812529j),0.004459094018503873,1.278966333401463,0.5485951175865063,0.5871909558773041
33,135168,4391260,0.016896,1,2,42912,True,True,True,0.26000719134870665,(0.001208701026115259+0.00434386307850457j),0.004508891728055496,1.2994066208398154,0.5469509736502136,0.5866078585386276
34,139264,4395355,0.017408,0,2,47008,True,True,True,0.2539878786554866,(0.001204104650759226+0.0042140376803331j),0.004382691134593809,1.2924760702562699,0.5432254548985715,0.5806853771209717
35,143360,4399451,0.01792,0,2,51104,True,True,True,0.26248777906333653,(0.001090192569531215+0.004413735444813682j),0.004546381024008624,1.3286431982708542,0.544464620474242,0.584754079580307
36,147456,4403547,0.018432,0,2,55200,True,True,True,0.268908662501336,(0.0011983970061596977+0.004461156216980074j),0.0046193149033890825,1.3083625534812198,0.5334410404305294,0.5750219523906708
37,151552,4407644,0.018944,1,2,59296,True,True,True,0.2584294308489172,(0.0009705941914629901+0.004321800607292927j),0.004429448450281277,1.3498807548369551,0.5329131149684843,0.5710512101650238
38,155648,4411739,0.019456,0,2,63392,True,True,True,0.2589804129517903,(0.0011773086855389008+0.004351617974012928j),0.004508063301773581,1.306576549991733,0.5504235283232656,0.5899949967861176
39,159744,4415835,0.019968,0,2,67488,True,True,True,0.26707042084269383,(0.0012836628929886265+0.004466770988566209j),0.004647562101482096,1.2909568817815837,0.5478066109478578,0.5898808091878891
40,163840,4419932,0.02048,1,2,71584,True,True,True,0.26685819356609625,(0.0011948923329598014+0.004432616311602053j),0.004590844699316968,1.3074870108552974,0.5338153340239872,0.5747448056936264
41,167936,4424027,0.020992,0,2,75680,True,True,True,0.2602019922356652,(0.0012135424294046583+0.004275450290739874j),0.004444340267863503,1.294230653530701,0.5290908955689677,0.5675145089626312
42,172032,4428123,0.021504,0,2,79776,True,True,True,0.2648953034335269,(0.0010080749497805373+0.004436298157786467j),0.0045493907778025216,1.3473571568083174,0.5346305944052281,0.5749764144420624
43,176128,4432219,0.022016,0,2,83872,True,True,True,0.27271964951391364,(0.0010679789510904913+0.004638600937917362j),0.004759957741537227,1.3445025739068763,0.5379263101079028,0.5811499208211899
44,180224,4436316,0.022528,1,2,87968,False,True,False,0.26621296963966334,(0.0014238192462404508+0.004578690891323345j),0.004794963141073359,1.2693091820913467,0.5398449030192329,0.5810215175151825
45,184320,4440411,0.02304,0,2,92064,False,True,False,0.2580468087430128,(0.0016982791241270806+0.004292585999959374j),0.004616323921746941,1.1940621888188008,0.5458059940350145,0.5847429484128952
46,188416,4452635,0.023552,8128,3,3904,False,True,False,0.2649939974461844,(0.004547469531258444+0.0002454033015846323j),0.004554086287956402,0.053912509828619726,0.5349567727385085,0.5753595679998398
47,192512,4452667,0.024064,4064,3,8000,False,True,False,0.2652695563170298,(-0.00352196396834277-0.00288831530557835j),0.004554843081681619,-2.4547232497156846,0.5348699867647786,0.5753566473722458
48,196608,4450668,0.024576,-2031,3,12096,False,True,False,0.2655804119817936,(-0.00455017405199118-0.0005553942299958869j),0.00458394444273996,-3.0201334712223153,0.5399761574427078,0.580952450633049
49,200704,4456795,0.025088,0,3,16192,False,True,False,0.27329487809545694,(0.0010001317651298055+0.004609230865953922j),0.004716489449080111,1.3571240999141405,0.5367884244476238,0.5801174491643906
50,204800,4460891,0.0256,0,3,20288,False,True,False,0.2748035784048019,(0.0009020685528086647+0.004696528423964232j),0.0047823746100729364,1.3810359628033242,0.5447007004166863,0.5891949385404587
51,208896,4464987,0.026112,0,3,24384,True,True,True,0.2733714317503713,(0.001196082844537941+0.0046138615886948545j),0.0047663752402251945,1.3171432489691388,0.5430379318122193,0.5868979543447495
52,212992,4469084,0.026624,1,3,28480,True,True,True,0.26980098289370985,(0.000891303823734098+0.00462177943251277j),0.0047069382435932896,1.3802864468658624,0.5452336561152853,0.5880384892225266
53,217088,4473180,0.027136,1,3,32576,True,True,True,0.2593488284007324,(0.000701164278632974+0.004429229337331668j),0.004484384446979364,1.4137952643367864,0.5418432466726182,0.5809167623519897
54,221184,4477275,0.027648,0,3,36672,True,True,True,0.24083000237735547,(0.0010787855072950715+0.003956623747567151j),0.004101054699776901,1.3046133691002941,0.5316101788297216,0.5643414705991745
55,225280,4481371,0.02816,0,3,40768,True,True,True,0.24884057677466154,(0.0012529409123619626+0.004099663105570891j),0.004286851817948644,1.274191159290718,0.5432383289368947,0.5790969580411911
56,229376,4485467,0.028672,0,3,44864,True,True,True,0.26424577088305007,(0.001419557704160117+0.004367512865639938j),0.004592419047405269,1.2565404007957168,0.5470104412221599,0.5880731344223022
57,233472,4489563,0.029184,0,3,48960,True,True,True,0.25762850178040403,(0.0013096625676030976+0.004235848862247899j),0.004433692775191755,1.2709340205678785,0.5390744902777722,0.5773977935314178
58,237568,4493659,0.029696,0,3,53056,True,True,True,0.2679321562033791,(0.0013369756290009971+0.0043821287442785415j),0.004581545172098038,1.2746696997240843,0.5273775856410188,0.5681647956371307
59,241664,4497755,0.030208,0,3,57152,True,True,True,0.2711470944273147,(0.001351328684164128+0.004419603802068811j),0.004621578407850054,1.2740654815604695,0.5230486505702867,0.5645551681518555
60,245760,4501852,0.03072,1,3,61248,True,True,True,0.2672883844824355,(0.0010068247184626777+0.004467841124027755j),0.004579879946380805,1.3491494727972868,0.5312288236824456,0.5721015185117722
61,249856,4505947,0.031232,0,3,65344,True,True,True,0.27107441392986664,(0.0013357978398945835+0.0044942838974314555j),0.004688597191034725,1.2818905523246318,0.5404706646150161,0.583334892988205
62,253952,4510043,0.031744,0,3,69440,True,False,False,0.13153433429624267,(0.001554183671647779+0.004426566695093525j),0.004691479467217968,1.2331386492766252,2.4339817589794546,2.476834163069725
63,258048,4514139,0.032256,0,3,73536,True,False,False,0.08888879507126439,(0.00169980331450993+0.004389042425002968j),0.004706699981568283,1.2013003657755736,5.416685224653776,5.459824487566948
64,262144,4518235,0.032768,0,3,77632,True,False,False,0.07990273751817419,(0.001699250897969519+0.004324783344646435j),0.004646633683902942,1.1964168666678643,6.53860352546403,6.580617129802704
65,266240,4522332,0.03328,1,3,81728,True,False,False,0.07824125225628915,(0.0013933691504081321+0.004356594463416111j),0.004573990916910198,1.2612476939877006,6.624367159902822,6.665169283747673
66,270336,4526428,0.033792,1,3,85824,True,False,False,0.07587440188611191,(0.0013041751210003604+0.004457185452549003j),0.004644068787674313,1.286141724316014,6.655995644921719,6.694535583257675
67,274432,4530523,0.034304,0,3,89920,False,False,False,0.0769175854864118,(0.0015678214075495489+0.004396212075719992j),0.004667413050146401,1.2282272423410476,6.554379697834005,6.593388259410858
68,278528,4542747,0.034816,8128,4,1760,False,False,False,0.08597985441315165,(0.005066283573465239+0.00034999030444959325j),0.005078358244548373,0.0689726756303229,6.758426343340691,6.808760344982147
69,282624,4542779,0.035328,4064,4,5856,False,False,False,0.0857009006288708,(-0.0038966589911976885-0.003238719072000978j),0.005066877985606587,-2.4481426241304436,6.759721722902659,6.80973681807518
70,286720,4544843,0.03584,2032,4,9952,False,False,False,0.08525779282376747,(0.004325880698897092-0.0025736448588474193j),0.005033576430388451,-0.536691526326966,6.741963816067408,6.791329249739647
71,290816,4546907,0.036352,0,4,14048,False,False,False,0.0818033690015016,(0.0011822849366477169+0.004670129356209848j),0.004817458445607716,1.3228467728695121,6.720242903354096,6.765516325831413
72,294912,4551003,0.036864,0,4,18144,False,False,False,0.07658097028160148,(0.0008517722304822827+0.004438565003908057j),0.0045195547597676146,1.3811986992356107,6.7219641213364305,6.761618614196777
73,299008,4555099,0.037376,0,4,22240,False,False,False,0.08613404389567611,(0.0011849698335850026+0.0049152028039830455j),0.005056023349509896,1.334227966715792,6.6581370011692105,6.707903429865837
74,303104,4559195,0.037888,0,4,26336,True,False,False,0.08726659571551212,(0.0016595927555988928+0.004842576482874993j),0.005119061936227209,1.2406318687205053,6.6524727994418935,6.703523203730583
75,307200,4563291,0.0384,0,4,30432,True,False,False,0.07303287114951702,(0.001432858640864123+0.004032332716192873j),0.0042793446950179625,1.229370113401519,6.647078068400921,6.682722374796867
76,311296,4567387,0.038912,0,4,34528,True,False,False,0.07923837125521409,(0.001686126196189353+0.004315979331039012j),0.004633648577032135,1.198358325356545,6.621968636371651,6.663808822631836
77,315392,4571483,0.039424,0,4,38624,True,False,False,0.08766369642748506,(0.0017031705964680188+0.004852024258675652j),0.0051422689046227675,1.2332107176608704,6.6245479222476575,6.675851330161095
78,319488,4575579,0.039936,0,4,42720,True,False,False,0.08111151553103035,(0.0017214618264675924+0.004433371066833172j),0.004755860577878481,1.2004198351270303,6.642704557350704,6.686696857213974
79,323584,4579675,0.040448,0,4,46816,True,False,False,0.10671176630261674,(0.0013274729713343197+0.004468864548466894j),0.0046618595905676295,1.2820488137155435,3.674980498404129,3.7173110097646713
80,327680,4583771,0.04096,0,4,50912,True,True,True,0.17364185979381344,(0.0011104452242883332+0.0048122481560667054j),0.0049387064006389545,1.3440119960319097,1.5273621675226863,1.5748461335897446
81,331776,4587867,0.041472,0,4,55008,True,False,False,0.13566484987135102,(0.0011900787687552166+0.004564289775742337j),0.004716887600185949,1.3157381520156248,2.309129150389409,2.3524254262447357
82,335872,4591963,0.041984,0,4,59104,True,True,True,0.1663171407536924,(0.0012317423905629345+0.004361708579217488j),0.004532294236557146,1.2955643672094288,1.3985216467121702,1.4383072257041931
83,339968,4596059,0.042496,0,4,63200,True,True,True,0.26471751311013225,(0.001558865952620833+0.00430077474184848j),0.004574573907847846,1.2230632263032186,0.5405374832466419,0.5812702029943466
84,344064,4600155,0.043008,0,4,67296,True,True,True,0.2792268825008271,(0.0016212932750898708+0.004545583027784552j),0.004826066405089617,1.2281878779094144,0.5361519398429078,0.5814892947673798
85,348160,4604251,0.04352,0,4,71392,True,True,True,0.2832122191263414,(0.001568572376109022+0.004689580014148107j),0.004944955005678986,1.2480138106379053,0.546382714975119,0.5940293073654175
86,352256,4608347,0.044032,0,4,75488,True,True,True,0.2751351562277797,(0.0014124280165170157+0.004572151352605746j),0.004785344386037095,1.2711764645789363,0.5418399951586526,0.5862161815166473
87,356352,4612443,0.044544,0,4,79584,True,True,True,0.2711253433830607,(0.0012792764994174382+0.004507944933506286j),0.0046859487711120714,1.2942834417500173,0.539963691491252,0.5828050822019577
88,360448,4616539,0.045056,0,4,83680,True,True,True,0.2780326176311392,(0.0014125086541028251+0.004613805346804851j),0.004825181911194686,1.2737084804157615,0.5414278402357562,0.5867877900600433
89,364544,4620635,0.045568,0,4,87776,False,True,False,0.2717667108050532,(0.0013978470154112287+0.004703990842016978j),0.004907291118353758,1.281945292248661,0.5413104739012351,0.5844783782958984
90,368640,4626764,0.04608,2033,4,91872,False,True,False,0.2662074290976547,(0.004115316763378964-0.002495104285846531j),0.004812626877309069,-0.5450368010824937,0.5440730211399605,0.5855702757835388
91,372736,4626795,0.046592,-2032,5,3712,False,True,False,0.282542960509231,(-0.004899029038211988-8.122809335022387e-05j),0.004899702391002294,-3.125013725308483,0.5400234934244572,0.5868739485740662
92,376832,4626827,0.047104,-6096,5,7808,False,True,False,0.2825020973176275,(0.003908930591380348+0.002952507348220343j),0.004898677169351359,0.646899486603501,0.5395280432357176,0.5863208025693893
93,380928,4626859,0.047616,-10160,5,11904,False,True,False,0.2807600356970303,(-0.001420950169111977-0.004657543716583497j),0.004869477677840383,-1.8669123818056594,0.5399243687694288,0.5861264914274216
94,385024,4641116,0.048128,1,5,16000,False,True,False,0.2650614809565532,(0.0010542710537117725+0.004575124896595126j),0.004695024523273451,1.344314387574751,0.5685874798206638,0.6115537732839584
95,389120,4645211,0.04864,0,5,20096,False,True,False,0.2667422739644077,(0.0010977299055325784+0.004457196663720133j),0.004590382668643046,1.3293194581197063,0.534952635962959,0.5759309530258179
96,393216,4649307,0.049152,0,5,24192,True,True,True,0.26466251848509825,(0.0010486869362193254+0.004394194972639804j),0.0045175982277942785,1.336525561985254,0.5277840580651971,0.5675379633903503
97,397312,4653403,0.049664,0,5,28288,True,True,True,0.25854313841229054,(0.001198925223421213+0.004261898495125296j),0.004427324301890123,1.2965709791550253,0.5339610295058146,0.5722101628780365
98,401408,4657499,0.050176,0,5,32384,True,True,True,0.2537591241878097,(0.001220992856318022+0.004200952361654078j),0.004374794200881525,1.287942494915078,0.5425047534699575,0.5798429846763611
99,405504,4661596,0.050688,1,5,36480,True,True,True,0.2590655534926447,(0.0011303389414594528+0.004347174614996451j),0.004491724975535481,1.3164124223967255,0.5442177708614893,0.5833706706762314
100,409600,4665692,0.0512,1,5,40576,True,True,True,0.27545885714841517,(0.001241740275123457+0.004628777994975647j),0.004792442450111889,1.3087020787717447,0.5450552239659276,0.589808464050293
101,413696,4669788,0.051712,1,5,44672,True,True,True,0.2779047219199058,(0.0013383854927980384+0.004623275702312929j),0.004813102320430073,1.289010720505806,0.5374273640261628,0.5824072808027267
102,417792,4673883,0.052224,0,5,48768,True,True,True,0.28072829168306407,(0.0014892805370576398+0.004618240714550299j),0.004852432772907704,1.258847275319138,0.5363134186037127,0.5821952819824219
103,421888,4677979,0.052736,0,5,52864,True,True,True,0.27647214381674806,(0.0013533142580344057+0.004639687152038339j),0.004833027658703067,1.2869878818229048,0.5499437435476484,0.5954587310552597
104,425984,4682075,0.053248,0,5,56960,True,True,True,0.2715921696331709,(0.001087912656261071+0.004603111202176992j),0.004729924596360954,1.338712126802001,0.5463894941519993,0.5899020284414291
105,430080,4686171,0.05376,0,5,61056,True,True,True,0.2669719744416374,(0.001055495801123365+0.004535850831207893j),0.004657039204168071,1.342164417057586,0.5496048207813974,0.5917836278676987
106,434176,4690267,0.054272,0,5,65152,True,True,True,0.25933246973065593,(0.0011738677237808808+0.004384331485952915j),0.00453875842182117,1.3091906786672414,0.5567507899047981,0.5968938916921616
107,438272,4694363,0.054784,0,5,69248,True,True,True,0.26592635147561616,(0.0014396359888415133+0.004449124742918487j),0.004676244514395839,1.257851704672455,0.5601043060592626,0.6027272641658783
108,442368,4698459,0.055296,0,5,73344,True,True,True,0.27365159790299287,(0.0015497665053611947+0.004564716338565147j),0.004820623556419133,1.243497177656846,0.5584733039849059,0.6036799997091293
109,446464,4702555,0.055808,0,5,77440,True,True,True,0.2633210162250354,(0.0013221811004029498+0.004381795354342359j),0.004576930564209931,1.2777401668138901,0.5471677345553811,0.5879338681697845
110,450560,4706651,0.05632,0,5,81536,True,True,True,0.26824181335626013,(0.0012740111219966598+0.004465711961654281j),0.0046438871286276235,1.29289142838727,0.5420455105218226,0.5840716063976288
111,454656,4710747,0.056832,0,5,85632,True,True,True,0.26388173742294235,(0.0014123473641952727+0.004534563825781714j),0.004749420403295272,1.2688567766150023,0.5375280882444592,0.5777595490217209
112,458752,4714843,0.057344,0,5,89728,False,True,False,0.2522196006429852,(0.0013772325045995537+0.004293720322152726j),0.004509191011322637,1.2604086118008029,0.5350556534434683,0.5714054554700851
113,462848,4725035,0.057856,6096,6,1568,False,True,False,0.2771232078693172,(-0.0020002876001643417+0.004297049846018963j),0.004739808842405231,2.0064671134474126,0.5274695198960893,0.5713474452495575
114,466944,4725067,0.058368,2032,6,5664,False,True,False,0.27702128795645814,(0.00413210728460306-0.002319090529045502j),0.004738406007654707,-0.5114293343015762,0.5277817565190994,0.5716506838798523
115,471040,4725099,0.05888,-2032,6,9760,False,True,False,0.276592565978206,(-0.004702814275236275-0.000545451646585368j),0.004734340461577387,-3.0261244877072064,0.5278071537418947,0.5715312659740448
116,475136,4731227,0.059392,0,6,13856,False,True,False,0.261387587164352,(0.0011452191894361628+0.004324249063830631j),0.0044733272804359965,1.3119033303989793,0.5314278199197381,0.5703994929790497
117,479232,4735323,0.059904,0,6,17952,False,True,False,0.26600518395588735,(0.0011882035152338427+0.00440899760787155j),0.004566299103194086,1.307555089993816,0.5333333931089501,0.5739450305700302
118,483328,4739419,0.060416,0,6,22048,False,True,False,0.26354711468027764,(0.0012722185803642125+0.004339840170588295j),0.00452247198139201,1.285636904251594,0.5330185708165498,0.5728038549423218
119,487424,4743516,0.060928,1,6,26144,True,True,True,0.2655258469985231,(0.0010413614298705306+0.004482633907505584j),0.004602003952230026,1.3425349502168569,0.5439972900983086,0.5852604806423187
120,491520,4747612,0.06144,1,6,30240,True,True,True,0.27026658341105503,(0.0006871157719793929+0.004660496024741168j),0.0047108758507024015,1.424416812159449,0.5483031597970439,0.5915093868970871
121,495616,4751707,0.061952,0,6,34336,True,True,True,0.27212727343914983,(0.00103874048233643+0.004593169010476414j),0.004709159516139308,1.3483885391116444,0.5392289521801527,0.5823541730642319
122,499712,4755803,0.062464,0,6,38432,True,True,True,0.28136708133251975,(0.0015478134989297052+0.004631816125900667j),0.00488358958673049,1.248293057797807,0.5387114553079869,0.5850265026092529
123,503808,4759899,0.062976,0,6,42528,True,True,True,0.27890087509243017,(0.0013600301944214322+0.00462867624870359j),0.004824347204031933,1.2850123849861281,0.5356196312800044,0.5807973593473434
124,507904,4763995,0.063488,0,6,46624,True,True,True,0.26336035378327605,(0.001049261617941425+0.0043808875864818145j),0.004504789227952348,1.3357157400217448,0.5320584679757843,0.5717116296291351
125,512000,4768091,0.064,0,6,50720,True,True,True,0.26497822213724925,(0.001099080196697002+0.00443634202713449j),0.004570460355422775,1.3279414286903835,0.5397274050774757,0.5804852843284607
126,516096,4772188,0.064512,1,6,54816,True,True,True,0.2588557900323732,(0.0013698338171910028+0.004291962654778482j),0.004505262269472581,1.2618532123786583,0.5491224961879504,0.5885597169399261
127,520192,4776284,0.065024,1,6,58912,True,True,True,0.26525822500006635,(0.0014099236859939925+0.004358861980797595j),0.004581218458878557,1.2579566494377912,0.5409942829315486,0.5819407552480698
128,524288,4780379,0.065536,0,6,63008,True,True,True,0.2663899652999382,(0.0013118458205982157+0.004388013938848249j),0.004579913294435554,1.2802928513905263,0.5342598690886164,0.5750688314437866
129,528384,4784475,0.066048,0,6,67104,True,True,True,0.25666966629660665,(0.0012463167346545275+0.004264542171658961j),0.004442929814541037,1.286463776193324,0.5445433095922607,0.5829474925994873
130,532480,4788571,0.06656,0,6,71200,True,True,True,0.2606059923710226,(0.001271455909544945+0.004320777588694721j),0.00450396704038599,1.2846087811950069,0.54270473673413,0.5822484195232391
131,536576,4792667,0.067072,0,6,75296,True,True,True,0.2670879834822261,(0.001595899119666262+0.004329908780645395j),0.00461465102135163,1.2176697888301709,0.5365249042267309,0.5777384489774704
132,540672,4796763,0.067584,0,6,79392,True,True,True,0.26593394499633477,(0.001477311710559645+0.004342725822956805j),0.004587125185073165,1.2428958119988545,0.5347466339577565,0.5754424184560776
133,544768,4800859,0.068096,0,6,83488,True,True,True,0.2652553665245194,(0.0013141328612987792+0.004389330045641679j),0.004581829702937256,1.2798968884696806,0.5400880761578909,0.5809650123119354
134,548864,4804955,0.068608,0,6,87584,False,True,False,0.25548083595374993,(0.0015057567714245848+0.004342790980108081j),0.004596426541521042,1.2370415480903751,0.542590490303864,0.5804785937070847
135,552960,4817180,0.06912,8129,6,91680,False,True,False,0.26036916131092225,(0.004673620949138175+0.00024960406064367444j),0.0046802815047081335,0.05335630613581867,0.5395512157685356,0.5787885040044785
136,557056,4817212,0.069632,4065,7,3520,False,True,False,0.27341327144153854,(-0.0035304699699410433-0.003130835945304359j),0.004718723548277156,-2.416116014289601,0.5372784161036481,0.5806876122951508
137,561152,4817244,0.070144,1,7,7616,False,True,False,0.27403920750408217,(0.001010539602555097+0.004616804647374057j),0.0047261057373218915,1.355311797069995,0.5376433134511249,0.5812972784042358
138,565248,4817276,0.070656,-4063,7,11712,False,True,False,0.2746479667516686,(0.0018912570769004213-0.004346463071505326j),0.004740104910535782,-1.1603806139411221,0.5378884612654133,0.5817724317312241
139,569344,4825435,0.071168,0,7,15808,False,True,False,0.25937216918957146,(0.0011938454665440122+0.004362559508218352j),0.004522962796744413,1.3036790097834017,0.5521339003347727,0.5919571816921234
140,573440,4829531,0.07168,0,7,19904,False,True,False,0.26774346245706554,(0.0009418111768576637+0.004568398639175929j),0.004664469360953987,1.3674868432051928,0.5443368442013263,0.5863718241453171
141,577536,4833627,0.072192,0,7,24000,True,True,True,0.26587676777880576,(0.001102610189571028+0.004463079859444132j),0.0045972634318604925,1.3285947230861475,0.5408037074042943,0.5819414108991623
142,581632,4837724,0.072704,1,7,28096,True,True,True,0.2619208785763954,(0.0012054341276794263+0.004364128878079499j),0.004527548155532052,1.3013016855057298,0.5421426589707972,0.582074448466301
143,585728,4841820,0.073216,1,7,32192,True,True,True,0.26004799444738186,(0.0012996243478831987+0.004280701998500875j),0.004473637563055396,1.2760393722352807,0.5373060159033105,0.5762767046689987
144,589824,4845916,0.073728,1,7,36288,True,True,True,0.26352682248810066,(0.0013929034499800838+0.004376577528341034j),0.004592886987782971,1.2626696720599786,0.5511815324075017,0.5923157185316086
145,593920,4850011,0.07424,0,7,40384,True,True,True,0.27321560983225973,(0.0014136076722512999+0.004603422423890218j),0.004815577292892621,1.2728590831142508,0.560267982433693,0.605463907122612
146,598016,4854107,0.074752,0,7,44480,True,True,True,0.2697569569525196,(0.0012948903346004814+0.004510190476376705j),0.00469239375072477,1.2912130045767223,0.5456335561563538,0.5884547084569931
147,602112,4858203,0.075264,0,7,48576,True,True,True,0.26704062643742627,(0.0014034649430516995+0.004351442985962747j),0.004572173433549901,1.258801319004848,0.5305424443764983,0.5712808817625046
148,606208,4862299,0.075776,0,7,52672,True,True,True,0.26110270903330773,(0.001204834540491995+0.004328357525056808j),0.004492917218765382,1.299310555739649,0.5375498470396575,0.5768783092498779
149,610304,4866396,0.076288,1,7,56768,True,True,True,0.24788848233138613,(0.000885925455637422+0.004191896025296573j),0.004284490191358078,1.3625187593746237,0.5466587176655056,0.5824494808912277
150,614400,4870491,0.0768,0,7,60864,True,True,True,0.2601141176285434,(0.0013182434384379415+0.004314238663366558j),0.004511144090745888,1.2742497022015684,0.5462691178352976,0.5859115123748779
151,618496,4874587,0.077312,0,7,64960,True,True,True,0.27010121357136685,(0.0014941599628287964+0.004411796556139344j),0.004657946204850752,1.2442470656108626,0.5370899949431283,0.579356774687767
152,622592,4878683,0.077824,0,7,69056,True,True,True,0.2758319253957052,(0.0012682927921888675+0.004576544230142604j),0.004749033975154294,1.3004519486229928,0.5343123720322084,0.5783122479915619
153,626688,4882779,0.078336,0,7,73152,True,True,True,0.27404653150617597,(0.0011890329932240313+0.004588957075942728j),0.004740498550133744,1.3172644783717473,0.5393673486206108,0.5831638276576996
154,630784,4886875,0.078848,0,7,77248,True,True,True,0.27119602861279707,(0.001236306317670613+0.004529799008937786j),0.004695479993833008,1.3043580041913996,0.5387397575259696,0.5815081000328064
155,634880,4890971,0.07936,0,7,81344,True,True,True,0.27342762369718,(0.0012399300344019713+0.004586782940726171j),0.004751421285841605,1.3067799874345216,0.5439590769382545,0.5879130214452744
156,638976,4895067,0.079872,0,7,85440,True,True,True,0.25670283077288303,(0.0014843755553559303+0.004419445796424099j),0.004662067345810103,1.246761198916183,0.5523321337147029,0.5912964046001434
157,643072,4899163,0.080384,0,7,89536,False,True,False,0.25712482738830733,(0.0016360898784780716+0.004385459434551182j),0.00468070983319329,1.213717477491946,0.5544384543875003,0.5936891287565231
158,647168,4913419,0.080896,10160,8,1376,False,True,False,0.2738845838199934,(-0.0015876886917470013-0.004421074468700674j),0.004697515815800758,-1.9155711352157767,0.531179403244459,0.5742559283971786
159,651264,4913451,0.081408,6096,8,5472,False,True,False,0.2747492677176624,(-0.0013158162001726363+0.004526012931705732j),0.00471340273375873,1.853720561422047,0.5310687131217184,0.5744308680295944
160,655360,4913483,0.08192,2032,8,9568,False,True,False,0.2747634003920657,(0.003737797470948664-0.0028737000744164056j),0.004714793956423873,-0.6554386217012346,0.5309266415904615,0.5742820203304291
161,659456,4915547,0.082432,0,8,13664,False,True,False,0.2760058670060885,(0.0016051542012133788+0.00447398890371161j),0.004753219616239878,1.2263258552386604,0.5340496829226165,0.5780879855155945
162,663552,4919643,0.082944,0,8,17760,False,True,False,0.27497714732101164,(0.0016332720032709552+0.004516072649607772j),0.00480234209664452,1.2237740985103753,0.5476249916746951,0.5924192517995834
163,667648,4923739,0.083456,0,8,21856,False,True,False,0.2733575276500988,(0.0016469296756453885+0.004519756643704177j),0.004810465411457552,1.221364639004181,0.556940211069477,0.6019181460142136
164,671744,4927835,0.083968,0,8,25952,True,True,True,0.2655826518710453,(0.0013094385268856785+0.004465689287358343j),0.004653709280447115,1.2855693847150558,0.5558054338160154,0.5979837030172348
165,675840,4931932,0.08448,1,8,30048,True,True,True,0.2620066553332512,(0.0010008056079044434+0.0044481756529488265j),0.00455937259985403,1.3494891413311099,0.5494416678685756,0.589939534664154
166,679936,4936027,0.084992,0,8,34144,True,True,True,0.25745610810815944,(0.0012829361577189977+0.004307185143174958j),0.004494192813216837,1.281304418017169,0.5547843706430848,0.5941679924726486
167,684032,4940123,0.085504,0,8,38240,True,True,True,0.26383925616404263,(0.0012050656839874409+0.004426963193058868j),0.004588048214156221,1.3050253747795577,0.5481423154096086,0.5891540050506592
168,688128,4944220,0.086016,1,8,42336,True,True,True,0.2699244067190662,(0.0008380194484942735+0.004581934378772789j),0.004657939377818761,1.389899279461403,0.5367680805238122,0.578949898481369
169,692224,4948315,0.086528,0,8,46432,True,True,True,0.2691021030184952,(0.00121419546525523+0.0044533788553063475j),0.00461593477604873,1.304620022784614,0.53117277336095,0.5726411193609238
170,696320,4952411,0.08704,0,8,50528,True,True,True,0.26370857056758684,(0.0015938477998613623+0.004269459998787447j),0.00455726228018193,1.213504897991644,0.5379725842213715,0.5781805366277695
171,700416,4956507,0.087552,0,8,54624,True,True,True,0.2568596341044175,(0.001446965486859506+0.004214076097215652j),0.004455574763516697,1.240044764929582,0.5458980072328209,0.5844587683677673
172,704512,4960604,0.088064,1,8,58720,True,True,True,0.26834124851878693,(0.0008934368200219986+0.0046038240991153915j),0.0046897148833342376,1.3791148572475473,0.5527223312153192,0.5956104695796967
173,708608,4964700,0.088576,1,8,62816,True,True,True,0.2773340662906,(0.0009627857840257513+0.004797044213699565j),0.004892707803876148,1.372723971241416,0.560669449801557,0.60738605260849
174,712704,4968795,0.089088,0,8,66912,True,True,True,0.2678611827980943,(0.0010743244283594811+0.0045672352206597025j),0.004691887737169807,1.3397718736689235,0.5551330463819606,0.5980423539876938
175,716800,4972891,0.0896,0,8,71008,True,True,True,0.26521123625627346,(0.0010548052056041765+0.004463329559517832j),0.004586275698062134,1.3387272036829811,0.5424371911275525,0.5834772288799286
176,720896,4976987,0.090112,0,8,75104,True,True,True,0.25737022850050784,(0.0011324525934055022+0.004313776409934131j),0.004459945716173578,1.314069283511442,0.5453875555595226,0.5840764492750168
177,724992,4981083,0.090624,0,8,79200,True,True,True,0.26016421509739096,(0.0013264669173897253+0.00434301814084294j),0.004541070474526934,1.2743698025520087,0.554166359432325,0.5943984687328339
178,729088,4985180,0.091136,1,8,83296,True,True,True,0.2783413309071134,(0.0013001352711514097+0.00466852028999491j),0.004846177196655742,1.299188582266864,0.545488141480179,0.5912983268499374
179,733184,4989275,0.091648,0,8,87392,False,True,False,0.2669927542714062,(0.0010690162338773935+0.0047141621899569105j),0.004833851555593401,1.347800703208135,0.54517560929071,0.5870215147733688
180,737280,4999467,0.09216,6096,8,91488,False,True,False,0.24816357519383125,(-0.0014479165006434653+0.0043169281492356215j),0.004553276934088076,1.8944096410174938,0.5657326760074871,0.6028598994016647
181,741376,5001531,0.092672,4064,9,3328,False,True,False,0.2740896007100458,(-0.0037899232005933095-0.002977920345328503j),0.004819909485614524,-2.475603261145279,0.5575766126187574,0.602867066860199
182,745472,5001563,0.093184,0,9,7424,False,True,False,0.2743042616798551,(0.00130453694455819+0.004636674957322557j),0.004816697135961462,1.296534520595517,0.5566299001124788,0.6019200682640076
183,749568,5001595,0.093696,-4064,9,11520,False,True,False,0.27343656950933776,(0.0016448575650682739-0.0045140736020721755j),0.00480441639476505,-1.2213648928016885,0.5571284056004779,0.6021496653556824
184,753664,5009755,0.094208,0,9,15616,False,True,False,0.24644837794190042,(0.0014424054288444065+0.004024460919176389j),0.004275139659840118,1.226649391143599,0.5499930625137114,0.5855579823255539
185,757760,5013851,0.09472,0,9,19712,False,True,False,0.24879306161420675,(0.0012449191670893779+0.004102749387320414j),0.0042874673488837835,1.2761908291392956,0.5429787220660903,0.5788056254386902
186,761856,5017947,0.095232,0,9,23808,False,True,False,0.26695567150173954,(0.0011847130863471237+0.004528474155278807j),0.004680878472251788,1.3149168858210374,0.5535382083577316,0.5960132926702499
187,765952,5022043,0.095744,0,9,27904,True,True,True,0.2637983930091585,(0.0012155635620488801+0.004491220067611713j),0.004652811243656798,1.3064756759036986,0.5633993665169301,0.605538547039032
188,770048,5026139,0.096256,0,9,32000,True,True,True,0.2601781313069146,(0.0014610321221578382+0.004345406927177649j),0.004584449391665322,1.2464460140416111,0.5636380757930741,0.604562520980835
189,774144,5030236,0.096768,1,9,36096,True,True,True,0.2574682516876231,(0.001298756614798111+0.004280571292086525j),0.004473260481026915,1.276216500083633,0.5491678509292242,0.5881567001342773
190,778240,5034331,0.09728,0,9,40192,True,True,True,0.2557230534224733,(0.001108738527750533+0.004290301714831174j),0.004431251508005581,1.3179003234342883,0.5472720788091381,0.5855646580457687
191,782336,5038427,0.097792,0,9,44288,True,True,True,0.2591844276449496,(0.0011696742442483666+0.004405803800622378j),0.004558425711496962,1.3112975975206218,0.5608249286130765,0.6012123078107834
192,786432,5042523,0.098304,0,9,48384,True,True,True,0.26868207485726564,(0.0011177235910650781+0.004592068204744255j),0.004726139695676223,1.3320360923306238,0.5598665867529256,0.6034280955791473
193,790528,5046619,0.098816,0,9,52480,True,True,True,0.26639007139566734,(0.0012616732316124942+0.004464204940363573j),0.004639067265403041,1.295359831326025,0.5482883426646452,0.5901688933372498
194,794624,5050715,0.099328,0,9,56576,True,True,True,0.2536069365130275,(0.0014990938223051057+0.004108733154170838j),0.0043736678452136685,1.220949003984714,0.5422185106395125,0.579489216208458
195,798720,5054811,0.09984,0,9,60672,True,True,True,0.26324630262348936,(0.0014473933824976843+0.004342594477702816j),0.004577452828973017,1.2490743958972919,0.5487804343548445,0.5896417945623398
196,802816,5058907,0.100352,0,9,64768,True,True,True,0.26746161674679997,(0.0013964631045754207+0.004455196331173598j),0.00466892745196829,1.2670499289100425,0.5509006238761466,0.5933460593223572
197,806912,5063003,0.100864,0,9,68864,True,True,True,0.25574049545490446,(0.0013486357963794198+0.004207392214630718j),0.004418253926497562,1.2606039860007627,0.5440070331470497,0.5820767134428024
198,811008,5067100,0.101376,1,9,72960,True,True,True,0.2629884708976966,(0.001045123129219692+0.0044137623372614765j),0.004535810878449172,1.3382912235991724,0.540570451212055,0.5807358473539352
199,815104,5071195,0.101888,0,9,77056,True,True,True,0.2873942479114494,(0.0010623899727609538+0.004878621166164128j),0.0049929567329557,1.3563794191279657,0.538916393710259,0.5874359309673309
200,819200,5075291,0.1024,0,9,81152,True,True,True,0.2725851962025746,(0.0010468577792493766+0.0046323056860140535j),0.004749122779909261,1.3485391685098471,0.5472674857602668,0.5911948531866074
201,823296,5079387,0.102912,0,9,85248,True,True,True,0.2513843183766455,(0.001134941201452397+0.00439649283533871j),0.004540621188993728,1.3181647689098932,0.5467931267368271,0.583678126335144
202,827392,5083483,0.103424,0,9,89344,False,True,False,0.26256421755141157,(0.0010627634370894722+0.0046536944780845866j),0.004773503788473327,1.3462767516536025,0.5515670240928654,0.5924075841903687
203,831488,5091643,0.103936,4064,10,1184,False,True,False,0.27258876397618037,(-0.0038680063793312966-0.00277723489387529j),0.004761775614863231,-2.5188869491625456,0.5512196226945838,0.5954654663801193
204,835584,5091675,0.104448,0,10,5280,False,True,False,0.27240588233562446,(0.001487311386628569+0.0045247471758307605j),0.0047629226495906314,1.2532161691794101,0.55156569647999,0.5957751721143723
205,839680,5091707,0.10496,-4064,10,9376,False,True,False,0.2721740620175623,(0.0014356126180578048-0.00453346011489686j),0.004755338495048216,-1.264116616301169,0.5513755050294287,0.5954885333776474
206,843776,5099867,0.105472,0,10,13472,False,True,False,0.2594300166800149,(0.0014767794994913843+0.004273745334716329j),0.004521700661933252,1.2380941194824366,0.5523710983458887,0.5922305434942245
207,847872,5103963,0.105984,0,10,17568,False,True,False,0.2635039470208177,(0.0012883266803848526+0.004463702338228557j),0.004645904023943945,1.2898096493804307,0.5612177508783607,0.6030931174755096
208,851968,5108059,0.106496,0,10,21664,False,True,False,0.26676893350381925,(0.0011085188613918987+0.0045316800695588055j),0.00466529080753795,1.330891881128166,0.5533470249568841,0.5957435071468353
209,856064,5112155,0.107008,0,10,25760,True,True,True,0.26769649861033307,(0.0009767804087360958+0.004581372966701971j),0.004684343948400701,1.360734656079032,0.5538200423149755,0.5965711772441864
210,860160,5116251,0.10752,0,10,29856,True,True,True,0.256131266937885,(0.0009048122182806056+0.00439301727572447j),0.004485229752773376,1.367670860405023,0.5571939318707251,0.5963140577077866
211,864256,5120347,0.108032,0,10,33952,True,True,True,0.25301897115559957,(0.0010068931640645764+0.004322075987329293j),0.0044378119252722345,1.341913576472646,0.5601182547167346,0.5984288305044174
212,868352,5124443,0.108544,0,10,38048,True,True,True,0.26696855591367613,(0.0012309215601142838+0.004492112724254102j),0.004657708086018251,1.3033429265307364,0.5505673324772662,0.5928188413381577
213,872448,5128539,0.109056,0,10,42144,True,True,True,0.26061560705088677,(0.0014043112701381327+0.004290370017869034j),0.004514351009133707,1.2544701620679264,0.5449885148501848,0.5847017467021942
214,876544,5132635,0.109568,0,10,46240,True,True,True,0.26336949602200077,(0.0015175076975572559+0.004303237990655464j),0.004562969079049955,1.231768689979611,0.5437184754310922,0.584243655204773
215,880640,5136731,0.11008,0,10,50336,True,True,True,0.27464480256794577,(0.0016993485450312845+0.004501897630615793j),0.004811950514504906,1.2098585843646474,0.551037136036287,0.5959927290678024
216,884736,5140827,0.110592,0,10,54432,True,True,True,0.27500097293793924,(0.0016943086540589032+0.004499716621939183j),0.004808131809026731,1.21067905365459,0.5508883384485461,0.5959579795598984
217,888832,5144923,0.111104,0,10,58528,True,True,True,0.27728841349715994,(0.0014592047535882462+0.004608045616475609j),0.004833566273096357,1.264121918909197,0.5470731589989841,0.5926406234502792
218,892928,5149019,0.111616,0,10,62624,True,True,True,0.2808954442284297,(0.001321540028381485+0.004706366969990381j),0.00488839013406571,1.2970474776506113,0.5431006966767402,0.5896233022212982
219,897024,5153115,0.112128,0,10,66720,True,True,True,0.26688871885297244,(0.0012163594036441242+0.004456810196717522j),0.004619814642212257,1.3043634891796592,0.542377872830745,0.5839741080999374
220,901120,5157211,0.11264,0,10,70816,True,True,True,0.2584040243452016,(0.0012297490842230225+0.00434190848764283j),0.004512698984555939,1.2947970233139183,0.5552511155037323,0.594979465007782
221,905216,5161307,0.113152,0,10,74912,True,True,True,0.26956783335469564,(0.0014425355859659845+0.004480879786438754j),0.004707355157335554,1.2593424341663264,0.549948134696654,0.5930426567792892
222,909312,5165403,0.113664,0,10,79008,True,True,True,0.2860522821392337,(0.0014710913905272292+0.004750496996945799j),0.004973060586527616,1.2704907946331834,0.5395488067357961,0.5876323580741882
223,913408,5169500,0.114176,1,10,83104,True,True,True,0.28140672063874517,(0.0010721642674111451+0.00477187328708063j),0.0048908394866594195,1.3497825405392807,0.5418614433934189,0.5884615629911423
224,917504,5173596,0.114688,1,10,87200,False,True,False,0.25867954021012346,(0.0009839169384996689+0.00453073974476785j),0.004636345023473296,1.3569519895502433,0.5357271852248144,0.5741462409496307
225,921600,5177692,0.1152,1,10,91296,False,True,False,0.26237223676573584,(0.0011429895995709038+0.00454483339878272j),0.004686356350878383,1.3244138479151768,0.5322185693016872,0.5715646147727966
226,925696,5181787,0.115712,0,11,3136,False,True,False,0.2701034954758276,(0.0013597724802481925+0.0044589495582259085j),0.004661674845036207,1.2748012130593906,0.5383609316350877,0.5807285010814667
227,929792,5181819,0.116224,-4064,11,7232,False,True,False,0.26852876195676684,(0.0015255994291846465-0.00438126032616622j),0.004639277493744758,-1.235716894414013,0.5394909994438597,0.5814155340194702
228,933888,5181851,0.116736,-8128,11,11328,False,True,False,0.26892700058895613,(-0.003820842233905499+0.0026459066180629393j),0.004647543136744965,2.535922712155432,0.5400452058880975,0.582147091627121
229,937984,5194076,0.117248,1,11,15424,False,True,False,0.2691833879073944,(0.0010258072970440611+0.0047867337971681965j),0.004895416331183805,1.3596872888997011,0.5980976072263786,0.6448211520910263
230,942080,5198171,0.11776,0,11,19520,False,True,False,0.27073871499175883,(0.0013708190441480024+0.004736808820083946j),0.0049311765989288915,1.289095063901871,0.5949415767398565,0.6419998109340668
231,946176,5202267,0.118272,0,11,23616,False,True,False,0.25498334889723284,(0.0013814387836797268+0.004397449823860593j),0.0046093316290353945,1.2664131183099794,0.5954814634201167,0.6368898153305054
232,950272,5206364,0.118784,1,11,27712,True,True,True,0.2520701625705865,(0.0009223825889995769+0.004332380078972095j),0.004429481548574711,1.3610240803390832,0.5634445223882787,0.6016745418310165
233,954368,5210460,0.119296,1,11,31808,True,True,True,0.26164867311179046,(0.0008087107334952197+0.004453052814775219j),0.004525891340017774,1.391146134456171,0.5444633618706969,0.5844766497612
234,958464,5214555,0.119808,0,11,35904,True,True,True,0.26854883778171956,(0.0012413561194861147+0.004505624623853556j),0.004673501713539979,1.3019536667625724,0.5487865994516878,0.5914403796195984
235,962560,5218651,0.12032,0,11,40000,True,True,True,0.2726733173974843,(0.001378589420936903+0.004526878296162865j),0.004732138617981256,1.2751848920096938,0.5424629878076264,0.5860351324081421
236,966656,5222747,0.120832,0,11,44096,True,True,True,0.26774424452520174,(0.0013053061679331418+0.0044299709635238094j),0.004618275319825397,1.2842518255973607,0.5379742199872226,0.579518124461174
237,970752,5226844,0.121344,1,11,48192,True,True,True,0.2529277516354949,(0.0009143590480539627+0.004254492347760584j),0.0043516384966942635,1.359100328612116,0.5398657003944332,0.5767626166343689
238,974848,5230940,0.121856,1,11,52288,True,True,True,0.2678507653416655,(0.0010920771787949514+0.004531790102875468j),0.0046615184329749015,1.3343235913479703,0.5483664187313746,0.5907491445541382
239,978944,5235035,0.122368,0,11,56384,True,True,True,0.27166443355630754,(0.0013576998340728897+0.004544220909553324j),0.004742709406474656,1.2804637172622124,0.5497189797711337,0.5935218185186386
240,983040,5239132,0.12288,1,11,60480,True,True,True,0.24298761555141254,(0.0009359177755966125+0.00412392315729343j),0.004228792296854827,1.3476281418310532,0.5537337934408951,0.5884793698787689
241,987136,5243228,0.123392,1,11,64576,True,True,True,0.2594503125405808,(0.000872214900954877+0.004443342101533314j),0.004528139558881353,1.3769638279001095,0.5535284658088118,0.5934781283140182
242,991232,5247323,0.123904,0,11,68672,True,True,True,0.2728972761722316,(0.0010649047350872493+0.00460220143954971j),0.004723799337927541,1.343407899747667,0.5392853326323054,0.5826791524887085
243,995328,5251420,0.124416,1,11,72768,True,True,True,0.2677790176885852,(0.0010331007579770734+0.004533070798005724j),0.004649304037795878,1.346720423115713,0.5431229706384719,0.5850762128829956
244,999424,5255516,0.124928,1,11,76864,True,True,True,0.27273585576465686,(0.001190185230456936+0.004606812727866582j),0.004758073600989309,1.317971325646566,0.5488263894264966,0.5929315090179443
245,1003520,5259611,0.12544,0,11,80960,True,True,True,0.277553334130381,(0.001377950261444966+0.004616611618738488j),0.00481786776087591,1.2807377876274038,0.5415111722890744,0.5867087841033936
246,1007616,5263707,0.125952,0,11,85056,True,True,True,0.2655589509320627,(0.0011514306146589667+0.004635249098410475j),0.004776120461702055,1.3273170531356284,0.5375551530033255,0.5783406347036362
247,1011712,5267804,0.126464,1,11,89152,False,True,False,0.25538412849058145,(0.0009827635050397186+0.004463016645785106j),0.004569938915061435,1.3540537158216441,0.535083797776337,0.5724174678325653
248,1015808,5280027,0.126976,8128,12,992,False,True,False,0.2812606928866462,(0.0048793151638969095+8.05644236800617e-05j),0.004879980235103132,0.016509920106764792,0.5399580759163802,0.5863421857357025
249,1019904,5278028,0.127488,2033,12,5088,False,True,False,0.2816763742277087,(0.0041030436954555246-0.002639239528791662j),0.004878581029065087,-0.5716079390475177,0.5385550842790271,0.584967315196991
250,1024000,5278060,0.128,-2031,12,9184,False,True,False,0.28242789552891234,(-0.004878754419270177-0.0002662660909589648j),0.004886014972832446,-3.0870700906873467,0.5376792656874811,0.5842850655317307
251,1028096,5278091,0.128512,-6096,12,13280,False,True,False,0.2681008918313915,(0.0038474847466956337+0.0025998928860442062j),0.004643552723396047,0.5942567128822575,0.5426132080040174,0.5846357047557831
252,1032192,5288283,0.129024,0,12,17376,False,True,False,0.24375932875272263,(0.0011357620006579774+0.0040703688113794805j),0.0042258558402753655,1.2986857372531115,0.5460942745071787,0.5805922597646713
253,1036288,5292379,0.129536,0,12,21472,False,True,False,0.25538271104520355,(0.0011127166312888783+0.004253423429781606j),0.004396561062303354,1.3149255298493328,0.5379460291956822,0.5754789561033249
254,1040384,5296476,0.130048,1,12,25568,True,True,True,0.2632105657612795,(0.0011581742548442148+0.0043932573571891466j),0.004543355347216472,1.313035430034399,0.5401483179505394,0.5803552120923996
255,1044480,5300571,0.13056,0,12,29664,True,True,True,0.26986947258717187,(0.0013068274108764114+0.004486378559068552j),0.004672835376630335,1.2873514021821055,0.541962749115588,0.5845340937376022
256,1048576,5304667,0.131072,0,12,33760,True,True,True,0.2716474398335631,(0.0014068769556635232+0.0045219013663756165j),0.004735704249169993,1.2691645381137087,0.5479715361191466,0.5916292369365692
257,1052672,5308763,0.131584,0,12,37856,True,True,True,0.2602069168691974,(0.0014259509292018208+0.004322987510848465j),0.004552093701962135,1.2521812254494566,0.553095674227995,0.5932641923427582
258,1056768,5312859,0.132096,0,12,41952,True,True,True,0.26067296967171716,(0.001243339607338989+0.004388924606338943j),0.004561639242564598,1.294739177254704,0.5553010262917414,0.5957848429679871
259,1060864,5316955,0.132608,0,12,46048,True,True,True,0.2763320728115187,(0.001091005945684809+0.004723962722877519j),0.004848310817249239,1.3438244988245012,0.5541697016465323,0.5999841392040253
260,1064960,5321051,0.13312,0,12,50144,True,True,True,0.2754645271489226,(0.0013234191848957258+0.0046175039478779465j),0.004803413478727236,1.2916694754434184,0.5464955195365455,0.591369017958641
261,1069056,5325147,0.133632,0,12,54240,True,True,True,0.26852039912809356,(0.0015103311655884739+0.00438350483122627j),0.004636401064956728,1.2389860736762326,0.5387882672532496,0.5806553810834885
262,1073152,5329243,0.134144,0,12,58336,True,False,False,0.12222192020312277,(0.0016917557631161454+0.0040214872795306614j),0.004362842823373725,1.172591181605333,2.4462056325581023,2.4833016842603683
263,1077248,5333339,0.134656,0,12,62432,True,False,False,0.08371985216496043,(0.001522863605885863+0.004194885739388139j),0.004462754746639531,1.2225621889916407,5.489172343866355,5.527917593717575
264,1081344,5337436,0.135168,1,12,66528,True,False,False,0.07678297321464417,(0.000837113473129972+0.004424337184075886j),0.004502834494548102,1.383800318183157,6.664573420147217,6.704098269343376
265,1085440,5341532,0.13568,1,12,70624,True,False,False,0.075825225755414,(0.0010644786672962556+0.0043263854821034625j),0.0044554153760210085,1.329544959208023,6.688882765976795,6.72756265103817
266,1089536,5345627,0.136192,0,12,74720,True,False,False,0.0777915075019332,(0.0013604196351404264+0.004361358503073744j),0.00456860915115413,1.2684347849139403,6.676964480041531,6.717616260051727
267,1093632,5349723,0.136704,0,12,78816,True,False,False,0.0828610428066847,(0.0015486982431894794+0.004585583083988033j),0.004840045296132608,1.2450921911444341,6.60539333945425,6.651059195399284
268,1097728,5353821,0.137216,2,12,82912,True,False,False,0.08195769883417732,(0.0011937036958979035+0.004685608387128368j),0.004835271912842961,1.3213430856688024,6.74911831950998,6.794759154319763
269,1101824,5357917,0.137728,2,12,87008,False,False,False,0.0716654800554192,(0.0005531018437636853+0.004432103696542682j),0.004466482377272085,1.4466437471388893,6.906468290897046,6.942122623324394
270,1105920,5366076,0.13824,4065,12,91104,False,False,False,0.07377076771462239,(-0.004091817902133142-0.0020419652606560356j),0.004573029178776726,-2.6787163810812644,6.832708365234196,6.870096296072006
271,1110016,5374235,0.138752,8128,13,2944,False,False,False,0.08087575586757796,(0.004779806391792624+8.861341029904627e-05j),0.004780627728604942,0.018536997739119303,6.768167156707149,6.812728449702263
272,1114112,5374267,0.139264,4064,13,7040,False,False,False,0.0800133242828991,(-0.003767808252151954-0.0028533788785221463j),0.004726325216209805,-2.4934329082951177,6.763541054221683,6.807121142745018
273,1118208,5374299,0.139776,0,13,11136,False,False,False,0.07956224503645665,(0.0013792993209312803+0.004496803629903398j),0.004703584750234004,1.273177782321964,6.7703096256518736,6.813439726829529
274,1122304,5378395,0.140288,0,13,15232,False,False,False,0.07909923134694494,(0.0015060370202961348+0.004398239469498638j),0.004648941593261645,1.2408918421229516,6.697100535491124,6.739266023039818
275,1126400,5382492,0.1408,1,13,19328,False,False,False,0.07780223075074265,(0.001290172857201479+0.0043936989878511305j),0.0045792070052907054,1.2851830749053166,6.6471269868946585,6.687608331441879
276,1130496,5386588,0.141312,1,13,23424,False,False,False,0.07864006701111693,(0.0010540703263440517+0.004463093516908906j),0.004585877014656342,1.3388713181506051,6.581861800468286,6.622819036245346
277,1134592,5390682,0.141824,-1,13,27520,True,False,False,0.08301430893626999,(0.0015449788316282908+0.004589310350730047j),0.004842388778846393,1.2460661944160356,6.588775629410941,6.634496435523033
278,1138688,5394779,0.142336,0,13,31616,True,False,False,0.07878097899540573,(0.001481786310700397+0.004374651467605647j),0.004618794878927114,1.24420473670389,6.651206343796035,6.692744478583336
279,1142784,5398876,0.142848,1,13,35712,True,False,False,0.09576023729412096,(0.0010937122441491563+0.004038675938138141j),0.004184149830765837,1.3063300491750123,3.679667399162275,3.7137223184108734
280,1146880,5402972,0.14336,1,13,39808,True,True,True,0.2383815900640343,(0.0012815346971280827+0.004158815962114253j),0.004351790595453722,1.2718803162847057,0.6127624549315758,0.6496810913085938
281,1150976,5407067,0.143872,0,13,43904,True,True,True,0.26364871875573537,(0.0013686838317304665+0.004418645928249998j),0.004625767749301804,1.2704170494974214,0.5558803660749743,0.5974064767360687
282,1155072,5411164,0.144384,1,13,48000,True,True,True,0.26715586396351754,(0.0012130199951223312+0.004499399727171521j),0.004660044572044107,1.3074611161349192,0.5495655838572667,0.5918039679527283
283,1159168,5415260,0.144896,1,13,52096,True,True,True,0.25698590459791865,(0.001158258764511068+0.004307109301455813j),0.004460129359139025,1.3080933467821958,0.5475274608915194,0.5862440466880798
284,1163264,5419356,0.145408,1,13,56192,True,True,True,0.2581379731067278,(0.001248193819057321+0.004339140607048203j),0.004515100111588618,1.2906994427415837,0.55376852676701,0.5933034271001816
285,1167360,5423452,0.14592,1,13,60288,True,True,True,0.2530657803756539,(0.0013788577757052885+0.00419175764528281j),0.00441271808780142,1.2530004458654427,0.5521800321637115,0.5899625867605209
286,1171456,5427547,0.146432,0,13,64384,True,True,True,0.25392783983290507,(0.001401972804627126+0.004166755137027025j),0.00439629117744209,1.246228731526822,0.5473219261437456,0.585045263171196
287,1175552,5431643,0.146944,0,13,68480,True,True,True,0.2652653510843641,(0.0014373715911341833+0.004373403795019587j),0.004603552741665001,1.253255857245764,0.5448719137584159,0.5861142575740814
288,1179648,5435739,0.147456,0,13,72576,True,True,True,0.26566180677487866,(0.00145395835175196+0.004343914276516279j),0.00458078444486872,1.2478058759437545,0.5376427555518017,0.5784688889980316
289,1183744,5439835,0.147968,0,13,76672,True,True,True,0.2634471009230045,(0.0014112452051848665+0.004300735879135284j),0.004526360804359151,1.2537266677052141,0.5335782988276216,0.5733728855848312
290,1187840,5443931,0.14848,0,13,80768,True,True,True,0.25121895961789686,(0.0013545192402851529+0.004096059693806466j),0.004314212255734364,1.2514281391921533,0.5380727033377047,0.5743184983730316
291,1191936,5448027,0.148992,0,13,84864,True,True,True,0.24618455862048508,(0.001239173099831446+0.004247836216677644j),0.004424891241043571,1.286954298856598,0.5431489357370782,0.5781912803649902
292,1196032,5452123,0.149504,0,13,88960,False,True,False,0.25460500594550434,(0.001456645781360352+0.004342461175011724j),0.004580260471724191,1.2471487770574143,0.5413396313714424,0.578863725066185
293,1200128,5464347,0.150016,8128,14,800,False,True,False,0.2664892367017101,(0.004595258533890168-0.00025639798128029975j),0.004602405992314784,-0.05573840974724589,0.5403135139541736,0.581617996096611
294,1204224,5464379,0.150528,4064,14,4896,False,True,False,0.2677067102634058,(-0.0039035142522089628-0.002474915637314424j),0.004621972623136355,-2.576531583209091,0.5393652625029224,0.5810040086507797
295,1208320,5464411,0.15104,0,14,8992,False,True,False,0.2676224417366838,(0.0017066501910134538+0.0042936749487946044j),0.004620421998085522,1.1924641946640253,0.5397369743995677,0.5813761651515961
296,1212416,5468507,0.151552,0,14,13088,False,True,False,0.2540449166869206,(0.0012582258203098654+0.004159380751831945j),0.004345524186286909,1.2770446405022853,0.5336992416461102,0.5705199241638184
297,1216512,5472603,0.152064,0,14,17184,False,True,False,0.24859482152857068,(0.0012690168352510153+0.004147650472783568j),0.004337442584349937,1.2738802772540043,0.553916127141515,0.5904026478528976
298,1220608,5476700,0.152576,1,14,21280,False,True,False,0.2558611321685786,(0.0011615097203271432+0.004337193105057625j),0.0044900277127178,1.309134118890352,0.5548674484680924,0.5937363505363464
299,1224704,5480796,0.153088,1,14,25376,True,True,True,0.24902334455788566,(0.0011255067621460822+0.004187091354160079j),0.004335723639684458,1.3081995949229324,0.5533850609771982,0.5899706929922104
300,1228800,5484891,0.1536,0,14,29472,True,True,True,0.2524803523265553,(0.0013228128281321033+0.004215829556643872j),0.004418489858418024,1.266752277708672,0.5565978879327824,0.5944947451353073
301,1232896,5488987,0.154112,0,14,33568,True,True,True,0.25659362997876295,(0.001523597078719511+0.004232821106107312j),0.004498680092492703,1.2252864490022244,0.559860953567165,0.5993203818798065
302,1236992,5493083,0.154624,0,14,37664,True,True,True,0.2701015466384452,(0.0015930439218050786+0.004434456215466593j),0.004711920082481281,1.2259117421093622,0.5500180173758105,0.5933022946119308
303,1241088,5497179,0.155136,0,14,41760,True,True,True,0.2654883946307786,(0.0015101082344784968+0.004325150491303857j),0.0045811956574966055,1.2348826680926182,0.5382364009561323,0.5790502279996872
304,1245184,5501275,0.155648,0,14,45856,True,True,True,0.2642378873941613,(0.0014789350860992378+0.004294330327625845j),0.004541863268710591,1.239125775840792,0.5361206526207132,0.5763632953166962
305,1249280,5505371,0.15616,0,14,49952,True,True,True,0.2704631814372041,(0.0014297452012599925+0.004460898789483908j),0.004684419852078267,1.2606343751470939,0.5420946543757261,0.5848787277936935
306,1253376,5509467,0.156672,0,14,54048,True,True,True,0.25862368887790793,(0.0014114606716766828+0.004290730646771298j),0.0045169227036592555,1.2529907254827484,0.5547799785112384,0.5945469737052917
307,1257472,5513563,0.157184,0,14,58144,True,True,True,0.2537946459711735,(0.0014512878585148262+0.004152496169937046j),0.004398802210785839,1.2345690612285416,0.5482861363456426,0.5860335677862167
308,1261568,5517659,0.157696,0,14,62240,True,True,True,0.25880367193626036,(0.0013953166604228435+0.004247498083004329j),0.004470810726029341,1.253399184203357,0.5424842444975086,0.5814279019832611
309,1265664,5521755,0.158208,0,14,66336,True,True,True,0.25852433212459397,(0.0012096553631778682+0.004317856823054481j),0.004484100092779276,1.297646864720312,0.5464240381960734,0.5855598300695419
310,1269760,5525851,0.15872,0,14,70432,True,True,True,0.26478919294097997,(0.0012756367113437668+0.004410535775679678j),0.004591304264354332,1.2892540359027742,0.5455173013175918,0.5866492241621017
311,1273856,5529947,0.159232,0,14,74528,True,True,True,0.26738258733865083,(0.0014459702809501217+0.004439384043162406j),0.004668935717706549,1.2559186226601515,0.551789156057867,0.5942759960889816
312,1277952,5534043,0.159744,0,14,78624,True,True,True,0.25761703065587765,(0.0013013793274676412+0.004291751269303245j),0.004484720405056056,1.276380664774593,0.5515944654460578,0.5908040851354599
313,1282048,5538139,0.160256,0,14,82720,True,True,True,0.2594854532357755,(0.001014695960330343+0.004360357591237143j),0.004476865668676032,1.3421562446445414,0.539021821863747,0.5779357999563217
314,1286144,5542236,0.160768,1,14,86816,False,True,False,0.25534036090986695,(0.0010348878449817414+0.004494382765061006j),0.004611991900531523,1.3444786345884008,0.5423552649187608,0.5801824033260345
315,1290240,5546331,0.16128,0,14,90912,False,True,False,0.24958348378421272,(0.0015809884356665748+0.004215168793332553j),0.004501907638989949,1.2119632322931633,0.5466115493167396,0.5829229354858398
316,1294336,5552459,0.161792,2032,15,2752,False,True,False,0.2653891462384448,(0.0037756615455502513-0.0024862762863175044j),0.004520751030354544,-0.5823280105725755,0.5254411813925184,0.5652527213096619
317,1298432,5552491,0.162304,-2032,15,6848,False,True,False,0.2657521082769784,(-0.004521714802829172-0.00017802384287181412j),0.0045252179225707245,-3.1022421077858477,0.5259034994737588,0.5658674240112305
318,1302528,5552523,0.162816,-6096,15,10944,False,True,False,0.2648650947094851,(0.0035480581267110073+0.00278413095489372j),0.004510000182319003,0.665336521026977,0.5263289531903287,0.5660385489463806
319,1306624,5562715,0.163328,0,15,15040,False,True,False,0.2620496140457573,(0.001531028169564713+0.004261039621478605j),0.004527748437337394,1.2258529584701106,0.5415241879914068,0.5814525336027145
320,1310720,5566812,0.16384,1,15,19136,False,True,False,0.26453769584680464,(0.0011282515653286331+0.00448029271963071j),0.0046201703916893,1.32410036700869,0.547386468762953,0.5885750651359558
321,1314816,5570908,0.164352,1,15,23232,False,True,False,0.2602922116740193,(0.0010637771205495672+0.004353568314823194j),0.004481649119915256,1.3311460884082906,0.5387595665150288,0.5779144465923309
322,1318912,5575003,0.164864,0,15,27328,True,True,True,0.2646714154148712,(0.001350060593372117+0.004299112239390732j),0.004506110257489876,1.2665159901569734,0.5260034771882566,0.5656261295080185
323,1323008,5579099,0.165376,0,15,31424,True,True,True,0.2675197135922362,(0.001229299289273+0.004407258670649587j),0.004575489671349184,1.2987837668896933,0.5257819233489514,0.5663109868764877
324,1327104,5583195,0.165888,0,15,35520,True,True,True,0.2527301679389408,(0.0011438527326352401+0.004195144440594359j),0.00434829115301711,1.3046058624948298,0.5373194205840789,0.5739810466766357
325,1331200,5587291,0.1664,0,15,39616,True,True,True,0.24252120082883175,(0.0013404286467247842+0.003997623218501677j),0.004216365775648994,1.2472710654732522,0.5534920044503024,0.588080883026123
326,1335296,5591387,0.166912,0,15,43712,True,True,True,0.2571775457631954,(0.0015098749844689487+0.004185489604321386j),0.0044494994883253446,1.2245854919847523,0.5440344222728948,0.5825654715299606
327,1339392,5595483,0.167424,0,15,47808,True,True,True,0.26432524091011667,(0.0014117994702806471+0.004327530007223564j),0.004551998869475376,1.2554462062864538,0.5386840960050098,0.5791479051113129
328,1343488,5599579,0.167936,0,15,51904,True,True,True,0.2621376516183847,(0.0013181958784353406+0.004343836003591089j),0.004539443974763663,1.2761650037093621,0.544478221527759,0.5846533477306366
329,1347584,5603675,0.168448,0,15,56000,True,True,True,0.2602155447030736,(0.0014567732237749647+0.004242818646846353j),0.004485944526577967,1.2400577194321012,0.5383806447420117,0.5774832665920258
330,1351680,5607772,0.16896,1,15,60096,True,True,True,0.26420496559852147,(0.0012353303830398529+0.004402993922998593j),0.00457300739571061,1.2972628513414242,0.5426832718703825,0.5834076106548309
331,1355776,5611867,0.169472,0,15,64192,True,True,True,0.2645956652886718,(0.0013486633031770535+0.004399815742174559j),0.004601876929082688,1.2733620636596512,0.5481978807485378,0.5894669741392136
332,1359872,5615963,0.169984,0,15,68288,True,True,True,0.27635966275564405,(0.001538395327785914+0.004518762326779053j),0.004773455053781399,1.2426579370597932,0.5369393073322216,0.5813388675451279
333,1363968,5620060,0.170496,1,15,72384,True,True,True,0.28065909499300684,(0.0013899322538439272+0.004688437803033093j),0.004890128904557162,1.2825907901516267,0.5446156770475633,0.5911828726530075
334,1368064,5624155,0.171008,0,15,76480,True,True,True,0.2787902846792729,(0.001505395943641435+0.004657137912448599j),0.0048943999103769785,1.2581526999750539,0.5536297896520709,0.6002864688634872
335,1372160,5628251,0.17152,0,15,80576,True,True,True,0.2782403905799784,(0.0013851585328944899+0.004671326949604034j),0.004872366943421579,1.2825319635019046,0.549059815247206,0.5951337069272995
336,1376256,5632347,0.172032,0,15,84672,True,True,True,0.25835564575952363,(0.0014878867435889247+0.004418020064904829j),0.004661835288343993,1.2459498434659404,0.5424659481705443,0.5812639445066452
337,1380352,5636443,0.172544,0,15,88768,False,True,False,0.2661307059301699,(0.001742326334063677+0.0044784482607504j),0.00480543441101739,1.1997678069313928,0.5420525528553599,0.5833700597286224
338,1384448,5650699,0.173056,10160,16,608,False,True,False,0.2807983627799369,(-0.0014132177560300736-0.004678753858631776j),0.0048875271964072394,-1.864132822427261,0.5440899108503512,0.5906622856855392
339,1388544,5650731,0.173568,6096,16,4704,False,True,False,0.28175733500795064,(-0.0016292651991435913+0.00462401096559049j),0.004902650558528672,1.909562177118072,0.5438451356478441,0.5907425284385681
340,1392640,5650763,0.17408,2032,16,8800,False,True,False,0.2810896310741443,(0.004032377747532641-0.0027645120137144447j),0.00488902822376471,-0.6009814789944031,0.5438568421206966,0.5905141830444336
341,1396736,5652827,0.174592,0,16,12896,False,True,False,0.27995892582994847,(0.0013644086381278274+0.004682448638769451j),0.00487718527293271,1.287259194961097,0.5457013503526119,0.5921090841293335
342,1400832,5656923,0.175104,0,16,16992,False,True,False,0.2694191676957321,(0.0012987608029786238+0.004501592194187054j),0.004685201373059593,1.289912543456448,0.5464975984850089,0.5892708152532578
343,1404928,5661020,0.175616,1,16,21088,False,True,False,0.2724290212387798,(0.0013557614569333096+0.004514417086428908j),0.004713602736585594,1.2790476630851628,0.5394092203654874,0.5826522558927536
344,1409024,5665116,0.176128,1,16,25184,True,True,True,0.2703439033029992,(0.0015023504482026882+0.004452830832832162j),0.004699442445124271,1.2453972397154547,0.5445303148943486,0.5874657332897186
345,1413120,5669212,0.17664,1,16,29280,True,True,True,0.26084853462192703,(0.0015064276691071788+0.0042858697602228745j),0.004542906990446158,1.2327973663021916,0.5488662670965079,0.5889388173818588
346,1417216,5673307,0.177152,0,16,33376,True,True,True,0.26680859121689254,(0.0017233605136990984+0.004346323777514884j),0.004675521557983502,1.1933022514222584,0.5563818107259524,0.5990244597196579
347,1421312,5677403,0.177664,0,16,37472,True,True,True,0.28118617001285623,(0.0017648563265804532+0.004599738199242859j),0.004926693551972255,1.2044321407102385,0.5511238823654319,0.5984399318695068
348,1425408,5681499,0.178176,0,16,41568,True,True,True,0.2765548104730267,(0.0017933494122994718+0.004409004550129239j),0.004759771343001174,1.1844871287004388,0.5314170018017368,0.5754271447658539
349,1429504,5685595,0.178688,0,16,45664,True,True,True,0.2665701091804682,(0.0016608712100729577+0.004276843269699999j),0.00458801498799071,1.200381524244915,0.5360344693741199,0.5770386159420013
350,1433600,5689691,0.1792,0,16,49760,True,True,True,0.27603880819109367,(0.001647519716432292+0.00448414294414518j),0.004777222954767775,1.218696301508401,0.5400274148415931,0.5845701545476913
351,1437696,5693787,0.179712,0,16,53856,True,True,True,0.27423717356605604,(0.0018811367461085812+0.004391660175502362j),0.004777588780405176,1.1660975677898966,0.5460581921807042,0.5904646962881088
352,1441792,5697883,0.180224,0,16,57952,True,True,True,0.26939315416499676,(0.001895787593627749+0.004261155598661815j),0.004663845798926014,1.1521917534315318,0.5405786387936542,0.5828797817230225
353,1445888,5701979,0.180736,0,16,62048,True,True,True,0.2704970887722574,(0.0018084369666119368+0.004265944201606953j),0.004633435463393503,1.1698372476397976,0.5303428144210389,0.5722107142210007
354,1449984,5706075,0.181248,0,16,66144,True,True,True,0.2631123469104774,(0.0014536311531551688+0.004261454370101405j),0.004502558925531079,1.2420618201093678,0.532675277665522,0.5722941160202026
355,1454080,5710171,0.18176,0,16,70240,True,True,True,0.266366325753132,(0.0013174392407077908+0.004407645976290434j),0.004600324902141802,1.2803502910288584,0.5411182266002784,0.5824431627988815
356,1458176,5714267,0.182272,0,16,74336,True,True,True,0.27057933254212896,(0.0013928641345691333+0.004495997771867698j),0.004706810646500274,1.2703723153640838,0.5461706870280945,0.5893164128065109
357,1462272,5718363,0.182784,0,16,78432,True,True,True,0.2670809726675467,(0.0012795950443333676+0.004403007790597894j),0.004585176232332653,1.2879685794606828,0.5334450177163121,0.5744196623563766
358,1466368,5722459,0.183296,0,16,82528,True,True,True,0.26574562793667467,(0.0016406126164279962+0.004275302399884901j),0.004579281643188625,1.2043836478611014,0.5377712923688862,0.5786349177360535
1 window_index tx_sample rx_sample time_seconds local_delay_samples packet_index position_inside_packet_samples inside_reliable_region correlation_above_threshold reliable_for_delay normalized_correlation gain gain_amplitude phase_rad residual_power rx_ac_power
2 0 0 4256092 0.0 1 1 0 False True False 0.2723983005613592 (0.0014400764308659896+0.004547916824745963j) 0.004770468275918322 1.264139438138503 0.5320521433901737 0.5746949911117554
3 1 4096 4258156 0.000512 -2031 1 4096 False True False 0.2729793659247979 (-0.004663053599288344+0.00040199323732778125j) 0.004680349071671177 3.0555971153877457 0.5307691750552395 0.5735055059194565
4 2 8192 4258188 0.001024 -6095 1 8192 False True False 0.2744171645442273 (0.004046229816782595+0.0023981760914401954j) 0.004703533171539868 0.5350301142527935 0.5298967126207345 0.5730501264333725
5 3 12288 4258220 0.001536 -10159 1 12288 False True False 0.2745940021638059 (-0.001877375284743114-0.004308549206226646j) 0.004699801508812957 -1.9817223367149237 0.5290641319544691 0.572209820151329
6 4 16384 4272476 0.002048 1 1 16384 False True False 0.26655475961180447 (0.0015909658512084958+0.0043219233704984905j) 0.004605452633582567 1.2180752315139343 0.5385030300563245 0.5796909034252167
7 5 20480 4276572 0.00256 1 1 20480 False True False 0.2704674132861876 (0.0015020188131524086+0.004503663352078344j) 0.004747530316271536 1.2488863714827263 0.5517759339741067 0.5953255593776703
8 6 24576 4280667 0.003072 0 1 24576 True True True 0.2779743002913568 (0.001574055297828197+0.004628794269849324j) 0.004889108965160313 1.2430064552849862 0.5566272125305693 0.6032393425703049
9 7 28672 4284763 0.003584 0 1 28672 True True True 0.2720544529364392 (0.0016932309240155242+0.004457847887134059j) 0.004768588758413548 1.2077965884614033 0.5530613403203055 0.5972672551870346
10 8 32768 4288859 0.004096 0 1 32768 True True True 0.2649913203278537 (0.0018990710284393965+0.004188594569993716j) 0.004598999374085488 1.1451260339739677 0.5459171758273589 0.5871468633413315
11 9 36864 4292955 0.004608 0 1 36864 True True True 0.2721722386513534 (0.0018268451981139167+0.004317763275913575j) 0.004688330522126165 1.1705361837258939 0.5365336736680916 0.5794586539268494
12 10 40960 4297051 0.00512 0 1 40960 True True True 0.2721968822811185 (0.001724738414167657+0.004364487642303184j) 0.004692917533594935 1.1944559420309822 0.5372551467224218 0.5802462548017502
13 11 45056 4301147 0.005632 0 1 45056 True True True 0.27115565572908557 (0.0018536312646620433+0.0043132285698386785j) 0.004694666075559072 1.1649051100363104 0.5411645818582298 0.5841116160154343
14 12 49152 4305244 0.006144 1 1 49152 True True True 0.26695565820866574 (0.0015749959490531304+0.004372541401953098j) 0.004647551027296822 1.2250623805453835 0.5459189026441111 0.5878093242645264
15 13 53248 4309339 0.006656 0 1 53248 True True True 0.2556440262627536 (0.0016446481954502357+0.004141139532609057j) 0.0044557720223700045 1.1927503782494664 0.5527965436310334 0.5914500951766968
16 14 57344 4313435 0.007168 0 1 57344 True True True 0.2654944778350678 (0.001579553863468991+0.004353550882949614j) 0.004631241269684746 1.2227468320256794 0.551303941123149 0.5931107252836227
17 15 61440 4317531 0.00768 0 1 61440 True True True 0.2819287365366617 (0.0016676229288336369+0.0046224170689160154j) 0.004914031521243816 1.2245604961967766 0.5432338343896431 0.5901404470205307
18 16 65536 4321628 0.008192 1 1 65536 True True True 0.2849343081441107 (0.0015551300976373065+0.004760709738123959j) 0.005008271840789566 1.255064382840333 0.5515766203313819 0.6003147065639496
19 17 69632 4325724 0.008704 1 1 69632 True True True 0.2668779433455796 (0.0015400349773235437+0.0044066605083271275j) 0.004668015056427071 1.234585792156039 0.5544426689160701 0.5969604849815369
20 18 73728 4329819 0.009216 0 1 73728 True True True 0.26731850919222144 (0.0015998970853807015+0.004351612962721423j) 0.004636400118748897 1.2184796304589962 0.544979127072188 0.5869199484586716
21 19 77824 4333915 0.009728 0 1 77824 True True True 0.2757493751671597 (0.0015028961676935508+0.0045326408799782995j) 0.004775304203683616 1.2506319351828965 0.5405722579331813 0.58505879342556
22 20 81920 4338011 0.01024 0 1 81920 True True True 0.2747031051630683 (0.001434360817300166+0.004554302124498627j) 0.004774835996703836 1.2656843127617807 0.5449793922392892 0.5894611924886703
23 21 86016 4342106 0.010752 -1 1 86016 False True False 0.262832641274786 (0.0017063341695680602+0.004412668558523586j) 0.004731090794480502 1.201816607513573 0.5405771973365503 0.5806919783353806
24 22 90112 4346203 0.011264 0 1 90112 False True False 0.24463720210977444 (0.001540875532155414+0.004130615883847389j) 0.004408660225679404 1.2137471203289174 0.5462349738883019 0.5810066908597946
25 23 94208 4360459 0.011776 10160 2 1952 False True False 0.2716641040460329 (-0.0013022645358288175-0.004525075678879153j) 0.00470873686043944 -1.8510125610584165 0.5428179407596163 0.5860707759857178
26 24 98304 4360491 0.012288 6096 2 6048 False True False 0.2718898121257277 (-0.0016149804689081098+0.004431209064076905j) 0.0047163307437574796 1.920291000004672 0.5434848560970025 0.5868685692548752
27 25 102400 4360523 0.0128 2032 2 10144 False True False 0.2725240587031942 (0.00391949046182433-0.0026463739117019856j) 0.004729238877543486 -0.5938754774412633 0.5434089720090052 0.5870054960250854
28 26 106496 4362587 0.013312 0 2 14240 False True False 0.2760592697755412 (0.0013920156722528913+0.004580095816437278j) 0.0047869599245809365 1.2757405072063803 0.5415059501043626 0.5861778110265732
29 27 110592 4366683 0.013824 0 2 18336 False True False 0.2724376874597982 (0.0014133537140496781+0.0045130584690135705j) 0.004729192897921709 1.2673013462261535 0.5413853024567086 0.5847897380590439
30 28 114688 4370780 0.014336 1 2 22432 False True False 0.2719029335917029 (0.0011697644964912767+0.004560116010595991j) 0.0047077602962922165 1.3196899415543735 0.5406078471906972 0.5837664008140564
31 29 118784 4374876 0.014848 1 2 26528 True True True 0.2700707220369181 (0.0013350388080086953+0.004474286128071312j) 0.004669214599345446 1.2808261632328335 0.5394193308566163 0.5818590819835663
32 30 122880 4378971 0.01536 0 2 30624 True True True 0.2686195464655446 (0.0012246606908276484+0.0044642820496554455j) 0.004629212462885483 1.3030584917227905 0.5373847039400281 0.5791759938001633
33 31 126976 4383067 0.015872 0 2 34720 True True True 0.2633530926845802 (0.0011406041785767163+0.004404294536372791j) 0.004549592097684131 1.3173881793080358 0.5396795929719889 0.5798983573913574
34 32 131072 4387163 0.016384 0 2 38816 True True True 0.25637788480815954 (0.0012829050950408745+0.004270558977812529j) 0.004459094018503873 1.278966333401463 0.5485951175865063 0.5871909558773041
35 33 135168 4391260 0.016896 1 2 42912 True True True 0.26000719134870665 (0.001208701026115259+0.00434386307850457j) 0.004508891728055496 1.2994066208398154 0.5469509736502136 0.5866078585386276
36 34 139264 4395355 0.017408 0 2 47008 True True True 0.2539878786554866 (0.001204104650759226+0.0042140376803331j) 0.004382691134593809 1.2924760702562699 0.5432254548985715 0.5806853771209717
37 35 143360 4399451 0.01792 0 2 51104 True True True 0.26248777906333653 (0.001090192569531215+0.004413735444813682j) 0.004546381024008624 1.3286431982708542 0.544464620474242 0.584754079580307
38 36 147456 4403547 0.018432 0 2 55200 True True True 0.268908662501336 (0.0011983970061596977+0.004461156216980074j) 0.0046193149033890825 1.3083625534812198 0.5334410404305294 0.5750219523906708
39 37 151552 4407644 0.018944 1 2 59296 True True True 0.2584294308489172 (0.0009705941914629901+0.004321800607292927j) 0.004429448450281277 1.3498807548369551 0.5329131149684843 0.5710512101650238
40 38 155648 4411739 0.019456 0 2 63392 True True True 0.2589804129517903 (0.0011773086855389008+0.004351617974012928j) 0.004508063301773581 1.306576549991733 0.5504235283232656 0.5899949967861176
41 39 159744 4415835 0.019968 0 2 67488 True True True 0.26707042084269383 (0.0012836628929886265+0.004466770988566209j) 0.004647562101482096 1.2909568817815837 0.5478066109478578 0.5898808091878891
42 40 163840 4419932 0.02048 1 2 71584 True True True 0.26685819356609625 (0.0011948923329598014+0.004432616311602053j) 0.004590844699316968 1.3074870108552974 0.5338153340239872 0.5747448056936264
43 41 167936 4424027 0.020992 0 2 75680 True True True 0.2602019922356652 (0.0012135424294046583+0.004275450290739874j) 0.004444340267863503 1.294230653530701 0.5290908955689677 0.5675145089626312
44 42 172032 4428123 0.021504 0 2 79776 True True True 0.2648953034335269 (0.0010080749497805373+0.004436298157786467j) 0.0045493907778025216 1.3473571568083174 0.5346305944052281 0.5749764144420624
45 43 176128 4432219 0.022016 0 2 83872 True True True 0.27271964951391364 (0.0010679789510904913+0.004638600937917362j) 0.004759957741537227 1.3445025739068763 0.5379263101079028 0.5811499208211899
46 44 180224 4436316 0.022528 1 2 87968 False True False 0.26621296963966334 (0.0014238192462404508+0.004578690891323345j) 0.004794963141073359 1.2693091820913467 0.5398449030192329 0.5810215175151825
47 45 184320 4440411 0.02304 0 2 92064 False True False 0.2580468087430128 (0.0016982791241270806+0.004292585999959374j) 0.004616323921746941 1.1940621888188008 0.5458059940350145 0.5847429484128952
48 46 188416 4452635 0.023552 8128 3 3904 False True False 0.2649939974461844 (0.004547469531258444+0.0002454033015846323j) 0.004554086287956402 0.053912509828619726 0.5349567727385085 0.5753595679998398
49 47 192512 4452667 0.024064 4064 3 8000 False True False 0.2652695563170298 (-0.00352196396834277-0.00288831530557835j) 0.004554843081681619 -2.4547232497156846 0.5348699867647786 0.5753566473722458
50 48 196608 4450668 0.024576 -2031 3 12096 False True False 0.2655804119817936 (-0.00455017405199118-0.0005553942299958869j) 0.00458394444273996 -3.0201334712223153 0.5399761574427078 0.580952450633049
51 49 200704 4456795 0.025088 0 3 16192 False True False 0.27329487809545694 (0.0010001317651298055+0.004609230865953922j) 0.004716489449080111 1.3571240999141405 0.5367884244476238 0.5801174491643906
52 50 204800 4460891 0.0256 0 3 20288 False True False 0.2748035784048019 (0.0009020685528086647+0.004696528423964232j) 0.0047823746100729364 1.3810359628033242 0.5447007004166863 0.5891949385404587
53 51 208896 4464987 0.026112 0 3 24384 True True True 0.2733714317503713 (0.001196082844537941+0.0046138615886948545j) 0.0047663752402251945 1.3171432489691388 0.5430379318122193 0.5868979543447495
54 52 212992 4469084 0.026624 1 3 28480 True True True 0.26980098289370985 (0.000891303823734098+0.00462177943251277j) 0.0047069382435932896 1.3802864468658624 0.5452336561152853 0.5880384892225266
55 53 217088 4473180 0.027136 1 3 32576 True True True 0.2593488284007324 (0.000701164278632974+0.004429229337331668j) 0.004484384446979364 1.4137952643367864 0.5418432466726182 0.5809167623519897
56 54 221184 4477275 0.027648 0 3 36672 True True True 0.24083000237735547 (0.0010787855072950715+0.003956623747567151j) 0.004101054699776901 1.3046133691002941 0.5316101788297216 0.5643414705991745
57 55 225280 4481371 0.02816 0 3 40768 True True True 0.24884057677466154 (0.0012529409123619626+0.004099663105570891j) 0.004286851817948644 1.274191159290718 0.5432383289368947 0.5790969580411911
58 56 229376 4485467 0.028672 0 3 44864 True True True 0.26424577088305007 (0.001419557704160117+0.004367512865639938j) 0.004592419047405269 1.2565404007957168 0.5470104412221599 0.5880731344223022
59 57 233472 4489563 0.029184 0 3 48960 True True True 0.25762850178040403 (0.0013096625676030976+0.004235848862247899j) 0.004433692775191755 1.2709340205678785 0.5390744902777722 0.5773977935314178
60 58 237568 4493659 0.029696 0 3 53056 True True True 0.2679321562033791 (0.0013369756290009971+0.0043821287442785415j) 0.004581545172098038 1.2746696997240843 0.5273775856410188 0.5681647956371307
61 59 241664 4497755 0.030208 0 3 57152 True True True 0.2711470944273147 (0.001351328684164128+0.004419603802068811j) 0.004621578407850054 1.2740654815604695 0.5230486505702867 0.5645551681518555
62 60 245760 4501852 0.03072 1 3 61248 True True True 0.2672883844824355 (0.0010068247184626777+0.004467841124027755j) 0.004579879946380805 1.3491494727972868 0.5312288236824456 0.5721015185117722
63 61 249856 4505947 0.031232 0 3 65344 True True True 0.27107441392986664 (0.0013357978398945835+0.0044942838974314555j) 0.004688597191034725 1.2818905523246318 0.5404706646150161 0.583334892988205
64 62 253952 4510043 0.031744 0 3 69440 True False False 0.13153433429624267 (0.001554183671647779+0.004426566695093525j) 0.004691479467217968 1.2331386492766252 2.4339817589794546 2.476834163069725
65 63 258048 4514139 0.032256 0 3 73536 True False False 0.08888879507126439 (0.00169980331450993+0.004389042425002968j) 0.004706699981568283 1.2013003657755736 5.416685224653776 5.459824487566948
66 64 262144 4518235 0.032768 0 3 77632 True False False 0.07990273751817419 (0.001699250897969519+0.004324783344646435j) 0.004646633683902942 1.1964168666678643 6.53860352546403 6.580617129802704
67 65 266240 4522332 0.03328 1 3 81728 True False False 0.07824125225628915 (0.0013933691504081321+0.004356594463416111j) 0.004573990916910198 1.2612476939877006 6.624367159902822 6.665169283747673
68 66 270336 4526428 0.033792 1 3 85824 True False False 0.07587440188611191 (0.0013041751210003604+0.004457185452549003j) 0.004644068787674313 1.286141724316014 6.655995644921719 6.694535583257675
69 67 274432 4530523 0.034304 0 3 89920 False False False 0.0769175854864118 (0.0015678214075495489+0.004396212075719992j) 0.004667413050146401 1.2282272423410476 6.554379697834005 6.593388259410858
70 68 278528 4542747 0.034816 8128 4 1760 False False False 0.08597985441315165 (0.005066283573465239+0.00034999030444959325j) 0.005078358244548373 0.0689726756303229 6.758426343340691 6.808760344982147
71 69 282624 4542779 0.035328 4064 4 5856 False False False 0.0857009006288708 (-0.0038966589911976885-0.003238719072000978j) 0.005066877985606587 -2.4481426241304436 6.759721722902659 6.80973681807518
72 70 286720 4544843 0.03584 2032 4 9952 False False False 0.08525779282376747 (0.004325880698897092-0.0025736448588474193j) 0.005033576430388451 -0.536691526326966 6.741963816067408 6.791329249739647
73 71 290816 4546907 0.036352 0 4 14048 False False False 0.0818033690015016 (0.0011822849366477169+0.004670129356209848j) 0.004817458445607716 1.3228467728695121 6.720242903354096 6.765516325831413
74 72 294912 4551003 0.036864 0 4 18144 False False False 0.07658097028160148 (0.0008517722304822827+0.004438565003908057j) 0.0045195547597676146 1.3811986992356107 6.7219641213364305 6.761618614196777
75 73 299008 4555099 0.037376 0 4 22240 False False False 0.08613404389567611 (0.0011849698335850026+0.0049152028039830455j) 0.005056023349509896 1.334227966715792 6.6581370011692105 6.707903429865837
76 74 303104 4559195 0.037888 0 4 26336 True False False 0.08726659571551212 (0.0016595927555988928+0.004842576482874993j) 0.005119061936227209 1.2406318687205053 6.6524727994418935 6.703523203730583
77 75 307200 4563291 0.0384 0 4 30432 True False False 0.07303287114951702 (0.001432858640864123+0.004032332716192873j) 0.0042793446950179625 1.229370113401519 6.647078068400921 6.682722374796867
78 76 311296 4567387 0.038912 0 4 34528 True False False 0.07923837125521409 (0.001686126196189353+0.004315979331039012j) 0.004633648577032135 1.198358325356545 6.621968636371651 6.663808822631836
79 77 315392 4571483 0.039424 0 4 38624 True False False 0.08766369642748506 (0.0017031705964680188+0.004852024258675652j) 0.0051422689046227675 1.2332107176608704 6.6245479222476575 6.675851330161095
80 78 319488 4575579 0.039936 0 4 42720 True False False 0.08111151553103035 (0.0017214618264675924+0.004433371066833172j) 0.004755860577878481 1.2004198351270303 6.642704557350704 6.686696857213974
81 79 323584 4579675 0.040448 0 4 46816 True False False 0.10671176630261674 (0.0013274729713343197+0.004468864548466894j) 0.0046618595905676295 1.2820488137155435 3.674980498404129 3.7173110097646713
82 80 327680 4583771 0.04096 0 4 50912 True True True 0.17364185979381344 (0.0011104452242883332+0.0048122481560667054j) 0.0049387064006389545 1.3440119960319097 1.5273621675226863 1.5748461335897446
83 81 331776 4587867 0.041472 0 4 55008 True False False 0.13566484987135102 (0.0011900787687552166+0.004564289775742337j) 0.004716887600185949 1.3157381520156248 2.309129150389409 2.3524254262447357
84 82 335872 4591963 0.041984 0 4 59104 True True True 0.1663171407536924 (0.0012317423905629345+0.004361708579217488j) 0.004532294236557146 1.2955643672094288 1.3985216467121702 1.4383072257041931
85 83 339968 4596059 0.042496 0 4 63200 True True True 0.26471751311013225 (0.001558865952620833+0.00430077474184848j) 0.004574573907847846 1.2230632263032186 0.5405374832466419 0.5812702029943466
86 84 344064 4600155 0.043008 0 4 67296 True True True 0.2792268825008271 (0.0016212932750898708+0.004545583027784552j) 0.004826066405089617 1.2281878779094144 0.5361519398429078 0.5814892947673798
87 85 348160 4604251 0.04352 0 4 71392 True True True 0.2832122191263414 (0.001568572376109022+0.004689580014148107j) 0.004944955005678986 1.2480138106379053 0.546382714975119 0.5940293073654175
88 86 352256 4608347 0.044032 0 4 75488 True True True 0.2751351562277797 (0.0014124280165170157+0.004572151352605746j) 0.004785344386037095 1.2711764645789363 0.5418399951586526 0.5862161815166473
89 87 356352 4612443 0.044544 0 4 79584 True True True 0.2711253433830607 (0.0012792764994174382+0.004507944933506286j) 0.0046859487711120714 1.2942834417500173 0.539963691491252 0.5828050822019577
90 88 360448 4616539 0.045056 0 4 83680 True True True 0.2780326176311392 (0.0014125086541028251+0.004613805346804851j) 0.004825181911194686 1.2737084804157615 0.5414278402357562 0.5867877900600433
91 89 364544 4620635 0.045568 0 4 87776 False True False 0.2717667108050532 (0.0013978470154112287+0.004703990842016978j) 0.004907291118353758 1.281945292248661 0.5413104739012351 0.5844783782958984
92 90 368640 4626764 0.04608 2033 4 91872 False True False 0.2662074290976547 (0.004115316763378964-0.002495104285846531j) 0.004812626877309069 -0.5450368010824937 0.5440730211399605 0.5855702757835388
93 91 372736 4626795 0.046592 -2032 5 3712 False True False 0.282542960509231 (-0.004899029038211988-8.122809335022387e-05j) 0.004899702391002294 -3.125013725308483 0.5400234934244572 0.5868739485740662
94 92 376832 4626827 0.047104 -6096 5 7808 False True False 0.2825020973176275 (0.003908930591380348+0.002952507348220343j) 0.004898677169351359 0.646899486603501 0.5395280432357176 0.5863208025693893
95 93 380928 4626859 0.047616 -10160 5 11904 False True False 0.2807600356970303 (-0.001420950169111977-0.004657543716583497j) 0.004869477677840383 -1.8669123818056594 0.5399243687694288 0.5861264914274216
96 94 385024 4641116 0.048128 1 5 16000 False True False 0.2650614809565532 (0.0010542710537117725+0.004575124896595126j) 0.004695024523273451 1.344314387574751 0.5685874798206638 0.6115537732839584
97 95 389120 4645211 0.04864 0 5 20096 False True False 0.2667422739644077 (0.0010977299055325784+0.004457196663720133j) 0.004590382668643046 1.3293194581197063 0.534952635962959 0.5759309530258179
98 96 393216 4649307 0.049152 0 5 24192 True True True 0.26466251848509825 (0.0010486869362193254+0.004394194972639804j) 0.0045175982277942785 1.336525561985254 0.5277840580651971 0.5675379633903503
99 97 397312 4653403 0.049664 0 5 28288 True True True 0.25854313841229054 (0.001198925223421213+0.004261898495125296j) 0.004427324301890123 1.2965709791550253 0.5339610295058146 0.5722101628780365
100 98 401408 4657499 0.050176 0 5 32384 True True True 0.2537591241878097 (0.001220992856318022+0.004200952361654078j) 0.004374794200881525 1.287942494915078 0.5425047534699575 0.5798429846763611
101 99 405504 4661596 0.050688 1 5 36480 True True True 0.2590655534926447 (0.0011303389414594528+0.004347174614996451j) 0.004491724975535481 1.3164124223967255 0.5442177708614893 0.5833706706762314
102 100 409600 4665692 0.0512 1 5 40576 True True True 0.27545885714841517 (0.001241740275123457+0.004628777994975647j) 0.004792442450111889 1.3087020787717447 0.5450552239659276 0.589808464050293
103 101 413696 4669788 0.051712 1 5 44672 True True True 0.2779047219199058 (0.0013383854927980384+0.004623275702312929j) 0.004813102320430073 1.289010720505806 0.5374273640261628 0.5824072808027267
104 102 417792 4673883 0.052224 0 5 48768 True True True 0.28072829168306407 (0.0014892805370576398+0.004618240714550299j) 0.004852432772907704 1.258847275319138 0.5363134186037127 0.5821952819824219
105 103 421888 4677979 0.052736 0 5 52864 True True True 0.27647214381674806 (0.0013533142580344057+0.004639687152038339j) 0.004833027658703067 1.2869878818229048 0.5499437435476484 0.5954587310552597
106 104 425984 4682075 0.053248 0 5 56960 True True True 0.2715921696331709 (0.001087912656261071+0.004603111202176992j) 0.004729924596360954 1.338712126802001 0.5463894941519993 0.5899020284414291
107 105 430080 4686171 0.05376 0 5 61056 True True True 0.2669719744416374 (0.001055495801123365+0.004535850831207893j) 0.004657039204168071 1.342164417057586 0.5496048207813974 0.5917836278676987
108 106 434176 4690267 0.054272 0 5 65152 True True True 0.25933246973065593 (0.0011738677237808808+0.004384331485952915j) 0.00453875842182117 1.3091906786672414 0.5567507899047981 0.5968938916921616
109 107 438272 4694363 0.054784 0 5 69248 True True True 0.26592635147561616 (0.0014396359888415133+0.004449124742918487j) 0.004676244514395839 1.257851704672455 0.5601043060592626 0.6027272641658783
110 108 442368 4698459 0.055296 0 5 73344 True True True 0.27365159790299287 (0.0015497665053611947+0.004564716338565147j) 0.004820623556419133 1.243497177656846 0.5584733039849059 0.6036799997091293
111 109 446464 4702555 0.055808 0 5 77440 True True True 0.2633210162250354 (0.0013221811004029498+0.004381795354342359j) 0.004576930564209931 1.2777401668138901 0.5471677345553811 0.5879338681697845
112 110 450560 4706651 0.05632 0 5 81536 True True True 0.26824181335626013 (0.0012740111219966598+0.004465711961654281j) 0.0046438871286276235 1.29289142838727 0.5420455105218226 0.5840716063976288
113 111 454656 4710747 0.056832 0 5 85632 True True True 0.26388173742294235 (0.0014123473641952727+0.004534563825781714j) 0.004749420403295272 1.2688567766150023 0.5375280882444592 0.5777595490217209
114 112 458752 4714843 0.057344 0 5 89728 False True False 0.2522196006429852 (0.0013772325045995537+0.004293720322152726j) 0.004509191011322637 1.2604086118008029 0.5350556534434683 0.5714054554700851
115 113 462848 4725035 0.057856 6096 6 1568 False True False 0.2771232078693172 (-0.0020002876001643417+0.004297049846018963j) 0.004739808842405231 2.0064671134474126 0.5274695198960893 0.5713474452495575
116 114 466944 4725067 0.058368 2032 6 5664 False True False 0.27702128795645814 (0.00413210728460306-0.002319090529045502j) 0.004738406007654707 -0.5114293343015762 0.5277817565190994 0.5716506838798523
117 115 471040 4725099 0.05888 -2032 6 9760 False True False 0.276592565978206 (-0.004702814275236275-0.000545451646585368j) 0.004734340461577387 -3.0261244877072064 0.5278071537418947 0.5715312659740448
118 116 475136 4731227 0.059392 0 6 13856 False True False 0.261387587164352 (0.0011452191894361628+0.004324249063830631j) 0.0044733272804359965 1.3119033303989793 0.5314278199197381 0.5703994929790497
119 117 479232 4735323 0.059904 0 6 17952 False True False 0.26600518395588735 (0.0011882035152338427+0.00440899760787155j) 0.004566299103194086 1.307555089993816 0.5333333931089501 0.5739450305700302
120 118 483328 4739419 0.060416 0 6 22048 False True False 0.26354711468027764 (0.0012722185803642125+0.004339840170588295j) 0.00452247198139201 1.285636904251594 0.5330185708165498 0.5728038549423218
121 119 487424 4743516 0.060928 1 6 26144 True True True 0.2655258469985231 (0.0010413614298705306+0.004482633907505584j) 0.004602003952230026 1.3425349502168569 0.5439972900983086 0.5852604806423187
122 120 491520 4747612 0.06144 1 6 30240 True True True 0.27026658341105503 (0.0006871157719793929+0.004660496024741168j) 0.0047108758507024015 1.424416812159449 0.5483031597970439 0.5915093868970871
123 121 495616 4751707 0.061952 0 6 34336 True True True 0.27212727343914983 (0.00103874048233643+0.004593169010476414j) 0.004709159516139308 1.3483885391116444 0.5392289521801527 0.5823541730642319
124 122 499712 4755803 0.062464 0 6 38432 True True True 0.28136708133251975 (0.0015478134989297052+0.004631816125900667j) 0.00488358958673049 1.248293057797807 0.5387114553079869 0.5850265026092529
125 123 503808 4759899 0.062976 0 6 42528 True True True 0.27890087509243017 (0.0013600301944214322+0.00462867624870359j) 0.004824347204031933 1.2850123849861281 0.5356196312800044 0.5807973593473434
126 124 507904 4763995 0.063488 0 6 46624 True True True 0.26336035378327605 (0.001049261617941425+0.0043808875864818145j) 0.004504789227952348 1.3357157400217448 0.5320584679757843 0.5717116296291351
127 125 512000 4768091 0.064 0 6 50720 True True True 0.26497822213724925 (0.001099080196697002+0.00443634202713449j) 0.004570460355422775 1.3279414286903835 0.5397274050774757 0.5804852843284607
128 126 516096 4772188 0.064512 1 6 54816 True True True 0.2588557900323732 (0.0013698338171910028+0.004291962654778482j) 0.004505262269472581 1.2618532123786583 0.5491224961879504 0.5885597169399261
129 127 520192 4776284 0.065024 1 6 58912 True True True 0.26525822500006635 (0.0014099236859939925+0.004358861980797595j) 0.004581218458878557 1.2579566494377912 0.5409942829315486 0.5819407552480698
130 128 524288 4780379 0.065536 0 6 63008 True True True 0.2663899652999382 (0.0013118458205982157+0.004388013938848249j) 0.004579913294435554 1.2802928513905263 0.5342598690886164 0.5750688314437866
131 129 528384 4784475 0.066048 0 6 67104 True True True 0.25666966629660665 (0.0012463167346545275+0.004264542171658961j) 0.004442929814541037 1.286463776193324 0.5445433095922607 0.5829474925994873
132 130 532480 4788571 0.06656 0 6 71200 True True True 0.2606059923710226 (0.001271455909544945+0.004320777588694721j) 0.00450396704038599 1.2846087811950069 0.54270473673413 0.5822484195232391
133 131 536576 4792667 0.067072 0 6 75296 True True True 0.2670879834822261 (0.001595899119666262+0.004329908780645395j) 0.00461465102135163 1.2176697888301709 0.5365249042267309 0.5777384489774704
134 132 540672 4796763 0.067584 0 6 79392 True True True 0.26593394499633477 (0.001477311710559645+0.004342725822956805j) 0.004587125185073165 1.2428958119988545 0.5347466339577565 0.5754424184560776
135 133 544768 4800859 0.068096 0 6 83488 True True True 0.2652553665245194 (0.0013141328612987792+0.004389330045641679j) 0.004581829702937256 1.2798968884696806 0.5400880761578909 0.5809650123119354
136 134 548864 4804955 0.068608 0 6 87584 False True False 0.25548083595374993 (0.0015057567714245848+0.004342790980108081j) 0.004596426541521042 1.2370415480903751 0.542590490303864 0.5804785937070847
137 135 552960 4817180 0.06912 8129 6 91680 False True False 0.26036916131092225 (0.004673620949138175+0.00024960406064367444j) 0.0046802815047081335 0.05335630613581867 0.5395512157685356 0.5787885040044785
138 136 557056 4817212 0.069632 4065 7 3520 False True False 0.27341327144153854 (-0.0035304699699410433-0.003130835945304359j) 0.004718723548277156 -2.416116014289601 0.5372784161036481 0.5806876122951508
139 137 561152 4817244 0.070144 1 7 7616 False True False 0.27403920750408217 (0.001010539602555097+0.004616804647374057j) 0.0047261057373218915 1.355311797069995 0.5376433134511249 0.5812972784042358
140 138 565248 4817276 0.070656 -4063 7 11712 False True False 0.2746479667516686 (0.0018912570769004213-0.004346463071505326j) 0.004740104910535782 -1.1603806139411221 0.5378884612654133 0.5817724317312241
141 139 569344 4825435 0.071168 0 7 15808 False True False 0.25937216918957146 (0.0011938454665440122+0.004362559508218352j) 0.004522962796744413 1.3036790097834017 0.5521339003347727 0.5919571816921234
142 140 573440 4829531 0.07168 0 7 19904 False True False 0.26774346245706554 (0.0009418111768576637+0.004568398639175929j) 0.004664469360953987 1.3674868432051928 0.5443368442013263 0.5863718241453171
143 141 577536 4833627 0.072192 0 7 24000 True True True 0.26587676777880576 (0.001102610189571028+0.004463079859444132j) 0.0045972634318604925 1.3285947230861475 0.5408037074042943 0.5819414108991623
144 142 581632 4837724 0.072704 1 7 28096 True True True 0.2619208785763954 (0.0012054341276794263+0.004364128878079499j) 0.004527548155532052 1.3013016855057298 0.5421426589707972 0.582074448466301
145 143 585728 4841820 0.073216 1 7 32192 True True True 0.26004799444738186 (0.0012996243478831987+0.004280701998500875j) 0.004473637563055396 1.2760393722352807 0.5373060159033105 0.5762767046689987
146 144 589824 4845916 0.073728 1 7 36288 True True True 0.26352682248810066 (0.0013929034499800838+0.004376577528341034j) 0.004592886987782971 1.2626696720599786 0.5511815324075017 0.5923157185316086
147 145 593920 4850011 0.07424 0 7 40384 True True True 0.27321560983225973 (0.0014136076722512999+0.004603422423890218j) 0.004815577292892621 1.2728590831142508 0.560267982433693 0.605463907122612
148 146 598016 4854107 0.074752 0 7 44480 True True True 0.2697569569525196 (0.0012948903346004814+0.004510190476376705j) 0.00469239375072477 1.2912130045767223 0.5456335561563538 0.5884547084569931
149 147 602112 4858203 0.075264 0 7 48576 True True True 0.26704062643742627 (0.0014034649430516995+0.004351442985962747j) 0.004572173433549901 1.258801319004848 0.5305424443764983 0.5712808817625046
150 148 606208 4862299 0.075776 0 7 52672 True True True 0.26110270903330773 (0.001204834540491995+0.004328357525056808j) 0.004492917218765382 1.299310555739649 0.5375498470396575 0.5768783092498779
151 149 610304 4866396 0.076288 1 7 56768 True True True 0.24788848233138613 (0.000885925455637422+0.004191896025296573j) 0.004284490191358078 1.3625187593746237 0.5466587176655056 0.5824494808912277
152 150 614400 4870491 0.0768 0 7 60864 True True True 0.2601141176285434 (0.0013182434384379415+0.004314238663366558j) 0.004511144090745888 1.2742497022015684 0.5462691178352976 0.5859115123748779
153 151 618496 4874587 0.077312 0 7 64960 True True True 0.27010121357136685 (0.0014941599628287964+0.004411796556139344j) 0.004657946204850752 1.2442470656108626 0.5370899949431283 0.579356774687767
154 152 622592 4878683 0.077824 0 7 69056 True True True 0.2758319253957052 (0.0012682927921888675+0.004576544230142604j) 0.004749033975154294 1.3004519486229928 0.5343123720322084 0.5783122479915619
155 153 626688 4882779 0.078336 0 7 73152 True True True 0.27404653150617597 (0.0011890329932240313+0.004588957075942728j) 0.004740498550133744 1.3172644783717473 0.5393673486206108 0.5831638276576996
156 154 630784 4886875 0.078848 0 7 77248 True True True 0.27119602861279707 (0.001236306317670613+0.004529799008937786j) 0.004695479993833008 1.3043580041913996 0.5387397575259696 0.5815081000328064
157 155 634880 4890971 0.07936 0 7 81344 True True True 0.27342762369718 (0.0012399300344019713+0.004586782940726171j) 0.004751421285841605 1.3067799874345216 0.5439590769382545 0.5879130214452744
158 156 638976 4895067 0.079872 0 7 85440 True True True 0.25670283077288303 (0.0014843755553559303+0.004419445796424099j) 0.004662067345810103 1.246761198916183 0.5523321337147029 0.5912964046001434
159 157 643072 4899163 0.080384 0 7 89536 False True False 0.25712482738830733 (0.0016360898784780716+0.004385459434551182j) 0.00468070983319329 1.213717477491946 0.5544384543875003 0.5936891287565231
160 158 647168 4913419 0.080896 10160 8 1376 False True False 0.2738845838199934 (-0.0015876886917470013-0.004421074468700674j) 0.004697515815800758 -1.9155711352157767 0.531179403244459 0.5742559283971786
161 159 651264 4913451 0.081408 6096 8 5472 False True False 0.2747492677176624 (-0.0013158162001726363+0.004526012931705732j) 0.00471340273375873 1.853720561422047 0.5310687131217184 0.5744308680295944
162 160 655360 4913483 0.08192 2032 8 9568 False True False 0.2747634003920657 (0.003737797470948664-0.0028737000744164056j) 0.004714793956423873 -0.6554386217012346 0.5309266415904615 0.5742820203304291
163 161 659456 4915547 0.082432 0 8 13664 False True False 0.2760058670060885 (0.0016051542012133788+0.00447398890371161j) 0.004753219616239878 1.2263258552386604 0.5340496829226165 0.5780879855155945
164 162 663552 4919643 0.082944 0 8 17760 False True False 0.27497714732101164 (0.0016332720032709552+0.004516072649607772j) 0.00480234209664452 1.2237740985103753 0.5476249916746951 0.5924192517995834
165 163 667648 4923739 0.083456 0 8 21856 False True False 0.2733575276500988 (0.0016469296756453885+0.004519756643704177j) 0.004810465411457552 1.221364639004181 0.556940211069477 0.6019181460142136
166 164 671744 4927835 0.083968 0 8 25952 True True True 0.2655826518710453 (0.0013094385268856785+0.004465689287358343j) 0.004653709280447115 1.2855693847150558 0.5558054338160154 0.5979837030172348
167 165 675840 4931932 0.08448 1 8 30048 True True True 0.2620066553332512 (0.0010008056079044434+0.0044481756529488265j) 0.00455937259985403 1.3494891413311099 0.5494416678685756 0.589939534664154
168 166 679936 4936027 0.084992 0 8 34144 True True True 0.25745610810815944 (0.0012829361577189977+0.004307185143174958j) 0.004494192813216837 1.281304418017169 0.5547843706430848 0.5941679924726486
169 167 684032 4940123 0.085504 0 8 38240 True True True 0.26383925616404263 (0.0012050656839874409+0.004426963193058868j) 0.004588048214156221 1.3050253747795577 0.5481423154096086 0.5891540050506592
170 168 688128 4944220 0.086016 1 8 42336 True True True 0.2699244067190662 (0.0008380194484942735+0.004581934378772789j) 0.004657939377818761 1.389899279461403 0.5367680805238122 0.578949898481369
171 169 692224 4948315 0.086528 0 8 46432 True True True 0.2691021030184952 (0.00121419546525523+0.0044533788553063475j) 0.00461593477604873 1.304620022784614 0.53117277336095 0.5726411193609238
172 170 696320 4952411 0.08704 0 8 50528 True True True 0.26370857056758684 (0.0015938477998613623+0.004269459998787447j) 0.00455726228018193 1.213504897991644 0.5379725842213715 0.5781805366277695
173 171 700416 4956507 0.087552 0 8 54624 True True True 0.2568596341044175 (0.001446965486859506+0.004214076097215652j) 0.004455574763516697 1.240044764929582 0.5458980072328209 0.5844587683677673
174 172 704512 4960604 0.088064 1 8 58720 True True True 0.26834124851878693 (0.0008934368200219986+0.0046038240991153915j) 0.0046897148833342376 1.3791148572475473 0.5527223312153192 0.5956104695796967
175 173 708608 4964700 0.088576 1 8 62816 True True True 0.2773340662906 (0.0009627857840257513+0.004797044213699565j) 0.004892707803876148 1.372723971241416 0.560669449801557 0.60738605260849
176 174 712704 4968795 0.089088 0 8 66912 True True True 0.2678611827980943 (0.0010743244283594811+0.0045672352206597025j) 0.004691887737169807 1.3397718736689235 0.5551330463819606 0.5980423539876938
177 175 716800 4972891 0.0896 0 8 71008 True True True 0.26521123625627346 (0.0010548052056041765+0.004463329559517832j) 0.004586275698062134 1.3387272036829811 0.5424371911275525 0.5834772288799286
178 176 720896 4976987 0.090112 0 8 75104 True True True 0.25737022850050784 (0.0011324525934055022+0.004313776409934131j) 0.004459945716173578 1.314069283511442 0.5453875555595226 0.5840764492750168
179 177 724992 4981083 0.090624 0 8 79200 True True True 0.26016421509739096 (0.0013264669173897253+0.00434301814084294j) 0.004541070474526934 1.2743698025520087 0.554166359432325 0.5943984687328339
180 178 729088 4985180 0.091136 1 8 83296 True True True 0.2783413309071134 (0.0013001352711514097+0.00466852028999491j) 0.004846177196655742 1.299188582266864 0.545488141480179 0.5912983268499374
181 179 733184 4989275 0.091648 0 8 87392 False True False 0.2669927542714062 (0.0010690162338773935+0.0047141621899569105j) 0.004833851555593401 1.347800703208135 0.54517560929071 0.5870215147733688
182 180 737280 4999467 0.09216 6096 8 91488 False True False 0.24816357519383125 (-0.0014479165006434653+0.0043169281492356215j) 0.004553276934088076 1.8944096410174938 0.5657326760074871 0.6028598994016647
183 181 741376 5001531 0.092672 4064 9 3328 False True False 0.2740896007100458 (-0.0037899232005933095-0.002977920345328503j) 0.004819909485614524 -2.475603261145279 0.5575766126187574 0.602867066860199
184 182 745472 5001563 0.093184 0 9 7424 False True False 0.2743042616798551 (0.00130453694455819+0.004636674957322557j) 0.004816697135961462 1.296534520595517 0.5566299001124788 0.6019200682640076
185 183 749568 5001595 0.093696 -4064 9 11520 False True False 0.27343656950933776 (0.0016448575650682739-0.0045140736020721755j) 0.00480441639476505 -1.2213648928016885 0.5571284056004779 0.6021496653556824
186 184 753664 5009755 0.094208 0 9 15616 False True False 0.24644837794190042 (0.0014424054288444065+0.004024460919176389j) 0.004275139659840118 1.226649391143599 0.5499930625137114 0.5855579823255539
187 185 757760 5013851 0.09472 0 9 19712 False True False 0.24879306161420675 (0.0012449191670893779+0.004102749387320414j) 0.0042874673488837835 1.2761908291392956 0.5429787220660903 0.5788056254386902
188 186 761856 5017947 0.095232 0 9 23808 False True False 0.26695567150173954 (0.0011847130863471237+0.004528474155278807j) 0.004680878472251788 1.3149168858210374 0.5535382083577316 0.5960132926702499
189 187 765952 5022043 0.095744 0 9 27904 True True True 0.2637983930091585 (0.0012155635620488801+0.004491220067611713j) 0.004652811243656798 1.3064756759036986 0.5633993665169301 0.605538547039032
190 188 770048 5026139 0.096256 0 9 32000 True True True 0.2601781313069146 (0.0014610321221578382+0.004345406927177649j) 0.004584449391665322 1.2464460140416111 0.5636380757930741 0.604562520980835
191 189 774144 5030236 0.096768 1 9 36096 True True True 0.2574682516876231 (0.001298756614798111+0.004280571292086525j) 0.004473260481026915 1.276216500083633 0.5491678509292242 0.5881567001342773
192 190 778240 5034331 0.09728 0 9 40192 True True True 0.2557230534224733 (0.001108738527750533+0.004290301714831174j) 0.004431251508005581 1.3179003234342883 0.5472720788091381 0.5855646580457687
193 191 782336 5038427 0.097792 0 9 44288 True True True 0.2591844276449496 (0.0011696742442483666+0.004405803800622378j) 0.004558425711496962 1.3112975975206218 0.5608249286130765 0.6012123078107834
194 192 786432 5042523 0.098304 0 9 48384 True True True 0.26868207485726564 (0.0011177235910650781+0.004592068204744255j) 0.004726139695676223 1.3320360923306238 0.5598665867529256 0.6034280955791473
195 193 790528 5046619 0.098816 0 9 52480 True True True 0.26639007139566734 (0.0012616732316124942+0.004464204940363573j) 0.004639067265403041 1.295359831326025 0.5482883426646452 0.5901688933372498
196 194 794624 5050715 0.099328 0 9 56576 True True True 0.2536069365130275 (0.0014990938223051057+0.004108733154170838j) 0.0043736678452136685 1.220949003984714 0.5422185106395125 0.579489216208458
197 195 798720 5054811 0.09984 0 9 60672 True True True 0.26324630262348936 (0.0014473933824976843+0.004342594477702816j) 0.004577452828973017 1.2490743958972919 0.5487804343548445 0.5896417945623398
198 196 802816 5058907 0.100352 0 9 64768 True True True 0.26746161674679997 (0.0013964631045754207+0.004455196331173598j) 0.00466892745196829 1.2670499289100425 0.5509006238761466 0.5933460593223572
199 197 806912 5063003 0.100864 0 9 68864 True True True 0.25574049545490446 (0.0013486357963794198+0.004207392214630718j) 0.004418253926497562 1.2606039860007627 0.5440070331470497 0.5820767134428024
200 198 811008 5067100 0.101376 1 9 72960 True True True 0.2629884708976966 (0.001045123129219692+0.0044137623372614765j) 0.004535810878449172 1.3382912235991724 0.540570451212055 0.5807358473539352
201 199 815104 5071195 0.101888 0 9 77056 True True True 0.2873942479114494 (0.0010623899727609538+0.004878621166164128j) 0.0049929567329557 1.3563794191279657 0.538916393710259 0.5874359309673309
202 200 819200 5075291 0.1024 0 9 81152 True True True 0.2725851962025746 (0.0010468577792493766+0.0046323056860140535j) 0.004749122779909261 1.3485391685098471 0.5472674857602668 0.5911948531866074
203 201 823296 5079387 0.102912 0 9 85248 True True True 0.2513843183766455 (0.001134941201452397+0.00439649283533871j) 0.004540621188993728 1.3181647689098932 0.5467931267368271 0.583678126335144
204 202 827392 5083483 0.103424 0 9 89344 False True False 0.26256421755141157 (0.0010627634370894722+0.0046536944780845866j) 0.004773503788473327 1.3462767516536025 0.5515670240928654 0.5924075841903687
205 203 831488 5091643 0.103936 4064 10 1184 False True False 0.27258876397618037 (-0.0038680063793312966-0.00277723489387529j) 0.004761775614863231 -2.5188869491625456 0.5512196226945838 0.5954654663801193
206 204 835584 5091675 0.104448 0 10 5280 False True False 0.27240588233562446 (0.001487311386628569+0.0045247471758307605j) 0.0047629226495906314 1.2532161691794101 0.55156569647999 0.5957751721143723
207 205 839680 5091707 0.10496 -4064 10 9376 False True False 0.2721740620175623 (0.0014356126180578048-0.00453346011489686j) 0.004755338495048216 -1.264116616301169 0.5513755050294287 0.5954885333776474
208 206 843776 5099867 0.105472 0 10 13472 False True False 0.2594300166800149 (0.0014767794994913843+0.004273745334716329j) 0.004521700661933252 1.2380941194824366 0.5523710983458887 0.5922305434942245
209 207 847872 5103963 0.105984 0 10 17568 False True False 0.2635039470208177 (0.0012883266803848526+0.004463702338228557j) 0.004645904023943945 1.2898096493804307 0.5612177508783607 0.6030931174755096
210 208 851968 5108059 0.106496 0 10 21664 False True False 0.26676893350381925 (0.0011085188613918987+0.0045316800695588055j) 0.00466529080753795 1.330891881128166 0.5533470249568841 0.5957435071468353
211 209 856064 5112155 0.107008 0 10 25760 True True True 0.26769649861033307 (0.0009767804087360958+0.004581372966701971j) 0.004684343948400701 1.360734656079032 0.5538200423149755 0.5965711772441864
212 210 860160 5116251 0.10752 0 10 29856 True True True 0.256131266937885 (0.0009048122182806056+0.00439301727572447j) 0.004485229752773376 1.367670860405023 0.5571939318707251 0.5963140577077866
213 211 864256 5120347 0.108032 0 10 33952 True True True 0.25301897115559957 (0.0010068931640645764+0.004322075987329293j) 0.0044378119252722345 1.341913576472646 0.5601182547167346 0.5984288305044174
214 212 868352 5124443 0.108544 0 10 38048 True True True 0.26696855591367613 (0.0012309215601142838+0.004492112724254102j) 0.004657708086018251 1.3033429265307364 0.5505673324772662 0.5928188413381577
215 213 872448 5128539 0.109056 0 10 42144 True True True 0.26061560705088677 (0.0014043112701381327+0.004290370017869034j) 0.004514351009133707 1.2544701620679264 0.5449885148501848 0.5847017467021942
216 214 876544 5132635 0.109568 0 10 46240 True True True 0.26336949602200077 (0.0015175076975572559+0.004303237990655464j) 0.004562969079049955 1.231768689979611 0.5437184754310922 0.584243655204773
217 215 880640 5136731 0.11008 0 10 50336 True True True 0.27464480256794577 (0.0016993485450312845+0.004501897630615793j) 0.004811950514504906 1.2098585843646474 0.551037136036287 0.5959927290678024
218 216 884736 5140827 0.110592 0 10 54432 True True True 0.27500097293793924 (0.0016943086540589032+0.004499716621939183j) 0.004808131809026731 1.21067905365459 0.5508883384485461 0.5959579795598984
219 217 888832 5144923 0.111104 0 10 58528 True True True 0.27728841349715994 (0.0014592047535882462+0.004608045616475609j) 0.004833566273096357 1.264121918909197 0.5470731589989841 0.5926406234502792
220 218 892928 5149019 0.111616 0 10 62624 True True True 0.2808954442284297 (0.001321540028381485+0.004706366969990381j) 0.00488839013406571 1.2970474776506113 0.5431006966767402 0.5896233022212982
221 219 897024 5153115 0.112128 0 10 66720 True True True 0.26688871885297244 (0.0012163594036441242+0.004456810196717522j) 0.004619814642212257 1.3043634891796592 0.542377872830745 0.5839741080999374
222 220 901120 5157211 0.11264 0 10 70816 True True True 0.2584040243452016 (0.0012297490842230225+0.00434190848764283j) 0.004512698984555939 1.2947970233139183 0.5552511155037323 0.594979465007782
223 221 905216 5161307 0.113152 0 10 74912 True True True 0.26956783335469564 (0.0014425355859659845+0.004480879786438754j) 0.004707355157335554 1.2593424341663264 0.549948134696654 0.5930426567792892
224 222 909312 5165403 0.113664 0 10 79008 True True True 0.2860522821392337 (0.0014710913905272292+0.004750496996945799j) 0.004973060586527616 1.2704907946331834 0.5395488067357961 0.5876323580741882
225 223 913408 5169500 0.114176 1 10 83104 True True True 0.28140672063874517 (0.0010721642674111451+0.00477187328708063j) 0.0048908394866594195 1.3497825405392807 0.5418614433934189 0.5884615629911423
226 224 917504 5173596 0.114688 1 10 87200 False True False 0.25867954021012346 (0.0009839169384996689+0.00453073974476785j) 0.004636345023473296 1.3569519895502433 0.5357271852248144 0.5741462409496307
227 225 921600 5177692 0.1152 1 10 91296 False True False 0.26237223676573584 (0.0011429895995709038+0.00454483339878272j) 0.004686356350878383 1.3244138479151768 0.5322185693016872 0.5715646147727966
228 226 925696 5181787 0.115712 0 11 3136 False True False 0.2701034954758276 (0.0013597724802481925+0.0044589495582259085j) 0.004661674845036207 1.2748012130593906 0.5383609316350877 0.5807285010814667
229 227 929792 5181819 0.116224 -4064 11 7232 False True False 0.26852876195676684 (0.0015255994291846465-0.00438126032616622j) 0.004639277493744758 -1.235716894414013 0.5394909994438597 0.5814155340194702
230 228 933888 5181851 0.116736 -8128 11 11328 False True False 0.26892700058895613 (-0.003820842233905499+0.0026459066180629393j) 0.004647543136744965 2.535922712155432 0.5400452058880975 0.582147091627121
231 229 937984 5194076 0.117248 1 11 15424 False True False 0.2691833879073944 (0.0010258072970440611+0.0047867337971681965j) 0.004895416331183805 1.3596872888997011 0.5980976072263786 0.6448211520910263
232 230 942080 5198171 0.11776 0 11 19520 False True False 0.27073871499175883 (0.0013708190441480024+0.004736808820083946j) 0.0049311765989288915 1.289095063901871 0.5949415767398565 0.6419998109340668
233 231 946176 5202267 0.118272 0 11 23616 False True False 0.25498334889723284 (0.0013814387836797268+0.004397449823860593j) 0.0046093316290353945 1.2664131183099794 0.5954814634201167 0.6368898153305054
234 232 950272 5206364 0.118784 1 11 27712 True True True 0.2520701625705865 (0.0009223825889995769+0.004332380078972095j) 0.004429481548574711 1.3610240803390832 0.5634445223882787 0.6016745418310165
235 233 954368 5210460 0.119296 1 11 31808 True True True 0.26164867311179046 (0.0008087107334952197+0.004453052814775219j) 0.004525891340017774 1.391146134456171 0.5444633618706969 0.5844766497612
236 234 958464 5214555 0.119808 0 11 35904 True True True 0.26854883778171956 (0.0012413561194861147+0.004505624623853556j) 0.004673501713539979 1.3019536667625724 0.5487865994516878 0.5914403796195984
237 235 962560 5218651 0.12032 0 11 40000 True True True 0.2726733173974843 (0.001378589420936903+0.004526878296162865j) 0.004732138617981256 1.2751848920096938 0.5424629878076264 0.5860351324081421
238 236 966656 5222747 0.120832 0 11 44096 True True True 0.26774424452520174 (0.0013053061679331418+0.0044299709635238094j) 0.004618275319825397 1.2842518255973607 0.5379742199872226 0.579518124461174
239 237 970752 5226844 0.121344 1 11 48192 True True True 0.2529277516354949 (0.0009143590480539627+0.004254492347760584j) 0.0043516384966942635 1.359100328612116 0.5398657003944332 0.5767626166343689
240 238 974848 5230940 0.121856 1 11 52288 True True True 0.2678507653416655 (0.0010920771787949514+0.004531790102875468j) 0.0046615184329749015 1.3343235913479703 0.5483664187313746 0.5907491445541382
241 239 978944 5235035 0.122368 0 11 56384 True True True 0.27166443355630754 (0.0013576998340728897+0.004544220909553324j) 0.004742709406474656 1.2804637172622124 0.5497189797711337 0.5935218185186386
242 240 983040 5239132 0.12288 1 11 60480 True True True 0.24298761555141254 (0.0009359177755966125+0.00412392315729343j) 0.004228792296854827 1.3476281418310532 0.5537337934408951 0.5884793698787689
243 241 987136 5243228 0.123392 1 11 64576 True True True 0.2594503125405808 (0.000872214900954877+0.004443342101533314j) 0.004528139558881353 1.3769638279001095 0.5535284658088118 0.5934781283140182
244 242 991232 5247323 0.123904 0 11 68672 True True True 0.2728972761722316 (0.0010649047350872493+0.00460220143954971j) 0.004723799337927541 1.343407899747667 0.5392853326323054 0.5826791524887085
245 243 995328 5251420 0.124416 1 11 72768 True True True 0.2677790176885852 (0.0010331007579770734+0.004533070798005724j) 0.004649304037795878 1.346720423115713 0.5431229706384719 0.5850762128829956
246 244 999424 5255516 0.124928 1 11 76864 True True True 0.27273585576465686 (0.001190185230456936+0.004606812727866582j) 0.004758073600989309 1.317971325646566 0.5488263894264966 0.5929315090179443
247 245 1003520 5259611 0.12544 0 11 80960 True True True 0.277553334130381 (0.001377950261444966+0.004616611618738488j) 0.00481786776087591 1.2807377876274038 0.5415111722890744 0.5867087841033936
248 246 1007616 5263707 0.125952 0 11 85056 True True True 0.2655589509320627 (0.0011514306146589667+0.004635249098410475j) 0.004776120461702055 1.3273170531356284 0.5375551530033255 0.5783406347036362
249 247 1011712 5267804 0.126464 1 11 89152 False True False 0.25538412849058145 (0.0009827635050397186+0.004463016645785106j) 0.004569938915061435 1.3540537158216441 0.535083797776337 0.5724174678325653
250 248 1015808 5280027 0.126976 8128 12 992 False True False 0.2812606928866462 (0.0048793151638969095+8.05644236800617e-05j) 0.004879980235103132 0.016509920106764792 0.5399580759163802 0.5863421857357025
251 249 1019904 5278028 0.127488 2033 12 5088 False True False 0.2816763742277087 (0.0041030436954555246-0.002639239528791662j) 0.004878581029065087 -0.5716079390475177 0.5385550842790271 0.584967315196991
252 250 1024000 5278060 0.128 -2031 12 9184 False True False 0.28242789552891234 (-0.004878754419270177-0.0002662660909589648j) 0.004886014972832446 -3.0870700906873467 0.5376792656874811 0.5842850655317307
253 251 1028096 5278091 0.128512 -6096 12 13280 False True False 0.2681008918313915 (0.0038474847466956337+0.0025998928860442062j) 0.004643552723396047 0.5942567128822575 0.5426132080040174 0.5846357047557831
254 252 1032192 5288283 0.129024 0 12 17376 False True False 0.24375932875272263 (0.0011357620006579774+0.0040703688113794805j) 0.0042258558402753655 1.2986857372531115 0.5460942745071787 0.5805922597646713
255 253 1036288 5292379 0.129536 0 12 21472 False True False 0.25538271104520355 (0.0011127166312888783+0.004253423429781606j) 0.004396561062303354 1.3149255298493328 0.5379460291956822 0.5754789561033249
256 254 1040384 5296476 0.130048 1 12 25568 True True True 0.2632105657612795 (0.0011581742548442148+0.0043932573571891466j) 0.004543355347216472 1.313035430034399 0.5401483179505394 0.5803552120923996
257 255 1044480 5300571 0.13056 0 12 29664 True True True 0.26986947258717187 (0.0013068274108764114+0.004486378559068552j) 0.004672835376630335 1.2873514021821055 0.541962749115588 0.5845340937376022
258 256 1048576 5304667 0.131072 0 12 33760 True True True 0.2716474398335631 (0.0014068769556635232+0.0045219013663756165j) 0.004735704249169993 1.2691645381137087 0.5479715361191466 0.5916292369365692
259 257 1052672 5308763 0.131584 0 12 37856 True True True 0.2602069168691974 (0.0014259509292018208+0.004322987510848465j) 0.004552093701962135 1.2521812254494566 0.553095674227995 0.5932641923427582
260 258 1056768 5312859 0.132096 0 12 41952 True True True 0.26067296967171716 (0.001243339607338989+0.004388924606338943j) 0.004561639242564598 1.294739177254704 0.5553010262917414 0.5957848429679871
261 259 1060864 5316955 0.132608 0 12 46048 True True True 0.2763320728115187 (0.001091005945684809+0.004723962722877519j) 0.004848310817249239 1.3438244988245012 0.5541697016465323 0.5999841392040253
262 260 1064960 5321051 0.13312 0 12 50144 True True True 0.2754645271489226 (0.0013234191848957258+0.0046175039478779465j) 0.004803413478727236 1.2916694754434184 0.5464955195365455 0.591369017958641
263 261 1069056 5325147 0.133632 0 12 54240 True True True 0.26852039912809356 (0.0015103311655884739+0.00438350483122627j) 0.004636401064956728 1.2389860736762326 0.5387882672532496 0.5806553810834885
264 262 1073152 5329243 0.134144 0 12 58336 True False False 0.12222192020312277 (0.0016917557631161454+0.0040214872795306614j) 0.004362842823373725 1.172591181605333 2.4462056325581023 2.4833016842603683
265 263 1077248 5333339 0.134656 0 12 62432 True False False 0.08371985216496043 (0.001522863605885863+0.004194885739388139j) 0.004462754746639531 1.2225621889916407 5.489172343866355 5.527917593717575
266 264 1081344 5337436 0.135168 1 12 66528 True False False 0.07678297321464417 (0.000837113473129972+0.004424337184075886j) 0.004502834494548102 1.383800318183157 6.664573420147217 6.704098269343376
267 265 1085440 5341532 0.13568 1 12 70624 True False False 0.075825225755414 (0.0010644786672962556+0.0043263854821034625j) 0.0044554153760210085 1.329544959208023 6.688882765976795 6.72756265103817
268 266 1089536 5345627 0.136192 0 12 74720 True False False 0.0777915075019332 (0.0013604196351404264+0.004361358503073744j) 0.00456860915115413 1.2684347849139403 6.676964480041531 6.717616260051727
269 267 1093632 5349723 0.136704 0 12 78816 True False False 0.0828610428066847 (0.0015486982431894794+0.004585583083988033j) 0.004840045296132608 1.2450921911444341 6.60539333945425 6.651059195399284
270 268 1097728 5353821 0.137216 2 12 82912 True False False 0.08195769883417732 (0.0011937036958979035+0.004685608387128368j) 0.004835271912842961 1.3213430856688024 6.74911831950998 6.794759154319763
271 269 1101824 5357917 0.137728 2 12 87008 False False False 0.0716654800554192 (0.0005531018437636853+0.004432103696542682j) 0.004466482377272085 1.4466437471388893 6.906468290897046 6.942122623324394
272 270 1105920 5366076 0.13824 4065 12 91104 False False False 0.07377076771462239 (-0.004091817902133142-0.0020419652606560356j) 0.004573029178776726 -2.6787163810812644 6.832708365234196 6.870096296072006
273 271 1110016 5374235 0.138752 8128 13 2944 False False False 0.08087575586757796 (0.004779806391792624+8.861341029904627e-05j) 0.004780627728604942 0.018536997739119303 6.768167156707149 6.812728449702263
274 272 1114112 5374267 0.139264 4064 13 7040 False False False 0.0800133242828991 (-0.003767808252151954-0.0028533788785221463j) 0.004726325216209805 -2.4934329082951177 6.763541054221683 6.807121142745018
275 273 1118208 5374299 0.139776 0 13 11136 False False False 0.07956224503645665 (0.0013792993209312803+0.004496803629903398j) 0.004703584750234004 1.273177782321964 6.7703096256518736 6.813439726829529
276 274 1122304 5378395 0.140288 0 13 15232 False False False 0.07909923134694494 (0.0015060370202961348+0.004398239469498638j) 0.004648941593261645 1.2408918421229516 6.697100535491124 6.739266023039818
277 275 1126400 5382492 0.1408 1 13 19328 False False False 0.07780223075074265 (0.001290172857201479+0.0043936989878511305j) 0.0045792070052907054 1.2851830749053166 6.6471269868946585 6.687608331441879
278 276 1130496 5386588 0.141312 1 13 23424 False False False 0.07864006701111693 (0.0010540703263440517+0.004463093516908906j) 0.004585877014656342 1.3388713181506051 6.581861800468286 6.622819036245346
279 277 1134592 5390682 0.141824 -1 13 27520 True False False 0.08301430893626999 (0.0015449788316282908+0.004589310350730047j) 0.004842388778846393 1.2460661944160356 6.588775629410941 6.634496435523033
280 278 1138688 5394779 0.142336 0 13 31616 True False False 0.07878097899540573 (0.001481786310700397+0.004374651467605647j) 0.004618794878927114 1.24420473670389 6.651206343796035 6.692744478583336
281 279 1142784 5398876 0.142848 1 13 35712 True False False 0.09576023729412096 (0.0010937122441491563+0.004038675938138141j) 0.004184149830765837 1.3063300491750123 3.679667399162275 3.7137223184108734
282 280 1146880 5402972 0.14336 1 13 39808 True True True 0.2383815900640343 (0.0012815346971280827+0.004158815962114253j) 0.004351790595453722 1.2718803162847057 0.6127624549315758 0.6496810913085938
283 281 1150976 5407067 0.143872 0 13 43904 True True True 0.26364871875573537 (0.0013686838317304665+0.004418645928249998j) 0.004625767749301804 1.2704170494974214 0.5558803660749743 0.5974064767360687
284 282 1155072 5411164 0.144384 1 13 48000 True True True 0.26715586396351754 (0.0012130199951223312+0.004499399727171521j) 0.004660044572044107 1.3074611161349192 0.5495655838572667 0.5918039679527283
285 283 1159168 5415260 0.144896 1 13 52096 True True True 0.25698590459791865 (0.001158258764511068+0.004307109301455813j) 0.004460129359139025 1.3080933467821958 0.5475274608915194 0.5862440466880798
286 284 1163264 5419356 0.145408 1 13 56192 True True True 0.2581379731067278 (0.001248193819057321+0.004339140607048203j) 0.004515100111588618 1.2906994427415837 0.55376852676701 0.5933034271001816
287 285 1167360 5423452 0.14592 1 13 60288 True True True 0.2530657803756539 (0.0013788577757052885+0.00419175764528281j) 0.00441271808780142 1.2530004458654427 0.5521800321637115 0.5899625867605209
288 286 1171456 5427547 0.146432 0 13 64384 True True True 0.25392783983290507 (0.001401972804627126+0.004166755137027025j) 0.00439629117744209 1.246228731526822 0.5473219261437456 0.585045263171196
289 287 1175552 5431643 0.146944 0 13 68480 True True True 0.2652653510843641 (0.0014373715911341833+0.004373403795019587j) 0.004603552741665001 1.253255857245764 0.5448719137584159 0.5861142575740814
290 288 1179648 5435739 0.147456 0 13 72576 True True True 0.26566180677487866 (0.00145395835175196+0.004343914276516279j) 0.00458078444486872 1.2478058759437545 0.5376427555518017 0.5784688889980316
291 289 1183744 5439835 0.147968 0 13 76672 True True True 0.2634471009230045 (0.0014112452051848665+0.004300735879135284j) 0.004526360804359151 1.2537266677052141 0.5335782988276216 0.5733728855848312
292 290 1187840 5443931 0.14848 0 13 80768 True True True 0.25121895961789686 (0.0013545192402851529+0.004096059693806466j) 0.004314212255734364 1.2514281391921533 0.5380727033377047 0.5743184983730316
293 291 1191936 5448027 0.148992 0 13 84864 True True True 0.24618455862048508 (0.001239173099831446+0.004247836216677644j) 0.004424891241043571 1.286954298856598 0.5431489357370782 0.5781912803649902
294 292 1196032 5452123 0.149504 0 13 88960 False True False 0.25460500594550434 (0.001456645781360352+0.004342461175011724j) 0.004580260471724191 1.2471487770574143 0.5413396313714424 0.578863725066185
295 293 1200128 5464347 0.150016 8128 14 800 False True False 0.2664892367017101 (0.004595258533890168-0.00025639798128029975j) 0.004602405992314784 -0.05573840974724589 0.5403135139541736 0.581617996096611
296 294 1204224 5464379 0.150528 4064 14 4896 False True False 0.2677067102634058 (-0.0039035142522089628-0.002474915637314424j) 0.004621972623136355 -2.576531583209091 0.5393652625029224 0.5810040086507797
297 295 1208320 5464411 0.15104 0 14 8992 False True False 0.2676224417366838 (0.0017066501910134538+0.0042936749487946044j) 0.004620421998085522 1.1924641946640253 0.5397369743995677 0.5813761651515961
298 296 1212416 5468507 0.151552 0 14 13088 False True False 0.2540449166869206 (0.0012582258203098654+0.004159380751831945j) 0.004345524186286909 1.2770446405022853 0.5336992416461102 0.5705199241638184
299 297 1216512 5472603 0.152064 0 14 17184 False True False 0.24859482152857068 (0.0012690168352510153+0.004147650472783568j) 0.004337442584349937 1.2738802772540043 0.553916127141515 0.5904026478528976
300 298 1220608 5476700 0.152576 1 14 21280 False True False 0.2558611321685786 (0.0011615097203271432+0.004337193105057625j) 0.0044900277127178 1.309134118890352 0.5548674484680924 0.5937363505363464
301 299 1224704 5480796 0.153088 1 14 25376 True True True 0.24902334455788566 (0.0011255067621460822+0.004187091354160079j) 0.004335723639684458 1.3081995949229324 0.5533850609771982 0.5899706929922104
302 300 1228800 5484891 0.1536 0 14 29472 True True True 0.2524803523265553 (0.0013228128281321033+0.004215829556643872j) 0.004418489858418024 1.266752277708672 0.5565978879327824 0.5944947451353073
303 301 1232896 5488987 0.154112 0 14 33568 True True True 0.25659362997876295 (0.001523597078719511+0.004232821106107312j) 0.004498680092492703 1.2252864490022244 0.559860953567165 0.5993203818798065
304 302 1236992 5493083 0.154624 0 14 37664 True True True 0.2701015466384452 (0.0015930439218050786+0.004434456215466593j) 0.004711920082481281 1.2259117421093622 0.5500180173758105 0.5933022946119308
305 303 1241088 5497179 0.155136 0 14 41760 True True True 0.2654883946307786 (0.0015101082344784968+0.004325150491303857j) 0.0045811956574966055 1.2348826680926182 0.5382364009561323 0.5790502279996872
306 304 1245184 5501275 0.155648 0 14 45856 True True True 0.2642378873941613 (0.0014789350860992378+0.004294330327625845j) 0.004541863268710591 1.239125775840792 0.5361206526207132 0.5763632953166962
307 305 1249280 5505371 0.15616 0 14 49952 True True True 0.2704631814372041 (0.0014297452012599925+0.004460898789483908j) 0.004684419852078267 1.2606343751470939 0.5420946543757261 0.5848787277936935
308 306 1253376 5509467 0.156672 0 14 54048 True True True 0.25862368887790793 (0.0014114606716766828+0.004290730646771298j) 0.0045169227036592555 1.2529907254827484 0.5547799785112384 0.5945469737052917
309 307 1257472 5513563 0.157184 0 14 58144 True True True 0.2537946459711735 (0.0014512878585148262+0.004152496169937046j) 0.004398802210785839 1.2345690612285416 0.5482861363456426 0.5860335677862167
310 308 1261568 5517659 0.157696 0 14 62240 True True True 0.25880367193626036 (0.0013953166604228435+0.004247498083004329j) 0.004470810726029341 1.253399184203357 0.5424842444975086 0.5814279019832611
311 309 1265664 5521755 0.158208 0 14 66336 True True True 0.25852433212459397 (0.0012096553631778682+0.004317856823054481j) 0.004484100092779276 1.297646864720312 0.5464240381960734 0.5855598300695419
312 310 1269760 5525851 0.15872 0 14 70432 True True True 0.26478919294097997 (0.0012756367113437668+0.004410535775679678j) 0.004591304264354332 1.2892540359027742 0.5455173013175918 0.5866492241621017
313 311 1273856 5529947 0.159232 0 14 74528 True True True 0.26738258733865083 (0.0014459702809501217+0.004439384043162406j) 0.004668935717706549 1.2559186226601515 0.551789156057867 0.5942759960889816
314 312 1277952 5534043 0.159744 0 14 78624 True True True 0.25761703065587765 (0.0013013793274676412+0.004291751269303245j) 0.004484720405056056 1.276380664774593 0.5515944654460578 0.5908040851354599
315 313 1282048 5538139 0.160256 0 14 82720 True True True 0.2594854532357755 (0.001014695960330343+0.004360357591237143j) 0.004476865668676032 1.3421562446445414 0.539021821863747 0.5779357999563217
316 314 1286144 5542236 0.160768 1 14 86816 False True False 0.25534036090986695 (0.0010348878449817414+0.004494382765061006j) 0.004611991900531523 1.3444786345884008 0.5423552649187608 0.5801824033260345
317 315 1290240 5546331 0.16128 0 14 90912 False True False 0.24958348378421272 (0.0015809884356665748+0.004215168793332553j) 0.004501907638989949 1.2119632322931633 0.5466115493167396 0.5829229354858398
318 316 1294336 5552459 0.161792 2032 15 2752 False True False 0.2653891462384448 (0.0037756615455502513-0.0024862762863175044j) 0.004520751030354544 -0.5823280105725755 0.5254411813925184 0.5652527213096619
319 317 1298432 5552491 0.162304 -2032 15 6848 False True False 0.2657521082769784 (-0.004521714802829172-0.00017802384287181412j) 0.0045252179225707245 -3.1022421077858477 0.5259034994737588 0.5658674240112305
320 318 1302528 5552523 0.162816 -6096 15 10944 False True False 0.2648650947094851 (0.0035480581267110073+0.00278413095489372j) 0.004510000182319003 0.665336521026977 0.5263289531903287 0.5660385489463806
321 319 1306624 5562715 0.163328 0 15 15040 False True False 0.2620496140457573 (0.001531028169564713+0.004261039621478605j) 0.004527748437337394 1.2258529584701106 0.5415241879914068 0.5814525336027145
322 320 1310720 5566812 0.16384 1 15 19136 False True False 0.26453769584680464 (0.0011282515653286331+0.00448029271963071j) 0.0046201703916893 1.32410036700869 0.547386468762953 0.5885750651359558
323 321 1314816 5570908 0.164352 1 15 23232 False True False 0.2602922116740193 (0.0010637771205495672+0.004353568314823194j) 0.004481649119915256 1.3311460884082906 0.5387595665150288 0.5779144465923309
324 322 1318912 5575003 0.164864 0 15 27328 True True True 0.2646714154148712 (0.001350060593372117+0.004299112239390732j) 0.004506110257489876 1.2665159901569734 0.5260034771882566 0.5656261295080185
325 323 1323008 5579099 0.165376 0 15 31424 True True True 0.2675197135922362 (0.001229299289273+0.004407258670649587j) 0.004575489671349184 1.2987837668896933 0.5257819233489514 0.5663109868764877
326 324 1327104 5583195 0.165888 0 15 35520 True True True 0.2527301679389408 (0.0011438527326352401+0.004195144440594359j) 0.00434829115301711 1.3046058624948298 0.5373194205840789 0.5739810466766357
327 325 1331200 5587291 0.1664 0 15 39616 True True True 0.24252120082883175 (0.0013404286467247842+0.003997623218501677j) 0.004216365775648994 1.2472710654732522 0.5534920044503024 0.588080883026123
328 326 1335296 5591387 0.166912 0 15 43712 True True True 0.2571775457631954 (0.0015098749844689487+0.004185489604321386j) 0.0044494994883253446 1.2245854919847523 0.5440344222728948 0.5825654715299606
329 327 1339392 5595483 0.167424 0 15 47808 True True True 0.26432524091011667 (0.0014117994702806471+0.004327530007223564j) 0.004551998869475376 1.2554462062864538 0.5386840960050098 0.5791479051113129
330 328 1343488 5599579 0.167936 0 15 51904 True True True 0.2621376516183847 (0.0013181958784353406+0.004343836003591089j) 0.004539443974763663 1.2761650037093621 0.544478221527759 0.5846533477306366
331 329 1347584 5603675 0.168448 0 15 56000 True True True 0.2602155447030736 (0.0014567732237749647+0.004242818646846353j) 0.004485944526577967 1.2400577194321012 0.5383806447420117 0.5774832665920258
332 330 1351680 5607772 0.16896 1 15 60096 True True True 0.26420496559852147 (0.0012353303830398529+0.004402993922998593j) 0.00457300739571061 1.2972628513414242 0.5426832718703825 0.5834076106548309
333 331 1355776 5611867 0.169472 0 15 64192 True True True 0.2645956652886718 (0.0013486633031770535+0.004399815742174559j) 0.004601876929082688 1.2733620636596512 0.5481978807485378 0.5894669741392136
334 332 1359872 5615963 0.169984 0 15 68288 True True True 0.27635966275564405 (0.001538395327785914+0.004518762326779053j) 0.004773455053781399 1.2426579370597932 0.5369393073322216 0.5813388675451279
335 333 1363968 5620060 0.170496 1 15 72384 True True True 0.28065909499300684 (0.0013899322538439272+0.004688437803033093j) 0.004890128904557162 1.2825907901516267 0.5446156770475633 0.5911828726530075
336 334 1368064 5624155 0.171008 0 15 76480 True True True 0.2787902846792729 (0.001505395943641435+0.004657137912448599j) 0.0048943999103769785 1.2581526999750539 0.5536297896520709 0.6002864688634872
337 335 1372160 5628251 0.17152 0 15 80576 True True True 0.2782403905799784 (0.0013851585328944899+0.004671326949604034j) 0.004872366943421579 1.2825319635019046 0.549059815247206 0.5951337069272995
338 336 1376256 5632347 0.172032 0 15 84672 True True True 0.25835564575952363 (0.0014878867435889247+0.004418020064904829j) 0.004661835288343993 1.2459498434659404 0.5424659481705443 0.5812639445066452
339 337 1380352 5636443 0.172544 0 15 88768 False True False 0.2661307059301699 (0.001742326334063677+0.0044784482607504j) 0.00480543441101739 1.1997678069313928 0.5420525528553599 0.5833700597286224
340 338 1384448 5650699 0.173056 10160 16 608 False True False 0.2807983627799369 (-0.0014132177560300736-0.004678753858631776j) 0.0048875271964072394 -1.864132822427261 0.5440899108503512 0.5906622856855392
341 339 1388544 5650731 0.173568 6096 16 4704 False True False 0.28175733500795064 (-0.0016292651991435913+0.00462401096559049j) 0.004902650558528672 1.909562177118072 0.5438451356478441 0.5907425284385681
342 340 1392640 5650763 0.17408 2032 16 8800 False True False 0.2810896310741443 (0.004032377747532641-0.0027645120137144447j) 0.00488902822376471 -0.6009814789944031 0.5438568421206966 0.5905141830444336
343 341 1396736 5652827 0.174592 0 16 12896 False True False 0.27995892582994847 (0.0013644086381278274+0.004682448638769451j) 0.00487718527293271 1.287259194961097 0.5457013503526119 0.5921090841293335
344 342 1400832 5656923 0.175104 0 16 16992 False True False 0.2694191676957321 (0.0012987608029786238+0.004501592194187054j) 0.004685201373059593 1.289912543456448 0.5464975984850089 0.5892708152532578
345 343 1404928 5661020 0.175616 1 16 21088 False True False 0.2724290212387798 (0.0013557614569333096+0.004514417086428908j) 0.004713602736585594 1.2790476630851628 0.5394092203654874 0.5826522558927536
346 344 1409024 5665116 0.176128 1 16 25184 True True True 0.2703439033029992 (0.0015023504482026882+0.004452830832832162j) 0.004699442445124271 1.2453972397154547 0.5445303148943486 0.5874657332897186
347 345 1413120 5669212 0.17664 1 16 29280 True True True 0.26084853462192703 (0.0015064276691071788+0.0042858697602228745j) 0.004542906990446158 1.2327973663021916 0.5488662670965079 0.5889388173818588
348 346 1417216 5673307 0.177152 0 16 33376 True True True 0.26680859121689254 (0.0017233605136990984+0.004346323777514884j) 0.004675521557983502 1.1933022514222584 0.5563818107259524 0.5990244597196579
349 347 1421312 5677403 0.177664 0 16 37472 True True True 0.28118617001285623 (0.0017648563265804532+0.004599738199242859j) 0.004926693551972255 1.2044321407102385 0.5511238823654319 0.5984399318695068
350 348 1425408 5681499 0.178176 0 16 41568 True True True 0.2765548104730267 (0.0017933494122994718+0.004409004550129239j) 0.004759771343001174 1.1844871287004388 0.5314170018017368 0.5754271447658539
351 349 1429504 5685595 0.178688 0 16 45664 True True True 0.2665701091804682 (0.0016608712100729577+0.004276843269699999j) 0.00458801498799071 1.200381524244915 0.5360344693741199 0.5770386159420013
352 350 1433600 5689691 0.1792 0 16 49760 True True True 0.27603880819109367 (0.001647519716432292+0.00448414294414518j) 0.004777222954767775 1.218696301508401 0.5400274148415931 0.5845701545476913
353 351 1437696 5693787 0.179712 0 16 53856 True True True 0.27423717356605604 (0.0018811367461085812+0.004391660175502362j) 0.004777588780405176 1.1660975677898966 0.5460581921807042 0.5904646962881088
354 352 1441792 5697883 0.180224 0 16 57952 True True True 0.26939315416499676 (0.001895787593627749+0.004261155598661815j) 0.004663845798926014 1.1521917534315318 0.5405786387936542 0.5828797817230225
355 353 1445888 5701979 0.180736 0 16 62048 True True True 0.2704970887722574 (0.0018084369666119368+0.004265944201606953j) 0.004633435463393503 1.1698372476397976 0.5303428144210389 0.5722107142210007
356 354 1449984 5706075 0.181248 0 16 66144 True True True 0.2631123469104774 (0.0014536311531551688+0.004261454370101405j) 0.004502558925531079 1.2420618201093678 0.532675277665522 0.5722941160202026
357 355 1454080 5710171 0.18176 0 16 70240 True True True 0.266366325753132 (0.0013174392407077908+0.004407645976290434j) 0.004600324902141802 1.2803502910288584 0.5411182266002784 0.5824431627988815
358 356 1458176 5714267 0.182272 0 16 74336 True True True 0.27057933254212896 (0.0013928641345691333+0.004495997771867698j) 0.004706810646500274 1.2703723153640838 0.5461706870280945 0.5893164128065109
359 357 1462272 5718363 0.182784 0 16 78432 True True True 0.2670809726675467 (0.0012795950443333676+0.004403007790597894j) 0.004585176232332653 1.2879685794606828 0.5334450177163121 0.5744196623563766
360 358 1466368 5722459 0.183296 0 16 82528 True True True 0.26574562793667467 (0.0016406126164279962+0.004275302399884901j) 0.004579281643188625 1.2043836478611014 0.5377712923688862 0.5786349177360535

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@@ -0,0 +1,17 @@
packet_index,raw_power_code2,rms_full_iq_code,mean_i,mean_q,ac_power_code2,ac_rms_code,max_abs_i,max_abs_q,max_complex_magnitude,background_ac_power_code2,background_subtracted_useful_power_code2,symbol_error_rate,symbol_rms_deviation,matched_component_power,residual_power,matched_residual_db,band_gain_nonuniformity_db,initial_frequency_hz,diagnostic_residual_phase_error_rad,local_delay_median_samples,local_delay_min_samples,local_delay_max_samples,local_correlation_median,local_correlation_min,local_gain_amplitude_median,local_phase_unwrapped_span_rad,ser_minus_lab056_b,evm_minus_lab056_b,matched_residual_minus_lab056_b_db,ripple_minus_lab056_b_db
1,4.900591831425598,2.2137280391740983,0.9692702913631633,1.8366285119667014,0.5879026427373475,0.7667480960115568,3.0,4.0,4.4721360206604,0.5252822403066744,0.06262040243067313,0.08517887563884156,1.088322316906538,0.7075133679013462,0.8380110003749788,-0.7351506962803888,6.642520146946069,1.0073017677042053,5.396055347590577,0.0,0,1,0.2720544529364392,0.2556440262627536,0.004692917533594935,0.120558278787813,0.05021991563884157,0.24297231690653787,-2.199996696280389,1.1711381469460687
2,4.865146982310094,2.2057078188894588,0.9677527748872702,1.8294528269164065,0.5817039030956508,0.7626951573831126,3.0,4.0,4.4721360206604,0.5252822403066744,0.05642166278897642,0.09795570698466781,1.104921348985033,0.6708739973434846,0.8190373162813612,-0.8666272994726886,6.598551357893342,1.6416990453424165,0.9116196756938657,0.0,0,1,0.2633530926845802,0.2539878786554866,0.0045493907778025216,0.0709144214354922,0.06299674698466781,0.25957134898503287,-2.3314732994726888,1.127169357893342
3,6.015186004162331,2.4525876139625127,0.9700940860215054,1.8342655220256676,1.7095734631363353,1.3075065824447445,6.0,7.0,7.211102485656738,0.5252822403066744,1.184291222829661,0.10221465076660988,1.3578439728375573,0.6181275875589448,1.1396667156434608,-2.6569973778482696,7.370968795797246,-0.9619877262845884,0.9174219316762064,0.0,0,1,0.2672883844824355,0.24083000237735547,0.004581545172098038,0.15725486354106955,0.06725569076660988,0.5124939728375573,-4.12184337784827,1.899586795797246
4,8.462127124523066,2.9089735517056643,0.9603494623655914,1.846362296219216,4.130802305757289,2.032437528131502,6.0,7.0,7.6157732009887695,0.5252822403066744,3.6055200654506145,0.15587734241908008,1.6634180909816034,0.694252592647496,1.920968976998595,-4.420028409350613,10.617549420778396,2.5845496302438504,5.388297118381418,0.0,0,0,0.2731302498054202,0.1663171407536924,0.004805263148615891,0.12094876972869106,0.12091838241908008,0.8180680909816034,-5.884874409350614,5.146167420778395
5,4.954615417967395,2.2258965425121167,0.9645117932708983,1.8537439299340963,0.5879658608412441,0.7667893197229889,3.0,4.0,4.242640495300293,0.5252822403066744,0.06268362053456977,0.08986371379897785,1.0991964913376657,0.7021817411712009,0.8483991001186207,-0.8215066687796163,6.409725568268307,-1.2358463102217572,0.8342172701371073,0.0,0,1,0.26644916295862675,0.2537591241878097,0.0046666418592819555,0.09866723940073996,0.05490475379897786,0.2538464913376657,-2.2863526687796165,0.9383435682683068
6,4.919647502601457,2.218027840808464,0.968934269857787,1.8444437218175511,0.5788412403444356,0.7608161672470135,3.0,4.0,4.4721360206604,0.5252822403066744,0.05355900003776126,0.075809199318569,1.1024024281507157,0.6444662106996041,0.783214058873921,-0.8468032228257232,6.3642932090088,-1.7795429995488667,5.318131944986163,0.0,0,1,0.2655258469985231,0.25666966629660665,0.004581829702937256,0.20674702332927808,0.040850239318569,0.2570524281507156,-2.3116492228257233,0.8929112090087994
7,4.958322493929934,2.226729102053039,0.9635145681581686,1.856150277488727,0.5846683182554333,0.7646360691567154,3.0,4.0,4.4721360206604,0.5252822403066744,0.05938607794875894,0.08390119250425894,1.1001519668540132,0.6819353341348239,0.8253697594999119,-0.8290535905764504,6.236828217134885,-0.2484094971075878,1.4617535496008514,0.0,0,1,0.266458697108116,0.24788848233138613,0.004627604818355622,0.11827169376376112,0.04894223250425894,0.25480196685401313,-2.2938995905764505,0.765446217134885
8,4.913306451612903,2.2165979454138505,0.9589186611168922,1.8453433922996878,0.5884892174705705,0.7671305087601265,3.0,4.0,4.4721360206604,0.5252822403066744,0.06320697716389612,0.08262350936967632,1.1492572709962479,0.6381478875618168,0.8428608001594871,-1.2083452015652267,6.714920606410644,-1.0783628659018663,0.78177232042639,0.0,0,1,0.26521123625627346,0.2568596341044175,0.004588048214156221,0.17639438146975883,0.04766454936967632,0.3039072709962478,-2.673191201565227,1.2435386064106435
9,4.8869558619493585,2.2106460281893523,0.9541276448144294,1.840042924037461,0.5908383370498989,0.7686600920107007,3.0,4.0,4.4721360206604,0.5252822403066744,0.06555609674322449,0.08943781942078365,1.141830995657666,0.6581222468886276,0.858045321706861,-1.1520365600725753,6.809131520732102,0.8322819250764986,1.0738651986809553,0.0,0,1,0.2629884708976966,0.2513843183766455,0.004577452828973017,0.13543041514325171,0.05447885942078365,0.29648099565766595,-2.6168825600725754,1.3377495207321015
10,4.915355098855359,2.2170600124614035,0.9478299514394728,1.850437911897329,0.5928530162226577,0.769969490449237,3.0,4.0,4.242640495300293,0.5252822403066744,0.06757077591598337,0.08347529812606473,1.0923957700987015,0.6971368095977797,0.8319132362097249,-0.7676001965024029,6.678161163217084,-1.3378733037888852,0.7703154441715622,0.0,0,1,0.26769649861033307,0.25301897115559957,0.004684343948400701,0.1578122760403755,0.048516338126064734,0.24704577009870143,-2.232446196502403,1.2067791632170835
11,4.919918487686438,2.218088926911281,0.9430389351370101,1.852898456468956,0.5973633645170526,0.7728928544869933,3.0,4.0,4.4721360206604,0.5252822403066744,0.07208112421037827,0.08049403747870527,1.0853439130113745,0.6882509611422404,0.8107399547939167,-0.7113474983787614,6.630624104636567,1.1396956047405093,0.8869440636679229,1.0,0,1,0.2677790176885852,0.24298761555141254,0.0046615184329749015,0.11596124244647732,0.04553507747870528,0.2399939130113744,-2.1761934983787614,1.1592421046365669
12,6.8007067291016305,2.607816467679739,0.9549947970863684,1.8480749219562955,2.4733107494758295,1.5726763015559908,6.0,7.0,8.062257766723633,0.5252822403066744,1.9480285091691552,0.12819420783645655,1.4566037803957919,0.6313306634190563,1.3394908423846723,-3.2668286553130113,7.945031576922354,-0.15870982770940278,1.0850946010670803,0.0,0,1,0.2691949358576327,0.2602069168691974,0.004654618220793532,0.10483842514826858,0.09323524783645655,0.6112537803957918,-4.731674655313011,2.4736495769223534
13,7.57159425945196,2.751653004913948,0.9523066250433576,1.8468283905653833,3.253931247152167,1.8038656399943336,6.0,7.0,7.810249328613281,0.5252822403066744,2.7286490068454925,0.16013628620102216,1.542471770787923,0.6706715317796331,1.5956745609431342,-3.764344492637608,9.871896166053979,-3.768747766207012,1.4778689507229945,0.0,0,1,0.25756193885232326,0.2383815900640343,0.004487614735363821,0.0618646152553739,0.12517732620102218,0.6971217707879229,-5.229190492637608,4.400514166053979
14,4.931039715574054,2.220594450946425,0.9521657127991675,1.8542859001040584,0.5860439716189889,0.7655350884309542,3.0,4.0,4.4721360206604,0.5252822403066744,0.06076173131231455,0.09454855195911414,1.1250423245117716,0.6318534852320092,0.7997497398817571,-1.0233772215014318,6.450865575756282,0.07157023489205856,0.8500145465030344,0.0,0,1,0.25880367193626036,0.24902334455788566,0.004498680092492703,0.11686979564231703,0.059589591959114147,0.2796923245117715,-2.488223221501432,0.9794835757562819
15,4.914639698231009,2.2168986666582233,0.9496509712105445,1.8523890045091918,0.5814577070833247,0.7625337416031664,3.0,4.0,4.4721360206604,0.5252822403066744,0.05617546677665031,0.09284497444633731,1.1566134639773282,0.6485174305492952,0.8675572440266134,-1.2637648711797032,7.550266963349408,0.6368695507363243,5.326810530921518,0.0,0,1,0.26432524091011667,0.24252120082883175,0.00457300739571061,0.08002037051007749,0.057886014446337314,0.3112634639773282,-2.7286108711797032,2.0788849633494078
16,4.976760319112036,2.2308653744930544,0.956902532084634,1.864615851543531,0.5843055893746447,0.7643988418192722,3.0,4.0,4.4721360206604,0.5252822403066744,0.059023349067970354,0.08603066439522998,1.063656865382626,0.7029467258520877,0.7952899743189897,-0.5360309519366353,6.3916733554839595,1.3365576309608829,0.7414410771269146,0.0,0,1,0.26939315416499676,0.26084853462192703,0.004663845798926014,0.13577682602915098,0.05107170439522998,0.2183068653826259,-2.000876951936635,0.9202913554839594
1 packet_index raw_power_code2 rms_full_iq_code mean_i mean_q ac_power_code2 ac_rms_code max_abs_i max_abs_q max_complex_magnitude background_ac_power_code2 background_subtracted_useful_power_code2 symbol_error_rate symbol_rms_deviation matched_component_power residual_power matched_residual_db band_gain_nonuniformity_db initial_frequency_hz diagnostic_residual_phase_error_rad local_delay_median_samples local_delay_min_samples local_delay_max_samples local_correlation_median local_correlation_min local_gain_amplitude_median local_phase_unwrapped_span_rad ser_minus_lab056_b evm_minus_lab056_b matched_residual_minus_lab056_b_db ripple_minus_lab056_b_db
2 1 4.900591831425598 2.2137280391740983 0.9692702913631633 1.8366285119667014 0.5879026427373475 0.7667480960115568 3.0 4.0 4.4721360206604 0.5252822403066744 0.06262040243067313 0.08517887563884156 1.088322316906538 0.7075133679013462 0.8380110003749788 -0.7351506962803888 6.642520146946069 1.0073017677042053 5.396055347590577 0.0 0 1 0.2720544529364392 0.2556440262627536 0.004692917533594935 0.120558278787813 0.05021991563884157 0.24297231690653787 -2.199996696280389 1.1711381469460687
3 2 4.865146982310094 2.2057078188894588 0.9677527748872702 1.8294528269164065 0.5817039030956508 0.7626951573831126 3.0 4.0 4.4721360206604 0.5252822403066744 0.05642166278897642 0.09795570698466781 1.104921348985033 0.6708739973434846 0.8190373162813612 -0.8666272994726886 6.598551357893342 1.6416990453424165 0.9116196756938657 0.0 0 1 0.2633530926845802 0.2539878786554866 0.0045493907778025216 0.0709144214354922 0.06299674698466781 0.25957134898503287 -2.3314732994726888 1.127169357893342
4 3 6.015186004162331 2.4525876139625127 0.9700940860215054 1.8342655220256676 1.7095734631363353 1.3075065824447445 6.0 7.0 7.211102485656738 0.5252822403066744 1.184291222829661 0.10221465076660988 1.3578439728375573 0.6181275875589448 1.1396667156434608 -2.6569973778482696 7.370968795797246 -0.9619877262845884 0.9174219316762064 0.0 0 1 0.2672883844824355 0.24083000237735547 0.004581545172098038 0.15725486354106955 0.06725569076660988 0.5124939728375573 -4.12184337784827 1.899586795797246
5 4 8.462127124523066 2.9089735517056643 0.9603494623655914 1.846362296219216 4.130802305757289 2.032437528131502 6.0 7.0 7.6157732009887695 0.5252822403066744 3.6055200654506145 0.15587734241908008 1.6634180909816034 0.694252592647496 1.920968976998595 -4.420028409350613 10.617549420778396 2.5845496302438504 5.388297118381418 0.0 0 0 0.2731302498054202 0.1663171407536924 0.004805263148615891 0.12094876972869106 0.12091838241908008 0.8180680909816034 -5.884874409350614 5.146167420778395
6 5 4.954615417967395 2.2258965425121167 0.9645117932708983 1.8537439299340963 0.5879658608412441 0.7667893197229889 3.0 4.0 4.242640495300293 0.5252822403066744 0.06268362053456977 0.08986371379897785 1.0991964913376657 0.7021817411712009 0.8483991001186207 -0.8215066687796163 6.409725568268307 -1.2358463102217572 0.8342172701371073 0.0 0 1 0.26644916295862675 0.2537591241878097 0.0046666418592819555 0.09866723940073996 0.05490475379897786 0.2538464913376657 -2.2863526687796165 0.9383435682683068
7 6 4.919647502601457 2.218027840808464 0.968934269857787 1.8444437218175511 0.5788412403444356 0.7608161672470135 3.0 4.0 4.4721360206604 0.5252822403066744 0.05355900003776126 0.075809199318569 1.1024024281507157 0.6444662106996041 0.783214058873921 -0.8468032228257232 6.3642932090088 -1.7795429995488667 5.318131944986163 0.0 0 1 0.2655258469985231 0.25666966629660665 0.004581829702937256 0.20674702332927808 0.040850239318569 0.2570524281507156 -2.3116492228257233 0.8929112090087994
8 7 4.958322493929934 2.226729102053039 0.9635145681581686 1.856150277488727 0.5846683182554333 0.7646360691567154 3.0 4.0 4.4721360206604 0.5252822403066744 0.05938607794875894 0.08390119250425894 1.1001519668540132 0.6819353341348239 0.8253697594999119 -0.8290535905764504 6.236828217134885 -0.2484094971075878 1.4617535496008514 0.0 0 1 0.266458697108116 0.24788848233138613 0.004627604818355622 0.11827169376376112 0.04894223250425894 0.25480196685401313 -2.2938995905764505 0.765446217134885
9 8 4.913306451612903 2.2165979454138505 0.9589186611168922 1.8453433922996878 0.5884892174705705 0.7671305087601265 3.0 4.0 4.4721360206604 0.5252822403066744 0.06320697716389612 0.08262350936967632 1.1492572709962479 0.6381478875618168 0.8428608001594871 -1.2083452015652267 6.714920606410644 -1.0783628659018663 0.78177232042639 0.0 0 1 0.26521123625627346 0.2568596341044175 0.004588048214156221 0.17639438146975883 0.04766454936967632 0.3039072709962478 -2.673191201565227 1.2435386064106435
10 9 4.8869558619493585 2.2106460281893523 0.9541276448144294 1.840042924037461 0.5908383370498989 0.7686600920107007 3.0 4.0 4.4721360206604 0.5252822403066744 0.06555609674322449 0.08943781942078365 1.141830995657666 0.6581222468886276 0.858045321706861 -1.1520365600725753 6.809131520732102 0.8322819250764986 1.0738651986809553 0.0 0 1 0.2629884708976966 0.2513843183766455 0.004577452828973017 0.13543041514325171 0.05447885942078365 0.29648099565766595 -2.6168825600725754 1.3377495207321015
11 10 4.915355098855359 2.2170600124614035 0.9478299514394728 1.850437911897329 0.5928530162226577 0.769969490449237 3.0 4.0 4.242640495300293 0.5252822403066744 0.06757077591598337 0.08347529812606473 1.0923957700987015 0.6971368095977797 0.8319132362097249 -0.7676001965024029 6.678161163217084 -1.3378733037888852 0.7703154441715622 0.0 0 1 0.26769649861033307 0.25301897115559957 0.004684343948400701 0.1578122760403755 0.048516338126064734 0.24704577009870143 -2.232446196502403 1.2067791632170835
12 11 4.919918487686438 2.218088926911281 0.9430389351370101 1.852898456468956 0.5973633645170526 0.7728928544869933 3.0 4.0 4.4721360206604 0.5252822403066744 0.07208112421037827 0.08049403747870527 1.0853439130113745 0.6882509611422404 0.8107399547939167 -0.7113474983787614 6.630624104636567 1.1396956047405093 0.8869440636679229 1.0 0 1 0.2677790176885852 0.24298761555141254 0.0046615184329749015 0.11596124244647732 0.04553507747870528 0.2399939130113744 -2.1761934983787614 1.1592421046365669
13 12 6.8007067291016305 2.607816467679739 0.9549947970863684 1.8480749219562955 2.4733107494758295 1.5726763015559908 6.0 7.0 8.062257766723633 0.5252822403066744 1.9480285091691552 0.12819420783645655 1.4566037803957919 0.6313306634190563 1.3394908423846723 -3.2668286553130113 7.945031576922354 -0.15870982770940278 1.0850946010670803 0.0 0 1 0.2691949358576327 0.2602069168691974 0.004654618220793532 0.10483842514826858 0.09323524783645655 0.6112537803957918 -4.731674655313011 2.4736495769223534
14 13 7.57159425945196 2.751653004913948 0.9523066250433576 1.8468283905653833 3.253931247152167 1.8038656399943336 6.0 7.0 7.810249328613281 0.5252822403066744 2.7286490068454925 0.16013628620102216 1.542471770787923 0.6706715317796331 1.5956745609431342 -3.764344492637608 9.871896166053979 -3.768747766207012 1.4778689507229945 0.0 0 1 0.25756193885232326 0.2383815900640343 0.004487614735363821 0.0618646152553739 0.12517732620102218 0.6971217707879229 -5.229190492637608 4.400514166053979
15 14 4.931039715574054 2.220594450946425 0.9521657127991675 1.8542859001040584 0.5860439716189889 0.7655350884309542 3.0 4.0 4.4721360206604 0.5252822403066744 0.06076173131231455 0.09454855195911414 1.1250423245117716 0.6318534852320092 0.7997497398817571 -1.0233772215014318 6.450865575756282 0.07157023489205856 0.8500145465030344 0.0 0 1 0.25880367193626036 0.24902334455788566 0.004498680092492703 0.11686979564231703 0.059589591959114147 0.2796923245117715 -2.488223221501432 0.9794835757562819
16 15 4.914639698231009 2.2168986666582233 0.9496509712105445 1.8523890045091918 0.5814577070833247 0.7625337416031664 3.0 4.0 4.4721360206604 0.5252822403066744 0.05617546677665031 0.09284497444633731 1.1566134639773282 0.6485174305492952 0.8675572440266134 -1.2637648711797032 7.550266963349408 0.6368695507363243 5.326810530921518 0.0 0 1 0.26432524091011667 0.24252120082883175 0.00457300739571061 0.08002037051007749 0.057886014446337314 0.3112634639773282 -2.7286108711797032 2.0788849633494078
17 16 4.976760319112036 2.2308653744930544 0.956902532084634 1.864615851543531 0.5843055893746447 0.7643988418192722 3.0 4.0 4.4721360206604 0.5252822403066744 0.059023349067970354 0.08603066439522998 1.063656865382626 0.7029467258520877 0.7952899743189897 -0.5360309519366353 6.3916733554839595 1.3365576309608829 0.7414410771269146 0.0 0 1 0.26939315416499676 0.26084853462192703 0.004663845798926014 0.13577682602915098 0.05107170439522998 0.2183068653826259 -2.000876951936635 0.9202913554839594

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -0,0 +1,951 @@
{
"lab": "Lab063",
"status": "COMPLETED_OFFLINE",
"rf_tx": 0,
"hardware_queries": 0,
"lab062_status_preserved": "RF_SESSION_INVALID_TX_UNDERRUN",
"lab062_commit": "f8ae6c6bfceaa21b6c08dcf55d2bff996dd0dae5",
"physical_device": "Auron HackRF Plus",
"api_firmware_identification": "HackRF One r9",
"integrity": {
"tx_sha256": "e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5",
"rx_sha256": "ce0bd603e4ca356af67d504ee11c9e9f38171f31c7427fbe61216a28126b2b32",
"tx_samples": 1476096,
"rx_samples": 24000000
},
"actual_inter_packet_gap": {
"tx_samples": 1476096,
"packets": 16,
"packet_waveform_samples": 92256,
"packet_product_samples": 1476096,
"identity_confirmed": true,
"additional_inter_packet_gap_samples": 0,
"additional_inter_packet_gap_seconds": 0.0,
"actual": "0 additional samples (no planned 5 ms gaps)",
"reason": "IMPLEMENTATION_OMISSION: prepare() writes the 16 complete packet waveforms back-to-back and has no gap parameter or zero-fill operation",
"packet_internal_note": "Each packet waveform still contains its own guards and RRC tails"
},
"tx_underrun_scale": {
"bytes": 16672,
"complex_samples": 8336,
"duration_seconds": 0.001042,
"duration_milliseconds": 1.042,
"symbols": 521.0,
"fraction_of_packet": 0.09035726673603885,
"percent_of_packet": 9.035726673603884,
"interpretation": "Scale only; RX does not prove that this many RF samples were lost or repeated"
},
"tx_underrun_log": {
"binary_path": "C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe",
"binary_exists": true,
"local_source_files": [],
"progress_line": "1 underruns, longest 16672 bytes",
"final_line": "0 underruns, longest 0 bytes",
"counter_semantics": "NOT_ESTABLISHED",
"note": "No local source or documentation was found that explains the reset between progress and final counters"
},
"background": {
"before": {
"raw_power_code2": 4.867889351370101,
"rms_full_iq_code": 2.2063293841514464,
"mean_i": 0.9631677072493929,
"mean_q": 1.8471644120707595,
"ac_power_code2": 0.5281809538613338,
"ac_rms_code": 0.7267605890947402,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.123105525970459
},
"after": {
"raw_power_code2": 4.852031304197017,
"rms_full_iq_code": 2.202732690136735,
"mean_i": 0.9442421089143254,
"mean_q": 1.8541991848768644,
"ac_power_code2": 0.5223835267520149,
"ac_rms_code": 0.7227610440194013,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604
},
"ac_power_code2_used": 0.5252822403066744,
"preflight_ac_rms_code": 0.9854828456229909
},
"local_alignment": {
"valid_windows": 221,
"total_windows": 359,
"minimum_correlation": 0.0716654800554192,
"median_correlation": 0.2655258469985231,
"maximum_correlation": 0.2873942479114494,
"delay_min_samples": 0,
"delay_median_samples": 0.0,
"delay_max_samples": 1,
"jump_candidates": [],
"local_delay_discontinuity": false,
"local_delay_discontinuity_scope": "NO_IN_221_RELIABLE_WINDOWS; UNDETERMINED_IN_22_INTERNAL_LOW_CORRELATION_WINDOWS",
"underrun_location": "NOT_LOCALIZED_FROM_RX",
"reliable_region_inside_packet_samples": [
24000,
86000
],
"correlation_threshold": 0.15,
"internal_low_correlation_windows": {
"count": 22,
"packet_counts": {
"3": 5,
"4": 7,
"12": 7,
"13": 3
},
"windows": [
{
"window_index": 62,
"packet_index": 3,
"tx_sample": 253952,
"rx_sample_selected_but_not_used_for_delay_verdict": 4510043,
"position_inside_packet_samples": 69440,
"normalized_correlation": 0.13153433429624267
},
{
"window_index": 63,
"packet_index": 3,
"tx_sample": 258048,
"rx_sample_selected_but_not_used_for_delay_verdict": 4514139,
"position_inside_packet_samples": 73536,
"normalized_correlation": 0.08888879507126439
},
{
"window_index": 64,
"packet_index": 3,
"tx_sample": 262144,
"rx_sample_selected_but_not_used_for_delay_verdict": 4518235,
"position_inside_packet_samples": 77632,
"normalized_correlation": 0.07990273751817419
},
{
"window_index": 65,
"packet_index": 3,
"tx_sample": 266240,
"rx_sample_selected_but_not_used_for_delay_verdict": 4522332,
"position_inside_packet_samples": 81728,
"normalized_correlation": 0.07824125225628915
},
{
"window_index": 66,
"packet_index": 3,
"tx_sample": 270336,
"rx_sample_selected_but_not_used_for_delay_verdict": 4526428,
"position_inside_packet_samples": 85824,
"normalized_correlation": 0.07587440188611191
},
{
"window_index": 74,
"packet_index": 4,
"tx_sample": 303104,
"rx_sample_selected_but_not_used_for_delay_verdict": 4559195,
"position_inside_packet_samples": 26336,
"normalized_correlation": 0.08726659571551212
},
{
"window_index": 75,
"packet_index": 4,
"tx_sample": 307200,
"rx_sample_selected_but_not_used_for_delay_verdict": 4563291,
"position_inside_packet_samples": 30432,
"normalized_correlation": 0.07303287114951702
},
{
"window_index": 76,
"packet_index": 4,
"tx_sample": 311296,
"rx_sample_selected_but_not_used_for_delay_verdict": 4567387,
"position_inside_packet_samples": 34528,
"normalized_correlation": 0.07923837125521409
},
{
"window_index": 77,
"packet_index": 4,
"tx_sample": 315392,
"rx_sample_selected_but_not_used_for_delay_verdict": 4571483,
"position_inside_packet_samples": 38624,
"normalized_correlation": 0.08766369642748506
},
{
"window_index": 78,
"packet_index": 4,
"tx_sample": 319488,
"rx_sample_selected_but_not_used_for_delay_verdict": 4575579,
"position_inside_packet_samples": 42720,
"normalized_correlation": 0.08111151553103035
},
{
"window_index": 79,
"packet_index": 4,
"tx_sample": 323584,
"rx_sample_selected_but_not_used_for_delay_verdict": 4579675,
"position_inside_packet_samples": 46816,
"normalized_correlation": 0.10671176630261674
},
{
"window_index": 81,
"packet_index": 4,
"tx_sample": 331776,
"rx_sample_selected_but_not_used_for_delay_verdict": 4587867,
"position_inside_packet_samples": 55008,
"normalized_correlation": 0.13566484987135102
},
{
"window_index": 262,
"packet_index": 12,
"tx_sample": 1073152,
"rx_sample_selected_but_not_used_for_delay_verdict": 5329243,
"position_inside_packet_samples": 58336,
"normalized_correlation": 0.12222192020312277
},
{
"window_index": 263,
"packet_index": 12,
"tx_sample": 1077248,
"rx_sample_selected_but_not_used_for_delay_verdict": 5333339,
"position_inside_packet_samples": 62432,
"normalized_correlation": 0.08371985216496043
},
{
"window_index": 264,
"packet_index": 12,
"tx_sample": 1081344,
"rx_sample_selected_but_not_used_for_delay_verdict": 5337436,
"position_inside_packet_samples": 66528,
"normalized_correlation": 0.07678297321464417
},
{
"window_index": 265,
"packet_index": 12,
"tx_sample": 1085440,
"rx_sample_selected_but_not_used_for_delay_verdict": 5341532,
"position_inside_packet_samples": 70624,
"normalized_correlation": 0.075825225755414
},
{
"window_index": 266,
"packet_index": 12,
"tx_sample": 1089536,
"rx_sample_selected_but_not_used_for_delay_verdict": 5345627,
"position_inside_packet_samples": 74720,
"normalized_correlation": 0.0777915075019332
},
{
"window_index": 267,
"packet_index": 12,
"tx_sample": 1093632,
"rx_sample_selected_but_not_used_for_delay_verdict": 5349723,
"position_inside_packet_samples": 78816,
"normalized_correlation": 0.0828610428066847
},
{
"window_index": 268,
"packet_index": 12,
"tx_sample": 1097728,
"rx_sample_selected_but_not_used_for_delay_verdict": 5353821,
"position_inside_packet_samples": 82912,
"normalized_correlation": 0.08195769883417732
},
{
"window_index": 277,
"packet_index": 13,
"tx_sample": 1134592,
"rx_sample_selected_but_not_used_for_delay_verdict": 5390682,
"position_inside_packet_samples": 27520,
"normalized_correlation": 0.08301430893626999
},
{
"window_index": 278,
"packet_index": 13,
"tx_sample": 1138688,
"rx_sample_selected_but_not_used_for_delay_verdict": 5394779,
"position_inside_packet_samples": 31616,
"normalized_correlation": 0.07878097899540573
},
{
"window_index": 279,
"packet_index": 13,
"tx_sample": 1142784,
"rx_sample_selected_but_not_used_for_delay_verdict": 5398876,
"position_inside_packet_samples": 35712,
"normalized_correlation": 0.09576023729412096
}
],
"interpretation": "Delay is not established in these windows; low correlation is itself a local anomaly, but it does not identify an underrun without a reliable timing discontinuity"
},
"excluded_region_reason": "Packet edges and repeated PRBS preamble have correlation aliases spaced by 2032 samples; 22 additional internal windows are below the 0.15 correlation threshold. All are retained in CSV, and delay is not asserted for any excluded window"
},
"packet_quality": [
{
"packet_index": 1,
"raw_power_code2": 4.900591831425598,
"rms_full_iq_code": 2.2137280391740983,
"mean_i": 0.9692702913631633,
"mean_q": 1.8366285119667014,
"ac_power_code2": 0.5879026427373475,
"ac_rms_code": 0.7667480960115568,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.06262040243067313,
"symbol_error_rate": 0.08517887563884156,
"symbol_rms_deviation": 1.088322316906538,
"matched_component_power": 0.7075133679013462,
"residual_power": 0.8380110003749788,
"matched_residual_db": -0.7351506962803888,
"band_gain_nonuniformity_db": 6.642520146946069,
"initial_frequency_hz": 1.0073017677042053,
"diagnostic_residual_phase_error_rad": 5.396055347590577,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.2720544529364392,
"local_correlation_min": 0.2556440262627536,
"local_gain_amplitude_median": 0.004692917533594935,
"local_phase_unwrapped_span_rad": 0.120558278787813,
"ser_minus_lab056_b": 0.05021991563884157,
"evm_minus_lab056_b": 0.24297231690653787,
"matched_residual_minus_lab056_b_db": -2.199996696280389,
"ripple_minus_lab056_b_db": 1.1711381469460687
},
{
"packet_index": 2,
"raw_power_code2": 4.865146982310094,
"rms_full_iq_code": 2.2057078188894588,
"mean_i": 0.9677527748872702,
"mean_q": 1.8294528269164065,
"ac_power_code2": 0.5817039030956508,
"ac_rms_code": 0.7626951573831126,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.05642166278897642,
"symbol_error_rate": 0.09795570698466781,
"symbol_rms_deviation": 1.104921348985033,
"matched_component_power": 0.6708739973434846,
"residual_power": 0.8190373162813612,
"matched_residual_db": -0.8666272994726886,
"band_gain_nonuniformity_db": 6.598551357893342,
"initial_frequency_hz": 1.6416990453424165,
"diagnostic_residual_phase_error_rad": 0.9116196756938657,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.2633530926845802,
"local_correlation_min": 0.2539878786554866,
"local_gain_amplitude_median": 0.0045493907778025216,
"local_phase_unwrapped_span_rad": 0.0709144214354922,
"ser_minus_lab056_b": 0.06299674698466781,
"evm_minus_lab056_b": 0.25957134898503287,
"matched_residual_minus_lab056_b_db": -2.3314732994726888,
"ripple_minus_lab056_b_db": 1.127169357893342
},
{
"packet_index": 3,
"raw_power_code2": 6.015186004162331,
"rms_full_iq_code": 2.4525876139625127,
"mean_i": 0.9700940860215054,
"mean_q": 1.8342655220256676,
"ac_power_code2": 1.7095734631363353,
"ac_rms_code": 1.3075065824447445,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"max_complex_magnitude": 7.211102485656738,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 1.184291222829661,
"symbol_error_rate": 0.10221465076660988,
"symbol_rms_deviation": 1.3578439728375573,
"matched_component_power": 0.6181275875589448,
"residual_power": 1.1396667156434608,
"matched_residual_db": -2.6569973778482696,
"band_gain_nonuniformity_db": 7.370968795797246,
"initial_frequency_hz": -0.9619877262845884,
"diagnostic_residual_phase_error_rad": 0.9174219316762064,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.2672883844824355,
"local_correlation_min": 0.24083000237735547,
"local_gain_amplitude_median": 0.004581545172098038,
"local_phase_unwrapped_span_rad": 0.15725486354106955,
"ser_minus_lab056_b": 0.06725569076660988,
"evm_minus_lab056_b": 0.5124939728375573,
"matched_residual_minus_lab056_b_db": -4.12184337784827,
"ripple_minus_lab056_b_db": 1.899586795797246
},
{
"packet_index": 4,
"raw_power_code2": 8.462127124523066,
"rms_full_iq_code": 2.9089735517056643,
"mean_i": 0.9603494623655914,
"mean_q": 1.846362296219216,
"ac_power_code2": 4.130802305757289,
"ac_rms_code": 2.032437528131502,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"max_complex_magnitude": 7.6157732009887695,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 3.6055200654506145,
"symbol_error_rate": 0.15587734241908008,
"symbol_rms_deviation": 1.6634180909816034,
"matched_component_power": 0.694252592647496,
"residual_power": 1.920968976998595,
"matched_residual_db": -4.420028409350613,
"band_gain_nonuniformity_db": 10.617549420778396,
"initial_frequency_hz": 2.5845496302438504,
"diagnostic_residual_phase_error_rad": 5.388297118381418,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 0,
"local_correlation_median": 0.2731302498054202,
"local_correlation_min": 0.1663171407536924,
"local_gain_amplitude_median": 0.004805263148615891,
"local_phase_unwrapped_span_rad": 0.12094876972869106,
"ser_minus_lab056_b": 0.12091838241908008,
"evm_minus_lab056_b": 0.8180680909816034,
"matched_residual_minus_lab056_b_db": -5.884874409350614,
"ripple_minus_lab056_b_db": 5.146167420778395
},
{
"packet_index": 5,
"raw_power_code2": 4.954615417967395,
"rms_full_iq_code": 2.2258965425121167,
"mean_i": 0.9645117932708983,
"mean_q": 1.8537439299340963,
"ac_power_code2": 0.5879658608412441,
"ac_rms_code": 0.7667893197229889,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.242640495300293,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.06268362053456977,
"symbol_error_rate": 0.08986371379897785,
"symbol_rms_deviation": 1.0991964913376657,
"matched_component_power": 0.7021817411712009,
"residual_power": 0.8483991001186207,
"matched_residual_db": -0.8215066687796163,
"band_gain_nonuniformity_db": 6.409725568268307,
"initial_frequency_hz": -1.2358463102217572,
"diagnostic_residual_phase_error_rad": 0.8342172701371073,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.26644916295862675,
"local_correlation_min": 0.2537591241878097,
"local_gain_amplitude_median": 0.0046666418592819555,
"local_phase_unwrapped_span_rad": 0.09866723940073996,
"ser_minus_lab056_b": 0.05490475379897786,
"evm_minus_lab056_b": 0.2538464913376657,
"matched_residual_minus_lab056_b_db": -2.2863526687796165,
"ripple_minus_lab056_b_db": 0.9383435682683068
},
{
"packet_index": 6,
"raw_power_code2": 4.919647502601457,
"rms_full_iq_code": 2.218027840808464,
"mean_i": 0.968934269857787,
"mean_q": 1.8444437218175511,
"ac_power_code2": 0.5788412403444356,
"ac_rms_code": 0.7608161672470135,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.05355900003776126,
"symbol_error_rate": 0.075809199318569,
"symbol_rms_deviation": 1.1024024281507157,
"matched_component_power": 0.6444662106996041,
"residual_power": 0.783214058873921,
"matched_residual_db": -0.8468032228257232,
"band_gain_nonuniformity_db": 6.3642932090088,
"initial_frequency_hz": -1.7795429995488667,
"diagnostic_residual_phase_error_rad": 5.318131944986163,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.2655258469985231,
"local_correlation_min": 0.25666966629660665,
"local_gain_amplitude_median": 0.004581829702937256,
"local_phase_unwrapped_span_rad": 0.20674702332927808,
"ser_minus_lab056_b": 0.040850239318569,
"evm_minus_lab056_b": 0.2570524281507156,
"matched_residual_minus_lab056_b_db": -2.3116492228257233,
"ripple_minus_lab056_b_db": 0.8929112090087994
},
{
"packet_index": 7,
"raw_power_code2": 4.958322493929934,
"rms_full_iq_code": 2.226729102053039,
"mean_i": 0.9635145681581686,
"mean_q": 1.856150277488727,
"ac_power_code2": 0.5846683182554333,
"ac_rms_code": 0.7646360691567154,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.05938607794875894,
"symbol_error_rate": 0.08390119250425894,
"symbol_rms_deviation": 1.1001519668540132,
"matched_component_power": 0.6819353341348239,
"residual_power": 0.8253697594999119,
"matched_residual_db": -0.8290535905764504,
"band_gain_nonuniformity_db": 6.236828217134885,
"initial_frequency_hz": -0.2484094971075878,
"diagnostic_residual_phase_error_rad": 1.4617535496008514,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.266458697108116,
"local_correlation_min": 0.24788848233138613,
"local_gain_amplitude_median": 0.004627604818355622,
"local_phase_unwrapped_span_rad": 0.11827169376376112,
"ser_minus_lab056_b": 0.04894223250425894,
"evm_minus_lab056_b": 0.25480196685401313,
"matched_residual_minus_lab056_b_db": -2.2938995905764505,
"ripple_minus_lab056_b_db": 0.765446217134885
},
{
"packet_index": 8,
"raw_power_code2": 4.913306451612903,
"rms_full_iq_code": 2.2165979454138505,
"mean_i": 0.9589186611168922,
"mean_q": 1.8453433922996878,
"ac_power_code2": 0.5884892174705705,
"ac_rms_code": 0.7671305087601265,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.06320697716389612,
"symbol_error_rate": 0.08262350936967632,
"symbol_rms_deviation": 1.1492572709962479,
"matched_component_power": 0.6381478875618168,
"residual_power": 0.8428608001594871,
"matched_residual_db": -1.2083452015652267,
"band_gain_nonuniformity_db": 6.714920606410644,
"initial_frequency_hz": -1.0783628659018663,
"diagnostic_residual_phase_error_rad": 0.78177232042639,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.26521123625627346,
"local_correlation_min": 0.2568596341044175,
"local_gain_amplitude_median": 0.004588048214156221,
"local_phase_unwrapped_span_rad": 0.17639438146975883,
"ser_minus_lab056_b": 0.04766454936967632,
"evm_minus_lab056_b": 0.3039072709962478,
"matched_residual_minus_lab056_b_db": -2.673191201565227,
"ripple_minus_lab056_b_db": 1.2435386064106435
},
{
"packet_index": 9,
"raw_power_code2": 4.8869558619493585,
"rms_full_iq_code": 2.2106460281893523,
"mean_i": 0.9541276448144294,
"mean_q": 1.840042924037461,
"ac_power_code2": 0.5908383370498989,
"ac_rms_code": 0.7686600920107007,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.06555609674322449,
"symbol_error_rate": 0.08943781942078365,
"symbol_rms_deviation": 1.141830995657666,
"matched_component_power": 0.6581222468886276,
"residual_power": 0.858045321706861,
"matched_residual_db": -1.1520365600725753,
"band_gain_nonuniformity_db": 6.809131520732102,
"initial_frequency_hz": 0.8322819250764986,
"diagnostic_residual_phase_error_rad": 1.0738651986809553,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.2629884708976966,
"local_correlation_min": 0.2513843183766455,
"local_gain_amplitude_median": 0.004577452828973017,
"local_phase_unwrapped_span_rad": 0.13543041514325171,
"ser_minus_lab056_b": 0.05447885942078365,
"evm_minus_lab056_b": 0.29648099565766595,
"matched_residual_minus_lab056_b_db": -2.6168825600725754,
"ripple_minus_lab056_b_db": 1.3377495207321015
},
{
"packet_index": 10,
"raw_power_code2": 4.915355098855359,
"rms_full_iq_code": 2.2170600124614035,
"mean_i": 0.9478299514394728,
"mean_q": 1.850437911897329,
"ac_power_code2": 0.5928530162226577,
"ac_rms_code": 0.769969490449237,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.242640495300293,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.06757077591598337,
"symbol_error_rate": 0.08347529812606473,
"symbol_rms_deviation": 1.0923957700987015,
"matched_component_power": 0.6971368095977797,
"residual_power": 0.8319132362097249,
"matched_residual_db": -0.7676001965024029,
"band_gain_nonuniformity_db": 6.678161163217084,
"initial_frequency_hz": -1.3378733037888852,
"diagnostic_residual_phase_error_rad": 0.7703154441715622,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.26769649861033307,
"local_correlation_min": 0.25301897115559957,
"local_gain_amplitude_median": 0.004684343948400701,
"local_phase_unwrapped_span_rad": 0.1578122760403755,
"ser_minus_lab056_b": 0.048516338126064734,
"evm_minus_lab056_b": 0.24704577009870143,
"matched_residual_minus_lab056_b_db": -2.232446196502403,
"ripple_minus_lab056_b_db": 1.2067791632170835
},
{
"packet_index": 11,
"raw_power_code2": 4.919918487686438,
"rms_full_iq_code": 2.218088926911281,
"mean_i": 0.9430389351370101,
"mean_q": 1.852898456468956,
"ac_power_code2": 0.5973633645170526,
"ac_rms_code": 0.7728928544869933,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.07208112421037827,
"symbol_error_rate": 0.08049403747870527,
"symbol_rms_deviation": 1.0853439130113745,
"matched_component_power": 0.6882509611422404,
"residual_power": 0.8107399547939167,
"matched_residual_db": -0.7113474983787614,
"band_gain_nonuniformity_db": 6.630624104636567,
"initial_frequency_hz": 1.1396956047405093,
"diagnostic_residual_phase_error_rad": 0.8869440636679229,
"local_delay_median_samples": 1.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.2677790176885852,
"local_correlation_min": 0.24298761555141254,
"local_gain_amplitude_median": 0.0046615184329749015,
"local_phase_unwrapped_span_rad": 0.11596124244647732,
"ser_minus_lab056_b": 0.04553507747870528,
"evm_minus_lab056_b": 0.2399939130113744,
"matched_residual_minus_lab056_b_db": -2.1761934983787614,
"ripple_minus_lab056_b_db": 1.1592421046365669
},
{
"packet_index": 12,
"raw_power_code2": 6.8007067291016305,
"rms_full_iq_code": 2.607816467679739,
"mean_i": 0.9549947970863684,
"mean_q": 1.8480749219562955,
"ac_power_code2": 2.4733107494758295,
"ac_rms_code": 1.5726763015559908,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"max_complex_magnitude": 8.062257766723633,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 1.9480285091691552,
"symbol_error_rate": 0.12819420783645655,
"symbol_rms_deviation": 1.4566037803957919,
"matched_component_power": 0.6313306634190563,
"residual_power": 1.3394908423846723,
"matched_residual_db": -3.2668286553130113,
"band_gain_nonuniformity_db": 7.945031576922354,
"initial_frequency_hz": -0.15870982770940278,
"diagnostic_residual_phase_error_rad": 1.0850946010670803,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.2691949358576327,
"local_correlation_min": 0.2602069168691974,
"local_gain_amplitude_median": 0.004654618220793532,
"local_phase_unwrapped_span_rad": 0.10483842514826858,
"ser_minus_lab056_b": 0.09323524783645655,
"evm_minus_lab056_b": 0.6112537803957918,
"matched_residual_minus_lab056_b_db": -4.731674655313011,
"ripple_minus_lab056_b_db": 2.4736495769223534
},
{
"packet_index": 13,
"raw_power_code2": 7.57159425945196,
"rms_full_iq_code": 2.751653004913948,
"mean_i": 0.9523066250433576,
"mean_q": 1.8468283905653833,
"ac_power_code2": 3.253931247152167,
"ac_rms_code": 1.8038656399943336,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"max_complex_magnitude": 7.810249328613281,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 2.7286490068454925,
"symbol_error_rate": 0.16013628620102216,
"symbol_rms_deviation": 1.542471770787923,
"matched_component_power": 0.6706715317796331,
"residual_power": 1.5956745609431342,
"matched_residual_db": -3.764344492637608,
"band_gain_nonuniformity_db": 9.871896166053979,
"initial_frequency_hz": -3.768747766207012,
"diagnostic_residual_phase_error_rad": 1.4778689507229945,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.25756193885232326,
"local_correlation_min": 0.2383815900640343,
"local_gain_amplitude_median": 0.004487614735363821,
"local_phase_unwrapped_span_rad": 0.0618646152553739,
"ser_minus_lab056_b": 0.12517732620102218,
"evm_minus_lab056_b": 0.6971217707879229,
"matched_residual_minus_lab056_b_db": -5.229190492637608,
"ripple_minus_lab056_b_db": 4.400514166053979
},
{
"packet_index": 14,
"raw_power_code2": 4.931039715574054,
"rms_full_iq_code": 2.220594450946425,
"mean_i": 0.9521657127991675,
"mean_q": 1.8542859001040584,
"ac_power_code2": 0.5860439716189889,
"ac_rms_code": 0.7655350884309542,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.06076173131231455,
"symbol_error_rate": 0.09454855195911414,
"symbol_rms_deviation": 1.1250423245117716,
"matched_component_power": 0.6318534852320092,
"residual_power": 0.7997497398817571,
"matched_residual_db": -1.0233772215014318,
"band_gain_nonuniformity_db": 6.450865575756282,
"initial_frequency_hz": 0.07157023489205856,
"diagnostic_residual_phase_error_rad": 0.8500145465030344,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.25880367193626036,
"local_correlation_min": 0.24902334455788566,
"local_gain_amplitude_median": 0.004498680092492703,
"local_phase_unwrapped_span_rad": 0.11686979564231703,
"ser_minus_lab056_b": 0.059589591959114147,
"evm_minus_lab056_b": 0.2796923245117715,
"matched_residual_minus_lab056_b_db": -2.488223221501432,
"ripple_minus_lab056_b_db": 0.9794835757562819
},
{
"packet_index": 15,
"raw_power_code2": 4.914639698231009,
"rms_full_iq_code": 2.2168986666582233,
"mean_i": 0.9496509712105445,
"mean_q": 1.8523890045091918,
"ac_power_code2": 0.5814577070833247,
"ac_rms_code": 0.7625337416031664,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.05617546677665031,
"symbol_error_rate": 0.09284497444633731,
"symbol_rms_deviation": 1.1566134639773282,
"matched_component_power": 0.6485174305492952,
"residual_power": 0.8675572440266134,
"matched_residual_db": -1.2637648711797032,
"band_gain_nonuniformity_db": 7.550266963349408,
"initial_frequency_hz": 0.6368695507363243,
"diagnostic_residual_phase_error_rad": 5.326810530921518,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.26432524091011667,
"local_correlation_min": 0.24252120082883175,
"local_gain_amplitude_median": 0.00457300739571061,
"local_phase_unwrapped_span_rad": 0.08002037051007749,
"ser_minus_lab056_b": 0.057886014446337314,
"evm_minus_lab056_b": 0.3112634639773282,
"matched_residual_minus_lab056_b_db": -2.7286108711797032,
"ripple_minus_lab056_b_db": 2.0788849633494078
},
{
"packet_index": 16,
"raw_power_code2": 4.976760319112036,
"rms_full_iq_code": 2.2308653744930544,
"mean_i": 0.956902532084634,
"mean_q": 1.864615851543531,
"ac_power_code2": 0.5843055893746447,
"ac_rms_code": 0.7643988418192722,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"max_complex_magnitude": 4.4721360206604,
"background_ac_power_code2": 0.5252822403066744,
"background_subtracted_useful_power_code2": 0.059023349067970354,
"symbol_error_rate": 0.08603066439522998,
"symbol_rms_deviation": 1.063656865382626,
"matched_component_power": 0.7029467258520877,
"residual_power": 0.7952899743189897,
"matched_residual_db": -0.5360309519366353,
"band_gain_nonuniformity_db": 6.3916733554839595,
"initial_frequency_hz": 1.3365576309608829,
"diagnostic_residual_phase_error_rad": 0.7414410771269146,
"local_delay_median_samples": 0.0,
"local_delay_min_samples": 0,
"local_delay_max_samples": 1,
"local_correlation_median": 0.26939315416499676,
"local_correlation_min": 0.26084853462192703,
"local_gain_amplitude_median": 0.004663845798926014,
"local_phase_unwrapped_span_rad": 0.13577682602915098,
"ser_minus_lab056_b": 0.05107170439522998,
"evm_minus_lab056_b": 0.2183068653826259,
"matched_residual_minus_lab056_b_db": -2.000876951936635,
"ripple_minus_lab056_b_db": 0.9202913554839594
}
],
"group_trends": [
{
"packets": "1-4",
"useful_power_mean": 1.2272133383749813,
"symbol_error_rate_mean": 0.11030664395229983,
"symbol_rms_deviation_mean": 1.303626432427683,
"matched_component_power_mean": 0.672691886362818,
"residual_power_mean": 1.179421002324599,
"matched_residual_db_mean": -2.16970094573799,
"initial_frequency_hz_mean": 1.067890679251471,
"diagnostic_residual_phase_error_rad_mean": 3.153348518335517,
"local_phase_unwrapped_span_rad_mean": 0.11741908337326645,
"local_gain_amplitude_median": 0.004637231352846487
},
{
"packets": "5-8",
"useful_power_mean": 0.05970891892124652,
"symbol_error_rate_mean": 0.08304940374787052,
"symbol_rms_deviation_mean": 1.1127520393346606,
"matched_component_power_mean": 0.6666827933918614,
"residual_power_mean": 0.8249609296629852,
"matched_residual_db_mean": -0.9264271709367542,
"initial_frequency_hz_mean": -1.0855404181950195,
"diagnostic_residual_phase_error_rad_mean": 2.0989687712876277,
"local_phase_unwrapped_span_rad_mean": 0.1500200844908845,
"local_gain_amplitude_median": 0.004607826516255922
},
{
"packets": "9-12",
"useful_power_mean": 0.5383091265096853,
"symbol_error_rate_mean": 0.09540034071550255,
"symbol_rms_deviation_mean": 1.1940436147908833,
"matched_component_power_mean": 0.668710170261926,
"residual_power_mean": 0.9600473387737937,
"matched_residual_db_mean": -1.4744532275666877,
"initial_frequency_hz_mean": 0.11884859957967997,
"diagnostic_residual_phase_error_rad_mean": 0.9540548268968803,
"local_phase_unwrapped_span_rad_mean": 0.12851058969459328,
"local_gain_amplitude_median": 0.004658068326884217
},
{
"packets": "13-16",
"useful_power_mean": 0.7261523885006069,
"symbol_error_rate_mean": 0.10839011925042591,
"symbol_rms_deviation_mean": 1.2219461061649122,
"matched_component_power_mean": 0.6634972933532564,
"residual_power_mean": 1.0145678797926236,
"matched_residual_db_mean": -1.6468793843138447,
"initial_frequency_hz_mean": -0.4309375874044365,
"diagnostic_residual_phase_error_rad_mean": 2.0990337763186155,
"local_phase_unwrapped_span_rad_mean": 0.09863290185922985,
"local_gain_amplitude_median": 0.0045358437441016565
}
],
"special_packets_3_4_12_14": {
"packets": [
3,
4,
12,
14
],
"all_have_power_drop_below_median": false,
"all_have_correlation_below_median": false,
"all_have_large_delay_change": false,
"interpretation": "No common underrun signature unless one of all three booleans is true with localized alignment evidence"
},
"packets_most_affected": [
13,
4,
12,
3
],
"active_rx_level": {
"ac_rms_min": 0.7608161672470135,
"ac_rms_max": 2.032437528131502,
"max_abs_i_min": 3.0,
"max_abs_i_max": 6.0,
"max_abs_q_min": 4.0,
"max_abs_q_max": 7.0,
"mean_i_min": 0.9430389351370101,
"mean_i_max": 0.9700940860215054,
"mean_q_min": 1.8294528269164065,
"mean_q_max": 1.864615851543531,
"local_gain_amplitude_median_min": 0.004487614735363821,
"local_gain_amplitude_median_max": 0.004805263148615891,
"analog_overload": "LESS_LIKELY_FROM_DIGITAL_LEVEL_BUT_NOT_EXCLUDED_WITHOUT_INSTRUMENT"
},
"lab056_comparison": {
"reference": {
"symbol_error_rate": 0.03495896,
"evm_rms": 0.84535,
"matched_residual_db": 1.464846,
"band_ripple_db": 5.471382
},
"packets_worse_on_all_three_core_metrics": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16
]
},
"quality_distribution": "GLOBAL",
"primary_cause_status": "PARTIALLY_LOCALIZED",
"packets_worse_than_lab056_on_ser_evm_and_matched_residual": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16
],
"global_degradation_rule": "at least 12/16 packets worse than Lab056 B on SER, EVM and matched/residual",
"global_degradation": true,
"local_delay_discontinuity": false,
"next_single_step": "Before another TX, investigate the low active RX level, gain/geometry and possible analogue compression; also change TX streaming/logging so any underrun is unambiguous. Do not change RF parameters yet.",
"lab063_commit": "NOT_PERFORMED",
"push": "NOT_PERFORMED",
"lab064": "NOT_CREATED"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,230 @@
{
"lab": "Lab064",
"stage": "SINGLE_RF_LEVEL_CAPTURE",
"passed": true,
"rf_tx_count": 1,
"automatic_tx_repeats": 0,
"point": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 20000,
"samples_per_symbol": 400,
"digital_carrier_hz": 50000,
"rrc_rolloff": 0.35,
"rrc_span_symbols": 10,
"prbs": "PRBS7 x^7+x^6+1, deterministic initial state",
"full_phy_packet": false,
"tx_vga_db": 10,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN",
"levels_db_relative_nominal": [
-18.0,
-12.0,
-6.0,
0.0
]
},
"tx_sha256": "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9",
"process_before": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 333,
"errors": []
}
]
},
"inventory": {
"passed": true,
"serials": [
"000000000000000097c063dc2e5327d3",
"000000000000000097c063dc323b97d3"
],
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3",
"raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One"
},
"clock": {
"passed": true,
"master_reg29": 38,
"slave_reg29": 38,
"slave_clkin_status": "DETECTED",
"slave_clock_wait": {
"state": "DETECTED",
"queries": 2,
"time_to_detect_ms": 139.0420999377966,
"elapsed_ms": 139.0420999377966,
"polls": [
{
"query": 1,
"start_ms": 50.13589980080724,
"end_ms": 67.04779993742704,
"raw": "CLKIN status: no clock signal detected",
"state": "NOT_DETECTED",
"exit_code": 0
},
{
"query": 2,
"start_ms": 117.27159982547164,
"end_ms": 139.0420999377966,
"raw": "CLKIN status: clock signal detected",
"state": "DETECTED",
"exit_code": 0
}
]
},
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3"
},
"rx_level_before_tx": {
"samples": 65536,
"mean_i": 0.9547576904296875,
"mean_q": 1.83575439453125,
"power_code2": 4.8329315185546875,
"ac_power_code2": 0.5513750740792602,
"rms_code": 2.1983929399801774,
"peak_magnitude_code": 4.242640687119285,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 5.710618637663133,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION"
},
"tx_process": {
"returncode": 0,
"stdout_file": "tx_stdout.txt",
"stderr_file": "tx_stderr.txt"
},
"tx_counter_summary": {
"expected_kind": "underrun",
"observations": [
{
"count": 0,
"role": "UNKNOWN",
"kind": "underrun",
"text": "0 underruns",
"character_offset": 337
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "underrun",
"text": "0 underruns",
"character_offset": 509
}
],
"selected_counts": [
0,
0
],
"final_count": 0,
"maximum_count": 0,
"unparsed_loss_text": false,
"clean": true
},
"rx_samples": 16000000,
"rx_bytes": 32000000,
"rx_duration_seconds": 2.0,
"rx_counter_summary": {
"expected_kind": "overrun",
"observations": [
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 336
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 458
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 580
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 751
}
],
"selected_counts": [
0,
0,
0,
0
],
"final_count": 0,
"maximum_count": 0,
"unparsed_loss_text": false,
"clean": true
},
"rx_sha256": "02015891948aaee52ff81e60fdfeb391bb9b76cd9192b75972b8fedbc8690d86",
"rx_level": {
"samples": 16000000,
"mean_i": 0.9548163125,
"mean_q": 1.83674125,
"power_code2": 5.2568038125,
"ac_power_code2": 0.9715112024323407,
"rms_code": 2.2927720803647276,
"peak_magnitude_code": 8.602325267042627,
"max_abs_i": 7.0,
"max_abs_q": 8.0,
"papr_db": 11.485099505760791,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION"
},
"rx_clipping": false,
"process_after": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 333,
"errors": []
}
]
},
"cleanup_errors": []
}

View File

@@ -0,0 +1,164 @@
{
"lab": "Lab064",
"stage": "COMMON_CLOCK_AND_RX_ONLY_PREFLIGHT",
"passed": true,
"rf_tx_count": 0,
"stop_before_tx": true,
"point": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 20000,
"samples_per_symbol": 400,
"digital_carrier_hz": 50000,
"rrc_rolloff": 0.35,
"rrc_span_symbols": 10,
"prbs": "PRBS7 x^7+x^6+1, deterministic initial state",
"full_phy_packet": false,
"tx_vga_db": 10,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN",
"levels_db_relative_nominal": [
-18.0,
-12.0,
-6.0,
0.0
]
},
"tx_sha256": "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9",
"process_before": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 329,
"errors": []
}
]
},
"inventory": {
"passed": true,
"serials": [
"000000000000000097c063dc2e5327d3",
"000000000000000097c063dc323b97d3"
],
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3",
"raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One"
},
"clock": {
"passed": true,
"master_reg29": 38,
"slave_reg29": 38,
"slave_clkin_status": "DETECTED",
"slave_clock_wait": {
"state": "DETECTED",
"queries": 1,
"time_to_detect_ms": 66.79299985989928,
"elapsed_ms": 66.79299985989928,
"polls": [
{
"query": 1,
"start_ms": 50.07890006527305,
"end_ms": 66.79299985989928,
"raw": "CLKIN status: clock signal detected",
"state": "DETECTED",
"exit_code": 0
}
]
},
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3"
},
"rx_process": {
"returncode": 0,
"stdout": "",
"stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 800000/0Mio\nStop with Ctrl-C\n 1.8 MiB / 0.117 sec = 15.6 MiB/second, average power -35.3 dBfs, 9792 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.11842 s\nhackrf_stop_rx() done\nTransfer statistics:\n1892448 bytes transferred by M0\n1867776 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n"
},
"rx_counter_summary": {
"expected_kind": "overrun",
"observations": [
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 333
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 502
}
],
"selected_counts": [
0,
0
],
"final_count": 0,
"maximum_count": 0,
"unparsed_loss_text": false,
"clean": true
},
"rx_level": {
"samples": 800000,
"mean_i": 0.9337375,
"mean_q": 1.80165,
"power_code2": 4.810095,
"ac_power_code2": 0.6922865585937501,
"rms_code": 2.1931928779749397,
"peak_magnitude_code": 5.385164807134504,
"max_abs_i": 4.0,
"max_abs_q": 5.0,
"papr_db": 7.802443440680863,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION",
"symbol_energy": "NOT_APPLICABLE_TO_BACKGROUND",
"ac_rms_code": 0.8320375944593791,
"unexpected_strong_signal": false,
"strong_signal_rule": "AC RMS >= 20.0 code or max |I|/|Q| >= 100.0 code"
},
"rx_sha256": "02d87adcbb621027290a77d5f8fd3190c299d13e89f887cd294d4af352a6ef52",
"rx_overruns": 0,
"process_after": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 329,
"errors": []
}
]
},
"cleanup_errors": []
}

View File

@@ -0,0 +1,221 @@
{
"lab": "Lab064",
"stage": "PREPARATION_ONLY",
"rf_tx_count": 0,
"head": "4437917465274257ff0ca5d3c269029da45de3ec",
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 20000,
"samples_per_symbol": 400,
"digital_carrier_hz": 50000,
"rrc_rolloff": 0.35,
"rrc_span_symbols": 10,
"prbs": "PRBS7 x^7+x^6+1, deterministic initial state",
"full_phy_packet": false,
"tx_vga_db": 10,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN",
"levels_db_relative_nominal": [
-18.0,
-12.0,
-6.0,
0.0
]
},
"segments": [
{
"label": "L0",
"level_db": -18.0,
"start_sample": 800000,
"samples": 800000,
"duration_seconds": 0.1,
"analysis_start_sample": 808400,
"analysis_samples": 783200,
"metrics": {
"samples": 800000,
"mean_i": -9.625e-05,
"mean_q": 2.75e-05,
"power_code2": 30.87065625,
"ac_power_code2": 30.870656239979688,
"rms_code": 5.556136809870686,
"peak_magnitude_code": 9.219544457292887,
"max_abs_i": 9.0,
"max_abs_q": 9.0,
"papr_db": 4.398730638796093,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0015435328125,
"requested_relative_power_db": -18.0,
"tx_rms_code": 5.556136809870686,
"tx_peak_abs_i_code": 9.0,
"tx_peak_abs_q_code": 9.0,
"tx_peak_magnitude_code": 9.219544457292887,
"digital_clipping": false,
"actual_relative_power_db": -17.97368512020099
}
},
{
"label": "L1",
"level_db": -12.0,
"start_sample": 2000000,
"samples": 800000,
"duration_seconds": 0.1,
"analysis_start_sample": 2008400,
"analysis_samples": 783200,
"metrics": {
"samples": 800000,
"mean_i": -5e-05,
"mean_q": 5e-05,
"power_code2": 122.2567675,
"ac_power_code2": 122.25676749499999,
"rms_code": 11.056978226441435,
"peak_magnitude_code": 17.804493814764857,
"max_abs_i": 17.0,
"max_abs_q": 17.0,
"papr_db": 4.1378635346865025,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.006112838375,
"requested_relative_power_db": -12.0,
"tx_rms_code": 11.056978226441435,
"tx_peak_abs_i_code": 17.0,
"tx_peak_abs_q_code": 17.0,
"tx_peak_magnitude_code": 17.804493814764857,
"digital_clipping": false,
"actual_relative_power_db": -11.99641465105681
},
"tx_input_difference_from_previous_db": 5.9772704691441785
},
{
"label": "L2",
"level_db": -6.0,
"start_sample": 3200000,
"samples": 800000,
"duration_seconds": 0.1,
"analysis_start_sample": 3208400,
"analysis_samples": 783200,
"metrics": {
"samples": 800000,
"mean_i": 5.625e-05,
"mean_q": 2.625e-05,
"power_code2": 486.5064875,
"ac_power_code2": 486.50648749614686,
"rms_code": 22.05689206347984,
"peak_magnitude_code": 35.12833614050059,
"max_abs_i": 34.0,
"max_abs_q": 35.0,
"papr_db": 4.0422652379446395,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.024325324375,
"requested_relative_power_db": -6.0,
"tx_rms_code": 22.05689206347984,
"tx_peak_abs_i_code": 34.0,
"tx_peak_abs_q_code": 35.0,
"tx_peak_magnitude_code": 35.12833614050059,
"digital_clipping": false,
"actual_relative_power_db": -5.998257379520232
},
"tx_input_difference_from_previous_db": 5.998157271536577
},
{
"label": "L3",
"level_db": 0.0,
"start_sample": 4400000,
"samples": 800000,
"duration_seconds": 0.1,
"analysis_start_sample": 4408400,
"analysis_samples": 783200,
"metrics": {
"samples": 800000,
"mean_i": 8.25e-05,
"mean_q": 0.00011125,
"power_code2": 1936.04021375,
"ac_power_code2": 1936.0402137308172,
"rms_code": 44.00045697205883,
"peak_magnitude_code": 69.6419413859206,
"max_abs_i": 69.0,
"max_abs_q": 69.0,
"papr_db": 3.9882736474748155,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0968020106875,
"requested_relative_power_db": 0.0,
"tx_rms_code": 44.00045697205883,
"tx_peak_abs_i_code": 69.0,
"tx_peak_abs_q_code": 69.0,
"tx_peak_magnitude_code": 69.6419413859206,
"digital_clipping": false,
"actual_relative_power_db": 0.0
},
"tx_input_difference_from_previous_db": 5.998257379520232
}
],
"leading_zero_samples": 800000,
"gap_samples": 400000,
"trailing_zero_samples": 800000,
"tx_samples": 6000000,
"tx_bytes": 12000000,
"tx_duration_seconds": 0.75,
"tx_sha256": "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9",
"rx_samples": 16000000,
"rx_duration_seconds": 2.0,
"rx_lead_seconds": 0.5,
"automatic_retry": false,
"tx_command_prepared_not_run": [
"C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe",
"-d",
"000000000000000097c063dc323b97d3",
"-t",
"C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab064\\tx_level_staircase.cs8",
"-f",
"1400000000",
"-s",
"8000000",
"-n",
"6000000",
"-x",
"10",
"-a",
"0",
"-p",
"0",
"-B"
],
"rx_command_prepared_not_run": [
"C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe",
"-d",
"000000000000000097c063dc2e5327d3",
"-r",
"C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab064\\rx_stream.cs8",
"-f",
"1400000000",
"-s",
"8000000",
"-n",
"16000000",
"-l",
"24",
"-g",
"24",
"-a",
"0",
"-p",
"0",
"-B"
]
}

View File

@@ -0,0 +1,425 @@
{
"lab": "Lab064",
"stage": "OFFLINE_RF_LEVEL_LINEARITY_ANALYSIS",
"packet_receiver_used": false,
"location": {
"start_sample": 4123520,
"correlation": 0.0888256100450642,
"coarse_cfo_hz": 0.0,
"stride": 32
},
"rows": [
{
"label": "L0",
"level_db": -18.0,
"rx_start_sample": 4923521,
"alignment_adjustment_samples": 1,
"full_iq": {
"samples": 800000,
"mean_i": 0.94972375,
"mean_q": 1.8355175,
"power_code2": 5.18564125,
"ac_power_code2": 0.9145415558796861,
"rms_code": 2.2772003095907043,
"peak_magnitude_code": 7.0710678118654755,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"papr_db": 9.841675359702911,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.00025928206249999997,
"ac_rms_code": 0.9563166608815754
},
"background_label": "INITIAL_GUARD",
"background": {
"samples": 160000,
"mean_i": 0.940225,
"mean_q": 1.8409875,
"power_code2": 4.7947875,
"ac_power_code2": 0.5215294742187488,
"rms_code": 2.189700321961889,
"peak_magnitude_code": 4.242640687119285,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 5.7450314065030845,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.000239739375,
"ac_rms_code": 0.7221699759881665
},
"background_window_start_sample": 4443520,
"matched_signal_power": 0.0007507510158784873,
"matched_signal_amplitude_rms": 0.027399836055686307,
"residual_power": 1.2137948040249413,
"residual_to_matched_amplitude_ratio": 40.209129659782626,
"matched_to_residual_db": -32.08649345507262,
"complex_gain_h": {
"real": 0.0018760642981310563,
"imag": -0.0045080629571906915,
"phase_rad_at_active_start": -1.1764391150184978
},
"gain_abs": 0.00488285253481168,
"gain_power_abs_h_squared": 2.384224887671685e-05,
"cfo_hz": 0.0957717781274782,
"residual_spectrum": {
"residual_band_h1_power_code2": 0.0029441230361582733,
"residual_band_h2_power_code2": 0.002517548539085255,
"residual_band_h3_power_code2": 0.0017878979213816356,
"interpretation": "Diagnostic residual bands at 50/100/150 kHz; not calibrated RF harmonic power"
}
},
{
"label": "L1",
"level_db": -12.0,
"rx_start_sample": 6123541,
"alignment_adjustment_samples": 21,
"full_iq": {
"samples": 800000,
"mean_i": 0.9560375,
"mean_q": 1.8325725,
"power_code2": 5.2504775,
"ac_power_code2": 0.9781478308375009,
"rms_code": 2.2913920441513276,
"peak_magnitude_code": 7.211102550927978,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"papr_db": 9.958045419078847,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.000262523875,
"ac_rms_code": 0.9890135645366553
},
"background_label": "GAP_L0_L1",
"background": {
"samples": 160000,
"mean_i": 0.95144375,
"mean_q": 1.8329875,
"power_code2": 4.78826875,
"ac_power_code2": 0.5231803654296865,
"rms_code": 2.1882113129220406,
"peak_magnitude_code": 4.242640687119285,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 5.7509398714368505,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.00023941343750000002,
"ac_rms_code": 0.7233120802459243
},
"background_window_start_sample": 5883520,
"matched_signal_power": 0.0029612351609719875,
"matched_signal_amplitude_rms": 0.054417232206094304,
"residual_power": 1.0695946032022712,
"residual_to_matched_amplitude_ratio": 19.005231005856622,
"matched_to_residual_db": -25.577463055166668,
"complex_gain_h": {
"real": 0.004471119012843702,
"imag": -0.001937685853593986,
"phase_rad_at_active_start": -0.40894566669212534
},
"gain_abs": 0.0048729387123409105,
"gain_power_abs_h_squared": 2.374553169423069e-05,
"cfo_hz": -0.16857111258676097,
"residual_spectrum": {
"residual_band_h1_power_code2": 0.0037442904303572424,
"residual_band_h2_power_code2": 0.0029946268848091966,
"residual_band_h3_power_code2": 0.0022268690579244723,
"interpretation": "Diagnostic residual bands at 50/100/150 kHz; not calibrated RF harmonic power"
}
},
{
"label": "L2",
"level_db": -6.0,
"rx_start_sample": 7323533,
"alignment_adjustment_samples": 13,
"full_iq": {
"samples": 800000,
"mean_i": 0.9631825,
"mean_q": 1.84173875,
"power_code2": 5.17589875,
"ac_power_code2": 0.856176598442187,
"rms_code": 2.275060164039624,
"peak_magnitude_code": 7.280109889280518,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"papr_db": 10.102900974475599,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002587949375,
"ac_rms_code": 0.925298113281437
},
"background_label": "GAP_L1_L2",
"background": {
"samples": 160000,
"mean_i": 0.9560375,
"mean_q": 1.8575625,
"power_code2": 4.88045,
"ac_power_code2": 0.5159038571874985,
"rms_code": 2.209174053803819,
"peak_magnitude_code": 4.242640687119285,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 5.668126373000443,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002440225,
"ac_rms_code": 0.7182644757939087
},
"background_window_start_sample": 7083520,
"matched_signal_power": 0.011333436190702588,
"matched_signal_amplitude_rms": 0.10645861257175292,
"residual_power": 0.5290886880136152,
"residual_to_matched_amplitude_ratio": 6.832559719073439,
"matched_to_residual_db": -16.691668725481204,
"complex_gain_h": {
"real": 0.0032772531007889995,
"imag": -0.003478187284280655,
"phase_rad_at_active_start": -0.8151334504253348
},
"gain_abs": 0.00477893028523777,
"gain_power_abs_h_squared": 2.283817467116275e-05,
"cfo_hz": 0.006742170898886185,
"residual_spectrum": {
"residual_band_h1_power_code2": 0.004466260208758569,
"residual_band_h2_power_code2": 0.0030543665029441423,
"residual_band_h3_power_code2": 0.0020345488796523733,
"interpretation": "Diagnostic residual bands at 50/100/150 kHz; not calibrated RF harmonic power"
}
},
{
"label": "L3",
"level_db": 0.0,
"rx_start_sample": 8523534,
"alignment_adjustment_samples": 14,
"full_iq": {
"samples": 800000,
"mean_i": 0.9575575,
"mean_q": 1.8561875,
"power_code2": 5.48103,
"ac_power_code2": 1.1186815990375,
"rms_code": 2.3411599689043037,
"peak_magnitude_code": 7.280109889280518,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"papr_db": 9.85413690444334,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002740515,
"ac_rms_code": 1.0576774551050523
},
"background_label": "GAP_L2_L3",
"background": {
"samples": 160000,
"mean_i": 0.97165,
"mean_q": 1.8424125,
"power_code2": 4.8607875,
"ac_power_code2": 0.5221999573437506,
"rms_code": 2.204719369897221,
"peak_magnitude_code": 4.47213595499958,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 6.14323360311441,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.00024303937499999998,
"ac_rms_code": 0.7226340410911671
},
"background_window_start_sample": 8283520,
"matched_signal_power": 0.0453318643989967,
"matched_signal_amplitude_rms": 0.21291280938214285,
"residual_power": 0.740861773845582,
"residual_to_matched_amplitude_ratio": 4.042656143280289,
"matched_to_residual_db": -12.133336061267785,
"complex_gain_h": {
"real": 0.003384387504328541,
"imag": -0.003391322182689881,
"phase_rad_at_active_start": -0.7864216245934512
},
"gain_abs": 0.004791152776343041,
"gain_power_abs_h_squared": 2.295514492625963e-05,
"cfo_hz": -0.07606695286129402,
"residual_spectrum": {
"residual_band_h1_power_code2": 0.009576142863317505,
"residual_band_h2_power_code2": 0.004468597337512337,
"residual_band_h3_power_code2": 0.002725169628283891,
"interpretation": "Diagnostic residual bands at 50/100/150 kHz; not calibrated RF harmonic power"
}
}
],
"background_windows": [
{
"label": "INITIAL_GUARD",
"tx_relative_start_sample": 320000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 4443520,
"metrics": {
"samples": 160000,
"mean_i": 0.940225,
"mean_q": 1.8409875,
"power_code2": 4.7947875,
"ac_power_code2": 0.5215294742187488,
"rms_code": 2.189700321961889,
"peak_magnitude_code": 4.242640687119285,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 5.7450314065030845,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.000239739375,
"ac_rms_code": 0.7221699759881665
}
},
{
"label": "GAP_L0_L1",
"tx_relative_start_sample": 1760000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 5883520,
"metrics": {
"samples": 160000,
"mean_i": 0.95144375,
"mean_q": 1.8329875,
"power_code2": 4.78826875,
"ac_power_code2": 0.5231803654296865,
"rms_code": 2.1882113129220406,
"peak_magnitude_code": 4.242640687119285,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 5.7509398714368505,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.00023941343750000002,
"ac_rms_code": 0.7233120802459243
}
},
{
"label": "GAP_L1_L2",
"tx_relative_start_sample": 2960000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 7083520,
"metrics": {
"samples": 160000,
"mean_i": 0.9560375,
"mean_q": 1.8575625,
"power_code2": 4.88045,
"ac_power_code2": 0.5159038571874985,
"rms_code": 2.209174053803819,
"peak_magnitude_code": 4.242640687119285,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 5.668126373000443,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002440225,
"ac_rms_code": 0.7182644757939087
}
},
{
"label": "GAP_L2_L3",
"tx_relative_start_sample": 4160000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 8283520,
"metrics": {
"samples": 160000,
"mean_i": 0.97165,
"mean_q": 1.8424125,
"power_code2": 4.8607875,
"ac_power_code2": 0.5221999573437506,
"rms_code": 2.204719369897221,
"peak_magnitude_code": 4.47213595499958,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 6.14323360311441,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.00024303937499999998,
"ac_rms_code": 0.7226340410911671
}
},
{
"label": "FINAL_GUARD",
"tx_relative_start_sample": 5440000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 9563520,
"metrics": {
"samples": 160000,
"mean_i": 0.958375,
"mean_q": 1.83606875,
"power_code2": 4.81993125,
"ac_power_code2": 0.5303001546484385,
"rms_code": 2.195434182570728,
"peak_magnitude_code": 4.47213595499958,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 6.179891520223454,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002409965625,
"ac_rms_code": 0.7282171068084288
}
}
],
"background_summary": {
"ac_power_min_code2": 0.5159038571874985,
"ac_power_max_code2": 0.5303001546484385,
"ac_rms_min_code": 0.7182644757939087,
"ac_rms_max_code": 0.7282171068084288,
"maximum_to_minimum_ac_power_db": 0.11952978854087751,
"stability_rule_db": 3.0,
"stable": true
},
"comparisons": [
{
"comparison": "L1/L0",
"tx_input_difference_db": 5.9772704691441785,
"rx_matched_power_difference_db": 5.959769689089129,
"linearity_error_db": -0.01750078005504907,
"tx_amplitude_ratio": 1.9900478704552953,
"rx_matched_amplitude_ratio": 1.9860422557090833
},
{
"comparison": "L2/L1",
"tx_input_difference_db": 5.998157271536577,
"rx_matched_power_difference_db": 5.828887063637578,
"linearity_error_db": -0.16927020789899938,
"tx_amplitude_ratio": 1.9948390610676463,
"rx_matched_amplitude_ratio": 1.9563400830193338
},
{
"comparison": "L3/L2",
"tx_input_difference_db": 5.998257379520232,
"rx_matched_power_difference_db": 6.020419771848732,
"linearity_error_db": 0.022162392328500147,
"tx_amplitude_ratio": 1.9948620524335567,
"rx_matched_amplitude_ratio": 1.9999585213327857
}
],
"total_comparison": {
"comparison": "L3/L0",
"tx_digital_power_difference_db": 17.97368512020099,
"rx_matched_power_difference_db": 17.80907652457544,
"total_linearity_error_db": -0.16460859562555186,
"tx_amplitude_ratio": 7.9192536969014835,
"rx_matched_amplitude_ratio": 7.770586982689514
},
"classification": {
"case": "LINEAR_BUT_WEAK",
"rules_fixed_before_rf": {
"linear_max_abs_error_db": 1.0,
"compression_upper_step_error_at_most_db": -1.5,
"weak_l3_matched_to_residual_below_db": 3.0,
"healthy_l3_matched_to_residual_at_least_db": 6.0
}
},
"capture_valid": true,
"capture_invalid_reasons": [],
"tx_underruns_maximum": 0,
"tx_underruns_final": 0,
"rx_overruns_maximum": 0,
"rx_overruns_final": 0,
"rx_clipping": false
}

View File

@@ -0,0 +1,39 @@
{
"lab": "Lab064",
"stage": "SOFTWARE_LINEARITY_GATE",
"rf_tx_count": 0,
"channel_model": "known linear complex gain plus DC and deterministic Gaussian noise",
"rows": [
{
"label": "L0",
"matched_signal_power": 4.310961695783257,
"residual_power": 0.0018007645625517528,
"gain_abs": 0.37000937351312335
},
{
"label": "L1",
"matched_signal_power": 17.072568748673206,
"residual_power": 0.0017975392617719525,
"gain_abs": 0.3700018841553234
},
{
"label": "L2",
"matched_signal_power": 67.93699349861977,
"residual_power": 0.0017977879292746589,
"gain_abs": 0.37000113388875977
},
{
"label": "L3",
"matched_signal_power": 270.35275600931345,
"residual_power": 0.001803678589230678,
"gain_abs": 0.3700016234349186
}
],
"linearity_errors_db": [
-2.3407130973929213e-05,
-8.27380804224731e-05,
-1.2603446491787906e-05
],
"passed": true,
"tx_sha256": "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9"
}

View File

@@ -0,0 +1,232 @@
{
"lab": "Lab065",
"stage": "SINGLE_RF_LEVEL_CAPTURE",
"passed": true,
"rf_tx_count": 1,
"automatic_tx_repeats": 0,
"point": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 20000,
"samples_per_symbol": 400,
"digital_carrier_hz": 50000,
"rrc_rolloff": 0.35,
"rrc_span_symbols": 10,
"prbs": "PRBS7 x^7+x^6+1, deterministic initial state",
"full_phy_packet": false,
"tx_vga_db": 20,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN",
"levels_db_relative_nominal": [
-18.0,
-12.0,
-6.0,
0.0
],
"geometry_unchanged_from_lab064": true,
"waveform_source": "Lab064 exact CS8 copy"
},
"tx_sha256": "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9",
"process_before": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 292,
"errors": []
}
]
},
"inventory": {
"passed": true,
"serials": [
"000000000000000097c063dc2e5327d3",
"000000000000000097c063dc323b97d3"
],
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3",
"raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One"
},
"clock": {
"passed": true,
"master_reg29": 38,
"slave_reg29": 38,
"slave_clkin_status": "DETECTED",
"slave_clock_wait": {
"state": "DETECTED",
"queries": 2,
"time_to_detect_ms": 136.89709990285337,
"elapsed_ms": 136.89709990285337,
"polls": [
{
"query": 1,
"start_ms": 50.08170008659363,
"end_ms": 67.4550998955965,
"raw": "CLKIN status: no clock signal detected",
"state": "NOT_DETECTED",
"exit_code": 0
},
{
"query": 2,
"start_ms": 117.92290001176298,
"end_ms": 136.89709990285337,
"raw": "CLKIN status: clock signal detected",
"state": "DETECTED",
"exit_code": 0
}
]
},
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3"
},
"rx_level_before_tx": {
"samples": 65536,
"mean_i": 0.9449310302734375,
"mean_q": 1.8423919677734375,
"power_code2": 4.87310791015625,
"ac_power_code2": 0.5858050952665499,
"rms_code": 2.2075117010236323,
"peak_magnitude_code": 4.47213595499958,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 6.132239671543243,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION"
},
"tx_process": {
"returncode": 0,
"stdout_file": "tx_stdout.txt",
"stderr_file": "tx_stderr.txt"
},
"tx_counter_summary": {
"expected_kind": "underrun",
"observations": [
{
"count": 0,
"role": "UNKNOWN",
"kind": "underrun",
"text": "0 underruns",
"character_offset": 337
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "underrun",
"text": "0 underruns",
"character_offset": 509
}
],
"selected_counts": [
0,
0
],
"final_count": 0,
"maximum_count": 0,
"unparsed_loss_text": false,
"clean": true
},
"rx_samples": 16000000,
"rx_bytes": 32000000,
"rx_duration_seconds": 2.0,
"rx_counter_summary": {
"expected_kind": "overrun",
"observations": [
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 337
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 459
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 581
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 752
}
],
"selected_counts": [
0,
0,
0,
0
],
"final_count": 0,
"maximum_count": 0,
"unparsed_loss_text": false,
"clean": true
},
"rx_sha256": "845d7b7dcaef70e179ab69e6ba0041601859630786d2f4d51c16a8c1c7869d7e",
"rx_level": {
"samples": 16000000,
"mean_i": 0.942780625,
"mean_q": 1.8349653125,
"power_code2": 5.6163274375,
"ac_power_code2": 1.3603944325463857,
"rms_code": 2.3698792031451728,
"peak_magnitude_code": 10.816653826391969,
"max_abs_i": 10.0,
"max_abs_q": 10.0,
"papr_db": 13.187334420841685,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION"
},
"rx_clipping": false,
"process_after": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 292,
"errors": []
}
]
},
"cleanup_errors": []
}

View File

@@ -0,0 +1,181 @@
{
"lab": "Lab065",
"stage": "COMMON_CLOCK_AND_RX_ONLY_PREFLIGHT",
"passed": true,
"rf_tx_count": 0,
"stop_before_tx": true,
"point": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 20000,
"samples_per_symbol": 400,
"digital_carrier_hz": 50000,
"rrc_rolloff": 0.35,
"rrc_span_symbols": 10,
"prbs": "PRBS7 x^7+x^6+1, deterministic initial state",
"full_phy_packet": false,
"tx_vga_db": 20,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN",
"levels_db_relative_nominal": [
-18.0,
-12.0,
-6.0,
0.0
],
"geometry_unchanged_from_lab064": true,
"waveform_source": "Lab064 exact CS8 copy"
},
"tx_sha256": "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9",
"process_before": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 289,
"errors": []
}
]
},
"inventory": {
"passed": true,
"serials": [
"000000000000000097c063dc2e5327d3",
"000000000000000097c063dc323b97d3"
],
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3",
"raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One"
},
"clock": {
"passed": true,
"master_reg29": 38,
"slave_reg29": 38,
"slave_clkin_status": "DETECTED",
"slave_clock_wait": {
"state": "DETECTED",
"queries": 3,
"time_to_detect_ms": 201.98559993878007,
"elapsed_ms": 201.98559993878007,
"polls": [
{
"query": 1,
"start_ms": 50.617999862879515,
"end_ms": 66.89479993656278,
"raw": "CLKIN status: no clock signal detected",
"state": "NOT_DETECTED",
"exit_code": 0
},
{
"query": 2,
"start_ms": 117.23309988155961,
"end_ms": 136.1208998132497,
"raw": "CLKIN status: no clock signal detected",
"state": "NOT_DETECTED",
"exit_code": 0
},
{
"query": 3,
"start_ms": 187.1324998792261,
"end_ms": 201.98559993878007,
"raw": "CLKIN status: clock signal detected",
"state": "DETECTED",
"exit_code": 0
}
]
},
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3"
},
"rx_process": {
"returncode": 0,
"stdout": "",
"stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 800000/0Mio\nStop with Ctrl-C\n 1.8 MiB / 0.116 sec = 15.9 MiB/second, average power -34.8 dBfs, 9024 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.11556 s\nhackrf_stop_rx() done\nTransfer statistics:\n1847520 bytes transferred by M0\n1835008 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n"
},
"rx_counter_summary": {
"expected_kind": "overrun",
"observations": [
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 333
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 502
}
],
"selected_counts": [
0,
0
],
"final_count": 0,
"maximum_count": 0,
"unparsed_loss_text": false,
"clean": true
},
"rx_level": {
"samples": 800000,
"mean_i": 0.94889625,
"mean_q": 1.85107375,
"power_code2": 5.4432075,
"ac_power_code2": 1.1163293787968742,
"rms_code": 2.333068258752838,
"peak_magnitude_code": 8.06225774829855,
"max_abs_i": 6.0,
"max_abs_q": 8.0,
"papr_db": 10.770584663112091,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION",
"symbol_energy": "NOT_APPLICABLE_TO_BACKGROUND",
"ac_rms_code": 1.0565648956864289,
"unexpected_strong_signal": false
},
"rx_sha256": "be3c61dfa1bc40d1a9f6777689026804a1ccfc340b82680d3ec5304ddd68f78c",
"rx_overruns": 0,
"process_after": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 289,
"errors": []
}
]
},
"cleanup_errors": []
}

View File

@@ -0,0 +1,219 @@
{
"lab": "Lab065",
"stage": "PREPARATION_ONLY",
"rf_tx_count": 0,
"head": "cff226e0bf9e36a627829ea11a4ca3292ae20953",
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 20000,
"samples_per_symbol": 400,
"digital_carrier_hz": 50000,
"rrc_rolloff": 0.35,
"rrc_span_symbols": 10,
"prbs": "PRBS7 x^7+x^6+1, deterministic initial state",
"full_phy_packet": false,
"tx_vga_db": 20,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN",
"levels_db_relative_nominal": [
-18.0,
-12.0,
-6.0,
0.0
],
"geometry_unchanged_from_lab064": true,
"waveform_source": "Lab064 exact CS8 copy"
},
"segments": [
{
"label": "L0",
"level_db": -18.0,
"start_sample": 800000,
"samples": 800000,
"duration_seconds": 0.1,
"analysis_start_sample": 808400,
"analysis_samples": 783200,
"metrics": {
"samples": 800000,
"mean_i": -9.625e-05,
"mean_q": 2.75e-05,
"power_code2": 30.87065625,
"ac_power_code2": 30.870656239979688,
"rms_code": 5.556136809870686,
"peak_magnitude_code": 9.219544457292887,
"max_abs_i": 9.0,
"max_abs_q": 9.0,
"papr_db": 4.398730638796093,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0015435328125,
"requested_relative_power_db": -18.0,
"tx_rms_code": 5.556136809870686,
"tx_peak_abs_i_code": 9.0,
"tx_peak_abs_q_code": 9.0,
"tx_peak_magnitude_code": 9.219544457292887,
"digital_clipping": false,
"actual_relative_power_db": -17.97368512020099
}
},
{
"label": "L1",
"level_db": -12.0,
"start_sample": 2000000,
"samples": 800000,
"duration_seconds": 0.1,
"analysis_start_sample": 2008400,
"analysis_samples": 783200,
"metrics": {
"samples": 800000,
"mean_i": -5e-05,
"mean_q": 5e-05,
"power_code2": 122.2567675,
"ac_power_code2": 122.25676749499999,
"rms_code": 11.056978226441435,
"peak_magnitude_code": 17.804493814764857,
"max_abs_i": 17.0,
"max_abs_q": 17.0,
"papr_db": 4.1378635346865025,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.006112838375,
"requested_relative_power_db": -12.0,
"tx_rms_code": 11.056978226441435,
"tx_peak_abs_i_code": 17.0,
"tx_peak_abs_q_code": 17.0,
"tx_peak_magnitude_code": 17.804493814764857,
"digital_clipping": false,
"actual_relative_power_db": -11.99641465105681
},
"tx_input_difference_from_previous_db": 5.9772704691441785
},
{
"label": "L2",
"level_db": -6.0,
"start_sample": 3200000,
"samples": 800000,
"duration_seconds": 0.1,
"analysis_start_sample": 3208400,
"analysis_samples": 783200,
"metrics": {
"samples": 800000,
"mean_i": 5.625e-05,
"mean_q": 2.625e-05,
"power_code2": 486.5064875,
"ac_power_code2": 486.50648749614686,
"rms_code": 22.05689206347984,
"peak_magnitude_code": 35.12833614050059,
"max_abs_i": 34.0,
"max_abs_q": 35.0,
"papr_db": 4.0422652379446395,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.024325324375,
"requested_relative_power_db": -6.0,
"tx_rms_code": 22.05689206347984,
"tx_peak_abs_i_code": 34.0,
"tx_peak_abs_q_code": 35.0,
"tx_peak_magnitude_code": 35.12833614050059,
"digital_clipping": false,
"actual_relative_power_db": -5.998257379520232
},
"tx_input_difference_from_previous_db": 5.998157271536577
},
{
"label": "L3",
"level_db": 0.0,
"start_sample": 4400000,
"samples": 800000,
"duration_seconds": 0.1,
"analysis_start_sample": 4408400,
"analysis_samples": 783200,
"metrics": {
"samples": 800000,
"mean_i": 8.25e-05,
"mean_q": 0.00011125,
"power_code2": 1936.04021375,
"ac_power_code2": 1936.0402137308172,
"rms_code": 44.00045697205883,
"peak_magnitude_code": 69.6419413859206,
"max_abs_i": 69.0,
"max_abs_q": 69.0,
"papr_db": 3.9882736474748155,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0968020106875,
"requested_relative_power_db": 0.0,
"tx_rms_code": 44.00045697205883,
"tx_peak_abs_i_code": 69.0,
"tx_peak_abs_q_code": 69.0,
"tx_peak_magnitude_code": 69.6419413859206,
"digital_clipping": false,
"actual_relative_power_db": 0.0
},
"tx_input_difference_from_previous_db": 5.998257379520232
}
],
"tx_samples": 6000000,
"tx_bytes": 12000000,
"tx_duration_seconds": 0.75,
"tx_sha256": "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9",
"source_tx_sha256": "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9",
"waveform_unchanged_from_lab064": true,
"automatic_retry": false,
"tx_command_prepared_not_run": [
"C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe",
"-d",
"000000000000000097c063dc323b97d3",
"-t",
"C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab065\\tx_level_staircase.cs8",
"-f",
"1400000000",
"-s",
"8000000",
"-n",
"6000000",
"-x",
"20",
"-a",
"0",
"-p",
"0",
"-B"
],
"rx_command_prepared_not_run": [
"C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe",
"-d",
"000000000000000097c063dc2e5327d3",
"-r",
"C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab065\\rx_stream.cs8",
"-f",
"1400000000",
"-s",
"8000000",
"-n",
"16000000",
"-l",
"24",
"-g",
"24",
"-a",
"0",
"-p",
"0",
"-B"
]
}

View File

@@ -0,0 +1,515 @@
{
"lab": "Lab065",
"stage": "OFFLINE_RF_LEVEL_LINEARITY_ANALYSIS",
"packet_receiver_used": false,
"location": {
"start_sample": 4217216,
"correlation": 0.28566040369708917,
"coarse_cfo_hz": 0.0,
"stride": 32
},
"rows": [
{
"label": "L0",
"level_db": -18.0,
"rx_start_sample": 5017215,
"alignment_adjustment_samples": -1,
"full_iq": {
"samples": 800000,
"mean_i": 0.9456825,
"mean_q": 1.849345,
"power_code2": 5.91858,
"ac_power_code2": 1.6041876801687494,
"rms_code": 2.4328131864160882,
"peak_magnitude_code": 7.280109889280518,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"papr_db": 9.520583473606806,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.000295929,
"ac_rms_code": 1.2665653082919766
},
"background_label": "INITIAL_GUARD",
"background": {
"samples": 160000,
"mean_i": 0.9375625,
"mean_q": 1.83864375,
"power_code2": 4.84290625,
"ac_power_code2": 0.5832719691796884,
"rms_code": 2.200660412239926,
"peak_magnitude_code": 4.47213595499958,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 6.1592393370019245,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.00024214531250000003,
"ac_rms_code": 0.7637224425009969
},
"matched_signal_power": 0.009849829325472823,
"residual_power": 1.147671646182205,
"matched_to_residual_db": -20.663889470509574,
"complex_gain_h": {
"real": -0.0069147093491316635,
"imag": 0.016278708105995708,
"phase_rad_at_active_start": 1.9724722764994853
},
"gain_abs": 0.01768642256034779,
"gain_power_abs_h_squared": 0.00031280954298317925,
"cfo_hz": 0.051385857393477286,
"residual_spectrum": {
"residual_band_h1_power_code2": 0.005700729949335216,
"residual_band_h2_power_code2": 0.004639110794845057,
"residual_band_h3_power_code2": 0.003007515042889266,
"interpretation": "Diagnostic residual bands at 50/100/150 kHz; not calibrated RF harmonic power"
}
},
{
"label": "L1",
"level_db": -12.0,
"rx_start_sample": 6217220,
"alignment_adjustment_samples": 4,
"full_iq": {
"samples": 800000,
"mean_i": 0.943035,
"mean_q": 1.84948125,
"power_code2": 5.45620125,
"ac_power_code2": 1.1463053446734381,
"rms_code": 2.335851290215197,
"peak_magnitude_code": 7.810249675906654,
"max_abs_i": 7.0,
"max_abs_q": 7.0,
"papr_db": 10.48439454272797,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.00027281006250000003,
"ac_rms_code": 1.0706565017191265
},
"background_label": "GAP_L0_L1",
"background": {
"samples": 160000,
"mean_i": 0.94049375,
"mean_q": 1.8457,
"power_code2": 4.89708125,
"ac_power_code2": 0.6059442662109387,
"rms_code": 2.2129349854887286,
"peak_magnitude_code": 5.0990195135927845,
"max_abs_i": 4.0,
"max_abs_q": 5.0,
"papr_db": 7.250360382891476,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002448540625,
"ac_rms_code": 0.7784242199539648
},
"matched_signal_power": 0.038319468321711674,
"residual_power": 0.6202840436902609,
"matched_to_residual_db": -12.091711347697867,
"complex_gain_h": {
"real": -0.010179637303215595,
"imag": 0.014270629544800722,
"phase_rad_at_active_start": 2.1904112551609387
},
"gain_abs": 0.017529286443833295,
"gain_power_abs_h_squared": 0.00030727588322995773,
"cfo_hz": -0.015456037277818255,
"residual_spectrum": {
"residual_band_h1_power_code2": 0.0075272705585461884,
"residual_band_h2_power_code2": 0.005178438128918921,
"residual_band_h3_power_code2": 0.0030044589971250603,
"interpretation": "Diagnostic residual bands at 50/100/150 kHz; not calibrated RF harmonic power"
}
},
{
"label": "L2",
"level_db": -6.0,
"rx_start_sample": 7417219,
"alignment_adjustment_samples": 3,
"full_iq": {
"samples": 800000,
"mean_i": 0.94256,
"mean_q": 1.85174125,
"power_code2": 5.55749625,
"ac_power_code2": 1.2401312394484378,
"rms_code": 2.3574342514691686,
"peak_magnitude_code": 7.280109889280518,
"max_abs_i": 6.0,
"max_abs_q": 7.0,
"papr_db": 9.793966912760688,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002778748125,
"ac_rms_code": 1.1136117992588073
},
"background_label": "GAP_L1_L2",
"background": {
"samples": 160000,
"mean_i": 0.94511875,
"mean_q": 1.8435375,
"power_code2": 4.89561875,
"ac_power_code2": 0.6037387844921858,
"rms_code": 2.2126045173053406,
"peak_magnitude_code": 8.06225774829855,
"max_abs_i": 7.0,
"max_abs_q": 7.0,
"papr_db": 11.231057671986083,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002447809375,
"ac_rms_code": 0.7770062963015073
},
"matched_signal_power": 0.15371936701352645,
"residual_power": 0.7099975700355287,
"matched_to_residual_db": -6.645282748943733,
"complex_gain_h": {
"real": -0.00913356439809709,
"imag": 0.015044605957089683,
"phase_rad_at_active_start": 2.1164192954656
},
"gain_abs": 0.01760006156291179,
"gain_power_abs_h_squared": 0.000309762167018285,
"cfo_hz": -0.02238057704898943,
"residual_spectrum": {
"residual_band_h1_power_code2": 0.016197144376941752,
"residual_band_h2_power_code2": 0.007835153285271243,
"residual_band_h3_power_code2": 0.003956469302302745,
"interpretation": "Diagnostic residual bands at 50/100/150 kHz; not calibrated RF harmonic power"
}
},
{
"label": "L3",
"level_db": 0.0,
"rx_start_sample": 8617220,
"alignment_adjustment_samples": 4,
"full_iq": {
"samples": 800000,
"mean_i": 0.941795,
"mean_q": 1.85647375,
"power_code2": 6.38914875,
"ac_power_code2": 2.055676143535938,
"rms_code": 2.52767655169723,
"peak_magnitude_code": 8.602325267042627,
"max_abs_i": 7.0,
"max_abs_q": 8.0,
"papr_db": 10.637887203839098,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.00031945743750000003,
"ac_rms_code": 1.4337629314276255
},
"background_label": "GAP_L2_L3",
"background": {
"samples": 160000,
"mean_i": 0.9481,
"mean_q": 1.8589625,
"power_code2": 4.9655625,
"ac_power_code2": 0.6109273135937494,
"rms_code": 2.228354213315289,
"peak_magnitude_code": 6.324555320336759,
"max_abs_i": 5.0,
"max_abs_q": 6.0,
"papr_db": 9.060915387364618,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.000248278125,
"ac_rms_code": 0.7816183938430246
},
"matched_signal_power": 0.609773488771332,
"residual_power": 1.8217771923731447,
"matched_to_residual_db": -4.753267221075902,
"complex_gain_h": {
"real": -0.009107358713761582,
"imag": 0.015027742846344474,
"phase_rad_at_active_start": 2.1156425161969685
},
"gain_abs": 0.017572052748526183,
"gain_power_abs_h_squared": 0.0003087770377969866,
"cfo_hz": -0.006443832004222744,
"residual_spectrum": {
"residual_band_h1_power_code2": 0.05148134451389538,
"residual_band_h2_power_code2": 0.019651663054535452,
"residual_band_h3_power_code2": 0.008610269373925542,
"interpretation": "Diagnostic residual bands at 50/100/150 kHz; not calibrated RF harmonic power"
}
}
],
"background_windows": [
{
"label": "INITIAL_GUARD",
"tx_relative_start_sample": 320000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 4537216,
"metrics": {
"samples": 160000,
"mean_i": 0.9375625,
"mean_q": 1.83864375,
"power_code2": 4.84290625,
"ac_power_code2": 0.5832719691796884,
"rms_code": 2.200660412239926,
"peak_magnitude_code": 4.47213595499958,
"max_abs_i": 3.0,
"max_abs_q": 4.0,
"papr_db": 6.1592393370019245,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.00024214531250000003,
"ac_rms_code": 0.7637224425009969
}
},
{
"label": "GAP_L0_L1",
"tx_relative_start_sample": 1760000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 5977216,
"metrics": {
"samples": 160000,
"mean_i": 0.94049375,
"mean_q": 1.8457,
"power_code2": 4.89708125,
"ac_power_code2": 0.6059442662109387,
"rms_code": 2.2129349854887286,
"peak_magnitude_code": 5.0990195135927845,
"max_abs_i": 4.0,
"max_abs_q": 5.0,
"papr_db": 7.250360382891476,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002448540625,
"ac_rms_code": 0.7784242199539648
}
},
{
"label": "GAP_L1_L2",
"tx_relative_start_sample": 2960000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 7177216,
"metrics": {
"samples": 160000,
"mean_i": 0.94511875,
"mean_q": 1.8435375,
"power_code2": 4.89561875,
"ac_power_code2": 0.6037387844921858,
"rms_code": 2.2126045173053406,
"peak_magnitude_code": 8.06225774829855,
"max_abs_i": 7.0,
"max_abs_q": 7.0,
"papr_db": 11.231057671986083,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002447809375,
"ac_rms_code": 0.7770062963015073
}
},
{
"label": "GAP_L2_L3",
"tx_relative_start_sample": 4160000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 8377216,
"metrics": {
"samples": 160000,
"mean_i": 0.9481,
"mean_q": 1.8589625,
"power_code2": 4.9655625,
"ac_power_code2": 0.6109273135937494,
"rms_code": 2.228354213315289,
"peak_magnitude_code": 6.324555320336759,
"max_abs_i": 5.0,
"max_abs_q": 6.0,
"papr_db": 9.060915387364618,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.000248278125,
"ac_rms_code": 0.7816183938430246
}
},
{
"label": "FINAL_GUARD",
"tx_relative_start_sample": 5440000,
"samples": 160000,
"duration_seconds": 0.02,
"rx_start_sample": 9657216,
"metrics": {
"samples": 160000,
"mean_i": 0.94553125,
"mean_q": 1.8361,
"power_code2": 5.00006875,
"ac_power_code2": 0.7347761952734375,
"rms_code": 2.2360833504142907,
"peak_magnitude_code": 9.486832980505138,
"max_abs_i": 9.0,
"max_abs_q": 9.0,
"papr_db": 12.55266533595234,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.0002500034375,
"ac_rms_code": 0.8571908744692966
}
}
],
"background_summary": {
"ac_power_min_code2": 0.5832719691796884,
"ac_power_max_code2": 0.7347761952734375,
"ac_rms_min_code": 0.7637224425009969,
"ac_rms_max_code": 0.8571908744692966,
"maximum_to_minimum_ac_power_db": 1.0028397226073626,
"stability_rule_db": 3.0,
"stable": true
},
"comparisons": [
{
"comparison": "L1/L0",
"tx_input_difference_db": 5.9772704691441785,
"rx_matched_power_difference_db": 5.899907694072936,
"linearity_error_db": -0.07736277507124267
},
{
"comparison": "L2/L1",
"tx_input_difference_db": 5.998157271536577,
"rx_matched_power_difference_db": 6.033091127942342,
"linearity_error_db": 0.03493385640576463
},
{
"comparison": "L3/L2",
"tx_input_difference_db": 5.998257379520232,
"rx_matched_power_difference_db": 5.9843995108689985,
"linearity_error_db": -0.013857868651233396
}
],
"capture_valid": true,
"capture_invalid_reasons": [],
"tx_underruns_maximum": 0,
"rx_overruns_maximum": 0,
"rx_clipping": false,
"lab064_to_lab065": {
"rows": [
{
"label": "L0",
"tx_vga_nominal_difference_db": 10.0,
"rx_matched_power_difference_db": 11.179327767173566,
"gain_power_abs_h_squared_difference_db": 11.179327767173568,
"residual_power_difference_db": -0.24327621738947727,
"matched_to_residual_improvement_db": 11.422603984563047,
"complex_gain_h_old": {
"real": 0.0018760642981310563,
"imag": -0.0045080629571906915,
"phase_rad_at_active_start": -1.1764391150184978
},
"complex_gain_h_new": {
"real": -0.0069147093491316635,
"imag": 0.016278708105995708,
"phase_rad_at_active_start": 1.9724722764994853
},
"complex_gain_phase_change_degrees": -179.5806672053524,
"residual_spectral_band_difference_db": {
"h1_50000_hz": 2.869745130254167,
"h2_100000_hz": 2.6545689216728405,
"h3_150000_hz": 2.25865088789477
}
},
{
"label": "L1",
"tx_vga_nominal_difference_db": 10.0,
"rx_matched_power_difference_db": 11.119465772157373,
"gain_power_abs_h_squared_difference_db": 11.119465772157373,
"residual_power_difference_db": -2.3662859353114283,
"matched_to_residual_improvement_db": 13.4857517074688,
"complex_gain_h_old": {
"real": 0.004471119012843702,
"imag": -0.001937685853593986,
"phase_rad_at_active_start": -0.40894566669212534
},
"complex_gain_h_new": {
"real": -0.010179637303215595,
"imag": 0.014270629544800722,
"phase_rad_at_active_start": 2.1904112551609387
},
"complex_gain_phase_change_degrees": 148.9321810702975,
"residual_spectral_band_difference_db": {
"h1_50000_hz": 3.0326799855695237,
"h2_100000_hz": 2.378560725133286,
"h3_150000_hz": 1.3007160057992286
}
},
{
"label": "L2",
"tx_vga_nominal_difference_db": 10.0,
"rx_matched_power_difference_db": 11.323669836462136,
"gain_power_abs_h_squared_difference_db": 11.323669836462136,
"residual_power_difference_db": 1.2772838599246652,
"matched_to_residual_improvement_db": 10.046385976537472,
"complex_gain_h_old": {
"real": 0.0032772531007889995,
"imag": -0.003478187284280655,
"phase_rad_at_active_start": -0.8151334504253348
},
"complex_gain_h_new": {
"real": -0.00913356439809709,
"imag": 0.015044605957089683,
"phase_rad_at_active_start": 2.1164192954656
},
"complex_gain_phase_change_degrees": 167.96559975953804,
"residual_spectral_band_difference_db": {
"h1_50000_hz": 5.594944314904455,
"h2_100000_hz": 4.091263491385863,
"h3_150000_hz": 2.888396722883724
}
},
{
"label": "L3",
"tx_vga_nominal_difference_db": 10.0,
"rx_matched_power_difference_db": 11.287649575482401,
"gain_power_abs_h_squared_difference_db": 11.287649575482403,
"residual_power_difference_db": 3.907580735290519,
"matched_to_residual_improvement_db": 7.380068840191884,
"complex_gain_h_old": {
"real": 0.003384387504328541,
"imag": -0.003391322182689881,
"phase_rad_at_active_start": -0.7864216245934512
},
"complex_gain_h_new": {
"real": -0.009107358713761582,
"imag": 0.015027742846344474,
"phase_rad_at_active_start": 2.1156425161969685
},
"complex_gain_phase_change_degrees": 166.2760271435506,
"residual_spectral_band_difference_db": {
"h1_50000_hz": 7.304592641009381,
"h2_100000_hz": 6.432280867349566,
"h3_150000_hz": 4.996231985221501
}
}
],
"rules_fixed_before_rf": {
"internal_linear_max_abs_error_db": 1.0,
"compression_upper_step_error_at_most_db": -1.5,
"meaningful_matched_gain_median_at_least_db": 3.0,
"meaningful_ratio_improvement_median_at_least_db": 3.0,
"maximum_level_to_level_gain_spread_db": 3.0,
"residual_tracks_if_within_matched_gain_db": 3.0
}
},
"classification": {
"case": "LINEAR_GAIN_IMPROVEMENT",
"summary": {
"median_matched_gain_db": 11.233488671327983,
"median_residual_gain_db": 0.5170038212675939,
"median_matched_to_residual_improvement_db": 10.73449498055026,
"matched_gain_level_spread_db": 0.20420406430476312,
"maximum_internal_linearity_error_db": 0.07736277507124267,
"upper_step_linearity_error_db": -0.013857868651233396
},
"rules_fixed_before_rf": {
"internal_linear_max_abs_error_db": 1.0,
"compression_upper_step_error_at_most_db": -1.5,
"meaningful_matched_gain_median_at_least_db": 3.0,
"meaningful_ratio_improvement_median_at_least_db": 3.0,
"maximum_level_to_level_gain_spread_db": 3.0,
"residual_tracks_if_within_matched_gain_db": 3.0
}
}
}

View File

@@ -0,0 +1,17 @@
{
"lab": "Lab065",
"stage": "SOFTWARE_GATE",
"rf_tx_count": 0,
"passed": true,
"tx_sha256": "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9",
"waveform_unchanged_from_lab064": true,
"lab064_baseline_classification": "LINEAR_BUT_WEAK",
"classification_rules": {
"internal_linear_max_abs_error_db": 1.0,
"compression_upper_step_error_at_most_db": -1.5,
"meaningful_matched_gain_median_at_least_db": 3.0,
"meaningful_ratio_improvement_median_at_least_db": 3.0,
"maximum_level_to_level_gain_spread_db": 3.0,
"residual_tracks_if_within_matched_gain_db": 3.0
}
}

View File

@@ -0,0 +1,224 @@
{
"lab": "Lab066",
"stage": "SINGLE_RF_CAPTURE",
"passed": true,
"rf_tx_count": 1,
"automatic_tx_repeats": 0,
"point": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 500000,
"samples_per_symbol": 16,
"digital_carrier_hz": 50000.0,
"packets": 16,
"payload_bytes": 256,
"tx_vga_db": 20,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"geometry_unchanged": true,
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN"
},
"tx_sha256": "621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199",
"process_before": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 300,
"errors": []
}
]
},
"inventory": {
"passed": true,
"serials": [
"000000000000000097c063dc2e5327d3",
"000000000000000097c063dc323b97d3"
],
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3",
"raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One"
},
"clock": {
"passed": true,
"master_reg29": 38,
"slave_reg29": 38,
"slave_clkin_status": "DETECTED",
"slave_clock_wait": {
"state": "DETECTED",
"queries": 2,
"time_to_detect_ms": 131.2907999381423,
"elapsed_ms": 131.2907999381423,
"polls": [
{
"query": 1,
"start_ms": 50.125200068578124,
"end_ms": 66.83470006100833,
"raw": "CLKIN status: no clock signal detected",
"state": "NOT_DETECTED",
"exit_code": 0
},
{
"query": 2,
"start_ms": 116.86519999057055,
"end_ms": 131.2907999381423,
"raw": "CLKIN status: clock signal detected",
"state": "DETECTED",
"exit_code": 0
}
]
},
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3"
},
"rx_level_before_tx": {
"samples": 65536,
"mean_i": 0.952423095703125,
"mean_q": 1.83642578125,
"power_code2": 5.656829833984375,
"ac_power_code2": 1.377260430715979,
"rms_code": 2.3784090972716143,
"peak_magnitude_code": 5.385164807134504,
"max_abs_i": 4.0,
"max_abs_q": 5.0,
"papr_db": 7.0982488319834305,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION",
"ac_rms_code": 1.173567395046394,
"unexpected_strong_signal": false
},
"tx_process": {
"returncode": 0,
"stdout_file": "tx_stdout.txt",
"stderr_file": "tx_stderr.txt"
},
"tx_counter_summary": {
"expected_kind": "underrun",
"observations": [
{
"count": 0,
"role": "UNKNOWN",
"kind": "underrun",
"text": "0 underruns",
"character_offset": 336
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "underrun",
"text": "0 underruns",
"character_offset": 506
}
],
"selected_counts": [
0,
0
],
"final_count": 0,
"maximum_count": 0,
"unparsed_loss_text": false,
"clean": true
},
"rx_counter_summary": {
"expected_kind": "overrun",
"observations": [
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 337
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 459
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 580
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 751
}
],
"selected_counts": [
0,
0,
0,
0
],
"final_count": 0,
"maximum_count": 0,
"unparsed_loss_text": false,
"clean": true
},
"rx_samples": 16000000,
"rx_sha256": "72ff7ddd8b30baa4a5c066361ca1f8dfa664f1da37f65c0c373b211ce6cf00f0",
"rx_level": {
"samples": 16000000,
"mean_i": 0.9510684375,
"mean_q": 1.844211625,
"power_code2": 5.0153848125,
"ac_power_code2": 0.7097371219061666,
"rms_code": 2.239505483918269,
"peak_magnitude_code": 5.830951894845301,
"max_abs_i": 4.0,
"max_abs_q": 5.0,
"papr_db": 8.311746565484663,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"symbol_energy_code2_seconds": 0.000250769240625,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION"
},
"rx_clipping": false,
"process_after": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 300,
"errors": []
}
]
},
"cleanup_errors": []
}

View File

@@ -0,0 +1,17 @@
packet_index,legacy_header,legacy_fec,legacy_crc,legacy_packet_output,t2_header,t2_fec,t2_crc,t2_packet_output
1,False,False,False,False,False,False,False,False
2,False,False,False,False,False,False,False,False
3,False,False,False,False,False,False,False,False
4,True,True,True,True,True,True,True,True
5,True,True,True,True,True,True,True,True
6,True,True,True,True,True,True,True,True
7,True,True,True,True,True,True,True,True
8,True,True,True,True,True,True,True,True
9,False,False,False,False,False,False,False,False
10,True,True,True,True,True,True,True,True
11,True,True,True,True,True,True,True,True
12,True,True,True,True,True,True,True,True
13,True,True,True,True,True,True,True,True
14,True,True,True,True,True,True,True,True
15,False,False,False,False,False,False,False,False
16,False,False,False,False,False,False,False,False
1 packet_index legacy_header legacy_fec legacy_crc legacy_packet_output t2_header t2_fec t2_crc t2_packet_output
2 1 False False False False False False False False
3 2 False False False False False False False False
4 3 False False False False False False False False
5 4 True True True True True True True True
6 5 True True True True True True True True
7 6 True True True True True True True True
8 7 True True True True True True True True
9 8 True True True True True True True True
10 9 False False False False False False False False
11 10 True True True True True True True True
12 11 True True True True True True True True
13 12 True True True True True True True True
14 13 True True True True True True True True
15 14 True True True True True True True True
16 15 False False False False False False False False
17 16 False False False False False False False False

View File

@@ -0,0 +1,164 @@
{
"lab": "Lab066",
"stage": "RX_ONLY_PREFLIGHT",
"passed": true,
"rf_tx_count": 0,
"point": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 500000,
"samples_per_symbol": 16,
"digital_carrier_hz": 50000.0,
"packets": 16,
"payload_bytes": 256,
"tx_vga_db": 20,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"geometry_unchanged": true,
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN"
},
"tx_sha256": "621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199",
"stop_before_tx": true,
"process_before": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 294,
"errors": []
}
]
},
"inventory": {
"passed": true,
"serials": [
"000000000000000097c063dc2e5327d3",
"000000000000000097c063dc323b97d3"
],
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3",
"raw_output": "hackrf_info version: 2024.02.1\nlibhackrf version: 2024.02.1 (0.9)\nFound HackRF\nIndex: 0\nSerial number: 000000000000000097c063dc323b97d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0x00744f5a\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One\n\nFound HackRF\nIndex: 1\nSerial number: 000000000000000097c063dc2e5327d3\nBoard ID Number: 4 (HackRF One)\nFirmware Version: 2024.02.1 (API:1.08)\nPart ID Number: 0xa000cb3c 0xbc4b4739\nHardware Revision: r9\nHardware does not appear to have been manufactured by Great Scott Gadgets.\nHardware supported by installed firmware:\n HackRF One"
},
"clock": {
"passed": true,
"master_reg29": 38,
"slave_reg29": 38,
"slave_clkin_status": "DETECTED",
"slave_clock_wait": {
"state": "DETECTED",
"queries": 2,
"time_to_detect_ms": 132.11270002648234,
"elapsed_ms": 132.11270002648234,
"polls": [
{
"query": 1,
"start_ms": 50.09360006079078,
"end_ms": 66.02549995295703,
"raw": "CLKIN status: no clock signal detected",
"state": "NOT_DETECTED",
"exit_code": 0
},
{
"query": 2,
"start_ms": 116.46570009179413,
"end_ms": 132.11270002648234,
"raw": "CLKIN status: clock signal detected",
"state": "DETECTED",
"exit_code": 0
}
]
},
"master_serial": "000000000000000097c063dc323b97d3",
"slave_serial": "000000000000000097c063dc2e5327d3"
},
"rx_process": {
"returncode": 0,
"stdout": "",
"stderr": "call hackrf_set_sample_rate(8000000 Hz/8.000 MHz)\ncall hackrf_set_hw_sync_mode(0)\ncall hackrf_set_freq(1400000000 Hz/1400.000 MHz)\ncall hackrf_set_amp_enable(0)\ncall hackrf_set_antenna_enable(0)\nsamples_to_xfer 800000/0Mio\nStop with Ctrl-C\n 1.8 MiB / 0.115 sec = 15.9 MiB/second, average power -35.2 dBfs, 11712 bytes free in buffer, 0 overruns, longest 0 bytes\n\nExiting...\nTotal time: 0.11546 s\nhackrf_stop_rx() done\nTransfer statistics:\n1850016 bytes transferred by M0\n1835008 bytes transferred by M4\n0 overruns, longest 0 bytes\nhackrf_close() done\nhackrf_exit() done\nfclose() done\nexit\n"
},
"rx_counter_summary": {
"expected_kind": "overrun",
"observations": [
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 334
},
{
"count": 0,
"role": "UNKNOWN",
"kind": "overrun",
"text": "0 overruns",
"character_offset": 503
}
],
"selected_counts": [
0,
0
],
"final_count": 0,
"maximum_count": 0,
"unparsed_loss_text": false,
"clean": true
},
"rx_level": {
"samples": 800000,
"mean_i": 0.94753,
"mean_q": 1.83594125,
"power_code2": 4.95347625,
"ac_power_code2": 0.6849828756484371,
"rms_code": 2.2256406381084974,
"peak_magnitude_code": 5.385164807134504,
"max_abs_i": 4.0,
"max_abs_q": 5.0,
"papr_db": 7.674879128392212,
"clipped_components_fraction": 0.0,
"clipped_samples_fraction": 0.0,
"saturation_detected": false,
"analog_compression": "UNKNOWN_WITHOUT_CALIBRATION",
"symbol_energy": "NOT_APPLICABLE_TO_BACKGROUND",
"ac_rms_code": 0.8276369225985735,
"unexpected_strong_signal": false
},
"rx_sha256": "ff817582e6a8fc03b489bf89f46322a9db8a9493335a4360a1b0f9bedad7c4d5",
"rx_overruns": 0,
"process_after": {
"state": "CLEAR",
"attempts": [
{
"state": "CLEAR",
"mechanism": "psutil",
"matches": [],
"inspected": 294,
"errors": []
}
]
},
"cleanup_errors": []
}

View File

@@ -0,0 +1,217 @@
{
"lab": "Lab066",
"stage": "PREPARATION_ONLY",
"rf_tx_count": 0,
"head": "dacf04f2d0a15c0c1b56a7fb527db61fc2e38462",
"parameters": {
"rf_frequency_hz": 1400000000,
"sample_rate_hz": 8000000,
"symbol_rate": 500000,
"samples_per_symbol": 16,
"digital_carrier_hz": 50000.0,
"packets": 16,
"payload_bytes": 256,
"tx_vga_db": 20,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": false,
"bias_tee": false,
"geometry": {
"frequency_hz": 1400000000,
"physical_path": "MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
"path_confirmed": true,
"tx_antenna": "existing 1400 MHz antenna near window",
"rx_antenna": "existing 1400 MHz antenna on desk",
"distance_m": 1.2,
"orientation": "same polarization; fixed during preflight and RF session",
"visibility": "LOS indoor"
},
"geometry_unchanged": true,
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN"
},
"packet_samples": 92256,
"inter_packet_gap_seconds": 0.005,
"inter_packet_gap_samples": 40000,
"number_of_gaps": 15,
"zero_guard_before_samples": 800000,
"zero_guard_after_samples": 800000,
"base_tx_samples": 2076096,
"expected_tx_samples": 3676096,
"tx_samples": 3676096,
"tx_bytes": 7352192,
"tx_duration_seconds": 0.459512,
"tx_sha256": "621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199",
"layout": [
{
"packet_index": 1,
"start_sample": 800000,
"samples": 92256,
"payload_sha256": "414dee46d0555da2caabe0d4e446eb52d22be2f380ed4529fd7f192420d06465",
"following_gap_start_sample": 892256,
"following_gap_samples": 40000
},
{
"packet_index": 2,
"start_sample": 932256,
"samples": 92256,
"payload_sha256": "f5304773cc626858c4ad1cfe509bfe40418cfee6d9c65718c7c271c664465f2d",
"following_gap_start_sample": 1024512,
"following_gap_samples": 40000
},
{
"packet_index": 3,
"start_sample": 1064512,
"samples": 92256,
"payload_sha256": "e5604108e4a0a0441b962cf65822838d817a228d5df899dfd64dab958f32a59c",
"following_gap_start_sample": 1156768,
"following_gap_samples": 40000
},
{
"packet_index": 4,
"start_sample": 1196768,
"samples": 92256,
"payload_sha256": "43a7b5866bcf826920aae650830abfd2fa75b6e5460078c1bbde3ec7b461703f",
"following_gap_start_sample": 1289024,
"following_gap_samples": 40000
},
{
"packet_index": 5,
"start_sample": 1329024,
"samples": 92256,
"payload_sha256": "46836a613f080ddeba9c1b23bc8d8dd981db24975115074fa01b31699099efb8",
"following_gap_start_sample": 1421280,
"following_gap_samples": 40000
},
{
"packet_index": 6,
"start_sample": 1461280,
"samples": 92256,
"payload_sha256": "6ff8c9b941d37c39834f8cc5be3fdf563b3e55c51fc0c7d7344d4e046a15d13c",
"following_gap_start_sample": 1553536,
"following_gap_samples": 40000
},
{
"packet_index": 7,
"start_sample": 1593536,
"samples": 92256,
"payload_sha256": "273543a396d7499a1e1b325415b38555c72bb2665a227cd88aff5b797e18875d",
"following_gap_start_sample": 1685792,
"following_gap_samples": 40000
},
{
"packet_index": 8,
"start_sample": 1725792,
"samples": 92256,
"payload_sha256": "20051b24e17274d3b0cf3c170ea09559409c18ff429a3020ff28cb83d9b7bb3b",
"following_gap_start_sample": 1818048,
"following_gap_samples": 40000
},
{
"packet_index": 9,
"start_sample": 1858048,
"samples": 92256,
"payload_sha256": "9239a9fdb3fc94354cc8372dfa06867a18500ad13f867ea3a4cd4468e76bb9f0",
"following_gap_start_sample": 1950304,
"following_gap_samples": 40000
},
{
"packet_index": 10,
"start_sample": 1990304,
"samples": 92256,
"payload_sha256": "997be4e3b7a26708a48afd8ac0932460dbb34d67a359f1770dd76214f810e658",
"following_gap_start_sample": 2082560,
"following_gap_samples": 40000
},
{
"packet_index": 11,
"start_sample": 2122560,
"samples": 92256,
"payload_sha256": "fb1d718a4c2fa358f24ba34197b3100384b0df4229efae846944949894526903",
"following_gap_start_sample": 2214816,
"following_gap_samples": 40000
},
{
"packet_index": 12,
"start_sample": 2254816,
"samples": 92256,
"payload_sha256": "778de948620ddcf8c70f639f72ed042f97915234a57055421af9cbeb16c47e1f",
"following_gap_start_sample": 2347072,
"following_gap_samples": 40000
},
{
"packet_index": 13,
"start_sample": 2387072,
"samples": 92256,
"payload_sha256": "cabcd273073d70d686900e180be3c59e970cb3633bb370ba2198e64540727190",
"following_gap_start_sample": 2479328,
"following_gap_samples": 40000
},
{
"packet_index": 14,
"start_sample": 2519328,
"samples": 92256,
"payload_sha256": "3d6fda80bdd274d781399b1d1831cb4cb4a7c17bcd69930330564bf0ed6eb125",
"following_gap_start_sample": 2611584,
"following_gap_samples": 40000
},
{
"packet_index": 15,
"start_sample": 2651584,
"samples": 92256,
"payload_sha256": "ece74586bedf93fc3f5e07f41f64eea4383425d43424fe209ca30d911279c6ff",
"following_gap_start_sample": 2743840,
"following_gap_samples": 40000
},
{
"packet_index": 16,
"start_sample": 2783840,
"samples": 92256,
"payload_sha256": "bba4133aea193e327938abc18d2a0215f1df0e821d378d530dc0b47498af9a5c"
}
],
"rx_samples": 16000000,
"rx_duration_seconds": 2,
"automatic_retry": false,
"tx_command_prepared_not_run": [
"C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe",
"-d",
"000000000000000097c063dc323b97d3",
"-t",
"C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab066\\tx_stream.cs8",
"-f",
"1400000000",
"-s",
"8000000",
"-n",
"3676096",
"-x",
"20",
"-a",
"0",
"-p",
"0",
"-B"
],
"rx_command_prepared_not_run": [
"C:\\Users\\user\\Tools\\HackRF\\Library\\bin\\hackrf_transfer.exe",
"-d",
"000000000000000097c063dc2e5327d3",
"-r",
"C:\\Users\\user\\Desktop\\projects\\SDR_Rover\\data\\raw\\lab066\\rx_stream.cs8",
"-f",
"1400000000",
"-s",
"8000000",
"-n",
"16000000",
"-l",
"24",
"-g",
"24",
"-a",
"0",
"-p",
"0",
"-B"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,382 @@
{
"lab": "Lab066",
"capture_valid": true,
"legacy": {
"candidates": 145,
"header_pass": 10,
"fec_started": 10,
"fec_pass": 10,
"crc_started": 10,
"crc_pass": 10,
"packet_output": 10,
"exact_payload_match": 10,
"packet_indexes": [
4,
5,
6,
7,
8,
10,
11,
12,
13,
14
]
},
"t2": {
"candidates": 145,
"header_pass": 10,
"fec_started": 10,
"fec_pass": 10,
"crc_started": 10,
"crc_pass": 10,
"packet_output": 10,
"exact_payload_match": 10,
"packet_indexes": [
4,
5,
6,
7,
8,
10,
11,
12,
13,
14
]
},
"passed_by_both": [
4,
5,
6,
7,
8,
10,
11,
12,
13,
14
],
"passed_only_by_legacy": [],
"passed_only_by_t2": [],
"failed_by_both": [
1,
2,
3,
9,
15,
16
],
"packet_rows": [
{
"packet_index": 1,
"legacy": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
},
"t2": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
}
},
{
"packet_index": 2,
"legacy": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
},
"t2": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
}
},
{
"packet_index": 3,
"legacy": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
},
"t2": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
}
},
{
"packet_index": 4,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 5,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 6,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 7,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 8,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 9,
"legacy": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
},
"t2": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
}
},
{
"packet_index": 10,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 11,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 12,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 13,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 14,
"legacy": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
},
"t2": {
"candidate_at_expected_packet": true,
"header": true,
"fec": true,
"crc": true,
"packet_output": true
}
},
{
"packet_index": 15,
"legacy": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
},
"t2": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
}
},
{
"packet_index": 16,
"legacy": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
},
"t2": {
"candidate_at_expected_packet": true,
"header": false,
"fec": false,
"crc": false,
"packet_output": false
}
}
],
"physical": {
"symbol_error_rate": 0.011046635434412266,
"rms_symbol_deviation": 0.5283737542111951,
"matched_component_power": 8.359397909690596,
"residual_power": 2.333261015636848,
"matched_residual_db": 5.542116733950265,
"band_gain_nonuniformity_p95_p05_db_median": 2.8700698316435833,
"band_gain_nonuniformity_p95_p05_db_min": 2.7249057267348604,
"band_gain_nonuniformity_p95_p05_db_max": 3.1116789732634516
},
"lab056_B": {
"symbol_error_rate": 0.03495896464646465,
"rms_symbol_deviation": 0.8453497751219741,
"matched_residual_db": 1.4648455366051558,
"band_gain_nonuniformity_db": 5.471381501203027
},
"difference_from_lab056_B": {
"symbol_error_rate_absolute": -0.023912329212052382,
"rms_symbol_deviation_absolute": -0.3169760209107789,
"matched_residual_db": 4.077271197345109,
"band_gain_nonuniformity_db": -2.6013116695594434
},
"lab062": {
"symbol_error_rate": 0.0992866269165247,
"rms_symbol_deviation": 1.2204009809742542,
"matched_residual_db": -1.7300509612417754,
"band_gain_nonuniformity_db": 6.660340655081576,
"capture_status": "RF_SESSION_INVALID_TX_UNDERRUN"
},
"difference_from_lab062": {
"symbol_error_rate_absolute": -0.08823999148211244,
"rms_symbol_deviation_absolute": -0.6920272267630591,
"matched_residual_db": 7.27216769519204,
"band_gain_nonuniformity_db": -3.790270823437993
},
"classification": "PARTIAL_PACKET_RECOVERY_NO_T2_GAIN",
"primary_result": "Аппаратно валидный Lab066 дал одинаковые 10/16 точных пакетов в legacy и T2; физическое качество лучше Lab056 B и невалидной Lab062.",
"recommended_next_single_step": "Отдельно разрешить офлайн-сравнение header-ошибок пакетов 1-3, 9, 15-16 с принятыми пакетами по сохранённому RX; новый TX не нужен."
}

View File

@@ -0,0 +1,507 @@
{
"lab": "Lab066",
"stage": "SOFTWARE_GATE",
"rf_tx_count": 0,
"tx_sha256": "621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199",
"legacy": {
"mode": "legacy",
"candidates": 16,
"header_pass": 16,
"fec_started": 16,
"fec_pass": 16,
"crc_started": 16,
"crc_pass": 16,
"packet_output": 16,
"exact_payload_match": 16,
"packet_indexes": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16
],
"exact_ordered_payloads": true,
"t2_state_scope": "NOT_APPLICABLE",
"fallback_between_modes": false,
"passed": true,
"rows": [
{
"absolute_refined": 800000,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 1,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 932256,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 2,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 1064512,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 3,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 1196768,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 4,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 1329024,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 5,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 1461280,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 6,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 1593536,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 7,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 1725792,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 8,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 1858048,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 9,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 1990304,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 10,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 2122560,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 11,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 2254816,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 12,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 2387072,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 13,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 2519328,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 14,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 2651584,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 15,
"t2_tracking_runs_for_candidate": 0
},
{
"absolute_refined": 2783840,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 16,
"t2_tracking_runs_for_candidate": 0
}
],
"detector_statistics": {
"total_local_peaks": 80004,
"first_stage_candidates": 21193,
"cheap_stage_checked": 21193,
"cheap_stage_rejected": 20800,
"clusters": 37,
"representative_checks": 16,
"inside_accepted_frame": 377
},
"candidate_overflow": 0
},
"t2": {
"mode": "t2",
"candidates": 16,
"header_pass": 16,
"fec_started": 16,
"fec_pass": 16,
"crc_started": 16,
"crc_pass": 16,
"packet_output": 16,
"exact_payload_match": 16,
"packet_indexes": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16
],
"exact_ordered_payloads": true,
"t2_state_scope": "NEW_PREAMBLE_ESTIMATE_PER_PACKET",
"fallback_between_modes": false,
"passed": true,
"rows": [
{
"absolute_refined": 800000,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 1,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 932256,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 2,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 1064512,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 3,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 1196768,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 4,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 1329024,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 5,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 1461280,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 6,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 1593536,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 7,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 1725792,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 8,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 1858048,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 9,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 1990304,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 10,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 2122560,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 11,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 2254816,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 12,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 2387072,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 13,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 2519328,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 14,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 2651584,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 15,
"t2_tracking_runs_for_candidate": 2
},
{
"absolute_refined": 2783840,
"reason": "CRC_PASS",
"header": true,
"fec_started": true,
"fec": true,
"crc_started": true,
"crc": true,
"packet_output": true,
"packet_index_after_verdict": 16,
"t2_tracking_runs_for_candidate": 2
}
],
"detector_statistics": {
"total_local_peaks": 80004,
"first_stage_candidates": 21193,
"cheap_stage_checked": 21193,
"cheap_stage_rejected": 20800,
"clusters": 37,
"representative_checks": 16,
"inside_accepted_frame": 377
},
"candidate_overflow": 0,
"t2_state_reset_evidence": {
"estimate_source": "each candidate's own preamble",
"context_scope": "new PacketMeasure context for every candidate",
"tracking_runs_per_accepted_packet": [
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
],
"all_accepted_packets_have_fresh_tracking_runs": true,
"persistent_tracking_state_in_packet_processor": false
}
},
"gaps_verified_zero": true,
"t2_state_reset_verified_by_fresh_preamble_per_packet": true,
"passed": true
}

View File

@@ -0,0 +1,146 @@
candidate_number,position,nearest_packet,difference_samples,category,strict_reason
1,4902630,1,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_CHECKSUM_MISMATCH
2,4900598,1,-2032,UNRELATED,PHY_HEADER_MAGIC_MISMATCH
3,4904662,1,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
4,4898566,1,-4064,UNRELATED,PHY_HEADER_MAGIC_MISMATCH
5,4896534,1,-6096,UNRELATED,PHY_HEADER_MAGIC_MISMATCH
6,4906694,1,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
7,4894502,1,-8128,UNRELATED,PHY_HEADER_MAGIC_MISMATCH
8,4908726,1,6096,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
9,4910758,1,8128,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
10,4902630,1,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_CHECKSUM_MISMATCH
11,4900598,1,-2032,UNRELATED,PHY_HEADER_MAGIC_MISMATCH
12,4904662,1,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
13,4898566,1,-4064,UNRELATED,PHY_HEADER_MAGIC_MISMATCH
14,4906694,1,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
15,4902630,1,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_CHECKSUM_MISMATCH
16,4900598,1,-2032,UNRELATED,PHY_HEADER_MAGIC_MISMATCH
17,4904662,1,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
18,4968617,1,65987,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
19,4958408,1,55778,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
20,4982295,2,-52591,UNRELATED,PHY_HEADER_MAGIC_MISMATCH
21,5034886,2,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_CHECKSUM_MISMATCH
22,5032854,2,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
23,5036918,2,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
24,5030822,2,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
25,5028790,2,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
26,5038949,2,4063,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
27,5026758,2,-8128,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
28,5040981,2,6095,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
29,5043013,2,8127,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
30,5034886,2,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_CHECKSUM_MISMATCH
31,5032854,2,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
32,5034886,2,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_CHECKSUM_MISMATCH
33,5036918,2,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
34,5032854,2,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
35,5036918,2,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
36,5030822,2,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
37,5167142,3,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_MAGIC_MISMATCH
38,5165110,3,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
39,5169174,3,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
40,5163078,3,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
41,5161046,3,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
42,5171206,3,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
43,5159014,3,-8128,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
44,5173238,3,6096,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
45,5175270,3,8128,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
46,5167142,3,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_MAGIC_MISMATCH
47,5169174,3,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
48,5165110,3,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
49,5171206,3,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
50,5163078,3,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
51,5167142,3,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_MAGIC_MISMATCH
52,5169174,3,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
53,5165110,3,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
54,5198234,3,31092,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
55,5196202,3,29060,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
56,5194172,3,27030,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
57,5228601,3,61459,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
58,5230634,3,63492,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
59,5232665,3,65523,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
60,5220198,3,53056,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
61,5299398,4,0,TRUE_PREAMBLE_POSITION,CRC_PASS
62,5431654,5,0,TRUE_PREAMBLE_POSITION,CRC_PASS
63,5563910,6,0,TRUE_PREAMBLE_POSITION,CRC_PASS
64,5696166,7,0,TRUE_PREAMBLE_POSITION,CRC_PASS
65,5828422,8,0,TRUE_PREAMBLE_POSITION,CRC_PASS
66,5960678,9,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_CHECKSUM_MISMATCH
67,5958646,9,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
68,5962710,9,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
69,5956614,9,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
70,5954582,9,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
71,5952550,9,-8128,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
72,5960678,9,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_CHECKSUM_MISMATCH
73,5958646,9,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
74,5962710,9,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
75,5956614,9,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
76,5960678,9,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_CHECKSUM_MISMATCH
77,5958646,9,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
78,5962710,9,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
79,5964742,9,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
80,5966774,9,6096,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
81,5968806,9,8128,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
82,5964742,9,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
83,6017761,9,57083,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
84,6015727,9,55049,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
85,6092934,10,0,TRUE_PREAMBLE_POSITION,CRC_PASS
86,6225190,11,0,TRUE_PREAMBLE_POSITION,CRC_PASS
87,6355414,12,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
88,6353382,12,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
89,6351350,12,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
90,6349317,12,-8129,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
91,6355414,12,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
92,6353382,12,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
93,6351350,12,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
94,6355414,12,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
95,6357446,12,0,TRUE_PREAMBLE_POSITION,CRC_PASS
96,6487670,13,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
97,6485638,13,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
98,6483606,13,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
99,6481574,13,-8128,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
100,6487670,13,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
101,6485638,13,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
102,6483606,13,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
103,6487670,13,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
104,6485638,13,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
105,6489702,13,0,TRUE_PREAMBLE_POSITION,CRC_PASS
106,6617894,14,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
107,6615862,14,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
108,6613830,14,-8128,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
109,6617894,14,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
110,6621958,14,0,TRUE_PREAMBLE_POSITION,CRC_PASS
111,6750150,15,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
112,6748118,15,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
113,6746086,15,-8128,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
114,6750150,15,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
115,6748118,15,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
116,6750150,15,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
117,6754214,15,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_MAGIC_MISMATCH
118,6752182,15,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
119,6756246,15,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
120,6758278,15,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
121,6760309,15,6095,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
122,6762341,15,8127,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
123,6754214,15,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_MAGIC_MISMATCH
124,6752182,15,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
125,6756246,15,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
126,6758278,15,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
127,6754214,15,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_MAGIC_MISMATCH
128,6752182,15,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
129,6756246,15,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
130,6880374,16,-6096,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
131,6878342,16,-8128,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
132,6886470,16,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_VERSION_MISMATCH
133,6884438,16,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
134,6888502,16,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
135,6882406,16,-4064,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
136,6890534,16,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
137,6892566,16,6096,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
138,6894597,16,8127,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
139,6888502,16,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
140,6886470,16,0,TRUE_PREAMBLE_POSITION,PHY_HEADER_VERSION_MISMATCH
141,6892566,16,6096,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
142,6890534,16,4064,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
143,6884438,16,-2032,ZERO_GAP,PHY_HEADER_MAGIC_MISMATCH
144,6888502,16,2032,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
145,6902724,16,16254,REPEATED_PRBS_LOCAL_MAXIMUM,PHY_HEADER_MAGIC_MISMATCH
1 candidate_number position nearest_packet difference_samples category strict_reason
2 1 4902630 1 0 TRUE_PREAMBLE_POSITION PHY_HEADER_CHECKSUM_MISMATCH
3 2 4900598 1 -2032 UNRELATED PHY_HEADER_MAGIC_MISMATCH
4 3 4904662 1 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
5 4 4898566 1 -4064 UNRELATED PHY_HEADER_MAGIC_MISMATCH
6 5 4896534 1 -6096 UNRELATED PHY_HEADER_MAGIC_MISMATCH
7 6 4906694 1 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
8 7 4894502 1 -8128 UNRELATED PHY_HEADER_MAGIC_MISMATCH
9 8 4908726 1 6096 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
10 9 4910758 1 8128 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
11 10 4902630 1 0 TRUE_PREAMBLE_POSITION PHY_HEADER_CHECKSUM_MISMATCH
12 11 4900598 1 -2032 UNRELATED PHY_HEADER_MAGIC_MISMATCH
13 12 4904662 1 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
14 13 4898566 1 -4064 UNRELATED PHY_HEADER_MAGIC_MISMATCH
15 14 4906694 1 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
16 15 4902630 1 0 TRUE_PREAMBLE_POSITION PHY_HEADER_CHECKSUM_MISMATCH
17 16 4900598 1 -2032 UNRELATED PHY_HEADER_MAGIC_MISMATCH
18 17 4904662 1 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
19 18 4968617 1 65987 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
20 19 4958408 1 55778 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
21 20 4982295 2 -52591 UNRELATED PHY_HEADER_MAGIC_MISMATCH
22 21 5034886 2 0 TRUE_PREAMBLE_POSITION PHY_HEADER_CHECKSUM_MISMATCH
23 22 5032854 2 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
24 23 5036918 2 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
25 24 5030822 2 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
26 25 5028790 2 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
27 26 5038949 2 4063 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
28 27 5026758 2 -8128 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
29 28 5040981 2 6095 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
30 29 5043013 2 8127 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
31 30 5034886 2 0 TRUE_PREAMBLE_POSITION PHY_HEADER_CHECKSUM_MISMATCH
32 31 5032854 2 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
33 32 5034886 2 0 TRUE_PREAMBLE_POSITION PHY_HEADER_CHECKSUM_MISMATCH
34 33 5036918 2 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
35 34 5032854 2 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
36 35 5036918 2 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
37 36 5030822 2 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
38 37 5167142 3 0 TRUE_PREAMBLE_POSITION PHY_HEADER_MAGIC_MISMATCH
39 38 5165110 3 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
40 39 5169174 3 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
41 40 5163078 3 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
42 41 5161046 3 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
43 42 5171206 3 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
44 43 5159014 3 -8128 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
45 44 5173238 3 6096 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
46 45 5175270 3 8128 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
47 46 5167142 3 0 TRUE_PREAMBLE_POSITION PHY_HEADER_MAGIC_MISMATCH
48 47 5169174 3 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
49 48 5165110 3 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
50 49 5171206 3 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
51 50 5163078 3 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
52 51 5167142 3 0 TRUE_PREAMBLE_POSITION PHY_HEADER_MAGIC_MISMATCH
53 52 5169174 3 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
54 53 5165110 3 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
55 54 5198234 3 31092 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
56 55 5196202 3 29060 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
57 56 5194172 3 27030 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
58 57 5228601 3 61459 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
59 58 5230634 3 63492 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
60 59 5232665 3 65523 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
61 60 5220198 3 53056 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
62 61 5299398 4 0 TRUE_PREAMBLE_POSITION CRC_PASS
63 62 5431654 5 0 TRUE_PREAMBLE_POSITION CRC_PASS
64 63 5563910 6 0 TRUE_PREAMBLE_POSITION CRC_PASS
65 64 5696166 7 0 TRUE_PREAMBLE_POSITION CRC_PASS
66 65 5828422 8 0 TRUE_PREAMBLE_POSITION CRC_PASS
67 66 5960678 9 0 TRUE_PREAMBLE_POSITION PHY_HEADER_CHECKSUM_MISMATCH
68 67 5958646 9 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
69 68 5962710 9 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
70 69 5956614 9 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
71 70 5954582 9 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
72 71 5952550 9 -8128 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
73 72 5960678 9 0 TRUE_PREAMBLE_POSITION PHY_HEADER_CHECKSUM_MISMATCH
74 73 5958646 9 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
75 74 5962710 9 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
76 75 5956614 9 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
77 76 5960678 9 0 TRUE_PREAMBLE_POSITION PHY_HEADER_CHECKSUM_MISMATCH
78 77 5958646 9 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
79 78 5962710 9 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
80 79 5964742 9 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
81 80 5966774 9 6096 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
82 81 5968806 9 8128 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
83 82 5964742 9 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
84 83 6017761 9 57083 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
85 84 6015727 9 55049 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
86 85 6092934 10 0 TRUE_PREAMBLE_POSITION CRC_PASS
87 86 6225190 11 0 TRUE_PREAMBLE_POSITION CRC_PASS
88 87 6355414 12 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
89 88 6353382 12 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
90 89 6351350 12 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
91 90 6349317 12 -8129 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
92 91 6355414 12 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
93 92 6353382 12 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
94 93 6351350 12 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
95 94 6355414 12 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
96 95 6357446 12 0 TRUE_PREAMBLE_POSITION CRC_PASS
97 96 6487670 13 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
98 97 6485638 13 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
99 98 6483606 13 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
100 99 6481574 13 -8128 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
101 100 6487670 13 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
102 101 6485638 13 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
103 102 6483606 13 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
104 103 6487670 13 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
105 104 6485638 13 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
106 105 6489702 13 0 TRUE_PREAMBLE_POSITION CRC_PASS
107 106 6617894 14 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
108 107 6615862 14 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
109 108 6613830 14 -8128 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
110 109 6617894 14 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
111 110 6621958 14 0 TRUE_PREAMBLE_POSITION CRC_PASS
112 111 6750150 15 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
113 112 6748118 15 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
114 113 6746086 15 -8128 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
115 114 6750150 15 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
116 115 6748118 15 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
117 116 6750150 15 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
118 117 6754214 15 0 TRUE_PREAMBLE_POSITION PHY_HEADER_MAGIC_MISMATCH
119 118 6752182 15 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
120 119 6756246 15 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
121 120 6758278 15 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
122 121 6760309 15 6095 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
123 122 6762341 15 8127 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
124 123 6754214 15 0 TRUE_PREAMBLE_POSITION PHY_HEADER_MAGIC_MISMATCH
125 124 6752182 15 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
126 125 6756246 15 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
127 126 6758278 15 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
128 127 6754214 15 0 TRUE_PREAMBLE_POSITION PHY_HEADER_MAGIC_MISMATCH
129 128 6752182 15 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
130 129 6756246 15 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
131 130 6880374 16 -6096 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
132 131 6878342 16 -8128 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
133 132 6886470 16 0 TRUE_PREAMBLE_POSITION PHY_HEADER_VERSION_MISMATCH
134 133 6884438 16 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
135 134 6888502 16 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
136 135 6882406 16 -4064 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
137 136 6890534 16 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
138 137 6892566 16 6096 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
139 138 6894597 16 8127 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
140 139 6888502 16 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
141 140 6886470 16 0 TRUE_PREAMBLE_POSITION PHY_HEADER_VERSION_MISMATCH
142 141 6892566 16 6096 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
143 142 6890534 16 4064 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
144 143 6884438 16 -2032 ZERO_GAP PHY_HEADER_MAGIC_MISMATCH
145 144 6888502 16 2032 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH
146 145 6902724 16 16254 REPEATED_PRBS_LOCAL_MAXIMUM PHY_HEADER_MAGIC_MISMATCH

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -0,0 +1,17 @@
packet,strict_result,candidate_position,expected_packet_position,candidate_difference_samples,preamble_errors,preamble_error_rate,preamble_correlation,header_raw_errors,header_voted_errors,header_copy_1_errors,header_copy_2_errors,header_copy_3_errors,magic_errors,version_errors,length_errors,checksum_errors,expected_header_bits,received_raw_header_bits,voted_header_bits,header_accepted,header_reason,legacy_header_bits,t2_header_bits,legacy_initial_frequency_hz,t2_initial_frequency_hz,reference_frequency_hz,legacy_frequency_error_vs_reference_hz,initial_phase_error_rad,timing_offset_samples,fractional_timing_offset,reference_timing_offset_samples,reference_fractional_timing_offset,local_matched_power,local_residual_power,local_matched_residual_db,rms_symbol_deviation,legacy_t2_header_differences,classification
1,HEADER_FAIL,4902630,4902630,0,15,0.01171875,0.8981139142983712,3,1,1,2,0,0,0,1,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000101000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000110000000000000111000000000,110100111001000100000001000000010000110100001000,False,CHECKSUM_MISMATCH,111111000101000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000110000000000000111000000000,111111000101000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000110000000000000111000000000,-2.662272181646709,-5.3879680108224575,-2.6542601970280364,-0.008011984618672585,1.8341164291785854,0,0.0,0,0.0,8.982336070665001,2.7583799759789063,5.127352085281537,0.5541564541425134,0,HEADER_SPECIFIC_FAILURE
2,HEADER_FAIL,5034886,5034886,0,10,0.0078125,0.892574719565451,6,1,3,2,1,0,0,1,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000100000111000000000000000000000111000000000000000000000001000001110000111111000000000000000000111000000000,110100111001000100000001000000010010110000001000,False,CHECKSUM_MISMATCH,111111000111000000111111111000000111000100000111000000000000000000000111000000000000000000000001000001110000111111000000000000000000111000000000,111111000111000000111111111000000111000100000111000000000000000000000111000000000000000000000011000001110000111111000000000000000000111000000000,-11.085402212024045,-5.423727145761877,2.664169158774504,-13.749571370798549,1.8865220093820032,0,0.0,0,0.0,8.566883580374462,3.867819679092585,3.4535664637802532,0.6719263565992358,1,HEADER_SPECIFIC_FAILURE
3,HEADER_FAIL,5167142,5167142,0,11,0.00859375,0.8832445602414427,3,1,1,1,1,1,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111110001000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,110100110001000100000001000000010000110000001000,False,MAGIC_MISMATCH,111111000111000000111110001000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111110001000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,-2.14390103272374,2.717358680061899,4.3756668288999,-6.51956786162364,1.837976468233186,0,0.0,0,0.0,8.391114739306301,2.917171371178907,4.5885771684300085,0.589618554298201,0,HEADER_SPECIFIC_FAILURE
4,PASS,5299398,5299398,0,12,0.009375,0.8702559090330103,0,0,0,0,0,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,110100111001000100000001000000010000110000001000,True,,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,-4.969843852460903,0.5011874511379912,3.928841196279306,-8.898685048740209,1.823004794704275,0,0.0,0,0.0,8.221366239802954,2.9179318124892393,4.498688563977461,0.5957520861601466,0,PASSED
5,PASS,5431654,5431654,0,15,0.01171875,0.882298526549992,0,0,0,0,0,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,110100111001000100000001000000010000110000001000,True,,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,3.163024030078619,-1.2710648335872299,1.1365290837564324,2.026494946322187,1.8355890323417587,0,0.0,0,0.0,8.188755217773341,1.2708156134102264,8.091353471792932,0.39394203715952975,0,PASSED
6,PASS,5563910,5563910,0,17,0.01328125,0.8834263035683648,0,0,0,0,0,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,110100111001000100000001000000010000110000001000,True,,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,5.595453900367469,1.2623874159193273,-4.567512776067651,10.162966676435119,1.7721238280090583,0,0.0,0,0.0,8.667865149110309,1.6073728447094802,7.317955191422993,0.43062797582960244,0,PASSED
7,PASS,5696166,5696166,0,7,0.00546875,0.8957036694801145,1,0,0,0,1,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000001,110100111001000100000001000000010000110000001000,True,,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000001,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,-1.2654548420073324,-1.236432022604831,-6.203901481459032,4.9384466394516995,1.8155098517430892,0,0.0,0,0.0,8.65014337171221,2.0185187625245264,6.319905151171046,0.4830640770103008,1,PASSED
8,PASS,5828422,5828422,0,10,0.0078125,0.8935154947988603,3,0,1,2,0,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111001000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000010000111000000000,110100111001000100000001000000010000110000001000,True,,111001000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000010000111000000000,111001000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000010000111000000000,9.131379183391202,-0.4710188398180419,4.02876530540373,5.102613877987472,1.6973544391851634,0,0.0,0,0.0,8.476859162285322,2.688967210304384,4.986494612866651,0.5632163702340075,0,PASSED
9,HEADER_FAIL,5960678,5960678,0,13,0.01015625,0.8831012072365596,4,1,1,2,1,0,0,1,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000011010000000000000000000111000000000000000000000111011000000000111111000000000000000000111000000000,110100111001000100000001000000011000110000001000,False,CHECKSUM_MISMATCH,111111000111000000111111111000000111000000000011010000000000000000000111000000000000000000000111011000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000011010000000000000000000111000000000000000000000111011000000000111111000000000000000000111000000000,6.363378164483905,-1.9815016298670118,8.696281322717777,-2.332903158233872,1.7240388753166553,0,0.0,0,0.0,8.379835253157635,3.513421286396085,3.7750525233897125,0.6475113327264761,0,HEADER_SPECIFIC_FAILURE
10,PASS,6092934,6092934,0,14,0.0109375,0.8756981622368548,1,0,0,0,1,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111110111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,110100111001000100000001000000010000110000001000,True,,111111000111000000111110111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111110111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,10.521050631968299,4.784422094967777,8.894608707236657,1.6264419247316422,1.6172834220436263,0,0.0,0,0.0,7.7745725932128815,2.478953865410118,4.964080786327893,0.5646716196549459,0,PASSED
11,PASS,6225190,6225190,0,14,0.0109375,0.8739448578846127,0,0,0,0,0,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,110100111001000100000001000000010000110000001000,True,,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,-4.3377788034794795,5.576222280700207,6.2889992427567645,-10.626778046236243,1.8042319285279784,0,0.0,0,0.0,8.281301835417366,2.613504672826743,5.008753330856255,0.5617749030480063,0,PASSED
12,PASS,6357446,6357446,0,15,0.01171875,0.8691086828109845,0,0,0,0,0,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,110100111001000100000001000000010000110000001000,True,,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,-14.662329907046818,-12.429475985972452,-7.481009787452366,-7.181320119594452,1.9299825595605988,0,0.0,0,0.0,8.105161843192903,1.785984725783043,6.568839508606049,0.4694161471804715,0,PASSED
13,PASS,6489702,6489702,0,19,0.01484375,0.8870876180609537,0,0,0,0,0,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,110100111001000100000001000000010000110000001000,True,,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,2.005711398433546,-3.8713317585287843,-9.48236864846436,11.488080046897906,1.7755837460769197,0,0.0,0,0.0,8.379598937532618,1.5074086416620165,7.44992232360151,0.42413477685697976,0,PASSED
14,PASS,6621958,6621958,0,13,0.01015625,0.8979602974476922,1,0,0,0,1,0,0,0,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000110000000000000111111000000000000000000111000000000,110100111001000100000001000000010000110000001000,True,,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000110000000000000111111000000000000000000111000000000,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,7.210729633183354,3.326192426336044,-3.8425458753995345,11.053275508582889,1.6778789052916618,0,0.0,0,0.0,8.575750726813316,2.4203963781579967,5.493856544116208,0.5312600671059894,1,PASSED
15,HEADER_FAIL,6754214,6754214,0,12,0.009375,0.8887378180983065,7,2,2,2,3,1,0,1,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,111111000111000011111111111000000111000000000111000000000000000000000111001000110000000000000111000000000000111111000000000000000000111001100000,110101111001000100000001001000010000110000001000,False,MAGIC_MISMATCH,111111000111000011111111111000000111000000000111000000000000000000000111001000110000000000000111000000000000111111000000000000000000111001100000,111111000111000011111111111000000111000000000111000000000000000000000111001000110000000000000111000000000000111111000000000000000000111001100000,-5.7315977256001345,-3.5200403113930196,0.10139388237069231,-5.832991607970826,1.7811965898235738,0,0.0,0,0.0,7.968245167205011,3.1321489434833123,4.055202820682332,0.6269600363881329,0,HEADER_SPECIFIC_FAILURE
16,HEADER_FAIL,6886470,6886470,0,16,0.0125,0.8805097957519517,5,2,1,2,2,0,1,1,0,111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000,101111000111000000111111111000000111000000000111000000000011000000000111000000000000001100000111000000000000111111000000000000000000111000000000,110100111001000100010001000001010000110000001000,False,VERSION_MISMATCH,101111000111000000111111111000000111000000000111000000000011000000000111000000000000001100000111000000000000111111000000000000000000111000000000,000111000000111111100000000101011110110001101000011101111000001111000110111101111011100000111001010010111111000000111111111111111011000111111111,4.7344866536019055,228.10491338016192,10.381403191597384,-5.646916537995478,1.6829380426891485,0,0.0,0,0.0,8.084601213892752,3.04749463363358,4.237156529516785,0.613962963260252,107,HEADER_SPECIFIC_FAILURE
1 packet strict_result candidate_position expected_packet_position candidate_difference_samples preamble_errors preamble_error_rate preamble_correlation header_raw_errors header_voted_errors header_copy_1_errors header_copy_2_errors header_copy_3_errors magic_errors version_errors length_errors checksum_errors expected_header_bits received_raw_header_bits voted_header_bits header_accepted header_reason legacy_header_bits t2_header_bits legacy_initial_frequency_hz t2_initial_frequency_hz reference_frequency_hz legacy_frequency_error_vs_reference_hz initial_phase_error_rad timing_offset_samples fractional_timing_offset reference_timing_offset_samples reference_fractional_timing_offset local_matched_power local_residual_power local_matched_residual_db rms_symbol_deviation legacy_t2_header_differences classification
2 1 HEADER_FAIL 4902630 4902630 0 15 0.01171875 0.8981139142983712 3 1 1 2 0 0 0 1 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000101000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000110000000000000111000000000 110100111001000100000001000000010000110100001000 False CHECKSUM_MISMATCH 111111000101000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000110000000000000111000000000 111111000101000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000110000000000000111000000000 -2.662272181646709 -5.3879680108224575 -2.6542601970280364 -0.008011984618672585 1.8341164291785854 0 0.0 0 0.0 8.982336070665001 2.7583799759789063 5.127352085281537 0.5541564541425134 0 HEADER_SPECIFIC_FAILURE
3 2 HEADER_FAIL 5034886 5034886 0 10 0.0078125 0.892574719565451 6 1 3 2 1 0 0 1 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000100000111000000000000000000000111000000000000000000000001000001110000111111000000000000000000111000000000 110100111001000100000001000000010010110000001000 False CHECKSUM_MISMATCH 111111000111000000111111111000000111000100000111000000000000000000000111000000000000000000000001000001110000111111000000000000000000111000000000 111111000111000000111111111000000111000100000111000000000000000000000111000000000000000000000011000001110000111111000000000000000000111000000000 -11.085402212024045 -5.423727145761877 2.664169158774504 -13.749571370798549 1.8865220093820032 0 0.0 0 0.0 8.566883580374462 3.867819679092585 3.4535664637802532 0.6719263565992358 1 HEADER_SPECIFIC_FAILURE
4 3 HEADER_FAIL 5167142 5167142 0 11 0.00859375 0.8832445602414427 3 1 1 1 1 1 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111110001000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 110100110001000100000001000000010000110000001000 False MAGIC_MISMATCH 111111000111000000111110001000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111110001000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 -2.14390103272374 2.717358680061899 4.3756668288999 -6.51956786162364 1.837976468233186 0 0.0 0 0.0 8.391114739306301 2.917171371178907 4.5885771684300085 0.589618554298201 0 HEADER_SPECIFIC_FAILURE
5 4 PASS 5299398 5299398 0 12 0.009375 0.8702559090330103 0 0 0 0 0 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 110100111001000100000001000000010000110000001000 True 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 -4.969843852460903 0.5011874511379912 3.928841196279306 -8.898685048740209 1.823004794704275 0 0.0 0 0.0 8.221366239802954 2.9179318124892393 4.498688563977461 0.5957520861601466 0 PASSED
6 5 PASS 5431654 5431654 0 15 0.01171875 0.882298526549992 0 0 0 0 0 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 110100111001000100000001000000010000110000001000 True 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 3.163024030078619 -1.2710648335872299 1.1365290837564324 2.026494946322187 1.8355890323417587 0 0.0 0 0.0 8.188755217773341 1.2708156134102264 8.091353471792932 0.39394203715952975 0 PASSED
7 6 PASS 5563910 5563910 0 17 0.01328125 0.8834263035683648 0 0 0 0 0 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 110100111001000100000001000000010000110000001000 True 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 5.595453900367469 1.2623874159193273 -4.567512776067651 10.162966676435119 1.7721238280090583 0 0.0 0 0.0 8.667865149110309 1.6073728447094802 7.317955191422993 0.43062797582960244 0 PASSED
8 7 PASS 5696166 5696166 0 7 0.00546875 0.8957036694801145 1 0 0 0 1 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000001 110100111001000100000001000000010000110000001000 True 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000001 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 -1.2654548420073324 -1.236432022604831 -6.203901481459032 4.9384466394516995 1.8155098517430892 0 0.0 0 0.0 8.65014337171221 2.0185187625245264 6.319905151171046 0.4830640770103008 1 PASSED
9 8 PASS 5828422 5828422 0 10 0.0078125 0.8935154947988603 3 0 1 2 0 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111001000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000010000111000000000 110100111001000100000001000000010000110000001000 True 111001000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000010000111000000000 111001000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000010000111000000000 9.131379183391202 -0.4710188398180419 4.02876530540373 5.102613877987472 1.6973544391851634 0 0.0 0 0.0 8.476859162285322 2.688967210304384 4.986494612866651 0.5632163702340075 0 PASSED
10 9 HEADER_FAIL 5960678 5960678 0 13 0.01015625 0.8831012072365596 4 1 1 2 1 0 0 1 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000011010000000000000000000111000000000000000000000111011000000000111111000000000000000000111000000000 110100111001000100000001000000011000110000001000 False CHECKSUM_MISMATCH 111111000111000000111111111000000111000000000011010000000000000000000111000000000000000000000111011000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000011010000000000000000000111000000000000000000000111011000000000111111000000000000000000111000000000 6.363378164483905 -1.9815016298670118 8.696281322717777 -2.332903158233872 1.7240388753166553 0 0.0 0 0.0 8.379835253157635 3.513421286396085 3.7750525233897125 0.6475113327264761 0 HEADER_SPECIFIC_FAILURE
11 10 PASS 6092934 6092934 0 14 0.0109375 0.8756981622368548 1 0 0 0 1 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111110111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 110100111001000100000001000000010000110000001000 True 111111000111000000111110111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111110111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 10.521050631968299 4.784422094967777 8.894608707236657 1.6264419247316422 1.6172834220436263 0 0.0 0 0.0 7.7745725932128815 2.478953865410118 4.964080786327893 0.5646716196549459 0 PASSED
12 11 PASS 6225190 6225190 0 14 0.0109375 0.8739448578846127 0 0 0 0 0 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 110100111001000100000001000000010000110000001000 True 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 -4.3377788034794795 5.576222280700207 6.2889992427567645 -10.626778046236243 1.8042319285279784 0 0.0 0 0.0 8.281301835417366 2.613504672826743 5.008753330856255 0.5617749030480063 0 PASSED
13 12 PASS 6357446 6357446 0 15 0.01171875 0.8691086828109845 0 0 0 0 0 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 110100111001000100000001000000010000110000001000 True 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 -14.662329907046818 -12.429475985972452 -7.481009787452366 -7.181320119594452 1.9299825595605988 0 0.0 0 0.0 8.105161843192903 1.785984725783043 6.568839508606049 0.4694161471804715 0 PASSED
14 13 PASS 6489702 6489702 0 19 0.01484375 0.8870876180609537 0 0 0 0 0 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 110100111001000100000001000000010000110000001000 True 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 2.005711398433546 -3.8713317585287843 -9.48236864846436 11.488080046897906 1.7755837460769197 0 0.0 0 0.0 8.379598937532618 1.5074086416620165 7.44992232360151 0.42413477685697976 0 PASSED
15 14 PASS 6621958 6621958 0 13 0.01015625 0.8979602974476922 1 0 0 0 1 0 0 0 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000110000000000000111111000000000000000000111000000000 110100111001000100000001000000010000110000001000 True 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000110000000000000111111000000000000000000111000000000 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 7.210729633183354 3.326192426336044 -3.8425458753995345 11.053275508582889 1.6778789052916618 0 0.0 0 0.0 8.575750726813316 2.4203963781579967 5.493856544116208 0.5312600671059894 1 PASSED
16 15 HEADER_FAIL 6754214 6754214 0 12 0.009375 0.8887378180983065 7 2 2 2 3 1 0 1 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 111111000111000011111111111000000111000000000111000000000000000000000111001000110000000000000111000000000000111111000000000000000000111001100000 110101111001000100000001001000010000110000001000 False MAGIC_MISMATCH 111111000111000011111111111000000111000000000111000000000000000000000111001000110000000000000111000000000000111111000000000000000000111001100000 111111000111000011111111111000000111000000000111000000000000000000000111001000110000000000000111000000000000111111000000000000000000111001100000 -5.7315977256001345 -3.5200403113930196 0.10139388237069231 -5.832991607970826 1.7811965898235738 0 0.0 0 0.0 7.968245167205011 3.1321489434833123 4.055202820682332 0.6269600363881329 0 HEADER_SPECIFIC_FAILURE
17 16 HEADER_FAIL 6886470 6886470 0 16 0.0125 0.8805097957519517 5 2 1 2 2 0 1 1 0 111111000111000000111111111000000111000000000111000000000000000000000111000000000000000000000111000000000000111111000000000000000000111000000000 101111000111000000111111111000000111000000000111000000000011000000000111000000000000001100000111000000000000111111000000000000000000111000000000 110100111001000100010001000001010000110000001000 False VERSION_MISMATCH 101111000111000000111111111000000111000000000111000000000011000000000111000000000000001100000111000000000000111111000000000000000000111000000000 000111000000111111100000000101011110110001101000011101111000001111000110111101111011100000111001010010111111000000111111111111111011000111111111 4.7344866536019055 228.10491338016192 10.381403191597384 -5.646916537995478 1.6829380426891485 0 0.0 0 0.0 8.084601213892752 3.04749463363358 4.237156529516785 0.613962963260252 107 HEADER_SPECIFIC_FAILURE

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -0,0 +1,49 @@
packet,region,symbols,decision_errors,magnitude_median,magnitude_minimum,phase_error_rms_rad,imaginary_rms,timing_offset_samples
1,preamble_tail,128,0,1.0988442307313235,0.43466351049701235,0.36545432588063453,0.3677449037710503,0
1,header,144,3,1.0815752733984212,0.5778378379912865,0.6187439503436525,0.551502400297575,0
1,postheader,128,2,1.1114278978759744,0.4714742841146855,0.5693534448896019,0.49591231338100494,0
2,preamble_tail,128,0,1.074345037947809,0.5715381413183729,0.5169701760998907,0.4918784327994302,0
2,header,144,6,1.0888449278310801,0.4753465266196904,0.7542889272180515,0.6186207192551644,0
2,postheader,128,0,1.1317475637994039,0.6993167478293558,0.28345944315453764,0.2904885233790264,0
3,preamble_tail,128,0,1.0919580830559625,0.4931835747157359,0.577421183092019,0.5161252295458062,0
3,header,144,4,1.152609811941216,0.6541218073505881,0.5437712455230955,0.433109513511742,0
3,postheader,128,0,1.0857706086674181,0.3396593308737327,0.2976136824815135,0.3003548051915534,0
4,preamble_tail,128,0,1.1087294828126495,0.5024192881228802,0.6792582574914069,0.6647511818530001,0
4,header,144,0,1.1507766975854852,0.42562892480326897,0.3156584316410723,0.33839321792646554,0
4,postheader,128,0,1.1449814637127051,0.5937437256113064,0.29460252451816493,0.31949283720140587,0
5,preamble_tail,128,0,1.1434636342884739,0.6047967729049536,0.35172140313369066,0.3535407042323131,0
5,header,144,0,1.1363877434085625,0.6007022877000862,0.2522418948656545,0.27555358339271957,0
5,postheader,128,5,1.0966485328526976,0.41749527315450785,0.6464901825183261,0.5318845761533794,0
6,preamble_tail,128,0,1.1318097006554524,0.6221411610236426,0.2794053247219388,0.30212984078304644,0
6,header,144,0,1.118944116022563,0.604506255970942,0.4000248179092374,0.40617877592291496,0
6,postheader,128,3,1.1203373379450718,0.5733983281027794,0.6433269203677763,0.5585770337413266,0
7,preamble_tail,128,0,1.098335506453933,0.685298350349321,0.31267846128306165,0.3400209740040822,0
7,header,144,1,1.0859515485682385,0.4918795883455653,0.49770271058274784,0.48404835853198735,0
7,postheader,128,3,1.078419996569039,0.44698965664144213,0.5990105590866479,0.5112821191437632,0
8,preamble_tail,128,0,1.0950824513758386,0.5415446078858628,0.37054349208551474,0.38513707581929985,0
8,header,144,3,1.0904644019616199,0.43076194377790394,0.6094384014423195,0.5588536614362375,0
8,postheader,128,2,1.0935087479377619,0.63642176553416,0.4463244127331142,0.43911459515487505,0
9,preamble_tail,128,2,1.093901338967227,0.4388973792742324,0.5923392165896195,0.5322335060592657,0
9,header,144,4,1.1195324105485278,0.49998913621143454,0.611185029044535,0.5659527404173302,0
9,postheader,128,0,1.1053805607840526,0.640256963735712,0.28052596266122526,0.30630431218636367,0
10,preamble_tail,128,3,1.1419841905626784,0.5060536577715014,0.5971065417005673,0.5330612346503504,0
10,header,144,1,1.1147443336597755,0.6501217642416475,0.39358947394490806,0.40010760065192014,0
10,postheader,128,0,1.1787629415552199,0.42900718390148934,0.2926514547716184,0.3306690896219249,0
11,preamble_tail,128,3,1.1704570892176922,0.6573740193329803,0.6151666707460389,0.6107317885152251,0
11,header,144,0,1.12981219997058,0.5282686497447672,0.324658042677611,0.3384614869201178,0
11,postheader,128,0,1.1070044356208588,0.5046571226194821,0.33630657442006734,0.36220237044356646,0
12,preamble_tail,128,4,1.1293212243971127,0.5975355368621857,0.5056848722345468,0.41499438743931705,0
12,header,144,0,1.1346606346022847,0.37281496808234904,0.2862848068844218,0.3172306512537894,0
12,postheader,128,1,1.1452864327334882,0.4013942634977783,0.4893751135204076,0.4862028130220328,0
13,preamble_tail,128,0,1.1020405947443312,0.5476951608093663,0.26825405646139866,0.299908757841907,0
13,header,144,0,1.1246852022329477,0.5448659176501547,0.3819108989758959,0.3972670513029744,0
13,postheader,128,2,1.0925865889420296,0.5942311935828164,0.5526657411269684,0.47037502313805846,0
14,preamble_tail,128,0,1.0986885517578937,0.4240058786452209,0.307170345418273,0.30833136259021016,0
14,header,144,1,1.1117645619461933,0.5698477702591676,0.5701021956757241,0.5678681526072823,0
14,postheader,128,3,1.106509873733971,0.5370530426198264,0.594466571272217,0.5534673376824929,0
15,preamble_tail,128,1,1.0605799496659238,0.5096523999436898,0.4395937997414911,0.41506255958111626,0
15,header,144,7,1.0998344881084918,0.562650314086593,0.6887166853647746,0.5814901000470972,0
15,postheader,128,2,1.1227074410764701,0.5161407533490777,0.5946319825247028,0.5701686238399535,0
16,preamble_tail,128,2,1.1150803467611397,0.5398340206811254,0.5646446219736847,0.48272300998033535,0
16,header,144,5,1.1024025293008193,0.41214915514462663,0.6355591984079474,0.49483023185734204,0
16,postheader,128,0,1.1777412846771014,0.3344663773895672,0.3015102248779219,0.3386110581722476,0
1 packet region symbols decision_errors magnitude_median magnitude_minimum phase_error_rms_rad imaginary_rms timing_offset_samples
2 1 preamble_tail 128 0 1.0988442307313235 0.43466351049701235 0.36545432588063453 0.3677449037710503 0
3 1 header 144 3 1.0815752733984212 0.5778378379912865 0.6187439503436525 0.551502400297575 0
4 1 postheader 128 2 1.1114278978759744 0.4714742841146855 0.5693534448896019 0.49591231338100494 0
5 2 preamble_tail 128 0 1.074345037947809 0.5715381413183729 0.5169701760998907 0.4918784327994302 0
6 2 header 144 6 1.0888449278310801 0.4753465266196904 0.7542889272180515 0.6186207192551644 0
7 2 postheader 128 0 1.1317475637994039 0.6993167478293558 0.28345944315453764 0.2904885233790264 0
8 3 preamble_tail 128 0 1.0919580830559625 0.4931835747157359 0.577421183092019 0.5161252295458062 0
9 3 header 144 4 1.152609811941216 0.6541218073505881 0.5437712455230955 0.433109513511742 0
10 3 postheader 128 0 1.0857706086674181 0.3396593308737327 0.2976136824815135 0.3003548051915534 0
11 4 preamble_tail 128 0 1.1087294828126495 0.5024192881228802 0.6792582574914069 0.6647511818530001 0
12 4 header 144 0 1.1507766975854852 0.42562892480326897 0.3156584316410723 0.33839321792646554 0
13 4 postheader 128 0 1.1449814637127051 0.5937437256113064 0.29460252451816493 0.31949283720140587 0
14 5 preamble_tail 128 0 1.1434636342884739 0.6047967729049536 0.35172140313369066 0.3535407042323131 0
15 5 header 144 0 1.1363877434085625 0.6007022877000862 0.2522418948656545 0.27555358339271957 0
16 5 postheader 128 5 1.0966485328526976 0.41749527315450785 0.6464901825183261 0.5318845761533794 0
17 6 preamble_tail 128 0 1.1318097006554524 0.6221411610236426 0.2794053247219388 0.30212984078304644 0
18 6 header 144 0 1.118944116022563 0.604506255970942 0.4000248179092374 0.40617877592291496 0
19 6 postheader 128 3 1.1203373379450718 0.5733983281027794 0.6433269203677763 0.5585770337413266 0
20 7 preamble_tail 128 0 1.098335506453933 0.685298350349321 0.31267846128306165 0.3400209740040822 0
21 7 header 144 1 1.0859515485682385 0.4918795883455653 0.49770271058274784 0.48404835853198735 0
22 7 postheader 128 3 1.078419996569039 0.44698965664144213 0.5990105590866479 0.5112821191437632 0
23 8 preamble_tail 128 0 1.0950824513758386 0.5415446078858628 0.37054349208551474 0.38513707581929985 0
24 8 header 144 3 1.0904644019616199 0.43076194377790394 0.6094384014423195 0.5588536614362375 0
25 8 postheader 128 2 1.0935087479377619 0.63642176553416 0.4463244127331142 0.43911459515487505 0
26 9 preamble_tail 128 2 1.093901338967227 0.4388973792742324 0.5923392165896195 0.5322335060592657 0
27 9 header 144 4 1.1195324105485278 0.49998913621143454 0.611185029044535 0.5659527404173302 0
28 9 postheader 128 0 1.1053805607840526 0.640256963735712 0.28052596266122526 0.30630431218636367 0
29 10 preamble_tail 128 3 1.1419841905626784 0.5060536577715014 0.5971065417005673 0.5330612346503504 0
30 10 header 144 1 1.1147443336597755 0.6501217642416475 0.39358947394490806 0.40010760065192014 0
31 10 postheader 128 0 1.1787629415552199 0.42900718390148934 0.2926514547716184 0.3306690896219249 0
32 11 preamble_tail 128 3 1.1704570892176922 0.6573740193329803 0.6151666707460389 0.6107317885152251 0
33 11 header 144 0 1.12981219997058 0.5282686497447672 0.324658042677611 0.3384614869201178 0
34 11 postheader 128 0 1.1070044356208588 0.5046571226194821 0.33630657442006734 0.36220237044356646 0
35 12 preamble_tail 128 4 1.1293212243971127 0.5975355368621857 0.5056848722345468 0.41499438743931705 0
36 12 header 144 0 1.1346606346022847 0.37281496808234904 0.2862848068844218 0.3172306512537894 0
37 12 postheader 128 1 1.1452864327334882 0.4013942634977783 0.4893751135204076 0.4862028130220328 0
38 13 preamble_tail 128 0 1.1020405947443312 0.5476951608093663 0.26825405646139866 0.299908757841907 0
39 13 header 144 0 1.1246852022329477 0.5448659176501547 0.3819108989758959 0.3972670513029744 0
40 13 postheader 128 2 1.0925865889420296 0.5942311935828164 0.5526657411269684 0.47037502313805846 0
41 14 preamble_tail 128 0 1.0986885517578937 0.4240058786452209 0.307170345418273 0.30833136259021016 0
42 14 header 144 1 1.1117645619461933 0.5698477702591676 0.5701021956757241 0.5678681526072823 0
43 14 postheader 128 3 1.106509873733971 0.5370530426198264 0.594466571272217 0.5534673376824929 0
44 15 preamble_tail 128 1 1.0605799496659238 0.5096523999436898 0.4395937997414911 0.41506255958111626 0
45 15 header 144 7 1.0998344881084918 0.562650314086593 0.6887166853647746 0.5814901000470972 0
46 15 postheader 128 2 1.1227074410764701 0.5161407533490777 0.5946319825247028 0.5701686238399535 0
47 16 preamble_tail 128 2 1.1150803467611397 0.5398340206811254 0.5646446219736847 0.48272300998033535 0
48 16 header 144 5 1.1024025293008193 0.41214915514462663 0.6355591984079474 0.49483023185734204 0
49 16 postheader 128 0 1.1777412846771014 0.3344663773895672 0.3015102248779219 0.3386110581722476 0

File diff suppressed because it is too large Load Diff

View File

@@ -570,3 +570,174 @@
[synthetic CSV](../data/processed/lab061/synthetic_packet_results.csv). [synthetic CSV](../data/processed/lab061/synthetic_packet_results.csv).
- **STOP:** Lab061 фиксируется этим отдельным коммитом; push выполняется - **STOP:** Lab061 фиксируется этим отдельным коммитом; push выполняется
пользователем отдельно, Lab062 не создана. пользователем отдельно, Lab062 не создана.
## Lab062 — полный 500K PHY-пакет, подготовка и RX-only preflight
- **Запись 056; RF TX=0.** Подготовлены16 пакетов по256 байт payload,
0,184512с. Legacy/T2 дали16/16 строгих HEADER/FEC/CRC и точных payload.
- **Геометрия:**1400МГц, примерно1,2м, LOS в помещении; TX возле окна, RX на
столе, одинаковая поляризация, антенны и кабели неподвижны.
- **Аппаратный preflight PASS:** MASTER/SLAVE reg29=0x26, SLAVE CLKIN=DETECTED
через133,5795мс. RX-only:800000 отсчётов, RMS2,314058, AC RMS0,985483,
max|I|/|Q|=6/8, clipping0, overruns0, сильного фона нет.
- **Проверки:** quick gate962/35/13 PASS, pytest962 passed. Усиления10/24/24дБ
сохранены; аналоговая компрессия без прибора остаётся неизвестной.
- [План](lab062_current_state.md), [отчёт](lab062_rx_preflight.md),
[software](../data/processed/lab062/software_gate.json),
[preflight](../data/processed/lab062/preflight_result.json).
- **STOP:** технически готово к одному TX, но отдельного разрешения ещё нет.
Lab062 не коммитировалась, push не выполнялся, Lab063 не создана.
- **Единственный RF-сеанс:** выполнен один TX без повторов. RX сохранён полностью: 24 000 000
комплексных отсчётов, 3,000 с, overruns 0, clipping 0. В TX-журнале зарегистрирован
промежуточный `1 underruns, longest 16672 bytes`, поэтому сеанс признан невалидным для чистого
A/B-сравнения. Legacy/T2 дали одинаковый пакетный итог 0/16, T2 gain 0.
- [RF-отчёт](lab062_rf_result.md),
[JSON](../data/processed/lab062/rf_analysis.json),
[покадровый CSV](../data/processed/lab062/packet_comparison.csv).
- **Текущее состояние:** `RF TX=0`; повтор не выполнялся, Lab062 не закоммичена, push не
выполнялся, Lab063 не создана. Следующий шаг требует отдельного согласования.
## Lab063: офлайн-локализация TX underrun и ухудшения Lab062
- **Запись 058; только сохранённые TX/RX, RF TX=0.** Lab062 перед анализом зафиксирована
коммитом `f8ae6c6bfceaa21b6c08dcf55d2bff996dd0dae5`; её статус
`RF_SESSION_INVALID_TX_UNDERRUN` сохранён.
- **Фактические паузы:** 92 256 × 16 = 1 476 096 отсчётов, поэтому дополнительных пауз между
полными packet waveform нет. Причина: ошибка реализации `prepare()`, пакеты записаны подряд
без параметра паузы и без вставки нулей.
- **Масштаб журнала:** 16 672 байта cs8 = 8 336 комплексных отсчётов = 1,042 мс = 521 символ =
9,035727% одного waveform. RX не подтверждает потерю или повтор именно такого числа отсчётов.
- **Локальное сопоставление:** 221 надёжное окно из 359, задержка 0…1 отсчёт, скачков нет.
Ещё 22 внутренних окна пакетов3,4,12,13 имеют корреляцию ниже0,15; задержка там не
установлена. `UNDERRUN LOCATION=NOT_LOCALIZED_FROM_RX`. Повторяющаяся преамбула с
корреляционными копиями и низкокорреляционные окна исключены из решения о разрыве.
- **Качество:** все 16 пакетов хуже Lab056 B по SER, EVM и matched/residual. Пакеты 3,4,12,13
имеют дополнительные всплески AC-мощности и остатка при почти постоянном локальном |h|;
пакет14 общего признака с ними не показывает. Итог: `GLOBAL_RF_DEGRADATION`, причина
`PARTIALLY_LOCALIZED`.
- **RX-уровень:** AC RMS0,760816…2,032438 кода, max|I|=3…6, max|Q|=4…7. Сильная аналоговая
перегрузка менее вероятна, но без прибора не исключена. Значение расхождения счётчиков
`hackrf_transfer` локально не установлено: `COUNTER SEMANTICS=NOT_ESTABLISHED`.
- [Текущее состояние](lab063_current_state.md), [отчёт](lab063_offline_result.md),
[JSON](../data/processed/lab063/summary.json),
[пакеты CSV](../data/processed/lab063/packet_quality.csv),
[локальное сопоставление CSV](../data/processed/lab063/local_alignment.csv).
- **STOP:** Lab063 не коммитировалась, push не выполнялся, Lab064 не создана. Следующий шаг
требует отдельного согласования; RF TX=0.
## Lab064: измерение уровня и линейности RF-тракта
- **Запись 059; подготовка и RX-only, RF TX=0.** Создан один 0,75-секундный
PRBS7/BPSK/RRC waveform с четырьмя 100-мс участками −18/−12/−6/0 дБ,
промежутками по 50 мс и нулями по 100 мс в начале и конце.
- **Цифровые уровни:** RMS 5,556137/11,056978/22,056892/44,000457 кода; шаги
+5,977270/+5,998157/+5,998257 дБ; max |I|/|Q| не выше 69/69, clipping0.
- **Методика:** пакетный приёмник, FEC, CRC, T2 и JPEG не используются. Главная
величина — мощность согласованной с известным TX составляющей. Анализатор
выдаёт `INVALID_CAPTURE` без A/B/C при любом промежуточном underrun, overrun
или clipping.
- **Аппаратный preflight PASS:** MASTER/SLAVE reg29=0x26, SLAVE CLKIN=DETECTED
при первом опросе через66,793мс. RX-only:800000 отсчётов, полный RMS2,193193,
AC RMS0,832038, max|I|/|Q|=4/5, clipping0, overruns0, сильного фона нет.
- **Проверки:** quick gate984/37/13 PASS, pytest984 passed, целевые13 passed,
независимая read-only проверка чистая.
- [Текущее состояние](lab064_current_state.md), [отчёт](lab064_rx_preflight.md),
[подготовка](../data/processed/lab064/preparation.json),
[software gate](../data/processed/lab064/software_gate.json),
[preflight](../data/processed/lab064/preflight_result.json).
- **STOP:** технически готово к одному TX, но отдельного разрешения ещё нет.
Lab064 не коммитируется, push не выполняется, Lab065 не начинается.
- **Единственный RF-сеанс:** один TX, повторов0, underruns0, overruns0,
clipping0; RX16000000 отсчётов за2,0с. Фон стабилен: AC RMS
0,718264…0,728217 кода, разброс0,119530дБ.
- **Линейность:** L0→L1/L1→L2/L2→L3 дали ошибки
−0,017501/−0,169270/+0,022162дБ. Полный рост TX/RX равен
17,973685/17,809077дБ, общая ошибка −0,164609дБ. Признака компрессии нет.
- **Итог `LINEAR_BUT_WEAK`:** L3 matched/residual равен −12,133336дБ. Тракт
следует цифровым ступеням, но согласованная полезная составляющая остаётся
слабее остатка. [RF-отчёт](lab064_rf_result.md),
[RF JSON](../data/processed/lab064/rf_result.json),
[capture JSON](../data/processed/lab064/capture_result.json).
- **Текущее состояние:** `RF TX=0`, процессы CLEAR; второй TX не выполнялся,
Lab064 не коммитировалась, push не выполнялся, Lab065 не создана.
- **Независимая проверка:** прямой пересчёт из TX/RX CS8 подтвердил все SHA,
счётчики, фоны, matched/residual/`h`, ступени и спектральные полосы;
расхождений нет. Quick gate и pytest после RF:986 passed,0 failed.
## Lab065: измерение уровня при TX VGA 20 дБ
- **База:** Lab064 зафиксирована коммитом
`cff226e0bf9e36a627829ea11a4ca3292ae20953`; push не выполнялся.
- **Единственное изменение параметра:** TX VGA 10 → 20 дБ. Частота 1400 МГц,
RX LNA/VGA 24/24 дБ, усилители, геометрия, антенны и кабели сохранены.
- **Waveform:** точная копия Lab064, 6000000 отсчётов, 0,75 с; SHA-256
`fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9`.
- **Подготовлено:** RX-first runner, максимальные счётчики потерь, сравнение
линейности внутри Lab065 и по одинаковым уровням Lab064/Lab065, численные
правила классификации. Software gate PASS.
- **RX-only preflight:** обе HackRF и роли подтверждены, reg29=0x26 у MASTER и
SLAVE, CLKIN обнаружен на третьем опросе через201,986мс. Фон:800000 отсчётов,
AC RMS1,056565 кода, max|I|/|Q|=6/8, clipping0, overruns0. Cleanup PASS.
- **Граница:** `RF TX=0`. Lab065 не коммитировалась. Нужны рассмотрение
подготовки и отдельное прямое разрешение на один TX; Lab066 не начинать.
- [Текущее состояние](lab065_current_state.md),
[RX-only отчёт](lab065_rx_preflight.md),
[подготовка](../data/processed/lab065/preparation.json),
[software gate](../data/processed/lab065/software_gate.json),
[preflight](../data/processed/lab065/preflight_result.json).
- **Единственный RF-сеанс:** TX1, автоматических повторов0; underrun/overrun/
clipping0, cleanup PASS, процессы CLEAR. RX16000000 отсчётов, SHA-256
`845d7b7dcaef70e179ab69e6ba0041601859630786d2f4d51c16a8c1c7869d7e`.
- **Линейность:** ошибки ступеней −0,077363/+0,034934/−0,013858дБ, компрессии
L2/L3 нет. Медианный прирост matched power+11,233489дБ, изменение остатка
+0,517004дБ, улучшение matched/residual+10,734495дБ.
- **Результат:** `LINEAR_GAIN_IMPROVEMENT`. Фон стабилен; диагностические полосы
остатка растут слабее matched power. [RF-отчёт](lab065_rf_result.md),
[RF JSON](../data/processed/lab065/rf_result.json),
[capture JSON](../data/processed/lab065/capture_result.json).
- **STOP:** `RF TX=0`; повторов и изменения усилений не было. Lab065 не
коммитировалась, push отсутствует, Lab066 не создана.
- **Независимая проверка:** прямой пересчёт CS8 подтвердил SHA, счётчики,
локализацию, фон, matched/residual, `h`, CFO и спектральные полосы. Расхождений
нет. Quick gate1000/38/13 PASS, pytest1000 passed, diff check PASS.
- **Фиксация:** Lab065 зафиксирована локальным коммитом
`dacf04f2d0a15c0c1b56a7fb527db61fc2e38462`; push не выполнялся.
## Lab066 — исправленный повтор полного 500K PHY-сеанса
- **Основание:** Lab062 остаётся `RF_SESSION_INVALID_TX_UNDERRUN`, legacy/T2
0/16. Lab066 исправляет отсутствовавшие межпакетные паузы и использует
максимальный наблюдавшийся счётчик потерь.
- **TX:** 16 полных PHY-пакетов по256 байт, packet waveform92256 отсчётов;
15 нулевых пауз по40000 отсчётов/5мс и guards по800000 отсчётов/100мс.
Всего3676096 отсчётов,0,459512с; SHA-256
`621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199`.
- **Параметры:** 1400МГц, Fs8Мвыб/с,500ксимв/с, несущая+50кГц,
TX VGA20дБ, RX LNA/VGA24/24дБ, amplifier/Bias-Tee OFF; прежняя геометрия.
- **Software gate:** legacy и T2 независимо дали16/16 HEADER/FEC/CRC,
packet output и точных упорядоченных payload. Fallback отсутствует; T2
инициализируется по собственной преамбуле каждого пакета.
- **RX-only preflight:** MASTER/SLAVE reg29=0x26, CLKIN DETECTED через132,113мс;
AC RMS0,827637, max|I|/|Q|=4/5, clipping0, maximum overruns0. Cleanup PASS,
процессы CLEAR.
- **Проверки:** quick gate1013/39/13 PASS, pytest1013 passed, diff check PASS;
verifier и adversary не оставили открытых замечаний.
- [Состояние](lab066_current_state.md), [RX-only отчёт](lab066_rx_preflight.md),
[подготовка](../data/processed/lab066/preparation.json),
[software gate](../data/processed/lab066/software_gate.json),
[preflight](../data/processed/lab066/preflight_result.json).
- **STOP:** RF TX=0; требуется отдельное прямое разрешение на один TX. Lab066
не коммитировалась, push не выполнялся, Lab067 не создавалась.
- **Единственный RF-сеанс:** один TX, повторов0; maximum underrun/overrun0/0,
clipping0, cleanup PASS, процессы CLEAR. RX16000000 отсчётов, SHA-256
`72ff7ddd8b30baa4a5c066361ca1f8dfa664f1da37f65c0c373b211ce6cf00f0`.
- **Строгий результат:** legacy и T2 совпали — по10/16 точных пакетов;
приняты4–8 и10–14, отказали на header пакеты1–3,9,15,16. Выигрыша T2 нет.
- **Физическое качество:** SER0,011047, RMS0,528374, matched/residual
+5,542117дБ, медианная неравномерность2,870070дБ. Все четыре показателя лучше
Lab056 B и невалидной Lab062.
- **Итог:** `PARTIAL_PACKET_RECOVERY_NO_T2_GAIN`. [RF-отчёт](lab066_rf_result.md),
[RF summary](../data/processed/lab066/rf_summary.json),
[packet CSV](../data/processed/lab066/packet_comparison.csv).
- **После сеанса:** RF TX=0, второй TX не выполнялся. Lab066 не
коммитировалась, push не выполнялся, Lab067 не создавалась.

View File

@@ -0,0 +1,48 @@
# Lab062 — полный пакет 500K, подготовка к одному RF-сеансу
Lab062 проверяет T2 на полном штатном PHY-пакете в одном будущем коротком
эфирном сеансе. На текущем этапе разрешены подготовка, программный шлюз,
аппаратная проверка общей опоры и RX-only запись фона. Передача запрещена до
отдельного разрешения пользователя.
## Неподвижная физическая схема
| Условие | Фактическое значение |
|---|---|
| Частота | 1400000000 Гц, только для Lab062 |
| Расстояние TX–RX | примерно 1,2 м |
| Геометрия | прямая видимость, помещение |
| TX | плата и антенна возле окна |
| RX | плата и антенна на столе пользователя |
| Антенны | имеющиеся антенны на 1400 МГц, неподвижны |
| Поляризация | одинаковая |
| Тактирование | 10 МГц TCXO → MASTER → MASTER CLKOUT → SLAVE CLKIN |
Длинный кабель общей опоры, USB-подключение, антенны и остальные кабели не
перемещаются. Пользователь по возможности не проходит между антеннами. Во время
будущего сеанса не меняются частота, усиления, ориентация и PHY.
## Параметры
- 16 полных пакетов, payload каждого — 256 байт;
- BPSK, 500000 символов/с, Fs 8000000 выборок/с, 16 выборок/символ;
- центральная частота 1400 МГц, цифровая несущая +50 кГц;
- TX VGA 10 дБ, RX LNA/VGA 24/24 дБ;
- RF amplifier и Bias-Tee выключены;
- один конечный TX-waveform и одна будущая RX-запись;
- режим приёмника задаётся заранее: `legacy` или `t2`, без CRC-fallback.
RX-only preflight не меняет усиления. Он проверяет rail-коды, overruns,
максимальные |I|/|Q|, полный и AC RMS, сильный фон и ошибки аппаратных команд.
Эвристический STOP для неожиданно сильного цифрового фона: AC RMS не менее 20
кодов или максимум |I|/|Q| не менее 100 кодов. Отсутствие цифрового клиппинга
не доказывает отсутствие аналоговой компрессии.
Обязательная аппаратная точка: MASTER reg29=0x26, SLAVE reg29=0x26 и SLAVE
CLKIN=DETECTED. Любой отказ означает `RF TX = 0` и STOP.
Lab062 не коммитируется. Push не выполняется. Lab063 не создаётся автоматически.
## Фактический RF-результат
14 сентября 2026 года выполнен ровно один разрешённый TX-сеанс. Полная RX-запись сохранена, но в промежуточной строке `hackrf_transfer` зарегистрирован `1 underruns, longest 16672 bytes`. Повтор не выполнялся. Строгие `legacy` и `t2` на одной записи дали 0/16 CRC и пакетов; T2 gain равен 0. Подробности и покадровая таблица приведены в [отчёте](lab062_rf_result.md). Текущий статус: `RF TX = 0`, Lab062 не закоммичена, push не выполнялся, Lab063 не создана.

108
docs/lab062_rf_result.md Normal file
View File

@@ -0,0 +1,108 @@
# Lab062 — результат единственного RF-сеанса
Передача была запущена один раз. Приёмник сохранил полную трёхсекундную IQ-запись без переполнений и цифрового клиппинга. Однако `hackrf_transfer` во время передачи сообщил об одном кратком underrun: буфер передатчика один раз опустел на интервал до 16 672 байт. В итоговой строке утилита напечатала ноль underrun, но промежуточную ненулевую строку игнорировать нельзя. Поэтому этот сеанс нельзя считать чистым сравнением `legacy` и `t2`.
Оба строгих варианта приёмника обработали одну и ту же запись и выдали 0 из 16 пакетов. T2 не дал выигрыша в пакетах. Установлено, что передача состоялась, общий тактовый сигнал перед ней был исправен, RX-файл полный, а строгий результат равен 0/16 в обоих режимах. Нельзя установить, каким был бы результат без underrun, и нельзя приписывать все ошибки самому T2 или эфирному каналу. Аналоговая компрессия также остаётся неизвестной без измерительного прибора.
## Условия
| Параметр | Значение |
|---|---:|
| RF | 1 400 000 000 Гц |
| Символьная скорость | 500 000 символов/с |
| Частота дискретизации | 8 000 000 комплексных отсчётов/с |
| Цифровая несущая | +50 000 Гц |
| Пакеты | 16 полных PHY-пакетов по 256 байт payload |
| TX | 1 476 096 отсчётов, 0,184512 с, VGA 10 дБ |
| RX | LNA/VGA 24/24 дБ, 3 с |
| RF amplifier / Bias-Tee | OFF / OFF |
| Геометрия | около 1,2 м, LOS, помещение; TX возле окна, RX на столе |
| Антенны | имеющиеся антенны на 1400 МГц, одинаковая поляризация, неподвижны |
| Опора | 10 МГц TCXO → MASTER → MASTER CLKOUT → SLAVE CLKIN |
SHA-256 передаваемого файла: `e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5`.
## Аппаратный результат
- перед TX повторно получены `MASTER reg29 = 0x26`, `SLAVE reg29 = 0x26`, `SLAVE CLKIN = DETECTED`;
- выполнен один TX-сеанс, автоматических повторов нет;
- RX: 24 000 000 комплексных отсчётов, 48 000 000 байт, 3,000 с;
- SHA-256 RX: `ce0bd603e4ca356af67d504ee11c9e9f38171f31c7427fbe61216a28126b2b32`;
- RX overruns: 0 во всех пяти строках журнала;
- RX clipping: 0;
- TX underruns: промежуточный максимум 1, `longest 16672 bytes`; финальная строка — 0;
- cleanup: оба CLKOUT выключены без зарегистрированных ошибок, SDR-процессы после сеанса — `CLEAR`;
- текущее состояние: `RF TX = 0`.
Из-за ненулевой промежуточной строки underrun статус сеанса: `INVALID_TX_UNDERRUN`. Полученные файлы сохранены, повтор не выполнялся.
## Строгое декодирование одной записи
| Стадия | legacy | T2 |
|---|---:|---:|
| CANDIDATES | 144 | 144 |
| TRUE PACKETS FOUND | 0 | 0 |
| HEADER ACCEPTED | 3 | 3 |
| FEC STARTED | 3 | 3 |
| FEC PASS | 3 | 3 |
| CRC STARTED | 3 | 3 |
| CRC PASS | 0 | 0 |
| PACKET OUTPUT | 0 | 0 |
| EXACT PAYLOAD MATCH | 0 | 0 |
Детектор в обоих запусках получил 209 956 первичных кандидатов, дешёвая ступень отклонила 209 812, после группировки строгий декодер проверил 144 кандидата. Переполнения очереди кандидатов не было. Никакого fallback между `legacy` и `t2` не выполнялось.
- `PASSED BY BOTH = []`
- `PASSED ONLY BY LEGACY = []`
- `PASSED ONLY BY T2 = []`
- `FAILED BY BOTH = [1, 2, …, 16]`
## Таблица 16 фактических границ
Начало потока найдено только после строгого вердикта корреляцией с первым TX-пакетом: отсчёт 4 256 091, отношение пика к медиане 21,739. Знание TX не передавалось детектору и не использовалось для повторной настройки приёмника. Во всех строках `H/F/C/O` означают header/FEC/CRC/output; `1` — проход, `0` — непроход. Ошибки символов и оценки частоты — диагностические, по известной границе и известным переданным символам.
| № | legacy H/F/C/O | T2 H/F/C/O | Preamble errors | Header errors | Payload errors до FEC | CFO нач., Гц | T2 фин., Гц | T2 lock |
|---:|:---:|:---:|---:|---:|---:|---:|---:|:---:|
| 1 | 0/0/0/0 | 0/0/0/0 | 108 | 20 | 367 | -2.511 | +1.939 | не определён |
| 2 | 0/0/0/0 | 0/0/0/0 | 135 | 11 | 377 | +16.850 | -2.223 | не определён |
| 3 | 0/0/0/0 | 0/0/0/0 | 466 | 115 | 2229 | -266.238 | -265.796 | не определён |
| 4 | 0/0/0/0 | 0/0/0/0 | 515 | 104 | 2266 | +297.250 | +293.800 | не определён |
| 5 | 0/0/0/0 | 0/0/0/0 | 108 | 27 | 369 | -1.712 | -0.835 | не определён |
| 6 | 1/1/0/0 | 1/1/0/0 | 112 | 10 | 345 | +4.676 | -3.164 | не определён |
| 7 | 0/0/0/0 | 0/0/0/0 | 113 | 7 | 344 | +2.113 | +1.094 | не определён |
| 8 | 0/0/0/0 | 0/0/0/0 | 91 | 19 | 368 | +0.964 | +0.354 | не определён |
| 9 | 0/0/0/0 | 0/0/0/0 | 105 | 21 | 367 | -2.679 | +0.191 | не определён |
| 10 | 0/0/0/0 | 0/0/0/0 | 116 | 7 | 345 | -0.290 | +0.947 | не определён |
| 11 | 0/0/0/0 | 1/1/0/0 | 109 | 9 | 392 | +0.757 | -0.142 | не определён |
| 12 | 0/0/0/0 | 0/0/0/0 | 297 | 110 | 2181 | -223.050 | -222.389 | не определён |
| 13 | 0/0/0/0 | 0/0/0/0 | 304 | 36 | 524 | -0.161 | -2.081 | не определён |
| 14 | 1/1/0/0 | 0/0/0/0 | 314 | 127 | 2091 | +228.209 | +224.928 | не определён |
| 15 | 1/1/0/0 | 1/1/0/0 | 131 | 7 | 395 | -9.960 | +2.284 | не определён |
| 16 | 0/0/0/0 | 0/0/0/0 | 100 | 23 | 355 | +13.157 | -0.868 | не определён |
В реализации T2 нет отдельного детектора lock, поэтому поле нельзя честно заменить на `PASS` или `FAIL`. Сохранены начальное состояние частоты и конечное состояние петли.
## Физическое качество по методике Lab058
Функции `analyze_values` и `channel_metrics` из Lab058 применены отдельно к каждому полному пакету. Для оценки использованы диагностические границы и чередующиеся обучающие/проверочные участки с защитными краями. Это измерение сделано после строгого результата и не меняет 0/16.
| Метрика | Lab062 | Lab056, 500K | Разница по смыслу |
|---|---:|---:|---|
| Диагностическая доля ошибочных символов | 0,099287 | 0,034959 | Lab062 хуже |
| Нормированное RMS-отклонение, EVM | 1,220401 | 0,845350 | Lab062 хуже |
| Matched/residual | -1,730051 дБ | +1,464846 дБ | Lab062 хуже на 3,194897 дБ |
| Неравномерность усиления, p95–p05 | медиана 6,660341 дБ | среднее 5,471382 дБ | Lab062 больше |
Для Lab062 разброс неравномерности между пакетами составил 6,236828…10,617549 дБ. Остаток включает шум, искажения канала и возможное влияние underrun; называть его чистым шумом нельзя. Отдельная диагностика именно выходных символов T2 дала SER 0,186626 и RMS 1,699461; это другой срез данных, поэтому он не подменяет приведённые выше сопоставимые метрики Lab058.
## Инженерный вывод
Чистое сравнение `legacy` и T2 не состоялось из-за зафиксированного TX underrun. Фактический строгий результат существующей записи — 0/16 для обоих режимов, выигрыш T2 равен нулю. В записи видны неоднородные повреждения пакетов и заметно худшее качество символов, чем у 500K-сегментов Lab056, но эти наблюдения нельзя отделить от аппаратной ошибки передачи.
Следующий одиночный шаг: без RF локализовать момент underrun относительно границ пакетов и проверить, совместимы ли провалы качества с его положением. Новый RF-сеанс, Lab063, изменение PHY или усилений этим отчётом не разрешаются.
`LAB062 COMMIT = NOT PERFORMED`
`PUSH = NOT PERFORMED`
`RF TX = 0`

108
docs/lab062_rx_preflight.md Normal file
View File

@@ -0,0 +1,108 @@
# Lab062 — подготовка и RX-only preflight
14 сентября 2026 года выполнена подготовка полного 500K PHY-сеанса и одна
аппаратная проверка при выключенном передатчике. Результат preflight — PASS.
Передача не запускалась: `RF TX = 0`.
## Условия
| Параметр | Значение |
|---|---|
| Центральная частота | 1400000000 Гц |
| Скорость символов | 500000 символов/с |
| Частота дискретизации | 8000000 выборок/с |
| Пакеты | 16 полных PHY-пакетов |
| Payload | 256 байт в каждом пакете |
| TX VGA | 10 дБ |
| RX LNA / VGA | 24 / 24 дБ |
| RF amplifier / Bias-Tee | выключены |
| Расстояние TX–RX | примерно 1,2 м |
| Геометрия | прямая видимость, помещение |
| TX | плата и антенна возле окна |
| RX | плата и антенна на столе пользователя |
| Антенны | имеющиеся антенны на 1400 МГц, неподвижны |
| Поляризация | одинаковая |
| Общая опора | 10 МГц TCXO → MASTER → MASTER CLKOUT → SLAVE CLKIN |
Длинный clock-кабель и USB-схема не менялись. Антенны, кабели, ориентация,
частота, усиления и PHY должны остаться неизменными до будущего разрешённого
сеанса.
## Программная проверка
Создан один waveform из 16 пакетов. Его длина — 1476096 комплексных отсчётов,
2952192 байта и 0,184512 с. SHA-256:
`e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5`.
Строгий приёмник в заранее выбранных режимах дал:
| Режим | Header | FEC | CRC | Точный payload и порядок |
|---|---:|---:|---:|---:|
| legacy | 16/16 | 16/16 | 16/16 | 16/16 |
| T2 | 16/16 | 16/16 | 16/16 | 16/16 |
Автоматического повторного декодирования по результату CRC нет.
## Общая опора и RX-only фон
Свежая инвентаризация подтвердила обе HackRF One r9 с firmware/libhackrf
2024.02.1. Роли сохранены:
- MASTER `000000000000000097c063dc323b97d3`;
- SLAVE `000000000000000097c063dc2e5327d3`.
Аппаратная проверка получила:
```text
MASTER reg29 = 0x26
SLAVE reg29 = 0x26
SLAVE CLKIN = DETECTED
CLKIN query = 2
time to detect = 133.5795 ms
```
Первый опрос SLAVE ещё показывал отсутствие опоры, второй штатный опрос её
обнаружил. После этого SLAVE записал 800000 комплексных отсчётов, 0,1 с, при
1400 МГц и RX LNA/VGA 24/24 дБ.
| Метрика RX-only записи | Значение |
|---|---:|
| Полный RMS IQ | 2,314058 кода |
| AC RMS после удаления среднего | 0,985483 кода |
| Средние I / Q | 0,966063 / 1,857529 кода |
| Максимум \|I\| / \|Q\| | 6 / 8 кодов |
| Максимальная комплексная амплитуда | 8,246211 кода |
| Цифровой clipping | 0 / 800000 отсчётов |
| RX overruns | 0 |
| Неожиданно сильный сигнал | нет |
Сильным цифровым фоном считался бы AC RMS не менее 20 кодов или максимум
`|I|/|Q|` не менее 100 кодов. Оба показателя значительно ниже порога.
Отсутствие rail-кодов не доказывает отсутствия аналоговой компрессии при
будущем TX. Абсолютная RF-мощность без измерительного прибора также неизвестна.
Усиления по результату preflight не менялись.
Унаследованное от Lab056 поле энергии на символ исключено из обработанной
сводки: у фоновой записи нет символов, поэтому такая величина к ней неприменима.
Сырой аппаратный JSON сохранён без переписывания; это поле не участвовало в
решении PASS.
SHA-256 RX-only записи:
`4cc0ceef5a95f84e5aa0c232d14ff1123efd307494b5c8a5646854be912fdbca`.
После записи оба CLKOUT выключены без ошибок. Проверка процессов до и после
дала `CLEAR`. Вызовов `hackrf_transfer -t` не было. Эксклюзивный маркер
preflight запрещает его автоматический повтор.
Артефакты:
- [подготовка](../data/processed/lab062/preparation.json);
- [программный шлюз](../data/processed/lab062/software_gate.json);
- [результат preflight](../data/processed/lab062/preflight_result.json);
- исходные TX и RX-only CS8 находятся в `data/raw/lab062/` и в Git не входят.
`READY FOR SINGLE LAB062 TX = YES` означает только техническую готовность.
Отдельного разрешения на передачу ещё нет. `RF TX = 0`. STOP.
Lab062 не коммитируется. Push не выполняется. Lab063 не создаётся автоматически.

View File

@@ -0,0 +1,78 @@
# Lab063: текущее состояние
## Статус
Lab063 выполнена полностью офлайн по сохранённым файлам единственного RF-сеанса Lab062. Новых передач, запросов к HackRF и аппаратных команд не было.
- `LAB063 STATUS = COMPLETED_OFFLINE`
- `RF TX = 0`
- `LAB063 COMMIT = NOT PERFORMED`
- `PUSH = NOT PERFORMED`
- `LAB064 = NOT CREATED`
Lab062 перед началом анализа зафиксирована отдельным коммитом:
- `LAB062 COMMIT = f8ae6c6bfceaa21b6c08dcf55d2bff996dd0dae5`
- `NEW HEAD = f8ae6c6bfceaa21b6c08dcf55d2bff996dd0dae5`
- сообщение: `Lab062: record invalidated 500 ksymbol/s RF packet trial`
Статус аппаратного опыта сохранён без изменения: `RF_SESSION_INVALID_TX_UNDERRUN`. Результат `legacy = 0/16` и `T2 = 0/16` не переобъявлялся как валидное сравнение приёмников.
## Исходные данные
Анализ использует только сохранённые файлы Lab062:
| Объект | Значение |
|---|---|
| TX | `data/raw/lab062/tx_stream.cs8` |
| TX SHA-256 | `e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5` |
| TX | 1 476 096 комплексных отсчётов |
| RX | `data/raw/lab062/rx_stream.cs8` |
| RX SHA-256 | `ce0bd603e4ca356af67d504ee11c9e9f38171f31c7427fbe61216a28126b2b32` |
| RX | 24 000 000 комплексных отсчётов |
| Начало TX в RX | отсчёт 4 256 091 |
| Частота дискретизации | 8 Мвыб/с |
| Символьная скорость | 500 ксимв/с |
| Пакетов | 16 |
| Длина одного полного waveform | 92 256 отсчётов |
Физическое устройство и ответ программного интерфейса записаны отдельно:
- `PHYSICAL DEVICE = Auron HackRF Plus`
- `API/FIRMWARE IDENTIFICATION = HackRF One r9`
## Зафиксированный результат
Фактический TX-файл содержит пакеты вплотную: `92 256 × 16 = 1 476 096`. Дополнительных пауз между полными waveform нет. Внутренние защитные участки и хвосты RRC каждого пакета сохранены.
`INTER-PACKET GAP ACTUAL = 0 additional samples = 0 s`
Причина установлена по `prepare()` в `experiments/lab062_full_packet_rf_preflight.py`: шестнадцать результатов `build_parameterized_tx_cs8(...)` записываются подряд, параметра паузы и записи нулей между ними нет. Это ошибка реализации подготовленного потока Lab062, а не доказанное ограничение генератора PHY.
Записанный `longest = 16 672 bytes` для cs8 соответствует 8 336 комплексным отсчётам, 1,042 мс, 521 символу и 9,035727 % waveform одного пакета. Это оценка масштаба сообщения журнала. RX-запись не доказывает, что именно столько эфирных отсчётов было потеряно, повторено или заменено.
Локальное сопоставление 512-символьными окнами с шагом 256 символов дало 359 окон. В 221 надёжном внутреннем окне задержка равна 0…1 отсчёту, скачков не найдено. Ещё 22 внутренних окна в пакетах 3, 4, 12 и 13 имеют корреляцию ниже порога 0,15; задержка в них не установлена:
- `UNDERRUN LOCATION = NOT_LOCALIZED_FROM_RX`
- `LOCAL DELAY DISCONTINUITY = NO IN 221 RELIABLE WINDOWS; UNDETERMINED IN 22 INTERNAL LOW-CORRELATION WINDOWS`
Участки на краях пакетов и повторяющаяся PRBS-преамбула сохранены в CSV, но исключены из решения о разрыве: там возникают корреляционные копии с шагом 2 032 отсчёта. Те же ограничения применены к 22 внутренним окнам с низкой корреляцией. Низкая корреляция сама по себе отмечает локальную аномалию, но без надёжной временной привязки не определяет underrun.
Ухудшение относительно Lab056 B наблюдается у всех 16 пакетов по трём общим показателям: доле ошибочных символов, EVM и отношению согласованной составляющей к остатку. При этом пакеты 3, 4, 12 и 13 дополнительно выделяются всплесками AC-мощности и остатка. Пакет 14 такого общего физического признака не имеет.
- `PACKETS MOST AFFECTED = 13, 4, 12, 3`
- `LAB062 QUALITY DISTRIBUTION = GLOBAL`
- `PRIMARY CAUSE STATUS = PARTIALLY_LOCALIZED`
Установлено глобальное ухудшение принятого сигнала и отсутствие наблюдаемого временного скачка в надёжных окнах. Точная физическая причина ухудшения и смысл расхождения промежуточного и итогового счётчиков `hackrf_transfer` не установлены.
## Артефакты
- `experiments/lab063_tx_underrun_localization.py`
- `tests/test_lab063_tx_underrun_localization.py`
- `data/processed/lab063/summary.json`
- `data/processed/lab063/packet_quality.csv`
- `data/processed/lab063/local_alignment.csv`
- `docs/lab063_offline_result.md`
Следующий один шаг до нового TX: отдельно согласовать исследование уровня RX, усилений, геометрии и возможной аналоговой компрессии или слишком слабого полезного сигнала. Для будущего повтора также потребуется однозначное журналирование TX underrun и явное добавление запланированных межпакетных пауз. RF-параметры в Lab063 не менялись.

View File

@@ -0,0 +1,212 @@
# Lab063: офлайн-локализация TX underrun и ухудшения пакетов Lab062
## Что установлено
Lab062 остаётся аппаратно невалидным опытом: во время единственной передачи журнал показал `1 underruns, longest 16672 bytes`, хотя итоговая строка показала ноль. Офлайн-анализ не нашёл в RX-записи временного скачка, пропуска или повтора ожидаемого масштаба в 221 надёжном внутреннем окне. Локальная задержка в них составляет 0…1 отсчёт. Ещё в 22 внутренних окнах корреляция ниже 0,15, поэтому задержку там установить нельзя.
Качество сигнала при этом хуже Lab056 B на протяжении всего потока. Все 16 пакетов имеют большую долю ошибочных символов и EVM, а отношение согласованной полезной составляющей к остатку у всех ниже. Пакеты 3, 4, 12 и 13 содержат дополнительные всплески AC-мощности и остатка при почти неизменной TX-согласованной амплитуде. Это указывает на добавочную помеху или искажение, а не на провал полезной несущей в этих пакетах. По сохранённой записи нельзя установить конкретный аппаратный источник.
Цифровые значения далеки от пределов cs8: по пакетам `max |I| = 3…6`, `max |Q| = 4…7`. Сильная аналоговая перегрузка поэтому менее вероятна. Отсутствие rail clipping не является измерением аналоговой линейности, и без отдельного прибора аналоговую компрессию исключить нельзя.
Итоговый выбор: **B. `GLOBAL_RF_DEGRADATION`**. Единичный локальный underrun недостаточен для объяснения всего результата, а его положение по RX не локализовано.
## Целостность и границы анализа
Анализ выполнен без RF и без опроса аппаратуры:
- TX SHA-256: `e84bbce227426c0aac13a48ded1286ca4a44fc6e3efce01f6e5a513217c87ff5`;
- RX SHA-256: `ce0bd603e4ca356af67d504ee11c9e9f38171f31c7427fbe61216a28126b2b32`;
- TX: 1 476 096 комплексных отсчётов;
- RX: 24 000 000 комплексных отсчётов;
- сохранённое начало TX в RX: отсчёт 4 256 091;
- `RF TX = 0`;
- аппаратных запросов: 0.
Поиск использует известный TX только после строгого результата `0/16`; это диагностическая привязка, которая не превращает пакет в принятый и не меняет verdict `legacy` или T2.
## Фактические паузы между пакетами
Проверка длины даёт точное равенство:
`92 256 отсчётов × 16 пакетов = 1 476 096 отсчётов`.
Следовательно:
`ACTUAL INTER-PACKET GAP = 0 additional samples = 0 s`.
Запланированных пауз 5 мс в TX-файле нет. Внутренние защитные интервалы и хвосты RRC, входящие в каждый 92 256-отсчётный waveform, присутствуют.
Код `prepare()` в `experiments/lab062_full_packet_rf_preflight.py` записывает шестнадцать результатов `build_parameterized_tx_cs8(...)` непосредственно друг за другом. Между вызовами нет параметра паузы, массива нулей или другой операции, которая добавила бы 5 мс. Причина: **ошибка реализации подготовки Lab062**. Возможность сформировать паузы в других генераторах проекта означает, что это не установленное ограничение PHY-генератора.
## Масштаб сообщения TX underrun
Для cs8 один комплексный отсчёт занимает два байта:
| Величина | Значение |
|---|---:|
| Журнал, bytes | 16 672 |
| Комплексные отсчёты | 8 336 |
| Длительность при 8 Мвыб/с | 1,042 мс |
| Символы при 500 ксимв/с | 521 |
| Доля waveform одного пакета | 9,035727 % |
Это только пересчёт масштаба строки журнала. Он не доказывает фактическую потерю, повтор или замену 8 336 отсчётов в эфире.
## Локальное сопоставление TX и RX
TX разбит на окна по 512 символов, то есть по 8 192 отсчёта. Шаг равен 256 символам, или 4 096 отсчётам. Для каждого окна независимо искалось положение в RX в пределах ±12 000 отсчётов, затем вычислялись нормированная корреляция, комплексный коэффициент `h`, его амплитуда и фаза, а также остаточная мощность.
Повторяющаяся PRBS-преамбула создаёт ложные корреляционные максимумы с периодом 2 032 отсчёта. Поэтому решение о временном скачке использует внутреннюю часть каждого пакета от отсчёта 24 000 до 86 000 и требует корреляцию не ниже 0,15. Края, преамбула и внутренние окна ниже порога остаются в `local_alignment.csv` для проверки, но их выбранная задержка не участвует в verdict.
| Показатель | Значение |
|---|---:|
| Всего окон | 359 |
| Надёжных окон | 221 |
| Внутренних окон с корреляцией ниже 0,15 | 22 |
| Корреляция, минимум по всем окнам | 0,071665 |
| Корреляция, медиана по всем окнам | 0,265526 |
| Корреляция, максимум по всем окнам | 0,287394 |
| Локальная задержка в надёжных окнах | 0…1 отсчёт |
| Кандидаты на скачок | 0 |
- `UNDERRUN LOCATION = NOT_LOCALIZED_FROM_RX`
- `LOCAL DELAY DISCONTINUITY = NO IN 221 RELIABLE WINDOWS; UNDETERMINED IN 22 INTERNAL LOW-CORRELATION WINDOWS`
Внутренние окна с низкой корреляцией распределены так:
- пакет 3: 5 окон, позиции 69 440…85 824 отсчёта внутри пакета;
- пакет 4: 7 окон, позиции 26 336…46 816 и 55 008 отсчётов;
- пакет 12: 7 окон, позиции 58 336…82 912 отсчётов;
- пакет 13: 3 окна, позиции 27 520…35 712 отсчёта.
Низкая корреляция совпадает с пакетами, где выросли AC-мощность и остаток. Она подтверждает локальные участки сильного искажения. Без надёжной оценки задержки эти участки не доказывают пропуск или повтор отсчётов и не локализуют TX underrun.
Поиск не подгонялся под ожидаемые 8 336 отсчётов. Он способен обнаружить синтетически вставленный скачок и проверяет переходы между пакетами; оба свойства закрыты отдельными тестами.
## Качество пакетов 1–16
`raw` означает полную принятую мощность вместе с DC. `useful` в таблице означает AC-мощность пакета после вычитания средней фоновой AC-мощности до и после потока. Это избыточная над фоном мощность, а не доказанная мощность только полезного TX-сигнала. `M/R` означает отношение TX-согласованной составляющей к остатку. Остаток включает шум, помехи, искажения канала и возможное влияние underrun.
| № | raw, код² | useful, код² | SER, % | EVM RMS | matched / residual, код² | M/R, дБ | ripple, дБ | CFO, Гц | phase, рад |
|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
| 1 | 4,900592 | 0,062620 | 8,517888 | 1,088322 | 0,707513 / 0,838011 | -0,735151 | 6,642520 | +1,007302 | 5,396055 |
| 2 | 4,865147 | 0,056422 | 9,795571 | 1,104921 | 0,670874 / 0,819037 | -0,866627 | 6,598551 | +1,641699 | 0,911620 |
| 3 | 6,015186 | 1,184291 | 10,221465 | 1,357844 | 0,618128 / 1,139667 | -2,656997 | 7,370969 | -0,961988 | 0,917422 |
| 4 | 8,462127 | 3,605520 | 15,587734 | 1,663418 | 0,694253 / 1,920969 | -4,420028 | 10,617549 | +2,584550 | 5,388297 |
| 5 | 4,954615 | 0,062684 | 8,986371 | 1,099196 | 0,702182 / 0,848399 | -0,821507 | 6,409726 | -1,235846 | 0,834217 |
| 6 | 4,919648 | 0,053559 | 7,580920 | 1,102402 | 0,644466 / 0,783214 | -0,846803 | 6,364293 | -1,779543 | 5,318132 |
| 7 | 4,958322 | 0,059386 | 8,390119 | 1,100152 | 0,681935 / 0,825370 | -0,829054 | 6,236828 | -0,248409 | 1,461754 |
| 8 | 4,913306 | 0,063207 | 8,262351 | 1,149257 | 0,638148 / 0,842861 | -1,208345 | 6,714921 | -1,078363 | 0,781772 |
| 9 | 4,886956 | 0,065556 | 8,943782 | 1,141831 | 0,658122 / 0,858045 | -1,152037 | 6,809132 | +0,832282 | 1,073865 |
| 10 | 4,915355 | 0,067571 | 8,347530 | 1,092396 | 0,697137 / 0,831913 | -0,767600 | 6,678161 | -1,337873 | 0,770315 |
| 11 | 4,919918 | 0,072081 | 8,049404 | 1,085344 | 0,688251 / 0,810740 | -0,711347 | 6,630624 | +1,139696 | 0,886944 |
| 12 | 6,800707 | 1,948029 | 12,819421 | 1,456604 | 0,631331 / 1,339491 | -3,266829 | 7,945032 | -0,158710 | 1,085095 |
| 13 | 7,571594 | 2,728649 | 16,013629 | 1,542472 | 0,670672 / 1,595675 | -3,764344 | 9,871896 | -3,768748 | 1,477869 |
| 14 | 4,931040 | 0,060762 | 9,454855 | 1,125042 | 0,631853 / 0,799750 | -1,023377 | 6,450866 | +0,071570 | 0,850015 |
| 15 | 4,914640 | 0,056175 | 9,284497 | 1,156613 | 0,648517 / 0,867557 | -1,263765 | 7,550267 | +0,636870 | 5,326811 |
| 16 | 4,976760 | 0,059023 | 8,603066 | 1,063657 | 0,702947 / 0,795290 | -0,536031 | 6,391673 | +1,336558 | 0,741441 |
Полные значения, включая локальную задержку, корреляцию, `|h|`, DC и разности относительно Lab056 B, находятся в `data/processed/lab063/packet_quality.csv`.
## Уровень RX и DC во время передачи
Средняя фоновая AC-мощность соседних окон равна 0,525282 код², что соответствует AC RMS 0,724764 кода. На RX-only preflight было 0,985483 кода AC RMS.
| № | RMS full | AC RMS | mean I | mean Q | max \|I\| | max \|Q\| | max \|IQ\| |
|---:|---:|---:|---:|---:|---:|---:|---:|
| 1 | 2,213728 | 0,766748 | 0,969270 | 1,836629 | 3 | 4 | 4,472136 |
| 2 | 2,205708 | 0,762695 | 0,967753 | 1,829453 | 3 | 4 | 4,472136 |
| 3 | 2,452588 | 1,307507 | 0,970094 | 1,834266 | 6 | 7 | 7,211102 |
| 4 | 2,908974 | 2,032438 | 0,960349 | 1,846362 | 6 | 7 | 7,615773 |
| 5 | 2,225897 | 0,766789 | 0,964512 | 1,853744 | 3 | 4 | 4,242640 |
| 6 | 2,218028 | 0,760816 | 0,968934 | 1,844444 | 3 | 4 | 4,472136 |
| 7 | 2,226729 | 0,764636 | 0,963515 | 1,856150 | 3 | 4 | 4,472136 |
| 8 | 2,216598 | 0,767131 | 0,958919 | 1,845343 | 3 | 4 | 4,472136 |
| 9 | 2,210646 | 0,768660 | 0,954128 | 1,840043 | 3 | 4 | 4,472136 |
| 10 | 2,217060 | 0,769969 | 0,947830 | 1,850438 | 3 | 4 | 4,242640 |
| 11 | 2,218089 | 0,772893 | 0,943039 | 1,852898 | 3 | 4 | 4,472136 |
| 12 | 2,607816 | 1,572676 | 0,954995 | 1,848075 | 6 | 7 | 8,062258 |
| 13 | 2,751653 | 1,803866 | 0,952307 | 1,846828 | 6 | 7 | 7,810249 |
| 14 | 2,220594 | 0,765535 | 0,952166 | 1,854286 | 3 | 4 | 4,472136 |
| 15 | 2,216899 | 0,762534 | 0,949651 | 1,852389 | 3 | 4 | 4,472136 |
| 16 | 2,230865 | 0,764399 | 0,956903 | 1,864616 | 3 | 4 | 4,472136 |
DC стабилен: `mean I = 0,943039…0,970094`, `mean Q = 1,829453…1,864616`. Ступени AC-амплитуды есть в пакетах 3, 4, 12 и 13. При этом медиана локального `|h|` по пакетам меняется только от 0,004488 до 0,004805. Рост полной AC-мощности в этих пакетах создаёт главным образом остаток, а не согласованный полезный компонент.
## Пакеты 3, 4, 12 и 14
У четырёх ранее отмеченных пакетов нет общего признака underrun:
- у всех четырёх нет скачка задержки;
- у них нет общего провала мощности;
- у них нет общей потери локальной корреляции;
- пакет 14 близок к обычным пакетам по AC RMS, SER, EVM и неравномерности полосы;
- пакеты 3, 4 и 12 имеют всплески AC-мощности и остатка; аналогичный, ещё более выраженный всплеск есть у пакета 13.
Поэтому связывать набор `3, 4, 12, 14` с одним TX underrun оснований нет. По сводному ранжированию наиболее повреждены пакеты `13, 4, 12, 3`.
## Тренд по четвертям потока
| Пакеты | useful, среднее код² | SER, % | EVM RMS | matched, код² | residual, код² | M/R, дБ | CFO, Гц | phase error, рад | local phase span, рад | медиана \|h\| |
|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|
| 1–4 | 1,227213 | 11,030664 | 1,303626 | 0,672692 | 1,179421 | -2,169701 | +1,067891 | 3,153349 | 0,117419 | 0,004637 |
| 5–8 | 0,059709 | 8,304940 | 1,112752 | 0,666683 | 0,824961 | -0,926427 | -1,085540 | 2,098969 | 0,150020 | 0,004608 |
| 9–12 | 0,538309 | 9,540034 | 1,194044 | 0,668710 | 0,960047 | -1,474453 | +0,118849 | 0,954055 | 0,128511 | 0,004658 |
| 13–16 | 0,726152 | 10,839012 | 1,221946 | 0,663497 | 1,014568 | -1,646879 | -0,430938 | 2,099034 | 0,098633 | 0,004536 |
Согласованная составляющая и локальный коэффициент передачи стабильны по четвертям. Средний локальный фазовый размах лежит в пределах 0,098633…0,150020 рад; последовательного роста к концу потока нет. Остаток и SER меняются вместе со всплесками избыточной мощности. Базовое качество всех четвертей хуже Lab056 B.
## Сравнение с Lab056 B
| Метрика | Lab056 B | Lab062, диапазон пакетов | Результат |
|---|---:|---:|---|
| SER | 3,495896 % | 7,580920…16,013629 % | все 16 хуже |
| EVM RMS | 0,845350 | 1,063657…1,663418 | все 16 хуже |
| Matched/residual | +1,464846 дБ | -4,420028…-0,536031 дБ | все 16 хуже |
| Неравномерность полосы | 5,471382 дБ | 6,236828…10,617549 дБ | все 16 хуже |
Ухудшение не ограничено одним пакетом или коротким участком. Локальный TX-согласованный gain не показывает потери длиной около 8 336 отсчётов. Поэтому наблюдавшийся TX underrun остаётся достаточной причиной признать Lab062 невалидной, но не является достаточным объяснением глобально худшего качества.
## Смысл счётчиков `hackrf_transfer`
Сохранены обе строки:
- промежуточная: `1 underruns, longest 16672 bytes`;
- итоговая: `0 underruns, longest 0 bytes`.
В локальной установке исходный файл `hackrf_transfer.c` и документация с описанием сброса этих счётчиков не найдены. В бинарном файле обнаружены только строки формата статистики. Поэтому:
`COUNTER SEMANTICS = NOT_ESTABLISHED`.
Нулевая итоговая строка не отменяет ненулевое промежуточное наблюдение. Причину расхождения без исходного кода используемой версии придумывать нельзя.
## Графики и машинные результаты
- [Локальная задержка](../data/processed/lab063/local_delay_vs_time.png)
- [Нормированная корреляция](../data/processed/lab063/normalized_correlation_vs_time.png)
- [Амплитуда коэффициента передачи](../data/processed/lab063/gain_vs_time.png)
- [Фаза коэффициента передачи](../data/processed/lab063/phase_vs_time.png)
- [Принятая мощность по пакетам](../data/processed/lab063/received_power_by_packet.png)
- [SER по пакетам](../data/processed/lab063/symbol_error_rate_by_packet.png)
- [Matched/residual по пакетам](../data/processed/lab063/matched_residual_by_packet.png)
- [Сравнение Lab056 B и Lab062](../data/processed/lab063/lab056_b_vs_lab062_packets.png)
- [Сводка JSON](../data/processed/lab063/summary.json)
- [Качество пакетов CSV](../data/processed/lab063/packet_quality.csv)
- [Локальное сопоставление CSV](../data/processed/lab063/local_alignment.csv)
## Инженерный вывод
`LAB062 QUALITY DISTRIBUTION = GLOBAL`.
`PRIMARY CAUSE STATUS = PARTIALLY_LOCALIZED`.
Найдена ошибка подготовки TX: обещанные межпакетные паузы не были записаны. Подтверждено глобальное ухудшение относительно Lab056 B и отдельные всплески помехи или искажения. Положение underrun и точная физическая причина общего ухудшения не установлены.
`NEXT SINGLE STEP = до нового TX отдельно исследовать уровень RX, усиления, геометрию и возможную аналоговую компрессию либо слишком слабый полезный сигнал; будущий TX-процесс должен иметь явные паузы и однозначное журналирование underrun`.
Новый RF-сеанс требует отдельного разрешения. В рамках Lab063 параметры PHY, приёмник, усиления и частота не менялись.
- `RF TX = 0`
- `LAB063 COMMIT = NOT PERFORMED`
- `PUSH = NOT PERFORMED`
- `LAB064 = NOT CREATED`

View File

@@ -0,0 +1,141 @@
# Lab064: измерение уровня и линейности RF-тракта
Lab064 проверяет, следует ли мощность согласованной принятой составляющей
заранее заданной цифровой лестнице TX. Это измерительный опыт с известным
PRBS7/BPSK-сигналом, а не пакетный тест. FEC, CRC, T2, JPEG и packet output в
нём не используются.
На текущем этапе сформирован сигнал, подготовлены RX-first runner, офлайн-
анализатор и полный учёт сообщений overruns/underruns. Перед аппаратным
preflight и будущим RF-сеансом исходные параметры не меняются.
## Физические условия
| Условие | Значение |
|---|---|
| Центральная частота | 1400000000 Гц |
| Расстояние TX–RX | примерно 1,2 м |
| Геометрия | прямая видимость, помещение |
| TX | плата и антенна возле окна |
| RX | плата и антенна на столе пользователя |
| Антенны | имеющиеся антенны на 1400 МГц |
| Поляризация | одинаковая |
| Тактирование | 10 МГц TCXO → MASTER → MASTER CLKOUT → SLAVE CLKIN |
Антенны, платы, длинный кабель общей опоры, USB-подключение и остальные
кабели не перемещаются. Во время опыта не меняются частота, усиления,
ориентация и форма сигнала.
## Подготовленный измерительный сигнал
Параметры сигнала: BPSK/PRBS7, 20000 символов/с, Fs 8000000 комплексных
отсчётов/с, 400 отсчётов/символ, цифровая несущая +50000 Гц и существующий RRC
с roll-off 0,35 и span 10 символов. TX VGA равен 10 дБ. RX LNA/VGA равны
24/24 дБ. RF amplifier и Bias-Tee выключены.
Один файл содержит 100 мс нулей, четыре одинаковых по содержанию участка по
100 мс, три нулевых промежутка по 50 мс и 100 мс нулей в конце. Общая длина:
6000000 комплексных отсчётов, 12000000 байт, 0,75 с. Нулевые участки являются
цифровыми нулями IQ; они не означают аппаратного выключения TX посреди файла.
SHA-256 подготовленного CS8:
`fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9`.
| Уровень | Задано, дБ | Фактически, дБ | TX RMS, код | max \|I\| / \|Q\|, код | Шаг мощности, дБ | Clipping |
|---|---:|---:|---:|---:|---:|---|
| L0 | −18 | −17,973685 | 5,556137 | 9 / 9 | — | нет |
| L1 | −12 | −11,996415 | 11,056978 | 17 / 17 | +5,977270 | нет |
| L2 | −6 | −5,998257 | 22,056892 | 34 / 35 | +5,998157 | нет |
| L3 | 0 | 0 | 44,000457 | 69 / 69 | +5,998257 | нет |
Небольшое отклонение L0 от −18 дБ вызвано квантованием CS8. Каждый шаг
укладывается в заранее установленный допуск ±0,1 дБ.
## Анализ будущей записи
Для каждого L0…L3 анализатор отдельно выдаёт полный и AC RMS, средние I/Q,
max |I|, max |Q| и максимальную комплексную амплитуду. По соседнему нулевому
окну оценивается фон. По известному TX оцениваются комплексный коэффициент
передачи `h`, `|h|²`, мощность согласованной составляющей, мощность остатка и
их отношение.
Для каждой соседней пары вычисляются:
```text
TX INPUT DIFFERENCE
RX MATCHED POWER DIFFERENCE
LINEARITY ERROR = RX difference − TX difference
```
Критерии зафиксированы до RF:
- линейный участок: максимальная абсолютная ошибка шага не более 1,0 дБ;
- признак компрессии: ошибка верхнего шага не более −1,5 дБ;
- `LINEAR_BUT_WEAK`: шаги линейны, фон стабилен, а L3 ниже 3 дБ над остатком;
- `HEALTHY_LINEAR_RANGE`: шаги линейны, фон стабилен, а L3 не менее 6 дБ над
остатком;
- неоднозначный результат получает статус `NOT_LOCALIZED`.
Эти границы являются правилами данного опыта, а не абсолютной калибровкой
RF-мощности. Абсолютную выходную и принятую мощность без измерительного прибора
установить нельзя.
Синтетическая проверка известного линейного комплексного канала с DC и шумом
восстановила три цифровых шага с максимальной ошибкой меньше 0,0001 дБ. Это
проверяет вычисления анализатора, но не подтверждает аппаратные свойства
HackRF или эфирного канала.
## Управление аппаратным сеансом
Preflight допускает только RX-команды. Он проверяет MASTER/SLAVE reg29=0x26,
SLAVE CLKIN=DETECTED, процессы, инвентаризацию, 0,1 с фона, rail-коды,
overruns, AC RMS и максимумы |I|/|Q|. Усиления автоматически не меняются.
Будущий runner запускает RX раньше TX. Передача требует отдельного явного
флага, создаёт одноразовый маркер до обращения к SDR и допускает ровно один
TX-вызов. Полные stdout и stderr сохраняются раздельно. В итог попадают все
промежуточные и финальные счётчики потерь, их максимум и последнее значение.
Любой underrun, overrun, clipping или аппаратная ошибка завершает опыт без
повтора. Анализатор при этом может сохранить диагностические метрики, но
выдаёт только `INVALID_CAPTURE`: варианты A/B/C запрещены. Проверка использует
все строки счётчиков и их максимум, поэтому последний ноль не может скрыть
предыдущее ненулевое значение.
После исправления строгой проверки счётчиков quick gate прошёл: 984 теста
ядра, 37 функциональных проверок выполнены, 13 пропущены. Полный pytest:
984 passed, 0 failed. Независимая read-only проверка подтвердила подготовленный
CS8, программные метрики и запрет классификации невалидной записи.
## Аппаратный preflight
14 сентября 2026 года выполнена одна разрешённая аппаратная проверка при
выключенном передатчике. MASTER/SLAVE reg29 равны `0x26`, SLAVE CLKIN имеет
состояние `DETECTED` при первом опросе через 66,793 мс. RX-only запись длиной
800000 отсчётов дала AC RMS 0,832038 кода, max |I|/|Q| 4/5 кодов, clipping 0 и
overruns 0. Неожиданно сильного сигнала нет. После отключения CLKOUT процессы
имеют состояние `CLEAR`, ошибок очистки нет. Подробности приведены в
[отчёте preflight](lab064_rx_preflight.md).
`RF TX = 0`. На этом этапе Lab064 не коммитируется. Push не выполняется.
Lab065 автоматически не начинается.
## Фактический RF-результат
14 сентября 2026 года выполнен один разрешённый RF-сеанс без повторов. TX
underruns 0, RX overruns 0, clipping 0; RX содержит 16000000 комплексных
отсчётов за 2,0 с. Согласованная мощность выросла на 17,809077 дБ при цифровом
росте 17,973685 дБ. Общая ошибка линейности равна −0,164609 дБ. Верхняя ступень
дала +6,020420 дБ при ожидаемых +5,998257 дБ, признака компрессии нет.
Фон стабилен: AC RMS 0,718264…0,728217 кода, разброс мощности 0,119530 дБ.
Даже L3 остаётся на −12,133336 дБ относительно остатка. Итог по заранее
заданным критериям: `LINEAR_BUT_WEAK`. Подробные значения приведены в
[RF-отчёте](lab064_rf_result.md).
После сеанса `RF TX = 0`, процессы `CLEAR`. Усиления не менялись, второй TX не
выполнялся. Lab064 не коммитировалась, push не выполнялся, Lab065 не создана.
Независимый пересчёт непосредственно по TX/RX CS8 подтвердил SHA, аппаратные
счётчики, все четыре matched/residual/`h`, пять окон фона, три ступени и общий
результат L3/L0. Расхождений нет, вердикт проверки: `чисто`. После сеанса quick
gate и полный pytest дали 986 passed, 0 failed; `git diff --check` прошёл.

216
docs/lab064_rf_result.md Normal file
View File

@@ -0,0 +1,216 @@
# Lab064: результат измерения уровня и линейности RF-тракта
В одном коротком OTA-сеансе цифровая мощность TX была увеличена почти на 18 дБ,
то есть цифровая амплитуда выросла примерно в 7,92 раза. Согласованная с
известным TX амплитуда на RX выросла в 7,77 раза, а её мощность на 17,81 дБ.
Коэффициент передачи `|h|` почти не менялся. Признака компрессии на верхнем
уровне не обнаружено.
При этом полезная согласованная составляющая остаётся слабее остатка даже на
L3: −12,13 дБ. Фон во всех пяти нулевых окнах стабилен. По заранее заданным
критериям результат классифицирован как `LINEAR_BUT_WEAK`.
Опыт установил относительную линейность именно этой цифровой лестницы в
текущей OTA-геометрии. Он не измеряет абсолютную мощность в ваттах или дБм и не
разделяет вклад TX, антенн, эфирного канала и RX. Для этого нужен измерительный
прибор или отдельный проведённый тест по кабелю.
## Сеанс и аппаратная целостность
14 сентября 2026 года выполнен ровно один разрешённый TX. RX стартовал раньше
TX. Повторных передач не было.
| Проверка | Результат |
|---|---:|
| TX waveform SHA-256 | `fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9` |
| RF / Fs / symbol rate | 1400000000 Гц / 8000000 отсчётов/с / 20000 символов/с |
| TX VGA / RX LNA / RX VGA | 10 / 24 / 24 дБ |
| RF amplifier / Bias-Tee | выключены |
| MASTER / SLAVE reg29 | `0x26` / `0x26` |
| SLAVE CLKIN | `DETECTED`, второй опрос, 139,042 мс |
| Выполненные TX-сеансы | 1 |
| Автоматические повторы | 0 |
| TX underrun, максимум / финал | 0 / 0 |
| RX overrun, максимум / финал | 0 / 0 |
| RX clipping | 0 |
| RX длина | 16000000 комплексных отсчётов, 2,000000 с |
| RX SHA-256 | `02015891948aaee52ff81e60fdfeb391bb9b76cd9192b75972b8fedbc8690d86` |
| Процессы до / после | `CLEAR` / `CLEAR` |
| Ошибки очистки | 0 |
В TX-журнале сохранены две строки `0 underruns`; в RX-журнале сохранены четыре
строки `0 overruns`. Анализ использует все наблюдения и их максимум. Финальный
нулевой счётчик не мог бы скрыть промежуточное ненулевое значение.
## Фон
Каждое окно имеет длину 160000 отсчётов, или 20 мс, и лежит внутри цифрового
нулевого участка вдали от активной границы.
| Окно | AC power, код² | AC RMS, код |
|---|---:|---:|
| Начальный guard | 0,521529 | 0,722170 |
| Gap L0–L1 | 0,523180 | 0,723312 |
| Gap L1–L2 | 0,515904 | 0,718264 |
| Gap L2–L3 | 0,522200 | 0,722634 |
| Конечный guard | 0,530300 | 0,728217 |
Диапазон AC RMS равен 0,718264…0,728217 кода. Отношение максимальной AC-мощности
к минимальной составляет 0,119530 дБ при заранее заданной границе стабильности
3 дБ. Фон считается стабильным.
## Метрики участков
Мощности приведены в квадрате цифрового кода RX. Это относительные цифровые
величины, а не ватты и не дБм.
### L0, −18 дБ
```text
FULL IQ RMS = 2.277200 code
AC RMS = 0.956317 code
MEAN I = 0.949724 code
MEAN Q = 1.835518 code
MAX |I| = 6 code
MAX |Q| = 7 code
MAX COMPLEX MAGNITUDE = 7.071068 code
BACKGROUND AC POWER = 0.521529 code^2
MATCHED SIGNAL POWER = 0.000750751 code^2
RESIDUAL POWER = 1.213794804 code^2
MATCHED / RESIDUAL = -32.086493 dB
h = 0.001876064 - j0.004508063
|h| = 0.004882853
|h|^2 = 0.000023842249
CFO = +0.095772 Hz
```
### L1, −12 дБ
```text
FULL IQ RMS = 2.291392 code
AC RMS = 0.989014 code
MEAN I = 0.956038 code
MEAN Q = 1.832573 code
MAX |I| = 6 code
MAX |Q| = 7 code
MAX COMPLEX MAGNITUDE = 7.211103 code
BACKGROUND AC POWER = 0.523180 code^2
MATCHED SIGNAL POWER = 0.002961235 code^2
RESIDUAL POWER = 1.069594603 code^2
MATCHED / RESIDUAL = -25.577463 dB
h = 0.004471119 - j0.001937686
|h| = 0.004872939
|h|^2 = 0.000023745532
CFO = -0.168571 Hz
```
### L2, −6 дБ
```text
FULL IQ RMS = 2.275060 code
AC RMS = 0.925298 code
MEAN I = 0.963183 code
MEAN Q = 1.841739 code
MAX |I| = 6 code
MAX |Q| = 7 code
MAX COMPLEX MAGNITUDE = 7.280110 code
BACKGROUND AC POWER = 0.515904 code^2
MATCHED SIGNAL POWER = 0.011333436 code^2
RESIDUAL POWER = 0.529088688 code^2
MATCHED / RESIDUAL = -16.691669 dB
h = 0.003277253 - j0.003478187
|h| = 0.004778930
|h|^2 = 0.000022838175
CFO = +0.006742 Hz
```
### L3, 0 дБ
```text
FULL IQ RMS = 2.341160 code
AC RMS = 1.057677 code
MEAN I = 0.957558 code
MEAN Q = 1.856188 code
MAX |I| = 6 code
MAX |Q| = 7 code
MAX COMPLEX MAGNITUDE = 7.280110 code
BACKGROUND AC POWER = 0.522200 code^2
MATCHED SIGNAL POWER = 0.045331864 code^2
RESIDUAL POWER = 0.740861774 code^2
MATCHED / RESIDUAL = -12.133336 dB
h = 0.003384388 - j0.003391322
|h| = 0.004791153
|h|^2 = 0.000022955145
CFO = -0.076067 Hz
```
Максимумы активных участков равны `|I|=6` и `|Q|=7`. Полная двухсекундная
запись также далека от rail-кодов: `|I|=7`, `|Q|=8`. Это исключает цифровой
clipping в записи, но не является самостоятельным доказательством идеальной
линейности аналогового тракта.
## Линейность мощности и амплитуды
| Пара | TX, дБ | RX matched, дБ | Ошибка, дБ | TX amplitude ratio | RX matched amplitude ratio |
|---|---:|---:|---:|---:|---:|
| L0 → L1 | +5,977270 | +5,959770 | −0,017501 | 1,990048 | 1,986042 |
| L1 → L2 | +5,998157 | +5,828887 | −0,169270 | 1,994839 | 1,956340 |
| L2 → L3 | +5,998257 | +6,020420 | +0,022162 | 1,994862 | 1,999959 |
| L0 → L3 | +17,973685 | +17,809077 | −0,164609 | 7,919254 | 7,770587 |
Максимальная абсолютная ошибка отдельной ступени равна 0,169270 дБ и заметно
меньше заранее установленной границы линейности 1,0 дБ. Верхняя ступень не
отстаёт от TX: она выросла на 6,020420 дБ при ожидаемых 5,998257 дБ. Порог
признака компрессии составлял −1,5 дБ ошибки верхней ступени; фактическая
ошибка равна +0,022162 дБ.
`|h|` изменился от 0,004882853 на L0 до 0,004791153 на L3. Это соответствует
−0,164609 дБ по мощности и совпадает с общей ошибкой линейности. Систематического
падения коэффициента передачи на верхнем уровне нет.
Остаточная мощность при переходе L2 → L3 выросла примерно на 1,46 дБ, тогда
как согласованная полезная мощность выросла на 6,02 дБ. Отношение
matched/residual улучшилось с −16,69 до −12,13 дБ. Ухудшения формы сигнала на
L3 относительно L2 по этому показателю нет.
Диагностические полосы остатка около 50/100/150 кГц на L3 равны
0,009576/0,004469/0,002725 код². Они не растут быстрее согласованной мощности
при переходе L2 → L3. Эти полосы не являются калиброванным измерением
RF-гармоник, поэтому абсолютный вывод о спектральной чистоте потребовал бы
анализатора спектра.
## Вывод
```text
CLASSIFICATION = LINEAR_BUT_WEAK
```
Текущий тракт воспроизводит цифровые ступени почти один к одному по дБ. Данных
за компрессию при TX VGA 10 дБ и RX LNA/VGA 24/24 дБ нет. Главная проблема
этого сеанса состоит в низкой согласованной полезной мощности относительно
остатка: даже на L3 запас равен −12,13 дБ.
Практически это означает, что простое объяснение Lab062 аналоговой перегрузкой
текущего тракта не подтверждается. Слабое отношение полезной составляющей к
остатку остаётся вероятным фактором плохого 500K-приёма, хотя Lab064 использует
узкий сигнал 20 ksymbol/s и сама по себе не объясняет все широкополосные
искажения Lab062.
Рекомендуемый следующий отдельный шаг: согласовать повтор той же лестницы при
TX VGA 20 дБ, сохранив RX LNA/VGA 24/24 дБ, частоту, геометрию, waveform и
общую опору. Это проверит, улучшается ли matched/residual при сохранении
линейности. В рамках Lab064 усиления не менялись и второй TX не выполнялся.
## Независимая проверка
Проверяющий агент работал только с сохранёнными файлами и не обращался к
оборудованию. Он независимо пересчитал SHA-256, положение четырёх сегментов,
пять окон фона, matched/residual, комплексные `h`, отношения мощности и
амплитуды, общий результат L3/L0 и все двенадцать спектральных значений.
Подтверждённых расхождений нет. Целевые тесты дали 15 passed; итоговый вердикт:
`чисто`.
После RF-сеанса quick gate прошёл: 986 тестов ядра, 37 функциональных проверок,
13 пропусков. Полный pytest: 986 passed, 0 failed. `git diff --check`: PASS.
`RF TX = 0`. Lab064 не коммитировалась, push не выполнялся, Lab065 не создана.

120
docs/lab064_rx_preflight.md Normal file
View File

@@ -0,0 +1,120 @@
# Lab064: подготовка и RX-only preflight
14 сентября 2026 года завершена программная подготовка измерения уровня и
линейности текущего OTA-тракта. Затем выполнена одна аппаратная проверка общей
опоры и RX-фона. Preflight прошёл. Передатчик не запускался: `RF TX = 0`.
## Условия
| Параметр | Значение |
|---|---|
| Центральная частота | 1400000000 Гц |
| Скорость символов | 20000 символов/с |
| Частота дискретизации | 8000000 комплексных отсчётов/с |
| Цифровая несущая | +50000 Гц |
| TX VGA | 10 дБ |
| RX LNA / VGA | 24 / 24 дБ |
| RF amplifier / Bias-Tee | выключены |
| Расстояние TX–RX | примерно 1,2 м |
| Геометрия | прямая видимость, помещение |
| TX | плата и антенна возле окна |
| RX | плата и антенна на столе пользователя |
| Антенны | имеющиеся антенны на 1400 МГц |
| Поляризация | одинаковая |
| Общая опора | 10 МГц TCXO → MASTER → MASTER CLKOUT → SLAVE CLKIN |
Антенны, платы, длинный кабель общей опоры, USB-подключение и остальные
кабели не перемещались. Усиления не менялись.
## Измерительный TX-файл
Подготовлен один детерминированный PRBS7/BPSK/RRC-сигнал с уровнями −18, −12,
−6 и 0 дБ относительно номинального waveform. Он состоит из 100 мс начальных
нулей, четырёх участков по 100 мс, трёх промежутков по 50 мс и 100 мс конечных
нулей. Полная длительность равна 0,75 с, длина составляет 6000000 комплексных
отсчётов и 12000000 байт.
| Уровень | TX RMS, код | max \|I\| / \|Q\|, код | Фактический уровень, дБ | Шаг, дБ |
|---|---:|---:|---:|---:|
| L0 | 5,556137 | 9 / 9 | −17,973685 | — |
| L1 | 11,056978 | 17 / 17 | −11,996415 | +5,977270 |
| L2 | 22,056892 | 34 / 35 | −5,998257 | +5,998157 |
| L3 | 44,000457 | 69 / 69 | 0 | +5,998257 |
Цифрового clipping нет. SHA-256:
`fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9`.
Синтетический линейный канал с известным комплексным коэффициентом, DC и
шумом прошёл software gate. После независимой проверки анализатор изменён так,
чтобы промежуточный ненулевой счётчик нельзя было скрыть финальным нулём. При
любой потере сохраняются диагностические метрики, но A/B/C-классификация
запрещается и результат получает статус `INVALID_CAPTURE`.
## Common clock
Свежая инвентаризация подтвердила две HackRF One r9 с firmware/libhackrf
2024.02.1. Роли сохранены:
- MASTER `000000000000000097c063dc323b97d3`;
- SLAVE `000000000000000097c063dc2e5327d3`.
Аппаратная проверка получила:
```text
MASTER reg29 = 0x26
SLAVE reg29 = 0x26
SLAVE CLKIN = DETECTED
CLKIN query = 1
time to detect = 66.793 ms
```
## RX-only фон
SLAVE записал 800000 комплексных отсчётов, 0,1 с, при 1400 МГц и RX LNA/VGA
24/24 дБ.
| Метрика | Значение |
|---|---:|
| Полный RMS IQ | 2,193193 кода |
| AC RMS после удаления среднего | 0,832038 кода |
| Средние I / Q | 0,933738 / 1,801650 кода |
| max \|I\| / \|Q\| | 4 / 5 кодов |
| Максимальная комплексная амплитуда | 5,385165 кода |
| Clipping | 0 / 800000 отсчётов |
| RX overruns | 0, максимум и финальное значение |
| Неожиданно сильный сигнал | нет |
Порог STOP для неожиданно сильного цифрового фона: AC RMS не менее 20 кодов
или max |I|/|Q| не менее 100 кодов. Измеренные значения значительно ниже.
Отсутствие rail-кодов не доказывает отсутствие аналоговой компрессии при
будущей передаче. Абсолютная RF-мощность без измерительного прибора неизвестна.
SHA-256 RX-only записи:
`02d87adcbb621027290a77d5f8fd3190c299d13e89f887cd294d4af352a6ef52`.
Процессы до и после preflight имели состояние `CLEAR`. Оба CLKOUT выключены,
ошибок очистки нет. Preflight сохранил все две строки счётчика RX overruns;
обе равны нулю. Вызовов `hackrf_transfer -t` не было, `rf_tx_count = 0`.
## Проверки и артефакты
- quick gate: 984 теста ядра, 37 функциональных проверок, 13 пропусков;
- pytest: 984 passed, 0 failed;
- целевые тесты Lab064: 13 passed;
- `git diff --check`: PASS;
- независимая read-only проверка: чисто.
Артефакты:
- [подготовка](../data/processed/lab064/preparation.json);
- [software gate](../data/processed/lab064/software_gate.json);
- [preflight](../data/processed/lab064/preflight_result.json);
- CS8 и исходные аппаратные журналы находятся в `data/raw/lab064/` и в Git не
входят.
`READY FOR SINGLE LAB064 TX = YES` означает техническую готовность только этой
конфигурации. Передача требует отдельного явного разрешения пользователя.
`RF TX = 0`. STOP.
Lab064 не коммитируется до аппаратного результата. Push не выполняется.
Lab065 автоматически не начинается.

View File

@@ -0,0 +1,70 @@
# Lab065: подготовка измерения при TX VGA 20 дБ
Lab065 повторяет измерение Lab064 с одним изменением аппаратного параметра:
TX VGA повышен с 10 до 20 дБ. Частота 1400000000 Гц, RX LNA/VGA 24/24 дБ,
геометрия, антенны, кабели, общая опора и цифровой waveform сохранены.
TX-файл Lab065 является побайтовой копией Lab064. Его SHA-256 должен быть равен
`fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9`.
Длина остаётся равной 6000000 комплексных отсчётов и 0,75 с. Ступени
−18/−12/−6/0 дБ, PRBS7, BPSK, RRC, 20000 символов/с, Fs 8000000 отсчётов/с и
цифровая несущая +50000 Гц не меняются.
## Сравнение с Lab064
Для L0, L1, L2 и L3 анализатор выдаёт изменение согласованной мощности,
`|h|²`, остаточной мощности и matched/residual. Номинальное изменение TX VGA
равно +10 дБ и приводится как справочная величина, а не как условие PASS.
До RF зафиксированы численные правила:
- линейность внутри Lab065: максимальная абсолютная ошибка шага не более 1 дБ;
- компрессия: ошибка верхнего шага не более −1,5 дБ;
- заметный прирост: медиана прироста matched power не менее 3 дБ;
- заметное улучшение matched/residual: медиана не менее 3 дБ;
- согласованность прироста четырёх уровней: разброс не более 3 дБ;
- остаток считается растущим почти как сигнал, если его медианный прирост
отстаёт от медианного прироста matched power не более чем на 3 дБ.
Эти пороги нужны для воспроизводимой классификации конкретного опыта. Они не
заменяют измерение абсолютной RF-мощности.
## Аппаратная граница
Подготовка допускает программные проверки, common-clock preflight и RX-only
запись фона. Любая команда с `-t` внутри preflight запрещена. Передача Lab065
требует нового прямого разрешения пользователя и в текущий этап не входит.
Автоматических повторов и изменения усилений после ошибки нет.
`RF TX = 0`.
## Результат подготовки
Подготовка выполнена от HEAD
`cff226e0bf9e36a627829ea11a4ca3292ae20953`. Software gate прошёл. Побайтовая
копия waveform имеет требуемый SHA-256, подготовленная TX-команда содержит
TX VGA 20 дБ, а RX-команда сохраняет LNA/VGA 24/24 дБ.
Common-clock и RX-only preflight прошёл. Обе HackRF One r9 обнаружены с
прежними ролями. MASTER и SLAVE имеют reg29 `0x26`; SLAVE CLKIN обнаружен на
третьем опросе через 201,986 мс. В RX-фоне из 800000 отсчётов AC RMS равен
1,056565 кода, max |I|/|Q| равны 6/8, clipping и overruns отсутствуют.
Процессы до и после проверки имеют состояние CLEAR, ошибок очистки нет.
Lab065 готова к рассмотрению перед одним RF-сеансом. Текущая подготовка такого
разрешения не содержит. `RF TX = 0`.
## Единственный RF-сеанс
После отдельного прямого разрешения выполнен один TX. Общая опора прошла:
MASTER/SLAVE reg29 `0x26`, SLAVE CLKIN обнаружен на втором опросе через
136,897 мс. TX underrun, RX overrun, clipping и ошибки очистки отсутствуют.
Повторов не было. RX содержит 16000000 отсчётов, SHA-256
`845d7b7dcaef70e179ab69e6ba0041601859630786d2f4d51c16a8c1c7869d7e`.
Медианный прирост matched power относительно Lab064 равен +11,233489 дБ,
медианное изменение остатка +0,517004 дБ, улучшение matched/residual
+10,734495 дБ. Ошибки ступеней равны −0,077363/+0,034934/−0,013858 дБ.
Признаков компрессии нет. Классификация: `LINEAR_GAIN_IMPROVEMENT`.
[Полный RF-отчёт](lab065_rf_result.md). `RF TX = 0`.

114
docs/lab065_rf_result.md Normal file
View File

@@ -0,0 +1,114 @@
# Lab065: один OTA-сеанс при TX VGA 20 дБ
15 сентября 2026 года выполнен один разрешённый OTA-сеанс Lab065 на частоте
1400000000 Гц. Передача использовала точную копию waveform Lab064 с SHA-256
`fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9`.
Автоматических и ручных повторов не было.
## Аппаратная валидность
Перед TX обе HackRF One r9 и их роли подтверждены. MASTER и SLAVE имели reg29
`0x26`; SLAVE CLKIN обнаружен на втором опросе через 136,897 мс. RX стартовал
раньше TX. Результат сеанса:
```text
COMPLETED TX SESSIONS = 1
AUTOMATIC TX REPEATS = 0
TX UNDERRUN MAXIMUM = 0
RX OVERRUN MAXIMUM = 0
RX CLIPPING = NO
CLEANUP ERRORS = []
SDR PROCESSES = CLEAR
```
RX содержит 16000000 комплексных отсчётов, 32000000 байт и 2,0 с. SHA-256:
`845d7b7dcaef70e179ab69e6ba0041601859630786d2f4d51c16a8c1c7869d7e`.
Максимумы всей записи равны `|I|=10` и `|Q|=10`; rail-кодов нет.
## Линейность внутри Lab065
| Переход | TX, дБ | RX matched, дБ | Ошибка, дБ |
|---|---:|---:|---:|
| L0 → L1 | +5,977270 | +5,899908 | −0,077363 |
| L1 → L2 | +5,998157 | +6,033091 | +0,034934 |
| L2 → L3 | +5,998257 | +5,984400 | −0,013858 |
Максимальная абсолютная ошибка равна 0,077363 дБ при границе 1 дБ. Ошибка
верхней ступени равна −0,013858 дБ при пороге компрессии −1,5 дБ. Согласованная
мощность L3 выросла относительно L2 на 5,984400 дБ. Признаков компрессии на
L2/L3 нет.
## Сравнение Lab064 и Lab065
| Уровень | Matched, дБ | Остаток, дБ | Улучшение matched/residual, дБ | Изменение \|h\|², дБ |
|---|---:|---:|---:|---:|
| L0 | +11,179328 | −0,243276 | +11,422604 | +11,179328 |
| L1 | +11,119466 | −2,366286 | +13,485752 | +11,119466 |
| L2 | +11,323670 | +1,277284 | +10,046386 | +11,323670 |
| L3 | +11,287650 | +3,907581 | +7,380069 | +11,287650 |
Медианный прирост согласованной мощности равен +11,233489 дБ. Его разброс по
четырём уровням составляет 0,204204 дБ. Медианное изменение остатка равно
+0,517004 дБ, а медианное улучшение matched/residual равно +10,734495 дБ.
При TX VGA 20 дБ matched/residual для L0/L1/L2/L3 равен
−20,663889/−12,091711/−6,645283/−4,753267 дБ. Отношение улучшилось на каждом
уровне, хотя даже на L3 согласованная составляющая остаётся слабее остатка.
## Комплексный коэффициент передачи
| Уровень | h Lab064 | h Lab065 | \|h\| Lab064 | \|h\| Lab065 | Изменение фазы, градусы |
|---|---|---|---:|---:|---:|
| L0 | 0,001876 − j0,004508 | −0,006915 + j0,016279 | 0,004883 | 0,017686 | −179,581 |
| L1 | 0,004471 − j0,001938 | −0,010180 + j0,014271 | 0,004873 | 0,017529 | +148,932 |
| L2 | 0,003277 − j0,003478 | −0,009134 + j0,015045 | 0,004779 | 0,017600 | +167,966 |
| L3 | 0,003384 − j0,003391 | −0,009107 + j0,015028 | 0,004791 | 0,017572 | +166,276 |
Модуль `h` внутри Lab065 почти постоянен: 0,017529…0,017686. Его мощность
относительно Lab064 выросла на 11,119…11,324 дБ, что согласуется с matched
power. Фаза между отдельными сеансами не имеет непрерывной временной привязки,
поэтому приведённый поворот является диагностикой конкретных записей, а не
калиброванной фазовой характеристикой тракта.
## Фон и остаточные полосы
Пять нулевых окон Lab065 имеют AC RMS 0,763722…0,857191 кода. Разброс фоновой
AC-мощности равен 1,002840 дБ при границе 3 дБ, поэтому фон классифицирован как
стабильный. В Lab064 разброс составлял 0,119530 дБ; фон Lab065 стабильный, но
межоконный разброс стал больше.
Изменение диагностических полос остатка относительно Lab064:
| Уровень | 50 кГц, дБ | 100 кГц, дБ | 150 кГц, дБ |
|---|---:|---:|---:|
| L0 | +2,869745 | +2,654569 | +2,258651 |
| L1 | +3,032680 | +2,378561 | +1,300716 |
| L2 | +5,594944 | +4,091263 | +2,888397 |
| L3 | +7,304593 | +6,432281 | +4,996232 |
На верхних уровнях остаточные полосы выросли, особенно около 50 кГц. На L3 их
рост остаётся ниже прироста matched power +11,287650 дБ, а matched/residual
улучшился на 7,380069 дБ. Эти цифровые полосы не являются калиброванным
измерением RF-гармоник.
## Итог
```text
CLASSIFICATION = LINEAR_GAIN_IMPROVEMENT
```
Повышение TX VGA с 10 до 20 дБ дало устойчивый прирост согласованной принятой
мощности примерно на 11,2 дБ без потери линейности. Остаток вырос существенно
меньше, поэтому отношение полезной составляющей к остатку улучшилось на всех
четырёх уровнях. Верхняя ступень не показывает компрессии.
Результат остаётся относительным измерением всего OTA-тракта. Он не определяет
абсолютную RF-мощность и не доказывает прохождение полного PHY-пакета, FEC, CRC,
T2 или JPEG.
Независимая проверка пересчитала сохранённый CS8, локализацию, фон, matched,
residual, `h`, CFO, внутреннюю линейность и сравнение с Lab064. Расхождений нет.
Рекомендуемый следующий одиночный шаг: рассмотреть scope Lab065 и отдельно
разрешить локальный коммит. Новую RF-передачу для этого выполнять не требуется.
`RF TX = 0`. Lab065 не коммитировалась, push не выполнялся, Lab066 не создана.

View File

@@ -0,0 +1,83 @@
# Lab065: подготовка и RX-only preflight
15 сентября 2026 года подготовлена Lab065 с TX VGA 20 дБ. Пользователь
подтвердил неизменность расстояния около 1,2 м, прямой видимости, положения TX
возле окна и RX на столе, антенн, поляризации, USB, общей опоры и RF-кабелей.
## Неизменность сигнала
TX-файл Lab065 является побайтовой копией файла Lab064:
```text
TX samples = 6000000
TX bytes = 12000000
TX duration = 0.750000 s
TX SHA-256 = fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9
WAVEFORM UNCHANGED FROM LAB064 = YES
```
Сохранены PRBS7, BPSK, RRC, ступени −18/−12/−6/0 дБ, интервалы и нулевые
защитные участки, 20000 символов/с, Fs 8000000 комплексных отсчётов/с и
цифровая несущая +50000 Гц. Из аппаратных параметров изменён только TX VGA:
10 → 20 дБ. RX LNA/VGA остаются равными 24/24 дБ; RF amplifier и Bias-Tee
выключены.
Software gate прошёл. Он подтвердил SHA, пригодность результата Lab064 как
базы сравнения, синтетическую проверку линейности и наличие численных правил
классификации, зафиксированных до RF.
## Common clock
Перед аппаратными командами проверка процессов через psutil осмотрела 289
процессов и получила CLEAR. Обнаружены обе HackRF One r9 с firmware и
libhackrf 2024.02.1. Роли совпали с Lab064:
- MASTER `000000000000000097c063dc323b97d3`;
- SLAVE `000000000000000097c063dc2e5327d3`.
Результат общей опоры:
```text
MASTER reg29 = 0x26
SLAVE reg29 = 0x26
SLAVE CLKIN = DETECTED
CLKIN query = 3
time to detect = 201.986 ms
```
Первые два опроса не обнаружили CLKIN, третий опрос прошёл в пределах штатного
окна ожидания. Итоговый common-clock gate имеет статус PASS.
## RX-only фон
SLAVE записал 800000 комплексных отсчётов при 1400000000 Гц и RX LNA/VGA
24/24 дБ.
| Метрика | Значение |
|---|---:|
| Полный RMS IQ | 2,333068 кода |
| AC RMS после удаления среднего | 1,056565 кода |
| Средние I / Q | 0,948896 / 1,851074 кода |
| max \|I\| / \|Q\| | 6 / 8 кодов |
| Максимальная комплексная амплитуда | 8,062258 кода |
| Clipping | 0 / 800000 отсчётов |
| RX overruns, максимум / финал | 0 / 0 |
| Неожиданно сильный сигнал | нет |
SHA-256 RX-фона:
`be3c61dfa1bc40d1a9f6777689026804a1ccfc340b82680d3ec5304ddd68f78c`.
Оба CLKOUT выключены без ошибок. Повторная проверка процессов получила CLEAR.
Команд передачи не было.
```text
LAB065 PREPARATION = PASS
COMMON CLOCK = PASS
RX PREFLIGHT = PASS
RF TX = 0
READY FOR SINGLE LAB065 TX = YES
WAITING FOR EXPLICIT RF AUTHORIZATION = YES
```
Готовность означает, что программные и аппаратные входные проверки пройдены.
Она не разрешает передачу и не предсказывает результат измерения.

View File

@@ -0,0 +1,92 @@
# Lab066 — исправленный повтор полного 500K PHY-сеанса
## Цель и границы
Lab066 повторяет исходную цель Lab062 после двух установленных дефектов того
сеанса: пакеты Lab062 шли вплотную, без заявленных пауз 5 мс, а в TX-журнале
был промежуточный underrun. Исторический результат Lab062 сохраняется без
изменений: `RF_SESSION_INVALID_TX_UNDERRUN`, legacy 0/16, T2 0/16.
На этапе подготовки Lab066 была ограничена программным декодированием,
common-clock и RX-only preflight; передача тогда не выполнялась. После этого
пользователь отдельно разрешил один TX. Автоматический повтор оставался
запрещён и не выполнялся.
## Радиопараметры
- RF: 1400000000 Гц;
- Fs: 8000000 комплексных отсчётов/с;
- символьная скорость: 500000 символов/с, 16 отсчётов/символ;
- цифровая несущая: +50000 Гц;
- TX VGA: 20 дБ;
- RX LNA/VGA: 24/24 дБ;
- RF amplifier и Bias-Tee: OFF;
- 16 штатных PHY-пакетов с PRBS7-преамбулой, заголовком, FEC и CRC;
- payload: 256 байт, детерминированный и различимый для каждого пакета;
- геометрия: около 1,2 м, LOS в помещении, прежние антенны и поляризация;
MASTER TX возле окна, SLAVE RX на столе.
## Итоговый TX-файл
Каждый packet waveform занимает 92256 отсчётов. Между соседними пакетами
записаны 15 нулевых пауз по 40000 отсчётов, то есть ровно по 5 мс. Перед первым
и после последнего пакета добавлены нулевые guards по 800000 отсчётов, или по
100 мс.
Расчёт длины:
```text
16 × 92256 + 15 × 40000 = 2076096 отсчётов без внешних guards
2076096 + 2 × 800000 = 3676096 отсчётов всего
3676096 / 8000000 = 0,459512 с
```
Фактическая длина совпала с расчётом: 3676096 комплексных отсчётов,
7352192 байта. SHA-256:
`621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199`.
Повторная сборка дала те же байты. Нулевые guards и каждая из 15 пауз проверены
по точным границам из сохранённой разметки.
## Программное декодирование
Весь конечный TX-файл дважды прошёл один и тот же строгий приёмный тракт. Режимы
legacy и T2 запускались отдельно, автоматического fallback между ними нет.
| Режим | Кандидаты | Header | FEC | CRC | Выход | Payload и порядок |
|---|---:|---:|---:|---:|---:|---:|
| legacy | 16 | 16/16 | 16/16 | 16/16 | 16/16 | 16/16 |
| T2 | 16 | 16/16 | 16/16 | 16/16 | 16/16 | 16/16 |
Позиции принятых пакетов равны ожидаемым позициям в разметке. Для каждого
кандидата T2 заново оценивает начальные параметры по собственной преамбуле.
Наблюдение дало по два локальных запуска слежения на пакет: для заголовка и
полного кадра. Контекст обработки создаётся заново, состояния между пакетами
не переносятся.
Аппаратный анализ применил legacy и T2 к одному сохранённому RX-файлу. До
строгого вердикта декодеру не передавались payload или ожидаемые биты. Известный
TX использован после вердикта только для физических диагностик и сравнения с
Lab056 B, Lab062 и Lab066.
## Проверки перед preflight
- `python tools/quick_gate.py`: PASS, 1013 проверок ядра, 39 функциональных,
13 аппаратных пропусков;
- `python -m pytest tests/ -q`: 1013 passed;
- `git diff --check`: PASS.
Независимый verifier пересчитал длину, SHA, все нулевые диапазоны, пакетные
срезы, программное декодирование и RX-only метрики; расхождений нет. Read-only
adversary проверил запрет TX, одноразовость, привязку capture к конфигурации,
счётчики, live-проверку фона и границу oracle-диагностики; открытых замечаний
нет.
## Текущее состояние
Common-clock и RX-only preflight прошли; измерения приведены в
[отдельном отчёте](lab066_rx_preflight.md). `RF TX=0`. Lab066 не
коммитировалась, push не выполнялся, Lab067 не создавалась.
После отдельного разрешения выполнен один аппаратно валидный RF-сеанс без
повторов. Legacy и T2 дали одинаковые 10/16 точных пакетов. Полные результаты
и физическое сравнение приведены в [RF-отчёте](lab066_rf_result.md).

118
docs/lab066_rf_result.md Normal file
View File

@@ -0,0 +1,118 @@
# Lab066 — один OTA RF-сеанс полного 500K PHY-потока
## Аппаратная валидность
15 сентября 2026 года выполнен один разрешённый TX всего подготовленного
потока. Передача запускалась один раз; автоматических повторов не было. RX
стартовал раньше TX и сохранил 16000000 комплексных отсчётов за 2,000000 с.
- TX SHA-256:
`621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199`;
- RX SHA-256:
`72ff7ddd8b30baa4a5c066361ca1f8dfa664f1da37f65c0c373b211ce6cf00f0`;
- TX underrun observations: 0, 0; maximum 0;
- RX overrun observations: 0, 0, 0, 0; maximum 0;
- clipping: нет;
- cleanup errors: нет;
- SDR-процессы до и после: `CLEAR`.
Непосредственно перед TX обе платы имели reg29=`0x26`; SLAVE CLKIN обнаружен
на втором опросе через 131,291 мс. Live RX-проверка дала AC RMS 1,173567 кода,
max |I|/|Q|=4/5 и не обнаружила clipping или сильный фон. После сеанса оба
CLKOUT отключены.
## Строгое декодирование одной RX-записи
Legacy и T2 получили одну и ту же непрерывную IQ-запись. Поиск кандидатов,
временная синхронизация, RRC, пороги, PHY header, FEC, CRC и критерии принятия
не менялись. Автоматического fallback между режимами нет.
| Метрика | legacy | T2 |
|---|---:|---:|
| Кандидаты | 145 | 145 |
| Header PASS | 10 | 10 |
| FEC started | 10 | 10 |
| FEC PASS | 10 | 10 |
| CRC started | 10 | 10 |
| CRC PASS | 10 | 10 |
| Packet output | 10 | 10 |
| Exact payload match | 10 | 10 |
Оба режима приняли пакеты 4, 5, 6, 7, 8, 10, 11, 12, 13 и 14. Пакеты 1, 2,
3, 9, 15 и 16 не прошли PHY header у обоих режимов. Выигрыша одного режима
над другим нет.
| Пакет | Legacy H/F/C/O | T2 H/F/C/O |
|---:|:---:|:---:|
| 1 | 0/0/0/0 | 0/0/0/0 |
| 2 | 0/0/0/0 | 0/0/0/0 |
| 3 | 0/0/0/0 | 0/0/0/0 |
| 4 | 1/1/1/1 | 1/1/1/1 |
| 5 | 1/1/1/1 | 1/1/1/1 |
| 6 | 1/1/1/1 | 1/1/1/1 |
| 7 | 1/1/1/1 | 1/1/1/1 |
| 8 | 1/1/1/1 | 1/1/1/1 |
| 9 | 0/0/0/0 | 0/0/0/0 |
| 10 | 1/1/1/1 | 1/1/1/1 |
| 11 | 1/1/1/1 | 1/1/1/1 |
| 12 | 1/1/1/1 | 1/1/1/1 |
| 13 | 1/1/1/1 | 1/1/1/1 |
| 14 | 1/1/1/1 | 1/1/1/1 |
| 15 | 0/0/0/0 | 0/0/0/0 |
| 16 | 0/0/0/0 | 0/0/0/0 |
H/F/C/O означает header/FEC/CRC/output. Для каждого из 16 ожидаемых пакетов
детектор имел кандидат точно на диагностической границе пакета. У шести
непринятых пакетов FEC и CRC не запускались из-за отказа PHY header.
## Физическая диагностика после строгого результата
Сопоставимые показатели рассчитаны отдельно по всем 16 пакетам методикой
Lab058. Известный TX использован после завершения строгих прогонов и не влиял
на принятие пакетов.
| Показатель | Lab066 |
|---|---:|
| Доля ошибочных символов | 0,0110466, или 1,104664% |
| Нормированное RMS-отклонение символов | 0,528374 |
| Согласованная мощность | 8,359398 код² |
| Остаточная мощность | 2,333261 код² |
| Matched/residual | +5,542117 дБ |
| Неравномерность усиления p95–p05 | медиана 2,870070 дБ |
| Диапазон неравномерности по пакетам | 2,724906…3,111679 дБ |
Остаток включает шум и немоделированные искажения; это не калиброванная
мощность шума. Физические показатели являются диагностическими и не превращают
непринятый пакет в успешный.
## Сравнение
| Показатель | Lab056 B | Lab062 | Lab066 |
|---|---:|---:|---:|
| Доля ошибочных символов | 0,034959 | 0,099287 | 0,011047 |
| RMS-отклонение | 0,845350 | 1,220401 | 0,528374 |
| Matched/residual | +1,464846 дБ | −1,730051 дБ | +5,542117 дБ |
| Неравномерность полосы | 5,471382 дБ | 6,660341 дБ | 2,870070 дБ |
Относительно Lab056 B доля ошибочных символов ниже на 0,0239123, или на
68,40%; RMS-отклонение ниже на 0,316976, matched/residual выше на 4,077271 дБ,
а неравномерность меньше на 2,601312 дБ.
Относительно Lab062 доля ошибочных символов ниже на 0,0882400, или на 88,87%;
RMS-отклонение ниже на 0,692027, matched/residual выше на 7,272168 дБ, а
неравномерность меньше на 3,790271 дБ. Сравнение с Lab062 контекстное: тот
сеанс остаётся аппаратно невалидным из-за TX underrun.
## Итог
Классификация: `PARTIAL_PACKET_RECOVERY_NO_T2_GAIN`. Аппаратно чистая запись
дала одинаковые 10/16 точных пакетов в legacy и T2. Физическое качество заметно
лучше Lab056 B и невалидной Lab062, однако шесть пакетов остановились на PHY
header, поэтому результат не является полным 16/16 успехом.
Следующий отдельный шаг, если он будет разрешён: только офлайн сравнить ошибки
PHY header, timing и CFO пакетов 1–3, 9, 15–16 с принятыми пакетами по уже
сохранённому RX. Новый TX для этого не нужен.
Сейчас `RF TX=0`, процессы `CLEAR`. Lab066 не коммитировалась, push не
выполнялся, Lab067 не создавалась.

View File

@@ -0,0 +1,35 @@
# Lab066 — common-clock и RX-only preflight
## Результат
15 сентября 2026 года выполнен один preflight без передачи. До и после него
SDR-процессы имели состояние `CLEAR`; обе HackRF One r9 и назначение ролей
подтверждены.
Общая опора прошла проверку:
- MASTER reg29 = `0x26`;
- SLAVE reg29 = `0x26`;
- SLAVE CLKIN = `DETECTED`;
- обнаружение произошло на втором опросе через 132,113 мс.
RX-only команда записала 800000 комплексных отсчётов на частоте 1400 МГц с
RX LNA/VGA 24/24 дБ. Максимум всех наблюдавшихся счётчиков overrun равен нулю.
После проверки оба CLKOUT отключены; ошибок очистки нет.
## Уровень фона
- полный RMS: 2,225641 кода;
- AC RMS: 0,827637 кода;
- средние I/Q: 0,947530 / 1,835941 кода;
- max |I| / |Q|: 4 / 5;
- доля clipped components и samples: 0 / 0;
- неожиданный сильный сигнал: нет;
- SHA-256 RX-only записи:
`ff817582e6a8fc03b489bf89f46322a9db8a9493335a4360a1b0f9bedad7c4d5`.
## Граница разрешения
Preflight не запускал TX и не расходует право на будущий единственный сеанс.
Сейчас `RF TX=0`. Для одного Lab066 TX требуется отдельное прямое разрешение.
Автоматические повторы, изменение усилений и переход к Lab067 запрещены.

View File

@@ -0,0 +1,49 @@
# Lab067: текущее состояние
Дата: 15 сентября 2026 года.
## Граница работы
Lab067 выполнена полностью офлайн по сохранённой аппаратно валидной записи
Lab066. HackRF Plus не опрашивался, аппаратные команды не запускались, RF TX
оставался равным 0. Алгоритмы приёмника, PHY-заголовок, пороги, FEC, CRC и
критерии принятия пакета не менялись.
Исторический строгий результат Lab066 сохранён:
- legacy: 10/16 точных пакетов;
- T2: 10/16 точных пакетов;
- приняты пакеты 4–8 и 10–14;
- пакеты 1–3, 9, 15 и 16 остановились на PHY-заголовке.
## Проверенные исходники
- TX: 7 352 192 байта, 3 676 096 комплексных отсчётов, SHA-256
`621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199`;
- RX: 32 000 000 байт, 16 000 000 комплексных отсчётов, 2,0 с при
8 Мвыб/с, SHA-256
`72ff7ddd8b30baa4a5c066361ca1f8dfa664f1da37f65c0c373b211ce6cf00f0`;
- на расчётной позиции каждого из 16 пакетов найден строгий кандидат с
нулевым смещением уточнённой позиции.
## Текущий вывод
Все шесть отказов локализованы в PHY-заголовке: преамбулы этих пакетов лежат
внутри диапазона принятых пакетов, но в коротком окне от последних 128 символов
преамбулы до конца заголовка растёт остаток. Медиана `matched/residual` снижается
с 5,906881 dB у принятых пакетов до 4,146180 dB у отказавших.
28 сырых ошибок заголовка занимают разные позиции; ни одна позиция не
повторяется между отказавшими пакетами. TX-заголовки всех 16 пакетов идентичны,
корректны и дают текущий программный круговой тест 16/16 в legacy и T2.
Систематическая ошибка обработки заголовка не найдена.
`HEADER_FAILURE_ROOT_CAUSE = LOCAL_RF_QUALITY`
`ONE SMALL FIX JUSTIFIED = NO`
Рекомендация: закрыть текущую диагностическую ветку на достигнутом результате
10/16 и перейти к ветке управления и телеметрии CRSF/ELRS. QPSK с меньшей
символьной скоростью можно рассматривать позднее для видеоканала.
Lab067 не коммитировалась. Push не выполнялся.

View File

@@ -0,0 +1,151 @@
# Lab067: офлайн-анализ отказов PHY-заголовка Lab066
## Результат
Причина шести отказов совместима с кратковременным ростом несогласованного
остатка именно в области заголовка. Данных за небольшую ошибку логики приёмника,
временной привязки, сопровождения несущей или состояния кандидатов нет.
`HEADER_FAILURE_ROOT_CAUSE = LOCAL_RF_QUALITY`
`ONE SMALL FIX JUSTIFIED = NO`
`BRANCH DECISION = NO_SMALL_FIX_JUSTIFIED`
Исторический результат Lab066 остаётся 10/16 для legacy и 10/16 для T2.
Oracle-расчёты ниже диагностические и не меняют строгий результат.
## Целостность и геометрия данных
SHA-256 TX и RX совпали с зафиксированными значениями Lab066. RX имеет
16 000 000 комплексных отсчётов, 32 000 000 байт и длительность 2,0 с при
8 Мвыб/с. Все 16 ожидаемых позиций подтверждены строгими кандидатами;
уточнённое смещение для каждого пакета равно 0 отсчётов.
## Сводная таблица
`P err` означает ошибки 1280-символьной преамбулы. `H raw` означает ошибки
среди 144 переданных символов заголовка. `H vote` означает ошибки после штатной
мягкой суммы трёх повторений. Локальная метрика рассчитана по фиксированному
окну: последние 128 символов преамбулы и весь заголовок.
| Пакет | Строгий результат | P err | P corr | H raw | Копии 1/2/3 | H vote | Поля с ошибкой | CFO legacy, Hz | CFO T2/P3, Hz | Timing, отсч. | Локальный M/R, dB | RMS | Legacy/T2 diff | Классификация |
|---:|---|---:|---:|---:|---:|---:|---|---:|---:|---:|---:|---:|---:|---|
| 1 | HEADER FAIL | 15 | 0,898114 | 3 | 1/2/0 | 1 | length | -2,662 | -5,388 | 0 | 5,127352 | 0,554156 | 0 | HEADER_SPECIFIC_FAILURE |
| 2 | HEADER FAIL | 10 | 0,892575 | 6 | 3/2/1 | 1 | length | -11,085 | -5,424 | 0 | 3,453566 | 0,671926 | 1 | HEADER_SPECIFIC_FAILURE |
| 3 | HEADER FAIL | 11 | 0,883245 | 3 | 1/1/1 | 1 | magic | -2,144 | 2,717 | 0 | 4,588577 | 0,589619 | 0 | HEADER_SPECIFIC_FAILURE |
| 4 | PASS | 12 | 0,870256 | 0 | 0/0/0 | 0 | none | -4,970 | 0,501 | 0 | 4,498689 | 0,595752 | 0 | PASSED |
| 5 | PASS | 15 | 0,882299 | 0 | 0/0/0 | 0 | none | 3,163 | -1,271 | 0 | 8,091353 | 0,393942 | 0 | PASSED |
| 6 | PASS | 17 | 0,883426 | 0 | 0/0/0 | 0 | none | 5,595 | 1,262 | 0 | 7,317955 | 0,430628 | 0 | PASSED |
| 7 | PASS | 7 | 0,895704 | 1 | 0/0/1 | 0 | none | -1,265 | -1,236 | 0 | 6,319905 | 0,483064 | 1 | PASSED |
| 8 | PASS | 10 | 0,893515 | 3 | 1/2/0 | 0 | none | 9,131 | -0,471 | 0 | 4,986495 | 0,563216 | 0 | PASSED |
| 9 | HEADER FAIL | 13 | 0,883101 | 4 | 1/2/1 | 1 | length | 6,363 | -1,982 | 0 | 3,775053 | 0,647511 | 0 | HEADER_SPECIFIC_FAILURE |
| 10 | PASS | 14 | 0,875698 | 1 | 0/0/1 | 0 | none | 10,521 | 4,784 | 0 | 4,964081 | 0,564672 | 0 | PASSED |
| 11 | PASS | 14 | 0,873945 | 0 | 0/0/0 | 0 | none | -4,338 | 5,576 | 0 | 5,008753 | 0,561775 | 0 | PASSED |
| 12 | PASS | 15 | 0,869109 | 0 | 0/0/0 | 0 | none | -14,662 | -12,429 | 0 | 6,568840 | 0,469416 | 0 | PASSED |
| 13 | PASS | 19 | 0,887088 | 0 | 0/0/0 | 0 | none | 2,006 | -3,871 | 0 | 7,449922 | 0,424135 | 0 | PASSED |
| 14 | PASS | 13 | 0,897960 | 1 | 0/0/1 | 0 | none | 7,211 | 3,326 | 0 | 5,493857 | 0,531260 | 1 | PASSED |
| 15 | HEADER FAIL | 12 | 0,888738 | 7 | 2/2/3 | 2 | magic, length | -5,732 | -3,520 | 0 | 4,055203 | 0,626960 | 0 | HEADER_SPECIFIC_FAILURE |
| 16 | HEADER FAIL | 16 | 0,880510 | 5 | 1/2/2 | 2 | version, length | 4,734 | 228,105 | 0 | 4,237157 | 0,613963 | 107 | HEADER_SPECIFIC_FAILURE |
Полные строки битов `EXPECTED HEADER BITS`, `RECEIVED RAW HEADER BITS`,
`VOTED HEADER BITS`, причины строгого отказа и позиции ошибок находятся в
`summary.json` и `header_packet_comparison.csv`.
## Преамбула: распределения
| Метрика | Passed min / median / max | Failed min / median / max |
|---|---:|---:|
| Ошибки, бит | 7 / 14 / 19 | 10 / 12,5 / 16 |
| Доля ошибок | 0,005469 / 0,010938 / 0,014844 | 0,007813 / 0,009766 / 0,012500 |
| Корреляция | 0,869109 / 0,882862 / 0,897960 | 0,880510 / 0,885991 / 0,898114 |
| RMS отклонение | 0,489327 / 0,532530 / 0,567221 | 0,489090 / 0,523373 / 0,538197 |
| Matched power | 7,774573 / 8,330450 / 8,667865 | 7,968245 / 8,385475 / 8,982336 |
| Residual power | 2,053382 / 2,346123 / 2,645143 | 2,118219 / 2,258980 / 2,379173 |
| Matched/residual, dB | 4,924949 / 5,473142 / 6,208025 | 5,381167 / 5,624735 / 6,212224 |
Преамбула не отделяет отказавшие пакеты от принятых: медианные физические
показатели failed-группы не хуже. Ухудшение появляется после последних
128 символов преамбулы и внутри заголовка. В этом окне медиана residual power
равна 3,089822 у failed и 2,219458 у passed; медиана `matched/residual` равна
4,146180 и 5,906881 dB соответственно.
## Карта ошибок заголовка
У отказавших пакетов найдено 28 сырых ошибочных решений. Ни одна позиция
не повторяется в двух failed-пакетах. Ошибки встречаются во всех трёх копиях:
9, 11 и 8 ошибок соответственно. После мягкой суммы остаётся 1 ошибка у
пакетов 1, 2, 3 и 9 и 2 ошибки у пакетов 15 и 16.
Общей позиции, стабильно плохой копии, концентрации только в начале или только
в конце заголовка нет. Это не поддерживает гипотезу о систематической ошибке
формата или индексации заголовка.
## Переход преамбула → заголовок
На последних 128 символах преамбулы медиана фазовой RMS-ошибки составляет
0,361 rad у passed и 0,541 rad у failed. На заголовке значения составляют
0,388 и 0,627 rad. У failed-пакетов ошибки заголовка лежат в диапазоне 3–7
сырых решений, а в первых 128 символах после заголовка медиана ошибок равна 0.
Медианная амплитуда остаётся близкой к единице. Общего скачка амплитуды,
смещения точки выборки или одинакового фазового скачка не найдено. Наблюдается
короткое ухудшение фазового остатка, различное по позиции в каждом пакете.
## Timing, CFO и T2
Штатное timing-смещение и диагностическое oracle-смещение равны 0 отсчётов для
всех 16 пакетов. Расхождение legacy CFO с контрольной оценкой создаёт за весь
144-символьный заголовок фазовую ошибку от -0,02488 до +0,02079 rad. Этот
масштаб недостаточен для объяснения 1–2 ошибок после мягкого голосования.
T2 начинает влиять с символа 1280, то есть с начала заголовка. Для пакетов
1, 3, 4–6, 8–13 и 15 его жёсткие решения заголовка побитно совпадают с legacy.
Различия равны одному биту для пакетов 2, 7 и 14. У пакета 16 оценка P3 стала
выбросом 228,105 Hz и изменила 107 решений. Это ухудшение одного пакета не
объясняет шесть legacy-отказов и не даёт основания менять T2 в этой ветке.
## Паузы и положение в сеансе
Для пакета 1 исследован внешний guard длиной 800 000 отсчётов. Для пакетов
2–16 исследованы реальные паузы по 40 000 отсчётов. AC RMS перед пакетами
лежит в диапазоне 0,744879–1,302893. Признаков хвоста предыдущей формы по
критерию превышения первых 8000 отсчётов над серединой паузы на 3 dB нет.
После пакета 16 отдельно проверен конечный guard.
Группы START и END имеют больше ошибок заголовка, чем MIDDLE 1, однако пакет 9
отказывает в середине, пакеты 4, 13 и 14 проходят, а timing, CFO и фон не дают
монотонного временного тренда. Расположение пакетов не доказывает
`START_END_TRANSIENT`.
## 145 кандидатов
Строгий журнал содержит 145 проверок:
- 27 проверок на точных позициях преамбулы, 16 уникальных позиций и 11
повторных проверок той же позиции;
- 54 локальных максимума повторяющейся PRBS-структуры внутри формы пакета;
- 56 кандидатов в нулевых паузах;
- 8 кандидатов вне этих областей.
Каждый кандидат получает новый `PacketMeasure` и полностью независимый строгий
проход. Состояние после отказа не переносится. Граница `accepted_until`
изменяется только после CRC PASS. Большое число кандидатов увеличивает объём
работы, но не объясняет выборочные ошибки настоящих заголовков.
## TX и решение по ветке
Все 16 TX-заголовков побитно идентичны. Magic `0xD391`, версия 1, длина
268 байт, checksum и тройное повторение корректны. Текущий программный прогон
дал 16/16 точных пакетов и для legacy, и для T2.
Конкретная небольшая ошибка приёмника, которая объяснила бы значимую часть
шести отказов, не найдена. Зафиксирован достигнутый результат: 10/16 точных
полных пакетов при 500 ксимв/с и TX VGA 20 dB в аппаратно валидной OTA-записи.
Текущую диагностическую ветку следует закрыть. Следующая проектная ветка:
CRSF/ELRS для управления и телеметрии.
QPSK с меньшей скоростью символов остаётся будущим кандидатом для видеоканала.
В Lab067 QPSK, новый PHY и изменения BPSK не выполнялись.
RF TX = 0. Lab067 не коммитировалась. Push не выполнялся.

View File

@@ -0,0 +1,475 @@
"""Lab062: подготовка полного 500K PHY-сеанса и RX-only preflight."""
from __future__ import annotations
from dataclasses import asdict
import hashlib
import json
from pathlib import Path
import subprocess
import sys
import time
if __package__ in (None, ""):
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import numpy as np
from experiments import lab049_bpsk_symbol_rate as phy
from experiments import lab053_packet_processing as packet_processing
from experiments import lab053_streaming_receiver as streaming
from experiments import lab054_hardware_control as lab054
from experiments import lab056_abab_energy as measurements
from experiments import lab056_capture_runner as hardware
ROOT = Path(__file__).resolve().parents[1]
RAW = ROOT / "data/raw/lab062"
OUTPUT = ROOT / "data/processed/lab062"
POINT = hardware.OperatingPoint(
frequency_hz=1_400_000_000,
physical_path="MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
path_confirmed=True,
tx_antenna="existing 1400 MHz antenna near window",
rx_antenna="existing 1400 MHz antenna on desk",
distance_m=1.2,
orientation="same polarization; fixed during preflight and RF session",
visibility="LOS indoor",
)
MODE = phy.PhyMode(500_000)
PACKETS = 16
PAYLOAD_BYTES = 256
PREFLIGHT_SAMPLES = 800_000
RX_SECONDS = 3
RX_SAMPLES = RX_SECONDS * MODE.sample_rate_hz
RX_LEAD_SECONDS = 0.5
STRONG_AC_RMS_CODE = 20.0
STRONG_COMPONENT_CODE = 100.0
def save_new(path: Path, value: dict) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("x", encoding="utf-8") as stream:
json.dump(value, stream, ensure_ascii=False, indent=2)
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
while block := stream.read(1024 * 1024):
digest.update(block)
return digest.hexdigest()
def plans():
result = lab054.plans()
if len(result) != PACKETS or any(len(frame.plan.payload) != PAYLOAD_BYTES for frame in result):
raise RuntimeError("Штатный генератор не дал 16 payload по 256 байт")
return result
def parameters() -> dict:
return {
"rf_frequency_hz": POINT.frequency_hz,
"sample_rate_hz": MODE.sample_rate_hz,
"symbol_rate": MODE.symbol_rate,
"samples_per_symbol": MODE.samples_per_symbol,
"digital_carrier_hz": lab054.phy.lab045.CARRIER_OFFSET_HZ,
"packets": PACKETS,
"payload_bytes": PAYLOAD_BYTES,
"tx_vga_db": 10,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": False,
"bias_tee": False,
"geometry": asdict(POINT),
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN",
}
def transfer_command(path: Path | str, samples: int, *, transmit: bool = False) -> list[str]:
return hardware.command(POINT, path, samples, transmit=transmit)
def prepare() -> dict:
RAW.mkdir(parents=True, exist_ok=True)
OUTPUT.mkdir(parents=True, exist_ok=True)
waveform_path = RAW / "tx_stream.cs8"
if waveform_path.exists():
raise FileExistsError("Lab062 TX уже существует; перезапись запрещена")
with waveform_path.open("xb") as stream:
for frame in plans():
stream.write(phy.build_parameterized_tx_cs8(frame.plan, MODE))
samples = waveform_path.stat().st_size // 2
result = {
"lab": "Lab062", "stage": "PREPARATION_ONLY", "rf_tx_count": 0,
"head": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(),
"parameters": parameters(), "tx_samples": samples,
"tx_bytes": waveform_path.stat().st_size,
"tx_duration_seconds": samples / MODE.sample_rate_hz,
"tx_sha256": sha256(waveform_path), "rx_samples": RX_SAMPLES,
"rx_duration_seconds": RX_SECONDS, "automatic_retry": False,
"tx_command_prepared_not_run": transfer_command(waveform_path, samples, transmit=True),
"rx_command_prepared_not_run": transfer_command(RAW / "rx_stream.cs8", RX_SAMPLES),
}
save_new(RAW / "tx_metadata.json", result)
save_new(OUTPUT / "preparation.json", result)
return result
def validate_prepared() -> dict:
metadata = json.loads((RAW / "tx_metadata.json").read_text(encoding="utf-8"))
path = RAW / "tx_stream.cs8"
expected = hashlib.sha256()
expected_bytes = 0
for frame in plans():
block = phy.build_parameterized_tx_cs8(frame.plan, MODE)
expected.update(block)
expected_bytes += len(block)
if (metadata.get("stage") != "PREPARATION_ONLY" or metadata.get("rf_tx_count") != 0
or metadata.get("parameters") != parameters() or path.stat().st_size != expected_bytes
or metadata.get("tx_sha256") != expected.hexdigest() or sha256(path) != expected.hexdigest()):
raise RuntimeError("Подготовленный Lab062 TX или параметры изменились")
return metadata
def decode(mode: str, source_path: Path | None = None, *, diagnostics: bool = False) -> dict:
observations = []
receiver = streaming.StreamingReceiver(
processor=packet_processing.PacketProcessor(carrier_tracking_mode=mode),
packet_observer=lambda row, outcome: observations.append((row, outcome)),
)
received = []
with (source_path or (RAW / "tx_stream.cs8")).open("rb") as stream:
while block := stream.read(2 * receiver.block_samples):
values = np.frombuffer(block, np.int8)
samples = values[::2].astype(np.float32) + 1j * values[1::2].astype(np.float32)
received.extend(receiver.push_iq_block(samples.astype(np.complex64)))
received.extend(receiver.finish())
expected = [frame.plan.payload for frame in plans()]
actual = [item.payload for item in received]
result = {
"mode": mode, "candidates": len(observations), "true_packets_found": len(actual),
"header_pass": sum(outcome.phy_header_pass for _, outcome in observations),
"fec_started": sum(outcome.fec_attempted for _, outcome in observations),
"fec_pass": sum(outcome.fec_pass for _, outcome in observations),
"crc_started": sum(outcome.crc != "NOT_REACHED" for _, outcome in observations),
"crc_pass": sum(outcome.crc == "PASS" for _, outcome in observations),
"packet_output": len(actual),
"exact_payload_match": sum(payload in expected for payload in actual),
"exact_ordered_payloads": actual == expected,
"passed": len(actual) == PACKETS and actual == expected,
}
if diagnostics:
payload_to_index = {payload: index + 1 for index, payload in enumerate(expected)}
result["passed_packet_indexes"] = sorted(
payload_to_index[payload] for payload in actual if payload in payload_to_index
)
rows = []
for row, outcome in observations:
payload = None
if outcome.frame is not None and outcome.frame.reception.payload_bytes is not None:
payload = bytes(outcome.frame.reception.payload_bytes)
traces = row.get("carrier_tracking_traces", ())
final_frequency = None
if traces and len(traces[-1].frequency_hz):
final_frequency = float(traces[-1].frequency_hz[-1])
rows.append({
"absolute_refined": int(row["absolute_refined"]),
"reason": outcome.reason,
"header": bool(outcome.phy_header_pass),
"fec_started": bool(outcome.fec_attempted),
"fec": bool(outcome.fec_pass),
"crc_started": outcome.crc != "NOT_REACHED",
"crc": outcome.crc == "PASS",
"packet_output": bool(outcome.accepted and outcome.crc == "PASS"),
"packet_index_after_verdict": payload_to_index.get(payload),
"initial_frequency_hz": row.get("cfo_hz"),
"t2_final_frequency_hz": final_frequency,
"t2_lock_status": "NOT_DEFINED_BY_IMPLEMENTATION" if mode == "t2" else "NOT_APPLICABLE",
})
result["rows"] = rows
result["detector_statistics"] = dict(receiver.detection_statistics)
result["candidate_overflow"] = receiver.candidate_overflow
return result
def software_gate() -> dict:
metadata = validate_prepared()
legacy = decode("legacy")
t2 = decode("t2")
result = {
"lab": "Lab062", "stage": "SOFTWARE_GATE", "rf_tx_count": 0,
"tx_sha256": metadata["tx_sha256"], "legacy": legacy, "t2": t2,
"passed": legacy["passed"] and t2["passed"],
}
save_new(OUTPUT / "software_gate.json", result)
if not result["passed"]:
raise RuntimeError("Lab062 software gate FAIL")
return result
def preflight(*, runner=None, process_checker=None, clock_checker=None,
sleep_function=time.sleep) -> dict:
metadata = validate_prepared()
software = json.loads((OUTPUT / "software_gate.json").read_text(encoding="utf-8"))
if not software.get("passed") or software.get("tx_sha256") != metadata["tx_sha256"]:
raise RuntimeError("Нет действующего software gate")
save_new(RAW / "preflight_attempt.json", {
"lab": "Lab062", "rf_tx_count": 0, "point": asdict(POINT),
"tx_sha256": metadata["tx_sha256"],
})
actual_runner = runner or lab054.clock._default_command_runner
process_checker = process_checker or lab054.check_processes
clock_checker = clock_checker or hardware.common_clock
def rx_only(command):
if "-t" in command:
raise PermissionError("TX запрещён в Lab062 preflight")
return actual_runner(command)
result = {
"lab": "Lab062", "stage": "RX_ONLY_PREFLIGHT", "passed": False,
"rf_tx_count": 0, "point": asdict(POINT), "parameters": parameters(),
"tx_sha256": metadata["tx_sha256"], "stop_before_tx": True,
}
clock_started = False
try:
before = process_checker()
result["process_before"] = before.to_dict()
lab054.require_clear(before)
result["inventory"] = lab054.phy.lab045._verify_device_inventory(rx_only)
clock_started = True
result["clock"] = clock_checker(
POINT, rx_only, lab054.clock.TransmitGuard(), sleep_function=sleep_function
)
hardware.require_clock_pass(result["clock"])
path = RAW / "preflight_rx.cs8"
if path.exists():
raise FileExistsError("Lab062 preflight RX уже существует")
captured = rx_only(transfer_command(path, PREFLIGHT_SAMPLES))
result["rx_process"] = {
"returncode": captured.returncode,
"stdout": captured.stdout or "", "stderr": captured.stderr or "",
}
log = (captured.stdout or "") + (captured.stderr or "")
if captured.returncode or not hardware.clean_counter_log(log, "overrun"):
raise RuntimeError("RX preflight: процесс или счётчик overruns не прошёл")
if path.stat().st_size != 2 * PREFLIGHT_SAMPLES:
raise RuntimeError("Неверная длина Lab062 preflight RX")
level = hardware.receive_level(path)
# У RX-only фона нет символов. Унаследованная метрика Lab056 была бы
# привязана к её 20 ksymbol/s и здесь физически неприменима.
level.pop("symbol_energy_code2_seconds", None)
level["symbol_energy"] = "NOT_APPLICABLE_TO_BACKGROUND"
ac_rms = float(np.sqrt(max(0.0, level["ac_power_code2"])))
strong = bool(ac_rms >= STRONG_AC_RMS_CODE or level["max_abs_i"] >= STRONG_COMPONENT_CODE
or level["max_abs_q"] >= STRONG_COMPONENT_CODE)
level.update({
"ac_rms_code": ac_rms,
"unexpected_strong_signal": strong,
"strong_signal_rule": (
f"AC RMS >= {STRONG_AC_RMS_CODE} code or max |I|/|Q| >= "
f"{STRONG_COMPONENT_CODE} code"
),
})
result["rx_level"] = level
result["rx_sha256"] = sha256(path)
result["rx_overruns"] = 0
if level["saturation_detected"]:
raise RuntimeError("RX clipping; STOP без изменения gain")
if strong:
raise RuntimeError("Неожиданно сильный RX-only фон; STOP без изменения gain")
result["passed"] = True
except Exception as error:
result["error"] = str(error)
raise
finally:
errors = lab054.disable_clock_outputs(rx_only) if clock_started else []
try:
after = process_checker()
result["process_after"] = after.to_dict()
lab054.require_clear(after)
except Exception as error:
errors.append(str(error))
result["cleanup_errors"] = errors
result["passed"] = result["passed"] and not errors
save_new(RAW / "preflight_result.json", result)
OUTPUT.mkdir(parents=True, exist_ok=True)
(OUTPUT / "preflight_result.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8"
)
if not result["passed"]:
raise RuntimeError("Lab062 preflight cleanup FAIL")
return result
def require_preflight(metadata: dict) -> dict:
"""Проверить сохранённый preflight именно для подготовленного потока Lab062."""
record = json.loads((RAW / "preflight_result.json").read_text(encoding="utf-8"))
if (record.get("passed") is not True or record.get("rf_tx_count") != 0
or record.get("point") != asdict(POINT)
or record.get("parameters") != parameters()
or record.get("tx_sha256") != metadata["tx_sha256"]):
raise PermissionError("Нет успешного RX-only preflight для этой конфигурации Lab062")
hardware.require_clock_pass(record.get("clock", {}))
level = record.get("rx_level", {})
if (level.get("saturation_detected") is not False
or level.get("unexpected_strong_signal") is not False
or record.get("rx_overruns") != 0):
raise PermissionError("RX-only preflight не разрешает передачу")
return record
def capture_once(*, authorization: bool = False, runner=None, process_starter=None,
process_checker=None, clock_checker=None,
sleep_function=time.sleep) -> dict:
"""Выполнить один RX-first сеанс и навсегда израсходовать попытку до обращения к SDR."""
if authorization is not True:
raise PermissionError("Нужно отдельное разрешение на единственный RF-сеанс Lab062")
metadata = validate_prepared()
require_preflight(metadata)
receive_path = RAW / "rx_stream.cs8"
if receive_path.exists() or (RAW / "capture_result.json").exists():
raise FileExistsError("Аппаратный результат Lab062 уже существует")
actual_runner = runner or lab054.clock._default_command_runner
process_starter = process_starter or lab054.clock._default_process_starter
process_checker = process_checker or lab054.check_processes
clock_checker = clock_checker or hardware.common_clock
save_new(RAW / "hardware_attempt.json", {
"lab": "Lab062", "authorized_once": True, "automatic_retry": False,
"point": asdict(POINT), "parameters": parameters(),
"tx_sha256": metadata["tx_sha256"],
})
result = {
"lab": "Lab062", "stage": "SINGLE_RF_CAPTURE", "passed": False,
"rf_tx_count": 0, "automatic_tx_repeats": 0,
"point": asdict(POINT), "parameters": parameters(),
"tx_sha256": metadata["tx_sha256"],
}
guard = lab054.clock.TransmitGuard()
process = None
clock_started = False
try:
before = process_checker()
result["process_before"] = before.to_dict()
lab054.require_clear(before)
result["inventory"] = lab054.phy.lab045._verify_device_inventory(actual_runner)
clock_started = True
result["clock"] = clock_checker(
POINT, actual_runner, guard, sleep_function=sleep_function
)
hardware.require_clock_pass(result["clock"])
process = process_starter(
transfer_command(receive_path, RX_SAMPLES),
RAW / "rx_stdout.txt", RAW / "rx_stderr.txt",
)
sleep_function(RX_LEAD_SECONDS)
if process.poll() is not None:
raise RuntimeError("RX завершился до TX")
before_tx = hardware.receive_level(receive_path, tail_samples=65536)
before_tx.pop("symbol_energy_code2_seconds", None)
result["rx_level_before_tx"] = before_tx
if before_tx["saturation_detected"]:
raise RuntimeError("RX clipping до TX; RF TX = 0")
guard.register_transmit()
result["rf_tx_count"] = guard.transmit_calls
transmitted = actual_runner(transfer_command(
RAW / "tx_stream.cs8", metadata["tx_samples"], transmit=True
))
save_new(RAW / "tx_process_result.json", {
"returncode": transmitted.returncode,
"stdout": transmitted.stdout or "", "stderr": transmitted.stderr or "",
})
if transmitted.returncode:
raise RuntimeError("Единственный TX завершился ошибкой; повтор запрещён")
if process.wait(RX_SECONDS + 10):
raise RuntimeError("RX завершился ошибкой; передача уже выполнена, повтор запрещён")
process.close_logs()
result["rx_samples"] = receive_path.stat().st_size // 2
result["rx_bytes"] = receive_path.stat().st_size
result["rx_duration_seconds"] = result["rx_samples"] / MODE.sample_rate_hz
if result["rx_bytes"] != RX_SAMPLES * 2:
raise RuntimeError("Повреждённая длина RX; передача уже выполнена, повтор запрещён")
rx_log = "".join(
(RAW / f"rx_{kind}.txt").read_text(encoding="utf-8")
for kind in ("stdout", "stderr")
)
tx_log = (transmitted.stdout or "") + (transmitted.stderr or "")
if not hardware.clean_counter_log(rx_log, "overrun"):
raise RuntimeError("RX overrun или неоднозначный счётчик; повтор запрещён")
if not hardware.clean_counter_log(tx_log, "underrun"):
raise RuntimeError("TX underrun или неоднозначный счётчик; повтор запрещён")
result["rx_overruns"] = 0
result["tx_underruns"] = 0
result["rx_sha256"] = sha256(receive_path)
level = hardware.receive_level(receive_path)
level.pop("symbol_energy_code2_seconds", None)
result["rx_level"] = level
result["rx_clipping"] = bool(level["saturation_detected"])
if result["rx_clipping"]:
raise RuntimeError("RX clipping в записи; передача уже выполнена, повтор запрещён")
result["passed"] = True
except Exception as error:
result["error"] = str(error)
raise
finally:
errors = []
if process is not None:
try:
process.terminate()
except Exception as error:
errors.append(str(error))
if clock_started:
errors.extend(lab054.disable_clock_outputs(actual_runner))
try:
after = process_checker()
result["process_after"] = after.to_dict()
lab054.require_clear(after)
except Exception as error:
errors.append(str(error))
result["cleanup_errors"] = errors
result["passed"] = result["passed"] and not errors
save_new(RAW / "capture_result.json", result)
OUTPUT.mkdir(parents=True, exist_ok=True)
(OUTPUT / "capture_result.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8"
)
if not result["passed"]:
raise RuntimeError("Lab062 RF-сеанс завершён с ошибкой; повтор запрещён")
return result
def run_functional_tests() -> None:
assert MODE.samples_per_symbol == 16
assert len(plans()) == 16
assert all(len(frame.plan.payload) == 256 for frame in plans())
assert "-t" not in transfer_command("NUL", 65536)
assert "-t" in transfer_command("NUL", 65536, transmit=True)
def main() -> None:
import argparse
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--stage", choices=("prepare", "software", "preflight", "capture"), required=True)
parser.add_argument("--authorize-one-rf", action="store_true")
arguments = parser.parse_args()
if arguments.stage == "prepare":
result = prepare()
elif arguments.stage == "software":
result = software_gate()
elif arguments.stage == "preflight":
result = preflight()
else:
result = capture_once(authorization=arguments.authorize_one_rf)
print(json.dumps(result, ensure_ascii=False, indent=2))
print("RF TX = 0")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,330 @@
"""Lab062: офлайн-анализ единственной сохранённой RX IQ-записи."""
from __future__ import annotations
from collections import Counter
import csv
import json
import math
from pathlib import Path
import re
import sys
if __package__ in (None, ""):
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import numpy as np
from scipy import signal
from experiments import lab058_abab_symbol_quality as lab058
from experiments import lab062_full_packet_rf_preflight as lab062
def counter_values(text: str, name: str) -> list[int]:
pattern = re.compile(rf"(?<![\w.+-])(\d+)\s+(?:(?:rx|tx)\s+)?{name}s?\b", re.I)
return [int(match.group(1)) for match in pattern.finditer(text)]
def locate_burst(tx: lab058.Cs8File, rx: lab058.Cs8File, frame_samples: int) -> dict:
"""Найти начало по первому полному пакету, не передавая границы декодеру."""
stride = lab062.MODE.samples_per_symbol
tx_raw = np.memmap(tx.path, np.int8, mode="r")
rx_raw = np.memmap(rx.path, np.int8, mode="r")
tx_decimated = (
tx_raw[0:2 * frame_samples:2 * stride].astype(np.float32)
+ 1j * tx_raw[1:2 * frame_samples:2 * stride].astype(np.float32)
)
rx_decimated = (
rx_raw[0::2 * stride].astype(np.float32)
+ 1j * rx_raw[1::2 * stride].astype(np.float32)
)
tx_decimated -= np.mean(tx_decimated)
rx_decimated -= np.mean(rx_decimated)
correlation = signal.correlate(rx_decimated, tx_decimated, mode="valid", method="fft")
coarse = int(np.argmax(abs(correlation))) * stride
first = tx.read(0, frame_samples).astype(np.complex128)
first -= np.mean(first)
candidates = range(max(0, coarse - 2 * stride), min(rx.size - frame_samples, coarse + 2 * stride) + 1)
values = []
for start in candidates:
received = rx.read(start, frame_samples).astype(np.complex128)
received -= np.mean(received)
values.append(abs(np.vdot(first, received)))
offset = int(np.argmax(values))
start = candidates.start + offset
median = float(np.median(abs(correlation)))
return {
"rx_start_sample": start,
"coarse_start_sample": coarse,
"correlation_peak_to_median": float(abs(correlation[coarse // stride]) / max(median, 1e-30)),
"method": "TX first-frame correlation; used only after strict receiver verdict",
}
def strict_row(rows: list[dict], nominal: int) -> dict | None:
if not rows:
return None
selected = min(rows, key=lambda row: abs(row["absolute_refined"] - nominal))
return selected if abs(selected["absolute_refined"] - nominal) <= 64 else None
def diagnostic_symbol_rows(rx: lab058.Cs8File, start: int, frame_samples: int,
mode: str) -> list[dict]:
processor = lab062.packet_processing.PacketProcessor(carrier_tracking_mode=mode)
rows = []
for index, frame in enumerate(lab062.plans(), 1):
values = rx.read(start + (index - 1) * frame_samples, frame_samples).astype(np.complex64)
context = lab062.packet_processing.PacketMeasure()
token = lab062.packet_processing.CURRENT.set(context)
try:
probe = processor.extract(values, 0, frame.plan.frame_symbol_count)
finally:
lab062.packet_processing.CURRENT.reset(token)
expected = 2.0 * frame.plan.frame_bits.astype(np.float64) - 1.0
if not probe.passed or probe.normalized_real.size != expected.size:
rows.append({"packet_index": index, "measurable": False, "reason": probe.reason})
continue
soft = np.asarray(probe.normalized_real, dtype=np.float64)
errors = np.signbit(soft) != np.signbit(expected)
p = lab062.phy.lab045.PREAMBLE_BIT_COUNT
h = p + lab062.phy.lab045.PHY_HEADER_BIT_COUNT
traces = context.cache.get("carrier_tracking_traces", ())
final_frequency = None
if traces and len(traces[-1].frequency_hz):
final_frequency = float(traces[-1].frequency_hz[-1])
rows.append({
"packet_index": index,
"measurable": True,
"preamble_symbol_errors": int(np.sum(errors[:p])),
"header_symbol_errors": int(np.sum(errors[p:h])),
"payload_symbols_before_fec_errors": int(np.sum(errors[h:])),
"symbols": int(len(expected)),
"symbol_errors": int(np.sum(errors)),
"symbol_error_rate": float(np.mean(errors)),
"symbol_rms_deviation": float(np.sqrt(np.mean((soft - expected) ** 2))),
"initial_frequency_hz": float(probe.carrier["cfo_hz"]),
"t2_final_frequency_hz": final_frequency,
"t2_lock_status": "NOT_DEFINED_BY_IMPLEMENTATION" if mode == "t2" else "NOT_APPLICABLE",
})
return rows
def waveform_quality(tx: lab058.Cs8File, rx: lab058.Cs8File, start: int) -> dict:
transmitted = tx.read(0, tx.size).astype(np.complex128)
received = rx.read(start, tx.size).astype(np.complex128)
transmitted -= np.mean(transmitted)
received -= np.mean(received)
product = received * np.conj(transmitted)
block = 4096
count = len(product) // block
block_values = np.mean(product[:count * block].reshape(count, block), axis=1)
block_times = (np.arange(count) * block + 0.5 * block) / lab062.MODE.sample_rate_hz
phase = np.unwrap(np.angle(block_values))
weights = np.maximum(abs(block_values), 1e-12)
design = np.column_stack((np.ones(count), block_times))
root = np.sqrt(weights / np.max(weights))
coefficients, *_ = np.linalg.lstsq(design * root[:, None], phase * root, rcond=None)
frequency_hz = float(coefficients[1] / (2 * np.pi))
times = np.arange(len(received)) / lab062.MODE.sample_rate_hz
corrected = received * np.exp(-2j * np.pi * frequency_hz * times)
gain = np.vdot(transmitted, corrected) / np.vdot(transmitted, transmitted)
matched = gain * transmitted
residual = corrected - matched
matched_power = float(np.mean(abs(matched) ** 2))
residual_power = float(np.mean(abs(residual) ** 2))
frequencies, tx_psd = signal.welch(
transmitted, fs=lab062.MODE.sample_rate_hz, nperseg=8192,
noverlap=4096, return_onesided=False,
)
_, rx_psd = signal.welch(
corrected, fs=lab062.MODE.sample_rate_hz, nperseg=8192,
noverlap=4096, return_onesided=False,
)
_, cross = signal.csd(
corrected, transmitted, fs=lab062.MODE.sample_rate_hz, nperseg=8192,
noverlap=4096, return_onesided=False,
)
transfer = np.conj(cross) / np.maximum(tx_psd, 1e-30)
coherence = abs(cross) ** 2 / np.maximum(tx_psd * rx_psd, 1e-30)
occupied = tx_psd >= np.max(tx_psd) * 0.01
stable = occupied & (coherence >= 0.5)
gain_db = 20 * np.log10(np.maximum(abs(transfer[stable]), 1e-30))
return {
"frequency_offset_hz": frequency_hz,
"complex_gain": {"real": float(gain.real), "imag": float(gain.imag)},
"matched_component_power_code2": matched_power,
"residual_power_code2": residual_power,
"matched_residual_db": float(10 * math.log10(matched_power / residual_power)),
"residual_interpretation": "Contains noise, channel distortion and any TX-underrun effect; not pure noise",
"band_bins": int(np.sum(stable)),
"band_gain_nonuniformity_p95_p05_db": (
float(np.percentile(gain_db, 95) - np.percentile(gain_db, 5)) if gain_db.size else None
),
"band_gain_max_min_db": float(np.ptp(gain_db)) if gain_db.size else None,
"median_coherence": float(np.median(coherence[stable])) if np.any(stable) else None,
"tx_psd_threshold_db": -20.0,
"coherence_threshold": 0.5,
}
def lab058_quality(tx: lab058.Cs8File, rx: lab058.Cs8File, start: int,
frame_samples: int) -> dict:
"""Применить к каждому полному PHY-кадру неизменённую методику Lab058."""
rows = []
for index, frame in enumerate(lab062.plans(), 1):
offset = (index - 1) * frame_samples
transmitted = tx.read(offset, frame_samples)
received = rx.read(start + offset, frame_samples)
expected = 2.0 * frame.plan.frame_bits.astype(np.float64) - 1.0
metrics, _working = lab058.analyze_values(received, expected, lab062.MODE.symbol_rate)
channel, _arrays = lab058.channel_metrics(
transmitted, received, lab062.MODE.symbol_rate, metrics["oracle"]["cfo_hz"]
)
rows.append({"packet_index": index, "oracle": metrics["oracle"], "channel": channel})
selected = [row["oracle"]["metrics"] for row in rows]
errors = sum(row["errors"] for row in selected)
symbols = sum(row["symbols"] for row in selected)
matched = float(np.mean([row["matched_component_power"] for row in selected]))
residual = float(np.mean([row["residual_power"] for row in selected]))
ripple = [row["channel"]["amplitude_ripple_p95_p05_db"] for row in rows]
return {
"method": "Lab058 analyze_values/oracle validation tiles, independently per full PHY packet",
"packets": rows,
"symbol_errors": errors,
"symbols": symbols,
"symbol_error_rate": errors / symbols,
"evm_rms": float(math.sqrt(residual / matched)),
"matched_component_power": matched,
"residual_power": residual,
"matched_residual_db": float(10 * math.log10(matched / residual)),
"residual_interpretation": "Contains noise and unmodelled distortion; not pure noise",
"band_gain_nonuniformity_p95_p05_db_median": float(np.median(ripple)),
"band_gain_nonuniformity_p95_p05_db_min": float(np.min(ripple)),
"band_gain_nonuniformity_p95_p05_db_max": float(np.max(ripple)),
}
def analyze() -> dict:
capture = json.loads((lab062.RAW / "capture_result.json").read_text(encoding="utf-8"))
legacy = json.loads((lab062.OUTPUT / "legacy_rf_decode.json").read_text(encoding="utf-8"))
t2 = json.loads((lab062.OUTPUT / "t2_rf_decode.json").read_text(encoding="utf-8"))
tx = lab058.Cs8File(lab062.RAW / "tx_stream.cs8")
rx = lab058.Cs8File(lab062.RAW / "rx_stream.cs8")
frame_samples = lab062.phy.frame_waveform_sample_count(lab062.plans()[0].plan, lab062.MODE)
location = locate_burst(tx, rx, frame_samples)
start = location["rx_start_sample"]
legacy_symbols = diagnostic_symbol_rows(rx, start, frame_samples, "legacy")
t2_symbols = diagnostic_symbol_rows(rx, start, frame_samples, "t2")
packet_rows = []
for index in range(1, lab062.PACKETS + 1):
nominal = start + (index - 1) * frame_samples
legacy_strict = strict_row(legacy["rows"], nominal)
t2_strict = strict_row(t2["rows"], nominal)
packet_rows.append({
"packet_index": index,
"nominal_rx_start": nominal,
"legacy": legacy_strict,
"t2": t2_strict,
"diagnostic_legacy": legacy_symbols[index - 1],
"diagnostic_t2": t2_symbols[index - 1],
})
rx_log = (lab062.RAW / "rx_stderr.txt").read_text(encoding="utf-8")
tx_process = json.loads((lab062.RAW / "tx_process_result.json").read_text(encoding="utf-8"))
tx_log = (tx_process.get("stdout") or "") + (tx_process.get("stderr") or "")
level = lab062.hardware.receive_level(lab062.RAW / "rx_stream.cs8")
level.pop("symbol_energy_code2_seconds", None)
quality = waveform_quality(tx, rx, start)
comparable_quality = lab058_quality(tx, rx, start, frame_samples)
all_diag = [row for row in t2_symbols if row.get("measurable")]
total_errors = sum(row["symbol_errors"] for row in all_diag)
total_symbols = sum(row["symbols"] for row in all_diag)
rms = math.sqrt(sum(row["symbol_rms_deviation"] ** 2 * row["symbols"] for row in all_diag) / total_symbols)
legacy_set = set(legacy["passed_packet_indexes"])
t2_set = set(t2["passed_packet_indexes"])
result = {
"lab": "Lab062",
"status": "RF_SESSION_INVALID_TX_UNDERRUN",
"rf_tx_count": capture["rf_tx_count"],
"automatic_tx_repeats": capture["automatic_tx_repeats"],
"integrity": {
"tx_sha256": lab062.sha256(lab062.RAW / "tx_stream.cs8"),
"rx_sha256": lab062.sha256(lab062.RAW / "rx_stream.cs8"),
"rx_samples": rx.size,
"rx_bytes": (lab062.RAW / "rx_stream.cs8").stat().st_size,
"rx_duration_seconds": rx.size / lab062.MODE.sample_rate_hz,
"rx_overrun_values": counter_values(rx_log, "overrun"),
"tx_underrun_values": counter_values(tx_log, "underrun"),
"rx_overruns_max": max(counter_values(rx_log, "overrun"), default=None),
"tx_underruns_max": max(counter_values(tx_log, "underrun"), default=None),
"rx_clipping": bool(level["saturation_detected"]),
"rx_clipped_samples_fraction": level["clipped_samples_fraction"],
},
"clock": capture["clock"],
"cleanup_errors": capture["cleanup_errors"],
"location": location,
"legacy": {key: value for key, value in legacy.items() if key != "rows"},
"t2": {key: value for key, value in t2.items() if key != "rows"},
"passed_by_both": sorted(legacy_set & t2_set),
"passed_only_by_legacy": sorted(legacy_set - t2_set),
"passed_only_by_t2": sorted(t2_set - legacy_set),
"failed_by_both": sorted(set(range(1, 17)) - legacy_set - t2_set),
"packet_rows": packet_rows,
"diagnostic_symbol_error_rate_t2": total_errors / total_symbols,
"symbol_rms_deviation_t2": rms,
"lab058_quality": comparable_quality,
"waveform_quality": quality,
"lab056_comparison": {
"lab056_B_oracle_symbol_error_rate": 0.03495896,
"lab056_B_oracle_evm_rms": 0.845350,
"scope": "Lab056 used a different PRBS ABAB waveform and method; values are contextual, not identical estimands",
},
"primary_result": (
"The sole RF session is invalid as a clean legacy-versus-T2 acceptance test because "
"hackrf_transfer reported one transient TX underrun; both strict modes produced 0/16."
),
"recommended_next_single_step": (
"Offline localize the underrun position against packet boundaries before deciding whether a new RF lab is justified."
),
"rf_tx_now": 0,
"commit": "NOT_PERFORMED", "push": "NOT_PERFORMED", "lab063": "NOT_CREATED",
}
lab062.OUTPUT.mkdir(parents=True, exist_ok=True)
(lab062.OUTPUT / "rf_analysis.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8"
)
with (lab062.OUTPUT / "packet_comparison.csv").open("w", newline="", encoding="utf-8-sig") as stream:
writer = csv.writer(stream)
writer.writerow([
"packet_index", "legacy_header", "legacy_fec", "legacy_crc", "legacy_output",
"t2_header", "t2_fec", "t2_crc", "t2_output", "preamble_errors_t2",
"header_errors_t2", "payload_errors_before_fec_t2", "initial_frequency_hz_t2",
"t2_final_frequency_hz", "t2_lock_status",
])
for row in packet_rows:
legacy_row, t2_row, diagnostic = row["legacy"], row["t2"], row["diagnostic_t2"]
writer.writerow([
row["packet_index"], *(legacy_row.get(key) if legacy_row else False for key in ("header", "fec", "crc", "packet_output")),
*(t2_row.get(key) if t2_row else False for key in ("header", "fec", "crc", "packet_output")),
diagnostic.get("preamble_symbol_errors"), diagnostic.get("header_symbol_errors"),
diagnostic.get("payload_symbols_before_fec_errors"), diagnostic.get("initial_frequency_hz"),
diagnostic.get("t2_final_frequency_hz"), diagnostic.get("t2_lock_status"),
])
return result
def main() -> None:
result = analyze()
concise = {key: result[key] for key in (
"status", "rf_tx_count", "automatic_tx_repeats", "integrity", "legacy", "t2",
"passed_by_both", "passed_only_by_legacy", "passed_only_by_t2", "failed_by_both",
"diagnostic_symbol_error_rate_t2", "symbol_rms_deviation_t2", "waveform_quality",
"primary_result", "recommended_next_single_step", "rf_tx_now",
)}
print(json.dumps(concise, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,567 @@
"""Lab063: офлайн-локализация TX underrun и ухудшения качества Lab062."""
from __future__ import annotations
from dataclasses import dataclass
import csv
import json
import math
from pathlib import Path
import re
import sys
if __package__ in (None, ""):
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal
from experiments import lab058_abab_symbol_quality as lab058
from experiments import lab062_full_packet_rf_preflight as lab062
ROOT = Path(__file__).resolve().parents[1]
RAW = ROOT / "data/raw/lab062"
LAB062 = ROOT / "data/processed/lab062"
OUTPUT = ROOT / "data/processed/lab063"
TX_PATH = RAW / "tx_stream.cs8"
RX_PATH = RAW / "rx_stream.cs8"
FRAME_SAMPLES = 92_256
PACKETS = 16
SAMPLE_RATE = 8_000_000
SYMBOL_RATE = 500_000
WINDOW_SYMBOLS = 512
WINDOW_SAMPLES = WINDOW_SYMBOLS * (SAMPLE_RATE // SYMBOL_RATE)
STEP_SYMBOLS = 256
STEP_SAMPLES = STEP_SYMBOLS * (SAMPLE_RATE // SYMBOL_RATE)
SEARCH_MARGIN_SAMPLES = 12_000
MIN_LOCAL_CORRELATION = 0.15
RELIABLE_PACKET_START = 24_000
RELIABLE_PACKET_END = 86_000
LAB056_B = {
"symbol_error_rate": 0.03495896,
"evm_rms": 0.845350,
"matched_residual_db": 1.464846,
"band_ripple_db": 5.471382,
}
@dataclass(frozen=True)
class ArrayReader:
"""Минимальный интерфейс чтения для автономных проверок алгоритма."""
values: np.ndarray
@property
def size(self) -> int:
return int(len(self.values))
def read(self, start: int, count: int) -> np.ndarray:
return np.asarray(self.values[start:start + count], dtype=np.complex64)
def underrun_scale(byte_count: int = 16_672) -> dict:
if type(byte_count) is not int or byte_count <= 0 or byte_count % 2:
raise ValueError("Размер cs8 underrun должен быть положительным чётным числом байт")
samples = byte_count // 2
duration = samples / SAMPLE_RATE
symbols = samples * SYMBOL_RATE / SAMPLE_RATE
return {
"bytes": byte_count,
"complex_samples": samples,
"duration_seconds": duration,
"duration_milliseconds": duration * 1000,
"symbols": symbols,
"fraction_of_packet": samples / FRAME_SAMPLES,
"percent_of_packet": 100 * samples / FRAME_SAMPLES,
"interpretation": "Scale only; RX does not prove that this many RF samples were lost or repeated",
}
def actual_gap() -> dict:
metadata = json.loads((RAW / "tx_metadata.json").read_text(encoding="utf-8"))
total = int(metadata["tx_samples"])
expected = FRAME_SAMPLES * PACKETS
return {
"tx_samples": total,
"packets": PACKETS,
"packet_waveform_samples": FRAME_SAMPLES,
"packet_product_samples": expected,
"identity_confirmed": total == expected,
"additional_inter_packet_gap_samples": total - expected,
"additional_inter_packet_gap_seconds": (total - expected) / SAMPLE_RATE,
"actual": "0 additional samples (no planned 5 ms gaps)",
"reason": (
"IMPLEMENTATION_OMISSION: prepare() writes the 16 complete packet waveforms "
"back-to-back and has no gap parameter or zero-fill operation"
),
"packet_internal_note": "Each packet waveform still contains its own guards and RRC tails",
}
def normalized_match(transmitted: np.ndarray, search: np.ndarray) -> dict:
"""Найти локальный участок RX с нормировкой по AC-энергии каждого положения."""
transmitted = np.asarray(transmitted, dtype=np.complex128)
search = np.asarray(search, dtype=np.complex128)
if transmitted.ndim != 1 or search.ndim != 1 or len(search) < len(transmitted):
raise ValueError("Нужны одномерные TX и более длинное RX-окно")
centered_tx = transmitted - np.mean(transmitted)
tx_energy = float(np.vdot(centered_tx, centered_tx).real)
if tx_energy <= 0:
raise ValueError("TX-окно не содержит AC-энергии")
correlation = signal.correlate(search, centered_tx, mode="valid", method="fft")
count = len(centered_tx)
kernel = np.ones(count, dtype=np.float64)
sums = signal.fftconvolve(search, kernel, mode="valid")
powers = signal.fftconvolve(abs(search) ** 2, kernel, mode="valid")
rx_energies = np.maximum(powers - abs(sums) ** 2 / count, 0.0)
normalized = abs(correlation) / np.sqrt(np.maximum(tx_energy * rx_energies, 1e-30))
best = int(np.argmax(normalized))
centered_rx = search[best:best + count] - np.mean(search[best:best + count])
gain = complex(np.vdot(centered_tx, centered_rx) / tx_energy)
residual = centered_rx - gain * centered_tx
return {
"offset": best,
"normalized_correlation": float(normalized[best]),
"gain": gain,
"gain_amplitude": float(abs(gain)),
"phase_rad": float(np.angle(gain)),
"residual_power": float(np.mean(abs(residual) ** 2)),
"rx_ac_power": float(np.mean(abs(centered_rx) ** 2)),
}
def track_alignment(tx, rx, rx_start: int, *, frame_samples: int = FRAME_SAMPLES,
window_samples: int = WINDOW_SAMPLES,
step_samples: int = STEP_SAMPLES,
search_margin: int = SEARCH_MARGIN_SAMPLES,
reliable_packet_start: int = RELIABLE_PACKET_START,
reliable_packet_end: int = RELIABLE_PACKET_END) -> list[dict]:
"""Сопоставить короткие перекрывающиеся TX-окна с RX независимо по времени."""
rows = []
for tx_start in range(0, tx.size - window_samples + 1, step_samples):
expected_rx = rx_start + tx_start
low = max(0, expected_rx - search_margin)
high = min(rx.size, expected_rx + search_margin + window_samples)
match = normalized_match(tx.read(tx_start, window_samples), rx.read(low, high - low))
matched_rx = low + match.pop("offset")
packet = min(PACKETS, tx_start // frame_samples + 1)
position_inside_packet = tx_start - (packet - 1) * frame_samples
inside_reliable_region = reliable_packet_start <= position_inside_packet <= reliable_packet_end
correlation_above_threshold = match["normalized_correlation"] >= MIN_LOCAL_CORRELATION
rows.append({
"window_index": len(rows),
"tx_sample": tx_start,
"rx_sample": matched_rx,
"time_seconds": tx_start / SAMPLE_RATE,
"local_delay_samples": matched_rx - expected_rx,
"packet_index": packet,
"position_inside_packet_samples": position_inside_packet,
"inside_reliable_region": inside_reliable_region,
"correlation_above_threshold": correlation_above_threshold,
"reliable_for_delay": inside_reliable_region and correlation_above_threshold,
**match,
})
return rows
def alignment_verdict(rows: list[dict], expected_jump: int) -> dict:
valid = [row for row in rows if row.get("reliable_for_delay") is True]
internal_low_correlation = [
row for row in rows
if row.get("inside_reliable_region") is True
and row.get("correlation_above_threshold") is False
]
jumps = []
for left, right in zip(valid, valid[1:]):
change = right["local_delay_samples"] - left["local_delay_samples"]
if abs(change) >= max(256, expected_jump // 4):
jumps.append({
"left_window": left["window_index"], "right_window": right["window_index"],
"tx_sample": right["tx_sample"], "rx_sample": right["rx_sample"],
"packet_index": right["packet_index"],
"position_inside_packet_samples": right["position_inside_packet_samples"],
"delay_change_samples": change,
"left_correlation": left["normalized_correlation"],
"right_correlation": right["normalized_correlation"],
})
delays = np.asarray([row["local_delay_samples"] for row in valid], dtype=np.float64)
correlations = np.asarray([row["normalized_correlation"] for row in rows], dtype=np.float64)
return {
"valid_windows": len(valid),
"total_windows": len(rows),
"minimum_correlation": float(np.min(correlations)),
"median_correlation": float(np.median(correlations)),
"maximum_correlation": float(np.max(correlations)),
"delay_min_samples": int(np.min(delays)) if len(delays) else None,
"delay_median_samples": float(np.median(delays)) if len(delays) else None,
"delay_max_samples": int(np.max(delays)) if len(delays) else None,
"jump_candidates": jumps,
"local_delay_discontinuity": bool(jumps),
"local_delay_discontinuity_scope": (
f"NO_IN_{len(valid)}_RELIABLE_WINDOWS; "
f"UNDETERMINED_IN_{len(internal_low_correlation)}_INTERNAL_LOW_CORRELATION_WINDOWS"
if not jumps else "DETECTED_IN_RELIABLE_WINDOWS"
),
"underrun_location": "NOT_LOCALIZED_FROM_RX" if not jumps else jumps[0],
"reliable_region_inside_packet_samples": [RELIABLE_PACKET_START, RELIABLE_PACKET_END],
"correlation_threshold": MIN_LOCAL_CORRELATION,
"internal_low_correlation_windows": {
"count": len(internal_low_correlation),
"packet_counts": {
str(packet): sum(row["packet_index"] == packet for row in internal_low_correlation)
for packet in sorted({row["packet_index"] for row in internal_low_correlation})
},
"windows": [
{
"window_index": row["window_index"],
"packet_index": row["packet_index"],
"tx_sample": row["tx_sample"],
"rx_sample_selected_but_not_used_for_delay_verdict": row["rx_sample"],
"position_inside_packet_samples": row["position_inside_packet_samples"],
"normalized_correlation": row["normalized_correlation"],
}
for row in internal_low_correlation
],
"interpretation": (
"Delay is not established in these windows; low correlation is itself a local anomaly, "
"but it does not identify an underrun without a reliable timing discontinuity"
),
},
"excluded_region_reason": (
"Packet edges and repeated PRBS preamble have correlation aliases spaced by 2032 samples; "
"22 additional internal windows are below the 0.15 correlation threshold. All are retained "
"in CSV, and delay is not asserted for any excluded window"
),
}
def moments(values: np.ndarray) -> dict:
values = np.asarray(values)
mean = complex(np.mean(values, dtype=np.complex128))
power = float(np.mean(abs(values.astype(np.complex128)) ** 2))
ac_power = max(0.0, power - abs(mean) ** 2)
return {
"raw_power_code2": power,
"rms_full_iq_code": math.sqrt(power),
"mean_i": float(mean.real), "mean_q": float(mean.imag),
"ac_power_code2": ac_power, "ac_rms_code": math.sqrt(ac_power),
"max_abs_i": float(np.max(abs(values.real))),
"max_abs_q": float(np.max(abs(values.imag))),
"max_complex_magnitude": float(np.max(abs(values))),
}
def packet_quality(tx, rx, rx_start: int, background_ac_power: float,
lab062_analysis: dict, alignment: list[dict]) -> list[dict]:
rows = []
physical = lab062_analysis["lab058_quality"]["packets"]
for index in range(1, PACKETS + 1):
values = rx.read(rx_start + (index - 1) * FRAME_SAMPLES, FRAME_SAMPLES)
level = moments(values)
metrics = physical[index - 1]["oracle"]["metrics"]
channel = physical[index - 1]["channel"]
local = [row for row in alignment if row["packet_index"] == index and row["reliable_for_delay"]]
phases = np.unwrap([row["phase_rad"] for row in local]) if local else np.empty(0)
row = {
"packet_index": index,
**level,
"background_ac_power_code2": background_ac_power,
"background_subtracted_useful_power_code2": max(0.0, level["ac_power_code2"] - background_ac_power),
"symbol_error_rate": metrics["ber"],
"symbol_rms_deviation": metrics["evm_rms"],
"matched_component_power": metrics["matched_component_power"],
"residual_power": metrics["residual_power"],
"matched_residual_db": metrics["matched_residual_db"],
"band_gain_nonuniformity_db": channel["amplitude_ripple_p95_p05_db"],
"initial_frequency_hz": physical[index - 1]["oracle"]["cfo_hz"],
"diagnostic_residual_phase_error_rad": channel["residual_phase_ripple_p95_p05_rad"],
"local_delay_median_samples": float(np.median([item["local_delay_samples"] for item in local])),
"local_delay_min_samples": int(min(item["local_delay_samples"] for item in local)),
"local_delay_max_samples": int(max(item["local_delay_samples"] for item in local)),
"local_correlation_median": float(np.median([item["normalized_correlation"] for item in local])),
"local_correlation_min": float(min(item["normalized_correlation"] for item in local)),
"local_gain_amplitude_median": float(np.median([item["gain_amplitude"] for item in local])),
"local_phase_unwrapped_span_rad": float(np.ptp(phases)) if len(phases) else None,
"ser_minus_lab056_b": metrics["ber"] - LAB056_B["symbol_error_rate"],
"evm_minus_lab056_b": metrics["evm_rms"] - LAB056_B["evm_rms"],
"matched_residual_minus_lab056_b_db": metrics["matched_residual_db"] - LAB056_B["matched_residual_db"],
"ripple_minus_lab056_b_db": channel["amplitude_ripple_p95_p05_db"] - LAB056_B["band_ripple_db"],
}
rows.append(row)
return rows
def group_trends(rows: list[dict]) -> list[dict]:
result = []
for low in (1, 5, 9, 13):
selected = rows[low - 1:low + 3]
result.append({
"packets": f"{low}-{low + 3}",
"useful_power_mean": float(np.mean([row["background_subtracted_useful_power_code2"] for row in selected])),
"symbol_error_rate_mean": float(np.mean([row["symbol_error_rate"] for row in selected])),
"symbol_rms_deviation_mean": float(np.mean([row["symbol_rms_deviation"] for row in selected])),
"matched_component_power_mean": float(np.mean([row["matched_component_power"] for row in selected])),
"residual_power_mean": float(np.mean([row["residual_power"] for row in selected])),
"matched_residual_db_mean": float(np.mean([row["matched_residual_db"] for row in selected])),
"initial_frequency_hz_mean": float(np.mean([row["initial_frequency_hz"] for row in selected])),
"diagnostic_residual_phase_error_rad_mean": float(np.mean(
[row["diagnostic_residual_phase_error_rad"] for row in selected]
)),
"local_phase_unwrapped_span_rad_mean": float(np.mean(
[row["local_phase_unwrapped_span_rad"] for row in selected]
)),
"local_gain_amplitude_median": float(np.median([row["local_gain_amplitude_median"] for row in selected])),
})
return result
def classify(packet_rows: list[dict], alignment: dict) -> dict:
worse = [
row for row in packet_rows
if row["symbol_error_rate"] > LAB056_B["symbol_error_rate"]
and row["symbol_rms_deviation"] > LAB056_B["evm_rms"]
and row["matched_residual_db"] < LAB056_B["matched_residual_db"]
]
global_degradation = len(worse) >= 12
discontinuity = alignment["local_delay_discontinuity"]
if discontinuity and global_degradation:
distribution, primary = "MIXED", "PARTIALLY_LOCALIZED"
elif discontinuity:
distribution, primary = "LOCALIZED", "PARTIALLY_LOCALIZED"
elif global_degradation:
distribution, primary = "GLOBAL", "PARTIALLY_LOCALIZED"
else:
distribution, primary = "NOT_LOCALIZED", "NOT_LOCALIZED"
return {
"quality_distribution": distribution,
"primary_cause_status": primary,
"packets_worse_than_lab056_on_ser_evm_and_matched_residual": [row["packet_index"] for row in worse],
"global_degradation_rule": "at least 12/16 packets worse than Lab056 B on SER, EVM and matched/residual",
"global_degradation": global_degradation,
"local_delay_discontinuity": discontinuity,
}
def write_csv(path: Path, rows: list[dict]) -> None:
with path.open("w", newline="", encoding="utf-8-sig") as stream:
writer = csv.DictWriter(stream, fieldnames=list(rows[0]))
writer.writeheader()
for row in rows:
writer.writerow({key: (json.dumps(value) if isinstance(value, (dict, list)) else value)
for key, value in row.items()})
def plots(alignment: list[dict], packets: list[dict]) -> None:
OUTPUT.mkdir(parents=True, exist_ok=True)
time_ms = np.asarray([row["time_seconds"] * 1000 for row in alignment])
packet_indexes = np.arange(1, PACKETS + 1)
def line(name: str, values, ylabel: str, title: str) -> None:
figure, axis = plt.subplots(figsize=(9, 4.5))
axis.plot(time_ms, values, linewidth=1.2)
axis.set(xlabel="Время TX, мс", ylabel=ylabel, title=title)
axis.grid(True, alpha=0.3); figure.tight_layout()
figure.savefig(OUTPUT / name, dpi=160); plt.close(figure)
figure, axis = plt.subplots(figsize=(9, 4.5))
unreliable = [row for row in alignment if not row["reliable_for_delay"]]
reliable = [row for row in alignment if row["reliable_for_delay"]]
axis.scatter([row["time_seconds"] * 1000 for row in unreliable],
[row["local_delay_samples"] for row in unreliable], s=7, alpha=0.25,
label="исключено: края, преамбула или низкая корреляция")
axis.plot([row["time_seconds"] * 1000 for row in reliable],
[row["local_delay_samples"] for row in reliable], linewidth=1.2,
label="надёжная внутренняя часть")
axis.set(xlabel="Время TX, мс", ylabel="Локальная задержка, отсчёты",
title="Локальная временная привязка TX и RX")
axis.grid(True, alpha=0.3); axis.legend(); figure.tight_layout()
figure.savefig(OUTPUT / "local_delay_vs_time.png", dpi=160); plt.close(figure)
line("normalized_correlation_vs_time.png", [row["normalized_correlation"] for row in alignment],
"Нормированная корреляция", "Устойчивость локального сопоставления")
reliable_time_ms = np.asarray([row["time_seconds"] * 1000 for row in reliable])
figure, axis = plt.subplots(figsize=(9, 4.5))
axis.plot(reliable_time_ms, [row["gain_amplitude"] for row in reliable], linewidth=1.2)
axis.set(xlabel="Время TX, мс", ylabel="|h|, коды RX / код TX",
title="Локальная амплитуда канала в надёжных окнах")
axis.grid(True, alpha=0.3); figure.tight_layout()
figure.savefig(OUTPUT / "gain_vs_time.png", dpi=160); plt.close(figure)
figure, axis = plt.subplots(figsize=(9, 4.5))
phase = np.unwrap([row["phase_rad"] for row in reliable])
axis.plot(reliable_time_ms, phase, linewidth=1.2)
axis.set(xlabel="Время TX, мс", ylabel="Развёрнутая фаза, рад",
title="Локальная фаза канала в надёжных окнах")
axis.grid(True, alpha=0.3); figure.tight_layout()
figure.savefig(OUTPUT / "phase_vs_time.png", dpi=160); plt.close(figure)
def bars(name: str, values, ylabel: str, title: str, baseline=None) -> None:
figure, axis = plt.subplots(figsize=(9, 4.5))
axis.bar(packet_indexes, values)
if baseline is not None:
axis.axhline(baseline, color="tab:red", linestyle="--", label="Lab056 B")
axis.legend()
axis.set(xlabel="Номер пакета", ylabel=ylabel, title=title, xticks=packet_indexes)
axis.grid(True, axis="y", alpha=0.3); figure.tight_layout()
figure.savefig(OUTPUT / name, dpi=160); plt.close(figure)
bars("received_power_by_packet.png", [row["background_subtracted_useful_power_code2"] for row in packets],
"Полезная AC-мощность, код²", "Принятая мощность по пакетам")
bars("symbol_error_rate_by_packet.png", [100 * row["symbol_error_rate"] for row in packets],
"Ошибочные символы, %", "Диагностическая SER по пакетам", 100 * LAB056_B["symbol_error_rate"])
bars("matched_residual_by_packet.png", [row["matched_residual_db"] for row in packets],
"Matched/residual, дБ", "Полезная согласованная составляющая к остатку", LAB056_B["matched_residual_db"])
figure, axes = plt.subplots(2, 2, figsize=(11, 7))
comparisons = [
("SER, %", [100 * row["symbol_error_rate"] for row in packets], 100 * LAB056_B["symbol_error_rate"]),
("EVM RMS", [row["symbol_rms_deviation"] for row in packets], LAB056_B["evm_rms"]),
("Matched/residual, дБ", [row["matched_residual_db"] for row in packets], LAB056_B["matched_residual_db"]),
("Неравномерность, дБ", [row["band_gain_nonuniformity_db"] for row in packets], LAB056_B["band_ripple_db"]),
]
for axis, (label, values, baseline) in zip(axes.flat, comparisons):
axis.bar(packet_indexes, values); axis.axhline(baseline, color="tab:red", linestyle="--")
axis.set(xlabel="Пакет", ylabel=label, xticks=packet_indexes); axis.grid(True, axis="y", alpha=0.3)
figure.suptitle("Lab056 B и пакеты Lab062"); figure.tight_layout()
figure.savefig(OUTPUT / "lab056_b_vs_lab062_packets.png", dpi=160); plt.close(figure)
def local_counter_semantics() -> dict:
binary = Path(r"C:\Users\user\Tools\HackRF\Library\bin\hackrf_transfer.exe")
source_candidates = list(binary.parent.parent.rglob("hackrf_transfer.c")) if binary.parent.parent.exists() else []
return {
"binary_path": str(binary), "binary_exists": binary.exists(),
"local_source_files": [str(path) for path in source_candidates],
"progress_line": "1 underruns, longest 16672 bytes",
"final_line": "0 underruns, longest 0 bytes",
"counter_semantics": "NOT_ESTABLISHED" if not source_candidates else "LOCAL_SOURCE_REQUIRES_REVIEW",
"note": "No local source or documentation was found that explains the reset between progress and final counters",
}
def run() -> dict:
OUTPUT.mkdir(parents=True, exist_ok=True)
lab062_analysis = json.loads((LAB062 / "rf_analysis.json").read_text(encoding="utf-8"))
if lab062_analysis["status"] != "RF_SESSION_INVALID_TX_UNDERRUN":
raise RuntimeError("Lab062 must remain INVALID_TX_UNDERRUN")
tx, rx = lab058.Cs8File(TX_PATH), lab058.Cs8File(RX_PATH)
rx_start = int(lab062_analysis["location"]["rx_start_sample"])
gap = actual_gap()
if not gap["identity_confirmed"] or gap["additional_inter_packet_gap_samples"] != 0:
raise RuntimeError("Unexpected Lab062 TX accounting")
scale = underrun_scale()
alignment_rows = track_alignment(tx, rx, rx_start)
alignment = alignment_verdict(alignment_rows, scale["complex_samples"])
before = moments(rx.read(rx_start - FRAME_SAMPLES, FRAME_SAMPLES))
after = moments(rx.read(rx_start + tx.size, FRAME_SAMPLES))
background_ac_power = 0.5 * (before["ac_power_code2"] + after["ac_power_code2"])
packet_rows = packet_quality(tx, rx, rx_start, background_ac_power, lab062_analysis, alignment_rows)
trends = group_trends(packet_rows)
classification = classify(packet_rows, alignment)
most_affected = sorted(
packet_rows,
key=lambda row: (row["symbol_error_rate"], row["symbol_rms_deviation"], -row["matched_residual_db"]),
reverse=True,
)[:4]
selected = {3, 4, 12, 14}
special = [row for row in packet_rows if row["packet_index"] in selected]
special_common = {
"packets": sorted(selected),
"all_have_power_drop_below_median": all(
row["background_subtracted_useful_power_code2"] < np.median(
[item["background_subtracted_useful_power_code2"] for item in packet_rows]
) for row in special
),
"all_have_correlation_below_median": all(
row["local_correlation_median"] < np.median([item["local_correlation_median"] for item in packet_rows])
for row in special
),
"all_have_large_delay_change": all(
row["local_delay_max_samples"] - row["local_delay_min_samples"] >= scale["complex_samples"] // 4
for row in special
),
"interpretation": "No common underrun signature unless one of all three booleans is true with localized alignment evidence",
}
result = {
"lab": "Lab063", "status": "COMPLETED_OFFLINE", "rf_tx": 0,
"hardware_queries": 0, "lab062_status_preserved": lab062_analysis["status"],
"lab062_commit": "f8ae6c6bfceaa21b6c08dcf55d2bff996dd0dae5",
"physical_device": "Auron HackRF Plus",
"api_firmware_identification": "HackRF One r9",
"integrity": {
"tx_sha256": lab062.sha256(TX_PATH), "rx_sha256": lab062.sha256(RX_PATH),
"tx_samples": tx.size, "rx_samples": rx.size,
},
"actual_inter_packet_gap": gap,
"tx_underrun_scale": scale,
"tx_underrun_log": local_counter_semantics(),
"background": {"before": before, "after": after, "ac_power_code2_used": background_ac_power,
"preflight_ac_rms_code": 0.9854828456229909},
"local_alignment": alignment,
"packet_quality": packet_rows,
"group_trends": trends,
"special_packets_3_4_12_14": special_common,
"packets_most_affected": [row["packet_index"] for row in most_affected],
"active_rx_level": {
"ac_rms_min": min(row["ac_rms_code"] for row in packet_rows),
"ac_rms_max": max(row["ac_rms_code"] for row in packet_rows),
"max_abs_i_min": min(row["max_abs_i"] for row in packet_rows),
"max_abs_i_max": max(row["max_abs_i"] for row in packet_rows),
"max_abs_q_min": min(row["max_abs_q"] for row in packet_rows),
"max_abs_q_max": max(row["max_abs_q"] for row in packet_rows),
"mean_i_min": min(row["mean_i"] for row in packet_rows),
"mean_i_max": max(row["mean_i"] for row in packet_rows),
"mean_q_min": min(row["mean_q"] for row in packet_rows),
"mean_q_max": max(row["mean_q"] for row in packet_rows),
"local_gain_amplitude_median_min": min(row["local_gain_amplitude_median"] for row in packet_rows),
"local_gain_amplitude_median_max": max(row["local_gain_amplitude_median"] for row in packet_rows),
"analog_overload": "LESS_LIKELY_FROM_DIGITAL_LEVEL_BUT_NOT_EXCLUDED_WITHOUT_INSTRUMENT",
},
"lab056_comparison": {"reference": LAB056_B,
"packets_worse_on_all_three_core_metrics": classification["packets_worse_than_lab056_on_ser_evm_and_matched_residual"]},
**classification,
"next_single_step": (
"Before another TX, investigate the low active RX level, gain/geometry and possible analogue compression; "
"also change TX streaming/logging so any underrun is unambiguous. Do not change RF parameters yet."
if classification["quality_distribution"] == "GLOBAL" else
"Improve TX streaming and underrun logging before any separately authorized repeat."
),
"lab063_commit": "NOT_PERFORMED", "push": "NOT_PERFORMED", "lab064": "NOT_CREATED",
}
write_csv(OUTPUT / "local_alignment.csv", alignment_rows)
write_csv(OUTPUT / "packet_quality.csv", packet_rows)
plots(alignment_rows, packet_rows)
(OUTPUT / "summary.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
return result
def run_functional_tests() -> None:
scale = underrun_scale()
assert scale["complex_samples"] == 8336
assert abs(scale["duration_milliseconds"] - 1.042) < 1e-12
assert scale["symbols"] == 521.0
transmitted = np.exp(1j * np.arange(128) * 0.31)
search = np.concatenate((np.zeros(37, complex), (0.4 + 0.2j) * transmitted, np.zeros(19, complex)))
result = normalized_match(transmitted, search)
assert result["offset"] == 37 and result["normalized_correlation"] > 0.999999
def main() -> None:
result = run()
print(json.dumps({
"status": result["status"],
"actual_inter_packet_gap": result["actual_inter_packet_gap"],
"tx_underrun_scale": result["tx_underrun_scale"],
"local_alignment": result["local_alignment"],
"packets_most_affected": result["packets_most_affected"],
"active_rx_level": result["active_rx_level"],
"quality_distribution": result["quality_distribution"],
"primary_cause_status": result["primary_cause_status"],
"next_single_step": result["next_single_step"],
"rf_tx": result["rf_tx"],
}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,957 @@
"""Lab064: лестница цифровых уровней и измерение линейности RF-тракта.
Подготовка и анализ не используют пакетный приёмник. Аппаратный preflight
работает только в режиме RX. Передача доступна отдельной командой с явным
флагом и защищена одноразовым маркером.
"""
from __future__ import annotations
from dataclasses import asdict
import argparse
import hashlib
import json
from pathlib import Path
import re
import subprocess
import sys
import time
if __package__ in (None, ""):
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import numpy as np
from scipy import signal
from experiments import lab043_pluto_to_rtlsdr as shaping
from experiments import lab054_hardware_control as lab054
from experiments import lab055_energy_audit as energy
from experiments import lab056_abab_energy as lab056
from experiments import lab056_capture_runner as hardware
ROOT = Path(__file__).resolve().parents[1]
RAW = ROOT / "data/raw/lab064"
OUTPUT = ROOT / "data/processed/lab064"
SAMPLE_RATE = 8_000_000
SYMBOL_RATE = 20_000
SAMPLES_PER_SYMBOL = SAMPLE_RATE // SYMBOL_RATE
CARRIER_HZ = 50_000
NOMINAL_RMS_CODE = 44.0
LEVELS = (("L0", -18.0), ("L1", -12.0), ("L2", -6.0), ("L3", 0.0))
SEGMENT_SAMPLES = 800_000
GAP_SAMPLES = 400_000
LEADING_ZERO_SAMPLES = 800_000
TRAILING_ZERO_SAMPLES = 800_000
PRBS_SYMBOLS = SEGMENT_SAMPLES // SAMPLES_PER_SYMBOL - 42
TRIM_SAMPLES = 21 * SAMPLES_PER_SYMBOL
TX_SAMPLES = (
LEADING_ZERO_SAMPLES
+ len(LEVELS) * SEGMENT_SAMPLES
+ (len(LEVELS) - 1) * GAP_SAMPLES
+ TRAILING_ZERO_SAMPLES
)
RX_SECONDS = 2.0
RX_SAMPLES = int(RX_SECONDS * SAMPLE_RATE)
RX_LEAD_SECONDS = 0.5
PREFLIGHT_SAMPLES = 800_000
STRONG_AC_RMS_CODE = 20.0
STRONG_COMPONENT_CODE = 100.0
BACKGROUND_WINDOW_SAMPLES = 160_000
POINT = hardware.OperatingPoint(
frequency_hz=1_400_000_000,
physical_path="MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
path_confirmed=True,
tx_antenna="existing 1400 MHz antenna near window",
rx_antenna="existing 1400 MHz antenna on desk",
distance_m=1.2,
orientation="same polarization; fixed during preflight and RF session",
visibility="LOS indoor",
)
def save_new(path: Path, value: dict) -> None:
"""Записать новый JSON и не перезаписывать свидетельства опыта."""
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("x", encoding="utf-8") as stream:
json.dump(value, stream, ensure_ascii=False, indent=2, allow_nan=False)
stream.write("\n")
def save_text_new(path: Path, value: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("x", encoding="utf-8") as stream:
stream.write(value)
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
while block := stream.read(1024 * 1024):
digest.update(block)
return digest.hexdigest()
def parameters() -> dict:
return {
"rf_frequency_hz": POINT.frequency_hz,
"sample_rate_hz": SAMPLE_RATE,
"symbol_rate": SYMBOL_RATE,
"samples_per_symbol": SAMPLES_PER_SYMBOL,
"digital_carrier_hz": CARRIER_HZ,
"rrc_rolloff": shaping.LAB042_RRC_ROLLOFF,
"rrc_span_symbols": shaping.LAB042_RRC_SPAN_SYMBOLS,
"prbs": "PRBS7 x^7+x^6+1, deterministic initial state",
"full_phy_packet": False,
"tx_vga_db": 10,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": False,
"bias_tee": False,
"geometry": asdict(POINT),
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN",
"levels_db_relative_nominal": [level for _, level in LEVELS],
}
def transfer_command(path: Path | str, samples: int, *, transmit: bool = False) -> list[str]:
return hardware.command(POINT, path, samples, transmit=transmit)
def _complex_to_cs8(values: np.ndarray) -> np.ndarray:
interleaved = np.empty(2 * len(values), dtype=np.int8)
interleaved[::2] = np.clip(np.rint(values.real), -128, 127).astype(np.int8)
interleaved[1::2] = np.clip(np.rint(values.imag), -128, 127).astype(np.int8)
return interleaved
def nominal_segment() -> np.ndarray:
"""Один участок длиной 100 мс с прежними PRBS7, BPSK и RRC."""
symbols = 2.0 * shaping.pilot_prbs7(PRBS_SYMBOLS) - 1.0
waveform = shaping.shape_frame_like_lab042(symbols, SAMPLES_PER_SYMBOL)
if len(waveform) != SEGMENT_SAMPLES:
raise RuntimeError("RRC-участок не равен заранее заданным 100 мс")
carrier = np.exp(2j * np.pi * CARRIER_HZ * np.arange(len(waveform)) / SAMPLE_RATE)
waveform = waveform * carrier
waveform *= NOMINAL_RMS_CODE / np.sqrt(np.mean(np.abs(waveform) ** 2))
return waveform
def level_segment(level_db: float) -> np.ndarray:
scale = 10 ** (level_db / 20)
return _complex_to_cs8(nominal_segment() * scale)
def segment_metrics(interleaved: np.ndarray, level_db: float) -> dict:
values = interleaved[::2].astype(np.float32) + 1j * interleaved[1::2].astype(np.float32)
moments = energy.Moments()
moments.add(values)
result = moments.result(SYMBOL_RATE)
result.update({
"requested_relative_power_db": level_db,
"tx_rms_code": result["rms_code"],
"tx_peak_abs_i_code": result["max_abs_i"],
"tx_peak_abs_q_code": result["max_abs_q"],
"tx_peak_magnitude_code": result["peak_magnitude_code"],
"digital_clipping": bool(result["clipped_samples_fraction"] > 0),
})
return result
def prepared_segments() -> tuple[list[dict], dict[str, np.ndarray]]:
cursor = LEADING_ZERO_SAMPLES
rows: list[dict] = []
blocks: dict[str, np.ndarray] = {}
for index, (label, level_db) in enumerate(LEVELS):
block = level_segment(level_db)
metrics = segment_metrics(block, level_db)
rows.append({
"label": label,
"level_db": level_db,
"start_sample": cursor,
"samples": SEGMENT_SAMPLES,
"duration_seconds": SEGMENT_SAMPLES / SAMPLE_RATE,
"analysis_start_sample": cursor + TRIM_SAMPLES,
"analysis_samples": SEGMENT_SAMPLES - 2 * TRIM_SAMPLES,
"metrics": metrics,
})
blocks[label] = block
cursor += SEGMENT_SAMPLES
if index < len(LEVELS) - 1:
cursor += GAP_SAMPLES
if cursor + TRAILING_ZERO_SAMPLES != TX_SAMPLES:
raise RuntimeError("Ошибка схемы TX waveform")
nominal_power = rows[-1]["metrics"]["power_code2"]
for row in rows:
row["metrics"]["actual_relative_power_db"] = float(
10 * np.log10(row["metrics"]["power_code2"] / nominal_power)
)
for lower, upper in zip(rows, rows[1:]):
upper["tx_input_difference_from_previous_db"] = float(
10 * np.log10(
upper["metrics"]["power_code2"] / lower["metrics"]["power_code2"]
)
)
return rows, blocks
def prepare() -> dict:
"""Создать единственный конечный TX-файл и его проверяемые метаданные."""
RAW.mkdir(parents=True, exist_ok=True)
OUTPUT.mkdir(parents=True, exist_ok=True)
tx_path = RAW / "tx_level_staircase.cs8"
rows, blocks = prepared_segments()
with tx_path.open("xb") as stream:
stream.write(bytes(2 * LEADING_ZERO_SAMPLES))
for index, (label, _) in enumerate(LEVELS):
stream.write(blocks[label].tobytes())
if index < len(LEVELS) - 1:
stream.write(bytes(2 * GAP_SAMPLES))
stream.write(bytes(2 * TRAILING_ZERO_SAMPLES))
if tx_path.stat().st_size != 2 * TX_SAMPLES:
raise RuntimeError("Неверная длина подготовленного TX")
if any(row["metrics"]["digital_clipping"] for row in rows):
raise RuntimeError("В подготовленном TX обнаружен цифровой clipping")
steps = [row["tx_input_difference_from_previous_db"] for row in rows[1:]]
if any(abs(step - 6.0) > 0.1 for step in steps):
raise RuntimeError("Цифровая лестница не выдерживает шаг +6 дБ")
result = {
"lab": "Lab064",
"stage": "PREPARATION_ONLY",
"rf_tx_count": 0,
"head": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(),
"parameters": parameters(),
"segments": rows,
"leading_zero_samples": LEADING_ZERO_SAMPLES,
"gap_samples": GAP_SAMPLES,
"trailing_zero_samples": TRAILING_ZERO_SAMPLES,
"tx_samples": TX_SAMPLES,
"tx_bytes": 2 * TX_SAMPLES,
"tx_duration_seconds": TX_SAMPLES / SAMPLE_RATE,
"tx_sha256": sha256(tx_path),
"rx_samples": RX_SAMPLES,
"rx_duration_seconds": RX_SECONDS,
"rx_lead_seconds": RX_LEAD_SECONDS,
"automatic_retry": False,
"tx_command_prepared_not_run": transfer_command(tx_path, TX_SAMPLES, transmit=True),
"rx_command_prepared_not_run": transfer_command(RAW / "rx_stream.cs8", RX_SAMPLES),
}
save_new(RAW / "tx_metadata.json", result)
save_new(OUTPUT / "preparation.json", result)
return result
def validate_prepared() -> dict:
metadata = json.loads((RAW / "tx_metadata.json").read_text(encoding="utf-8"))
path = RAW / "tx_level_staircase.cs8"
rows, blocks = prepared_segments()
digest = hashlib.sha256()
digest.update(bytes(2 * LEADING_ZERO_SAMPLES))
for index, (label, _) in enumerate(LEVELS):
digest.update(blocks[label].tobytes())
if index < len(LEVELS) - 1:
digest.update(bytes(2 * GAP_SAMPLES))
digest.update(bytes(2 * TRAILING_ZERO_SAMPLES))
if (
metadata.get("lab") != "Lab064"
or metadata.get("stage") != "PREPARATION_ONLY"
or metadata.get("rf_tx_count") != 0
or metadata.get("parameters") != parameters()
or metadata.get("segments") != rows
or metadata.get("tx_samples") != TX_SAMPLES
or path.stat().st_size != 2 * TX_SAMPLES
or metadata.get("tx_sha256") != digest.hexdigest()
or sha256(path) != digest.hexdigest()
):
raise RuntimeError("Подготовленный Lab064 TX или параметры изменились")
return metadata
def difference_db(new: float, old: float) -> float:
if new <= 0 or old <= 0:
raise ValueError("Для разности в дБ нужны положительные мощности")
return float(10 * np.log10(new / old))
def counter_observations(log: str) -> list[dict]:
"""Сохранить все промежуточные и итоговые счётчики потерь из лога."""
pattern = re.compile(
r"(?<![\w.+-])(\d+)\s+(?:(rx|tx)\s+)?(overruns?|underruns?)\b",
re.IGNORECASE,
)
return [
{
"count": int(match.group(1)),
"role": (match.group(2) or "UNKNOWN").upper(),
"kind": match.group(3).lower().rstrip("s"),
"text": match.group(0),
"character_offset": match.start(),
}
for match in pattern.finditer(log)
]
def counter_summary(log: str, expected_kind: str) -> dict:
observations = counter_observations(log)
selected = [row for row in observations if row["kind"] == expected_kind]
unparsed = re.search(
r"overrun|underrun",
re.sub(
r"(?<![\w.+-])\d+\s+(?:(?:rx|tx)\s+)?(?:overruns?|underruns?)\b",
"",
log,
flags=re.IGNORECASE,
),
re.IGNORECASE,
)
return {
"expected_kind": expected_kind,
"observations": observations,
"selected_counts": [row["count"] for row in selected],
"final_count": selected[-1]["count"] if selected else None,
"maximum_count": max((row["count"] for row in selected), default=None),
"unparsed_loss_text": bool(unparsed),
"clean": bool(selected) and not unparsed and all(row["count"] == 0 for row in observations),
}
def synthetic_linearity_gate() -> dict:
"""Проверить метрики на известном линейном канале без аппаратуры."""
rows, blocks = prepared_segments()
random_generator = np.random.default_rng(64064)
measured = []
for row in rows:
block = blocks[row["label"]]
reference = block[::2].astype(np.float64) + 1j * block[1::2].astype(np.float64)
reference = reference[TRIM_SAMPLES:-TRIM_SAMPLES]
noise = random_generator.normal(0, 0.03, len(reference)) + 1j * random_generator.normal(
0, 0.03, len(reference)
)
received = 0.37 * np.exp(0.41j) * reference + (0.8 - 0.3j) + noise
fitted = energy.fit_channel(reference, received, SAMPLE_RATE)
measured.append({
"label": row["label"],
"matched_signal_power": fitted["heldout_signal_power"],
"residual_power": fitted["heldout_residual_power"],
"gain_abs": fitted["gain_abs"],
})
step_errors = []
for index in range(1, len(rows)):
tx_step = rows[index]["tx_input_difference_from_previous_db"]
rx_step = difference_db(
measured[index]["matched_signal_power"],
measured[index - 1]["matched_signal_power"],
)
step_errors.append(rx_step - tx_step)
passed = max(abs(error) for error in step_errors) < 0.02
return {
"lab": "Lab064",
"stage": "SOFTWARE_LINEARITY_GATE",
"rf_tx_count": 0,
"channel_model": "known linear complex gain plus DC and deterministic Gaussian noise",
"rows": measured,
"linearity_errors_db": step_errors,
"passed": passed,
}
def software_gate() -> dict:
metadata = validate_prepared()
result = synthetic_linearity_gate()
result["tx_sha256"] = metadata["tx_sha256"]
save_new(OUTPUT / "software_gate.json", result)
if not result["passed"]:
raise RuntimeError("Lab064 software gate FAIL")
return result
def locate_waveform(tx: energy.Cs8File, rx: energy.Cs8File) -> dict:
"""Найти всю лестницу по прореженной диагностической корреляции."""
stride = 32
def decimated(source: energy.Cs8File) -> np.ndarray:
chunks = [
source.read(start, min(262_144, source.size - start))[::stride]
for start in range(0, source.size, 262_144)
]
return np.concatenate(chunks).astype(np.complex128)
reference = decimated(tx)
received = decimated(rx)
if len(received) < len(reference):
raise ValueError("RX короче TX waveform")
reference -= reference.mean()
received -= received.mean()
reference_energy = float(np.sum(np.abs(reference) ** 2))
cumulative = np.concatenate(([0.0], np.cumsum(np.abs(received) ** 2)))
window_energy = cumulative[len(reference):] - cumulative[:-len(reference)]
time_axis = np.arange(len(reference)) * stride / SAMPLE_RATE
best = (-1.0, 0, 0.0)
for frequency_hz in np.arange(-3.0, 3.01, 0.25):
rotated = reference * np.exp(2j * np.pi * frequency_hz * time_axis)
correlation = signal.fftconvolve(received, np.conj(rotated[::-1]), mode="valid")
scores = np.abs(correlation) / np.sqrt(
np.maximum(reference_energy * window_energy, 1e-30)
)
index = int(np.argmax(scores))
if scores[index] > best[0]:
best = (float(scores[index]), index * stride, float(frequency_hz))
if best[0] < 0.05:
raise RuntimeError("Лестница уровней не локализована; измерение UNKNOWN")
return {"start_sample": best[1], "correlation": best[0], "coarse_cfo_hz": best[2], "stride": stride}
def _window_metrics(values: np.ndarray) -> dict:
moments = energy.Moments()
moments.add(values)
result = moments.result(SYMBOL_RATE)
result["ac_rms_code"] = float(np.sqrt(max(0.0, result["ac_power_code2"])))
return result
def background_windows() -> list[dict]:
"""Окна внутри всех нулевых участков, вдали от активных границ."""
starts = (
("INITIAL_GUARD", 320_000),
("GAP_L0_L1", 1_760_000),
("GAP_L1_L2", 2_960_000),
("GAP_L2_L3", 4_160_000),
("FINAL_GUARD", 5_440_000),
)
return [
{
"label": label,
"tx_relative_start_sample": start,
"samples": BACKGROUND_WINDOW_SAMPLES,
"duration_seconds": BACKGROUND_WINDOW_SAMPLES / SAMPLE_RATE,
}
for label, start in starts
]
def summarize_background(rows: list[dict]) -> dict:
powers = [row["metrics"]["ac_power_code2"] for row in rows]
rms_values = [row["metrics"]["ac_rms_code"] for row in rows]
variation_db = difference_db(max(powers), min(powers))
return {
"ac_power_min_code2": min(powers),
"ac_power_max_code2": max(powers),
"ac_rms_min_code": min(rms_values),
"ac_rms_max_code": max(rms_values),
"maximum_to_minimum_ac_power_db": variation_db,
"stability_rule_db": 3.0,
"stable": variation_db <= 3.0,
}
def residual_spectral_diagnostics(
reference: np.ndarray,
received: np.ndarray,
cfo_hz: float,
complex_gain: dict,
) -> dict:
"""Оценить паразитные полосы после вычитания согласованной составляющей."""
rotated = reference * np.exp(2j * np.pi * cfo_hz * np.arange(len(reference)) / SAMPLE_RATE)
rotated -= rotated.mean()
centered_received = received - received.mean()
gain = complex(complex_gain["real"], complex_gain["imag"])
residual = centered_received - gain * rotated
frequencies, density = energy.spectrum(residual)
half_width = 0.675 * SYMBOL_RATE
bands = {}
for harmonic in (1, 2, 3):
center = harmonic * CARRIER_HZ
bands[f"residual_band_h{harmonic}_power_code2"] = energy.band_power(
frequencies, density, center - half_width, center + half_width
)
bands["interpretation"] = (
"Diagnostic residual bands at 50/100/150 kHz; not calibrated RF harmonic power"
)
return bands
def classify_linearity(
rows: list[dict], comparisons: list[dict], background_summary: dict
) -> dict:
errors = [row["linearity_error_db"] for row in comparisons]
l3_ratio = rows[-1]["matched_to_residual_db"]
clipping = any(row["full_iq"]["clipped_samples_fraction"] > 0 for row in rows)
if clipping:
case = "INVALID_RX_CLIPPING"
elif comparisons[-1]["linearity_error_db"] <= -1.5:
case = "COMPRESSION"
elif (
max(abs(value) for value in errors) <= 1.0
and l3_ratio < 3.0
and background_summary["stable"]
):
case = "LINEAR_BUT_WEAK"
elif (
max(abs(value) for value in errors) <= 1.0
and l3_ratio >= 6.0
and background_summary["stable"]
):
case = "HEALTHY_LINEAR_RANGE"
else:
case = "NOT_LOCALIZED"
return {
"case": case,
"rules_fixed_before_rf": {
"linear_max_abs_error_db": 1.0,
"compression_upper_step_error_at_most_db": -1.5,
"weak_l3_matched_to_residual_below_db": 3.0,
"healthy_l3_matched_to_residual_at_least_db": 6.0,
},
}
def capture_validity(capture: dict) -> dict:
"""Не дать последнему нулевому счётчику скрыть промежуточную потерю."""
reasons = []
for role, key in (("TX", "tx_counter_summary"), ("RX", "rx_counter_summary")):
summary = capture.get(key, {})
if summary.get("clean") is not True:
reasons.append(f"{role}_COUNTER_NOT_CLEAN")
if summary.get("maximum_count") != 0:
reasons.append(f"{role}_MAXIMUM_COUNTER_NOT_ZERO")
if capture.get("passed") is not True:
reasons.append("CAPTURE_RUNNER_NOT_PASSED")
if capture.get("rx_clipping") is not False:
reasons.append("RX_CLIPPING_NOT_EXCLUDED")
return {"valid": not reasons, "invalid_reasons": reasons}
def analyze_capture() -> dict:
"""Проанализировать сохранённый RX только как известный измерительный сигнал."""
metadata = validate_prepared()
rx_path = RAW / "rx_stream.cs8"
capture = json.loads((RAW / "capture_result.json").read_text(encoding="utf-8"))
if capture.get("rf_tx_count") != 1 or capture.get("rx_sha256") != sha256(rx_path):
raise RuntimeError("Нет подтверждённой единственной RX-записи Lab064")
tx = energy.Cs8File(RAW / "tx_level_staircase.cs8")
rx = energy.Cs8File(rx_path)
location = locate_waveform(tx, rx)
background_rows = []
for window in background_windows():
rx_start = location["start_sample"] + window["tx_relative_start_sample"]
background_rows.append({
**window,
"rx_start_sample": rx_start,
"metrics": _window_metrics(rx.read(rx_start, window["samples"])),
})
background_by_label = {row["label"]: row for row in background_rows}
preceding_background = {
"L0": "INITIAL_GUARD",
"L1": "GAP_L0_L1",
"L2": "GAP_L1_L2",
"L3": "GAP_L2_L3",
}
rows = []
for segment in metadata["segments"]:
tx_start = segment["start_sample"]
nominal_rx_start = location["start_sample"] + tx_start
fitted = energy.analyze_rx(
lab056.OffsetSource(tx, tx_start),
rx,
[nominal_rx_start],
SEGMENT_SAMPLES,
SAMPLES_PER_SYMBOL,
)["frames"][0]
actual_start = fitted["start"]
full_values = rx.read(actual_start, SEGMENT_SAMPLES)
active_reference = tx.read(tx_start + TRIM_SAMPLES, SEGMENT_SAMPLES - 2 * TRIM_SAMPLES)
active_received = rx.read(actual_start + TRIM_SAMPLES, SEGMENT_SAMPLES - 2 * TRIM_SAMPLES)
complex_gain = lab056.complex_gain(active_reference, active_received, fitted["cfo_hz"])
matched = fitted["heldout_signal_power"]
residual = fitted["heldout_residual_power"]
background = background_by_label[preceding_background[segment["label"]]]
rows.append({
"label": segment["label"],
"level_db": segment["level_db"],
"rx_start_sample": actual_start,
"alignment_adjustment_samples": fitted["alignment_adjustment"],
"full_iq": _window_metrics(full_values),
"background_label": background["label"],
"background": background["metrics"],
"background_window_start_sample": background["rx_start_sample"],
"matched_signal_power": matched,
"matched_signal_amplitude_rms": float(np.sqrt(matched)),
"residual_power": residual,
"residual_to_matched_amplitude_ratio": float(np.sqrt(residual / matched)),
"matched_to_residual_db": difference_db(matched, residual),
"complex_gain_h": complex_gain,
"gain_abs": fitted["gain_abs"],
"gain_power_abs_h_squared": fitted["gain_abs"] ** 2,
"cfo_hz": fitted["cfo_hz"],
"residual_spectrum": residual_spectral_diagnostics(
active_reference, active_received, fitted["cfo_hz"], complex_gain
),
})
comparisons = []
for index in range(1, len(rows)):
tx_difference = metadata["segments"][index]["tx_input_difference_from_previous_db"]
rx_difference = difference_db(
rows[index]["matched_signal_power"], rows[index - 1]["matched_signal_power"]
)
comparisons.append({
"comparison": f"{rows[index]['label']}/{rows[index - 1]['label']}",
"tx_input_difference_db": tx_difference,
"rx_matched_power_difference_db": rx_difference,
"linearity_error_db": rx_difference - tx_difference,
"tx_amplitude_ratio": float(10 ** (tx_difference / 20)),
"rx_matched_amplitude_ratio": float(10 ** (rx_difference / 20)),
})
total_tx_difference = difference_db(
metadata["segments"][-1]["metrics"]["power_code2"],
metadata["segments"][0]["metrics"]["power_code2"],
)
total_rx_difference = difference_db(
rows[-1]["matched_signal_power"], rows[0]["matched_signal_power"]
)
total_comparison = {
"comparison": "L3/L0",
"tx_digital_power_difference_db": total_tx_difference,
"rx_matched_power_difference_db": total_rx_difference,
"total_linearity_error_db": total_rx_difference - total_tx_difference,
"tx_amplitude_ratio": float(10 ** (total_tx_difference / 20)),
"rx_matched_amplitude_ratio": float(10 ** (total_rx_difference / 20)),
}
background_summary = summarize_background(background_rows)
validity = capture_validity(capture)
classification = (
classify_linearity(rows, comparisons, background_summary)
if validity["valid"]
else {
"case": "INVALID_CAPTURE",
"invalid_reasons": validity["invalid_reasons"],
"diagnostic_metrics_only": True,
"a_b_c_classification_permitted": False,
}
)
result = {
"lab": "Lab064",
"stage": "OFFLINE_RF_LEVEL_LINEARITY_ANALYSIS",
"packet_receiver_used": False,
"location": location,
"rows": rows,
"background_windows": background_rows,
"background_summary": background_summary,
"comparisons": comparisons,
"total_comparison": total_comparison,
"classification": classification,
"capture_valid": validity["valid"],
"capture_invalid_reasons": validity["invalid_reasons"],
"tx_underruns_maximum": capture.get("tx_counter_summary", {}).get("maximum_count"),
"tx_underruns_final": capture.get("tx_counter_summary", {}).get("final_count"),
"rx_overruns_maximum": capture.get("rx_counter_summary", {}).get("maximum_count"),
"rx_overruns_final": capture.get("rx_counter_summary", {}).get("final_count"),
"rx_clipping": any(row["full_iq"]["clipped_samples_fraction"] > 0 for row in rows),
}
save_new(OUTPUT / "rf_result.json", result)
return result
def preflight(*, runner=None, process_checker=None, clock_checker=None, sleep_function=time.sleep) -> dict:
"""Проверить common clock и 0,1 с RX-фона, не создавая TX-команду."""
metadata = validate_prepared()
software = json.loads((OUTPUT / "software_gate.json").read_text(encoding="utf-8"))
if not software.get("passed") or software.get("tx_sha256") != metadata["tx_sha256"]:
raise RuntimeError("Нет действующего Lab064 software gate")
save_new(RAW / "preflight_attempt.json", {
"lab": "Lab064",
"rf_tx_count": 0,
"point": asdict(POINT),
"parameters": parameters(),
"tx_sha256": metadata["tx_sha256"],
})
actual_runner = runner or lab054.clock._default_command_runner
process_checker = process_checker or lab054.check_processes
clock_checker = clock_checker or hardware.common_clock
def rx_only(command: list[str]):
if "-t" in command:
raise PermissionError("TX запрещён в Lab064 preflight")
return actual_runner(command)
result = {
"lab": "Lab064",
"stage": "COMMON_CLOCK_AND_RX_ONLY_PREFLIGHT",
"passed": False,
"rf_tx_count": 0,
"stop_before_tx": True,
"point": asdict(POINT),
"parameters": parameters(),
"tx_sha256": metadata["tx_sha256"],
}
clock_started = False
try:
before = process_checker()
result["process_before"] = before.to_dict()
lab054.require_clear(before)
result["inventory"] = lab054.phy.lab045._verify_device_inventory(rx_only)
clock_started = True
result["clock"] = clock_checker(
POINT,
rx_only,
lab054.clock.TransmitGuard(),
sleep_function=sleep_function,
)
hardware.require_clock_pass(result["clock"])
path = RAW / "preflight_rx.cs8"
if path.exists():
raise FileExistsError("Lab064 preflight RX уже существует")
captured = rx_only(transfer_command(path, PREFLIGHT_SAMPLES))
stdout = captured.stdout or ""
stderr = captured.stderr or ""
result["rx_process"] = {"returncode": captured.returncode, "stdout": stdout, "stderr": stderr}
result["rx_counter_summary"] = counter_summary(stdout + stderr, "overrun")
if captured.returncode or not result["rx_counter_summary"]["clean"]:
raise RuntimeError("RX preflight: процесс или счётчик overruns не прошёл")
if path.stat().st_size != 2 * PREFLIGHT_SAMPLES:
raise RuntimeError("Неверная длина Lab064 preflight RX")
level = hardware.receive_level(path)
level.pop("symbol_energy_code2_seconds", None)
level["symbol_energy"] = "NOT_APPLICABLE_TO_BACKGROUND"
level["ac_rms_code"] = float(np.sqrt(max(0.0, level["ac_power_code2"])))
level["unexpected_strong_signal"] = bool(
level["ac_rms_code"] >= STRONG_AC_RMS_CODE
or level["max_abs_i"] >= STRONG_COMPONENT_CODE
or level["max_abs_q"] >= STRONG_COMPONENT_CODE
)
level["strong_signal_rule"] = (
f"AC RMS >= {STRONG_AC_RMS_CODE} code or max |I|/|Q| >= {STRONG_COMPONENT_CODE} code"
)
result["rx_level"] = level
result["rx_sha256"] = sha256(path)
result["rx_overruns"] = result["rx_counter_summary"]["final_count"]
if level["saturation_detected"]:
raise RuntimeError("RX clipping; STOP без изменения gain")
if level["unexpected_strong_signal"]:
raise RuntimeError("Неожиданно сильный RX-only фон; STOP без изменения gain")
result["passed"] = True
except Exception as error:
result["error"] = str(error)
raise
finally:
errors = lab054.disable_clock_outputs(rx_only) if clock_started else []
try:
after = process_checker()
result["process_after"] = after.to_dict()
lab054.require_clear(after)
except Exception as error:
errors.append(str(error))
result["cleanup_errors"] = errors
result["passed"] = result["passed"] and not errors
save_new(RAW / "preflight_result.json", result)
OUTPUT.mkdir(parents=True, exist_ok=True)
(OUTPUT / "preflight_result.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2, allow_nan=False) + "\n",
encoding="utf-8",
)
if not result["passed"]:
raise RuntimeError("Lab064 preflight cleanup FAIL")
return result
def require_preflight(metadata: dict) -> dict:
record = json.loads((RAW / "preflight_result.json").read_text(encoding="utf-8"))
if (
record.get("passed") is not True
or record.get("rf_tx_count") != 0
or record.get("point") != asdict(POINT)
or record.get("parameters") != parameters()
or record.get("tx_sha256") != metadata["tx_sha256"]
):
raise PermissionError("Нет успешного RX-only preflight для этой конфигурации Lab064")
hardware.require_clock_pass(record.get("clock", {}))
level = record.get("rx_level", {})
if (
level.get("saturation_detected") is not False
or level.get("unexpected_strong_signal") is not False
or record.get("rx_overruns") != 0
):
raise PermissionError("RX-only preflight не разрешает передачу")
return record
def capture_once(
*,
authorization: bool = False,
runner=None,
process_starter=None,
process_checker=None,
clock_checker=None,
sleep_function=time.sleep,
) -> dict:
"""Один RX-first сеанс; любая попытка расходуется до обращения к SDR."""
if authorization is not True:
raise PermissionError("Нужно отдельное разрешение на единственный RF-сеанс Lab064")
metadata = validate_prepared()
require_preflight(metadata)
receive_path = RAW / "rx_stream.cs8"
if receive_path.exists() or (RAW / "capture_result.json").exists():
raise FileExistsError("Аппаратный результат Lab064 уже существует")
actual_runner = runner or lab054.clock._default_command_runner
process_starter = process_starter or lab054.clock._default_process_starter
process_checker = process_checker or lab054.check_processes
clock_checker = clock_checker or hardware.common_clock
save_new(RAW / "hardware_attempt.json", {
"lab": "Lab064",
"authorized_once": True,
"automatic_retry": False,
"point": asdict(POINT),
"parameters": parameters(),
"tx_sha256": metadata["tx_sha256"],
})
result = {
"lab": "Lab064",
"stage": "SINGLE_RF_LEVEL_CAPTURE",
"passed": False,
"rf_tx_count": 0,
"automatic_tx_repeats": 0,
"point": asdict(POINT),
"parameters": parameters(),
"tx_sha256": metadata["tx_sha256"],
}
guard = lab054.clock.TransmitGuard()
process = None
clock_started = False
try:
before = process_checker()
result["process_before"] = before.to_dict()
lab054.require_clear(before)
result["inventory"] = lab054.phy.lab045._verify_device_inventory(actual_runner)
clock_started = True
result["clock"] = clock_checker(
POINT, actual_runner, guard, sleep_function=sleep_function
)
hardware.require_clock_pass(result["clock"])
process = process_starter(
transfer_command(receive_path, RX_SAMPLES),
RAW / "rx_stdout.txt",
RAW / "rx_stderr.txt",
)
sleep_function(RX_LEAD_SECONDS)
if process.poll() is not None:
raise RuntimeError("RX завершился до TX")
before_tx = hardware.receive_level(receive_path, tail_samples=65_536)
before_tx.pop("symbol_energy_code2_seconds", None)
result["rx_level_before_tx"] = before_tx
if before_tx["saturation_detected"]:
raise RuntimeError("RX clipping до TX; RF TX = 0")
guard.register_transmit()
result["rf_tx_count"] = guard.transmit_calls
transmitted = actual_runner(
transfer_command(RAW / "tx_level_staircase.cs8", TX_SAMPLES, transmit=True)
)
tx_stdout = transmitted.stdout or ""
tx_stderr = transmitted.stderr or ""
save_text_new(RAW / "tx_stdout.txt", tx_stdout)
save_text_new(RAW / "tx_stderr.txt", tx_stderr)
result["tx_process"] = {
"returncode": transmitted.returncode,
"stdout_file": "tx_stdout.txt",
"stderr_file": "tx_stderr.txt",
}
result["tx_counter_summary"] = counter_summary(tx_stdout + tx_stderr, "underrun")
if transmitted.returncode:
raise RuntimeError("Единственный TX завершился ошибкой; повтор запрещён")
if process.wait(RX_SECONDS + 10):
raise RuntimeError("RX завершился ошибкой; передача уже выполнена, повтор запрещён")
process.close_logs()
result["rx_samples"] = receive_path.stat().st_size // 2
result["rx_bytes"] = receive_path.stat().st_size
result["rx_duration_seconds"] = result["rx_samples"] / SAMPLE_RATE
if result["rx_bytes"] != 2 * RX_SAMPLES:
raise RuntimeError("Повреждённая длина RX; повтор запрещён")
rx_stdout = (RAW / "rx_stdout.txt").read_text(encoding="utf-8")
rx_stderr = (RAW / "rx_stderr.txt").read_text(encoding="utf-8")
result["rx_counter_summary"] = counter_summary(rx_stdout + rx_stderr, "overrun")
result["rx_sha256"] = sha256(receive_path)
level = hardware.receive_level(receive_path)
level.pop("symbol_energy_code2_seconds", None)
result["rx_level"] = level
result["rx_clipping"] = bool(level["saturation_detected"])
if not result["tx_counter_summary"]["clean"]:
raise RuntimeError("TX underrun или неоднозначный счётчик; результат сохранён, повтор запрещён")
if not result["rx_counter_summary"]["clean"]:
raise RuntimeError("RX overrun или неоднозначный счётчик; результат сохранён, повтор запрещён")
if result["rx_clipping"]:
raise RuntimeError("RX clipping в записи; результат сохранён, повтор запрещён")
result["passed"] = True
except Exception as error:
result["error"] = str(error)
raise
finally:
errors = []
if process is not None:
try:
process.terminate()
except Exception as error:
errors.append(str(error))
if clock_started:
errors.extend(lab054.disable_clock_outputs(actual_runner))
try:
after = process_checker()
result["process_after"] = after.to_dict()
lab054.require_clear(after)
except Exception as error:
errors.append(str(error))
result["cleanup_errors"] = errors
result["passed"] = result["passed"] and not errors
save_new(RAW / "capture_result.json", result)
OUTPUT.mkdir(parents=True, exist_ok=True)
(OUTPUT / "capture_result.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2, allow_nan=False) + "\n",
encoding="utf-8",
)
if not result["passed"]:
raise RuntimeError("Lab064 RF-сеанс завершён с ошибкой; повтор запрещён")
return result
def run_functional_tests() -> None:
assert SAMPLES_PER_SYMBOL == 400
assert PRBS_SYMBOLS == 1958
assert TX_SAMPLES == 6_000_000
rows, _ = prepared_segments()
assert len(rows) == 4
assert all(not row["metrics"]["digital_clipping"] for row in rows)
assert max(abs(row["tx_input_difference_from_previous_db"] - 6.0) for row in rows[1:]) < 0.1
assert synthetic_linearity_gate()["passed"]
assert "-t" not in transfer_command("NUL", 65_536)
try:
capture_once(authorization=False)
except PermissionError:
pass
else:
raise AssertionError("RF без отдельного разрешения")
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--stage",
choices=("prepare", "software", "preflight", "capture", "analyze"),
required=True,
)
parser.add_argument("--authorize-one-rf", action="store_true")
arguments = parser.parse_args()
if arguments.stage == "prepare":
result = prepare()
elif arguments.stage == "software":
result = software_gate()
elif arguments.stage == "preflight":
result = preflight()
elif arguments.stage == "capture":
result = capture_once(authorization=arguments.authorize_one_rf)
else:
result = analyze_capture()
print(json.dumps(result, ensure_ascii=False, indent=2, allow_nan=False))
print("RF TX = 0")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,623 @@
"""Lab065: та же лестница уровней при TX VGA 20 дБ.
Подготовка, программная проверка и preflight не передают RF. Единственный
аппаратный сеанс доступен только отдельной командой с явным разрешением.
"""
from __future__ import annotations
from dataclasses import asdict
import argparse
import hashlib
import json
from pathlib import Path
import shutil
import subprocess
import sys
import time
if __package__ in (None, ""):
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import numpy as np
from experiments import lab054_hardware_control as lab054
from experiments import lab056_capture_runner as hardware
from experiments import lab064_rf_level_linearity as lab064
ROOT = Path(__file__).resolve().parents[1]
RAW = ROOT / "data/raw/lab065"
OUTPUT = ROOT / "data/processed/lab065"
LAB064_RAW = ROOT / "data/raw/lab064"
LAB064_RESULT = ROOT / "data/processed/lab064/rf_result.json"
EXPECTED_TX_SHA256 = "fa260719659b2984fe29588238415622cd75c6daefec6cc9130ba1bf851bd3f9"
TX_VGA_DB = 20
TX_VGA_DIFFERENCE_DB = 10.0
MEANINGFUL_GAIN_DB = 3.0
MEANINGFUL_RATIO_IMPROVEMENT_DB = 3.0
MAX_LEVEL_TO_LEVEL_GAIN_SPREAD_DB = 3.0
RESIDUAL_TRACKING_MARGIN_DB = 3.0
POINT = hardware.OperatingPoint(**asdict(lab064.POINT))
def save_new(path: Path, value: dict) -> None:
"""Записать новое свидетельство и не перезаписывать результат опыта."""
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("x", encoding="utf-8") as stream:
json.dump(value, stream, ensure_ascii=False, indent=2, allow_nan=False)
stream.write("\n")
def save_text_new(path: Path, value: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("x", encoding="utf-8") as stream:
stream.write(value)
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
while block := stream.read(1024 * 1024):
digest.update(block)
return digest.hexdigest()
def parameters() -> dict:
result = lab064.parameters()
result["tx_vga_db"] = TX_VGA_DB
result["geometry_unchanged_from_lab064"] = True
result["waveform_source"] = "Lab064 exact CS8 copy"
return result
def transfer_command(path: Path | str, samples: int, *, transmit: bool = False) -> list[str]:
command = lab064.transfer_command(path, samples, transmit=transmit)
if transmit:
command[command.index("-x") + 1] = str(TX_VGA_DB)
return command
def validate_lab064_waveform() -> dict:
source = LAB064_RAW / "tx_level_staircase.cs8"
metadata = json.loads((LAB064_RAW / "tx_metadata.json").read_text(encoding="utf-8"))
digest = sha256(source)
if (
digest != EXPECTED_TX_SHA256
or metadata.get("tx_sha256") != EXPECTED_TX_SHA256
or source.stat().st_size != 2 * lab064.TX_SAMPLES
or metadata.get("segments") != lab064.prepared_segments()[0]
):
raise RuntimeError("Waveform Lab064 не совпадает с зафиксированным образцом")
return metadata
def validate_prepared() -> dict:
metadata = json.loads((RAW / "tx_metadata.json").read_text(encoding="utf-8"))
path = RAW / "tx_level_staircase.cs8"
if (
metadata.get("lab") != "Lab065"
or metadata.get("stage") != "PREPARATION_ONLY"
or metadata.get("rf_tx_count") != 0
or metadata.get("parameters") != parameters()
or metadata.get("tx_sha256") != EXPECTED_TX_SHA256
or metadata.get("source_tx_sha256") != EXPECTED_TX_SHA256
or path.stat().st_size != 2 * lab064.TX_SAMPLES
or sha256(path) != EXPECTED_TX_SHA256
):
raise RuntimeError("Подготовленный Lab065 TX или параметры изменились")
return metadata
def prepare() -> dict:
"""Скопировать точные байты Lab064 в отдельный каталог Lab065."""
source_metadata = validate_lab064_waveform()
RAW.mkdir(parents=True, exist_ok=True)
OUTPUT.mkdir(parents=True, exist_ok=True)
target = RAW / "tx_level_staircase.cs8"
if target.exists():
raise FileExistsError("TX-файл Lab065 уже существует")
shutil.copyfile(LAB064_RAW / "tx_level_staircase.cs8", target)
if sha256(target) != EXPECTED_TX_SHA256:
target.unlink()
raise RuntimeError("Копия waveform Lab065 не прошла SHA-256")
result = {
"lab": "Lab065",
"stage": "PREPARATION_ONLY",
"rf_tx_count": 0,
"head": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(),
"parameters": parameters(),
"segments": source_metadata["segments"],
"tx_samples": lab064.TX_SAMPLES,
"tx_bytes": 2 * lab064.TX_SAMPLES,
"tx_duration_seconds": lab064.TX_SAMPLES / lab064.SAMPLE_RATE,
"tx_sha256": sha256(target),
"source_tx_sha256": source_metadata["tx_sha256"],
"waveform_unchanged_from_lab064": True,
"automatic_retry": False,
"tx_command_prepared_not_run": transfer_command(target, lab064.TX_SAMPLES, transmit=True),
"rx_command_prepared_not_run": transfer_command(RAW / "rx_stream.cs8", lab064.RX_SAMPLES),
}
save_new(RAW / "tx_metadata.json", result)
save_new(OUTPUT / "preparation.json", result)
return result
def compare_sessions(old_result: dict, new_rows: list[dict]) -> dict:
"""Сопоставить одинаковые цифровые уровни Lab064 и Lab065."""
old_by_label = {row["label"]: row for row in old_result["rows"]}
rows = []
for new in new_rows:
old = old_by_label[new["label"]]
comparison = {
"label": new["label"],
"tx_vga_nominal_difference_db": TX_VGA_DIFFERENCE_DB,
"rx_matched_power_difference_db": lab064.difference_db(
new["matched_signal_power"], old["matched_signal_power"]
),
"gain_power_abs_h_squared_difference_db": lab064.difference_db(
new["gain_power_abs_h_squared"], old["gain_power_abs_h_squared"]
),
"residual_power_difference_db": lab064.difference_db(
new["residual_power"], old["residual_power"]
),
"matched_to_residual_improvement_db": (
new["matched_to_residual_db"] - old["matched_to_residual_db"]
),
}
if "complex_gain_h" in new and "residual_spectrum" in new:
old_gain = complex(
old["complex_gain_h"]["real"], old["complex_gain_h"]["imag"]
)
new_gain = complex(
new["complex_gain_h"]["real"], new["complex_gain_h"]["imag"]
)
comparison["complex_gain_h_old"] = old["complex_gain_h"]
comparison["complex_gain_h_new"] = new["complex_gain_h"]
comparison["complex_gain_phase_change_degrees"] = float(
np.degrees(np.angle(new_gain / old_gain))
)
comparison["residual_spectral_band_difference_db"] = {
f"h{harmonic}_{harmonic * lab064.CARRIER_HZ}_hz": lab064.difference_db(
new["residual_spectrum"][f"residual_band_h{harmonic}_power_code2"],
old["residual_spectrum"][f"residual_band_h{harmonic}_power_code2"],
)
for harmonic in (1, 2, 3)
}
rows.append(comparison)
return {"rows": rows, "rules_fixed_before_rf": classification_rules()}
def classification_rules() -> dict:
return {
"internal_linear_max_abs_error_db": 1.0,
"compression_upper_step_error_at_most_db": -1.5,
"meaningful_matched_gain_median_at_least_db": MEANINGFUL_GAIN_DB,
"meaningful_ratio_improvement_median_at_least_db": MEANINGFUL_RATIO_IMPROVEMENT_DB,
"maximum_level_to_level_gain_spread_db": MAX_LEVEL_TO_LEVEL_GAIN_SPREAD_DB,
"residual_tracks_if_within_matched_gain_db": RESIDUAL_TRACKING_MARGIN_DB,
}
def classify_result(new_result: dict, cross_comparison: dict) -> dict:
"""Выбрать один из пяти заранее заданных результатов Lab065."""
if not new_result.get("capture_valid"):
return {"case": "INVALID_CAPTURE", "rules_fixed_before_rf": classification_rules()}
internal_errors = [row["linearity_error_db"] for row in new_result["comparisons"]]
upper_error = internal_errors[-1]
cross_rows = cross_comparison["rows"]
matched = np.asarray([row["rx_matched_power_difference_db"] for row in cross_rows])
residual = np.asarray([row["residual_power_difference_db"] for row in cross_rows])
improvements = np.asarray([row["matched_to_residual_improvement_db"] for row in cross_rows])
median_matched = float(np.median(matched))
median_residual = float(np.median(residual))
median_improvement = float(np.median(improvements))
spread = float(np.ptp(matched))
linear = max(abs(value) for value in internal_errors) <= 1.0
if upper_error <= -1.5:
case = "COMPRESSION_AT_HIGHER_TX_GAIN"
elif median_matched < MEANINGFUL_GAIN_DB:
case = "NO_MEANINGFUL_GAIN"
elif (
linear
and spread <= MAX_LEVEL_TO_LEVEL_GAIN_SPREAD_DB
and median_improvement >= MEANINGFUL_RATIO_IMPROVEMENT_DB
):
case = "LINEAR_GAIN_IMPROVEMENT"
elif (
median_residual >= median_matched - RESIDUAL_TRACKING_MARGIN_DB
and median_improvement < MEANINGFUL_RATIO_IMPROVEMENT_DB
):
case = "RESIDUAL_RISES_WITH_SIGNAL"
else:
case = "NOT_LOCALIZED"
return {
"case": case,
"summary": {
"median_matched_gain_db": median_matched,
"median_residual_gain_db": median_residual,
"median_matched_to_residual_improvement_db": median_improvement,
"matched_gain_level_spread_db": spread,
"maximum_internal_linearity_error_db": max(abs(value) for value in internal_errors),
"upper_step_linearity_error_db": upper_error,
},
"rules_fixed_before_rf": classification_rules(),
}
def software_gate() -> dict:
metadata = validate_prepared()
old_result = json.loads(LAB064_RESULT.read_text(encoding="utf-8"))
synthetic = lab064.synthetic_linearity_gate()
result = {
"lab": "Lab065",
"stage": "SOFTWARE_GATE",
"rf_tx_count": 0,
"passed": bool(synthetic["passed"] and old_result["capture_valid"]),
"tx_sha256": metadata["tx_sha256"],
"waveform_unchanged_from_lab064": metadata["waveform_unchanged_from_lab064"],
"lab064_baseline_classification": old_result["classification"]["case"],
"classification_rules": classification_rules(),
}
save_new(OUTPUT / "software_gate.json", result)
if not result["passed"]:
raise RuntimeError("Lab065 software gate FAIL")
return result
def preflight(*, runner=None, process_checker=None, clock_checker=None, sleep_function=time.sleep) -> dict:
"""Проверить общую опору и 0,1 с RX-фона при полном запрете TX."""
metadata = validate_prepared()
software = json.loads((OUTPUT / "software_gate.json").read_text(encoding="utf-8"))
if not software.get("passed") or software.get("tx_sha256") != metadata["tx_sha256"]:
raise RuntimeError("Нет действующего Lab065 software gate")
save_new(RAW / "preflight_attempt.json", {
"lab": "Lab065", "rf_tx_count": 0, "point": asdict(POINT),
"parameters": parameters(), "tx_sha256": metadata["tx_sha256"],
})
actual_runner = runner or lab054.clock._default_command_runner
process_checker = process_checker or lab054.check_processes
clock_checker = clock_checker or hardware.common_clock
def rx_only(command: list[str]):
if "-t" in command:
raise PermissionError("TX запрещён в Lab065 preflight")
return actual_runner(command)
result = {
"lab": "Lab065", "stage": "COMMON_CLOCK_AND_RX_ONLY_PREFLIGHT",
"passed": False, "rf_tx_count": 0, "stop_before_tx": True,
"point": asdict(POINT), "parameters": parameters(),
"tx_sha256": metadata["tx_sha256"],
}
clock_started = False
try:
before = process_checker()
result["process_before"] = before.to_dict()
lab054.require_clear(before)
result["inventory"] = lab054.phy.lab045._verify_device_inventory(rx_only)
clock_started = True
result["clock"] = clock_checker(
POINT, rx_only, lab054.clock.TransmitGuard(), sleep_function=sleep_function
)
hardware.require_clock_pass(result["clock"])
path = RAW / "preflight_rx.cs8"
captured = rx_only(transfer_command(path, lab064.PREFLIGHT_SAMPLES))
stdout, stderr = captured.stdout or "", captured.stderr or ""
result["rx_process"] = {
"returncode": captured.returncode, "stdout": stdout, "stderr": stderr,
}
result["rx_counter_summary"] = lab064.counter_summary(stdout + stderr, "overrun")
if captured.returncode or not result["rx_counter_summary"]["clean"]:
raise RuntimeError("RX preflight: процесс или счётчик overruns не прошёл")
if path.stat().st_size != 2 * lab064.PREFLIGHT_SAMPLES:
raise RuntimeError("Неверная длина Lab065 preflight RX")
level = hardware.receive_level(path)
level.pop("symbol_energy_code2_seconds", None)
level["symbol_energy"] = "NOT_APPLICABLE_TO_BACKGROUND"
level["ac_rms_code"] = float(np.sqrt(max(0.0, level["ac_power_code2"])))
level["unexpected_strong_signal"] = bool(
level["ac_rms_code"] >= lab064.STRONG_AC_RMS_CODE
or level["max_abs_i"] >= lab064.STRONG_COMPONENT_CODE
or level["max_abs_q"] >= lab064.STRONG_COMPONENT_CODE
)
result["rx_level"] = level
result["rx_sha256"] = sha256(path)
result["rx_overruns"] = result["rx_counter_summary"]["final_count"]
if level["saturation_detected"] or level["unexpected_strong_signal"]:
raise RuntimeError("RX-only уровень не прошёл gate; STOP без изменения gain")
result["passed"] = True
except Exception as error:
result["error"] = str(error)
raise
finally:
errors = lab054.disable_clock_outputs(rx_only) if clock_started else []
try:
after = process_checker()
result["process_after"] = after.to_dict()
lab054.require_clear(after)
except Exception as error:
errors.append(str(error))
result["cleanup_errors"] = errors
result["passed"] = result["passed"] and not errors
save_new(RAW / "preflight_result.json", result)
OUTPUT.mkdir(parents=True, exist_ok=True)
(OUTPUT / "preflight_result.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2, allow_nan=False) + "\n",
encoding="utf-8",
)
if not result["passed"]:
raise RuntimeError("Lab065 preflight FAIL")
return result
def require_preflight(metadata: dict) -> dict:
record = json.loads((RAW / "preflight_result.json").read_text(encoding="utf-8"))
if (
record.get("passed") is not True
or record.get("rf_tx_count") != 0
or record.get("point") != asdict(POINT)
or record.get("parameters") != parameters()
or record.get("tx_sha256") != metadata["tx_sha256"]
):
raise PermissionError("Нет успешного RX-only preflight для конфигурации Lab065")
hardware.require_clock_pass(record.get("clock", {}))
level = record.get("rx_level", {})
if (
level.get("saturation_detected") is not False
or level.get("unexpected_strong_signal") is not False
or record.get("rx_overruns") != 0
):
raise PermissionError("RX-only preflight не разрешает передачу")
return record
def capture_once(
*, authorization: bool = False, runner=None, process_starter=None,
process_checker=None, clock_checker=None, sleep_function=time.sleep,
) -> dict:
"""Выполнить один RX-first сеанс после отдельного прямого разрешения."""
if authorization is not True:
raise PermissionError("Нужно отдельное разрешение на единственный RF-сеанс Lab065")
metadata = validate_prepared()
require_preflight(metadata)
receive_path = RAW / "rx_stream.cs8"
if receive_path.exists() or (RAW / "capture_result.json").exists():
raise FileExistsError("Аппаратный результат Lab065 уже существует")
actual_runner = runner or lab054.clock._default_command_runner
process_starter = process_starter or lab054.clock._default_process_starter
process_checker = process_checker or lab054.check_processes
clock_checker = clock_checker or hardware.common_clock
save_new(RAW / "hardware_attempt.json", {
"lab": "Lab065", "authorized_once": True, "automatic_retry": False,
"point": asdict(POINT), "parameters": parameters(),
"tx_sha256": metadata["tx_sha256"],
})
result = {
"lab": "Lab065", "stage": "SINGLE_RF_LEVEL_CAPTURE", "passed": False,
"rf_tx_count": 0, "automatic_tx_repeats": 0, "point": asdict(POINT),
"parameters": parameters(), "tx_sha256": metadata["tx_sha256"],
}
guard = lab054.clock.TransmitGuard()
process = None
clock_started = False
try:
before = process_checker()
result["process_before"] = before.to_dict()
lab054.require_clear(before)
result["inventory"] = lab054.phy.lab045._verify_device_inventory(actual_runner)
clock_started = True
result["clock"] = clock_checker(
POINT, actual_runner, guard, sleep_function=sleep_function
)
hardware.require_clock_pass(result["clock"])
process = process_starter(
transfer_command(receive_path, lab064.RX_SAMPLES),
RAW / "rx_stdout.txt", RAW / "rx_stderr.txt",
)
sleep_function(lab064.RX_LEAD_SECONDS)
if process.poll() is not None:
raise RuntimeError("RX завершился до TX")
before_tx = hardware.receive_level(receive_path, tail_samples=65_536)
before_tx.pop("symbol_energy_code2_seconds", None)
result["rx_level_before_tx"] = before_tx
if before_tx["saturation_detected"]:
raise RuntimeError("RX clipping до TX; RF TX = 0")
guard.register_transmit()
result["rf_tx_count"] = guard.transmit_calls
transmitted = actual_runner(
transfer_command(RAW / "tx_level_staircase.cs8", lab064.TX_SAMPLES, transmit=True)
)
tx_stdout, tx_stderr = transmitted.stdout or "", transmitted.stderr or ""
save_text_new(RAW / "tx_stdout.txt", tx_stdout)
save_text_new(RAW / "tx_stderr.txt", tx_stderr)
result["tx_process"] = {
"returncode": transmitted.returncode,
"stdout_file": "tx_stdout.txt", "stderr_file": "tx_stderr.txt",
}
result["tx_counter_summary"] = lab064.counter_summary(
tx_stdout + tx_stderr, "underrun"
)
if transmitted.returncode:
raise RuntimeError("Единственный TX завершился ошибкой; повтор запрещён")
if process.wait(lab064.RX_SECONDS + 10):
raise RuntimeError("RX завершился ошибкой; повтор запрещён")
process.close_logs()
result["rx_samples"] = receive_path.stat().st_size // 2
result["rx_bytes"] = receive_path.stat().st_size
result["rx_duration_seconds"] = result["rx_samples"] / lab064.SAMPLE_RATE
if result["rx_bytes"] != 2 * lab064.RX_SAMPLES:
raise RuntimeError("Повреждённая длина RX; повтор запрещён")
rx_stdout = (RAW / "rx_stdout.txt").read_text(encoding="utf-8")
rx_stderr = (RAW / "rx_stderr.txt").read_text(encoding="utf-8")
result["rx_counter_summary"] = lab064.counter_summary(
rx_stdout + rx_stderr, "overrun"
)
result["rx_sha256"] = sha256(receive_path)
level = hardware.receive_level(receive_path)
level.pop("symbol_energy_code2_seconds", None)
result["rx_level"] = level
result["rx_clipping"] = bool(level["saturation_detected"])
result["passed"] = True
validity = lab064.capture_validity(result)
if not validity["valid"]:
result["passed"] = False
raise RuntimeError("Запись невалидна; результат сохранён, повтор запрещён")
except Exception as error:
result["error"] = str(error)
raise
finally:
errors = []
if process is not None:
try:
process.terminate()
except Exception as error:
errors.append(str(error))
if clock_started:
errors.extend(lab054.disable_clock_outputs(actual_runner))
try:
after = process_checker()
result["process_after"] = after.to_dict()
lab054.require_clear(after)
except Exception as error:
errors.append(str(error))
result["cleanup_errors"] = errors
result["passed"] = result["passed"] and not errors
save_new(RAW / "capture_result.json", result)
OUTPUT.mkdir(parents=True, exist_ok=True)
(OUTPUT / "capture_result.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2, allow_nan=False) + "\n",
encoding="utf-8",
)
if not result["passed"]:
raise RuntimeError("Lab065 RF-сеанс завершён с ошибкой; повтор запрещён")
return result
def analyze_capture() -> dict:
"""Рассчитать метрики Lab065 и прямое сравнение с Lab064."""
metadata = validate_prepared()
rx_path = RAW / "rx_stream.cs8"
capture = json.loads((RAW / "capture_result.json").read_text(encoding="utf-8"))
if capture.get("rf_tx_count") != 1 or capture.get("rx_sha256") != sha256(rx_path):
raise RuntimeError("Нет подтверждённой единственной RX-записи Lab065")
tx = lab064.energy.Cs8File(RAW / "tx_level_staircase.cs8")
rx = lab064.energy.Cs8File(rx_path)
location = lab064.locate_waveform(tx, rx)
background_rows = []
for window in lab064.background_windows():
rx_start = location["start_sample"] + window["tx_relative_start_sample"]
background_rows.append({
**window, "rx_start_sample": rx_start,
"metrics": lab064._window_metrics(rx.read(rx_start, window["samples"])),
})
background_by_label = {row["label"]: row for row in background_rows}
preceding = {"L0": "INITIAL_GUARD", "L1": "GAP_L0_L1",
"L2": "GAP_L1_L2", "L3": "GAP_L2_L3"}
rows = []
for segment in metadata["segments"]:
tx_start = segment["start_sample"]
nominal_rx_start = location["start_sample"] + tx_start
fitted = lab064.energy.analyze_rx(
lab064.lab056.OffsetSource(tx, tx_start), rx, [nominal_rx_start],
lab064.SEGMENT_SAMPLES, lab064.SAMPLES_PER_SYMBOL,
)["frames"][0]
actual_start = fitted["start"]
active_reference = tx.read(
tx_start + lab064.TRIM_SAMPLES,
lab064.SEGMENT_SAMPLES - 2 * lab064.TRIM_SAMPLES,
)
active_received = rx.read(
actual_start + lab064.TRIM_SAMPLES,
lab064.SEGMENT_SAMPLES - 2 * lab064.TRIM_SAMPLES,
)
complex_gain = lab064.lab056.complex_gain(
active_reference, active_received, fitted["cfo_hz"]
)
matched = fitted["heldout_signal_power"]
residual = fitted["heldout_residual_power"]
background = background_by_label[preceding[segment["label"]]]
rows.append({
"label": segment["label"], "level_db": segment["level_db"],
"rx_start_sample": actual_start,
"alignment_adjustment_samples": fitted["alignment_adjustment"],
"full_iq": lab064._window_metrics(rx.read(actual_start, lab064.SEGMENT_SAMPLES)),
"background_label": background["label"], "background": background["metrics"],
"matched_signal_power": matched, "residual_power": residual,
"matched_to_residual_db": lab064.difference_db(matched, residual),
"complex_gain_h": complex_gain, "gain_abs": fitted["gain_abs"],
"gain_power_abs_h_squared": fitted["gain_abs"] ** 2,
"cfo_hz": fitted["cfo_hz"],
"residual_spectrum": lab064.residual_spectral_diagnostics(
active_reference, active_received, fitted["cfo_hz"], complex_gain
),
})
comparisons = []
for index in range(1, len(rows)):
tx_difference = metadata["segments"][index]["tx_input_difference_from_previous_db"]
rx_difference = lab064.difference_db(
rows[index]["matched_signal_power"], rows[index - 1]["matched_signal_power"]
)
comparisons.append({
"comparison": f"{rows[index]['label']}/{rows[index - 1]['label']}",
"tx_input_difference_db": tx_difference,
"rx_matched_power_difference_db": rx_difference,
"linearity_error_db": rx_difference - tx_difference,
})
validity = lab064.capture_validity(capture)
result = {
"lab": "Lab065", "stage": "OFFLINE_RF_LEVEL_LINEARITY_ANALYSIS",
"packet_receiver_used": False, "location": location, "rows": rows,
"background_windows": background_rows,
"background_summary": lab064.summarize_background(background_rows),
"comparisons": comparisons, "capture_valid": validity["valid"],
"capture_invalid_reasons": validity["invalid_reasons"],
"tx_underruns_maximum": capture.get("tx_counter_summary", {}).get("maximum_count"),
"rx_overruns_maximum": capture.get("rx_counter_summary", {}).get("maximum_count"),
"rx_clipping": any(row["full_iq"]["clipped_samples_fraction"] > 0 for row in rows),
}
old_result = json.loads(LAB064_RESULT.read_text(encoding="utf-8"))
result["lab064_to_lab065"] = compare_sessions(old_result, rows)
result["classification"] = classify_result(result, result["lab064_to_lab065"])
save_new(OUTPUT / "rf_result.json", result)
return result
def run_functional_tests() -> None:
assert transfer_command("NUL", 100, transmit=True)[-7:-5] == ["-x", "20"]
assert "-t" not in transfer_command("NUL", 100)
assert validate_lab064_waveform()["tx_sha256"] == EXPECTED_TX_SHA256
assert lab064.synthetic_linearity_gate()["passed"]
try:
capture_once(authorization=False)
except PermissionError:
pass
else:
raise AssertionError("RF без отдельного разрешения")
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--stage", choices=("prepare", "software", "preflight", "capture", "analyze"),
required=True,
)
parser.add_argument("--authorize-one-rf", action="store_true")
arguments = parser.parse_args()
if arguments.stage == "prepare":
result = prepare()
elif arguments.stage == "software":
result = software_gate()
elif arguments.stage == "preflight":
result = preflight()
elif arguments.stage == "capture":
result = capture_once(authorization=arguments.authorize_one_rf)
else:
result = analyze_capture()
print(json.dumps(result, ensure_ascii=False, indent=2, allow_nan=False))
print("RF TX NOW = 0")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,786 @@
"""Lab066: исправленный повтор полного 500K PHY-сеанса.
Подготовка, программная проверка и preflight не передают RF. Единственный
аппаратный сеанс доступен только отдельной командой с явным разрешением.
"""
from __future__ import annotations
from dataclasses import asdict
import argparse
import csv
import hashlib
import json
from pathlib import Path
import subprocess
import sys
import time
if __package__ in (None, ""):
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import numpy as np
from scipy import signal
from experiments import lab049_bpsk_symbol_rate as phy
from experiments import lab053_packet_processing as packet_processing
from experiments import lab053_streaming_receiver as streaming
from experiments import lab054_hardware_control as lab054
from experiments import lab056_capture_runner as hardware
from experiments import lab058_abab_symbol_quality as lab058
from experiments import lab064_rf_level_linearity as lab064
ROOT = Path(__file__).resolve().parents[1]
RAW = ROOT / "data/raw/lab066"
OUTPUT = ROOT / "data/processed/lab066"
POINT = hardware.OperatingPoint(
frequency_hz=1_400_000_000,
physical_path="MASTER TX near window -> LOS indoor -> SLAVE RX on desk",
path_confirmed=True,
tx_antenna="existing 1400 MHz antenna near window",
rx_antenna="existing 1400 MHz antenna on desk",
distance_m=1.2,
orientation="same polarization; fixed during preflight and RF session",
visibility="LOS indoor",
)
MODE = phy.PhyMode(500_000)
PACKETS = 16
PAYLOAD_BYTES = 256
PACKET_SAMPLES = 92_256
INTER_PACKET_GAP_SECONDS = 0.005
INTER_PACKET_GAP_SAMPLES = 40_000
NUMBER_OF_GAPS = PACKETS - 1
GUARD_SECONDS = 0.1
GUARD_SAMPLES = 800_000
BASE_TX_SAMPLES = PACKETS * PACKET_SAMPLES + NUMBER_OF_GAPS * INTER_PACKET_GAP_SAMPLES
EXPECTED_TX_SAMPLES = BASE_TX_SAMPLES + 2 * GUARD_SAMPLES
PREFLIGHT_SAMPLES = 800_000
RX_SECONDS = 2
RX_SAMPLES = RX_SECONDS * MODE.sample_rate_hz
RX_LEAD_SECONDS = 0.5
TX_VGA_DB = 20
STRONG_AC_RMS_CODE = 20.0
STRONG_COMPONENT_CODE = 100.0
def save_new(path: Path, value: dict) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
with path.open("x", encoding="utf-8") as stream:
json.dump(value, stream, ensure_ascii=False, indent=2, allow_nan=False)
stream.write("\n")
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
while block := stream.read(1024 * 1024):
digest.update(block)
return digest.hexdigest()
def plans():
result = lab054.plans()
payloads = [frame.plan.payload for frame in result]
if len(result) != PACKETS or any(len(payload) != PAYLOAD_BYTES for payload in payloads):
raise RuntimeError("Штатный генератор не дал 16 payload по 256 байт")
if len(set(payloads)) != PACKETS:
raise RuntimeError("Payload пакетов должны однозначно различаться")
return result
def parameters() -> dict:
return {
"rf_frequency_hz": POINT.frequency_hz,
"sample_rate_hz": MODE.sample_rate_hz,
"symbol_rate": MODE.symbol_rate,
"samples_per_symbol": MODE.samples_per_symbol,
"digital_carrier_hz": lab054.phy.lab045.CARRIER_OFFSET_HZ,
"packets": PACKETS,
"payload_bytes": PAYLOAD_BYTES,
"tx_vga_db": TX_VGA_DB,
"rx_lna_db": 24,
"rx_vga_db": 24,
"rf_amplifier": False,
"bias_tee": False,
"geometry": asdict(POINT),
"geometry_unchanged": True,
"clock_path": "10 MHz TCXO -> MASTER -> MASTER CLKOUT -> SLAVE CLKIN",
}
def transfer_command(path: Path | str, samples: int, *, transmit: bool = False) -> list[str]:
command = hardware.command(POINT, path, samples, transmit=transmit)
if transmit:
command[command.index("-x") + 1] = str(TX_VGA_DB)
return command
def build_waveform() -> tuple[bytes, list[dict]]:
"""Собрать финальный поток с нулевыми guards и паузами."""
blocks: list[bytes] = [bytes(2 * GUARD_SAMPLES)]
layout: list[dict] = []
cursor = GUARD_SAMPLES
for index, frame in enumerate(plans(), start=1):
packet = phy.build_parameterized_tx_cs8(frame.plan, MODE)
if len(packet) != 2 * PACKET_SAMPLES:
raise RuntimeError(f"Пакет {index}: ожидалось {PACKET_SAMPLES} отсчётов")
layout.append({
"packet_index": index,
"start_sample": cursor,
"samples": PACKET_SAMPLES,
"payload_sha256": hashlib.sha256(frame.plan.payload).hexdigest(),
})
blocks.append(packet)
cursor += PACKET_SAMPLES
if index != PACKETS:
blocks.append(bytes(2 * INTER_PACKET_GAP_SAMPLES))
layout[-1]["following_gap_start_sample"] = cursor
layout[-1]["following_gap_samples"] = INTER_PACKET_GAP_SAMPLES
cursor += INTER_PACKET_GAP_SAMPLES
blocks.append(bytes(2 * GUARD_SAMPLES))
waveform = b"".join(blocks)
if len(waveform) != 2 * EXPECTED_TX_SAMPLES or cursor + GUARD_SAMPLES != EXPECTED_TX_SAMPLES:
raise RuntimeError("Неверная длина итогового TX-потока Lab066")
return waveform, layout
def prepare() -> dict:
RAW.mkdir(parents=True, exist_ok=True)
OUTPUT.mkdir(parents=True, exist_ok=True)
waveform_path = RAW / "tx_stream.cs8"
if waveform_path.exists():
raise FileExistsError("Lab066 TX уже существует; перезапись запрещена")
waveform, layout = build_waveform()
waveform_path.write_bytes(waveform)
result = {
"lab": "Lab066", "stage": "PREPARATION_ONLY", "rf_tx_count": 0,
"head": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(),
"parameters": parameters(), "packet_samples": PACKET_SAMPLES,
"inter_packet_gap_seconds": INTER_PACKET_GAP_SECONDS,
"inter_packet_gap_samples": INTER_PACKET_GAP_SAMPLES,
"number_of_gaps": NUMBER_OF_GAPS,
"zero_guard_before_samples": GUARD_SAMPLES,
"zero_guard_after_samples": GUARD_SAMPLES,
"base_tx_samples": BASE_TX_SAMPLES,
"expected_tx_samples": EXPECTED_TX_SAMPLES,
"tx_samples": EXPECTED_TX_SAMPLES, "tx_bytes": len(waveform),
"tx_duration_seconds": EXPECTED_TX_SAMPLES / MODE.sample_rate_hz,
"tx_sha256": sha256(waveform_path), "layout": layout,
"rx_samples": RX_SAMPLES, "rx_duration_seconds": RX_SECONDS,
"automatic_retry": False,
"tx_command_prepared_not_run": transfer_command(waveform_path, EXPECTED_TX_SAMPLES, transmit=True),
"rx_command_prepared_not_run": transfer_command(RAW / "rx_stream.cs8", RX_SAMPLES),
}
save_new(RAW / "tx_metadata.json", result)
save_new(OUTPUT / "preparation.json", result)
return result
def validate_prepared() -> dict:
metadata = json.loads((RAW / "tx_metadata.json").read_text(encoding="utf-8"))
path = RAW / "tx_stream.cs8"
expected, layout = build_waveform()
expected_digest = hashlib.sha256(expected).hexdigest()
actual = path.read_bytes()
if (
metadata.get("lab") != "Lab066"
or metadata.get("stage") != "PREPARATION_ONLY"
or metadata.get("rf_tx_count") != 0
or metadata.get("parameters") != parameters()
or metadata.get("layout") != layout
or metadata.get("expected_tx_samples") != EXPECTED_TX_SAMPLES
or metadata.get("tx_samples") != EXPECTED_TX_SAMPLES
or len(actual) != 2 * EXPECTED_TX_SAMPLES
or metadata.get("tx_sha256") != expected_digest
or hashlib.sha256(actual).hexdigest() != expected_digest
or actual != expected
):
raise RuntimeError("Подготовленный Lab066 TX или его разметка изменились")
return metadata
def decode(mode: str, source_path: Path | None = None, *, diagnostics: bool = False) -> dict:
"""Строго декодировать весь поток; legacy и T2 запускаются отдельно."""
observations = []
receiver = streaming.StreamingReceiver(
processor=packet_processing.PacketProcessor(carrier_tracking_mode=mode),
packet_observer=lambda row, outcome: observations.append((row, outcome)),
)
received = []
with (source_path or (RAW / "tx_stream.cs8")).open("rb") as stream:
while block := stream.read(2 * receiver.block_samples):
values = np.frombuffer(block, np.int8)
samples = values[::2].astype(np.float32) + 1j * values[1::2].astype(np.float32)
received.extend(receiver.push_iq_block(samples.astype(np.complex64)))
received.extend(receiver.finish())
expected = [frame.plan.payload for frame in plans()]
actual = [item.payload for item in received]
payload_to_index = {payload: index for index, payload in enumerate(expected, start=1)}
result = {
"mode": mode, "candidates": len(observations),
"header_pass": sum(outcome.phy_header_pass for _, outcome in observations),
"fec_started": sum(outcome.fec_attempted for _, outcome in observations),
"fec_pass": sum(outcome.fec_pass for _, outcome in observations),
"crc_started": sum(outcome.crc != "NOT_REACHED" for _, outcome in observations),
"crc_pass": sum(outcome.crc == "PASS" for _, outcome in observations),
"packet_output": len(actual),
"exact_payload_match": sum(payload in payload_to_index for payload in actual),
"packet_indexes": [payload_to_index.get(payload) for payload in actual],
"exact_ordered_payloads": actual == expected,
"t2_state_scope": "NEW_PREAMBLE_ESTIMATE_PER_PACKET" if mode == "t2" else "NOT_APPLICABLE",
"fallback_between_modes": False,
"passed": len(actual) == PACKETS and actual == expected,
}
if diagnostics:
result["rows"] = [{
"absolute_refined": int(row["absolute_refined"]),
"reason": outcome.reason,
"header": bool(outcome.phy_header_pass),
"fec_started": bool(outcome.fec_attempted), "fec": bool(outcome.fec_pass),
"crc_started": outcome.crc != "NOT_REACHED", "crc": outcome.crc == "PASS",
"packet_output": bool(outcome.accepted and outcome.crc == "PASS"),
"packet_index_after_verdict": payload_to_index.get(
bytes(outcome.frame.reception.payload_bytes)
if outcome.frame is not None and outcome.frame.reception.payload_bytes is not None else b""
),
"t2_tracking_runs_for_candidate": len(row.get("carrier_tracking_traces", ())),
} for row, outcome in observations]
result["detector_statistics"] = dict(receiver.detection_statistics)
result["candidate_overflow"] = receiver.candidate_overflow
if mode == "t2":
result["t2_state_reset_evidence"] = {
"estimate_source": "each candidate's own preamble",
"context_scope": "new PacketMeasure context for every candidate",
"tracking_runs_per_accepted_packet": [
row["t2_tracking_runs_for_candidate"]
for row in result["rows"] if row["packet_output"]
],
"all_accepted_packets_have_fresh_tracking_runs": all(
row["t2_tracking_runs_for_candidate"] > 0
for row in result["rows"] if row["packet_output"]
),
"persistent_tracking_state_in_packet_processor": False,
}
return result
def software_gate() -> dict:
metadata = validate_prepared()
legacy = decode("legacy", diagnostics=True)
t2 = decode("t2", diagnostics=True)
result = {
"lab": "Lab066", "stage": "SOFTWARE_GATE", "rf_tx_count": 0,
"tx_sha256": metadata["tx_sha256"], "legacy": legacy, "t2": t2,
"gaps_verified_zero": True,
"t2_state_reset_verified_by_fresh_preamble_per_packet": bool(
t2.get("t2_state_reset_evidence", {}).get(
"all_accepted_packets_have_fresh_tracking_runs"
)
),
"passed": (
legacy["passed"] and t2["passed"]
and t2.get("t2_state_reset_evidence", {}).get(
"all_accepted_packets_have_fresh_tracking_runs"
) is True
),
}
save_new(OUTPUT / "software_gate.json", result)
if not result["passed"]:
raise RuntimeError("Lab066 software gate FAIL")
return result
def preflight(*, runner=None, process_checker=None, clock_checker=None,
sleep_function=time.sleep) -> dict:
metadata = validate_prepared()
software = json.loads((OUTPUT / "software_gate.json").read_text(encoding="utf-8"))
if not software.get("passed") or software.get("tx_sha256") != metadata["tx_sha256"]:
raise RuntimeError("Нет действующего software gate Lab066")
save_new(RAW / "preflight_attempt.json", {
"lab": "Lab066", "rf_tx_count": 0, "point": asdict(POINT),
"tx_sha256": metadata["tx_sha256"],
})
actual_runner = runner or lab054.clock._default_command_runner
process_checker = process_checker or lab054.check_processes
clock_checker = clock_checker or hardware.common_clock
def rx_only(command):
if "-t" in command:
raise PermissionError("TX запрещён в Lab066 preflight")
return actual_runner(command)
result = {
"lab": "Lab066", "stage": "RX_ONLY_PREFLIGHT", "passed": False,
"rf_tx_count": 0, "point": asdict(POINT), "parameters": parameters(),
"tx_sha256": metadata["tx_sha256"], "stop_before_tx": True,
}
clock_started = False
try:
before = process_checker()
result["process_before"] = before.to_dict()
lab054.require_clear(before)
result["inventory"] = lab054.phy.lab045._verify_device_inventory(rx_only)
clock_started = True
result["clock"] = clock_checker(
POINT, rx_only, lab054.clock.TransmitGuard(), sleep_function=sleep_function
)
hardware.require_clock_pass(result["clock"])
path = RAW / "preflight_rx.cs8"
if path.exists():
raise FileExistsError("Lab066 preflight RX уже существует")
captured = rx_only(transfer_command(path, PREFLIGHT_SAMPLES))
stdout, stderr = captured.stdout or "", captured.stderr or ""
result["rx_process"] = {"returncode": captured.returncode, "stdout": stdout, "stderr": stderr}
result["rx_counter_summary"] = lab064.counter_summary(stdout + stderr, "overrun")
if captured.returncode or not result["rx_counter_summary"]["clean"]:
raise RuntimeError("RX preflight: процесс или максимум overruns не прошёл")
if path.stat().st_size != 2 * PREFLIGHT_SAMPLES:
raise RuntimeError("Неверная длина Lab066 preflight RX")
level = hardware.receive_level(path)
level.pop("symbol_energy_code2_seconds", None)
level["symbol_energy"] = "NOT_APPLICABLE_TO_BACKGROUND"
ac_rms = float(np.sqrt(max(0.0, level["ac_power_code2"])))
strong = bool(ac_rms >= STRONG_AC_RMS_CODE or level["max_abs_i"] >= STRONG_COMPONENT_CODE
or level["max_abs_q"] >= STRONG_COMPONENT_CODE)
level.update({"ac_rms_code": ac_rms, "unexpected_strong_signal": strong})
result["rx_level"] = level
result["rx_sha256"] = sha256(path)
result["rx_overruns"] = result["rx_counter_summary"]["maximum_count"]
if level["saturation_detected"]:
raise RuntimeError("RX clipping; STOP без изменения gain")
if strong:
raise RuntimeError("Неожиданно сильный RX-only фон; STOP без изменения gain")
result["passed"] = True
except Exception as error:
result["error"] = str(error)
raise
finally:
errors = lab054.disable_clock_outputs(rx_only) if clock_started else []
try:
after = process_checker()
result["process_after"] = after.to_dict()
lab054.require_clear(after)
except Exception as error:
errors.append(str(error))
result["cleanup_errors"] = errors
result["passed"] = result["passed"] and not errors
save_new(RAW / "preflight_result.json", result)
OUTPUT.mkdir(parents=True, exist_ok=True)
(OUTPUT / "preflight_result.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2, allow_nan=False) + "\n", encoding="utf-8"
)
if not result["passed"]:
raise RuntimeError("Lab066 preflight FAIL")
return result
def require_preflight(metadata: dict) -> dict:
record = json.loads((RAW / "preflight_result.json").read_text(encoding="utf-8"))
if (record.get("passed") is not True or record.get("rf_tx_count") != 0
or record.get("point") != asdict(POINT) or record.get("parameters") != parameters()
or record.get("tx_sha256") != metadata["tx_sha256"]):
raise PermissionError("Нет успешного RX-only preflight для конфигурации Lab066")
hardware.require_clock_pass(record.get("clock", {}))
if (record.get("rx_overruns") != 0
or record.get("rx_level", {}).get("saturation_detected") is not False
or record.get("rx_level", {}).get("unexpected_strong_signal") is not False):
raise PermissionError("RX-only preflight не разрешает передачу")
return record
def capture_once(*, authorization: bool = False, runner=None, process_starter=None,
process_checker=None, clock_checker=None, sleep_function=time.sleep) -> dict:
"""Выполнить будущий единственный RX-first сеанс после отдельного разрешения."""
if authorization is not True:
raise PermissionError("Нужно отдельное разрешение на единственный RF-сеанс Lab066")
metadata = validate_prepared()
require_preflight(metadata)
receive_path = RAW / "rx_stream.cs8"
if receive_path.exists() or (RAW / "capture_result.json").exists():
raise FileExistsError("Аппаратный результат Lab066 уже существует")
actual_runner = runner or lab054.clock._default_command_runner
process_starter = process_starter or lab054.clock._default_process_starter
process_checker = process_checker or lab054.check_processes
clock_checker = clock_checker or hardware.common_clock
save_new(RAW / "hardware_attempt.json", {
"lab": "Lab066", "authorized_once": True, "automatic_retry": False,
"point": asdict(POINT), "parameters": parameters(), "tx_sha256": metadata["tx_sha256"],
})
result = {
"lab": "Lab066", "stage": "SINGLE_RF_CAPTURE", "passed": False,
"rf_tx_count": 0, "automatic_tx_repeats": 0, "point": asdict(POINT),
"parameters": parameters(), "tx_sha256": metadata["tx_sha256"],
}
guard, process, clock_started = lab054.clock.TransmitGuard(), None, False
try:
before = process_checker(); result["process_before"] = before.to_dict(); lab054.require_clear(before)
result["inventory"] = lab054.phy.lab045._verify_device_inventory(actual_runner)
clock_started = True
result["clock"] = clock_checker(POINT, actual_runner, guard, sleep_function=sleep_function)
hardware.require_clock_pass(result["clock"])
process = process_starter(transfer_command(receive_path, RX_SAMPLES), RAW / "rx_stdout.txt", RAW / "rx_stderr.txt")
sleep_function(RX_LEAD_SECONDS)
if process.poll() is not None:
raise RuntimeError("RX завершился до TX")
before_tx = hardware.receive_level(receive_path, tail_samples=65_536)
before_tx.pop("symbol_energy_code2_seconds", None)
before_tx_ac_rms = float(np.sqrt(max(0.0, before_tx["ac_power_code2"])))
before_tx_strong = bool(
before_tx_ac_rms >= STRONG_AC_RMS_CODE
or before_tx["max_abs_i"] >= STRONG_COMPONENT_CODE
or before_tx["max_abs_q"] >= STRONG_COMPONENT_CODE
)
before_tx.update({
"ac_rms_code": before_tx_ac_rms,
"unexpected_strong_signal": before_tx_strong,
})
result["rx_level_before_tx"] = before_tx
if before_tx["saturation_detected"]:
raise RuntimeError("RX clipping до TX; RF TX = 0")
if before_tx_strong:
raise RuntimeError("Неожиданно сильный фон непосредственно перед TX; RF TX = 0")
guard.register_transmit(); result["rf_tx_count"] = guard.transmit_calls
transmitted = actual_runner(transfer_command(RAW / "tx_stream.cs8", EXPECTED_TX_SAMPLES, transmit=True))
tx_stdout, tx_stderr = transmitted.stdout or "", transmitted.stderr or ""
(RAW / "tx_stdout.txt").write_text(tx_stdout, encoding="utf-8")
(RAW / "tx_stderr.txt").write_text(tx_stderr, encoding="utf-8")
result["tx_process"] = {"returncode": transmitted.returncode,
"stdout_file": "tx_stdout.txt", "stderr_file": "tx_stderr.txt"}
result["tx_counter_summary"] = lab064.counter_summary(tx_stdout + tx_stderr, "underrun")
if transmitted.returncode:
raise RuntimeError("Единственный TX завершился ошибкой; повтор запрещён")
if process.wait(RX_SECONDS + 10):
raise RuntimeError("RX завершился ошибкой; повтор запрещён")
process.close_logs()
rx_log = (RAW / "rx_stdout.txt").read_text(encoding="utf-8") + (RAW / "rx_stderr.txt").read_text(encoding="utf-8")
result["rx_counter_summary"] = lab064.counter_summary(rx_log, "overrun")
result["rx_samples"] = receive_path.stat().st_size // 2
result["rx_sha256"] = sha256(receive_path)
result["rx_level"] = hardware.receive_level(receive_path)
result["rx_clipping"] = bool(result["rx_level"]["saturation_detected"])
result["passed"] = result["rx_samples"] == RX_SAMPLES
validity = lab064.capture_validity(result)
if not validity["valid"] or not result["passed"]:
result["passed"] = False
raise RuntimeError("INVALID_CAPTURE; запись сохранена, повтор запрещён")
except Exception as error:
result["error"] = str(error)
raise
finally:
errors = []
if process is not None:
try: process.terminate()
except Exception as error: errors.append(str(error))
if clock_started: errors.extend(lab054.disable_clock_outputs(actual_runner))
try:
after = process_checker(); result["process_after"] = after.to_dict(); lab054.require_clear(after)
except Exception as error: errors.append(str(error))
result["cleanup_errors"] = errors
result["passed"] = result["passed"] and not errors
save_new(RAW / "capture_result.json", result)
OUTPUT.mkdir(parents=True, exist_ok=True)
(OUTPUT / "capture_result.json").write_text(json.dumps(result, ensure_ascii=False, indent=2, allow_nan=False) + "\n", encoding="utf-8")
if not result["passed"]:
raise RuntimeError("Lab066 RF-сеанс невалиден; повтор запрещён")
return result
def locate_first_packet(tx: lab058.Cs8File, rx: lab058.Cs8File) -> dict:
"""Найти первый пакет после строгого verdict, не раскрывая границы декодеру."""
stride = MODE.samples_per_symbol
reference = tx.read(GUARD_SAMPLES, PACKET_SAMPLES).astype(np.complex64)
received = rx.read(0, rx.size).astype(np.complex64)
reference = reference[::stride] - np.mean(reference[::stride])
received = received[::stride] - np.mean(received[::stride])
correlation = signal.correlate(received, reference, mode="valid", method="fft")
coarse = int(np.argmax(abs(correlation))) * stride
full_reference = tx.read(GUARD_SAMPLES, PACKET_SAMPLES).astype(np.complex128)
full_reference -= np.mean(full_reference)
starts = range(max(0, coarse - 2 * stride), min(rx.size - PACKET_SAMPLES, coarse + 2 * stride) + 1)
scores = []
for start in starts:
values = rx.read(start, PACKET_SAMPLES).astype(np.complex128)
values -= np.mean(values)
scores.append(abs(np.vdot(full_reference, values)))
first_start = starts.start + int(np.argmax(scores))
return {
"first_packet_rx_start_sample": first_start,
"stream_rx_start_sample": first_start - GUARD_SAMPLES,
"coarse_first_packet_start_sample": coarse,
"method": "first known packet correlation after strict receiver verdict",
}
def physical_packet_diagnostics(tx: lab058.Cs8File, rx: lab058.Cs8File,
location: dict) -> dict:
"""Оценить 16 пакетов известным TX только после строгого решения."""
rows = []
stream_start = location["stream_rx_start_sample"]
for layout, frame in zip(validate_prepared()["layout"], plans()):
packet_index = layout["packet_index"]
tx_start = layout["start_sample"]
rx_start = stream_start + tx_start
transmitted = tx.read(tx_start, PACKET_SAMPLES)
received = rx.read(rx_start, PACKET_SAMPLES)
expected = 2.0 * frame.plan.frame_bits.astype(np.float64) - 1.0
metrics, _working = lab058.analyze_values(received, expected, MODE.symbol_rate)
channel, _arrays = lab058.channel_metrics(
transmitted, received, MODE.symbol_rate, metrics["oracle"]["cfo_hz"]
)
oracle = metrics["oracle"]["metrics"]
rows.append({
"packet_index": packet_index, "tx_start_sample": tx_start,
"rx_start_sample": rx_start,
"symbol_error_rate": oracle["errors"] / oracle["symbols"],
"symbol_rms_deviation": float(np.sqrt(
oracle["residual_power"] / oracle["matched_component_power"]
)),
"matched_component_power": oracle["matched_component_power"],
"residual_power": oracle["residual_power"],
"matched_residual_db": float(10 * np.log10(
oracle["matched_component_power"] / oracle["residual_power"]
)),
"band_gain_nonuniformity_p95_p05_db": channel["amplitude_ripple_p95_p05_db"],
})
return {
"method": "Lab058 oracle diagnostics per packet after strict verdict",
"rows": rows,
"comparison": {
"lab056_B_oracle_symbol_error_rate": 0.03495896,
"lab056_B_oracle_evm_rms": 0.845350,
"lab062_source": "data/processed/lab062/rf_analysis.json",
"scope": "Lab056 B and Lab062 are contextual comparisons, not identical estimands",
},
}
def summarize_analysis(result: dict) -> dict:
"""Свести строгие и физические результаты без повторного декодирования."""
legacy, t2 = result["run_a_legacy"], result["run_b_t2"]
legacy_set, t2_set = set(legacy["packet_indexes"]), set(t2["packet_indexes"])
layout = validate_prepared()["layout"]
stream_start = result["location_after_strict_runs"]["stream_rx_start_sample"]
packet_rows = []
for layout_row in layout:
index = layout_row["packet_index"]
nominal = stream_start + layout_row["start_sample"]
modes = {}
for label, strict, accepted in (
("legacy", legacy, index in legacy_set), ("t2", t2, index in t2_set)
):
candidates = [
row for row in strict["rows"]
if abs(row["absolute_refined"] - nominal) <= 64
]
best = max(candidates, key=lambda row: (
row["packet_output"], row["crc"], row["fec"], row["header"],
-abs(row["absolute_refined"] - nominal),
)) if candidates else None
modes[label] = {
"candidate_at_expected_packet": best is not None,
"header": accepted or bool(best and best["header"]),
"fec": accepted or bool(best and best["fec"]),
"crc": accepted or bool(best and best["crc"]),
"packet_output": accepted,
}
packet_rows.append({"packet_index": index, **modes})
physical_rows = result["physical_diagnostics"]["rows"]
matched = float(np.mean([row["matched_component_power"] for row in physical_rows]))
residual = float(np.mean([row["residual_power"] for row in physical_rows]))
physical = {
"symbol_error_rate": float(np.mean([row["symbol_error_rate"] for row in physical_rows])),
"rms_symbol_deviation": float(np.sqrt(np.mean([
row["symbol_rms_deviation"] ** 2 for row in physical_rows
]))),
"matched_component_power": matched,
"residual_power": residual,
"matched_residual_db": float(10 * np.log10(matched / residual)),
"band_gain_nonuniformity_p95_p05_db_median": float(np.median([
row["band_gain_nonuniformity_p95_p05_db"] for row in physical_rows
])),
"band_gain_nonuniformity_p95_p05_db_min": float(np.min([
row["band_gain_nonuniformity_p95_p05_db"] for row in physical_rows
])),
"band_gain_nonuniformity_p95_p05_db_max": float(np.max([
row["band_gain_nonuniformity_p95_p05_db"] for row in physical_rows
])),
}
lab056 = {
"symbol_error_rate": 0.03495896464646465,
"rms_symbol_deviation": 0.8453497751219741,
"matched_residual_db": 1.4648455366051558,
"band_gain_nonuniformity_db": 5.471381501203027,
}
lab062_result = json.loads(
(ROOT / "data/processed/lab062/rf_analysis.json").read_text(encoding="utf-8")
)["lab058_quality"]
lab062 = {
"symbol_error_rate": lab062_result["symbol_error_rate"],
"rms_symbol_deviation": lab062_result["evm_rms"],
"matched_residual_db": lab062_result["matched_residual_db"],
"band_gain_nonuniformity_db": lab062_result[
"band_gain_nonuniformity_p95_p05_db_median"
],
"capture_status": "RF_SESSION_INVALID_TX_UNDERRUN",
}
def differences(reference: dict) -> dict:
return {
"symbol_error_rate_absolute": (
physical["symbol_error_rate"] - reference["symbol_error_rate"]
),
"rms_symbol_deviation_absolute": (
physical["rms_symbol_deviation"] - reference["rms_symbol_deviation"]
),
"matched_residual_db": (
physical["matched_residual_db"] - reference["matched_residual_db"]
),
"band_gain_nonuniformity_db": (
physical["band_gain_nonuniformity_p95_p05_db_median"]
- reference["band_gain_nonuniformity_db"]
),
}
return {
"lab": "Lab066", "capture_valid": result["capture_valid"],
"legacy": {key: legacy[key] for key in (
"candidates", "header_pass", "fec_started", "fec_pass", "crc_started",
"crc_pass", "packet_output", "exact_payload_match", "packet_indexes",
)},
"t2": {key: t2[key] for key in (
"candidates", "header_pass", "fec_started", "fec_pass", "crc_started",
"crc_pass", "packet_output", "exact_payload_match", "packet_indexes",
)},
"passed_by_both": sorted(legacy_set & t2_set),
"passed_only_by_legacy": sorted(legacy_set - t2_set),
"passed_only_by_t2": sorted(t2_set - legacy_set),
"failed_by_both": sorted(set(range(1, PACKETS + 1)) - legacy_set - t2_set),
"packet_rows": packet_rows, "physical": physical,
"lab056_B": lab056, "difference_from_lab056_B": differences(lab056),
"lab062": lab062, "difference_from_lab062": differences(lab062),
"classification": "PARTIAL_PACKET_RECOVERY_NO_T2_GAIN",
"primary_result": (
"Аппаратно валидный Lab066 дал одинаковые 10/16 точных пакетов "
"в legacy и T2; физическое качество лучше Lab056 B и невалидной Lab062."
),
"recommended_next_single_step": (
"Отдельно разрешить офлайн-сравнение header-ошибок пакетов "
"1-3, 9, 15-16 с принятыми пакетами по сохранённому RX; новый TX не нужен."
),
}
def write_summary_outputs(result: dict) -> dict:
summary = summarize_analysis(result)
save_new(OUTPUT / "rf_summary.json", summary)
with (OUTPUT / "packet_comparison.csv").open("x", newline="", encoding="utf-8-sig") as stream:
writer = csv.writer(stream)
writer.writerow([
"packet_index", "legacy_header", "legacy_fec", "legacy_crc",
"legacy_packet_output", "t2_header", "t2_fec", "t2_crc", "t2_packet_output",
])
for row in summary["packet_rows"]:
writer.writerow([
row["packet_index"], row["legacy"]["header"], row["legacy"]["fec"],
row["legacy"]["crc"], row["legacy"]["packet_output"],
row["t2"]["header"], row["t2"]["fec"], row["t2"]["crc"],
row["t2"]["packet_output"],
])
return summary
def analyze_saved_capture() -> dict:
"""Строго обработать одну будущую RX-запись обоими режимами."""
metadata = validate_prepared()
capture = json.loads((RAW / "capture_result.json").read_text(encoding="utf-8"))
rx_path = RAW / "rx_stream.cs8"
if (
capture.get("lab") != "Lab066"
or capture.get("rf_tx_count") != 1
or capture.get("automatic_tx_repeats") != 0
or capture.get("point") != asdict(POINT)
or capture.get("parameters") != parameters()
or capture.get("tx_sha256") != metadata["tx_sha256"]
or capture.get("rx_sha256") != sha256(rx_path)
):
raise RuntimeError("Нет подтверждённой единственной RX-записи Lab066")
validity = lab064.capture_validity(capture)
if not validity["valid"]:
result = {
"lab": "Lab066", "stage": "STRICT_DUAL_OFFLINE_ANALYSIS",
"classification": "INVALID_CAPTURE", "capture_valid": False,
"capture_invalid_reasons": validity["invalid_reasons"],
"rf_tx_count": capture.get("rf_tx_count"), "automatic_tx_repeats": 0,
}
save_new(OUTPUT / "rf_result.json", result)
return result
legacy = decode("legacy", rx_path, diagnostics=True)
t2 = decode("t2", rx_path, diagnostics=True)
strict_runs_complete = (
legacy.get("candidate_overflow") == 0
and t2.get("candidate_overflow") == 0
and isinstance(legacy.get("rows"), list)
and isinstance(t2.get("rows"), list)
)
if not strict_runs_complete:
raise RuntimeError("Строгие legacy/T2 прогоны не завершены; oracle-диагностика запрещена")
tx = lab058.Cs8File(RAW / "tx_stream.cs8")
rx = lab058.Cs8File(rx_path)
location = locate_first_packet(tx, rx)
result = {
"lab": "Lab066", "stage": "STRICT_DUAL_OFFLINE_ANALYSIS",
"tx_sha256": metadata["tx_sha256"], "rx_sha256": capture["rx_sha256"],
"capture_valid": validity["valid"], "capture_invalid_reasons": validity["invalid_reasons"],
"run_a_legacy": legacy, "run_b_t2": t2,
"same_rx_capture": True, "fallback_between_modes": False,
"strict_runs_complete": True,
"location_after_strict_runs": location,
"physical_diagnostics_scope": "KNOWN_TX_ONLY_AFTER_COMPLETE_STRICT_RUNS",
"physical_diagnostics": physical_packet_diagnostics(tx, rx, location),
"comparison_targets": ["Lab056 B", "Lab062", "Lab066"],
}
save_new(OUTPUT / "rf_result.json", result)
return result
def summarize_saved_analysis() -> dict:
return write_summary_outputs(json.loads(
(OUTPUT / "rf_result.json").read_text(encoding="utf-8")
))
def run_functional_tests() -> None:
assert EXPECTED_TX_SAMPLES == 3_676_096
assert transfer_command("NUL", 100, transmit=True)[-7:-5] == ["-x", "20"]
assert "-t" not in transfer_command("NUL", 100)
try:
capture_once(authorization=False)
except PermissionError:
pass
else:
raise AssertionError("RF без отдельного разрешения")
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--stage",
choices=("prepare", "software", "preflight", "capture", "analyze", "summarize"),
required=True,
)
parser.add_argument("--authorize-one-rf", action="store_true")
arguments = parser.parse_args()
if arguments.stage == "prepare": result = prepare()
elif arguments.stage == "software": result = software_gate()
elif arguments.stage == "preflight": result = preflight()
elif arguments.stage == "capture": result = capture_once(authorization=arguments.authorize_one_rf)
elif arguments.stage == "analyze": result = analyze_saved_capture()
else: result = summarize_saved_analysis()
print(json.dumps(result, ensure_ascii=False, indent=2, allow_nan=False))
print("RF TX NOW = 0")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,906 @@
"""Lab067: офлайн-анализ отказов PHY-заголовка в сохранённой записи Lab066.
Строгий результат Lab066 загружается без изменений. Известный TX используется
только после этого результата для диагностического подсчёта ошибок.
Аппаратные команды и передача RF в этой лаборатории отсутствуют.
"""
from __future__ import annotations
import csv
import hashlib
import json
import math
from pathlib import Path
import struct
import sys
from typing import Any
if __package__ in (None, ""):
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
from experiments import lab053_packet_processing as packet_processing
from experiments import lab058_abab_symbol_quality as symbol_quality
from experiments import lab066_full_packet_rf_retest as lab066
from protocol import bpsk_carrier_tracking as carrier_tracking
ROOT = Path(__file__).resolve().parents[1]
RAW = ROOT / "data/raw/lab066"
LAB066 = ROOT / "data/processed/lab066"
OUTPUT = ROOT / "data/processed/lab067"
TX_PATH = RAW / "tx_stream.cs8"
RX_PATH = RAW / "rx_stream.cs8"
TX_SHA256 = "621b0bb8ec72bba4f522c79a5c77669c850740ea481270c4dcc2a7317819f199"
RX_SHA256 = "72ff7ddd8b30baa4a5c066361ca1f8dfa664f1da37f65c0c373b211ce6cf00f0"
RX_BYTES = 32_000_000
RX_SAMPLES = 16_000_000
SAMPLE_RATE_HZ = 8_000_000
SYMBOL_RATE = 500_000
SAMPLES_PER_SYMBOL = 16
PREAMBLE_SYMBOLS = 1280
HEADER_SYMBOLS = 144
HEADER_BITS = 48
HEADER_REPETITION = 3
POSTHEADER_SYMBOLS = 128
FAILED_PACKETS = {1, 2, 3, 9, 15, 16}
PASSED_PACKETS = set(range(1, 17)) - FAILED_PACKETS
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
for block in iter(lambda: stream.read(1024 * 1024), b""):
digest.update(block)
return digest.hexdigest()
def save_json(path: Path, value: Any) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
json.dumps(value, ensure_ascii=False, indent=2, allow_nan=False) + "\n",
encoding="utf-8",
)
def bits_text(bits: np.ndarray) -> str:
return "".join(str(int(value)) for value in np.asarray(bits).reshape(-1))
def finite(value: float) -> float | None:
return float(value) if np.isfinite(value) else None
def source_integrity() -> tuple[dict, dict, dict]:
"""Проверить неизменность Lab066 до любой oracle-диагностики."""
capture = json.loads((LAB066 / "capture_result.json").read_text(encoding="utf-8"))
strict = json.loads((LAB066 / "rf_result.json").read_text(encoding="utf-8"))
metadata = json.loads((LAB066 / "preparation.json").read_text(encoding="utf-8"))
tx_digest = sha256(TX_PATH)
rx_digest = sha256(RX_PATH)
integrity = {
"tx_path": str(TX_PATH.relative_to(ROOT)),
"tx_bytes": TX_PATH.stat().st_size,
"tx_samples": TX_PATH.stat().st_size // 2,
"tx_sha256": tx_digest,
"rx_path": str(RX_PATH.relative_to(ROOT)),
"rx_bytes": RX_PATH.stat().st_size,
"rx_samples": RX_PATH.stat().st_size // 2,
"rx_duration_seconds": (RX_PATH.stat().st_size // 2) / SAMPLE_RATE_HZ,
"rx_sha256": rx_digest,
"sample_rate_hz": SAMPLE_RATE_HZ,
}
if (
tx_digest != TX_SHA256
or rx_digest != RX_SHA256
or integrity["rx_bytes"] != RX_BYTES
or integrity["rx_samples"] != RX_SAMPLES
or metadata.get("tx_sha256") != TX_SHA256
or metadata.get("parameters", {}).get("sample_rate_hz") != SAMPLE_RATE_HZ
or capture.get("rx_sha256") != RX_SHA256
or capture.get("rf_tx_count") != 1
or capture.get("automatic_tx_repeats") != 0
or capture.get("passed") is not True
or strict.get("capture_valid") is not True
):
raise RuntimeError("Исходники или аппаратная валидность Lab066 не подтверждены")
for mode in ("run_a_legacy", "run_b_t2"):
result = strict[mode]
if (
result.get("header_pass") != 10
or result.get("packet_output") != 10
or result.get("exact_payload_match") != 10
or result.get("packet_indexes") != sorted(PASSED_PACKETS)
):
raise RuntimeError("Исторический строгий результат Lab066 изменился")
return integrity, metadata, strict
def extract_symbols(
received: symbol_quality.Cs8File,
frame_start: int,
symbol_count: int,
mode: str,
) -> dict:
"""Повторить штатные timing/carrier операции для известного окна пакета."""
processor = packet_processing.PacketProcessor(carrier_tracking_mode=mode)
length = (symbol_count + 42) * SAMPLES_PER_SYMBOL
segment = received.read(frame_start, length).astype(np.complex64)
matched = processor.filter(processor.shift(segment))
nominal = 16 * SAMPLES_PER_SYMBOL + processor.taps.size - 1
timing = int(processor.timing(matched, nominal, processor.expected))
initial = processor.carrier(
matched, nominal, timing, processor.bits, len(processor.bits)
)
symbols = matched[
nominal + timing:
nominal + timing + symbol_count * SAMPLES_PER_SYMBOL:
SAMPLES_PER_SYMBOL
].astype(np.complex128)
if symbols.size != symbol_count or initial["abs_h"] == 0:
raise RuntimeError("Не удалось извлечь диагностическое окно символов")
times = (np.arange(symbol_count, dtype=np.float64) + 0.5) / SYMBOL_RATE
if mode == "legacy":
corrected = symbols * np.exp(-2j * np.pi * initial["cfo_hz"] * times)
gain = initial["abs_h"] * np.exp(1j * initial["phase_rad"])
corrected /= gain
phase_trace = (
initial["phase_rad"] + 2 * np.pi * initial["cfo_hz"] * times
)
frequency_trace = np.full(symbol_count, initial["cfo_hz"], dtype=float)
detector_error = np.angle(corrected * np.where(corrected.real >= 0, 1, -1))
estimate = {
"frequency_hz": float(initial["cfo_hz"]),
"gain": complex(gain),
"phase_fit_rmse_rad": None,
"squared_coherence": None,
}
else:
estimate_value = carrier_tracking.estimate_p3(
symbols[:PREAMBLE_SYMBOLS], processor.expected, SYMBOL_RATE
)
tracked = carrier_tracking.track_t2(
symbols, SYMBOL_RATE, estimate_value, start_index=PREAMBLE_SYMBOLS
)
corrected = tracked.corrected.copy()
phase_trace = tracked.phase_rad.copy()
frequency_trace = tracked.frequency_hz.copy()
detector_error = tracked.detector_error_rad.copy()
estimate = {
"frequency_hz": float(estimate_value.frequency_hz),
"gain": complex(estimate_value.gain),
"phase_fit_rmse_rad": float(estimate_value.phase_fit_rmse_rad),
"squared_coherence": float(estimate_value.squared_coherence),
}
return {
"corrected": corrected,
"raw_symbols": symbols,
"matched": matched,
"hard_bits": (corrected.real >= 0).astype(np.uint8),
"timing_samples": timing,
"timing_fraction": timing / SAMPLES_PER_SYMBOL,
"nominal": nominal,
"sample_positions": frame_start + nominal + timing + np.arange(symbol_count) * SAMPLES_PER_SYMBOL,
"initial": estimate,
"phase_trace": phase_trace,
"frequency_trace": frequency_trace,
"detector_error": detector_error,
}
def reference_sync_diagnostic(extracted: dict, expected_bits: np.ndarray) -> dict:
"""Oracle-проверка timing/CFO после штатного результата, без влияния на него."""
expected = 2.0 * np.asarray(expected_bits, dtype=np.float64) - 1.0
indexes = np.arange(len(expected), dtype=np.int64)
candidates = []
for offset in range(-SAMPLES_PER_SYMBOL // 2, SAMPLES_PER_SYMBOL // 2 + 1):
start = extracted["nominal"] + offset
symbols = extracted["matched"][
start:start + len(expected) * SAMPLES_PER_SYMBOL:SAMPLES_PER_SYMBOL
].astype(np.complex128)
if len(symbols) != len(expected):
continue
frequency, gain, coherence = symbol_quality.fit_cfo_gain(
symbols, expected, indexes, SYMBOL_RATE, len(expected)
)
candidates.append((coherence, offset, frequency, gain))
coherence, timing, frequency, gain = max(candidates, key=lambda item: item[0])
return {
"scope": "KNOWN_BITS_AFTER_STRICT_VERDICT",
"timing_offset_samples": int(timing),
"timing_fraction": timing / SAMPLES_PER_SYMBOL,
"frequency_hz": float(frequency),
"gain_real": float(gain.real),
"gain_imag": float(gain.imag),
"coherence": float(coherence),
}
def physical_metrics(extracted: dict, expected_bits: np.ndarray, selected: slice) -> dict:
expected = 2.0 * np.asarray(expected_bits[selected], dtype=np.float64) - 1.0
raw = extracted["raw_symbols"][selected]
indexes = np.arange(len(extracted["raw_symbols"]), dtype=np.float64)[selected]
frequency = extracted["initial"]["frequency_hz"]
times = (indexes + 0.5) / SYMBOL_RATE
derotated = raw * np.exp(-2j * np.pi * frequency * times)
gain = complex(extracted["initial"]["gain"])
predicted = gain * expected
residual = derotated - predicted
matched_power = float(np.mean(abs(predicted) ** 2))
residual_power = float(np.mean(abs(residual) ** 2))
normalized = derotated / gain
errors = int(np.count_nonzero((normalized.real >= 0) != (expected > 0)))
correlation = float(
abs(np.vdot(expected, raw))
/ math.sqrt(float(np.vdot(expected, expected).real * np.vdot(raw, raw).real) + 1e-30)
)
return {
"symbols": int(len(expected)),
"errors": errors,
"error_rate": errors / len(expected),
"correlation": correlation,
"matched_component_power": matched_power,
"residual_power": residual_power,
"matched_residual_db": finite(10 * np.log10(matched_power / residual_power)),
"rms_symbol_deviation": float(np.sqrt(residual_power / matched_power)),
}
def header_diagnostics(received_soft: np.ndarray, expected_bits: np.ndarray) -> dict:
soft = np.asarray(received_soft[:HEADER_SYMBOLS], dtype=np.float64)
raw = (soft >= 0.0).astype(np.uint8)
expected = np.asarray(expected_bits[:HEADER_SYMBOLS], dtype=np.uint8)
raw_groups = raw.reshape(HEADER_BITS, HEADER_REPETITION)
expected_groups = expected.reshape(HEADER_BITS, HEADER_REPETITION)
voted = (np.sum(soft.reshape(HEADER_BITS, HEADER_REPETITION), axis=1) >= 0.0).astype(np.uint8)
expected_voted = expected_groups[:, 0]
fields = lab066.phy.lab045.lab044.bits_to_bytes(voted)
magic, version, length, checksum = struct.unpack(
lab066.phy.lab045.PHY_HEADER_FIELDS_FORMAT, fields
)
decoded = lab066.phy.lab045.decode_phy_header_soft(soft)
field_errors = {
"magic": int(np.count_nonzero(voted[:16] != expected_voted[:16])),
"version": int(np.count_nonzero(voted[16:24] != expected_voted[16:24])),
"length": int(np.count_nonzero(voted[24:40] != expected_voted[24:40])),
"checksum": int(np.count_nonzero(voted[40:48] != expected_voted[40:48])),
}
return {
"expected_header_bits": bits_text(expected),
"received_raw_header_bits": bits_text(raw),
"raw_header_errors": int(np.count_nonzero(raw != expected)),
"copy_errors": [
int(np.count_nonzero(raw_groups[:, index] != expected_groups[:, index]))
for index in range(HEADER_REPETITION)
],
"voted_header_bits": bits_text(voted),
"expected_voted_bits": bits_text(expected_voted),
"voted_header_errors": int(np.count_nonzero(voted != expected_voted)),
"magic_errors": field_errors["magic"],
"version_errors": field_errors["version"],
"length_errors": field_errors["length"],
"checksum_errors": field_errors["checksum"],
"decoded_magic": magic,
"decoded_version": version,
"decoded_length": length,
"decoded_checksum": checksum,
"accepted": bool(decoded["passed"]),
"reason": decoded["reason"],
"raw_error_positions": np.flatnonzero(raw != expected).astype(int).tolist(),
"voted_error_positions": np.flatnonzero(voted != expected_voted).astype(int).tolist(),
}
def gap_metrics(received: symbol_quality.Cs8File, start: int, count: int) -> dict:
values = received.read(start, count).astype(np.complex128)
mean = np.mean(values)
centered = values - mean
edge = min(count // 4, 8000)
first_power = float(np.mean(abs(centered[:edge]) ** 2))
middle_start = max(edge, count // 2 - edge // 2)
middle_power = float(np.mean(abs(centered[middle_start:middle_start + edge]) ** 2))
tail_ratio_db = float(10 * np.log10(max(first_power, 1e-30) / max(middle_power, 1e-30)))
return {
"length_samples": count,
"duration_seconds": count / SAMPLE_RATE_HZ,
"background_ac_rms": float(np.sqrt(np.mean(abs(centered) ** 2))),
"mean_i": float(mean.real),
"mean_q": float(mean.imag),
"residual_energy_mean": float(np.mean(abs(centered) ** 2)),
"leading_edge_to_middle_db": tail_ratio_db,
"previous_waveform_tail_detected": bool(tail_ratio_db > 3.0),
}
def strict_candidate_for_packet(rows: list[dict], expected: int) -> dict | None:
candidates = [row for row in rows if abs(int(row["absolute_refined"]) - expected) <= 64]
if not candidates:
return None
return min(
candidates,
key=lambda row: (
abs(int(row["absolute_refined"]) - expected),
int(row["absolute_refined"]),
),
)
def candidate_analysis(strict: dict, expected_starts: list[int]) -> tuple[dict, list[dict]]:
rows = strict["run_a_legacy"]["rows"]
packet_samples = lab066.PACKET_SAMPLES
gap_intervals = []
metadata = json.loads((LAB066 / "preparation.json").read_text(encoding="utf-8"))
stream_start = strict["location_after_strict_runs"]["stream_rx_start_sample"]
for layout in metadata["layout"][:-1]:
low = stream_start + layout["following_gap_start_sample"]
gap_intervals.append((low, low + layout["following_gap_samples"]))
output_rows = []
true = repeated = gaps = unrelated = 0
true_positions = set()
per_packet = {index: 0 for index in range(1, 17)}
for number, row in enumerate(rows, start=1):
position = int(row["absolute_refined"])
distances = np.abs(np.asarray(expected_starts, dtype=np.int64) - position)
nearest_index = int(np.argmin(distances)) + 1
delta = position - expected_starts[nearest_index - 1]
in_gap = any(low <= position < high for low, high in gap_intervals)
if abs(delta) <= 64:
category = "TRUE_PREAMBLE_POSITION"
true += 1
true_positions.add((nearest_index, position))
elif -64 <= delta < packet_samples:
category = "REPEATED_PRBS_LOCAL_MAXIMUM"
repeated += 1
elif in_gap:
category = "ZERO_GAP"
gaps += 1
else:
category = "UNRELATED"
unrelated += 1
if category in {"TRUE_PREAMBLE_POSITION", "REPEATED_PRBS_LOCAL_MAXIMUM"}:
per_packet[nearest_index] += 1
output_rows.append({
"candidate_number": number,
"position": position,
"nearest_packet": nearest_index,
"difference_samples": delta,
"category": category,
"strict_reason": row["reason"],
})
summary = {
"total_strict_candidates": len(rows),
"true_preamble_position_checks": true,
"unique_true_preamble_positions": len(true_positions),
"duplicate_true_position_checks": true - len(true_positions),
"repeated_prbs_local_maxima": repeated,
"zero_gap_candidates": gaps,
"unrelated_candidates": unrelated,
"checks_associated_with_each_real_preamble": per_packet,
"detector_statistics": strict["run_a_legacy"]["detector_statistics"],
"candidate_processing_state": "NEW_PACKET_MEASURE_AND_INDEPENDENT_DECODE_PER_CANDIDATE",
"persistent_state_between_rejected_candidates": False,
"accepted_until_changes_only_after_crc_pass": True,
}
return summary, output_rows
def distribution(rows: list[dict], packets: set[int], key: str) -> dict:
values = np.asarray([row[key] for row in rows if row["packet"] in packets], dtype=float)
return {
"minimum": float(np.min(values)),
"median": float(np.median(values)),
"maximum": float(np.max(values)),
"values": {str(row["packet"]): row[key] for row in rows if row["packet"] in packets},
}
def assign_classifications(rows: list[dict]) -> None:
passed = [row for row in rows if row["packet"] in PASSED_PACKETS]
limits = {
"preamble_errors_max": max(row["preamble_errors"] for row in passed),
"preamble_mr_p10": float(np.percentile([row["preamble_matched_residual_db"] for row in passed], 10)),
"preamble_rms_p90": float(np.percentile([row["preamble_rms_symbol_deviation"] for row in passed], 90)),
"correlation_p10": float(np.percentile([row["preamble_correlation"] for row in passed], 10)),
}
for row in rows:
if row["packet"] in PASSED_PACKETS:
row["classification"] = "PASSED"
continue
physical_bad = sum((
row["preamble_errors"] > limits["preamble_errors_max"],
row["preamble_matched_residual_db"] < limits["preamble_mr_p10"],
row["preamble_rms_symbol_deviation"] > limits["preamble_rms_p90"],
row["preamble_correlation"] < limits["correlation_p10"],
))
if row["preamble_errors"] > limits["preamble_errors_max"]:
row["classification"] = "PREAMBLE_ALREADY_BAD"
elif physical_bad >= 2:
row["classification"] = "LOCAL_RF_DEGRADATION"
elif row["header_voted_errors"] > 0:
row["classification"] = "HEADER_SPECIFIC_FAILURE"
else:
row["classification"] = "NOT_LOCALIZED"
def group_summary(rows: list[dict]) -> dict:
groups = {"START": range(1, 5), "MIDDLE_1": range(5, 9), "MIDDLE_2": range(9, 13), "END": range(13, 17)}
result = {}
for name, indexes in groups.items():
selected = [row for row in rows if row["packet"] in indexes]
result[name] = {
"packets": list(indexes),
"preamble_error_rate": float(np.mean([row["preamble_error_rate"] for row in selected])),
"header_error_rate": float(np.mean([row["header_raw_errors"] / HEADER_SYMBOLS for row in selected])),
"matched_power": float(np.mean([row["local_matched_power"] for row in selected])),
"residual_power": float(np.mean([row["local_residual_power"] for row in selected])),
"matched_residual_db": float(10 * np.log10(
np.mean([row["local_matched_power"] for row in selected])
/ np.mean([row["local_residual_power"] for row in selected])
)),
"initial_frequency_offset_hz": float(np.mean([row["legacy_initial_frequency_hz"] for row in selected])),
"timing_offset_samples": float(np.mean([row["timing_offset_samples"] for row in selected])),
"background_ac_rms": float(np.mean([row["gap_background_ac_rms"] for row in selected])),
}
return result
def make_plots(rows: list[dict], transitions: dict[int, dict], candidates: dict) -> list[str]:
OUTPUT.mkdir(parents=True, exist_ok=True)
packets = [row["packet"] for row in rows]
colors = ["C3" if packet in FAILED_PACKETS else "C0" for packet in packets]
plots = []
def save(name: str) -> None:
plt.tight_layout()
plt.savefig(OUTPUT / name, dpi=160)
plt.close()
plots.append(name)
plt.figure(figsize=(10, 4.5))
plt.bar(packets, [row["preamble_errors"] for row in rows], color=colors)
plt.xticks(packets); plt.xlabel("Пакет"); plt.ylabel("Ошибки преамбулы, бит")
plt.grid(axis="y", alpha=.25); save("preamble_errors_by_packet.png")
plt.figure(figsize=(10, 4.5))
x = np.arange(1, 17)
plt.bar(x - .18, [row["header_raw_errors"] for row in rows], width=.36, label="raw")
plt.bar(x + .18, [row["header_voted_errors"] for row in rows], width=.36, label="voted", color=colors)
plt.xticks(x); plt.xlabel("Пакет"); plt.ylabel("Ошибки PHY header, бит"); plt.legend()
plt.grid(axis="y", alpha=.25); save("header_errors_by_packet.png")
figure, axes = plt.subplots(3, 1, figsize=(10, 8), sharex=True)
axes[0].bar(packets, [row["local_matched_power"] for row in rows], color=colors)
axes[0].set_ylabel("Matched power")
axes[1].bar(packets, [row["local_residual_power"] for row in rows], color=colors)
axes[1].set_ylabel("Residual power")
axes[2].bar(packets, [row["local_matched_residual_db"] for row in rows], color=colors)
axes[2].set_ylabel("Matched/residual, dB"); axes[2].set_xlabel("Пакет"); axes[2].set_xticks(packets)
for axis in axes: axis.grid(axis="y", alpha=.25)
save("local_signal_quality_by_packet.png")
matrix = np.zeros((16, HEADER_SYMBOLS), dtype=np.uint8)
for row in rows:
for position in row["header_raw_error_positions"]:
matrix[row["packet"] - 1, position] = 1
plt.figure(figsize=(13, 5))
plt.imshow(matrix, aspect="auto", interpolation="nearest", cmap="Reds")
plt.xlabel("Позиция защищённого PHY header, 0...143"); plt.ylabel("Пакет")
plt.yticks(np.arange(16), np.arange(1, 17)); plt.colorbar(label="Ошибка")
save("header_error_position_map.png")
representative = [4, 1, 14, 16]
figure, axes = plt.subplots(len(representative), 3, figsize=(13, 10), sharex=True)
for line, packet in enumerate(representative):
values = transitions[packet]
x = np.arange(-128, HEADER_SYMBOLS + 128)
axes[line, 0].plot(x, values["corrected_real"], lw=.7)
axes[line, 0].scatter(x[values["errors"]], np.asarray(values["corrected_real"])[values["errors"]], s=12, color="red")
axes[line, 1].plot(x, values["corrected_imag"], lw=.7)
axes[line, 2].plot(x, values["phase_error_rad"], lw=.7)
for axis in axes[line]:
axis.axvline(0, color="black", lw=.8); axis.axvline(HEADER_SYMBOLS, color="black", lw=.8)
axis.grid(alpha=.2)
axes[line, 0].set_ylabel(f"P{packet}")
axes[0, 0].set_title("Re, ошибки красным"); axes[0, 1].set_title("Im"); axes[0, 2].set_title("Фазовая ошибка, rad")
for axis in axes[-1]: axis.set_xlabel("Символ относительно начала header")
save("preamble_header_transition.png")
figure, axes = plt.subplots(2, 1, figsize=(10, 6), sharex=True)
axes[0].bar(packets, [row["timing_offset_samples"] for row in rows], color=colors)
axes[0].set_ylabel("Timing, samples")
axes[1].plot(packets, [row["legacy_initial_frequency_hz"] for row in rows], "o-", label="legacy")
axes[1].plot(packets, [row["t2_initial_frequency_hz"] for row in rows], "s-", label="T2/P3")
axes[1].set_ylabel("CFO, Hz"); axes[1].set_xlabel("Пакет"); axes[1].legend()
for axis in axes: axis.grid(alpha=.25)
save("timing_and_cfo_by_packet.png")
plt.figure(figsize=(10, 4.5))
plt.bar(packets, [row["gap_background_ac_rms"] for row in rows], color=colors)
plt.xlabel("Пакет"); plt.ylabel("AC RMS перед пакетом"); plt.xticks(packets); plt.grid(axis="y", alpha=.25)
save("gap_background_by_packet.png")
per_packet = candidates["checks_associated_with_each_real_preamble"]
plt.figure(figsize=(10, 4.5))
plt.bar(packets, [per_packet[str(packet)] if str(packet) in per_packet else per_packet[packet] for packet in packets], color=colors)
plt.xlabel("Пакет"); plt.ylabel("Строгие проверки кандидатов"); plt.xticks(packets); plt.grid(axis="y", alpha=.25)
save("candidate_checks_by_packet.png")
return plots
def write_csvs(rows: list[dict], candidate_rows: list[dict], bit_rows: list[dict], transition_rows: list[dict]) -> None:
main_fields = [
"packet", "strict_result", "candidate_position", "expected_packet_position", "candidate_difference_samples",
"preamble_errors", "preamble_error_rate", "preamble_correlation", "header_raw_errors", "header_voted_errors",
"header_copy_1_errors", "header_copy_2_errors", "header_copy_3_errors", "magic_errors", "version_errors",
"length_errors", "checksum_errors", "expected_header_bits", "received_raw_header_bits", "voted_header_bits",
"header_accepted", "header_reason", "legacy_header_bits", "t2_header_bits",
"legacy_initial_frequency_hz", "t2_initial_frequency_hz", "reference_frequency_hz",
"legacy_frequency_error_vs_reference_hz", "initial_phase_error_rad", "timing_offset_samples", "fractional_timing_offset",
"reference_timing_offset_samples", "reference_fractional_timing_offset", "local_matched_power", "local_residual_power",
"local_matched_residual_db", "rms_symbol_deviation", "legacy_t2_header_differences", "classification",
]
with (OUTPUT / "header_packet_comparison.csv").open("w", newline="", encoding="utf-8-sig") as stream:
writer = csv.DictWriter(stream, fieldnames=main_fields, extrasaction="ignore")
writer.writeheader(); writer.writerows(rows)
for name, values in (
("header_bit_errors.csv", bit_rows),
("candidate_analysis.csv", candidate_rows),
("transition_metrics.csv", transition_rows),
):
with (OUTPUT / name).open("w", newline="", encoding="utf-8-sig") as stream:
writer = csv.DictWriter(stream, fieldnames=list(values[0]))
writer.writeheader(); writer.writerows(values)
def analyze() -> dict:
integrity, metadata, strict = source_integrity()
received = symbol_quality.Cs8File(RX_PATH)
stream_start = int(strict["location_after_strict_runs"]["stream_rx_start_sample"])
expected_starts = [stream_start + int(item["start_sample"]) for item in metadata["layout"]]
plans = lab066.plans()
packet_rows: list[dict] = []
bit_rows: list[dict] = []
transition_rows: list[dict] = []
transitions: dict[int, dict] = {}
tx_headers = []
for packet, (layout, frame, rx_start) in enumerate(zip(metadata["layout"], plans, expected_starts), start=1):
expected_frame = frame.plan.frame_bits.astype(np.uint8)
expected_header = frame.plan.phy_header_bits.astype(np.uint8)
tx_headers.append(expected_header)
legacy = extract_symbols(received, rx_start, PREAMBLE_SYMBOLS + HEADER_SYMBOLS, "legacy")
t2 = extract_symbols(received, rx_start, PREAMBLE_SYMBOLS + HEADER_SYMBOLS, "t2")
transition = extract_symbols(
received, rx_start, PREAMBLE_SYMBOLS + HEADER_SYMBOLS + POSTHEADER_SYMBOLS, "legacy"
)
preamble = physical_metrics(legacy, expected_frame, slice(0, PREAMBLE_SYMBOLS))
local = physical_metrics(legacy, expected_frame, slice(PREAMBLE_SYMBOLS - 128, PREAMBLE_SYMBOLS + HEADER_SYMBOLS))
reference = reference_sync_diagnostic(
legacy, expected_frame[:PREAMBLE_SYMBOLS + HEADER_SYMBOLS]
)
header_legacy = header_diagnostics(
legacy["corrected"].real[PREAMBLE_SYMBOLS:], expected_header
)
header_t2 = header_diagnostics(
t2["corrected"].real[PREAMBLE_SYMBOLS:], expected_header
)
legacy_t2_differences = int(np.count_nonzero(
legacy["hard_bits"][PREAMBLE_SYMBOLS:] != t2["hard_bits"][PREAMBLE_SYMBOLS:]
))
strict_row = strict_candidate_for_packet(strict["run_a_legacy"]["rows"], rx_start)
candidate_position = int(strict_row["absolute_refined"]) if strict_row else None
if packet == 1:
preceding_start = stream_start
preceding_count = lab066.GUARD_SAMPLES
else:
preceding_count = lab066.INTER_PACKET_GAP_SAMPLES
preceding_start = rx_start - preceding_count
gap = gap_metrics(received, preceding_start, preceding_count)
trailing = gap_metrics(received, rx_start + lab066.PACKET_SAMPLES, lab066.GUARD_SAMPLES) if packet == 16 else None
row = {
"packet": packet,
"strict_result": "PASS" if packet in PASSED_PACKETS else "HEADER_FAIL",
"candidate_position": candidate_position,
"expected_packet_position": rx_start,
"candidate_difference_samples": None if candidate_position is None else candidate_position - rx_start,
"timing_offset_samples": legacy["timing_samples"],
"fractional_timing_offset": legacy["timing_fraction"],
"timing_metric_confidence": None,
"preamble_symbols": preamble["symbols"],
"preamble_errors": preamble["errors"],
"preamble_error_rate": preamble["error_rate"],
"preamble_correlation": preamble["correlation"],
"preamble_rms_symbol_deviation": preamble["rms_symbol_deviation"],
"preamble_matched_power": preamble["matched_component_power"],
"preamble_residual_power": preamble["residual_power"],
"preamble_matched_residual_db": preamble["matched_residual_db"],
"legacy_initial_frequency_hz": legacy["initial"]["frequency_hz"],
"t2_initial_frequency_hz": t2["initial"]["frequency_hz"],
"initial_phase_error_rad": float(np.angle(legacy["initial"]["gain"])),
"frequency_difference_legacy_t2_hz": legacy["initial"]["frequency_hz"] - t2["initial"]["frequency_hz"],
"reference_frequency_hz": reference["frequency_hz"],
"legacy_frequency_error_vs_reference_hz": legacy["initial"]["frequency_hz"] - reference["frequency_hz"],
"reference_timing_offset_samples": reference["timing_offset_samples"],
"reference_fractional_timing_offset": reference["timing_fraction"],
"reference_coherence": reference["coherence"],
"legacy_expected_phase_drift_preamble_rad": float(2 * np.pi * legacy["initial"]["frequency_hz"] * PREAMBLE_SYMBOLS / SYMBOL_RATE),
"legacy_expected_phase_drift_header_rad": float(2 * np.pi * legacy["initial"]["frequency_hz"] * HEADER_SYMBOLS / SYMBOL_RATE),
"legacy_expected_phase_drift_full_packet_rad": float(2 * np.pi * legacy["initial"]["frequency_hz"] * len(expected_frame) / SYMBOL_RATE),
"phase_error_from_cfo_mismatch_over_header_rad": float(
2 * np.pi * (legacy["initial"]["frequency_hz"] - reference["frequency_hz"])
* HEADER_SYMBOLS / SYMBOL_RATE
),
"expected_header_bits": header_legacy["expected_header_bits"],
"received_raw_header_bits": header_legacy["received_raw_header_bits"],
"header_raw_errors": header_legacy["raw_header_errors"],
"header_copy_1_errors": header_legacy["copy_errors"][0],
"header_copy_2_errors": header_legacy["copy_errors"][1],
"header_copy_3_errors": header_legacy["copy_errors"][2],
"voted_header_bits": header_legacy["voted_header_bits"],
"header_voted_errors": header_legacy["voted_header_errors"],
"magic_errors": header_legacy["magic_errors"],
"version_errors": header_legacy["version_errors"],
"length_errors": header_legacy["length_errors"],
"checksum_errors": header_legacy["checksum_errors"],
"decoded_magic": header_legacy["decoded_magic"],
"decoded_length": header_legacy["decoded_length"],
"header_accepted": header_legacy["accepted"],
"header_reason": header_legacy["reason"],
"header_raw_error_positions": header_legacy["raw_error_positions"],
"header_voted_error_positions": header_legacy["voted_error_positions"],
"legacy_header_bits": header_legacy["received_raw_header_bits"],
"t2_header_bits": header_t2["received_raw_header_bits"],
"legacy_t2_header_differences": legacy_t2_differences,
"local_window": "last 128 preamble symbols plus complete 144-symbol header",
"local_matched_power": local["matched_component_power"],
"local_residual_power": local["residual_power"],
"local_matched_residual_db": local["matched_residual_db"],
"rms_symbol_deviation": local["rms_symbol_deviation"],
"header_error_rate": header_legacy["raw_header_errors"] / HEADER_SYMBOLS,
"preceding_zero_gap_length": gap["length_samples"],
"gap_background_ac_rms": gap["background_ac_rms"],
"gap_mean_i": gap["mean_i"], "gap_mean_q": gap["mean_q"],
"gap_residual_energy": gap["residual_energy_mean"],
"previous_waveform_tail_detected": gap["previous_waveform_tail_detected"],
"gap_leading_edge_to_middle_db": gap["leading_edge_to_middle_db"],
"trailing_guard_packet_16": trailing,
}
packet_rows.append(row)
for position in range(HEADER_SYMBOLS):
bit_rows.append({
"packet": packet, "protected_bit_position": position,
"field_bit_position": position // HEADER_REPETITION,
"copy": position % HEADER_REPETITION + 1,
"expected": int(expected_header[position]),
"legacy_received": int(legacy["hard_bits"][PREAMBLE_SYMBOLS + position]),
"t2_received": int(t2["hard_bits"][PREAMBLE_SYMBOLS + position]),
"legacy_error": int(position in header_legacy["raw_error_positions"]),
"t2_error": int(position in header_t2["raw_error_positions"]),
})
start = PREAMBLE_SYMBOLS - 128
stop = PREAMBLE_SYMBOLS + HEADER_SYMBOLS + 128
corrected = transition["corrected"][start:stop]
truth = 2.0 * expected_frame[start:stop] - 1.0
errors = np.flatnonzero((corrected.real >= 0) != (truth > 0))
phase_error = np.angle(corrected * truth)
transitions[packet] = {
"corrected_real": corrected.real.astype(float).tolist(),
"corrected_imag": corrected.imag.astype(float).tolist(),
"magnitude": abs(corrected).astype(float).tolist(),
"phase_error_rad": phase_error.astype(float).tolist(),
"hard_decisions": (corrected.real >= 0).astype(int).tolist(),
"errors": errors.astype(int).tolist(),
"sample_positions": transition["sample_positions"][start:stop].astype(int).tolist(),
}
regions = {"preamble_tail": slice(0, 128), "header": slice(128, 128 + HEADER_SYMBOLS), "postheader": slice(128 + HEADER_SYMBOLS, None)}
for name, selected in regions.items():
values = corrected[selected]
local_truth = truth[selected]
transition_rows.append({
"packet": packet, "region": name,
"symbols": len(values),
"decision_errors": int(np.count_nonzero((values.real >= 0) != (local_truth > 0))),
"magnitude_median": float(np.median(abs(values))),
"magnitude_minimum": float(np.min(abs(values))),
"phase_error_rms_rad": float(np.sqrt(np.mean(np.angle(values * local_truth) ** 2))),
"imaginary_rms": float(np.sqrt(np.mean(values.imag ** 2))),
"timing_offset_samples": transition["timing_samples"],
})
assign_classifications(packet_rows)
candidate_summary, candidate_rows = candidate_analysis(strict, expected_starts)
tx_header_identical = all(np.array_equal(tx_headers[0], item) for item in tx_headers[1:])
tx_header_decodes = [lab066.phy.lab045.decode_phy_header_soft(2.0 * item - 1.0) for item in tx_headers]
software_current = {
mode: lab066.decode(mode, TX_PATH, diagnostics=False)
for mode in ("legacy", "t2")
}
software_16_of_16 = all(
result["packet_output"] == 16 and result["exact_payload_match"] == 16
for result in software_current.values()
)
groups = group_summary(packet_rows)
distributions = {
label: {
metric: distribution(packet_rows, packets, metric)
for metric in (
"preamble_errors", "preamble_error_rate", "preamble_correlation",
"preamble_rms_symbol_deviation", "preamble_matched_power",
"preamble_residual_power", "preamble_matched_residual_db",
"header_raw_errors", "header_voted_errors",
)
}
for label, packets in (("passed", PASSED_PACKETS), ("failed", FAILED_PACKETS))
}
failed_classes = {str(row["packet"]): row["classification"] for row in packet_rows if row["packet"] in FAILED_PACKETS}
passed_local_residual = float(np.median([
row["local_residual_power"] for row in packet_rows if row["packet"] in PASSED_PACKETS
]))
failed_local_residual = float(np.median([
row["local_residual_power"] for row in packet_rows if row["packet"] in FAILED_PACKETS
]))
passed_local_ratio = float(np.median([
row["local_matched_residual_db"] for row in packet_rows if row["packet"] in PASSED_PACKETS
]))
failed_local_ratio = float(np.median([
row["local_matched_residual_db"] for row in packet_rows if row["packet"] in FAILED_PACKETS
]))
failed_error_positions = [
position for row in packet_rows if row["packet"] in FAILED_PACKETS
for position in row["header_raw_error_positions"]
]
repeated_failed_positions = sorted({
position for position in failed_error_positions
if failed_error_positions.count(position) > 1
})
diagnostic_strict_agreement = all(
row["header_accepted"] == (row["strict_result"] == "PASS")
for row in packet_rows
)
timing_agreement = all(
row["timing_offset_samples"] == row["reference_timing_offset_samples"]
for row in packet_rows
)
cfo_scale_small = max(abs(row["phase_error_from_cfo_mismatch_over_header_rad"])
for row in packet_rows) < 0.1
candidate_state_independent = (
candidate_summary["persistent_state_between_rejected_candidates"] is False
and candidate_summary["accepted_until_changes_only_after_crc_pass"] is True
)
local_quality_conditions = {
"tx_and_software_valid": bool(
tx_header_identical and all(item["passed"] for item in tx_header_decodes)
and software_16_of_16
),
"strict_header_reproduced": diagnostic_strict_agreement,
"no_common_failed_error_position": not repeated_failed_positions,
"failed_local_residual_at_least_20_percent_higher": (
failed_local_residual > 1.2 * passed_local_residual
),
"failed_local_matched_residual_at_least_1_db_lower": (
failed_local_ratio < passed_local_ratio - 1.0
),
"receiver_and_oracle_timing_agree": timing_agreement,
"cfo_mismatch_phase_scale_below_0p1_rad": cfo_scale_small,
"candidate_state_independent": candidate_state_independent,
}
root_cause = (
"LOCAL_RF_QUALITY" if all(local_quality_conditions.values())
else "NOT_LOCALIZED"
)
small_fix_evidence = {
"receiver_header_logic": bool(not diagnostic_strict_agreement),
"timing_transition": bool(not timing_agreement and not cfo_scale_small),
"carrier_transition": bool(not cfo_scale_small and timing_agreement),
"candidate_state_handling": bool(not candidate_state_independent),
}
one_small_fix = any(small_fix_evidence.values())
plots = make_plots(packet_rows, transitions, candidate_summary)
write_csvs(packet_rows, candidate_rows, bit_rows, transition_rows)
save_json(OUTPUT / "transition_symbols.json", transitions)
summary = {
"lab": "Lab067",
"mode": "OFFLINE_DIAGNOSTIC_ONLY",
"rf_tx": 0,
"hardware_accessed": False,
"lab066_integrity": integrity,
"historical_strict_result_unchanged": {
"legacy": "10/16", "t2": "10/16",
"passed_packets": sorted(PASSED_PACKETS), "failed_packets": sorted(FAILED_PACKETS),
},
"packet_positions_verified": len(expected_starts) == 16 and all(
row["candidate_difference_samples"] is not None and abs(row["candidate_difference_samples"]) <= 64
for row in packet_rows
),
"packet_rows": packet_rows,
"passed_failed_distributions": distributions,
"start_middle_end_groups": groups,
"failed_packet_classifications": failed_classes,
"header_error_position_analysis": {
"failed_raw_error_count": len(failed_error_positions),
"positions_repeated_between_failed_packets": repeated_failed_positions,
"systematic_common_position_found": bool(repeated_failed_positions),
"interpretation": "Позиции ошибок различаются; общей битовой позиции отказа нет.",
},
"local_quality_evidence": {
"passed_local_residual_power_median": passed_local_residual,
"failed_local_residual_power_median": failed_local_residual,
"passed_local_matched_residual_db_median": passed_local_ratio,
"failed_local_matched_residual_db_median": failed_local_ratio,
"failed_minus_passed_residual_power_median": failed_local_residual - passed_local_residual,
"failed_minus_passed_matched_residual_db_median": failed_local_ratio - passed_local_ratio,
"scope": "last 128 preamble symbols plus complete header",
"decision_conditions": local_quality_conditions,
},
"legacy_t2_header_difference": (
"NONE" if all(row["legacy_t2_header_differences"] == 0 for row in packet_rows)
else "PRESENT"
),
"t2_influence_starts_at_symbol": PREAMBLE_SYMBOLS,
"t2_explanation": "T2 начинает сопровождение после преамбулы; его решения заголовка сравнены побитно со штатным legacy.",
"candidate_analysis": candidate_summary,
"tx_validation": {
"headers_identical_at_all_packet_positions": tx_header_identical,
"all_headers_decode_with_correct_magic_version_length_checksum": all(item["passed"] for item in tx_header_decodes),
"decoded_packet_lengths": [item["packet_bytes"] for item in tx_header_decodes],
"software_roundtrip_current": software_current,
"legacy_and_t2_16_of_16": software_16_of_16,
},
"header_failure_root_cause": root_cause,
"one_small_fix_justified": one_small_fix,
"branch_decision": (
"ONE_SMALL_FIX_JUSTIFIED" if one_small_fix
else "NO_SMALL_FIX_JUSTIFIED"
),
"small_fix_assessment": {
"evidence_flags": small_fix_evidence,
"receiver_header_logic_error_found": small_fix_evidence["receiver_header_logic"],
"timing_transition_error_found": small_fix_evidence["timing_transition"],
"carrier_transition_error_explains_six_failures": small_fix_evidence["carrier_transition"],
"candidate_state_error_found": small_fix_evidence["candidate_state_handling"],
"reason": "TX и программный тракт дают 16/16; ошибки заголовка не имеют общей позиции, timing совпадает, а локальный остаток в failed header-окнах выше.",
},
"achieved_result": "10/16 exact full packets at 500 ksymbol/s, TX VGA 20 dB, hardware-valid OTA capture",
"recommended_next_project_branch": "CRSF / ELRS CONTROL AND TELEMETRY",
"qpsk_note": "QPSK с меньшей символьной скоростью остаётся будущим кандидатом для видеоканала; в Lab067 не реализован.",
"plots": plots,
"lab067_commit": "NOT PERFORMED",
"push": "NOT PERFORMED",
}
save_json(OUTPUT / "summary.json", summary)
return summary
def run_functional_tests() -> None:
expected = np.repeat(np.arange(HEADER_BITS, dtype=np.uint8) % 2, HEADER_REPETITION)
exact = header_diagnostics(2.0 * expected.astype(float) - 1.0, expected)
assert exact["raw_header_errors"] == 0
assert exact["voted_header_errors"] == 0
changed = expected.copy(); changed[3:5] ^= 1
result = header_diagnostics(2.0 * changed.astype(float) - 1.0, expected)
assert result["raw_header_errors"] == 2
assert result["voted_header_errors"] == 1
def main() -> None:
run_functional_tests()
result = analyze()
print(json.dumps({
"lab": result["lab"],
"historical_strict_result": result["historical_strict_result_unchanged"],
"root_cause": result["header_failure_root_cause"],
"one_small_fix_justified": result["one_small_fix_justified"],
"failed_packet_classifications": result["failed_packet_classifications"],
"plots": result["plots"],
}, ensure_ascii=False, indent=2))
print("RF TX = 0")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,142 @@
"""Lab062: программные условия и запрет TX до отдельного разрешения."""
from __future__ import annotations
from dataclasses import asdict
from pathlib import Path
import subprocess
import json
import pytest
from experiments import lab062_full_packet_rf_preflight as lab
from tools.hackrf_process_check import ProcessCheck, ProcessState
def test_fixed_packet_and_operating_point():
assert len(lab.plans()) == 16
assert all(len(frame.plan.payload) == 256 for frame in lab.plans())
assert lab.parameters()["rf_frequency_hz"] == 1_400_000_000
assert lab.parameters()["symbol_rate"] == 500_000
assert lab.parameters()["tx_vga_db"] == 10
assert lab.parameters()["rx_lna_db"] == lab.parameters()["rx_vga_db"] == 24
assert lab.POINT.distance_m == 1.2 and lab.POINT.visibility == "LOS indoor"
def test_rx_and_tx_commands_are_fixed_and_distinct():
receive = lab.transfer_command("rx.cs8", 800_000)
transmit = lab.transfer_command("tx.cs8", 100, transmit=True)
assert "-r" in receive and "-t" not in receive
assert "-t" in transmit and "-r" not in transmit
assert receive[receive.index("-f") + 1] == "1400000000"
assert receive[receive.index("-l") + 1] == receive[receive.index("-g") + 1] == "24"
assert transmit[transmit.index("-x") + 1] == "10"
@pytest.mark.parametrize("failure", [None, "clock", "clipping", "strong", "overrun"])
def test_preflight_never_transmits_and_fails_closed(tmp_path, monkeypatch, failure):
raw, output = tmp_path / "raw", tmp_path / "processed"
raw.mkdir(); output.mkdir()
monkeypatch.setattr(lab, "RAW", raw); monkeypatch.setattr(lab, "OUTPUT", output)
(raw / "tx_stream.cs8").write_bytes(b"test")
metadata = {"tx_sha256": "TEST"}
(output / "software_gate.json").write_text('{"passed": true, "tx_sha256": "TEST"}')
monkeypatch.setattr(lab, "validate_prepared", lambda: metadata)
monkeypatch.setattr(lab.lab054.phy.lab045, "_verify_device_inventory", lambda runner: {"passed": True})
def clock(point, runner, guard, **kwargs):
return {"passed": failure != "clock", "master_reg29": 0x26,
"slave_reg29": 0x26, "slave_clkin_status": "DETECTED"}
def runner(command):
assert "-t" not in command
if "-r" in command:
value = 127 if failure == "clipping" else (110 if failure == "strong" else 1)
Path(command[command.index("-r") + 1]).write_bytes(bytes([value, value]) * 800_000)
log = "1 RX overruns" if failure == "overrun" else "0 RX overruns"
return subprocess.CompletedProcess(command, 0, log, "")
monkeypatch.setattr(lab.lab054, "disable_clock_outputs", lambda runner: [])
kwargs = dict(runner=runner, clock_checker=clock,
process_checker=lambda: ProcessCheck(ProcessState.CLEAR, ()),
sleep_function=lambda _: None)
if failure:
with pytest.raises(RuntimeError):
lab.preflight(**kwargs)
else:
assert lab.preflight(**kwargs)["passed"]
result = __import__("json").loads((raw / "preflight_result.json").read_text())
assert result["rf_tx_count"] == 0
if failure is None:
assert "symbol_energy_code2_seconds" not in result["rx_level"]
assert result["rx_level"]["symbol_energy"] == "NOT_APPLICABLE_TO_BACKGROUND"
def test_second_preflight_is_refused_before_hardware(tmp_path, monkeypatch):
monkeypatch.setattr(lab, "RAW", tmp_path)
monkeypatch.setattr(lab, "OUTPUT", tmp_path)
(tmp_path / "preflight_attempt.json").write_text("{}")
monkeypatch.setattr(lab, "validate_prepared", lambda: {"tx_sha256": "TEST"})
(tmp_path / "software_gate.json").write_text('{"passed": true, "tx_sha256": "TEST"}')
with pytest.raises(FileExistsError):
lab.preflight(runner=lambda command: pytest.fail("hardware"))
def test_capture_refuses_missing_authorization_before_files_or_hardware(tmp_path, monkeypatch):
monkeypatch.setattr(lab, "RAW", tmp_path)
monkeypatch.setattr(lab, "OUTPUT", tmp_path)
with pytest.raises(PermissionError):
lab.capture_once(
authorization=False,
runner=lambda command: pytest.fail("hardware"),
)
assert not (tmp_path / "hardware_attempt.json").exists()
def test_capture_is_rx_first_single_tx_and_refuses_second_attempt(tmp_path, monkeypatch):
raw, output = tmp_path / "raw", tmp_path / "processed"
raw.mkdir(); output.mkdir()
monkeypatch.setattr(lab, "RAW", raw); monkeypatch.setattr(lab, "OUTPUT", output)
tx = raw / "tx_stream.cs8"; tx.write_bytes(b"\x01\x01" * 100)
metadata = {"tx_sha256": lab.sha256(tx), "tx_samples": 100}
monkeypatch.setattr(lab, "validate_prepared", lambda: metadata)
monkeypatch.setattr(lab, "require_preflight", lambda value: {})
monkeypatch.setattr(lab, "RX_SAMPLES", 800_000)
monkeypatch.setattr(lab.lab054.phy.lab045, "_verify_device_inventory", lambda runner: {"passed": True})
monkeypatch.setattr(lab.lab054, "disable_clock_outputs", lambda runner: [])
events = []
class Process:
def poll(self): return None
def wait(self, timeout): return 0
def close_logs(self): pass
def terminate(self): pass
def starter(command, stdout, stderr):
events.append("RX")
Path(command[command.index("-r") + 1]).write_bytes(b"\x01\x01" * 800_000)
Path(stdout).write_text("")
Path(stderr).write_text("0 RX overruns")
return Process()
def runner(command):
if "-t" in command:
events.append("TX")
return subprocess.CompletedProcess(command, 0, "0 TX underruns", "")
return subprocess.CompletedProcess(command, 0, "", "")
def clock(point, runner, guard, **kwargs):
guard.tx_allowed = True
return {
"passed": True, "master_reg29": 0x26, "slave_reg29": 0x26,
"slave_clkin_status": "DETECTED",
}
result = lab.capture_once(
authorization=True, runner=runner, process_starter=starter,
process_checker=lambda: ProcessCheck(ProcessState.CLEAR, ()),
clock_checker=clock, sleep_function=lambda _: None,
)
assert events == ["RX", "TX"]
assert result["rf_tx_count"] == 1 and result["automatic_tx_repeats"] == 0
assert result["rx_overruns"] == result["tx_underruns"] == 0
assert json.loads((raw / "capture_result.json").read_text())["passed"]
with pytest.raises(FileExistsError):
lab.capture_once(authorization=True, runner=lambda command: pytest.fail("hardware"))

View File

@@ -0,0 +1,111 @@
"""Lab063: автономные проверки локального сопоставления без SDR."""
from __future__ import annotations
import numpy as np
from experiments import lab063_tx_underrun_localization as lab
def test_underrun_scale_is_exact():
result = lab.underrun_scale(16_672)
assert result["complex_samples"] == 8_336
assert result["duration_seconds"] == 0.001042
assert result["symbols"] == 521
assert np.isclose(result["fraction_of_packet"], 8_336 / 92_256)
def test_normalized_match_recovers_offset_gain_and_low_residual():
random_generator = np.random.default_rng(6301)
transmitted = (random_generator.choice((-1.0, 1.0), 2048)
* np.exp(1j * np.arange(2048) * 0.01))
gain = 0.35 - 0.2j
search = np.concatenate((np.zeros(321, complex), gain * transmitted, np.zeros(400, complex)))
result = lab.normalized_match(transmitted, search)
assert result["offset"] == 321
assert result["normalized_correlation"] > 0.999999
assert abs(result["gain"] - gain) < 1e-12
assert result["residual_power"] < 1e-20
def test_alignment_localizes_inserted_delay_jump():
random_generator = np.random.default_rng(6302)
transmitted = random_generator.choice((-1.0, 1.0), 8192).astype(np.complex64)
split, inserted = 4096, 700
received = np.concatenate((np.zeros(1000), transmitted[:split], np.zeros(inserted), transmitted[split:], np.zeros(1000)))
rows = lab.track_alignment(
lab.ArrayReader(transmitted), lab.ArrayReader(received), 1000,
frame_samples=8192, window_samples=512, step_samples=256, search_margin=1000,
reliable_packet_start=0, reliable_packet_end=8192,
)
verdict = lab.alignment_verdict(rows, inserted)
assert verdict["local_delay_discontinuity"]
assert any(abs(row["delay_change_samples"]) >= inserted - 1 for row in verdict["jump_candidates"])
def test_alignment_compares_reliable_windows_across_packet_boundary():
rows = [
{
"window_index": 4, "tx_sample": 1000, "rx_sample": 2000,
"packet_index": 1, "position_inside_packet_samples": 1000,
"local_delay_samples": 0, "normalized_correlation": 0.9,
"inside_reliable_region": True, "correlation_above_threshold": True,
"reliable_for_delay": True,
},
{
"window_index": 9, "tx_sample": 9000, "rx_sample": 10700,
"packet_index": 2, "position_inside_packet_samples": 800,
"local_delay_samples": 700, "normalized_correlation": 0.9,
"inside_reliable_region": True, "correlation_above_threshold": True,
"reliable_for_delay": True,
},
]
verdict = lab.alignment_verdict(rows, 700)
assert verdict["local_delay_discontinuity"]
assert verdict["jump_candidates"][0]["packet_index"] == 2
def test_alignment_discloses_internal_low_correlation_window():
rows = [
{
"window_index": 0, "tx_sample": 1000, "rx_sample": 2000,
"packet_index": 1, "position_inside_packet_samples": 1000,
"local_delay_samples": 0, "normalized_correlation": 0.9,
"inside_reliable_region": True, "correlation_above_threshold": True,
"reliable_for_delay": True,
},
{
"window_index": 1, "tx_sample": 1256, "rx_sample": 2956,
"packet_index": 1, "position_inside_packet_samples": 1256,
"local_delay_samples": 700, "normalized_correlation": 0.1,
"inside_reliable_region": True, "correlation_above_threshold": False,
"reliable_for_delay": False,
},
]
verdict = lab.alignment_verdict(rows, 700)
assert verdict["internal_low_correlation_windows"]["count"] == 1
assert "UNDETERMINED_IN_1_INTERNAL_LOW_CORRELATION_WINDOWS" in verdict["local_delay_discontinuity_scope"]
assert verdict["local_delay_discontinuity"] is False
def test_classification_marks_global_degradation_without_jump():
packets = [{
"packet_index": index,
"symbol_error_rate": 0.1,
"symbol_rms_deviation": 1.2,
"matched_residual_db": -1.0,
} for index in range(1, 17)]
result = lab.classify(packets, {"local_delay_discontinuity": False})
assert result["quality_distribution"] == "GLOBAL"
assert result["primary_cause_status"] == "PARTIALLY_LOCALIZED"
def test_classification_marks_mixed_when_jump_and_global_damage_coexist():
packets = [{
"packet_index": index,
"symbol_error_rate": 0.1,
"symbol_rms_deviation": 1.2,
"matched_residual_db": -1.0,
} for index in range(1, 17)]
result = lab.classify(packets, {"local_delay_discontinuity": True})
assert result["quality_distribution"] == "MIXED"

View File

@@ -0,0 +1,198 @@
"""Lab064: цифровая лестница, измерительные метрики и запрет RF без разрешения."""
from __future__ import annotations
import json
from pathlib import Path
import subprocess
import numpy as np
import pytest
from experiments import lab064_rf_level_linearity as lab
from tools.hackrf_process_check import ProcessCheck, ProcessState
def test_fixed_operating_point_and_measurement_scope():
parameters = lab.parameters()
assert parameters["rf_frequency_hz"] == 1_400_000_000
assert parameters["sample_rate_hz"] == 8_000_000
assert parameters["symbol_rate"] == 20_000
assert parameters["samples_per_symbol"] == 400
assert parameters["digital_carrier_hz"] == 50_000
assert parameters["levels_db_relative_nominal"] == [-18.0, -12.0, -6.0, 0.0]
assert parameters["full_phy_packet"] is False
assert parameters["tx_vga_db"] == 10
assert parameters["rx_lna_db"] == parameters["rx_vga_db"] == 24
assert lab.POINT.distance_m == 1.2
assert lab.POINT.visibility == "LOS indoor"
def test_waveform_has_exact_guards_segments_gaps_and_levels():
rows, blocks = lab.prepared_segments()
assert lab.TX_SAMPLES == 6_000_000
assert lab.TX_SAMPLES / lab.SAMPLE_RATE == 0.75
assert all(row["samples"] == 800_000 for row in rows)
assert [row["start_sample"] for row in rows] == [800_000, 2_000_000, 3_200_000, 4_400_000]
assert all(len(blocks[row["label"]]) == 2 * lab.SEGMENT_SAMPLES for row in rows)
assert all(not row["metrics"]["digital_clipping"] for row in rows)
steps = [row["tx_input_difference_from_previous_db"] for row in rows[1:]]
assert np.allclose(steps, 6.0, atol=0.1)
def test_background_windows_cover_both_guards_and_all_gaps():
windows = lab.background_windows()
assert [row["label"] for row in windows] == [
"INITIAL_GUARD", "GAP_L0_L1", "GAP_L1_L2", "GAP_L2_L3", "FINAL_GUARD"
]
assert all(row["samples"] == 160_000 for row in windows)
zero_ranges = [
(0, 800_000),
(1_600_000, 2_000_000),
(2_800_000, 3_200_000),
(4_000_000, 4_400_000),
(5_200_000, 6_000_000),
]
for row, (low, high) in zip(windows, zero_ranges):
assert low <= row["tx_relative_start_sample"]
assert row["tx_relative_start_sample"] + row["samples"] <= high
def test_background_stability_uses_ac_power_range():
stable = lab.summarize_background([
{"metrics": {"ac_power_code2": 1.0, "ac_rms_code": 1.0}},
{"metrics": {"ac_power_code2": 1.5, "ac_rms_code": np.sqrt(1.5)}},
])
changed = lab.summarize_background([
{"metrics": {"ac_power_code2": 1.0, "ac_rms_code": 1.0}},
{"metrics": {"ac_power_code2": 4.0, "ac_rms_code": 2.0}},
])
assert stable["stable"] is True
assert changed["stable"] is False
assert changed["maximum_to_minimum_ac_power_db"] == pytest.approx(6.020599913)
def test_synthetic_linear_channel_recovers_digital_steps():
result = lab.synthetic_linearity_gate()
assert result["passed"]
assert max(abs(value) for value in result["linearity_errors_db"]) < 0.02
gains = [row["gain_abs"] for row in result["rows"]]
assert np.allclose(gains, 0.37, atol=0.001)
def test_counter_parser_keeps_every_intermediate_and_final_observation():
log = "0 TX underruns\n1 TX underrun\n3 TX underruns\n3 TX underruns\n"
summary = lab.counter_summary(log, "underrun")
assert summary["selected_counts"] == [0, 1, 3, 3]
assert summary["final_count"] == 3
assert summary["maximum_count"] == 3
assert summary["clean"] is False
assert [row["character_offset"] for row in summary["observations"]] == sorted(
row["character_offset"] for row in summary["observations"]
)
assert lab.counter_summary("0 RX overruns", "overrun")["clean"] is True
def test_intermediate_loss_cannot_be_hidden_by_final_zero():
tx = lab.counter_summary("0 TX underruns\n1 TX underrun\n0 TX underruns", "underrun")
rx = lab.counter_summary("0 RX overruns", "overrun")
validity = lab.capture_validity({
"passed": False,
"rx_clipping": False,
"tx_counter_summary": tx,
"rx_counter_summary": rx,
})
assert tx["final_count"] == 0
assert tx["maximum_count"] == 1
assert validity["valid"] is False
assert "TX_MAXIMUM_COUNTER_NOT_ZERO" in validity["invalid_reasons"]
assert "CAPTURE_RUNNER_NOT_PASSED" in validity["invalid_reasons"]
def test_commands_fix_gains_and_keep_rx_separate_from_tx():
receive = lab.transfer_command("rx.cs8", 800_000)
transmit = lab.transfer_command("tx.cs8", 100, transmit=True)
assert "-r" in receive and "-t" not in receive
assert "-t" in transmit and "-r" not in transmit
assert receive[receive.index("-f") + 1] == "1400000000"
assert receive[receive.index("-s") + 1] == "8000000"
assert receive[receive.index("-l") + 1] == receive[receive.index("-g") + 1] == "24"
assert transmit[transmit.index("-x") + 1] == "10"
assert receive[-5:] == ["-a", "0", "-p", "0", "-B"]
assert transmit[-5:] == ["-a", "0", "-p", "0", "-B"]
@pytest.mark.parametrize("failure", [None, "clock", "clipping", "strong", "overrun"])
def test_preflight_never_transmits_and_fails_closed(tmp_path, monkeypatch, failure):
raw = tmp_path / "raw"
output = tmp_path / "processed"
raw.mkdir()
output.mkdir()
monkeypatch.setattr(lab, "RAW", raw)
monkeypatch.setattr(lab, "OUTPUT", output)
(raw / "tx_level_staircase.cs8").write_bytes(b"test")
metadata = {"tx_sha256": "TEST"}
(output / "software_gate.json").write_text(
'{"passed": true, "tx_sha256": "TEST"}', encoding="utf-8"
)
monkeypatch.setattr(lab, "validate_prepared", lambda: metadata)
monkeypatch.setattr(
lab.lab054.phy.lab045,
"_verify_device_inventory",
lambda runner: {"passed": True},
)
def clock(point, runner, guard, **kwargs):
return {
"passed": failure != "clock",
"master_reg29": 0x26,
"slave_reg29": 0x26,
"slave_clkin_status": "DETECTED",
}
def runner(command):
assert "-t" not in command
if "-r" in command:
value = 127 if failure == "clipping" else (110 if failure == "strong" else 1)
Path(command[command.index("-r") + 1]).write_bytes(bytes([value, value]) * 800_000)
log = "1 RX overruns" if failure == "overrun" else "0 RX overruns"
return subprocess.CompletedProcess(command, 0, log, "")
monkeypatch.setattr(lab.lab054, "disable_clock_outputs", lambda runner: [])
options = {
"runner": runner,
"clock_checker": clock,
"process_checker": lambda: ProcessCheck(ProcessState.CLEAR, ()),
"sleep_function": lambda _: None,
}
if failure:
with pytest.raises(RuntimeError):
lab.preflight(**options)
else:
assert lab.preflight(**options)["passed"]
result = json.loads((raw / "preflight_result.json").read_text(encoding="utf-8"))
assert result["rf_tx_count"] == 0
assert result["stop_before_tx"] is True
def test_second_preflight_is_refused_before_hardware(tmp_path, monkeypatch):
monkeypatch.setattr(lab, "RAW", tmp_path)
monkeypatch.setattr(lab, "OUTPUT", tmp_path)
(tmp_path / "preflight_attempt.json").write_text("{}", encoding="utf-8")
(tmp_path / "software_gate.json").write_text(
'{"passed": true, "tx_sha256": "TEST"}', encoding="utf-8"
)
monkeypatch.setattr(lab, "validate_prepared", lambda: {"tx_sha256": "TEST"})
with pytest.raises(FileExistsError):
lab.preflight(runner=lambda command: pytest.fail("hardware must not run"))
def test_capture_refuses_missing_authorization_before_files_or_hardware(tmp_path, monkeypatch):
monkeypatch.setattr(lab, "RAW", tmp_path)
monkeypatch.setattr(lab, "OUTPUT", tmp_path)
with pytest.raises(PermissionError):
lab.capture_once(
authorization=False,
runner=lambda command: pytest.fail("hardware must not run"),
)
assert not (tmp_path / "hardware_attempt.json").exists()

View File

@@ -0,0 +1,151 @@
"""Lab065: неизменный waveform, TX VGA 20 дБ и границы классификации."""
from __future__ import annotations
import json
from pathlib import Path
import subprocess
import sys
import pytest
from experiments import lab065_rf_level_linearity as lab
from tools.hackrf_process_check import ProcessCheck, ProcessState
def test_only_operating_parameter_change_is_tx_vga():
old = lab.lab064.parameters()
new = lab.parameters()
assert new.pop("geometry_unchanged_from_lab064") is True
assert new.pop("waveform_source") == "Lab064 exact CS8 copy"
assert new["tx_vga_db"] == 20
new["tx_vga_db"] = 10
assert new == old
def test_tx_command_uses_20_db_and_rx_remains_24_24():
transmit = lab.transfer_command("tx.cs8", 100, transmit=True)
receive = lab.transfer_command("rx.cs8", 100)
assert transmit[transmit.index("-x") + 1] == "20"
assert receive[receive.index("-l") + 1] == "24"
assert receive[receive.index("-g") + 1] == "24"
assert transmit[-5:] == receive[-5:] == ["-a", "0", "-p", "0", "-B"]
def test_exact_lab064_waveform_is_required():
metadata = lab.validate_lab064_waveform()
assert metadata["tx_sha256"] == lab.EXPECTED_TX_SHA256
assert metadata["tx_samples"] == 6_000_000
def _result(matched_gain, residual_gain, improvements, errors=(0.0, 0.0, 0.0)):
old = {row["label"]: row for row in json.loads(
lab.LAB064_RESULT.read_text(encoding="utf-8")
)["rows"]}
rows = []
for index, label in enumerate(("L0", "L1", "L2", "L3")):
baseline = old[label]
rows.append({
"label": label,
"matched_signal_power": baseline["matched_signal_power"] * 10 ** (matched_gain[index] / 10),
"residual_power": baseline["residual_power"] * 10 ** (residual_gain[index] / 10),
"matched_to_residual_db": baseline["matched_to_residual_db"] + improvements[index],
"gain_power_abs_h_squared": baseline["gain_power_abs_h_squared"] * 10 ** (matched_gain[index] / 10),
})
return {
"capture_valid": True,
"rows": rows,
"comparisons": [{"linearity_error_db": error} for error in errors],
}
@pytest.mark.parametrize(
("result", "expected"),
[
(_result([10] * 4, [1] * 4, [9] * 4), "LINEAR_GAIN_IMPROVEMENT"),
(_result([10] * 4, [10] * 4, [0] * 4), "RESIDUAL_RISES_WITH_SIGNAL"),
(_result([1] * 4, [0] * 4, [1] * 4), "NO_MEANINGFUL_GAIN"),
(_result([10] * 4, [1] * 4, [9] * 4, errors=(0, 0, -1.6)), "COMPRESSION_AT_HIGHER_TX_GAIN"),
],
)
def test_classification_cases(result, expected):
comparison = lab.compare_sessions(
json.loads(lab.LAB064_RESULT.read_text(encoding="utf-8")), result["rows"]
)
assert lab.classify_result(result, comparison)["case"] == expected
@pytest.mark.parametrize("failure", [None, "clock", "overrun", "clipping"])
def test_preflight_never_transmits_and_fails_closed(tmp_path, monkeypatch, failure):
raw, output = tmp_path / "raw", tmp_path / "output"
raw.mkdir()
output.mkdir()
monkeypatch.setattr(lab, "RAW", raw)
monkeypatch.setattr(lab, "OUTPUT", output)
(raw / "tx_level_staircase.cs8").write_bytes(b"test")
metadata = {"tx_sha256": "TEST"}
(output / "software_gate.json").write_text('{"passed": true, "tx_sha256": "TEST"}')
monkeypatch.setattr(lab, "validate_prepared", lambda: metadata)
monkeypatch.setattr(lab.lab054.phy.lab045, "_verify_device_inventory", lambda runner: {"passed": True})
monkeypatch.setattr(lab.lab054, "disable_clock_outputs", lambda runner: [])
monkeypatch.setattr(lab, "parameters", lambda: {})
def clock(point, runner, guard, **kwargs):
return {"passed": failure != "clock", "master_reg29": 0x26,
"slave_reg29": 0x26, "slave_clkin_status": "DETECTED"}
def runner(command):
assert "-t" not in command
if "-r" in command:
value = 127 if failure == "clipping" else 1
Path(command[command.index("-r") + 1]).write_bytes(bytes([value, value]) * 800_000)
log = "1 RX overruns" if failure == "overrun" else "0 RX overruns"
return subprocess.CompletedProcess(command, 0, log, "")
options = {
"runner": runner,
"clock_checker": clock,
"process_checker": lambda: ProcessCheck(ProcessState.CLEAR, ()),
"sleep_function": lambda _: None,
}
if failure:
with pytest.raises(RuntimeError):
lab.preflight(**options)
else:
assert lab.preflight(**options)["passed"]
assert json.loads((raw / "preflight_result.json").read_text())["rf_tx_count"] == 0
def test_capture_is_unavailable_without_new_authorization():
with pytest.raises(PermissionError):
lab.capture_once(authorization=False)
def test_existing_attempt_blocks_capture_before_hardware(tmp_path, monkeypatch):
monkeypatch.setattr(lab, "RAW", tmp_path)
monkeypatch.setattr(lab, "validate_prepared", lambda: {"tx_sha256": "TEST"})
monkeypatch.setattr(lab, "require_preflight", lambda metadata: {})
(tmp_path / "hardware_attempt.json").write_text("{}", encoding="utf-8")
with pytest.raises(FileExistsError):
lab.capture_once(
authorization=True,
runner=lambda command: pytest.fail("hardware must not run"),
process_starter=lambda *args: pytest.fail("hardware must not run"),
)
def test_cli_labels_current_rf_state_after_completed_capture(monkeypatch, capsys):
monkeypatch.setattr(
lab,
"capture_once",
lambda authorization=False: {
"stage": "SINGLE_RF_LEVEL_CAPTURE", "rf_tx_count": 1, "passed": True,
},
)
monkeypatch.setattr(
sys, "argv", ["lab065", "--stage", "capture", "--authorize-one-rf"]
)
lab.main()
output = capsys.readouterr().out
assert '"rf_tx_count": 1' in output
assert output.endswith("RF TX NOW = 0\n")

View File

@@ -0,0 +1,149 @@
"""Lab066: исправленные паузы, строгий software gate и запрет TX."""
from __future__ import annotations
import hashlib
import json
from pathlib import Path
import subprocess
import pytest
from experiments import lab066_full_packet_rf_retest as lab
from tools.hackrf_process_check import ProcessCheck, ProcessState
def test_fixed_layout_and_operating_point():
waveform, layout = lab.build_waveform()
assert len(lab.plans()) == 16
assert all(len(frame.plan.payload) == 256 for frame in lab.plans())
assert len({frame.plan.payload for frame in lab.plans()}) == 16
assert lab.PACKET_SAMPLES == 92_256
assert lab.INTER_PACKET_GAP_SAMPLES == 40_000
assert lab.NUMBER_OF_GAPS == 15
assert lab.GUARD_SAMPLES == 800_000
assert lab.BASE_TX_SAMPLES == 2_076_096
assert lab.EXPECTED_TX_SAMPLES == 3_676_096
assert len(waveform) == 2 * lab.EXPECTED_TX_SAMPLES
assert [row["packet_index"] for row in layout] == list(range(1, 17))
assert lab.parameters()["tx_vga_db"] == 20
assert lab.parameters()["rx_lna_db"] == lab.parameters()["rx_vga_db"] == 24
def test_guards_and_all_gaps_are_exact_zero():
waveform, layout = lab.build_waveform()
samples = memoryview(waveform)
assert not any(samples[:2 * lab.GUARD_SAMPLES])
assert not any(samples[-2 * lab.GUARD_SAMPLES:])
for row in layout[:-1]:
low = 2 * row["following_gap_start_sample"]
high = low + 2 * row["following_gap_samples"]
assert high - low == 2 * 40_000
assert not any(samples[low:high])
def test_transfer_commands_are_rx_only_or_fixed_tx():
receive = lab.transfer_command("rx.cs8", 800_000)
transmit = lab.transfer_command("tx.cs8", 100, transmit=True)
assert "-r" in receive and "-t" not in receive
assert "-t" in transmit and "-r" not in transmit
assert receive[receive.index("-f") + 1] == "1400000000"
assert receive[receive.index("-l") + 1] == receive[receive.index("-g") + 1] == "24"
assert transmit[transmit.index("-x") + 1] == "20"
def test_prepare_metadata_and_two_strict_roundtrips(tmp_path, monkeypatch):
raw, output = tmp_path / "raw", tmp_path / "processed"
monkeypatch.setattr(lab, "RAW", raw); monkeypatch.setattr(lab, "OUTPUT", output)
metadata = lab.prepare()
assert metadata["tx_samples"] == lab.EXPECTED_TX_SAMPLES
assert metadata["tx_sha256"] == hashlib.sha256((raw / "tx_stream.cs8").read_bytes()).hexdigest()
result = lab.software_gate()
for mode in ("legacy", "t2"):
row = result[mode]
assert row["header_pass"] == row["fec_pass"] == row["crc_pass"] == 16
assert row["packet_output"] == row["exact_payload_match"] == 16
assert row["packet_indexes"] == list(range(1, 17))
assert row["exact_ordered_payloads"] and row["passed"]
assert row["fallback_between_modes"] is False
assert result["t2"]["t2_state_scope"] == "NEW_PREAMBLE_ESTIMATE_PER_PACKET"
assert result["t2"]["t2_state_reset_evidence"][
"tracking_runs_per_accepted_packet"
] == [2] * 16
assert result["t2_state_reset_verified_by_fresh_preamble_per_packet"] is True
@pytest.mark.parametrize("failure", [None, "clock", "clipping", "strong", "overrun"])
def test_preflight_never_transmits_and_fails_closed(tmp_path, monkeypatch, failure):
raw, output = tmp_path / "raw", tmp_path / "processed"
raw.mkdir(); output.mkdir()
monkeypatch.setattr(lab, "RAW", raw); monkeypatch.setattr(lab, "OUTPUT", output)
(raw / "tx_stream.cs8").write_bytes(b"test")
monkeypatch.setattr(lab, "validate_prepared", lambda: {"tx_sha256": "TEST"})
(output / "software_gate.json").write_text('{"passed": true, "tx_sha256": "TEST"}')
monkeypatch.setattr(lab.lab054.phy.lab045, "_verify_device_inventory", lambda runner: {"passed": True})
def clock(point, runner, guard, **kwargs):
return {"passed": failure != "clock", "master_reg29": 0x26,
"slave_reg29": 0x26, "slave_clkin_status": "DETECTED"}
def runner(command):
assert "-t" not in command
if "-r" in command:
value = 127 if failure == "clipping" else (110 if failure == "strong" else 1)
Path(command[command.index("-r") + 1]).write_bytes(bytes([value, value]) * lab.PREFLIGHT_SAMPLES)
log = "1 RX overruns\n0 RX overruns" if failure == "overrun" else "0 RX overruns"
return subprocess.CompletedProcess(command, 0, log, "")
monkeypatch.setattr(lab.lab054, "disable_clock_outputs", lambda runner: [])
kwargs = dict(runner=runner, clock_checker=clock,
process_checker=lambda: ProcessCheck(ProcessState.CLEAR, ()),
sleep_function=lambda _: None)
if failure:
with pytest.raises(RuntimeError): lab.preflight(**kwargs)
else:
assert lab.preflight(**kwargs)["passed"]
record = json.loads((raw / "preflight_result.json").read_text())
assert record["rf_tx_count"] == 0
if failure == "overrun":
assert record["rx_counter_summary"]["maximum_count"] == 1
def test_capture_refuses_without_authorization_before_hardware(tmp_path, monkeypatch):
monkeypatch.setattr(lab, "RAW", tmp_path); monkeypatch.setattr(lab, "OUTPUT", tmp_path)
with pytest.raises(PermissionError):
lab.capture_once(authorization=False, runner=lambda command: pytest.fail("hardware"))
assert not (tmp_path / "hardware_attempt.json").exists()
def test_future_analysis_declares_strict_modes_and_physical_comparison():
source = Path(lab.__file__).read_text(encoding="utf-8")
assert 'decode("legacy", rx_path, diagnostics=True)' in source
assert 'decode("t2", rx_path, diagnostics=True)' in source
assert "physical_packet_diagnostics(tx, rx, location)" in source
assert "if not strict_runs_complete" in source
assert '["Lab056 B", "Lab062", "Lab066"]' in source
def test_future_analysis_rejects_capture_from_another_configuration(tmp_path, monkeypatch):
monkeypatch.setattr(lab, "RAW", tmp_path); monkeypatch.setattr(lab, "OUTPUT", tmp_path)
rx = tmp_path / "rx_stream.cs8"; rx.write_bytes(b"\x00\x00")
capture = {
"lab": "Lab066", "rf_tx_count": 1, "automatic_tx_repeats": 0,
"point": {}, "parameters": {}, "tx_sha256": "WRONG",
"rx_sha256": lab.sha256(rx),
}
(tmp_path / "capture_result.json").write_text(json.dumps(capture))
monkeypatch.setattr(lab, "validate_prepared", lambda: {"tx_sha256": "EXPECTED"})
monkeypatch.setattr(lab, "decode", lambda *args, **kwargs: pytest.fail("decode"))
with pytest.raises(RuntimeError, match="подтверждённой"):
lab.analyze_saved_capture()
def test_second_preflight_is_refused_before_hardware(tmp_path, monkeypatch):
monkeypatch.setattr(lab, "RAW", tmp_path); monkeypatch.setattr(lab, "OUTPUT", tmp_path)
(tmp_path / "preflight_attempt.json").write_text("{}")
monkeypatch.setattr(lab, "validate_prepared", lambda: {"tx_sha256": "TEST"})
(tmp_path / "software_gate.json").write_text('{"passed": true, "tx_sha256": "TEST"}')
with pytest.raises(FileExistsError):
lab.preflight(runner=lambda command: pytest.fail("hardware"))

View File

@@ -0,0 +1,79 @@
"""Проверки диагностических вычислений 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}