Changes in / [8289ae3:304e42f] in sasview
- Files:
-
- 17 deleted
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
setup.py
- Property mode changed from 100755 to 100644
r3b3b40b r14ec91c5 351 351 "src", "sas", "qtgui", "Utilities") 352 352 packages.append("sas.qtgui.Utilities") 353 package_dir["sas.qtgui.UtilitiesUI"] = os.path.join(354 "src", "sas", "qtgui", "Utilities","UI")355 packages.append("sas.qtgui.Utilities.UI")356 353 357 354 package_dir["sas.qtgui.Calculators"] = os.path.join( -
src/sas/qtgui/GUITests.py
r3b3b40b rda9a0722 44 44 from Utilities.UnitTesting import GuiUtilsTest 45 45 from Utilities.UnitTesting import SasviewLoggerTest 46 from Utilities.UnitTesting import GridPanelTest47 from Utilities.UnitTesting import ModelEditorTest48 from Utilities.UnitTesting import PluginDefinitionTest49 from Utilities.UnitTesting import TabbedModelEditorTest50 46 51 47 # Unit Testing … … 103 99 unittest.makeSuite(GuiUtilsTest.DoubleValidatorTest, 'test'), 104 100 unittest.makeSuite(GuiUtilsTest.HashableStandardItemTest, 'test'), 105 unittest.makeSuite(GridPanelTest.BatchOutputPanelTest, 'test'),106 unittest.makeSuite(ModelEditorTest.ModelEditorTest, 'test'),107 unittest.makeSuite(PluginDefinitionTest.PluginDefinitionTest, 'test'),108 unittest.makeSuite(TabbedModelEditorTest.TabbedModelEditorTest,'test'),109 101 110 102 # Calculators -
src/sas/qtgui/MainWindow/DataExplorer.py
r8ac3551 re90988c 473 473 Notify the gui manager about the new perspective chosen. 474 474 """ 475 self.communicator.perspectiveChangedSignal.emit(self.cbFitting. itemText(index))475 self.communicator.perspectiveChangedSignal.emit(self.cbFitting.currentText()) 476 476 self.chkBatch.setEnabled(self.parent.perspective().allowBatch()) 477 477 478 def display File(self, filename=None, is_data=True):478 def displayData(self, data_list): 479 479 """ 480 480 Forces display of charts for the given filename 481 481 """ 482 model = self.model if is_data else self.theory_model 482 plot_to_show = data_list[0] 483 484 # passed plot is used ONLY to figure out its title, 485 # so all the charts related by it can be pulled from 486 # the data explorer indices. 487 filename = plot_to_show.filename 488 model = self.model if plot_to_show.is_data else self.theory_model 489 483 490 # Now query the model item for available plots 484 491 plots = GuiUtils.plotsFromFilename(filename, model) … … 499 506 if new_plots: 500 507 self.plotData(new_plots) 501 502 def displayData(self, data_list):503 """504 Forces display of charts for the given data set505 """506 plot_to_show = data_list[0]507 # passed plot is used ONLY to figure out its title,508 # so all the charts related by it can be pulled from509 # the data explorer indices.510 filename = plot_to_show.filename511 self.displayFile(filename=filename, is_data=plot_to_show.is_data)512 508 513 509 def addDataPlot2D(self, plot_set, item): … … 1031 1027 pass 1032 1028 1033 def onAnalysisUpdate(self, new_perspective=""):1034 """1035 Update the perspective combo index based on passed string1036 """1037 assert new_perspective in Perspectives.PERSPECTIVES.keys()1038 self.cbFitting.blockSignals(True)1039 self.cbFitting.setCurrentIndex(self.cbFitting.findText(new_perspective))1040 self.cbFitting.blockSignals(False)1041 pass1042 1043 1029 def loadComplete(self, output): 1044 1030 """ -
src/sas/qtgui/MainWindow/GuiManager.py
r8ac3551 r14ec91c5 19 19 20 20 import sas.qtgui.Utilities.ObjectLibrary as ObjectLibrary 21 from sas.qtgui.Utilities.TabbedModelEditor import TabbedModelEditor22 from sas.qtgui.Utilities.PluginManager import PluginManager23 21 from sas.qtgui.MainWindow.UI.AcknowledgementsUI import Ui_Acknowledgements 24 22 from sas.qtgui.MainWindow.AboutBox import AboutBox … … 49 47 Main SasView window functionality 50 48 """ 49 51 50 def __init__(self, parent=None): 52 51 """ … … 183 182 Respond to change of the perspective signal 184 183 """ 184 185 # Save users from themselves... 186 #if isinstance(self._current_perspective, Perspectives.PERSPECTIVES[str(perspective_name)]): 187 self.setupPerspectiveMenubarOptions(self._current_perspective) 188 # return 189 185 190 # Close the previous perspective 186 191 self.clearPerspectiveMenubarOptions(self._current_perspective) … … 192 197 # Default perspective 193 198 self._current_perspective = Perspectives.PERSPECTIVES[str(perspective_name)](parent=self) 194 195 self.setupPerspectiveMenubarOptions(self._current_perspective)196 199 197 200 subwindow = self._workspace.workspace.addSubWindow(self._current_perspective) … … 355 358 self.communicate.updateTheoryFromPerspectiveSignal.connect(self.updateTheoryFromPerspective) 356 359 self.communicate.plotRequestedSignal.connect(self.showPlot) 357 self.communicate.plotFromFilenameSignal.connect(self.showPlotFromFilename)358 360 self.communicate.updateModelFromDataOperationPanelSignal.connect(self.updateModelFromDataOperationPanel) 359 361 … … 404 406 self._workspace.actionFit_Results.triggered.connect(self.actionFit_Results) 405 407 self._workspace.actionChain_Fitting.triggered.connect(self.actionChain_Fitting) 406 self._workspace.actionAdd_Custom_Model.triggered.connect(self.actionAdd_Custom_Model)407 408 self._workspace.actionEdit_Custom_Model.triggered.connect(self.actionEdit_Custom_Model) 408 self._workspace.actionManage_Custom_Models.triggered.connect(self.actionManage_Custom_Models)409 409 # Window 410 410 self._workspace.actionCascade.triggered.connect(self.actionCascade) … … 417 417 self._workspace.actionInversion.triggered.connect(self.actionInversion) 418 418 self._workspace.actionInvariant.triggered.connect(self.actionInvariant) 419 self._workspace.actionCorfunc.triggered.connect(self.actionCorfunc)420 419 # Help 421 420 self._workspace.actionDocumentation.triggered.connect(self.actionDocumentation) … … 663 662 pass 664 663 665 def actionAdd_Custom_Model(self):666 """667 """668 self.model_editor = TabbedModelEditor(self)669 self.model_editor.show()670 671 664 def actionEdit_Custom_Model(self): 672 665 """ 673 666 """ 674 self.model_editor = TabbedModelEditor(self, edit_only=True) 675 self.model_editor.show() 676 677 def actionManage_Custom_Models(self): 678 """ 679 """ 680 self.model_manager = PluginManager(self) 681 self.model_manager.show() 667 print("actionEdit_Custom_Model TRIGGERED") 668 pass 682 669 683 670 #============ ANALYSIS ================= … … 687 674 """ 688 675 self.perspectiveChanged("Fitting") 689 # Notify other widgets690 self.filesWidget.onAnalysisUpdate("Fitting")691 676 692 677 def actionInversion(self): … … 694 679 Change to the Inversion perspective 695 680 """ 681 # For now we'll just update the analysis menu status but when the inversion is implemented delete from here 682 self.checkAnalysisOption(self._workspace.actionInversion) 683 # to here and uncomment the following line 696 684 self.perspectiveChanged("Inversion") 697 self.filesWidget.onAnalysisUpdate("Inversion")698 685 699 686 def actionInvariant(self): … … 702 689 """ 703 690 self.perspectiveChanged("Invariant") 704 self.filesWidget.onAnalysisUpdate("Invariant")705 706 def actionCorfunc(self):707 """708 Change to the Corfunc perspective709 """710 self.perspectiveChanged("Corfunc")711 self.filesWidget.onAnalysisUpdate("Corfunc")712 691 713 692 #============ WINDOW ================= … … 800 779 self.filesWidget.model.appendRow(new_item) 801 780 self._data_manager.add_data(new_datalist_item) 802 803 def showPlotFromFilename(self, filename):804 """805 Pass the show plot request to the data explorer806 """807 if hasattr(self, "filesWidget"):808 self.filesWidget.displayFile(filename=filename, is_data=True)809 781 810 782 def showPlot(self, plot): … … 856 828 elif isinstance(perspective, Perspectives.PERSPECTIVES["Invariant"]): 857 829 self.checkAnalysisOption(self._workspace.actionInvariant) 858 elif isinstance(perspective, Perspectives.PERSPECTIVES["Inversion"]): 859 self.checkAnalysisOption(self._workspace.actionInversion) 860 elif isinstance(perspective, Perspectives.PERSPECTIVES["Corfunc"]): 861 self.checkAnalysisOption(self._workspace.actionCorfunc) 830 # elif isinstance(perspective, Perspectives.PERSPECTIVES["Inversion"]): 831 # self.checkAnalysisOption(self._workspace.actionInversion) -
src/sas/qtgui/MainWindow/MainWindow.py
r8ac3551 r8353d90 30 30 except Exception as ex: 31 31 import logging 32 logging.error("Application failed with: " + str(ex))32 logging.error("Application failed with: ", ex) 33 33 print("Application failed with: ", ex) 34 34 -
src/sas/qtgui/MainWindow/UI/MainWindowUI.ui
r8ac3551 r1543f0c 8 8 <y>0</y> 9 9 <width>915</width> 10 <height> 762</height>10 <height>527</height> 11 11 </rect> 12 12 </property> … … 25 25 <y>0</y> 26 26 <width>915</width> 27 <height>2 6</height>27 <height>21</height> 28 28 </rect> 29 29 </property> … … 108 108 <addaction name="actionChain_Fitting"/> 109 109 <addaction name="separator"/> 110 <addaction name="actionAdd_Custom_Model"/>111 110 <addaction name="actionEdit_Custom_Model"/> 112 <addaction name="actionManage_Custom_Models"/>113 111 </widget> 114 112 <widget class="QMenu" name="menuWindow"> … … 128 126 <string>Analysis</string> 129 127 </property> 130 <addaction name="actionCorfunc"/>131 128 <addaction name="actionFitting"/> 129 <addaction name="actionInversion"/> 132 130 <addaction name="actionInvariant"/> 133 <addaction name="actionInversion"/>134 131 </widget> 135 132 <widget class="QMenu" name="menuHelp"> … … 508 505 </property> 509 506 </action> 510 <action name="actionAdd_Custom_Model">511 <property name="text">512 <string>Add Custom Model</string>513 </property>514 </action>515 <action name="actionManage_Custom_Models">516 <property name="text">517 <string>Manage Custom Models</string>518 </property>519 </action>520 <action name="actionCorfunc">521 <property name="checkable">522 <bool>true</bool>523 </property>524 <property name="text">525 <string>Correlation Function</string>526 </property>527 </action>528 507 </widget> 529 508 <resources/> -
src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py
r8b480d27 re4c475b7 111 111 112 112 # Disconnect all local slots 113 #tab_object.disconnect()113 tab_object.disconnect() 114 114 115 115 # Reconnect tab signals to local slots … … 171 171 # No such tab! 172 172 return 173 sim_fitter_list, fitter_id = \ 174 tab_object.prepareFitters(fitter=sim_fitter_list[0], fit_id=fitter_id) 173 sim_fitter_list, fitter_id = tab_object.prepareFitters(fitter=sim_fitter_list[0], fit_id=fitter_id) 175 174 page_ids.append([tab_object.page_id]) 176 175 except ValueError: … … 179 178 "Not all tabs chosen for fitting have parameters selected for fitting." 180 179 QtWidgets.QMessageBox.warning(self, 181 'Warning',182 no_params_msg,183 QtWidgets.QMessageBox.Ok)180 'Warning', 181 no_params_msg, 182 QtWidgets.QMessageBox.Ok) 184 183 185 184 return … … 675 674 676 675 constraint.func = constraint_text 677 # param1 is the parameter we're constraining678 676 constraint.param = param1 679 680 677 # Find the right tab 681 678 constrained_tab = self.getObjectByName(model1) -
src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py
r3b3b40b r14ec91c5 8 8 from bumps import fitters 9 9 10 import sas.qtgui.Utilities.LocalConfig as LocalConfig11 10 import sas.qtgui.Utilities.ObjectLibrary as ObjectLibrary 12 11 … … 117 116 tab = FittingWidget(parent=self.parent, data=data, tab_id=self.maxIndex+1) 118 117 tab.is_batch_fitting = is_batch 119 120 118 # Add this tab to the object library so it can be retrieved by scripting/jupyter 121 119 tab_name = self.getTabName(is_batch=is_batch) … … 125 123 self.updateFitDict(data, tab_name) 126 124 self.maxIndex += 1 127 icon = QtGui.QIcon() 128 if is_batch: 129 icon.addPixmap(QtGui.QPixmap("src/sas/qtgui/images/icons/layers.svg")) 130 self.addTab(tab, icon, tab_name) 131 # Show the new tab 132 self.setCurrentIndex(self.maxIndex-1) 133 # Notify listeners 125 self.addTab(tab, tab_name) 134 126 self.tabsModifiedSignal.emit() 135 127 … … 148 140 ObjectLibrary.addObject(tab_name, tab) 149 141 self.tabs.append(tab) 150 icon = QtGui.QIcon() 151 icon.addPixmap(QtGui.QPixmap("src/sas/qtgui/images/icons/link.svg")) 152 self.addTab(tab, icon, tab_name) 153 154 # This will be the last tab, so set the index accordingly 155 self.setCurrentIndex(self.count()-1) 142 self.addTab(tab, tab_name) 156 143 157 144 def updateFitDict(self, item_key, tab_name): -
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
r8b480d27 re4c475b7 24 24 import sas.qtgui.Utilities.GuiUtils as GuiUtils 25 25 import sas.qtgui.Utilities.LocalConfig as LocalConfig 26 from sas.qtgui.Utilities.GridPanel import BatchOutputPanel27 26 from sas.qtgui.Utilities.CategoryInstaller import CategoryInstaller 28 27 from sas.qtgui.Plotting.PlotterData import Data1D … … 37 36 from sas.qtgui.Perspectives.Fitting.FittingLogic import FittingLogic 38 37 from sas.qtgui.Perspectives.Fitting import FittingUtilities 39 from sas.qtgui.Perspectives.Fitting import ModelUtilities40 38 from sas.qtgui.Perspectives.Fitting.SmearingWidget import SmearingWidget 41 39 from sas.qtgui.Perspectives.Fitting.OptionsWidget import OptionsWidget … … 52 50 CATEGORY_DEFAULT = "Choose category..." 53 51 CATEGORY_STRUCTURE = "Structure Factor" 54 CATEGORY_CUSTOM = "Plugin Models"55 52 STRUCTURE_DEFAULT = "None" 56 53 … … 86 83 constraintAddedSignal = QtCore.pyqtSignal(list) 87 84 newModelSignal = QtCore.pyqtSignal() 88 fittingFinishedSignal = QtCore.pyqtSignal(tuple)89 batchFittingFinishedSignal = QtCore.pyqtSignal(tuple)90 91 85 def __init__(self, parent=None, data=None, tab_id=1): 92 86 … … 217 211 self.page_stack = [] 218 212 self.all_data = [] 219 # custom plugin models220 # {model.name:model}221 self.custom_models = self.customModels()222 213 # Polydisp widget table default index for function combobox 223 214 self.orig_poly_index = 3 … … 424 415 self.onSelectModel() 425 416 426 @classmethod427 def customModels(cls):428 """ Reads in file names in the custom plugin directory """429 return ModelUtilities._find_models()430 431 417 def initializeControls(self): 432 418 """ … … 479 465 self._poly_model.itemChanged.connect(self.onPolyModelChange) 480 466 self._magnet_model.itemChanged.connect(self.onMagnetModelChange) 481 self.lstParams.selectionModel().selectionChanged.connect(self.onSelectionChanged)482 483 # Local signals484 self.batchFittingFinishedSignal.connect(self.batchFitComplete)485 self.fittingFinishedSignal.connect(self.fitComplete)486 467 487 468 # Signals from separate tabs asking for replot 488 469 self.options_widget.plot_signal.connect(self.onOptionsUpdate) 489 490 # Signals from other widgets491 self.communicate.customModelDirectoryChanged.connect(self.onCustomModelChange)492 470 493 471 def modelName(self): … … 598 576 # widget.params[0] is the parameter we're constraining 599 577 constraint.param = mc_widget.params[0] 600 # parametershould have the model name preamble578 # Function should have the model name preamble 601 579 model_name = self.kernel_module.name 602 # param_used is the parameter we're using in constraining function 603 param_used = mc_widget.params[1] 604 # Replace param_used with model_name.param_used 605 updated_param_used = model_name + "." + param_used 606 new_func = c_text.replace(param_used, updated_param_used) 607 constraint.func = new_func 580 constraint.func = model_name + "." + c_text 608 581 # Which row is the constrained parameter in? 609 582 row = self.getRowFromName(constraint.param) … … 704 677 Delete constraints from selected parameters. 705 678 """ 706 params = [s.data() for s in self.lstParams.selectionModel().selectedRows() 707 if self.isCheckable(s.row())] 708 for param in params: 709 self.deleteConstraintOnParameter(param=param) 679 self.deleteConstraintOnParameter(param=None) 710 680 711 681 def deleteConstraintOnParameter(self, param=None): … … 716 686 max_col = self.lstParams.itemDelegate().param_max 717 687 for row in range(self._model_model.rowCount()): 718 if not self.rowHasConstraint(row):719 continue720 688 # Get the Constraint object from of the model item 721 689 item = self._model_model.item(row, 1) 722 constraint = self.getConstraintForRow(row) 690 if not item.hasChildren(): 691 continue 692 constraint = item.child(0).data() 723 693 if constraint is None: 724 694 continue … … 846 816 return constraints 847 817 848 def getConstraintsForFitting(self):849 """850 Return a list of constraints in format ready for use in fiting851 """852 # Get constraints853 constraints = self.getComplexConstraintsForModel()854 # See if there are any constraints across models855 multi_constraints = [cons for cons in constraints if self.isConstraintMultimodel(cons[1])]856 857 if multi_constraints:858 # Let users choose what to do859 msg = "The current fit contains constraints relying on other fit pages.\n"860 msg += "Parameters with those constraints are:\n" +\861 '\n'.join([cons[0] for cons in multi_constraints])862 msg += "\n\nWould you like to remove these constraints or cancel fitting?"863 msgbox = QtWidgets.QMessageBox(self)864 msgbox.setIcon(QtWidgets.QMessageBox.Warning)865 msgbox.setText(msg)866 msgbox.setWindowTitle("Existing Constraints")867 # custom buttons868 button_remove = QtWidgets.QPushButton("Remove")869 msgbox.addButton(button_remove, QtWidgets.QMessageBox.YesRole)870 button_cancel = QtWidgets.QPushButton("Cancel")871 msgbox.addButton(button_cancel, QtWidgets.QMessageBox.RejectRole)872 retval = msgbox.exec_()873 if retval == QtWidgets.QMessageBox.RejectRole:874 # cancel fit875 raise ValueError("Fitting cancelled")876 else:877 # remove constraint878 for cons in multi_constraints:879 self.deleteConstraintOnParameter(param=cons[0])880 # re-read the constraints881 constraints = self.getComplexConstraintsForModel()882 883 return constraints884 885 818 def showModelDescription(self): 886 819 """ … … 941 874 self.respondToModelStructure(model=model, structure_factor=structure) 942 875 943 def onCustomModelChange(self):944 """945 Reload the custom model combobox946 """947 self.custom_models = self.customModels()948 self.readCustomCategoryInfo()949 # See if we need to update the combo in-place950 if self.cbCategory.currentText() != CATEGORY_CUSTOM: return951 952 current_text = self.cbModel.currentText()953 self.cbModel.blockSignals(True)954 self.cbModel.clear()955 self.cbModel.blockSignals(False)956 self.enableModelCombo()957 self.disableStructureCombo()958 # Retrieve the list of models959 model_list = self.master_category_dict[CATEGORY_CUSTOM]960 # Populate the models combobox961 self.cbModel.addItems(sorted([model for (model, _) in model_list]))962 new_index = self.cbModel.findText(current_text)963 if new_index != -1:964 self.cbModel.setCurrentIndex(self.cbModel.findText(current_text))965 966 def onSelectionChanged(self):967 """968 React to parameter selection969 """970 rows = self.lstParams.selectionModel().selectedRows()971 # Clean previous messages972 self.communicate.statusBarUpdateSignal.emit("")973 if len(rows) == 1:974 # Show constraint, if present975 row = rows[0].row()976 if self.rowHasConstraint(row):977 func = self.getConstraintForRow(row).func978 if func is not None:979 self.communicate.statusBarUpdateSignal.emit("Active constrain: "+func)980 981 876 def replaceConstraintName(self, old_name, new_name=""): 982 877 """ … … 991 886 new_func = func.replace(old_name, new_name) 992 887 self._model_model.item(row, 1).child(0).data().func = new_func 993 994 def isConstraintMultimodel(self, constraint):995 """996 Check if the constraint function text contains current model name997 """998 current_model_name = self.kernel_module.name999 if current_model_name in constraint:1000 return False1001 else:1002 return True1003 888 1004 889 def updateData(self): … … 1220 1105 except ValueError as ex: 1221 1106 # This should not happen! GUI explicitly forbids this situation 1222 self.communicate.statusBarUpdateSignal.emit( str(ex))1107 self.communicate.statusBarUpdateSignal.emit('Fitting attempt without parameters.') 1223 1108 return 1224 1109 1225 1110 # Create the fitting thread, based on the fitter 1226 completefn = self.batchFit tingCompleted if self.is_batch_fitting else self.fittingCompleted1111 completefn = self.batchFitComplete if self.is_batch_fitting else self.fitComplete 1227 1112 1228 1113 calc_fit = FitThread(handler=handler, … … 1261 1146 pass 1262 1147 1263 def batchFittingCompleted(self, result):1264 """1265 Send the finish message from calculate threads to main thread1266 """1267 self.batchFittingFinishedSignal.emit(result)1268 1269 1148 def batchFitComplete(self, result): 1270 1149 """ … … 1273 1152 #re-enable the Fit button 1274 1153 self.setFittingStopped() 1275 # Show the grid panel1276 self.grid_window = BatchOutputPanel(parent=self, output_data=result[0])1277 self.grid_window.show()1278 1279 def fittingCompleted(self, result):1280 """1281 Send the finish message from calculate threads to main thread1282 """1283 self.fittingFinishedSignal.emit(result)1284 1154 1285 1155 def fitComplete(self, result): … … 1292 1162 1293 1163 if result is None: 1294 msg = "Fitting failed ."1164 msg = "Fitting failed after: %s s.\n" % GuiUtils.formatNumber(elapsed) 1295 1165 self.communicate.statusBarUpdateSignal.emit(msg) 1296 1166 return … … 1358 1228 smearing, accuracy, smearing_min, smearing_max = self.smearing_widget.state() 1359 1229 1360 # Get the constraints.1361 1230 constraints = self.getComplexConstraintsForModel() 1362 if fitter is None:1363 # For single fits - check for inter-model constraints1364 constraints = self.getConstraintsForFitting()1365 1366 1231 smearer = None 1367 1232 handler = None … … 1377 1242 constraints=constraints) 1378 1243 except ValueError as ex: 1379 raise ValueError("Setting model parameters failed with: %s" % ex) 1244 logging.error("Setting model parameters failed with: %s" % ex) 1245 return 1380 1246 1381 1247 qmin, qmax, _ = self.logic.computeRangeFromData(data) … … 1543 1409 if not dict: 1544 1410 return 1545 if self._m agnet_model.rowCount() == 0:1411 if self._model_model.rowCount() == 0: 1546 1412 return 1547 1413 … … 1689 1555 self.models[model.name] = model 1690 1556 1691 self.readCustomCategoryInfo()1692 1693 def readCustomCategoryInfo(self):1694 """1695 Reads the custom model category1696 """1697 #Looking for plugins1698 self.plugins = list(self.custom_models.values())1699 plugin_list = []1700 for name, plug in self.custom_models.items():1701 self.models[name] = plug1702 plugin_list.append([name, True])1703 self.master_category_dict[CATEGORY_CUSTOM] = plugin_list1704 1705 1557 def regenerateModelDict(self): 1706 1558 """ … … 1810 1662 Setting model parameters into QStandardItemModel based on selected _model_ 1811 1663 """ 1812 name = model_name 1813 if self.cbCategory.currentText() == CATEGORY_CUSTOM: 1814 # custom kernel load requires full path 1815 name = os.path.join(ModelUtilities.find_plugins_dir(), model_name+".py") 1816 kernel_module = generate.load_kernel_module(name) 1664 kernel_module = generate.load_kernel_module(model_name) 1817 1665 self.model_parameters = modelinfo.make_parameter_table(getattr(kernel_module, 'parameters', [])) 1818 1666 -
src/sas/qtgui/Perspectives/Fitting/ModelUtilities.py
- Property mode changed from 100644 to 100755
r3b3b40b rb3e8629 179 179 plugins = {} 180 180 for filename in os.listdir(directory): 181 182 181 name, ext = os.path.splitext(filename) 183 182 if ext == '.py' and not name == '__init__': … … 185 184 try: 186 185 model = load_custom_model(path) 187 #model.name = PLUGIN_NAME_BASE + model.name186 model.name = PLUGIN_NAME_BASE + model.name 188 187 plugins[model.name] = model 189 188 except Exception: … … 416 415 implement model 417 416 """ 418 def __init__(self): 419 self.__modelmanager = ModelManagerBase() 420 self.cat_model_list = [self.__modelmanager.model_dictionary[model_name] for model_name \ 421 in list(self.__modelmanager.model_dictionary.keys()) \ 422 if model_name not in list(self.__modelmanager.stored_plugins.keys())] 423 424 CategoryInstaller.check_install(model_list=self.cat_model_list) 425 417 __modelmanager = ModelManagerBase() 418 cat_model_list = [__modelmanager.model_dictionary[model_name] for model_name \ 419 in list(__modelmanager.model_dictionary.keys()) \ 420 if model_name not in list(__modelmanager.stored_plugins.keys())] 421 422 CategoryInstaller.check_install(model_list=cat_model_list) 426 423 def findModels(self): 427 424 return self.__modelmanager.findModels() -
src/sas/qtgui/Perspectives/Fitting/MultiConstraint.py
r3b3b40b r14ec91c5 114 114 115 115 # 3. parameter name should be a separate word, but can have "()[]*+-/ " around 116 #valid_neighbours = "()[]*+-/ "117 #start_loc = parameter_string_start -1118 #end_loc = parameter_string_end119 #if not any([constraint_text[start_loc] == ch for ch in valid_neighbours]):120 #return False121 #if end_loc < len(constraint_text):122 #if not any([constraint_text[end_loc] == ch for ch in valid_neighbours]):123 #return False116 valid_neighbours = "()[]*+-/ " 117 start_loc = parameter_string_start -1 118 end_loc = parameter_string_end 119 if not any([constraint_text[start_loc] == ch for ch in valid_neighbours]): 120 return False 121 if end_loc < len(constraint_text): 122 if not any([constraint_text[end_loc] == ch for ch in valid_neighbours]): 123 return False 124 124 125 125 # 4. replace parameter name with "1" and try to evaluate the expression -
src/sas/qtgui/Perspectives/Fitting/UI/FittingWidgetUI.ui
r3b3b40b re4c475b7 7 7 <x>0</x> 8 8 <y>0</y> 9 <width> 680</width>9 <width>568</width> 10 10 <height>605</height> 11 11 </rect> -
src/sas/qtgui/Perspectives/Fitting/UnitTesting/ConstraintWidgetTest.py
- Property mode changed from 100644 to 100755
r3b3b40b r725d9c06 22 22 if not QtWidgets.QApplication.instance(): 23 23 app = QtWidgets.QApplication(sys.argv) 24 #app = QtWidgets.QApplication(sys.argv) 24 25 25 26 class ConstraintWidgetTest(unittest.TestCase): … … 70 71 # click on "batch" 71 72 QTest.mouseClick(self.widget.btnBatch, QtCore.Qt.LeftButton) 72 QtWidgets.QApplication.processEvents()73 app.processEvents() 73 74 # See what the current type is now 74 75 self.assertEqual(self.widget.currentType, "BatchPage") … … 77 78 # Go back to single fit 78 79 QTest.mouseClick(self.widget.btnSingle, QtCore.Qt.LeftButton) 79 QtWidgets.QApplication.processEvents()80 app.processEvents() 80 81 # See what the current type is now 81 82 self.assertEqual(self.widget.currentType, "FitPage") -
src/sas/qtgui/Utilities/GuiUtils.py
r3b3b40b r63319b0 213 213 plotRequestedSignal = QtCore.pyqtSignal(list) 214 214 215 # Plot from file names216 plotFromFilenameSignal = QtCore.pyqtSignal(str)217 218 215 # Plot update requested from a perspective 219 216 plotUpdateSignal = QtCore.pyqtSignal(list) … … 239 236 # Send result of Data Operation Utility panel to Data Explorer 240 237 updateModelFromDataOperationPanelSignal = QtCore.pyqtSignal(QtGui.QStandardItem, dict) 241 242 # Notify about a new custom plugin being written/deleted/modified243 customModelDirectoryChanged = QtCore.pyqtSignal()244 238 245 239 def updateModelItemWithPlot(item, update_data, name=""): … … 878 872 raise TypeError 879 873 880 def findNextFilename(filename, directory):881 """882 Finds the next available (non-existing) name for 'filename' in 'directory'.883 plugin.py -> plugin (n).py - for first 'n' for which the file doesn't exist884 """885 basename, ext = os.path.splitext(filename)886 # limit the number of copies887 MAX_FILENAMES = 1000888 # Start with (1)889 number_ext = 1890 proposed_filename = ""891 found_filename = False892 # Find the next available filename or exit if too many copies893 while not found_filename or number_ext > MAX_FILENAMES:894 proposed_filename = basename + " ("+str(number_ext)+")" + ext895 if os.path.exists(os.path.join(directory, proposed_filename)):896 number_ext += 1897 else:898 found_filename = True899 900 return proposed_filename901 902 903 874 class DoubleValidator(QtGui.QDoubleValidator): 904 875 """ -
src/sas/qtgui/Utilities/LocalConfig.py
r3b3b40b rc3eb858 141 141 # Time out for updating sasview 142 142 UPDATE_TIMEOUT = 2 143 144 # Logging levels to disable, if any145 DISABLE_LOGGING = logging.DEBUG146 147 143 def printEVT(message): 148 144 """
Note: See TracChangeset
for help on using the changeset viewer.