This commit is contained in:
awe
2026-03-25 18:54:59 +03:00
parent fa4870c56c
commit 64e66933e4
14 changed files with 350 additions and 42 deletions

View File

@ -82,6 +82,62 @@ class AsciiSweepParser:
return events
class ComplexAsciiSweepParser:
"""Incremental parser for ASCII ``step real imag`` streams."""
def __init__(self):
self._buf = bytearray()
self._last_step: Optional[int] = None
self._seen_points = False
def feed(self, data: bytes) -> List[ParserEvent]:
if data:
self._buf += data
events: List[ParserEvent] = []
while True:
nl = self._buf.find(b"\n")
if nl == -1:
break
line = bytes(self._buf[:nl])
del self._buf[: nl + 1]
if line.endswith(b"\r"):
line = line[:-1]
if not line:
continue
if line.lower().startswith(b"sweep_start"):
self._last_step = None
self._seen_points = False
events.append(StartEvent())
continue
parts = line.split()
if len(parts) < 3:
continue
try:
step = int(parts[0], 10)
real = float(parts[1])
imag = float(parts[2])
except Exception:
continue
if step < 0 or (not math.isfinite(real)) or (not math.isfinite(imag)):
continue
if self._seen_points and self._last_step is not None and step <= self._last_step:
events.append(StartEvent())
self._seen_points = True
self._last_step = step
events.append(
PointEvent(
ch=0,
x=step,
y=float(abs(complex(real, imag))),
aux=(float(real), float(imag)),
)
)
return events
class LegacyBinaryParser:
"""Byte-resynchronizing parser for legacy 8-byte binary records."""

View File

@ -10,6 +10,7 @@ from queue import Full, Queue
from rfg_adc_plotter.io.serial_source import SerialChunkReader, SerialLineSource
from rfg_adc_plotter.io.sweep_parser_core import (
AsciiSweepParser,
ComplexAsciiSweepParser,
LegacyBinaryParser,
LogScale16BitX2BinaryParser,
LogScaleBinaryParser32,
@ -33,6 +34,7 @@ class SweepReader(threading.Thread):
logscale: bool = False,
parser_16_bit_x2: bool = False,
parser_test: bool = False,
parser_complex_ascii: bool = False,
):
super().__init__(daemon=True)
self._port_path = port_path
@ -44,9 +46,12 @@ class SweepReader(threading.Thread):
self._logscale = bool(logscale)
self._parser_16_bit_x2 = bool(parser_16_bit_x2)
self._parser_test = bool(parser_test)
self._parser_complex_ascii = bool(parser_complex_ascii)
self._src: SerialLineSource | None = None
def _build_parser(self):
if self._parser_complex_ascii:
return ComplexAsciiSweepParser(), SweepAssembler(fancy=self._fancy, apply_inversion=False)
if self._parser_test:
return ParserTestStreamParser(), SweepAssembler(fancy=self._fancy, apply_inversion=False)
if self._parser_16_bit_x2: