Changes in src/sas/qtgui/Perspectives/Fitting/FittingWidget.py [dcabba7:0109f2a] in sasview
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
rdcabba7 r0109f2a 49 49 50 50 51 51 52 TAB_MAGNETISM = 4 52 53 TAB_POLY = 3 … … 60 61 61 62 logger = logging.getLogger(__name__) 63 62 64 63 65 class ToolTippedItemModel(QtGui.QStandardItemModel): … … 91 93 fittingFinishedSignal = QtCore.pyqtSignal(tuple) 92 94 batchFittingFinishedSignal = QtCore.pyqtSignal(tuple) 93 Calc1DFinishedSignal = QtCore.pyqtSignal( dict)94 Calc2DFinishedSignal = QtCore.pyqtSignal( dict)95 Calc1DFinishedSignal = QtCore.pyqtSignal(tuple) 96 Calc2DFinishedSignal = QtCore.pyqtSignal(tuple) 95 97 96 98 def __init__(self, parent=None, data=None, tab_id=1): … … 219 221 # Utility variable to enable unselectable option in category combobox 220 222 self._previous_category_index = 0 221 # Utility variable for multishell display 222 self._last_model_row = 0 223 # Utility variables for multishell display 224 self._n_shells_row = 0 225 self._num_shell_params = 0 223 226 # Dictionary of {model name: model class} for the current category 224 227 self.models = {} … … 248 251 self.kernel_module_copy = None 249 252 250 # dictionaries of current params251 self.poly_params = {}252 self.magnet_params = {}253 254 253 # Page id for fitting 255 254 # To keep with previous SasView values, use 200 as the start offset … … 268 267 self.has_poly_error_column = False 269 268 self.has_magnet_error_column = False 270 271 # If the widget generated theory item, save it272 self.theory_item = None273 269 274 270 # signal communicator … … 394 390 # Tag along functionality 395 391 self.label.setText("Data loaded from: ") 396 if self.logic.data.filename: 397 self.lblFilename.setText(self.logic.data.filename) 398 else: 399 self.lblFilename.setText(self.logic.data.name) 392 self.lblFilename.setText(self.logic.data.filename) 400 393 self.updateQRange() 401 394 # Switch off Data2D control … … 530 523 # Signals from separate tabs asking for replot 531 524 self.options_widget.plot_signal.connect(self.onOptionsUpdate) 525 self.options_widget.plot_signal.connect(self.onOptionsUpdate) 532 526 533 527 # Signals from other widgets … … 676 670 Return list of all parameters for the current model 677 671 """ 678 return [self._model_model.item(row).text() for row in range(self._model_model.rowCount())] 672 return [self._model_model.item(row).text() 673 for row in range(self._model_model.rowCount()) 674 if self.isCheckable(row)] 679 675 680 676 def modifyViewOnRow(self, row, font=None, brush=None): … … 704 700 assert isinstance(constraint, Constraint) 705 701 assert 0 <= row <= self._model_model.rowCount() 702 assert self.isCheckable(row) 706 703 707 704 item = QtGui.QStandardItem() … … 724 721 max_col = self.lstParams.itemDelegate().param_max 725 722 for row in self.selectedParameters(): 723 assert(self.isCheckable(row)) 726 724 param = self._model_model.item(row, 0).text() 727 725 value = self._model_model.item(row, 1).text() … … 766 764 max_col = self.lstParams.itemDelegate().param_max 767 765 for row in range(self._model_model.rowCount()): 766 if not self.isCheckable(row): 767 continue 768 768 if not self.rowHasConstraint(row): 769 769 continue … … 794 794 For the given row, return its constraint, if any 795 795 """ 796 try:796 if self.isCheckable(row): 797 797 item = self._model_model.item(row, 1) 798 return item.child(0).data() 799 except AttributeError: 800 # return none when no constraints 801 return None 798 try: 799 return item.child(0).data() 800 except AttributeError: 801 # return none when no constraints 802 pass 803 return None 802 804 803 805 def rowHasConstraint(self, row): … … 805 807 Finds out if row of the main model has a constraint child 806 808 """ 807 item = self._model_model.item(row, 1) 808 if item.hasChildren(): 809 c = item.child(0).data() 810 if isinstance(c, Constraint): 811 return True 809 if self.isCheckable(row): 810 item = self._model_model.item(row, 1) 811 if item.hasChildren(): 812 c = item.child(0).data() 813 if isinstance(c, Constraint): 814 return True 812 815 return False 813 816 … … 816 819 Finds out if row of the main model has an active constraint child 817 820 """ 818 item = self._model_model.item(row, 1) 819 if item.hasChildren(): 820 c = item.child(0).data() 821 if isinstance(c, Constraint) and c.active: 822 return True 821 if self.isCheckable(row): 822 item = self._model_model.item(row, 1) 823 if item.hasChildren(): 824 c = item.child(0).data() 825 if isinstance(c, Constraint) and c.active: 826 return True 823 827 return False 824 828 … … 827 831 Finds out if row of the main model has an active, nontrivial constraint child 828 832 """ 829 item = self._model_model.item(row, 1) 830 if item.hasChildren(): 831 c = item.child(0).data() 832 if isinstance(c, Constraint) and c.func and c.active: 833 return True 833 if self.isCheckable(row): 834 item = self._model_model.item(row, 1) 835 if item.hasChildren(): 836 c = item.child(0).data() 837 if isinstance(c, Constraint) and c.func and c.active: 838 return True 834 839 return False 835 840 … … 959 964 model = self.cbModel.currentText() 960 965 961 # Assure the control is active 962 if not self.cbModel.isEnabled(): 963 return 964 # Empty combobox forced to be read 966 # empty combobox forced to be read 965 967 if not model: 966 968 return 969 # Reset structure factor 970 self.cbStructureFactor.setCurrentIndex(0) 967 971 968 972 # Reset parameters to fit … … 971 975 self.has_poly_error_column = False 972 976 973 structure = None 974 if self.cbStructureFactor.isEnabled(): 975 structure = str(self.cbStructureFactor.currentText()) 976 self.respondToModelStructure(model=model, structure_factor=structure) 977 self.respondToModelStructure(model=model, structure_factor=None) 977 978 978 979 def onSelectBatchFilename(self, data_index): … … 1117 1118 self.disableModelCombo() 1118 1119 self.enableStructureCombo() 1119 # set the index to 01120 self.cbStructureFactor.setCurrentIndex(0)1121 self.model_parameters = None1122 1120 self._model_model.clear() 1123 1121 return … … 1144 1142 model_row = item.row() 1145 1143 name_index = self._poly_model.index(model_row, 0) 1146 parameter_name = str(name_index.data()) # "distribution of sld" etc.1147 if " istribution of" in parameter_name:1144 parameter_name = str(name_index.data()).lower() # "distribution of sld" etc. 1145 if "distribution of" in parameter_name: 1148 1146 # just the last word 1149 1147 parameter_name = parameter_name.rsplit()[-1] … … 1190 1188 # Update the sasmodel 1191 1189 # PD[ratio] -> width, npts -> npts, nsigs -> nsigmas 1192 #self.kernel_module.setParam(parameter_name + '.' + delegate.columnDict()[model_column], value) 1193 key = parameter_name + '.' + delegate.columnDict()[model_column] 1194 self.poly_params[key] = value 1190 self.kernel_module.setParam(parameter_name + '.' + delegate.columnDict()[model_column], value) 1195 1191 1196 1192 # Update plot … … 1201 1197 row = self.getRowFromName(parameter_name) 1202 1198 param_item = self._model_model.item(row) 1203 self._model_model.blockSignals(True)1204 1199 param_item.child(0).child(0, model_column).setText(item.text()) 1205 self._model_model.blockSignals(False)1206 1200 1207 1201 def onMagnetModelChange(self, item): … … 1232 1226 # Unparsable field 1233 1227 return 1234 delegate = self.lstMagnetic.itemDelegate() 1235 1236 if model_column > 1: 1237 if model_column == delegate.mag_min: 1238 pos = 1 1239 elif model_column == delegate.mag_max: 1240 pos = 2 1241 elif model_column == delegate.mag_unit: 1242 pos = 0 1243 else: 1244 raise AttributeError("Wrong column in magnetism table.") 1245 # min/max to be changed in self.kernel_module.details[parameter_name] = ['Ang', 0.0, inf] 1246 self.kernel_module.details[parameter_name][pos] = value 1247 else: 1248 self.magnet_params[parameter_name] = value 1249 #self.kernel_module.setParam(parameter_name) = value 1250 # Force the chart update when actual parameters changed 1228 1229 property_index = self._magnet_model.headerData(1, model_column)-1 # Value, min, max, etc. 1230 1231 # Update the parameter value - note: this supports +/-inf as well 1232 self.kernel_module.params[parameter_name] = value 1233 1234 # min/max to be changed in self.kernel_module.details[parameter_name] = ['Ang', 0.0, inf] 1235 self.kernel_module.details[parameter_name][property_index] = value 1236 1237 # Force the chart update when actual parameters changed 1238 if model_column == 1: 1251 1239 self.recalculatePlotData() 1252 1240 … … 1509 1497 # Data going in 1510 1498 data = self.logic.data 1511 model = copy.deepcopy(self.kernel_module)1499 model = self.kernel_module 1512 1500 qmin = self.q_range_min 1513 1501 qmax = self.q_range_max 1514 # add polydisperse/magnet parameters if asked1515 self.updateKernelModelWithExtraParams(model)1516 1502 1517 1503 params_to_fit = self.main_params_to_fit … … 1523 1509 raise ValueError('Fitting requires at least one parameter to optimize.') 1524 1510 1511 # Potential smearing added 1512 # Remember that smearing_min/max can be None -> 1513 # deal with it until Python gets discriminated unions 1514 self.addWeightingToData(data) 1515 1525 1516 # Get the constraints. 1526 1517 constraints = self.getComplexConstraintsForModel() … … 1539 1530 data = GuiUtils.dataFromItem(fit_index) 1540 1531 # Potential weights added directly to data 1541 weighted_data =self.addWeightingToData(data)1532 self.addWeightingToData(data) 1542 1533 try: 1543 fitter_single.set_model(model, fit_id, params_to_fit, data= weighted_data,1534 fitter_single.set_model(model, fit_id, params_to_fit, data=data, 1544 1535 constraints=constraints) 1545 1536 except ValueError as ex: 1546 1537 raise ValueError("Setting model parameters failed with: %s" % ex) 1547 1538 1548 qmin, qmax, _ = self.logic.computeRangeFromData( weighted_data)1549 fitter_single.set_data(data= weighted_data, id=fit_id, smearer=smearer, qmin=qmin,1539 qmin, qmax, _ = self.logic.computeRangeFromData(data) 1540 fitter_single.set_data(data=data, id=fit_id, smearer=smearer, qmin=qmin, 1550 1541 qmax=qmax) 1551 1542 fitter_single.select_problem_for_fit(id=fit_id, value=1) … … 1577 1568 # internal so can use closure for param_dict 1578 1569 param_name = str(self._model_model.item(row, 0).text()) 1579 if param_name not in list(param_dict.keys()):1570 if not self.isCheckable(row) or param_name not in list(param_dict.keys()): 1580 1571 return 1581 1572 # modify the param value … … 1589 1580 # Utility function for updateof polydispersity part of the main model 1590 1581 param_name = str(self._model_model.item(row, 0).text())+'.width' 1591 if param_name not in list(param_dict.keys()):1582 if not self.isCheckable(row) or param_name not in list(param_dict.keys()): 1592 1583 return 1593 1584 # modify the param value … … 1938 1929 Adds weighting contribution to fitting data 1939 1930 """ 1940 new_data = copy.deepcopy(data)1941 1931 # Send original data for weighting 1942 1932 weight = FittingUtilities.getWeight(data=data, is2d=self.is2D, flag=self.weighting) 1943 1933 if self.is2D: 1944 new_data.err_data = weight1934 data.err_data = weight 1945 1935 else: 1946 new_data.dy = weight 1947 1948 return new_data 1936 data.dy = weight 1937 pass 1949 1938 1950 1939 def updateQRange(self): … … 1966 1955 # Crete/overwrite model items 1967 1956 self._model_model.clear() 1968 1969 # First, add parameters from the main model 1970 if model_name is not None: 1957 self._poly_model.clear() 1958 self._magnet_model.clear() 1959 1960 if model_name is None: 1961 if structure_factor not in (None, "None"): 1962 # S(Q) on its own, treat the same as a form factor 1963 self.kernel_module = None 1964 self.fromStructureFactorToQModel(structure_factor) 1965 else: 1966 # No models selected 1967 return 1968 else: 1971 1969 self.fromModelToQModel(model_name) 1972 1973 # Then, add structure factor derived parameters 1974 if structure_factor is not None and structure_factor != "None": 1975 if model_name is None: 1976 # Instantiate the current sasmodel for SF-only models 1977 self.kernel_module = self.models[structure_factor]() 1978 self.fromStructureFactorToQModel(structure_factor) 1979 else: 1980 # Allow the SF combobox visibility for the given sasmodel 1981 self.enableStructureFactorControl(structure_factor) 1982 if self.cbStructureFactor.isEnabled(): 1983 structure_factor = self.cbStructureFactor.currentText() 1970 self.addExtraShells() 1971 1972 if structure_factor not in (None, "None"): 1973 # add S(Q) 1984 1974 self.fromStructureFactorToQModel(structure_factor) 1985 1986 # Then, add multishells 1987 if model_name is not None: 1988 # Multishell models need additional treatment 1989 self.addExtraShells() 1990 1991 # Add polydispersity to the model 1992 self.poly_params = {} 1993 self.setPolyModel() 1994 # Add magnetic parameters to the model 1995 self.magnet_params = {} 1996 self.setMagneticModel() 1975 else: 1976 # enable selection of S(Q) 1977 self.enableStructureFactorControl(structure_factor) 1978 1979 # Add polydispersity to the model 1980 self.setPolyModel() 1981 # Add magnetic parameters to the model 1982 self.setMagneticModel() 1997 1983 1998 1984 # Adjust the table cells width … … 2019 2005 """ 2020 2006 name = model_name 2021 kernel_module = None2022 2007 if self.cbCategory.currentText() == CATEGORY_CUSTOM: 2023 2008 # custom kernel load requires full path … … 2025 2010 try: 2026 2011 kernel_module = generate.load_kernel_module(name) 2027 except ModuleNotFoundError as ex: 2028 pass 2029 2030 if kernel_module is None: 2031 # mismatch between "name" attribute and actual filename. 2032 curr_model = self.models[model_name] 2033 name, _ = os.path.splitext(os.path.basename(curr_model.filename)) 2034 try: 2035 kernel_module = generate.load_kernel_module(name) 2036 except ModuleNotFoundError as ex: 2037 logging.error("Can't find the model "+ str(ex)) 2038 return 2012 except ModuleNotFoundError: 2013 # maybe it's a recategorised custom model? 2014 name = os.path.join(ModelUtilities.find_plugins_dir(), model_name+".py") 2015 # If this rises, it's a valid problem. 2016 kernel_module = generate.load_kernel_module(name) 2039 2017 2040 2018 if hasattr(kernel_module, 'parameters'): … … 2067 2045 self.shell_names = self.shellNamesList() 2068 2046 2069 # Update theQModel2047 # Get new rows for QModel 2070 2048 new_rows = FittingUtilities.addParametersToModel(self.model_parameters, self.kernel_module, self.is2D) 2071 2049 2050 # Add heading row 2051 FittingUtilities.addHeadingRowToModel(self._model_model, model_name) 2052 2053 # Update QModel 2072 2054 for row in new_rows: 2073 2055 self._model_model.appendRow(row) 2074 # Update the counter used for multishell display2075 self._last_model_row = self._model_model.rowCount()2076 2056 2077 2057 def fromStructureFactorToQModel(self, structure_factor): … … 2079 2059 Setting model parameters into QStandardItemModel based on selected _structure factor_ 2080 2060 """ 2081 if structure_factor is None or structure_factor=="None": 2082 return 2083 structure_module = generate.load_kernel_module(structure_factor) 2084 structure_parameters = modelinfo.make_parameter_table(getattr(structure_module, 'parameters', [])) 2085 2086 structure_kernel = self.models[structure_factor]() 2087 form_kernel = self.kernel_module 2088 2089 self.kernel_module = MultiplicationModel(form_kernel, structure_kernel) 2090 2091 new_rows = FittingUtilities.addSimpleParametersToModel(structure_parameters, self.is2D) 2061 s_kernel = self.models[structure_factor]() 2062 p_kernel = self.kernel_module 2063 2064 if p_kernel is None: 2065 # Not a product model, just S(Q) 2066 self.kernel_module = s_kernel 2067 params = modelinfo.ParameterTable(self.kernel_module._model_info.parameters.kernel_parameters) 2068 new_rows = FittingUtilities.addSimpleParametersToModel(params, self.is2D) 2069 else: 2070 p_pars_len = len(p_kernel._model_info.parameters.kernel_parameters) 2071 s_pars_len = len(s_kernel._model_info.parameters.kernel_parameters) 2072 2073 self.kernel_module = MultiplicationModel(p_kernel, s_kernel) 2074 all_params = self.kernel_module._model_info.parameters.kernel_parameters 2075 all_param_names = [param.name for param in all_params] 2076 2077 # S(Q) params from the product model are not necessarily the same as those from the S(Q) model; any 2078 # conflicting names with P(Q) params will cause a rename; we also lose radius_effective (for now...) 2079 2080 # TODO: merge rest of beta approx implementation in 2081 # This is to ensure compatibility when we merge beta approx support in...! 2082 2083 # radius_effective is always s_params[0] 2084 2085 # if radius_effective_mode is in all_params, then all_params contains radius_effective and we want to 2086 # keep it in the model 2087 2088 # if radius_effective_mode is NOT in all_params, then radius_effective should NOT be kept, because the user 2089 # cannot specify it themselves; but, make sure we only remove it if it's actually there in the first place 2090 # (sasmodels master removes it already) 2091 if "radius_effective_mode" in all_param_names: 2092 # Show all parameters 2093 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len]) 2094 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters) 2095 else: 2096 # Ensure radius_effective is not displayed 2097 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters[1:]) 2098 if "radius_effective" in all_param_names: 2099 s_params = modelinfo.ParameterTable(all_params[p_pars_len+1:p_pars_len+s_pars_len]) 2100 else: 2101 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len-1]) 2102 2103 # Get new rows for QModel 2104 # Any renamed parameters are stored as data in the relevant item, for later handling 2105 new_rows = FittingUtilities.addSimpleParametersToModel(s_params, self.is2D, s_params_orig) 2106 2107 # TODO: merge rest of beta approx implementation in 2108 # These parameters are not part of P(Q) nor S(Q), but are added only to the product model (e.g. specifying 2109 # structure factor calculation mode) 2110 # product_params = all_params[p_pars_len+s_pars_len:] 2111 2112 # Add heading row 2113 FittingUtilities.addHeadingRowToModel(self._model_model, structure_factor) 2114 2115 # Update QModel 2092 2116 for row in new_rows: 2093 2117 self._model_model.appendRow(row) 2094 2118 # disable fitting of parameters not listed in self.kernel_module (probably radius_effective) 2095 if row[0].text() not in self.kernel_module.params.keys(): 2096 row_num = self._model_model.rowCount() - 1 2097 FittingUtilities.markParameterDisabled(self._model_model, row_num) 2098 2099 # Update the counter used for multishell display 2100 self._last_model_row = self._model_model.rowCount() 2119 # if row[0].text() not in self.kernel_module.params.keys(): 2120 # row_num = self._model_model.rowCount() - 1 2121 # FittingUtilities.markParameterDisabled(self._model_model, row_num) 2101 2122 2102 2123 def haveParamsToFit(self): … … 2124 2145 model_row = item.row() 2125 2146 name_index = self._model_model.index(model_row, 0) 2147 name_item = self._model_model.itemFromIndex(name_index) 2126 2148 2127 2149 # Extract changed value. … … 2132 2154 return 2133 2155 2134 parameter_name = str(self._model_model.data(name_index)) # sld, background etc. 2156 # if the item has user data, this is the actual parameter name (e.g. to handle duplicate names) 2157 if name_item.data(QtCore.Qt.UserRole): 2158 parameter_name = str(name_item.data(QtCore.Qt.UserRole)) 2159 else: 2160 parameter_name = str(self._model_model.data(name_index)) 2135 2161 2136 2162 # Update the parameter value - note: this supports +/-inf as well … … 2231 2257 name = self.nameFromData(fitted_data) 2232 2258 # Notify the GUI manager so it can create the theory model in DataExplorer 2233 self.theory_item = GuiUtils.createModelItemWithPlot(fitted_data, name=name)2234 self.communicate.updateTheoryFromPerspectiveSignal.emit( self.theory_item)2259 new_item = GuiUtils.createModelItemWithPlot(fitted_data, name=name) 2260 self.communicate.updateTheoryFromPerspectiveSignal.emit(new_item) 2235 2261 2236 2262 def nameFromData(self, fitted_data): … … 2255 2281 return self.completed1D if isinstance(self.data, Data1D) else self.completed2D 2256 2282 2257 def updateKernelModelWithExtraParams(self, model=None):2258 """2259 Updates kernel model 'model' with extra parameters from2260 the polydisp and magnetism tab, if the tabs are enabled2261 """2262 if model is None: return2263 if not hasattr(model, 'setParam'): return2264 2265 # add polydisperse parameters if asked2266 if self.chkPolydispersity.isChecked():2267 for key, value in self.poly_params.items():2268 model.setParam(key, value)2269 # add magnetic params if asked2270 if self.chkMagnetism.isChecked():2271 for key, value in self.magnet_params.items():2272 model.setParam(key, value)2273 2274 2283 def calculateQGridForModelExt(self, data=None, model=None, completefn=None, use_threads=True): 2275 2284 """ … … 2279 2288 data = self.data 2280 2289 if model is None: 2281 model = copy.deepcopy(self.kernel_module) 2282 self.updateKernelModelWithExtraParams(model) 2283 2290 model = self.kernel_module 2284 2291 if completefn is None: 2285 2292 completefn = self.methodCompleteForData() 2286 2293 smearer = self.smearing_widget.smearer() 2287 weight = FittingUtilities.getWeight(data=data, is2d=self.is2D, flag=self.weighting)2288 2289 2294 # Awful API to a backend method. 2290 2295 calc_thread = self.methodCalculateForData()(data=data, … … 2295 2300 smearer=smearer, 2296 2301 state=None, 2297 weight= weight,2302 weight=None, 2298 2303 fid=None, 2299 2304 toggle_mode_on=False, … … 2343 2348 residuals = self.calculateResiduals(fitted_data) 2344 2349 self.model_data = fitted_data 2345 new_plots = [fitted_data] 2346 if residuals is not None: 2347 new_plots.append(residuals) 2348 2349 if self.data_is_loaded: 2350 GuiUtils.deleteRedundantPlots(self.all_data[self.data_index], new_plots) 2351 else: 2352 # delete theory items for the model, in order to get rid of any redundant items, e.g. beta(Q), S_eff(Q) 2353 self.communicate.deleteIntermediateTheoryPlotsSignal.emit(self.kernel_module.id) 2350 2351 new_plots = [fitted_data, residuals] 2354 2352 2355 2353 # Create plots for intermediate product data … … 2366 2364 new_plots.append(sq_data) 2367 2365 2368 # Update/generate plots 2366 if self.data_is_loaded: 2367 GuiUtils.deleteRedundantPlots(self.all_data[self.data_index], new_plots) 2368 2369 # TODO: merge rest of beta approx implementation in 2370 # TODO: refactor 2371 # deal with constrained radius_effective 2372 # for row in range(self._model_model.rowCount()): 2373 # if self._model_model.item(row, 0).text() == "radius_effective_mode": 2374 # if GuiUtils.toDouble(self._model_model.item(row, 1).text()) == 0: 2375 # return 2376 # radius_effective = intermediate_ER() 2377 # if radius_effective: 2378 # for row in range(self._model_model.rowCount()): 2379 # if self._model_model.item(row, 0).text() == "radius_effective": 2380 # self._model_model.item(row, 1).setText(str(radius_effective)) 2381 # break 2382 2369 2383 for plot in new_plots: 2370 self.communicate.plotUpdateSignal.emit([plot]) 2384 if hasattr(plot, "id") and "esidual" in plot.id: 2385 # TODO: fix updates to residuals plot 2386 pass 2387 elif plot is not None: 2388 self.communicate.plotUpdateSignal.emit([plot]) 2371 2389 2372 2390 def complete2D(self, return_data): … … 2375 2393 """ 2376 2394 fitted_data = self.logic.new2DPlot(return_data) 2377 residuals =self.calculateResiduals(fitted_data)2395 self.calculateResiduals(fitted_data) 2378 2396 self.model_data = fitted_data 2379 new_plots = [fitted_data]2380 if residuals is not None:2381 new_plots.append(residuals)2382 2383 # Update/generate plots2384 for plot in new_plots:2385 self.communicate.plotUpdateSignal.emit([plot])2386 2397 2387 2398 def calculateResiduals(self, fitted_data): … … 2393 2404 2394 2405 # Modify fitted_data with weighting 2395 weighted_data =self.addWeightingToData(fitted_data)2396 2397 self.createNewIndex( weighted_data)2406 self.addWeightingToData(fitted_data) 2407 2408 self.createNewIndex(fitted_data) 2398 2409 # Calculate difference between return_data and logic.data 2399 self.chi2 = FittingUtilities.calculateChi2( weighted_data, self.logic.data)2410 self.chi2 = FittingUtilities.calculateChi2(fitted_data, self.logic.data) 2400 2411 # Update the control 2401 2412 chi2_repr = "---" if self.chi2 is None else GuiUtils.formatNumber(self.chi2, high=True) 2402 2413 self.lblChi2Value.setText(chi2_repr) 2403 2414 2415 # self.communicate.plotUpdateSignal.emit([fitted_data]) 2416 2404 2417 # Plot residuals if actual data 2405 2418 if not self.data_is_loaded: 2406 2419 return 2407 2420 2408 residuals_plot = FittingUtilities.plotResiduals(self.data, weighted_data)2421 residuals_plot = FittingUtilities.plotResiduals(self.data, fitted_data) 2409 2422 residuals_plot.id = "Residual " + residuals_plot.id 2410 2423 self.createNewIndex(residuals_plot) … … 2475 2488 self._poly_model.clear() 2476 2489 2477 parameters = self.model_parameters.form_volume_parameters2478 if self.is2D:2479 parameters += self.model_parameters.orientation_parameters2480 2481 2490 [self.setPolyModelParameters(i, param) for i, param in \ 2482 enumerate(parameters) if param.polydisperse] 2483 2491 enumerate(self.model_parameters.form_volume_parameters) if param.polydisperse] 2484 2492 FittingUtilities.addPolyHeadersToModel(self._poly_model) 2485 2493 … … 2514 2522 _, min, max = self.kernel_module.details[param_name] 2515 2523 2516 # Update local param dict2517 self.poly_params[param_name + '.width'] = width2518 self.poly_params[param_name + '.npts'] = npts2519 self.poly_params[param_name + '.nsigmas'] = nsigs2520 2521 2524 # Construct a row with polydisp. related variable. 2522 2525 # This will get added to the polydisp. model … … 2566 2569 def updateFunctionCaption(row): 2567 2570 # Utility function for update of polydispersity function name in the main model 2568 self._model_model.blockSignals(True) 2571 if not self.isCheckable(row): 2572 return 2569 2573 param_name = str(self._model_model.item(row, 0).text()) 2570 self._model_model.blockSignals(False)2571 2574 if param_name != param.name: 2572 2575 return 2573 2576 # Modify the param value 2574 self._model_model.blockSignals(True)2575 2577 if self.has_error_column: 2576 2578 # err column changes the indexing … … 2578 2580 else: 2579 2581 self._model_model.item(row, 0).child(0).child(0,4).setText(combo_string) 2580 self._model_model.blockSignals(False)2581 2582 2582 2583 if combo_string == 'array': … … 2697 2698 param.units] 2698 2699 2699 self.magnet_params[param.name] = param.default2700 2701 2700 FittingUtilities.addCheckedListToModel(model, checked_list) 2702 2701 … … 2738 2737 2739 2738 self.lstParams.setIndexWidget(shell_index, func) 2740 self._ last_model_row = self._model_model.rowCount()2739 self._n_shells_row = shell_row - 1 2741 2740 2742 2741 # Set the index to the state-kept value … … 2749 2748 """ 2750 2749 # Find row location of the combobox 2751 last_row = self._last_model_row2752 remove_rows = self._ model_model.rowCount() - last_row2750 first_row = self._n_shells_row + 1 2751 remove_rows = self._num_shell_params 2753 2752 2754 2753 if remove_rows > 1: 2755 self._model_model.removeRows(last_row, remove_rows) 2756 2757 FittingUtilities.addShellsToModel(self.model_parameters, self._model_model, index) 2754 self._model_model.removeRows(first_row, remove_rows) 2755 2756 new_rows = FittingUtilities.addShellsToModel(self.model_parameters, self._model_model, index, first_row) 2757 self._num_shell_params = len(new_rows) 2758 2758 2759 self.current_shell_displayed = index 2759 2760 … … 2875 2876 # TODO: add polidyspersity and magnetism 2876 2877 2878 2877 2879 def updateUndo(self): 2878 2880 """ … … 2911 2913 if self.all_data: 2912 2914 index = self.all_data[self.data_index] 2913 else:2914 index = self.theory_item2915 2915 report_logic = ReportPageLogic(self, 2916 2916 kernel_module=self.kernel_module, … … 3036 3036 # first - regular params 3037 3037 param_list = [] 3038 3039 param_list.append(['model_name', str(self.cbModel.currentText())])3040 3038 def gatherParams(row): 3041 3039 """ … … 3124 3122 if lines[0] != 'sasview_parameter_values': 3125 3123 return False 3126 3127 model = lines[1].split(',') 3128 3129 if model[0] != 'model_name': 3130 return False 3131 3132 context['model_name'] = [model[1]] 3133 for line in lines[2:-1]: 3124 for line in lines[1:-1]: 3134 3125 if len(line) != 0: 3135 3126 item = line.split(',') … … 3157 3148 except IndexError: 3158 3149 pass 3159 3160 if str(self.cbModel.currentText()) != str(context['model_name'][0]):3161 msg = QtWidgets.QMessageBox()3162 msg.setIcon(QtWidgets.QMessageBox.Information)3163 msg.setText("The model in the clipboard is not the same as the currently loaded model. \3164 Not all parameters saved may paste correctly.")3165 msg.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)3166 result = msg.exec_()3167 if result == QtWidgets.QMessageBox.Ok:3168 pass3169 else:3170 return3171 3150 3172 3151 self.updateFullModel(context) … … 3207 3186 param_repr = GuiUtils.formatNumber(param_dict[param_name][3+ioffset], high=True) 3208 3187 self._model_model.item(row, 3+ioffset).setText(param_repr) 3209 self.setFocus()3210 3211 3188 3212 3189 # block signals temporarily, so we don't end up … … 3215 3192 self.iterateOverModel(updateFittedValues) 3216 3193 self._model_model.blockSignals(False) 3217 3218 3194 3219 3195 def updateFullPolyModel(self, param_dict): … … 3260 3236 param_repr = GuiUtils.formatNumber(param_dict[param_name][5+ioffset], high=True) 3261 3237 self._poly_model.item(row, 5+ioffset).setText(param_repr) 3262 self.setFocus()3263 3238 3264 3239 # block signals temporarily, so we don't end up … … 3268 3243 self._poly_model.blockSignals(False) 3269 3244 3245
Note: See TracChangeset
for help on using the changeset viewer.