use Parameter when collecting fit values
This commit is contained in:
		| @@ -19,14 +19,16 @@ class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter): | ||||
|         super().__init__(parent) | ||||
|         self.setupUi(self) | ||||
|  | ||||
|         self.parametername.setText(label + ' ') | ||||
|         self.name = label | ||||
|  | ||||
|         self.parametername.setText(convert(label) + ' ') | ||||
|  | ||||
|         self.parameter_line.setText('1') | ||||
|         self.parameter_line.setMaximumWidth(160) | ||||
|         self.lineEdit.setMaximumWidth(100) | ||||
|         self.lineEdit_2.setMaximumWidth(100) | ||||
|  | ||||
|         self.label_3.setText(f'< {label} <') | ||||
|         self.label_3.setText(f'< {convert(label)} <') | ||||
|  | ||||
|         self.checkBox.stateChanged.connect(self.enableBounds) | ||||
|         self.global_checkbox.stateChanged.connect(lambda: self.state_changed.emit()) | ||||
| @@ -46,10 +48,6 @@ class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter): | ||||
|  | ||||
|         self.menu = QtWidgets.QMenu(self) | ||||
|  | ||||
|     @property | ||||
|     def name(self): | ||||
|         return convert(self.parametername.text().strip(), old='html', new='str') | ||||
|  | ||||
|     def set_parameter_string(self, p: str): | ||||
|         self.parameter_line.setText(p) | ||||
|         self.parameter_line.setToolTip(p) | ||||
|   | ||||
| @@ -1,5 +1,8 @@ | ||||
| from __future__ import annotations | ||||
|  | ||||
| from typing import Optional | ||||
|  | ||||
| from nmreval.fit.parameter import Parameter | ||||
| from nmreval.utils.text import convert | ||||
|  | ||||
| from ..Qt import QtWidgets, QtCore, QtGui | ||||
| @@ -62,8 +65,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit): | ||||
|         self.glob_values = [1] * len(func.params) | ||||
|  | ||||
|         for k, v in enumerate(func.params): | ||||
|             name = convert(v) | ||||
|             widgt = FitModelWidget(label=name, parent=self.scrollwidget) | ||||
|             widgt = FitModelWidget(label=v, parent=self.scrollwidget) | ||||
|             widgt.parameter_pos = k | ||||
|             widgt.func_idx = idx | ||||
|             try: | ||||
| @@ -83,7 +85,7 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit): | ||||
|             self.global_parameter.append(widgt) | ||||
|             self.scrollwidget.layout().addWidget(widgt) | ||||
|  | ||||
|             widgt2 = ParameterSingleWidget(name=name, parent=self.scrollwidget2) | ||||
|             widgt2 = ParameterSingleWidget(name=v, parent=self.scrollwidget2) | ||||
|             widgt2.valueChanged.connect(self.change_single_parameter) | ||||
|             widgt2.removeSingleValue.connect(self.change_single_parameter) | ||||
|             widgt2.installEventFilter(self) | ||||
| @@ -206,62 +208,51 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit): | ||||
|         if sid not in self.data_values: | ||||
|             self.data_values[sid] = [None] * len(self.data_parameter) | ||||
|  | ||||
|     def get_parameter(self, use_func=None): | ||||
|     def get_parameter(self, use_func=None) -> tuple[dict[str, list[Parameter]], list[Optional[Parameter]]]: | ||||
|         bds = [] | ||||
|         is_global = [] | ||||
|         is_fixed = [] | ||||
|         globs = [] | ||||
|  | ||||
|         param_general = [] | ||||
|  | ||||
|         for g in self.global_parameter: | ||||
|             if isinstance(g, FitModelWidget): | ||||
|                 p_i, bds_i, fixed_i, global_i = g.get_parameter() | ||||
|                 parameter_i = Parameter(name=g.name, value=p_i, lb=bds_i[0], ub=bds_i[1], var=fixed_i) | ||||
|                 param_general.append(parameter_i) | ||||
|  | ||||
|                 globs.append(p_i) | ||||
|                 bds.append(bds_i) | ||||
|                 is_fixed.append(fixed_i) | ||||
|                 is_global.append(global_i) | ||||
|  | ||||
|         lb, ub = list(zip(*bds)) | ||||
|  | ||||
|         data_parameter = {} | ||||
|         if use_func is None: | ||||
|             use_func = list(self.data_values.keys()) | ||||
|  | ||||
|         global_p = None | ||||
|         for sid, parameter in self.data_values.items(): | ||||
|             if sid not in use_func: | ||||
|                 continue | ||||
|  | ||||
|             kw_p = {} | ||||
|             p = [] | ||||
|             if global_p is None: | ||||
|                 global_p = {'value': [], 'idx': [], 'var': [], 'ub': [], 'lb': []} | ||||
|  | ||||
|             for i, (p_i, g) in enumerate(zip(parameter, self.global_parameter)): | ||||
|                 if isinstance(g, FitModelWidget): | ||||
|                     if (p_i is None) or is_global[i]: | ||||
|                         p.append(globs[i]) | ||||
|                         if is_global[i]: | ||||
|                             if i not in global_p['idx']: | ||||
|                                 global_p['value'].append(globs[i]) | ||||
|                                 global_p['idx'].append(i) | ||||
|                                 global_p['var'].append(is_fixed[i]) | ||||
|                                 global_p['ub'].append(ub[i]) | ||||
|                                 global_p['lb'].append(lb[i]) | ||||
|                     if p_i is None: | ||||
|                         # set has no oen value | ||||
|                         p.append(param_general[i].copy()) | ||||
|                     else: | ||||
|                         p.append(p_i) | ||||
|                         lb, ub = bds[i] | ||||
|                         try: | ||||
|                             if not (lb < p[i] < ub): | ||||
|                                 raise ValueError(f'Parameter {g.name} is outside bounds ({lb}, {ub})') | ||||
|                         except TypeError: | ||||
|                             pass | ||||
|  | ||||
|                     try: | ||||
|                         if p[i] > ub[i]: | ||||
|                             raise ValueError(f'Parameter {g.name} is outside bounds ({lb[i]}, {ub[i]})') | ||||
|                     except TypeError: | ||||
|                         pass | ||||
|  | ||||
|                     try: | ||||
|                         if p[i] < lb[i]: | ||||
|                             raise ValueError(f'Parameter {g.name} is outside bounds ({lb[i]}, {ub[i]})') | ||||
|                     except TypeError: | ||||
|                         pass | ||||
|                         # create Parameter | ||||
|                         p.append( | ||||
|                             Parameter(name=g.name, value=p_i, lb=lb, ub=ub, var=is_fixed[i]) | ||||
|                         ) | ||||
|  | ||||
|                 else: | ||||
|                     if p_i is None: | ||||
| @@ -271,9 +262,17 @@ class QFitParameterWidget(QtWidgets.QWidget, Ui_FormFit): | ||||
|                     else: | ||||
|                         kw_p[g.argname] = p_i | ||||
|  | ||||
|             global_parameter = [] | ||||
|             for param, global_flag in zip(param_general, is_global): | ||||
|                 if global_flag: | ||||
|                     global_parameter.append(param) | ||||
|                 else: | ||||
|                     global_parameter.append(None) | ||||
|  | ||||
|  | ||||
|             data_parameter[sid] = (p, kw_p) | ||||
|  | ||||
|         return data_parameter, lb, ub, is_fixed, global_p | ||||
|         return data_parameter, global_parameter | ||||
|  | ||||
|     def set_parameter(self, set_id: str | None, parameter: list[float]) -> int: | ||||
|         num_parameter = list(filter(lambda g: not isinstance(g, SelectionWidget), self.global_parameter)) | ||||
| @@ -304,7 +303,7 @@ class ParameterSingleWidget(QtWidgets.QWidget): | ||||
|  | ||||
|         self._init_ui() | ||||
|  | ||||
|         self._name = name | ||||
|         self.name = 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') | ||||
|   | ||||
| @@ -220,27 +220,31 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog): | ||||
|     def _prepare(self, model: list, function_use: list = None, | ||||
|                  parameter: dict = None, add_idx: bool = False, cnt: int = 0) -> tuple[dict, int]: | ||||
|         if parameter is None: | ||||
|             parameter = {'parameter': {}, 'lb': (), 'ub': (), 'var': [], | ||||
|                          'glob': {'idx': [], 'value': [], 'var': [], 'lb': [], 'ub': []}, | ||||
|                          'links': [], 'color': []} | ||||
|             parameter = { | ||||
|                 'parameter': {}, | ||||
|                 'glob': [], | ||||
|                 'links': [], | ||||
|                 'color': [], | ||||
|             } | ||||
|  | ||||
|         for i, f in enumerate(model): | ||||
|             print(i, f) | ||||
|             if not f['active']: | ||||
|                 continue | ||||
|  | ||||
|             try: | ||||
|                 p, lb, ub, var, glob = self.param_widgets[f['cnt']].get_parameter(function_use) | ||||
|                 p, glob = self.param_widgets[f['cnt']].get_parameter(function_use) | ||||
|             except ValueError as e: | ||||
|                 _ = QtWidgets.QMessageBox().warning(self, 'Invalid value', str(e), | ||||
|                                                     QtWidgets.QMessageBox.Ok) | ||||
|                 return {}, -1 | ||||
|  | ||||
|             p_len = len(parameter['lb']) | ||||
|             print(p) | ||||
|             print(glob) | ||||
|             p_len = len(p) | ||||
|             parameter['color'].append(f['color']) | ||||
|  | ||||
|             parameter['lb'] += lb | ||||
|             parameter['ub'] += ub | ||||
|             parameter['var'] += var | ||||
|             parameter['color'] += [f['color']] | ||||
|             print(parameter) | ||||
|  | ||||
|             cnt = f['cnt'] | ||||
|  | ||||
|   | ||||
| @@ -190,20 +190,23 @@ class Parameter: | ||||
|         self._value = value * self.scale | ||||
|  | ||||
|     @property | ||||
|     def value(self) -> float: | ||||
|     def value(self) -> float | None: | ||||
|         # TODO first _value, then _expr | ||||
|         if self._value is not None: | ||||
|             return self._value | ||||
|  | ||||
|         if self._expr is not None and self.eval_allowed: | ||||
|             return eval(self._expr, {}, self.namespace) | ||||
|         elif self._value is not None: | ||||
|             return self._value | ||||
|  | ||||
|         return | ||||
|  | ||||
|     @property | ||||
|     def scaled_error(self) -> None | float: | ||||
|         if self.error is None: | ||||
|             return self.error | ||||
|         else: | ||||
|         if self.error is not None: | ||||
|             return self.error / self.scale | ||||
|  | ||||
|         return | ||||
|  | ||||
|     @scaled_error.setter | ||||
|     def scaled_error(self, value) -> None: | ||||
|         self.error = value * self.scale | ||||
|   | ||||
		Reference in New Issue
	
	Block a user