Changes in / [0101c9f:5a2bb75] in sasview
- Location:
- src/sas/qtgui
- Files:
-
- 1 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/MainWindow/DataExplorer.py
r339e22b rfd7ef36 42 42 # Main model for keeping loaded data 43 43 self.model = QtGui.QStandardItemModel(self) 44 44 45 # Secondary model for keeping frozen data sets 45 46 self.theory_model = QtGui.QStandardItemModel(self) … … 97 98 self.communicator.plotUpdateSignal.connect(self.updatePlot) 98 99 self.communicator.maskEditorSignal.connect(self.showEditDataMask) 99 self.communicator.extMaskEditorSignal.connect(self.extShowEditDataMask)100 100 101 101 self.cbgraph.editTextChanged.connect(self.enableGraphCombo) … … 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): … … 1059 1059 self.new_plot.show() 1060 1060 1061 def extShowEditDataMask(self):1062 self.showEditDataMask()1063 1064 1061 def showEditDataMask(self, data=None): 1065 1062 """ 1066 1063 Mask Editor for 2D plots 1067 1064 """ 1068 try: 1069 if data is None or not isinstance(data, Data2D): 1070 index = self.current_view.selectedIndexes()[0] 1071 proxy = self.current_view.model() 1072 model = proxy.sourceModel() 1073 model_item = model.itemFromIndex(proxy.mapToSource(index)) 1074 1075 data = GuiUtils.dataFromItem(model_item) 1076 1077 if data is None or not isinstance(data, Data2D): 1078 msg = QtWidgets.QMessageBox() 1079 msg.setIcon(QtWidgets.QMessageBox.Information) 1080 msg.setText("Error: cannot apply mask. \ 1081 Please select a 2D dataset.") 1082 msg.setStandardButtons(QtWidgets.QMessageBox.Cancel) 1083 msg.exec_() 1084 return 1085 except: 1086 msg = QtWidgets.QMessageBox() 1087 msg.setIcon(QtWidgets.QMessageBox.Information) 1088 msg.setText("Error: No dataset selected. \ 1089 Please select a 2D dataset.") 1090 msg.setStandardButtons(QtWidgets.QMessageBox.Cancel) 1091 msg.exec_() 1092 return 1065 if data is None or not isinstance(data, Data2D): 1066 index = self.current_view.selectedIndexes()[0] 1067 proxy = self.current_view.model() 1068 model = proxy.sourceModel() 1069 model_item = model.itemFromIndex(proxy.mapToSource(index)) 1070 1071 data = GuiUtils.dataFromItem(model_item) 1093 1072 1094 1073 mask_editor = MaskEditor(self, data) -
src/sas/qtgui/MainWindow/GuiManager.py
r339e22b rf84d793 422 422 self._workspace.actionExcel.triggered.connect(self.actionExcel) 423 423 self._workspace.actionLatex.triggered.connect(self.actionLatex) 424 424 425 # View 425 426 self._workspace.actionShow_Grid_Window.triggered.connect(self.actionShow_Grid_Window) … … 451 452 self._workspace.actionManage_Custom_Models.triggered.connect(self.actionManage_Custom_Models) 452 453 self._workspace.actionAddMult_Models.triggered.connect(self.actionAddMult_Models) 453 self._workspace.actionEditMask.triggered.connect(self.actionEditMask)454 455 454 # Window 456 455 self._workspace.actionCascade.triggered.connect(self.actionCascade) … … 782 781 self.add_mult_editor.show() 783 782 784 def actionEditMask(self):785 786 self.communicate.extMaskEditorSignal.emit()787 788 783 #============ ANALYSIS ================= 789 784 def actionFitting(self): -
src/sas/qtgui/MainWindow/UI/MainWindowUI.ui
r339e22b rdda8f16 113 113 <addaction name="actionManage_Custom_Models"/> 114 114 <addaction name="actionAddMult_Models"/> 115 <addaction name="separator"/>116 <addaction name="EditMask"/>117 115 </widget> 118 116 <widget class="QMenu" name="menuWindow"> … … 415 413 </property> 416 414 </action> 417 <action name="EditMask">418 <property name="text">419 <string>Edit Mask</string>420 </property>421 </action>422 415 <action name="actionCascade"> 423 416 <property name="text"> -
src/sas/qtgui/Perspectives/Fitting/FittingUtilities.py
r70f4458 rb764ae5 8 8 from sas.qtgui.Plotting.PlotterData import Data1D 9 9 from sas.qtgui.Plotting.PlotterData import Data2D 10 11 from sas.qtgui.Perspectives.Fitting.AssociatedComboBox import AssociatedComboBox12 10 13 11 model_header_captions = ['Parameter', 'Value', 'Min', 'Max', 'Units'] … … 63 61 return (param_name, param_length) 64 62 65 def createFixedChoiceComboBox(param, item_row): 66 """ 67 Determines whether param is a fixed-choice parameter, modifies items in item_row appropriately and returns a combo 68 box containing the fixed choices. Returns None if param is not fixed-choice. 69 70 item_row is a list of QStandardItem objects for insertion into the parameter table. 71 """ 72 73 # Determine whether this is a fixed-choice parameter. There are lots of conditionals, simply because the 74 # implementation is not yet concrete; there are several possible indicators that the parameter is fixed-choice. 75 # TODO: (when the sasmodels implementation is concrete, clean this up) 76 choices = None 77 if isinstance(param.choices, (list, tuple)) and len(param.choices) > 0: 78 # The choices property is concrete in sasmodels, probably will use this 79 choices = param.choices 80 elif isinstance(param.units, (list, tuple)): 81 choices = [str(x) for x in param.units] 82 83 cbox = None 84 if choices is not None: 85 # Use combo box for input, if it is fixed-choice 86 cbox = AssociatedComboBox(item_row[1], idx_as_value=True) 87 cbox.addItems(choices) 88 item_row[2].setEditable(False) 89 item_row[3].setEditable(False) 90 91 return cbox 92 93 def addParametersToModel(parameters, kernel_module, is2D, model=None, view=None): 94 """ 95 Update local ModelModel with sasmodel parameters. 96 Actually appends to model, if model and view params are not None. 97 Always returns list of lists of QStandardItems. 63 def addParametersToModel(parameters, kernel_module, is2D): 64 """ 65 Update local ModelModel with sasmodel parameters 98 66 """ 99 67 multishell_parameters = getIterParams(parameters) … … 104 72 else: 105 73 params = parameters.iq_parameters 106 107 rows = [] 74 item = [] 108 75 for param in params: 109 76 # don't include shell parameters 110 77 if param.name == multishell_param_name: 111 78 continue 112 113 79 # Modify parameter name from <param>[n] to <param>1 114 80 item_name = param.name 115 81 if param in multishell_parameters: 116 82 continue 83 # item_name = replaceShellName(param.name, 1) 117 84 118 85 item1 = QtGui.QStandardItem(item_name) 119 86 item1.setCheckable(True) 120 87 item1.setEditable(False) 121 88 # item_err = QtGui.QStandardItem() 122 89 # check for polydisp params 123 90 if param.polydisperse: … … 126 93 item1_1 = QtGui.QStandardItem("Distribution") 127 94 item1_1.setEditable(False) 128 129 95 # Find param in volume_params 130 96 for p in parameters.form_volume_parameters: … … 133 99 width = kernel_module.getParam(p.name+'.width') 134 100 ptype = kernel_module.getParam(p.name+'.type') 101 135 102 item1_2 = QtGui.QStandardItem(str(width)) 136 103 item1_2.setEditable(False) … … 143 110 poly_item.appendRow([item1_1, item1_2, item1_3, item1_4, item1_5]) 144 111 break 145 146 112 # Add the polydisp item as a child 147 113 item1.appendRow([poly_item]) 148 149 114 # Param values 150 115 item2 = QtGui.QStandardItem(str(param.default)) 116 # TODO: the error column. 117 # Either add a proxy model or a custom view delegate 118 #item_err = QtGui.QStandardItem() 151 119 item3 = QtGui.QStandardItem(str(param.limits[0])) 152 120 item4 = QtGui.QStandardItem(str(param.limits[1])) 153 item5 = QtGui.QStandardItem( str(param.units))121 item5 = QtGui.QStandardItem(param.units) 154 122 item5.setEditable(False) 155 156 # Check if fixed-choice (returns combobox, if so, also makes some items uneditable) 157 row = [item1, item2, item3, item4, item5] 158 cbox = createFixedChoiceComboBox(param, row) 159 160 # Append to the model and use the combobox, if required 161 if None not in (model, view): 162 model.appendRow(row) 163 if cbox: 164 view.setIndexWidget(item2.index(), cbox) 165 rows.append(row) 166 167 return rows 168 169 def addSimpleParametersToModel(parameters, is2D, parameters_original=None, model=None, view=None): 170 """ 171 Update local ModelModel with sasmodel parameters (non-dispersed, non-magnetic) 172 Actually appends to model, if model and view params are not None. 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 are 176 the display names; see below) 123 item.append([item1, item2, item3, item4, item5]) 124 return item 125 126 def addSimpleParametersToModel(parameters, is2D): 127 """ 128 Update local ModelModel with sasmodel parameters 177 129 """ 178 130 if is2D: … … 180 132 else: 181 133 params = parameters.iq_parameters 182 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_parameters 191 else: 192 # no difference in names anyway 193 params_orig = params 194 195 rows = [] 196 for param, param_orig in zip(params, params_orig): 134 item = [] 135 for param in params: 197 136 # Create the top level, checkable item 198 item_name = param _orig.name137 item_name = param.name 199 138 item1 = QtGui.QStandardItem(item_name) 200 item1.setData(param.name, QtCore.Qt.UserRole)201 139 item1.setCheckable(True) 202 140 item1.setEditable(False) 203 204 141 # Param values 205 142 # TODO: add delegate for validation of cells 206 143 item2 = QtGui.QStandardItem(str(param.default)) 207 item3 = QtGui.QStandardItem(str(param.limits[0])) 208 item4 = QtGui.QStandardItem(str(param.limits[1])) 209 item5 = QtGui.QStandardItem(str(param.units)) 210 item5.setEditable(False) 211 212 # Check if fixed-choice (returns combobox, if so, also makes some items uneditable) 213 row = [item1, item2, item3, item4, item5] 214 cbox = createFixedChoiceComboBox(param, row) 215 216 # Append to the model and use the combobox, if required 217 if None not in (model, view): 218 model.appendRow(row) 219 if cbox: 220 view.setIndexWidget(item2.index(), cbox) 221 rows.append(row) 222 223 return rows 144 item4 = QtGui.QStandardItem(str(param.limits[0])) 145 item5 = QtGui.QStandardItem(str(param.limits[1])) 146 item6 = QtGui.QStandardItem(param.units) 147 item6.setEditable(False) 148 item.append([item1, item2, item4, item5, item6]) 149 return item 224 150 225 151 def markParameterDisabled(model, row): … … 256 182 model.appendRow(item_list) 257 183 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 184 def addHeadersToModel(model): 275 185 """ … … 317 227 model.header_tooltips = copy.copy(poly_header_error_tooltips) 318 228 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. 229 def addShellsToModel(parameters, model, index): 230 """ 231 Find out multishell parameters and update the model with the requested number of them 325 232 """ 326 233 multishell_parameters = getIterParams(parameters) 327 234 328 rows = []329 235 for i in range(index): 330 236 for par in multishell_parameters: … … 344 250 item1_3 = QtGui.QStandardItem(str(p.limits[0])) 345 251 item1_4 = QtGui.QStandardItem(str(p.limits[1])) 346 item1_5 = QtGui.QStandardItem( str(p.units))252 item1_5 = QtGui.QStandardItem(p.units) 347 253 poly_item.appendRow([item1_1, item1_2, item1_3, item1_4, item1_5]) 348 254 break … … 352 258 item3 = QtGui.QStandardItem(str(par.limits[0])) 353 259 item4 = QtGui.QStandardItem(str(par.limits[1])) 354 item5 = QtGui.QStandardItem(str(par.units)) 355 item5.setEditable(False) 356 357 # Check if fixed-choice (returns combobox, if so, also makes some items uneditable) 358 row = [item1, item2, item3, item4, item5] 359 cbox = createFixedChoiceComboBox(par, row) 360 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 367 368 # Apply combobox if required 369 if None not in (view, cbox): 370 view.setIndexWidget(item2.index(), cbox) 371 372 rows.append(row) 373 374 return rows 260 item5 = QtGui.QStandardItem(par.units) 261 model.appendRow([item1, item2, item3, item4, item5]) 375 262 376 263 def calculateChi2(reference_data, current_data): -
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
r339e22b r5a2bb75 48 48 from sas.qtgui.Perspectives.Fitting.ReportPageLogic import ReportPageLogic 49 49 50 50 51 TAB_MAGNETISM = 4 51 52 TAB_POLY = 3 … … 187 188 188 189 # Overwrite data type descriptor 189 190 190 self.is2D = True if isinstance(self.logic.data, Data2D) else False 191 191 … … 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 … … 1507 1481 # update charts 1508 1482 self.onPlot() 1509 #self.recalculatePlotData()1510 1511 1483 1512 1484 # Read only value - we can get away by just printing it here … … 1523 1495 # Data going in 1524 1496 data = self.logic.data 1525 model = copy.deepcopy(self.kernel_module)1497 model = self.kernel_module 1526 1498 qmin = self.q_range_min 1527 1499 qmax = self.q_range_max 1528 # add polydisperse/magnet parameters if asked1529 self.updateKernelModelWithExtraParams(model)1530 1500 1531 1501 params_to_fit = self.main_params_to_fit … … 1591 1561 # internal so can use closure for param_dict 1592 1562 param_name = str(self._model_model.item(row, 0).text()) 1593 if not self.isCheckable(row) orparam_name not in list(param_dict.keys()):1563 if param_name not in list(param_dict.keys()): 1594 1564 return 1595 1565 # modify the param value 1596 1566 param_repr = GuiUtils.formatNumber(param_dict[param_name][0], high=True) 1597 1567 self._model_model.item(row, 1).setText(param_repr) 1598 self.kernel_module.setParam(param_name, param_dict[param_name][0])1599 1568 if self.has_error_column: 1600 1569 error_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) … … 1604 1573 # Utility function for updateof polydispersity part of the main model 1605 1574 param_name = str(self._model_model.item(row, 0).text())+'.width' 1606 if not self.isCheckable(row) orparam_name not in list(param_dict.keys()):1575 if param_name not in list(param_dict.keys()): 1607 1576 return 1608 1577 # modify the param value … … 1638 1607 poly_item.insertColumn(2, [QtGui.QStandardItem("")]) 1639 1608 1609 # block signals temporarily, so we don't end up 1610 # updating charts with every single model change on the end of fitting 1611 self._model_model.blockSignals(True) 1612 1640 1613 if not self.has_error_column: 1641 1614 # create top-level error column … … 1644 1617 self.iterateOverModel(createErrorColumn) 1645 1618 1619 # we need to enable signals for this, otherwise the final column mysteriously disappears (don't ask, I don't 1620 # know) 1621 self._model_model.blockSignals(False) 1646 1622 self._model_model.insertColumn(2, error_column) 1623 self._model_model.blockSignals(True) 1647 1624 1648 1625 FittingUtilities.addErrorHeadersToModel(self._model_model) … … 1653 1630 self.has_error_column = True 1654 1631 1655 # block signals temporarily, so we don't end up1656 # updating charts with every single model change on the end of fitting1657 self._model_model.itemChanged.disconnect()1658 1632 self.iterateOverModel(updateFittedValues) 1659 1633 self.iterateOverModel(updatePolyValues) 1660 self._model_model.itemChanged.connect(self.onMainParamsChange) 1634 1635 self._model_model.blockSignals(False) 1661 1636 1662 1637 # Adjust the table cells width. … … 1693 1668 param_repr = GuiUtils.formatNumber(param_dict[param_name][0], high=True) 1694 1669 self._poly_model.item(row_i, 1).setText(param_repr) 1695 self.kernel_module.setParam(param_name, param_dict[param_name][0])1696 1670 if self.has_poly_error_column: 1697 1671 error_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) 1698 1672 self._poly_model.item(row_i, 2).setText(error_repr) 1673 1699 1674 1700 1675 def createErrorColumn(row_i): … … 1717 1692 # block signals temporarily, so we don't end up 1718 1693 # updating charts with every single model change on the end of fitting 1719 self._poly_model. itemChanged.disconnect()1694 self._poly_model.blockSignals(True) 1720 1695 self.iterateOverPolyModel(updateFittedValues) 1721 self._poly_model. itemChanged.connect(self.onPolyModelChange)1696 self._poly_model.blockSignals(False) 1722 1697 1723 1698 if self.has_poly_error_column: … … 1729 1704 1730 1705 # switch off reponse to model change 1706 self._poly_model.blockSignals(True) 1731 1707 self._poly_model.insertColumn(2, error_column) 1708 self._poly_model.blockSignals(False) 1732 1709 FittingUtilities.addErrorPolyHeadersToModel(self._poly_model) 1733 1710 … … 1762 1739 param_repr = GuiUtils.formatNumber(param_dict[param_name][0], high=True) 1763 1740 self._magnet_model.item(row, 1).setText(param_repr) 1764 self.kernel_module.setParam(param_name, param_dict[param_name][0])1765 1741 if self.has_magnet_error_column: 1766 1742 error_repr = GuiUtils.formatNumber(param_dict[param_name][1], high=True) … … 1782 1758 # block signals temporarily, so we don't end up 1783 1759 # updating charts with every single model change on the end of fitting 1784 self._magnet_model. itemChanged.disconnect()1760 self._magnet_model.blockSignals(True) 1785 1761 self.iterateOverMagnetModel(updateFittedValues) 1786 self._magnet_model. itemChanged.connect(self.onMagnetModelChange)1762 self._magnet_model.blockSignals(False) 1787 1763 1788 1764 if self.has_magnet_error_column: … … 1794 1770 1795 1771 # switch off reponse to model change 1772 self._magnet_model.blockSignals(True) 1796 1773 self._magnet_model.insertColumn(2, error_column) 1774 self._magnet_model.blockSignals(False) 1797 1775 FittingUtilities.addErrorHeadersToModel(self._magnet_model) 1798 1776 … … 1806 1784 self.cmdPlot.setText("Show Plot") 1807 1785 # Force data recalculation so existing charts are updated 1786 self.recalculatePlotData() 1808 1787 self.showPlot() 1809 self.recalculatePlotData()1810 1788 1811 1789 def onSmearingOptionsUpdate(self): … … 1972 1950 # Crete/overwrite model items 1973 1951 self._model_model.clear() 1974 self._poly_model.clear() 1975 self._magnet_model.clear()1976 1977 if model_name is None:1978 if structure_factor not in (None, "None"): 1979 # S(Q) on its own, treat the same as a form factor1980 self.kernel_module = None1981 self.fromStructureFactorToQModel(structure_factor)1982 else:1983 # No models selected1984 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) 1985 1963 else: 1986 self.fromModelToQModel(model_name)1987 self.addExtraShells()1988 1989 1964 # Allow the SF combobox visibility for the given sasmodel 1990 1965 self.enableStructureFactorControl(structure_factor) 1991 1992 # Add S(Q)1993 1966 if self.cbStructureFactor.isEnabled(): 1994 1967 structure_factor = self.cbStructureFactor.currentText() 1995 1968 self.fromStructureFactorToQModel(structure_factor) 1996 1969 1997 # Add polydispersity to the model 1998 self.poly_params = {} 1999 self.setPolyModel() 2000 # Add magnetic parameters to the model 2001 self.magnet_params = {} 2002 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() 2003 1979 2004 1980 # Adjust the table cells width … … 2073 2049 self.shell_names = self.shellNamesList() 2074 2050 2075 # Add heading row2076 FittingUtilities.addHeadingRowToModel(self._model_model, model_name)2077 2078 2051 # Update the QModel 2079 FittingUtilities.addParametersToModel(2080 self.model_parameters, 2081 self.kernel_module,2082 self.is2D,2083 self._model_model,2084 self.lstParams)2052 new_rows = FittingUtilities.addParametersToModel(self.model_parameters, self.kernel_module, self.is2D) 2053 2054 for row in new_rows: 2055 self._model_model.appendRow(row) 2056 # Update the counter used for multishell display 2057 self._last_model_row = self._model_model.rowCount() 2085 2058 2086 2059 def fromStructureFactorToQModel(self, structure_factor): … … 2090 2063 if structure_factor is None or structure_factor=="None": 2091 2064 return 2092 2093 if self.kernel_module is None: 2094 # Structure factor is the only selected model; build it and show all its params 2095 self.kernel_module = self.models[structure_factor]() 2096 s_params = self.kernel_module._model_info.parameters 2097 s_params_orig = s_params 2098 2099 else: 2100 s_kernel = self.models[structure_factor]() 2101 p_kernel = self.kernel_module 2102 2103 p_pars_len = len(p_kernel._model_info.parameters.kernel_parameters) 2104 s_pars_len = len(s_kernel._model_info.parameters.kernel_parameters) 2105 2106 self.kernel_module = MultiplicationModel(p_kernel, s_kernel) 2107 all_params = self.kernel_module._model_info.parameters.kernel_parameters 2108 all_param_names = [param.name for param in all_params] 2109 2110 # S(Q) params from the product model are not necessarily the same as those from the S(Q) model; any 2111 # conflicting names with P(Q) params will cause a rename 2112 2113 if "radius_effective_mode" in all_param_names: 2114 # Show all parameters 2115 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len]) 2116 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters) 2117 else: 2118 # Ensure radius_effective is not displayed 2119 s_params_orig = modelinfo.ParameterTable(s_kernel._model_info.parameters.kernel_parameters[1:]) 2120 if "radius_effective" in all_param_names: 2121 s_params = modelinfo.ParameterTable(all_params[p_pars_len+1:p_pars_len+s_pars_len]) 2122 else: 2123 s_params = modelinfo.ParameterTable(all_params[p_pars_len:p_pars_len+s_pars_len-1]) 2124 2125 # Add heading row 2126 FittingUtilities.addHeadingRowToModel(self._model_model, structure_factor) 2127 2128 # Get new rows for QModel 2129 # Any renamed parameters are stored as data in the relevant item, for later handling 2130 FittingUtilities.addSimpleParametersToModel( 2131 s_params, 2132 self.is2D, 2133 s_params_orig, 2134 self._model_model, 2135 self.lstParams) 2065 structure_module = generate.load_kernel_module(structure_factor) 2066 structure_parameters = modelinfo.make_parameter_table(getattr(structure_module, 'parameters', [])) 2067 2068 structure_kernel = self.models[structure_factor]() 2069 form_kernel = self.kernel_module 2070 2071 self.kernel_module = MultiplicationModel(form_kernel, structure_kernel) 2072 2073 new_rows = FittingUtilities.addSimpleParametersToModel(structure_parameters, self.is2D) 2074 for row in new_rows: 2075 self._model_model.appendRow(row) 2076 # disable fitting of parameters not listed in self.kernel_module (probably radius_effective) 2077 if row[0].text() not in self.kernel_module.params.keys(): 2078 row_num = self._model_model.rowCount() - 1 2079 FittingUtilities.markParameterDisabled(self._model_model, row_num) 2080 2081 # Update the counter used for multishell display 2082 self._last_model_row = self._model_model.rowCount() 2136 2083 2137 2084 def haveParamsToFit(self): … … 2159 2106 model_row = item.row() 2160 2107 name_index = self._model_model.index(model_row, 0) 2161 name_item = self._model_model.itemFromIndex(name_index)2162 2108 2163 2109 # Extract changed value. … … 2168 2114 return 2169 2115 2170 # if the item has user data, this is the actual parameter name (e.g. to handle duplicate names) 2171 if name_item.data(QtCore.Qt.UserRole): 2172 parameter_name = str(name_item.data(QtCore.Qt.UserRole)) 2173 else: 2174 parameter_name = str(self._model_model.data(name_index)) 2116 parameter_name = str(self._model_model.data(name_index)) # sld, background etc. 2175 2117 2176 2118 # Update the parameter value - note: this supports +/-inf as well … … 2295 2237 return self.completed1D if isinstance(self.data, Data1D) else self.completed2D 2296 2238 2297 def updateKernelModelWithExtraParams(self, model=None):2298 """2299 Updates kernel model 'model' with extra parameters from2300 the polydisp and magnetism tab, if the tabs are enabled2301 """2302 if model is None: return2303 if not hasattr(model, 'setParam'): return2304 2305 # add polydisperse parameters if asked2306 if self.chkPolydispersity.isChecked():2307 for key, value in self.poly_params.items():2308 model.setParam(key, value)2309 # add magnetic params if asked2310 if self.chkMagnetism.isChecked():2311 for key, value in self.magnet_params.items():2312 model.setParam(key, value)2313 2314 2239 def calculateQGridForModelExt(self, data=None, model=None, completefn=None, use_threads=True): 2315 2240 """ … … 2319 2244 data = self.data 2320 2245 if model is None: 2321 model = copy.deepcopy(self.kernel_module) 2322 self.updateKernelModelWithExtraParams(model) 2323 2246 model = self.kernel_module 2324 2247 if completefn is None: 2325 2248 completefn = self.methodCompleteForData() … … 2406 2329 new_plots.append(sq_data) 2407 2330 2408 for plot in new_plots:2409 self.communicate.plotUpdateSignal.emit([plot])2410 2411 def complete2D(self, return_data):2412 """2413 Plot the current 2D data2414 """2415 fitted_data = self.logic.new2DPlot(return_data)2416 residuals = self.calculateResiduals(fitted_data)2417 self.model_data = fitted_data2418 new_plots = [fitted_data]2419 if residuals is not None:2420 new_plots.append(residuals)2421 2422 2331 # Update/generate plots 2423 2332 for plot in new_plots: 2424 2333 self.communicate.plotUpdateSignal.emit([plot]) 2334 2335 def complete2D(self, return_data): 2336 """ 2337 Plot the current 2D data 2338 """ 2339 fitted_data = self.logic.new2DPlot(return_data) 2340 self.calculateResiduals(fitted_data) 2341 self.model_data = fitted_data 2425 2342 2426 2343 def calculateResiduals(self, fitted_data): … … 2553 2470 _, min, max = self.kernel_module.details[param_name] 2554 2471 2555 # Update local param dict2556 self.poly_params[param_name + '.width'] = width2557 self.poly_params[param_name + '.npts'] = npts2558 self.poly_params[param_name + '.nsigmas'] = nsigs2559 2560 2472 # Construct a row with polydisp. related variable. 2561 2473 # This will get added to the polydisp. model … … 2605 2517 def updateFunctionCaption(row): 2606 2518 # Utility function for update of polydispersity function name in the main model 2607 if not self.isCheckable(row):2608 return2609 self._model_model.blockSignals(True)2610 2519 param_name = str(self._model_model.item(row, 0).text()) 2611 self._model_model.blockSignals(False)2612 2520 if param_name != param.name: 2613 2521 return 2614 2522 # Modify the param value 2615 self._model_model.blockSignals(True)2616 2523 if self.has_error_column: 2617 2524 # err column changes the indexing … … 2619 2526 else: 2620 2527 self._model_model.item(row, 0).child(0).child(0,4).setText(combo_string) 2621 self._model_model.blockSignals(False)2622 2528 2623 2529 if combo_string == 'array': … … 2738 2644 param.units] 2739 2645 2740 self.magnet_params[param.name] = param.default2741 2742 2646 FittingUtilities.addCheckedListToModel(model, checked_list) 2743 2647 … … 2779 2683 2780 2684 self.lstParams.setIndexWidget(shell_index, func) 2781 self._ n_shells_row = shell_row - 12685 self._last_model_row = self._model_model.rowCount() 2782 2686 2783 2687 # Set the index to the state-kept value … … 2790 2694 """ 2791 2695 # Find row location of the combobox 2792 first_row = self._n_shells_row + 12793 remove_rows = self._ num_shell_params2696 last_row = self._last_model_row 2697 remove_rows = self._model_model.rowCount() - last_row 2794 2698 2795 2699 if remove_rows > 1: 2796 self._model_model.removeRows(first_row, remove_rows) 2797 2798 new_rows = FittingUtilities.addShellsToModel( 2799 self.model_parameters, 2800 self._model_model, 2801 index, 2802 first_row, 2803 self.lstParams) 2804 2805 self._num_shell_params = len(new_rows) 2700 self._model_model.removeRows(last_row, remove_rows) 2701 2702 FittingUtilities.addShellsToModel(self.model_parameters, self._model_model, index) 2806 2703 self.current_shell_displayed = index 2807 2704 … … 3316 3213 self._poly_model.blockSignals(False) 3317 3214 3318 3319 -
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): -
src/sas/qtgui/Plotting/Plotter.py
rc2f3ca2 rb764ae5 30 30 # Dictionary of {plot_id:Data1d} 31 31 self.plot_dict = {} 32 # Dictionaty of {plot_id:line} 33 34 self.plot_lines = {} 32 35 33 # Window for text add 36 34 self.addText = AddText(self) … … 184 182 self.plot_dict[self._data.id] = self.data 185 183 186 self.plot_lines[self._data.id] = line187 188 184 # Now add the legend with some customizations. 189 185 … … 200 196 201 197 # refresh canvas 202 self.canvas.draw ()198 self.canvas.draw_idle() 203 199 # This is an important processEvent. 204 200 # This allows charts to be properly updated in order … … 420 416 This effectlvely refreshes the chart with changes to one of its plots 421 417 """ 422 import logging423 418 self.removePlot(id) 424 419 self.plot(data=new_plot) … … 475 470 """ 476 471 selected_plot = self.plot_dict[id] 477 selected_line = self.plot_lines[id] 472 478 473 # Old style color - single integer for enum color 479 474 # New style color - #hhhhhh -
src/sas/qtgui/Utilities/GuiUtils.py
r339e22b r0eff615 265 265 # Mask Editor requested 266 266 maskEditorSignal = QtCore.pyqtSignal(Data2D) 267 268 #second Mask Editor for external269 extMaskEditorSignal = QtCore.pyqtSignal()270 267 271 268 # Fitting parameter copy to clipboard
Note: See TracChangeset
for help on using the changeset viewer.