forked from IPKM/nmreval
catch errors in fit preparation
This commit is contained in:
parent
e2e52cebde
commit
a406908a69
@ -298,7 +298,8 @@ class ParameterSingleWidget(QtWidgets.QWidget):
|
|||||||
|
|
||||||
self._name = name
|
self._name = name
|
||||||
self.label.setText(convert(name))
|
self.label.setText(convert(name))
|
||||||
self.label.setToolTip('If this is bold then this parameter is only for this data. otherwise the general parameter is used and displayed')
|
self.label.setToolTip('If this is bold then this parameter is only for this data. '
|
||||||
|
'Otherwise, the general parameter is used and displayed')
|
||||||
|
|
||||||
self.value_line.setValidator(QtGui.QDoubleValidator())
|
self.value_line.setValidator(QtGui.QDoubleValidator())
|
||||||
self.value_line.textChanged.connect(lambda: self.valueChanged.emit(self.value) if self.value is not None else 0)
|
self.value_line.textChanged.connect(lambda: self.valueChanged.emit(self.value) if self.value is not None else 0)
|
||||||
|
@ -916,10 +916,12 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
|
|||||||
self.action_odr_fit: 'odr'
|
self.action_odr_fit: 'odr'
|
||||||
}[self.ac_group.checkedAction()]
|
}[self.ac_group.checkedAction()]
|
||||||
|
|
||||||
self.fit_dialog.fit_button.setEnabled(False)
|
fit_is_ready = self.management.prepare_fit(parameter, links, fit_options)
|
||||||
self.management.start_fit(parameter, links, fit_options)
|
if fit_is_ready:
|
||||||
self.status.setText('Fit running...'.format(self.management.fitter.step))
|
self.management.start_fit()
|
||||||
self.fit_timer.start(500)
|
self.fit_dialog.fit_button.setEnabled(False)
|
||||||
|
self.status.setText('Fit running...'.format(self.management.fitter.step))
|
||||||
|
self.fit_timer.start(500)
|
||||||
|
|
||||||
@QtCore.pyqtSlot(dict, int, bool)
|
@QtCore.pyqtSlot(dict, int, bool)
|
||||||
def show_fit_preview(self, funcs: dict, num: int, show: bool):
|
def show_fit_preview(self, funcs: dict, num: int, show: bool):
|
||||||
|
@ -424,9 +424,9 @@ class UpperManagement(QtCore.QObject):
|
|||||||
for d in self.data.values():
|
for d in self.data.values():
|
||||||
d.mask = np.ones_like(d.mask, dtype=bool)
|
d.mask = np.ones_like(d.mask, dtype=bool)
|
||||||
|
|
||||||
def start_fit(self, parameter: dict, links: list, fit_options: dict):
|
def prepare_fit(self, parameter: dict, links: list, fit_options: dict) -> bool:
|
||||||
if self._fit_active:
|
if self._fit_active:
|
||||||
return
|
return False
|
||||||
|
|
||||||
self.__fit_options = (parameter, links, fit_options)
|
self.__fit_options = (parameter, links, fit_options)
|
||||||
|
|
||||||
@ -436,67 +436,80 @@ class UpperManagement(QtCore.QObject):
|
|||||||
fit_mode = fit_options['fit_mode']
|
fit_mode = fit_options['fit_mode']
|
||||||
we_option = fit_options['we']
|
we_option = fit_options['we']
|
||||||
|
|
||||||
for model_id, model_p in parameter.items():
|
self.fitter.fitmethod = fit_mode
|
||||||
m = Model(model_p['func'])
|
|
||||||
models[model_id] = m
|
|
||||||
|
|
||||||
m_complex = model_p['complex']
|
# all-encompassing error catch
|
||||||
|
try:
|
||||||
|
for model_id, model_p in parameter.items():
|
||||||
|
m = Model(model_p['func'])
|
||||||
|
models[model_id] = m
|
||||||
|
|
||||||
# sets are not in active order but in order they first appeared in fit dialog
|
m_complex = model_p['complex']
|
||||||
# iterate over order of set id in active order and access parameter inside loop
|
|
||||||
# instead of directly looping
|
|
||||||
list_ids = list(model_p['parameter'].keys())
|
|
||||||
set_order = [self.active_id.index(i) for i in list_ids]
|
|
||||||
for pos in set_order:
|
|
||||||
set_id = list_ids[pos]
|
|
||||||
|
|
||||||
data_i = self.data[set_id]
|
# sets are not in active order but in order they first appeared in fit dialog
|
||||||
set_params = model_p['parameter'][set_id]
|
# iterate over order of set id in active order and access parameter inside loop
|
||||||
|
# instead of directly looping
|
||||||
|
list_ids = list(model_p['parameter'].keys())
|
||||||
|
set_order = [self.active_id.index(i) for i in list_ids]
|
||||||
|
for pos in set_order:
|
||||||
|
set_id = list_ids[pos]
|
||||||
|
|
||||||
if we_option.lower() == 'deltay':
|
data_i = self.data[set_id]
|
||||||
we = data_i.y_err**2
|
set_params = model_p['parameter'][set_id]
|
||||||
else:
|
|
||||||
we = we_option
|
|
||||||
|
|
||||||
if m_complex is None or m_complex == 1:
|
if we_option.lower() == 'deltay':
|
||||||
_y = data_i.y.real
|
we = data_i.y_err**2
|
||||||
elif m_complex == 2 and np.iscomplexobj(data_i.y):
|
else:
|
||||||
_y = data_i.y.imag
|
we = we_option
|
||||||
else:
|
|
||||||
_y = data_i.y
|
|
||||||
|
|
||||||
_x = data_i.x
|
if m_complex is None or m_complex == 1:
|
||||||
|
_y = data_i.y.real
|
||||||
|
elif m_complex == 2 and np.iscomplexobj(data_i.y):
|
||||||
|
_y = data_i.y.imag
|
||||||
|
else:
|
||||||
|
_y = data_i.y
|
||||||
|
|
||||||
if fit_limits == 'none':
|
_x = data_i.x
|
||||||
inside = slice(None)
|
|
||||||
elif fit_limits == 'x':
|
|
||||||
x_lim, _ = self.graphs[self.current_graph].ranges
|
|
||||||
inside = np.where((_x >= x_lim[0]) & (_x <= x_lim[1]))
|
|
||||||
else:
|
|
||||||
inside = np.where((_x >= fit_limits[0]) & (_x <= fit_limits[1]))
|
|
||||||
|
|
||||||
if isinstance(we, str):
|
if fit_limits == 'none':
|
||||||
d = fit_d.Data(_x[inside], _y[inside], we=we, idx=set_id)
|
inside = slice(None)
|
||||||
else:
|
elif fit_limits == 'x':
|
||||||
d = fit_d.Data(_x[inside], _y[inside], we=we[inside], idx=set_id)
|
x_lim, _ = self.graphs[self.current_graph].ranges
|
||||||
|
inside = np.where((_x >= x_lim[0]) & (_x <= x_lim[1]))
|
||||||
|
else:
|
||||||
|
inside = np.where((_x >= fit_limits[0]) & (_x <= fit_limits[1]))
|
||||||
|
|
||||||
d.set_model(m)
|
if isinstance(we, str):
|
||||||
d.set_parameter(set_params[0], var=model_p['var'],
|
d = fit_d.Data(_x[inside], _y[inside], we=we, idx=set_id)
|
||||||
lb=model_p['lb'], ub=model_p['ub'],
|
else:
|
||||||
fun_kwargs=set_params[1])
|
d = fit_d.Data(_x[inside], _y[inside], we=we[inside], idx=set_id)
|
||||||
|
|
||||||
self.fitter.add_data(d)
|
d.set_model(m)
|
||||||
|
d.set_parameter(set_params[0], var=model_p['var'],
|
||||||
|
lb=model_p['lb'], ub=model_p['ub'],
|
||||||
|
fun_kwargs=set_params[1])
|
||||||
|
|
||||||
model_globs = model_p['glob']
|
self.fitter.add_data(d)
|
||||||
if model_globs:
|
|
||||||
m.set_global_parameter(**model_p['glob'])
|
|
||||||
|
|
||||||
for links_i in links:
|
model_globs = model_p['glob']
|
||||||
self.fitter.set_link_parameter((models[links_i[0]], links_i[1]),
|
if model_globs:
|
||||||
(models[links_i[2]], links_i[3]))
|
m.set_global_parameter(**model_p['glob'])
|
||||||
|
|
||||||
|
for links_i in links:
|
||||||
|
self.fitter.set_link_parameter((models[links_i[0]], links_i[1]),
|
||||||
|
(models[links_i[2]], links_i[3]))
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error('Fit preparation failed', *e.args)
|
||||||
|
QtWidgets.QMessageBox.warning(QtWidgets.QWidget(),
|
||||||
|
'Fit prep failed',
|
||||||
|
f'Fit preparation failed with message\n{e.args}')
|
||||||
|
return False
|
||||||
|
|
||||||
|
def start_fit(self):
|
||||||
with busy_cursor():
|
with busy_cursor():
|
||||||
self.fit_worker = FitWorker(self.fitter, fit_mode)
|
self.fit_worker = FitWorker(self.fitter)
|
||||||
self.fit_thread = QtCore.QThread()
|
self.fit_thread = QtCore.QThread()
|
||||||
self.fit_worker.moveToThread(self.fit_thread)
|
self.fit_worker.moveToThread(self.fit_thread)
|
||||||
|
|
||||||
@ -532,7 +545,8 @@ class UpperManagement(QtCore.QObject):
|
|||||||
for set_id, set_parameter in parameter.items():
|
for set_id, set_parameter in parameter.items():
|
||||||
new_values = [v.value for v in res[set_id].parameter.values()]
|
new_values = [v.value for v in res[set_id].parameter.values()]
|
||||||
parameter[set_id] = (new_values, set_parameter[1])
|
parameter[set_id] = (new_values, set_parameter[1])
|
||||||
self.start_fit(*self.__fit_options)
|
if self.prepare_fit(*self.__fit_options):
|
||||||
|
self.start_fit()
|
||||||
|
|
||||||
def make_fits(self, res: dict, opts: list, param_graph: str, show_fit: bool, parts: bool, extrapolate: list) -> None:
|
def make_fits(self, res: dict, opts: list, param_graph: str, show_fit: bool, parts: bool, extrapolate: list) -> None:
|
||||||
"""
|
"""
|
||||||
@ -1270,16 +1284,15 @@ class UpperManagement(QtCore.QObject):
|
|||||||
class FitWorker(QtCore.QObject):
|
class FitWorker(QtCore.QObject):
|
||||||
finished = QtCore.pyqtSignal(list, bool)
|
finished = QtCore.pyqtSignal(list, bool)
|
||||||
|
|
||||||
def __init__(self, fitter, mode):
|
def __init__(self, fitter):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.fitter = fitter
|
self.fitter = fitter
|
||||||
self.mode = mode
|
|
||||||
|
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
res = self.fitter.run(mode=self.mode)
|
res = self.fitter.run()
|
||||||
success = True
|
success = True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
res = [e]
|
res = [e]
|
||||||
|
@ -23,7 +23,7 @@ class FitAbortException(Exception):
|
|||||||
|
|
||||||
class FitRoutine(object):
|
class FitRoutine(object):
|
||||||
def __init__(self, mode='lsq'):
|
def __init__(self, mode='lsq'):
|
||||||
self._fitmethod = mode
|
self.fitmethod = mode
|
||||||
self.data = []
|
self.data = []
|
||||||
self.fit_model = None
|
self.fit_model = None
|
||||||
self._no_own_model = []
|
self._no_own_model = []
|
||||||
@ -169,10 +169,13 @@ class FitRoutine(object):
|
|||||||
logger.info('Fit aborted by user')
|
logger.info('Fit aborted by user')
|
||||||
self._abort = True
|
self._abort = True
|
||||||
|
|
||||||
def run(self, mode='lsq'):
|
def run(self, mode: str=None):
|
||||||
self._abort = False
|
self._abort = False
|
||||||
self.parameter = Parameters()
|
self.parameter = Parameters()
|
||||||
|
|
||||||
|
if mode is None:
|
||||||
|
mode = self.fitmethod
|
||||||
|
|
||||||
fit_groups, linked_parameter = self.prepare_links()
|
fit_groups, linked_parameter = self.prepare_links()
|
||||||
|
|
||||||
for data_groups in fit_groups:
|
for data_groups in fit_groups:
|
||||||
|
Loading…
Reference in New Issue
Block a user