ionozond: окно эха — фаза каждого зондирования за 1,6 МБ вместо 80
Станция удаляет каждую запись после проверки архива, а архив хранил только мощность — вместе с записью каждые пять минут пропадали доплер, замирания и фаза. Теперь в архив вырезается окно эха: комплексный сигнал вокруг эхо-сигналов, побитово совпадающий с эталонной реализацией. Как оно устроено, почему запись удаляется только после проверки окна и как сохранить сигнал целиком.
Одно зондирование станции ionozond — это запись .lfs на 80 МБ, а при периоде повторения 300 секунд одна станция даёт около 23 ГБ в сутки. Хранить такие записи вечно нельзя, поэтому приёмник после каждого зондирования пишет архив .h5 в формате chirpsounder2 и удаляет запись, как только архив прочитан обратно. Но архив хранит мощность — спектрограмму. Вместе с записью каждые пять минут пропадала быстрая часть канала: доплеровский сдвиг и рассеяние, замирания и фаза, в которой записана дисперсия групповой задержки.
Что такое окно эха
После обращения ЛЧМ эхо-сигналы занимают полосу частот биений в несколько сотен герц из 40 кГц, которые хранит запись. Окно эха сдвигает эту полосу к нулю, пропускает через фильтр нижних частот, прореживает и дописывает результат в архив отдельной группой echo_window. На записях станции на Кипре это 1,57 МБ — 1/51 записи, и внутри полосы окна сигнал сохранён без потерь. Архив вырастает с 1,25 до 2,81 МБ за зондирование, то есть примерно на 450 МБ за станцию в сутки.
Формат окна задан спецификацией платформы обработки ionograms-handler, а эталонная реализация живёт в её модуле muf. Окно в ionozond сверяется с этим эталоном, а не само с собой:
- То же окно. Диапазон дальностей — объединение автоматического стробирования по ионограмме мощности и геометрии мод с одним–тремя скачками, плюс 150 км. Он следует за энергией эха, а не только за расчётной трассой.
- Те же отсчёты. Прореживание суммирует отводы фильтра в том же порядке, что и
scipy.signal.upfirdn, поэтому результат побитово совпадает с эталоном в формате complex64. Это важно: проверка вmufзаново вырезает окно по сохранённым отводам и требует полностью совпадающих отсчётов. - Только numpy и h5py. SciPy на станции необязателен, поэтому отводы фильтра Кайзера считаются по формуле из спецификации и сохраняются вместе с окном — читателю не нужно соглашаться с этим проектировщиком фильтров.
Проверка на пяти записях 4 февраля 2026 года, с 03:00 до 18:00 UTC, дала полное совпадение: одно и то же окно 2486–4112 км, прореживание в 45 раз, 3595 отводов; из 222 304 отсчётов не отличается ни один. Собственная проверка muf проходит: подавление вне полосы 82,6 дБ, неравномерность в полосе 0,0006 дБ. На вырезание окна уходит 1,9 секунды после 1,3 секунды на построение продуктов.
Одно расхождение всё же нашлось, и оно поучительно. Во встроенной таблице станций muf координаты передатчика на Кипре отличаются от заголовка записи на 0,6 км, и окно muf смещается на те же 0,6 км. Верны оба окна: решают координаты, а не реализация.
Запись удаляется только после проверки окна
Окно имеет смысл, только если запись не удалят раньше, чем окно будет надёжно сохранено. Ревизия нашла два пути, по которым запись уходила без этой гарантии.
Первый — немедленное удаление в самом приёмнике. Окно вырезалось без полной проверки: чтение обратно доказывало, что байты дошли до диска, но не что это правильные байты. Фильтр, точное повторное вырезание и пересчитанная мощность — то, что поймает сдвиг или ошибку знака после будущей правки, — запускались только с проверкой. А архив, в котором окно уже было, отпускал запись вообще без проверки.
Второй путь — плановая очистка по сроку хранения и таймер освобождения диска. Они решали по архиву мощности, не глядя на окно. Запись, которую приёмник придержал из-за неудачного окна, через несколько часов всё равно удалялась — и с ней последняя копия фазы.
Теперь запись считается готовой к удалению, только если в архиве есть проверенное окно. Недостающее окно сначала вырезается и проверяется; запись, у которой вырезать не удалось, остаётся. Оба пути решают через одну и ту же функцию, поэтому разойтись во мнении, когда запись можно удалять, они не могут. Плановая очистка тратит на это не больше 15 секунд за проход, чтобы накопившиеся записи не задержали следующее зондирование. На копии одной записи очистка вырезала окно, проверила его и отпустила запись за 5,5 секунды.
Сигнал целиком
Для тех, кому нужна вся запись, а не окно, в параметрах консоли появился флажок «Полный сигнал z в архиве .h5». Он расширяет окно до всей полосы: без сдвига, без прореживания, с одним отводом — случай, который спецификация уже допускает. Тогда архив хранит запись отсчёт в отсчёт и полностью её заменяет.


На записи 4 февраля, 12:00, сохранённый сигнал совпал с отсчётами .lfs, занял в архиве 69 МБ из 80 при сжатии gzip с перестановкой байтов, а ионограмма, построенная muf из архива, совпала с построенной из записи до 0,000000 дБ.
Сигнал хранится внутри окна, а не в корневом наборе данных z, который предусматривает chirpsounder2, — и это сделано намеренно. Корневой z muf читает с временной привязкой второй версии формата и подписал бы каждую частоту на 7,5 МГц ниже настоящей. Окно же несёт собственное время и параметры развёртки.
Где окно уже пригодилось
Октябрьские зондирования трассы NIC1 — Йошкар-Ола записаны как архивы с окнами эха. Из окна, а не из сохранённой мощности, их читает имитатор КВ-канала: окно снова проходит через спектрограмму исходной записи, поэтому масштаб и пересчёт в отношение несущей к шуму остаются такими же, как у .lfs. Об имитаторе — следующий разбор.
Последняя правка этой серии — мелкая, но заметная: синхронизация с сетевым хранилищем отказывалась выгружать архивы, когда хранилище было подключено автомонтированием. В таблице монтирования в одной точке оказываются две записи — ловушка autofs и смонтированный поверх неё ресурс, — а программа брала первую и считала ресурс неподключённым. Теперь, как и в ядре, выигрывает последняя.
Выводы
- Удалять сырые данные можно, только когда сохранено всё, что из них ещё понадобится: архив мощности не заменяет запись, потому что теряет фазу.
- Почти вся информация о канале занимает узкую полосу: окно в 1/51 записи хранит её без потерь.
- Совместимость с эталоном лучше доказывать побитовым совпадением отсчётов, чем близостью графиков.
- Решение «можно ли удалять» должно приниматься в одном месте: два независимых правила рано или поздно разойдутся.
Доступность
Исходный код открыт.
- Исходный код: github.com/nikita-konkin/ionozond
- Интерактивные модели: konkin-nikita.ru/ionozond-playground
Теги
Другие обновления по проекту
ionozond: консоль ЛЧМ-ионозонда, восстановленная по бинарнику
Исходники консоли наклонного ЛЧМ-зондирования были утеряны, остался только собранный бинарник. Как по нему восстановили программу и доказали совпадение с оригиналом, какие причу...