Changes in / [b69b549:bc7371fd] in sasview
- Location:
- src/sas/qtgui
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/MainWindow/DataExplorer.py
r60d55a7 rfd7ef36 560 560 # Now query the model item for available plots 561 561 plots = GuiUtils.plotsFromFilename(filename, model) 562 ids_keys = list(self.active_plots.keys()) 563 ids_vals = [val.data.id for val in self.active_plots.values()] 562 564 563 565 new_plots = [] 564 566 for item, plot in plots.items(): 565 if not self.updatePlot(plot): 567 plot_id = plot.id 568 if plot_id in ids_keys: 569 self.active_plots[plot_id].replacePlot(plot_id, plot) 570 elif plot_id in ids_vals: 571 list(self.active_plots.values())[ids_vals.index(plot_id)].replacePlot(plot_id, plot) 572 else: 566 573 # Don't plot intermediate results, e.g. P(Q), S(Q) 567 match = GuiUtils.theory_plot_ID_pattern.match(plot .id)574 match = GuiUtils.theory_plot_ID_pattern.match(plot_id) 568 575 # 2nd match group contains the identifier for the intermediate result, if present (e.g. "[P(Q)]") 569 576 if match and match.groups()[1] != None: … … 699 706 self.active_plots[plot_set.id] = old_plot 700 707 701 def updatePlot(self, data): 702 """ 703 Modify existing plot for immediate response and returns True. 704 Returns false, if the plot does not exist already. 705 """ 706 try: # there might be a list or a single value being passed 707 data = data[0] 708 except TypeError: 709 pass 708 def updatePlot(self, new_data): 709 """ 710 Modify existing plot for immediate response 711 """ 712 data = new_data[0] 710 713 assert type(data).__name__ in ['Data1D', 'Data2D'] 711 714 … … 716 719 if data_id in ids_keys: 717 720 self.active_plots[data_id].replacePlot(data_id, data) 718 return True719 721 elif data_id in ids_vals: 720 722 list(self.active_plots.values())[ids_vals.index(data_id)].replacePlot(data_id, data) 721 return True722 return False723 723 724 724 def chooseFiles(self): -
src/sas/qtgui/Perspectives/Fitting/FittingLogic.py
rdcabba7 rb4d05bd 161 161 Create a new 1D data instance based on fitting results 162 162 """ 163 164 return self._create1DPlot(tab_id, return_data['x'], return_data['y'], 165 return_data['model'], return_data['data']) 163 # Unpack return data from Calc1D 164 x, y, page_id, state, weight,\ 165 fid, toggle_mode_on, \ 166 elapsed, index, model, \ 167 data, update_chisqr, source, \ 168 unsmeared_output, unsmeared_data, unsmeared_error, \ 169 pq_values, sq_values = return_data 170 171 return self._create1DPlot(tab_id, x, y, model, data) 166 172 167 173 def new2DPlot(self, return_data): … … 169 175 Create a new 2D data instance based on fitting results 170 176 """ 171 image = return_data['image']172 data = return_data['data']173 model = return_data['model']177 image, data, page_id, model, state, toggle_mode_on,\ 178 elapsed, index, fid, qmin, qmax, weight, \ 179 update_chisqr, source = return_data 174 180 175 181 np.nan_to_num(image) … … 177 183 new_plot.name = model.name + '2d' 178 184 new_plot.title = "Analytical model 2D " 179 new_plot.id = str( return_data['page_id']) + " " + data.name180 new_plot.group_id = str( return_data['page_id']) + " Model2D"185 new_plot.id = str(page_id) + " " + data.name 186 new_plot.group_id = str(page_id) + " Model2D" 181 187 new_plot.detector = data.detector 182 188 new_plot.source = data.source … … 212 218 (pq_plot, sq_plot). If either are unavailable, the corresponding plot is None. 213 219 """ 220 # Unpack return data from Calc1D 221 x, y, page_id, state, weight, \ 222 fid, toggle_mode_on, \ 223 elapsed, index, model, \ 224 data, update_chisqr, source, \ 225 unsmeared_output, unsmeared_data, unsmeared_error, \ 226 pq_values, sq_values = return_data 214 227 215 228 pq_plot = None 216 229 sq_plot = None 217 230 218 if return_data.get('pq_values', None) is not None: 219 pq_plot = self._create1DPlot(tab_id, return_data['x'], 220 return_data['pq_values'], return_data['model'], 221 return_data['data'], component="P(Q)") 222 if return_data.get('sq_values', None) is not None: 223 sq_plot = self._create1DPlot(tab_id, return_data['x'], 224 return_data['sq_values'], return_data['model'], 225 return_data['data'], component="S(Q)") 231 if pq_values is not None: 232 pq_plot = self._create1DPlot(tab_id, x, pq_values, model, data, component="P(Q)") 233 if sq_values is not None: 234 sq_plot = self._create1DPlot(tab_id, x, sq_values, model, data, component="S(Q)") 226 235 227 236 return pq_plot, sq_plot -
src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py
r70f4458 rbc7371fd 167 167 return rows 168 168 169 def addSimpleParametersToModel(parameters, is2D, parameters_original=None,model=None, view=None):169 def addSimpleParametersToModel(parameters, is2D, model=None, view=None): 170 170 """ 171 171 Update local ModelModel with sasmodel parameters (non-dispersed, non-magnetic) 172 172 Actually appends to model, if model and view params are not None. 173 173 Always returns list of lists of QStandardItems. 174 175 parameters_original: list of parameters before any tagging on their IDs, e.g. for product model (so that those are176 the display names; see below)177 174 """ 178 175 if is2D: … … 181 178 params = parameters.iq_parameters 182 179 183 if parameters_original:184 # 'parameters_original' contains the parameters as they are to be DISPLAYED, while 'parameters'185 # contains the parameters as they were renamed; this is for handling name collisions in product model.186 # The 'real name' of the parameter will be stored in the item's user data.187 if is2D:188 params_orig = [p for p in parameters_original.kernel_parameters if p.type != 'magnetic']189 else:190 params_orig = parameters_original.iq_parameters191 else:192 # no difference in names anyway193 params_orig = params194 195 180 rows = [] 196 for param , param_orig in zip(params, params_orig):181 for param in params: 197 182 # Create the top level, checkable item 198 item_name = param _orig.name183 item_name = param.name 199 184 item1 = QtGui.QStandardItem(item_name) 200 item1.setData(param.name, QtCore.Qt.UserRole)201 185 item1.setCheckable(True) 202 186 item1.setEditable(False) … … 256 240 model.appendRow(item_list) 257 241 258 def addHeadingRowToModel(model, name):259 """adds a non-interactive top-level row to the model"""260 header_row = [QtGui.QStandardItem() for i in range(5)]261 header_row[0].setText(name)262 263 font = header_row[0].font()264 font.setBold(True)265 header_row[0].setFont(font)266 267 for item in header_row:268 item.setEditable(False)269 item.setCheckable(False)270 item.setSelectable(False)271 272 model.appendRow(header_row)273 274 242 def addHeadersToModel(model): 275 243 """ … … 317 285 model.header_tooltips = copy.copy(poly_header_error_tooltips) 318 286 319 def addShellsToModel(parameters, model, index, row_num=None, view=None): 320 """ 321 Find out multishell parameters and update the model with the requested number of them. 322 Inserts them after the row at row_num, if not None; otherwise, appends to end. 323 If view param is not None, supports fixed-choice params. 324 Returns a list of lists of QStandardItem objects. 287 def addShellsToModel(parameters, model, index, view=None): 288 """ 289 Find out multishell parameters and update the model with the requested number of them 290 Always appends to model. If view param is not None, supports fixed-choice params. 291 Returns list of lists of QStandardItems. 325 292 """ 326 293 multishell_parameters = getIterParams(parameters) … … 359 326 cbox = createFixedChoiceComboBox(par, row) 360 327 361 # Always add to the model 362 if row_num is None: 363 model.appendRow(row) 364 else: 365 model.insertRow(row_num, row) 366 row_num += 1 328 # Always append to the model 329 model.appendRow(row) 367 330 368 331 # Apply combobox if required -
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
r0109f2a ra758043 91 91 fittingFinishedSignal = QtCore.pyqtSignal(tuple) 92 92 batchFittingFinishedSignal = QtCore.pyqtSignal(tuple) 93 Calc1DFinishedSignal = QtCore.pyqtSignal( dict)94 Calc2DFinishedSignal = QtCore.pyqtSignal( dict)93 Calc1DFinishedSignal = QtCore.pyqtSignal(tuple) 94 Calc2DFinishedSignal = QtCore.pyqtSignal(tuple) 95 95 96 96 def __init__(self, parent=None, data=None, tab_id=1): … … 219 219 # Utility variable to enable unselectable option in category combobox 220 220 self._previous_category_index = 0 221 # Utility variables for multishell display 222 self._n_shells_row = 0 223 self._num_shell_params = 0 221 # Utility variable for multishell display 222 self._last_model_row = 0 224 223 # Dictionary of {model name: model class} for the current category 225 224 self.models = {} … … 248 247 # copy of current kernel model 249 248 self.kernel_module_copy = None 250 251 # dictionaries of current params252 self.poly_params = {}253 self.magnet_params = {}254 249 255 250 # Page id for fitting … … 677 672 Return list of all parameters for the current model 678 673 """ 679 return [self._model_model.item(row).text() 680 for row in range(self._model_model.rowCount()) 681 if self.isCheckable(row)] 674 return [self._model_model.item(row).text() for row in range(self._model_model.rowCount())] 682 675 683 676 def modifyViewOnRow(self, row, font=None, brush=None): … … 707 700 assert isinstance(constraint, Constraint) 708 701 assert 0 <= row <= self._model_model.rowCount() 709 assert self.isCheckable(row)710 702 711 703 item = QtGui.QStandardItem() … … 728 720 max_col = self.lstParams.itemDelegate().param_max 729 721 for row in self.selectedParameters(): 730 assert(self.isCheckable(row))731 722 param = self._model_model.item(row, 0).text() 732 723 value = self._model_model.item(row, 1).text() … … 771 762 max_col = self.lstParams.itemDelegate().param_max 772 763 for row in range(self._model_model.rowCount()): 773 if not self.isCheckable(row):774 continue775 764 if not self.rowHasConstraint(row): 776 765 continue … … 801 790 For the given row, return its constraint, if any 802 791 """ 803 if self.isCheckable(row):792 try: 804 793 item = self._model_model.item(row, 1) 805 try: 806 return item.child(0).data() 807 except AttributeError: 808 # return none when no constraints 809 pass 810 return None 794 return item.child(0).data() 795 except AttributeError: 796 # return none when no constraints 797 return None 811 798 812 799 def rowHasConstraint(self, row): … … 814 801 Finds out if row of the main model has a constraint child 815 802 """ 816 if self.isCheckable(row): 817 item = self._model_model.item(row, 1) 818 if item.hasChildren(): 819 c = item.child(0).data() 820 if isinstance(c, Constraint): 821 return True 803 item = self._model_model.item(row, 1) 804 if item.hasChildren(): 805 c = item.child(0).data() 806 if isinstance(c, Constraint): 807 return True 822 808 return False 823 809 … … 826 812 Finds out if row of the main model has an active constraint child 827 813 """ 828 if self.isCheckable(row): 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.active: 833 return True 814 item = self._model_model.item(row, 1) 815 if item.hasChildren(): 816 c = item.child(0).data() 817 if isinstance(c, Constraint) and c.active: 818 return True 834 819 return False 835 820 … … 838 823 Finds out if row of the main model has an active, nontrivial constraint child 839 824 """ 840 if self.isCheckable(row): 841 item = self._model_model.item(row, 1) 842 if item.hasChildren(): 843 c = item.child(0).data() 844 if isinstance(c, Constraint) and c.func and c.active: 845 return True 825 item = self._model_model.item(row, 1) 826 if item.hasChildren(): 827 c = item.child(0).data() 828 if isinstance(c, Constraint) and c.func and c.active: 829 return True 846 830 return False 847 831 … … 1202 1186 # Update the sasmodel 1203 1187 # PD[ratio] -> width, npts -> npts, nsigs -> nsigmas 1204 #self.kernel_module.setParam(parameter_name + '.' + delegate.columnDict()[model_column], value) 1205 key = parameter_name + '.' + delegate.columnDict()[model_column] 1206 self.poly_params[key] = value 1188 self.kernel_module.setParam(parameter_name + '.' + delegate.columnDict()[model_column], value) 1207 1189 1208 1190 # Update plot … … 1213 1195 row = self.getRowFromName(parameter_name) 1214 1196 param_item = self._model_model.item(row) 1215 self._model_model.blockSignals(True)1216 1197 param_item.child(0).child(0, model_column).setText(item.text()) 1217 self._model_model.blockSignals(False)1218 1198 1219 1199 def onMagnetModelChange(self, item): … … 1244 1224 # Unparsable field 1245 1225 return 1246 delegate = self.lstMagnetic.itemDelegate() 1247 1248 if model_column > 1: 1249 if model_column == delegate.mag_min: 1250 pos = 1 1251 elif model_column == delegate.mag_max: 1252 pos = 2 1253 elif model_column == delegate.mag_unit: 1254 pos = 0 1255 else: 1256 raise AttributeError("Wrong column in magnetism table.") 1257 # min/max to be changed in self.kernel_module.details[parameter_name] = ['Ang', 0.0, inf] 1258 self.kernel_module.details[parameter_name][pos] = value 1259 else: 1260 self.magnet_params[parameter_name] = value 1261 #self.kernel_module.setParam(parameter_name) = value 1262 # Force the chart update when actual parameters changed 1226 1227 property_index = self._magnet_model.headerData(1, model_column)-1 # Value, min, max, etc. 1228 1229 # Update the parameter value - note: this supports +/-inf as well 1230 self.kernel_module.params[parameter_name] = value 1231 1232 # min/max to be changed in self.kernel_module.details[parameter_name] = ['Ang', 0.0, inf] 1233 self.kernel_module.details[parameter_name][property_index] = value 1234 1235 # Force the chart update when actual parameters changed 1236 if model_column == 1: 1263 1237 self.recalculatePlotData() 1264 1238 … … 1521 1495 # Data going in 1522 1496 data = self.logic.data 1523 model = copy.deepcopy(self.kernel_module)1497 model = self.kernel_module 1524 1498 qmin = self.q_range_min 1525 1499 qmax = self.q_range_max 1526 # add polydisperse/magnet parameters if asked1527 self.updateKernelModelWithExtraParams(model)1528 1500 1529 1501 params_to_fit = self.main_params_to_fit … … 1589 1561 # internal so can use closure for param_dict 1590 1562 param_name = str(self._model_model.item(row, 0).text()) 1591 if not self.isCheckable(row) orparam_name not in list(param_dict.keys()):1563 if param_name not in list(param_dict.keys()): 1592 1564 return 1593 1565 # modify the param value … … 1601 1573 # Utility function for updateof polydispersity part of the main model 1602 1574 param_name = str(self._model_model.item(row, 0).text())+'.width' 1603 if not self.isCheckable(row) orparam_name not in list(param_dict.keys()):1575 if param_name not in list(param_dict.keys()): 1604 1576 return 1605 1577 # modify the param value … … 1978 1950 # Crete/overwrite model items 1979 1951 self._model_model.clear() 1980 self._poly_model.clear() 1981 self._magnet_model.clear()1982 1983 if model_name is None:1984 if structure_factor not in (None, "None"): 1985 # S(Q) on its own, treat the same as a form factor1986 self.kernel_module = None1987 self.fromStructureFactorToQModel(structure_factor)1988 else:1989 # No models selected1990 return1952 1953 # First, add parameters from the main model 1954 if model_name is not None: 1955 self.fromModelToQModel(model_name) 1956 1957 # Then, add structure factor derived parameters 1958 if structure_factor is not None and structure_factor != "None": 1959 if model_name is None: 1960 # Instantiate the current sasmodel for SF-only models 1961 self.kernel_module = self.models[structure_factor]() 1962 self.fromStructureFactorToQModel(structure_factor) 1991 1963 else: 1992 self.fromModelToQModel(model_name)1993 self.addExtraShells()1994 1995 1964 # Allow the SF combobox visibility for the given sasmodel 1996 1965 self.enableStructureFactorControl(structure_factor) 1997 1998 # Add S(Q)1999 1966 if self.cbStructureFactor.isEnabled(): 2000 1967 structure_factor = self.cbStructureFactor.currentText() 2001 1968 self.fromStructureFactorToQModel(structure_factor) 2002 1969 2003 # Add polydispersity to the model 2004 self.poly_params = {} 2005 self.setPolyModel() 2006 # Add magnetic parameters to the model 2007 self.magnet_params = {} 2008 self.setMagneticModel() 1970 # Then, add multishells 1971 if model_name is not None: 1972 # Multishell models need additional treatment 1973 self.addExtraShells() 1974 1975 # Add polydispersity to the model 1976 self.setPolyModel() 1977 # Add magnetic parameters to the model 1978 self.setMagneticModel() 2009 1979 2010 1980 # Adjust the table cells width … … 2079 2049 self.shell_names = self.shellNamesList() 2080 2050 2081 # Add heading row2082 FittingUtilities.addHeadingRowToModel(self._model_model, model_name)2083 2084 2051 # Update the QModel 2085 2052 FittingUtilities.addParametersToModel( … … 2090 2057 self.lstParams) 2091 2058 2059 # Update the counter used for multishell display 2060 self._last_model_row = self._model_model.rowCount() 2061 2092 2062 def fromStructureFactorToQModel(self, structure_factor): 2093 2063 """ … … 2096 2066 if structure_factor is None or structure_factor=="None": 2097 2067 return 2098 2099 s_kernel = self.models[structure_factor]() 2100 p_kernel = self.kernel_module 2101 2102 # if p_kernel is None: 2103 # # Not a product model, just S(Q) 2104 # self.kernel_module = s_kernel 2105 # params = modelinfo.ParameterTable(self.kernel_module._model_info.parameters.kernel_parameters) 2106 # FittingUtilities.addSimpleParametersToModel(params, self.is2D) 2107 # else: 2108 p_pars_len = len(p_kernel._model_info.parameters.kernel_parameters) 2109 s_pars_len = len(s_kernel._model_info.parameters.kernel_parameters) 2110 2111 self.kernel_module = MultiplicationModel(p_kernel, s_kernel) 2112 all_params = self.kernel_module._model_info.parameters.kernel_parameters 2113 all_param_names = [param.name for param in all_params] 2114 2115 # S(Q) params from the product model are not necessarily the same as those from the S(Q) model; any 2116 # conflicting names with P(Q) params will cause a rename 2117 2118 if "radius_effective_mode" in all_param_names: 2119 # Show all parameters 2120 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len]) 2121 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters) 2122 else: 2123 # Ensure radius_effective is not displayed 2124 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters[1:]) 2125 if "radius_effective" in all_param_names: 2126 s_params = modelinfo.ParameterTable(all_params[p_pars_len+1:p_pars_len+s_pars_len]) 2127 else: 2128 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len-1]) 2129 2130 # Add heading row 2131 FittingUtilities.addHeadingRowToModel(self._model_model, structure_factor) 2132 2133 # Get new rows for QModel 2134 # Any renamed parameters are stored as data in the relevant item, for later handling 2068 structure_module = generate.load_kernel_module(structure_factor) 2069 structure_parameters = modelinfo.make_parameter_table(getattr(structure_module, 'parameters', [])) 2070 2071 structure_kernel = self.models[structure_factor]() 2072 form_kernel = self.kernel_module 2073 2074 self.kernel_module = MultiplicationModel(form_kernel, structure_kernel) 2075 2076 # Update the QModel 2135 2077 FittingUtilities.addSimpleParametersToModel( 2136 s _params,2078 structure_parameters, 2137 2079 self.is2D, 2138 s_params_orig,2139 2080 self._model_model, 2140 2081 self.lstParams) 2082 2083 # Any parameters removed from the structure factor when producing the product model, e.g. radius_effective, must 2084 # be disabled (greyed out, etc.) 2085 for r in range(self._last_model_row, self._model_model.rowCount()): 2086 param_name = self._model_model.item(r, 0).text() 2087 if param_name not in self.kernel_module.params.keys(): 2088 FittingUtilities.markParameterDisabled(self._model_model, r) 2089 2090 # Update the counter used for multishell display 2091 self._last_model_row = self._model_model.rowCount() 2141 2092 2142 2093 def haveParamsToFit(self): … … 2164 2115 model_row = item.row() 2165 2116 name_index = self._model_model.index(model_row, 0) 2166 name_item = self._model_model.itemFromIndex(name_index)2167 2117 2168 2118 # Extract changed value. … … 2173 2123 return 2174 2124 2175 # if the item has user data, this is the actual parameter name (e.g. to handle duplicate names) 2176 if name_item.data(QtCore.Qt.UserRole): 2177 parameter_name = str(name_item.data(QtCore.Qt.UserRole)) 2178 else: 2179 parameter_name = str(self._model_model.data(name_index)) 2125 parameter_name = str(self._model_model.data(name_index)) # sld, background etc. 2180 2126 2181 2127 # Update the parameter value - note: this supports +/-inf as well … … 2300 2246 return self.completed1D if isinstance(self.data, Data1D) else self.completed2D 2301 2247 2302 def updateKernelModelWithExtraParams(self, model=None):2303 """2304 Updates kernel model 'model' with extra parameters from2305 the polydisp and magnetism tab, if the tabs are enabled2306 """2307 if model is None: return2308 if not hasattr(model, 'setParam'): return2309 2310 # add polydisperse parameters if asked2311 if self.chkPolydispersity.isChecked():2312 for key, value in self.poly_params.items():2313 model.setParam(key, value)2314 # add magnetic params if asked2315 if self.chkMagnetism.isChecked():2316 for key, value in self.magnet_params.items():2317 model.setParam(key, value)2318 2319 2248 def calculateQGridForModelExt(self, data=None, model=None, completefn=None, use_threads=True): 2320 2249 """ … … 2324 2253 data = self.data 2325 2254 if model is None: 2326 model = copy.deepcopy(self.kernel_module) 2327 self.updateKernelModelWithExtraParams(model) 2328 2255 model = self.kernel_module 2329 2256 if completefn is None: 2330 2257 completefn = self.methodCompleteForData() … … 2411 2338 new_plots.append(sq_data) 2412 2339 2413 for plot in new_plots:2414 self.communicate.plotUpdateSignal.emit([plot])2415 2416 def complete2D(self, return_data):2417 """2418 Plot the current 2D data2419 """2420 fitted_data = self.logic.new2DPlot(return_data)2421 residuals = self.calculateResiduals(fitted_data)2422 self.model_data = fitted_data2423 new_plots = [fitted_data]2424 if residuals is not None:2425 new_plots.append(residuals)2426 2427 2340 # Update/generate plots 2428 2341 for plot in new_plots: 2429 2342 self.communicate.plotUpdateSignal.emit([plot]) 2343 2344 def complete2D(self, return_data): 2345 """ 2346 Plot the current 2D data 2347 """ 2348 fitted_data = self.logic.new2DPlot(return_data) 2349 self.calculateResiduals(fitted_data) 2350 self.model_data = fitted_data 2430 2351 2431 2352 def calculateResiduals(self, fitted_data): … … 2558 2479 _, min, max = self.kernel_module.details[param_name] 2559 2480 2560 # Update local param dict2561 self.poly_params[param_name + '.width'] = width2562 self.poly_params[param_name + '.npts'] = npts2563 self.poly_params[param_name + '.nsigmas'] = nsigs2564 2565 2481 # Construct a row with polydisp. related variable. 2566 2482 # This will get added to the polydisp. model … … 2610 2526 def updateFunctionCaption(row): 2611 2527 # Utility function for update of polydispersity function name in the main model 2612 if not self.isCheckable(row):2613 return2614 self._model_model.blockSignals(True)2615 2528 param_name = str(self._model_model.item(row, 0).text()) 2616 self._model_model.blockSignals(False)2617 2529 if param_name != param.name: 2618 2530 return 2619 2531 # Modify the param value 2620 self._model_model.blockSignals(True)2621 2532 if self.has_error_column: 2622 2533 # err column changes the indexing … … 2624 2535 else: 2625 2536 self._model_model.item(row, 0).child(0).child(0,4).setText(combo_string) 2626 self._model_model.blockSignals(False)2627 2537 2628 2538 if combo_string == 'array': … … 2743 2653 param.units] 2744 2654 2745 self.magnet_params[param.name] = param.default2746 2747 2655 FittingUtilities.addCheckedListToModel(model, checked_list) 2748 2656 … … 2784 2692 2785 2693 self.lstParams.setIndexWidget(shell_index, func) 2786 self._ n_shells_row = shell_row - 12694 self._last_model_row = self._model_model.rowCount() 2787 2695 2788 2696 # Set the index to the state-kept value … … 2795 2703 """ 2796 2704 # Find row location of the combobox 2797 first_row = self._n_shells_row + 12798 remove_rows = self._ num_shell_params2705 last_row = self._last_model_row 2706 remove_rows = self._model_model.rowCount() - last_row 2799 2707 2800 2708 if remove_rows > 1: 2801 self._model_model.removeRows( first_row, remove_rows)2802 2803 new_rows =FittingUtilities.addShellsToModel(2709 self._model_model.removeRows(last_row, remove_rows) 2710 2711 FittingUtilities.addShellsToModel( 2804 2712 self.model_parameters, 2805 2713 self._model_model, 2806 2714 index, 2807 first_row,2808 2715 self.lstParams) 2809 2716 2810 self._num_shell_params = len(new_rows)2811 2717 self.current_shell_displayed = index 2812 2718 -
src/sas/qtgui/Perspectives/Fitting/ModelThread.py
rdcabba7 r2df558e 101 101 elapsed = time.time() - self.starttime 102 102 103 res = dict(image = output, data = self.data, page_id = self.page_id,104 model = self.model, state = self.state,105 toggle_mode_on = self.toggle_mode_on, elapsed = elapsed,106 index = index_model, fid = self.fid,107 qmin = self.qmin, qmax = self.qmax,108 weight = self.weight, update_chisqr = self.update_chisqr,109 source = self.source)110 111 103 if LocalConfig.USING_TWISTED: 112 return res 113 else: 114 self.completefn(res) 104 return (output, 105 self.data, 106 self.page_id, 107 self.model, 108 self.state, 109 self.toggle_mode_on, 110 elapsed, 111 index_model, 112 self.fid, 113 self.qmin, 114 self.qmax, 115 self.weight, 116 self.update_chisqr, 117 self.source) 118 else: 119 self.completefn((output, 120 self.data, 121 self.page_id, 122 self.model, 123 self.state, 124 self.toggle_mode_on, 125 elapsed, 126 index_model, 127 self.fid, 128 self.qmin, 129 self.qmax, 130 self.weight, 131 #qstep=self.qstep, 132 self.update_chisqr, 133 self.source)) 134 115 135 116 136 class Calc1D(CalcThread): … … 216 236 elapsed = time.time() - self.starttime 217 237 218 res = dict(x = self.data.x[index], y = output[index],219 page_id = self.page_id, state = self.state, weight = self.weight,220 fid = self.fid, toggle_mode_on = self.toggle_mode_on,221 elapsed = elapsed, index = index, model = self.model,222 data = self.data, update_chisqr = self.update_chisqr,223 source = self.source, unsmeared_output = unsmeared_output,224 unsmeared_data = unsmeared_data, unsmeared_error = unsmeared_error,225 pq_values = pq_values, sq_values = sq_values)226 227 238 if LocalConfig.USING_TWISTED: 228 return res 229 else: 230 self.completefn(res) 239 return (self.data.x[index], output[index], 240 self.page_id, 241 self.state, 242 self.weight, 243 self.fid, 244 self.toggle_mode_on, 245 elapsed, index, self.model, 246 self.data, 247 self.update_chisqr, 248 self.source, 249 unsmeared_output, unsmeared_data, unsmeared_error, 250 pq_values, sq_values) 251 else: 252 self.completefn((self.data.x[index], output[index], 253 self.page_id, 254 self.state, 255 self.weight, 256 self.fid, 257 self.toggle_mode_on, 258 elapsed, index, self.model, 259 self.data, 260 self.update_chisqr, 261 self.source, 262 unsmeared_output, unsmeared_data, unsmeared_error, 263 pq_values, sq_values)) 231 264 232 265 def results(self): -
src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py
r3fbd77b r605d944 256 256 self.widget.cbStructureFactor.setCurrentIndex(structure_index) 257 257 258 # We have 3 more param rows now (radius_effective is removed), and a new heading258 # We have 4 more rows now 259 259 self.assertEqual(self.widget._model_model.rowCount(), rowcount+4) 260 260 … … 276 276 last_index = self.widget.cbStructureFactor.count() 277 277 self.widget.cbStructureFactor.setCurrentIndex(last_index-1) 278 # Do we have all the rows (incl. radius_effective & heading row)?279 self.assertEqual(self.widget._model_model.rowCount(), 5)278 # Do we have all the rows? 279 self.assertEqual(self.widget._model_model.rowCount(), 4) 280 280 281 281 # Are the command buttons properly enabled? … … 445 445 self.assertEqual(self.widget.kernel_module.details['radius_bell'][1], 1.0) 446 446 447 #self.widget.show()448 #QtWidgets.QApplication.exec_()449 450 447 # Change the number of points 451 self.assertEqual(self.widget. poly_params['radius_bell.npts'], 35)448 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.npts'), 35) 452 449 self.widget._poly_model.item(0,4).setText("22") 453 self.assertEqual(self.widget. poly_params['radius_bell.npts'], 22)450 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.npts'), 22) 454 451 # try something stupid 455 452 self.widget._poly_model.item(0,4).setText("butt") 456 453 # see that this didn't annoy the control at all 457 self.assertEqual(self.widget. poly_params['radius_bell.npts'], 22)454 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.npts'), 22) 458 455 459 456 # Change the number of sigmas 460 self.assertEqual(self.widget. poly_params['radius_bell.nsigmas'], 3)457 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.nsigmas'), 3) 461 458 self.widget._poly_model.item(0,5).setText("222") 462 self.assertEqual(self.widget. poly_params['radius_bell.nsigmas'], 222)459 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.nsigmas'), 222) 463 460 # try something stupid again 464 461 self.widget._poly_model.item(0,4).setText("beer") 465 462 # no efect 466 self.assertEqual(self.widget. poly_params['radius_bell.nsigmas'], 222)463 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.nsigmas'), 222) 467 464 468 465 def testOnPolyComboIndexChange(self): … … 485 482 self.widget.onPolyComboIndexChange('rectangle', 0) 486 483 # check values 487 self.assertEqual(self.widget. poly_params['radius_bell.npts'], 35)488 self.assertAlmostEqual(self.widget. poly_params['radius_bell.nsigmas'], 1.73205, 5)484 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.npts'), 35) 485 self.assertAlmostEqual(self.widget.kernel_module.getParam('radius_bell.nsigmas'), 1.73205, 5) 489 486 # Change the index 490 487 self.widget.onPolyComboIndexChange('lognormal', 0) 491 488 # check values 492 self.assertEqual(self.widget. poly_params['radius_bell.npts'], 80)493 self.assertEqual(self.widget. poly_params['radius_bell.nsigmas'], 8)489 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.npts'), 80) 490 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.nsigmas'), 8) 494 491 # Change the index 495 492 self.widget.onPolyComboIndexChange('schulz', 0) 496 493 # check values 497 self.assertEqual(self.widget. poly_params['radius_bell.npts'], 80)498 self.assertEqual(self.widget. poly_params['radius_bell.nsigmas'], 8)494 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.npts'), 80) 495 self.assertEqual(self.widget.kernel_module.getParam('radius_bell.nsigmas'), 8) 499 496 500 497 # mock up file load … … 509 506 Test opening of the load file dialog for 'array' polydisp. function 510 507 """ 511 512 # open a non-existent file513 508 filename = os.path.join("UnitTesting", "testdata_noexist.txt") 514 with self.assertRaises(OSError, msg="testdata_noexist.txt should be a non-existent file"):515 os.stat(filename)516 509 QtWidgets.QFileDialog.getOpenFileName = MagicMock(return_value=(filename,'')) 517 510 self.widget.show() … … 529 522 530 523 # good file 531 # TODO: this depends on the working directory being src/sas/qtgui,532 # TODO: which isn't convenient if you want to run this test suite533 # TODO: individually534 524 filename = os.path.join("UnitTesting", "testdata.txt") 535 try:536 os.stat(filename)537 except OSError:538 self.assertTrue(False, "testdata.txt does not exist")539 525 QtWidgets.QFileDialog.getOpenFileName = MagicMock(return_value=(filename,'')) 540 526 … … 602 588 603 589 # Assure we have the combobox available 604 cbox_row = self.widget._n_shells_row605 func_index = self.widget._model_model.index( cbox_row, 1)590 last_row = self.widget._last_model_row 591 func_index = self.widget._model_model.index(last_row-1, 1) 606 592 self.assertIsInstance(self.widget.lstParams.indexWidget(func_index), QtWidgets.QComboBox) 607 608 # get number of rows before changing shell count609 last_row = self.widget._model_model.rowCount()610 593 611 594 # Change the combo box index … … 1041 1024 1042 1025 # Check the model 1043 self.assertEqual(self.widget._model_model.rowCount(), 7)1026 self.assertEqual(self.widget._model_model.rowCount(), 6) 1044 1027 self.assertEqual(self.widget._model_model.columnCount(), 5) 1045 1028 … … 1157 1140 # two rows selected 1158 1141 index1 = self.widget.lstParams.model().index(1, 0, QtCore.QModelIndex()) 1159 index2 = self.widget.lstParams.model().index( 3, 0, QtCore.QModelIndex())1142 index2 = self.widget.lstParams.model().index(2, 0, QtCore.QModelIndex()) 1160 1143 selection_model = self.widget.lstParams.selectionModel() 1161 1144 selection_model.select(index1, selection_model.Select | selection_model.Rows) … … 1193 1176 # several random parameters 1194 1177 self.assertEqual(self.widget.getRowFromName('scale'), 0) 1195 self.assertEqual(self.widget.getRowFromName('length'), 6)1178 self.assertEqual(self.widget.getRowFromName('length'), 5) 1196 1179 1197 1180 def testGetParamNames(self): … … 1230 1213 # Create a constraint object 1231 1214 const = Constraint(parent=None, value=7.0) 1232 row = 31215 row = 2 1233 1216 1234 1217 spy = QtSignalSpy(self.widget, self.widget.constraintAddedSignal) … … 1249 1232 # assign complex constraint now 1250 1233 const = Constraint(parent=None, param='radius', func='5*sld') 1251 row = 51234 row = 4 1252 1235 # call the method tested 1253 1236 self.widget.addConstraintToRow(constraint=const, row=row) … … 1308 1291 self.widget.cbModel.setCurrentIndex(model_index) 1309 1292 1293 # select two rows 1310 1294 row1 = 1 1311 row2 = 5 1312 1313 param1 = "background" 1314 param2 = "radius" 1315 1316 #default_value1 = "0.001" 1317 default_value2 = "20" 1318 1319 # select two rows 1295 row2 = 4 1320 1296 index1 = self.widget.lstParams.model().index(row1, 0, QtCore.QModelIndex()) 1321 1297 index2 = self.widget.lstParams.model().index(row2, 0, QtCore.QModelIndex()) … … 1334 1310 1335 1311 # delete one of the constraints 1336 self.widget.deleteConstraintOnParameter(param= param1)1312 self.widget.deleteConstraintOnParameter(param='background') 1337 1313 1338 1314 # see that the other constraint is still present 1339 cons = self.widget.getConstraintForRow( row2)1340 self.assertEqual(cons.param, param2)1341 self.assertEqual(cons.value, default_value2)1315 cons = self.widget.getConstraintForRow(4) # 4 = radius 1316 self.assertEqual(cons.param, "radius") 1317 self.assertEqual(cons.value, "20") 1342 1318 1343 1319 # kill the other constraint … … 1345 1321 1346 1322 # see that the other constraint is still present 1347 self.assertEqual(self.widget.getConstraintsForModel(), [( param2, None)])1323 self.assertEqual(self.widget.getConstraintsForModel(), [('radius', None)]) 1348 1324 1349 1325 def testGetConstraintForRow(self): … … 1365 1341 self.widget.cbModel.setCurrentIndex(model_index) 1366 1342 1343 # select two rows 1367 1344 row1 = 1 1368 row2 = 5 1369 1370 # select two rows 1345 row2 = 4 1371 1346 index1 = self.widget.lstParams.model().index(row1, 0, QtCore.QModelIndex()) 1372 1347 index2 = self.widget.lstParams.model().index(row2, 0, QtCore.QModelIndex()) … … 1378 1353 self.widget.addSimpleConstraint() 1379 1354 1380 con_list = [False, True, False, False, False,True, False]1355 con_list = [False, True, False, False, True, False] 1381 1356 new_list = [] 1382 1357 for row in range(self.widget._model_model.rowCount()): … … 1396 1371 self.widget.cbModel.setCurrentIndex(model_index) 1397 1372 1373 # select two rows 1398 1374 row1 = 1 1399 row2 = 5 1400 1401 # select two rows 1375 row2 = 4 1402 1376 index1 = self.widget.lstParams.model().index(row1, 0, QtCore.QModelIndex()) 1403 1377 index2 = self.widget.lstParams.model().index(row2, 0, QtCore.QModelIndex()) … … 1413 1387 constraint_objects[0].active = False 1414 1388 1415 con_list = [False, False, False, False, False,True, False]1389 con_list = [False, False, False, False, True, False] 1416 1390 new_list = [] 1417 1391 for row in range(self.widget._model_model.rowCount()): … … 1434 1408 self.assertEqual(self.widget.getConstraintsForModel(),[]) 1435 1409 1410 # select two rows 1436 1411 row1 = 1 1437 row2 = 5 1438 1439 param1 = "background" 1440 param2 = "radius" 1441 1442 default_value1 = "0.001" 1443 default_value2 = "20" 1444 1445 # select two rows 1412 row2 = 4 1446 1413 index1 = self.widget.lstParams.model().index(row1, 0, QtCore.QModelIndex()) 1447 1414 index2 = self.widget.lstParams.model().index(row2, 0, QtCore.QModelIndex()) … … 1455 1422 # simple constraints 1456 1423 # self.assertEqual(self.widget.getConstraintsForModel(), [('background', '0.001'), ('radius', '20')]) 1457 cons = self.widget.getConstraintForRow( row1)1458 self.assertEqual(cons.param, param1)1459 self.assertEqual(cons.value, default_value1)1460 cons = self.widget.getConstraintForRow( row2)1461 self.assertEqual(cons.param, param2)1462 self.assertEqual(cons.value, default_value2)1424 cons = self.widget.getConstraintForRow(1) # 1 - background 1425 self.assertEqual(cons.param, "background") 1426 self.assertEqual(cons.value, "0.001") 1427 cons = self.widget.getConstraintForRow(4) # 4 = radius 1428 self.assertEqual(cons.param, "radius") 1429 self.assertEqual(cons.value, "20") 1463 1430 1464 1431 objects = self.widget.getConstraintObjectsForModel() 1465 1432 self.assertEqual(len(objects), 2) 1466 self.assertEqual(objects[1].value, default_value2) 1467 self.assertEqual(objects[0].param, param1) 1468 1433 self.assertEqual(objects[1].value, '20') 1434 self.assertEqual(objects[0].param, 'background') 1435 1436 # add complex constraint 1437 const = Constraint(parent=None, param='scale', func='5*sld') 1469 1438 row = 0 1470 param = "scale"1471 func = "5*sld"1472 1473 # add complex constraint1474 const = Constraint(parent=None, param=param, func=func)1475 1439 self.widget.addConstraintToRow(constraint=const, row=row) 1476 1440 #self.assertEqual(self.widget.getConstraintsForModel(),[('scale', '5*sld'), ('background', '0.001'), ('radius', None)]) 1477 cons = self.widget.getConstraintForRow( row2)1478 self.assertEqual(cons.param, param2)1479 self.assertEqual(cons.value, default_value2)1441 cons = self.widget.getConstraintForRow(4) # 4 = radius 1442 self.assertEqual(cons.param, "radius") 1443 self.assertEqual(cons.value, "20") 1480 1444 1481 1445 objects = self.widget.getConstraintObjectsForModel() 1482 1446 self.assertEqual(len(objects), 3) 1483 self.assertEqual(objects[0].func, func)1447 self.assertEqual(objects[0].func, '5*sld') 1484 1448 1485 1449 def testReplaceConstraintName(self):
Note: See TracChangeset
for help on using the changeset viewer.