ch1 ch2 new
This commit is contained in:
@ -286,6 +286,28 @@ class LegacyBinaryParser:
|
||||
)
|
||||
)
|
||||
|
||||
def _emit_secondary_point(
|
||||
self,
|
||||
events: List[ParserEvent],
|
||||
step: int,
|
||||
ch_1_word: int,
|
||||
ch_2_word: int,
|
||||
) -> None:
|
||||
self._mode = "bin"
|
||||
self._current_signal_kind = self._current_signal_kind or "bin_iq"
|
||||
ch_1 = u16_to_i16(int(ch_1_word))
|
||||
ch_2 = u16_to_i16(int(ch_2_word))
|
||||
events.append(
|
||||
PointEvent(
|
||||
ch=0,
|
||||
x=int(step),
|
||||
y=0.0,
|
||||
aux=(float(ch_1), float(ch_2)),
|
||||
signal_kind="bin_iq",
|
||||
is_secondary=True,
|
||||
)
|
||||
)
|
||||
|
||||
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))
|
||||
@ -310,8 +332,9 @@ class LegacyBinaryParser:
|
||||
w0 = words[:, 0]
|
||||
w1 = words[:, 1]
|
||||
is_tty_point = (w0 == 0x000A) & (w1 != 0xFFFF)
|
||||
is_sec_point = (w0 == 0x00A8) & (w1 != 0xFFFF)
|
||||
is_legacy_point = (raw[:, 6] == 0x0A) & (w0 != 0xFFFF)
|
||||
valid = is_tty_point
|
||||
valid = is_tty_point | is_sec_point
|
||||
if require_not_legacy:
|
||||
valid = valid & (~is_legacy_point)
|
||||
if valid.size <= 0 or not bool(valid[0]):
|
||||
@ -321,7 +344,15 @@ class LegacyBinaryParser:
|
||||
if valid_count <= 0:
|
||||
return False
|
||||
|
||||
steps = words[:valid_count, 1].astype(np.int64, copy=True)
|
||||
primary_mask = is_tty_point[:valid_count]
|
||||
secondary_mask = is_sec_point[:valid_count]
|
||||
|
||||
primary_indices = np.nonzero(primary_mask)[0]
|
||||
if primary_indices.size <= 0:
|
||||
# No primary records in this block — cannot batch
|
||||
return False
|
||||
|
||||
primary_steps = words[:valid_count, 1][primary_mask].astype(np.int64, copy=True)
|
||||
if self._current_signal_kind != "bin_iq":
|
||||
if self._seen_points:
|
||||
events.append(StartEvent(ch=0, signal_kind="bin_iq"))
|
||||
@ -330,44 +361,72 @@ class LegacyBinaryParser:
|
||||
self._current_signal_kind = "bin_iq"
|
||||
self._reset_tagged_steps()
|
||||
|
||||
if self._seen_points and self._last_step is not None and steps[0] <= int(self._last_step):
|
||||
if self._seen_points and self._last_step is not None and primary_steps[0] <= int(self._last_step):
|
||||
events.append(StartEvent(ch=0, signal_kind="bin_iq"))
|
||||
self._last_step = None
|
||||
self._seen_points = False
|
||||
self._reset_tagged_steps()
|
||||
|
||||
reset_idx = np.nonzero(np.diff(steps) <= 0)[0]
|
||||
take_count = int(reset_idx[0] + 1) if reset_idx.size > 0 else int(steps.size)
|
||||
reset_idx = np.nonzero(np.diff(primary_steps) <= 0)[0]
|
||||
if reset_idx.size > 0:
|
||||
reset_primary_pos = int(reset_idx[0] + 1)
|
||||
if reset_primary_pos < primary_indices.size:
|
||||
take_count = int(primary_indices[reset_primary_pos])
|
||||
else:
|
||||
take_count = valid_count
|
||||
else:
|
||||
take_count = valid_count
|
||||
if take_count <= 0:
|
||||
return False
|
||||
|
||||
primary_mask_take = is_tty_point[:take_count]
|
||||
secondary_mask_take = is_sec_point[:take_count]
|
||||
batch_words = words[:take_count].copy()
|
||||
xs = batch_words[:, 1].astype(np.int64, copy=False)
|
||||
ch_1 = batch_words[:, 2].astype(np.uint16, copy=False).view(np.int16)
|
||||
ch_2 = batch_words[:, 3].astype(np.uint16, copy=False).view(np.int16)
|
||||
del raw
|
||||
del words
|
||||
del w0
|
||||
del w1
|
||||
del self._buf[: take_count * 8]
|
||||
|
||||
ch_1_i64 = ch_1.astype(np.int64)
|
||||
ch_2_i64 = ch_2.astype(np.int64)
|
||||
ys = ((ch_1_i64 * ch_1_i64) + (ch_2_i64 * ch_2_i64)).astype(np.float32)
|
||||
self._mode = "bin"
|
||||
self._seen_points = True
|
||||
self._last_step = int(xs[-1])
|
||||
self._current_signal_kind = "bin_iq"
|
||||
self._reset_tagged_steps()
|
||||
events.append(
|
||||
BatchPointEvent(
|
||||
ch=0,
|
||||
xs=xs,
|
||||
ys=ys,
|
||||
aux=(ch_1.astype(np.float32), ch_2.astype(np.float32)),
|
||||
signal_kind="bin_iq",
|
||||
if np.any(primary_mask_take):
|
||||
p_words = batch_words[primary_mask_take]
|
||||
p_xs = p_words[:, 1].astype(np.int64, copy=False)
|
||||
p_ch1 = p_words[:, 2].astype(np.uint16, copy=False).view(np.int16)
|
||||
p_ch2 = p_words[:, 3].astype(np.uint16, copy=False).view(np.int16)
|
||||
p_ch1_i64 = p_ch1.astype(np.int64)
|
||||
p_ch2_i64 = p_ch2.astype(np.int64)
|
||||
p_ys = ((p_ch1_i64 * p_ch1_i64) + (p_ch2_i64 * p_ch2_i64)).astype(np.float32)
|
||||
self._mode = "bin"
|
||||
self._seen_points = True
|
||||
self._last_step = int(p_xs[-1])
|
||||
self._current_signal_kind = "bin_iq"
|
||||
self._reset_tagged_steps()
|
||||
events.append(
|
||||
BatchPointEvent(
|
||||
ch=0,
|
||||
xs=p_xs,
|
||||
ys=p_ys,
|
||||
aux=(p_ch1.astype(np.float32), p_ch2.astype(np.float32)),
|
||||
signal_kind="bin_iq",
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if np.any(secondary_mask_take):
|
||||
s_words = batch_words[secondary_mask_take]
|
||||
s_xs = s_words[:, 1].astype(np.int64, copy=False)
|
||||
s_ch1 = s_words[:, 2].astype(np.uint16, copy=False).view(np.int16)
|
||||
s_ch2 = s_words[:, 3].astype(np.uint16, copy=False).view(np.int16)
|
||||
events.append(
|
||||
BatchPointEvent(
|
||||
ch=0,
|
||||
xs=s_xs,
|
||||
ys=np.zeros(s_xs.size, dtype=np.float32),
|
||||
aux=(s_ch1.astype(np.float32), s_ch2.astype(np.float32)),
|
||||
signal_kind="bin_iq",
|
||||
is_secondary=True,
|
||||
)
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
def feed(self, data: bytes) -> List[ParserEvent]:
|
||||
@ -387,6 +446,7 @@ class LegacyBinaryParser:
|
||||
is_tty_tagged_low_point = (w0 == 0x00A3 and w1 != 0xFFFF)
|
||||
is_tty_tagged_high_point = (w0 == 0x00A4 and w1 != 0xFFFF)
|
||||
is_logdet_point = (w0 == 0x001A and w3 == 0x0000)
|
||||
is_secondary_point = (w0 == 0x00A8 and w1 != 0xFFFF)
|
||||
|
||||
if is_legacy_start:
|
||||
self._emit_legacy_start(events, ch=int(self._buf[7]))
|
||||
@ -404,7 +464,7 @@ class LegacyBinaryParser:
|
||||
continue
|
||||
|
||||
if self._mode == "legacy":
|
||||
if is_tty_point and (not is_legacy_point) and self._try_emit_tty_batch(events, require_not_legacy=True):
|
||||
if (is_tty_point or is_secondary_point) and (not is_legacy_point) and self._try_emit_tty_batch(events, require_not_legacy=True):
|
||||
continue
|
||||
if is_legacy_point:
|
||||
self._emit_legacy_point(
|
||||
@ -440,11 +500,15 @@ class LegacyBinaryParser:
|
||||
)
|
||||
del self._buf[:8]
|
||||
continue
|
||||
if is_secondary_point and (not is_legacy_point):
|
||||
self._emit_secondary_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 == "bin":
|
||||
if is_tty_point and self._try_emit_tty_batch(events, require_not_legacy=False):
|
||||
if (is_tty_point or is_secondary_point) and self._try_emit_tty_batch(events, require_not_legacy=False):
|
||||
continue
|
||||
if is_tty_point:
|
||||
self._emit_tty_point(events, step=int(w1), ch_1_word=int(w2), ch_2_word=int(w3))
|
||||
@ -470,6 +534,10 @@ class LegacyBinaryParser:
|
||||
)
|
||||
del self._buf[:8]
|
||||
continue
|
||||
if is_secondary_point:
|
||||
self._emit_secondary_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,
|
||||
@ -485,9 +553,13 @@ class LegacyBinaryParser:
|
||||
|
||||
# Mode is still unknown. Accept only unambiguous point shapes to avoid
|
||||
# jumping between tty and legacy interpretations on coincidental bytes.
|
||||
if is_tty_point and (not is_legacy_point):
|
||||
if (is_tty_point or is_secondary_point) and (not is_legacy_point):
|
||||
if self._try_emit_tty_batch(events, require_not_legacy=True):
|
||||
continue
|
||||
if is_secondary_point:
|
||||
self._emit_secondary_point(events, step=int(w1), ch_1_word=int(w2), ch_2_word=int(w3))
|
||||
del self._buf[:8]
|
||||
continue
|
||||
self._emit_tty_point(events, step=int(w1), ch_1_word=int(w2), ch_2_word=int(w3))
|
||||
del self._buf[:8]
|
||||
continue
|
||||
@ -514,6 +586,11 @@ class LegacyBinaryParser:
|
||||
del self._buf[:8]
|
||||
continue
|
||||
|
||||
if is_secondary_point and (not is_legacy_point):
|
||||
self._emit_secondary_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,
|
||||
@ -737,10 +814,18 @@ class SweepAssembler:
|
||||
self._tagged_high_ys: list[float] = []
|
||||
self._tagged_high_aux_1: list[float] = []
|
||||
self._tagged_high_aux_2: list[float] = []
|
||||
self._secondary_xs: list[int] = []
|
||||
self._secondary_aux_1: list[float] = []
|
||||
self._secondary_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_secondary_current(self) -> None:
|
||||
self._secondary_xs.clear()
|
||||
self._secondary_aux_1.clear()
|
||||
self._secondary_aux_2.clear()
|
||||
|
||||
def _reset_tagged_current(self) -> None:
|
||||
self._tagged_low_xs.clear()
|
||||
self._tagged_low_ys.clear()
|
||||
@ -757,6 +842,7 @@ class SweepAssembler:
|
||||
self._aux_1.clear()
|
||||
self._aux_2.clear()
|
||||
self._reset_tagged_current()
|
||||
self._reset_secondary_current()
|
||||
self._cur_channel = None
|
||||
self._cur_signal_kind = None
|
||||
self._cur_channels.clear()
|
||||
@ -870,6 +956,30 @@ class SweepAssembler:
|
||||
self._aux_2.extend(aux_2_arr[:aux_width].tolist())
|
||||
return packet
|
||||
|
||||
def _consume_secondary_point(self, event: PointEvent) -> None:
|
||||
self._secondary_xs.append(int(event.x))
|
||||
if event.aux is not None:
|
||||
self._secondary_aux_1.append(float(event.aux[0]))
|
||||
self._secondary_aux_2.append(float(event.aux[1]))
|
||||
|
||||
def _consume_secondary_batch(self, event: BatchPointEvent) -> None:
|
||||
xs_arr = np.asarray(event.xs, dtype=np.int64).reshape(-1)
|
||||
width = xs_arr.size
|
||||
if width <= 0:
|
||||
return
|
||||
self._secondary_xs.extend(xs_arr.tolist())
|
||||
if event.aux is not None:
|
||||
try:
|
||||
aux_1, aux_2 = event.aux
|
||||
aux_1_arr = np.asarray(aux_1, dtype=np.float32).reshape(-1)
|
||||
aux_2_arr = np.asarray(aux_2, dtype=np.float32).reshape(-1)
|
||||
aux_width = min(width, aux_1_arr.size, aux_2_arr.size)
|
||||
except Exception:
|
||||
aux_width = 0
|
||||
if aux_width > 0:
|
||||
self._secondary_aux_1.extend(aux_1_arr[:aux_width].tolist())
|
||||
self._secondary_aux_2.extend(aux_2_arr[:aux_width].tolist())
|
||||
|
||||
def consume(self, event: ParserEvent) -> Optional[SweepPacket]:
|
||||
if isinstance(event, StartEvent):
|
||||
packet = self.finalize_current()
|
||||
@ -879,8 +989,15 @@ class SweepAssembler:
|
||||
self._cur_signal_kind = event.signal_kind
|
||||
return packet
|
||||
if isinstance(event, BatchPointEvent):
|
||||
if event.is_secondary:
|
||||
self._consume_secondary_batch(event)
|
||||
return None
|
||||
return self._consume_batch(event)
|
||||
|
||||
if isinstance(event, PointEvent) and event.is_secondary:
|
||||
self._consume_secondary_point(event)
|
||||
return None
|
||||
|
||||
point_ch = int(event.ch)
|
||||
point_signal_kind = event.signal_kind
|
||||
packet: Optional[SweepPacket] = None
|
||||
@ -1015,4 +1132,14 @@ class SweepAssembler:
|
||||
}
|
||||
if do1_tagged_payload is not None:
|
||||
info["_do1_tagged_payload"] = do1_tagged_payload
|
||||
if (
|
||||
self._secondary_xs
|
||||
and self._secondary_aux_1
|
||||
and self._secondary_aux_2
|
||||
and len(self._secondary_aux_1) == len(self._secondary_xs)
|
||||
):
|
||||
info["_secondary_payload"] = {
|
||||
"ch1": self._scatter(self._secondary_xs, self._secondary_aux_1, target_width),
|
||||
"ch2": self._scatter(self._secondary_xs, self._secondary_aux_2, target_width),
|
||||
}
|
||||
return (sweep, info, aux_curves)
|
||||
|
||||
Reference in New Issue
Block a user