Changeset 14ec91c5 in sasview for src/sas/qtgui/Perspectives/Fitting
- Timestamp:
- Feb 2, 2018 9:21:48 AM (7 years ago)
- Branches:
- ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc
- Children:
- a90c9c5
- Parents:
- 5e66738
- Location:
- src/sas/qtgui/Perspectives/Fitting
- Files:
-
- 10 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
src/sas/qtgui/Perspectives/Fitting/ComplexConstraint.py
rda9a0722 r14ec91c5 15 15 # Local UI 16 16 from sas.qtgui.Perspectives.Fitting.UI.ComplexConstraintUI import Ui_ComplexConstraintUI 17 from sas.qtgui.Perspectives.Fitting.Constraint simport Constraint17 from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 18 18 19 19 class ComplexConstraint(QtWidgets.QDialog, Ui_ComplexConstraintUI): … … 36 36 37 37 self.setFixedSize(self.minimumSizeHint()) 38 39 # Default focus is on OK 40 self.cmdOK.setFocus() 38 41 39 42 def setupData(self): -
src/sas/qtgui/Perspectives/Fitting/Constraint.py
rba01ad1 r14ec91c5 2 2 """ 3 3 Internal representation of a single parameter constraint 4 Currently just a data structure, might get expaned with more functionality, 5 hence made into a class. 4 6 """ 5 7 def __init__(self, parent=None, param=None, value=0.0, min=None, max=None, func=None): … … 51 53 self._max = val 52 54 53 def delete(self, constraint=None):54 pass -
src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py
rda9a0722 r14ec91c5 5 5 6 6 import sas.qtgui.Utilities.GuiUtils as GuiUtils 7 import sas.qtgui.Utilities.LocalConfig as LocalConfig 8 7 9 from PyQt5 import QtGui, QtCore, QtWidgets 8 10 … … 15 17 from sas.qtgui.Perspectives.Fitting.ConsoleUpdate import ConsoleUpdate 16 18 from sas.qtgui.Perspectives.Fitting.ComplexConstraint import ComplexConstraint 17 from sas.qtgui.Perspectives.Fitting.Constraint simport Constraint19 from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 18 20 19 21 class ConstraintWidget(QtWidgets.QWidget, Ui_ConstraintWidgetUI): … … 22 24 """ 23 25 24 def __init__(self, parent=None , tab_id=1):26 def __init__(self, parent=None): 25 27 super(ConstraintWidget, self).__init__() 26 28 self.parent = parent 27 29 self.setupUi(self) 28 30 self.currentType = "FitPage" 29 self.tab_id = tab_id30 31 # Page id for fitting 31 32 # To keep with previous SasView values, use 300 as the start offset 32 self.page_id = 30 0 + self.tab_id33 self.page_id = 301 33 34 34 35 # Remember previous content of modified cell … … 118 119 pass 119 120 121 def getTabsForFit(self): 122 """ 123 Returns list of tab names selected for fitting 124 """ 125 return [tab for tab in self.tabs_for_fitting if self.tabs_for_fitting[tab]] 126 120 127 def onFit(self): 121 128 """ … … 123 130 """ 124 131 # Find out all tabs to fit 125 tabs_to_fit = [tab for tab in self.tabs_for_fitting if self.tabs_for_fitting[tab]]132 tabs_to_fit = self.getTabsForFit() 126 133 127 134 # Single fitter for the simultaneous run 128 135 sim_fitter = Fit() 129 136 sim_fitter.fitter_id = self.page_id 137 138 # Notify the parent about fitting started 139 self.parent.fittingStartedSignal.emit(tabs_to_fit) 130 140 131 141 # prepare fitting problems for each tab … … 157 167 completefn = self.onBatchFitComplete if self.currentType=='BatchPage' else self.onFitComplete 158 168 159 #ifUSING_TWISTED:160 handler = None161 updater = None162 #else:163 #handler = ConsoleUpdate(parent=self.parent,164 #manager=self,165 #improvement_delta=0.1)166 #updater = handler.update_fit169 if LocalConfig.USING_TWISTED: 170 handler = None 171 updater = None 172 else: 173 handler = ConsoleUpdate(parent=self.parent, 174 manager=self, 175 improvement_delta=0.1) 176 updater = handler.update_fit 167 177 168 178 batch_inputs = {} … … 178 188 completefn=completefn) 179 189 180 #ifUSING_TWISTED:181 # start the trhrhread with twisted182 calc_thread = threads.deferToThread(calc_fit.compute)183 calc_thread.addCallback(completefn)184 calc_thread.addErrback(self.onFitFailed)185 #else:186 ## Use the old python threads + Queue187 #calc_fit.queue()188 #calc_fit.ready(2.5)190 if LocalConfig.USING_TWISTED: 191 # start the trhrhread with twisted 192 calc_thread = threads.deferToThread(calc_fit.compute) 193 calc_thread.addCallback(completefn) 194 calc_thread.addErrback(self.onFitFailed) 195 else: 196 # Use the old python threads + Queue 197 calc_fit.queue() 198 calc_fit.ready(2.5) 189 199 190 200 … … 300 310 self.cmdFit.setEnabled(True) 301 311 312 # Notify the parent about completed fitting 313 self.parent.fittingStoppedSignal.emit(self.getTabsForFit()) 314 302 315 # get the elapsed time 303 316 elapsed = result[1] … … 330 343 self.cmdFit.setEnabled(True) 331 344 345 # Notify the parent about completed fitting 346 self.parent.fittingStoppedSignal.emit(self.getTabsForFit()) 347 332 348 # get the elapsed time 333 349 elapsed = result[1] … … 348 364 self.cmdFit.setText("Fit") 349 365 self.cmdFit.setEnabled(True) 366 367 # Notify the parent about completed fitting 368 self.parent.fittingStoppedSignal.emit(self.getTabsForFit()) 350 369 351 370 msg = "Fitting failed: %s s.\n" % reason -
src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py
r63319b0 r14ec91c5 19 19 """ 20 20 tabsModifiedSignal = QtCore.pyqtSignal() 21 fittingStartedSignal = QtCore.pyqtSignal(list) 22 fittingStoppedSignal = QtCore.pyqtSignal(list) 23 21 24 name = "Fitting" # For displaying in the combo box in DataExplorer 22 25 def __init__(self, parent=None, data=None): … … 32 35 # Max index for adding new, non-clashing tab names 33 36 self.maxIndex = 0 34 self.maxCSIndex = 035 37 36 38 # Index of the current tab … … 40 42 self.optimizer = 'Levenberg-Marquardt' 41 43 42 # Dataset inde -> Fitting tab mapping44 # Dataset index -> Fitting tab mapping 43 45 self.dataToFitTab = {} 44 46 45 47 # The tabs need to be closeable 46 48 self.setTabsClosable(True) 49 50 # The tabs need to be movabe 51 self.setMovable(True) 47 52 48 53 self.communicate = self.parent.communicator() … … 54 59 self.tabCloseRequested.connect(self.tabCloses) 55 60 self.communicate.dataDeletedSignal.connect(self.dataDeleted) 61 self.fittingStartedSignal.connect(self.onFittingStarted) 62 self.fittingStoppedSignal.connect(self.onFittingStopped) 56 63 57 64 # Perspective window not allowed to close by default … … 69 76 self.gpu_options_widget = GPUOptions(self) 70 77 71 #self.setWindowTitle('Fit panel - Active Fitting Optimizer: %s' % self.optimizer)72 78 self.updateWindowTitle() 73 79 … … 82 88 def setClosable(self, value=True): 83 89 """ 84 Allow outsiders close this widget90 Allow outsiders to close this widget 85 91 """ 86 92 assert isinstance(value, bool) … … 124 130 Add a new C&S fitting tab 125 131 """ 126 tab = ConstraintWidget(parent=self, tab_id=self.maxCSIndex) 132 tabs = [isinstance(tab, ConstraintWidget) for tab in self.tabs] 133 if any(tabs): 134 # We already have a C&S tab: show it 135 self.setCurrentIndex(tabs.index(True)) 136 return 137 tab = ConstraintWidget(parent=self) 127 138 # Add this tab to the object library so it can be retrieved by scripting/jupyter 128 139 tab_name = self.getCSTabName() # TODO update the tab name scheme 129 140 ObjectLibrary.addObject(tab_name, tab) 130 141 self.tabs.append(tab) 131 self.maxCSIndex += 1132 142 self.addTab(tab, tab_name) 133 143 … … 155 165 """ 156 166 page_name = "Const. & Simul. Fit" 157 page_name = page_name + str(self.maxCSIndex)158 167 return page_name 159 168 … … 263 272 self.updateWindowTitle() 264 273 274 def onFittingStarted(self, tabs_for_fitting=None): 275 """ 276 Notify tabs listed in tabs_for_fitting 277 that the fitting thread started 278 """ 279 assert(isinstance(tabs_for_fitting, list)) 280 assert(len(tabs_for_fitting)>0) 281 282 for tab_object in self.tabs: 283 if not isinstance(tab_object, FittingWidget): 284 continue 285 page_name = "Page%s"%tab_object.tab_id 286 if any([page_name in tab for tab in tabs_for_fitting]): 287 tab_object.setFittingStarted() 288 265 289 pass 290 291 def onFittingStopped(self, tabs_for_fitting=None): 292 """ 293 Notify tabs listed in tabs_for_fitting 294 that the fitting thread stopped 295 """ 296 assert(isinstance(tabs_for_fitting, list)) 297 assert(len(tabs_for_fitting)>0) 298 299 for tab_object in self.tabs: 300 if not isinstance(tab_object, FittingWidget): 301 continue 302 page_name = "Page%s"%tab_object.tab_id 303 if any([page_name in tab for tab in tabs_for_fitting]): 304 tab_object.setFittingStopped() 305 306 pass -
src/sas/qtgui/Perspectives/Fitting/FittingWidget.py
r63319b0 r14ec91c5 23 23 24 24 import sas.qtgui.Utilities.GuiUtils as GuiUtils 25 import sas.qtgui.Utilities.LocalConfig as LocalConfig 26 25 27 from sas.qtgui.Utilities.CategoryInstaller import CategoryInstaller 26 28 from sas.qtgui.Plotting.PlotterData import Data1D … … 41 43 from sas.qtgui.Perspectives.Fitting.ViewDelegate import PolyViewDelegate 42 44 from sas.qtgui.Perspectives.Fitting.ViewDelegate import MagnetismViewDelegate 43 from sas.qtgui.Perspectives.Fitting.Constraint simport Constraint45 from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 44 46 from sas.qtgui.Perspectives.Fitting.MultiConstraint import MultiConstraint 45 47 … … 53 55 DEFAULT_POLYDISP_FUNCTION = 'gaussian' 54 56 55 USING_TWISTED = True56 #USING_TWISTED = False57 57 58 58 class ToolTippedItemModel(QtGui.QStandardItemModel): … … 1086 1086 batch_outputs = {} 1087 1087 #--------------------------------- 1088 if USING_TWISTED:1088 if LocalConfig.USING_TWISTED: 1089 1089 handler = None 1090 1090 updater = None … … 1114 1114 completefn=completefn) 1115 1115 1116 if USING_TWISTED:1116 if LocalConfig.USING_TWISTED: 1117 1117 # start the trhrhread with twisted 1118 1118 calc_thread = threads.deferToThread(calc_fit.compute) 1119 calc_thread.addCallback( self.fitComplete)1119 calc_thread.addCallback(completefn) 1120 1120 calc_thread.addErrback(self.fitFailed) 1121 1121 else: … … 1124 1124 calc_fit.ready(2.5) 1125 1125 1126 1127 #disable the Fit button1128 self.cmdFit.setText('Running...')1129 1126 self.communicate.statusBarUpdateSignal.emit('Fitting started...') 1130 self.cmdFit.setEnabled(False) 1127 # Disable some elements 1128 self.setFittingStarted() 1131 1129 1132 1130 def updateFit(self): … … 1147 1145 """ 1148 1146 #re-enable the Fit button 1149 self.cmdFit.setText("Fit") 1150 self.cmdFit.setEnabled(True) 1147 self.setFittingStopped() 1151 1148 1152 1149 print ("BATCH FITTING FINISHED") … … 1160 1157 """ 1161 1158 #re-enable the Fit button 1162 self.cmdFit.setText("Fit") 1163 self.cmdFit.setEnabled(True) 1159 self.setFittingStopped() 1164 1160 1165 1161 assert result is not None … … 2232 2228 self.setMagneticModel() 2233 2229 2230 def setFittingStarted(self): 2231 """ 2232 Set item enablement on fitting start 2233 """ 2234 #disable the Fit button 2235 self.cmdFit.setText('Running...') 2236 self.cmdFit.setEnabled(False) 2237 2238 def setFittingStopped(self): 2239 """ 2240 Set item enablement on fitting stop 2241 """ 2242 #enable the Fit button 2243 self.cmdFit.setText("Fit") 2244 self.cmdFit.setEnabled(True) 2245 2234 2246 def readFitPage(self, fp): 2235 2247 """ -
src/sas/qtgui/Perspectives/Fitting/MultiConstraint.py
r5e66738 r14ec91c5 43 43 self.cmdRevert.clicked.connect(self.revert) 44 44 self.txtConstraint.editingFinished.connect(self.validateFormula) 45 46 # Default focus is on OK 47 self.cmdOK.setFocus() 45 48 46 49 def revert(self): -
src/sas/qtgui/Perspectives/Fitting/UI/ComplexConstraintUI.ui
r2d466e4 r14ec91c5 7 7 <x>0</x> 8 8 <y>0</y> 9 <width> 359</width>10 <height>16 6</height>9 <width>406</width> 10 <height>167</height> 11 11 </rect> 12 12 </property> … … 92 92 <widget class="QPushButton" name="cmdRevert"> 93 93 <property name="text"> 94 <string> Revert</string>94 <string>Swap</string> 95 95 </property> 96 96 </widget> … … 165 165 <string>OK</string> 166 166 </property> 167 <property name="default"> 168 <bool>true</bool> 169 </property> 167 170 </widget> 168 171 </item> -
src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui
rd3c0b95 r14ec91c5 10 10 <x>0</x> 11 11 <y>0</y> 12 <width> 369</width>13 <height>1 43</height>12 <width>426</width> 13 <height>162</height> 14 14 </rect> 15 15 </property> … … 85 85 <widget class="QPushButton" name="cmdRevert"> 86 86 <property name="text"> 87 <string> Revert</string>87 <string>Swap</string> 88 88 </property> 89 89 </widget> … … 150 150 <property name="text"> 151 151 <string>OK</string> 152 </property> 153 <property name="default"> 154 <bool>true</bool> 152 155 </property> 153 156 </widget> -
src/sas/qtgui/Perspectives/Fitting/UnitTesting/ConstraintWidgetTest.py
rda9a0722 r14ec91c5 15 15 # Local 16 16 from sas.qtgui.Perspectives.Fitting.ConstraintWidget import ConstraintWidget 17 from sas.qtgui.Perspectives.Fitting.Constraint simport Constraint17 from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 18 18 19 19 if not QtWidgets.QApplication.instance(): -
src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingOptionsTest.py
r53c771e r14ec91c5 1 1 import sys 2 2 import unittest 3 import webbrowser 3 4 from bumps import options 4 5 … … 114 115 115 116 # test disabled until pyQt5 works well 116 def notestOnHelp(self):117 def testOnHelp(self): 117 118 ''' Test help display''' 118 #Mock the QWebView method 119 QtWebKit.QWebView.show = MagicMock() 120 QtWebKit.QWebView.load = MagicMock() 119 webbrowser.open = MagicMock() 121 120 122 121 # Invoke the action on default tab 123 122 self.widget.onHelp() 124 123 # Check if show() got called 125 self.assertTrue( QtWebKit.QWebView.show.called)124 self.assertTrue(webbrowser.open.called) 126 125 # Assure the filename is correct 127 self.assertIn("optimizer.html", QtWebKit.QWebView.load.call_args[0][0].toString())126 self.assertIn("optimizer.html", webbrowser.open.call_args[0][0]) 128 127 129 128 # Change the combo index … … 131 130 self.widget.onHelp() 132 131 # Check if show() got called 133 self.assertEqual( QtWebKit.QWebView.show.call_count, 2)132 self.assertEqual(webbrowser.open.call_count, 2) 134 133 # Assure the filename is correct 135 self.assertIn("fit-dream", QtWebKit.QWebView.load.call_args[0][0].toString())134 self.assertIn("fit-dream", webbrowser.open.call_args[0][0]) 136 135 137 136 # Change the index again … … 139 138 self.widget.onHelp() 140 139 # Check if show() got called 141 self.assertEqual( QtWebKit.QWebView.show.call_count, 3)140 self.assertEqual(webbrowser.open.call_count, 3) 142 141 # Assure the filename is correct 143 self.assertIn("fit-lm", QtWebKit.QWebView.load.call_args[0][0].toString())142 self.assertIn("fit-lm", webbrowser.open.call_args[0][0]) 144 143 145 144 def testWidgetFromOptions(self): -
src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py
r63319b0 r14ec91c5 17 17 from sas.qtgui.Utilities.GuiUtils import * 18 18 from sas.qtgui.Perspectives.Fitting.FittingWidget import * 19 from sas.qtgui.Perspectives.Fitting.Constraint simport Constraint19 from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 20 20 21 21 from sas.qtgui.UnitTesting.TestUtils import QtSignalSpy … … 787 787 self.assertEqual(update_spy.count(), 1) 788 788 789 # test disabled until pyqt5 deals with html properly 790 def notestOnHelp(self): 789 def testOnHelp(self): 791 790 """ 792 791 Test various help pages shown in this widget 793 792 """ 794 #Mock the QWebViewmethod795 QtWebKit.QWebView.show= MagicMock()796 QtWebKit.QWebView.load= MagicMock()793 #Mock the webbrowser.open method 794 self.widget.parent.showHelp = MagicMock() 795 #webbrowser.open = MagicMock() 797 796 798 797 # Invoke the action on default tab 799 798 self.widget.onHelp() 800 799 # Check if show() got called 801 self.assertTrue( QtWebKit.QWebView.show.called)800 self.assertTrue(self.widget.parent.showHelp.called) 802 801 # Assure the filename is correct 803 self.assertIn("fitting_help.html", QtWebKit.QWebView.load.call_args[0][0].toString())802 self.assertIn("fitting_help.html", self.widget.parent.showHelp.call_args[0][0]) 804 803 805 804 # Change the tab to options … … 807 806 self.widget.onHelp() 808 807 # Check if show() got called 809 self.assertEqual( QtWebKit.QWebView.show.call_count, 2)808 self.assertEqual(self.widget.parent.showHelp.call_count, 2) 810 809 # Assure the filename is correct 811 self.assertIn("residuals_help.html", QtWebKit.QWebView.load.call_args[0][0].toString())810 self.assertIn("residuals_help.html", self.widget.parent.showHelp.call_args[0][0]) 812 811 813 812 # Change the tab to smearing … … 815 814 self.widget.onHelp() 816 815 # Check if show() got called 817 self.assertEqual( QtWebKit.QWebView.show.call_count, 3)816 self.assertEqual(self.widget.parent.showHelp.call_count, 3) 818 817 # Assure the filename is correct 819 self.assertIn(" sm_help.html", QtWebKit.QWebView.load.call_args[0][0].toString())818 self.assertIn("resolution.html", self.widget.parent.showHelp.call_args[0][0]) 820 819 821 820 # Change the tab to poly … … 823 822 self.widget.onHelp() 824 823 # Check if show() got called 825 self.assertEqual( QtWebKit.QWebView.show.call_count, 4)824 self.assertEqual(self.widget.parent.showHelp.call_count, 4) 826 825 # Assure the filename is correct 827 self.assertIn("p d_help.html", QtWebKit.QWebView.load.call_args[0][0].toString())826 self.assertIn("polydispersity.html", self.widget.parent.showHelp.call_args[0][0]) 828 827 829 828 # Change the tab to magnetism … … 831 830 self.widget.onHelp() 832 831 # Check if show() got called 833 self.assertEqual( QtWebKit.QWebView.show.call_count, 5)832 self.assertEqual(self.widget.parent.showHelp.call_count, 5) 834 833 # Assure the filename is correct 835 self.assertIn("mag _help.html", QtWebKit.QWebView.load.call_args[0][0].toString())834 self.assertIn("magnetism.html", self.widget.parent.showHelp.call_args[0][0]) 836 835 837 836 def testReadFitPage(self):
Note: See TracChangeset
for help on using the changeset viewer.