235 lines
7.2 KiB
Python
235 lines
7.2 KiB
Python
import numpy as np
|
|
from pandas import read_csv
|
|
import matplotlib
|
|
matplotlib.use('Qt5Agg')
|
|
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT as NavigationToolbar
|
|
from matplotlib.figure import Figure
|
|
import crds_calc
|
|
import PyQt5
|
|
from PyQt5 import QtWidgets, QtCore
|
|
from memdb import mem
|
|
import pathlib
|
|
|
|
# Helper functions
|
|
|
|
class Global(QtWidgets.QWidget):
|
|
csv_selected = QtCore.pyqtSignal()
|
|
correlation_complete = QtCore.pyqtSignal()
|
|
fitting_complete = QtCore.pyqtSignal()
|
|
globj = Global()
|
|
|
|
def display_warning(message: str):
|
|
msg = QtWidgets.QMessageBox()
|
|
msg.setIcon(QtWidgets.QMessageBox.warning)
|
|
msg.setText("Warning")
|
|
msg.setInformativeText(message)
|
|
msg.setWindowTitle("Warning")
|
|
msg.exec_()
|
|
|
|
def display_error(message: str):
|
|
msg = QtWidgets.QMessageBox()
|
|
msg.setIcon(QtWidgets.QMessageBox.Critical)
|
|
msg.setText("Error")
|
|
msg.setInformativeText(message)
|
|
msg.setWindowTitle("Error")
|
|
msg.exec_()
|
|
|
|
|
|
# Menu definitions
|
|
|
|
class file_menu(QtWidgets.QMenu):
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
open_csv = QtWidgets.QAction("Open CSV File", self)
|
|
open_csv.setShortcut("Ctrl+O")
|
|
open_csv.triggered.connect(self.select_csv)
|
|
self.addAction(open_csv)
|
|
|
|
def select_csv(self):
|
|
filename, _ = QtWidgets.QFileDialog.getOpenFileName(self)
|
|
data = read_csv(filename, comment="%", delimiter=";").to_numpy()
|
|
mem['x_data'] = data.transpose()[0]
|
|
mem['y_data'] = data.transpose()[1]
|
|
try:
|
|
mem['v_data'] = data[2].transpose()
|
|
except IndexError:
|
|
display_error('No voltage column detected. Functionality will be limited.')
|
|
|
|
globj.csv_selected.emit()
|
|
|
|
class help_menu(QtWidgets.QMenu):
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
visit_repo = QtWidgets.QAction("Go to GitHub Repo", self)
|
|
visit_repo.triggered.connect(self.go_to_repo)
|
|
self.addAction(visit_repo)
|
|
|
|
def go_to_repo(self):
|
|
PyQt5.QtGui.QDesktopServices.openUrl(QtCore.QUrl('https://github.com/turtlebasket/crds_analyze'))
|
|
|
|
# Inputs / Parameter boxes
|
|
|
|
class combo_grouping_algo(QtWidgets.QComboBox):
|
|
def change(self):
|
|
mem['grouping_algo'] = self.currentIndex()
|
|
globj.grouping_algo_changed.emit()
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
self.currentIndexChanged.connect(self.change)
|
|
|
|
class config_area(QtWidgets.QStackedWidget):
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
self.setCurrentIndex(0)
|
|
globj.grouping_algo_changed.connect(lambda: self.setCurrentIndex(mem['grouping_algo']))
|
|
|
|
class spin_min_voltage(QtWidgets.QDoubleSpinBox):
|
|
def changeVal(self, val):
|
|
mem['min_voltage'] = float(val)
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
mem['min_voltage'] = float(self.value())
|
|
self.textChanged.connect(self.changeVal)
|
|
|
|
class spin_group_len(QtWidgets.QDoubleSpinBox):
|
|
def changeVal(self, val):
|
|
mem['group_len'] = float(val)
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
mem['group_len'] = float(self.value())
|
|
self.textChanged.connect(self.changeVal)
|
|
|
|
class spin_peak_len(QtWidgets.QDoubleSpinBox):
|
|
def changeVal(self, val):
|
|
mem['peak_len'] = float(val)
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
mem['peak_len'] = float(self.value())
|
|
self.textChanged.connect(self.changeVal)
|
|
|
|
class spin_min_peakheight(QtWidgets.QDoubleSpinBox):
|
|
def changeVal(self, val):
|
|
mem['peak_minheight'] = float(val)
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
mem['peak_minheight'] = float(self.value())
|
|
self.textChanged.connect(self.changeVal)
|
|
|
|
class spin_min_peakprominence(QtWidgets.QDoubleSpinBox):
|
|
def changeVal(self, val):
|
|
mem['peak_prominence'] = float(val)
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
mem['peak_prominence'] = float(self.value())
|
|
self.textChanged.connect(self.changeVal)
|
|
|
|
class spin_moving_average_denom(QtWidgets.QSpinBox):
|
|
def changeVal(self, val):
|
|
mem['moving_avg_denom'] = int(val)
|
|
print(isinstance(val, str))
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
mem['moving_avg_denom'] = float(self.value())
|
|
self.textChanged.connect(self.changeVal)
|
|
|
|
class equation_view(QtWidgets.QGraphicsView):
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
pix = PyQt5.QtGui.QPixmap(f"{pathlib.Path(__file__).parent.resolve()}/assets/eq3.png")
|
|
item = QtWidgets.QGraphicsPixmapItem(pix)
|
|
item.setScale(0.38)
|
|
scene = QtWidgets.QGraphicsScene()
|
|
scene.addItem(item)
|
|
self.setScene(scene)
|
|
|
|
class correlate_button(QtWidgets.QPushButton):
|
|
def calc(self):
|
|
groups_raw = None
|
|
try:
|
|
if (mem['grouping_algo'] == 0):
|
|
display_error('VThreshold not yet implemented.')
|
|
return
|
|
elif (mem['grouping_algo'] == 1):
|
|
groups_raw = crds_calc.spaced_groups()
|
|
|
|
mem['groups_correlated'] = crds_calc.correlate_groups(groups_raw)
|
|
globj.correlation_complete.emit()
|
|
|
|
except KeyError:
|
|
display_error('Failed to correlate. Did you import a data file & set parameters?')
|
|
|
|
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
self.pressed.connect(self.calc)
|
|
|
|
class fit_button(QtWidgets.QPushButton):
|
|
def fit(self):
|
|
print("hi")
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
self.pressed.connect(self.fit)
|
|
|
|
|
|
# Graph stuff
|
|
|
|
class graph_tab(QtWidgets.QTabWidget):
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
globj.csv_selected.connect(lambda: self.setCurrentIndex(0))
|
|
globj.correlation_complete.connect(lambda: self.setCurrentIndex(1))
|
|
globj.fitting_complete.connect(lambda: self.setCurrentIndex(2))
|
|
|
|
class MplCanvas(FigureCanvasQTAgg):
|
|
def __init__(self, parent=None, width=5, height=4, dpi=100):
|
|
fig = Figure(figsize=(width, height), dpi=dpi)
|
|
self.axes = fig.add_subplot(111)
|
|
fig.tight_layout()
|
|
super(MplCanvas, self).__init__(fig)
|
|
|
|
class base_graph(QtWidgets.QWidget):
|
|
"""
|
|
Widget with embedded matplotlib graph & navigation toolbar
|
|
|
|
Reference: https://www.mfitzp.com/tutorials/plotting-matplotlib/
|
|
"""
|
|
|
|
canv = None
|
|
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
self.canv = MplCanvas(self)
|
|
# Example
|
|
# canv.axes.plot([0,1,2,3,4], [10,1,20,3,40])
|
|
toolbar = NavigationToolbar(self.canv, self)
|
|
layout = QtWidgets.QVBoxLayout()
|
|
layout.addWidget(toolbar)
|
|
layout.addWidget(self.canv)
|
|
self.setLayout(layout)
|
|
|
|
def plot(self):
|
|
self.canv.axes.plot(mem['x_data'], mem['y_data'])
|
|
|
|
def plot_full(self):
|
|
self.canv.axes.clear()
|
|
self.plot()
|
|
self.canv.draw()
|
|
print("attempted plot")
|
|
|
|
class rawdata_graph(base_graph):
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
globj.csv_selected.connect(self.plot_full)
|
|
|
|
class peaks_graph(base_graph):
|
|
def __init__(self, x):
|
|
super().__init__(x)
|
|
globj.correlation_complete.connect(self.plot_full)
|
|
|
|
def plot(self):
|
|
for i in mem['groups_correlated']:
|
|
self.canv.axes.plot(i)
|
|
|
|
|
|
class timeconstant_graph(base_graph):
|
|
pass |