Changeset 14ec91c5 in sasview for src/sas/qtgui/Perspectives/Fitting


Ignore:
Timestamp:
Feb 2, 2018 9:21:48 AM (7 years ago)
Author:
Piotr Rozyczko <rozyczko@…>
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
Message:

More code review related fixes

Location:
src/sas/qtgui/Perspectives/Fitting
Files:
10 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/sas/qtgui/Perspectives/Fitting/ComplexConstraint.py

    rda9a0722 r14ec91c5  
    1515# Local UI 
    1616from sas.qtgui.Perspectives.Fitting.UI.ComplexConstraintUI import Ui_ComplexConstraintUI 
    17 from sas.qtgui.Perspectives.Fitting.Constraints import Constraint 
     17from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 
    1818 
    1919class ComplexConstraint(QtWidgets.QDialog, Ui_ComplexConstraintUI): 
     
    3636 
    3737        self.setFixedSize(self.minimumSizeHint()) 
     38 
     39        # Default focus is on OK 
     40        self.cmdOK.setFocus() 
    3841 
    3942    def setupData(self): 
  • src/sas/qtgui/Perspectives/Fitting/Constraint.py

    rba01ad1 r14ec91c5  
    22    """ 
    33    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. 
    46    """ 
    57    def __init__(self, parent=None, param=None, value=0.0, min=None, max=None, func=None): 
     
    5153        self._max = val 
    5254 
    53     def delete(self, constraint=None): 
    54         pass 
  • src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py

    rda9a0722 r14ec91c5  
    55 
    66import sas.qtgui.Utilities.GuiUtils as GuiUtils 
     7import sas.qtgui.Utilities.LocalConfig as LocalConfig 
     8 
    79from PyQt5 import QtGui, QtCore, QtWidgets 
    810 
     
    1517from sas.qtgui.Perspectives.Fitting.ConsoleUpdate import ConsoleUpdate 
    1618from sas.qtgui.Perspectives.Fitting.ComplexConstraint import ComplexConstraint 
    17 from sas.qtgui.Perspectives.Fitting.Constraints import Constraint 
     19from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 
    1820 
    1921class ConstraintWidget(QtWidgets.QWidget, Ui_ConstraintWidgetUI): 
     
    2224    """ 
    2325 
    24     def __init__(self, parent=None, tab_id=1): 
     26    def __init__(self, parent=None): 
    2527        super(ConstraintWidget, self).__init__() 
    2628        self.parent = parent 
    2729        self.setupUi(self) 
    2830        self.currentType = "FitPage" 
    29         self.tab_id = tab_id 
    3031        # Page id for fitting 
    3132        # To keep with previous SasView values, use 300 as the start offset 
    32         self.page_id = 300 + self.tab_id 
     33        self.page_id = 301 
    3334 
    3435        # Remember previous content of modified cell 
     
    118119        pass 
    119120 
     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 
    120127    def onFit(self): 
    121128        """ 
     
    123130        """ 
    124131        # 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() 
    126133 
    127134        # Single fitter for the simultaneous run 
    128135        sim_fitter = Fit() 
    129136        sim_fitter.fitter_id = self.page_id 
     137 
     138        # Notify the parent about fitting started 
     139        self.parent.fittingStartedSignal.emit(tabs_to_fit) 
    130140 
    131141        # prepare fitting problems for each tab 
     
    157167        completefn = self.onBatchFitComplete if self.currentType=='BatchPage' else self.onFitComplete 
    158168 
    159         #if USING_TWISTED: 
    160         handler = None 
    161         updater = None 
    162         #else: 
    163         #    handler = ConsoleUpdate(parent=self.parent, 
    164         #                            manager=self, 
    165         #                            improvement_delta=0.1) 
    166         #    updater = handler.update_fit 
     169        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 
    167177 
    168178        batch_inputs = {} 
     
    178188                             completefn=completefn) 
    179189 
    180         #if USING_TWISTED: 
    181         # start the trhrhread with twisted 
    182         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 + Queue 
    187         #    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) 
    189199 
    190200 
     
    300310        self.cmdFit.setEnabled(True) 
    301311 
     312        # Notify the parent about completed fitting 
     313        self.parent.fittingStoppedSignal.emit(self.getTabsForFit()) 
     314 
    302315        # get the elapsed time 
    303316        elapsed = result[1] 
     
    330343        self.cmdFit.setEnabled(True) 
    331344 
     345        # Notify the parent about completed fitting 
     346        self.parent.fittingStoppedSignal.emit(self.getTabsForFit()) 
     347 
    332348        # get the elapsed time 
    333349        elapsed = result[1] 
     
    348364        self.cmdFit.setText("Fit") 
    349365        self.cmdFit.setEnabled(True) 
     366 
     367        # Notify the parent about completed fitting 
     368        self.parent.fittingStoppedSignal.emit(self.getTabsForFit()) 
    350369 
    351370        msg = "Fitting failed: %s s.\n" % reason 
  • src/sas/qtgui/Perspectives/Fitting/FittingPerspective.py

    r63319b0 r14ec91c5  
    1919    """ 
    2020    tabsModifiedSignal = QtCore.pyqtSignal() 
     21    fittingStartedSignal = QtCore.pyqtSignal(list) 
     22    fittingStoppedSignal = QtCore.pyqtSignal(list) 
     23 
    2124    name = "Fitting" # For displaying in the combo box in DataExplorer 
    2225    def __init__(self, parent=None, data=None): 
     
    3235        # Max index for adding new, non-clashing tab names 
    3336        self.maxIndex = 0 
    34         self.maxCSIndex = 0 
    3537 
    3638        # Index of the current tab 
     
    4042        self.optimizer = 'Levenberg-Marquardt' 
    4143 
    42         # Dataset inde -> Fitting tab mapping 
     44        # Dataset index -> Fitting tab mapping 
    4345        self.dataToFitTab = {} 
    4446 
    4547        # The tabs need to be closeable 
    4648        self.setTabsClosable(True) 
     49 
     50        # The tabs need to be movabe 
     51        self.setMovable(True) 
    4752 
    4853        self.communicate = self.parent.communicator() 
     
    5459        self.tabCloseRequested.connect(self.tabCloses) 
    5560        self.communicate.dataDeletedSignal.connect(self.dataDeleted) 
     61        self.fittingStartedSignal.connect(self.onFittingStarted) 
     62        self.fittingStoppedSignal.connect(self.onFittingStopped) 
    5663 
    5764        # Perspective window not allowed to close by default 
     
    6976        self.gpu_options_widget = GPUOptions(self) 
    7077 
    71         #self.setWindowTitle('Fit panel - Active Fitting Optimizer: %s' % self.optimizer) 
    7278        self.updateWindowTitle() 
    7379 
     
    8288    def setClosable(self, value=True): 
    8389        """ 
    84         Allow outsiders close this widget 
     90        Allow outsiders to close this widget 
    8591        """ 
    8692        assert isinstance(value, bool) 
     
    124130        Add a new C&S fitting tab 
    125131        """ 
    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) 
    127138        # Add this tab to the object library so it can be retrieved by scripting/jupyter 
    128139        tab_name = self.getCSTabName() # TODO update the tab name scheme 
    129140        ObjectLibrary.addObject(tab_name, tab) 
    130141        self.tabs.append(tab) 
    131         self.maxCSIndex += 1 
    132142        self.addTab(tab, tab_name) 
    133143 
     
    155165        """ 
    156166        page_name = "Const. & Simul. Fit" 
    157         page_name = page_name + str(self.maxCSIndex) 
    158167        return page_name 
    159168 
     
    263272        self.updateWindowTitle() 
    264273 
     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 
    265289        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  
    2323 
    2424import sas.qtgui.Utilities.GuiUtils as GuiUtils 
     25import sas.qtgui.Utilities.LocalConfig as LocalConfig 
     26 
    2527from sas.qtgui.Utilities.CategoryInstaller import CategoryInstaller 
    2628from sas.qtgui.Plotting.PlotterData import Data1D 
     
    4143from sas.qtgui.Perspectives.Fitting.ViewDelegate import PolyViewDelegate 
    4244from sas.qtgui.Perspectives.Fitting.ViewDelegate import MagnetismViewDelegate 
    43 from sas.qtgui.Perspectives.Fitting.Constraints import Constraint 
     45from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 
    4446from sas.qtgui.Perspectives.Fitting.MultiConstraint import MultiConstraint 
    4547 
     
    5355DEFAULT_POLYDISP_FUNCTION = 'gaussian' 
    5456 
    55 USING_TWISTED = True 
    56 #USING_TWISTED = False 
    5757 
    5858class ToolTippedItemModel(QtGui.QStandardItemModel): 
     
    10861086        batch_outputs = {} 
    10871087        #--------------------------------- 
    1088         if USING_TWISTED: 
     1088        if LocalConfig.USING_TWISTED: 
    10891089            handler = None 
    10901090            updater = None 
     
    11141114                            completefn=completefn) 
    11151115 
    1116         if USING_TWISTED: 
     1116        if LocalConfig.USING_TWISTED: 
    11171117            # start the trhrhread with twisted 
    11181118            calc_thread = threads.deferToThread(calc_fit.compute) 
    1119             calc_thread.addCallback(self.fitComplete) 
     1119            calc_thread.addCallback(completefn) 
    11201120            calc_thread.addErrback(self.fitFailed) 
    11211121        else: 
     
    11241124            calc_fit.ready(2.5) 
    11251125 
    1126  
    1127         #disable the Fit button 
    1128         self.cmdFit.setText('Running...') 
    11291126        self.communicate.statusBarUpdateSignal.emit('Fitting started...') 
    1130         self.cmdFit.setEnabled(False) 
     1127        # Disable some elements 
     1128        self.setFittingStarted() 
    11311129 
    11321130    def updateFit(self): 
     
    11471145        """ 
    11481146        #re-enable the Fit button 
    1149         self.cmdFit.setText("Fit") 
    1150         self.cmdFit.setEnabled(True) 
     1147        self.setFittingStopped() 
    11511148 
    11521149        print ("BATCH FITTING FINISHED") 
     
    11601157        """ 
    11611158        #re-enable the Fit button 
    1162         self.cmdFit.setText("Fit") 
    1163         self.cmdFit.setEnabled(True) 
     1159        self.setFittingStopped() 
    11641160 
    11651161        assert result is not None 
     
    22322228        self.setMagneticModel() 
    22332229 
     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 
    22342246    def readFitPage(self, fp): 
    22352247        """ 
  • src/sas/qtgui/Perspectives/Fitting/MultiConstraint.py

    r5e66738 r14ec91c5  
    4343        self.cmdRevert.clicked.connect(self.revert) 
    4444        self.txtConstraint.editingFinished.connect(self.validateFormula) 
     45 
     46        # Default focus is on OK 
     47        self.cmdOK.setFocus() 
    4548 
    4649    def revert(self): 
  • src/sas/qtgui/Perspectives/Fitting/UI/ComplexConstraintUI.ui

    r2d466e4 r14ec91c5  
    77    <x>0</x> 
    88    <y>0</y> 
    9     <width>359</width> 
    10     <height>166</height> 
     9    <width>406</width> 
     10    <height>167</height> 
    1111   </rect> 
    1212  </property> 
     
    9292         <widget class="QPushButton" name="cmdRevert"> 
    9393          <property name="text"> 
    94            <string>Revert</string> 
     94           <string>Swap</string> 
    9595          </property> 
    9696         </widget> 
     
    165165        <string>OK</string> 
    166166       </property> 
     167       <property name="default"> 
     168        <bool>true</bool> 
     169       </property> 
    167170      </widget> 
    168171     </item> 
  • src/sas/qtgui/Perspectives/Fitting/UI/MultiConstraintUI.ui

    rd3c0b95 r14ec91c5  
    1010    <x>0</x> 
    1111    <y>0</y> 
    12     <width>369</width> 
    13     <height>143</height> 
     12    <width>426</width> 
     13    <height>162</height> 
    1414   </rect> 
    1515  </property> 
     
    8585      <widget class="QPushButton" name="cmdRevert"> 
    8686       <property name="text"> 
    87         <string>Revert</string> 
     87        <string>Swap</string> 
    8888       </property> 
    8989      </widget> 
     
    150150       <property name="text"> 
    151151        <string>OK</string> 
     152       </property> 
     153       <property name="default"> 
     154        <bool>true</bool> 
    152155       </property> 
    153156      </widget> 
  • src/sas/qtgui/Perspectives/Fitting/UnitTesting/ConstraintWidgetTest.py

    rda9a0722 r14ec91c5  
    1515# Local 
    1616from sas.qtgui.Perspectives.Fitting.ConstraintWidget import ConstraintWidget 
    17 from sas.qtgui.Perspectives.Fitting.Constraints import Constraint 
     17from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 
    1818 
    1919if not QtWidgets.QApplication.instance(): 
  • src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingOptionsTest.py

    r53c771e r14ec91c5  
    11import sys 
    22import unittest 
     3import webbrowser 
    34from bumps import options 
    45 
     
    114115 
    115116    # test disabled until pyQt5 works well 
    116     def notestOnHelp(self): 
     117    def testOnHelp(self): 
    117118        ''' Test help display''' 
    118         #Mock the QWebView method 
    119         QtWebKit.QWebView.show = MagicMock() 
    120         QtWebKit.QWebView.load = MagicMock() 
     119        webbrowser.open = MagicMock() 
    121120 
    122121        # Invoke the action on default tab 
    123122        self.widget.onHelp() 
    124123        # Check if show() got called 
    125         self.assertTrue(QtWebKit.QWebView.show.called) 
     124        self.assertTrue(webbrowser.open.called) 
    126125        # 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]) 
    128127 
    129128        # Change the combo index 
     
    131130        self.widget.onHelp() 
    132131        # Check if show() got called 
    133         self.assertEqual(QtWebKit.QWebView.show.call_count, 2) 
     132        self.assertEqual(webbrowser.open.call_count, 2) 
    134133        # 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]) 
    136135 
    137136        # Change the index again 
     
    139138        self.widget.onHelp() 
    140139        # Check if show() got called 
    141         self.assertEqual(QtWebKit.QWebView.show.call_count, 3) 
     140        self.assertEqual(webbrowser.open.call_count, 3) 
    142141        # 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]) 
    144143 
    145144    def testWidgetFromOptions(self): 
  • src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py

    r63319b0 r14ec91c5  
    1717from sas.qtgui.Utilities.GuiUtils import * 
    1818from sas.qtgui.Perspectives.Fitting.FittingWidget import * 
    19 from sas.qtgui.Perspectives.Fitting.Constraints import Constraint 
     19from sas.qtgui.Perspectives.Fitting.Constraint import Constraint 
    2020 
    2121from sas.qtgui.UnitTesting.TestUtils import QtSignalSpy 
     
    787787            self.assertEqual(update_spy.count(), 1) 
    788788 
    789     # test disabled until pyqt5 deals with html properly 
    790     def notestOnHelp(self): 
     789    def testOnHelp(self): 
    791790        """ 
    792791        Test various help pages shown in this widget 
    793792        """ 
    794         #Mock the QWebView method 
    795         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() 
    797796 
    798797        # Invoke the action on default tab 
    799798        self.widget.onHelp() 
    800799        # Check if show() got called 
    801         self.assertTrue(QtWebKit.QWebView.show.called) 
     800        self.assertTrue(self.widget.parent.showHelp.called) 
    802801        # 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]) 
    804803 
    805804        # Change the tab to options 
     
    807806        self.widget.onHelp() 
    808807        # Check if show() got called 
    809         self.assertEqual(QtWebKit.QWebView.show.call_count, 2) 
     808        self.assertEqual(self.widget.parent.showHelp.call_count, 2) 
    810809        # 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]) 
    812811 
    813812        # Change the tab to smearing 
     
    815814        self.widget.onHelp() 
    816815        # Check if show() got called 
    817         self.assertEqual(QtWebKit.QWebView.show.call_count, 3) 
     816        self.assertEqual(self.widget.parent.showHelp.call_count, 3) 
    818817        # 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]) 
    820819 
    821820        # Change the tab to poly 
     
    823822        self.widget.onHelp() 
    824823        # Check if show() got called 
    825         self.assertEqual(QtWebKit.QWebView.show.call_count, 4) 
     824        self.assertEqual(self.widget.parent.showHelp.call_count, 4) 
    826825        # Assure the filename is correct 
    827         self.assertIn("pd_help.html", QtWebKit.QWebView.load.call_args[0][0].toString()) 
     826        self.assertIn("polydispersity.html", self.widget.parent.showHelp.call_args[0][0]) 
    828827 
    829828        # Change the tab to magnetism 
     
    831830        self.widget.onHelp() 
    832831        # Check if show() got called 
    833         self.assertEqual(QtWebKit.QWebView.show.call_count, 5) 
     832        self.assertEqual(self.widget.parent.showHelp.call_count, 5) 
    834833        # 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]) 
    836835 
    837836    def testReadFitPage(self): 
Note: See TracChangeset for help on using the changeset viewer.