1
0
Fork 0
mirror of https://github.com/Athemis/PyDSF.git synced 2025-04-05 14:46:03 +00:00

Overhaul of data saving

This commit is contained in:
Alexander Minges 2015-07-08 17:48:27 +02:00
parent 6a2c7f2762
commit 71c25f902b
6 changed files with 327 additions and 215 deletions

View file

@ -20,5 +20,6 @@ if __name__ == "__main__":
app.installTranslator(translator) app.installTranslator(translator)
# fire up main ui # fire up main ui
ui = MainWindow() ui = MainWindow()
ui.show() ui.showMaximized()
#ui.show()
sys.exit(app.exec_()) sys.exit(app.exec_())

View file

@ -478,80 +478,44 @@ class Plate:
self.max_tm = max(self.tms) self.max_tm = max(self.tms)
self.min_tm = min(self.tms) self.min_tm = min(self.tms)
def write_tm_table(self, filename): def write_tm_table(self, filename, avg=False):
with open(filename, 'w') as f: with open(filename, 'w') as f:
f.write('#{:<4s}{:>13s}\n'.format('ID', '"Tm [°C]"')) writer = csv.writer(f, dialect='excel')
header = ['ID', 'Tm [°C]']
if avg:
header.append('SD [°C]')
writer.writerow(header)
for well in self.wells: for well in self.wells:
if np.isnan(well.tm) or well in self.denatured_wells: row = [well.name, well.tm]
f.write('{:<5s}{:>12s}\n'.format(well.name, 'NaN')) if avg:
else: row.append(well.tm_sd)
f.write('{:<5s}{:>12s}\n'.format(well.name, str(well.tm))) writer.writerow(row)
def write_avg_tm_table(self, filename): def write_data_table(self, filename, dataType='raw'):
with open(filename, 'w') as f: with open(filename, 'w') as f:
f.write('#{:<4s}{:>13s}{:>13s}\n'.format('"ID"', '"Tm [°C]"', writer = csv.writer(f, dialect='excel')
'"SD"')) header = ['Tm [°C]']
for well in self.wells: for well in self.wells:
if np.isnan(well.tm) or well in self.denatured_wells: header.append(well.name)
f.write('{:<5s}{:>12s}{:>12s}\n'.format(well.name, 'NaN', writer.writerow(header)
'NaN'))
else:
f.write('{:<5s}{:>12s}{:>12s}\n'.format(well.name,
str(well.tm),
str(well.tm_sd)))
def write_raw_table(self, filename):
with open(filename, 'w') as f:
f.write('#"Raw data"\n')
f.write('#{:<10s}'.format('"T [°C]"'))
for well in self.wells:
f.write('{:>15s}'.format(well.name))
f.write('\n')
i = 0 i = 0
row = []
for t in self.temprange: for t in self.temprange:
f.write('{:<10s}'.format(str(t))) row.append(str(t))
for well in self.wells: for well in self.wells:
if dataType == 'raw':
d = well.raw[i] d = well.raw[i]
d_rounded = float(np.round(d, decimals=3)) elif dataType == 'filtered':
f.write('{:>-15.3f}'.format(d_rounded))
f.write('\n')
i += 1
def write_filtered_table(self, filename):
with open(filename, 'w') as f:
f.write('#"Filtered data" \n')
f.write('#{:<10s}'.format('"T [°C]"'))
for well in self.wells:
f.write('{:>15s}'.format(well.name))
f.write('\n')
i = 0
for t in self.temprange:
f.write('{:<10s}'.format(str(t)))
for well in self.wells:
d = well.filtered[i] d = well.filtered[i]
d_rounded = float(np.round(d, decimals=3)) elif dataType == 'derivative':
f.write('{:>-15.3f}'.format(d_rounded))
f.write('\n')
i += 1
def write_derivative_table(self, filename):
with open(filename, 'w') as f:
f.write('#"Derivative dI/dT"\n')
f.write('#{:<10s}'.format('"T [°C]"'))
for well in self.wells:
f.write('{:>15s}'.format(well.name))
f.write('\n')
i = 0
for t in self.temprange:
f.write('{:<10s}'.format(str(t)))
for well in self.wells:
d = well.derivatives[1][i] d = well.derivatives[1][i]
else:
raise ValueError('Valid dataTypes are "raw", "filtered", and "derivative"! dataType provided was:{}'.format(dataType))
d_rounded = float(np.round(d, decimals=3)) d_rounded = float(np.round(d, decimals=3))
f.write('{:>-15.3f}'.format(d_rounded)) row.append(d_rounded)
f.write('\n') writer.writerow(row)
row = []
i += 1 i += 1
# TODO: Implement 'write_baseline_corrected_table() # TODO: Implement 'write_baseline_corrected_table()

View file

@ -11,7 +11,12 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object): class Ui_MainWindow(object):
def setupUi(self, MainWindow): def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow") MainWindow.setObjectName("MainWindow")
MainWindow.resize(1066, 795) MainWindow.resize(4095, 4095)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
MainWindow.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) MainWindow.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.centralWidget = QtWidgets.QWidget(MainWindow) self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.centralWidget.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
@ -128,33 +133,6 @@ class Ui_MainWindow(object):
self.doubleSpinBox_dt.setObjectName("doubleSpinBox_dt") self.doubleSpinBox_dt.setObjectName("doubleSpinBox_dt")
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_dt) self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_dt)
self.gridLayout.addWidget(self.groupBox_temp, 0, 0, 1, 1) self.gridLayout.addWidget(self.groupBox_temp, 0, 0, 1, 1)
self.groupBox_cutoff = QtWidgets.QGroupBox(self.groupBox_processing)
self.groupBox_cutoff.setEnabled(True)
self.groupBox_cutoff.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.groupBox_cutoff.setCheckable(True)
self.groupBox_cutoff.setChecked(False)
self.groupBox_cutoff.setObjectName("groupBox_cutoff")
self.formLayout_2 = QtWidgets.QFormLayout(self.groupBox_cutoff)
self.formLayout_2.setFieldGrowthPolicy(QtWidgets.QFormLayout.ExpandingFieldsGrow)
self.formLayout_2.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.formLayout_2.setFormAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.formLayout_2.setObjectName("formLayout_2")
self.label_cutoff_high = QtWidgets.QLabel(self.groupBox_cutoff)
self.label_cutoff_high.setObjectName("label_cutoff_high")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_cutoff_high)
self.doubleSpinBox_upper = QtWidgets.QDoubleSpinBox(self.groupBox_cutoff)
self.doubleSpinBox_upper.setPrefix("")
self.doubleSpinBox_upper.setDecimals(1)
self.doubleSpinBox_upper.setObjectName("doubleSpinBox_upper")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_upper)
self.label_cutoff_low = QtWidgets.QLabel(self.groupBox_cutoff)
self.label_cutoff_low.setObjectName("label_cutoff_low")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_cutoff_low)
self.doubleSpinBox_lower = QtWidgets.QDoubleSpinBox(self.groupBox_cutoff)
self.doubleSpinBox_lower.setDecimals(1)
self.doubleSpinBox_lower.setObjectName("doubleSpinBox_lower")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_lower)
self.gridLayout.addWidget(self.groupBox_cutoff, 0, 1, 1, 1)
self.groupBox_signal_threshold = QtWidgets.QGroupBox(self.groupBox_processing) self.groupBox_signal_threshold = QtWidgets.QGroupBox(self.groupBox_processing)
self.groupBox_signal_threshold.setEnabled(True) self.groupBox_signal_threshold.setEnabled(True)
self.groupBox_signal_threshold.setCheckable(True) self.groupBox_signal_threshold.setCheckable(True)
@ -190,8 +168,67 @@ class Ui_MainWindow(object):
self.doubleSpinBox_cbar_end.setObjectName("doubleSpinBox_cbar_end") self.doubleSpinBox_cbar_end.setObjectName("doubleSpinBox_cbar_end")
self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_cbar_end) self.formLayout_4.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_cbar_end)
self.gridLayout.addWidget(self.groupBox_cbar, 1, 1, 1, 1) self.gridLayout.addWidget(self.groupBox_cbar, 1, 1, 1, 1)
self.groupBox_cutoff = QtWidgets.QGroupBox(self.groupBox_processing)
self.groupBox_cutoff.setEnabled(True)
self.groupBox_cutoff.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.groupBox_cutoff.setCheckable(True)
self.groupBox_cutoff.setChecked(False)
self.groupBox_cutoff.setObjectName("groupBox_cutoff")
self.formLayout_2 = QtWidgets.QFormLayout(self.groupBox_cutoff)
self.formLayout_2.setFieldGrowthPolicy(QtWidgets.QFormLayout.ExpandingFieldsGrow)
self.formLayout_2.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.formLayout_2.setFormAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.formLayout_2.setObjectName("formLayout_2")
self.label_cutoff_high = QtWidgets.QLabel(self.groupBox_cutoff)
self.label_cutoff_high.setObjectName("label_cutoff_high")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_cutoff_high)
self.doubleSpinBox_upper = QtWidgets.QDoubleSpinBox(self.groupBox_cutoff)
self.doubleSpinBox_upper.setPrefix("")
self.doubleSpinBox_upper.setDecimals(1)
self.doubleSpinBox_upper.setObjectName("doubleSpinBox_upper")
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_upper)
self.label_cutoff_low = QtWidgets.QLabel(self.groupBox_cutoff)
self.label_cutoff_low.setObjectName("label_cutoff_low")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_cutoff_low)
self.doubleSpinBox_lower = QtWidgets.QDoubleSpinBox(self.groupBox_cutoff)
self.doubleSpinBox_lower.setDecimals(1)
self.doubleSpinBox_lower.setObjectName("doubleSpinBox_lower")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_lower)
self.gridLayout.addWidget(self.groupBox_cutoff, 0, 1, 1, 1)
self.groupBox_output = QtWidgets.QGroupBox(self.groupBox_processing)
self.groupBox_output.setCheckable(True)
self.groupBox_output.setChecked(False)
self.groupBox_output.setObjectName("groupBox_output")
self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_output)
self.gridLayout_2.setObjectName("gridLayout_2")
self.checkBox_saveplots = QtWidgets.QCheckBox(self.groupBox_output)
self.checkBox_saveplots.setObjectName("checkBox_saveplots")
self.gridLayout_2.addWidget(self.checkBox_saveplots, 0, 0, 1, 1)
self.buttonBox_output = QtWidgets.QDialogButtonBox(self.groupBox_output)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.buttonBox_output.sizePolicy().hasHeightForWidth())
self.buttonBox_output.setSizePolicy(sizePolicy)
self.buttonBox_output.setOrientation(QtCore.Qt.Vertical)
self.buttonBox_output.setStandardButtons(QtWidgets.QDialogButtonBox.Open)
self.buttonBox_output.setObjectName("buttonBox_output")
self.gridLayout_2.addWidget(self.buttonBox_output, 2, 1, 1, 1)
self.lineEdit_output = QtWidgets.QLineEdit(self.groupBox_output)
self.lineEdit_output.setObjectName("lineEdit_output")
self.gridLayout_2.addWidget(self.lineEdit_output, 2, 0, 1, 1)
self.checkBox_savetables = QtWidgets.QCheckBox(self.groupBox_output)
self.checkBox_savetables.setObjectName("checkBox_savetables")
self.gridLayout_2.addWidget(self.checkBox_savetables, 1, 0, 1, 1)
self.gridLayout.addWidget(self.groupBox_output, 2, 0, 1, 2)
self.formLayout_3.setWidget(2, QtWidgets.QFormLayout.SpanningRole, self.groupBox_processing) self.formLayout_3.setWidget(2, QtWidgets.QFormLayout.SpanningRole, self.groupBox_processing)
self.buttonBox_process = QtWidgets.QDialogButtonBox(self.groupBox_experiment) self.buttonBox_process = QtWidgets.QDialogButtonBox(self.groupBox_experiment)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.buttonBox_process.sizePolicy().hasHeightForWidth())
self.buttonBox_process.setSizePolicy(sizePolicy)
self.buttonBox_process.setMinimumSize(QtCore.QSize(0, 0))
self.buttonBox_process.setStandardButtons(QtWidgets.QDialogButtonBox.NoButton) self.buttonBox_process.setStandardButtons(QtWidgets.QDialogButtonBox.NoButton)
self.buttonBox_process.setObjectName("buttonBox_process") self.buttonBox_process.setObjectName("buttonBox_process")
self.formLayout_3.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.buttonBox_process) self.formLayout_3.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.buttonBox_process)
@ -220,7 +257,7 @@ class Ui_MainWindow(object):
self.horizontalLayout.addWidget(self.splitter) self.horizontalLayout.addWidget(self.splitter)
MainWindow.setCentralWidget(self.centralWidget) MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow) self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 1066, 28)) self.menuBar.setGeometry(QtCore.QRect(0, 0, 4095, 28))
self.menuBar.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates)) self.menuBar.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedStates))
self.menuBar.setObjectName("menuBar") self.menuBar.setObjectName("menuBar")
self.menuFile = QtWidgets.QMenu(self.menuBar) self.menuFile = QtWidgets.QMenu(self.menuBar)
@ -251,10 +288,10 @@ class Ui_MainWindow(object):
self.label_tmin.setBuddy(self.doubleSpinBox_tmin) self.label_tmin.setBuddy(self.doubleSpinBox_tmin)
self.label_tmax.setBuddy(self.doubleSpinBox_tmax) self.label_tmax.setBuddy(self.doubleSpinBox_tmax)
self.label_dt.setBuddy(self.doubleSpinBox_dt) self.label_dt.setBuddy(self.doubleSpinBox_dt)
self.label_cutoff_high.setBuddy(self.doubleSpinBox_upper)
self.label_cutoff_low.setBuddy(self.doubleSpinBox_lower)
self.label_cbar_start.setBuddy(self.doubleSpinBox_cbar_start) self.label_cbar_start.setBuddy(self.doubleSpinBox_cbar_start)
self.label_cbar_end.setBuddy(self.doubleSpinBox_cbar_end) self.label_cbar_end.setBuddy(self.doubleSpinBox_cbar_end)
self.label_cutoff_high.setBuddy(self.doubleSpinBox_upper)
self.label_cutoff_low.setBuddy(self.doubleSpinBox_lower)
self.retranslateUi(MainWindow) self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(-1) self.tabWidget.setCurrentIndex(-1)
@ -279,12 +316,6 @@ class Ui_MainWindow(object):
self.doubleSpinBox_tmax.setSuffix(_translate("MainWindow", " °C")) self.doubleSpinBox_tmax.setSuffix(_translate("MainWindow", " °C"))
self.label_dt.setText(_translate("MainWindow", "<html><head/><body><p>&Delta;T</p></body></html>")) self.label_dt.setText(_translate("MainWindow", "<html><head/><body><p>&Delta;T</p></body></html>"))
self.doubleSpinBox_dt.setSuffix(_translate("MainWindow", " °C")) self.doubleSpinBox_dt.setSuffix(_translate("MainWindow", " °C"))
self.groupBox_cutoff.setToolTip(_translate("MainWindow", "<html><head/><body><p>Only T<span style=\" vertical-align:sub;\">m</span> values within this limit are considered valid.</p></body></html>"))
self.groupBox_cutoff.setTitle(_translate("MainWindow", "&Cutoff"))
self.label_cutoff_high.setText(_translate("MainWindow", "&Upper"))
self.doubleSpinBox_upper.setSuffix(_translate("MainWindow", " °C"))
self.label_cutoff_low.setText(_translate("MainWindow", "Lower"))
self.doubleSpinBox_lower.setSuffix(_translate("MainWindow", " °C"))
self.groupBox_signal_threshold.setToolTip(_translate("MainWindow", "<html><head/><body><p>If the signal exceeds this threshold, the coresponding well is assumed to be denatured.</p></body></html>")) self.groupBox_signal_threshold.setToolTip(_translate("MainWindow", "<html><head/><body><p>If the signal exceeds this threshold, the coresponding well is assumed to be denatured.</p></body></html>"))
self.groupBox_signal_threshold.setTitle(_translate("MainWindow", "Signal &Threshold")) self.groupBox_signal_threshold.setTitle(_translate("MainWindow", "Signal &Threshold"))
self.groupBox_cbar.setToolTip(_translate("MainWindow", "<html><head/><body><p>Defines the range of the colorbar used for the T<span style=\" vertical-align:sub;\">m</span> heatmap.</p></body></html>")) self.groupBox_cbar.setToolTip(_translate("MainWindow", "<html><head/><body><p>Defines the range of the colorbar used for the T<span style=\" vertical-align:sub;\">m</span> heatmap.</p></body></html>"))
@ -293,6 +324,16 @@ class Ui_MainWindow(object):
self.doubleSpinBox_cbar_start.setSuffix(_translate("MainWindow", " °C")) self.doubleSpinBox_cbar_start.setSuffix(_translate("MainWindow", " °C"))
self.label_cbar_end.setText(_translate("MainWindow", "En&d")) self.label_cbar_end.setText(_translate("MainWindow", "En&d"))
self.doubleSpinBox_cbar_end.setSuffix(_translate("MainWindow", " °C")) self.doubleSpinBox_cbar_end.setSuffix(_translate("MainWindow", " °C"))
self.groupBox_cutoff.setToolTip(_translate("MainWindow", "<html><head/><body><p>Only T<span style=\" vertical-align:sub;\">m</span> values within this limit are considered valid.</p></body></html>"))
self.groupBox_cutoff.setTitle(_translate("MainWindow", "&Cutoff"))
self.label_cutoff_high.setText(_translate("MainWindow", "&Upper"))
self.doubleSpinBox_upper.setSuffix(_translate("MainWindow", " °C"))
self.label_cutoff_low.setText(_translate("MainWindow", "Lower"))
self.doubleSpinBox_lower.setSuffix(_translate("MainWindow", " °C"))
self.groupBox_output.setTitle(_translate("MainWindow", "Sa&ve processing results"))
self.checkBox_saveplots.setText(_translate("MainWindow", "Save plots"))
self.lineEdit_output.setToolTip(_translate("MainWindow", "Output results to this path"))
self.checkBox_savetables.setText(_translate("MainWindow", "Save tabular results"))
self.groupBox_results.setTitle(_translate("MainWindow", "Plots")) self.groupBox_results.setTitle(_translate("MainWindow", "Plots"))
self.menuFile.setTitle(_translate("MainWindow", "Fi&le")) self.menuFile.setTitle(_translate("MainWindow", "Fi&le"))
self.menuHelp.setTitle(_translate("MainWindow", "Hel&p")) self.menuHelp.setTitle(_translate("MainWindow", "Hel&p"))

View file

@ -5,11 +5,13 @@ Module implementing MainWindow.
from PyQt5.QtCore import (pyqtSlot, QObject, pyqtSignal, QThreadPool, from PyQt5.QtCore import (pyqtSlot, QObject, pyqtSignal, QThreadPool,
QRunnable, QCoreApplication) QRunnable, QCoreApplication)
from PyQt5.QtWidgets import (QMainWindow, QProgressBar, QDialogButtonBox, from PyQt5.QtWidgets import (QMainWindow, QProgressBar, QDialogButtonBox,
QFileDialog, QMessageBox, QApplication) QFileDialog, QMessageBox, QApplication,
QTableWidget, QTableWidgetItem)
from .Ui_mainwindow import Ui_MainWindow from .Ui_mainwindow import Ui_MainWindow
from .mplwidget import MplWidget from .mplwidget import MplWidget
from pydsf import Experiment, PlotResults from pydsf import Experiment, PlotResults
import os
VERSION = "1.0" VERSION = "1.0"
_translate = QCoreApplication.translate _translate = QCoreApplication.translate
@ -125,6 +127,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.tasks = Tasks() self.tasks = Tasks()
self.worker = Worker(self) self.worker = Worker(self)
self.outputPath = None
@pyqtSlot("QAbstractButton*") @pyqtSlot("QAbstractButton*")
def on_buttonBox_open_reset_clicked(self, button): def on_buttonBox_open_reset_clicked(self, button):
""" """
@ -142,7 +146,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
elif button == self.buttonBox_open_reset.button( elif button == self.buttonBox_open_reset.button(
QDialogButtonBox.Reset): QDialogButtonBox.Reset):
self.listWidget_data.clear() self.listWidget_data.clear()
self.remove_plate_tabs()
@pyqtSlot("QAbstractButton*")
def on_buttonBox_output_clicked(self, button):
if button == self.buttonBox_output.button(QDialogButtonBox.Open):
path = QFileDialog.getExistingDirectory(parent=self, caption=_translate('MainWindow', 'Choose output path'), options=QFileDialog.ShowDirsOnly)
self.lineEdit_output.setText(path.strip())
@pyqtSlot("QString") @pyqtSlot("QString")
def on_comboBox_instrument_currentIndexChanged(self, p0): def on_comboBox_instrument_currentIndexChanged(self, p0):
@ -155,7 +164,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.groupBox_temp.setEnabled(False) self.groupBox_temp.setEnabled(False)
def generate_plot_tab(self, name): def generate_plot_tab(self, name):
tab = MplWidget(parent=self) tab = MplWidget(parent=self.tabWidget)
tab.setObjectName(name) tab.setObjectName(name)
return tab return tab
@ -171,26 +180,35 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def generate_plate_tabs(self, plate): def generate_plate_tabs(self, plate):
plotter = PlotResults() plotter = PlotResults()
if id != 'average': if plate.id != 'average':
tab = self.generate_plot_tab("tab_heatmap_{}".format(id)) tab = self.generate_plot_tab("tab_heatmap_{}".format(plate.id))
title = _translate("MainWindow", "Heatmap #") title = _translate("MainWindow", "Heatmap #")
self.tabWidget.addTab(tab, title + str(plate.id)) self.tabWidget.addTab(tab, title + str(plate.id))
plotter.plot_tm_heatmap_single(plate, tab) plotter.plot_tm_heatmap_single(plate, tab)
if self.checkBox_saveplots.isChecked():
tab.canvas.save("{}/heatmap_{}.svg".format(self.outputPath, plate.id))
tab = self.generate_plot_tab("tab_raw_{}".format(id)) tab = self.generate_plot_tab("tab_raw_{}".format(plate.id))
title = _translate("MainWindow", "Raw Data #") title = _translate("MainWindow", "Raw Data #")
self.tabWidget.addTab(tab, title + str(plate.id)) self.tabWidget.addTab(tab, title + str(plate.id))
plotter.plot_raw(plate, tab) plotter.plot_raw(plate, tab)
if self.checkBox_saveplots.isChecked():
tab.canvas.save("{}/raw_{}.svg".format(self.outputPath, plate.id))
tab = self.generate_plot_tab("tab_derivative_{}".format(id)) tab = self.generate_plot_tab("tab_derivative_{}".format(plate.id))
title = _translate("MainWindow", "Derivatives #") title = _translate("MainWindow", "Derivatives #")
self.tabWidget.addTab(tab, title + str(plate.id)) self.tabWidget.addTab(tab, title + str(plate.id))
plotter.plot_derivative(plate, tab) plotter.plot_derivative(plate, tab)
if self.checkBox_saveplots.isChecked():
tab.canvas.save("{}/derivatives_{}.svg".format(self.outputPath, plate.id))
else: else:
tab = self.generate_plot_tab("tab_heatmap_{}".format(id)) tab = self.generate_plot_tab("tab_heatmap_{}".format(plate.id))
title = _translate("MainWindow", "Heatmap ") title = _translate("MainWindow", "Heatmap ")
self.tabWidget.addTab(tab, title + str(plate.id)) self.tabWidget.addTab(tab, title + str(plate.id))
plotter.plot_tm_heatmap_single(plate, tab) plotter.plot_tm_heatmap_single(plate, tab)
if self.checkBox_saveplots.isChecked():
tab.canvas.save("{}/heatmap_{}.svg".format(self.outputPath, plate.id))
@pyqtSlot() @pyqtSlot()
def on_buttonBox_process_accepted(self): def on_buttonBox_process_accepted(self):
@ -204,6 +222,22 @@ class MainWindow(QMainWindow, Ui_MainWindow):
_translate("MainWindow", "No data file loaded!"), _translate("MainWindow", "No data file loaded!"),
QMessageBox.Close, QMessageBox.Close) QMessageBox.Close, QMessageBox.Close)
return return
if self.groupBox_output.isChecked() and self.lineEdit_output.text().strip() == '':
QMessageBox.critical(
self, _translate("MainWindow", "Error"),
_translate("MainWindow", "No output path set!"),
QMessageBox.Close, QMessageBox.Close)
return
elif self.groupBox_output.isChecked() and self.lineEdit_output.text().strip() != '':
path = self.lineEdit_output.text().strip()
if os.path.isdir(path):
self.outputPath = self.lineEdit_output.text().strip()
else:
QMessageBox.critical(
self, _translate("MainWindow", "Error"),
_translate("MainWindow", "Output path does not exist!"),
QMessageBox.Close, QMessageBox.Close)
if self.spinBox_signal_threshold.value( if self.spinBox_signal_threshold.value(
) == 0 and self.groupBox_signal_threshold.isChecked(): ) == 0 and self.groupBox_signal_threshold.isChecked():
QMessageBox.warning( QMessageBox.warning(
@ -213,6 +247,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
"Signal threshold is currently set to zero."), "Signal threshold is currently set to zero."),
QMessageBox.Ok, QMessageBox.Ok) QMessageBox.Ok, QMessageBox.Ok)
self.remove_plate_tabs()
self.progressBar.setEnabled(True) self.progressBar.setEnabled(True)
self.statusBar.showMessage(_translate("MainWindow", "Processing...")) self.statusBar.showMessage(_translate("MainWindow", "Processing..."))
@ -225,32 +260,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# For now, only read the first entry # For now, only read the first entry
exp = self.tasks.data[0] exp = self.tasks.data[0]
save_data = QMessageBox.question(
self, _translate("MainWindow", "Save data"),
_translate(
"MainWindow", "Calculations are finished. Save results?"),
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if save_data == QMessageBox.Yes:
dialog = QFileDialog()
dialog.setFileMode(QFileDialog.Directory)
folder = dialog.getExistingDirectory(
self, _translate("MainWindow", "Choose path for results"))
for plate in exp.plates:
plate.write_tm_table(
'{}/plate_{}_04_tm.csv'.format(folder, str(plate.id)))
plate.write_derivative_table(
'{}/plate_{}_03_dI_dT.csv'.format(folder, str(plate.id)))
plate.write_filtered_table(
'{}/plate_{}_02_filtered_data.csv'.format(folder,
str(plate.id)))
plate.write_raw_table('{}/plate_{}_01_raw_data.csv'.format(
folder, str(plate.id)))
if exp.avg_plate:
exp.avg_plate.write_avg_tm_table(
'{}/plate_{}_05_tm_avg.csv'.format(
folder, str(self.worker.exp.avg_plate.id)))
for i in range(len(self.worker.exp.plates)): for i in range(len(self.worker.exp.plates)):
plate = exp.plates[i] plate = exp.plates[i]
@ -261,6 +270,24 @@ class MainWindow(QMainWindow, Ui_MainWindow):
plate = exp.avg_plate plate = exp.avg_plate
self.generate_plate_tabs(plate) self.generate_plate_tabs(plate)
if self.groupBox_output.isChecked():
if self.checkBox_savetables.isChecked():
for plate in exp.plates:
plate.write_tm_table(
'{}/plate_{}_tm.csv'.format(self.outputPath, str(plate.id)))
plate.write_data_table(
'{}/plate_{}_dI_dT.csv'.format(self.outputPath, str(plate.id)), dataType='derivative')
plate.write_data_table(
'{}/plate_{}_filtered_data.csv'.format(self.outputPath,
str(plate.id)), dataType='filtered')
plate.write_data_table('{}/plate_{}_raw_data.csv'.format(
self.outputPath, str(plate.id)))
if exp.avg_plate:
exp.avg_plate.write_tm_table(
'{}/plate_{}_tm_avg.csv'.format(
self.outputPath, str(self.worker.exp.avg_plate.id)), avg=True)
self.progressBar.setEnabled(False) self.progressBar.setEnabled(False)
self.statusBar.showMessage(_translate("MainWindow", "Finished!")) self.statusBar.showMessage(_translate("MainWindow", "Finished!"))

View file

@ -6,10 +6,16 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1066</width> <width>4095</width>
<height>795</height> <height>4095</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>PyDSF</string> <string>PyDSF</string>
</property> </property>
@ -291,82 +297,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox_cutoff">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Only T&lt;span style=&quot; vertical-align:sub;&quot;&gt;m&lt;/span&gt; values within this limit are considered valid.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="title">
<string>&amp;Cutoff</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_cutoff_high">
<property name="text">
<string>&amp;Upper</string>
</property>
<property name="buddy">
<cstring>doubleSpinBox_upper</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_upper">
<property name="prefix">
<string/>
</property>
<property name="suffix">
<string> °C</string>
</property>
<property name="decimals">
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_cutoff_low">
<property name="text">
<string>Lower</string>
</property>
<property name="buddy">
<cstring>doubleSpinBox_lower</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_lower">
<property name="suffix">
<string> °C</string>
</property>
<property name="decimals">
<number>1</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QGroupBox" name="groupBox_signal_threshold"> <widget class="QGroupBox" name="groupBox_signal_threshold">
<property name="enabled"> <property name="enabled">
@ -459,11 +389,151 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox_cutoff">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Only T&lt;span style=&quot; vertical-align:sub;&quot;&gt;m&lt;/span&gt; values within this limit are considered valid.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="title">
<string>&amp;Cutoff</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="formAlignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_cutoff_high">
<property name="text">
<string>&amp;Upper</string>
</property>
<property name="buddy">
<cstring>doubleSpinBox_upper</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_upper">
<property name="prefix">
<string/>
</property>
<property name="suffix">
<string> °C</string>
</property>
<property name="decimals">
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_cutoff_low">
<property name="text">
<string>Lower</string>
</property>
<property name="buddy">
<cstring>doubleSpinBox_lower</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_lower">
<property name="suffix">
<string> °C</string>
</property>
<property name="decimals">
<number>1</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_output">
<property name="title">
<string>Sa&amp;ve processing results</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_saveplots">
<property name="text">
<string>Save plots</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDialogButtonBox" name="buttonBox_output">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Open</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLineEdit" name="lineEdit_output">
<property name="toolTip">
<string>Output results to this path</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_savetables">
<property name="text">
<string>Save tabular results</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QDialogButtonBox" name="buttonBox_process"> <widget class="QDialogButtonBox" name="buttonBox_process">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="standardButtons"> <property name="standardButtons">
<set>QDialogButtonBox::NoButton</set> <set>QDialogButtonBox::NoButton</set>
</property> </property>
@ -530,7 +600,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1066</width> <width>4095</width>
<height>28</height> <height>28</height>
</rect> </rect>
</property> </property>

View file

@ -28,6 +28,15 @@ class MplCanvas(FigureCanvas):
self.ax.clear() self.ax.clear()
self.fig.clear() self.fig.clear()
def save(self, filename):
try:
self.fig.savefig(filename, dpi=300)
except IOError:
QtWidgets.QMessageBox.critical(
self, _translate("MainWindow", "Error"),
_translate("MainWindow", "Error saving figure! Please check permissions/free space of target path!"),
QtWidgets.QMessageBox.Close, QtWidgets.QMessageBox.Close)
class CustomNavigationToolbar(NavigationToolbar): class CustomNavigationToolbar(NavigationToolbar):
toolitems = ( toolitems = (