extrapolate_fit (#21)
New sets with arbitrary x range can be created from fit results Co-authored-by: Dominik Demuth <dominik.demuth@physik.tu-darmstadt.de> Reviewed-on: #21
This commit is contained in:
@ -11,10 +11,10 @@ from pyqtgraph import ViewBox
|
||||
from nmreval.configs import *
|
||||
|
||||
from .management import UpperManagement
|
||||
from ..Qt import QtCore, QtGui, QtPrintSupport, QtWidgets
|
||||
from ..Qt import QtGui, QtPrintSupport
|
||||
from ..data.shift_graphs import QShift
|
||||
from ..data.signaledit import QApodDialog, QBaselineDialog, QPhasedialog
|
||||
from ..fit.result import QFitResult
|
||||
from ..fit.result import FitExtension, QFitResult
|
||||
from ..graphs.graphwindow import QGraphWindow
|
||||
from ..graphs.movedialog import QMover
|
||||
from ..io.fcbatchreader import QFCReader
|
||||
@ -164,6 +164,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
||||
self.datawidget.startShowProperty.connect(self.management.get_properties)
|
||||
self.datawidget.propertyChanged.connect(self.management.update_property)
|
||||
self.datawidget.tree.saveFits.connect(self.save_fit_parameter)
|
||||
self.datawidget.tree.extendFits.connect(self.extend_fit)
|
||||
|
||||
self.management.newData.connect(self.show_new_data)
|
||||
self.management.newGraph.connect(self.new_graph)
|
||||
@ -907,10 +908,10 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
||||
res_dialog.redoFit.connect(self.management.redo_fits)
|
||||
res_dialog.show()
|
||||
|
||||
@QtCore.pyqtSlot(dict, list, str, bool, dict)
|
||||
def accepts_fit(self, res: dict, opts: list, param_graph: str, show_fit: bool, parts: dict) -> None:
|
||||
@QtCore.pyqtSlot(dict, list, str, bool, bool, list)
|
||||
def accepts_fit(self, res: dict, opts: list, param_graph: str, show_fit: bool, parts: bool, extrapolate: list) -> None:
|
||||
self.fit_dialog.set_parameter(res)
|
||||
self.management.make_fits(res, opts, param_graph, show_fit, parts)
|
||||
self.management.make_fits(res, opts, param_graph, show_fit, parts, extrapolate)
|
||||
|
||||
@QtCore.pyqtSlot(name='on_actionFunction_editor_triggered')
|
||||
def edit_models(self):
|
||||
@ -922,6 +923,16 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
||||
self.editor.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
self.editor.show()
|
||||
|
||||
@QtCore.pyqtSlot(list)
|
||||
def extend_fit(self, sets: list):
|
||||
w = FitExtension(self)
|
||||
res = w.exec()
|
||||
print(res)
|
||||
if res:
|
||||
p = w.values
|
||||
x = linspace(p[0], p[1], num=p[2])
|
||||
self.management.extend_fits(sets, x)
|
||||
|
||||
@QtCore.pyqtSlot(name='on_action_create_fit_function_triggered')
|
||||
def open_fitmodel_wizard(self):
|
||||
from ..fit.function_creation_dialog import QUserFitCreator
|
||||
@ -931,7 +942,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
||||
|
||||
helper.show()
|
||||
|
||||
|
||||
@QtCore.pyqtSlot(name='on_actionShift_triggered')
|
||||
def shift_dialog(self):
|
||||
s = QShift(self)
|
||||
|
@ -4,6 +4,8 @@ import pathlib
|
||||
import re
|
||||
import uuid
|
||||
|
||||
import numpy as np
|
||||
|
||||
from nmreval.fit import data as fit_d
|
||||
from nmreval.fit.model import Model
|
||||
from nmreval.fit.result import FitResult
|
||||
@ -482,7 +484,7 @@ class UpperManagement(QtCore.QObject):
|
||||
parameter[set_id] = (new_values, set_parameter[1])
|
||||
self.start_fit(*self.__fit_options)
|
||||
|
||||
def make_fits(self, res: dict, opts: list, param_graph: str, show_fit: bool, parts: dict) -> None:
|
||||
def make_fits(self, res: dict, opts: list, param_graph: str, show_fit: bool, parts: bool, extrapolate: list) -> None:
|
||||
"""
|
||||
|
||||
Args:
|
||||
@ -491,6 +493,7 @@ class UpperManagement(QtCore.QObject):
|
||||
param_graph: None if no parameter to plot, '' for new graph, or id of existig graph
|
||||
show_fit: plot fit curve?
|
||||
parts: key is that of original data, value is list of subplots
|
||||
extrapolate:
|
||||
|
||||
"""
|
||||
f_id_list = []
|
||||
@ -503,6 +506,26 @@ class UpperManagement(QtCore.QObject):
|
||||
if reject:
|
||||
continue
|
||||
|
||||
if not all(e is None for e in extrapolate):
|
||||
spacefunc = np.geomspace if fit.islog else np.linspace
|
||||
|
||||
xmin = fit.x.min()
|
||||
xmax = fit.x.max()
|
||||
|
||||
len_data = len(fit.x_data)
|
||||
num_pts = 20*len_data-9 if len_data < 51 else 3*len_data
|
||||
|
||||
if extrapolate[0] is not None:
|
||||
xmin = extrapolate[0]
|
||||
if extrapolate[1] is not None:
|
||||
xmax = extrapolate[1]
|
||||
if extrapolate[2] is not None:
|
||||
num_pts = extrapolate[2]
|
||||
|
||||
_x = spacefunc(xmin, xmax, num=num_pts)
|
||||
|
||||
fit = fit.with_new_x(_x)
|
||||
|
||||
data_k = self.data[k]
|
||||
if delete_prev:
|
||||
tobedeleted.extend([f.id for f in data_k.get_fits()])
|
||||
@ -527,18 +550,16 @@ class UpperManagement(QtCore.QObject):
|
||||
f_id_list.append(f_id)
|
||||
data_k.set_fits(f_id)
|
||||
|
||||
if parts:
|
||||
color_scheme = available_cycles['colorblind']
|
||||
for subfunc, col in zip(fit.sub(fit.x), cycle(color_scheme)):
|
||||
subfunc.value = data_k.value
|
||||
subfunc.group = data_k.group
|
||||
subfunc.name += data_name
|
||||
sub_f_id = self.add(subfunc, color=col, linestyle=LineStyle.Dashed, symbol=SymbolStyle.No)
|
||||
|
||||
f_id_list.append(sub_f_id)
|
||||
gid = data_k.graph
|
||||
|
||||
if k in parts and show_fit:
|
||||
color_scheme = available_cycles['colorblind']
|
||||
for subfunc, col in zip(parts[k], cycle(color_scheme)):
|
||||
subfunc.value = data_k.value
|
||||
subfunc.group = data_k.group
|
||||
subfunc.name += data_name
|
||||
sub_f_id = self.add(subfunc, color=col, linestyle=LineStyle.Dashed, symbol=SymbolStyle.No)
|
||||
|
||||
f_id_list.append(sub_f_id)
|
||||
|
||||
self.delete_sets(tobedeleted)
|
||||
|
||||
if accepted and (param_graph != '-1'):
|
||||
@ -546,6 +567,27 @@ class UpperManagement(QtCore.QObject):
|
||||
|
||||
self.newData.emit(f_id_list, gid)
|
||||
|
||||
def extend_fits(self, set_id: list, x_range: np.ndarray):
|
||||
graphs = {}
|
||||
for sid in set_id:
|
||||
data = self[sid]
|
||||
fit = data.copy(full=True, keep_color=True)
|
||||
fit.data = fit.data.with_new_x(x_range)
|
||||
|
||||
graph_id = data.graph
|
||||
if graph_id not in graphs:
|
||||
graphs[graph_id] = []
|
||||
graphs[graph_id].append(self.add(fit))
|
||||
|
||||
color_scheme = available_cycles['colorblind']
|
||||
for subfunc, col in zip(fit.data.sub(fit.x), cycle(color_scheme)):
|
||||
subfunc.value = fit.value
|
||||
subfunc.group = fit.group
|
||||
graphs[graph_id].append(self.add(subfunc, color=col, linestyle=LineStyle.Dashed, symbol=SymbolStyle.No))
|
||||
|
||||
for k, v in graphs.items():
|
||||
self.newData.emit(v, k)
|
||||
|
||||
def make_fit_parameter(self, fit_sets: list[str | FitResult], graph_id: str = None):
|
||||
fit_dict = self._collect_fit_parameter(fit_sets)
|
||||
|
||||
|
Reference in New Issue
Block a user