Compare commits

..

No commits in common. "3369bb290a9ad434d3b4f2ce8240dca3015b4169" and "2f7b9fc1ebb65a8f5e566e71d1134211d2ea304e" have entirely different histories.

View File

@ -1,14 +1,13 @@
# %% imports # %% imports
import sys import sys
from pathlib import Path from pathlib import Path
from typing import Callable, List, Literal, Tuple from typing import Callable, List, Tuple
import matplotlib as mpl import matplotlib as mpl
import numpy as np import numpy as np
import xarray as xr import xarray as xr
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
from matplotlib.lines import Line2D
from matplotlib.ticker import EngFormatter from matplotlib.ticker import EngFormatter
from numpy import typing as npt from numpy import typing as npt
from PySide6.QtGui import QAction, QKeySequence from PySide6.QtGui import QAction, QKeySequence
@ -35,23 +34,20 @@ DEFAULT_CONFIG = dict(
class PlotWidget(QWidget): class PlotWidget(QWidget):
traces: List[Tuple[int | str]] enabled_ports: List[Tuple[int | str]]
lines: List[Line2D]
def __init__(self, type_: str = "logmag"): def __init__(self):
super().__init__() super().__init__()
self.traces = [(1, 1)] self.enabled_ports = [(1, 1)]
layout = QVBoxLayout() layout = QVBoxLayout()
self.setLayout(layout) self.setLayout(layout)
self.fig = plt.Figure(figsize=(5, 4), dpi=100, tight_layout=True) self.fig = plt.Figure(figsize=(5, 4), dpi=100, tight_layout=True)
self.ax = self.fig.add_subplot(111) self.ax = self.fig.add_subplot(111)
self.set_plot_type(type_) self.setup_logmag()
self.lines = [ # self.setup_smith()
self.ax.plot([np.nan], [np.nan], label="$S_{" + str(m) + str(n) + "}$")[0] for m, n in self.traces
]
self.ax.legend(loc="upper right") self.ax.legend(loc="upper right")
canvas = FigureCanvasQTAgg(self.fig) canvas = FigureCanvasQTAgg(self.fig)
@ -61,37 +57,6 @@ class PlotWidget(QWidget):
# toolbar.addAction("blah") # toolbar.addAction("blah")
# self.addToolBar(toolbar) # self.addToolBar(toolbar)
def set_plot_type(
self,
type_: Literal["logmag", "phase", "vswr", "smith"],
sweep_type: Literal["frequency", "time"] = "frequency",
) -> None:
if sweep_type != "frequency":
raise NotImplementedError("Only frequency sweeps are currently supported")
if type_ == "logmag":
self.setup_logmag()
elif type_ == "phase":
self.setup_phase()
elif type_ == "vswr":
self.setup_vswr()
elif type_ == "smith":
self.setup_smith()
else:
raise ValueError(f"Unknown plot type: {type_}")
self._plot_type = type_
def update_plot(self, data: xr.DataArray):
if self._plot_type == "logmag":
self.update_logmag(data)
elif self._plot_type == "phase":
self.update_phase(data)
elif self._plot_type == "vswr":
self.update_vswr(data)
elif self._plot_type == "smith":
self.update_smith(data)
def setup_rect(self) -> None: def setup_rect(self) -> None:
self.ax.grid(True) self.ax.grid(True)
self.ax.xaxis.set_major_formatter(EngFormatter()) self.ax.xaxis.set_major_formatter(EngFormatter())
@ -99,11 +64,11 @@ class PlotWidget(QWidget):
def update_rect(self, data: xr.DataArray, func: Callable[[npt.ArrayLike], npt.ArrayLike]) -> None: def update_rect(self, data: xr.DataArray, func: Callable[[npt.ArrayLike], npt.ArrayLike]) -> None:
self.ax.set_xlim(data["frequency"].min().data, data["frequency"].max().data) self.ax.set_xlim(data["frequency"].min().data, data["frequency"].max().data)
for ii, (m, n) in enumerate(self.traces): # remove old lines
self.lines[ii].set_xdata(data["frequency"]) for line in self.ax.lines:
self.lines[ii].set_ydata(func(data.sel(m=m, n=n))) line.remove()
for m, n in self.enabled_ports:
self.fig.canvas.draw() self.ax.plot(data["frequency"], func(data.sel(m=m, n=n)))
def setup_logmag(self, ylim: List[float] = [-30, 30]) -> None: def setup_logmag(self, ylim: List[float] = [-30, 30]) -> None:
self.setup_rect() self.setup_rect()
@ -138,12 +103,12 @@ class PlotWidget(QWidget):
rf_plt.smith(ax=self.ax, smithR=1, chart_type="z", draw_vswr=None) rf_plt.smith(ax=self.ax, smithR=1, chart_type="z", draw_vswr=None)
def update_smith(self, data: xr.DataArray) -> None: def update_smith(self, data: xr.DataArray) -> None:
for ii, (m, n) in enumerate(self.traces): # remove old lines
for line in self.ax.lines:
line.remove()
for m, n in self.enabled_ports:
sel = data.sel(m=m, n=n) sel = data.sel(m=m, n=n)
self.lines[ii].set_xdata(sel.real) self.ax.plot(sel.real, sel.imag)
self.lines[ii].set_ydata(sel.imag)
self.fig.canvas.draw()
# Subclass QMainWindow to customize your application's main window # Subclass QMainWindow to customize your application's main window
@ -151,8 +116,6 @@ class MainWindow(QMainWindow):
config_path: Path | None config_path: Path | None
# device: Charon # device: Charon
plots: List[PlotWidget]
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@ -194,31 +157,22 @@ class MainWindow(QMainWindow):
menu_calibration = QMenu("&Calibration") menu_calibration = QMenu("&Calibration")
menubar.addMenu(menu_calibration) menubar.addMenu(menu_calibration)
menu_simulation = QMenu("Si&mulation")
menubar.addMenu(menu_simulation)
action_generate_data = QAction("&Generate data", self)
menu_file.addAction(action_generate_data)
action_generate_data.triggered.connect(self.generate_sim_data)
action_generate_data.setShortcut(QKeySequence("Ctrl+G"))
# Content # Content
window_layout = QVBoxLayout() window_layout = QVBoxLayout()
prog_sweep = QProgressBar() prog_sweep = QProgressBar()
prog_sweep.setMinimum(0) prog_sweep.setMinimum(0)
prog_sweep.setMaximum(100) prog_sweep.setMaximum(100)
prog_sweep.setFormat("%v / %m") prog_sweep.setTextVisible(False)
# prog_sweep.setTextVisible(False)
prog_sweep.setValue(50) prog_sweep.setValue(50)
window_layout.addWidget(prog_sweep) window_layout.addWidget(prog_sweep)
# window_widget.se # window_widget.se
plot_layout = QVBoxLayout() plot_layout = QVBoxLayout()
# TODO: handle plots properly # TODO: handle plots properly
self.plots = [] for i in range(2):
for type_ in ["logmag", "phase", "vswr", "smith"]: plot0 = PlotWidget()
self.plots.append(PlotWidget(type_=type_)) plot_layout.addWidget(plot0)
plot_layout.addWidget(self.plots[-1])
plot_widget = QWidget() plot_widget = QWidget()
plot_widget.setLayout(plot_layout) plot_widget.setLayout(plot_layout)
window_layout.addWidget(plot_widget) window_layout.addWidget(plot_widget)
@ -246,18 +200,6 @@ class MainWindow(QMainWindow):
print("loading config") print("loading config")
# TODO: load config # TODO: load config
def generate_sim_data(self) -> None:
coords = {"frequency": np.linspace(1e9, 2e9, 101), "m": [1], "n": [1]}
shape = tuple(len(v) for v in coords.values())
data = xr.DataArray(
((-1 + 2 * np.random.rand(*shape)) + 1j * (-1 + 2 * np.random.rand(*shape))) / np.sqrt(2),
dims=list(coords.keys()),
coords=coords,
)
for plot in self.plots:
plot.update_plot(data)
def main() -> None: def main() -> None:
app = QApplication(sys.argv) app = QApplication(sys.argv)