diff --git a/src/mcltspice/raw_parser.py b/src/mcltspice/raw_parser.py index f9b8a27..13742b2 100644 --- a/src/mcltspice/raw_parser.py +++ b/src/mcltspice/raw_parser.py @@ -52,6 +52,19 @@ class RawFile: return arr return None + def resolve_index(self, name: str) -> int | None: + """Return a variable's data-row index by exact name (case-insensitive). + + Unlike get_variable (partial match, returns the data array), this does an + exact case-insensitive name match and returns the integer row index into + self.data, or None if there's no exact match. + """ + name_lower = name.lower() + for var in self.variables: + if var.name.lower() == name_lower: + return var.index + return None + def get_time(self, run: int | None = None) -> np.ndarray | None: """Get the time axis (for transient analysis).""" return self.get_variable("time", run=run) diff --git a/src/mcltspice/server.py b/src/mcltspice/server.py index acfb7c3..f2aef06 100644 --- a/src/mcltspice/server.py +++ b/src/mcltspice/server.py @@ -1272,17 +1272,10 @@ async def tune_circuit( if raw is None: return {"error": "No raw data from simulation", "params_used": effective_params} - # Find the signal variable - sig_idx = None - time_idx = None - freq_idx = None - for var in raw.variables: - if var.name.lower() == signal.lower(): - sig_idx = var.index - if var.name.lower() == "time": - time_idx = var.index - if var.name.lower() == "frequency": - freq_idx = var.index + # Find the signal variable (exact, case-insensitive) + sig_idx = raw.resolve_index(signal) + time_idx = raw.resolve_index("time") + freq_idx = raw.resolve_index("frequency") if sig_idx is None: available = [v.name for v in raw.variables] @@ -1513,19 +1506,18 @@ async def plot_waveform( signal_list = signals if signals else [signal] is_multi = len(signal_list) > 1 - # Resolve all signal names (case-insensitive) + # Resolve all signal names (exact, case-insensitive) sig_names = [v.name for v in raw_data.variables] sig_lower = {s.lower(): s for s in sig_names} resolved: list[tuple[str, int]] = [] # (actual_name, index) for s in signal_list: - actual = sig_lower.get(s.lower()) - if actual is None: + idx = raw_data.resolve_index(s) + if idx is None: return { "error": f"Signal '{s}' not found", "available_signals": sig_names, } - idx = next(i for i, v in enumerate(raw_data.variables) if v.name == actual) - resolved.append((actual, idx)) + resolved.append((sig_lower[s.lower()], idx)) # Get x-axis data (time or frequency) x_var = raw_data.variables[0]