Compare commits
3 Commits
25d16cc5fd
...
b5f8d7663d
Author | SHA1 | Date | |
---|---|---|---|
b5f8d7663d | |||
fe3e142452 | |||
bbc8def460 |
@ -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):
|
||||||
"""
|
"""
|
||||||
|
@ -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")
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user