BUGFIX: VFT;

change to src layout
This commit is contained in:
dominik
2022-10-20 17:23:15 +02:00
parent 89ce4bab9f
commit 8d148b639b
445 changed files with 1387 additions and 1920 deletions

267
src/gui_qt/io/dscreader.py Normal file
View File

@@ -0,0 +1,267 @@
from __future__ import annotations
from pathlib import Path
import numpy as np
from pyqtgraph import PlotDataItem
from nmreval.data.points import Points
from nmreval.io.dsc import Cyclohexane, DSCCalibrator, DSCSample
from ..Qt import QtWidgets, QtCore
from .._py.dscfile_dialog import Ui_Dialog
class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
data_read = QtCore.pyqtSignal(list)
file_ext = ['.txt', '.dsc']
def __init__(self, sample=None, empty=None, reference=None, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
self.calibrator = DSCCalibrator()
self.current_run = (-1, 'h')
self.sample_idx = None
self.fname = None
self.raw_graph.setLabel('bottom', text='T', units='K')
self.raw_graph.setTitle('Raw data')
self.raw_graph.addLegend()
self.raw_sample = PlotDataItem(x=[], y=[], name='Sample')
self.empty_sample = PlotDataItem(x=[], y=[], pen={'dash': (5, 5)}, name='Empty')
self.raw_graph.addItem(self.raw_sample)
self.raw_graph.addItem(self.empty_sample)
self.end_graph.setTitle('End result')
self.end_graph.setLabel('bottom', text='T', units='K')
self.baseline_sample = PlotDataItem(x=[], y=[])
self.end_graph.addItem(self.baseline_sample)
self.baseline_graph.setTitle('Time dependence')
self.baseline_graph.setLabel('bottom', text='t', units='min')
self.drift_sample = PlotDataItem(x=[], y=[])
self.slope_graph = PlotDataItem(x=[], y=[], pen={'color': 'r', 'dash': (5, 5)})
self.baseline_graph.addItem(self.drift_sample)
self.baseline_graph.addItem(self.slope_graph)
self.calib_graph.setTitle('Calibration')
self.calib_graph.setLabel('bottom', text='T', units='K')
self.ref_plotitems = []
self.sample = None
if sample is not None:
self.add_sample(sample)
self.empty = None
if empty is not None:
self.add_empty(empty=empty)
self.references = []
if reference is not None:
if isinstance(reference, (str, Path, DSCSample)):
reference = [reference]
for r in reference:
self.add_reference(ref=r)
def __call__(self, fname: Path | str):
self.clear_plots()
self.add_sample(fname)
return self
def add_sample(self, fname: Path | str):
self.sample = self.calibrator.set_measurement(fname, mode='sample')
self.fname = self.sample.fname
self.step_listWidget.clear()
for opts in self.sample.steps:
item = QtWidgets.QListWidgetItem()
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable)
item.setCheckState(QtCore.Qt.Unchecked)
if opts[0] == 'i':
item.setFlags(QtCore.Qt.NoItemFlags)
item.setText(f'{opts[1]:.2f} K for {opts[1] / 60:.0f} min')
else:
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable)
item.setText(f'{opts[2]:.2f} K to {opts[3]:.2f} K with {opts[1]} K/min')
self.step_listWidget.addItem(item)
@QtCore.pyqtSlot(name='on_loadempty_button_clicked')
def add_empty(self, empty=None):
if empty is None:
empty, _ = QtWidgets.QFileDialog.getOpenFileName(directory=str(self.fname.parent))
if empty:
self.empty = self.calibrator.set_measurement(empty, mode='empty')
self.empty_label.setText(str(self.empty.fname.name))
self.update_plots()
@QtCore.pyqtSlot(name='on_delempty_button_clicked')
def remove_empty(self):
self.empty_label.setText('No empty measurement')
self.calibrator.empty = None
self.update_plots()
@QtCore.pyqtSlot(name='on_ref_add_pushButton_clicked')
def add_reference(self, ref: str | Path = None):
if ref is None:
ref, _ = QtWidgets.QFileDialog.getOpenFileName(directory=str(self.fname.parent))
if ref:
ref = self.calibrator.set_measurement(ref, mode='reference')
self.references.append(ref)
item = QtWidgets.QTableWidgetItem(str(ref.fname.name))
item.setData(QtCore.Qt.UserRole, ref.fname)
item.setFlags(QtCore.Qt.ItemIsEnabled)
rowcnt = self.reference_tableWidget.rowCount()
self.reference_tableWidget.setRowCount(rowcnt+1)
self.reference_tableWidget.setItem(rowcnt, 0, item)
self.reference_tableWidget.setCellWidget(rowcnt, 1, ReferenceComboBox())
self.reference_tableWidget.resizeColumnsToContents()
self.update_plots()
@QtCore.pyqtSlot(name='on_ref_remove_pushButton_clicked')
def remove_reference(self):
idx = self.reference_tableWidget.currentRow()
self.calibrator.remove_reference(self.reference_tableWidget.item(idx, 0).data(QtCore.Qt.UserRole))
self.reference_tableWidget.removeRow(idx)
self.update_plots()
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem, name='on_step_listWidget_itemChanged')
def select_run(self, item: QtWidgets.QListWidgetItem):
idx = self.step_listWidget.indexFromItem(item).row()
self.step_listWidget.blockSignals(True)
for row in range(self.step_listWidget.count()):
if idx == row:
continue
self.step_listWidget.item(row).setCheckState(QtCore.Qt.Unchecked)
self.step_listWidget.blockSignals(False)
if item.checkState() == QtCore.Qt.Checked:
mode, rate, _, _ = self.sample.steps[idx]
self.current_run = (rate, mode)
self.sample_idx = idx
self.update_plots()
else:
self.current_run = (-1, 'h')
self.sample_idx = None
self.clear_plots()
def get_data(self, ):
if self.sample_idx is None:
return
rate = self.current_run[0]
slope_type = {self.none_radioButton: None,
self.isotherm_radioButton: 'iso',
self.slope_radioButton: 'curve'}[self.buttonGroup.checkedButton()]
try:
raw_sample, drift_value, sample_data, empty_data, slope = self.calibrator.get_data(self.sample_idx,
slope=slope_type)
except ValueError as e:
_msg = QtWidgets.QMessageBox.warning(self, 'No rate found', e.args[0])
return
self.calibrator.ref_list = []
for row in range(self.reference_tableWidget.rowCount()):
self.calibrator.ref_list.append(self.reference_tableWidget.cellWidget(row, 1).get_reference())
calib_x, calib_y, regions = self.calibrator.get_calibration(rate)
drift_value[0] /= 60.
slope[0] /= 60.
if calib_x is not None:
sample_data[0] *= calib_x[0]
sample_data[0] += calib_x[1]
if self.cp_checkBox.isChecked():
sample_data[1] *= calib_y
return sample_data, raw_sample, empty_data, drift_value, slope, calib_x, calib_y, regions
@QtCore.pyqtSlot(QtWidgets.QAbstractButton, name='on_buttonGroup_buttonClicked')
@QtCore.pyqtSlot(int, name='on_cp_checkBox_stateChanged')
def update_plots(self, _=None):
sample_data, raw_sample, empty_data, drift_value, slope, calib_x, calib_y, regions = self.get_data()
self.raw_sample.setData(x=raw_sample[0], y=raw_sample[1])
self.drift_sample.setData(x=drift_value[0], y=drift_value[1])
self.slope_graph.setData(x=slope[0], y=slope[1])
if empty_data is not None:
self.empty_sample.setData(x=empty_data[0], y=empty_data[1])
self.calib_graph.clear()
if calib_x is not None:
for ref_zoom, onset, grad_points in regions:
ref_plot = PlotDataItem(x=ref_zoom[0], y=ref_zoom[1])
self.calib_graph.addItem(ref_plot)
self.calib_graph.addItem(PlotDataItem(x=grad_points[0], y=grad_points[1],
symbol='x'))
view_limits = -np.max(ref_zoom[1])/10, np.max(ref_zoom[1]) * 1.1
cut_idx, = np.where((onset < view_limits[1]) & (onset > view_limits[0]))
self.calib_graph.addItem(PlotDataItem(x=ref_zoom[0, cut_idx], y=onset[cut_idx],
pen={'color': 'r', 'dash': (2, 5)}))
self.calib_graph.addItem(PlotDataItem(x=[ref_zoom[0, 0], ref_zoom[0, -1]], y=[0, 0],
pen={'color': 'r', 'dash': (2, 5)}))
self.baseline_sample.setData(x=sample_data[0], y=sample_data[1])
def clear_plots(self):
for plot in [self.raw_sample, self.baseline_sample, self.empty_sample, self.drift_sample, self.slope_graph]:
plot.setData(x=[], y=[])
self.calib_graph.clear()
def export_data(self, filesave=False, close_after=True):
try:
sample_data = self.get_data()[0]
except TypeError:
return
rate, mode = self.current_run
new_val = Points(sample_data[0], sample_data[1], value=rate, name=f'{self.fname.stem} {rate} ({mode})')
if filesave:
new_val.savetxt(self.fname.with_name(f'{self.fname.stem} {rate}K-min {mode}.dat'.replace(' ', '_')))
else:
self.data_read.emit([new_val])
if close_after:
super().accept()
@QtCore.pyqtSlot(QtWidgets.QAbstractButton, name='on_buttonBox_clicked')
def button_clicked(self, bttn: QtWidgets.QAbstractButton):
bttn_value = self.buttonBox.standardButton(bttn)
if bttn_value in (self.buttonBox.Ok, self.buttonBox.Apply, self.buttonBox.Save):
self.export_data(filesave=bttn_value==self.buttonBox.Save, close_after=bttn_value==self.buttonBox.Ok)
else:
super().close()
class ReferenceComboBox(QtWidgets.QComboBox):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.references = [Cyclohexane]
for ref in self.references:
self.addItem(ref.name)
def get_reference(self):
return self.references[self.currentIndex()]