Changeset 9ba91b7 in sasview for src/sas/qtgui/Perspectives/Fitting
- Timestamp:
- Sep 7, 2018 10:11:37 AM (6 years ago)
- Branches:
- ESS_GUI, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
- Children:
- 254199c
- Parents:
- d6c4987 (diff), fb560d2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - git-author:
- Ingo Breßler <dev@…> (09/07/18 10:09:21)
- git-committer:
- Ingo Breßler <dev@…> (09/07/18 10:11:37)
- Location:
- src/sas/qtgui/Perspectives/Fitting
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Perspectives/Fitting/FittingLogic.py
r40975f8 r9ba91b7 161 161 Create a new 1D data instance based on fitting results 162 162 """ 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 intermediate_results = return_data 170 171 return self._create1DPlot(tab_id, x, y, model, data) 163 return self._create1DPlot(tab_id, return_data['x'], return_data['y'], 164 return_data['model'], return_data['data']) 172 165 173 166 def new2DPlot(self, return_data): … … 175 168 Create a new 2D data instance based on fitting results 176 169 """ 177 image , data, page_id, model, state, toggle_mode_on,\178 elapsed, index, fid, qmin, qmax, weight, \179 update_chisqr, source = return_data170 image = return_data['image'] 171 data = return_data['data'] 172 model = return_data['model'] 180 173 181 174 np.nan_to_num(image) … … 183 176 new_plot.name = model.name + '2d' 184 177 new_plot.title = "Analytical model 2D " 185 new_plot.id = str( page_id) + " " + data.name186 new_plot.group_id = str( page_id) + " Model2D"178 new_plot.id = str(return_data['page_id']) + " " + data.name 179 new_plot.group_id = str(return_data['page_id']) + " Model2D" 187 180 new_plot.detector = data.detector 188 181 new_plot.source = data.source … … 218 211 (pq_plot, sq_plot). If either are unavailable, the corresponding plot is None. 219 212 """ 220 # Unpack return data from Calc1D221 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 intermediate_results = return_data227 228 213 plots = [] 229 for name, result in intermediate_results.items(): 230 plots.append(self._create1DPlot(tab_id, x, result, model, data, component=name)) 214 for name, result in return_data['intermediate_results'].items(): 215 plots.append(self._create1DPlot(tab_id, return_data['x'], result, 216 return_data['model'], return_data['data'], 217 component=name)) 231 218 return plots 232 219 -
src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py
rb764ae5 r4ea8020 124 124 return item 125 125 126 def addSimpleParametersToModel(parameters, is2D ):126 def addSimpleParametersToModel(parameters, is2D, parameters_original=None): 127 127 """ 128 128 Update local ModelModel with sasmodel parameters 129 parameters_original: list of parameters before any tagging on their IDs, e.g. for product model 130 (so that those are the display names; see below) 129 131 """ 130 132 if is2D: … … 132 134 else: 133 135 params = parameters.iq_parameters 136 137 if parameters_original: 138 # 'parameters_original' contains the parameters as they are to be DISPLAYED, while 'parameters' 139 # contains the parameters as they were renamed; this is for handling name collisions in product model. 140 # The 'real name' of the parameter will be stored in the item's user data. 141 if is2D: 142 params_orig = [p for p in parameters_original.kernel_parameters if p.type != 'magnetic'] 143 else: 144 params_orig = parameters_original.iq_parameters 145 else: 146 # no difference in names anyway 147 params_orig = params 148 134 149 item = [] 135 for param in params:150 for param, param_orig in zip(params, params_orig): 136 151 # Create the top level, checkable item 137 item_name = param .name152 item_name = param_orig.name 138 153 item1 = QtGui.QStandardItem(item_name) 154 item1.setData(param.name, QtCore.Qt.UserRole) 139 155 item1.setCheckable(True) 140 156 item1.setEditable(False) … … 144 160 item4 = QtGui.QStandardItem(str(param.limits[0])) 145 161 item5 = QtGui.QStandardItem(str(param.limits[1])) 146 item6 = QtGui.QStandardItem( param.units)162 item6 = QtGui.QStandardItem(str(param.units)) 147 163 item6.setEditable(False) 148 164 item.append([item1, item2, item4, item5, item6]) … … 182 198 model.appendRow(item_list) 183 199 200 def addHeadingRowToModel(model, name): 201 """adds a non-interactive top-level row to the model""" 202 header_row = [QtGui.QStandardItem() for i in range(5)] 203 header_row[0].setText(name) 204 205 font = header_row[0].font() 206 font.setBold(True) 207 header_row[0].setFont(font) 208 209 for item in header_row: 210 item.setEditable(False) 211 item.setCheckable(False) 212 item.setSelectable(False) 213 214 model.appendRow(header_row) 215 184 216 def addHeadersToModel(model): 185 217 """ … … 227 259 model.header_tooltips = copy.copy(poly_header_error_tooltips) 228 260 229 def addShellsToModel(parameters, model, index): 230 """ 231 Find out multishell parameters and update the model with the requested number of them 261 def addShellsToModel(parameters, model, index, row_num=None): 262 """ 263 Find out multishell parameters and update the model with the requested number of them. 264 Inserts them after the row at row_num, if not None; otherwise, appends to end. 265 Returns a list of lists of QStandardItem objects. 232 266 """ 233 267 multishell_parameters = getIterParams(parameters) 234 268 269 rows = [] 235 270 for i in range(index): 236 271 for par in multishell_parameters: … … 259 294 item4 = QtGui.QStandardItem(str(par.limits[1])) 260 295 item5 = QtGui.QStandardItem(par.units) 261 model.appendRow([item1, item2, item3, item4, item5]) 296 row = [item1, item2, item3, item4, item5] 297 rows.append(row) 298 299 if row_num is None: 300 model.appendRow(row) 301 else: 302 model.insertRow(row_num, row) 303 row_num += 1 304 305 return rows 262 306 263 307 def calculateChi2(reference_data, current_data): -
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
r40975f8 r9ba91b7 91 91 fittingFinishedSignal = QtCore.pyqtSignal(tuple) 92 92 batchFittingFinishedSignal = QtCore.pyqtSignal(tuple) 93 Calc1DFinishedSignal = QtCore.pyqtSignal( tuple)94 Calc2DFinishedSignal = QtCore.pyqtSignal( tuple)93 Calc1DFinishedSignal = QtCore.pyqtSignal(dict) 94 Calc2DFinishedSignal = QtCore.pyqtSignal(dict) 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 variable for multishell display 222 self._last_model_row = 0 221 # Utility variables for multishell display 222 self._n_shells_row = 0 223 self._num_shell_params = 0 223 224 # Dictionary of {model name: model class} for the current category 224 225 self.models = {} … … 676 677 Return list of all parameters for the current model 677 678 """ 678 return [self._model_model.item(row).text() for row in range(self._model_model.rowCount())] 679 return [self._model_model.item(row).text() 680 for row in range(self._model_model.rowCount()) 681 if self.isCheckable(row)] 679 682 680 683 def modifyViewOnRow(self, row, font=None, brush=None): … … 704 707 assert isinstance(constraint, Constraint) 705 708 assert 0 <= row <= self._model_model.rowCount() 709 assert self.isCheckable(row) 706 710 707 711 item = QtGui.QStandardItem() … … 724 728 max_col = self.lstParams.itemDelegate().param_max 725 729 for row in self.selectedParameters(): 730 assert(self.isCheckable(row)) 726 731 param = self._model_model.item(row, 0).text() 727 732 value = self._model_model.item(row, 1).text() … … 766 771 max_col = self.lstParams.itemDelegate().param_max 767 772 for row in range(self._model_model.rowCount()): 773 if not self.isCheckable(row): 774 continue 768 775 if not self.rowHasConstraint(row): 769 776 continue … … 794 801 For the given row, return its constraint, if any 795 802 """ 796 try:803 if self.isCheckable(row): 797 804 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 805 try: 806 return item.child(0).data() 807 except AttributeError: 808 # return none when no constraints 809 pass 810 return None 802 811 803 812 def rowHasConstraint(self, row): … … 805 814 Finds out if row of the main model has a constraint child 806 815 """ 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 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 812 822 return False 813 823 … … 816 826 Finds out if row of the main model has an active constraint child 817 827 """ 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 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 823 834 return False 824 835 … … 827 838 Finds out if row of the main model has an active, nontrivial constraint child 828 839 """ 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 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 834 846 return False 835 847 … … 1197 1209 self.updateData() 1198 1210 1211 # update in param model 1212 if model_column in [delegate.poly_pd, delegate.poly_error, delegate.poly_min, delegate.poly_max]: 1213 row = self.getRowFromName(parameter_name) 1214 param_item = self._model_model.item(row) 1215 self._model_model.blockSignals(True) 1216 param_item.child(0).child(0, model_column).setText(item.text()) 1217 self._model_model.blockSignals(False) 1218 1199 1219 def onMagnetModelChange(self, item): 1200 1220 """ … … 1569 1589 # internal so can use closure for param_dict 1570 1590 param_name = str(self._model_model.item(row, 0).text()) 1571 if param_name not in list(param_dict.keys()):1591 if not self.isCheckable(row) or param_name not in list(param_dict.keys()): 1572 1592 return 1573 1593 # modify the param value … … 1581 1601 # Utility function for updateof polydispersity part of the main model 1582 1602 param_name = str(self._model_model.item(row, 0).text())+'.width' 1583 if param_name not in list(param_dict.keys()):1603 if not self.isCheckable(row) or param_name not in list(param_dict.keys()): 1584 1604 return 1585 1605 # modify the param value … … 1958 1978 # Crete/overwrite model items 1959 1979 self._model_model.clear() 1960 1961 # First, add parameters from the main model 1962 if model_name is not None: 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 factor 1986 self.kernel_module = None 1987 self.fromStructureFactorToQModel(structure_factor) 1988 else: 1989 # No models selected 1990 return 1991 else: 1963 1992 self.fromModelToQModel(model_name) 1964 1965 # Then, add structure factor derived parameters 1966 if structure_factor is not None and structure_factor != "None": 1967 if model_name is None: 1968 # Instantiate the current sasmodel for SF-only models 1969 self.kernel_module = self.models[structure_factor]() 1970 self.fromStructureFactorToQModel(structure_factor) 1971 else: 1993 self.addExtraShells() 1994 1972 1995 # Allow the SF combobox visibility for the given sasmodel 1973 1996 self.enableStructureFactorControl(structure_factor) 1997 1998 # Add S(Q) 1974 1999 if self.cbStructureFactor.isEnabled(): 1975 2000 structure_factor = self.cbStructureFactor.currentText() 1976 2001 self.fromStructureFactorToQModel(structure_factor) 1977 2002 1978 # Then, add multishells 1979 if model_name is not None: 1980 # Multishell models need additional treatment 1981 self.addExtraShells() 1982 1983 # Add polydispersity to the model 1984 self.poly_params = {} 1985 self.setPolyModel() 1986 # Add magnetic parameters to the model 1987 self.magnet_params = {} 1988 self.setMagneticModel() 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() 1989 2009 1990 2010 # Adjust the table cells width … … 2059 2079 self.shell_names = self.shellNamesList() 2060 2080 2061 # Update theQModel2081 # Get new rows for QModel 2062 2082 new_rows = FittingUtilities.addParametersToModel(self.model_parameters, self.kernel_module, self.is2D) 2063 2083 2084 # Add heading row 2085 FittingUtilities.addHeadingRowToModel(self._model_model, model_name) 2086 2087 # Update QModel 2064 2088 for row in new_rows: 2065 2089 self._model_model.appendRow(row) 2066 # Update the counter used for multishell display2067 self._last_model_row = self._model_model.rowCount()2068 2090 2069 2091 def fromStructureFactorToQModel(self, structure_factor): … … 2073 2095 if structure_factor is None or structure_factor=="None": 2074 2096 return 2075 structure_module = generate.load_kernel_module(structure_factor) 2076 structure_parameters = modelinfo.make_parameter_table(getattr(structure_module, 'parameters', [])) 2077 2078 structure_kernel = self.models[structure_factor]() 2079 form_kernel = self.kernel_module 2080 2081 self.kernel_module = MultiplicationModel(form_kernel, structure_kernel) 2082 2083 new_rows = FittingUtilities.addSimpleParametersToModel(structure_parameters, self.is2D) 2097 2098 s_kernel = self.models[structure_factor]() 2099 p_kernel = self.kernel_module 2100 2101 if p_kernel is None: 2102 # Not a product model, just S(Q) 2103 self.kernel_module = s_kernel 2104 params = modelinfo.ParameterTable(self.kernel_module._model_info.parameters.kernel_parameters) 2105 new_rows = FittingUtilities.addSimpleParametersToModel(params, self.is2D) 2106 else: 2107 p_pars_len = len(p_kernel._model_info.parameters.kernel_parameters) 2108 s_pars_len = len(s_kernel._model_info.parameters.kernel_parameters) 2109 2110 self.kernel_module = MultiplicationModel(p_kernel, s_kernel) 2111 all_params = self.kernel_module._model_info.parameters.kernel_parameters 2112 all_param_names = [param.name for param in all_params] 2113 2114 # S(Q) params from the product model are not necessarily the same as those from the S(Q) model; any 2115 # conflicting names with P(Q) params will cause a rename; we also lose radius_effective (for now...) 2116 2117 # TODO: merge rest of beta approx implementation in 2118 # This is to ensure compatibility when we merge beta approx support in...! 2119 2120 # radius_effective is always s_params[0] 2121 2122 # if radius_effective_mode is in all_params, then all_params contains radius_effective and we want to 2123 # keep it in the model 2124 2125 # if radius_effective_mode is NOT in all_params, then radius_effective should NOT be kept, because the user 2126 # cannot specify it themselves; but, make sure we only remove it if it's actually there in the first place 2127 # (sasmodels master removes it already) 2128 if "radius_effective_mode" in all_param_names: 2129 # Show all parameters 2130 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len]) 2131 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters) 2132 else: 2133 # Ensure radius_effective is not displayed 2134 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters[1:]) 2135 if "radius_effective" in all_param_names: 2136 s_params = modelinfo.ParameterTable(all_params[p_pars_len+1:p_pars_len+s_pars_len]) 2137 else: 2138 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len-1]) 2139 2140 # Get new rows for QModel 2141 # Any renamed parameters are stored as data in the relevant item, for later handling 2142 new_rows = FittingUtilities.addSimpleParametersToModel(s_params, self.is2D, s_params_orig) 2143 2144 # TODO: merge rest of beta approx implementation in 2145 # These parameters are not part of P(Q) nor S(Q), but are added only to the product model (e.g. specifying 2146 # structure factor calculation mode) 2147 # product_params = all_params[p_pars_len+s_pars_len:] 2148 2149 # Add heading row 2150 FittingUtilities.addHeadingRowToModel(self._model_model, structure_factor) 2151 2152 # Update QModel 2084 2153 for row in new_rows: 2085 2154 self._model_model.appendRow(row) 2086 2155 # disable fitting of parameters not listed in self.kernel_module (probably radius_effective) 2087 if row[0].text() not in self.kernel_module.params.keys(): 2088 row_num = self._model_model.rowCount() - 1 2089 FittingUtilities.markParameterDisabled(self._model_model, row_num) 2090 2091 # Update the counter used for multishell display 2092 self._last_model_row = self._model_model.rowCount() 2156 # if row[0].text() not in self.kernel_module.params.keys(): 2157 # row_num = self._model_model.rowCount() - 1 2158 # FittingUtilities.markParameterDisabled(self._model_model, row_num) 2093 2159 2094 2160 def haveParamsToFit(self): … … 2116 2182 model_row = item.row() 2117 2183 name_index = self._model_model.index(model_row, 0) 2184 name_item = self._model_model.itemFromIndex(name_index) 2118 2185 2119 2186 # Extract changed value. … … 2124 2191 return 2125 2192 2126 parameter_name = str(self._model_model.data(name_index)) # sld, background etc. 2193 # if the item has user data, this is the actual parameter name (e.g. to handle duplicate names) 2194 if name_item.data(QtCore.Qt.UserRole): 2195 parameter_name = str(name_item.data(QtCore.Qt.UserRole)) 2196 else: 2197 parameter_name = str(self._model_model.data(name_index)) 2127 2198 2128 2199 # Update the parameter value - note: this supports +/-inf as well … … 2352 2423 new_plots.append(plot) 2353 2424 2354 # Update/generate plots2355 2425 for plot in new_plots: 2356 2426 self.communicate.plotUpdateSignal.emit([plot]) … … 2552 2622 def updateFunctionCaption(row): 2553 2623 # Utility function for update of polydispersity function name in the main model 2624 if not self.isCheckable(row): 2625 return 2626 self._model_model.blockSignals(True) 2554 2627 param_name = str(self._model_model.item(row, 0).text()) 2628 self._model_model.blockSignals(False) 2555 2629 if param_name != param.name: 2556 2630 return 2557 2631 # Modify the param value 2632 self._model_model.blockSignals(True) 2558 2633 if self.has_error_column: 2559 2634 # err column changes the indexing … … 2561 2636 else: 2562 2637 self._model_model.item(row, 0).child(0).child(0,4).setText(combo_string) 2638 self._model_model.blockSignals(False) 2563 2639 2564 2640 if combo_string == 'array': … … 2720 2796 2721 2797 self.lstParams.setIndexWidget(shell_index, func) 2722 self._ last_model_row = self._model_model.rowCount()2798 self._n_shells_row = shell_row - 1 2723 2799 2724 2800 # Set the index to the state-kept value … … 2731 2807 """ 2732 2808 # Find row location of the combobox 2733 last_row = self._last_model_row2734 remove_rows = self._ model_model.rowCount() - last_row2809 first_row = self._n_shells_row + 1 2810 remove_rows = self._num_shell_params 2735 2811 2736 2812 if remove_rows > 1: 2737 self._model_model.removeRows(last_row, remove_rows) 2738 2739 FittingUtilities.addShellsToModel(self.model_parameters, self._model_model, index) 2813 self._model_model.removeRows(first_row, remove_rows) 2814 2815 new_rows = FittingUtilities.addShellsToModel(self.model_parameters, self._model_model, index, first_row) 2816 self._num_shell_params = len(new_rows) 2817 2740 2818 self.current_shell_displayed = index 2741 2819 -
src/sas/qtgui/Perspectives/Fitting/ModelThread.py
r40975f8 r9ba91b7 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 103 111 if LocalConfig.USING_TWISTED: 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 112 return res 113 else: 114 self.completefn(res) 135 115 136 116 class Calc1D(CalcThread): … … 249 229 elapsed = time.time() - self.starttime 250 230 231 res = dict(x = self.data.x[index], y = output[index], 232 page_id = self.page_id, state = self.state, weight = self.weight, 233 fid = self.fid, toggle_mode_on = self.toggle_mode_on, 234 elapsed = elapsed, index = index, model = self.model, 235 data = self.data, update_chisqr = self.update_chisqr, 236 source = self.source, unsmeared_output = unsmeared_output, 237 unsmeared_data = unsmeared_data, unsmeared_error = unsmeared_error, 238 intermediate_results = results_eval) 239 251 240 if LocalConfig.USING_TWISTED: 252 return (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 results_eval) 264 else: 265 self.completefn((self.data.x[index], output[index], 266 self.page_id, 267 self.state, 268 self.weight, 269 self.fid, 270 self.toggle_mode_on, 271 elapsed, index, self.model, 272 self.data, 273 self.update_chisqr, 274 self.source, 275 unsmeared_output, unsmeared_data, unsmeared_error, 276 results_eval)) 241 return res 242 else: 243 self.completefn(res) 277 244 278 245 def results(self): -
src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py
r66d4370 r4ea8020 256 256 self.widget.cbStructureFactor.setCurrentIndex(structure_index) 257 257 258 # We have 4 more rows now258 # We have 3 more param rows now (radius_effective is removed), and a new heading 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 ?279 self.assertEqual(self.widget._model_model.rowCount(), 4)278 # Do we have all the rows (incl. radius_effective & heading row)? 279 self.assertEqual(self.widget._model_model.rowCount(), 5) 280 280 281 281 # Are the command buttons properly enabled? … … 509 509 Test opening of the load file dialog for 'array' polydisp. function 510 510 """ 511 512 # open a non-existent file 511 513 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) 512 516 QtWidgets.QFileDialog.getOpenFileName = MagicMock(return_value=(filename,'')) 513 517 self.widget.show() … … 525 529 526 530 # 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 suite 533 # TODO: individually 527 534 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") 528 539 QtWidgets.QFileDialog.getOpenFileName = MagicMock(return_value=(filename,'')) 529 540 … … 591 602 592 603 # Assure we have the combobox available 593 last_row = self.widget._last_model_row594 func_index = self.widget._model_model.index( last_row-1, 1)604 cbox_row = self.widget._n_shells_row 605 func_index = self.widget._model_model.index(cbox_row, 1) 595 606 self.assertIsInstance(self.widget.lstParams.indexWidget(func_index), QtWidgets.QComboBox) 607 608 # get number of rows before changing shell count 609 last_row = self.widget._model_model.rowCount() 596 610 597 611 # Change the combo box index … … 1027 1041 1028 1042 # Check the model 1029 self.assertEqual(self.widget._model_model.rowCount(), 6)1043 self.assertEqual(self.widget._model_model.rowCount(), 7) 1030 1044 self.assertEqual(self.widget._model_model.columnCount(), 5) 1031 1045 … … 1143 1157 # two rows selected 1144 1158 index1 = self.widget.lstParams.model().index(1, 0, QtCore.QModelIndex()) 1145 index2 = self.widget.lstParams.model().index( 2, 0, QtCore.QModelIndex())1159 index2 = self.widget.lstParams.model().index(3, 0, QtCore.QModelIndex()) 1146 1160 selection_model = self.widget.lstParams.selectionModel() 1147 1161 selection_model.select(index1, selection_model.Select | selection_model.Rows) … … 1179 1193 # several random parameters 1180 1194 self.assertEqual(self.widget.getRowFromName('scale'), 0) 1181 self.assertEqual(self.widget.getRowFromName('length'), 5)1195 self.assertEqual(self.widget.getRowFromName('length'), 6) 1182 1196 1183 1197 def testGetParamNames(self): … … 1216 1230 # Create a constraint object 1217 1231 const = Constraint(parent=None, value=7.0) 1218 row = 21232 row = 3 1219 1233 1220 1234 spy = QtSignalSpy(self.widget, self.widget.constraintAddedSignal) … … 1235 1249 # assign complex constraint now 1236 1250 const = Constraint(parent=None, param='radius', func='5*sld') 1237 row = 41251 row = 5 1238 1252 # call the method tested 1239 1253 self.widget.addConstraintToRow(constraint=const, row=row) … … 1294 1308 self.widget.cbModel.setCurrentIndex(model_index) 1295 1309 1310 row1 = 1 1311 row2 = 5 1312 1313 param1 = "background" 1314 param2 = "radius" 1315 1316 #default_value1 = "0.001" 1317 default_value2 = "20" 1318 1296 1319 # select two rows 1297 row1 = 11298 row2 = 41299 1320 index1 = self.widget.lstParams.model().index(row1, 0, QtCore.QModelIndex()) 1300 1321 index2 = self.widget.lstParams.model().index(row2, 0, QtCore.QModelIndex()) … … 1313 1334 1314 1335 # delete one of the constraints 1315 self.widget.deleteConstraintOnParameter(param= 'background')1336 self.widget.deleteConstraintOnParameter(param=param1) 1316 1337 1317 1338 # see that the other constraint is still present 1318 cons = self.widget.getConstraintForRow( 4) # 4 = radius1319 self.assertEqual(cons.param, "radius")1320 self.assertEqual(cons.value, "20")1339 cons = self.widget.getConstraintForRow(row2) 1340 self.assertEqual(cons.param, param2) 1341 self.assertEqual(cons.value, default_value2) 1321 1342 1322 1343 # kill the other constraint … … 1324 1345 1325 1346 # see that the other constraint is still present 1326 self.assertEqual(self.widget.getConstraintsForModel(), [( 'radius', None)])1347 self.assertEqual(self.widget.getConstraintsForModel(), [(param2, None)]) 1327 1348 1328 1349 def testGetConstraintForRow(self): … … 1344 1365 self.widget.cbModel.setCurrentIndex(model_index) 1345 1366 1367 row1 = 1 1368 row2 = 5 1369 1346 1370 # select two rows 1347 row1 = 11348 row2 = 41349 1371 index1 = self.widget.lstParams.model().index(row1, 0, QtCore.QModelIndex()) 1350 1372 index2 = self.widget.lstParams.model().index(row2, 0, QtCore.QModelIndex()) … … 1356 1378 self.widget.addSimpleConstraint() 1357 1379 1358 con_list = [False, True, False, False, True, False]1380 con_list = [False, True, False, False, False, True, False] 1359 1381 new_list = [] 1360 1382 for row in range(self.widget._model_model.rowCount()): … … 1374 1396 self.widget.cbModel.setCurrentIndex(model_index) 1375 1397 1398 row1 = 1 1399 row2 = 5 1400 1376 1401 # select two rows 1377 row1 = 11378 row2 = 41379 1402 index1 = self.widget.lstParams.model().index(row1, 0, QtCore.QModelIndex()) 1380 1403 index2 = self.widget.lstParams.model().index(row2, 0, QtCore.QModelIndex()) … … 1390 1413 constraint_objects[0].active = False 1391 1414 1392 con_list = [False, False, False, False, True, False]1415 con_list = [False, False, False, False, False, True, False] 1393 1416 new_list = [] 1394 1417 for row in range(self.widget._model_model.rowCount()): … … 1411 1434 self.assertEqual(self.widget.getConstraintsForModel(),[]) 1412 1435 1436 row1 = 1 1437 row2 = 5 1438 1439 param1 = "background" 1440 param2 = "radius" 1441 1442 default_value1 = "0.001" 1443 default_value2 = "20" 1444 1413 1445 # select two rows 1414 row1 = 11415 row2 = 41416 1446 index1 = self.widget.lstParams.model().index(row1, 0, QtCore.QModelIndex()) 1417 1447 index2 = self.widget.lstParams.model().index(row2, 0, QtCore.QModelIndex()) … … 1425 1455 # simple constraints 1426 1456 # self.assertEqual(self.widget.getConstraintsForModel(), [('background', '0.001'), ('radius', '20')]) 1427 cons = self.widget.getConstraintForRow( 1) # 1 - background1428 self.assertEqual(cons.param, "background")1429 self.assertEqual(cons.value, "0.001")1430 cons = self.widget.getConstraintForRow( 4) # 4 = radius1431 self.assertEqual(cons.param, "radius")1432 self.assertEqual(cons.value, "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) 1433 1463 1434 1464 objects = self.widget.getConstraintObjectsForModel() 1435 1465 self.assertEqual(len(objects), 2) 1436 self.assertEqual(objects[1].value, '20') 1437 self.assertEqual(objects[0].param, 'background') 1466 self.assertEqual(objects[1].value, default_value2) 1467 self.assertEqual(objects[0].param, param1) 1468 1469 row = 0 1470 param = "scale" 1471 func = "5*sld" 1438 1472 1439 1473 # add complex constraint 1440 const = Constraint(parent=None, param='scale', func='5*sld') 1441 row = 0 1474 const = Constraint(parent=None, param=param, func=func) 1442 1475 self.widget.addConstraintToRow(constraint=const, row=row) 1443 1476 #self.assertEqual(self.widget.getConstraintsForModel(),[('scale', '5*sld'), ('background', '0.001'), ('radius', None)]) 1444 cons = self.widget.getConstraintForRow( 4) # 4 = radius1445 self.assertEqual(cons.param, "radius")1446 self.assertEqual(cons.value, "20")1477 cons = self.widget.getConstraintForRow(row2) 1478 self.assertEqual(cons.param, param2) 1479 self.assertEqual(cons.value, default_value2) 1447 1480 1448 1481 objects = self.widget.getConstraintObjectsForModel() 1449 1482 self.assertEqual(len(objects), 3) 1450 self.assertEqual(objects[0].func, '5*sld')1483 self.assertEqual(objects[0].func, func) 1451 1484 1452 1485 def testReplaceConstraintName(self): -
src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingLogicTest.py
re752ab8 rd6c4987 103 103 data, False, None, 104 104 None, None, None, 105 None , None)105 None) 106 106 107 107 new_plot = self.logic.new1DPlot(return_data=return_data, tab_id=0)
Note: See TracChangeset
for help on using the changeset viewer.