diff --git a/pyrelacs/ui/mainwindow.py b/pyrelacs/ui/mainwindow.py index a9ade22..a4f0a6a 100644 --- a/pyrelacs/ui/mainwindow.py +++ b/pyrelacs/ui/mainwindow.py @@ -22,6 +22,7 @@ from pyrelacs.worker import Worker from pyrelacs.repros.repros import Repro from pyrelacs.util.logging import config_logging from pyrelacs.ui.about import AboutDialog +from pyrelacs.ui.plots.calibration import CalibrationPlot log = config_logging() _root = path(__file__).parent.parent @@ -37,14 +38,15 @@ class PyRelacs(QMainWindow): ) # Ensure icons are displayed with text self.setWindowTitle("PyRelacs") - self.beat_plot = pg.PlotWidget() - self.power_plot = pg.PlotWidget() + self.figure = pg.GraphicsLayoutWidget() - self.beat_plot.addLegend() - self.power_plot.addLegend() - self.beat_plot.setBackground("w") - self.power_plot.setBackground("w") - self.power_plot.setLogMode(x=False, y=True) + filename = path.joinpath(path.cwd(), "data.nix") + if filename.exists(): + self.nix_file = nix.File.open(str(filename), nix.FileMode.ReadOnly) + else: + self.nix_file = nix.File.open(str(filename), nix.FileMode.Overwrite) + + self.calibration_plot = CalibrationPlot(self.figure, self.nix_file) self.threadpool = QThreadPool() self.repros = Repro() @@ -59,20 +61,13 @@ class PyRelacs(QMainWindow): self.create_toolbars() layout = QGridLayout() - layout.addWidget(self.beat_plot, 0, 0, 1, 2) - layout.addWidget(self.power_plot, 1, 0, 1, 2) + layout.addWidget(self.figure, 0, 0, 2, 2) layout.addWidget(self.text, 2, 0, 1, 2) widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget) - filename = path.joinpath(path.cwd(), "data.nix") - if filename.exists(): - self.nix_file = nix.File.open(str(filename), nix.FileMode.ReadOnly) - else: - self.nix_file = nix.File.open(str(filename), nix.FileMode.Overwrite) - def create_actions(self): self._rlx_exitaction = QAction(QIcon(":/icons/exit.png"), "Exit", self) self._rlx_exitaction.setStatusTip("Close relacs") @@ -103,7 +98,7 @@ class PyRelacs(QMainWindow): ) self._daq_calibaction.setStatusTip("Calibrate the attenuator device") # self._daq_calibaction.setShortcut(QKeySequence("Alt+d")) - self._daq_calibaction.triggered.connect(self.plot_calibration) + self._daq_calibaction.triggered.connect(self.calibration_plot.plot) self.create_menu() def create_menu(self): @@ -166,73 +161,7 @@ class PyRelacs(QMainWindow): self.plot_calibration_button = QPushButton("Plot Calibration") self.plot_calibration_button.setCheckable(True) - self.plot_calibration_button.clicked.connect(self.plot_calibration) - - def plot_calibration(self): - def decibel(power, ref_power=1.0, min_power=1e-20): - """Transform power to decibel relative to ref_power. - - \\[ decibel = 10 \\cdot \\log_{10}(power/ref\\_power) \\] - Power values smaller than `min_power` are set to `-np.inf`. - - Parameters - ---------- - power: float or array - Power values, for example from a power spectrum or spectrogram. - ref_power: float or None or 'peak' - Reference power for computing decibel. - If set to `None` or 'peak', the maximum power is used. - min_power: float - Power values smaller than `min_power` are set to `-np.inf`. - - Returns - ------- - decibel_psd: array - Power values in decibel relative to `ref_power`. - """ - if np.isscalar(power): - tmp_power = np.array([power]) - decibel_psd = np.array([power]) - else: - tmp_power = power - decibel_psd = power.copy() - if ref_power is None or ref_power == "peak": - ref_power = np.max(decibel_psd) - decibel_psd[tmp_power <= min_power] = float("-inf") - decibel_psd[tmp_power > min_power] = 10.0 * np.log10( - decibel_psd[tmp_power > min_power] / ref_power - ) - if np.isscalar(power): - return decibel_psd[0] - else: - return decibel_psd - - block = self.nix_file.blocks[0] - colors = ["red", "green", "blue", "black", "yellow"] - for i, (stim, fish) in enumerate( - zip(list(block.data_arrays)[::2], list(block.data_arrays)[1::2]) - ): - beat = stim[:] + fish[:] - beat_squared = beat**2 - - f, powerspec = welch( - beat_squared, - window="flattop", - fs=40_000.0, - nperseg=100_000, - ) - - peaks = find_peaks(powerspec, prominence=0.001)[0] - pen = pg.mkPen(colors[i]) - - self.beat_plot.plot( - np.arange(0, len(beat)) / 40_000.0, - beat, - pen=pen, - name=stim.name, - ) - self.power_plot.plot(f, powerspec, pen=pen, name=stim.name) - self.power_plot.plot(f[peaks], powerspec[peaks], pen=None, symbol="x") + self.plot_calibration_button.clicked.connect(self.calibration_plot.plot) def connect_dac(self): devices = uldaq.get_daq_device_inventory(uldaq.InterfaceType.USB)