Merge branch 'master' into 234-value-tooltip
This commit is contained in:
commit
c81450843e
@ -365,6 +365,9 @@ class Ui_BaseWindow(object):
|
|||||||
self.actionBinning.setObjectName("actionBinning")
|
self.actionBinning.setObjectName("actionBinning")
|
||||||
self.actionTNMH = QtWidgets.QAction(BaseWindow)
|
self.actionTNMH = QtWidgets.QAction(BaseWindow)
|
||||||
self.actionTNMH.setObjectName("actionTNMH")
|
self.actionTNMH.setObjectName("actionTNMH")
|
||||||
|
self.actionExclude_region = QtWidgets.QAction(BaseWindow)
|
||||||
|
self.actionExclude_region.setCheckable(True)
|
||||||
|
self.actionExclude_region.setObjectName("actionExclude_region")
|
||||||
self.menuSave.addAction(self.actionSave)
|
self.menuSave.addAction(self.actionSave)
|
||||||
self.menuSave.addAction(self.actionExportGraphic)
|
self.menuSave.addAction(self.actionExportGraphic)
|
||||||
self.menuSave.addAction(self.action_save_fit_parameter)
|
self.menuSave.addAction(self.action_save_fit_parameter)
|
||||||
@ -419,6 +422,7 @@ class Ui_BaseWindow(object):
|
|||||||
self.menuLimits.addAction(self.action_no_range)
|
self.menuLimits.addAction(self.action_no_range)
|
||||||
self.menuLimits.addAction(self.action_x_range)
|
self.menuLimits.addAction(self.action_x_range)
|
||||||
self.menuLimits.addAction(self.action_custom_range)
|
self.menuLimits.addAction(self.action_custom_range)
|
||||||
|
self.menuLimits.addAction(self.actionExclude_region)
|
||||||
self.menuFit.addAction(self.action_FitWidget)
|
self.menuFit.addAction(self.action_FitWidget)
|
||||||
self.menuFit.addSeparator()
|
self.menuFit.addSeparator()
|
||||||
self.menuFit.addAction(self.action_create_fit_function)
|
self.menuFit.addAction(self.action_create_fit_function)
|
||||||
@ -631,6 +635,7 @@ class Ui_BaseWindow(object):
|
|||||||
self.actionTNMH_model.setText(_translate("BaseWindow", "Tg , Hodge, TNMH,,,"))
|
self.actionTNMH_model.setText(_translate("BaseWindow", "Tg , Hodge, TNMH,,,"))
|
||||||
self.actionBinning.setText(_translate("BaseWindow", "Binning..."))
|
self.actionBinning.setText(_translate("BaseWindow", "Binning..."))
|
||||||
self.actionTNMH.setText(_translate("BaseWindow", "TNMH..."))
|
self.actionTNMH.setText(_translate("BaseWindow", "TNMH..."))
|
||||||
|
self.actionExclude_region.setText(_translate("BaseWindow", "Exclude region"))
|
||||||
from ..data.datawidget.datawidget import DataWidget
|
from ..data.datawidget.datawidget import DataWidget
|
||||||
from ..data.integral_widget import IntegralWidget
|
from ..data.integral_widget import IntegralWidget
|
||||||
from ..data.point_select import PointSelectWidget
|
from ..data.point_select import PointSelectWidget
|
||||||
|
@ -136,8 +136,8 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
|||||||
max_x = max(max_x, data.x.max())
|
max_x = max(max_x, data.x.max())
|
||||||
|
|
||||||
item = QtWidgets.QListWidgetItem(name)
|
item = QtWidgets.QListWidgetItem(name)
|
||||||
item.setCheckState(QtCore.Qt.Checked)
|
item.setCheckState(QtCore.Qt.CheckState.Checked)
|
||||||
item.setData(QtCore.Qt.UserRole, key)
|
item.setData(QtCore.Qt.ItemDataRole.UserRole, key)
|
||||||
item.setForeground(mkBrush(c.rgb()))
|
item.setForeground(mkBrush(c.rgb()))
|
||||||
self.listWidget.addItem(item)
|
self.listWidget.addItem(item)
|
||||||
|
|
||||||
@ -191,10 +191,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
|||||||
|
|
||||||
for idx in range(self.listWidget.count()):
|
for idx in range(self.listWidget.count()):
|
||||||
item = self.listWidget.item(idx)
|
item = self.listWidget.item(idx)
|
||||||
if item.checkState() == QtCore.Qt.Unchecked:
|
if item.checkState() == QtCore.Qt.CheckState.Unchecked:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
key = item.data(QtCore.Qt.UserRole)
|
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||||
plot = self._plots[key]
|
plot = self._plots[key]
|
||||||
data, _ = self._dsc[key]
|
data, _ = self._dsc[key]
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
|||||||
item = self.listWidget.item(idx)
|
item = self.listWidget.item(idx)
|
||||||
|
|
||||||
tree_item = QtWidgets.QTreeWidgetItem([item.text()])
|
tree_item = QtWidgets.QTreeWidgetItem([item.text()])
|
||||||
values = self._tg_value.get(item.data(QtCore.Qt.UserRole))
|
values = self._tg_value.get(item.data(QtCore.Qt.ItemDataRole.UserRole))
|
||||||
|
|
||||||
if values is not None:
|
if values is not None:
|
||||||
for name, pos in values.items():
|
for name, pos in values.items():
|
||||||
@ -223,7 +223,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
|||||||
|
|
||||||
self.tg_tree.addTopLevelItem(tree_item)
|
self.tg_tree.addTopLevelItem(tree_item)
|
||||||
|
|
||||||
key = item.data(QtCore.Qt.UserRole)
|
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||||
plot = self._plots[key]
|
plot = self._plots[key]
|
||||||
data, _ = self._dsc[key]
|
data, _ = self._dsc[key]
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
|||||||
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
|
@QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
|
||||||
def change_visibility(self, item: QtWidgets.QListWidgetItem):
|
def change_visibility(self, item: QtWidgets.QListWidgetItem):
|
||||||
is_checked = bool(item.checkState())
|
is_checked = bool(item.checkState())
|
||||||
plot = self._plots[item.data(QtCore.Qt.UserRole)]
|
plot = self._plots[item.data(QtCore.Qt.ItemDataRole.UserRole)]
|
||||||
for val in plot:
|
for val in plot:
|
||||||
val.setVisible(is_checked)
|
val.setVisible(is_checked)
|
||||||
|
|
||||||
@ -275,10 +275,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
|||||||
self.tnmh_tree.clear()
|
self.tnmh_tree.clear()
|
||||||
for idx in range(self.listWidget.count()):
|
for idx in range(self.listWidget.count()):
|
||||||
item = self.listWidget.item(idx)
|
item = self.listWidget.item(idx)
|
||||||
if item.checkState() == QtCore.Qt.Unchecked:
|
if item.checkState() == QtCore.Qt.CheckState.Unchecked:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
key = item.data(QtCore.Qt.UserRole)
|
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||||
|
|
||||||
data = self.get_fictive(key, baselines)
|
data = self.get_fictive(key, baselines)
|
||||||
|
|
||||||
@ -292,7 +292,7 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
|||||||
item = self.listWidget.item(idx)
|
item = self.listWidget.item(idx)
|
||||||
|
|
||||||
tree_item = QtWidgets.QTreeWidgetItem([item.text()])
|
tree_item = QtWidgets.QTreeWidgetItem([item.text()])
|
||||||
values = self._fit.get(item.data(QtCore.Qt.UserRole))
|
values = self._fit.get(item.data(QtCore.Qt.ItemDataRole.UserRole))
|
||||||
|
|
||||||
if values is not None:
|
if values is not None:
|
||||||
child_item = QtWidgets.QTreeWidgetItem([values.parameter_string()])
|
child_item = QtWidgets.QTreeWidgetItem([values.parameter_string()])
|
||||||
@ -305,10 +305,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
|||||||
ret_dic = {}
|
ret_dic = {}
|
||||||
for idx in range(self.listWidget.count()):
|
for idx in range(self.listWidget.count()):
|
||||||
item = self.listWidget.item(idx)
|
item = self.listWidget.item(idx)
|
||||||
if item.checkState() == QtCore.Qt.Unchecked:
|
if item.checkState() == QtCore.Qt.CheckState.Unchecked:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
key = item.data(QtCore.Qt.UserRole)
|
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||||
|
|
||||||
cp = None
|
cp = None
|
||||||
if self.fictive_export_check.isChecked():
|
if self.fictive_export_check.isChecked():
|
||||||
@ -332,10 +332,10 @@ class TgCalculator(QtWidgets.QWizard, Ui_DSCEvalDialog):
|
|||||||
m = []
|
m = []
|
||||||
for idx in range(self.listWidget.count()):
|
for idx in range(self.listWidget.count()):
|
||||||
item = self.listWidget.item(idx)
|
item = self.listWidget.item(idx)
|
||||||
if item.checkState() == QtCore.Qt.Unchecked:
|
if item.checkState() == QtCore.Qt.CheckState.Unchecked:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
key = item.data(QtCore.Qt.UserRole)
|
key = item.data(QtCore.Qt.ItemDataRole.UserRole)
|
||||||
data, _ = self._dsc[key]
|
data, _ = self._dsc[key]
|
||||||
try:
|
try:
|
||||||
tg_value = self._tg_value[key][tg_type][0]
|
tg_value = self._tg_value[key][tg_type][0]
|
||||||
|
@ -58,7 +58,8 @@ class FitToolbar(QtWidgets.QToolBar):
|
|||||||
|
|
||||||
@QtCore.pyqtSlot(QtWidgets.QAction)
|
@QtCore.pyqtSlot(QtWidgets.QAction)
|
||||||
def change_limit_type(self, action: QtWidgets.QAction):
|
def change_limit_type(self, action: QtWidgets.QAction):
|
||||||
is_custom = (action.text() == 'Custom')
|
is_custom = (action.text() in ['Custom', 'Exclude region'])
|
||||||
|
print(is_custom)
|
||||||
|
|
||||||
for w in [self.label, self.label2, self.lineedit, self.lineedit2]:
|
for w in [self.label, self.label2, self.lineedit, self.lineedit2]:
|
||||||
w.setEnabled(is_custom)
|
w.setEnabled(is_custom)
|
||||||
@ -93,5 +94,6 @@ class FitToolbar(QtWidgets.QToolBar):
|
|||||||
return {
|
return {
|
||||||
'None': 'none',
|
'None': 'none',
|
||||||
'Visible x range': 'x',
|
'Visible x range': 'x',
|
||||||
'Custom': self.region.getRegion(),
|
'Custom': ('in', self.region.getRegion()),
|
||||||
|
'Exclude region': ('out', self.region.getRegion()),
|
||||||
}[action_text]
|
}[action_text]
|
||||||
|
@ -264,11 +264,16 @@ class QDSCReader(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.cp_checkBox.isChecked() and self.references:
|
||||||
|
y_label = 'cp'
|
||||||
|
else:
|
||||||
|
y_label = 'q'
|
||||||
|
|
||||||
rate, mode = self.current_run
|
rate, mode = self.current_run
|
||||||
new_val = DSC(sample_data[0], sample_data[1], value=rate, name=f'{self.fname.stem} {rate} ({mode})')
|
new_val = DSC(sample_data[0], sample_data[1], value=rate, name=f'{self.fname.stem} {rate}K-min ({mode}, {y_label})')
|
||||||
|
|
||||||
if filesave:
|
if filesave:
|
||||||
new_val.savetxt(self.fname.with_name(f'{self.fname.stem} {rate}K-min {mode}.dat'.replace(' ', '_')))
|
new_val.savetxt(self.fname.with_name(f'{self.fname.stem}_{rate}K-min_{y_label}{mode}.dat'.replace(' ', '_')))
|
||||||
close_after = False
|
close_after = False
|
||||||
else:
|
else:
|
||||||
self.data_read.emit([new_val])
|
self.data_read.emit([new_val])
|
||||||
|
@ -888,7 +888,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
|||||||
self.fit_dialog.load(self.management.active_sets)
|
self.fit_dialog.load(self.management.active_sets)
|
||||||
for item in self.fit_dialog.preview_lines:
|
for item in self.fit_dialog.preview_lines:
|
||||||
self.current_graph_widget.add_external(item)
|
self.current_graph_widget.add_external(item)
|
||||||
if self.action_custom_range.isChecked():
|
if self.action_custom_range.isChecked() or self.actionExclude_region.isChecked():
|
||||||
self.current_graph_widget.add_external(self.fit_toolbar.region)
|
self.current_graph_widget.add_external(self.fit_toolbar.region)
|
||||||
|
|
||||||
block_window = True
|
block_window = True
|
||||||
@ -904,7 +904,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
|||||||
if self.current_graph_widget is None:
|
if self.current_graph_widget is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if action == self.action_custom_range and self.fit_dialog.isVisible():
|
if action in [self.action_custom_range, self.actionExclude_region] and self.fit_dialog.isVisible():
|
||||||
self.current_graph_widget.add_external(self.fit_toolbar.region)
|
self.current_graph_widget.add_external(self.fit_toolbar.region)
|
||||||
else:
|
else:
|
||||||
self.current_graph_widget.remove_external(self.fit_toolbar.region)
|
self.current_graph_widget.remove_external(self.fit_toolbar.region)
|
||||||
|
@ -511,13 +511,16 @@ class UpperManagement(QtCore.QObject):
|
|||||||
|
|
||||||
_x = data_i.x
|
_x = data_i.x
|
||||||
|
|
||||||
|
# options for fit limits 'none', 'x', ('in', custom region), ('out', excluded region)
|
||||||
if fit_limits == 'none':
|
if fit_limits == 'none':
|
||||||
inside = slice(None)
|
inside = slice(None)
|
||||||
elif fit_limits == 'x':
|
elif fit_limits == 'x':
|
||||||
x_lim, _ = self.graphs[self.current_graph].ranges
|
x_lim, _ = self.graphs[self.current_graph].ranges
|
||||||
inside = np.where((_x >= x_lim[0]) & (_x <= x_lim[1]))
|
inside = np.where((_x >= x_lim[0]) & (_x <= x_lim[1]))
|
||||||
|
elif fit_limits[0] == 'in':
|
||||||
|
inside = np.where((_x >= fit_limits[1][0]) & (_x <= fit_limits[1][1]))
|
||||||
else:
|
else:
|
||||||
inside = np.where((_x >= fit_limits[0]) & (_x <= fit_limits[1]))
|
inside = np.where((_x < fit_limits[1][0]) | (_x > fit_limits[1][1]))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if isinstance(we, str):
|
if isinstance(we, str):
|
||||||
|
@ -11,7 +11,8 @@ try:
|
|||||||
from scipy.integrate import simpson
|
from scipy.integrate import simpson
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from scipy.integrate import simps as simpson
|
from scipy.integrate import simps as simpson
|
||||||
from scipy.interpolate import interp1d
|
from scipy.interpolate import CubicSpline
|
||||||
|
|
||||||
|
|
||||||
ReferenceValue = namedtuple('Reference', ['name', 'transitions'])
|
ReferenceValue = namedtuple('Reference', ['name', 'transitions'])
|
||||||
Cyclohexane = ReferenceValue('Cyclohexane', [(-87.06+273.15, 79.58), (6.54+273.15, None)])
|
Cyclohexane = ReferenceValue('Cyclohexane', [(-87.06+273.15, 79.58), (6.54+273.15, None)])
|
||||||
@ -38,7 +39,7 @@ class DSCSample:
|
|||||||
def read_file(self, fname: str | Path) -> None:
|
def read_file(self, fname: str | Path) -> None:
|
||||||
fname = Path(fname)
|
fname = Path(fname)
|
||||||
|
|
||||||
# file contains weird deg C character in stupiod ISO encoding
|
# file contains weird deg C character in stupid ISO encoding
|
||||||
with fname.open('r', encoding='iso-8859-15') as f:
|
with fname.open('r', encoding='iso-8859-15') as f:
|
||||||
ii = 1
|
ii = 1
|
||||||
for line in f:
|
for line in f:
|
||||||
@ -144,9 +145,12 @@ class DSCCalibrator:
|
|||||||
self.reference = []
|
self.reference = []
|
||||||
self.ref_list = []
|
self.ref_list = []
|
||||||
|
|
||||||
def set_measurement(self,
|
def set_measurement(
|
||||||
fname: str | Path | DSCSample, mode: str = 'sample',
|
self: DSCCalibrator,
|
||||||
reference: ReferenceValue = Cyclohexane):
|
fname: str | Path | DSCSample,
|
||||||
|
mode: str = 'sample',
|
||||||
|
reference: ReferenceValue = Cyclohexane
|
||||||
|
):
|
||||||
if mode not in ['sample', 'empty', 'reference']:
|
if mode not in ['sample', 'empty', 'reference']:
|
||||||
raise ValueError(f'Unknown mode {mode}, not "sample", "empty", "reference"')
|
raise ValueError(f'Unknown mode {mode}, not "sample", "empty", "reference"')
|
||||||
if mode == 'reference' and not isinstance(reference, ReferenceValue):
|
if mode == 'reference' and not isinstance(reference, ReferenceValue):
|
||||||
@ -266,7 +270,12 @@ class DSCCalibrator:
|
|||||||
|
|
||||||
return sol
|
return sol
|
||||||
|
|
||||||
def get_data(self, idx: int, slope: str = 'iso', limits: tuple[float, float] = None):
|
def get_data(
|
||||||
|
self: DSCCalibrator,
|
||||||
|
idx: int,
|
||||||
|
slope: str = 'iso',
|
||||||
|
limits: tuple[float, float] = None
|
||||||
|
) -> tuple[np.ndarray, np.ndarray, np.ndarray,np.ndarray | None, np.ndarray]:
|
||||||
if self.sample.steps[idx][0] == 'i':
|
if self.sample.steps[idx][0] == 'i':
|
||||||
raise ValueError('baseline correction is not implemented for isotherms')
|
raise ValueError('baseline correction is not implemented for isotherms')
|
||||||
|
|
||||||
@ -292,7 +301,7 @@ class DSCCalibrator:
|
|||||||
empty_y = empty_data[1]
|
empty_y = empty_data[1]
|
||||||
if self.sample.length(idx) != self.empty.length(idx_empty):
|
if self.sample.length(idx) != self.empty.length(idx_empty):
|
||||||
with np.errstate(all='ignore'):
|
with np.errstate(all='ignore'):
|
||||||
empty_y = interp1d(empty_data[2]-empty_data[2, 0], empty_data[1], fill_value='extrapolate')(sample_data[2, 0])
|
empty_y = CubicSpline(empty_data[2]-empty_data[2, 0], empty_data[1], extrapolate=True)(sample_data[2] - sample_data[2, 0])
|
||||||
|
|
||||||
sample_data[1] -= empty_y
|
sample_data[1] -= empty_y
|
||||||
drift_value = sample_data.copy()[(2, 1), :]
|
drift_value = sample_data.copy()[(2, 1), :]
|
||||||
@ -346,9 +355,10 @@ class DSCCalibrator:
|
|||||||
|
|
||||||
offset = region[0, 0]
|
offset = region[0, 0]
|
||||||
sample_data[1] -= m * (sample_data[2] - region[1, 0]) + offset
|
sample_data[1] -= m * (sample_data[2] - region[1, 0]) + offset
|
||||||
line = np.array([[sample_data[2, 0], sample_data[2, -1]],
|
line = np.array([
|
||||||
[m * (sample_data[2, 0] - region[1, 0]) + offset,
|
[sample_data[2, 0], sample_data[2, -1]],
|
||||||
m * (sample_data[2, -1] - region[1, 0]) + offset]])
|
[m * (sample_data[2, 0] - region[1, 0]) + offset, m * (sample_data[2, -1] - region[1, 0]) + offset]
|
||||||
|
])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
line = np.array([[sample_data[2, 0], sample_data[2, -1]], [0, 0]])
|
line = np.array([[sample_data[2, 0], sample_data[2, -1]], [0, 0]])
|
||||||
|
@ -247,6 +247,7 @@
|
|||||||
<addaction name="action_no_range"/>
|
<addaction name="action_no_range"/>
|
||||||
<addaction name="action_x_range"/>
|
<addaction name="action_x_range"/>
|
||||||
<addaction name="action_custom_range"/>
|
<addaction name="action_custom_range"/>
|
||||||
|
<addaction name="actionExclude_region"/>
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="action_FitWidget"/>
|
<addaction name="action_FitWidget"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
@ -1021,6 +1022,14 @@
|
|||||||
<string>TNMH...</string>
|
<string>TNMH...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionExclude_region">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Exclude region</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
Loading…
Reference in New Issue
Block a user