From a77874c97290ae94fa820c973c2fc6577cf447a7 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Tue, 10 Feb 2026 13:20:47 -0700 Subject: [PATCH] Fix binary parsers for UTF-16 headers and AC analysis - Handle UTF-16 LE encoded .raw file headers (Windows/Wine output) - Fix mixed-precision transient data: float64 time + float32 signals - Fix AC analysis: all variables stored as complex128, not mixed - Fix schematic parser losing components at SYMBOL boundaries - Use proper atan2 for phase calculation, report magnitude in dB --- src/mcp_ltspice/raw_parser.py | 28 +++++++--------------------- src/mcp_ltspice/server.py | 21 ++++++++++++--------- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/src/mcp_ltspice/raw_parser.py b/src/mcp_ltspice/raw_parser.py index d32e6aa..3e5e8d2 100644 --- a/src/mcp_ltspice/raw_parser.py +++ b/src/mcp_ltspice/raw_parser.py @@ -172,28 +172,14 @@ def _parse_binary_data( - Complex AC: frequency (float64) + other vars as (float64, float64) pairs """ if is_complex: - # Complex data (AC analysis): freq as double + complex values - # freq (8 bytes) + (n_vars-1) * (real + imag) = 8 + (n-1)*16 bytes per point - bytes_per_point = 8 + (n_vars - 1) * 16 - expected_bytes = bytes_per_point * points + # Complex data (AC analysis): ALL variables stored as complex128 + # Each value is (real float64, imag float64) = 16 bytes + bytes_per_point = n_vars * 16 + actual_points = len(data) // bytes_per_point - if len(data) >= expected_bytes: - result = np.zeros((n_vars, points), dtype=np.complex128) - offset = 0 - - for p in range(points): - # Frequency as double (real) - result[0, p] = struct.unpack(" 0 else -200 + for x in sampled + ], + "phase_degrees": [ + math.degrees(math.atan2(x.imag, x.real)) for x in sampled ], - "real": [x.real for x in sampled], - "imag": [x.imag for x in sampled], } else: result["signals"][name] = {"values": sampled.tolist()}