adjustments to fit to see if fit is at least running, could help with #39

Co-authored-by: Dominik Demuth <dominik.demuth@physik.tu-darmstadt.de>
Reviewed-on: #43
This commit is contained in:
Dominik Demuth 2023-04-08 18:37:07 +00:00
parent ffecc9c873
commit 02f8a3bb31
5 changed files with 30 additions and 15 deletions

View File

@ -58,7 +58,7 @@ class RdBuCMap:
elif val < self.min: elif val < self.min:
col = QtGui.QColor.fromRgb(*RdBuCMap._rdbu[-1]) col = QtGui.QColor.fromRgb(*RdBuCMap._rdbu[-1])
else: else:
col = QtGui.QColor.fromRgb(*(float(self.spline[i](val)) for i in range(3))) col = QtGui.QColor.fromRgb(*(int(self.spline[i](val)) for i in range(3)))
return col return col

View File

@ -66,7 +66,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self._block_window_change = False self._block_window_change = False
self.fname = None self.fname = None
self.tim = QtCore.QTimer()
self.settings = QtCore.QSettings('NMREVal', 'settings') self.settings = QtCore.QSettings('NMREVal', 'settings')
self._init_gui() self._init_gui()
@ -887,6 +886,11 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.fit_dialog.fit_button.setEnabled(False) self.fit_dialog.fit_button.setEnabled(False)
self.management.start_fit(parameter, links, fit_options) self.management.start_fit(parameter, links, fit_options)
self.status.setText('Fit running...'.format(self.management.fitter.step))
tim = QtCore.QTimer()
tim.setInterval(500)
tim.timeout.connect(lambda: self.status.setText(f'Fit running... ({self.management.fitter.step} evaluations)'))
tim.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):
@ -910,6 +914,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
@QtCore.pyqtSlot(list) @QtCore.pyqtSlot(list)
def show_fit_results(self, results: list): def show_fit_results(self, results: list):
self.fit_dialog.fit_button.setEnabled(True) self.fit_dialog.fit_button.setEnabled(True)
self.status.setText('')
if results: if results:
res_dialog = QFitResult(results, self.management, parent=self) res_dialog = QFitResult(results, self.management, parent=self)
res_dialog.add_graphs(self.management.graphs.list()) res_dialog.add_graphs(self.management.graphs.list())

View File

@ -398,7 +398,7 @@ class UpperManagement(QtCore.QObject):
self.__fit_options = (parameter, links, fit_options) self.__fit_options = (parameter, links, fit_options)
fitter = FitRoutine() self.fitter = FitRoutine()
models = {} models = {}
fit_limits = fit_options['limits'] fit_limits = fit_options['limits']
fit_mode = fit_options['fit_mode'] fit_mode = fit_options['fit_mode']
@ -442,18 +442,18 @@ class UpperManagement(QtCore.QObject):
lb=model_p['lb'], ub=model_p['ub'], lb=model_p['lb'], ub=model_p['ub'],
fun_kwargs=set_params[1]) fun_kwargs=set_params[1])
fitter.add_data(d) self.fitter.add_data(d)
model_globs = model_p['glob'] model_globs = model_p['glob']
if model_globs: if model_globs:
m.set_global_parameter(**model_p['glob']) m.set_global_parameter(**model_p['glob'])
for links_i in links: for links_i in links:
fitter.set_link_parameter((models[links_i[0]], links_i[1]), self.fitter.set_link_parameter((models[links_i[0]], links_i[1]),
(models[links_i[2]], links_i[3])) (models[links_i[2]], links_i[3]))
with busy_cursor(): with busy_cursor():
self.fit_worker = FitWorker(fitter, fit_mode) self.fit_worker = FitWorker(self.fitter, fit_mode)
self.fit_thread = QtCore.QThread() self.fit_thread = QtCore.QThread()
self.fit_worker.moveToThread(self.fit_thread) self.fit_worker.moveToThread(self.fit_thread)
@ -469,7 +469,7 @@ class UpperManagement(QtCore.QObject):
@QtCore.pyqtSlot(list, bool) @QtCore.pyqtSlot(list, bool)
def end_fit(self, result: list, success: bool): def end_fit(self, result: list, success: bool):
print('FIT FINISHED') logger.info('FIT FINISHED')
if success: if success:
self.fitFinished.emit(result) self.fitFinished.emit(result)
else: else:

View File

@ -1,3 +1,4 @@
import time
import warnings import warnings
from itertools import product from itertools import product
@ -31,6 +32,7 @@ class FitRoutine(object):
self.result = [] self.result = []
self.linked = [] self.linked = []
self._abort = False self._abort = False
self.step = 0
def add_data(self, x, y=None, we=None, idx=None): def add_data(self, x, y=None, we=None, idx=None):
if isinstance(x, Data): if isinstance(x, Data):
@ -165,7 +167,7 @@ class FitRoutine(object):
self.find_paths(neighbor, graph, coupled_nodes, visited_nodes) self.find_paths(neighbor, graph, coupled_nodes, visited_nodes)
def abort(self): def abort(self):
print('ABORT ???') logger.info('Fit aborted by user')
self._abort = True self._abort = True
def run(self, mode='lsq'): def run(self, mode='lsq'):
@ -311,14 +313,17 @@ class FitRoutine(object):
return r return r
def _least_squares_single(self, data, p0, lb, ub, var): def _least_squares_single(self, data, p0, lb, ub, var):
self.step = 0
def cost(p): def cost(p):
self.step += 1
if self._abort: if self._abort:
raise FitAbortException(f'Fit aborted by user') raise FitAbortException(f'Fit aborted by user')
return self.__cost_scipy(p, data, var, data.para_keys) return self.__cost_scipy(p, data, var, data.para_keys)
with np.errstate(all='ignore'): with np.errstate(all='ignore'):
res = optimize.least_squares(cost, p0, bounds=(lb, ub), max_nfev=1000 * len(p0)) res = optimize.least_squares(cost, p0, bounds=(lb, ub), max_nfev=500 * len(p0))
err, corr, partial_corr = self._calc_error(res.jac, np.sum(res.fun**2), *res.jac.shape) err, corr, partial_corr = self._calc_error(res.jac, np.sum(res.fun**2), *res.jac.shape)
self.make_results(data, res.x, var, data.para_keys, res.jac.shape, self.make_results(data, res.x, var, data.para_keys, res.jac.shape,
@ -326,12 +331,13 @@ class FitRoutine(object):
def _least_squares_global(self, data, p0, lb, ub, var, data_pars): def _least_squares_global(self, data, p0, lb, ub, var, data_pars):
def cost(p): def cost(p):
self.step += 1
if self._abort: if self._abort:
raise FitAbortException(f'Fit aborted by user') raise FitAbortException(f'Fit aborted by user')
return self.__cost_scipy_glob(p, data, var, data_pars) return self.__cost_scipy_glob(p, data, var, data_pars)
with np.errstate(all='ignore'): with np.errstate(all='ignore'):
res = optimize.least_squares(cost, p0, bounds=(lb, ub), max_nfev=1000 * len(p0)) res = optimize.least_squares(cost, p0, bounds=(lb, ub), max_nfev=500 * len(p0))
err, corr, partial_corr = self._calc_error(res.jac, np.sum(res.fun**2), *res.jac.shape) err, corr, partial_corr = self._calc_error(res.jac, np.sum(res.fun**2), *res.jac.shape)
for v, var_pars_k in zip(data, data_pars): for v, var_pars_k in zip(data, data_pars):
@ -340,25 +346,27 @@ class FitRoutine(object):
def _nm_single(self, data, p0, lb, ub, var): def _nm_single(self, data, p0, lb, ub, var):
def cost(p): def cost(p):
self.step += 1
if self._abort: if self._abort:
raise FitAbortException(f'Fit aborted by user') raise FitAbortException(f'Fit aborted by user')
return (self.__cost_scipy(p, data, var, data.para_keys)**2).sum() return (self.__cost_scipy(p, data, var, data.para_keys)**2).sum()
with np.errstate(all='ignore'): with np.errstate(all='ignore'):
res = optimize.minimize(cost, p0, bounds=[(b1, b2) for (b1, b2) in zip(lb, ub)], res = optimize.minimize(cost, p0, bounds=[(b1, b2) for (b1, b2) in zip(lb, ub)],
method='Nelder-Mead', options={'maxiter': 1000 * len(p0)}) method='Nelder-Mead', options={'maxiter': 500 * len(p0)})
self.make_results(data, res.x, var, data.para_keys, (len(data), len(p0))) self.make_results(data, res.x, var, data.para_keys, (len(data), len(p0)))
def _nm_global(self, data, p0, lb, ub, var, data_pars): def _nm_global(self, data, p0, lb, ub, var, data_pars):
def cost(p): def cost(p):
self.step += 1
if self._abort: if self._abort:
raise FitAbortException(f'Fit aborted by user') raise FitAbortException(f'Fit aborted by user')
return (self.__cost_scipy_glob(p, data, var, data_pars)**2).sum() return (self.__cost_scipy_glob(p, data, var, data_pars)**2).sum()
with np.errstate(all='ignore'): with np.errstate(all='ignore'):
res = optimize.minimize(cost, p0, bounds=[(b1, b2) for (b1, b2) in zip(lb, ub)], res = optimize.minimize(cost, p0, bounds=[(b1, b2) for (b1, b2) in zip(lb, ub)],
method='Nelder-Mead', options={'maxiter': 1000 * len(p0)}) method='Nelder-Mead', options={'maxiter': 500 * len(p0)})
for v, var_pars_k in zip(data, data_pars): for v, var_pars_k in zip(data, data_pars):
self.make_results(v, res.x, var, var_pars_k, (sum(len(d) for d in data), len(p0))) self.make_results(v, res.x, var, var_pars_k, (sum(len(d) for d in data), len(p0)))
@ -367,6 +375,7 @@ class FitRoutine(object):
odr_data = odr.Data(data.x, data.y) odr_data = odr.Data(data.x, data.y)
def func(p, _): def func(p, _):
self.step += 1
if self._abort: if self._abort:
raise FitAbortException(f'Fit aborted by user') raise FitAbortException(f'Fit aborted by user')
return self.__cost_odr(p, data, var_pars, data.para_keys) return self.__cost_odr(p, data, var_pars, data.para_keys)
@ -390,6 +399,7 @@ class FitRoutine(object):
def _odr_global(self, data, p0, var, data_pars): def _odr_global(self, data, p0, var, data_pars):
def func(p, _): def func(p, _):
self.step += 1
if self._abort: if self._abort:
raise FitAbortException(f'Fit aborted by user') raise FitAbortException(f'Fit aborted by user')
return self.__cost_odr_glob(p, data, var, data_pars) return self.__cost_odr_glob(p, data, var, data_pars)

View File

@ -155,8 +155,8 @@ class AsciiReader:
# more than one axis, append column number # more than one axis, append column number
kwargs['name'] = filename + '_' + str(y[j-1]) kwargs['name'] = filename + '_' + str(y[j-1])
if j+num_y+1 < raw_data.shape[2]: if j+num_y < raw_data.shape[2]:
kwargs['y_err'] = raw_data[i, j+num_y+1] kwargs['y_err'] = raw_data[i, :, j+num_y]
imported_sets.append(cls(x=raw_data[i, :, 0], y=raw_data[i, :, j:j+single_len].T, **kwargs)) imported_sets.append(cls(x=raw_data[i, :, 0], y=raw_data[i, :, j:j+single_len].T, **kwargs))