Compare commits

..

3 Commits

3 changed files with 43 additions and 13 deletions

View File

@ -1,10 +1,17 @@
from typing import Tuple from typing import Tuple
import numpy as np import numpy as np
from IPython import embed from IPython import embed
from pyqtgraph.Qt.QtCore import QMutex
class CircBuffer: class CircBuffer:
def __init__(self, size: int, channels: int = 1, samplerate: int = 40_000): def __init__(
self,
size: int,
mutex: QMutex,
channels: int = 1,
samplerate: int = 40_000,
):
self.__size = size self.__size = size
self.__channels = channels self.__channels = channels
self.__samplereate = samplerate self.__samplereate = samplerate
@ -16,7 +23,7 @@ class CircBuffer:
self.__is_full = [False for i in range(channels)] self.__is_full = [False for i in range(channels)]
self.__totalcount = [0 for i in range(channels)] self.__totalcount = [0 for i in range(channels)]
self.__overflows = [0 for i in range(channels)] self.__overflows = [0 for i in range(channels)]
self.__read_increment = samplerate * 0.1 self.mutex = mutex
@property @property
def size(self): def size(self):
@ -40,6 +47,7 @@ class CircBuffer:
return self.__index[channel] return self.__index[channel]
def append(self, item, channel: int = 0): def append(self, item, channel: int = 0):
self.mutex.lock()
self.__buffer[channel, self.write_index(channel)] = item self.__buffer[channel, self.write_index(channel)] = item
self.__index[channel] = (self.write_index(channel) + 1) % self.__size self.__index[channel] = (self.write_index(channel) + 1) % self.__size
self.__totalcount[channel] += 1 self.__totalcount[channel] += 1
@ -49,6 +57,7 @@ class CircBuffer:
if self.__index[channel] == 0: if self.__index[channel] == 0:
self.__is_full[channel] = True self.__is_full[channel] = True
self.__overflows[channel] += 1 self.__overflows[channel] += 1
self.mutex.unlock()
def get_all(self, channel: int = 0): def get_all(self, channel: int = 0):
""" """

View File

@ -2,7 +2,7 @@ import time
from pathlib import Path as path from pathlib import Path as path
from PyQt6.QtGui import QAction, QIcon, QKeySequence from PyQt6.QtGui import QAction, QIcon, QKeySequence
from PyQt6.QtCore import Qt, QSize, QThreadPool from PyQt6.QtCore import Qt, QSize, QThreadPool, QMutex, QTimer
from PyQt6.QtWidgets import ( from PyQt6.QtWidgets import (
QGridLayout, QGridLayout,
QToolBar, QToolBar,
@ -13,6 +13,7 @@ from PyQt6.QtWidgets import (
QStatusBar, QStatusBar,
) )
from pyqtgraph.Qt.QtCore import QThread
import uldaq import uldaq
import nixio as nix import nixio as nix
import pyqtgraph as pg import pyqtgraph as pg
@ -44,6 +45,9 @@ class PyRelacs(QMainWindow):
Qt.ToolButtonStyle.ToolButtonTextBesideIcon Qt.ToolButtonStyle.ToolButtonTextBesideIcon
) # Ensure icons are displayed with text ) # Ensure icons are displayed with text
self.setWindowTitle("PyRelacs") self.setWindowTitle("PyRelacs")
self.mutex = QMutex()
self.timer = QTimer(self)
self.timer.setInterval(200)
self.figure = pg.GraphicsLayoutWidget() self.figure = pg.GraphicsLayoutWidget()
@ -80,13 +84,14 @@ class PyRelacs(QMainWindow):
end = time.time() end = time.time()
log.debug(f"Buffer allocation took {end - start}") log.debug(f"Buffer allocation took {end - start}")
self.buffer = CircBuffer(size=BUFFERSIZE, samplerate=SAMPLERATE) self.buffer = CircBuffer(
size=BUFFERSIZE, samplerate=SAMPLERATE, mutex=self.mutex
)
# self.connect_dac() # self.connect_dac()
# self.daq_producer = DaqProducer(self.buffer, self.daq_device, [1, 1]) # self.daq_producer = DaqProducer(self.buffer, self.daq_device, [1, 1])
self.sin_producer = SinProducer(self.buffer) self.sin_producer = SinProducer(self.buffer)
self.continously_plot = Continously(self.figure, self.buffer) self.continously_plot = Continously(self.figure, self.buffer)
self.continously_plot.plot_daq()
def create_actions(self): def create_actions(self):
self._rlx_exitaction = QAction(QIcon(":/icons/exit.png"), "Exit", self) self._rlx_exitaction = QAction(QIcon(":/icons/exit.png"), "Exit", self)
@ -129,6 +134,10 @@ class PyRelacs(QMainWindow):
self._stop_recording = QAction(QIcon(":/icons/stop.png"), "Stop", self) self._stop_recording = QAction(QIcon(":/icons/stop.png"), "Stop", self)
self._stop_recording.triggered.connect(self.stop_recording) self._stop_recording.triggered.connect(self.stop_recording)
self._refresh = QAction("Refresh", self)
self._refresh.triggered.connect(self.refresh_plot)
self._refresh.setShortcut(QKeySequence("Alt+r"))
self.create_menu() self.create_menu()
def create_menu(self): def create_menu(self):
@ -171,6 +180,7 @@ class PyRelacs(QMainWindow):
daq_toolbar.addAction(self._run_action) daq_toolbar.addAction(self._run_action)
daq_toolbar.addAction(self._run_sinus_action) daq_toolbar.addAction(self._run_sinus_action)
daq_toolbar.addAction(self._stop_recording) daq_toolbar.addAction(self._stop_recording)
daq_toolbar.addAction(self._refresh)
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, daq_toolbar) self.addToolBar(Qt.ToolBarArea.TopToolBarArea, daq_toolbar)
repro_toolbar = QToolBar("Repros") repro_toolbar = QToolBar("Repros")
@ -184,6 +194,9 @@ class PyRelacs(QMainWindow):
repro_toolbar.addAction(repro_action) repro_toolbar.addAction(repro_action)
self.addToolBar(Qt.ToolBarArea.BottomToolBarArea, repro_toolbar) self.addToolBar(Qt.ToolBarArea.BottomToolBarArea, repro_toolbar)
def refresh_plot(self):
self.continously_plot.refresh()
def plot_continously(self): def plot_continously(self):
plot_daq = Worker(self.continously_plot.plot_daq) plot_daq = Worker(self.continously_plot.plot_daq)
plot_daq.signals.result.connect(self.print_output) plot_daq.signals.result.connect(self.print_output)
@ -212,13 +225,13 @@ class PyRelacs(QMainWindow):
sinus_pro.signals.progress.connect(self.progress_fn) sinus_pro.signals.progress.connect(self.progress_fn)
self.threadpool.start(sinus_pro) self.threadpool.start(sinus_pro)
# plot_daq = Worker(self.continously_plot.plot_daq) # plot_daq = Worker(self.continously_plot.plot_daq, self.timer)
# plot_daq.signals.result.connect(self.print_output) # plot_daq.signals.result.connect(self.print_output)
# plot_daq.signals.finished.connect(self.thread_complete) # plot_daq.signals.finished.connect(self.thread_complete)
# plot_daq.signals.progress.connect(self.progress_fn) # plot_daq.signals.progress.connect(self.progress_fn)
# self.threadpool.start(plot_daq) # self.threadpool.start(plot_daq)
# self.continously_plot.plot_daq() self.continously_plot.plot_daq()
def stop_recording(self): def stop_recording(self):
self.add_to_textfield("pressed") self.add_to_textfield("pressed")

View File

@ -1,9 +1,8 @@
import time
import pyqtgraph as pg import pyqtgraph as pg
from IPython import embed from IPython import embed
import numpy as np import numpy as np
from pyqtgraph.Qt.QtCore import QTimer
from PyQt6.QtCore import QTimer
from pyrelacs.dataio.circbuffer import CircBuffer from pyrelacs.dataio.circbuffer import CircBuffer
from pyrelacs.util.logging import config_logging from pyrelacs.util.logging import config_logging
@ -17,11 +16,16 @@ class Continously:
def plot_daq(self, *args, **kwargs): def plot_daq(self, *args, **kwargs):
self.figure.setBackground("w") self.figure.setBackground("w")
self.daq_plot = self.figure.addPlot(row=0, col=0)
prev_plot = self.figure.getItem(row=0, col=0)
if prev_plot:
self.figure.removeItem(prev_plot)
self.continous_plot = self.figure.addPlot(row=0, col=0)
pen = pg.mkPen("red") pen = pg.mkPen("red")
self.time = np.zeros(self.buffer.size) self.time = np.zeros(self.buffer.size)
self.data = np.zeros(self.buffer.size) self.data = np.zeros(self.buffer.size)
self.line = self.daq_plot.plot( self.line = self.continous_plot.plot(
self.time, self.time,
self.data, self.data,
pen=pen, pen=pen,
@ -29,8 +33,8 @@ class Continously:
) )
# self.plot_index = 0 # self.plot_index = 0
self.CHUNK_PLOT = 1_000
self.timer = QTimer() self.timer = QTimer()
self.CHUNK_PLOT = 10_000
self.timer.setInterval(200) self.timer.setInterval(200)
self.timer.timeout.connect(self.update_plot) self.timer.timeout.connect(self.update_plot)
self.timer.start() self.timer.start()
@ -41,7 +45,8 @@ class Continously:
log.debug(self.buffer.totalcount()) log.debug(self.buffer.totalcount())
try: try:
times, items = self.buffer.read( times, items = self.buffer.read(
self.buffer.write_index() - self.CHUNK_PLOT, extend=self.CHUNK_PLOT self.buffer.write_index() - self.CHUNK_PLOT - 1_000,
extend=self.CHUNK_PLOT,
) )
except IndexError as e: except IndexError as e:
items = np.zeros(self.CHUNK_PLOT) items = np.zeros(self.CHUNK_PLOT)
@ -65,3 +70,6 @@ class Continously:
def stop_plotting(self): def stop_plotting(self):
self.timer.stop() self.timer.stop()
def refresh(self):
self.continous_plot.enableAutoRange()