ampl parser
This commit is contained in:
@ -10,7 +10,15 @@ from typing import List, Optional, Sequence, Set
|
||||
import numpy as np
|
||||
|
||||
from rfg_adc_plotter.constants import DATA_INVERSION_THRESHOLD, LOG_BASE, LOG_EXP_LIMIT, LOG_POSTSCALER, LOG_SCALER
|
||||
from rfg_adc_plotter.types import ParserEvent, PointEvent, StartEvent, SweepAuxCurves, SweepInfo, SweepPacket
|
||||
from rfg_adc_plotter.types import (
|
||||
ParserEvent,
|
||||
PointEvent,
|
||||
SignalKind,
|
||||
StartEvent,
|
||||
SweepAuxCurves,
|
||||
SweepInfo,
|
||||
SweepPacket,
|
||||
)
|
||||
|
||||
|
||||
def u32_to_i32(value: int) -> int:
|
||||
@ -153,6 +161,7 @@ class LegacyBinaryParser:
|
||||
self._last_step: Optional[int] = None
|
||||
self._seen_points = False
|
||||
self._mode: Optional[str] = None
|
||||
self._current_signal_kind: Optional[SignalKind] = None
|
||||
|
||||
@staticmethod
|
||||
def _u16_at(buf: bytearray, offset: int) -> int:
|
||||
@ -162,16 +171,22 @@ class LegacyBinaryParser:
|
||||
self._mode = "legacy"
|
||||
self._last_step = None
|
||||
self._seen_points = False
|
||||
self._current_signal_kind = None
|
||||
events.append(StartEvent(ch=int(ch)))
|
||||
|
||||
def _emit_tty_start(self, events: List[ParserEvent]) -> None:
|
||||
self._mode = "tty"
|
||||
def _emit_bin_start(self, events: List[ParserEvent], signal_kind: SignalKind) -> None:
|
||||
self._mode = "bin"
|
||||
self._last_step = None
|
||||
self._seen_points = False
|
||||
events.append(StartEvent(ch=0))
|
||||
self._current_signal_kind = signal_kind
|
||||
events.append(StartEvent(ch=0, signal_kind=signal_kind))
|
||||
|
||||
def _emit_tty_start(self, events: List[ParserEvent]) -> None:
|
||||
self._emit_bin_start(events, signal_kind="bin_iq")
|
||||
|
||||
def _emit_legacy_point(self, events: List[ParserEvent], step: int, value_word_hi: int, value_word_lo: int, ch: int) -> None:
|
||||
self._mode = "legacy"
|
||||
self._current_signal_kind = None
|
||||
if self._seen_points and self._last_step is not None and step <= self._last_step:
|
||||
events.append(StartEvent(ch=int(ch)))
|
||||
self._seen_points = True
|
||||
@ -179,12 +194,23 @@ class LegacyBinaryParser:
|
||||
value = u32_to_i32((int(value_word_hi) << 16) | int(value_word_lo))
|
||||
events.append(PointEvent(ch=int(ch), x=int(step), y=float(value)))
|
||||
|
||||
def _emit_tty_point(self, events: List[ParserEvent], step: int, ch_1_word: int, ch_2_word: int) -> None:
|
||||
self._mode = "tty"
|
||||
def _prepare_bin_point(self, events: List[ParserEvent], step: int, signal_kind: SignalKind) -> None:
|
||||
self._mode = "bin"
|
||||
if self._current_signal_kind != signal_kind:
|
||||
if self._seen_points:
|
||||
events.append(StartEvent(ch=0, signal_kind=signal_kind))
|
||||
self._last_step = None
|
||||
self._seen_points = False
|
||||
self._current_signal_kind = signal_kind
|
||||
if self._seen_points and self._last_step is not None and step <= self._last_step:
|
||||
events.append(StartEvent(ch=0))
|
||||
events.append(StartEvent(ch=0, signal_kind=signal_kind))
|
||||
self._last_step = None
|
||||
self._seen_points = False
|
||||
self._seen_points = True
|
||||
self._last_step = int(step)
|
||||
|
||||
def _emit_tty_point(self, events: List[ParserEvent], step: int, ch_1_word: int, ch_2_word: int) -> None:
|
||||
self._prepare_bin_point(events, step=int(step), signal_kind="bin_iq")
|
||||
ch_1 = u16_to_i16(int(ch_1_word))
|
||||
ch_2 = u16_to_i16(int(ch_2_word))
|
||||
events.append(
|
||||
@ -193,6 +219,19 @@ class LegacyBinaryParser:
|
||||
x=int(step),
|
||||
y=tty_ch_pair_to_sweep(ch_1, ch_2),
|
||||
aux=(float(ch_1), float(ch_2)),
|
||||
signal_kind="bin_iq",
|
||||
)
|
||||
)
|
||||
|
||||
def _emit_logdet_point(self, events: List[ParserEvent], step: int, value_word: int) -> None:
|
||||
self._prepare_bin_point(events, step=int(step), signal_kind="bin_logdet")
|
||||
value = u16_to_i16(int(value_word))
|
||||
events.append(
|
||||
PointEvent(
|
||||
ch=0,
|
||||
x=int(step),
|
||||
y=float(value),
|
||||
signal_kind="bin_logdet",
|
||||
)
|
||||
)
|
||||
|
||||
@ -210,6 +249,7 @@ class LegacyBinaryParser:
|
||||
is_tty_start = (w0 == 0x000A and w1 == 0xFFFF and w2 == 0xFFFF and w3 == 0xFFFF)
|
||||
is_legacy_point = (self._buf[6] == 0x0A and w0 != 0xFFFF)
|
||||
is_tty_point = (w0 == 0x000A and w1 != 0xFFFF)
|
||||
is_logdet_point = (w0 == 0x001A and w3 == 0x0000)
|
||||
|
||||
if is_legacy_start:
|
||||
self._emit_legacy_start(events, ch=int(self._buf[7]))
|
||||
@ -221,19 +261,44 @@ class LegacyBinaryParser:
|
||||
del self._buf[:8]
|
||||
continue
|
||||
|
||||
if is_logdet_point:
|
||||
self._emit_logdet_point(events, step=int(w1), value_word=int(w2))
|
||||
del self._buf[:8]
|
||||
continue
|
||||
|
||||
if self._mode == "legacy":
|
||||
if is_legacy_point:
|
||||
self._emit_legacy_point(events, step=int(w0), value_word_hi=int(w1), value_word_lo=int(w2), ch=int(self._buf[7]))
|
||||
self._emit_legacy_point(
|
||||
events,
|
||||
step=int(w0),
|
||||
value_word_hi=int(w1),
|
||||
value_word_lo=int(w2),
|
||||
ch=int(self._buf[7]),
|
||||
)
|
||||
del self._buf[:8]
|
||||
continue
|
||||
if is_tty_point and (not is_legacy_point):
|
||||
self._emit_tty_point(events, step=int(w1), ch_1_word=int(w2), ch_2_word=int(w3))
|
||||
del self._buf[:8]
|
||||
continue
|
||||
del self._buf[:1]
|
||||
continue
|
||||
|
||||
if self._mode == "tty":
|
||||
if self._mode == "bin":
|
||||
if is_tty_point:
|
||||
self._emit_tty_point(events, step=int(w1), ch_1_word=int(w2), ch_2_word=int(w3))
|
||||
del self._buf[:8]
|
||||
continue
|
||||
if is_legacy_point and (not is_tty_point):
|
||||
self._emit_legacy_point(
|
||||
events,
|
||||
step=int(w0),
|
||||
value_word_hi=int(w1),
|
||||
value_word_lo=int(w2),
|
||||
ch=int(self._buf[7]),
|
||||
)
|
||||
del self._buf[:8]
|
||||
continue
|
||||
del self._buf[:1]
|
||||
continue
|
||||
|
||||
@ -245,7 +310,13 @@ class LegacyBinaryParser:
|
||||
continue
|
||||
|
||||
if is_legacy_point and (not is_tty_point):
|
||||
self._emit_legacy_point(events, step=int(w0), value_word_hi=int(w1), value_word_lo=int(w2), ch=int(self._buf[7]))
|
||||
self._emit_legacy_point(
|
||||
events,
|
||||
step=int(w0),
|
||||
value_word_hi=int(w1),
|
||||
value_word_lo=int(w2),
|
||||
ch=int(self._buf[7]),
|
||||
)
|
||||
del self._buf[:8]
|
||||
continue
|
||||
|
||||
@ -454,6 +525,7 @@ class SweepAssembler:
|
||||
self._aux_1: list[float] = []
|
||||
self._aux_2: list[float] = []
|
||||
self._cur_channel: Optional[int] = None
|
||||
self._cur_signal_kind: Optional[SignalKind] = None
|
||||
self._cur_channels: set[int] = set()
|
||||
|
||||
def _reset_current(self) -> None:
|
||||
@ -462,6 +534,7 @@ class SweepAssembler:
|
||||
self._aux_1.clear()
|
||||
self._aux_2.clear()
|
||||
self._cur_channel = None
|
||||
self._cur_signal_kind = None
|
||||
self._cur_channels.clear()
|
||||
|
||||
def _scatter(self, xs: Sequence[int], values: Sequence[float], width: int) -> np.ndarray:
|
||||
@ -500,9 +573,11 @@ class SweepAssembler:
|
||||
self._reset_current()
|
||||
if event.ch is not None:
|
||||
self._cur_channel = int(event.ch)
|
||||
self._cur_signal_kind = event.signal_kind
|
||||
return packet
|
||||
|
||||
point_ch = int(event.ch)
|
||||
point_signal_kind = event.signal_kind
|
||||
packet: Optional[SweepPacket] = None
|
||||
if self._cur_channel is None:
|
||||
self._cur_channel = point_ch
|
||||
@ -513,6 +588,12 @@ class SweepAssembler:
|
||||
packet = self.finalize_current()
|
||||
self._reset_current()
|
||||
self._cur_channel = point_ch
|
||||
if self._cur_signal_kind != point_signal_kind:
|
||||
if self._xs:
|
||||
packet = self.finalize_current()
|
||||
self._reset_current()
|
||||
self._cur_channel = point_ch
|
||||
self._cur_signal_kind = point_signal_kind
|
||||
|
||||
self._cur_channels.add(point_ch)
|
||||
self._xs.append(int(event.x))
|
||||
@ -581,6 +662,7 @@ class SweepAssembler:
|
||||
"sweep": self._sweep_idx,
|
||||
"ch": ch_primary,
|
||||
"chs": ch_list,
|
||||
"signal_kind": self._cur_signal_kind,
|
||||
"n_valid": n_valid,
|
||||
"min": vmin,
|
||||
"max": vmax,
|
||||
|
||||
@ -43,13 +43,17 @@ def _looks_like_legacy_8byte_stream(data: bytes) -> bool:
|
||||
min_matches = max(_LEGACY_STREAM_MIN_RECORDS, int(blocks * _LEGACY_STREAM_MIN_MATCH_RATIO))
|
||||
matched_steps_legacy: list[int] = []
|
||||
matched_steps_tty: list[int] = []
|
||||
matched_steps_logdet: list[int] = []
|
||||
for block_idx in range(blocks):
|
||||
base = offset + (block_idx * 8)
|
||||
if (_u16le_at(buf, base + 6) & 0x00FF) != 0x000A:
|
||||
w0 = _u16le_at(buf, base)
|
||||
w1 = _u16le_at(buf, base + 2)
|
||||
w3 = _u16le_at(buf, base + 6)
|
||||
if w0 == 0x000A and w1 != 0xFFFF:
|
||||
matched_steps_tty.append(w1)
|
||||
elif w0 == 0x001A and w3 == 0x0000:
|
||||
matched_steps_logdet.append(w1)
|
||||
continue
|
||||
matched_steps_legacy.append(_u16le_at(buf, base))
|
||||
|
||||
@ -70,6 +74,14 @@ def _looks_like_legacy_8byte_stream(data: bytes) -> bool:
|
||||
if monotonic_or_reset >= max(4, len(matched_steps_tty) - 4):
|
||||
return True
|
||||
|
||||
if len(matched_steps_logdet) >= tty_min_matches:
|
||||
monotonic_or_reset = 0
|
||||
for prev_step, next_step in zip(matched_steps_logdet, matched_steps_logdet[1:]):
|
||||
if next_step == (prev_step + 1) or next_step <= 2:
|
||||
monotonic_or_reset += 1
|
||||
if monotonic_or_reset >= max(4, len(matched_steps_logdet) - 4):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user